calliope-ts 0.0.4 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. package/README.md +69 -3
  2. package/dist/calliope/bracketing.d.ts.map +1 -1
  3. package/dist/calliope/bracketing.js +59 -5
  4. package/dist/calliope/deps.d.ts +5 -1
  5. package/dist/calliope/deps.d.ts.map +1 -1
  6. package/dist/calliope/deps.js +53 -3
  7. package/dist/calliope/engine.d.ts.map +1 -1
  8. package/dist/calliope/engine.js +6 -1
  9. package/dist/calliope/relstress.d.ts.map +1 -1
  10. package/dist/calliope/relstress.js +411 -15
  11. package/dist/calliope/syntax.d.ts +33 -0
  12. package/dist/calliope/syntax.d.ts.map +1 -1
  13. package/dist/calliope/syntax.js +199 -0
  14. package/dist/data/en_common_words.json +1 -0
  15. package/dist/display.d.ts +15 -1
  16. package/dist/display.d.ts.map +1 -1
  17. package/dist/display.js +112 -10
  18. package/dist/fabbhalle.d.ts +54 -0
  19. package/dist/fabbhalle.d.ts.map +1 -0
  20. package/dist/fabbhalle.js +404 -0
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +86 -33
  23. package/dist/phonological.d.ts.map +1 -1
  24. package/dist/phonological.js +7 -1
  25. package/dist/rewriteEn.d.ts +14 -0
  26. package/dist/rewriteEn.d.ts.map +1 -0
  27. package/dist/rewriteEn.js +392 -0
  28. package/dist/rhyme.d.ts +35 -3
  29. package/dist/rhyme.d.ts.map +1 -1
  30. package/dist/rhyme.js +176 -11
  31. package/dist/russian/accentuator.d.ts +31 -0
  32. package/dist/russian/accentuator.d.ts.map +1 -0
  33. package/dist/russian/accentuator.js +546 -0
  34. package/dist/russian/collocations.d.ts +7 -0
  35. package/dist/russian/collocations.d.ts.map +1 -0
  36. package/dist/russian/collocations.js +38 -0
  37. package/dist/russian/compounds.d.ts +6 -0
  38. package/dist/russian/compounds.d.ts.map +1 -0
  39. package/dist/russian/compounds.js +81 -0
  40. package/dist/russian/download.d.ts +23 -0
  41. package/dist/russian/download.d.ts.map +1 -0
  42. package/dist/russian/download.js +117 -0
  43. package/dist/russian/engine.d.ts +6 -0
  44. package/dist/russian/engine.d.ts.map +1 -0
  45. package/dist/russian/engine.js +1424 -0
  46. package/dist/russian/parser.d.ts +8 -0
  47. package/dist/russian/parser.d.ts.map +1 -0
  48. package/dist/russian/parser.js +92 -0
  49. package/dist/russian/paths.d.ts +55 -0
  50. package/dist/russian/paths.d.ts.map +1 -0
  51. package/dist/russian/paths.js +114 -0
  52. package/dist/russian/rewrite.d.ts +6 -0
  53. package/dist/russian/rewrite.d.ts.map +1 -0
  54. package/dist/russian/rewrite.js +400 -0
  55. package/dist/russian/rhyme.d.ts +18 -0
  56. package/dist/russian/rhyme.d.ts.map +1 -0
  57. package/dist/russian/rhyme.js +230 -0
  58. package/dist/russian/syllabifier.d.ts +14 -0
  59. package/dist/russian/syllabifier.d.ts.map +1 -0
  60. package/dist/russian/syllabifier.js +475 -0
  61. package/dist/russian/types.d.ts +94 -0
  62. package/dist/russian/types.d.ts.map +1 -0
  63. package/dist/russian/types.js +27 -0
  64. package/dist/scandroidNative/constants.d.ts +16 -0
  65. package/dist/scandroidNative/constants.d.ts.map +1 -0
  66. package/dist/scandroidNative/constants.js +60 -0
  67. package/dist/scandroidNative/deduceParameters.d.ts +16 -0
  68. package/dist/scandroidNative/deduceParameters.d.ts.map +1 -0
  69. package/dist/scandroidNative/deduceParameters.js +69 -0
  70. package/dist/scandroidNative/dictionary-data.d.ts +2 -0
  71. package/dist/scandroidNative/dictionary-data.d.ts.map +1 -0
  72. package/dist/scandroidNative/dictionary-data.js +744 -0
  73. package/dist/scandroidNative/dictionary.d.ts +12 -0
  74. package/dist/scandroidNative/dictionary.d.ts.map +1 -0
  75. package/dist/scandroidNative/dictionary.js +50 -0
  76. package/dist/scandroidNative/engine.d.ts +41 -0
  77. package/dist/scandroidNative/engine.d.ts.map +1 -0
  78. package/dist/scandroidNative/engine.js +119 -0
  79. package/dist/scandroidNative/machine.d.ts +93 -0
  80. package/dist/scandroidNative/machine.d.ts.map +1 -0
  81. package/dist/scandroidNative/machine.js +795 -0
  82. package/dist/scandroidNative/positioner.d.ts +32 -0
  83. package/dist/scandroidNative/positioner.d.ts.map +1 -0
  84. package/dist/scandroidNative/positioner.js +208 -0
  85. package/dist/scandroidNative/syllabizer.d.ts +3 -0
  86. package/dist/scandroidNative/syllabizer.d.ts.map +1 -0
  87. package/dist/scandroidNative/syllabizer.js +215 -0
  88. package/dist/scandroidNative/utilities.d.ts +37 -0
  89. package/dist/scandroidNative/utilities.d.ts.map +1 -0
  90. package/dist/scandroidNative/utilities.js +86 -0
  91. package/dist/scansion.d.ts.map +1 -1
  92. package/dist/scansion.js +118 -14
  93. package/dist/stress.d.ts +1 -0
  94. package/dist/stress.d.ts.map +1 -1
  95. package/dist/stress.js +502 -42
  96. package/dist/types.d.ts +3 -0
  97. package/dist/types.d.ts.map +1 -1
  98. package/package.json +27 -6
  99. package/tools/fetch-russian-data.mjs +30 -0
  100. package/webapp/public/app.js +2418 -0
  101. package/webapp/public/assets/GithubLogo.png +0 -0
  102. package/webapp/public/assets/NPM2.png +0 -0
  103. package/webapp/public/assets/fonts/MurenaBold-webfont.woff2 +0 -0
  104. package/webapp/public/assets/fonts/MurenaItalic-webfont.woff2 +0 -0
  105. package/webapp/public/assets/fonts/MurenaRegular-webfont.woff2 +0 -0
  106. package/webapp/public/assets/fonts/Myra_4F_Caps_Bold-webfont.woff2 +0 -0
  107. package/webapp/public/assets/fonts/SinkinSans-700Bold.otf +0 -0
  108. package/webapp/public/assets/fonts/butterflies.ttf +0 -0
  109. package/webapp/public/assets/fonts/midcase_blackline-webfont.woff2 +0 -0
  110. package/webapp/public/assets/fonts/neueral-bold-webfont.woff2 +0 -0
  111. package/webapp/public/assets/fonts/neueral-regular-webfont.woff2 +0 -0
  112. package/webapp/public/assets/fonts/popelka-webfont.woff2 +0 -0
  113. package/webapp/public/assets/fonts/vremenagrotesk-webfont.woff +0 -0
  114. package/webapp/public/assets/fonts/wicky_javick_bold-webfont.woff2 +0 -0
  115. package/webapp/public/assets/logos/Logo_Var_10_Celtic_Knot_SVG.svg +116 -0
  116. package/webapp/public/assets/logos/Logo_Var_11_Graph_SVG.svg +313 -0
  117. package/webapp/public/assets/logos/Logo_Var_12_Limacon_Knot_SVG.svg +3942 -0
  118. package/webapp/public/assets/logos/Logo_Var_13_Crescents_SVG.svg +1030 -0
  119. package/webapp/public/assets/logos/Logo_Var_1_Spiral_SVG.svg +1491 -0
  120. package/webapp/public/assets/logos/Logo_Var_2_Tunnel_SVG.svg +12 -0
  121. package/webapp/public/assets/logos/Logo_Var_3_Triskelion_SVG.svg +10 -0
  122. package/webapp/public/assets/logos/Logo_Var_4_Quinquetra_PNG.png +0 -0
  123. package/webapp/public/assets/logos/Logo_Var_5_Penrose_Pentagram_SVG.svg +37 -0
  124. package/webapp/public/assets/logos/Logo_Var_6_Triskelion2_SVG.svg +10 -0
  125. package/webapp/public/assets/logos/Logo_Var_7_SixfoldSpirals_SVG.svg +20 -0
  126. package/webapp/public/assets/logos/Logo_Var_8_Radial_Labyrinth_SVG.svg +163 -0
  127. package/webapp/public/assets/logos/Logo_Var_9_Radial_Labyrinth_2_SVG.svg +106 -0
  128. package/webapp/public/index.html +316 -0
  129. package/webapp/public/styles.css +1114 -0
  130. package/webapp/server.mjs +680 -0
  131. package/src/caesura.ts +0 -201
  132. package/src/calliope/boundaries.ts +0 -190
  133. package/src/calliope/bracketing.ts +0 -390
  134. package/src/calliope/deps.ts +0 -160
  135. package/src/calliope/engine.ts +0 -77
  136. package/src/calliope/feats.ts +0 -46
  137. package/src/calliope/names.ts +0 -44
  138. package/src/calliope/postag.ts +0 -253
  139. package/src/calliope/prosodic.ts +0 -262
  140. package/src/calliope/relstress.ts +0 -645
  141. package/src/calliope/stressrules.ts +0 -147
  142. package/src/calliope/syntax.ts +0 -218
  143. package/src/calliope/udpos.ts +0 -152
  144. package/src/calliope_src_contents.md +0 -19049
  145. package/src/clio/caesura.ts +0 -145
  146. package/src/clio/depfix.ts +0 -88
  147. package/src/clio/display.ts +0 -1042
  148. package/src/clio/engine.ts +0 -38
  149. package/src/clio/parser.ts +0 -845
  150. package/src/clio/phonological.ts +0 -849
  151. package/src/clio/phrasestress.ts +0 -108
  152. package/src/clio/pipeline.ts +0 -154
  153. package/src/clio/rhyme.ts +0 -740
  154. package/src/clio/scandroid.ts +0 -434
  155. package/src/clio/scansion.ts +0 -1130
  156. package/src/clio/semantics.ts +0 -134
  157. package/src/clio/stress.ts +0 -1731
  158. package/src/clio/tagfix.ts +0 -104
  159. package/src/depfix.ts +0 -88
  160. package/src/display.ts +0 -1138
  161. package/src/engine.ts +0 -22
  162. package/src/index.ts +0 -690
  163. package/src/parser.ts +0 -501
  164. package/src/phonological.ts +0 -917
  165. package/src/phrasestress.ts +0 -108
  166. package/src/rhyme.ts +0 -748
  167. package/src/scandroid.ts +0 -434
  168. package/src/scansion.ts +0 -1174
  169. package/src/semantics.ts +0 -134
  170. package/src/stress.ts +0 -2111
  171. package/src/tagfix.ts +0 -104
  172. package/src/types.ts +0 -265
  173. package/tests/DataForHayesLinesOnly.txt +0 -364
  174. package/tests/DataForHayesStressSymbolsRevised.txt +0 -728
  175. package/tests/basic.test.ts +0 -1102
  176. package/tests/bench-hayes.mjs +0 -72
  177. package/tests/epg64.meter.train.txt +0 -8139
  178. package/tests/litlab-sample-2016.txt +0 -1738
  179. package/tests/prosodic.meter.train.txt +0 -13192
  180. package/tests/wagner-stress.test.ts +0 -188
  181. package/tsconfig.json +0 -29
  182. package/vitest.config.d.ts +0 -2
  183. package/vitest.config.js +0 -14
@@ -51,6 +51,205 @@ export function isInherentlyGiven(w) {
51
51
  export function isLightNominalHead(w) {
52
52
  return isPronoun(w) || isInherentlyGiven(w);
53
53
  }
54
+ /** Focus-sensitive particles (Krifka §4.4.6, Association with Focus): a
55
+ * premodifying "just / only / even / merely" marks its sister as the FOCUS —
56
+ * the ASSOCIATE bears the accent, the particle is a functor and reduces
57
+ * ("the carriage held but just OURSELVES": "just" = "only", so the accent
58
+ * belongs to the pronoun it exclusivises). Returns the associate, or null
59
+ * when the word is not a premodifying focus particle. A postmodifying or
60
+ * clause-final "just/only" ("he only just made it") is temporal/degree use
61
+ * and returns null. */
62
+ const FOCUS_PARTICLES = new Set(['just', 'only', 'even', 'merely']);
63
+ export function focusAssociateOf(w, words) {
64
+ if (!FOCUS_PARTICLES.has(bare(w)))
65
+ return null;
66
+ if (!/^RB/.test(w.lexicalClass))
67
+ return null;
68
+ const gov = w.dependency?.governor;
69
+ // canonical case: the particle is an ADVMOD premodifier of its associate
70
+ if (gov && gov !== w && !isPunct(gov) && gov.absoluteIndex > w.absoluteIndex)
71
+ return gov;
72
+ // parse-robust fallback: the particle immediately precedes a pronoun the
73
+ // parser attached elsewhere ("but just Ourselves" with "just" hung on the verb)
74
+ const next = words.find(x => x.absoluteIndex === w.absoluteIndex + 1 && x.syllables.length > 0);
75
+ if (next && (PRON.test(next.lexicalClass) || feat(next, 'PronType') === 'Prs'))
76
+ return next;
77
+ return null;
78
+ }
79
+ /** Marginal-modal use of dare/need (Quirk et al.): the BARE-infinitive
80
+ * complement construction — "dare he aspire", "What the hand dare seize" —
81
+ * is the AUXILIARY usage (the one that licenses subject inversion), so the
82
+ * verb reduces like a modal and the beat belongs to its infinitive. The
83
+ * LEXICAL usage takes a to-infinitive ("dared to aspire") or a nominal
84
+ * object ("dared the leap") and keeps full content stress — the gate is the
85
+ * complement's shape, not the lemma alone. */
86
+ const MARGINAL_MODALS = new Set(['dare', 'dares', 'dared', 'durst', 'need']);
87
+ export function isMarginalModalUse(w, words) {
88
+ if (!MARGINAL_MODALS.has(bare(w)) || !/^VB/.test(w.lexicalClass))
89
+ return false;
90
+ // A clausal-complement child that is a bare verb (no "to" mark below it).
91
+ const comp = words.find(d => d !== w && d.dependency?.governor === w &&
92
+ /^(XCOMP|CCOMP)$/.test(d.canonicalRel ?? '') && /^VB/.test(d.lexicalClass));
93
+ if (comp) {
94
+ const hasTo = words.some(m => m !== comp && m.dependency?.governor === comp &&
95
+ (m.lexicalClass === 'TO' || bare(m) === 'to'));
96
+ return !hasTo;
97
+ }
98
+ // Surface fallback for mis-parses: an immediately-following bare infinitive
99
+ // ("dare seize"), or inverted pronoun subject + bare verb ("dare he aspire").
100
+ const at = (k) => words.find(x => x.absoluteIndex === w.absoluteIndex + k);
101
+ const n1 = at(1);
102
+ if (n1 && n1.lexicalClass === 'VB')
103
+ return true;
104
+ const n2 = at(2);
105
+ if (n1 && n1.lexicalClass === 'PRP' && n2 && /^VBP?$/.test(n2.lexicalClass))
106
+ return true;
107
+ return false;
108
+ }
109
+ /** A CAPITALIZED personal/possessive pronoun in mid-sentence ("but just
110
+ * Ourselves", "For His Civility" — Dickinson's reverential capitals).
111
+ * English capitalizes pronouns only sentence-initially and in "I", so a
112
+ * capital here is the poet's deliberate typographic FOCUS mark: the pronoun
113
+ * is referential/contrastive — Wagner's "functor role" ceded to a full
114
+ * referring use, Krifka (78): an accented pronoun signals narrow focus. */
115
+ export function isCapitalizedFocalPronoun(w, words) {
116
+ if (!PRON.test(w.lexicalClass) && feat(w, 'PronType') !== 'Prs')
117
+ return false;
118
+ if (!/^[A-Z]/.test(w.word))
119
+ return false;
120
+ const lower = bare(w);
121
+ if (lower === 'i' || lower.startsWith('i')) {
122
+ // "I" and its contractions are conventionally capital — no signal there.
123
+ if (lower === 'i' || /^i(ll|m|d|ve)$/.test(lower))
124
+ return false;
125
+ }
126
+ // Conventional capitalization is NOT a focus mark: a pronoun opening a
127
+ // QUOTED sentence ("Who said, "It is just as I feared!"") or following
128
+ // sentence-internal terminal punctuation or a colon is capitalized by
129
+ // orthographic rule, not by the poet's emphasis. Scan back over the
130
+ // punctuation tokens abutting the pronoun; a quote mark or sentence
131
+ // punctuation among them disqualifies. (Dashes and commas do NOT
132
+ // disqualify — Dickinson's mid-clause capitals stand.)
133
+ for (const x of [...words]
134
+ .filter(p => p.absoluteIndex < w.absoluteIndex)
135
+ .sort((a, b) => b.absoluteIndex - a.absoluteIndex)) {
136
+ if (/[A-Za-z]/.test(x.word))
137
+ break; // reached a real word
138
+ if (/["“”'‘’.!?:]/.test(x.word))
139
+ return false; // conventional capital
140
+ }
141
+ // Mid-sentence only: some earlier alphabetic word must exist.
142
+ return words.some(x => x.absoluteIndex < w.absoluteIndex && /[A-Za-z]/.test(x.word));
143
+ }
144
+ /** A POSTPOSED preposition: orphaned from its complement, which stands
145
+ * immediately to its LEFT as a wh-word — the inverted pied-piping of "what
146
+ * FOR is this form" (= "for what"), and the bare "Who WITH?", "Where FROM?".
147
+ * Such a preposition cannot procliticize (no rightward complement to lean on)
148
+ * and takes its STRONG form (Selkirk 1996: function words are weak only where
149
+ * they can cliticize onto a following host) — the same phonology as clause-
150
+ * final stranding, caught here in the wh-adjacent inversion the transitivity
151
+ * test misses. Subordinators never match ("what if…" is a mark, not case),
152
+ * and neither does a preposition with a genuine rightward complement
153
+ * ("who for the WORLD would…", "when in ROME…" stay reduced). */
154
+ export function isPostposedPreposition(w, words) {
155
+ const pos = w.lexicalClass;
156
+ const rel = w.canonicalRel ?? '';
157
+ if (pos !== 'IN' && pos !== 'TO' && rel !== 'CASE')
158
+ return false;
159
+ if (rel === 'COMPMARK' || rel === 'ADVMARK')
160
+ return false;
161
+ const prev = words
162
+ .filter(x => x.syllables.length > 0 && x.absoluteIndex < w.absoluteIndex)
163
+ .sort((a, b) => b.absoluteIndex - a.absoluteIndex)[0];
164
+ if (!prev || prev.absoluteIndex !== w.absoluteIndex - 1)
165
+ return false;
166
+ if (!/^(WDT|WP|WP\$|WRB)$/.test(prev.lexicalClass))
167
+ return false;
168
+ // No genuine rightward complement: neither a following nominal governor (UD
169
+ // attaches the prep as CASE dependent of the noun it precedes) nor a
170
+ // following nominal/pronominal child.
171
+ const gov = w.dependency?.governor;
172
+ if (gov && !isPunct(gov) && (NOUN.test(gov.lexicalClass) || PRON.test(gov.lexicalClass)) &&
173
+ gov.absoluteIndex > w.absoluteIndex)
174
+ return false;
175
+ if (words.some(d => d.dependency?.governor === w &&
176
+ (NOUN.test(d.lexicalClass) || PRON.test(d.lexicalClass)) &&
177
+ d.absoluteIndex > w.absoluteIndex))
178
+ return false;
179
+ return true;
180
+ }
181
+ /** Subject–auxiliary INVERSION without interrogative force: the aux/modal
182
+ * precedes its clause's subject in a sentence that is NOT a question —
183
+ * optative "So, may then each moment drip off…" / "May she rest", negative
184
+ * inversion "Never did I see", conditional inversion "Had I known". The
185
+ * inverted auxiliary is the overt exponent of the operator that triggered the
186
+ * inversion (wish / negation / condition — Krifka: illocutionary and polarity
187
+ * operators are accentable focus exponents), so it is NOT the reduced given-
188
+ * auxiliary of a plain declarative: it anchors a light beat ("HAD I but
189
+ * known", "never DID I see"). In a QUESTION the inversion is discharged by
190
+ * the interrogative operator instead (wh-word or final "?") and the aux stays
191
+ * reduced ("won't you GUIDE me…?", "do I have to BLESS?"). */
192
+ export function isInvertedOperatorAux(w, words) {
193
+ const rel = w.canonicalRel ?? '';
194
+ if (rel !== 'AUX' && rel !== 'AUXPASS' && w.lexicalClass !== 'MD')
195
+ return false;
196
+ if (!/^(MD|VB)/.test(w.lexicalClass))
197
+ return false;
198
+ const head = w.dependency?.governor;
199
+ if (!head || head === w || isPunct(head))
200
+ return false;
201
+ const subj = words.find(d => d.dependency?.governor === head &&
202
+ /^(NSUBJ|NSUBJPASS)$/.test(d.canonicalRel ?? ''));
203
+ if (!subj || subj.absoluteIndex < w.absoluteIndex)
204
+ return false; // normal order / imperative
205
+ if (words.some(x => x.word.includes('?')))
206
+ return false; // overt question
207
+ const firstAlpha = words
208
+ .filter(x => /[A-Za-z]/.test(x.word))
209
+ .sort((a, b) => a.absoluteIndex - b.absoluteIndex)[0];
210
+ // A wh-fronted clause is interrogative even when verse carries the "?" on a
211
+ // later line.
212
+ if (firstAlpha && /^(WDT|WP|WP\$|WRB)$/.test(firstAlpha.lexicalClass))
213
+ return false;
214
+ return true;
215
+ }
216
+ /** Semi-modal "have to" (necessity): have/has/had governing a TO-infinitive
217
+ * open complement with no intervening object — "do I have to bless", "we had
218
+ * to laugh". This is the reduced ("hafta") functor use: under broad focus
219
+ * the whole chain subordinates and the beat belongs to the infinitive (or
220
+ * falls to the subject by alternation). The LEXICAL uses keep full content
221
+ * stress and never match: possession with a purpose infinitive ("I have
222
+ * BOOKS to read" — the object intervenes, the infinitive is ACL on the
223
+ * noun), causative ("have him CALL me" — bare infinitive), existential /
224
+ * plain possession ("what do I HAVE here" — no infinitive at all). A
225
+ * narrow/verum focus on the necessity itself ("Who do I HAVE to bless?") is
226
+ * a marked reading that needs a cue the text must supply — an all-caps HAVE
227
+ * is honored as that typographic cue. */
228
+ const HAVE_FORMS = new Set(['have', 'has', 'had', 'hath', 'having']);
229
+ export function isSemiModalHaveTo(w, words) {
230
+ if (!HAVE_FORMS.has(bare(w)) || !/^VB/.test(w.lexicalClass))
231
+ return false;
232
+ if (/^[A-Z]{2,}$/.test(w.word))
233
+ return false; // typographic narrow focus
234
+ const kids = words.filter(d => d !== w && d.dependency?.governor === w);
235
+ if (kids.some(d => /^(DOBJ|OBJ|IOBJ)$/.test(d.canonicalRel ?? '')))
236
+ return false;
237
+ const comp = kids.find(d => /^(XCOMP|CCOMP)$/.test(d.canonicalRel ?? '') &&
238
+ /^VB/.test(d.lexicalClass));
239
+ if (comp) {
240
+ const hasTo = words.some(m => m !== comp && m.dependency?.governor === comp &&
241
+ (m.lexicalClass === 'TO' || bare(m) === 'to'));
242
+ if (hasTo)
243
+ return true;
244
+ }
245
+ // Parse-robust surface fallback: have + "to" + verb, immediately adjacent.
246
+ const n1 = words.find(x => x.absoluteIndex === w.absoluteIndex + 1);
247
+ const n2 = words.find(x => x.absoluteIndex === w.absoluteIndex + 2);
248
+ if (n1 && (n1.lexicalClass === 'TO' || bare(n1) === 'to') &&
249
+ n2 && /^VB/.test(n2.lexicalClass))
250
+ return true;
251
+ return false;
252
+ }
54
253
  /** A child relation that makes a verb BRANCH (carry an internal argument) — the
55
254
  * specifier-restriction trigger (Wagner §6.3.2): a transitive/clausal VP whose
56
255
  * branchingness blocks subordination of its subject. */