@jjlmoya/utils-forensic-science 1.1.0 → 1.3.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 (46) hide show
  1. package/package.json +3 -2
  2. package/src/category/i18n/de.ts +15 -15
  3. package/src/category/i18n/en.ts +15 -15
  4. package/src/category/i18n/es.ts +16 -16
  5. package/src/category/i18n/fr.ts +15 -15
  6. package/src/category/i18n/id.ts +17 -17
  7. package/src/category/i18n/it.ts +18 -18
  8. package/src/category/i18n/ja.ts +15 -16
  9. package/src/category/i18n/ko.ts +16 -17
  10. package/src/category/i18n/nl.ts +17 -17
  11. package/src/category/i18n/pl.ts +18 -18
  12. package/src/category/i18n/pt.ts +17 -17
  13. package/src/category/i18n/ru.ts +18 -18
  14. package/src/category/i18n/sv.ts +18 -18
  15. package/src/category/i18n/tr.ts +18 -18
  16. package/src/category/i18n/zh.ts +17 -18
  17. package/src/category/index.ts +3 -1
  18. package/src/entries.ts +5 -1
  19. package/src/index.ts +1 -0
  20. package/src/tests/locale_completeness.test.ts +2 -2
  21. package/src/tests/tool_validation.test.ts +2 -2
  22. package/src/tool/bloodstain-pattern-origin-analyzer/bibliography.astro +9 -0
  23. package/src/tool/bloodstain-pattern-origin-analyzer/bibliography.ts +7 -0
  24. package/src/tool/bloodstain-pattern-origin-analyzer/bloodstain-pattern-origin-analyzer.css +438 -0
  25. package/src/tool/bloodstain-pattern-origin-analyzer/component.astro +558 -0
  26. package/src/tool/bloodstain-pattern-origin-analyzer/entry.ts +32 -0
  27. package/src/tool/bloodstain-pattern-origin-analyzer/i18n/de.ts +119 -0
  28. package/src/tool/bloodstain-pattern-origin-analyzer/i18n/en.ts +119 -0
  29. package/src/tool/bloodstain-pattern-origin-analyzer/i18n/es.ts +119 -0
  30. package/src/tool/bloodstain-pattern-origin-analyzer/i18n/fr.ts +119 -0
  31. package/src/tool/bloodstain-pattern-origin-analyzer/i18n/id.ts +119 -0
  32. package/src/tool/bloodstain-pattern-origin-analyzer/i18n/it.ts +119 -0
  33. package/src/tool/bloodstain-pattern-origin-analyzer/i18n/ja.ts +119 -0
  34. package/src/tool/bloodstain-pattern-origin-analyzer/i18n/ko.ts +119 -0
  35. package/src/tool/bloodstain-pattern-origin-analyzer/i18n/nl.ts +119 -0
  36. package/src/tool/bloodstain-pattern-origin-analyzer/i18n/pl.ts +119 -0
  37. package/src/tool/bloodstain-pattern-origin-analyzer/i18n/pt.ts +119 -0
  38. package/src/tool/bloodstain-pattern-origin-analyzer/i18n/ru.ts +119 -0
  39. package/src/tool/bloodstain-pattern-origin-analyzer/i18n/sv.ts +119 -0
  40. package/src/tool/bloodstain-pattern-origin-analyzer/i18n/tr.ts +119 -0
  41. package/src/tool/bloodstain-pattern-origin-analyzer/i18n/zh.ts +119 -0
  42. package/src/tool/bloodstain-pattern-origin-analyzer/index.ts +11 -0
  43. package/src/tool/bloodstain-pattern-origin-analyzer/logic.test.ts +23 -0
  44. package/src/tool/bloodstain-pattern-origin-analyzer/logic.ts +137 -0
  45. package/src/tool/bloodstain-pattern-origin-analyzer/seo.astro +10 -0
  46. package/src/tools.ts +3 -1
@@ -0,0 +1,438 @@
1
+ .bpa-shell {
2
+ --bpa-ink: #32151c;
3
+ --bpa-muted: #78525a;
4
+ --bpa-line: rgba(94, 28, 43, 0.16);
5
+ --bpa-panel: #fff6f1;
6
+ --bpa-panel-strong: #fff;
7
+ --bpa-red: #b3203f;
8
+ --bpa-red-soft: rgba(179, 32, 63, 0.1);
9
+ --bpa-gold: #d89d2b;
10
+ --bpa-teal: #18b79d;
11
+
12
+ display: grid;
13
+ gap: 1rem;
14
+ width: 100%;
15
+ color: var(--bpa-ink);
16
+ }
17
+
18
+ .theme-dark .bpa-shell {
19
+ --bpa-ink: #f4f7fb;
20
+ --bpa-muted: #a8b1bf;
21
+ --bpa-line: rgba(226, 232, 240, 0.14);
22
+ --bpa-panel: #111418;
23
+ --bpa-panel-strong: #171b21;
24
+ --bpa-red-soft: rgba(255, 74, 112, 0.16);
25
+ }
26
+
27
+ .theme-dark .bpa-card {
28
+ background:
29
+ linear-gradient(135deg, rgba(255,255,255,.035), transparent 34%),
30
+ var(--bpa-panel);
31
+ box-shadow: 0 24px 70px rgba(0, 0, 0, 0.34);
32
+ }
33
+
34
+ .bpa-card {
35
+ display: grid;
36
+ gap: 0.85rem;
37
+ width: 100%;
38
+ padding: clamp(0.75rem, 1.8vw, 1rem);
39
+ border: 1px solid var(--bpa-line);
40
+ border-radius: 8px;
41
+ background:
42
+ linear-gradient(135deg, rgba(255,255,255,.64), transparent 32%),
43
+ var(--bpa-panel);
44
+ box-shadow: 0 24px 70px rgba(65, 16, 28, 0.12);
45
+ }
46
+
47
+ .bpa-stage {
48
+ display: grid;
49
+ grid-template-columns: minmax(0, 1.15fr) minmax(280px, 0.85fr);
50
+ gap: 0.85rem;
51
+ }
52
+
53
+ .bpa-surface-panel,
54
+ .bpa-view-panel,
55
+ .bpa-table-wrap {
56
+ min-width: 0;
57
+ overflow: hidden;
58
+ border: 1px solid var(--bpa-line);
59
+ border-radius: 8px;
60
+ background: color-mix(in srgb, var(--bpa-panel-strong) 70%, transparent);
61
+ }
62
+
63
+ .bpa-toolbar {
64
+ display: flex;
65
+ align-items: center;
66
+ justify-content: space-between;
67
+ gap: 0.75rem;
68
+ padding: 0.15rem 0.1rem;
69
+ }
70
+
71
+ .bpa-segment,
72
+ .bpa-actions {
73
+ display: flex;
74
+ gap: 0.45rem;
75
+ }
76
+
77
+ .bpa-active-strip {
78
+ display: inline-flex;
79
+ align-items: center;
80
+ min-height: 2.25rem;
81
+ margin-inline: auto;
82
+ padding: 0 0.85rem;
83
+ border: 1px solid var(--bpa-line);
84
+ border-radius: 999px;
85
+ background: color-mix(in srgb, var(--bpa-panel-strong) 82%, transparent);
86
+ color: var(--bpa-muted);
87
+ font-size: 0.88rem;
88
+ }
89
+
90
+ .bpa-active-strip span {
91
+ width: 0.72rem;
92
+ height: 0.72rem;
93
+ margin-right: 0.45rem;
94
+ border-radius: 999px;
95
+ box-shadow: 0 0 0 4px var(--bpa-red-soft);
96
+ }
97
+
98
+ .bpa-active-strip strong {
99
+ color: var(--bpa-ink);
100
+ }
101
+
102
+ .bpa-shell button {
103
+ display: inline-flex;
104
+ align-items: center;
105
+ justify-content: center;
106
+ gap: 0.35rem;
107
+ min-height: 2.25rem;
108
+ border: 1px solid var(--bpa-line);
109
+ border-radius: 7px;
110
+ background: var(--bpa-panel-strong);
111
+ color: var(--bpa-ink);
112
+ font-size: inherit;
113
+ font-weight: 750;
114
+ cursor: pointer;
115
+ transition: transform 160ms ease, border-color 160ms ease, background 160ms ease;
116
+ }
117
+
118
+ .bpa-shell button svg {
119
+ width: 1rem;
120
+ height: 1rem;
121
+ }
122
+
123
+ .bpa-shell button:hover,
124
+ .bpa-segment button.is-active {
125
+ border-color: rgba(179, 32, 63, 0.48);
126
+ background: var(--bpa-red);
127
+ color: white;
128
+ }
129
+
130
+ .bpa-shell button:hover {
131
+ transform: translateY(-1px);
132
+ }
133
+
134
+ .bpa-actions button,
135
+ .bpa-segment button {
136
+ padding: 0 0.8rem;
137
+ }
138
+
139
+ .bpa-surface-wrap {
140
+ padding: 0.65rem;
141
+ }
142
+
143
+ .bpa-surface-wrap canvas {
144
+ display: block;
145
+ width: 100%;
146
+ aspect-ratio: 1.55;
147
+ border-radius: 8px;
148
+ border: 1px solid var(--bpa-line);
149
+ cursor: crosshair;
150
+ touch-action: none;
151
+ box-shadow: inset 0 0 0 1px rgba(255,255,255,.45);
152
+ }
153
+
154
+ .bpa-surface-wrap canvas.can-grab {
155
+ cursor: grab;
156
+ }
157
+
158
+ .bpa-surface-wrap canvas.is-dragging {
159
+ cursor: grabbing;
160
+ }
161
+
162
+ .bpa-view-panel {
163
+ display: grid;
164
+ grid-template-rows: minmax(240px, 1fr) auto;
165
+ overflow: hidden;
166
+ }
167
+
168
+ .bpa-view-panel p {
169
+ margin: 0;
170
+ padding: 0.65rem 0.8rem;
171
+ border-top: 1px solid var(--bpa-line);
172
+ background: color-mix(in srgb, var(--bpa-panel-strong) 74%, transparent);
173
+ color: var(--bpa-muted);
174
+ font-size: 0.92rem;
175
+ }
176
+
177
+ .bpa-three {
178
+ min-height: 260px;
179
+ background:
180
+ radial-gradient(circle at 50% 35%, rgba(245, 198, 94, 0.12), transparent 34%),
181
+ radial-gradient(circle at 72% 25%, rgba(24, 183, 157, 0.08), transparent 30%),
182
+ linear-gradient(145deg, #171b21, #06080b);
183
+ }
184
+
185
+ .bpa-three canvas {
186
+ display: block;
187
+ width: 100%;
188
+ height: 100%;
189
+ }
190
+
191
+ .bpa-dashboard {
192
+ display: grid;
193
+ grid-template-columns: repeat(4, minmax(0, 1fr));
194
+ gap: 0;
195
+ overflow: hidden;
196
+ border: 1px solid var(--bpa-line);
197
+ border-radius: 8px;
198
+ background:
199
+ linear-gradient(90deg, var(--bpa-red-soft), transparent 42%),
200
+ color-mix(in srgb, var(--bpa-panel-strong) 66%, transparent);
201
+ }
202
+
203
+ .bpa-focus-panel {
204
+ display: grid;
205
+ grid-template-columns: minmax(110px, 0.7fr) repeat(3, minmax(150px, 1fr));
206
+ gap: 0.85rem;
207
+ align-items: center;
208
+ padding: 0.72rem 0.82rem;
209
+ border: 1px solid var(--bpa-line);
210
+ border-radius: 8px;
211
+ background:
212
+ linear-gradient(90deg, color-mix(in srgb, var(--bpa-red) 9%, transparent), transparent 55%),
213
+ color-mix(in srgb, var(--bpa-panel-strong) 76%, transparent);
214
+ }
215
+
216
+ .bpa-focus-title {
217
+ display: inline-flex;
218
+ align-items: center;
219
+ gap: 0.55rem;
220
+ min-width: 0;
221
+ font-size: 0.95rem;
222
+ }
223
+
224
+ .bpa-focus-title span {
225
+ width: 0.8rem;
226
+ height: 0.8rem;
227
+ flex: 0 0 auto;
228
+ border-radius: 999px;
229
+ box-shadow: 0 0 0 5px var(--bpa-red-soft);
230
+ }
231
+
232
+ .bpa-focus-title strong {
233
+ overflow: hidden;
234
+ text-overflow: ellipsis;
235
+ white-space: nowrap;
236
+ }
237
+
238
+ .bpa-focus-panel label {
239
+ display: grid;
240
+ grid-template-columns: auto minmax(72px, 1fr) minmax(54px, auto);
241
+ gap: 0.55rem;
242
+ align-items: center;
243
+ min-width: 0;
244
+ color: var(--bpa-muted);
245
+ font-size: 0.78rem;
246
+ font-weight: 850;
247
+ text-transform: uppercase;
248
+ }
249
+
250
+ .bpa-focus-panel input[type="range"] {
251
+ width: 100%;
252
+ accent-color: var(--bpa-red);
253
+ }
254
+
255
+ .bpa-focus-panel output {
256
+ color: var(--bpa-ink);
257
+ font-size: 0.86rem;
258
+ font-weight: 850;
259
+ text-align: right;
260
+ text-transform: none;
261
+ }
262
+
263
+ .bpa-readout {
264
+ display: grid;
265
+ gap: 0.35rem;
266
+ padding: 0.85rem;
267
+ border-right: 1px solid var(--bpa-line);
268
+ position: relative;
269
+ }
270
+
271
+ .bpa-readout::before {
272
+ content: "";
273
+ position: absolute;
274
+ inset: 0 auto 0 0;
275
+ width: 3px;
276
+ background: transparent;
277
+ }
278
+
279
+ .bpa-readout:first-child::before {
280
+ background: var(--bpa-teal);
281
+ }
282
+
283
+ .bpa-readout:nth-child(2)::before {
284
+ background: var(--bpa-gold);
285
+ }
286
+
287
+ .bpa-readout:nth-child(3)::before {
288
+ background: var(--bpa-red);
289
+ }
290
+
291
+ .bpa-readout:nth-child(4)::before {
292
+ background: #6b7cff;
293
+ }
294
+
295
+ .bpa-readout:last-child {
296
+ border-right: 0;
297
+ }
298
+
299
+ .bpa-readout span {
300
+ color: var(--bpa-muted);
301
+ font-size: 0.82rem;
302
+ font-weight: 800;
303
+ text-transform: uppercase;
304
+ }
305
+
306
+ .bpa-readout strong {
307
+ font-size: clamp(1rem, 2vw, 1.35rem);
308
+ line-height: 1.15;
309
+ }
310
+
311
+ #bpa-confidence[data-confidence="high"] {
312
+ color: var(--bpa-teal);
313
+ }
314
+
315
+ #bpa-confidence[data-confidence="medium"] {
316
+ color: var(--bpa-gold);
317
+ }
318
+
319
+ #bpa-confidence[data-confidence="low"] {
320
+ color: var(--bpa-red);
321
+ }
322
+
323
+ .bpa-table-wrap {
324
+ overflow-x: auto;
325
+ }
326
+
327
+ .bpa-table {
328
+ width: 100%;
329
+ border-collapse: collapse;
330
+ min-width: 720px;
331
+ }
332
+
333
+ .bpa-table caption {
334
+ padding: 0.75rem 0.85rem;
335
+ text-align: left;
336
+ font-weight: 850;
337
+ }
338
+
339
+ .bpa-table th,
340
+ .bpa-table td {
341
+ padding: 0.48rem;
342
+ border-top: 1px solid var(--bpa-line);
343
+ }
344
+
345
+ .bpa-table th {
346
+ color: var(--bpa-muted);
347
+ font-size: 0.82rem;
348
+ text-align: left;
349
+ }
350
+
351
+ .bpa-table input {
352
+ width: 100%;
353
+ min-height: 2.25rem;
354
+ border: 1px solid var(--bpa-line);
355
+ border-radius: 7px;
356
+ background: var(--bpa-panel-strong);
357
+ color: var(--bpa-ink);
358
+ font-size: inherit;
359
+ font-weight: 700;
360
+ padding: 0 0.55rem;
361
+ transition: border-color 160ms ease, box-shadow 160ms ease;
362
+ }
363
+
364
+ .bpa-table input:focus {
365
+ border-color: rgba(179, 32, 63, 0.55);
366
+ box-shadow: 0 0 0 3px var(--bpa-red-soft);
367
+ outline: none;
368
+ }
369
+
370
+ .bpa-table tr.is-selected {
371
+ background: var(--bpa-red-soft);
372
+ }
373
+
374
+ .bpa-table tr.is-selected input {
375
+ border-color: rgba(179, 32, 63, 0.32);
376
+ }
377
+
378
+ .bpa-table td:last-child {
379
+ width: 3.2rem;
380
+ text-align: right;
381
+ }
382
+
383
+ .bpa-table td:last-child .bpa-icon-button {
384
+ display: inline-grid;
385
+ place-items: center;
386
+ width: 2.35rem;
387
+ padding: 0;
388
+ }
389
+
390
+ .bpa-icon-button svg {
391
+ width: 1.1rem;
392
+ height: 1.1rem;
393
+ pointer-events: none;
394
+ }
395
+
396
+ .bpa-disclaimer {
397
+ margin: 0;
398
+ padding: 0.85rem 1rem;
399
+ border-left: 4px solid var(--bpa-gold);
400
+ border-radius: 8px;
401
+ background:
402
+ linear-gradient(90deg, color-mix(in srgb, var(--bpa-gold) 18%, transparent), transparent),
403
+ color-mix(in srgb, var(--bpa-panel-strong) 72%, transparent);
404
+ color: var(--bpa-muted);
405
+ font-weight: 700;
406
+ }
407
+
408
+ @media (max-width: 860px) {
409
+ .bpa-stage,
410
+ .bpa-dashboard,
411
+ .bpa-focus-panel {
412
+ grid-template-columns: 1fr;
413
+ }
414
+
415
+ .bpa-toolbar {
416
+ align-items: stretch;
417
+ flex-direction: column;
418
+ }
419
+
420
+ .bpa-active-strip {
421
+ width: 100%;
422
+ justify-content: center;
423
+ }
424
+
425
+ .bpa-readout {
426
+ border-right: 0;
427
+ border-bottom: 1px solid var(--bpa-line);
428
+ }
429
+
430
+ .bpa-readout:last-child {
431
+ border-bottom: 0;
432
+ }
433
+
434
+ .bpa-segment button,
435
+ .bpa-actions button {
436
+ flex: 1;
437
+ }
438
+ }