From 7fdf733a64670fceefc3ded35cfa581e1c458179 Mon Sep 17 00:00:00 2001 From: Einav Weiss Keidar Date: Tue, 20 Mar 2018 14:45:40 +0200 Subject: Adding Prettier and fixing up eslint version Issue-ID: SDC-1094 Change-Id: Ie83ad95a03899345dd90235daf0323cbe3bc6afd Signed-off-by: Einav Weiss Keidar --- .../webapp/lib/ecomp/asdc/sequencer/model/Model.js | 864 ++++++++++----------- 1 file changed, 428 insertions(+), 436 deletions(-) (limited to 'dox-sequence-diagram-ui/src/main/webapp/lib/ecomp/asdc/sequencer/model/Model.js') diff --git a/dox-sequence-diagram-ui/src/main/webapp/lib/ecomp/asdc/sequencer/model/Model.js b/dox-sequence-diagram-ui/src/main/webapp/lib/ecomp/asdc/sequencer/model/Model.js index 1e68cd6034..3145506268 100644 --- a/dox-sequence-diagram-ui/src/main/webapp/lib/ecomp/asdc/sequencer/model/Model.js +++ b/dox-sequence-diagram-ui/src/main/webapp/lib/ecomp/asdc/sequencer/model/Model.js @@ -24,489 +24,481 @@ import Metamodel from './Metamodel'; * A wrapper for a model instance. */ export default class Model { + // /////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * Construct model from model JSON. JSON is assumed to be in more or less + * the correct structure, but it's OK if it's missing IDs. + * + * @param json initial JSON; will be updated in situ. + * @param metamodel Metaobject definition. + */ + constructor(json, metamodel) { + if (metamodel) { + Common.assertInstanceOf(metamodel, Metamodel); + } - // /////////////////////////////////////////////////////////////////////////////////////////////// + this.metamodel = metamodel || Metamodel.getDefault(); + Common.assertInstanceOf(this.metamodel, Metamodel); - /** - * Construct model from model JSON. JSON is assumed to be in more or less - * the correct structure, but it's OK if it's missing IDs. - * - * @param json initial JSON; will be updated in situ. - * @param metamodel Metaobject definition. - */ - constructor(json, metamodel) { + this.jsonschema = require('./schema/asdc_sequencer_schema.json'); + this.templates = { + defaultModel: require('./templates/default.model.json'), + defaultMetamodel: require('./templates/default.metamodel.json') + }; - if (metamodel) { - Common.assertInstanceOf(metamodel, Metamodel); - } + this.model = this._preprocess(Common.assertType(json, 'Object')); + Common.assertPlainObject(this.model); - this.metamodel = metamodel || Metamodel.getDefault(); - Common.assertInstanceOf(this.metamodel, Metamodel); - - this.jsonschema = require('./schema/asdc_sequencer_schema.json'); - this.templates = { - defaultModel: require('./templates/default.model.json'), - defaultMetamodel: require('./templates/default.metamodel.json'), - }; - - this.model = this._preprocess(Common.assertType(json, 'Object')); - Common.assertPlainObject(this.model); - - this.renumber(); - - this.addLifeline = this.addLifeline.bind(this); - this.addMessage = this.addMessage.bind(this); - this.renumber = this.renumber.bind(this); - } - - // /////////////////////////////////////////////////////////////////////////////////////////////// - - /** - * Unwrap to get model object. - * @returns {*} - */ - unwrap() { - return Common.assertPlainObject(this.model); - } - - // /////////////////////////////////////////////////////////////////////////////////////////////// - - /** - * Get the metamodel which defines valid states for this model. - * @returns Metamodel definition. - */ - getMetamodel() { - return Common.assertInstanceOf(this.metamodel, Metamodel); - } - - // /////////////////////////////////////////////////////////////////////////////////////////////// - - /** - * Find lifeline by its ID. - * @param id lifeline ID. - * @returns lifeline object, if found. - */ - getLifelineById(id) { - for (const lifeline of this.model.diagram.lifelines) { - if (lifeline.id === id) { - return lifeline; - } - } - return undefined; - } - - // /////////////////////////////////////////////////////////////////////////////////////////////// - - /** - * Get message by ID. - * @param id message ID. - * @returns message if matched. - */ - getMessageById(id) { - Common.assertNotNull(id); - const step = this.getStepByMessageId(id); - if (step) { - return step.message; + this.renumber(); + + this.addLifeline = this.addLifeline.bind(this); + this.addMessage = this.addMessage.bind(this); + this.renumber = this.renumber.bind(this); } - return undefined; - } - - // /////////////////////////////////////////////////////////////////////////////////////////////// - - /** - * Get step by message ID. - * @param id step ID. - * @returns step if matched. - */ - getStepByMessageId(id) { - Common.assertNotNull(id); - for (const step of this.model.diagram.steps) { - if (step.message && step.message.id === id) { - return step; - } + + // /////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * Unwrap to get model object. + * @returns {*} + */ + unwrap() { + return Common.assertPlainObject(this.model); } - return undefined; - } - - // /////////////////////////////////////////////////////////////////////////////////////////////// - - /** - * Add message to steps. - * @returns {{}} - */ - addMessage(index) { - const d = this.model.diagram; - const step = {}; - step.message = {}; - step.message.id = Model._guid(); - step.message.name = '[Unnamed Message]'; - step.message.type = 'request'; - step.message.from = d.lifelines.length > 0 ? d.lifelines[0].id : -1; - step.message.to = d.lifelines.length > 1 ? d.lifelines[1].id : -1; - if (index >= 0) { - d.steps.splice(index, 0, step); - } else { - d.steps.push(step); + + // /////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * Get the metamodel which defines valid states for this model. + * @returns Metamodel definition. + */ + getMetamodel() { + return Common.assertInstanceOf(this.metamodel, Metamodel); } - this.renumber(); - return step; - } - - // /////////////////////////////////////////////////////////////////////////////////////////////// - - /** - * Delete message with ID. - * @param id to be deleted. - */ - deleteMessageById(id) { - Common.assertNotNull(id); - const step = this.getStepByMessageId(id); - if (step) { - const index = this.model.diagram.steps.indexOf(step); - if (index !== -1) { - this.model.diagram.steps.splice(index, 1); - } + + // /////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * Find lifeline by its ID. + * @param id lifeline ID. + * @returns lifeline object, if found. + */ + getLifelineById(id) { + for (const lifeline of this.model.diagram.lifelines) { + if (lifeline.id === id) { + return lifeline; + } + } + return undefined; } - this.renumber(); - } - - // /////////////////////////////////////////////////////////////////////////////////////////////// - - /** - * Add lifeline to lifelines. - * @param index optional index. - * @returns {{}} - */ - addLifeline(index) { - const lifeline = {}; - lifeline.id = Model._guid(); - lifeline.name = '[Unnamed Lifeline]'; - if (index >= 0) { - this.model.diagram.lifelines.splice(index, 0, lifeline); - } else { - this.model.diagram.lifelines.push(lifeline); + + // /////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * Get message by ID. + * @param id message ID. + * @returns message if matched. + */ + getMessageById(id) { + Common.assertNotNull(id); + const step = this.getStepByMessageId(id); + if (step) { + return step.message; + } + return undefined; } - this.renumber(); - return lifeline; - } - - // /////////////////////////////////////////////////////////////////////////////////////////////// - - /** - * Delete lifeline with ID. - * @param id to be deleted. - */ - deleteLifelineById(id) { - Common.assertNotNull(id); - this.deleteStepsByLifelineId(id); - const lifeline = this.getLifelineById(id); - if (lifeline) { - const index = this.model.diagram.lifelines.indexOf(lifeline); - if (index !== -1) { - this.model.diagram.lifelines.splice(index, 1); - } + + // /////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * Get step by message ID. + * @param id step ID. + * @returns step if matched. + */ + getStepByMessageId(id) { + Common.assertNotNull(id); + for (const step of this.model.diagram.steps) { + if (step.message && step.message.id === id) { + return step; + } + } + return undefined; } - this.renumber(); - } - - // /////////////////////////////////////////////////////////////////////////////////////////////// - - /** - * Delete all steps corresponding to lifeline. - * @param id lifeline ID. - */ - deleteStepsByLifelineId(id) { - Common.assertNotNull(id); - const steps = this.getStepsByLifelineId(id); - for (const step of steps) { - this.deleteMessageById(step.message.id); + + // /////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * Add message to steps. + * @returns {{}} + */ + addMessage(index) { + const d = this.model.diagram; + const step = {}; + step.message = {}; + step.message.id = Model._guid(); + step.message.name = '[Unnamed Message]'; + step.message.type = 'request'; + step.message.from = d.lifelines.length > 0 ? d.lifelines[0].id : -1; + step.message.to = d.lifelines.length > 1 ? d.lifelines[1].id : -1; + if (index >= 0) { + d.steps.splice(index, 0, step); + } else { + d.steps.push(step); + } + this.renumber(); + return step; } - this.renumber(); - } - - // /////////////////////////////////////////////////////////////////////////////////////////////// - - /** - * Get all steps corresponding to lifeline. - * @param id lifeline ID. - * @return steps from/to lifeline. - */ - getStepsByLifelineId(id) { - Common.assertNotNull(id); - const steps = []; - for (const step of this.model.diagram.steps) { - if (step.message) { - if (step.message.from === id || step.message.to === id) { - steps.push(step); + + // /////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * Delete message with ID. + * @param id to be deleted. + */ + deleteMessageById(id) { + Common.assertNotNull(id); + const step = this.getStepByMessageId(id); + if (step) { + const index = this.model.diagram.steps.indexOf(step); + if (index !== -1) { + this.model.diagram.steps.splice(index, 1); + } } - } + this.renumber(); } - return steps; - } - - // /////////////////////////////////////////////////////////////////////////////////////////////// - - /** - * Validate model. Disabled, because we removed the jsonschema dependency. - * @returns {Array} of validation errors, if any. - */ - validate() { - const errors = []; - return errors; - } - - // /////////////////////////////////////////////////////////////////////////////////////////////// - - /** - * Reorder messages. - * @param index message index. - * @param afterIndex new (after) index. - */ - reorderMessages(index, afterIndex) { - Common.assertType(index, 'Number'); - Common.assertType(afterIndex, 'Number'); - const steps = this.model.diagram.steps; - const element = steps[index]; - steps.splice(index, 1); - steps.splice(afterIndex, 0, element); - this.renumber(); - } - - // /////////////////////////////////////////////////////////////////////////////////////////////// - - /** - * Reorder lifelines. - * @param index lifeline index. - * @param afterIndex new (after) index. - */ - reorderLifelines(index, afterIndex) { - Common.assertType(index, 'Number'); - Common.assertType(afterIndex, 'Number'); - const lifelines = this.model.diagram.lifelines; - const element = lifelines[index]; - lifelines.splice(index, 1); - lifelines.splice(afterIndex, 0, element); - this.renumber(); - } - - // /////////////////////////////////////////////////////////////////////////////////////////////// - - /** - * Renumber lifelines and messages. - */ - renumber() { - const modelJSON = this.unwrap(); - let stepIndex = 1; - let lifelineIndex = 1; - for (const step of modelJSON.diagram.steps) { - if (step.message) { - step.message.index = stepIndex++; - } + + // /////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * Add lifeline to lifelines. + * @param index optional index. + * @returns {{}} + */ + addLifeline(index) { + const lifeline = {}; + lifeline.id = Model._guid(); + lifeline.name = '[Unnamed Lifeline]'; + if (index >= 0) { + this.model.diagram.lifelines.splice(index, 0, lifeline); + } else { + this.model.diagram.lifelines.push(lifeline); + } + this.renumber(); + return lifeline; } - for (const lifeline of modelJSON.diagram.lifelines) { - lifeline.index = lifelineIndex++; + + // /////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * Delete lifeline with ID. + * @param id to be deleted. + */ + deleteLifelineById(id) { + Common.assertNotNull(id); + this.deleteStepsByLifelineId(id); + const lifeline = this.getLifelineById(id); + if (lifeline) { + const index = this.model.diagram.lifelines.indexOf(lifeline); + if (index !== -1) { + this.model.diagram.lifelines.splice(index, 1); + } + } + this.renumber(); } - } - - // /////////////////////////////////////////////////////////////////////////////////////////////// - - /** - * Build a simple, navigable dataset describing fragments. - * @returns {{}}, indexed by (stop) message ID, describing fragments. - */ - analyzeFragments() { - - const fData = {}; - - let depth = 0; - const modelJSON = this.unwrap(); - const open = []; - - const getData = function g(stop, fragment) { - let data = fData[stop]; - if (!data) { - data = { stop, start: [], fragment }; - fData[stop] = data; - } - return data; - }; - - const fragmentsByStart = {}; - for (const step of modelJSON.diagram.steps) { - if (step.message && step.message.fragment) { - const message = step.message; - const fragment = message.fragment; - if (fragment.start) { - fragmentsByStart[fragment.start] = fragment; - open.push(message.id); - depth++; + + // /////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * Delete all steps corresponding to lifeline. + * @param id lifeline ID. + */ + deleteStepsByLifelineId(id) { + Common.assertNotNull(id); + const steps = this.getStepsByLifelineId(id); + for (const step of steps) { + this.deleteMessageById(step.message.id); } - if (fragment.stop) { - if (open.length > 0) { - getData(message.id).start.push(open.pop()); - } - depth = Math.max(depth - 1, 0); + this.renumber(); + } + + // /////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * Get all steps corresponding to lifeline. + * @param id lifeline ID. + * @return steps from/to lifeline. + */ + getStepsByLifelineId(id) { + Common.assertNotNull(id); + const steps = []; + for (const step of this.model.diagram.steps) { + if (step.message) { + if (step.message.from === id || step.message.to === id) { + steps.push(step); + } + } } - } + return steps; } - if (open.length > 0) { - for (const o of open) { - getData(o, fragmentsByStart[o]).start.push(o); - } + // /////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * Validate model. Disabled, because we removed the jsonschema dependency. + * @returns {Array} of validation errors, if any. + */ + validate() { + const errors = []; + return errors; } - return fData; - } + // /////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * Reorder messages. + * @param index message index. + * @param afterIndex new (after) index. + */ + reorderMessages(index, afterIndex) { + Common.assertType(index, 'Number'); + Common.assertType(afterIndex, 'Number'); + const steps = this.model.diagram.steps; + const element = steps[index]; + steps.splice(index, 1); + steps.splice(afterIndex, 0, element); + this.renumber(); + } - // /////////////////////////////////////////////////////////////////////////////////////////////// + // /////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * Reorder lifelines. + * @param index lifeline index. + * @param afterIndex new (after) index. + */ + reorderLifelines(index, afterIndex) { + Common.assertType(index, 'Number'); + Common.assertType(afterIndex, 'Number'); + const lifelines = this.model.diagram.lifelines; + const element = lifelines[index]; + lifelines.splice(index, 1); + lifelines.splice(afterIndex, 0, element); + this.renumber(); + } - /** - * Build a simple, navigable dataset describing occurrences. - * @returns a map, indexed by lifeline ID, of objects containing {start:[],stop:[],active[]}. - * @private - */ - analyzeOccurrences() { + // /////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * Renumber lifelines and messages. + */ + renumber() { + const modelJSON = this.unwrap(); + let stepIndex = 1; + let lifelineIndex = 1; + for (const step of modelJSON.diagram.steps) { + if (step.message) { + step.message.index = stepIndex++; + } + } + for (const lifeline of modelJSON.diagram.lifelines) { + lifeline.index = lifelineIndex++; + } + } - const oData = {}; + // /////////////////////////////////////////////////////////////////////////////////////////////// - // A few inline functions. They make this method kinda lengthy, but they - // reduce clutter in the class and keep it coherent, so it's OK. + /** + * Build a simple, navigable dataset describing fragments. + * @returns {{}}, indexed by (stop) message ID, describing fragments. + */ + analyzeFragments() { + const fData = {}; - const getDataByLifelineId = function get(lifelineId) { - if (!oData[lifelineId]) { - oData[lifelineId] = { active: [], start: {}, stop: {} }; - } - return oData[lifelineId]; - }; + let depth = 0; + const modelJSON = this.unwrap(); + const open = []; - const contains = function contains(array, value) { - return (array && (array.indexOf(value) !== -1)); - }; + const getData = function g(stop, fragment) { + let data = fData[stop]; + if (!data) { + data = { stop, start: [], fragment }; + fData[stop] = data; + } + return data; + }; + + const fragmentsByStart = {}; + for (const step of modelJSON.diagram.steps) { + if (step.message && step.message.fragment) { + const message = step.message; + const fragment = message.fragment; + if (fragment.start) { + fragmentsByStart[fragment.start] = fragment; + open.push(message.id); + depth++; + } + if (fragment.stop) { + if (open.length > 0) { + getData(message.id).start.push(open.pop()); + } + depth = Math.max(depth - 1, 0); + } + } + } - const process = function process(message, lifelineId) { - const oRule = message.occurrences; - if (oRule) { + if (open.length > 0) { + for (const o of open) { + getData(o, fragmentsByStart[o]).start.push(o); + } + } - const oDataLifeline = getDataByLifelineId(lifelineId); - if (oDataLifeline) { + return fData; + } - // Record all starts. + // /////////////////////////////////////////////////////////////////////////////////////////////// - if (contains(oRule.start, lifelineId)) { - oDataLifeline.active.push(message.id); - oDataLifeline.start[message.id] = undefined; - } + /** + * Build a simple, navigable dataset describing occurrences. + * @returns a map, indexed by lifeline ID, of objects containing {start:[],stop:[],active[]}. + * @private + */ + analyzeOccurrences() { + const oData = {}; - // Reconcile with stops. + // A few inline functions. They make this method kinda lengthy, but they + // reduce clutter in the class and keep it coherent, so it's OK. - if (contains(oRule.stop, lifelineId)) { - const startMessageId = oDataLifeline.active.pop(); - oDataLifeline.stop[message.id] = startMessageId; - if (startMessageId) { - oDataLifeline.start[startMessageId] = message.id; + const getDataByLifelineId = function get(lifelineId) { + if (!oData[lifelineId]) { + oData[lifelineId] = { active: [], start: {}, stop: {} }; + } + return oData[lifelineId]; + }; + + const contains = function contains(array, value) { + return array && array.indexOf(value) !== -1; + }; + + const process = function process(message, lifelineId) { + const oRule = message.occurrences; + if (oRule) { + const oDataLifeline = getDataByLifelineId(lifelineId); + if (oDataLifeline) { + // Record all starts. + + if (contains(oRule.start, lifelineId)) { + oDataLifeline.active.push(message.id); + oDataLifeline.start[message.id] = undefined; + } + + // Reconcile with stops. + + if (contains(oRule.stop, lifelineId)) { + const startMessageId = oDataLifeline.active.pop(); + oDataLifeline.stop[message.id] = startMessageId; + if (startMessageId) { + oDataLifeline.start[startMessageId] = message.id; + } + } + } + } + }; + + // Analyze start and end. + + const modelJSON = this.unwrap(); + for (const step of modelJSON.diagram.steps) { + if (step.message) { + const message = step.message; + if (message.occurrences) { + process(message, message.from); + process(message, message.to); + } } - } } - } - }; - - // Analyze start and end. - - const modelJSON = this.unwrap(); - for (const step of modelJSON.diagram.steps) { - if (step.message) { - const message = step.message; - if (message.occurrences) { - process(message, message.from); - process(message, message.to); + + // Reset active. (We used it, but it's not actually for us; it's for keeping + // track of active occurrences when rendering the diagram.) + + for (const lifelineId of Object.keys(oData)) { + oData[lifelineId].active = []; } - } - } - // Reset active. (We used it, but it's not actually for us; it's for keeping - // track of active occurrences when rendering the diagram.) + // Reconcile the start and end (message ID) maps for each lifeline, + // finding a "stop" for every start. Default to starting and stopping + // on the same message, which is the same as no occurrence. + + for (const lifelineId of Object.keys(oData)) { + const lifelineData = oData[lifelineId]; + for (const startId of Object.keys(lifelineData.start)) { + const stopId = lifelineData.start[startId]; + if (!stopId) { + lifelineData.start[startId] = startId; + lifelineData.stop[startId] = startId; + } + } + } - for (const lifelineId of Object.keys(oData)) { - oData[lifelineId].active = []; + return oData; } - // Reconcile the start and end (message ID) maps for each lifeline, - // finding a "stop" for every start. Default to starting and stopping - // on the same message, which is the same as no occurrence. - - for (const lifelineId of Object.keys(oData)) { - const lifelineData = oData[lifelineId]; - for (const startId of Object.keys(lifelineData.start)) { - const stopId = lifelineData.start[startId]; - if (!stopId) { - lifelineData.start[startId] = startId; - lifelineData.stop[startId] = startId; + // /////////////////////////////////////////////////////////////////////////////////////////////// + // /////////////////////////////////////////////////////////////////////////////////////////////// + // /////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * Preprocess model, adding IDs and whatnot. + * @param original to be preprocessed. + * @returns preprocessed JSON. + * @private + */ + _preprocess(original) { + const json = _merge({}, this.templates.defaultModel, original); + const metamodel = this.metamodel.unwrap(); + if (!json.diagram.metadata.ref) { + if (metamodel.diagram.metadata.id) { + json.diagram.metadata.ref = metamodel.diagram.metadata.id; + } else { + json.diagram.metadata.ref = '$'; + } } - } - } - return oData; - } - - // /////////////////////////////////////////////////////////////////////////////////////////////// - // /////////////////////////////////////////////////////////////////////////////////////////////// - // /////////////////////////////////////////////////////////////////////////////////////////////// - - /** - * Preprocess model, adding IDs and whatnot. - * @param original to be preprocessed. - * @returns preprocessed JSON. - * @private - */ - _preprocess(original) { - - const json = _merge({}, this.templates.defaultModel, original); - const metamodel = this.metamodel.unwrap(); - if (!json.diagram.metadata.ref) { - if (metamodel.diagram.metadata.id) { - json.diagram.metadata.ref = metamodel.diagram.metadata.id; - } else { - json.diagram.metadata.ref = '$'; - } - } + for (const lifeline of json.diagram.lifelines) { + lifeline.id = lifeline.id || lifeline.name; + } - for (const lifeline of json.diagram.lifelines) { - lifeline.id = lifeline.id || lifeline.name; - } + for (const step of json.diagram.steps) { + if (step.message) { + step.message.id = step.message.id || Model._guid(); + const occurrences = step.message.occurrences; + if (occurrences) { + occurrences.start = occurrences.start || []; + occurrences.stop = occurrences.stop || []; + } + } + } - for (const step of json.diagram.steps) { - if (step.message) { - step.message.id = step.message.id || Model._guid(); - const occurrences = step.message.occurrences; - if (occurrences) { - occurrences.start = occurrences.start || []; - occurrences.stop = occurrences.stop || []; + if (!json.diagram.metadata.id || json.diagram.metadata.id === '$') { + json.diagram.metadata.id = Model._guid(); } - } - } - if (!json.diagram.metadata.id || json.diagram.metadata.id === '$') { - json.diagram.metadata.id = Model._guid(); + return json; } - return json; - } - - // /////////////////////////////////////////////////////////////////////////////////////////////// - - /** - * Create pseudo-UUID. - * @returns {string} - * @private - */ - static _guid() { - function s4() { - return Math.floor((1 + Math.random()) * 0x10000) - .toString(16) - .substring(1); + // /////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * Create pseudo-UUID. + * @returns {string} + * @private + */ + static _guid() { + function s4() { + return Math.floor((1 + Math.random()) * 0x10000) + .toString(16) + .substring(1); + } + return `${s4()}-${s4()}-${s4()}-${s4()}-${s4()}-${s4()}-${s4()}-${s4()}`; } - return `${s4()}-${s4()}-${s4()}-${s4()}-${s4()}-${s4()}-${s4()}-${s4()}`; - } - } -- cgit 1.2.3-korg