| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857 | <template>  <div id="app">    <b-loading :active.sync="isLoading" :can-cancel="isLoading"/>    <ShowInfo/>    <section class="add_padding">      <GetUnits v-bind:units="units"                v-bind:source_units="source_units"                v-bind:isSourceOtherUnits="isSourceOtherUnits"                @unitsData="units=$event"                @source_unitsData="source_units=$event"                @isSourceOtherUnitsData="isSourceOtherUnits=$event"      />      <GetHostIndex v-bind:hostIndex="simulationSetup.hostIndex"                    @hostIndexData="simulationSetup.hostIndex=$event" />      <GetSourceParameters v-bind:fromWL="simulationSetup.fromWL"                           v-bind:toWL="simulationSetup.toWL"                           v-bind:stepWL="simulationSetup.stepWL"                           v-bind:source_units="source_units"                           @fromWLData="simulationSetup.fromWL=$event"                           @toWLData="simulationSetup.toWL=$event"                           @stepWLData="simulationSetup.stepWL=$event"                           @source_unitsData="source_units=$event"      />      <GetMaterials v-bind:materials="materials"                    v-bind:plot_width="chart.layout.width"                    v-bind:plot_height="chart.layout.height"      />      <GetParticleParameters v-bind:layers="simulationSetup.layers"                             v-bind:units="units"                             v-bind:materials="materials"      />      <div  class="field is-horizontal">        <div class="field-label is-normal">          <label class="label">Modes to plot</label>        </div>        <div class="field-body" >          <b-field label="">            <b-input v-model="simulationSetup.total_mode_n" type='number' min=1 style="width:7rem"/>          </b-field>        </div>      </div>      <div class="add_padding">        <b-button class="is-primary is-medium" @click="runSimulation();">          Run simulation        </b-button><br>        It took {{ ttime }} s.      </div>      <div class="field is-grouped is-grouped-multiline add_padding">        <b-switch v-model="plotSelector.isPlotQsca">          Qsca        </b-switch>        <b-switch v-model="plotSelector.isPlotQabs">          Qabs        </b-switch>        <b-switch v-model="plotSelector.isPlotQext">          Qext        </b-switch>      </div>      <!--        <b-table :data="plotSelectorData" :columns="plotSelectorColumns" :mobile-cards="isShowInfo"></b-table>-->      <table class="table is-narrow add_padding">        <thead>        <tr>          <th v-for="mode_name in simulationRuntime.mode_n_names" v-bind:key="mode_name.name">            {{ mode_name.name == 'type' ? '': mode_name.name}}          </th>        </tr>        </thead>        <tbody>        <tr>          <th>E</th>          <td v-for="(mode,index) in plotSelector.isPlotModeE" v-bind:key="index">            <template v-if="(simulationRuntime.total_mode_n_evaluated - 1) < index">              <b-checkbox v-model="plotSelector.isPlotModeE[index]" disabled> </b-checkbox>            </template>            <template v-else>              <b-checkbox v-model="plotSelector.isPlotModeE[index]"> </b-checkbox>            </template>          </td>        </tr>        <tr>          <th>H</th>          <td v-for="(mode,index) in plotSelector.isPlotModeH" v-bind:key="index">            <template v-if="(simulationRuntime.total_mode_n_evaluated - 1) < index">              <b-checkbox v-model="plotSelector.isPlotModeH[index]" disabled> </b-checkbox>            </template>            <template v-else>              <b-checkbox v-model="plotSelector.isPlotModeH[index]"> </b-checkbox>            </template>          </td>        </tr>        </tbody>      </table>    </section>    <div class="chart-container">      <reactive-chart :chart="chart"/>    </div>  </div></template><script>  // You should put *.wasm to public/ and *.js to src/ folder  // To compile fibbonacci example use  //   emcc -O3 -s WASM=1 -s EXTRA_EXPORTED_RUNTIME_METHODS='["cwrap"]' -s ALLOW_MEMORY_GROWTH=1 -s MODULARIZE=1 -s 'EXPORT_NAME="fibonacci"' -o ./fibonacci.js fibonacci.c  // for and example from https://gist.github.com/ashleygwilliams/32c31a3f5b8c87bf2894108b3534ee4f  // import fibonacci from './fibonacci.js';  // const module = fibonacci({  //   locateFile(path) {  //     console.log(path);  //     return path;  //   }  // });  // module.onRuntimeInitialized = () => {  //   console.log(module._fib(12));  // };  // // Test the size of wasm file  // fetch('nmiejs.wasm'  // ).then(response =>  //         response.arrayBuffer()  // ).then(bytes =>  //         console.log(bytes)  // );  import nmiejs from './nmiejs.js';  // // Test nmiejs if working  // (async () => {  //   const module = await nmiejs({  //     locateFile(path) {  //       let deploy_path = process.env.BASE_URL;  //       // '/themes/custom/physics/mie/';  //       // console.log();  //       // // let deploy_path = '';  //       console.log(deploy_path + path);  //       return deploy_path + path;  //     }  //   })  //     const nmie = new module.nmie();  //       nmie.ClearTarget();  //       let R = 100.0;  //       let reN = 4.0;  //       let imN = 0.01;  //       nmie.AddTargetLayerReIm(R, reN, imN)  //       nmie.SetModeNmaxAndType(-1, -1);  //       let WL = 800;  //       nmie.SetWavelength(WL);  //       nmie.RunMieCalculation();  //       console.log(nmie.GetQsca());  //  // })();  const range = (start, stop, step = 1) => Array(Math.ceil((stop - start) / step)).fill(start).map((x, y) => x + y * step);  function rangeInt(size, startAt = 0) {    return [...Array(size).keys()].map(i => i + startAt);  }  import ReactiveChart from "./components/ReactiveChart.vue";  import ShowInfo from "./components/ShowInfo.vue";  import GetMaterials from "./components/GetMaterials.vue";  import GetHostIndex from "./components/GetHostIndex.vue";  import GetUnits from "./components/GetUnits.vue";  import GetSourceParameters from "./components/GetSourceParameters.vue";  import GetParticleParameters from "./components/GetParticleParameters.vue";  export default {    name: 'app',    components: {      GetHostIndex,      GetMaterials,      GetSourceParameters,      GetParticleParameters,      GetUnits,      ReactiveChart,      ShowInfo    },    data() {        return {          nmie: undefined,          ttime: "",          window: {            width: 0,            height: 0          },          units: 'nm',          units_prev: 'nm',          source_units: 'nm',          source_units_prev: 'nm',          materials: [],          isSourceOtherUnits: false,          simulationSetup: {            hostIndex: 1,            stepWL: 2,            fromWL: 300.0,            toWL: 1000.0,            layers: [              {                R: 100.0,                material: 'nk',                isMaterialLoaded:true,                reN: 4.0,                imN: 0.01,                index: 0              }            ],            total_mode_n: 4          },          simulationRuntime: {            r_units: 'nm',            r_source_units: 'nm',            stepWL: 2,            fromWL: 300.0,            toWL: 1000.0,            layers: [              {                R: 100.0,                material: 'nk',                reN: 4.0,                imN: 0.01,                index:0              }            ],            mode_n: [],            mode_n_names: [],            mode_types: range(0, 2),            mode_names: ['E', 'H'],            WLs: [],            Qsca: [],            Qabs: [],            Qext: [],            Qsca_n: [[], []],            Qabs_n: [[], []],            layout: {},            trace1: {},            trace2: {},            total_mode_n_evaluated: 4,          },          plotData: {            pWLs: [],            pQsca: [],            pQabs: [],            pQext: [],            pQsca_n: [[], []],            pQabs_n: [[], []],          },          changes: 0,          isShowInfo: false,          isLoading: true,          isRunning: false,          plotSelector: {            isPlotModeE: [],            isPlotModeH: [],            isPlotQabs: true,            isPlotQsca: true,            isPlotQext: false,          },          // plotSelectorData: undefined,          // plotSelectorColumns: undefined,          // plotSelectorNames: undefined,          chart: {            uuid: "spectra",            traces: [              {                y: [],                line: {                  color: "#5e9e7e",                  width: 4,                  shape: "line"                }              }            ],            layout: {              margin: {                l:0,                r:40,                b:50,                t:0              },              // paper_bgcolor: '#7f7f7f',              // plot_bgcolor: '#c7c7c7',              // title: 'reactive charts',              xaxis: {                // will be set on mount                title: ''              },              yaxis: {                title: 'Normalized cross-sections'              },              showlegend: true,              legend: {                orientation:"h",                x: -.1,                y: 1.05              },              // width: 100,              height: 100            }          }        };      },    created() {        window.addEventListener('resize', this.handleResize);        this.handleResize();      },    destroyed() {        window.removeEventListener('resize', this.handleResize)      },    mounted() {      this.setXaxisTitle();      (async () => {        const module = await nmiejs({          locateFile(path) {            let deploy_path = process.env.BASE_URL;            // '/themes/custom/physics/mie/';            // console.log();            // // let deploy_path = '';            console.log(deploy_path + path);            return deploy_path + path;          }        })        this.nmie = new module.nmie();        this.isLoading = false;        this.runMie();        this.setIsPlotMode();        this.setModeNNames();        this.plotResults();      })();    },    watch: {      plotSelector: {          handler: function () {            this.plotResults();          },          deep: true        },      'simulationSetup.total_mode_n': function () {        this.setIsPlotMode();        this.setModeNNames();      },      units: {        handler: function () {          if (!this.isSourceOtherUnits) {            this.source_units = this.units;          }          let u = this.units;          let u_prev = this.units_prev;          let layers = this.simulationSetup.layers;          for (let i=0; i<layers.length; i++) {            layers[i].R = this.convertUnits(u_prev, u, layers[i].R);          }          this.units_prev = this.units;        }      },      source_units: {        handler: function () {          // this.$buefy.notification.open({          //   duration: 4000,          //   message: 'Source parameters were restored from last simulation for correct plotting.',          //   type: 'is-info',          //   position: 'is-top',          // });          this.setXaxisTitle();          let u = this.source_units;          let u_prev = this.source_units_prev;          for (let i=0; i<this.plotData.pWLs.length; i++) {            this.plotData.pWLs[i] = this.convertUnits(u_prev, u,                    this.plotData.pWLs[i]);          }          this.simulationSetup.fromWL = this.convertUnits(u_prev, u,                  this.simulationSetup.fromWL);          this.simulationSetup.toWL = this.convertUnits(u_prev, u,                  this.simulationSetup.toWL);          if (this.simulationSetup.fromWL > this.simulationSetup.toWL) {            let tmp = this.simulationSetup.fromWL;            this.simulationSetup.fromWL = this.simulationSetup.toWL;            this.simulationSetup.toWL = tmp;          }          this.simulationSetup.stepWL = (this.simulationSetup.toWL-this.simulationSetup.fromWL)                  /this.plotData.pWLs.length;          this.source_units_prev = this.source_units;          // Update plotting          this.plotSelector.isPlotQsca = !this.plotSelector.isPlotQsca          setTimeout(                  () => {                    this.plotSelector.isPlotQsca = !this.plotSelector.isPlotQsca                  }, 2);        }      },      isSourceOtherUnits: {        handler: function () {          // this.setEmptyChart();          this.setXaxisTitle();          if (!this.isSourceOtherUnits) {            this.source_units = this.units;          } else {            this.source_units = 'THz'          }        }      },      window: {        handler: function () {            // this.chart.layout.width = this.window.width * 0.92;            this.chart.layout.height = this.window.height * 0.95;            // if (this.window.width < 600) this.chart.layout.width = this.window.width;            if (this.window.height < 600) this.chart.layout.height = this.window.height;          },        deep: true      }    },    methods: {      handleResize() {          this.window.width = window.innerWidth;          this.window.height = window.innerHeight*0.8;        },      convertUnits2nm(fromU, val) {        if (fromU === 'nm') return val;        if (fromU === 'mkm') return val*1e3;        if (fromU === 'mm') return val*1e6;        if (fromU === 'cm') return val*1e7;        if (fromU === 'm') return val*1e9;        if (fromU === 'km') return val*1e12;        let c = 299792458; // m/s        let hc = 1239841930.092394328e-15; // m*eV        if (fromU === 'THz') return c/(val*1e12)*1e9;        if (fromU === 'GHz') return c/(val*1e9)*1e9;        if (fromU === 'MHz') return c/(val*1e6)*1e9;        if (fromU === 'kHz') return c/(val*1e3)*1e9;        if (fromU === 'Hz') return c/(val*1e0)*1e9;        if (fromU === 'eV') return hc/(val*1e0)*1e9;        if (fromU === 'meV') return hc/(val/1e3)*1e9;        if (fromU === 'fs') return (val/1e12)/c*1e9;        if (fromU === 'ps') return (val/1e15)/c*1e9;        return undefined;      },      convertUnitsFrom_nm(toU, val) {        if (toU === 'nm') return val;        if (toU === 'mkm') return val/1e3;        if (toU === 'mm') return val/1e6;        if (toU === 'cm') return val/1e7;        if (toU === 'm') return val/1e9;        if (toU === 'km') return val/1e12;        let c = 299792458; // m/s        let hc = 1239841930.092394328e-15; // m*eV        if (toU === 'THz') return c/(val/1e9)/1e12;        if (toU === 'GHz') return c/(val/1e9)/1e9;        if (toU === 'MHz') return c/(val/1e9)/1e6;        if (toU === 'kHz') return c/(val/1e9)/1e3;        if (toU === 'Hz') return c/(val/1e9)/1e0;        if (toU === 'eV') return hc/(val/1e9);        if (toU === 'meV') return hc/(val/1e9)*1e3;        if (toU === 'fs') return (val/1e9)/c*1e12;        if (toU === 'ps') return (val/1e9)/c*1e15;        return undefined;      },      convertUnits(fromU,toU, val) {        if (fromU === toU) return val;        return this.convertUnitsFrom_nm(toU, this.convertUnits2nm(fromU, val));      },      notifyDanger: function(message) {        this.$buefy.notification.open({          duration: 3000,          message: message,          type: 'is-danger',          position: 'is-bottom-left',        });      },      runSimulation: function() {          this.$buefy.notification.open({            duration: 200,            message: 'Simulation was started!',            type: 'is-danger',            position: 'is-bottom-left',            });          setTimeout(                  () => {                    this.runMie();                    this.plotResults();                    this.$buefy.notification.open({                      duration: 3000,                      message: 'Finished! '+"It took " + this.ttime + " s.",                      type: 'is-success',                      position: 'is-bottom-left',                      })                    ;                  }, 20);        },      runMie: function () {        this.simulationRuntime.r_units = this.units;        this.simulationRuntime.r_source_units = this.source_units;        this.simulationRuntime.fromWL = this.simulationSetup.fromWL;        this.simulationRuntime.toWL = this.simulationSetup.toWL;        this.simulationRuntime.stepWL = this.simulationSetup.stepWL;        this.simulationRuntime.layers =this.simulationSetup.layers; // TODO: not a copy, but we need spline_n.at() method in every layer.        let t0 = performance.now();        let fromWL = parseFloat(this.simulationSetup.fromWL);        let toWL = parseFloat(this.simulationSetup.toWL);        let stepWL = parseFloat(this.simulationSetup.stepWL);        let host = parseFloat(this.simulationSetup.hostIndex);        let Qsca = [], Qabs = [], Qext = [];        let Qsca_n = [[], []], Qabs_n = [[], []];        let WLs = range(fromWL, toWL, stepWL);        this.simulationRuntime.WLs = WLs;        let total_mode_n = this.simulationSetup.total_mode_n;        let mode_n = [];        mode_n = rangeInt(Number(total_mode_n), 1);        this.simulationRuntime.total_mode_n_evaluated = total_mode_n;        let mode_types = range(0, 2);        this.simulationSetup.mode_n = mode_n;        this.simulationSetup.mode_types = mode_types;        mode_types.forEach(function (mode_type) {          mode_n.forEach(function () {            Qsca_n[mode_type].push([]);            Qabs_n[mode_type].push([]);            });        });        // Provide all sizes (germetry and wavelengths) to nmie in same units [nm]        const nmie = this.nmie;        // nmie.ClearTarget();        // nmie.AddTargetLayerReIm( this.convertUnits2nm(this.units, R)*host,        //         reN/host, imN/host);        let WLs_nm = range(fromWL, toWL, stepWL);        let WL_points = WLs_nm.length;        for (let i = 0; i < WL_points; i++) {          let WL = this.convertUnits2nm(this.source_units, WLs[i]);          nmie.ClearTarget();          for (let num_layer = 0;               num_layer < this.simulationRuntime.layers.length;               num_layer++) {            let layer = this.simulationRuntime.layers[num_layer];            let R = parseFloat(layer.R);            if (layer.material === 'PEC') {              //  TODO: set PEC layer              continue;            }            if (layer.material !== 'nk') {              if ( layer.spline_n === undefined ) {                this.notifyDanger('Failed to load material!');                return;              }              if (layer.spline_n.xs[0] > WL                      || layer.spline_n.xs[layer.spline_n.xs.length-1] < WL) {                this.notifyDanger('ERROR!!! Source parameters are out of material spectral range!');                return;              }              layer.reN = layer.spline_n.at(WL);              layer.imN = layer.spline_k.at(WL);            }            let reN = parseFloat(layer.reN);            let imN = parseFloat(layer.imN);            nmie.AddTargetLayerReIm( this.convertUnits2nm(this.units, R)*host,                    reN/host, imN/host);          }          nmie.SetModeNmaxAndType(-1, -1);          nmie.SetWavelength(WL);          nmie.RunMieCalculation();          Qsca.push(nmie.GetQsca());          Qabs.push(nmie.GetQabs());          Qext.push(nmie.GetQsca()+nmie.GetQabs());          mode_types.forEach(function (mode_type) {            mode_n.forEach(function (n) {              nmie.SetModeNmaxAndType(n, mode_type);              nmie.RunMieCalculation();              Qsca_n[mode_type][n - 1].push(nmie.GetQsca());              Qabs_n[mode_type][n - 1].push(nmie.GetQabs());            });          });        }        this.simulationRuntime.Qsca = Qsca;        this.simulationRuntime.Qabs = Qabs;        this.simulationRuntime.Qext = Qext;        this.simulationRuntime.Qsca_n = Qsca_n;        this.simulationRuntime.Qabs_n = Qabs_n;        let t1 = performance.now();        this.ttime = ((t1 - t0) / 1000).toFixed(2);        // console.log("It took " + this.ttime + " s.");        this.plotData.pWLs = WLs.slice();        this.plotData.pQsca = Qsca;        this.plotData.pQabs = Qabs;        this.plotData.pQext = Qext;        this.plotData.pQsca_n = Qsca_n;        this.plotData.pQabs_n = Qabs_n;        this.changes++;      },      filterBug: function () {        let Qsca = this.simulationRuntime.Qsca;        let Qabs = this.simulationRuntime.Qabs;        let Qext = this.simulationRuntime.Qext;        let Qsca_n = this.simulationRuntime.Qsca_n;        let Qabs_n = this.simulationRuntime.Qabs_n;        let total_mode_n = this.simulationSetup.total_mode_n;        for (let mode_type = 0; mode_type < 2; mode_type++) {          for (let n = 0; n < total_mode_n; n++){            this.filterMedian(Qsca_n[mode_type][n]);            this.filterMedian(Qabs_n[mode_type][n]);          }        }        this.filterMedian(Qsca);        this.filterMedian(Qabs);        for (let i = 0; i < Qsca.length; i++) {          Qext[i] = Qsca[i] + Qabs[i];        }        // this.filterMedian(Qext);        this.simulationRuntime.Qsca = Qsca;        this.simulationRuntime.Qabs = Qabs;        this.simulationRuntime.Qext = Qext;        this.simulationRuntime.Qsca_n = Qsca_n;        this.simulationRuntime.Qabs_n = Qabs_n;      },      filterMedian: function(spectra) {        let l = spectra.length;        let i;        for (i = 1; i < l-1; i++) {          let prev = spectra[i-1];          let curr = spectra[i];          let next = spectra[i+1];          let diff1 = Math.abs((prev-curr)/curr);          let diff2 = Math.abs((next-curr)/curr);          if (diff1 > 0.3 && diff2 > 0.3) {            spectra[i] = (prev+next)/2.0;          }           // console.log(spectra(i));        }        // return spectra;      },      setIsPlotMode: function () {          let total_mode_n = this.simulationSetup.total_mode_n;          total_mode_n++;          let np1 = Number(total_mode_n);          let mode_n = rangeInt(Number(np1), 0);          let modeE = [];          let modeH = [];          mode_n.forEach(function (n) {            if (n !== 0) {              modeE.push(false);              modeH.push(false);            }          });          let saved_modes = this.simulationSetup.total_mode_n > this.simulationRuntime.total_mode_n_evaluated ?                  this.simulationRuntime.total_mode_n_evaluated : this.simulationSetup.total_mode_n;          this.simulationRuntime.total_mode_n_evaluated = saved_modes;          let oldModeE = this.plotSelector.isPlotModeE;          let oldModeH = this.plotSelector.isPlotModeH;          let ii;          for (ii = 0; ii < saved_modes; ++ii) {            if (ii < oldModeE.length) {              modeE[ii] = oldModeE[ii];              modeH[ii] = oldModeH[ii];            }          }          this.plotSelector.isPlotModeE = modeE;          this.plotSelector.isPlotModeH = modeH;        },      setXaxisTitle: function () {        if (this.source_units.endsWith('Hz')) {          this.chart.layout.xaxis.title = "Frequency, " + this.source_units;        } else if (this.source_units.endsWith('eV')) {          this.chart.layout.xaxis.title = "Energy, " + this.source_units;        } else if (this.source_units.endsWith('s')) {          this.chart.layout.xaxis.title = "Period, " + this.source_units;        } else {            this.chart.layout.xaxis.title = "Wavelength, " + this.source_units;        }      },      setModeNNames: function () {        let total_mode_n = this.simulationSetup.total_mode_n;        total_mode_n++;        let np1 = Number(total_mode_n);        let mode_n = rangeInt(Number(np1), 0);        let mode_n_names = [];        mode_n.forEach(function (n) {          if (n === 0) mode_n_names.push({id: 0, name: 'type'});          else if (n === 1) mode_n_names.push({id: 1, name: 'dipole'});          else if (n === 2) mode_n_names.push({id: 2, name: 'quadrupole'});          else if (n === 3) mode_n_names.push({id: 3, name: 'octupole'});          else mode_n_names.push({id: n, name: (Math.pow(2, n)).toString()});        });        this.simulationRuntime.mode_n_names = mode_n_names;      },      setQtotalChart: function () {        let traceQsca, traceQabs, traceQext;        traceQsca = {          x: this.plotData.pWLs,          y: this.plotData.pQsca,          type: 'scatter',          name: 'Qsca'        };        traceQabs = {          x: this.plotData.pWLs,          y: this.plotData.pQabs,          type: 'scatter',          name: 'Qabs'        };        traceQext = {          x: this.plotData.pWLs,          y: this.plotData.pQext,          type: 'scatter',          name: 'Qext'        };        this.chart.traces = [];        if (this.plotSelector.isPlotQsca === true) this.chart.traces.push(traceQsca);        if (this.plotSelector.isPlotQabs === true) this.chart.traces.push(traceQabs);        if (this.plotSelector.isPlotQext === true) this.chart.traces.push(traceQext);      },      plotResults: function () {        this.setQtotalChart();        let mode_type, mode_n;        let mode_n_names = this.simulationRuntime.mode_n_names;        let mode_names = this.simulationRuntime.mode_names;        for (mode_type = 0; mode_type < 2; ++mode_type) {          for (mode_n = 0; mode_n < this.simulationRuntime.total_mode_n_evaluated; ++mode_n) {            let is_mode_plot = mode_type === 0 ? this.plotSelector.isPlotModeE : this.plotSelector.isPlotModeH;            if (is_mode_plot[mode_n] === false) continue;            if (this.plotSelector.isPlotQsca === true) {              let trace_sca = {                x: this.plotData.pWLs,                y: this.plotData.pQsca_n[mode_type][mode_n],                  type: 'scatter',                name: 'Qsca ' + mode_names[mode_type] + ' ' + mode_n_names[mode_n + 1].name              };              this.chart.traces.push(trace_sca);            }            if (this.plotSelector.isPlotQabs === true) {              let trace_abs = {                x: this.plotData.pWLs,                y: this.plotData.pQabs_n[mode_type][mode_n],                type: 'scatter',                name: 'Qabs ' + mode_names[mode_type] + ' ' + mode_n_names[mode_n + 1].name                };              this.chart.traces.push(trace_abs);            }          }        }      }    },  };</script><style lang="scss">  // Import Bulma's core  @import "~bulma/sass/utilities/_all";  // https://bulma.io/documentation/customize/variables/  // $body-background-color: $green;  // Set your colors  $primary: #7957d5;  $twitter: #4099FF;  $twitter-invert: findColorInvert($twitter);  // Setup $colors to use as bulma classes (e.g. 'is-twitter')   $colors: (             "white": ($white, $black),             "black": ($black, $white),             "light": ($light, $light-invert),             "dark": ($dark, $dark-invert),             "primary": ($primary, $primary-invert),             "info": ($info, $info-invert),             "success": ($success, $success-invert),             "warning": ($warning, $warning-invert),             "danger": ($danger, $danger-invert),             "twitter": ($twitter, $twitter-invert)   );  // Links  // $link: $primary;  // $link-invert: $primary-invert;  // $link-focus-border: $primary;  // Import Bulma and Buefy styles  @charset "utf-8";  /*! bulma.io v0.7.5 | MIT License | github.com/jgthms/bulma */  @import "~bulma/sass/utilities/_all";  @import "~bulma/sass/base/_all";  /*@import "~bulma/sass/elements/_all";*/  @import "~bulma/sass/elements/box.sass";  @import "~bulma/sass/elements/button.sass";  @import "~bulma/sass/elements/container.sass";  @import "~bulma/sass/elements/content.sass";  /*@import "~bulma/sass/elements/icon.sass";*/  @import "~bulma/sass/elements/image.sass";  @import "~bulma/sass/elements/notification.sass";  @import "~bulma/sass/elements/progress.sass";  @import "~bulma/sass/elements/table.sass";  @import "~bulma/sass/elements/tag.sass";  @import "~bulma/sass/elements/title.sass";  @import "~bulma/sass/elements/other.sass";  @import "~bulma/sass/form/_all";  /*@import "~bulma/sass/components/_all";*/  @import "~bulma/sass/components/dropdown";  @import "~bulma/sass/components/tabs";  @import "~bulma/sass/components/modal";  @import "~bulma/sass/components/message";  @import "~bulma/sass/grid/_all";  /*@import "~bulma/sass/layout/_all";*/  // @import "~bulma";  @import "~buefy/src/scss/buefy";  .add_padding {    padding: 1rem;  }  // Custom styles to build into the design of physics.ifmo.ru  // npm run build && ./deploy.sh  && xclip -sel c < dist/index.html  .content table {    width: auto;  }  ul {    padding-left: 1.5em;  }  body {    line-height: 1.42857;  }  /*.container {*/  /*  width: 750px;*/  /*}*/  h1 {    font-size: 34px;    font-weight: bold;  }  .block-views-blockmessages-header-message-block {    top: 25px;  }</style>
 |