@diagrammo/dgmo 0.16.0 → 0.17.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 (53) hide show
  1. package/dist/advanced.cjs +133 -280
  2. package/dist/advanced.d.cts +9 -2
  3. package/dist/advanced.d.ts +9 -2
  4. package/dist/advanced.js +133 -280
  5. package/dist/auto.cjs +135 -269
  6. package/dist/auto.js +96 -96
  7. package/dist/auto.mjs +135 -269
  8. package/dist/cli.cjs +125 -125
  9. package/dist/index.cjs +132 -266
  10. package/dist/index.js +132 -266
  11. package/dist/internal.cjs +133 -280
  12. package/dist/internal.d.cts +9 -2
  13. package/dist/internal.d.ts +9 -2
  14. package/dist/internal.js +133 -280
  15. package/docs/language-reference.md +14 -18
  16. package/docs/migration-sequence-color-to-tags.md +1 -1
  17. package/gallery/fixtures/sequence-tags-protocols.dgmo +3 -3
  18. package/gallery/fixtures/sequence-tags.dgmo +3 -3
  19. package/gallery/fixtures/sequence.dgmo +4 -4
  20. package/package.json +7 -3
  21. package/src/auto/index.ts +2 -2
  22. package/src/boxes-and-lines/layout.ts +1 -2
  23. package/src/c4/parser.ts +1 -1
  24. package/src/class/parser.ts +1 -1
  25. package/src/cli.ts +2 -2
  26. package/src/completion.ts +1 -14
  27. package/src/cycle/parser.ts +1 -1
  28. package/src/d3.ts +2 -3
  29. package/src/diagnostics.ts +20 -0
  30. package/src/echarts.ts +2 -2
  31. package/src/editor/dgmo.grammar.d.ts +1 -1
  32. package/src/er/parser.ts +1 -1
  33. package/src/graph/flowchart-renderer.ts +3 -0
  34. package/src/infra/renderer.ts +1 -2
  35. package/src/journey-map/parser.ts +1 -1
  36. package/src/kanban/parser.ts +1 -1
  37. package/src/mindmap/parser.ts +2 -3
  38. package/src/org/parser.ts +1 -1
  39. package/src/pert/analyzer.ts +10 -10
  40. package/src/pert/layout.ts +1 -1
  41. package/src/pert/parser.ts +1 -1
  42. package/src/pyramid/parser.ts +1 -1
  43. package/src/raci/parser.ts +2 -2
  44. package/src/ring/parser.ts +1 -1
  45. package/src/sequence/parser.ts +66 -14
  46. package/src/sequence/participant-inference.ts +18 -181
  47. package/src/sequence/renderer.ts +47 -136
  48. package/src/sitemap/parser.ts +1 -1
  49. package/src/tech-radar/parser.ts +2 -2
  50. package/src/utils/extract-alias.ts +1 -1
  51. package/src/utils/inline-markdown.ts +1 -1
  52. package/src/utils/time-ticks.ts +1 -1
  53. package/src/wireframe/parser.ts +1 -1
package/dist/auto.cjs CHANGED
@@ -418,6 +418,9 @@ function nameMergedMessage(args) {
418
418
  function akaRemovedMessage() {
419
419
  return `'aka' is no longer supported \u2014 use the participant name directly`;
420
420
  }
421
+ function participantTypeRemovedMessage(type) {
422
+ return `'${type}' is no longer supported \u2014 drop 'is a ${type}'; the participant renders as the default rectangle`;
423
+ }
421
424
  function tagShorthandRemovedMessage(args) {
422
425
  return `Bare tag shorthand 'tag ${args.name} ${args.alias}' was removed. Use 'tag ${args.name} as ${args.alias}' instead.`;
423
426
  }
@@ -451,7 +454,15 @@ var init_diagnostics = __esm({
451
454
  * participant declaration. Forgiving normalization makes aliasing
452
455
  * unnecessary; the diagnostic directs users to the new syntax.
453
456
  */
454
- AKA_REMOVED: "E_AKA_REMOVED"
457
+ AKA_REMOVED: "E_AKA_REMOVED",
458
+ /**
459
+ * Error: a removed sequence participant-type keyword was used in
460
+ * an `is a X` declaration. The 0.16.0 trim retained only
461
+ * `actor`/`database`/`cache`/`queue`; `service`/`frontend`/
462
+ * `networking`/`gateway`/`external` no longer carry semantic
463
+ * weight and emit this error so users drop the override.
464
+ */
465
+ PARTICIPANT_TYPE_REMOVED: "E_PARTICIPANT_TYPE_REMOVED"
455
466
  };
456
467
  ALIAS_DIAGNOSTIC_CODES = {
457
468
  /** Alias token used before its declaration (strict-ordering rule). */
@@ -3114,81 +3125,7 @@ var init_participant_inference = __esm({
3114
3125
  // Names that would incorrectly match general patterns in later groups
3115
3126
  { pattern: /^KeyDB$/i, type: "cache" },
3116
3127
  // not database (DB$ suffix)
3117
- { pattern: /Webhook/i, type: "external" },
3118
- // not frontend (Web contains)
3119
- { pattern: /^Upstream$/i, type: "external" },
3120
- // not queue (Stream$ suffix)
3121
- { pattern: /^Downstream$/i, type: "external" },
3122
- // not queue (Stream$ suffix)
3123
- // ── 1. Infrastructure overrides ─────────────────────────
3124
- // These names end in -er/-or but are NOT actors
3125
- { pattern: /^.*Router$/i, type: "networking" },
3126
- { pattern: /^.*Scheduler$/i, type: "service" },
3127
- { pattern: /^.*Dispatcher$/i, type: "service" },
3128
- { pattern: /^.*Balancer$/i, type: "networking" },
3129
- { pattern: /^.*Controller$/i, type: "service" },
3130
- { pattern: /^.*Handler$/i, type: "service" },
3131
- { pattern: /^.*Processor$/i, type: "service" },
3132
- { pattern: /^.*Connector$/i, type: "service" },
3133
- { pattern: /^.*Adapter$/i, type: "service" },
3134
- { pattern: /^.*Provider$/i, type: "service" },
3135
- { pattern: /^.*Manager$/i, type: "service" },
3136
- { pattern: /^.*Orchestrator$/i, type: "service" },
3137
- { pattern: /^.*Monitor$/i, type: "service" },
3138
- { pattern: /^.*Resolver$/i, type: "service" },
3139
- { pattern: /^.*Logger$/i, type: "service" },
3140
- { pattern: /^.*Server$/i, type: "service" },
3141
- { pattern: /^.*Broker$/i, type: "queue" },
3142
- { pattern: /^.*Worker$/i, type: "service" },
3143
- { pattern: /^.*Consumer$/i, type: "service" },
3144
- { pattern: /^.*Producer$/i, type: "service" },
3145
- { pattern: /^.*Publisher$/i, type: "service" },
3146
- { pattern: /^.*Subscriber$/i, type: "service" },
3147
- { pattern: /^.*Listener$/i, type: "service" },
3148
- // New -er/-or suffixes that are services, not actors
3149
- { pattern: /^.*Watcher$/i, type: "service" },
3150
- { pattern: /^.*Executor$/i, type: "service" },
3151
- { pattern: /^.*Aggregator$/i, type: "service" },
3152
- { pattern: /^.*Collector$/i, type: "service" },
3153
- { pattern: /^.*Transformer$/i, type: "service" },
3154
- { pattern: /^.*Validator$/i, type: "service" },
3155
- { pattern: /^.*Generator$/i, type: "service" },
3156
- { pattern: /^.*Indexer$/i, type: "service" },
3157
- { pattern: /^.*Crawler$/i, type: "service" },
3158
- { pattern: /^.*Scanner$/i, type: "service" },
3159
- { pattern: /^.*Parser$/i, type: "service" },
3160
- { pattern: /^.*Emitter$/i, type: "service" },
3161
- { pattern: /^.*Exporter$/i, type: "service" },
3162
- { pattern: /^.*Importer$/i, type: "service" },
3163
- { pattern: /^.*Loader$/i, type: "service" },
3164
- { pattern: /^.*Renderer$/i, type: "service" },
3165
- { pattern: /^.*Checker$/i, type: "service" },
3166
- { pattern: /^.*Inspector$/i, type: "service" },
3167
- { pattern: /^.*Encoder$/i, type: "service" },
3168
- { pattern: /^.*Decoder$/i, type: "service" },
3169
- { pattern: /^.*Notifier$/i, type: "service" },
3170
- // ── 2. Networking patterns ──────────────────────────────
3171
- { pattern: /Gateway/i, type: "networking" },
3172
- { pattern: /GW$/i, type: "networking" },
3173
- { pattern: /Proxy/i, type: "networking" },
3174
- { pattern: /LB$/i, type: "networking" },
3175
- { pattern: /LoadBalancer/i, type: "networking" },
3176
- { pattern: /CDN/i, type: "networking" },
3177
- { pattern: /Firewall/i, type: "networking" },
3178
- { pattern: /WAF$/i, type: "networking" },
3179
- { pattern: /DNS/i, type: "networking" },
3180
- { pattern: /Ingress/i, type: "networking" },
3181
- // Named products & patterns
3182
- { pattern: /Nginx/i, type: "networking" },
3183
- { pattern: /Traefik/i, type: "networking" },
3184
- { pattern: /Envoy/i, type: "networking" },
3185
- { pattern: /Istio/i, type: "networking" },
3186
- { pattern: /Kong/i, type: "networking" },
3187
- { pattern: /Akamai/i, type: "networking" },
3188
- { pattern: /Cloudflare/i, type: "networking" },
3189
- { pattern: /Mesh$/i, type: "networking" },
3190
- { pattern: /ServiceMesh/i, type: "networking" },
3191
- // ── 3. Database patterns ────────────────────────────────
3128
+ // ── 1. Database patterns ────────────────────────────────
3192
3129
  { pattern: /DB$/i, type: "database" },
3193
3130
  { pattern: /Database/i, type: "database" },
3194
3131
  { pattern: /Datastore/i, type: "database" },
@@ -3222,16 +3159,15 @@ var init_participant_inference = __esm({
3222
3159
  { pattern: /Milvus/i, type: "database" },
3223
3160
  { pattern: /Presto/i, type: "database" },
3224
3161
  { pattern: /Table$/i, type: "database" },
3225
- // ── 4. Cache patterns ──────────────────────────────────
3162
+ // ── 2. Cache patterns ──────────────────────────────────
3226
3163
  { pattern: /Cache/i, type: "cache" },
3227
3164
  { pattern: /Redis/i, type: "cache" },
3228
3165
  { pattern: /Memcache/i, type: "cache" },
3229
- // CDN already matched by networking above
3230
3166
  // Named products
3231
3167
  { pattern: /Dragonfly/i, type: "cache" },
3232
3168
  { pattern: /Hazelcast/i, type: "cache" },
3233
3169
  { pattern: /Valkey/i, type: "cache" },
3234
- // ── 5. Queue/Messaging patterns ─────────────────────────
3170
+ // ── 3. Queue/Messaging patterns ─────────────────────────
3235
3171
  { pattern: /Queue/i, type: "queue" },
3236
3172
  { pattern: /MQ$/i, type: "queue" },
3237
3173
  { pattern: /SQS/i, type: "queue" },
@@ -3244,6 +3180,7 @@ var init_participant_inference = __esm({
3244
3180
  { pattern: /Stream$/i, type: "queue" },
3245
3181
  { pattern: /SNS/i, type: "queue" },
3246
3182
  { pattern: /PubSub/i, type: "queue" },
3183
+ { pattern: /Broker$/i, type: "queue" },
3247
3184
  // Named products & patterns
3248
3185
  { pattern: /NATS/i, type: "queue" },
3249
3186
  { pattern: /Pulsar/i, type: "queue" },
@@ -3254,7 +3191,7 @@ var init_participant_inference = __esm({
3254
3191
  { pattern: /Sidekiq/i, type: "queue" },
3255
3192
  { pattern: /EventHub/i, type: "queue" },
3256
3193
  { pattern: /Channel$/i, type: "queue" },
3257
- // ── 6. Actor patterns ──────────────────────────────────
3194
+ // ── 4. Actor patterns ──────────────────────────────────
3258
3195
  // Exact matches first
3259
3196
  { pattern: /^Admin$/i, type: "actor" },
3260
3197
  { pattern: /^User$/i, type: "actor" },
@@ -3273,98 +3210,11 @@ var init_participant_inference = __esm({
3273
3210
  { pattern: /^Fan$/i, type: "actor" },
3274
3211
  { pattern: /^Purchaser$/i, type: "actor" },
3275
3212
  { pattern: /^Reviewer$/i, type: "actor" },
3276
- // Suffix rules (after infrastructure overrides filtered above)
3213
+ // Suffix rules
3277
3214
  { pattern: /User$/i, type: "actor" },
3278
3215
  { pattern: /Actor$/i, type: "actor" },
3279
3216
  { pattern: /Analyst$/i, type: "actor" },
3280
- { pattern: /Staff$/i, type: "actor" },
3281
- // ── 7. Frontend patterns ────────────────────────────────
3282
- { pattern: /App$/i, type: "frontend" },
3283
- { pattern: /Application/i, type: "frontend" },
3284
- { pattern: /Mobile/i, type: "frontend" },
3285
- { pattern: /iOS/i, type: "frontend" },
3286
- { pattern: /Android/i, type: "frontend" },
3287
- { pattern: /Web/i, type: "frontend" },
3288
- { pattern: /Browser/i, type: "frontend" },
3289
- { pattern: /Frontend/i, type: "frontend" },
3290
- { pattern: /UI$/i, type: "frontend" },
3291
- { pattern: /Dashboard/i, type: "frontend" },
3292
- { pattern: /CLI$/i, type: "frontend" },
3293
- { pattern: /Terminal/i, type: "frontend" },
3294
- // Frameworks & patterns
3295
- { pattern: /React/i, type: "frontend" },
3296
- { pattern: /^Vue$/i, type: "frontend" },
3297
- { pattern: /Angular/i, type: "frontend" },
3298
- { pattern: /Svelte/i, type: "frontend" },
3299
- { pattern: /NextJS/i, type: "frontend" },
3300
- { pattern: /Nuxt/i, type: "frontend" },
3301
- { pattern: /Remix/i, type: "frontend" },
3302
- { pattern: /Electron/i, type: "frontend" },
3303
- { pattern: /Tauri/i, type: "frontend" },
3304
- { pattern: /Widget$/i, type: "frontend" },
3305
- { pattern: /Portal/i, type: "frontend" },
3306
- { pattern: /Console$/i, type: "frontend" },
3307
- { pattern: /^SPA$/i, type: "frontend" },
3308
- { pattern: /^PWA$/i, type: "frontend" },
3309
- // ── 8. Service patterns ─────────────────────────────────
3310
- { pattern: /Service/i, type: "service" },
3311
- { pattern: /Svc$/i, type: "service" },
3312
- { pattern: /API$/i, type: "service" },
3313
- { pattern: /Lambda/i, type: "service" },
3314
- { pattern: /Function$/i, type: "service" },
3315
- { pattern: /Fn$/i, type: "service" },
3316
- { pattern: /Job$/i, type: "service" },
3317
- { pattern: /Cron/i, type: "service" },
3318
- { pattern: /Microservice/i, type: "service" },
3319
- // Auth
3320
- { pattern: /^Auth$/i, type: "service" },
3321
- { pattern: /^AuthN$/i, type: "service" },
3322
- { pattern: /^AuthZ$/i, type: "service" },
3323
- { pattern: /^SSO$/i, type: "service" },
3324
- { pattern: /OAuth/i, type: "service" },
3325
- { pattern: /^OIDC$/i, type: "service" },
3326
- // SaaS
3327
- { pattern: /Stripe/i, type: "service" },
3328
- { pattern: /Twilio/i, type: "service" },
3329
- { pattern: /SendGrid/i, type: "service" },
3330
- { pattern: /Mailgun/i, type: "service" },
3331
- // Cloud/infra
3332
- { pattern: /^S3$/i, type: "service" },
3333
- { pattern: /^Blob$/i, type: "service" },
3334
- { pattern: /Vercel/i, type: "service" },
3335
- { pattern: /Netlify/i, type: "service" },
3336
- { pattern: /Heroku/i, type: "service" },
3337
- { pattern: /Docker/i, type: "service" },
3338
- { pattern: /Kubernetes/i, type: "service" },
3339
- { pattern: /K8s/i, type: "service" },
3340
- { pattern: /Terraform/i, type: "service" },
3341
- // Security
3342
- { pattern: /Vault/i, type: "service" },
3343
- { pattern: /^HSM$/i, type: "service" },
3344
- { pattern: /KMS/i, type: "service" },
3345
- { pattern: /^IAM$/i, type: "service" },
3346
- // AI/ML
3347
- { pattern: /^LLM$/i, type: "service" },
3348
- { pattern: /GPT/i, type: "service" },
3349
- { pattern: /^Claude$/i, type: "service" },
3350
- { pattern: /Embedding/i, type: "service" },
3351
- { pattern: /Inference/i, type: "service" },
3352
- // Suffixes & patterns
3353
- { pattern: /Pipeline$/i, type: "service" },
3354
- { pattern: /Registry/i, type: "service" },
3355
- { pattern: /Engine$/i, type: "service" },
3356
- { pattern: /Daemon/i, type: "service" },
3357
- // ── 9. External patterns ────────────────────────────────
3358
- { pattern: /External/i, type: "external" },
3359
- { pattern: /Ext$/i, type: "external" },
3360
- { pattern: /ThirdParty/i, type: "external" },
3361
- { pattern: /3P$/i, type: "external" },
3362
- { pattern: /Vendor/i, type: "external" },
3363
- // Named products & patterns
3364
- { pattern: /Callback/i, type: "external" },
3365
- { pattern: /^AWS$/i, type: "external" },
3366
- { pattern: /^GCP$/i, type: "external" },
3367
- { pattern: /Azure/i, type: "external" }
3217
+ { pattern: /Staff$/i, type: "actor" }
3368
3218
  ];
3369
3219
  RULE_COUNT = PARTICIPANT_RULES.length;
3370
3220
  }
@@ -3657,7 +3507,7 @@ function parseSequenceDgmo(content) {
3657
3507
  const pushWarning = (line12, message) => {
3658
3508
  result.diagnostics.push(makeDgmoError(line12, message, "warning"));
3659
3509
  };
3660
- if (!content || !content.trim()) {
3510
+ if (!content?.trim()) {
3661
3511
  return fail(0, "Empty content");
3662
3512
  }
3663
3513
  const lines = content.split("\n");
@@ -3668,7 +3518,7 @@ function parseSequenceDgmo(content) {
3668
3518
  const fl = lines[fi].trim();
3669
3519
  if (!fl || fl.startsWith("//")) continue;
3670
3520
  const parsed = parseFirstLine(fl);
3671
- if (parsed && parsed.chartType === "sequence") {
3521
+ if (parsed?.chartType === "sequence") {
3672
3522
  hasExplicitChart = true;
3673
3523
  firstLineIndex = fi;
3674
3524
  if (parsed.title) {
@@ -3983,6 +3833,17 @@ function parseSequenceDgmo(content) {
3983
3833
  const id = isAMatch[1];
3984
3834
  const typeStr = isAMatch[2].toLowerCase();
3985
3835
  let remainder = isAMatch[3]?.trim() || "";
3836
+ if (REMOVED_PARTICIPANT_TYPES.has(typeStr)) {
3837
+ result.diagnostics.push(
3838
+ makeDgmoError(
3839
+ lineNumber,
3840
+ participantTypeRemovedMessage(typeStr),
3841
+ "error",
3842
+ NAME_DIAGNOSTIC_CODES.PARTICIPANT_TYPE_REMOVED
3843
+ )
3844
+ );
3845
+ continue;
3846
+ }
3986
3847
  const participantType = VALID_PARTICIPANT_TYPES.has(
3987
3848
  typeStr
3988
3849
  ) ? typeStr : "default";
@@ -4283,6 +4144,25 @@ function parseSequenceDgmo(content) {
4283
4144
  }
4284
4145
  continue;
4285
4146
  }
4147
+ const elifMatch = trimmed.match(/^elif\b\s*(.*)$/i);
4148
+ if (elifMatch) {
4149
+ const tailRaw = elifMatch[1].trim();
4150
+ const tail = tailRaw ? " " + tailRaw : "";
4151
+ pushError(
4152
+ lineNumber,
4153
+ `'elif' is not a keyword. Did you mean 'else if${tail}'?`
4154
+ );
4155
+ continue;
4156
+ }
4157
+ const elseLabelMatch = trimmed.match(/^else\s+(.+)$/i);
4158
+ if (elseLabelMatch) {
4159
+ const tail = elseLabelMatch[1].trim();
4160
+ pushError(
4161
+ lineNumber,
4162
+ `'else' does not take a label. Did you mean 'else if ${tail}'?`
4163
+ );
4164
+ continue;
4165
+ }
4286
4166
  {
4287
4167
  const noteParsed = parseNoteLine(
4288
4168
  trimmed,
@@ -4406,7 +4286,7 @@ function looksLikeSequence(content) {
4406
4286
  return ARROW_PATTERN.test(trimmed);
4407
4287
  });
4408
4288
  }
4409
- var KNOWN_SEQ_OPTIONS, KNOWN_SEQ_BOOLEANS, VALID_PARTICIPANT_TYPES, IS_A_PATTERN, POSITION_ONLY_PATTERN, COLORED_PARTICIPANT_PATTERN, GROUP_HEADING_PATTERN, GROUP_HEADING_FALLBACK, LEGACY_GROUP_PATTERN, SECTION_PATTERN, ARROW_PATTERN, NOTE_BARE, NOTE_MULTI;
4289
+ var KNOWN_SEQ_OPTIONS, KNOWN_SEQ_BOOLEANS, VALID_PARTICIPANT_TYPES, REMOVED_PARTICIPANT_TYPES, IS_A_PATTERN, POSITION_ONLY_PATTERN, COLORED_PARTICIPANT_PATTERN, GROUP_HEADING_PATTERN, GROUP_HEADING_FALLBACK, LEGACY_GROUP_PATTERN, SECTION_PATTERN, ARROW_PATTERN, NOTE_BARE, NOTE_MULTI;
4410
4290
  var init_parser = __esm({
4411
4291
  "src/sequence/parser.ts"() {
4412
4292
  "use strict";
@@ -4419,15 +4299,17 @@ var init_parser = __esm({
4419
4299
  KNOWN_SEQ_OPTIONS = /* @__PURE__ */ new Set(["active-tag"]);
4420
4300
  KNOWN_SEQ_BOOLEANS = /* @__PURE__ */ new Set(["activations", "solid-fill", "no-title"]);
4421
4301
  VALID_PARTICIPANT_TYPES = /* @__PURE__ */ new Set([
4422
- "service",
4423
4302
  "database",
4424
4303
  "actor",
4425
4304
  "queue",
4426
- "cache",
4427
- "gateway",
4428
- "external",
4305
+ "cache"
4306
+ ]);
4307
+ REMOVED_PARTICIPANT_TYPES = /* @__PURE__ */ new Set([
4308
+ "service",
4309
+ "frontend",
4429
4310
  "networking",
4430
- "frontend"
4311
+ "gateway",
4312
+ "external"
4431
4313
  ]);
4432
4314
  IS_A_PATTERN = /^([^:]+?)\s+is\s+an?\s+(\w+)(?:\s+(.+))?$/i;
4433
4315
  POSITION_ONLY_PATTERN = /^([^:]+?)\s+position\s+(-?\d+)$/i;
@@ -5321,7 +5203,7 @@ function parseClassDiagram(content, palette) {
5321
5203
  if (trimmed.startsWith("//")) continue;
5322
5204
  if (!contentStarted && indent === 0 && i === 0) {
5323
5205
  const firstLine = parseFirstLine(trimmed);
5324
- if (firstLine && firstLine.chartType === "class") {
5206
+ if (firstLine?.chartType === "class") {
5325
5207
  if (firstLine.title) {
5326
5208
  result.title = firstLine.title;
5327
5209
  result.titleLineNumber = lineNumber;
@@ -5722,7 +5604,7 @@ function parseERDiagram(content, palette) {
5722
5604
  if (trimmed.startsWith("//")) continue;
5723
5605
  if (!firstLineParsed && indent === 0) {
5724
5606
  const firstLineResult = parseFirstLine(trimmed);
5725
- if (firstLineResult && firstLineResult.chartType === "er") {
5607
+ if (firstLineResult?.chartType === "er") {
5726
5608
  firstLineParsed = true;
5727
5609
  if (firstLineResult.title) {
5728
5610
  result.title = firstLineResult.title;
@@ -6654,7 +6536,7 @@ function parseExtendedChart(content, palette) {
6654
6536
  ""
6655
6537
  ) : trimmed;
6656
6538
  const dataRow2 = parseDataRowValues(strippedLine);
6657
- if (dataRow2 && dataRow2.values.length === 1) {
6539
+ if (dataRow2?.values.length === 1) {
6658
6540
  const source = sankeyStack.at(-1).name;
6659
6541
  const linkColor = valColorMatch?.[2] ? resolveColorWithDiagnostic(
6660
6542
  valColorMatch[2].trim(),
@@ -6886,7 +6768,7 @@ function parseExtendedChart(content, palette) {
6886
6768
  }
6887
6769
  }
6888
6770
  const dataRow = parseDataRowValues(trimmed);
6889
- if (dataRow && dataRow.values.length === 1) {
6771
+ if (dataRow?.values.length === 1) {
6890
6772
  const { label: rawLabel, color: pointColor } = extractColor(
6891
6773
  dataRow.label,
6892
6774
  palette
@@ -8934,7 +8816,7 @@ function parseOrg(content, palette) {
8934
8816
  const pushWarning = (line12, message) => {
8935
8817
  result.diagnostics.push(makeDgmoError(line12, message, "warning"));
8936
8818
  };
8937
- if (!content || !content.trim()) {
8819
+ if (!content?.trim()) {
8938
8820
  return fail(0, "No content provided");
8939
8821
  }
8940
8822
  const lines = content.split("\n");
@@ -9231,7 +9113,7 @@ function parseKanban(content, palette) {
9231
9113
  const warn2 = (line12, message) => {
9232
9114
  result.diagnostics.push(makeDgmoError(line12, message, "warning"));
9233
9115
  };
9234
- if (!content || !content.trim()) {
9116
+ if (!content?.trim()) {
9235
9117
  return fail(0, "No content provided");
9236
9118
  }
9237
9119
  const lines = content.split("\n");
@@ -9620,7 +9502,7 @@ function parseC4(content, palette) {
9620
9502
  result.error = formatDgmoError(diag);
9621
9503
  return result;
9622
9504
  };
9623
- if (!content || !content.trim()) {
9505
+ if (!content?.trim()) {
9624
9506
  return fail(0, "No content provided");
9625
9507
  }
9626
9508
  const lines = content.split("\n");
@@ -10371,7 +10253,7 @@ function parseSitemap(content, palette) {
10371
10253
  const pushWarning = (line12, message) => {
10372
10254
  result.diagnostics.push(makeDgmoError(line12, message, "warning"));
10373
10255
  };
10374
- if (!content || !content.trim()) {
10256
+ if (!content?.trim()) {
10375
10257
  return fail(0, "No content provided");
10376
10258
  }
10377
10259
  const lines = content.split("\n");
@@ -13055,7 +12937,7 @@ function parsePert(content, parseOpts = {}) {
13055
12937
  const head = trimmed.slice(0, firstSpace).toLowerCase();
13056
12938
  const value = trimmed.slice(firstSpace + 1).trim();
13057
12939
  const hint = NEAR_DIRECTIVE_HINTS.find((h) => h.stem === head);
13058
- if (hint && hint.matches.test(value)) {
12940
+ if (hint?.matches.test(value)) {
13059
12941
  error(
13060
12942
  lineNumber,
13061
12943
  `Unknown directive '${head}'. Did you mean '${hint.canonical}'?`,
@@ -14362,7 +14244,7 @@ function parseMindmap(content, palette) {
14362
14244
  const pushWarning = (line12, message) => {
14363
14245
  result.diagnostics.push(makeDgmoError(line12, message, "warning"));
14364
14246
  };
14365
- if (!content || !content.trim()) {
14247
+ if (!content?.trim()) {
14366
14248
  return fail(0, "No content provided");
14367
14249
  }
14368
14250
  const lines = content.split("\n");
@@ -14533,7 +14415,7 @@ function parseMindmap(content, palette) {
14533
14415
  const diag = makeDgmoError(1, "No nodes found in mindmap");
14534
14416
  result.diagnostics.push(diag);
14535
14417
  result.error = formatDgmoError(diag);
14536
- } else if (titleRoot && titleRoot.children.length === 0 && result.roots.length === 1 && !result.error) {
14418
+ } else if (titleRoot?.children.length === 0 && result.roots.length === 1 && !result.error) {
14537
14419
  }
14538
14420
  return result;
14539
14421
  }
@@ -14992,7 +14874,7 @@ function parseWireframe(content) {
14992
14874
  const indent = measureIndent(line12);
14993
14875
  if (phase === "header") {
14994
14876
  const firstLineResult = parseFirstLine(trimmed);
14995
- if (firstLineResult && firstLineResult.chartType === "wireframe") {
14877
+ if (firstLineResult?.chartType === "wireframe") {
14996
14878
  title = firstLineResult.title || null;
14997
14879
  titleLineNumber = lineNumber;
14998
14880
  continue;
@@ -15287,7 +15169,7 @@ function parseTechRadar(content) {
15287
15169
  const warn2 = (line12, message) => {
15288
15170
  result.diagnostics.push(makeDgmoError(line12, message, "warning"));
15289
15171
  };
15290
- if (!content || !content.trim()) {
15172
+ if (!content?.trim()) {
15291
15173
  return fail(0, "No content provided");
15292
15174
  }
15293
15175
  function isRingName(name) {
@@ -15324,7 +15206,7 @@ function parseTechRadar(content) {
15324
15206
  if (trimmed.startsWith("//")) continue;
15325
15207
  if (!headerParsed) {
15326
15208
  const firstLine = parseFirstLine(trimmed);
15327
- if (firstLine && firstLine.chartType === "tech-radar") {
15209
+ if (firstLine?.chartType === "tech-radar") {
15328
15210
  result.title = firstLine.title ?? "";
15329
15211
  result.titleLineNumber = lineNumber;
15330
15212
  headerParsed = true;
@@ -15616,7 +15498,7 @@ function parseCycle(content) {
15616
15498
  const indent = measureIndent(raw);
15617
15499
  if (!headerParsed) {
15618
15500
  const firstLineResult = parseFirstLine(trimmed);
15619
- if (firstLineResult && firstLineResult.chartType === "cycle") {
15501
+ if (firstLineResult?.chartType === "cycle") {
15620
15502
  result.title = firstLineResult.title ?? "";
15621
15503
  result.titleLineNumber = lineNum;
15622
15504
  headerParsed = true;
@@ -15840,7 +15722,7 @@ function parseJourneyMap(content, palette) {
15840
15722
  const warn2 = (line12, message) => {
15841
15723
  result.diagnostics.push(makeDgmoError(line12, message, "warning"));
15842
15724
  };
15843
- if (!content || !content.trim()) {
15725
+ if (!content?.trim()) {
15844
15726
  return fail(0, "No content provided");
15845
15727
  }
15846
15728
  const lines = content.split("\n");
@@ -16260,7 +16142,7 @@ function parsePyramid(content) {
16260
16142
  const indent = measureIndent(raw);
16261
16143
  if (!headerParsed) {
16262
16144
  const firstLineResult = parseFirstLine(trimmed);
16263
- if (firstLineResult && firstLineResult.chartType === "pyramid") {
16145
+ if (firstLineResult?.chartType === "pyramid") {
16264
16146
  result.title = firstLineResult.title ?? "";
16265
16147
  result.titleLineNumber = lineNum;
16266
16148
  headerParsed = true;
@@ -16394,7 +16276,7 @@ function parseRing(content) {
16394
16276
  const indent = measureIndent(raw);
16395
16277
  if (!headerParsed) {
16396
16278
  const firstLineResult = parseFirstLine(trimmed);
16397
- if (firstLineResult && firstLineResult.chartType === "ring") {
16279
+ if (firstLineResult?.chartType === "ring") {
16398
16280
  result.title = firstLineResult.title ?? "";
16399
16281
  result.titleLineNumber = lineNum;
16400
16282
  headerParsed = true;
@@ -16841,7 +16723,7 @@ function parseRaci(content, palette) {
16841
16723
  const errorAt = (line12, message, code) => {
16842
16724
  result.diagnostics.push(makeDgmoError(line12, message, "error", code));
16843
16725
  };
16844
- if (!content || !content.trim()) {
16726
+ if (!content?.trim()) {
16845
16727
  return fail(0, "No content provided");
16846
16728
  }
16847
16729
  const lines = content.split("\n");
@@ -17162,7 +17044,7 @@ function parseRaci(content, palette) {
17162
17044
  if (roleId === null) continue;
17163
17045
  if (rolesExplicit) {
17164
17046
  const entry = roleStore.get(roleId);
17165
- if (entry && entry.declaredLine === lineNumber) {
17047
+ if (entry?.declaredLine === lineNumber) {
17166
17048
  const candidates = result.roleDisplayNames.filter(
17167
17049
  (n) => n !== entry.displayName
17168
17050
  );
@@ -23443,8 +23325,7 @@ async function layoutBoxesAndLines(parsed, collapseInfo, layoutOptions) {
23443
23325
  const edge = parsed.edges[i];
23444
23326
  if (edgeParallelCounts[i] === 0) continue;
23445
23327
  const elkEdge = edgeById.get(`e${i}`);
23446
- if (!elkEdge || !elkEdge.sections || elkEdge.sections.length === 0)
23447
- continue;
23328
+ if (!elkEdge?.sections || elkEdge.sections.length === 0) continue;
23448
23329
  const container = elkEdge.container ?? "root";
23449
23330
  const off = containerAbs.get(container) ?? { x: 0, y: 0 };
23450
23331
  const s = elkEdge.sections[0];
@@ -28370,6 +28251,8 @@ function renderNodeShape(g, node, palette, isDark, endTerminalIds, colorOff, sol
28370
28251
  case "document":
28371
28252
  renderDocument(g, node, palette, isDark, colorOff, solid);
28372
28253
  break;
28254
+ default:
28255
+ break;
28373
28256
  }
28374
28257
  }
28375
28258
  function renderFlowchart(container, graph, layout, palette, isDark, onClickItem, exportDims) {
@@ -30940,7 +30823,7 @@ function renderNodes(svg, nodes, palette, isDark, animate, expandedNodeIds, acti
30940
30823
  const badgeText = `${node.computedInstances}x`;
30941
30824
  g.append("text").attr("x", x + node.width - 6).attr("y", y + NODE_HEADER_HEIGHT2 / 2 + META_FONT_SIZE4 * 0.35).attr("text-anchor", "end").attr("font-family", FONT_FAMILY).attr("font-size", META_FONT_SIZE4).attr("fill", textFill).attr("data-instance-node", node.id).style("cursor", "pointer").text(badgeText);
30942
30825
  }
30943
- const showDots = activeGroup != null && activeGroup.toLowerCase() === "capabilities";
30826
+ const showDots = activeGroup?.toLowerCase() === "capabilities";
30944
30827
  const roles = showDots && !node.isEdge ? inferRoles(node.properties) : [];
30945
30828
  if (roles.length > 0) {
30946
30829
  const dotY = isCollapsedGroup ? y + node.height - COLLAPSE_BAR_HEIGHT6 - NODE_PAD_BOTTOM2 / 2 : y + node.height - NODE_PAD_BOTTOM2 / 2;
@@ -31739,7 +31622,7 @@ function analyzePert(parsed) {
31739
31622
  for (const e of edges) {
31740
31623
  if (!e.lag || e.lag.amount >= 0) continue;
31741
31624
  const src = activities.find((a) => a.id === e.source);
31742
- if (!src || !src.duration) continue;
31625
+ if (!src?.duration) continue;
31743
31626
  const leadDays = -toDays(e.lag, sprintDays);
31744
31627
  const srcDurDays = toDays(src.duration.m, sprintDays);
31745
31628
  if (e.type === "FS" && leadDays > srcDurDays) {
@@ -32245,7 +32128,7 @@ function buildSummary(input) {
32245
32128
  const anchor = input.anchor ?? null;
32246
32129
  if (parsedActivities.length === 0) return null;
32247
32130
  if (projectMu === null) {
32248
- if (anchor && anchor.kind === "backward") {
32131
+ if (anchor?.kind === "backward") {
32249
32132
  return [
32250
32133
  { text: "Expected duration: ?", level: 0 },
32251
32134
  { text: "P50 latest-safe start: ?", level: 0 },
@@ -32268,13 +32151,13 @@ function buildSummary(input) {
32268
32151
  const sigmaPositive = projectSigma !== null && projectSigma > 0;
32269
32152
  const showMcDetail = mc && sigmaPositive;
32270
32153
  const sigmaParen = showMcDetail ? ` (\xB1 ${roundForCaption(projectSigma)} ${pluralizeUnit(projectSigma, unit)})` : "";
32271
- if (anchor && anchor.kind === "forward") {
32154
+ if (anchor?.kind === "forward") {
32272
32155
  const projectMuDays = projectMu * unitToDays(unit);
32273
32156
  rows.push({
32274
32157
  text: `Expected finish: ${addCalendarDays(anchor.date, projectMuDays)}${sigmaParen}.`,
32275
32158
  level: 0
32276
32159
  });
32277
- } else if (anchor && anchor.kind === "backward") {
32160
+ } else if (anchor?.kind === "backward") {
32278
32161
  const projectMuDays = projectMu * unitToDays(unit);
32279
32162
  rows.push({
32280
32163
  text: `Expected start: ${addCalendarDays(anchor.date, -projectMuDays)}${sigmaParen}.`,
@@ -32293,13 +32176,13 @@ function buildSummary(input) {
32293
32176
  { pct: 80, days: monteCarloResult.p80 },
32294
32177
  { pct: 95, days: monteCarloResult.p95 }
32295
32178
  ];
32296
- if (anchor && anchor.kind === "forward") {
32179
+ if (anchor?.kind === "forward") {
32297
32180
  for (const { pct, days } of percentiles) {
32298
32181
  const offsetDays = roundConservative(days, "forward");
32299
32182
  const date = addCalendarDays(anchor.date, offsetDays);
32300
32183
  rows.push({ text: `P${pct} finish: ${date}.`, level: 1 });
32301
32184
  }
32302
- } else if (anchor && anchor.kind === "backward") {
32185
+ } else if (anchor?.kind === "backward") {
32303
32186
  for (const { pct, days } of percentiles) {
32304
32187
  const offsetDays = roundConservative(days, "backward");
32305
32188
  const date = addCalendarDays(anchor.date, -offsetDays);
@@ -32343,20 +32226,20 @@ function buildProjectSubtitle(input) {
32343
32226
  const sigmaPositive = projectSigma !== null && projectSigma > 0;
32344
32227
  const sigmaParen = sigmaPositive ? ` (\xB1 ${roundForCaption(projectSigma)})` : "";
32345
32228
  if (projectMu === null) {
32346
- if (anchor && anchor.kind === "forward") {
32229
+ if (anchor?.kind === "forward") {
32347
32230
  return `Expected finish: ? \xB7 \u2248 ? ${pluralizeUnit(2, unit)} of work`;
32348
32231
  }
32349
- if (anchor && anchor.kind === "backward") {
32232
+ if (anchor?.kind === "backward") {
32350
32233
  return `Expected start: ? \xB7 \u2248 ? ${pluralizeUnit(2, unit)} lead time`;
32351
32234
  }
32352
32235
  return `\u2248 ? ${pluralizeUnit(2, unit)}`;
32353
32236
  }
32354
32237
  const muStr = `${roundForCaption(projectMu)} ${pluralizeUnit(projectMu, unit)}`;
32355
- if (anchor && anchor.kind === "forward") {
32238
+ if (anchor?.kind === "forward") {
32356
32239
  const projectMuDays = projectMu * unitToDays(unit);
32357
32240
  return `Expected finish: ${addCalendarDays(anchor.date, projectMuDays)} \xB7 \u2248 ${muStr} of work${sigmaParen}`;
32358
32241
  }
32359
- if (anchor && anchor.kind === "backward") {
32242
+ if (anchor?.kind === "backward") {
32360
32243
  const projectMuDays = projectMu * unitToDays(unit);
32361
32244
  return `Expected start: ${addCalendarDays(anchor.date, -projectMuDays)} \xB7 \u2248 ${muStr} lead time${sigmaParen}`;
32362
32245
  }
@@ -32546,7 +32429,7 @@ function computeNodeSizing(resolved) {
32546
32429
  return { activityWidth, milestoneWidth, outerColW, midColW };
32547
32430
  }
32548
32431
  function nodeDimensions(resolved, id, sizing, overrides) {
32549
- if (overrides && overrides[id]) {
32432
+ if (overrides?.[id]) {
32550
32433
  return { width: overrides[id].width, height: overrides[id].height };
32551
32434
  }
32552
32435
  const r = resolved.activities.find((a) => a.activity.id === id);
@@ -42932,9 +42815,6 @@ function wrapLabelWords(words) {
42932
42815
  function renderRectParticipant(g, palette, isDark, color, solid) {
42933
42816
  g.append("rect").attr("x", -W / 2).attr("y", 0).attr("width", W).attr("height", H).attr("rx", 2).attr("ry", 2).attr("fill", fill(palette, isDark, color, solid)).attr("stroke", stroke(palette, color)).attr("stroke-width", SW);
42934
42817
  }
42935
- function renderServiceParticipant(g, palette, isDark, color, solid) {
42936
- g.append("rect").attr("x", -W / 2).attr("y", 0).attr("width", W).attr("height", H).attr("rx", SERVICE_BORDER_RADIUS).attr("ry", SERVICE_BORDER_RADIUS).attr("fill", fill(palette, isDark, color, solid)).attr("stroke", stroke(palette, color)).attr("stroke-width", SW);
42937
- }
42938
42818
  function renderActorParticipant(g, palette, color) {
42939
42819
  const headR = 8;
42940
42820
  const cx = 0;
@@ -42989,31 +42869,6 @@ function renderCacheParticipant(g, palette, isDark, color, solid) {
42989
42869
  g.append("line").attr("x1", W / 2).attr("y1", topY).attr("x2", W / 2).attr("y2", topY + bodyH).attr("stroke", s).attr("stroke-width", SW).attr("stroke-dasharray", dash);
42990
42870
  g.append("ellipse").attr("cx", 0).attr("cy", topY).attr("rx", W / 2).attr("ry", ry).attr("fill", f).attr("stroke", s).attr("stroke-width", SW).attr("stroke-dasharray", dash);
42991
42871
  }
42992
- function renderNetworkingParticipant(g, palette, isDark, color, solid) {
42993
- const inset = 16;
42994
- const points = [
42995
- `${-W / 2 + inset},0`,
42996
- `${W / 2 - inset},0`,
42997
- `${W / 2},${H / 2}`,
42998
- `${W / 2 - inset},${H}`,
42999
- `${-W / 2 + inset},${H}`,
43000
- `${-W / 2},${H / 2}`
43001
- ].join(" ");
43002
- g.append("polygon").attr("points", points).attr("fill", fill(palette, isDark, color, solid)).attr("stroke", stroke(palette, color)).attr("stroke-width", SW);
43003
- }
43004
- function renderFrontendParticipant(g, palette, isDark, color, solid) {
43005
- const screenH = H - 10;
43006
- const s = stroke(palette, color);
43007
- g.append("rect").attr("x", -W / 2).attr("y", 0).attr("width", W).attr("height", screenH).attr("rx", 3).attr("ry", 3).attr("fill", fill(palette, isDark, color, solid)).attr("stroke", s).attr("stroke-width", SW);
43008
- g.append("line").attr("x1", 0).attr("y1", screenH).attr("x2", 0).attr("y2", H - 2).attr("stroke", s).attr("stroke-width", SW);
43009
- g.append("line").attr("x1", -14).attr("y1", H - 2).attr("x2", 14).attr("y2", H - 2).attr("stroke", s).attr("stroke-width", SW);
43010
- }
43011
- function renderExternalParticipant(g, palette, isDark, color, solid) {
43012
- g.append("rect").attr("x", -W / 2).attr("y", 0).attr("width", W).attr("height", H).attr("rx", 2).attr("ry", 2).attr("fill", fill(palette, isDark, color, solid)).attr("stroke", stroke(palette, color)).attr("stroke-width", SW).attr("stroke-dasharray", "6 3");
43013
- }
43014
- function renderGatewayParticipant(g, palette, isDark, color, _solid) {
43015
- renderRectParticipant(g, palette, isDark, color);
43016
- }
43017
42872
  function groupMessagesBySection(elements, messages) {
43018
42873
  const groups = [];
43019
42874
  let currentGroup = null;
@@ -43652,7 +43507,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
43652
43507
  }
43653
43508
  }
43654
43509
  const lastStep = renderSteps[renderSteps.length - 1];
43655
- const lastIsSelfCall = lastStep && lastStep.type === "call" && lastStep.from === lastStep.to;
43510
+ const lastIsSelfCall = lastStep?.type === "call" && lastStep.from === lastStep.to;
43656
43511
  const lastStepTrailing = lastIsSelfCall ? SELF_CALL_HEIGHT + 25 : stepSpacing;
43657
43512
  let contentBottomY = renderSteps.length > 0 ? Math.max(
43658
43513
  stepYPositions[stepYPositions.length - 1] + lastStepTrailing,
@@ -43826,6 +43681,9 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
43826
43681
  const FRAME_PADDING_X = 30;
43827
43682
  const FRAME_PADDING_BOTTOM = 15;
43828
43683
  const FRAME_LABEL_HEIGHT = 18;
43684
+ const SELF_ARROW_PROJECTION = ACTIVATION_WIDTH / 2 + SELF_CALL_WIDTH;
43685
+ const SELF_ARROW_FRAME_PAD = 10;
43686
+ const frameRightmostX = Math.max(...Array.from(participantX.values()));
43829
43687
  const collectMsgIndices = (els) => {
43830
43688
  const indices = [];
43831
43689
  for (const el of els) {
@@ -43892,16 +43750,40 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
43892
43750
  maxPX = Math.max(maxPX, px);
43893
43751
  }
43894
43752
  }
43895
- const frameX = minPX - FRAME_PADDING_X;
43753
+ let extraLeft = 0;
43754
+ let extraRight = 0;
43755
+ let maxStepIsSelfCall = false;
43756
+ for (const mi of allIndices) {
43757
+ const m = messages[mi];
43758
+ if (m.from === m.to) {
43759
+ const px = participantX.get(m.from);
43760
+ if (px !== void 0) {
43761
+ const flipLeft = px === frameRightmostX;
43762
+ if (flipLeft) {
43763
+ const loopMin = px - SELF_ARROW_PROJECTION;
43764
+ const need = minPX - FRAME_PADDING_X - loopMin + SELF_ARROW_FRAME_PAD;
43765
+ if (need > 0) extraLeft = Math.max(extraLeft, need);
43766
+ } else {
43767
+ const loopMax = px + SELF_ARROW_PROJECTION;
43768
+ const need = loopMax - (maxPX + FRAME_PADDING_X) + SELF_ARROW_FRAME_PAD;
43769
+ if (need > 0) extraRight = Math.max(extraRight, need);
43770
+ }
43771
+ }
43772
+ if (msgToLastStep.get(mi) === maxStep) {
43773
+ maxStepIsSelfCall = true;
43774
+ }
43775
+ }
43776
+ }
43777
+ const frameX = minPX - FRAME_PADDING_X - extraLeft;
43896
43778
  const frameY = stepY(minStep) - FRAME_PADDING_TOP;
43897
- const frameW = maxPX - minPX + FRAME_PADDING_X * 2;
43898
- const frameH = stepY(maxStep) - stepY(minStep) + FRAME_PADDING_TOP + FRAME_PADDING_BOTTOM;
43779
+ const frameW = maxPX - minPX + FRAME_PADDING_X * 2 + extraLeft + extraRight;
43780
+ const frameH = stepY(maxStep) - stepY(minStep) + FRAME_PADDING_TOP + FRAME_PADDING_BOTTOM + (maxStepIsSelfCall ? SELF_CALL_HEIGHT : 0);
43899
43781
  svg.append("rect").attr("x", frameX).attr("y", frameY).attr("width", frameW).attr("height", frameH).attr("fill", "none").attr("stroke", palette.textMuted).attr("stroke-width", 1).attr("stroke-dasharray", "2 3").attr("rx", 3).attr("ry", 3).attr("class", "block-frame").attr("data-block-line", String(el.lineNumber));
43900
43782
  deferredLabels.push({
43901
43783
  x: frameX + 6,
43902
43784
  y: frameY + FRAME_LABEL_HEIGHT - 4,
43903
43785
  text: `${el.type} ${el.label}`,
43904
- bold: true,
43786
+ bold: false,
43905
43787
  italic: false,
43906
43788
  blockLine: el.lineNumber
43907
43789
  });
@@ -43927,7 +43809,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
43927
43809
  y: dividerY + 14,
43928
43810
  text: `else if ${branchData.label}`,
43929
43811
  bold: false,
43930
- italic: true,
43812
+ italic: false,
43931
43813
  blockLine: branchData.lineNumber
43932
43814
  });
43933
43815
  }
@@ -43954,7 +43836,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
43954
43836
  y: dividerY + 14,
43955
43837
  text: "else",
43956
43838
  bold: false,
43957
- italic: true,
43839
+ italic: false,
43958
43840
  blockLine: el.elseLineNumber
43959
43841
  });
43960
43842
  }
@@ -44024,7 +43906,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
44024
43906
  return side === "right" ? px + ACTIVATION_WIDTH / 2 + offset : px - ACTIVATION_WIDTH / 2 + offset;
44025
43907
  };
44026
43908
  const leftmostX = Math.min(...Array.from(participantX.values()));
44027
- const rightmostX = Math.max(...Array.from(participantX.values()));
43909
+ const rightmostX = frameRightmostX;
44028
43910
  const sectionLineX1 = leftmostX - PARTICIPANT_BOX_WIDTH / 2 - 10;
44029
43911
  const sectionLineX2 = rightmostX + PARTICIPANT_BOX_WIDTH / 2 + 10;
44030
43912
  for (const region of sectionRegions) {
@@ -44283,27 +44165,12 @@ function renderParticipant(svg, participant, cx, cy, palette, isDark, color, tag
44283
44165
  case "database":
44284
44166
  renderDatabaseParticipant(g, palette, isDark, color, solid);
44285
44167
  break;
44286
- case "service":
44287
- renderServiceParticipant(g, palette, isDark, color, solid);
44288
- break;
44289
44168
  case "queue":
44290
44169
  renderQueueParticipant(g, palette, isDark, color, solid);
44291
44170
  break;
44292
44171
  case "cache":
44293
44172
  renderCacheParticipant(g, palette, isDark, color, solid);
44294
44173
  break;
44295
- case "networking":
44296
- renderNetworkingParticipant(g, palette, isDark, color, solid);
44297
- break;
44298
- case "frontend":
44299
- renderFrontendParticipant(g, palette, isDark, color, solid);
44300
- break;
44301
- case "external":
44302
- renderExternalParticipant(g, palette, isDark, color, solid);
44303
- break;
44304
- case "gateway":
44305
- renderGatewayParticipant(g, palette, isDark, color, solid);
44306
- break;
44307
44174
  default:
44308
44175
  renderRectParticipant(g, palette, isDark, color, solid);
44309
44176
  break;
@@ -44331,7 +44198,7 @@ function renderParticipant(svg, participant, cx, cy, palette, isDark, color, tag
44331
44198
  });
44332
44199
  }
44333
44200
  }
44334
- var d3Selection21, PARTICIPANT_GAP, PARTICIPANT_BOX_WIDTH, PARTICIPANT_BOX_HEIGHT, TOP_MARGIN, TITLE_HEIGHT8, PARTICIPANT_Y_OFFSET, SERVICE_BORDER_RADIUS, MESSAGE_START_OFFSET, LIFELINE_TAIL, ARROWHEAD_SIZE, NOTE_MAX_W, NOTE_FOLD, NOTE_PAD_H, NOTE_PAD_V, NOTE_FONT_SIZE, NOTE_LINE_H, NOTE_GAP, NOTE_CHAR_W, NOTE_CHARS_PER_LINE, ACTIVATION_WIDTH, SELF_CALL_HEIGHT, SELF_CALL_WIDTH, NOTE_LANE_MAX, LABEL_CHAR_WIDTH, LABEL_MAX_CHARS, fill, stroke, SW, W, H;
44201
+ var d3Selection21, PARTICIPANT_GAP, PARTICIPANT_BOX_WIDTH, PARTICIPANT_BOX_HEIGHT, TOP_MARGIN, TITLE_HEIGHT8, PARTICIPANT_Y_OFFSET, MESSAGE_START_OFFSET, LIFELINE_TAIL, ARROWHEAD_SIZE, NOTE_MAX_W, NOTE_FOLD, NOTE_PAD_H, NOTE_PAD_V, NOTE_FONT_SIZE, NOTE_LINE_H, NOTE_GAP, NOTE_CHAR_W, NOTE_CHARS_PER_LINE, ACTIVATION_WIDTH, SELF_CALL_HEIGHT, SELF_CALL_WIDTH, NOTE_LANE_MAX, LABEL_CHAR_WIDTH, LABEL_MAX_CHARS, fill, stroke, SW, W, H;
44335
44202
  var init_renderer19 = __esm({
44336
44203
  "src/sequence/renderer.ts"() {
44337
44204
  "use strict";
@@ -44353,7 +44220,6 @@ var init_renderer19 = __esm({
44353
44220
  TOP_MARGIN = 20;
44354
44221
  TITLE_HEIGHT8 = 30;
44355
44222
  PARTICIPANT_Y_OFFSET = 10;
44356
- SERVICE_BORDER_RADIUS = 10;
44357
44223
  MESSAGE_START_OFFSET = 30;
44358
44224
  LIFELINE_TAIL = 30;
44359
44225
  ARROWHEAD_SIZE = 8;
@@ -44545,7 +44411,7 @@ function parseVisualization(content, palette) {
44545
44411
  const warn2 = (line12, message) => {
44546
44412
  result.diagnostics.push(makeDgmoError(line12, message, "warning"));
44547
44413
  };
44548
- if (!content || !content.trim()) {
44414
+ if (!content?.trim()) {
44549
44415
  return fail(0, "Empty content");
44550
44416
  }
44551
44417
  const lines = content.split("\n");
@@ -46585,7 +46451,7 @@ function renderTimelineTagLegendOverlay(container, parsed, palette, isDark, setu
46585
46451
  const groupKey = groupName.toLowerCase();
46586
46452
  groupEl.attr("data-tag-group", groupKey);
46587
46453
  if (isActive && !viewMode) {
46588
- const isSwimActive = currentSwimlaneGroup != null && currentSwimlaneGroup.toLowerCase() === groupKey;
46454
+ const isSwimActive = currentSwimlaneGroup?.toLowerCase() === groupKey;
46589
46455
  const pillWidth3 = measureLegendText(groupName, LG_PILL_FONT_SIZE) + LG_PILL_PAD;
46590
46456
  const pillXOff = LG_CAPSULE_PAD;
46591
46457
  const iconX = pillXOff + pillWidth3 + 5;
@@ -50706,7 +50572,7 @@ pre.dgmo, code.language-dgmo, pre > code.language-dgmo,
50706
50572
 
50707
50573
  // src/auto/index.ts
50708
50574
  init_safe_href();
50709
- var VERSION = "0.16.0";
50575
+ var VERSION = "0.17.0";
50710
50576
  var DEFAULTS = {
50711
50577
  theme: "auto",
50712
50578
  palette: "nord",
@@ -50854,7 +50720,7 @@ function resolveTheme(theme) {
50854
50720
  function ensureStyles() {
50855
50721
  if (typeof document === "undefined") return;
50856
50722
  const html = document.documentElement;
50857
- if (html && html.dataset && html.dataset[STYLE_FLAG] === "1") return;
50723
+ if (html?.dataset?.[STYLE_FLAG] === "1") return;
50858
50724
  const linked = document.querySelector(
50859
50725
  'link[rel="stylesheet"][href*="auto.css"]'
50860
50726
  );
@@ -51010,7 +50876,7 @@ function deriveAriaLabel(source) {
51010
50876
  function determineReplaceTarget(matched) {
51011
50877
  if (matched.tagName === "CODE") {
51012
50878
  const parent = matched.parentElement;
51013
- if (parent && parent.tagName === "PRE") {
50879
+ if (parent?.tagName === "PRE") {
51014
50880
  const meaningfulChildren = Array.from(parent.childNodes).filter(
51015
50881
  (n) => n.nodeType === 1 || n.nodeType === 3 && (n.textContent || "").trim().length > 0
51016
50882
  );