@laplace.live/persona-sdk 1.24.0 → 1.25.1
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/README.md +10 -10
- package/dist/client/client.js +5 -6
- package/dist/client/legacy-names.d.ts +2 -0
- package/dist/client/{legacy-kinds.js → legacy-names.js} +12 -3
- package/dist/client/node.d.ts +13 -0
- package/dist/client/node.js +29 -0
- package/dist/client/scene-hotkeys.d.ts +16 -0
- package/dist/client/scene-hotkeys.js +17 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/values/bindings.d.ts +40 -15
- package/dist/values/controller.d.ts +9 -6
- package/dist/values/edit-history.d.ts +4 -0
- package/dist/values/edit-history.js +14 -7
- package/dist/values/effect-schema.d.ts +26 -0
- package/dist/values/effect-schema.js +76 -91
- package/dist/values/hotkey-targets.d.ts +10 -3
- package/dist/values/hotkey-targets.js +20 -0
- package/dist/values/hotkeys.d.ts +9 -1
- package/dist/values/hotkeys.js +11 -0
- package/dist/values/labels.js +1 -0
- package/dist/values/limits.d.ts +96 -8
- package/dist/values/limits.js +109 -1
- package/dist/values/lipsync.d.ts +7 -8
- package/dist/values/locale.d.ts +4 -1
- package/dist/values/locale.js +4 -0
- package/dist/values/model-movement.d.ts +19 -4
- package/dist/values/model-movement.js +17 -4
- package/dist/values/volumetric-lighting.d.ts +1 -1
- package/dist/values/volumetric-lighting.js +1 -1
- package/dist/wire/envelope.js +6 -3
- package/dist/wire/methods.d.ts +16 -17
- package/dist/wire/protocol.d.ts +2 -0
- package/dist/wire/protocol.js +4 -0
- package/dist/wire/schemas/fields.d.ts +8 -0
- package/dist/wire/schemas/fields.js +1 -0
- package/dist/wire/schemas/requests.d.ts +2 -2
- package/dist/wire/schemas/requests.js +70 -20
- package/dist/wire/schemas/settings.d.ts +3 -3
- package/dist/wire/schemas/settings.js +3 -3
- package/dist/wire/types.d.ts +68 -115
- package/dist/wire/types.js +68 -9
- package/package.json +2 -2
- package/dist/client/legacy-kinds.d.ts +0 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Scope and parameter metadata are plain data; labels and rendering stay with their consumers.
|
|
2
|
-
import { finiteOr, isOneOf, isRecord } from "./guards.js";
|
|
2
|
+
import { finiteOr, isOneOf, isRecord, keysOf } from "./guards.js";
|
|
3
3
|
import { clamp, hexColorOr } from "./limits.js";
|
|
4
4
|
/** Supported owners of each toggle effect; scene and layer membership are independent. */
|
|
5
5
|
export const EFFECT_SCOPES = {
|
|
@@ -48,6 +48,57 @@ export const SCENE_EFFECT_KEYS = keysForScope('scene');
|
|
|
48
48
|
/** Scene toggle keys; retained for existing SDK consumers. */
|
|
49
49
|
export const TOGGLE_EFFECT_KEYS = SCENE_EFFECT_KEYS;
|
|
50
50
|
export const LAYER_EFFECT_KEYS = keysForScope('layer');
|
|
51
|
+
/** Levels' color channels, run before the master levels; each suffixes its own copy of the params (`inputBlackR`). */
|
|
52
|
+
export const LEVEL_CHANNELS = ['R', 'G', 'B'];
|
|
53
|
+
/** Color Shift's hue bands, around the wheel from red; each suffixes its own copy of the params (`hueRed`). */
|
|
54
|
+
export const COLOR_SHIFT_BANDS = ['Red', 'Yellow', 'Green', 'Cyan', 'Blue', 'Magenta'];
|
|
55
|
+
/** Select Colors' color slots, `color1` up. */
|
|
56
|
+
export const SELECT_COLORS_SLOTS = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
|
57
|
+
/** The color slots a layer's bloom can limit its glow to, `color1` up. */
|
|
58
|
+
export const BLOOM_COLOR_SLOTS = [1, 2, 3, 4, 5];
|
|
59
|
+
/** One channel's levels, shared by the master set and each of {@link LEVEL_CHANNELS}. */
|
|
60
|
+
const LEVEL_SPECS = {
|
|
61
|
+
inputBlack: { default: 0, min: 0, max: 1, step: 0.01 },
|
|
62
|
+
inputWhite: { default: 1, min: 0, max: 1, step: 0.01 },
|
|
63
|
+
inputGamma: { default: 1, min: 0.1, max: 4, step: 0.01 },
|
|
64
|
+
outputBlack: { default: 0, min: 0, max: 1, step: 0.01 },
|
|
65
|
+
outputWhite: { default: 1, min: 0, max: 1, step: 0.01 },
|
|
66
|
+
};
|
|
67
|
+
/** One hue band's offsets, shared by each of {@link COLOR_SHIFT_BANDS}. */
|
|
68
|
+
const COLOR_SHIFT_SPECS = {
|
|
69
|
+
hue: { default: 0, min: -180, max: 180, step: 1, unit: '°' },
|
|
70
|
+
saturation: { default: 0, min: -1, max: 1, step: 0.01 },
|
|
71
|
+
luminance: { default: 0, min: -1, max: 1, step: 0.01 },
|
|
72
|
+
luminanceSaturation: { default: 0, min: -1, max: 1, step: 0.01 },
|
|
73
|
+
};
|
|
74
|
+
const SELECT_COLORS_DEFAULTS = {
|
|
75
|
+
1: '#ff0000',
|
|
76
|
+
2: '#ffff00',
|
|
77
|
+
3: '#00ff00',
|
|
78
|
+
4: '#00ffff',
|
|
79
|
+
5: '#0000ff',
|
|
80
|
+
6: '#ff00ff',
|
|
81
|
+
7: '#ffffff',
|
|
82
|
+
8: '#808080',
|
|
83
|
+
9: '#000000',
|
|
84
|
+
10: '#ff8800',
|
|
85
|
+
};
|
|
86
|
+
/**
|
|
87
|
+
* `table` once per suffix, suffix by suffix, each key suffixed (`{ hue }` over `['Red', 'Blue']` is
|
|
88
|
+
* `{ hueRed, hueBlue }`): how a per-channel parameter set spells its specs, labels and descriptions.
|
|
89
|
+
*/
|
|
90
|
+
export function suffixKeys(table, suffixes) {
|
|
91
|
+
// Object.fromEntries widens its keys to string; the entries are exactly the keys named.
|
|
92
|
+
return Object.fromEntries(suffixes.flatMap(suffix => keysOf(table).map(key => [`${key}${suffix}`, table[key]])));
|
|
93
|
+
}
|
|
94
|
+
/** `spec(slot)` for each color slot, keyed `color${slot}${suffix}` in slot order. */
|
|
95
|
+
function colorSlotSpecs(slots, suffix, spec) {
|
|
96
|
+
// Object.fromEntries widens its keys to string; the entries are exactly the keys named.
|
|
97
|
+
return Object.fromEntries(slots.map(slot => [`color${slot}${suffix}`, spec(slot)]));
|
|
98
|
+
}
|
|
99
|
+
// The first slot starts on: with every pick off the mask is zero, so switching selection on
|
|
100
|
+
// would select nothing rather than narrow.
|
|
101
|
+
const slotEnabled = (slot) => ({ default: slot === 1 });
|
|
51
102
|
// Declared string-indexed so generic call sites (slider loop, healing walk) iterate
|
|
52
103
|
// without erasure casts; `satisfies` still checks exact per-effect param parity here.
|
|
53
104
|
export const EFFECT_SPECS = {
|
|
@@ -60,28 +111,7 @@ export const EFFECT_SPECS = {
|
|
|
60
111
|
temperature: { default: 0, min: -100, max: 100, step: 1 },
|
|
61
112
|
tint: { default: 0, min: -100, max: 100, step: 1 },
|
|
62
113
|
},
|
|
63
|
-
levels:
|
|
64
|
-
inputBlack: { default: 0, min: 0, max: 1, step: 0.01 },
|
|
65
|
-
inputWhite: { default: 1, min: 0, max: 1, step: 0.01 },
|
|
66
|
-
inputGamma: { default: 1, min: 0.1, max: 4, step: 0.01 },
|
|
67
|
-
outputBlack: { default: 0, min: 0, max: 1, step: 0.01 },
|
|
68
|
-
outputWhite: { default: 1, min: 0, max: 1, step: 0.01 },
|
|
69
|
-
inputBlackR: { default: 0, min: 0, max: 1, step: 0.01 },
|
|
70
|
-
inputWhiteR: { default: 1, min: 0, max: 1, step: 0.01 },
|
|
71
|
-
inputGammaR: { default: 1, min: 0.1, max: 4, step: 0.01 },
|
|
72
|
-
outputBlackR: { default: 0, min: 0, max: 1, step: 0.01 },
|
|
73
|
-
outputWhiteR: { default: 1, min: 0, max: 1, step: 0.01 },
|
|
74
|
-
inputBlackG: { default: 0, min: 0, max: 1, step: 0.01 },
|
|
75
|
-
inputWhiteG: { default: 1, min: 0, max: 1, step: 0.01 },
|
|
76
|
-
inputGammaG: { default: 1, min: 0.1, max: 4, step: 0.01 },
|
|
77
|
-
outputBlackG: { default: 0, min: 0, max: 1, step: 0.01 },
|
|
78
|
-
outputWhiteG: { default: 1, min: 0, max: 1, step: 0.01 },
|
|
79
|
-
inputBlackB: { default: 0, min: 0, max: 1, step: 0.01 },
|
|
80
|
-
inputWhiteB: { default: 1, min: 0, max: 1, step: 0.01 },
|
|
81
|
-
inputGammaB: { default: 1, min: 0.1, max: 4, step: 0.01 },
|
|
82
|
-
outputBlackB: { default: 0, min: 0, max: 1, step: 0.01 },
|
|
83
|
-
outputWhiteB: { default: 1, min: 0, max: 1, step: 0.01 },
|
|
84
|
-
},
|
|
114
|
+
levels: suffixKeys(LEVEL_SPECS, ['', ...LEVEL_CHANNELS]),
|
|
85
115
|
colorWheels: {
|
|
86
116
|
lift: { default: 0, min: -1, max: 1, step: 0.01 },
|
|
87
117
|
gamma: { default: 0, min: -1, max: 1, step: 0.01 },
|
|
@@ -92,32 +122,7 @@ export const EFFECT_SPECS = {
|
|
|
92
122
|
shadowLimit: { default: 0.3, min: 0, max: 1, step: 0.01 },
|
|
93
123
|
highlightLimit: { default: 0.7, min: 0, max: 1, step: 0.01 },
|
|
94
124
|
},
|
|
95
|
-
colorShift:
|
|
96
|
-
hueRed: { default: 0, min: -180, max: 180, step: 1, unit: '°' },
|
|
97
|
-
saturationRed: { default: 0, min: -1, max: 1, step: 0.01 },
|
|
98
|
-
luminanceRed: { default: 0, min: -1, max: 1, step: 0.01 },
|
|
99
|
-
luminanceSaturationRed: { default: 0, min: -1, max: 1, step: 0.01 },
|
|
100
|
-
hueYellow: { default: 0, min: -180, max: 180, step: 1, unit: '°' },
|
|
101
|
-
saturationYellow: { default: 0, min: -1, max: 1, step: 0.01 },
|
|
102
|
-
luminanceYellow: { default: 0, min: -1, max: 1, step: 0.01 },
|
|
103
|
-
luminanceSaturationYellow: { default: 0, min: -1, max: 1, step: 0.01 },
|
|
104
|
-
hueGreen: { default: 0, min: -180, max: 180, step: 1, unit: '°' },
|
|
105
|
-
saturationGreen: { default: 0, min: -1, max: 1, step: 0.01 },
|
|
106
|
-
luminanceGreen: { default: 0, min: -1, max: 1, step: 0.01 },
|
|
107
|
-
luminanceSaturationGreen: { default: 0, min: -1, max: 1, step: 0.01 },
|
|
108
|
-
hueCyan: { default: 0, min: -180, max: 180, step: 1, unit: '°' },
|
|
109
|
-
saturationCyan: { default: 0, min: -1, max: 1, step: 0.01 },
|
|
110
|
-
luminanceCyan: { default: 0, min: -1, max: 1, step: 0.01 },
|
|
111
|
-
luminanceSaturationCyan: { default: 0, min: -1, max: 1, step: 0.01 },
|
|
112
|
-
hueBlue: { default: 0, min: -180, max: 180, step: 1, unit: '°' },
|
|
113
|
-
saturationBlue: { default: 0, min: -1, max: 1, step: 0.01 },
|
|
114
|
-
luminanceBlue: { default: 0, min: -1, max: 1, step: 0.01 },
|
|
115
|
-
luminanceSaturationBlue: { default: 0, min: -1, max: 1, step: 0.01 },
|
|
116
|
-
hueMagenta: { default: 0, min: -180, max: 180, step: 1, unit: '°' },
|
|
117
|
-
saturationMagenta: { default: 0, min: -1, max: 1, step: 0.01 },
|
|
118
|
-
luminanceMagenta: { default: 0, min: -1, max: 1, step: 0.01 },
|
|
119
|
-
luminanceSaturationMagenta: { default: 0, min: -1, max: 1, step: 0.01 },
|
|
120
|
-
},
|
|
125
|
+
colorShift: suffixKeys(COLOR_SHIFT_SPECS, COLOR_SHIFT_BANDS),
|
|
121
126
|
selectColors: {
|
|
122
127
|
hueRange: { default: 0.08, min: 0, max: 0.5, step: 0.01 },
|
|
123
128
|
saturationRange: { default: 1, min: 0, max: 1, step: 0.01 },
|
|
@@ -289,25 +294,10 @@ export const EFFECT_COLOR_SPECS = {
|
|
|
289
294
|
midtonesColor: { default: '#ffffff' },
|
|
290
295
|
highlightsColor: { default: '#ffffff' },
|
|
291
296
|
},
|
|
292
|
-
selectColors: {
|
|
293
|
-
color1: { default: '#ff0000' },
|
|
294
|
-
color2: { default: '#ffff00' },
|
|
295
|
-
color3: { default: '#00ff00' },
|
|
296
|
-
color4: { default: '#00ffff' },
|
|
297
|
-
color5: { default: '#0000ff' },
|
|
298
|
-
color6: { default: '#ff00ff' },
|
|
299
|
-
color7: { default: '#ffffff' },
|
|
300
|
-
color8: { default: '#808080' },
|
|
301
|
-
color9: { default: '#000000' },
|
|
302
|
-
color10: { default: '#ff8800' },
|
|
303
|
-
},
|
|
297
|
+
selectColors: colorSlotSpecs(SELECT_COLORS_SLOTS, '', slot => ({ default: SELECT_COLORS_DEFAULTS[slot] })),
|
|
304
298
|
bloom: {
|
|
305
299
|
tint: { default: '#ffffff' },
|
|
306
|
-
|
|
307
|
-
color2: { default: '#ffffff' },
|
|
308
|
-
color3: { default: '#ffffff' },
|
|
309
|
-
color4: { default: '#ffffff' },
|
|
310
|
-
color5: { default: '#ffffff' },
|
|
300
|
+
...colorSlotSpecs(BLOOM_COLOR_SLOTS, '', () => ({ default: '#ffffff' })),
|
|
311
301
|
},
|
|
312
302
|
rim: {
|
|
313
303
|
color: { default: '#ffeb74' },
|
|
@@ -335,26 +325,11 @@ export const EFFECT_BOOLEAN_SPECS = {
|
|
|
335
325
|
bloom: {
|
|
336
326
|
selectColors: { default: false },
|
|
337
327
|
invertColors: { default: false },
|
|
338
|
-
|
|
339
|
-
// selection on would make the glow vanish rather than narrow.
|
|
340
|
-
color1Enabled: { default: true },
|
|
341
|
-
color2Enabled: { default: false },
|
|
342
|
-
color3Enabled: { default: false },
|
|
343
|
-
color4Enabled: { default: false },
|
|
344
|
-
color5Enabled: { default: false },
|
|
328
|
+
...colorSlotSpecs(BLOOM_COLOR_SLOTS, 'Enabled', slotEnabled),
|
|
345
329
|
},
|
|
346
330
|
selectColors: {
|
|
347
331
|
invert: { default: false },
|
|
348
|
-
|
|
349
|
-
color2Enabled: { default: false },
|
|
350
|
-
color3Enabled: { default: false },
|
|
351
|
-
color4Enabled: { default: false },
|
|
352
|
-
color5Enabled: { default: false },
|
|
353
|
-
color6Enabled: { default: false },
|
|
354
|
-
color7Enabled: { default: false },
|
|
355
|
-
color8Enabled: { default: false },
|
|
356
|
-
color9Enabled: { default: false },
|
|
357
|
-
color10Enabled: { default: false },
|
|
332
|
+
...colorSlotSpecs(SELECT_COLORS_SLOTS, 'Enabled', slotEnabled),
|
|
358
333
|
},
|
|
359
334
|
};
|
|
360
335
|
/** Blend-mode order shared by effect editors and shader uniforms. */
|
|
@@ -384,21 +359,31 @@ export const EFFECT_BLEND_MODES = [
|
|
|
384
359
|
'color',
|
|
385
360
|
'luminosity',
|
|
386
361
|
];
|
|
362
|
+
// The wire types derive from these, so every member a type admits also heals and publishes.
|
|
363
|
+
export const FLARE_MODES = ['add', 'screen', 'colorDodge'];
|
|
364
|
+
export const FLARE_RAYS_MODES = ['sun', 'shine', 'god'];
|
|
365
|
+
export const GRADIENT_TYPES = ['solid', 'linear', 'circle', 'ellipse'];
|
|
366
|
+
export const BLUR_MODES = ['gaussian', 'bokeh'];
|
|
367
|
+
export const BLOOM_MODES = ['normal', 'streak', 'star'];
|
|
368
|
+
export const RIM_MODES = ['single', 'double', 'sharpenSingle', 'sharpenDouble'];
|
|
369
|
+
export const COLOR_WHEELS_MODES = ['liftGammaGain', 'shadowsMidtonesHighlights'];
|
|
370
|
+
/** Effects quality tiers, lowest first. */
|
|
371
|
+
export const EFFECTS_QUALITY_LEVELS = ['low', 'medium', 'high'];
|
|
387
372
|
/** Enum defaults and allowed values. */
|
|
388
373
|
export const EFFECT_ENUM_SPECS = {
|
|
389
374
|
flare: {
|
|
390
|
-
mode: { default: 'add', values:
|
|
391
|
-
raysMode: { default: 'sun', values:
|
|
375
|
+
mode: { default: 'add', values: FLARE_MODES },
|
|
376
|
+
raysMode: { default: 'sun', values: FLARE_RAYS_MODES },
|
|
392
377
|
},
|
|
393
378
|
gradient: {
|
|
394
|
-
type: { default: 'circle', values:
|
|
379
|
+
type: { default: 'circle', values: GRADIENT_TYPES },
|
|
395
380
|
blendMode: { default: 'normal', values: EFFECT_BLEND_MODES },
|
|
396
381
|
},
|
|
397
|
-
blur: { mode: { default: 'gaussian', values:
|
|
398
|
-
bloom: { mode: { default: 'normal', values:
|
|
399
|
-
rim: { mode: { default: 'single', values:
|
|
400
|
-
outline: { quality: { default: 'medium', values:
|
|
401
|
-
colorWheels: { mode: { default: 'liftGammaGain', values:
|
|
382
|
+
blur: { mode: { default: 'gaussian', values: BLUR_MODES } },
|
|
383
|
+
bloom: { mode: { default: 'normal', values: BLOOM_MODES } },
|
|
384
|
+
rim: { mode: { default: 'single', values: RIM_MODES } },
|
|
385
|
+
outline: { quality: { default: 'medium', values: EFFECTS_QUALITY_LEVELS } },
|
|
386
|
+
colorWheels: { mode: { default: 'liftGammaGain', values: COLOR_WHEELS_MODES } },
|
|
402
387
|
};
|
|
403
388
|
/** Select the layer effects from any value set containing them. */
|
|
404
389
|
export function pickLayerEffects(effects) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { Hotkey, MotionGroup } from '../wire/types.ts';
|
|
1
|
+
import type { Hotkey, ModelRef, MotionGroup } from '../wire/types.ts';
|
|
2
2
|
/** A hotkey action Persona can run. */
|
|
3
|
-
type HotkeyAction = NonNullable<Hotkey['action']>;
|
|
3
|
+
export type HotkeyAction = NonNullable<Hotkey['action']>;
|
|
4
4
|
/** What a model offers hotkeys: its expressions (a null `file` on formats with none) and its motion groups. */
|
|
5
5
|
export interface HotkeyListing {
|
|
6
6
|
expressions: readonly {
|
|
@@ -53,4 +53,11 @@ export declare function modelMatchesFile(file: string, model: {
|
|
|
53
53
|
vtubeFile?: string | null;
|
|
54
54
|
entryFile?: string;
|
|
55
55
|
}): boolean;
|
|
56
|
-
|
|
56
|
+
/**
|
|
57
|
+
* Labels a model's hotkeys by what each points at — an expression's Name, a motion's label, a
|
|
58
|
+
* load-model's model name — or undefined for an action with no file, or once the target is gone.
|
|
59
|
+
* Walks the listing once, so a shortcut list builds one per model and asks it per row.
|
|
60
|
+
* @param models `model.list`'s refs; scene item refs carry no `vtubeFile` (see {@link modelMatchesFile}).
|
|
61
|
+
* @param groupLabel Display name for a motion group; VRM groups are clip refs, not names.
|
|
62
|
+
*/
|
|
63
|
+
export declare function hotkeyTargetLabels(listing: HotkeyListing, models: readonly Pick<ModelRef, 'name' | 'vtubeFile' | 'entryFile'>[], groupLabel?: (group: string) => string): (h: Pick<Hotkey, 'action' | 'file'>) => string | undefined;
|
|
@@ -86,3 +86,23 @@ export function modelMatchesFile(file, model) {
|
|
|
86
86
|
return true;
|
|
87
87
|
return model.entryFile !== undefined && fileBasename(model.entryFile).toLowerCase() === base;
|
|
88
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* Labels a model's hotkeys by what each points at — an expression's Name, a motion's label, a
|
|
91
|
+
* load-model's model name — or undefined for an action with no file, or once the target is gone.
|
|
92
|
+
* Walks the listing once, so a shortcut list builds one per model and asks it per row.
|
|
93
|
+
* @param models `model.list`'s refs; scene item refs carry no `vtubeFile` (see {@link modelMatchesFile}).
|
|
94
|
+
* @param groupLabel Display name for a motion group; VRM groups are clip refs, not names.
|
|
95
|
+
*/
|
|
96
|
+
export function hotkeyTargetLabels(listing, models, groupLabel) {
|
|
97
|
+
const labelByFile = {
|
|
98
|
+
'expression-toggle': new Map(hotkeyTargets(listing, 'expression-toggle').map(x => [x.file, x.label])),
|
|
99
|
+
'motion-play': new Map(hotkeyTargets(listing, 'motion-play', groupLabel).map(x => [x.file, x.label])),
|
|
100
|
+
};
|
|
101
|
+
return h => {
|
|
102
|
+
if (h.action === 'model-load')
|
|
103
|
+
return models.find(m => modelMatchesFile(h.file, m))?.name;
|
|
104
|
+
if (h.action !== 'expression-toggle' && h.action !== 'motion-play')
|
|
105
|
+
return undefined;
|
|
106
|
+
return labelByFile[h.action].get(h.file);
|
|
107
|
+
};
|
|
108
|
+
}
|
package/dist/values/hotkeys.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Hotkey } from '../wire/types.ts';
|
|
1
|
+
import type { Hotkey, HotkeyState } from '../wire/types.ts';
|
|
2
2
|
/** True when the combo carries a command modifier and so may be registered globally. */
|
|
3
3
|
export declare function hasCommandModifier(accelerator: string | null): boolean;
|
|
4
4
|
/**
|
|
@@ -9,6 +9,12 @@ export declare function hasCommandModifier(accelerator: string | null): boolean;
|
|
|
9
9
|
export declare function canRunInBackground(accelerator: string | null): boolean;
|
|
10
10
|
/** True when a model hotkey is meant to fire while Persona sits in the background — what main registers on, and what the globe shows. */
|
|
11
11
|
export declare function hotkeyRunsInBackground(h: Hotkey): boolean;
|
|
12
|
+
/**
|
|
13
|
+
* True when main should hold an OS registration for `h` but doesn't — another app owns its
|
|
14
|
+
* command-modifier combo. A non-command combo (a controller one included) never registers, so its
|
|
15
|
+
* absence is not contention; nor is anything under the model's master switch turned off.
|
|
16
|
+
*/
|
|
17
|
+
export declare function hotkeyContended(state: Pick<HotkeyState, 'keyboardEnabled' | 'registered'>, h: Hotkey): boolean;
|
|
12
18
|
/**
|
|
13
19
|
* Why a `hold` hotkey toggles instead of holding, or null when it can hold. A combo registered with
|
|
14
20
|
* the OS reaches Persona as a press alone — Electron reports no key-up for it — and one registration
|
|
@@ -16,6 +22,8 @@ export declare function hotkeyRunsInBackground(h: Hotkey): boolean;
|
|
|
16
22
|
* `'shared'` when only another one on its combo does, which `registered` (main's list) alone can tell.
|
|
17
23
|
*/
|
|
18
24
|
export declare function holdBlockedBy(h: Pick<Hotkey, 'hold' | 'global' | 'accelerator'>, registered: boolean): 'own' | 'shared' | null;
|
|
25
|
+
/** A hotkey's playback options, which every writer and healer treats as one group. */
|
|
26
|
+
export type HotkeyOptions = Pick<Hotkey, 'hold' | 'fadeSeconds' | 'deactivateAfterSeconds' | 'stopsOnLastFrame'>;
|
|
19
27
|
/** VTS's editor limits for a hotkey's fade and auto-off times, in seconds; healing clamps API input to them. */
|
|
20
28
|
export declare const HOTKEY_FADE_SECONDS_MAX = 2;
|
|
21
29
|
export declare const HOTKEY_DEACTIVATE_SECONDS_MIN = 0.1;
|
package/dist/values/hotkeys.js
CHANGED
|
@@ -25,6 +25,17 @@ export function canRunInBackground(accelerator) {
|
|
|
25
25
|
export function hotkeyRunsInBackground(h) {
|
|
26
26
|
return h.global && h.active && h.action !== null && canRunInBackground(h.accelerator);
|
|
27
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* True when main should hold an OS registration for `h` but doesn't — another app owns its
|
|
30
|
+
* command-modifier combo. A non-command combo (a controller one included) never registers, so its
|
|
31
|
+
* absence is not contention; nor is anything under the model's master switch turned off.
|
|
32
|
+
*/
|
|
33
|
+
export function hotkeyContended(state, h) {
|
|
34
|
+
return (state.keyboardEnabled &&
|
|
35
|
+
hotkeyRunsInBackground(h) &&
|
|
36
|
+
hasCommandModifier(h.accelerator) &&
|
|
37
|
+
!state.registered.includes(h.id));
|
|
38
|
+
}
|
|
28
39
|
/**
|
|
29
40
|
* Why a `hold` hotkey toggles instead of holding, or null when it can hold. A combo registered with
|
|
30
41
|
* the OS reaches Persona as a press alone — Electron reports no key-up for it — and one registration
|
package/dist/values/labels.js
CHANGED
|
@@ -26,6 +26,7 @@ export function motionSlots(files) {
|
|
|
26
26
|
return files.flatMap((file, index) => (file === '' ? [] : [{ file, index }]));
|
|
27
27
|
}
|
|
28
28
|
// English fallbacks; localizing clients keep their own map and use these for unknown kinds.
|
|
29
|
+
// The panel's `KIND_SPECS` labels must read the same — a desktop test holds them together.
|
|
29
30
|
const AUTOMATION_ACTION_KIND_LABELS = {
|
|
30
31
|
'effect-toggle': 'Toggle Effect',
|
|
31
32
|
'effect-params': 'Apply Effect Settings',
|
package/dist/values/limits.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import type { AssetRef, Attach, AttachDepth, CameraAnchor, CameraFollowDamping, CameraTrackTarget, ChromaKey, EnvironmentLook, KeyableContent, ModelFormat, MToonTuning, ObjectContent, ObjectSpace, SceneCameraAim, SceneCameraAimSettings, SceneCameraFocus, SceneCameraFocusSettings, SceneCameraFollow, SceneCameraFollowSettings, SceneCameraHandheld, SceneEnvironment, SceneLight, SceneLightCameraFollowOptions, SceneLightType, ScreenPlacement, VrmPlacement } from '../wire/types.ts';
|
|
1
|
+
import type { AssetRef, Attach, AttachAnchor, AttachDepth, CameraAnchor, CameraFollowDamping, CameraTrackTarget, ChromaKey, EnvironmentLook, KeyableContent, ModelFormat, MToonTuning, ObjectContent, ObjectSpace, SceneCameraAim, SceneCameraAimSettings, SceneCameraFocus, SceneCameraFocusSettings, SceneCameraFollow, SceneCameraFollowSettings, SceneCameraHandheld, SceneEnvironment, SceneLight, SceneLightCameraFollowOptions, SceneLightType, ScreenPlacement, TextFont, VrmPlacement } from '../wire/types.ts';
|
|
2
2
|
export declare function clamp(v: number, min: number, max: number): number;
|
|
3
3
|
/** Clamp to the unit interval. */
|
|
4
4
|
export declare function clamp01(v: number): number;
|
|
5
5
|
/** Wrap an angle into (-π, π]. */
|
|
6
6
|
export declare function wrapAngle(a: number): number;
|
|
7
|
+
/** Wrap degrees into (-180°, 180°], {@link wrapAngle}'s range; whole turns keep in-range values exact. */
|
|
8
|
+
export declare function wrapDegrees(v: number): number;
|
|
7
9
|
export declare const DEFAULT_LIVE2D_PLACEMENT: ScreenPlacement;
|
|
8
10
|
export declare const DEFAULT_VRM_PLACEMENT: VrmPlacement;
|
|
9
11
|
/** Scene colors heal to 6-digit hex; both cases are spelled out because JSON Schema patterns carry no flags. */
|
|
@@ -27,6 +29,11 @@ export declare const SCENE_LIGHT_SPOT_ANGLE_MIN = 1;
|
|
|
27
29
|
export declare const SCENE_LIGHT_SPOT_ANGLE_MAX = 89;
|
|
28
30
|
export declare const DEFAULT_SPOT_ANGLE_DEG = 30;
|
|
29
31
|
export declare const DEFAULT_SPOT_PENUMBRA = 0.3;
|
|
32
|
+
/** Light azimuth and roll bounds in degrees, symmetric: a half turn either way. */
|
|
33
|
+
export declare const SCENE_LIGHT_AZIMUTH_MAX = 180;
|
|
34
|
+
export declare const SCENE_LIGHT_ROLL_MAX = 180;
|
|
35
|
+
/** Light elevation bound in degrees, symmetric: straight up or straight down. */
|
|
36
|
+
export declare const SCENE_LIGHT_ELEVATION_MAX = 90;
|
|
30
37
|
/** Positional lights need falloff headroom; the slider and scene healing share this ceiling. */
|
|
31
38
|
export declare function sceneLightIntensityMax(type: SceneLightType): number;
|
|
32
39
|
/** Whether a light of `type` aims with azimuth/elevation. */
|
|
@@ -41,6 +48,7 @@ export declare const LIVE2D_SCALE_MIN = 0.1;
|
|
|
41
48
|
export declare const LIVE2D_SCALE_MAX = 24;
|
|
42
49
|
export declare const VRM_SCALE_MIN = 0.05;
|
|
43
50
|
export declare const VRM_SCALE_MAX = 10;
|
|
51
|
+
export declare const SCENE_LIGHT_RANGE_MIN = 0.1;
|
|
44
52
|
export declare const SCENE_LIGHT_RANGE_MAX = 20;
|
|
45
53
|
/** Past this the 5-tap kernel spreads thin enough that its dither reads as noise. */
|
|
46
54
|
export declare const SCENE_LIGHT_SHADOW_RADIUS_MAX = 16;
|
|
@@ -48,6 +56,8 @@ export declare const SCENE_LIGHT_SHADOW_RADIUS_MAX = 16;
|
|
|
48
56
|
export declare const SCENE_LIGHT_POINT_SHADOW_RADIUS_MAX = 32;
|
|
49
57
|
export declare const SCENE_LIGHT_SHADOW_SOURCE_SIZE_MAX = 10;
|
|
50
58
|
export declare const DEFAULT_LIGHT_SHADOW_SOURCE_SIZE = 0.1;
|
|
59
|
+
/** A light override's key: the baked light's traversal index, in decimal digits. */
|
|
60
|
+
export declare const LIGHT_OVERRIDE_KEY_RE: RegExp;
|
|
51
61
|
/** Shadow softness (PCF disk radius, in shadow-map texels) ceiling for a light of `type`. */
|
|
52
62
|
export declare function sceneLightShadowRadiusMax(type: SceneLightType): number;
|
|
53
63
|
/**
|
|
@@ -68,6 +78,8 @@ export declare const CAMERA_DAMPING_MAX = 10;
|
|
|
68
78
|
/** Ceiling for {@link SceneCameraAim}'s lookahead time, in seconds, and its smoothing. */
|
|
69
79
|
export declare const CAMERA_AIM_LOOKAHEAD_MAX = 1;
|
|
70
80
|
export declare const CAMERA_AIM_SMOOTHING_MAX = 30;
|
|
81
|
+
/** {@link SceneCameraAim}'s bias bound on each axis, symmetric: a share of the slack between its zones. */
|
|
82
|
+
export declare const CAMERA_AIM_BIAS_MAX = 0.5;
|
|
71
83
|
/** Ceiling for {@link SceneCameraHandheld}'s speed. */
|
|
72
84
|
export declare const CAMERA_HANDHELD_SPEED_MAX = 2;
|
|
73
85
|
/** Warudo's Handheld Movement defaults, switched off. */
|
|
@@ -105,6 +117,30 @@ export declare function cameraTrackKind(item: {
|
|
|
105
117
|
kind: 'object';
|
|
106
118
|
space: ObjectSpace;
|
|
107
119
|
}): 'model' | 'object' | null;
|
|
120
|
+
/**
|
|
121
|
+
* The layer `target` tracks in `scene` — the primary model for a primary pick, else the first model — when it
|
|
122
|
+
* is one a camera can track.
|
|
123
|
+
*/
|
|
124
|
+
export declare function cameraTrackItem<T extends {
|
|
125
|
+
kind: 'model';
|
|
126
|
+
instanceId: string;
|
|
127
|
+
ref: {
|
|
128
|
+
kind: string;
|
|
129
|
+
};
|
|
130
|
+
} | {
|
|
131
|
+
kind: 'object';
|
|
132
|
+
instanceId: string;
|
|
133
|
+
space: ObjectSpace;
|
|
134
|
+
}>(scene: {
|
|
135
|
+
items: readonly T[];
|
|
136
|
+
primaryInstanceId: string | null;
|
|
137
|
+
}, target: CameraTrackTarget): T | undefined;
|
|
138
|
+
/** A layer the camera's follow, aim and focus pickers offer; `model` tells a model from an object. */
|
|
139
|
+
export interface CameraTrackCandidate {
|
|
140
|
+
instanceId: string;
|
|
141
|
+
name: string;
|
|
142
|
+
model: boolean;
|
|
143
|
+
}
|
|
108
144
|
/** Rows for the camera's follow, aim and focus pickers, in layer order. One rule, or the console offers a layer the desktop drops. */
|
|
109
145
|
export declare function cameraTrackCandidates(items: readonly ({
|
|
110
146
|
kind: 'model';
|
|
@@ -118,11 +154,7 @@ export declare function cameraTrackCandidates(items: readonly ({
|
|
|
118
154
|
instanceId: string;
|
|
119
155
|
name: string;
|
|
120
156
|
space: ObjectSpace;
|
|
121
|
-
})[]):
|
|
122
|
-
instanceId: string;
|
|
123
|
-
name: string;
|
|
124
|
-
model: boolean;
|
|
125
|
-
}[];
|
|
157
|
+
})[]): CameraTrackCandidate[];
|
|
126
158
|
/** Manual navigation stops short of ±90°; authored camera elevations remain unrestricted. */
|
|
127
159
|
export declare const ELEVATION_LIMIT: number;
|
|
128
160
|
/** Manual navigation distance bounds; authored cameras retain signed, unrestricted distances. */
|
|
@@ -153,6 +185,23 @@ export declare const MTOON_OUTLINE_WIDTH_MAX = 2;
|
|
|
153
185
|
/** HDR headroom: past ×1 the point is pushing emissive parts over the bloom threshold. */
|
|
154
186
|
export declare const MTOON_EMISSIVE_MAX = 4;
|
|
155
187
|
export declare const MTOON_UV_ANIMATION_MAX = 4;
|
|
188
|
+
/** Each {@link MToonTuning} field's `[min, max]`: offsets −1..1, `shade` 0..1, multipliers 0 to their ceiling. */
|
|
189
|
+
export declare const MTOON_RANGES: {
|
|
190
|
+
readonly shade: readonly [0, 1];
|
|
191
|
+
readonly shadingShift: readonly [-1, 1];
|
|
192
|
+
readonly shadingToony: readonly [-1, 1];
|
|
193
|
+
readonly giEqualization: readonly [-1, 1];
|
|
194
|
+
readonly normalScale: readonly [0, 2];
|
|
195
|
+
readonly rim: readonly [0, 2];
|
|
196
|
+
readonly rimLift: readonly [-1, 1];
|
|
197
|
+
readonly rimFresnelPower: readonly [0, 4];
|
|
198
|
+
readonly rimLightingMix: readonly [-1, 1];
|
|
199
|
+
readonly matcap: readonly [0, 4];
|
|
200
|
+
readonly outlineWidth: readonly [0, 2];
|
|
201
|
+
readonly outlineLightingMix: readonly [-1, 1];
|
|
202
|
+
readonly emissive: readonly [0, 4];
|
|
203
|
+
readonly uvAnimation: readonly [0, 4];
|
|
204
|
+
};
|
|
156
205
|
export declare function defaultMToonTuning(): MToonTuning;
|
|
157
206
|
export declare const DEFAULT_LIGHT_AZIMUTH_DEG = 45;
|
|
158
207
|
export declare const DEFAULT_LIGHT_ELEVATION_DEG: number;
|
|
@@ -262,8 +311,26 @@ export declare const TEXT_BEVEL_RESOLUTION_MAX = 8;
|
|
|
262
311
|
export declare const TEXT_EMISSION_MAX = 4;
|
|
263
312
|
/** A PostScript name: printable ASCII, at most 63 chars, minus the quote and backslash that would escape `local("…")`. */
|
|
264
313
|
export declare const TEXT_POSTSCRIPT_NAME_RE: RegExp;
|
|
314
|
+
/** A text font's CSS `font-weight` bounds. */
|
|
315
|
+
export declare const TEXT_FONT_WEIGHT_MIN = 1;
|
|
316
|
+
export declare const TEXT_FONT_WEIGHT_MAX = 1000;
|
|
317
|
+
/** A text font's CSS `font-stretch` bounds, in percent. */
|
|
318
|
+
export declare const TEXT_FONT_STRETCH_MIN = 50;
|
|
319
|
+
export declare const TEXT_FONT_STRETCH_MAX = 200;
|
|
320
|
+
/** CSS's normal face: what a text font, or a font file, that leaves its weight, slope or width unsaid reads as. */
|
|
321
|
+
export declare const DEFAULT_TEXT_FONT_FACE: Pick<TextFont, 'weight' | 'italic' | 'stretch'>;
|
|
265
322
|
/** A prop is a mesh, so it only exists in the three.js scene; every other kind renders in both. */
|
|
266
323
|
export declare function objectSupportsSpace(kind: ObjectContent['kind'], space: ObjectSpace): boolean;
|
|
324
|
+
/** The {@link ObjectContent} kinds that stream from a registered asset; the rest carry their source inline. */
|
|
325
|
+
declare const ASSET_CONTENT_KINDS: readonly ["image", "video", "prop"];
|
|
326
|
+
/** The variants of {@link ObjectContent} that stream from a registered asset. */
|
|
327
|
+
export type AssetContent = Extract<ObjectContent, {
|
|
328
|
+
kind: (typeof ASSET_CONTENT_KINDS)[number];
|
|
329
|
+
}>;
|
|
330
|
+
/** Whether `kind` — a content kind, or an Inventory row's — is one whose asset streams into a layer. */
|
|
331
|
+
export declare function isAssetContentKind(kind: string): kind is AssetContent['kind'];
|
|
332
|
+
/** Whether the content streams from a registered asset: image, video and prop; the rest carry their source inline. */
|
|
333
|
+
export declare function isAssetContent(content: ObjectContent): content is AssetContent;
|
|
267
334
|
/** The asset an object streams from, or null for kinds that carry their source inline (web, capture, text). */
|
|
268
335
|
export declare function contentAssetId(content: ObjectContent): string | null;
|
|
269
336
|
/**
|
|
@@ -281,6 +348,12 @@ export declare function pinRiders(items: readonly {
|
|
|
281
348
|
parentInstanceId: string;
|
|
282
349
|
} | null;
|
|
283
350
|
}[], instanceId: string): Set<string>;
|
|
351
|
+
/** A pin picker row; `ridesThis` flags a model that already rides the item. */
|
|
352
|
+
interface PinnableParent {
|
|
353
|
+
instanceId: string;
|
|
354
|
+
name: string;
|
|
355
|
+
ridesThis: boolean;
|
|
356
|
+
}
|
|
284
357
|
/**
|
|
285
358
|
* Rows for the pin picker: every other Live2D model, each flagged when it already rides
|
|
286
359
|
* `instanceId` — picking one would put the two in a circle, so both apps offer it disabled
|
|
@@ -297,10 +370,20 @@ export declare function pinnableParents(models: readonly {
|
|
|
297
370
|
attach?: {
|
|
298
371
|
parentInstanceId: string;
|
|
299
372
|
} | null;
|
|
300
|
-
}[], instanceId: string):
|
|
373
|
+
}[], instanceId: string): PinnableParent[];
|
|
374
|
+
/**
|
|
375
|
+
* {@link pinnableParents} for an object: every model of the one format its space can ride. Nothing
|
|
376
|
+
* rides an object, so no row is ever flagged.
|
|
377
|
+
*/
|
|
378
|
+
export declare function objectPinParents(models: readonly {
|
|
379
|
+
instanceId: string;
|
|
380
|
+
ref: {
|
|
381
|
+
kind: string;
|
|
382
|
+
name: string;
|
|
383
|
+
};
|
|
384
|
+
}[], space: ObjectSpace): {
|
|
301
385
|
instanceId: string;
|
|
302
386
|
name: string;
|
|
303
|
-
ridesThis: boolean;
|
|
304
387
|
}[];
|
|
305
388
|
/**
|
|
306
389
|
* Whether pinning puts an item inside its Live2D host's ArtMesh stack, where `attach.depth` places
|
|
@@ -323,6 +406,8 @@ export declare function pinEntersStack(item: {
|
|
|
323
406
|
export declare function depthStops(meshes: readonly string[]): AttachDepth[];
|
|
324
407
|
/** Which stop a depth sits at; an ArtMesh the host no longer has reads as the frontmost. */
|
|
325
408
|
export declare function depthStopIndex(meshes: readonly string[], depth: AttachDepth): number;
|
|
409
|
+
/** A stored anchor — a model's root, a VRM bone or a point on a Live2D ArtMesh — as a usable one, or null. */
|
|
410
|
+
export declare function healAttachAnchor(raw: unknown): AttachAnchor | null;
|
|
326
411
|
export declare const DEFAULT_HEAD_ANGLE: NonNullable<Attach['headAngle']>;
|
|
327
412
|
/**
|
|
328
413
|
* A fresh pin onto `parentInstanceId`: root anchor, in front of the model. A screen-space item (a
|
|
@@ -343,6 +428,8 @@ export declare const STORAGE_KEY_MAX_LENGTH = 128;
|
|
|
343
428
|
export declare const STORAGE_VALUE_MAX_LENGTH: number;
|
|
344
429
|
/** Keys one API key may hold; a `storage.set` that would exceed it answers `invalid-state`. */
|
|
345
430
|
export declare const STORAGE_KEYS_MAX = 256;
|
|
431
|
+
/** `session.identify` refuses a longer name, so a client composing one trims it to this. */
|
|
432
|
+
export declare const SESSION_NAME_MAX_LENGTH = 64;
|
|
346
433
|
/** `speech.play` URL ceiling — sized for a ~40 s WAV as a base64 `data:audio/*` payload. */
|
|
347
434
|
export declare const SPEECH_URL_MAX_LENGTH = 8000000;
|
|
348
435
|
/**
|
|
@@ -364,3 +451,4 @@ export declare const TWO_COLUMN_WIDTH = 672;
|
|
|
364
451
|
export declare const SAVED_COLORS_MAX = 12;
|
|
365
452
|
/** 3D-stage resolution multipliers offered by both performance pickers. */
|
|
366
453
|
export declare const RENDER_SCALE_PRESETS: readonly [1, 0.85, 0.75, 0.66, 0.5];
|
|
454
|
+
export {};
|