<commit_before>/*
* Functions to create the mini modal maps
*/

// initialize map
function CDADModalMap(mapid, lat, lon, zoom, surveyid, type, numid) {

	//console.log(mapid);

    //where detroit is 42.377410, -83.093719
    this.map = new L.Map(mapid, {
		minZoom: 8,
		maxZoom: 16,
		attributionControl: false,
	});

	// add CartoDB tiles
	this.CartoDBLayer = L.tileLayer('http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png');

	// add cartoDB tiles to start
	this.map.addLayer(this.CartoDBLayer);

	// create empty container for locations
	this.LOCATION = null;

	// create and empty container for detroit city boundary
	this.DETLAYER = null;
	this.CDOBCLAYER = null;

	if (type == 'locationAndSA') {
		// add location
		CDADModalMap.add_LOCATION(this, numid);

		// add SA
		CDADModalMap.add_SA(this, surveyid, numid);

	} else if (type == 'SA') {
		// add SA
		CDADModalMap.add_SA(this, surveyid, numid);

	} else if (type == 'location') {
		// add location
		CDADModalMap.add_LOCATION(this, numid);

		// set center and zoom
		this.map.setView([lat,lon], zoom);

		bounds[numid] = this.map.getBounds();

	} else {
		this.DETLAYER_style = L.geoJson(null, {
		    style: CDADModalMap.getStyleColorFor_DETLAYER,
		}).addTo(this.map);

		this.DETLAYER = omnivore.topojson(detlayer, null, this.DETLAYER_style);

		// set center and zoom
		this.map.setView([lat,lon], zoom);

		var southWest = L.latLng(42.257746, -83.295593);
		var northEast = L.latLng(42.489061, -82.853394);
		bounds[numid] = L.latLngBounds(southWest, northEast);

		console.log(bounds[numid]);

	}

}

CDADModalMap.add_LOCATION = function(sel, numid) {
	// define layer styles and oneachfeature popup styling
	sel.LOCATION = L.geoJson(locations, {
		pointToLayer: CDADModalMap.getStyleFor_LOCATION,
		filter: function(feature, layer) {
			if (feature.properties.counterId == numid) {
				return true;
			} else {
				return false;
			}
	    }
	});

	sel.map.addLayer(sel.LOCATION);
}

CDADModalMap.add_SA = function(sel, surveyid, numid) {
	$.ajax({
		type: "GET",
		url: "/getjsonformap/"+ surveyid +"/",
		success: function(data){
			// load the draw tools
			if (data) {
				var geojson = JSON.parse(data);

				sel.CDOBCLAYER = L.geoJson(geojson, {
			        style: CDADModalMap.getStyleColorFor_CDOBCLAYER,
			    });
			    sel.map.addLayer(sel.CDOBCLAYER);

			    // fit map to bounds of layer
				bounds[numid] = sel.CDOBCLAYER.getBounds();
				sel.map.fitBounds(bounds[numid]);

			}
        }
	});
}

CDADModalMap.getStyleFor_LOCATION = function(feature, latlng){
	var locationIcon = L.icon({
	    iconUrl: feature.properties.iconUrl,
	    iconSize: [24, 32],
		iconAnchor: [12, 30],
	});

	return L.marker(latlng, {icon: locationIcon});

}

CDADModalMap.getStyleColorFor_CDOBCLAYER = function (feature){
    return {
        weight: 2,
        opacity: 0.75,
        color: '#e8c51d',
        fillOpacity: 0.5,
        fill: '#e8c51d'
    }
}

CDADModalMap.getStyleColorFor_DETLAYER = function (feature){
    return {
        weight: 2,
        opacity: 1,
        color: '#252525',
        fillOpacity: 0
    }
}

<commit_msg>bounds<commit_after>/*
* Functions to create the mini modal maps
*/

// initialize map
function CDADModalMap(mapid, lat, lon, zoom, surveyid, type, numid) {

	//console.log(mapid);

    //where detroit is 42.377410, -83.093719
    this.map = new L.Map(mapid, {
		minZoom: 8,
		maxZoom: 16,
		attributionControl: false,
	});

	// add CartoDB tiles
	this.CartoDBLayer = L.tileLayer('http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png');

	// add cartoDB tiles to start
	this.map.addLayer(this.CartoDBLayer);

	// create empty container for locations
	this.LOCATION = null;

	// create and empty container for detroit city boundary
	this.DETLAYER = null;
	this.CDOBCLAYER = null;

	if (type == 'locationAndSA') {
		// add location
		CDADModalMap.add_LOCATION(this, numid);

		// add SA
		CDADModalMap.add_SA(this, surveyid, numid);

	} else if (type == 'SA') {
		// add SA
		CDADModalMap.add_SA(this, surveyid, numid);

	} else if (type == 'location') {
		// add location
		CDADModalMap.add_LOCATION(this, numid);

		// set center and zoom
		this.map.setView([lat,lon], zoom);

		bounds[numid] = this.map.getBounds();

	} else {
		this.DETLAYER_style = L.geoJson(null, {
		    style: CDADModalMap.getStyleColorFor_DETLAYER,
		}).addTo(this.map);

		this.DETLAYER = omnivore.topojson(detlayer, null, this.DETLAYER_style);

		// set center and zoom
		this.map.setView([lat,lon], zoom);

		var southWest = L.latLng(42.257746, -83.295593);
		var northEast = L.latLng(42.489061, -82.853394);
		bounds[numid] = L.latLngBounds(southWest, northEast);

	}

}

CDADModalMap.add_LOCATION = function(sel, numid) {
	// define layer styles and oneachfeature popup styling
	sel.LOCATION = L.geoJson(locations, {
		pointToLayer: CDADModalMap.getStyleFor_LOCATION,
		filter: function(feature, layer) {
			if (feature.properties.counterId == numid) {
				return true;
			} else {
				return false;
			}
	    }
	});

	sel.map.addLayer(sel.LOCATION);
}

CDADModalMap.add_SA = function(sel, surveyid, numid) {
	$.ajax({
		type: "GET",
		url: "/getjsonformap/"+ surveyid +"/",
		success: function(data){
			// load the draw tools
			if (data) {
				var geojson = JSON.parse(data);

				sel.CDOBCLAYER = L.geoJson(geojson, {
			        style: CDADModalMap.getStyleColorFor_CDOBCLAYER,
			    });
			    sel.map.addLayer(sel.CDOBCLAYER);

			    // fit map to bounds of layer
				bounds[numid] = sel.CDOBCLAYER.getBounds();
				sel.map.fitBounds(bounds[numid]);

			}
        }
	});
}

CDADModalMap.getStyleFor_LOCATION = function(feature, latlng){
	var locationIcon = L.icon({
	    iconUrl: feature.properties.iconUrl,
	    iconSize: [24, 32],
		iconAnchor: [12, 30],
	});

	return L.marker(latlng, {icon: locationIcon});

}

CDADModalMap.getStyleColorFor_CDOBCLAYER = function (feature){
    return {
        weight: 2,
        opacity: 0.75,
        color: '#e8c51d',
        fillOpacity: 0.5,
        fill: '#e8c51d'
    }
}

CDADModalMap.getStyleColorFor_DETLAYER = function (feature){
    return {
        weight: 2,
        opacity: 1,
        color: '#252525',
        fillOpacity: 0
    }
}

<|endoftext|>


<commit_before>taxi.bdd = function bdd () {

  var
    helpers = [
      'driver',
      'passenger',
      'beforeEach',
      'afterEach'
    ],
    drivers,
    config,
    driverContext;

  function initialize () {
    drivers = [];
    driverContext = null;
    passengerContext = null;
    config = {
      drivers : drivers
    };
  }

  // Helpers:
  function addDriver (name, callback) {
    var
      driver = {
        key : driverKey(name),
        name : name,
        passengers : []
      };
    driverContext = driver;
    callback.call(this);
    driverContext = null;
    drivers.push(driver);
    return driver;
  }
  function addPassenger (name, callback) {
    var
      passenger = {
        key : passengerKey(name),
        name : name,
        callback : callback
      };
    passenger = passenger;
    driverContext.passengers.push(passenger);
    return passenger;
  }
  function validate (name, callback, type) {
    if (!name || !_.isString(name)) {
      throw new Error('invalid ' + type + ' name');
    }
    if (!_.isFunction(callback)) {
      throw new Error('invalid ' + type + ' callback');
    }
  }

  // Keys:
  function nameToKey (name) {
    return (name || '')
      .replace(/[^\w]+/g, '_')
      .toLowerCase();
  }
  function uniqueKey (list, key) {
    var
      testKey = key,
      index = 1;
    function test (item) {
      return item.key === testKey;
    }
    while (_.any(list, test)) {
      testKey = key + '_' + index++;
    }
    return testKey;
  }
  function driverKey (name) {
    return uniqueKey(drivers, nameToKey(name));
  }
  function passengerKey (name) {
    return uniqueKey(driverContext.passengers, nameToKey(name));
  }

  // Class:
  initialize();
  return {
    driver : function (name, callback) {
      if (driverContext) {
        throw new Error('already driving');
      }
      validate(name, callback, 'driver');
      return addDriver(name, callback);
    },
    passenger : function (name, callback) {
      if (!driverContext) {
        throw new Error('no driver');
      }
      validate(name, callback, 'passenger');
      return addPassenger(name, callback);
    },
    beforeEach : function (callback) {
    },
    afterEach : function (callback) {
    },
    data : function data () {
      return config;
    },
    inject : function (context) {
      if (_.isObject(context)) {
        _.each(helpers, function (helper) {
          context[helper] = this[helper];
        }, this);
      }
    },
   reset : function () {
     initialize();
   }
  };
};
<commit_msg>Remove unused passenger context.<commit_after>taxi.bdd = function bdd () {

  var
    helpers = [
      'driver',
      'passenger',
      'beforeEach',
      'afterEach'
    ],
    drivers,
    config,
    driverContext;

  function initialize () {
    drivers = [];
    driverContext = null;
    config = {
      drivers : drivers
    };
  }

  // Helpers:
  function addDriver (name, callback) {
    var
      driver = {
        key : driverKey(name),
        name : name,
        passengers : []
      };
    driverContext = driver;
    callback.call(this);
    driverContext = null;
    drivers.push(driver);
    return driver;
  }
  function addPassenger (name, callback) {
    var
      passenger = {
        key : passengerKey(name),
        name : name,
        callback : callback
      };
    passenger = passenger;
    driverContext.passengers.push(passenger);
    return passenger;
  }
  function validate (name, callback, type) {
    if (!name || !_.isString(name)) {
      throw new Error('invalid ' + type + ' name');
    }
    if (!_.isFunction(callback)) {
      throw new Error('invalid ' + type + ' callback');
    }
  }

  // Keys:
  function nameToKey (name) {
    return (name || '')
      .replace(/[^\w]+/g, '_')
      .toLowerCase();
  }
  function uniqueKey (list, key) {
    var
      testKey = key,
      index = 1;
    function test (item) {
      return item.key === testKey;
    }
    while (_.any(list, test)) {
      testKey = key + '_' + index++;
    }
    return testKey;
  }
  function driverKey (name) {
    return uniqueKey(drivers, nameToKey(name));
  }
  function passengerKey (name) {
    return uniqueKey(driverContext.passengers, nameToKey(name));
  }

  // Class:
  initialize();
  return {
    driver : function (name, callback) {
      if (driverContext) {
        throw new Error('already driving');
      }
      validate(name, callback, 'driver');
      return addDriver(name, callback);
    },
    passenger : function (name, callback) {
      if (!driverContext) {
        throw new Error('no driver');
      }
      validate(name, callback, 'passenger');
      return addPassenger(name, callback);
    },
    beforeEach : function (callback) {
    },
    afterEach : function (callback) {
    },
    data : function data () {
      return config;
    },
    inject : function (context) {
      if (_.isObject(context)) {
        _.each(helpers, function (helper) {
          context[helper] = this[helper];
        }, this);
      }
    },
   reset : function () {
     initialize();
   }
  };
};
<|endoftext|>


<commit_before>
'use strict';

var LinkList = require('./linklist');

module.exports = Port;

function Port () {
    this._closed = false;
    this._message = void 0;

    this._takers = new LinkList();
    this._senders = new LinkList();

    // Native Promise does not support inherits yet !!!
    this._promise = new Promise(function (resolve) {
        this._resolve = resolve;
    }.bind(this));
}
// require('util').inherits(Port, Promise);

Port.prototype.take = function () {
    var self = this;
    return new Promise(function (resolve) {
        self._take(resolve);
    });
}

Port.prototype.put = function (data) {
    var self = this;
    return new Promise(function (resolve) {
        self._put(data, resolve);
    });
}

Port.prototype.then = function (ifResolved) {
    return this._promise.then(ifResolved)
}

Port.prototype.close = function (message) {
    if (this._closed) return;
    this._closed = true;
    this._message = message;

    this._resolve(message);

    while (!this._takers.isEmpty()) {
        this._takers.shift()({
            done: true,
            value: message
        });
    }
    while (!this._senders.isEmpty()) {
        this._senders.shift()(false);
    }
}

Port.prototype.isClosed = function () {
    return this._closed;
}

Port.prototype.getCloseMessage = function () {
    return this._message;
}

// internal usage, release zalgo!
Port.prototype._take = function (cb) {
    if (this._closed) {
        cb({ done: true, value: this._message });
        return;
    }
    if (this._senders.isEmpty()) {
        return this._takers.push(cb); // handle object
    } else {
        var sender = this._senders.shift();
        sender(true);
        cb({ done: false, value: sender.data });
    }
}

// internal usage, release zalgo!
Port.prototype._put = function (data, cb) {
    if (this._closed) {
        cb(false);
        return;
    }
    if (this._takers.isEmpty()) {
        cb.data = data;
        return this._senders.push(cb);
    } else {
        var taker = this._takers.shift();
        taker({ done: false, value: data });
        cb(true);
    }
}
<commit_msg>refactor port.js<commit_after>
'use strict'

var LinkList = require('./linklist')

module.exports = Port

function Port () {
    this._closed = false
    this._message = void 0

    this._takers = new LinkList()
    this._senders = new LinkList()

    // Native Promise does not support inherits yet !!!
    var self = this
    self._promise = new Promise(function (resolve) {
        self._resolve = resolve
    })
}
// require('util').inherits(Port, Promise)

Port.prototype.take = function () {
    var self = this
    return new Promise(function (resolve) {
        self._take(resolve)
    })
}

Port.prototype.put = function (data) {
    var self = this
    return new Promise(function (resolve) {
        self._put(data, resolve)
    })
}

Port.prototype.then = function (ifResolved) {
    return this._promise.then(ifResolved)
}

Port.prototype.close = function (message) {
    if (this._closed) { return }
    this._closed = true
    this._message = message

    this._resolve(message)

    while (!this._takers.isEmpty()) {
        this._takers.shift()({
            done: true,
            value: message
        })
    }
    while (!this._senders.isEmpty()) {
        this._senders.shift()(false)
    }
}

Port.prototype.isClosed = function () {
    return this._closed
}

Port.prototype.getCloseMessage = function () {
    if (!this._closed) {
        throw new Error('Cannot get message from open port!')
    }
    return this._message
}

// internal usage, release zalgo!
Port.prototype._take = function (cb) {
    if (this._closed) {
        cb({ done: true, value: this._message })
        return
    }
    if (this._senders.isEmpty()) {
        return this._takers.push(cb) // handle object
    }
    var sender = this._senders.shift()
    sender(true)
    cb({ done: false, value: sender.data })
}

// internal usage, release zalgo!
Port.prototype._put = function (data, cb) {
    if (this._closed) {
        cb(false)
        return
    }
    if (this._takers.isEmpty()) {
        cb.data = data
        return this._senders.push(cb)
    }
    var taker = this._takers.shift()
    taker({ done: false, value: data })
    cb(true)
}
<|endoftext|>


<commit_before>// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.

define([
  'api',
  'addons/documents/index-results/stores',
  'addons/documents/index-results/actiontypes',
  'addons/documents/shared-resources',
  'testUtils'
], function (FauxtonAPI, Stores, ActionTypes, Documents, testUtils) {
  var assert = testUtils.assert;
  var dispatchToken;
  var store;
  var opts;

  describe('Index Results Store', function () {
    beforeEach(function () {
      store = new Stores.IndexResultsStore();
      dispatchToken = FauxtonAPI.dispatcher.register(store.dispatch);
      opts = {
        params: {},
        database: {
          safeID: function () { return '1';}
        }
      };
    });

    afterEach(function () {
      FauxtonAPI.dispatcher.unregister(dispatchToken);
    });

    describe('#hasResults', function () {

      it('returns true for collection', function () {
        store._collection = [1, 2, 3];

        assert.ok(store.hasResults());
      });

      it('returns false for empty collection', function () {
        store._collection = [];

        assert.notOk(store.hasResults());
      });

    });

    describe('#getResults', function () {

      it('has correct doc format', function () {
        store._collection = new Documents.AllDocs([{_id: 'testId'}], opts);

        var doc = store.getResults().results[0];
        assert.equal(doc.id, 'testId');
        assert.equal(doc.keylabel, 'id');
      });

    });
  });

  describe('canSelectAll', function () {

    it('returns true for selected docs less than collection', function () {
      store._collection = new Documents.AllDocs([{_id: 'testId1'}, {_id: 'testId2'}], opts);

      store._selectedItems = {'testId1': true};
      assert.ok(store.canSelectAll());
    });

    it('returns false for selected docs same as collection', function () {
      store._collection = new Documents.AllDocs([{_id: 'testId1'}, {_id: 'testId2'}], opts);

      store._selectedItems = {
        'testId1': true,
        'testId2': true
      };

      assert.notOk(store.canSelectAll());
    });

    it('returns true even with _all_docs (mango)', function () {
      store._collection = new Documents.AllDocs([
        {_id: 'testId1'},
        {_id: 'testId2'},
        {_id: '_all_docs'}
      ], opts);

      store._selectedItems = {
        'testId1': true,
        'testId2': true
      };

      assert.notOk(store.canSelectAll());
    });
  });

  describe('canDeselectAll', function () {

    it('returns true for selected docs', function () {
      store._selectedItems = {'testId1': true};
      assert.ok(store.canDeselectAll());
    });

    it('returns false for no selected docs', function () {
      store._selectedItems = {};

      assert.notOk(store.canDeselectAll());
    });

  });

  describe('getDocContent', function () {

    it('returns full doc if not collapsed', function () {
      store._collection = new Documents.AllDocs([{_id: 'testId1', 'value': 'one'}], opts);

      var doc = store._collection.first();
      var result = store.getDocContent(doc);

      assert.equal(JSON.parse(result).value, 'one');
    });

    it('returns just the revision as content if collapsed', function () {
      store._collection = new Documents.AllDocs([{_id: 'testId1', _rev: 'a', 'value': 'one'}], opts);

      var doc = store._collection.first();
      store._allCollapsed = true;
      var result = store.getDocContent(doc);

      assert.deepEqual({"rev": "a"}, JSON.parse(result));
    });

  });

  describe('#selectDoc', function () {

    it('selects doc if not already selected', function () {
      store._selectedItems = {};
      store.selectDoc('id');
      assert.equal(store.getSelectedItemsLength(), 1);
    });

    it('deselects doc if already selected', function () {
      store._selectedItems = {'id': true};
      store.selectDoc('id');
      assert.equal(store.getSelectedItemsLength(), 0);
    });
  });

  describe('#selectAllDocuments', function () {

    it('selects all documents', function () {
      store._collection = new Documents.AllDocs([{_id: 'testId1', 'value': 'one'}], opts);

      store.selectAllDocuments();
      assert.ok(store.getSelectedItems().testId1);
    });

  });

  describe('toggleSelectAllDocuments', function () {

    it('deselects all documents', function () {
      store._collection = new Documents.AllDocs([{_id: 'testId1', 'value': 'one'}], opts);

      store.selectAllDocuments();
      assert.ok(store.getSelectedItems().testId1);
      store.toggleSelectAllDocuments();
      assert.equal(store.getSelectedItemsLength(), 0);
    });

    it('deselects all documents', function () {
      store.reset();
      store._collection = new Documents.AllDocs([{_id: 'testId1', 'value': 'one'}], opts);

      assert.equal(Object.keys(store.getSelectedItems()).length, 0);
      store.toggleSelectAllDocuments();
      assert.equal(store.getSelectedItemsLength(), 1);
    });
  });

  describe('#createBulkDeleteFromSelected', function () {

    it('correctly creates BulkDeleteDocCollection', function () {
      store._collection = new Documents.AllDocs([{_id: 'testId1'}, {_id: 'testId2'}], opts);

      store._bulkDeleteDocCollection = Documents.BulkDeleteDocCollection;

      store._selectedItems = {
        'testId1': true,
        'testId2': true
      };

      var bulkDelete = store.createBulkDeleteFromSelected();

      assert.equal(bulkDelete.length, 2);
      assert.ok(bulkDelete.at(0).get('_deleted'));
    });
  });

  it('tries to guess a pseudo schema for table views', function () {
    var doclist = [
      {_id: 'testId1', value: 'one'},
      {_id: 'testId2', foo: 'one'},
      {_id: 'testId3', bar: 'one'},
    ];

    var schema = store.getPseudoSchema(doclist);

    assert.ok(schema.indexOf('_id') !== -1);
    assert.ok(schema.indexOf('value') !== -1);
    assert.ok(schema.indexOf('foo') !== -1);
    assert.ok(schema.indexOf('bar') !== -1);
  });

  it('uses unique values for the pseudo schema', function () {
    var doclist = [
      {_id: 'testId1', foo: 'one'},
      {_id: 'testId2', foo: 'one'}
    ];

    var schema = store.getPseudoSchema(doclist);

    assert.equal(schema.length, 2);
    assert.equal(schema.length, 2);
    assert.ok(schema.indexOf('foo') !== -1);
    assert.ok(schema.indexOf('_id') !== -1);
  });

  it('puts the id into the array as first element', function () {
    var doclist = [
      {foo: 'one', _id: 'testId1'},
      {foo: 'one', _id: 'testId2'}
    ];

    var schema = store.getPseudoSchema(doclist);

    assert.equal(schema.shift(), '_id');
  });

  it('normalizes different content from include_docs enabled', function () {
    var doclist = [
      {_id: 'testId2', foo: 'one', doc: {"_rev": "1", "ente": "gans", "fuchs": "hase"}},
      {_id: 'testId3', foo: 'two', doc: {"_rev": "2", "haus": "blau", "tanne": "acht"}}
    ];

    var res = store.normalizeTableData(doclist);
    assert.deepEqual(res[0], {"_rev": "1", "ente": "gans", "fuchs": "hase"});
  });

  it('normalizes different content from include_docs disabled', function () {
    var doclist = [
      {id: 'testId2', foo: 'one'},
      {id: 'testId3', foo: 'two'}
    ];

    var res = store.normalizeTableData(doclist);
    assert.deepEqual(doclist, res);
  });

  it('finds out if we have at least one editable/deleteable doc which needs an id', function () {
    var doclist = [
      {id: 'testId2', foo: 'one'},
      {id: 'testId3', foo: 'two'}
    ];

    assert.ok(store.getHasEditableAndDeletableDoc(doclist));

    doclist = [
      {foo: 'one'},
      {foo: 'two'}
    ];

    assert.notOk(store.getHasEditableAndDeletableDoc(doclist));
  });

  describe('#getMangoDoc', function () {
    beforeEach(function () {
      store = new Stores.IndexResultsStore();
      dispatchToken = FauxtonAPI.dispatcher.register(store.dispatch);
      opts = {
        params: {},
        database: {
          safeID: function () { return '1';}
        }
      };
    });

    var fakeMango = {
      ddoc: '_design/e4d338e5d6f047749f5399ab998b4fa04ba0c816',
      def: {
        fields: [
          {'_id': 'asc'},
          {'foo': 'bar'},
          {'ente': 'gans'}
        ]
      },
      name: 'e4d338e5d6f047749f5399ab998b4fa04ba0c816',
      type: 'json'
    };

    it('creates a special id from the header fields', function () {
      var doc = new Documents.MangoIndex(fakeMango, opts);
      assert.equal(store.getMangoDoc(doc).header, 'json: _id, foo, ente');
    });

    it('supports custom header fields', function () {
      FauxtonAPI.registerExtension('mango:additionalIndexes', {
        createHeader: function (doc) {
          return ['foobar'];
        }
      });

      var doc = new Documents.MangoIndex({
        ddoc: '_design/e4d338e5d6f047749f5399ab998b4fa04ba0c816',
        def: {
          fields: []
        },
        name: 'e4d338e5d6f047749f5399ab998b4fa04ba0c816',
        type: 'json'
      }, opts);
      assert.equal(store.getMangoDoc(doc).header, 'foobar');
    });

    it('removes the name and ddoc field', function () {
      var doc = new Documents.MangoIndex(fakeMango, opts);
      assert.ok(doc.get('name'));
      assert.ok(doc.get('ddoc'));

      store._allCollapsed = false;
      var newDoc = store.getMangoDoc(doc);
      assert.notOk(JSON.parse(newDoc.content).name);
      assert.notOk(JSON.parse(newDoc.content).ddoc);
      assert.ok(JSON.parse(newDoc.content).type);
    });
  });

  describe('#getDocId', function () {

    it('returns id if it exists', function () {
      var doc = new Documents.Doc({
        _id: 'doc-id'
      }, opts);

      assert.equal(store.getDocId(doc), 'doc-id');

    });

    it('returns key if it exists', function () {
      var doc = new Documents.Doc({
        key: 'doc-key'
      }, opts);

      assert.equal(store.getDocId(doc), 'doc-key');

    });

    it('returns empty string if no key or id exists', function () {
      var doc = new Documents.Doc({
        key: null,
        value: 'the-value'
      }, opts);

      assert.equal(store.getDocId(doc), '');

    });
  });

  describe('isEditable', function () {
    store = new Stores.IndexResultsStore();

    it('returns false for no collection', function () {
      store._collection = null;
      assert.notOk(store.isEditable());
    });

    it('returns false for empty collection', function () {
      store._collection = [];
      assert.notOk(store.isEditable());
    });

    it('delegates to collection', function () {
      store._collection = {
        attributes: {
          fields: ["foo"]
        }
      };
      store._collection.isEditable = function () { return {'stub': true}; };
      assert.deepEqual(store.isEditable(), {'stub': true});
      store._collection = {};
    });

    it('retuns false for ghost-docs that are filtered away', function () {
      store._collection = {};
      assert.equal(store.isEditable({}), false);
    });
  });

  describe('isDeletable', function () {
    store = new Stores.IndexResultsStore();

    it('retuns false for ghost-docs that are filtered away', function () {
      assert.equal(store.isDeletable({}), false);
    });
  });
});
<commit_msg>move tests into describe block<commit_after>// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.

define([
  'api',
  'addons/documents/index-results/stores',
  'addons/documents/index-results/actiontypes',
  'addons/documents/shared-resources',
  'testUtils'
], function (FauxtonAPI, Stores, ActionTypes, Documents, testUtils) {
  var assert = testUtils.assert;
  var dispatchToken;
  var store;
  var opts;

  describe('Index Results Store', function () {
    beforeEach(function () {
      store = new Stores.IndexResultsStore();
      dispatchToken = FauxtonAPI.dispatcher.register(store.dispatch);
      store.reset();
      opts = {
        params: {limit: 10, skip: 0},
        database: {
          safeID: function () { return '1';}
        }
      };
    });

    afterEach(function () {
      FauxtonAPI.dispatcher.unregister(dispatchToken);
    });

    it('hasResults returns true for collection', function () {
      store._collection = [1, 2, 3];

      assert.ok(store.hasResults());
    });

    it('hasResults returns false for empty collection', function () {
      store._collection = [];

      assert.notOk(store.hasResults());
    });

    it('getResults has correct doc format', function () {
      store._collection = new Documents.AllDocs([{_id: 'testId'}], opts);

      var doc = store.getResults().results[0];
      assert.equal(doc.id, 'testId');
      assert.equal(doc.keylabel, 'id');
    });

    it('tries to guess a pseudo schema for table views', function () {
      var doclist = [
        {_id: 'testId1', value: 'one'},
        {_id: 'testId2', foo: 'one'},
        {_id: 'testId3', bar: 'one'},
      ];

      var schema = store.getPseudoSchema(doclist);

      assert.ok(schema.indexOf('_id') !== -1);
      assert.ok(schema.indexOf('value') !== -1);
      assert.ok(schema.indexOf('foo') !== -1);
      assert.ok(schema.indexOf('bar') !== -1);
    });

    it('uses unique values for the pseudo schema', function () {
      var doclist = [
        {_id: 'testId1', foo: 'one'},
        {_id: 'testId2', foo: 'one'}
      ];

      var schema = store.getPseudoSchema(doclist);

      assert.equal(schema.length, 2);
      assert.equal(schema.length, 2);
      assert.ok(schema.indexOf('foo') !== -1);
      assert.ok(schema.indexOf('_id') !== -1);
    });

    it('puts the id into the array as first element', function () {
      var doclist = [
        {foo: 'one', _id: 'testId1'},
        {foo: 'one', _id: 'testId2'}
      ];

      var schema = store.getPseudoSchema(doclist);

      assert.equal(schema.shift(), '_id');
    });

    it('normalizes different content from include_docs enabled', function () {
      var doclist = [
        {_id: 'testId2', foo: 'one', doc: {"_rev": "1", "ente": "gans", "fuchs": "hase"}},
        {_id: 'testId3', foo: 'two', doc: {"_rev": "2", "haus": "blau", "tanne": "acht"}}
      ];

      var res = store.normalizeTableData(doclist);
      assert.deepEqual(res[0], {"_rev": "1", "ente": "gans", "fuchs": "hase"});
    });

    it('normalizes different content from include_docs disabled', function () {
      var doclist = [
        {id: 'testId2', foo: 'one'},
        {id: 'testId3', foo: 'two'}
      ];

      var res = store.normalizeTableData(doclist);
      assert.deepEqual(doclist, res);
    });

    it('finds out if we have at least one editable/deleteable doc which needs an id', function () {
      var doclist = [
        {id: 'testId2', foo: 'one'},
        {id: 'testId3', foo: 'two'}
      ];

      assert.ok(store.getHasEditableAndDeletableDoc(doclist));

      doclist = [
        {foo: 'one'},
        {foo: 'two'}
      ];

      assert.notOk(store.getHasEditableAndDeletableDoc(doclist));
    });

  });

  describe('canSelectAll', function () {

    it('returns true for selected docs less than collection', function () {
      store._collection = new Documents.AllDocs([{_id: 'testId1'}, {_id: 'testId2'}], opts);

      store._selectedItems = {'testId1': true};
      assert.ok(store.canSelectAll());
    });

    it('returns false for selected docs same as collection', function () {
      store._collection = new Documents.AllDocs([{_id: 'testId1'}, {_id: 'testId2'}], opts);

      store._selectedItems = {
        'testId1': true,
        'testId2': true
      };

      assert.notOk(store.canSelectAll());
    });

    it('returns true even with _all_docs (mango)', function () {
      store._collection = new Documents.AllDocs([
        {_id: 'testId1'},
        {_id: 'testId2'},
        {_id: '_all_docs'}
      ], opts);

      store._selectedItems = {
        'testId1': true,
        'testId2': true
      };

      assert.notOk(store.canSelectAll());
    });
  });

  describe('canDeselectAll', function () {

    it('returns true for selected docs', function () {
      store._selectedItems = {'testId1': true};
      assert.ok(store.canDeselectAll());
    });

    it('returns false for no selected docs', function () {
      store._selectedItems = {};

      assert.notOk(store.canDeselectAll());
    });

  });

  describe('getDocContent', function () {

    it('returns full doc if not collapsed', function () {
      store._collection = new Documents.AllDocs([{_id: 'testId1', 'value': 'one'}], opts);

      var doc = store._collection.first();
      var result = store.getDocContent(doc);

      assert.equal(JSON.parse(result).value, 'one');
    });

    it('returns just the revision as content if collapsed', function () {
      store._collection = new Documents.AllDocs([{_id: 'testId1', _rev: 'a', 'value': 'one'}], opts);

      var doc = store._collection.first();
      store._allCollapsed = true;
      var result = store.getDocContent(doc);

      assert.deepEqual({"rev": "a"}, JSON.parse(result));
    });

  });

  describe('#selectDoc', function () {

    it('selects doc if not already selected', function () {
      store._selectedItems = {};
      store.selectDoc('id');
      assert.equal(store.getSelectedItemsLength(), 1);
    });

    it('deselects doc if already selected', function () {
      store._selectedItems = {'id': true};
      store.selectDoc('id');
      assert.equal(store.getSelectedItemsLength(), 0);
    });
  });

  describe('#selectAllDocuments', function () {

    it('selects all documents', function () {
      store._collection = new Documents.AllDocs([{_id: 'testId1', 'value': 'one'}], opts);

      store.selectAllDocuments();
      assert.ok(store.getSelectedItems().testId1);
    });

  });

  describe('toggleSelectAllDocuments', function () {

    it('deselects all documents', function () {
      store._collection = new Documents.AllDocs([{_id: 'testId1', 'value': 'one'}], opts);

      store.selectAllDocuments();
      assert.ok(store.getSelectedItems().testId1);
      store.toggleSelectAllDocuments();
      assert.equal(store.getSelectedItemsLength(), 0);
    });

    it('deselects all documents', function () {
      store.reset();
      store._collection = new Documents.AllDocs([{_id: 'testId1', 'value': 'one'}], opts);

      assert.equal(Object.keys(store.getSelectedItems()).length, 0);
      store.toggleSelectAllDocuments();
      assert.equal(store.getSelectedItemsLength(), 1);
    });
  });

  describe('#createBulkDeleteFromSelected', function () {

    it('correctly creates BulkDeleteDocCollection', function () {
      store._collection = new Documents.AllDocs([{_id: 'testId1'}, {_id: 'testId2'}], opts);

      store._bulkDeleteDocCollection = Documents.BulkDeleteDocCollection;

      store._selectedItems = {
        'testId1': true,
        'testId2': true
      };

      var bulkDelete = store.createBulkDeleteFromSelected();

      assert.equal(bulkDelete.length, 2);
      assert.ok(bulkDelete.at(0).get('_deleted'));
    });
  });

  describe('#getMangoDoc', function () {
    beforeEach(function () {
      store = new Stores.IndexResultsStore();
      dispatchToken = FauxtonAPI.dispatcher.register(store.dispatch);
      opts = {
        params: {},
        database: {
          safeID: function () { return '1';}
        }
      };
    });

    var fakeMango = {
      ddoc: '_design/e4d338e5d6f047749f5399ab998b4fa04ba0c816',
      def: {
        fields: [
          {'_id': 'asc'},
          {'foo': 'bar'},
          {'ente': 'gans'}
        ]
      },
      name: 'e4d338e5d6f047749f5399ab998b4fa04ba0c816',
      type: 'json'
    };

    it('creates a special id from the header fields', function () {
      var doc = new Documents.MangoIndex(fakeMango, opts);
      assert.equal(store.getMangoDoc(doc).header, 'json: _id, foo, ente');
    });

    it('supports custom header fields', function () {
      FauxtonAPI.registerExtension('mango:additionalIndexes', {
        createHeader: function (doc) {
          return ['foobar'];
        }
      });

      var doc = new Documents.MangoIndex({
        ddoc: '_design/e4d338e5d6f047749f5399ab998b4fa04ba0c816',
        def: {
          fields: []
        },
        name: 'e4d338e5d6f047749f5399ab998b4fa04ba0c816',
        type: 'json'
      }, opts);
      assert.equal(store.getMangoDoc(doc).header, 'foobar');
    });

    it('removes the name and ddoc field', function () {
      var doc = new Documents.MangoIndex(fakeMango, opts);
      assert.ok(doc.get('name'));
      assert.ok(doc.get('ddoc'));

      store._allCollapsed = false;
      var newDoc = store.getMangoDoc(doc);
      assert.notOk(JSON.parse(newDoc.content).name);
      assert.notOk(JSON.parse(newDoc.content).ddoc);
      assert.ok(JSON.parse(newDoc.content).type);
    });
  });

  describe('#getDocId', function () {

    it('returns id if it exists', function () {
      var doc = new Documents.Doc({
        _id: 'doc-id'
      }, opts);

      assert.equal(store.getDocId(doc), 'doc-id');

    });

    it('returns key if it exists', function () {
      var doc = new Documents.Doc({
        key: 'doc-key'
      }, opts);

      assert.equal(store.getDocId(doc), 'doc-key');

    });

    it('returns empty string if no key or id exists', function () {
      var doc = new Documents.Doc({
        key: null,
        value: 'the-value'
      }, opts);

      assert.equal(store.getDocId(doc), '');

    });
  });

  describe('isEditable', function () {
    store = new Stores.IndexResultsStore();

    it('returns false for no collection', function () {
      store._collection = null;
      assert.notOk(store.isEditable());
    });

    it('returns false for empty collection', function () {
      store._collection = [];
      assert.notOk(store.isEditable());
    });

    it('delegates to collection', function () {
      store._collection = {
        attributes: {
          fields: ["foo"]
        }
      };
      store._collection.isEditable = function () { return {'stub': true}; };
      assert.deepEqual(store.isEditable(), {'stub': true});
      store._collection = {};
    });

    it('retuns false for ghost-docs that are filtered away', function () {
      store._collection = {};
      assert.equal(store.isEditable({}), false);
    });
  });

  describe('isDeletable', function () {
    store = new Stores.IndexResultsStore();

    it('retuns false for ghost-docs that are filtered away', function () {
      assert.equal(store.isDeletable({}), false);
    });
  });
});
<|endoftext|>


<commit_before>'use strict';

import noble from 'noble';
import Promise from 'es6-promises';

let peripheralsIn = {};
let isScanning = false;
let isMonitoring = false;

/**
 * Associate the given in-Node object with the BLE module.
 * @param n the in-Node object to be registered as a BLE node
 * @param categoryName the category name
 * @param address the ble address delimited by '-'
 * @param uuid the ble identifier (optional)
 * @param parse the parse function
 * @param useString whether or not to use String type rather than JSON object as the payload format
 * @param RED the initialized RED object
 * @return void (sync)
 */
export function registerIn(n, categoryName, address, uuid, parse, useString, RED) {
  if (!n || !categoryName || !address || !parse) {
    throw new Error('Invalid node!');
  }
  if (!RED) {
    throw new Error('RED is required!!');
  }
  let category = peripheralsIn[categoryName];
  if (!category) {
    category = {};
    peripheralsIn[categoryName] = category;
  }
  let ary = [];
  if (address in category) {
    ary = category[address];
    ary = ary.filter(ele => {
      if (RED.nodes.getNode(ele.id)) {
        return (ele.id !== n.id);
      }
      return false;
    });
  }
  ary.push({
    id: n.id,
    parse: parse,
    useString: useString
  });
  category[address] = ary;
  if (uuid) {
    category[uuid] = category[address];
    RED.log.info(`[BLE] category=[${categoryName}], address=[${address}], uuid=[${uuid}], node ID=[${n.id}] has been registered.`);
  } else {
    RED.log.info(`[BLE] category=[${categoryName}], address=[${address}], node ID=[${n.id}] has been registered.`);
  }
}

/**
 * Start the BLE module.
 * @param RED the initialized RED object
 * @return Promise
 */
export function start(RED) {
  if (!RED) {
    throw new Error('RED is required!');
  }
  return new Promise((resolve, reject) => {
    if (isScanning) {
      resolve();
      return;
    }
    noble.on('stateChange', state => {
      if (state === 'poweredOn') {
        RED.log.info('[BLE] Start Scanning...');
        noble.startScanning([], true);
        isScanning = true;
        resolve();
      } else {
        noble.stopScanning();
        isScanning = false;
        reject();
      }
    });
    if (noble.state === 'poweredOn') {
      RED.log.info('[BLE] Start Scanning...');
      noble.startScanning([], true);
      isScanning = true;
      resolve();
    }
  }).then(() => {
    return new Promise((resolve, reject) => {
      if (isMonitoring) {
        resolve();
        return;
      }
      isMonitoring = true;
      noble.on('discover', peripheral => {
        let adv = peripheral.advertisement;
        if (!adv.localName) {
          return;
        }
        // Remove a NULL terminator
        let categoryName = adv.localName.replace(new RegExp('\0', 'g'), '');
        // look up a category by the category name
        let category = peripheralsIn[categoryName];
        if (!category) {
          RED.log.warn(`[BLE] Unknown peripheral: category=[${categoryName}], peripheral.address=[${peripheral.address}], peripheral.uuid=[${peripheral.uuid}]`);
          return;
        }
        // check if the peripheral.address matches
        let address = peripheral.address;
        let uuid = null;
        let bleNodes = null;
        if (address === 'unknown') {
          uuid = peripheral.uuid;
          bleNodes = category[uuid];
          if (!bleNodes || bleNodes.length === 0) {
            RED.log.warn(`[BLE] Unknown node: category=[${categoryName}], uuid=[${uuid}]`);
            return;
          }
        }
        if (!uuid) {
          if (address.indexOf('-') >= 0) {
            address = address.replace(new RegExp('-', 'g'), ':');
          }
          bleNodes = category[address];
          if (!bleNodes || bleNodes.length === 0) {
            RED.log.warn(`[BLE] Unknown node: category=[${categoryName}], address=[${address}]`);
            return;
          }
        }
        // send the ble node a payload if the address exists
        let removed = false;
        bleNodes = bleNodes.filter(ele => {
          let node = RED.nodes.getNode(ele.id);
          if (!node) {
            removed = true;
            return false;
          }
          let data = ele.parse(adv.manufacturerData);
          let payload = {
            data: data,
            tstamp: Date.now(),
            rssi: peripheral.rssi,
            address: address
          };
          if (uuid) {
            payload.uuid = uuid;
          }
          if (ele.useString) {
            payload = JSON.stringify(payload);
          }
          node.send({'payload': payload});
          return true;
        });
        if (removed) {
          category[uuid] = bleNodes;
          if (address !== 'unknown') {
            category[address] = bleNodes;
          }
        }
      });
      resolve();
      RED.log.info('[BLE] Set up done.');
    });
  });
}

/**
 * Stop the BLE module immediately.
 * @param RED the initialized RED object
 * @return void (sync)
 */
export function stop(RED) {
  noble.stopScanning();
  isScanning = false;
  RED.log.info('[BLE] Stop scanning.');
}
<commit_msg>Remove unused argument<commit_after>'use strict';

import noble from 'noble';
import Promise from 'es6-promises';

let peripheralsIn = {};
let isScanning = false;
let isMonitoring = false;

/**
 * Associate the given in-Node object with the BLE module.
 * @param n the in-Node object to be registered as a BLE node
 * @param categoryName the category name
 * @param address the ble address delimited by '-'
 * @param uuid the ble identifier (optional)
 * @param parse the parse function
 * @param useString whether or not to use String type rather than JSON object as the payload format
 * @param RED the initialized RED object
 * @return void (sync)
 */
export function registerIn(n, categoryName, address, uuid, parse, useString, RED) {
  if (!n || !categoryName || !address || !parse) {
    throw new Error('Invalid node!');
  }
  if (!RED) {
    throw new Error('RED is required!!');
  }
  let category = peripheralsIn[categoryName];
  if (!category) {
    category = {};
    peripheralsIn[categoryName] = category;
  }
  let ary = [];
  if (address in category) {
    ary = category[address];
    ary = ary.filter(ele => {
      if (RED.nodes.getNode(ele.id)) {
        return (ele.id !== n.id);
      }
      return false;
    });
  }
  ary.push({
    id: n.id,
    parse: parse,
    useString: useString
  });
  category[address] = ary;
  if (uuid) {
    category[uuid] = category[address];
    RED.log.info(`[BLE] category=[${categoryName}], address=[${address}], uuid=[${uuid}], node ID=[${n.id}] has been registered.`);
  } else {
    RED.log.info(`[BLE] category=[${categoryName}], address=[${address}], node ID=[${n.id}] has been registered.`);
  }
}

/**
 * Start the BLE module.
 * @param RED the initialized RED object
 * @return Promise
 */
export function start(RED) {
  if (!RED) {
    throw new Error('RED is required!');
  }
  return new Promise((resolve, reject) => {
    if (isScanning) {
      resolve();
      return;
    }
    noble.on('stateChange', state => {
      if (state === 'poweredOn') {
        RED.log.info('[BLE] Start Scanning...');
        noble.startScanning([], true);
        isScanning = true;
        resolve();
      } else {
        noble.stopScanning();
        isScanning = false;
        reject();
      }
    });
    if (noble.state === 'poweredOn') {
      RED.log.info('[BLE] Start Scanning...');
      noble.startScanning([], true);
      isScanning = true;
      resolve();
    }
  }).then(() => {
    return new Promise(resolve => {
      if (isMonitoring) {
        resolve();
        return;
      }
      isMonitoring = true;
      noble.on('discover', peripheral => {
        let adv = peripheral.advertisement;
        if (!adv.localName) {
          return;
        }
        // Remove a NULL terminator
        let categoryName = adv.localName.replace(new RegExp('\0', 'g'), '');
        // look up a category by the category name
        let category = peripheralsIn[categoryName];
        if (!category) {
          RED.log.warn(`[BLE] Unknown peripheral: category=[${categoryName}], peripheral.address=[${peripheral.address}], peripheral.uuid=[${peripheral.uuid}]`);
          return;
        }
        // check if the peripheral.address matches
        let address = peripheral.address;
        let uuid = null;
        let bleNodes = null;
        if (address === 'unknown') {
          uuid = peripheral.uuid;
          bleNodes = category[uuid];
          if (!bleNodes || bleNodes.length === 0) {
            RED.log.warn(`[BLE] Unknown node: category=[${categoryName}], uuid=[${uuid}]`);
            return;
          }
        }
        if (!uuid) {
          if (address.indexOf('-') >= 0) {
            address = address.replace(new RegExp('-', 'g'), ':');
          }
          bleNodes = category[address];
          if (!bleNodes || bleNodes.length === 0) {
            RED.log.warn(`[BLE] Unknown node: category=[${categoryName}], address=[${address}]`);
            return;
          }
        }
        // send the ble node a payload if the address exists
        let removed = false;
        bleNodes = bleNodes.filter(ele => {
          let node = RED.nodes.getNode(ele.id);
          if (!node) {
            removed = true;
            return false;
          }
          let data = ele.parse(adv.manufacturerData);
          let payload = {
            data: data,
            tstamp: Date.now(),
            rssi: peripheral.rssi,
            address: address
          };
          if (uuid) {
            payload.uuid = uuid;
          }
          if (ele.useString) {
            payload = JSON.stringify(payload);
          }
          node.send({'payload': payload});
          return true;
        });
        if (removed) {
          category[uuid] = bleNodes;
          if (address !== 'unknown') {
            category[address] = bleNodes;
          }
        }
      });
      resolve();
      RED.log.info('[BLE] Set up done.');
    });
  });
}

/**
 * Stop the BLE module immediately.
 * @param RED the initialized RED object
 * @return void (sync)
 */
export function stop(RED) {
  noble.stopScanning();
  isScanning = false;
  RED.log.info('[BLE] Stop scanning.');
}
<|endoftext|>


<commit_before>
/**
 * Module dependencies.
 */

var Like = require('./like');
var Reblog = require('./reblog');
var Comment = require('./comment');
var debug = require('debug')('wpcom:post');

/**
 * Post methods
 *
 * @param {String} id
 * @param {String} sid site id
 * @param {WPCOM} wpcom
 * @api public
 */

function Post(id, sid, wpcom) {
  if (!(this instanceof Post)) {
    return new Post(id, sid, wpcom);
  }

  this.wpcom = wpcom;
  this._sid = sid;

  // set `id` and/or `slug` properties
  id = id || {};
  if ('object' !== typeof id) {
    this._id = id;
  } else {
    this._id = id.id;
    this._slug = id.slug;
  }
}

/**
 * Set post `id`
 *
 * @param {String} id
 * @api public
 */

Post.prototype.id = function (id) {
  this._id = id;
};

/**
 * Set post `slug`
 *
 * @param {String} slug
 * @api public
 */

Post.prototype.slug = function (slug) {
  this._slug = slug;
};

/**
 * Get post
 *
 * @param {Object} [query]
 * @param {Function} fn
 * @api public
 */

Post.prototype.get = function (query, fn) {
  if (!this._id && this._slug) {
    return this.getBySlug(query, fn);
  }

  var path = '/sites/' + this._sid + '/posts/' + this._id;
  return this.wpcom.req.get(path, query, fn);
};

/**
 * Get post by slug
 *
 * @param {Object} [query]
 * @param {Function} fn
 * @api public
 */

Post.prototype.getBySlug = function (query, fn) {
  var path = '/sites/' + this._sid + '/posts/slug:' + this._slug;
  return this.wpcom.req.get(path, query, fn);
};

/**
 * Add post
 *
 * @param {Object} [query]
 * @param {Object} body
 * @param {Function} fn
 * @api public
 */

Post.prototype.add = function (query, body, fn) {
  if ('function' === typeof body) {
    fn = body;
    body = query;
    query = {};
  }

  var path = '/sites/' + this._sid + '/posts/new';
  return this.wpcom.req.post(path, query, body, function (err, data) {
    if (err) {
      return fn(err);
    }

    // update POST object
    this._id = data.ID;
    debug('Set post _id: %s', this._id);

    this._slug = data.slug;
    debug('Set post _slug: %s', this._slug);

    fn(null, data)
  }.bind(this));
};

/**
 * Edit post
 *
 * @param {Object} [query]
 * @param {Object} body
 * @param {Function} fn
 * @api public
 */

Post.prototype.update = function (query, body, fn) {
  var path = '/sites/' + this._sid + '/posts/' + this._id;
  return this.wpcom.req.put(path, query, body, fn);
};

/**
 * Delete post
 *
 * @param {Object} [query]
 * @param {Function} fn
 * @api public
 */

Post.prototype['delete'] =
Post.prototype.del = function (query, fn) {
  var path = '/sites/' + this._sid + '/posts/' + this._id + '/delete';
  return this.wpcom.req.del(path, query, fn);
};

/**
 * Restore post
 *
 * @param {Object} [query]
 * @param {Function} fn
 * @api public
 */

Post.prototype.restore = function (query, fn) {
  var path = '/sites/' + this._sid + '/posts/' + this._id + '/restore';
  return this.wpcom.req.put(path, query, null, fn);
};

/**
 * Get post likes list
 *
 * @param {Object} [query]
 * @param {Function} fn
 * @api public
 */

Post.prototype.likesList = function (query, fn) {
  var path = '/sites/' + this._sid + '/posts/' + this._id + '/likes';
  return this.wpcom.req.get(path, query, fn);
};

/**
 * Search within a site for related posts
 *
 * @param {Object} [query]
 * @param {Object} body
 * @param {Function} fn
 * @api public
 */

Post.prototype.related = function (body, fn) {
  var path = '/sites/' + this._sid + '/posts/' + this._id + '/related';
  return this.wpcom.req.put(path, query, null, fn);
};

/**
 * Create a `Like` instance
 *
 * @api public
 */

Post.prototype.like = function () {
  return new Like(this._id, this._sid, this.wpcom);
};

/**
 * Create a `Reblog` instance
 *
 * @api public
 */

Post.prototype.reblog = function () {
  return new Reblog(this._id, this._sid, this.wpcom);
};

/**
 * Create a `Comment` instance
 *
 * @param {String} [cid] comment id
 * @api public
 */

Post.prototype.comment = function (cid) {
  return new Comment(cid, this._id, this._sid, this.wpcom);
};

/**
 * Return recent comments
 *
 * @param {Object} [query]
 * @param {String} id
 * @api public
 */

Post.prototype.comments = function (query, fn) {
  var comment = new Comment(null, this._id, this._sid, this.wpcom);
  comment.replies(query, fn);
  return comment;
};

/**
 * Expose `Post` module
 */

module.exports = Post;<commit_msg>Fix Post#related parameters<commit_after>
/**
 * Module dependencies.
 */

var Like = require('./like');
var Reblog = require('./reblog');
var Comment = require('./comment');
var debug = require('debug')('wpcom:post');

/**
 * Post methods
 *
 * @param {String} id
 * @param {String} sid site id
 * @param {WPCOM} wpcom
 * @api public
 */

function Post(id, sid, wpcom) {
  if (!(this instanceof Post)) {
    return new Post(id, sid, wpcom);
  }

  this.wpcom = wpcom;
  this._sid = sid;

  // set `id` and/or `slug` properties
  id = id || {};
  if ('object' !== typeof id) {
    this._id = id;
  } else {
    this._id = id.id;
    this._slug = id.slug;
  }
}

/**
 * Set post `id`
 *
 * @param {String} id
 * @api public
 */

Post.prototype.id = function (id) {
  this._id = id;
};

/**
 * Set post `slug`
 *
 * @param {String} slug
 * @api public
 */

Post.prototype.slug = function (slug) {
  this._slug = slug;
};

/**
 * Get post
 *
 * @param {Object} [query]
 * @param {Function} fn
 * @api public
 */

Post.prototype.get = function (query, fn) {
  if (!this._id && this._slug) {
    return this.getBySlug(query, fn);
  }

  var path = '/sites/' + this._sid + '/posts/' + this._id;
  return this.wpcom.req.get(path, query, fn);
};

/**
 * Get post by slug
 *
 * @param {Object} [query]
 * @param {Function} fn
 * @api public
 */

Post.prototype.getBySlug = function (query, fn) {
  var path = '/sites/' + this._sid + '/posts/slug:' + this._slug;
  return this.wpcom.req.get(path, query, fn);
};

/**
 * Add post
 *
 * @param {Object} [query]
 * @param {Object} body
 * @param {Function} fn
 * @api public
 */

Post.prototype.add = function (query, body, fn) {
  if ('function' === typeof body) {
    fn = body;
    body = query;
    query = {};
  }

  var path = '/sites/' + this._sid + '/posts/new';
  return this.wpcom.req.post(path, query, body, function (err, data) {
    if (err) {
      return fn(err);
    }

    // update POST object
    this._id = data.ID;
    debug('Set post _id: %s', this._id);

    this._slug = data.slug;
    debug('Set post _slug: %s', this._slug);

    fn(null, data)
  }.bind(this));
};

/**
 * Edit post
 *
 * @param {Object} [query]
 * @param {Object} body
 * @param {Function} fn
 * @api public
 */

Post.prototype.update = function (query, body, fn) {
  var path = '/sites/' + this._sid + '/posts/' + this._id;
  return this.wpcom.req.put(path, query, body, fn);
};

/**
 * Delete post
 *
 * @param {Object} [query]
 * @param {Function} fn
 * @api public
 */

Post.prototype['delete'] =
Post.prototype.del = function (query, fn) {
  var path = '/sites/' + this._sid + '/posts/' + this._id + '/delete';
  return this.wpcom.req.del(path, query, fn);
};

/**
 * Restore post
 *
 * @param {Object} [query]
 * @param {Function} fn
 * @api public
 */

Post.prototype.restore = function (query, fn) {
  var path = '/sites/' + this._sid + '/posts/' + this._id + '/restore';
  return this.wpcom.req.put(path, query, null, fn);
};

/**
 * Get post likes list
 *
 * @param {Object} [query]
 * @param {Function} fn
 * @api public
 */

Post.prototype.likesList = function (query, fn) {
  var path = '/sites/' + this._sid + '/posts/' + this._id + '/likes';
  return this.wpcom.req.get(path, query, fn);
};

/**
 * Search within a site for related posts
 *
 * @param {Object} body
 * @param {Function} fn
 * @api public
 */

Post.prototype.related = function (body, fn) {
  var path = '/sites/' + this._sid + '/posts/' + this._id + '/related';
  return this.wpcom.req.put(path, body, null, fn);
};

/**
 * Create a `Like` instance
 *
 * @api public
 */

Post.prototype.like = function () {
  return new Like(this._id, this._sid, this.wpcom);
};

/**
 * Create a `Reblog` instance
 *
 * @api public
 */

Post.prototype.reblog = function () {
  return new Reblog(this._id, this._sid, this.wpcom);
};

/**
 * Create a `Comment` instance
 *
 * @param {String} [cid] comment id
 * @api public
 */

Post.prototype.comment = function (cid) {
  return new Comment(cid, this._id, this._sid, this.wpcom);
};

/**
 * Return recent comments
 *
 * @param {Object} [query]
 * @param {String} id
 * @api public
 */

Post.prototype.comments = function (query, fn) {
  var comment = new Comment(null, this._id, this._sid, this.wpcom);
  comment.replies(query, fn);
  return comment;
};

/**
 * Expose `Post` module
 */

module.exports = Post;<|endoftext|>


<commit_before>'use strict'

const TelegramBot = require('node-telegram-bot-api')
const bot = new TelegramBot(process.env.TELEGRAM_API_TOKEN, {polling: true})

const flickrHandler = require('./flickrHandler')
const ForecastHandler = require('./forecastHandler')
const forecastHandler = new ForecastHandler(onKpAlert)

const PHOTO_COMMAND = '🌌 Aurora photo'
const VISIBILITY_COMMAND = '🔎  Visibility'
const SCHEDULE_ALERT_COMMAND = '🔔 Schedule alert'
const CANCEL_ALERT_COMMAND = '🔕 Unschedule alert'
const LIVE_PHOTO_COMMAND = '📷 Live photo'
const KP_PHOTO = 'https://www.whelancameras.ie/image/data/Article/image%202.jpg'

const FINLAND_OPTION_CAM = '🇫🇮 Finland'
const SWEDEN_OPTION_CAM = '🇸🇪 Sweden'
const NORWAY_OPTION_CAM = '🇳🇴 Norway'

const options = {
    reply_markup: JSON.stringify({
        one_time_keyboard: true,
        keyboard: [
            [{text: PHOTO_COMMAND}, {text: VISIBILITY_COMMAND}],
            [{text: SCHEDULE_ALERT_COMMAND}, {text: CANCEL_ALERT_COMMAND}],
            [{text: LIVE_PHOTO_COMMAND}]
        ]
    })
}

const camOptions = {
    reply_markup: JSON.stringify({
        one_time_keyboard: true,
        keyboard: [
            [{text: FINLAND_OPTION_CAM}],
            [{text: NORWAY_OPTION_CAM}],
            [{text: SWEDEN_OPTION_CAM}]
        ]
    })
}

const kpOptions = {
    reply_markup: JSON.stringify({
        one_time_keyboard: true,
        keyboard: [
            [{ text: '1' }, { text: '2' }, { text: '3'}],
            [{ text: '4' }, { text: '5' }, { text: '6'}],
            [{ text: '7' }, { text: '8' }]
        ]
    })
}

var alertInput = false
var camInput = false

// Event handling

bot.onText(new RegExp(LIVE_PHOTO_COMMAND), msg => {
    invalidateInputs()
    console.info(`[MSG] Live photo request from ${msg.from.first_name}`)
    const text = 'Choose a cam from one of these regions:'
    bot.sendMessage(msg.from.id, text, camOptions)
    camInput = true
})

bot.onText(new RegExp(VISIBILITY_COMMAND), msg => {
    console.info(`[MSG] Visibility check from ${msg.from.first_name}`)
    bot.sendPhoto(msg.from.id, KP_PHOTO).then(() => {
        const forecast = forecastHandler.getForecast()
        const arrowDown = '🔻'
        const arrowUp = '🔺'
        var text = `Current Kp index is ${forecast.nextH}`
        if (forecast.next4H == forecast.nextH) {
            text += ' without major changes within the next 4h.'
        } else if (forecast.next4H < forecast.nextH) {
            text += ` and within the next 4h it will decrease to ${forecast.next4H} ${arrowDown}.`
        } else {
            text += ` and within the next 4h it will increase to ${forecast.next4H} ${arrowUp}.`
        }
        bot.sendMessage(msg.from.id, text, options)
    })
})

bot.onText(new RegExp(PHOTO_COMMAND), msg => {
    console.info(`[MSG] Send photo to ${msg.from.first_name}`)
    bot.sendChatAction(msg.from.id, 'typing').then(() => {
        return flickrHandler.fetchRandomPhoto()
    }).then(result => {
        console.log(`Sent photo by ${result.owner} to ${msg.from.first_name}`)
        bot.sendPhoto(msg.from.id, result.photo).then(() => {
            bot.sendMessage(msg.from.id, `A gorgeous photo by ${result.owner}.`, options)
        })
    })
})

bot.onText(new RegExp(CANCEL_ALERT_COMMAND), msg => {
    console.info(`[MSG] Cancel alert from ${msg.from.first_name}`)
    const text = `Ok ${msg.from.first_name}, I won't be sending you any more alerts!`
    bot.sendMessage(msg.from.id, text, options)
    forecastHandler.deregisterFromAlerts(msg.from.id)
})

bot.onText(new RegExp(SCHEDULE_ALERT_COMMAND), msg => {
    invalidateInputs()
    console.info(`[MSG] Schedule alert for ${msg.from.first_name}`)
    bot.sendPhoto(msg.from.id, KP_PHOTO).then(() => {
        const text = 'Choose which Kp index you\'d like to be informed about:'
        bot.sendMessage(msg.from.id, text, kpOptions)
        alertInput = true
    })
})

bot.onText(/\/start/, (msg, match) => {
    console.info(`[MSG] /start from ${msg.from.first_name}`)
    const text = `Hey ${msg.from.first_name}! What would you like to do?`
    bot.sendMessage(msg.from.id, text, options)
})

bot.on('message', msg => {
    if (alertInput) {
        alertInput = false
        const value = parseInt(msg.text)
        if (value > 0 && value <= 8) {
            forecastHandler.registerForAlerts(msg.from.first_name, msg.from.id, value)
            const text = `Ok, ${msg.from.first_name}, I will alert you when Kp reaches ${value}.`
            return bot.sendMessage(msg.from.id, text, options)
        }
        sendUnrecognizedMessage(msg.from.id)
    } else if (camInput) {
        camInput = false
        const photos = getLivePhotos()
        if (photos[msg.text]) {
            return bot.sendPhoto(msg.from.id, photos[msg.text].url).then(() => {
                const text = `Here's a photo from ${photos[msg.text].location}.`
                bot.sendMessage(msg.from.id, text, options)
            })
        }
        return sendUnrecognizedMessage(msg.from.id)
    }
})

// Helper functions

function invalidateInputs() {
    alertInput = false
    camInput = false
}

function getLivePhotos() {
    var dict = {}
    dict[SWEDEN_OPTION_CAM] = {url: 'http://uk.jokkmokk.jp/photo/nr3/latest.jpg', location: 'Porjus, Jokkmokk, Sweden'}
    dict[FINLAND_OPTION_CAM] = {url: 'http://aurora.fmi.fi/public_service/latest_DYN.jpg', location: 'Helsinki, Finland'}
    dict[NORWAY_OPTION_CAM] = {url: 'http://polaris.nipr.ac.jp/~acaurora/aurora/Tromso/latest.jpg', location: 'Tromsø, Norway'}
    return dict
}

function sendUnrecognizedMessage(chatId) {
    const text = 'Unrecognized answer. Please choose what you\'d like to do:'
    bot.sendMessage(chatId, text, options)
}

function onKpAlert(chats, kp) {
    chats.forEach(chat => {
        console.info(`[MSG] Send alert to ${chat.user}`)
        const text = `⚠ Alert! ⚠ Alert! Current Kp is ${kp}!`
        bot.sendMessage(chat.chatId, text)
    })
}<commit_msg>prevent caching of live photos<commit_after>'use strict'

const TelegramBot = require('node-telegram-bot-api')
const bot = new TelegramBot(process.env.TELEGRAM_API_TOKEN, {polling: true})

const flickrHandler = require('./flickrHandler')
const ForecastHandler = require('./forecastHandler')
const forecastHandler = new ForecastHandler(onKpAlert)

const PHOTO_COMMAND = '🌌 Aurora photo'
const VISIBILITY_COMMAND = '🔎  Visibility'
const SCHEDULE_ALERT_COMMAND = '🔔 Schedule alert'
const CANCEL_ALERT_COMMAND = '🔕 Unschedule alert'
const LIVE_PHOTO_COMMAND = '📷 Live photo'
const KP_PHOTO = 'https://www.whelancameras.ie/image/data/Article/image%202.jpg'

const FINLAND_OPTION_CAM = '🇫🇮 Finland'
const SWEDEN_OPTION_CAM = '🇸🇪 Sweden'
const NORWAY_OPTION_CAM = '🇳🇴 Norway'

const options = {
    reply_markup: JSON.stringify({
        one_time_keyboard: true,
        keyboard: [
            [{text: PHOTO_COMMAND}, {text: VISIBILITY_COMMAND}],
            [{text: SCHEDULE_ALERT_COMMAND}, {text: CANCEL_ALERT_COMMAND}],
            [{text: LIVE_PHOTO_COMMAND}]
        ]
    })
}

const camOptions = {
    reply_markup: JSON.stringify({
        one_time_keyboard: true,
        keyboard: [
            [{text: FINLAND_OPTION_CAM}],
            [{text: NORWAY_OPTION_CAM}],
            [{text: SWEDEN_OPTION_CAM}]
        ]
    })
}

const kpOptions = {
    reply_markup: JSON.stringify({
        one_time_keyboard: true,
        keyboard: [
            [{ text: '1' }, { text: '2' }, { text: '3'}],
            [{ text: '4' }, { text: '5' }, { text: '6'}],
            [{ text: '7' }, { text: '8' }]
        ]
    })
}

var alertInput = false
var camInput = false

// Event handling

bot.onText(new RegExp(LIVE_PHOTO_COMMAND), msg => {
    invalidateInputs()
    console.info(`[MSG] Live photo request from ${msg.from.first_name}`)
    const text = 'Choose a cam from one of these regions:'
    bot.sendMessage(msg.from.id, text, camOptions)
    camInput = true
})

bot.onText(new RegExp(VISIBILITY_COMMAND), msg => {
    console.info(`[MSG] Visibility check from ${msg.from.first_name}`)
    bot.sendPhoto(msg.from.id, KP_PHOTO).then(() => {
        const forecast = forecastHandler.getForecast()
        const arrowDown = '🔻'
        const arrowUp = '🔺'
        var text = `Current Kp index is ${forecast.nextH}`
        if (forecast.next4H == forecast.nextH) {
            text += ' without major changes within the next 4h.'
        } else if (forecast.next4H < forecast.nextH) {
            text += ` and within the next 4h it will decrease to ${forecast.next4H} ${arrowDown}.`
        } else {
            text += ` and within the next 4h it will increase to ${forecast.next4H} ${arrowUp}.`
        }
        bot.sendMessage(msg.from.id, text, options)
    })
})

bot.onText(new RegExp(PHOTO_COMMAND), msg => {
    console.info(`[MSG] Send photo to ${msg.from.first_name}`)
    bot.sendChatAction(msg.from.id, 'typing').then(() => {
        return flickrHandler.fetchRandomPhoto()
    }).then(result => {
        console.log(`Sent photo by ${result.owner} to ${msg.from.first_name}`)
        bot.sendPhoto(msg.from.id, result.photo).then(() => {
            bot.sendMessage(msg.from.id, `A gorgeous photo by ${result.owner}.`, options)
        })
    })
})

bot.onText(new RegExp(CANCEL_ALERT_COMMAND), msg => {
    console.info(`[MSG] Cancel alert from ${msg.from.first_name}`)
    const text = `Ok ${msg.from.first_name}, I won't be sending you any more alerts!`
    bot.sendMessage(msg.from.id, text, options)
    forecastHandler.deregisterFromAlerts(msg.from.id)
})

bot.onText(new RegExp(SCHEDULE_ALERT_COMMAND), msg => {
    invalidateInputs()
    console.info(`[MSG] Schedule alert for ${msg.from.first_name}`)
    bot.sendPhoto(msg.from.id, KP_PHOTO).then(() => {
        const text = 'Choose which Kp index you\'d like to be informed about:'
        bot.sendMessage(msg.from.id, text, kpOptions)
        alertInput = true
    })
})

bot.onText(/\/start/, (msg, match) => {
    console.info(`[MSG] /start from ${msg.from.first_name}`)
    const text = `Hey ${msg.from.first_name}! What would you like to do?`
    bot.sendMessage(msg.from.id, text, options)
})

bot.on('message', msg => {
    if (alertInput) {
        alertInput = false
        const value = parseInt(msg.text)
        if (value > 0 && value <= 8) {
            forecastHandler.registerForAlerts(msg.from.first_name, msg.from.id, value)
            const text = `Ok, ${msg.from.first_name}, I will alert you when Kp reaches ${value}.`
            return bot.sendMessage(msg.from.id, text, options)
        }
        sendUnrecognizedMessage(msg.from.id)
    } else if (camInput) {
        camInput = false
        const photos = getLivePhotos()
        if (photos[msg.text]) {
            return bot.sendPhoto(msg.from.id, photos[msg.text].url).then(() => {
                const text = `Here's a photo from ${photos[msg.text].location}.`
                bot.sendMessage(msg.from.id, text, options)
            })
        }
        return sendUnrecognizedMessage(msg.from.id)
    }
})

// Helper functions

function invalidateInputs() {
    alertInput = false
    camInput = false
}

function getLivePhotos() {
    var dict = {}
    dict[SWEDEN_OPTION_CAM] = {url: `http://uk.jokkmokk.jp/photo/nr3/latest.jpg?${Math.random()}`, location: 'Porjus, Jokkmokk, Sweden'}
    dict[FINLAND_OPTION_CAM] = {url: `http://aurora.fmi.fi/public_service/latest_DYN.jpg?${Math.random()}`, location: 'Helsinki, Finland'}
    dict[NORWAY_OPTION_CAM] = {url: `http://polaris.nipr.ac.jp/~acaurora/aurora/Tromso/latest.jpg?${Math.random()}`, location: 'Tromsø, Norway'}
    return dict
}

function sendUnrecognizedMessage(chatId) {
    const text = 'Unrecognized answer. Please choose what you\'d like to do:'
    bot.sendMessage(chatId, text, options)
}

function onKpAlert(chats, kp) {
    chats.forEach(chat => {
        console.info(`[MSG] Send alert to ${chat.user}`)
        const text = `⚠ Alert! ⚠ Alert! Current Kp is ${kp}!`
        bot.sendMessage(chat.chatId, text)
    })
}<|endoftext|>


<commit_before>/// boo.js --- Base primitives for prototypical OO
//
// Copyright (c) 2011 The Orphoundation
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation files
// (the "Software"), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

/// Module boo
void function(root, exports) {

  //// -- Aliases -------------------------------------------------------------
  var slice        = [].slice
  var keys         = Object.keys
  var inherit      = Object.create
  var define       = Object.defineProperty
  var descriptor   = Object.getOwnPropertyDescriptor
  var has_getter_p = function () {
                       try {
                         return true === Object.create( {}
                                                      , { x: { get:
                                                               function(){
                                                                 return true }}}).x }
                       catch(e){ return false }}()

  //// -- Interfaces ----------------------------------------------------------

  ///// Interface DataObject
  // :: { "to_data" -> () -> Object }

  //// -- Helpers -------------------------------------------------------------

  ///// Function copy_property
  // :internal:
  // Copies a property from ``source`' to ``target`'.
  //
  // copy_property! :: Object, target:Object*, String -> target
  function copy_property(source, target, property) {
    !has_getter_p?     target[property] = source[property]
    : /* otherwise */  define(target, property, descriptor(source, property))

    return target
  }

  ///// Function data_obj_p
  // :internal:
  // Checks if the given subject matches the ``DataObject`` interface
  //
  // data_obj_p :: Any -> Bool
  function data_obj_p(subject) {
    return subject != null
    &&     typeof subject.to_data == 'function' }

  ///// Function resolve_mixins
  // :internal:
  // Returns the proper mixin for the given object.
  //
  // resolve_mixin :: Object -> Object
  function resolve_mixin(object) {
    return data_obj_p(object)?  object.to_data()
    :      /* otherwise */      object }

  ///// Function fast_extend
  // :internal:
  // Extends the target object with the provided mixins, using a
  // right-most precedence rule — when a there's a property conflict, the
  // property defined in the last object wins.
  //
  // ``DataObject``s are properly handled by the ``resolve_mixin``
  // function.
  //
  // :warning: low-level
  //    This function is not meant to be called directly from end-user
  //    code, use the ``extend`` function instead.
  //
  // fast_extend :: Object, [Object | DataObject] -> Object
  function fast_extend(object, mixins) {
    var i, j, len, mixin, props, key
    for (i = 0, len = mixins.length; i < len; ++i) {
      mixin = resolve_mixin(mixins[i])
      props = keys(mixin)
      for (j = props.length; j--;) {
        key         = props[j]
        copy_property(mixin, object, key) }}

    return object }

  //// -- Basic primitives ----------------------------------------------------

  ///// Function extend
  // Extends the target object with the provided mixins, using a
  // right-most precedence rule.
  //
  // :see-also:
  //   - ``fast_extend`` — lower level function.
  //   - ``merge``       — pure version.
  //
  // extend :: Object, (Object | DataObject)... -> Object
  function extend(target) {
    return fast_extend(target, slice.call(arguments, 1)) }

  ///// Function merge
  // Creates a new object that merges the provided mixins, using a
  // right-most precedence rule.
  //
  // :see-also:
  //   - ``extend`` — impure version.
  //
  // merge :: (Object | DataObject)... -> Object
  function merge() {
    return fast_extend({}, arguments) }

  ///// Function derive
  // Creates a new object inheriting from the given prototype and extends
  // the new instance with the provided mixins.
  //
  // derive :: Object, (Object | DataObject)... -> Object
  function derive(proto) {
    return fast_extend(inherit(proto), slice.call(arguments, 1)) }

  ///// Function make
  // Constructs a new instance of the given object.
  //
  // If the object provides an ``init`` function, that function is
  // invoked to do initialisation on the new instance.
  //
  // make :: a:Object, Any... -> Object <| a
  function make(base) {
    return Base.make.apply(base, slice.call(arguments, 1)) }

  //// -- Root object ---------------------------------------------------------

  ///// Object Base
  // The root object for basing all the OOP code. Provides the previous
  // primitive combinators in an easy and OOP-way.
  var Base = {

    ////// Function make
    // Constructs new instances of the object the function is being
    // applied to.
    //
    // If the object provides an ``init`` function, that function is
    // invoked to do initialisation on the new instance.
    //
    // make :: Any... -> Object
    make:
    function _make() {
      var result = inherit(this)
      if (typeof result.init == 'function')
        result.init.apply(result, arguments)

      return result }

    ////// Function derive
    // Constructs a new object that inherits from the object this function
    // is being applied to, and extends it with the provided mixins.
    //
    // derive :: (Object | DataObject)... -> Object
  , derive:
    function _derive() {
      return fast_extend(inherit(this), arguments) }}

  //// -- Exports -------------------------------------------------------------
  exports.extend   = extend
  exports.merge    = merge
  exports.derive   = derive
  exports.make     = make
  exports.Base     = Base
  exports.internal = { data_obj_p    : data_obj_p
                     , fast_extend   : fast_extend
                     , resolve_mixin : resolve_mixin
                     , copy_property : copy_property
                     }

}
( this
, typeof exports == 'undefined'?  this.boo = this.boo || {}
  /* otherwise, yay modules! */:  exports
)
<commit_msg>Fixes type annotation.<commit_after>/// boo.js --- Base primitives for prototypical OO
//
// Copyright (c) 2011 The Orphoundation
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation files
// (the "Software"), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

/// Module boo
void function(root, exports) {

  //// -- Aliases -------------------------------------------------------------
  var slice        = [].slice
  var keys         = Object.keys
  var inherit      = Object.create
  var define       = Object.defineProperty
  var descriptor   = Object.getOwnPropertyDescriptor
  var has_getter_p = function () {
                       try {
                         return true === Object.create( {}
                                                      , { x: { get:
                                                               function(){
                                                                 return true }}}).x }
                       catch(e){ return false }}()

  //// -- Interfaces ----------------------------------------------------------

  ///// Interface DataObject
  // DataObject :: { "to_data" -> () -> Object }

  //// -- Helpers -------------------------------------------------------------

  ///// Function copy_property
  // :internal:
  // Copies a property from ``source`' to ``target`'.
  //
  // copy_property! :: Object, target:Object*, String -> target
  function copy_property(source, target, property) {
    !has_getter_p?     target[property] = source[property]
    : /* otherwise */  define(target, property, descriptor(source, property))

    return target
  }

  ///// Function data_obj_p
  // :internal:
  // Checks if the given subject matches the ``DataObject`` interface
  //
  // data_obj_p :: Any -> Bool
  function data_obj_p(subject) {
    return subject != null
    &&     typeof subject.to_data == 'function' }

  ///// Function resolve_mixins
  // :internal:
  // Returns the proper mixin for the given object.
  //
  // resolve_mixin :: Object -> Object
  function resolve_mixin(object) {
    return data_obj_p(object)?  object.to_data()
    :      /* otherwise */      object }

  ///// Function fast_extend
  // :internal:
  // Extends the target object with the provided mixins, using a
  // right-most precedence rule — when a there's a property conflict, the
  // property defined in the last object wins.
  //
  // ``DataObject``s are properly handled by the ``resolve_mixin``
  // function.
  //
  // :warning: low-level
  //    This function is not meant to be called directly from end-user
  //    code, use the ``extend`` function instead.
  //
  // fast_extend :: Object, [Object | DataObject] -> Object
  function fast_extend(object, mixins) {
    var i, j, len, mixin, props, key
    for (i = 0, len = mixins.length; i < len; ++i) {
      mixin = resolve_mixin(mixins[i])
      props = keys(mixin)
      for (j = props.length; j--;) {
        key         = props[j]
        copy_property(mixin, object, key) }}

    return object }

  //// -- Basic primitives ----------------------------------------------------

  ///// Function extend
  // Extends the target object with the provided mixins, using a
  // right-most precedence rule.
  //
  // :see-also:
  //   - ``fast_extend`` — lower level function.
  //   - ``merge``       — pure version.
  //
  // extend :: Object, (Object | DataObject)... -> Object
  function extend(target) {
    return fast_extend(target, slice.call(arguments, 1)) }

  ///// Function merge
  // Creates a new object that merges the provided mixins, using a
  // right-most precedence rule.
  //
  // :see-also:
  //   - ``extend`` — impure version.
  //
  // merge :: (Object | DataObject)... -> Object
  function merge() {
    return fast_extend({}, arguments) }

  ///// Function derive
  // Creates a new object inheriting from the given prototype and extends
  // the new instance with the provided mixins.
  //
  // derive :: Object, (Object | DataObject)... -> Object
  function derive(proto) {
    return fast_extend(inherit(proto), slice.call(arguments, 1)) }

  ///// Function make
  // Constructs a new instance of the given object.
  //
  // If the object provides an ``init`` function, that function is
  // invoked to do initialisation on the new instance.
  //
  // make :: a:Object, Any... -> Object <| a
  function make(base) {
    return Base.make.apply(base, slice.call(arguments, 1)) }

  //// -- Root object ---------------------------------------------------------

  ///// Object Base
  // The root object for basing all the OOP code. Provides the previous
  // primitive combinators in an easy and OOP-way.
  var Base = {

    ////// Function make
    // Constructs new instances of the object the function is being
    // applied to.
    //
    // If the object provides an ``init`` function, that function is
    // invoked to do initialisation on the new instance.
    //
    // make :: Any... -> Object
    make:
    function _make() {
      var result = inherit(this)
      if (typeof result.init == 'function')
        result.init.apply(result, arguments)

      return result }

    ////// Function derive
    // Constructs a new object that inherits from the object this function
    // is being applied to, and extends it with the provided mixins.
    //
    // derive :: (Object | DataObject)... -> Object
  , derive:
    function _derive() {
      return fast_extend(inherit(this), arguments) }}

  //// -- Exports -------------------------------------------------------------
  exports.extend   = extend
  exports.merge    = merge
  exports.derive   = derive
  exports.make     = make
  exports.Base     = Base
  exports.internal = { data_obj_p    : data_obj_p
                     , fast_extend   : fast_extend
                     , resolve_mixin : resolve_mixin
                     , copy_property : copy_property
                     }

}
( this
, typeof exports == 'undefined'?  this.boo = this.boo || {}
  /* otherwise, yay modules! */:  exports
)
<|endoftext|>


<commit_before>/**
 * Module dependencies.
 */

var debug = require('debug')('wpcom:post');

/**
 * Post methods
 *
 * @param {String} id
 * @param {String} sid site id
 * @param {WPCOM} wpcom
 * @api public
 */

function Post(id, sid, wpcom){
  if (!(this instanceof Post)) return new Post(id, sid, wpcom);

  this.wpcom = wpcom;
  this._sid = sid;

  // set `id` and/or `slug` properties
  id = id || {};
  if ('object' != typeof id) {
    this._id = id;
  } else {
    this._id = id.id;
    this._slug = id.slug;
  }
}

/**
 * Set post `id`
 *
 * @api public
 */

Post.prototype.id = function(id){
  this._id = id;
};

/**
 * Set post `slug`
 *
 * @param {String} slug
 * @api public
 */

Post.prototype.slug = function(slug){
  this._slug = slug;
};

/**
 * Get post
 *
 * @param {Object} [query]
 * @param {Function} fn
 * @api public
 */

Post.prototype.get = function(query, fn){
  if (!this._id && this._slug) {
    return this.getBySlug(query, fn);
  }

  var path = '/sites/' + this._sid + '/posts/' + this._id;
  this.wpcom.sendRequest(path, query, null, fn);
};

/**
 * Get post by slug
 *
 * @param {Object} [query]
 * @param {Function} fn
 * @api public
 */

Post.prototype.getBySlug = function(query, fn){
  var path = '/sites/' + this._sid + '/posts/slug:' + this._slug;
  this.wpcom.sendRequest(path, query, null, fn);
};

/**
 * Add post
 *
 * @param {Object} body
 * @param {Function} fn
 * @api public
 */

Post.prototype.add = function(body, fn){
  var path = '/sites/' + this._sid + '/posts/new';
  this.wpcom.sendRequest({ path: path, method: 'post' }, null, body, fn);
};

/**
 * Edit post
 *
 * @param {Object} body
 * @param {Function} fn
 * @api public
 */

Post.prototype.update = function(body, fn){
  var path = '/sites/' + this._sid + '/posts/' + this._id;
  this.wpcom.sendRequest({ path: path, method: 'post' }, null, body, fn);
};

/**
 * Delete post
 *
 * @param {Function} fn
 * @api public
 */

Post.prototype['delete'] =
Post.prototype.del = function(fn){
  var path = '/sites/' + this._sid + '/posts/' + this._id + '/delete';
  this.wpcom.sendRequest({ path: path, method: 'post' }, null, null, fn);
};

/**
 * Get post likes list
 *
 * @param {Object} [query]
 * @param {Function} fn
 * @api public
 */

Post.prototype.likes = function(query, fn){
  var path = '/sites/' + this._sid + '/posts/' + this._id + '/likes';
  this.wpcom.sendRequest(path, query, null, fn);
};

/**
 * Like a post
 *
 * @param {Object} [query]
 * @param {Function} fn
 * @api public
 */

Post.prototype.like = function(query, fn){
  var path = '/sites/' + this._sid + '/posts/' + this._id + '/likes/new';
  this.wpcom.sendRequest({ path: path, method: 'post' }, query, fn);
};

/**
 * Expose `Post` module
 */

module.exports = Post;
<commit_msg>post: refact -> use Like class to like stuff<commit_after>
/**
 * Module dependencies.
 */

var Like = require('./like');
var debug = require('debug')('wpcom:post');

/**
 * Post methods
 *
 * @param {String} id
 * @param {String} sid site id
 * @param {WPCOM} wpcom
 * @api public
 */

function Post(id, sid, wpcom){
  if (!(this instanceof Post)) return new Post(id, sid, wpcom);

  this.wpcom = wpcom;
  this._sid = sid;

  // set `id` and/or `slug` properties
  id = id || {};
  if ('object' != typeof id) {
    this._id = id;
  } else {
    this._id = id.id;
    this._slug = id.slug;
  }
}

/**
 * Set post `id`
 *
 * @api public
 */

Post.prototype.id = function(id){
  this._id = id;
};

/**
 * Set post `slug`
 *
 * @param {String} slug
 * @api public
 */

Post.prototype.slug = function(slug){
  this._slug = slug;
};

/**
 * Get post
 *
 * @param {Object} [query]
 * @param {Function} fn
 * @api public
 */

Post.prototype.get = function(query, fn){
  if (!this._id && this._slug) {
    return this.getBySlug(query, fn);
  }

  var path = '/sites/' + this._sid + '/posts/' + this._id;
  this.wpcom.sendRequest(path, query, null, fn);
};

/**
 * Get post by slug
 *
 * @param {Object} [query]
 * @param {Function} fn
 * @api public
 */

Post.prototype.getBySlug = function(query, fn){
  var path = '/sites/' + this._sid + '/posts/slug:' + this._slug;
  this.wpcom.sendRequest(path, query, null, fn);
};

/**
 * Add post
 *
 * @param {Object} body
 * @param {Function} fn
 * @api public
 */

Post.prototype.add = function(body, fn){
  var path = '/sites/' + this._sid + '/posts/new';
  this.wpcom.sendRequest({ path: path, method: 'post' }, null, body, fn);
};

/**
 * Edit post
 *
 * @param {Object} body
 * @param {Function} fn
 * @api public
 */

Post.prototype.update = function(body, fn){
  var path = '/sites/' + this._sid + '/posts/' + this._id;
  this.wpcom.sendRequest({ path: path, method: 'post' }, null, body, fn);
};

/**
 * Delete post
 *
 * @param {Function} fn
 * @api public
 */

Post.prototype['delete'] =
Post.prototype.del = function(fn){
  var path = '/sites/' + this._sid + '/posts/' + this._id + '/delete';
  this.wpcom.sendRequest({ path: path, method: 'post' }, null, null, fn);
};

/**
 * Get post likes list
 *
 * @param {Object} [query]
 * @param {Function} fn
 * @api public
 */

Post.prototype.likes = function(query, fn){
  var path = '/sites/' + this._sid + '/posts/' + this._id + '/likes';
  this.wpcom.sendRequest(path, query, null, fn);
};

/**
 * Create a `Like` instance
 *
 * @api public
 */

Post.prototype.like = function(){
  return Like( this._id, this._sid, this.wpcom);
};

/**
 * Expose `Post` module
 */

module.exports = Post;
<|endoftext|>