<commit_before>const rethinkdbdash = require("rethinkdbdash");
module.exports = {
	init: async () => {
		const publicConfig = JSON.parse(require("fs").readFileSync("public-config.json").toString());
		const privateConfig = JSON.parse(require("fs").readFileSync("private-config.json").toString());
		if(!privateConfig.database) {
			console.warn("No RethinkDB connection info in private-config.yml, Oxyl won't work as expected");
			return false;
		}

		let dbName = publicConfig.databaseName || "Oxyl";
		let connectionInfo = privateConfig.database;
		connectionInfo.silent = true;
		connectionInfo.db = dbName;
		const r = rethinkdbdash(connectionInfo); // eslint-disable-line id-length

		let dbs = await r.dbList().run();
		if(!~dbs.indexOf(dbName)) {
			console.info(`Creating database ${dbName}...`);
			await r.dbCreate(dbName).run();
		}

		let tableList = await r.tableList().run(), tableWait = [];
		let tablesExpected = [
			"autoRole", "blacklist", "censors", "donators", "editedCommands",
			"ignoredChannels", "locales", "modLog", "roleMe",
			"rolePersist", "savedQueues", "settings", "timedEvents", "warnings"
		];

		for(let table of tablesExpected) {
			if(!~tableList.indexOf(table)) {
				console.info(`Creating "${table}" table...`);
				await r.tableCreate(table).run();
			}
		}
		await Promise.all(tableWait);
		console.startup(`RethinkDB initated on master`);
		await r.poolMaster.drain();
		return true;
	},
	connect: async () => {
		if(!bot.privateConfig.database) return;

		let dbName = bot.publicConfig.databaseName || "Oxyl";
		let connectionInfo = bot.privateConfig.database;
		connectionInfo.silent = true;
		connectionInfo.db = dbName;
		global.r = rethinkdbdash(connectionInfo); // eslint-disable-line id-length

		let prefixes = await r.table("settings").filter({ name: "prefix" }).run();
		prefixes.forEach(setting => {
			let shard = ~~((setting.guildID / 4194304) % cluster.worker.maxShards);
			if(shard >= cluster.worker.shardStart && shard <= cluster.worker.shardEnd) {
				bot.prefixes.set(setting.guildID, setting.value);
			}
		});

		let censors = await r.table("censors").run();
		censors.forEach(censor => {
			let shard = ~~((censor.guildID / 4194304) % cluster.worker.maxShards);
			if(shard >= cluster.worker.shardStart && shard <= cluster.worker.shardEnd) {
				let censorsCache = bot.censors.get(censor.guildID);
				if(censorsCache) {
					censorsCache.set(censor.censorID, { action: censor.action, regex: censor.regex });
				} else {
					bot.censors.set(censor.guildID, new Map())
						.get(censor.guildID)
						.set(censor.censorID, { action: censor.action, regex: censor.regex });
				}
			}
		});

		let channels = await r.table("ignoredChannels").run();
		channels.forEach(ignored => {
			let shard = ~~((ignored.guildID / 4194304) % cluster.worker.maxShards);
			if(shard >= cluster.worker.shardStart && shard <= cluster.worker.shardEnd) {
				bot.ignoredChannels.set(ignored.channelID, ignored.guildID);
			}
		});

		let locales = await r.table("locales").run();
		locales.forEach(locale => bot.localeCache.set(locale.id, locale.locale));
	}
};

if(!cluster.isMaster) module.exports.connect();
<commit_msg>turn off pool for master<commit_after>const rethinkdbdash = require("rethinkdbdash");
module.exports = {
	init: async () => {
		const publicConfig = JSON.parse(require("fs").readFileSync("public-config.json").toString());
		const privateConfig = JSON.parse(require("fs").readFileSync("private-config.json").toString());
		if(!privateConfig.database) {
			console.warn("No RethinkDB connection info in private-config.yml, Oxyl won't work as expected");
			return false;
		}

		let dbName = publicConfig.databaseName || "Oxyl";
		let connectionInfo = privateConfig.database;
		connectionInfo.silent = true;
		connectionInfo.db = dbName;
		connectionInfo.pool = false;
		const r = rethinkdbdash(connectionInfo); // eslint-disable-line id-length

		let dbs = await r.dbList().run();
		if(!~dbs.indexOf(dbName)) {
			console.info(`Creating database ${dbName}...`);
			await r.dbCreate(dbName).run();
		}

		let tableList = await r.tableList().run(), tableWait = [];
		let tablesExpected = [
			"autoRole", "blacklist", "censors", "donators", "editedCommands",
			"ignoredChannels", "locales", "modLog", "roleMe",
			"rolePersist", "savedQueues", "settings", "timedEvents", "warnings"
		];

		for(let table of tablesExpected) {
			if(!~tableList.indexOf(table)) {
				console.info(`Creating "${table}" table...`);
				await r.tableCreate(table).run();
			}
		}
		await Promise.all(tableWait);
		console.startup(`RethinkDB initated on master`);
		await r.close();
		return true;
	},
	connect: async () => {
		if(!bot.privateConfig.database) return;

		let dbName = bot.publicConfig.databaseName || "Oxyl";
		let connectionInfo = bot.privateConfig.database;
		connectionInfo.silent = true;
		connectionInfo.db = dbName;
		global.r = rethinkdbdash(connectionInfo); // eslint-disable-line id-length

		let prefixes = await r.table("settings").filter({ name: "prefix" }).run();
		prefixes.forEach(setting => {
			let shard = ~~((setting.guildID / 4194304) % cluster.worker.maxShards);
			if(shard >= cluster.worker.shardStart && shard <= cluster.worker.shardEnd) {
				bot.prefixes.set(setting.guildID, setting.value);
			}
		});

		let censors = await r.table("censors").run();
		censors.forEach(censor => {
			let shard = ~~((censor.guildID / 4194304) % cluster.worker.maxShards);
			if(shard >= cluster.worker.shardStart && shard <= cluster.worker.shardEnd) {
				let censorsCache = bot.censors.get(censor.guildID);
				if(censorsCache) {
					censorsCache.set(censor.censorID, { action: censor.action, regex: censor.regex });
				} else {
					bot.censors.set(censor.guildID, new Map())
						.get(censor.guildID)
						.set(censor.censorID, { action: censor.action, regex: censor.regex });
				}
			}
		});

		let channels = await r.table("ignoredChannels").run();
		channels.forEach(ignored => {
			let shard = ~~((ignored.guildID / 4194304) % cluster.worker.maxShards);
			if(shard >= cluster.worker.shardStart && shard <= cluster.worker.shardEnd) {
				bot.ignoredChannels.set(ignored.channelID, ignored.guildID);
			}
		});

		let locales = await r.table("locales").run();
		locales.forEach(locale => bot.localeCache.set(locale.id, locale.locale));
	}
};

if(!cluster.isMaster) module.exports.connect();
<|endoftext|>


<commit_before>'use strict'

import {
  Card,
  Component,
  Container,
  View,
  Button,
  Text,
  Snackbar
} from 'material'

// controls

/**
 * [initTest description]
 * @return {[type]} [description]
 */
export default function (body) {
  var view = new View({
    name: 'snackbar'
  }).insert(body)

  var hero = new Container({
    name: 'hero'
  }).insert(view)

  var container = new Container({
    name: 'card'
  }).insert(view)

  new Snackbar({
    layout: [Component, 'content', { display: 'flex', direction: 'horizontal' },
      [Text, 'text', {text: 'Message sent'}],
      [Button, 'undo', { text: 'undo' }]
    ]
  }).insert(hero)

  var layout = [Component, 'content', { display: 'flex', direction: 'horizontal' },
    [Text, 'text', { flex: '1', text: 'Message sent'}],
    [Button, 'undo', { flex: 'none', text: 'undo' }]
  ]

  new Button({
    text: 'show'
  }).insert(container).on('click', () => {
    var snackbar = new Snackbar({
      layout: layout
    }).insert(document.body)

    console.log('snack', snackbar)
  })
};
<commit_msg>update snackbar view<commit_after>'use strict'

import {
  Card,
  Component,
  Container,
  View,
  Button,
  Text,
  Snackbar
} from 'material'

// controls

/**
 * [initTest description]
 * @return {[type]} [description]
 */
export default function (body) {
  var view = new View({
    name: 'snackbar'
  }).insert(body)

  var hero = new Container({
    name: 'hero'
  }).insert(view)

  var container = new Container({
    name: 'card'
  }).insert(view)

  var layout = [Component, 'content', { display: 'flex', direction: 'horizontal' },
    [Text, 'text', { flex: '1', text: 'Message sent'}],
    [Button, 'undo', { flex: 'none', text: 'undo' }]
  ]

  new Snackbar({
    layout: layout,
    delay: 0
  }).insert(hero)

  new Button({
    text: 'show'
  }).insert(container).on('click', () => {
    var sb = new Snackbar({
      layout: layout
    }).insert(document.body)

    sb.layout.get('undo').on('click', () => {
      console.log('undo')
    })
  })
};
<|endoftext|>


<commit_before>/** File: template.js
 * Candy - Chats are not dead yet.
 *
 * Authors:
 *   - Patrick Stadler <patrick.stadler@gmail.com>
 *   - Michael Weibel <michael.weibel@gmail.com>
 *
 * Copyright:
 *   (c) 2011 Amiado Group AG. All rights reserved.
 *   (c) 2012-2014 Patrick Stadler & Michael Weibel. All rights reserved.
 */
'use strict';

/* global Candy */

/** Class: Candy.View.Template
 * Contains mustache.js templates
 */
Candy.View.Template = (function(self){
	self.Window = {
		/**
		 * Unread messages - used to extend the window title
		 */
		unreadmessages: '({{count}}) {{title}}'
	};

	self.Chat = {
		pane: '
{{> tabs}}{{> toolbar}}{{> rooms}}
{{> modal}}',
		rooms: '

',
		tabs: '

',
		tab: '
' +
				'{{#privateUserChat}}@{{/privateUserChat}}{{name}}' +
				'\u00D7' +
				'
',
		modal: '
\u00D7' +
				'' +
				'' +
				'

',
		adminMessage: '
{{time}}
' +
				'{{sender}}' +
				'▸{{subject}} {{message}}

',
		infoMessage: '
{{time}}
' +
				'•{{subject}} {{message}}

',
		toolbar: '
' +
				'

' +
				'
{{> soundcontrol}}
' +
				'

' +
				'
' +
				'

' +
				'
' +
				'

',
		soundcontrol: '<object id="chat-sound-player" type="application/x-shockwave-flash" data="{{assetsPath}}audioplayer.swf"' +
						' width="0" height="0"><param name="movie" value="{{assetsPath}}audioplayer.swf" /><param name="AllowScriptAccess"' +
						' value="always" /><param name="FlashVars" value="listener=audioplayerListener&mp3={{assetsPath}}notify.mp3" />' +
						'</object>',
		Context: {
			menu: '
' +
				'

',
			menulinks: '
{{label}}
',
			contextModalForm: '<form action="#" id="context-modal-form">' +
							'{{_label}}' +
							'<input type="text" name="contextModalField" id="context-modal-field" />' +
							'<input type="submit" class="button" name="send" value="{{_submit}}" /></form>',
			adminMessageReason: '×' +
							'
{{_action}}
{{#reason}}
{{_reason}}
{{/reason}}'
		},
		tooltip: '
' +
					'

'
	};

	self.Room = {
		pane: '
' +
			'{{> roster}}{{> messages}}{{> form}}
',
		subject: '
{{time}}
' +
				'{{roomName}}' +
				'▸{{_roomSubject}} {{{subject}}}

',
		form: '
' +
				'<form method="post" class="message-form">' +
				'<input name="message" class="field" type="text" aria-label="Message Form Text Field" autocomplete="off" maxlength="1000" />' +
				'<input type="submit" class="submit" name="submit" value="{{_messageSubmit}}" /></form>
'
	};

	self.Roster = {
		pane: '

',
		user: '
' +
				'
{{displayNick}}

' +
				'
▾
' +
				'

' +
				'

'
	};

	self.Message = {
		pane: '

',
		item: '
{{time}}
' +
				'{{displayName}}' +
				'▸{{{message}}}

'
	};

	self.Login = {
		form: '<form method="post" id="login-form" class="login-form">' +
			'{{#displayNickname}}{{_labelNickname}}<input type="text" id="username" name="username"/>{{/displayNickname}}' +
			'{{#displayUsername}}{{_labelUsername}}' +
			'<input type="text" id="username" name="username"/>' +
			'{{#displayDomain}} @ ' +
			'<select id="domain" name="domain">{{#domains}}<option value="{{domain}}">{{domain}}</option>{{/domains}}</select>' +
			'{{/displayDomain}}' +
			'{{/displayUsername}}' +
			'{{#presetJid}}<input type="hidden" id="username" name="username" value="{{presetJid}}"/>{{/presetJid}}' +
			'{{#displayPassword}}{{_labelPassword}}' +
			'<input type="password" id="password" name="password" />{{/displayPassword}}' +
			'<input type="submit" class="button" value="{{_loginSubmit}}" /></form>'
	};

	self.PresenceError = {
		enterPasswordForm: '{{_label}}' +
			'<form method="post" id="enter-password-form" class="enter-password-form">' +
			'{{_labelPassword}}<input type="password" id="password" name="password" />' +
			'<input type="submit" class="button" value="{{_joinSubmit}}" /></form>',
		nicknameConflictForm: '{{_label}}' +
			'<form method="post" id="nickname-conflict-form" class="nickname-conflict-form">' +
			'{{_labelNickname}}<input type="text" id="nickname" name="nickname" />' +
			'<input type="submit" class="button" value="{{_loginSubmit}}" /></form>',
		displayError: '{{_error}}'
	};

	return self;
}(Candy.View.Template || {}));
<commit_msg>Allow links to render correctly in adminMessage and infoMessage<commit_after>/** File: template.js
 * Candy - Chats are not dead yet.
 *
 * Authors:
 *   - Patrick Stadler <patrick.stadler@gmail.com>
 *   - Michael Weibel <michael.weibel@gmail.com>
 *
 * Copyright:
 *   (c) 2011 Amiado Group AG. All rights reserved.
 *   (c) 2012-2014 Patrick Stadler & Michael Weibel. All rights reserved.
 */
'use strict';

/* global Candy */

/** Class: Candy.View.Template
 * Contains mustache.js templates
 */
Candy.View.Template = (function(self){
	self.Window = {
		/**
		 * Unread messages - used to extend the window title
		 */
		unreadmessages: '({{count}}) {{title}}'
	};

	self.Chat = {
		pane: '
{{> tabs}}{{> toolbar}}{{> rooms}}
{{> modal}}',
		rooms: '

',
		tabs: '

',
		tab: '
' +
				'{{#privateUserChat}}@{{/privateUserChat}}{{name}}' +
				'\u00D7' +
				'
',
		modal: '
\u00D7' +
				'' +
				'' +
				'

',
		adminMessage: '
{{time}}
' +
				'{{sender}}' +
				'▸{{subject}} {{{message}}}

',
		infoMessage: '
{{time}}
' +
				'•{{subject}} {{{message}}}

',
		toolbar: '
' +
				'

' +
				'
{{> soundcontrol}}
' +
				'

' +
				'
' +
				'

' +
				'
' +
				'

',
		soundcontrol: '<object id="chat-sound-player" type="application/x-shockwave-flash" data="{{assetsPath}}audioplayer.swf"' +
						' width="0" height="0"><param name="movie" value="{{assetsPath}}audioplayer.swf" /><param name="AllowScriptAccess"' +
						' value="always" /><param name="FlashVars" value="listener=audioplayerListener&mp3={{assetsPath}}notify.mp3" />' +
						'</object>',
		Context: {
			menu: '
' +
				'

',
			menulinks: '
{{label}}
',
			contextModalForm: '<form action="#" id="context-modal-form">' +
							'{{_label}}' +
							'<input type="text" name="contextModalField" id="context-modal-field" />' +
							'<input type="submit" class="button" name="send" value="{{_submit}}" /></form>',
			adminMessageReason: '×' +
							'
{{_action}}
{{#reason}}
{{_reason}}
{{/reason}}'
		},
		tooltip: '
' +
					'

'
	};

	self.Room = {
		pane: '
' +
			'{{> roster}}{{> messages}}{{> form}}
',
		subject: '
{{time}}
' +
				'{{roomName}}' +
				'▸{{_roomSubject}} {{{subject}}}

',
		form: '
' +
				'<form method="post" class="message-form">' +
				'<input name="message" class="field" type="text" aria-label="Message Form Text Field" autocomplete="off" maxlength="1000" />' +
				'<input type="submit" class="submit" name="submit" value="{{_messageSubmit}}" /></form>
'
	};

	self.Roster = {
		pane: '

',
		user: '
' +
				'
{{displayNick}}

' +
				'
▾
' +
				'

' +
				'

'
	};

	self.Message = {
		pane: '

',
		item: '
{{time}}
' +
				'{{displayName}}' +
				'▸{{{message}}}

'
	};

	self.Login = {
		form: '<form method="post" id="login-form" class="login-form">' +
			'{{#displayNickname}}{{_labelNickname}}<input type="text" id="username" name="username"/>{{/displayNickname}}' +
			'{{#displayUsername}}{{_labelUsername}}' +
			'<input type="text" id="username" name="username"/>' +
			'{{#displayDomain}} @ ' +
			'<select id="domain" name="domain">{{#domains}}<option value="{{domain}}">{{domain}}</option>{{/domains}}</select>' +
			'{{/displayDomain}}' +
			'{{/displayUsername}}' +
			'{{#presetJid}}<input type="hidden" id="username" name="username" value="{{presetJid}}"/>{{/presetJid}}' +
			'{{#displayPassword}}{{_labelPassword}}' +
			'<input type="password" id="password" name="password" />{{/displayPassword}}' +
			'<input type="submit" class="button" value="{{_loginSubmit}}" /></form>'
	};

	self.PresenceError = {
		enterPasswordForm: '{{_label}}' +
			'<form method="post" id="enter-password-form" class="enter-password-form">' +
			'{{_labelPassword}}<input type="password" id="password" name="password" />' +
			'<input type="submit" class="button" value="{{_joinSubmit}}" /></form>',
		nicknameConflictForm: '{{_label}}' +
			'<form method="post" id="nickname-conflict-form" class="nickname-conflict-form">' +
			'{{_labelNickname}}<input type="text" id="nickname" name="nickname" />' +
			'<input type="submit" class="button" value="{{_loginSubmit}}" /></form>',
		displayError: '{{_error}}'
	};

	return self;
}(Candy.View.Template || {}));
<|endoftext|>


<commit_before>export function alertStuff() {
  alert('hi stuff');
}

<commit_msg>moving stuff<commit_after><|endoftext|>


<commit_before>#!/usr/bin/env node

var resolve = require('resolve');
var path = require('path');
var fs = require('fs');

if (process.argv.length !== 3) {
  throw new Error("Need exactly one arg to reasonLoadEnv.js");
}

var curDir = process.argv.slice(2)[0];

const KEYS = [
  'dependencies',
  'peerDependencies',
];
var visited = {};

function resolveDep(dependency, dirs) {
    for (var dir of dirs) {
        try {
            return resolve.sync(
                path.join(dependency, 'package.json'),
                {basedir: dir}
            );
        } catch (err) { }
    }
    throw "cannot find " + dependency + " in " + dirs;
}

function traverseSync(filename, handler) {
  const pkg = JSON.parse(
    fs.readFileSync(filename, 'utf8')
  );
  handler(filename, pkg);
  KEYS.forEach(function(key) {
    Object.keys(
      pkg[key] || {}
    ).forEach(function(dependency) {
      var pJson = path.join(dependency, 'package.json');
      if (!visited[pJson]) {
        try {
          const resolved = resolveDep(dependency, [curDir, path.dirname(filename)]);
          // We won't traverse transitive dependencies because this is to be used
          // only post installation, for the sake of building, and also because
          // you shouldn't be *able* to rely on binaries or environment variables
          // from dependencies you didn't model.
          visited[pJson] = true;
          traverseSync(resolved, handler);
          //
          // We might want to allow two modes, however - so that transitive
          // dependencies can build up paths for linking etc.  But if we go that
          // far, you probably want to use a custom build system anyways.
        } catch (err) {
          // We are forgiving on optional dependencies -- if we can't find them,
          // just skip them
          if (pkg["optionalDependencies"] && pkg["optionalDependencies"][dependency]) {
            return;
          }
          throw err;
        }
      }
    });
  });
}

var cmds = [];
var seenVars = {};

function traverse(filePath, packageJson) {
  var packageJsonDir = path.dirname(filePath);
  var envPaths = packageJson.exportedEnvVars;
  var packageName = packageJson.name;
  var envVarScopePrefix =
    packageName.replace(new RegExp("\-", "g"), function(s){return "_";}).toUpperCase() + "__";
  for (var envVar in envPaths) {
    if (!envPaths.hasOwnProperty(envVar)) {
      continue;
    }

    var errorPrefix = "environment variable " + envVar + " from dependency package " + filePath;
    var config = envPaths[envVar];
    if (!config.global) {
      if (envVar.indexOf(envVarScopePrefix) !== 0) {
        throw new Error(
          errorPrefix +
            " doesn't begin with " + envVarScopePrefix + " yet it is not marked as 'global'. The package" +
            "owner for " + packageName + " likely made a mistake."
        );
      }
    } else {
      // Else, it's global, but better not be trying to step on another package!
      if (envVar.indexOf("__") !== -1) {
        throw new Error(
          errorPrefix +
            " is a global environment variable, but it looks like it's trying to step on a " +
            " package because it has a double underscore - which is how we express namespaced env vars." +
            "The package owner for " + packageName + " likely made a mistake."
        );
      }
    }
    var normalizedVal = config.resolveAsRelativePath ? path.resolve(packageJsonDir, config.val) : config.val;

    // The seenVars will only cover the cases when another package declares the variable, not when it's loaded
    // from your bashrc etc.
    if (seenVars[envVar] && (config.globalCollisionBehavior === 'fail' || config.globalCollisionBehavior == null)) {
      throw new Error(
        errorPrefix +
          " is a global environment variable that has already been set by some other package and " +
          "it is configured with " +
          "globalCollisionBehavior='fail' (which is the default behavior)."
      );
    }
    if (config.globalCollisionBehavior === 'fail' ||
        config.globalCollisionBehavior == null ||
        config.globalCollisionBehavior === 'clobber') {
      cmds.push("export " + envVar + '="' + normalizedVal + '"');
    } else if (config.globalCollisionBehavior === 'joinPath') {
      cmds.push("export " + envVar + '="' + normalizedVal + ":$" + envVar + '"');
    } else {
      throw new Error(
        errorPrefix +
          " is configured with an unknown globalCollisionBehavior:" +
          config.globalCollisionBehavior + "."
      );
    }
    seenVars[envVar] = true;
  }
}

try {
  traverseSync(path.join(curDir, 'package.json'), traverse);
} catch (err) {
  if (err.code === 'ENOENT') {
    console.error("Fail to find package.json!: " + err.message);
  } else {
    throw err;
  }
}
console.log(cmds.join(" && "));

/**
 * TODO: Cache this result on disk in a .reasonLoadEnvCache so that we don't
 * have to repeat this process.
 */
<commit_msg>Some minor cleanup/variable renames.<commit_after>#!/usr/bin/env node

var resolve = require('resolve');
var path = require('path');
var fs = require('fs');

if (process.argv.length !== 3) {
  throw new Error("Need exactly one arg to reasonLoadEnv.js");
}

var curDir = process.argv.slice(2)[0];

const KEYS = [
  'dependencies',
  'peerDependencies',
];
var visited = {};

function resolveDep(dependency, dirs) {
    for (var dir of dirs) {
        try {
            return resolve.sync(
                path.join(dependency, 'package.json'),
                {basedir: dir}
            );
        } catch (err) { }
    }
    throw "cannot find " + dependency + " in " + dirs;
}

function traverseSync(absolutePathToPackageJson, handler) {
  const pkg = JSON.parse(
    fs.readFileSync(absolutePathToPackageJson, 'utf8')
  );
  handler(absolutePathToPackageJson, pkg);
  KEYS.forEach(function(key) {
    Object.keys(
      pkg[key] || {}
    ).forEach(function(dependencyName) {
      if (!visited[dependencyName]) {
        try {
          const resolved = resolveDep(dependencyName, [curDir, path.dirname(absolutePathToPackageJson)]);
          // We won't traverse transitive dependencies because this is to be used
          // only post installation, for the sake of building, and also because
          // you shouldn't be *able* to rely on binaries or environment variables
          // from dependencies you didn't model.
          visited[dependencyName] = true;
          traverseSync(resolved, handler);
          //
          // We might want to allow two modes, however - so that transitive
          // dependencies can build up paths for linking etc.  But if we go that
          // far, you probably want to use a custom build system anyways.
        } catch (err) {
          // We are forgiving on optional dependencies -- if we can't find them,
          // just skip them
          if (pkg["optionalDependencies"] && pkg["optionalDependencies"][dependencyName]) {
            return;
          }
          throw err;
        }
      }
    });
  });
}

var cmds = [];
var seenVars = {};

function traverse(filePath, packageJson) {
  var packageJsonDir = path.dirname(filePath);
  var envPaths = packageJson.exportedEnvVars;
  var packageName = packageJson.name;
  var envVarScopePrefix =
    packageName.replace(new RegExp("\-", "g"), function(s){return "_";}).toUpperCase() + "__";
  for (var envVar in envPaths) {
    if (!envPaths.hasOwnProperty(envVar)) {
      continue;
    }

    var errorPrefix = "environment variable " + envVar + " from dependency package " + filePath;
    var config = envPaths[envVar];
    if (!config.global) {
      if (envVar.indexOf(envVarScopePrefix) !== 0) {
        throw new Error(
          errorPrefix +
            " doesn't begin with " + envVarScopePrefix + " yet it is not marked as 'global'. The package" +
            "owner for " + packageName + " likely made a mistake."
        );
      }
    } else {
      // Else, it's global, but better not be trying to step on another package!
      if (envVar.indexOf("__") !== -1) {
        throw new Error(
          errorPrefix +
            " is a global environment variable, but it looks like it's trying to step on a " +
            " package because it has a double underscore - which is how we express namespaced env vars." +
            "The package owner for " + packageName + " likely made a mistake."
        );
      }
    }
    var normalizedVal = config.resolveAsRelativePath ? path.resolve(packageJsonDir, config.val) : config.val;

    // The seenVars will only cover the cases when another package declares the variable, not when it's loaded
    // from your bashrc etc.
    if (seenVars[envVar] && (config.globalCollisionBehavior === 'fail' || config.globalCollisionBehavior == null)) {
      throw new Error(
        errorPrefix +
          " is a global environment variable that has already been set by some other package and " +
          "it is configured with " +
          "globalCollisionBehavior='fail' (which is the default behavior)."
      );
    }
    if (config.globalCollisionBehavior === 'fail' ||
        config.globalCollisionBehavior == null ||
        config.globalCollisionBehavior === 'clobber') {
      cmds.push("export " + envVar + '="' + normalizedVal + '"');
    } else if (config.globalCollisionBehavior === 'joinPath') {
      cmds.push("export " + envVar + '="' + normalizedVal + ":$" + envVar + '"');
    } else {
      throw new Error(
        errorPrefix +
          " is configured with an unknown globalCollisionBehavior:" +
          config.globalCollisionBehavior + "."
      );
    }
    seenVars[envVar] = true;
  }
}

try {
  traverseSync(path.join(curDir, 'package.json'), traverse);
} catch (err) {
  if (err.code === 'ENOENT') {
    console.error("Fail to find package.json!: " + err.message);
  } else {
    throw err;
  }
}
console.log(cmds.join(" && "));

/**
 * TODO: Cache this result on disk in a .reasonLoadEnvCache so that we don't
 * have to repeat this process.
 */
<|endoftext|>


<commit_before>import DialogNew from '../shared/dialog(new)';
import WaitCursor from '../shared/wait-cursor';
import FloatingButton from '../shared/floating-button';
import {argbHexToRgba} from '../shared/utils/convert';
import {getWindowMetrics} from '../shared/utils/helper';

let dateType = {
    DATE: 1,
    TIME: 2,
    DATE_TIME: 3
};

// JsonCalls

(function (jsonCalls) {

    //m[<ActionID>] = m.<ActionName> = function ...
    //==> JsonCalls.ActionName(); || JsonCalls[5]();

    jsonCalls[1] = jsonCalls.ToggleWaitCursor = function (value, srcIframe) {
        if (value.enabled) {
            WaitCursor.show(value.timeout, value.text, srcIframe[0]);
            return;
        }
        WaitCursor.hide(srcIframe[0]);
    };

    jsonCalls[2] = jsonCalls.SelectTab = function (value, srcIframe) {
        FloatingButton.hide(srcIframe[0]);

        //noinspection Eslint
        if (value.params && Array === value.params.constructor) {
            value.params = '?' + value.params.join('&');
        }

        window.ChaynsWeb.SelectTapp(value);
    };

    jsonCalls[16] = jsonCalls.ShowDialog = function (value, srcIframe) {
        if (value.dialog === undefined) {
            jsonCalls.Helper.throw(16, 2, 'Field dialog missing.', value, srcIframe);
            return;
        }
        if ((value.dialog.buttons || []).length === 0) {
            jsonCalls.Helper.throw(16, 2, 'Field dialog.buttons missing.', value, srcIframe);
            return;
        }

        value.dialog.callback = (buttonType) => jsonCalls.Helper.return(value, buttonType, srcIframe);

        DialogNew.show('alert', value.dialog);
    };

    jsonCalls[18] = jsonCalls.GetGlobalData = function (value, srcIframe) {
        let data = window.ChaynsInfo.getGlobalData();
        jsonCalls.Helper.return(value, data, srcIframe);
    };

    jsonCalls[30] = jsonCalls.DateTimePicker = function (value, srcIframe) {
        if (!value.dialog) {
            value.dialog = {}
        }

        value.dialog.selectedDate = (value.selectedDate === -1) ? null : value.selectedDate;
        value.dialog.minDate = (value.minDate === -1) ? null : value.minDate;
        value.dialog.maxDate = (value.maxDate === -1) ? null : value.maxDate;
        value.dialog.callback = (ret) => jsonCalls.Helper.return(value, ret, srcIframe);

        let dialogType;
        switch (value.type) {
            case dateType.DATE_TIME:
                dialogType = 'dateTime';
                break;
            case dateType.DATE:
                dialogType = 'date';
                break;
            case dateType.TIME:
                dialogType = 'time';
                break;
            default:
                dialogType = 'dateTime';
        }

        DialogNew.show(dialogType, value.dialog);
    };

    jsonCalls[50] = jsonCalls.MultiSelectDialog = function (value, srcIframe) {
        if (value.dialog === undefined) {
            jsonCalls.Helper.throw(50, 2, 'Field dialog missing.', value, srcIframe);
            return;
        }
        if ((value.dialog.buttons || []).length === 0) {
            jsonCalls.Helper.throw(50, 2, 'Field dialog.buttons missing.', value, srcIframe);
            return;
        }
        if ((value.list || []).length === 0) {
            jsonCalls.Helper.throw(50, 2, 'Field list missing.', value, srcIframe);
            return;
        }

        value.dialog.list = value.list;
        value.dialog.callback = (retVal) => jsonCalls.Helper.return(value, retVal, srcIframe);

        DialogNew.show('select', value.dialog);
    };

    jsonCalls[72] = jsonCalls.ShowFloatingButton = function (value, srcIfame) {
        jsonCalls.Helper.RemoveJsonCallEventListener(72);
        if (value.enabled) {
            var bgColor = argbHexToRgba(value.color);
            bgColor = bgColor ? `rgba(${bgColor.r}, ${bgColor.g}, ${bgColor.b}, ${bgColor.a})` : '';
            //noinspection JSUnresolvedVariable
            var color = argbHexToRgba(value.colorText);
            color = color ? `rgba(${color.r}, ${color.g}, ${color.b}, ${color.a})` : '';
            var text;
            if ('text' in value) {
                text = value.text;
            } else if ('icon' in value) {
                text = `<span class='fa ${value.icon}'></span>`;
            } else {
                text = '!';
            }
            FloatingButton.show(text, srcIfame[0], bgColor, color);
            jsonCalls.Helper.AddJsonCallEventListener(72, value, srcIfame);
        } else {
            FloatingButton.hide(srcIfame[0]);
        }
    };

    jsonCalls[75] = jsonCalls.AddChaynsCallErrorListener = function (value, srcIframe) {
        jsonCalls.Helper.AddJsonCallEventListener(75, value, srcIframe);
    };

    jsonCalls[77] = jsonCalls.SetIframeHeigth = function (value, srcIframe) {
        //noinspection JSUnresolvedVariable
        if (window.ChaynsInfo.IsFacebook && window.FB) {
            setTimeout(function () {
                //noinspection JSUnresolvedVariable,JSUnresolvedFunction
                window.FB.Canvas.setSize({
                    'height': $(document.body).height()
                });
            }, 500);
        }

        let $iframe = srcIframe;

        if (!value.full && !('height' in value) && !('fullViewport' in value)) {
            jsonCalls.Helper.throw(77, 2, 'Field height missing.', value, srcIframe);
            return;
        } else if (value.full) {
            value.height = getWindowMetrics().AvailHeight;
        } else if (value.fullViewport) {
            let $NavItems = $('#NavItems');
            let $PageHead = $('#PageHead');
            let navHeight = $NavItems.height();
            let maxHeight = $NavItems.height() + 45;
            let headerHeight = $PageHead.height() + ($('.domainOfferAttention').outerHeight() || 0);
            let pageheadHeight = $PageHead.height() + $('#TitleConnect').height() + 50;
            let minHeight = $(window).height() - headerHeight - 35;
            let h, margin;

            $('#BodyContent').css('margin-bottom', '0px');
            $('#BodyContentCell').css('padding-bottom', '0px');
            value.height = $(window.top).height() + $(window).scrollTop() - $PageHead.height() - $('#TitleConnectSites').height() - 30;
            if (value.height > $(window.top).height()) {
                value.height = $(window.top).height();
            }
            $iframe.height(value.height);
            $(window).bind('scroll', function () {
                if (minHeight > maxHeight) {
                    maxHeight = minHeight;
                }

                h = minHeight + $(window).scrollTop();

                if (h > maxHeight) {
                    h = maxHeight;
                } else {
                    h = h - 25;
                }

                if (h < $(window).height() - 28) {
                    $iframe.height(h);
                    $iframe.css('margin-top', -35);
                } else {
                    margin = $(window).scrollTop() - pageheadHeight;
                    if (margin + $iframe.height() <= navHeight + 65) {
                        $iframe.css('margin-top', margin);
                        $iframe.height($(window).height());
                    }
                }
            });
        } else {
            value.height = parseInt(value.height, 10);
        }

        if (isNaN(value.height)) {
            jsonCalls.Helper.throw(77, 1, 'Field heigth is not typeof number', value, srcIframe);
            return;
        }

        value.growOnly = value.growOnly !== false; // true als default

        if ($iframe && (!value.growOnly || $iframe[0].style.height < value.height)) {
            $iframe[0].style.height = value.height;
        }

        // if (window.positionFloatingButton) {
        //     window.positionFloatingButton();
        // }
    };

    jsonCalls[103] = jsonCalls.ShowDialog = function (value, srcIframe) {
        if (value.dialog === undefined) {
            jsonCalls.Helper.throw(103, 2, 'Field dialog missing.', value, srcIframe);
            return;
        }
        if ((value.dialog.buttons || []).length === 0) {
            jsonCalls.Helper.throw(103, 2, 'Field dialog.buttons missing.', value, srcIframe);
            return;
        }

        value.dialog.callback = (retVal) => jsonCalls.Helper.return(value, retVal, srcIframe);

        DialogNew.show('input', value.dialog);
    };

})(window.JsonCalls = window.JsonCalls || {});

// JsonCalls.Helper
(function (m) {
    var jsonCallEventListener = [];

    m.AddJsonCallEventListener = function (action, request, srcIframe) {
        jsonCallEventListener.push({
            action: action,
            callback: request.callback,
            addJSONParam: request.addJSONParam,
            srcIframe: srcIframe
        });
    };

    /**
     * @return {boolean}
     */
    m.DispatchJsonCallEvent = function (action, response, destIframe) {
        var retVal = false;

        jsonCallEventListener.forEach(function (listener) {
            if ((listener.action !== action) || (destIframe && listener.srcIframe !== destIframe)) {
                return;
            }
            if (!destIframe) {
                destIframe = listener.srcIframe;
            }
            window.CustomTappCommunication.AnswerJsonCall(listener, response, destIframe);
            retVal = true;
        });

        return retVal;
    };

    m.RemoveJsonCallEventListener = function (action, callback) {
        jsonCallEventListener = jsonCallEventListener.filter(function (listener) {
            if (listener.action === action) {
                return !(!callback || listener.callback === callback);
            }
            return true;
        });
    };

    m.throw = function (action, code, message, request, srcIframe) {
        var retVal = {
            action: action,
            errorCode: code,
            message: message,
            value: request
        };
        m.DispatchJsonCallEvent(75, retVal, srcIframe);
    };

    m.return = window.CustomTappCommunication.AnswerJsonCall;

    /**
     * @return {number}
     */
    m.EncodeDialogButtonTypes = function (type) {
        return type <= 0 ? type - 10 : type;
    };

    /**
     * @return {number}
     */
    m.DecodeDialogButtonTypes = function (type) {
        return type <= -10 ? type + 10 : type;
    };

    m.GeoWatchNumber = null;

    m.OverlayCloseParam = {};

    m.Throttle = function (fn, threshhold, scope) {
        threshhold = threshhold ? threshhold : 250;
        var last,
            deferTimer;
        return function () {
            var context = scope || this;

            var now = +new Date,
                args = arguments;
            if (last && now < last + threshhold) {
                // hold on to it
                clearTimeout(deferTimer);
                deferTimer = setTimeout(function () {
                    last = now;
                    fn.apply(context, args);
                }, threshhold);
            } else {
                last = now;
                fn.apply(context, args);
            }
        };
    };
})(window.JsonCalls.Helper = window.JsonCalls.Helper || {});<commit_msg>adds json call 54 tobit login<commit_after>import DialogNew from '../shared/dialog(new)';
import WaitCursor from '../shared/wait-cursor';
import FloatingButton from '../shared/floating-button';
import {argbHexToRgba} from '../shared/utils/convert';
import {getWindowMetrics} from '../shared/utils/helper';

let dateType = {
    DATE: 1,
    TIME: 2,
    DATE_TIME: 3
};

// JsonCalls

(function (jsonCalls) {

    //m[<ActionID>] = m.<ActionName> = function ...
    //==> JsonCalls.ActionName(); || JsonCalls[5]();

    jsonCalls[1] = jsonCalls.ToggleWaitCursor = function (value, srcIframe) {
        if (value.enabled) {
            WaitCursor.show(value.timeout, value.text, srcIframe[0]);
            return;
        }
        WaitCursor.hide(srcIframe[0]);
    };

    jsonCalls[2] = jsonCalls.SelectTab = function (value, srcIframe) {
        FloatingButton.hide(srcIframe[0]);

        //noinspection Eslint
        if (value.params && Array === value.params.constructor) {
            value.params = '?' + value.params.join('&');
        }

        window.ChaynsWeb.SelectTapp(value);
    };

    jsonCalls[16] = jsonCalls.ShowDialog = function (value, srcIframe) {
        if (value.dialog === undefined) {
            jsonCalls.Helper.throw(16, 2, 'Field dialog missing.', value, srcIframe);
            return;
        }
        if ((value.dialog.buttons || []).length === 0) {
            jsonCalls.Helper.throw(16, 2, 'Field dialog.buttons missing.', value, srcIframe);
            return;
        }

        value.dialog.callback = (buttonType) => jsonCalls.Helper.return(value, buttonType, srcIframe);

        DialogNew.show('alert', value.dialog);
    };

    jsonCalls[18] = jsonCalls.GetGlobalData = function (value, srcIframe) {
        let data = window.ChaynsInfo.getGlobalData();
        jsonCalls.Helper.return(value, data, srcIframe);
    };

    jsonCalls[30] = jsonCalls.DateTimePicker = function (value, srcIframe) {
        if (!value.dialog) {
            value.dialog = {}
        }

        value.dialog.selectedDate = (value.selectedDate === -1) ? null : value.selectedDate;
        value.dialog.minDate = (value.minDate === -1) ? null : value.minDate;
        value.dialog.maxDate = (value.maxDate === -1) ? null : value.maxDate;
        value.dialog.callback = (ret) => jsonCalls.Helper.return(value, ret, srcIframe);

        let dialogType;
        switch (value.type) {
            case dateType.DATE_TIME:
                dialogType = 'dateTime';
                break;
            case dateType.DATE:
                dialogType = 'date';
                break;
            case dateType.TIME:
                dialogType = 'time';
                break;
            default:
                dialogType = 'dateTime';
        }

        DialogNew.show(dialogType, value.dialog);
    };

    jsonCalls[50] = jsonCalls.MultiSelectDialog = function (value, srcIframe) {
        if (value.dialog === undefined) {
            jsonCalls.Helper.throw(50, 2, 'Field dialog missing.', value, srcIframe);
            return;
        }
        if ((value.dialog.buttons || []).length === 0) {
            jsonCalls.Helper.throw(50, 2, 'Field dialog.buttons missing.', value, srcIframe);
            return;
        }
        if ((value.list || []).length === 0) {
            jsonCalls.Helper.throw(50, 2, 'Field list missing.', value, srcIframe);
            return;
        }

        value.dialog.list = value.list;
        value.dialog.callback = (retVal) => jsonCalls.Helper.return(value, retVal, srcIframe);

        DialogNew.show('select', value.dialog);
    };

    jsonCalls[54] = jsonCalls.TobitLogin = function (value) {
        if ((value.urlParams || []).length) {
            window.Login.setReloadParams(value.urlParams);
        }

        if ((value.fbPermissions || []).length) {
            window.Login.facebookLogin(false, value.fbPermissions.join(','));
        } else {
            if (!window.ChaynsInfo.IsFacebook) {
                window.Login.showDialog();
            } else {
                window.Login.facebookLogin();
            }
        }
    };

    jsonCalls[72] = jsonCalls.ShowFloatingButton = function (value, srcIfame) {
        jsonCalls.Helper.RemoveJsonCallEventListener(72);
        if (value.enabled) {
            var bgColor = argbHexToRgba(value.color);
            bgColor = bgColor ? `rgba(${bgColor.r}, ${bgColor.g}, ${bgColor.b}, ${bgColor.a})` : '';
            //noinspection JSUnresolvedVariable
            var color = argbHexToRgba(value.colorText);
            color = color ? `rgba(${color.r}, ${color.g}, ${color.b}, ${color.a})` : '';
            var text;
            if ('text' in value) {
                text = value.text;
            } else if ('icon' in value) {
                text = `<span class='fa ${value.icon}'></span>`;
            } else {
                text = '!';
            }
            FloatingButton.show(text, srcIfame[0], bgColor, color);
            jsonCalls.Helper.AddJsonCallEventListener(72, value, srcIfame);
        } else {
            FloatingButton.hide(srcIfame[0]);
        }
    };

    jsonCalls[75] = jsonCalls.AddChaynsCallErrorListener = function (value, srcIframe) {
        jsonCalls.Helper.AddJsonCallEventListener(75, value, srcIframe);
    };

    jsonCalls[77] = jsonCalls.SetIframeHeigth = function (value, srcIframe) {
        //noinspection JSUnresolvedVariable
        if (window.ChaynsInfo.IsFacebook && window.FB) {
            setTimeout(function () {
                //noinspection JSUnresolvedVariable,JSUnresolvedFunction
                window.FB.Canvas.setSize({
                    'height': $(document.body).height()
                });
            }, 500);
        }

        let $iframe = srcIframe;

        if (!value.full && !('height' in value) && !('fullViewport' in value)) {
            jsonCalls.Helper.throw(77, 2, 'Field height missing.', value, srcIframe);
            return;
        } else if (value.full) {
            value.height = getWindowMetrics().AvailHeight;
        } else if (value.fullViewport) {
            let $NavItems = $('#NavItems');
            let $PageHead = $('#PageHead');
            let navHeight = $NavItems.height();
            let maxHeight = $NavItems.height() + 45;
            let headerHeight = $PageHead.height() + ($('.domainOfferAttention').outerHeight() || 0);
            let pageheadHeight = $PageHead.height() + $('#TitleConnect').height() + 50;
            let minHeight = $(window).height() - headerHeight - 35;
            let h, margin;

            $('#BodyContent').css('margin-bottom', '0px');
            $('#BodyContentCell').css('padding-bottom', '0px');
            value.height = $(window.top).height() + $(window).scrollTop() - $PageHead.height() - $('#TitleConnectSites').height() - 30;
            if (value.height > $(window.top).height()) {
                value.height = $(window.top).height();
            }
            $iframe.height(value.height);
            $(window).bind('scroll', function () {
                if (minHeight > maxHeight) {
                    maxHeight = minHeight;
                }

                h = minHeight + $(window).scrollTop();

                if (h > maxHeight) {
                    h = maxHeight;
                } else {
                    h = h - 25;
                }

                if (h < $(window).height() - 28) {
                    $iframe.height(h);
                    $iframe.css('margin-top', -35);
                } else {
                    margin = $(window).scrollTop() - pageheadHeight;
                    if (margin + $iframe.height() <= navHeight + 65) {
                        $iframe.css('margin-top', margin);
                        $iframe.height($(window).height());
                    }
                }
            });
        } else {
            value.height = parseInt(value.height, 10);
        }

        if (isNaN(value.height)) {
            jsonCalls.Helper.throw(77, 1, 'Field heigth is not typeof number', value, srcIframe);
            return;
        }

        value.growOnly = value.growOnly !== false; // true als default

        if ($iframe && (!value.growOnly || $iframe[0].style.height < value.height)) {
            $iframe[0].style.height = value.height;
        }

        // if (window.positionFloatingButton) {
        //     window.positionFloatingButton();
        // }
    };

    jsonCalls[103] = jsonCalls.ShowDialog = function (value, srcIframe) {
        if (value.dialog === undefined) {
            jsonCalls.Helper.throw(103, 2, 'Field dialog missing.', value, srcIframe);
            return;
        }
        if ((value.dialog.buttons || []).length === 0) {
            jsonCalls.Helper.throw(103, 2, 'Field dialog.buttons missing.', value, srcIframe);
            return;
        }

        value.dialog.callback = (retVal) => jsonCalls.Helper.return(value, retVal, srcIframe);

        DialogNew.show('input', value.dialog);
    };

})(window.JsonCalls = window.JsonCalls || {});

// JsonCalls.Helper
(function (m) {
    var jsonCallEventListener = [];

    m.AddJsonCallEventListener = function (action, request, srcIframe) {
        jsonCallEventListener.push({
            action: action,
            callback: request.callback,
            addJSONParam: request.addJSONParam,
            srcIframe: srcIframe
        });
    };

    /**
     * @return {boolean}
     */
    m.DispatchJsonCallEvent = function (action, response, destIframe) {
        var retVal = false;

        jsonCallEventListener.forEach(function (listener) {
            if ((listener.action !== action) || (destIframe && listener.srcIframe !== destIframe)) {
                return;
            }
            if (!destIframe) {
                destIframe = listener.srcIframe;
            }
            window.CustomTappCommunication.AnswerJsonCall(listener, response, destIframe);
            retVal = true;
        });

        return retVal;
    };

    m.RemoveJsonCallEventListener = function (action, callback) {
        jsonCallEventListener = jsonCallEventListener.filter(function (listener) {
            if (listener.action === action) {
                return !(!callback || listener.callback === callback);
            }
            return true;
        });
    };

    m.throw = function (action, code, message, request, srcIframe) {
        var retVal = {
            action: action,
            errorCode: code,
            message: message,
            value: request
        };
        m.DispatchJsonCallEvent(75, retVal, srcIframe);
    };

    m.return = window.CustomTappCommunication.AnswerJsonCall;

    /**
     * @return {number}
     */
    m.EncodeDialogButtonTypes = function (type) {
        return type <= 0 ? type - 10 : type;
    };

    /**
     * @return {number}
     */
    m.DecodeDialogButtonTypes = function (type) {
        return type <= -10 ? type + 10 : type;
    };

    m.GeoWatchNumber = null;

    m.OverlayCloseParam = {};

    m.Throttle = function (fn, threshhold, scope) {
        threshhold = threshhold ? threshhold : 250;
        var last,
            deferTimer;
        return function () {
            var context = scope || this;

            var now = +new Date,
                args = arguments;
            if (last && now < last + threshhold) {
                // hold on to it
                clearTimeout(deferTimer);
                deferTimer = setTimeout(function () {
                    last = now;
                    fn.apply(context, args);
                }, threshhold);
            } else {
                last = now;
                fn.apply(context, args);
            }
        };
    };
})(window.JsonCalls.Helper = window.JsonCalls.Helper || {});<|endoftext|>


<commit_before>/* Dispatch area - Should be eliminate after dispatching */

var markersGroup = new L.LayerGroup();
var isDispatching = false;
var isFilterOpen = false;
var placeIcon = L.icon({
	iconUrl: '/static/icons/place_marker.png',
	iconSize: [40, 40],
	iconAnchor: [20, 40],
	popupAnchor: [0,-40]
});

var dispatchingAmbulances = {};
var numberOfDispatchingAmbulances = 0;

var currentAddress;
var currentLocation;
var currentPatients;

var submitDispatching = function () {

    // submit form
    $('#dispatch-form-collapse').submit();

};

var beginDispatching = function () {

    isDispatching = true;
    var filtersDiv = $('#filtersDiv');
    isFilterOpen = filtersDiv.hasClass('show');
    console.log('Begin dispatching.');

    $('#dispatchBeginButton').hide();
    $('#dispatchSubmitButton').show();
    $('#dispatchCancelButton').show();

    // open filter and available ambulances
    filtersDiv.addClass('show');
    $('#ambulance_status').addClass('show');
    $('#ambulance_AV').addClass('show');

    // Handle double click
    mymap.doubleClickZoom.disable();
    mymap.on('dblclick', function(e) {
	// update marker location
	updateCurrentMarker(e.latlng);
    });

    // Update current location
    updateCurrentLocation(mymap.getCenter());

    // Update current address
    updateCurrentAddress(currentLocation);

    // Clear current currentPatients
    currentPatients = {};

    // Initialize patient form
    $('#patients').empty();

    // add new patient form entry
    addPatientForm(0);

    // resize size
    resizeMap();

    // center map
    mymap.setView(currentLocation, mymap.getZoom());

}

var endDispatching = function () {

    isDispatching = false;
    dispatchingAmbulances = {};
    console.log('End dispatching.');

    // remove marker
    markersGroup.clearLayers();

    // unselect priority
    $('#priority-buttons label.btn').removeClass('active');
    $('input:radio[name=priority]').prop('checked', false);

    // clear description
    $('#comment').val('');

    // clear ambulances buttons
    $('#ambulance-selection :button').remove();
    $('#ambulance-selection-message').show();

    // clear patients
    $('#patients').find('.btn-new-patient').off('click');
    $('#patients').empty();

    // show buttons
    $('#dispatchBeginButton').show();
    $('#dispatchSubmitButton').hide();
    $('#dispatchCancelButton').hide();

    // close dispatch panel
    $('#dispatchDiv').removeClass('show');

    if (!isFilterOpen) {
        // close filter panel
        $('#filtersDiv').removeClass('show');
    }

    // remove dblclick handler
    mymap.off('dblclick');
    mymap.doubleClickZoom.enable();

    // invalidate map size
    mymap.invalidateSize();

}

var removeFromDispatchingList = function(ambulance) {

    // delete from dispatching list
    delete dispatchingAmbulances[ambulance.id];
    numberOfDispatchingAmbulances--;

    // show message if last button
    if (numberOfDispatchingAmbulances == 0)
        $('#ambulance-selection-message').show();

}

var addToDispatchingList = function(ambulance) {

    // quick return if null or not dispatching
    if (ambulance == null || !isDispatching)
        return;

    // add ambulance to dispatching list
    console.log('Adding ambulance ' + ambulance.identifier + ' to dispatching list');

    // already in?
    if (ambulance.id in dispatchingAmbulances) {
        console.log('Already in dispatching list, skip');
        return;
    }

    // not available?
    if (ambulance.status != STATUS_AVAILABLE) {
        console.log('Ambulance is not available');
        bsalert('Can only dispatch available ambulances!');
        return;
    }

    // hide message if first button
    if (numberOfDispatchingAmbulances == 0)
        $('#ambulance-selection-message').hide();

    // add ambulance to list of dispatching ambulances
    dispatchingAmbulances[ambulance.id] = ambulance;
    numberOfDispatchingAmbulances++;

    // add button to ambulance dispatch grid
    $('#ambulance-selection').append(
        '<button id="dispatch-button-' + ambulance.id + '"'
        + ' value="' + ambulance.id + '"'
        + ' type="button" class="btn btn-sm '+ ambulance_buttons['AV'] + '"'
        + ' style="margin: 2px 2px;"'
        + ' draggable="true">'
        + ambulance.identifier
        + '</button>'
    );
    $('#dispatch-button-' + ambulance.id)
        .on('dragstart', function (e) {
            // on start of drag, copy information and fade button
            console.log('dragstart');
            this.style.opacity = '0.4';
            e.originalEvent.dataTransfer.setData("text/plain", ambulance.id);
        })
        .on('dragend', function (e) {
            console.log('dragend');
            if (e.originalEvent.dataTransfer.dropEffect == 'none') {
                // Remove button if not dropped back
                removeFromDispatchingList(ambulance);
                // Remove button
                $(this).remove();
            } else {
                // Restore opacity if dropped back in
                this.style.opacity = '1.0';
            }
        });
}

var updateCurrentMarker = function(latlng) {

    // update current location
    updateCurrentLocation(latlng);

    // update address?
    if ($('#update-address').prop('checked'))
        updateCurrentAddress(latlng);

}

var updateCurrentLocation = function(location) {

    console.log('Setting current location to: ' + location.lat + ', ' + location.lng);

    // set currentLocation
    currentLocation = location;

    // update coordinates on form
    $('#curr-lat').html(currentLocation.lat.toFixed(6));
    $('#curr-lng').html(currentLocation.lng.toFixed(6));

    // remove existing marker
    markersGroup.clearLayers();

    // laydown marker
    var marker = L.marker(location,
        {
            icon: placeIcon,
            draggable: true
        })
        .addTo(markersGroup);
    markersGroup.addTo(mymap);

    // pan to location: kaung and mauricio though it made more sense to not pan
    // mymap.panTo(location);

    // marker can be dragged on the dispatch map
    marker.on('dragend', function(e) {

	// update current marker
	updateCurrentMarker(marker.getLatLng());

    });
}

var updateCurrentAddress = function(location) {

    var options = {
        types: 'address',
        limit: 1
    };
    geocoder.reverse(location, options,
        function (results, status) {

        if (status != "success") {
            bsalert("Could not geocode:\nError " + status + ", " + results['error']);
            return;
        }

        // quick return if found nothing
        if (results.length == 0) {
            console.log('Got nothing from geocode');
            return;
        }

        // parse features into current address
        currentAddress = geocoder.parse_feature(results[0]);

        console.log(
            'Setting currentAddress to:'
            + '\nnumber: ' + currentAddress['number']
            + '\nstreet: ' + currentAddress['street']
            + '\nunit: ' + currentAddress['unit']
            + '\nlocation: ' + currentAddress['location']['latitude']
            + ',' + currentAddress['location']['longitude']
            + '\nneighborhood: ' + currentAddress['neighborhood']
            + '\nzipcode: ' + currentAddress['zipcode']
            + '\ncity: ' + currentAddress['city']
            + '\nstate: ' + currentAddress['state']
            + '\ncountry: ' + currentAddress['country']
        );

        // set input text
        $('#street').val(currentAddress['street_address']);

    });

}

var updateCoordinates = function() {

    // when the user changes the street address
    var address =$('#street').val();

    // quick return if no address
    if (!address)
        return;

    // otherwise geocode and update
    var options = {
        types: 'address',
        limit: 1,
        autocomplete: 'true'
    };
    geocoder.geocode(address, options,
        function (results, status) {

            if (status != "success") {
                bsalert("Could not geocode:\nError " + status + ", " + results['error']);
                return;
            }

            // quick return if found nothing
            if (results.length == 0) {
                console.log('Got nothing from geocode');
                return;
            }

            // parse features into address
            var address = geocoder.parse_feature(results[0]);

            console.log(
                'Setting currentLocation to:'
                + '\nnumber: ' + address['number']
                + '\nstreet: ' + address['street']
                + '\nunit: ' + address['unit']
                + '\nlocation: ' + address['location']['latitude']
                + ',' + address['location']['longitude']
                + '\nneighborhood: ' + address['neighborhood']
                + '\nzipcode: ' + address['zipcode']
                + '\ncity: ' + address['city']
                + '\nstate: ' + address['state']
                + '\ncountry: ' + address['country']
            );

            // set current location
            updateCurrentLocation({
                lat: address['location']['latitude'],
                lng: address['location']['longitude']
            });

        });
}

function dispatchCall() {

    var form = {};

    // call information
    var street_address = $('#street').val().trim();
    form['details'] = $('#comment').val().trim();
    form['priority'] = $('input:radio[name=priority]:checked').val();

    // checks
    if (form["priority"] === undefined) {
        bsalert("Please select the priority level.");
        return;
    }
    if (numberOfDispatchingAmbulances == 0) {
        bsalert("Please dispatch at least one ambulance.");
        return;
    }

    // address information
    form['neighborhood'] = currentAddress['neighborhood'];
    form['city'] = currentAddress['city'];
    form['state'] = currentAddress['state'];
    form['country'] = currentAddress['country'];
    form['zipcode'] = currentAddress['zipcode'];
    form['location'] = currentAddress['location'];

    // Has the user modified the street address?
    if (street_address != currentAddress['street_address']) {

        // parse street address
        var address = geocoder.parse_street_address(street_address, form['country']);

        form['number'] = address['number'];
        form['street'] = address['street'];
        form['unit'] = address['unit'];

    } else {

        form['number'] = currentAddress['number'];
        form['street'] = currentAddress['street'];
        form['unit'] = currentAddress['unit'];

    }

    // Make sure blanks are undefined
    if (form['number'] == "") {
        form['number'] = undefined;
    }

    // ambulances
    var ambulances = [];
    for (var id in dispatchingAmbulances) {
        if (dispatchingAmbulances.hasOwnProperty(id))
            ambulances.push({ 'ambulance_id': id });
		}
    form['ambulancecall_set'] = ambulances;

    // patients
    var patients = [];
    for (var index in currentPatients)
        if (currentPatients.hasOwnProperty(index)) {
            var patient = currentPatients[index];
            var obj = { 'name': patient[0] };
            if (patient[1])
                // add age
                obj['age'] = parseInt(patient[1]);
            patients.push(obj);
        }
    form['patient_set'] = patients;

    // make json call
    var postJsonUrl = APIBaseUrl + 'call/';
    console.log("Form:");
    console.log(form);
    console.log("Will post:");
    console.log(JSON.stringify(form));

    var CSRFToken = Cookies.get('csrftoken');
    console.log('csrftoken = ' + CSRFToken);

    // retrieve csrf token
    $.ajaxSetup({
        beforeSend: function (xhr, settings) {
            if (!CSRFSafeMethod(settings.type) && !this.crossDomain) {
                xhr.setRequestHeader("X-CSRFToken", CSRFToken);
            }
        }
    });

    // make ajax call
    $.ajax({
        url: postJsonUrl,
        type: 'POST',
        dataType: 'json',
        contentType: 'application/json',
        data: JSON.stringify(form),
        success: function (data) {

            // Log success
            console.log("Succesfully posted new call.");

            // End dispatching
            endDispatching();

        },
        error: function (jqXHR, textStatus, errorThrown) {

            // Log failure
            console.log("Failed to post new call.");
            console.log(jqXHR.responseText);

            // Show modal
            bsalert(jqXHR.responseText, 'alert-danger', 'Failure');

            // Do not end dispatching to give user chance to make changes
            // endDispatching();

        }
    });
}

// patient functions

var addPatient = function(index) {

    console.log('Adding patient index ' + index);

    var name = $('#patient-' + index + '-name').val().trim();
    var age = $('#patient-' + index + '-age').val().trim();

    // is name empty?
    if (!name) {
        bsalert('Empty name');
        return;
    }

    // add name
    currentPatients[index] = [name, age];

    // change button symbol
    var symbol = $('#patient-' + index + '-symbol');
    symbol.removeClass('fa-plus');
    symbol.addClass('fa-minus');

    // change button action from add to remove
    $('#patients').find('#patient-' + index + '-button')
        .off('click')
        .on('click', function(e) { removePatient(index); });

    // add new form
    addPatientForm(index + 1);

}

var removePatient = function(index) {

    console.log('Removing patient index ' + index);

    // remove from storage
    delete currentPatients[index];

    // remove from form
    $('#patients')
        .find('#patient-' + index + '-form')
        .remove();

}

var addPatientForm = function(index) {

    console.log('Adding patient form ' + index);

    // add new patient form entry
    $('#patients').append(newPatientForm(index, 'fa-plus'));

    // bind addPatient to click
    $('#patients').find('#patient-' + index + '-button')
        .on('click', function(e) { addPatient(index); });

}

var newPatientForm = function(index, symbol) {

    var html =
        '
' +
            '
' +
                '<input id="patient-' + index + '-name" ' +
                       'type="text" ' +
                       'class="form-control" ' +
                       'placeholder="Name">' +
            '
' +
            '
' +
                '<input id="patient-' + index + '-age" ' +
                       'type="number" min="0" ' +
                       'class="form-control" ' +
                       'placeholder="Age">' +
            '
' +
            '
' +
                '<button class="btn btn-default btn-block btn-new-patient" ' +
                       ' type="button" ' +
                       ' id="patient-' + index + '-button">' +
                    '' +
                '</button>' +
            '
' +
        '
';

    // console.log('html = "' + html + '"');

    return html;

}

// Ready function
$(function() {

    // connect actions to inputs

    $("#street").change(function () {

        // update coordinates?
        if ($('#update-coordinates').prop('checked'))
            updateCoordinates();

    });

    $('#update-coordinates').change(function () {

        // update coordinates?
        if ($('#update-coordinates').prop('checked'))
            updateCoordinates();

    });

    $('#update-address').change(function () {

        // update address?
        if ($('#update-address').prop('checked'))
            updateCurrentAddress(currentLocation);

    });

    $('#dispatch-form-collapse').submit(function (e) {

        // prevent normal form submission
        e.preventDefault();

        // dispatch call
        dispatchCall();

    });

});

// CSRF functions
function CSRFSafeMethod(method) {
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
<commit_msg>Fixing problems with javascript dispatching form.<commit_after>/* Dispatch area - Should be eliminate after dispatching */

var markersGroup = new L.LayerGroup();
var isDispatching = false;
var isFilterOpen = false;
var placeIcon = L.icon({
	iconUrl: '/static/icons/place_marker.png',
	iconSize: [40, 40],
	iconAnchor: [20, 40],
	popupAnchor: [0,-40]
});

var dispatchingAmbulances = {};
var numberOfDispatchingAmbulances = 0;

var currentAddress;
var currentLocation;
var currentPatients;

var submitDispatching = function () {

    // submit form
    $('#dispatch-form-collapse').submit();

};

var beginDispatching = function () {

    isDispatching = true;
    var filtersDiv = $('#filtersDiv');
    isFilterOpen = filtersDiv.hasClass('show');
    console.log('Begin dispatching.');

    $('#dispatchBeginButton').hide();
    $('#dispatchSubmitButton').show();
    $('#dispatchCancelButton').show();

    // open filter and available ambulances
    filtersDiv.addClass('show');
    $('#ambulance_status').addClass('show');
    $('#ambulance_AV').addClass('show');

    // Handle double click
    mymap.doubleClickZoom.disable();
    mymap.on('dblclick', function(e) {
	// update marker location
	updateCurrentMarker(e.latlng);
    });

    // Update current location
    updateCurrentLocation(mymap.getCenter());

    // Update current address
    updateCurrentAddress(currentLocation);

    // Clear current currentPatients
    currentPatients = {};

    // Initialize patient form
    $('#patients').empty();

    // add new patient form entry
    addPatientForm(0);

    // resize size
    resizeMap();

    // center map
    mymap.setView(currentLocation, mymap.getZoom());

}

var endDispatching = function () {

    isDispatching = false;
    dispatchingAmbulances = {};
    console.log('End dispatching.');

    // remove marker
    markersGroup.clearLayers();

    // unselect priority
    $('#priority-buttons label.btn').removeClass('active');
    $('input:radio[name=priority]').prop('checked', false);

    // clear description
    $('#comment').val('');

    // clear ambulances buttons
    $('#ambulance-selection :button').remove();
    $('#ambulance-selection-message').show();

    // clear patients
    $('#patients').find('.btn-new-patient').off('click');
    $('#patients').empty();

    // show buttons
    $('#dispatchBeginButton').show();
    $('#dispatchSubmitButton').hide();
    $('#dispatchCancelButton').hide();

    // close dispatch panel
    $('#dispatchDiv').removeClass('show');

    if (!isFilterOpen) {
        // close filter panel
        $('#filtersDiv').removeClass('show');
    }

    // remove dblclick handler
    mymap.off('dblclick');
    mymap.doubleClickZoom.enable();

    // invalidate map size
    mymap.invalidateSize();

}

var removeFromDispatchingList = function(ambulance) {

    // delete from dispatching list
    delete dispatchingAmbulances[ambulance.id];
    numberOfDispatchingAmbulances--;

    // show message if last button
    if (numberOfDispatchingAmbulances == 0)
        $('#ambulance-selection-message').show();

}

var addToDispatchingList = function(ambulance) {

    // quick return if null or not dispatching
    if (ambulance == null || !isDispatching)
        return;

    // add ambulance to dispatching list
    console.log('Adding ambulance ' + ambulance.identifier + ' to dispatching list');

    // already in?
    if (ambulance.id in dispatchingAmbulances) {
        console.log('Already in dispatching list, skip');
        return;
    }

    // not available?
    if (ambulance.status != STATUS_AVAILABLE) {
        console.log('Ambulance is not available');
        bsalert('Can only dispatch available ambulances!');
        return;
    }

    // hide message if first button
    if (numberOfDispatchingAmbulances == 0)
        $('#ambulance-selection-message').hide();

    // add ambulance to list of dispatching ambulances
    dispatchingAmbulances[ambulance.id] = ambulance;
    numberOfDispatchingAmbulances++;

    // add button to ambulance dispatch grid
    $('#ambulance-selection').append(
        '<button id="dispatch-button-' + ambulance.id + '"'
        + ' value="' + ambulance.id + '"'
        + ' type="button" class="btn btn-sm '+ ambulance_buttons['AV'] + '"'
        + ' style="margin: 2px 2px;"'
        + ' draggable="true">'
        + ambulance.identifier
        + '</button>'
    );
    $('#dispatch-button-' + ambulance.id)
        .on('dragstart', function (e) {
            // on start of drag, copy information and fade button
            console.log('dragstart');
            this.style.opacity = '0.4';
            e.originalEvent.dataTransfer.setData("text/plain", ambulance.id);
        })
        .on('dragend', function (e) {
            console.log('dragend');
            if (e.originalEvent.dataTransfer.dropEffect == 'none') {
                // Remove button if not dropped back
                removeFromDispatchingList(ambulance);
                // Remove button
                $(this).remove();
            } else {
                // Restore opacity if dropped back in
                this.style.opacity = '1.0';
            }
        });
}

var updateCurrentMarker = function(latlng) {

    // update current location
    updateCurrentLocation(latlng);

    // update address?
    if ($('#update-address').prop('checked'))
        updateCurrentAddress(latlng);

}

var updateCurrentLocation = function(location) {

    console.log('Setting current location to: ' + location.lat + ', ' + location.lng);

    // set currentLocation
    currentLocation = location;

    // update coordinates on form
    $('#curr-lat').html(currentLocation.lat.toFixed(6));
    $('#curr-lng').html(currentLocation.lng.toFixed(6));

    // remove existing marker
    markersGroup.clearLayers();

    // laydown marker
    var marker = L.marker(location,
        {
            icon: placeIcon,
            draggable: true
        })
        .addTo(markersGroup);
    markersGroup.addTo(mymap);

    // pan to location: kaung and mauricio though it made more sense to not pan
    // mymap.panTo(location);

    // marker can be dragged on the dispatch map
    marker.on('dragend', function(e) {

	// update current marker
	updateCurrentMarker(marker.getLatLng());

    });
}

var updateCurrentAddress = function(location) {

    var options = {
        types: 'address',
        limit: 1
    };
    geocoder.reverse(location, options,
        function (results, status) {

        if (status != "success") {
            bsalert("Could not geocode:\nError " + status + ", " + results['error']);
            return;
        }

        // quick return if found nothing
        if (results.length == 0) {
            console.log('Got nothing from geocode');
            return;
        }

        // parse features into current address
        currentAddress = geocoder.parse_feature(results[0]);

        console.log(
            'Setting currentAddress to:'
            + '\nnumber: ' + currentAddress['number']
            + '\nstreet: ' + currentAddress['street']
            + '\nunit: ' + currentAddress['unit']
            + '\nlocation: ' + currentAddress['location']['latitude']
            + ',' + currentAddress['location']['longitude']
            + '\nneighborhood: ' + currentAddress['neighborhood']
            + '\nzipcode: ' + currentAddress['zipcode']
            + '\ncity: ' + currentAddress['city']
            + '\nstate: ' + currentAddress['state']
            + '\ncountry: ' + currentAddress['country']
        );

        // set input text
        $('#street').val(currentAddress['street_address']);

    });

}

var updateCoordinates = function() {

    // when the user changes the street address
    var address =$('#street').val();

    // quick return if no address
    if (!address)
        return;

    // otherwise geocode and update
    var options = {
        types: 'address',
        limit: 1,
        autocomplete: 'true'
    };
    geocoder.geocode(address, options,
        function (results, status) {

            if (status != "success") {
                bsalert("Could not geocode:\nError " + status + ", " + results['error']);
                return;
            }

            // quick return if found nothing
            if (results.length == 0) {
                console.log('Got nothing from geocode');
                return;
            }

            // parse features into address
            var address = geocoder.parse_feature(results[0]);

            console.log(
                'Setting currentLocation to:'
                + '\nnumber: ' + address['number']
                + '\nstreet: ' + address['street']
                + '\nunit: ' + address['unit']
                + '\nlocation: ' + address['location']['latitude']
                + ',' + address['location']['longitude']
                + '\nneighborhood: ' + address['neighborhood']
                + '\nzipcode: ' + address['zipcode']
                + '\ncity: ' + address['city']
                + '\nstate: ' + address['state']
                + '\ncountry: ' + address['country']
            );

            // set current location
            updateCurrentLocation({
                lat: address['location']['latitude'],
                lng: address['location']['longitude']
            });

        });
}

function dispatchCall() {

    var form = {};

    // call information
    var street_address = $('#street').val().trim();
    form['details'] = $('#comment').val().trim();
    form['priority'] = $('input:radio[name=priority]:checked').val();

    // checks
    if (form["priority"] === undefined) {
        bsalert("Please select the priority level.");
        return;
    }
    if (numberOfDispatchingAmbulances == 0) {
        bsalert("Please dispatch at least one ambulance.");
        return;
    }

    // address information
    form['neighborhood'] = currentAddress['neighborhood'];
    form['city'] = currentAddress['city'];
    form['state'] = currentAddress['state'];
    form['country'] = currentAddress['country'];
    form['zipcode'] = currentAddress['zipcode'];
    form['location'] = currentAddress['location'];

    // Has the user modified the street address?
    if (street_address != currentAddress['street_address']) {

        // parse street address
        var address = geocoder.parse_street_address(street_address, form['country']);

        form['number'] = address['number'];
        form['street'] = address['street'];
        form['unit'] = address['unit'];

    } else {

        form['number'] = currentAddress['number'];
        form['street'] = currentAddress['street'];
        form['unit'] = currentAddress['unit'];

    }

    // Make sure blanks are undefined
    if (form['number'] == "") {
        form['number'] = undefined;
    }

    // ambulances
    var ambulances = [];
    for (var id in dispatchingAmbulances) {
        if (dispatchingAmbulances.hasOwnProperty(id))
            ambulances.push({ 'ambulance_id': id });
		}
    form['ambulancecall_set'] = ambulances;

    // patients
    var patients = [];
    for (var index in currentPatients)
        if (currentPatients.hasOwnProperty(index)) {
            var patient = currentPatients[index];
            var obj = { 'name': patient[0] };
            if (patient[1])
                // add age
                obj['age'] = parseInt(patient[1]);
            patients.push(obj);
        }
    // retrieve last patient
    var lastPatient = $('#patients div:last-child');
    console.log('last patient');
    console.log(lastPatient);

    form['patient_set'] = patients;

    // make json call
    var postJsonUrl = APIBaseUrl + 'call/';
    console.log("Form:");
    console.log(form);
    console.log("Will post:");
    console.log(JSON.stringify(form));

    var CSRFToken = Cookies.get('csrftoken');
    console.log('csrftoken = ' + CSRFToken);

    // retrieve csrf token
    $.ajaxSetup({
        beforeSend: function (xhr, settings) {
            if (!CSRFSafeMethod(settings.type) && !this.crossDomain) {
                xhr.setRequestHeader("X-CSRFToken", CSRFToken);
            }
        }
    });

    // make ajax call
    $.ajax({
        url: postJsonUrl,
        type: 'POST',
        dataType: 'json',
        contentType: 'application/json',
        data: JSON.stringify(form),
        success: function (data) {

            // Log success
            console.log("Succesfully posted new call.");

            // End dispatching
            endDispatching();

        },
        error: function (jqXHR, textStatus, errorThrown) {

            // Log failure
            console.log("Failed to post new call.");
            console.log(jqXHR.responseText);

            // Show modal
            bsalert(jqXHR.responseText, 'alert-danger', 'Failure');

            // Do not end dispatching to give user chance to make changes
            // endDispatching();

        }
    });
}

// patient functions

var addPatient = function(index) {

    console.log('Adding patient index ' + index);

    var name = $('#patient-' + index + '-name').val().trim();
    var age = $('#patient-' + index + '-age').val().trim();

    // is name empty?
    if (!name) {
        bsalert('Empty name');
        return;
    }

    // add name
    currentPatients[index] = [name, age];

    // change button symbol
    var symbol = $('#patient-' + index + '-symbol');
    symbol.removeClass('fa-plus');
    symbol.addClass('fa-minus');

    // change button action from add to remove
    $('#patients').find('#patient-' + index + '-button')
        .off('click')
        .on('click', function(e) { removePatient(index); });

    // add new form
    addPatientForm(index + 1);

}

var removePatient = function(index) {

    console.log('Removing patient index ' + index);

    // remove from storage
    delete currentPatients[index];

    // remove from form
    $('#patients')
        .find('#patient-' + index + '-form')
        .remove();

}

var addPatientForm = function(index) {

    console.log('Adding patient form ' + index);

    // add new patient form entry
    $('#patients').append(newPatientForm(index, 'fa-plus'));

    // bind addPatient to click
    $('#patients').find('#patient-' + index + '-button')
        .on('click', function(e) { addPatient(index); });

}

var newPatientForm = function(index, symbol) {

    var html =
        '
' +
            '
' +
                '<input id="patient-' + index + '-name" ' +
                       'type="text" ' +
                       'class="form-control" ' +
                       'placeholder="Name">' +
            '
' +
            '
' +
                '<input id="patient-' + index + '-age" ' +
                       'type="number" min="0" ' +
                       'class="form-control" ' +
                       'placeholder="Age">' +
            '
' +
            '
' +
                '<button class="btn btn-default btn-block btn-new-patient" ' +
                       ' type="button" ' +
                       ' id="patient-' + index + '-button">' +
                    '' +
                '</button>' +
            '
' +
        '
';

    // console.log('html = "' + html + '"');

    return html;

}

// Ready function
$(function() {

    // connect actions to inputs

    $("#street").change(function () {

        // update coordinates?
        if ($('#update-coordinates').prop('checked'))
            updateCoordinates();

    });

    $('#update-coordinates').change(function () {

        // update coordinates?
        if ($('#update-coordinates').prop('checked'))
            updateCoordinates();

    });

    $('#update-address').change(function () {

        // update address?
        if ($('#update-address').prop('checked'))
            updateCurrentAddress(currentLocation);

    });

    $('#dispatch-form-collapse').submit(function (e) {

        // prevent normal form submission
        e.preventDefault();

        // dispatch call
        dispatchCall();

    });

});

// CSRF functions
function CSRFSafeMethod(method) {
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
<|endoftext|>