<commit_before>"use strict";
var config = require("config"),
    fs = require("fs"),
    path = require("path"),
    seeder = require("./seed"),
    startupHooks = require("../startup_hooks");

let mongoose = require("mongoose-q")(require("mongoose"), {
    spread: true,
    q: require("q-bluebird")
});
let debug = require("debug")("app:persistence");
let models = {};

/**
 * Initializes the MongoDB Connection
 */
function connect() {
    let db = config.database;

    let isComposed = () => parseInt(config.container.composed);
    let composeConnectionString = () => {
        let host = db.composeConnection.host;
        let port = db.composeConnection.port;
        let dbName = db.composeConnection.dbName;
        return `mongodb://${host}:${port}/${dbName}`;
    };
    let connectionString = isComposed() ? composeConnectionString() : db.connectionString;
    mongoose.connect(connectionString);
}

function disconnect() {
    mongoose.disconnect();
}

/**
 * Dynamically load model types
 */
function getModels() {
    let modelNames = fs.readdirSync(path.join(__dirname, "models")),
        loadModel = (modelName) => {
            debug(`loading model ${modelName}`);
            let modelFunction = require(`./models/${modelName}`);
            debug(`preparing model ${modelName}`);
            models[modelName] = modelFunction(mongoose);
        };

    modelNames.forEach(loadModel);
}

/**
 * Populate seed data
 * @returns {*}
 */
function populateSeed() {
    if (config.database.populateSeedData) {
        debug("loading seed data");
        let seedingPromise = seeder.seedData(models);
        startupHooks.addHook(seedingPromise);
    }
}

debug("Initializing Persistence");
connect();
getModels();
populateSeed();

module.exports = {models, disconnect};
<commit_msg>#82 - Removing vestigial disconnect method<commit_after>"use strict";
var config = require("config"),
    fs = require("fs"),
    path = require("path"),
    seeder = require("./seed"),
    startupHooks = require("../startup_hooks");

let mongoose = require("mongoose-q")(require("mongoose"), {
    spread: true,
    q: require("q-bluebird")
});
let debug = require("debug")("app:persistence");
let models = {};

/**
 * Initializes the MongoDB Connection
 */
function connect() {
    let db = config.database;

    let isComposed = () => parseInt(config.container.composed);
    let composeConnectionString = () => {
        let host = db.composeConnection.host;
        let port = db.composeConnection.port;
        let dbName = db.composeConnection.dbName;
        return `mongodb://${host}:${port}/${dbName}`;
    };
    let connectionString = isComposed() ? composeConnectionString() : db.connectionString;
    mongoose.connect(connectionString);
}

/**
 * Dynamically load model types
 */
function getModels() {
    let modelNames = fs.readdirSync(path.join(__dirname, "models")),
        loadModel = (modelName) => {
            debug(`loading model ${modelName}`);
            let modelFunction = require(`./models/${modelName}`);
            debug(`preparing model ${modelName}`);
            models[modelName] = modelFunction(mongoose);
        };

    modelNames.forEach(loadModel);
}

/**
 * Populate seed data
 * @returns {*}
 */
function populateSeed() {
    if (config.database.populateSeedData) {
        debug("loading seed data");
        let seedingPromise = seeder.seedData(models);
        startupHooks.addHook(seedingPromise);
    }
}

debug("Initializing Persistence");
connect();
getModels();
populateSeed();

module.exports = {models};
<|endoftext|>


<commit_before>odoo.define('hr_attendance.kiosk_mode', function (require) {
"use strict";

var core = require('web.core');
var Model = require('web.Model');
var Widget = require('web.Widget');
var Session = require('web.session');
var BarcodeHandlerMixin = require('barcodes.BarcodeHandlerMixin');

var QWeb = core.qweb;
var _t = core._t;

var KioskMode = Widget.extend(BarcodeHandlerMixin, {
    events: {
        "click .o_hr_attendance_button_employees": function(){ this.do_action('hr_attendance.hr_employee_attendance_action_kanban'); },
    },

    init: function (parent, action) {
        // Note: BarcodeHandlerMixin.init calls this._super.init, so there's no need to do it here.
        // Yet, "_super" must be present in a function for the class mechanism to replace it with the actual parent method.
        this._super;
        BarcodeHandlerMixin.init.apply(this, arguments);
    },

    start: function () {
        var self = this;
        self.session = Session;
        var res_company = new Model('res.company');
        res_company.query(['name'])
           .filter([['id', '=', self.session.company_id]])
           .all()
           .then(function (companies){
                self.company_name = companies[0].name;
                self.company_image_url = self.session.url('/web/image', {model: 'res.company', id: self.session.company_id, field: 'logo',})
                self.$el.html(QWeb.render("HrAttendanceKioskMode", {widget: self}));
                self.start_clock();
            });
        return self._super.apply(this, arguments);
    },

    on_barcode_scanned: function(barcode) {
        var self = this;
        var hr_employee = new Model('hr.employee');
        hr_employee.call('attendance_scan', [barcode, ])
            .then(function (result) {
                if (result.action) {
                    self.do_action(result.action);
                } else if (result.warning) {
                    self.do_warn(result.warning);
                }
            });
    },

    start_clock: function() {
        this.clock_start = setInterval(function() {this.$(".o_hr_attendance_clock").text(new Date().toLocaleTimeString(navigator.language, {hour: '2-digit', minute:'2-digit'}));}, 500);
        // First clock refresh before interval to avoid delay
        this.$(".o_hr_attendance_clock").text(new Date().toLocaleTimeString(navigator.language, {hour: '2-digit', minute:'2-digit'}));
    },

    destroy: function () {
        clearInterval(this.clock_start);
        this._super.apply(this, arguments);
    },
});

core.action_registry.add('hr_attendance_kiosk_mode', KioskMode);

return KioskMode;

});
<commit_msg>[FIX] hr_attendance: Keep the kiosk session alive<commit_after>odoo.define('hr_attendance.kiosk_mode', function (require) {
"use strict";

var core = require('web.core');
var Model = require('web.Model');
var Widget = require('web.Widget');
var Session = require('web.session');
var BarcodeHandlerMixin = require('barcodes.BarcodeHandlerMixin');

var QWeb = core.qweb;
var _t = core._t;

var KioskMode = Widget.extend(BarcodeHandlerMixin, {
    events: {
        "click .o_hr_attendance_button_employees": function(){ this.do_action('hr_attendance.hr_employee_attendance_action_kanban'); },
    },

    init: function (parent, action) {
        // Note: BarcodeHandlerMixin.init calls this._super.init, so there's no need to do it here.
        // Yet, "_super" must be present in a function for the class mechanism to replace it with the actual parent method.
        this._super;
        BarcodeHandlerMixin.init.apply(this, arguments);
    },

    start: function () {
        var self = this;
        self.session = Session;
        var res_company = new Model('res.company');
        res_company.query(['name'])
           .filter([['id', '=', self.session.company_id]])
           .all()
           .then(function (companies){
                self.company_name = companies[0].name;
                self.company_image_url = self.session.url('/web/image', {model: 'res.company', id: self.session.company_id, field: 'logo',})
                self.$el.html(QWeb.render("HrAttendanceKioskMode", {widget: self}));
                self.start_clock();
            });
        // Make a RPC call every day to keep the session alive
        self._interval = window.setInterval(this._callServer.bind(this), (60*60*1000*24));
        return self._super.apply(this, arguments);
    },

    on_barcode_scanned: function(barcode) {
        var self = this;
        var hr_employee = new Model('hr.employee');
        hr_employee.call('attendance_scan', [barcode, ])
            .then(function (result) {
                if (result.action) {
                    self.do_action(result.action);
                } else if (result.warning) {
                    self.do_warn(result.warning);
                }
            });
    },

    start_clock: function() {
        this.clock_start = setInterval(function() {this.$(".o_hr_attendance_clock").text(new Date().toLocaleTimeString(navigator.language, {hour: '2-digit', minute:'2-digit'}));}, 500);
        // First clock refresh before interval to avoid delay
        this.$(".o_hr_attendance_clock").text(new Date().toLocaleTimeString(navigator.language, {hour: '2-digit', minute:'2-digit'}));
    },

    destroy: function () {
        clearInterval(this.clock_start);
        clearInterval(this._interval);
        this._super.apply(this, arguments);
    },

    _callServer: function () {
        // Make a call to the database to avoid the auto close of the session
        return Session.rpc('/web/webclient/version_info', {})
    },

});

core.action_registry.add('hr_attendance_kiosk_mode', KioskMode);

return KioskMode;

});
<|endoftext|>


<commit_before>'use strict';

import fetch from 'node-fetch';
import constants from '../constants'
import { config, relation } from '../helpers'
// -- Internal
const credentials = config('themoviedb');
const RELATIONS = ['object'];

const action = (state) => {
  if (!credentials) return (state);

  return new Promise((resolve, reject) => {
    const ms = new Date()
    const { object } = relation(RELATIONS, state.nlp.relations) || state.nlp.concepts;
    console.log('ActionMovieDB'.bold.yellow, `object: ${object}`);

    let url = `${credentials.url}/3/search/multi?api_key=${credentials.apikey}&query=${object}`;
    fetch(url)
      .then(response => response.text())
      .then(body => {
        const data = JSON.parse(body).results[0];
        if (data) {
          state.action = _extract(data);
          state.action.ms = (new Date() - ms);
          state.action.engine = 'themoviedb';
          state.action.type = constants.action.type.rich;
        }

        resolve(state);
      })
  });
};

const _extract = (data) => {
  let item = {
    date: data.release_date || data.first_air_date,
    image: `http://image.tmdb.org/t/p/w320${data.poster_path || data.profile_path}`,
    text: data.overview,
    title: data.title || data.name,
    value: {
      id: data.id,
      popularity: data.popularity,
      vote_average: data.vote_average,
    },
  };

  if (data.media_type === 'person') {
    item.entity = constants.entity.person;
    item.embed = data.known_for.map(movie => _extract(movie));
  }

  return item;
}

export default action;
<commit_msg>Fixed typo<commit_after>'use strict';

import fetch from 'node-fetch';
import constants from '../constants'
import { config, relation } from '../helpers'
// -- Internal
const credentials = config('themoviedb');
const RELATIONS = ['object'];

const action = (state) => {
  if (!credentials) return (state);

  return new Promise((resolve, reject) => {
    const ms = new Date()
    const { object } = relation(RELATIONS, state.nlp.relations) || state.nlp.concepts;
    console.log('ActionMovieDB'.bold.yellow, `object: ${object}`);

    let url = `${credentials.url}/3/search/multi?api_key=${credentials.apikey}&query=${object}`;
    fetch(url)
      .then(response => response.text())
      .then(body => {
        const data = JSON.parse(body).results[0];
        if (data) {
          state.action = _extract(data);
          state.action.ms = (new Date() - ms);
          state.action.engine = 'themoviedb';
          state.action.type = constants.action.type.rich;
        }

        resolve(state);
      })
  });
};

const _extract = (data) => {
  let item = {
    date: data.release_date || data.first_air_date,
    image: `http://image.tmdb.org/t/p/w320${data.poster_path || data.profile_path}`,
    text: data.overview,
    title: data.title || data.name,
    value: {
      id: data.id,
      popularity: data.popularity,
      vote_average: data.vote_average,
    },
  };

  if (data.media_type === 'person') {
    item.entity = constants.entity.person;
    item.related = data.known_for.map(movie => _extract(movie));
  }

  return item;
}

export default action;
<|endoftext|>


<commit_before>import * as ValueMax from "./ValueMax.js";

export { Base64ArrayBuffer_To_ArrayBuffer_Generator };

const base64String = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

/** Mapping table for base64 (as Uint8) to index. */
let table_base64_Uint8_to_index = new Uint8Array( new ArrayBuffer(256) );
for (let i = 0; i < base64String.length; ++i)
  table_base64_Uint8_to_index[ base64String.codePointAt(i) ] = i;

/**
 * @param  {ArrayBuffer}                   base64ArrayBuffer The input base64 data as ArrayBuffer.
 * @param  {ValueMax.Percentage.Aggregate} progressToYield   Return this when every time yield.
 * @param  {ValueMax.Percentage.Concrete}  progressToAdvance Increase this when every time advanced.
 * @param  {Uint32}                        suspendByteCount  Everytime so many bytes decoded, yield for releasing CPU time.
 * @return {ArrayBuffer} Return decoded data when done.
 */
function* Base64ArrayBuffer_To_ArrayBuffer_Generator(
            base64ArrayBuffer,
            progressYield,
            progressAdvance,
            suspendByteCount) {

  suspendByteCount = ( suspendByteCount <= 0 ) ? 1024 : suspendByteCount;

  let sourceByteLength = base64ArrayBuffer.byteLength;

  if (progressToAdvance) {
    progressToAdvance.accumulation = 0;
    progressToAdvance.total = sourceByteLength;
  }

  let resultByteLength = sourceByteLength * 0.75;
  let resultArrayBuffer = new ArrayBuffer( resultByteLength );

  let sourceBytes = new Uint8Array( base64ArrayBuffer );
  let resultBytes = new Uint8Array( resultArrayBuffer );
  for (let i = 0; i < sourceByteLength; ++i) {

!!! ...unfinished...

    resultBytes[ i ] = table_base64_Uint8_to_index[ sourceBytes[ i ] ];
  }

        len = base64.length, i, p = 0,
        encoded1, encoded2, encoded3, encoded4;

      if (base64[base64.length - 1] === "=") {
        bufferLength--;
        if (base64[base64.length - 2] === "=") {
          bufferLength--;
        }
      }

      var arraybuffer = new ArrayBuffer(bufferLength),
      bytes = new Uint8Array(arraybuffer);

      for (i = 0; i < len; i+=4) {
        encoded1 = THREE.Base64.base64ToIndexNew(base64[i]);
        encoded2 = THREE.Base64.base64ToIndexNew(base64[i+1]);
        encoded3 = THREE.Base64.base64ToIndexNew(base64[i+2]);
        encoded4 = THREE.Base64.base64ToIndexNew(base64[i+3]);

        bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);
        bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);
        bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);
      }

      return arraybuffer;
    };

  return result;
}
<commit_msg>Update Base64ArrayBufferToFloat32.js<commit_after>import * as ValueMax from "./ValueMax.js";

export { Base64ArrayBuffer_To_ArrayBuffer_Generator };

const base64String = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

/** Mapping table for base64 (as Uint8) to index. */
let table_base64_Uint8_to_index = new Uint8Array( new ArrayBuffer(256) );
{
  for (let i = 0; i < table_base64_Uint8_to_index.length; ++i)
    table_base64_Uint8_to_index[ i ] = 255; // For identifying any non-base64 bytes.

  for (let i = 0; i < base64String.length; ++i)
    table_base64_Uint8_to_index[ base64String.codePointAt(i) ] = i;

  // Support decoding URL-safe base64 strings, as Node.js does.
  // See: https://en.wikipedia.org/wiki/Base64#URL_applications
  table_base64_Uint8_to_index['-'.charCodeAt(0)] = 62
  table_base64_Uint8_to_index['_'.charCodeAt(0)] = 63
}

/**
 *
 * @param  {ArrayBuffer} sourceBase64ArrayBuffer
 *   The input base64 data as ArrayBuffer. If the last bytes not enough 4 bytes, they will be discarded (will
 * not be decoded). If an input byte is not a legal base64 code (i.e. not A..Z, a..z, 0..0, +, /), the byte
 * will be skipped (as if it does not exist). So the input bytes can be separated by new line.
 *
 * @param  {ValueMax.Percentage.Aggregate} progressToYield
 *   Return this when every time yield.
 *
 * @param  {ValueMax.Percentage.Concrete}  progressToAdvance
 *   Increase this when every time advanced.
 *
 * @param  {Uint32} suspendByteCount
 *   Everytime so many bytes decoded, yield for releasing CPU time. Default is 1024 bytes.
 *
 * @return {ValueMax.Percentage.Aggregate or Uint8Array}
 *   Return progressYield when ( done = false ). Return decoded data as Uint8Array when ( done = true ).
 */
function* Base64ArrayBuffer_To_Uint8Array_Generator(
  sourceBase64ArrayBuffer, progressToYield, progressToAdvance, suspendByteCount) {

  suspendByteCount = ( suspendByteCount <= 0 ) ? 1024 : suspendByteCount;

  let sourceByteLength = sourceBase64ArrayBuffer.byteLength;

  if (progressToAdvance) {
    progressToAdvance.accumulation = 0;
    progressToAdvance.total = sourceByteLength;
  }

  // Decoding base64 will result a shorten data (75% in size). However, the source may not be pure base64 codes.
  // So it is safer to prepare same size bufer as source.
  let targetByteLength = sourceByteLength;
  let targetArrayBuffer = new ArrayBuffer( targetByteLength );

  let sourceBytes = new Uint8Array( sourceBase64ArrayBuffer );
  let targetBytes = new Uint8Array( targetArrayBuffer );

  const BYTES_PER_DECODE_UNIT = 4; // A decode unit consists of 4 base64 encoded source bytes.
  let encodedArrayBuffer = new ArrayBuffer( BYTES_PER_DECODE_UNIT );
  let encodedBytes = new Uint8Array( encodedArrayBuffer );

  let resultBytes = 0; // Accumulate the real result byte count.
  let byteCountAfterYield = 0;
  let sourceIndex = 0;
  while (sourceIndex < sourceByteLength) {

!!! ...unfinished... Skip several lines

    for (let j = 0; j < BYTES_PER_DECODE_UNIT; ++j, ++sourceIndex) {  // Extract 4 source bytes.
      if (sourceIndex >= sourceByteLength)
        break; // Decoding is done. (Ignore last non-4-bytes.)

      let b = table_base64_Uint8_to_index[ sourceBytes[ sourceIndex ] ];
      progressToAdvance.accumulation++;
      byteCountAfterYield++;

      if (byteCountAfterYield >= suspendByteCount) { // Every suspendByteCount, release CPU time.
        yield progressToYield;
        byteCountAfterYield = 0;
      }

      if (255 === b)
        continue; // Skip any non-base64 bytes.

      encodedBytes[ j ] = b;
    }

    if (sourceIndex >= sourceByteLength)
      break; // Decoding is done. (Ignore last non-4-bytes.)

!!! ...unfinished...

    targetBytes[ i ] = table_base64_Uint8_to_index[ sourceBytes[ i ] ];
  }

        len = base64.length, i, p = 0,
        encoded1, encoded2, encoded3, encoded4;

      if (base64[base64.length - 1] === "=") {
        bufferLength--;
        if (base64[base64.length - 2] === "=") {
          bufferLength--;
        }
      }

      var arraybuffer = new ArrayBuffer(bufferLength),
      bytes = new Uint8Array(arraybuffer);

      for (i = 0; i < len; i+=4) {
        encoded1 = THREE.Base64.base64ToIndexNew(base64[i]);
        encoded2 = THREE.Base64.base64ToIndexNew(base64[i+1]);
        encoded3 = THREE.Base64.base64ToIndexNew(base64[i+2]);
        encoded4 = THREE.Base64.base64ToIndexNew(base64[i+3]);

        bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);
        bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);
        bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);
      }

      return arraybuffer;
    };

!!! ...unfinished... adjust resultBytes byteOffset , length]
  let resultBytes = new Uint8Array( targetArrayBuffer, 0, resultBytes );

  return result;
}
<|endoftext|>


<commit_before>var linkTargetFinder = function () {
	var prefManager = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
	return {
		init : function () {
			gBrowser.addEventListener("load", function () {
				var autoRun = prefManager.getBoolPref("extensions.linktargetfinder.autorun");
				if (autoRun) {
					linkTargetFinder.run();
				}
			}, false);

			gBrowser.addEventListener("DOMContentLoaded", function() {
				alert('a');
			}, false);
		},

		run : function () {
			var head = content.document.getElementsByTagName("head")[0],
				style = content.document.getElementById("link-target-finder-style"),
				allLinks = content.document.getElementsByTagName("a"),
				foundLinks = 0;

			if (!style) {
				style = content.document.createElement("link");
				style.id = "link-target-finder-style";
				style.type = "text/css";
				style.rel = "stylesheet";
				style.href = "chrome://linktargetfinder/skin/skin.css";
				head.appendChild(style);
			}

			for (var i=0, il=allLinks.length; i<il; i++) {
				elm = allLinks[i];
				if (elm.getAttribute("target")) {
					elm.className += ((elm.className.length > 0)? " " : "") + "link-target-finder-selected";
					foundLinks++;
				}
			}
			if (foundLinks === 0) {
				alert("No links found with a target attribute");
			}
			else {
				alert("Found " + foundLinks + " links with a target attribute");
			}
		}
	};
}();
window.addEventListener("load", linkTargetFinder.init, false);<commit_msg>remove example js<commit_after><|endoftext|>


<commit_before>/*
 * Konfigurācijā tieks saņemts JSON masīvs
 * Attribūti
 *  options - tiek saņemts caur konstruktoru
 *      read_only(Boolean) - vai ir marķieris kustināms vai ir noklusētais marķieris redzams
 *      map_prefix(String) - konteinera id sākums, piemērs, id="my_map_134", map_prefix="my_map"
 *      icon(GIcon) - marķiera ikona
 *      unique_id - unikāls identifikātors obligāti jānorāda
 *      center_marker (bool) - nocentrē karti pārvietojot marķieri
 *      zoom (int) - level of magnification
 *  lat - noklusētais platums
 *  lng - noklusētais garums
 *  marker_count - skaitītājs no kura sāk marķieru skaitīšana, nav īpaša nozīme
 *
 */
LolitaGoogleMap=function(options){
    this.options=options
    this.marker_counter=0 //create index for each marker
    this.markers=[] //store all markers that are on map
    this.lat=56.9444123864; //coordinares of Rīga, Latvia
    this.lng=24.1009140015;
}
LolitaGoogleMap.prototype={
    /*
     *@@PUBLIC
     */
    init:function(){
        var that=this
        $(document).ready(function(){
            $("body").eq(0).unload(function(){
                GUnload()
            })
            that.load_map()
        })
    },
    /*
     *@@PRIVATE
     */
    load_map:function(){
        if (GBrowserIsCompatible()){// Do Map if Compatible Browser only
            this.map = new GMap2(elementById((this.options.map_prefix || "map")+"_"+this.options.unique_id));
            if(!this.options.read_only) this.map.enableScrollWheelZoom();
            this.options.zoom=this.options.zoom || 15
            this.add_controls() // add Gmap controls to map
            this.set_default_center()

            if(this.options.type=="multimedia"){ //need close tab if map in system side
                this.hide_current_tab()
            }
        }else{
            $("#"+(this.options.map_prefix || "map")+"_"+this.options.unique_id).html("
Error! Render Google Map
") ;
        }

    },
    /*
     *@@PRIVATE
     */
    set_default_center:function(){
        try{
            this.map.setCenter(new GLatLng(this.lat,this.lng),this.options.zoom);
            setTimeout(function(that){
                that.add_markers()
                if (that.options.center_marker && that.last_marker()){
                    that.set_marker(that.last_marker(),true,that.options.zoom)
                }
            },1000,this)
        }catch(e){
            alert(e)
            setTimeout(function(that){
                that.set_default_center()
            },500,this)
        }
    },
    /*
     *@@PRIVATE
     *Default function that add given markers to map.
     *Add default marker if not read only map and is single marker map and no marker
     *is added yet
     */
    add_markers:function(){
        var icon=this.create_icon();
        for(var i=0;i<this.options.lat.length;i++){
            var lat=this.options.lat[i];
            var lng=this.options.lng[i];
            if(!((!lat || !lng) || (lat==0 || lng==0))){
                var point=new GLatLng(lat,lng);
                this.add_simple_marker(point,icon,{
                    lat:lat,
                    lng:lng
                })
            }
        }
        if(this.marker_counter==0 && !this.options.read_only && this.options.single){
            this.add_simple_marker(new GLatLng(this.lat,this.lng),icon,{})
        }
    },
    /*
     *@@PRIVATE
     *Add marker to map and creates related INPUT field
     *Params:
     *  point(GLatLng) - point where marke need to be
     *  icon(GIcon) - icon of marker
     *  values(JSON) - values that is set to input fields mostly (lat,lng, etc.)
     */
    add_simple_marker:function(start,icon,values){
        var marker=new GMarker(start,{
            icon:icon,
            draggable: !this.options.read_only
        });
        marker.counter=this.marker_counter
        this.map.addOverlay(marker);
        this.add_marker_events(marker)
        if(values) this.create_form_elements()
        this.markers.push(marker)
        this.marker_counter+=1
        return marker
    },
    /*@@PRIVATE
     * Create new INPUT elements with hidden type
     * Params:
     *  values(JSON) - contains default values for input fields
     * Return:
     *  void
     */
    create_form_elements:function(values){
        values=values || {}
        var $container=$("#object_map_"+this.options.unique_id+"_container")
        var fields=["lat","lng","description"]
        for(var i=0;i<fields.length;i++){
            var value=eval("values."+fields[i]+" ? values."+fields[i]+" : 0")
            $container.append('<input type="hidden" '+
                'name="map['+this.options.unique_id+']['+this.marker_counter+']['+fields[i]+']"'+
                'id="object_map_'+this.options.unique_id+'_'+fields[i]+'_'+this.marker_counter+'"'+
                'value="'+value+'"'
                )
        }
    },
    /*
     *@@PUBLIC
     *Add new marker to map if no single marker map or no marker added yet
     *This is used from outside to add marker
     */
    add_new_marker:function(lat,lng,icon){
        if(!this.options.single || this.markers.length<1){
            lat=lat || this.lat
            lng=lng || this.lng
            icon=icon || this.create_icon()
            return this.add_simple_marker(new GLatLng(lat,lng),icon,{})
        }else{
            return false
        }
    },
    add_marker_events:function(marker){
        var that=this;
        if (!this.options.read_only){
            GEvent.addListener(this.map, 'click', function(overlay, point){
                if (overlay){
                }else if (point){
                    if(that.last_marker()){
                        that.last_marker().setPoint(point)
                        that.current_zoom=this.getZoom();
                        that.set_marker(that.last_marker())
                    }
                }
            });
        }

        if (!this.options.read_only){
            marker.enableDragging()
            GEvent.addListener(marker,'dragend',function() {
                that.current_zoom=that.map.getZoom();
                that.set_marker(this)
            });
        //            GEvent.addListener(marker,'click',function(){
        //                this.openInfoWindowHtml("asdfArturs");
        //            })
        }
    },
    add_controls:function(){
        this.map.addControl(new GLargeMapControl());
        this.map.addControl(new GMapTypeControl());
        this.map.addControl(new GScaleControl()) ;
        this.map.addControl(new GOverviewMapControl()) ;
    },

    create_icon:function(){
        if(!this.options.icon){
            var icon = new GIcon();
            icon.image = "http://labs.google.com/ridefinder/images/mm_20_red.png";
            icon.shadow = "http://labs.google.com/ridefinder/images/mm_20_shadow.png";
            icon.iconSize = new GSize(12, 20);
            icon.shadowSize = new GSize(22, 20);
            icon.iconAnchor = new GPoint(6, 20);
            return icon
        }else{
            return this.options.icon
        }
    },
    set_marker:function(marker,center,zoom){
        var point=marker.getLatLng();
        $('#object_map_'+this.options.unique_id+'_lat_'+marker.counter).attr("value",point.lat());
        $('#object_map_'+this.options.unique_id+'_lng_'+marker.counter).attr("value",point.lng());
        if(this.options.center_marker || center) this.change_center(point,zoom)//map.getZoom()

    },
    /*
     * @@PRIVATE
     * marker(GMarker) - must be specified
     * center(Boolean) - optional, center or not
     * zoom(Integer) - optional, map zoom to set
     */
    change_center:function(point,zoom){
        this.map.setCenter(point,zoom ||this.current_zoom);
    },
    last_marker:function(){
        return this.markers[this.markers.length-1]
    },
    /*
     * Seach for specific address, when found change last marker position to id
     * otherwise alert message that address canot be found
     */
    show_address:function(address){
        if (!this.map.geocoder)
            this.map.geocoder=new GClientGeocoder();
        var that=this
        this.map.geocoder.getLatLng(
            address,
            function(point){
                if (!point) {
                    return "Not Found"
                } else{
                    if(!that.options.read_only){
                        if (typeof(that.last_marker())=="undefined"){
                            var icon=that.create_icon();
                            that.add_new_marker(point.lat,point.lng,icon)
                        }else{
                            that.last_marker().setPoint(point)
                        }
                        that.set_marker(that.last_marker(),true)
                    }else{
                       that.change_center(point)
                    }
                    return true
                }
            }
            )
    },
    hide_current_tab:function(){
        if(!this.options.opened){
            $('#tab'+this.options.index+'container').css("display","none");
        }
        $("#map_form_"+this.options.unique_id).css("display","block")
    }
}<commit_msg>Google map change center<commit_after>/*
 * Konfigurācijā tieks saņemts JSON masīvs
 * Attribūti
 *  options - tiek saņemts caur konstruktoru
 *      read_only(Boolean) - vai ir marķieris kustināms vai ir noklusētais marķieris redzams
 *      map_prefix(String) - konteinera id sākums, piemērs, id="my_map_134", map_prefix="my_map"
 *      icon(GIcon) - marķiera ikona
 *      unique_id - unikāls identifikātors obligāti jānorāda
 *      center_marker (bool) - nocentrē karti pārvietojot marķieri
 *      zoom (int) - level of magnification
 *  lat - noklusētais platums
 *  lng - noklusētais garums
 *  marker_count - skaitītājs no kura sāk marķieru skaitīšana, nav īpaša nozīme
 *
 */
LolitaGoogleMap=function(options){
    this.options=options
    this.marker_counter=0 //create index for each marker
    this.markers=[] //store all markers that are on map
    this.lat=56.9444123864; //coordinares of Rīga, Latvia
    this.lng=24.1009140015;
}
LolitaGoogleMap.prototype={
    /*
     *@@PUBLIC
     */
    init:function(){
        var that=this
        $(document).ready(function(){
            $("body").eq(0).unload(function(){
                GUnload()
            })
            that.load_map()
        })
    },
    /*
     *@@PRIVATE
     */
    load_map:function(){
        if (GBrowserIsCompatible()){// Do Map if Compatible Browser only
            this.map = new GMap2(elementById((this.options.map_prefix || "map")+"_"+this.options.unique_id));
            if(!this.options.read_only) this.map.enableScrollWheelZoom();
            this.options.zoom=this.options.zoom || 15
            this.add_controls() // add Gmap controls to map
            this.set_default_center()

            if(this.options.type=="multimedia"){ //need close tab if map in system side
                this.hide_current_tab()
            }
        }else{
            $("#"+(this.options.map_prefix || "map")+"_"+this.options.unique_id).html("
Error! Render Google Map
") ;
        }

    },
    /*
     *@@PRIVATE
     */
    set_default_center:function(){
        try{
            this.map.setCenter(new GLatLng(this.lat,this.lng),this.options.zoom);
            setTimeout(function(that){
                that.add_markers()
                if (that.options.center_marker && that.last_marker()){
                    that.set_marker(that.last_marker(),true,that.options.zoom)
                }
            },1000,this)
        }catch(e){
            alert(e)
            setTimeout(function(that){
                that.set_default_center()
            },500,this)
        }
    },
    /*
     *@@PRIVATE
     *Default function that add given markers to map.
     *Add default marker if not read only map and is single marker map and no marker
     *is added yet
     */
    add_markers:function(){
        var icon=this.create_icon();
        for(var i=0;i<this.options.lat.length;i++){
            var lat=this.options.lat[i];
            var lng=this.options.lng[i];
            if(!((!lat || !lng) || (lat==0 || lng==0))){
                var point=new GLatLng(lat,lng);
                this.add_simple_marker(point,icon,{
                    lat:lat,
                    lng:lng
                })
            }
        }
        if(this.marker_counter==0 && !this.options.read_only && this.options.single){
            this.add_simple_marker(new GLatLng(this.lat,this.lng),icon,{})
        }
    },
    /*
     *@@PRIVATE
     *Add marker to map and creates related INPUT field
     *Params:
     *  point(GLatLng) - point where marke need to be
     *  icon(GIcon) - icon of marker
     *  values(JSON) - values that is set to input fields mostly (lat,lng, etc.)
     */
    add_simple_marker:function(start,icon,values){
        var marker=new GMarker(start,{
            icon:icon,
            draggable: !this.options.read_only
        });
        marker.counter=this.marker_counter
        this.map.addOverlay(marker);
        this.add_marker_events(marker)
        if(values) this.create_form_elements()
        this.markers.push(marker)
        this.marker_counter+=1
        return marker
    },
    /*@@PRIVATE
     * Create new INPUT elements with hidden type
     * Params:
     *  values(JSON) - contains default values for input fields
     * Return:
     *  void
     */
    create_form_elements:function(values){
        values=values || {}
        var $container=$("#object_map_"+this.options.unique_id+"_container")
        var fields=["lat","lng","description"]
        for(var i=0;i<fields.length;i++){
            var value=eval("values."+fields[i]+" ? values."+fields[i]+" : 0")
            $container.append('<input type="hidden" '+
                'name="map['+this.options.unique_id+']['+this.marker_counter+']['+fields[i]+']"'+
                'id="object_map_'+this.options.unique_id+'_'+fields[i]+'_'+this.marker_counter+'"'+
                'value="'+value+'"'
                )
        }
    },
    /*
     *@@PUBLIC
     *Add new marker to map if no single marker map or no marker added yet
     *This is used from outside to add marker
     */
    add_new_marker:function(lat,lng,icon){
        if(!this.options.single || this.markers.length<1){
            lat=lat || this.lat
            lng=lng || this.lng
            icon=icon || this.create_icon()
            return this.add_simple_marker(new GLatLng(lat,lng),icon,{})
        }else{
            return false
        }
    },
    add_marker_events:function(marker){
        var that=this;
        if (!this.options.read_only){
            GEvent.addListener(this.map, 'click', function(overlay, point){
                if (overlay){
                }else if (point){
                    if(that.last_marker()){
                        that.last_marker().setPoint(point)
                        that.current_zoom=this.getZoom();
                        that.set_marker(that.last_marker())
                    }
                }
            });
        }

        if (!this.options.read_only){
            marker.enableDragging()
            GEvent.addListener(marker,'dragend',function() {
                that.current_zoom=that.map.getZoom();
                that.set_marker(this)
            });
        //            GEvent.addListener(marker,'click',function(){
        //                this.openInfoWindowHtml("asdfArturs");
        //            })
        }
    },
    add_controls:function(){
        this.map.addControl(new GLargeMapControl());
        this.map.addControl(new GMapTypeControl());
        this.map.addControl(new GScaleControl()) ;
        this.map.addControl(new GOverviewMapControl()) ;
    },

    create_icon:function(){
        if(!this.options.icon){
            var icon = new GIcon();
            icon.image = "http://labs.google.com/ridefinder/images/mm_20_red.png";
            icon.shadow = "http://labs.google.com/ridefinder/images/mm_20_shadow.png";
            icon.iconSize = new GSize(12, 20);
            icon.shadowSize = new GSize(22, 20);
            icon.iconAnchor = new GPoint(6, 20);
            return icon
        }else{
            return this.options.icon
        }
    },
    set_marker:function(marker,center,zoom){
        var point=marker.getLatLng();
        $('#object_map_'+this.options.unique_id+'_lat_'+marker.counter).attr("value",point.lat());
        $('#object_map_'+this.options.unique_id+'_lng_'+marker.counter).attr("value",point.lng());
        if(this.options.center_marker || center) this.change_center(point,zoom)//map.getZoom()

    },
    /*
     * @@PRIVATE
     * marker(GMarker) - must be specified
     * center(Boolean) - optional, center or not
     * zoom(Integer) - optional, map zoom to set
     */
    change_center:function(point,zoom){
        this.map.setCenter(point,zoom ||this.current_zoom);
    },
    last_marker:function(){
        return this.markers[this.markers.length-1]
    },
    /*
     * Seach for specific address, when found change last marker position to id
     * otherwise alert message that address canot be found
     */
    show_address:function(address,zoom){
        if (!this.map.geocoder)
            this.map.geocoder=new GClientGeocoder();
        var that=this
        this.map.geocoder.getLatLng(
            address,
            function(point){
                if (!point) {
                    return "Not Found"
                } else{
                    if(!that.options.read_only){
                        if (typeof(that.last_marker())=="undefined"){
                            var icon=that.create_icon();
                            that.add_new_marker(point.lat,point.lng,icon)
                        }else{
                            that.last_marker().setPoint(point)
                        }
                        that.set_marker(that.last_marker(),true,zoom)
                    }else{
                       that.change_center(point,zoom)
                    }
                    return true
                }
            }
            )
    },
    hide_current_tab:function(){
        if(!this.options.opened){
            $('#tab'+this.options.index+'container').css("display","none");
        }
        $("#map_form_"+this.options.unique_id).css("display","block")
    }
}<|endoftext|>


<commit_before><commit_msg>Refine saveFromJson<commit_after><|endoftext|>


<commit_before>import React,{ Component } from 'react';
import {Animation} from '../../lib';
import range from 'lodash.range';
import assign from 'lodash.assign';
import flatten from 'lodash.flatten';

export default class SpinningDots extends Component {
    constructor() {
        super();
        this.state = {
            layers: 9,
            start: 4,
            width: 0,
            height: 0
        };
    }

    componentDidMount() {
        // store the height and width of the container
        let width = this.refs.container.clientWidth;
        let height = this.refs.container.clientHeight;

        // now that we know the size, re-render the stars
        this.setState({ width, height });
    }

    getStyles() {
        return {
            body: {
                background: '#0e7cf0',
                margin: '0px',
                color: 'white',
                position: 'absolute',
                top: 0,
                left: 0,
                width: '100%',
                height: '100%'
            },
            a: {
                color: '#6db0f7'
            },
            circle: {
                background: '#2a2a2a',
                borderRadius: '50%',
                width: '10px',
                height: '10px',
                position: 'absolute',
                top: '50%',
                left: '50%'
            },
            sourceLink: {
                textDecoration: 'none',
                padding: '6px',
                fontFamily: 'Roboto',
                fontWeight: 'bold',
                backgroundColor: 'white',
                color: 'black',
                position: 'absolute',
                top: 0,
                right: 0
            }
        };
    }

    getRotationAndTranslateForCircle( layer, fraction ) {
        const rotate = `rotate(${(360 * fraction)}deg)`;
        const translate = `translate(${(layer * 20 - 2.5)}px)`;
        return { rotation: rotate, translation: translate };
    }

    getAnimationForCircle( layer, rotation, translation ) {

        return {
            keyframes: [
                { transform: rotation + ' rotate(0deg) ' + translation },
                { transform: rotation + ' rotate(360deg) ' + translation }
            ], timing: {
                duration: 1000 * layer,
                iterations: Infinity
            }
        };
    }

    renderCircles( layerCount, startCount ) {

        let {circle} = this.getStyles();

        return flatten(range(layerCount).map(( l, idx ) => {
            const n = idx * startCount;

            return range(n).map(( c, cIdx ) => {

                let {rotation,translation} = this.getRotationAndTranslateForCircle(idx, cIdx / n);
                let {keyframes,timing} = this.getAnimationForCircle(idx, rotation, translation);

                return <Animation key={idx + '_' + cIdx} keyframes={keyframes} timing={timing}>
                    <div style={assign({},circle,{transform: `${rotation} ${translation}`})}>

                </Animation>;
            });
        }));

    }

    render() {
        const {body,sourceLink} = this.getStyles();
        const {layers,start} = this.state;

        return

            {this.renderCircles(layers, start)}

                View Source

;
    }
}
<commit_msg>change source link<commit_after>import React,{ Component } from 'react';
import {Animation} from '../../lib';
import range from 'lodash.range';
import assign from 'lodash.assign';
import flatten from 'lodash.flatten';

export default class SpinningDots extends Component {
    constructor() {
        super();
        this.state = {
            layers: 9,
            start: 4,
            width: 0,
            height: 0
        };
    }

    componentDidMount() {
        // store the height and width of the container
        let width = this.refs.container.clientWidth;
        let height = this.refs.container.clientHeight;

        // now that we know the size, re-render the stars
        this.setState({ width, height });
    }

    getStyles() {
        return {
            body: {
                background: '#0e7cf0',
                margin: '0px',
                color: 'white',
                position: 'absolute',
                top: 0,
                left: 0,
                width: '100%',
                height: '100%'
            },
            a: {
                color: '#6db0f7'
            },
            circle: {
                background: '#2a2a2a',
                borderRadius: '50%',
                width: '10px',
                height: '10px',
                position: 'absolute',
                top: '50%',
                left: '50%'
            },
            sourceLink: {
                textDecoration: 'none',
                padding: '6px',
                fontFamily: 'Roboto',
                fontWeight: 'bold',
                backgroundColor: 'white',
                color: 'black',
                position: 'absolute',
                top: 0,
                right: 0
            }
        };
    }

    getRotationAndTranslateForCircle( layer, fraction ) {
        const rotate = `rotate(${(360 * fraction)}deg)`;
        const translate = `translate(${(layer * 20 - 2.5)}px)`;
        return { rotation: rotate, translation: translate };
    }

    getAnimationForCircle( layer, rotation, translation ) {

        return {
            keyframes: [
                { transform: rotation + ' rotate(0deg) ' + translation },
                { transform: rotation + ' rotate(360deg) ' + translation }
            ], timing: {
                duration: 1000 * layer,
                iterations: Infinity
            }
        };
    }

    renderCircles( layerCount, startCount ) {

        let {circle} = this.getStyles();

        return flatten(range(layerCount).map(( l, idx ) => {
            const n = idx * startCount;

            return range(n).map(( c, cIdx ) => {

                let {rotation,translation} = this.getRotationAndTranslateForCircle(idx, cIdx / n);
                let {keyframes,timing} = this.getAnimationForCircle(idx, rotation, translation);

                return <Animation key={idx + '_' + cIdx} keyframes={keyframes} timing={timing}>
                    <div style={assign({},circle,{transform: `${rotation} ${translation}`})}>

                </Animation>;
            });
        }));

    }

    render() {
        const {body,sourceLink} = this.getStyles();
        const {layers,start} = this.state;

        return

            {this.renderCircles(layers, start)}

                View Source

;
    }
}
<|endoftext|>


<commit_before>var should = require('should'),
	async = require('async'),
	_ = require('appcelerator').lodash,
	APIBuilder = require('appcelerator').apibuilder,
	server = new APIBuilder(),
	log = APIBuilder.createLogger({}, { name: 'api-connector-mysql TEST', useConsole: true, level: 'info' }),
	connector = server.getConnector('appc.mysql'),
	Model;

describe('Connector', function() {

	before(function(next) {
		// define your model
		Model = APIBuilder.Model.extend('post', {
			fields: {
				title: { type: String },
				content: { type: String }
			},
			connector: 'appc.mysql'
		});

		should(Model).be.an.object;

		Model.deleteAll(function() {
			next();
		});
	});

	after(function(next) {
		Model.deleteAll(function(err) {
			if (err) {
				log.error(err.message);
			}
			next();
		});
	});

	it('should be able to fetch schema', function(next) {
		connector.fetchSchema(function(err, schema) {
			should(err).be.not.ok;
			should(schema).be.an.object;
			next();
		});
	});

	it('should create models from tables', function() {
		var SuperPost = connector.getModel('appc.mysql/super_post');
		should(SuperPost).be.ok;
	});

	it('should be able to extend from tables', function(next) {
		var SupererPost = APIBuilder.Model.extend('appc.mysql/super_post', 'superer_post', {
			fields: {
				MyTitle: { name: 'title', type: String },
				MyContent: { name: 'content', type: String }
			},
			connector: 'appc.mysql'
		});
		should(SupererPost).be.ok;
		should(SupererPost._supermodel).be.ok;
		should(SupererPost._parent).be.ok;
		SupererPost.create({
			MyTitle: 'cheese',
			MyContent: 'was eaten this night'
		}, function(err, instance) {
			should(err).be.not.ok;
			should(instance).be.an.Object;
			should(instance.getPrimaryKey()).be.a.Number;
			should(instance.MyTitle).be.ok;
			should(instance.MyContent).be.ok;
			next();
		});
	});

	it('should be able to use named fields', function(next) {
		var Model = APIBuilder.Model.extend('post', {
				fields: {
					MyTitle: { name: 'title', type: String },
					MyContent: { name: 'content', type: String }
				},
				connector: 'appc.mysql'
			}),
			title = 'Test',
			content = 'Hello world',
			object = {
				MyTitle: title,
				MyContent: content
			};
		Model.create(object, function(err, instance) {
			should(err).be.not.ok;
			should(instance).be.an.Object;
			should(instance.getPrimaryKey()).be.a.Number;
			should(instance.MyTitle).equal(title);
			should(instance.MyContent).equal(content);
			Model.query({
				where: {
					MyTitle: 'Test'
				}
			}, function(err, coll) {
				should(err).be.not.ok;
				should(coll.length).be.greaterThan(0);
				instance.delete(next);
			});
		});
	});

	it('API-298: should be able to use named fields', function(next) {
		// create a model from a mysql table
		var uc_1 = APIBuilder.createModel('uc_1', {
				fields: {
					fname: { type: String, description: 'First name', name: 'first_name', required: true },
					lname: { type: String, description: 'Last name', required: true, name: 'last_name' },
					email: { type: String, description: 'Email address', required: true, name: 'email_address' }
				},
				connector: 'appc.mysql',
				metadata: {
					'appc.mysql': { table: 'employee' }
				}
			}),
			object = {
				fname: 'Test',
				lname: 'Smith',
				email: 'dtoth@appcelerator.com'
			};
		uc_1.create(object, function(err, instance) {
			should(err).be.not.ok;
			should(instance).be.an.Object;
			should(instance.getPrimaryKey()).be.a.Number;
			should(instance.fname).equal(object.fname);
			should(instance.lname).equal(object.lname);
			should(instance.email).equal(object.email);
			uc_1.query({
				where: {
					lname: object.lname
				}
			}, function(err, coll) {
				should(err).be.not.ok;
				should(coll.length).be.greaterThan(0);
				instance.delete(next);
			});
		});
	});

	it('should be able to ignore fields absent from schema', function(next) {
		var Model = APIBuilder.Model.extend('post', {
				fields: {
					MyTitle: { name: 'title', type: String },
					MyContent: { name: 'content', type: String },
					MyCustomField: { type: String }
				},
				connector: 'appc.mysql'
			}),
			title = 'Test',
			content = 'Hello world',
			object = {
				MyTitle: title,
				MyContent: content,
				MyCustomField: 'should be ignored'
			};
		Model.create(object, function(err, instance) {
			should(err).be.not.ok;
			should(instance).be.an.Object;
			should(instance.getPrimaryKey()).be.a.Number;
			should(instance.MyTitle).equal(title);
			should(instance.MyContent).equal(content);
			instance.delete(next);
		});
	});

	it('should be able to create instance', function(next) {

		var title = 'Test',
			content = 'Hello world',
			object = {
				title: title,
				content: content
			};

		Model.create(object, function(err, instance) {
			should(err).be.not.ok;
			should(instance).be.an.object;
			should(instance.getPrimaryKey()).be.a.Number;
			should(instance.title).equal(title);
			should(instance.content).equal(content);
			instance.delete(next);
		});

	});

	it('should be able to fetch schema with post table', function(next) {
		connector.fetchSchema(function(err, schema) {
			should(err).be.not.ok;
			should(schema).be.an.object;
			should(schema.objects.post.id).be.ok;
			should(schema.objects.post.title).be.ok;
			should(schema.objects.post.content).be.ok;
			should(schema.primary_keys.post).be.ok;
			next();
		});
	});

	it('should be able to find an instance by ID', function(next) {

		var title = 'Test',
			content = 'Hello world',
			object = {
				title: title,
				content: content
			};

		Model.create(object, function(err, instance) {
			should(err).be.not.ok;
			should(instance).be.an.object;

			var id = instance.getPrimaryKey();
			Model.find(id, function(err, instance2) {
				should(err).be.not.ok;
				should(instance2).be.an.object;
				should(instance2.getPrimaryKey()).equal(id);
				should(instance2.title).equal(title);
				should(instance2.content).equal(content);
				instance.delete(next);
			});

		});

	});

	it('should be able to find an instance by field value', function(next) {

		var title = 'Test',
			content = 'Hello world',
			object = {
				title: title,
				content: content
			};

		Model.create(object, function(err, instance) {
			should(err).be.not.ok;
			should(instance).be.an.object;

			var query = { title: title };
			Model.find(query, function(err, coll) {
				should(err).be.not.ok;
				var instance2 = coll[0];
				should(instance2).be.an.object;
				should(instance2.title).equal(title);
				instance.delete(next);
			});

		});

	});

	it('should be able to query', function(callback) {

		var title = 'Test',
			content = 'Hello world',
			object = {
				title: title,
				content: content
			};

		Model.create(object, function(err, instance) {
			should(err).be.not.ok;
			should(instance).be.an.object;

			var options = {
				where: { content: { $like: 'Hello%' } },
				sel: { content: 1 },
				order: { title: -1, content: 1 },
				limit: 3,
				skip: 0
			};
			Model.query(options, function(err, coll) {
				should(err).be.not.ok;

				async.eachSeries(coll, function(obj, next) {
					should(obj.getPrimaryKey()).be.a.Number;
					should(obj.title).be.not.ok;
					should(obj.content).be.a.string;
					obj.remove(next);
				}, callback);
			});
		});

	});

	it('API-325: should be able to query with unsel', function(callback) {

		var Model = APIBuilder.Model.extend('post', {
			fields: {
				myTitle: { name: 'title', type: String },
				myContent: { name: 'content', type: String }
			},
			connector: 'appc.mysql'
		});
		var title = 'Test',
			content = 'Hello world',
			object = {
				myTitle: title,
				myContent: content
			};

		Model.create(object, function(err, instance) {
			should(err).be.not.ok;
			should(instance).be.an.object;

			var options = {
				where: { myContent: { $like: 'Hello%' } },
				unsel: { myTitle: 1 },
				order: { myTitle: -1, myContent: 1 },
				limit: 3,
				skip: 0
			};
			Model.query(options, function(err, coll) {
				should(err).be.not.ok;

				async.eachSeries(coll, function(obj, next) {
					should(obj.getPrimaryKey()).be.a.Number;
					should(obj.myTitle).be.not.ok;
					should(obj.myContent).be.a.String;
					obj.remove(next);
				}, callback);
			});
		});

	});

	it('should be able to find all instances', function(next) {

		var posts = [
			{
				title: 'Test1',
				content: 'Hello world'
			},
			{
				title: 'Test2',
				content: 'Goodbye world'
			}];

		Model.deleteAll(function() {
			Model.create(posts, function(err, coll) {
				var keys = [];
				coll.forEach(function(post) {
					keys.push(post.getPrimaryKey());
				});

				Model.find(function(err, coll2) {
					should(err).be.not.ok;
					should(coll2.length).equal(coll.length);

					coll2.forEach(function(post, i) {
						should(post.getPrimaryKey()).equal(keys[i]);
					});

					Model.deleteAll(next);
				});

			});
		});

	});

	it('API-337: should be able to query with order', function(next) {

		var posts = [
			{
				title: 'Test1',
				content: 'Hello world'
			},
			{
				title: 'Test2',
				content: 'Goodbye world'
			},
			{
				title: 'Test3',
				content: 'Goodbye world'
			}
		];

		Model.deleteAll(function() {
			Model.create(posts, function(err, coll) {
				should(err).be.not.ok;

				Model.query({ order: { title: 1 }, limit: 2 }, function(err, coll2) {
					should(err).be.not.ok;
					should(coll2[0].getPrimaryKey()).equal(coll[0].getPrimaryKey());
					should(coll2[1].getPrimaryKey()).equal(coll[1].getPrimaryKey());

					Model.query({ order: { title: -1 } }, function(err, coll2) {
						should(err).be.not.ok;
						should(coll2[0].getPrimaryKey()).equal(coll[2].getPrimaryKey());
						should(coll2[1].getPrimaryKey()).equal(coll[1].getPrimaryKey());

						Model.deleteAll(next);
					});
				});

			});
		});

	});

	it('API-281: should support paging', function(next) {

		var posts = [];
		for (var i = 1; i <= 30; i++) {
			posts.push({
				title: 'Test' + i,
				content: 'Hello world'
			});
		}

		Model.deleteAll(function() {
			Model.create(posts, function(err, coll) {
				should(err).be.not.ok;

				Model.query({ per_page: 1, page: 2 }, function(err, coll2) {
					should(err).be.not.ok;
					should(coll2[0].getPrimaryKey()).equal(coll[1].getPrimaryKey());

					Model.query({ skip: 1, limit: 1 }, function(err, coll2) {
						should(err).be.not.ok;
						should(coll2[0].getPrimaryKey()).equal(coll[1].getPrimaryKey());

						Model.query({ page: 2 }, function(err, coll2) {
							should(err).be.not.ok;
							should(coll2[0].getPrimaryKey()).equal(coll[10].getPrimaryKey());

							Model.deleteAll(next);
						});
					});
				});

			});
		});

	});

	it('should be able to update an instance', function(next) {

		var title = 'Test',
			content = 'Hello world',
			object = {
				title: title,
				content: content
			};

		Model.create(object, function(err, instance) {
			should(err).be.not.ok;
			should(instance).be.an.object;

			var id = instance.getPrimaryKey();
			Model.find(id, function(err, instance2) {
				should(err).be.not.ok;

				instance2.set('content', 'Goodbye world');
				instance2.save(function(err, result) {
					should(err).be.not.ok;

					should(result).be.an.object;
					should(result.getPrimaryKey()).equal(id);
					should(result.title).equal(title);
					should(result.content).equal('Goodbye world');
					instance.delete(next);
				});

			});

		});

	});

});<commit_msg>Add Test for Query with Skip<commit_after>var should = require('should'),
	async = require('async'),
	_ = require('appcelerator').lodash,
	APIBuilder = require('appcelerator').apibuilder,
	server = new APIBuilder(),
	log = APIBuilder.createLogger({}, { name: 'api-connector-mysql TEST', useConsole: true, level: 'info' }),
	connector = server.getConnector('appc.mysql'),
	Model;

describe('Connector', function() {

	before(function(next) {
		// define your model
		Model = APIBuilder.Model.extend('post', {
			fields: {
				title: { type: String },
				content: { type: String }
			},
			connector: 'appc.mysql'
		});

		should(Model).be.an.object;

		Model.deleteAll(function() {
			next();
		});
	});

	after(function(next) {
		Model.deleteAll(function(err) {
			if (err) {
				log.error(err.message);
			}
			next();
		});
	});

	it('should be able to fetch schema', function(next) {
		connector.fetchSchema(function(err, schema) {
			should(err).be.not.ok;
			should(schema).be.an.object;
			next();
		});
	});

	it('should create models from tables', function() {
		var SuperPost = connector.getModel('appc.mysql/super_post');
		should(SuperPost).be.ok;
	});

	it('should be able to extend from tables', function(next) {
		var SupererPost = APIBuilder.Model.extend('appc.mysql/super_post', 'superer_post', {
			fields: {
				MyTitle: { name: 'title', type: String },
				MyContent: { name: 'content', type: String }
			},
			connector: 'appc.mysql'
		});
		should(SupererPost).be.ok;
		should(SupererPost._supermodel).be.ok;
		should(SupererPost._parent).be.ok;
		SupererPost.create({
			MyTitle: 'cheese',
			MyContent: 'was eaten this night'
		}, function(err, instance) {
			should(err).be.not.ok;
			should(instance).be.an.Object;
			should(instance.getPrimaryKey()).be.a.Number;
			should(instance.MyTitle).be.ok;
			should(instance.MyContent).be.ok;
			next();
		});
	});

	it('should be able to use named fields', function(next) {
		var Model = APIBuilder.Model.extend('post', {
				fields: {
					MyTitle: { name: 'title', type: String },
					MyContent: { name: 'content', type: String }
				},
				connector: 'appc.mysql'
			}),
			title = 'Test',
			content = 'Hello world',
			object = {
				MyTitle: title,
				MyContent: content
			};
		Model.create(object, function(err, instance) {
			should(err).be.not.ok;
			should(instance).be.an.Object;
			should(instance.getPrimaryKey()).be.a.Number;
			should(instance.MyTitle).equal(title);
			should(instance.MyContent).equal(content);
			Model.query({
				where: {
					MyTitle: 'Test'
				}
			}, function(err, coll) {
				should(err).be.not.ok;
				should(coll.length).be.greaterThan(0);
				instance.delete(next);
			});
		});
	});

	it('API-298: should be able to use named fields', function(next) {
		// create a model from a mysql table
		var uc_1 = APIBuilder.createModel('uc_1', {
				fields: {
					fname: { type: String, description: 'First name', name: 'first_name', required: true },
					lname: { type: String, description: 'Last name', required: true, name: 'last_name' },
					email: { type: String, description: 'Email address', required: true, name: 'email_address' }
				},
				connector: 'appc.mysql',
				metadata: {
					'appc.mysql': { table: 'employee' }
				}
			}),
			object = {
				fname: 'Test',
				lname: 'Smith',
				email: 'dtoth@appcelerator.com'
			};
		uc_1.create(object, function(err, instance) {
			should(err).be.not.ok;
			should(instance).be.an.Object;
			should(instance.getPrimaryKey()).be.a.Number;
			should(instance.fname).equal(object.fname);
			should(instance.lname).equal(object.lname);
			should(instance.email).equal(object.email);
			uc_1.query({
				where: {
					lname: object.lname
				}
			}, function(err, coll) {
				should(err).be.not.ok;
				should(coll.length).be.greaterThan(0);
				instance.delete(next);
			});
		});
	});

	it('should be able to ignore fields absent from schema', function(next) {
		var Model = APIBuilder.Model.extend('post', {
				fields: {
					MyTitle: { name: 'title', type: String },
					MyContent: { name: 'content', type: String },
					MyCustomField: { type: String }
				},
				connector: 'appc.mysql'
			}),
			title = 'Test',
			content = 'Hello world',
			object = {
				MyTitle: title,
				MyContent: content,
				MyCustomField: 'should be ignored'
			};
		Model.create(object, function(err, instance) {
			should(err).be.not.ok;
			should(instance).be.an.Object;
			should(instance.getPrimaryKey()).be.a.Number;
			should(instance.MyTitle).equal(title);
			should(instance.MyContent).equal(content);
			instance.delete(next);
		});
	});

	it('should be able to create instance', function(next) {

		var title = 'Test',
			content = 'Hello world',
			object = {
				title: title,
				content: content
			};

		Model.create(object, function(err, instance) {
			should(err).be.not.ok;
			should(instance).be.an.object;
			should(instance.getPrimaryKey()).be.a.Number;
			should(instance.title).equal(title);
			should(instance.content).equal(content);
			instance.delete(next);
		});

	});

	it('should be able to fetch schema with post table', function(next) {
		connector.fetchSchema(function(err, schema) {
			should(err).be.not.ok;
			should(schema).be.an.object;
			should(schema.objects.post.id).be.ok;
			should(schema.objects.post.title).be.ok;
			should(schema.objects.post.content).be.ok;
			should(schema.primary_keys.post).be.ok;
			next();
		});
	});

	it('should be able to find an instance by ID', function(next) {

		var title = 'Test',
			content = 'Hello world',
			object = {
				title: title,
				content: content
			};

		Model.create(object, function(err, instance) {
			should(err).be.not.ok;
			should(instance).be.an.object;

			var id = instance.getPrimaryKey();
			Model.find(id, function(err, instance2) {
				should(err).be.not.ok;
				should(instance2).be.an.object;
				should(instance2.getPrimaryKey()).equal(id);
				should(instance2.title).equal(title);
				should(instance2.content).equal(content);
				instance.delete(next);
			});

		});

	});

	it('should be able to find an instance by field value', function(next) {

		var title = 'Test',
			content = 'Hello world',
			object = {
				title: title,
				content: content
			};

		Model.create(object, function(err, instance) {
			should(err).be.not.ok;
			should(instance).be.an.object;

			var query = { title: title };
			Model.find(query, function(err, coll) {
				should(err).be.not.ok;
				var instance2 = coll[0];
				should(instance2).be.an.object;
				should(instance2.title).equal(title);
				instance.delete(next);
			});

		});

	});

	it('should be able to query', function(callback) {

		var title = 'Test',
			content = 'Hello world',
			object = {
				title: title,
				content: content
			};

		Model.create(object, function(err, instance) {
			should(err).be.not.ok;
			should(instance).be.an.object;

			var options = {
				where: { content: { $like: 'Hello%' } },
				sel: { content: 1 },
				order: { title: -1, content: 1 },
				limit: 3,
				skip: 0
			};
			Model.query(options, function(err, coll) {
				should(err).be.not.ok;

				async.eachSeries(coll, function(obj, next) {
					should(obj.getPrimaryKey()).be.a.Number;
					should(obj.title).be.not.ok;
					should(obj.content).be.a.string;
					obj.remove(next);
				}, callback);
			});
		});

	});

	it('API-325: should be able to query with unsel', function(callback) {

		var Model = APIBuilder.Model.extend('post', {
			fields: {
				myTitle: { name: 'title', type: String },
				myContent: { name: 'content', type: String }
			},
			connector: 'appc.mysql'
		});
		var title = 'Test',
			content = 'Hello world',
			object = {
				myTitle: title,
				myContent: content
			};

		Model.create(object, function(err, instance) {
			should(err).be.not.ok;
			should(instance).be.an.object;

			var options = {
				where: { myContent: { $like: 'Hello%' } },
				unsel: { myTitle: 1 },
				order: { myTitle: -1, myContent: 1 },
				limit: 3,
				skip: 0
			};
			Model.query(options, function(err, coll) {
				should(err).be.not.ok;

				async.eachSeries(coll, function(obj, next) {
					should(obj.getPrimaryKey()).be.a.Number;
					should(obj.myTitle).be.not.ok;
					should(obj.myContent).be.a.String;
					obj.remove(next);
				}, callback);
			});
		});

	});

	it('should be able to find all instances', function(next) {

		var posts = [
			{
				title: 'Test1',
				content: 'Hello world'
			},
			{
				title: 'Test2',
				content: 'Goodbye world'
			}];

		Model.deleteAll(function() {
			Model.create(posts, function(err, coll) {
				var keys = [];
				coll.forEach(function(post) {
					keys.push(post.getPrimaryKey());
				});

				Model.find(function(err, coll2) {
					should(err).be.not.ok;
					should(coll2.length).equal(coll.length);

					coll2.forEach(function(post, i) {
						should(post.getPrimaryKey()).equal(keys[i]);
					});

					Model.deleteAll(next);
				});

			});
		});

	});

	it('API-337: should be able to query with order', function(next) {

		var posts = [
			{
				title: 'Test1',
				content: 'Hello world'
			},
			{
				title: 'Test2',
				content: 'Goodbye world'
			},
			{
				title: 'Test3',
				content: 'Goodbye world'
			}
		];

		Model.deleteAll(function() {
			Model.create(posts, function(err, coll) {
				should(err).be.not.ok;

				Model.query({ order: { title: 1 }, limit: 2 }, function(err, coll2) {
					should(err).be.not.ok;
					should(coll2[0].getPrimaryKey()).equal(coll[0].getPrimaryKey());
					should(coll2[1].getPrimaryKey()).equal(coll[1].getPrimaryKey());

					Model.query({ order: { title: -1 } }, function(err, coll2) {
						should(err).be.not.ok;
						should(coll2[0].getPrimaryKey()).equal(coll[2].getPrimaryKey());
						should(coll2[1].getPrimaryKey()).equal(coll[1].getPrimaryKey());

						Model.deleteAll(next);
					});
				});

			});
		});

	});

	it('API-281: should support paging', function(next) {

		var posts = [];
		for (var i = 1; i <= 30; i++) {
			posts.push({
				title: 'Test' + i,
				content: 'Hello world'
			});
		}

		Model.deleteAll(function() {
			Model.create(posts, function(err, coll) {
				should(err).be.not.ok;

				Model.query({ per_page: 1, page: 2 }, function(err, coll2) {
					should(err).be.not.ok;
					should(coll2[0].getPrimaryKey()).equal(coll[1].getPrimaryKey());

					Model.query({ skip: 1, limit: 1 }, function(err, coll2) {
						should(err).be.not.ok;
						should(coll2[0].getPrimaryKey()).equal(coll[1].getPrimaryKey());

						Model.query({ page: 2 }, function(err, coll2) {
							should(err).be.not.ok;
							should(coll2[0].getPrimaryKey()).equal(coll[10].getPrimaryKey());

							Model.deleteAll(next);
						});
					});
				});

			});
		});

	});

	it('should be able to update an instance', function(next) {

		var title = 'Test',
			content = 'Hello world',
			object = {
				title: title,
				content: content
			};

		Model.create(object, function(err, instance) {
			should(err).be.not.ok;
			should(instance).be.an.object;

			var id = instance.getPrimaryKey();
			Model.find(id, function(err, instance2) {
				should(err).be.not.ok;

				instance2.set('content', 'Goodbye world');
				instance2.save(function(err, result) {
					should(err).be.not.ok;

					should(result).be.an.object;
					should(result.getPrimaryKey()).equal(id);
					should(result.title).equal(title);
					should(result.content).equal('Goodbye world');
					instance.delete(next);
				});

			});

		});

	});

	it('API-377: should be able to query with just skip', function(callback) {
		Model.query({}, function(err, coll1) {
			should(err).be.not.ok;
			should(coll1).be.ok;
			Model.query({ skip: 1 }, function(err, coll2) {
				should(err).be.not.ok;
				should(coll2).be.ok;
				callback();
			});
		});
	});

});<|endoftext|>


<commit_before>import React, { Component } from 'react'
import injectSheet from 'react-jss'

import Spacer from '../components/spacer'
import teamMemberInfo from './team-member-info'
import TeamMember from './team-member'

class Team extends Component {
	constructor(props) {
		super(props)
		this.state = {
			teamMemberId: 0,
		}
	}

	render() {
		const { classes } = this.props
		const { teamMemberId } = this.state
		const { name, title, bio } = teamMemberInfo[teamMemberId]

		return (

						{teamMemberInfo.map(teamMember => {
							return (

									<button
										className={classes.button}
										onClick={() => {
											this.handleClick(teamMember.id)
										}}
									>

										<Spacer width="16px" />
									</button>

							)
						})}

				<TeamMember name={name} title={title} bio={bio} />

		)
	}

	handleClick(teamMemberId) {
		this.setState({
			teamMemberId,
		})
	}
}

const styles = {
	scrollContainer: {
		overflow: 'auto',
	},
	teamMemberContainer: {
		display: 'flex',
	},
	imageAndButtonContainer: {
		display: 'flex',
		'justify-content': 'center',
	},
	headshot: {
		height: '240px',
		width: '240px',
		border: '2px solid #FFFFFF',
		'&:hover': {
			border: '2px solid #24A894',
		},
	},
	button: {
		cursor: 'pointer',
		outline: 'none',
		border: 'none',
	},
}

export default injectSheet(styles)(Team)
<commit_msg>Design changes for bio images (#193)<commit_after>import React, { Component } from 'react'
import injectSheet from 'react-jss'
import classNames from 'classnames'

import Spacer from '../components/spacer'
import teamMemberInfo from './team-member-info'
import TeamMember from './team-member'

class Team extends Component {
	constructor(props) {
		super(props)
		this.state = {
			teamMemberId: 0,
		}
	}

	render() {
		const { classes } = this.props
		const { teamMemberId } = this.state
		const { name, title, bio } = teamMemberInfo[teamMemberId]

		const notClickedStyle = classNames(
			classes.headshotSize,
			classes.headshotNotClicked,
		)
		const clickedStyle = classNames(
			classes.headshotSize,
			classes.headshotClicked,
		)

		return (

						{teamMemberInfo.map(teamMember => {
							return (

									<button
										className={classes.button}
										onClick={() => {
											this.handleClick(teamMember.id)
										}}
									>

										<Spacer width="16px" />
									</button>

							)
						})}

				<TeamMember name={name} title={title} bio={bio} />

		)
	}

	handleClick(teamMemberId) {
		this.setState({
			teamMemberId,
		})
	}
}

const styles = {
	scrollContainer: {
		overflow: 'auto',
	},
	teamMemberContainer: {
		display: 'flex',
	},
	imageAndButtonContainer: {
		display: 'flex',
		'justify-content': 'center',
	},
	headshotSize: {
		height: '240px',
		width: '240px',
	},
	headshotNotClicked: {
		border: '2px solid #FFFFFF',
		'&:hover': {
			border: '2px solid #24A894',
		},
	},
	headshotClicked: {
		border: '2px solid #24A894',
	},
	button: {
		cursor: 'pointer',
		outline: 'none',
		border: 'none',
		'background-color': '#FFFFFF', // for Safari
	},
}

export default injectSheet(styles)(Team)
<|endoftext|>


<commit_before>var tabData, fsID,
    dev = chrome.app.getDetails().update_url ? false : true,
    domain = dev ? 'dev4' : 'www',
    mergeEditUrl = 'https://' + domain + '.wikitree.com/wiki/Special:MergeEdit',
    editFamilyUrl = 'https://' + domain + '.wikitree.com/index.php?action=editfamily',
    newPersonUrl = 'https://' + domain + '.wikitree.com/wiki/Special:NewPerson';

// Initiate the scraping
chrome.runtime.getBackgroundPage(function(background){
  background.getTabData();
});

// Listen for the scraping response
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
  if(request.type === 'tabData'){

    // Save the response
    tabData = request;
    setImportSummary(tabData.genscrape);

    // Hide the loading indicator
    document.body.classList.add('loaded');

    // Show FamilySearch components on FamilySearch pages
    if(isFSTreeUrl(tabData.url)){
      fsID = tabData.url.split('/')[5];
      document.body.classList.add('familysearch');
    }
  }
});

//
// Setup button listeners
//

document.getElementById('update-existing-btn').addEventListener('click', updateExisting);
document.getElementById('create-related-btn').addEventListener('click', createRelated);
document.getElementById('create-unrelated-btn').addEventListener('click', createUnrelated);
document.getElementById('fs-connections-btn').addEventListener('click', fsConnect);

//
// Input listeners so that forms are submitted on enter
//
//
document.getElementById('update-existing').addEventListener('keypress', enterListener(updateExisting));
document.getElementById('create-related').addEventListener('keypress', enterListener(createRelated));
document.getElementById('create-unrelated').addEventListener('keypress', enterListener(createUnrelated));
document.getElementById('fs-connections').addEventListener('keypress', enterListener(fsConnect));

/**
 * Update an existing person by POSTing gedcomx data to the MergeEdit page
 */
function updateExisting(){
  var wtID = document.getElementById('update-existing-wt-id').value;
  postData(mergeEditUrl, wtID, tabData.genscrape);
}

/**
 * Open the EditFamilySearch page for the given WikiTree profile
 */
function fsConnect(){
  var wtID = document.getElementById('fs-connections-wt-id').value;
  chrome.tabs.create({
    url: 'http://www.wikitree.com/index.php?title=Special:EditFamilySearch&action=viewUser&user_name=' + wtID + '&fs_id=' + fsID
  });
}

/**
 * Create a new profile related to the given WikiTree profile
 */
function createRelated(){
  var wtID = document.getElementById('create-related-wt-id').value,
      relation = document.getElementById('create-related-relation').value;
  postData(editFamilyUrl + '&w=' + relation + '&title=' + wtID, '', tabData.genscrape);
}

/**
 * Create a new profile related to the given WikiTree profile
 */
function createUnrelated(){
  postData(newPersonUrl, '', tabData.genscrape);
}

/**
 * Check if a URL is of a person in the FamilySearch tree.
 *
 * @param {String} url
 * @return {Boolean}
 */
function isFSTreeUrl(url){
  return url.indexOf('https://familysearch.org/tree/person/') === 0;
}

/**
 * POST JSON data to the specified URL
 *
 * @param  {string} url
 * @param  {string} profileId
 * @param  {object} data
 */
function postData(url, profileId, data){
  var $form = document.getElementById('form'),
      $wtId = document.getElementById('wtId'),
      $wtUsername = document.getElementById('wtUsername');

  $form.action = url;

  // Decide whether we have a user ID or a profile name
  if(profileId){
    if(parseInt(profileId, 10)){
      $wtId.value = profileId;
    } else {
      $wtUsername.value = profileId;
    }
  }

  document.getElementById('postData').value = JSON.stringify(data);
  $form.submit();
}

/**
 * Setup an event listener that calls the given function when
 * an enter keypress event is detected
 *
 * @param {Function} func
 * @return {Function} listener
 */
function enterListener(func){
  return function(event){
    if(enterPressed(event)){
      func();
    }
  };
}

/**
 * Check if an event was fired by pressing the enter key
 *
 * @param {Event} event
 * @return {Boolean}
 */
function enterPressed(event){
  var key = event.which || event.keyCode;
  return key === 13;
}

/**
 * Set the import summary for genscrape data
 */
function setImportSummary(gedx){
  if(gedx && gedx.description && Array.isArray(gedx.sourceDescriptions)){
    var description = gedx.sourceDescriptions.find(function(sd){
      return sd.id === gedx.description.substring(1);
    });
    if(description && description.repository && Array.isArray(gedx.agents)){
      var agent = gedx.agents.find(function(a){
        return a.id === description.repository.resource.substring(1);
      });
      if(agent){
        var person = gedx.persons.find(function(p){ return p.principal; }) || gedx.persons[0];
        gedx.summary = 'Imported data from ' + agent.names[0].value + ' ' + person.id + '.';
      }
    }
  }
}
<commit_msg>fix dev url<commit_after>var tabData, fsID,
    dev = chrome.app.getDetails().update_url ? false : true,
    domain = dev ? 'dev' : 'www',
    mergeEditUrl = 'https://' + domain + '.wikitree.com/wiki/Special:MergeEdit',
    editFamilyUrl = 'https://' + domain + '.wikitree.com/index.php?action=editfamily',
    newPersonUrl = 'https://' + domain + '.wikitree.com/wiki/Special:NewPerson';

// Initiate the scraping
chrome.runtime.getBackgroundPage(function(background){
  background.getTabData();
});

// Listen for the scraping response
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
  if(request.type === 'tabData'){

    // Save the response
    tabData = request;
    setImportSummary(tabData.genscrape);

    // Hide the loading indicator
    document.body.classList.add('loaded');

    // Show FamilySearch components on FamilySearch pages
    if(isFSTreeUrl(tabData.url)){
      fsID = tabData.url.split('/')[5];
      document.body.classList.add('familysearch');
    }
  }
});

//
// Setup button listeners
//

document.getElementById('update-existing-btn').addEventListener('click', updateExisting);
document.getElementById('create-related-btn').addEventListener('click', createRelated);
document.getElementById('create-unrelated-btn').addEventListener('click', createUnrelated);
document.getElementById('fs-connections-btn').addEventListener('click', fsConnect);

//
// Input listeners so that forms are submitted on enter
//
//
document.getElementById('update-existing').addEventListener('keypress', enterListener(updateExisting));
document.getElementById('create-related').addEventListener('keypress', enterListener(createRelated));
document.getElementById('create-unrelated').addEventListener('keypress', enterListener(createUnrelated));
document.getElementById('fs-connections').addEventListener('keypress', enterListener(fsConnect));

/**
 * Update an existing person by POSTing gedcomx data to the MergeEdit page
 */
function updateExisting(){
  var wtID = document.getElementById('update-existing-wt-id').value;
  postData(mergeEditUrl, wtID, tabData.genscrape);
}

/**
 * Open the EditFamilySearch page for the given WikiTree profile
 */
function fsConnect(){
  var wtID = document.getElementById('fs-connections-wt-id').value;
  chrome.tabs.create({
    url: 'http://www.wikitree.com/index.php?title=Special:EditFamilySearch&action=viewUser&user_name=' + wtID + '&fs_id=' + fsID
  });
}

/**
 * Create a new profile related to the given WikiTree profile
 */
function createRelated(){
  var wtID = document.getElementById('create-related-wt-id').value,
      relation = document.getElementById('create-related-relation').value;
  postData(editFamilyUrl + '&w=' + relation + '&title=' + wtID, '', tabData.genscrape);
}

/**
 * Create a new profile related to the given WikiTree profile
 */
function createUnrelated(){
  postData(newPersonUrl, '', tabData.genscrape);
}

/**
 * Check if a URL is of a person in the FamilySearch tree.
 *
 * @param {String} url
 * @return {Boolean}
 */
function isFSTreeUrl(url){
  return url.indexOf('https://familysearch.org/tree/person/') === 0;
}

/**
 * POST JSON data to the specified URL
 *
 * @param  {string} url
 * @param  {string} profileId
 * @param  {object} data
 */
function postData(url, profileId, data){
  var $form = document.getElementById('form'),
      $wtId = document.getElementById('wtId'),
      $wtUsername = document.getElementById('wtUsername');

  $form.action = url;

  // Decide whether we have a user ID or a profile name
  if(profileId){
    if(parseInt(profileId, 10)){
      $wtId.value = profileId;
    } else {
      $wtUsername.value = profileId;
    }
  }

  document.getElementById('postData').value = JSON.stringify(data);
  $form.submit();
}

/**
 * Setup an event listener that calls the given function when
 * an enter keypress event is detected
 *
 * @param {Function} func
 * @return {Function} listener
 */
function enterListener(func){
  return function(event){
    if(enterPressed(event)){
      func();
    }
  };
}

/**
 * Check if an event was fired by pressing the enter key
 *
 * @param {Event} event
 * @return {Boolean}
 */
function enterPressed(event){
  var key = event.which || event.keyCode;
  return key === 13;
}

/**
 * Set the import summary for genscrape data
 */
function setImportSummary(gedx){
  if(gedx && gedx.description && Array.isArray(gedx.sourceDescriptions)){
    var description = gedx.sourceDescriptions.find(function(sd){
      return sd.id === gedx.description.substring(1);
    });
    if(description && description.repository && Array.isArray(gedx.agents)){
      var agent = gedx.agents.find(function(a){
        return a.id === description.repository.resource.substring(1);
      });
      if(agent){
        var person = gedx.persons.find(function(p){ return p.principal; }) || gedx.persons[0];
        gedx.summary = 'Imported data from ' + agent.names[0].value + ' ' + person.id + '.';
      }
    }
  }
}
<|endoftext|>


<commit_before>require('colors');
var mout = require('mout');
var template = require('../util/template');

function StandardRenderer(command, config) {
    this._sizes = {
        id: 13,    // Id max chars
        label: 20, // Label max chars
        sumup: 5   // Amount to sum when the label exceeds
    };
    this._colors = {
        warn: 'yellow',
        error: 'red',
        conflict: 'magenta',
        'default': 'cyan'
    };

    this._command = command;
    this._config = config;

    if (this.constructor._wideCommands.indexOf(command) === -1) {
        this._compact = true;
    } else {
        this._compact = process.stdout.columns < 120;
    }
}

StandardRenderer.prototype.end = function (data) {
    var method = '_' + mout.string.camelCase(this._command);

    if (this[method]) {
        this[method](data);
    }
};

StandardRenderer.prototype.error = function (err) {
    var str;

    this._guessOrigin(err);

    err.id = err.code || 'error';
    err.level = 'error';

    str = this._prefix(err) + ' ' + err.message + '\n';

    // Check if additional details were provided
    if (err.details) {
        str += mout.string.trim(err.details) + '\n';
    }

    // Print stack if verbose or the error has no code
    // In some cases there's no stack (Maximum call stack exceeded errors)
    if (err.stack && (this._config.verbose || !err.code)) {
        str += '\n' + err.stack + '\n';
    }

    this._write(process.stderr, 'bower ' + str);
};

StandardRenderer.prototype.log = function (log) {
    var method = '_' + mout.string.camelCase(log.id) + 'Log';

    this._guessOrigin(log);

    // Call render method for this log entry or the generic one
    if (this[method]) {
        this[method](log);
    } else {
        this._genericLog(log);
    }
};

StandardRenderer.prototype.updateNotice = function (data) {
    var str = template.render('std/update-notice.std', data);
    this._write(process.stderr, str);
};

// -------------------------

StandardRenderer.prototype._help = function (data) {
    var str;
    var that = this;
    var specific;

    if (!data.command) {
        str = template.render('std/help.std', data);
        that._write(process.stdout, str);
    } else {
        // Check if a specific template exists for the command
        specific = 'std/help-' + data.command.replace(/\s+/g, '/') + '.std';

        if (template.exists(specific)) {
            str = template.render(specific, data);
        } else {
            str =  template.render('std/help-generic.std', data);
        }

        that._write(process.stdout, str);
    }
};

StandardRenderer.prototype._cacheList = function (entries) {
    entries.forEach(function (pkgMeta) {
        this.log({
            level: 'info',
            id: 'cached-entry',
            message: pkgMeta._source + (pkgMeta._release ? '#' + pkgMeta._release : ''),
            data: {
                name: pkgMeta.name,
                version: pkgMeta.version
            }
        });
    }, this);
};

// -------------------------

StandardRenderer.prototype._genericLog = function (log) {
    var stream;
    var str;

    if (log.level === 'warn') {
        stream = process.stderr;
    } else {
        stream = process.stdout;
    }

    str = this._prefix(log) + ' ' + log.message + '\n';
    this._write(stream, 'bower ' + str);
};

StandardRenderer.prototype._checkoutLog = function (log) {
    if (this._compact) {
        log.message = log.origin.split('#')[0] + '#' + log.message;
    }

    this._genericLog(log);
};

StandardRenderer.prototype._incompatibleLog = function (log) {
    var str;
    var templatePath;

    // Generate dependants string for each pick
    log.data.picks.forEach(function (pick) {
        pick.dependants = pick.dependants.map(function (dependant) {
            var release = dependant.pkgMeta._release;
            return dependant.endpoint.name + (release ? '#' + release : '');
        }).join(', ');
    });

    templatePath = log.data.resolution ? 'std/conflict-resolved.std' : 'std/conflict.std';
    str = template.render(templatePath, log.data);

    this._write(process.stdout, '\n');
    this._write(process.stdout, str);
    this._write(process.stdout, '\n');
};

StandardRenderer.prototype._solvedLog = function (log) {
    this._incompatibleLog(log);
};

StandardRenderer.prototype._cachedEntryLog = function (log) {
    if (this._compact) {
        log.message = log.origin;
    }

    this._genericLog(log);
};

// -------------------------

StandardRenderer.prototype._guessOrigin = function (log) {
    if (log.data.endpoint) {
        log.origin = log.data.endpoint.name || (log.data.registry && log.data.endpoint.source);

        // Resort to using the resolver name for unnamed endpoints
        if (!log.origin && log.data.resolver) {
            log.origin = log.data.resolver.name;
        }

        if (log.data.endpoint.target) {
            log.origin += '#' + log.data.endpoint.target;
        }
    } else if (log.data.name) {
        log.origin = log.data.name;

        if (log.data.version) {
            log.origin += '#' + log.data.version;
        }
    }
};

StandardRenderer.prototype._prefix = function (log) {
    var label;
    var length;
    var nrSpaces;
    var id = this.constructor._idMappings[log.id] || log.id;
    var idColor = this._colors[log.level] || this._colors['default'];

    if (this._compact) {
        // If there's not enough space for the id, adjust it
        // for subsequent logs
        if (id.length > this._sizes.id) {
            this._sizes.id = id.length += this._sizes.sumup;
        }

        return mout.string.rpad(id, this._sizes.id)[idColor];
    }

    // Construct the label
    label = log.origin || '';
    length = id.length + label.length + 1;
    nrSpaces = this._sizes.id + this._sizes.label - length;

    // Ensure at least one space between the label and the id
    if (nrSpaces < 1) {
        // Also adjust the label size for subsequent logs
        this._sizes.label = label.length + this._sizes.sumup;
        nrSpaces = this._sizes.id + this._sizes.label - length;
    }

    return label.green + mout.string.repeat(' ', nrSpaces) + id[idColor];
};

StandardRenderer.prototype._write = function (stream, str) {
    if (!this._config.color) {
        str = str.replace(/\x1B\[\d+m/g, '');
    }

    stream.write(str);
};

StandardRenderer._wideCommands = [
    'install',
    'update',
    'cache clean',
    'cache list'
];
StandardRenderer._idMappings = {
    'mutual': 'conflict',
    'cached-entry': 'cached'
};

module.exports = StandardRenderer;
<commit_msg>Fix cache list not displaying the correct version.<commit_after>require('colors');
var mout = require('mout');
var template = require('../util/template');

function StandardRenderer(command, config) {
    this._sizes = {
        id: 13,    // Id max chars
        label: 20, // Label max chars
        sumup: 5   // Amount to sum when the label exceeds
    };
    this._colors = {
        warn: 'yellow',
        error: 'red',
        conflict: 'magenta',
        'default': 'cyan'
    };

    this._command = command;
    this._config = config;

    if (this.constructor._wideCommands.indexOf(command) === -1) {
        this._compact = true;
    } else {
        this._compact = process.stdout.columns < 120;
    }
}

StandardRenderer.prototype.end = function (data) {
    var method = '_' + mout.string.camelCase(this._command);

    if (this[method]) {
        this[method](data);
    }
};

StandardRenderer.prototype.error = function (err) {
    var str;

    this._guessOrigin(err);

    err.id = err.code || 'error';
    err.level = 'error';

    str = this._prefix(err) + ' ' + err.message + '\n';

    // Check if additional details were provided
    if (err.details) {
        str += mout.string.trim(err.details) + '\n';
    }

    // Print stack if verbose or the error has no code
    // In some cases there's no stack (Maximum call stack exceeded errors)
    if (err.stack && (this._config.verbose || !err.code)) {
        str += '\n' + err.stack + '\n';
    }

    this._write(process.stderr, 'bower ' + str);
};

StandardRenderer.prototype.log = function (log) {
    var method = '_' + mout.string.camelCase(log.id) + 'Log';

    this._guessOrigin(log);

    // Call render method for this log entry or the generic one
    if (this[method]) {
        this[method](log);
    } else {
        this._genericLog(log);
    }
};

StandardRenderer.prototype.updateNotice = function (data) {
    var str = template.render('std/update-notice.std', data);
    this._write(process.stderr, str);
};

// -------------------------

StandardRenderer.prototype._help = function (data) {
    var str;
    var that = this;
    var specific;

    if (!data.command) {
        str = template.render('std/help.std', data);
        that._write(process.stdout, str);
    } else {
        // Check if a specific template exists for the command
        specific = 'std/help-' + data.command.replace(/\s+/g, '/') + '.std';

        if (template.exists(specific)) {
            str = template.render(specific, data);
        } else {
            str =  template.render('std/help-generic.std', data);
        }

        that._write(process.stdout, str);
    }
};

StandardRenderer.prototype._cacheList = function (entries) {
    entries.forEach(function (pkgMeta) {
        this.log({
            level: 'info',
            id: 'cached-entry',
            message: pkgMeta._source + (pkgMeta._release ? '#' + pkgMeta._release : ''),
            data: {
                name: pkgMeta.name,
                version: pkgMeta._version || (pkgMeta._target === '*' ? '' : pkgMeta._target)

            }
        });
    }, this);
};

// -------------------------

StandardRenderer.prototype._genericLog = function (log) {
    var stream;
    var str;

    if (log.level === 'warn') {
        stream = process.stderr;
    } else {
        stream = process.stdout;
    }

    str = this._prefix(log) + ' ' + log.message + '\n';
    this._write(stream, 'bower ' + str);
};

StandardRenderer.prototype._checkoutLog = function (log) {
    if (this._compact) {
        log.message = log.origin.split('#')[0] + '#' + log.message;
    }

    this._genericLog(log);
};

StandardRenderer.prototype._incompatibleLog = function (log) {
    var str;
    var templatePath;

    // Generate dependants string for each pick
    log.data.picks.forEach(function (pick) {
        pick.dependants = pick.dependants.map(function (dependant) {
            var release = dependant.pkgMeta._release;
            return dependant.endpoint.name + (release ? '#' + release : '');
        }).join(', ');
    });

    templatePath = log.data.resolution ? 'std/conflict-resolved.std' : 'std/conflict.std';
    str = template.render(templatePath, log.data);

    this._write(process.stdout, '\n');
    this._write(process.stdout, str);
    this._write(process.stdout, '\n');
};

StandardRenderer.prototype._solvedLog = function (log) {
    this._incompatibleLog(log);
};

StandardRenderer.prototype._cachedEntryLog = function (log) {
    if (this._compact) {
        log.message = log.origin;
    }

    this._genericLog(log);
};

// -------------------------

StandardRenderer.prototype._guessOrigin = function (log) {
    if (log.data.endpoint) {
        log.origin = log.data.endpoint.name || (log.data.registry && log.data.endpoint.source);

        // Resort to using the resolver name for unnamed endpoints
        if (!log.origin && log.data.resolver) {
            log.origin = log.data.resolver.name;
        }

        if (log.data.endpoint.target) {
            log.origin += '#' + log.data.endpoint.target;
        }
    } else if (log.data.name) {
        log.origin = log.data.name;

        if (log.data.version) {
            log.origin += '#' + log.data.version;
        }
    }
};

StandardRenderer.prototype._prefix = function (log) {
    var label;
    var length;
    var nrSpaces;
    var id = this.constructor._idMappings[log.id] || log.id;
    var idColor = this._colors[log.level] || this._colors['default'];

    if (this._compact) {
        // If there's not enough space for the id, adjust it
        // for subsequent logs
        if (id.length > this._sizes.id) {
            this._sizes.id = id.length += this._sizes.sumup;
        }

        return mout.string.rpad(id, this._sizes.id)[idColor];
    }

    // Construct the label
    label = log.origin || '';
    length = id.length + label.length + 1;
    nrSpaces = this._sizes.id + this._sizes.label - length;

    // Ensure at least one space between the label and the id
    if (nrSpaces < 1) {
        // Also adjust the label size for subsequent logs
        this._sizes.label = label.length + this._sizes.sumup;
        nrSpaces = this._sizes.id + this._sizes.label - length;
    }

    return label.green + mout.string.repeat(' ', nrSpaces) + id[idColor];
};

StandardRenderer.prototype._write = function (stream, str) {
    if (!this._config.color) {
        str = str.replace(/\x1B\[\d+m/g, '');
    }

    stream.write(str);
};

StandardRenderer._wideCommands = [
    'install',
    'update',
    'cache clean',
    'cache list'
];
StandardRenderer._idMappings = {
    'mutual': 'conflict',
    'cached-entry': 'cached'
};

module.exports = StandardRenderer;
<|endoftext|>