PageSourceSearch

https://www.langenachtderunternehmen.at/swstatic-260908033654/swsc…/dist/prod/ssa-parser.js

js langenachtderunternehmen.at collected 2026-10-04 22:38:18 UTC 9,642 bytes, 293 lines download raw bytes

vendor: 9,642 bytes, lines 1-293
1import { b as VTTCue, p as parseVTTTimestamp } from './index.js';
2
3const FORMAT_START_RE = /^Format:[\s\t]*/, STYLE_START_RE = /^Style:[\s\t]*/, DIALOGUE_START_RE = /^Dialogue:[\s\t]*/, FORMAT_SPLIT_RE = /[\s\t]*,[\s\t]*/, STYLE_FUNCTION_RE = /\{[^}]+\}/g, NEW_LINE_RE = /\\N/g, STYLES_SECTION_START_RE = /^\[(.*)[\s\t]?Styles\]$/, EVENTS_SECTION_START_RE = /^\[(.*)[\s\t]?Events\]$/;
4class SSAParser {
5  f;
6  O = 0;
7  a = null;
8  j = [];
9  k = [];
10  N = null;
11  d;
12  P = {};
13  async init(init) {
14    this.f = init;
15    if (init.errors)
16      this.d = (await import('./errors.js')).ParseErrorBuilder;
17  }
18  parse(line, lineCount) {
19    if (this.O) {
20      switch (this.O) {
21        case 1:
22          if (line === "") {
23            this.O = 0;
24          } else if (STYLE_START_RE.test(line)) {
25            if (this.N) {
26              const styles = line.replace(STYLE_START_RE, "").split(FORMAT_SPLIT_RE);
27              this.S(styles);
28            } else {
29              this.e(this.d?.T("Style", lineCount));
30            }
31          } else if (FORMAT_START_RE.test(line)) {
32            this.N = line.replace(FORMAT_START_RE, "").split(FORMAT_SPLIT_RE);
33          } else if (EVENTS_SECTION_START_RE.test(line)) {
34            this.N = null;
35            this.O = 2;
36          }
37          break;
38        case 2:
39          if (line === "") {
40            this.Q();
41          } else if (DIALOGUE_START_RE.test(line)) {
42            this.Q();
43            if (this.N) {
44              const dialogue = line.replace(DIALOGUE_START_RE, "").split(FORMAT_SPLIT_RE), cue = this.U(dialogue, lineCount);
45              if (cue)
46                this.a = cue;
47            } else {
48              this.e(this.d?.T("Dialogue", lineCount));
49            }
50          } else if (this.a) {
51            this.a.text += "\n" + line.replace(STYLE_FUNCTION_RE, "").replace(NEW_LINE_RE, "\n");
52          } else if (FORMAT_START_RE.test(line)) {
53            this.N = line.replace(FORMAT_START_RE, "").split(FORMAT_SPLIT_RE);
54          } else if (STYLES_SECTION_START_RE.test(line)) {
55            this.N = null;
56            this.O = 1;
57          } else if (EVENTS_SECTION_START_RE.test(line)) {
58            this.N = null;
59          }
60      }
61    } else if (line === "") ; else if (STYLES_SECTION_START_RE.test(line)) {
62      this.N = null;
63      this.O = 1;
64    } else if (EVENTS_SECTION_START_RE.test(line)) {
65      this.N = null;
66      this.O = 2;
67    }
68  }
69  done() {
70    return {
71      metadata: {},
72      cues: this.j,
73      regions: [],
74      errors: this.k
75    };
76  }
77  Q() {
78    if (!this.a)
79      return;
80    this.j.push(this.a);
81    this.f.onCue?.(this.a);
82    this.a = null;
83  }
84  S(values) {
85    let name = "Default", styles = {}, outlineX, align = "center", vertical = "bottom", marginV, outlineY = 1.2, outlineColor, bgColor, borderStyle = 3, transform = [];
86    for (let i = 0; i < this.N.length; i++) {
87      const field = this.N[i], value = values[i];
88      switch (field) {
89        case "Name":
90          name = value;
91          break;
92        case "Fontname":
93          styles["font-family"] = value;
94          break;
95        case "Fontsize":
96          styles["font-size"] = `calc(${value} / var(--overlay-height))`;
97          break;
98        case "PrimaryColour":
99          const color = parseColor(value);
100          if (color)
101            styles["--cue-color"] = color;
102          break;
103        case "BorderStyle":
104          borderStyle = parseInt(value, 10);
105          break;
106        case "BackColour":
107          bgColor = parseColor(value);
108          break;
109        case "OutlineColour":
110          const _outlineColor = parseColor(value);
111          if (_outlineColor)
112            outlineColor = _outlineColor;
113          break;
114        case "Bold":
115          if (parseInt(value))
116            styles["font-weight"] = "bold";
117          break;
118        case "Italic":
119          if (parseInt(value))
120            styles["font-style"] = "italic";
121          break;
122        case "Underline":
123          if (parseInt(value))
124            styles["text-decoration"] = "underline";
125          break;
126        case "StrikeOut":
127          if (parseInt(value))
128            styles["text-decoration"] = "line-through";
129          break;
130        case "Spacing":
131          styles["letter-spacing"] = value + "px";
132          break;
133        case "AlphaLevel":
134          styles["opacity"] = parseFloat(value);
135          break;
136        case "ScaleX":
137          transform.push(`scaleX(${parseFloat(value) / 100})`);
138          break;
139        case "ScaleY":
140          transform.push(`scaleY(${parseFloat(value) / 100})`);
141          break;
142        case "Angle":
143          transform.push(`rotate(${value}deg)`);
144          break;
145        case "Shadow":
146          outlineY = parseInt(value, 10) * 1.2;
147          break;
148        case "MarginL":
149          styles["--cue-width"] = "auto";
150          styles["--cue-left"] = parseFloat(value) + "px";
151          break;
152        case "MarginR":
153          styles["--cue-width"] = "auto";
154          styles["--cue-right"] = parseFloat(value) + "px";
155          break;
156        case "MarginV":
157          marginV = parseFloat(value);
158          break;
159        case "Outline":
160          outlineX = parseInt(value, 10);
161          break;
162        case "Alignment":
163          const alignment = parseInt(value, 10);
164          if (alignment >= 4)
165            vertical = alignment >= 7 ? "top" : "center";
166          switch (alignment % 3) {
167            case 1:
168              align = "start";
169              break;
170            case 2:
171              align = "center";
172              break;
173            case 3:
174              align = "end";
175              break;
176          }
177      }
178    }
179    styles.R = vertical;
180    styles["--cue-white-space"] = "normal";
181    styles["--cue-line-height"] = "normal";
182    styles["--cue-text-align"] = align;
183    if (vertical === "center") {
184      styles[`--cue-top`] = "50%";
185      transform.push("translateY(-50%)");
186    } else {
187      styles[`--cue-${vertical}`] = (marginV || 0) + "px";
188    }
189    if (borderStyle === 1) {
190      styles["--cue-padding-y"] = "0";
191    }
192    if (borderStyle === 1 || bgColor) {
193      styles["--cue-bg-color"] = borderStyle === 1 ? "none" : bgColor;
194    }
195    if (borderStyle === 3 && outlineColor) {
196      styles["--cue-outline"] = `${outlineX}px solid ${outlineColor}`;
197    }
198    if (borderStyle === 1 && typeof outlineX === "number") {
199      const color = bgColor ?? "#000";
200      styles["--cue-text-shadow"] = [
201        outlineColor && buildTextShadow(outlineX * 1.2, outlineY * 1.2, outlineColor),
202        outlineColor ? buildTextShadow(outlineX * (outlineX / 2), outlineY * (outlineX / 2), color) : buildTextShadow(outlineX, outlineY, color)
203      ].filter(Boolean).join(", ");
204    }
205    if (transform.length)
206      styles["--cue-transform"] = transform.join(" ");
207    this.P[name] = styles;
208  }
209  U(values, lineCount) {
210    const fields = this.V(values);
211    const timestamp = this.o(fields.Start, fields.End, lineCount);
212    if (!timestamp)
213      return;
214    const cue = new VTTCue(timestamp[0], timestamp[1], ""), styles = { ...this.P[fields.Style] || {} }, voice = fields.Name ? `<v ${fields.Name}>` : "";
215    const vertical = styles.R, marginLeft = fields.MarginL && parseFloat(fields.MarginL), marginRight = fields.MarginR && parseFloat(fields.MarginR), marginV = fields.MarginV && parseFloat(fields.MarginV);
216    if (marginLeft) {
217      styles["--cue-width"] = "auto";
218      styles["--cue-left"] = marginLeft + "px";
219    }
220    if (marginRight) {
221      styles["--cue-width"] = "auto";
222      styles["--cue-right"] = marginRight + "px";
223    }
224    if (marginV && vertical !== "center") {
225      styles[`--cue-${vertical}`] = marginV + "px";
226    }
227    cue.text = voice + values.slice(this.N.length - 1).join(", ").replace(STYLE_FUNCTION_RE, "").replace(NEW_LINE_RE, "\n");
228    delete styles.R;
229    if (Object.keys(styles).length)
230      cue.style = styles;
231    return cue;
232  }
233  V(values) {
234    const fields = {};
235    for (let i = 0; i < this.N.length; i++) {
236      fields[this.N[i]] = values[i];
237    }
238    return fields;
239  }
240  o(startTimeText, endTimeText, lineCount) {
241    const startTime = parseVTTTimestamp(startTimeText), endTime = parseVTTTimestamp(endTimeText);
242    if (startTime !== null && endTime !== null && endTime > startTime) {
243      return [startTime, endTime];
244    } else {
245      if (startTime === null) {
246        this.e(this.d?.q(startTimeText, lineCount));
247      }
248      if (endTime === null) {
249        this.e(this.d?.r(endTimeText, lineCount));
250      }
251      if (startTime != null && endTime !== null && endTime > startTime) {
252        this.e(this.d?.s(startTime, endTime, lineCount));
253      }
254    }
255  }
256  e(error) {
257    if (!error)
258      return;
259    this.k.push(error);
260    if (this.f.strict) {
261      this.f.cancel();
262      throw error;
263    } else {
264      this.f.onError?.(error);
265    }
266  }
267}
268function parseColor(color) {
269  const abgr = parseInt(color.replace("&H", ""), 16);
270  if (abgr >= 0) {
271    const a = abgr >> 24 & 255 ^ 255;
272    const alpha = a / 255;
273    const b = abgr >> 16 & 255;
274    const g = abgr >> 8 & 255;
275    const r = abgr & 255;
276    return "rgba(" + [r, g, b, alpha].join(",") + ")";
277  }
278  return null;
279}
280function buildTextShadow(x, y, color) {
281  const noOfShadows = Math.ceil(2 * Math.PI * x);
282  let textShadow = "";
283  for (let i = 0; i < noOfShadows; i++) {
284    const theta = 2 * Math.PI * i / noOfShadows;
285    textShadow += x * Math.cos(theta) + "px " + y * Math.sin(theta) + "px 0 " + color + (i == noOfShadows - 1 ? "" : ",");
286  }
287  return textShadow;
288}
289function createSSAParser() {
290  return new SSAParser();
291}
292
293export { SSAParser, createSSAParser as default };

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.