<commit_before>import './compatibility'
import sendToActiveTab from './sendToActiveTab'
import landmarkName from './landmarkName'
import { defaultInterfaceSettings, dismissalStates } from './defaults'

//
// Creating a landmarks tree in response to info from content script
//

// Handle incoming landmarks message response
//
// If there are landmarks, then the response will be a list of objects that
// represent the landmarks.
//
//     [ { label: X, role: Y, depth: Z }, { . . . }, . . . ]
//
// If we got some landmarks from the page, make the tree of them. If there was
// an error, let the user know.
function handleLandmarksResponse(response) {
	const display = document.getElementById('landmarks')
	removeChildNodes(display)

	if (response === undefined && browser.runtime.lastError) {
		addText(display, 'Landmarks cannot run on this page.')  // FIXME translate
		// doesn't appear that the problem is the page has not loaded yet (?)
		return
	}

	if (browser.runtime.lastError) {
		// TODO: Seems this is not going to happen?
		addText(display,
			browser.i18n.getMessage('errorGettingLandmarksFromContentScript')
		)
		addReloadButton(display)
		return
	}

	if (Array.isArray(response)) {
		// Content script would normally send back an array of landmarks
		if (response.length === 0) {
			addText(display, browser.i18n.getMessage('noLandmarksFound'))
		} else {
			makeLandmarksTree(response, display)
		}
	} else {
		addText(display, errorString() + 'content script sent: ' + response)
	}
}

// Go through the landmarks identified for the page and create an HTML
// nested list to mirror the structure of those landmarks
function makeLandmarksTree(landmarks, container) {
	let previousDepth = 0
	const root = document.createElement('ul')  // start of tree
	let base = root                            // anchor for sub-trees
	let previousItem = null                    // last item to be created

	landmarks.forEach(function(landmark, index) {
		const depthChange = landmark.depth - previousDepth
		const absDepthChange = Math.abs(depthChange)

		function whenDepthIncreases() {
			base = document.createElement('ul')
			previousItem.appendChild(base)
		}

		function whenDepthDecreases() {
			// The parent of base is an
, the grandparent is the

			base = base.parentElement.parentElement
		}

		// If the depth has changed, insert/step back the appropriate number of
		// levels

		if (absDepthChange > 0) {
			const operation =
				depthChange > 0 ? whenDepthIncreases : whenDepthDecreases
			for (let i = 0; i < absDepthChange; i++) {
				operation()
			}
		}

		// If nesting hasn't changed, stick with the current base

		// Create the
 for this landmark
		const item = document.createElement('li')
		const button = document.createElement('button')
		button.className = 'browser-style'
		button.appendChild(document.createTextNode(landmarkName(landmark)))
		button.addEventListener('click', function() {
			focusLandmark(index)
		})
		item.appendChild(button)
		base.appendChild(item)  // add to current base

		// Housekeeping
		previousDepth = landmark.depth
		previousItem = item
	})

	container.appendChild(root)
}

//
// DOM manipulation utilities
//

// Remove all nodes contained within a node
function removeChildNodes(element) {
	while (element.firstChild) {
		element.removeChild(element.firstChild)
	}
}

// Append text paragraph to the given element
function addText(element, message) {
	const newPara = document.createElement('p')
	const newParaText = document.createTextNode(message)
	newPara.appendChild(newParaText)
	element.appendChild(newPara)
}

// Create a button that reloads the current page and add it to an element
// (Needs to be done this way to avoid CSP violation)
// TODO will this be needed?
function addReloadButton(element) {
	const button = document.createElement('button')
	button.className = 'browser-style'
	button.appendChild(document.createTextNode(
		browser.i18n.getMessage('tryReloading')))
	button.addEventListener('click', reloadActivePage)
	element.appendChild(button)
}

//
// General utilities
//

// When a landmark's corresponding button in the UI is clicked, focus it
function focusLandmark(index) {
	sendToActiveTab({
		request: 'focus-landmark',
		index: index
	})
}

// Function to reload the page in the current tab
function reloadActivePage() {
	browser.tabs.query({ active: true, currentWindow: true }, function(tabs) {
		browser.tabs.reload(tabs[0].tabId)
	})
	window.close()  // FIXME not good for sidebar?
}

// Return localised "Error: " string
function errorString() {
	return browser.i18n.getMessage('errorWord') + ': '
}

//
// Management
//

// Send a message to ask for the latest landmarks
function requestLandmarks() {
	sendToActiveTab({ request: 'get-landmarks' }, handleLandmarksResponse)
}

if (INTERFACE === 'sidebar') {
	// TODO: DRY out making buttons?
	function createNote() {  // eslint-disable-line no-inner-declarations
		browser.storage.sync.get(dismissalStates, function(items) {
			if (!items.dismissedSidebarNotAlone) {
				const para = document.createElement('p')
				const text = document.createTextNode(
					browser.i18n.getMessage('hintSidebarIsNotPrimary'))
				para.appendChild(text)

				const optionsButton = document.createElement('button')
				const optionsText = document.createTextNode(
					browser.i18n.getMessage('hintSidebarIsNotPrimaryOptions'))
				optionsButton.appendChild(optionsText)
				optionsButton.className = 'browser-style'
				optionsButton.onclick = function() {
					browser.runtime.openOptionsPage()
				}

				const dismissButton = document.createElement('button')
				const dismissText = document.createTextNode(
					browser.i18n.getMessage('hintDismiss'))
				dismissButton.appendChild(dismissText)
				dismissButton.className = 'browser-style'
				dismissButton.onclick = function() {
					browser.storage.sync.set({
						dismissedSidebarNotAlone: true
					}, function() {
						removeNote()
					})
				}

				const container = document.createElement('div')
				container.appendChild(para)
				container.appendChild(optionsButton)
				container.appendChild(dismissButton)
				container.id = 'config-message'

				document.body.insertBefore(container, document.body.firstChild)
			}
		})
	}

	function removeNote() {  // eslint-disable-line no-inner-declarations
		const message = document.getElementById('config-message')
		if (message) message.remove()
	}

	// We may be running in a sidebar, in which case listen for requests to update
	browser.runtime.onMessage.addListener(function(message) {
		switch (message.request) {
			case 'update-sidebar':
			case 'update-badge':  // FIXME COULD HAPPEN WHEN POPUP OPEN?
				requestLandmarks()
				break
		}
	})

	browser.storage.sync.get(defaultInterfaceSettings, function(items) {
		if (items.interface === 'popup') {
			createNote()
		}
	})

	// The sidebar may be open whilst the user interface setting is changed. This
	// relies on the fact that the popup can't be open when the user is making
	// these changes. We don't react to the value of this preference on load for
	// the same reason -- that would require knowing if we are the sidebar or not.
	browser.storage.onChanged.addListener(function(changes) {
		if (changes.hasOwnProperty('interface')) {
			switch (changes.interface.newValue) {
				case 'sidebar': removeNote()
					break
				case 'popup': createNote()
					break
				default:
					throw Error(`Unknown interface type "${changes.interface.newValue}`)  // FIXME DRY-ish (at least the error message?)
			}
		}
	})
}

// When the pop-up (or sidebar) opens, translate the heading and grab and
// process the list of page landmarks
// FIXME https://github.com/matatk/landmarks/issues/192
document.addEventListener('DOMContentLoaded', function() {
	document.getElementById('heading').innerText =
		browser.i18n.getMessage('popupHeading')

	requestLandmarks()
})
<commit_msg>DRY making of buttons in popup<commit_after>import './compatibility'
import sendToActiveTab from './sendToActiveTab'
import landmarkName from './landmarkName'
import { defaultInterfaceSettings, dismissalStates } from './defaults'

//
// Creating a landmarks tree in response to info from content script
//

// Handle incoming landmarks message response
//
// If there are landmarks, then the response will be a list of objects that
// represent the landmarks.
//
//     [ { label: X, role: Y, depth: Z }, { . . . }, . . . ]
//
// If we got some landmarks from the page, make the tree of them. If there was
// an error, let the user know.
function handleLandmarksResponse(response) {
	const display = document.getElementById('landmarks')
	removeChildNodes(display)

	if (response === undefined && browser.runtime.lastError) {
		addText(display, 'Landmarks cannot run on this page.')  // FIXME translate
		// doesn't appear that the problem is the page has not loaded yet (?)
		return
	}

	if (browser.runtime.lastError) {
		// TODO: Seems this is not going to happen?
		addText(display,
			browser.i18n.getMessage('errorGettingLandmarksFromContentScript')
		)
		addReloadButton(display)
		return
	}

	if (Array.isArray(response)) {
		// Content script would normally send back an array of landmarks
		if (response.length === 0) {
			addText(display, browser.i18n.getMessage('noLandmarksFound'))
		} else {
			makeLandmarksTree(response, display)
		}
	} else {
		addText(display, errorString() + 'content script sent: ' + response)
	}
}

// Go through the landmarks identified for the page and create an HTML
// nested list to mirror the structure of those landmarks
function makeLandmarksTree(landmarks, container) {
	let previousDepth = 0
	const root = document.createElement('ul')  // start of tree
	let base = root                            // anchor for sub-trees
	let previousItem = null                    // last item to be created

	landmarks.forEach(function(landmark, index) {
		const depthChange = landmark.depth - previousDepth
		const absDepthChange = Math.abs(depthChange)

		function whenDepthIncreases() {
			base = document.createElement('ul')
			previousItem.appendChild(base)
		}

		function whenDepthDecreases() {
			// The parent of base is an
, the grandparent is the

			base = base.parentElement.parentElement
		}

		// If the depth has changed, insert/step back the appropriate number of
		// levels

		if (absDepthChange > 0) {
			const operation =
				depthChange > 0 ? whenDepthIncreases : whenDepthDecreases
			for (let i = 0; i < absDepthChange; i++) {
				operation()
			}
		}

		// If nesting hasn't changed, stick with the current base

		// Create the
 for this landmark
		const item = document.createElement('li')
		const button = document.createElement('button')
		button.className = 'browser-style'
		button.appendChild(document.createTextNode(landmarkName(landmark)))
		button.addEventListener('click', function() {
			focusLandmark(index)
		})
		item.appendChild(button)
		base.appendChild(item)  // add to current base

		// Housekeeping
		previousDepth = landmark.depth
		previousItem = item
	})

	container.appendChild(root)
}

//
// DOM manipulation utilities
//

// Remove all nodes contained within a node
function removeChildNodes(element) {
	while (element.firstChild) {
		element.removeChild(element.firstChild)
	}
}

// Append text paragraph to the given element
function addText(element, message) {
	const newPara = document.createElement('p')
	const newParaText = document.createTextNode(message)
	newPara.appendChild(newParaText)
	element.appendChild(newPara)
}

function makeButton(nameMessage, onClick) {
	const button = document.createElement('button')
	button.className = 'browser-style'
	button.appendChild(document.createTextNode(
		browser.i18n.getMessage(nameMessage)))
	button.onclick = onClick
	return button
}

// Create a button that reloads the current page and add it to an element
// (Needs to be done this way to avoid CSP violation)
// TODO will this be needed?
function addReloadButton(element) {
	const button = makeButton('tryReloading', reloadActivePage)
	element.appendChild(button)
}

//
// General utilities
//

// When a landmark's corresponding button in the UI is clicked, focus it
function focusLandmark(index) {
	sendToActiveTab({
		request: 'focus-landmark',
		index: index
	})
}

// Function to reload the page in the current tab
function reloadActivePage() {
	browser.tabs.query({ active: true, currentWindow: true }, function(tabs) {
		browser.tabs.reload(tabs[0].tabId)
	})
	window.close()  // FIXME not good for sidebar?
}

// Return localised "Error: " string
function errorString() {
	return browser.i18n.getMessage('errorWord') + ': '
}

//
// Management
//

// Send a message to ask for the latest landmarks
function requestLandmarks() {
	sendToActiveTab({ request: 'get-landmarks' }, handleLandmarksResponse)
}

if (INTERFACE === 'sidebar') {
	function createNote() {  // eslint-disable-line no-inner-declarations
		browser.storage.sync.get(dismissalStates, function(items) {
			if (!items.dismissedSidebarNotAlone) {
				const para = document.createElement('p')
				para.appendChild(document.createTextNode(
					browser.i18n.getMessage('hintSidebarIsNotPrimary')))

				const optionsButton = makeButton(
					'hintSidebarIsNotPrimaryOptions',
					function() {
						browser.runtime.openOptionsPage()
					})

				const dismissButton = makeButton('hintDismiss',
					function() {
						browser.storage.sync.set({
							dismissedSidebarNotAlone: true
						}, function() {
							removeNote()
						})
					})

				const container = document.createElement('div')
				container.id = 'config-message'
				container.appendChild(para)
				container.appendChild(optionsButton)
				container.appendChild(dismissButton)

				document.body.insertBefore(container, document.body.firstChild)
			}
		})
	}

	function removeNote() {  // eslint-disable-line no-inner-declarations
		const message = document.getElementById('config-message')
		if (message) message.remove()
	}

	// We may be running in a sidebar, in which case listen for requests to update
	browser.runtime.onMessage.addListener(function(message) {
		switch (message.request) {
			case 'update-sidebar':
			case 'update-badge':  // FIXME COULD HAPPEN WHEN POPUP OPEN?
				requestLandmarks()
				break
		}
	})

	browser.storage.sync.get(defaultInterfaceSettings, function(items) {
		if (items.interface === 'popup') {
			createNote()
		}
	})

	// The sidebar may be open whilst the user interface setting is changed. This
	// relies on the fact that the popup can't be open when the user is making
	// these changes. We don't react to the value of this preference on load for
	// the same reason -- that would require knowing if we are the sidebar or not.
	browser.storage.onChanged.addListener(function(changes) {
		if (changes.hasOwnProperty('interface')) {
			switch (changes.interface.newValue) {
				case 'sidebar': removeNote()
					break
				case 'popup': createNote()
					break
				default:
					throw Error(`Unknown interface type "${changes.interface.newValue}`)  // FIXME DRY-ish (at least the error message?)
			}
		}
	})
}

// When the pop-up (or sidebar) opens, translate the heading and grab and
// process the list of page landmarks
// FIXME https://github.com/matatk/landmarks/issues/192
document.addEventListener('DOMContentLoaded', function() {
	document.getElementById('heading').innerText =
		browser.i18n.getMessage('popupHeading')

	requestLandmarks()
})
<|endoftext|>


<commit_before><commit_msg>add box collider<commit_after>/* @flow */
import Matter from 'matter-js';
import type Gob from '../gob';

// implements Collider interface
export default class BoxCollider {
  gob: Gob;
  constructor(gob: Gob) {
    this.gob = gob;
  }
  getMatterBody(): Matter.Body {
    const vertices = [
      // TL
      Matter.Vector.create(
        this.gob.position.x - this.gob.width / 2,
        this.gob.position.y - this.gob.height / 2,
      ),
      // TR
      Matter.Vector.create(
        this.gob.position.x + this.gob.width / 2,
        this.gob.position.y - this.gob.height / 2,
      ),
      // BR
      Matter.Vector.create(
        this.gob.position.x + this.gob.width / 2,
        this.gob.position.y + this.gob.height / 2,
      ),
      // BL
      Matter.Vector.create(
        this.gob.position.x - this.gob.width / 2,
        this.gob.position.y + this.gob.height / 2,
      ),
    ];
    // create the collider from the width + height
    return Matter.Body.create({
      angle: this.gob.angle,
      angularVelocity: this.gob.angularVelocity,
      mass: this.gob.mass,
      position: Matter.Vector.create(this.gob.position.x, this.gob.position.y),
      velocity: Matter.Vector.create(this.gob.velocity.x, this.gob.velocity.y),
      vertices: vertices,
    });
  }
}
<|endoftext|>


<commit_before>const util = require('util');

const Type   = require('./type').Type;
const Random = require('./random').Random;
const _ = require('./helpers');

/**
 * Helper func to decide where an attack lands
 * Unless the attacker is putting effort in being precise,
 * There is only a 50% chance their attack will hit its target.
 *
 * @param Array of locations to hit
 * @param String location being targeted
 * @param Boolean Is the attacker trying to be precise
 * @returns String location that get hit
 */
function decideHitLocation(locations, target, precise) {
  if (target && (precise || Random.coinFlip())) { return target; }
  return Random.fromArray(locations);
}

/** OVERVIEW ** //////////////////////////////
* The purpose of this class is to standardize
* the realtime combat API between players & NPCs.
*/

/**
* Generic func to apply all mods to a stat,
* starting with the base stat.
*/
const applyMod  = (stat, modifier) => modifier(stat)
const applyMods = (base, modsObj)  => _
  .reduceValues(modsObj, applyMod, base);

function CombatHelper(entity) {
  this._entity = entity;

  /*
   * Example modifier: {
      name: 'berserk',
      effect: damage => damage * 2
    }
   * Speed mods will affect time in between attacks
   * in milliseconds. So, doubling it will half attack speed.
   */
  this.speedMods   = {};
  this.damageMods  = {};
  this.toHitMods   = {};
  this.defenseMods = {};
  this.dodgeMods   = {};

  this.addMod = type =>
    modifier => this[type][modifier.name] = modifier.effect;

  this.addSpeedMod   = this.addMod('speedMods');
  this.addDamageMod  = this.addMod('damageMods');
  this.addToHitMod   = this.addMod('toHitMods');
  this.addDefenseMod = this.addMod('defenseMods');
  this.addDodgeMod   = this.addMod('dodgeMods');

  this.deleteMod = type =>
    name => delete this[type][name];

  this.removeSpeedMod   = this.deleteMod('speedMods');
  this.removeDamageMod  = this.deleteMod('damageMods');
  this.removeToHitMod   = this.deleteMod('toHitMods');
  this.removeDefenseMod = this.deleteMod('defenseMods');
  this.removeDodgeMod   = this.deleteMod('dodgeMods');

  this.deleteAllMods = name => {
    if (!name) { return false; } //TODO: Eventually, remove all mods?
    this.removeSpeedMod(name);
    this.removeDamageMod(name);
    this.removeToHitMod(name);
    this.removeDodgeMod(name);
    this.removeDefenseMod(name);
  };

  /**
   * Get hydrated primary or offhand weapon of player/npc.
   */
   //FIXME: Can be done better with changes to npc class.
   // Works, since this will let you get damage attr.
  this.getWeapon  = location => Type.isPlayer(this._entity) ?
    this._entity.getEquipped(location || 'wield', true) :
    () => this._entity;

  this.getOffhand = () => this.getWeapon('offhand');

  /**
   * Get just the name of the attack.
   */
  this.getAttackName = location => {
    const defaultWeapon = 'bare hands';
    if (Type.isPlayer(this._entity)) {
      const weapon = this.getWeapon(location);
      return weapon ?
        weapon.getShortDesc('en') :
        defaultWeapon;
    }
    return this._entity.getAttack('en') || defaultWeapon;
  }

  this.getPrimaryAttackName   = () => this.getAttackName('wield');
  this.getSecondaryAttackName = () => this.getAttackName('offhand');

  /**
  * Gets damage range from weapon obj
  * @param   Weapon obj
  * @param   Base possible damage for hand-to-hand
  * @return  Array of [min, max] damage range
  */
  const getWeaponDamage = (weapon, base) => weapon ?
    (weapon.getAttribute('damage') ?
      weapon.getAttribute('damage')
        .split('-')
        .map(dmg => parseInt(dmg, 10)) :
        base) :
      base;

  /**
   * Get the damage a player can do
   * @return int
   */
  this.getDamage = location => {
    location = location || 'wield';

    const self   = this._entity;
    const weapon = Type.isPlayer(self) ?
      this.getWeapon(location) :
      self;
    const base   = Type.isPlayer(self) ?
      [ 1, self.getAttribute('stamina') + 5 ] :
      [ 1, 20 ];

    const damageRange = getWeaponDamage(weapon, base);
    const damageRoll  = Random.inRange(...damageRange);

    const min = damageRange[0];
    const modifiedDamageRoll = applyMods(damageRoll, this.damageMods);

    const damageWithinBounds = _.setBounds(min, Infinity);
    const damageDealt = damageWithinBounds(modifiedDamageRoll);

    util.log('Deals damage: ', damageDealt);

    return damageDealt;
  };

  const getWeaponSpeed = (weapon, base, factor) => (weapon ?
    weapon.getAttribute('speed') : base) * factor;

  /**
   * Get attack speed of a player
   * @return float milliseconds between attacks
   */
  this.getAttackSpeed = Type.isNpc(this._entity) ?
    () => this._entity.getAttribute('speed') * 1000 || 1000 :
    secondAttack => {
      const weapon  = secondAttack ? this.getWeapon() : this.getOffhand();

      const minimum = secondAttack ? 750 : 500;
      const maximum = 10 * 1000;

      const speedWithinBounds = _.setBounds(minimum, maximum);

      const unarmedSpeed    = this._entity.getAttribute('quickness');
      const weaponSpeed     = getWeaponSpeed(weapon, unarmedSpeed, 500);
      const attributesSpeed = unarmedSpeed * 500
        + this._entity.getAttribute('cleverness') * 250;

      const baseSpeed = maximum - weaponSpeed - attributesSpeed;

      util.log("Their base speed is ", baseSpeed);

      const speed = applyMods(baseSpeed, this.speedMods);

      util.log("Their modified speed is ", speed);

      return speedWithinBounds(speed);
    };

  this.getDodgeChance = () => {
    const dodgeSkill = Type.isPlayer(this._entity) ?
      this._entity.getSkills('dodging') + Random.roll() :
      this._entity.getAttribute('speed') + Random.roll();
    const dodgeBonus = Type.isPlayer(this._entity) ?
      this._entity.getAttribute('quickness')
      + Math.round(this._entity.getAttribute('cleverness') / 2) :
      this._entity.getAttribute('level') || 1;

    const dodgeChance = applyMods(dodgeSkill + dodgeBonus, this.dodgeMods);
    const dodgeWithinBounds = _.setBounds(5, 90);

    util.log('Base dodge chance is ', dodgeChance);
    return dodgeWithinBounds(dodgeChance);
  }

  this.getDesc = () => Type.isPlayer(this._entity) ?
    this._entity.getName() : this._entity.getShortDesc('en');

  this.getToHitChance = () => {
    //TODO: Weapon skills related to weapon type?
    //TODO: General combat skills?
    // Replace 1 with skill get.
    const toHitSkill = this._entity.getAttribute('level') + Random.roll(); //For now, 1-20.
    const toHitBonus = this._entity.getAttribute('cleverness')
      + Math.round(this._entity.getAttribute('quickness') / 2);
    const toHitChance = applyMods(toHitSkill + toHitBonus, this.toHitMods);
    const toHitWithinBounds = _.setBounds(5, 90);
    util.log('To hit chance is ', toHitChance);
    return toHitWithinBounds(toHitChance);
  }

  this.getDefense = () => {
    //TODO: Replace with defense func from player.
    return this._entity.getAttribute('level') * 2;
  }

  this.getTarget = () => Type.isPlayer(this._entity) ?
    this._entity.getPreference('target') :
    this._entity.getAttribute('target');

  return this;
}

function getHelper(entity) {
  return new CombatHelper(entity);
}

exports.CombatHelper = CombatHelper;
exports.CombatUtil   = {
  getHelper, decideHitLocation
};
<commit_msg>Try to balance speed somewhat artificially.<commit_after>const util = require('util');

const Type   = require('./type').Type;
const Random = require('./random').Random;
const _ = require('./helpers');

/**
 * Helper func to decide where an attack lands
 * Unless the attacker is putting effort in being precise,
 * There is only a 50% chance their attack will hit its target.
 *
 * @param Array of locations to hit
 * @param String location being targeted
 * @param Boolean Is the attacker trying to be precise
 * @returns String location that get hit
 */
function decideHitLocation(locations, target, precise) {
  if (target && (precise || Random.coinFlip())) { return target; }
  return Random.fromArray(locations);
}

/** OVERVIEW ** //////////////////////////////
* The purpose of this class is to standardize
* the realtime combat API between players & NPCs.
*/

/**
* Generic func to apply all mods to a stat,
* starting with the base stat.
*/
const applyMod  = (stat, modifier) => modifier(stat)
const applyMods = (base, modsObj)  => _
  .reduceValues(modsObj, applyMod, base);

function CombatHelper(entity) {
  this._entity = entity;

  /*
   * Example modifier: {
      name: 'berserk',
      effect: damage => damage * 2
    }
   * Speed mods will affect time in between attacks
   * in milliseconds. So, doubling it will half attack speed.
   */
  this.speedMods   = {};
  this.damageMods  = {};
  this.toHitMods   = {};
  this.defenseMods = {};
  this.dodgeMods   = {};

  this.addMod = type =>
    modifier => this[type][modifier.name] = modifier.effect;

  this.addSpeedMod   = this.addMod('speedMods');
  this.addDamageMod  = this.addMod('damageMods');
  this.addToHitMod   = this.addMod('toHitMods');
  this.addDefenseMod = this.addMod('defenseMods');
  this.addDodgeMod   = this.addMod('dodgeMods');

  this.deleteMod = type =>
    name => delete this[type][name];

  this.removeSpeedMod   = this.deleteMod('speedMods');
  this.removeDamageMod  = this.deleteMod('damageMods');
  this.removeToHitMod   = this.deleteMod('toHitMods');
  this.removeDefenseMod = this.deleteMod('defenseMods');
  this.removeDodgeMod   = this.deleteMod('dodgeMods');

  this.deleteAllMods = name => {
    if (!name) { return false; } //TODO: Eventually, remove all mods?
    this.removeSpeedMod(name);
    this.removeDamageMod(name);
    this.removeToHitMod(name);
    this.removeDodgeMod(name);
    this.removeDefenseMod(name);
  };

  /**
   * Get hydrated primary or offhand weapon of player/npc.
   */
   //FIXME: Can be done better with changes to npc class.
   // Works, since this will let you get damage attr.
  this.getWeapon  = location => Type.isPlayer(this._entity) ?
    this._entity.getEquipped(location || 'wield', true) :
    () => this._entity;

  this.getOffhand = () => this.getWeapon('offhand');

  /**
   * Get just the name of the attack.
   */
  this.getAttackName = location => {
    const defaultWeapon = 'bare hands';
    if (Type.isPlayer(this._entity)) {
      const weapon = this.getWeapon(location);
      return weapon ?
        weapon.getShortDesc('en') :
        defaultWeapon;
    }
    return this._entity.getAttack('en') || defaultWeapon;
  }

  this.getPrimaryAttackName   = () => this.getAttackName('wield');
  this.getSecondaryAttackName = () => this.getAttackName('offhand');

  /**
  * Gets damage range from weapon obj
  * @param   Weapon obj
  * @param   Base possible damage for hand-to-hand
  * @return  Array of [min, max] damage range
  */
  const getWeaponDamage = (weapon, base) => weapon ?
    (weapon.getAttribute('damage') ?
      weapon.getAttribute('damage')
        .split('-')
        .map(dmg => parseInt(dmg, 10)) :
        base) :
      base;

  /**
   * Get the damage a player can do
   * @return int
   */
  this.getDamage = location => {
    location = location || 'wield';

    const self   = this._entity;
    const weapon = Type.isPlayer(self) ?
      this.getWeapon(location) :
      self;
    const base   = Type.isPlayer(self) ?
      [ 1, self.getAttribute('stamina') + 5 ] :
      [ 1, 20 ];

    const damageRange = getWeaponDamage(weapon, base);
    const damageRoll  = Random.inRange(...damageRange);

    const min = damageRange[0];
    const modifiedDamageRoll = applyMods(damageRoll, this.damageMods);

    const damageWithinBounds = _.setBounds(min, Infinity);
    const damageDealt = damageWithinBounds(modifiedDamageRoll);

    util.log('Deals damage: ', damageDealt);

    return damageDealt;
  };

  const getWeaponSpeed = (weapon, base, factor) => (weapon ?
    weapon.getAttribute('speed') : base) * factor;

  /**
   * Get attack speed of a player
   * @return float milliseconds between attacks
   */
  this.getAttackSpeed = Type.isNpc(this._entity) ?
    () => this._entity.getAttribute('speed') * 1000 || 1000 :
    secondAttack => {
      const weapon  = secondAttack ? this.getWeapon() : this.getOffhand();

      const minimum = secondAttack ? 750 : 500;
      const maximum = 10 * 1000;

      const speedWithinBounds = _.setBounds(minimum, maximum);

      const unarmedSpeed    = this._entity.getAttribute('quickness');
      const weaponSpeed     = getWeaponSpeed(weapon, unarmedSpeed, 500);
      const attributesSpeed = unarmedSpeed * 500
        + this._entity.getAttribute('cleverness') * 250;

      const baseSpeed = Math.min(maximum - weaponSpeed - attributesSpeed, 6000);

      util.log("Their base speed is ", baseSpeed);

      const speed = applyMods(baseSpeed, this.speedMods);

      util.log("Their modified speed is ", speed);

      return speedWithinBounds(speed);
    };

  this.getDodgeChance = () => {
    const dodgeSkill = Type.isPlayer(this._entity) ?
      this._entity.getSkills('dodging') + Random.roll() :
      this._entity.getAttribute('speed') + Random.roll();
    const dodgeBonus = Type.isPlayer(this._entity) ?
      this._entity.getAttribute('quickness')
      + Math.round(this._entity.getAttribute('cleverness') / 2) :
      this._entity.getAttribute('level') || 1;

    const dodgeChance = applyMods(dodgeSkill + dodgeBonus, this.dodgeMods);
    const dodgeWithinBounds = _.setBounds(5, 90);

    util.log('Base dodge chance is ', dodgeChance);
    return dodgeWithinBounds(dodgeChance);
  }

  this.getDesc = () => Type.isPlayer(this._entity) ?
    this._entity.getName() : this._entity.getShortDesc('en');

  this.getToHitChance = () => {
    //TODO: Weapon skills related to weapon type?
    //TODO: General combat skills?
    // Replace 1 with skill get.
    const toHitSkill = this._entity.getAttribute('level') + Random.roll(); //For now, 1-20.
    const toHitBonus = this._entity.getAttribute('cleverness')
      + Math.round(this._entity.getAttribute('quickness') / 2);
    const toHitChance = applyMods(toHitSkill + toHitBonus, this.toHitMods);
    const toHitWithinBounds = _.setBounds(5, 90);
    util.log('To hit chance is ', toHitChance);
    return toHitWithinBounds(toHitChance);
  }

  this.getDefense = () => {
    //TODO: Replace with defense func from player.
    return this._entity.getAttribute('level') * 2;
  }

  this.getTarget = () => Type.isPlayer(this._entity) ?
    this._entity.getPreference('target') :
    this._entity.getAttribute('target');

  return this;
}

function getHelper(entity) {
  return new CombatHelper(entity);
}

exports.CombatHelper = CombatHelper;
exports.CombatUtil   = {
  getHelper, decideHitLocation
};
<|endoftext|>


<commit_before>// Copyright 2002-2014, University of Colorado Boulder

/**
 * A round toggle button that switches the value of a property that can take on valueUp or valueDown.  It
 * sticks in the down position when pressed, popping back up when pressed
 * again.
 *
 * @author John Blanco
 * @author Sam Reid
 */
define( function( require ) {
  'use strict';

  // modules
  var inherit = require( 'PHET_CORE/inherit' );
  var RoundButtonView = require( 'SUN/buttons/RoundButtonView' );
  var StickyToggleButtonInteractionStateProperty = require( 'SUN/buttons/StickyToggleButtonInteractionStateProperty' );
  var StickyToggleButtonModel = require( 'SUN/buttons/StickyToggleButtonModel' );

  /**
   * @param {Object} valueUp value when the toggle is in the 'up' position
   * @param {Object} valueDown value when the toggle is in the 'down' position
   * @param {Property} property axon property that can be either valueUp or valueDown.
   * @param {Object} [options]
   * @constructor
   */
  function RoundStickyToggleButton( valueUp, valueDown, property, options ) {
    var buttonModel = new StickyToggleButtonModel( valueUp, valueDown, property );
    RoundButtonView.call( this, buttonModel, new StickyToggleButtonInteractionStateProperty( buttonModel ), options );
  }

  return inherit( RoundButtonView, RoundStickyToggleButton );
} );<commit_msg>add together support, see https://github.com/phetsims/color-vision/issues/90<commit_after>// Copyright 2002-2014, University of Colorado Boulder

/**
 * A round toggle button that switches the value of a property that can take on valueUp or valueDown.  It
 * sticks in the down position when pressed, popping back up when pressed
 * again.
 *
 * @author John Blanco
 * @author Sam Reid
 */
define( function( require ) {
  'use strict';

  // modules
  var inherit = require( 'PHET_CORE/inherit' );
  var RoundButtonView = require( 'SUN/buttons/RoundButtonView' );
  var StickyToggleButtonInteractionStateProperty = require( 'SUN/buttons/StickyToggleButtonInteractionStateProperty' );
  var StickyToggleButtonModel = require( 'SUN/buttons/StickyToggleButtonModel' );

  /**
   * @param {Object} valueUp value when the toggle is in the 'up' position
   * @param {Object} valueDown value when the toggle is in the 'down' position
   * @param {Property} property axon property that can be either valueUp or valueDown.
   * @param {Object} [options]
   * @constructor
   */
  function RoundStickyToggleButton( valueUp, valueDown, property, options ) {
    var buttonModel = new StickyToggleButtonModel( valueUp, valueDown, property );
    RoundButtonView.call( this, buttonModel, new StickyToggleButtonInteractionStateProperty( buttonModel ), options );

    // Tandem support
    // Give it a novel name to reduce the risk of parent or child collisions
    this.roundStickyToggleButtonTandem = options.tandem;
    this.roundStickyToggleButtonTandem && this.roundStickyToggleButtonTandem.addInstance( this );
  }

  return inherit( RoundButtonView, RoundStickyToggleButton );
} );<|endoftext|>


<commit_before>;(function ($, window, document, undefined) {
  'use strict';

  Foundation.libs.offcanvas = {
    name : 'offcanvas',

    version : '5.2.2',

    settings : {
      close_on_click: true,
    },

    init : function (scope, method, options) {
      this.bindings(method, options);
    },

    events : function () {
      var self = this,
          S = self.S;

      S(this.scope).off('.offcanvas')
        .on('click.fndtn.offcanvas', '.left-off-canvas-toggle', function (e) {
          self.click_toggle_class(e, 'move-right');
        })
        .on('click.fndtn.offcanvas', '.left-off-canvas-menu a', function (e) {
          var settings = self.get_settings(e)
          if (settings.close_on_click)
            S(".off-canvas-wrap").removeClass("move-right");
        })
        .on('click.fndtn.offcanvas', '.right-off-canvas-toggle', function (e) {
          self.click_toggle_class(e, 'move-left');
        })
        .on('click.fndtn.offcanvas', '.right-off-canvas-menu a', function (e) {
          var settings = self.get_settings(e)
          if (settings.close_on_click)
            S(".off-canvas-wrap").removeClass("move-left");
        })
        .on('click.fndtn.offcanvas', '.exit-off-canvas', function (e) {
          self.click_remove_class(e, 'move-left');
          self.click_remove_class(e, 'move-right');
        })
    },

    click_toggle_class: function(e, class_name) {
      e.preventDefault();
      this.S(e.target).closest('.off-canvas-wrap').toggleClass(class_name);
    },

    click_remove_class: function(e, class_name) {
      e.preventDefault();
      this.S('.off-canvas-wrap').removeClass(class_name);
    },

    get_settings: function(e) {
      var offcanvas  = this.S(e.target).closest('[' + this.attr_name() + ']')
      return offcanvas.data(this.attr_name(true) + '-init') || this.settings;
    },

    reflow : function () {}
  };
}(jQuery, this, this.document));
<commit_msg>Delete comma, add semicolon<commit_after>;(function ($, window, document, undefined) {
  'use strict';

  Foundation.libs.offcanvas = {
    name : 'offcanvas',

    version : '5.2.2',

    settings : {
      close_on_click: true
    },

    init : function (scope, method, options) {
      this.bindings(method, options);
    },

    events : function () {
      var self = this,
          S = self.S;

      S(this.scope).off('.offcanvas')
        .on('click.fndtn.offcanvas', '.left-off-canvas-toggle', function (e) {
          self.click_toggle_class(e, 'move-right');
        })
        .on('click.fndtn.offcanvas', '.left-off-canvas-menu a', function (e) {
          var settings = self.get_settings(e)
          if (settings.close_on_click)
            S(".off-canvas-wrap").removeClass("move-right");
        })
        .on('click.fndtn.offcanvas', '.right-off-canvas-toggle', function (e) {
          self.click_toggle_class(e, 'move-left');
        })
        .on('click.fndtn.offcanvas', '.right-off-canvas-menu a', function (e) {
          var settings = self.get_settings(e)
          if (settings.close_on_click)
            S(".off-canvas-wrap").removeClass("move-left");
        })
        .on('click.fndtn.offcanvas', '.exit-off-canvas', function (e) {
          self.click_remove_class(e, 'move-left');
          self.click_remove_class(e, 'move-right');
        })
    },

    click_toggle_class: function(e, class_name) {
      e.preventDefault();
      this.S(e.target).closest('.off-canvas-wrap').toggleClass(class_name);
    },

    click_remove_class: function(e, class_name) {
      e.preventDefault();
      this.S('.off-canvas-wrap').removeClass(class_name);
    },

    get_settings: function(e) {
      var offcanvas  = this.S(e.target).closest('[' + this.attr_name() + ']');
      return offcanvas.data(this.attr_name(true) + '-init') || this.settings;
    },

    reflow : function () {}
  };
}(jQuery, this, this.document));
<|endoftext|>


<commit_before>var dutils = {};
dutils.conf = {};

dutils.urls = function(){

    function _get_path(name, kwargs, urls)
    {

        var path = urls[name] || undefined;

        if (!path)
            throw('URL not found for view: ' + name);

        var _path = path;

        for (key in kwargs)
        {
            if (!path.match('\<' + key +'\>'))
                throw(key + ' does not exist in ' + _path);
            path = path.replace('\<' + key +'\>', kwargs[key]);
        }

        var re = new RegExp('\<[a-zA-Z0-9-_]{1,}\>', 'g');
        var missing_args = path.match(re);
        if (missing_args)
            throw('Missing arguments (' + missing_args.join(", ") + ') for url ' + _path);

        return path;

    }

    return {

        resolve: function(name, kwargs, urls) {
            if (!urls)
                urls = dutils.conf.urls || {};

            return _get_path(name, kwargs, urls);
        }

    }

}();<commit_msg>fixes for jslint compliance<commit_after>var dutils = {};
dutils.conf = {};

dutils.urls = function(){

    function _get_path(name, kwargs, urls)
    {

        var path = urls[name] || false;

        if (!path)
        {
            throw('URL not found for view: ' + name);
        }

        var _path = path;

        var key;
        for (key in kwargs)
        {
            if (kwargs.hasOwnProperty(key)) {
                if (!path.match('<' + key +'>'))
                {
                    throw(key + ' does not exist in ' + _path);
                }
                path = path.replace('<' + key +'>', kwargs[key]);
            }
        }

        var re = new RegExp('<[a-zA-Z0-9-_]{1,}>', 'g');
        var missing_args = path.match(re);
        if (missing_args)
        {
            throw('Missing arguments (' + missing_args.join(", ") + ') for url ' + _path);
        }

        return path;

    }

    return {

        resolve: function(name, kwargs, urls) {
            if (!urls)
            {
                urls = dutils.conf.urls || {};
            }

            return _get_path(name, kwargs, urls);
        }

    };

}();
<|endoftext|>


<commit_before>import React, { Component } from "react";
import Login from "../Login/Login";
import App from "../App/App";
import "./Main.css";

class Main extends Component {
	constructor(props) {
		super(props);
		this.state = {
			userInfo: {
				token: "",
				username: "",
				role: ""
			}
		};
		this.rememberUserInfo = this.rememberUserInfo.bind(this);
		this.forgetUserInfo = this.forgetUserInfo.bind(this);
	}

	// This function will remember the token, username and  when the server gives it for the very first time
	// It'll store it in local storage with key : "aiims-login-token" and then reload the browser.
	// It'll also keep it in state of the Main component, so that it can be passed to other components.
	rememberUserInfo(token, username, role) {
		this.setState({
			userInfo: {
				token: token,
				username: username,
				role: role
			}
		});
		localStorage["aiims-login-token"] = JSON.stringify(token);
		localStorage["aiims-login-username"] = JSON.stringify(username);
		localStorage["aiims-login-role"] = JSON.stringify(role);
		window.location.reload();
	}

	// ForgetToken will remove token from local storage and reset the token key in state of Main component.
	// It'll be fired when the user hits logout.
	forgetUserInfo() {
		this.setState({
			userInfo: {
				token: "",
				username: "",
				role: ""
			}
		});
		delete window.localStorage["aiims-login-token"];
		delete window.localStorage["aiims-login-username"];
		delete window.localStorage["aiims-login-role"];
		window.location.reload();
	}

	// This function is important for browser to know what to render depending upon what's
	// in the local storage.
	componentWillMount() {
		if (!localStorage["aiims-login-token"]) {
			return <Login userInfo={this.rememberUserInfo} />;
		} else {
			return <App userInfo={this.state.userInfo} />;
		}
	}

	// Render function will render everything. Nothing much is added to it yet,
	render() {
		if (!localStorage["aiims-login-token"]) {
			return <Login userInfo={this.rememberUserInfo} />;
		} else {
			return <App userInfo={this.state.userInfo} />;
		}
	}
}

export default Main;
<commit_msg>Fix code duplication issue<commit_after>import React, { Component } from "react";
import Login from "../Login/Login";
import App from "../App/App";
import "./Main.css";

class Main extends Component {
	constructor(props) {
		super(props);
		this.state = {
			userInfo: {
				token: "",
				username: "",
				role: ""
			}
		};
		this.rememberUserInfo = this.rememberUserInfo.bind(this);
		this.forgetUserInfo = this.forgetUserInfo.bind(this);
		this.createApp = this.createApp.bind(this);
	}

	// This function will remember the token, username and  when the server gives it for the very first time
	// It'll store it in local storage with key : "aiims-login-token" and then reload the browser.
	// It'll also keep it in state of the Main component, so that it can be passed to other components.
	rememberUserInfo(token, username, role) {
		this.setState({
			userInfo: {
				token: token,
				username: username,
				role: role
			}
		});
		localStorage["aiims-login-token"] = JSON.stringify(token);
		localStorage["aiims-login-username"] = JSON.stringify(username);
		localStorage["aiims-login-role"] = JSON.stringify(role);
		window.location.reload();
	}

	// ForgetToken will remove token from local storage and reset the token key in state of Main component.
	// It'll be fired when the user hits logout.
	forgetUserInfo() {
		this.setState({
			userInfo: {
				token: "",
				username: "",
				role: ""
			}
		});
		delete window.localStorage["aiims-login-token"];
		delete window.localStorage["aiims-login-username"];
		delete window.localStorage["aiims-login-role"];
		window.location.reload();
	}

	createApp() {
		if (!localStorage["aiims-login-token"]) {
			return <Login userInfo={this.rememberUserInfo} />;
		} else {
			return <App userInfo={this.state.userInfo} />;
		}
	}

	// This function is important for browser to know what to render depending upon what's
	// in the local storage.
	componentWillMount() {
		createApp();
	}

	// Render function will render everything. Nothing much is added to it yet,
	render() {
		createApp();
	}
}

export default Main;
<|endoftext|>


<commit_before>var path = require('path');
var fs = require('fs-extra');
var colors = require('colors');
var mockGenByCases = require('swagger-mock-file-generator-by-cases');
var mockGen = require('swagger-mock-file-generator');
var express = require('express');
var middleware = require('swagger-express-middleware-with-chance');
var inquirer = require('inquirer');
var cli = require('../util/cli');
var apiCasesMiddleware = require('api-cases-middleware');
var proxyMiddleware = require('express-proxy-middleware');
var juicerAdapter = require('juicer-express-adapter');
var chokidar = require('chokidar');
var getConfig = require('../api-creators/getConfigData.js');
var Finder = require('fs-finder');

module.exports = {
    create: create
};

var mock = {
    server: null,
    swaggerFilePath: '',
    configFilePath: '',
    options: '',
    cb: null
};

function create(swaggerFile, options, cb) {
    mock.swaggerFilePath = swaggerFile;
    mock.options = options;
    mock.cb = cb;
    var mockFilePath = options.file;
    var port = options.server;

    if (!/(\.json|\.yaml)$/.test(swaggerFile)) {
        console.log('需要json或yaml格式的swagger文件'.red);
        throw new Error();
    } else {
        fs.access(swaggerFile, fs.R_OK, function(err) {
            if (err) {
                console.log(swaggerFile + '该swagger文件不存在或无读权限'.red);
                throw new Error();
            } else {
                if (mockFilePath) {
                    mockGen(swaggerFile, mockFilePath, function(err) {
                        if (err) throw err;
                        mockConfig(mock.options);
                        // console.log('含有mock数据的swagger文件生成成功:'+ mockFilePath.green)
                        // console.log('使用含有mock数据的swagger文件启动Mock Server'.green);
                    })
                } else {
                    if (port) {
                        // console.log('使用'+ swaggerFile +'文件启动Mock Server'.green);
                        runMockServer(swaggerFile, port);
                   }
                }
            }
        })
    }
}

function mockGenByCaseFunc () {
    var config = require(path.resolve(mock.configFilePath));
    if (config.mockDir) {
        var mockDir = `./${config.mockDir}/`;
        if (!fs.existsSync(mockDir)) {
            try {
                fs.mkdirSync(mockDir);
                questionAndGen(mockDir);
            } catch (error) {
                console.log('配置文件中的mockDir设置无效'.red);
                runMockServer(mock.swaggerFilePath, mock.options.server);
                return;
            }
        } else {
            questionAndGen(mockDir);
        }
    } else {
        // no matter what happens
        // run mock server
        runMockServer(mock.swaggerFilePath, mock.options.server);
    }
}

function questionAndGen(mockDir) {
    var mockFileByCasesQuestion = { name: 'mock', message: `是否以${mockDir}文件夹初始化swagger文件的mock数据?`, type: 'confirm', default: true };
    inquirer.prompt(mockFileByCasesQuestion).then(function(answers) {
        if (answers.mock) {
            mockGenByCases(mock.swaggerFilePath, mockDir, function(err) {
                if (err) throw err;
                runMockServer(mock.swaggerFilePath, mock.options.server);
            })
        } else {
            runMockServer(mock.swaggerFilePath, mock.options.server);
        }
    })
}
const createConfigQuestion = { name: 'create', message: '是否需要生成默认配置文件?', type: 'confirm', default: true };
const useDefaultQuestion = { name: 'useDefault', message: '是否需要使用默认配置文件?', type: 'confirm', default: true };
function mockConfig(options) {
    var configPath = options.config || '';
    var hasLite = options.lite;
    var mockFilePath = options.file;
    var port = options.server;
    var defaultConfigPath = path.resolve(path.join(mockFilePath, '..') + '/mock.config.js');
    mock.configFilePath = configPath;
    //默认文件是否存在
    if (!configPath && !hasLite) {
        if (!fs.existsSync(defaultConfigPath)) {
            inquirer.prompt(createConfigQuestion).then(function(answers) {
                if (answers.create) {
                    mock.configFilePath = defaultConfigPath;
                    fs.writeFile(mock.configFilePath, '', (err) => {
                        if (err) throw err;
                        var mockCB = mockGenByCaseFunc();
                        createDefaultConfigFile(mockCB);
                    });
                } else {
                    Finder.from(path.join(options.file, '..')).findFiles('mock.config.js', function(files) {
                        if (files) {
                            inquirer.prompt(useDefaultQuestion).then(function(answers) {
                                if (answers.useDefault) {
                                    // 默认路径
                                    configPath = files[0];
                                    mock.configFilePath = configPath;
                                    mockGenByCaseFunc();
                                } else {
                                    runMockServer(mock.swaggerFilePath, mock.options.server);
                                }
                            });
                        } else {
                            runMockServer(options.file, options.server);
                        }
                    });
                }
            });
        } else {
            // 找到默认配置文件
            mockGenByCaseFunc();
        }
    } else if (configPath && !hasLite) {
        mockGenByCaseFunc();
    } else {
        runMockServer(options.file, options.server);
    }
    return configPath;
}

function runMockServer(swaggerFile, port) {
    var swagger = swaggerFile;
    var port = isNaN(parseInt(port)) ? 8000 : parseInt(port);
    // Set the DEBUG environment variable to enable debug output
    process.env.DEBUG = 'swagger:middleware';
    var app = express();
    middleware(swagger, app, function(err, middleware) {
        app.use(
            middleware.metadata(),
            middleware.CORS(),
            middleware.files(),
            middleware.parseRequest(),
            // middleware.validateRequest(),
            proxyMiddleware(mock.configFilePath),
            apiCasesMiddleware(mock.configFilePath),
            middleware.mock()
        );

        mock.server = app.listen(port, function() {
            openHotReload();
            console.log('The mock server is now running at http://localhost:' + port);
        });
    });
}

function openHotReload() {
    var paths = [mock.swaggerFilePath, mock.configFilePath];
    paths.forEach((path) => {
        if (path && fs.existsSync(path)) {
            chokidar.watch(path).on('change', (event, path) => {
                mock.server.close();
                console.log('重新生成mock数据并重启Mock Server......'.green);
                create(mock.swaggerFilePath, mock.options, mock.cb);
            });
        }
    })
}

function createDefaultConfigFile(cb) {
    if (!mock.configFilePath) {
        console.log('读取默认配置文件路径出错'.red);
        cb(mock.options.file, mock.options.server);
    } else {
        var config = getConfig({ file: mock.swaggerFilePath });
        if (config && config.swagger && config.swagger.paths) {
            juicerAdapter(path.join(__dirname, '../../templates/mock/config-template.juicer'), config, function(err, str) {
                outPutFile(mock.configFilePath, str, cb);
            })
        } else {
            cb(mock.options.file, mock.options.server);
            console.log('读取swagger文件配置出错'.red);
        }
    }
}

function outPutFile(filePath, str, cb) {
    fs.outputFile(filePath, str, function(err) {
        if (err) {
            throw err;
        }
        cb(mock.options.file, mock.options.server);
        console.log(('生成默认配置文件成功!文件位置: ' + filePath).green);
    })
}
<commit_msg>fix(mock.js): set config file path when exist<commit_after>var path = require('path');
var fs = require('fs-extra');
var colors = require('colors');
var mockGenByCases = require('swagger-mock-file-generator-by-cases');
var mockGen = require('swagger-mock-file-generator');
var express = require('express');
var middleware = require('swagger-express-middleware-with-chance');
var inquirer = require('inquirer');
var cli = require('../util/cli');
var apiCasesMiddleware = require('api-cases-middleware');
var proxyMiddleware = require('express-proxy-middleware');
var juicerAdapter = require('juicer-express-adapter');
var chokidar = require('chokidar');
var getConfig = require('../api-creators/getConfigData.js');
var Finder = require('fs-finder');

module.exports = {
    create: create
};

var mock = {
    server: null,
    swaggerFilePath: '',
    configFilePath: '',
    options: '',
    cb: null
};
var createConfigQuestion = { name: 'create', message: '是否需要生成默认配置文件?', type: 'confirm', default: true };
var useDefaultQuestion = { name: 'useDefault', message: '是否需要使用默认配置文件?', type: 'confirm', default: true };

function create(swaggerFile, options, cb) {
    mock.swaggerFilePath = swaggerFile;
    mock.options = options;
    mock.cb = cb;
    var mockFilePath = options.file;
    var port = options.server;

    if (!/(\.json|\.yaml)$/.test(swaggerFile)) {
        console.log('需要json或yaml格式的swagger文件'.red);
        throw new Error();
    } else {
        fs.access(swaggerFile, fs.R_OK, function(err) {
            if (err) {
                console.log(swaggerFile + '该swagger文件不存在或无读权限'.red);
                throw new Error();
            } else {
                if (mockFilePath) {
                    mockGen(swaggerFile, mockFilePath, function(err) {
                        if (err) throw err;
                        mockConfig(mock.options);
                        // console.log('含有mock数据的swagger文件生成成功:'+ mockFilePath.green)
                        // console.log('使用含有mock数据的swagger文件启动Mock Server'.green);
                    })
                } else {
                    if (port) {
                        // console.log('使用'+ swaggerFile +'文件启动Mock Server'.green);
                        runMockServer(swaggerFile, port);
                   }
                }
            }
        })
    }
}

function mockGenByCaseFunc () {
    var config = require(path.resolve(mock.configFilePath));
    if (config.mockDir) {
        var mockDir = `./${config.mockDir}/`;
        if (!fs.existsSync(mockDir)) {
            try {
                fs.mkdirSync(mockDir);
                questionAndGen(mockDir);
            } catch (error) {
                console.log('配置文件中的mockDir设置无效'.red);
                runMockServer(mock.swaggerFilePath, mock.options.server);
                return;
            }
        } else {
            questionAndGen(mockDir);
        }
    } else {
        // no matter what happens
        // run mock server
        runMockServer(mock.swaggerFilePath, mock.options.server);
    }
}

function questionAndGen(mockDir) {
    var mockFileByCasesQuestion = { name: 'mock', message: `是否以${mockDir}文件夹初始化swagger文件的mock数据?`, type: 'confirm', default: true };
    inquirer.prompt(mockFileByCasesQuestion).then(function(answers) {
        if (answers.mock) {
            mockGenByCases(mock.swaggerFilePath, mockDir, function(err) {
                if (err) throw err;
                runMockServer(mock.swaggerFilePath, mock.options.server);
            })
        } else {
            runMockServer(mock.swaggerFilePath, mock.options.server);
        }
    })
}

function mockConfig(options) {
    var configPath = options.config || '';
    var hasLite = options.lite;
    var mockFilePath = options.file;
    var port = options.server;
    var defaultConfigPath = path.resolve(path.join(mockFilePath, '..') + '/mock.config.js');
    mock.configFilePath = configPath;
    //默认文件是否存在
    if (!configPath && !hasLite) {
        if (!fs.existsSync(defaultConfigPath)) {
            inquirer.prompt(createConfigQuestion).then(function(answers) {
                if (answers.create) {
                    mock.configFilePath = defaultConfigPath;
                    fs.writeFile(mock.configFilePath, '', (err) => {
                        if (err) throw err;
                        var mockCB = mockGenByCaseFunc();
                        createDefaultConfigFile(mockCB);
                    });
                } else {
                    Finder.from(path.join(options.file, '..')).findFiles('mock.config.js', function(files) {
                        if (files) {
                            inquirer.prompt(useDefaultQuestion).then(function(answers) {
                                if (answers.useDefault) {
                                    // 默认路径
                                    configPath = files[0];
                                    mock.configFilePath = configPath;
                                    mockGenByCaseFunc();
                                } else {
                                    runMockServer(mock.swaggerFilePath, mock.options.server);
                                }
                            });
                        } else {
                            runMockServer(options.file, options.server);
                        }
                    });
                }
            });
        } else {
            // 找到默认配置文件
            mock.configFilePath = defaultConfigPath;
            mockGenByCaseFunc();
        }
    } else if (configPath && !hasLite) {
        mockGenByCaseFunc();
    } else {
        runMockServer(options.file, options.server);
    }
    return configPath;
}

function runMockServer(swaggerFile, port) {
    var swagger = swaggerFile;
    var port = isNaN(parseInt(port)) ? 8000 : parseInt(port);
    // Set the DEBUG environment variable to enable debug output
    process.env.DEBUG = 'swagger:middleware';
    var app = express();
    middleware(swagger, app, function(err, middleware) {
        app.use(
            middleware.metadata(),
            middleware.CORS(),
            middleware.files(),
            middleware.parseRequest(),
            // middleware.validateRequest(),
            proxyMiddleware(mock.configFilePath),
            apiCasesMiddleware(mock.configFilePath),
            middleware.mock()
        );

        mock.server = app.listen(port, function() {
            openHotReload();
            console.log('The mock server is now running at http://localhost:' + port);
        });
    });
}

function openHotReload() {
    var paths = [mock.swaggerFilePath, mock.configFilePath];
    paths.forEach((path) => {
        if (path && fs.existsSync(path)) {
            chokidar.watch(path).on('change', (event, path) => {
                mock.server.close();
                console.log('重新生成mock数据并重启Mock Server......'.green);
                create(mock.swaggerFilePath, mock.options, mock.cb);
            });
        }
    })
}

function createDefaultConfigFile(cb) {
    if (!mock.configFilePath) {
        console.log('读取默认配置文件路径出错'.red);
        cb(mock.options.file, mock.options.server);
    } else {
        var config = getConfig({ file: mock.swaggerFilePath });
        if (config && config.swagger && config.swagger.paths) {
            juicerAdapter(path.join(__dirname, '../../templates/mock/config-template.juicer'), config, function(err, str) {
                outPutFile(mock.configFilePath, str, cb);
            })
        } else {
            cb(mock.options.file, mock.options.server);
            console.log('读取swagger文件配置出错'.red);
        }
    }
}

function outPutFile(filePath, str, cb) {
    fs.outputFile(filePath, str, function(err) {
        if (err) {
            throw err;
        }
        cb(mock.options.file, mock.options.server);
        console.log(('生成默认配置文件成功!文件位置: ' + filePath).green);
    })
}
<|endoftext|>


<commit_before>import BlockComponent from '../BlockComponent';
import InlineLayout from '../Layouts/inline';

export default class Paragraph extends BlockComponent {

	constructor(renderer, node, subComponents) {
		super(renderer, node, subComponents);

		this.lineViews = [];
		this.style = {};
	}

	async componentDidMount() {
		var refresh = await super.componentDidMount();

		if (refresh)
			await this.refresh();
	}

	getOffset(DOM, targetOffset) {

		// If this medthod was called, that means text node only in this component
		var offset = targetOffset;

		// Finding line view which contains range
		for (var index in this.lineViews) {
			var lineView = this.lineViews[index][0];

			if (range.intersectsNode(lineView))
				break;

			// Count length of text node before line view which contains range
			offset += lineView.childNodes[0].length;
		}

		return offset;
	}
/*
	getPosition(offset) {

		var count = offset;
		for (var index in this.lineViews) {
			var dom = this.lineViews[index][0];
			var textNode = dom.childNodes[0];

			if (textNode.length < count) {
				count -= textNode.length;
			} else {
				return {
					DOM: dom,
					offset: count
				};
			}
		}
	}
*/
	updateDOMs() {

		// sync dom of all components because original dom might be splited by inline layout
		this.subComponents.forEach(function(component) {

			var doms = [];
			for (var index in this.lineViews) {
				var lineView = this.lineViews[index];
				var dom = $(lineView).find('[shijiref=' + component.node.id + ']').first();

				if (dom.length) {
					doms.push(dom[0]);
				} else if (doms.length > 0 && !dom.length) {
					// Not found DOM anymore
					break;
				}
			}

			component.dom = (doms.length > 1) ? doms : doms[0];
		}.bind(this));
	}

	layout($DOM) {

		var offscreen = this.renderer.offscreen;

		return new Promise(function(resolve) {

			// Split by line by using offscreen
			var renderTask = offscreen.render($DOM);
			renderTask.then(function() {

				// Initializing offscreen
				offscreen.getContent()
					.css({
						whiteSpace: 'pre-wrap',
						wordBreak: 'break-all'
					});
				offscreen.resize(this.style.width, this.style.height);

				// Apply inline layout
				var layout = new InlineLayout(this, offscreen);
				try {
					this.lineViews = layout.grabLines($DOM[0]);
				} catch(e) {
					console.log(e);
					console.log($DOM);
				}

				this.updateDOMs();
//return resolve();
				// Clear all then re-append lines
				$DOM
					.empty()
					.append(this.lineViews);

				// Clear offscreen buffer
				offscreen.empty();

				resolve();

			}.bind(this));

		}.bind(this));
	}

	render() {

		// Figuring style
		var style = this.style = Object.assign({}, this.node.parent ? {
			width: this.node.parent.style.width
		} : {}, this.node.style || {});

		var text = this.node.text || '';

		// Create DOM
		var $DOM = $('<div>')
			.addClass('shiji-paragraph')
			.html(text.replace(/ /g, '&nbsp'))
			.css(style);

		this.dom = $DOM[0];

		if (this.subComponents)
			this.renderer.appendComponents(this, this.subComponents);

		return this.layout($DOM);
	}
}
<commit_msg>clear code<commit_after>import BlockComponent from '../BlockComponent';
import InlineLayout from '../Layouts/inline';

export default class Paragraph extends BlockComponent {

	constructor(renderer, node, subComponents) {
		super(renderer, node, subComponents);

		this.lineViews = [];
		this.style = {};
	}

	async componentDidMount() {
		var refresh = await super.componentDidMount();

		if (refresh)
			await this.refresh();
	}

	getOffset(DOM, targetOffset) {

		// If this medthod was called, that means text node only in this component
		var offset = targetOffset;

		// Finding line view which contains range
		for (var index in this.lineViews) {
			var lineView = this.lineViews[index][0];

			if (range.intersectsNode(lineView))
				break;

			// Count length of text node before line view which contains range
			offset += lineView.childNodes[0].length;
		}

		return offset;
	}

	updateDOMs() {

		// sync dom of all components because original dom might be splited by inline layout
		this.subComponents.forEach(function(component) {

			var doms = [];
			for (var index in this.lineViews) {
				var lineView = this.lineViews[index];
				var dom = $(lineView).find('[shijiref=' + component.node.id + ']').first();

				if (dom.length) {
					doms.push(dom[0]);
				} else if (doms.length > 0 && !dom.length) {
					// Not found DOM anymore
					break;
				}
			}

			component.dom = (doms.length > 1) ? doms : doms[0];
		}.bind(this));
	}

	layout($DOM) {

		var offscreen = this.renderer.offscreen;

		return new Promise(function(resolve) {

			// Split by line by using offscreen
			var renderTask = offscreen.render($DOM);
			renderTask.then(function() {

				// Initializing offscreen
				offscreen.getContent()
					.css({
						whiteSpace: 'pre-wrap',
						wordBreak: 'break-all'
					});
				offscreen.resize(this.style.width, this.style.height);

				// Apply inline layout
				var layout = new InlineLayout(this, offscreen);
				try {
					this.lineViews = layout.grabLines($DOM[0]);
				} catch(e) {
					console.log(e);
					console.log($DOM);
				}

				this.updateDOMs();
//return resolve();
				// Clear all then re-append lines
				$DOM
					.empty()
					.append(this.lineViews);

				// Clear offscreen buffer
				offscreen.empty();

				resolve();

			}.bind(this));

		}.bind(this));
	}

	render() {

		// Figuring style
		var style = this.style = Object.assign({}, this.node.parent ? {
			width: this.node.parent.style.width
		} : {}, this.node.style || {});

		var text = this.node.text || '';

		// Create DOM
		var $DOM = $('<div>')
			.addClass('shiji-paragraph')
			.html(text.replace(/ /g, '&nbsp'))
			.css(style);

		this.dom = $DOM[0];

		if (this.subComponents)
			this.renderer.appendComponents(this, this.subComponents);

		return this.layout($DOM);
	}
}
<|endoftext|>


<commit_before>/* ================================================================
 * mobile-driver by xdf(xudafeng[at]126.com)
 *
 * first created at : Tue Mar 17 2015 00:16:10 GMT+0800 (CST)
 *
 * ================================================================
 * Copyright xdf
 *
 * Licensed under the MIT License
 * You may not use this file except in compliance with the License.
 *
 * ================================================================ */

'use strict';

var _ = require('lodash');
var moment = require('moment');

_.moment = moment;

_.camelcase = function(str) {
  return str.split('-').reduce(function(str, word) {
    return str + word[0].toUpperCase() + word.slice(1);
  });
};

_.getConfig = function(program) {
  var cfg = {};

  program.options.forEach(function(item) {
    var key = _.camelcase(item.name());

    if (key in program) {

      if (typeof program[key] !== 'function') {
        cfg[key] = program[key];
      }
    }
  });
  return cfg;
};

module.exports = _;
<commit_msg>now can change dir<commit_after>/* ================================================================
 * mobile-driver by xdf(xudafeng[at]126.com)
 *
 * first created at : Tue Mar 17 2015 00:16:10 GMT+0800 (CST)
 *
 * ================================================================
 * Copyright xdf
 *
 * Licensed under the MIT License
 * You may not use this file except in compliance with the License.
 *
 * ================================================================ */

'use strict';

var _ = require('lodash');
var moment = require('moment');
var path = require('path');

_.moment = moment;

_.camelcase = function(str) {
  return str.split('-').reduce(function(str, word) {
    return str + word[0].toUpperCase() + word.slice(1);
  });
};

_.getConfig = function(program) {
  var cfg = {};

  program.options.forEach(function(item) {
    var key = _.camelcase(item.name());

    if (key in program) {

      if (typeof program[key] !== 'function') {
        if (key === 'cwd') {
          program[key] = path.resolve(process.cwd(), program[key] === './test' ? '' : program[key]);
        }

        cfg[key] = program[key];
      }
    }
  });

  return cfg;
};

module.exports = _;
<|endoftext|>


<commit_before>define([
	'knockout',
	'atlas-state',
	'text!./data-sources.html',
	'appConfig',
	'services/AuthAPI',
	'pages/Page',
	'utils/CommonUtils',
	'databindings',
	'./components/reports/person',
	'./components/reports/dashboard',
	'./components/reports/datadensity',
	'./components/reports/person',
	'./components/reports/visit',
	'./components/reports/condition',
	'./components/reports/conditionEra',
	'./components/reports/procedure',
	'./components/reports/drug',
	'./components/reports/drugEra',
	'./components/reports/measurement',
	'./components/reports/observation',
	'./components/reports/death',
	'./components/reports/achillesHeel',
	'less!./data-sources.less'
], function (
	ko,
	sharedState,
	view,
	config,
	authApi,
	Page,
	commonUtils
) {
	class DataSources extends Page {
		constructor(params) {
			super(params);

			this.reports = [{
					name: "Dashboard",
					path: "dashboard",
					component: "report-dashboard",
					summary: ko.observable()
				},
				{
					name: "Data Density",
					path: "datadensity",
					component: "report-datadensity",
				},
				{
					name: "Person",
					path: "person",
					component: "report-person",
				},
				{
					name: "Visit",
					path: "visit",
					component: "report-visit",
				},
				{
					name: "Condition Occurrence",
					path: "condition",
					component: "report-condition",
				},
				{
					name: "Condition Era",
					path: "conditionera",
					component: "report-condition-era",
				},
				{
					name: "Procedure",
					path: "procedure",
					component: "report-procedure",
				},
				{
					name: "Drug Exposure",
					path: "drug",
					component: "report-drug",
				},
				{
					name: "Drug Era",
					path: "drugera",
					component: "report-drug-era",
				},
				{
					name: "Measurement",
					path: "measurement",
					component: "report-measurement",
				},
				{
					name: "Observation",
					path: "observation",
					component: "report-observation",
				},
				{
					name: "Death",
					path: "death",
					component: "report-death",
				},
				{
					name: "Achilles Heel",
					path: "achillesheel",
					component: "report-achilles-heel",
				},
			];

			this.model = params.model;
			this.sources = sharedState.sources().filter(function (s) {
				return s.hasResults && s.hasCDM;
			});

			this.loadingReport = ko.observable(false);
			this.hasError = ko.observable(false);

			this.isReportLoading = ko.pureComputed(function () {
				return this.loadingReport() && !this.hasError() && !this.model.loadingReportDrilldown();
			}, this);

			this.isAuthenticated = authApi.isAuthenticated;
			this.canViewCdmResults = ko.pureComputed(() => {
				return (config.userAuthenticationEnabled && this.isAuthenticated() && authApi.isPermittedViewCdmResults()) || !config.userAuthenticationEnabled;
			});

			this.showSelectionArea = params.showSelectionArea == undefined ? true : params.showSelectionArea;
			this.currentSource = ko.observable(this.sources[0]);
			this.currentReport = ko.observable();
			this.selectedReport = ko.observable();

			this.selectedReportSubscription = this.selectedReport.subscribe(r => {
				this.updateLocation();
			});

			this.selectedSourceSubscription = this.currentSource.subscribe(r => {
				this.updateLocation();
			})

			this.currentConcept = ko.observable();
		}

		dispose() {
			this.selectedReportSubscription.dispose();
			this.selectedSourceSubscription.dispose();
		}

		updateLocation() {
			if (this.currentSource() && this.selectedReport()) {
				document.location = "#/datasources/" + this.currentSource().sourceKey + "/" + this.selectedReport().path;
			}
		}

		onRouterParamsChanged(changedParams, newParams) {
			if (newParams == null && changedParams == null)
				return;

			if (newParams == null) {
				// initial page load direct from URL
				this.currentSource(this.sources.find(s => s.sourceKey == changedParams.sourceKey));
				this.currentReport(this.reports.find(r => r.path == changedParams.reportName));
				this.selectedReport(this.reports.find(r => r.path == changedParams.reportName));
			} else {
				if (changedParams.sourceKey) {
					this.currentSource(this.sources.find(s => s.sourceKey == newParams.sourceKey));
				}
				if (changedParams.reportName) {
					this.currentReport(this.reports.find(r => r.path == newParams.reportName));
					this.selectedReport(this.reports.find(r => r.path == newParams.reportName));
				}
			}
		}
	}

	return commonUtils.build('data-sources', DataSources, view);
});<commit_msg>Use DS with result & vocabulary daimons for Data Source tab (#1236)<commit_after>define([
	'knockout',
	'atlas-state',
	'text!./data-sources.html',
	'appConfig',
	'services/AuthAPI',
	'pages/Page',
	'utils/CommonUtils',
	'databindings',
	'./components/reports/person',
	'./components/reports/dashboard',
	'./components/reports/datadensity',
	'./components/reports/person',
	'./components/reports/visit',
	'./components/reports/condition',
	'./components/reports/conditionEra',
	'./components/reports/procedure',
	'./components/reports/drug',
	'./components/reports/drugEra',
	'./components/reports/measurement',
	'./components/reports/observation',
	'./components/reports/death',
	'./components/reports/achillesHeel',
	'less!./data-sources.less'
], function (
	ko,
	sharedState,
	view,
	config,
	authApi,
	Page,
	commonUtils
) {
	class DataSources extends Page {
		constructor(params) {
			super(params);

			this.reports = [{
					name: "Dashboard",
					path: "dashboard",
					component: "report-dashboard",
					summary: ko.observable()
				},
				{
					name: "Data Density",
					path: "datadensity",
					component: "report-datadensity",
				},
				{
					name: "Person",
					path: "person",
					component: "report-person",
				},
				{
					name: "Visit",
					path: "visit",
					component: "report-visit",
				},
				{
					name: "Condition Occurrence",
					path: "condition",
					component: "report-condition",
				},
				{
					name: "Condition Era",
					path: "conditionera",
					component: "report-condition-era",
				},
				{
					name: "Procedure",
					path: "procedure",
					component: "report-procedure",
				},
				{
					name: "Drug Exposure",
					path: "drug",
					component: "report-drug",
				},
				{
					name: "Drug Era",
					path: "drugera",
					component: "report-drug-era",
				},
				{
					name: "Measurement",
					path: "measurement",
					component: "report-measurement",
				},
				{
					name: "Observation",
					path: "observation",
					component: "report-observation",
				},
				{
					name: "Death",
					path: "death",
					component: "report-death",
				},
				{
					name: "Achilles Heel",
					path: "achillesheel",
					component: "report-achilles-heel",
				},
			];

			this.model = params.model;
			this.sources = sharedState.sources().filter(function (s) {
				return s.hasResults && s.hasVocabulary;
			});

			this.loadingReport = ko.observable(false);
			this.hasError = ko.observable(false);

			this.isReportLoading = ko.pureComputed(function () {
				return this.loadingReport() && !this.hasError() && !this.model.loadingReportDrilldown();
			}, this);

			this.isAuthenticated = authApi.isAuthenticated;
			this.canViewCdmResults = ko.pureComputed(() => {
				return (config.userAuthenticationEnabled && this.isAuthenticated() && authApi.isPermittedViewCdmResults()) || !config.userAuthenticationEnabled;
			});

			this.showSelectionArea = params.showSelectionArea == undefined ? true : params.showSelectionArea;
			this.currentSource = ko.observable(this.sources[0]);
			this.currentReport = ko.observable();
			this.selectedReport = ko.observable();

			this.selectedReportSubscription = this.selectedReport.subscribe(r => {
				this.updateLocation();
			});

			this.selectedSourceSubscription = this.currentSource.subscribe(r => {
				this.updateLocation();
			})

			this.currentConcept = ko.observable();
		}

		dispose() {
			this.selectedReportSubscription.dispose();
			this.selectedSourceSubscription.dispose();
		}

		updateLocation() {
			if (this.currentSource() && this.selectedReport()) {
				document.location = "#/datasources/" + this.currentSource().sourceKey + "/" + this.selectedReport().path;
			}
		}

		onRouterParamsChanged(changedParams, newParams) {
			if (newParams == null && changedParams == null)
				return;

			if (newParams == null) {
				// initial page load direct from URL
				this.currentSource(this.sources.find(s => s.sourceKey == changedParams.sourceKey));
				this.currentReport(this.reports.find(r => r.path == changedParams.reportName));
				this.selectedReport(this.reports.find(r => r.path == changedParams.reportName));
			} else {
				if (changedParams.sourceKey) {
					this.currentSource(this.sources.find(s => s.sourceKey == newParams.sourceKey));
				}
				if (changedParams.reportName) {
					this.currentReport(this.reports.find(r => r.path == newParams.reportName));
					this.selectedReport(this.reports.find(r => r.path == newParams.reportName));
				}
			}
		}
	}

	return commonUtils.build('data-sources', DataSources, view);
});<|endoftext|>


<commit_before>// aliases<commit_msg>add compatibility aliases<commit_after>var mathTrig = require('./math-trig');

exports.CEILINGMATH = mathTrig.CEILING.MATH;
exports.CEILINGPRECISE = mathTrig.CEILING.PRECISE;
exports.FLOORMATH = mathTrig.FLOOR.MATH;
exports.FLOORPRECISE = mathTrig.FLOOR.PRECISE;
exports.ISOCEILING = exports.ISO.CEILING;<|endoftext|>


<commit_before>
/*!
 * Ext JS Connect 0.0.1
 * Copyright(c) 2010 Ext JS, Inc.
 * MIT Licensed
 */

/**
 * Framework version.
 */

require('./proto');

exports.version = '0.0.1';

/**
 * Module dependencies.
 */

var sys = require('sys'),
    url = require('url'),
    path = require('path'),
    http = require('http');

// Response extensions

require('./response')

// chdir to CONNECT_CWD when present

if (process.env.CONNECT_CWD) {
    process.chdir(process.env.CONNECT_CWD);
}

// Runtime environment

var envName = process.env.CONNECT_ENV || 'development';

// Path to configuration module

var configPath = path.join(process.cwd(), 'config', envName);

// Connect environment configuration.

var env = exports.env = require(configPath);

// Defaults

env.name = envName;
env.port = env.port || process.env.CONNECT_SOCKET;

var Layer = function Layer(config) {
    if (!(config.provider || config.filter || config.module)) {
        throw new Error("Must provide either 'provider', 'filter', or 'module' in layer config");
    }

    if (config.provider) {
        config.module = require("./providers/" + config.provider);
        this.name = config.provider;
    }
    else if (config.filter) {
        config.module = require("./filters/" + config.filter);
        this.name = config.filter;
    }

    if (config.module.name) {
        this.name = config.module.name;
    }

    if (config.param) {
        config.params = [config.param];
    }

    this.mixin(config.module);

    this.route = config.route || this.route;
    this.config = config;

    config.params = config.params || [];
    config.params.unshift(env);

    if (this.setup) {
        this.setup.apply(this, config.params);
    }
};
Layer.prototype = {
    route: '/',
    handle: function handle(req, res, next) {
        sys.debug("Warning: " + this.name + " middleware is missing handle");
        next(req, res);
    },
    name: "unnamed"
};

/**
 * Run the given middleware configurations.
 *
 * The first value in each configuration array
 * may be an string or array of paths to match,
 * followed by the module object or name. All additional
 * arguments are passed to the optional setup function.
 *
 *   Connect.run(
 *      { filter: "log" },
 *      { provider: "static", param: __dirname + '/public' }
 *   )
 *
 * @param  {Array} middleware
 * @return {Server}
 * @api public
 */

exports.run = function run(configs, port) {
    var stack = [];
    configs.push({ provider: "404" });
    configs.forEach(function(config) {
        if (config.route instanceof Array) {
            config.route.forEach(function (route) {
                config.route = route;
                stack.push(new Layer(config));
            });
            return;
        }
        stack.push(new Layer(config));
    });

    var server = http.createServer(function(req, res){
        req.url = url.parse(req.url);

        var pathname = req.url.pathname,
            index = 0,
            scope = {};

        function next(req, res) {
            var layer = stack[index++];
            if (pathname.indexOf(layer.route) === 0) {
                return layer.handle(req, res, next, scope);
            }
            next(res, req);
        }
        next(req, res);
    });

    server.listen(server.port = port || env.port);
    return server;
}<commit_msg>Self-calling next()<commit_after>
/*!
 * Ext JS Connect 0.0.1
 * Copyright(c) 2010 Ext JS, Inc.
 * MIT Licensed
 */

/**
 * Framework version.
 */

require('./proto');

exports.version = '0.0.1';

/**
 * Module dependencies.
 */

var sys = require('sys'),
    url = require('url'),
    path = require('path'),
    http = require('http');

// Response extensions

require('./response')

// chdir to CONNECT_CWD when present

if (process.env.CONNECT_CWD) {
    process.chdir(process.env.CONNECT_CWD);
}

// Runtime environment

var envName = process.env.CONNECT_ENV || 'development';

// Path to configuration module

var configPath = path.join(process.cwd(), 'config', envName);

// Connect environment configuration.

var env = exports.env = require(configPath);

// Defaults

env.name = envName;
env.port = env.port || process.env.CONNECT_SOCKET;

var Layer = function Layer(config) {
    if (!(config.provider || config.filter || config.module)) {
        throw new Error("Must provide either 'provider', 'filter', or 'module' in layer config");
    }

    if (config.provider) {
        config.module = require("./providers/" + config.provider);
        this.name = config.provider;
    }
    else if (config.filter) {
        config.module = require("./filters/" + config.filter);
        this.name = config.filter;
    }

    if (config.module.name) {
        this.name = config.module.name;
    }

    if (config.param) {
        config.params = [config.param];
    }

    this.mixin(config.module);

    this.route = config.route || this.route;
    this.config = config;

    config.params = config.params || [];
    config.params.unshift(env);

    if (this.setup) {
        this.setup.apply(this, config.params);
    }
};
Layer.prototype = {
    route: '/',
    handle: function handle(req, res, next) {
        sys.debug("Warning: " + this.name + " middleware is missing handle");
        next(req, res);
    },
    name: "unnamed"
};

/**
 * Run the given middleware configurations.
 *
 * The first value in each configuration array
 * may be an string or array of paths to match,
 * followed by the module object or name. All additional
 * arguments are passed to the optional setup function.
 *
 *   Connect.run(
 *      { filter: "log" },
 *      { provider: "static", param: __dirname + '/public' }
 *   )
 *
 * @param  {Array} middleware
 * @return {Server}
 * @api public
 */

exports.run = function run(configs, port) {
    var stack = [];
    configs.push({ provider: "404" });
    configs.forEach(function(config) {
        if (config.route instanceof Array) {
            config.route.forEach(function (route) {
                config.route = route;
                stack.push(new Layer(config));
            });
            return;
        }
        stack.push(new Layer(config));
    });

    var server = http.createServer(function(req, res){
        req.url = url.parse(req.url);

        var pathname = req.url.pathname,
            index = 0,
            scope = {};

        (function next(req, res) {
            var layer = stack[index++];
            if (pathname.indexOf(layer.route) === 0) {
                return layer.handle(req, res, next, scope);
            }
            next(res, req);
        })(req, res);
    });

    server.listen(server.port = port || env.port);
    return server;
}<|endoftext|>


<commit_before>/*
 * Copyright https://github.com/divio/django-cms
 */

// #############################################################################
// NAMESPACES
var CMS = window.CMS || {};
var apphooks_configuration = window.apphooks_configuration || {};

// #############################################################################
// APP HOOK SELECT
(function ($) {
    'use strict';

    // shorthand for jQuery(document).ready();
    $(function () {

        var appHooks = $('#application_urls'),
            selected = appHooks.find('option:selected'),
            appNsRow = $('.form-row.application_namespace'),
            appNs = appNsRow.find('#id_application_namespace'),
            appCfgsRow = $('.form-row.application_configs'),
            appCfgs = appCfgsRow.find('#application_configs'),
            appCfgsAdd = appCfgsRow.find('#add_application_configs'),
            original_ns = appNs.val();

        // Shows / hides namespace / config selection widgets depending on the user input
        appHooks.setupNamespaces = function () {
            var opt = $(this).find('option:selected');

            if ($(appCfgs).length > 0 && apphooks_configuration[opt.val()]) {
                appCfgs.html('');
                for (var i = 0; i < apphooks_configuration[opt.val()].length; i++) {
                    var selectedCfgs = '';
                    if (apphooks_configuration[opt.val()][i][0] === window.apphooks_configuration_value) {
                        selectedCfgs = 'selected="selected"';
                    }
                    appCfgs.append(
                        '<option ' + selectedCfgs + ' value="' + apphooks_configuration[opt.val()][i][0] + '">' +
                            apphooks_configuration[opt.val()][i][1] +
                        '</option>'
                    );
                }
                appCfgsAdd.attr('href', window.apphooks_configuration_url[opt.val()]);
                appCfgsRow.removeClass('hidden');
                appNsRow.addClass('hidden');
            } else {
                appCfgsRow.addClass('hidden');
                if (opt.data('namespace')) {
                    appNsRow.removeClass('hidden');
                } else {
                    appNsRow.addClass('hidden');
                }
            }
        };

        // Hide the namespace widgets if its not required.
        appHooks.setupNamespaces();

        // Show it if we change to an app_hook that requires a namespace
        appHooks.on('change', function () {
            var self = $(this),
                opt = self.find('option:selected');

            appHooks.setupNamespaces();

            // If we clear the app_hook, clear out the app_namespace too
            if (!self.val()) {
                appNs.val('');
                appNs.removeAttr('value');
            }

            // When selecting back the original apphook we try
            // to restore the original configuration
            if (selected.val() === opt.val()) {
                if (original_ns) {
                    appNs.val(original_ns);
                }
            } else if (opt.data('namespace')) {
                // If new apphook has a namespace, suggest the default
                appNs.val(opt.data('namespace'));
            } else {
                // Cleanup the whole thing
                appNs.val('');
                appNs.removeAttr('value');
            }
        });

    });
})(CMS.$);
<commit_msg>add `?_popup=1` to add apphook url<commit_after>/*
 * Copyright https://github.com/divio/django-cms
 */

// #############################################################################
// NAMESPACES
var CMS = window.CMS || {};
var apphooks_configuration = window.apphooks_configuration || {};

// #############################################################################
// APP HOOK SELECT
(function ($) {
    'use strict';

    // shorthand for jQuery(document).ready();
    $(function () {
        var appHooks = $('#application_urls'),
            selected = appHooks.find('option:selected'),
            appNsRow = $('.form-row.application_namespace'),
            appNs = appNsRow.find('#id_application_namespace'),
            appCfgsRow = $('.form-row.application_configs'),
            appCfgs = appCfgsRow.find('#application_configs'),
            appCfgsAdd = appCfgsRow.find('#add_application_configs'),
            original_ns = appNs.val();

        // Shows / hides namespace / config selection widgets depending on the user input
        appHooks.setupNamespaces = function () {
            var opt = $(this).find('option:selected');

            if ($(appCfgs).length > 0 && apphooks_configuration[opt.val()]) {
                appCfgs.html('');
                for (var i = 0; i < apphooks_configuration[opt.val()].length; i++) {
                    var selectedCfgs = '';
                    if (apphooks_configuration[opt.val()][i][0] === window.apphooks_configuration_value) {
                        selectedCfgs = 'selected="selected"';
                    }
                    appCfgs.append(
                        '<option ' + selectedCfgs + ' value="' + apphooks_configuration[opt.val()][i][0] + '">' +
                            apphooks_configuration[opt.val()][i][1] +
                        '</option>'
                    );
                }
                appCfgsAdd.attr('href', window.apphooks_configuration_url[opt.val()] +
                    // Here we check if we are on django>=1.8 by checking if the method introduced in that version
                    // exists, and if it does - we add `_popup` ourselves, because otherwise the popup with
                    // apphook creation form will not be dismissed correctly
                    (window.showRelatedObjectPopup ? '?_popup=1' : ''));
                appCfgsRow.removeClass('hidden');
                appNsRow.addClass('hidden');
            } else {
                appCfgsRow.addClass('hidden');
                if (opt.data('namespace')) {
                    appNsRow.removeClass('hidden');
                } else {
                    appNsRow.addClass('hidden');
                }
            }
        };

        // Hide the namespace widgets if its not required.
        appHooks.setupNamespaces();

        // Show it if we change to an app_hook that requires a namespace
        appHooks.on('change', function () {
            var self = $(this),
                opt = self.find('option:selected');

            appHooks.setupNamespaces();

            // If we clear the app_hook, clear out the app_namespace too
            if (!self.val()) {
                appNs.val('');
                appNs.removeAttr('value');
            }

            // When selecting back the original apphook we try
            // to restore the original configuration
            if (selected.val() === opt.val()) {
                if (original_ns) {
                    appNs.val(original_ns);
                }
            } else if (opt.data('namespace')) {
                // If new apphook has a namespace, suggest the default
                appNs.val(opt.data('namespace'));
            } else {
                // Cleanup the whole thing
                appNs.val('');
                appNs.removeAttr('value');
            }
        });

    });
})(CMS.$);
<|endoftext|>


<commit_before>!function(e){function r(i){if(s[i])return s[i].exports;var a=s[i]={exports:{},id:i,loaded:!1};return e[i].call(a.exports,a,a.exports,r),a.loaded=!0,a.exports}var s={};return r.m=e,r.c=s,r.p="",r(0)}([function(e,r,s){(function(e){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}var i=s(1),a=r(i),c=function(e,r){var s=r.scores.reduce(function(e,r){return e+=r}),i=s>=35,a=i?"green":"red",c=function(e,r){return"
"+e+"	"+r+"
"};return'
\n
Лабораторная работа #'+e+'
\n
\n
\n                    № Вопроса	\n                    Score	\n
\n
\n                    '+r.scores.reduce(function(e,r,s){return e+=c(s+1,r)},"")+"\n
\n
\n
\n                        Лабораторная работа: "+(i?"ПРИНЯТА":"НЕ ПРИНЯТА")+"	\n                        "+(i?"Итог: "+s+"	":"Причина: Недостаточно баллов или плагиат	")+"\n
\n
\n
\n
"},d=e(".js-search-btn"),t=e(".js-search-input"),n=e(".js-result-box");d.on("click",function(){yaCounter39419275.reachGoal("SEARCH_BTN_CLICKED");var e=t.val();n.empty();var r=a["default"].filter(function(r){return r.id==e});console.log(r[0]),r.length>0?n.append(c(1,r[0])):n.append("
Не найдено
")})}).call(r,s(2))},function(e,r){e.exports=[{id:"45e7b9c9bf8ec9a4",plagiarism:!0,scores:[20,0,20,20,20,10]},{id:"6f9bd3569dabb970",plagiarism:!0,scores:[20,10,0,5,20,20]},{id:"71309152d2683517",plagiarism:!0,scores:[20,20,10,0,20]},{id:"d5b16acd07a1ca5d",plagiarism:!0,scores:[20,20,0,10,20]},{id:"57c2a4e48a9a475c",plagiarism:!0,scores:[20,20,20,20]},{id:"067b3dc661ea7f78",plagiarism:!0,scores:[20,20,20,20,0,20]},{id:"b390e8dccf68ab55",plagiarism:!0,scores:[20,20,20,20,20,20]},{id:"82ef3508455ab64d",plagiarism:!0,scores:[20,20,20,0,20]},{id:"b842534d41f599e1",plagiarism:!0,scores:[20,0,0,20,20]},{id:"e01fcc7dd180f684",plagiarism:!0,scores:[20,0,0,20,0,20]},{id:"8412a4c82d485393",plagiarism:!0,scores:[0,12,12,0,0,0]},{id:"39abd267b19ec1d9",plagiarism:!0,scores:[12,10,15,12,0,10]},{id:"ee50e0a4afc194a2",plagiarism:!1,scores:[0,0,0,0,0]},{id:"2b4dc51c0d58bb01",plagiarism:!0,scores:[5,10,12,10,0]},{id:"3cd3ad8741297d74",plagiarism:!0,scores:[0,0,15,14,0,0]},{id:"9497d327806600e6",plagiarism:!0,scores:[0,0,10,12,6,0]},{id:"5cf298d66cef3118",plagiarism:!0,scores:[0,0,0,0]},{id:"b139289fdb35959f",scores:[0]},{id:"672ae2cf2c5c8bb2",scores:[0]},{id:"ef5b578fee80757f",scores:[0]},{id:"8e6a72fb97df1348",scores:[0]},{id:"d8c2d66969868265",scores:[0]},{id:"351d5b4ec0c3ba50",scores:[0]}]},function(e,r){e.exports=jQuery}]);<commit_msg>updated results<commit_after>!function(e){function r(i){if(s[i])return s[i].exports;var a=s[i]={exports:{},id:i,loaded:!1};return e[i].call(a.exports,a,a.exports,r),a.loaded=!0,a.exports}var s={};return r.m=e,r.c=s,r.p="",r(0)}([function(e,r,s){(function(e){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}var i=s(1),a=r(i),c=function(e,r){var s=r.scores.reduce(function(e,r){return e+=r}),i=s>=35,a=i?"green":"red",c=function(e,r){return"
"+e+"	"+r+"
"};return'
\n
Лабораторная работа #'+e+'
\n
\n
\n                    № Вопроса	\n                    Score	\n
\n
\n                    '+r.scores.reduce(function(e,r,s){return e+=c(s+1,r)},"")+"\n
\n
\n
\n                        Лабораторная работа: "+(i?"ПРИНЯТА":"НЕ ПРИНЯТА")+"	\n                        "+(i?"Итог: "+s+"	":"Причина: Недостаточно баллов или плагиат	")+"\n
\n
\n
\n
"},d=e(".js-search-btn"),t=e(".js-search-input"),n=e(".js-result-box");d.on("click",function(){yaCounter39419275.reachGoal("SEARCH_BTN_CLICKED");var e=t.val();n.empty();var r=a["default"].filter(function(r){return r.id==e});console.log(r[0]),r.length>0?n.append(c(1,r[0])):n.append("
Не найдено
")})}).call(r,s(2))},function(e,r){e.exports=[{id:"45e7b9c9bf8ec9a4",plagiarism:!0,scores:[20,0,20,20,20,10]},{id:"6f9bd3569dabb970",plagiarism:!0,scores:[20,10,0,5,20,20]},{id:"71309152d2683517",plagiarism:!0,scores:[20,20,10,0,20]},{id:"d5b16acd07a1ca5d",plagiarism:!0,scores:[20,20,0,10,20]},{id:"57c2a4e48a9a475c",plagiarism:!0,scores:[20,20,20,20]},{id:"067b3dc661ea7f78",plagiarism:!0,scores:[20,20,20,20,0,20]},{id:"b390e8dccf68ab55",plagiarism:!0,scores:[20,20,20,20,20,20]},{id:"82ef3508455ab64d",plagiarism:!0,scores:[20,20,20,0,20]},{id:"b842534d41f599e1",plagiarism:!0,scores:[20,0,0,20,20]},{id:"e01fcc7dd180f684",plagiarism:!0,scores:[20,0,0,20,0,20]},{id:"8412a4c82d485393",plagiarism:!0,scores:[0,12,12,0,0,0]},{id:"39abd267b19ec1d9",plagiarism:!0,scores:[12,10,15,12,0,10]},{id:"ee50e0a4afc194a2",plagiarism:!1,scores:[0,0,0,0,0]},{id:"2b4dc51c0d58bb01",plagiarism:!0,scores:[5,10,12,10,0]},{id:"3cd3ad8741297d74",plagiarism:!0,scores:[0,0,15,0,0,0]},{id:"9497d327806600e6",plagiarism:!0,scores:[15,0,10,12,6,0]},{id:"5cf298d66cef3118",plagiarism:!0,scores:[0,0,0,0]},{id:"b139289fdb35959f",scores:[0]},{id:"672ae2cf2c5c8bb2",scores:[0]},{id:"ef5b578fee80757f",scores:[0]},{id:"8e6a72fb97df1348",scores:[0]},{id:"d8c2d66969868265",scores:[0]},{id:"351d5b4ec0c3ba50",scores:[0]}]},function(e,r){e.exports=jQuery}]);<|endoftext|>