<commit_before>var fs               = require('fs'),
    util             = require('util'),
    events           = require('events'),
    moment           = require('moment'),
    Playlist         = require('./api/Playlist'),
    Melted           = require('./api/Melted'),
    Media            = require('./api/Media'),
    StreamerCom      = require('./api/StreamerCom');

function fetch( config ) {

    StreamerCom.call(this);

    this.mosto = config.mosto;
    this.driver = config.mosto.driver;
    this.name = "fetcher";

    this.scheduler = undefined;
    this.fetcher = undefined;
    this.player = undefined;

    this.playlists = []; // this is the scheduled playlists....in a range between now and max_playlist_duration
    this.time_window_from = "";
    this.time_window_to = "";
    this.playlists_updated = false;

}

fetch.prototype = new StreamerCom();

fetch.prototype.init = function() {
    var self = this;

    self.scheduler = self.mosto.scheduler;
    self.player = self.mosto.player;

    self.name = "fetcher";

    /*GOING DOWN: we listen to ourself and emit on Scheduler*/
    self.on( 'fetch_downstream', function(playlists) {
        console.log("mbc-mosto: [INFO] [FETCH] Auto received fetch_downstream: " + playlists.length + " scheduler:"+self.scheduler);
        if (self.scheduler) self.scheduler.emit('datasend', playlists );
    });

    /*COMING FROM BELOW: we listen to Scheduler*/
    if (self.scheduler) self.scheduler.on( 'fetch_upstream', function() {
        console.log("mbc-mosto: [INFO] [FETCH] timer unlock from fetch_upstream. Top of machine reached.");
        self.upstreamCheck(self);
    });

    //open data receiver
    //open data receiver
    if (self.Open( self ) && self.IsReceiving()) {
        console.log('mbc-mosto: [INFO] [FETCH] Opened');
    } else throw new Error("mbc-mosto: [ERROR] [FETCH] couldn't open StreamerCom");

}

        self.driver = self.mosto.driver;

        self.scheduler = self.mosto.scheduler;
        if (self.scheduler) self.scheduler.on( 'fetch_upstream', function() {
            self.checkoutPlaylists( function() {
                console.log("mbc-mosto: [INFO] [FETCH] timer unlock from fetch_upstream. Top of machine reached.");
                self.player.timerUnlock();
            });
        });

        self.player = self.mosto.player;

    }

    /** FETCH MODULE */

    //TODO: testing json, then mongodb

    /** addPlaylist
     *
     *       add a new playlist
     */
    fetch.prototype.addPlaylist = function(playlist) {

        console.log("mbc-mosto: [INFO] Adding playlist " + playlist.name);
        self.playlists.push(playlist);
        console.log("mbc-mosto: [INFO] Added playlist:\nid: " + playlist.id
                    + "\nname: " + playlist.name
                    + "\nstartDate: " + playlist.startDate
                    + "\nendDate: " + playlist.endDate);
        self.orderPlaylists();
    };

    /** updatePlaylist
     *
     *       update only if we are in range?! i dont want playlists scheduled for tomorrow nw!!!
     */
    fetch.prototype.updatePlaylist = function(playlist) {

        console.log("mbc-mosto: [INFO] Updating playlist " + playlist.name);
        var i = -1;
        self.playlists.some(function(element, index, array) {
            if (element.id === playlist.id) {
                i = index;
                return true;
            }
        });

        //update may create or delete if needed
        if (i==-1) {
            return self.addPlaylist(playlist);
        } else {
            if ( (moment(playlist.startDate) <= self.time_window_to &&
                  moment(playlist.endDate) >= self.time_window_from ) ) {
                self.playlists[i] = playlist;
            } else return self.removePlaylist(playlist.id);
        }

        console.log("mbc-mosto: [INFO] Updated playlist:\nid: " + playlist.id
                    + "\nname: " + playlist.name
                    + "\nstartDate: " + playlist.startDate
                    + "\nendDate: " + playlist.endDate);

        self.orderPlaylists();
    };

    /** removePlaylist
     *
     *
     */
    fetch.prototype.removePlaylist = function(id) {

        console.log("mbc-mosto: [INFO] Removing playlist id: " + id);
        var i = -1;
        var playlist = undefined;
        if (self.playlists.length>0) {
            self.playlists.some(function(element, index, array) {
                if (element!==undefined) {
                    if (element.id === id) {
                        i = index;
                        playlist = element;
                        return true;
                    }
                }
            });
        }
        if (i!=-1) self.playlists.splice(i, 1);
        if (playlist!=undefined) {
            console.log("mbc-mosto: [INFO] Removed playlist:\nid: " + playlist.id
                        + "\nname: " + playlist.name
                        + "\nstartDate: " + playlist.startDate
                        + "\nendDate: " + playlist.endDate);
        }
        self.orderPlaylists();
    };

    /** orderPlaylists
     *       Sort playlists using startDate as key
     *
     *
     */
    fetch.prototype.orderPlaylists = function() {

        self.removeBlackPlaylist();
        self.trimPlaylists();

        if (self.playlists.length==0) {

            var sch_rightnow = moment().add( moment.duration({ milliseconds: -1000 }) ).format("DD/MM/YYYY HH:mm:ss.SSS");
            self.startBlack( sch_rightnow, "22:22:22.22", sch_rightnow, moment( sch_rightnow,"DD/MM/YYYY HH:mm:ss.SSS").add(moment.duration({ milliseconds: 80542220 }) ).format('DD/MM/YYYY HH:mm:ss.SSS') );
        }

        console.log("mbc-mosto: [INFO] Start ordering playlists " + self.playlists.length);
        self.playlists.sort(function (item1, item2) {
            if (item1.startDate < item2.startDate)
                return -1;
            else if (item1.startDate > item2.startDate)
                return 1;
            else
                return 0;
        });
        console.log("mbc-mosto: [INFO] Finish ordering playlists");
        self.playlists_updated = true;

        //Here we must emit a "scheduler" event with actual self.playlists object...
        //if (self.scheduler) self.scheduler.convertPlaylistsToScheduledClips();
        self.emit('fetch_downstream', self.playlists );

    };

    /** trimPlaylists
     *       remove any playlist that is out of our time window
     *
     *
     */
    fetch.prototype.trimPlaylists = function() {
        self.updateTimeWindow();
        var newplaylists = [];
        for(var i=0; i<self.playlists.length;i++) {
            var playlist = self.playlists[i];
            if ( (moment(playlist.startDate) <= self.time_window_to &&
                  moment(playlist.endDate) >= self.time_window_from )
                && (playlist.id != 'black_id') ) {
                console.log("mbc-mosto: [INFO] [FETCH] trimming playlists:" + playlist.id );
                newplaylists.push(playlist);
            }
        }
        self.playlists = newplaylists;
    }

    fetch.prototype.removeBlackPlaylist = function() {
        var i = -1;
        var playlist = undefined;
        if (self.playlists.length>0) {
            self.playlists.some(function(element, index, array) {
                if (element!==undefined) {
                    if (element.id === 'black_id') {
                        i = index;
                        playlist = element;
                        return true;
                    }
                }
            });
        }
        if (i!=-1) self.playlists.splice(i, 1);
    }

    fetch.prototype.updateTimeWindow = function() {
        if (self.player) self.player.timer_clock = moment();
        if (self.player) self.player.sync_lock_start = moment();

        self.time_window_from = moment( moment().toDate());
        //var last_time_window_to = self.time_window_to.clone();
        //var last_time_window_to = self.time_window_from.clone();
        self.time_window_to = self.time_window_from.clone();
        self.time_window_to.add( moment.duration({ hours: 4 }) );

        if (self.driver)
            self.driver.setWindow( self.time_window_from, self.time_window_to );

    }

    /**     checkoutPlaylists
     *       checkout load next playlists if needed
     *       each call to checkoutPlaylists advance the time_window
     *
     *       We are using a minimum memory overhead approach to store the playlists
     *       Full playlist has a maximum of 4 hours total length starting from "now"
     *       Any older playlist are removed from memory to release memory
     */
    fetch.prototype.checkoutPlaylists = function(callback) {
        console.log("mbc-mosto: [INFO] [FETCH] checking out new playlists in our time window.");

        //TODO: just ask for the difference between "actual time window" and "last time window"
        var last_time_window_to = moment(self.time_window_to);

        self.updateTimeWindow();

        console.log("mbc-mosto: [INFO] [FETCH] checkoutPlaylists > from: " + self.time_window_from.format("DD/MM/YYYY HH:mm:ss") + " to:" + self.time_window_to.format("DD/MM/YYYY HH:mm:ss") );

        //now we read playlists, between "last_time_window_to" and "time_window_to"
        if (self.driver) {
            self.driver.getPlaylists( { from: self.time_window_from, to: self.time_window_to, setWindow: false }, function(playlists) {

                //just import new ones....
                console.log("mbc-mosto: [INFO] [LOGIC] checkoutPlaylists > receive playlists from: " + last_time_window_to.format("DD/MM/YYYY HH:mm:ss") + " to:" + self.time_window_to.format("DD/MM/YYYY HH:mm:ss") );
                for( var p=0;p<playlists.length;p++) {
                    var playlist = playlists[p];
                    var i = -1;
                    self.playlists.some( function(element, index, array) {
                        if (element.id === playlist.id) {
                            i = index;
                            return true;
                        }
                    });
                    if (i==-1) {
                        self.playlists.push(playlist);
                    }
                }

                self.orderPlaylists();

                //update the boundaries
                self.driver.setWindow( self.time_window_from, self.time_window_to );

                if (callback) callback(playlists);
            } );
        } else console.error("mbc-mosto: ERROR [FETCH] checkoutPlaylist > playlist driver is undefined! ");
    }

    fetch.prototype.startBlack = function( schedule_time, sch_duration, sch_expect_start, sch_expect_end ) {
        var BlackMedia = new Media( 'black_id' /*id*/, '0' /*orig_order*/, '0'/*actual_order*/, 'black_id' /*playlist_id*/, 'black' /*name*/, 'file' /*type*/, self.mosto.config.black, sch_duration/*length*/, ''/*fps*/ );
        console.log("mbc-mosto: [INFO] [LOGIC] startBlack > media:" + BlackMedia.file + " schedule_time:" + schedule_time + " sch_duration:" + sch_duration + " sch_expect_start:" + sch_expect_start + " sch_expect_end:" + sch_expect_end + " fps?:"+BlackMedia.fps );
        var medias = [];
        medias.push(BlackMedia);
        self.playlists.push( new Playlist( BlackMedia.id, BlackMedia.id, moment( sch_expect_start, "DD/MM/YYYY HH:mm:ss.SSS" ).toDate(), medias, moment( sch_expect_end, "DD/MM/YYYY HH:mm:ss.SSS" ).toDate(), "snap" ) );
    }

exports = module.exports = function(config) {
    var mosto_fetch = new fetch(config);
    mosto_fetch.ResetListeners();
    return mosto_fetch;
};
<commit_msg>Just reordering declarations for correct inheritance.<commit_after>var fs               = require('fs'),
    util             = require('util'),
    events           = require('events'),
    moment           = require('moment'),
    Playlist         = require('./api/Playlist'),
    Melted           = require('./api/Melted'),
    Media            = require('./api/Media'),
    StreamerCom      = require('./api/StreamerCom');

function fetch( config ) {

    StreamerCom.call(this);

    this.mosto = config.mosto;
    this.driver = config.mosto.driver;
    this.name = "fetcher";

    this.scheduler = undefined;
    this.fetcher = undefined;
    this.player = undefined;

    this.playlists = []; // this is the scheduled playlists....in a range between now and max_playlist_duration
    this.time_window_from = "";
    this.time_window_to = "";
    this.playlists_updated = false;

}

fetch.prototype = new StreamerCom();

fetch.prototype.init = function() {
    var self = this;

    self.scheduler = self.mosto.scheduler;
    self.player = self.mosto.player;

    self.name = "fetcher";

    /*GOING DOWN: we listen to ourself and emit on Scheduler*/
    self.on( 'fetch_downstream', function(playlists) {
        console.log("mbc-mosto: [INFO] [FETCH] Auto received fetch_downstream: " + playlists.length + " scheduler:"+self.scheduler);
        if (self.scheduler) self.scheduler.emit('datasend', playlists );
    });

    /*COMING FROM BELOW: we listen to Scheduler*/
    if (self.scheduler) self.scheduler.on( 'fetch_upstream', function() {
        console.log("mbc-mosto: [INFO] [FETCH] timer unlock from fetch_upstream. Top of machine reached.");
        self.upstreamCheck(self);
    });

    //open data receiver
    //open data receiver
    if (self.Open( self ) && self.IsReceiving()) {
        console.log('mbc-mosto: [INFO] [FETCH] Opened');
    } else throw new Error("mbc-mosto: [ERROR] [FETCH] couldn't open StreamerCom");

}

/** FETCH MODULE */

//TODO: testing json, then mongodb

/** addPlaylist
 *
 *       add a new playlist
 */
fetch.prototype.addPlaylist = function( playlist, mself ) {
    var self = mself || this;
    console.log("mbc-mosto: [INFO] Adding playlist " + playlist.name);
    self.playlists.push(playlist);
    console.log("mbc-mosto: [INFO] Added playlist:\nid: " + playlist.id
                + "\nname: " + playlist.name
                + "\nstartDate: " + playlist.startDate
                + "\nendDate: " + playlist.endDate);
    self.orderPlaylists();
}

/** updatePlaylist
 *
 *       update only if we are in range?! i dont want playlists scheduled for tomorrow nw!!!
 */
fetch.prototype.updatePlaylist = function(playlist, mself) {
    var self = mself || this;
    console.log("mbc-mosto: [INFO] Updating playlist " + playlist.name);
    var i = -1;
    self.playlists.some(function(element, index, array) {
        if (element.id === playlist.id) {
            i = index;
            return true;
        }
    });

    //update may create or delete if needed
    if (i==-1) {
        return self.addPlaylist(playlist);
    } else {
        if ( (moment(playlist.startDate) <= self.time_window_to &&
              moment(playlist.endDate) >= self.time_window_from ) ) {
            self.playlists[i] = playlist;
        } else return self.removePlaylist(playlist.id);
    }

    console.log("mbc-mosto: [INFO] Updated playlist:\nid: " + playlist.id
                + "\nname: " + playlist.name
                + "\nstartDate: " + playlist.startDate
                + "\nendDate: " + playlist.endDate);

    self.orderPlaylists();
};

/** removePlaylist
 *
 *
 */
fetch.prototype.removePlaylist = function(id, mself) {
    var self = mself || this;
    console.log("mbc-mosto: [INFO] Removing playlist id: " + id);
    var i = -1;
    var playlist = undefined;
    if (self.playlists.length>0) {
        self.playlists.some(function(element, index, array) {
            if (element!==undefined) {
                if (element.id === id) {
                    i = index;
                    playlist = element;
                    return true;
                }
            }
        });
    }
    if (i!=-1) self.playlists.splice(i, 1);
    if (playlist!=undefined) {
        console.log("mbc-mosto: [INFO] Removed playlist:\nid: " + playlist.id
                    + "\nname: " + playlist.name
                    + "\nstartDate: " + playlist.startDate
                    + "\nendDate: " + playlist.endDate);
    }
    self.orderPlaylists();
};

/** orderPlaylists
 *       Sort playlists using startDate as key
 *
 *
 */
fetch.prototype.orderPlaylists = function() {

    this.removeBlackPlaylist();
    this.trimPlaylists();

    if (this.playlists.length==0) {

        var sch_rightnow = moment().add( moment.duration({ milliseconds: -1000 }) ).format("DD/MM/YYYY HH:mm:ss.SSS");
        this.startBlack( sch_rightnow, "22:22:22.22", sch_rightnow, moment( sch_rightnow,"DD/MM/YYYY HH:mm:ss.SSS").add(moment.duration({ milliseconds: 80542220 }) ).format('DD/MM/YYYY HH:mm:ss.SSS') );
    }

    console.log("mbc-mosto: [INFO] [FETCH] Start ordering playlists " + this.playlists.length);
    this.playlists.sort(function (item1, item2) {
        if (item1.startDate < item2.startDate)
            return -1;
        else if (item1.startDate > item2.startDate)
            return 1;
        else
            return 0;
    });
    console.log("mbc-mosto: [INFO] [FETCH] Finish ordering playlists (" + this.playlists.length + ")");
    this.playlists_updated = true;
    console.log("mbc-mosto: [INFO] [FETCH] this.emit : 'fetch_downstream'" + this.playlists );
    this.emit('fetch_downstream', this.playlists );
}

/** trimPlaylists
 *       remove any playlist that is out of our time window
 *
 *
 */
fetch.prototype.trimPlaylists = function() {
    this.updateTimeWindow();
    var newplaylists = [];
    for(var i=0; i<this.playlists.length;i++) {
        var playlist = this.playlists[i];
        if ( (moment(playlist.startDate) <= this.time_window_to &&
              moment(playlist.endDate) >= this.time_window_from )
            && (playlist.id != 'black_id') ) {
            console.log("mbc-mosto: [INFO] [FETCH] trimming playlists:" + playlist.id );
            newplaylists.push(playlist);
        }
    }
    this.playlists = newplaylists;
}

fetch.prototype.removeBlackPlaylist = function() {
    var i = -1;
    var playlist = undefined;
    if (this.playlists.length>0) {
        this.playlists.some(function(element, index, array) {
            if (element!==undefined) {
                if (element.id === 'black_id') {
                    i = index;
                    playlist = element;
                    return true;
                }
            }
        });
    }
    if (i!=-1) this.playlists.splice(i, 1);
}

fetch.prototype.updateTimeWindow = function() {
    if (this.player) this.player.timer_clock = moment();
    if (this.player) this.player.sync_lock_start = moment();

    this.time_window_from = moment( moment().toDate());
    //var last_time_window_to = this.time_window_to.clone();
    //var last_time_window_to = this.time_window_from.clone();
    this.time_window_to = this.time_window_from.clone();
    this.time_window_to.add( moment.duration({ hours: 4 }) );

    if (this.driver)
        this.driver.setWindow( this.time_window_from, this.time_window_to );

}

fetch.prototype.upstreamCheck = function(self) {

    console.log("mbc-mosto: [INFO] [FETCH] upstreamcheck() > doing a checkoutPlaylists()");
    self.checkoutPlaylists( function(playlists) {

        console.log("mbc-mosto: [INFO] [FETCH] upstreamcheck() > calllback from checkoutPlaylist : timer unlock from fetch_upstream.");
        if (self.player) self.player.timerUnlock("from [FETCH] upstreamcheck");
    });

}

/**     checkoutPlaylists
 *       checkout load next playlists if needed
 *       each call to checkoutPlaylists advance the time_window
 *
 *       We are using a minimum memory overhead approach to store the playlists
 *       Full playlist has a maximum of 4 hours total length starting from "now"
 *       Any older playlist are removed from memory to release memory
 */
fetch.prototype.checkoutPlaylists = function(callback) {
    console.log("mbc-mosto: [INFO] [FETCH] checking out new playlists in our time window.");

    var self = this;

    //TODO: just ask for the difference between "actual time window" and "last time window"
    var last_time_window_to = moment(this.time_window_to);

    this.updateTimeWindow();

    console.log("mbc-mosto: [INFO] [FETCH] checkoutPlaylists > from: " + this.time_window_from.format("DD/MM/YYYY HH:mm:ss") + " to:" + this.time_window_to.format("DD/MM/YYYY HH:mm:ss") );

    //now we read playlists, between "last_time_window_to" and "time_window_to"
    if (this.driver) {
        this.driver.getPlaylists( { from: this.time_window_from, to: this.time_window_to, setWindow: false }, function(playlists) {

            //just import new ones....
            console.log("mbc-mosto: [INFO] [FETCH] checkoutPlaylists > receive playlists from: " + last_time_window_to.format("DD/MM/YYYY HH:mm:ss") + " to:" + self.time_window_to.format("DD/MM/YYYY HH:mm:ss") );
            for( var p=0;p<playlists.length;p++) {
                var playlist = playlists[p];
                var i = -1;
                self.playlists.some( function(element, index, array) {
                    if (element.id === playlist.id) {
                        i = index;
                        return true;
                    }
                });
                if (i==-1) {
                    self.playlists.push(playlist);
                }
            }

            self.orderPlaylists();

            //update the boundaries
            self.driver.setWindow( self.time_window_from, self.time_window_to );

            if (callback) callback(playlists);
        } );
    } else console.error("mbc-mosto: ERROR [FETCH] checkoutPlaylist > playlist driver is undefined! ");
}

fetch.prototype.startBlack = function( schedule_time, sch_duration, sch_expect_start, sch_expect_end ) {
    var BlackMedia = new Media( 'black_id' /*id*/,
        '0' /*orig_order*/,
        '0'/*actual_order*/,
        'black_id' /*playlist_id*/,
        'black' /*name*/,
        'file' /*type*/,
        this.mosto.config.black,
        sch_duration/*length*/,
        ''/*fps*/ );
    console.log("mbc-mosto: [INFO] [FETCH] startBlack > media: " + BlackMedia.file
        + " schedule_time: " + schedule_time
        + " sch_duration: "  + sch_duration
        + " sch_expect_start: " + sch_expect_start
        + " sch_expect_end: " + sch_expect_end
        + " fps: "+BlackMedia.fps );

    var medias = [];
    medias.push(BlackMedia);
    this.playlists.push( new Playlist( BlackMedia.id, BlackMedia.id, moment( sch_expect_start, "DD/MM/YYYY HH:mm:ss.SSS" ).toDate(), medias, moment( sch_expect_end, "DD/MM/YYYY HH:mm:ss.SSS" ).toDate(), "snap" ) );
}

exports = module.exports = function(config) {
    var mosto_fetch = new fetch(config);
    mosto_fetch.ResetListeners();
    return mosto_fetch;
};
<|endoftext|>


<commit_before>var heap_metrics = require( './../build/Release/heap_metrics.node' );
var assert = require('assert');

function consume_heap()
{
    var garbage = [];

    for (var i=0; i<1000; i++)
    {
        garbage.push("this is a long string to consume heap memory... lets make it a little longer... and longer still... why stop now");

    }
}

describe('DumpHeapMetrics', function(){
  it('should return true', function(){
    for(var i=0;i<120;i++){
        consume_heap();
    }
    assert(heap_metrics.DumpHeapMetrics());
  });
})<commit_msg>more heap usage<commit_after>var heap_metrics = require( './../build/Release/heap_metrics.node' );
var assert = require('assert');

function consume_heap()
{
    var garbage = [];

    for (var i=0; i<1300; i++)
    {
        garbage.push("this is a long string to consume heap memory... lets make it a little longer... and longer still... why stop now");

    }
}

describe('DumpHeapMetrics', function(){
  it('should return true', function(){
    for(var i=0;i<180;i++){
        consume_heap();
    }
    assert(heap_metrics.DumpHeapMetrics());
  });
})<|endoftext|>


<commit_before>import PouchDB from 'pouchdb-browser'
import PouchDebug from 'pouchdb-debug'
import PouchUpsert from 'pouchdb-upsert'
import PouchFind from 'pouchdb-find'
import PouchLiveFind from 'pouchdb-live-find'

import Model from '@/models/model'

PouchDB.plugin(PouchDebug)

if (!process.env.IS_WEB) {
  PouchDB.debug.enable('*')
} else {
  PouchDB.debug.disable()
}

PouchDB.plugin(PouchUpsert)
PouchDB.plugin(PouchFind)
PouchDB.plugin(PouchLiveFind)

/**
 * This class wraps the PouchDB interface to provide some methods that deal with
 * the revisions (`_rev`) automatically.
 */
class DbInterface {
  /**
   * Creates an instance of DbInterface and the main index
   * @param {String} name
   * @return {DbInterface}
   */
  static create (name) {
    const db = new DbInterface(name)

    db.createIndex('modelType', ['modelType'])

    return db
  }

  /**
   * @param {String} name
   */
  constructor (name) {
    this.__db = new PouchDB(name)
  }

  /**
   * @param {String} name
   * @param {Array} fields
   * @return {Boolean} if the index was created of already exists
   */
  async createIndex (name, fields) {
    try {
      const { result } = await this.__db.createIndex({
        index: { name, fields }
      })
      return result === 'created'
    } catch (error) {
      console.error(`Error creating the index \`${name}\``, error)
      throw error
    }
  }

  /**
   * Finds a document by the id, and returns the associated Model. If the document
   * does not exist, it return `null`
   * @param {String} id
   * @return {(Model|null)}
   */
  async find (id) {
    try {
      const doc = await this.__db.get(id)
      return Model.fromDoc(doc)
    } catch (error) {
      return null
    }
  }

  /**
   * Gets a document by the id, and returns the associated Model. If the document
   * does not exist, it throws an Error.
   * @param {String} id
   * @return {Model}
   */
  async get (id) {
    try {
      const doc = await this.__db.get(id)
      return Model.fromDoc(doc)
    } catch (error) {
      console.error(`Error getting \`${id}\``, error)
      throw error
    }
  }

  /**
   * Returns all the documents of a specific type.
   *
   * Under the hood uses `pouch.allDocs`, which is the recommended way to get several
   * documents.
   * @see {@link https://pouchdb.com/guides/queries.html#avoiding-map-reduce}
   *
   * @param {String} modelType
   * @return {Object}
   */
  async getAllByType (modelType) {
    try {
      const { rows } = await this.__db.allDocs({
        include_docs: true,
        startkey: modelType,
        endkey: `${modelType}\ufff0`
      })
      return rows.map(row => Model.fromDoc(row.doc))
    } catch (error) {
      console.error(`Error getting all documents of type ${modelType}`, error)
      throw error
    }
  }

  /**
   * Perform a query on the db.
   *
   * Currently uses `pouch.allDocs`, although `find` would admit more complex queries.
   * The usage of this method is discouraged. Usually `getAll` is enough.
   * @see {@link https://pouchdb.com/api.html#batch_fetch}
   *
   * @param {Object} query
   * @param {Boolean} query.models - by default this method would return models
   * @return {Object}
   */
  async query (query) {
    try {
      const options = Object.assign({ include_docs: true }, query)
      const result = await this.__db.allDocs(options)
      return result.rows.map(row => Model.fromDoc(row.doc))
    } catch (error) {
      console.error(`Error quering the db with \`${query}\``, error)
      throw error
    }
  }

  /**
   * This method creates a new document on the db.
   * @param {Model} model
   * @return {Model} the updated model (with the revision)
   */
  async create (model) {
    try {
      const { updated, rev } = await this.__db.putIfNotExists(model.doc)

      if (updated) {
        return Model.fromDoc(Object.assign(model.doc, { _rev: rev }))
      }

      throw new Error(`The document \`${model.id}\` already exists`)
    } catch (error) {
      console.error(`Error creating \`${model.id}\``, error)
      throw error
    }
  }

  /**
   * This method replaces a document on the db if it exists or creates a new one.
   * It does not check the revision, so it could add a new revision.
   * @param {Model} model
   * @return {Model} the updated model (with the revision)
   */
  async store (model) {
    try {
      // Store the document, even creating a new revision
      const { ok, rev } = await this.__db.put(model.doc)

      if (ok) {
        return Model.fromDoc(Object.assign(model.doc, { _rev: rev }))
      }

      throw new Error(`Unknown PouchDB error`)
    } catch (error) {
      console.error(`Error storing \`${model.id}\``, error)
      throw error
    }
  }

  /**
   * This method updates a document on the db.
   * It ensures that replacing the document with the last revision.
   * @param {Model} model
   * @return {Model} the updated model (with the revision)
   */
  async update (model) {
    try {
      // Get the last revision to replace that document
      const { _id, _rev } = await this.get(model.id)

      if (_id) {
        const updatedModel = Model.fromDoc(Object.assign(model.doc, { _rev }))
        return this.store(updatedModel)
      }
    } catch (error) {
      if (error.name === 'TypeError') {
        console.error(`Error updating inexistent \`${model.id}\``, error)
        throw new Error(`The document \`${model.id}\` does not exist`)
      } else {
        console.error(`Error updating \`${model.id}\``, error)
        throw error
      }
    }
  }

  /**
   * This method removes a document from the db.
   * @param {Model} model
   * @return {Boolean}
   */
  async delete (model) {
    try {
      // The `remove` method needs the `_id` and the `_rev`, retrieving the model
      // from the db is the best way to be sure that the `_rev` is up-to-date
      const updatedModel = await this.get(model.id)

      if (updatedModel) {
        const { ok } = this.__db.remove(updatedModel.doc)
        return ok
      }
    } catch (error) {
      if (error.name === 'TypeError') {
        console.error(`Error deleting inexistent \`${model.id}\``, error)
        throw new Error(`The document \`${model.id}\` does not exist`)
      } else {
        console.error(`Error deleting \`${model.id}\``, error)
        throw error
      }
    }
  }
}

export default DbInterface
<commit_msg>chore: enable PouchDB debug only when the `DEBUG_POUCHDB` environment variable is set (#216)<commit_after>import PouchDB from 'pouchdb-browser'
import PouchDebug from 'pouchdb-debug'
import PouchUpsert from 'pouchdb-upsert'
import PouchFind from 'pouchdb-find'
import PouchLiveFind from 'pouchdb-live-find'

import Model from '@/models/model'

PouchDB.plugin(PouchDebug)

if (process.env.DEBUG_POUCHDB) {
  PouchDB.debug.enable('*')
} else {
  PouchDB.debug.disable()
}

PouchDB.plugin(PouchUpsert)
PouchDB.plugin(PouchFind)
PouchDB.plugin(PouchLiveFind)

/**
 * This class wraps the PouchDB interface to provide some methods that deal with
 * the revisions (`_rev`) automatically.
 */
class DbInterface {
  /**
   * Creates an instance of DbInterface and the main index
   * @param {String} name
   * @return {DbInterface}
   */
  static create (name) {
    const db = new DbInterface(name)

    db.createIndex('modelType', ['modelType'])

    return db
  }

  /**
   * @param {String} name
   */
  constructor (name) {
    this.__db = new PouchDB(name)
  }

  /**
   * @param {String} name
   * @param {Array} fields
   * @return {Boolean} if the index was created of already exists
   */
  async createIndex (name, fields) {
    try {
      const { result } = await this.__db.createIndex({
        index: { name, fields }
      })
      return result === 'created'
    } catch (error) {
      console.error(`Error creating the index \`${name}\``, error)
      throw error
    }
  }

  /**
   * Finds a document by the id, and returns the associated Model. If the document
   * does not exist, it return `null`
   * @param {String} id
   * @return {(Model|null)}
   */
  async find (id) {
    try {
      const doc = await this.__db.get(id)
      return Model.fromDoc(doc)
    } catch (error) {
      return null
    }
  }

  /**
   * Gets a document by the id, and returns the associated Model. If the document
   * does not exist, it throws an Error.
   * @param {String} id
   * @return {Model}
   */
  async get (id) {
    try {
      const doc = await this.__db.get(id)
      return Model.fromDoc(doc)
    } catch (error) {
      console.error(`Error getting \`${id}\``, error)
      throw error
    }
  }

  /**
   * Returns all the documents of a specific type.
   *
   * Under the hood uses `pouch.allDocs`, which is the recommended way to get several
   * documents.
   * @see {@link https://pouchdb.com/guides/queries.html#avoiding-map-reduce}
   *
   * @param {String} modelType
   * @return {Object}
   */
  async getAllByType (modelType) {
    try {
      const { rows } = await this.__db.allDocs({
        include_docs: true,
        startkey: modelType,
        endkey: `${modelType}\ufff0`
      })
      return rows.map(row => Model.fromDoc(row.doc))
    } catch (error) {
      console.error(`Error getting all documents of type ${modelType}`, error)
      throw error
    }
  }

  /**
   * Perform a query on the db.
   *
   * Currently uses `pouch.allDocs`, although `find` would admit more complex queries.
   * The usage of this method is discouraged. Usually `getAll` is enough.
   * @see {@link https://pouchdb.com/api.html#batch_fetch}
   *
   * @param {Object} query
   * @param {Boolean} query.models - by default this method would return models
   * @return {Object}
   */
  async query (query) {
    try {
      const options = Object.assign({ include_docs: true }, query)
      const result = await this.__db.allDocs(options)
      return result.rows.map(row => Model.fromDoc(row.doc))
    } catch (error) {
      console.error(`Error quering the db with \`${query}\``, error)
      throw error
    }
  }

  /**
   * This method creates a new document on the db.
   * @param {Model} model
   * @return {Model} the updated model (with the revision)
   */
  async create (model) {
    try {
      const { updated, rev } = await this.__db.putIfNotExists(model.doc)

      if (updated) {
        return Model.fromDoc(Object.assign(model.doc, { _rev: rev }))
      }

      throw new Error(`The document \`${model.id}\` already exists`)
    } catch (error) {
      console.error(`Error creating \`${model.id}\``, error)
      throw error
    }
  }

  /**
   * This method replaces a document on the db if it exists or creates a new one.
   * It does not check the revision, so it could add a new revision.
   * @param {Model} model
   * @return {Model} the updated model (with the revision)
   */
  async store (model) {
    try {
      // Store the document, even creating a new revision
      const { ok, rev } = await this.__db.put(model.doc)

      if (ok) {
        return Model.fromDoc(Object.assign(model.doc, { _rev: rev }))
      }

      throw new Error(`Unknown PouchDB error`)
    } catch (error) {
      console.error(`Error storing \`${model.id}\``, error)
      throw error
    }
  }

  /**
   * This method updates a document on the db.
   * It ensures that replacing the document with the last revision.
   * @param {Model} model
   * @return {Model} the updated model (with the revision)
   */
  async update (model) {
    try {
      // Get the last revision to replace that document
      const { _id, _rev } = await this.get(model.id)

      if (_id) {
        const updatedModel = Model.fromDoc(Object.assign(model.doc, { _rev }))
        return this.store(updatedModel)
      }
    } catch (error) {
      if (error.name === 'TypeError') {
        console.error(`Error updating inexistent \`${model.id}\``, error)
        throw new Error(`The document \`${model.id}\` does not exist`)
      } else {
        console.error(`Error updating \`${model.id}\``, error)
        throw error
      }
    }
  }

  /**
   * This method removes a document from the db.
   * @param {Model} model
   * @return {Boolean}
   */
  async delete (model) {
    try {
      // The `remove` method needs the `_id` and the `_rev`, retrieving the model
      // from the db is the best way to be sure that the `_rev` is up-to-date
      const updatedModel = await this.get(model.id)

      if (updatedModel) {
        const { ok } = this.__db.remove(updatedModel.doc)
        return ok
      }
    } catch (error) {
      if (error.name === 'TypeError') {
        console.error(`Error deleting inexistent \`${model.id}\``, error)
        throw new Error(`The document \`${model.id}\` does not exist`)
      } else {
        console.error(`Error deleting \`${model.id}\``, error)
        throw error
      }
    }
  }
}

export default DbInterface
<|endoftext|>


<commit_before>// Protractor configuration file,
// see link for more information https://github.com/angular/protractor/blob/master/lib/config.ts
const {SpecReporter} = require('jasmine-spec-reporter');

const config = {};
const capabilities = {
    browserName: 'chrome',
    chromeOptions: {
        // Use headless Chrome https://github.com/angular/protractor/blob/master/docs/browser-setup.md#using-headless-chrome
        args: [
            '--headless',
            '--disable-gpu',
            '--js-flags=--expose-gc',
            '--no-sandbox'
        ],
        perfLoggingPrefs: {
            traceCategories: 'v8,blink.console,disabled-by-default-devtools.timeline,devtools.timeline'
        }
    },
    loggingPrefs: {
        performance: 'ALL',
        browser: 'ALL'
    }
};

// On Travis we use Saucelabs browsers.
if (process.env.TRAVIS) {
    capabilities.build = `TRAVIS #${process.env.TRAVIS_BUILD_NUMBER} (${process.env.TRAVIS_BUILD_ID})`;
    capabilities['tunnel-identifier'] = process.env.TRAVIS_JOB_NUMBER;
    capabilities.name = 'Angular Lab (E2E)';

    config.sauceUser = process.env.SAUCE_USERNAME;
    config.sauceKey = process.env.SAUCE_ACCESS_KEY;
}

Object.assign(config, {
    capabilities,
    allScriptsTimeout: 120000,
    specs: [
        './e2e/**/*.e2e-spec.ts'
    ],
    // https://github.com/angular/protractor/blob/master/docs/server-setup.md#connecting-directly-to-browser-drivers
    directConnect: !process.env.TRAVIS,
    baseUrl: 'http://localhost:4224/',
    framework: 'jasmine',
    jasmineNodeOpts: {
        showColors: true,
        showTiming: true,
        defaultTimeoutInterval: 120000,
        print: () => {}
    },
    // Option for Angular to test against Angular 2+ applications on the page.
    // Protractor will wait for the app to be stable before each action, and search within all apps when finding elements.
    // rootElement: 'rj-lab',
    // TODO: Use above when https://github.com/angular/protractor/issues/4336 is fixed
    useAllAngular2AppRoots: true,
    // Turn off control flow (https://github.com/angular/protractor/tree/master/exampleTypescript/asyncAwait)
    SELENIUM_PROMISE_MANAGER: false,
    onPrepare: () => {
        // Add jasmine spec reporter
        jasmine.getEnv()
            .addReporter(new SpecReporter({spec: {displayStacktrace: true}}));
        // Include jasmine expect
        require('jasmine-expect');
        // Transpile all TS to JS
        require('ts-node')
            .register({
                project: 'e2e/tsconfig.e2e.json'
            });
    }
});

module.exports = {
    config
};
<commit_msg>chore: remove logging flags from e2e test config<commit_after>// Protractor configuration file,
// see link for more information https://github.com/angular/protractor/blob/master/lib/config.ts
const {SpecReporter} = require('jasmine-spec-reporter');

const config = {};
const capabilities = {
    browserName: 'chrome',
    chromeOptions: {
        // Use headless Chrome https://github.com/angular/protractor/blob/master/docs/browser-setup.md#using-headless-chrome
        args: [
            '--headless',
            '--disable-gpu',
            // '--js-flags=--expose-gc',
            '--no-sandbox'
        ],
        // perfLoggingPrefs: {
        //     traceCategories: 'v8,blink.console,disabled-by-default-devtools.timeline,devtools.timeline'
        // }
    },
    loggingPrefs: {
        performance: 'ALL',
        browser: 'ALL'
    }
};

// On Travis we use Saucelabs browsers.
if (process.env.TRAVIS) {
    capabilities.build = `TRAVIS #${process.env.TRAVIS_BUILD_NUMBER} (${process.env.TRAVIS_BUILD_ID})`;
    capabilities['tunnel-identifier'] = process.env.TRAVIS_JOB_NUMBER;
    capabilities.name = 'Angular Lab (E2E)';

    config.sauceUser = process.env.SAUCE_USERNAME;
    config.sauceKey = process.env.SAUCE_ACCESS_KEY;
}

Object.assign(config, {
    capabilities,
    allScriptsTimeout: 120000,
    specs: [
        './e2e/**/*.e2e-spec.ts'
    ],
    // https://github.com/angular/protractor/blob/master/docs/server-setup.md#connecting-directly-to-browser-drivers
    directConnect: !process.env.TRAVIS,
    baseUrl: 'http://localhost:4224/',
    framework: 'jasmine',
    jasmineNodeOpts: {
        showColors: true,
        showTiming: true,
        defaultTimeoutInterval: 120000,
        print: () => {}
    },
    // Option for Angular to test against Angular 2+ applications on the page.
    // Protractor will wait for the app to be stable before each action, and search within all apps when finding elements.
    // rootElement: 'rj-lab',
    // TODO: Use above when https://github.com/angular/protractor/issues/4336 is fixed
    useAllAngular2AppRoots: true,
    // Turn off control flow (https://github.com/angular/protractor/tree/master/exampleTypescript/asyncAwait)
    SELENIUM_PROMISE_MANAGER: false,
    onPrepare: () => {
        // Add jasmine spec reporter
        jasmine.getEnv()
            .addReporter(new SpecReporter({spec: {displayStacktrace: true}}));
        // Include jasmine expect
        require('jasmine-expect');
        // Transpile all TS to JS
        require('ts-node')
            .register({
                project: 'e2e/tsconfig.e2e.json'
            });
    }
});

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


<commit_before>// Protractor configuration file, see link for more information
// https://github.com/angular/protractor/blob/master/lib/config.ts

/* global jasmine */
const SpecReporter = require('jasmine-spec-reporter');

const config = {};

const argv = require('yargs')
	.wrap(null)
	.usage('Angular Lab E2E test options. Usage: $0 --browsers CHROME_DESKTOP')
	.options({
		browsers: {
			describe: 'Comma separated list of preconfigured browsers to use.',
			default: 'CHROME_DESKTOP',
			type: 'string'
		}
	})
	.help('help')
	.argv;

const capabilities = {
	CHROME_DESKTOP: {
		browserName: 'chrome',
		chromeOptions: {
			'args': ['--js-flags=--expose-gc'],
			'perfLoggingPrefs': {
				'traceCategories': 'v8,blink.console,disabled-by-default-devtools.timeline,devtools.timeline'
			}
		},
		loggingPrefs: {
			performance: 'ALL',
			browser: 'ALL'
		}
	}
};

// On Travis we use Saucelabs browsers.
if (process.env.TRAVIS) {
	Object.keys(capabilities)
		.forEach((key) => {
			capabilities[key].build = `TRAVIS #${process.env.TRAVIS_BUILD_NUMBER} (${process.env.TRAVIS_BUILD_ID})`;
			capabilities[key]['tunnel-identifier'] = process.env.TRAVIS_JOB_NUMBER;
			capabilities[key].name = 'E2E - Angular Lab';
		});

	config.sauceUser = process.env.SAUCE_USERNAME;
	config.sauceKey = process.env.SAUCE_ACCESS_KEY;
}

exports.config = Object.assign(config, {
	allScriptsTimeout: 11000,
	specs: [
		'./e2e/**/*.e2e-spec.ts'
	],
	multiCapabilities: argv.browsers
		.split(',')
		.map((browser) => {
			const caps = capabilities[browser];
			console.log(`Testing against: ${browser}`);

			if (!caps) {
				throw new Error(`There is no browser with name "${browser};" configured.`);
			}
		return caps;
	}),
	directConnect: true,
	baseUrl: `http://localhost:4200/`,
	framework: 'jasmine',
	jasmineNodeOpts: {
		showColors: true,
		defaultTimeoutInterval: 30000,
		print: function () {} // Remove protractor dot reporter
	},
	// Special option for Angular2, to test against all Angular2 applications on the page.
	// This means that Protractor will wait for every app to be stable before each action, and search within all apps when finding elements.
	useAllAngular2AppRoots: true,
	onPrepare: function () {
		// Add jasmine spec reporter
		jasmine.getEnv()
			.addReporter(new SpecReporter({displayStacktrace: 'all'}));
		// Include jasmine expect
		require('jasmine-expect');
	},
	beforeLaunch: function () {
		require('ts-node')
			.register({
				project: 'e2e'
			});
	},
	plugins: [
		{
			package: 'protractor-accessibility-plugin',
			chromeA11YDevTools: {
				treatWarningsAsFailures: true
			}
		},
		{
			package: 'protractor-console-plugin',
			failOnWarning: false,
			failOnError: true,
			logWarnings: true,
			exclude: [
				'info'
			]
		}
	]
});
<commit_msg>chore(e2e): don't fail on warnings<commit_after>// Protractor configuration file, see link for more information
// https://github.com/angular/protractor/blob/master/lib/config.ts

/* global jasmine */
const SpecReporter = require('jasmine-spec-reporter');

const config = {};

const argv = require('yargs')
	.wrap(null)
	.usage('Angular Lab E2E test options. Usage: $0 --browsers CHROME_DESKTOP')
	.options({
		browsers: {
			describe: 'Comma separated list of preconfigured browsers to use.',
			default: 'CHROME_DESKTOP',
			type: 'string'
		}
	})
	.help('help')
	.argv;

const capabilities = {
	CHROME_DESKTOP: {
		browserName: 'chrome',
		chromeOptions: {
			'args': ['--js-flags=--expose-gc'],
			'perfLoggingPrefs': {
				'traceCategories': 'v8,blink.console,disabled-by-default-devtools.timeline,devtools.timeline'
			}
		},
		loggingPrefs: {
			performance: 'ALL',
			browser: 'ALL'
		}
	}
};

// On Travis we use Saucelabs browsers.
if (process.env.TRAVIS) {
	Object.keys(capabilities)
		.forEach((key) => {
			capabilities[key].build = `TRAVIS #${process.env.TRAVIS_BUILD_NUMBER} (${process.env.TRAVIS_BUILD_ID})`;
			capabilities[key]['tunnel-identifier'] = process.env.TRAVIS_JOB_NUMBER;
			capabilities[key].name = 'E2E - Angular Lab';
		});

	config.sauceUser = process.env.SAUCE_USERNAME;
	config.sauceKey = process.env.SAUCE_ACCESS_KEY;
}

exports.config = Object.assign(config, {
	allScriptsTimeout: 11000,
	specs: [
		'./e2e/**/*.e2e-spec.ts'
	],
	multiCapabilities: argv.browsers
		.split(',')
		.map((browser) => {
			const caps = capabilities[browser];
			console.log(`Testing against: ${browser}`);

			if (!caps) {
				throw new Error(`There is no browser with name "${browser};" configured.`);
			}
		return caps;
	}),
	directConnect: true,
	baseUrl: `http://localhost:4200/`,
	framework: 'jasmine',
	jasmineNodeOpts: {
		showColors: true,
		defaultTimeoutInterval: 30000,
		print: function () {} // Remove protractor dot reporter
	},
	// Special option for Angular2, to test against all Angular2 applications on the page.
	// This means that Protractor will wait for every app to be stable before each action, and search within all apps when finding elements.
	useAllAngular2AppRoots: true,
	onPrepare: function () {
		// Add jasmine spec reporter
		jasmine.getEnv()
			.addReporter(new SpecReporter({displayStacktrace: 'all'}));
		// Include jasmine expect
		require('jasmine-expect');
	},
	beforeLaunch: function () {
		require('ts-node')
			.register({
				project: 'e2e'
			});
	},
	plugins: [
		{
			package: 'protractor-accessibility-plugin',
			chromeA11YDevTools: {
				treatWarningsAsFailures: false
			}
		},
		{
			package: 'protractor-console-plugin',
			failOnWarning: false,
			failOnError: true,
			logWarnings: false,
			exclude: [
				'info'
			]
		}
	]
});
<|endoftext|>


<commit_before>/**
 * @providesModule react-native-localytics
 * @flow
 */
import ReactNative from 'react-native';
import invariant from 'fbjs/lib/invariant';

const { NativeModules } = ReactNative;
const VOOLocalytics = NativeModules.VOOLocalytics;

import type {
  CustomerParams,
  ItemParams,
  CheckoutParams,
  Coordinates,
  ContentParams,
  SearchParams,
  ShareParams,
  RatingParams,
  InvitationParams
} from './VOOLocalyticsTypes';

export function tagPurchased(params: ItemParams = {}): void {
  VOOLocalytics.tagPurchased(params);
}
export function tagAddedToCard(params: ItemParams = {}): void {
  VOOLocalytics.tagAddedToCard(params);
}
export function tagStartedCheckout(params: CheckoutParams = {}): void {
  VOOLocalytics.tagStartedCheckout(params);
}
export function tagCompletedCheckout(params: CheckoutParams = {}): void {
  VOOLocalytics.tagCompletedCheckout(params);
}

export function tagCustomerRegistered(params: CustomerParams = {}): void {
  VOOLocalytics.tagCustomerRegistered(params);
}

export function tagCustomerLoggedIn(params: CustomerParams = {}): void {
  VOOLocalytics.tagCustomerLoggedIn(params);
}

export function tagCustomerLoggedOut(params?: Object = {}): void {
  VOOLocalytics.tagCustomerLoggedOut(params);
}

export function tagEvent(eventName: string, attributes?: Object): void {
  invariant(typeof eventName === 'string' && eventName.trim(), 'Event Name has to be specified');
  VOOLocalytics.tagEvent({ eventName, attributes });
}

export function setCustomerId(id: string): void {
  VOOLocalytics.setCustomerId(id);
}

export function setCustomerFirstName(name: string): void {
  VOOLocalytics.setCustomerFirstName(name);
}

export function setCustomerLastName(name: string): void {
  VOOLocalytics.setCustomerLastName(name);
}

export function setCustomerFullName(name: string): void {
  VOOLocalytics.setCustomerFullName(name);
}

export function setCustomerEmail(email: string): void {
  VOOLocalytics.setCustomerEmail(email);
}

export function setLocation(coords: Coordinates): void {
  invariant(
    coords && coords.hasOwnProperty('lng') && coords.hasOwnProperty('lat'),
    'Coordinates has to contain lng and lat'
  );
  VOOLocalytics.setLocation(coords);
}

export function tagContentViewed(content: ContentParams = {}): void {
  VOOLocalytics.tagContentViewed(content);
}

export function tagSearched(search: SearchParams = {}): void {
  VOOLocalytics.tagSearched(search);
}

export function tagShared(search: ShareParams = {}): void {
  VOOLocalytics.tagShared(Share);
}

export function tagContentRated(rating: RatingParams = {}): void {
  VOOLocalytics.tagContentRated(rating);
}

export function tagInvited(method:string, attributes?: Object): void {
  VOOLocalytics.tagInvited({method, attributes});
}<commit_msg>fixed typo in tagShared<commit_after>/**
 * @providesModule react-native-localytics
 * @flow
 */
import ReactNative from 'react-native';
import invariant from 'fbjs/lib/invariant';

const { NativeModules } = ReactNative;
const VOOLocalytics = NativeModules.VOOLocalytics;

import type {
  CustomerParams,
  ItemParams,
  CheckoutParams,
  Coordinates,
  ContentParams,
  SearchParams,
  ShareParams,
  RatingParams,
  InvitationParams
} from './VOOLocalyticsTypes';

export function tagPurchased(params: ItemParams = {}): void {
  VOOLocalytics.tagPurchased(params);
}
export function tagAddedToCard(params: ItemParams = {}): void {
  VOOLocalytics.tagAddedToCard(params);
}
export function tagStartedCheckout(params: CheckoutParams = {}): void {
  VOOLocalytics.tagStartedCheckout(params);
}
export function tagCompletedCheckout(params: CheckoutParams = {}): void {
  VOOLocalytics.tagCompletedCheckout(params);
}

export function tagCustomerRegistered(params: CustomerParams = {}): void {
  VOOLocalytics.tagCustomerRegistered(params);
}

export function tagCustomerLoggedIn(params: CustomerParams = {}): void {
  VOOLocalytics.tagCustomerLoggedIn(params);
}

export function tagCustomerLoggedOut(params?: Object = {}): void {
  VOOLocalytics.tagCustomerLoggedOut(params);
}

export function tagEvent(eventName: string, attributes?: Object): void {
  invariant(typeof eventName === 'string' && eventName.trim(), 'Event Name has to be specified');
  VOOLocalytics.tagEvent({ eventName, attributes });
}

export function setCustomerId(id: string): void {
  VOOLocalytics.setCustomerId(id);
}

export function setCustomerFirstName(name: string): void {
  VOOLocalytics.setCustomerFirstName(name);
}

export function setCustomerLastName(name: string): void {
  VOOLocalytics.setCustomerLastName(name);
}

export function setCustomerFullName(name: string): void {
  VOOLocalytics.setCustomerFullName(name);
}

export function setCustomerEmail(email: string): void {
  VOOLocalytics.setCustomerEmail(email);
}

export function setLocation(coords: Coordinates): void {
  invariant(
    coords && coords.hasOwnProperty('lng') && coords.hasOwnProperty('lat'),
    'Coordinates has to contain lng and lat'
  );
  VOOLocalytics.setLocation(coords);
}

export function tagContentViewed(content: ContentParams = {}): void {
  VOOLocalytics.tagContentViewed(content);
}

export function tagSearched(search: SearchParams = {}): void {
  VOOLocalytics.tagSearched(search);
}

export function tagShared(share: ShareParams = {}): void {
  VOOLocalytics.tagShared(share);
}

export function tagContentRated(rating: RatingParams = {}): void {
  VOOLocalytics.tagContentRated(rating);
}

export function tagInvited(method:string, attributes?: Object): void {
  VOOLocalytics.tagInvited({method, attributes});
}<|endoftext|>


<commit_before>/*global gettext, LayoutManagerFactory, OpManagerFactory, Variable, Wirecloud*/

(function () {

    "use strict";

    /**
     * Specific class for publish windows
     */
    var PublishWorkspaceWindowMenu = function PublishWorkspaceWindowMenu(workspace) {

        var fields, user_name, marketFields;

        user_name = OpManagerFactory.getInstance().contextManager.get('username');
        fields = [
            {
                'type': 'group',
                'shortTitle': gettext('General info'),
                'fields': [
                    {name: 'name', label: gettext('Mashup Name'), type: 'text', required: true, initialValue: workspace.getName(), defaultValue: workspace.getName()},
                    {name: 'vendor', label: gettext('Vendor'), type: 'text',  required: true},
                    {name: 'version', label: gettext('Version'), type: 'version',  required: true},
                    {name: 'email', label: gettext('Email'), type: 'text',  required: true},
                    {name: 'description', label: gettext('Description'), type: 'longtext'},
                    {name: 'doc_uri', label: gettext('Homepage'), type: 'text'},
                    {name: 'author', label: gettext('Author'), type: 'text',  initialValue: user_name, defaultValue: user_name}
                ]
            },
            {
                'type': 'group',
                'shortTitle': gettext('Media'),
                'fields': [
                    {
                        name: 'image',
                        label: gettext('Image shown in catalogue (170x80 px)'),
                        type: 'file'
                    }
                ]
            },
            {
                'type': 'group',
                'shortTitle': gettext('Advanced'),
                'fields': [
                    {name: 'readOnlyWidgets', label: gettext('Block widgets'), type: 'boolean'},
                    {name: 'readOnlyConnectables', label: gettext('Block connections'), type: 'boolean'}
                ]
            }
        ];

        this._addVariableParametrization(workspace, fields);
        Wirecloud.ui.FormWindowMenu.call(this, fields, gettext('Upload workspace to local catalogue'), 'publish_workspace', {autoHide: false});

        //fill a warning message
        var warning = document.createElement('div');
        warning.addClassName('alert');
        warning.innerHTML = gettext("Warning! Configured and stored data in your workspace (properties and preferences except passwords) will be shared by default!");
        this.windowContent.insertBefore(warning, this.form.wrapperElement);
    };
    PublishWorkspaceWindowMenu.prototype = new Wirecloud.ui.FormWindowMenu();

    PublishWorkspaceWindowMenu.prototype._addVariableParametrization = function _addVariableParametrization(workspace, fields) {
        var key, tab_field;

        this.workspace = workspace;

        for (key in workspace.tabInstances) {
            tab_field = this._parseTab(workspace.tabInstances[key]);
            if (tab_field !== null) {
                fields.push(tab_field);
            }
        }
    };

    PublishWorkspaceWindowMenu.prototype._parseTab = function _parseTab(tab) {

        var i, j, name, iwidget, iwidgets, iwidget_params, pref_params,
            prop_params, variable, variables, varManager, var_elements,
            fields;

        varManager = tab.workspace.getVarManager();
        iwidgets = tab.getDragboard().getIWidgets();
        fields = [];

        for (i = 0; i < iwidgets.length; i++) {
            iwidget = iwidgets[i].internal_iwidget;
            variables = varManager.getIWidgetVariables(iwidget.id);
            pref_params = [];
            for (j = 0; j < iwidget.preferenceList.length; j += 1) {
                pref_params.push({
                    label: iwidget.preferenceList[j].label,
                    type: 'parametrizableValue',
                    variable: iwidget.preferenceList[j],
                    canBeHidden: true,
                    parentWindow: this
                });
            }

            prop_params = [];
            for (name in variables) {
                variable = variables[name];
                if (variable.vardef.aspect === Variable.prototype.PROPERTY) {
                    prop_params.push({
                        label: variable.getLabel(),
                        type: 'parametrizableValue',
                        variable: variable,
                        parentWindow: this
                    });
                }
            }

            var_elements = {};
            if (pref_params.length !== 0) {
                var_elements.pref = {
                    label: gettext('Preferences'),
                    type: 'fieldset',
                    fields: pref_params
                };
            }
            if (prop_params.length !== 0) {
                var_elements.props = {
                    label: gettext('Properties'),
                    type: 'fieldset',
                    fields: prop_params.sort(this._sortVariables)
                };
            }

            if (pref_params.length + prop_params.length !== 0) {
                fields.push({
                    name: iwidget.id,
                    label: iwidget.name,
                    type: 'fieldset',
                    nested: true,
                    fields: var_elements
                });
            }
        }

        if (fields.length > 0) {
            return {
                'shortTitle': tab.tabInfo.name,
                'fields': fields,
                'nested': true,
                'name': 'tab-' + tab.tabInfo.name
            };
        } else {
            return null;
        }
    };

    PublishWorkspaceWindowMenu.prototype._sortVariables = function _sortVariables(var1, var2) {
        return var1.variable.vardef.order - var2.variable.vardef.order;
    };

    PublishWorkspaceWindowMenu.prototype.show = function show(parentWindow) {
        Wirecloud.ui.FormWindowMenu.prototype.show.call(this, parentWindow);
        this.setValue(this.workspace.workspaceGlobalInfo.params);
    };

    PublishWorkspaceWindowMenu.prototype.setFocus = function setFocus() {
        this.form.fieldInterfaces.name.focus();
    };

    PublishWorkspaceWindowMenu.prototype.executeOperation = function executeOperation(data) {
        var key;

        data.parametrization = {
            iwidgets: {},
            ioperators: {}
        };

        for (key in data) {
            if (key.startsWith('tab-')) {
                Wirecloud.Utils.merge(data.parametrization.iwidgets, data[key]);
                delete data[key];
            }
        }

        OpManagerFactory.getInstance().activeWorkspace.publish(data, {
            onFailure: function (msg) {
                // TODO
                this.form.pSetMsgs([msg]);
            }.bind(this),
            onSuccess: function () {
                this.hide();
            }.bind(this),
            onComplete: function () {
                this.form.acceptButton.enable();
                this.form.cancelButton.enable();
            }.bind(this)
        });
    };

    Wirecloud.ui.PublishWorkspaceWindowMenu = PublishWorkspaceWindowMenu;
})();
<commit_msg>Fix regressions publishing workspaces<commit_after>/*global gettext, LayoutManagerFactory, OpManagerFactory, Variable, Wirecloud*/

(function () {

    "use strict";

    /**
     * Specific class for publish windows
     */
    var PublishWorkspaceWindowMenu = function PublishWorkspaceWindowMenu(workspace) {

        var fields, user_name, marketFields;

        user_name = OpManagerFactory.getInstance().contextManager.get('username');
        fields = [
            {
                'type': 'group',
                'shortTitle': gettext('General info'),
                'fields': [
                    {name: 'name', label: gettext('Mashup Name'), type: 'text', required: true, initialValue: workspace.getName(), defaultValue: workspace.getName()},
                    {name: 'vendor', label: gettext('Vendor'), type: 'text',  required: true},
                    {name: 'version', label: gettext('Version'), type: 'version',  required: true},
                    {name: 'email', label: gettext('Email'), type: 'text',  required: true},
                    {name: 'description', label: gettext('Description'), type: 'longtext'},
                    {name: 'doc_uri', label: gettext('Homepage'), type: 'text'},
                    {name: 'author', label: gettext('Author'), type: 'text',  initialValue: user_name, defaultValue: user_name}
                ]
            },
            {
                'type': 'group',
                'shortTitle': gettext('Media'),
                'fields': [
                    {
                        name: 'image',
                        label: gettext('Image shown in catalogue (170x80 px)'),
                        type: 'file'
                    }
                ]
            },
            {
                'type': 'group',
                'shortTitle': gettext('Advanced'),
                'fields': [
                    {name: 'readOnlyWidgets', label: gettext('Block widgets'), type: 'boolean'},
                    {name: 'readOnlyConnectables', label: gettext('Block connections'), type: 'boolean'}
                ]
            }
        ];

        this._addVariableParametrization(workspace, fields);
        Wirecloud.ui.FormWindowMenu.call(this, fields, gettext('Upload workspace to local catalogue'), 'publish_workspace', {autoHide: false});

        //fill a warning message
        var warning = document.createElement('div');
        warning.className = 'alert';
        warning.innerHTML = gettext("Warning! Configured and stored data in your workspace (properties and preferences except passwords) will be shared by default!");
        this.windowContent.insertBefore(warning, this.form.wrapperElement);
    };
    PublishWorkspaceWindowMenu.prototype = new Wirecloud.ui.FormWindowMenu();

    PublishWorkspaceWindowMenu.prototype._addVariableParametrization = function _addVariableParametrization(workspace, fields) {
        var key, tab_field;

        this.workspace = workspace;

        for (key in workspace.tabInstances) {
            tab_field = this._parseTab(workspace.tabInstances[key]);
            if (tab_field !== null) {
                fields.push(tab_field);
            }
        }
    };

    PublishWorkspaceWindowMenu.prototype._parseTab = function _parseTab(tab) {

        var i, j, name, iwidget, iwidgets, iwidget_params, pref_params,
            prop_params, variable, variables, varManager, var_elements,
            fields;

        varManager = tab.workspace.getVarManager();
        iwidgets = tab.getDragboard().getIWidgets();
        fields = [];

        for (i = 0; i < iwidgets.length; i++) {
            iwidget = iwidgets[i].internal_iwidget;
            variables = varManager.getIWidgetVariables(iwidget.id);
            pref_params = [];
            for (j = 0; j < iwidget.preferenceList.length; j += 1) {
                pref_params.push({
                    label: iwidget.preferenceList[j].label,
                    type: 'parametrizableValue',
                    variable: iwidget.preferenceList[j],
                    canBeHidden: true,
                    parentWindow: this
                });
            }

            prop_params = [];
            for (name in variables) {
                variable = variables[name];
                if (variable.vardef.aspect === Variable.prototype.PROPERTY) {
                    prop_params.push({
                        label: variable.getLabel(),
                        type: 'parametrizableValue',
                        variable: variable,
                        parentWindow: this
                    });
                }
            }

            var_elements = {};
            if (pref_params.length !== 0) {
                var_elements.pref = {
                    label: gettext('Preferences'),
                    type: 'fieldset',
                    fields: pref_params
                };
            }
            if (prop_params.length !== 0) {
                var_elements.props = {
                    label: gettext('Properties'),
                    type: 'fieldset',
                    fields: prop_params.sort(this._sortVariables)
                };
            }

            if (pref_params.length + prop_params.length !== 0) {
                fields.push({
                    name: iwidget.id,
                    label: iwidget.name,
                    type: 'fieldset',
                    nested: true,
                    fields: var_elements
                });
            }
        }

        if (fields.length > 0) {
            return {
                'shortTitle': tab.tabInfo.name,
                'fields': fields,
                'nested': true,
                'name': 'tab-' + tab.tabInfo.name
            };
        } else {
            return null;
        }
    };

    PublishWorkspaceWindowMenu.prototype._sortVariables = function _sortVariables(var1, var2) {
        return var1.variable.vardef.order - var2.variable.vardef.order;
    };

    PublishWorkspaceWindowMenu.prototype.setFocus = function setFocus() {
        this.form.fieldInterfaces.name.focus();
    };

    PublishWorkspaceWindowMenu.prototype.executeOperation = function executeOperation(data) {
        var key;

        data.parametrization = {
            iwidgets: {},
            ioperators: {}
        };

        for (key in data) {
            if (key.startsWith('tab-')) {
                Wirecloud.Utils.merge(data.parametrization.iwidgets, data[key]);
                delete data[key];
            }
        }

        OpManagerFactory.getInstance().activeWorkspace.publish(data, {
            onFailure: function (msg) {
                // TODO
                this.form.pSetMsgs([msg]);
            }.bind(this),
            onSuccess: function () {
                this.hide();
            }.bind(this),
            onComplete: function () {
                this.form.acceptButton.enable();
                this.form.cancelButton.enable();
            }.bind(this)
        });
    };

    Wirecloud.ui.PublishWorkspaceWindowMenu = PublishWorkspaceWindowMenu;
})();
<|endoftext|>


<commit_before>var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000 );
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );

var cubeGeo = new THREE.BoxGeometry(1, 1, 1);

var size = 501;
var divisions = 501;

var gridHelper = new THREE.GridHelper( size, divisions );
scene.add( gridHelper );

camera.position.z = 100;
camera.position.y = 100;
camera.rotation.x = -Math.PI/4;

var light = new THREE.AmbientLight(0x404040);
scene.add(light);

document.addEventListener('keyup', keyUp, false);
document.addEventListener('keydown', keyDown, false);
function keyUp(event) {
  key[event.which || event.keyCode] = false;
}
function keyDown(event) {
  key[event.which || event.keyCode] = true;
//console.log(event.which);
}
var rotation = 0;
var key = {
check: () => {
  //put things that happen while keys are pushed here
}
}

const alien  = class{
  constructor(c,x,z){
    this.mat = new THREE.MeshBasicMaterial({color:c, wireframe:false});
    this.mesh = new THREE.Mesh(cubeGeo,this.mat);
    scene.add(this.mesh);
    this.mesh.position.x = x;
    this.mesh.position.z = z;
    this.mesh.position.y = 0.5;
  }
  move(x,z){
    this.mesh.position.x += x;
    this.mesh.position.z += z;
  }
  kill(){
    scene.remove(this.mesh);
  }
};

function tick(){
  /*cubeMesh.position.x += 0.01;
  cubeMesh.position.z += 0.01;*/
  key.check();

  //camera.rotation.y = 0;
  /*THE CAMERA CURRENTLY DOESNT WORK
  camera.position.z = 5*Math.cos((rotation*Math.PI)/180);
  camera.position.x = 5*Math.sin((rotation*Math.PI)/180);
  camera.rotation.x = 0;
 camera.rotation.y = (rotation*Math.PI)/180;
 camera.rotation.x = -Math.PI/4;
*/
  //this needs to be fixed
/*  camera.rotation.x = (rotation*Math.PI)/180;
  camera.rotation.z = -(rotation*Math.PI)/180;*/
  //console.log('tick');
  renderer.render(scene,camera);
}
var interval = setInterval(tick,30);
<commit_msg>formattig<commit_after>var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000 );
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

var cubeGeo = new THREE.BoxGeometry(0.9, 0.9, 0.9);

var size = 501;
var divisions = 501;

var gridHelper = new THREE.GridHelper(size, divisions);
scene.add(gridHelper);

camera.position.z = 100;
camera.position.y = 100;
camera.rotation.x = -Math.PI/4;

var light = new THREE.AmbientLight(0x404040);
scene.add(light);

document.addEventListener('keyup', keyUp, false);
document.addEventListener('keydown', keyDown, false);
function keyUp(event) {
  key[event.which || event.keyCode] = false;
}
function keyDown(event) {
  key[event.which || event.keyCode] = true;
//console.log(event.which);
}
var rotation = 0;
var key = {
check: () => {
  //put things that happen while keys are pushed here
}
}

const alien  = class{
  constructor(c,x,z){
    this.mat = new THREE.MeshBasicMaterial({color:c, wireframe:false});
    this.mesh = new THREE.Mesh(cubeGeo,this.mat);
    scene.add(this.mesh);
    this.mesh.position.x = x;
    this.mesh.position.z = z;
    this.mesh.position.y = 0.5;
  }
  move(x,z){
    this.mesh.position.x += x;
    this.mesh.position.z += z;
  }
  kill(){
    scene.remove(this.mesh);
  }
};

function tick(){
  /*cubeMesh.position.x += 0.01;
  cubeMesh.position.z += 0.01;*/
  key.check();

  //camera.rotation.y = 0;
  /*THE CAMERA CURRENTLY DOESNT WORK
  camera.position.z = 5*Math.cos((rotation*Math.PI)/180);
  camera.position.x = 5*Math.sin((rotation*Math.PI)/180);
  camera.rotation.x = 0;
 camera.rotation.y = (rotation*Math.PI)/180;
 camera.rotation.x = -Math.PI/4;
*/
  //this needs to be fixed
/*  camera.rotation.x = (rotation*Math.PI)/180;
  camera.rotation.z = -(rotation*Math.PI)/180;*/
  //console.log('tick');
  renderer.render(scene,camera);
}
var interval = setInterval(tick,30);
<|endoftext|>


<commit_before>#!/usr/bin/env node

'use strict';

const mkdirp = require('mkdirp');

const https = require('follow-redirects').https;

const boxen = require('boxen');

const fs = require('fs');

const colors = require('colors/safe');

const argv = require('yargs')

	.usage(colors.cyan.bold('\nUsage : $0 <command> [info] <option> [info]          '))

	.command('u', colors.cyan.bold(' ❱ ') + ' instagram username  ❱❱  For HD image')

	.command('m', colors.cyan.bold(' ❱ ') + ' instagram username  ❱❱  For medium image')

	.command('w', colors.cyan.bold(' ❱ ') + ' instagram username  ❱❱  For small image')

	.command('l', colors.cyan.bold(' ❱ ') + ' full link to download image')

	.command('v', colors.cyan.bold(' ❱ ') + ' full link to download video')

	.demand(['n'])

	.describe('n', colors.cyan.bold('❱') + '  save image or video as      ')

    .example('$0 -u [user-name] -n [image-name]')

    .example('$0 -l [imageLink] -n [image-name]')

    .example('$0 -v [videoLink] -n [video-name]')

	.argv;

const options = {

	hostname: 'www.instagram.com',

	port: 443,

	path: '/' + argv.u,

	method: 'GET',

	headers: {

		'accept': 'text/html,application/json,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',

		'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36',

		'Host': 'www.instagram.com',

		'Connection': 'Keep-Alive',

		'Accept-Language': 'en-GB,en-US;q=0.8,en;q=0.6'

	}

};

const saveImage = './Instagram/';

const removeSlash = saveImage.replace('./', '');

const savedIn = removeSlash.replace('/', '');

mkdirp(removeSlash, err => {
	if (err) {
		console.log(colors.red.bold('\n ❱ Directory Created      :    ✖\n'));

		process.exit(1);
	} else {
		/* no need */
	}
});

// for checking whether the remote image is available in high resolution or not.
function detectFullSize(urls) {
	// checking the small size image.
	const matchURL = urls.match(/150/g);

	// available pixels
	const badCase = null;

	const checkURL = matchURL;

	// storing pixel in array
	const arrIndex = ['150'];

	// checking if the pixles is available in the link
	if (badCase === checkURL) {
		return ['notHD'];

		// because matchURL gives output in array
	} else if (matchURL[0] === arrIndex[0]) {
		return ['HD'];
	}
}

// parsing images based on the resolution obtained.
function redefineLink(contentLinks) {
	const findPattern = contentLinks.match(/150/g);

	// null because
	const nullFire = null;

	// finding the least resolution provided by instagram.
	const gotPattern = ['150'];

	// not all profile pictures are available on HD
	if (nullFire === findPattern) {
		// if pixel is missing
		return contentLinks.replace('\\', '').replace('\\', '').replace('\\', '').replace('\\', '').replace('\\', '');
	} else if (findPattern[0] === gotPattern[0]) {
		// if pixel is available
		return contentLinks.replace('/s150x150', '').replace('\\', '').replace('\\', '').replace('\\', '').replace('\\', '').replace('\\', '').replace('\\', '');
	}
}

// checking if the given argument is an URL or not
function checkURL(baseURL) {
	const canValid = baseURL.match(/instagram.com/g);

	const rareCase = null;

	const mainValid = ['instagram.com'];

	if (canValid === rareCase) {
		return ['URL is not valid'];
	} else if (canValid[0] === mainValid[0]) {
		return ['URL is valid'];
	}
}

function checkInternet(cb) {
	require('dns').lookup('instagram.com', err => {
		if (err && err.code === 'ENOTFOUND') {
			cb(false);
		} else {
			cb(true);
		}
	});
}

// checking internet connection
checkInternet(isConnected => {
	if (isConnected) {
		console.log(colors.cyan.bold('\n ❱ Internet Connection   :    ✔\n'));
	} else {
		// stop the whole process if the network is unreachable
		console.log(colors.red.bold('\n ❱ Internet Connection   :    ✖\n'));

		process.exit(1);
	}
});

if (argv.u) {
	const req = https.request(options, res => {
		if (res.statusCode === 200) {
			console.log(colors.cyan.bold(' ❱ Valid Username        :    ✔'));

			setTimeout(() => {
				mkdirp(removeSlash, err => {
					if (err) {
						// optional
						console.log(colors.red.bold(boxen('Sorry! Couldn\'t create the desired directory')));
					} else {
						/* do nothing */
					}
				});
			}, 1500);
		} else {
			// stopping the whole process if the username is invalid
			console.log(colors.red.bold(' ❱ Valid Username        :    ✖\n'));

			process.exit(1);
		}

		let store = '';

		res.setEncoding = 'utf8';

		res.on('data', d => {
			store += d;
		});

		res.on('end', () => {
			const imagePattern = new RegExp(/profile_pic_url":"[a-zA-Z://\\-a-zA-Z.0-9\\-a-zA-Z.0-9]*/);
			// regex to match the parsed image patterns.

			const regMatches = store.match(imagePattern);

			// [0] because we need only one link
			if (regMatches && regMatches[0]) {
				const imageLink = regMatches[0].replace('profile_pic_url":"', '');

				// storing func's output in a variable.
				const imageHD = detectFullSize(imageLink);

				// stroing initial HD'ed image in array
				const hdArray = ['HD'];

				// storing initial notHD'ed image in array
				const notHDArray = ['notHD'];

				if (hdArray[0] === imageHD[0]) {
					// because initiall imageHD shows output in array ['150', '150'] and null
					console.log(colors.cyan.bold('\n ❱ Image Resolution      :    ✔\n'));

					// if case is null
				} else if (notHDArray[0] === imageHD[0]) {
					console.log(colors.red.bold('\n ❱ Image Resolution      :    ✖\n'));
				}

				// using previously made function
				const remChars = redefineLink(imageLink);

				// saving image
				const imageFile = fs.createWriteStream(removeSlash + argv.n + '.jpg');

				// downloading image
				https.get(remChars, res => {
					res.pipe(imageFile);

					console.log(colors.cyan.bold(' ❱ Image Saved In        : '), ' ', colors.green.bold(savedIn), colors.cyan.bold('❱'), colors.green.bold(argv.n + '.jpg\n'));
				}).on('error', err => {
					console.log(err);

					console.log('❱ Failed to Save the image');

					process.exit(1);
				});
			}
		});
	});
	req.end();
}

if (argv.l) {
	const getNodeImage = argv.l;

	const verifyLink = checkURL(argv.l);

	const unvarLink = ['URL is not valid'];

	if (verifyLink[0] === unvarLink[0]) {
		console.log(colors.red.bold('\n ❱ Valid Link          :      ✖\n'));

		process.exit(1);
	}
	const reqImages = https.request(getNodeImage, res => {
		if (res.statusCode === 200) {
			console.log(colors.cyan.bold(' ❱ Public Image          :    ✔\n'));

			setTimeout(() => {
				mkdirp(removeSlash, err => {
					if (err) {
						// optional
						console.log(colors.red.bold(boxen('Sorry! Couldn\'t create the desired directory')));
					} else {
					/* do nothing */
					}
				});
			}, 1500);
		} else {
			// stopping the whole process if the username is invalid
			console.log(colors.red.bold(' ❱ Public Image          :    ✖\n'));

			process.exit(1);
		}

		let storePublic = '';

		res.setEncoding = 'utf8';

		res.on('data', d => {
			storePublic += d;
		});
		res.on('end', () => {
			const imagePublicPattern = new RegExp(/display_src":"[a-zA-Z://\\-a-zA-Z.0-9\\-a-zA-Z.0-9]*/);
			// regex to match the parsed image patterns.
			const regMatches = storePublic.match(imagePublicPattern);
			// [0] because we need only one link
			if (regMatches && regMatches[0]) {
				const imageLink = regMatches[0].replace('display_src":"', '');

				// using previously made function
				const remChars = redefineLink(imageLink);

				// saving image
				const imageFile = fs.createWriteStream(removeSlash + argv.n + '.jpg');

				// downloading image
				https.get(remChars, res => {
					res.pipe(imageFile);

					console.log(colors.cyan.bold(' ❱ Image Saved In        : '), ' ', colors.green.bold(savedIn), colors.cyan.bold('❱'), colors.green.bold(argv.n + '.jpg\n'));
				}).on('error', err => {
					console.log(err);

					console.log('\n ❱ Failed to Save the image');

					process.exit(1);
				});
			}
		});
	});
	reqImages.end();
}

if (argv.v) {
	const getNodeVideo = argv.v;

	const verifyVideoLink = checkURL(argv.v);

	const unvarVideoLink = ['URL is not valid'];

	if (verifyVideoLink[0] === unvarVideoLink[0]) {
		console.log(colors.red.bold('\n ❱ Valid Link          :      ✖\n'));

		process.exit(1);
	}

	const reqVideo = https.request(getNodeVideo, res => {
		if (res.statusCode === 200) {
			console.log(colors.cyan.bold(' ❱ Public Video          :    ✔'));

			setTimeout(() => {
				mkdirp(removeSlash, err => {
					if (err) {
						// optional
						console.log(colors.red.bold(boxen('Sorry! Couldn\'t create the desired directory')));
					} else {
						/* do nothing */
					}
				});
			}, 1500);
		} else {
			// stopping the whole process if the username is invalid
			console.log(colors.red.bold(' ❱ Public Video          :    ✖ | Invalid Link\n'));
			process.exit(1);
		}

		let storeVideo = '';

		res.setEncoding = 'utf8';

		res.on('data', d => {
			storeVideo += d;
		});
		res.on('end', () => {
			const videoPattern = new RegExp(/video_url":"[a-zA-Z://\\-a-zA-Z.0-9\\-a-zA-Z.0-9]*/);
			// regex to match the parsed image patterns.
			const regMatches = storeVideo.match(videoPattern);
			// [0] because we need only one link
			if (regMatches && regMatches[0]) {
				const imageLink = regMatches[0].replace('video_url":"', '');

				// using previously made function
				const remChars = redefineLink(imageLink);

				// saving image
				const videoFile = fs.createWriteStream(removeSlash + argv.n + '.mp4');

				// downloading image
				https.get(remChars, res => {
					res.pipe(videoFile);

					console.log(colors.cyan.bold('\n ❱ Video Saved In        : '), ' ', colors.green.bold(savedIn), colors.cyan.bold('❱'), colors.green.bold(argv.n + '.mp4\n'));
				}).on('error', err => {
					console.log(err);

					console.log('\n ❱ Failed to Save the video');

					process.exit(1);
				});
			}
		});
	});
	reqVideo.end();
}
<commit_msg>executable<commit_after>#!/usr/bin/env node

'use strict';

const mkdirp = require('mkdirp');

const https = require('follow-redirects').https;

const boxen = require('boxen');

const fs = require('fs');

const colors = require('colors/safe');

const argv = require('yargs')

	.usage(colors.cyan.bold('\nUsage : $0 <command> [info] <option> [info]          '))

	.command('u', colors.cyan.bold(' ❱ ') + ' instagram username  ❱❱  For HD image')

	.command('m', colors.cyan.bold(' ❱ ') + ' instagram username  ❱❱  For medium image')

	.command('w', colors.cyan.bold(' ❱ ') + ' instagram username  ❱❱  For small image')

	.command('l', colors.cyan.bold(' ❱ ') + ' full link to download image')

	.command('v', colors.cyan.bold(' ❱ ') + ' full link to download video')

	.demand(['n'])

	.describe('n', colors.cyan.bold('❱') + '  save image or video as      ')

    .example('$0 -u [user-name] -n [image-name]')

    .example('$0 -l [imageLink] -n [image-name]')

    .example('$0 -v [videoLink] -n [video-name]')

	.argv;

const options = {

	hostname: 'www.instagram.com',

	port: 443,

	path: '/' + argv.u,

	method: 'GET',

	headers: {

		'accept': 'text/html,application/json,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',

		'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36',

		'Host': 'www.instagram.com',

		'Connection': 'Keep-Alive',

		'Accept-Language': 'en-GB,en-US;q=0.8,en;q=0.6'

	}

};

const saveImage = './Instagram/';

const removeSlash = saveImage.replace('./', '');

const savedIn = removeSlash.replace('/', '');

mkdirp(removeSlash, err => {
	if (err) {
		console.log(colors.red.bold('\n ❱ Directory Created      :    ✖\n'));

		process.exit(1);
	} else {
		/* no need */
	}
});

// for checking whether the remote image is available in high resolution or not.
function detectFullSize(urls) {
	// checking the small size image.
	const matchURL = urls.match(/150/g);

	// available pixels
	const badCase = null;

	const checkURL = matchURL;

	// storing pixel in array
	const arrIndex = ['150'];

	// checking if the pixles is available in the link
	if (badCase === checkURL) {
		return ['notHD'];

		// because matchURL gives output in array
	} else if (matchURL[0] === arrIndex[0]) {
		return ['HD'];
	}
}

// parsing images based on the resolution obtained.
function redefineLink(contentLinks) {
	const findPattern = contentLinks.match(/150/g);

	// null because
	const nullFire = null;

	// finding the least resolution provided by instagram.
	const gotPattern = ['150'];

	// not all profile pictures are available on HD
	if (nullFire === findPattern) {
		// if pixel is missing
		return contentLinks.replace('\\', '').replace('\\', '').replace('\\', '').replace('\\', '').replace('\\', '');
	} else if (findPattern[0] === gotPattern[0]) {
		// if pixel is available
		return contentLinks.replace('/s150x150', '').replace('\\', '').replace('\\', '').replace('\\', '').replace('\\', '').replace('\\', '').replace('\\', '');
	}
}

// checking if the given argument is an URL or not
function checkURL(baseURL) {
	const canValid = baseURL.match(/instagram.com/g);

	const rareCase = null;

	const mainValid = ['instagram.com'];

	if (canValid === rareCase) {
		return ['URL is not valid'];
	} else if (canValid[0] === mainValid[0]) {
		return ['URL is valid'];
	}
}

function checkInternet(cb) {
	require('dns').lookup('instagram.com', err => {
		if (err && err.code === 'ENOTFOUND') {
			cb(false);
		} else {
			cb(true);
		}
	});
}

// checking internet connection
checkInternet(isConnected => {
	if (isConnected) {
		console.log(colors.cyan.bold('\n ❱ Internet Connection   :    ✔\n'));
	} else {
		// stop the whole process if the network is unreachable
		console.log(colors.red.bold('\n ❱ Internet Connection   :    ✖\n'));

		process.exit(1);
	}
});

if (argv.u) {
	const req = https.request(options, res => {
		if (res.statusCode === 200) {
			console.log(colors.cyan.bold(' ❱ Valid Username        :    ✔'));

			setTimeout(() => {
				mkdirp(removeSlash, err => {
					if (err) {
						// optional
						console.log(colors.red.bold(boxen('Sorry! Couldn\'t create the desired directory')));
					} else {
						/* do nothing */
					}
				});
			}, 1500);
		} else {
			// stopping the whole process if the username is invalid
			console.log(colors.red.bold(' ❱ Valid Username        :    ✖\n'));

			process.exit(1);
		}

		let store = '';

		res.setEncoding = 'utf8';

		res.on('data', d => {
			store += d;
		});

		res.on('end', () => {
			const imagePattern = new RegExp(/profile_pic_url":"[a-zA-Z://\\-a-zA-Z.0-9\\-a-zA-Z.0-9]*/);
			// regex to match the parsed image patterns.

			const regMatches = store.match(imagePattern);

			// [0] because we need only one link
			if (regMatches && regMatches[0]) {
				const imageLink = regMatches[0].replace('profile_pic_url":"', '');

				// storing func's output in a variable.
				const imageHD = detectFullSize(imageLink);

				// stroing initial HD'ed image in array
				const hdArray = ['HD'];

				// storing initial notHD'ed image in array
				const notHDArray = ['notHD'];

				if (hdArray[0] === imageHD[0]) {
					// because initiall imageHD shows output in array ['150', '150'] and null
					console.log(colors.cyan.bold('\n ❱ Image Resolution      :    ✔\n'));

					// if case is null
				} else if (notHDArray[0] === imageHD[0]) {
					console.log(colors.red.bold('\n ❱ Image Resolution      :    ✖\n'));
				}

				// using previously made function
				const remChars = redefineLink(imageLink);

				// saving image
				const imageFile = fs.createWriteStream(removeSlash + argv.n + '.jpg');

				// downloading image
				https.get(remChars, res => {
					res.pipe(imageFile);

					console.log(colors.cyan.bold(' ❱ Image Saved In        : '), ' ', colors.green.bold(savedIn), colors.cyan.bold('❱'), colors.green.bold(argv.n + '.jpg\n'));
				}).on('error', err => {
					console.log(err);

					console.log('❱ Failed to Save the image');

					process.exit(1);
				});
			}
		});
	});
	req.end();
}

if (argv.l) {
	const getNodeImage = argv.l;

	const verifyLink = checkURL(argv.l);

	const unvarLink = ['URL is not valid'];

	if (verifyLink[0] === unvarLink[0]) {
		console.log(colors.red.bold('\n ❱ Valid Link          :      ✖\n'));

		process.exit(1);
	}
	const reqImages = https.request(getNodeImage, res => {
		if (res.statusCode === 200) {
			console.log(colors.cyan.bold(' ❱ Public Image          :    ✔\n'));

			setTimeout(() => {
				mkdirp(removeSlash, err => {
					if (err) {
						// optional
						console.log(colors.red.bold(boxen('Sorry! Couldn\'t create the desired directory')));
					} else {
					/* do nothing */
					}
				});
			}, 1500);
		} else {
			// stopping the whole process if the username is invalid
			console.log(colors.red.bold(' ❱ Public Image          :    ✖\n'));

			process.exit(1);
		}

		let storePublic = '';

		res.setEncoding = 'utf8';

		res.on('data', d => {
			storePublic += d;
		});
		res.on('end', () => {
			const imagePublicPattern = new RegExp(/display_src":"[a-zA-Z://\\-a-zA-Z.0-9\\-a-zA-Z.0-9]*/);
			// regex to match the parsed image patterns.
			const regMatches = storePublic.match(imagePublicPattern);
			// [0] because we need only one link
			if (regMatches && regMatches[0]) {
				const imageLink = regMatches[0].replace('display_src":"', '');

				// using previously made function
				const remChars = redefineLink(imageLink);

				// saving image
				const imageFile = fs.createWriteStream(removeSlash + argv.n + '.jpg');

				// downloading image
				https.get(remChars, res => {
					res.pipe(imageFile);

					console.log(colors.cyan.bold(' ❱ Image Saved In        : '), ' ', colors.green.bold(savedIn), colors.cyan.bold('❱'), colors.green.bold(argv.n + '.jpg\n'));
				}).on('error', err => {
					console.log(err);

					console.log('\n ❱ Failed to Save the image');

					process.exit(1);
				});
			}
		});
	});
	reqImages.end();
}

if (argv.v) {
	const getNodeVideo = argv.v;

	const verifyVideoLink = checkURL(argv.v);

	const unvarVideoLink = ['URL is not valid'];

	if (verifyVideoLink[0] === unvarVideoLink[0]) {
		console.log(colors.red.bold('\n ❱ Valid Link          :      ✖\n'));

		process.exit(1);
	}

	const reqVideo = https.request(getNodeVideo, res => {
		if (res.statusCode === 200) {
			console.log(colors.cyan.bold(' ❱ Public Video          :    ✔'));

			setTimeout(() => {
				mkdirp(removeSlash, err => {
					if (err) {
						// optional
						console.log(colors.red.bold(boxen('Sorry! Couldn\'t create the desired directory')));
					} else {
						/* do nothing */
					}
				});
			}, 1500);
		} else {
			// stopping the whole process if the username is invalid
			console.log(colors.red.bold(' ❱ Public Video          :    ✖ | Invalid Link\n'));
			process.exit(1);
		}

		let storeVideo = '';

		res.setEncoding = 'utf8';

		res.on('data', d => {
			storeVideo += d;
		});
		res.on('end', () => {
			const videoPattern = new RegExp(/video_url":"[a-zA-Z://\\-a-zA-Z.0-9\\-a-zA-Z.0-9]*/);
			// regex to match the parsed image patterns.
			const regMatches = storeVideo.match(videoPattern);
			// [0] because we need only one link
			if (regMatches && regMatches[0]) {
				const imageLink = regMatches[0].replace('video_url":"', '');

				// using previously made function
				const remChars = redefineLink(imageLink);

				// saving image
				const videoFile = fs.createWriteStream(removeSlash + argv.n + '.mp4');

				// downloading image
				https.get(remChars, res => {
					res.pipe(videoFile);

					console.log(colors.cyan.bold('\n ❱ Video Saved In        : '), ' ', colors.green.bold(savedIn), colors.cyan.bold('❱'), colors.green.bold(argv.n + '.mp4\n'));
				}).on('error', err => {
					console.log(err);

					console.log('\n ❱ Failed to Save the video');

					process.exit(1);
				});
			}
		});
	});
	reqVideo.end();
}
<|endoftext|>


<commit_before>"use strict";

var obj = { size: 20 };

// @boop(obj, "blue", true)
export default function CustomStuff() {
    this.showSomethign = () => {
        console.log("show something!");
    };
}
<commit_msg>Make jshint happy w/ unused var in sample module.<commit_after>"use strict";

var obj = { size: 20 };

// @boop(obj, "blue", true)
export default function CustomStuff() {
    this.showSomethign = () => {
        console.log("show something!");
    };
}

console.log(obj); // To make jshint happy.
<|endoftext|>