retold-data-service 2.1.0 → 2.1.2

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 (25) hide show
  1. package/.github/workflows/publish-image.yml +66 -0
  2. package/BUILDING-AND-PUBLISHING.md +140 -0
  3. package/Dockerfile +21 -0
  4. package/package.json +25 -16
  5. package/source/services/comprehension-loader/pict-app/providers/Pict-Provider-ComprehensionLoader.js +2 -2
  6. package/source/services/comprehension-loader/pict-app/views/PictView-ComprehensionLoader-Layout.js +43 -43
  7. package/source/services/comprehension-loader/pict-app/views/PictView-ComprehensionLoader-Load.js +14 -14
  8. package/source/services/comprehension-loader/pict-app/views/PictView-ComprehensionLoader-Schema.js +3 -3
  9. package/source/services/comprehension-loader/pict-app/views/PictView-ComprehensionLoader-Session.js +2 -2
  10. package/source/services/comprehension-loader/pict-app/views/PictView-ComprehensionLoader-Source.js +7 -7
  11. package/source/services/comprehension-loader/web/comprehension-loader.js +77 -77
  12. package/source/services/comprehension-loader/web/comprehension-loader.min.js +1 -1
  13. package/source/services/data-cloner/pict-app/providers/Pict-Provider-DataCloner.js +3 -3
  14. package/source/services/data-cloner/pict-app/views/PictView-DataCloner-Connection.js +1 -1
  15. package/source/services/data-cloner/pict-app/views/PictView-DataCloner-Deploy.js +5 -5
  16. package/source/services/data-cloner/pict-app/views/PictView-DataCloner-Export.js +11 -11
  17. package/source/services/data-cloner/pict-app/views/PictView-DataCloner-Layout.js +53 -53
  18. package/source/services/data-cloner/pict-app/views/PictView-DataCloner-Schema.js +3 -3
  19. package/source/services/data-cloner/pict-app/views/PictView-DataCloner-Session.js +2 -2
  20. package/source/services/data-cloner/pict-app/views/PictView-DataCloner-Sync.js +22 -22
  21. package/source/services/data-cloner/pict-app/views/PictView-DataCloner-ViewData.js +4 -4
  22. package/source/services/data-cloner/web/data-cloner.js +110 -108
  23. package/source/services/data-cloner/web/data-cloner.js.map +1 -1
  24. package/source/services/data-cloner/web/data-cloner.min.js +1 -1
  25. package/source/services/data-cloner/web/data-cloner.min.js.map +1 -1
@@ -215,7 +215,7 @@ module.exports.default_configuration =
215
215
  </div>
216
216
 
217
217
  <details style="margin-bottom:10px">
218
- <summary style="cursor:pointer; font-size:0.9em; color:#666">Advanced Session Options</summary>
218
+ <summary style="cursor:pointer; font-size:0.9em; color:var(--theme-color-text-secondary, #666)">Advanced Session Options</summary>
219
219
  <div style="padding:10px 0">
220
220
  <label for="authURI">Authentication URI Template (leave blank for default)</label>
221
221
  <input type="text" id="authURI" placeholder="Authenticate/{~D:Record.UserName~}/{~D:Record.Password~}">
@@ -235,7 +235,7 @@ module.exports.default_configuration =
235
235
  <button class="primary" onclick="pict.views['ComprehensionLoader-Session'].configureSession()">Configure Session</button>
236
236
  <div id="sessionConfigStatus"></div>
237
237
 
238
- <hr style="margin:16px 0; border:none; border-top:1px solid #eee">
238
+ <hr style="margin:16px 0; border:none; border-top:1px solid var(--theme-color-border-light, #eee)">
239
239
 
240
240
  <div class="inline-group">
241
241
  <div>
@@ -189,8 +189,8 @@ class ComprehensionLoaderSourceView extends libPictView
189
189
  if (!tmpContainer) return;
190
190
 
191
191
  let tmpHtml = '<table style="width:100%; border-collapse:collapse; margin-top:8px; font-size:0.9em">';
192
- tmpHtml += '<thead><tr><th style="text-align:left; padding:6px 12px; border-bottom:2px solid #ddd">Entity</th>';
193
- tmpHtml += '<th style="text-align:right; padding:6px 12px; border-bottom:2px solid #ddd">Records</th></tr></thead>';
192
+ tmpHtml += '<thead><tr><th style="text-align:left; padding:6px 12px; border-bottom:2px solid var(--theme-color-border-default, #ddd)">Entity</th>';
193
+ tmpHtml += '<th style="text-align:right; padding:6px 12px; border-bottom:2px solid var(--theme-color-border-default, #ddd)">Records</th></tr></thead>';
194
194
  tmpHtml += '<tbody>';
195
195
 
196
196
  let tmpEntityList = pResult.EntityList || [];
@@ -200,8 +200,8 @@ class ComprehensionLoaderSourceView extends libPictView
200
200
  let tmpName = tmpEntityList[i];
201
201
  let tmpCount = tmpRecordCounts[tmpName] || 0;
202
202
  tmpHtml += '<tr>';
203
- tmpHtml += '<td style="padding:4px 12px; border-bottom:1px solid #f0f0f0">' + this.pict.providers.ComprehensionLoader.escapeHtml(tmpName) + '</td>';
204
- tmpHtml += '<td style="padding:4px 12px; border-bottom:1px solid #f0f0f0; text-align:right; font-variant-numeric:tabular-nums">' + this.pict.providers.ComprehensionLoader.formatNumber(tmpCount) + '</td>';
203
+ tmpHtml += '<td style="padding:4px 12px; border-bottom:1px solid var(--theme-color-background-tertiary, #f0f0f0)">' + this.pict.providers.ComprehensionLoader.escapeHtml(tmpName) + '</td>';
204
+ tmpHtml += '<td style="padding:4px 12px; border-bottom:1px solid var(--theme-color-background-tertiary, #f0f0f0); text-align:right; font-variant-numeric:tabular-nums">' + this.pict.providers.ComprehensionLoader.formatNumber(tmpCount) + '</td>';
205
205
  tmpHtml += '</tr>';
206
206
  }
207
207
 
@@ -287,11 +287,11 @@ module.exports.default_configuration =
287
287
  <div style="display:flex; gap:16px; align-items:center">
288
288
  <label style="font-weight:normal; margin:0; cursor:pointer">
289
289
  <input type="radio" name="comprehensionSourceMode" id="sourceMode_url" value="url" checked onchange="pict.views['ComprehensionLoader-Source'].onSourceModeChange()"> URL
290
- <span style="color:#888; font-size:0.85em">(fetch from a URL)</span>
290
+ <span style="color:var(--theme-color-text-muted, #888); font-size:0.85em">(fetch from a URL)</span>
291
291
  </label>
292
292
  <label style="font-weight:normal; margin:0; cursor:pointer">
293
293
  <input type="radio" name="comprehensionSourceMode" id="sourceMode_file" value="file" onchange="pict.views['ComprehensionLoader-Source'].onSourceModeChange()"> File Upload
294
- <span style="color:#888; font-size:0.85em">(load JSON from local files)</span>
294
+ <span style="color:var(--theme-color-text-muted, #888); font-size:0.85em">(load JSON from local files)</span>
295
295
  </label>
296
296
  </div>
297
297
  </div>
@@ -305,7 +305,7 @@ module.exports.default_configuration =
305
305
  <div id="sourceFileSection" style="display:none">
306
306
  <label for="comprehensionFiles">Comprehension JSON File(s)</label>
307
307
  <input type="file" id="comprehensionFiles" multiple accept=".json" style="margin-bottom:10px">
308
- <div style="font-size:0.8em; color:#888; margin-bottom:10px">Multiple files will be merged (entity keys combined).</div>
308
+ <div style="font-size:0.8em; color:var(--theme-color-text-muted, #888); margin-bottom:10px">Multiple files will be merged (entity keys combined).</div>
309
309
  <button class="primary" onclick="pict.views['ComprehensionLoader-Source'].loadFromFiles()">Load Files</button>
310
310
  </div>
311
311
 
@@ -1971,7 +1971,7 @@
1971
1971
  .pict-histogram-value-label
1972
1972
  {
1973
1973
  text-align: center;
1974
- color: #666;
1974
+ color: var(--theme-color-text-secondary, #666);
1975
1975
  font-size: 11px;
1976
1976
  padding: 2px 0;
1977
1977
  white-space: nowrap;
@@ -1983,7 +1983,7 @@
1983
1983
  .pict-histogram-bin-label
1984
1984
  {
1985
1985
  text-align: center;
1986
- color: #333;
1986
+ color: var(--theme-color-text-primary, #333);
1987
1987
  font-size: 11px;
1988
1988
  padding: 4px 2px 0 2px;
1989
1989
  white-space: nowrap;
@@ -2018,7 +2018,7 @@
2018
2018
  left: 0;
2019
2019
  right: 0;
2020
2020
  height: 4px;
2021
- background: #E0E0E0;
2021
+ background: var(--theme-color-border-default, #E0E0E0);
2022
2022
  border-radius: 2px;
2023
2023
  }
2024
2024
  .pict-histogram-horizontal .pict-histogram-range-track
@@ -2051,7 +2051,7 @@
2051
2051
  top: 4px;
2052
2052
  width: 16px;
2053
2053
  height: 16px;
2054
- background: #fff;
2054
+ background: var(--theme-color-background-panel, #fff);
2055
2055
  border: 2px solid #4A90D9;
2056
2056
  border-radius: 50%;
2057
2057
  cursor: grab;
@@ -2097,7 +2097,7 @@
2097
2097
  {
2098
2098
  width: 100%;
2099
2099
  height: 1px;
2100
- background: #ccc;
2100
+ background: var(--theme-color-border-default, #ccc);
2101
2101
  }
2102
2102
  .pict-histogram-label-row
2103
2103
  {
@@ -2107,7 +2107,7 @@
2107
2107
  .pict-histogram-fill-label
2108
2108
  {
2109
2109
  font-size: 10px;
2110
- color: #666;
2110
+ color: var(--theme-color-text-secondary, #666);
2111
2111
  text-align: center;
2112
2112
  white-space: nowrap;
2113
2113
  overflow: visible;
@@ -5393,9 +5393,9 @@
5393
5393
  }
5394
5394
  if (tmpHtml === '') {
5395
5395
  if (tmpIsLive) {
5396
- tmpHtml = '<div style="font-size:0.9em; color:#888; padding:8px 0">Load in progress, waiting for entity data\u2026</div>';
5396
+ tmpHtml = '<div style="font-size:0.9em; color:var(--theme-color-text-muted, #888); padding:8px 0">Load in progress, waiting for entity data\u2026</div>';
5397
5397
  } else {
5398
- tmpHtml = '<div style="font-size:0.9em; color:#888; padding:8px 0">No load data available. Run a load to see operation details here.</div>';
5398
+ tmpHtml = '<div style="font-size:0.9em; color:var(--theme-color-text-muted, #888); padding:8px 0">No load data available. Run a load to see operation details here.</div>';
5399
5399
  }
5400
5400
  }
5401
5401
  tmpContainer.innerHTML = tmpHtml;
@@ -5615,11 +5615,11 @@
5615
5615
  DefaultDestinationAddress: '#ComprehensionLoader-Application-Container',
5616
5616
  CSS: /*css*/`
5617
5617
  * { box-sizing: border-box; margin: 0; padding: 0; }
5618
- body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: #f5f5f5; color: #333; padding: 20px; }
5619
- h1 { margin-bottom: 20px; color: #1a1a1a; }
5620
- h2 { margin-bottom: 12px; color: #444; font-size: 1.2em; border-bottom: 2px solid #ddd; padding-bottom: 6px; }
5618
+ body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: var(--theme-color-background-secondary, #f5f5f5); color: var(--theme-color-text-primary, #333); padding: 20px; }
5619
+ h1 { margin-bottom: 20px; color: var(--theme-color-text-primary, #1a1a1a); }
5620
+ h2 { margin-bottom: 12px; color: var(--theme-color-text-secondary, #444); font-size: 1.2em; border-bottom: 2px solid var(--theme-color-border-default, #ddd); padding-bottom: 6px; }
5621
5621
 
5622
- .section { background: #fff; border-radius: 8px; padding: 20px; margin-bottom: 16px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }
5622
+ .section { background: var(--theme-color-background-panel, #fff); border-radius: 8px; padding: 20px; margin-bottom: 16px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }
5623
5623
 
5624
5624
  /* Accordion layout */
5625
5625
  .accordion-row { display: flex; gap: 0; margin-bottom: 16px; align-items: stretch; }
@@ -5629,25 +5629,25 @@ h2 { margin-bottom: 12px; color: #444; font-size: 1.2em; border-bottom: 2px soli
5629
5629
  user-select: none;
5630
5630
  }
5631
5631
  .accordion-card {
5632
- flex: 1; background: #fff; border-radius: 8px; box-shadow: 0 1px 3px rgba(0,0,0,0.1);
5632
+ flex: 1; background: var(--theme-color-background-panel, #fff); border-radius: 8px; box-shadow: 0 1px 3px rgba(0,0,0,0.1);
5633
5633
  overflow: hidden; min-width: 0;
5634
5634
  }
5635
5635
  .accordion-header {
5636
5636
  display: flex; align-items: center; padding: 14px 20px; cursor: pointer;
5637
5637
  user-select: none; gap: 12px; transition: background 0.15s; line-height: 1.4;
5638
5638
  }
5639
- .accordion-header:hover { background: #fafafa; }
5640
- .accordion-title { font-weight: 600; color: #333; font-size: 1.05em; white-space: nowrap; }
5641
- .accordion-preview { flex: 1; font-style: italic; color: #888; font-size: 0.9em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
5639
+ .accordion-header:hover { background: var(--theme-color-background-secondary, #fafafa); }
5640
+ .accordion-title { font-weight: 600; color: var(--theme-color-text-primary, #333); font-size: 1.05em; white-space: nowrap; }
5641
+ .accordion-preview { flex: 1; font-style: italic; color: var(--theme-color-text-muted, #888); font-size: 0.9em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
5642
5642
  .accordion-toggle {
5643
5643
  flex: 0 0 20px; display: flex; align-items: center; justify-content: center;
5644
- border-radius: 4px; transition: background 0.15s, transform 0.25s; font-size: 0.7em; color: #888;
5644
+ border-radius: 4px; transition: background 0.15s, transform 0.25s; font-size: 0.7em; color: var(--theme-color-text-muted, #888);
5645
5645
  }
5646
- .accordion-header:hover .accordion-toggle { background: #eee; color: #555; }
5646
+ .accordion-header:hover .accordion-toggle { background: var(--theme-color-border-light, #eee); color: var(--theme-color-text-secondary, #555); }
5647
5647
  .accordion-card.open .accordion-toggle { transform: rotate(180deg); }
5648
5648
  .accordion-body { padding: 0 20px 20px; display: none; }
5649
5649
  .accordion-card.open .accordion-body { display: block; }
5650
- .accordion-card.open .accordion-header { border-bottom: 1px solid #eee; }
5650
+ .accordion-card.open .accordion-header { border-bottom: 1px solid var(--theme-color-border-light, #eee); }
5651
5651
  .accordion-card.open .accordion-preview { display: none; }
5652
5652
 
5653
5653
  /* Action controls (go link + auto checkbox) */
@@ -5660,13 +5660,13 @@ h2 { margin-bottom: 12px; color: #444; font-size: 1.2em; border-bottom: 2px soli
5660
5660
  }
5661
5661
  .accordion-go:hover { background: #e8f0fe; text-decoration: underline; }
5662
5662
  .accordion-auto {
5663
- font-size: 0.82em; color: #999; white-space: nowrap; cursor: pointer;
5663
+ font-size: 0.82em; color: var(--theme-color-text-muted, #999); white-space: nowrap; cursor: pointer;
5664
5664
  }
5665
5665
  .accordion-auto .auto-label { display: none; }
5666
5666
  .accordion-auto:hover .auto-label { display: inline; }
5667
5667
  .accordion-auto input[type="checkbox"] { width: auto; margin: 0; cursor: pointer; vertical-align: middle; position: relative; top: 0px; opacity: 0.75; transition: opacity 0.15s; }
5668
5668
  .accordion-auto:hover input[type="checkbox"] { opacity: 1; }
5669
- .accordion-auto:hover { color: #666; }
5669
+ .accordion-auto:hover { color: var(--theme-color-text-secondary, #666); }
5670
5670
 
5671
5671
  /* Phase status indicator */
5672
5672
  .accordion-phase {
@@ -5674,12 +5674,12 @@ h2 { margin-bottom: 12px; color: #444; font-size: 1.2em; border-bottom: 2px soli
5674
5674
  font-size: 0.85em; line-height: 1;
5675
5675
  }
5676
5676
  .accordion-phase.visible { display: flex; }
5677
- .accordion-phase-ok { color: #28a745; }
5677
+ .accordion-phase-ok { color: var(--theme-color-status-success, #28a745); }
5678
5678
  .accordion-phase-error { color: #dc3545; }
5679
- .accordion-phase-busy { color: #28a745; }
5679
+ .accordion-phase-busy { color: var(--theme-color-status-success, #28a745); }
5680
5680
  .accordion-phase-busy .phase-spinner {
5681
5681
  display: inline-block; width: 14px; height: 14px;
5682
- border: 2px solid #28a745; border-top-color: transparent; border-radius: 50%;
5682
+ border: 2px solid var(--theme-color-status-success, #28a745); border-top-color: transparent; border-radius: 50%;
5683
5683
  animation: phase-spin 0.8s linear infinite; vertical-align: middle;
5684
5684
  }
5685
5685
  @keyframes phase-spin {
@@ -5691,13 +5691,13 @@ h2 { margin-bottom: 12px; color: #444; font-size: 1.2em; border-bottom: 2px soli
5691
5691
  }
5692
5692
  .accordion-controls button {
5693
5693
  padding: 4px 10px; font-size: 0.82em; font-weight: 500; background: none;
5694
- border: 1px solid #ccc; border-radius: 4px; color: #666; cursor: pointer; margin: 0;
5694
+ border: 1px solid var(--theme-color-border-default, #ccc); border-radius: 4px; color: var(--theme-color-text-secondary, #666); cursor: pointer; margin: 0;
5695
5695
  }
5696
- .accordion-controls button:hover { background: #f0f0f0; border-color: #aaa; color: #333; }
5696
+ .accordion-controls button:hover { background: var(--theme-color-background-tertiary, #f0f0f0); border-color: var(--theme-color-text-muted, #aaa); color: var(--theme-color-text-primary, #333); }
5697
5697
 
5698
5698
  label { display: block; font-weight: 600; margin-bottom: 4px; font-size: 0.9em; }
5699
5699
  input[type="text"], input[type="password"], input[type="number"] {
5700
- width: 100%; padding: 8px 12px; border: 1px solid #ccc; border-radius: 4px;
5700
+ width: 100%; padding: 8px 12px; border: 1px solid var(--theme-color-border-default, #ccc); border-radius: 4px;
5701
5701
  font-size: 0.95em; margin-bottom: 10px;
5702
5702
  }
5703
5703
  input[type="text"]:focus, input[type="password"]:focus, input[type="number"]:focus {
@@ -5708,13 +5708,13 @@ button {
5708
5708
  padding: 8px 16px; border: none; border-radius: 4px; cursor: pointer;
5709
5709
  font-size: 0.9em; font-weight: 600; margin-right: 8px; margin-bottom: 8px;
5710
5710
  }
5711
- button.primary { background: #4a90d9; color: #fff; }
5711
+ button.primary { background: #4a90d9; color: var(--theme-color-background-panel, #fff); }
5712
5712
  button.primary:hover { background: #357abd; }
5713
- button.secondary { background: #6c757d; color: #fff; }
5713
+ button.secondary { background: #6c757d; color: var(--theme-color-background-panel, #fff); }
5714
5714
  button.secondary:hover { background: #5a6268; }
5715
- button.danger { background: #dc3545; color: #fff; }
5715
+ button.danger { background: #dc3545; color: var(--theme-color-background-panel, #fff); }
5716
5716
  button.danger:hover { background: #c82333; }
5717
- button.success { background: #28a745; color: #fff; }
5717
+ button.success { background: var(--theme-color-status-success, #28a745); color: var(--theme-color-background-panel, #fff); }
5718
5718
  button.success:hover { background: #218838; }
5719
5719
  button:disabled { opacity: 0.5; cursor: not-allowed; }
5720
5720
 
@@ -5729,7 +5729,7 @@ button:disabled { opacity: 0.5; cursor: not-allowed; }
5729
5729
 
5730
5730
  a { color: #4a90d9; }
5731
5731
 
5732
- select { background: #fff; width: 100%; padding: 8px 12px; border: 1px solid #ccc; border-radius: 4px; font-size: 0.95em; margin-bottom: 10px; }
5732
+ select { background: var(--theme-color-background-panel, #fff); width: 100%; padding: 8px 12px; border: 1px solid var(--theme-color-border-default, #ccc); border-radius: 4px; font-size: 0.95em; margin-bottom: 10px; }
5733
5733
 
5734
5734
  .checkbox-row { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
5735
5735
  .checkbox-row input[type="checkbox"] { width: auto; margin: 0; }
@@ -5737,16 +5737,16 @@ select { background: #fff; width: 100%; padding: 8px 12px; border: 1px solid #cc
5737
5737
 
5738
5738
  /* Live Status Bar */
5739
5739
  .live-status-bar {
5740
- background: #fff; border-radius: 8px; margin-bottom: 16px;
5740
+ background: var(--theme-color-background-panel, #fff); border-radius: 8px; margin-bottom: 16px;
5741
5741
  box-shadow: 0 1px 3px rgba(0,0,0,0.1);
5742
5742
  position: sticky; top: 0; z-index: 100; border-left: 4px solid #6c757d;
5743
5743
  }
5744
5744
  .live-status-bar.phase-idle { border-left-color: #6c757d; }
5745
5745
  .live-status-bar.phase-disconnected { border-left-color: #dc3545; }
5746
5746
  .live-status-bar.phase-ready { border-left-color: #4a90d9; }
5747
- .live-status-bar.phase-loading { border-left-color: #28a745; }
5747
+ .live-status-bar.phase-loading { border-left-color: var(--theme-color-status-success, #28a745); }
5748
5748
  .live-status-bar.phase-stopping { border-left-color: #ffc107; }
5749
- .live-status-bar.phase-complete { border-left-color: #28a745; }
5749
+ .live-status-bar.phase-complete { border-left-color: var(--theme-color-status-success, #28a745); }
5750
5750
 
5751
5751
  .live-status-dot {
5752
5752
  width: 12px; height: 12px; border-radius: 50%; flex-shrink: 0;
@@ -5756,34 +5756,34 @@ select { background: #fff; width: 100%; padding: 8px 12px; border: 1px solid #cc
5756
5756
  .live-status-bar.phase-disconnected .live-status-dot { background: #dc3545; }
5757
5757
  .live-status-bar.phase-ready .live-status-dot { background: #4a90d9; }
5758
5758
  .live-status-bar.phase-loading .live-status-dot {
5759
- background: #28a745;
5759
+ background: var(--theme-color-status-success, #28a745);
5760
5760
  animation: live-pulse 1.5s ease-in-out infinite;
5761
5761
  }
5762
5762
  .live-status-bar.phase-stopping .live-status-dot {
5763
5763
  background: #ffc107;
5764
5764
  animation: live-pulse 0.8s ease-in-out infinite;
5765
5765
  }
5766
- .live-status-bar.phase-complete .live-status-dot { background: #28a745; }
5766
+ .live-status-bar.phase-complete .live-status-dot { background: var(--theme-color-status-success, #28a745); }
5767
5767
 
5768
5768
  @keyframes live-pulse {
5769
5769
  0%, 100% { opacity: 1; transform: scale(1); }
5770
5770
  50% { opacity: 0.4; transform: scale(0.8); }
5771
5771
  }
5772
5772
 
5773
- .live-status-message { flex: 1; font-size: 0.92em; color: #333; line-height: 1.4; }
5773
+ .live-status-message { flex: 1; font-size: 0.92em; color: var(--theme-color-text-primary, #333); line-height: 1.4; }
5774
5774
 
5775
5775
  .live-status-meta {
5776
- display: flex; gap: 16px; flex-shrink: 0; font-size: 0.82em; color: #666;
5776
+ display: flex; gap: 16px; flex-shrink: 0; font-size: 0.82em; color: var(--theme-color-text-secondary, #666);
5777
5777
  }
5778
5778
  .live-status-meta-item { white-space: nowrap; }
5779
- .live-status-meta-item strong { color: #333; }
5779
+ .live-status-meta-item strong { color: var(--theme-color-text-primary, #333); }
5780
5780
 
5781
5781
  .live-status-progress-bar {
5782
5782
  height: 3px; background: #e9ecef; border-radius: 2px; overflow: hidden;
5783
5783
  position: absolute; bottom: 0; left: 0; right: 0;
5784
5784
  }
5785
5785
  .live-status-progress-fill {
5786
- height: 100%; background: #28a745; transition: width 1s ease;
5786
+ height: 100%; background: var(--theme-color-status-success, #28a745); transition: width 1s ease;
5787
5787
  }
5788
5788
  /* Expandable status bar */
5789
5789
  .live-status-header {
@@ -5795,7 +5795,7 @@ select { background: #fff; width: 100%; padding: 8px 12px; border: 1px solid #cc
5795
5795
  }
5796
5796
  .live-status-expand-toggle {
5797
5797
  flex: 0 0 20px; display: flex; align-items: center; justify-content: center;
5798
- font-size: 0.7em; color: #888; transition: transform 0.25s;
5798
+ font-size: 0.7em; color: var(--theme-color-text-muted, #888); transition: transform 0.25s;
5799
5799
  }
5800
5800
  .live-status-bar.expanded .live-status-expand-toggle { transform: rotate(180deg); }
5801
5801
 
@@ -5807,9 +5807,9 @@ select { background: #fff; width: 100%; padding: 8px 12px; border: 1px solid #cc
5807
5807
  .status-detail-section { margin-bottom: 14px; }
5808
5808
  .status-detail-section:last-child { margin-bottom: 0; }
5809
5809
  .status-detail-section-title {
5810
- font-size: 0.85em; font-weight: 600; color: #555; text-transform: uppercase;
5810
+ font-size: 0.85em; font-weight: 600; color: var(--theme-color-text-secondary, #555); text-transform: uppercase;
5811
5811
  letter-spacing: 0.5px; margin-bottom: 8px; padding-bottom: 4px;
5812
- border-bottom: 1px solid #eee;
5812
+ border-bottom: 1px solid var(--theme-color-border-light, #eee);
5813
5813
  }
5814
5814
 
5815
5815
  /* Running Operations */
@@ -5823,26 +5823,26 @@ select { background: #fff; width: 100%; padding: 8px 12px; border: 1px solid #cc
5823
5823
  min-width: 120px;
5824
5824
  }
5825
5825
  .running-op-bar-fill { height: 100%; background: #4a90d9; transition: width 0.5s ease; }
5826
- .running-op-count { font-size: 0.85em; color: #666; white-space: nowrap; }
5827
- .running-op-pending { color: #888; font-size: 0.85em; font-style: italic; padding: 4px 0; }
5826
+ .running-op-count { font-size: 0.85em; color: var(--theme-color-text-secondary, #666); white-space: nowrap; }
5827
+ .running-op-pending { color: var(--theme-color-text-muted, #888); font-size: 0.85em; font-style: italic; padding: 4px 0; }
5828
5828
 
5829
5829
  /* Completed Operations */
5830
- .completed-op-row { padding: 8px 0; border-bottom: 1px solid #f0f0f0; }
5830
+ .completed-op-row { padding: 8px 0; border-bottom: 1px solid var(--theme-color-background-tertiary, #f0f0f0); }
5831
5831
  .completed-op-row:last-child { border-bottom: none; }
5832
5832
  .completed-op-header {
5833
5833
  display: flex; align-items: center; gap: 10px; font-size: 0.9em; margin-bottom: 4px;
5834
5834
  }
5835
5835
  .completed-op-name { font-weight: 600; }
5836
- .completed-op-stats { color: #666; font-size: 0.85em; }
5837
- .completed-op-checkmark { color: #28a745; }
5836
+ .completed-op-stats { color: var(--theme-color-text-secondary, #666); font-size: 0.85em; }
5837
+ .completed-op-checkmark { color: var(--theme-color-status-success, #28a745); }
5838
5838
 
5839
5839
  /* Error Operations */
5840
- .error-op-row { padding: 6px 0; border-bottom: 1px solid #f0f0f0; font-size: 0.9em; }
5840
+ .error-op-row { padding: 6px 0; border-bottom: 1px solid var(--theme-color-background-tertiary, #f0f0f0); font-size: 0.9em; }
5841
5841
  .error-op-row:last-child { border-bottom: none; }
5842
5842
  .error-op-header { display: flex; align-items: center; gap: 8px; }
5843
5843
  .error-op-name { font-weight: 600; color: #dc3545; }
5844
5844
  .error-op-status { font-size: 0.82em; color: #dc3545; }
5845
- .error-op-message { font-size: 0.82em; color: #888; margin-top: 2px; padding-left: 18px; }
5845
+ .error-op-message { font-size: 0.82em; color: var(--theme-color-text-muted, #888); margin-top: 2px; padding-left: 18px; }
5846
5846
  `,
5847
5847
  Templates: [{
5848
5848
  Hash: 'ComprehensionLoader-Layout',
@@ -5991,12 +5991,12 @@ select { background: #fff; width: 100%; padding: 8px 12px; border: 1px solid #cc
5991
5991
  let tmpDurationStr = tmpDurationSec < 60 ? tmpDurationSec + 's' : Math.floor(tmpDurationSec / 60) + 'm ' + tmpDurationSec % 60 + 's';
5992
5992
  let tmpTotalPushed = this.pict.providers.ComprehensionLoader.formatNumber(pReport.Summary.TotalPushed);
5993
5993
  let tmpTotalRecords = this.pict.providers.ComprehensionLoader.formatNumber(pReport.Summary.TotalRecords);
5994
- tmpCardsContainer.innerHTML = '' + '<div class="report-card ' + tmpOutcomeClass + '">' + ' <div class="card-label">Outcome</div>' + ' <div class="card-value" style="color:' + tmpOutcomeColor + '">' + pReport.Outcome + '</div>' + '</div>' + '<div class="report-card">' + ' <div class="card-label">Duration</div>' + ' <div class="card-value">' + tmpDurationStr + '</div>' + '</div>' + '<div class="report-card">' + ' <div class="card-label">Entities</div>' + ' <div class="card-value">' + pReport.Summary.Complete + ' / ' + pReport.Summary.TotalEntities + '</div>' + '</div>' + '<div class="report-card">' + ' <div class="card-label">Records Pushed</div>' + ' <div class="card-value">' + tmpTotalPushed + '</div>' + ' <div style="font-size:0.75em; color:#888">of ' + tmpTotalRecords + '</div>' + '</div>';
5994
+ tmpCardsContainer.innerHTML = '' + '<div class="report-card ' + tmpOutcomeClass + '">' + ' <div class="card-label">Outcome</div>' + ' <div class="card-value" style="color:' + tmpOutcomeColor + '">' + pReport.Outcome + '</div>' + '</div>' + '<div class="report-card">' + ' <div class="card-label">Duration</div>' + ' <div class="card-value">' + tmpDurationStr + '</div>' + '</div>' + '<div class="report-card">' + ' <div class="card-label">Entities</div>' + ' <div class="card-value">' + pReport.Summary.Complete + ' / ' + pReport.Summary.TotalEntities + '</div>' + '</div>' + '<div class="report-card">' + ' <div class="card-label">Records Pushed</div>' + ' <div class="card-value">' + tmpTotalPushed + '</div>' + ' <div style="font-size:0.75em; color:var(--theme-color-text-muted, #888)">of ' + tmpTotalRecords + '</div>' + '</div>';
5995
5995
 
5996
5996
  // Anomalies
5997
5997
  let tmpAnomalyContainer = document.getElementById('reportAnomalies');
5998
5998
  if (pReport.Anomalies.length === 0) {
5999
- tmpAnomalyContainer.innerHTML = '<div style="color:#28a745; font-weight:600; font-size:0.9em">No anomalies detected.</div>';
5999
+ tmpAnomalyContainer.innerHTML = '<div style="color:var(--theme-color-status-success, #28a745); font-weight:600; font-size:0.9em">No anomalies detected.</div>';
6000
6000
  } else {
6001
6001
  let tmpHtml = '<h4 style="margin:0 0 8px; color:#dc3545; font-size:0.95em">Anomalies (' + pReport.Anomalies.length + ')</h4>';
6002
6002
  tmpHtml += '<table class="progress-table">';
@@ -6017,7 +6017,7 @@ select { background: #fff; width: 100%; padding: 8px 12px; border: 1px solid #cc
6017
6017
  // Entity details
6018
6018
  let tmpEntityContainer = document.getElementById('reportEntityDetails');
6019
6019
  if (pReport.Entities && pReport.Entities.length > 0) {
6020
- let tmpHtml = '<h4 style="margin:0 0 8px; font-size:0.95em; color:#444">Entity Details</h4>';
6020
+ let tmpHtml = '<h4 style="margin:0 0 8px; font-size:0.95em; color:var(--theme-color-text-secondary, #444)">Entity Details</h4>';
6021
6021
  tmpHtml += '<table class="progress-table">';
6022
6022
  tmpHtml += '<tr><th>Entity</th><th>Duration</th><th>Records</th><th>Status</th></tr>';
6023
6023
  for (let i = 0; i < pReport.Entities.length; i++) {
@@ -6181,22 +6181,22 @@ select { background: #fff; width: 100%; padding: 8px 12px; border: 1px solid #cc
6181
6181
  DefaultDestinationAddress: '#ComprehensionLoader-Section-Load',
6182
6182
  CSS: /*css*/`
6183
6183
  .progress-table { width: 100%; border-collapse: collapse; margin-top: 4px; margin-bottom: 4px; }
6184
- .progress-table th, .progress-table td { text-align: left; padding: 6px 12px; border-bottom: 1px solid #eee; font-size: 0.9em; }
6184
+ .progress-table th, .progress-table td { text-align: left; padding: 6px 12px; border-bottom: 1px solid var(--theme-color-border-light, #eee); font-size: 0.9em; }
6185
6185
  .progress-table th { background: #f8f9fa; font-weight: 600; }
6186
- .progress-table-muted td { color: #888; padding: 3px 12px; font-size: 0.85em; border-bottom: 1px solid #f4f5f6; }
6186
+ .progress-table-muted td { color: var(--theme-color-text-muted, #888); padding: 3px 12px; font-size: 0.85em; border-bottom: 1px solid #f4f5f6; }
6187
6187
  .progress-bar-container { width: 120px; height: 16px; background: #e9ecef; border-radius: 8px; overflow: hidden; display: inline-block; vertical-align: middle; }
6188
- .progress-bar-fill { height: 100%; background: #28a745; transition: width 0.3s; }
6189
- .sync-section-header { font-size: 0.8em; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; color: #4a90d9; padding: 10px 0 2px 0; margin-top: 6px; border-top: 1px solid #e0e0e0; }
6188
+ .progress-bar-fill { height: 100%; background: var(--theme-color-status-success, #28a745); transition: width 0.3s; }
6189
+ .sync-section-header { font-size: 0.8em; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; color: #4a90d9; padding: 10px 0 2px 0; margin-top: 6px; border-top: 1px solid var(--theme-color-border-default, #e0e0e0); }
6190
6190
  .sync-section-header:first-child { border-top: none; margin-top: 10px; }
6191
6191
  .sync-section-header-error { color: #dc3545; }
6192
- .sync-section-header-ok { color: #28a745; }
6193
- .sync-section-count { font-weight: 400; color: #999; font-size: 0.95em; }
6194
- .sync-section-overflow { font-size: 0.8em; color: #aaa; padding: 2px 12px 6px; }
6195
- .sync-pending-count { text-align: right; color: #aaa; font-size: 0.85em; }
6192
+ .sync-section-header-ok { color: var(--theme-color-status-success, #28a745); }
6193
+ .sync-section-count { font-weight: 400; color: var(--theme-color-text-muted, #999); font-size: 0.95em; }
6194
+ .sync-section-overflow { font-size: 0.8em; color: var(--theme-color-text-muted, #aaa); padding: 2px 12px 6px; }
6195
+ .sync-pending-count { text-align: right; color: var(--theme-color-text-muted, #aaa); font-size: 0.85em; }
6196
6196
  .report-card { background: #f8f9fa; border-radius: 8px; padding: 12px 16px; min-width: 140px; text-align: center; border: 1px solid #e9ecef; }
6197
- .report-card .card-label { font-size: 0.8em; color: #666; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 4px; }
6197
+ .report-card .card-label { font-size: 0.8em; color: var(--theme-color-text-secondary, #666); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 4px; }
6198
6198
  .report-card .card-value { font-size: 1.4em; font-weight: 700; }
6199
- .report-card.outcome-success { border-left: 4px solid #28a745; }
6199
+ .report-card.outcome-success { border-left: 4px solid var(--theme-color-status-success, #28a745); }
6200
6200
  .report-card.outcome-partial { border-left: 4px solid #ffc107; }
6201
6201
  .report-card.outcome-error { border-left: 4px solid #dc3545; }
6202
6202
  .report-card.outcome-stopped { border-left: 4px solid #6c757d; }
@@ -6227,7 +6227,7 @@ select { background: #fff; width: 100%; padding: 8px 12px; border: 1px solid #cc
6227
6227
  <div id="loadProgress"></div>
6228
6228
 
6229
6229
  <!-- Load Report (appears after load completes) -->
6230
- <div id="loadReportSection" style="display:none; margin-top:16px; padding-top:16px; border-top:2px solid #ddd">
6230
+ <div id="loadReportSection" style="display:none; margin-top:16px; padding-top:16px; border-top:2px solid var(--theme-color-border-default, #ddd)">
6231
6231
  <h3 style="margin:0 0 12px; font-size:1.1em">Load Report</h3>
6232
6232
 
6233
6233
  <div id="reportSummaryCards" style="display:flex; gap:12px; flex-wrap:wrap; margin-bottom:16px"></div>
@@ -6289,12 +6289,12 @@ select { background: #fff; width: 100%; padding: 8px 12px; border: 1px solid #cc
6289
6289
  let tmpContainer = document.getElementById('entityList');
6290
6290
  if (!tmpContainer) return;
6291
6291
  if (tmpEntities.length === 0) {
6292
- tmpContainer.innerHTML = '<div style="color:#888; font-size:0.9em">No entities found.</div>';
6292
+ tmpContainer.innerHTML = '<div style="color:var(--theme-color-text-muted, #888); font-size:0.9em">No entities found.</div>';
6293
6293
  return;
6294
6294
  }
6295
- let tmpHtml = '<div style="font-size:0.9em; color:#555">';
6295
+ let tmpHtml = '<div style="font-size:0.9em; color:var(--theme-color-text-secondary, #555)">';
6296
6296
  for (let i = 0; i < tmpEntities.length; i++) {
6297
- tmpHtml += '<span style="display:inline-block; background:#f0f0f0; border-radius:4px; padding:2px 8px; margin:2px 4px 2px 0; font-size:0.9em">';
6297
+ tmpHtml += '<span style="display:inline-block; background:var(--theme-color-background-tertiary, #f0f0f0); border-radius:4px; padding:2px 8px; margin:2px 4px 2px 0; font-size:0.9em">';
6298
6298
  tmpHtml += this.pict.providers.ComprehensionLoader.escapeHtml(tmpEntities[i]);
6299
6299
  tmpHtml += '</span>';
6300
6300
  }
@@ -6490,7 +6490,7 @@ select { background: #fff; width: 100%; padding: 8px 12px; border: 1px solid #cc
6490
6490
  </div>
6491
6491
 
6492
6492
  <details style="margin-bottom:10px">
6493
- <summary style="cursor:pointer; font-size:0.9em; color:#666">Advanced Session Options</summary>
6493
+ <summary style="cursor:pointer; font-size:0.9em; color:var(--theme-color-text-secondary, #666)">Advanced Session Options</summary>
6494
6494
  <div style="padding:10px 0">
6495
6495
  <label for="authURI">Authentication URI Template (leave blank for default)</label>
6496
6496
  <input type="text" id="authURI" placeholder="Authenticate/{~D:Record.UserName~}/{~D:Record.Password~}">
@@ -6510,7 +6510,7 @@ select { background: #fff; width: 100%; padding: 8px 12px; border: 1px solid #cc
6510
6510
  <button class="primary" onclick="pict.views['ComprehensionLoader-Session'].configureSession()">Configure Session</button>
6511
6511
  <div id="sessionConfigStatus"></div>
6512
6512
 
6513
- <hr style="margin:16px 0; border:none; border-top:1px solid #eee">
6513
+ <hr style="margin:16px 0; border:none; border-top:1px solid var(--theme-color-border-light, #eee)">
6514
6514
 
6515
6515
  <div class="inline-group">
6516
6516
  <div>
@@ -6674,8 +6674,8 @@ select { background: #fff; width: 100%; padding: 8px 12px; border: 1px solid #cc
6674
6674
  let tmpContainer = document.getElementById('comprehensionSummary');
6675
6675
  if (!tmpContainer) return;
6676
6676
  let tmpHtml = '<table style="width:100%; border-collapse:collapse; margin-top:8px; font-size:0.9em">';
6677
- tmpHtml += '<thead><tr><th style="text-align:left; padding:6px 12px; border-bottom:2px solid #ddd">Entity</th>';
6678
- tmpHtml += '<th style="text-align:right; padding:6px 12px; border-bottom:2px solid #ddd">Records</th></tr></thead>';
6677
+ tmpHtml += '<thead><tr><th style="text-align:left; padding:6px 12px; border-bottom:2px solid var(--theme-color-border-default, #ddd)">Entity</th>';
6678
+ tmpHtml += '<th style="text-align:right; padding:6px 12px; border-bottom:2px solid var(--theme-color-border-default, #ddd)">Records</th></tr></thead>';
6679
6679
  tmpHtml += '<tbody>';
6680
6680
  let tmpEntityList = pResult.EntityList || [];
6681
6681
  let tmpRecordCounts = pResult.RecordCounts || {};
@@ -6683,8 +6683,8 @@ select { background: #fff; width: 100%; padding: 8px 12px; border: 1px solid #cc
6683
6683
  let tmpName = tmpEntityList[i];
6684
6684
  let tmpCount = tmpRecordCounts[tmpName] || 0;
6685
6685
  tmpHtml += '<tr>';
6686
- tmpHtml += '<td style="padding:4px 12px; border-bottom:1px solid #f0f0f0">' + this.pict.providers.ComprehensionLoader.escapeHtml(tmpName) + '</td>';
6687
- tmpHtml += '<td style="padding:4px 12px; border-bottom:1px solid #f0f0f0; text-align:right; font-variant-numeric:tabular-nums">' + this.pict.providers.ComprehensionLoader.formatNumber(tmpCount) + '</td>';
6686
+ tmpHtml += '<td style="padding:4px 12px; border-bottom:1px solid var(--theme-color-background-tertiary, #f0f0f0)">' + this.pict.providers.ComprehensionLoader.escapeHtml(tmpName) + '</td>';
6687
+ tmpHtml += '<td style="padding:4px 12px; border-bottom:1px solid var(--theme-color-background-tertiary, #f0f0f0); text-align:right; font-variant-numeric:tabular-nums">' + this.pict.providers.ComprehensionLoader.formatNumber(tmpCount) + '</td>';
6688
6688
  tmpHtml += '</tr>';
6689
6689
  }
6690
6690
  tmpHtml += '</tbody>';
@@ -6749,11 +6749,11 @@ select { background: #fff; width: 100%; padding: 8px 12px; border: 1px solid #cc
6749
6749
  <div style="display:flex; gap:16px; align-items:center">
6750
6750
  <label style="font-weight:normal; margin:0; cursor:pointer">
6751
6751
  <input type="radio" name="comprehensionSourceMode" id="sourceMode_url" value="url" checked onchange="pict.views['ComprehensionLoader-Source'].onSourceModeChange()"> URL
6752
- <span style="color:#888; font-size:0.85em">(fetch from a URL)</span>
6752
+ <span style="color:var(--theme-color-text-muted, #888); font-size:0.85em">(fetch from a URL)</span>
6753
6753
  </label>
6754
6754
  <label style="font-weight:normal; margin:0; cursor:pointer">
6755
6755
  <input type="radio" name="comprehensionSourceMode" id="sourceMode_file" value="file" onchange="pict.views['ComprehensionLoader-Source'].onSourceModeChange()"> File Upload
6756
- <span style="color:#888; font-size:0.85em">(load JSON from local files)</span>
6756
+ <span style="color:var(--theme-color-text-muted, #888); font-size:0.85em">(load JSON from local files)</span>
6757
6757
  </label>
6758
6758
  </div>
6759
6759
  </div>
@@ -6767,7 +6767,7 @@ select { background: #fff; width: 100%; padding: 8px 12px; border: 1px solid #cc
6767
6767
  <div id="sourceFileSection" style="display:none">
6768
6768
  <label for="comprehensionFiles">Comprehension JSON File(s)</label>
6769
6769
  <input type="file" id="comprehensionFiles" multiple accept=".json" style="margin-bottom:10px">
6770
- <div style="font-size:0.8em; color:#888; margin-bottom:10px">Multiple files will be merged (entity keys combined).</div>
6770
+ <div style="font-size:0.8em; color:var(--theme-color-text-muted, #888); margin-bottom:10px">Multiple files will be merged (entity keys combined).</div>
6771
6771
  <button class="primary" onclick="pict.views['ComprehensionLoader-Source'].loadFromFiles()">Load Files</button>
6772
6772
  </div>
6773
6773