<commit_before>var $live = $('#live'),
    showlive = $('#showlive')[0];

/**
 * Defer callable. Kinda tricky to explain. Basically:
 *  "Don't make newFn callable until I tell you via this trigger callback."
 *
 * Example:

      // Only start logging after 3 seconds
      var log = function (str) { console.log(str); };
      var deferredLog = deferCallable(log, function (done) {
        setTimeout(done, 3000);
      });

      setInterval(function () {
        deferredLog(Date.now(), 500);
      });

 */
var deferCallable = function (newFn, trigger) {
  var args,
      pointerFn = function () {
        // Initially, the pointer basically does nothing, waiting for the
        // trigger to fire, but we save the arguments that wrapper was called
        // with so that they can be passed to the newFn when it's ready.
        args = [].slice.call(arguments);
      };

  // Immediately call the trigger so that the user can inform us of when
  // the newFn is callable.
  // When it is, swap round the pointers and, if the wrapper was aleady called,
  // immediately call the pointerFn.
  trigger(function () {
    pointerFn = newFn;
    if (args) {
      pointerFn.apply(null, args);
    }
  });

  // Wrapper the pointer function. This means we can swap pointerFn around
  // without breaking external references.
  return function wrapper() {
    return pointerFn.apply(null, [].slice.call(arguments));
  };
};

/**
 * =============================================================================
 * =============================================================================
 * =============================================================================
 */

function sendReload() {
  if (saveChecksum) {
    $.ajax({
      url: jsbin.getURL() + '/reload',
      data: {
        code: jsbin.state.code,
        revision: jsbin.state.revision,
        checksum: saveChecksum
      },
      type: 'post'
    });
  }
}

function codeChangeLive(event, data) {
  clearTimeout(deferredLiveRender);

  var editor,
      line,
      panel = jsbin.panels.panels.live;

  if (jsbin.panels.ready) {
    if (jsbin.settings.includejs === false && data.panelId === 'javascript') {
      // ignore
    } else if (panel.visible) {
      // test to see if they're write a while loop
      if (!jsbin.lameEditor && jsbin.panels.focused && jsbin.panels.focused.id === 'javascript') {
        // check the current line doesn't match a for or a while or a do - which could trip in to an infinite loop
        editor = jsbin.panels.focused.editor;
        line = editor.getLine(editor.getCursor().line);
        if (ignoreDuringLive.test(line) === true) {
          // ignore
          throttledPreview.cancel();
          deferredLiveRender = setTimeout(function () {
            codeChangeLive(event, data);
          }, 1000);
        } else {
          throttledPreview();
        }
      } else {
        throttledPreview();
      }
    }
  }
}

/** ============================================================================
 * JS Bin Renderer
 * Messages to and from the runner.
 * ========================================================================== */

var renderer = (function () {

  var renderer = {};

  /**
   * Store what runner origin *should* be
   * TODO this should allow anything if x-origin protection should be disabled
   */
  renderer.runner = {};
  renderer.runner.origin = '*';

  /**
   * Setup the renderer
   */
  renderer.setup = function (runnerFrame) {
    renderer.runner.window = runnerFrame.contentWindow;
    renderer.runner.iframe = runnerFrame;
  };

  /**
   * Log error messages, indicating that it's from the renderer.
   */
  renderer.error = function () {
    // it's quite likely that the error that fires on this handler actually comes
    // from another service on the page, like a browser plugin, which we can
    // safely ignore.
    window.console.warn.apply(console, ['Renderer:'].concat([].slice.call(arguments)));
  };

  /**
   * Handle all incoming postMessages to the renderer
   */
  renderer.handleMessage = function (event) {
    if (!event.origin) return;
    var data = event.data;

    // specific change to handle reveal embedding
    try {
      if (event.data.indexOf('slide:') === 0 || event.data === 'jsbin:refresh') {
        // reset the state of the panel visibility
        jsbin.panels.allEditors(function (p) {
          p.visible = false;
        });
        jsbin.panels.restore();
        return;
      }
    } catch (e) {}

    try {
      data = JSON.parse(event.data);
    } catch (e) {
      return renderer.error('Error parsing event data:', e.message);
    }
    if (typeof renderer[data.type] !== 'function') {
      return renderer.error('No matching event handler:', data.type);
    }
    try {
      renderer[data.type](data.data);
    } catch (e) {
      renderer.error(e.message);
    }
  };

  /**
   * Send message to the runner window
   */
  renderer.postMessage = function (type, data) {
    if (!renderer.runner.window) {
      return renderer.error('postMessage: No connection to runner window.');
    }
    renderer.runner.window.postMessage(JSON.stringify({
      type: type,
      data: data
    }), renderer.runner.origin);
  };

  /**
   * When the renderer is complete, it means we didn't hit an initial
   * infinite loop
   */
  renderer.complete = function () {
    try {
      delete sessionStorage.runnerPending;
    } catch (e) {}
  };

  /**
   * Pass loop protection hit calls up to the error UI
   */
  renderer.loopProtectHit = function (line) {
    var cm = jsbin.panels.panels.javascript.editor;

    // grr - more setTimeouts to the rescue. We need this to go in *after*
    // jshint does it's magic, but jshint set on a setTimeout, so we have to
    // schedule after.
    setTimeout(function () {
      var annotations = cm.state.lint.annotations || [];
      if (typeof cm.updateLinting !== 'undefined') {
        // note: this just updated the *source* reference
        annotations = annotations.filter(function (a) {
          return a.source !== 'loopProtectLine:' + line;
        });
        annotations.push({
          from: CodeMirror.Pos(line-1, 0),
          to: CodeMirror.Pos(line-1, 0),
          message: 'Exiting potential infinite loop.\nTo disable loop protection: add "// noprotect" to your code',
          severity: 'warning',
          source: 'loopProtectLine:' + line
        });

        cm.updateLinting(annotations);
      }
    }, cm.state.lint.options.delay || 0);
  };

  /**
   * When the iframe resizes, update the size text
   */
  renderer.resize = (function () {
    var size = $live.find('.size');

    var hide = throttle(function () {
      size.fadeOut(200);
    }, 2000);

    var embedResizeDone = false;

    return function (data) {
      if (!jsbin.embed) {
        // Display the iframe size in px in the JS Bin UI
        size.show().html(data.width + 'px');
        hide();
      }
      if (jsbin.embed && self !== top && embedResizeDone === false) {
        embedResizeDone = true;
        // Inform the outer page of a size change
        var height = ($body.outerHeight(true) - $(renderer.runner.iframe).height()) + data.offsetHeight;
       window.parent.postMessage({ height: height }, '*');
      }
    };
  }());

  /**
   * When the iframe focuses, simulate that here
   */
  renderer.focus = function () {
    jsbin.panels.focus(jsbin.panels.panels.live);
    // also close any open dropdowns
    closedropdown();
  };

  /**
   * Proxy console logging to JS Bin's console
   */
  renderer.console = function (data) {
    var method = data.method,
        args = data.args;

    if (!window._console) {return;}
    if (!window._console[method]) {method = 'log';}

    // skip the entire console rendering if the console is hidden
    if (!jsbin.panels.panels.console.visible) { return; }

    window._console[method].apply(window._console, args);
  };

  /**
   * Load scripts into rendered iframe
   */
  renderer['console:load:script:success'] = function (url) {
    $document.trigger('console:load:script:success', url);
  };

  renderer['console:load:script:error'] = function (err) {
    $document.trigger('console:load:script:error', err);
  };

  /**
   * Load DOME into rendered iframe
   * TODO abstract these so that they are automatically triggered
   */
  renderer['console:load:dom:success'] = function (url) {
    $document.trigger('console:load:dom:success', url);
  };

  renderer['console:load:dom:error'] = function (err) {
    $document.trigger('console:load:dom:error', err);
  };

  return renderer;

}());

/** ============================================================================
 * Live rendering.
 *
 * Comes in two tasty flavours. Basic mode, which is essentially an IE7
 * fallback. Take a look at https://github.com/jsbin/jsbin/issues/651 for more.
 * It uses the iframe's name and JS Bin's event-stream support to keep the
 * page up-to-date.
 *
 * The second mode uses postMessage to inform the runner of changes to code,
 * config and anything that affects rendering, and also listens for messages
 * coming back to update the JS Bin UI.
 * ========================================================================== */

/**
 * Render live preview.
 * Create the runner iframe, and if postMe wait until the iframe is loaded to
 * start postMessaging the runner.
 */
var renderLivePreview = (function () {

  // Runner iframe
  var iframe;

  // Basic mode
  // This adds the runner iframe to the page. It's only run once.
  if (!$live.find('iframe').length) {
    iframe = document.createElement('iframe');
    iframe.setAttribute('class', 'stretch');
    iframe.setAttribute('sandbox', 'allow-forms allow-pointer-lock allow-popups allow-same-origin allow-scripts');
    iframe.setAttribute('frameBorder', '0');
    iframe.setAttribute('name', '<proxy>');
    $live.prepend(iframe);
    iframe.src = jsbin.runner;
    try {
      iframe.contentWindow.name = '/' + jsbin.state.code + '/' + jsbin.state.revision;
    } catch (e) {
      // ^- this shouldn't really fail, but if we're honest, it's a fucking mystery as to why it even works.
      // problem is: if this throws (because iframe.contentWindow is undefined), then the execution exits
      // and `var renderLivePreview` is set to undefined. The knock on effect is that the calls to renderLivePreview
      // then fail, and jsbin doesn't boot up. Tears all round, so we catch.
    }
  }

  // The big daddy that handles postmessaging the runner.
  var renderLivePreview = function (requested) {
    // No postMessage? Don't render – the event-stream will handle it.
    if (!window.postMessage) { return; }

    // Inform other pages event streaming render to reload
    if (requested) { sendReload(); }
    getPreparedCode().then(function (source) {
      var includeJsInRealtime = jsbin.settings.includejs;

      // Tell the iframe to reload
      var visiblePanels = jsbin.panels.getVisible();
      var outputPanelOpen = visiblePanels.indexOf(jsbin.panels.panels.live) > -1;
      var consolePanelOpen = visiblePanels.indexOf(jsbin.panels.panels.console) > -1;
      if (!outputPanelOpen && !consolePanelOpen) {
        return;
      }
      // this is a flag that helps detect crashed runners
      if (jsbin.settings.includejs) {
        sessionStorage.runnerPending = 1;
      }

      renderer.postMessage('render', {
        source: source,
        options: {
          requested: requested,
          debug: jsbin.settings.debug,
          includeJsInRealtime: jsbin.settings.includejs
        }
      });

    });
  };

  /**
   * Events
   */

  $document.on('codeChange.live', function (event, arg) {
    if (arg.origin === 'setValue' || arg.origin === undefined) {
      return;
    }
    delete sessionStorage.runnerPending;
  });

  // Listen for console input and post it to the iframe
  $document.on('console:run', function (event, cmd) {
    renderer.postMessage('console:run', cmd);
  });

  $document.on('console:load:script', function (event, url) {
    renderer.postMessage('console:load:script', url);
  });

  $document.on('console:load:dom', function (event, html) {
    renderer.postMessage('console:load:dom', html);
  });

  // When the iframe loads, swap round the callbacks and immediately invoke
  // if renderLivePreview was called already.
  return deferCallable(renderLivePreview, function (done) {
    iframe.onload = function () {
      if (window.postMessage) {
        // Setup postMessage listening to the runner
        $window.on('message', function (event) {
          renderer.handleMessage(event.originalEvent);
        });
        renderer.setup(iframe);
      }
      done();
    };
  });

}());

// this needs to be after renderLivePreview is set (as it's defined using
// var instead of a first class function).
var throttledPreview = throttle(renderLivePreview, 200),
    liveScrollTop = null;

// timer value: used in the delayed render (because iframes don't have
// innerHeight/Width) in Chrome & WebKit
var deferredLiveRender = null;

$document.bind('codeChange.live', codeChangeLive);
<commit_msg>Throttle the renderLivePreview before deferring it<commit_after>var $live = $('#live'),
    showlive = $('#showlive')[0];

/**
 * Defer callable. Kinda tricky to explain. Basically:
 *  "Don't make newFn callable until I tell you via this trigger callback."
 *
 * Example:

      // Only start logging after 3 seconds
      var log = function (str) { console.log(str); };
      var deferredLog = deferCallable(log, function (done) {
        setTimeout(done, 3000);
      });

      setInterval(function () {
        deferredLog(Date.now(), 500);
      });

 */
var deferCallable = function (newFn, trigger) {
  var args,
      pointerFn = function () {
        // Initially, the pointer basically does nothing, waiting for the
        // trigger to fire, but we save the arguments that wrapper was called
        // with so that they can be passed to the newFn when it's ready.
        args = [].slice.call(arguments);
      };

  // Immediately call the trigger so that the user can inform us of when
  // the newFn is callable.
  // When it is, swap round the pointers and, if the wrapper was aleady called,
  // immediately call the pointerFn.
  trigger(function () {
    pointerFn = newFn;
    if (args) {
      pointerFn.apply(null, args);
    }
  });

  // Wrapper the pointer function. This means we can swap pointerFn around
  // without breaking external references.
  return function wrapper() {
    return pointerFn.apply(null, [].slice.call(arguments));
  };
};

/**
 * =============================================================================
 * =============================================================================
 * =============================================================================
 */

function sendReload() {
  if (saveChecksum) {
    $.ajax({
      url: jsbin.getURL() + '/reload',
      data: {
        code: jsbin.state.code,
        revision: jsbin.state.revision,
        checksum: saveChecksum
      },
      type: 'post'
    });
  }
}

function codeChangeLive(event, data) {
  clearTimeout(deferredLiveRender);

  var editor,
      line,
      panel = jsbin.panels.panels.live;

  if (jsbin.panels.ready) {
    if (jsbin.settings.includejs === false && data.panelId === 'javascript') {
      // ignore
    } else if (panel.visible) {
      // test to see if they're write a while loop
      if (!jsbin.lameEditor && jsbin.panels.focused && jsbin.panels.focused.id === 'javascript') {
        // check the current line doesn't match a for or a while or a do - which could trip in to an infinite loop
        editor = jsbin.panels.focused.editor;
        line = editor.getLine(editor.getCursor().line);
        if (ignoreDuringLive.test(line) === true) {
          // ignore
          throttledPreview.cancel();
          deferredLiveRender = setTimeout(function () {
            codeChangeLive(event, data);
          }, 1000);
        } else {
          throttledPreview();
        }
      } else {
        throttledPreview();
      }
    }
  }
}

/** ============================================================================
 * JS Bin Renderer
 * Messages to and from the runner.
 * ========================================================================== */

var renderer = (function () {

  var renderer = {};

  /**
   * Store what runner origin *should* be
   * TODO this should allow anything if x-origin protection should be disabled
   */
  renderer.runner = {};
  renderer.runner.origin = '*';

  /**
   * Setup the renderer
   */
  renderer.setup = function (runnerFrame) {
    renderer.runner.window = runnerFrame.contentWindow;
    renderer.runner.iframe = runnerFrame;
  };

  /**
   * Log error messages, indicating that it's from the renderer.
   */
  renderer.error = function () {
    // it's quite likely that the error that fires on this handler actually comes
    // from another service on the page, like a browser plugin, which we can
    // safely ignore.
    window.console.warn.apply(console, ['Renderer:'].concat([].slice.call(arguments)));
  };

  /**
   * Handle all incoming postMessages to the renderer
   */
  renderer.handleMessage = function (event) {
    if (!event.origin) return;
    var data = event.data;

    // specific change to handle reveal embedding
    try {
      if (event.data.indexOf('slide:') === 0 || event.data === 'jsbin:refresh') {
        // reset the state of the panel visibility
        jsbin.panels.allEditors(function (p) {
          p.visible = false;
        });
        jsbin.panels.restore();
        return;
      }
    } catch (e) {}

    try {
      data = JSON.parse(event.data);
    } catch (e) {
      return renderer.error('Error parsing event data:', e.message);
    }
    if (typeof renderer[data.type] !== 'function') {
      return renderer.error('No matching event handler:', data.type);
    }
    try {
      renderer[data.type](data.data);
    } catch (e) {
      renderer.error(e.message);
    }
  };

  /**
   * Send message to the runner window
   */
  renderer.postMessage = function (type, data) {
    if (!renderer.runner.window) {
      return renderer.error('postMessage: No connection to runner window.');
    }
    renderer.runner.window.postMessage(JSON.stringify({
      type: type,
      data: data
    }), renderer.runner.origin);
  };

  /**
   * When the renderer is complete, it means we didn't hit an initial
   * infinite loop
   */
  renderer.complete = function () {
    try {
      delete sessionStorage.runnerPending;
    } catch (e) {}
  };

  /**
   * Pass loop protection hit calls up to the error UI
   */
  renderer.loopProtectHit = function (line) {
    var cm = jsbin.panels.panels.javascript.editor;

    // grr - more setTimeouts to the rescue. We need this to go in *after*
    // jshint does it's magic, but jshint set on a setTimeout, so we have to
    // schedule after.
    setTimeout(function () {
      var annotations = cm.state.lint.annotations || [];
      if (typeof cm.updateLinting !== 'undefined') {
        // note: this just updated the *source* reference
        annotations = annotations.filter(function (a) {
          return a.source !== 'loopProtectLine:' + line;
        });
        annotations.push({
          from: CodeMirror.Pos(line-1, 0),
          to: CodeMirror.Pos(line-1, 0),
          message: 'Exiting potential infinite loop.\nTo disable loop protection: add "// noprotect" to your code',
          severity: 'warning',
          source: 'loopProtectLine:' + line
        });

        cm.updateLinting(annotations);
      }
    }, cm.state.lint.options.delay || 0);
  };

  /**
   * When the iframe resizes, update the size text
   */
  renderer.resize = (function () {
    var size = $live.find('.size');

    var hide = throttle(function () {
      size.fadeOut(200);
    }, 2000);

    var embedResizeDone = false;

    return function (data) {
      if (!jsbin.embed) {
        // Display the iframe size in px in the JS Bin UI
        size.show().html(data.width + 'px');
        hide();
      }
      if (jsbin.embed && self !== top && embedResizeDone === false) {
        embedResizeDone = true;
        // Inform the outer page of a size change
        var height = ($body.outerHeight(true) - $(renderer.runner.iframe).height()) + data.offsetHeight;
       window.parent.postMessage({ height: height }, '*');
      }
    };
  }());

  /**
   * When the iframe focuses, simulate that here
   */
  renderer.focus = function () {
    jsbin.panels.focus(jsbin.panels.panels.live);
    // also close any open dropdowns
    closedropdown();
  };

  /**
   * Proxy console logging to JS Bin's console
   */
  renderer.console = function (data) {
    var method = data.method,
        args = data.args;

    if (!window._console) {return;}
    if (!window._console[method]) {method = 'log';}

    // skip the entire console rendering if the console is hidden
    if (!jsbin.panels.panels.console.visible) { return; }

    window._console[method].apply(window._console, args);
  };

  /**
   * Load scripts into rendered iframe
   */
  renderer['console:load:script:success'] = function (url) {
    $document.trigger('console:load:script:success', url);
  };

  renderer['console:load:script:error'] = function (err) {
    $document.trigger('console:load:script:error', err);
  };

  /**
   * Load DOME into rendered iframe
   * TODO abstract these so that they are automatically triggered
   */
  renderer['console:load:dom:success'] = function (url) {
    $document.trigger('console:load:dom:success', url);
  };

  renderer['console:load:dom:error'] = function (err) {
    $document.trigger('console:load:dom:error', err);
  };

  return renderer;

}());

/** ============================================================================
 * Live rendering.
 *
 * Comes in two tasty flavours. Basic mode, which is essentially an IE7
 * fallback. Take a look at https://github.com/jsbin/jsbin/issues/651 for more.
 * It uses the iframe's name and JS Bin's event-stream support to keep the
 * page up-to-date.
 *
 * The second mode uses postMessage to inform the runner of changes to code,
 * config and anything that affects rendering, and also listens for messages
 * coming back to update the JS Bin UI.
 * ========================================================================== */

/**
 * Render live preview.
 * Create the runner iframe, and if postMe wait until the iframe is loaded to
 * start postMessaging the runner.
 */
var renderLivePreview = (function () {

  // Runner iframe
  var iframe;

  // Basic mode
  // This adds the runner iframe to the page. It's only run once.
  if (!$live.find('iframe').length) {
    iframe = document.createElement('iframe');
    iframe.setAttribute('class', 'stretch');
    iframe.setAttribute('sandbox', 'allow-forms allow-pointer-lock allow-popups allow-same-origin allow-scripts');
    iframe.setAttribute('frameBorder', '0');
    iframe.setAttribute('name', '<proxy>');
    $live.prepend(iframe);
    iframe.src = jsbin.runner;
    try {
      iframe.contentWindow.name = '/' + jsbin.state.code + '/' + jsbin.state.revision;
    } catch (e) {
      // ^- this shouldn't really fail, but if we're honest, it's a fucking mystery as to why it even works.
      // problem is: if this throws (because iframe.contentWindow is undefined), then the execution exits
      // and `var renderLivePreview` is set to undefined. The knock on effect is that the calls to renderLivePreview
      // then fail, and jsbin doesn't boot up. Tears all round, so we catch.
    }
  }

  // The big daddy that handles postmessaging the runner.
  var renderLivePreview = function (requested) {
    // No postMessage? Don't render – the event-stream will handle it.
    if (!window.postMessage) { return; }

    // Inform other pages event streaming render to reload
    if (requested) { sendReload(); }
    getPreparedCode().then(function (source) {
      var includeJsInRealtime = jsbin.settings.includejs;

      // Tell the iframe to reload
      var visiblePanels = jsbin.panels.getVisible();
      var outputPanelOpen = visiblePanels.indexOf(jsbin.panels.panels.live) > -1;
      var consolePanelOpen = visiblePanels.indexOf(jsbin.panels.panels.console) > -1;
      if (!outputPanelOpen && !consolePanelOpen) {
        return;
      }
      // this is a flag that helps detect crashed runners
      if (jsbin.settings.includejs) {
        sessionStorage.runnerPending = 1;
      }

      renderer.postMessage('render', {
        source: source,
        options: {
          requested: requested,
          debug: jsbin.settings.debug,
          includeJsInRealtime: jsbin.settings.includejs
        }
      });

    });
  };

  /**
   * Events
   */

  $document.on('codeChange.live', function (event, arg) {
    if (arg.origin === 'setValue' || arg.origin === undefined) {
      return;
    }
    delete sessionStorage.runnerPending;
  });

  // Listen for console input and post it to the iframe
  $document.on('console:run', function (event, cmd) {
    renderer.postMessage('console:run', cmd);
  });

  $document.on('console:load:script', function (event, url) {
    renderer.postMessage('console:load:script', url);
  });

  $document.on('console:load:dom', function (event, html) {
    renderer.postMessage('console:load:dom', html);
  });

  // When the iframe loads, swap round the callbacks and immediately invoke
  // if renderLivePreview was called already.
  var throttle = function (fn, wait) {
    var ready = true;
    var throttled = function () {
      if (ready) {
        ready = false;
        setTimeout(function () {
          ready = true;
        }, wait);
        return fn.apply(null, arguments);
      }
    };
    return throttled;
  };
  return deferCallable(throttle(renderLivePreview, 200), function (done) {
    iframe.onload = function () {
      if (window.postMessage) {
        // Setup postMessage listening to the runner
        $window.on('message', function (event) {
          renderer.handleMessage(event.originalEvent);
        });
        renderer.setup(iframe);
      }
      done();
    };
  });

}());

// this needs to be after renderLivePreview is set (as it's defined using
// var instead of a first class function).
var throttledPreview = throttle(renderLivePreview, 200),
    liveScrollTop = null;

// timer value: used in the delayed render (because iframes don't have
// innerHeight/Width) in Chrome & WebKit
var deferredLiveRender = null;

$document.bind('codeChange.live', codeChangeLive);
<|endoftext|>


<commit_before>var App = {

	socket: null,
	svg: null,
	projection: null,

	config: {
		remove_dot_ms: 10000							// how long to wait to remove map point
	},

	stats: {
		num_tweets: 0,
		num_tweets_mapped: 0
	},

	map_dims: {
		width: 960,
		height: 700
	},

	init: function()
	{
		this.initSocket();
		this.initMap();
	},

	initSocket: function()
	{
		this.socket = io.connect();

		// when we get a "stats" update from server
		this.socket.on("stats", function(response) {
			$(".server-total-count").text(response.data.tt);
			$(".server-geo-count").text(response.data.gt);
			$(".server-connected-clients").text(response.data.cc);

			// uptime
			var server_uptime_ms = response.data.ut;
			var server_uptime_sec = Math.floor(response.data.ut / 1000);
			var server_uptime_human = '';

			if (server_uptime_sec >= 3600) {
				server_uptime_human += (Math.floor(server_uptime_sec / 3600) % 24) + ' hr';
			}
			if (server_uptime_sec >= 60) {
				server_uptime_human += (Math.floor(server_uptime_sec / 60) % 60) + ' min ';
			}

			server_uptime_human += server_uptime_sec % 60 + ' sec';
			$(".server-uptime").text(server_uptime_human);

			var tweets_per_sec = Math.round(response.data.tt / server_uptime_sec);
			$(".tweets-per-sec").text(tweets_per_sec);

		});

		// when we get a "msg" update from server (coordinates)
		this.socket.on("msg", function(data) {

			App.stats.num_tweets_mapped++;

			$(".tweet-count").text(App.stats.num_tweets_mapped);

			if (data.coords) {
				// place point on map
				var p = App.projection([data.coords[0], data.coords[1]]);
				var circle = App.svg.append("circle")
					.attr("cx", p[0])
					.attr("cy", p[1])
					.attr("r", 4)
					.attr("fill","red")
					.attr("opacity", 0.6);

				// remove point after some time
				setTimeout(function() {
					circle.remove();
					App.stats.num_tweets_mapped--;
				}, App.config.remove_dot_ms);
			}
			else if (data.message) {
				console.log("Message from server: " + data.message);
			}
		});
	},

	initMap: function()
	{
		this.projection = d3.geo.stereographic()
			.scale(245)
			.translate([this.map_dims.width / 2, this.map_dims.height / 2])
			.rotate([-20, 0])
			.clipAngle(180 - 1e-4)
			.clipExtent([[0, 0], [this.map_dims.width, this.map_dims.height]])
			.precision(.1);

		var path = d3.geo.path()
			.projection(this.projection);

		var graticule = d3.geo.graticule();

		this.svg = d3.select("#map").append("svg")
			.attr("width", this.map_dims.width)
			.attr("height", this.map_dims.height);

		this.svg.append("path")
			.datum(graticule)
			.attr("class", "graticule")
			.attr("d", path);

		// load world features
		d3.json("/json/world-50m.json", function(error, world) {
			App.svg.insert("path", ".graticule")
				.datum(topojson.feature(world, world.objects.land))
				.attr("class", "land")
				.attr("d", path);

			App.svg.insert("path", ".graticule")
				.datum(topojson.mesh(world, world.objects.countries, function(a, b) { return a !== b; }))
				.attr("class", "boundary")
				.attr("d", path);
			});

		d3.select(self.frameElement).style("height", this.map_dims.height + "px");
	}

};
<commit_msg>human-readable time string (add days)<commit_after>var App = {

	socket: null,
	svg: null,
	projection: null,

	config: {
		remove_dot_ms: 10000							// how long to wait to remove map point
	},

	stats: {
		num_tweets: 0,
		num_tweets_mapped: 0
	},

	map_dims: {
		width: 960,
		height: 700
	},

	init: function()
	{
		this.initSocket();
		this.initMap();
	},

	initSocket: function()
	{
		this.socket = io.connect();

		// when we get a "stats" update from server
		this.socket.on("stats", function(response) {
			$(".server-total-count").text(response.data.tt);
			$(".server-geo-count").text(response.data.gt);
			$(".server-connected-clients").text(response.data.cc);

			// uptime: make human-readable string
			var server_uptime_ms = response.data.ut;
			var server_uptime_sec = Math.floor(response.data.ut / 1000);
			var server_uptime_human = '';

			if (server_uptime_sec >= 86400) {
				var days = Math.floor(server_uptime_sec / 86400);
				server_uptime_human += days + (days===1?' day ' : ' days ');
			}
			if (server_uptime_sec >= 3600) {
				server_uptime_human += (Math.floor(server_uptime_sec / 3600) % 24) + ' hr ';
			}
			if (server_uptime_sec >= 60) {
				server_uptime_human += (Math.floor(server_uptime_sec / 60) % 60) + ' min ';
			}

			server_uptime_human += server_uptime_sec % 60 + ' sec';
			$(".server-uptime").text(server_uptime_human);

			var tweets_per_sec = Math.round(response.data.tt / server_uptime_sec);
			$(".tweets-per-sec").text(tweets_per_sec);

		});

		// when we get a "msg" update from server (coordinates)
		this.socket.on("msg", function(data) {

			App.stats.num_tweets_mapped++;

			$(".tweet-count").text(App.stats.num_tweets_mapped);

			if (data.coords) {
				// place point on map
				var p = App.projection([data.coords[0], data.coords[1]]);
				var circle = App.svg.append("circle")
					.attr("cx", p[0])
					.attr("cy", p[1])
					.attr("r", 4)
					.attr("fill","red")
					.attr("opacity", 0.6);

				// remove point after some time
				setTimeout(function() {
					circle.remove();
					App.stats.num_tweets_mapped--;
				}, App.config.remove_dot_ms);
			}
			else if (data.message) {
				console.log("Message from server: " + data.message);
			}
		});
	},

	initMap: function()
	{
		this.projection = d3.geo.stereographic()
			.scale(245)
			.translate([this.map_dims.width / 2, this.map_dims.height / 2])
			.rotate([-20, 0])
			.clipAngle(180 - 1e-4)
			.clipExtent([[0, 0], [this.map_dims.width, this.map_dims.height]])
			.precision(.1);

		var path = d3.geo.path()
			.projection(this.projection);

		var graticule = d3.geo.graticule();

		this.svg = d3.select("#map").append("svg")
			.attr("width", this.map_dims.width)
			.attr("height", this.map_dims.height);

		this.svg.append("path")
			.datum(graticule)
			.attr("class", "graticule")
			.attr("d", path);

		// load world features
		d3.json("/json/world-50m.json", function(error, world) {
			App.svg.insert("path", ".graticule")
				.datum(topojson.feature(world, world.objects.land))
				.attr("class", "land")
				.attr("d", path);

			App.svg.insert("path", ".graticule")
				.datum(topojson.mesh(world, world.objects.countries, function(a, b) { return a !== b; }))
				.attr("class", "boundary")
				.attr("d", path);
			});

		d3.select(self.frameElement).style("height", this.map_dims.height + "px");
	}

};
<|endoftext|>


<commit_before>/*
 * zoomerang.js - http://yyx990803.github.io/zoomerang/
 */

(function () {

    // elements
    var overlay = document.createElement('div'),
        wrapper = document.createElement('div'),
        target,
        parent,
        placeholder

    // state
    var shown = false,
        lock  = false,
        originalStyles

    // options
    var options = {
        transitionDuration: '.4s',
        transitionTimingFunction: 'cubic-bezier(.4,0,0,1)',
        bgColor: '#fff',
        bgOpacity: 1,
        maxWidth: 1000,
        maxHeight: 1000
    }

    // compatibility stuff
    var trans = sniffTransition(),
        transitionProp = trans.transition,
        transformProp = trans.transform,
        transformCssProp = transformProp.replace(/(.*)Transform/, '-$1-transform'),
        transEndEvent = trans.transEnd

    setStyle(overlay, {
        position: 'fixed',
        display: 'none',
        zIndex: 99998,
        top: 0,
        left: 0,
        right: 0,
        bottom: 0,
        opacity: 0,
        backgroundColor: options.bgColor,
        transition: 'opacity ' +
            options.transitionDuration + ' ' +
            options.transitionTimingFunction
    })

    setStyle(wrapper, {
        position: 'fixed',
        zIndex: 99999,
        top: '50%',
        left: '50%',
        width: 0,
        height: 0
    })

    // helpers ----------------------------------------------------------------

    function setStyle (el, styles, remember) {
        checkTrans(styles)
        var s = el.style,
            original = {}
        for (var key in styles) {
            if (remember) {
                original[key] = s[key] || ''
            }
            s[key] = styles[key]
        }
        return original
    }

    function sniffTransition () {
        var ret   = {},
            trans = ['transition', 'webkitTransition', 'mozTransition'],
            tform = ['transform', 'webkitTransform', 'mozTransform'],
            end   = {
                'transition'       : 'transitionend',
                'mozTransition'    : 'transitionend',
                'webkitTransition' : 'webkitTransitionEnd'
            }
        trans.some(function (prop) {
            if (overlay.style[prop] !== undefined) {
                ret.transition = prop
                ret.transEnd = end[prop]
                return true
            }
        })
        tform.some(function (prop) {
            if (overlay.style[prop] !== undefined) {
                ret.transform = prop
                return true
            }
        })
        return ret
    }

    function checkTrans (styles) {
        if (styles.transition) {
            styles[transitionProp] = styles.transition
        }
        if (styles.transform) {
            styles[transformProp] = styles.transform
        }
    }

    var stylesToCopy = [
        'position', 'display', 'float',
        'top', 'left', 'right', 'bottom',
        'marginBottom', 'marginLeft', 'marginRight',
        'marginTop', 'font', 'lineHeight', 'verticalAlign'
    ]

    function copy (el, box) {
        var styles = getComputedStyle(el),
            ph = document.createElement('div'),
            i = stylesToCopy.length, key
        while (i--) {
            key = stylesToCopy[i]
            ph.style[key] = styles[key]
        }
        setStyle(ph, {
            visibility: 'hidden',
            width: box.width + 'px',
            height: box.height + 'px',
            display: styles.display === 'inline'
                ? 'inline-block'
                : styles.display
        })
        if (options.deepCopy) {
            ph.innerHTML = el.innerHTML
        } else {
            ph.textContent = el.textContent
        }
        return ph
    }

    var api = {

        config: function (opts) {

            if (!opts) return options
            for (var key in opts) {
                options[key] = opts[key]
            }
            setStyle(overlay, {
                backgroundColor: options.bgColor,
                transition: 'opacity ' +
                    options.transitionDuration + ' ' +
                    options.transitionTimingFunction
            })
            return this
        },

        open: function (el) {

            if (lock || shown) return

            target = typeof el === 'string'
                ? document.querySelector(el)
                : el

            shown = true
            parent = target.parentNode

            var p     = target.getBoundingClientRect(),
                scale = Math.min(options.maxWidth / p.width, options.maxHeight / p.height),
                dx    = p.left - (window.innerWidth - p.width) / 2,
                dy    = p.top - (window.innerHeight - p.height) / 2

            placeholder = copy(target, p)

            originalStyles = setStyle(target, {
                position: 'absolute',
                top: 0,
                left: 0,
                right: '',
                bottom: '',
                whiteSpace: 'nowrap',
                marginTop: -p.height / 2 + 'px',
                marginLeft: -p.width / 2 + 'px',
                transform: 'translate(' + dx + 'px, ' + dy + 'px)',
                transition: ''
            }, true)

            // deal with % width and height
            setStyle(wrapper, {
                width: p.width + 'px',
                height: p.height + 'px'
            })

            // insert overlay & placeholder
            parent.appendChild(overlay)
            parent.appendChild(wrapper)
            parent.insertBefore(placeholder, target)
            wrapper.appendChild(target)
            overlay.style.display = 'block'

            // force layout
            var force = target.offsetHeight

            // trigger transition
            overlay.style.opacity = options.bgOpacity
            setStyle(target, {
                transition:
                    transformCssProp + ' ' +
                    options.transitionDuration + ' ' +
                    options.transitionTimingFunction,
                transform: 'scale(' + scale + ')'
            })
            return this
        },

        close: function () {

            if (!shown || lock) return
            lock = true

            var p  = placeholder.getBoundingClientRect(),
                dx = p.left - (window.innerWidth - p.width) / 2,
                dy = p.top - (window.innerHeight - p.height) / 2

            overlay.style.opacity = 0
            setStyle(target, {
                transform: 'translate(' + dx + 'px, ' + dy + 'px)'
            })

            target.addEventListener(transEndEvent, onEnd)
            function onEnd () {
                target.removeEventListener(transEndEvent, onEnd)
                setStyle(target, originalStyles)
                parent.insertBefore(target, placeholder)
                parent.removeChild(placeholder)
                parent.removeChild(overlay)
                parent.removeChild(wrapper)
                overlay.style.display = 'none'
                placeholder = null
                shown = false
                lock = false
            }

            return this
        },

        listen: function listen (el) {

            if (typeof el === 'string') {
                var els = document.querySelectorAll(el),
                    i = els.length
                while (i--) {
                    listen(els[i])
                }
                return
            }

            el.addEventListener('click', function (e) {
                e.stopPropagation()
                if (shown) {
                    api.close()
                } else {
                    api.open(el)
                }
            })

            return this
        }
    }

    overlay.addEventListener('click', api.close)

    // umd expose
    if (typeof exports == "object") {
        module.exports = api
    } else if (typeof define == "function" && define.amd) {
        define(function(){ return api })
    } else {
        this.Zoomerang = api
    }
})()<commit_msg>updated zoomerang to version 0.1.6<commit_after>/*
 * zoomerang.js - http://yyx990803.github.io/zoomerang/
 */

(function () {

    // regex
    var percentageRE = /^([\d\.]+)%$/

    // elements
    var overlay = document.createElement('div'),
        wrapper = document.createElement('div'),
        target,
        parent,
        placeholder

    // state
    var shown = false,
        lock  = false,
        originalStyles

    // options
    var options = {
        transitionDuration: '.4s',
        transitionTimingFunction: 'cubic-bezier(.4,0,0,1)',
        bgColor: '#fff',
        bgOpacity: 1,
        maxWidth: 300,
        maxHeight: 300
    }

    // compatibility stuff
    var trans = sniffTransition(),
        transitionProp = trans.transition,
        transformProp = trans.transform,
        transformCssProp = transformProp.replace(/(.*)Transform/, '-$1-transform'),
        transEndEvent = trans.transEnd

    setStyle(overlay, {
        position: 'fixed',
        display: 'none',
        zIndex: 99998,
        top: 0,
        left: 0,
        right: 0,
        bottom: 0,
        opacity: 0,
        backgroundColor: options.bgColor,
        transition: 'opacity ' +
            options.transitionDuration + ' ' +
            options.transitionTimingFunction
    })

    setStyle(wrapper, {
        position: 'fixed',
        zIndex: 99999,
        top: '50%',
        left: '50%',
        width: 0,
        height: 0
    })

    // helpers ----------------------------------------------------------------

    function setStyle (el, styles, remember) {
        checkTrans(styles)
        var s = el.style,
            original = {}
        for (var key in styles) {
            if (remember) {
                original[key] = s[key] || ''
            }
            s[key] = styles[key]
        }
        return original
    }

    function sniffTransition () {
        var ret   = {},
            trans = ['webkitTransition', 'transition', 'mozTransition'],
            tform = ['webkitTransform', 'transform', 'mozTransform'],
            end   = {
                'transition'       : 'transitionend',
                'mozTransition'    : 'transitionend',
                'webkitTransition' : 'webkitTransitionEnd'
            }
        trans.some(function (prop) {
            if (overlay.style[prop] !== undefined) {
                ret.transition = prop
                ret.transEnd = end[prop]
                return true
            }
        })
        tform.some(function (prop) {
            if (overlay.style[prop] !== undefined) {
                ret.transform = prop
                return true
            }
        })
        return ret
    }

    function checkTrans (styles) {
        if (styles.transition) {
            styles[transitionProp] = styles.transition
        }
        if (styles.transform) {
            styles[transformProp] = styles.transform
        }
    }

    var stylesToCopy = [
        'position', 'display', 'float',
        'top', 'left', 'right', 'bottom',
        'marginBottom', 'marginLeft', 'marginRight',
        'marginTop', 'font', 'lineHeight', 'verticalAlign'
    ]

    function copy (el, box) {
        var styles = getComputedStyle(el),
            ph = document.createElement('div'),
            i = stylesToCopy.length, key
        while (i--) {
            key = stylesToCopy[i]
            ph.style[key] = styles[key]
        }
        setStyle(ph, {
            visibility: 'hidden',
            width: box.width + 'px',
            height: box.height + 'px',
            display: styles.display === 'inline'
                ? 'inline-block'
                : styles.display
        })
        if (options.deepCopy) {
            ph.innerHTML = el.innerHTML
        } else {
            ph.textContent = el.textContent
        }
        return ph
    }

    var api = {

        config: function (opts) {

            if (!opts) return options
            for (var key in opts) {
                options[key] = opts[key]
            }
            setStyle(overlay, {
                backgroundColor: options.bgColor,
                transition: 'opacity ' +
                    options.transitionDuration + ' ' +
                    options.transitionTimingFunction
            })
            return this
        },

        open: function (el) {

            if (lock || shown) return

            target = typeof el === 'string'
                ? document.querySelector(el)
                : el

            shown = true
            parent = target.parentNode

            var p     = target.getBoundingClientRect(),
                scale = Math.min(options.maxWidth / p.width, options.maxHeight / p.height),
                dx    = p.left - (window.innerWidth - p.width) / 2,
                dy    = p.top - (window.innerHeight - p.height) / 2

            placeholder = copy(target, p)

            originalStyles = setStyle(target, {
                position: 'absolute',
                top: 0,
                left: 0,
                right: '',
                bottom: '',
                whiteSpace: 'nowrap',
                marginTop: -p.height / 2 + 'px',
                marginLeft: -p.width / 2 + 'px',
                transform: 'translate(' + dx + 'px, ' + dy + 'px)',
                transition: ''
            }, true)

            // deal with % width and height
            var wPctMatch = target.style.width.match(percentageRE),
                hPctMatch = target.style.height.match(percentageRE)
            if (wPctMatch || hPctMatch) {
                var wPct = wPctMatch ? +wPctMatch[1] / 100 : 1,
                    hPct = hPctMatch ? +hPctMatch[1] / 100 : 1
                setStyle(wrapper, {
                    width: ~~(p.width / wPct) + 'px',
                    height: ~~(p.height / hPct) + 'px'
                })
            }

            // insert overlay & placeholder
            parent.appendChild(overlay)
            parent.appendChild(wrapper)
            parent.insertBefore(placeholder, target)
            wrapper.appendChild(target)
            overlay.style.display = 'block'

            // force layout
            var force = target.offsetHeight

            // trigger transition
            overlay.style.opacity = options.bgOpacity
            setStyle(target, {
                transition:
                    transformCssProp + ' ' +
                    options.transitionDuration + ' ' +
                    options.transitionTimingFunction,
                transform: 'scale(' + scale + ')'
            })
            return this
        },

        close: function () {

            if (!shown || lock) return
            lock = true

            var p  = placeholder.getBoundingClientRect(),
                dx = p.left - (window.innerWidth - p.width) / 2,
                dy = p.top - (window.innerHeight - p.height) / 2

            overlay.style.opacity = 0
            setStyle(target, {
                transform: 'translate(' + dx + 'px, ' + dy + 'px)'
            })

            target.addEventListener(transEndEvent, onEnd)
            function onEnd () {
                target.removeEventListener(transEndEvent, onEnd)
                setStyle(target, originalStyles)
                parent.insertBefore(target, placeholder)
                parent.removeChild(placeholder)
                parent.removeChild(overlay)
                parent.removeChild(wrapper)
                overlay.style.display = 'none'
                placeholder = null
                shown = false
                lock = false
            }

            return this
        },

        listen: function listen (el) {

            if (typeof el === 'string') {
                var els = document.querySelectorAll(el),
                    i = els.length
                while (i--) {
                    listen(els[i])
                }
                return
            }

            el.addEventListener('click', function (e) {
                e.stopPropagation()
                if (shown) {
                    api.close()
                } else {
                    api.open(el)
                }
            })

            return this
        }
    }

    overlay.addEventListener('click', api.close)
    wrapper.addEventListener('click', api.close)

    // umd expose
    if (typeof exports == "object") {
        module.exports = api
    } else if (typeof define == "function" && define.amd) {
        define(function(){ return api })
    } else {
        this.Zoomerang = api
    }
})();
<|endoftext|>


<commit_before>/*
* Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See full license at the bottom of this file.
*/

var tenant = '{your_subdomain}.onmicrosoft.com';
var clientId = '{your_app_client_ID}';

// *********************************************************
//
// O365-Angular-Unified-API-Connect, https://github.com/OfficeDev/O365-Angular-Unified-API-Connect
//
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// MIT License:
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// *********************************************************
<commit_msg>Removed unused variable.<commit_after>/*
* Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See full license at the bottom of this file.
*/

var clientId = '{your_app_client_ID}';

// *********************************************************
//
// O365-Angular-Unified-API-Connect, https://github.com/OfficeDev/O365-Angular-Unified-API-Connect
//
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// MIT License:
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// *********************************************************
<|endoftext|>


<commit_before>/*global

$: true,
playlistManager: true,
loadPlaylistView: true,

*/

/** EVENTS
 ****************************************************************************/

function deleteVideoButtonClicked(li) {
    var playlist = playlistManager.getCurrentlySelectedPlaylist();
    var allSelectedVideos = li.parent().find('.video.selected');

    $.each(allSelectedVideos, function(index, item) {
        $video = $(item);
        playlist.deleteVideo($video.index());
        $video.remove();
    });

    playlistManager.save();
}

function playlistMouseDown(event) {
	$('#left-menu li').removeClass('selected');
	$(this).addClass('selected');
}

function loadPlaylist(playlistId) {
    $.ajax({
        url: '/api/playlists/' + playlistId,
        type: 'GET',
        statusCode: {
            200: function(data) {
                var playlist = new Playlist(data.title, data.videos, data.remoteId, data.owner, data.isPrivate);
                playlist.createViews();
                loadPlaylistView(playlist);
            },
            404: function(data) {
                alert("No such playlist found");
            }
        }
    });
}

function savePlaylistButtonClicked(event) {
    var $playlistBar = $('#right > .playlists .info');
    var playlist = $playlistBar.data('model');
    var newPlaylist = playlist.copy(); // create copy without connection to remote

    newPlaylist.createViews();
    playlistManager.addPlaylist(newPlaylist);
    newPlaylist.getMenuView().appendTo('#left .playlists ul');

    if (logged_in) {
        newPlaylist.createNewPlaylistOnRemote(function() {
            playlistManager.save();
            newPlaylist.getMenuView().addClass('remote');
        });
    } else {
        playlistManager.save();
    }

    $playlistBar.find('.copy').hide();
}

function syncPlaylistButtonClicked(event) {
    var playlist = playlistManager.getCurrentlySelectedPlaylist();
    console.log('syncing playlist ' + playlist.title);
    playlist.sync(function() {
        updatePlaylistBar(playlist);
        playlistManager.save();
        playlist.getMenuView().addClass('remote');
        history.pushState(null, null, playlist.getUrl());
    });
}

function showPlaylistSharePopup(playlist, elem, arrowDirection) {
    $('#share-playlist-popup .link input').val(playlist.getUrl());

    $('#share-playlist-popup .twitter')
        .unbind('click')
        .click(function(event) {
            event.preventDefault();
            window.open(playlist.getTwitterShareUrl(), 'Share playlist on Twitter', 400, 400);
            return false;
        });

    $('#share-playlist-popup .facebook')
        .unbind('click')
        .click(function(event) {
            event.preventDefault();
            window.open(playlist.getFacebookShareUrl(), 'Share playlist on Facebook', 400, 400);
            return false;
        });

    elem.arrowPopup('#share-playlist-popup', arrowDirection);
}

function shareButtonClicked(event) {
    var playlistBar = $(this).parent();
    var playlist = playlistBar.data('playlist');
    showPlaylistSharePopup(playlist, $(this), 'up');
}

function updatePlaylistBar(playlist) {
    var $playlistBar = $('#right > .playlists .info');
    $playlistBar.data('model', playlist);
    $playlistBar.find('.title').text(playlist.title);
    $playlistBar.find('.owner').hide();
    $playlistBar.find('.copy').hide().unbind('click');
    $playlistBar.find('.sync').hide().unbind('click');

    if (playlist.owner) {
        if (my_user_id === '' || playlist.owner.id !== parseInt(my_user_id, 10)) {
            $playlistBar.find('.owner').text(playlist.owner.name).show();

            // Add save button if not already saved
            if (!playlistManager.getPlaylistsMap().hasOwnProperty(playlist.remoteId)) {
               $playlistBar.find('.copy').show().one('click', savePlaylistButtonClicked);
            }
        }
    } else if (logged_in) {
        $playlistBar.find('.sync').show().one('click', syncPlaylistButtonClicked);
    }
}

function loadPlaylistView(playlist) {
    $('#right > div').hide();

	$('#right > .playlists .pane').hide().removeClass('active');
    $('#left .menu li').removeClass('selected');

    playlist.playlistDOMHandle.addClass('active');
    playlist.leftMenuDOMHandle.addClass('selected');

    updatePlaylistBar(playlist);

    if (playlist.playlistDOMHandle.find('.video').length !== playlist.videos.length) {
        playlist.playlistDOMHandle.html('');
        $.each(playlist.videos, function(i, item) {
            if (item) {
                $video = item.createListView();
                $video.data('additionalMenuButtons', [{
                    title: 'Delete',
                    args: $video,
                    callback: deleteVideoButtonClicked
                }]);
                $video.addClass('droppable');
                $video.addClass('draggable');
                $video.addClass('reorderable');
                $video.appendTo(playlist.playlistDOMHandle);
            }
        });
    }
	playlist.playlistDOMHandle.show();
    $('#right > .playlists').show();
}

/**
 * Mark the playlistElem in the #left as selected, then
 * fill #playlist with the contained videos.
 */
function playlistClicked(event) {
    var playlist = $(this).data('model');

    if (playlist.remoteId) {
        history.pushState(null, null, playlist.getUrl());
    } else {
        history.pushState(null, null, '/');
    }

    loadPlaylistView(playlist);
}

/** CLASS PLAYLIST
 ****************************************************************************/

function Playlist(title, videos, remoteId, owner, isPrivate) {
    var i,
        self = this;
    self.title = title;
    self.videos = [];
    /* The loop that adds videos to self.videos is moved to the end of the class to avoid reference errors */
    self.remoteId = remoteId || null;
    self.isPrivate = isPrivate || false;
    self.owner = owner;
    self.synced = true; // not part of JSON structure
    self.syncing = false; // not part of JSON structure
    self.leftMenuDOMHandle = null;
    self.playlistDOMHandle = null;

    self.getTwitterShareUrl = function() {
        var url = self.getUrl(),
            text = "Check out self playlist!" + ' -- ' + self.title;
        return encodeURI('http://twitter.com/share?related=youtify&via=youtify' + '&url=' + url + '&counturl=' + url + '&text=' + text);
    };

    self.getFacebookShareUrl = function() {
        var url = self.getUrl();
        return 'http://facebook.com/sharer.php?u=' + url;
    };

    self.getUrl = function() {
        return location.protocol + '//' + location.host + '/users/' + self.owner.id + '/playlists/' + self.remoteId;
    };

    self.copy = function() {
        return new Playlist(self.title, self.videos);
    };

    self.getMenuView = function() {
        if (self.leftMenuDOMHandle === null) {
            self.createViews();
        }
        return self.leftMenuDOMHandle;
    };

    self.setAsPlaying = function() {
        $('#left .menu li').removeClass('playing');
        self.getMenuView().addClass('playing');
    };

    self.rename = function(newTitle) {
        var title = $.trim(newTitle);
        if (title.length > 0 && title.length < 50) {
            self.title = newTitle;
        }
        self.synced = false;
        if (self.leftMenuDOMHandle) {
            self.leftMenuDOMHandle.find('.title').text(newTitle);
        }
    };

    self.unsync = function(callback) {
        $.ajax({
            type: 'DELETE',
            url: '/api/playlists/' + self.remoteId,
			statusCode: {
				200: function(data) {
					if (callback) {
						callback();
					}
				},
				404: function(data) {
					Notification.warn(translations['No such playlist found']);
				},
				409: function(data) {
					Notification.error(translations['Your account has been used somewhere else. Please reload the page.']);
				}
			}
        });

        self.remoteId = null;
        self.owner = null;
    };

    self.createNewPlaylistOnRemote = function(callback) {
        var self = self,
            params = {
                'json': JSON.stringify(self.toJSON()),
				'device': device
            };

        self.syncing = true;

		$.ajax({
            type: 'POST',
            url: '/api/playlists',
			data: params,
			statusCode: {
				200: function(data, textStatus) {
					self.syncing = false;
					if (textStatus === 'success') {
						self.remoteId = data.remoteId;
						self.owner = data.owner;
						self.synced = true;
                    } else {
						alert('Failed to create new playlist ' + self.title);
					}
					if (callback) {
						callback();
					}
				},
				409: function(data) {
					Notification.error(translations['Your account has been used somewhere else. Please reload the page.']);
				}
			}
        });
    };

    self.updatePlaylistOnRemote = function(callback) {
        var self = self,
            params = {
                'json': JSON.stringify(self.toJSON()),
				'device': device
            };

        self.syncing = true;

		$.ajax({
            type: 'POST',
            url: '/api/playlists/' + self.remoteId,
			data: params,
			statusCode: {
				200: function(data, textStatus) {
					self.syncing = false;
					if (textStatus === 'success') {
						self.synced = true;
					} else {
						alert('Failed to create new playlist ' + self.title);
					}
					if (callback) {
						callback();
					}
				},
				404: function(data) {
					Notification.warn(translations['No such playlist found']);
				},
				409: function(data) {
					Notification.error(translations['Your account has been used somewhere else. Please reload the page.']);
				}
			}
        });
    };

    self.sync = function(callback) {
        if (self.remoteId && self.synced) {
            callback();
        } else if (self.remoteId) {
            self.updatePlaylistOnRemote(callback);
        } else {
            self.createNewPlaylistOnRemote(callback);
        }
    };

    self.addVideo = function(video) {
        if (self.syncing) {
            alert("Please wait until the playlist is synced");
            return;
        }

        var newVideo = video.clone();
        newVideo.onPlayCallback = self.setAsPlaying;
        self.videos.push(newVideo);

        var $video = newVideo.createListView();
        $video.data('additionalMenuButtons', [{
            title: 'Delete',
            args: $video,
            callback: deleteVideoButtonClicked
        }]);
        $video.addClass('droppable');
        $video.addClass('draggable');
        $video.addClass('reorderable');
        $video.appendTo(self.playlistDOMHandle);

        self.synced = false;
    };

    self.moveVideo = function(sourceIndex, destIndex) {
        if (self.syncing) {
            alert("Please wait until the playlist is synced");
            return;
        }

        var tmp;

        if (destIndex > sourceIndex) {
            destIndex -= 1;
        }

        tmp = self.videos.splice(sourceIndex, 1)[0];
        self.videos.splice(destIndex, 0, tmp);

        self.synced = false;
    };

    self.deleteVideo = function(index) {
        if (self.syncing) {
            alert("Please wait until the playlist is synced");
            return;
        }

        self.videos.splice(index, 1);
        self.synced = false;
    };

    self.toJSON = function() {
        return {
            title: self.title,
            videos: self.videos,
            remoteId: self.remoteId,
            owner: self.owner,
            isPrivate: self.isPrivate
        };
    };

    self.createViews = function() {
        var table = $('
')
                .addClass('pane')
                .appendTo('#right > .playlists')
                .data('model', self),
            li = $('
')
                .addClass("playlistElem")
                .addClass('droppable')
                .data('model', self)
                .bind('contextmenu', showPlaylistContextMenu)
                .mousedown(playlistMouseDown)
                .click(playlistClicked);

        $('').text(self.title).appendTo(li);

        if (self.remoteId) {
            li.addClass('remote');
        } else {
            li.addClass('local');
        }

        if (self.isPrivate) {
            li.addClass('private');
        }
        self.leftMenuDOMHandle = li;
        self.playlistDOMHandle = table;
    };

	self.removeDuplicates = function() {
		var deleted = 0,
            i, j;
		for (i = self.videos.length-1; i > 0; i -= 1) {
			for (j = i-1; j >= 0; j -= 1) {
				if (self.videos[i].videoId === self.videos[j].videoId) {
					self.deleteVideo(j);
					deleted += 1;
					break;
				}
			}
		}
		playlistManager.save();
		loadPlaylistView(self);
		return deleted;
	};

    for (i = 0; i < videos.length; i+= 1) {
        if (videos[i]) {
            var video = new Video(videos[i].videoId, videos[i].title, videos[i].type, videos[i].rating, self.setAsPlaying);
            self.videos.push(video);
        }
    }
}
<commit_msg>Removed duplicate variables<commit_after>/*global

$: true,
playlistManager: true,
loadPlaylistView: true,

*/

/** EVENTS
 ****************************************************************************/

function deleteVideoButtonClicked(li) {
    var playlist = playlistManager.getCurrentlySelectedPlaylist();
    var allSelectedVideos = li.parent().find('.video.selected');

    $.each(allSelectedVideos, function(index, item) {
        $video = $(item);
        playlist.deleteVideo($video.index());
        $video.remove();
    });

    playlistManager.save();
}

function playlistMouseDown(event) {
	$('#left-menu li').removeClass('selected');
	$(this).addClass('selected');
}

function loadPlaylist(playlistId) {
    $.ajax({
        url: '/api/playlists/' + playlistId,
        type: 'GET',
        statusCode: {
            200: function(data) {
                var playlist = new Playlist(data.title, data.videos, data.remoteId, data.owner, data.isPrivate);
                playlist.createViews();
                loadPlaylistView(playlist);
            },
            404: function(data) {
                alert("No such playlist found");
            }
        }
    });
}

function savePlaylistButtonClicked(event) {
    var $playlistBar = $('#right > .playlists .info');
    var playlist = $playlistBar.data('model');
    var newPlaylist = playlist.copy(); // create copy without connection to remote

    newPlaylist.createViews();
    playlistManager.addPlaylist(newPlaylist);
    newPlaylist.getMenuView().appendTo('#left .playlists ul');

    if (logged_in) {
        newPlaylist.createNewPlaylistOnRemote(function() {
            playlistManager.save();
            newPlaylist.getMenuView().addClass('remote');
        });
    } else {
        playlistManager.save();
    }

    $playlistBar.find('.copy').hide();
}

function syncPlaylistButtonClicked(event) {
    var playlist = playlistManager.getCurrentlySelectedPlaylist();
    console.log('syncing playlist ' + playlist.title);
    playlist.sync(function() {
        updatePlaylistBar(playlist);
        playlistManager.save();
        playlist.getMenuView().addClass('remote');
        history.pushState(null, null, playlist.getUrl());
    });
}

function showPlaylistSharePopup(playlist, elem, arrowDirection) {
    $('#share-playlist-popup .link input').val(playlist.getUrl());

    $('#share-playlist-popup .twitter')
        .unbind('click')
        .click(function(event) {
            event.preventDefault();
            window.open(playlist.getTwitterShareUrl(), 'Share playlist on Twitter', 400, 400);
            return false;
        });

    $('#share-playlist-popup .facebook')
        .unbind('click')
        .click(function(event) {
            event.preventDefault();
            window.open(playlist.getFacebookShareUrl(), 'Share playlist on Facebook', 400, 400);
            return false;
        });

    elem.arrowPopup('#share-playlist-popup', arrowDirection);
}

function shareButtonClicked(event) {
    var playlistBar = $(this).parent();
    var playlist = playlistBar.data('playlist');
    showPlaylistSharePopup(playlist, $(this), 'up');
}

function updatePlaylistBar(playlist) {
    var $playlistBar = $('#right > .playlists .info');
    $playlistBar.data('model', playlist);
    $playlistBar.find('.title').text(playlist.title);
    $playlistBar.find('.owner').hide();
    $playlistBar.find('.copy').hide().unbind('click');
    $playlistBar.find('.sync').hide().unbind('click');

    if (playlist.owner) {
        if (my_user_id === '' || playlist.owner.id !== parseInt(my_user_id, 10)) {
            $playlistBar.find('.owner').text(playlist.owner.name).show();

            // Add save button if not already saved
            if (!playlistManager.getPlaylistsMap().hasOwnProperty(playlist.remoteId)) {
               $playlistBar.find('.copy').show().one('click', savePlaylistButtonClicked);
            }
        }
    } else if (logged_in) {
        $playlistBar.find('.sync').show().one('click', syncPlaylistButtonClicked);
    }
}

function loadPlaylistView(playlist) {
    $('#right > div').hide();

	$('#right > .playlists .pane').hide().removeClass('active');
    $('#left .menu li').removeClass('selected');

    playlist.playlistDOMHandle.addClass('active');
    playlist.leftMenuDOMHandle.addClass('selected');

    updatePlaylistBar(playlist);

    if (playlist.playlistDOMHandle.find('.video').length !== playlist.videos.length) {
        playlist.playlistDOMHandle.html('');
        $.each(playlist.videos, function(i, item) {
            if (item) {
                $video = item.createListView();
                $video.data('additionalMenuButtons', [{
                    title: 'Delete',
                    args: $video,
                    callback: deleteVideoButtonClicked
                }]);
                $video.addClass('droppable');
                $video.addClass('draggable');
                $video.addClass('reorderable');
                $video.appendTo(playlist.playlistDOMHandle);
            }
        });
    }
	playlist.playlistDOMHandle.show();
    $('#right > .playlists').show();
}

/**
 * Mark the playlistElem in the #left as selected, then
 * fill #playlist with the contained videos.
 */
function playlistClicked(event) {
    var playlist = $(this).data('model');

    if (playlist.remoteId) {
        history.pushState(null, null, playlist.getUrl());
    } else {
        history.pushState(null, null, '/');
    }

    loadPlaylistView(playlist);
}

/** CLASS PLAYLIST
 ****************************************************************************/

function Playlist(title, videos, remoteId, owner, isPrivate) {
    var i,
        self = this;
    self.title = title;
    self.videos = [];
    /* The loop that adds videos to self.videos is moved to the end of the class to avoid reference errors */
    self.remoteId = remoteId || null;
    self.isPrivate = isPrivate || false;
    self.owner = owner;
    self.synced = true; // not part of JSON structure
    self.syncing = false; // not part of JSON structure
    self.leftMenuDOMHandle = null;
    self.playlistDOMHandle = null;

    self.getTwitterShareUrl = function() {
        var url = self.getUrl(),
            text = "Check out self playlist!" + ' -- ' + self.title;
        return encodeURI('http://twitter.com/share?related=youtify&via=youtify' + '&url=' + url + '&counturl=' + url + '&text=' + text);
    };

    self.getFacebookShareUrl = function() {
        var url = self.getUrl();
        return 'http://facebook.com/sharer.php?u=' + url;
    };

    self.getUrl = function() {
        return location.protocol + '//' + location.host + '/users/' + self.owner.id + '/playlists/' + self.remoteId;
    };

    self.copy = function() {
        return new Playlist(self.title, self.videos);
    };

    self.getMenuView = function() {
        if (self.leftMenuDOMHandle === null) {
            self.createViews();
        }
        return self.leftMenuDOMHandle;
    };

    self.setAsPlaying = function() {
        $('#left .menu li').removeClass('playing');
        self.getMenuView().addClass('playing');
    };

    self.rename = function(newTitle) {
        var title = $.trim(newTitle);
        if (title.length > 0 && title.length < 50) {
            self.title = newTitle;
        }
        self.synced = false;
        if (self.leftMenuDOMHandle) {
            self.leftMenuDOMHandle.find('.title').text(newTitle);
        }
    };

    self.unsync = function(callback) {
        $.ajax({
            type: 'DELETE',
            url: '/api/playlists/' + self.remoteId,
			statusCode: {
				200: function(data) {
					if (callback) {
						callback();
					}
				},
				404: function(data) {
					Notification.warn(translations['No such playlist found']);
				},
				409: function(data) {
					Notification.error(translations['Your account has been used somewhere else. Please reload the page.']);
				}
			}
        });

        self.remoteId = null;
        self.owner = null;
    };

    self.createNewPlaylistOnRemote = function(callback) {
        var params = {
                'json': JSON.stringify(self.toJSON()),
				'device': device
            };

        self.syncing = true;

		$.ajax({
            type: 'POST',
            url: '/api/playlists',
			data: params,
			statusCode: {
				200: function(data, textStatus) {
					self.syncing = false;
					if (textStatus === 'success') {
						self.remoteId = data.remoteId;
						self.owner = data.owner;
						self.synced = true;
                    } else {
						alert('Failed to create new playlist ' + self.title);
					}
					if (callback) {
						callback();
					}
				},
				409: function(data) {
					Notification.error(translations['Your account has been used somewhere else. Please reload the page.']);
				}
			}
        });
    };

    self.updatePlaylistOnRemote = function(callback) {
        var params = {
                'json': JSON.stringify(self.toJSON()),
				'device': device
            };

        self.syncing = true;

		$.ajax({
            type: 'POST',
            url: '/api/playlists/' + self.remoteId,
			data: params,
			statusCode: {
				200: function(data, textStatus) {
					self.syncing = false;
					if (textStatus === 'success') {
						self.synced = true;
					} else {
						alert('Failed to create new playlist ' + self.title);
					}
					if (callback) {
						callback();
					}
				},
				404: function(data) {
					Notification.warn(translations['No such playlist found']);
				},
				409: function(data) {
					Notification.error(translations['Your account has been used somewhere else. Please reload the page.']);
				}
			}
        });
    };

    self.sync = function(callback) {
        if (self.remoteId && self.synced) {
            callback();
        } else if (self.remoteId) {
            self.updatePlaylistOnRemote(callback);
        } else {
            self.createNewPlaylistOnRemote(callback);
        }
    };

    self.addVideo = function(video) {
        if (self.syncing) {
            alert("Please wait until the playlist is synced");
            return;
        }

        var newVideo = video.clone();
        newVideo.onPlayCallback = self.setAsPlaying;
        self.videos.push(newVideo);

        var $video = newVideo.createListView();
        $video.data('additionalMenuButtons', [{
            title: 'Delete',
            args: $video,
            callback: deleteVideoButtonClicked
        }]);
        $video.addClass('droppable');
        $video.addClass('draggable');
        $video.addClass('reorderable');
        $video.appendTo(self.playlistDOMHandle);

        self.synced = false;
    };

    self.moveVideo = function(sourceIndex, destIndex) {
        if (self.syncing) {
            alert("Please wait until the playlist is synced");
            return;
        }

        var tmp;

        if (destIndex > sourceIndex) {
            destIndex -= 1;
        }

        tmp = self.videos.splice(sourceIndex, 1)[0];
        self.videos.splice(destIndex, 0, tmp);

        self.synced = false;
    };

    self.deleteVideo = function(index) {
        if (self.syncing) {
            alert("Please wait until the playlist is synced");
            return;
        }

        self.videos.splice(index, 1);
        self.synced = false;
    };

    self.toJSON = function() {
        return {
            title: self.title,
            videos: self.videos,
            remoteId: self.remoteId,
            owner: self.owner,
            isPrivate: self.isPrivate
        };
    };

    self.createViews = function() {
        var table = $('
')
                .addClass('pane')
                .appendTo('#right > .playlists')
                .data('model', self),
            li = $('
')
                .addClass("playlistElem")
                .addClass('droppable')
                .data('model', self)
                .bind('contextmenu', showPlaylistContextMenu)
                .mousedown(playlistMouseDown)
                .click(playlistClicked);

        $('').text(self.title).appendTo(li);

        if (self.remoteId) {
            li.addClass('remote');
        } else {
            li.addClass('local');
        }

        if (self.isPrivate) {
            li.addClass('private');
        }
        self.leftMenuDOMHandle = li;
        self.playlistDOMHandle = table;
    };

	self.removeDuplicates = function() {
		var deleted = 0,
            i, j;
		for (i = self.videos.length-1; i > 0; i -= 1) {
			for (j = i-1; j >= 0; j -= 1) {
				if (self.videos[i].videoId === self.videos[j].videoId) {
					self.deleteVideo(j);
					deleted += 1;
					break;
				}
			}
		}
		playlistManager.save();
		loadPlaylistView(self);
		return deleted;
	};

    for (i = 0; i < videos.length; i+= 1) {
        if (videos[i]) {
            var video = new Video(videos[i].videoId, videos[i].title, videos[i].type, videos[i].rating, self.setAsPlaying);
            self.videos.push(video);
        }
    }
}
<|endoftext|>


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

'use strict';

let fs = require('fs');

let NUM_REQUEST = 1000;
let NUM_COORDS = 2;
let url_template = "http://127.0.0.1:5000/route/v1/driving/{coords}?steps=false&alternatives=false";
let coord_template = "{lon},{lat}";
let coords_separator = ";";

let monaco_poly_path = process.argv[2];
let poly_data = fs.readFileSync(monaco_poly_path, 'utf-8');

// lets assume there is only one ring
// cut of name and ring number and the two END statements
let coordinates = poly_data.split('\n')
  .filter((l) => l != '')
  .slice(2, -2).map((coord_line) => coord_line.split(' ')
  .filter((elem) => elem != ''))
  .map((coord) => [parseFloat(coord[0]), parseFloat(coord[1])]);

var sw = [Number.MAX_VALUE, Number.MAX_VALUE];
var ne = [Number.MIN_VALUE, Number.MIN_VALUE];

coordinates.forEach((c) => {
  sw[0] = Math.min(sw[0], c[0]);
  sw[1] = Math.min(sw[1], c[1]);
  ne[0] = Math.max(ne[0], c[0]);
  ne[1] = Math.max(ne[1], c[1]);
});

// Yes this an own seeded random number generator because its only a few lines
var seed = 0x1337;
function seededRandom(min, max) {
  seed = (seed * 9301 + 49297) % 233280;
  var rnd = seed / 233280;
  return min + rnd * (max - min);
}

function getRandomCoordinate() {
  let lon = seededRandom(sw[0], ne[0]);
  let lat = seededRandom(sw[1], ne[1]);
  return [lon, lat];
}

for (var i = 0; i < NUM_REQUEST; ++i)
{
  var coords = [];
  for (var j = 0; j < NUM_COORDS; ++j)
  {
    coords.push(getRandomCoordinate());
  }
  let coords_string = coords.map((c) => coord_template.replace("{lon}", c[0]).replace("{lat}", c[1])).join(coords_separator);
  console.log(url_template.replace("{coords}", coords_string));
}

<commit_msg>Make the poly2req script work with 4.9 and 5.0 and add modes<commit_after>#!/usr/bin/env node

'use strict';

let fs = require('fs');

let VERSION = "route_5.0";
let SAMPLE_SIZE = 20;
let NUM_REQUEST = 1000;
let NUM_COORDS = 2;
let PORT = 5000;
let url_templates = {
  "route_5.0": "http://127.0.0.1:{port}/route/v1/driving/{coords}?steps=false&alternatives=false",
  "route_4.9": "http://127.0.0.1:{port}/viaroute?{coords}&instructions=false&alt=false",
  "table_5.0": "http://127.0.0.1:{port}/table/v1/driving/{coords}",
  "table_4.9": "http://127.0.0.1:{port}/table?{coords}"
};

let coord_templates =  {
  "route_5.0": "{lon},{lat}",
  "route_4.9": "loc={lat},{lon}",
  "table_5.0": "{lon},{lat}",
  "table_4.9": "loc={lat},{lon}"
};

let coords_separators = {
  "route_5.0": ";",
  "route_4.9": "&",
  "table_5.0": ";",
  "table_4.9": "&"
};
var axis = "distance";

var sw = [Number.MAX_VALUE, Number.MAX_VALUE];
var ne = [Number.MIN_VALUE, Number.MIN_VALUE];

if (process.argv.length > 2 && process.argv[2] == "planet")
{
  sw = [-180., -85.];
  ne = [180., 85.];
}
if (process.argv.length > 2 && process.argv[2] == "us")
{
  sw = [-127., 24.];
  ne = [-67., 48.];
}
else if (process.argv.length > 2 && process.argv[2] == "dc")
{
  sw = [-77.138, 38.808];
  ne = [-76.909, 38.974];
}
else if (process.argv.length > 2)
{
  let monaco_poly_path = process.argv[2];
  let poly_data = fs.readFileSync(monaco_poly_path, 'utf-8');

  // lets assume there is only one ring
  // cut of name and ring number and the two END statements
  let coordinates = poly_data.split('\n')
    .filter((l) => l != '')
    .slice(2, -2).map((coord_line) => coord_line.split(' ')
    .filter((elem) => elem != ''))
    .map((coord) => [parseFloat(coord[0]), parseFloat(coord[1])]);

  coordinates.forEach((c) => {
    sw[0] = Math.min(sw[0], c[0]);
    sw[1] = Math.min(sw[1], c[1]);
    ne[0] = Math.max(ne[0], c[0]);
    ne[1] = Math.max(ne[1], c[1]);
  });
}

if (process.argv.length > 3)
{
  axis = process.argv[3];
}

console.error(sw);
console.error(ne);

// Yes this an own seeded random number generator because its only a few lines
var seed = 0x1337;
function seededRandom(min, max) {
  seed = (seed * 9301 + 49297) % 233280;
  var rnd = seed / 233280;
  return min + rnd * (max - min);
}

function getRandomCoordinate() {
  let lon = seededRandom(sw[0], ne[0]);
  let lat = seededRandom(sw[1], ne[1]);
  return [lon, lat];
}

function makeQuery(coords) {
  let coords_string = coords.map((c) => coord_templates[VERSION].replace("{lon}", c[0]).replace("{lat}", c[1])).join(coords_separators[VERSION]);
  return url_templates[VERSION].replace("{coords}", coords_string).replace("{port}", PORT);
}

if (axis == "distance")
{
  for (var i = 0; i < NUM_REQUEST; ++i)
  {
    var coords = [];
    for (var j = 0; j < NUM_COORDS; ++j)
    {
      coords.push(getRandomCoordinate());
    }
    console.log(makeQuery(coords));
  }
}
else if (axis == "waypoints")
{
  for (var power = 0; power <= 1; ++power)
  {
    for (var factor = 1; factor <= 10; ++factor)
    {
      let num_coords = factor*Math.pow(10, power);
      console.error(num_coords);
      for (var i = 0; i < SAMPLE_SIZE; ++i)
      {
        var coords = [];
        for (var j = 0; j < num_coords; ++j)
        {
          coords.push(getRandomCoordinate());
        }
        console.log(makeQuery(coords));
      }
    }
  }
}

<|endoftext|>


<commit_before>function sayHello() {
	document.write('Hello Again, World');
}
<commit_msg>[86] updating the greeting...<commit_after>function sayHello() {
	document.write('I just called to say hello.');
}
<|endoftext|>


<commit_before>'use strict';

const Future = require('..');

function printStatus(fn) {;
  switch(%GetOptimizationStatus(fn)) {
    case 1: console.log('Function is optimized'); break;
    case 2: console.log('Function is not optimized'); break;
    case 3: console.log('Function is always optimized'); break;
    case 4: console.log('Function is never optimized'); break;
    case 6: console.log('Function is maybe deoptimized'); break;
    case 7: console.log('Function is optimized by TurboFan'); break;
    default: console.log('Unknown optimization status'); break;
  }
}

const noop = () => {};
const m = Future.of(1);

console.log('--- map chain ap fork ---');

Future.of(1)
.map(x => x + 1)
.chain(x => Future.of(f => f(x + 1)))
.ap(Future.of(x => x + 1))
.fork(noop, noop);

%OptimizeFunctionOnNextCall(Future.of);
%OptimizeFunctionOnNextCall(m.map);
%OptimizeFunctionOnNextCall(m.chain);
%OptimizeFunctionOnNextCall(m.ap);
%OptimizeFunctionOnNextCall(m.fork);

printStatus(Future.of);
printStatus(m.map);
printStatus(m.chain);
printStatus(m.ap);
printStatus(m.fork);

Future.of(1)
.map(x => x + 1)
.chain(x => Future.of(f => f(x + 1)))
.ap(Future.of(x => x + 1))
.fork(noop, noop);

printStatus(Future.of);
printStatus(m.map);
printStatus(m.chain);
printStatus(m.ap);
printStatus(m.fork);

console.log('--- cache fork ---');

Future.cache(Future.of(1)).fork(noop, noop);

%OptimizeFunctionOnNextCall(Future.cache);
%OptimizeFunctionOnNextCall(Future.prototype.fork);

printStatus(Future.cache);
printStatus(Future.prototype.fork);

Future.cache(Future.of(1)).fork(noop, noop);

printStatus(Future.cache);
printStatus(Future.prototype.fork);

console.log('--- parallel fork ---');

Future.parallel(2, [Future.of(1), Future.of(2)]).fork(noop, noop);

%OptimizeFunctionOnNextCall(Future.parallel);
%OptimizeFunctionOnNextCall(Future.prototype.fork);

printStatus(Future.parallel);
printStatus(Future.prototype.fork);

Future.parallel(2, [Future.of(1), Future.of(2)]).fork(noop, noop);

printStatus(Future.parallel);
printStatus(Future.prototype.fork);
<commit_msg>Remove stray semicolon<commit_after>'use strict';

const Future = require('..');

function printStatus(fn) {
  switch(%GetOptimizationStatus(fn)) {
    case 1: console.log('Function is optimized'); break;
    case 2: console.log('Function is not optimized'); break;
    case 3: console.log('Function is always optimized'); break;
    case 4: console.log('Function is never optimized'); break;
    case 6: console.log('Function is maybe deoptimized'); break;
    case 7: console.log('Function is optimized by TurboFan'); break;
    default: console.log('Unknown optimization status'); break;
  }
}

const noop = () => {};
const m = Future.of(1);

console.log('--- map chain ap fork ---');

Future.of(1)
.map(x => x + 1)
.chain(x => Future.of(f => f(x + 1)))
.ap(Future.of(x => x + 1))
.fork(noop, noop);

%OptimizeFunctionOnNextCall(Future.of);
%OptimizeFunctionOnNextCall(m.map);
%OptimizeFunctionOnNextCall(m.chain);
%OptimizeFunctionOnNextCall(m.ap);
%OptimizeFunctionOnNextCall(m.fork);

printStatus(Future.of);
printStatus(m.map);
printStatus(m.chain);
printStatus(m.ap);
printStatus(m.fork);

Future.of(1)
.map(x => x + 1)
.chain(x => Future.of(f => f(x + 1)))
.ap(Future.of(x => x + 1))
.fork(noop, noop);

printStatus(Future.of);
printStatus(m.map);
printStatus(m.chain);
printStatus(m.ap);
printStatus(m.fork);

console.log('--- cache fork ---');

Future.cache(Future.of(1)).fork(noop, noop);

%OptimizeFunctionOnNextCall(Future.cache);
%OptimizeFunctionOnNextCall(Future.prototype.fork);

printStatus(Future.cache);
printStatus(Future.prototype.fork);

Future.cache(Future.of(1)).fork(noop, noop);

printStatus(Future.cache);
printStatus(Future.prototype.fork);

console.log('--- parallel fork ---');

Future.parallel(2, [Future.of(1), Future.of(2)]).fork(noop, noop);

%OptimizeFunctionOnNextCall(Future.parallel);
%OptimizeFunctionOnNextCall(Future.prototype.fork);

printStatus(Future.parallel);
printStatus(Future.prototype.fork);

Future.parallel(2, [Future.of(1), Future.of(2)]).fork(noop, noop);

printStatus(Future.parallel);
printStatus(Future.prototype.fork);
<|endoftext|>