<commit_before>/**
 * Software License Agreement (BSD License)
 *
 * Copyright (c) 2010 IBM Corporation.
 * All rights reserved.
 *
 * Redistribution and use of this software in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above
 *   copyright notice, this list of conditions and the
 *   following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above
 *   copyright notice, this list of conditions and the
 *   following disclaimer in the documentation and/or other
 *   materials provided with the distribution.
 *
 * * Neither the name of IBM nor the names of its
 *   contributors may be used to endorse or promote products
 *   derived from this software without specific prior
 *   written permission of IBM.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * Describes a debuggable web browser. A browser may be remote and contain one or more
 * JavaScript execution contexts. Each JavaScript execution context may contain one or
 * more compilation units. A browser provides notification to registered listeners describing
 * events that occur in the browser.
 *
 * @constructor
 * @type Browser
 * @return a new Browser
 * @version 1.0
 */
function Browser() {
	this.contexts = []; // array of contexts
	this.handlers = []; // map of event types to array of handler functions
	this.EVENT_TYPES = ["onBreak", "onConsoleDebug", "onConsoleError", "onConsoleInfo", "onConsoleLog",
	                    "onConsoleWarn", "onContextCreated", "onContextDestroyed", "onInspectNode",
	                    "onResume", "onSuspend", "onToggleBreakpoint"];
}

// ---- API ----

/**
 * Returns all JavaScript execution contexts currently known to this {@link Browser}.
 *

 * This function does not require communication with the remote browser.
 *

 * @function
 * @returns an array of {@link JavaScriptContext}
 */
Browser.prototype.getJavaScriptContexts = function() {
	// return a copy of contexts so the master copy is not corrupted
	var knownContexts = [];
	for (var id in this.contexts) {
		knownContexts.push(this.contexts[id]);
	}
	return knownContexts;
};

/**
 * Registers a listener (function) for a specific type of event.
 *

 * The supported event types and associated listener function signatures summarized in the
 * following table.
 *

 *

 *

 *

 *   Event Type
 *   Listener Function
 *   Description
 *

 *

 *   onBreak
 *   function({@link CompilationUnit}, lineNumber)
 *   specified execution context has suspended execution
 *

 *

 *   onConsoleDebug
 *   TODO
 *   TODO
 *

 *

 *   onConsoleError
 *   TODO
 *   TODO
 *

 *

 *   onConsoleInfo
 *   function({@link JavaScriptContext}, messages[])
 *   specified information messages have been written by the specified JavaScript execution context
 *

 *

 *   onConsoleLog
 *   function({@link JavaScriptContext}, messages[])
 *   specified log messages have been written by the specified JavaScript execution context
 *

 *

 *   onConsoleWarn
 *   function({@link JavaScriptContext}, messages[])
 *   specified warning messages have been written by the specified JavaScript execution context
 *

 *

 *   onContextCreated
 *   function({@link JavaScriptContext})
 *   specified execution context has been created
 *

 *

 *   onContextDestroyed
 *   function({@link JavaScriptContext})
 *   specified execution context no longer exists
 *

 *

 *   onInspectNode
 *   TODO
 *   TODO
 *

 *

 *   onResume
 *   function({@link JavaScriptContext})
 *   specified execution context has resumed execution
 *

 *

 *   onScript
 *   function({@link CompilationUnit})
 *   specified compilation unit has been compiled (loaded)
 *

 *

 *   onToggleBreakpoint
 *   function({@link JavaScriptContext}, {@link Breakpoint})
 *   TODO
 *

 *

 *

 *

 *

 *
TODO: notification the browser has been destroyed?

 *
TODO: how can clients remove (deregister) listeners?

 *

 *

 * @function
 * @param eventType an event type ({@link String}) listed in the above table
 * @param listener a listener (function) that handles the event
 */
Browser.prototype.on = function(eventType, listener) {
	for ( var i = 0; i < this.EVENT_TYPES.length; i++) {
		if (eventType == this.EVENT_TYPES[i]) {
			var list = this.handlers[eventType];
			if (!list) {
				list = [];
				this.handlers[eventType] = list;
			}
			// TODO: do we need to validate function argument length?
			list.push(listener);
			return;
		}
	}
};

/**
 * Disconnects this client from the browser it is associated with.
 *
 * @function
 */
Browser.prototype.disconnect = function() {

}

//TODO: support to remove a listener

// ---- PRIVATE ----

/**
 * Notification the given context has been added to this browser.
 * Adds the context to the list of active contexts and notifies context
 * listeners.
 *
 * @function
 * @param context the {@link JavaScriptContext} that has been added
 */
Browser.prototype._contextCreated = function(context) {
	// if already present, don't add it again
	var id = context.getId();
	if (this.contexts[id]) {
		return;
	}
	this.contexts[id] = context;
	this._dispatch("onContextCreated", [context]);
};

/**
 * Notification the given context has been destroyed.
 * Removes the context from the list of active contexts and notifies context
 * listeners.
 *
 * @function
 * @param id the identifier of the {@link JavaScriptContext} that has been destroyed
 */
Browser.prototype._contextDestroyed = function(id) {
	var destroyed = this.contexts[id];
	if (destroyed) {
		this.contexts[id] = null;
		this._dispatch("onContextDestroyed", [destroyed]);
	}
};

/**
 * Dispatches an event notification to all registered functions for
 * the specified event type.
 *
 * @param eventType event type
 * @param arguments arguments to be applied to handler functions
 */
Browser.prototype._dispatch = function(eventType, arguments) {
	functions = this.handlers[eventType];
	if (functions) {
		for ( var i = 0; i < functions.length; i++) {
			functions[i].apply(null, arguments);
		}
	}
};

<commit_msg>fix to context destroyed<commit_after>/**
 * Software License Agreement (BSD License)
 *
 * Copyright (c) 2010 IBM Corporation.
 * All rights reserved.
 *
 * Redistribution and use of this software in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above
 *   copyright notice, this list of conditions and the
 *   following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above
 *   copyright notice, this list of conditions and the
 *   following disclaimer in the documentation and/or other
 *   materials provided with the distribution.
 *
 * * Neither the name of IBM nor the names of its
 *   contributors may be used to endorse or promote products
 *   derived from this software without specific prior
 *   written permission of IBM.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * Describes a debuggable web browser. A browser may be remote and contain one or more
 * JavaScript execution contexts. Each JavaScript execution context may contain one or
 * more compilation units. A browser provides notification to registered listeners describing
 * events that occur in the browser.
 *
 * @constructor
 * @type Browser
 * @return a new Browser
 * @version 1.0
 */
function Browser() {
	this.contexts = []; // array of contexts
	this.handlers = []; // map of event types to array of handler functions
	this.EVENT_TYPES = ["onBreak", "onConsoleDebug", "onConsoleError", "onConsoleInfo", "onConsoleLog",
	                    "onConsoleWarn", "onContextCreated", "onContextDestroyed", "onInspectNode",
	                    "onResume", "onSuspend", "onToggleBreakpoint"];
}

// ---- API ----

/**
 * Returns all JavaScript execution contexts currently known to this {@link Browser}.
 *

 * This function does not require communication with the remote browser.
 *

 * @function
 * @returns an array of {@link JavaScriptContext}
 */
Browser.prototype.getJavaScriptContexts = function() {
	// return a copy of contexts so the master copy is not corrupted
	var knownContexts = [];
	for (var id in this.contexts) {
		knownContexts.push(this.contexts[id]);
	}
	return knownContexts;
};

/**
 * Registers a listener (function) for a specific type of event.
 *

 * The supported event types and associated listener function signatures summarized in the
 * following table.
 *

 *

 *

 *

 *   Event Type
 *   Listener Function
 *   Description
 *

 *

 *   onBreak
 *   function({@link CompilationUnit}, lineNumber)
 *   specified execution context has suspended execution
 *

 *

 *   onConsoleDebug
 *   TODO
 *   TODO
 *

 *

 *   onConsoleError
 *   TODO
 *   TODO
 *

 *

 *   onConsoleInfo
 *   function({@link JavaScriptContext}, messages[])
 *   specified information messages have been written by the specified JavaScript execution context
 *

 *

 *   onConsoleLog
 *   function({@link JavaScriptContext}, messages[])
 *   specified log messages have been written by the specified JavaScript execution context
 *

 *

 *   onConsoleWarn
 *   function({@link JavaScriptContext}, messages[])
 *   specified warning messages have been written by the specified JavaScript execution context
 *

 *

 *   onContextCreated
 *   function({@link JavaScriptContext})
 *   specified execution context has been created
 *

 *

 *   onContextDestroyed
 *   function({@link JavaScriptContext})
 *   specified execution context no longer exists
 *

 *

 *   onInspectNode
 *   TODO
 *   TODO
 *

 *

 *   onResume
 *   function({@link JavaScriptContext})
 *   specified execution context has resumed execution
 *

 *

 *   onScript
 *   function({@link CompilationUnit})
 *   specified compilation unit has been compiled (loaded)
 *

 *

 *   onToggleBreakpoint
 *   function({@link JavaScriptContext}, {@link Breakpoint})
 *   TODO
 *

 *

 *

 *

 *

 *
TODO: notification the browser has been destroyed?

 *
TODO: how can clients remove (deregister) listeners?

 *

 *

 * @function
 * @param eventType an event type ({@link String}) listed in the above table
 * @param listener a listener (function) that handles the event
 */
Browser.prototype.on = function(eventType, listener) {
	for ( var i = 0; i < this.EVENT_TYPES.length; i++) {
		if (eventType == this.EVENT_TYPES[i]) {
			var list = this.handlers[eventType];
			if (!list) {
				list = [];
				this.handlers[eventType] = list;
			}
			// TODO: do we need to validate function argument length?
			list.push(listener);
			return;
		}
	}
};

/**
 * Disconnects this client from the browser it is associated with.
 *
 * @function
 */
Browser.prototype.disconnect = function() {

}

//TODO: support to remove a listener

// ---- PRIVATE ----

/**
 * Notification the given context has been added to this browser.
 * Adds the context to the list of active contexts and notifies context
 * listeners.
 *
 * @function
 * @param context the {@link JavaScriptContext} that has been added
 */
Browser.prototype._contextCreated = function(context) {
	// if already present, don't add it again
	var id = context.getId();
	if (this.contexts[id]) {
		return;
	}
	this.contexts[id] = context;
	this._dispatch("onContextCreated", [context]);
};

/**
 * Notification the given context has been destroyed.
 * Removes the context from the list of active contexts and notifies context
 * listeners.
 *
 * @function
 * @param id the identifier of the {@link JavaScriptContext} that has been destroyed
 */
Browser.prototype._contextDestroyed = function(id) {
	var destroyed = this.contexts[id];
	if (destroyed) {
		delete this.contexts[id];
		this._dispatch("onContextDestroyed", [destroyed]);
	}
};

/**
 * Dispatches an event notification to all registered functions for
 * the specified event type.
 *
 * @param eventType event type
 * @param arguments arguments to be applied to handler functions
 */
Browser.prototype._dispatch = function(eventType, arguments) {
	functions = this.handlers[eventType];
	if (functions) {
		for ( var i = 0; i < functions.length; i++) {
			functions[i].apply(null, arguments);
		}
	}
};

<|endoftext|>


<commit_before>/**
 * Made - a markdown slide application
 * js of slide show
 * Copyright (c) 2016-2020, liang wei. (MIT Licensed)
 * https://github.com/pipiliang/made
 */

// write and made slide here

$(document).ready(() => {
	document.addEventListener('keydown', handleGlobalBodyKeyDown, false)
})

// //low algorithm need be optimize，performance problems
// var onInput = (event) => {
// 	onWrite(event.target.value, false)
// }

var onWrite = (content, isNew) => {
	if (isNew) {
		pageNumber = 0
	}
	//console.log(content)
	var allslides = $("#showContainer").children();
	var slideCount = allslides.length;

	var allrows = content.split("\n");
	var rows = allrows.length;
	var slideArray = getSlideArray(allrows);
	var needSlideCount = slideArray.length + 1;

	if (needSlideCount < slideCount) { //remove
		EventPool.getInstance().fire({ type: Event.SLIDE_COUNT_CHANGED , count : needSlideCount})
		for (var i = 0; i < slideCount - needSlideCount; i++) {
			$("#showContainer").children(":last").remove();
		}

	}

	if (needSlideCount > slideCount) { //add
		EventPool.getInstance().fire({ type: Event.SLIDE_COUNT_CHANGED , count : needSlideCount})
		for (var i = 0; i < needSlideCount - slideCount; i++) {
			var add = document.createElement('div');
			add.setAttribute('class', 'item');
			$("#showContainer").children(":last").after(add.outerHTML);
		}
	}

	var allslides = $("#showContainer").children();
	var from = 0;
	for (var i = 0; i < needSlideCount; i++) {
		var to = (i == needSlideCount - 1) ? rows : slideArray[i];
		var curcontext = allrows.slice(from, to).join("\n");
		console.log(marked(curcontext))
		allslides[i].innerHTML = '

' + marked(curcontext) + '

';
		from = slideArray[i] + 1;
	}

	//需要再研究，这样应该会影响效率
	$("#showContainer table").attr("class","table");
	$("#showContainer pre").attr("class","hljs");
}

function getSlideArray(o) {
	var splitarray = new Array();
	for (var i = 0; i < o.length; i++) {
		if (o[i].like('---')) {
			splitarray.push(i);
		}
	}
	return splitarray;
}

// show and control slide here

var isShow = false;
var pageNumber = 0;

function showSlide() {
	if (!isShow) {
		show(true);
		$("#page").show()
	}
	var children = $("#showContainer").children();
	console.log(pageNumber + " - " + children.length)
	if (pageNumber >= children.length) {
		pageNumber = children.length - 1
	}
	$('#showHere').animate({ 'opacity': 0 }, 200, function () {
		$(this).html(children[pageNumber].innerHTML).animate({ 'opacity': 1 }, 400);
		$(this).css('transform', 'scale(' + 1.2 + ')')
	});
	$("#page").html((pageNumber + 1) + " / " + (lastSlideIndex() + 1));
}

function hideSlide() {
	if (isShow) {
		show(false);
		$("#page").hide();
	}
}

function show(state) {
	if (isElectron) {
		var electron = require('electron');
		electron.remote.getCurrentWindow().setFullScreen(state);
		electron.remote.getCurrentWindow().setMenuBarVisibility(!state);
	}
	state ? $("#showcase").show() : $("#showcase").hide()
	state ? document.addEventListener('keydown', handleBodyKeyDown, false) : document.removeEventListener('keydown', handleBodyKeyDown, false);
	isShow = state;
}

var handleBodyKeyDown = (event) => {
	console.log(event.keyCode);
	switch (event.keyCode) {
		case 27: //esc
			hideSlide();
			break;
		case 37: //left
		case 38: //up
			if (pageNumber > 0) {
				pageNumber--;
				showSlide();
			}
			break;
		case 39: //right
		case 40: //down
		case 13: //enter
			if (pageNumber < lastSlideIndex()) {
				pageNumber++;
				showSlide();
			}
			break;
		case 80: //P Page
			$("#page").toggle()
			break;
		case 84: //T thumbnail
			break;
	}
	event.returnValue = false;
}

var handleGlobalBodyKeyDown = (event) => {
	switch (event.keyCode) {
		case 118: //F7
			isShow ? hideSlide() : showSlide()
			event.returnValue = false;
			break;
		case 27:  //esc
			if (isElectron) {
				require('electron').remote.getCurrentWindow().setFullScreen(false)
			}
			break;
	}
}

var lastSlideIndex = function () {
	return $("#showContainer").children().length - 1
}

if (isElectron) {
    var router = MessageRouter.create()
    router.on('view', (event, message) => {
        if (message === 'showslide') {
			isShow ? hideSlide() : showSlide()
		}
    })
}
<commit_msg>[fixbug] rollback<commit_after>/**
 * Made - a markdown slide application
 * js of slide show
 * Copyright (c) 2016-2020, liang wei. (MIT Licensed)
 * https://github.com/pipiliang/made
 */

// write and made slide here

$(document).ready(() => {
	document.addEventListener('keydown', handleGlobalBodyKeyDown, false)
})

// //low algorithm need be optimize，performance problems
// var onInput = (event) => {
// 	onWrite(event.target.value, false)
// }

var onWrite = (content, isNew) => {
	if (isNew) {
		pageNumber = 0
	}
	//console.log(content)
	var allslides = $("#showContainer").children();
	var slideCount = allslides.length;

	var allrows = content.split("\n");
	var rows = allrows.length;
	var slideArray = getSlideArray(allrows);
	var needSlideCount = slideArray.length + 1;

	if (needSlideCount < slideCount) { //remove
		EventPool.getInstance().fire({ type: Event.SLIDE_COUNT_CHANGED , count : needSlideCount})
		for (var i = 0; i < slideCount - needSlideCount; i++) {
			$("#showContainer").children(":last").remove();
		}

	}

	if (needSlideCount > slideCount) { //add
		EventPool.getInstance().fire({ type: Event.SLIDE_COUNT_CHANGED , count : needSlideCount})
		for (var i = 0; i < needSlideCount - slideCount; i++) {
			var add = document.createElement('div');
			add.setAttribute('class', 'item');
			$("#showContainer").children(":last").after(add.outerHTML);
		}
	}

	var allslides = $("#showContainer").children();
	var from = 0;
	for (var i = 0; i < needSlideCount; i++) {
		var to = (i == needSlideCount - 1) ? rows : slideArray[i];
		var curcontext = allrows.slice(from, to).join("\n");
		console.log(marked(curcontext))
		allslides[i].innerHTML = marked(curcontext);
		from = slideArray[i] + 1;
	}

	//需要再研究，这样应该会影响效率
	$("#showContainer table").attr("class","table");
	$("#showContainer pre").attr("class","hljs");
}

function getSlideArray(o) {
	var splitarray = new Array();
	for (var i = 0; i < o.length; i++) {
		if (o[i].like('---')) {
			splitarray.push(i);
		}
	}
	return splitarray;
}

// show and control slide here

var isShow = false;
var pageNumber = 0;

function showSlide() {
	if (!isShow) {
		show(true);
		$("#page").show()
	}
	var children = $("#showContainer").children();
	console.log(pageNumber + " - " + children.length)
	if (pageNumber >= children.length) {
		pageNumber = children.length - 1
	}
	$('#showHere').animate({ 'opacity': 0 }, 200, function () {
		$(this).html(children[pageNumber].innerHTML).animate({ 'opacity': 1 }, 400);
		$(this).css('transform', 'scale(' + 1.2 + ')')
	});
	$("#page").html((pageNumber + 1) + " / " + (lastSlideIndex() + 1));
}

function hideSlide() {
	if (isShow) {
		show(false);
		$("#page").hide();
	}
}

function show(state) {
	if (isElectron) {
		var electron = require('electron');
		electron.remote.getCurrentWindow().setFullScreen(state);
		electron.remote.getCurrentWindow().setMenuBarVisibility(!state);
	}
	state ? $("#showcase").show() : $("#showcase").hide()
	state ? document.addEventListener('keydown', handleBodyKeyDown, false) : document.removeEventListener('keydown', handleBodyKeyDown, false);
	isShow = state;
}

var handleBodyKeyDown = (event) => {
	console.log(event.keyCode);
	switch (event.keyCode) {
		case 27: //esc
			hideSlide();
			break;
		case 37: //left
		case 38: //up
			if (pageNumber > 0) {
				pageNumber--;
				showSlide();
			}
			break;
		case 39: //right
		case 40: //down
		case 13: //enter
			if (pageNumber < lastSlideIndex()) {
				pageNumber++;
				showSlide();
			}
			break;
		case 80: //P Page
			$("#page").toggle()
			break;
		case 84: //T thumbnail
			break;
	}
	event.returnValue = false;
}

var handleGlobalBodyKeyDown = (event) => {
	switch (event.keyCode) {
		case 118: //F7
			isShow ? hideSlide() : showSlide()
			event.returnValue = false;
			break;
		case 27:  //esc
			if (isElectron) {
				require('electron').remote.getCurrentWindow().setFullScreen(false)
			}
			break;
	}
}

var lastSlideIndex = function () {
	return $("#showContainer").children().length - 1
}

if (isElectron) {
    var router = MessageRouter.create()
    router.on('view', (event, message) => {
        if (message === 'showslide') {
			isShow ? hideSlide() : showSlide()
		}
    })
}
<|endoftext|>


<commit_before>import UiStore from './UiStore'
import { createServer } from 'reactotron-core-server'
import { action, observable, computed, reaction, observe } from 'mobx'
import {
  contains,
  last,
  isNil,
  reject,
  equals,
  reverse,
  pipe,
  propEq,
  map,
  fromPairs,
  test,
  any,
  path
} from 'ramda'
import { dotPath } from 'ramdasauce'
import shallowDiff from '../Lib/ShallowDiff'

const isSubscription = propEq('type', 'state.values.change')
const isSubscriptionCommandWithEmptyChanges = command =>
  isSubscription(command) && dotPath('payload.changes.length', command) === 0

/**
 * Functions to check a command when searching.
 */
const COMMON_MATCHING_PATHS = [
  path(['type']),
  path(['payload', 'message']),
  path(['payload', 'preview']),
  path(['payload', 'name']),
  path(['payload', 'path']),
  path(['payload', 'triggerType']),
  path(['payload', 'description']),
  path(['payload', 'request', 'url']),
  path(['payload', 'request', 'url'])
]

class Session {
  // commands to exlude in the timeline
  @observable commandsHiddenInTimeline = []

  // holds the last known state of the subscription values
  subscriptions = {}

  // checks if it was the exact same as last time
  isSubscriptionValuesSameAsLastTime (command) {
    if (!isSubscription(command)) return false
    const rawChanges = command.payload ? command.payload.changes : []
    const newSubscriptions = fromPairs(map(change => [change.path, change.value], rawChanges))
    const isNew = !equals(this.subscriptions, newSubscriptions)

    // 🚨🚨🚨 side effect alert 🚨🚨🚨
    if (isNew) {
      const diff = shallowDiff(this.subscriptions, newSubscriptions)
      command.payload.changed = map(v => v.rightValue, diff.difference || [])
      command.payload.added = diff.onlyOnRight || []
      command.payload.removed = diff.onlyOnLeft || []
      this.subscriptions = newSubscriptions
    }
    // 🚨🚨🚨 side effect alert 🚨🚨🚨

    return !isNew
  }

  /**
   * Should we reject this command when we are searching?
   *
   * This will be based on the search term that user has typed in.
   */
  rejectCommandWhenSearching = command => {
    // only reject when we're searching
    if (!this.ui.isTimelineSearchVisible || !this.ui.isValidSearchPhrase) {
      return false
    }

    // safely matching the search term regexp against something passed in
    const matching = value =>
      value && typeof value === 'string' && test(this.ui.searchRegexp, value)

    // typical paths that might match
    if (any(x => matching(x(command)), COMMON_MATCHING_PATHS)) {
      return false
    }

    // A few commands have their UI represented differently than their data. This is probably
    // not the best place for this, however, it'll be fine for now.
    if (command.type === 'log' && (matching('debug') || matching('warning') || matching('error'))) {
      return false
    } else if (command.type === 'client.intro' && matching('connection')) {
      return false
    }

    // ignore everything else
    return true
  }

  @computed
  get commands () {
    return pipe(
      dotPath('server.commands.all'),
      reject(isSubscriptionCommandWithEmptyChanges),
      reject(this.isSubscriptionValuesSameAsLastTime),
      reject(command => contains(command.type, this.commandsHiddenInTimeline)),
      reject(this.rejectCommandWhenSearching),
      reverse
    )(this)
  }

  @computed
  get watches () {
    const changeCommands = this.server.commands['state.values.change']
    if (isNil(changeCommands)) return []
    if (changeCommands.length === 0) return []
    const recentCommand = last(changeCommands)
    return dotPath('payload.changes', recentCommand) || []
  }

  @computed
  get backups () {
    return this.server.commands['state.backup.response']
  }

  // are commands of this type hidden?
  isCommandHidden (commandType) {
    return contains(commandType, this.commandsHiddenInTimeline)
  }

  // toggles whether a command type is to be ignored or not
  @action
  toggleCommandVisibility (commandType) {
    const hidden = this.isCommandHidden(commandType)
    if (hidden) {
      this.commandsHiddenInTimeline.remove(commandType)
    } else {
      this.commandsHiddenInTimeline.push(commandType)
    }
    return !hidden
  }

  constructor (port = 9090) {
    this.server = createServer({ port })
    this.server.start()
    this.isSubscriptionValuesSameAsLastTime = this.isSubscriptionValuesSameAsLastTime.bind(this)

    // create the ui store
    this.ui = new UiStore(this.server)

    // hide or show the watch panel depending if we have watches
    reaction(
      () => this.watches.length > 0,
      show => {
        this.ui.showWatchPanel = show
      }
    )

    // when a new backup arrives, open the editor to rename it
    observe(this.backups, change => {
      if (change.type === 'splice' && change.added.length === 1) {
        this.ui.openRenameStateDialog(change.added[0])
      }
    })
  }
}

export default Session
<commit_msg>Persist timeline filter settings<commit_after>import UiStore from './UiStore'
import { createServer } from 'reactotron-core-server'
import { action, observable, computed, reaction, observe } from 'mobx'
import {
  contains,
  last,
  isNil,
  reject,
  equals,
  reverse,
  pipe,
  propEq,
  map,
  fromPairs,
  test,
  any,
  path
} from 'ramda'
import { dotPath } from 'ramdasauce'
import shallowDiff from '../Lib/ShallowDiff'

const isSubscription = propEq('type', 'state.values.change')
const isSubscriptionCommandWithEmptyChanges = command =>
  isSubscription(command) && dotPath('payload.changes.length', command) === 0

/**
 * Functions to check a command when searching.
 */
const COMMON_MATCHING_PATHS = [
  path(['type']),
  path(['payload', 'message']),
  path(['payload', 'preview']),
  path(['payload', 'name']),
  path(['payload', 'path']),
  path(['payload', 'triggerType']),
  path(['payload', 'description']),
  path(['payload', 'request', 'url']),
  path(['payload', 'request', 'url'])
]

class Session {
  // commands to exlude in the timeline
  @observable commandsHiddenInTimeline = JSON.parse(localStorage.getItem('commandsHiddenInTimeline')) || []

  // holds the last known state of the subscription values
  subscriptions = {}

  // checks if it was the exact same as last time
  isSubscriptionValuesSameAsLastTime (command) {
    if (!isSubscription(command)) return false
    const rawChanges = command.payload ? command.payload.changes : []
    const newSubscriptions = fromPairs(map(change => [change.path, change.value], rawChanges))
    const isNew = !equals(this.subscriptions, newSubscriptions)

    // 🚨🚨🚨 side effect alert 🚨🚨🚨
    if (isNew) {
      const diff = shallowDiff(this.subscriptions, newSubscriptions)
      command.payload.changed = map(v => v.rightValue, diff.difference || [])
      command.payload.added = diff.onlyOnRight || []
      command.payload.removed = diff.onlyOnLeft || []
      this.subscriptions = newSubscriptions
    }
    // 🚨🚨🚨 side effect alert 🚨🚨🚨

    return !isNew
  }

  /**
   * Should we reject this command when we are searching?
   *
   * This will be based on the search term that user has typed in.
   */
  rejectCommandWhenSearching = command => {
    // only reject when we're searching
    if (!this.ui.isTimelineSearchVisible || !this.ui.isValidSearchPhrase) {
      return false
    }

    // safely matching the search term regexp against something passed in
    const matching = value =>
      value && typeof value === 'string' && test(this.ui.searchRegexp, value)

    // typical paths that might match
    if (any(x => matching(x(command)), COMMON_MATCHING_PATHS)) {
      return false
    }

    // A few commands have their UI represented differently than their data. This is probably
    // not the best place for this, however, it'll be fine for now.
    if (command.type === 'log' && (matching('debug') || matching('warning') || matching('error'))) {
      return false
    } else if (command.type === 'client.intro' && matching('connection')) {
      return false
    }

    // ignore everything else
    return true
  }

  @computed
  get commands () {
    return pipe(
      dotPath('server.commands.all'),
      reject(isSubscriptionCommandWithEmptyChanges),
      reject(this.isSubscriptionValuesSameAsLastTime),
      reject(command => contains(command.type, this.commandsHiddenInTimeline)),
      reject(this.rejectCommandWhenSearching),
      reverse
    )(this)
  }

  @computed
  get watches () {
    const changeCommands = this.server.commands['state.values.change']
    if (isNil(changeCommands)) return []
    if (changeCommands.length === 0) return []
    const recentCommand = last(changeCommands)
    return dotPath('payload.changes', recentCommand) || []
  }

  @computed
  get backups () {
    return this.server.commands['state.backup.response']
  }

  // are commands of this type hidden?
  isCommandHidden (commandType) {
    return contains(commandType, this.commandsHiddenInTimeline)
  }

  // toggles whether a command type is to be ignored or not
  @action
  toggleCommandVisibility (commandType) {
    const hidden = this.isCommandHidden(commandType)
    if (hidden) {
      this.commandsHiddenInTimeline.remove(commandType)
    } else {
      this.commandsHiddenInTimeline.push(commandType)
    }
    localStorage.setItem('commandsHiddenInTimeline', JSON.stringify(this.commandsHiddenInTimeline))
    return !hidden
  }

  constructor (port = 9090) {
    this.server = createServer({ port })
    this.server.start()
    this.isSubscriptionValuesSameAsLastTime = this.isSubscriptionValuesSameAsLastTime.bind(this)

    // create the ui store
    this.ui = new UiStore(this.server)

    // hide or show the watch panel depending if we have watches
    reaction(
      () => this.watches.length > 0,
      show => {
        this.ui.showWatchPanel = show
      }
    )

    // when a new backup arrives, open the editor to rename it
    observe(this.backups, change => {
      if (change.type === 'splice' && change.added.length === 1) {
        this.ui.openRenameStateDialog(change.added[0])
      }
    })
  }
}

export default Session
<|endoftext|>


<commit_before>import React from 'react';
var PieChart = require('react-chartjs').Pie;

export default React.createClass({
  getInitialState: function () {
    var stats = this.props.user || [];

    var buildCount = Math.floor(stats.total_building_count_add);
    var waterCount = Math.floor(stats.total_waterway_count_add);
    var poiCount = Math.floor(stats.total_poi_count_add);
    var roadKm = Number(stats.total_road_km_add).toFixed(2);
    var waterKm = Number(stats.total_waterway_km_add).toFixed(2);

    var noDist = false;
    var noCount = false;
    if (buildCount === 0 &&
      waterCount === 0 && poiCount === 0) {
      noCount = true;
      noDist = true;
    }
    if (roadKm === 0 && waterKm === 0) noDist = true;

    var chartDataCount = [];
    var tooltipTemplate = '<%if (label){%><%=label%>: <%}%><%= value %>';
    if (noCount === true) {
      chartDataCount = [{
        value: 1,
        color: '#d6d6d6',
        highlight: '#d6d6d6',
        label: 'No Edits'
      }];
      tooltipTemplate = 'No Edits';
    } else {
      chartDataCount = [
        {
          value: waterCount,
          color: '#a8dde1',
          highlight: '#8abcc0',
          label: 'Waterways'
        },
        {
          value: buildCount,
          color: '#fbd1b3',
          highlight: '#dcb296',
          label: 'Buildings'
        },
        {
          value: poiCount,
          color: '#d3e7b9',
          highlight: '#b5c89b',
          label: 'POIs'
        }
      ];
    }
    var chartDataDist = [
      {
        value: roadKm,
        color: '#faf3b6',
        highlight: '#dcd599',
        label: 'Roads'
      },
      {
        value: waterKm,
        color: '#a8dde1',
        highlight: '8abcc0',
        label: 'Waterways'
      },
      {
        value: 0,
        color: '#fbd1b3',
        highlight: '#dcb296',
        label: 'Buildings'
      },
      {
        value: 0,
        color: '#d3e7b9',
        highlight: '#b5c89b',
        label: 'POIs'
      }
    ];
    return {
      chartOptions: {
        animationSteps: 50,
        animationEasing: 'easeOutQuart',
        tooltipTemplate: tooltipTemplate
      },
      chartData: chartDataCount,
      chartDataCount: chartDataCount,
      chartDataDist: chartDataDist,
      noCount: noCount,
      noDist: noDist
    };
  },
  loadDist: function () {
    this.setState({
      chartData: this.state.chartDataDist
    });
  },
  loadCounts: function () {
    this.setState({
      chartData: this.state.chartDataCount
    });
  },

  render: function () {
    return

        <PieChart data={this.state.chartData} options={this.state.chartOptions} width='200px' height='200px' />

    {/*

        <input type="button" onClick={this.loadCounts} value="By Quantity"
         className = {this.state.noCount ? 'disabled' : ''}/>
        <input type="button" onClick={this.loadDist} value="By Distance"
         className = {this.state.noDist ? 'disabled' : ''} />

 */}

;
  }
});
<commit_msg>Adds road count to pie chart<commit_after>import React from 'react';
var PieChart = require('react-chartjs').Pie;

export default React.createClass({
  getInitialState: function () {
    var stats = this.props.user || [];

    var roadCount = Math.floor(stats.total_road_count_add);
    var buildCount = Math.floor(stats.total_building_count_add);
    var waterCount = Math.floor(stats.total_waterway_count_add);
    var poiCount = Math.floor(stats.total_poi_count_add);

    var noCount = false;
    if (roadCount === 0 && buildCount === 0 &&
      waterCount === 0 && poiCount === 0) noCount = true;

    var chartDataCount = [];
    var tooltipTemplate = '<%if (label){%><%=label%>: <%}%><%= value %>';
    if (noCount === true) {
      chartDataCount = [{
        value: 1,
        color: '#d6d6d6',
        highlight: '#d6d6d6',
        label: 'No Edits'
      }];
      tooltipTemplate = 'No Edits';
    } else {
      chartDataCount = [
        {
          value: roadCount,
          color: '#faf3b6',
          highlight: '#dcd599',
          label: 'Roads'
        },
        {
          value: waterCount,
          color: '#a8dde1',
          highlight: '#8abcc0',
          label: 'Waterways'
        },
        {
          value: buildCount,
          color: '#fbd1b3',
          highlight: '#dcb296',
          label: 'Buildings'
        },
        {
          value: poiCount,
          color: '#d3e7b9',
          highlight: '#b5c89b',
          label: 'POIs'
        }
      ];
    }
    return {
      chartOptions: {
        animationSteps: 50,
        animationEasing: 'easeOutQuart',
        tooltipTemplate: tooltipTemplate
      },
      chartData: chartDataCount,
      chartDataCount: chartDataCount,
      noCount: noCount
    };
  },
  render: function () {
    return

        <PieChart data={this.state.chartData} options={this.state.chartOptions} width='200px' height='200px' />

;
  }
});
<|endoftext|>


<commit_before>import {
  name as LIB_NAME,
  version as LIB_VERSION
} from '../../package.json';

const {
  toString
} = Object.prototype;

function _isBasicObject(val) {
  return typeof val === 'object' &&
    val !== null &&
    val.__proto__ === undefined;
}

function _argsStr(count, name = 'arg') {
  let names = [];

  for (let i = 0; i < count; i++) {
    names.push(`${name}${i + 1}`);
  }

  return names.join(', ');
}

function typeStr(val, k = undefined) {
  let t = (_isBasicObject(val)) ?
    'BasicObject' :
    toString.call(val).match(/^\[object ([^\]]*)\]$/)[1];

  if (t === 'Object') {
    if (val.constructor && (
      (val.constructor.name && val.constructor.name !== t)
    )) {
      t = val.constructor.name;
    }
  }

  if (val instanceof Error) {
    // name might be a getter that throws
    try {
      let name = val.name;

      if (name && name !== t) {
        t = name;
      }
    } catch (err) {}
  }

  if (val instanceof Function) {
    if (val.name && val.name !== t && (
      val.name.match(/^[A-Z]/) ||
      (k &&
        ['__apivis__chain_link',
          'constructor',
          'prototype',
          '__proto__'
        ].includes(k)
      )
    )) {
      t = val.name;
    }

    t = `${t}(${_argsStr(val.length)})`;
  }

  if (val && (
    (val.hasOwnProperty && val.hasOwnProperty('constructor'))
  )) {
    if (!t.endsWith('Prototype') && (
      (t !== 'Object' || val === Object.prototype)
    )) {
      t = `${t}.prototype`;
    }
  }

  return t;
}

function valueStr(val) {
  switch (typeof val) {
  case 'boolean':
  case 'number':
    return `${val}`;
  case 'string':
    return JSON.stringify(val);
  case 'object':
    if (Array.isArray(val) && val !== Array.prototype) {
      return `${val.length}`;
    } else if (val instanceof Date) {
      return JSON.stringify(val);
    } else if (val instanceof Error) {
      // message might be a getter that throws
      try {
        let msg = val.message;

        if (msg) {
          return JSON.stringify(msg);
        }
      } catch (err) {
        return '';
      }
    }
  default:
    return '';
  }
}

function descStr(val, k) {
  if (val === undefined || val === null) {
    return 'n/a';
  }

  let desc = Object.getOwnPropertyDescriptor(val, k);
  let d1 = '';
  let d2 = '';

  if (desc === undefined) {
    return 'n/a';
  }

  if (desc.hasOwnProperty('value')) { d1 += 'v'; }
  if (desc.writable) { d1 += 'w'; }
  if (desc.get) { d1 += 'g'; }
  if (desc.set) { d1 += 's'; }
  if (desc.enumerable) { d2 += 'e'; }
  if (desc.configurable) { d2 += 'c'; }

  return (d2) ? `${d1} ${d2}` : d1;
}

function memberStr(val, k, leaf = val) {
  let sk = String(k);
  let sd = descStr(val, k);
  let isGetter = sd.includes('g');
  // Do not attempt to resolve these
  let skip = [
    'arguments',
    'callee',
    'caller'
  ];
  // Only resolve these in the context of leaf
  let leafOnly = [
    '__proto__'
  ];
  let st;
  let v;
  let sv = '';

  // First resolve k in the context of leaf (like it would be normally)
  try {
    if (!skip.includes(k)) {
      v = _swallowPromiseRejection(leaf[k]);
    }
  } catch (err) {
    v = (isGetter) ? _getterTagDummy : err;
  }

  // Then try resolving k in the context of val (reached through
  // following __proto__) to eventually get a shadowed value (some
  // props only make sense when resolved in the context of leaf
  // and an exception will be thrown upon trying to access them through val)
  try {
    if ( !(val === leaf || leafOnly.includes(k) || skip.includes(k)) ) {
      let shadowed = _swallowPromiseRejection(val[k]);

      if (shadowed !== undefined && shadowed !== null) {
        v = shadowed;
      }
    }
  } catch (err) {
    // Leave v as set by trying to resolve k in the context of leaf
  }

  st = typeStr(v, k);
  sv = valueStr(v);

  return `${sk}{${sd}}: ${st}${(sv) ? `:${sv}` : ''}`;
}

const _compare = (a, b) => {
  let sa = String(a);
  let sb = String(b);
  let na;
  let nb;

  if (Number.isNaN(na = Number(sa)) || Number.isNaN(nb = Number(sb))) {
    return (sa < sb) ? -1 : (sa > sb) ? 1 : 0;
  }

  return na - nb;
};

const _keys = (val, kind) =>
  (val === undefined || val === null) ?
    [] :
    Object[`getOwnProperty${kind}`](val).sort(_compare);

const _symbols = val => _keys(val, 'Symbols');
const _names = val => _keys(val, 'Names');

const members = val => _symbols(val).concat(_names(val));

const _swallowPromiseRejection = v => (
  (typeof v === 'object' && v !== null &&
    typeof v.catch === 'function' &&
      v.catch(err => {})),
  v
);

const _getterTagDummy = {
  __proto__: {
    get [Symbol.toStringTag]() { return 'Getter'; }
  }
};

function membersStr(val, indent = '  ', level = 0, leaf = val) {
  return members(val).
    map(k => `${indent.repeat(level)}${memberStr(val, k, leaf)}`).
    join('\n');
}

function inspectStr(val, indent = '  ') {
  let st = typeStr(val);
  let sv = valueStr(val);

  return `${st}${(sv) ? `:${sv}` : ''}`;
}

function chain(val) {
  let links = [val];

  for (let link = Object.getPrototypeOf(val);
    link;
    link = Object.getPrototypeOf(link)
  ) {
    links.push(link);
  }

  return links;
}

function chainStr(val, indent = '  ') {
  return chain(val).
    reverse().
    map((v, i) => `${indent.repeat(i)}[${typeStr(v, '__apivis__chain_link')}]`).
    join('\n');
}

function apiStr(val, indent = '  ') {
  return chain(val).
    reverse().
    map((v, i) => `${indent.repeat(i)}[${typeStr(v, '__apivis__chain_link')}]\n${membersStr(v, indent, i + 1, val)}`).
    join('\n');
}

// peek42 plugin
function peek42(fnOutput, fnComment) {
  return {
    type(val, comment = undefined, opts = undefined) {
      fnOutput(
        typeStr(val),
        fnComment(comment, val, 'type'),
        opts
      );
    },
    desc(val, k, comment = undefined, opts = undefined) {
      fnOutput(
        descStr(val, k),
        fnComment(comment, `${String(k)} in ${typeStr(val)}`, 'desc'),
        opts
      );
    },
    members(val, comment = undefined, opts = undefined) {
      fnOutput(
        membersStr(val,
          (opts && typeof opts.indent === 'string') ?
            opts.indent :
            undefined,
          (opts && typeof opts.indentLevel === 'number') ?
            opts.indentLevel :
            undefined
        ),
        fnComment(comment, typeStr(val), 'members'),
        opts
      );
    },
    inspect(val, comment = undefined, opts = undefined) {
      fnOutput(
        inspectStr(val,
          (opts && typeof opts.indent === 'string') ?
            opts.indent :
            undefined
        ),
        fnComment(comment, typeStr(val), 'inspect'),
        opts
      );
    },
    chain(val, comment = undefined, opts = undefined) {
      fnOutput(
        chainStr(val,
          (opts && typeof opts.indent === 'string') ?
            opts.indent :
            undefined
        ),
        fnComment(comment, typeStr(val), 'chain'),
        opts
      );
    },
    api(val, comment = undefined, opts = undefined) {
      fnOutput(
        apiStr(val,
          (opts && typeof opts.indent === 'string') ?
            opts.indent :
            undefined
        ),
        fnComment(comment, typeStr(val), 'api'),
        opts
      );
    }
  };
}

const apivis = {
  get [Symbol.toStringTag]() {
    return LIB_NAME;
  },
  version: LIB_VERSION,
  typeStr,
  descStr,
  memberStr,
  members,
  membersStr,
  inspectStr,
  chain,
  chainStr,
  apiStr,
  peek42
};

export {
  typeStr,
  descStr,
  memberStr,
  members,
  membersStr,
  inspectStr,
  chain,
  chainStr,
  apiStr
};
export default apivis;
<commit_msg>Add plugin method<commit_after>import {
  name as LIB_NAME,
  version as LIB_VERSION
} from '../../package.json';

const {
  toString
} = Object.prototype;

function _isBasicObject(val) {
  return typeof val === 'object' &&
    val !== null &&
    val.__proto__ === undefined;
}

function _argsStr(count, name = 'arg') {
  let names = [];

  for (let i = 0; i < count; i++) {
    names.push(`${name}${i + 1}`);
  }

  return names.join(', ');
}

function typeStr(val, k = undefined) {
  let t = (_isBasicObject(val)) ?
    'BasicObject' :
    toString.call(val).match(/^\[object ([^\]]*)\]$/)[1];

  if (t === 'Object') {
    if (val.constructor && (
      (val.constructor.name && val.constructor.name !== t)
    )) {
      t = val.constructor.name;
    }
  }

  if (val instanceof Error) {
    // name might be a getter that throws
    try {
      let name = val.name;

      if (name && name !== t) {
        t = name;
      }
    } catch (err) {}
  }

  if (val instanceof Function) {
    if (val.name && val.name !== t && (
      val.name.match(/^[A-Z]/) ||
      (k &&
        ['__apivis__chain_link',
          'constructor',
          'prototype',
          '__proto__'
        ].includes(k)
      )
    )) {
      t = val.name;
    }

    t = `${t}(${_argsStr(val.length)})`;
  }

  if (val && (
    (val.hasOwnProperty && val.hasOwnProperty('constructor'))
  )) {
    if (!t.endsWith('Prototype') && (
      (t !== 'Object' || val === Object.prototype)
    )) {
      t = `${t}.prototype`;
    }
  }

  return t;
}

function valueStr(val) {
  switch (typeof val) {
  case 'boolean':
  case 'number':
    return `${val}`;
  case 'string':
    return JSON.stringify(val);
  case 'object':
    if (Array.isArray(val) && val !== Array.prototype) {
      return `${val.length}`;
    } else if (val instanceof Date) {
      return JSON.stringify(val);
    } else if (val instanceof Error) {
      // message might be a getter that throws
      try {
        let msg = val.message;

        if (msg) {
          return JSON.stringify(msg);
        }
      } catch (err) {
        return '';
      }
    }
  default:
    return '';
  }
}

function descStr(val, k) {
  if (val === undefined || val === null) {
    return 'n/a';
  }

  let desc = Object.getOwnPropertyDescriptor(val, k);
  let d1 = '';
  let d2 = '';

  if (desc === undefined) {
    return 'n/a';
  }

  if (desc.hasOwnProperty('value')) { d1 += 'v'; }
  if (desc.writable) { d1 += 'w'; }
  if (desc.get) { d1 += 'g'; }
  if (desc.set) { d1 += 's'; }
  if (desc.enumerable) { d2 += 'e'; }
  if (desc.configurable) { d2 += 'c'; }

  return (d2) ? `${d1} ${d2}` : d1;
}

function memberStr(val, k, leaf = val) {
  let sk = String(k);
  let sd = descStr(val, k);
  let isGetter = sd.includes('g');
  // Do not attempt to resolve these
  let skip = [
    'arguments',
    'callee',
    'caller'
  ];
  // Only resolve these in the context of leaf
  let leafOnly = [
    '__proto__'
  ];
  let st;
  let v;
  let sv = '';

  // First resolve k in the context of leaf (like it would be normally)
  try {
    if (!skip.includes(k)) {
      v = _swallowPromiseRejection(leaf[k]);
    }
  } catch (err) {
    v = (isGetter) ? _getterTagDummy : err;
  }

  // Then try resolving k in the context of val (reached through
  // following __proto__) to eventually get a shadowed value (some
  // props only make sense when resolved in the context of leaf
  // and an exception will be thrown upon trying to access them through val)
  try {
    if ( !(val === leaf || leafOnly.includes(k) || skip.includes(k)) ) {
      let shadowed = _swallowPromiseRejection(val[k]);

      if (shadowed !== undefined && shadowed !== null) {
        v = shadowed;
      }
    }
  } catch (err) {
    // Leave v as set by trying to resolve k in the context of leaf
  }

  st = typeStr(v, k);
  sv = valueStr(v);

  return `${sk}{${sd}}: ${st}${(sv) ? `:${sv}` : ''}`;
}

const _compare = (a, b) => {
  let sa = String(a);
  let sb = String(b);
  let na;
  let nb;

  if (Number.isNaN(na = Number(sa)) || Number.isNaN(nb = Number(sb))) {
    return (sa < sb) ? -1 : (sa > sb) ? 1 : 0;
  }

  return na - nb;
};

const _keys = (val, kind) =>
  (val === undefined || val === null) ?
    [] :
    Object[`getOwnProperty${kind}`](val).sort(_compare);

const _symbols = val => _keys(val, 'Symbols');
const _names = val => _keys(val, 'Names');

const members = val => _symbols(val).concat(_names(val));

const _swallowPromiseRejection = v => (
  (typeof v === 'object' && v !== null &&
    typeof v.catch === 'function' &&
      v.catch(err => {})),
  v
);

const _getterTagDummy = {
  __proto__: {
    get [Symbol.toStringTag]() { return 'Getter'; }
  }
};

function membersStr(val, indent = '  ', level = 0, leaf = val) {
  return members(val).
    map(k => `${indent.repeat(level)}${memberStr(val, k, leaf)}`).
    join('\n');
}

function inspectStr(val, indent = '  ') {
  let st = typeStr(val);
  let sv = valueStr(val);

  return `${st}${(sv) ? `:${sv}` : ''}`;
}

function chain(val) {
  let links = [val];

  for (let link = Object.getPrototypeOf(val);
    link;
    link = Object.getPrototypeOf(link)
  ) {
    links.push(link);
  }

  return links;
}

function chainStr(val, indent = '  ') {
  return chain(val).
    reverse().
    map((v, i) => `${indent.repeat(i)}[${typeStr(v, '__apivis__chain_link')}]`).
    join('\n');
}

function apiStr(val, indent = '  ') {
  return chain(val).
    reverse().
    map((v, i) => `${indent.repeat(i)}[${typeStr(v, '__apivis__chain_link')}]\n${membersStr(v, indent, i + 1, val)}`).
    join('\n');
}

// peek42 plugin
function peek42(fnOutput, fnComment) {
  return {
    type(val, comment = undefined, opts = undefined) {
      fnOutput(
        typeStr(val),
        fnComment(comment, val, 'type'),
        opts
      );
    },
    desc(val, k, comment = undefined, opts = undefined) {
      fnOutput(
        descStr(val, k),
        fnComment(comment, `${String(k)} in ${typeStr(val)}`, 'desc'),
        opts
      );
    },
    member(val, k, comment = undefined, opts = undefined) {
      fnOutput(
        memberStr(val, k),
        fnComment(comment, `${String(k)} in ${typeStr(val)}`, 'member'),
        opts
      );
    },
    members(val, comment = undefined, opts = undefined) {
      fnOutput(
        membersStr(val,
          (opts && typeof opts.indent === 'string') ?
            opts.indent :
            undefined,
          (opts && typeof opts.indentLevel === 'number') ?
            opts.indentLevel :
            undefined
        ),
        fnComment(comment, typeStr(val), 'members'),
        opts
      );
    },
    inspect(val, comment = undefined, opts = undefined) {
      fnOutput(
        inspectStr(val,
          (opts && typeof opts.indent === 'string') ?
            opts.indent :
            undefined
        ),
        fnComment(comment, typeStr(val), 'inspect'),
        opts
      );
    },
    chain(val, comment = undefined, opts = undefined) {
      fnOutput(
        chainStr(val,
          (opts && typeof opts.indent === 'string') ?
            opts.indent :
            undefined
        ),
        fnComment(comment, typeStr(val), 'chain'),
        opts
      );
    },
    api(val, comment = undefined, opts = undefined) {
      fnOutput(
        apiStr(val,
          (opts && typeof opts.indent === 'string') ?
            opts.indent :
            undefined
        ),
        fnComment(comment, typeStr(val), 'api'),
        opts
      );
    }
  };
}

const apivis = {
  get [Symbol.toStringTag]() {
    return LIB_NAME;
  },
  version: LIB_VERSION,
  typeStr,
  descStr,
  memberStr,
  members,
  membersStr,
  inspectStr,
  chain,
  chainStr,
  apiStr,
  peek42
};

export {
  typeStr,
  descStr,
  memberStr,
  members,
  membersStr,
  inspectStr,
  chain,
  chainStr,
  apiStr
};
export default apivis;
<|endoftext|>


<commit_before>import Ember from 'ember';
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
const { computed, observer } = Ember;
import { belongsTo } from 'ember-data/relationships';
import Constants from 'tsygan/constants';
const { types } = Constants;

// This defines what a schema field is, using solely tsygan transforms
// Ideally, this could be exoressed as a schema itself
export default Model.extend({
  // Name of the field - should be any string
  name:             attr('tsygan@string'),
  // Type of the field (see typeOptions below for choises)
  type:             attr('tsygan@enum', {'enum-set': Object.keys(types)}),
  // Whether the field is an array of things
  array:            attr('tsygan@boolean', {defaultValue: false}),
  // In case the field type is a string, what language is that (see transforms)
  language:         attr('tsygan@spacedog-language', {defaultValue: 'English'}),
  // If type is an enum, determines the list of allowed values
  enumSet:          attr('tsygan@string', {array: true}),
  // If type is hasMany or belongsTo, this link to the model name it relates to
  relatedTo:        attr('tsygan@string'),
  // Any type may provide a list of examples to display to the user (up to the implementor to use them or not,
  // typically as placeholders in inputs).
  examples:         attr('tsygan@string', {array: true}),
  // Whether the field should be required - if it is, a defaultValue can be specified
  // For array-ed, the require applies for the entire array, not individual elements
  required:         attr('tsygan@boolean', {defaultValue: false}),
  // Default value, in case the field is required
  // For arrays, the default is for the entire array, not for individual elements - complex objects used as
  // defaultValues are shallow copied, so careful with modifying them
  // A default value would usually override the first "example" as a placeholder in inputs
  defaultValue:     attr('tsygan@string'),

  // Numerical types may have restrictions (<, <=, >, >= and step)
  // Step is usable only with gte, and will coerce values to match `gte + n * step`
  // This apply to individual elements in an array
  step:             attr('tsygan@number'),
  gte:              attr('tsygan@number'),
  gt:               attr('tsygan@number'),
  lte:              attr('tsygan@number'),
  lt:               attr('tsygan@number'),

  // Any type may have a regexp validation pattern (does NOT support modifiers)
  // This apply to individual elements in an array
  // XXX future: could be an array to allow more fine grain validation
  // XXX implement lengths checks (can be interpolated from / to pattern?)
  pattern:          attr('tsygan@regexp'),

  // Links back to the parent model this field belongs to
  parentModel:      belongsTo('tsygan@spacedog-schema'),

  // This returns the type choices that are available, depending on whether the object is sealed (field has already
  // been saved to SpaceDog, or not)
  // If the former, then only subtypes changes are allowed
  // If the latter, then all types are available
  typeOptions: computed('_spacetypehard', function(){
    // If it sealed, restrict to that
    var sth = this.get('_spacetypehard');
    // Either the object is un-sealed (all types), or it is (restricted to same spacedog type)
    return Object.keys(types).filter(function(key){
      return !sth || types[key] === sth;
    });
  }),

  // XXX all these are somewhat ugly hacks
  // This method MUST be called after a first save, and will mark the field as "locked" on SpaceDog
  seal: function(){
    if (!this.get('_spacetypehard'))
      this.set('_spacetypehard', this.get('_spacetypesoft'));
  },

  sealed: computed('_spacetypehard', function(){
    return !!this.get('_spacetypehard');
  }),

  // The hard type will be there if the object was saved on the service already, to keep track of the actual
  // SpaceDog type.
  // This is to accomodate for the types that we don't know how to preserve (long vs. int, float vs. double)
  _spacetypehard:        attr('string'),
  // The soft type if the SpaceDog type we will infer if we are saving for the first time
  _spacetypesoft:      attr('string'),

  // Observes the type to adjust what we will send to SpaceDog (on first save)
  typeObserver: observer('type', function(){
    this.set('_spacetypesoft', types[this.get('type')]);
  }),

  init: function(){
    /* eslint no-dangle-underscore:0 */
    this._super(...arguments);
    this.set('_spacetypesoft', types[this.get('type')]);
  },

  // Helpers for component template
  hasRelation:      computed('type', function () {
    const currentType = this.get('type');
    return currentType === 'hasMany' || currentType === 'belongsTo';
  }),

  hasArray:         computed('type', function(){
    const currentType = this.get('type');
    return ['json', 'belongsTo', 'hasMany'].indexOf(currentType) === -1;
  }),

  hasLanguage:         computed('type', function(){
    return this.get('type') === 'string';
  }),

  hasPattern:         computed('type', function(){
    return ['string', 'identifier', 'password'].indexOf(this.get('type')) !== -1;
  }),

  hasBoundaries:         computed('type', function(){
    return ['integer', 'number'].indexOf(this.get('type')) !== -1;
  }),

  hasEnum:         computed('type', function(){
    const currentType = this.get('type');
    return currentType === 'enum';
  }),

  fieldEnumSet: computed('enumSet', {
    get(/*key*/) {
      return (this.get('enumSet') || []).join(',');
    },
    set(key, value) {
      if (this.get('_oldEnumSetValue') && value === this.get('_oldEnumSetValue'))
        return value;
      this.set('enumSet', (value || '').split(','));
      return this.set('_oldEnumSetValue', value);
    }
  }),

  fieldExamples: computed('examples', {
    get(/*key*/) {
      return (this.get('examples') || []).join(',');
    },
    set(key, value) {
      if (this.get('_oldExamplesValue') && value === this.get('_oldExamplesValue'))
        return value;
      this.set('examples', (value || '').split(','));
      return this.set('_oldExamplesValue', value);
    }
  })

});
<commit_msg>Add a “system” property<commit_after>import Ember from 'ember';
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
const { computed, observer } = Ember;
import { belongsTo } from 'ember-data/relationships';
import Constants from 'tsygan/constants';
const { types } = Constants;

// This defines what a schema field is, using solely tsygan transforms
// Ideally, this could be exoressed as a schema itself
export default Model.extend({
  // Name of the field - should be any string
  name:             attr('tsygan@string'),
  // Type of the field (see typeOptions below for choises)
  type:             attr('tsygan@enum', {'enum-set': Object.keys(types)}),
  // Whether the field is an array of things
  array:            attr('tsygan@boolean', {defaultValue: false}),
  // In case the field type is a string, what language is that (see transforms)
  language:         attr('tsygan@spacedog-language', {defaultValue: 'English'}),
  // If type is an enum, determines the list of allowed values
  enumSet:          attr('tsygan@string', {array: true}),
  // If type is hasMany or belongsTo, this link to the model name it relates to
  relatedTo:        attr('tsygan@string'),
  // Any type may provide a list of examples to display to the user (up to the implementor to use them or not,
  // typically as placeholders in inputs).
  examples:         attr('tsygan@string', {array: true}),
  // Whether the field should be required - if it is, a defaultValue can be specified
  // For array-ed, the require applies for the entire array, not individual elements
  required:         attr('tsygan@boolean', {defaultValue: false}),
  // Default value, in case the field is required
  // For arrays, the default is for the entire array, not for individual elements - complex objects used as
  // defaultValues are shallow copied, so careful with modifying them
  // A default value would usually override the first "example" as a placeholder in inputs
  defaultValue:     attr('tsygan@string'),
  // Denote that a property is a read-only, system property (eg: think "reset code")
  // XXX no UI for that right now
  system:         attr('tsygan@boolean'),

  // Numerical types may have restrictions (<, <=, >, >= and step)
  // Step is usable only with gte, and will coerce values to match `gte + n * step`
  // This apply to individual elements in an array
  step:             attr('tsygan@number'),
  gte:              attr('tsygan@number'),
  gt:               attr('tsygan@number'),
  lte:              attr('tsygan@number'),
  lt:               attr('tsygan@number'),

  // Any type may have a regexp validation pattern (does NOT support modifiers)
  // This apply to individual elements in an array
  // XXX future: could be an array to allow more fine grain validation
  // XXX implement lengths checks (can be interpolated from / to pattern?)
  pattern:          attr('tsygan@regexp'),

  // Links back to the parent model this field belongs to
  parentModel:      belongsTo('tsygan@spacedog-schema'),

  // This returns the type choices that are available, depending on whether the object is sealed (field has already
  // been saved to SpaceDog, or not)
  // If the former, then only subtypes changes are allowed
  // If the latter, then all types are available
  typeOptions: computed('_spacetypehard', function(){
    // If it sealed, restrict to that
    var sth = this.get('_spacetypehard');
    // Either the object is un-sealed (all types), or it is (restricted to same spacedog type)
    return Object.keys(types).filter(function(key){
      return !sth || types[key] === sth;
    });
  }),

  // XXX all these are somewhat ugly hacks
  // This method MUST be called after a first save, and will mark the field as "locked" on SpaceDog
  seal: function(){
    if (!this.get('_spacetypehard'))
      this.set('_spacetypehard', this.get('_spacetypesoft'));
  },

  sealed: computed('_spacetypehard', function(){
    return !!this.get('_spacetypehard');
  }),

  // The hard type will be there if the object was saved on the service already, to keep track of the actual
  // SpaceDog type.
  // This is to accomodate for the types that we don't know how to preserve (long vs. int, float vs. double)
  _spacetypehard:        attr('string'),
  // The soft type if the SpaceDog type we will infer if we are saving for the first time
  _spacetypesoft:      attr('string'),

  // Observes the type to adjust what we will send to SpaceDog (on first save)
  typeObserver: observer('type', function(){
    this.set('_spacetypesoft', types[this.get('type')]);
  }),

  init: function(){
    /* eslint no-dangle-underscore:0 */
    this._super(...arguments);
    this.set('_spacetypesoft', types[this.get('type')]);
  },

  // Helpers for component template
  hasRelation:      computed('type', function () {
    const currentType = this.get('type');
    return currentType === 'hasMany' || currentType === 'belongsTo';
  }),

  hasArray:         computed('type', function(){
    const currentType = this.get('type');
    return ['json', 'belongsTo', 'hasMany'].indexOf(currentType) === -1;
  }),

  hasLanguage:         computed('type', function(){
    return this.get('type') === 'string';
  }),

  hasPattern:         computed('type', function(){
    return ['string', 'identifier', 'password'].indexOf(this.get('type')) !== -1;
  }),

  hasBoundaries:         computed('type', function(){
    return ['integer', 'number'].indexOf(this.get('type')) !== -1;
  }),

  hasEnum:         computed('type', function(){
    const currentType = this.get('type');
    return currentType === 'enum';
  }),

  fieldEnumSet: computed('enumSet', {
    get(/*key*/) {
      return (this.get('enumSet') || []).join(',');
    },
    set(key, value) {
      if (this.get('_oldEnumSetValue') && value === this.get('_oldEnumSetValue'))
        return value;
      this.set('enumSet', (value || '').split(','));
      return this.set('_oldEnumSetValue', value);
    }
  }),

  fieldPattern: computed('pattern', {
    get(/*key*/) {
      return this.get('pattern') ? this.get('pattern').source : '';
    },
    set(key, value) {
      if (this.get('_oldEnumSetValue') && value === this.get('_oldEnumSetValue'))
        return value;
      this.set('pattern', value ? new RegExp(value) : '');
      return this.set('_oldEnumSetValue', value);
    }
  }),

  fieldExamples: computed('examples', {
    get(/*key*/) {
      return (this.get('examples') || []).join(',');
    },
    set(key, value) {
      if (this.get('_oldExamplesValue') && value === this.get('_oldExamplesValue'))
        return value;
      this.set('examples', (value || '').split(','));
      return this.set('_oldExamplesValue', value);
    }
  })

});
<|endoftext|>


<commit_before>/**
 * Fade between sections (
 and preamble are wrapped in a section) with keyboard up/down.
 */
    $('#content h1:first-child, #content #preamble').wrapAll("");
    var sections = $('.sect1');
    sections.hide();
    var current = 0;
    $(sections[current]).show();
    var sectionsLength = sections.length;
    $(document).keydown(function (e) {
      if (e.keyCode === 38) {
        // up
        if (current > 0) {
          e.preventDefault();
          current -= 1;
          $(sections[current+1]).fadeOut(300, function() {
            $(sections[current]).fadeIn(300);
          });
        }
      }
      else if (e.keyCode === 40) {
        // down
        if (current < sectionsLength - 1) {
          e.preventDefault();
          current += 1;
          $(sections[current-1]).fadeOut(300, function() {
            $(sections[current]).fadeIn(300);
          });
        }
      }
    });<commit_msg>only when doc's ready<commit_after>/**
 * Fade between sections (
 and preamble are wrapped in a section) with keyboard up/down.
 */
$(document).ready(
  function() {
    $('#content h1:first-child, #content #preamble').wrapAll("");
    var sections = $('.sect1');
    sections.hide();
    var current = 0;
    $(sections[current]).show();
    var sectionsLength = sections.length;
    $(document).keydown(function (e) {
      if (e.keyCode === 38) {
        // up
        if (current > 0) {
          e.preventDefault();
          current -= 1;
          $(sections[current+1]).fadeOut(300, function() {
            $(sections[current]).fadeIn(300);
          });
        }
      }
      else if (e.keyCode === 40) {
        // down
        if (current < sectionsLength - 1) {
          e.preventDefault();
          current += 1;
          $(sections[current-1]).fadeOut(300, function() {
            $(sections[current]).fadeIn(300);
          });
        }
      }
    });
  }
);<|endoftext|>


<commit_before>/*
==================================================================================================
  Core - JavaScript Foundation
  Copyright 2010-2012 Sebastian Werner
==================================================================================================
*/

/**
 * Detects browser language settings
 */
core.Module("core.detect.Locale",
{
	/**
	 * {=String} Locale string as configured by the user e.g. `de_AT`, `es_ES` or short like `de`
	 */
	VALUE : (function()
	{
		var nav = navigator;
		var input = (nav.userLanguage || nav.language).toLowerCase();
		var split = input.indexOf("-");

		return split > 0 ? input.substring(0, split) : input;
	})()
});
<commit_msg>Imporved support for non browsers<commit_after>/*
==================================================================================================
  Core - JavaScript Foundation
  Copyright 2010-2012 Sebastian Werner
==================================================================================================
*/

/**
 * Detects browser language settings
 */
core.Module("core.detect.Locale",
{
	/**
	 * {=String} Locale string as configured by the user e.g. `de_AT`, `es_ES` or short like `de`
	 */
	VALUE : (function(global)
	{
		var nav = global.navigator || {};
		var input = (nav.userLanguage || nav.language || "en").toLowerCase();
		var split = input.indexOf("-");

		return split > 0 ? input.substring(0, split) : input;
	})(this)
});
<|endoftext|>


<commit_before>
define([
  'jquery',
  'underscore',
  'backbone',
  'helpers/conf',
  'text!templates/basic_nav.html',
  'text!templates/conf.html'
], function($, _, Backbone, ConfHelper, BasicNavTemplate, ConfTemplate){

  var ConfView = Backbone.View.extend ({
    el: '#main',

    initialize: function () {

      // unbind previous events
      // FIXME: need better solution for this
      $(this.el).unbind ('scroll');
      $(this.el).unbind ('click');

      // clear page content
      $(this.el).html ('');

    },

    render: function () {

      $('#right-navbar').html (_.template (BasicNavTemplate,
                                           { title: 'Ayarlar' }));
      $(this.el).append (_.template (ConfTemplate));

    },

    events: {
      'click ul.theme a': 'changeTheme'
    },

    changeTheme: function (ev) {
      var theme = $(ev.currentTarget).attr ('href').replace (/^#/, '');

      ConfHelper.options.theme = theme;
      ConfHelper.switchTheme ();
      ConfHelper.saveConf ();

      return false;
    },

  });

  return ConfView;

});
<commit_msg>use options in ConfTemplate<commit_after>
define([
  'jquery',
  'underscore',
  'backbone',
  'helpers/conf',
  'text!templates/basic_nav.html',
  'text!templates/conf.html'
], function($, _, Backbone, ConfHelper, BasicNavTemplate, ConfTemplate){

  var ConfView = Backbone.View.extend ({
    el: '#main',

    initialize: function () {

      // unbind previous events
      // FIXME: need better solution for this
      $(this.el).unbind ('scroll');
      $(this.el).unbind ('click');

      // clear page content
      $(this.el).html ('');

    },

    render: function () {

      $('#right-navbar').html (_.template (BasicNavTemplate,
                                           { title: 'Ayarlar' }));
      $(this.el).append (_.template (ConfTemplate,
                                     { options: ConfHelper.options }));

    },

    events: {
      'click ul.theme a': 'changeTheme'
    },

    changeTheme: function (ev) {
      var theme = $(ev.currentTarget).attr ('href').replace (/^#/, '');

      ConfHelper.options.theme = theme;
      ConfHelper.switchTheme ();
      ConfHelper.saveConf ();

      return false;
    },

  });

  return ConfView;

});
<|endoftext|>


<commit_before>const log = require('../../app/lib/logger');
const Postcode = require('postcode');
const https = require('https');
const messages = require('../lib/messages');

const baseUrl = 'https://api.postcodes.io';

function lookup(res, next) {
  let url;
  const location = res.locals.location;
  const outcode = Postcode.validOutcode(location);

  if (outcode) {
    url = `${baseUrl}/outcodes/${location}`;
  } else {
    url = `${baseUrl}/postcodes/${location}`;
  }

  https.get(url, (postcodeRes) => {
    log.info('postcodeio-lookup-start');
    let body = '';

    postcodeRes.on('data', (chunk) => {
      body += chunk;
    });

    postcodeRes.on('end', () => {
      log.info('postcodeio-lookup-end');
      let postcode;
      switch (postcodeRes.statusCode) {
        case 200:
          postcode = JSON.parse(body);
          // eslint-disable-next-line no-param-reassign
          res.locals.coordinates = {
            latitude: postcode.result.latitude,
            longitude: postcode.result.longitude,
          };
          next();
          break;
        case 404:
          log.warn({ res: postcodeRes }, '404 from postcodes.io');
          next({ type: 'invalid-postcode', message: messages.invalidPostcodeMessage(location) });
          break;
        default:
          log.warn({ url, response: postcodeRes.statusCode });
          next(
            {
              type: 'postcode-service-error',
              message: `Postcode service error: ${postcodeRes.statusCode}`,
            }
          );
      }
    });
  }).on('error', (e) => {
    // TODO: Add 'standard' error
    log.error({ err: e }, 'Postcode lookup failed');
    next({ type: 'postcode-service-error', message: e.message });
  });
}

module.exports = {
  lookup,
};
<commit_msg>:evergreen_tree: Log location lookup failures<commit_after>const log = require('../../app/lib/logger');
const Postcode = require('postcode');
const https = require('https');
const messages = require('../lib/messages');

const baseUrl = 'https://api.postcodes.io';

function lookup(res, next) {
  let url;
  const location = res.locals.location;
  const outcode = Postcode.validOutcode(location);

  if (outcode) {
    url = `${baseUrl}/outcodes/${location}`;
  } else {
    url = `${baseUrl}/postcodes/${location}`;
  }

  https.get(url, (postcodeRes) => {
    log.info('postcodeio-lookup-start');
    let body = '';

    postcodeRes.on('data', (chunk) => {
      body += chunk;
    });

    postcodeRes.on('end', () => {
      log.info('postcodeio-lookup-end');
      let postcode;
      switch (postcodeRes.statusCode) {
        case 200:
          postcode = JSON.parse(body);
          // eslint-disable-next-line no-param-reassign
          res.locals.coordinates = {
            latitude: postcode.result.latitude,
            longitude: postcode.result.longitude,
          };
          next();
          break;
        case 404:
          log.warn({ res: postcodeRes, location }, '404 from postcodes.io');
          next({ type: 'invalid-postcode', message: messages.invalidPostcodeMessage(location) });
          break;
        default:
          log.warn({ url, response: postcodeRes.statusCode, location });
          next(
            {
              type: 'postcode-service-error',
              message: `Postcode service error: ${postcodeRes.statusCode}`,
            }
          );
      }
    });
  }).on('error', (e) => {
    // TODO: Add 'standard' error
    log.error({ err: e, location }, 'Postcode lookup failed');
    next({ type: 'postcode-service-error', message: e.message });
  });
}

module.exports = {
  lookup,
};
<|endoftext|>


<commit_before>define(function() {

    var pad0 = function(n) {
        return n < 10 ? "0"+n : n+"";
    };

    var _overlapRange = function(r1,r2) {
        var d1,d2,d3,d4;
        d1 = this.date2string(r1[0]);
        d2 = this.date2string(r1[1]);
        d3 = this.date2string(r2[0]);
        d4 = this.date2string(r2[1]);
        return (d1 <= d4 && d3 <= d2);
    };

    return {
        isArray: function(a) {
            return Object.prototype.toString.call( a ) === '[object Array]'
        },
        date2string : function(d) {
            return d.getFullYear()+"-"+pad0((d.getMonth()+1)) + "-" + pad0(d.getDate());
        },
        extend : function(obj1, obj2) {
            for(var i in obj2) {
                obj1[i]= obj2[i];
            }
            return obj1;
        },
        getDateAddingDays: function(d, days) {
            var n = new Date(d);
            n.setDate(n.getDate()+ (+days));
            return n;
        },
        splitRange: function(range, d) {
            var begin = new Date(range[0]);
            var end   = new Date(range[1]);
            var point = this.date2string(d);
            if (point > this.date2string(end) || point < this.date2string(begin)) {
                return [null,null];
            }
            var mid1 = this.getDateAddingDays(d, -1);
            var mid2 = this.getDateAddingDays(d, 1);

            return [+mid1 > +begin ? [begin, mid1] : null, mid2 < end ? [mid2, end] : null];

        },

        overlaps : function(dateOrRange1, dateOrRange2) {
            var i,j, c1, c2;
            dateOrRange1 = this.normalizeDates(dateOrRange1);
            dateOrRange2 = this.normalizeDates(dateOrRange2);
            for( i = 0; i < dateOrRange1.length; i++) {
                if(dateOrRange1[i] instanceof Date) {
                    c1 = [dateOrRange1[i], dateOrRange1[i]];
                }else {
                    c1 = dateOrRange1[i].length === 1 ? [dateOrRange1[i][0], dateOrRange1[i][0]] : dateOrRange1[i];
                }
                for(j=0; j < dateOrRange2.length; j++) {
                    if(dateOrRange2[j] instanceof Date) {
                        c2 = [dateOrRange2[j],dateOrRange2[j]];
                    }else {
                        c2 = dateOrRange2[j].length === 1 ? [dateOrRange2[j][0], dateOrRange2[j][0]] : dateOrRange2[j];
                    }
                    if(_overlapRange.apply(this, [c1,c2])) {
                        return true;
                    }
                }
            }
            return false;
        },
        normalizeDate  : function (inpt) {
            var returnDate, d;
            if(arguments.length === 3) {
                returnDate = new Date(arguments[0], arguments[1], arguments[2]);
            }else if (inpt instanceof Date) {

                returnDate = new Date(+inpt);

            } else if (typeof inpt === "string") {

                switch (inpt) {
                    case "now":
                    case "today" :
                        returnDate = new Date();
                        break;
                    case "yesterday" :
                        d = new Date();
                        d.setDate(d.getDate() - 1);
                        returnDate = d;
                        break;
                    case "tomorrow" :
                        d = new Date();
                        d.setDate(d.getDate() + 1);
                        returnDate = d;
                        break;
                    case "--" :
                    case "a long time ago" :
                        returnDate = new Date(0, 0, 1);
                        break;
                    case "++" :
                    case "future" :
                        returnDate = new Date((new Date()).getFullYear() + 4000, 11, 31);
                        break;
                    default :
                        var parts = inpt.split("-");
                        if(parts.length === 3) {
                            returnDate = new Date();
                            returnDate.setDate(parts[2]);
                            returnDate.setMonth(+parts[1]-1);
                            returnDate.setFullYear(parts[0]);
                        }

                }
            }

            returnDate.setHours(15);
            returnDate.setMinutes(0);
            returnDate.setSeconds(0);
            return returnDate;
        },
        normalizeDates : function (dates) {
            var i,j;
            var ret = [];
            if (this.isArray(dates)) {
                for (i = 0; i < dates.length; i++) {
                    if (!this.isArray(dates[i])) {
                        ret[i] =  [this.normalizeDate(dates[i])];
                    }else {
                        ret[i] = [];
                        for (j = 0; j < dates[i].length; j++) {
                            ret[i][j] = this.normalizeDate(dates[i][j]);
                            if(j === 1 && this.date2string(ret[i][0]) > this.date2string(ret[i][j])) {
                                throw "inverted ranges";
                            }
                        }
                    }

                }
            } else {
                ret = [[this.normalizeDate(dates)]];
            }
            return ret;
        },
        functionize : function(value) {
            if(typeof value !== "function") {
                var scalar = value;
                value = function() {
                    return scalar;
                }
            }
            return value;
        },
        ucfirst: function(str) {
            return str.charAt(0).toUpperCase() + str.slice(1);
        },
        buildEventsListener: function(eventsName, object) {
            var _listeners = {};
            var method;

            for(var i = 0; i < eventsName.length; i++) {
                _listeners[eventsName[i]] = [];
                method = "on"+this.ucfirst(eventsName[i]);

                object[method] = (function(eventName) {
                    return function(cbk) {
                        _listeners[eventName].push(cbk);
                    }
                })(eventsName[i]);
            }

            var _callback = function (c, ui, args) {
                if (args === undefined) args = [];
                for (var i = 0; i < _listeners[c].length; i++) {
                    _listeners[c][i].apply(ui, args);
                }
            };

            return function(name, context, args) {
                if (args === undefined) args = [];
                for (var i = 0; i < _listeners[name].length; i++) {
                    _listeners[name][i].apply(context, args);
                }
            }

        }
    }
});<commit_msg>deleted legacy & useless code<commit_after>define(function() {

    var pad0 = function(n) {
        return n < 10 ? "0"+n : n+"";
    };

    var _overlapRange = function(r1,r2) {
        var d1,d2,d3,d4;
        d1 = this.date2string(r1[0]);
        d2 = this.date2string(r1[1]);
        d3 = this.date2string(r2[0]);
        d4 = this.date2string(r2[1]);
        return (d1 <= d4 && d3 <= d2);
    };

    return {
        isArray: function(a) {
            return Object.prototype.toString.call( a ) === '[object Array]'
        },
        date2string : function(d) {
            return d.getFullYear()+"-"+pad0((d.getMonth()+1)) + "-" + pad0(d.getDate());
        },
        extend : function(obj1, obj2) {
            for(var i in obj2) {
                obj1[i]= obj2[i];
            }
            return obj1;
        },
        getDateAddingDays: function(d, days) {
            var n = new Date(d);
            n.setDate(n.getDate()+ (+days));
            return n;
        },
        splitRange: function(range, d) {
            var begin = new Date(range[0]);
            var end   = new Date(range[1]);
            var point = this.date2string(d);
            if (point > this.date2string(end) || point < this.date2string(begin)) {
                return [null,null];
            }
            var mid1 = this.getDateAddingDays(d, -1);
            var mid2 = this.getDateAddingDays(d, 1);

            return [+mid1 > +begin ? [begin, mid1] : null, mid2 < end ? [mid2, end] : null];

        },

        overlaps : function(dateOrRange1, dateOrRange2) {
            var i,j, c1, c2;
            dateOrRange1 = this.normalizeDates(dateOrRange1);
            dateOrRange2 = this.normalizeDates(dateOrRange2);
            for( i = 0; i < dateOrRange1.length; i++) {
                if(dateOrRange1[i] instanceof Date) {
                    c1 = [dateOrRange1[i], dateOrRange1[i]];
                }else {
                    c1 = dateOrRange1[i].length === 1 ? [dateOrRange1[i][0], dateOrRange1[i][0]] : dateOrRange1[i];
                }
                for(j=0; j < dateOrRange2.length; j++) {
                    if(dateOrRange2[j] instanceof Date) {
                        c2 = [dateOrRange2[j],dateOrRange2[j]];
                    }else {
                        c2 = dateOrRange2[j].length === 1 ? [dateOrRange2[j][0], dateOrRange2[j][0]] : dateOrRange2[j];
                    }
                    if(_overlapRange.apply(this, [c1,c2])) {
                        return true;
                    }
                }
            }
            return false;
        },
        normalizeDate  : function (inpt) {
            var returnDate, d;
            if(arguments.length === 3) {
                returnDate = new Date(arguments[0], arguments[1], arguments[2]);
            }else if (inpt instanceof Date) {

                returnDate = new Date(+inpt);

            } else if (typeof inpt === "string") {

                switch (inpt) {
                    case "now":
                    case "today" :
                        returnDate = new Date();
                        break;
                    case "yesterday" :
                        d = new Date();
                        d.setDate(d.getDate() - 1);
                        returnDate = d;
                        break;
                    case "tomorrow" :
                        d = new Date();
                        d.setDate(d.getDate() + 1);
                        returnDate = d;
                        break;
                    case "--" :
                    case "a long time ago" :
                        returnDate = new Date(0, 0, 1);
                        break;
                    case "++" :
                    case "future" :
                        returnDate = new Date((new Date()).getFullYear() + 4000, 11, 31);
                        break;
                    default :
                        var parts = inpt.split("-");
                        if(parts.length === 3) {
                            returnDate = new Date();
                            returnDate.setDate(parts[2]);
                            returnDate.setMonth(+parts[1]-1);
                            returnDate.setFullYear(parts[0]);
                        }

                }
            }

            returnDate.setHours(15);
            returnDate.setMinutes(0);
            returnDate.setSeconds(0);
            return returnDate;
        },
        normalizeDates : function (dates) {
            var i,j;
            var ret = [];
            if (this.isArray(dates)) {
                for (i = 0; i < dates.length; i++) {
                    if (!this.isArray(dates[i])) {
                        ret[i] =  [this.normalizeDate(dates[i])];
                    }else {
                        ret[i] = [];
                        for (j = 0; j < dates[i].length; j++) {
                            ret[i][j] = this.normalizeDate(dates[i][j]);
                            if(j === 1 && this.date2string(ret[i][0]) > this.date2string(ret[i][j])) {
                                throw "inverted ranges";
                            }
                        }
                    }

                }
            } else {
                ret = [[this.normalizeDate(dates)]];
            }
            return ret;
        },
        functionize : function(value) {
            if(typeof value !== "function") {
                var scalar = value;
                value = function() {
                    return scalar;
                }
            }
            return value;
        },
        ucfirst: function(str) {
            return str.charAt(0).toUpperCase() + str.slice(1);
        },
        buildEventsListener: function(eventsName, object) {
            var _listeners = {};
            var method;

            for(var i = 0; i < eventsName.length; i++) {
                _listeners[eventsName[i]] = [];
                method = "on"+this.ucfirst(eventsName[i]);

                object[method] = (function(eventName) {
                    return function(cbk) {
                        _listeners[eventName].push(cbk);
                    }
                })(eventsName[i]);
            }

            return function(name, context, args) {
                if (args === undefined) args = [];
                for (var i = 0; i < _listeners[name].length; i++) {
                    _listeners[name][i].apply(context, args);
                }
            }

        }
    }
});<|endoftext|>


<commit_before>import React, { PureComponent } from 'react';
import { css } from 'glamor';
import Globals from '../utils/Globals';

import Text from './Text';

import stubailoImg from '../media/images/speakers/sashko-pb.jpg';
import jbaxleyiiiImg from '../media/images/speakers/jbaxleyiii-pb.jpg';
import sibeliusImg from '../media/images/speakers/sibelius-pb.jpg';
import daciukImg from '../media/images/speakers/daciuk-pb.jpg';
import marsiglioImg from '../media/images/speakers/marsiglio-pb.jpg';
import amorimImg from '../media/images/speakers/amorim-pb.jpg';
import keteImg from '../media/images/speakers/kete-pb.jpg';
import milfontImg from '../media/images/speakers/milfont-pb.jpg';

const styles = {
  container: css({
    background: Globals.colors.white,
    width: '100vw',
    alignItems: 'center',
    '@media(max-width: 720px)': {
      alignSelf: 'auto',
    },
  }),
  link: css({
    color: '#666666',
  }),
  name: css({
    fontSize: '1.999em',
    color: Globals.colors.primary,
    fontWeight: 'light',
    margin: '0.66em 0 0.15em 0',
    lineHeight: 1,
  }),
  locale: css({
    fontSize: '1em',
    fontWeight: 'lighter',
    margin: '0 0 0.33em 0',
  }),
  theme: css({
    fontSize: '1.414em',
    color: Globals.colors.subheader,
    margin: '0 0 0.33em 0',
    fontWeight: 'lighter',
  }),
  card: css({
    width: 300,
    maxWidth: '100%',
    padding: '0',
    backgroundColor: Globals.colors.white,
    borderRadius: 0,
    margin: 20,
    '@media(min-width: 720px)': {
      margin: 10,
    },
  }),
  cards: css({
    display: 'flex',
    flexWrap: 'wrap',
    alignItems: 'flex-start',
    justifyContent: 'space-around',
    width: '100%',
    margin: '0 auto',
    maxWidth: 1000,
  }),
};

const Speakers = [
  {
    id: 7,
    name: 'Sashko Stubailo',
    theme: 'The GraphQL and Apollo stack: Connecting everything together',
    origin: 'San Francisco, California, EUA',
    github: 'https://github.com/stubailo',
    avatar: stubailoImg,
  },
  {
    id: 8,
    name: 'James Baxtley',
    theme: 'Statically Typing your GraphQL App',
    origin: ' Anderson, South Carolina, EUA',
    github: 'https://github.com/jbaxleyiii',
    avatar: jbaxleyiiiImg,
  },
  {
    id: 1,
    name: 'Sibelius Seraphini',
    theme: 'Relay Modern',
    origin: 'São Paulo, Brasil',
    github: 'https://github.com/sibelius',
    avatar: sibeliusImg,
  },
  {
    id: 2,
    name: 'Matheus Marsiglio',
    theme: 'Isomorphic React + Redux App',
    origin: 'São Paulo, Brasil',
    github: 'https://github.com/mtmr0x',
    avatar: marsiglioImg,
  },
  {
    id: 3,
    name: 'Raphael Amorim',
    theme: 'Scratching React Fiber',
    origin: 'Rio de Janeiro, Brasil',
    github: 'https://github.com/raphamorim',
    avatar: amorimImg,
  },
  {
    id: 4,
    name: 'Fernando Daciuk',
    theme: 'The Magic World of Tests with Jest',
    origin: 'Curitiba, Brasil',
    github: 'https://github.com/fdaciuk',
    avatar: daciukImg,
  },
  {
    id: 5,
    name: 'Kete Rufino',
    theme: 'From a legacy front end to a React SPA',
    origin: 'Ceara, Brasil',
    github: 'https://github.com/ketemartinsrufino',
    avatar: keteImg,
  },
  {
    id: 6,
    name: 'Christiano Milfont',
    theme: 'From a legacy front end to a React SPA',
    origin: 'Ceara, Brasil',
    github: 'https://github.com/cmilfont',
    avatar: milfontImg,
  },
];

class TextSpeakers extends PureComponent {
  render() {
    return (

        <Text title="Palestrantes" reverse />

          {Speakers.map(speaker => {
            return (

                <div
                  {...css({
                    backgroundImage: `url('${speaker.avatar}')`,
                    backgroundSize: 'cover',
                    backgroundPosition: 'center',
                    height: 300,
                  })}
                />

                  {speaker.name}

                  {speaker.origin}

                  {speaker.theme}

            );
          })}

    );
  }
}

export default TextSpeakers;
<commit_msg>James misspelled.<commit_after>import React, { PureComponent } from 'react';
import { css } from 'glamor';
import Globals from '../utils/Globals';

import Text from './Text';

import stubailoImg from '../media/images/speakers/sashko-pb.jpg';
import jbaxleyiiiImg from '../media/images/speakers/jbaxleyiii-pb.jpg';
import sibeliusImg from '../media/images/speakers/sibelius-pb.jpg';
import daciukImg from '../media/images/speakers/daciuk-pb.jpg';
import marsiglioImg from '../media/images/speakers/marsiglio-pb.jpg';
import amorimImg from '../media/images/speakers/amorim-pb.jpg';
import keteImg from '../media/images/speakers/kete-pb.jpg';
import milfontImg from '../media/images/speakers/milfont-pb.jpg';

const styles = {
  container: css({
    background: Globals.colors.white,
    width: '100vw',
    alignItems: 'center',
    '@media(max-width: 720px)': {
      alignSelf: 'auto',
    },
  }),
  link: css({
    color: '#666666',
  }),
  name: css({
    fontSize: '1.999em',
    color: Globals.colors.primary,
    fontWeight: 'light',
    margin: '0.66em 0 0.15em 0',
    lineHeight: 1,
  }),
  locale: css({
    fontSize: '1em',
    fontWeight: 'lighter',
    margin: '0 0 0.33em 0',
  }),
  theme: css({
    fontSize: '1.414em',
    color: Globals.colors.subheader,
    margin: '0 0 0.33em 0',
    fontWeight: 'lighter',
  }),
  card: css({
    width: 300,
    maxWidth: '100%',
    padding: '0',
    backgroundColor: Globals.colors.white,
    borderRadius: 0,
    margin: 20,
    '@media(min-width: 720px)': {
      margin: 10,
    },
  }),
  cards: css({
    display: 'flex',
    flexWrap: 'wrap',
    alignItems: 'flex-start',
    justifyContent: 'space-around',
    width: '100%',
    margin: '0 auto',
    maxWidth: 1000,
  }),
};

const Speakers = [
  {
    id: 7,
    name: 'Sashko Stubailo',
    theme: 'The GraphQL and Apollo stack: Connecting everything together',
    origin: 'San Francisco, California, EUA',
    github: 'https://github.com/stubailo',
    avatar: stubailoImg,
  },
  {
    id: 8,
    name: 'James Baxley',
    theme: 'Statically Typing your GraphQL App',
    origin: ' Anderson, South Carolina, EUA',
    github: 'https://github.com/jbaxleyiii',
    avatar: jbaxleyiiiImg,
  },
  {
    id: 1,
    name: 'Sibelius Seraphini',
    theme: 'Relay Modern',
    origin: 'São Paulo, Brasil',
    github: 'https://github.com/sibelius',
    avatar: sibeliusImg,
  },
  {
    id: 2,
    name: 'Matheus Marsiglio',
    theme: 'Isomorphic React + Redux App',
    origin: 'São Paulo, Brasil',
    github: 'https://github.com/mtmr0x',
    avatar: marsiglioImg,
  },
  {
    id: 3,
    name: 'Raphael Amorim',
    theme: 'Scratching React Fiber',
    origin: 'Rio de Janeiro, Brasil',
    github: 'https://github.com/raphamorim',
    avatar: amorimImg,
  },
  {
    id: 4,
    name: 'Fernando Daciuk',
    theme: 'The Magic World of Tests with Jest',
    origin: 'Curitiba, Brasil',
    github: 'https://github.com/fdaciuk',
    avatar: daciukImg,
  },
  {
    id: 5,
    name: 'Kete Rufino',
    theme: 'From a legacy front end to a React SPA',
    origin: 'Ceara, Brasil',
    github: 'https://github.com/ketemartinsrufino',
    avatar: keteImg,
  },
  {
    id: 6,
    name: 'Christiano Milfont',
    theme: 'From a legacy front end to a React SPA',
    origin: 'Ceara, Brasil',
    github: 'https://github.com/cmilfont',
    avatar: milfontImg,
  },
];

class TextSpeakers extends PureComponent {
  render() {
    return (

        <Text title="Palestrantes" reverse />

          {Speakers.map(speaker => {
            return (

                <div
                  {...css({
                    backgroundImage: `url('${speaker.avatar}')`,
                    backgroundSize: 'cover',
                    backgroundPosition: 'center',
                    height: 300,
                  })}
                />

                  {speaker.name}

                  {speaker.origin}

                  {speaker.theme}

            );
          })}

    );
  }
}

export default TextSpeakers;
<|endoftext|>


<commit_before>// TODO: remove global
this.getAvatarUrlFromUsername = function(username) {
	const key = `avatar_random_${ username }`;
	const random = typeof Session !== 'undefined' ? Session.keys[key] : 0;
	if (username == null) {
		return;
	}
	const cdnPrefix = (RocketChat.settings.get('CDN_PREFIX') || '').trim().replace(/\/$/, '');
	const pathPrefix = (__meteor_runtime_config__.ROOT_URL_PATH_PREFIX || '').trim().replace(/\/$/, '');
	let path = pathPrefix;
	if (cdnPrefix) {
		path = cdnPrefix + pathPrefix;
	} else if (Meteor.isCordova) {
		path = Meteor.absoluteUrl().replace(/\/$/, '');
	}
	return `${ path }/avatar/${ encodeURIComponent(username) }?_dc=${ random }`;
};
<commit_msg>[FIX] avatar?_dc=undefined (#12365)<commit_after>// TODO: remove global
this.getAvatarUrlFromUsername = function(username) {
	const key = `avatar_random_${ username }`;
	const random = typeof Session !== 'undefined' && typeof Session.keys[key] !== 'undefined' ? Session.keys[key] : 0;
	if (username == null) {
		return;
	}
	const cdnPrefix = (RocketChat.settings.get('CDN_PREFIX') || '').trim().replace(/\/$/, '');
	const pathPrefix = (__meteor_runtime_config__.ROOT_URL_PATH_PREFIX || '').trim().replace(/\/$/, '');
	let path = pathPrefix;
	if (cdnPrefix) {
		path = cdnPrefix + pathPrefix;
	} else if (Meteor.isCordova) {
		path = Meteor.absoluteUrl().replace(/\/$/, '');
	}
	return `${ path }/avatar/${ encodeURIComponent(username) }?_dc=${ random }`;
};
<|endoftext|>


<commit_before>import { is } from 'funkis'

export async function timed(fn) {
  if (!is(Function, fn)) {
    fn = Promise.resolve.bind(Promise, fn)
  }

  const start = process.hrtime()
  const result = await(fn())
  const duration = process.hrtime(start)
  const ms = (duration[0] * 1e9 + duration[1]) / 1e6

  return { result, duration:
    { ms }
  }
}<commit_msg>Simplify performance timer<commit_after>import { val } from 'funkis'

export async function timed(proc) {
  const start = process.hrtime()
  const result = await Promise.resolve(val(proc))
  const duration = process.hrtime(start)

  duration.ns = duration[0] * 1e9 + duration[1]
  duration.ms = duration.ns / 1e6
  duration.s  = duration.ns / 1e9

  return { result, duration }
}<|endoftext|>