<commit_before>const JOIN = 'join',
DISMISS = 'dismiss',
STOP = 'stop',
Context = require('./context/Context'),
Reverse = require('./context/Reverse');

function get_context (type,_context,...args) {
    var i =0,j,ln,parts,part,strings,
    name,fn,timeout,context,resolve,reject;

    if (args && args.length) {
        if (Array.isArray(args[i])) {
            name = '';
            strings = args[i];
            parts = args.slice(i+1);
            for (i=0,j=0,ln=strings.length;i<ln;i++) {
                name += strings[i] + ((part = parts[j++]) !== undefined ? part : '');
            }
        } else {
            if (typeof args[i] === 'string' || typeof args[i] === 'symbol') {
                name = args[i++];
            }
            if (typeof args[i] === 'function') {
                fn = args[i++];
            }
            timeout = args[i] | 0;
        }
    }

    context = new _context(function (res,rej) {
        resolve = res;
        reject = rej;
    });

    context.init({
        name,
        timeout,
        reject,
        resolve,
        fn,
        type
    });

    if (type && typeof fn === 'function') {
        context[type](fn,timeout);
    }

    if (strings) {
        return  (...args) => context[type](...args);
    }

    return context;
};

function block (...args) {
    return get_context(DISMISS,Context,...args)
}
block.join = function (...args) {
    return get_context(JOIN,Context,...args)
};
block.stop = function (...args) {
    return get_context(STOP,Context,...args);
};
block.dismiss = function (...args) {
    return get_context(DISMISS,Context,...args);
};
block.reverse = function (...args) {
    return get_context(DISMISS,Reverse,...args);
};
block.reverse.join = block.join.reverse = function (...args) {
    return get_context(JOIN,Reverse,...args);
};
block.reverse.stop = block.stop.reverse = function (...args) {
    return get_context(STOP,Reverse,...args);
};
block.reverse.dismiss = block.dismiss.reverse = function (...args) {
    return get_context(DISMISS,Reverse,...args);
};

module.exports = block;

<commit_msg>update libs/index<commit_after>const JOIN = 'join',
DISMISS = 'dismiss',
STOP = 'stop',
Context = require('./context/Context'),
Reverse = require('./context/Reverse');

function get_context (type,_context,...args) {
    var i =0,j,ln,parts,part,strings,
    name,fn,timeout,context,resolve,reject;

    if (args && args.length) {
        if (Array.isArray(args[i])) {
            name = '';
            strings = args[i];
            parts = args.slice(i+1);
            for (i=0,j=0,ln=strings.length;i<ln;i++) {
                name += strings[i] + ((part = parts[j++]) !== undefined ? part : '');
            }
        } else {
            if (typeof args[i] === 'string' || typeof args[i] === 'symbol') {
                name = args[i++];
            }
            if (typeof args[i] === 'function' || args[i] instanceof Promise) {
                fn = args[i++];
            }
            timeout = args[i] | 0;
        }
    }

    context = new _context(function (res,rej) {
        resolve = res;
        reject = rej;
    });

    context.init({
        name,
        timeout,
        reject,
        resolve,
        fn,
        type
    });

    if (type && fn) {
        context[type](fn,timeout);
    }

    if (strings) {
        return  (...args) => context[type](...args);
    }

    return context;
};

function block (...args) {
    return get_context(DISMISS,Context,...args)
}
block.join = function (...args) {
    return get_context(JOIN,Context,...args)
};
block.stop = function (...args) {
    return get_context(STOP,Context,...args);
};
block.dismiss = function (...args) {
    return get_context(DISMISS,Context,...args);
};
block.reverse = function (...args) {
    return get_context(DISMISS,Reverse,...args);
};
block.reverse.join = block.join.reverse = function (...args) {
    return get_context(JOIN,Reverse,...args);
};
block.reverse.stop = block.stop.reverse = function (...args) {
    return get_context(STOP,Reverse,...args);
};
block.reverse.dismiss = block.dismiss.reverse = function (...args) {
    return get_context(DISMISS,Reverse,...args);
};

module.exports = block;

<|endoftext|>


<commit_before>/*
 * OpenSeadragon - IIIFTileSource
 *
 * Copyright (C) 2009 CodePlex Foundation
 * Copyright (C) 2010-2013 OpenSeadragon contributors
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * - Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 *
 * - Neither the name of CodePlex Foundation nor the names of its
 *   contributors may be used to endorse or promote products derived from
 *   this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * The getTileUrl implementation is based on Jon Stroop's Python version,
 * which is released under the New BSD license:
 * https://gist.github.com/jpstroop/4624253
 */

(function( $ ){

/**
 * A client implementation of the International Image Interoperability
 * Format: Image API Draft 0.2 - Please read more about the specification
 * at
 *
 * @class
 * @extends OpenSeadragon.TileSource
 * @see http://library.stanford.edu/iiif/image-api/
 */
$.IIIFTileSource = function( options ){

    $.extend( true, this, options );

    if( !(this.height && this.width && this.identifier && this.tilesUrl ) ){
        throw new Error('IIIF required parameters not provided.');
    }

    //TODO: at this point the base tile source implementation assumes
    //      a tile is a square and so only has one property tileSize
    //      to store it.  It may be possible to make tileSize a vector
    //      OpenSeadraon.Point but would require careful implementation
    //      to preserve backward compatibility.
    options.tileSize = this.tile_width;

    if (! options.maxLevel) {
        var mf = -1;
        if (this.scale_factor instanceof Array) {
            for (var i = 0;i < this.scale_factor.length;i++)
            {
                var cf = Number(this.scale_factor[i]);
                if (!isNaN(cf) && cf > mf) { mf = cf; }
            }
        }
        if ( mf < 0 ) { options.maxLevel = Number(Math.ceil(Math.log(Math.max(this.width, this.height ), 2))); }
        else { options.maxLevel = mf; }
    }

    $.TileSource.apply( this, [ options ] );
};

$.extend( $.IIIFTileSource.prototype, $.TileSource.prototype, {
    /**
     * Determine if the data and/or url imply the image service is supported by
     * this tile source.
     * @function
     * @name OpenSeadragon.IIIFTileSource.prototype.supports
     * @param {Object|Array} data
     * @param {String} optional - url
     */
    supports: function( data, url ){
        return (
            data.ns &&
            "http://library.stanford.edu/iiif/image-api/ns/" == data.ns
        ) || (
            data.profile && (
                "http://library.stanford.edu/iiif/image-api/compliance.html#level1" == data.profile ||
                "http://library.stanford.edu/iiif/image-api/compliance.html#level2" == data.profile ||
                "http://library.stanford.edu/iiif/image-api/compliance.html#level3" == data.profile ||
                "http://library.stanford.edu/iiif/image-api/compliance.html" == data.profile
            )
        ) || (
            data.documentElement &&
            "info" == data.documentElement.tagName &&
            "http://library.stanford.edu/iiif/image-api/ns/" ==
                data.documentElement.namespaceURI
        );
    },

    /**
     *
     * @function
     * @name OpenSeadragon.IIIFTileSource.prototype.configure
     * @param {Object|XMLDocument} data - the raw configuration
     * @param {String} url - the url the data was retreived from if any.
     * @return {Object} options - A dictionary of keyword arguments sufficient
     *      to configure this tile source via it's constructor.
     */
    configure: function( data, url ){
        var service,
            options,
            host;

        if( !$.isPlainObject(data) ){

            options = configureFromXml( this, data );

        }else{

            options = configureFromObject( this, data );
        }

        if( url && !options.tilesUrl ){
            service = url.split('/');
            service.pop(); //info.json or info.xml
            service = service.join('/');
            if( 'http' !== url.substring( 0, 4 ) ){
                host = location.protocol + '//' + location.host;
                service = host + service;
            }
            options.tilesUrl = service.replace(
                data.identifier,
                ''
            );
        }

        return options;
    },

    /**
     * Responsible for retreiving the url which will return an image for the
     * region speified by the given x, y, and level components.
     * @function
     * @name OpenSeadragon.IIIFTileSource.prototype.getTileUrl
     * @param {Number} level - z index
     * @param {Number} x
     * @param {Number} y
     * @throws {Error}
     */
    getTileUrl: function( level, x, y ){

        //# constants
        var IIIF_ROTATION = '0',
            IIIF_QUALITY = 'native.jpg',

            //## get the scale (level as a decimal)
            scale = Math.pow( 0.5, this.maxLevel - level ),

            //## get iiif size
            iiif_size = 'pct:' + ( scale * 100 ),

            //# image dimensions at this level
            level_width = Math.ceil( this.width * scale ),
            level_height = Math.ceil( this.height * scale ),

            //## iiif region
            iiif_tile_size_width = Math.ceil( this.tileSize / scale ),
            iiif_tile_size_height = Math.ceil( this.tileSize / scale ),
            iiif_region,
            iiif_tile_x,
            iiif_tile_y,
            iiif_tile_w,
            iiif_tile_h;

        if ( level_width < this.tile_width && level_height < this.tile_height ){
            iiif_region = 'full';
        } else {
            iiif_tile_x = x * iiif_tile_size_width;
            iiif_tile_y = y * iiif_tile_size_height;
            iiif_tile_w = Math.min( iiif_tile_size_width, this.width - iiif_tile_x );
            iiif_tile_h = Math.min( iiif_tile_size_height, this.height - iiif_tile_y );
            iiif_region = [ iiif_tile_x, iiif_tile_y, iiif_tile_w, iiif_tile_h ].join(',');
        }

        return [
            this.tilesUrl,
            this.identifier,
            iiif_region,
            iiif_size,
            IIIF_ROTATION,
            IIIF_QUALITY
        ].join('/');
    }

});

/**
 * @private
 * @inner
 * @function
 *
    <?xml version="1.0" encoding="UTF-8"?>
    <info xmlns="http://library.stanford.edu/iiif/image-api/ns/">
      <identifier>1E34750D-38DB-4825-A38A-B60A345E591C</identifier>
      <width>6000</width>
      <height>4000</height>
      <scale_factors>
        <scale_factor>1</scale_factor>
        <scale_factor>2</scale_factor>
        <scale_factor>4</scale_factor>
      </scale_factors>
      <tile_width>1024</tile_width>
      <tile_height>1024</tile_height>
      <formats>
        <format>jpg</format>
        <format>png</format>
      </formats>
      <qualities>
        <quality>native</quality>
        <quality>grey</quality>
      </qualities>
    </info>
 */
function configureFromXml( tileSource, xmlDoc ){

    //parse the xml
    if ( !xmlDoc || !xmlDoc.documentElement ) {
        throw new Error( $.getString( "Errors.Xml" ) );
    }

    var root            = xmlDoc.documentElement,
        rootName        = root.tagName,
        configuration   = null;

    if ( rootName == "info" ) {

        try {

            configuration = {
                "ns": root.namespaceURI
            };

            parseXML( root, configuration );

            return configureFromObject( tileSource, configuration );

        } catch ( e ) {
            throw (e instanceof Error) ?
                e :
                new Error( $.getString("Errors.IIIF") );
        }
    }

    throw new Error( $.getString( "Errors.IIIF" ) );

}

/**
 * @private
 * @inner
 * @function
 */
function parseXML( node, configuration, property ){
    var i,
        value;
    if( node.nodeType == 3 && property ){//text node
        value = node.nodeValue.trim();
        if( value.match(/^\d*$/)){
            value = Number( value );
        }
        if( !configuration[ property ] ){
            configuration[ property ] = value;
        }else{
            if( !$.isArray( configuration[ property ] ) ){
                configuration[ property ] = [ configuration[ property ] ];
            }
            configuration[ property ].push( value );
        }
    } else if( node.nodeType == 1 ){
        for( i = 0; i < node.childNodes.length; i++ ){
            parseXML( node.childNodes[ i ], configuration, node.nodeName );
        }
    }
}

/**
 * @private
 * @inner
 * @function
 *
    {
        "profile" : "http://library.stanford.edu/iiif/image-api/compliance.html#level1",
        "identifier" : "1E34750D-38DB-4825-A38A-B60A345E591C",
        "width" : 6000,
        "height" : 4000,
        "scale_factors" : [ 1, 2, 4 ],
        "tile_width" : 1024,
        "tile_height" : 1024,
        "formats" : [ "jpg", "png" ],
        "quality" : [ "native", "grey" ]
    }
 */
function configureFromObject( tileSource, configuration ){
    //the image_host property is not part of the iiif standard but is included here to
    //allow the info.json and info.xml specify a different server to load the
    //images from so we can test the implementation.
    if( configuration.image_host ){
        configuration.tilesUrl = configuration.image_host;
    }
    return configuration;
}

}( OpenSeadragon ));
<commit_msg>Update iiiftilesource.js<commit_after>/*
 * OpenSeadragon - IIIFTileSource
 *
 * Copyright (C) 2009 CodePlex Foundation
 * Copyright (C) 2010-2013 OpenSeadragon contributors
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * - Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 *
 * - Neither the name of CodePlex Foundation nor the names of its
 *   contributors may be used to endorse or promote products derived from
 *   this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * The getTileUrl implementation is based on Jon Stroop's Python version,
 * which is released under the New BSD license:
 * https://gist.github.com/jpstroop/4624253
 */

(function( $ ){

/**
 * A client implementation of the International Image Interoperability
 * Format: Image API Draft 0.2 - Please read more about the specification
 * at
 *
 * @class
 * @extends OpenSeadragon.TileSource
 * @see http://library.stanford.edu/iiif/image-api/
 */
$.IIIFTileSource = function( options ){

    $.extend( true, this, options );

    if( !(this.height && this.width && this.identifier && this.tilesUrl ) ){
        throw new Error('IIIF required parameters not provided.');
    }

    //TODO: at this point the base tile source implementation assumes
    //      a tile is a square and so only has one property tileSize
    //      to store it.  It may be possible to make tileSize a vector
    //      OpenSeadraon.Point but would require careful implementation
    //      to preserve backward compatibility.
    options.tileSize = this.tile_width;

    if (! options.maxLevel ) {
        var mf = -1;
        if ( this.scale_factor instanceof Array ) {
            for ( var i = 0; i < this.scale_factor.length; i++ )
            {
                var cf = Number( this.scale_factor[i] );
                if ( !isNaN(cf) && cf > mf ) { mf = cf; }
            }
        }
        if ( mf < 0 ) { options.maxLevel = Number( Math.ceil( Math.log( Math.max( this.width, this.height ), 2 ))); }
        else { options.maxLevel = mf; }
    }

    $.TileSource.apply( this, [ options ] );
};

$.extend( $.IIIFTileSource.prototype, $.TileSource.prototype, {
    /**
     * Determine if the data and/or url imply the image service is supported by
     * this tile source.
     * @function
     * @name OpenSeadragon.IIIFTileSource.prototype.supports
     * @param {Object|Array} data
     * @param {String} optional - url
     */
    supports: function( data, url ){
        return (
            data.ns &&
            "http://library.stanford.edu/iiif/image-api/ns/" == data.ns
        ) || (
            data.profile && (
                "http://library.stanford.edu/iiif/image-api/compliance.html#level1" == data.profile ||
                "http://library.stanford.edu/iiif/image-api/compliance.html#level2" == data.profile ||
                "http://library.stanford.edu/iiif/image-api/compliance.html#level3" == data.profile ||
                "http://library.stanford.edu/iiif/image-api/compliance.html" == data.profile
            )
        ) || (
            data.documentElement &&
            "info" == data.documentElement.tagName &&
            "http://library.stanford.edu/iiif/image-api/ns/" ==
                data.documentElement.namespaceURI
        );
    },

    /**
     *
     * @function
     * @name OpenSeadragon.IIIFTileSource.prototype.configure
     * @param {Object|XMLDocument} data - the raw configuration
     * @param {String} url - the url the data was retreived from if any.
     * @return {Object} options - A dictionary of keyword arguments sufficient
     *      to configure this tile source via it's constructor.
     */
    configure: function( data, url ){
        var service,
            options,
            host;

        if( !$.isPlainObject(data) ){

            options = configureFromXml( this, data );

        }else{

            options = configureFromObject( this, data );
        }

        if( url && !options.tilesUrl ){
            service = url.split('/');
            service.pop(); //info.json or info.xml
            service = service.join('/');
            if( 'http' !== url.substring( 0, 4 ) ){
                host = location.protocol + '//' + location.host;
                service = host + service;
            }
            options.tilesUrl = service.replace(
                data.identifier,
                ''
            );
        }

        return options;
    },

    /**
     * Responsible for retreiving the url which will return an image for the
     * region speified by the given x, y, and level components.
     * @function
     * @name OpenSeadragon.IIIFTileSource.prototype.getTileUrl
     * @param {Number} level - z index
     * @param {Number} x
     * @param {Number} y
     * @throws {Error}
     */
    getTileUrl: function( level, x, y ){

        //# constants
        var IIIF_ROTATION = '0',
            IIIF_QUALITY = 'native.jpg',

            //## get the scale (level as a decimal)
            scale = Math.pow( 0.5, this.maxLevel - level ),

            //## get iiif size
            iiif_size = 'pct:' + ( scale * 100 ),

            //# image dimensions at this level
            level_width = Math.ceil( this.width * scale ),
            level_height = Math.ceil( this.height * scale ),

            //## iiif region
            iiif_tile_size_width = Math.ceil( this.tileSize / scale ),
            iiif_tile_size_height = Math.ceil( this.tileSize / scale ),
            iiif_region,
            iiif_tile_x,
            iiif_tile_y,
            iiif_tile_w,
            iiif_tile_h;

        if ( level_width < this.tile_width && level_height < this.tile_height ){
            iiif_region = 'full';
        } else {
            iiif_tile_x = x * iiif_tile_size_width;
            iiif_tile_y = y * iiif_tile_size_height;
            iiif_tile_w = Math.min( iiif_tile_size_width, this.width - iiif_tile_x );
            iiif_tile_h = Math.min( iiif_tile_size_height, this.height - iiif_tile_y );
            iiif_region = [ iiif_tile_x, iiif_tile_y, iiif_tile_w, iiif_tile_h ].join(',');
        }

        return [
            this.tilesUrl,
            this.identifier,
            iiif_region,
            iiif_size,
            IIIF_ROTATION,
            IIIF_QUALITY
        ].join('/');
    }

});

/**
 * @private
 * @inner
 * @function
 *
    <?xml version="1.0" encoding="UTF-8"?>
    <info xmlns="http://library.stanford.edu/iiif/image-api/ns/">
      <identifier>1E34750D-38DB-4825-A38A-B60A345E591C</identifier>
      <width>6000</width>
      <height>4000</height>
      <scale_factors>
        <scale_factor>1</scale_factor>
        <scale_factor>2</scale_factor>
        <scale_factor>4</scale_factor>
      </scale_factors>
      <tile_width>1024</tile_width>
      <tile_height>1024</tile_height>
      <formats>
        <format>jpg</format>
        <format>png</format>
      </formats>
      <qualities>
        <quality>native</quality>
        <quality>grey</quality>
      </qualities>
    </info>
 */
function configureFromXml( tileSource, xmlDoc ){

    //parse the xml
    if ( !xmlDoc || !xmlDoc.documentElement ) {
        throw new Error( $.getString( "Errors.Xml" ) );
    }

    var root            = xmlDoc.documentElement,
        rootName        = root.tagName,
        configuration   = null;

    if ( rootName == "info" ) {

        try {

            configuration = {
                "ns": root.namespaceURI
            };

            parseXML( root, configuration );

            return configureFromObject( tileSource, configuration );

        } catch ( e ) {
            throw (e instanceof Error) ?
                e :
                new Error( $.getString("Errors.IIIF") );
        }
    }

    throw new Error( $.getString( "Errors.IIIF" ) );

}

/**
 * @private
 * @inner
 * @function
 */
function parseXML( node, configuration, property ){
    var i,
        value;
    if( node.nodeType == 3 && property ){//text node
        value = node.nodeValue.trim();
        if( value.match(/^\d*$/)){
            value = Number( value );
        }
        if( !configuration[ property ] ){
            configuration[ property ] = value;
        }else{
            if( !$.isArray( configuration[ property ] ) ){
                configuration[ property ] = [ configuration[ property ] ];
            }
            configuration[ property ].push( value );
        }
    } else if( node.nodeType == 1 ){
        for( i = 0; i < node.childNodes.length; i++ ){
            parseXML( node.childNodes[ i ], configuration, node.nodeName );
        }
    }
}

/**
 * @private
 * @inner
 * @function
 *
    {
        "profile" : "http://library.stanford.edu/iiif/image-api/compliance.html#level1",
        "identifier" : "1E34750D-38DB-4825-A38A-B60A345E591C",
        "width" : 6000,
        "height" : 4000,
        "scale_factors" : [ 1, 2, 4 ],
        "tile_width" : 1024,
        "tile_height" : 1024,
        "formats" : [ "jpg", "png" ],
        "quality" : [ "native", "grey" ]
    }
 */
function configureFromObject( tileSource, configuration ){
    //the image_host property is not part of the iiif standard but is included here to
    //allow the info.json and info.xml specify a different server to load the
    //images from so we can test the implementation.
    if( configuration.image_host ){
        configuration.tilesUrl = configuration.image_host;
    }
    return configuration;
}

}( OpenSeadragon ));
<|endoftext|>


<commit_before>/*
       Licensed to the Apache Software Foundation (ASF) under one
       or more contributor license agreements.  See the NOTICE file
       distributed with this work for additional information
       regarding copyright ownership.  The ASF licenses this file
       to you 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.
*/

var Q = require('q'),
    nopt  = require('nopt'),
    path  = require('path'),
    build = require('./build'),
    utils = require('./utils'),
    ConfigParser = require('./ConfigParser'),
    packages = require('./package'),
    execSync = require('child_process').execSync;

var ROOT = path.join(__dirname, '..', '..');

module.exports.run = function (argv) {
    if (!utils.isCordovaProject(ROOT)){
        return Q.reject('Could not find project at ' + ROOT);
    }

    try {
        // Check if ran from admin prompt and fail quickly if CLI has administrative permissions
        // http://stackoverflow.com/a/11995662/64949
        execSync('net session', {'stdio': 'ignore'});
        return Q.reject('Can not run this platform with administrative permissions. Please run from a non-admin prompt.');
    } catch (e) {}

    // parse arg
    var args  = nopt({'debug': Boolean, 'release': Boolean, 'nobuild': Boolean,
        'device': Boolean, 'emulator': Boolean, 'target': String, 'archs': String,
        'phone': Boolean, 'win': Boolean, 'appx': String}, {'r' : '--release'}, argv);

    // Validate args
    if (args.debug && args.release) {
        return Q.reject('Only one of "debug"/"release" options should be specified');
    }
    if ((args.device && args.emulator) || ((args.device || args.emulator) && args.target)) {
        return Q.reject('Only one of "device"/"emulator"/"target" options should be specified');
    }
    if (args.phone && args.win) {
        return Q.reject('Only one of "phone"/"win" options should be specified');
    }

    // Get build/deploy options
    var buildType    = args.release ? 'release' : 'debug',
        buildArchs   = args.archs ? args.archs.split(' ') : ['anycpu'],
        projectType  = args.phone ? 'phone' : 'windows',
        deployTarget = args.target ? args.target : (args.emulator ? 'emulator' : 'device'),
        projOverride = args.appx;

    // for win switch we should correctly handle 8.0 and 8.1 version as per configuration
    // as well as 10
    var targetWindowsVersion = getWindowsTargetVersion();
    if (projectType == 'windows') {
        if (targetWindowsVersion == '8.0') {
            projectType = 'windows80';
        }
        else if (targetWindowsVersion === '10.0') {
            projectType = 'windows10';
        }
    }
    else if (projectType === 'phone') {
        if (targetWindowsVersion === '10.0' || targetWindowsVersion === 'UAP') {
            projectType = 'windows10';
        }
    }

    if (projOverride) {
        switch (projOverride) {
            case '8.1-phone':
                projectType = 'phone';
                targetWindowsVersion = '8.1';
                break;
            case '8.1-win':
                projectType = 'windows';
                targetWindowsVersion = '8.1';
                break;
            case 'uap':
                projectType = 'windows10';
                break;
            default:
                console.warn('Unrecognized --appx parameter passed to run: "' + projOverride + '", ignoring.');
                break;
        }
    }

    if (projectType == 'windows' && getWindowsTargetVersion() == '8.0') {
        console.log('Warning: windows8 has been deprecated.  Please update you project to target windows8.1');
        projectType = 'windows80';
    }

    // if --nobuild isn't specified then build app first
    var buildPackages = args.nobuild ? Q() : build.run(argv);

    return buildPackages.then(function () {
        return packages.getPackage(projectType, buildType, buildArchs[0]);
    }).then(function(pkg) {
        console.log('\nDeploying ' + pkg.type + ' package to ' + deployTarget + ':\n' + pkg.appx);
        switch (pkg.type) {
            case 'phone':
                return packages.deployToPhone(pkg, deployTarget, false).catch(function(e) {
                    if (args.target || args.emulator || args.device) {
                        throw e; // Explicit target, carry on
                    }

                    // 'device' was inferred initially, because no target was specified
                    return packages.deployToPhone(pkg, 'emulator', false);
                });

            case 'windows10':
                if (args.phone) {
                    // Win10 emulator launch is not currently supported, always force device
                    if (args.emulator || args.target === 'emulator') {
                        console.warn('Windows 10 Phone emulator is not currently supported, attempting deploy to device.');
                    }
                    return packages.deployToPhone(pkg, 'device', true);
                }
                else {
                    return packages.deployToDesktop(pkg, deployTarget, projectType);
                }

                break;
            default: // 'windows'
                return packages.deployToDesktop(pkg, deployTarget, projectType);

        }
    });
};

module.exports.help = function () {
    console.log('\nUsage: run [ --device | --emulator | --target=<id> ] [ --debug | --release | --nobuild ]');
    console.log('           [ --x86 | --x64 | --arm ] [--phone | --win]');
    console.log('    --device      : Deploys and runs the project on the connected device.');
    console.log('    --emulator    : Deploys and runs the project on an emulator.');
    console.log('    --target=<id> : Deploys and runs the project on the specified target.');
    console.log('    --debug       : Builds project in debug mode.');
    console.log('    --release     : Builds project in release mode.');
    console.log('    --nobuild     : Uses pre-built package, or errors if project is not built.');
    console.log('    --archs       : Specific chip architectures (`anycpu`, `arm`, `x86`, `x64`).');
    console.log('    --phone, --win');
    console.log('                  : Specifies project type to deploy');
    console.log('    --appx=<8.1-win|8.1-phone|uap>');
    console.log('                  : Overrides windows-target-version to build Windows 8.1, ');
    console.log('                              Windows Phone 8.1, or Windows 10.');
    console.log('');
    console.log('Examples:');
    console.log('    run');
    console.log('    run --emulator');
    console.log('    run --device');
    console.log('    run --target=7988B8C3-3ADE-488d-BA3E-D052AC9DC710');
    console.log('    run --device --release');
    console.log('    run --emulator --debug');
    console.log('    run --device --appx=phone-8.1');
    console.log('');

    process.exit(0);
};

function getWindowsTargetVersion() {
    var config = new ConfigParser(path.join(ROOT, 'config.xml'));
    var windowsTargetVersion = config.getWindowsTargetVersion();
    switch(windowsTargetVersion) {
        case '8':
        case '8.0':
            return '8.0';
        case '8.1':
            return '8.1';
        case '10.0':
        case 'UAP':
            return '10.0';
        default:
            throw new Error('Unsupported windows-target-version value: ' + windowsTargetVersion);
    }
}
<commit_msg>CB-9164 Better error message when deploying to Windows10 phone emulator<commit_after>/*
       Licensed to the Apache Software Foundation (ASF) under one
       or more contributor license agreements.  See the NOTICE file
       distributed with this work for additional information
       regarding copyright ownership.  The ASF licenses this file
       to you 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.
*/

var Q = require('q'),
    nopt  = require('nopt'),
    path  = require('path'),
    build = require('./build'),
    utils = require('./utils'),
    ConfigParser = require('./ConfigParser'),
    packages = require('./package'),
    execSync = require('child_process').execSync;

var ROOT = path.join(__dirname, '..', '..');

module.exports.run = function (argv) {
    if (!utils.isCordovaProject(ROOT)){
        return Q.reject('Could not find project at ' + ROOT);
    }

    try {
        // Check if ran from admin prompt and fail quickly if CLI has administrative permissions
        // http://stackoverflow.com/a/11995662/64949
        execSync('net session', {'stdio': 'ignore'});
        return Q.reject('Can not run this platform with administrative permissions. Please run from a non-admin prompt.');
    } catch (e) {}

    // parse arg
    var args  = nopt({'debug': Boolean, 'release': Boolean, 'nobuild': Boolean,
        'device': Boolean, 'emulator': Boolean, 'target': String, 'archs': String,
        'phone': Boolean, 'win': Boolean, 'appx': String}, {'r' : '--release'}, argv);

    // Validate args
    if (args.debug && args.release) {
        return Q.reject('Only one of "debug"/"release" options should be specified');
    }
    if ((args.device && args.emulator) || ((args.device || args.emulator) && args.target)) {
        return Q.reject('Only one of "device"/"emulator"/"target" options should be specified');
    }
    if (args.phone && args.win) {
        return Q.reject('Only one of "phone"/"win" options should be specified');
    }

    // Get build/deploy options
    var buildType    = args.release ? 'release' : 'debug',
        buildArchs   = args.archs ? args.archs.split(' ') : ['anycpu'],
        projectType  = args.phone ? 'phone' : 'windows',
        deployTarget = args.target ? args.target : (args.emulator ? 'emulator' : 'device'),
        projOverride = args.appx;

    // for win switch we should correctly handle 8.0 and 8.1 version as per configuration
    // as well as 10
    var targetWindowsVersion = getWindowsTargetVersion();
    if (projectType == 'windows') {
        if (targetWindowsVersion == '8.0') {
            projectType = 'windows80';
        }
        else if (targetWindowsVersion === '10.0') {
            projectType = 'windows10';
        }
    }
    else if (projectType === 'phone') {
        if (targetWindowsVersion === '10.0' || targetWindowsVersion === 'UAP') {
            projectType = 'windows10';
        }
    }

    if (projOverride) {
        switch (projOverride) {
            case '8.1-phone':
                projectType = 'phone';
                targetWindowsVersion = '8.1';
                break;
            case '8.1-win':
                projectType = 'windows';
                targetWindowsVersion = '8.1';
                break;
            case 'uap':
                projectType = 'windows10';
                break;
            default:
                console.warn('Unrecognized --appx parameter passed to run: "' + projOverride + '", ignoring.');
                break;
        }
    }

    if (projectType == 'windows' && getWindowsTargetVersion() == '8.0') {
        console.log('Warning: windows8 has been deprecated.  Please update you project to target windows8.1');
        projectType = 'windows80';
    }

    // if --nobuild isn't specified then build app first
    var buildPackages = args.nobuild ? Q() : build.run(argv);

    return buildPackages.then(function () {
        return packages.getPackage(projectType, buildType, buildArchs[0]);
    }).then(function(pkg) {
        console.log('\nDeploying ' + pkg.type + ' package to ' + deployTarget + ':\n' + pkg.appx);
        switch (pkg.type) {
            case 'phone':
                return packages.deployToPhone(pkg, deployTarget, false).catch(function(e) {
                    if (args.target || args.emulator || args.device) {
                        throw e; // Explicit target, carry on
                    }
                    // 'device' was inferred initially, because no target was specified
                    return packages.deployToPhone(pkg, 'emulator', false);
                });
            case 'windows10':
                if (args.phone) {
                    // Win10 emulator launch is not currently supported, always force device
                    if (args.emulator || args.target === 'emulator') {
                        console.warn('Windows 10 Phone emulator is currently not supported.');
                        console.warn('If you want to deploy to emulator, please use Visual Studio instead.');
                        console.warn('Attempting to deploy to device...');
                    }
                    return packages.deployToPhone(pkg, 'device', true);
                }
                else {
                    return packages.deployToDesktop(pkg, deployTarget, projectType);
                }
                break;
            default: // 'windows'
                return packages.deployToDesktop(pkg, deployTarget, projectType);
        }
    });
};

module.exports.help = function () {
    console.log('\nUsage: run [ --device | --emulator | --target=<id> ] [ --debug | --release | --nobuild ]');
    console.log('           [ --x86 | --x64 | --arm ] [--phone | --win]');
    console.log('    --device      : Deploys and runs the project on the connected device.');
    console.log('    --emulator    : Deploys and runs the project on an emulator.');
    console.log('    --target=<id> : Deploys and runs the project on the specified target.');
    console.log('    --debug       : Builds project in debug mode.');
    console.log('    --release     : Builds project in release mode.');
    console.log('    --nobuild     : Uses pre-built package, or errors if project is not built.');
    console.log('    --archs       : Specific chip architectures (`anycpu`, `arm`, `x86`, `x64`).');
    console.log('    --phone, --win');
    console.log('                  : Specifies project type to deploy');
    console.log('    --appx=<8.1-win|8.1-phone|uap>');
    console.log('                  : Overrides windows-target-version to build Windows 8.1, ');
    console.log('                              Windows Phone 8.1, or Windows 10.');
    console.log('');
    console.log('Examples:');
    console.log('    run');
    console.log('    run --emulator');
    console.log('    run --device');
    console.log('    run --target=7988B8C3-3ADE-488d-BA3E-D052AC9DC710');
    console.log('    run --device --release');
    console.log('    run --emulator --debug');
    console.log('    run --device --appx=phone-8.1');
    console.log('');

    process.exit(0);
};

function getWindowsTargetVersion() {
    var config = new ConfigParser(path.join(ROOT, 'config.xml'));
    var windowsTargetVersion = config.getWindowsTargetVersion();
    switch(windowsTargetVersion) {
        case '8':
        case '8.0':
            return '8.0';
        case '8.1':
            return '8.1';
        case '10.0':
        case 'UAP':
            return '10.0';
        default:
            throw new Error('Unsupported windows-target-version value: ' + windowsTargetVersion);
    }
}
<|endoftext|>


<commit_before>var thunky = require('thunky')

module.exports = Cursor

function Cursor (archive, name, opts) {
  if (!(this instanceof Cursor)) return new Cursor(archive, name, opts)

  var self = this

  this.name = name
  this.opened = false
  this.position = 0
  this.index = 0
  this.offset = 0
  this.open = thunky(open)

  this._content = null
  this._stat = null
  this._seekTo = 0
  this._seeking = true
  this._start = 0
  this._end = 0
  this._range = null
  this._download = !opts || opts.download !== false

  this.open()

  function open (cb) {
    archive.stat(name, function (err, st) {
      if (err) return cb(err)
      archive._ensureContent(function (err) {
        if (err) return cb(err)
        if (!st.isFile()) return cb(new Error('Not a file'))

        self._content = archive.content
        self._stat = st
        self._start = st.offset
        self._end = st.offset + st.blocks

        if (self._seekTo === 0 && self._download) {
          self._range = self._content.download({start: self._start, end: self._end, linear: true})
        }

        cb(null)
      })
    })
  }
}

Cursor.prototype.seek = function (pos) {
  if (pos === this.position) return this
  this._seeking = true
  this._seekTo = pos
  return this
}

Cursor.prototype._seek = function (bytes, cb) {
  var self = this

  this.open(function (err) {
    if (err) return cb(err)

    if (bytes < 0) bytes += self._stat.size
    if (bytes < 0) bytes = 0
    if (bytes > self._stat.size) bytes = self._stat.size

    var st = self._stat
    var opts = {start: self._start, end: self._end}

    if (bytes === 0) return onseek(null, self._start, 0)
    if (bytes === self._stat.size) return onseek(self._end, 0)

    self._content.seek(st.byteOffset + bytes, opts, onseek)
  })

  function onseek (err, index, offset) {
    if (err) return cb(err)
    cb(null, bytes, index, offset)
  }
}

Cursor.prototype.next = function (cb) {
  if (this._seeking) this._seekAndNext(cb)
  else this._next(this.position, this.index, this.offset, cb)
}

Cursor.prototype.close = function (cb) {
  if (!cb) cb = noop

  var self = this
  this.open(function (err) {
    if (err) return cb(err)
    if (self._range) self._content.undownload(self._range)
    cb()
  })
}

Cursor.prototype._next = function (pos, index, offset, cb) {
  if (index < this._start || index >= this._end) return cb(null, null)

  var self = this

  this._content.get(this.index, function (err, data) {
    if (err) return cb(err)

    if (offset) {
      data = data.slice(offset)
    }

    self.position = pos + data.length
    self.offset = 0
    self.index++

    cb(null, data)
  })
}

Cursor.prototype._seekAndNext = function (cb) {
  var self = this
  var seekTo = this._seekTo

  this._seek(seekTo, function (err, pos, index, offset) {
    if (err) return cb(err)

    if (seekTo === self._seekTo) {
      self._seeking = false
      self._seekTo = -1
      self.position = pos
      self.index = index
      self.offset = offset

      if (self._download) {
        if (self._range) self._content.undownload(self._range)
        self._range = self._content.download({start: self.index, end: self._end, linear: true})
      }
    }

    self._next(pos, index, offset, cb)
  })
}

function noop () {}
<commit_msg>fix optimized case<commit_after>var thunky = require('thunky')

module.exports = Cursor

function Cursor (archive, name, opts) {
  if (!(this instanceof Cursor)) return new Cursor(archive, name, opts)

  var self = this

  this.name = name
  this.opened = false
  this.position = 0
  this.index = 0
  this.offset = 0
  this.open = thunky(open)

  this._content = null
  this._stat = null
  this._seekTo = 0
  this._seeking = true
  this._start = 0
  this._end = 0
  this._range = null
  this._download = !opts || opts.download !== false

  this.open()

  function open (cb) {
    archive.stat(name, function (err, st) {
      if (err) return cb(err)
      archive._ensureContent(function (err) {
        if (err) return cb(err)
        if (!st.isFile()) return cb(new Error('Not a file'))

        self._content = archive.content
        self._stat = st
        self._start = st.offset
        self._end = st.offset + st.blocks

        if (self._seekTo === 0 && self._download) {
          self._range = self._content.download({start: self._start, end: self._end, linear: true})
        }

        cb(null)
      })
    })
  }
}

Cursor.prototype.seek = function (pos) {
  if (pos === this.position && this._seekTo === -1) return this
  this._seeking = true
  this._seekTo = pos
  return this
}

Cursor.prototype._seek = function (bytes, cb) {
  var self = this

  this.open(function (err) {
    if (err) return cb(err)

    if (bytes < 0) bytes += self._stat.size
    if (bytes < 0) bytes = 0
    if (bytes > self._stat.size) bytes = self._stat.size

    var st = self._stat
    var opts = {start: self._start, end: self._end}

    if (bytes === 0) return onseek(null, self._start, 0)
    if (bytes === self._stat.size) return onseek(self._end, 0)

    self._content.seek(st.byteOffset + bytes, opts, onseek)
  })

  function onseek (err, index, offset) {
    if (err) return cb(err)
    cb(null, bytes, index, offset)
  }
}

Cursor.prototype.next = function (cb) {
  if (this._seeking) this._seekAndNext(cb)
  else this._next(this.position, this.index, this.offset, cb)
}

Cursor.prototype.close = function (cb) {
  if (!cb) cb = noop

  var self = this
  this.open(function (err) {
    if (err) return cb(err)
    if (self._range) self._content.undownload(self._range)
    cb()
  })
}

Cursor.prototype._next = function (pos, index, offset, cb) {
  if (index < this._start || index >= this._end) return cb(null, null)

  var self = this

  this._content.get(this.index, function (err, data) {
    if (err) return cb(err)

    if (offset) {
      data = data.slice(offset)
    }

    self.position = pos + data.length
    self.offset = 0
    self.index++

    cb(null, data)
  })
}

Cursor.prototype._seekAndNext = function (cb) {
  var self = this
  var seekTo = this._seekTo

  this._seek(seekTo, function (err, pos, index, offset) {
    if (err) return cb(err)

    if (seekTo === self._seekTo) {
      self._seeking = false
      self._seekTo = -1
      self.position = pos
      self.index = index
      self.offset = offset

      if (self._download) {
        if (self._range) self._content.undownload(self._range)
        self._range = self._content.download({start: self.index, end: self._end, linear: true})
      }
    }

    self._next(pos, index, offset, cb)
  })
}

function noop () {}
<|endoftext|>


<commit_before>/*
 * daemon.js: Wrapper for C++ bindings
 *
 * (C) 2010 and Charlie Robbins
 * MIT LICENCE
 *
 */

var fs = require('fs'),
    binding;

//
// Try catch here around multiple build paths to support
// `node@0.4.x` and `node@0.6.x`.
//
try { binding = require('../build/default/daemon') }
catch (ex) { binding = require('../build/Release/daemon') }

var daemon = exports;

//
// Export the raw bindings directly
//
Object.keys(binding).forEach(function (k) { daemon[k] = binding[k] });

//
// function start (fd)
//   Wrapper around C++ start code to update the pid property of the
//   global process js object.
//
daemon.start = function (fd) {
  var pid;
  if (typeof(fd) === 'object') {
    console.log(fd);
    pid = binding.start(fd.stdout, fd.stderr);
  }
  else {
    pid = binding.start(fd);
  }
  process.pid = pid;
  return pid;
};

//
// function daemonize ([out, lock, callback])
//   Run is designed to encapsulate the basic daemon operation in a single async call.
//   When the callback returns you are in the the child process.
//
daemon.daemonize = function (out, lock, callback) {
  //
  // If we only get one argument assume it's an fd and
  // simply return with the pid from daemon.start(fd);
  //
  if (arguments.length === 1) {
    return daemon.start(out);
  }

  var errors = [],
      fds = {},
      outstanding = 0;

  var finish = function () {
    if (errors.length) {
      callback(new Error('could reopen stdout/stderr: ' + errors.join('')))
    }
    try {
      var pid = daemon.start(fds.both || fds);
      daemon.lock(lock);
      callback(null, pid);
    }
    catch (ex) {
      callback(ex);
    }
  };

  var open = function (name, path) {
    outstanding++;
    fs.open(path, 'a+', 0666, function (err, fd) {
      if (err) {
        errors.push(err);
      }
      else {
        fds[name] = fd;
      }
      if (--outstanding === 0) {
        finish();
      }
    });
  };

  if (typeof out === 'object') {
    if (out.stdout) {
      open('stdout', out.stdout);
    }
    if (out.stderr) {
      open('stderr', out.stderr);
    }
  }
  else {
    open('both', out);
  }
};

//
// function kill (lock, callback)
//   Asynchronously stop the process in the lock file and
//   remove the lock file
//
daemon.kill = function (lock, callback) {
  fs.readFile(lock, function (err, data) {
    if (err) {
      return callback(err);
    }

    try {
      // Stop the process with the pid in the lock file
      var pid = parseInt(data.toString());
      if (pid > 0) {
        process.kill(pid);
      }

      // Remove the lock file
      fs.unlink(lock, function (err) {
        return err
          ? callback(err)
          : callback(null, pid);
      });
    }
    catch (ex) {
      callback(ex);
    }
  });
};
<commit_msg>Not sure why, but this makes the redirected handles work<commit_after>/*
 * daemon.js: Wrapper for C++ bindings
 *
 * (C) 2010 and Charlie Robbins
 * MIT LICENCE
 *
 */

var fs = require('fs'),
    binding;

//
// Try catch here around multiple build paths to support
// `node@0.4.x` and `node@0.6.x`.
//
try { binding = require('../build/default/daemon') }
catch (ex) { binding = require('../build/Release/daemon') }

var daemon = exports;

//
// Export the raw bindings directly
//
Object.keys(binding).forEach(function (k) { daemon[k] = binding[k] });

//
// function start (fd)
//   Wrapper around C++ start code to update the pid property of the
//   global process js object.
//
daemon.start = function (fd) {
  var pid;
  if (typeof(fd) === 'object') {
    process.stdout.write('');
    process.stderr.write('');
    pid = binding.start(fd.stdout, fd.stderr);
  }
  else {
    pid = binding.start(fd);
  }
  process.pid = pid;
  return pid;
};

//
// function daemonize ([out, lock, callback])
//   Run is designed to encapsulate the basic daemon operation in a single async call.
//   When the callback returns you are in the the child process.
//
daemon.daemonize = function (out, lock, callback) {
  //
  // If we only get one argument assume it's an fd and
  // simply return with the pid from daemon.start(fd);
  //
  if (arguments.length === 1) {
    return daemon.start(out);
  }

  var errors = [],
      fds = {},
      outstanding = 0;

  var finish = function () {
    if (errors.length) {
      callback(new Error('could reopen stdout/stderr: ' + errors.join('')))
    }
    try {
      var pid = daemon.start(fds.both || fds);
      daemon.lock(lock);
      callback(null, pid);
    }
    catch (ex) {
      callback(ex);
    }
  };

  var open = function (name, path) {
    outstanding++;
    fs.open(path, 'a+', 0666, function (err, fd) {
      if (err) {
        errors.push(err);
      }
      else {
        fds[name] = fd;
      }
      if (--outstanding === 0) {
        finish();
      }
    });
  };

  if (typeof out === 'object') {
    if (out.stdout) {
      open('stdout', out.stdout);
    }
    if (out.stderr) {
      open('stderr', out.stderr);
    }
  }
  else {
    open('both', out);
  }
};

//
// function kill (lock, callback)
//   Asynchronously stop the process in the lock file and
//   remove the lock file
//
daemon.kill = function (lock, callback) {
  fs.readFile(lock, function (err, data) {
    if (err) {
      return callback(err);
    }

    try {
      // Stop the process with the pid in the lock file
      var pid = parseInt(data.toString());
      if (pid > 0) {
        process.kill(pid);
      }

      // Remove the lock file
      fs.unlink(lock, function (err) {
        return err
          ? callback(err)
          : callback(null, pid);
      });
    }
    catch (ex) {
      callback(ex);
    }
  });
};
<|endoftext|>


<commit_before>'use strict';

var request = require("request");
var defaultUserAgent = require("./user_agent");

module.exports = {

  // @param {string} apiToken the Dialog API token
  // @param {string} botId the Dialog bot Id
  // @param {Object} payload Properties expected by the track API endpoint
  //   see https://docs.dialoganalytics.com/reference/track/
  track: function(apiToken, botId, payload) {
    var options = {
      url: 'https://api.dialoganalytics.com/v1/b/' + botId + '/track',
      headers: {
        'User-Agent': defaultUserAgent,
        'Authorization': 'Api-Key ' + apiToken
      },
      json: payload
    }

    function callback(error, response, body) {};

    return request.post(options, callback);
  }
};
<commit_msg>Throw an error when no api token defined<commit_after>'use strict';

var request = require("request");
var defaultUserAgent = require("./user_agent");

module.exports = {

  // @param {string} apiToken the Dialog API token
  // @param {string} botId the Dialog bot Id
  // @param {Object} payload Properties expected by the track API endpoint
  //   see https://docs.dialoganalytics.com/reference/track/
  track: function(apiToken, botId, payload) {
    if (!apiToken) {
      throw new Error('Please configure Dialog with a valid API token first');
    };

    var options = {
      url: 'https://api.dialoganalytics.com/v1/b/' + botId + '/track',
      headers: {
        'User-Agent': defaultUserAgent,
        'Authorization': 'Api-Key ' + apiToken
      },
      json: payload
    }

    function callback(error, response, body) {};

    return request.post(options, callback);
  }
};
<|endoftext|>


<commit_before>var Modem = require('docker-modem'),
  Container = require('./container'),
  Image = require('./image'),
  util = require('./util');

var Docker = function(opts) {
  this.modem = new Modem(opts);
};

Docker.prototype.createContainer = function(opts, callback) {
  var self = this;
  var optsf = {
    path: '/containers/create?',
    method: 'POST',
    options: opts,
    statusCodes: {
      201: true,
      404: "no such container",
      406: 'impossible to attach',
      500: "server error"
    }
  };

  this.modem.dial(optsf, function(err, data) {
    if(err) return callback(err, data);
    callback(err, self.getContainer(data.Id));
  });
};

Docker.prototype.createImage = function(auth, opts, callback) {
  if (!callback && typeof(opts) === 'function') {
    callback = opts;
    opts = auth;
    auth = undefined;
  }

  var self = this;
  var optsf = {
    path: '/images/create?',
    method: 'POST',
    options: opts,
    authconfig: auth,
    isStream: true,
    statusCodes: {
      200: true,
      500: "server error"
    }
  };

  this.modem.dial(optsf, function(err, data) {
    callback(err, data);
  });
};

Docker.prototype.checkAuth = function(opts, callback) {
  var self = this;
  var opts = {
    path: '/auth',
    method: 'POST',
    options: opts,
    statusCodes: {
      200: true,
      204: true,
      500: "server error"
    }
  };

  this.modem.dial(opts, function(err, data) {
    callback(err, data);
  });
};

Docker.prototype.buildImage = function(file, opts, callback) {
  if (!callback && typeof(opts) === 'function') {
    callback = opts;
    opts = null;
  }

  var self = this;
  var opts = {
    path: '/build?',
    method: 'POST',
    file: file,
    options: opts,
    isStream: true,
    statusCodes: {
      200: true,
      500: "server error"
    }
  };

  this.modem.dial(opts, function(err, data) {
    callback(err, data);
  });
};

Docker.prototype.getContainer = function(id) {
  return new Container(this.modem, id);
};

Docker.prototype.getImage = function(name) {
  return new Image(this.modem, name);
};

Docker.prototype.listContainers = function(opts, callback) {
  var self = this;

  if (!callback && typeof(opts) === 'function') {
    callback = opts;
    opts = null;
  }

  var optsf = {
    path: '/containers/json?',
    method: 'GET',
    options: opts,
    statusCodes: {
      200: true,
      400: "bad parameter",
      500: "server error"
    }
  };

  this.modem.dial(optsf, function(err, data) {
    callback(err, data);
  });
};

Docker.prototype.listImages = function(opts, callback) {
  if (!callback && typeof(opts) === 'function') {
    callback = opts;
    opts = null;
  }

  var opts = {
    path: '/images/json?',
    method: 'GET',
    options: opts,
    statusCodes: {
      200: true,
      400: "bad parameter",
      500: "server error"
    }
  };

  this.modem.dial(opts, function(err, data) {
    callback(err, data);
  });
};

Docker.prototype.searchImages = function(opts, callback) {
  var opts = {
    path: '/images/search?',
    method: 'GET',
    options: opts,
    statusCodes: {
      200: true,
      500: "server error"
    }
  };

  this.modem.dial(opts, function(err, data) {
    callback(err, data);
  });
};

Docker.prototype.info = function(callback) {
  var opts = {
    path: '/info',
    method: 'GET',
    statusCodes: {
      200: true,
      500: "server error"
    }
  };

  this.modem.dial(opts, function(err, data) {
    callback(err, data);
  });
};

Docker.prototype.version = function(callback) {
  var opts = {
    path: '/version',
    method: 'GET',
    statusCodes: {
      200: true,
      500: "server error"
    }
  };

  this.modem.dial(opts, function(err, data) {
    callback(err, data);
  });
};

Docker.prototype.getEvents = function(opts, callback) {
  if (!callback && typeof(opts) === 'function') {
    callback = opts;
    opts = null;
  }

  var optsf = {
    path: '/events?',
    method: 'GET',
    options: opts,
    isStream: true,
    statusCodes: {
      200: true,
      500: "server error"
    }
  };

  this.modem.dial(optsf, function(err, data) {
    callback(err, data);
  });
};

/**
Pull is a wrapper around parsing out the tag from the image
(which create image cannot do but run can for whatever reasons) and create image overloading.
*/
Docker.prototype.pull = function(repoTag, opts, callback) {
  if (typeof opts === 'function') {
    callback = opts;
    opts = {};
  }

  var imageSrc = util.parseRepositoryTag(repoTag);
  var pullOpts = {
    fromImage: imageSrc.repository,
    tag: imageSrc.tag
  };

  // allow overriding the pull opts
  for (var key in opts) pullOpts[key] = opts[key];

  // XXX: Should we allow authopts here?
  return this.createImage(pullOpts, callback);
};

Docker.prototype.run = function(image, cmd, streamo, callback) {

  function handler(err, container) {
    if (err) return callback(err, container);

    container.attach({stream: true, stdout: true, stderr: true}, function handler(err, stream) {
      if(err) return callback(err, data);

      if(streamo) {
        stream.setEncoding('utf8');
        stream.pipe(streamo, {end: true});
      }

      container.start(function(err, data) {
        if(err) return callback(err, data);

        container.wait(function(err, data) {
          callback(err, data, container);
        });
      });
    });
  }

  var optsc = {
    'Hostname': '',
    'User': '',
    'AttachStdin': false,
    'AttachStdout': true,
    'AttachStderr': true,
    'Tty': true,
    'OpenStdin': false,
    'StdinOnce': false,
    'Env': null,
    'Cmd': cmd,
    'Image': image,
    'Volumes': {},
    'VolumesFrom': ''
  };

  this.createContainer(optsc, handler);
};

module.exports = Docker;
<commit_msg>new is optional<commit_after>var Modem = require('docker-modem'),
  Container = require('./container'),
  Image = require('./image'),
  util = require('./util');

var Docker = function(opts) {
  if (!(this instanceof Docker)) return new Docker(opts);
  this.modem = new Modem(opts);
};

Docker.prototype.createContainer = function(opts, callback) {
  var self = this;
  var optsf = {
    path: '/containers/create?',
    method: 'POST',
    options: opts,
    statusCodes: {
      201: true,
      404: "no such container",
      406: 'impossible to attach',
      500: "server error"
    }
  };

  this.modem.dial(optsf, function(err, data) {
    if(err) return callback(err, data);
    callback(err, self.getContainer(data.Id));
  });
};

Docker.prototype.createImage = function(auth, opts, callback) {
  if (!callback && typeof(opts) === 'function') {
    callback = opts;
    opts = auth;
    auth = undefined;
  }

  var self = this;
  var optsf = {
    path: '/images/create?',
    method: 'POST',
    options: opts,
    authconfig: auth,
    isStream: true,
    statusCodes: {
      200: true,
      500: "server error"
    }
  };

  this.modem.dial(optsf, function(err, data) {
    callback(err, data);
  });
};

Docker.prototype.checkAuth = function(opts, callback) {
  var self = this;
  var opts = {
    path: '/auth',
    method: 'POST',
    options: opts,
    statusCodes: {
      200: true,
      204: true,
      500: "server error"
    }
  };

  this.modem.dial(opts, function(err, data) {
    callback(err, data);
  });
};

Docker.prototype.buildImage = function(file, opts, callback) {
  if (!callback && typeof(opts) === 'function') {
    callback = opts;
    opts = null;
  }

  var self = this;
  var opts = {
    path: '/build?',
    method: 'POST',
    file: file,
    options: opts,
    isStream: true,
    statusCodes: {
      200: true,
      500: "server error"
    }
  };

  this.modem.dial(opts, function(err, data) {
    callback(err, data);
  });
};

Docker.prototype.getContainer = function(id) {
  return new Container(this.modem, id);
};

Docker.prototype.getImage = function(name) {
  return new Image(this.modem, name);
};

Docker.prototype.listContainers = function(opts, callback) {
  var self = this;

  if (!callback && typeof(opts) === 'function') {
    callback = opts;
    opts = null;
  }

  var optsf = {
    path: '/containers/json?',
    method: 'GET',
    options: opts,
    statusCodes: {
      200: true,
      400: "bad parameter",
      500: "server error"
    }
  };

  this.modem.dial(optsf, function(err, data) {
    callback(err, data);
  });
};

Docker.prototype.listImages = function(opts, callback) {
  if (!callback && typeof(opts) === 'function') {
    callback = opts;
    opts = null;
  }

  var opts = {
    path: '/images/json?',
    method: 'GET',
    options: opts,
    statusCodes: {
      200: true,
      400: "bad parameter",
      500: "server error"
    }
  };

  this.modem.dial(opts, function(err, data) {
    callback(err, data);
  });
};

Docker.prototype.searchImages = function(opts, callback) {
  var opts = {
    path: '/images/search?',
    method: 'GET',
    options: opts,
    statusCodes: {
      200: true,
      500: "server error"
    }
  };

  this.modem.dial(opts, function(err, data) {
    callback(err, data);
  });
};

Docker.prototype.info = function(callback) {
  var opts = {
    path: '/info',
    method: 'GET',
    statusCodes: {
      200: true,
      500: "server error"
    }
  };

  this.modem.dial(opts, function(err, data) {
    callback(err, data);
  });
};

Docker.prototype.version = function(callback) {
  var opts = {
    path: '/version',
    method: 'GET',
    statusCodes: {
      200: true,
      500: "server error"
    }
  };

  this.modem.dial(opts, function(err, data) {
    callback(err, data);
  });
};

Docker.prototype.getEvents = function(opts, callback) {
  if (!callback && typeof(opts) === 'function') {
    callback = opts;
    opts = null;
  }

  var optsf = {
    path: '/events?',
    method: 'GET',
    options: opts,
    isStream: true,
    statusCodes: {
      200: true,
      500: "server error"
    }
  };

  this.modem.dial(optsf, function(err, data) {
    callback(err, data);
  });
};

/**
Pull is a wrapper around parsing out the tag from the image
(which create image cannot do but run can for whatever reasons) and create image overloading.
*/
Docker.prototype.pull = function(repoTag, opts, callback) {
  if (typeof opts === 'function') {
    callback = opts;
    opts = {};
  }

  var imageSrc = util.parseRepositoryTag(repoTag);
  var pullOpts = {
    fromImage: imageSrc.repository,
    tag: imageSrc.tag
  };

  // allow overriding the pull opts
  for (var key in opts) pullOpts[key] = opts[key];

  // XXX: Should we allow authopts here?
  return this.createImage(pullOpts, callback);
};

Docker.prototype.run = function(image, cmd, streamo, callback) {

  function handler(err, container) {
    if (err) return callback(err, container);

    container.attach({stream: true, stdout: true, stderr: true}, function handler(err, stream) {
      if(err) return callback(err, data);

      if(streamo) {
        stream.setEncoding('utf8');
        stream.pipe(streamo, {end: true});
      }

      container.start(function(err, data) {
        if(err) return callback(err, data);

        container.wait(function(err, data) {
          callback(err, data, container);
        });
      });
    });
  }

  var optsc = {
    'Hostname': '',
    'User': '',
    'AttachStdin': false,
    'AttachStdout': true,
    'AttachStderr': true,
    'Tty': true,
    'OpenStdin': false,
    'StdinOnce': false,
    'Env': null,
    'Cmd': cmd,
    'Image': image,
    'Volumes': {},
    'VolumesFrom': ''
  };

  this.createContainer(optsc, handler);
};

module.exports = Docker;
<|endoftext|>


<commit_before>const axios = require('axios')
const {logger} = require("@pastash/pastash");

let metricsToSend = []
let spansToSend = []
let onMetrics = []
let onSpans = []
let httpThroughputMetrics = [0,0,0,0,0]
let sendingQueueLength = 0
let sendingErrors = 0
let waitingForResend = 0

function fireMetrics() {
    metricsToSend.length && onMetrics.length && onMetrics.pop()()
}

function fireSpans() {
    spansToSend.length && onSpans.length && onSpans.pop()()
}

function sendMetrics(obj, retries) {
    retries = retries || 0
    metricsToSend.push({retries, payload: obj})
    fireMetrics()
}

function sendSpans(obj, retries) {
    retries = retries || 0
    spansToSend.push({retries, payload: obj})
    fireSpans()
}

async function startMetricsSender () {
    while (true) {
        if (!metricsToSend.length) {
            await new Promise(f => onMetrics.push(f))
        }
        let toSend = ['{"streams":[']
        let len = 14
        let i = 0
        metricsToSend = metricsToSend.filter(m => m.payload)
        for (; i < metricsToSend.length && len < 20 * 1024 * 1024; i++) {
            if (i > 0) {
                toSend.push(',')
            }
            let str = JSON.stringify(metricsToSend[i].payload.streams)
            str = str.substring(1, str.length - 1)
            toSend.push(str)
            len += str.length
        }
        toSend.push(']}')
        let sending = metricsToSend.slice(0, i)
        metricsToSend = metricsToSend.slice(i)
        fireMetrics()
        const body = toSend.join('')
        toSend = null
        const sendingLength = sending.length
        sendingQueueLength += sendingLength
        sending = sending.filter(s => s.retries < 4)
        try {
            var response = await axios.post(`${module.exports.host}/loki/api/v1/push`, body, {
                headers: {
                    'Content-Type': 'application/json'
                }
            })
            //logger.debug('Metrics posted', response.status, response.statusText)
        } catch (e) {
            sendingErrors += sendingLength
            if (e instanceof axios.AxiosError) {
                logger.error(`HTTP ERROR '${e.message}' [${e.response?.status}]: ${e.response?.data}`)
            } else {
                logger.error(e)
            }
            waitingForResend += sending.length
            setTimeout(() => {
                metricsToSend.push.apply(metricsToSend,
                    sending.map(s => ({...s, retries: s.retries + 1})))
                fireMetrics()
                waitingForResend -= sending.length
            }, 10000)
        } finally {
            sendingQueueLength -= sendingLength
            httpThroughputMetrics[Math.floor(Date.now()/1000) % 5] += body.length
        }
        await new Promise(f => setTimeout(f, 100))
    }
}

async function startSpansSender () {
    while (true) {
        if (!spansToSend.length) {
            await new Promise(f => onSpans.push(f))
        }
        let toSend = ['[']
        let len = 2
        let i = 0
        spansToSend = spansToSend.filter(m => m.payload)
        for (; i < spansToSend.length && len < 20 * 1024 * 1024; i++) {
            if (i > 0) {
                toSend.push(',')
            }
            let str = JSON.stringify(spansToSend[i].payload)
            if (!str) {
                continue
            }
            str = str.substring(1, str.length - 1)
            toSend.push(str)
            len += str.length
        }
        toSend.push(']')
        let sending = spansToSend.slice(0, i)
        spansToSend = spansToSend.slice(i)
        fireSpans()
        const body = toSend.join('')
        toSend = null
        const sendingLength = sending.length
        sendingQueueLength += sendingLength
        sending = sending.filter(s => s.retries < 4)
        try {
            var response = await axios.post(`${module.exports.host}/tempo/spans`, body, {
                headers: {
                    'Content-Type': 'application/json'
                }
            })
            //logger.debug('Spans posted', response.status, response.statusText)
        } catch (e) {
            sendingErrors += sendingLength
            if (e instanceof axios.AxiosError) {
                logger.error(`HTTP ERROR '${e.message}' [${e.response?.status}]: ${e.response?.data}`)
            } else {
                logger.error(e)
            }
            waitingForResend += sending.length
            setTimeout(() => {
                spansToSend.push.apply(spansToSend,
                    sending.filter(s => s.retries < 4).map(s => ({...s, retries: s.retries + 1})))
                fireSpans()
                waitingForResend -= sending.length
            }, 10000)
        } finally {
            sendingQueueLength -= sendingLength
            httpThroughputMetrics[Math.floor(Date.now()/1000) % 5] += body.length
        }
        await new Promise(f => setTimeout(f, 100))
    }
}

for (let i = 0; i < 10; i++) {
    startMetricsSender()
    startSpansSender()
}

(() => {
    let lastReport = Date.now()
    setInterval(() => {
        if (Date.now() - lastReport >= 5000) {
            const avgThroughput = httpThroughputMetrics.reduce((sum, a) => sum + a, 0) / 5 / 1024 / 1024
            logger.info(`input_queue=${metricsToSend.length + spansToSend.length} ` +
                `errors=${sendingErrors} currently_sending=${sendingQueueLength} ` +
                `avg_5s_throughput=${avgThroughput}MB/s`)
            lastReport = Date.now()
        }
        httpThroughputMetrics[(Math.floor(Date.now()/1000) + 1) % 5] = 0
    }, 1000)
})()

module.exports = {
    sendMetrics,
    sendSpans,
    host: ''
}<commit_msg>debug maxBodyLength & maxContentLength<commit_after>const axios = require('axios')
const {logger} = require("@pastash/pastash");

let metricsToSend = []
let spansToSend = []
let onMetrics = []
let onSpans = []
let httpThroughputMetrics = [0,0,0,0,0]
let sendingQueueLength = 0
let sendingErrors = 0
let waitingForResend = 0

function fireMetrics() {
    metricsToSend.length && onMetrics.length && onMetrics.pop()()
}

function fireSpans() {
    spansToSend.length && onSpans.length && onSpans.pop()()
}

function sendMetrics(obj, retries) {
    retries = retries || 0
    metricsToSend.push({retries, payload: obj})
    fireMetrics()
}

function sendSpans(obj, retries) {
    retries = retries || 0
    spansToSend.push({retries, payload: obj})
    fireSpans()
}

async function startMetricsSender () {
    while (true) {
        if (!metricsToSend.length) {
            await new Promise(f => onMetrics.push(f))
        }
        let toSend = ['{"streams":[']
        let len = 14
        let i = 0
        metricsToSend = metricsToSend.filter(m => m.payload)
        for (; i < metricsToSend.length && len < 20 * 1024 * 1024; i++) {
            if (i > 0) {
                toSend.push(',')
            }
            let str = JSON.stringify(metricsToSend[i].payload.streams)
            str = str.substring(1, str.length - 1)
            toSend.push(str)
            len += str.length
        }
        toSend.push(']}')
        let sending = metricsToSend.slice(0, i)
        metricsToSend = metricsToSend.slice(i)
        fireMetrics()
        const body = toSend.join('')
        toSend = null
        const sendingLength = sending.length
        sendingQueueLength += sendingLength
        sending = sending.filter(s => s.retries < 4)
        try {
            var response = await axios.post(`${module.exports.host}/loki/api/v1/push`, body, {
                maxBodyLength: 50 * 1024 * 1024,
                maxContentLength: 50 * 1024 * 1024,
                headers: {
                    'Content-Type': 'application/json'
                }
            })
            //logger.debug('Metrics posted', response.status, response.statusText)
        } catch (e) {
            sendingErrors += sendingLength
            if (e instanceof axios.AxiosError) {
                logger.error(`HTTP ERROR '${e.message}' [${e.response?.status}]: ${e.response?.data}`)
            } else {
                logger.error(e)
            }
            waitingForResend += sending.length
            setTimeout(() => {
                metricsToSend.push.apply(metricsToSend,
                    sending.map(s => ({...s, retries: s.retries + 1})))
                fireMetrics()
                waitingForResend -= sending.length
            }, 10000)
        } finally {
            sendingQueueLength -= sendingLength
            httpThroughputMetrics[Math.floor(Date.now()/1000) % 5] += body.length
        }
        await new Promise(f => setTimeout(f, 100))
    }
}

async function startSpansSender () {
    while (true) {
        if (!spansToSend.length) {
            await new Promise(f => onSpans.push(f))
        }
        let toSend = ['[']
        let len = 2
        let i = 0
        spansToSend = spansToSend.filter(m => m.payload)
        for (; i < spansToSend.length && len < 20 * 1024 * 1024; i++) {
            if (i > 0) {
                toSend.push(',')
            }
            let str = JSON.stringify(spansToSend[i].payload)
            if (!str) {
                continue
            }
            str = str.substring(1, str.length - 1)
            toSend.push(str)
            len += str.length
        }
        toSend.push(']')
        let sending = spansToSend.slice(0, i)
        spansToSend = spansToSend.slice(i)
        fireSpans()
        const body = toSend.join('')
        toSend = null
        const sendingLength = sending.length
        sendingQueueLength += sendingLength
        sending = sending.filter(s => s.retries < 4)
        try {
            var response = await axios.post(`${module.exports.host}/tempo/spans`, body, {
                maxBodyLength: 50 * 1024 * 1024,
                maxContentLength: 50 * 1024 * 1024,
                headers: {
                    'Content-Type': 'application/json'
                }
            })
            //logger.debug('Spans posted', response.status, response.statusText)
        } catch (e) {
            sendingErrors += sendingLength
            if (e instanceof axios.AxiosError) {
                logger.error(`HTTP ERROR '${e.message}' [${e.response?.status}]: ${e.response?.data}`)
            } else {
                logger.error(e)
            }
            waitingForResend += sending.length
            setTimeout(() => {
                spansToSend.push.apply(spansToSend,
                    sending.filter(s => s.retries < 4).map(s => ({...s, retries: s.retries + 1})))
                fireSpans()
                waitingForResend -= sending.length
            }, 10000)
        } finally {
            sendingQueueLength -= sendingLength
            httpThroughputMetrics[Math.floor(Date.now()/1000) % 5] += body.length
        }
        await new Promise(f => setTimeout(f, 100))
    }
}

for (let i = 0; i < 10; i++) {
    startMetricsSender()
    startSpansSender()
}

(() => {
    let lastReport = Date.now()
    setInterval(() => {
        if (Date.now() - lastReport >= 5000) {
            const avgThroughput = httpThroughputMetrics.reduce((sum, a) => sum + a, 0) / 5 / 1024 / 1024
            logger.info(`input_queue=${metricsToSend.length + spansToSend.length} ` +
                `errors=${sendingErrors} currently_sending=${sendingQueueLength} ` +
                `avg_5s_throughput=${avgThroughput}MB/s`)
            lastReport = Date.now()
        }
        httpThroughputMetrics[(Math.floor(Date.now()/1000) + 1) % 5] = 0
    }, 1000)
})()

module.exports = {
    sendMetrics,
    sendSpans,
    host: ''
}<|endoftext|>


<commit_before>// create the global engine object
var engine = global.engine = {};

// dependencies
var WebSocketServer = require('ws').Server;
var httpServer = require('http');
var Flow = require('./client/flow');

// create flow emitter out of engine
engine = Flow(engine);

// static values
engine.operation_id = '@';
engine.public_file_id = '!';
engine.public_session = '*';
engine.session_role = 'role';
engine.session_locale = 'locale';
engine.session_user = 'user';
engine.http = {
    'maxAge': 86400,
    'maxAge_fingerprint': 94670000
};

// set network access
engine._access = {
    'M': true,
    'C': true,
    'E': true,
    'P': true,
    'F': true,
    'W': true,
};

// set public role
engine._roles = {
    '*': true
};

// engine global dependend dependencies
var Session = require('./session');
var Composition = require('./composition');
var Instance = require('./client/instance');
var Static = require('./static');
var utils = require('./client/utils');

// data transform handlers
engine.handlers = {
    transform: require('./client/transform')
};

/**
 * Create server module instances
 */
engine.load = function (name, role, callback) {

    // ensure callback
    callback = callback || function () {};

    if (!name) {
        return callback(engine.log('E', new Error('No composition name.')));
    }

    // check instance chache
    if (engine.instances[name]) {

        if (!utils.roleAccess(engine.instances[name], role)) {
            return callback(engine.log('E', new Error('Access denied for instance:' + name)));
        }

        return callback(null, engine.instances[name]);
    }

    // tell cache to remove instance on composition change
    var related = {instances: {}};
    related.instances[name] = true;

    // get composition
    Composition(name, related, role, function (err, composition) {

        if (err) {
            return callback(err);
        }

        if (!composition._main) {
            return callback(engine.log('E', new Error('Module "' + composition.module + '" has no "main" config in the package.json.')));
        }

        // require module and create instance
        Instance(require(composition._main), composition, role, callback);
    });
};

/**
 * Start the HTTP and WebSocket servers.
 *
 * @public
 * @param {string} The absolute path to the repo.
 * @param {number} The port number.
 * @param {boolean} Indicates if engine should run in production mode.
 */
module.exports = function start (repo, port, logLevel, production) {

    // save starting parameters
    engine.repo = repo + (repo[(repo.length - 1)] === '/' ? '' : '/');
    engine.port = port;
    engine.production = production;
    engine.logLevel = logLevel || (production ? 'error' : 'debug');

    // static paths values
    engine.root = require('path').normalize(__dirname + '/../');
    engine.paths = {
        app_public: engine.repo + 'public/',
        app_markup: engine.repo + 'markup/',
        app_composition: engine.repo + 'composition/'
    };

    // extend engine with logging methods
    engine.log = require('./client/logs');

    // save engine in instances cache under the operation id
    engine.instances[engine.operation_id] = engine;

    // create a http server and listen to requests, with the session request handler
    engine.http.server = httpServer.createServer(Session);

    // create a websocket server
    engine.socket = new WebSocketServer({server: engine.http.server});

    // start http server
    engine.http.server.listen(port, function () {

        // core http resouce event interface
        engine.mind(['E', Static.client])
              .mind(['P', Static.public])
              .mind(['F', Static.file])
              .mind(['W', Static.wrap])
              // TODO load html snippted over websocket,
              //      until html imports are supported
              .mind(['M', Static.markup])
              .mind(['C', Static.composition]);

        // listen to websocket connections with the session connection handler
        engine.socket.on('connection', Session);
    });
};
<commit_msg>reload handler dummy array<commit_after>// create the global engine object
var engine = global.engine = {_r: []};

// dependencies
var WebSocketServer = require('ws').Server;
var httpServer = require('http');
var Flow = require('./client/flow');

// create flow emitter out of engine
engine = Flow(engine);

// static values
engine.operation_id = '@';
engine.public_file_id = '!';
engine.public_session = '*';
engine.session_role = 'role';
engine.session_locale = 'locale';
engine.session_user = 'user';
engine.http = {
    'maxAge': 86400,
    'maxAge_fingerprint': 94670000
};

// set network access
engine._access = {
    'M': true,
    'C': true,
    'E': true,
    'P': true,
    'F': true,
    'W': true,
};

// set public role
engine._roles = {
    '*': true
};

// engine global dependend dependencies
var Session = require('./session');
var Composition = require('./composition');
var Instance = require('./client/instance');
var Static = require('./static');
var utils = require('./client/utils');

// data transform handlers
engine.handlers = {
    transform: require('./client/transform')
};

/**
 * Create server module instances
 */
engine.load = function (name, role, callback) {

    // ensure callback
    callback = callback || function () {};

    if (!name) {
        return callback(engine.log('E', new Error('No composition name.')));
    }

    // check instance chache
    if (engine.instances[name]) {

        if (!utils.roleAccess(engine.instances[name], role)) {
            return callback(engine.log('E', new Error('Access denied for instance:' + name)));
        }

        return callback(null, engine.instances[name]);
    }

    // tell cache to remove instance on composition change
    var related = {instances: {}};
    related.instances[name] = true;

    // get composition
    Composition(name, related, role, function (err, composition) {

        if (err) {
            return callback(err);
        }

        if (!composition._main) {
            return callback(engine.log('E', new Error('Module "' + composition.module + '" has no "main" config in the package.json.')));
        }

        // require module and create instance
        Instance(require(composition._main), composition, role, callback);
    });
};

/**
 * Start the HTTP and WebSocket servers.
 *
 * @public
 * @param {string} The absolute path to the repo.
 * @param {number} The port number.
 * @param {boolean} Indicates if engine should run in production mode.
 */
module.exports = function start (repo, port, logLevel, production) {

    // save starting parameters
    engine.repo = repo + (repo[(repo.length - 1)] === '/' ? '' : '/');
    engine.port = port;
    engine.production = production;
    engine.logLevel = logLevel || (production ? 'error' : 'debug');

    // static paths values
    engine.root = require('path').normalize(__dirname + '/../');
    engine.paths = {
        app_public: engine.repo + 'public/',
        app_markup: engine.repo + 'markup/',
        app_composition: engine.repo + 'composition/'
    };

    // extend engine with logging methods
    engine.log = require('./client/logs');

    // save engine in instances cache under the operation id
    engine.instances[engine.operation_id] = engine;

    // create a http server and listen to requests, with the session request handler
    engine.http.server = httpServer.createServer(Session);

    // create a websocket server
    engine.socket = new WebSocketServer({server: engine.http.server});

    // start http server
    engine.http.server.listen(port, function () {

        // core http resouce event interface
        engine.mind(['E', Static.client])
              .mind(['P', Static.public])
              .mind(['F', Static.file])
              .mind(['W', Static.wrap])
              // TODO load html snippted over websocket,
              //      until html imports are supported
              .mind(['M', Static.markup])
              .mind(['C', Static.composition]);

        // listen to websocket connections with the session connection handler
        engine.socket.on('connection', Session);
    });
};
<|endoftext|>


<commit_before>var colorz = require('colorz')

function engine () {
  var options

  function kindOf (value) {
  if (value === null) return 'null'
  if (value === undefined) return 'undefined'
  if (Array.isArray(value)) return 'array'

  return typeof value === 'object'
    ? Object.prototype.toString.call(value)
      .replace(/^\[object |\]$/g, '')
      .toLowerCase()
    : typeof value
}

  function isObject (obj) {
    return Object.prototype.toString.call(obj) === '[object Object]'
  }

  function filter (arr, fn) {
    var result = []

    var val
    var i = -1
    var j = -1
    var len = arr.length

    while (++i < len) {
      val = arr[i]
      if (fn(val, i, arr)) result[++j] = val
    }
    return result
  }

  function repeat (str, n) {
    var result = ''

    while (n > 0) {
      if (n % 2) result += str
      n = Math.floor(n / 2)
      str += str
    }
    return result
  }

  function indent (str, char, num) {
    if (num === 0) return str
    char = num > 1
      ? repeat(char, num)
      : char

    var re = /^(?!\s*$)/mg
    return str.replace(re, char)
  }

  function getType (value) {
    var map = {
      'number'    : 'num',
      'string'    : 'str',
      'boolean'   : 'bool',
      'function'  : 'func',
      'null'      : 'null',
      'undefined' : 'undef',
      'object'    : 'obj',
      'array'     : 'arr',
      'regexp'    : 'regex',
      'date'      : 'date'
    }
    return map[kindOf(value)] || map['' + value]
  }

  function cleanObject (obj) {
    var lastKey = ''
    var key

    for (key in obj) {
      // get object's prototype last key for placement of trailing comma
      lastKey = key
    }
    return lastKey
  }

  function cleanArray (arr) {
    if (options.display.xarr) return arr

    return filter(arr, function (item) {
      return ['func', 'obj', 'arr', 'date'].indexOf(getType(item)) === -1
    })
  }

  function generateLevel (level) {
    var levelStr = repeat(' ', options.level.spaces)
    var opts = options.level

    if (options.level.show && levelStr.length) {
      levelStr = levelStr.replace(' ', useColorProvider(opts.char, opts.color))
    }
    return repeat(levelStr, level)
  }

  function hasChild (obj) {
    var key
    for (key in obj) {
      if (Array.isArray(obj[key]) || isObject(obj[key])) return true
    }
  }

  function colorify (value, level) {
    var type = getType(value)
    var color = options.colors[type]

    return generateLevel(type === 'func' ? 0 : level)
      + (type === 'str' ? colorifySpec('"', 'quot') : '')
      + useColorProvider(formatOutputType(value, type, level), color)
      + (type === 'str' ? colorifySpec('"', 'quot') : '')
  }

  function colorifySpec (char, type, level) {
    return generateLevel(level) + useColorProvider('' + char, options.colors[type])
  }

  function useColorProvider (str, color) {
    if (!color) return str
    if (options.params.colored) {
      if (Array.isArray(color) && color.length > 1) {
        return useColorProvider(colorz[color[0]](str), color.slice(1))
      } else {
        return colorz[Array.isArray(color) ? color[0] : color](str)
      }
    }
    return str
  }

  function formatOutputType (value, type, level) {
    if (type === 'func') {
      if (options.display.func) {
        var str = value.toString().split(/\n/)
        var first = str[0] + '\n'
        var rest = str.slice(1)
        return first + indent(rest.join('\n'), ' ', generateLevel(level).length)
      } else {
        return '[Function]'
      }
    }

    if (type === 'date' && !options.display.date) return '[Date]'

    return '' + value
  }

  return {
    gen: function (json, level, isChild) {
      var colored = ''
      var result
      var key

      level = level || 0

      if (isObject(json)) {
        var lastKey = cleanObject(json)
        colored += colorifySpec('{', 'brack', isChild ? 0 : level) + '\n'
        level++

        for (key in json) {
          result = colorifySpec(key, 'attr', level)
            + colorifySpec(': ', 'punc')
            + this.gen(json[key], level, true)
            + (key !== lastKey ? colorifySpec(',', 'punc') : '')

          colored += result + '\n'
        }

        colored += colorifySpec('}', 'brack', --level)
      } else if (Array.isArray(json)) {
        json = cleanArray(json)

        if (hasChild(json)) {
          result = json.map(function (item) {
            return this.gen(item, level + 1)
          }.bind(this))

          colored += colorifySpec('[', 'brack', isChild ? 0 : level)
          colored += result.join(colorifySpec(', ', 'punc') + '\n')
          colored += colorifySpec(']', 'brack', level)
        } else {
          var coloredArray = colorifySpec('[', 'brack', isChild ? 0 : level)

          for (key in json) {
            coloredArray += colorify(json[key]) + (json.length - 1 > key ? colorifySpec(', ', 'punc') : '')
          }

          colored += coloredArray + colorifySpec(']', 'brack')
        }
      } else {
        return generateLevel(isChild ? 0 : level)
          + colorify(json, typeof json === 'function' ? level : '')
      }

      return colored
    },

    setOptions: function (opts) {
      options = opts
      return this
    }
  }
}

module.exports = engine()
<commit_msg>update lib/engine -- always show objects and arrays in filtered arrays<commit_after>var colorz = require('colorz')

function engine () {
  var options

  function kindOf (value) {
  if (value === null) return 'null'
  if (value === undefined) return 'undefined'
  if (Array.isArray(value)) return 'array'

  return typeof value === 'object'
    ? Object.prototype.toString.call(value)
      .replace(/^\[object |\]$/g, '')
      .toLowerCase()
    : typeof value
}

  function isObject (obj) {
    return Object.prototype.toString.call(obj) === '[object Object]'
  }

  function filter (arr, fn) {
    var result = []

    var val
    var i = -1
    var j = -1
    var len = arr.length

    while (++i < len) {
      val = arr[i]
      if (fn(val, i, arr)) result[++j] = val
    }
    return result
  }

  function repeat (str, n) {
    var result = ''

    while (n > 0) {
      if (n % 2) result += str
      n = Math.floor(n / 2)
      str += str
    }
    return result
  }

  function indent (str, char, num) {
    if (num === 0) return str
    char = num > 1
      ? repeat(char, num)
      : char

    var re = /^(?!\s*$)/mg
    return str.replace(re, char)
  }

  function getType (value) {
    var map = {
      'number'    : 'num',
      'string'    : 'str',
      'boolean'   : 'bool',
      'function'  : 'func',
      'null'      : 'null',
      'undefined' : 'undef',
      'object'    : 'obj',
      'array'     : 'arr',
      'regexp'    : 'regex',
      'date'      : 'date'
    }
    return map[kindOf(value)] || map['' + value]
  }

  function cleanObject (obj) {
    var lastKey = ''
    var key

    for (key in obj) {
      // get object's prototype last key for placement of trailing comma
      lastKey = key
    }
    return lastKey
  }

  function cleanArray (arr) {
    if (options.display.xarr) return arr

    return filter(arr, function (item) {
      return ['func', 'date'].indexOf(getType(item)) === -1
    })
  }

  function generateLevel (level) {
    var levelStr = repeat(' ', options.level.spaces)
    var opts = options.level

    if (options.level.show && levelStr.length) {
      levelStr = levelStr.replace(' ', useColorProvider(opts.char, opts.color))
    }
    return repeat(levelStr, level)
  }

  function hasChild (obj) {
    var key
    for (key in obj) {
      if (Array.isArray(obj[key]) || isObject(obj[key])) return true
    }
  }

  function colorify (value, level) {
    var type = getType(value)
    var color = options.colors[type]

    return generateLevel(type === 'func' ? 0 : level)
      + (type === 'str' ? colorifySpec('"', 'quot') : '')
      + useColorProvider(formatOutputType(value, type, level), color)
      + (type === 'str' ? colorifySpec('"', 'quot') : '')
  }

  function colorifySpec (char, type, level) {
    return generateLevel(level) + useColorProvider('' + char, options.colors[type])
  }

  function useColorProvider (str, color) {
    if (!color) return str
    if (options.params.colored) {
      if (Array.isArray(color) && color.length > 1) {
        return useColorProvider(colorz[color[0]](str), color.slice(1))
      } else {
        return colorz[Array.isArray(color) ? color[0] : color](str)
      }
    }
    return str
  }

  function formatOutputType (value, type, level) {
    if (type === 'func') {
      if (options.display.func) {
        var str = value.toString().split(/\n/)
        var first = str[0] + '\n'
        var rest = str.slice(1)
        return first + indent(rest.join('\n'), ' ', generateLevel(level).length)
      } else {
        return '[Function]'
      }
    }

    if (type === 'date' && !options.display.date) return '[Date]'

    return '' + value
  }

  return {
    gen: function (json, level, isChild) {
      var colored = ''
      var result
      var key

      level = level || 0

      if (isObject(json)) {
        var lastKey = cleanObject(json)
        colored += colorifySpec('{', 'brack', isChild ? 0 : level) + '\n'
        level++

        for (key in json) {
          result = colorifySpec(key, 'attr', level)
            + colorifySpec(': ', 'punc')
            + this.gen(json[key], level, true)
            + (key !== lastKey ? colorifySpec(',', 'punc') : '')

          colored += result + '\n'
        }

        colored += colorifySpec('}', 'brack', --level)
      } else if (Array.isArray(json)) {
        json = cleanArray(json)

        if (hasChild(json)) {
          result = json.map(function (item) {
            return this.gen(item, level + 1)
          }.bind(this))

          colored += colorifySpec('[', 'brack', isChild ? 0 : level)
          colored += result.join(colorifySpec(', ', 'punc') + '\n')
          colored += colorifySpec(']', 'brack', level)
        } else {
          var coloredArray = colorifySpec('[', 'brack', isChild ? 0 : level)

          for (key in json) {
            coloredArray += colorify(json[key]) + (json.length - 1 > key ? colorifySpec(', ', 'punc') : '')
          }

          colored += coloredArray + colorifySpec(']', 'brack')
        }
      } else {
        return generateLevel(isChild ? 0 : level)
          + colorify(json, typeof json === 'function' ? level : '')
      }

      return colored
    },

    setOptions: function (opts) {
      options = opts
      return this
    }
  }
}

module.exports = engine()
<|endoftext|>