{"version":3,"sources":["https://lively-kernel.org/lively4/lively4-constraints/src/components/demo/lively-simulation-controller.js"],"names":["Morph","_","LivelySimulationController","initialize","initializeStartStopButton","initializeStepButton","initializeAppendCellButton","initializeVelocitySlider","initializeRevertSelect","initializeStopOnErrorCheckBox","initializeResetTimeButton","initializeTimeDeltaInput","startStopButton","get","addEventListener","onStartStopButton","stepButton","onStepButton","appendCellButton","event","onAppendCellButton","velocitySlider","onVelocitySlider","revertSelect","onRevertSelect","onRevertSelectChange","stopOnErrorCheckBox","target","checked","stopOnError","onStopOnError","resetTimeButton","handleResetTime","timeDeltaInput","value","timeDelta","handleTimeDelta","initializeEngine","engine","registerIsRunningUpdater","registerVelocityUpdater","registerStopOnErrorUpdater","registerTimeUpdater","registerTimeDeltaUpdater","detachedCallback","isRunning","velocity","velocitySpan","time","timeSpan","dt","dtSpan","getEngine","toggleStartStop","step","simulation","getSimulation","addCell","setVelocity","options","generateCheckpointOptions","resetRevertSelect","forEach","option","appendChild","snapshot","revert","setTime","setTimeDeltaPerStepInMilliseconds","e","children","checkpointOptions","takeRight","child","remove","history","filter","getHistory","map","timestamp","selector","shadowRoot","querySelector","getRootNode","isFocused","isChildFocused","doc","document"],"mappings":"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","file":"lively-simulation-controller.js","sourcesContent":["\"enable aexpr\";\n\nimport Morph from 'src/components/widgets/lively-morph.js';\nimport _ from 'src/external/lodash/lodash.js';\n\nexport default class LivelySimulationController extends Morph {\n  \n  // life cycle\n  initialize() {\n    this.initializeStartStopButton();\n    this.initializeStepButton();\n    this.initializeAppendCellButton();\n    this.initializeVelocitySlider();\n    this.initializeRevertSelect();\n    this.initializeStopOnErrorCheckBox();\n    this.initializeResetTimeButton();\n    this.initializeTimeDeltaInput();\n  }\n  \n  initializeStartStopButton() {\n    const startStopButton = this.get('#startStopButton');\n    startStopButton.addEventListener('click', () => this.onStartStopButton());\n  }\n  \n  initializeStepButton() {\n    const stepButton = this.get('#stepButton');\n    stepButton.addEventListener('click', () => this.onStepButton());\n  }\n  \n  initializeAppendCellButton() {\n    const appendCellButton = this.get('#appendCellButton');\n    appendCellButton.addEventListener('click', (event) => this.onAppendCellButton(event));\n  }\n  \n  initializeVelocitySlider() {\n    const velocitySlider = this.get('#velocitySlider');\n    velocitySlider.addEventListener('input', (event) => this.onVelocitySlider(event));\n  }\n  \n  initializeRevertSelect() {\n    const revertSelect = this.get('#revertSelect');\n    revertSelect.addEventListener('click', () => this.onRevertSelect());\n    revertSelect.addEventListener('change', (event) => this.onRevertSelectChange(event));\n  }\n  \n  initializeStopOnErrorCheckBox() {\n    const stopOnErrorCheckBox = this.get('#stopOnErrorCheckBox');\n    stopOnErrorCheckBox.addEventListener('change', ({ target: { checked: stopOnError }}) => this.onStopOnError(stopOnError))\n  }\n  \n  initializeResetTimeButton() {\n    const resetTimeButton = this.get('#resetTime');\n    resetTimeButton.addEventListener('click', () => this.handleResetTime());\n  }\n  \n  initializeTimeDeltaInput() {\n    const timeDeltaInput = this.get('#dt');\n    timeDeltaInput.addEventListener('change', ({ target: { value: timeDelta }}) => this.handleTimeDelta(timeDelta));\n  }\n  \n  initializeEngine(engine) {\n    this.registerIsRunningUpdater(engine);\n    this.registerVelocityUpdater(engine);\n    this.registerStopOnErrorUpdater(engine);\n    this.registerTimeUpdater(engine);\n    this.registerTimeDeltaUpdater(engine);\n  }\n  \n  detachedCallback() {\n    if (this.isRunningUpdater) this.isRunningUpdater.dispose();\n    if (this.velocityUpdater) this.velocityUpdater.dispose();\n    if (this.stopOnErrorUpdater) this.stopOnErrorUpdater.dispose();\n    if (this.timeUpdater) this.timeUpdater.dispose();\n    if (this.timeDeltaUpdater) this.timeDeltaUpdater.dispose();\n  }\n  \n  registerIsRunningUpdater(engine) {\n    this.isRunningUpdater = aexpr(() => engine.isRunning).dataflow(isRunning => {\n      const startStopButton = this.get('#startStopButton');\n      startStopButton.textContent = isRunning ? 'Stop' : 'Start';\n      if (isRunning) startStopButton.classList.add('stop');\n      else startStopButton.classList.remove('stop');\n    });\n  }\n  \n  registerVelocityUpdater(engine) {\n    this.velocityUpdater = aexpr(() => engine.velocity).dataflow(velocity => {\n      const velocitySlider = this.get('#velocitySlider');\n      velocitySlider.value = velocity;\n      const velocitySpan = this.get('#velocitySpan');\n      velocitySpan.innerText = velocity;\n    });\n  }\n  \n  registerStopOnErrorUpdater(engine) {\n    this.stopOnErrorUpdater = aexpr(() => engine.stopOnError).dataflow(stopOnError => {\n      const stopOnErrorCheckBox = this.get('#stopOnErrorCheckBox');\n      stopOnErrorCheckBox.checked = stopOnError;\n    });\n  }\n  \n  registerTimeUpdater(engine) {\n    this.timeUpdater = aexpr(() => engine.time).dataflow(time => {\n      const timeSpan = this.get('#time');\n      timeSpan.innerText = time;\n    });\n  }\n  \n  registerTimeDeltaUpdater(engine) {\n    this.timeDeltaUpdater = aexpr(() => engine.timeDeltaPerStepInMilliseconds).dataflow(dt => {\n      const dtSpan = this.get('#dt');\n      dtSpan.value = dt;\n    });\n  }\n  \n  // event listener\n  onStartStopButton() {\n    const engine = this.getEngine();\n    if (!engine) return;\n    engine.toggleStartStop();\n  }\n  \n  onStepButton() {\n    const engine = this.getEngine();\n    if (!engine) return;\n    engine.step();\n  }\n  \n  onAppendCellButton(event) {\n    const simulation = this.getSimulation();\n    if (simulation && simulation.addCell) simulation.addCell(event);\n  }\n  \n  onVelocitySlider({ target: { value: velocity } }) {\n    const engine = this.getEngine();\n    if (!engine) return;\n    engine.setVelocity(velocity);\n  }\n  \n  onRevertSelect() {\n    const revertSelect = this.get('#revertSelect');\n    const options = this.generateCheckpointOptions();\n    this.resetRevertSelect();\n    _.forEach(options, option => revertSelect.appendChild(option));\n  }\n  \n  onRevertSelectChange({ target: { value: snapshot } }){\n    const simulation = this.getSimulation();\n    if (simulation && simulation.revert) simulation.revert(snapshot);\n    this.resetRevertSelect();\n  }\n  \n  onStopOnError(stopOnError) {\n    const engine = this.getEngine();\n    if (!engine) return;\n    engine.stopOnError = stopOnError;\n  }\n  \n  handleResetTime() {\n    const engine = this.getEngine();\n    if (!engine) return;\n    engine.setTime(0);\n  }\n  \n  handleTimeDelta(timeDelta) {\n    const engine = this.getEngine();\n    if (!engine) return;\n    try {\n      engine.setTimeDeltaPerStepInMilliseconds(parseInt(timeDelta));\n    } catch (e) { /* ignore */ }\n  }\n  \n  // other\n  resetRevertSelect() {\n    const revertSelect = this.get('#revertSelect');\n    const { children } = revertSelect;\n    const checkpointOptions = _.takeRight(children, children.length - 1);\n    _.forEach(checkpointOptions, child => child.remove());\n    revertSelect.value = '';\n  }\n  \n  generateCheckpointOptions() {\n    const history = _.filter(this.getHistory());\n    return _.map(history, ({ snapshot, timestamp }) => (\n      <option value={snapshot}>\n        { timestamp }\n      </option>\n    ));\n  }\n  \n  get(selector) {\n    const { shadowRoot } = this;\n    return shadowRoot.querySelector(selector);\n  }\n  \n  getSimulation() {\n    return this.getRootNode().host;\n  }\n  \n  getEngine() {\n    const simulation = this.getSimulation();\n    return simulation && simulation.getEngine && simulation.getEngine();\n  }\n  \n  getHistory() {\n    const simulation = this.getSimulation();\n    return simulation && simulation.getHistory && simulation.getHistory();\n  }\n  \n  isFocused() {\n    return this.isChildFocused(this.get('#dt'));\n  }\n  \n  isChildFocused(child, doc = document) {\n    if (doc.activeElement === child) return true;\n    if (doc.activeElement && doc.activeElement.shadowRoot)\n\t\t\treturn this.isChildFocused(child, doc.activeElement.shadowRoot)\n    return false;\n  }\n}"]}