<commit_before>(function () {
"use strict";

var i, j, k, pieces, currentPlayer, singlePlayer;

currentPlayer = 2;
singlePlayer = true;

function $(id) {
  return document.getElementById(id);
}

function html(id, text) {
  $(id).innerHTML = text;
}

function animate(element, klass, callback) {
  var wrapper = function () {
    var regex = new RegExp(' ' + klass, 'g');
    if (callback) {
      callback();
    }
    element.className = element.className.replace(regex, '');
    element.removeEventListener('webkitTransitionEnd', wrapper, true);
  };
  element.addEventListener('webkitTransitionEnd', wrapper, true);
  element.className += ' ' + klass;
}

function findCenter(element) {
  var x = 0, y = 0;
  if (element) {
    x = element.offsetWidth / 2;
    y = element.offsetHeight / 2;
  }
  while (element && !isNaN(element.offsetLeft) && !isNaN(element.offsetTop)) {
    x += element.offsetLeft - element.scrollLeft;
    y += element.offsetTop - element.scrollTop;
    element = element.offsetParent;
  }
  return { x: x, y: y };
}

function countScore(total, factor) {
  return (total % factor === 0) ? total / factor : 0;
}

function getScore() {
  return parseInt($('player' + currentPlayer + '-score').innerHTML);
}

function setScore(newScore) {
  html('player' + currentPlayer + '-score', newScore);
}

function countUnique(array) {
  var i, keys;
  keys = {};
  for (i = 0; i < array.length; i += 1) {
    keys[array[i]] = 1;
  }
  return Object.keys(keys).length;
}

function bonusScore(values) {
  var i, score, straight, unique;
  if (values.length <= 1) {
    return 0;
  }
  unique = countUnique(values);
  if (values.length <= 2) {
    /* a pair */
    if (unique === 1) return 2;
    return 0;
  }
  if (values.length <= 3) {
    /* a pair */
    if (unique === 2) return 2;
    /* three of a kind */
    if (unique === 1) return 6;
    return 0;
  }
  score = 0;
  straight = 0;
  values.sort();
  for (i = 0; i < values.length - 1; i += 1) {
    if (values[i] + 1 === values[i + 1]) {
      straight += 1;
    }
  }
  /* a straight */
  if (straight === 3) score += 4;
  /* a pair */
  if (unique === 3) score += 2;
  /* three of a kind */
  if (unique === 2) score += 6;
  /* four of a kind */
  if (unique === 1) score += 12;
  return score;
}

function updateScore(element) {
  setScore(guessScore(element));
}

function guessScore(element, guess) {
  var i, j, value, values, score, classes, matches, total;
  score = getScore();
  classes = element.className.replace(/\s+/g, ' ').split(' ');
  for (i = 0; i < classes.length; i += 1) {
    total = 0;
    values = [];
    matches = document.getElementsByClassName(classes[i]);
    for (j = 0; j < matches.length; j += 1) {
      value = parseInt(matches[j].innerHTML);
      if (guess && matches[j] === element) {
        value = guess;
      }
      if (!isNaN(value)) {
        values.push(value);
        total += value;
      }
    }
    score += countScore(total, 3);
    score += countScore(total, 5);
    score += countScore(total, 7);
    score += bonusScore(values);
  }
  return score;
}

function isPlayable(element) {
  return element && element.nodeName === 'TD' && element.innerHTML === '';
}

function endTurn(piece, tile) {
  tile.innerHTML = piece.innerHTML;
  piece.parentNode.removeChild(piece);
  updateScore(tile);
  toggleTurn();
}

var dragDrop = {
  initialMouseX: null,
  initialMouseY: null,
  startX: null,
  startY: null,
  draggedObject: null,
  droppedObject: null,

  bind: function (element) {
    if (typeof element === "string") {
      element = $(element);
    }
    if (element) {
      element.addEventListener("mousedown", dragDrop.startDragMouse, false);
      element.style.color = "#000";
      element.style.top = "0px";
      element.style.left = "0px";
    }
  },

  unbind: function (element) {
    if (typeof element === "string") {
      element = $(element);
    }
    if (element) {
      element.removeEventListener("mousedown", dragDrop.startDragMouse, false);
      element.style.color = "#fff";
    }
  },

  startDragMouse: function (e) {
    dragDrop.startDrag(this);
    dragDrop.initialMouseX = e.clientX;
    dragDrop.initialMouseY = e.clientY;
    document.addEventListener("mousemove", dragDrop.dragMouse, false);
    document.addEventListener("mouseup", dragDrop.releaseElement, false);
    return false;
  },

  startDrag: function (object) {
    if (dragDrop.draggedObjct) {
      dragDrop.releaseElement();
    }
    dragDrop.startX = parseInt(object.style.left);
    dragDrop.startY = parseInt(object.style.top);
    dragDrop.draggedObject = object;
  },

  dragMouse: function (e) {
    var dx = e.clientX - dragDrop.initialMouseX;
    var dy = e.clientY - dragDrop.initialMouseY;
    dragDrop.draggedObject.style.left = dragDrop.startX + dx + "px";
    dragDrop.draggedObject.style.top = dragDrop.startY + dy + "px";
    if (dragDrop.droppedObject) {
      dragDrop.droppedObject.className = dragDrop.droppedObject.className.replace(/ dropping/g, '');
    }
    dragDrop.draggedObject.style.display = 'none';
    dragDrop.droppedObject = document.elementFromPoint(e.clientX, e.clientY);
    dragDrop.draggedObject.style.display = 'inline-block';
    if (isPlayable(dragDrop.droppedObject)) {
      dragDrop.droppedObject.className += ' dropping';
    }
    return false;
  },

  releaseElement: function (e) {
    var under = null;
    document.removeEventListener("mousemove", dragDrop.dragMouse, false);
    document.removeEventListener("mouseup", dragDrop.releaseElement, false);
    dragDrop.draggedObject.style.display = 'none';
    under = document.elementFromPoint(e.clientX, e.clientY);
    if (isPlayable(under)) {
      endTurn(dragDrop.draggedObject, under);
    } else {
      dragDrop.draggedObject.style.display = 'inline-block';
      dragDrop.draggedObject.style.left = dragDrop.startX + "px";
      dragDrop.draggedObject.style.top = dragDrop.startY + "px";
    }
    dragDrop.draggedObject = null;
    if (dragDrop.droppedObject) {
      dragDrop.droppedObject.style.background = "#fff";
    }
    dragDrop.droppedObject = null;
  }
}

function fakeMove(piece, tile) {
  var pieceCenter, tileCenter;

  if (isPlayable(tile)) {
    pieceCenter = findCenter(piece);
    tileCenter = findCenter(tile);
    animate(piece, 'moving', function () { endTurn(piece, tile); });
    piece.style.left = parseInt(piece.style.left) + (tileCenter.x - pieceCenter.x) + 'px';
    piece.style.top = parseInt(piece.style.top) + (tileCenter.y - pieceCenter.y) + 'px';
  }
}

function makeMove() {
  var i, j, tiles, playables, piece, pieces, value, score, scores, best;

  tiles = document.getElementsByTagName('td');
  playables = [];
  for (i = 0; i < tiles.length; i += 1) {
    if (isPlayable(tiles[i])) {
      playables.push(tiles[i]);
    }
  }

  pieces = [];
  for (i = 0; i < 8; i += 1) {
    piece = $("piece" + currentPlayer + i);
    if (piece) {
      pieces.push(piece);
    }
  }

  best = { piece: undefined, tile: undefined, score: 0 };
  for (i = 0; i < pieces.length; i += 1) {
    value = parseInt(pieces[i].innerHTML);
    for (j = 0; j < playables.length; j += 1) {
      score = guessScore(playables[j], value);
      if (score >= best.score) {
        best = { piece: pieces[i], tile: playables[j], score: score };
      }
    }
  }

  fakeMove(best.piece, best.tile);

  console.log('Best move is:');
  console.log('Piece: ' + best.piece.innerHTML);
  console.log('Tile: ' + best.tile.className);
  console.log('Score: ' + best.score);
}

function toggleTurn() {
  var i;
  for (i = 0; i < 8; i += 1) {
    dragDrop.unbind("piece1" + i);
    dragDrop.unbind("piece2" + i);
  }
  currentPlayer = (currentPlayer === 1) ? 2 : 1;
  for (i = 0; i < 8; i += 1) {
    dragDrop.bind("piece" + currentPlayer + i);
  }
  if (singlePlayer && currentPlayer === 2) {
    makeMove();
  }
}

function shuffle(array) {
  var i, j, temp;
  for (i = array.length - 1; i > 0; i -= 1) {
    j = Math.floor(Math.random() * (i + 1));
    temp = array[i];
    array[i] = array[j];
    array[j] = temp;
  }
}

pieces = [];
for (i = 0; i < 4; i += 1) {
  for (j = 1; j <= 13; j += 1) {
    pieces.push(j);
  }
}
shuffle(pieces);

for (i = 0, j = 0, k = 0; i < 16; i += 1) {
  if (i % 2 === 0) {
    html("piece1" + j, pieces[i]);
    j += 1;
  } else {
    html("piece2" + k, pieces[i]);
    k += 1;
  }
}

toggleTurn();

}());
<commit_msg>Paves the way for an AI vs. AI setup in the future.<commit_after>(function () {
"use strict";

var i, j, k, pieces, currentPlayer, numberOfPlayers;

currentPlayer = 2;
numberOfPlayers = 1;

function $(id) {
  return document.getElementById(id);
}

function html(id, text) {
  $(id).innerHTML = text;
}

function animate(element, klass, callback) {
  var wrapper = function () {
    var regex = new RegExp(' ' + klass, 'g');
    if (callback) {
      callback();
    }
    element.className = element.className.replace(regex, '');
    element.removeEventListener('webkitTransitionEnd', wrapper, true);
  };
  element.addEventListener('webkitTransitionEnd', wrapper, true);
  element.className += ' ' + klass;
}

function findCenter(element) {
  var x = 0, y = 0;
  if (element) {
    x = element.offsetWidth / 2;
    y = element.offsetHeight / 2;
  }
  while (element && !isNaN(element.offsetLeft) && !isNaN(element.offsetTop)) {
    x += element.offsetLeft - element.scrollLeft;
    y += element.offsetTop - element.scrollTop;
    element = element.offsetParent;
  }
  return { x: x, y: y };
}

function countScore(total, factor) {
  return (total % factor === 0) ? total / factor : 0;
}

function getScore() {
  return parseInt($('player' + currentPlayer + '-score').innerHTML);
}

function setScore(newScore) {
  html('player' + currentPlayer + '-score', newScore);
}

function countUnique(array) {
  var i, keys;
  keys = {};
  for (i = 0; i < array.length; i += 1) {
    keys[array[i]] = 1;
  }
  return Object.keys(keys).length;
}

function bonusScore(values) {
  var i, score, straight, unique;
  if (values.length <= 1) {
    return 0;
  }
  unique = countUnique(values);
  if (values.length <= 2) {
    /* a pair */
    if (unique === 1) return 2;
    return 0;
  }
  if (values.length <= 3) {
    /* a pair */
    if (unique === 2) return 2;
    /* three of a kind */
    if (unique === 1) return 6;
    return 0;
  }
  score = 0;
  straight = 0;
  values.sort();
  for (i = 0; i < values.length - 1; i += 1) {
    if (values[i] + 1 === values[i + 1]) {
      straight += 1;
    }
  }
  /* a straight */
  if (straight === 3) score += 4;
  /* a pair */
  if (unique === 3) score += 2;
  /* three of a kind */
  if (unique === 2) score += 6;
  /* four of a kind */
  if (unique === 1) score += 12;
  return score;
}

function updateScore(element) {
  setScore(guessScore(element));
}

function guessScore(element, guess) {
  var i, j, value, values, score, classes, matches, total;
  score = getScore();
  classes = element.className.replace(/\s+/g, ' ').split(' ');
  for (i = 0; i < classes.length; i += 1) {
    total = 0;
    values = [];
    matches = document.getElementsByClassName(classes[i]);
    for (j = 0; j < matches.length; j += 1) {
      value = parseInt(matches[j].innerHTML);
      if (guess && matches[j] === element) {
        value = guess;
      }
      if (!isNaN(value)) {
        values.push(value);
        total += value;
      }
    }
    score += countScore(total, 3);
    score += countScore(total, 5);
    score += countScore(total, 7);
    score += bonusScore(values);
  }
  return score;
}

function isPlayable(element) {
  return element && element.nodeName === 'TD' && element.innerHTML === '';
}

function endTurn(piece, tile) {
  tile.innerHTML = piece.innerHTML;
  piece.parentNode.removeChild(piece);
  updateScore(tile);
  toggleTurn();
}

var dragDrop = {
  initialMouseX: null,
  initialMouseY: null,
  startX: null,
  startY: null,
  draggedObject: null,
  droppedObject: null,

  bind: function (element) {
    if (typeof element === "string") {
      element = $(element);
    }
    if (element) {
      element.addEventListener("mousedown", dragDrop.startDragMouse, false);
      element.style.color = "#000";
      element.style.top = "0px";
      element.style.left = "0px";
    }
  },

  unbind: function (element) {
    if (typeof element === "string") {
      element = $(element);
    }
    if (element) {
      element.removeEventListener("mousedown", dragDrop.startDragMouse, false);
      element.style.color = "#fff";
    }
  },

  startDragMouse: function (e) {
    dragDrop.startDrag(this);
    dragDrop.initialMouseX = e.clientX;
    dragDrop.initialMouseY = e.clientY;
    document.addEventListener("mousemove", dragDrop.dragMouse, false);
    document.addEventListener("mouseup", dragDrop.releaseElement, false);
    return false;
  },

  startDrag: function (object) {
    if (dragDrop.draggedObjct) {
      dragDrop.releaseElement();
    }
    dragDrop.startX = parseInt(object.style.left);
    dragDrop.startY = parseInt(object.style.top);
    dragDrop.draggedObject = object;
  },

  dragMouse: function (e) {
    var dx = e.clientX - dragDrop.initialMouseX;
    var dy = e.clientY - dragDrop.initialMouseY;
    dragDrop.draggedObject.style.left = dragDrop.startX + dx + "px";
    dragDrop.draggedObject.style.top = dragDrop.startY + dy + "px";
    if (dragDrop.droppedObject) {
      dragDrop.droppedObject.className = dragDrop.droppedObject.className.replace(/ dropping/g, '');
    }
    dragDrop.draggedObject.style.display = 'none';
    dragDrop.droppedObject = document.elementFromPoint(e.clientX, e.clientY);
    dragDrop.draggedObject.style.display = 'inline-block';
    if (isPlayable(dragDrop.droppedObject)) {
      dragDrop.droppedObject.className += ' dropping';
    }
    return false;
  },

  releaseElement: function (e) {
    var under = null;
    document.removeEventListener("mousemove", dragDrop.dragMouse, false);
    document.removeEventListener("mouseup", dragDrop.releaseElement, false);
    dragDrop.draggedObject.style.display = 'none';
    under = document.elementFromPoint(e.clientX, e.clientY);
    if (isPlayable(under)) {
      endTurn(dragDrop.draggedObject, under);
    } else {
      dragDrop.draggedObject.style.display = 'inline-block';
      dragDrop.draggedObject.style.left = dragDrop.startX + "px";
      dragDrop.draggedObject.style.top = dragDrop.startY + "px";
    }
    dragDrop.draggedObject = null;
    if (dragDrop.droppedObject) {
      dragDrop.droppedObject.style.background = "#fff";
    }
    dragDrop.droppedObject = null;
  }
}

function fakeMove(piece, tile) {
  var pieceCenter, tileCenter;

  if (isPlayable(tile)) {
    pieceCenter = findCenter(piece);
    tileCenter = findCenter(tile);
    animate(piece, 'moving', function () { endTurn(piece, tile); });
    piece.style.left = parseInt(piece.style.left) + (tileCenter.x - pieceCenter.x) + 'px';
    piece.style.top = parseInt(piece.style.top) + (tileCenter.y - pieceCenter.y) + 'px';
  }
}

function makeMove() {
  var i, j, tiles, playables, piece, pieces, value, score, scores, best;

  tiles = document.getElementsByTagName('td');
  playables = [];
  for (i = 0; i < tiles.length; i += 1) {
    if (isPlayable(tiles[i])) {
      playables.push(tiles[i]);
    }
  }

  pieces = [];
  for (i = 0; i < 8; i += 1) {
    piece = $("piece" + currentPlayer + i);
    if (piece) {
      pieces.push(piece);
    }
  }

  best = { piece: undefined, tile: undefined, score: 0 };
  for (i = 0; i < pieces.length; i += 1) {
    value = parseInt(pieces[i].innerHTML);
    for (j = 0; j < playables.length; j += 1) {
      score = guessScore(playables[j], value);
      if (score >= best.score) {
        best = { piece: pieces[i], tile: playables[j], score: score };
      }
    }
  }

  fakeMove(best.piece, best.tile);

  console.log('Best move is:');
  console.log('Piece: ' + best.piece.innerHTML);
  console.log('Tile: ' + best.tile.className);
  console.log('Score: ' + best.score);
}

function toggleTurn() {
  var i;
  for (i = 0; i < 8; i += 1) {
    dragDrop.unbind("piece1" + i);
    dragDrop.unbind("piece2" + i);
  }
  currentPlayer = (currentPlayer === 1) ? 2 : 1;
  for (i = 0; i < 8; i += 1) {
    dragDrop.bind("piece" + currentPlayer + i);
  }
  if (numberOfPlayers < 2 && currentPlayer === 2) {
    makeMove();
  }
}

function shuffle(array) {
  var i, j, temp;
  for (i = array.length - 1; i > 0; i -= 1) {
    j = Math.floor(Math.random() * (i + 1));
    temp = array[i];
    array[i] = array[j];
    array[j] = temp;
  }
}

pieces = [];
for (i = 0; i < 4; i += 1) {
  for (j = 1; j <= 13; j += 1) {
    pieces.push(j);
  }
}
shuffle(pieces);

for (i = 0, j = 0, k = 0; i < 16; i += 1) {
  if (i % 2 === 0) {
    html("piece1" + j, pieces[i]);
    j += 1;
  } else {
    html("piece2" + k, pieces[i]);
    k += 1;
  }
}

toggleTurn();

}());
<|endoftext|>


<commit_before><commit_msg>Remove blank file<commit_after><|endoftext|>


<commit_before>/* =============================================================

	Modals v4.0
	Simple modal dialogue pop-up windows by Chris Ferdinandi.
	http://gomakethings.com

	Free to use under the MIT License.
	http://gomakethings.com/mit/

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

window.modals = (function (window, document, undefined) {

	'use strict';

	// Show the target modal window
	// Private method
	var _showModal = function (event) {

		// Define the modal
		var dataID = this.getAttribute('data-target');
		var dataTarget = document.querySelector(dataID);

		// Define the modal background
		var modalBg = document.createElement('div');
		modalBg.setAttribute('data-modal-bg', null);
		buoy.addClass(modalBg, 'modal-bg');

		// Prevent `hideModals()` and the default link behavior
		event.stopPropagation();
		event.preventDefault();

		// Activate the modal
		buoy.addClass(dataTarget, 'active');
		dataTarget.style.top = window.pageYOffset + 50 + 'px';
		document.body.appendChild(modalBg);

	};

	// Stop YouTube, Vimeo, and HTML5 videos from playing when hiding a modal
	// Private method
	var _stopVideo = function (modal) {
		var iframe = modal.querySelector( 'iframe');
		var video = modal.querySelector( 'video' );
		if ( iframe !== null ) {
			var iframeSrc = iframe.src;
			iframe.src = iframeSrc;
		}
		if ( video !== null ) {
			video.pause();
		}
	};

	// Hide all modal windows
	// Private method
	var _hideModals = function (modalWindows, event) {

		// Get modal background element
		var modalsBg = document.querySelectorAll('[data-modal-bg]');

		// Prevent hide modal link from opening a URL
		if ( this !== undefined && this.tagName == 'A' ) {
			event.preventDefault();
		}

		// Hide all modals
		Array.prototype.forEach.call(modalWindows, function (modal, index) {
			buoy.removeClass(modal, 'active');
		});

		// Hide all modal backgrounds
		Array.prototype.forEach.call(modalsBg, function (bg, index) {
			document.body.removeChild(bg);
		});

		// Stop any modal videos from playing
		Array.prototype.forEach.call(modalWindows, function (modal, index) {
			_stopVideo(modal);
		});

	};

	// Hide modals when the esc key is pressed
	var _handleEscKey = function (modalWindows) {
		if (event.keyCode == 27) {
			_hideModals(modalWindows, event);
		}
	};

	// Don't hide modals when clicking inside one
	// Private method
	var _handleModalClick = function (event) {
		event.stopPropagation();
	};

	// Initialize Modals
	// Public method
	var init = function () {

		// Feature test before initializing
		if ( 'querySelector' in document && 'addEventListener' in window && Array.prototype.forEach ) {

			// Selectors and variables
			var modalToggles = document.querySelectorAll('[data-modal]');
			var modalWindows = document.querySelectorAll('[data-modal-window]');
			var modalCloseButtons = document.querySelectorAll('[data-modal-close]');

			// When modal toggle is clicked, show modal
			Array.prototype.forEach.call(modalToggles, function (toggle, index) {
				toggle.addEventListener('click', _showModal, false);
			});

			// When modal close is clicked, hide modals
			Array.prototype.forEach.call(modalCloseButtons, function (btn, index) {
				btn.addEventListener('click', _hideModals.bind(btn, modalWindows), false);
			});

			//  Hide all modals
			document.addEventListener('click', _hideModals.bind(this, modalWindows), false); // When body is clicked
			document.addEventListener('touchstart', _hideModals.bind(this, modalWindows), false); // When body is tapped
			document.addEventListener('keydown', _handleEscKey.bind(this, modalWindows), false); // When esc key is pressed

			// When modal itself is clicked, don't close it
			Array.prototype.forEach.call(modalWindows, function (win, index) {
				win.addEventListener('click', _handleModalClick, false);
				win.addEventListener('touchstart', _handleModalClick, false);
			});

		}

	};

	// Return public methods
	return {
		init: init
	};

})(window, document);<commit_msg>Updated function arguments to fix errors in Firefox<commit_after>/* =============================================================

	Modals v4.0
	Simple modal dialogue pop-up windows by Chris Ferdinandi.
	http://gomakethings.com

	Free to use under the MIT License.
	http://gomakethings.com/mit/

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

window.modals = (function (window, document, undefined) {

	'use strict';

	// Show the target modal window
	// Private method
	var _showModal = function (event) {

		// Define the modal
		var dataID = this.getAttribute('data-target');
		var dataTarget = document.querySelector(dataID);

		// Define the modal background
		var modalBg = document.createElement('div');
		modalBg.setAttribute('data-modal-bg', null);
		buoy.addClass(modalBg, 'modal-bg');

		// Prevent `hideModals()` and the default link behavior
		event.stopPropagation();
		event.preventDefault();

		// Activate the modal
		buoy.addClass(dataTarget, 'active');
		dataTarget.style.top = window.pageYOffset + 50 + 'px';
		document.body.appendChild(modalBg);

	};

	// Stop YouTube, Vimeo, and HTML5 videos from playing when hiding a modal
	// Private method
	var _stopVideo = function (modal) {
		var iframe = modal.querySelector( 'iframe');
		var video = modal.querySelector( 'video' );
		if ( iframe !== null ) {
			var iframeSrc = iframe.src;
			iframe.src = iframeSrc;
		}
		if ( video !== null ) {
			video.pause();
		}
	};

	// Hide all modal windows
	// Private method
	var _hideModals = function (modalWindows, event) {

		// Get modal background element
		var modalsBg = document.querySelectorAll('[data-modal-bg]');

		// Prevent hide modal link from opening a URL
		if ( this !== undefined && this !== null && this.tagName == 'A' ) {
			event.preventDefault();
		}

		// Hide all modals
		Array.prototype.forEach.call(modalWindows, function (modal, index) {
			buoy.removeClass(modal, 'active');
		});

		// Hide all modal backgrounds
		Array.prototype.forEach.call(modalsBg, function (bg, index) {
			document.body.removeChild(bg);
		});

		// Stop any modal videos from playing
		Array.prototype.forEach.call(modalWindows, function (modal, index) {
			_stopVideo(modal);
		});

	};

	// Hide modals when the esc key is pressed
	var _handleEscKey = function (modalWindows, event) {
		if (event.keyCode == 27) {
			_hideModals(modalWindows, event);
		}
	};

	// Don't hide modals when clicking inside one
	// Private method
	var _handleModalClick = function (event) {
		event.stopPropagation();
	};

	// Initialize Modals
	// Public method
	var init = function () {

		// Feature test before initializing
		if ( 'querySelector' in document && 'addEventListener' in window && Array.prototype.forEach ) {

			// Selectors and variables
			var modalToggles = document.querySelectorAll('[data-modal]');
			var modalWindows = document.querySelectorAll('[data-modal-window]');
			var modalCloseButtons = document.querySelectorAll('[data-modal-close]');

			// When modal toggle is clicked, show modal
			Array.prototype.forEach.call(modalToggles, function (toggle, index) {
				toggle.addEventListener('click', _showModal, false);
			});

			// When modal close is clicked, hide modals
			Array.prototype.forEach.call(modalCloseButtons, function (btn, index) {
				btn.addEventListener('click', _hideModals.bind(btn, modalWindows), false);
			});

			//  Hide all modals
			document.addEventListener('click', _hideModals.bind(null, modalWindows), false); // When body is clicked
			document.addEventListener('touchstart', _hideModals.bind(null, modalWindows), false); // When body is tapped
			document.addEventListener('keydown', _handleEscKey.bind(null, modalWindows), false); // When esc key is pressed

			// When modal itself is clicked, don't close it
			Array.prototype.forEach.call(modalWindows, function (win, index) {
				win.addEventListener('click', _handleModalClick, false);
				win.addEventListener('touchstart', _handleModalClick, false);
			});

		}

	};

	// Return public methods
	return {
		init: init
	};

})(window, document);<|endoftext|>


<commit_before>/* global Log, Class, Loader, Class , MM */
/* exported Module */

/* Magic Mirror
 * Module Blueprint.
 *
 * By Michael Teeuw http://michaelteeuw.nl
 * MIT Licensed.
 */

var Module = Class.extend({

	/*********************************************************
	 * All methods (and properties) below can be subclassed. *
	 *********************************************************/

	// Set the minimum MagicMirror module version for this module.
	requiresVersion: "2.0.0",

	// Module config defaults.
	defaults: {},

	// Timer reference used for showHide animation callbacks.
	showHideTimer: null,

	// Array to store lockStrings. These strings are used to lock
	// visibility when hiding and showing module.
	lockStrings: [],

	// Storage of the nunjuck Environment,
	// This should not be referenced directly.
	// Use the nunjucksEnvironment() to get it.
	_nunjucksEnvironment: null,

	/* init()
	 * Is called when the module is instantiated.
	 */
	init: function () {
		//Log.log(this.defaults);
	},

	/* start()
	 * Is called when the module is started.
	 */
	start: function () {
		Log.info("Starting module: " + this.name);
	},

	/* getScripts()
	 * Returns a list of scripts the module requires to be loaded.
	 *
	 * return Array<String> - An array with filenames.
	 */
	getScripts: function () {
		return [];
	},

	/* getStyles()
	 * Returns a list of stylesheets the module requires to be loaded.
	 *
	 * return Array<String> - An array with filenames.
	 */
	getStyles: function () {
		return [];
	},

	/* getTranslations()
	 * Returns a map of translation files the module requires to be loaded.
	 *
	 * return Map<String, String> - A map with langKeys and filenames.
	 */
	getTranslations: function () {
		return false;
	},

	/* getDom()
	 * This method generates the dom which needs to be displayed. This method is called by the Magic Mirror core.
	 * This method can to be subclassed if the module wants to display info on the mirror.
	 * Alternatively, the getTemplete method could be subclassed.
	 *
	 * return domobject - The dom to display.
	 */
	getDom: function () {
		var div = document.createElement("div");
		var template = this.getTemplate();
		var templateData = this.getTemplateData();

		// Check to see if we need to render a template string or a file.
		if (/^.*(\.html)$/.test(template)) {
			// the template is a filename
			this.nunjucksEnvironment().render(template, templateData, function (err, res) {
				if (err) {
					Log.error(err)
				}

				// The inner content of the div will be set after the template is received.
				// This isn't the most optimal way, but since it's near instant
				// it probably won't be an issue.
				// If it gives problems, we can always add a way to pre fetch the templates.
				// Let's not over optimise this ... KISS! :)
				div.innerHTML = res;
			});
		} else {
			// the template is a template string.
			div.innerHTML = this.nunjucksEnvironment().renderString(template, templateData);
		}

		return div;
	},

	/* getHeader()
	 * This method generates the header string which needs to be displayed if a user has a header configured for this module.
	 * This method is called by the Magic Mirror core, but only if the user has configured a default header for the module.
	 * This method needs to be subclassed if the module wants to display modified headers on the mirror.
	 *
	 * return string - The header to display above the header.
	 */
	getHeader: function () {
		return this.data.header;
	},

	/* getTemplate()
	 * This method returns the template for the module which is used by the default getDom implementation.
	 * This method needs to be subclassed if the module wants to use a tempate.
	 * It can either return a template sting, or a template filename.
	 * If the string ends with '.html' it's considered a file from within the module's folder.
	 *
	 * return string - The template string of filename.
	 */
	getTemplate: function () {
		return "
" + this.name + "

" + this.identifier + "
";
	},

	/* getTemplateData()
	 * This method returns the data to be used in the template.
	 * This method needs to be subclassed if the module wants to use a custom data.
	 *
	 * return Object
	 */
	getTemplateData: function () {
		return {}
	},

	/* notificationReceived(notification, payload, sender)
	 * This method is called when a notification arrives.
	 * This method is called by the Magic Mirror core.
	 *
	 * argument notification string - The identifier of the notification.
	 * argument payload mixed - The payload of the notification.
	 * argument sender Module - The module that sent the notification.
	 */
	notificationReceived: function (notification, payload, sender) {
		if (sender) {
			Log.log(this.name + " received a module notification: " + notification + " from sender: " + sender.name);
		} else {
			Log.log(this.name + " received a system notification: " + notification);
		}
	},

	/** nunjucksEnvironment()
	 * Returns the nunjucks environment for the current module.
	 * The environment is checked in the _nunjucksEnvironment instance variable.

	 * @returns Nunjucks Environment
	 */
	nunjucksEnvironment: function() {
		if (this._nunjucksEnvironment != null) {
			return this._nunjucksEnvironment;
		}

		var self = this;

		this._nunjucksEnvironment = new nunjucks.Environment(new nunjucks.WebLoader(this.file(""), {async: true}));
		this._nunjucksEnvironment.addFilter("translate", function(str) {
			return self.translate(str)
		});

		return this._nunjucksEnvironment;
	},

	/* socketNotificationReceived(notification, payload)
	 * This method is called when a socket notification arrives.
	 *
	 * argument notification string - The identifier of the notification.
	 * argument payload mixed - The payload of the notification.
	 */
	socketNotificationReceived: function (notification, payload) {
		Log.log(this.name + " received a socket notification: " + notification + " - Payload: " + payload);
	},

	/* suspend()
	 * This method is called when a module is hidden.
	 */
	suspend: function () {
		Log.log(this.name + " is suspended.");
	},

	/* resume()
	 * This method is called when a module is shown.
	 */
	resume: function () {
		Log.log(this.name + " is resumed.");
	},

	/*********************************************
	 * The methods below don"t need subclassing. *
	 *********************************************/

	/* setData(data)
	 * Set the module data.
	 *
	 * argument data obejct - Module data.
	 */
	setData: function (data) {
		this.data = data;
		this.name = data.name;
		this.identifier = data.identifier;
		this.hidden = false;

		this.setConfig(data.config);
	},

	/* setConfig(config)
	 * Set the module config and combine it with the module defaults.
	 *
	 * argument config obejct - Module config.
	 */
	setConfig: function (config) {
		this.config = Object.assign({}, this.defaults, config);
	},

	/* socket()
	 * Returns a socket object. If it doesn"t exist, it"s created.
	 * It also registers the notification callback.
	 */
	socket: function () {
		if (typeof this._socket === "undefined") {
			this._socket = this._socket = new MMSocket(this.name);
		}

		var self = this;
		this._socket.setNotificationCallback(function (notification, payload) {
			self.socketNotificationReceived(notification, payload);
		});

		return this._socket;
	},

	/* file(file)
	 * Retrieve the path to a module file.
	 *
	 * argument file string - Filename.
	 *
	 * return string - File path.
	 */
	file: function (file) {
		return (this.data.path + "/" + file).replace("//", "/");
	},

	/* loadStyles()
	 * Load all required stylesheets by requesting the MM object to load the files.
	 *
	 * argument callback function - Function called when done.
	 */
	loadStyles: function (callback) {
		this.loadDependencies("getStyles", callback);
	},

	/* loadScripts()
	 * Load all required scripts by requesting the MM object to load the files.
	 *
	 * argument callback function - Function called when done.
	 */
	loadScripts: function (callback) {
		this.loadDependencies("getScripts", callback);
	},

	/* loadDependencies(funcName, callback)
	 * Helper method to load all dependencies.
	 *
	 * argument funcName string - Function name to call to get scripts or styles.
	 * argument callback function - Function called when done.
	 */
	loadDependencies: function (funcName, callback) {
		var self = this;
		var dependencies = this[funcName]();

		var loadNextDependency = function () {
			if (dependencies.length > 0) {
				var nextDependency = dependencies[0];
				Loader.loadFile(nextDependency, self, function () {
					dependencies = dependencies.slice(1);
					loadNextDependency();
				});
			} else {
				callback();
			}
		};

		loadNextDependency();
	},

	/* loadScripts()
	 * Load all required scripts by requesting the MM object to load the files.
	 *
	 * argument callback function - Function called when done.
	 */
	loadTranslations: function (callback) {
		var self = this;
		var translations = this.getTranslations();
		var lang = config.language.toLowerCase();

		// The variable `first` will contain the first
		// defined translation after the following line.
		for (var first in translations) { break; }

		if (translations) {
			var translationFile = translations[lang] || undefined;
			var translationsFallbackFile = translations[first];

			// If a translation file is set, load it and then also load the fallback translation file.
			// Otherwise only load the fallback translation file.
			if (translationFile !== undefined && translationFile !== translationsFallbackFile) {
				Translator.load(self, translationFile, false, function () {
					Translator.load(self, translationsFallbackFile, true, callback);
				});
			} else {
				Translator.load(self, translationsFallbackFile, true, callback);
			}
		} else {
			callback();
		}
	},

	/* translate(key, defaultValueOrVariables, defaultValue)
	 * Request the translation for a given key with optional variables and default value.
	 *
	 * argument key string - The key of the string to translate
     * argument defaultValueOrVariables string/object - The default value or variables for translating. (Optional)
     * argument defaultValue string - The default value with variables. (Optional)
	 */
	translate: function (key, defaultValueOrVariables, defaultValue) {
		if(typeof defaultValueOrVariables === "object") {
			return Translator.translate(this, key, defaultValueOrVariables) || defaultValue || "";
		}
		return Translator.translate(this, key) || defaultValueOrVariables || "";
	},

	/* updateDom(speed)
	 * Request an (animated) update of the module.
	 *
	 * argument speed Number - The speed of the animation. (Optional)
	 */
	updateDom: function (speed) {
		MM.updateDom(this, speed);
	},

	/* sendNotification(notification, payload)
	 * Send a notification to all modules.
	 *
	 * argument notification string - The identifier of the notification.
	 * argument payload mixed - The payload of the notification.
	 */
	sendNotification: function (notification, payload) {
		MM.sendNotification(notification, payload, this);
	},

	/* sendSocketNotification(notification, payload)
	 * Send a socket notification to the node helper.
	 *
	 * argument notification string - The identifier of the notification.
	 * argument payload mixed - The payload of the notification.
	 */
	sendSocketNotification: function (notification, payload) {
		this.socket().sendNotification(notification, payload);
	},

	/* hideModule(module, speed, callback)
	 * Hide this module.
	 *
	 * argument speed Number - The speed of the hide animation.
	 * argument callback function - Called when the animation is done.
	 * argument options object - Optional settings for the hide method.
	 */
	hide: function (speed, callback, options) {
		if (typeof callback === "object") {
			options = callback;
			callback = function () { };
		}

		callback = callback || function () { };
		options = options || {};

		var self = this;
		MM.hideModule(self, speed, function () {
			self.suspend();
			callback();
		}, options);
	},

	/* showModule(module, speed, callback)
	 * Show this module.
	 *
	 * argument speed Number - The speed of the show animation.
	 * argument callback function - Called when the animation is done.
	 * argument options object - Optional settings for the hide method.
	 */
	show: function (speed, callback, options) {
		if (typeof callback === "object") {
			options = callback;
			callback = function () { };
		}

		callback = callback || function () { };
		options = options || {};

		this.resume();
		MM.showModule(this, speed, callback, options);
	}
});

Module.definitions = {};

Module.create = function (name) {

	// Make sure module definition is available.
	if (!Module.definitions[name]) {
		return;
	}

	var moduleDefinition = Module.definitions[name];
	var clonedDefinition = cloneObject(moduleDefinition);

	// Note that we clone the definition. Otherwise the objects are shared, which gives problems.
	var ModuleClass = Module.extend(clonedDefinition);

	return new ModuleClass();

};

/* cmpVersions(a,b)
* Compare two symantic version numbers and return the difference.
*
* argument a string - Version number a.
* argument a string - Version number b.
*/
function cmpVersions(a, b) {
	var i, diff;
	var regExStrip0 = /(\.0+)+$/;
	var segmentsA = a.replace(regExStrip0, "").split(".");
	var segmentsB = b.replace(regExStrip0, "").split(".");
	var l = Math.min(segmentsA.length, segmentsB.length);

	for (i = 0; i < l; i++) {
		diff = parseInt(segmentsA[i], 10) - parseInt(segmentsB[i], 10);
		if (diff) {
			return diff;
		}
	}
	return segmentsA.length - segmentsB.length;
}

Module.register = function (name, moduleDefinition) {

	if (moduleDefinition.requiresVersion) {
		Log.log("Check MagicMirror version for module '" + name + "' - Minimum version:  " + moduleDefinition.requiresVersion + " - Current version: " + version);
		if (cmpVersions(version, moduleDefinition.requiresVersion) >= 0) {
			Log.log("Version is ok!");
		} else {
			Log.log("Version is incorrect. Skip module: '" + name + "'");
			return;
		}
	}
	Log.log("Module registered: " + name);
	Module.definitions[name] = moduleDefinition;
};

if (typeof exports != "undefined") { // For testing purpose only
	// A good a idea move the function cmpversions a helper file.
	// It's used into other side.
	exports._test = {
		cmpVersions: cmpVersions
	}
}
<commit_msg>Remove trailing spaces.<commit_after>/* global Log, Class, Loader, Class , MM */
/* exported Module */

/* Magic Mirror
 * Module Blueprint.
 *
 * By Michael Teeuw http://michaelteeuw.nl
 * MIT Licensed.
 */

var Module = Class.extend({

	/*********************************************************
	 * All methods (and properties) below can be subclassed. *
	 *********************************************************/

	// Set the minimum MagicMirror module version for this module.
	requiresVersion: "2.0.0",

	// Module config defaults.
	defaults: {},

	// Timer reference used for showHide animation callbacks.
	showHideTimer: null,

	// Array to store lockStrings. These strings are used to lock
	// visibility when hiding and showing module.
	lockStrings: [],

	// Storage of the nunjuck Environment,
	// This should not be referenced directly.
	// Use the nunjucksEnvironment() to get it.
	_nunjucksEnvironment: null,

	/* init()
	 * Is called when the module is instantiated.
	 */
	init: function () {
		//Log.log(this.defaults);
	},

	/* start()
	 * Is called when the module is started.
	 */
	start: function () {
		Log.info("Starting module: " + this.name);
	},

	/* getScripts()
	 * Returns a list of scripts the module requires to be loaded.
	 *
	 * return Array<String> - An array with filenames.
	 */
	getScripts: function () {
		return [];
	},

	/* getStyles()
	 * Returns a list of stylesheets the module requires to be loaded.
	 *
	 * return Array<String> - An array with filenames.
	 */
	getStyles: function () {
		return [];
	},

	/* getTranslations()
	 * Returns a map of translation files the module requires to be loaded.
	 *
	 * return Map<String, String> - A map with langKeys and filenames.
	 */
	getTranslations: function () {
		return false;
	},

	/* getDom()
	 * This method generates the dom which needs to be displayed. This method is called by the Magic Mirror core.
	 * This method can to be subclassed if the module wants to display info on the mirror.
	 * Alternatively, the getTemplete method could be subclassed.
	 *
	 * return domobject - The dom to display.
	 */
	getDom: function () {
		var div = document.createElement("div");
		var template = this.getTemplate();
		var templateData = this.getTemplateData();

		// Check to see if we need to render a template string or a file.
		if (/^.*(\.html)$/.test(template)) {
			// the template is a filename
			this.nunjucksEnvironment().render(template, templateData, function (err, res) {
				if (err) {
					Log.error(err)
				}

				// The inner content of the div will be set after the template is received.
				// This isn't the most optimal way, but since it's near instant
				// it probably won't be an issue.
				// If it gives problems, we can always add a way to pre fetch the templates.
				// Let's not over optimise this ... KISS! :)
				div.innerHTML = res;
			});
		} else {
			// the template is a template string.
			div.innerHTML = this.nunjucksEnvironment().renderString(template, templateData);
		}

		return div;
	},

	/* getHeader()
	 * This method generates the header string which needs to be displayed if a user has a header configured for this module.
	 * This method is called by the Magic Mirror core, but only if the user has configured a default header for the module.
	 * This method needs to be subclassed if the module wants to display modified headers on the mirror.
	 *
	 * return string - The header to display above the header.
	 */
	getHeader: function () {
		return this.data.header;
	},

	/* getTemplate()
	 * This method returns the template for the module which is used by the default getDom implementation.
	 * This method needs to be subclassed if the module wants to use a tempate.
	 * It can either return a template sting, or a template filename.
	 * If the string ends with '.html' it's considered a file from within the module's folder.
	 *
	 * return string - The template string of filename.
	 */
	getTemplate: function () {
		return "
" + this.name + "

" + this.identifier + "
";
	},

	/* getTemplateData()
	 * This method returns the data to be used in the template.
	 * This method needs to be subclassed if the module wants to use a custom data.
	 *
	 * return Object
	 */
	getTemplateData: function () {
		return {}
	},

	/* notificationReceived(notification, payload, sender)
	 * This method is called when a notification arrives.
	 * This method is called by the Magic Mirror core.
	 *
	 * argument notification string - The identifier of the notification.
	 * argument payload mixed - The payload of the notification.
	 * argument sender Module - The module that sent the notification.
	 */
	notificationReceived: function (notification, payload, sender) {
		if (sender) {
			Log.log(this.name + " received a module notification: " + notification + " from sender: " + sender.name);
		} else {
			Log.log(this.name + " received a system notification: " + notification);
		}
	},

	/** nunjucksEnvironment()
	 * Returns the nunjucks environment for the current module.
	 * The environment is checked in the _nunjucksEnvironment instance variable.

	 * @returns Nunjucks Environment
	 */
	nunjucksEnvironment: function() {
		if (this._nunjucksEnvironment != null) {
			return this._nunjucksEnvironment;
		}

		var self = this;

		this._nunjucksEnvironment = new nunjucks.Environment(new nunjucks.WebLoader(this.file(""), {async: true}));
		this._nunjucksEnvironment.addFilter("translate", function(str) {
			return self.translate(str)
		});

		return this._nunjucksEnvironment;
	},

	/* socketNotificationReceived(notification, payload)
	 * This method is called when a socket notification arrives.
	 *
	 * argument notification string - The identifier of the notification.
	 * argument payload mixed - The payload of the notification.
	 */
	socketNotificationReceived: function (notification, payload) {
		Log.log(this.name + " received a socket notification: " + notification + " - Payload: " + payload);
	},

	/* suspend()
	 * This method is called when a module is hidden.
	 */
	suspend: function () {
		Log.log(this.name + " is suspended.");
	},

	/* resume()
	 * This method is called when a module is shown.
	 */
	resume: function () {
		Log.log(this.name + " is resumed.");
	},

	/*********************************************
	 * The methods below don"t need subclassing. *
	 *********************************************/

	/* setData(data)
	 * Set the module data.
	 *
	 * argument data obejct - Module data.
	 */
	setData: function (data) {
		this.data = data;
		this.name = data.name;
		this.identifier = data.identifier;
		this.hidden = false;

		this.setConfig(data.config);
	},

	/* setConfig(config)
	 * Set the module config and combine it with the module defaults.
	 *
	 * argument config obejct - Module config.
	 */
	setConfig: function (config) {
		this.config = Object.assign({}, this.defaults, config);
	},

	/* socket()
	 * Returns a socket object. If it doesn"t exist, it"s created.
	 * It also registers the notification callback.
	 */
	socket: function () {
		if (typeof this._socket === "undefined") {
			this._socket = this._socket = new MMSocket(this.name);
		}

		var self = this;
		this._socket.setNotificationCallback(function (notification, payload) {
			self.socketNotificationReceived(notification, payload);
		});

		return this._socket;
	},

	/* file(file)
	 * Retrieve the path to a module file.
	 *
	 * argument file string - Filename.
	 *
	 * return string - File path.
	 */
	file: function (file) {
		return (this.data.path + "/" + file).replace("//", "/");
	},

	/* loadStyles()
	 * Load all required stylesheets by requesting the MM object to load the files.
	 *
	 * argument callback function - Function called when done.
	 */
	loadStyles: function (callback) {
		this.loadDependencies("getStyles", callback);
	},

	/* loadScripts()
	 * Load all required scripts by requesting the MM object to load the files.
	 *
	 * argument callback function - Function called when done.
	 */
	loadScripts: function (callback) {
		this.loadDependencies("getScripts", callback);
	},

	/* loadDependencies(funcName, callback)
	 * Helper method to load all dependencies.
	 *
	 * argument funcName string - Function name to call to get scripts or styles.
	 * argument callback function - Function called when done.
	 */
	loadDependencies: function (funcName, callback) {
		var self = this;
		var dependencies = this[funcName]();

		var loadNextDependency = function () {
			if (dependencies.length > 0) {
				var nextDependency = dependencies[0];
				Loader.loadFile(nextDependency, self, function () {
					dependencies = dependencies.slice(1);
					loadNextDependency();
				});
			} else {
				callback();
			}
		};

		loadNextDependency();
	},

	/* loadScripts()
	 * Load all required scripts by requesting the MM object to load the files.
	 *
	 * argument callback function - Function called when done.
	 */
	loadTranslations: function (callback) {
		var self = this;
		var translations = this.getTranslations();
		var lang = config.language.toLowerCase();

		// The variable `first` will contain the first
		// defined translation after the following line.
		for (var first in translations) { break; }

		if (translations) {
			var translationFile = translations[lang] || undefined;
			var translationsFallbackFile = translations[first];

			// If a translation file is set, load it and then also load the fallback translation file.
			// Otherwise only load the fallback translation file.
			if (translationFile !== undefined && translationFile !== translationsFallbackFile) {
				Translator.load(self, translationFile, false, function () {
					Translator.load(self, translationsFallbackFile, true, callback);
				});
			} else {
				Translator.load(self, translationsFallbackFile, true, callback);
			}
		} else {
			callback();
		}
	},

	/* translate(key, defaultValueOrVariables, defaultValue)
	 * Request the translation for a given key with optional variables and default value.
	 *
	 * argument key string - The key of the string to translate
     * argument defaultValueOrVariables string/object - The default value or variables for translating. (Optional)
     * argument defaultValue string - The default value with variables. (Optional)
	 */
	translate: function (key, defaultValueOrVariables, defaultValue) {
		if(typeof defaultValueOrVariables === "object") {
			return Translator.translate(this, key, defaultValueOrVariables) || defaultValue || "";
		}
		return Translator.translate(this, key) || defaultValueOrVariables || "";
	},

	/* updateDom(speed)
	 * Request an (animated) update of the module.
	 *
	 * argument speed Number - The speed of the animation. (Optional)
	 */
	updateDom: function (speed) {
		MM.updateDom(this, speed);
	},

	/* sendNotification(notification, payload)
	 * Send a notification to all modules.
	 *
	 * argument notification string - The identifier of the notification.
	 * argument payload mixed - The payload of the notification.
	 */
	sendNotification: function (notification, payload) {
		MM.sendNotification(notification, payload, this);
	},

	/* sendSocketNotification(notification, payload)
	 * Send a socket notification to the node helper.
	 *
	 * argument notification string - The identifier of the notification.
	 * argument payload mixed - The payload of the notification.
	 */
	sendSocketNotification: function (notification, payload) {
		this.socket().sendNotification(notification, payload);
	},

	/* hideModule(module, speed, callback)
	 * Hide this module.
	 *
	 * argument speed Number - The speed of the hide animation.
	 * argument callback function - Called when the animation is done.
	 * argument options object - Optional settings for the hide method.
	 */
	hide: function (speed, callback, options) {
		if (typeof callback === "object") {
			options = callback;
			callback = function () { };
		}

		callback = callback || function () { };
		options = options || {};

		var self = this;
		MM.hideModule(self, speed, function () {
			self.suspend();
			callback();
		}, options);
	},

	/* showModule(module, speed, callback)
	 * Show this module.
	 *
	 * argument speed Number - The speed of the show animation.
	 * argument callback function - Called when the animation is done.
	 * argument options object - Optional settings for the hide method.
	 */
	show: function (speed, callback, options) {
		if (typeof callback === "object") {
			options = callback;
			callback = function () { };
		}

		callback = callback || function () { };
		options = options || {};

		this.resume();
		MM.showModule(this, speed, callback, options);
	}
});

Module.definitions = {};

Module.create = function (name) {

	// Make sure module definition is available.
	if (!Module.definitions[name]) {
		return;
	}

	var moduleDefinition = Module.definitions[name];
	var clonedDefinition = cloneObject(moduleDefinition);

	// Note that we clone the definition. Otherwise the objects are shared, which gives problems.
	var ModuleClass = Module.extend(clonedDefinition);

	return new ModuleClass();

};

/* cmpVersions(a,b)
* Compare two symantic version numbers and return the difference.
*
* argument a string - Version number a.
* argument a string - Version number b.
*/
function cmpVersions(a, b) {
	var i, diff;
	var regExStrip0 = /(\.0+)+$/;
	var segmentsA = a.replace(regExStrip0, "").split(".");
	var segmentsB = b.replace(regExStrip0, "").split(".");
	var l = Math.min(segmentsA.length, segmentsB.length);

	for (i = 0; i < l; i++) {
		diff = parseInt(segmentsA[i], 10) - parseInt(segmentsB[i], 10);
		if (diff) {
			return diff;
		}
	}
	return segmentsA.length - segmentsB.length;
}

Module.register = function (name, moduleDefinition) {

	if (moduleDefinition.requiresVersion) {
		Log.log("Check MagicMirror version for module '" + name + "' - Minimum version:  " + moduleDefinition.requiresVersion + " - Current version: " + version);
		if (cmpVersions(version, moduleDefinition.requiresVersion) >= 0) {
			Log.log("Version is ok!");
		} else {
			Log.log("Version is incorrect. Skip module: '" + name + "'");
			return;
		}
	}
	Log.log("Module registered: " + name);
	Module.definitions[name] = moduleDefinition;
};

if (typeof exports != "undefined") { // For testing purpose only
	// A good a idea move the function cmpversions a helper file.
	// It's used into other side.
	exports._test = {
		cmpVersions: cmpVersions
	}
}
<|endoftext|>


<commit_before>var Office = {

  eventApi: 'https://online.ntnu.no/service_static/office_status',
  lightApi: 'http://draug.online.ntnu.no/lys.txt',
  titleError: 'Oops',
  titleOpen: 'Åpent',
  titleClosed: 'Lukket',
  titleMeeting: 'Møte',
  titleWaffles: 'Vafler',
  msgError: 'Klarte ikke hente kontorstatus',
  msgOpen: 'Gratis kaffe og te til alle!',
  msgClosed: 'Finn et komitemedlem for å åpne opp.',
  msgUntitledMeeting: 'Kontoret er opptatt', // titled meetings and waffles get names from calendar entries
  lightLimit: 860,

  debug: 0,

  get: function(callback) {
    if (callback == undefined) {
      console.log('ERROR: Callback is required. In the callback you should insert the results into the DOM.');
      return;
    }

    var self = this;
    this.getEventData( function(status, title, message) {
      if (status == 'open') {
        self.getLightData(callback);
      }
      else {
        // status: "closed"
        // title: "Lukket"
        // message: "Finn et komitemedlem for å åpne opp"
        callback(status, title, message);
      }
    });
  },

  getEventData: function(callback) {
    if (callback == undefined) {
      console.log('ERROR: Callback is required. In the callback you should insert the results into the DOM.');
      return;
    }

    // Receives info on current event from Onlines servers (without comments)
    // 1              // 0=closed, 1=meeting, 2=waffles, 3=error
    // Møte: dotKom   // event title or 'No title'-meeting or nothing
    var self = this;
    Ajaxer.getPlainText({
      url: self.eventApi,
      success: function(data) {
        var status = data.split('\n',2)[0];
        var title = data.split('\n',2)[1];

        // empty meeting title?
        if (title == '' && status == 1)
          title = self.msgUntitledMeeting;

        // set the status from fetched data
        switch(Number(status)) {
          case 0: callback('open', self.titleOpen, self.msgOpen); break;
          case 1: callback('meeting', self.titleMeeting, title); break;
          case 2: callback('waffle', self.titleWaffles, title); break;
          default: callback('error', self.titleError, 'eventStatus was "'+status+'"');
        }
      },
      error: function(jqXHR, text, err) {
        if (self.debug) console.log('ERROR: Failed to get event data.');
        callback('error', self.titleError, self.msgError);
      },
    });
  },

  getLightData: function(callback) {
    if (callback == undefined) {
      console.log('ERROR: Callback is required. In the callback you should insert the results into the DOM.');
      return;
    }

    // Receives current light intensity from the office: OFF 0-800-1023 ON
    var self = this;
    Ajaxer.getPlainText({
      url: self.lightApi,
      success: function(data) {
        if (data > self.lightLimit) {
          callback('closed', self.titleClosed, self.msgClosed);
        }
        else {
          callback('open', self.titleOpen, self.msgOpen);
        }
      },
      error: function(jqXHR, err) {
        if (self.debug) console.log('ERROR: Failed to get light data.');
        callback('error', self.titleError, self.msgError);
      },
    });
  },

}
<commit_msg>office: fixed an error message displaying derpily<commit_after>var Office = {

  eventApi: 'https://online.ntnu.no/service_static/office_status',
  lightApi: 'http://draug.online.ntnu.no/lys.txt',
  titleError: 'Oops',
  titleOpen: 'Åpent',
  titleClosed: 'Lukket',
  titleMeeting: 'Møte',
  titleWaffles: 'Vafler',
  msgError: 'Klarte ikke hente kontorstatus',
  msgOpen: 'Gratis kaffe og te til alle!',
  msgClosed: 'Finn et komitemedlem for å åpne opp.',
  msgUntitledMeeting: 'Kontoret er opptatt', // titled meetings and waffles get names from calendar entries
  lightLimit: 860,

  debug: 0,

  get: function(callback) {
    if (callback == undefined) {
      console.log('ERROR: Callback is required. In the callback you should insert the results into the DOM.');
      return;
    }

    var self = this;
    this.getEventData( function(status, title, message) {
      if (status == 'open') {
        self.getLightData(callback);
      }
      else {
        // status: "closed"
        // title: "Lukket"
        // message: "Finn et komitemedlem for å åpne opp"
        callback(status, title, message);
      }
    });
  },

  getEventData: function(callback) {
    if (callback == undefined) {
      console.log('ERROR: Callback is required. In the callback you should insert the results into the DOM.');
      return;
    }

    // Receives info on current event from Onlines servers (without comments)
    // 1              // 0=closed, 1=meeting, 2=waffles, 3=error
    // Møte: dotKom   // event title or 'No title'-meeting or nothing
    var self = this;
    Ajaxer.getPlainText({
      url: self.eventApi,
      success: function(data) {
        var status = data.split('\n',2)[0];
        var title = data.split('\n',2)[1];

        // empty meeting title?
        if (title == '' && status == 1)
          title = self.msgUntitledMeeting;

        // set the status from fetched data
        switch(Number(status)) {
          case 0: callback('open', self.titleOpen, self.msgOpen); break;
          case 1: callback('meeting', self.titleMeeting, title); break;
          case 2: callback('waffle', self.titleWaffles, title); break;
          default: callback('error', self.titleError, self.msgError);
        }
      },
      error: function(jqXHR, text, err) {
        if (self.debug) console.log('ERROR: Failed to get event data.');
        callback('error', self.titleError, self.msgError);
      },
    });
  },

  getLightData: function(callback) {
    if (callback == undefined) {
      console.log('ERROR: Callback is required. In the callback you should insert the results into the DOM.');
      return;
    }

    // Receives current light intensity from the office: OFF 0-800-1023 ON
    var self = this;
    Ajaxer.getPlainText({
      url: self.lightApi,
      success: function(data) {
        if (data > self.lightLimit) {
          callback('closed', self.titleClosed, self.msgClosed);
        }
        else {
          callback('open', self.titleOpen, self.msgOpen);
        }
      },
      error: function(jqXHR, err) {
        if (self.debug) console.log('ERROR: Failed to get light data.');
        callback('error', self.titleError, self.msgError);
      },
    });
  },

}
<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react';
import { inject } from 'mobx-react';
import { observable, computed } from 'mobx';
import { withJob } from 'react-jobs';
import { Link } from 'react-router-dom';
import Helmet from 'react-helmet';
import Segment from 'components/segment';
import Button from 'components/button';
import { autobind } from 'core-decorators';

const LoadingComponent = () => (
  <Segment>

Loading list of planets....

  </Segment>
);

@inject('planets')
@withJob({
  work: ({ match, planets }) => planets.fetchAll({ page: Number(match.params.page || 1) }),
  shouldWorkAgain: (prev, next) => prev.match.params.page !== next.match.params.page,
  LoadingComponent,
})
export default class Planets extends Component {

  static propTypes = {
    jobResult: PropTypes.shape({
      results: PropTypes.array,
      count: PropTypes.number,
      previous: PropTypes.string,
      next: PropTypes.string,
    }),
    history: PropTypes.shape({
      push: PropTypes.func,
    }),
    match: PropTypes.shape({
      params: PropTypes.shape({
        page: PropTypes.string,
      }),
    }),
  };

  /**
   * Fired when pagination buttons are clicked.
   * @param {Event} Click-event.
   * @return {void}
   */
  @autobind onClickPage(e) {
    // Prevent default click behaviour
    e.preventDefault();

    // Extract wanted url from node's dataset.
    const { url } = e.currentTarget.dataset;
    const pagestr = url.match(/page=(\d+)/);
    const page = parseInt(pagestr && pagestr[1], 10) || 1;

    // this.context.history.push()
    const { match, history } = this.props;
    history.push(match.path.replace(':page', page));
  }

  /**
   * @var {observableObject} Promise that contains fetched data.
   */
  @observable
  planets = null;

  /**
   * @var {observableObject} Current page
   */
  @computed
  get page() {
    return Number(this.props.match.params.page || 1);
  }

  /**
   * @var {Number} Calculate every time the current page changes.
   */
  @computed
  get from() {
    return (this.page * 10) - 9;
  }

  /**
   * @var {Number} Calculate every time the current page changes.
   */
  @computed
  get to() {
    return this.page * 10;
  }

  /**
   * Render method
   * @return {React.Component}
   */
  render() {
    const { results, count, previous, next } = this.props.jobResult;
    return (

        <Helmet title="Planets" />

        <Segment>

Showing {this.from}-{Math.min(this.to, count)} of {count} planets available.

              {results.map(({ name, url }) => (
                <li key={`planet_${name}`}>
                  <Link to={`/planets/detail/${url.match(/(\d+)\/$/)[1]}`}>{name}</Link>

              ))}

              <Button disabled={!previous} data-url={previous} onClick={this.onClickPage}>
                Previous
              </Button>
              <Button disabled={!next} data-url={next} onClick={this.onClickPage}>
                Next
              </Button>

        </Segment>

    );
  }
}
<commit_msg>Cleanup<commit_after>import React, { Component, PropTypes } from 'react';
import { inject } from 'mobx-react';
import { computed } from 'mobx';
import { withJob } from 'react-jobs';
import { Link } from 'react-router-dom';
import Helmet from 'react-helmet';
import Segment from 'components/segment';
import Button from 'components/button';
import { autobind } from 'core-decorators';

const LoadingComponent = () => (
  <Segment>

Loading list of planets....

  </Segment>
);

@inject('planets')
@withJob({
  work: ({ match, planets }) => planets.fetchAll({ page: Number(match.params.page || 1) }),
  shouldWorkAgain: (prev, next) => prev.match.params.page !== next.match.params.page,
  LoadingComponent,
})
export default class Planets extends Component {

  static propTypes = {
    jobResult: PropTypes.shape({
      results: PropTypes.array,
      count: PropTypes.number,
      previous: PropTypes.string,
      next: PropTypes.string,
    }),
    history: PropTypes.shape({
      push: PropTypes.func,
    }),
    match: PropTypes.shape({
      params: PropTypes.shape({
        page: PropTypes.string,
      }),
    }),
  };

  /**
   * Fired when pagination buttons are clicked.
   * @param {Event} Click-event.
   * @return {void}
   */
  @autobind
  onClickPage(e) {
    // Prevent default click behaviour
    e.preventDefault();

    // Extract wanted url from node's dataset.
    const { url } = e.currentTarget.dataset;
    const pagestr = url.match(/page=(\d+)/);
    const page = parseInt(pagestr && pagestr[1], 10) || 1;

    // this.context.history.push()
    const { match, history } = this.props;
    history.push(match.path.replace(':page', page));
  }

  /**
   * @var {observableObject} Current page
   */
  @computed
  get page() {
    return Number(this.props.match.params.page || 1);
  }

  /**
   * @var {Number} Calculate every time the current page changes.
   */
  @computed
  get from() {
    return (this.page * 10) - 9;
  }

  /**
   * @var {Number} Calculate every time the current page changes.
   */
  @computed
  get to() {
    return Math.min(this.page * 10, this.props.jobResult.count);
  }

  /**
   * Render method
   * @return {React.Component}
   */
  render() {
    const { results, count, previous, next } = this.props.jobResult;
    return (

        <Helmet title="Planets" />

        <Segment>

Showing {this.from}-{this.to} of {count} planets available.

              {results.map(({ name, url }) => (
                <li key={`planet_${name}`}>
                  <Link to={`/planets/detail/${url.match(/(\d+)\/$/)[1]}`}>{name}</Link>

              ))}

              <Button disabled={!previous} data-url={previous} onClick={this.onClickPage}>
                Previous
              </Button>
              <Button disabled={!next} data-url={next} onClick={this.onClickPage}>
                Next
              </Button>

        </Segment>

    );
  }
}
<|endoftext|>


<commit_before>'use strict';

const sendGrid = require('sendgrid');

function sendEmail(number, carrier, interactions){
  sendGrid.send({
    to: number + carrier,
    from: 'radcliffe.tracey@gmail.com',
    subject: 'Drug Interactions',
    text: 'This is where the interactions will go' + interactions
  }, function(err, json){
    if(err) return console.log(err);
    console.log(json);
  });
}

sendEmail('3602694800', '@tmomail.net', 'why yes there are some. wouldnt you like to know');
<commit_msg>working and semding email and text<commit_after>'use strict';
let helper = require('sendgrid').mail,
  from_email = new helper.Email('radcliffe.tracey@gmail.com'),
  to_email = new helper.Email('2069312759@pm.sprint.com'),
  subject = 'hello world',
  content = new helper.Content('text/plain', 'AHHHHHHH'),
  mail = new helper.Mail(from_email, subject, to_email, content);

let sg = require('sendgrid')(process.env.SENDGRID_API_KEY);
var request = sg.emptyRequest({
  method: 'POST',
  path: '/v3/mail/send',
  body: mail.toJSON()
});

sg.API(request, function(error, response) {
  console.log(response.statusCode);
  console.log(response.body);
  console.log(response.headers);
});
<|endoftext|>


<commit_before>var config = require('config');
var log = require('./client/log')('geocode');
var get = require('./client/request').get;

var southWest = [-123.099060058594, 36.745486924699];
var northEast = [-121.192932128906, 38.182068998322];

/**********tismart **********************/
var dev_amigo_token = "A:m8SOB7KwYWuuWAeYEHHjBf7U9VIZFrMuH2LLjS";

/**
 * Geocode
 */

module.exports = geocode;
module.exports.reverse = reverse;
module.exports.suggest = suggest;
module.exports.suggestAmigo = suggestAmigo;
module.exports.reverseAmigo = reverseAmigo;

/**
 * Geocode
 */

function geocode(address, callback) {
  log('--> geocoding %s', address);
  get('/geocode/' + address, function(err, res) {
    if (err) {
      log('<-- geocoding error %s', err);
      callback(err, res);
    } else {
      log('<-- geocoding complete %j', res.body);
      callback(null, res.body);
    }
  });
}

/**
 * Reverse geocode
 */

function reverse(ll, callback) {
  log('--> reverse geocoding %s', ll);
  get('/geocode/reverse/' + ll[0] + ',' + ll[1], function(err, res) {
    if (err) {
      log('<-- geocoding error %e', err);
      callback(err, res);
    } else {
      log('<-- geocoding complete %j', res.body);
      callback(null, res.body);
    }
  });
}

function reverseAmigo(ll, callback) {
  log('--> reverse geocoding %s', ll);

  var parameter = {'point.lon':ll[0], 'point.lat':ll[1] };
  get('https://www.amigocloud.com/api/v1/me/geocoder/reverse', parameter, function(err, res) {
    console.log("change reverse", res);
    if (err) {
      log('<-- geocoding error %e', err);
      callback(err, res);
    } else {
      log('<-- geocoding complete %j', res.body.features);
      callback(null, res.body.features);
    }
  });
}

/**
 * Suggestions!
 */

function suggestAmigo(text, callback) {

    var lista_direcciones;

    //get('https://www.amigocloud.com/api/v1/me/geocoder/autocomplete?text=' + text +'&token=' + dev_amigo_token,
    get('https://www.amigocloud.com/api/v1/me/geocoder/search?token=R:DNiePlGOMsw93cEgde88woWAQxm1xzWt7lvVXe&boundary.rect.min_lat=36.155617833819&boundary.rect.min_lon=-123.607177734375&boundary.rect.max_lat=38.826870521381&boundary.rect.max_lon=-120.701293945312&sources=osm,oa&text=' + text,

        function(err, res) {

            if(err) {
                console.log("Error amigo cloud");
                log("Amigo Cloud Response Error ->", err);

            }else{
                if(res.body.features) {

                    var lista_direcciones = res.body.features;
                    if (lista_direcciones.length > 0) {
                         callback(
                            null,
                            lista_direcciones
                        );
                    }else {
                        callback(true, res);
                    }

                }
            }
    });
}

function suggest(text, callback) {
  var bingSuggestions, nominatimSuggestions, totalSuggestions;
  log('--> getting suggestion for %s', text);

  get('/geocode/suggest/'+ text, function(err, res){

    if (err) {
      log('<-- suggestion error %s', err);
      callback(err, res);
    } else {
      log('<-- got %s suggestions', res.body.length);

	bingSuggestions = res.body;

    console.log("------------API GEOCODE---------------");
    console.log("res ->", res.body);
    console.log("res.body ->", res);

//      callback(null, res.body);
	get('http://nominatim.openstreetmap.org/search' +
	    '?format=json&addressdetails=1&' +
	    'viewbox=' + southWest[0] + ',' +
	    northEast[1] + ',' + northEast[0] + ',' + southWest[1] +
	    '&bounded=1' +
	    'countrycodes=us&q=' + text, function (err, nRes) {
		var inside = false;
	    nominatimSuggestions = [];
            for (var i = 0; i < nRes.body.length; i++) {
//		inside = inside && (nRes.body[i].lng > southWest[0]);
//		inside = inside && (nRes.body[i].lng < northEast[0]);
//		inside = inside && (nRes.body[i].lat > southWest[1]);
//		inside = inside && (nRes.body[i].lat < northEast[1]);
//		if (inside) {
                    nominatimSuggestions.push(nRes.body[i]);
//		}
            }

            console.log('======data enviada===============');
            console.log(nominatimSuggestions.slice(0,2).concat(bingSuggestions.slice(0,3)));
            callback(
		null,
		nominatimSuggestions.slice(0,2).concat(bingSuggestions.slice(0,3))
	    );
	});
    }
  });

}<commit_msg>adding reverse function<commit_after>var config = require('config');
var log = require('./client/log')('geocode');
var get = require('./client/request').get;

var southWest = [-123.099060058594, 36.745486924699];
var northEast = [-121.192932128906, 38.182068998322];

/**********tismart **********************/
var dev_amigo_token = "A:m8SOB7KwYWuuWAeYEHHjBf7U9VIZFrMuH2LLjS";

/**
 * Geocode
 */

module.exports = geocode;
module.exports.reverse = reverse;
module.exports.suggest = suggest;
module.exports.suggestAmigo = suggestAmigo;
module.exports.reverseAmigo = reverseAmigo;

/**
 * Geocode
 */

function geocode(address, callback) {
  log('--> geocoding %s', address);
  get('/geocode/' + address, function(err, res) {
    if (err) {
      log('<-- geocoding error %s', err);
      callback(err, res);
    } else {
      log('<-- geocoding complete %j', res.body);
      callback(null, res.body);
    }
  });
}

/**
 * Reverse geocode
 */

function reverse(ll, callback) {
  log('--> reverse geocoding %s', ll);
  get('/geocode/reverse/' + ll[0] + ',' + ll[1], function(err, res) {
    if (err) {
      log('<-- geocoding error %e', err);
      callback(err, res);
    } else {
      log('<-- geocoding complete %j', res.body);
      callback(null, res.body);
    }
  });
}

function reverseAmigo(ll, callback) {
  log('--> reverse geocoding %s', ll);

  var parameter = {'point.lon':ll[0], 'point.lat':ll[1], 'token':'R:DNiePlGOMsw93cEgde88woWAQxm1xzWt7lvVXe' };
  get('https://www.amigocloud.com/api/v1/me/geocoder/reverse', parameter, function(err, res) {
    console.log("change reverse", res);
    if (err) {
      log('<-- geocoding error %e', err);
      callback(err, res);
    } else {
      log('<-- geocoding complete %j', res.body.features);
      callback(null, res.body.features);
    }
  });
}

/**
 * Suggestions!
 */

function suggestAmigo(text, callback) {

    var lista_direcciones;

    //get('https://www.amigocloud.com/api/v1/me/geocoder/autocomplete?text=' + text +'&token=' + dev_amigo_token,
    get('https://www.amigocloud.com/api/v1/me/geocoder/search?token=R:DNiePlGOMsw93cEgde88woWAQxm1xzWt7lvVXe&boundary.rect.min_lat=36.155617833819&boundary.rect.min_lon=-123.607177734375&boundary.rect.max_lat=38.826870521381&boundary.rect.max_lon=-120.701293945312&sources=osm,oa&text=' + text,

        function(err, res) {

            if(err) {
                console.log("Error amigo cloud");
                log("Amigo Cloud Response Error ->", err);

            }else{
                if(res.body.features) {

                    var lista_direcciones = res.body.features;
                    if (lista_direcciones.length > 0) {
                         callback(
                            null,
                            lista_direcciones
                        );
                    }else {
                        callback(true, res);
                    }

                }
            }
    });
}

function suggest(text, callback) {
  var bingSuggestions, nominatimSuggestions, totalSuggestions;
  log('--> getting suggestion for %s', text);

  get('/geocode/suggest/'+ text, function(err, res){

    if (err) {
      log('<-- suggestion error %s', err);
      callback(err, res);
    } else {
      log('<-- got %s suggestions', res.body.length);

	bingSuggestions = res.body;

    console.log("------------API GEOCODE---------------");
    console.log("res ->", res.body);
    console.log("res.body ->", res);

//      callback(null, res.body);
	get('http://nominatim.openstreetmap.org/search' +
	    '?format=json&addressdetails=1&' +
	    'viewbox=' + southWest[0] + ',' +
	    northEast[1] + ',' + northEast[0] + ',' + southWest[1] +
	    '&bounded=1' +
	    'countrycodes=us&q=' + text, function (err, nRes) {
		var inside = false;
	    nominatimSuggestions = [];
            for (var i = 0; i < nRes.body.length; i++) {
//		inside = inside && (nRes.body[i].lng > southWest[0]);
//		inside = inside && (nRes.body[i].lng < northEast[0]);
//		inside = inside && (nRes.body[i].lat > southWest[1]);
//		inside = inside && (nRes.body[i].lat < northEast[1]);
//		if (inside) {
                    nominatimSuggestions.push(nRes.body[i]);
//		}
            }

            console.log('======data enviada===============');
            console.log(nominatimSuggestions.slice(0,2).concat(bingSuggestions.slice(0,3)));
            callback(
		null,
		nominatimSuggestions.slice(0,2).concat(bingSuggestions.slice(0,3))
	    );
	});
    }
  });

}<|endoftext|>


<commit_before>(function(){var t=Array.prototype.forEach.call.bind(Array.prototype.forEach);window.forEach=t})(),function(){function t(t,o){1==arguments.length&&(o=t,t=null),o&&o.hasOwnProperty("constructor")||(o.constructor=function(){this.super()});var n=o.constructor,r=t&&t.prototype||Object.prototype;return n.prototype=e(r,o),"super"in n.prototype||(n.prototype.super=i),n}function e(t,e){return Object.create(t,o(e))}function o(t){var e={};for(var o in t)e[o]=n(t,o);return e}function n(t,e){return t&&Object.getOwnPropertyDescriptor(t,e)||n(Object.getPrototypeOf(t),e)}function i(t){var e=i.caller,o=e._nom;if(!o&&(o=e._nom=l.call(this,e),!o))return console.warn('called super() on a method not in "this"'),void 0;"_super"in e||a(e,o,Object.getPrototypeOf(this));var n=e._super;if(n){var r=n[o];return"_super"in r||a(r,o,n),r.apply(this,t||[])}}function r(t,e,o){for(var n=t;n&&(!n.hasOwnProperty(e)||n[e]==o);)n=Object.getPrototypeOf(n);return n}function a(t,e,o){t._super=r(o,e,t),t._super&&(t._super[e]._nom=e)}function l(t){for(var e in this){var o=n(this,e);if(o.value==t)return e}}window.$class=t,window.extend=e,window.$super=i}(),function(){function t(t,o){if(t!=window){var i=mixin({},a,o);Toolkit.addResolvePath(i,t),i.installTemplate=function(){this.super(),e.call(this,t)},i.readyCallback=function(){this.installTemplate(),n.call(this)},Toolkit.parseHostEvents(t.attributes,i),Toolkit.installSheets(t),Toolkit.shimStyling(t),t.register({prototype:i}),logFlags.comps&&console.log("initialized component "+t.options.name)}}function e(t){var e=t.querySelector("template");if(e){var n=this.webkitCreateShadowRoot();return n.host=this,n.appendChild(e.createInstance()),PointerGestures.register(n),o.call(this,n),n}}function o(t){document.upgradeElements(t),document.watchDOM(t),Toolkit.bindModel.call(this,t),Toolkit.marshalNodeReferences.call(this,t);var e=Toolkit.accumulateEvents(t);Toolkit.bindAccumulatedLocalEvents.call(this,t,e)}function n(){Toolkit.observeProperties.call(this),Toolkit.takeAttributes.call(this);var t=Toolkit.accumulateHostEvents.call(this);Toolkit.bindAccumulatedHostEvents.call(this,t),this.ready&&this.ready()}function i(t,e){for(var o=t;o&&o!=this;){var n=Array.prototype.indexOf.call(e,o);if(n>=0)return n;o=o.parentNode}}var r=window.logFlags||{},a={isToolkitElement:!0,"super":$super,bind:function(){Toolkit.bind.apply(this,arguments)},job:function(){return Toolkit.job.apply(this,arguments)},asyncMethod:function(t,e,o){var n=e&&e.length?e:[e];return window.setTimeout(function(){this[t].apply(this,n)}.bind(this),o||0)},dispatch:function(t,e){this[t]&&this[t].apply(this,e)},send:function(t,e,o){var n=o||this;r.events&&console.log("[%s]: sending [%s]",n.localName,t),n.dispatchEvent(new CustomEvent(t,{bubbles:!0,detail:e}))},asend:function(){this.asyncMethod("send",arguments)}};window.Toolkit={register:t,findDistributedTarget:i}}(),function(){function t(t,o,n,i){e.bind&&console.log("[%s]: bindProperties: [%s] to [%s].[%s]",n.localName,i,t.localName,o),Object.defineProperty(t,o,{get:function(){return ChangeSummary.getValueAtPath(n,i)},set:function(t){ChangeSummary.setValueAtPath(n,i,t)},configurable:!0,enumerable:!0})}var e=window.logFlags||{};Toolkit.bindProperties=t}(),function(){function t(t){o.bind&&console.group("[%s] bindModel",this.localName),HTMLTemplateElement.bindTree(t,this),o.bind&&console.groupEnd()}function e(t,e,o){var n=Toolkit.propertyForAttribute.call(this,t);n?Toolkit.bindProperties(this,n,e,o):HTMLElement.prototype.bind.apply(this,arguments)}var o=window.logFlags||{},n=/\{\{([^{}]*)}}/;Toolkit.bind=e,Toolkit.bindModel=t,Toolkit.bindPattern=n}(),function(){function t(){forEach(this.attributes,function(t){var i=e.call(this,t.name);if(i){if(t.value.search(n)>=0)return;var r=this[i],a=o(t.value,r);a!==r&&(this[i]=a)}},this)}function e(t){for(var e,o=Object.keys(Object.getPrototypeOf(this)),n=0;e=o[n];n++)if(e.toLowerCase()==t)return e}function o(t,e){var o=typeof e;switch(t){case"":case"true":return"boolean"==o?!0:t;case"false":return"boolean"==o?!1:t}return isNaN(t)?t:parseFloat(t)}var n=Toolkit.bindPattern;Toolkit.takeAttributes=t,Toolkit.propertyForAttribute=e}(),Toolkit.marshalNodeReferences=function(t){var e=this.$=this.$||{};if(t){var o=t.querySelectorAll("[id]");forEach(o,function(t){e[t.id]=t})}},function(){function t(t,e,o){var n=o.bind(this);for(var i in e)s.events&&console.log('[%s] bindAccumulatedEvents: addEventListener("%s", listen)',t.localName,i),t.addEventListener(i,n)}function e(e){t.call(this,this,e,i)}function o(e,o){t.call(this,e,o,n)}function n(t){if(!t.cancelBubble){t.on=c+t.type,s.events&&console.group("[%s]: listenLocal [%s]",this.localName,t.on);for(var e=t.target;e&&e!=this;){var o=w(e);if(o&&a.call(o,e,t))return;e=e.parentNode}s.events&&console.groupEnd()}}function i(t){t.cancelBubble||(s.events&&console.group("[%s]: listenHost [%s]",this.localName,t.type),l.call(this,this,t),s.events&&console.groupEnd())}function r(t){var e=T.get(t);return e||(e=[],T.set(t,e)),e}function a(t,e){if(t.attributes){var o=r(e);if(0>o.indexOf(t)){o.push(t);var n=t.getAttribute(e.on);n&&(s.events&&console.log("[%s] found handler name [%s]",this.localName,n),k(this,n,[e,e.detail,t]))}}return e.cancelBubble}function l(t,e){var o=E.call(t,e.type);return o&&(s.events&&console.log("[%s] found host handler name [%s]",t.localName,o),k(t,o,[e,e.detail,t])),e.cancelBubble}var s=window.logFlags||{},c="on-",u=function(t,e){e.eventDelegates=f(t)},f=function(t){var e={};if(t)for(var o,n=0;o=t[n];n++)o.name.slice(0,c.length)==c&&(e[o.name.slice(c.length)]=o.value);return e},d=function(t,e){var o=e||{};return h(t,o),m(t,o),b(t,o),o},h=function(t,e){var o=t.attributes;if(o)for(var n,i=0;n=o[i];i++)n.name.slice(0,c.length)===c&&v(n.name.slice(c.length),e)},p={webkitanimationstart:"webkitAnimationStart",webkitanimationend:"webkitAnimationEnd",webkittransitionend:"webkitTransitionEnd",domfocusout:"DOMFocusOut",domfocusin:"DOMFocusIn"},v=function(t,e){var o=p[t]||t;e[o]=1},m=function(t,e){for(var o,n=t.childNodes,i=0;o=n[i];i++)d(o,e)},b=function(t,e){if("template"==t.localName){var o=y(t);o&&m(o,e)}},y=function(t){return t.ref?t.ref.content:t.content},g=function(t){for(var e=t||{},o=Object.getPrototypeOf(this);o&&o!==HTMLElement.prototype;){if(o.hasOwnProperty("eventDelegates"))for(var n in o.eventDelegates)v(n,e);o=Object.getPrototypeOf(o)}return e},w=function(t){for(var e=t;e.parentNode&&"shadow-root"!==e.localName;)e=e.parentNode;return e.host},k=function(t,e,o){t&&(s.events&&console.group("[%s] dispatch [%s]",t.localName,e),t.dispatch(e,o),s.events&&console.groupEnd())},T=new SideTable("handledList"),E=function(t){for(var e=this;e;){if(e.hasOwnProperty("eventDelegates")){var o=e.eventDelegates[t]||e.eventDelegates[t.toLowerCase()];if(o)return o}e=e.__proto__}};Toolkit.parseHostEvents=u,Toolkit.accumulateEvents=d,Toolkit.accumulateHostEvents=g,Toolkit.bindAccumulatedHostEvents=e,Toolkit.bindAccumulatedLocalEvents=o}(),function(){function t(){for(var t in this)e.call(this,t)}function e(t){o.call(this,t)&&(i.watch&&console.log("["+this.localName+"] watching ["+t+"]"),Model.observePath(this,t,function(e,o){i.data&&console.log("[%s#%s] watch: [%s] now [%s] was [%s]",this.localName,this.node.id||"",t,this[t],o),n.call(this,t,o)}.bind(this)))}function o(t){return"_"!=t[0]&&!(t in Object.prototype)&&Boolean(this[t+r])}function n(t,e){var o=t+r;this[o]&&this[o](e)}var i=window.logFlags||{},r="Changed";Toolkit.observeProperties=t}(),function(){function t(t){e(t),o(t)}function e(t){var e=t.querySelectorAll("[rel=stylesheet]"),o=t.querySelector("template");if(o)var n=templateContent(o);n&&p(e,function(t){if(!t.hasAttribute(h)){t.parentNode.removeChild(t);var e=r(t);e&&n.insertBefore(e,n.firstChild)}})}function o(t){var e=t.globalStyles||(t.globalStyles=s(t,"global"));a(e,c.head)}function n(t,e){var o=e.controllerStyles||(e.controllerStyles=s(e,"controller"));u.queue(function(){var e=i(t);e&&a(o,e)})}function i(t){for(var e=t;e.parentNode&&"shadow-root"!=e.localName;)e=e.parentNode;return e==c?c.head:e}function r(t){if(t.__resource){var e=c.createElement("style");return e.textContent=t.__resource,e}console.warn("Could not find content for stylesheet",t)}function a(t,e){t.forEach(function(t){e.appendChild(t.cloneNode(!0))})}function l(t,e){return d?d.call(t,e):void 0}function s(t,e){var o=[],n=t.querySelectorAll("[rel=stylesheet]"),i="["+h+"="+e+"]";Array.prototype.forEach.call(n,function(t){l(t,i)&&(t.parentNode.removeChild(t),o.push(r(t)))});var a=t.querySelectorAll("style");return Array.prototype.forEach.call(a,function(t){l(t,i)&&(t.parentNode.removeChild(t),o.push(t))}),o}window.logFlags||{};var c=window.ShadowDOMPolyfill?ShadowDOMPolyfill.wrap(document):document,u={list:[],queue:function(t){t&&u.list.push(t),u.queueFlush()},queueFlush:function(){u.flushing||(u.flushing=!0,requestAnimationFrame(u.flush))},flush:function(){u.list.forEach(function(t){t()}),u.list=[],u.flusing=!1}},f=HTMLElement.prototype,d=f.matches||f.matchesSelector||f.webkitMatchesSelector||f.mozMatchesSelector,h="toolkit-scope",p=Array.prototype.forEach.call.bind(Array.prototype.forEach);Toolkit.installSheets=t,Toolkit.installControllerStyles=n}(),function(){function t(t,e){var n=o(e);t.resolvePath=function(t){return n+t}}function e(t){if(t){var e=t.split("/");return e.pop(),e.push(""),e.join("/")}return""}function o(t){return e(t.ownerDocument.URL||t.ownerDocument._URL||t.ownerDocument.impl._URL)}Toolkit.addResolvePath=t}(),function(){document.write("<!-- begin Toolkit injections -->\n"),document.write("<!-- injected meta tags for mobile -->\n"),document.write('<meta name="apple-mobile-web-app-capable" content="yes">\n'),document.write('<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no">\n'),document.write("<!-- injected FOUC prevention -->\n"),document.write("<style>body {opacity: 0;}</style>"),document.write("<!-- end Toolkit injections -->\n"),window.addEventListener("WebComponentsReady",function(){document.body.style.webkitTransition="opacity 0.3s",document.body.style.opacity=1})}();<commit_msg>freshen build<commit_after>(function(){var t=Array.prototype.forEach.call.bind(Array.prototype.forEach);window.forEach=t})(),function(){function t(t,o){1==arguments.length&&(o=t,t=null),o&&o.hasOwnProperty("constructor")||(o.constructor=function(){this.super()});var n=o.constructor,r=t&&t.prototype||Object.prototype;return n.prototype=e(r,o),"super"in n.prototype||(n.prototype.super=i),n}function e(t,e){return Object.create(t,o(e))}function o(t){var e={};for(var o in t)e[o]=n(t,o);return e}function n(t,e){return t&&Object.getOwnPropertyDescriptor(t,e)||n(Object.getPrototypeOf(t),e)}function i(t){var e=i.caller,o=e._nom;if(!o&&(o=e._nom=l.call(this,e),!o))return console.warn('called super() on a method not in "this"'),void 0;"_super"in e||a(e,o,Object.getPrototypeOf(this));var n=e._super;if(n){var r=n[o];return"_super"in r||a(r,o,n),r.apply(this,t||[])}}function r(t,e,o){for(var n=t;n&&(!n.hasOwnProperty(e)||n[e]==o);)n=Object.getPrototypeOf(n);return n}function a(t,e,o){t._super=r(o,e,t),t._super&&(t._super[e]._nom=e)}function l(t){for(var e in this){var o=n(this,e);if(o.value==t)return e}}window.$class=t,window.extend=e,window.$super=i}(),function(){function t(t,o){if(t!=window){var n=mixin({},a,o);Toolkit.addResolvePath(n,t),n.installTemplate=function(){this.super(),e.call(this,t)},Toolkit.publishAttributes(t.attributes.attribute),Toolkit.parseHostEvents(t.attributes,n),Toolkit.installSheets(t),Toolkit.shimStyling(t),t.register({prototype:n}),logFlags.comps&&console.log("initialized component "+t.options.name)}}function e(t){var e=t.querySelector("template");if(e){var n=this.webkitCreateShadowRoot();return n.host=this,n.appendChild(e.createInstance()),PointerGestures.register(n),o.call(this,n),n}}function o(t){document.upgradeElements(t),document.watchDOM(t),Toolkit.bindModel.call(this,t),Toolkit.marshalNodeReferences.call(this,t);var e=Toolkit.accumulateEvents(t);Toolkit.bindAccumulatedLocalEvents.call(this,t,e)}function n(){Toolkit.observeProperties.call(this),Toolkit.takeAttributes.call(this);var t=Toolkit.accumulateHostEvents.call(this);Toolkit.bindAccumulatedHostEvents.call(this,t),this.ready&&this.ready()}function i(t,e){for(var o=t;o&&o!=this;){var n=Array.prototype.indexOf.call(e,o);if(n>=0)return n;o=o.parentNode}}var r=window.logFlags||{},a={isToolkitElement:!0,"super":$super,readyCallback:function(){this.installTemplate(),n.call(this)},bind:function(){Toolkit.bind.apply(this,arguments)},job:function(){return Toolkit.job.apply(this,arguments)},asyncMethod:function(t,e,o){var n=e&&e.length?e:[e];return window.setTimeout(function(){this[t].apply(this,n)}.bind(this),o||0)},dispatch:function(t,e){this[t]&&this[t].apply(this,e)},send:function(t,e,o){var n=o||this;r.events&&console.log("[%s]: sending [%s]",n.localName,t),n.dispatchEvent(new CustomEvent(t,{bubbles:!0,detail:e}))},asend:function(){this.asyncMethod("send",arguments)}};window.Toolkit={register:t,findDistributedTarget:i}}(),function(){function t(t,o,n,i){e.bind&&console.log("[%s]: bindProperties: [%s] to [%s].[%s]",n.localName,i,t.localName,o),Object.defineProperty(t,o,{get:function(){return ChangeSummary.getValueAtPath(n,i)},set:function(t){ChangeSummary.setValueAtPath(n,i,t)},configurable:!0,enumerable:!0})}var e=window.logFlags||{};Toolkit.bindProperties=t}(),function(){function t(t){o.bind&&console.group("[%s] bindModel",this.localName),HTMLTemplateElement.bindTree(t,this),o.bind&&console.groupEnd()}function e(t,e,o){var n=Toolkit.propertyForAttribute.call(this,t);n?Toolkit.bindProperties(this,n,e,o):HTMLElement.prototype.bind.apply(this,arguments)}var o=window.logFlags||{},n=/\{\{([^{}]*)}}/;Toolkit.bind=e,Toolkit.bindModel=t,Toolkit.bindPattern=n}(),function(){function t(){forEach(this.attributes,function(t){var i=e.call(this,t.name);if(i){if(t.value.search(n)>=0)return;var r=this[i],a=o(t.value,r);a!==r&&(this[i]=a)}},this)}function e(t){for(var e,o=Object.keys(this.__proto__),n=0;e=o[n];n++)if(e.toLowerCase()==t)return e}function o(t,e){var o=typeof e;switch(t){case"":case"true":return"boolean"==o?!0:t;case"false":return"boolean"==o?!1:t}return isNaN(t)?t:parseFloat(t)}var n=Toolkit.bindPattern,i=function(t){};Toolkit.takeAttributes=t,Toolkit.propertyForAttribute=e,Toolkit.publishAttributes=i}(),Toolkit.marshalNodeReferences=function(t){var e=this.$=this.$||{};if(t){var o=t.querySelectorAll("[id]");forEach(o,function(t){e[t.id]=t})}},function(){function t(t,e,o){var n=o.bind(this);for(var i in e)s.events&&console.log('[%s] bindAccumulatedEvents: addEventListener("%s", listen)',t.localName,i),t.addEventListener(i,n)}function e(e){t.call(this,this,e,i)}function o(e,o){t.call(this,e,o,n)}function n(t){if(!t.cancelBubble){t.on=c+t.type,s.events&&console.group("[%s]: listenLocal [%s]",this.localName,t.on);for(var e=t.target;e&&e!=this;){var o=w(e);if(o&&a.call(o,e,t))return;e=e.parentNode}s.events&&console.groupEnd()}}function i(t){t.cancelBubble||(s.events&&console.group("[%s]: listenHost [%s]",this.localName,t.type),l.call(this,this,t),s.events&&console.groupEnd())}function r(t){var e=T.get(t);return e||(e=[],T.set(t,e)),e}function a(t,e){if(t.attributes){var o=r(e);if(0>o.indexOf(t)){o.push(t);var n=t.getAttribute(e.on);n&&(s.events&&console.log("[%s] found handler name [%s]",this.localName,n),k(this,n,[e,e.detail,t]))}}return e.cancelBubble}function l(t,e){var o=E.call(t,e.type);return o&&(s.events&&console.log("[%s] found host handler name [%s]",t.localName,o),k(t,o,[e,e.detail,t])),e.cancelBubble}var s=window.logFlags||{},c="on-",u=function(t,e){e.eventDelegates=f(t)},f=function(t){var e={};if(t)for(var o,n=0;o=t[n];n++)o.name.slice(0,c.length)==c&&(e[o.name.slice(c.length)]=o.value);return e},d=function(t,e){var o=e||{};return h(t,o),m(t,o),b(t,o),o},h=function(t,e){var o=t.attributes;if(o)for(var n,i=0;n=o[i];i++)n.name.slice(0,c.length)===c&&v(n.name.slice(c.length),e)},p={webkitanimationstart:"webkitAnimationStart",webkitanimationend:"webkitAnimationEnd",webkittransitionend:"webkitTransitionEnd",domfocusout:"DOMFocusOut",domfocusin:"DOMFocusIn"},v=function(t,e){var o=p[t]||t;e[o]=1},m=function(t,e){for(var o,n=t.childNodes,i=0;o=n[i];i++)d(o,e)},b=function(t,e){if("template"==t.localName){var o=y(t);o&&m(o,e)}},y=function(t){return t.ref?t.ref.content:t.content},g=function(t){for(var e=t||{},o=this.__proto__;o&&o!==HTMLElement.prototype;){if(o.hasOwnProperty("eventDelegates"))for(var n in o.eventDelegates)v(n,e);o=o.__proto__}return e},w=function(t){for(var e=t;e.parentNode&&"shadow-root"!==e.localName;)e=e.parentNode;return e.host},k=function(t,e,o){t&&(s.events&&console.group("[%s] dispatch [%s]",t.localName,e),t.dispatch(e,o),s.events&&console.groupEnd())},T=new SideTable("handledList"),E=function(t){for(var e=this;e;){if(e.hasOwnProperty("eventDelegates")){var o=e.eventDelegates[t]||e.eventDelegates[t.toLowerCase()];if(o)return o}e=e.__proto__}};Toolkit.parseHostEvents=u,Toolkit.accumulateEvents=d,Toolkit.accumulateHostEvents=g,Toolkit.bindAccumulatedHostEvents=e,Toolkit.bindAccumulatedLocalEvents=o}(),function(){function t(){for(var t in this)e.call(this,t)}function e(t){o.call(this,t)&&(i.watch&&console.log("["+this.localName+"] watching ["+t+"]"),Model.observePath(this,t,function(e,o){i.data&&console.log("[%s#%s] watch: [%s] now [%s] was [%s]",this.localName,this.node.id||"",t,this[t],o),n.call(this,t,o)}.bind(this)))}function o(t){return"_"!=t[0]&&!(t in Object.prototype)&&Boolean(this[t+r])}function n(t,e){var o=t+r;this[o]&&this[o](e)}var i=window.logFlags||{},r="Changed";Toolkit.observeProperties=t}(),function(){function t(t){e(t),o(t)}function e(t){var e=t.querySelectorAll("[rel=stylesheet]"),o=t.querySelector("template");if(o)var n=templateContent(o);n&&p(e,function(t){if(!t.hasAttribute(h)){t.parentNode.removeChild(t);var e=r(t);e&&n.insertBefore(e,n.firstChild)}})}function o(t){var e=t.globalStyles||(t.globalStyles=s(t,"global"));a(e,c.head)}function n(t,e){var o=e.controllerStyles||(e.controllerStyles=s(e,"controller"));u.queue(function(){var e=i(t);e&&a(o,e)})}function i(t){for(var e=t;e.parentNode&&"shadow-root"!=e.localName;)e=e.parentNode;return e==c?c.head:e}function r(t){if(t.__resource){var e=c.createElement("style");return e.textContent=t.__resource,e}console.warn("Could not find content for stylesheet",t)}function a(t,e){t.forEach(function(t){e.appendChild(t.cloneNode(!0))})}function l(t,e){return d?d.call(t,e):void 0}function s(t,e){var o=[],n=t.querySelectorAll("[rel=stylesheet]"),i="["+h+"="+e+"]";Array.prototype.forEach.call(n,function(t){l(t,i)&&(t.parentNode.removeChild(t),o.push(r(t)))});var a=t.querySelectorAll("style");return Array.prototype.forEach.call(a,function(t){l(t,i)&&(t.parentNode.removeChild(t),o.push(t))}),o}window.logFlags||{};var c=window.ShadowDOMPolyfill?ShadowDOMPolyfill.wrap(document):document,u={list:[],queue:function(t){t&&u.list.push(t),u.queueFlush()},queueFlush:function(){u.flushing||(u.flushing=!0,requestAnimationFrame(u.flush))},flush:function(){u.list.forEach(function(t){t()}),u.list=[],u.flusing=!1}},f=HTMLElement.prototype,d=f.matches||f.matchesSelector||f.webkitMatchesSelector||f.mozMatchesSelector,h="toolkit-scope",p=Array.prototype.forEach.call.bind(Array.prototype.forEach);Toolkit.installSheets=t,Toolkit.installControllerStyles=n}(),function(){function t(t,e){var n=o(e);t.resolvePath=function(t){return n+t}}function e(t){if(t){var e=t.split("/");return e.pop(),e.push(""),e.join("/")}return""}function o(t){return e(t.ownerDocument.URL||t.ownerDocument._URL||t.ownerDocument.impl._URL)}Toolkit.addResolvePath=t}(),function(){document.write("<!-- begin Toolkit injections -->\n"),document.write("<!-- injected meta tags for mobile -->\n"),document.write('<meta name="apple-mobile-web-app-capable" content="yes">\n'),document.write('<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no">\n'),document.write("<!-- injected FOUC prevention -->\n"),document.write("<style>body {opacity: 0;}</style>"),document.write("<!-- end Toolkit injections -->\n"),window.addEventListener("WebComponentsReady",function(){document.body.style.webkitTransition="opacity 0.3s",document.body.style.opacity=1})}();<|endoftext|>


<commit_before>// Resolves key path for given object into an event and adds it to provided fragment

'use strict';

var resolvePath = require('dbjs/_setup/resolve-property-path')
  , serialize   = require('dbjs/_setup/serialize/value')

  , tokenize = resolvePath.tokenize, resolveObject = resolvePath.resolveObject;

module.exports = function (fragment, obj, path) {
	var names = tokenize(path), desc, propertyObj, event;
	propertyObj = resolveObject(obj, names);
	desc = propertyObj._getDescriptor_(names[names.length - 1]);
	if (desc.master !== obj.master) return;
	event = desc._lastOwnEvent_;
	if (!event) return;
	fragment.update(obj.__id__ + '/' + path, { value: serialize(event.value), stamp: event.stamp });
};
<commit_msg>Fix require path<commit_after>// Resolves key path for given object into an event and adds it to provided fragment

'use strict';

var resolvePath = require('dbjs/_setup/utils/resolve-property-path')
  , serialize   = require('dbjs/_setup/serialize/value')

  , tokenize = resolvePath.tokenize, resolveObject = resolvePath.resolveObject;

module.exports = function (fragment, obj, path) {
	var names = tokenize(path), desc, propertyObj, event;
	propertyObj = resolveObject(obj, names);
	desc = propertyObj._getDescriptor_(names[names.length - 1]);
	if (desc.master !== obj.master) return;
	event = desc._lastOwnEvent_;
	if (!event) return;
	fragment.update(obj.__id__ + '/' + path, { value: serialize(event.value), stamp: event.stamp });
};
<|endoftext|>


<commit_before>(function(socket) {
  function isInPage(node) {
    return (node === document.body) ? false : document.body.contains(node);
  }

  const ERROR_MSG_EVENT = 'error:message';
  const TEMPLATE = `

Build error

<%= message %>

    `;

  const POPUP = document.createElement('div');
  const BODY = document.getElementsByTagName('body')[0];

  socket.on(ERROR_MSG_EVENT, function (error) {
    let message = error.message.replace(/\[\d+m/gm, '');

    if (isInPage(POPUP)) {
      BODY.removeChild(POPUP);
    }

    POPUP.innerHTML = TEMPLATE
      .replace('<%= message %>', message);
    BODY.appendChild(POPUP);

    console.error(message, error);
  });
})(window.___browserSync___.socket);
<commit_msg>Улучшены стили окна ошибки, + копка закрытия окна ошибки<commit_after>((socket) => {
  function isInPage(node) {
    return (node === document.body) ? false : document.body.contains(node);
  }

  const ERROR_MSG_EVENT = 'error:message';
  const TEMPLATE = `

          Build error
          <button class="__bs_scrMsg__close" type="button" onclick="getElementById('__bs_scrMsg').remove()"><svg class="__bs_scrMsg__close_icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><defs/><path d="M19 6.4L13.4 12l5.6 5.6-1.4 1.4-5.6-5.6L6.4 19 5 17.6l5.6-5.6L5 6.4 6.4 5l5.6 5.6L17.6 5z"/></svg></button>

<%= message %>

    `;

  const POPUP = document.createElement('div');
  const BODY = document.getElementsByTagName('body')[0];

  socket.on(ERROR_MSG_EVENT, (error) => {
    const message = error.message.replace(/\[\d+m/gm, '');

    if (isInPage(POPUP)) {
      BODY.removeChild(POPUP);
    }

    POPUP.innerHTML = TEMPLATE
      .replace('<%= message %>', message);
    BODY.appendChild(POPUP);

    console.error(message, error);
  });
})(window.___browserSync___.socket);
<|endoftext|>