@nodaro/prompts 1.7.3 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +5422 -4269
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1198 -61
- package/dist/index.d.ts +1198 -61
- package/dist/index.js +5336 -4271
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/b7-person-pack-e2e.test.ts +37 -0
- package/src/__tests__/catalog-funnel-ratchet.test.ts +97 -0
- package/src/__tests__/catalog-packs.test.ts +130 -0
- package/src/__tests__/catalog-sidecar-coverage.test.ts +27 -0
- package/src/__tests__/catalog-terms.test.ts +162 -0
- package/src/__tests__/character-default-role.test.ts +3 -2
- package/src/__tests__/content-free-contract.test.ts +45 -0
- package/src/__tests__/dod-replace-pack-acceptance.test.ts +41 -0
- package/src/__tests__/fixtures/parameter-hint-golden.json +2959 -0
- package/src/__tests__/fixtures/person-sector-pack.ts +27 -0
- package/src/__tests__/i18n-entry-completeness.test.ts +5 -2
- package/src/__tests__/parameter-hint-mode.test.ts +385 -0
- package/src/__tests__/parameter-prompt-hint-pack-fallback.test.ts +25 -0
- package/src/__tests__/person-packs.test.ts +166 -0
- package/src/__tests__/project-all-catalogs.test.ts +26 -0
- package/src/__tests__/prompt-builder.test.ts +53 -0
- package/src/__tests__/registered-catalogs-funnel.test.ts +30 -0
- package/src/__tests__/registered-catalogs-guard.test.ts +11 -0
- package/src/__tests__/term.test.ts +104 -0
- package/src/__tests__/transitions.test.ts +8 -5
- package/src/__tests__/upstream-immutability.test.ts +23 -0
- package/src/action-fx.ts +67 -17
- package/src/aesthetic.ts +54 -6
- package/src/atmosphere.ts +64 -23
- package/src/backdrop.ts +44 -30
- package/src/camera-format.ts +33 -11
- package/src/camera-motions.ts +89 -0
- package/src/catalog-packs.ts +125 -0
- package/src/catalog-sidecar-coverage.ts +36 -0
- package/src/character-fx.ts +112 -39
- package/src/color-look.ts +44 -27
- package/src/composition-effects.ts +21 -7
- package/src/era.ts +24 -0
- package/src/exposure-settings.ts +76 -18
- package/src/framing.ts +100 -0
- package/src/held-prop.ts +125 -63
- package/src/identity-lock.ts +12 -5
- package/src/image-reference-doctrine.ts +55 -0
- package/src/index.ts +5 -0
- package/src/instrumentation.ts +148 -57
- package/src/lens.ts +31 -15
- package/src/lighting.ts +120 -59
- package/src/loop-subject.ts +27 -1
- package/src/materials.ts +123 -69
- package/src/mood.ts +123 -51
- package/src/music-genre.ts +171 -67
- package/src/music-mood.ts +85 -17
- package/src/parameter-prompt-hint.ts +168 -56
- package/src/person-packs.ts +182 -0
- package/src/person.ts +506 -408
- package/src/photo-genre.ts +37 -22
- package/src/photographer.ts +138 -1
- package/src/picker-catalogs.ts +86 -40
- package/src/pose.ts +105 -40
- package/src/post-process-effects.ts +51 -8
- package/src/prompt-builder.ts +16 -1
- package/src/render-quality.ts +25 -7
- package/src/setting.ts +30 -14
- package/src/style.ts +33 -15
- package/src/styling.ts +155 -94
- package/src/temporal.ts +80 -18
- package/src/term.ts +155 -0
- package/src/transitions.ts +73 -26
- package/src/voice-character.ts +190 -90
- package/src/voice-delivery.ts +83 -12
package/src/materials.ts
CHANGED
|
@@ -8,7 +8,10 @@
|
|
|
8
8
|
*
|
|
9
9
|
* Grammar: every entry's `promptHint` begins with `"made of ..."` — this reads
|
|
10
10
|
* correctly regardless of target ("a dress made of silk", "a human made of
|
|
11
|
-
* glass", "a pillow made of leather", "a train made of plastic").
|
|
11
|
+
* glass", "a pillow made of leather", "a train made of plastic"). The compact
|
|
12
|
+
* `term` keeps that same head ("made of polished gold"): without it the
|
|
13
|
+
* fragment stops saying what the subject IS and merely names a material
|
|
14
|
+
* present in the scene, which is a different image.
|
|
12
15
|
*
|
|
13
16
|
* For clothing-specific phrasing ("wearing silk"), see the `fabric` dimension
|
|
14
17
|
* on the Styling node. There is intentional overlap in vocabulary (leather,
|
|
@@ -20,6 +23,8 @@
|
|
|
20
23
|
* backend orchestrator.
|
|
21
24
|
*/
|
|
22
25
|
|
|
26
|
+
import { resolveTerm, type PickerHintMode } from "./term.js"
|
|
27
|
+
|
|
23
28
|
export type MaterialCategory =
|
|
24
29
|
| "fabric"
|
|
25
30
|
| "metal"
|
|
@@ -35,89 +40,99 @@ export interface Material {
|
|
|
35
40
|
readonly category: MaterialCategory
|
|
36
41
|
readonly description: string
|
|
37
42
|
readonly promptHint: string
|
|
43
|
+
/**
|
|
44
|
+
* Compact professional term (see `term.ts`). Authored on EVERY material, and
|
|
45
|
+
* always in the catalog's `"made of ..."` grammar — that grammar is what
|
|
46
|
+
* makes the fragment mean "the subject IS this material" rather than "this
|
|
47
|
+
* material is somewhere in the scene", so it belongs to the term as much as
|
|
48
|
+
* to the hint. It also carries the qualifier the label drops where the bare
|
|
49
|
+
* noun would mislead: "gold"/"silver" alone read as COLORS, "mesh" as 3D
|
|
50
|
+
* geometry, "Subsurface Glow" is a UI label for subsurface scattering.
|
|
51
|
+
*/
|
|
52
|
+
readonly term?: string
|
|
38
53
|
}
|
|
39
54
|
|
|
40
55
|
export const MATERIALS: ReadonlyArray<Material> = [
|
|
41
56
|
// -------------------- Fabric --------------------
|
|
42
|
-
{ id: "silk", label: "Silk", category: "fabric", description: "Smooth glossy silk", promptHint: "made of smooth glossy silk with a subtle natural sheen and delicate fluid drape" },
|
|
43
|
-
{ id: "cotton", label: "Cotton", category: "fabric", description: "Soft matte cotton", promptHint: "made of soft matte cotton fabric with a natural woven texture and subtle wrinkles" },
|
|
44
|
-
{ id: "denim", label: "Denim", category: "fabric", description: "Heavy indigo denim", promptHint: "made of heavy indigo denim with visible diagonal weave, worn edges and subtle fading" },
|
|
45
|
-
{ id: "leather", label: "Leather", category: "fabric", description: "Rich supple leather", promptHint: "made of rich supple leather with a soft satin sheen, natural grain and warm brown tones" },
|
|
46
|
-
{ id: "velvet", label: "Velvet", category: "fabric", description: "Plush velvet", promptHint: "made of plush velvet with a deep soft nap, rich saturated color and directional sheen" },
|
|
47
|
-
{ id: "satin", label: "Satin", category: "fabric", description: "Glossy satin", promptHint: "made of glossy satin with a lustrous mirror-like surface and fluid draping folds" },
|
|
48
|
-
{ id: "lace", label: "Lace", category: "fabric", description: "Delicate patterned lace", promptHint: "made of delicate patterned lace with intricate floral openwork and a fine translucent texture" },
|
|
49
|
-
{ id: "wool", label: "Wool", category: "fabric", description: "Warm woven wool", promptHint: "made of warm woven wool with a soft matte surface, visible fibers and a cozy textured feel" },
|
|
50
|
-
{ id: "linen", label: "Linen", category: "fabric", description: "Natural textured linen", promptHint: "made of natural linen with a loose open weave, slight slubs and a slightly wrinkled airy drape" },
|
|
51
|
-
{ id: "tweed", label: "Tweed", category: "fabric", description: "Rustic woven tweed", promptHint: "made of rustic tweed with a flecked multi-color woven texture and a rough heritage feel" },
|
|
52
|
-
{ id: "cashmere", label: "Cashmere", category: "fabric", description: "Luxurious soft cashmere", promptHint: "made of luxurious cashmere with an ultra-soft matte texture and a fine dense weave" },
|
|
53
|
-
{ id: "chiffon", label: "Chiffon", category: "fabric", description: "Sheer flowing chiffon", promptHint: "made of sheer chiffon with a lightweight floating drape, soft translucent layers and a gentle shimmer" },
|
|
54
|
-
{ id: "fur", label: "Fur", category: "fabric", description: "Thick plush fur", promptHint: "made of thick plush fur with long dense strands, natural variation and a soft directional flow" },
|
|
55
|
-
{ id: "suede", label: "Suede", category: "fabric", description: "Soft napped suede", promptHint: "made of soft napped suede with a matte velvety surface, fine fuzzy texture and a warm leather feel" },
|
|
56
|
-
{ id: "mesh", label: "Mesh", category: "fabric", description: "See-through net mesh", promptHint: "made of see-through net mesh with an open woven grid, sheer transparency and an athletic technical feel" },
|
|
57
|
-
{ id: "patent-leather", label: "Patent Leather", category: "fabric", description: "High-gloss patent leather", promptHint: "made of high-gloss patent leather with a mirror-bright reflective surface, deep saturated color and a slick lacquered finish" },
|
|
57
|
+
{ id: "silk", label: "Silk", category: "fabric", description: "Smooth glossy silk", promptHint: "made of smooth glossy silk with a subtle natural sheen and delicate fluid drape", term: "made of silk" },
|
|
58
|
+
{ id: "cotton", label: "Cotton", category: "fabric", description: "Soft matte cotton", promptHint: "made of soft matte cotton fabric with a natural woven texture and subtle wrinkles", term: "made of cotton" },
|
|
59
|
+
{ id: "denim", label: "Denim", category: "fabric", description: "Heavy indigo denim", promptHint: "made of heavy indigo denim with visible diagonal weave, worn edges and subtle fading", term: "made of heavy indigo denim" },
|
|
60
|
+
{ id: "leather", label: "Leather", category: "fabric", description: "Rich supple leather", promptHint: "made of rich supple leather with a soft satin sheen, natural grain and warm brown tones", term: "made of leather" },
|
|
61
|
+
{ id: "velvet", label: "Velvet", category: "fabric", description: "Plush velvet", promptHint: "made of plush velvet with a deep soft nap, rich saturated color and directional sheen", term: "made of velvet" },
|
|
62
|
+
{ id: "satin", label: "Satin", category: "fabric", description: "Glossy satin", promptHint: "made of glossy satin with a lustrous mirror-like surface and fluid draping folds", term: "made of satin" },
|
|
63
|
+
{ id: "lace", label: "Lace", category: "fabric", description: "Delicate patterned lace", promptHint: "made of delicate patterned lace with intricate floral openwork and a fine translucent texture", term: "made of lace" },
|
|
64
|
+
{ id: "wool", label: "Wool", category: "fabric", description: "Warm woven wool", promptHint: "made of warm woven wool with a soft matte surface, visible fibers and a cozy textured feel", term: "made of wool" },
|
|
65
|
+
{ id: "linen", label: "Linen", category: "fabric", description: "Natural textured linen", promptHint: "made of natural linen with a loose open weave, slight slubs and a slightly wrinkled airy drape", term: "made of linen" },
|
|
66
|
+
{ id: "tweed", label: "Tweed", category: "fabric", description: "Rustic woven tweed", promptHint: "made of rustic tweed with a flecked multi-color woven texture and a rough heritage feel", term: "made of tweed" },
|
|
67
|
+
{ id: "cashmere", label: "Cashmere", category: "fabric", description: "Luxurious soft cashmere", promptHint: "made of luxurious cashmere with an ultra-soft matte texture and a fine dense weave", term: "made of cashmere" },
|
|
68
|
+
{ id: "chiffon", label: "Chiffon", category: "fabric", description: "Sheer flowing chiffon", promptHint: "made of sheer chiffon with a lightweight floating drape, soft translucent layers and a gentle shimmer", term: "made of chiffon" },
|
|
69
|
+
{ id: "fur", label: "Fur", category: "fabric", description: "Thick plush fur", promptHint: "made of thick plush fur with long dense strands, natural variation and a soft directional flow", term: "made of fur" },
|
|
70
|
+
{ id: "suede", label: "Suede", category: "fabric", description: "Soft napped suede", promptHint: "made of soft napped suede with a matte velvety surface, fine fuzzy texture and a warm leather feel", term: "made of suede" },
|
|
71
|
+
{ id: "mesh", label: "Mesh", category: "fabric", description: "See-through net mesh", promptHint: "made of see-through net mesh with an open woven grid, sheer transparency and an athletic technical feel", term: "made of sheer mesh fabric" },
|
|
72
|
+
{ id: "patent-leather", label: "Patent Leather", category: "fabric", description: "High-gloss patent leather", promptHint: "made of high-gloss patent leather with a mirror-bright reflective surface, deep saturated color and a slick lacquered finish", term: "made of patent leather" },
|
|
58
73
|
|
|
59
74
|
// -------------------- Metal --------------------
|
|
60
|
-
{ id: "gold", label: "Gold", category: "metal", description: "Polished gold", promptHint: "made of polished gold with a warm yellow metallic sheen and rich mirror-like reflections" },
|
|
61
|
-
{ id: "silver", label: "Silver", category: "metal", description: "Polished silver", promptHint: "made of polished silver with a cool bright metallic sheen and clean mirror-like reflections" },
|
|
62
|
-
{ id: "bronze", label: "Bronze", category: "metal", description: "Patinaed cast bronze", promptHint: "made of cast bronze with a warm brown-gold metallic surface and a mottled greenish patina in the recesses" },
|
|
63
|
-
{ id: "chrome", label: "Chrome", category: "metal", description: "Hyper-reflective chrome", promptHint: "made of hyper-reflective polished chrome with liquid mirror surfaces and sharp environmental reflections" },
|
|
64
|
-
{ id: "copper", label: "Copper", category: "metal", description: "Warm copper with patina", promptHint: "made of warm copper with a rich rose-orange metallic gleam and touches of blue-green oxidation" },
|
|
65
|
-
{ id: "brass", label: "Brass", category: "metal", description: "Antique brass", promptHint: "made of antique brass with a warm yellow-gold hue, brushed texture and slight tarnish in the crevices" },
|
|
66
|
-
{ id: "steel", label: "Steel", category: "metal", description: "Brushed stainless steel", promptHint: "made of brushed stainless steel with fine directional grain and cool soft reflections" },
|
|
67
|
-
{ id: "iron", label: "Iron", category: "metal", description: "Rough wrought iron", promptHint: "made of rough wrought iron with a dark matte surface, hammered texture and traces of rust" },
|
|
68
|
-
{ id: "platinum", label: "Platinum", category: "metal", description: "Lustrous platinum", promptHint: "made of lustrous platinum with a cool white-grey metallic sheen and premium polished finish" },
|
|
69
|
-
{ id: "titanium", label: "Titanium", category: "metal", description: "Matte industrial titanium", promptHint: "made of matte titanium with a cool silvery-grey surface, subtle anodized tints and an industrial precision finish" },
|
|
75
|
+
{ id: "gold", label: "Gold", category: "metal", description: "Polished gold", promptHint: "made of polished gold with a warm yellow metallic sheen and rich mirror-like reflections", term: "made of polished gold" },
|
|
76
|
+
{ id: "silver", label: "Silver", category: "metal", description: "Polished silver", promptHint: "made of polished silver with a cool bright metallic sheen and clean mirror-like reflections", term: "made of polished silver" },
|
|
77
|
+
{ id: "bronze", label: "Bronze", category: "metal", description: "Patinaed cast bronze", promptHint: "made of cast bronze with a warm brown-gold metallic surface and a mottled greenish patina in the recesses", term: "made of patinated cast bronze" },
|
|
78
|
+
{ id: "chrome", label: "Chrome", category: "metal", description: "Hyper-reflective chrome", promptHint: "made of hyper-reflective polished chrome with liquid mirror surfaces and sharp environmental reflections", term: "made of polished chrome" },
|
|
79
|
+
{ id: "copper", label: "Copper", category: "metal", description: "Warm copper with patina", promptHint: "made of warm copper with a rich rose-orange metallic gleam and touches of blue-green oxidation", term: "made of patinated copper" },
|
|
80
|
+
{ id: "brass", label: "Brass", category: "metal", description: "Antique brass", promptHint: "made of antique brass with a warm yellow-gold hue, brushed texture and slight tarnish in the crevices", term: "made of antique brass" },
|
|
81
|
+
{ id: "steel", label: "Steel", category: "metal", description: "Brushed stainless steel", promptHint: "made of brushed stainless steel with fine directional grain and cool soft reflections", term: "made of brushed stainless steel" },
|
|
82
|
+
{ id: "iron", label: "Iron", category: "metal", description: "Rough wrought iron", promptHint: "made of rough wrought iron with a dark matte surface, hammered texture and traces of rust", term: "made of wrought iron" },
|
|
83
|
+
{ id: "platinum", label: "Platinum", category: "metal", description: "Lustrous platinum", promptHint: "made of lustrous platinum with a cool white-grey metallic sheen and premium polished finish", term: "made of polished platinum" },
|
|
84
|
+
{ id: "titanium", label: "Titanium", category: "metal", description: "Matte industrial titanium", promptHint: "made of matte titanium with a cool silvery-grey surface, subtle anodized tints and an industrial precision finish", term: "made of matte titanium" },
|
|
70
85
|
|
|
71
86
|
// -------------------- Stone --------------------
|
|
72
|
-
{ id: "marble", label: "Marble", category: "stone", description: "White marble with veins", promptHint: "made of polished white marble with grey-blue veining, a smooth glossy surface and classical elegance" },
|
|
73
|
-
{ id: "granite", label: "Granite", category: "stone", description: "Speckled polished granite", promptHint: "made of polished granite with a speckled grey-black crystalline surface and a cool glossy finish" },
|
|
74
|
-
{ id: "obsidian", label: "Obsidian", category: "stone", description: "Glossy black obsidian", promptHint: "made of polished black obsidian with a deep glassy surface, subtle rainbow flecks and razor-sharp highlights" },
|
|
75
|
-
{ id: "sandstone", label: "Sandstone", category: "stone", description: "Warm layered sandstone", promptHint: "made of warm weathered sandstone with horizontal layered striations, soft ochre tones and a rough grainy surface" },
|
|
76
|
-
{ id: "slate", label: "Slate", category: "stone", description: "Dark flat slate", promptHint: "made of dark slate with flat matte grey-blue surfaces, subtle cleavage lines and a cool sedimentary texture" },
|
|
77
|
-
{ id: "jade", label: "Jade", category: "stone", description: "Translucent green jade", promptHint: "made of polished jade with a translucent green glow, fine internal veining and a smooth waxy surface" },
|
|
78
|
-
{ id: "onyx", label: "Onyx", category: "stone", description: "Banded polished onyx", promptHint: "made of polished onyx with dramatic black-and-white banding, translucent depth and a glossy finish" },
|
|
79
|
-
{ id: "concrete", label: "Concrete", category: "stone", description: "Cast industrial concrete", promptHint: "made of cast concrete with a rough grey surface, visible formwork lines, scattered aggregate and an industrial brutalist feel" },
|
|
80
|
-
{ id: "terrazzo", label: "Terrazzo", category: "stone", description: "Composite terrazzo with chips", promptHint: "made of polished terrazzo with embedded marble and glass chips suspended in a smooth cement matrix, a mid-century speckled surface and a glossy finish" },
|
|
87
|
+
{ id: "marble", label: "Marble", category: "stone", description: "White marble with veins", promptHint: "made of polished white marble with grey-blue veining, a smooth glossy surface and classical elegance", term: "made of polished marble" },
|
|
88
|
+
{ id: "granite", label: "Granite", category: "stone", description: "Speckled polished granite", promptHint: "made of polished granite with a speckled grey-black crystalline surface and a cool glossy finish", term: "made of polished granite" },
|
|
89
|
+
{ id: "obsidian", label: "Obsidian", category: "stone", description: "Glossy black obsidian", promptHint: "made of polished black obsidian with a deep glassy surface, subtle rainbow flecks and razor-sharp highlights", term: "made of polished obsidian" },
|
|
90
|
+
{ id: "sandstone", label: "Sandstone", category: "stone", description: "Warm layered sandstone", promptHint: "made of warm weathered sandstone with horizontal layered striations, soft ochre tones and a rough grainy surface", term: "made of weathered sandstone" },
|
|
91
|
+
{ id: "slate", label: "Slate", category: "stone", description: "Dark flat slate", promptHint: "made of dark slate with flat matte grey-blue surfaces, subtle cleavage lines and a cool sedimentary texture", term: "made of slate" },
|
|
92
|
+
{ id: "jade", label: "Jade", category: "stone", description: "Translucent green jade", promptHint: "made of polished jade with a translucent green glow, fine internal veining and a smooth waxy surface", term: "made of polished jade" },
|
|
93
|
+
{ id: "onyx", label: "Onyx", category: "stone", description: "Banded polished onyx", promptHint: "made of polished onyx with dramatic black-and-white banding, translucent depth and a glossy finish", term: "made of polished onyx" },
|
|
94
|
+
{ id: "concrete", label: "Concrete", category: "stone", description: "Cast industrial concrete", promptHint: "made of cast concrete with a rough grey surface, visible formwork lines, scattered aggregate and an industrial brutalist feel", term: "made of cast concrete" },
|
|
95
|
+
{ id: "terrazzo", label: "Terrazzo", category: "stone", description: "Composite terrazzo with chips", promptHint: "made of polished terrazzo with embedded marble and glass chips suspended in a smooth cement matrix, a mid-century speckled surface and a glossy finish", term: "made of polished terrazzo" },
|
|
81
96
|
|
|
82
97
|
// -------------------- Wood --------------------
|
|
83
|
-
{ id: "oak", label: "Oak", category: "wood", description: "Rich grained oak", promptHint: "made of rich grained oak with warm honey-brown tones, strong vertical grain lines and a satin finish" },
|
|
84
|
-
{ id: "mahogany", label: "Mahogany", category: "wood", description: "Deep red mahogany", promptHint: "made of polished mahogany with a deep reddish-brown tone, tight swirling grain and a glossy heirloom finish" },
|
|
85
|
-
{ id: "walnut", label: "Walnut", category: "wood", description: "Dark walnut", promptHint: "made of walnut with deep chocolate-brown tones, flowing grain patterns and a soft satin sheen" },
|
|
86
|
-
{ id: "bamboo", label: "Bamboo", category: "wood", description: "Light segmented bamboo", promptHint: "made of pale bamboo with visible horizontal node segments, clean vertical grain and a light natural finish" },
|
|
87
|
-
{ id: "birch", label: "Birch", category: "wood", description: "Pale smooth birch", promptHint: "made of pale birch with fine close grain, a smooth cream-white surface and subtle warmth" },
|
|
88
|
-
{ id: "driftwood", label: "Driftwood", category: "wood", description: "Weathered driftwood", promptHint: "made of weathered driftwood with silver-grey sun-bleached surfaces, smoothed edges and a raw organic texture" },
|
|
98
|
+
{ id: "oak", label: "Oak", category: "wood", description: "Rich grained oak", promptHint: "made of rich grained oak with warm honey-brown tones, strong vertical grain lines and a satin finish", term: "made of oak" },
|
|
99
|
+
{ id: "mahogany", label: "Mahogany", category: "wood", description: "Deep red mahogany", promptHint: "made of polished mahogany with a deep reddish-brown tone, tight swirling grain and a glossy heirloom finish", term: "made of polished mahogany" },
|
|
100
|
+
{ id: "walnut", label: "Walnut", category: "wood", description: "Dark walnut", promptHint: "made of walnut with deep chocolate-brown tones, flowing grain patterns and a soft satin sheen", term: "made of walnut" },
|
|
101
|
+
{ id: "bamboo", label: "Bamboo", category: "wood", description: "Light segmented bamboo", promptHint: "made of pale bamboo with visible horizontal node segments, clean vertical grain and a light natural finish", term: "made of bamboo" },
|
|
102
|
+
{ id: "birch", label: "Birch", category: "wood", description: "Pale smooth birch", promptHint: "made of pale birch with fine close grain, a smooth cream-white surface and subtle warmth", term: "made of birch" },
|
|
103
|
+
{ id: "driftwood", label: "Driftwood", category: "wood", description: "Weathered driftwood", promptHint: "made of weathered driftwood with silver-grey sun-bleached surfaces, smoothed edges and a raw organic texture", term: "made of weathered driftwood" },
|
|
89
104
|
|
|
90
105
|
// -------------------- Glass / Ceramic --------------------
|
|
91
|
-
{ id: "glass", label: "Glass", category: "glass-ceramic", description: "Clear transparent glass", promptHint: "made of clear transparent glass with sharp refracted highlights, crisp edge caustics and subtle internal reflections" },
|
|
92
|
-
{ id: "stained-glass", label: "Stained Glass", category: "glass-ceramic", description: "Jewel-toned stained glass", promptHint: "made of stained glass with jewel-toned panels, dark lead caming and vibrant light filtering through saturated color" },
|
|
93
|
-
{ id: "crystal", label: "Crystal", category: "glass-ceramic", description: "Faceted clear crystal", promptHint: "made of faceted clear crystal with sharp prismatic facets, rainbow caustics and brilliant internal reflections" },
|
|
94
|
-
{ id: "porcelain", label: "Porcelain", category: "glass-ceramic", description: "Smooth white porcelain", promptHint: "made of smooth white porcelain with a soft satin glaze, delicate translucency and a fine ceramic finish" },
|
|
95
|
-
{ id: "ceramic-glazed", label: "Glazed Ceramic", category: "glass-ceramic", description: "Earthy glazed ceramic", promptHint: "made of glazed ceramic with warm earth tones, a glossy vitrified surface and subtle kiln-fired variation" },
|
|
96
|
-
{ id: "terracotta", label: "Terracotta", category: "glass-ceramic", description: "Warm unglazed terracotta", promptHint: "made of unglazed terracotta with a warm orange-brown matte surface, fine clay texture and a rustic handmade feel" },
|
|
106
|
+
{ id: "glass", label: "Glass", category: "glass-ceramic", description: "Clear transparent glass", promptHint: "made of clear transparent glass with sharp refracted highlights, crisp edge caustics and subtle internal reflections", term: "made of clear glass" },
|
|
107
|
+
{ id: "stained-glass", label: "Stained Glass", category: "glass-ceramic", description: "Jewel-toned stained glass", promptHint: "made of stained glass with jewel-toned panels, dark lead caming and vibrant light filtering through saturated color", term: "made of stained glass" },
|
|
108
|
+
{ id: "crystal", label: "Crystal", category: "glass-ceramic", description: "Faceted clear crystal", promptHint: "made of faceted clear crystal with sharp prismatic facets, rainbow caustics and brilliant internal reflections", term: "made of faceted crystal" },
|
|
109
|
+
{ id: "porcelain", label: "Porcelain", category: "glass-ceramic", description: "Smooth white porcelain", promptHint: "made of smooth white porcelain with a soft satin glaze, delicate translucency and a fine ceramic finish", term: "made of porcelain" },
|
|
110
|
+
{ id: "ceramic-glazed", label: "Glazed Ceramic", category: "glass-ceramic", description: "Earthy glazed ceramic", promptHint: "made of glazed ceramic with warm earth tones, a glossy vitrified surface and subtle kiln-fired variation", term: "made of glazed ceramic" },
|
|
111
|
+
{ id: "terracotta", label: "Terracotta", category: "glass-ceramic", description: "Warm unglazed terracotta", promptHint: "made of unglazed terracotta with a warm orange-brown matte surface, fine clay texture and a rustic handmade feel", term: "made of unglazed terracotta" },
|
|
97
112
|
|
|
98
113
|
// -------------------- Natural / Elemental --------------------
|
|
99
|
-
{ id: "water", label: "Water", category: "natural", description: "Flowing translucent water", promptHint: "made of flowing translucent water with dynamic refractions, moving highlights and rippled internal caustics" },
|
|
100
|
-
{ id: "fire", label: "Fire", category: "natural", description: "Living flame", promptHint: "made of living flame with dancing orange-yellow tongues, glowing ember cores and wisps of drifting smoke" },
|
|
101
|
-
{ id: "ice", label: "Ice", category: "natural", description: "Translucent crystalline ice", promptHint: "made of translucent crystalline ice with internal fractures, cool blue highlights and a frosted glossy surface" },
|
|
102
|
-
{ id: "smoke", label: "Smoke", category: "natural", description: "Drifting ethereal smoke", promptHint: "made of drifting ethereal smoke with soft volumetric wisps, translucent layers and a slow hypnotic flow" },
|
|
103
|
-
{ id: "sand", label: "Sand", category: "natural", description: "Fine granular sand", promptHint: "made of fine granular sand with a soft golden matte surface, subtle grain texture and gentle shifting edges" },
|
|
104
|
-
{ id: "moss", label: "Moss", category: "natural", description: "Lush living moss", promptHint: "made of lush living moss with a soft velvety green surface, fine plant texture and an organic overgrown feel" },
|
|
105
|
-
{ id: "leaves", label: "Leaves", category: "natural", description: "Layered plant leaves", promptHint: "made of layered plant leaves with overlapping green foliage, visible veining and a natural dappled texture" },
|
|
114
|
+
{ id: "water", label: "Water", category: "natural", description: "Flowing translucent water", promptHint: "made of flowing translucent water with dynamic refractions, moving highlights and rippled internal caustics", term: "made of flowing water" },
|
|
115
|
+
{ id: "fire", label: "Fire", category: "natural", description: "Living flame", promptHint: "made of living flame with dancing orange-yellow tongues, glowing ember cores and wisps of drifting smoke", term: "made of living flame" },
|
|
116
|
+
{ id: "ice", label: "Ice", category: "natural", description: "Translucent crystalline ice", promptHint: "made of translucent crystalline ice with internal fractures, cool blue highlights and a frosted glossy surface", term: "made of crystalline ice" },
|
|
117
|
+
{ id: "smoke", label: "Smoke", category: "natural", description: "Drifting ethereal smoke", promptHint: "made of drifting ethereal smoke with soft volumetric wisps, translucent layers and a slow hypnotic flow", term: "made of drifting smoke" },
|
|
118
|
+
{ id: "sand", label: "Sand", category: "natural", description: "Fine granular sand", promptHint: "made of fine granular sand with a soft golden matte surface, subtle grain texture and gentle shifting edges", term: "made of fine sand" },
|
|
119
|
+
{ id: "moss", label: "Moss", category: "natural", description: "Lush living moss", promptHint: "made of lush living moss with a soft velvety green surface, fine plant texture and an organic overgrown feel", term: "made of living moss" },
|
|
120
|
+
{ id: "leaves", label: "Leaves", category: "natural", description: "Layered plant leaves", promptHint: "made of layered plant leaves with overlapping green foliage, visible veining and a natural dappled texture", term: "made of layered plant leaves" },
|
|
106
121
|
|
|
107
122
|
// -------------------- Exotic / Futuristic --------------------
|
|
108
|
-
{ id: "holographic", label: "Holographic", category: "exotic", description: "Iridescent hologram", promptHint: "made of holographic iridescent material with shifting rainbow sheen, prismatic highlights and a futuristic shimmer" },
|
|
109
|
-
{ id: "liquid-metal", label: "Liquid Metal", category: "exotic", description: "Reflective liquid chrome", promptHint: "made of reflective liquid metal with a flowing mercury-like chrome surface, seamless reflections and metallic pooling highlights" },
|
|
110
|
-
{ id: "neon", label: "Neon Glow", category: "exotic", description: "Glowing neon tubing", promptHint: "made of glowing neon tubing with saturated magenta and cyan light, a soft halo glow and a cybernetic futuristic feel" },
|
|
111
|
-
{ id: "translucent", label: "Translucent Resin", category: "exotic", description: "Frosted glowing resin", promptHint: "made of frosted translucent resin with soft internal glow, milky subsurface scattering and a smooth cast finish" },
|
|
112
|
-
{ id: "subsurface", label: "Subsurface Glow", category: "exotic", description: "Light glows beneath the surface", promptHint: "made of a soft translucent material with pronounced subsurface scattering, light penetrating beneath the surface and glowing warmly from within" },
|
|
113
|
-
{ id: "mirror", label: "Mirror", category: "exotic", description: "Perfect mirror surface", promptHint: "made of perfect mirror surface with flawless reflections, no tint and razor-sharp reflected detail" },
|
|
114
|
-
{ id: "plasma", label: "Plasma", category: "exotic", description: "Glowing electric plasma", promptHint: "made of glowing electric plasma with arcing internal bolts, a radiant violet-pink core and a haze of ionized energy" },
|
|
115
|
-
{ id: "crystal-shard", label: "Crystal Shards", category: "exotic", description: "Shattered glowing crystal", promptHint: "made of fractured glowing crystal shards with sharp prismatic facets, internal luminescence and dynamic rainbow refraction" },
|
|
116
|
-
{ id: "obsidian-glass", label: "Obsidian Glass", category: "exotic", description: "Dark volcanic glass", promptHint: "made of dark obsidian volcanic glass with a glossy black surface, razor-sharp edges and subtle iridescent highlights" },
|
|
117
|
-
{ id: "iridescent", label: "Iridescent", category: "exotic", description: "Color-shifting iridescent surface", promptHint: "made of iridescent rainbow-shifting surface, the kind of color play seen on oil slicks, butterfly wings and mother-of-pearl, with hues that shift as the angle changes" },
|
|
118
|
-
{ id: "mother-of-pearl", label: "Mother-of-Pearl", category: "exotic", description: "Pearlescent inner shell layer", promptHint: "made of mother-of-pearl with a pearlescent cream surface, soft iridescent shimmer and the layered nacre depth seen in inlay work and fine jewelry" },
|
|
119
|
-
{ id: "carbon-fiber", label: "Carbon Fiber", category: "exotic", description: "Woven black carbon-fiber composite", promptHint: "made of woven carbon-fiber composite with a glossy black checkered weave pattern, a hi-tech aerospace feel and subtle directional sheen" },
|
|
120
|
-
{ id: "holographic-film", label: "Holographic Film", category: "exotic", description: "Light-refracting holographic film", promptHint: "made of light-refracting holographic film with a thin reflective sheet surface, prismatic rainbow shimmer and shifting spectral highlights as the angle changes" },
|
|
123
|
+
{ id: "holographic", label: "Holographic", category: "exotic", description: "Iridescent hologram", promptHint: "made of holographic iridescent material with shifting rainbow sheen, prismatic highlights and a futuristic shimmer", term: "made of holographic iridescent material" },
|
|
124
|
+
{ id: "liquid-metal", label: "Liquid Metal", category: "exotic", description: "Reflective liquid chrome", promptHint: "made of reflective liquid metal with a flowing mercury-like chrome surface, seamless reflections and metallic pooling highlights", term: "made of liquid metal" },
|
|
125
|
+
{ id: "neon", label: "Neon Glow", category: "exotic", description: "Glowing neon tubing", promptHint: "made of glowing neon tubing with saturated magenta and cyan light, a soft halo glow and a cybernetic futuristic feel", term: "made of glowing neon tubing" },
|
|
126
|
+
{ id: "translucent", label: "Translucent Resin", category: "exotic", description: "Frosted glowing resin", promptHint: "made of frosted translucent resin with soft internal glow, milky subsurface scattering and a smooth cast finish", term: "made of translucent resin" },
|
|
127
|
+
{ id: "subsurface", label: "Subsurface Glow", category: "exotic", description: "Light glows beneath the surface", promptHint: "made of a soft translucent material with pronounced subsurface scattering, light penetrating beneath the surface and glowing warmly from within", term: "made of translucent subsurface-scattering material" },
|
|
128
|
+
{ id: "mirror", label: "Mirror", category: "exotic", description: "Perfect mirror surface", promptHint: "made of perfect mirror surface with flawless reflections, no tint and razor-sharp reflected detail", term: "made of perfect mirror surface" },
|
|
129
|
+
{ id: "plasma", label: "Plasma", category: "exotic", description: "Glowing electric plasma", promptHint: "made of glowing electric plasma with arcing internal bolts, a radiant violet-pink core and a haze of ionized energy", term: "made of glowing electric plasma" },
|
|
130
|
+
{ id: "crystal-shard", label: "Crystal Shards", category: "exotic", description: "Shattered glowing crystal", promptHint: "made of fractured glowing crystal shards with sharp prismatic facets, internal luminescence and dynamic rainbow refraction", term: "made of fractured glowing crystal shards" },
|
|
131
|
+
{ id: "obsidian-glass", label: "Obsidian Glass", category: "exotic", description: "Dark volcanic glass", promptHint: "made of dark obsidian volcanic glass with a glossy black surface, razor-sharp edges and subtle iridescent highlights", term: "made of dark volcanic obsidian glass" },
|
|
132
|
+
{ id: "iridescent", label: "Iridescent", category: "exotic", description: "Color-shifting iridescent surface", promptHint: "made of iridescent rainbow-shifting surface, the kind of color play seen on oil slicks, butterfly wings and mother-of-pearl, with hues that shift as the angle changes", term: "made of iridescent color-shifting material" },
|
|
133
|
+
{ id: "mother-of-pearl", label: "Mother-of-Pearl", category: "exotic", description: "Pearlescent inner shell layer", promptHint: "made of mother-of-pearl with a pearlescent cream surface, soft iridescent shimmer and the layered nacre depth seen in inlay work and fine jewelry", term: "made of mother-of-pearl" },
|
|
134
|
+
{ id: "carbon-fiber", label: "Carbon Fiber", category: "exotic", description: "Woven black carbon-fiber composite", promptHint: "made of woven carbon-fiber composite with a glossy black checkered weave pattern, a hi-tech aerospace feel and subtle directional sheen", term: "made of woven carbon fiber" },
|
|
135
|
+
{ id: "holographic-film", label: "Holographic Film", category: "exotic", description: "Light-refracting holographic film", promptHint: "made of light-refracting holographic film with a thin reflective sheet surface, prismatic rainbow shimmer and shifting spectral highlights as the angle changes", term: "made of holographic film" },
|
|
121
136
|
] as const
|
|
122
137
|
|
|
123
138
|
const materialById = new Map<string, Material>(MATERIALS.map((m) => [m.id, m]))
|
|
@@ -138,12 +153,30 @@ export function getMaterialPromptHint(id: string | undefined | null): string {
|
|
|
138
153
|
return getMaterial(id)?.promptHint ?? ""
|
|
139
154
|
}
|
|
140
155
|
|
|
156
|
+
/**
|
|
157
|
+
* Compact counterpart of `getMaterialPromptHint`: the short professional term
|
|
158
|
+
* this material injects in compact hint mode ("made of brushed stainless
|
|
159
|
+
* steel" where the hint is the full "made of ..." paragraph). The `"made of"`
|
|
160
|
+
* grammar is part of the TERM, not a wrapper the consumer adds — it is what
|
|
161
|
+
* distinguishes "the subject is made of glass" from "there is glass in the
|
|
162
|
+
* scene", and a thin client injecting `term` standalone (see
|
|
163
|
+
* `ProjectedCatalogOption`) has nothing else to reconstruct it from. Empty
|
|
164
|
+
* string for an unknown id.
|
|
165
|
+
*/
|
|
166
|
+
export function getMaterialTerm(id: string | undefined | null): string {
|
|
167
|
+
return resolveTerm(getMaterial(id))
|
|
168
|
+
}
|
|
169
|
+
|
|
141
170
|
/**
|
|
142
171
|
* Multi-pick: 1-2 material ids → composite material clause. Single → entry's
|
|
143
172
|
* own promptHint. Two → "made of {A} and {B}" using lowercased entry labels.
|
|
144
173
|
* Covers leather+brass handbag, wood+steel chair, glass+chrome lamp, etc.
|
|
174
|
+
*
|
|
175
|
+
* @param mode `"compact"` emits the bare material term(s) instead (delegates
|
|
176
|
+
* to `buildMaterialTerms`).
|
|
145
177
|
*/
|
|
146
|
-
export function buildMaterialHints(value: unknown): string {
|
|
178
|
+
export function buildMaterialHints(value: unknown, mode: PickerHintMode = "full"): string {
|
|
179
|
+
if (mode === "compact") return buildMaterialTerms(value)
|
|
147
180
|
const ids: string[] = []
|
|
148
181
|
if (typeof value === "string" && value) ids.push(value)
|
|
149
182
|
else if (Array.isArray(value)) {
|
|
@@ -161,6 +194,27 @@ export function buildMaterialHints(value: unknown): string {
|
|
|
161
194
|
return `made of ${labels[0]} and ${labels[1]}`
|
|
162
195
|
}
|
|
163
196
|
|
|
197
|
+
/**
|
|
198
|
+
* Compact counterpart of `buildMaterialHints`: one material's term, or two
|
|
199
|
+
* joined with " and " ("made of polished gold and made of walnut"). Each term
|
|
200
|
+
* carries its own "made of" grammar, so the join needs no wrapper and a
|
|
201
|
+
* pack-added entry whose term is only the derived label still reads correctly.
|
|
202
|
+
*/
|
|
203
|
+
export function buildMaterialTerms(value: unknown): string {
|
|
204
|
+
const ids: string[] = []
|
|
205
|
+
if (typeof value === "string" && value) ids.push(value)
|
|
206
|
+
else if (Array.isArray(value)) {
|
|
207
|
+
for (const v of value) {
|
|
208
|
+
if (typeof v === "string" && v && !ids.includes(v)) ids.push(v)
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
const terms = ids
|
|
212
|
+
.slice(0, 2)
|
|
213
|
+
.map((id) => getMaterialTerm(id))
|
|
214
|
+
.filter((t) => t.length > 0)
|
|
215
|
+
return terms.join(" and ")
|
|
216
|
+
}
|
|
217
|
+
|
|
164
218
|
export const MATERIAL_IDS: ReadonlyArray<string> = MATERIALS.map((m) => m.id)
|
|
165
219
|
|
|
166
220
|
export const MATERIAL_CATEGORY_LABELS: Readonly<Record<MaterialCategory, string>> = {
|
package/src/mood.ts
CHANGED
|
@@ -23,6 +23,8 @@
|
|
|
23
23
|
* backend orchestrator.
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
|
+
import { resolveTerm, type PickerHintMode } from "./term.js"
|
|
27
|
+
|
|
26
28
|
export type MoodCategory = "positive" | "negative" | "neutral" | "intense"
|
|
27
29
|
|
|
28
30
|
export interface Mood {
|
|
@@ -31,69 +33,79 @@ export interface Mood {
|
|
|
31
33
|
readonly category: MoodCategory
|
|
32
34
|
readonly description: string
|
|
33
35
|
readonly promptHint: string
|
|
36
|
+
/**
|
|
37
|
+
* Compact professional term injected in compact hint mode (see `term.ts`).
|
|
38
|
+
*
|
|
39
|
+
* Written in the SAME register as the `promptHint`: this catalog describes
|
|
40
|
+
* the SUBJECT's emotional state, so a term names the expression / demeanor
|
|
41
|
+
* ("melancholic expression", "cocky smirk", "fierce, commanding intensity"),
|
|
42
|
+
* never the scene's mood — "melancholic mood" would instruct a different
|
|
43
|
+
* picture from the one full mode asks for.
|
|
44
|
+
*/
|
|
45
|
+
readonly term?: string
|
|
34
46
|
}
|
|
35
47
|
|
|
36
48
|
export const MOODS: ReadonlyArray<Mood> = [
|
|
37
49
|
// -------------------- Positive --------------------
|
|
38
|
-
{ id: "happy", label: "Happy", category: "positive", description: "Warm, smiling happiness", promptHint: "with a warm, happy expression and a genuine smile" },
|
|
39
|
-
{ id: "joyful", label: "Joyful", category: "positive", description: "Radiant, unrestrained joy", promptHint: "with a radiant, joyful expression full of delight, the corners of the mouth rising uncontrollably, steps light" },
|
|
40
|
-
{ id: "relieved", label: "Relieved", category: "positive", description: "Tension releasing into calm", promptHint: "with a relieved expression, letting out a long breath, shoulders relaxing completely, a faint long-awaited smile" },
|
|
41
|
-
{ id: "serene", label: "Serene", category: "positive", description: "Calm, peaceful contentment", promptHint: "with a serene, peaceful expression and relaxed posture" },
|
|
42
|
-
{ id: "playful", label: "Playful", category: "positive", description: "Mischievous, playful energy", promptHint: "with a playful, mischievous expression and light energy" },
|
|
43
|
-
{ id: "confident", label: "Confident", category: "positive", description: "Self-assured, confident", promptHint: "with a confident, self-assured expression and poised demeanor" },
|
|
44
|
-
{ id: "loving", label: "Loving", category: "positive", description: "Tender, affectionate", promptHint: "with a tender, loving expression" },
|
|
45
|
-
{ id: "amused", label: "Amused", category: "positive", description: "Subtly amused, smirking", promptHint: "with a subtly amused expression, a faint smirk" },
|
|
46
|
-
{ id: "smirking", label: "Smirking", category: "neutral", description: "Cocky, arrogant amusement", promptHint: "with a cocky, arrogant smirk and one eyebrow slightly raised" },
|
|
47
|
-
{ id: "eccentric", label: "Eccentric", category: "positive", description: "Quirky, unconventional", promptHint: "with a quirky, eccentric expression and offbeat playful energy" },
|
|
48
|
-
{ id: "hopeful", label: "Hopeful", category: "positive", description: "Bright-eyed, optimistic", promptHint: "with a hopeful expression, a soft slight smile and bright, expectant eyes" },
|
|
50
|
+
{ id: "happy", label: "Happy", category: "positive", description: "Warm, smiling happiness", promptHint: "with a warm, happy expression and a genuine smile", term: "happy expression" },
|
|
51
|
+
{ id: "joyful", label: "Joyful", category: "positive", description: "Radiant, unrestrained joy", promptHint: "with a radiant, joyful expression full of delight, the corners of the mouth rising uncontrollably, steps light", term: "radiant joyful expression" },
|
|
52
|
+
{ id: "relieved", label: "Relieved", category: "positive", description: "Tension releasing into calm", promptHint: "with a relieved expression, letting out a long breath, shoulders relaxing completely, a faint long-awaited smile", term: "relieved expression" },
|
|
53
|
+
{ id: "serene", label: "Serene", category: "positive", description: "Calm, peaceful contentment", promptHint: "with a serene, peaceful expression and relaxed posture", term: "serene expression" },
|
|
54
|
+
{ id: "playful", label: "Playful", category: "positive", description: "Mischievous, playful energy", promptHint: "with a playful, mischievous expression and light energy", term: "playful expression" },
|
|
55
|
+
{ id: "confident", label: "Confident", category: "positive", description: "Self-assured, confident", promptHint: "with a confident, self-assured expression and poised demeanor", term: "confident, self-assured demeanor" },
|
|
56
|
+
{ id: "loving", label: "Loving", category: "positive", description: "Tender, affectionate", promptHint: "with a tender, loving expression", term: "tender, loving expression" },
|
|
57
|
+
{ id: "amused", label: "Amused", category: "positive", description: "Subtly amused, smirking", promptHint: "with a subtly amused expression, a faint smirk", term: "faintly amused expression" },
|
|
58
|
+
{ id: "smirking", label: "Smirking", category: "neutral", description: "Cocky, arrogant amusement", promptHint: "with a cocky, arrogant smirk and one eyebrow slightly raised", term: "cocky smirk" },
|
|
59
|
+
{ id: "eccentric", label: "Eccentric", category: "positive", description: "Quirky, unconventional", promptHint: "with a quirky, eccentric expression and offbeat playful energy", term: "quirky, eccentric energy" },
|
|
60
|
+
{ id: "hopeful", label: "Hopeful", category: "positive", description: "Bright-eyed, optimistic", promptHint: "with a hopeful expression, a soft slight smile and bright, expectant eyes", term: "hopeful expression" },
|
|
49
61
|
|
|
50
62
|
// -------------------- Negative --------------------
|
|
51
|
-
{ id: "sad", label: "Sad", category: "negative", description: "Quietly sad, downcast", promptHint: "with a quietly sad, downcast expression, head lowered, shoulders trembling slightly, eyes reddening" },
|
|
52
|
-
{ id: "angry", label: "Angry", category: "negative", description: "Clear anger, tension", promptHint: "with an angry expression, furrowed brow and tight jaw, fists clenched, chest heaving" },
|
|
53
|
-
{ id: "afraid", label: "Afraid", category: "negative", description: "Frightened, wide-eyed", promptHint: "with a frightened expression, wide eyes and tense posture" },
|
|
54
|
-
{ id: "anxious", label: "Anxious", category: "negative", description: "Nervous, worried", promptHint: "with an anxious, worried expression and restless tension, fingers tapping, eyes darting, breath quickening" },
|
|
55
|
-
{ id: "melancholy", label: "Melancholy", category: "negative", description: "Wistful sadness", promptHint: "with a melancholy, wistful expression lost in thought" },
|
|
56
|
-
{ id: "devastated", label: "Devastated", category: "negative", description: "Heartbroken grief", promptHint: "with a devastated, heartbroken expression" },
|
|
57
|
-
{ id: "grieving", label: "Grieving", category: "negative", description: "Deep grief, loss", promptHint: "with a grieving expression of deep loss" },
|
|
58
|
-
{ id: "caught-off-guard", label: "Caught Off Guard", category: "negative", description: "Startled mid-reaction", promptHint: "with a startled, caught-off-guard expression, lips slightly parted mid-reaction" },
|
|
59
|
-
{ id: "aloof", label: "Aloof", category: "negative", description: "Withdrawn, uninterested", promptHint: "with an aloof, withdrawn expression and a gaze pointedly elsewhere" },
|
|
60
|
-
{ id: "vulnerable", label: "Vulnerable", category: "negative", description: "Exposed, defenseless", promptHint: "with a vulnerable, exposed expression, eyes faintly tearful and shoulders soft" },
|
|
61
|
-
{ id: "coy", label: "Coy", category: "negative", description: "Shy, downcast", promptHint: "with a coy, shy expression, downcast eyes, a faint blush and lips lightly pressed" },
|
|
62
|
-
{ id: "bored", label: "Bored", category: "negative", description: "Disinterested, deadpan", promptHint: "with a bored, disinterested expression and a slack, deadpan stare" },
|
|
63
|
-
{ id: "embarrassed", label: "Embarrassed", category: "negative", description: "Blushing, eyes averted", promptHint: "with an embarrassed expression, flushed red cheeks and eyes averted" },
|
|
64
|
-
{ id: "disgusted", label: "Disgusted", category: "negative", description: "Repulsed, recoiling", promptHint: "with a disgusted expression, lip curled and nose wrinkled in distaste" },
|
|
65
|
-
{ id: "bewildered", label: "Bewildered", category: "negative", description: "Confused, lost", promptHint: "with a bewildered, confused expression, brow furrowed and eyes wide" },
|
|
63
|
+
{ id: "sad", label: "Sad", category: "negative", description: "Quietly sad, downcast", promptHint: "with a quietly sad, downcast expression, head lowered, shoulders trembling slightly, eyes reddening", term: "sad, downcast expression" },
|
|
64
|
+
{ id: "angry", label: "Angry", category: "negative", description: "Clear anger, tension", promptHint: "with an angry expression, furrowed brow and tight jaw, fists clenched, chest heaving", term: "angry expression" },
|
|
65
|
+
{ id: "afraid", label: "Afraid", category: "negative", description: "Frightened, wide-eyed", promptHint: "with a frightened expression, wide eyes and tense posture", term: "fearful expression" },
|
|
66
|
+
{ id: "anxious", label: "Anxious", category: "negative", description: "Nervous, worried", promptHint: "with an anxious, worried expression and restless tension, fingers tapping, eyes darting, breath quickening", term: "anxious, nervous expression" },
|
|
67
|
+
{ id: "melancholy", label: "Melancholy", category: "negative", description: "Wistful sadness", promptHint: "with a melancholy, wistful expression lost in thought", term: "melancholic expression" },
|
|
68
|
+
{ id: "devastated", label: "Devastated", category: "negative", description: "Heartbroken grief", promptHint: "with a devastated, heartbroken expression", term: "devastated, heartbroken expression" },
|
|
69
|
+
{ id: "grieving", label: "Grieving", category: "negative", description: "Deep grief, loss", promptHint: "with a grieving expression of deep loss", term: "grief-stricken expression" },
|
|
70
|
+
{ id: "caught-off-guard", label: "Caught Off Guard", category: "negative", description: "Startled mid-reaction", promptHint: "with a startled, caught-off-guard expression, lips slightly parted mid-reaction", term: "caught-off-guard expression" },
|
|
71
|
+
{ id: "aloof", label: "Aloof", category: "negative", description: "Withdrawn, uninterested", promptHint: "with an aloof, withdrawn expression and a gaze pointedly elsewhere", term: "aloof, detached expression" },
|
|
72
|
+
{ id: "vulnerable", label: "Vulnerable", category: "negative", description: "Exposed, defenseless", promptHint: "with a vulnerable, exposed expression, eyes faintly tearful and shoulders soft", term: "vulnerable, exposed expression" },
|
|
73
|
+
{ id: "coy", label: "Coy", category: "negative", description: "Shy, downcast", promptHint: "with a coy, shy expression, downcast eyes, a faint blush and lips lightly pressed", term: "coy, bashful expression" },
|
|
74
|
+
{ id: "bored", label: "Bored", category: "negative", description: "Disinterested, deadpan", promptHint: "with a bored, disinterested expression and a slack, deadpan stare", term: "bored, deadpan expression" },
|
|
75
|
+
{ id: "embarrassed", label: "Embarrassed", category: "negative", description: "Blushing, eyes averted", promptHint: "with an embarrassed expression, flushed red cheeks and eyes averted", term: "embarrassed, flushed expression" },
|
|
76
|
+
{ id: "disgusted", label: "Disgusted", category: "negative", description: "Repulsed, recoiling", promptHint: "with a disgusted expression, lip curled and nose wrinkled in distaste", term: "disgusted expression" },
|
|
77
|
+
{ id: "bewildered", label: "Bewildered", category: "negative", description: "Confused, lost", promptHint: "with a bewildered, confused expression, brow furrowed and eyes wide", term: "bewildered expression" },
|
|
66
78
|
|
|
67
79
|
// -------------------- Neutral / Contemplative --------------------
|
|
68
|
-
{ id: "thoughtful", label: "Thoughtful", category: "neutral", description: "Deep in thought", promptHint: "with a thoughtful, contemplative expression" },
|
|
69
|
-
{ id: "stoic", label: "Stoic", category: "neutral", description: "Impassive, unreadable", promptHint: "with a stoic, impassive expression revealing nothing" },
|
|
70
|
-
{ id: "calm", label: "Calm", category: "neutral", description: "Centered, unreactive", promptHint: "with a calm, centered expression" },
|
|
71
|
-
{ id: "curious", label: "Curious", category: "neutral", description: "Intrigued, alert", promptHint: "with a curious, intrigued expression and alert eyes" },
|
|
72
|
-
{ id: "mysterious", label: "Mysterious", category: "neutral", description: "Inscrutable, enigmatic", promptHint: "with a mysterious, enigmatic expression hard to read" },
|
|
73
|
-
{ id: "dazed", label: "Dazed", category: "neutral", description: "Dreamy, half-present", promptHint: "with a dazed, dreamy expression, eyes slightly out of focus and only half-present" },
|
|
74
|
-
{ id: "sleepy", label: "Sleepy", category: "neutral", description: "Drowsy, heavy-lidded", promptHint: "with a sleepy, drowsy expression, heavy eyelids and a slow, soft blink" },
|
|
75
|
-
{ id: "unbothered", label: "Unbothered", category: "neutral", description: "Calm self-possession", promptHint: "with an unbothered, self-possessed expression and a confident, detached calm" },
|
|
80
|
+
{ id: "thoughtful", label: "Thoughtful", category: "neutral", description: "Deep in thought", promptHint: "with a thoughtful, contemplative expression", term: "thoughtful, contemplative expression" },
|
|
81
|
+
{ id: "stoic", label: "Stoic", category: "neutral", description: "Impassive, unreadable", promptHint: "with a stoic, impassive expression revealing nothing", term: "stoic, impassive expression" },
|
|
82
|
+
{ id: "calm", label: "Calm", category: "neutral", description: "Centered, unreactive", promptHint: "with a calm, centered expression", term: "calm expression" },
|
|
83
|
+
{ id: "curious", label: "Curious", category: "neutral", description: "Intrigued, alert", promptHint: "with a curious, intrigued expression and alert eyes", term: "curious expression" },
|
|
84
|
+
{ id: "mysterious", label: "Mysterious", category: "neutral", description: "Inscrutable, enigmatic", promptHint: "with a mysterious, enigmatic expression hard to read", term: "mysterious, enigmatic expression" },
|
|
85
|
+
{ id: "dazed", label: "Dazed", category: "neutral", description: "Dreamy, half-present", promptHint: "with a dazed, dreamy expression, eyes slightly out of focus and only half-present", term: "dazed, dreamy expression" },
|
|
86
|
+
{ id: "sleepy", label: "Sleepy", category: "neutral", description: "Drowsy, heavy-lidded", promptHint: "with a sleepy, drowsy expression, heavy eyelids and a slow, soft blink", term: "sleepy expression" },
|
|
87
|
+
{ id: "unbothered", label: "Unbothered", category: "neutral", description: "Calm self-possession", promptHint: "with an unbothered, self-possessed expression and a confident, detached calm", term: "unbothered, self-possessed calm" },
|
|
76
88
|
|
|
77
89
|
// -------------------- Intense / Dramatic --------------------
|
|
78
|
-
{ id: "fierce", label: "Fierce", category: "intense", description: "Fierce, commanding", promptHint: "with a fierce, commanding expression and blazing intensity" },
|
|
79
|
-
{ id: "determined", label: "Determined", category: "intense", description: "Resolute, focused will", promptHint: "with a determined, resolute expression and iron focus" },
|
|
80
|
-
{ id: "passionate", label: "Passionate", category: "intense", description: "Burning passion", promptHint: "with a passionate, burning expression full of conviction" },
|
|
81
|
-
{ id: "brooding", label: "Brooding", category: "intense", description: "Dark, brooding melancholy", promptHint: "with a brooding, dark expression and moody introspection" },
|
|
82
|
-
{ id: "seductive", label: "Seductive", category: "intense", description: "Alluring, seductive", promptHint: "with a seductive, alluring expression and lidded gaze" },
|
|
83
|
-
{ id: "defiant", label: "Defiant", category: "intense", description: "Defiant, unyielding", promptHint: "with a defiant, unyielding expression and challenging stance" },
|
|
84
|
-
{ id: "sultry", label: "Sultry", category: "intense", description: "Smoldering, heavy-lidded", promptHint: "with a sultry, smoldering expression, heavy-lidded gaze and lips softly parted" },
|
|
85
|
-
{ id: "smoldering", label: "Smoldering", category: "intense", description: "Coiled, slow-burning intensity", promptHint: "with a smoldering, coiled expression, slow-burning intensity behind half-closed eyes and a still, predatory calm" },
|
|
86
|
-
{ id: "sinister", label: "Sinister", category: "intense", description: "Dark, malicious, threatening", promptHint: "with a sinister expression, a slow crooked smile and eyes glinting with dark malicious intent" },
|
|
87
|
-
{ id: "wiccan-mystical", label: "Wiccan / Mystical", category: "intense", description: "Quietly otherworldly, occult", promptHint: "with a quietly mystical, otherworldly expression, eyes distant and knowing as if reading something the camera cannot see" },
|
|
88
|
-
{ id: "lazy-shy", label: "Lazy Shy", category: "neutral", description: "Drowsy, soft, half-shy", promptHint: "with a soft, drowsy half-shy expression, eyes lowered and barely-there smile, languid and unbothered" },
|
|
89
|
-
{ id: "awe", label: "Awe", category: "intense", description: "Wonder, reverent", promptHint: "with an awestruck expression of wonder, mouth slightly agape and wide-eyed" },
|
|
90
|
-
{ id: "shocked", label: "Shocked", category: "intense", description: "Surprised, mouth open", promptHint: "with a shocked, surprised expression, eyes wide, brows raised and mouth open" },
|
|
90
|
+
{ id: "fierce", label: "Fierce", category: "intense", description: "Fierce, commanding", promptHint: "with a fierce, commanding expression and blazing intensity", term: "fierce, commanding intensity" },
|
|
91
|
+
{ id: "determined", label: "Determined", category: "intense", description: "Resolute, focused will", promptHint: "with a determined, resolute expression and iron focus", term: "determined, resolute expression" },
|
|
92
|
+
{ id: "passionate", label: "Passionate", category: "intense", description: "Burning passion", promptHint: "with a passionate, burning expression full of conviction", term: "passionate expression" },
|
|
93
|
+
{ id: "brooding", label: "Brooding", category: "intense", description: "Dark, brooding melancholy", promptHint: "with a brooding, dark expression and moody introspection", term: "brooding expression" },
|
|
94
|
+
{ id: "seductive", label: "Seductive", category: "intense", description: "Alluring, seductive", promptHint: "with a seductive, alluring expression and lidded gaze", term: "seductive expression" },
|
|
95
|
+
{ id: "defiant", label: "Defiant", category: "intense", description: "Defiant, unyielding", promptHint: "with a defiant, unyielding expression and challenging stance", term: "defiant expression" },
|
|
96
|
+
{ id: "sultry", label: "Sultry", category: "intense", description: "Smoldering, heavy-lidded", promptHint: "with a sultry, smoldering expression, heavy-lidded gaze and lips softly parted", term: "sultry expression" },
|
|
97
|
+
{ id: "smoldering", label: "Smoldering", category: "intense", description: "Coiled, slow-burning intensity", promptHint: "with a smoldering, coiled expression, slow-burning intensity behind half-closed eyes and a still, predatory calm", term: "smoldering intensity" },
|
|
98
|
+
{ id: "sinister", label: "Sinister", category: "intense", description: "Dark, malicious, threatening", promptHint: "with a sinister expression, a slow crooked smile and eyes glinting with dark malicious intent", term: "sinister expression" },
|
|
99
|
+
{ id: "wiccan-mystical", label: "Wiccan / Mystical", category: "intense", description: "Quietly otherworldly, occult", promptHint: "with a quietly mystical, otherworldly expression, eyes distant and knowing as if reading something the camera cannot see", term: "occult, otherworldly mystical expression" },
|
|
100
|
+
{ id: "lazy-shy", label: "Lazy Shy", category: "neutral", description: "Drowsy, soft, half-shy", promptHint: "with a soft, drowsy half-shy expression, eyes lowered and barely-there smile, languid and unbothered", term: "drowsy, half-shy expression" },
|
|
101
|
+
{ id: "awe", label: "Awe", category: "intense", description: "Wonder, reverent", promptHint: "with an awestruck expression of wonder, mouth slightly agape and wide-eyed", term: "awestruck wonder" },
|
|
102
|
+
{ id: "shocked", label: "Shocked", category: "intense", description: "Surprised, mouth open", promptHint: "with a shocked, surprised expression, eyes wide, brows raised and mouth open", term: "shocked expression" },
|
|
91
103
|
|
|
92
104
|
// -------------------- Micro-emotions --------------------
|
|
93
|
-
{ id: "flirty", label: "Flirty", category: "positive", description: "Playful flirtation, lingering smile, sustained eye contact", promptHint: "with a flirty expression, a lingering playful smile and sustained, knowing eye contact with the camera" },
|
|
94
|
-
{ id: "suspicious", label: "Suspicious", category: "negative", description: "Wary distrust, narrowed eyes, side-eye", promptHint: "with a suspicious, wary expression, eyes narrowed in distrust and a sidelong side-eye glance" },
|
|
95
|
-
{ id: "resigned", label: "Resigned", category: "neutral", description: "Quiet acceptance of an unpleasant situation, sigh", promptHint: "with a resigned expression of quiet acceptance, shoulders softly dropped mid-sigh and a tired half-closed gaze" },
|
|
96
|
-
{ id: "conflicted", label: "Conflicted", category: "neutral", description: "Visible internal struggle, brow furrowed, gaze unfocused", promptHint: "with a conflicted expression of visible internal struggle, brow furrowed and gaze unfocused, caught between two impulses" },
|
|
105
|
+
{ id: "flirty", label: "Flirty", category: "positive", description: "Playful flirtation, lingering smile, sustained eye contact", promptHint: "with a flirty expression, a lingering playful smile and sustained, knowing eye contact with the camera", term: "flirty expression" },
|
|
106
|
+
{ id: "suspicious", label: "Suspicious", category: "negative", description: "Wary distrust, narrowed eyes, side-eye", promptHint: "with a suspicious, wary expression, eyes narrowed in distrust and a sidelong side-eye glance", term: "suspicious, wary expression" },
|
|
107
|
+
{ id: "resigned", label: "Resigned", category: "neutral", description: "Quiet acceptance of an unpleasant situation, sigh", promptHint: "with a resigned expression of quiet acceptance, shoulders softly dropped mid-sigh and a tired half-closed gaze", term: "resigned expression of quiet acceptance" },
|
|
108
|
+
{ id: "conflicted", label: "Conflicted", category: "neutral", description: "Visible internal struggle, brow furrowed, gaze unfocused", promptHint: "with a conflicted expression of visible internal struggle, brow furrowed and gaze unfocused, caught between two impulses", term: "conflicted, torn expression" },
|
|
97
109
|
] as const
|
|
98
110
|
|
|
99
111
|
const moodById = new Map<string, Mood>(MOODS.map((m) => [m.id, m]))
|
|
@@ -114,6 +126,15 @@ export function getMoodPromptHint(id: string | undefined | null): string {
|
|
|
114
126
|
return getMood(id)?.promptHint ?? ""
|
|
115
127
|
}
|
|
116
128
|
|
|
129
|
+
/**
|
|
130
|
+
* The COMPACT counterpart of `getMoodPromptHint`: the short professional term
|
|
131
|
+
* ("melancholic expression", "cocky smirk") a consumer injects instead of the
|
|
132
|
+
* full expression clause. Same lookup, same empty-string-on-miss behavior.
|
|
133
|
+
*/
|
|
134
|
+
export function getMoodTerm(id: string | undefined | null): string {
|
|
135
|
+
return resolveTerm(getMood(id))
|
|
136
|
+
}
|
|
137
|
+
|
|
117
138
|
export const MOOD_IDS: ReadonlyArray<string> = MOODS.map((m) => m.id)
|
|
118
139
|
|
|
119
140
|
export const MOOD_CATEGORY_LABELS: Readonly<Record<MoodCategory, string>> = {
|
|
@@ -163,14 +184,42 @@ function buildMoodHint(value: unknown): string {
|
|
|
163
184
|
return `with a ${labels[0]} and ${labels[1]} expression`
|
|
164
185
|
}
|
|
165
186
|
|
|
187
|
+
/**
|
|
188
|
+
* Combine 1-2 mood ids into a single COMPACT clause: the entry's short
|
|
189
|
+
* professional term, or the two terms joined with " and " for a mixed mood
|
|
190
|
+
* ("cocky smirk and aloof, detached expression"). The full-mode weave rebuilds
|
|
191
|
+
* the "with a ... expression" template from labels; a term already carries its
|
|
192
|
+
* own grammar, so compact just joins.
|
|
193
|
+
*/
|
|
194
|
+
function buildMoodTerm(value: unknown): string {
|
|
195
|
+
const ids: string[] = []
|
|
196
|
+
if (typeof value === "string" && value) ids.push(value)
|
|
197
|
+
else if (Array.isArray(value)) {
|
|
198
|
+
for (const v of value) {
|
|
199
|
+
if (typeof v === "string" && v && !ids.includes(v)) ids.push(v)
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
const terms = ids
|
|
203
|
+
.slice(0, 2)
|
|
204
|
+
.map((id) => getMoodTerm(id))
|
|
205
|
+
.filter((t) => t.length > 0)
|
|
206
|
+
return terms.join(" and ")
|
|
207
|
+
}
|
|
208
|
+
|
|
166
209
|
/**
|
|
167
210
|
* Build prompt hints from MoodData: optional pre-text, the selected mood's
|
|
168
211
|
* hint (single or mixed), optional post-text. Returns array — caller joins
|
|
169
212
|
* with ", ".
|
|
213
|
+
*
|
|
214
|
+
* @param mode `"compact"` swaps the mood fragment for its short professional
|
|
215
|
+
* term (delegates to `buildMoodTerms`); pre/post free text is unaffected.
|
|
170
216
|
*/
|
|
171
217
|
export function buildMoodHints(
|
|
172
218
|
data: Record<string, unknown> & MoodValue,
|
|
219
|
+
mode: PickerHintMode = "full",
|
|
173
220
|
): string[] {
|
|
221
|
+
if (mode === "compact") return buildMoodTerms(data)
|
|
222
|
+
|
|
174
223
|
const hints: string[] = []
|
|
175
224
|
|
|
176
225
|
const pre = typeof data.preText === "string" ? data.preText.trim() : ""
|
|
@@ -184,3 +233,26 @@ export function buildMoodHints(
|
|
|
184
233
|
|
|
185
234
|
return hints
|
|
186
235
|
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Compact counterpart of `buildMoodHints`: the same pre-text → mood →
|
|
239
|
+
* post-text order, emitting the mood's short professional term ("melancholic
|
|
240
|
+
* expression", "cocky smirk") instead of the full expression clause. Free-text
|
|
241
|
+
* pre/post fields are user prose and pass through unchanged in both modes.
|
|
242
|
+
*/
|
|
243
|
+
export function buildMoodTerms(
|
|
244
|
+
data: Record<string, unknown> & MoodValue,
|
|
245
|
+
): string[] {
|
|
246
|
+
const terms: string[] = []
|
|
247
|
+
|
|
248
|
+
const pre = typeof data.preText === "string" ? data.preText.trim() : ""
|
|
249
|
+
if (pre) terms.push(pre)
|
|
250
|
+
|
|
251
|
+
const moodTerm = buildMoodTerm(data.mood)
|
|
252
|
+
if (moodTerm) terms.push(moodTerm)
|
|
253
|
+
|
|
254
|
+
const post = typeof data.postText === "string" ? data.postText.trim() : ""
|
|
255
|
+
if (post) terms.push(post)
|
|
256
|
+
|
|
257
|
+
return terms
|
|
258
|
+
}
|