@abi-software/simulationvuer 3.0.9 → 3.0.10-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,14 +1,17 @@
1
1
  <template>
2
2
  <div class="simulation-vuer" v-loading="showUserMessage" :element-loading-text="userMessage">
3
3
  <div class="container" v-if="opencorOmexFile === null">
4
- <p v-if="!hasValidSimulationUiInfo && !showUserMessage" class="default error"><span class="error">Error:</span> {{ errorMessage }}.</p>
4
+ <p v-if="!hasValidSimulationUiInfo && !showUserMessage" class="default error">
5
+ <span class="error">Error:</span> {{ errorMessage }}.
6
+ </p>
5
7
  <div class="main" v-if="hasValidSimulationUiInfo">
6
- <div class="main-left" :class="{'with-buttons': uuid}">
8
+ <div class="main-left" :class="{ 'with-buttons': uuid }">
7
9
  <p class="default name">{{ name }}</p>
8
10
  <el-divider></el-divider>
9
11
  <p class="default input-parameters">Input parameters</p>
10
12
  <div class="input scrollbar">
11
- <SimulationVuerInput v-for="(input, index) in simulationUiInfo.input"
13
+ <SimulationVuerInput
14
+ v-for="(input, index) in simulationUiInfo.input"
12
15
  ref="simInput"
13
16
  :defaultValue="input.defaultValue"
14
17
  :key="`input-${index}`"
@@ -33,7 +36,8 @@
33
36
  </div>
34
37
  </div>
35
38
  <div class="main-right" ref="output" v-show="isSimulationValid">
36
- <PlotVuer v-for="(_outputPlot, index) in simulationUiInfo.output.plots"
39
+ <PlotVuer
40
+ v-for="(_outputPlot, index) in simulationUiInfo.output.plots"
37
41
  :key="`output-${index}`"
38
42
  :metadata="plotMetadata(index)"
39
43
  :data-source="{ data: simulationResults[index] }"
@@ -43,7 +47,10 @@
43
47
  />
44
48
  </div>
45
49
  <div class="main-right" v-show="!isSimulationValid">
46
- <p class="default error"><span class="error">Error:</span> <span v-html="errorMessage"></span>.</p>
50
+ <p class="default error">
51
+ <span class="error">Error:</span>
52
+ <span v-html="errorMessage"></span>.
53
+ </p>
47
54
  </div>
48
55
  </div>
49
56
  </div>
@@ -53,33 +60,150 @@
53
60
  </div>
54
61
  </template>
55
62
 
63
+ <script setup>
64
+ import { onMounted, onUnmounted, ref } from 'vue'
65
+
66
+ const emit = defineEmits(['data-notification'])
67
+
68
+ const activeSubscriptions = ref([])
69
+ // Only for demonstration purposes.
70
+ let intervalTimer = null
71
+
72
+ // Only for demonstration purposes.
73
+ function getMockValue(type, tick) {
74
+ if (type === 'sine') return Math.sin(tick * 0.1) * 10
75
+ if (type === 'linear') return tick
76
+ return Math.random() * 10
77
+ }
78
+
79
+ // Only for demonstration purposes.
80
+ function mockType(req) {
81
+ return Math.random() < 0.5 ? 'sine' : 'random'
82
+ }
83
+
84
+ // Only for demonstration purposes.
85
+ function generateMockSeries(type, length = 100) {
86
+ const data = []
87
+ for (let i = 0; i < length; i++) {
88
+ data.push(getMockValue(type, i))
89
+ }
90
+ return data
91
+ }
92
+
93
+ function addDataSubscription(subscription) {
94
+ if (!subscription || typeof subscription !== 'object') {
95
+ console.error('addDataSubscription: Subscription must be an object.')
96
+ return
97
+ }
98
+
99
+ const EXPECTED_ID = 'nz.ac.auckland.simulation-data-request'
100
+ const EXPECTED_MAJOR_VERSION = 0
101
+
102
+ if (subscription.id !== EXPECTED_ID) {
103
+ console.warn(`Request ignored: Invalid ID '${subscription.id}'`)
104
+ return
105
+ }
106
+
107
+ const subscriptionMajorVersion = parseInt(subscription.version.split('.')[0])
108
+ if (subscriptionMajorVersion !== EXPECTED_MAJOR_VERSION) {
109
+ console.warn(
110
+ `Request ignored: Version mismatch. Expected v${EXPECTED_MAJOR_VERSION}.x, got v${subscription.version}`
111
+ )
112
+ return
113
+ }
114
+
115
+ activeSubscriptions.value.push(subscription.payload)
116
+ sendDataForSubscription(subscription.payload)
117
+ }
118
+
119
+ function sendDataForSubscription(dataSubscription) {
120
+ // Only for demonstration purposes.
121
+ const type = mockType(dataSubscription)
122
+ let data = {
123
+ y: generateMockSeries(type, 100),
124
+ title: `${dataSubscription.component}.${dataSubscription.variable}`,
125
+ }
126
+ if (dataSubscription.withVOI) {
127
+ const voi_type = 'linear'
128
+ data.x = generateMockSeries(voi_type, 100)
129
+ }
130
+
131
+ const response = {
132
+ id: 'nz.ac.auckland.simulation-data-response',
133
+ version: '0.1.0',
134
+ payload: {
135
+ windowId: dataSubscription.windowId,
136
+ ownerId: dataSubscription.ownerId,
137
+ data: data,
138
+ },
139
+ }
140
+
141
+ emit('data-notification', response)
142
+ }
143
+
144
+ function removeDataSubscription(subscriptionId) {
145
+ activeSubscriptions.value = activeSubscriptions.value.filter(
146
+ (sub) => sub.windowId !== subscriptionId
147
+ )
148
+ }
149
+
150
+ defineExpose({ addDataSubscription, removeDataSubscription })
151
+
152
+ // Only for demonstration purposes.
153
+ onMounted(() => {
154
+ intervalTimer = setInterval(() => {
155
+ if (activeSubscriptions.value.length === 0) return
156
+
157
+ activeSubscriptions.value.forEach((subscription) => {
158
+ sendDataForSubscription(subscription)
159
+ })
160
+ }, 3000)
161
+ })
162
+
163
+ // Only for demonstration purposes.
164
+ onUnmounted(() => {
165
+ if (intervalTimer) clearInterval(intervalTimer)
166
+ })
167
+ </script>
168
+
56
169
  <script>
57
- import { PlotVuer } from "@abi-software/plotvuer";
58
- import "@abi-software/plotvuer/dist/style.css";
59
- import SimulationVuerInput from "./SimulationVuerInput.vue";
60
- import { ElButton, ElDivider, ElLoading } from "element-plus";
61
- import { evaluateValue, finaliseUi, OPENCOR_SOLVER_NAME } from "./common.js";
62
- import { validJson } from "./json.js";
63
- import { create, all } from "mathjs";
64
- import OpenCOR from '@opencor/opencor';
65
- import '@opencor/opencor/style.css';
170
+ import { PlotVuer } from '@abi-software/plotvuer'
171
+ import '@abi-software/plotvuer/dist/style.css'
172
+ import SimulationVuerInput from './SimulationVuerInput.vue'
173
+ import { ElButton, ElDivider, ElLoading } from 'element-plus'
174
+ import { evaluateValue, finaliseUi, OPENCOR_SOLVER_NAME } from './common.js'
175
+ import { validJson } from './json.js'
176
+ import { create, all } from 'mathjs'
177
+ import OpenCOR from '@opencor/opencor'
178
+ import '@opencor/opencor/style.css'
66
179
 
67
- const PMR_URL = "https://models.physiomeproject.org/";
180
+ const PMR_URL = 'https://models.physiomeproject.org/'
68
181
 
69
- const math = create(all, {});
182
+ const math = create(all, {})
70
183
 
71
184
  const IdType = Object.freeze({
72
185
  DATASET_ID: 'dataset_id',
73
186
  DATASET_URL: 'dataset_url',
74
187
  PMR_PATH: 'pmr_path',
75
188
  RAW_COMBINE_ARCHIVE: 'raw_combine_archive',
76
- });
189
+ })
190
+
191
+ function isWebProtocol(urlString) {
192
+ try {
193
+ const url = new URL(urlString)
194
+ // Protocol property includes the colon, e.g., "https:".
195
+ return url.protocol === 'http:' || url.protocol === 'https:'
196
+ } catch (_err) {
197
+ // String was not a valid URL.
198
+ return false
199
+ }
200
+ }
77
201
 
78
202
  /**
79
203
  * SimulationVuer
80
204
  */
81
205
  export default {
82
- name: "SimulationVuer",
206
+ name: 'SimulationVuer',
83
207
  components: {
84
208
  PlotVuer,
85
209
  SimulationVuerInput,
@@ -111,39 +235,39 @@ export default {
111
235
  data: function () {
112
236
  // Determine the ID's type.
113
237
 
114
- let idType;
238
+ let idType
115
239
 
116
- if (typeof this.id === "number") {
117
- idType = IdType.DATASET_ID;
240
+ if (typeof this.id === 'number') {
241
+ idType = IdType.DATASET_ID
118
242
  } else if (this.id instanceof Uint8Array) {
119
- idType = IdType.RAW_COMBINE_ARCHIVE;
120
- } else if (this.id.startsWith("https://")) {
121
- idType = IdType.DATASET_URL;
243
+ idType = IdType.RAW_COMBINE_ARCHIVE
244
+ } else if (isWebProtocol(this.id)) {
245
+ idType = IdType.DATASET_URL
122
246
  } else {
123
- idType = IdType.PMR_PATH;
247
+ idType = IdType.PMR_PATH
124
248
  }
125
249
 
126
250
  // Retrieve some information about the dataset.
127
251
 
128
252
  if (idType === IdType.DATASET_ID) {
129
- const xmlhttp = new XMLHttpRequest();
253
+ const xmlhttp = new XMLHttpRequest()
130
254
 
131
- xmlhttp.open("GET", this.apiLocation + "/sim/dataset/" + this.id);
255
+ xmlhttp.open('GET', this.apiLocation + '/sim/dataset/' + this.id)
132
256
  xmlhttp.onreadystatechange = () => {
133
257
  if (xmlhttp.readyState === 4) {
134
258
  if (xmlhttp.status === 200) {
135
- const datasetInfo = JSON.parse(xmlhttp.responseText);
259
+ const datasetInfo = JSON.parse(xmlhttp.responseText)
136
260
 
137
- this.name = datasetInfo.name;
138
- this.uuid = (datasetInfo.study !== undefined) ? datasetInfo.study.uuid : undefined;
261
+ this.name = datasetInfo.name
262
+ this.uuid = datasetInfo.study !== undefined ? datasetInfo.study.uuid : undefined
139
263
  }
140
264
  }
141
- };
142
- xmlhttp.send();
265
+ }
266
+ xmlhttp.send()
143
267
  }
144
268
 
145
269
  return {
146
- errorMessage: "",
270
+ errorMessage: '',
147
271
  fileManager: undefined,
148
272
  hasFinalisedUi: false,
149
273
  hasValidSimulationUiInfo: false,
@@ -165,10 +289,10 @@ export default {
165
289
  simulationResultsId: {},
166
290
  simulationUiInfo: {},
167
291
  solver: undefined,
168
- userMessage: "",
292
+ userMessage: '',
169
293
  ui: null,
170
294
  uuid: null,
171
- };
295
+ }
172
296
  },
173
297
  methods: {
174
298
  /**
@@ -178,13 +302,13 @@ export default {
178
302
  */
179
303
  plotMetadata(index) {
180
304
  return {
181
- version: "1.1.0",
182
- type: "plot",
305
+ version: '1.1.0',
306
+ type: 'plot',
183
307
  attrs: {
184
- style: "timeseries",
308
+ style: 'timeseries',
185
309
  layout: this.layout[index],
186
310
  },
187
- };
311
+ }
188
312
  },
189
313
  /**
190
314
  * @public
@@ -194,49 +318,49 @@ export default {
194
318
  buildSimulationUi(simulationUiInfo) {
195
319
  // Keep track of the simulation UI information.
196
320
 
197
- this.simulationUiInfo = simulationUiInfo;
321
+ this.simulationUiInfo = simulationUiInfo
198
322
 
199
323
  // Make sure that the simulation UI information is valid.
200
324
 
201
- this.hasValidSimulationUiInfo = validJson(this.simulationUiInfo);
325
+ this.hasValidSimulationUiInfo = validJson(this.simulationUiInfo)
202
326
 
203
327
  if (!this.hasValidSimulationUiInfo) {
204
- this.errorMessage = "the simulation.json file is malformed";
328
+ this.errorMessage = 'the simulation.json file is malformed'
205
329
 
206
- return;
330
+ return
207
331
  }
208
332
 
209
333
  // Retrieve and keep track of the solver to be used for the simulation.
210
334
 
211
335
  this.simulationUiInfo.simulation.solvers.forEach((solver) => {
212
- if ((solver.if === undefined) || evaluateValue(this, solver.if)) {
213
- this.solver = solver;
336
+ if (solver.if === undefined || evaluateValue(this, solver.if)) {
337
+ this.solver = solver
214
338
  }
215
- });
339
+ })
216
340
 
217
341
  if (this.solver === undefined) {
218
- this.hasValidSimulationUiInfo = false;
219
- this.errorMessage = "no solver name and/or solver version specified";
342
+ this.hasValidSimulationUiInfo = false
343
+ this.errorMessage = 'no solver name and/or solver version specified'
220
344
 
221
- return;
345
+ return
222
346
  }
223
347
 
224
- this.opencorBasedSimulation = this.solver.name === OPENCOR_SOLVER_NAME;
348
+ this.opencorBasedSimulation = this.solver.name === OPENCOR_SOLVER_NAME
225
349
 
226
350
  // Initialise our UI.
227
351
 
228
352
  this.simulationUiInfo.output.data.forEach((data) => {
229
- this.simulationResultsId[data.id] = data.name;
230
- });
353
+ this.simulationResultsId[data.id] = data.name
354
+ })
231
355
 
232
- let index = -1;
356
+ let index = -1
233
357
 
234
358
  this.simulationUiInfo.output.plots.forEach((outputPlot) => {
235
- ++index;
359
+ ++index
236
360
 
237
361
  this.layout[index] = {
238
- paper_bgcolor: "rgba(0, 0, 0, 0)",
239
- plot_bgcolor: "rgba(0, 0, 0, 0)",
362
+ paper_bgcolor: 'rgba(0, 0, 0, 0)',
363
+ plot_bgcolor: 'rgba(0, 0, 0, 0)',
240
364
  autosize: true,
241
365
  margin: {
242
366
  t: 25,
@@ -250,7 +374,7 @@ export default {
250
374
  responsive: true,
251
375
  scrollZoom: true,
252
376
  },
253
- dragmode: "pan",
377
+ dragmode: 'pan',
254
378
  xaxis: {
255
379
  title: {
256
380
  text: outputPlot.xAxisTitle,
@@ -267,8 +391,8 @@ export default {
267
391
  },
268
392
  },
269
393
  },
270
- };
271
- });
394
+ }
395
+ })
272
396
 
273
397
  // Finalise our UI.
274
398
  // Note: we try both here and in the mounted() function since we have no
@@ -276,8 +400,8 @@ export default {
276
400
  // information.
277
401
 
278
402
  this.$nextTick(() => {
279
- finaliseUi(this);
280
- });
403
+ finaliseUi(this)
404
+ })
281
405
  },
282
406
  /**
283
407
  * @public
@@ -286,7 +410,7 @@ export default {
286
410
  * method.
287
411
  */
288
412
  runOnOsparc() {
289
- window.open(`https://osparc.io/study/${this.uuid}`, "_blank");
413
+ window.open(`https://osparc.io/study/${this.uuid}`, '_blank')
290
414
  },
291
415
  /**
292
416
  * @public
@@ -294,7 +418,7 @@ export default {
294
418
  * clicked, calls this method.
295
419
  */
296
420
  viewDataset() {
297
- window.open(`https://sparc.science/datasets/${this.id}?type=dataset`, "_blank");
421
+ window.open(`https://sparc.science/datasets/${this.id}?type=dataset`, '_blank')
298
422
  },
299
423
  /**
300
424
  * @public
@@ -302,22 +426,22 @@ export default {
302
426
  * calls this method.
303
427
  */
304
428
  viewWorkspace() {
305
- const url = PMR_URL + this.id;
429
+ const url = PMR_URL + this.id
306
430
 
307
- window.open(url.substring(0, url.lastIndexOf("/")), "_blank");
431
+ window.open(url.substring(0, url.lastIndexOf('/')), '_blank')
308
432
  },
309
433
  /**
310
434
  * @public
311
435
  * Data needed to set a model's parameters.
312
436
  */
313
437
  parametersData() {
314
- const res = {};
438
+ const res = {}
315
439
 
316
440
  this.simulationUiInfo.parameters.forEach((parameter) => {
317
- res[parameter.name] = evaluateValue(this, parameter.value);
318
- });
441
+ res[parameter.name] = evaluateValue(this, parameter.value)
442
+ })
319
443
 
320
- return res;
444
+ return res
321
445
  },
322
446
  /**
323
447
  * @public
@@ -326,15 +450,15 @@ export default {
326
450
  outputData() {
327
451
  if (this.output === undefined) {
328
452
  if (this.simulationUiInfo.output.data !== undefined) {
329
- this.output = [];
453
+ this.output = []
330
454
 
331
455
  this.simulationUiInfo.output.data.forEach((output) => {
332
- this.output.push(output.name);
333
- });
456
+ this.output.push(output.name)
457
+ })
334
458
  }
335
459
  }
336
460
 
337
- return this.output;
461
+ return this.output
338
462
  },
339
463
  /**
340
464
  * @public
@@ -342,37 +466,39 @@ export default {
342
466
  */
343
467
  retrieveRequest() {
344
468
  const request = {
345
- solver: this.solver
346
- };
469
+ solver: this.solver,
470
+ }
347
471
 
348
472
  if (this.opencorBasedSimulation) {
349
473
  request.opencor = {
350
474
  model_url: this.simulationUiInfo.simulation.opencor.resource,
351
475
  json_config: {},
352
- };
476
+ }
353
477
 
354
- if ((this.simulationUiInfo.simulation.opencor.endingPoint !== undefined)
355
- && (this.simulationUiInfo.simulation.opencor.pointInterval !== undefined)) {
478
+ if (
479
+ this.simulationUiInfo.simulation.opencor.endingPoint !== undefined &&
480
+ this.simulationUiInfo.simulation.opencor.pointInterval !== undefined
481
+ ) {
356
482
  request.opencor.json_config.simulation = {
357
- "Ending point": this.simulationUiInfo.simulation.opencor.endingPoint,
358
- "Point interval": this.simulationUiInfo.simulation.opencor.pointInterval,
359
- };
483
+ 'Ending point': this.simulationUiInfo.simulation.opencor.endingPoint,
484
+ 'Point interval': this.simulationUiInfo.simulation.opencor.pointInterval,
485
+ }
360
486
  }
361
487
 
362
- request.opencor.json_config.parameters = this.parametersData();
488
+ request.opencor.json_config.parameters = this.parametersData()
363
489
 
364
- const output = this.outputData();
490
+ const output = this.outputData()
365
491
 
366
492
  if (output !== undefined) {
367
- request.opencor.json_config.output = output;
493
+ request.opencor.json_config.output = output
368
494
  }
369
495
  } else {
370
- request.osparc = {};
496
+ request.osparc = {}
371
497
 
372
- request.osparc.job_inputs = this.parametersData();
498
+ request.osparc.job_inputs = this.parametersData()
373
499
  }
374
500
 
375
- return request;
501
+ return request
376
502
  },
377
503
  /**
378
504
  * @public
@@ -384,50 +510,50 @@ export default {
384
510
  // Convert, if needed, the results to a JSON format that is compatible
385
511
  // with our OpenCOR results.
386
512
 
387
- if (typeof (results) === "string") {
388
- const SPACES = /[ \t]+/g;
389
- const lines = results.trim().split("\n");
390
- const iMax = lines[0].trim().split(SPACES).length;
513
+ if (typeof results === 'string') {
514
+ const SPACES = /[ \t]+/g
515
+ const lines = results.trim().split('\n')
516
+ const iMax = lines[0].trim().split(SPACES).length
391
517
 
392
- results = {};
518
+ results = {}
393
519
 
394
520
  for (let i = 0; i < iMax; ++i) {
395
- results[i] = [];
521
+ results[i] = []
396
522
  }
397
523
 
398
- let i = -1;
524
+ let i = -1
399
525
 
400
526
  lines.forEach((line) => {
401
- ++i;
527
+ ++i
402
528
 
403
- let j = -1;
404
- const values = line.trim().split(SPACES);
529
+ let j = -1
530
+ const values = line.trim().split(SPACES)
405
531
 
406
532
  values.forEach((value) => {
407
- results[++j][i] = Number(value);
408
- });
409
- });
533
+ results[++j][i] = Number(value)
534
+ })
535
+ })
410
536
  }
411
537
 
412
538
  // Get the results ready for plotting.
413
539
 
414
- const parser = new math.parser();
540
+ const parser = new math.parser()
415
541
 
416
542
  Object.keys(this.simulationResultsId).forEach((id) => {
417
- parser.set(id, results[this.simulationResultsId[id]]);
418
- });
543
+ parser.set(id, results[this.simulationResultsId[id]])
544
+ })
419
545
 
420
- let index = -1;
546
+ let index = -1
421
547
 
422
548
  this.simulationUiInfo.output.plots.forEach((outputPlot) => {
423
549
  this.simulationResults[++index] = [
424
550
  {
425
551
  x: parser.evaluate(outputPlot.xValue),
426
552
  y: parser.evaluate(outputPlot.yValue),
427
- type: "scatter",
553
+ type: 'scatter',
428
554
  },
429
- ];
430
- });
555
+ ]
556
+ })
431
557
  },
432
558
  /**
433
559
  * @public
@@ -435,9 +561,15 @@ export default {
435
561
  * @arg `xmlhttp`
436
562
  */
437
563
  showHttpIssue(xmlhttp) {
438
- this.isSimulationValid = false;
439
- this.showUserMessage = false;
440
- this.errorMessage = xmlhttp.statusText.toLowerCase() + " (<a href='https://httpstatuses.com/" + xmlhttp.status + "/' target='_blank'>" + xmlhttp.status + "</a>)";
564
+ this.isSimulationValid = false
565
+ this.showUserMessage = false
566
+ this.errorMessage =
567
+ xmlhttp.statusText.toLowerCase() +
568
+ " (<a href='https://httpstatuses.com/" +
569
+ xmlhttp.status +
570
+ "/' target='_blank'>" +
571
+ xmlhttp.status +
572
+ '</a>)'
441
573
  },
442
574
  /**
443
575
  * @public
@@ -449,44 +581,44 @@ export default {
449
581
  checkSimulation(data) {
450
582
  // Check the simulation.
451
583
 
452
- const xmlhttp = new XMLHttpRequest();
584
+ const xmlhttp = new XMLHttpRequest()
453
585
 
454
- xmlhttp.open("POST", this.apiLocation + "/check_simulation");
455
- xmlhttp.setRequestHeader("Content-type", "application/json");
586
+ xmlhttp.open('POST', this.apiLocation + '/check_simulation')
587
+ xmlhttp.setRequestHeader('Content-type', 'application/json')
456
588
  xmlhttp.onreadystatechange = () => {
457
589
  if (xmlhttp.readyState === 4) {
458
590
  if (xmlhttp.status === 200) {
459
- let response = JSON.parse(xmlhttp.responseText);
591
+ let response = JSON.parse(xmlhttp.responseText)
460
592
 
461
- this.isSimulationValid = response.status === "ok";
593
+ this.isSimulationValid = response.status === 'ok'
462
594
 
463
595
  if (this.isSimulationValid) {
464
596
  if (response.results !== undefined) {
465
597
  // The simulation is finished, so process its results.
466
598
 
467
- this.showUserMessage = false;
599
+ this.showUserMessage = false
468
600
 
469
- this.processSimulationResults(response.results);
601
+ this.processSimulationResults(response.results)
470
602
  } else {
471
603
  // The simulation is not yet finished, so check again in a
472
604
  // second.
473
605
 
474
- let that = this;
606
+ let that = this
475
607
 
476
608
  setTimeout(function () {
477
- that.checkSimulation(data);
478
- }, 1000);
609
+ that.checkSimulation(data)
610
+ }, 1000)
479
611
  }
480
612
  } else {
481
- this.showUserMessage = false;
482
- this.errorMessage = response.description;
613
+ this.showUserMessage = false
614
+ this.errorMessage = response.description
483
615
  }
484
616
  } else {
485
- this.showHttpIssue(xmlhttp);
617
+ this.showHttpIssue(xmlhttp)
486
618
  }
487
619
  }
488
- };
489
- xmlhttp.send(JSON.stringify(data));
620
+ }
621
+ xmlhttp.send(JSON.stringify(data))
490
622
  },
491
623
  /**
492
624
  * @public
@@ -497,72 +629,73 @@ export default {
497
629
  // Start the simulation (after resetting our previous simulation data, in
498
630
  // case there were sonme).
499
631
 
500
- this.userMessage = "Loading simulation results...";
501
- this.showUserMessage = true;
632
+ this.userMessage = 'Loading simulation results...'
633
+ this.showUserMessage = true
502
634
 
503
635
  this.$nextTick(() => {
504
- this.simulationResults = {};
636
+ this.simulationResults = {}
505
637
 
506
- const xmlhttp = new XMLHttpRequest();
638
+ const xmlhttp = new XMLHttpRequest()
507
639
 
508
- xmlhttp.open("POST", this.apiLocation + "/start_simulation");
509
- xmlhttp.setRequestHeader("Content-type", "application/json");
640
+ xmlhttp.open('POST', this.apiLocation + '/start_simulation')
641
+ xmlhttp.setRequestHeader('Content-type', 'application/json')
510
642
  xmlhttp.onreadystatechange = () => {
511
643
  if (xmlhttp.readyState === 4) {
512
644
  if (xmlhttp.status === 200) {
513
- let response = JSON.parse(xmlhttp.responseText);
645
+ let response = JSON.parse(xmlhttp.responseText)
514
646
 
515
- this.isSimulationValid = response.status === "ok";
647
+ this.isSimulationValid = response.status === 'ok'
516
648
 
517
649
  if (this.isSimulationValid) {
518
- this.checkSimulation(response.data);
650
+ this.checkSimulation(response.data)
519
651
  } else {
520
- this.showUserMessage = false;
521
- this.errorMessage = response.description;
652
+ this.showUserMessage = false
653
+ this.errorMessage = response.description
522
654
  }
523
655
  } else {
524
- this.showHttpIssue(xmlhttp);
656
+ this.showHttpIssue(xmlhttp)
525
657
  }
526
658
  }
527
- };
528
- xmlhttp.send(JSON.stringify(this.retrieveRequest()));
529
- });
659
+ }
660
+ xmlhttp.send(JSON.stringify(this.retrieveRequest()))
661
+ })
530
662
  },
531
663
  },
532
664
  created: function () {
533
665
  // Try to retrieve the UI information.
534
666
 
535
667
  if (this.idType === IdType.DATASET_ID) {
536
- this.userMessage = "Retrieving UI information...";
537
- this.showUserMessage = true;
668
+ this.userMessage = 'Retrieving UI information...'
669
+ this.showUserMessage = true
538
670
 
539
671
  // Retrieve and build the simulation UI.
540
672
 
541
673
  this.$nextTick(() => {
542
- const xmlhttp = new XMLHttpRequest();
674
+ const xmlhttp = new XMLHttpRequest()
543
675
 
544
- xmlhttp.open("GET", this.apiLocation + "/simulation_ui_file/" + this.id);
676
+ xmlhttp.open('GET', this.apiLocation + '/simulation_ui_file/' + this.id)
545
677
  xmlhttp.onreadystatechange = () => {
546
678
  if (xmlhttp.readyState === 4) {
547
- this.showUserMessage = false;
679
+ this.showUserMessage = false
548
680
 
549
681
  if (xmlhttp.status === 200) {
550
682
  this.$nextTick(() => {
551
- this.buildSimulationUi(JSON.parse(xmlhttp.responseText));
552
- });
683
+ this.buildSimulationUi(JSON.parse(xmlhttp.responseText))
684
+ })
553
685
  } else {
554
- this.errorMessage = "the simulation dataset could not be retrieved";
686
+ this.errorMessage = 'the simulation dataset could not be retrieved'
555
687
  }
556
688
  }
557
- };
558
- xmlhttp.send();
559
- });
689
+ }
690
+ xmlhttp.send()
691
+ })
560
692
  } else if (this.idType === IdType.DATASET_URL) {
561
- this.opencorOmexFile = this.id;
693
+ this.opencorOmexFile = this.id
562
694
  } else if (this.idType === IdType.PMR_PATH) {
563
- this.opencorOmexFile = PMR_URL + this.id;
564
- } else { // IdType.RAW_COMBINE_ARCHIVE
565
- this.opencorOmexFile = this.id;
695
+ this.opencorOmexFile = PMR_URL + this.id
696
+ } else {
697
+ // IdType.RAW_COMBINE_ARCHIVE
698
+ this.opencorOmexFile = this.id
566
699
  }
567
700
  },
568
701
  mounted: function () {
@@ -571,20 +704,20 @@ export default {
571
704
  // idea how long it's going to take to retrieve the simulation UI
572
705
  // information.
573
706
 
574
- this.isMounted = true;
707
+ this.isMounted = true
575
708
 
576
- finaliseUi(this);
709
+ finaliseUi(this)
577
710
  },
578
- };
711
+ }
579
712
  </script>
580
713
 
581
714
  <!-- Add "scoped" attribute to limit CSS to this component only -->
582
715
  <style scoped lang="scss">
583
716
  .simulation-vuer {
584
- --el-color-primary: #8300BF;
585
- --el-color-primary-light-7: #DAB3EC;
586
- --el-color-primary-light-8: #E6CCF2;
587
- --el-color-primary-light-9: #F3E6F9;
717
+ --el-color-primary: #8300bf;
718
+ --el-color-primary-light-7: #dab3ec;
719
+ --el-color-primary-light-8: #e6ccf2;
720
+ --el-color-primary-light-9: #f3e6f9;
588
721
  }
589
722
 
590
723
  :deep(.el-button:hover) {
@@ -598,29 +731,32 @@ export default {
598
731
 
599
732
  :deep(.el-loading-spinner) {
600
733
  .path {
601
- stroke: #8300BF;
734
+ stroke: #8300bf;
602
735
  }
603
736
 
604
737
  i,
605
738
  .el-loading-text {
606
- color: #8300BF;
739
+ color: #8300bf;
607
740
  }
608
741
  }
609
742
 
610
- :deep(.p-floatlabel:has(input:focus)) label, :deep(.p-floatlabel:has(input:-webkit-autofill)) label, :deep(.p-floatlabel:has(textarea:focus)) label, :deep(.p-floatlabel:has(.p-inputwrapper-focus)) label {
611
- color: #8300BF;
743
+ :deep(.p-floatlabel:has(input:focus)) label,
744
+ :deep(.p-floatlabel:has(input:-webkit-autofill)) label,
745
+ :deep(.p-floatlabel:has(textarea:focus)) label,
746
+ :deep(.p-floatlabel:has(.p-inputwrapper-focus)) label {
747
+ color: #8300bf;
612
748
  }
613
749
 
614
750
  :deep(.p-inputtext:enabled:focus) {
615
- border-color: #8300BF;
751
+ border-color: #8300bf;
616
752
  }
617
753
 
618
754
  :deep(.p-select:not(.p-disabled).p-focus) {
619
- border-color: #8300BF;
755
+ border-color: #8300bf;
620
756
  }
621
757
 
622
758
  :deep(.p-slider-range) {
623
- background-color: #8300BF;
759
+ background-color: #8300bf;
624
760
  }
625
761
 
626
762
  div.input {
@@ -823,21 +959,22 @@ span.error {
823
959
  /* Note: not sure why, but the following rules need to be global!? */
824
960
 
825
961
  .p-select-option:not(.p-select-option-selected):not(.p-disabled).p-focus {
826
- background: #F5F7FA !important;
962
+ background: #f5f7fa !important;
827
963
  }
828
964
 
829
965
  .p-select-option.p-select-option-selected.p-focus {
830
- background: #F5F7FA !important;
831
- color: #8300BF !important;
966
+ background: #f5f7fa !important;
967
+ color: #8300bf !important;
832
968
  }
833
969
 
834
970
  .p-select-option.p-select-option-selected {
835
- background: white !important;
836
- color: #8300BF !important;
971
+ background: white !important;
972
+ color: #8300bf !important;
837
973
  }
838
974
 
839
975
  .p-select-option-label {
840
- font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
841
- font-size: 0.875rem;
976
+ font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Fira Sans',
977
+ 'Droid Sans', 'Helvetica Neue', sans-serif;
978
+ font-size: 0.875rem;
842
979
  }
843
980
  </style>