schematex 0.9.6 → 0.9.7

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.
@@ -17466,6 +17466,19 @@ function truncate3(s, n) {
17466
17466
  return s.length <= n ? s : s.slice(0, n - 1) + "\u2026";
17467
17467
  }
17468
17468
 
17469
+ // src/core/format.ts
17470
+ function formatProbability(n) {
17471
+ if (!Number.isFinite(n)) return String(n);
17472
+ if (n <= 0) return "0";
17473
+ if (n >= 1) return "1";
17474
+ if (n < 1e-3) return n.toExponential(2);
17475
+ for (let p = 3; p <= 9; p++) {
17476
+ const s = parseFloat(n.toPrecision(p));
17477
+ if (s > 0 && s < 1) return String(s);
17478
+ }
17479
+ return String(parseFloat(n.toPrecision(9)));
17480
+ }
17481
+
17469
17482
  // src/diagrams/faulttree/analysis.ts
17470
17483
  var EXPANSION_CAP = 5e4;
17471
17484
  var EXACT_CUTSET_CAP = 20;
@@ -18219,9 +18232,7 @@ function summarise2(layout) {
18219
18232
  return parts.join(" ");
18220
18233
  }
18221
18234
  function fmtProb(n) {
18222
- if (n === 0) return "0";
18223
- if (n >= 1e-3) return String(parseFloat(n.toPrecision(3)));
18224
- return n.toExponential(2);
18235
+ return formatProbability(n);
18225
18236
  }
18226
18237
  function clip2(s, n) {
18227
18238
  return s.length <= n ? s : s.slice(0, n - 1) + "\u2026";
@@ -20684,6 +20695,7 @@ function parseRbd(text2) {
20684
20695
  seenIds.add(id);
20685
20696
  let label;
20686
20697
  let R;
20698
+ let dist;
20687
20699
  if (peek()?.t === "string") {
20688
20700
  label = tokens[pos++].v;
20689
20701
  }
@@ -20692,10 +20704,16 @@ function parseRbd(text2) {
20692
20704
  const attr = parseAttr(w);
20693
20705
  if (!attr) break;
20694
20706
  pos++;
20695
- if (attr.key === "p") R = clamp01(1 - attr.value, w, warnings);
20696
- else R = clamp01(attr.value, w, warnings);
20707
+ if (attr.kind === "dist") dist = attr.dist;
20708
+ else R = clamp01(attr.failure ? 1 - attr.value : attr.value, w, warnings);
20697
20709
  }
20698
- return { kind: "block", id, ...label !== void 0 ? { label } : {}, ...R !== void 0 ? { R } : {} };
20710
+ return {
20711
+ kind: "block",
20712
+ id,
20713
+ ...label !== void 0 ? { label } : {},
20714
+ ...R !== void 0 ? { R } : {},
20715
+ ...dist !== void 0 ? { dist } : {}
20716
+ };
20699
20717
  };
20700
20718
  const parseGroup = (kwRaw) => {
20701
20719
  const kw = kwRaw.toLowerCase();
@@ -20769,10 +20787,19 @@ function parseRbd(text2) {
20769
20787
  } else {
20770
20788
  root = { kind: "series", children: top };
20771
20789
  }
20790
+ let mission;
20791
+ if (metadata.mission !== void 0) {
20792
+ const v = parseFloat(metadata.mission);
20793
+ if (!Number.isFinite(v) || v < 0) {
20794
+ throw new RbdParseError(`mission time must be a non-negative number (got '${metadata.mission}')`);
20795
+ }
20796
+ mission = v;
20797
+ }
20772
20798
  return {
20773
20799
  type: "rbd",
20774
20800
  ...title2 ? { title: title2 } : {},
20775
20801
  root,
20802
+ ...mission !== void 0 ? { mission } : {},
20776
20803
  warnings,
20777
20804
  ...Object.keys(metadata).length > 0 ? { metadata } : {}
20778
20805
  };
@@ -20825,11 +20852,10 @@ function tokenize6(src) {
20825
20852
  }
20826
20853
  function stripBodyDirectives(body, metadata) {
20827
20854
  return body.split("\n").filter((line2) => {
20828
- const m = line2.match(/^\s*(title|standard|note)\s*:\s*(.+)$/i);
20855
+ const m = line2.match(/^\s*(title|standard|note|mission)\s*:\s*(.+)$/i);
20829
20856
  if (m) {
20830
20857
  const key = m[1].toLowerCase();
20831
- if (key !== "title") metadata[key] = m[2].trim();
20832
- else metadata.title = m[2].trim();
20858
+ metadata[key] = m[2].trim();
20833
20859
  return false;
20834
20860
  }
20835
20861
  return true;
@@ -20841,15 +20867,33 @@ function extractQuoted(s) {
20841
20867
  return s.length > 0 ? s.trim() : void 0;
20842
20868
  }
20843
20869
  function parseAttr(w) {
20870
+ const wb = w.match(/^weibull\s*[=:]\s*(.+)$/i);
20871
+ if (wb) {
20872
+ const parts = wb[1].split(",").map((s) => parseFloat(s.trim()));
20873
+ if (parts.length === 2 && parts.every((x) => Number.isFinite(x) && x > 0)) {
20874
+ return { kind: "dist", dist: { kind: "weibull", beta: parts[0], eta: parts[1] } };
20875
+ }
20876
+ return null;
20877
+ }
20878
+ const rt = w.match(/^rate\s*[=:]\s*(.+)$/i);
20879
+ if (rt) {
20880
+ const v = parseFloat(rt[1].trim());
20881
+ return Number.isFinite(v) && v >= 0 ? { kind: "dist", dist: { kind: "exp", rate: v } } : null;
20882
+ }
20883
+ const mt = w.match(/^(mtbf|mttf)\s*[=:]\s*(.+)$/i);
20884
+ if (mt) {
20885
+ const v = parseFloat(mt[2].trim());
20886
+ return Number.isFinite(v) && v > 0 ? { kind: "dist", dist: { kind: "exp", rate: 1 / v } } : null;
20887
+ }
20844
20888
  const m = w.match(/^(R|r|p|prob|q)\s*[=:]\s*(.+)$/);
20845
20889
  if (m) {
20846
20890
  const key = m[1].toLowerCase();
20847
20891
  const value = parseNum(m[2]);
20848
20892
  if (value === void 0) return null;
20849
- return { key: key === "p" || key === "q" ? "p" : "R", value };
20893
+ return { kind: "R", value, failure: key === "p" || key === "q" };
20850
20894
  }
20851
20895
  const bare = parseNum(w);
20852
- if (bare !== void 0) return { key: "R", value: bare };
20896
+ if (bare !== void 0) return { kind: "R", value: bare, failure: false };
20853
20897
  return null;
20854
20898
  }
20855
20899
  function parseNum(s) {
@@ -20878,8 +20922,11 @@ var KOFN_ENUM_CAP = 18;
20878
20922
  function analyseRbd(ast) {
20879
20923
  const notes = [];
20880
20924
  const warnings = [...ast.warnings];
20925
+ if (ast.mission !== void 0) {
20926
+ notes.push(`Mission time t = ${ast.mission}; block reliabilities with a rate/MTBF/Weibull are evaluated as R(t).`);
20927
+ }
20881
20928
  const blocks = [];
20882
- collectBlocks(ast.root, blocks);
20929
+ collectBlocks(ast.root, blocks, ast.mission, warnings);
20883
20930
  const missing = blocks.filter((b) => b.R === void 0).map((b) => b.id);
20884
20931
  const baseEnv = new Map(blocks.map((b) => [b.id, b.R]));
20885
20932
  const systemReliability = evalStructure(ast.root, baseEnv, notes);
@@ -20895,10 +20942,15 @@ function analyseRbd(ast) {
20895
20942
  const rDown = evalStructure(ast.root, down, notes);
20896
20943
  const importance = rUp !== void 0 && rDown !== void 0 ? rUp - rDown : void 0;
20897
20944
  const isSpof = rDown === 0;
20945
+ let criticality;
20946
+ if (importance !== void 0 && b.R !== void 0 && systemReliability < 1) {
20947
+ criticality = importance * (1 - b.R) / (1 - systemReliability);
20948
+ }
20898
20949
  return {
20899
20950
  id: b.id,
20900
20951
  ...b.R !== void 0 ? { R: b.R } : {},
20901
20952
  ...importance !== void 0 ? { importance } : {},
20953
+ ...criticality !== void 0 ? { criticality } : {},
20902
20954
  isSpof
20903
20955
  };
20904
20956
  });
@@ -20923,12 +20975,25 @@ function analyseRbd(ast) {
20923
20975
  notes
20924
20976
  };
20925
20977
  }
20926
- function collectBlocks(s, out) {
20978
+ function collectBlocks(s, out, mission, warnings) {
20927
20979
  if (s.kind === "block") {
20928
- out.push({ id: s.id, ...s.R !== void 0 ? { R: s.R } : {} });
20980
+ const R = resolveBlockR(s, mission, warnings);
20981
+ out.push({ id: s.id, ...R !== void 0 ? { R } : {} });
20929
20982
  return;
20930
20983
  }
20931
- for (const c of s.children) collectBlocks(c, out);
20984
+ for (const c of s.children) collectBlocks(c, out, mission, warnings);
20985
+ }
20986
+ function resolveBlockR(b, mission, warnings) {
20987
+ if (b.dist) {
20988
+ if (mission === void 0) {
20989
+ warnings.push(`Block "${b.id}" has a failure distribution but no mission time \u2014 add 'mission: <t>' to evaluate R(t)${b.R !== void 0 ? ", falling back to its constant R" : ""}.`);
20990
+ return b.R;
20991
+ }
20992
+ const t = mission;
20993
+ if (b.dist.kind === "exp") return Math.exp(-b.dist.rate * t);
20994
+ return Math.exp(-Math.pow(t / b.dist.eta, b.dist.beta));
20995
+ }
20996
+ return b.R;
20932
20997
  }
20933
20998
  function evalStructure(s, env, notes) {
20934
20999
  if (s.kind === "block") return env.get(s.id);
@@ -21159,7 +21224,7 @@ function renderRbdLayout(layout, config) {
21159
21224
  class: "sx-rbd-rsys",
21160
21225
  "text-anchor": "middle"
21161
21226
  },
21162
- systemLabel(analysis)
21227
+ systemLabel(analysis, ast.mission)
21163
21228
  )
21164
21229
  );
21165
21230
  for (const w of layout.wires) inner.push(chunk3WNW5Y7P_cjs.path({ d: w.path, class: "sx-rbd-wire" }));
@@ -21229,12 +21294,16 @@ function renderBlock(b) {
21229
21294
  parts
21230
21295
  );
21231
21296
  }
21232
- function systemLabel(analysis) {
21297
+ function systemLabel(analysis, mission) {
21233
21298
  if (analysis.systemReliability === void 0) {
21234
21299
  const miss = analysis.missing.length > 0 ? ` \u2014 missing R on ${analysis.missing.join(", ")}` : "";
21235
21300
  return `System reliability: n/a${miss}`;
21236
21301
  }
21237
- return `System reliability R = ${fmtR(analysis.systemReliability)}`;
21302
+ const arg = mission !== void 0 ? `(t=${fmtVal3(mission)})` : "";
21303
+ return `System reliability R${arg} = ${fmtR(analysis.systemReliability)}`;
21304
+ }
21305
+ function fmtVal3(n) {
21306
+ return String(parseFloat(n.toFixed(2)));
21238
21307
  }
21239
21308
  function fmtR(n) {
21240
21309
  if (n >= 1) return "1";
@@ -41280,5 +41349,5 @@ exports.timeline = timeline;
41280
41349
  exports.umlclass = umlclass;
41281
41350
  exports.usecase = usecase;
41282
41351
  exports.welding = welding;
41283
- //# sourceMappingURL=chunk-KH5GRKUM.cjs.map
41284
- //# sourceMappingURL=chunk-KH5GRKUM.cjs.map
41352
+ //# sourceMappingURL=chunk-6X7MVZZT.cjs.map
41353
+ //# sourceMappingURL=chunk-6X7MVZZT.cjs.map