<commit_before>// ==UserScript==
// @name                OLog
// @namespace           http://www.olog.com/
// @description         OLog Userscript
// @downloadURL         https://github.com/skiwi2/OLog-Userscript/raw/master/olog.user.js
// @updateURL           https://github.com/skiwi2/OLog-Userscript/raw/master/olog.user.js
// @version             0.3pre
// @include             http://s*-*.ogame.gameforge.com/game/*
// @grant               GM_xmlhttpRequest
// @grant               GM_getValue
// @grant               GM_setValue
// ==/UserScript==

"use strict";

var oLogInstanceUrl = getSetting("settings.ologinstanceurl", "http://localhost:8080/");

var menuTable = document.getElementById("menuTable");

menuTable.insertAdjacentHTML("beforeend", '' +
    '
\n' +
    '    \n' +
    '        OLog Settings\n' +
    '    \n' +
    '
\n');

var oLogMenuLi = document.getElementById("ologMenuLi");
oLogMenuLi.addEventListener("focus", function(c) {
    if (b(c.target).closest(".dropdown").length == 0) {
        b(".currentlySelected a").removeClass("hover");
        b(".currentlySelected").removeClass("focus");
    }
});

var oLogMenuAnchor = document.getElementById("ologMenuAnchor");
oLogMenuAnchor.addEventListener("click", function() {
    showOLogSettings();
});

if (window.location.hash === "#ologsettings") {
    showOLogSettings();
}

function showOLogSettings() {
    var menuTableLiList = menuTable.querySelectorAll("li");
    for (var i = 0; i < menuTableLiList.length; i++) {
        menuTableLiList[i].querySelector(".menubutton").classList.remove("selected");
    }

    oLogMenuAnchor.classList.add("selected");

    var contentWrapperDiv = document.getElementById("contentWrapper");
    while (contentWrapperDiv.firstChild) {
        contentWrapperDiv.removeChild(contentWrapperDiv.firstChild);
    }

    contentWrapperDiv.insertAdjacentHTML("beforeend", '' +
        '
\n' +
        '
\n' +
        '
\n' +
        '
\n' +
        '
OLog Settings
\n' +
        '
\n' +
        '
\n' +
        '

\n' +
        '
\n' +
        '
\n' +
        '
\n' +
        '
\n' +
        '                                Server Group	\n' +
        '                                ' + getWindowVariable("constants.language") + '	\n' +
        '
\n' +
        '
\n' +
        '                                Universe ID	\n' +
        '                                ' + getWindowVariable("constants.name") + '	\n' +
        '
\n' +
        '
\n' +
        '                                Player ID	\n' +
        '                                ' + getWindowVariable("playerId") + '	\n' +
        '
\n' +
        '
\n' +
        '                                Player Name	\n' +
        '                                ' + getWindowVariable("playerName") + '	\n' +
        '
\n' +
        '
\n' +
        '                                Userscript Version	\n' +
        '                                ' + GM_info.script.version + '	\n' +
        '
\n' +
        '
\n' +
        '
\n' +
        '
\n' +
        '
\n' +
        '
\n' +
        '
\n' +
        '

\n' +
        '

\n' +
        '
\n' +
        '
\n' +
        '
Your settings
\n' +
        '
\n' +
        '
\n' +
        '
\n' +
        '                OLog Instance URL:\n' +
        '
\n' +
        '                    <input class="textinput w200" type="text" size="30" value="' + oLogInstanceUrl + '" id="ologInstanceUrlInput" />\n' +
        '
\n' +
        '
\n' +
        '
\n' +
        '                <input class="btn_blue" type="submit" value="Save settings" id="ologSaveSettingsInput" />\n' +
        '
\n' +
        '

\n' +
        '
\n' +
        '
\n' +
        '
\n' +
        '
\n' +
        '');

    var oLogInstanceUrlInput = document.getElementById("ologInstanceUrlInput");

    var oLogSaveSettingsInput = document.getElementById("ologSaveSettingsInput");
    oLogSaveSettingsInput.addEventListener("click", function() {
        saveSetting("settings.ologinstanceurl", oLogInstanceUrlInput.value);
        showSuccessMessage("Settings have been saved.");
    });
}

var page = getWindowVariable("currentPage");

if (page === "messages") {
    var observer = new MutationObserver(function(mutations) {
        mutations.forEach(function(mutation) {
            for(var i = 0; i < mutation.addedNodes.length; i++) {
                var node = mutation.addedNodes[i];
                if (node.localName === "ul" && node.classList.contains("tab_inner")) {
                    //send all messages at once such that all SR keys can be sent at once to the server
                    processMessageNodes(node.querySelectorAll(".msg"));
                }
            }
        });
    });

    observer.observe(document, { childList: true, subtree: true });
}
else if (page === "research") {
    var itemBoxDivs = document.querySelectorAll(".item_box");
    processResearchNodes(itemBoxDivs);
}

var planetListDiv = document.getElementById("planetList");
if (planetListDiv !== null) {
    processPlanetNodes(planetListDiv.children);
}

function processMessageNodes(nodes) {
    var reportKeys = {
        sr: [],     //spy report
        cr: [],     //combat report
        rr: [],     //recycle report
        mr: []      //missile report
    };

    for (var i = 0; i < nodes.length; i++) {
        var node = nodes[i];
        var apiElement = node.querySelector(".icon_apikey");
        if (apiElement !== null) {
            var key = apiElement.parentNode.href.replace(/.*?:\/\//g, "");
            var type = key.substring(0, 2);
            if (reportKeys.hasOwnProperty(type)) {
                reportKeys[type].push(key);
            }
        }
    }

    console.log(reportKeys);

    postData({
        endpoint: "keys",
        data: {
            reportKeys: reportKeys
        }
    });
}

function processPlanetNodes(nodes) {
    var planets = [];

    for (var i = 0; i < nodes.length; i++) {
        var planetDiv = nodes[i];
        var planetId = planetDiv.id.replace("planet-", "");
        var planetName = planetDiv.querySelector(".planet-name").innerHTML;
        var planetCoordsRaw = planetDiv.querySelector(".planet-koords").innerHTML;
        var planetCoordsList = planetCoordsRaw.slice(1, -1).split(":");
        planets.push({
            id: planetId,
            name: planetName,
            galaxy: planetCoordsList[0],
            solarSystem: planetCoordsList[1],
            position: planetCoordsList[2]
        });
    }

    var planetsString = JSON.stringify(planets);
    if (getSetting("planets_cache", "") !== planetsString) {
        postData({
            endpoint: "planets",
            data: {
                planets: planets
            }
        });
        saveSetting("planets_cache", planetsString);
    }
}

function processResearchNodes(nodes) {
    var researches = [];

    for (var i = 0; i < nodes.length; i++) {
        var node = nodes[i];
        var detailButtonElement = node.querySelector(".detail_button");
        if (detailButtonElement !== null) {
            var researchId = detailButtonElement.getAttribute("ref");
            var cloneLevelNode = detailButtonElement.querySelector(".level").cloneNode(true);
            var children = [].slice.call(cloneLevelNode.children);

            for (var j = 0; j < children.length; j++) {
                var child = children[j];
                if (child.className === "textlabel" || child.className === "undermark") {
                    cloneLevelNode.removeChild(child);
                }
            }
            var researchLevel = cloneLevelNode.innerHTML.trim();

            researches.push({
                id: researchId,
                level: researchLevel
            });
        }
    }

    var researchesString = JSON.stringify(researches);
    if (getSetting("researches_cache", "") !== researchesString) {
        postData({
            endpoint: "researches",
            data: {
                researches: researches
            }
        });
        saveSetting("researches_cache", researchesString);
    }
}

function postData(object) {
    addPlayerData(object.data);
    console.log(JSON.stringify(object.data));
    GM_xmlhttpRequest({
        method: "POST",
        url: oLogInstanceUrl + "api/userscript/" + object.endpoint,
        data: JSON.stringify(object.data),
        headers: {
            "Content-Type": "application/json"
        },
        onload: function(response) {
            console.log("load");
        },
        onerror: function(response) {
            console.log("error");
        }
    });
}

function addPlayerData(data) {
    data.serverGroup = getWindowVariable("constants.language");
    data.universe = getWindowVariable("constants.name");
    data.playerId = getWindowVariable("playerId");
    data.playerName = getWindowVariable("playerName");
}

/**
 * Returns a global variable.
 *
 * Needed because a @grant other than none puts the script
 * in a separate scope.
 *
 * @param {string} name The name of the global variable.
 */
function getWindowVariable(name) {
    return window.eval(name);
}

function showSuccessMessage(message) {
    getWindowVariable("fadeBox")(message, false);
}

function showErrorMessage(message) {
    getWindowVariable("fadeBox")(message, true);
}

function saveSetting(key, value) {
    var fullKey = getWindowVariable("constants.language") + ":" + getWindowVariable("constants.name") + ":" + getWindowVariable("playerId") + ":" + key;
    GM_setValue(fullKey, value);
}

function getSetting(key, defaultValue) {
    var fullKey = getWindowVariable("constants.language") + ":" + getWindowVariable("constants.name") + ":" + getWindowVariable("playerId") + ":" + key;
    return GM_getValue(fullKey, defaultValue);
}<commit_msg>Saving your settings now also resets the caches.<commit_after>// ==UserScript==
// @name                OLog
// @namespace           http://www.olog.com/
// @description         OLog Userscript
// @downloadURL         https://github.com/skiwi2/OLog-Userscript/raw/master/olog.user.js
// @updateURL           https://github.com/skiwi2/OLog-Userscript/raw/master/olog.user.js
// @version             0.3pre
// @include             http://s*-*.ogame.gameforge.com/game/*
// @grant               GM_xmlhttpRequest
// @grant               GM_getValue
// @grant               GM_setValue
// ==/UserScript==

"use strict";

var oLogInstanceUrl = getSetting("settings.ologinstanceurl", "http://localhost:8080/");

var menuTable = document.getElementById("menuTable");

menuTable.insertAdjacentHTML("beforeend", '' +
    '
\n' +
    '    \n' +
    '        OLog Settings\n' +
    '    \n' +
    '
\n');

var oLogMenuLi = document.getElementById("ologMenuLi");
oLogMenuLi.addEventListener("focus", function(c) {
    if (b(c.target).closest(".dropdown").length == 0) {
        b(".currentlySelected a").removeClass("hover");
        b(".currentlySelected").removeClass("focus");
    }
});

var oLogMenuAnchor = document.getElementById("ologMenuAnchor");
oLogMenuAnchor.addEventListener("click", function() {
    showOLogSettings();
});

if (window.location.hash === "#ologsettings") {
    showOLogSettings();
}

function showOLogSettings() {
    var menuTableLiList = menuTable.querySelectorAll("li");
    for (var i = 0; i < menuTableLiList.length; i++) {
        menuTableLiList[i].querySelector(".menubutton").classList.remove("selected");
    }

    oLogMenuAnchor.classList.add("selected");

    var contentWrapperDiv = document.getElementById("contentWrapper");
    while (contentWrapperDiv.firstChild) {
        contentWrapperDiv.removeChild(contentWrapperDiv.firstChild);
    }

    contentWrapperDiv.insertAdjacentHTML("beforeend", '' +
        '
\n' +
        '
\n' +
        '
\n' +
        '
\n' +
        '
OLog Settings
\n' +
        '
\n' +
        '
\n' +
        '

\n' +
        '
\n' +
        '
\n' +
        '
\n' +
        '
\n' +
        '                                Server Group	\n' +
        '                                ' + getWindowVariable("constants.language") + '	\n' +
        '
\n' +
        '
\n' +
        '                                Universe ID	\n' +
        '                                ' + getWindowVariable("constants.name") + '	\n' +
        '
\n' +
        '
\n' +
        '                                Player ID	\n' +
        '                                ' + getWindowVariable("playerId") + '	\n' +
        '
\n' +
        '
\n' +
        '                                Player Name	\n' +
        '                                ' + getWindowVariable("playerName") + '	\n' +
        '
\n' +
        '
\n' +
        '                                Userscript Version	\n' +
        '                                ' + GM_info.script.version + '	\n' +
        '
\n' +
        '
\n' +
        '
\n' +
        '
\n' +
        '
\n' +
        '
\n' +
        '
\n' +
        '

\n' +
        '

\n' +
        '
\n' +
        '
\n' +
        '
Your settings
\n' +
        '
\n' +
        '
\n' +
        '
\n' +
        '                OLog Instance URL:\n' +
        '
\n' +
        '                    <input class="textinput w200" type="text" size="30" value="' + oLogInstanceUrl + '" id="ologInstanceUrlInput" />\n' +
        '
\n' +
        '
\n' +
        '
\n' +
        '                <input class="btn_blue" type="submit" value="Save settings" id="ologSaveSettingsInput" />\n' +
        '
\n' +
        '

\n' +
        '
\n' +
        '
\n' +
        '
\n' +
        '
\n' +
        '');

    var oLogInstanceUrlInput = document.getElementById("ologInstanceUrlInput");

    var oLogSaveSettingsInput = document.getElementById("ologSaveSettingsInput");
    oLogSaveSettingsInput.addEventListener("click", function() {
        saveSetting("settings.ologinstanceurl", oLogInstanceUrlInput.value);
        saveSetting("planets_cache", "");
        saveSetting("researches_cache", "");
        showSuccessMessage("Settings have been saved.");
    });
}

var page = getWindowVariable("currentPage");

if (page === "messages") {
    var observer = new MutationObserver(function(mutations) {
        mutations.forEach(function(mutation) {
            for(var i = 0; i < mutation.addedNodes.length; i++) {
                var node = mutation.addedNodes[i];
                if (node.localName === "ul" && node.classList.contains("tab_inner")) {
                    //send all messages at once such that all SR keys can be sent at once to the server
                    processMessageNodes(node.querySelectorAll(".msg"));
                }
            }
        });
    });

    observer.observe(document, { childList: true, subtree: true });
}
else if (page === "research") {
    var itemBoxDivs = document.querySelectorAll(".item_box");
    processResearchNodes(itemBoxDivs);
}

var planetListDiv = document.getElementById("planetList");
if (planetListDiv !== null) {
    processPlanetNodes(planetListDiv.children);
}

function processMessageNodes(nodes) {
    var reportKeys = {
        sr: [],     //spy report
        cr: [],     //combat report
        rr: [],     //recycle report
        mr: []      //missile report
    };

    for (var i = 0; i < nodes.length; i++) {
        var node = nodes[i];
        var apiElement = node.querySelector(".icon_apikey");
        if (apiElement !== null) {
            var key = apiElement.parentNode.href.replace(/.*?:\/\//g, "");
            var type = key.substring(0, 2);
            if (reportKeys.hasOwnProperty(type)) {
                reportKeys[type].push(key);
            }
        }
    }

    console.log(reportKeys);

    postData({
        endpoint: "keys",
        data: {
            reportKeys: reportKeys
        }
    });
}

function processPlanetNodes(nodes) {
    var planets = [];

    for (var i = 0; i < nodes.length; i++) {
        var planetDiv = nodes[i];
        var planetId = planetDiv.id.replace("planet-", "");
        var planetName = planetDiv.querySelector(".planet-name").innerHTML;
        var planetCoordsRaw = planetDiv.querySelector(".planet-koords").innerHTML;
        var planetCoordsList = planetCoordsRaw.slice(1, -1).split(":");
        planets.push({
            id: planetId,
            name: planetName,
            galaxy: planetCoordsList[0],
            solarSystem: planetCoordsList[1],
            position: planetCoordsList[2]
        });
    }

    var planetsString = JSON.stringify(planets);
    if (getSetting("planets_cache", "") !== planetsString) {
        postData({
            endpoint: "planets",
            data: {
                planets: planets
            }
        });
        saveSetting("planets_cache", planetsString);
    }
}

function processResearchNodes(nodes) {
    var researches = [];

    for (var i = 0; i < nodes.length; i++) {
        var node = nodes[i];
        var detailButtonElement = node.querySelector(".detail_button");
        if (detailButtonElement !== null) {
            var researchId = detailButtonElement.getAttribute("ref");
            var cloneLevelNode = detailButtonElement.querySelector(".level").cloneNode(true);
            var children = [].slice.call(cloneLevelNode.children);

            for (var j = 0; j < children.length; j++) {
                var child = children[j];
                if (child.className === "textlabel" || child.className === "undermark") {
                    cloneLevelNode.removeChild(child);
                }
            }
            var researchLevel = cloneLevelNode.innerHTML.trim();

            researches.push({
                id: researchId,
                level: researchLevel
            });
        }
    }

    var researchesString = JSON.stringify(researches);
    if (getSetting("researches_cache", "") !== researchesString) {
        postData({
            endpoint: "researches",
            data: {
                researches: researches
            }
        });
        saveSetting("researches_cache", researchesString);
    }
}

function postData(object) {
    addPlayerData(object.data);
    console.log(JSON.stringify(object.data));
    GM_xmlhttpRequest({
        method: "POST",
        url: oLogInstanceUrl + "api/userscript/" + object.endpoint,
        data: JSON.stringify(object.data),
        headers: {
            "Content-Type": "application/json"
        },
        onload: function(response) {
            console.log("load");
        },
        onerror: function(response) {
            console.log("error");
        }
    });
}

function addPlayerData(data) {
    data.serverGroup = getWindowVariable("constants.language");
    data.universe = getWindowVariable("constants.name");
    data.playerId = getWindowVariable("playerId");
    data.playerName = getWindowVariable("playerName");
}

/**
 * Returns a global variable.
 *
 * Needed because a @grant other than none puts the script
 * in a separate scope.
 *
 * @param {string} name The name of the global variable.
 */
function getWindowVariable(name) {
    return window.eval(name);
}

function showSuccessMessage(message) {
    getWindowVariable("fadeBox")(message, false);
}

function showErrorMessage(message) {
    getWindowVariable("fadeBox")(message, true);
}

function saveSetting(key, value) {
    var fullKey = getWindowVariable("constants.language") + ":" + getWindowVariable("constants.name") + ":" + getWindowVariable("playerId") + ":" + key;
    GM_setValue(fullKey, value);
}

function getSetting(key, defaultValue) {
    var fullKey = getWindowVariable("constants.language") + ":" + getWindowVariable("constants.name") + ":" + getWindowVariable("playerId") + ":" + key;
    return GM_getValue(fullKey, defaultValue);
}<|endoftext|>


<commit_before>
class Invoker {

  constructor(commands) {
    this.commands = commands;
  }

  start(commandName) {
    if (this.commands[commandName]) this.commands[commandName].start();
  }

  stop(commandName) {
    this.commands[commandName].stop();
  }
}

module.exports = Invoker;
<commit_msg>when stop down - green<commit_after>
class Invoker {

  constructor(commands) {
    this.commands = commands;
  }

  start(commandName) {
    if (this.commands[commandName]) this.commands[commandName].start();
  }

  stop(commandName) {
    if (this.commands[commandName]) this.commands[commandName].stop();
  }
}

module.exports = Invoker;
<|endoftext|>


<commit_before>import _ from 'lodash'
import {inserter} from '../utils'

let endpoints = (app, pool, handleError) => {
	let table = 'item'

	app.get('/api/item/:itemId', function(req, res) {
		console.log('[GET] Route matched:', '/api/item/:itemId');
		pool.query(`SELECT * FROM ${table} where item_id = "${req.params.itemId}"`, function(err, result) {
			// handle an error from the query
			if (err) {
				return handleError(err, res)
			}

			console.log('Result:', result.rows);
			// working:
			// res.setHeader('Content-Type', 'application/json');
			// res.send(JSON.stringify(result.rows));
			// working:
			res.json(result.rows);

			// not working:
			// res.writeHead(200, {'content-type': 'application/json'})
			// res.send(JSON.stringify(result.rows)) // JSON string on GET
			// res.end()
		})
	})

	app.post('/api/item/:itemId', function(req, res) {
		console.log('[POST] Route matched:', '/api/item/:itemId');

		let updateTitle = '',
			updateContent = ''

		if (req.body.title !== undefined) {
			updateTitle = `item_title = "${req.body.title}" `
		}

		if (req.body.content !== undefined) {
			updateContent = `content = "${req.body.content}" `
		}

		if (!updateTitle && updateContent) {
			console.log('NO CONTENT ERROR PLZ');
			return false;
		}

		pool.query(`UPDATE ${table} SET ${updateTitle} ${updateContent} where item_id = "${req.params.itemId}"`, function(err, result) {
			// handle an error from the query
			if (err) {
				return handleError(err, res)
			}

			console.log('Result:', result.rows);
			// working:
			// res.setHeader('Content-Type', 'application/json');
			// res.send(JSON.stringify(result.rows));
			// working:
			res.json(result.rows);

			// not working:
			// res.writeHead(200, {'content-type': 'application/json'})
			// res.send(JSON.stringify(result.rows)) // JSON string on GET
			// res.end()
		})
	})

	app.get('/api/items', function(req, res) {
		pool.query(`SELECT * FROM ${table}`, function(err, result) {
			// handle an error from the query
			if (err) {
				return handleError(err, res)
			}

			console.log('Result:', result.rows);
			// working:
			// res.setHeader('Content-Type', 'application/json');
			// res.send(JSON.stringify(result.rows));
			// working:
			res.json(result.rows);

			// not working:
			// res.writeHead(200, {'content-type': 'application/json'})
			// res.send(JSON.stringify(result.rows)) // JSON string on GET
			// res.end()
		})
	})

	app.post('/api/items', function(req, res) {
		let validItems = {}

		// console.log('Raw:', req.body);

		// validation
		if (_.isString(req.body.item_title) && req.body.item_title !== '') {
			validItems.item_title = req.body.item_title
		}

		if (_.isString(req.body.content) && req.body.content !== '') {
			validItems.content = req.body.content
		}

		if (_.isEmpty(validItems)) {
			console.log('Empty, should throw error now');
		}

		let sql = inserter(table, validItems)

		pool.query(sql.query, sql.data, (err) => {

			if (err) {
				return handleError(err, res)
			}

			res.json({success: true});
		})
	})

	// app.post('/api/visit', function(req, res) {
	// 	// Create a log with request IP and current time of request
	// 	pool.query('INSERT INTO visit (date, ip) VALUES ($1, $2)', [new Date(), req.ip], function(err) {
	// 		res.json({success: true});
	// 	})
	// })
}

export default endpoints
<commit_msg>adding new routes<commit_after>import _ from 'lodash'
import {inserter} from '../utils'

let endpoints = (app, pool, handleError) => {
	let table = 'item'

	app.get('/api/item/:itemId', function(req, res) {
		console.log('[GET] Route matched:', '/api/item/:itemId');
		let query = `SELECT * FROM ${table} where item_id = "${req.params.itemId}"`
		console.log('Query:', query);

		pool.query(query, function(err, result) {
			// handle an error from the query
			if (err) {
				return handleError(err, res)
			}

			console.log('Result:', result.rows);
			// working:
			// res.setHeader('Content-Type', 'application/json');
			// res.send(JSON.stringify(result.rows));
			// working:
			res.json(result.rows);

			// not working:
			// res.writeHead(200, {'content-type': 'application/json'})
			// res.send(JSON.stringify(result.rows)) // JSON string on GET
			// res.end()
		})
	})

	app.post('/api/item/:itemId', function(req, res) {
		console.log('[POST] Route matched:', '/api/item/:itemId');

		let updateTitle = '',
			updateContent = ''

		if (req.body.title !== undefined) {
			updateTitle = `item_title = "${req.body.title}" `
		}

		if (req.body.content !== undefined) {
			updateContent = `content = "${req.body.content}" `
		}

		if (!updateTitle && updateContent) {
			console.log('NO CONTENT ERROR PLZ');
			return false;
		}

		pool.query(`UPDATE ${table} SET ${updateTitle} ${updateContent} where item_id = "${req.params.itemId}"`, function(err, result) {
			// handle an error from the query
			if (err) {
				return handleError(err, res)
			}

			console.log('Result:', result.rows);
			// working:
			// res.setHeader('Content-Type', 'application/json');
			// res.send(JSON.stringify(result.rows));
			// working:
			res.json(result.rows);

			// not working:
			// res.writeHead(200, {'content-type': 'application/json'})
			// res.send(JSON.stringify(result.rows)) // JSON string on GET
			// res.end()
		})
	})

	app.get('/api/items', function(req, res) {
		pool.query(`SELECT * FROM ${table}`, function(err, result) {
			// handle an error from the query
			if (err) {
				return handleError(err, res)
			}

			console.log('Result:', result.rows);
			// working:
			// res.setHeader('Content-Type', 'application/json');
			// res.send(JSON.stringify(result.rows));
			// working:
			res.json(result.rows);

			// not working:
			// res.writeHead(200, {'content-type': 'application/json'})
			// res.send(JSON.stringify(result.rows)) // JSON string on GET
			// res.end()
		})
	})

	app.post('/api/items', function(req, res) {
		console.log('[POST] Route matched:', '/api/items');
		console.log('Raw:', req.body);

		let validItems = {}

		// validation
		if (_.isString(req.body.item_title) && req.body.item_title !== '') {
			validItems.item_title = req.body.item_title
		}

		if (_.isString(req.body.content) && req.body.content !== '') {
			validItems.content = req.body.content
		}

		if (_.isEmpty(validItems)) {
			console.log('Empty, should throw error now');
		}

		let sql = inserter(table, validItems)

		pool.query(sql.query, sql.data, (err) => {

			if (err) {
				return handleError(err, res)
			}

			res.json({success: true});
		})
	})

	// app.post('/api/visit', function(req, res) {
	// 	// Create a log with request IP and current time of request
	// 	pool.query('INSERT INTO visit (date, ip) VALUES ($1, $2)', [new Date(), req.ip], function(err) {
	// 		res.json({success: true});
	// 	})
	// })
}

export default endpoints
<|endoftext|>


<commit_before>const moment                = require('moment');
const ICOPortfolio          = require('./ico_portfolio');
const BinarySocket          = require('../socket');
const BinaryPjax            = require('../../base/binary_pjax');
const Client                = require('../../base/client');
const localize              = require('../../base/localize').localize;
const State                 = require('../../base/storage').State;
const urlFor                = require('../../base/url').urlFor;
const jpClient              = require('../../common_functions/country_base').jpClient;
const getDecimalPlaces      = require('../../common_functions/currency').getDecimalPlaces;
const formatMoney           = require('../../common_functions/currency').formatMoney;
const onlyNumericOnKeypress = require('../../common_functions/event_handler');
const FormManager           = require('../../common_functions/form_manager');
const getLanguage           = require('../../base/language').get;
const Url                   = require('../../base/url');

const ICOSubscribe = (() => {
    const form_id = '#frm_ico_bid';
    let currency,
        $form_error,
        $duration,
        $price,
        $total;

    const onLoad = () => {
        if (jpClient()) {
            BinaryPjax.loadPreviousUrl();
            return;
        }

        const language = (getLanguage() || '').toLowerCase();
        const image = language.match(/(ru|id|pt)/gi)
            ? Url.urlForStatic(`images/pages/ico/auction-${language}.svg`)
            : Url.urlForStatic('images/pages/ico/auction.svg');
        // Set image based on language.
        $('.ico-auction')
            .off('error')
            .on('error', function () {
                // Just in case of error.
                $(this).attr('src',
                    Url.urlForStatic('images/pages/ico/auction.svg'));
            })
            .attr('src', image);

        BinarySocket.wait('website_status', 'landing_company', 'get_settings').then(() => {
            if (State.getResponse('website_status.ico_status') === 'closed') {
                $(form_id).replaceWith($('<p/>', { class: 'notice-msg center-text', text: localize('The ICO is currently unavailable.') }));
                ICOcountDown();
                ICOPortfolio.onLoad();
                showContent();
            } else {
                init();
            }
        });
    };

    const init = () => {
        BinarySocket.wait('balance').then((response) => {
            ICOPortfolio.onLoad();
            currency = Client.get('currency') || '';
            if (currency) {
                $('.currency').text(currency);
            } else {
                $(form_id).find('.topMenuBalance').html(formatMoney(currency, 0));
            }
            $duration = $('#duration');
            $price    = $('#price');
            $total    = $('#total');
            calculateTotal();
            const to_show = showContent();
            if (to_show !== 'ico_subscribe') {
                return;
            }

            const balance = response.balance.balance;
            if (+balance === 0) {
                $(`${form_id} input`).attr('disabled', 'disabled');
                $(form_id)
                    .on('submit', (evt) => { evt.preventDefault(); })
                    .find('button').addClass('inactive');
                $('#topup_wrapper').setVisibility(1);
            } else {
                const decimal_places = getDecimalPlaces(currency);
                $form_error          = $('#form_error');

                FormManager.init(form_id, [
                    { selector: '#duration', validations: ['req', ['number', { min: 25, max: 1000000 }]], parent_node: 'parameters' },
                    { selector: '#price',    validations: ['req', ['number', { type: 'float', decimals: `1, ${decimal_places}`, min: Math.pow(10, -decimal_places).toFixed(decimal_places), max: 999999999999999 }]] },

                    { request_field: 'buy', value: 1 },
                    { request_field: 'amount',        parent_node: 'parameters', value: () => document.getElementById('price').value },
                    { request_field: 'contract_type', parent_node: 'parameters', value: 'BINARYICO' },
                    { request_field: 'symbol',        parent_node: 'parameters', value: 'BINARYICO' },
                    { request_field: 'basis',         parent_node: 'parameters', value: 'stake' },
                    { request_field: 'currency',      parent_node: 'parameters', value: currency },
                    { request_field: 'duration_unit', parent_node: 'parameters', value: 'c' },
                ]);
                FormManager.handleSubmit({
                    form_selector       : form_id,
                    enable_button       : 1,
                    fnc_response_handler: handleResponse,
                });
                $(`${form_id} input`).on('keypress', onlyNumericOnKeypress)
                    .on('input change', calculateTotal);
            }
        });
    };

    const calculateTotal = () => {
        const duration_val = $duration.val();
        const price_val    = $price.val();
        let total          = 0;
        if (duration_val && price_val) {
            total = +duration_val * +price_val;
        }
        $total.html(formatMoney(currency, total));
    };

    const ICOcountDown = () => {
        const timer = $('.timer');
        const days = timer.find('.time .days');
        const hours = timer.find('.time .hours');
        const minutes = timer.find('.time .minutes');
        const seconds = timer.find('.time .seconds');
        const timerID = window.setInterval(() => {
            const start_time = 1510704000;
            const current_time = window.time.unix();
            const time_left = start_time - current_time;
            if(time_left >= 0) {
                const s = (`0${  time_left % 60}`).slice(-2);
                const m = (`0${  Math.floor(time_left/ 60) % 60}`).slice(-2);
                const h = (`0${  Math.floor(time_left / 3600) % 24}`).slice(-2);
                const d = (`0${  Math.floor(time_left / (3600 * 24))}`).slice(-2);
                days.text(d);
                hours.text(h);
                minutes.text(m);
                seconds.text(s);
                timer.setVisibility(1); // Make the timer visible.
                // Force reload in case some-one's on the page and watching the timer.
                if(time_left === 0) {
                    setTimeout(() => window.location.reload(), 500);
                }
            } else {
                window.clearInterval(timerID);
            }
        }, 1000);
    };

    const handleResponse = (response) => {
        if (response.error) {
            $form_error.text(response.error.message).setVisibility(1);
        } else {
            $form_error.setVisibility(0);
            $('#duration, #price').val('');
            $.scrollTo($('#ico_bids'), 500, { offset: -10 });
        }
    };

    const showContent = () => {
        let to_show = 'feature_not_allowed';
        if (Client.get('landing_company_shortcode') === 'costarica') {
            if (/au|ca|ch|nz|sg/.test(Client.get('residence'))
                && !/professional_requested|professional/.test(State.getResponse('get_account_status.status'))) {
                to_show = 'ico_professional_message';
            } else {
                to_show = 'ico_subscribe';
            }
            to_show = 'ico_subscribe';
        } else if (Client.hasCostaricaAccount()) {
            to_show = 'ico_account_message';
        } else if (Client.canOpenICO() || Client.canUpgradeVirtualToReal(State.getResponse('landing_company'))) {
            to_show = 'ico_new_account_message';
            const button_new_account = document.getElementById('ico_new_account');
            if(!State.getResponse('get_settings.account_opening_reason')) {
                askForAccountOpeningReason();
            }
            if (button_new_account) {
                button_new_account.removeEventListener('click', newAccountOnClick);
                button_new_account.addEventListener('click', newAccountOnClick);
            }
        }
        const el_to_show = document.getElementById(to_show);
        if (el_to_show) {
            el_to_show.setVisibility(1);
        }
        return to_show;
    };

    const newAccountOnClick = () => {
        const el_account_opening_reason = document.getElementById('account_opening_reason');
        const el_error = document.getElementById('new_account_error');
        if (Client.hasAccountType('real')) {
            BinarySocket.wait('get_settings').then((response) => {
                const req = populateReq(response.get_settings);

                // Check if client has account_opening_reason set.
                if($(el_account_opening_reason).is(':visible') && !req.account_opening_reason) {
                    const value = el_account_opening_reason.value;
                    if(value) {
                        req.account_opening_reason = value;
                    } else {
                        el_error.setVisibility(1).textContent = localize('Please select a value for account_opening_reason.');
                        return;
                    }
                }

                BinarySocket.send(req).then((response_new_account_real) => {
                    if (response_new_account_real.error) {
                        if (el_error) {
                            el_error.setVisibility(1).textContent = response_new_account_real.error.message;
                        }
                    } else {
                        localStorage.setItem('is_new_account', 1);
                        Client.processNewAccount({
                            email       : Client.get('email'),
                            loginid     : response_new_account_real.new_account_real.client_id,
                            token       : response_new_account_real.new_account_real.oauth_token,
                            redirect_url: urlFor('user/set-currency'),
                        });
                    }
                });
            });
        } else {
            BinaryPjax.load(urlFor('new_account/realws') + (Client.canUpgradeVirtualToReal(State.getResponse('landing_company')) ? '' : '#ico'));
        }
    };

    const populateReq = (get_settings) => {
        const dob = moment(+get_settings.date_of_birth * 1000).format('YYYY-MM-DD');
        const req = {
            new_account_real      : 1,
            account_type          : 'ico',
            date_of_birth         : dob,
            salutation            : get_settings.salutation,
            first_name            : get_settings.first_name,
            last_name             : get_settings.last_name,
            address_line_1        : get_settings.address_line_1,
            address_line_2        : get_settings.address_line_2,
            address_city          : get_settings.address_city,
            address_state         : get_settings.address_state,
            address_postcode      : get_settings.address_postcode,
            phone                 : get_settings.phone,
            account_opening_reason: get_settings.account_opening_reason,
            residence             : Client.get('residence'),
        };
        if (get_settings.tax_identification_number) {
            req.tax_identification_number = get_settings.tax_identification_number;
        }
        if (get_settings.tax_residence) {
            req.tax_residence = get_settings.tax_residence;
        }
        return req;
    };

    const askForAccountOpeningReason = () => {
        const el_to_show = document.getElementById('row_account_opening_reason');
        el_to_show.setVisibility(1);
    };

    const onUnload = () => {
        ICOPortfolio.onUnload();
    };

    return {
        onLoad,
        onUnload,
    };
})();

module.exports = ICOSubscribe;
<commit_msg>Check for virtual<commit_after>const moment                = require('moment');
const ICOPortfolio          = require('./ico_portfolio');
const BinarySocket          = require('../socket');
const BinaryPjax            = require('../../base/binary_pjax');
const Client                = require('../../base/client');
const localize              = require('../../base/localize').localize;
const State                 = require('../../base/storage').State;
const urlFor                = require('../../base/url').urlFor;
const jpClient              = require('../../common_functions/country_base').jpClient;
const getDecimalPlaces      = require('../../common_functions/currency').getDecimalPlaces;
const formatMoney           = require('../../common_functions/currency').formatMoney;
const onlyNumericOnKeypress = require('../../common_functions/event_handler');
const FormManager           = require('../../common_functions/form_manager');
const getLanguage           = require('../../base/language').get;
const Url                   = require('../../base/url');

const ICOSubscribe = (() => {
    const form_id = '#frm_ico_bid';
    let currency,
        $form_error,
        $duration,
        $price,
        $total;

    const onLoad = () => {
        if (jpClient()) {
            BinaryPjax.loadPreviousUrl();
            return;
        }

        const language = (getLanguage() || '').toLowerCase();
        const image = language.match(/(ru|id|pt)/gi)
            ? Url.urlForStatic(`images/pages/ico/auction-${language}.svg`)
            : Url.urlForStatic('images/pages/ico/auction.svg');
        // Set image based on language.
        $('.ico-auction')
            .off('error')
            .on('error', function () {
                // Just in case of error.
                $(this).attr('src',
                    Url.urlForStatic('images/pages/ico/auction.svg'));
            })
            .attr('src', image);

        BinarySocket.wait('website_status', 'landing_company', 'get_settings').then(() => {
            if (State.getResponse('website_status.ico_status') === 'closed') {
                $(form_id).replaceWith($('<p/>', { class: 'notice-msg center-text', text: localize('The ICO is currently unavailable.') }));
                ICOcountDown();
                ICOPortfolio.onLoad();
                showContent();
            } else {
                init();
            }
        });
    };

    const init = () => {
        BinarySocket.wait('balance').then((response) => {
            ICOPortfolio.onLoad();
            currency = Client.get('currency') || '';
            if (currency) {
                $('.currency').text(currency);
            } else {
                $(form_id).find('.topMenuBalance').html(formatMoney(currency, 0));
            }
            $duration = $('#duration');
            $price    = $('#price');
            $total    = $('#total');
            calculateTotal();
            const to_show = showContent();
            if (to_show !== 'ico_subscribe') {
                return;
            }

            const balance = response.balance.balance;
            if (+balance === 0) {
                $(`${form_id} input`).attr('disabled', 'disabled');
                $(form_id)
                    .on('submit', (evt) => { evt.preventDefault(); })
                    .find('button').addClass('inactive');
                $('#topup_wrapper').setVisibility(1);
            } else {
                const decimal_places = getDecimalPlaces(currency);
                $form_error          = $('#form_error');

                FormManager.init(form_id, [
                    { selector: '#duration', validations: ['req', ['number', { min: 25, max: 1000000 }]], parent_node: 'parameters' },
                    { selector: '#price',    validations: ['req', ['number', { type: 'float', decimals: `1, ${decimal_places}`, min: Math.pow(10, -decimal_places).toFixed(decimal_places), max: 999999999999999 }]] },

                    { request_field: 'buy', value: 1 },
                    { request_field: 'amount',        parent_node: 'parameters', value: () => document.getElementById('price').value },
                    { request_field: 'contract_type', parent_node: 'parameters', value: 'BINARYICO' },
                    { request_field: 'symbol',        parent_node: 'parameters', value: 'BINARYICO' },
                    { request_field: 'basis',         parent_node: 'parameters', value: 'stake' },
                    { request_field: 'currency',      parent_node: 'parameters', value: currency },
                    { request_field: 'duration_unit', parent_node: 'parameters', value: 'c' },
                ]);
                FormManager.handleSubmit({
                    form_selector       : form_id,
                    enable_button       : 1,
                    fnc_response_handler: handleResponse,
                });
                $(`${form_id} input`).on('keypress', onlyNumericOnKeypress)
                    .on('input change', calculateTotal);
            }
        });
    };

    const calculateTotal = () => {
        const duration_val = $duration.val();
        const price_val    = $price.val();
        let total          = 0;
        if (duration_val && price_val) {
            total = +duration_val * +price_val;
        }
        $total.html(formatMoney(currency, total));
    };

    const ICOcountDown = () => {
        const timer = $('.timer');
        const days = timer.find('.time .days');
        const hours = timer.find('.time .hours');
        const minutes = timer.find('.time .minutes');
        const seconds = timer.find('.time .seconds');
        const timerID = window.setInterval(() => {
            const start_time = 1510704000;
            const current_time = window.time.unix();
            const time_left = start_time - current_time;
            if(time_left >= 0) {
                const s = (`0${  time_left % 60}`).slice(-2);
                const m = (`0${  Math.floor(time_left/ 60) % 60}`).slice(-2);
                const h = (`0${  Math.floor(time_left / 3600) % 24}`).slice(-2);
                const d = (`0${  Math.floor(time_left / (3600 * 24))}`).slice(-2);
                days.text(d);
                hours.text(h);
                minutes.text(m);
                seconds.text(s);
                timer.setVisibility(1); // Make the timer visible.
                // Force reload in case some-one's on the page and watching the timer.
                if(time_left === 0) {
                    setTimeout(() => window.location.reload(), 500);
                }
            } else {
                window.clearInterval(timerID);
            }
        }, 1000);
    };

    const handleResponse = (response) => {
        if (response.error) {
            $form_error.text(response.error.message).setVisibility(1);
        } else {
            $form_error.setVisibility(0);
            $('#duration, #price').val('');
            $.scrollTo($('#ico_bids'), 500, { offset: -10 });
        }
    };

    const showContent = () => {
        let to_show = 'feature_not_allowed';
        if (Client.get('landing_company_shortcode') === 'costarica') {
            if (/au|ca|ch|nz|sg/.test(Client.get('residence'))
                && !/professional_requested|professional/.test(State.getResponse('get_account_status.status'))) {
                to_show = 'ico_professional_message';
            } else {
                to_show = 'ico_subscribe';
            }
            to_show = 'ico_subscribe';
        } else if (Client.hasCostaricaAccount()) {
            to_show = 'ico_account_message';
        } else if (Client.canOpenICO() || Client.canUpgradeVirtualToReal(State.getResponse('landing_company'))) {
            to_show = 'ico_new_account_message';
            const button_new_account = document.getElementById('ico_new_account');
            if(!State.getResponse('get_settings.account_opening_reason')
                && !Client.isAccountOfType('virtual')) {
                askForAccountOpeningReason();
            }
            if (button_new_account) {
                button_new_account.removeEventListener('click', newAccountOnClick);
                button_new_account.addEventListener('click', newAccountOnClick);
            }
        }
        const el_to_show = document.getElementById(to_show);
        if (el_to_show) {
            el_to_show.setVisibility(1);
        }
        return to_show;
    };

    const newAccountOnClick = () => {
        const el_account_opening_reason = document.getElementById('account_opening_reason');
        const el_error = document.getElementById('new_account_error');
        if (Client.hasAccountType('real')) {
            BinarySocket.wait('get_settings').then((response) => {
                const req = populateReq(response.get_settings);

                // Check if client has account_opening_reason set.
                if($(el_account_opening_reason).is(':visible') && !req.account_opening_reason) {
                    const value = el_account_opening_reason.value;
                    if(value) {
                        req.account_opening_reason = value;
                    } else {
                        el_error.setVisibility(1).textContent = localize('Please select a value for account_opening_reason.');
                        return;
                    }
                }

                BinarySocket.send(req).then((response_new_account_real) => {
                    if (response_new_account_real.error) {
                        if (el_error) {
                            el_error.setVisibility(1).textContent = response_new_account_real.error.message;
                        }
                    } else {
                        localStorage.setItem('is_new_account', 1);
                        Client.processNewAccount({
                            email       : Client.get('email'),
                            loginid     : response_new_account_real.new_account_real.client_id,
                            token       : response_new_account_real.new_account_real.oauth_token,
                            redirect_url: urlFor('user/set-currency'),
                        });
                    }
                });
            });
        } else {
            BinaryPjax.load(urlFor('new_account/realws') + (Client.canUpgradeVirtualToReal(State.getResponse('landing_company')) ? '' : '#ico'));
        }
    };

    const populateReq = (get_settings) => {
        const dob = moment(+get_settings.date_of_birth * 1000).format('YYYY-MM-DD');
        const req = {
            new_account_real      : 1,
            account_type          : 'ico',
            date_of_birth         : dob,
            salutation            : get_settings.salutation,
            first_name            : get_settings.first_name,
            last_name             : get_settings.last_name,
            address_line_1        : get_settings.address_line_1,
            address_line_2        : get_settings.address_line_2,
            address_city          : get_settings.address_city,
            address_state         : get_settings.address_state,
            address_postcode      : get_settings.address_postcode,
            phone                 : get_settings.phone,
            account_opening_reason: get_settings.account_opening_reason,
            residence             : Client.get('residence'),
        };
        if (get_settings.tax_identification_number) {
            req.tax_identification_number = get_settings.tax_identification_number;
        }
        if (get_settings.tax_residence) {
            req.tax_residence = get_settings.tax_residence;
        }
        return req;
    };

    const askForAccountOpeningReason = () => {
        const el_to_show = document.getElementById('row_account_opening_reason');
        el_to_show.setVisibility(1);
    };

    const onUnload = () => {
        ICOPortfolio.onUnload();
    };

    return {
        onLoad,
        onUnload,
    };
})();

module.exports = ICOSubscribe;
<|endoftext|>


<commit_before>module.exports = function(User) {

	User.disableRemoteMethod('find', true);
	User.disableRemoteMethod('exists', true);
	User.disableRemoteMethod('count', true);
	//User.disableRemoteMethod('upsert', true);
	User.disableRemoteMethod('updateAll', true);
	User.disableRemoteMethod('findOne', true);

	User.passwordUpdate = function(accessToken, password, next) {

		this.app.models.AccessToken.findById(accessToken, function(err, token) {
			if (err) {
				return next(err);
			} else if (!token) {
				return next(new Error('Token not found!'));
			}

			User.findById(token.userId, function(err, user) {
				if(err) {
					return next(err);
				} else if(!user) {
					return next(new Error('User not found!'));
				}

				user.updateAttribute('password', password, function(err, user) {
					if (err) {
						next(err);
					}

					return next(null, true);
				});
			});

		});
    }

    User.remoteMethod(
        'passwordUpdate',
        {
        	description: 'Resets the user password with the reset token',
			accepts: [
				{arg: 'accessToken', type: 'string'},
				{arg: 'password', type: 'string'}
			],
			returns: {arg: 'result', type: 'boolean'}
        }
    );

	User.on('resetPasswordRequest', function(info) {
		if (info.user) {

			User.app.models.Email.send({
				async: true,
				to: info.user.email,
				from: 'hello@prud.io',
				subject: 'Reset your password',
				template: {
					name: 'reset-password'
				},
				merge_vars: [
					{
						'rcpt': info.user.email,
						'vars': [
							{
								name: 'name',
								content: info.user.fname
							},
							{
								name: 'token',
								content: info.accessToken.id
							}]
					}
				]
			},
			function(err, result) {
				if(err) {
					console.error(err);
				}
			});
		}
	});

	User.observe('after save', function beforeSave(ctx, next) {

		// If instance = new object
		if (ctx.isNewInstance) {

			// Send welcome e-mail
			User.app.models.Email.send({
				async: true,
				to: ctx.instance.email,
				from: 'hello@prud.io',
				subject: 'Welcome to Prud.io',
				template: {
					name: 'signup-e-mail'
				},
				merge_vars: [
					{
						'rcpt': ctx.instance.email,
						'vars': [
							{
								name: 'name',
								content: ctx.instance.fname
							}]
					}
				]
			},
			function(err, result) {
				if(err) {
					console.error(err);
					return next(err);
				}
				next();
			});
		} else {
			next();
		}
	});

	User.observe('before save', function beforeSave(ctx, next) {

		// If instance = new object
		if (ctx.isNewInstance) {

			ctx.instance.created  = new Date();
			ctx.instance.modified = new Date();

			var name = ctx.instance.fname + " " + ctx.instance.lname + '\'s Account';

			ctx.instance.accounts.create({
				name: name
			},
			function(err, account) {
				if (err) {
					console.error(err);
					next(err);
				}

				ctx.instance.defaultAccountId = account.id;

				next();
			});

		} else {

		    ctx.instance.modified = new Date();
			next();
		}
	});

};
<commit_msg>Accountuser bug<commit_after>module.exports = function(User) {

	User.disableRemoteMethod('find', true);
	User.disableRemoteMethod('exists', true);
	User.disableRemoteMethod('count', true);
	//User.disableRemoteMethod('upsert', true);
	User.disableRemoteMethod('updateAll', true);
	User.disableRemoteMethod('findOne', true);

	User.passwordUpdate = function(accessToken, password, next) {

		this.app.models.AccessToken.findById(accessToken, function(err, token) {
			if (err) {
				return next(err);
			} else if (!token) {
				return next(new Error('Token not found!'));
			}

			User.findById(token.userId, function(err, user) {
				if(err) {
					return next(err);
				} else if(!user) {
					return next(new Error('User not found!'));
				}

				user.updateAttribute('password', password, function(err, user) {
					if (err) {
						next(err);
					}

					return next(null, true);
				});
			});

		});
    }

    User.remoteMethod(
        'passwordUpdate',
        {
        	description: 'Resets the user password with the reset token',
			accepts: [
				{arg: 'accessToken', type: 'string'},
				{arg: 'password', type: 'string'}
			],
			returns: {arg: 'result', type: 'boolean'}
        }
    );

	User.on('resetPasswordRequest', function(info) {
		if (info.user) {

			User.app.models.Email.send({
				async: true,
				to: info.user.email,
				from: 'hello@prud.io',
				subject: 'Reset your password',
				template: {
					name: 'reset-password'
				},
				merge_vars: [
					{
						'rcpt': info.user.email,
						'vars': [
							{
								name: 'name',
								content: info.user.fname
							},
							{
								name: 'token',
								content: info.accessToken.id
							}]
					}
				]
			},
			function(err, result) {
				if(err) {
					console.error(err);
				}
			});
		}
	});

	User.observe('after save', function afterSave(ctx, next) {

		// If instance = new object
		if (ctx.isNewInstance) {

			ctx.instance.created  = new Date();
			ctx.instance.modified = new Date();

			var name = ctx.instance.fname + " " + ctx.instance.lname + '\'s Account';

			ctx.instance.accounts.create({
				name: name
			},
			function(err, account) {
				if (err) {
					console.error(err);
					next(err);
				}

				ctx.instance.defaultAccountId = account.id;

				// Send welcome e-mail
				User.app.models.Email.send({
					async: true,
					to: ctx.instance.email,
					from: 'hello@prud.io',
					subject: 'Welcome to Prud.io',
					template: {
						name: 'signup-e-mail'
					},
					merge_vars: [
						{
							'rcpt': ctx.instance.email,
							'vars': [
								{
									name: 'name',
									content: ctx.instance.fname
								}]
						}
					]
				},
				function(err, result) {
					if(err) {
						console.error(err);
						return next(err);
					}
					next();
				});
			});

		} else {

		    ctx.instance.modified = new Date();
			next();
		}
	});

};
<|endoftext|>


<commit_before>const moment                = require('moment');
const ICOPortfolio          = require('./ico_portfolio');
const BinarySocket          = require('../socket');
const BinaryPjax            = require('../../base/binary_pjax');
const Client                = require('../../base/client');
const localize              = require('../../base/localize').localize;
const State                 = require('../../base/storage').State;
const urlFor                = require('../../base/url').urlFor;
const jpClient              = require('../../common_functions/country_base').jpClient;
const getDecimalPlaces      = require('../../common_functions/currency').getDecimalPlaces;
const formatMoney           = require('../../common_functions/currency').formatMoney;
const onlyNumericOnKeypress = require('../../common_functions/event_handler');
const FormManager           = require('../../common_functions/form_manager');
const getLanguage           = require('../../base/language').get;
const Url                   = require('../../base/url');

const ICOSubscribe = (() => {
    const form_id = '#frm_ico_bid';
    let currency,
        $form_error,
        $duration,
        $price,
        $total;

    const onLoad = () => {
        if (jpClient()) {
            BinaryPjax.loadPreviousUrl();
            return;
        }

        const language = (getLanguage() || '').toLowerCase();
        const image = language.match(/(ru|id|pt)/gi)
            ? Url.urlForStatic(`images/pages/ico/auction-${language}.svg`)
            : Url.urlForStatic('images/pages/ico/auction.svg');
        // Set image based on language.
        $('.ico-auction')
            .off('error')
            .on('error', function () {
                // Just in case of error.
                $(this).attr('src',
                    Url.urlForStatic('images/pages/ico/auction.svg'));
            })
            .attr('src', image);

        BinarySocket.wait('website_status', 'landing_company').then(() => {
            if (State.getResponse('website_status.ico_status') === 'closed') {
                $(form_id).replaceWith($('<p/>', { class: 'notice-msg center-text', text: localize('The ICO is currently unavailable.') }));
                ICOcountDown();
                ICOPortfolio.onLoad();
                showContent();
            } else {
                init();
            }
        });
    };

    const init = () => {
        BinarySocket.wait('balance').then((response) => {
            ICOPortfolio.onLoad();
            currency = Client.get('currency') || '';
            if (currency) {
                $('.currency').text(currency);
            } else {
                $(form_id).find('.topMenuBalance').html(formatMoney(currency, 0));
            }
            $duration = $('#duration');
            $price    = $('#price');
            $total    = $('#total');
            calculateTotal();
            const to_show = showContent();
            if (to_show !== 'ico_subscribe') {
                return;
            }

            const balance = response.balance.balance;
            if (+balance === 0) {
                $(`${form_id} input`).attr('disabled', 'disabled');
                $(form_id)
                    .on('submit', (evt) => { evt.preventDefault(); })
                    .find('button').addClass('inactive');
                $('#topup_wrapper').setVisibility(1);
            } else {
                const decimal_places = getDecimalPlaces(currency);
                $form_error          = $('#form_error');
                FormManager.init(form_id, [
                    { selector: '#duration', validations: ['req', ['number', { min: 25, max: 1000000 }]], parent_node: 'parameters' },
                    { selector: '#price',    validations: ['req', ['number', { type: 'float', decimals: `1, ${decimal_places}`, min: Math.pow(10, -decimal_places).toFixed(decimal_places), max: 999999999999999 }]] },

                    { request_field: 'buy', value: 1 },
                    { request_field: 'amount',        parent_node: 'parameters', value: () => document.getElementById('price').value },
                    { request_field: 'contract_type', parent_node: 'parameters', value: 'BINARYICO' },
                    { request_field: 'symbol',        parent_node: 'parameters', value: 'BINARYICO' },
                    { request_field: 'basis',         parent_node: 'parameters', value: 'stake' },
                    { request_field: 'currency',      parent_node: 'parameters', value: currency },
                    { request_field: 'duration_unit', parent_node: 'parameters', value: 'c' },
                ]);
                FormManager.handleSubmit({
                    form_selector       : form_id,
                    enable_button       : 1,
                    fnc_response_handler: handleResponse,
                });
                $(`${form_id} input`).on('keypress', onlyNumericOnKeypress)
                    .on('input change', calculateTotal);
            }
        });
    };

    const calculateTotal = () => {
        const duration_val = $duration.val();
        const price_val    = $price.val();
        let total          = 0;
        if (duration_val && price_val) {
            total = +duration_val * +price_val;
        }
        $total.html(formatMoney(currency, total));
    };

    const ICOcountDown = () => {
        const timer = $('.timer');
        const days = timer.find('.time .days');
        const hours = timer.find('.time .hours');
        const minutes = timer.find('.time .minutes');
        const seconds = timer.find('.time .seconds');
        const timerID = window.setInterval(() => {
            const start_time = 1510704000;
            const current_time = window.time.unix();
            const time_left = start_time - current_time;
            if(time_left >= 0) {
                const s = (`0${  time_left % 60}`).slice(-2);
                const m = (`0${  Math.floor(time_left/ 60) % 60}`).slice(-2);
                const h = (`0${  Math.floor(time_left / 3600) % 24}`).slice(-2);
                const d = (`0${  Math.floor(time_left / (3600 * 24))}`).slice(-2);
                days.text(d);
                hours.text(h);
                minutes.text(m);
                seconds.text(s);
                timer.setVisibility(1); // Make the timer visible.
                // Force reload in case some-one's on the page and watching the timer.
                if(time_left === 0) {
                    setTimeout(() => window.location.reload(), 500);
                }
            } else {
                window.clearInterval(timerID);
            }
        }, 1000);
    };

    const handleResponse = (response) => {
        if (response.error) {
            $form_error.text(response.error.message).setVisibility(1);
        } else {
            $form_error.setVisibility(0);
            $('#duration, #price').val('');
            $.scrollTo($('#ico_bids'), 500, { offset: -10 });
        }
    };

    const showContent = () => {
        let to_show = 'feature_not_allowed';
        if (Client.get('landing_company_shortcode') === 'costarica') {
            if (/au|ca|ch|nz|sg/.test(Client.get('residence'))
                && !/professional_requested|professional/.test(State.getResponse('get_account_status.status'))) {
                to_show = 'ico_professional_message';
            } else {
                to_show = 'ico_subscribe';
            }
            to_show = 'ico_subscribe';
        } else if (Client.hasCostaricaAccount()) {
            to_show = 'ico_account_message';
        } else if (Client.canOpenICO() || Client.canUpgradeVirtualToReal(State.getResponse('landing_company'))) {
            to_show = 'ico_new_account_message';
            const button_new_account = document.getElementById('ico_new_account');
            if (button_new_account) {
                button_new_account.removeEventListener('click', newAccountOnClick);
                button_new_account.addEventListener('click', newAccountOnClick);
            }
        }
        const el_to_show = document.getElementById(to_show);
        if (el_to_show) {
            el_to_show.setVisibility(1);
        }
        return to_show;
    };

    const newAccountOnClick = () => {
        if (Client.hasAccountType('real')) {
            BinarySocket.wait('get_settings').then((response) => {
                BinarySocket.send(populateReq(response.get_settings)).then((response_new_account_real) => {
                    if (response_new_account_real.error) {
                        const el_error = document.getElementById('new_account_error');
                        if (el_error) {
                            el_error.setVisibility(1).textContent = response_new_account_real.error.message;
                        }
                    } else {
                        localStorage.setItem('is_new_account', 1);
                        Client.processNewAccount({
                            email       : Client.get('email'),
                            loginid     : response_new_account_real.new_account_real.client_id,
                            token       : response_new_account_real.new_account_real.oauth_token,
                            redirect_url: urlFor('user/set-currency'),
                        });
                    }
                });
            });
        } else {
            BinaryPjax.load(urlFor('new_account/realws') + (Client.canUpgradeVirtualToReal(State.getResponse('landing_company')) ? '' : '#ico'));
        }
    };

    const populateReq = (get_settings) => {
        const dob = moment(+get_settings.date_of_birth * 1000).format('YYYY-MM-DD');
        const req = {
            new_account_real      : 1,
            account_type          : 'ico',
            date_of_birth         : dob,
            salutation            : get_settings.salutation,
            first_name            : get_settings.first_name,
            last_name             : get_settings.last_name,
            address_line_1        : get_settings.address_line_1,
            address_line_2        : get_settings.address_line_2,
            address_city          : get_settings.address_city,
            address_state         : get_settings.address_state,
            address_postcode      : get_settings.address_postcode,
            phone                 : get_settings.phone,
            account_opening_reason: get_settings.account_opening_reason,
            residence             : Client.get('residence'),
        };
        if (get_settings.tax_identification_number) {
            req.tax_identification_number = get_settings.tax_identification_number;
        }
        if (get_settings.tax_residence) {
            req.tax_residence = get_settings.tax_residence;
        }
        return req;
    };

    const onUnload = () => {
        ICOPortfolio.onUnload();
    };

    return {
        onLoad,
        onUnload,
    };
})();

module.exports = ICOSubscribe;
<commit_msg>disable Place bid button when final_price is zero<commit_after>const moment                = require('moment');
const ICOPortfolio          = require('./ico_portfolio');
const BinarySocket          = require('../socket');
const BinaryPjax            = require('../../base/binary_pjax');
const Client                = require('../../base/client');
const localize              = require('../../base/localize').localize;
const State                 = require('../../base/storage').State;
const urlFor                = require('../../base/url').urlFor;
const jpClient              = require('../../common_functions/country_base').jpClient;
const getDecimalPlaces      = require('../../common_functions/currency').getDecimalPlaces;
const formatMoney           = require('../../common_functions/currency').formatMoney;
const onlyNumericOnKeypress = require('../../common_functions/event_handler');
const FormManager           = require('../../common_functions/form_manager');
const getLanguage           = require('../../base/language').get;
const Url                   = require('../../base/url');

const ICOSubscribe = (() => {
    const form_id = '#frm_ico_bid';
    let currency,
        $form_error,
        $duration,
        $price,
        $total;

    const onLoad = () => {
        if (jpClient()) {
            BinaryPjax.loadPreviousUrl();
            return;
        }

        const language = (getLanguage() || '').toLowerCase();
        const image = language.match(/(ru|id|pt)/gi)
            ? Url.urlForStatic(`images/pages/ico/auction-${language}.svg`)
            : Url.urlForStatic('images/pages/ico/auction.svg');
        // Set image based on language.
        $('.ico-auction')
            .off('error')
            .on('error', function () {
                // Just in case of error.
                $(this).attr('src',
                    Url.urlForStatic('images/pages/ico/auction.svg'));
            })
            .attr('src', image);

        BinarySocket.wait('website_status', 'landing_company').then(() => {
            if (State.getResponse('website_status.ico_status') === 'closed') {
                $(form_id).replaceWith($('<p/>', { class: 'notice-msg center-text', text: localize('The ICO is currently unavailable.') }));
                ICOcountDown();
                ICOPortfolio.onLoad();
                showContent();
            } else {
                init();
            }
        });
    };

    const init = () => {
        BinarySocket.wait('balance').then((response) => {
            ICOPortfolio.onLoad();
            currency = Client.get('currency') || '';
            if (currency) {
                $('.currency').text(currency);
            } else {
                $(form_id).find('.topMenuBalance').html(formatMoney(currency, 0));
            }
            $duration = $('#duration');
            $price    = $('#price');
            $total    = $('#total');
            calculateTotal();
            const to_show = showContent();
            if (to_show !== 'ico_subscribe') {
                return;
            }

            const balance = response.balance.balance;
            if (+balance === 0) {
                $(`${form_id} input`).attr('disabled', 'disabled');
                $(form_id)
                    .on('submit', (evt) => { evt.preventDefault(); })
                    .find('button').addClass('inactive');
                $('#topup_wrapper').setVisibility(1);
            } else {
                const decimal_places = getDecimalPlaces(currency);
                $form_error          = $('#form_error');
                FormManager.init(form_id, [
                    { selector: '#duration', validations: ['req', ['number', { min: 25, max: 1000000 }]], parent_node: 'parameters' },
                    { selector: '#price',    validations: ['req', ['number', { type: 'float', decimals: `1, ${decimal_places}`, min: Math.pow(10, -decimal_places).toFixed(decimal_places), max: 999999999999999 }]] },

                    { request_field: 'buy', value: 1 },
                    { request_field: 'amount',        parent_node: 'parameters', value: () => document.getElementById('price').value },
                    { request_field: 'contract_type', parent_node: 'parameters', value: 'BINARYICO' },
                    { request_field: 'symbol',        parent_node: 'parameters', value: 'BINARYICO' },
                    { request_field: 'basis',         parent_node: 'parameters', value: 'stake' },
                    { request_field: 'currency',      parent_node: 'parameters', value: currency },
                    { request_field: 'duration_unit', parent_node: 'parameters', value: 'c' },
                ]);
                if (+State.getResponse('website_status.ico_info.final_price') === 0) {
                    $(form_id)
                        .on('submit', (evt) => { evt.preventDefault(); })
                        .find('button').addClass('inactive');
                } else {
                    FormManager.handleSubmit({
                        form_selector       : form_id,
                        enable_button       : 1,
                        fnc_response_handler: handleResponse,
                    });
                }
                $(`${form_id} input`).on('keypress', onlyNumericOnKeypress)
                    .on('input change', calculateTotal);
            }
        });
    };

    const calculateTotal = () => {
        const duration_val = $duration.val();
        const price_val    = $price.val();
        let total          = 0;
        if (duration_val && price_val) {
            total = +duration_val * +price_val;
        }
        $total.html(formatMoney(currency, total));
    };

    const ICOcountDown = () => {
        const timer = $('.timer');
        const days = timer.find('.time .days');
        const hours = timer.find('.time .hours');
        const minutes = timer.find('.time .minutes');
        const seconds = timer.find('.time .seconds');
        const timerID = window.setInterval(() => {
            const start_time = 1510704000;
            const current_time = window.time.unix();
            const time_left = start_time - current_time;
            if(time_left >= 0) {
                const s = (`0${  time_left % 60}`).slice(-2);
                const m = (`0${  Math.floor(time_left/ 60) % 60}`).slice(-2);
                const h = (`0${  Math.floor(time_left / 3600) % 24}`).slice(-2);
                const d = (`0${  Math.floor(time_left / (3600 * 24))}`).slice(-2);
                days.text(d);
                hours.text(h);
                minutes.text(m);
                seconds.text(s);
                timer.setVisibility(1); // Make the timer visible.
                // Force reload in case some-one's on the page and watching the timer.
                if(time_left === 0) {
                    setTimeout(() => window.location.reload(), 500);
                }
            } else {
                window.clearInterval(timerID);
            }
        }, 1000);
    };

    const handleResponse = (response) => {
        if (response.error) {
            $form_error.text(response.error.message).setVisibility(1);
        } else {
            $form_error.setVisibility(0);
            $('#duration, #price').val('');
            $.scrollTo($('#ico_bids'), 500, { offset: -10 });
        }
    };

    const showContent = () => {
        let to_show = 'feature_not_allowed';
        if (Client.get('landing_company_shortcode') === 'costarica') {
            if (/au|ca|ch|nz|sg/.test(Client.get('residence'))
                && !/professional_requested|professional/.test(State.getResponse('get_account_status.status'))) {
                to_show = 'ico_professional_message';
            } else {
                to_show = 'ico_subscribe';
            }
            to_show = 'ico_subscribe';
        } else if (Client.hasCostaricaAccount()) {
            to_show = 'ico_account_message';
        } else if (Client.canOpenICO() || Client.canUpgradeVirtualToReal(State.getResponse('landing_company'))) {
            to_show = 'ico_new_account_message';
            const button_new_account = document.getElementById('ico_new_account');
            if (button_new_account) {
                button_new_account.removeEventListener('click', newAccountOnClick);
                button_new_account.addEventListener('click', newAccountOnClick);
            }
        }
        const el_to_show = document.getElementById(to_show);
        if (el_to_show) {
            el_to_show.setVisibility(1);
        }
        return to_show;
    };

    const newAccountOnClick = () => {
        if (Client.hasAccountType('real')) {
            BinarySocket.wait('get_settings').then((response) => {
                BinarySocket.send(populateReq(response.get_settings)).then((response_new_account_real) => {
                    if (response_new_account_real.error) {
                        const el_error = document.getElementById('new_account_error');
                        if (el_error) {
                            el_error.setVisibility(1).textContent = response_new_account_real.error.message;
                        }
                    } else {
                        localStorage.setItem('is_new_account', 1);
                        Client.processNewAccount({
                            email       : Client.get('email'),
                            loginid     : response_new_account_real.new_account_real.client_id,
                            token       : response_new_account_real.new_account_real.oauth_token,
                            redirect_url: urlFor('user/set-currency'),
                        });
                    }
                });
            });
        } else {
            BinaryPjax.load(urlFor('new_account/realws') + (Client.canUpgradeVirtualToReal(State.getResponse('landing_company')) ? '' : '#ico'));
        }
    };

    const populateReq = (get_settings) => {
        const dob = moment(+get_settings.date_of_birth * 1000).format('YYYY-MM-DD');
        const req = {
            new_account_real      : 1,
            account_type          : 'ico',
            date_of_birth         : dob,
            salutation            : get_settings.salutation,
            first_name            : get_settings.first_name,
            last_name             : get_settings.last_name,
            address_line_1        : get_settings.address_line_1,
            address_line_2        : get_settings.address_line_2,
            address_city          : get_settings.address_city,
            address_state         : get_settings.address_state,
            address_postcode      : get_settings.address_postcode,
            phone                 : get_settings.phone,
            account_opening_reason: get_settings.account_opening_reason,
            residence             : Client.get('residence'),
        };
        if (get_settings.tax_identification_number) {
            req.tax_identification_number = get_settings.tax_identification_number;
        }
        if (get_settings.tax_residence) {
            req.tax_residence = get_settings.tax_residence;
        }
        return req;
    };

    const onUnload = () => {
        ICOPortfolio.onUnload();
    };

    return {
        onLoad,
        onUnload,
    };
})();

module.exports = ICOSubscribe;
<|endoftext|>


<commit_before>require(["dojo/ready", "dojo/on", "dojo/dom-class", "esri/map", "esri/dijit/Geocoder"],
    function (ready, on, domClass) {

        ready(function () {

            //Start map
            var options = {
                basemap: "streets", //streets | satellite | hybrid | topo | gray | oceans | national-geographic | osm.
                extent: new esri.geometry.Extent({
                    "xmin": -13094934.17795995,
                    "ymin": 3959049.5650010793,
                    "xmax": -12826640.20867888,
                    "ymax": 4053525.7319615935,
                    "spatialReference": { "wkid": 102100 }
                })
            };
            var map = new esri.Map("map", options);

            // Class to represent a bookmark
            function bookmarkEntry(name, extent) {
                var self = this;
                self.name = name;
                self.extent = extent;
            }

            // View model for bookmark
            function boomarksModelModel() {
                var self = this;

                var bookmarks = JSON.parse(localStorage.getItem("myMapBookmarks"));
                if (!bookmarks) bookmarks = [new bookmarkEntry("Overview", options.extent.toJson())];

                // Editable data
                self.bookmarks = ko.observableArray(bookmarks);

                // stores the value the user enters
                self.current = ko.observable();

                //listen for enter
                self.addBookmarkEnter = function (model, event) {
                    var keyCode = (event.which ? event.which : event.keyCode);
                    if (keyCode === 13) {
                        self.addBookmark();
                    }
                    return true;
                };

                //add a new one
                self.addBookmark = function () {
                    self.bookmarks.push(new bookmarkEntry(self.current(), map.extent.toJson()));
                    self.current(''); //clear the current value
                    self.save();
                };

                //zoom to it. set up history
                self.zoomBookmark = function (item) {
                    map.setExtent(new esri.geometry.Extent(item.extent));
                    //Don't want to use #! and can't build urls because no control on back end
                    history.pushState(item.extent, document.title, url + "?" + item.name);
                };

                self.zoomBookmarkbyName = function (name) {
                    var bm = self.bookmarks().filter(function (item) {
                        return (item.name.toLowerCase() === name.toLowerCase());
                    });
                    if (!bm[0]) return;
                    self.zoomBookmark(bm[0]);
                };

                //remove it
                self.remove = function (item) {
                    self.bookmarks.remove(item);
                    self.save();
                };

                self.save = function () {
                    localStorage.setItem("myMapBookmarks", JSON.stringify(self.bookmarks()));
                };

            }

            //Create model and apply the bindings to the UI
            var bmModel = new boomarksModelModel();
            ko.applyBindings(bmModel);

            //Allow bookmarks to work with back/forward buttons
            //event for loading history
            window.addEventListener("popstate", function (evt) {
                if (evt.state) {
                    map.setExtent(new esri.geometry.Extent(evt.state));
                }
            });

            //insert polyfill here / get a better browser!
            if (!history.pushState) {
                history.pushState = function () { };
                history.replaceState = history.pushState;
            }

            var url = [location.protocol, '//', location.host, location.pathname].join('');

            //don't use dojo.connect anymore. Map object now supports on. Undocumented?
            on(map, "load", function() {
                var bookname = decodeURIComponent(document.location.search.slice(1).split(";")[0]);
                if (bookname)
                    bmModel.zoomBookmarkbyName(bookname);
            });

            //add a geocoder because it looks really nice and is useful!
            // create the geocoder
            var geocoder = new esri.dijit.Geocoder({ map: map }, "search"); geocoder.startup();

            //Now lets make it responsive!
            on(dojo.byId('responsiveMenuSearch'), "click", function () {
                domClass.toggle(dojo.byId('search'), 'hide');
            });
            on(dojo.byId('responsiveMenuSearchBookmark'), "click", function () {
                domClass.toggle(dojo.byId('bookmarks'), 'hide');
            });

        });
    })
<commit_msg>trying to remove 5 lines<commit_after>require(["dojo/ready", "dojo/on", "dojo/dom-class", "esri/map", "esri/dijit/Geocoder"],
    function (ready, on, domClass) {

        ready(function () {

            //Start map
            var options = {
                basemap: "streets", //streets | satellite | hybrid | topo | gray | oceans | national-geographic | osm.
                extent: new esri.geometry.Extent({
                    "xmin": -13094934.17795995,
                    "ymin": 3959049.5650010793,
                    "xmax": -12826640.20867888,
                    "ymax": 4053525.7319615935,
                    "spatialReference": { "wkid": 102100 }
                })
            };
            var map = new esri.Map("map", options);

            // Class to represent a bookmark
            function bookmarkEntry(name, extent) {
                this.name = name;
                this.extent = extent;
            }

            // View model for bookmark
            function boomarksModelModel() {
                var self = this;

                var bookmarks = JSON.parse(localStorage.getItem("myMapBookmarks"));
                if (!bookmarks) bookmarks = [new bookmarkEntry("Overview", options.extent.toJson())];

                // Editable data
                self.bookmarks = ko.observableArray(bookmarks);

                // stores the value the user enters
                self.current = ko.observable();

                //listen for enter
                self.addBookmarkEnter = function (model, event) {
                    var keyCode = (event.which ? event.which : event.keyCode);
                    if (keyCode === 13) {
                        self.addBookmark();
                    }
                    return true;
                };

                //add a new one
                self.addBookmark = function () {
                    self.bookmarks.push(new bookmarkEntry(self.current(), map.extent.toJson()));
                    self.current(''); //clear the current value
                    self.save();
                };

                //zoom to it. set up history
                self.zoomBookmark = function (item) {
                    map.setExtent(new esri.geometry.Extent(item.extent));
                    //Don't want to use #! and can't build urls because no control on back end
                    history.pushState(item.extent, document.title, url + "?" + item.name);
                };

                self.zoomBookmarkbyName = function (name) {
                    var bm = self.bookmarks().filter(function (item) {
                        return (item.name.toLowerCase() === name.toLowerCase());
                    });
                    if (!bm[0]) return;
                    self.zoomBookmark(bm[0]);
                };

                //remove it
                self.remove = function (item) {
                    self.bookmarks.remove(item);
                    self.save();
                };

                self.save = function () {
                    localStorage.setItem("myMapBookmarks", JSON.stringify(self.bookmarks()));
                };

            }

            //Create model and apply the bindings to the UI
            var bmModel = new boomarksModelModel();
            ko.applyBindings(bmModel);

            //Allow bookmarks to work with back/forward buttons
            //event for loading history
            window.addEventListener("popstate", function (evt) {
                if (evt.state) {
                    map.setExtent(new esri.geometry.Extent(evt.state));
                }
            });

            //insert polyfill here / get a better browser!
            if (!history.pushState) {
                history.pushState = function () { };
                history.replaceState = function () { };
            }

            var url = [location.protocol, '//', location.host, location.pathname].join('');

            history.pushState(options.extent, document.title, url + "?overview");
            //don't use dojo.connect anymore. Map object now supports on. Undocumented?
            on(map, "load", function () {
                var bookname = decodeURIComponent(document.location.search.slice(1).split(";")[0]);
                if (bookname)
                    bmModel.zoomBookmarkbyName(bookname);
            });

            //add a geocoder because it looks really nice and is useful!
            // create the geocoder
            var geocoder = new esri.dijit.Geocoder({ map: map }, "search"); geocoder.startup();

            //Now lets make it responsive!
            on(dojo.byId('responsiveMenuSearch'), "click", function () {
                domClass.toggle(dojo.byId('search'), 'hide');
            });
            on(dojo.byId('responsiveMenuSearchBookmark'), "click", function () {
                domClass.toggle(dojo.byId('bookmarks'), 'hide');
            });

        });
    })
<|endoftext|>