@yamat47/playmaker 0.0.0-stage → 0.1.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/LICENSE +21 -0
- package/README.md +51 -2
- package/dist/playmaker.css +2 -0
- package/dist/playmaker.d.ts +319 -0
- package/dist/playmaker.js +2827 -0
- package/dist/playmaker.js.map +1 -0
- package/package.json +68 -3
|
@@ -0,0 +1,2827 @@
|
|
|
1
|
+
// src/common/base/lifecycle.ts
|
|
2
|
+
function e(e) {
|
|
3
|
+
return { dispose: e };
|
|
4
|
+
}
|
|
5
|
+
var t = class {
|
|
6
|
+
items = /* @__PURE__ */ new Set();
|
|
7
|
+
disposed = !1;
|
|
8
|
+
get isDisposed() {
|
|
9
|
+
return this.disposed;
|
|
10
|
+
}
|
|
11
|
+
add(e) {
|
|
12
|
+
return this.disposed ? (e.dispose(), e) : (this.items.add(e), e);
|
|
13
|
+
}
|
|
14
|
+
dispose() {
|
|
15
|
+
if (!this.disposed) {
|
|
16
|
+
this.disposed = !0;
|
|
17
|
+
for (let e of this.items) e.dispose();
|
|
18
|
+
this.items.clear();
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}, n = class {
|
|
22
|
+
_store = new t();
|
|
23
|
+
get isDisposed() {
|
|
24
|
+
return this._store.isDisposed;
|
|
25
|
+
}
|
|
26
|
+
_register(e) {
|
|
27
|
+
return this._store.add(e);
|
|
28
|
+
}
|
|
29
|
+
dispose() {
|
|
30
|
+
this._store.dispose();
|
|
31
|
+
}
|
|
32
|
+
}, r = .5;
|
|
33
|
+
function i(e) {
|
|
34
|
+
return Math.round(e / r) * r + 0;
|
|
35
|
+
}
|
|
36
|
+
function a(e) {
|
|
37
|
+
return {
|
|
38
|
+
lateralYard: i(e.lateralYard),
|
|
39
|
+
downfieldYard: i(e.downfieldYard)
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
// src/common/model/guards.ts
|
|
43
|
+
function o(e) {
|
|
44
|
+
return typeof e == "object" && !!e;
|
|
45
|
+
}
|
|
46
|
+
function s(e) {
|
|
47
|
+
return typeof e == "number" && Number.isFinite(e);
|
|
48
|
+
}
|
|
49
|
+
function c(e) {
|
|
50
|
+
return typeof e == "string" && e.trim() !== "";
|
|
51
|
+
}
|
|
52
|
+
function l(e, t) {
|
|
53
|
+
return t.some((t) => t === e);
|
|
54
|
+
}
|
|
55
|
+
function u(e, t, n) {
|
|
56
|
+
if (!Array.isArray(e)) return [];
|
|
57
|
+
let r = [], i = Math.min(e.length, t);
|
|
58
|
+
for (let t = 0; t < i; t += 1) {
|
|
59
|
+
let i = n(e[t], t);
|
|
60
|
+
i !== null && r.push(i);
|
|
61
|
+
}
|
|
62
|
+
return r;
|
|
63
|
+
}
|
|
64
|
+
// src/common/model/player.ts
|
|
65
|
+
var d = ["circle", "square"], f = "circle", p = ["outline", "solid"], m = .93;
|
|
66
|
+
function h(e) {
|
|
67
|
+
return l(e, d);
|
|
68
|
+
}
|
|
69
|
+
function ee(e) {
|
|
70
|
+
return l(e, p);
|
|
71
|
+
}
|
|
72
|
+
function te(e) {
|
|
73
|
+
if (!o(e)) return null;
|
|
74
|
+
let { lateralYard: t, downfieldYard: n } = e;
|
|
75
|
+
return !s(t) || !s(n) ? null : a({
|
|
76
|
+
lateralYard: t,
|
|
77
|
+
downfieldYard: n
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
function ne(e, t) {
|
|
81
|
+
if (!o(e)) return null;
|
|
82
|
+
let n = te(e.position);
|
|
83
|
+
return n === null ? null : {
|
|
84
|
+
id: c(e.id) ? e.id : `p${t}`,
|
|
85
|
+
position: n,
|
|
86
|
+
shape: h(e.shape) ? e.shape : f,
|
|
87
|
+
label: typeof e.label == "string" ? e.label : "",
|
|
88
|
+
...c(e.color) ? { color: e.color } : {},
|
|
89
|
+
...ee(e.fill) ? { fill: e.fill } : {}
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
function re(e) {
|
|
93
|
+
return u(e, 64, ne);
|
|
94
|
+
}
|
|
95
|
+
function ie(e) {
|
|
96
|
+
return {
|
|
97
|
+
id: e.id,
|
|
98
|
+
position: { ...e.position },
|
|
99
|
+
shape: e.shape,
|
|
100
|
+
label: e.label,
|
|
101
|
+
...e.color === void 0 ? {} : { color: e.color },
|
|
102
|
+
...e.fill === void 0 ? {} : { fill: e.fill }
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
// src/common/design/metrics.ts
|
|
106
|
+
var ae = 1, oe = .0021, se = .375, ce = 2.4, le = 10, ue = 1.5, de = .45, fe = 3, pe = 1.85, me = 1.2, he = .2, ge = 2, _e = .5, ve = 8, ye = .11, be = 1.5, xe = .4, Se = .72, Ce = .24, we = 1.1, Te = .7, Ee = .08, De = .75;
|
|
107
|
+
function Oe(e, t) {
|
|
108
|
+
let n = Math.max(0, e), r = Math.max(0, t), i = Math.max(ae, oe * n), a = 2 * m * r, o = Math.max(be, ye * a);
|
|
109
|
+
return {
|
|
110
|
+
yardLineWidth: i,
|
|
111
|
+
goalLineWidth: 2 * i,
|
|
112
|
+
midfieldLineWidth: ue * i,
|
|
113
|
+
hashTickLength: se * r,
|
|
114
|
+
numberHeight: Math.max(le, ce * r),
|
|
115
|
+
pylonSize: Math.max(fe, de * r),
|
|
116
|
+
goalpostCrossbarHalfLength: pe * r,
|
|
117
|
+
goalpostUprightLength: me * r,
|
|
118
|
+
goalpostStroke: Math.max(ge, he * a),
|
|
119
|
+
tokenDiameter: a,
|
|
120
|
+
markerStroke: o,
|
|
121
|
+
markerLabelFont: Math.max(ve, _e * a),
|
|
122
|
+
routeWidth: o,
|
|
123
|
+
blockWidth: o,
|
|
124
|
+
blockCapLength: xe * a,
|
|
125
|
+
arrowLength: Se * a,
|
|
126
|
+
arrowHalfWidth: Ce * a,
|
|
127
|
+
motionDash: [we * r, Te * r],
|
|
128
|
+
gridDotRadius: Math.max(De, Ee * r)
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
// src/common/editing/editor.ts
|
|
132
|
+
var ke = [
|
|
133
|
+
"select",
|
|
134
|
+
"add-player",
|
|
135
|
+
"draw-line"
|
|
136
|
+
], g = { kind: "none" };
|
|
137
|
+
function Ae(e, t) {
|
|
138
|
+
return e.kind === "none" || t.kind === "none" ? e.kind === t.kind : e.kind === t.kind && e.id === t.id;
|
|
139
|
+
}
|
|
140
|
+
function je(e, t) {
|
|
141
|
+
switch (e) {
|
|
142
|
+
case "add-player": return t.remainingPlayerSlots > 0;
|
|
143
|
+
case "draw-line": return t.canStartLine;
|
|
144
|
+
case "select": return !0;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
function Me(e, t) {
|
|
148
|
+
return e.players.length <= t.remainingPlayerSlots;
|
|
149
|
+
}
|
|
150
|
+
// src/common/base/event.ts
|
|
151
|
+
var _ = class {
|
|
152
|
+
listeners = /* @__PURE__ */ new Set();
|
|
153
|
+
disposed = !1;
|
|
154
|
+
onListenerError;
|
|
155
|
+
constructor(e = console.error) {
|
|
156
|
+
this.onListenerError = e;
|
|
157
|
+
}
|
|
158
|
+
event = (t) => this.disposed ? e(() => {}) : (this.listeners.add(t), e(() => {
|
|
159
|
+
this.listeners.delete(t);
|
|
160
|
+
}));
|
|
161
|
+
fire(e) {
|
|
162
|
+
if (!this.disposed) for (let t of [...this.listeners]) try {
|
|
163
|
+
t(e);
|
|
164
|
+
} catch (e) {
|
|
165
|
+
this.onListenerError(e);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
dispose() {
|
|
169
|
+
this.disposed = !0, this.listeners.clear();
|
|
170
|
+
}
|
|
171
|
+
}, Ne = class {
|
|
172
|
+
model;
|
|
173
|
+
history;
|
|
174
|
+
constructor(e, t) {
|
|
175
|
+
this.model = e, this.history = t;
|
|
176
|
+
}
|
|
177
|
+
get canUndo() {
|
|
178
|
+
return this.history.canUndo;
|
|
179
|
+
}
|
|
180
|
+
get canRedo() {
|
|
181
|
+
return this.history.canRedo;
|
|
182
|
+
}
|
|
183
|
+
execute(e) {
|
|
184
|
+
let t = e.apply(this.model);
|
|
185
|
+
return t && this.history.push(e), t;
|
|
186
|
+
}
|
|
187
|
+
undo() {
|
|
188
|
+
this.history.undo((e) => e.undo(this.model));
|
|
189
|
+
}
|
|
190
|
+
redo() {
|
|
191
|
+
this.history.redo((e) => e.apply(this.model));
|
|
192
|
+
}
|
|
193
|
+
}, Pe = class {
|
|
194
|
+
undoStack = [];
|
|
195
|
+
redoStack = [];
|
|
196
|
+
get canUndo() {
|
|
197
|
+
return this.undoStack.length > 0;
|
|
198
|
+
}
|
|
199
|
+
get canRedo() {
|
|
200
|
+
return this.redoStack.length > 0;
|
|
201
|
+
}
|
|
202
|
+
push(e) {
|
|
203
|
+
this.undoStack.push(e), this.redoStack.length = 0;
|
|
204
|
+
}
|
|
205
|
+
undo(e) {
|
|
206
|
+
this.move(this.undoStack, this.redoStack, e);
|
|
207
|
+
}
|
|
208
|
+
redo(e) {
|
|
209
|
+
this.move(this.redoStack, this.undoStack, e);
|
|
210
|
+
}
|
|
211
|
+
move(e, t, n) {
|
|
212
|
+
let r = e.at(-1);
|
|
213
|
+
r !== void 0 && (n(r), e.pop(), t.push(r));
|
|
214
|
+
}
|
|
215
|
+
}, Fe = ["offense", "defense"];
|
|
216
|
+
function Ie(e) {
|
|
217
|
+
return l(e, Fe);
|
|
218
|
+
}
|
|
219
|
+
function Le(e) {
|
|
220
|
+
if (typeof e == "object" && e && !Object.isFrozen(e)) {
|
|
221
|
+
Object.freeze(e);
|
|
222
|
+
for (let t of Object.values(e)) Le(t);
|
|
223
|
+
}
|
|
224
|
+
return e;
|
|
225
|
+
}
|
|
226
|
+
// src/common/formations/formation.ts
|
|
227
|
+
function Re(e) {
|
|
228
|
+
let { id: t, ...n } = ie(e);
|
|
229
|
+
return n;
|
|
230
|
+
}
|
|
231
|
+
function ze(e) {
|
|
232
|
+
if (!o(e)) return null;
|
|
233
|
+
let t = re(e.players).map(Re);
|
|
234
|
+
return t.length === 0 ? null : {
|
|
235
|
+
id: c(e.id) ? e.id : "formation",
|
|
236
|
+
name: c(e.name) ? e.name : "フォーメーション",
|
|
237
|
+
side: Ie(e.side) ? e.side : "offense",
|
|
238
|
+
players: t
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
function Be(e, t, n) {
|
|
242
|
+
let r = new Set(n);
|
|
243
|
+
return e.players.map((e) => {
|
|
244
|
+
let n = t.next("player", r);
|
|
245
|
+
return r.add(n), {
|
|
246
|
+
...e,
|
|
247
|
+
id: n
|
|
248
|
+
};
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
// src/common/model/id-factory.ts
|
|
252
|
+
var Ve = class {
|
|
253
|
+
counters = /* @__PURE__ */ new Map();
|
|
254
|
+
next(e, t) {
|
|
255
|
+
let n = this.counters.get(e) ?? 0, r;
|
|
256
|
+
do
|
|
257
|
+
n += 1, r = `${e}-${n}`;
|
|
258
|
+
while (t.has(r));
|
|
259
|
+
return this.counters.set(e, n), r;
|
|
260
|
+
}
|
|
261
|
+
}, He = [
|
|
262
|
+
"route",
|
|
263
|
+
"block",
|
|
264
|
+
"motion"
|
|
265
|
+
], Ue = ["straight", "bezier"], We = "route", Ge = "straight";
|
|
266
|
+
function Ke(e) {
|
|
267
|
+
return l(e, He);
|
|
268
|
+
}
|
|
269
|
+
function qe(e) {
|
|
270
|
+
return l(e, Ue);
|
|
271
|
+
}
|
|
272
|
+
function Je(e) {
|
|
273
|
+
return s(e) && e > 0;
|
|
274
|
+
}
|
|
275
|
+
function Ye(e, t, n) {
|
|
276
|
+
if (!o(e) || !c(e.startPlayerId) || !n.has(e.startPlayerId)) return null;
|
|
277
|
+
let r = te(e.end);
|
|
278
|
+
return r === null ? null : {
|
|
279
|
+
id: c(e.id) ? e.id : `l${t}`,
|
|
280
|
+
kind: Ke(e.kind) ? e.kind : We,
|
|
281
|
+
startPlayerId: e.startPlayerId,
|
|
282
|
+
waypoints: u(e.waypoints, 32, te),
|
|
283
|
+
end: r,
|
|
284
|
+
interpolation: qe(e.interpolation) ? e.interpolation : Ge,
|
|
285
|
+
...c(e.color) ? { color: e.color } : {},
|
|
286
|
+
...Je(e.thickness) ? { thickness: e.thickness } : {}
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
function Xe(e, t) {
|
|
290
|
+
return u(e, 128, (e, n) => Ye(e, n, t));
|
|
291
|
+
}
|
|
292
|
+
function Ze(e) {
|
|
293
|
+
return {
|
|
294
|
+
id: e.id,
|
|
295
|
+
kind: e.kind,
|
|
296
|
+
startPlayerId: e.startPlayerId,
|
|
297
|
+
waypoints: e.waypoints.map((e) => ({ ...e })),
|
|
298
|
+
end: { ...e.end },
|
|
299
|
+
interpolation: e.interpolation,
|
|
300
|
+
...e.color === void 0 ? {} : { color: e.color },
|
|
301
|
+
...e.thickness === void 0 ? {} : { thickness: e.thickness }
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
function Qe(e, t) {
|
|
305
|
+
let n = t.get(e.startPlayerId);
|
|
306
|
+
if (n !== void 0) return [
|
|
307
|
+
{ ...n.position },
|
|
308
|
+
...e.waypoints.map((e) => ({ ...e })),
|
|
309
|
+
{ ...e.end }
|
|
310
|
+
];
|
|
311
|
+
}
|
|
312
|
+
function $e(e) {
|
|
313
|
+
let t = /* @__PURE__ */ new Map();
|
|
314
|
+
for (let n of e) t.set(n.id, n);
|
|
315
|
+
return t;
|
|
316
|
+
}
|
|
317
|
+
// src/common/model/play-data.ts
|
|
318
|
+
var et = [
|
|
319
|
+
"own-redzone",
|
|
320
|
+
"middle",
|
|
321
|
+
"redzone"
|
|
322
|
+
], tt = "middle", nt = {
|
|
323
|
+
"own-redzone": "自陣RZ",
|
|
324
|
+
middle: "中央",
|
|
325
|
+
redzone: "相手RZ"
|
|
326
|
+
}, rt = {
|
|
327
|
+
"own-redzone": 10,
|
|
328
|
+
middle: 50,
|
|
329
|
+
redzone: 85
|
|
330
|
+
}, it = 2;
|
|
331
|
+
function at(e) {
|
|
332
|
+
return l(e, et);
|
|
333
|
+
}
|
|
334
|
+
function v(e) {
|
|
335
|
+
return {
|
|
336
|
+
zone: e,
|
|
337
|
+
losYard: rt[e]
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
function ot(e) {
|
|
341
|
+
return {
|
|
342
|
+
version: 2,
|
|
343
|
+
field: { ...e.field },
|
|
344
|
+
players: e.players.map(ie),
|
|
345
|
+
lines: e.lines.map(Ze)
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
function st(e) {
|
|
349
|
+
let t = o(e) ? e : {}, n = o(t.field) ? t.field.zone : void 0, r = ct(re(t.players)), i = new Set(r.map((e) => e.id));
|
|
350
|
+
return {
|
|
351
|
+
version: 2,
|
|
352
|
+
field: v(at(n) ? n : tt),
|
|
353
|
+
players: r,
|
|
354
|
+
lines: ct(Xe(t.lines, i))
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
function ct(e) {
|
|
358
|
+
let t = new Set(e.map((e) => e.id)), n = /* @__PURE__ */ new Set();
|
|
359
|
+
return e.map((e) => {
|
|
360
|
+
if (!n.has(e.id)) return n.add(e.id), e;
|
|
361
|
+
let r = 2;
|
|
362
|
+
for (; t.has(`${e.id}-${r}`);) r += 1;
|
|
363
|
+
let i = `${e.id}-${r}`;
|
|
364
|
+
return t.add(i), n.add(i), {
|
|
365
|
+
...e,
|
|
366
|
+
id: i
|
|
367
|
+
};
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
function y(e, t) {
|
|
371
|
+
if (!o(e)) return e;
|
|
372
|
+
let { absoluteYard: n, ...r } = e;
|
|
373
|
+
return s(n) ? {
|
|
374
|
+
...r,
|
|
375
|
+
downfieldYard: n - t
|
|
376
|
+
} : e;
|
|
377
|
+
}
|
|
378
|
+
function lt(e, t) {
|
|
379
|
+
return o(e) ? {
|
|
380
|
+
...e,
|
|
381
|
+
position: y(e.position, t)
|
|
382
|
+
} : e;
|
|
383
|
+
}
|
|
384
|
+
function ut(e, t) {
|
|
385
|
+
return o(e) ? {
|
|
386
|
+
...e,
|
|
387
|
+
waypoints: Array.isArray(e.waypoints) ? e.waypoints.slice(0, 32).map((e) => y(e, t)) : e.waypoints,
|
|
388
|
+
end: y(e.end, t),
|
|
389
|
+
thickness: s(e.thickness) ? e.thickness / 2 : e.thickness
|
|
390
|
+
} : e;
|
|
391
|
+
}
|
|
392
|
+
function dt(e) {
|
|
393
|
+
let t = v(o(e.field) && at(e.field.zone) ? e.field.zone : tt), { losYard: n } = t;
|
|
394
|
+
return {
|
|
395
|
+
...e,
|
|
396
|
+
field: t,
|
|
397
|
+
players: Array.isArray(e.players) ? e.players.slice(0, 64).map((e) => lt(e, n)) : e.players,
|
|
398
|
+
lines: Array.isArray(e.lines) ? e.lines.slice(0, 128).map((e) => ut(e, n)) : e.lines
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
// src/common/model/migration.ts
|
|
402
|
+
var ft = [{
|
|
403
|
+
to: 2,
|
|
404
|
+
migrate: dt
|
|
405
|
+
}];
|
|
406
|
+
function pt(e) {
|
|
407
|
+
return o(e) && s(e.version) ? e.version : 0;
|
|
408
|
+
}
|
|
409
|
+
function mt(e, t, n) {
|
|
410
|
+
if (!o(e)) return e;
|
|
411
|
+
let r = e;
|
|
412
|
+
for (let e of n) e.to > t && (r = e.migrate(r));
|
|
413
|
+
return r;
|
|
414
|
+
}
|
|
415
|
+
function ht(e) {
|
|
416
|
+
return st(mt(e, pt(e), ft));
|
|
417
|
+
}
|
|
418
|
+
// src/common/model/play-model.ts
|
|
419
|
+
function b(e, t, n, r) {
|
|
420
|
+
if (!Number.isInteger(t) || t < 0 || t > e.length) throw Error(`PlayModel: ${r} index out of range: ${t} (0..${e.length})`);
|
|
421
|
+
return [
|
|
422
|
+
...e.slice(0, t),
|
|
423
|
+
n,
|
|
424
|
+
...e.slice(t)
|
|
425
|
+
];
|
|
426
|
+
}
|
|
427
|
+
function gt(e, t, n) {
|
|
428
|
+
if (e.some((e) => e.id === t)) throw Error(`${n} "${t}"`);
|
|
429
|
+
}
|
|
430
|
+
function x(e, t, n) {
|
|
431
|
+
if (e > t) throw Error(`PlayModel: too many ${n}: ${e} > ${t}`);
|
|
432
|
+
}
|
|
433
|
+
function _t(e) {
|
|
434
|
+
x(e.players.length, 64, "players"), x(e.lines.length, 128, "lines");
|
|
435
|
+
for (let t of e.lines) x(t.waypoints.length, 32, "waypoints");
|
|
436
|
+
}
|
|
437
|
+
var vt = class extends n {
|
|
438
|
+
_onDidChange = this._register(new _());
|
|
439
|
+
onDidChange = this._onDidChange.event;
|
|
440
|
+
state;
|
|
441
|
+
constructor(e) {
|
|
442
|
+
super(), this.state = ht(e);
|
|
443
|
+
}
|
|
444
|
+
getData() {
|
|
445
|
+
return ot(this.state);
|
|
446
|
+
}
|
|
447
|
+
getSnapshot() {
|
|
448
|
+
return this.state;
|
|
449
|
+
}
|
|
450
|
+
getFieldZone() {
|
|
451
|
+
return this.state.field.zone;
|
|
452
|
+
}
|
|
453
|
+
findPlayer(e) {
|
|
454
|
+
return this.state.players.find((t) => t.id === e);
|
|
455
|
+
}
|
|
456
|
+
findLine(e) {
|
|
457
|
+
return this.state.lines.find((t) => t.id === e);
|
|
458
|
+
}
|
|
459
|
+
getPlayer(e) {
|
|
460
|
+
let t = this.findPlayer(e);
|
|
461
|
+
if (t === void 0) throw Error(`PlayModel: unknown player id "${e}"`);
|
|
462
|
+
return t;
|
|
463
|
+
}
|
|
464
|
+
getLine(e) {
|
|
465
|
+
let t = this.findLine(e);
|
|
466
|
+
if (t === void 0) throw Error(`PlayModel: unknown line id "${e}"`);
|
|
467
|
+
return t;
|
|
468
|
+
}
|
|
469
|
+
setFieldZone(e) {
|
|
470
|
+
this.commit({
|
|
471
|
+
...this.state,
|
|
472
|
+
field: v(e)
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
addPlayer(e) {
|
|
476
|
+
this.addPlayers([e]);
|
|
477
|
+
}
|
|
478
|
+
addPlayers(e) {
|
|
479
|
+
let t = new Set(this.state.players.map((e) => e.id));
|
|
480
|
+
for (let n of e) {
|
|
481
|
+
if (t.has(n.id)) throw Error(`PlayModel.addPlayers: duplicate player id "${n.id}"`);
|
|
482
|
+
t.add(n.id);
|
|
483
|
+
}
|
|
484
|
+
this.commit({
|
|
485
|
+
...this.state,
|
|
486
|
+
players: [...this.state.players, ...e]
|
|
487
|
+
});
|
|
488
|
+
}
|
|
489
|
+
removePlayerCore(e) {
|
|
490
|
+
let t = this.state.players.find((t) => t.id === e);
|
|
491
|
+
if (t === void 0) throw Error(`PlayModel.removePlayer: unknown player id "${e}"`);
|
|
492
|
+
let n = this.state.players.indexOf(t), r = [], i = [];
|
|
493
|
+
return this.state.lines.forEach((t, n) => {
|
|
494
|
+
t.startPlayerId === e ? r.push({
|
|
495
|
+
line: t,
|
|
496
|
+
index: n
|
|
497
|
+
}) : i.push(t);
|
|
498
|
+
}), this.state = {
|
|
499
|
+
...this.state,
|
|
500
|
+
players: this.state.players.filter((e) => e !== t),
|
|
501
|
+
lines: i
|
|
502
|
+
}, {
|
|
503
|
+
player: t,
|
|
504
|
+
index: n,
|
|
505
|
+
removedLines: r
|
|
506
|
+
};
|
|
507
|
+
}
|
|
508
|
+
removePlayer(e) {
|
|
509
|
+
let t = this.removePlayerCore(e);
|
|
510
|
+
return this.emitChange(), t;
|
|
511
|
+
}
|
|
512
|
+
removePlayers(e) {
|
|
513
|
+
let t = new Set(this.state.players.map((e) => e.id));
|
|
514
|
+
for (let n of e) if (!t.delete(n)) throw Error(`PlayModel.removePlayers: unknown or repeated player id "${n}"`);
|
|
515
|
+
let n = e.map((e) => this.removePlayerCore(e));
|
|
516
|
+
return this.emitChange(), n;
|
|
517
|
+
}
|
|
518
|
+
restorePlayer(e) {
|
|
519
|
+
gt(this.state.players, e.player.id, "PlayModel.restorePlayer: duplicate player id");
|
|
520
|
+
let t = b(this.state.players, e.index, e.player, "player"), n = this.state.lines;
|
|
521
|
+
for (let { line: t, index: r } of [...e.removedLines].sort((e, t) => e.index - t.index)) n = b(n, r, t, "line");
|
|
522
|
+
this.commit({
|
|
523
|
+
...this.state,
|
|
524
|
+
players: t,
|
|
525
|
+
lines: n
|
|
526
|
+
});
|
|
527
|
+
}
|
|
528
|
+
updatePlayer(e) {
|
|
529
|
+
let t = this.getPlayer(e.id);
|
|
530
|
+
return this.commit({
|
|
531
|
+
...this.state,
|
|
532
|
+
players: this.state.players.map((n) => n === t ? e : n)
|
|
533
|
+
}), t;
|
|
534
|
+
}
|
|
535
|
+
addLine(e) {
|
|
536
|
+
this.insertLine(e, this.state.lines.length);
|
|
537
|
+
}
|
|
538
|
+
insertLine(e, t) {
|
|
539
|
+
gt(this.state.lines, e.id, "PlayModel: duplicate line id"), this.commit({
|
|
540
|
+
...this.state,
|
|
541
|
+
lines: b(this.state.lines, t, e, "line")
|
|
542
|
+
});
|
|
543
|
+
}
|
|
544
|
+
removeLine(e) {
|
|
545
|
+
let t = this.state.lines.find((t) => t.id === e);
|
|
546
|
+
if (t === void 0) throw Error(`PlayModel.removeLine: unknown line id "${e}"`);
|
|
547
|
+
let n = this.state.lines.indexOf(t);
|
|
548
|
+
return this.commit({
|
|
549
|
+
...this.state,
|
|
550
|
+
lines: this.state.lines.filter((e) => e !== t)
|
|
551
|
+
}), {
|
|
552
|
+
line: t,
|
|
553
|
+
index: n
|
|
554
|
+
};
|
|
555
|
+
}
|
|
556
|
+
updateLine(e) {
|
|
557
|
+
let t = this.getLine(e.id);
|
|
558
|
+
return this.commit({
|
|
559
|
+
...this.state,
|
|
560
|
+
lines: this.state.lines.map((n) => n === t ? e : n)
|
|
561
|
+
}), t;
|
|
562
|
+
}
|
|
563
|
+
commit(e) {
|
|
564
|
+
_t(e), this.state = e, this.emitChange();
|
|
565
|
+
}
|
|
566
|
+
emitChange() {
|
|
567
|
+
this._onDidChange.fire(this.state);
|
|
568
|
+
}
|
|
569
|
+
};
|
|
570
|
+
// src/common/commands/command.ts
|
|
571
|
+
function S(e, t) {
|
|
572
|
+
/* v8 ignore start -- 履歴は apply が済んだコマンドしか積まないので、編集の操作からは届かない。 */
|
|
573
|
+
if (e === void 0) throw Error(`${t.label}: apply より前に undo された`);
|
|
574
|
+
/* v8 ignore stop */
|
|
575
|
+
return e;
|
|
576
|
+
}
|
|
577
|
+
// src/common/commands/field-commands.ts
|
|
578
|
+
var yt = class {
|
|
579
|
+
label = "フィールドゾーンの切替";
|
|
580
|
+
zone;
|
|
581
|
+
previous;
|
|
582
|
+
constructor(e) {
|
|
583
|
+
this.zone = e;
|
|
584
|
+
}
|
|
585
|
+
apply(e) {
|
|
586
|
+
return this.previous = e.getFieldZone(), this.previous !== this.zone && (e.setFieldZone(this.zone), !0);
|
|
587
|
+
}
|
|
588
|
+
undo(e) {
|
|
589
|
+
e.setFieldZone(S(this.previous, this));
|
|
590
|
+
}
|
|
591
|
+
}, bt = class {
|
|
592
|
+
label = "フォーメーションの読み込み";
|
|
593
|
+
players;
|
|
594
|
+
constructor(e) {
|
|
595
|
+
this.players = e;
|
|
596
|
+
}
|
|
597
|
+
apply(e) {
|
|
598
|
+
return this.players.length !== 0 && (e.addPlayers(this.players), !0);
|
|
599
|
+
}
|
|
600
|
+
undo(e) {
|
|
601
|
+
e.removePlayers(this.players.map((e) => e.id));
|
|
602
|
+
}
|
|
603
|
+
};
|
|
604
|
+
// src/common/commands/patch.ts
|
|
605
|
+
function xt(e) {
|
|
606
|
+
return e;
|
|
607
|
+
}
|
|
608
|
+
function St(e, t) {
|
|
609
|
+
let n = { ...xt(e) };
|
|
610
|
+
for (let [e, r] of Object.entries(t)) r === null ? delete n[e] : n[e] = r;
|
|
611
|
+
return n;
|
|
612
|
+
}
|
|
613
|
+
function Ct(e, t) {
|
|
614
|
+
let n = xt(e);
|
|
615
|
+
return Object.entries(t).some(([e, t]) => (t ?? void 0) !== n[e]);
|
|
616
|
+
}
|
|
617
|
+
// src/common/commands/line-commands.ts
|
|
618
|
+
function wt(e, t) {
|
|
619
|
+
return St(e, t);
|
|
620
|
+
}
|
|
621
|
+
var Tt = class {
|
|
622
|
+
label = "線の追加";
|
|
623
|
+
line;
|
|
624
|
+
constructor(e) {
|
|
625
|
+
this.line = e;
|
|
626
|
+
}
|
|
627
|
+
apply(e) {
|
|
628
|
+
return e.addLine(this.line), !0;
|
|
629
|
+
}
|
|
630
|
+
undo(e) {
|
|
631
|
+
e.removeLine(this.line.id);
|
|
632
|
+
}
|
|
633
|
+
}, Et = class {
|
|
634
|
+
label = "線の削除";
|
|
635
|
+
lineId;
|
|
636
|
+
removal;
|
|
637
|
+
constructor(e) {
|
|
638
|
+
this.lineId = e;
|
|
639
|
+
}
|
|
640
|
+
apply(e) {
|
|
641
|
+
return this.removal = e.removeLine(this.lineId), !0;
|
|
642
|
+
}
|
|
643
|
+
undo(e) {
|
|
644
|
+
let { line: t, index: n } = S(this.removal, this);
|
|
645
|
+
e.insertLine(t, n);
|
|
646
|
+
}
|
|
647
|
+
}, Dt = class {
|
|
648
|
+
label = "線の編集";
|
|
649
|
+
lineId;
|
|
650
|
+
patch;
|
|
651
|
+
previous;
|
|
652
|
+
constructor(e, t) {
|
|
653
|
+
this.lineId = e, this.patch = { ...t };
|
|
654
|
+
}
|
|
655
|
+
apply(e) {
|
|
656
|
+
let t = e.getLine(this.lineId);
|
|
657
|
+
return Ct(t, this.patch) ? (this.previous = e.updateLine(wt(t, this.patch)), !0) : !1;
|
|
658
|
+
}
|
|
659
|
+
undo(e) {
|
|
660
|
+
e.updateLine(S(this.previous, this));
|
|
661
|
+
}
|
|
662
|
+
};
|
|
663
|
+
// src/common/commands/player-commands.ts
|
|
664
|
+
function Ot(e, t) {
|
|
665
|
+
return St(e, t);
|
|
666
|
+
}
|
|
667
|
+
var kt = class {
|
|
668
|
+
label = "選手の追加";
|
|
669
|
+
player;
|
|
670
|
+
constructor(e) {
|
|
671
|
+
this.player = e;
|
|
672
|
+
}
|
|
673
|
+
apply(e) {
|
|
674
|
+
return e.addPlayer(this.player), !0;
|
|
675
|
+
}
|
|
676
|
+
undo(e) {
|
|
677
|
+
e.removePlayer(this.player.id);
|
|
678
|
+
}
|
|
679
|
+
}, At = class {
|
|
680
|
+
label = "選手の削除";
|
|
681
|
+
playerId;
|
|
682
|
+
removal;
|
|
683
|
+
constructor(e) {
|
|
684
|
+
this.playerId = e;
|
|
685
|
+
}
|
|
686
|
+
apply(e) {
|
|
687
|
+
return this.removal = e.removePlayer(this.playerId), !0;
|
|
688
|
+
}
|
|
689
|
+
undo(e) {
|
|
690
|
+
e.restorePlayer(S(this.removal, this));
|
|
691
|
+
}
|
|
692
|
+
}, jt = class {
|
|
693
|
+
label = "選手の編集";
|
|
694
|
+
playerId;
|
|
695
|
+
patch;
|
|
696
|
+
previous;
|
|
697
|
+
constructor(e, t) {
|
|
698
|
+
this.playerId = e, this.patch = { ...t };
|
|
699
|
+
}
|
|
700
|
+
apply(e) {
|
|
701
|
+
let t = e.getPlayer(this.playerId);
|
|
702
|
+
return Ct(t, this.patch) ? (this.previous = e.updatePlayer(Ot(t, this.patch)), !0) : !1;
|
|
703
|
+
}
|
|
704
|
+
undo(e) {
|
|
705
|
+
e.updatePlayer(S(this.previous, this));
|
|
706
|
+
}
|
|
707
|
+
}, Mt = 53, Nt = {
|
|
708
|
+
ncaa: 6.5,
|
|
709
|
+
nfl: 3,
|
|
710
|
+
nfhs: 9
|
|
711
|
+
}, Pt = "ncaa";
|
|
712
|
+
function C(e) {
|
|
713
|
+
switch (e) {
|
|
714
|
+
case "own-redzone": return {
|
|
715
|
+
startYard: -10,
|
|
716
|
+
endYard: 25
|
|
717
|
+
};
|
|
718
|
+
case "redzone": return {
|
|
719
|
+
startYard: 75,
|
|
720
|
+
endYard: 110
|
|
721
|
+
};
|
|
722
|
+
case "middle": return {
|
|
723
|
+
startYard: 35,
|
|
724
|
+
endYard: 65
|
|
725
|
+
};
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
function Ft(e) {
|
|
729
|
+
let { startYard: t, endYard: n } = C(e);
|
|
730
|
+
return n - t;
|
|
731
|
+
}
|
|
732
|
+
function It(e) {
|
|
733
|
+
return 53 / Ft(e);
|
|
734
|
+
}
|
|
735
|
+
function Lt(e, t) {
|
|
736
|
+
let { startYard: n, endYard: r } = C(t.zone);
|
|
737
|
+
return {
|
|
738
|
+
lateralYard: Math.min(Math.max(e.lateralYard, 0), 53),
|
|
739
|
+
downfieldYard: Math.min(Math.max(e.downfieldYard, n - t.losYard), r - t.losYard)
|
|
740
|
+
};
|
|
741
|
+
}
|
|
742
|
+
function Rt(e) {
|
|
743
|
+
return e <= 0 || e >= 100 ? null : 50 - Math.abs(50 - e);
|
|
744
|
+
}
|
|
745
|
+
function w(e, t) {
|
|
746
|
+
if (t <= 0) throw Error("Playmaker: stepYards は正の数である必要があります。");
|
|
747
|
+
let { startYard: n, endYard: r } = C(e), i = [], a = Math.ceil(n / t) * t;
|
|
748
|
+
for (let e = a; e <= r + 1e-9; e += t) i.push(e);
|
|
749
|
+
return i;
|
|
750
|
+
}
|
|
751
|
+
var zt = class {
|
|
752
|
+
viewportWidth;
|
|
753
|
+
viewportHeight;
|
|
754
|
+
zone;
|
|
755
|
+
losYard;
|
|
756
|
+
yardWindow;
|
|
757
|
+
scale;
|
|
758
|
+
fieldPixelWidth;
|
|
759
|
+
fieldPixelHeight;
|
|
760
|
+
offsetX;
|
|
761
|
+
offsetY;
|
|
762
|
+
constructor(e, t, n) {
|
|
763
|
+
this.viewportWidth = e, this.viewportHeight = t, this.zone = n.zone, this.losYard = n.losYard, this.yardWindow = C(n.zone);
|
|
764
|
+
let r = this.yardWindow.endYard - this.yardWindow.startYard, i = Math.max(0, e), a = Math.max(0, t);
|
|
765
|
+
this.scale = Math.min(i / 53, a / r), this.fieldPixelWidth = 53 * this.scale, this.fieldPixelHeight = r * this.scale, this.offsetX = (i - this.fieldPixelWidth) / 2, this.offsetY = (a - this.fieldPixelHeight) / 2;
|
|
766
|
+
}
|
|
767
|
+
xForLateralYard(e) {
|
|
768
|
+
return this.offsetX + e * this.scale;
|
|
769
|
+
}
|
|
770
|
+
yForAbsoluteYard(e) {
|
|
771
|
+
return this.offsetY + (this.yardWindow.endYard - e) * this.scale;
|
|
772
|
+
}
|
|
773
|
+
toCanvas(e) {
|
|
774
|
+
return {
|
|
775
|
+
x: this.xForLateralYard(e.lateralYard),
|
|
776
|
+
y: this.yForAbsoluteYard(this.losYard + e.downfieldYard)
|
|
777
|
+
};
|
|
778
|
+
}
|
|
779
|
+
lateralYardForX(e) {
|
|
780
|
+
return this.scale > 0 ? (e - this.offsetX) / this.scale : 0;
|
|
781
|
+
}
|
|
782
|
+
absoluteYardForY(e) {
|
|
783
|
+
return this.scale > 0 ? this.yardWindow.endYard - (e - this.offsetY) / this.scale : this.yardWindow.endYard;
|
|
784
|
+
}
|
|
785
|
+
fromCanvas(e) {
|
|
786
|
+
return {
|
|
787
|
+
lateralYard: this.lateralYardForX(e.x),
|
|
788
|
+
downfieldYard: this.absoluteYardForY(e.y) - this.losYard
|
|
789
|
+
};
|
|
790
|
+
}
|
|
791
|
+
containsYard(e) {
|
|
792
|
+
return e >= this.yardWindow.startYard && e <= this.yardWindow.endYard;
|
|
793
|
+
}
|
|
794
|
+
};
|
|
795
|
+
// src/common/geometry/polyline.ts
|
|
796
|
+
function* Bt(e) {
|
|
797
|
+
let t;
|
|
798
|
+
for (let n of e) t !== void 0 && (yield [t.point, n]), t = { point: n };
|
|
799
|
+
}
|
|
800
|
+
function Vt(e) {
|
|
801
|
+
let t = 0;
|
|
802
|
+
for (let [n, r] of Bt(e)) t += Math.hypot(r.x - n.x, r.y - n.y);
|
|
803
|
+
return t;
|
|
804
|
+
}
|
|
805
|
+
function Ht(e, t, n = 1) {
|
|
806
|
+
if (e.length < 2 || t <= 0) return [...e];
|
|
807
|
+
let r = n >= 1 ? t : Math.min(t, Vt(e) * n);
|
|
808
|
+
if (r <= 0) return [...e];
|
|
809
|
+
for (let t = e.length - 1; t > 0; t--) {
|
|
810
|
+
let n = e[t - 1], i = e[t];
|
|
811
|
+
/* v8 ignore start -- i は 1 から path.length - 1 までなので、a も b も範囲の内側にある。 */
|
|
812
|
+
if (n === void 0 || i === void 0) break;
|
|
813
|
+
/* v8 ignore stop */
|
|
814
|
+
let a = Math.hypot(i.x - n.x, i.y - n.y);
|
|
815
|
+
if (a > r) {
|
|
816
|
+
let o = (a - r) / a;
|
|
817
|
+
return [...e.slice(0, t), {
|
|
818
|
+
x: n.x + (i.x - n.x) * o,
|
|
819
|
+
y: n.y + (i.y - n.y) * o
|
|
820
|
+
}];
|
|
821
|
+
}
|
|
822
|
+
r -= a;
|
|
823
|
+
}
|
|
824
|
+
return e.slice(0, 1);
|
|
825
|
+
}
|
|
826
|
+
function Ut(e, t, n, r, i) {
|
|
827
|
+
let a = 1 - i, o = a * a * a, s = 3 * a * a * i, c = 3 * a * i * i, l = i * i * i;
|
|
828
|
+
return {
|
|
829
|
+
lateralYard: o * e.lateralYard + s * t.lateralYard + c * n.lateralYard + l * r.lateralYard,
|
|
830
|
+
downfieldYard: o * e.downfieldYard + s * t.downfieldYard + c * n.downfieldYard + l * r.downfieldYard
|
|
831
|
+
};
|
|
832
|
+
}
|
|
833
|
+
function Wt(e, t, n, r) {
|
|
834
|
+
return [{
|
|
835
|
+
lateralYard: t.lateralYard + (n.lateralYard - e.lateralYard) / 6,
|
|
836
|
+
downfieldYard: t.downfieldYard + (n.downfieldYard - e.downfieldYard) / 6
|
|
837
|
+
}, {
|
|
838
|
+
lateralYard: n.lateralYard - (r.lateralYard - t.lateralYard) / 6,
|
|
839
|
+
downfieldYard: n.downfieldYard - (r.downfieldYard - t.downfieldYard) / 6
|
|
840
|
+
}];
|
|
841
|
+
}
|
|
842
|
+
function Gt(e) {
|
|
843
|
+
let t = [];
|
|
844
|
+
for (let n of e) {
|
|
845
|
+
let e = t[t.length - 1];
|
|
846
|
+
(e === void 0 || e.lateralYard !== n.lateralYard || e.downfieldYard !== n.downfieldYard) && t.push({
|
|
847
|
+
lateralYard: n.lateralYard,
|
|
848
|
+
downfieldYard: n.downfieldYard
|
|
849
|
+
});
|
|
850
|
+
}
|
|
851
|
+
return t;
|
|
852
|
+
}
|
|
853
|
+
function Kt(e, t, n = 16) {
|
|
854
|
+
let r = Gt(e);
|
|
855
|
+
if (t === "straight" || r.length < 3) return r;
|
|
856
|
+
let i = Math.max(1, Math.floor(n)), a = r.slice(0, 1);
|
|
857
|
+
for (let [e, [t, n]] of [...Bt(r)].entries()) {
|
|
858
|
+
let [o, s] = Wt(r[e - 1] ?? t, t, n, r[e + 2] ?? n);
|
|
859
|
+
for (let e = 1; e <= i; e++) a.push(Ut(t, o, s, n, e / i));
|
|
860
|
+
}
|
|
861
|
+
return a;
|
|
862
|
+
}
|
|
863
|
+
// src/common/geometry/hit-test.ts
|
|
864
|
+
function qt(e, t, n = m) {
|
|
865
|
+
if (n <= 0) throw Error("Playmaker: radiusYards は正の数である必要があります。");
|
|
866
|
+
let r = n * n;
|
|
867
|
+
for (let n of [...e].reverse()) {
|
|
868
|
+
let e = n.position.lateralYard - t.lateralYard, i = n.position.downfieldYard - t.downfieldYard;
|
|
869
|
+
if (e * e + i * i <= r) return n;
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
var Jt = .6;
|
|
873
|
+
function Yt(e, t, n) {
|
|
874
|
+
let r = n.lateralYard - t.lateralYard, i = n.downfieldYard - t.downfieldYard, a = e.lateralYard - t.lateralYard, o = e.downfieldYard - t.downfieldYard, s = r * r + i * i, c = s > 0 ? Math.max(0, Math.min(1, (a * r + o * i) / s)) : 0, l = a - c * r, u = o - c * i;
|
|
875
|
+
return Math.sqrt(l * l + u * u);
|
|
876
|
+
}
|
|
877
|
+
function Xt(e, t) {
|
|
878
|
+
let n = t.length === 1 ? t[0] : void 0;
|
|
879
|
+
if (n !== void 0) return $t(e, n);
|
|
880
|
+
let r = Infinity;
|
|
881
|
+
for (let [n, i] of Bt(t)) r = Math.min(r, Yt(e, n, i));
|
|
882
|
+
return r;
|
|
883
|
+
}
|
|
884
|
+
function Zt(e, t, n, r = Jt) {
|
|
885
|
+
if (r <= 0) throw Error("Playmaker: toleranceYards は正の数である必要があります。");
|
|
886
|
+
let i = $e(t);
|
|
887
|
+
for (let t of [...e].reverse()) {
|
|
888
|
+
let e = Qe(t, i);
|
|
889
|
+
if (e !== void 0 && Xt(n, Kt(e, t.interpolation)) <= r) return t;
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
var Qt = .9;
|
|
893
|
+
function $t(e, t) {
|
|
894
|
+
return Math.hypot(e.lateralYard - t.lateralYard, e.downfieldYard - t.downfieldYard);
|
|
895
|
+
}
|
|
896
|
+
function en(e, t) {
|
|
897
|
+
let n = (e) => $t(t, e) <= Qt;
|
|
898
|
+
if (n(e.end)) return {
|
|
899
|
+
kind: "endpoint",
|
|
900
|
+
point: e.end
|
|
901
|
+
};
|
|
902
|
+
for (let [t, r] of [...e.waypoints.entries()].reverse()) if (n(r)) return {
|
|
903
|
+
kind: "waypoint",
|
|
904
|
+
index: t,
|
|
905
|
+
point: r
|
|
906
|
+
};
|
|
907
|
+
}
|
|
908
|
+
// src/common/editing/editor-notifier.ts
|
|
909
|
+
var tn = {
|
|
910
|
+
tool: Object.is,
|
|
911
|
+
selection: Ae,
|
|
912
|
+
canUndo: Object.is,
|
|
913
|
+
canRedo: Object.is,
|
|
914
|
+
fieldZone: Object.is,
|
|
915
|
+
isDrawing: Object.is,
|
|
916
|
+
remainingPlayerSlots: Object.is,
|
|
917
|
+
canStartLine: Object.is
|
|
918
|
+
}, nn = Object.keys(tn);
|
|
919
|
+
function rn(e, t, n) {
|
|
920
|
+
return tn[e](t[e], n[e]);
|
|
921
|
+
}
|
|
922
|
+
function an(e, t) {
|
|
923
|
+
return nn.every((n) => rn(n, e.state, t.state)) && e.player === t.player && e.line === t.line;
|
|
924
|
+
}
|
|
925
|
+
var on = class extends n {
|
|
926
|
+
_onDidChangeScene = this._register(new _());
|
|
927
|
+
onDidChangeScene = this._onDidChangeScene.event;
|
|
928
|
+
_onDidChangeViewState = this._register(new _());
|
|
929
|
+
onDidChangeViewState = this._onDidChangeViewState.event;
|
|
930
|
+
readView;
|
|
931
|
+
depth = 0;
|
|
932
|
+
sceneChanged = !1;
|
|
933
|
+
lastView;
|
|
934
|
+
constructor(e) {
|
|
935
|
+
super(), this.readView = e, this.lastView = e();
|
|
936
|
+
}
|
|
937
|
+
batch(e) {
|
|
938
|
+
this.depth++;
|
|
939
|
+
let t;
|
|
940
|
+
try {
|
|
941
|
+
t = e();
|
|
942
|
+
} finally {
|
|
943
|
+
this.depth--;
|
|
944
|
+
}
|
|
945
|
+
return this.flushIfIdle(), t;
|
|
946
|
+
}
|
|
947
|
+
markSceneChanged() {
|
|
948
|
+
this.sceneChanged = !0, this.flushIfIdle();
|
|
949
|
+
}
|
|
950
|
+
flushIfIdle() {
|
|
951
|
+
this.depth === 0 && this.flush();
|
|
952
|
+
}
|
|
953
|
+
flush() {
|
|
954
|
+
this.sceneChanged && (this.sceneChanged = !1, this._onDidChangeScene.fire());
|
|
955
|
+
let e = this.readView();
|
|
956
|
+
an(e, this.lastView) || (this.lastView = e, this._onDidChangeViewState.fire());
|
|
957
|
+
}
|
|
958
|
+
};
|
|
959
|
+
// src/common/editing/interaction.ts
|
|
960
|
+
function T(e, t) {
|
|
961
|
+
return e.lateralYard === t.lateralYard && e.downfieldYard === t.downfieldYard;
|
|
962
|
+
}
|
|
963
|
+
var sn = 33;
|
|
964
|
+
function cn(e, t, n) {
|
|
965
|
+
return {
|
|
966
|
+
type: "drag",
|
|
967
|
+
target: e,
|
|
968
|
+
origin: t,
|
|
969
|
+
grabOffset: {
|
|
970
|
+
lateralYard: t.lateralYard - n.lateralYard,
|
|
971
|
+
downfieldYard: t.downfieldYard - n.downfieldYard
|
|
972
|
+
},
|
|
973
|
+
current: t
|
|
974
|
+
};
|
|
975
|
+
}
|
|
976
|
+
function ln(e, t) {
|
|
977
|
+
return {
|
|
978
|
+
lateralYard: t.lateralYard + e.grabOffset.lateralYard,
|
|
979
|
+
downfieldYard: t.downfieldYard + e.grabOffset.downfieldYard
|
|
980
|
+
};
|
|
981
|
+
}
|
|
982
|
+
function un(e, t, n) {
|
|
983
|
+
switch (t.kind) {
|
|
984
|
+
case "player": return e.players.some((e) => e.id === t.playerId) ? {
|
|
985
|
+
kind: "player",
|
|
986
|
+
playerId: t.playerId,
|
|
987
|
+
patch: { position: n }
|
|
988
|
+
} : void 0;
|
|
989
|
+
case "endpoint": return e.lines.some((e) => e.id === t.lineId) ? {
|
|
990
|
+
kind: "line",
|
|
991
|
+
lineId: t.lineId,
|
|
992
|
+
patch: { end: n }
|
|
993
|
+
} : void 0;
|
|
994
|
+
case "waypoint": {
|
|
995
|
+
let r = e.lines.find((e) => e.id === t.lineId);
|
|
996
|
+
return r === void 0 ? void 0 : {
|
|
997
|
+
kind: "line",
|
|
998
|
+
lineId: r.id,
|
|
999
|
+
patch: { waypoints: r.waypoints.map((e, r) => r === t.index ? n : e) }
|
|
1000
|
+
};
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
function dn(e) {
|
|
1005
|
+
let t = e.at(-1);
|
|
1006
|
+
return t === void 0 ? void 0 : {
|
|
1007
|
+
waypoints: e.slice(0, -1),
|
|
1008
|
+
end: t
|
|
1009
|
+
};
|
|
1010
|
+
}
|
|
1011
|
+
function fn(e) {
|
|
1012
|
+
return {
|
|
1013
|
+
type: "draw-line",
|
|
1014
|
+
startPlayerId: e.id,
|
|
1015
|
+
start: e.position,
|
|
1016
|
+
points: [],
|
|
1017
|
+
cursor: e.position
|
|
1018
|
+
};
|
|
1019
|
+
}
|
|
1020
|
+
function pn(e, t) {
|
|
1021
|
+
let n = !T(e.points.at(-1) ?? e.start, t) && e.points.length < sn;
|
|
1022
|
+
return {
|
|
1023
|
+
...e,
|
|
1024
|
+
points: n ? [...e.points, t] : e.points,
|
|
1025
|
+
cursor: t
|
|
1026
|
+
};
|
|
1027
|
+
}
|
|
1028
|
+
function mn(e, t) {
|
|
1029
|
+
let n = dn(e.points);
|
|
1030
|
+
if (n !== void 0) return e.points.every((e) => T(e, t)) ? void 0 : n;
|
|
1031
|
+
}
|
|
1032
|
+
function hn(e, t, n) {
|
|
1033
|
+
return {
|
|
1034
|
+
id: t,
|
|
1035
|
+
kind: We,
|
|
1036
|
+
startPlayerId: e.startPlayerId,
|
|
1037
|
+
waypoints: n.waypoints,
|
|
1038
|
+
end: n.end,
|
|
1039
|
+
interpolation: Ge
|
|
1040
|
+
};
|
|
1041
|
+
}
|
|
1042
|
+
// src/common/editing/preview.ts
|
|
1043
|
+
var gn = "__playmaker_draft_line__";
|
|
1044
|
+
function _n(e, t) {
|
|
1045
|
+
switch (t.kind) {
|
|
1046
|
+
case "player": return {
|
|
1047
|
+
...e,
|
|
1048
|
+
players: e.players.map((e) => e.id === t.playerId ? Ot(e, t.patch) : e)
|
|
1049
|
+
};
|
|
1050
|
+
case "line": return {
|
|
1051
|
+
...e,
|
|
1052
|
+
lines: e.lines.map((e) => e.id === t.lineId ? wt(e, t.patch) : e)
|
|
1053
|
+
};
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
function vn(e) {
|
|
1057
|
+
return hn(e, gn, (e.points.length >= sn ? dn(e.points) : void 0) ?? {
|
|
1058
|
+
waypoints: e.points,
|
|
1059
|
+
end: e.cursor
|
|
1060
|
+
});
|
|
1061
|
+
}
|
|
1062
|
+
function yn(e, t) {
|
|
1063
|
+
if (t === void 0) return e;
|
|
1064
|
+
switch (t.type) {
|
|
1065
|
+
case "drag": {
|
|
1066
|
+
let n = un(e, t.target, t.current);
|
|
1067
|
+
return n === void 0 ? e : _n(e, n);
|
|
1068
|
+
}
|
|
1069
|
+
case "draw-line": return {
|
|
1070
|
+
...e,
|
|
1071
|
+
lines: [...e.lines, vn(t)]
|
|
1072
|
+
};
|
|
1073
|
+
}
|
|
1074
|
+
}
|
|
1075
|
+
function bn(e, t) {
|
|
1076
|
+
if (t.kind === "player") return {
|
|
1077
|
+
kind: "player",
|
|
1078
|
+
playerId: t.id
|
|
1079
|
+
};
|
|
1080
|
+
let n = t.kind === "line" ? e.lines.find((e) => e.id === t.id) : void 0;
|
|
1081
|
+
return n === void 0 ? { kind: "none" } : {
|
|
1082
|
+
kind: "line",
|
|
1083
|
+
waypointHandles: n.waypoints,
|
|
1084
|
+
endpointHandle: n.end
|
|
1085
|
+
};
|
|
1086
|
+
}
|
|
1087
|
+
// src/common/editing/editor-controller.ts
|
|
1088
|
+
var xn = class extends n {
|
|
1089
|
+
model;
|
|
1090
|
+
commands;
|
|
1091
|
+
ids;
|
|
1092
|
+
notifier;
|
|
1093
|
+
onDidChangeScene;
|
|
1094
|
+
onDidChangeViewState;
|
|
1095
|
+
tool = "select";
|
|
1096
|
+
selection = g;
|
|
1097
|
+
interaction;
|
|
1098
|
+
constructor(e, t, n) {
|
|
1099
|
+
super(), this.model = e, this.commands = t, this.ids = n, this.notifier = this._register(new on(() => ({
|
|
1100
|
+
state: this.getViewState(),
|
|
1101
|
+
player: this.getSelectedPlayer(),
|
|
1102
|
+
line: this.getSelectedLine()
|
|
1103
|
+
}))), this.onDidChangeScene = this.notifier.onDidChangeScene, this.onDidChangeViewState = this.notifier.onDidChangeViewState, this._register(this.model.onDidChange(() => this.notifier.markSceneChanged()));
|
|
1104
|
+
}
|
|
1105
|
+
getViewState() {
|
|
1106
|
+
let { players: e, lines: t } = this.model.getSnapshot();
|
|
1107
|
+
return {
|
|
1108
|
+
tool: this.tool,
|
|
1109
|
+
selection: this.getSelectedPlayer() === void 0 && this.getSelectedLine() === void 0 ? g : this.selection,
|
|
1110
|
+
canUndo: this.commands.canUndo,
|
|
1111
|
+
canRedo: this.commands.canRedo,
|
|
1112
|
+
fieldZone: this.model.getFieldZone(),
|
|
1113
|
+
isDrawing: this.interaction?.type === "draw-line",
|
|
1114
|
+
remainingPlayerSlots: 64 - e.length,
|
|
1115
|
+
canStartLine: t.length < 128
|
|
1116
|
+
};
|
|
1117
|
+
}
|
|
1118
|
+
getSelectedPlayer() {
|
|
1119
|
+
let e = this.selection;
|
|
1120
|
+
return e.kind === "player" ? this.model.findPlayer(e.id) : void 0;
|
|
1121
|
+
}
|
|
1122
|
+
getSelectedLine() {
|
|
1123
|
+
let e = this.selection;
|
|
1124
|
+
return e.kind === "line" ? this.model.findLine(e.id) : void 0;
|
|
1125
|
+
}
|
|
1126
|
+
getFrame() {
|
|
1127
|
+
let e = yn(this.model.getSnapshot(), this.interaction);
|
|
1128
|
+
return {
|
|
1129
|
+
scene: e,
|
|
1130
|
+
overlay: bn(e, this.selection)
|
|
1131
|
+
};
|
|
1132
|
+
}
|
|
1133
|
+
setTool(e) {
|
|
1134
|
+
e !== this.tool && this.notifier.batch(() => {
|
|
1135
|
+
this.tool = e, this.setInteraction(void 0);
|
|
1136
|
+
});
|
|
1137
|
+
}
|
|
1138
|
+
pointerDown(e) {
|
|
1139
|
+
this.notifier.batch(() => {
|
|
1140
|
+
switch (this.tool) {
|
|
1141
|
+
case "add-player":
|
|
1142
|
+
this.addPlayerAt(e);
|
|
1143
|
+
return;
|
|
1144
|
+
case "draw-line":
|
|
1145
|
+
this.drawLinePointerDown(e);
|
|
1146
|
+
return;
|
|
1147
|
+
case "select":
|
|
1148
|
+
this.selectPointerDown(e);
|
|
1149
|
+
return;
|
|
1150
|
+
}
|
|
1151
|
+
});
|
|
1152
|
+
}
|
|
1153
|
+
pointerMove(e) {
|
|
1154
|
+
let t = this.interaction;
|
|
1155
|
+
t !== void 0 && this.notifier.batch(() => this.setInteraction(t.type === "draw-line" ? {
|
|
1156
|
+
...t,
|
|
1157
|
+
cursor: this.clampToField(e)
|
|
1158
|
+
} : {
|
|
1159
|
+
...t,
|
|
1160
|
+
current: this.clampToField(ln(t, e))
|
|
1161
|
+
}));
|
|
1162
|
+
}
|
|
1163
|
+
pointerUp(e) {
|
|
1164
|
+
let t = this.interaction;
|
|
1165
|
+
t?.type === "drag" && this.notifier.batch(() => {
|
|
1166
|
+
this.setInteraction(void 0);
|
|
1167
|
+
let n = ln(t, e);
|
|
1168
|
+
if (T(n, t.origin)) return;
|
|
1169
|
+
let r = this.clampToField(n);
|
|
1170
|
+
if (T(r, t.origin)) return;
|
|
1171
|
+
let i = this.dropCommand(t, r);
|
|
1172
|
+
i !== void 0 && this.commands.execute(i);
|
|
1173
|
+
});
|
|
1174
|
+
}
|
|
1175
|
+
cancelInteraction() {
|
|
1176
|
+
this.notifier.batch(() => this.setInteraction(void 0));
|
|
1177
|
+
}
|
|
1178
|
+
commitLine() {
|
|
1179
|
+
let e = this.interaction;
|
|
1180
|
+
e?.type === "draw-line" && this.notifier.batch(() => {
|
|
1181
|
+
this.setInteraction(void 0);
|
|
1182
|
+
let t = this.lineFromDraft(e);
|
|
1183
|
+
t !== void 0 && (this.commands.execute(new Tt(t)), this.setTool("select"), this.setSelection({
|
|
1184
|
+
kind: "line",
|
|
1185
|
+
id: t.id
|
|
1186
|
+
}));
|
|
1187
|
+
});
|
|
1188
|
+
}
|
|
1189
|
+
deleteSelection() {
|
|
1190
|
+
let e = this.getSelectedPlayer(), t = this.getSelectedLine();
|
|
1191
|
+
this.notifier.batch(() => {
|
|
1192
|
+
if (e !== void 0) this.commands.execute(new At(e.id));
|
|
1193
|
+
else if (t !== void 0) this.commands.execute(new Et(t.id));
|
|
1194
|
+
else return;
|
|
1195
|
+
this.setSelection(g);
|
|
1196
|
+
});
|
|
1197
|
+
}
|
|
1198
|
+
updateSelectedPlayer(e) {
|
|
1199
|
+
let t = this.getSelectedPlayer();
|
|
1200
|
+
t !== void 0 && this.notifier.batch(() => this.commands.execute(new jt(t.id, e)));
|
|
1201
|
+
}
|
|
1202
|
+
updateSelectedLine(e) {
|
|
1203
|
+
let t = this.getSelectedLine();
|
|
1204
|
+
t !== void 0 && this.notifier.batch(() => this.commands.execute(new Dt(t.id, e)));
|
|
1205
|
+
}
|
|
1206
|
+
setFieldZone(e) {
|
|
1207
|
+
this.notifier.batch(() => {
|
|
1208
|
+
this.commands.execute(new yt(e)) && this.setInteraction(void 0);
|
|
1209
|
+
});
|
|
1210
|
+
}
|
|
1211
|
+
loadFormation(e) {
|
|
1212
|
+
if (!Me(e, this.getViewState())) return !1;
|
|
1213
|
+
let { players: t } = this.model.getSnapshot(), n = Be(e, this.ids, t.map((e) => e.id));
|
|
1214
|
+
return this.notifier.batch(() => {
|
|
1215
|
+
let e = this.commands.execute(new bt(n));
|
|
1216
|
+
return e && (this.setInteraction(void 0), this.setSelection(g)), e;
|
|
1217
|
+
});
|
|
1218
|
+
}
|
|
1219
|
+
undo() {
|
|
1220
|
+
this.notifier.batch(() => {
|
|
1221
|
+
let e = this.interaction;
|
|
1222
|
+
e?.type === "draw-line" ? this.setInteraction(e.points.length === 0 ? void 0 : {
|
|
1223
|
+
...e,
|
|
1224
|
+
points: e.points.slice(0, -1)
|
|
1225
|
+
}) : (this.setInteraction(void 0), this.commands.undo());
|
|
1226
|
+
});
|
|
1227
|
+
}
|
|
1228
|
+
redo() {
|
|
1229
|
+
this.notifier.batch(() => {
|
|
1230
|
+
this.setInteraction(void 0), this.commands.redo();
|
|
1231
|
+
});
|
|
1232
|
+
}
|
|
1233
|
+
setSelection(e) {
|
|
1234
|
+
Ae(this.selection, e) || (this.selection = e, this.notifier.markSceneChanged());
|
|
1235
|
+
}
|
|
1236
|
+
setInteraction(e) {
|
|
1237
|
+
e !== this.interaction && (this.interaction = e, this.notifier.markSceneChanged());
|
|
1238
|
+
}
|
|
1239
|
+
clampToField(e) {
|
|
1240
|
+
return a(Lt(e, this.model.getSnapshot().field));
|
|
1241
|
+
}
|
|
1242
|
+
dropCommand(e, t) {
|
|
1243
|
+
let n = un(this.model.getSnapshot(), e.target, t);
|
|
1244
|
+
if (n !== void 0) return n.kind === "player" ? new jt(n.playerId, n.patch) : new Dt(n.lineId, n.patch);
|
|
1245
|
+
}
|
|
1246
|
+
lineFromDraft(e) {
|
|
1247
|
+
let t = this.model.findPlayer(e.startPlayerId), n = t === void 0 ? void 0 : mn(e, t.position);
|
|
1248
|
+
return n === void 0 ? void 0 : hn(e, this.ids.next("line", new Set(this.model.getSnapshot().lines.map((e) => e.id))), n);
|
|
1249
|
+
}
|
|
1250
|
+
selectPointerDown(e) {
|
|
1251
|
+
let t = this.model.getSnapshot(), n = this.hitSelectedLineHandle(e);
|
|
1252
|
+
if (n !== void 0) {
|
|
1253
|
+
this.setInteraction(n);
|
|
1254
|
+
return;
|
|
1255
|
+
}
|
|
1256
|
+
let r = qt(t.players, e);
|
|
1257
|
+
if (r !== void 0) {
|
|
1258
|
+
this.setSelection({
|
|
1259
|
+
kind: "player",
|
|
1260
|
+
id: r.id
|
|
1261
|
+
}), this.setInteraction(cn({
|
|
1262
|
+
kind: "player",
|
|
1263
|
+
playerId: r.id
|
|
1264
|
+
}, r.position, e));
|
|
1265
|
+
return;
|
|
1266
|
+
}
|
|
1267
|
+
let i = Zt(t.lines, t.players, e);
|
|
1268
|
+
this.setSelection(i === void 0 ? g : {
|
|
1269
|
+
kind: "line",
|
|
1270
|
+
id: i.id
|
|
1271
|
+
});
|
|
1272
|
+
}
|
|
1273
|
+
hitSelectedLineHandle(e) {
|
|
1274
|
+
let t = this.getSelectedLine(), n = t === void 0 ? void 0 : en(t, e);
|
|
1275
|
+
return t === void 0 || n === void 0 ? void 0 : cn(n.kind === "endpoint" ? {
|
|
1276
|
+
kind: "endpoint",
|
|
1277
|
+
lineId: t.id
|
|
1278
|
+
} : {
|
|
1279
|
+
kind: "waypoint",
|
|
1280
|
+
lineId: t.id,
|
|
1281
|
+
index: n.index
|
|
1282
|
+
}, n.point, e);
|
|
1283
|
+
}
|
|
1284
|
+
drawLinePointerDown(e) {
|
|
1285
|
+
let t = this.interaction;
|
|
1286
|
+
if (t?.type === "draw-line") {
|
|
1287
|
+
this.setInteraction(pn(t, this.clampToField(e)));
|
|
1288
|
+
return;
|
|
1289
|
+
}
|
|
1290
|
+
if (!je("draw-line", this.getViewState())) return;
|
|
1291
|
+
let n = qt(this.model.getSnapshot().players, e);
|
|
1292
|
+
n !== void 0 && this.setInteraction(fn(n));
|
|
1293
|
+
}
|
|
1294
|
+
addPlayerAt(e) {
|
|
1295
|
+
if (!je("add-player", this.getViewState())) return;
|
|
1296
|
+
let { players: t } = this.model.getSnapshot(), n = this.ids.next("player", new Set(t.map((e) => e.id)));
|
|
1297
|
+
this.commands.execute(new kt({
|
|
1298
|
+
id: n,
|
|
1299
|
+
position: this.clampToField(e),
|
|
1300
|
+
shape: f,
|
|
1301
|
+
label: ""
|
|
1302
|
+
})), this.setSelection({
|
|
1303
|
+
kind: "player",
|
|
1304
|
+
id: n
|
|
1305
|
+
});
|
|
1306
|
+
}
|
|
1307
|
+
};
|
|
1308
|
+
// src/common/editing/play-session.ts
|
|
1309
|
+
function Sn(e) {
|
|
1310
|
+
let n = new t(), r = n.add(new vt(e)), i = new Ne(r, new Pe());
|
|
1311
|
+
return {
|
|
1312
|
+
store: n,
|
|
1313
|
+
model: r,
|
|
1314
|
+
controller: n.add(new xn(r, i, new Ve()))
|
|
1315
|
+
};
|
|
1316
|
+
}
|
|
1317
|
+
var Cn = class extends n {
|
|
1318
|
+
_onDidReset = this._register(new _());
|
|
1319
|
+
onDidReset = this._onDidReset.event;
|
|
1320
|
+
_onDidEdit = this._register(new _());
|
|
1321
|
+
onDidChange = (e) => this._onDidEdit.event(() => e(this.getPlayData()));
|
|
1322
|
+
_onDidChangeScene = this._register(new _());
|
|
1323
|
+
onDidChangeScene = this._onDidChangeScene.event;
|
|
1324
|
+
_onDidChangeViewState = this._register(new _());
|
|
1325
|
+
onDidChangeViewState = this._onDidChangeViewState.event;
|
|
1326
|
+
document;
|
|
1327
|
+
constructor(e) {
|
|
1328
|
+
super(), this.document = this.open(e);
|
|
1329
|
+
}
|
|
1330
|
+
get controller() {
|
|
1331
|
+
return this.document.controller;
|
|
1332
|
+
}
|
|
1333
|
+
get fieldZone() {
|
|
1334
|
+
return this.document.model.getFieldZone();
|
|
1335
|
+
}
|
|
1336
|
+
getPlayData() {
|
|
1337
|
+
return this.document.model.getData();
|
|
1338
|
+
}
|
|
1339
|
+
getSnapshot() {
|
|
1340
|
+
return this.document.model.getSnapshot();
|
|
1341
|
+
}
|
|
1342
|
+
setFieldZone(e) {
|
|
1343
|
+
this.document.controller.setFieldZone(e);
|
|
1344
|
+
}
|
|
1345
|
+
loadFormation(e) {
|
|
1346
|
+
let t = ze(e);
|
|
1347
|
+
return t !== null && this.document.controller.loadFormation(t);
|
|
1348
|
+
}
|
|
1349
|
+
setPlayData(e) {
|
|
1350
|
+
this.document.store.dispose(), this.document = this.open(e), this._onDidReset.fire(), this._onDidChangeScene.fire(), this._onDidChangeViewState.fire();
|
|
1351
|
+
}
|
|
1352
|
+
open(e) {
|
|
1353
|
+
let t = Sn(e), { store: n, model: r, controller: i } = t;
|
|
1354
|
+
return n.add(r.onDidChange(() => this._onDidEdit.fire())), n.add(i.onDidChangeScene(() => this._onDidChangeScene.fire())), n.add(i.onDidChangeViewState(() => this._onDidChangeViewState.fire())), t;
|
|
1355
|
+
}
|
|
1356
|
+
dispose() {
|
|
1357
|
+
this.document.store.dispose(), super.dispose();
|
|
1358
|
+
}
|
|
1359
|
+
}, wn = 1600, Tn = 4096;
|
|
1360
|
+
function En(e) {
|
|
1361
|
+
return !s(e) || e < 1 ? wn : Math.min(Math.round(e), Tn);
|
|
1362
|
+
}
|
|
1363
|
+
function Dn(e, t = {}) {
|
|
1364
|
+
let n = En(t.width);
|
|
1365
|
+
return {
|
|
1366
|
+
width: n,
|
|
1367
|
+
height: Math.round(n / It(e))
|
|
1368
|
+
};
|
|
1369
|
+
}
|
|
1370
|
+
// src/common/presets/alignments.ts
|
|
1371
|
+
function E(e, t) {
|
|
1372
|
+
return {
|
|
1373
|
+
lateralYard: e,
|
|
1374
|
+
downfieldYard: t
|
|
1375
|
+
};
|
|
1376
|
+
}
|
|
1377
|
+
function D(e, t, n, r = "circle") {
|
|
1378
|
+
return {
|
|
1379
|
+
id: e,
|
|
1380
|
+
position: n,
|
|
1381
|
+
shape: r,
|
|
1382
|
+
label: t
|
|
1383
|
+
};
|
|
1384
|
+
}
|
|
1385
|
+
function O(e, t = 0) {
|
|
1386
|
+
return E(e.lateralYard + t, e.downfieldYard - 1);
|
|
1387
|
+
}
|
|
1388
|
+
function k(e, t) {
|
|
1389
|
+
return E(e.lateralYard + t, e.downfieldYard);
|
|
1390
|
+
}
|
|
1391
|
+
var A = {
|
|
1392
|
+
lt: E(21.5, -1),
|
|
1393
|
+
lg: E(24, -1),
|
|
1394
|
+
c: E(26.5, -1),
|
|
1395
|
+
rg: E(29, -1),
|
|
1396
|
+
rt: E(31.5, -1)
|
|
1397
|
+
}, j = {
|
|
1398
|
+
eL: E(20.5, 1.5),
|
|
1399
|
+
n: E(25.5, 1.5),
|
|
1400
|
+
t: E(30, 1.5),
|
|
1401
|
+
eR: E(32.5, 1.5)
|
|
1402
|
+
}, M = E(35.5, 1.5), N = {
|
|
1403
|
+
eL: E(22.5, 1.5),
|
|
1404
|
+
n: E(26.5, 1.5),
|
|
1405
|
+
eR: E(30.5, 1.5)
|
|
1406
|
+
}, P = {
|
|
1407
|
+
w: E(22.5, 5),
|
|
1408
|
+
m: E(27, 5),
|
|
1409
|
+
s: E(34.5, 5)
|
|
1410
|
+
}, F = {
|
|
1411
|
+
m: E(24, 5),
|
|
1412
|
+
w: E(30, 5),
|
|
1413
|
+
nb: E(14, 5)
|
|
1414
|
+
};
|
|
1415
|
+
function I(e) {
|
|
1416
|
+
return {
|
|
1417
|
+
left: E(6.5, e),
|
|
1418
|
+
right: E(46.5, e)
|
|
1419
|
+
};
|
|
1420
|
+
}
|
|
1421
|
+
function L() {
|
|
1422
|
+
return [
|
|
1423
|
+
D("lt", "LT", A.lt, "square"),
|
|
1424
|
+
D("lg", "LG", A.lg, "square"),
|
|
1425
|
+
D("c", "C", A.c, "square"),
|
|
1426
|
+
D("rg", "RG", A.rg, "square"),
|
|
1427
|
+
D("rt", "RT", A.rt, "square")
|
|
1428
|
+
];
|
|
1429
|
+
}
|
|
1430
|
+
function R(e = j.eR) {
|
|
1431
|
+
return [
|
|
1432
|
+
D("de-l", "E", j.eL),
|
|
1433
|
+
D("dt-l", "N", j.n),
|
|
1434
|
+
D("dt-r", "T", j.t),
|
|
1435
|
+
D("de-r", "E", e)
|
|
1436
|
+
];
|
|
1437
|
+
}
|
|
1438
|
+
function On() {
|
|
1439
|
+
return [
|
|
1440
|
+
D("de-l", "E", N.eL),
|
|
1441
|
+
D("nt", "N", N.n),
|
|
1442
|
+
D("de-r", "E", N.eR)
|
|
1443
|
+
];
|
|
1444
|
+
}
|
|
1445
|
+
function z(e) {
|
|
1446
|
+
let { left: t, right: n } = I(e);
|
|
1447
|
+
return [D("cb-l", "CB", t), D("cb-r", "CB", n)];
|
|
1448
|
+
}
|
|
1449
|
+
function B() {
|
|
1450
|
+
return [
|
|
1451
|
+
...L(),
|
|
1452
|
+
D("y", "Y", E(34.5, -1), "square"),
|
|
1453
|
+
D("qb", "QB", E(26.5, -3)),
|
|
1454
|
+
D("fb", "FB", E(26.5, -6)),
|
|
1455
|
+
D("rb", "RB", E(26.5, -8.5)),
|
|
1456
|
+
D("x", "X", E(6.5, -1)),
|
|
1457
|
+
D("z", "Z", E(46.5, -2))
|
|
1458
|
+
];
|
|
1459
|
+
}
|
|
1460
|
+
function V() {
|
|
1461
|
+
return [
|
|
1462
|
+
...L(),
|
|
1463
|
+
D("y", "Y", E(34.5, -1), "square"),
|
|
1464
|
+
D("qb", "QB", E(26.5, -3)),
|
|
1465
|
+
D("rb", "RB", E(26.5, -7.5)),
|
|
1466
|
+
D("x", "X", E(6, -1)),
|
|
1467
|
+
D("h", "H", E(40, -2)),
|
|
1468
|
+
D("z", "Z", E(47, -1))
|
|
1469
|
+
];
|
|
1470
|
+
}
|
|
1471
|
+
function H() {
|
|
1472
|
+
return [
|
|
1473
|
+
...L(),
|
|
1474
|
+
D("qb", "QB", E(26.5, -5)),
|
|
1475
|
+
D("rb", "RB", E(29.5, -5)),
|
|
1476
|
+
D("x", "X", E(5.5, -1)),
|
|
1477
|
+
D("y", "Y", E(13, -2)),
|
|
1478
|
+
D("h", "H", E(40, -2)),
|
|
1479
|
+
D("z", "Z", E(47.5, -1))
|
|
1480
|
+
];
|
|
1481
|
+
}
|
|
1482
|
+
function kn() {
|
|
1483
|
+
return [
|
|
1484
|
+
...L(),
|
|
1485
|
+
D("qb", "QB", E(26.5, -5)),
|
|
1486
|
+
D("rb", "RB", E(24, -5)),
|
|
1487
|
+
D("x", "X", E(5.5, -1)),
|
|
1488
|
+
D("y", "Y", E(34.5, -1), "square"),
|
|
1489
|
+
D("h", "H", E(41, -2)),
|
|
1490
|
+
D("z", "Z", E(47.5, -1))
|
|
1491
|
+
];
|
|
1492
|
+
}
|
|
1493
|
+
function An() {
|
|
1494
|
+
return [
|
|
1495
|
+
...L(),
|
|
1496
|
+
D("qb", "QB", E(26.5, -5)),
|
|
1497
|
+
D("x", "X", E(5, -1)),
|
|
1498
|
+
D("f", "F", E(12, -2)),
|
|
1499
|
+
D("y", "Y", E(34.5, -1), "square"),
|
|
1500
|
+
D("h", "H", E(41, -2)),
|
|
1501
|
+
D("z", "Z", E(48, -1))
|
|
1502
|
+
];
|
|
1503
|
+
}
|
|
1504
|
+
function jn() {
|
|
1505
|
+
return [
|
|
1506
|
+
...L(),
|
|
1507
|
+
D("y", "Y", E(34.5, -1), "square"),
|
|
1508
|
+
D("qb", "QB", E(26.5, -4.5)),
|
|
1509
|
+
D("rb", "RB", E(26.5, -7.5)),
|
|
1510
|
+
D("x", "X", E(6, -1)),
|
|
1511
|
+
D("h", "H", E(40, -2)),
|
|
1512
|
+
D("z", "Z", E(47, -1))
|
|
1513
|
+
];
|
|
1514
|
+
}
|
|
1515
|
+
function Mn() {
|
|
1516
|
+
return [
|
|
1517
|
+
...L(),
|
|
1518
|
+
D("qb", "QB", E(26.5, -5)),
|
|
1519
|
+
D("rb", "RB", E(24, -5)),
|
|
1520
|
+
D("x", "X", E(5.5, -1)),
|
|
1521
|
+
D("z", "Z", E(37, -1)),
|
|
1522
|
+
D("h", "H", E(34.5, -2)),
|
|
1523
|
+
D("y", "Y", E(39.5, -2))
|
|
1524
|
+
];
|
|
1525
|
+
}
|
|
1526
|
+
function U() {
|
|
1527
|
+
return [
|
|
1528
|
+
...R(M),
|
|
1529
|
+
D("wlb", "W", P.w),
|
|
1530
|
+
D("mlb", "M", P.m),
|
|
1531
|
+
D("slb", "S", P.s),
|
|
1532
|
+
...z(6),
|
|
1533
|
+
D("fs", "FS", E(23, 11)),
|
|
1534
|
+
D("ss", "SS", E(32, 9))
|
|
1535
|
+
];
|
|
1536
|
+
}
|
|
1537
|
+
function Nn() {
|
|
1538
|
+
return [
|
|
1539
|
+
...On(),
|
|
1540
|
+
D("wlb", "W", E(19, 2.5)),
|
|
1541
|
+
D("mlb", "M", E(24.5, 5)),
|
|
1542
|
+
D("tlb", "T", E(29, 5)),
|
|
1543
|
+
D("slb", "S", E(34.5, 2.5)),
|
|
1544
|
+
...z(6),
|
|
1545
|
+
D("fs", "FS", E(23, 11)),
|
|
1546
|
+
D("ss", "SS", E(30, 11))
|
|
1547
|
+
];
|
|
1548
|
+
}
|
|
1549
|
+
function Pn(e = j.eR) {
|
|
1550
|
+
return [
|
|
1551
|
+
...R(e),
|
|
1552
|
+
D("mlb", "M", F.m),
|
|
1553
|
+
D("wlb", "W", F.w)
|
|
1554
|
+
];
|
|
1555
|
+
}
|
|
1556
|
+
var W = {
|
|
1557
|
+
cornerDepth: 6,
|
|
1558
|
+
fs: E(22, 11),
|
|
1559
|
+
ss: E(31, 11)
|
|
1560
|
+
};
|
|
1561
|
+
function G(e, t = j.eR) {
|
|
1562
|
+
return [
|
|
1563
|
+
...Pn(t),
|
|
1564
|
+
D("nb", "NB", F.nb),
|
|
1565
|
+
...z(e.cornerDepth),
|
|
1566
|
+
D("fs", "FS", e.fs),
|
|
1567
|
+
D("ss", "SS", e.ss)
|
|
1568
|
+
];
|
|
1569
|
+
}
|
|
1570
|
+
function Fn() {
|
|
1571
|
+
return [
|
|
1572
|
+
...R(),
|
|
1573
|
+
D("mlb", "M", E(27, 5)),
|
|
1574
|
+
D("nb", "NB", F.nb),
|
|
1575
|
+
D("db", "$", E(39, 5)),
|
|
1576
|
+
...z(6),
|
|
1577
|
+
D("fs", "FS", E(22, 11)),
|
|
1578
|
+
D("ss", "SS", E(31, 11))
|
|
1579
|
+
];
|
|
1580
|
+
}
|
|
1581
|
+
function In() {
|
|
1582
|
+
return [
|
|
1583
|
+
...R(),
|
|
1584
|
+
D("mlb", "M", E(24.5, 5)),
|
|
1585
|
+
D("wlb", "W", F.w),
|
|
1586
|
+
D("nb", "NB", E(39, 5)),
|
|
1587
|
+
...z(6),
|
|
1588
|
+
D("fs", "FS", E(23, 11)),
|
|
1589
|
+
D("ss", "SS", E(31, 9))
|
|
1590
|
+
];
|
|
1591
|
+
}
|
|
1592
|
+
function Ln() {
|
|
1593
|
+
return [
|
|
1594
|
+
...On(),
|
|
1595
|
+
D("wlb", "W", E(20.5, 5)),
|
|
1596
|
+
D("mlb", "M", E(26.5, 5)),
|
|
1597
|
+
D("slb", "S", E(32.5, 5)),
|
|
1598
|
+
D("nb", "NB", F.nb),
|
|
1599
|
+
...z(6),
|
|
1600
|
+
D("fs", "FS", E(23, 11)),
|
|
1601
|
+
D("ss", "SS", E(31, 9))
|
|
1602
|
+
];
|
|
1603
|
+
}
|
|
1604
|
+
// src/common/formations/presets.ts
|
|
1605
|
+
function K(e, t, n, r) {
|
|
1606
|
+
return {
|
|
1607
|
+
id: e,
|
|
1608
|
+
name: t,
|
|
1609
|
+
side: n,
|
|
1610
|
+
players: r.map(Re)
|
|
1611
|
+
};
|
|
1612
|
+
}
|
|
1613
|
+
var Rn = /* @__PURE__ */ Le([
|
|
1614
|
+
K("i-formation", "I-Formation", "offense", B()),
|
|
1615
|
+
K("singleback-ace", "Singleback Ace", "offense", V()),
|
|
1616
|
+
K("shotgun-spread", "Shotgun Spread", "offense", H()),
|
|
1617
|
+
K("trips", "Trips", "offense", kn()),
|
|
1618
|
+
K("empty", "Empty", "offense", An()),
|
|
1619
|
+
K("pistol", "Pistol", "offense", jn()),
|
|
1620
|
+
K("bunch", "Bunch", "offense", Mn()),
|
|
1621
|
+
K("defense-4-3", "4-3 Over", "defense", U()),
|
|
1622
|
+
K("defense-3-4", "3-4", "defense", Nn()),
|
|
1623
|
+
K("defense-nickel", "Nickel", "defense", G(W)),
|
|
1624
|
+
K("defense-dime", "Dime", "defense", Fn()),
|
|
1625
|
+
K("defense-4-2-5", "4-2-5", "defense", In()),
|
|
1626
|
+
K("defense-3-3-5", "3-3-5", "defense", Ln())
|
|
1627
|
+
]);
|
|
1628
|
+
function zn(e) {
|
|
1629
|
+
return Rn.find((t) => t.id === e);
|
|
1630
|
+
}
|
|
1631
|
+
// src/common/geometry/line-decoration.ts
|
|
1632
|
+
var Bn = .9;
|
|
1633
|
+
function Vn(e) {
|
|
1634
|
+
let t = e.at(-1);
|
|
1635
|
+
if (t !== void 0) for (let n = e.length - 2; n >= 0; n--) {
|
|
1636
|
+
let r = e[n];
|
|
1637
|
+
if (r !== void 0 && (r.x !== t.x || r.y !== t.y)) {
|
|
1638
|
+
let e = t.x - r.x, n = t.y - r.y, i = Math.hypot(e, n);
|
|
1639
|
+
return {
|
|
1640
|
+
tip: t,
|
|
1641
|
+
ux: e / i,
|
|
1642
|
+
uy: n / i
|
|
1643
|
+
};
|
|
1644
|
+
}
|
|
1645
|
+
}
|
|
1646
|
+
}
|
|
1647
|
+
function Hn(e, t) {
|
|
1648
|
+
return Ht(e, t, Bn);
|
|
1649
|
+
}
|
|
1650
|
+
function Un(e, t, n) {
|
|
1651
|
+
let r = Vn(e);
|
|
1652
|
+
if (r === void 0) return;
|
|
1653
|
+
let { tip: i, ux: a, uy: o } = r, s = i.x - t * a, c = i.y - t * o;
|
|
1654
|
+
return [
|
|
1655
|
+
i,
|
|
1656
|
+
{
|
|
1657
|
+
x: s - n * o,
|
|
1658
|
+
y: c + n * a
|
|
1659
|
+
},
|
|
1660
|
+
{
|
|
1661
|
+
x: s + n * o,
|
|
1662
|
+
y: c - n * a
|
|
1663
|
+
}
|
|
1664
|
+
];
|
|
1665
|
+
}
|
|
1666
|
+
function Wn(e, t) {
|
|
1667
|
+
let n = Vn(e);
|
|
1668
|
+
if (n === void 0) return;
|
|
1669
|
+
let { tip: r, ux: i, uy: a } = n, o = t / 2;
|
|
1670
|
+
return [{
|
|
1671
|
+
x: r.x + o * a,
|
|
1672
|
+
y: r.y - o * i
|
|
1673
|
+
}, {
|
|
1674
|
+
x: r.x - o * a,
|
|
1675
|
+
y: r.y + o * i
|
|
1676
|
+
}];
|
|
1677
|
+
}
|
|
1678
|
+
// src/common/geometry/player-marker.ts
|
|
1679
|
+
var Gn = .82;
|
|
1680
|
+
function Kn(e, t) {
|
|
1681
|
+
switch (e) {
|
|
1682
|
+
case "circle": return {
|
|
1683
|
+
kind: "circle",
|
|
1684
|
+
radius: t * Gn
|
|
1685
|
+
};
|
|
1686
|
+
case "square": return {
|
|
1687
|
+
kind: "square",
|
|
1688
|
+
halfSide: t / Math.SQRT2
|
|
1689
|
+
};
|
|
1690
|
+
}
|
|
1691
|
+
}
|
|
1692
|
+
// src/common/input/keymap.ts
|
|
1693
|
+
function qn(e) {
|
|
1694
|
+
let t = e.metaKey || e.ctrlKey, n = e.key.toLowerCase();
|
|
1695
|
+
return e.key === "Escape" ? "cancel-interaction" : e.key === "Enter" ? "commit-line" : t && n === "z" ? e.shiftKey ? "redo" : "undo" : t && n === "y" ? "redo" : null;
|
|
1696
|
+
}
|
|
1697
|
+
// src/common/plays/presets.ts
|
|
1698
|
+
function q(e, t, n, r, i, a) {
|
|
1699
|
+
return {
|
|
1700
|
+
id: e,
|
|
1701
|
+
kind: t,
|
|
1702
|
+
startPlayerId: n,
|
|
1703
|
+
waypoints: r,
|
|
1704
|
+
end: i,
|
|
1705
|
+
interpolation: a
|
|
1706
|
+
};
|
|
1707
|
+
}
|
|
1708
|
+
function J(e, t, n, r, i, a, o, s) {
|
|
1709
|
+
return {
|
|
1710
|
+
id: e,
|
|
1711
|
+
name: t,
|
|
1712
|
+
side: n,
|
|
1713
|
+
category: r,
|
|
1714
|
+
personnel: i,
|
|
1715
|
+
summary: a,
|
|
1716
|
+
data: {
|
|
1717
|
+
version: 2,
|
|
1718
|
+
field: v("middle"),
|
|
1719
|
+
players: o,
|
|
1720
|
+
lines: s
|
|
1721
|
+
}
|
|
1722
|
+
};
|
|
1723
|
+
}
|
|
1724
|
+
var Jn = {
|
|
1725
|
+
cornerDepth: 5,
|
|
1726
|
+
fs: E(18, 12),
|
|
1727
|
+
ss: E(35, 12)
|
|
1728
|
+
}, Y = {
|
|
1729
|
+
cornerDepth: 7,
|
|
1730
|
+
fs: E(26.5, 12),
|
|
1731
|
+
ss: E(34, 6)
|
|
1732
|
+
}, Yn = /* @__PURE__ */ Le([
|
|
1733
|
+
J("play-inside-zone", "Inside Zone", "offense", "run-zone", "11 pers", "ゾーンブロックで内側を一気に。RB は RG の内側を狙い、3 テクの動きで B ギャップか裏の A ギャップへ切る。", [
|
|
1734
|
+
...L(),
|
|
1735
|
+
D("y", "Y", E(34.5, -1), "square"),
|
|
1736
|
+
D("qb", "QB", E(26.5, -5)),
|
|
1737
|
+
D("rb", "RB", E(24, -5)),
|
|
1738
|
+
D("x", "X", E(6, -1)),
|
|
1739
|
+
D("h", "H", E(40, -2)),
|
|
1740
|
+
D("z", "Z", E(47, -1)),
|
|
1741
|
+
...U()
|
|
1742
|
+
], [
|
|
1743
|
+
q("bl-lt", "block", "lt", [], O(j.eL), "straight"),
|
|
1744
|
+
q("bl-lg", "block", "lg", [], O(j.n), "straight"),
|
|
1745
|
+
q("bl-c", "block", "c", [k(j.n, 1)], O(P.m), "bezier"),
|
|
1746
|
+
q("bl-rg", "block", "rg", [], O(j.t), "straight"),
|
|
1747
|
+
q("bl-rt", "block", "rt", [k(j.t, 1.5)], O(P.s), "bezier"),
|
|
1748
|
+
q("bl-y", "block", "y", [], O(M), "straight"),
|
|
1749
|
+
q("run-rb", "route", "rb", [E(27.5, -2)], E(28, 3.5), "bezier")
|
|
1750
|
+
]),
|
|
1751
|
+
J("play-outside-zone", "Outside Zone", "offense", "run-zone", "11 pers", "ワイドゾーンで横へ伸ばす。RB は TE の外側を狙い、E と S の動きで外へ出るか縦に切り返す。", [...V(), ...U()], [
|
|
1752
|
+
q("bl-lt", "block", "lt", [], O(j.eL), "straight"),
|
|
1753
|
+
q("bl-lg", "block", "lg", [], O(j.n), "straight"),
|
|
1754
|
+
q("bl-c", "block", "c", [k(j.n, 1)], O(P.m, .5), "bezier"),
|
|
1755
|
+
q("bl-rg", "block", "rg", [], O(j.t, .5), "straight"),
|
|
1756
|
+
q("bl-rt", "block", "rt", [k(j.t, 1.5)], O(P.s, .5), "bezier"),
|
|
1757
|
+
q("bl-y", "block", "y", [], O(M, .5), "straight"),
|
|
1758
|
+
q("run-rb", "route", "rb", [E(31, -5), E(35.5, -2)], E(37.5, 3), "bezier")
|
|
1759
|
+
]),
|
|
1760
|
+
J("play-power", "Power", "offense", "run-gap", "21 pers", "プレイサイドはダウンブロック、FB が 9 テクの E をキックアウト、バックサイドガードがプルして C ギャップをリードする。", [...B(), ...U()], [
|
|
1761
|
+
q("bl-y", "block", "y", [], O(P.s), "straight"),
|
|
1762
|
+
q("bl-rt", "block", "rt", [], O(j.t, .5), "straight"),
|
|
1763
|
+
q("bl-rg", "block", "rg", [k(j.t, -1.5)], O(P.m), "bezier"),
|
|
1764
|
+
q("bl-c", "block", "c", [], O(j.n), "straight"),
|
|
1765
|
+
q("bl-lt", "block", "lt", [], O(j.eL), "straight"),
|
|
1766
|
+
q("lead-fb", "block", "fb", [E(31, -3.5), E(33.5, -.5)], O(M, -.5), "bezier"),
|
|
1767
|
+
q("pull-lg", "block", "lg", [
|
|
1768
|
+
E(25, -4),
|
|
1769
|
+
E(31, -4),
|
|
1770
|
+
E(32.5, -2),
|
|
1771
|
+
E(32.5, 1)
|
|
1772
|
+
], E(31.5, 3.5), "bezier"),
|
|
1773
|
+
q("run-rb", "route", "rb", [E(30, -6), E(33, -3)], E(33.5, 4), "bezier")
|
|
1774
|
+
]),
|
|
1775
|
+
J("play-counter", "Counter (GT)", "offense", "run-gap", "21 pers", "バックサイドのガードが 9 テクの E をキックアウト、タックルが C ギャップへ巻き込み、FB がタックルの跡を埋める(GT カウンター)。", [...B(), ...U()], [
|
|
1776
|
+
q("bl-y", "block", "y", [], O(P.s), "straight"),
|
|
1777
|
+
q("bl-rt", "block", "rt", [], O(j.t, .5), "straight"),
|
|
1778
|
+
q("bl-rg", "block", "rg", [k(j.t, -1.5)], O(P.m), "bezier"),
|
|
1779
|
+
q("bl-c", "block", "c", [], O(j.n), "straight"),
|
|
1780
|
+
q("pull-lg", "block", "lg", [
|
|
1781
|
+
E(25, -4),
|
|
1782
|
+
E(32, -4),
|
|
1783
|
+
E(33.5, -.5)
|
|
1784
|
+
], O(M, -.5), "straight"),
|
|
1785
|
+
q("pull-lt", "block", "lt", [
|
|
1786
|
+
E(23, -5),
|
|
1787
|
+
E(31, -5),
|
|
1788
|
+
E(32.5, -2),
|
|
1789
|
+
E(32.5, 1)
|
|
1790
|
+
], E(31.5, 3.5), "straight"),
|
|
1791
|
+
q("fill-fb", "block", "fb", [E(24, -3), E(22.5, -.5)], O(j.eL, 1), "bezier"),
|
|
1792
|
+
q("run-rb", "route", "rb", [
|
|
1793
|
+
E(24, -7.5),
|
|
1794
|
+
E(30, -6.5),
|
|
1795
|
+
E(33, -3)
|
|
1796
|
+
], E(33.5, 4), "bezier")
|
|
1797
|
+
]),
|
|
1798
|
+
J("play-four-verticals", "Four Verticals", "offense", "pass-deep", "10 pers", "トリップスから 4 本の縦。対シングルハイのシームで勝負する。", [...kn(), ...G(Y, M)], [
|
|
1799
|
+
q("go-x", "route", "x", [E(4, 4)], E(4, 13), "straight"),
|
|
1800
|
+
q("seam-y", "route", "y", [E(33, 5)], E(31, 13), "bezier"),
|
|
1801
|
+
q("seam-h", "route", "h", [E(40, 5)], E(38, 13), "bezier"),
|
|
1802
|
+
q("go-z", "route", "z", [E(49, 4)], E(49, 13), "straight"),
|
|
1803
|
+
q("chk-rb", "route", "rb", [], E(20, -3), "straight")
|
|
1804
|
+
]),
|
|
1805
|
+
J("play-mesh", "Mesh", "offense", "pass-dropback", "10 pers", "浅いクロスの交差。対マン/ゾーン両対応で空いた所へ運ぶ。", [...H(), ...G(W)], [
|
|
1806
|
+
q("cross-y", "route", "y", [E(20, 3.5)], E(38, 4), "straight"),
|
|
1807
|
+
q("cross-h", "route", "h", [E(33, 3)], E(15, 3.5), "straight"),
|
|
1808
|
+
q("corner-x", "route", "x", [E(5, 5)], E(2, 9), "bezier"),
|
|
1809
|
+
q("sit-z", "route", "z", [], E(47, 5), "straight"),
|
|
1810
|
+
q("swing-rb", "route", "rb", [E(33, -4)], E(41, -3), "straight")
|
|
1811
|
+
]),
|
|
1812
|
+
J("play-smash", "Smash", "offense", "pass-dropback", "11 pers", "コーナー+ヒッチのハイロー。対カバー 2 のコーナーを攻める。", [...V(), ...G(Jn, M)], [
|
|
1813
|
+
q("hitch-z", "route", "z", [], E(47, 3), "straight"),
|
|
1814
|
+
q("corner-h", "route", "h", [E(41, 4)], E(46, 10), "bezier"),
|
|
1815
|
+
q("dig-y", "route", "y", [E(34.5, 8)], E(27, 9), "straight"),
|
|
1816
|
+
q("hitch-x", "route", "x", [], E(6, 3), "straight"),
|
|
1817
|
+
q("flat-rb", "route", "rb", [], E(22, -4), "straight")
|
|
1818
|
+
]),
|
|
1819
|
+
J("play-stick", "Stick", "offense", "pass-quick", "11 pers", "3 ステップの速攻。スティック(座り)+フラットで素早く配球する。", [...V(), ...G(W, M)], [
|
|
1820
|
+
q("stick-y", "route", "y", [], E(34.5, 4), "straight"),
|
|
1821
|
+
q("flat-h", "route", "h", [], E(45, 0), "straight"),
|
|
1822
|
+
q("hitch-z", "route", "z", [], E(47, 3), "straight"),
|
|
1823
|
+
q("slant-x", "route", "x", [E(6, 2)], E(10, 3), "bezier"),
|
|
1824
|
+
q("chk-rb", "route", "rb", [], E(21, -5), "straight")
|
|
1825
|
+
]),
|
|
1826
|
+
J("play-rpo-bubble", "RPO (IZ + Bubble)", "offense", "rpo", "11 pers", "バブル側の W を読み、W がボックスに入ればバブル、残ればインサイドゾーンへ分岐する。", [...H(), ...G(W)], [
|
|
1827
|
+
q("bl-lt", "block", "lt", [], O(j.eL), "straight"),
|
|
1828
|
+
q("bl-lg", "block", "lg", [k(j.n, -1)], O(F.m), "bezier"),
|
|
1829
|
+
q("bl-c", "block", "c", [], O(j.n), "straight"),
|
|
1830
|
+
q("bl-rg", "block", "rg", [], O(j.t), "straight"),
|
|
1831
|
+
q("bl-rt", "block", "rt", [], O(j.eR), "straight"),
|
|
1832
|
+
q("run-rb", "route", "rb", [E(26, -2.5)], E(23, 3), "straight"),
|
|
1833
|
+
q("bubble-h", "route", "h", [E(43, -3)], E(46, -.5), "bezier"),
|
|
1834
|
+
q("bl-z", "block", "z", [], O(I(W.cornerDepth).right), "straight"),
|
|
1835
|
+
q("glance-y", "route", "y", [E(15, 1)], E(19, 3), "bezier")
|
|
1836
|
+
]),
|
|
1837
|
+
J("play-pa-boot", "PA Boot (Sail)", "offense", "pa", "11 pers", "プレイアクションで QB がブートし、フラット/セイル/縦の 3 段で攻める。", [...V(), ...U()], [
|
|
1838
|
+
q("fake-rb", "motion", "rb", [E(24, -6)], E(20.5, -4.5), "straight"),
|
|
1839
|
+
q("boot-qb", "route", "qb", [E(31, -4)], E(36.5, -5), "bezier"),
|
|
1840
|
+
q("bl-lt", "block", "lt", [], O(j.eL), "straight"),
|
|
1841
|
+
q("bl-c", "block", "c", [], O(j.n), "straight"),
|
|
1842
|
+
q("bl-rg", "block", "rg", [], O(j.t), "straight"),
|
|
1843
|
+
q("flat-y", "route", "y", [E(37, -.5)], E(43, .5), "bezier"),
|
|
1844
|
+
q("sail-h", "route", "h", [E(41, 3)], E(46, 8), "bezier"),
|
|
1845
|
+
q("go-z", "route", "z", [E(49, 3)], E(49, 13), "straight"),
|
|
1846
|
+
q("comeback-x", "route", "x", [E(5, 9)], E(7.5, 7.5), "bezier")
|
|
1847
|
+
]),
|
|
1848
|
+
J("play-cover-1", "Cover 1 (Man Free)", "defense", "coverage", "Nickel", "1 ディープのフリーセイフティを残し、残りは全マン。W は穴(ラット)で待つ。", [...G({
|
|
1849
|
+
cornerDepth: 6,
|
|
1850
|
+
fs: E(26.5, 11),
|
|
1851
|
+
ss: E(38, 6)
|
|
1852
|
+
}), ...H()], [
|
|
1853
|
+
q("man-cbl", "motion", "cb-l", [], E(5.5, .5), "straight"),
|
|
1854
|
+
q("man-cbr", "motion", "cb-r", [], E(47.5, .5), "straight"),
|
|
1855
|
+
q("man-nb", "motion", "nb", [], E(13, -.5), "straight"),
|
|
1856
|
+
q("man-ss", "motion", "ss", [], E(40, -.5), "straight"),
|
|
1857
|
+
q("man-mlb", "motion", "mlb", [E(27.5, 2.5), E(27.5, -2.5)], E(29, -3.5), "straight"),
|
|
1858
|
+
q("rat-wlb", "motion", "wlb", [], E(27.5, 3.5), "straight"),
|
|
1859
|
+
q("free-fs", "motion", "fs", [], E(26.5, 13), "straight")
|
|
1860
|
+
]),
|
|
1861
|
+
J("play-cover-2", "Cover 2", "defense", "coverage", "Nickel", "2 ディープ 5 アンダーのゾーン。深いハーフを 2 人で分け、CB はフラットに座る。", [...G({
|
|
1862
|
+
cornerDepth: 5,
|
|
1863
|
+
fs: E(15, 11),
|
|
1864
|
+
ss: E(38, 11)
|
|
1865
|
+
}), ...H()], [
|
|
1866
|
+
q("half-fs", "motion", "fs", [], E(13, 14), "straight"),
|
|
1867
|
+
q("half-ss", "motion", "ss", [], E(40, 14), "straight"),
|
|
1868
|
+
q("flat-cbl", "motion", "cb-l", [], E(9.5, 4), "straight"),
|
|
1869
|
+
q("flat-cbr", "motion", "cb-r", [], E(43.5, 4), "straight"),
|
|
1870
|
+
q("hook-mlb", "motion", "mlb", [], E(21.5, 10), "straight"),
|
|
1871
|
+
q("hook-wlb", "motion", "wlb", [], E(32.5, 10), "straight"),
|
|
1872
|
+
q("curl-nb", "motion", "nb", [], E(16, 9), "straight")
|
|
1873
|
+
]),
|
|
1874
|
+
J("play-cover-3", "Cover 3", "defense", "coverage", "Nickel", "3 ディープ 4 アンダー。現代の基準となるシングルハイのゾーン。", [...G(Y), ...H()], [
|
|
1875
|
+
q("deep-cbl", "motion", "cb-l", [], E(7, 13), "straight"),
|
|
1876
|
+
q("deep-cbr", "motion", "cb-r", [], E(46, 13), "straight"),
|
|
1877
|
+
q("deep-fs", "motion", "fs", [], E(26.5, 14), "straight"),
|
|
1878
|
+
q("curl-nb", "motion", "nb", [], E(15.5, 9), "straight"),
|
|
1879
|
+
q("hook-mlb", "motion", "mlb", [], E(22, 10), "straight"),
|
|
1880
|
+
q("hook-wlb", "motion", "wlb", [], E(31, 10), "straight"),
|
|
1881
|
+
q("flat-ss", "motion", "ss", [], E(39, 4), "straight")
|
|
1882
|
+
]),
|
|
1883
|
+
J("play-cover-4", "Cover 4 (Quarters)", "defense", "coverage", "Nickel", "4 ディープのクォーターズ。縦パスを上から踏み潰す。", [...G({
|
|
1884
|
+
cornerDepth: 7,
|
|
1885
|
+
fs: E(20, 11),
|
|
1886
|
+
ss: E(33, 11)
|
|
1887
|
+
}), ...H()], [
|
|
1888
|
+
q("qtr-cbl", "motion", "cb-l", [], E(6, 13), "straight"),
|
|
1889
|
+
q("qtr-cbr", "motion", "cb-r", [], E(47, 13), "straight"),
|
|
1890
|
+
q("qtr-fs", "motion", "fs", [], E(18, 14), "straight"),
|
|
1891
|
+
q("qtr-ss", "motion", "ss", [], E(35, 14), "straight"),
|
|
1892
|
+
q("under-nb", "motion", "nb", [], E(16, 8), "straight"),
|
|
1893
|
+
q("under-mlb", "motion", "mlb", [], E(23, 9), "straight"),
|
|
1894
|
+
q("under-wlb", "motion", "wlb", [], E(31, 9), "straight")
|
|
1895
|
+
]),
|
|
1896
|
+
J("play-fire-zone", "Fire Zone", "defense", "pressure", "Nickel", "5 人ブリッツ+ライン 1 枚をドロップ、3 ディープ 3 アンダーで覆う。", [...G(Y), ...H()], [
|
|
1897
|
+
q("rush-dtl", "route", "dt-l", [], E(25, 0), "straight"),
|
|
1898
|
+
q("rush-dtr", "route", "dt-r", [], E(28.5, 0), "straight"),
|
|
1899
|
+
q("rush-der", "route", "de-r", [], E(33, 0), "straight"),
|
|
1900
|
+
q("blz-wlb", "route", "wlb", [E(31.5, 2.5)], E(31, 0), "bezier"),
|
|
1901
|
+
q("blz-nb", "route", "nb", [E(17, 2.5)], E(20, 0), "bezier"),
|
|
1902
|
+
q("drop-del", "motion", "de-l", [E(19, 4)], E(17, 7), "straight"),
|
|
1903
|
+
q("deep-cbl", "motion", "cb-l", [], E(7, 13), "straight"),
|
|
1904
|
+
q("deep-cbr", "motion", "cb-r", [], E(46, 13), "straight"),
|
|
1905
|
+
q("deep-fs", "motion", "fs", [], E(26.5, 14), "straight"),
|
|
1906
|
+
q("hook-mlb", "motion", "mlb", [], E(23, 9), "straight"),
|
|
1907
|
+
q("flat-ss", "motion", "ss", [], E(39, 4), "straight")
|
|
1908
|
+
]),
|
|
1909
|
+
J("play-cover-0", "Cover 0 Blitz", "defense", "pressure", "Nickel", "セイフティを残さず全マン、6 人で最大限の圧力をかける。FS が RB をマンで受け持つ。", [...G({
|
|
1910
|
+
cornerDepth: 5,
|
|
1911
|
+
fs: E(22, 9),
|
|
1912
|
+
ss: E(31, 9)
|
|
1913
|
+
}), ...H()], [
|
|
1914
|
+
q("rush-del", "route", "de-l", [], E(20, 0), "straight"),
|
|
1915
|
+
q("rush-dtl", "route", "dt-l", [], E(25, 0), "straight"),
|
|
1916
|
+
q("rush-dtr", "route", "dt-r", [], E(30.5, 0), "straight"),
|
|
1917
|
+
q("rush-der", "route", "de-r", [], E(33, 0), "straight"),
|
|
1918
|
+
q("blz-mlb", "route", "mlb", [E(27, 2.5)], E(27.5, 0), "bezier"),
|
|
1919
|
+
q("blz-wlb", "route", "wlb", [E(31.5, 2.5)], E(31, 0), "bezier"),
|
|
1920
|
+
q("man-cbl", "motion", "cb-l", [], E(5.5, .5), "straight"),
|
|
1921
|
+
q("man-cbr", "motion", "cb-r", [], E(47.5, .5), "straight"),
|
|
1922
|
+
q("man-nb", "motion", "nb", [], E(13, -.5), "straight"),
|
|
1923
|
+
q("man-fs", "motion", "fs", [E(22, 2.5), E(23, -2.5)], E(28, -4), "straight"),
|
|
1924
|
+
q("man-ss", "motion", "ss", [E(37, 4)], E(39.5, -.5), "straight")
|
|
1925
|
+
]),
|
|
1926
|
+
J("play-double-a", "Double-A Gap", "defense", "pressure", "Nickel", "両 A ギャップに 2 人を提示。実行・シム(見せ)どちらにも化ける。", [
|
|
1927
|
+
D("de-l", "E", j.eL),
|
|
1928
|
+
D("dt-l", "T", E(23, 1.5)),
|
|
1929
|
+
D("dt-r", "T", j.t),
|
|
1930
|
+
D("de-r", "E", j.eR),
|
|
1931
|
+
D("mlb", "M", E(25.5, 3)),
|
|
1932
|
+
D("wlb", "W", E(27.5, 3)),
|
|
1933
|
+
D("nb", "NB", F.nb),
|
|
1934
|
+
D("cb-l", "CB", I(7).left),
|
|
1935
|
+
D("cb-r", "CB", I(7).right),
|
|
1936
|
+
D("fs", "FS", Y.fs),
|
|
1937
|
+
D("ss", "SS", Y.ss),
|
|
1938
|
+
...H()
|
|
1939
|
+
], [
|
|
1940
|
+
q("aim-mlb", "route", "mlb", [], E(25.5, .5), "straight"),
|
|
1941
|
+
q("aim-wlb", "route", "wlb", [], E(27.5, .5), "straight"),
|
|
1942
|
+
q("rush-del", "route", "de-l", [], E(20, 0), "straight"),
|
|
1943
|
+
q("rush-dtl", "route", "dt-l", [], E(22.5, 0), "straight"),
|
|
1944
|
+
q("rush-dtr", "route", "dt-r", [], E(30.5, 0), "straight"),
|
|
1945
|
+
q("rush-der", "route", "de-r", [], E(33, 0), "straight"),
|
|
1946
|
+
q("bail-cbl", "motion", "cb-l", [], E(7, 12), "straight"),
|
|
1947
|
+
q("bail-cbr", "motion", "cb-r", [], E(46, 12), "straight"),
|
|
1948
|
+
q("deep-fs", "motion", "fs", [], E(26.5, 14), "straight"),
|
|
1949
|
+
q("curl-nb", "motion", "nb", [], E(15.5, 9), "straight"),
|
|
1950
|
+
q("flat-ss", "motion", "ss", [], E(39, 4), "straight")
|
|
1951
|
+
]),
|
|
1952
|
+
J("play-cover-6", "Cover 6", "defense", "coverage", "Nickel", "クォーター×2+ハーフの分割カバー。フィールドはクォーターズ、バウンダリは 2。", [
|
|
1953
|
+
...Pn(),
|
|
1954
|
+
D("nb", "NB", E(39, 5)),
|
|
1955
|
+
D("cb-l", "CB", I(5).left),
|
|
1956
|
+
D("cb-r", "CB", I(7).right),
|
|
1957
|
+
D("fs", "FS", E(15, 11)),
|
|
1958
|
+
D("ss", "SS", E(35, 10)),
|
|
1959
|
+
...H()
|
|
1960
|
+
], [
|
|
1961
|
+
q("flat-cbl", "motion", "cb-l", [], E(10, 4), "straight"),
|
|
1962
|
+
q("half-fs", "motion", "fs", [], E(12, 14), "straight"),
|
|
1963
|
+
q("qtr-cbr", "motion", "cb-r", [], E(47, 13), "straight"),
|
|
1964
|
+
q("qtr-ss", "motion", "ss", [], E(38, 14), "straight"),
|
|
1965
|
+
q("curl-nb", "motion", "nb", [], E(41, 9), "straight"),
|
|
1966
|
+
q("hook-mlb", "motion", "mlb", [], E(22, 10), "straight"),
|
|
1967
|
+
q("hook-wlb", "motion", "wlb", [], E(31, 10), "straight")
|
|
1968
|
+
])
|
|
1969
|
+
]);
|
|
1970
|
+
function Xn(e) {
|
|
1971
|
+
return Yn.find((t) => t.id === e);
|
|
1972
|
+
}
|
|
1973
|
+
// src/browser/input/pointer-input.ts
|
|
1974
|
+
function Zn(e) {
|
|
1975
|
+
return e instanceof HTMLInputElement || e instanceof HTMLSelectElement || e instanceof HTMLTextAreaElement;
|
|
1976
|
+
}
|
|
1977
|
+
var Qn = class extends n {
|
|
1978
|
+
constructor(t, n, r) {
|
|
1979
|
+
super();
|
|
1980
|
+
let i = n.canvas;
|
|
1981
|
+
i.tabIndex = 0;
|
|
1982
|
+
let a = (e) => n.clientToYard(e.clientX, e.clientY), o = null, s = (e) => {
|
|
1983
|
+
e.button === 0 && e.isPrimary && (o = e.pointerId, i.focus({ preventScroll: !0 }), i.setPointerCapture(e.pointerId), r.pointerDown(a(e)));
|
|
1984
|
+
}, c = (e) => {
|
|
1985
|
+
e.isPrimary && r.pointerMove(a(e));
|
|
1986
|
+
}, l = (e) => e.pointerId === o && (o = null, !0), u = (e) => {
|
|
1987
|
+
l(e) && r.pointerUp(a(e));
|
|
1988
|
+
}, d = (e) => {
|
|
1989
|
+
l(e) && !r.getViewState().isDrawing && r.cancelInteraction();
|
|
1990
|
+
}, f = () => r.commitLine(), p = (e) => {
|
|
1991
|
+
if (!Zn(e.target)) switch (qn(e)) {
|
|
1992
|
+
case "cancel-interaction":
|
|
1993
|
+
r.cancelInteraction();
|
|
1994
|
+
return;
|
|
1995
|
+
case "commit-line":
|
|
1996
|
+
e.target instanceof HTMLButtonElement || r.commitLine();
|
|
1997
|
+
return;
|
|
1998
|
+
case "undo":
|
|
1999
|
+
e.preventDefault(), r.undo();
|
|
2000
|
+
return;
|
|
2001
|
+
case "redo":
|
|
2002
|
+
e.preventDefault(), r.redo();
|
|
2003
|
+
return;
|
|
2004
|
+
case null: return;
|
|
2005
|
+
}
|
|
2006
|
+
}, m = new AbortController(), { signal: h } = m;
|
|
2007
|
+
i.addEventListener("pointerdown", s, { signal: h }), i.addEventListener("pointermove", c, { signal: h }), i.addEventListener("pointerup", u, { signal: h }), i.addEventListener("pointercancel", d, { signal: h }), i.addEventListener("lostpointercapture", d, { signal: h }), i.addEventListener("dblclick", f, { signal: h }), t.addEventListener("keydown", p, { signal: h }), this._register(e(() => {
|
|
2008
|
+
m.abort(), i.removeAttribute("tabindex");
|
|
2009
|
+
}));
|
|
2010
|
+
}
|
|
2011
|
+
}, $n = "data:font/woff2;base64,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", er = "Playmaker Saira", tr = `"${er}", sans-serif`;
|
|
2012
|
+
function nr(e) {
|
|
2013
|
+
return `700 ${e}px ${tr}`;
|
|
2014
|
+
}
|
|
2015
|
+
// src/browser/theme/field-font-face.ts
|
|
2016
|
+
var rr;
|
|
2017
|
+
function ir() {
|
|
2018
|
+
return rr ??= ar(), rr;
|
|
2019
|
+
}
|
|
2020
|
+
async function ar() {
|
|
2021
|
+
try {
|
|
2022
|
+
let e = new FontFace(er, `url("${$n}")`, { weight: "700" });
|
|
2023
|
+
document.fonts.add(e), await e.load();
|
|
2024
|
+
} catch {}
|
|
2025
|
+
}
|
|
2026
|
+
// src/browser/theme/css-color.ts
|
|
2027
|
+
var or = { status: "unresolved" };
|
|
2028
|
+
function sr() {
|
|
2029
|
+
if (or.status === "unresolved") {
|
|
2030
|
+
let e = document.createElement("canvas").getContext("2d");
|
|
2031
|
+
or = e === null ? { status: "unavailable" } : {
|
|
2032
|
+
status: "ready",
|
|
2033
|
+
ctx: e
|
|
2034
|
+
};
|
|
2035
|
+
}
|
|
2036
|
+
return or;
|
|
2037
|
+
}
|
|
2038
|
+
function cr(e) {
|
|
2039
|
+
let t = sr();
|
|
2040
|
+
if (t.status !== "ready") return e;
|
|
2041
|
+
let { ctx: n } = t;
|
|
2042
|
+
n.fillStyle = "#000000", n.fillStyle = e;
|
|
2043
|
+
let r = n.fillStyle;
|
|
2044
|
+
return n.fillStyle = "#ffffff", n.fillStyle = e, typeof r == "string" && n.fillStyle === r ? r : void 0;
|
|
2045
|
+
}
|
|
2046
|
+
// src/browser/theme/tokens.ts
|
|
2047
|
+
var lr = "#ffffff", X = "#212121", ur = "#d32f2f", dr = "#1976d2", fr = "#388e3c", pr = "#ff9800", mr = "#f5f5f5", hr = "#eeeeee", gr = "#bdbdbd", _r = "#9e9e9e", vr = {
|
|
2048
|
+
fieldGrass: {
|
|
2049
|
+
property: "--playmaker-field-grass",
|
|
2050
|
+
fallback: lr
|
|
2051
|
+
},
|
|
2052
|
+
fieldOob: {
|
|
2053
|
+
property: "--playmaker-field-oob",
|
|
2054
|
+
fallback: hr
|
|
2055
|
+
},
|
|
2056
|
+
fieldEndzone: {
|
|
2057
|
+
property: "--playmaker-field-endzone",
|
|
2058
|
+
fallback: mr
|
|
2059
|
+
},
|
|
2060
|
+
fieldLine: {
|
|
2061
|
+
property: "--playmaker-field-line",
|
|
2062
|
+
fallback: _r
|
|
2063
|
+
},
|
|
2064
|
+
fieldNumber: {
|
|
2065
|
+
property: "--playmaker-field-number",
|
|
2066
|
+
fallback: gr
|
|
2067
|
+
},
|
|
2068
|
+
fieldGoalLine: {
|
|
2069
|
+
property: "--playmaker-field-goal-line",
|
|
2070
|
+
fallback: "#616161"
|
|
2071
|
+
},
|
|
2072
|
+
fieldPylon: {
|
|
2073
|
+
property: "--playmaker-field-pylon",
|
|
2074
|
+
fallback: _r
|
|
2075
|
+
},
|
|
2076
|
+
fieldGoalpost: {
|
|
2077
|
+
property: "--playmaker-field-goalpost",
|
|
2078
|
+
fallback: _r
|
|
2079
|
+
},
|
|
2080
|
+
fieldGrid: {
|
|
2081
|
+
property: "--playmaker-field-grid",
|
|
2082
|
+
fallback: "rgba(0, 0, 0, 0.1)"
|
|
2083
|
+
},
|
|
2084
|
+
playerColor: {
|
|
2085
|
+
property: "--playmaker-player-color",
|
|
2086
|
+
fallback: X
|
|
2087
|
+
},
|
|
2088
|
+
playerLabel: {
|
|
2089
|
+
property: "--playmaker-player-label",
|
|
2090
|
+
fallback: lr
|
|
2091
|
+
},
|
|
2092
|
+
lineRoute: {
|
|
2093
|
+
property: "--playmaker-line-route",
|
|
2094
|
+
fallback: X
|
|
2095
|
+
},
|
|
2096
|
+
lineBlock: {
|
|
2097
|
+
property: "--playmaker-line-block",
|
|
2098
|
+
fallback: X
|
|
2099
|
+
},
|
|
2100
|
+
lineMotion: {
|
|
2101
|
+
property: "--playmaker-line-motion",
|
|
2102
|
+
fallback: X
|
|
2103
|
+
},
|
|
2104
|
+
swatch1: {
|
|
2105
|
+
property: "--playmaker-swatch-1",
|
|
2106
|
+
fallback: X
|
|
2107
|
+
},
|
|
2108
|
+
swatch2: {
|
|
2109
|
+
property: "--playmaker-swatch-2",
|
|
2110
|
+
fallback: ur
|
|
2111
|
+
},
|
|
2112
|
+
swatch3: {
|
|
2113
|
+
property: "--playmaker-swatch-3",
|
|
2114
|
+
fallback: dr
|
|
2115
|
+
},
|
|
2116
|
+
swatch4: {
|
|
2117
|
+
property: "--playmaker-swatch-4",
|
|
2118
|
+
fallback: fr
|
|
2119
|
+
},
|
|
2120
|
+
selection: {
|
|
2121
|
+
property: "--playmaker-selection",
|
|
2122
|
+
fallback: pr
|
|
2123
|
+
},
|
|
2124
|
+
selectionOutline: {
|
|
2125
|
+
property: "--playmaker-selection-outline",
|
|
2126
|
+
fallback: lr
|
|
2127
|
+
}
|
|
2128
|
+
};
|
|
2129
|
+
function yr(e) {
|
|
2130
|
+
return (t) => {
|
|
2131
|
+
let { property: n, fallback: r } = vr[t], i = e(n).trim();
|
|
2132
|
+
return i === "" ? r : i;
|
|
2133
|
+
};
|
|
2134
|
+
}
|
|
2135
|
+
// src/browser/theme/theme-reader.ts
|
|
2136
|
+
function Z(e) {
|
|
2137
|
+
let t = getComputedStyle(e), n = /* @__PURE__ */ new Map();
|
|
2138
|
+
for (let { property: e } of Object.values(vr)) n.set(e, cr(t.getPropertyValue(e).trim()) ?? "");
|
|
2139
|
+
return yr((e) => n.get(e) ?? "");
|
|
2140
|
+
}
|
|
2141
|
+
// src/browser/rendering/field-renderer.ts
|
|
2142
|
+
var br = .8, xr = .3, Sr = 2.5, Cr = 6, wr = .18;
|
|
2143
|
+
function Tr(e) {
|
|
2144
|
+
return {
|
|
2145
|
+
fieldColor: e("fieldGrass"),
|
|
2146
|
+
oobColor: e("fieldOob"),
|
|
2147
|
+
endzoneColor: e("fieldEndzone"),
|
|
2148
|
+
lineColor: e("fieldLine"),
|
|
2149
|
+
goalLineColor: e("fieldGoalLine"),
|
|
2150
|
+
numberColor: e("fieldNumber"),
|
|
2151
|
+
pylonColor: e("fieldPylon"),
|
|
2152
|
+
goalpostColor: e("fieldGoalpost")
|
|
2153
|
+
};
|
|
2154
|
+
}
|
|
2155
|
+
var Er = class {
|
|
2156
|
+
draw(e, t) {
|
|
2157
|
+
let { geometry: n, metrics: r } = t, i = Tr(t.theme), { viewportWidth: a, viewportHeight: o, yardWindow: s } = n, c = {
|
|
2158
|
+
left: n.xForLateralYard(0),
|
|
2159
|
+
right: n.xForLateralYard(53),
|
|
2160
|
+
top: n.yForAbsoluteYard(s.endYard),
|
|
2161
|
+
bottom: n.yForAbsoluteYard(s.startYard)
|
|
2162
|
+
};
|
|
2163
|
+
e.fillStyle = i.oobColor, e.fillRect(0, 0, a, o), e.fillStyle = i.fieldColor, e.fillRect(c.left, c.top, c.right - c.left, c.bottom - c.top), this.drawEndZones(e, n, c, i), this.drawHashes(e, n, c, r, i), this.drawYardLines(e, n, c, r, i), this.drawNumbers(e, n, r, i), this.drawEndZoneMarkers(e, n, c, r, i);
|
|
2164
|
+
}
|
|
2165
|
+
drawEndZones(e, t, { left: n, right: r }, i) {
|
|
2166
|
+
let { startYard: a, endYard: o } = t.yardWindow;
|
|
2167
|
+
if (e.fillStyle = i.endzoneColor, a < 0) {
|
|
2168
|
+
let i = t.yForAbsoluteYard(0), o = t.yForAbsoluteYard(a);
|
|
2169
|
+
e.fillRect(n, i, r - n, o - i);
|
|
2170
|
+
}
|
|
2171
|
+
if (o > 100) {
|
|
2172
|
+
let i = t.yForAbsoluteYard(o), a = t.yForAbsoluteYard(100);
|
|
2173
|
+
e.fillRect(n, i, r - n, a - i);
|
|
2174
|
+
}
|
|
2175
|
+
}
|
|
2176
|
+
drawHashes(e, t, { left: n, right: r }, i, a) {
|
|
2177
|
+
let o = Nt[Pt], s = 53 / 2, c = t.xForLateralYard(s - o), l = t.xForLateralYard(s + o), u = i.hashTickLength, d = u / 2;
|
|
2178
|
+
e.strokeStyle = a.lineColor, e.lineWidth = i.yardLineWidth, e.beginPath();
|
|
2179
|
+
for (let i of w(t.zone, 1)) {
|
|
2180
|
+
if (i < 0 || i > 100 || i % 5 == 0) continue;
|
|
2181
|
+
let a = t.yForAbsoluteYard(i);
|
|
2182
|
+
e.moveTo(n, a), e.lineTo(n + u, a), e.moveTo(r - u, a), e.lineTo(r, a), e.moveTo(c - d, a), e.lineTo(c + d, a), e.moveTo(l - d, a), e.lineTo(l + d, a);
|
|
2183
|
+
}
|
|
2184
|
+
e.stroke();
|
|
2185
|
+
}
|
|
2186
|
+
drawYardLines(e, t, { left: n, right: r, top: i, bottom: a }, o, s) {
|
|
2187
|
+
let c = new Path2D(), l = new Path2D(), u = new Path2D();
|
|
2188
|
+
for (let e of w(t.zone, 5)) {
|
|
2189
|
+
if (e < 0 || e > 100) continue;
|
|
2190
|
+
let i = t.yForAbsoluteYard(e), a = e === 0 || e === 100 ? c : e === 50 ? l : u;
|
|
2191
|
+
a.moveTo(n, i), a.lineTo(r, i);
|
|
2192
|
+
}
|
|
2193
|
+
e.strokeStyle = s.lineColor, e.lineWidth = o.yardLineWidth, e.stroke(u), e.lineWidth = o.midfieldLineWidth, e.stroke(l), e.lineWidth = o.goalLineWidth, e.beginPath(), e.moveTo(n, i), e.lineTo(n, a), e.moveTo(r, i), e.lineTo(r, a), e.moveTo(n, i), e.lineTo(r, i), e.moveTo(n, a), e.lineTo(r, a), e.stroke(), e.strokeStyle = s.goalLineColor, e.lineWidth = o.goalLineWidth, e.stroke(c);
|
|
2194
|
+
}
|
|
2195
|
+
drawNumbers(e, t, n, r) {
|
|
2196
|
+
let i = t.xForLateralYard(Cr), a = t.xForLateralYard(53 - Cr), o = xr * t.scale, s = br / 2;
|
|
2197
|
+
e.font = nr(n.numberHeight), e.textBaseline = "middle", e.textAlign = "center";
|
|
2198
|
+
let c = n.numberHeight * wr, l = (t, n, r, i) => {
|
|
2199
|
+
let [a, o] = [...t];
|
|
2200
|
+
e.save(), e.translate(n, r), e.rotate(i), t.length === 2 && a !== void 0 && o !== void 0 ? (e.fillText(a, -c / 2 - e.measureText(a).width / 2, 0), e.fillText(o, c / 2 + e.measureText(o).width / 2, 0)) : e.fillText(t, 0, 0), e.restore();
|
|
2201
|
+
}, u = (t, n, r) => {
|
|
2202
|
+
e.beginPath(), e.moveTo(t, n), e.lineTo(t - o, r), e.lineTo(t + o, r), e.closePath(), e.fill();
|
|
2203
|
+
};
|
|
2204
|
+
for (let n of w(t.zone, 10)) {
|
|
2205
|
+
let o = Rt(n);
|
|
2206
|
+
if (o === null) continue;
|
|
2207
|
+
let c = t.yForAbsoluteYard(n);
|
|
2208
|
+
if (e.fillStyle = r.numberColor, l(String(o), i, c, Math.PI / 2), l(String(o), a, c, -Math.PI / 2), n === 50) continue;
|
|
2209
|
+
let d = n < 50 ? -1 : 1, f = n + d * Sr, p = t.yForAbsoluteYard(f + d * s), m = t.yForAbsoluteYard(f - d * s);
|
|
2210
|
+
e.fillStyle = r.lineColor, u(i, p, m), u(a, p, m);
|
|
2211
|
+
}
|
|
2212
|
+
}
|
|
2213
|
+
drawEndZoneMarkers(e, t, { left: n, right: r }, i, a) {
|
|
2214
|
+
let { startYard: o, endYard: s } = t.yardWindow, c = i.pylonSize, l = (t, n) => {
|
|
2215
|
+
e.fillStyle = a.pylonColor, e.fillRect(t - c / 2, n - c / 2, c, c);
|
|
2216
|
+
};
|
|
2217
|
+
if (o < 0) {
|
|
2218
|
+
let s = t.yForAbsoluteYard(0), c = t.yForAbsoluteYard(o);
|
|
2219
|
+
l(n, s), l(r, s), l(n, c), l(r, c), this.drawGoalpost(e, t, c, "toward-top", i, a);
|
|
2220
|
+
}
|
|
2221
|
+
if (s > 100) {
|
|
2222
|
+
let o = t.yForAbsoluteYard(100), c = t.yForAbsoluteYard(s);
|
|
2223
|
+
l(n, o), l(r, o), l(n, c), l(r, c), this.drawGoalpost(e, t, c, "toward-bottom", i, a);
|
|
2224
|
+
}
|
|
2225
|
+
}
|
|
2226
|
+
drawGoalpost(e, t, n, r, i, a) {
|
|
2227
|
+
let o = t.xForLateralYard(53 / 2), s = i.goalpostCrossbarHalfLength, c = i.goalpostUprightLength, l = r === "toward-top" ? -1 : 1;
|
|
2228
|
+
e.save(), e.strokeStyle = a.goalpostColor, e.lineWidth = i.goalpostStroke, e.lineCap = "round", e.beginPath(), e.moveTo(o - s, n), e.lineTo(o + s, n), e.moveTo(o - s, n), e.lineTo(o - s, n + l * c), e.moveTo(o + s, n), e.lineTo(o + s, n + l * c), e.stroke(), e.restore();
|
|
2229
|
+
}
|
|
2230
|
+
}, Dr = class {
|
|
2231
|
+
cached;
|
|
2232
|
+
draw(e, t) {
|
|
2233
|
+
let { geometry: n, metrics: r } = t, i = [
|
|
2234
|
+
n.zone,
|
|
2235
|
+
n.offsetX,
|
|
2236
|
+
n.offsetY,
|
|
2237
|
+
n.scale,
|
|
2238
|
+
r.gridDotRadius
|
|
2239
|
+
].join(":");
|
|
2240
|
+
this.cached?.key !== i && (this.cached = {
|
|
2241
|
+
key: i,
|
|
2242
|
+
dots: Or(n, r.gridDotRadius)
|
|
2243
|
+
}), e.fillStyle = t.theme("fieldGrid"), e.fill(this.cached.dots);
|
|
2244
|
+
}
|
|
2245
|
+
};
|
|
2246
|
+
function Or(e, t) {
|
|
2247
|
+
let n = new Path2D(), i = 2 * t;
|
|
2248
|
+
for (let a of w(e.zone, r)) {
|
|
2249
|
+
let { startYard: o, endYard: s } = e.yardWindow;
|
|
2250
|
+
if (a >= 0 && a <= 100 && a % 5 == 0 || a === o || a === s) continue;
|
|
2251
|
+
let c = e.yForAbsoluteYard(a);
|
|
2252
|
+
for (let a = r; a < 53; a += r) n.rect(e.xForLateralYard(a) - t, c - t, i, i);
|
|
2253
|
+
}
|
|
2254
|
+
return n;
|
|
2255
|
+
}
|
|
2256
|
+
// src/browser/rendering/line-renderer.ts
|
|
2257
|
+
var kr = {
|
|
2258
|
+
route: "lineRoute",
|
|
2259
|
+
block: "lineBlock",
|
|
2260
|
+
motion: "lineMotion"
|
|
2261
|
+
}, Ar = class {
|
|
2262
|
+
draw(e, t) {
|
|
2263
|
+
let { geometry: n, metrics: r } = t, { lines: i, players: a } = t.scene;
|
|
2264
|
+
if (n.scale <= 0 || i.length === 0) return;
|
|
2265
|
+
let o = $e(a);
|
|
2266
|
+
for (let a of i) {
|
|
2267
|
+
let i = Qe(a, o);
|
|
2268
|
+
if (i === void 0) continue;
|
|
2269
|
+
let s = Kt(i, a.interpolation).map((e) => n.toCanvas(e));
|
|
2270
|
+
if (s.length < 2) continue;
|
|
2271
|
+
let c = a.color ?? t.theme(kr[a.kind]), l = this.widthFor(a.kind, r) * (a.thickness ?? 1), u = a.kind === "block";
|
|
2272
|
+
e.save(), e.strokeStyle = c, e.lineWidth = l, e.lineJoin = "round", e.lineCap = "round", a.kind === "motion" && e.setLineDash([...r.motionDash]);
|
|
2273
|
+
let d = u ? s : Hn(s, r.arrowLength);
|
|
2274
|
+
e.beginPath();
|
|
2275
|
+
for (let t of d) e.lineTo(t.x, t.y);
|
|
2276
|
+
e.stroke(), e.setLineDash([]), u ? this.drawBlockCap(e, s, c, r, l) : this.drawArrowHead(e, s, c, r), e.restore();
|
|
2277
|
+
}
|
|
2278
|
+
}
|
|
2279
|
+
widthFor(e, t) {
|
|
2280
|
+
return e === "block" ? t.blockWidth : t.routeWidth;
|
|
2281
|
+
}
|
|
2282
|
+
drawArrowHead(e, t, n, r) {
|
|
2283
|
+
let i = Un(t, r.arrowLength, r.arrowHalfWidth);
|
|
2284
|
+
if (i === void 0) return;
|
|
2285
|
+
let [a, o, s] = i;
|
|
2286
|
+
e.beginPath(), e.moveTo(a.x, a.y), e.lineTo(o.x, o.y), e.lineTo(s.x, s.y), e.closePath(), e.fillStyle = n, e.fill();
|
|
2287
|
+
}
|
|
2288
|
+
drawBlockCap(e, t, n, r, i) {
|
|
2289
|
+
let a = Wn(t, r.blockCapLength);
|
|
2290
|
+
if (a === void 0) return;
|
|
2291
|
+
let [o, s] = a;
|
|
2292
|
+
e.beginPath(), e.strokeStyle = n, e.lineWidth = i * 1.2, e.lineCap = "round", e.moveTo(o.x, o.y), e.lineTo(s.x, s.y), e.stroke();
|
|
2293
|
+
}
|
|
2294
|
+
}, jr = class {
|
|
2295
|
+
draw(e, t) {
|
|
2296
|
+
let { overlay: n } = t;
|
|
2297
|
+
switch (n.kind) {
|
|
2298
|
+
case "none": return;
|
|
2299
|
+
case "player":
|
|
2300
|
+
Mr(e, t, n.playerId);
|
|
2301
|
+
return;
|
|
2302
|
+
case "line":
|
|
2303
|
+
Nr(e, t, n);
|
|
2304
|
+
return;
|
|
2305
|
+
}
|
|
2306
|
+
}
|
|
2307
|
+
};
|
|
2308
|
+
function Mr(e, t, n) {
|
|
2309
|
+
let r = t.scene.players.find((e) => e.id === n);
|
|
2310
|
+
if (r === void 0) return;
|
|
2311
|
+
let { x: i, y: a } = t.geometry.toCanvas(r.position), o = m * t.geometry.scale + 4;
|
|
2312
|
+
e.beginPath(), e.arc(i, a, o, 0, Math.PI * 2), e.strokeStyle = t.theme("selection"), e.lineWidth = 2, e.stroke();
|
|
2313
|
+
}
|
|
2314
|
+
function Nr(e, t, n) {
|
|
2315
|
+
let { geometry: r } = t, i = t.theme("selection"), a = t.theme("selectionOutline"), o = Math.max(3, .45 * Qt * r.scale), s = () => {
|
|
2316
|
+
e.fillStyle = i, e.fill(), e.lineWidth = 1.5, e.strokeStyle = a, e.stroke();
|
|
2317
|
+
};
|
|
2318
|
+
for (let t of n.waypointHandles) {
|
|
2319
|
+
let { x: n, y: i } = r.toCanvas(t);
|
|
2320
|
+
e.beginPath(), e.rect(n - o, i - o, o * 2, o * 2), s();
|
|
2321
|
+
}
|
|
2322
|
+
let { x: c, y: l } = r.toCanvas(n.endpointHandle);
|
|
2323
|
+
e.beginPath(), e.arc(c, l, o + 1, 0, Math.PI * 2), s();
|
|
2324
|
+
}
|
|
2325
|
+
// src/browser/rendering/player-renderer.ts
|
|
2326
|
+
var Pr = class {
|
|
2327
|
+
draw(e, t) {
|
|
2328
|
+
let { geometry: n, metrics: r } = t, { players: i } = t.scene, a = t.theme("playerColor"), o = t.theme("fieldGrass"), s = t.theme("playerLabel"), c = m * n.scale;
|
|
2329
|
+
if (c <= 0) return;
|
|
2330
|
+
let l = r.markerLabelFont;
|
|
2331
|
+
for (let t of i) {
|
|
2332
|
+
let i = n.toCanvas(t.position), u = t.color ?? a, d = (t.fill ?? "outline") === "solid";
|
|
2333
|
+
e.beginPath();
|
|
2334
|
+
let f = Kn(t.shape, c);
|
|
2335
|
+
if (f.kind === "circle") e.arc(i.x, i.y, f.radius, 0, Math.PI * 2);
|
|
2336
|
+
else {
|
|
2337
|
+
let { halfSide: t } = f;
|
|
2338
|
+
e.rect(i.x - t, i.y - t, t * 2, t * 2);
|
|
2339
|
+
}
|
|
2340
|
+
if (e.fillStyle = d ? u : o, e.fill(), e.lineWidth = r.markerStroke, e.strokeStyle = u, e.stroke(), t.label !== "") {
|
|
2341
|
+
e.fillStyle = d ? s : u, e.font = nr(l), e.textAlign = "center", e.textBaseline = "alphabetic";
|
|
2342
|
+
let n = e.measureText(t.label), r = i.y + (n.actualBoundingBoxAscent - n.actualBoundingBoxDescent) / 2;
|
|
2343
|
+
e.fillText(t.label, i.x, r);
|
|
2344
|
+
}
|
|
2345
|
+
}
|
|
2346
|
+
}
|
|
2347
|
+
};
|
|
2348
|
+
// src/browser/rendering/layer.ts
|
|
2349
|
+
function Fr() {
|
|
2350
|
+
return {
|
|
2351
|
+
field: [new Er()],
|
|
2352
|
+
backdrop: [new Dr()],
|
|
2353
|
+
play: [new Ar(), new Pr()],
|
|
2354
|
+
editor: [new jr()]
|
|
2355
|
+
};
|
|
2356
|
+
}
|
|
2357
|
+
function Q(e, t, n) {
|
|
2358
|
+
for (let r of n) e.save(), r.draw(e, t), e.restore();
|
|
2359
|
+
}
|
|
2360
|
+
// src/browser/rendering/canvas-surface.ts
|
|
2361
|
+
var Ir = class extends n {
|
|
2362
|
+
canvas;
|
|
2363
|
+
ctx;
|
|
2364
|
+
layers;
|
|
2365
|
+
scene;
|
|
2366
|
+
overlay;
|
|
2367
|
+
frameRequest;
|
|
2368
|
+
dpr = 0;
|
|
2369
|
+
lifetime = new AbortController();
|
|
2370
|
+
constructor(t, n, r, i = Fr()) {
|
|
2371
|
+
super(), this.scene = n, this.overlay = r, this.layers = i, this.canvas = document.createElement("canvas"), this.canvas.className = "playmaker-canvas", t.appendChild(this.canvas), this._register(e(() => this.canvas.remove()));
|
|
2372
|
+
let a = this.canvas.getContext("2d");
|
|
2373
|
+
if (!a) throw Error("Playmaker: 2D canvas context を取得できませんでした。");
|
|
2374
|
+
this.ctx = a;
|
|
2375
|
+
let o = new ResizeObserver(() => this.resize());
|
|
2376
|
+
o.observe(t), this._register(e(() => {
|
|
2377
|
+
o.disconnect(), this.lifetime.abort(), this.cancelFrame();
|
|
2378
|
+
})), this.watchDevicePixelRatio(), this.redrawWhenFontLoads();
|
|
2379
|
+
}
|
|
2380
|
+
refresh() {
|
|
2381
|
+
this.invalidate();
|
|
2382
|
+
}
|
|
2383
|
+
setScene(e, t) {
|
|
2384
|
+
this.scene = e, this.overlay = t, this.invalidate();
|
|
2385
|
+
}
|
|
2386
|
+
clientToYard(e, t) {
|
|
2387
|
+
let n = this.canvas.getBoundingClientRect();
|
|
2388
|
+
return this.measure().fromCanvas({
|
|
2389
|
+
x: e - n.left,
|
|
2390
|
+
y: t - n.top
|
|
2391
|
+
});
|
|
2392
|
+
}
|
|
2393
|
+
async exportToPngBlob(e, t) {
|
|
2394
|
+
let { width: n, height: r } = Dn(e.field.zone, t), i = Z(this.host);
|
|
2395
|
+
await ir();
|
|
2396
|
+
let a = document.createElement("canvas");
|
|
2397
|
+
a.width = n, a.height = r;
|
|
2398
|
+
let o = a.getContext("2d");
|
|
2399
|
+
if (!o) throw Error("Playmaker: エクスポート用 2D canvas context を取得できませんでした。");
|
|
2400
|
+
let s = new zt(n, r, e.field);
|
|
2401
|
+
return this.paint(o, this.frameFor(s, e, i), void 0), new Promise((e, t) => {
|
|
2402
|
+
a.toBlob((n) => {
|
|
2403
|
+
n ? e(n) : t(/* @__PURE__ */ Error("Playmaker: PNG への変換に失敗しました。"));
|
|
2404
|
+
}, "image/png");
|
|
2405
|
+
});
|
|
2406
|
+
}
|
|
2407
|
+
redrawWhenFontLoads() {
|
|
2408
|
+
ir().then(() => {
|
|
2409
|
+
this.isDisposed || this.invalidate();
|
|
2410
|
+
});
|
|
2411
|
+
}
|
|
2412
|
+
resize() {
|
|
2413
|
+
let e = window.devicePixelRatio || 1, { clientWidth: t, clientHeight: n } = this.host, r = Math.max(1, Math.round(t * e)), i = Math.max(1, Math.round(n * e));
|
|
2414
|
+
(r !== this.canvas.width || i !== this.canvas.height || e !== this.dpr) && (this.dpr = e, this.canvas.width = r, this.canvas.height = i, this.ctx.setTransform(e, 0, 0, e, 0, 0), this.cancelFrame(), this.render());
|
|
2415
|
+
}
|
|
2416
|
+
watchDevicePixelRatio() {
|
|
2417
|
+
window.matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`).addEventListener("change", () => {
|
|
2418
|
+
this.resize(), this.watchDevicePixelRatio();
|
|
2419
|
+
}, {
|
|
2420
|
+
once: !0,
|
|
2421
|
+
signal: this.lifetime.signal
|
|
2422
|
+
});
|
|
2423
|
+
}
|
|
2424
|
+
invalidate() {
|
|
2425
|
+
this.frameRequest === void 0 && this.dpr !== 0 && (this.frameRequest = requestAnimationFrame(() => {
|
|
2426
|
+
this.frameRequest = void 0, this.render();
|
|
2427
|
+
}));
|
|
2428
|
+
}
|
|
2429
|
+
cancelFrame() {
|
|
2430
|
+
this.frameRequest !== void 0 && (cancelAnimationFrame(this.frameRequest), this.frameRequest = void 0);
|
|
2431
|
+
}
|
|
2432
|
+
render() {
|
|
2433
|
+
let e = this.frameFor(this.measure(), this.scene, Z(this.host));
|
|
2434
|
+
this.paint(this.ctx, e, this.overlay);
|
|
2435
|
+
}
|
|
2436
|
+
paint(e, t, n) {
|
|
2437
|
+
let r = n === void 0 ? void 0 : {
|
|
2438
|
+
...t,
|
|
2439
|
+
overlay: n
|
|
2440
|
+
};
|
|
2441
|
+
Q(e, t, this.layers.field), r !== void 0 && Q(e, r, this.layers.backdrop), Q(e, t, this.layers.play), r !== void 0 && Q(e, r, this.layers.editor);
|
|
2442
|
+
}
|
|
2443
|
+
frameFor(e, t, n) {
|
|
2444
|
+
return {
|
|
2445
|
+
geometry: e,
|
|
2446
|
+
metrics: Oe(e.fieldPixelWidth, e.scale),
|
|
2447
|
+
scene: t,
|
|
2448
|
+
theme: n
|
|
2449
|
+
};
|
|
2450
|
+
}
|
|
2451
|
+
measure() {
|
|
2452
|
+
let { clientWidth: e, clientHeight: t } = this.host;
|
|
2453
|
+
return new zt(e, t, this.scene.field);
|
|
2454
|
+
}
|
|
2455
|
+
get host() {
|
|
2456
|
+
return this.canvas.parentElement ?? this.canvas;
|
|
2457
|
+
}
|
|
2458
|
+
};
|
|
2459
|
+
// src/browser/ui/focus.ts
|
|
2460
|
+
function Lr(e, t, n) {
|
|
2461
|
+
let r = e.ownerDocument, i = e.contains(r.activeElement);
|
|
2462
|
+
n(), i && !e.contains(r.activeElement) && t.focus({ preventScroll: !0 });
|
|
2463
|
+
}
|
|
2464
|
+
// src/browser/theme/palette.ts
|
|
2465
|
+
var Rr = [
|
|
2466
|
+
{
|
|
2467
|
+
label: "黒",
|
|
2468
|
+
token: "swatch1"
|
|
2469
|
+
},
|
|
2470
|
+
{
|
|
2471
|
+
label: "赤",
|
|
2472
|
+
token: "swatch2"
|
|
2473
|
+
},
|
|
2474
|
+
{
|
|
2475
|
+
label: "青",
|
|
2476
|
+
token: "swatch3"
|
|
2477
|
+
},
|
|
2478
|
+
{
|
|
2479
|
+
label: "緑",
|
|
2480
|
+
token: "swatch4"
|
|
2481
|
+
}
|
|
2482
|
+
], zr = {
|
|
2483
|
+
circle: "丸",
|
|
2484
|
+
square: "四角"
|
|
2485
|
+
}, Br = {
|
|
2486
|
+
outline: "枠線",
|
|
2487
|
+
solid: "塗りつぶし"
|
|
2488
|
+
}, Vr = {
|
|
2489
|
+
route: "ルート",
|
|
2490
|
+
block: "ブロック",
|
|
2491
|
+
motion: "モーション"
|
|
2492
|
+
}, Hr = {
|
|
2493
|
+
straight: "直線",
|
|
2494
|
+
bezier: "曲線"
|
|
2495
|
+
};
|
|
2496
|
+
function Ur({ name: e, color: t, fill: n }) {
|
|
2497
|
+
let r = document.createElement("button");
|
|
2498
|
+
return r.type = "button", r.className = "playmaker-panel__swatch", r.title = e, r.setAttribute("aria-label", e), n === "outline" ? (r.classList.add("playmaker-panel__swatch--outline"), r.style.borderColor = t) : r.style.backgroundColor = t, r;
|
|
2499
|
+
}
|
|
2500
|
+
var Wr = class extends n {
|
|
2501
|
+
element;
|
|
2502
|
+
controller;
|
|
2503
|
+
focusFallback;
|
|
2504
|
+
shown;
|
|
2505
|
+
constructor(t, n, r) {
|
|
2506
|
+
super(), this.controller = n, this.focusFallback = r, this.element = document.createElement("div"), this.element.className = "playmaker-panel", t.appendChild(this.element), this._register(e(() => this.element.remove())), this._register(n.onDidChangeViewState(() => this.sync())), this.sync();
|
|
2507
|
+
}
|
|
2508
|
+
refresh() {
|
|
2509
|
+
this.shown = void 0, this.sync();
|
|
2510
|
+
}
|
|
2511
|
+
sync() {
|
|
2512
|
+
let e = this.selectedItem(), t = this.shown;
|
|
2513
|
+
e.kind === "player" && t?.kind === "player" && t.id === e.player.id ? t.update(e.player) : e.kind === "line" && t?.kind === "line" && t.id === e.line.id ? t.update(e.line) : (e.kind !== "none" || t?.kind !== "hint") && Lr(this.element, this.focusFallback, () => {
|
|
2514
|
+
this.shown = this.rebuild(e);
|
|
2515
|
+
});
|
|
2516
|
+
}
|
|
2517
|
+
selectedItem() {
|
|
2518
|
+
let e = this.controller.getSelectedPlayer();
|
|
2519
|
+
if (e !== void 0) return {
|
|
2520
|
+
kind: "player",
|
|
2521
|
+
player: e
|
|
2522
|
+
};
|
|
2523
|
+
let t = this.controller.getSelectedLine();
|
|
2524
|
+
return t === void 0 ? { kind: "none" } : {
|
|
2525
|
+
kind: "line",
|
|
2526
|
+
line: t
|
|
2527
|
+
};
|
|
2528
|
+
}
|
|
2529
|
+
rebuild(e) {
|
|
2530
|
+
switch (this.element.replaceChildren(), e.kind) {
|
|
2531
|
+
case "player": {
|
|
2532
|
+
let t = this.addPlayerFields();
|
|
2533
|
+
return t(e.player), {
|
|
2534
|
+
kind: "player",
|
|
2535
|
+
id: e.player.id,
|
|
2536
|
+
update: t
|
|
2537
|
+
};
|
|
2538
|
+
}
|
|
2539
|
+
case "line": {
|
|
2540
|
+
let t = this.addLineFields();
|
|
2541
|
+
return t(e.line), {
|
|
2542
|
+
kind: "line",
|
|
2543
|
+
id: e.line.id,
|
|
2544
|
+
update: t
|
|
2545
|
+
};
|
|
2546
|
+
}
|
|
2547
|
+
case "none": {
|
|
2548
|
+
let e = document.createElement("p");
|
|
2549
|
+
return e.className = "playmaker-panel__hint", e.textContent = "対象を選択するとプロパティを編集できます", this.element.appendChild(e), { kind: "hint" };
|
|
2550
|
+
}
|
|
2551
|
+
}
|
|
2552
|
+
}
|
|
2553
|
+
addPlayerFields() {
|
|
2554
|
+
let e = this.controller;
|
|
2555
|
+
this.addTitle("選手");
|
|
2556
|
+
let t = this.addText({
|
|
2557
|
+
label: "ラベル",
|
|
2558
|
+
onChange: (t) => e.updateSelectedPlayer({ label: t })
|
|
2559
|
+
}), n = this.addSelect("形状", d, zr, (t) => e.updateSelectedPlayer({ shape: t })), r = Z(this.element), i = p.flatMap((e) => Rr.map((t) => ({
|
|
2560
|
+
name: `${t.label}の${Br[e]}`,
|
|
2561
|
+
color: r(t.token),
|
|
2562
|
+
fill: e
|
|
2563
|
+
}))), a = this.addSwatches("色", i, {
|
|
2564
|
+
onChange: ({ color: t, fill: n }) => e.updateSelectedPlayer({
|
|
2565
|
+
color: t,
|
|
2566
|
+
fill: n
|
|
2567
|
+
}),
|
|
2568
|
+
onReset: () => e.updateSelectedPlayer({
|
|
2569
|
+
color: null,
|
|
2570
|
+
fill: null
|
|
2571
|
+
})
|
|
2572
|
+
}), o = r("playerColor");
|
|
2573
|
+
return (e) => {
|
|
2574
|
+
t(e.label), n(e.shape);
|
|
2575
|
+
let r = e.color === void 0 ? o : cr(e.color), i = e.fill ?? "outline";
|
|
2576
|
+
a((e) => e.color === r && e.fill === i);
|
|
2577
|
+
};
|
|
2578
|
+
}
|
|
2579
|
+
addLineFields() {
|
|
2580
|
+
let e = this.controller;
|
|
2581
|
+
this.addTitle("線");
|
|
2582
|
+
let t = this.addSelect("種別", He, Vr, (t) => e.updateSelectedLine({ kind: t })), n = this.addSelect("補間", Ue, Hr, (t) => e.updateSelectedLine({ interpolation: t })), r = Z(this.element), i = Rr.map((e) => ({
|
|
2583
|
+
name: e.label,
|
|
2584
|
+
color: r(e.token),
|
|
2585
|
+
fill: "solid"
|
|
2586
|
+
})), a = this.addSwatches("色", i, {
|
|
2587
|
+
onChange: ({ color: t }) => e.updateSelectedLine({ color: t }),
|
|
2588
|
+
onReset: () => e.updateSelectedLine({ color: null })
|
|
2589
|
+
}), o = this.addNumber({
|
|
2590
|
+
label: "太さ",
|
|
2591
|
+
onChange: (t) => e.updateSelectedLine({ thickness: t }),
|
|
2592
|
+
onReset: () => e.updateSelectedLine({ thickness: null })
|
|
2593
|
+
});
|
|
2594
|
+
return (e) => {
|
|
2595
|
+
t(e.kind), n(e.interpolation);
|
|
2596
|
+
let r = e.color === void 0 ? void 0 : cr(e.color);
|
|
2597
|
+
a((e) => e.color === r), o(e.thickness ?? 1);
|
|
2598
|
+
};
|
|
2599
|
+
}
|
|
2600
|
+
addTitle(e) {
|
|
2601
|
+
let t = document.createElement("h2");
|
|
2602
|
+
t.className = "playmaker-panel__title", t.textContent = e, this.element.appendChild(t);
|
|
2603
|
+
}
|
|
2604
|
+
addRow(e, t, n) {
|
|
2605
|
+
let r = document.createElement("label");
|
|
2606
|
+
r.className = "playmaker-panel__label", r.append(this.createRowText(e), t), this.appendRow(e, [r], n);
|
|
2607
|
+
}
|
|
2608
|
+
addGroupRow(e, t, n) {
|
|
2609
|
+
t.setAttribute("role", "group"), t.setAttribute("aria-label", e), this.appendRow(e, [this.createRowText(e), t], n);
|
|
2610
|
+
}
|
|
2611
|
+
createRowText(e) {
|
|
2612
|
+
let t = document.createElement("span");
|
|
2613
|
+
return t.className = "playmaker-panel__row-text", t.textContent = e, t;
|
|
2614
|
+
}
|
|
2615
|
+
appendRow(e, t, n) {
|
|
2616
|
+
let r = document.createElement("div");
|
|
2617
|
+
if (r.className = "playmaker-panel__row", r.append(...t), n !== void 0) {
|
|
2618
|
+
let t = document.createElement("button");
|
|
2619
|
+
t.type = "button", t.className = "playmaker-panel__reset", t.textContent = "既定", t.setAttribute("aria-label", `${e}を既定に戻す`), t.addEventListener("click", n), r.appendChild(t);
|
|
2620
|
+
}
|
|
2621
|
+
this.element.appendChild(r);
|
|
2622
|
+
}
|
|
2623
|
+
addText({ label: e, onChange: t, onReset: n }) {
|
|
2624
|
+
let r = document.createElement("input");
|
|
2625
|
+
return r.type = "text", r.addEventListener("change", () => t(r.value)), this.addRow(e, r, n), (e) => {
|
|
2626
|
+
r.value = e;
|
|
2627
|
+
};
|
|
2628
|
+
}
|
|
2629
|
+
addNumber({ label: e, onChange: t, onReset: n }) {
|
|
2630
|
+
let r = document.createElement("input");
|
|
2631
|
+
return r.type = "number", r.min = "0.25", r.step = "0.25", r.addEventListener("change", () => {
|
|
2632
|
+
let e = Number(r.value);
|
|
2633
|
+
Je(e) && t(e);
|
|
2634
|
+
}), this.addRow(e, r, n), (e) => {
|
|
2635
|
+
r.value = String(e);
|
|
2636
|
+
};
|
|
2637
|
+
}
|
|
2638
|
+
addSwatches(e, t, { onChange: n, onReset: r }) {
|
|
2639
|
+
let i = document.createElement("div");
|
|
2640
|
+
i.className = "playmaker-panel__swatches", t.some((e) => e.fill === "outline") && i.classList.add("playmaker-panel__swatches--rows");
|
|
2641
|
+
let a = t.map((e) => {
|
|
2642
|
+
let t = Ur(e);
|
|
2643
|
+
return t.addEventListener("click", () => n(e)), i.appendChild(t), {
|
|
2644
|
+
btn: t,
|
|
2645
|
+
choice: e
|
|
2646
|
+
};
|
|
2647
|
+
});
|
|
2648
|
+
return this.addGroupRow(e, i, r), (e) => {
|
|
2649
|
+
for (let { btn: t, choice: n } of a) t.setAttribute("aria-pressed", String(e(n)));
|
|
2650
|
+
};
|
|
2651
|
+
}
|
|
2652
|
+
addSelect(e, t, n, r) {
|
|
2653
|
+
let i = document.createElement("select");
|
|
2654
|
+
for (let e of t) {
|
|
2655
|
+
let t = document.createElement("option");
|
|
2656
|
+
t.value = e, t.textContent = n[e], i.appendChild(t);
|
|
2657
|
+
}
|
|
2658
|
+
return i.addEventListener("change", () => {
|
|
2659
|
+
l(i.value, t) && r(i.value);
|
|
2660
|
+
}), this.addRow(e, i), (e) => {
|
|
2661
|
+
i.value = e;
|
|
2662
|
+
};
|
|
2663
|
+
}
|
|
2664
|
+
}, Gr = {
|
|
2665
|
+
select: "選択",
|
|
2666
|
+
"add-player": "選手を追加",
|
|
2667
|
+
"draw-line": "線を描く"
|
|
2668
|
+
}, Kr = "置くと 64 人を超えるフォーメーションは読み込めません", qr = {
|
|
2669
|
+
"add-player": "選手は 64 人までです",
|
|
2670
|
+
"draw-line": "線は 128 本までです"
|
|
2671
|
+
}, Jr = {
|
|
2672
|
+
offense: "オフェンス",
|
|
2673
|
+
defense: "ディフェンス"
|
|
2674
|
+
};
|
|
2675
|
+
function $(e, t, n) {
|
|
2676
|
+
e.setAttribute("aria-disabled", String(!t)), Yr(e, t ? void 0 : n);
|
|
2677
|
+
}
|
|
2678
|
+
function Yr(e, t) {
|
|
2679
|
+
t === void 0 ? e.removeAttribute("title") : e.title = t;
|
|
2680
|
+
}
|
|
2681
|
+
var Xr = class extends n {
|
|
2682
|
+
element;
|
|
2683
|
+
toolButtons = /* @__PURE__ */ new Map();
|
|
2684
|
+
zoneButtons = /* @__PURE__ */ new Map();
|
|
2685
|
+
undoButton;
|
|
2686
|
+
redoButton;
|
|
2687
|
+
deleteButton;
|
|
2688
|
+
commitButton;
|
|
2689
|
+
cancelButton;
|
|
2690
|
+
formationPicker;
|
|
2691
|
+
constructor(t, n) {
|
|
2692
|
+
super(), this.element = document.createElement("div"), this.element.className = "playmaker-toolbar";
|
|
2693
|
+
for (let e of ke) {
|
|
2694
|
+
let t = this.addButton(Gr[e], () => n.setTool(e));
|
|
2695
|
+
this.toolButtons.set(e, t);
|
|
2696
|
+
}
|
|
2697
|
+
this.addSeparator(), this.undoButton = this.addButton("元に戻す", () => n.undo()), this.redoButton = this.addButton("やり直す", () => n.redo()), this.deleteButton = this.addButton("削除", () => n.deleteSelection()), this.addSeparator();
|
|
2698
|
+
for (let e of et) {
|
|
2699
|
+
let t = this.addButton(nt[e], () => n.setFieldZone(e));
|
|
2700
|
+
this.zoneButtons.set(e, t);
|
|
2701
|
+
}
|
|
2702
|
+
this.addSeparator(), this.formationPicker = this.addFormationPicker(n), this.addSeparator(), this.commitButton = this.addButton("線を確定", () => n.commitLine()), this.cancelButton = this.addButton("取消", () => n.cancelInteraction()), t.appendChild(this.element), this._register(e(() => this.element.remove())), this._register(n.onDidChangeViewState(() => this.sync(n))), this.sync(n);
|
|
2703
|
+
}
|
|
2704
|
+
addButton(e, t) {
|
|
2705
|
+
let n = document.createElement("button");
|
|
2706
|
+
return n.type = "button", n.textContent = e, n.className = "playmaker-toolbar__button", n.addEventListener("click", () => {
|
|
2707
|
+
n.getAttribute("aria-disabled") !== "true" && t();
|
|
2708
|
+
}), this.element.appendChild(n), n;
|
|
2709
|
+
}
|
|
2710
|
+
addSeparator() {
|
|
2711
|
+
let e = document.createElement("span");
|
|
2712
|
+
e.className = "playmaker-toolbar__sep", e.setAttribute("aria-hidden", "true"), this.element.appendChild(e);
|
|
2713
|
+
}
|
|
2714
|
+
addFormationPicker(e) {
|
|
2715
|
+
let t = document.createElement("select");
|
|
2716
|
+
t.className = "playmaker-toolbar__select", t.setAttribute("aria-label", "フォーメーション");
|
|
2717
|
+
let n = document.createElement("option");
|
|
2718
|
+
n.value = "", n.textContent = "フォーメーション読込…", t.appendChild(n);
|
|
2719
|
+
for (let e of Fe) {
|
|
2720
|
+
let n = document.createElement("optgroup");
|
|
2721
|
+
n.label = Jr[e];
|
|
2722
|
+
for (let t of Rn.filter((t) => t.side === e)) {
|
|
2723
|
+
let e = document.createElement("option");
|
|
2724
|
+
e.value = t.id, e.textContent = t.name, n.appendChild(e);
|
|
2725
|
+
}
|
|
2726
|
+
t.appendChild(n);
|
|
2727
|
+
}
|
|
2728
|
+
return t.addEventListener("change", () => {
|
|
2729
|
+
let n = zn(t.value);
|
|
2730
|
+
n !== void 0 && e.loadFormation(n), t.value = "";
|
|
2731
|
+
}), this.element.appendChild(t), t;
|
|
2732
|
+
}
|
|
2733
|
+
sync(e) {
|
|
2734
|
+
let t = e.getViewState();
|
|
2735
|
+
for (let [e, n] of this.toolButtons) n.setAttribute("aria-pressed", String(e === t.tool)), $(n, je(e, t), qr[e]);
|
|
2736
|
+
for (let [e, n] of this.zoneButtons) n.setAttribute("aria-pressed", String(e === t.fieldZone));
|
|
2737
|
+
$(this.undoButton, t.canUndo), $(this.redoButton, t.canRedo), $(this.deleteButton, t.selection.kind !== "none"), $(this.commitButton, t.isDrawing), $(this.cancelButton, t.isDrawing), this.syncFormationPicker(t);
|
|
2738
|
+
}
|
|
2739
|
+
syncFormationPicker(e) {
|
|
2740
|
+
let t = !1;
|
|
2741
|
+
for (let n of this.formationPicker.options) {
|
|
2742
|
+
let r = zn(n.value);
|
|
2743
|
+
n.disabled = r !== void 0 && !Me(r, e), t ||= n.disabled;
|
|
2744
|
+
}
|
|
2745
|
+
Yr(this.formationPicker, t ? Kr : void 0);
|
|
2746
|
+
}
|
|
2747
|
+
};
|
|
2748
|
+
// src/playmaker.ts
|
|
2749
|
+
function Zr() {
|
|
2750
|
+
try {
|
|
2751
|
+
return process.env.NODE_ENV !== "production";
|
|
2752
|
+
} catch {
|
|
2753
|
+
return !1;
|
|
2754
|
+
}
|
|
2755
|
+
}
|
|
2756
|
+
var Qr = class {
|
|
2757
|
+
onDidChange;
|
|
2758
|
+
store = new t();
|
|
2759
|
+
root;
|
|
2760
|
+
surface;
|
|
2761
|
+
session;
|
|
2762
|
+
currentMode;
|
|
2763
|
+
panel;
|
|
2764
|
+
ui;
|
|
2765
|
+
constructor(t, n = {}) {
|
|
2766
|
+
this.currentMode = n.mode ?? "edit", this.session = this.store.add(new Cn(n.initialData)), this.onDidChange = this.session.onDidChange, n.onChange !== void 0 && this.store.add(this.session.onDidChange(n.onChange)), this.root = document.createElement("div"), this.root.className = "playmaker-root", this.root.dataset.mode = this.currentMode, t.appendChild(this.root), this.store.add(e(() => this.root.remove()));
|
|
2767
|
+
let r = document.createElement("div");
|
|
2768
|
+
r.className = "playmaker-stage", this.root.appendChild(r);
|
|
2769
|
+
let { scene: i, overlay: a } = this.session.controller.getFrame();
|
|
2770
|
+
this.surface = this.store.add(new Ir(r, i, this.surfaceOverlay(a))), this.ui = this.createUi(), this.store.add(this.session.onDidChangeScene(() => this.draw())), this.store.add(this.session.onDidReset(() => this.replaceUi()));
|
|
2771
|
+
}
|
|
2772
|
+
get mode() {
|
|
2773
|
+
return this.currentMode;
|
|
2774
|
+
}
|
|
2775
|
+
setMode(e) {
|
|
2776
|
+
this.store.isDisposed ? this.warnIgnoredAfterDispose("setMode") : e !== this.currentMode && (this.currentMode = e, this.root.dataset.mode = e, e === "view" && this.session.controller.cancelInteraction(), this.replaceUi(), this.draw());
|
|
2777
|
+
}
|
|
2778
|
+
get fieldZone() {
|
|
2779
|
+
return this.session.fieldZone;
|
|
2780
|
+
}
|
|
2781
|
+
setFieldZone(e) {
|
|
2782
|
+
this.store.isDisposed ? this.warnIgnoredAfterDispose("setFieldZone") : this.session.setFieldZone(e);
|
|
2783
|
+
}
|
|
2784
|
+
loadFormation(e) {
|
|
2785
|
+
return this.store.isDisposed ? (this.warnIgnoredAfterDispose("loadFormation"), !1) : this.session.loadFormation(e);
|
|
2786
|
+
}
|
|
2787
|
+
setPlayData(e) {
|
|
2788
|
+
this.store.isDisposed ? this.warnIgnoredAfterDispose("setPlayData") : this.session.setPlayData(e);
|
|
2789
|
+
}
|
|
2790
|
+
restorePlayData(e) {
|
|
2791
|
+
this.store.isDisposed ? this.warnIgnoredAfterDispose("restorePlayData") : this.session.setPlayData(e);
|
|
2792
|
+
}
|
|
2793
|
+
getPlayData() {
|
|
2794
|
+
return this.session.getPlayData();
|
|
2795
|
+
}
|
|
2796
|
+
exportToPng(e) {
|
|
2797
|
+
return this.store.isDisposed ? Promise.reject(/* @__PURE__ */ Error("Playmaker: dispose したあとは PNG を書き出せません。")) : this.surface.exportToPngBlob(this.session.getSnapshot(), e);
|
|
2798
|
+
}
|
|
2799
|
+
refresh() {
|
|
2800
|
+
this.store.isDisposed ? this.warnIgnoredAfterDispose("refresh") : (this.surface.refresh(), this.panel?.refresh());
|
|
2801
|
+
}
|
|
2802
|
+
dispose() {
|
|
2803
|
+
this.ui.dispose(), this.store.dispose();
|
|
2804
|
+
}
|
|
2805
|
+
warnIgnoredAfterDispose(e) {
|
|
2806
|
+
Zr() && console.warn(`Playmaker: dispose したあとに ${e} を呼んだので、何もしません。`);
|
|
2807
|
+
}
|
|
2808
|
+
replaceUi() {
|
|
2809
|
+
Lr(this.root, this.surface.canvas, () => {
|
|
2810
|
+
this.ui.dispose(), this.ui = this.createUi();
|
|
2811
|
+
});
|
|
2812
|
+
}
|
|
2813
|
+
createUi() {
|
|
2814
|
+
let e = new t(), n = this.session.controller;
|
|
2815
|
+
return this.panel = void 0, this.currentMode === "edit" && (e.add(new Xr(this.root, n)), this.panel = e.add(new Wr(this.root, n, this.surface.canvas)), e.add(new Qn(this.root, this.surface, n))), e;
|
|
2816
|
+
}
|
|
2817
|
+
draw() {
|
|
2818
|
+
let { scene: e, overlay: t } = this.session.controller.getFrame();
|
|
2819
|
+
this.surface.setScene(e, this.surfaceOverlay(t));
|
|
2820
|
+
}
|
|
2821
|
+
surfaceOverlay(e) {
|
|
2822
|
+
return this.currentMode === "edit" ? e : void 0;
|
|
2823
|
+
}
|
|
2824
|
+
};
|
|
2825
|
+
export { it as CURRENT_PLAY_DATA_VERSION, Mt as FIELD_WIDTH_YARDS, nt as FIELD_ZONE_LABELS, et as FIELD_ZONE_VALUES, Rn as FORMATION_PRESETS, r as GRID_STEP_YARDS, Yn as PLAY_PRESETS, Qr as Playmaker, zn as getFormationPreset, Xn as getPlayPreset, ht as migratePlayData };
|
|
2826
|
+
|
|
2827
|
+
//# sourceMappingURL=playmaker.js.map
|