<commit_before>(function () {
    var settings = Store("settings");
    var Bundle = {};

    Bundle.Group = new Class({
        // label
        "initialize": function (params) {
            this.params = (typeOf(params) === "object") ? params : {};

            this.createDOM();
            this.setupDOM();

            return this.bundle;
        },

        "createDOM": function () {
            this.bundle = new Element("div", {
                "class": "setting bundle group"
            });

            this.container = new Element("div", {
                "class": "setting container group"
            });

            this.element = new Element("h2", {
                "class": "setting element group"
            });
        },

        "setupDOM": function () {
            if (typeOf(this.params.label) === "string") {
                this.element.set("text", this.params.label);
            }
            this.element.inject(this.container);
            this.container.inject(this.bundle);
        }
    });

    Bundle.Description = new Class({
        // text
        "initialize": function (params) {
            this.params = (typeOf(params) === "object") ? params : {};

            this.createDOM();
            this.setupDOM();

            return this.bundle;
        },

        "createDOM": function () {
            this.bundle = new Element("div", {
                "class": "setting bundle description"
            });

            this.container = new Element("div", {
                "class": "setting container description"
            });

            this.element = new Element("p", {
                "class": "setting element description"
            });
        },

        "setupDOM": function () {
            if (typeOf(this.params.text) === "string") {
                this.element.set("text", this.params.text);
            }
            this.element.inject(this.container);
            this.container.inject(this.bundle);
        }
    });

    Bundle.Button = new Class({
        // label, text, action(click)
        "initialize": function (params) {
            this.params = (typeOf(params) === "object") ? params : {};

            this.createDOM();
            this.setupDOM();
            this.addEvents();

            return this.bundle;
        },

        "createDOM": function () {
            this.bundle = new Element("div", {
                "class": "setting bundle button"
            });

            this.container = new Element("div", {
                "class": "setting container button"
            });

            this.element = new Element("button", {
                "class": "setting element button",
                "type": "button"
            });

            this.label = new Element("label", {
                "class": "setting label button"
            });
        },

        "setupDOM": function () {
            if (typeOf(this.params.label) === "string") {
                this.label.set("text", this.params.label);
                this.label.inject(this.container);
            }

            if (typeOf(this.params.text) === "string") {
                this.element.set("text", this.params.text);
            }
            this.element.inject(this.container);

            this.container.inject(this.bundle);
        },

        "addEvents": function () {
            if (typeOf(this.params.action) === "function") {
                this.element.addEvent("click", (function () {
                    this.params.action();
                }).bind(this));
            }
        }
    });

    Bundle.Text = new Class({
        // name, label, text, action(change), masked
        "initialize": function (params) {
            this.params = (typeOf(params) === "object") ? params : {};

            this.createDOM();
            this.setupDOM();
            this.addEvents();

            if (typeOf(this.params.name) === "string" && this.params.name !== "") {
                this.set(settings[this.params.name]);
            }

            return this.bundle;
        },

        "createDOM": function () {
            this.bundle = new Element("div", {
                "class": "setting bundle text"
            });

            this.container = new Element("div", {
                "class": "setting container text"
            });

            this.element = new Element("input", {
                "class": "setting element text",
                "type": "text"
            });

            this.label = new Element("label", {
                "class": "setting label text"
            });
        },

        "setupDOM": function () {
            if (typeOf(this.params.label) === "string") {
                this.label.set("text", this.params.label);
                this.label.inject(this.container);
            }

            if (typeOf(this.params.text) === "string") {
                this.element.set("placeholder", this.params.text);
            }
            if (this.params.masked === true) {
                this.element.set("type", "password");
            }
            this.element.inject(this.container);

            this.container.inject(this.bundle);
        },

        "addEvents": function () {
            var change = (function (event) {
                if (typeOf(this.params.name) === "string" && this.params.name !== "") {
                    settings[this.params.name] = this.get();
                    settings.save();
                }

                if (typeOf(this.params.action) === "function") {
                    this.params.action(this.get());
                }
            }).bind(this);

            this.element.addEvent("change", change);
            this.element.addEvent("keyup", change);
        },

        "get": function () {
            return this.element.get("value");
        },

        "set": function (value) {
            value = (typeOf(value) === "string") ? value : "";
            this.element.set("value", value);
            return this;
        }
    });

    Bundle.Checkbox = new Class({
        // name, label, action(change)
        "initialize": function (params) {
            this.params = (typeOf(params) === "object") ? params : {};

            this.createDOM();
            this.setupDOM();
            this.addEvents();

            if (typeOf(this.params.name) === "string" && this.params.name !== "") {
                this.set(settings[this.params.name]);
            }

            return this.bundle;
        },

        "createDOM": function () {
            this.bundle = new Element("div", {
                "class": "setting bundle checkbox"
            });

            this.container = new Element("div", {
                "class": "setting container checkbox"
            });

            this.element = new Element("input", {
                "id": String.uniqueID(),
                "class": "setting element checkbox",
                "type": "checkbox"
            });

            this.label = new Element("label", {
                "class": "setting label checkbox",
                "for": this.element.get("id")
            });
        },

        "setupDOM": function () {
            this.element.inject(this.container);
            if (typeOf(this.params.label) === "string") {
                this.label.set("text", this.params.label);
                this.label.inject(this.container);
            }
            this.container.inject(this.bundle);
        },

        "addEvents": function () {
            this.element.addEvent("change", (function (event) {
                if (typeOf(this.params.name) === "string" && this.params.name !== "") {
                    settings[this.params.name] = this.get();
                    settings.save();
                }

                if (typeOf(this.params.action) === "function") {
                    this.params.action(this.get());
                }
            }).bind(this));
        },

        "get": function () {
            return this.element.get("checked");
        },

        "set": function (value) {
            value = (typeOf(value) === "boolean") ? value : false;
            this.element.set("checked", value);
            return this;
        }
    });

    Bundle.Slider = new Class({
        // name, label, action(change), max, min, step
        "initialize": function (params) {
            this.params = (typeOf(params) === "object") ? params : {};

            this.createDOM();
            this.setupDOM();
            this.addEvents();

            if (typeOf(this.params.name) === "string" && this.params.name !== "") {
                this.set(settings[this.params.name]);
            }

            return this.bundle;
        },

        "createDOM": function () {
            this.bundle = new Element("div", {
                "class": "setting bundle slider"
            });

            this.container = new Element("div", {
                "class": "setting container slider"
            });

            this.element = new Element("input", {
                "class": "setting element slider",
                "type": "range"
            });

            this.label = new Element("label", {
                "class": "setting label slider"
            });
        },

        "setupDOM": function () {
            if (typeOf(this.params.label) === "string") {
                this.label.set("text", this.params.label);
                this.label.inject(this.container);
            }

            if (typeOf(this.params.max) === "string") {
                this.element.set("max", this.params.max);
            }
            if (typeOf(this.params.min) === "string") {
                this.element.set("min", this.params.min);
            }
            if (typeOf(this.params.step) === "string") {
                this.element.set("step", this.params.step);
            }
            this.element.inject(this.container);

            this.container.inject(this.bundle);
        },

        "addEvents": function () {
            this.element.addEvent("change", (function (event) {
                if (typeOf(this.params.name) === "string" && this.params.name !== "") {
                    settings[this.params.name] = this.get();
                    settings.save();
                }

                if (typeOf(this.params.action) === "function") {
                    this.params.action(this.get());
                }
            }).bind(this));
        },

        "get": function () {
            return this.element.get("value");
        },

        "set": function (value) {
            value = (typeOf(value) === "string") ? value : "";
            this.element.set("value", value);
            return this;
        }
    });

    Bundle.PopupButton = new Class({
        // name, label, action(change), options[{value, text}]
        "initialize": function (params) {
            this.params = (typeOf(params) === "object") ? params : {};
            this.params.options = (typeOf(this.params.options) === "array") ? this.params.options : [];

            this.createDOM();
            this.setupDOM();
            this.addEvents();

            if (typeOf(this.params.name) === "string" && this.params.name !== "") {
                this.set(settings[this.params.name]);
            }

            return this.bundle;
        },

        "createDOM": function () {
            this.bundle = new Element("div", {
                "class": "setting bundle popup-button"
            });

            this.container = new Element("div", {
                "class": "setting container popup-button"
            });

            this.element = new Element("select", {
                "class": "setting element popup-button"
            });

            this.label = new Element("label", {
                "class": "setting label popup-button"
            });

            this.params.options.each((function (option) {
                option = (typeOf(option) === "object") ? option : {};

                (new Element("option", {
                    "value": option.value,
                    "text": option.text || option.value
                })).inject(this.element);
            }).bind(this));
        },

        "setupDOM": function () {
            if (typeOf(this.params.label) === "string") {
                this.label.set("text", this.params.label);
                this.label.inject(this.container);
            }
            this.element.inject(this.container);
            this.container.inject(this.bundle);
        },

        "addEvents": function () {
            this.element.addEvent("change", (function (event) {
                if (typeOf(this.params.name) === "string" && this.params.name !== "") {
                    settings[this.params.name] = this.get();
                    settings.save();
                }

                if (typeOf(this.params.action) === "function") {
                    this.params.action(this.get());
                }
            }).bind(this));
        },

        "get": function () {
            return this.element.get("value");
        },

        "set": function (value) {
            value = (typeOf(value) === "string") ? value : "";
            this.element.set("value", value);
            return this;
        }
    });

    window.addEvent("domready", function () {

        (new Bundle.PopupButton({
            "options": [
                {
                    "value": "test1",
                    "text": "Erster Test"
                },

                {
                    "value": "test2"
                }
            ],

            "label": "wähle dein lieblingsteil: ",
            "name": "hahaha"
        })).inject($("content"));
    });

    return;
    this.Setting = new Class({
        "initialize": function (container) {
            // Check Container
            if (typeOf(container) !== "element") {
                throw "containerNotAnElement";
            }

            this.container = container;
        },

        "new": function (id, type, params) {
            switch (type) {
                case "button":
                    //
                    break;
                case "textfield": // param password
                    //
                    break;
                case "checkbox":
                    //
                    break;
                case "slider":
                    //
                    break;
                case "popupButton":
                    //
                    break;
                case "listBox":
                    //
                    break;
                case "radioButtons":
                    //
                    break;
                case "group":
                    //
                    break;
                case "separator":
                    //
                    break;
            }
        }
    });
}());
<commit_msg>ListBox is working<commit_after>(function () {
    var settings = Store("settings");
    var Bundle = {};

    Bundle.Group = new Class({
        // label
        "initialize": function (params) {
            this.params = (typeOf(params) === "object") ? params : {};

            this.createDOM();
            this.setupDOM();

            return this.bundle;
        },

        "createDOM": function () {
            this.bundle = new Element("div", {
                "class": "setting bundle group"
            });

            this.container = new Element("div", {
                "class": "setting container group"
            });

            this.element = new Element("h2", {
                "class": "setting element group"
            });
        },

        "setupDOM": function () {
            if (typeOf(this.params.label) === "string") {
                this.element.set("text", this.params.label);
            }
            this.element.inject(this.container);
            this.container.inject(this.bundle);
        }
    });

    Bundle.Description = new Class({
        // text
        "initialize": function (params) {
            this.params = (typeOf(params) === "object") ? params : {};

            this.createDOM();
            this.setupDOM();

            return this.bundle;
        },

        "createDOM": function () {
            this.bundle = new Element("div", {
                "class": "setting bundle description"
            });

            this.container = new Element("div", {
                "class": "setting container description"
            });

            this.element = new Element("p", {
                "class": "setting element description"
            });
        },

        "setupDOM": function () {
            if (typeOf(this.params.text) === "string") {
                this.element.set("text", this.params.text);
            }
            this.element.inject(this.container);
            this.container.inject(this.bundle);
        }
    });

    Bundle.Button = new Class({
        // label, text, action(click)
        "initialize": function (params) {
            this.params = (typeOf(params) === "object") ? params : {};

            this.createDOM();
            this.setupDOM();
            this.addEvents();

            return this.bundle;
        },

        "createDOM": function () {
            this.bundle = new Element("div", {
                "class": "setting bundle button"
            });

            this.container = new Element("div", {
                "class": "setting container button"
            });

            this.element = new Element("button", {
                "class": "setting element button",
                "type": "button"
            });

            this.label = new Element("label", {
                "class": "setting label button"
            });
        },

        "setupDOM": function () {
            if (typeOf(this.params.label) === "string") {
                this.label.set("text", this.params.label);
                this.label.inject(this.container);
            }

            if (typeOf(this.params.text) === "string") {
                this.element.set("text", this.params.text);
            }
            this.element.inject(this.container);

            this.container.inject(this.bundle);
        },

        "addEvents": function () {
            if (typeOf(this.params.action) === "function") {
                this.element.addEvent("click", (function () {
                    this.params.action();
                }).bind(this));
            }
        }
    });

    Bundle.Text = new Class({
        // name, label, text, action(change), masked
        "initialize": function (params) {
            this.params = (typeOf(params) === "object") ? params : {};

            this.createDOM();
            this.setupDOM();
            this.addEvents();

            if (typeOf(this.params.name) === "string" && this.params.name !== "") {
                this.set(settings[this.params.name]);
            }

            return this.bundle;
        },

        "createDOM": function () {
            this.bundle = new Element("div", {
                "class": "setting bundle text"
            });

            this.container = new Element("div", {
                "class": "setting container text"
            });

            this.element = new Element("input", {
                "class": "setting element text",
                "type": "text"
            });

            this.label = new Element("label", {
                "class": "setting label text"
            });
        },

        "setupDOM": function () {
            if (typeOf(this.params.label) === "string") {
                this.label.set("text", this.params.label);
                this.label.inject(this.container);
            }

            if (typeOf(this.params.text) === "string") {
                this.element.set("placeholder", this.params.text);
            }
            if (this.params.masked === true) {
                this.element.set("type", "password");
            }
            this.element.inject(this.container);

            this.container.inject(this.bundle);
        },

        "addEvents": function () {
            var change = (function (event) {
                if (typeOf(this.params.name) === "string" && this.params.name !== "") {
                    settings[this.params.name] = this.get();
                    settings.save();
                }

                if (typeOf(this.params.action) === "function") {
                    this.params.action(this.get());
                }
            }).bind(this);

            this.element.addEvent("change", change);
            this.element.addEvent("keyup", change);
        },

        "get": function () {
            return this.element.get("value");
        },

        "set": function (value) {
            value = (typeOf(value) === "string") ? value : "";
            this.element.set("value", value);
            return this;
        }
    });

    Bundle.Checkbox = new Class({
        // name, label, action(change)
        "initialize": function (params) {
            this.params = (typeOf(params) === "object") ? params : {};

            this.createDOM();
            this.setupDOM();
            this.addEvents();

            if (typeOf(this.params.name) === "string" && this.params.name !== "") {
                this.set(settings[this.params.name]);
            }

            return this.bundle;
        },

        "createDOM": function () {
            this.bundle = new Element("div", {
                "class": "setting bundle checkbox"
            });

            this.container = new Element("div", {
                "class": "setting container checkbox"
            });

            this.element = new Element("input", {
                "id": String.uniqueID(),
                "class": "setting element checkbox",
                "type": "checkbox"
            });

            this.label = new Element("label", {
                "class": "setting label checkbox",
                "for": this.element.get("id")
            });
        },

        "setupDOM": function () {
            this.element.inject(this.container);
            if (typeOf(this.params.label) === "string") {
                this.label.set("text", this.params.label);
                this.label.inject(this.container);
            }
            this.container.inject(this.bundle);
        },

        "addEvents": function () {
            this.element.addEvent("change", (function (event) {
                if (typeOf(this.params.name) === "string" && this.params.name !== "") {
                    settings[this.params.name] = this.get();
                    settings.save();
                }

                if (typeOf(this.params.action) === "function") {
                    this.params.action(this.get());
                }
            }).bind(this));
        },

        "get": function () {
            return this.element.get("checked");
        },

        "set": function (value) {
            value = (typeOf(value) === "boolean") ? value : false;
            this.element.set("checked", value);
            return this;
        }
    });

    Bundle.Slider = new Class({
        // name, label, action(change), max, min, step
        "initialize": function (params) {
            this.params = (typeOf(params) === "object") ? params : {};

            this.createDOM();
            this.setupDOM();
            this.addEvents();

            if (typeOf(this.params.name) === "string" && this.params.name !== "") {
                this.set(settings[this.params.name]);
            }

            return this.bundle;
        },

        "createDOM": function () {
            this.bundle = new Element("div", {
                "class": "setting bundle slider"
            });

            this.container = new Element("div", {
                "class": "setting container slider"
            });

            this.element = new Element("input", {
                "class": "setting element slider",
                "type": "range"
            });

            this.label = new Element("label", {
                "class": "setting label slider"
            });
        },

        "setupDOM": function () {
            if (typeOf(this.params.label) === "string") {
                this.label.set("text", this.params.label);
                this.label.inject(this.container);
            }

            if (typeOf(this.params.max) === "string") {
                this.element.set("max", this.params.max);
            }
            if (typeOf(this.params.min) === "string") {
                this.element.set("min", this.params.min);
            }
            if (typeOf(this.params.step) === "string") {
                this.element.set("step", this.params.step);
            }
            this.element.inject(this.container);

            this.container.inject(this.bundle);
        },

        "addEvents": function () {
            this.element.addEvent("change", (function (event) {
                if (typeOf(this.params.name) === "string" && this.params.name !== "") {
                    settings[this.params.name] = this.get();
                    settings.save();
                }

                if (typeOf(this.params.action) === "function") {
                    this.params.action(this.get());
                }
            }).bind(this));
        },

        "get": function () {
            return this.element.get("value");
        },

        "set": function (value) {
            value = (typeOf(value) === "string") ? value : "";
            this.element.set("value", value);
            return this;
        }
    });

    Bundle.PopupButton = new Class({
        // name, label, action(change), options[{value, text}]
        "initialize": function (params) {
            this.params = (typeOf(params) === "object") ? params : {};
            this.params.options = (typeOf(this.params.options) === "array") ? this.params.options : [];

            this.createDOM();
            this.setupDOM();
            this.addEvents();

            if (typeOf(this.params.name) === "string" && this.params.name !== "") {
                this.set(settings[this.params.name]);
            }

            return this.bundle;
        },

        "createDOM": function () {
            this.bundle = new Element("div", {
                "class": "setting bundle popup-button"
            });

            this.container = new Element("div", {
                "class": "setting container popup-button"
            });

            this.element = new Element("select", {
                "class": "setting element popup-button"
            });

            this.label = new Element("label", {
                "class": "setting label popup-button"
            });

            this.params.options.each((function (option) {
                option = (typeOf(option) === "object") ? option : {};

                (new Element("option", {
                    "value": option.value,
                    "text": option.text || option.value
                })).inject(this.element);
            }).bind(this));
        },

        "setupDOM": function () {
            if (typeOf(this.params.label) === "string") {
                this.label.set("text", this.params.label);
                this.label.inject(this.container);
            }
            this.element.inject(this.container);
            this.container.inject(this.bundle);
        },

        "addEvents": function () {
            this.element.addEvent("change", (function (event) {
                if (typeOf(this.params.name) === "string" && this.params.name !== "") {
                    settings[this.params.name] = this.get();
                    settings.save();
                }

                if (typeOf(this.params.action) === "function") {
                    this.params.action(this.get());
                }
            }).bind(this));
        },

        "get": function () {
            return this.element.get("value");
        },

        "set": function (value) {
            value = (typeOf(value) === "string") ? value : "";
            this.element.set("value", value);
            return this;
        }
    });

    Bundle.ListBox = new Class({
        "Extends": Bundle.PopupButton,

        "setupDOM": function () {
            this.element.set("size", "2");

            if (typeOf(this.params.label) === "string") {
                this.label.set("text", this.params.label);
                this.label.inject(this.container);
            }
            this.element.inject(this.container);
            this.container.inject(this.bundle);
        }
    });

    window.addEvent("domready", function () {

        (new Bundle.ListBox({
            "options": [
                {
                    "value": "test1",
                    "text": "Erster Test"
                }    ,

                    {
                        "value": "test2"
                    }
            ],

            "label": "wähle dein lieblingsteil: ",
            "name": "hahaha"
        })).inject($("content"));
    });

    return;
    this.Setting = new Class({
        "initialize": function (container) {
            // Check Container
            if (typeOf(container) !== "element") {
                throw "containerNotAnElement";
            }

            this.container = container;
        },

        "new": function (id, type, params) {
            switch (type) {
                case "button":
                    //
                    break;
                case "textfield": // param password
                    //
                    break;
                case "checkbox":
                    //
                    break;
                case "slider":
                    //
                    break;
                case "popupButton":
                    //
                    break;
                case "listBox":
                    //
                    break;
                case "radioButtons":
                    //
                    break;
                case "group":
                    //
                    break;
                case "separator":
                    //
                    break;
            }
        }
    });
}());
<|endoftext|>


<commit_before>// @flow
import { createWriteStream, readFileSync } from 'fs';
import { spawn } from 'child_process';
import { BrowserWindow } from 'electron';
import { Logger } from '../../common/logging';
import { prepareArgs } from './config';
import { CardanoNode } from './CardanoNode';
import {
  cardanoTlsConfigChannel,
  cardanoRestartChannel,
  cardanoAwaitUpdateChannel,
  cardanoStateChangeChannel
} from '../ipc/cardano.ipc';
import { safeExitWithCode } from '../utils/safeExitWithCode';
import type { TlsConfig, CardanoNodeState } from '../../common/types/cardanoNode.types';
import type { LauncherConfig } from '../config';

const startCardanoNode = (node: CardanoNode, launcherConfig: Object) => {
  const { nodePath, tlsPath, logsPrefix } = launcherConfig;
  const nodeArgs = prepareArgs(launcherConfig);
  const logFilePath = logsPrefix + '/cardano-node.log';
  const config = {
    nodePath,
    logFilePath,
    tlsPath,
    nodeArgs,
    startupTimeout: 5000,
    startupMaxRetries: 5,
    shutdownTimeout: 30000,
    killTimeout: 30000,
    updateTimeout: 60000,
  };
  return node.start(config);
};

const restartCardanoNode = async (node: CardanoNode) => {
  try {
    await node.restart();
  } catch (error) {
    Logger.info(`Could not restart CardanoNode: ${error}`);
  }
};

/**
 * Configures, starts and manages the CardanoNode responding to node
 * state changes, app events and IPC messages coming from the renderer.
 *
 * @param launcherConfig {LauncherConfig}
 * @param mainWindow
 */
export const setupCardano = (
  launcherConfig: LauncherConfig, mainWindow: BrowserWindow
): CardanoNode => {

  const cardanoNode = new CardanoNode(Logger, {
    // Dependencies on node.js apis are passed as props to ease testing
    spawn,
    readFileSync,
    createWriteStream,
    broadcastTlsConfig: (config: ?TlsConfig) => {
      if (!mainWindow.isDestroyed()) cardanoTlsConfigChannel.send(config, mainWindow);
    },
    broadcastStateChange: (state: CardanoNodeState) => {
      if (!mainWindow.isDestroyed()) cardanoStateChangeChannel.send(state, mainWindow);
    },
  }, {
    // CardanoNode lifecycle hooks
    onStarting: () => {},
    onRunning: () => {},
    onStopping: () => {},
    onStopped: () => {},
    onUpdating: () => {},
    onUpdated: () => {},
    onCrashed: (code) => {
      const restartTimeout = cardanoNode.startupTries > 0 ? 30000 : 0;
      Logger.info(`CardanoNode crashed with code ${code}. Restarting in ${restartTimeout}ms …`);
      setTimeout(() => restartCardanoNode(cardanoNode), restartTimeout);
    },
    onError: () => {},
    onUnrecoverable: () => {}
  });
  startCardanoNode(cardanoNode, launcherConfig);

  cardanoStateChangeChannel.onReceive(() => {
    Logger.info('ipcMain: Received request from renderer for node state.');
    return Promise.resolve(cardanoNode.state);
  });
  cardanoTlsConfigChannel.onReceive(() => {
    Logger.info('ipcMain: Received request from renderer for tls config.');
    return Promise.resolve(cardanoNode.tlsConfig);
  });
  cardanoAwaitUpdateChannel.onReceive(() => {
    Logger.info('ipcMain: Received request from renderer to await update.');
    setTimeout(async () => {
      await cardanoNode.expectNodeUpdate();
      Logger.info('CardanoNode applied an update. Exiting Daedalus with code 20.');
      safeExitWithCode(20);
    });
    return Promise.resolve();
  });
  cardanoRestartChannel.onReceive(() => {
    Logger.info('ipcMain: Received request from renderer to restart node.');
    return cardanoNode.restart(true); // forced restart
  });

  return cardanoNode;
};
<commit_msg>[DDW-448] reduce cardano stop and kill timeout to 10 seconds<commit_after>// @flow
import { createWriteStream, readFileSync } from 'fs';
import { spawn } from 'child_process';
import { BrowserWindow } from 'electron';
import { Logger } from '../../common/logging';
import { prepareArgs } from './config';
import { CardanoNode } from './CardanoNode';
import {
  cardanoTlsConfigChannel,
  cardanoRestartChannel,
  cardanoAwaitUpdateChannel,
  cardanoStateChangeChannel
} from '../ipc/cardano.ipc';
import { safeExitWithCode } from '../utils/safeExitWithCode';
import type { TlsConfig, CardanoNodeState } from '../../common/types/cardanoNode.types';
import type { LauncherConfig } from '../config';

const startCardanoNode = (node: CardanoNode, launcherConfig: Object) => {
  const { nodePath, tlsPath, logsPrefix } = launcherConfig;
  const nodeArgs = prepareArgs(launcherConfig);
  const logFilePath = logsPrefix + '/cardano-node.log';
  const config = {
    nodePath,
    logFilePath,
    tlsPath,
    nodeArgs,
    startupTimeout: 5000,
    startupMaxRetries: 5,
    shutdownTimeout: 10000,
    killTimeout: 10000,
    updateTimeout: 60000,
  };
  return node.start(config);
};

const restartCardanoNode = async (node: CardanoNode) => {
  try {
    await node.restart();
  } catch (error) {
    Logger.info(`Could not restart CardanoNode: ${error}`);
  }
};

/**
 * Configures, starts and manages the CardanoNode responding to node
 * state changes, app events and IPC messages coming from the renderer.
 *
 * @param launcherConfig {LauncherConfig}
 * @param mainWindow
 */
export const setupCardano = (
  launcherConfig: LauncherConfig, mainWindow: BrowserWindow
): CardanoNode => {

  const cardanoNode = new CardanoNode(Logger, {
    // Dependencies on node.js apis are passed as props to ease testing
    spawn,
    readFileSync,
    createWriteStream,
    broadcastTlsConfig: (config: ?TlsConfig) => {
      if (!mainWindow.isDestroyed()) cardanoTlsConfigChannel.send(config, mainWindow);
    },
    broadcastStateChange: (state: CardanoNodeState) => {
      if (!mainWindow.isDestroyed()) cardanoStateChangeChannel.send(state, mainWindow);
    },
  }, {
    // CardanoNode lifecycle hooks
    onStarting: () => {},
    onRunning: () => {},
    onStopping: () => {},
    onStopped: () => {},
    onUpdating: () => {},
    onUpdated: () => {},
    onCrashed: (code) => {
      const restartTimeout = cardanoNode.startupTries > 0 ? 30000 : 0;
      Logger.info(`CardanoNode crashed with code ${code}. Restarting in ${restartTimeout}ms …`);
      setTimeout(() => restartCardanoNode(cardanoNode), restartTimeout);
    },
    onError: () => {},
    onUnrecoverable: () => {}
  });
  startCardanoNode(cardanoNode, launcherConfig);

  cardanoStateChangeChannel.onReceive(() => {
    Logger.info('ipcMain: Received request from renderer for node state.');
    return Promise.resolve(cardanoNode.state);
  });
  cardanoTlsConfigChannel.onReceive(() => {
    Logger.info('ipcMain: Received request from renderer for tls config.');
    return Promise.resolve(cardanoNode.tlsConfig);
  });
  cardanoAwaitUpdateChannel.onReceive(() => {
    Logger.info('ipcMain: Received request from renderer to await update.');
    setTimeout(async () => {
      await cardanoNode.expectNodeUpdate();
      Logger.info('CardanoNode applied an update. Exiting Daedalus with code 20.');
      safeExitWithCode(20);
    });
    return Promise.resolve();
  });
  cardanoRestartChannel.onReceive(() => {
    Logger.info('ipcMain: Received request from renderer to restart node.');
    return cardanoNode.restart(true); // forced restart
  });

  return cardanoNode;
};
<|endoftext|>


<commit_before>// produces wrong line numbers:
// import 'source-map-support/register'

import React from 'react'
import ReactDOM from 'react-dom/server'

// https://github.com/ReactTraining/react-router/issues/4023
// Also adds `useBasename` and `useQueries`
import createHistory from 'react-router/lib/createMemoryHistory'

import Html from './html'
import normalize_common_settings from '../redux/normalize'
import timer from '../timer'
import create_history from '../history'
import { location_url, parse_location } from '../location'

import redux_render, { initialize as redux_initialize } from '../redux/server/server'
import { render_on_server as react_router_render } from '../react-router/render'

import { Preload } from '../redux/actions'

// isomorphic (universal) rendering (middleware).
// will be used in web_application.use(...)
export default async function(settings, { initialize, localize, assets, application, request, render, loading, html = {}, cookies, beforeRender })
{
	settings = normalize_common_settings(settings)

	const
	{
		routes,
		wrapper,
		authentication
	}
	= settings

	const error_handler = settings.error

	// If Redux is being used, then render for Redux.
	// Else render for pure React.
	const render_page = redux_render

	// Read protected cookie value (if configured)
	let protected_cookie_value
	if (authentication && authentication.protectedCookie)
	{
		protected_cookie_value = cookies.get(authentication.protectedCookie)
	}

	// `history` is created after the `store`.
	// At the same time, `store` needs the `history` later during navigation.
	// And `history` might need store for things like `react-router-redux`.
	// Hence the getter instead of a simple variable
	let history
	const get_history = () => history

	const initialize_timer = timer()

	// These `parameters` are used for `assets`, `html` modifiers
	// and also for `localize()` call.
	const initialize_result = await redux_initialize(settings,
	{
		protected_cookie_value,
		application,
		request,
		cookies,
		initialize,
		get_history
	})

	const { extension_javascript, afterwards, ...parameters } = initialize_result

	const normalize_result = result => _normalize_result(result, afterwards, settings)

	// Create `history` (`true` indicates server-side usage).
	// Koa `request.url` is not really a URL,
	// it's a URL without the `origin` (scheme, host, port).
	history = create_history(createHistory, request.url, settings.history, parameters, true)

	const location = history.getCurrentLocation()
	const path     = location.pathname

	// The above code (server-side `initialize()` method call) is not included
	// in this `try/catch` block because:
	//
	//  * `parameters` are used inside `.error()`
	//
	//  * even if an error was caught inside `initialize()`
	//    and a redirection was performed, say, to an `/error` page
	//    then it would fail again because `initialize()` would get called again,
	//    so wrapping `initialize()` with `try/catch` wouldn't help anyway.
	//
	try
	{
		const initialize_time = initialize_timer()

		// Internationalization

		let locale
		let messages
		let messagesJSON

		if (localize)
		{
			// `localize()` should normally be a synchronous function.
			// It could be asynchronous though for cases when it's taking
			// messages not from a JSON file but rather from an
			// "admin" user editable database.
			// If the rountrip time (ping) from the rendering service
			// to the database is small enough then it theoretically
			// won't introduce any major page rendering latency
			// (the database will surely cache such a hot query).
			// On the other hand, if a developer fights for each millisecond
			// then `localize()` should just return `messages` from memory.

			let result = localize(parameters)

			// If `localize()` returned a `Promise` then wait for it
			if (typeof result.then === 'function')
			{
				result = await result
			}

			locale   = result.locale
			messages = result.messages

			// A tiny optimization to avoid calculating
			// `JSON.stringify(messages)` for each rendered page:
			// `localize()` can return a cached `messagesJSON` string
			// instead of `messages` JSON object
			// to further reduce internationalization-induced latency
			// by an extra millisecond or so (benchmark if interested)
			// by not stringifying `messages` JSON object for each page rendered.
			messagesJSON = result.messagesJSON || JSON.stringify(messages)
		}

		// Render the web page
		const result = await render_page
		({
			...parameters,
			disable_server_side_rendering: render === false,
			history,
			routes,
			before_render: beforeRender,

			create_page_element: (child_element, props) =>
			{
				if (localize)
				{
					props.locale   = locale
					props.messages = messages
				}

				return React.createElement(wrapper, props, child_element)
			},

			render_webpage(content)
			{
				// Render page content
				content = render === false ? normalize_markup(loading) : (content && ReactDOM.renderToString(content))

				// `html` modifiers

				let { head } = html
				// camelCase support for those who prefer it
				let body_start = html.body_start || html.bodyStart
				let body_end   = html.body_end   || html.bodyEnd

				// Normalize `html` parameters
				head       = normalize_markup(typeof head       === 'function' ? head      (path, parameters) : head)
				body_start = normalize_markup(typeof body_start === 'function' ? body_start(path, parameters) : body_start)
				body_end   = normalize_markup(typeof body_end   === 'function' ? body_end  (path, parameters) : body_end)

				// Normalize assets
				assets = typeof assets === 'function' ? assets(path, parameters) : assets

				// Sanity check
				if (!assets.entries)
				{
					throw new Error(`"assets.entries" array parameter is required as of version 10.1.0. E.g. "{ ... entries: ['main'] ... }"`)
				}

				// Render the HTML
				return Html
				({
					...parameters,
					extension_javascript: typeof extension_javascript === 'function' ? extension_javascript() : extension_javascript,
					assets,
					locale,
					locale_messages_json: messagesJSON,
					head,
					body_start,
					body_end,
					protected_cookie_value,
					content
				})
			}
		})

		if (result.time)
		{
			result.time.initialize = initialize_time
		}

		return normalize_result(result)
	}
	catch (error)
	{
		// Redirection is sometimes done via an Error on server side.
		// (e.g. it can happen in `react-router`'s `onEnter()` during `match()`)
		if (error._redirect)
		{
			return normalize_result({ redirect: error._redirect })
		}

		if (error_handler)
		{
			const result = {}

			const error_handler_parameters =
			{
				path,
				url      : location_url(location),
				redirect : to => result.redirect = parse_location(to),
				server   : true
			}

			// Special case for Redux
			if (parameters.store)
			{
				error_handler_parameters.dispatch = redirecting_dispatch(parameters.store.dispatch, error_handler_parameters.redirect)
				error_handler_parameters.getState = parameters.store.getState
			}

			error_handler(error, error_handler_parameters)

			// Either redirects or throws the error
			if (result.redirect)
			{
				return normalize_result(result)
			}
		}

		throw error
	}
}

// Converts React.Elements to Strings
function normalize_markup(anything)
{
	if (!anything)
	{
		return ''
	}

	if (typeof anything === 'function')
	{
		return anything
	}

	if (typeof anything === 'string')
	{
		return anything
	}

	if (Array.isArray(anything))
	{
		return anything.map(normalize_markup).join('')
	}

	return ReactDOM.renderToString(anything)
}

// A special flavour of `dispatch` which `throw`s for redirects on the server side.
function redirecting_dispatch(dispatch, redirect)
{
	return (event) =>
	{
		switch (event.type)
		{
			// In case of navigation from @preload()
			case Preload:
				// `throw`s a special `Error` on server side
				return redirect(event.location)

			default:
				// Proceed with the original
				return dispatch(event)
		}
	}
}

function _normalize_result(result, afterwards, settings)
{
	// Stringify `redirect` location
	if (result.redirect)
	{
		// Prepend `basename` to relative URLs for server-side redirect.
		result.redirect = location_url(result.redirect, { basename: settings.history.options.basename })
	}

	// Add `afterwards`
	result.afterwards = afterwards

	return result
}<commit_msg>Server-side redirect limit to 1<commit_after>// produces wrong line numbers:
// import 'source-map-support/register'

import React from 'react'
import ReactDOM from 'react-dom/server'

// https://github.com/ReactTraining/react-router/issues/4023
// Also adds `useBasename` and `useQueries`
import createHistory from 'react-router/lib/createMemoryHistory'

import Html from './html'
import normalize_common_settings from '../redux/normalize'
import timer from '../timer'
import create_history from '../history'
import { location_url, parse_location } from '../location'

import redux_render, { initialize as redux_initialize } from '../redux/server/server'
import { render_on_server as react_router_render } from '../react-router/render'

import { Preload } from '../redux/actions'

// isomorphic (universal) rendering (middleware).
// will be used in web_application.use(...)
export default async function(settings, { initialize, localize, assets, application, request, render, loading, html = {}, cookies, beforeRender })
{
	settings = normalize_common_settings(settings)

	const
	{
		routes,
		wrapper,
		authentication
	}
	= settings

	const error_handler = settings.error

	// If Redux is being used, then render for Redux.
	// Else render for pure React.
	const render_page = redux_render

	// Read protected cookie value (if configured)
	let protected_cookie_value
	if (authentication && authentication.protectedCookie)
	{
		protected_cookie_value = cookies.get(authentication.protectedCookie)
	}

	// `history` is created after the `store`.
	// At the same time, `store` needs the `history` later during navigation.
	// And `history` might need store for things like `react-router-redux`.
	// Hence the getter instead of a simple variable
	let history
	const get_history = () => history

	const initialize_timer = timer()

	// These `parameters` are used for `assets`, `html` modifiers
	// and also for `localize()` call.
	const initialize_result = await redux_initialize(settings,
	{
		protected_cookie_value,
		application,
		request,
		cookies,
		initialize,
		get_history
	})

	const { extension_javascript, afterwards, ...parameters } = initialize_result

	const normalize_result = result => _normalize_result(result, afterwards, settings)

	// Create `history` (`true` indicates server-side usage).
	// Koa `request.url` is not really a URL,
	// it's a URL without the `origin` (scheme, host, port).
	history = create_history(createHistory, request.url, settings.history, parameters, true)

	const location = history.getCurrentLocation()
	const path     = location.pathname

	// The above code (server-side `initialize()` method call) is not included
	// in this `try/catch` block because:
	//
	//  * `parameters` are used inside `.error()`
	//
	//  * even if an error was caught inside `initialize()`
	//    and a redirection was performed, say, to an `/error` page
	//    then it would fail again because `initialize()` would get called again,
	//    so wrapping `initialize()` with `try/catch` wouldn't help anyway.
	//
	try
	{
		const initialize_time = initialize_timer()

		// Internationalization

		let locale
		let messages
		let messagesJSON

		if (localize)
		{
			// `localize()` should normally be a synchronous function.
			// It could be asynchronous though for cases when it's taking
			// messages not from a JSON file but rather from an
			// "admin" user editable database.
			// If the rountrip time (ping) from the rendering service
			// to the database is small enough then it theoretically
			// won't introduce any major page rendering latency
			// (the database will surely cache such a hot query).
			// On the other hand, if a developer fights for each millisecond
			// then `localize()` should just return `messages` from memory.

			let result = localize(parameters)

			// If `localize()` returned a `Promise` then wait for it
			if (typeof result.then === 'function')
			{
				result = await result
			}

			locale   = result.locale
			messages = result.messages

			// A tiny optimization to avoid calculating
			// `JSON.stringify(messages)` for each rendered page:
			// `localize()` can return a cached `messagesJSON` string
			// instead of `messages` JSON object
			// to further reduce internationalization-induced latency
			// by an extra millisecond or so (benchmark if interested)
			// by not stringifying `messages` JSON object for each page rendered.
			messagesJSON = result.messagesJSON || JSON.stringify(messages)
		}

		// Render the web page
		const result = await render_page
		({
			...parameters,
			disable_server_side_rendering: render === false,
			history,
			routes,
			before_render: beforeRender,

			create_page_element: (child_element, props) =>
			{
				if (localize)
				{
					props.locale   = locale
					props.messages = messages
				}

				return React.createElement(wrapper, props, child_element)
			},

			render_webpage(content)
			{
				// Render page content
				content = render === false ? normalize_markup(loading) : (content && ReactDOM.renderToString(content))

				// `html` modifiers

				let { head } = html
				// camelCase support for those who prefer it
				let body_start = html.body_start || html.bodyStart
				let body_end   = html.body_end   || html.bodyEnd

				// Normalize `html` parameters
				head       = normalize_markup(typeof head       === 'function' ? head      (path, parameters) : head)
				body_start = normalize_markup(typeof body_start === 'function' ? body_start(path, parameters) : body_start)
				body_end   = normalize_markup(typeof body_end   === 'function' ? body_end  (path, parameters) : body_end)

				// Normalize assets
				assets = typeof assets === 'function' ? assets(path, parameters) : assets

				// Sanity check
				if (!assets.entries)
				{
					throw new Error(`"assets.entries" array parameter is required as of version 10.1.0. E.g. "{ ... entries: ['main'] ... }"`)
				}

				// Render the HTML
				return Html
				({
					...parameters,
					extension_javascript: typeof extension_javascript === 'function' ? extension_javascript() : extension_javascript,
					assets,
					locale,
					locale_messages_json: messagesJSON,
					head,
					body_start,
					body_end,
					protected_cookie_value,
					content
				})
			}
		})

		if (result.time)
		{
			result.time.initialize = initialize_time
		}

		return normalize_result(result)
	}
	catch (error)
	{
		// Redirection is sometimes done via an Error on server side.
		// (e.g. it can happen in `react-router`'s `onEnter()` during `match()`)
		if (error._redirect)
		{
			return normalize_result({ redirect: error._redirect })
		}

		if (error_handler)
		{
			const result = {}

			const error_handler_parameters =
			{
				path,
				url      : location_url(location),
				redirect : (to) =>
				{
					// Only the first redirect takes effect on the server side
					if (!result.redirect)
					{
						result.redirect = parse_location(to)
					}
				},
				server   : true
			}

			// Special case for Redux
			if (parameters.store)
			{
				error_handler_parameters.dispatch = redirecting_dispatch(parameters.store.dispatch, error_handler_parameters.redirect)
				error_handler_parameters.getState = parameters.store.getState
			}

			error_handler(error, error_handler_parameters)

			// Either redirects or throws the error
			if (result.redirect)
			{
				return normalize_result(result)
			}
		}

		throw error
	}
}

// Converts React.Elements to Strings
function normalize_markup(anything)
{
	if (!anything)
	{
		return ''
	}

	if (typeof anything === 'function')
	{
		return anything
	}

	if (typeof anything === 'string')
	{
		return anything
	}

	if (Array.isArray(anything))
	{
		return anything.map(normalize_markup).join('')
	}

	return ReactDOM.renderToString(anything)
}

// A special flavour of `dispatch` which `throw`s for redirects on the server side.
function redirecting_dispatch(dispatch, redirect)
{
	return (event) =>
	{
		switch (event.type)
		{
			// In case of navigation from @preload()
			case Preload:
				// `throw`s a special `Error` on server side
				return redirect(event.location)

			default:
				// Proceed with the original
				return dispatch(event)
		}
	}
}

function _normalize_result(result, afterwards, settings)
{
	// Stringify `redirect` location
	if (result.redirect)
	{
		// Prepend `basename` to relative URLs for server-side redirect.
		result.redirect = location_url(result.redirect, { basename: settings.history.options.basename })
	}

	// Add `afterwards`
	result.afterwards = afterwards

	return result
}<|endoftext|>


<commit_before>// produces wrong line numbers:
// import 'source-map-support/register'

import React from 'react'

import fs from 'fs'

import Html from './html'
import Http_client from '../http client'

import { render_on_server as redux_render }        from '../redux/render'
import { render_on_server as react_router_render } from '../react-router/render'

import create_store from '../redux/store'
import set_up_http_client from '../redux/http client'

// isomorphic (universal) rendering (middleware).
// will be used in web_application.use(...)
export default async function({ preload, localize, assets, application, request, disable_server_side_rendering, html }, common)
{
	const
	{
		get_reducer,
		redux_middleware,
		on_store_created,
		on_preload_error,
		create_routes,
		wrapper
	}
	= common

	let
	{
		head,
		body,
		body_start,
		body_end,
		style
	}
	= html

	// In development mode Redux DevTools are activated, for example
	const development = process.env.NODE_ENV !== 'production'

	// Trims a question mark in the end (just in case)
	const url = request.url.replace(/\?$/, '')

	// Isomorphic http client (with cookie support)
	const http_client = new Http_client
	({
		host          : application.host,
		port          : application.port,
		secure        : application.secure,
		clone_request : request
	})

	// initial Flux store data (if using Flux)
	let store_data = {}

	// supports custom preloading before the page is rendered
	// (for example to authenticate the user and retrieve user selected language)
	if (preload)
	{
		store_data = (await preload(http_client, { request })) || store_data
	}

	// create Redux store
	let store
	if (get_reducer)
	{
		store = create_store(get_reducer,
		{
			development,
			server: true,
			create_routes,
			data: store_data,
			middleware: redux_middleware,
			on_store_created,
			on_preload_error,
			http_client
		})
	}

	// Customization of `http` utility
	// which can be used inside Redux action creators
	set_up_http_client(http_client, { store, on_before_send: common.http_request })

	// Internationalization

	let locale
	let messages

	if (localize)
	{
		const result = await localize(store)

		locale   = result.locale
		messages = result.messages
	}

	// If Redux is being used, then render for Redux.
	// Else render for pure React.
	const render = store ? redux_render : react_router_render

	// Render the web page
	return await render
	({
		disable_server_side_rendering,

		url,

		create_page_element: (child_element, props) =>
		{
			if (localize)
			{
				props.locale   = locale
				props.messages = messages
			}

			return React.createElement(wrapper, props, child_element)
		},

		render_webpage_as_react_element: content =>
		{
			assets = assets(url)
			if (assets.styles)
			{
				assets.style = assets.styles
			}

			if (head)
			{
				head = head(url)
			}

			if (body_start)
			{
				body_start = body_start(url)
			}

			if (body_end)
			{
				body_end = body_end(url)
			}

			const markup =
			(
				<Html
					development={development}
					assets={assets}
					locale={locale}
					head={head}
					body={body}
					body_start={body_start}
					body_end={body_end}
					style={style}
					store={store}>

					{content}
				</Html>
			)

			return markup
		},

		store,

		// create_routes is only used for bare React-router rendering
		create_routes: store ? undefined : create_routes
	})
}<commit_msg>`html.style` deprecation warning<commit_after>// produces wrong line numbers:
// import 'source-map-support/register'

import React from 'react'

import fs from 'fs'

import Html from './html'
import Http_client from '../http client'

import { render_on_server as redux_render }        from '../redux/render'
import { render_on_server as react_router_render } from '../react-router/render'

import create_store from '../redux/store'
import set_up_http_client from '../redux/http client'

// isomorphic (universal) rendering (middleware).
// will be used in web_application.use(...)
export default async function({ preload, localize, assets, application, request, disable_server_side_rendering, html }, common)
{
	const
	{
		get_reducer,
		redux_middleware,
		on_store_created,
		on_preload_error,
		create_routes,
		wrapper
	}
	= common

	let
	{
		head,
		body,
		body_start,
		body_end,
		style
	}
	= html

	if (style)
	{
		console.warn(`"html.style" parameter is deprecated and will be removed in the next major release. Use "html.head" instead: if (development) return [<style dangerouslySetInnerHTML={{ __html: style }} charSet="UTF-8"/>, ...]`)
	}

	// In development mode Redux DevTools are activated, for example
	const development = process.env.NODE_ENV !== 'production'

	// Trims a question mark in the end (just in case)
	const url = request.url.replace(/\?$/, '')

	// Isomorphic http client (with cookie support)
	const http_client = new Http_client
	({
		host          : application.host,
		port          : application.port,
		secure        : application.secure,
		clone_request : request
	})

	// initial Flux store data (if using Flux)
	let store_data = {}

	// supports custom preloading before the page is rendered
	// (for example to authenticate the user and retrieve user selected language)
	if (preload)
	{
		store_data = (await preload(http_client, { request })) || store_data
	}

	// create Redux store
	let store
	if (get_reducer)
	{
		store = create_store(get_reducer,
		{
			development,
			server: true,
			create_routes,
			data: store_data,
			middleware: redux_middleware,
			on_store_created,
			on_preload_error,
			http_client
		})
	}

	// Customization of `http` utility
	// which can be used inside Redux action creators
	set_up_http_client(http_client, { store, on_before_send: common.http_request })

	// Internationalization

	let locale
	let messages

	if (localize)
	{
		const result = await localize(store)

		locale   = result.locale
		messages = result.messages
	}

	// If Redux is being used, then render for Redux.
	// Else render for pure React.
	const render = store ? redux_render : react_router_render

	// Render the web page
	return await render
	({
		disable_server_side_rendering,

		url,

		create_page_element: (child_element, props) =>
		{
			if (localize)
			{
				props.locale   = locale
				props.messages = messages
			}

			return React.createElement(wrapper, props, child_element)
		},

		render_webpage_as_react_element: content =>
		{
			assets = assets(url)
			if (assets.styles)
			{
				assets.style = assets.styles
			}

			if (head)
			{
				head = head(url)
			}

			if (body_start)
			{
				body_start = body_start(url)
			}

			if (body_end)
			{
				body_end = body_end(url)
			}

			const markup =
			(
				<Html
					development={development}
					assets={assets}
					locale={locale}
					head={head}
					body={body}
					body_start={body_start}
					body_end={body_end}
					style={style}
					store={store}>

					{content}
				</Html>
			)

			return markup
		},

		store,

		// create_routes is only used for bare React-router rendering
		create_routes: store ? undefined : create_routes
	})
}<|endoftext|>


<commit_before>(function () {

    'use strict';
    var mainModule = angular.module('ui.sortable');

    /**
     * Controller for sortableItemHandle
     * @param $scope
     */
    mainModule.controller('sortableItemHandleController', ['$scope', function ($scope) {

        $scope.initHandle = function (element) {
            element.attr('sortable-elment-type', 'handle');
        };

    }]);

    mainModule.directive('sortableItemHandle', ['sortableConfig', '$helper', '$window', '$document',
        function (sortableConfig, $helper, $window, $document) {
            return {
                require: ['^sortableItem'],
                restrict: 'A',
                controller: 'sortableItemHandleController',
                link: function (scope, element) {

                    var clickedElm, sourceItem, sourceIndex, dragItem, placeElm,
                        hiddenPlaceElm, dragItemElm, pos, dragElm, firstMoving, clickedElmDragged, targetItem, targetBefore,
                        destIndex, targetScope, sameParent;
                    var elements; // As a parameter for callbacks
                    var config = {};

                    angular.extend(config, sortableConfig);
                    scope.initHandle(element);

                    if (config.handleClass) {
                        element.addClass(config.handleClass);
                    }

                    var hasTouch = 'ontouchstart' in window;

                    var dragStartEvent = function (event) {

                        clickedElm = angular.element(event.target);
                        var nodrag = function (targetElm) {
                            return (typeof targetElm.attr('nodrag')) !== 'undefined'
                                || (typeof targetElm.attr('data-nodrag')) !== 'undefined';
                        };

                        var target = clickedElm;
                        while(target && target[0] && target[0] != element
                            && !target.hasClass(config.itemClass)) {
                            if (nodrag(target)) {
                                return;
                            }
                            target = target.parent();
                        }

                        sourceItem = clickedElm.scope().itemData();
                        event.preventDefault();

                        firstMoving = true;
                        sourceIndex = scope.$index;
                        dragItem = {
                            index: scope.$index,
                            scope: scope,

                            reset: function (index, scope, dragItemScope) {
                                sameParent = (scope.sortableElement == dragItemScope.sortableElement);
                                if (sameParent && sourceIndex < index) {
                                    index--;
                                }
                                destIndex = index;
                                this.index = index;
                                this.scope = scope;
                                this.items = $helper.copyArray(scope.items);
                                var i = this.items.indexOf(dragItemScope);
                                if (i > -1) {
                                    this.items.splice(i, 1);
                                }

                                this.items.splice(index, 0, dragItemScope);
                            }
                        };

                        var tagName = scope.sortableItemElement.prop('tagName');

                        placeElm = angular.element($window.document.createElement(tagName))
                            .addClass(config.placeHolderClass);

                        hiddenPlaceElm = angular.element($window.document.createElement(tagName));

                        dragItemElm = scope.sortableItemElement;
                        pos = $helper.positionStarted(event, dragItemElm);
                        placeElm.css('height', $helper.height(dragItemElm) + 'px');
                        dragElm = angular.element($window.document.createElement(scope.sortableElement.prop('tagName')))
                            .addClass(scope.sortableElement.attr('class')).addClass(config.dragClass);
                        dragElm.css('width', $helper.width(dragItemElm) + 'px');

                        dragItemElm.after(placeElm);
                        dragItemElm.after(hiddenPlaceElm);
                        dragItemElm[0].parentNode.removeChild(dragItemElm[0]);
                        dragElm.append(dragItemElm);

                        // stop move when the menu item is dragged outside the body element
                        angular.element($window.document.body).bind('mouseleave', dragEndEvent);

                        $document.find('body').append(dragElm);

                        dragElm.css({
                            'left': event.pageX - pos.offsetX + 'px',
                            'top': event.pageY - pos.offsetY + 'px'
                        });

                        elements = {
                            placeholder: placeElm,
                            dragging: dragElm
                        };

                        scope.callbacks.start(scope, sourceItem, elements);

                        if (hasTouch) {
                            angular.element($document).bind('touchmove', dragMoveEvent);
                            angular.element($document).bind('touchend', dragEndEvent);
                            angular.element($document).bind('touchcancel', dragEndEvent);
                        } else {
                            angular.element($document).bind('mousemove', dragMoveEvent);
                            angular.element($document).bind('mouseup', dragEndEvent);
                        }
                    };

                    var dragMoveEvent = function (event) {

                        var currentAccept;
                        clickedElmDragged = true;

                        if (dragElm) {
                            event.preventDefault();

                            dragElm.css({
                                'left': event.pageX - pos.offsetX + 'px',
                                'top': event.pageY - pos.offsetY + 'px'
                            });

                            $helper.positionMoved(event, pos, firstMoving);

                            if (firstMoving) {
                                firstMoving = false;
                                return;
                            }

                            var targetX = event.pageX - $window.document.documentElement.scrollLeft;
                            var targetY = event.pageY - (window.pageYOffset || $window.document.documentElement.scrollTop);

                            // Select the drag target. Because IE does not support CSS 'pointer-events: none', it will always
                            // pick the drag element itself as the target. To prevent this, we hide the drag element while
                            // selecting the target.
                            if (angular.isFunction(dragElm.hide)) {
                                dragElm.hide();
                            }

                            // when using elementFromPoint() inside an iframe, you have to call
                            // elementFromPoint() twice to make sure IE8 returns the correct value
                            $window.document.elementFromPoint(targetX, targetY);

                            var targetElm = angular.element($window.document.elementFromPoint(targetX, targetY));
                            if (angular.isFunction(dragElm.show)) {
                                dragElm.show();
                            }

                            if (targetElm.attr('sortable-elment-type') != 'item' && targetElm.attr('sortable-elment-type') != 'handle') {
                                return;
                            }

                            targetItem = targetElm.scope();
                            targetElm = targetItem.sortableItemElement;

                            // move vertical
                            if (!pos.dirAx) {
                                sameParent = false;
                                // check it's new position
                                var targetOffset = $helper.offset(targetElm);
                                if ($helper.offset(placeElm).top > targetOffset.top) { // the move direction is up?
                                    targetBefore = $helper.offset(dragElm).top < targetOffset.top + $helper.height(targetElm) / 2;
                                } else {
                                    targetBefore = event.pageY < targetOffset.top;
                                }
                                if (targetBefore) {

                                    currentAccept = targetItem.accept(scope, targetItem.parentScope());
                                    if (currentAccept) {
                                        targetElm[0].parentNode.insertBefore(placeElm[0], targetElm[0]);
                                        destIndex = targetItem.$index;
                                        targetScope = targetItem.parentScope();
                                        dragItem.reset(destIndex, targetScope, scope);
                                    }
                                } else {
                                    currentAccept = targetItem.accept(scope, targetItem.parentScope());
                                    if (currentAccept) {
                                        targetElm.after(placeElm);
                                        destIndex = targetItem.$index + 1;
                                        targetScope = targetItem.parentScope();
                                        dragItem.reset(destIndex, targetScope, scope);
                                    }
                                }
                            }

                            scope.callbacks.move(scope, sourceItem, elements);
                        }

                    };

                    var dragEndEvent = function (event) {

                        if (dragElm) {
                            if (event) {
                                event.preventDefault();
                            }
                            // roll back elements changed
                            dragItemElm[0].parentNode.removeChild(dragItemElm[0]);
                            hiddenPlaceElm.replaceWith(dragItemElm);
                            placeElm.remove();

                            dragElm.remove();
                            dragElm = null;

                            scope.callbacks.stop(scope, sourceItem, elements);
                            // update model data
                            if (targetScope && !(sameParent && sourceIndex == destIndex)) {
                                var source = scope.removeItem();
                                targetScope.insertSortableItem(destIndex, source, scope);

                                if (sameParent) {
                                    scope.callbacks.orderChanged(scope.sortableElement.scope(), source);
                                } else {
                                    scope.callbacks.itemMoved(scope.sortableElement.scope(), source, targetScope);
                                }
                            }
                        }
                        if (hasTouch) {
                            angular.element($document).unbind('touchend', dragEndEvent);
                            angular.element($document).unbind('touchcancel', dragEndEvent);
                            angular.element($document).unbind('touchmove', dragMoveEvent);
                        }
                        else {
                            angular.element($document).unbind('mouseup', dragEndEvent);
                            angular.element($document).unbind('mousemove', dragMoveEvent);
                            angular.element($window.document.body).unbind('mouseleave', dragEndEvent);
                        }
                    };

                    if (hasTouch) {
                        element.bind('touchstart', dragStartEvent);
                    } else {
                        element.bind('mousedown', dragStartEvent);
                    }
                }
            };
        }]);
})();<commit_msg>refactor code.<commit_after>(function () {

    'use strict';
    var mainModule = angular.module('ui.sortable');

    /**
     * Controller for sortableItemHandle
     * @param $scope
     */
    mainModule.controller('sortableItemHandleController', ['$scope', function ($scope) {

        $scope.initHandle = function (element) {
            element.attr('sortable-elment-type', 'handle');
        };

    }]);

    mainModule.directive('sortableItemHandle', ['sortableConfig', '$helper', '$window', '$document',
        function (sortableConfig, $helper, $window, $document) {
            return {
                require: ['^sortableItem'],
                restrict: 'A',
                controller: 'sortableItemHandleController',
                link: function (scope, element) {

                    var clickedElm, sourceItem, sourceIndex, dragItem, placeElm,
                        hiddenPlaceElm, dragItemElm, pos, dragElm, firstMoving, clickedElmDragged, targetItem, targetBefore,
                        destIndex, targetScope, sameParent;
                    var elements; // As a parameter for callbacks
                    var config = {};

                    angular.extend(config, sortableConfig);
                    scope.initHandle(element);

                    if (config.handleClass) {
                        element.addClass(config.handleClass);
                    }

                    var hasTouch = 'ontouchstart' in window;

                    var dragStartEvent = function (event) {

                        clickedElm = angular.element(event.target);
                        var nodrag = function (targetElm) {
                            return (typeof targetElm.attr('nodrag')) !== 'undefined'
                                || (typeof targetElm.attr('data-nodrag')) !== 'undefined';
                        };

                        var target = clickedElm;
                        while(target && target[0] && target[0] != element
                            && !target.hasClass(config.itemClass)) {
                            if (nodrag(target)) {
                                return;
                            }
                            target = target.parent();
                        }

                        sourceItem = clickedElm.scope().itemData();
                        event.preventDefault();

                        firstMoving = true;
                        sourceIndex = scope.$index;
                        dragItem = {
                            index: scope.$index,
                            scope: scope,

                            reset: function (index, scope, dragItemScope) {
                                sameParent = (scope.sortableElement == dragItemScope.sortableElement);
                                if (sameParent && sourceIndex < index) {
                                    index--;
                                }
                                destIndex = index;
                                this.index = index;
                                this.scope = scope;
                                this.items = $helper.copyArray(scope.items);
                                var i = this.items.indexOf(dragItemScope);
                                if (i > -1) {
                                    this.items.splice(i, 1);
                                }

                                this.items.splice(index, 0, dragItemScope);
                            }
                        };

                        var tagName = scope.sortableItemElement.prop('tagName');

                        placeElm = angular.element($window.document.createElement(tagName))
                            .addClass(config.placeHolderClass);

                        hiddenPlaceElm = angular.element($window.document.createElement(tagName));

                        dragItemElm = scope.sortableItemElement;
                        pos = $helper.positionStarted(event, dragItemElm);
                        placeElm.css('height', $helper.height(dragItemElm) + 'px');
                        dragElm = angular.element($window.document.createElement(scope.sortableElement.prop('tagName')))
                            .addClass(scope.sortableElement.attr('class')).addClass(config.dragClass);
                        dragElm.css('width', $helper.width(dragItemElm) + 'px');

                        dragItemElm.after(placeElm);
                        dragItemElm.after(hiddenPlaceElm);
                        dragItemElm[0].parentNode.removeChild(dragItemElm[0]);
                        dragElm.append(dragItemElm);

                        // stop move when the menu item is dragged outside the body element
                        angular.element($window.document.body).bind('mouseleave', dragEndEvent);

                        $document.find('body').append(dragElm);

                        dragElm.css({
                            'left': event.pageX - pos.offsetX + 'px',
                            'top': event.pageY - pos.offsetY + 'px'
                        });

                        elements = {
                            placeholder: placeElm,
                            dragging: dragElm
                        };

                        scope.callbacks.start(scope, sourceItem, elements);

                        if (hasTouch) {
                            angular.element($document).bind('touchmove', dragMoveEvent);
                            angular.element($document).bind('touchend', dragEndEvent);
                            angular.element($document).bind('touchcancel', dragEndEvent);
                        } else {
                            angular.element($document).bind('mousemove', dragMoveEvent);
                            angular.element($document).bind('mouseup', dragEndEvent);
                        }
                    };

                    var dragMoveEvent = function (event) {

                        var currentAccept;
                        clickedElmDragged = true;

                        if (dragElm) {
                            event.preventDefault();

                            dragElm.css({
                                'left': event.pageX - pos.offsetX + 'px',
                                'top': event.pageY - pos.offsetY + 'px'
                            });

                            $helper.positionMoved(event, pos, firstMoving);

                            if (firstMoving) {
                                firstMoving = false;
                                return;
                            }

                            var targetX = event.pageX - $window.document.documentElement.scrollLeft;
                            var targetY = event.pageY - (window.pageYOffset || $window.document.documentElement.scrollTop);

                            // Select the drag target. Because IE does not support CSS 'pointer-events: none', it will always
                            // pick the drag element itself as the target. To prevent this, we hide the drag element while
                            // selecting the target.
                            // when using elementFromPoint() inside an iframe, you have to call
                            // elementFromPoint() twice to make sure IE8 returns the correct value
                            $window.document.elementFromPoint(targetX, targetY);

                            var targetElm = angular.element($window.document.elementFromPoint(targetX, targetY));

                            if (targetElm.attr('sortable-elment-type') != 'item' && targetElm.attr('sortable-elment-type') != 'handle') {
                                return;
                            }

                            targetItem = targetElm.scope();
                            targetElm = targetItem.sortableItemElement;

                            // move vertical
                            if (!pos.dirAx) {
                                sameParent = false;
                                // check it's new position
                                var targetOffset = $helper.offset(targetElm);
                                if ($helper.offset(placeElm).top > targetOffset.top) { // the move direction is up?
                                    targetBefore = $helper.offset(dragElm).top < targetOffset.top + $helper.height(targetElm) / 2;
                                } else {
                                    targetBefore = event.pageY < targetOffset.top;
                                }
                                if (targetBefore) {

                                    currentAccept = targetItem.accept(scope, targetItem.parentScope());
                                    if (currentAccept) {
                                        targetElm[0].parentNode.insertBefore(placeElm[0], targetElm[0]);
                                        destIndex = targetItem.$index;
                                        targetScope = targetItem.parentScope();
                                        dragItem.reset(destIndex, targetScope, scope);
                                    }
                                } else {
                                    currentAccept = targetItem.accept(scope, targetItem.parentScope());
                                    if (currentAccept) {
                                        targetElm.after(placeElm);
                                        destIndex = targetItem.$index + 1;
                                        targetScope = targetItem.parentScope();
                                        dragItem.reset(destIndex, targetScope, scope);
                                    }
                                }
                            }

                            scope.callbacks.move(scope, sourceItem, elements);
                        }

                    };

                    var dragEndEvent = function (event) {

                        if (dragElm) {
                            if (event) {
                                event.preventDefault();
                            }
                            // roll back elements changed
                            dragItemElm[0].parentNode.removeChild(dragItemElm[0]);
                            hiddenPlaceElm.replaceWith(dragItemElm);
                            placeElm.remove();

                            dragElm.remove();
                            dragElm = null;

                            scope.callbacks.stop(scope, sourceItem, elements);
                            // update model data
                            if (targetScope && !(sameParent && sourceIndex == destIndex)) {
                                var source = scope.removeItem();
                                targetScope.insertSortableItem(destIndex, source, scope);

                                if (sameParent) {
                                    scope.callbacks.orderChanged(scope.sortableElement.scope(), source);
                                } else {
                                    scope.callbacks.itemMoved(scope.sortableElement.scope(), source, targetScope);
                                }
                            }
                        }
                        if (hasTouch) {
                            angular.element($document).unbind('touchend', dragEndEvent);
                            angular.element($document).unbind('touchcancel', dragEndEvent);
                            angular.element($document).unbind('touchmove', dragMoveEvent);
                        }
                        else {
                            angular.element($document).unbind('mouseup', dragEndEvent);
                            angular.element($document).unbind('mousemove', dragMoveEvent);
                            angular.element($window.document.body).unbind('mouseleave', dragEndEvent);
                        }
                    };

                    if (hasTouch) {
                        element.bind('touchstart', dragStartEvent);
                    } else {
                        element.bind('mousedown', dragStartEvent);
                    }
                }
            };
        }]);
})();<|endoftext|>


<commit_before>(function(global) {
  'use strict';

  var script = document.currentScript || (function(scripts) {
    return scripts[scripts.length - 1];
  })(document.getElementsByTagName('script'));

  var hasUI = true;
  var params = script.src.split('?')[1].split('&');
  params.forEach(function(p) {
    var parts = p.split('=');
    if (parts.length > 1 && parts[0] === 'ui') {
      hasUI = parts[1] !== 'false';
    }
  });

  var iframe = document.createElement('iframe');
  iframe.setAttribute('allowfullscreen', true);
  iframe.setAttribute('allowtransparency', true);
  iframe.src = script.src.replace(/embed\.js/, 'embed.html') + '&';
  iframe.width = hasUI ? 482 : 480;
  iframe.height = hasUI ? 393 : 360;
  iframe.style.border = '0';
  iframe.className = 'phosphorus';

  script.parentNode.replaceChild(iframe, script);

}(this));
<commit_msg>Removed trailing ampersand<commit_after>(function(global) {
  'use strict';

  var script = document.currentScript || (function(scripts) {
    return scripts[scripts.length - 1];
  })(document.getElementsByTagName('script'));

  var hasUI = true;
  var params = script.src.split('?')[1].split('&');
  params.forEach(function(p) {
    var parts = p.split('=');
    if (parts.length > 1 && parts[0] === 'ui') {
      hasUI = parts[1] !== 'false';
    }
  });

  var iframe = document.createElement('iframe');
  iframe.setAttribute('allowfullscreen', true);
  iframe.setAttribute('allowtransparency', true);
  iframe.src = script.src.replace(/embed\.js/, 'embed.html');
  iframe.width = hasUI ? 482 : 480;
  iframe.height = hasUI ? 393 : 360;
  iframe.style.border = '0';
  iframe.className = 'phosphorus';

  script.parentNode.replaceChild(iframe, script);

}(this));
<|endoftext|>


<commit_before>// basic T1 cracker

function(addy){return addy}
<commit_msg>Update t1.js<commit_after>// basic T1 cracker

// It should look like this: yourname.scriptname {target:#s.your.target} note that we don't use quotes.
// based on: http://pastebin.com/SKyDLc34

var ez21_answers = ["open", "unlock", "release"]

function(addy){return addy}
<|endoftext|>