layoutbridge-spm 0.0.1 → 1.0.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/CHANGELOG.md +171 -0
- package/LICENSE +26 -0
- package/README.de.md +318 -0
- package/README.md +304 -4
- package/THIRD-PARTY-NOTICES.md +2878 -0
- package/dist/src/mcp/config.js +125 -0
- package/dist/src/mcp/dispatch.js +123 -0
- package/dist/src/mcp/license/free-tools.js +16 -0
- package/dist/src/mcp/license/gate.js +209 -0
- package/dist/src/mcp/license/index.js +96 -0
- package/dist/src/mcp/license/instance-name.js +56 -0
- package/dist/src/mcp/license/key-source.js +58 -0
- package/dist/src/mcp/license/lemonsqueezy-verifier.js +207 -0
- package/dist/src/mcp/license/placeholder-verifier.js +10 -0
- package/dist/src/mcp/license/polar-ids.js +63 -0
- package/dist/src/mcp/license/polar-verifier.js +265 -0
- package/dist/src/mcp/license/product-ids.js +72 -0
- package/dist/src/mcp/license/state-store.js +91 -0
- package/dist/src/mcp/license/types.js +11 -0
- package/dist/src/mcp/logging.js +270 -0
- package/dist/src/mcp/product-info.js +48 -0
- package/dist/src/mcp/server.js +250 -0
- package/dist/src/mcp/setup.js +608 -0
- package/dist/src/mcp/start.cjs +95 -0
- package/dist/src/mcp/tool-definition.js +2 -0
- package/dist/src/mcp/tools.js +2004 -0
- package/dist/src/mcp/typography-rules.js +70 -0
- package/dist/src/transport/com.js +250 -0
- package/dist/src/transport/osascript.js +171 -0
- package/dist/src/transport/queue.js +19 -0
- package/dist/src/transport/script-bundle.js +92 -0
- package/dist/src/transport/transport.js +30 -0
- package/indesign/commands/10-app.js +6 -0
- package/indesign/commands/20-documents.js +513 -0
- package/indesign/commands/22-document-setup.js +118 -0
- package/indesign/commands/23-save-package.js +255 -0
- package/indesign/commands/25-export.js +379 -0
- package/indesign/commands/26-export-image.js +197 -0
- package/indesign/commands/27-textdefaults.js +151 -0
- package/indesign/commands/28-selection.js +174 -0
- package/indesign/commands/30-pages.js +1032 -0
- package/indesign/commands/31-view.js +210 -0
- package/indesign/commands/32-sections.js +203 -0
- package/indesign/commands/35-parents.js +428 -0
- package/indesign/commands/37-layout.js +760 -0
- package/indesign/commands/40-frames.js +836 -0
- package/indesign/commands/41-shapes.js +505 -0
- package/indesign/commands/42-groups.js +117 -0
- package/indesign/commands/43-layers.js +291 -0
- package/indesign/commands/44-effects.js +274 -0
- package/indesign/commands/45-frame-options.js +247 -0
- package/indesign/commands/47-anchored.js +287 -0
- package/indesign/commands/50-modify.js +781 -0
- package/indesign/commands/52-align.js +139 -0
- package/indesign/commands/55-fit.js +106 -0
- package/indesign/commands/60-images.js +771 -0
- package/indesign/commands/62-embed.js +120 -0
- package/indesign/commands/69-placeholders.js +127 -0
- package/indesign/commands/70-text.js +567 -0
- package/indesign/commands/71-outlines.js +92 -0
- package/indesign/commands/72-place-text.js +366 -0
- package/indesign/commands/74-stories.js +116 -0
- package/indesign/commands/75-tables.js +676 -0
- package/indesign/commands/76-text-variables.js +260 -0
- package/indesign/commands/77-story-options.js +86 -0
- package/indesign/commands/78-frame-lines.js +304 -0
- package/indesign/commands/79-check-typography.js +303 -0
- package/indesign/commands/80-styles.js +1620 -0
- package/indesign/commands/81-composition.js +355 -0
- package/indesign/commands/82-object-styles.js +263 -0
- package/indesign/commands/83-indents-tabs.js +237 -0
- package/indesign/commands/84-import-styles.js +142 -0
- package/indesign/commands/85-swatches.js +112 -0
- package/indesign/commands/86-gradients.js +185 -0
- package/indesign/commands/87-replace-swatch.js +180 -0
- package/indesign/commands/88-replace-font.js +217 -0
- package/indesign/interpreter.js +758 -0
- package/package.json +55 -6
- package/rules/typography-rules.json +31 -0
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Auftrag A-7.6 (Sitzung 9) – check_typography: Verstoesse gegen allgemeine
|
|
3
|
+
* Satzregeln finden und melden, nie aendern. Die Regeln kommen als Daten
|
|
4
|
+
* (args.rule_rows, aus rules/typography-rules.json, vom Server nach Sprache
|
|
5
|
+
* und Kennungen ausgewaehlt): kind grep = InDesign-GREP-Suche (Mechanik
|
|
6
|
+
* von find_replace dry_run), kind lines = Pruefung auf den Zeilen eines
|
|
7
|
+
* Rahmens (idcFrameLineData aus 78-frame-lines.js).
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
var IDC_SEVERITY_RANK = { info: 0, warning: 1, error: 2 };
|
|
11
|
+
|
|
12
|
+
function idcRuleIdsOf(rows) {
|
|
13
|
+
var ids = [], i;
|
|
14
|
+
for (i = 0; i < rows.length; i++) {
|
|
15
|
+
if (!idcInList(ids, rows[i].id)) { ids.push(rows[i].id); }
|
|
16
|
+
}
|
|
17
|
+
return ids;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function idcInList(list, value) {
|
|
21
|
+
var i;
|
|
22
|
+
for (i = 0; i < list.length; i++) { if (list[i] === value) { return true; } }
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/* Textrahmen des Pruefbereichs: Dokumentseiten (und auf Wunsch Musterseiten), ohne gesperrte Ebenen (auf Wunsch mit). */
|
|
27
|
+
function idcFramesInScope(doc, scope, frame, story, includeMasters, includeLocked) {
|
|
28
|
+
var out = [], i, items, item, layer, locked;
|
|
29
|
+
if (scope === 'frame') { return [frame]; }
|
|
30
|
+
if (scope === 'story') {
|
|
31
|
+
try {
|
|
32
|
+
items = story.textContainers;
|
|
33
|
+
for (i = 0; i < items.length; i++) { out.push(IDC.concrete(items[i])); }
|
|
34
|
+
} catch (e0) { out = [frame]; }
|
|
35
|
+
return out;
|
|
36
|
+
}
|
|
37
|
+
try { items = doc.allPageItems; } catch (e1) { items = []; }
|
|
38
|
+
for (i = 0; i < items.length; i++) {
|
|
39
|
+
item = IDC.concrete(items[i]);
|
|
40
|
+
if (!IDC.isTextFrame(item)) { continue; }
|
|
41
|
+
if (!includeMasters && IDC.isOnParentSpread(item)) { continue; }
|
|
42
|
+
if (!includeLocked) {
|
|
43
|
+
locked = false;
|
|
44
|
+
try { layer = item.itemLayer; locked = layer !== null && layer !== undefined && layer.locked === true; } catch (e2) { locked = false; }
|
|
45
|
+
if (locked) { continue; }
|
|
46
|
+
}
|
|
47
|
+
out.push(item);
|
|
48
|
+
}
|
|
49
|
+
return out;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/* Fundstelle einer GREP-Suche als Finding. */
|
|
53
|
+
function idcGrepFinding(doc, rule, match) {
|
|
54
|
+
var entry = idcDescribeMatch(doc, match);
|
|
55
|
+
var story = null, storyLength = null, from, to, snippet = entry.text, contextText;
|
|
56
|
+
var length = 0;
|
|
57
|
+
try { length = Number(match.characters.length); } catch (e0) { length = entry.text === null ? 0 : entry.text.length; }
|
|
58
|
+
try { story = match.parentStory; storyLength = Number(story.characters.length); } catch (e1) { story = null; }
|
|
59
|
+
if (story !== null && entry.index !== null && storyLength !== null) {
|
|
60
|
+
from = Math.max(0, entry.index - 15);
|
|
61
|
+
to = Math.min(storyLength - 1, entry.index + length + 14);
|
|
62
|
+
try {
|
|
63
|
+
contextText = String(story.characters.itemByRange(from, to).contents);
|
|
64
|
+
snippet = contextText.replace(/[\r\n]/g, '\u00b6');
|
|
65
|
+
} catch (e2) { snippet = entry.text; }
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
rule_id: rule.id,
|
|
69
|
+
severity: rule.severity,
|
|
70
|
+
category: rule.category,
|
|
71
|
+
message: rule.message,
|
|
72
|
+
story_id: entry.story_id,
|
|
73
|
+
frame_id: entry.frame_id,
|
|
74
|
+
page_id: entry.page_id,
|
|
75
|
+
page_name: entry.page_name,
|
|
76
|
+
start_index: entry.index,
|
|
77
|
+
end_index: entry.index === null ? null : entry.index + length,
|
|
78
|
+
snippet: snippet,
|
|
79
|
+
suggestion: rule.suggestion
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function idcMatchInTable(match) {
|
|
84
|
+
var parent = null, name;
|
|
85
|
+
try { parent = match.parent; } catch (e0) { return false; }
|
|
86
|
+
if (parent === null || parent === undefined) { return false; }
|
|
87
|
+
name = IDC.className(parent);
|
|
88
|
+
return name === 'Cell' || name === 'Table';
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function idcRunGrepRule(doc, target, rule, args, findings, state) {
|
|
92
|
+
var found, i, options = app.findChangeGrepOptions;
|
|
93
|
+
try {
|
|
94
|
+
app.findGrepPreferences = NothingEnum.NOTHING;
|
|
95
|
+
app.changeGrepPreferences = NothingEnum.NOTHING;
|
|
96
|
+
idcSetFindOptions(options, { include_master_pages: args.include_master_pages === true, include_locked_layers: args.include_locked_layers === true });
|
|
97
|
+
app.findGrepPreferences.findWhat = rule.pattern;
|
|
98
|
+
found = target.findGrep();
|
|
99
|
+
} catch (e) {
|
|
100
|
+
state.failed.push({ rule_id: rule.id, error: String(e.message ? e.message : e), pattern: rule.pattern });
|
|
101
|
+
try { app.findGrepPreferences = NothingEnum.NOTHING; } catch (e1) { /* egal */ }
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
try { app.findGrepPreferences = NothingEnum.NOTHING; } catch (e2) { /* egal */ }
|
|
105
|
+
for (i = 0; i < found.length; i++) {
|
|
106
|
+
if (idcMatchInTable(found[i])) { state.tables_skipped += 1; continue; }
|
|
107
|
+
idcPush(findings, state, idcGrepFinding(doc, rule, found[i]));
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function idcLineFinding(rule, data, column, line, extraMessage) {
|
|
112
|
+
return {
|
|
113
|
+
rule_id: rule.id,
|
|
114
|
+
severity: rule.severity,
|
|
115
|
+
category: rule.category,
|
|
116
|
+
message: extraMessage ? rule.message + ' – ' + extraMessage : rule.message,
|
|
117
|
+
story_id: data.story_id,
|
|
118
|
+
frame_id: data.frame_id,
|
|
119
|
+
page_id: data.page_id,
|
|
120
|
+
page_name: data.page_name,
|
|
121
|
+
start_index: line === null ? null : line.start_index,
|
|
122
|
+
end_index: line === null ? null : line.end_index,
|
|
123
|
+
snippet: line === null ? null : (line.text === undefined ? null : line.text),
|
|
124
|
+
suggestion: rule.suggestion,
|
|
125
|
+
column_index: column === null ? null : column.column_index,
|
|
126
|
+
line_index: line === null ? null : line.index
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/* Alle Regeln laufen immer; der Deckel max_findings greift erst bei der Ausgabe.
|
|
131
|
+
Gesammelt wird bis zur festen Obergrenze IDC_FINDINGS_CEILING, damit ein
|
|
132
|
+
grosses Dokument den Aufruf nicht sprengt (zaehlt weiter als dropped). */
|
|
133
|
+
var IDC_FINDINGS_CEILING = 5000;
|
|
134
|
+
|
|
135
|
+
function idcPush(findings, state, finding) {
|
|
136
|
+
if (findings.length >= IDC_FINDINGS_CEILING) { state.dropped += 1; return; }
|
|
137
|
+
findings.push(finding);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function idcRunLineRule(rule, data, args, findings, state) {
|
|
141
|
+
var c, column, lines, i, run, runStart, maxHyphens, minChars, first, last, text, prev;
|
|
142
|
+
maxHyphens = idcGiven(args.max_consecutive_hyphens) ? args.max_consecutive_hyphens : 3;
|
|
143
|
+
minChars = idcGiven(args.min_last_line_chars) ? args.min_last_line_chars : 0;
|
|
144
|
+
|
|
145
|
+
if (rule.check === 'column_first_baselines_differ') {
|
|
146
|
+
prev = null;
|
|
147
|
+
for (c = 0; c < data.columns.length; c++) {
|
|
148
|
+
column = data.columns[c];
|
|
149
|
+
if (column.line_count === 0 || column.first_baseline_mm === null) { continue; }
|
|
150
|
+
if (prev !== null && Math.abs(column.first_baseline_mm - prev.first_baseline_mm) > 0.1) {
|
|
151
|
+
idcPush(findings, state, idcLineFinding(rule, data, column, column.lines[0],
|
|
152
|
+
'column ' + prev.column_index + ' starts at ' + prev.first_baseline_mm + ' mm, column ' + column.column_index + ' at ' + column.first_baseline_mm + ' mm'));
|
|
153
|
+
}
|
|
154
|
+
prev = column;
|
|
155
|
+
}
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
for (c = 0; c < data.columns.length; c++) {
|
|
160
|
+
column = data.columns[c];
|
|
161
|
+
lines = column.lines;
|
|
162
|
+
if (lines.length === 0) { continue; }
|
|
163
|
+
first = lines[0];
|
|
164
|
+
last = lines[lines.length - 1];
|
|
165
|
+
if (rule.check === 'widow') {
|
|
166
|
+
if (column.starts_with_last_line_of_paragraph) { idcPush(findings, state, idcLineFinding(rule, data, column, first, null)); }
|
|
167
|
+
} else if (rule.check === 'orphan') {
|
|
168
|
+
if (column.ends_with_first_line_of_paragraph) { idcPush(findings, state, idcLineFinding(rule, data, column, last, null)); }
|
|
169
|
+
} else if (rule.check === 'heading_at_column_end') {
|
|
170
|
+
if (last.is_first_line_of_paragraph && last.is_last_line_of_paragraph && !last.is_empty
|
|
171
|
+
&& last.paragraph_index !== null && last.paragraph_index < data.paragraph_count - 1) {
|
|
172
|
+
idcPush(findings, state, idcLineFinding(rule, data, column, last, null));
|
|
173
|
+
}
|
|
174
|
+
} else if (rule.check === 'empty_line_at_column_start') {
|
|
175
|
+
if (column.starts_with_empty_line) { idcPush(findings, state, idcLineFinding(rule, data, column, first, null)); }
|
|
176
|
+
} else if (rule.check === 'single_word_last_line') {
|
|
177
|
+
for (i = 0; i < lines.length; i++) {
|
|
178
|
+
if (!lines[i].is_last_line_of_paragraph || lines[i].is_empty || lines[i].paragraph_line_count === null || lines[i].paragraph_line_count < 2) { continue; }
|
|
179
|
+
text = lines[i].text === undefined ? '' : lines[i].text;
|
|
180
|
+
if (lines[i].word_count === 1 || (minChars > 0 && text.length < minChars)) {
|
|
181
|
+
idcPush(findings, state, idcLineFinding(rule, data, column, lines[i], lines[i].word_count === 1 ? 'single word' : text.length + ' characters'));
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
} else if (rule.check === 'hyphen_ladder') {
|
|
185
|
+
run = 0;
|
|
186
|
+
runStart = 0;
|
|
187
|
+
for (i = 0; i <= lines.length; i++) {
|
|
188
|
+
if (i < lines.length && lines[i].ends_with_hyphen) {
|
|
189
|
+
if (run === 0) { runStart = i; }
|
|
190
|
+
run += 1;
|
|
191
|
+
} else {
|
|
192
|
+
if (run > maxHyphens) {
|
|
193
|
+
idcPush(findings, state, idcLineFinding(rule, data, column, lines[runStart], run + ' hyphenated lines in a row (lines ' + runStart + '–' + (i - 1) + ')'));
|
|
194
|
+
}
|
|
195
|
+
run = 0;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
IDC.register('check_typography', { needs_document: true, read_only: true, ruler: 'spread' },
|
|
203
|
+
function (ctx) {
|
|
204
|
+
var args = ctx.args;
|
|
205
|
+
var doc = ctx.doc;
|
|
206
|
+
var scope = idcGiven(args.scope) ? String(args.scope) : 'document';
|
|
207
|
+
var rows = IDC.isArray(args.rule_rows) ? args.rule_rows : [];
|
|
208
|
+
var unknown = IDC.isArray(args.unknown_rule_ids) ? args.unknown_rule_ids : [];
|
|
209
|
+
var maxFindings = idcGiven(args.max_findings) ? args.max_findings : 500;
|
|
210
|
+
var severityMin = idcGiven(args.severity_min) ? String(args.severity_min) : 'info';
|
|
211
|
+
var frame = null, story = null, frames, target, i, r, rule, findings = [], state, counts = {}, out, kept = [], data, framesChecked = 0;
|
|
212
|
+
var grepRules = [], lineRules = [];
|
|
213
|
+
|
|
214
|
+
if (scope !== 'document' && scope !== 'frame' && scope !== 'story') {
|
|
215
|
+
IDC.fail('invalid_argument', 'scope must be document, frame or story.', { scope: scope });
|
|
216
|
+
}
|
|
217
|
+
if (unknown.length > 0) {
|
|
218
|
+
IDC.fail('invalid_argument', 'Unknown rule id(s): ' + unknown.join(', ') + '.', { unknown: unknown, available: idcRuleIdsOf(rows) });
|
|
219
|
+
}
|
|
220
|
+
if (typeof maxFindings !== 'number' || maxFindings < 1 || maxFindings > 2000 || Math.floor(maxFindings) !== maxFindings) {
|
|
221
|
+
IDC.fail('invalid_argument', 'max_findings must be a whole number between 1 and 2000.', { max_findings: args.max_findings });
|
|
222
|
+
}
|
|
223
|
+
if (!IDC.hasOwn(IDC_SEVERITY_RANK, severityMin)) {
|
|
224
|
+
IDC.fail('invalid_argument', 'severity_min must be info, warning or error.', { severity_min: severityMin });
|
|
225
|
+
}
|
|
226
|
+
if (scope !== 'document') {
|
|
227
|
+
frame = idcTextFrameArg(doc, args, 'frame_id').item;
|
|
228
|
+
story = idcStoryOf(frame);
|
|
229
|
+
}
|
|
230
|
+
if (rows.length === 0) {
|
|
231
|
+
ctx.warn('No rule selected for locale ' + (idcGiven(args.locale) ? args.locale : 'de') + '; nothing was checked.');
|
|
232
|
+
}
|
|
233
|
+
for (r = 0; r < rows.length; r++) {
|
|
234
|
+
if (rows[r].kind === 'grep') { grepRules.push(rows[r]); }
|
|
235
|
+
else if (rows[r].kind === 'lines') { lineRules.push(rows[r]); }
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
state = { max: maxFindings, truncated: false, failed: [], tables_skipped: 0, dropped: 0 };
|
|
239
|
+
|
|
240
|
+
/* Zeichenregeln: eine GREP-Suche je Regel ueber das Ziel. */
|
|
241
|
+
if (grepRules.length > 0) {
|
|
242
|
+
if (scope === 'document') { target = doc; }
|
|
243
|
+
else if (scope === 'story') { target = story; }
|
|
244
|
+
else {
|
|
245
|
+
try { target = frame.texts.item(0); } catch (e0) { target = null; }
|
|
246
|
+
if (target === null || target === undefined) { target = story; }
|
|
247
|
+
}
|
|
248
|
+
for (r = 0; r < grepRules.length; r++) {
|
|
249
|
+
idcRunGrepRule(doc, target, grepRules[r], args, findings, state);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/* Umbruchregeln: je Rahmen die Zeilen lesen, dann jede Regel darauf. */
|
|
254
|
+
if (lineRules.length > 0) {
|
|
255
|
+
frames = idcFramesInScope(doc, scope, frame, story, args.include_master_pages === true, args.include_locked_layers === true);
|
|
256
|
+
for (i = 0; i < frames.length; i++) {
|
|
257
|
+
var frameStory;
|
|
258
|
+
try { frameStory = frames[i].parentStory; } catch (e1) { continue; }
|
|
259
|
+
if (frameStory === null || frameStory === undefined) { continue; }
|
|
260
|
+
data = idcFrameLineData(doc, frames[i], frameStory, true, 5000, null);
|
|
261
|
+
framesChecked += 1;
|
|
262
|
+
for (r = 0; r < lineRules.length; r++) {
|
|
263
|
+
idcRunLineRule(lineRules[r], data, args, findings, state);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/* Schwere filtern, zaehlen (counts zaehlt alles), dann erst den Deckel anlegen. */
|
|
269
|
+
for (i = 0; i < findings.length; i++) {
|
|
270
|
+
if (IDC_SEVERITY_RANK[findings[i].severity] < IDC_SEVERITY_RANK[severityMin]) { continue; }
|
|
271
|
+
counts[findings[i].rule_id] = (counts[findings[i].rule_id] || 0) + 1;
|
|
272
|
+
if (kept.length >= maxFindings) { state.dropped += 1; continue; }
|
|
273
|
+
kept.push(findings[i]);
|
|
274
|
+
}
|
|
275
|
+
if (state.dropped > 0) { state.truncated = true; }
|
|
276
|
+
for (r = 0; r < state.failed.length; r++) {
|
|
277
|
+
ctx.warn('Rule ' + state.failed[r].rule_id + ' could not run – InDesign rejected the GREP pattern: ' + state.failed[r].error);
|
|
278
|
+
}
|
|
279
|
+
if (state.tables_skipped > 0) {
|
|
280
|
+
ctx.warn('tables_skipped: ' + state.tables_skipped + ' match(es) inside tables were not reported (table cells are not checked in this version).');
|
|
281
|
+
}
|
|
282
|
+
if (state.truncated) {
|
|
283
|
+
ctx.warn('Output cut at max_findings ' + maxFindings + ': ' + state.dropped + ' further finding(s) not listed (truncated true). All rules were run; counts is complete.');
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
out = {
|
|
287
|
+
scope: scope,
|
|
288
|
+
locale: idcGiven(args.locale) ? String(args.locale) : 'de',
|
|
289
|
+
frame_id: frame === null ? null : Number(frame.id),
|
|
290
|
+
story_id: story === null ? null : Number(story.id),
|
|
291
|
+
findings: kept,
|
|
292
|
+
finding_count: kept.length,
|
|
293
|
+
findings_dropped: state.dropped,
|
|
294
|
+
counts: counts,
|
|
295
|
+
rules_checked: idcRuleIdsOf(rows),
|
|
296
|
+
rules_failed: state.failed,
|
|
297
|
+
frames_checked: framesChecked,
|
|
298
|
+
tables_skipped: state.tables_skipped,
|
|
299
|
+
severity_min: severityMin,
|
|
300
|
+
truncated: state.truncated
|
|
301
|
+
};
|
|
302
|
+
return out;
|
|
303
|
+
});
|