<commit_before>// Import React
import React from "react";

// Import Spectacle Core tags
import {
  Appear, BlockQuote, Cite, Deck, Heading, Layout, Fill, ListItem, List, Quote, Slide,
  Text, Table, TableHeaderItem, TableItem, TableRow
} from "spectacle";

import FontAwesome from 'react-fontawesome';

import Caseify from './Components/Caseify.jsx';

// Import image preloader util
import preloader from "spectacle/lib/utils/preloader";

// Import theme
import createTheme from "spectacle/lib/themes/default";

// Require CSS
require("normalize.css");
require("spectacle/lib/themes/default/index.css");

const images = {
  city: require("../assets/city.jpg"),
  kat: require("../assets/kat.png"),
  logo: require("../assets/formidable-logo.svg"),
  markdown: require("../assets/markdown.png"),
  yo: require("../assets/foto_presentacion.jpg")
};

preloader(images);

const theme = createTheme({
  primary: "white",
  secondary: "#1F2022",
  tertiary: "#03A9FC",
  quartenary: "#CECECE"
}, {
  primary: "Montserrat",
  secondary: "Helvetica"
});

export default class Presentation extends React.Component {
  render() {
    return (
      <Deck transition={["slide"]} transitionDuration={500} theme={theme}>
        <Slide bgColor="primary">
					<Heading size={1} fit lineHeight={1} textColor="secondary">RESTful APIs</Heading>
					<Text margin="10px 0 0" textColor="tertiary" size={6} bold>Buenas prácticas</Text>
				</Slide>

        <Slide bgColor="black">
					<Heading size={1} caps fit textColor="primary" textFont="primary">Quién soy?</Heading>
          <List textColor="primary">
					  <Appear><ListItem textColor="primary">Juan Manuel Cruz</ListItem></Appear>
            <Appear><ListItem textColor="primary">Estudiante</ListItem></Appear>
            <Appear><ListItem textColor="primary">Desarrollador</ListItem></Appear>
            <Appear><ListItem textColor="primary">Autodidacta</ListItem></Appear>
            <Appear><ListItem textColor="primary">Hacker</ListItem></Appear>
					</List>
					<Appear><Text textColor="tertiary"><FontAwesome name="twitter" size="lg"/> wroughtbywind</Text></Appear>
          <Appear><Text textColor="primary"><FontAwesome name="github" size="lg"/> Malows</Text></Appear>
				</Slide>

        <Slide bgColor="primary">
          <Heading size={3} fit lineHeight={1} textColor="secondary">¿Por qué usar APIs RESTful?</Heading>
          <List>
            <Appear><Text margin="30px 10px" textColor="tertiary" size={6}>Proque son geniales</Text></Appear>
            <Appear><Text margin="30px 10px" textColor="tertiary" size={6}>
              {"Porque la carga de transferencia en aplicaciones web isomorfas se hace solo al principio. Luego de la carga inicial solo se transfieren datos"}
            </Text></Appear>
          </List>
        </Slide>

        <Slide>
          <Heading size={1} lineHeight={1} textColor="secondary">{"???"}</Heading>
        </Slide>

        <Slide>
          <Heading size={3} lineHeight={1} textColor="secondary">{"¿Qué son?"}</Heading>

            <Quote textSize={36} lineHeight={1} textColor="secondary">
              Un conjunto de protocolos y estándares que sirven para intercambiar datos entre aplicaciones
            </Quote>

              Wikipedia

          <Appear>
            <Text size={6}>Es una aplicación que se encarga de brindar información o otras aplicaciones</Text>
          </Appear>
        </Slide>

        <Slide>
          <Heading size={3} lineHeight={2} textColor="secondary">¿Qué tiene de bueno?</Heading>
          <Appear>
            <Text size={6}>
              Me permite acceder a datos de los cuales puedo o no ser dueño y
              consumirlos con aplicaciones de manera sencilla
            </Text>
          </Appear>
          <Appear><Text size={6} margin="1em 0">Por ejemplo</Text></Appear>
          <Appear>
            <List>
              <ListItem>El precio de divisas extranjeras</ListItem>
              <ListItem>Datos climatológicos</ListItem>
              <ListItem>Información de perfiles públicos</ListItem>
              <ListItem>Datos estatales públicos</ListItem>
            </List>
          </Appear>
        </Slide>

        <Slide>
          <Heading size={3} lineHeight={2} textColor="secondary">{"¿Qué más?"}</Heading>
          <Appear><Text size={6} margin="30px 0">Desacoplar dependecias estructurales y unificar la existencia de los datos</Text></Appear>
          <Appear>
            <Text size={6} margin="30px 0" textColor="tertiary" bold>
              Puedo tener todos los datos en una sola API, y tener una app web, una mobile y una de escritorio.
              Y que todas las aplicaciones usen los datos de la API, sin tener que tenerlos almacenados en
              lugares diferentes, repetidos o preocuparme de su sincronización
            </Text>
          </Appear>
        </Slide>

        <Slide>
          <Heading size={3}>Cosas a tener en cuenta en todo momento de su desarrollo</Heading>
          <List>
            <ListItem size={5}>DRY</ListItem>
            <ListItem size={5}>Tiempo de desarrollo por app menor</ListItem>
            <ListItem size={5}>Reducción en la transferencia de datos</ListItem>
            <ListItem size={5}>Cacheable</ListItem>
            <ListItem size={5}>Mayor tiempo total de desarrollo en app pequeñas</ListItem>
          </List>
        </Slide>

        <Slide>
          <Heading size={3} textColor="secondary">Nociones generales</Heading>
          <List>
            <Appear><ListItem>Funcionamiento</ListItem></Appear>
            <Appear><ListItem>Estética</ListItem></Appear>
            <Appear><ListItem>Seguridad</ListItem></Appear>
            <Appear><ListItem>Flexibilidad</ListItem></Appear>
          </List>
        </Slide>

        <Slide>
          <Text margin="2em 0">Toda pieza de software debería ser tan buena como su documentación</Text>
          <Text margin="2em 0">Si nuestro software no esta bien documentado, es menos probable que sea utilizado</Text>
        </Slide>

        <Slide>
          <Heading size={2}>Funcionamiento</Heading>
        </Slide>

        <Slide bgColor="tertiary">

            <TableRow>
              <TableHeaderItem>Acción</TableHeaderItem>
              <TableHeaderItem>Verbo</TableHeaderItem>
              <TableHeaderItem>Ruta</TableHeaderItem>
            </TableRow>
            <Appear>
              <TableRow>
                <TableItem>Listar</TableItem>
                <Appear><TableItem>GET</TableItem></Appear>
                <Appear><TableItem>...com/recursos/articulos</TableItem></Appear>
              </TableRow>
            </Appear>
            <Appear>
              <TableRow>
                <TableItem>Crear</TableItem>
                <Appear><TableItem>POST</TableItem></Appear>
                <Appear><TableItem>...com/recursos/articulos</TableItem></Appear>
              </TableRow>
            </Appear>
            <Appear>
              <TableRow>
                <TableItem>Leer</TableItem>
                <Appear><TableItem>GET</TableItem></Appear>
                <Appear><TableItem>...com/recursos/articulos/id</TableItem></Appear>
              </TableRow>
            </Appear>
            <Appear>
              <TableRow>
                <TableItem>Editar</TableItem>
                <Appear><TableItem>PUT</TableItem></Appear>
                <Appear><TableItem>...com/recursos/articulos/id</TableItem></Appear>
              </TableRow>
            </Appear>
            <Appear>
              <TableRow>
                <TableItem>Borrar</TableItem>
                <Appear><TableItem>DELETE</TableItem></Appear>
                <Appear><TableItem>...com/recursos/articulos/id</TableItem></Appear>
              </TableRow>
            </Appear>

        </Slide>

        <Slide>
          <Heading size={1}>FIN</Heading>
        </Slide>
      </Deck>
    );
  }
}
<commit_msg>Diapo 13 modificada diapo 12<commit_after>// Import React
import React from "react";

// Import Spectacle Core tags
import {
  Appear, BlockQuote, Cite, Deck, Heading, Layout, Fill, ListItem, List, Quote, Slide,
  Text, Table, TableHeaderItem, TableItem, TableRow
} from "spectacle";

import FontAwesome from 'react-fontawesome';

import Caseify from './Components/Caseify.jsx';

// Import image preloader util
import preloader from "spectacle/lib/utils/preloader";

// Import theme
import createTheme from "spectacle/lib/themes/default";

// Require CSS
require("normalize.css");
require("spectacle/lib/themes/default/index.css");

const images = {
  city: require("../assets/city.jpg"),
  kat: require("../assets/kat.png"),
  logo: require("../assets/formidable-logo.svg"),
  markdown: require("../assets/markdown.png"),
  yo: require("../assets/foto_presentacion.jpg")
};

preloader(images);

const theme = createTheme({
  primary: "white",
  secondary: "#1F2022",
  tertiary: "#03A9FC",
  quartenary: "#CECECE"
}, {
  primary: "Montserrat",
  secondary: "Helvetica"
});

export default class Presentation extends React.Component {
  render() {
    return (
      <Deck transition={["slide"]} transitionDuration={500} theme={theme}>
        <Slide bgColor="primary">
					<Heading size={1} fit lineHeight={1} textColor="secondary">RESTful APIs</Heading>
					<Text margin="10px 0 0" textColor="tertiary" size={6} bold>Buenas prácticas</Text>
				</Slide>

        <Slide bgColor="black">
					<Heading size={1} caps fit textColor="primary" textFont="primary">Quién soy?</Heading>
          <List textColor="primary">
					  <Appear><ListItem textColor="primary">Juan Manuel Cruz</ListItem></Appear>
            <Appear><ListItem textColor="primary">Estudiante</ListItem></Appear>
            <Appear><ListItem textColor="primary">Desarrollador</ListItem></Appear>
            <Appear><ListItem textColor="primary">Autodidacta</ListItem></Appear>
            <Appear><ListItem textColor="primary">Hacker</ListItem></Appear>
					</List>
					<Appear><Text textColor="tertiary"><FontAwesome name="twitter" size="lg"/> wroughtbywind</Text></Appear>
          <Appear><Text textColor="primary"><FontAwesome name="github" size="lg"/> Malows</Text></Appear>
				</Slide>

        <Slide bgColor="primary">
          <Heading size={3} fit lineHeight={1} textColor="secondary">¿Por qué usar APIs RESTful?</Heading>
          <List>
            <Appear><Text margin="30px 10px" textColor="tertiary" size={6}>Proque son geniales</Text></Appear>
            <Appear><Text margin="30px 10px" textColor="tertiary" size={6}>
              {"Porque la carga de transferencia en aplicaciones web isomorfas se hace solo al principio. Luego de la carga inicial solo se transfieren datos"}
            </Text></Appear>
          </List>
        </Slide>

        <Slide>
          <Heading size={1} lineHeight={1} textColor="secondary">{"???"}</Heading>
        </Slide>

        <Slide>
          <Heading size={3} lineHeight={1} textColor="secondary">{"¿Qué son?"}</Heading>

            <Quote textSize={36} lineHeight={1} textColor="secondary">
              Un conjunto de protocolos y estándares que sirven para intercambiar datos entre aplicaciones
            </Quote>

              Wikipedia

          <Appear>
            <Text size={6}>Es una aplicación que se encarga de brindar información o otras aplicaciones</Text>
          </Appear>
        </Slide>

        <Slide>
          <Heading size={3} lineHeight={2} textColor="secondary">¿Qué tiene de bueno?</Heading>
          <Appear>
            <Text size={6}>
              Me permite acceder a datos de los cuales puedo o no ser dueño y
              consumirlos con aplicaciones de manera sencilla
            </Text>
          </Appear>
          <Appear><Text size={6} margin="1em 0">Por ejemplo</Text></Appear>
          <Appear>
            <List>
              <ListItem>El precio de divisas extranjeras</ListItem>
              <ListItem>Datos climatológicos</ListItem>
              <ListItem>Información de perfiles públicos</ListItem>
              <ListItem>Datos estatales públicos</ListItem>
            </List>
          </Appear>
        </Slide>

        <Slide>
          <Heading size={3} lineHeight={2} textColor="secondary">{"¿Qué más?"}</Heading>
          <Appear><Text size={6} margin="30px 0">Desacoplar dependecias estructurales y unificar la existencia de los datos</Text></Appear>
          <Appear>
            <Text size={6} margin="30px 0" textColor="tertiary" bold>
              Puedo tener todos los datos en una sola API, y tener una app web, una mobile y una de escritorio.
              Y que todas las aplicaciones usen los datos de la API, sin tener que tenerlos almacenados en
              lugares diferentes, repetidos o preocuparme de su sincronización
            </Text>
          </Appear>
        </Slide>

        <Slide>
          <Heading size={3}>Cosas a tener en cuenta en todo momento de su desarrollo</Heading>
          <List>
            <ListItem size={5}>DRY</ListItem>
            <ListItem size={5}>Tiempo de desarrollo por app menor</ListItem>
            <ListItem size={5}>Reducción en la transferencia de datos</ListItem>
            <ListItem size={5}>Cacheable</ListItem>
            <ListItem size={5}>Mayor tiempo total de desarrollo en app pequeñas</ListItem>
          </List>
        </Slide>

        <Slide>
          <Heading size={3} textColor="secondary">Nociones generales</Heading>
          <List>
            <Appear><ListItem>Funcionamiento</ListItem></Appear>
            <Appear><ListItem>Estética</ListItem></Appear>
            <Appear><ListItem>Seguridad</ListItem></Appear>
            <Appear><ListItem>Flexibilidad</ListItem></Appear>
          </List>
        </Slide>

        <Slide>
          <Text margin="2em 0">Toda pieza de software debería ser tan buena como su documentación</Text>
          <Text margin="2em 0">Si nuestro software no esta bien documentado, es menos probable que sea utilizado</Text>
        </Slide>

        <Slide>
          <Heading size={2}>Funcionamiento</Heading>
        </Slide>

        <Slide>
          <Heading size={3}>I'm the resources buisness</Heading>
          <Text>Todo tipo de respuestas es llamado recurso, aún si es un error. Y todo recurso debe ser devuelto, sea cual sea la dirección solicitada</Text>
        </Slide>

        <Slide bgColor="tertiary">

            <TableRow>
              <TableHeaderItem>Acción</TableHeaderItem>
              <TableHeaderItem>Verbo</TableHeaderItem>
              <TableHeaderItem>Ruta</TableHeaderItem>
            </TableRow>
            <Appear>
              <TableRow>
                <TableItem>Listar</TableItem>
                <Appear><TableItem>GET</TableItem></Appear>
                <Appear><TableItem>...com/recursos/articulos</TableItem></Appear>
              </TableRow>
            </Appear>
            <Appear>
              <TableRow>
                <TableItem>Crear</TableItem>
                <Appear><TableItem>POST</TableItem></Appear>
                <Appear><TableItem>...com/recursos/articulos</TableItem></Appear>
              </TableRow>
            </Appear>
            <Appear>
              <TableRow>
                <TableItem>Leer</TableItem>
                <Appear><TableItem>GET</TableItem></Appear>
                <Appear><TableItem>...com/recursos/articulos/id</TableItem></Appear>
              </TableRow>
            </Appear>
            <Appear>
              <TableRow>
                <TableItem>Editar</TableItem>
                <Appear><TableItem>PUT</TableItem></Appear>
                <Appear><TableItem>...com/recursos/articulos/id</TableItem></Appear>
              </TableRow>
            </Appear>
            <Appear>
              <TableRow>
                <TableItem>Borrar</TableItem>
                <Appear><TableItem>DELETE</TableItem></Appear>
                <Appear><TableItem>...com/recursos/articulos/id</TableItem></Appear>
              </TableRow>
            </Appear>
            <Appear>
              <TableRow>
                <TableItem>Actualización</TableItem>
                <Appear><TableItem>PATCH</TableItem></Appear>
                <Appear><TableItem>...com/recursos/articulos/id</TableItem></Appear>
              </TableRow>
            </Appear>

        </Slide>

        <Slide>
          <Heading size={1}>FIN</Heading>
        </Slide>
      </Deck>
    );
  }
}
<|endoftext|>


<commit_before>import Ember from 'ember';
import DS from 'ember-data';

var Route = DS.Model.extend({
	identifiers: DS.attr(),
	imported_from_feed_onestop_ids: DS.attr('string'),
	onestop_id: Ember.computed.alias('id'),
	name: DS.attr('string'),
	vehicle_type: DS.attr('string'),
	short_name: DS.attr('string'),
	geometry: DS.attr(),
	color: DS.attr('string'),
	tags: DS.attr(),
	operated_by_onestop_id: DS.attr('string'),
	operated_by_name: DS.attr('string'),
	created_at: DS.attr('date'),
	updated_at: DS.attr('date'),
	route_stop_patterns_by_onestop_id: DS.attr(),
	route_path_opacity: 1,
	route_path_weight: 3,
	vehicle_type_color: {
		'bus' : '#8dd3c7',
		'rail' : '#b3de69',
		'metro': '#bebada',
		'ferry' : '#fb8072',
		'cablecar' : '#80b1d3',
		'tram' : '#fdb462'
	},
	default_color: "#6ea0a4",
	total: (function(){
		this.get('meta.total');
	}).property(),
	default_as_geojson_with_outline: (function(){
		return {
			type: "FeatureCollection",
			features: [
				{
					type: "Feature",
					geometry: this.get('geometry'),
					properties: {
						color: "#444444",
						weight: 5,
						opacity: 0
					},
					id: this.onestop_id,
					onestop_id: this.get('onestop_id'),
				},
				{
					type: "Feature",
					geometry: this.get('geometry'),
					properties: {
						color: this.get('default_color'),
						weight: 3,
						opacity: 1
					},
				},
			]
		}
	}).property('geometry'),
	operator_focus_as_geojson_with_outline: (function(){
		return {
			type: "FeatureCollection",
			features: [
				{
					type: "Feature",
					geometry: this.get('geometry'),
					properties: {
						color: "#444444",
						weight: 0,
						opacity: 0
					},
					id: this.onestop_id,
					onestop_id: this.get('onestop_id'),
				},
				{
					type: "Feature",
					geometry: this.get('geometry'),
					properties: {
						color: this.get('operated_by_route_default_color'),
						weight: 2.5,
						opacity: 1
					},
				},
			]
		}
	}).property('geometry'),

	mode_as_geojson_with_outline: (function(){
		let lineColor = this.get('vehicle_type_color')[this.get('vehicle_type')];
		let hexValue = lineColor.split("");
		hexValue.shift();
		var hexLetters = {
			a : 10,
			b : 11,
			c : 12,
			d : 13,
			e : 14,
			f : 15,
		}

		for (var i = 0; i < 6; i++){
			let hexDigit = hexValue[i]
			if (hexDigit >= 0){
				hexValue[i] = Number.parseInt(hexDigit);
			} else {
				hexValue[i] = hexLetters[hexDigit];
			}
		}

		let red = (hexValue[0] * 16) + hexValue[1];
		let green = (hexValue[2] * 16) + hexValue[3];
		let blue = (hexValue[4] * 16) + hexValue[5];

		// from turn-by-turn demo:
		var lum = 0.299 * red + 0.587 * green + 0.114 * blue,
    is_light = (lum > 0xbb);

    let borderColor = (is_light ? '#666666' : '#f8f8f8');

		return {
			type: "FeatureCollection",
			features: [
				{
					type: "Feature",
					geometry: this.get('geometry'),
					properties: {
						color: borderColor,
						weight: 5,
						opacity: 0
					},
					id: this.onestop_id,
					onestop_id: this.get('onestop_id'),
				},
				{
					type: "Feature",
					geometry: this.get('geometry'),
					properties: {
						color: this.get('vehicle_type_color')[this.get('vehicle_type')],
						weight: 3,
						opacity: 1
					},
				},
			]
		}
	}).property('geometry'),
	operator_as_geojson_with_outline: (function(){
		let lineColor = this.get('operator_color');
		let hexValue = lineColor.split("");
		hexValue.shift();
		var hexLetters = {
			a : 10,
			b : 11,
			c : 12,
			d : 13,
			e : 14,
			f : 15,
		}

		for (var i = 0; i < 6; i++){
			let hexDigit = hexValue[i]
			if (hexDigit >= 0){
				hexValue[i] = Number.parseInt(hexDigit);
			} else {
				hexValue[i] = hexLetters[hexDigit];
			}
		}

		let red = (hexValue[0] * 16) + hexValue[1];
		let green = (hexValue[2] * 16) + hexValue[3];
		let blue = (hexValue[4] * 16) + hexValue[5];

		// from turn-by-turn demo:
		var lum = 0.299 * red + 0.587 * green + 0.114 * blue,
    is_light = (lum > 0xbb);

    let borderColor = (is_light ? '#666666' : '#f8f8f8');

		return {
			type: "FeatureCollection",
			features: [
				{
					type: "Feature",
					geometry: this.get('geometry'),
					properties: {
						color: "#222222",
						weight: 5,
						opacity: 0
					},
					id: this.onestop_id,
					onestop_id: this.get('onestop_id'),
				},
				{
					type: "Feature",
					geometry: this.get('geometry'),
					properties: {
						color: this.get('operator_color'),
						weight: 3,
						opacity: 1
					},
				},
			]
		}
	}).property('geometry'),
	rsp_route_as_geojson_with_outline: (function(){
		return {
			type: "FeatureCollection",
			features: [
				{
					type: "Feature",
					geometry: this.get('geometry'),
					properties: {
						color: "#444444",
						weight: 5,
						opacity: 1
					},
					id: this.onestop_id,
					onestop_id: this.get('onestop_id'),
				},
				{
					type: "Feature",
					geometry: this.get('geometry'),
					properties: {
						color: this.get('default_color'),
						weight: 3,
						opacity: 1
					},
				},
			]
		}
	}).property('geometry'),
	operator_color: (function(){
		var str = this.get('operated_by_onestop_id');
		var hash = 0;
		for (var i = 0; i <str.length; i++) {
			hash = str.charCodeAt(i) + ((hash << 5) - hash);
		}
		var hex = ((hash>>24)&0xFF).toString(16) + ((hash>>16)&0xFF).toString(16) + ((hash>>8)&0xFF).toString(16) + (hash&0xFF).toString(16);
		hex += '000000';
		var colorCode = hex.substring(0, 6);
		colorCode.toString();
		colorCode = "#" + colorCode;
		return colorCode;
	}).property('operated_by_onestop_id'),

	operated_by_route_default_color: (function(){
		if (this.get('color') !== null && this.get('color') !== "ffffff"){
			return "#" + this.get('color');
		} else {
			return "#6ea0a4";
		}
	}).property('onestop_id')

});

export default Route;
<commit_msg>change line weight to 5 for invisible route line<commit_after>import Ember from 'ember';
import DS from 'ember-data';

var Route = DS.Model.extend({
	identifiers: DS.attr(),
	imported_from_feed_onestop_ids: DS.attr('string'),
	onestop_id: Ember.computed.alias('id'),
	name: DS.attr('string'),
	vehicle_type: DS.attr('string'),
	short_name: DS.attr('string'),
	geometry: DS.attr(),
	color: DS.attr('string'),
	tags: DS.attr(),
	operated_by_onestop_id: DS.attr('string'),
	operated_by_name: DS.attr('string'),
	created_at: DS.attr('date'),
	updated_at: DS.attr('date'),
	route_stop_patterns_by_onestop_id: DS.attr(),
	route_path_opacity: 1,
	route_path_weight: 3,
	vehicle_type_color: {
		'bus' : '#8dd3c7',
		'rail' : '#b3de69',
		'metro': '#bebada',
		'ferry' : '#fb8072',
		'cablecar' : '#80b1d3',
		'tram' : '#fdb462'
	},
	default_color: "#6ea0a4",
	total: (function(){
		this.get('meta.total');
	}).property(),
	default_as_geojson_with_outline: (function(){
		return {
			type: "FeatureCollection",
			features: [
				{
					type: "Feature",
					geometry: this.get('geometry'),
					properties: {
						color: "#444444",
						weight: 5,
						opacity: 0
					},
					id: this.onestop_id,
					onestop_id: this.get('onestop_id'),
				},
				{
					type: "Feature",
					geometry: this.get('geometry'),
					properties: {
						color: this.get('default_color'),
						weight: 3,
						opacity: 1
					},
				},
			]
		}
	}).property('geometry'),
	operator_focus_as_geojson_with_outline: (function(){
		return {
			type: "FeatureCollection",
			features: [
				{
					type: "Feature",
					geometry: this.get('geometry'),
					properties: {
						color: "#444444",
						weight: 5,
						opacity: 0
					},
					id: this.onestop_id,
					onestop_id: this.get('onestop_id'),
				},
				{
					type: "Feature",
					geometry: this.get('geometry'),
					properties: {
						color: this.get('operated_by_route_default_color'),
						weight: 2.5,
						opacity: 1
					},
				},
			]
		}
	}).property('geometry'),

	mode_as_geojson_with_outline: (function(){
		let lineColor = this.get('vehicle_type_color')[this.get('vehicle_type')];
		let hexValue = lineColor.split("");
		hexValue.shift();
		var hexLetters = {
			a : 10,
			b : 11,
			c : 12,
			d : 13,
			e : 14,
			f : 15,
		}

		for (var i = 0; i < 6; i++){
			let hexDigit = hexValue[i]
			if (hexDigit >= 0){
				hexValue[i] = Number.parseInt(hexDigit);
			} else {
				hexValue[i] = hexLetters[hexDigit];
			}
		}

		let red = (hexValue[0] * 16) + hexValue[1];
		let green = (hexValue[2] * 16) + hexValue[3];
		let blue = (hexValue[4] * 16) + hexValue[5];

		// from turn-by-turn demo:
		var lum = 0.299 * red + 0.587 * green + 0.114 * blue,
    is_light = (lum > 0xbb);

    let borderColor = (is_light ? '#666666' : '#f8f8f8');

		return {
			type: "FeatureCollection",
			features: [
				{
					type: "Feature",
					geometry: this.get('geometry'),
					properties: {
						color: borderColor,
						weight: 5,
						opacity: 0
					},
					id: this.onestop_id,
					onestop_id: this.get('onestop_id'),
				},
				{
					type: "Feature",
					geometry: this.get('geometry'),
					properties: {
						color: this.get('vehicle_type_color')[this.get('vehicle_type')],
						weight: 3,
						opacity: 1
					},
				},
			]
		}
	}).property('geometry'),
	operator_as_geojson_with_outline: (function(){
		let lineColor = this.get('operator_color');
		let hexValue = lineColor.split("");
		hexValue.shift();
		var hexLetters = {
			a : 10,
			b : 11,
			c : 12,
			d : 13,
			e : 14,
			f : 15,
		}

		for (var i = 0; i < 6; i++){
			let hexDigit = hexValue[i]
			if (hexDigit >= 0){
				hexValue[i] = Number.parseInt(hexDigit);
			} else {
				hexValue[i] = hexLetters[hexDigit];
			}
		}

		let red = (hexValue[0] * 16) + hexValue[1];
		let green = (hexValue[2] * 16) + hexValue[3];
		let blue = (hexValue[4] * 16) + hexValue[5];

		// from turn-by-turn demo:
		var lum = 0.299 * red + 0.587 * green + 0.114 * blue,
    is_light = (lum > 0xbb);

    let borderColor = (is_light ? '#666666' : '#f8f8f8');

		return {
			type: "FeatureCollection",
			features: [
				{
					type: "Feature",
					geometry: this.get('geometry'),
					properties: {
						color: "#222222",
						weight: 5,
						opacity: 0
					},
					id: this.onestop_id,
					onestop_id: this.get('onestop_id'),
				},
				{
					type: "Feature",
					geometry: this.get('geometry'),
					properties: {
						color: this.get('operator_color'),
						weight: 3,
						opacity: 1
					},
				},
			]
		}
	}).property('geometry'),
	rsp_route_as_geojson_with_outline: (function(){
		return {
			type: "FeatureCollection",
			features: [
				{
					type: "Feature",
					geometry: this.get('geometry'),
					properties: {
						color: "#444444",
						weight: 5,
						opacity: 1
					},
					id: this.onestop_id,
					onestop_id: this.get('onestop_id'),
				},
				{
					type: "Feature",
					geometry: this.get('geometry'),
					properties: {
						color: this.get('default_color'),
						weight: 3,
						opacity: 1
					},
				},
			]
		}
	}).property('geometry'),
	operator_color: (function(){
		var str = this.get('operated_by_onestop_id');
		var hash = 0;
		for (var i = 0; i <str.length; i++) {
			hash = str.charCodeAt(i) + ((hash << 5) - hash);
		}
		var hex = ((hash>>24)&0xFF).toString(16) + ((hash>>16)&0xFF).toString(16) + ((hash>>8)&0xFF).toString(16) + (hash&0xFF).toString(16);
		hex += '000000';
		var colorCode = hex.substring(0, 6);
		colorCode.toString();
		colorCode = "#" + colorCode;
		return colorCode;
	}).property('operated_by_onestop_id'),

	operated_by_route_default_color: (function(){
		if (this.get('color') !== null && this.get('color') !== "ffffff"){
			return "#" + this.get('color');
		} else {
			return "#6ea0a4";
		}
	}).property('onestop_id')

});

export default Route;
<|endoftext|>


<commit_before>console.log('Creating Bar Graph');

require.config({
   // baseUrl is automatically set to the directory where this main.js file is.
   // Or we can set it in this config:
   // This way one can call on jquery and libs directly
   waitSeconds: 15
});

require(['../graphic'], function(Graphic) {

   var info = {
      xs: [1, 2, 3, 4, 5],
      ys: [5, 3, 10, 14, 20],
      names: ['A', 'Base', 'Cat', 'A longer one', 'The tallest'],
      xlab: 'The x label',
      ylab: 'Freq',
      main: 'An awesome bar chart!',
      sub: null,
      margin: {
         bottom: 0.2,
         left: 0.2,
         top: 0.05,
         right: 0.05
      },
      xlim: [0, 6],
      ylim: [0, 22]
   };

   var w = Graphic.Window.new({
      px: 300,
      py: 300,
      xmin: 0,
      xmax: 1,
      ymin: 1,
      ymax: 0
   });

   var xbottom = Graphic.Group.new({
      transform: Graphic.Transform.scales(
         Graphic.Scale.range(0, 1, info.margin.left, 1 - info.margin.right),
         Graphic.Scale.range(0, 1, 0, info.margin.bottom)
      )
   });
   var yleft   = Graphic.Group.new({
      transform: Graphic.Transform.scales(
         Graphic.Scale.range(0, 1, 0, info.margin.left),
         Graphic.Scale.range(0, 1, info.margin.bottom, 1 - info.margin.top)
      )
   });
   var graphRegion = Graphic.Group.new({
      transform: Graphic.Transform.scales(
         Graphic.Scale.range(0, 1, info.margin.left, 1 - info.margin.right),
         Graphic.Scale.range(0, 1, info.margin.bottom, 1 - info.margin.top)
      )

   });
   console.log(Graphic.Scale.range);

   var graph   = Graphic.Group.new({
      transform: Graphic.Transform.scales(
         Graphic.Scale.range(info.xlim[0], info.xlim[1], 0, 1),
         Graphic.Scale.range(info.ylim[0], info.ylim[1], 0, 1)
      )
   });
   graphRegion.append(graph);

   w.append(xbottom).append(yleft).append(graphRegion);

   graphRegion.append(Graphic.Rect.new({
      x0: [0],
      y0: [0],
      x1: [1],
      y1: [1],
      themeParamsPath: 'background'
   }));

   document.body.appendChild(
      Graphic.Visitor.toSVG.new(Graphic.Settings.new()).visit(w)
   );
});
<commit_msg>Complete bar graph example.<commit_after>console.log('Creating Bar Graph');

require.config({
   // baseUrl is automatically set to the directory where this main.js file is.
   // Or we can set it in this config:
   // This way one can call on jquery and libs directly
   waitSeconds: 15
});

require(['../graphic'], function(Graphic) {

   var info = {
      ytop: [5, 3, 10, 14, 20],
      ybottom: [0, 0, 0, 0, 0],
      xleft: [0, 1.25, 2.50, 3.75, 5],
      xright: [1, 2.25, 3.50, 4.75, 6],
      name: ['A', 'Base', 'Cat', 'A longer one', 'The tallest'],
      xlab: 'The x label',
      ylab: 'Freq',
      main: 'An awesome bar chart!',
      sub: null,
      margin: {
         bottom: 0.2,
         left: 0.2,
         top: 0.05,
         right: 0.05,
         lines: 5
      },
      xlim: [0, 6],
      ylim: [0, 22],
      ytick: [0, 5, 10, 15, 20]
   };

   info.xmiddle = info.xleft.map(function(val, i) { return (val + info.xright[i])/2; });

   var w = Graphic.Window.new({
      px: 400,
      py: 400,
      xmin: 0,
      xmax: 1,
      ymin: 1,
      ymax: 0
   });

   // bottom margin -- number of lines for margines should be settable
   var xbottom = Graphic.Group.new({
      transform: Graphic.Transform.scales(
         Graphic.Scale.range(info.xlim[0], info.xlim[1], info.margin.left, 1 - info.margin.right),
         Graphic.Scale.range(info.margin.lines - 1, 0, 0, info.margin.bottom)
      )
   });

   // top margin
   var xtop = Graphic.Group.new({
      transform: Graphic.Transform.scales(
         Graphic.Scale.range(info.xlim[0], info.xlim[1], info.margin.left, 1 - info.margin.right),
         Graphic.Scale.range(0, info.margin.lines - 1, 1 - info.margin.top, 1)
      )
   });

   // left margin
   var yleft   = Graphic.Group.new({
      transform: Graphic.Transform.scales(
         Graphic.Scale.range(info.margin.lines - 1, 0, 0, info.margin.left),
         Graphic.Scale.range(info.ylim[0], info.ylim[1], info.margin.bottom, 1 - info.margin.top)
      )
   });

   // graph area, (0, 1) - coordinates
   var graphRegion = Graphic.Group.new({
      transform: Graphic.Transform.scales(
         Graphic.Scale.range(0, 1, info.margin.left, 1 - info.margin.right),
         Graphic.Scale.range(0, 1, info.margin.bottom, 1 - info.margin.top)
      )
   });

   // y axis
   var axis = Graphic.Group.new({
      transform: Graphic.Transform.scales(
         Graphic.Scale.range(0, 1, 0.2, 2),  // uses 2 lines of margin
         Graphic.Scale.ident()
      )
   });

   // graph area, scaled according to the xlim, ylim values
   var graph   = Graphic.Group.new({
      transform: Graphic.Transform.scales(
         Graphic.Scale.range(info.xlim[0], info.xlim[1], 0, 1),
         Graphic.Scale.range(info.ylim[0], info.ylim[1], 0, 1)
      )
   });

   graphRegion.append(graph);

   // add horizontal reference lines, then bars
   graph.append(Graphic.Segments.new({
      x0: info.ytick.map(function(v) { return info.xlim[0]; }),
      x1: info.ytick.map(function(v) { return info.xlim[1]; }),
      y0: info.ytick,
      y1: info.ytick,
      themeParamsPath: 'reference.line'
   })).append(Graphic.Rect.new({
      x0: info.xleft,
      x1: info.xright,
      y0: info.ybottom,
      y1: info.ytop
   }));

   w.append(xbottom).append(xtop).append(yleft).append(graphRegion);

   // graphRegion.append(Graphic.Rect.new({
   //    x0: [0],
   //    y0: [0],
   //    x1: [1],
   //    y1: [1],
   //    themeParamsPath: 'background'
   // }));

   // add bar names, then the x label
   xbottom.append(Graphic.Text.new({
      x: info.xmiddle,
      y: [1, 1, 1, 1, 1],
      text: info.name,
      themeParamsPath: 'axis.text'
   })).append(Graphic.Text.new({
      x: [(info.xlim[0] + info.xlim[1]) / 2],
      y: [2],
      text: [info.xlab],
      themeParamsPath: 'par.xlab_text'
   }));

   // add main title to top margin
   xtop.append(Graphic.Text.new({
      x: [(info.xlim[0] + info.xlim[1]) / 2],
      y: [2],
      text: [info.main],
      themeParamsPath: 'par.main_text'
   }));

   // add y label (vertical!)
   yleft.append(axis)
      .append(Graphic.Text.new({
         x: [3],
         y: [(info.ylim[0] + info.ylim[1]) / 2],
         text: [info.ylab],
         themeParamsPath: 'par.ylab_text',
         orientation: 'vertical'
      }));;

   // make an axis line with ticks and tick labels
   axis.append(Graphic.Segments.new({
      x0: [0],
      y0: [0],
      x1: [0],
      y1: [20], //  last tick
      themeParamsPath: 'axis.line'
   })).append(Graphic.Segments.new({
      x0: [0, 0, 0, 0, 0],
      y0: info.ytick,
      x1: [.3, .3, .3, .3, .3],
      y1: info.ytick,
      themeParamsPath: 'axis.line'
   })).append(Graphic.Text.new({
      x: [.5, .5, .5, .5, .5],
      y: info.ytick,
      text: info.ytick,
      themeParamsPath: 'axis.text'
   }));

   document.body.appendChild(
      Graphic.Visitor.toSVG.new(Graphic.Settings.new()).visit(w)
   );
});
<|endoftext|>


<commit_before>var mongoose = require('mongoose');

var Schema = mongoose.Schema;
var User = require('User');

var ambitSchema = new Schema({
  refId: {type: Number, index: true}, //a number used to keep track of the ambit
  name: String,
  coords: {
    latitude: Number,
    longitude: Number
  },
  weekdays: [Boolean], //0 is Sunday, 6 is Saturday
  startDate: Date,
  limit: Number,
  joinedUsers: Array,
  endDate: [Date],
  userId:  {type: Schema.Types.ObjectId, ref: 'User'}
  checkIns: [Date] // a history of successful check-ins
  //time (when during the day are you supposed to check in)
  //repeats (every week? every other week? is this necessary?)
});

var Ambit = mongoose.model('Ambit', ambitSchema);

module.exports = Ambit;
<commit_msg>Fixes to ambitSchema<commit_after>var mongoose = require('mongoose');

var Schema = mongoose.Schema;
var User = require('../users/userModel');

var ambitSchema = new Schema({
  refId: {type: Number, index: true}, //a number used to keep track of the ambit
  name: String,
  coords: {
    latitude: Number,
    longitude: Number
  },
  weekdays: [Boolean], //0 is Sunday, 6 is Saturday
  startDate: Date,
  limit: Number,
  joinedUsers: Array,
  endDate: [Date],
  userId:  {type: Schema.Types.ObjectId, ref: 'User'},
  checkIns: [Date] // a history of successful check-ins
  //time (when during the day are you supposed to check in)
  //repeats (every week? every other week? is this necessary?)
});

var Ambit = mongoose.model('Ambit', ambitSchema);

module.exports = Ambit;
<|endoftext|>


<commit_before>describe("预设不存在 unexist",function(){
	it("name为，test(\"\")为false，hint为null",function(){

		var ready = false;
		runs(function(){
			NR.provide('form/rule',function(D,Rule){
				ready = true;
				var r1;

				try{
					r1 = Rule.produce("unexist");
				}catch(e){
			  		expect(e).toEqual("Rule preset unexist does not exist");
				}
		  	});
		});

		waitsFor(function(){
			return ready;
		});
	});
});

describe("简单预设 required",function(){
	it("name为required，test(\"\")为false，hint为null",function(){

		var ready = false;
		runs(function(){
			NR.provide('form/rule',function(D,Rule){
				ready = true;

				var r1 = Rule.produce("required");
			  	expect(r1.name).toEqual("required");
			  	expect(r1.test("")).toEqual(false);
			  	expect(r1.test(null)).toEqual(false);
			  	expect(r1.test(undefined)).toEqual(false);
			  	expect(r1.test(0)).toEqual(true);
			  	expect(r1.test("ha")).toEqual(true);
			  	expect(r1.hint).toEqual(null);
		  	});
		});

		waitsFor(function(){
			return ready;
		});
	});
});

describe("简单预设 notempty",function(){
	it("name为notempty，test(\"\")为false，hint为null",function(){

		var ready = false;
		runs(function(){
			NR.provide('form/rule',function(D,Rule){
				ready = true;

				var r1 = Rule.produce("notempty");
			  	expect(r1.name).toEqual("notempty");
			  	expect(r1.test("")).toEqual(false);
			  	expect(r1.test([])).toEqual(false);
			  	expect(r1.test(null)).toEqual(false);
			  	expect(r1.test(undefined)).toEqual(false);
			  	expect(r1.test([1])).toEqual(true);
			  	expect(r1.hint).toEqual(null);
		  	});
		});

		waitsFor(function(){
			return ready;
		});
	});
});

describe("简单预设 allnumber",function(){
	it("name为allnumber",function(){

		var ready = false;
		runs(function(){
			NR.provide('form/rule',function(D,Rule){
				ready = true;

				var r1 = Rule.produce("allnumber");
			  	expect(r1.name).toEqual("allnumber");
			  	expect(r1.test("")).toEqual(false);
			  	expect(r1.test([])).toEqual(false);
			  	expect(r1.test(null)).toEqual(false);
			  	expect(r1.test(undefined)).toEqual(false);
			  	expect(r1.test([1])).toEqual(true);
			  	expect(r1.test([1,2])).toEqual(true);
			  	expect(r1.test([1,"23"])).toEqual(true);
			  	expect(r1.test([1,"2a3"])).toEqual(false);
			  	expect(r1.test("23")).toEqual(true);
			  	expect(r1.test(13)).toEqual(true);
			  	expect(r1.test(0)).toEqual(true);
			  	expect(r1.hint).toEqual(null);
		  	});
		});

		waitsFor(function(){
			return ready;
		});
	});
});

describe("简单预设 equal",function(){
	it("name为equal:abc，test(\"abc\")为true，test(\"b\")为false，hint为null",function(){

		var ready = false;
		runs(function(){
			NR.provide('form/rule',function(D,Rule){
				ready = true;

				var r1 = Rule.produce("equal:abc");
			  	expect(r1.name).toEqual("equal");
			  	expect(r1.test("abc")).toEqual(true);
			  	expect(r1.test("b")).toEqual(false);
			  	expect(r1.hint).toEqual(null);
		  	});
		});

		waitsFor(function(){
			return ready;
		});
	});
});

describe("简单预设 unequal",function(){
	it("name为unequal:abc，test(\"abc\")为false，test(\"b\")为true，hint为null",function(){

		var ready = false;
		runs(function(){
			NR.provide('form/rule',function(D,Rule){
				ready = true;

				var r1 = Rule.produce("unequal:abc");
			  	expect(r1.name).toEqual("unequal");
			  	expect(r1.test("abc")).toEqual(false);
			  	expect(r1.test("b")).toEqual(true);
			  	expect(r1.hint).toEqual(null);
		  	});
		});

		waitsFor(function(){
			return ready;
		});
	});
});

describe("简单预设 email",function(){
	it("name为email，test(\"aaa@163.com\")为true，hint为null",function(){

		var ready = false;
		runs(function(){
			NR.provide('form/rule',function(D,Rule){
				ready = true;

				var r1 = Rule.produce("email");
			  	expect(r1.name).toEqual("email");
			  	expect(r1.test("aaa@163.com")).toEqual(true);
			  	expect(r1.hint).toEqual(null);
		  	});
		});

		waitsFor(function(){
			return ready;
		});
	});
});

describe("预设配置 {name:email,hint:\"必须为email\"}",function(){
	it("name为\"email\"，hint为\"必须为email\"",function(){

		var ready = false;
		runs(function(){
			NR.provide('form/rule',function(D,Rule){
				ready = true;

				var r2 = Rule.produce({
					test:"email",
					hint:"必须为email"
				});
			  	expect(r2.name).toEqual("email");
			  	expect(r2.hint).toEqual("必须为email");
		  	});
		});

		waitsFor(function(){
			return ready;
		});
	});
});

describe("带参数预设配置 {test:\"min:5\",hint:\"长度不小于{0}\"}",function(){
	it("name为\"min\"，hint为\"长度不小于5\"，test abc为false，abcde为true，abcdef为true",function(){

		var ready = false;
		runs(function(){
			NR.provide('form/rule',function(D,Rule){
				ready = true;

				var r3 = Rule.produce({
					test:"min:5",
					hint:"长度不小于{0}"
				});

			  	expect(r3.name).toEqual("min");
			  	expect(r3.hint).toEqual("长度不小于5");
			  	expect(r3.test("abc")).toEqual(false);
			  	expect(r3.test("abcde")).toEqual(true);
			  	expect(r3.test("abcdef")).toEqual(true);

		  	});
		});

		waitsFor(function(){
			return ready;
		});
	});
});

describe("带参数预设配置 {test:\"max:5\",hint:\"长度不大于{0}\"}",function(){
	it("name为\"max\"，hint为\"长度不大于5\"，test abc为true，abcde为true，abcdef为false",function(){

		var ready = false;
		runs(function(){
			NR.provide('form/rule',function(D,Rule){
				ready = true;

				var r3 = Rule.produce({
					test:"max:5",
					hint:"长度不大于{0}"
				});

			  	expect(r3.name).toEqual("max");
			  	expect(r3.hint).toEqual("长度不大于5");
			  	expect(r3.test("abc")).toEqual(true);
			  	expect(r3.test("abcde")).toEqual(true);
			  	expect(r3.test("abcdef")).toEqual(false);

		  	});
		});

		waitsFor(function(){
			return ready;
		});
	});
});

describe("参数预设配置 in:a,b,c",function(){
	it("name为in",function(){

		var ready = false;
		runs(function(){
			NR.provide('form/rule',function(D,Rule){
				ready = true;

				var r1 = Rule.produce("in:a,b,c");
			  	expect(r1.name).toEqual("in");
			  	expect(r1.test("a")).toEqual(true);
			  	expect(r1.test("b")).toEqual(true);
			  	expect(r1.test("c")).toEqual(true);
			  	expect(r1.test("d")).toEqual(false);
			  	expect(r1.hint).toEqual(null);
		  	});
		});

		waitsFor(function(){
			return ready;
		});
	});
});

describe("自定义函数test",function(){
	it("name为\"mytest\"，hint为\"值必须为123\"，test 123为true",function(){

		var ready = false;
		runs(function(){
			NR.provide('form/rule',function(D,Rule){
				ready = true;

				var r4 = Rule.produce({
					name:"mytest",
					test:function(v){
						return v === 123;
					},
					hint:"值必须为123"
				});

		  		expect(r4.name).toEqual("mytest");
		  		expect(r4.hint).toEqual("值必须为123");
		  		expect(r4.test(123)).toEqual(true);

		  	});
		});

		waitsFor(function(){
			return ready;
		});
	});
});<commit_msg>change testcases<commit_after>describe("预设不存在 unexist",function(){
	it("name为，test(\"\")为false，hint为null",function(){

		var ready = false;
		runs(function(){
			NR.provide('form/rule',function(D,Rule){
				ready = true;
				var r1;

				try{
					r1 = Rule.produce("unexist");
				}catch(e){
			  		expect(e).toEqual("Rule preset unexist does not exist");
				}
		  	});
		});

		waitsFor(function(){
			return ready;
		});
	});
});

describe("简单预设 required",function(){
	it("name为required，test(\"\")为false，hint为null",function(){

		var ready = false;
		runs(function(){
			NR.provide('form/rule',function(D,Rule){
				ready = true;

				var r1 = Rule.produce("required");
			  	expect(r1.name).toEqual("required");
			  	expect(r1.test("")).toEqual(false);
			  	expect(r1.test(null)).toEqual(false);
			  	expect(r1.test(undefined)).toEqual(false);
			  	expect(r1.test(0)).toEqual(false);
			  	expect(r1.test("ha")).toEqual(true);
			  	expect(r1.hint).toEqual(null);
		  	});
		});

		waitsFor(function(){
			return ready;
		});
	});
});

describe("简单预设 notempty",function(){
	it("name为notempty，test(\"\")为false，hint为null",function(){

		var ready = false;
		runs(function(){
			NR.provide('form/rule',function(D,Rule){
				ready = true;

				var r1 = Rule.produce("notempty");
			  	expect(r1.name).toEqual("notempty");
			  	expect(r1.test([])).toEqual(false);
			  	expect(r1.test([1])).toEqual(true);
			  	expect(r1.hint).toEqual(null);
		  	});
		});

		waitsFor(function(){
			return ready;
		});
	});
});

describe("简单预设 numeric",function(){
	it("name为numeric",function(){

		var ready = false;
		runs(function(){
			NR.provide('form/rule',function(D,Rule){
				ready = true;

				var r1 = Rule.produce("numeric");
			  	expect(r1.name).toEqual("numeric");
			  	expect(r1.test("")).toEqual(false);
			  	expect(r1.test("23")).toEqual(true);
			  	expect(r1.test(13)).toEqual(true);
			  	expect(r1.test(0)).toEqual(true);
			  	expect(r1.hint).toEqual(null);
		  	});
		});

		waitsFor(function(){
			return ready;
		});
	});
});

describe("简单预设 equal",function(){
	it("name为equal:abc，test(\"abc\")为true，test(\"b\")为false，hint为null",function(){

		var ready = false;
		runs(function(){
			NR.provide('form/rule',function(D,Rule){
				ready = true;

				var r1 = Rule.produce("equal:abc");
			  	expect(r1.name).toEqual("equal");
			  	expect(r1.test("abc")).toEqual(true);
			  	expect(r1.test("b")).toEqual(false);
			  	expect(r1.hint).toEqual(null);
		  	});
		});

		waitsFor(function(){
			return ready;
		});
	});
});

describe("简单预设 unequal",function(){
	it("name为unequal:abc，test(\"abc\")为false，test(\"b\")为true，hint为null",function(){

		var ready = false;
		runs(function(){
			NR.provide('form/rule',function(D,Rule){
				ready = true;

				var r1 = Rule.produce("unequal:abc");
			  	expect(r1.name).toEqual("unequal");
			  	expect(r1.test("abc")).toEqual(false);
			  	expect(r1.test("b")).toEqual(true);
			  	expect(r1.hint).toEqual(null);
		  	});
		});

		waitsFor(function(){
			return ready;
		});
	});
});

describe("简单预设 email",function(){
	it("name为email，test(\"aaa@163.com\")为true，hint为null",function(){

		var ready = false;
		runs(function(){
			NR.provide('form/rule',function(D,Rule){
				ready = true;

				var r1 = Rule.produce("email");
			  	expect(r1.name).toEqual("email");
			  	expect(r1.test("aaa@163.com")).toEqual(true);
			  	expect(r1.hint).toEqual(null);
		  	});
		});

		waitsFor(function(){
			return ready;
		});
	});
});

describe("预设配置 {name:email,hint:\"必须为email\"}",function(){
	it("name为\"email\"，hint为\"必须为email\"",function(){

		var ready = false;
		runs(function(){
			NR.provide('form/rule',function(D,Rule){
				ready = true;

				var r2 = Rule.produce({
					test:"email",
					hint:"必须为email"
				});
			  	expect(r2.name).toEqual("email");
			  	expect(r2.hint).toEqual("必须为email");
		  	});
		});

		waitsFor(function(){
			return ready;
		});
	});
});

describe("带参数预设配置 {test:\"min:5\",hint:\"长度不小于{0}\"}",function(){
	it("name为\"min\"，hint为\"长度不小于5\"，test abc为false，abcde为true，abcdef为true",function(){

		var ready = false;
		runs(function(){
			NR.provide('form/rule',function(D,Rule){
				ready = true;

				var r3 = Rule.produce({
					test:"min:5",
					hint:"长度不小于{0}"
				});

			  	expect(r3.name).toEqual("min");
			  	expect(r3.hint).toEqual("长度不小于5");
			  	expect(r3.test("abc")).toEqual(false);
			  	expect(r3.test("abcde")).toEqual(true);
			  	expect(r3.test("abcdef")).toEqual(true);

		  	});
		});

		waitsFor(function(){
			return ready;
		});
	});
});

describe("带参数预设配置 {test:\"max:5\",hint:\"长度不大于{0}\"}",function(){
	it("name为\"max\"，hint为\"长度不大于5\"，test abc为true，abcde为true，abcdef为false",function(){

		var ready = false;
		runs(function(){
			NR.provide('form/rule',function(D,Rule){
				ready = true;

				var r3 = Rule.produce({
					test:"max:5",
					hint:"长度不大于{0}"
				});

			  	expect(r3.name).toEqual("max");
			  	expect(r3.hint).toEqual("长度不大于5");
			  	expect(r3.test("abc")).toEqual(true);
			  	expect(r3.test("abcde")).toEqual(true);
			  	expect(r3.test("abcdef")).toEqual(false);

		  	});
		});

		waitsFor(function(){
			return ready;
		});
	});
});

describe("参数预设配置 in:a,b,c",function(){
	it("name为in",function(){

		var ready = false;
		runs(function(){
			NR.provide('form/rule',function(D,Rule){
				ready = true;

				var r1 = Rule.produce("in:a,b,c");
			  	expect(r1.name).toEqual("in");
			  	expect(r1.test("a")).toEqual(true);
			  	expect(r1.test("b")).toEqual(true);
			  	expect(r1.test("c")).toEqual(true);
			  	expect(r1.test("d")).toEqual(false);
			  	expect(r1.hint).toEqual(null);
		  	});
		});

		waitsFor(function(){
			return ready;
		});
	});
});

describe("自定义函数test",function(){
	it("name为\"mytest\"，hint为\"值必须为123\"，test 123为true",function(){

		var ready = false;
		runs(function(){
			NR.provide('form/rule',function(D,Rule){
				ready = true;

				var r4 = Rule.produce({
					name:"mytest",
					test:function(v){
						return v === 123;
					},
					hint:"值必须为123"
				});

		  		expect(r4.name).toEqual("mytest");
		  		expect(r4.hint).toEqual("值必须为123");
		  		expect(r4.test(123)).toEqual(true);

		  	});
		});

		waitsFor(function(){
			return ready;
		});
	});
});<|endoftext|>


<commit_before>---
---
$(function() {
  $('#search-button').on('click', function() {
    return search();
  });

  $('#search-query').on('keyup', function() {
    return search();
  });

  function search() {
    var query   = $('#search-query').val();
    var result  = $('#search-results');
    var entries = $('#search-results .entries');

    if (!query.trim()) {
      result.hide();
      entries.empty();
    } else {
      var results = idx.search(query).slice(0, 100).map(function(result) {
        return docsMap[result.ref];
      });

      if (!results.length) {
        results = docsMap[query] ? [docsMap[query]] : [];
      }

      entries.empty();

      if (results.length) {
        results.forEach(function(page) {
          entries.append('
'+
          '
'+
          '    '+page.kanji+' '+page.keyword+''+
          '
'+
          '
');
        });
      } else {
        entries.append('
Kanji not found :-(
');
      }

      result.show();
    }
  }
});
<commit_msg>Showing multiple kanjis (#1)<commit_after>---
---
$(function() {
  $('#search-button').on('click', function() {
    return search();
  });

  $('#search-query').on('keyup', function() {
    return search();
  });

  function search() {
    var query   = $('#search-query').val();
    var result  = $('#search-results');
    var entries = $('#search-results .entries');

    if (!query.trim()) {
      result.hide();
      entries.empty();
    } else {
      var results = idx.search(query).slice(0, 100).map(function(result) {
        return docsMap[result.ref];
      });

      if (!results.length) {
        results = query.replace(/[a-zA-Z0-9]/g, '')
          .split('')
          .map(function(kanji) {
            return docsMap[kanji] ? docsMap[kanji] : null;
          })
          .filter(function(doc) {
            return doc !== null;
          });
      }

      entries.empty();

      if (results.length) {
        results.forEach(function(page) {
          entries.append('
'+
          '
'+
          '    '+page.kanji+' '+page.keyword+''+
          '
'+
          '
');
        });
      } else {
        entries.append('
Kanji not found :-(
');
      }

      result.show();
    }
  }
});
<|endoftext|>


<commit_before>/* globals chai, Mace, ace */
/**
 * Mace Test
 * for browser
 */

var expect = chai.expect;

describe("Mace", function () {
  var Ace = {
    Range: ace.require("ace/range").Range
  };

  var mace;
  before(function () {
    var editor = document.createElement("div"),
        preview = document.createElement("div");

    editor.appendChild(document.createTextNode("test"));

    mace = new Mace(editor, preview);
    expect(mace).to.have.property("value").and.to.equal("test");
  });
  beforeEach(function () {
    mace.ace.selection.clearSelection();
    mace.clear(true);
    expect(mace.value).to.equal("");
    mace.font_size = 12;
  });

  it("check properties", function () {
    expect(mace).to.have.property("ace").and.to.be.an("object");
    expect(mace).to.have.property("editor").and.to.be.an("object");
    expect(mace).to.have.property("preview").and.to.be.an("object");
  });

  it("value", function () {
    mace.ace.insert("hello");
    expect(mace).to.have.property("value").and.to.equal("hello");
  });

  it("font_size", function () {
    expect(mace).to.have.property("font_size").and.to.equal(12);
    expect(++mace.font_size).to.equal(13);
  });

  it("#clear (remove all)", function () {
    mace.ace.insert("clear");
    mace.clear(true);
    expect(mace.value).to.equal("");
  });

  it("#clear (remove current line)", function () {
    mace.ace.insert("clear\nline");
    mace.clear();
    expect(mace.value).to.equal("clear");
  });

  it("#indent", function () {
    mace.indent();
    expect(mace.value).to.equal("    ");
  });

  it("#outdent", function () {
    mace.indent(2);
    mace.outdent();
    expect(mace.value).to.equal("    ");
  });

  it("#heading", function () {
    mace.ace.insert("Mace");
    mace.ace.moveCursorTo(0, 0);
    mace.heading();
    expect(mace.value).to.equal("#Mace");
    expect(mace.ace.getCursorPosition().column).to.equal(1);
  });

  it("#heading (level up 1 -> 2)", function () {
    mace.ace.insert("#Mace");
    mace.ace.moveCursorTo(0, 1);
    mace.heading(2);
    expect(mace.value).to.equal("##Mace");
    expect(mace.ace.getCursorPosition().column).to.equal(2);
  });

  it("#heading (level down 2 -> 1)", function () {
    mace.ace.insert("##Mace");
    mace.ace.moveCursorTo(0, 2);
    mace.heading(1);
    expect(mace.value).to.equal("#Mace");
    expect(mace.ace.getCursorPosition().column).to.equal(1);
  });

  it("#heading (select a line)", function () {
    mace.ace.insert("##Mace\nMace = Markdown editor powered by Ace.\n");
    var range = new Ace.Range(1, 0, 2, 0);
    mace.ace.moveCursorTo(2, 0);
    mace.ace.selection.addRange(range);
    mace.heading(3);
    expect(mace.value).to.equal("##Mace\n###Mace = Markdown editor powered by Ace.\n");
  });

  it("#heading (select multi lines)", function () {
    mace.ace.insert("##Mace\n###Mace = Markdown editor powered by Ace.\n\n");
    var range = new Ace.Range(0, 0, 2, 0);
    mace.ace.moveCursorTo(2, 0);
    mace.ace.selection.addRange(range);
    mace.heading(3);
    expect(mace.value).to.equal("###Mace\n###Mace = Markdown editor powered by Ace.\n###\n");
  });

  it("#heading (range check)", function () {
    expect(mace.heading.bind(mace, -1)).to.throw(RangeError);
    expect(mace.heading.bind(mace, 7)).to.throw(RangeError);
  });

  it("#link (empty)", function () {
    mace.link();
    expect(mace.value).to.equal("[link](./)");
  });

  it("#link (select)", function () {
    mace.ace.insert("This is a editor.");
    var range = new Ace.Range(0, 10, 0, 16);
    mace.ace.moveCursorTo(0, 16);
    mace.ace.selection.addRange(range);
    mace.link("https://github.com/ww24/mace");
    expect(mace.value).to.equal("This is a [editor](https://github.com/ww24/mace).");
  });

  it("#link (select & set link_text)", function () {
    mace.ace.insert("This is a editor.");
    var range = new Ace.Range(0, 10, 0, 16);
    mace.ace.moveCursorTo(0, 16);
    mace.ace.selection.addRange(range);
    mace.link("https://github.com/ww24/mace", "mace");
    expect(mace.value).to.equal("This is a [mace](https://github.com/ww24/mace).");
  });

  it("#link (select & set link_text & set title)", function () {
    mace.ace.insert("This is a editor.");
    var range = new Ace.Range(0, 10, 0, 16);
    mace.ace.moveCursorTo(0, 16);
    mace.ace.selection.addRange(range);
    mace.link("https://github.com/ww24/mace", "mace", "title");
    expect(mace.value).to.equal("This is a [mace](https://github.com/ww24/mace \"title\").");
  });

  it("#link (select & set link_text & set title & image)", function () {
    mace.ace.insert("This is a editor.");
    var range = new Ace.Range(0, 10, 0, 16);
    mace.ace.moveCursorTo(0, 16);
    mace.ace.selection.addRange(range);
    mace.link("https://github.com/ww24/mace", "mace", "title", true);
    expect(mace.value).to.equal("This is a ![mace](https://github.com/ww24/mace \"title\").");
  });

  it("getLineText", function () {
    mace.ace.insert("This is a editor.");
    var text = mace.getLineText();
    expect(text).to.equal("This is a editor.");
  });

  it("#list", function () {
    mace.ace.insert("list item 1");
    mace.list();
    expect(mace.value).to.equal("- list item 1");
  });

  it("#list toggle reset", function () {
    mace.ace.insert("- list item 1");
    mace.list();
    expect(mace.value).to.equal("list item 1");
  });

  it("#list *", function () {
    mace.ace.insert("list item 1");
    mace.list("*");
    expect(mace.value).to.equal("* list item 1");
  });

  it("#list multi lines", function () {
    mace.ace.insert("list item 1\nlist item 2");
    var range = new Ace.Range(0, 0, 1, 1);
    mace.ace.moveCursorTo(0, 0);
    mace.ace.selection.addRange(range);
    mace.list();
    expect(mace.value).to.equal("- list item 1\n- list item 2");
  });

  it("#list multi lines (toggle reset)", function () {
    mace.ace.insert("- list item 1\n- list item 2");
    var range = new Ace.Range(0, 0, 1, 1);
    mace.ace.moveCursorTo(0, 0);
    mace.ace.selection.addRange(range);
    mace.list();
    expect(mace.value).to.equal("list item 1\nlist item 2");
  });

  it("#code", function () {
    mace.code();
    expect(mace.value).to.equal("```\n\n```");
    var pos = mace.ace.getCursorPosition();
    expect(pos.row).to.equal(1);
    expect(pos.column).to.equal(0);
  });

  it("#code selection", function () {
    mace.ace.insert("1. console.log(\"test\"); is debug message.");
    var range = new Ace.Range(0, 3, 0, 23);
    mace.ace.moveCursorTo(0, 3);
    mace.ace.selection.addRange(range);

    mace.code();

    expect(mace.value).to.equal("1. `console.log(\"test\");` is debug message.");
    expect(mace.ace.getCursorPosition().column).to.equal(25);
  });

  it("#code multi lines", function () {
    mace.ace.insert("function () {\n  console.log(\"test\");\n}\n");
    var range = new Ace.Range(0, 0, 3, 0);
    mace.ace.moveCursorTo(0, 0);
    mace.ace.selection.addRange(range);

    mace.code();

    expect(mace.value).to.equal("```\nfunction () {\n  console.log(\"test\");\n}\n```\n");

    var pos = mace.ace.getCursorPosition();
    expect(pos.row).to.equal(5);
    expect(pos.column).to.equal(0);
  });

  it.skip("#code set language", function () {
    mace.ace.insert("function () {\n  console.log(\"test\");\n}\n");
    var range = new Ace.Range(0, 0, 3, 0);
    mace.ace.moveCursorTo(0, 0);
    mace.ace.selection.addRange(range);

    mace.code("js");

    expect(mace.value).to.equal("```js\nfunction () {\n  console.log(\"test\");\n}\n```\n");

    var pos = mace.ace.getCursorPosition();
    expect(pos.row).to.equal(5);
    expect(pos.column).to.equal(0);
  });
});
<commit_msg>Fix test<commit_after>/* globals chai, Mace, ace */
/**
 * Mace Test
 * for browser
 */

var expect = chai.expect;

describe("Mace", function () {
  var Ace = {
    Range: ace.require("ace/range").Range
  };

  var mace;
  before(function () {
    var editor = document.createElement("div"),
        preview = document.createElement("div");

    editor.appendChild(document.createTextNode("test"));

    mace = new Mace(editor, preview);
    expect(mace).to.have.property("value").and.to.equal("test");
  });
  beforeEach(function () {
    mace.ace.selection.clearSelection();
    mace.clear(true);
    expect(mace.value).to.equal("");
    mace.font_size = 12;
  });

  it("check properties", function () {
    expect(mace).to.have.property("ace").and.to.be.an("object");
    expect(mace).to.have.property("editor").and.to.be.an("object");
    expect(mace).to.have.property("preview").and.to.be.an("object");
  });

  it("value", function () {
    mace.ace.insert("hello");
    expect(mace).to.have.property("value").and.to.equal("hello");
  });

  it("font_size", function () {
    expect(mace).to.have.property("font_size").and.to.equal(12);
    expect(++mace.font_size).to.equal(13);
  });

  it("#clear (remove all)", function () {
    mace.ace.insert("clear");
    mace.clear(true);
    expect(mace.value).to.equal("");
  });

  it("#clear (remove current line)", function () {
    mace.ace.insert("clear\nline");
    mace.clear();
    expect(mace.value).to.equal("clear");
  });

  it("#indent", function () {
    mace.indent();
    expect(mace.value).to.equal("    ");
  });

  it("#outdent", function () {
    mace.indent(2);
    mace.outdent();
    expect(mace.value).to.equal("    ");
  });

  it("#heading", function () {
    mace.ace.insert("Mace");
    mace.ace.moveCursorTo(0, 0);
    mace.heading();
    expect(mace.value).to.equal("#Mace");
    expect(mace.ace.getCursorPosition().column).to.equal(1);
  });

  it("#heading (level up 1 -> 2)", function () {
    mace.ace.insert("#Mace");
    mace.ace.moveCursorTo(0, 1);
    mace.heading(2);
    expect(mace.value).to.equal("##Mace");
    expect(mace.ace.getCursorPosition().column).to.equal(2);
  });

  it("#heading (level down 2 -> 1)", function () {
    mace.ace.insert("##Mace");
    mace.ace.moveCursorTo(0, 2);
    mace.heading(1);
    expect(mace.value).to.equal("#Mace");
    expect(mace.ace.getCursorPosition().column).to.equal(1);
  });

  it("#heading (select a line)", function () {
    mace.ace.insert("##Mace\nMace = Markdown editor powered by Ace.\n");
    var range = new Ace.Range(1, 0, 2, 0);
    mace.ace.moveCursorTo(2, 0);
    mace.ace.selection.addRange(range);
    mace.heading(3);
    expect(mace.value).to.equal("##Mace\n###Mace = Markdown editor powered by Ace.\n");
  });

  it("#heading (select multi lines)", function () {
    mace.ace.insert("##Mace\n###Mace = Markdown editor powered by Ace.\n\n");
    var range = new Ace.Range(0, 0, 2, 0);
    mace.ace.moveCursorTo(2, 0);
    mace.ace.selection.addRange(range);
    mace.heading(3);
    expect(mace.value).to.equal("###Mace\n###Mace = Markdown editor powered by Ace.\n###\n");
  });

  it("#heading (range check)", function () {
    expect(mace.heading.bind(mace, -1)).to.throw(RangeError);
    expect(mace.heading.bind(mace, 7)).to.throw(RangeError);
  });

  it("#link (empty)", function () {
    mace.link();
    expect(mace.value).to.equal("[link](./)");
  });

  it("#link (select)", function () {
    mace.ace.insert("This is a editor.");
    var range = new Ace.Range(0, 10, 0, 16);
    mace.ace.moveCursorTo(0, 16);
    mace.ace.selection.addRange(range);
    mace.link("https://github.com/ww24/mace");
    expect(mace.value).to.equal("This is a [editor](https://github.com/ww24/mace).");
  });

  it("#link (select & set link_text)", function () {
    mace.ace.insert("This is a editor.");
    var range = new Ace.Range(0, 10, 0, 16);
    mace.ace.moveCursorTo(0, 16);
    mace.ace.selection.addRange(range);
    mace.link("https://github.com/ww24/mace", "mace");
    expect(mace.value).to.equal("This is a [mace](https://github.com/ww24/mace).");
  });

  it("#link (select & set link_text & set title)", function () {
    mace.ace.insert("This is a editor.");
    var range = new Ace.Range(0, 10, 0, 16);
    mace.ace.moveCursorTo(0, 16);
    mace.ace.selection.addRange(range);
    mace.link("https://github.com/ww24/mace", "mace", "title");
    expect(mace.value).to.equal("This is a [mace](https://github.com/ww24/mace \"title\").");
  });

  it("#link (select & set link_text & set title & image)", function () {
    mace.ace.insert("This is a editor.");
    var range = new Ace.Range(0, 10, 0, 16);
    mace.ace.moveCursorTo(0, 16);
    mace.ace.selection.addRange(range);
    mace.link("https://github.com/ww24/mace", "mace", "title", true);
    expect(mace.value).to.equal("This is a ![mace](https://github.com/ww24/mace \"title\").");
  });

  it("getLineText", function () {
    mace.ace.insert("This is a editor.");
    var text = mace.getLineText();
    expect(text).to.equal("This is a editor.");
  });

  it("#list", function () {
    mace.ace.insert("list item 1");
    mace.list();
    expect(mace.value).to.equal("- list item 1");
  });

  it("#list toggle reset", function () {
    mace.ace.insert("- list item 1");
    mace.list();
    expect(mace.value).to.equal("list item 1");
  });

  it("#list *", function () {
    mace.ace.insert("list item 1");
    mace.list("*");
    expect(mace.value).to.equal("* list item 1");
  });

  it("#list multi lines", function () {
    mace.ace.insert("list item 1\nlist item 2");
    var range = new Ace.Range(0, 0, 1, 1);
    mace.ace.moveCursorTo(0, 0);
    mace.ace.selection.addRange(range);
    mace.list();
    expect(mace.value).to.equal("- list item 1\n- list item 2");
  });

  it("#list multi lines (toggle reset)", function () {
    mace.ace.insert("- list item 1\n- list item 2");
    var range = new Ace.Range(0, 0, 1, 1);
    mace.ace.moveCursorTo(0, 0);
    mace.ace.selection.addRange(range);
    mace.list();
    expect(mace.value).to.equal("list item 1\nlist item 2");
  });

  it("#code", function () {
    mace.code();
    expect(mace.value).to.equal("```\n\n```");
    var pos = mace.ace.getCursorPosition();
    expect(pos.row).to.equal(1);
    expect(pos.column).to.equal(0);
  });

  it("#code selection", function () {
    mace.ace.insert("1. console.log(\"test\"); is debug message.");
    var range = new Ace.Range(0, 3, 0, 23);
    mace.ace.moveCursorTo(0, 3);
    mace.ace.selection.addRange(range);

    mace.code();

    expect(mace.value).to.equal("1. `console.log(\"test\");` is debug message.");
    expect(mace.ace.getCursorPosition().column).to.equal(25);
  });

  it("#code multi lines", function () {
    mace.ace.insert("function () {\n  console.log(\"test\");\n}\n");
    var range = new Ace.Range(0, 0, 3, 0);
    mace.ace.moveCursorTo(0, 0);
    mace.ace.selection.addRange(range);

    mace.code();

    expect(mace.value).to.equal("```\nfunction () {\n  console.log(\"test\");\n}\n```\n");

    var pos = mace.ace.getCursorPosition();
    expect(pos.row).to.equal(5);
    expect(pos.column).to.equal(0);
  });

  it("#code set language", function () {
    mace.ace.insert("function () {\n  console.log(\"test\");\n}");
    var range = new Ace.Range(0, 0, 2, 1);
    mace.ace.moveCursorTo(0, 0);
    mace.ace.selection.addRange(range);

    mace.code("js");

    expect(mace.value).to.equal("```js\nfunction () {\n  console.log(\"test\");\n}\n```\n");

    var pos = mace.ace.getCursorPosition();
    expect(pos.row).to.equal(5);
    expect(pos.column).to.equal(0);
  });
});
<|endoftext|>


<commit_before>/*

The MIT License (MIT)
Copyright (c) 2012 Donovan Buck

Permission is hereby granted, free of charge, to any person obtaining a copy of this
software and associated documentation files (the "Software"), to deal in the Software
without restriction, including without limitation the rights to use, copy, modify,
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be included in all copies
or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

*/

/*

Command line parameters

	## Logging
	----------------------------------------------------------------------
	To set logging level use command line argument "--log loglevel"

	The valid values for loglevel are:

		error - Logs SPAS errors only
		warn - Adds communication issues with 3rd party API's
		data - [default] Adds all billable transaction events (request to API's & request for bundles)
		info - Adds program flow (function calls, enqueued jobs, etc)
		debug - Adds all datapoints other than API responses and bundles
		verbose - Adds everything (API Responses, conmpleted bundles, etc).
		input - Adds all requests and parameters

	##  Environment
	----------------------------------------------------------------------
	spas has two branches in the configuration file: development and live

	Passing the command line argument "--dev" will use the development node, otherwise live will be used

	## Execution mode
	----------------------------------------------------------------------
	spas can run as a service by passing the "--service" command line argument.

	Without "--service" spas will run in the console

*/

GLOBAL.bundles = {};
GLOBAL.cronjobs = [];
GLOBAL.config = {};

// ## Module dependencies.
var
  // My lib files
  configure = require('./lib/config')
  , winston = require('./lib/logging').winston
  , bundleManager = require('./lib/bundleManager')
  , engine = require('./lib/engine')
  , oauth = require('./lib/oauth')
  , oauth2 = require('./lib/oauth2')
  , keystone2 = require('./lib/keystone2')

  // Built in modules
    http = require('http')
  , url = require('url')
  , querystring = require('querystring')
  , fs = require('fs')
  , spawn = require('child_process').spawn

  // Other Dependencies
  , director = require('director')
  , _ = require('underscore')._
;

if (GLOBAL.config.args.create) {
	process.exit();
}

//
// ## Run spas as a service
//
if (GLOBAL.config.args.service) {

	// Specify output and error log file directories
	if (!fs.existsSync(process.cwd() + '/logs')) {
		fs.mkdirSync(process.cwd() + '/logs');
	}

	// These files should not be used. All output should be to the
	// Winston log files which are rotated daily
	var	out = fs.openSync(process.cwd() + '/logs/spasout.log', 'a'),
		err = fs.openSync(process.cwd() + '/logs/spaserr.log', 'a');

	// Spawn the main SPAS application
	var params = GLOBAL.config.isLocal ? ['spas'] : [];
	if (GLOBAL.config.args.dev) params.push('--dev');
	if (GLOBAL.config.args.log) {
		params.push('--log');
		params.push(GLOBAL.config.args.log);
	}

	var spasService = spawn(GLOBAL.config.isLocal ? 'node' : 'spas', params, { detached: true, stdio: [ 'ignore', out, err ] });

	spasService.unref();

	process.exit();

} else {

	// ## See if client will accept gzip encoding
	var acceptGZip = function(headers) {
		if (_.has(headers, "accept-encoding") && headers["accept-encoding"].match(/\bgzip\b/)) {
			return true;
		} else {
			return false;
		}
	}

	// ## Our Routes
	var router = new director.http.Router({

		// These are the return routes for authentication services
		'/oauth': {
			get: function() {
				var nonce = querystring.parse((url.parse(this.req.url).query)).oauth_nonce;

				if (!_.isUndefined(nonce)) {

					var nonceArray = nonce.split(","),
					bid = nonceArray[0],
					key = nonceArray[1],
					self = this;

					oauth.saveOauthToken( GLOBAL.bundles[bid][key], querystring.parse((url.parse(this.req.url).query)).oauth_nonce, querystring.parse((url.parse(this.req.url).query)).oauth_token, function( tout ) {

						if (_.has(tout, 'redirect')) {
							self.res.statusCode = 302;
							self.res.setHeader("Location", tout.redirect);
							self.res.end();
						}

					});
				} else {

					this.res.writeHead(404);
					this.res.end();

				}

			}
		},

		'/oauth2': {
			get: function() {
				var self = this;

				winston.info('oauth2 callback reqeusted');
				winston.debug(JSON.stringify(querystring.parse((url.parse(this.req.url).query))));

				oauth2.saveCode ( this.res, querystring.parse((url.parse(this.req.url).query)).state.split(','), querystring.parse((url.parse(this.req.url).query)).code, function( tout ) {
					if (_.has(tout, 'redirect')) {
						self.res.statusCode = 302;
						self.res.setHeader("Location", tout.redirect);
						self.res.end();
					}
				});
			}
		},

		// A bundle is being requested using the old, deprecated format 'http://domain.com/bundle/bundlename'
		'/bundle/:bid': {
	    	get: function(bid) {
	    		var gzip = acceptGZip(this.req.headers);
	    		winston.error('Old style bundle request made for ' + bid);
	    		engine.fulfill ( this.res, this.req.headers['x-forwarded-for'] || this.req.connection.remoteAddress, bid, querystring.parse((url.parse(this.req.url).query)).callback, gzip );
	    	}
		},

		// A bundle is being requested in the format 'http://domain.com/bundlename'
		'/:bid': {
	    	get: function(bid) {
	    		var gzip = acceptGZip(this.req.headers);
	    		engine.fulfill ( this.res, this.req.headers['x-forwarded-for'] || this.req.connection.remoteAddress, bid, querystring.parse((url.parse(this.req.url).query)).callback, gzip );
	    	}
		},

		// A bundle is being requested in the format 'http://bundlename.domain.com'
		'/': {
	    	get: function() {
	    		var gzip = acceptGZip(this.req.headers);
                bid = _.has(this.req.headers, 'host') ? this.req.headers.host.split('.')[0] : '';
                engine.fulfill ( this.res, this.req.headers['x-forwarded-for'] || this.req.connection.remoteAddress, bid, querystring.parse((url.parse(this.req.url).query)).callback, gzip );
	    	}
		}
	});

	// ### Create our server
	var server = http.createServer(function (req, res) {
		router.dispatch(req, res, function (err) {
			if (err) {
				res.writeHead(404);
				res.end();
			}
		});
	});

	//
	// ## Listener for bundle updater
	//
	var bundler = new bundleManager();
	bundler.refreshBundles();

	server.listen(GLOBAL.config.port);
	winston.info('Listening on port ' + GLOBAL.config.port);
}
<commit_msg>Added missing comma<commit_after>/*

The MIT License (MIT)
Copyright (c) 2012 Donovan Buck

Permission is hereby granted, free of charge, to any person obtaining a copy of this
software and associated documentation files (the "Software"), to deal in the Software
without restriction, including without limitation the rights to use, copy, modify,
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be included in all copies
or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

*/

/*

Command line parameters

	## Logging
	----------------------------------------------------------------------
	To set logging level use command line argument "--log loglevel"

	The valid values for loglevel are:

		error - Logs SPAS errors only
		warn - Adds communication issues with 3rd party API's
		data - [default] Adds all billable transaction events (request to API's & request for bundles)
		info - Adds program flow (function calls, enqueued jobs, etc)
		debug - Adds all datapoints other than API responses and bundles
		verbose - Adds everything (API Responses, conmpleted bundles, etc).
		input - Adds all requests and parameters

	##  Environment
	----------------------------------------------------------------------
	spas has two branches in the configuration file: development and live

	Passing the command line argument "--dev" will use the development node, otherwise live will be used

	## Execution mode
	----------------------------------------------------------------------
	spas can run as a service by passing the "--service" command line argument.

	Without "--service" spas will run in the console

*/

GLOBAL.bundles = {};
GLOBAL.cronjobs = [];
GLOBAL.config = {};

// ## Module dependencies.
var
  // My lib files
  configure = require('./lib/config')
  , winston = require('./lib/logging').winston
  , bundleManager = require('./lib/bundleManager')
  , engine = require('./lib/engine')
  , oauth = require('./lib/oauth')
  , oauth2 = require('./lib/oauth2')
  , keystone2 = require('./lib/keystone2')

  // Built in modules
  , http = require('http')
  , url = require('url')
  , querystring = require('querystring')
  , fs = require('fs')
  , spawn = require('child_process').spawn

  // Other Dependencies
  , director = require('director')
  , _ = require('underscore')._
;

if (GLOBAL.config.args.create) {
	process.exit();
}

//
// ## Run spas as a service
//
if (GLOBAL.config.args.service) {

	// Specify output and error log file directories
	if (!fs.existsSync(process.cwd() + '/logs')) {
		fs.mkdirSync(process.cwd() + '/logs');
	}

	// These files should not be used. All output should be to the
	// Winston log files which are rotated daily
	var	out = fs.openSync(process.cwd() + '/logs/spasout.log', 'a'),
		err = fs.openSync(process.cwd() + '/logs/spaserr.log', 'a');

	// Spawn the main SPAS application
	var params = GLOBAL.config.isLocal ? ['spas'] : [];
	if (GLOBAL.config.args.dev) params.push('--dev');
	if (GLOBAL.config.args.log) {
		params.push('--log');
		params.push(GLOBAL.config.args.log);
	}

	var spasService = spawn(GLOBAL.config.isLocal ? 'node' : 'spas', params, { detached: true, stdio: [ 'ignore', out, err ] });

	spasService.unref();

	process.exit();

} else {

	// ## See if client will accept gzip encoding
	var acceptGZip = function(headers) {
		if (_.has(headers, "accept-encoding") && headers["accept-encoding"].match(/\bgzip\b/)) {
			return true;
		} else {
			return false;
		}
	}

	// ## Our Routes
	var router = new director.http.Router({

		// These are the return routes for authentication services
		'/oauth': {
			get: function() {
				var nonce = querystring.parse((url.parse(this.req.url).query)).oauth_nonce;

				if (!_.isUndefined(nonce)) {

					var nonceArray = nonce.split(","),
					bid = nonceArray[0],
					key = nonceArray[1],
					self = this;

					oauth.saveOauthToken( GLOBAL.bundles[bid][key], querystring.parse((url.parse(this.req.url).query)).oauth_nonce, querystring.parse((url.parse(this.req.url).query)).oauth_token, function( tout ) {

						if (_.has(tout, 'redirect')) {
							self.res.statusCode = 302;
							self.res.setHeader("Location", tout.redirect);
							self.res.end();
						}

					});
				} else {

					this.res.writeHead(404);
					this.res.end();

				}

			}
		},

		'/oauth2': {
			get: function() {
				var self = this;

				winston.info('oauth2 callback reqeusted');
				winston.debug(JSON.stringify(querystring.parse((url.parse(this.req.url).query))));

				oauth2.saveCode ( this.res, querystring.parse((url.parse(this.req.url).query)).state.split(','), querystring.parse((url.parse(this.req.url).query)).code, function( tout ) {
					if (_.has(tout, 'redirect')) {
						self.res.statusCode = 302;
						self.res.setHeader("Location", tout.redirect);
						self.res.end();
					}
				});
			}
		},

		// A bundle is being requested using the old, deprecated format 'http://domain.com/bundle/bundlename'
		'/bundle/:bid': {
	    	get: function(bid) {
	    		var gzip = acceptGZip(this.req.headers);
	    		winston.error('Old style bundle request made for ' + bid);
	    		engine.fulfill ( this.res, this.req.headers['x-forwarded-for'] || this.req.connection.remoteAddress, bid, querystring.parse((url.parse(this.req.url).query)).callback, gzip );
	    	}
		},

		// A bundle is being requested in the format 'http://domain.com/bundlename'
		'/:bid': {
	    	get: function(bid) {
	    		var gzip = acceptGZip(this.req.headers);
	    		engine.fulfill ( this.res, this.req.headers['x-forwarded-for'] || this.req.connection.remoteAddress, bid, querystring.parse((url.parse(this.req.url).query)).callback, gzip );
	    	}
		},

		// A bundle is being requested in the format 'http://bundlename.domain.com'
		'/': {
	    	get: function() {
	    		var gzip = acceptGZip(this.req.headers);
                bid = _.has(this.req.headers, 'host') ? this.req.headers.host.split('.')[0] : '';
                engine.fulfill ( this.res, this.req.headers['x-forwarded-for'] || this.req.connection.remoteAddress, bid, querystring.parse((url.parse(this.req.url).query)).callback, gzip );
	    	}
		}
	});

	// ### Create our server
	var server = http.createServer(function (req, res) {
		router.dispatch(req, res, function (err) {
			if (err) {
				res.writeHead(404);
				res.end();
			}
		});
	});

	//
	// ## Listener for bundle updater
	//
	var bundler = new bundleManager();
	bundler.refreshBundles();

	server.listen(GLOBAL.config.port);
	winston.info('Listening on port ' + GLOBAL.config.port);
}
<|endoftext|>