@papaemmelab/isabl-web 0.3.45-beta.1 → 0.3.45-beta.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.
@@ -14679,7 +14679,7 @@ ___CSS_LOADER_EXPORT___.push([module.id, ".matrix-legend[data-v-4c88fa7c]{paddin
14679
14679
 
14680
14680
  /***/ }),
14681
14681
 
14682
- /***/ 1579:
14682
+ /***/ 31571:
14683
14683
  /***/ (function(module, __webpack_exports__, __webpack_require__) {
14684
14684
 
14685
14685
  "use strict";
@@ -14693,7 +14693,7 @@ __webpack_require__.r(__webpack_exports__);
14693
14693
 
14694
14694
  var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));
14695
14695
  // Module
14696
- ___CSS_LOADER_EXPORT___.push([module.id, ".project-matrix[data-v-2742f691]{height:100%;min-height:400px}.loading-container[data-v-2742f691],.project-matrix[data-v-2742f691]{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.loading-container[data-v-2742f691]{-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;min-height:300px}.filter-spacer[data-v-2742f691]{height:16px;background:#fff}.matrix-scroll-container[data-v-2742f691]{-webkit-box-flex:1;-ms-flex:1;flex:1;overflow:auto;max-height:calc(80vh - 180px)}.no-matches-message[data-v-2742f691]{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;padding:24px;color:#666;font-size:13px}.matrix-table[data-v-2742f691]{border-collapse:separate;border-spacing:0;table-layout:fixed}.header-row[data-v-2742f691]{display:grid;grid-template-columns:200px repeat(var(--col-count),50px);position:sticky;top:0;z-index:10;background:#fff;min-width:-webkit-fit-content;min-width:-moz-fit-content;min-width:fit-content}.corner-cell[data-v-2742f691]{position:sticky;left:0;z-index:11;border-right:2px solid #5b5dff;width:200px;-webkit-box-sizing:border-box;box-sizing:border-box}.corner-cell[data-v-2742f691],.header-cell[data-v-2742f691]{background:#fff;border-bottom:2px solid #5b5dff;height:130px}.header-cell[data-v-2742f691]{position:relative;width:50px;overflow:visible;cursor:pointer}.header-cell:hover .header-text[data-v-2742f691]{background:#fff6db;border-radius:2px}.header-cell.column-highlighted .header-text[data-v-2742f691]{background:#fff0d9;border-radius:2px;font-weight:700;color:#000}.header-text[data-v-2742f691]{position:absolute;bottom:8px;left:50%;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);-webkit-transform-origin:bottom left;transform-origin:bottom left;white-space:nowrap;font-size:11px;font-weight:500;color:#333;z-index:1}td.row-header[data-v-2742f691]{position:sticky;left:0;z-index:1;background:#fff;border-right:2px solid #5b5dff;padding:0 8px;width:200px;min-width:200px;max-width:200px;height:24px;border-bottom:1px solid #e0e0e0;cursor:pointer;vertical-align:middle;-webkit-box-sizing:border-box;box-sizing:border-box}.row-header.row-highlighted[data-v-2742f691]{background:#ffe8c5!important}.row-header.row-highlighted .system-id[data-v-2742f691]{font-weight:700;color:#000}.system-id[data-v-2742f691]{font-size:11px;font-family:monospace;color:#333;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.row-header[data-v-2742f691]:hover{background:#fff0d9}.row-header:hover .system-id[data-v-2742f691]{font-weight:600}td.matrix-cell[data-v-2742f691]{width:50px;min-width:50px;max-width:50px;height:24px;border-right:1px solid #e0e0e0;border-bottom:1px solid #e0e0e0;cursor:default;background:#fafafa;padding:0;vertical-align:middle;-webkit-box-sizing:border-box;box-sizing:border-box}.matrix-cell.has-analyses[data-v-2742f691]{cursor:pointer;background:#fff}.matrix-cell.cell-selected[data-v-2742f691],.matrix-cell.has-analyses[data-v-2742f691]:hover{border-right-color:#5b5dff;border-bottom-color:#5b5dff;background:#f0f0ff}.matrix-cell.cell-highlighted[data-v-2742f691]{background:#ffe8c5}.cell-stripes[data-v-2742f691]{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;gap:1px;height:100%;width:100%;padding:2px 4px}.stripe[data-v-2742f691]{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:3px;min-width:2px;max-width:5px;border-radius:1px}.cell-count-badge[data-v-2742f691]{width:100%;color:#fff;font-weight:600;text-shadow:0 0 2px rgba(0,0,0,.3)}.cell-count-badge[data-v-2742f691],.empty-cell[data-v-2742f691]{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;height:100%;font-size:10px}.empty-cell[data-v-2742f691]{color:#ccc}.native-tooltip[data-v-2742f691]{position:fixed;-webkit-transform:translateX(-50%) translateY(-100%);transform:translateX(-50%) translateY(-100%);z-index:9999;background:#fff;border-radius:4px;-webkit-box-shadow:0 2px 8px rgba(0,0,0,.2);box-shadow:0 2px 8px rgba(0,0,0,.2);min-width:280px;max-width:350px;max-height:300px;overflow-y:auto}.native-tooltip[data-v-2742f691] .tooltip-header{padding:8px 12px;background:#f5f5f5;font-weight:500;font-size:13px;border-bottom:1px solid #e0e0e0}.native-tooltip[data-v-2742f691] .tooltip-list{padding:4px 0}.native-tooltip[data-v-2742f691] .tooltip-item{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:6px 12px;cursor:pointer;font-size:12px}.native-tooltip[data-v-2742f691] .tooltip-item:hover{background:#e3f2fd}.native-tooltip[data-v-2742f691] .tooltip-item .status-dot{width:8px;height:8px;border-radius:50%;margin-right:8px;-ms-flex-negative:0;flex-shrink:0}.native-tooltip[data-v-2742f691] .tooltip-item .analysis-pk{color:#1976d2;font-weight:500}.native-tooltip[data-v-2742f691] .tooltip-item .sep{margin:0 6px;color:#999}.native-tooltip[data-v-2742f691] .tooltip-item .version{color:#666}.native-tooltip[data-v-2742f691] .tooltip-item .assembly{color:#999}.native-tooltip[data-v-2742f691] .tooltip-item .status-chip{margin-left:auto;padding:2px 6px;border-radius:3px;color:#fff;font-size:10px;font-weight:500}.native-tooltip[data-v-2742f691] .experiment-group-header{padding:6px 12px 4px;font-size:11px;font-weight:600;color:#1976d2;background:#f8f9fa;border-top:1px solid #e0e0e0;font-family:monospace}.native-tooltip[data-v-2742f691] .experiment-group-header:first-child{border-top:none}", ""]);
14696
+ ___CSS_LOADER_EXPORT___.push([module.id, ".project-matrix[data-v-28c10d94]{height:100%;min-height:400px}.loading-container[data-v-28c10d94],.project-matrix[data-v-28c10d94]{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.loading-container[data-v-28c10d94]{-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;min-height:300px}.filter-spacer[data-v-28c10d94]{height:16px;background:#fff}.matrix-scroll-container[data-v-28c10d94]{-webkit-box-flex:1;-ms-flex:1;flex:1;overflow:auto;max-height:calc(80vh - 180px)}.no-matches-message[data-v-28c10d94]{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;padding:24px;color:#666;font-size:13px}.matrix-table[data-v-28c10d94]{border-collapse:separate;border-spacing:0;table-layout:fixed}.header-row[data-v-28c10d94]{display:grid;grid-template-columns:200px repeat(var(--col-count),50px);position:sticky;top:0;z-index:10;background:#fff;min-width:-webkit-fit-content;min-width:-moz-fit-content;min-width:fit-content}.corner-cell[data-v-28c10d94]{position:sticky;left:0;z-index:11;border-right:2px solid #5b5dff;width:200px;-webkit-box-sizing:border-box;box-sizing:border-box}.corner-cell[data-v-28c10d94],.header-cell[data-v-28c10d94]{background:#fff;border-bottom:2px solid #5b5dff;height:130px}.header-cell[data-v-28c10d94]{position:relative;width:50px;overflow:visible;cursor:pointer}.header-cell:hover .header-text[data-v-28c10d94]{background:#fff6db;border-radius:2px}.header-cell.column-highlighted .header-text[data-v-28c10d94]{background:#fff0d9;border-radius:2px;font-weight:700;color:#000}.header-text[data-v-28c10d94]{position:absolute;bottom:8px;left:50%;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);-webkit-transform-origin:bottom left;transform-origin:bottom left;white-space:nowrap;font-size:11px;font-weight:500;color:#333;z-index:1}td.row-header[data-v-28c10d94]{position:sticky;left:0;z-index:1;background:#fff;border-right:2px solid #5b5dff;padding:0 8px;width:200px;min-width:200px;max-width:200px;height:24px;border-bottom:1px solid #e0e0e0;cursor:pointer;vertical-align:middle;-webkit-box-sizing:border-box;box-sizing:border-box}.row-header.row-highlighted[data-v-28c10d94]{background:#ffe8c5!important}.row-header.row-highlighted .system-id[data-v-28c10d94]{font-weight:700;color:#000}.system-id[data-v-28c10d94]{font-size:11px;font-family:monospace;color:#333;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.row-header[data-v-28c10d94]:hover{background:#fff0d9}.row-header:hover .system-id[data-v-28c10d94]{font-weight:600}td.matrix-cell[data-v-28c10d94]{width:50px;min-width:50px;max-width:50px;height:24px;border-right:1px solid #e0e0e0;border-bottom:1px solid #e0e0e0;cursor:default;background:#fafafa;padding:0;vertical-align:middle;-webkit-box-sizing:border-box;box-sizing:border-box}.matrix-cell.has-analyses[data-v-28c10d94]{cursor:pointer;background:#fff}.matrix-cell.cell-selected[data-v-28c10d94],.matrix-cell.has-analyses[data-v-28c10d94]:hover{border-right-color:#5b5dff;border-bottom-color:#5b5dff;background:#f0f0ff}.matrix-cell.cell-highlighted[data-v-28c10d94]{background:#ffe8c5}.cell-stripes[data-v-28c10d94]{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;gap:1px;height:100%;width:100%;padding:2px 4px}.stripe[data-v-28c10d94]{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:3px;min-width:2px;max-width:5px;border-radius:1px}.cell-count-badge[data-v-28c10d94]{width:100%;color:#fff;font-weight:600;text-shadow:0 0 2px rgba(0,0,0,.3)}.cell-count-badge[data-v-28c10d94],.empty-cell[data-v-28c10d94]{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;height:100%;font-size:10px}.empty-cell[data-v-28c10d94]{color:#ccc}.native-tooltip[data-v-28c10d94]{position:fixed;-webkit-transform:translateX(-50%) translateY(-100%);transform:translateX(-50%) translateY(-100%);z-index:9999;background:#fff;border-radius:4px;-webkit-box-shadow:0 2px 8px rgba(0,0,0,.2);box-shadow:0 2px 8px rgba(0,0,0,.2);min-width:280px;max-width:350px;max-height:300px;overflow-y:auto}.native-tooltip[data-v-28c10d94] .tooltip-header{padding:8px 12px;background:#f5f5f5;font-weight:500;font-size:13px;border-bottom:1px solid #e0e0e0}.native-tooltip[data-v-28c10d94] .tooltip-list{padding:4px 0}.native-tooltip[data-v-28c10d94] .tooltip-item{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:6px 12px;cursor:pointer;font-size:12px}.native-tooltip[data-v-28c10d94] .tooltip-item:hover{background:#e3f2fd}.native-tooltip[data-v-28c10d94] .tooltip-item .status-dot{width:8px;height:8px;border-radius:50%;margin-right:8px;-ms-flex-negative:0;flex-shrink:0}.native-tooltip[data-v-28c10d94] .tooltip-item .analysis-pk{color:#1976d2;font-weight:500}.native-tooltip[data-v-28c10d94] .tooltip-item .sep{margin:0 6px;color:#999}.native-tooltip[data-v-28c10d94] .tooltip-item .version{color:#666}.native-tooltip[data-v-28c10d94] .tooltip-item .assembly{color:#999}.native-tooltip[data-v-28c10d94] .tooltip-item .status-chip{margin-left:auto;padding:2px 6px;border-radius:3px;color:#fff;font-size:10px;font-weight:500}.native-tooltip[data-v-28c10d94] .experiment-group-header{padding:6px 12px 4px;font-size:11px;font-weight:600;color:#1976d2;background:#f8f9fa;border-top:1px solid #e0e0e0;font-family:monospace}.native-tooltip[data-v-28c10d94] .experiment-group-header:first-child{border-top:none}", ""]);
14697
14697
  // Exports
14698
14698
  /* harmony default export */ __webpack_exports__["default"] = (___CSS_LOADER_EXPORT___);
14699
14699
 
@@ -97316,19 +97316,19 @@ var update = add("689c5232", content, true, {"sourceMap":false,"shadowMode":fals
97316
97316
 
97317
97317
  /***/ }),
97318
97318
 
97319
- /***/ 16679:
97319
+ /***/ 77240:
97320
97320
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
97321
97321
 
97322
97322
  // style-loader: Adds some css to the DOM by adding a <style> tag
97323
97323
 
97324
97324
  // load the styles
97325
- var content = __webpack_require__(1579);
97325
+ var content = __webpack_require__(31571);
97326
97326
  if(content.__esModule) content = content.default;
97327
97327
  if(typeof content === 'string') content = [[module.id, content, '']];
97328
97328
  if(content.locals) module.exports = content.locals;
97329
97329
  // add the styles to the DOM
97330
97330
  var add = (__webpack_require__(54402)/* ["default"] */ .Z)
97331
- var update = add("6ecf86c4", content, true, {"sourceMap":false,"shadowMode":false});
97331
+ var update = add("909263a8", content, true, {"sourceMap":false,"shadowMode":false});
97332
97332
 
97333
97333
  /***/ }),
97334
97334
 
@@ -329929,10 +329929,10 @@ var ProjectMatrixModalvue_type_template_id_6865373b_scoped_true_staticRenderFns
329929
329929
 
329930
329930
  ;// CONCATENATED MODULE: ./src/components/projects/ProjectMatrixModal.vue?vue&type=template&id=6865373b&scoped=true&
329931
329931
 
329932
- ;// CONCATENATED MODULE: ./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./src/components/projects/ProjectMatrix.vue?vue&type=template&id=2742f691&scoped=true&
329932
+ ;// CONCATENATED MODULE: ./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./src/components/projects/ProjectMatrix.vue?vue&type=template&id=28c10d94&scoped=true&
329933
329933
  var cov_geimehe8j = function () {
329934
329934
  var path = "/Users/havasove/Desktop/repos/isabl_matrix/isabl_web/src/components/projects/ProjectMatrix.vue";
329935
- var hash = "6d5e6f72d2678492dbab470e36f9338523984f43";
329935
+ var hash = "a3c9c45073d167ae3a2510ad116feca13f8b05f9";
329936
329936
  var global = new Function("return this")();
329937
329937
  var gcv = "__coverage__";
329938
329938
  var coverageData = {
@@ -329975,7 +329975,7 @@ var cov_geimehe8j = function () {
329975
329975
  },
329976
329976
  end: {
329977
329977
  line: 5,
329978
- column: 1128
329978
+ column: 1131
329979
329979
  }
329980
329980
  },
329981
329981
  "4": {
@@ -330296,7 +330296,7 @@ var cov_geimehe8j = function () {
330296
330296
  },
330297
330297
  end: {
330298
330298
  line: 5,
330299
- column: 1124
330299
+ column: 1127
330300
330300
  }
330301
330301
  },
330302
330302
  type: "cond-expr",
@@ -330316,7 +330316,7 @@ var cov_geimehe8j = function () {
330316
330316
  },
330317
330317
  end: {
330318
330318
  line: 5,
330319
- column: 1124
330319
+ column: 1127
330320
330320
  }
330321
330321
  }],
330322
330322
  line: 1
@@ -330329,7 +330329,7 @@ var cov_geimehe8j = function () {
330329
330329
  },
330330
330330
  end: {
330331
330331
  line: 5,
330332
- column: 1124
330332
+ column: 1127
330333
330333
  }
330334
330334
  },
330335
330335
  type: "cond-expr",
@@ -330349,7 +330349,7 @@ var cov_geimehe8j = function () {
330349
330349
  },
330350
330350
  end: {
330351
330351
  line: 5,
330352
- column: 1124
330352
+ column: 1127
330353
330353
  }
330354
330354
  }],
330355
330355
  line: 1
@@ -330362,7 +330362,7 @@ var cov_geimehe8j = function () {
330362
330362
  },
330363
330363
  end: {
330364
330364
  line: 5,
330365
- column: 1124
330365
+ column: 1127
330366
330366
  }
330367
330367
  },
330368
330368
  type: "cond-expr",
@@ -330382,7 +330382,7 @@ var cov_geimehe8j = function () {
330382
330382
  },
330383
330383
  end: {
330384
330384
  line: 5,
330385
- column: 1124
330385
+ column: 1127
330386
330386
  }
330387
330387
  }],
330388
330388
  line: 1
@@ -330735,7 +330735,7 @@ var cov_geimehe8j = function () {
330735
330735
  "11": [0, 0]
330736
330736
  },
330737
330737
  _coverageSchema: "43e27e138ebf9cfc5966b082cf9a028302ed4184",
330738
- hash: "6d5e6f72d2678492dbab470e36f9338523984f43"
330738
+ hash: "a3c9c45073d167ae3a2510ad116feca13f8b05f9"
330739
330739
  };
330740
330740
  var coverage = global[gcv] || (global[gcv] = {});
330741
330741
  if (coverage[path] && coverage[path].hash === hash) {
@@ -330744,7 +330744,7 @@ var cov_geimehe8j = function () {
330744
330744
  return coverage[path] = coverageData;
330745
330745
  }();
330746
330746
  cov_geimehe8j.s[0]++;
330747
- var ProjectMatrixvue_type_template_id_2742f691_scoped_true_render = function render() {
330747
+ var ProjectMatrixvue_type_template_id_28c10d94_scoped_true_render = function render() {
330748
330748
  cov_geimehe8j.f[0]++;
330749
330749
  var _vm = (cov_geimehe8j.s[1]++, this),
330750
330750
  _c = (cov_geimehe8j.s[2]++, _vm._self._c);
@@ -330924,8 +330924,8 @@ var ProjectMatrixvue_type_template_id_2742f691_scoped_true_render = function ren
330924
330924
  }), _c('div', {
330925
330925
  ref: "tooltip",
330926
330926
  staticClass: "native-tooltip",
330927
- style: {
330928
- display: 'none'
330927
+ staticStyle: {
330928
+ "display": "none"
330929
330929
  },
330930
330930
  on: {
330931
330931
  "mouseenter": _vm.handleTooltipEnter,
@@ -330936,9 +330936,9 @@ var ProjectMatrixvue_type_template_id_2742f691_scoped_true_render = function ren
330936
330936
  staticClass: "tooltip-content"
330937
330937
  })])])))], 2);
330938
330938
  };
330939
- var ProjectMatrixvue_type_template_id_2742f691_scoped_true_staticRenderFns = (cov_geimehe8j.s[12]++, []);
330939
+ var ProjectMatrixvue_type_template_id_28c10d94_scoped_true_staticRenderFns = (cov_geimehe8j.s[12]++, []);
330940
330940
 
330941
- ;// CONCATENATED MODULE: ./src/components/projects/ProjectMatrix.vue?vue&type=template&id=2742f691&scoped=true&
330941
+ ;// CONCATENATED MODULE: ./src/components/projects/ProjectMatrix.vue?vue&type=template&id=28c10d94&scoped=true&
330942
330942
 
330943
330943
  ;// CONCATENATED MODULE: ./src/utils/matrixHelpers.js
330944
330944
  var cov_17wz1apxpu = function () {
@@ -341920,7 +341920,7 @@ var MatrixLegend_component = normalizeComponent(
341920
341920
  function ProjectMatrixvue_type_script_lang_js_typeof(obj) { "@babel/helpers - typeof"; return ProjectMatrixvue_type_script_lang_js_typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, ProjectMatrixvue_type_script_lang_js_typeof(obj); }
341921
341921
  var ProjectMatrixvue_type_script_lang_js_cov_geimehe8j = function () {
341922
341922
  var path = "/Users/havasove/Desktop/repos/isabl_matrix/isabl_web/src/components/projects/ProjectMatrix.vue";
341923
- var hash = "4d6068187e3b09b0395493ca183ae0ed262ae00e";
341923
+ var hash = "a0c0d0bf4b1dd7c7c1e69ed5b9fb98baf888abe6";
341924
341924
  var global = new Function("return this")();
341925
341925
  var gcv = "__coverage__";
341926
341926
  var coverageData = {
@@ -343318,251 +343318,261 @@ var ProjectMatrixvue_type_script_lang_js_cov_geimehe8j = function () {
343318
343318
  },
343319
343319
  "139": {
343320
343320
  start: {
343321
- line: 407,
343321
+ line: 404,
343322
+ column: 6
343323
+ },
343324
+ end: {
343325
+ line: 410,
343326
+ column: 8
343327
+ }
343328
+ },
343329
+ "140": {
343330
+ start: {
343331
+ line: 414,
343322
343332
  column: 22
343323
343333
  },
343324
343334
  end: {
343325
- line: 407,
343335
+ line: 414,
343326
343336
  column: 40
343327
343337
  }
343328
343338
  },
343329
- "140": {
343339
+ "141": {
343330
343340
  start: {
343331
- line: 408,
343341
+ line: 415,
343332
343342
  column: 6
343333
343343
  },
343334
343344
  end: {
343335
- line: 410,
343345
+ line: 417,
343336
343346
  column: 7
343337
343347
  }
343338
343348
  },
343339
- "141": {
343349
+ "142": {
343340
343350
  start: {
343341
- line: 409,
343351
+ line: 416,
343342
343352
  column: 8
343343
343353
  },
343344
343354
  end: {
343345
- line: 409,
343355
+ line: 416,
343346
343356
  column: 38
343347
343357
  }
343348
343358
  },
343349
- "142": {
343359
+ "143": {
343350
343360
  start: {
343351
- line: 417,
343361
+ line: 424,
343352
343362
  column: 27
343353
343363
  },
343354
343364
  end: {
343355
- line: 417,
343365
+ line: 424,
343356
343366
  column: 29
343357
343367
  }
343358
343368
  },
343359
- "143": {
343369
+ "144": {
343360
343370
  start: {
343361
- line: 418,
343371
+ line: 425,
343362
343372
  column: 6
343363
343373
  },
343364
343374
  end: {
343365
- line: 420,
343375
+ line: 427,
343366
343376
  column: 8
343367
343377
  }
343368
343378
  },
343369
- "144": {
343379
+ "145": {
343370
343380
  start: {
343371
- line: 419,
343381
+ line: 426,
343372
343382
  column: 8
343373
343383
  },
343374
343384
  end: {
343375
- line: 419,
343385
+ line: 426,
343376
343386
  column: 66
343377
343387
  }
343378
343388
  },
343379
- "145": {
343389
+ "146": {
343380
343390
  start: {
343381
- line: 423,
343391
+ line: 430,
343382
343392
  column: 21
343383
343393
  },
343384
343394
  end: {
343385
- line: 423,
343395
+ line: 430,
343386
343396
  column: 22
343387
343397
  }
343388
343398
  },
343389
- "146": {
343399
+ "147": {
343390
343400
  start: {
343391
- line: 424,
343401
+ line: 431,
343392
343402
  column: 30
343393
343403
  },
343394
343404
  end: {
343395
- line: 424,
343405
+ line: 431,
343396
343406
  column: 41
343397
343407
  }
343398
343408
  },
343399
- "147": {
343409
+ "148": {
343400
343410
  start: {
343401
- line: 425,
343411
+ line: 432,
343402
343412
  column: 6
343403
343413
  },
343404
343414
  end: {
343405
- line: 430,
343415
+ line: 437,
343406
343416
  column: 8
343407
343417
  }
343408
343418
  },
343409
- "148": {
343419
+ "149": {
343410
343420
  start: {
343411
- line: 426,
343421
+ line: 433,
343412
343422
  column: 8
343413
343423
  },
343414
343424
  end: {
343415
- line: 429,
343425
+ line: 436,
343416
343426
  column: 9
343417
343427
  }
343418
343428
  },
343419
- "149": {
343429
+ "150": {
343420
343430
  start: {
343421
- line: 427,
343431
+ line: 434,
343422
343432
  column: 10
343423
343433
  },
343424
343434
  end: {
343425
- line: 427,
343435
+ line: 434,
343426
343436
  column: 26
343427
343437
  }
343428
343438
  },
343429
- "150": {
343439
+ "151": {
343430
343440
  start: {
343431
- line: 428,
343441
+ line: 435,
343432
343442
  column: 10
343433
343443
  },
343434
343444
  end: {
343435
- line: 428,
343445
+ line: 435,
343436
343446
  column: 36
343437
343447
  }
343438
343448
  },
343439
- "151": {
343449
+ "152": {
343440
343450
  start: {
343441
- line: 432,
343451
+ line: 439,
343442
343452
  column: 6
343443
343453
  },
343444
343454
  end: {
343445
- line: 432,
343455
+ line: 439,
343446
343456
  column: 46
343447
343457
  }
343448
343458
  },
343449
- "152": {
343459
+ "153": {
343450
343460
  start: {
343451
- line: 436,
343461
+ line: 443,
343452
343462
  column: 6
343453
343463
  },
343454
343464
  end: {
343455
- line: 436,
343465
+ line: 443,
343456
343466
  column: 31
343457
343467
  }
343458
343468
  },
343459
- "153": {
343469
+ "154": {
343460
343470
  start: {
343461
- line: 440,
343471
+ line: 447,
343462
343472
  column: 6
343463
343473
  },
343464
343474
  end: {
343465
- line: 440,
343475
+ line: 447,
343466
343476
  column: 32
343467
343477
  }
343468
343478
  },
343469
- "154": {
343479
+ "155": {
343470
343480
  start: {
343471
- line: 441,
343481
+ line: 448,
343472
343482
  column: 6
343473
343483
  },
343474
343484
  end: {
343475
- line: 441,
343485
+ line: 448,
343476
343486
  column: 30
343477
343487
  }
343478
343488
  },
343479
- "155": {
343489
+ "156": {
343480
343490
  start: {
343481
- line: 445,
343491
+ line: 452,
343482
343492
  column: 22
343483
343493
  },
343484
343494
  end: {
343485
- line: 445,
343495
+ line: 452,
343486
343496
  column: 40
343487
343497
  }
343488
343498
  },
343489
- "156": {
343499
+ "157": {
343490
343500
  start: {
343491
- line: 448,
343501
+ line: 455,
343492
343502
  column: 6
343493
343503
  },
343494
343504
  end: {
343495
- line: 448,
343505
+ line: 455,
343496
343506
  column: 59
343497
343507
  }
343498
343508
  },
343499
- "157": {
343509
+ "158": {
343500
343510
  start: {
343501
- line: 448,
343511
+ line: 455,
343502
343512
  column: 53
343503
343513
  },
343504
343514
  end: {
343505
- line: 448,
343515
+ line: 455,
343506
343516
  column: 59
343507
343517
  }
343508
343518
  },
343509
- "158": {
343519
+ "159": {
343510
343520
  start: {
343511
- line: 451,
343521
+ line: 458,
343512
343522
  column: 6
343513
343523
  },
343514
343524
  end: {
343515
- line: 451,
343525
+ line: 458,
343516
343526
  column: 67
343517
343527
  }
343518
343528
  },
343519
- "159": {
343529
+ "160": {
343520
343530
  start: {
343521
- line: 451,
343531
+ line: 458,
343522
343532
  column: 61
343523
343533
  },
343524
343534
  end: {
343525
- line: 451,
343535
+ line: 458,
343526
343536
  column: 67
343527
343537
  }
343528
343538
  },
343529
- "160": {
343539
+ "161": {
343530
343540
  start: {
343531
- line: 454,
343541
+ line: 461,
343532
343542
  column: 6
343533
343543
  },
343534
343544
  end: {
343535
- line: 454,
343545
+ line: 461,
343536
343546
  column: 30
343537
343547
  }
343538
343548
  },
343539
- "161": {
343549
+ "162": {
343540
343550
  start: {
343541
- line: 458,
343551
+ line: 465,
343542
343552
  column: 30
343543
343553
  },
343544
343554
  end: {
343545
- line: 458,
343555
+ line: 465,
343546
343556
  column: 56
343547
343557
  }
343548
343558
  },
343549
- "162": {
343559
+ "163": {
343550
343560
  start: {
343551
- line: 459,
343561
+ line: 466,
343552
343562
  column: 6
343553
343563
  },
343554
343564
  end: {
343555
- line: 461,
343565
+ line: 468,
343556
343566
  column: 7
343557
343567
  }
343558
343568
  },
343559
- "163": {
343569
+ "164": {
343560
343570
  start: {
343561
- line: 460,
343571
+ line: 467,
343562
343572
  column: 8
343563
343573
  },
343564
343574
  end: {
343565
- line: 460,
343575
+ line: 467,
343566
343576
  column: 32
343567
343577
  }
343568
343578
  }
@@ -344450,7 +344460,7 @@ var ProjectMatrixvue_type_script_lang_js_cov_geimehe8j = function () {
344450
344460
  column: 37
344451
344461
  },
344452
344462
  end: {
344453
- line: 404,
344463
+ line: 411,
344454
344464
  column: 5
344455
344465
  }
344456
344466
  },
@@ -344604,169 +344614,169 @@ var ProjectMatrixvue_type_script_lang_js_cov_geimehe8j = function () {
344604
344614
  name: "(anonymous_43)",
344605
344615
  decl: {
344606
344616
  start: {
344607
- line: 406,
344617
+ line: 413,
344608
344618
  column: 4
344609
344619
  },
344610
344620
  end: {
344611
- line: 406,
344621
+ line: 413,
344612
344622
  column: 5
344613
344623
  }
344614
344624
  },
344615
344625
  loc: {
344616
344626
  start: {
344617
- line: 406,
344627
+ line: 413,
344618
344628
  column: 24
344619
344629
  },
344620
344630
  end: {
344621
- line: 411,
344631
+ line: 418,
344622
344632
  column: 5
344623
344633
  }
344624
344634
  },
344625
- line: 406
344635
+ line: 413
344626
344636
  },
344627
344637
  "44": {
344628
344638
  name: "(anonymous_44)",
344629
344639
  decl: {
344630
344640
  start: {
344631
- line: 415,
344641
+ line: 422,
344632
344642
  column: 4
344633
344643
  },
344634
344644
  end: {
344635
- line: 415,
344645
+ line: 422,
344636
344646
  column: 5
344637
344647
  }
344638
344648
  },
344639
344649
  loc: {
344640
344650
  start: {
344641
- line: 415,
344651
+ line: 422,
344642
344652
  column: 34
344643
344653
  },
344644
344654
  end: {
344645
- line: 433,
344655
+ line: 440,
344646
344656
  column: 5
344647
344657
  }
344648
344658
  },
344649
- line: 415
344659
+ line: 422
344650
344660
  },
344651
344661
  "45": {
344652
344662
  name: "(anonymous_45)",
344653
344663
  decl: {
344654
344664
  start: {
344655
- line: 418,
344665
+ line: 425,
344656
344666
  column: 23
344657
344667
  },
344658
344668
  end: {
344659
- line: 418,
344669
+ line: 425,
344660
344670
  column: 24
344661
344671
  }
344662
344672
  },
344663
344673
  loc: {
344664
344674
  start: {
344665
- line: 418,
344675
+ line: 425,
344666
344676
  column: 28
344667
344677
  },
344668
344678
  end: {
344669
- line: 420,
344679
+ line: 427,
344670
344680
  column: 7
344671
344681
  }
344672
344682
  },
344673
- line: 418
344683
+ line: 425
344674
344684
  },
344675
344685
  "46": {
344676
344686
  name: "(anonymous_46)",
344677
344687
  decl: {
344678
344688
  start: {
344679
- line: 425,
344689
+ line: 432,
344680
344690
  column: 43
344681
344691
  },
344682
344692
  end: {
344683
- line: 425,
344693
+ line: 432,
344684
344694
  column: 44
344685
344695
  }
344686
344696
  },
344687
344697
  loc: {
344688
344698
  start: {
344689
- line: 425,
344699
+ line: 432,
344690
344700
  column: 64
344691
344701
  },
344692
344702
  end: {
344693
- line: 430,
344703
+ line: 437,
344694
344704
  column: 7
344695
344705
  }
344696
344706
  },
344697
- line: 425
344707
+ line: 432
344698
344708
  },
344699
344709
  "47": {
344700
344710
  name: "(anonymous_47)",
344701
344711
  decl: {
344702
344712
  start: {
344703
- line: 435,
344713
+ line: 442,
344704
344714
  column: 4
344705
344715
  },
344706
344716
  end: {
344707
- line: 435,
344717
+ line: 442,
344708
344718
  column: 5
344709
344719
  }
344710
344720
  },
344711
344721
  loc: {
344712
344722
  start: {
344713
- line: 435,
344723
+ line: 442,
344714
344724
  column: 25
344715
344725
  },
344716
344726
  end: {
344717
- line: 437,
344727
+ line: 444,
344718
344728
  column: 5
344719
344729
  }
344720
344730
  },
344721
- line: 435
344731
+ line: 442
344722
344732
  },
344723
344733
  "48": {
344724
344734
  name: "(anonymous_48)",
344725
344735
  decl: {
344726
344736
  start: {
344727
- line: 439,
344737
+ line: 446,
344728
344738
  column: 4
344729
344739
  },
344730
344740
  end: {
344731
- line: 439,
344741
+ line: 446,
344732
344742
  column: 5
344733
344743
  }
344734
344744
  },
344735
344745
  loc: {
344736
344746
  start: {
344737
- line: 439,
344747
+ line: 446,
344738
344748
  column: 25
344739
344749
  },
344740
344750
  end: {
344741
- line: 442,
344751
+ line: 449,
344742
344752
  column: 5
344743
344753
  }
344744
344754
  },
344745
- line: 439
344755
+ line: 446
344746
344756
  },
344747
344757
  "49": {
344748
344758
  name: "(anonymous_49)",
344749
344759
  decl: {
344750
344760
  start: {
344751
- line: 444,
344761
+ line: 451,
344752
344762
  column: 4
344753
344763
  },
344754
344764
  end: {
344755
- line: 444,
344765
+ line: 451,
344756
344766
  column: 5
344757
344767
  }
344758
344768
  },
344759
344769
  loc: {
344760
344770
  start: {
344761
- line: 444,
344771
+ line: 451,
344762
344772
  column: 31
344763
344773
  },
344764
344774
  end: {
344765
- line: 462,
344775
+ line: 469,
344766
344776
  column: 5
344767
344777
  }
344768
344778
  },
344769
- line: 444
344779
+ line: 451
344770
344780
  }
344771
344781
  },
344772
344782
  branchMap: {
@@ -346021,266 +346031,266 @@ var ProjectMatrixvue_type_script_lang_js_cov_geimehe8j = function () {
346021
346031
  "37": {
346022
346032
  loc: {
346023
346033
  start: {
346024
- line: 408,
346034
+ line: 415,
346025
346035
  column: 6
346026
346036
  },
346027
346037
  end: {
346028
- line: 410,
346038
+ line: 417,
346029
346039
  column: 7
346030
346040
  }
346031
346041
  },
346032
346042
  type: "if",
346033
346043
  locations: [{
346034
346044
  start: {
346035
- line: 408,
346045
+ line: 415,
346036
346046
  column: 6
346037
346047
  },
346038
346048
  end: {
346039
- line: 410,
346049
+ line: 417,
346040
346050
  column: 7
346041
346051
  }
346042
346052
  }, {
346043
346053
  start: {
346044
- line: 408,
346054
+ line: 415,
346045
346055
  column: 6
346046
346056
  },
346047
346057
  end: {
346048
- line: 410,
346058
+ line: 417,
346049
346059
  column: 7
346050
346060
  }
346051
346061
  }],
346052
- line: 408
346062
+ line: 415
346053
346063
  },
346054
346064
  "38": {
346055
346065
  loc: {
346056
346066
  start: {
346057
- line: 419,
346067
+ line: 426,
346058
346068
  column: 34
346059
346069
  },
346060
346070
  end: {
346061
- line: 419,
346071
+ line: 426,
346062
346072
  column: 61
346063
346073
  }
346064
346074
  },
346065
346075
  type: "binary-expr",
346066
346076
  locations: [{
346067
346077
  start: {
346068
- line: 419,
346078
+ line: 426,
346069
346079
  column: 34
346070
346080
  },
346071
346081
  end: {
346072
- line: 419,
346082
+ line: 426,
346073
346083
  column: 56
346074
346084
  }
346075
346085
  }, {
346076
346086
  start: {
346077
- line: 419,
346087
+ line: 426,
346078
346088
  column: 60
346079
346089
  },
346080
346090
  end: {
346081
- line: 419,
346091
+ line: 426,
346082
346092
  column: 61
346083
346093
  }
346084
346094
  }],
346085
- line: 419
346095
+ line: 426
346086
346096
  },
346087
346097
  "39": {
346088
346098
  loc: {
346089
346099
  start: {
346090
- line: 426,
346100
+ line: 433,
346091
346101
  column: 8
346092
346102
  },
346093
346103
  end: {
346094
- line: 429,
346104
+ line: 436,
346095
346105
  column: 9
346096
346106
  }
346097
346107
  },
346098
346108
  type: "if",
346099
346109
  locations: [{
346100
346110
  start: {
346101
- line: 426,
346111
+ line: 433,
346102
346112
  column: 8
346103
346113
  },
346104
346114
  end: {
346105
- line: 429,
346115
+ line: 436,
346106
346116
  column: 9
346107
346117
  }
346108
346118
  }, {
346109
346119
  start: {
346110
- line: 426,
346120
+ line: 433,
346111
346121
  column: 8
346112
346122
  },
346113
346123
  end: {
346114
- line: 429,
346124
+ line: 436,
346115
346125
  column: 9
346116
346126
  }
346117
346127
  }],
346118
- line: 426
346128
+ line: 433
346119
346129
  },
346120
346130
  "40": {
346121
346131
  loc: {
346122
346132
  start: {
346123
- line: 448,
346133
+ line: 455,
346124
346134
  column: 6
346125
346135
  },
346126
346136
  end: {
346127
- line: 448,
346137
+ line: 455,
346128
346138
  column: 59
346129
346139
  }
346130
346140
  },
346131
346141
  type: "if",
346132
346142
  locations: [{
346133
346143
  start: {
346134
- line: 448,
346144
+ line: 455,
346135
346145
  column: 6
346136
346146
  },
346137
346147
  end: {
346138
- line: 448,
346148
+ line: 455,
346139
346149
  column: 59
346140
346150
  }
346141
346151
  }, {
346142
346152
  start: {
346143
- line: 448,
346153
+ line: 455,
346144
346154
  column: 6
346145
346155
  },
346146
346156
  end: {
346147
- line: 448,
346157
+ line: 455,
346148
346158
  column: 59
346149
346159
  }
346150
346160
  }],
346151
- line: 448
346161
+ line: 455
346152
346162
  },
346153
346163
  "41": {
346154
346164
  loc: {
346155
346165
  start: {
346156
- line: 448,
346166
+ line: 455,
346157
346167
  column: 10
346158
346168
  },
346159
346169
  end: {
346160
- line: 448,
346170
+ line: 455,
346161
346171
  column: 51
346162
346172
  }
346163
346173
  },
346164
346174
  type: "binary-expr",
346165
346175
  locations: [{
346166
346176
  start: {
346167
- line: 448,
346177
+ line: 455,
346168
346178
  column: 10
346169
346179
  },
346170
346180
  end: {
346171
- line: 448,
346181
+ line: 455,
346172
346182
  column: 17
346173
346183
  }
346174
346184
  }, {
346175
346185
  start: {
346176
- line: 448,
346186
+ line: 455,
346177
346187
  column: 21
346178
346188
  },
346179
346189
  end: {
346180
- line: 448,
346190
+ line: 455,
346181
346191
  column: 51
346182
346192
  }
346183
346193
  }],
346184
- line: 448
346194
+ line: 455
346185
346195
  },
346186
346196
  "42": {
346187
346197
  loc: {
346188
346198
  start: {
346189
- line: 451,
346199
+ line: 458,
346190
346200
  column: 6
346191
346201
  },
346192
346202
  end: {
346193
- line: 451,
346203
+ line: 458,
346194
346204
  column: 67
346195
346205
  }
346196
346206
  },
346197
346207
  type: "if",
346198
346208
  locations: [{
346199
346209
  start: {
346200
- line: 451,
346210
+ line: 458,
346201
346211
  column: 6
346202
346212
  },
346203
346213
  end: {
346204
- line: 451,
346214
+ line: 458,
346205
346215
  column: 67
346206
346216
  }
346207
346217
  }, {
346208
346218
  start: {
346209
- line: 451,
346219
+ line: 458,
346210
346220
  column: 6
346211
346221
  },
346212
346222
  end: {
346213
- line: 451,
346223
+ line: 458,
346214
346224
  column: 67
346215
346225
  }
346216
346226
  }],
346217
- line: 451
346227
+ line: 458
346218
346228
  },
346219
346229
  "43": {
346220
346230
  loc: {
346221
346231
  start: {
346222
- line: 459,
346232
+ line: 466,
346223
346233
  column: 6
346224
346234
  },
346225
346235
  end: {
346226
- line: 461,
346236
+ line: 468,
346227
346237
  column: 7
346228
346238
  }
346229
346239
  },
346230
346240
  type: "if",
346231
346241
  locations: [{
346232
346242
  start: {
346233
- line: 459,
346243
+ line: 466,
346234
346244
  column: 6
346235
346245
  },
346236
346246
  end: {
346237
- line: 461,
346247
+ line: 468,
346238
346248
  column: 7
346239
346249
  }
346240
346250
  }, {
346241
346251
  start: {
346242
- line: 459,
346252
+ line: 466,
346243
346253
  column: 6
346244
346254
  },
346245
346255
  end: {
346246
- line: 461,
346256
+ line: 468,
346247
346257
  column: 7
346248
346258
  }
346249
346259
  }],
346250
- line: 459
346260
+ line: 466
346251
346261
  },
346252
346262
  "44": {
346253
346263
  loc: {
346254
346264
  start: {
346255
- line: 459,
346265
+ line: 466,
346256
346266
  column: 10
346257
346267
  },
346258
346268
  end: {
346259
- line: 459,
346269
+ line: 466,
346260
346270
  column: 67
346261
346271
  }
346262
346272
  },
346263
346273
  type: "binary-expr",
346264
346274
  locations: [{
346265
346275
  start: {
346266
- line: 459,
346276
+ line: 466,
346267
346277
  column: 10
346268
346278
  },
346269
346279
  end: {
346270
- line: 459,
346280
+ line: 466,
346271
346281
  column: 25
346272
346282
  }
346273
346283
  }, {
346274
346284
  start: {
346275
- line: 459,
346285
+ line: 466,
346276
346286
  column: 29
346277
346287
  },
346278
346288
  end: {
346279
- line: 459,
346289
+ line: 466,
346280
346290
  column: 67
346281
346291
  }
346282
346292
  }],
346283
- line: 459
346293
+ line: 466
346284
346294
  }
346285
346295
  },
346286
346296
  s: {
@@ -346447,7 +346457,8 @@ var ProjectMatrixvue_type_script_lang_js_cov_geimehe8j = function () {
346447
346457
  "160": 0,
346448
346458
  "161": 0,
346449
346459
  "162": 0,
346450
- "163": 0
346460
+ "163": 0,
346461
+ "164": 0
346451
346462
  },
346452
346463
  f: {
346453
346464
  "0": 0,
@@ -346552,13 +346563,13 @@ var ProjectMatrixvue_type_script_lang_js_cov_geimehe8j = function () {
346552
346563
  version: 3,
346553
346564
  sources: ["ProjectMatrix.vue"],
346554
346565
  names: [],
346555
- mappings: ";AAmJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA",
346566
+ mappings: ";AAmJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA",
346556
346567
  file: "ProjectMatrix.vue",
346557
346568
  sourceRoot: "src/components/projects",
346558
- sourcesContent: ["<template>\n <div class=\"project-matrix\">\n <!-- Loading State -->\n <div v-if=\"loading\" class=\"loading-container\">\n <v-progress-circular indeterminate color=\"primary\" size=\"48\" />\n <div class=\"text-body-2 grey--text mt-3\">Loading matrix data...</div>\n </div>\n\n <!-- Error State -->\n <v-alert v-else-if=\"error\" type=\"error\" class=\"ma-4\">\n {{ error }}\n </v-alert>\n\n <!-- Empty State (only when no data at all, not due to filters) -->\n <v-alert v-else-if=\"!loading && matrixData.rows.length === 0\" type=\"info\" class=\"ma-4\">\n No {{ viewMode === 'individual' ? 'individuals' : 'experiments' }} or analyses found for this project.\n </v-alert>\n\n <!-- Matrix Content (always show when we have data) -->\n <template v-else>\n <!-- Filters -->\n <matrix-filters\n :view-mode=\"viewMode\"\n :statuses=\"filters.statuses\"\n :selected-columns=\"filters.selectedColumns\"\n :experiment-search=\"filters.experimentSearch\"\n :assemblies=\"filters.assemblies\"\n :techniques=\"filters.techniques\"\n :identifier-list=\"filters.identifierList\"\n :matched-identifier-count=\"matchedIdentifierCount\"\n :available-statuses=\"availableStatuses\"\n :available-columns=\"matrixData.columns\"\n :available-assemblies=\"availableAssemblies\"\n :available-techniques=\"availableTechniques\"\n :available-rows=\"matrixData.rows\"\n :hide-empty-rows=\"hideEmptyRows\"\n :has-active-filters=\"hasActiveFilters\"\n :has-highlights=\"hasHighlights\"\n :is-refreshing=\"refreshing\"\n @update:viewMode=\"handleViewModeChange\"\n @update:filters=\"updateFilters\"\n @update:hideEmptyRows=\"hideEmptyRows = $event\"\n @update-identifier-list=\"updateIdentifierList\"\n @clear-identifier-list=\"clearIdentifierList\"\n @clear-filters=\"clearFilters\"\n @clear-highlights=\"clearHighlights\"\n @refresh=\"refreshData\"\n />\n\n <!-- Spacer for visual separation -->\n <div class=\"filter-spacer\"></div>\n\n <!-- Matrix Grid -->\n <div\n class=\"matrix-scroll-container\"\n ref=\"scrollContainer\"\n >\n <!-- No matches message (inline, when filters exclude all results) -->\n <div v-if=\"filteredData.rows.length === 0 && hasActiveFilters\" class=\"no-matches-message\">\n <v-icon small color=\"grey\" class=\"mr-1\">mdi-filter-off</v-icon>\n No results match your filters\n </div>\n\n <template v-else>\n <!-- Header Row (CSS Grid for proper overflow of angled text) -->\n <div class=\"header-row\" :style=\"{ '--col-count': filteredData.columns.length }\">\n <div class=\"corner-cell\"></div>\n <div\n v-for=\"col in filteredData.columns\"\n :key=\"`header-${col}`\"\n class=\"header-cell\"\n :class=\"{ 'column-highlighted': highlightedColumnsMap[col] }\"\n @click=\"toggleColumnHighlight(col)\"\n >\n <span class=\"header-text\" :title=\"col\">{{ col }}</span>\n </div>\n </div>\n\n <!-- Data Table (same column widths as header) -->\n <table class=\"matrix-table\">\n <tbody>\n <tr v-for=\"row in filteredData.rows\" :key=\"row\">\n <td\n class=\"row-header\"\n :class=\"{ 'row-highlighted': highlightedRowsMap[row] }\"\n @click=\"toggleRowHighlight(row)\"\n >\n <span class=\"system-id\" :title=\"row\">{{ row }}</span>\n </td>\n <td\n v-for=\"col in filteredData.columns\"\n :key=\"col\"\n class=\"matrix-cell\"\n :class=\"{\n 'has-analyses': filteredData.cells[row]?.[col]?.length > 0,\n 'cell-highlighted': highlightedRowsMap[row] || highlightedColumnsMap[col],\n 'cell-selected': selectedCell && selectedCell.row === row && selectedCell.col === col\n }\"\n :data-row=\"row\"\n :data-col=\"col\"\n @click=\"handleCellClick($event, row, col)\"\n >\n <template v-if=\"filteredData.cells[row]?.[col]?.length\">\n <!-- Show stripes for small counts (\u2264 8) -->\n <div v-if=\"filteredData.cells[row][col].length <= 8\" class=\"cell-stripes\">\n <div\n v-for=\"(analysis, index) in filteredData.cells[row][col]\"\n :key=\"`${analysis.pk}-${analysis.experimentSystemId || ''}-${index}`\"\n class=\"stripe\"\n :style=\"{ backgroundColor: getStatusColor(analysis.status) }\"\n />\n </div>\n <!-- Show count badge for large counts (> 8) -->\n <div v-else class=\"cell-count-badge\" :style=\"{ backgroundColor: getPredominantColor(filteredData.cells[row][col]) }\">\n {{ filteredData.cells[row][col].length }}\n </div>\n </template>\n <span v-else class=\"empty-cell\">-</span>\n </td>\n </tr>\n </tbody>\n </table>\n </template>\n </div>\n\n <!-- Legend -->\n <matrix-legend\n :active-statuses=\"availableStatuses\"\n :view-mode=\"viewMode\"\n :stats=\"matrixStats\"\n />\n\n <!-- Native DOM Tooltip (bypasses Vue reactivity) -->\n <div\n ref=\"tooltip\"\n class=\"native-tooltip\"\n :style=\"{ display: 'none' }\"\n @mouseenter=\"handleTooltipEnter\"\n @mouseleave=\"handleTooltipLeave\"\n >\n <div class=\"tooltip-content\" ref=\"tooltipContent\"></div>\n </div>\n </template>\n </div>\n</template>\n\n<script>\nimport { fetchAllRecords } from '@/utils/api'\nimport {\n buildMatrixData,\n filterMatrixData,\n getStatusColor\n} from '@/utils/matrixHelpers'\nimport MatrixFilters from './MatrixFilters.vue'\nimport MatrixLegend from './MatrixLegend.vue'\n\nexport default {\n name: 'ProjectMatrix',\n components: {\n MatrixFilters,\n MatrixLegend\n },\n props: {\n projectId: {\n type: [String, Number],\n required: true\n }\n },\n data() {\n return {\n loading: false,\n refreshing: false,\n filtering: false,\n error: null,\n experiments: [],\n analyses: [],\n viewMode: 'experiment', // 'experiment' | 'individual'\n lockedProjectId: this.projectId, // Lock to initial project ID to prevent changes while modal is open\n matrixData: {\n rows: [],\n columns: [],\n cells: {},\n appVersions: {},\n viewMode: 'experiment',\n stats: {\n totalRows: 0,\n totalApps: 0,\n totalAnalyses: 0,\n byStatus: {},\n uniqueStatuses: [],\n uniqueAssemblies: [],\n uniqueTechniques: []\n }\n },\n filteredData: {\n rows: [],\n columns: [],\n cells: {},\n appVersions: {}\n },\n filters: {\n statuses: [],\n selectedColumns: [],\n experimentSearch: '',\n assemblies: [],\n techniques: [],\n identifierList: []\n },\n hideEmptyRows: false,\n highlightedRows: new Set(),\n highlightedColumns: new Set(),\n // Tooltip state (for native DOM tooltip)\n isOverTooltip: false,\n // Selected cell state\n selectedCell: null // { row, col }\n }\n },\n computed: {\n availableStatuses() {\n // Use pre-calculated stats from matrixData (avoids expensive iteration)\n return this.matrixData.stats?.uniqueStatuses || []\n },\n availableAssemblies() {\n // Use pre-calculated stats from matrixData\n return this.matrixData.stats?.uniqueAssemblies || []\n },\n availableTechniques() {\n // Use pre-calculated stats from matrixData\n return this.matrixData.stats?.uniqueTechniques || []\n },\n matrixStats() {\n // Use pre-calculated stats from matrixData (avoids expensive iteration on filter changes)\n // Note: Shows total stats, not filtered stats (for performance)\n const stats = this.matrixData.stats || {}\n return {\n totalRows: stats.totalRows || 0,\n totalApps: stats.totalApps || 0,\n totalAnalyses: stats.totalAnalyses || 0\n }\n },\n hasActiveFilters() {\n const columnsFiltered = this.filters.selectedColumns.length > 0 &&\n this.filters.selectedColumns.length < this.matrixData.columns.length\n return (\n this.filters.statuses.length > 0 ||\n columnsFiltered ||\n this.filters.experimentSearch ||\n this.filters.assemblies.length > 0 ||\n this.filters.techniques.length > 0 ||\n this.filters.identifierList.length > 0\n )\n },\n // Memoized highlight maps for O(1) lookup\n highlightedRowsMap() {\n const map = {}\n this.highlightedRows.forEach(r => { map[r] = true })\n return map\n },\n highlightedColumnsMap() {\n const map = {}\n this.highlightedColumns.forEach(c => { map[c] = true })\n return map\n },\n hasHighlights() {\n return this.highlightedRows.size > 0 || this.highlightedColumns.size > 0\n },\n // Count how many identifiers from the list actually exist in the data\n matchedIdentifierCount() {\n if (this.filters.identifierList.length === 0) return 0\n\n // Build case-insensitive set of all row IDs in the matrix\n const rowSet = new Set(\n this.matrixData.rows.map(row => row.toLowerCase())\n )\n\n // Count how many identifiers from the list exist in the data\n return this.filters.identifierList.filter(id =>\n rowSet.has(id.toLowerCase())\n ).length\n }\n },\n watch: {\n projectId: {\n immediate: true,\n handler(newId, oldId) {\n // Only fetch data on initial load (when oldId is undefined)\n // Ignore subsequent changes to keep matrix locked to original project\n if (oldId === undefined) {\n this.fetchData()\n }\n }\n },\n filters: {\n deep: true,\n handler() {\n this.applyFilters()\n }\n },\n hideEmptyRows() {\n this.applyFilters()\n },\n matrixData() {\n this.applyFilters()\n },\n 'filteredData.rows'() {\n // Reset scroll when data changes\n if (this.$refs.scrollContainer) {\n this.$refs.scrollContainer.scrollTop = 0\n }\n }\n },\n mounted() {\n // Close tooltip when clicking outside\n document.addEventListener('click', this.handleDocumentClick)\n },\n beforeDestroy() {\n document.removeEventListener('click', this.handleDocumentClick)\n },\n methods: {\n async fetchData(isRefresh = false) {\n // Set appropriate loading state\n if (isRefresh) {\n this.refreshing = true\n } else {\n this.loading = true\n }\n this.error = null\n\n // Store current filters before fetch (for refresh)\n const currentFilters = isRefresh ? { ...this.filters } : null\n\n try {\n // Fetch all experiments and analyses (with pagination)\n // Use lockedProjectId to prevent refetching if prop changes while modal is open\n const [experimentsRes, analysesRes] = await Promise.all([\n fetchAllRecords('experiments', {\n projects__pk: this.lockedProjectId,\n 'fields!': 'results,analytics,raw_data,bam_files'\n }),\n fetchAllRecords('analyses', {\n targets__projects__pk: this.lockedProjectId,\n 'fields!': 'targets,references,analytics,results'\n })\n ])\n\n this.experiments = experimentsRes.results || []\n this.analyses = analysesRes.results || []\n\n // Build matrix data and freeze it to prevent Vue reactivity overhead\n this.rebuildMatrixData()\n\n // Initialize selected columns to all columns (show all by default on initial load)\n // On refresh, restore previous filters\n if (isRefresh && currentFilters) {\n // Restore filters but ensure selectedColumns are still valid\n this.filters = {\n ...currentFilters,\n // Keep only columns that still exist after refresh\n selectedColumns: currentFilters.selectedColumns.filter(col =>\n this.matrixData.columns.includes(col)\n )\n }\n // If all selected columns were removed, default to all\n if (this.filters.selectedColumns.length === 0) {\n this.filters.selectedColumns = [...this.matrixData.columns]\n }\n } else {\n this.filters.selectedColumns = [...this.matrixData.columns]\n }\n } catch (err) {\n this.error = `Failed to load data: ${err.message}`\n console.error('Error loading matrix data:', err)\n } finally {\n if (isRefresh) {\n this.refreshing = false\n } else {\n this.loading = false\n }\n }\n },\n\n async refreshData() {\n await this.fetchData(true)\n },\n\n async applyFilters() {\n // Use requestAnimationFrame to yield to browser and prevent UI blocking\n await new Promise(resolve => requestAnimationFrame(resolve))\n\n // Filter matrix data (already frozen internally)\n // Include hideEmptyRows from component state\n this.filteredData = filterMatrixData(this.matrixData, {\n ...this.filters,\n hideEmptyRows: this.hideEmptyRows\n })\n },\n\n updateFilters(newFilters) {\n this.filters = { ...newFilters }\n },\n\n updateIdentifierList(identifiers) {\n this.filters.identifierList = identifiers\n },\n\n clearIdentifierList() {\n this.filters.identifierList = []\n },\n\n handleViewModeChange(newMode) {\n this.viewMode = newMode\n // Clear highlights and selection when switching views\n this.highlightedRows = new Set()\n this.highlightedColumns = new Set()\n this.selectedCell = null\n this.hideTooltipNative()\n // Rebuild matrix data with new view mode\n this.rebuildMatrixData()\n },\n\n rebuildMatrixData() {\n // buildMatrixData already freezes everything internally for performance\n this.matrixData = buildMatrixData(this.experiments, this.analyses, this.viewMode)\n // The watcher on matrixData will automatically call applyFilters()\n },\n\n handleOpenAnalysis(analysisId) {\n this.hideTooltipNative()\n this.$emit('open-analysis', analysisId)\n },\n\n toggleRowHighlight(row) {\n const newSet = new Set(this.highlightedRows)\n if (newSet.has(row)) {\n newSet.delete(row)\n } else {\n newSet.add(row)\n }\n this.highlightedRows = newSet\n },\n\n toggleColumnHighlight(col) {\n const newSet = new Set(this.highlightedColumns)\n if (newSet.has(col)) {\n newSet.delete(col)\n } else {\n newSet.add(col)\n }\n this.highlightedColumns = newSet\n },\n\n clearHighlights() {\n this.highlightedRows = new Set()\n this.highlightedColumns = new Set()\n },\n\n clearFilters() {\n this.filters = {\n statuses: [],\n selectedColumns: [],\n experimentSearch: '',\n assemblies: [],\n techniques: [],\n identifierList: []\n }\n },\n\n // Cell click handler - uses native DOM to avoid Vue re-renders\n handleCellClick(event, row, col) {\n console.log('handleCellClick called:', { row, col })\n const analyses = this.filteredData.cells[row]?.[col] || []\n console.log('analyses:', analyses.length)\n if (analyses.length === 0) return\n\n // Set selected cell\n this.selectedCell = { row, col }\n\n const rect = event.currentTarget.getBoundingClientRect()\n const tooltip = this.$refs.tooltip\n const content = this.$refs.tooltipContent\n\n console.log('tooltip ref:', !!tooltip, 'content ref:', !!content)\n if (!tooltip || !content) return\n\n // Store analyses for later use\n this._currentAnalyses = analyses\n\n // Build tooltip HTML directly (no Vue reactivity)\n const appName = analyses[0]?.application?.name || 'Unknown'\n let html = `<div class=\"tooltip-header\">${appName} - ${analyses.length} analysis${analyses.length !== 1 ? 'es' : ''}</div>`\n html += '<div class=\"tooltip-list\">'\n\n if (this.viewMode === 'individual') {\n // Group analyses by experiment for individual view\n const byExperiment = {}\n analyses.forEach(a => {\n const expId = a.experimentSystemId || 'Unknown'\n if (!byExperiment[expId]) {\n byExperiment[expId] = []\n }\n byExperiment[expId].push(a)\n })\n\n // Render grouped by experiment\n Object.entries(byExperiment).forEach(([expId, expAnalyses]) => {\n html += `<div class=\"experiment-group-header\">${expId}</div>`\n expAnalyses.forEach(a => {\n const color = this.getStatusColor(a.status)\n html += `<div class=\"tooltip-item\" data-pk=\"${a.pk}\">`\n html += `<span class=\"status-dot\" style=\"background:${color}\"></span>`\n html += `<span class=\"analysis-pk\">${a.pk}</span>`\n html += `<span class=\"sep\">|</span>`\n html += `<span class=\"version\">v${a.version || 'N/A'}</span>`\n if (a.assembly) html += `<span class=\"assembly\"> \xB7 ${a.assembly}</span>`\n html += `<span class=\"status-chip\" style=\"background:${color}\">${a.status}</span>`\n html += '</div>'\n })\n })\n } else {\n // Flat list for experiment view\n analyses.forEach(a => {\n const color = this.getStatusColor(a.status)\n html += `<div class=\"tooltip-item\" data-pk=\"${a.pk}\">`\n html += `<span class=\"status-dot\" style=\"background:${color}\"></span>`\n html += `<span class=\"analysis-pk\">${a.pk}</span>`\n html += `<span class=\"sep\">|</span>`\n html += `<span class=\"version\">v${a.version || 'N/A'}</span>`\n if (a.assembly) html += `<span class=\"assembly\"> \xB7 ${a.assembly}</span>`\n html += `<span class=\"status-chip\" style=\"background:${color}\">${a.status}</span>`\n html += '</div>'\n })\n }\n\n html += '</div>'\n content.innerHTML = html\n\n // Add click handlers to items\n content.querySelectorAll('.tooltip-item').forEach(item => {\n item.onclick = () => {\n const pk = parseInt(item.dataset.pk)\n this.hideTooltipNative()\n this.handleOpenAnalysis(pk)\n }\n })\n\n // Position and show tooltip\n tooltip.style.display = 'block'\n tooltip.style.left = `${rect.left + rect.width / 2}px`\n tooltip.style.top = `${rect.top - 8}px`\n },\n\n hideTooltipNative() {\n const tooltip = this.$refs.tooltip\n if (tooltip) {\n tooltip.style.display = 'none'\n }\n },\n\n getStatusColor,\n\n getPredominantColor(analyses) {\n // Count occurrences of each status\n const statusCounts = {}\n analyses.forEach(a => {\n statusCounts[a.status] = (statusCounts[a.status] || 0) + 1\n })\n\n // Find the most common status\n let maxCount = 0\n let predominantStatus = 'SUCCEEDED' // default\n Object.entries(statusCounts).forEach(([status, count]) => {\n if (count > maxCount) {\n maxCount = count\n predominantStatus = status\n }\n })\n\n return getStatusColor(predominantStatus)\n },\n\n handleTooltipEnter() {\n this.isOverTooltip = true\n },\n\n handleTooltipLeave() {\n this.isOverTooltip = false\n this.hideTooltipNative()\n },\n\n handleDocumentClick(event) {\n const tooltip = this.$refs.tooltip\n\n // Check if click was inside tooltip\n if (tooltip && tooltip.contains(event.target)) return\n\n // Check if click was on a matrix cell (this opens tooltip, don't close it)\n if (event.target.closest('.matrix-cell.has-analyses')) return\n\n // Hide tooltip if visible\n this.hideTooltipNative()\n\n // Only clear selection if clicking inside the matrix scroll container\n // (not when clicking tabs, filters, etc.)\n const scrollContainer = this.$refs.scrollContainer\n if (scrollContainer && scrollContainer.contains(event.target)) {\n this.selectedCell = null\n }\n }\n }\n}\n</script>\n\n<style scoped>\n.project-matrix {\n display: flex;\n flex-direction: column;\n height: 100%;\n min-height: 400px;\n}\n\n.loading-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n min-height: 300px;\n}\n\n.filter-spacer {\n height: 16px;\n background: white;\n}\n\n.matrix-scroll-container {\n flex: 1;\n overflow: auto;\n max-height: calc(80vh - 180px);\n}\n\n.no-matches-message {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 24px;\n color: #666;\n font-size: 13px;\n}\n\n.matrix-table {\n border-collapse: separate;\n border-spacing: 0;\n table-layout: fixed;\n}\n\n/* Header row - CSS Grid for proper text overflow */\n.header-row {\n display: grid;\n grid-template-columns: 200px repeat(var(--col-count), 50px);\n position: sticky;\n top: 0;\n z-index: 10;\n background: white;\n min-width: fit-content;\n}\n\n/* Corner cell - top-left */\n.corner-cell {\n position: sticky;\n left: 0;\n z-index: 11;\n background: white;\n border-bottom: 2px solid #5b5dff;\n border-right: 2px solid #5b5dff;\n height: 130px;\n width: 200px;\n box-sizing: border-box;\n}\n\n/* Column headers - angled text */\n.header-cell {\n position: relative;\n height: 130px;\n width: 50px;\n border-bottom: 2px solid #5b5dff;\n background: white;\n overflow: visible;\n cursor: pointer;\n}\n\n.header-cell:hover .header-text {\n background: #FFF6DB;\n border-radius: 2px;\n}\n\n.header-cell.column-highlighted .header-text {\n background: #FFF0D9;\n border-radius: 2px;\n font-weight: 700;\n color: #000;\n}\n\n.header-text {\n position: absolute;\n bottom: 8px;\n left: 50%;\n transform: rotate(-45deg);\n transform-origin: bottom left;\n white-space: nowrap;\n font-size: 11px;\n font-weight: 500;\n color: #333;\n z-index: 1;\n}\n\n/* Row headers - width must match corner-cell (200px) */\ntd.row-header {\n position: sticky;\n left: 0;\n z-index: 1;\n background: white;\n border-right: 2px solid #5b5dff;\n padding: 0 8px;\n width: 200px;\n min-width: 200px;\n max-width: 200px;\n height: 24px;\n border-bottom: 1px solid #e0e0e0;\n cursor: pointer;\n vertical-align: middle;\n box-sizing: border-box;\n}\n\n.row-header.row-highlighted {\n background: #FFE8C5 !important;\n}\n\n.row-header.row-highlighted .system-id {\n font-weight: 700;\n color: #000;\n}\n\n.system-id {\n font-size: 11px;\n font-family: monospace;\n color: #333;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* Hover highlight for row header */\n.row-header:hover {\n background: #FFF0D9;\n}\n\n.row-header:hover .system-id {\n font-weight: 600;\n}\n\n/* Table cell styles - width must match header-cell (50px) */\ntd.matrix-cell {\n width: 50px;\n min-width: 50px;\n max-width: 50px;\n height: 24px;\n border-right: 1px solid #e0e0e0;\n border-bottom: 1px solid #e0e0e0;\n cursor: default;\n background: #fafafa;\n padding: 0;\n vertical-align: middle;\n box-sizing: border-box;\n}\n\n.matrix-cell.has-analyses {\n cursor: pointer;\n background: white;\n}\n\n.matrix-cell.has-analyses:hover,\n.matrix-cell.cell-selected {\n border-right-color: #5b5dff;\n border-bottom-color: #5b5dff;\n background: #f0f0ff;\n}\n\n.matrix-cell.cell-highlighted {\n background: #FFE8C5;\n}\n\n.cell-stripes {\n display: flex;\n align-items: stretch;\n justify-content: center;\n gap: 1px;\n height: 100%;\n width: 100%;\n padding: 2px 4px;\n}\n\n.stripe {\n flex: 0 0 auto;\n width: 3px;\n min-width: 2px;\n max-width: 5px;\n border-radius: 1px;\n}\n\n.cell-count-badge {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n color: white;\n font-size: 10px;\n font-weight: 600;\n text-shadow: 0 0 2px rgba(0, 0, 0, 0.3);\n}\n\n.empty-cell {\n display: flex;\n align-items: center;\n justify-content: center;\n color: #ccc;\n font-size: 10px;\n height: 100%;\n}\n\n/* Native tooltip styles - use ::v-deep for dynamically generated content */\n.native-tooltip {\n position: fixed;\n transform: translateX(-50%) translateY(-100%);\n z-index: 9999;\n background: white;\n border-radius: 4px;\n box-shadow: 0 2px 8px rgba(0,0,0,0.2);\n min-width: 280px;\n max-width: 350px;\n max-height: 300px;\n overflow-y: auto;\n}\n\n.native-tooltip ::v-deep .tooltip-header {\n padding: 8px 12px;\n background: #f5f5f5;\n font-weight: 500;\n font-size: 13px;\n border-bottom: 1px solid #e0e0e0;\n}\n\n.native-tooltip ::v-deep .tooltip-list {\n padding: 4px 0;\n}\n\n.native-tooltip ::v-deep .tooltip-item {\n display: flex;\n align-items: center;\n padding: 6px 12px;\n cursor: pointer;\n font-size: 12px;\n}\n\n.native-tooltip ::v-deep .tooltip-item:hover {\n background: #e3f2fd;\n}\n\n.native-tooltip ::v-deep .tooltip-item .status-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n margin-right: 8px;\n flex-shrink: 0;\n}\n\n.native-tooltip ::v-deep .tooltip-item .analysis-pk {\n color: #1976d2;\n font-weight: 500;\n}\n\n.native-tooltip ::v-deep .tooltip-item .sep {\n margin: 0 6px;\n color: #999;\n}\n\n.native-tooltip ::v-deep .tooltip-item .version {\n color: #666;\n}\n\n.native-tooltip ::v-deep .tooltip-item .assembly {\n color: #999;\n}\n\n.native-tooltip ::v-deep .tooltip-item .status-chip {\n margin-left: auto;\n padding: 2px 6px;\n border-radius: 3px;\n color: white;\n font-size: 10px;\n font-weight: 500;\n}\n\n.native-tooltip ::v-deep .experiment-group-header {\n padding: 6px 12px 4px;\n font-size: 11px;\n font-weight: 600;\n color: #1976d2;\n background: #f8f9fa;\n border-top: 1px solid #e0e0e0;\n font-family: monospace;\n}\n\n.native-tooltip ::v-deep .experiment-group-header:first-child {\n border-top: none;\n}\n</style>\n"]
346569
+ sourcesContent: ["<template>\n <div class=\"project-matrix\">\n <!-- Loading State -->\n <div v-if=\"loading\" class=\"loading-container\">\n <v-progress-circular indeterminate color=\"primary\" size=\"48\" />\n <div class=\"text-body-2 grey--text mt-3\">Loading matrix data...</div>\n </div>\n\n <!-- Error State -->\n <v-alert v-else-if=\"error\" type=\"error\" class=\"ma-4\">\n {{ error }}\n </v-alert>\n\n <!-- Empty State (only when no data at all, not due to filters) -->\n <v-alert v-else-if=\"!loading && matrixData.rows.length === 0\" type=\"info\" class=\"ma-4\">\n No {{ viewMode === 'individual' ? 'individuals' : 'experiments' }} or analyses found for this project.\n </v-alert>\n\n <!-- Matrix Content (always show when we have data) -->\n <template v-else>\n <!-- Filters -->\n <matrix-filters\n :view-mode=\"viewMode\"\n :statuses=\"filters.statuses\"\n :selected-columns=\"filters.selectedColumns\"\n :experiment-search=\"filters.experimentSearch\"\n :assemblies=\"filters.assemblies\"\n :techniques=\"filters.techniques\"\n :identifier-list=\"filters.identifierList\"\n :matched-identifier-count=\"matchedIdentifierCount\"\n :available-statuses=\"availableStatuses\"\n :available-columns=\"matrixData.columns\"\n :available-assemblies=\"availableAssemblies\"\n :available-techniques=\"availableTechniques\"\n :available-rows=\"matrixData.rows\"\n :hide-empty-rows=\"hideEmptyRows\"\n :has-active-filters=\"hasActiveFilters\"\n :has-highlights=\"hasHighlights\"\n :is-refreshing=\"refreshing\"\n @update:viewMode=\"handleViewModeChange\"\n @update:filters=\"updateFilters\"\n @update:hideEmptyRows=\"hideEmptyRows = $event\"\n @update-identifier-list=\"updateIdentifierList\"\n @clear-identifier-list=\"clearIdentifierList\"\n @clear-filters=\"clearFilters\"\n @clear-highlights=\"clearHighlights\"\n @refresh=\"refreshData\"\n />\n\n <!-- Spacer for visual separation -->\n <div class=\"filter-spacer\"></div>\n\n <!-- Matrix Grid -->\n <div\n class=\"matrix-scroll-container\"\n ref=\"scrollContainer\"\n >\n <!-- No matches message (inline, when filters exclude all results) -->\n <div v-if=\"filteredData.rows.length === 0 && hasActiveFilters\" class=\"no-matches-message\">\n <v-icon small color=\"grey\" class=\"mr-1\">mdi-filter-off</v-icon>\n No results match your filters\n </div>\n\n <template v-else>\n <!-- Header Row (CSS Grid for proper overflow of angled text) -->\n <div class=\"header-row\" :style=\"{ '--col-count': filteredData.columns.length }\">\n <div class=\"corner-cell\"></div>\n <div\n v-for=\"col in filteredData.columns\"\n :key=\"`header-${col}`\"\n class=\"header-cell\"\n :class=\"{ 'column-highlighted': highlightedColumnsMap[col] }\"\n @click=\"toggleColumnHighlight(col)\"\n >\n <span class=\"header-text\" :title=\"col\">{{ col }}</span>\n </div>\n </div>\n\n <!-- Data Table (same column widths as header) -->\n <table class=\"matrix-table\">\n <tbody>\n <tr v-for=\"row in filteredData.rows\" :key=\"row\">\n <td\n class=\"row-header\"\n :class=\"{ 'row-highlighted': highlightedRowsMap[row] }\"\n @click=\"toggleRowHighlight(row)\"\n >\n <span class=\"system-id\" :title=\"row\">{{ row }}</span>\n </td>\n <td\n v-for=\"col in filteredData.columns\"\n :key=\"col\"\n class=\"matrix-cell\"\n :class=\"{\n 'has-analyses': filteredData.cells[row]?.[col]?.length > 0,\n 'cell-highlighted': highlightedRowsMap[row] || highlightedColumnsMap[col],\n 'cell-selected': selectedCell && selectedCell.row === row && selectedCell.col === col\n }\"\n :data-row=\"row\"\n :data-col=\"col\"\n @click=\"handleCellClick($event, row, col)\"\n >\n <template v-if=\"filteredData.cells[row]?.[col]?.length\">\n <!-- Show stripes for small counts (\u2264 8) -->\n <div v-if=\"filteredData.cells[row][col].length <= 8\" class=\"cell-stripes\">\n <div\n v-for=\"(analysis, index) in filteredData.cells[row][col]\"\n :key=\"`${analysis.pk}-${analysis.experimentSystemId || ''}-${index}`\"\n class=\"stripe\"\n :style=\"{ backgroundColor: getStatusColor(analysis.status) }\"\n />\n </div>\n <!-- Show count badge for large counts (> 8) -->\n <div v-else class=\"cell-count-badge\" :style=\"{ backgroundColor: getPredominantColor(filteredData.cells[row][col]) }\">\n {{ filteredData.cells[row][col].length }}\n </div>\n </template>\n <span v-else class=\"empty-cell\">-</span>\n </td>\n </tr>\n </tbody>\n </table>\n </template>\n </div>\n\n <!-- Legend -->\n <matrix-legend\n :active-statuses=\"availableStatuses\"\n :view-mode=\"viewMode\"\n :stats=\"matrixStats\"\n />\n\n <!-- Native DOM Tooltip (bypasses Vue reactivity) -->\n <div\n ref=\"tooltip\"\n class=\"native-tooltip\"\n style=\"display: none;\"\n @mouseenter=\"handleTooltipEnter\"\n @mouseleave=\"handleTooltipLeave\"\n >\n <div class=\"tooltip-content\" ref=\"tooltipContent\"></div>\n </div>\n </template>\n </div>\n</template>\n\n<script>\nimport { fetchAllRecords } from '@/utils/api'\nimport {\n buildMatrixData,\n filterMatrixData,\n getStatusColor\n} from '@/utils/matrixHelpers'\nimport MatrixFilters from './MatrixFilters.vue'\nimport MatrixLegend from './MatrixLegend.vue'\n\nexport default {\n name: 'ProjectMatrix',\n components: {\n MatrixFilters,\n MatrixLegend\n },\n props: {\n projectId: {\n type: [String, Number],\n required: true\n }\n },\n data() {\n return {\n loading: false,\n refreshing: false,\n filtering: false,\n error: null,\n experiments: [],\n analyses: [],\n viewMode: 'experiment', // 'experiment' | 'individual'\n lockedProjectId: this.projectId, // Lock to initial project ID to prevent changes while modal is open\n matrixData: {\n rows: [],\n columns: [],\n cells: {},\n appVersions: {},\n viewMode: 'experiment',\n stats: {\n totalRows: 0,\n totalApps: 0,\n totalAnalyses: 0,\n byStatus: {},\n uniqueStatuses: [],\n uniqueAssemblies: [],\n uniqueTechniques: []\n }\n },\n filteredData: {\n rows: [],\n columns: [],\n cells: {},\n appVersions: {}\n },\n filters: {\n statuses: [],\n selectedColumns: [],\n experimentSearch: '',\n assemblies: [],\n techniques: [],\n identifierList: []\n },\n hideEmptyRows: false,\n highlightedRows: new Set(),\n highlightedColumns: new Set(),\n // Tooltip state (for native DOM tooltip)\n isOverTooltip: false,\n // Selected cell state\n selectedCell: null // { row, col }\n }\n },\n computed: {\n availableStatuses() {\n // Use pre-calculated stats from matrixData (avoids expensive iteration)\n return this.matrixData.stats?.uniqueStatuses || []\n },\n availableAssemblies() {\n // Use pre-calculated stats from matrixData\n return this.matrixData.stats?.uniqueAssemblies || []\n },\n availableTechniques() {\n // Use pre-calculated stats from matrixData\n return this.matrixData.stats?.uniqueTechniques || []\n },\n matrixStats() {\n // Use pre-calculated stats from matrixData (avoids expensive iteration on filter changes)\n // Note: Shows total stats, not filtered stats (for performance)\n const stats = this.matrixData.stats || {}\n return {\n totalRows: stats.totalRows || 0,\n totalApps: stats.totalApps || 0,\n totalAnalyses: stats.totalAnalyses || 0\n }\n },\n hasActiveFilters() {\n const columnsFiltered = this.filters.selectedColumns.length > 0 &&\n this.filters.selectedColumns.length < this.matrixData.columns.length\n return (\n this.filters.statuses.length > 0 ||\n columnsFiltered ||\n this.filters.experimentSearch ||\n this.filters.assemblies.length > 0 ||\n this.filters.techniques.length > 0 ||\n this.filters.identifierList.length > 0\n )\n },\n // Memoized highlight maps for O(1) lookup\n highlightedRowsMap() {\n const map = {}\n this.highlightedRows.forEach(r => { map[r] = true })\n return map\n },\n highlightedColumnsMap() {\n const map = {}\n this.highlightedColumns.forEach(c => { map[c] = true })\n return map\n },\n hasHighlights() {\n return this.highlightedRows.size > 0 || this.highlightedColumns.size > 0\n },\n // Count how many identifiers from the list actually exist in the data\n matchedIdentifierCount() {\n if (this.filters.identifierList.length === 0) return 0\n\n // Build case-insensitive set of all row IDs in the matrix\n const rowSet = new Set(\n this.matrixData.rows.map(row => row.toLowerCase())\n )\n\n // Count how many identifiers from the list exist in the data\n return this.filters.identifierList.filter(id =>\n rowSet.has(id.toLowerCase())\n ).length\n }\n },\n watch: {\n projectId: {\n immediate: true,\n handler(newId, oldId) {\n // Only fetch data on initial load (when oldId is undefined)\n // Ignore subsequent changes to keep matrix locked to original project\n if (oldId === undefined) {\n this.fetchData()\n }\n }\n },\n filters: {\n deep: true,\n handler() {\n this.applyFilters()\n }\n },\n hideEmptyRows() {\n this.applyFilters()\n },\n matrixData() {\n this.applyFilters()\n },\n 'filteredData.rows'() {\n // Reset scroll when data changes\n if (this.$refs.scrollContainer) {\n this.$refs.scrollContainer.scrollTop = 0\n }\n }\n },\n mounted() {\n // Close tooltip when clicking outside\n document.addEventListener('click', this.handleDocumentClick)\n },\n beforeDestroy() {\n document.removeEventListener('click', this.handleDocumentClick)\n },\n methods: {\n async fetchData(isRefresh = false) {\n // Set appropriate loading state\n if (isRefresh) {\n this.refreshing = true\n } else {\n this.loading = true\n }\n this.error = null\n\n // Store current filters before fetch (for refresh)\n const currentFilters = isRefresh ? { ...this.filters } : null\n\n try {\n // Fetch all experiments and analyses (with pagination)\n // Use lockedProjectId to prevent refetching if prop changes while modal is open\n const [experimentsRes, analysesRes] = await Promise.all([\n fetchAllRecords('experiments', {\n projects__pk: this.lockedProjectId,\n 'fields!': 'results,analytics,raw_data,bam_files'\n }),\n fetchAllRecords('analyses', {\n targets__projects__pk: this.lockedProjectId,\n 'fields!': 'targets,references,analytics,results'\n })\n ])\n\n this.experiments = experimentsRes.results || []\n this.analyses = analysesRes.results || []\n\n // Build matrix data and freeze it to prevent Vue reactivity overhead\n this.rebuildMatrixData()\n\n // Initialize selected columns to all columns (show all by default on initial load)\n // On refresh, restore previous filters\n if (isRefresh && currentFilters) {\n // Restore filters but ensure selectedColumns are still valid\n this.filters = {\n ...currentFilters,\n // Keep only columns that still exist after refresh\n selectedColumns: currentFilters.selectedColumns.filter(col =>\n this.matrixData.columns.includes(col)\n )\n }\n // If all selected columns were removed, default to all\n if (this.filters.selectedColumns.length === 0) {\n this.filters.selectedColumns = [...this.matrixData.columns]\n }\n } else {\n this.filters.selectedColumns = [...this.matrixData.columns]\n }\n } catch (err) {\n this.error = `Failed to load data: ${err.message}`\n console.error('Error loading matrix data:', err)\n } finally {\n if (isRefresh) {\n this.refreshing = false\n } else {\n this.loading = false\n }\n }\n },\n\n async refreshData() {\n await this.fetchData(true)\n },\n\n async applyFilters() {\n // Use requestAnimationFrame to yield to browser and prevent UI blocking\n await new Promise(resolve => requestAnimationFrame(resolve))\n\n // Filter matrix data (already frozen internally)\n // Include hideEmptyRows from component state\n this.filteredData = filterMatrixData(this.matrixData, {\n ...this.filters,\n hideEmptyRows: this.hideEmptyRows\n })\n },\n\n updateFilters(newFilters) {\n this.filters = { ...newFilters }\n },\n\n updateIdentifierList(identifiers) {\n this.filters.identifierList = identifiers\n },\n\n clearIdentifierList() {\n this.filters.identifierList = []\n },\n\n handleViewModeChange(newMode) {\n this.viewMode = newMode\n // Clear highlights and selection when switching views\n this.highlightedRows = new Set()\n this.highlightedColumns = new Set()\n this.selectedCell = null\n this.hideTooltipNative()\n // Rebuild matrix data with new view mode\n this.rebuildMatrixData()\n },\n\n rebuildMatrixData() {\n // buildMatrixData already freezes everything internally for performance\n this.matrixData = buildMatrixData(this.experiments, this.analyses, this.viewMode)\n // The watcher on matrixData will automatically call applyFilters()\n },\n\n handleOpenAnalysis(analysisId) {\n this.hideTooltipNative()\n this.$emit('open-analysis', analysisId)\n },\n\n toggleRowHighlight(row) {\n const newSet = new Set(this.highlightedRows)\n if (newSet.has(row)) {\n newSet.delete(row)\n } else {\n newSet.add(row)\n }\n this.highlightedRows = newSet\n },\n\n toggleColumnHighlight(col) {\n const newSet = new Set(this.highlightedColumns)\n if (newSet.has(col)) {\n newSet.delete(col)\n } else {\n newSet.add(col)\n }\n this.highlightedColumns = newSet\n },\n\n clearHighlights() {\n this.highlightedRows = new Set()\n this.highlightedColumns = new Set()\n },\n\n clearFilters() {\n this.filters = {\n statuses: [],\n selectedColumns: [],\n experimentSearch: '',\n assemblies: [],\n techniques: [],\n identifierList: []\n }\n },\n\n // Cell click handler - uses native DOM to avoid Vue re-renders\n handleCellClick(event, row, col) {\n console.log('handleCellClick called:', { row, col })\n const analyses = this.filteredData.cells[row]?.[col] || []\n console.log('analyses:', analyses.length)\n if (analyses.length === 0) return\n\n // Set selected cell\n this.selectedCell = { row, col }\n\n const rect = event.currentTarget.getBoundingClientRect()\n const tooltip = this.$refs.tooltip\n const content = this.$refs.tooltipContent\n\n console.log('tooltip ref:', !!tooltip, 'content ref:', !!content)\n if (!tooltip || !content) return\n\n // Store analyses for later use\n this._currentAnalyses = analyses\n\n // Build tooltip HTML directly (no Vue reactivity)\n const appName = analyses[0]?.application?.name || 'Unknown'\n let html = `<div class=\"tooltip-header\">${appName} - ${analyses.length} analysis${analyses.length !== 1 ? 'es' : ''}</div>`\n html += '<div class=\"tooltip-list\">'\n\n if (this.viewMode === 'individual') {\n // Group analyses by experiment for individual view\n const byExperiment = {}\n analyses.forEach(a => {\n const expId = a.experimentSystemId || 'Unknown'\n if (!byExperiment[expId]) {\n byExperiment[expId] = []\n }\n byExperiment[expId].push(a)\n })\n\n // Render grouped by experiment\n Object.entries(byExperiment).forEach(([expId, expAnalyses]) => {\n html += `<div class=\"experiment-group-header\">${expId}</div>`\n expAnalyses.forEach(a => {\n const color = this.getStatusColor(a.status)\n html += `<div class=\"tooltip-item\" data-pk=\"${a.pk}\">`\n html += `<span class=\"status-dot\" style=\"background:${color}\"></span>`\n html += `<span class=\"analysis-pk\">${a.pk}</span>`\n html += `<span class=\"sep\">|</span>`\n html += `<span class=\"version\">v${a.version || 'N/A'}</span>`\n if (a.assembly) html += `<span class=\"assembly\"> \xB7 ${a.assembly}</span>`\n html += `<span class=\"status-chip\" style=\"background:${color}\">${a.status}</span>`\n html += '</div>'\n })\n })\n } else {\n // Flat list for experiment view\n analyses.forEach(a => {\n const color = this.getStatusColor(a.status)\n html += `<div class=\"tooltip-item\" data-pk=\"${a.pk}\">`\n html += `<span class=\"status-dot\" style=\"background:${color}\"></span>`\n html += `<span class=\"analysis-pk\">${a.pk}</span>`\n html += `<span class=\"sep\">|</span>`\n html += `<span class=\"version\">v${a.version || 'N/A'}</span>`\n if (a.assembly) html += `<span class=\"assembly\"> \xB7 ${a.assembly}</span>`\n html += `<span class=\"status-chip\" style=\"background:${color}\">${a.status}</span>`\n html += '</div>'\n })\n }\n\n html += '</div>'\n content.innerHTML = html\n\n // Add click handlers to items\n content.querySelectorAll('.tooltip-item').forEach(item => {\n item.onclick = () => {\n const pk = parseInt(item.dataset.pk)\n this.hideTooltipNative()\n this.handleOpenAnalysis(pk)\n }\n })\n\n // Position and show tooltip\n tooltip.style.display = 'block'\n tooltip.style.left = `${rect.left + rect.width / 2}px`\n tooltip.style.top = `${rect.top - 8}px`\n console.log('tooltip positioned at:', {\n left: tooltip.style.left,\n top: tooltip.style.top,\n rectTop: rect.top,\n rectLeft: rect.left,\n display: tooltip.style.display\n })\n },\n\n hideTooltipNative() {\n const tooltip = this.$refs.tooltip\n if (tooltip) {\n tooltip.style.display = 'none'\n }\n },\n\n getStatusColor,\n\n getPredominantColor(analyses) {\n // Count occurrences of each status\n const statusCounts = {}\n analyses.forEach(a => {\n statusCounts[a.status] = (statusCounts[a.status] || 0) + 1\n })\n\n // Find the most common status\n let maxCount = 0\n let predominantStatus = 'SUCCEEDED' // default\n Object.entries(statusCounts).forEach(([status, count]) => {\n if (count > maxCount) {\n maxCount = count\n predominantStatus = status\n }\n })\n\n return getStatusColor(predominantStatus)\n },\n\n handleTooltipEnter() {\n this.isOverTooltip = true\n },\n\n handleTooltipLeave() {\n this.isOverTooltip = false\n this.hideTooltipNative()\n },\n\n handleDocumentClick(event) {\n const tooltip = this.$refs.tooltip\n\n // Check if click was inside tooltip\n if (tooltip && tooltip.contains(event.target)) return\n\n // Check if click was on a matrix cell (this opens tooltip, don't close it)\n if (event.target.closest('.matrix-cell.has-analyses')) return\n\n // Hide tooltip if visible\n this.hideTooltipNative()\n\n // Only clear selection if clicking inside the matrix scroll container\n // (not when clicking tabs, filters, etc.)\n const scrollContainer = this.$refs.scrollContainer\n if (scrollContainer && scrollContainer.contains(event.target)) {\n this.selectedCell = null\n }\n }\n }\n}\n</script>\n\n<style scoped>\n.project-matrix {\n display: flex;\n flex-direction: column;\n height: 100%;\n min-height: 400px;\n}\n\n.loading-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n min-height: 300px;\n}\n\n.filter-spacer {\n height: 16px;\n background: white;\n}\n\n.matrix-scroll-container {\n flex: 1;\n overflow: auto;\n max-height: calc(80vh - 180px);\n}\n\n.no-matches-message {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 24px;\n color: #666;\n font-size: 13px;\n}\n\n.matrix-table {\n border-collapse: separate;\n border-spacing: 0;\n table-layout: fixed;\n}\n\n/* Header row - CSS Grid for proper text overflow */\n.header-row {\n display: grid;\n grid-template-columns: 200px repeat(var(--col-count), 50px);\n position: sticky;\n top: 0;\n z-index: 10;\n background: white;\n min-width: fit-content;\n}\n\n/* Corner cell - top-left */\n.corner-cell {\n position: sticky;\n left: 0;\n z-index: 11;\n background: white;\n border-bottom: 2px solid #5b5dff;\n border-right: 2px solid #5b5dff;\n height: 130px;\n width: 200px;\n box-sizing: border-box;\n}\n\n/* Column headers - angled text */\n.header-cell {\n position: relative;\n height: 130px;\n width: 50px;\n border-bottom: 2px solid #5b5dff;\n background: white;\n overflow: visible;\n cursor: pointer;\n}\n\n.header-cell:hover .header-text {\n background: #FFF6DB;\n border-radius: 2px;\n}\n\n.header-cell.column-highlighted .header-text {\n background: #FFF0D9;\n border-radius: 2px;\n font-weight: 700;\n color: #000;\n}\n\n.header-text {\n position: absolute;\n bottom: 8px;\n left: 50%;\n transform: rotate(-45deg);\n transform-origin: bottom left;\n white-space: nowrap;\n font-size: 11px;\n font-weight: 500;\n color: #333;\n z-index: 1;\n}\n\n/* Row headers - width must match corner-cell (200px) */\ntd.row-header {\n position: sticky;\n left: 0;\n z-index: 1;\n background: white;\n border-right: 2px solid #5b5dff;\n padding: 0 8px;\n width: 200px;\n min-width: 200px;\n max-width: 200px;\n height: 24px;\n border-bottom: 1px solid #e0e0e0;\n cursor: pointer;\n vertical-align: middle;\n box-sizing: border-box;\n}\n\n.row-header.row-highlighted {\n background: #FFE8C5 !important;\n}\n\n.row-header.row-highlighted .system-id {\n font-weight: 700;\n color: #000;\n}\n\n.system-id {\n font-size: 11px;\n font-family: monospace;\n color: #333;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* Hover highlight for row header */\n.row-header:hover {\n background: #FFF0D9;\n}\n\n.row-header:hover .system-id {\n font-weight: 600;\n}\n\n/* Table cell styles - width must match header-cell (50px) */\ntd.matrix-cell {\n width: 50px;\n min-width: 50px;\n max-width: 50px;\n height: 24px;\n border-right: 1px solid #e0e0e0;\n border-bottom: 1px solid #e0e0e0;\n cursor: default;\n background: #fafafa;\n padding: 0;\n vertical-align: middle;\n box-sizing: border-box;\n}\n\n.matrix-cell.has-analyses {\n cursor: pointer;\n background: white;\n}\n\n.matrix-cell.has-analyses:hover,\n.matrix-cell.cell-selected {\n border-right-color: #5b5dff;\n border-bottom-color: #5b5dff;\n background: #f0f0ff;\n}\n\n.matrix-cell.cell-highlighted {\n background: #FFE8C5;\n}\n\n.cell-stripes {\n display: flex;\n align-items: stretch;\n justify-content: center;\n gap: 1px;\n height: 100%;\n width: 100%;\n padding: 2px 4px;\n}\n\n.stripe {\n flex: 0 0 auto;\n width: 3px;\n min-width: 2px;\n max-width: 5px;\n border-radius: 1px;\n}\n\n.cell-count-badge {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n color: white;\n font-size: 10px;\n font-weight: 600;\n text-shadow: 0 0 2px rgba(0, 0, 0, 0.3);\n}\n\n.empty-cell {\n display: flex;\n align-items: center;\n justify-content: center;\n color: #ccc;\n font-size: 10px;\n height: 100%;\n}\n\n/* Native tooltip styles - use ::v-deep for dynamically generated content */\n.native-tooltip {\n position: fixed;\n transform: translateX(-50%) translateY(-100%);\n z-index: 9999;\n background: white;\n border-radius: 4px;\n box-shadow: 0 2px 8px rgba(0,0,0,0.2);\n min-width: 280px;\n max-width: 350px;\n max-height: 300px;\n overflow-y: auto;\n}\n\n.native-tooltip ::v-deep .tooltip-header {\n padding: 8px 12px;\n background: #f5f5f5;\n font-weight: 500;\n font-size: 13px;\n border-bottom: 1px solid #e0e0e0;\n}\n\n.native-tooltip ::v-deep .tooltip-list {\n padding: 4px 0;\n}\n\n.native-tooltip ::v-deep .tooltip-item {\n display: flex;\n align-items: center;\n padding: 6px 12px;\n cursor: pointer;\n font-size: 12px;\n}\n\n.native-tooltip ::v-deep .tooltip-item:hover {\n background: #e3f2fd;\n}\n\n.native-tooltip ::v-deep .tooltip-item .status-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n margin-right: 8px;\n flex-shrink: 0;\n}\n\n.native-tooltip ::v-deep .tooltip-item .analysis-pk {\n color: #1976d2;\n font-weight: 500;\n}\n\n.native-tooltip ::v-deep .tooltip-item .sep {\n margin: 0 6px;\n color: #999;\n}\n\n.native-tooltip ::v-deep .tooltip-item .version {\n color: #666;\n}\n\n.native-tooltip ::v-deep .tooltip-item .assembly {\n color: #999;\n}\n\n.native-tooltip ::v-deep .tooltip-item .status-chip {\n margin-left: auto;\n padding: 2px 6px;\n border-radius: 3px;\n color: white;\n font-size: 10px;\n font-weight: 500;\n}\n\n.native-tooltip ::v-deep .experiment-group-header {\n padding: 6px 12px 4px;\n font-size: 11px;\n font-weight: 600;\n color: #1976d2;\n background: #f8f9fa;\n border-top: 1px solid #e0e0e0;\n font-family: monospace;\n}\n\n.native-tooltip ::v-deep .experiment-group-header:first-child {\n border-top: none;\n}\n</style>\n"]
346559
346570
  },
346560
346571
  _coverageSchema: "43e27e138ebf9cfc5966b082cf9a028302ed4184",
346561
- hash: "4d6068187e3b09b0395493ca183ae0ed262ae00e"
346572
+ hash: "a0c0d0bf4b1dd7c7c1e69ed5b9fb98baf888abe6"
346562
346573
  };
346563
346574
  var coverage = global[gcv] || (global[gcv] = {});
346564
346575
  if (coverage[path] && coverage[path].hash === hash) {
@@ -347231,14 +347242,22 @@ function ProjectMatrixvue_type_script_lang_js_asyncToGenerator(fn) { return func
347231
347242
  tooltip.style.left = "".concat(rect.left + rect.width / 2, "px");
347232
347243
  ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[138]++;
347233
347244
  tooltip.style.top = "".concat(rect.top - 8, "px");
347245
+ ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[139]++;
347246
+ console.log('tooltip positioned at:', {
347247
+ left: tooltip.style.left,
347248
+ top: tooltip.style.top,
347249
+ rectTop: rect.top,
347250
+ rectLeft: rect.left,
347251
+ display: tooltip.style.display
347252
+ });
347234
347253
  },
347235
347254
  hideTooltipNative: function hideTooltipNative() {
347236
347255
  ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.f[43]++;
347237
- var tooltip = (ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[139]++, this.$refs.tooltip);
347238
- ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[140]++;
347256
+ var tooltip = (ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[140]++, this.$refs.tooltip);
347257
+ ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[141]++;
347239
347258
  if (tooltip) {
347240
347259
  ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.b[37][0]++;
347241
- ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[141]++;
347260
+ ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[142]++;
347242
347261
  tooltip.style.display = 'none';
347243
347262
  } else {
347244
347263
  ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.b[37][1]++;
@@ -347248,84 +347267,84 @@ function ProjectMatrixvue_type_script_lang_js_asyncToGenerator(fn) { return func
347248
347267
  getPredominantColor: function getPredominantColor(analyses) {
347249
347268
  ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.f[44]++;
347250
347269
  // Count occurrences of each status
347251
- var statusCounts = (ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[142]++, {});
347252
- ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[143]++;
347270
+ var statusCounts = (ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[143]++, {});
347271
+ ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[144]++;
347253
347272
  analyses.forEach(function (a) {
347254
347273
  ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.f[45]++;
347255
- ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[144]++;
347274
+ ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[145]++;
347256
347275
  statusCounts[a.status] = ((ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.b[38][0]++, statusCounts[a.status]) || (ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.b[38][1]++, 0)) + 1;
347257
347276
  });
347258
347277
 
347259
347278
  // Find the most common status
347260
- var maxCount = (ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[145]++, 0);
347261
- var predominantStatus = (ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[146]++, 'SUCCEEDED'); // default
347262
- ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[147]++;
347279
+ var maxCount = (ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[146]++, 0);
347280
+ var predominantStatus = (ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[147]++, 'SUCCEEDED'); // default
347281
+ ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[148]++;
347263
347282
  Object.entries(statusCounts).forEach(function (_ref5) {
347264
347283
  var _ref6 = ProjectMatrixvue_type_script_lang_js_slicedToArray(_ref5, 2),
347265
347284
  status = _ref6[0],
347266
347285
  count = _ref6[1];
347267
347286
  ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.f[46]++;
347268
- ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[148]++;
347287
+ ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[149]++;
347269
347288
  if (count > maxCount) {
347270
347289
  ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.b[39][0]++;
347271
- ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[149]++;
347272
- maxCount = count;
347273
347290
  ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[150]++;
347291
+ maxCount = count;
347292
+ ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[151]++;
347274
347293
  predominantStatus = status;
347275
347294
  } else {
347276
347295
  ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.b[39][1]++;
347277
347296
  }
347278
347297
  });
347279
- ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[151]++;
347298
+ ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[152]++;
347280
347299
  return getStatusColor(predominantStatus);
347281
347300
  },
347282
347301
  handleTooltipEnter: function handleTooltipEnter() {
347283
347302
  ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.f[47]++;
347284
- ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[152]++;
347303
+ ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[153]++;
347285
347304
  this.isOverTooltip = true;
347286
347305
  },
347287
347306
  handleTooltipLeave: function handleTooltipLeave() {
347288
347307
  ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.f[48]++;
347289
- ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[153]++;
347290
- this.isOverTooltip = false;
347291
347308
  ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[154]++;
347309
+ this.isOverTooltip = false;
347310
+ ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[155]++;
347292
347311
  this.hideTooltipNative();
347293
347312
  },
347294
347313
  handleDocumentClick: function handleDocumentClick(event) {
347295
347314
  ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.f[49]++;
347296
- var tooltip = (ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[155]++, this.$refs.tooltip);
347315
+ var tooltip = (ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[156]++, this.$refs.tooltip);
347297
347316
 
347298
347317
  // Check if click was inside tooltip
347299
- ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[156]++;
347318
+ ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[157]++;
347300
347319
  if ((ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.b[41][0]++, tooltip) && (ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.b[41][1]++, tooltip.contains(event.target))) {
347301
347320
  ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.b[40][0]++;
347302
- ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[157]++;
347321
+ ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[158]++;
347303
347322
  return;
347304
347323
  } else {
347305
347324
  ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.b[40][1]++;
347306
347325
  }
347307
347326
 
347308
347327
  // Check if click was on a matrix cell (this opens tooltip, don't close it)
347309
- ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[158]++;
347328
+ ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[159]++;
347310
347329
  if (event.target.closest('.matrix-cell.has-analyses')) {
347311
347330
  ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.b[42][0]++;
347312
- ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[159]++;
347331
+ ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[160]++;
347313
347332
  return;
347314
347333
  } else {
347315
347334
  ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.b[42][1]++;
347316
347335
  }
347317
347336
 
347318
347337
  // Hide tooltip if visible
347319
- ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[160]++;
347338
+ ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[161]++;
347320
347339
  this.hideTooltipNative();
347321
347340
 
347322
347341
  // Only clear selection if clicking inside the matrix scroll container
347323
347342
  // (not when clicking tabs, filters, etc.)
347324
- var scrollContainer = (ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[161]++, this.$refs.scrollContainer);
347325
- ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[162]++;
347343
+ var scrollContainer = (ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[162]++, this.$refs.scrollContainer);
347344
+ ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[163]++;
347326
347345
  if ((ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.b[44][0]++, scrollContainer) && (ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.b[44][1]++, scrollContainer.contains(event.target))) {
347327
347346
  ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.b[43][0]++;
347328
- ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[163]++;
347347
+ ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.s[164]++;
347329
347348
  this.selectedCell = null;
347330
347349
  } else {
347331
347350
  ProjectMatrixvue_type_script_lang_js_cov_geimehe8j.b[43][1]++;
@@ -347335,9 +347354,9 @@ function ProjectMatrixvue_type_script_lang_js_asyncToGenerator(fn) { return func
347335
347354
  });
347336
347355
  ;// CONCATENATED MODULE: ./src/components/projects/ProjectMatrix.vue?vue&type=script&lang=js&
347337
347356
  /* harmony default export */ var projects_ProjectMatrixvue_type_script_lang_js_ = (ProjectMatrixvue_type_script_lang_js_);
347338
- // EXTERNAL MODULE: ./node_modules/vue-style-loader/index.js??clonedRuleSet-12.use[0]!./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[3]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./src/components/projects/ProjectMatrix.vue?vue&type=style&index=0&id=2742f691&prod&scoped=true&lang=css&
347339
- var ProjectMatrixvue_type_style_index_0_id_2742f691_prod_scoped_true_lang_css_ = __webpack_require__(16679);
347340
- ;// CONCATENATED MODULE: ./src/components/projects/ProjectMatrix.vue?vue&type=style&index=0&id=2742f691&prod&scoped=true&lang=css&
347357
+ // EXTERNAL MODULE: ./node_modules/vue-style-loader/index.js??clonedRuleSet-12.use[0]!./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[3]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./src/components/projects/ProjectMatrix.vue?vue&type=style&index=0&id=28c10d94&prod&scoped=true&lang=css&
347358
+ var ProjectMatrixvue_type_style_index_0_id_28c10d94_prod_scoped_true_lang_css_ = __webpack_require__(77240);
347359
+ ;// CONCATENATED MODULE: ./src/components/projects/ProjectMatrix.vue?vue&type=style&index=0&id=28c10d94&prod&scoped=true&lang=css&
347341
347360
 
347342
347361
  ;// CONCATENATED MODULE: ./src/components/projects/ProjectMatrix.vue
347343
347362
 
@@ -347350,11 +347369,11 @@ var ProjectMatrixvue_type_style_index_0_id_2742f691_prod_scoped_true_lang_css_ =
347350
347369
 
347351
347370
  var ProjectMatrix_component = normalizeComponent(
347352
347371
  projects_ProjectMatrixvue_type_script_lang_js_,
347353
- ProjectMatrixvue_type_template_id_2742f691_scoped_true_render,
347354
- ProjectMatrixvue_type_template_id_2742f691_scoped_true_staticRenderFns,
347372
+ ProjectMatrixvue_type_template_id_28c10d94_scoped_true_render,
347373
+ ProjectMatrixvue_type_template_id_28c10d94_scoped_true_staticRenderFns,
347355
347374
  false,
347356
347375
  null,
347357
- "2742f691",
347376
+ "28c10d94",
347358
347377
  null
347359
347378
 
347360
347379
  )