<commit_before>/**
 * Feature track that draws features using HTML5 canvas elements.
 */

define( [
            'dojo/_base/declare',
            'dojo/dom-construct',
            'dojo/_base/array',
            'dojo/dom-geometry',
            'dojo/on',
            'JBrowse/View/GranularRectLayout',
            'JBrowse/View/Track/Canvas',
            'JBrowse/Errors',
            'JBrowse/View/Track/FeatureDetailMixin'
        ],
        function( declare, dom, array, domGeom, on, Layout, CanvasTrack, Errors, FeatureDetailMixin ) {

// indexes feature layout rectangles (fRects) (which include features)
// by canvas pixel coordinate, and by unique ID.  one of these indexes
// in each block.
var FRectIndex = declare( null,  {
    constructor: function(args) {
        var canvas = args.canvas;

        this.canvasDims = { h: canvas.height, w: canvas.width };

        this.byCoord = new Array( canvas.width );
        for( var i = 0; i < canvas.width; i++ )
            this.byCoord[i] = new Array( canvas.height );

        this.byID = {};
    },

    getByID: function( id ) {
        return this.byID[id];
    },

    getByCoord: function( x, y ) {
        return (this.byCoord[x]||[])[y];
    },

    _clampCoord: function( val, lBound, uBound ) {
        return Math.round( Math.max( lBound, Math.min( val, uBound ) ) );
    },

    addAll: function( fRects ) {
        var byCoord = this.byCoord;
        var byID = this.byID;
        var cW = this.canvasDims.w;
        var cH = this.canvasDims.h;
        array.forEach( fRects, function( fRect ) {
            // by coord
            for( var i = 0; i < fRect.w; ++i ) {
                for( var j = 0; j < fRect.h; ++j ) {
                    var x = this._clampCoord( fRect.l + i, 0, cW-1 );
                    var y = this._clampCoord( fRect.t + j, 0, cH-1 );
                    byCoord[x][y] = fRect;
                }
            }

            // by ID
            byID[ fRect.f.id() ] = fRect;
        }, this );
    }
});

return declare( [CanvasTrack,FeatureDetailMixin], {

    constructor: function( args ) {
        this._setupEventHandlers();
    },

    _defaultConfig: function() {
        return {
            maxFeatureScreenDensity: 400,
            style: {
                bgcolor: 'goldenrod',
                mouseovercolor: 'rgba(0,0,0,0.3)',
                fgcolor: null,
                height: 11,
                marginBottom: 1
            }
        };
    },

    getStyle: function( feature, name ) {
        var val = this.config.style[name];
        if( typeof val == 'function' )
            return val.call( this, feature, name, null, null, this );
        else
            return val;
    },

    fillBlock: function( args ) {
        var blockIndex = args.blockIndex;
        var block = args.block;
        var leftBase = args.leftBase;
        var rightBase = args.rightBase;
        var scale = args.scale;

        if( ! this.testCanvasSupport( blockIndex, block ) )
            return;

        var region = { ref: this.refSeq.name, start: leftBase, end: rightBase };

        this.store.getRegionStats(
            region,
            dojo.hitch( this, function( stats ) {

                var density        = stats.featureDensity;
                var featureScale   = this.config.style.featureScale || density / this.config.maxFeatureScreenDensity; // (feat/bp) / ( feat/px ) = px/bp )

                if( scale < featureScale ) {
                    this.fillTooManyFeaturesMessage(
                        blockIndex,
                        block,
                        scale
                    );
                    args.finishCallback();
                }
                else {
                    this.fillFeatures( dojo.mixin( {stats: stats}, args ) );
                }
            }),
            dojo.hitch( this, function(e) {
                this._handleError(e);
                args.finishCallback(e);
            })
        );
    },

    _getLayout: function( scale ) {
        // create the layout if we need to, and if we can
        if( ( ! this.layout || this.layout.pitchX != 4/scale ) && scale  )
            this.layout = new Layout({pitchX: 4/scale, pitchY: this.config.layoutPitchY || (this.config.style.height + this.config.style.marginBottom) });

        return this.layout;
    },

    fillFeatures: function( args ) {
        var thisB = this;

        var blockIndex = args.blockIndex;
        var block = args.block;
        var scale = args.scale;
        var leftBase = args.leftBase;
        var rightBase = args.rightBase;
        var finishCallback = args.finishCallback;

        var timedOut = false;
        if( this.config.blockDisplayTimeout )
            window.setTimeout( function() { timedOut = true; }, this.config.blockDisplayTimeout );

        var fRects = [];

        var toX = function(coord) { return (coord-leftBase)*scale; };

        var featCallback = dojo.hitch(this,function( feature ) {
            if( timedOut )
                throw new Errors.TrackBlockTimeout({ track: this, blockIndex: blockIndex, block: block });

            fRects.push( this.layoutFeature( args, feature, toX ) );
        });

        this.store.getFeatures( { ref: this.refSeq.name,
                                  start: leftBase,
                                  end: rightBase
                                },

                                featCallback, // callback for each feature

                                // callback when all features sent
                                function () {
                                    var totalHeight = thisB._getLayout(scale)
                                                           .getTotalHeight();
                                    var c = block.featureCanvas =
                                        dojo.create(
                                            'canvas',
                                            { height: totalHeight,
                                              width:  block.offsetWidth+1,
                                              style: {
                                                  cursor: 'default',
                                                  height: totalHeight+'px'
                                              },
                                              innerHTML: 'Your web browser cannot display this type of thisB.',
                                              className: 'canvas-track'
                                            },
                                            block
                                        );
                                    thisB.renderFeatures( args, c, fRects );

                                    thisB.renderClickMap( args, c, fRects );

                                    thisB.layoutCanvases([c]);
                                    thisB.heightUpdate( totalHeight,
                                                        blockIndex );
                                    finishCallback();
                                },

                                dojo.hitch( thisB, function(e) {
                                    this._handleError(e);
                                    finishCallback(e);
                                })
                              );
    },

    startZoom: function() {
        this.inherited( arguments );

        array.forEach( this.blocks, function(b) {
            try {
                b.featureCanvas.style.width = '100%';
            } catch(e) {};
        });
    },
    endZoom: function() {

        array.forEach( this.blocks, function(b) {
            try {
                delete b.featureCanvas.style.width;
            } catch(e) {};
        });

        this.inherited( arguments );
    },

    // calculate the placement of the feature on the canvas for this
    // block.
    layoutFeature: function( viewArgs, feature, toX ) {
        var scale = viewArgs.scale;
        var layoutStart = feature.get('start');
        var layoutEnd   = feature.get('end');

        var fHeight = this.config.style.height;
        var levelHeight = fHeight + this.config.style.marginBottom;

        var uniqueId = feature.id();
        var top = this._getLayout( scale )
                      .addRect( uniqueId,
                                layoutStart,
                                layoutEnd,
                                levelHeight);

        var fRect = {
            l: toX(layoutStart),
            h: fHeight,
            t: top,

            f: feature,
            toX: toX
        };
        fRect.w = toX(layoutEnd) - fRect.l;

        return fRect;
    },

    renderClickMap: function( args, canvas, fRects ) {
        var thisB = this;
        var block = args.block;

        // make an index of the fRects by ID, and by coordinate, and
        // store it in the block
        var index = new FRectIndex({ canvas: canvas });
        block.fRectIndex = index;
        index.addAll( fRects );

        var context = canvas.getContext('2d');
        if( ! context ) {
            console.warn( "No 2d context available from canvas" );
            return;
        }

        // make features get highlighted on mouse move
        on( canvas, 'mousemove', function( evt ) {
                domGeom.normalizeEvent( evt );
                var fRect = index.getByCoord( evt.layerX, evt.layerY );
                thisB.highlightFeature( args, fRect && fRect.f );
        });
        on( canvas, 'mouseout', function( evt ) {
                thisB.highlightFeature( args, undefined );
        });

        // connect up the event handlers
        for( var event in this.eventHandlers ) {
            var handler = this.eventHandlers[event];
            on( canvas, event, function( evt ) {
                domGeom.normalizeEvent( evt );
                var fRect = index.getByCoord( evt.layerX, evt.layerY );
                if( fRect ) {
                    handler.call({
                                     track: thisB,
                                     feature: fRect.f,
                                     fRect: fRect,
                                     callbackArgs: [ thisB, fRect.f ]
                                 });
                }
            });
        }
    },

    // draw the features on the canvas
    renderFeatures: function( args, canvas, fRects ) {
        var context = canvas.getContext('2d');
        array.forEach( fRects, dojo.hitch( this, 'renderFeature', context, args ) );
    },

    // given viewargs and a feature object, highlight that feature in
    // all blocks.  if feature is undefined or null, unhighlight any currently
    // highlighted feature
    highlightFeature: function( args, feature ) {

        if( this.lastHighlight == feature )
            return;

        array.forEach( this.blocks, function( block ) {
            var context;
            try      {  context = block.featureCanvas.getContext('2d'); }
            catch(e) {  return;                                         }

            if( this.lastHighlight ) {
                var r = block.fRectIndex.getByID( this.lastHighlight.id() );
                if( r )
                    this.renderFeature( context, args, r );
            }

            if( feature ) {
                var fRect = block.fRectIndex.getByID( feature.id() );
                if( ! fRect )
                    return;

                context.fillStyle = this.getStyle( fRect.f, 'mouseovercolor' );
                context.fillRect( fRect.l, fRect.t, fRect.w, fRect.h );
            }
        }, this );

        this.lastHighlight = feature;
    },

    // draw each feature
    renderFeature: function( context, viewArgs, fRect ) {
        // background
        var bgcolor = this.getStyle( fRect.f, 'bgcolor' );
        if( bgcolor ) {
            context.fillStyle = bgcolor;
            context.fillRect( fRect.l, fRect.t, fRect.w, fRect.h );
        }

        // foreground border
        var fgcolor;
        if( fRect.h > 3 ) {
            fgcolor = this.getStyle( fRect.f, 'fgcolor' );
            if( fgcolor ) {
                context.lineWidth = 1;
                context.strokeStyle = fgcolor;

                // need to stroke a smaller rectangle to remain within
                // the bounds of the feature's overall height and
                // width, because of the way stroking is done in
                // canvas.  thus the +0.5 and -1 business.
                context.strokeRect( fRect.l+0.5, fRect.t+0.5, fRect.w-1, fRect.h-1 );
            }
        }
        else if( fRect.h > 1 ) {
            fgcolor = this.getStyle( fRect.f, 'fgcolor' );
            if( fgcolor ) {
                context.fillStyle = fgcolor;
                context.fillRect( fRect.l, fRect.t+fRect.h-1, fRect.w, 1 );
            }
        }
    }
});
});<commit_msg>fix CanvasFeature layout pitchY in case where style.height and/or style.marginBottom are functions<commit_after>/**
 * Feature track that draws features using HTML5 canvas elements.
 */

define( [
            'dojo/_base/declare',
            'dojo/dom-construct',
            'dojo/_base/array',
            'dojo/dom-geometry',
            'dojo/on',
            'JBrowse/View/GranularRectLayout',
            'JBrowse/View/Track/Canvas',
            'JBrowse/Errors',
            'JBrowse/View/Track/FeatureDetailMixin'
        ],
        function( declare, dom, array, domGeom, on, Layout, CanvasTrack, Errors, FeatureDetailMixin ) {

// indexes feature layout rectangles (fRects) (which include features)
// by canvas pixel coordinate, and by unique ID.  one of these indexes
// in each block.
var FRectIndex = declare( null,  {
    constructor: function(args) {
        var canvas = args.canvas;

        this.canvasDims = { h: canvas.height, w: canvas.width };

        this.byCoord = new Array( canvas.width );
        for( var i = 0; i < canvas.width; i++ )
            this.byCoord[i] = new Array( canvas.height );

        this.byID = {};
    },

    getByID: function( id ) {
        return this.byID[id];
    },

    getByCoord: function( x, y ) {
        return (this.byCoord[x]||[])[y];
    },

    _clampCoord: function( val, lBound, uBound ) {
        return Math.round( Math.max( lBound, Math.min( val, uBound ) ) );
    },

    addAll: function( fRects ) {
        var byCoord = this.byCoord;
        var byID = this.byID;
        var cW = this.canvasDims.w;
        var cH = this.canvasDims.h;
        array.forEach( fRects, function( fRect ) {
            // by coord
            for( var i = 0; i < fRect.w; ++i ) {
                for( var j = 0; j < fRect.h; ++j ) {
                    var x = this._clampCoord( fRect.l + i, 0, cW-1 );
                    var y = this._clampCoord( fRect.t + j, 0, cH-1 );
                    byCoord[x][y] = fRect;
                }
            }

            // by ID
            byID[ fRect.f.id() ] = fRect;
        }, this );
    }
});

return declare( [CanvasTrack,FeatureDetailMixin], {

    constructor: function( args ) {
        this._setupEventHandlers();
    },

    _defaultConfig: function() {
        return {
            maxFeatureScreenDensity: 400,
            style: {
                bgcolor: 'goldenrod',
                mouseovercolor: 'rgba(0,0,0,0.3)',
                fgcolor: null,
                height: 11,
                marginBottom: 1
            }
        };
    },

    getStyle: function( feature, name ) {
        var val = this.config.style[name];
        if( typeof val == 'function' )
            return val.call( this, feature, name, null, null, this );
        else
            return val;
    },

    fillBlock: function( args ) {
        var blockIndex = args.blockIndex;
        var block = args.block;
        var leftBase = args.leftBase;
        var rightBase = args.rightBase;
        var scale = args.scale;

        if( ! this.testCanvasSupport( blockIndex, block ) )
            return;

        var region = { ref: this.refSeq.name, start: leftBase, end: rightBase };

        this.store.getRegionStats(
            region,
            dojo.hitch( this, function( stats ) {

                var density        = stats.featureDensity;
                var featureScale   = this.config.style.featureScale || density / this.config.maxFeatureScreenDensity; // (feat/bp) / ( feat/px ) = px/bp )

                if( scale < featureScale ) {
                    this.fillTooManyFeaturesMessage(
                        blockIndex,
                        block,
                        scale
                    );
                    args.finishCallback();
                }
                else {
                    this.fillFeatures( dojo.mixin( {stats: stats}, args ) );
                }
            }),
            dojo.hitch( this, function(e) {
                this._handleError(e);
                args.finishCallback(e);
            })
        );
    },

    _getLayout: function( scale ) {
        // create the layout if we need to, and if we can
        if( ( ! this.layout || this.layout.pitchX != 4/scale ) && scale  ) {
            // if no layoutPitchY configured, calculate it from the
            // height and marginBottom (parseInt in case one or both are functions), or default to 3 if the
            // calculation didn't result in anything sensible.
            var pitchY = this.config.layoutPitchY || parseInt(this.config.style.height + this.config.style.marginBottom) || 3;
            this.layout = new Layout({ pitchX: 4/scale, pitchY: pitchY });
        }

        return this.layout;
    },

    fillFeatures: function( args ) {
        var thisB = this;

        var blockIndex = args.blockIndex;
        var block = args.block;
        var scale = args.scale;
        var leftBase = args.leftBase;
        var rightBase = args.rightBase;
        var finishCallback = args.finishCallback;

        var timedOut = false;
        if( this.config.blockDisplayTimeout )
            window.setTimeout( function() { timedOut = true; }, this.config.blockDisplayTimeout );

        var fRects = [];

        var toX = function(coord) { return (coord-leftBase)*scale; };

        var featCallback = dojo.hitch(this,function( feature ) {
            if( timedOut )
                throw new Errors.TrackBlockTimeout({ track: this, blockIndex: blockIndex, block: block });

            fRects.push( this.layoutFeature( args, feature, toX ) );
        });

        this.store.getFeatures( { ref: this.refSeq.name,
                                  start: leftBase,
                                  end: rightBase
                                },

                                featCallback, // callback for each feature

                                // callback when all features sent
                                function () {
                                    var totalHeight = thisB._getLayout(scale)
                                                           .getTotalHeight();
                                    var c = block.featureCanvas =
                                        dojo.create(
                                            'canvas',
                                            { height: totalHeight,
                                              width:  block.offsetWidth+1,
                                              style: {
                                                  cursor: 'default',
                                                  height: totalHeight+'px'
                                              },
                                              innerHTML: 'Your web browser cannot display this type of thisB.',
                                              className: 'canvas-track'
                                            },
                                            block
                                        );
                                    thisB.renderFeatures( args, c, fRects );

                                    thisB.renderClickMap( args, c, fRects );

                                    thisB.layoutCanvases([c]);
                                    thisB.heightUpdate( totalHeight,
                                                        blockIndex );
                                    finishCallback();
                                },

                                dojo.hitch( thisB, function(e) {
                                    this._handleError(e);
                                    finishCallback(e);
                                })
                              );
    },

    startZoom: function() {
        this.inherited( arguments );

        array.forEach( this.blocks, function(b) {
            try {
                b.featureCanvas.style.width = '100%';
            } catch(e) {};
        });
    },
    endZoom: function() {

        array.forEach( this.blocks, function(b) {
            try {
                delete b.featureCanvas.style.width;
            } catch(e) {};
        });

        this.inherited( arguments );
    },

    // calculate the placement of the feature on the canvas for this
    // block.
    layoutFeature: function( viewArgs, feature, toX ) {
        var scale = viewArgs.scale;
        var layoutStart = feature.get('start');
        var layoutEnd   = feature.get('end');

        var fHeight = this.config.style.height;
        var levelHeight = fHeight + this.config.style.marginBottom;

        var uniqueId = feature.id();
        var top = this._getLayout( scale )
                      .addRect( uniqueId,
                                layoutStart,
                                layoutEnd,
                                levelHeight);

        var fRect = {
            l: toX(layoutStart),
            h: fHeight,
            t: top,

            f: feature,
            toX: toX
        };
        fRect.w = toX(layoutEnd) - fRect.l;

        return fRect;
    },

    renderClickMap: function( args, canvas, fRects ) {
        var thisB = this;
        var block = args.block;

        // make an index of the fRects by ID, and by coordinate, and
        // store it in the block
        var index = new FRectIndex({ canvas: canvas });
        block.fRectIndex = index;
        index.addAll( fRects );

        var context = canvas.getContext('2d');
        if( ! context ) {
            console.warn( "No 2d context available from canvas" );
            return;
        }

        // make features get highlighted on mouse move
        on( canvas, 'mousemove', function( evt ) {
                domGeom.normalizeEvent( evt );
                var fRect = index.getByCoord( evt.layerX, evt.layerY );
                thisB.highlightFeature( args, fRect && fRect.f );
        });
        on( canvas, 'mouseout', function( evt ) {
                thisB.highlightFeature( args, undefined );
        });

        // connect up the event handlers
        for( var event in this.eventHandlers ) {
            var handler = this.eventHandlers[event];
            on( canvas, event, function( evt ) {
                domGeom.normalizeEvent( evt );
                var fRect = index.getByCoord( evt.layerX, evt.layerY );
                if( fRect ) {
                    handler.call({
                                     track: thisB,
                                     feature: fRect.f,
                                     fRect: fRect,
                                     callbackArgs: [ thisB, fRect.f ]
                                 });
                }
            });
        }
    },

    // draw the features on the canvas
    renderFeatures: function( args, canvas, fRects ) {
        var context = canvas.getContext('2d');
        array.forEach( fRects, dojo.hitch( this, 'renderFeature', context, args ) );
    },

    // given viewargs and a feature object, highlight that feature in
    // all blocks.  if feature is undefined or null, unhighlight any currently
    // highlighted feature
    highlightFeature: function( args, feature ) {

        if( this.lastHighlight == feature )
            return;

        array.forEach( this.blocks, function( block ) {
            var context;
            try      {  context = block.featureCanvas.getContext('2d'); }
            catch(e) {  return;                                         }

            if( this.lastHighlight ) {
                var r = block.fRectIndex.getByID( this.lastHighlight.id() );
                if( r )
                    this.renderFeature( context, args, r );
            }

            if( feature ) {
                var fRect = block.fRectIndex.getByID( feature.id() );
                if( ! fRect )
                    return;

                context.fillStyle = this.getStyle( fRect.f, 'mouseovercolor' );
                context.fillRect( fRect.l, fRect.t, fRect.w, fRect.h );
            }
        }, this );

        this.lastHighlight = feature;
    },

    // draw each feature
    renderFeature: function( context, viewArgs, fRect ) {
        // background
        var bgcolor = this.getStyle( fRect.f, 'bgcolor' );
        if( bgcolor ) {
            context.fillStyle = bgcolor;
            context.fillRect( fRect.l, fRect.t, fRect.w, fRect.h );
        }

        // foreground border
        var fgcolor;
        if( fRect.h > 3 ) {
            fgcolor = this.getStyle( fRect.f, 'fgcolor' );
            if( fgcolor ) {
                context.lineWidth = 1;
                context.strokeStyle = fgcolor;

                // need to stroke a smaller rectangle to remain within
                // the bounds of the feature's overall height and
                // width, because of the way stroking is done in
                // canvas.  thus the +0.5 and -1 business.
                context.strokeRect( fRect.l+0.5, fRect.t+0.5, fRect.w-1, fRect.h-1 );
            }
        }
        else if( fRect.h > 1 ) {
            fgcolor = this.getStyle( fRect.f, 'fgcolor' );
            if( fgcolor ) {
                context.fillStyle = fgcolor;
                context.fillRect( fRect.l, fRect.t+fRect.h-1, fRect.w, 1 );
            }
        }
    }
});
});<|endoftext|>


<commit_before>var Transform = require('pipestream').Transform;
var util = require('../../util');

function getWeinreScript(name, localUIHost) {
	return new Buffer('\r\n<script src="http://weinre.' + localUIHost + '/target/target-script-min.js#'
	+ name + '"></script>\r\n');
}

module.exports = function(req, res, next) {
	if (req.rules.weinre) {
		var localUIHost = this.config.localUIHost;
		res.on('src', function(_res) {
			if (!util.supportHtmlTransform(_res)) {
				return;
			}
			var name = util.getPath(util.rule.getMatcher(req.rules.weinre));
			if (!name) {
				return;
			}

			var transform = new Transform();
			transform._transform = function(chunk, encoding, callback) {
				if (!chunk) {
					chunk = getWeinreScript(name, localUIHost);
				}
				callback(null, chunk);
			};

			res.addZipTransform(transform, false, true);

		});
	}

	next();
};<commit_msg>auto focus<commit_after>var Transform = require('pipestream').Transform;
var util = require('../../util');

function getWeinreScript(name, localUIHost) {
	return new Buffer('\r\n<script src="http://weinre.' + localUIHost + '/target/target-script-min.js#'
	+ (name || 'weinre') + '"></script>\r\n');
}

module.exports = function(req, res, next) {
	if (req.rules.weinre) {
		var localUIHost = this.config.localUIHost;
		res.on('src', function(_res) {
			if (!util.supportHtmlTransform(_res)) {
				return;
			}
			var name = util.getPath(util.rule.getMatcher(req.rules.weinre));
			if (!name) {
				return;
			}

			var transform = new Transform();
			transform._transform = function(chunk, encoding, callback) {
				if (!chunk) {
					chunk = getWeinreScript(name, localUIHost);
				}
				callback(null, chunk);
			};

			res.addZipTransform(transform, false, true);

		});
	}

	next();
};<|endoftext|>


<commit_before>/**
 * @overview tests for ccm component for rendering a quiz
 * @author André Kless <andre.kless@web.de> 2017
 * @license The MIT License (MIT)
 */

ccm.files[ 'ccm.quiz.tests.js' ] = {
  setup: function ( suite, callback ) {
    suite.container = document.createElement( 'div' );
    document.body.appendChild( suite.container );
    suite.ccm.component( './../../ccm-components/quiz/ccm.quiz.js', { element: suite.container }, function ( component ) {
      suite.component = component;
      callback();
    } );
  },
  fundamental: {
    setup: function ( suite, callback ) {
      suite.component.instance( function ( instance ) {
        suite.instance = instance;
        callback();
      } );
    },
    tests: {
      componentName: function ( suite ) {
        suite.assertSame( 'quiz', suite.instance.component.name );
      },
      frameworkVersion: function ( suite ) {
        suite.assertEquals( '8.0.0', suite.instance.ccm.version() );
      },
      publicProperties: function ( suite ) {
        suite.assertEquals( [ 'start', 'ccm', 'element', 'id', 'index', 'component' ], Object.keys( suite.instance ) );
      },
      startCallback: function ( suite ) {
        suite.instance.start( suite.passed );
      },
      componentTag: function ( suite ) {
        suite.container.innerHTML = '<ccm-quiz></ccm-quiz>';
        suite.passed();
      }
    }
  },
  templates: {
    setup: function ( suite, callback ) {
      suite.component.start( { questions: [ {}, {} ] }, function ( instance ) {
        suite.instance = instance;
        callback();
      } );
    },
    tests: {
      main: function ( suite ) {
        if ( !suite.instance.element.querySelector( '#questions' ) ) return suite.failed( 'missing "questions" container' );
        if ( !suite.instance.element.querySelector( '#prev' ) ) return suite.failed( 'missing "prev" container' );
        if ( !suite.instance.element.querySelector( '#next' ) ) return suite.failed( 'missing "next" container' );
        if ( !suite.instance.element.querySelector( '#finish' ) ) return suite.failed( 'missing "finish" container' );
        suite.passed();
      }
    }
  },
  dependencies: {
    tests: {
      loggedInUser: function ( suite ) {
        suite.component.start( {
          user: [ 'ccm.instance', './../../ccm-components/user/ccm.user.js' ],
          onfinish: function ( instance ) {
            suite.assertTrue( instance.user.isLoggedIn() );
          }
        }, function ( instance ) {
          if ( instance.user.isLoggedIn() ) suite.failed( 'user is already logged in' );
          instance.element.querySelector( 'button' ).click();
        } );
      },
      logStartEvent: function ( suite ) {
        suite.component.start( {
          logger: [ 'ccm.instance', './../../ccm-components/log/ccm.log.js', { onfinish: function ( instance, results ) {
            suite.assertSame( 'start', results.event );
          } } ]
        } );
      },
      logFinishEvent: function ( suite ) {
        suite.component.start( {
          logger: [ 'ccm.instance', './../../ccm-components/log/ccm.log.js', {
            events: { finish: true },
            onfinish: function ( instance, results ) {
              suite.assertSame( 'finish', results.event );
            }
          } ]
        }, function ( instance ) {
          instance.element.querySelector( 'button' ).click();
        } );
      }
    }
  },
  data: {
    tests: {
      singleQuestion: function ( suite ) {
        suite.component.start( {
          questions: {},
          logger: [ 'ccm.instance', './../../ccm-components/log/ccm.log.js', {
            logging: { data: true },
            onfinish: function ( instance, results ) {
              suite.assertSame( 1, results.data.questions.length );
            }
          } ]
        } );
      },
      defaultsByConfig: function ( suite ) {
        suite.component.start( {
          text: true, description: true, answers: true, input: true, attributes: true, swap: true, encode: true, random: true, feedback: true, correct: true,
          questions: {},
          logger: [ 'ccm.instance', './../../ccm-components/log/ccm.log.js', {
            logging: { data: true },
            onfinish: function ( instance, results ) {

              var data = results.data;
              if ( data.text        ) return suite.failed( 'text property not deleted' );
              if ( data.description ) return suite.failed( 'description property not deleted' );
              if ( data.answers     ) return suite.failed( 'answers property not deleted' );
              if ( data.input       ) return suite.failed( 'input property not deleted' );
              if ( data.attributes  ) return suite.failed( 'attributes property not deleted' );
              if ( data.swap        ) return suite.failed( 'swap property not deleted' );
              if ( data.encode      ) return suite.failed( 'encode property not deleted' );
              if ( data.random      ) return suite.failed( 'random property not deleted' );
              if ( data.feedback    ) return suite.failed( 'feedback property not deleted' );
              if ( data.correct     ) return suite.failed( 'correct property not deleted' );

              var question = data.questions[ 0 ];
              if ( !question.text        ) return suite.failed( 'missing text property' );
              if ( !question.description ) return suite.failed( 'missing description property' );
              if ( !question.answers     ) return suite.failed( 'missing answers property' );
              if ( !question.input       ) return suite.failed( 'missing input property' );
              if ( !question.random      ) return suite.failed( 'missing random property' );
              if ( !question.feedback    ) return suite.failed( 'missing feedback property' );
              if ( !question.correct     ) return suite.failed( 'missing correct property' );

              var answer = question.answers[ 0 ];
              if ( !answer.attributes  ) return suite.failed( 'missing attributes property' );
              if ( !answer.swap        ) return suite.failed( 'missing swap property' );
              if ( !answer.encode      ) return suite.failed( 'missing encode property' );

              suite.passed();
            }
          } ]
        } );
      },
      defaultInput: function ( suite ) {
        suite.component.start( {
          questions: {},
          logger: [ 'ccm.instance', './../../ccm-components/log/ccm.log.js', {
            logging: { data: true },
            onfinish: function ( instance, results ) {
              suite.assertSame( 'checkbox', results.data.questions[ 0 ].input );
            }
          } ]
        } );
      },
      singleAnswer: function ( suite ) {
        suite.component.start( {
          questions: { answers: {} },
          logger: [ 'ccm.instance', './../../ccm-components/log/ccm.log.js', {
            logging: { data: true },
            onfinish: function ( instance, results ) {
              suite.assertSame( 1, results.data.questions[ 0 ].answers.length );
            }
          } ]
        } );
      }
    }
  },
  finally: function ( suite, callback ) {
    document.body.removeChild( suite.container );
    callback();
  }
};

ccm.components.testsuite.quiz = ccm.files[ 'ccm.quiz.tests.js' ];<commit_msg>add unit test for ccm.quiz.js<commit_after>/**
 * @overview tests for ccm component for rendering a quiz
 * @author André Kless <andre.kless@web.de> 2017
 * @license The MIT License (MIT)
 */

ccm.files[ 'ccm.quiz.tests.js' ] = {
  setup: function ( suite, callback ) {
    suite.container = document.createElement( 'div' );
    document.body.appendChild( suite.container );
    suite.ccm.component( './../../ccm-components/quiz/ccm.quiz.js', { element: suite.container }, function ( component ) {
      suite.component = component;
      callback();
    } );
  },
  fundamental: {
    setup: function ( suite, callback ) {
      suite.component.instance( function ( instance ) {
        suite.instance = instance;
        callback();
      } );
    },
    tests: {
      componentName: function ( suite ) {
        suite.assertSame( 'quiz', suite.instance.component.name );
      },
      frameworkVersion: function ( suite ) {
        suite.assertEquals( '8.0.0', suite.instance.ccm.version() );
      },
      publicProperties: function ( suite ) {
        suite.assertEquals( [ 'start', 'ccm', 'element', 'id', 'index', 'component' ], Object.keys( suite.instance ) );
      },
      startCallback: function ( suite ) {
        suite.instance.start( suite.passed );
      },
      componentTag: function ( suite ) {
        suite.container.innerHTML = '<ccm-quiz></ccm-quiz>';
        suite.passed();
      }
    }
  },
  templates: {
    setup: function ( suite, callback ) {
      suite.component.start( { questions: [ {}, {} ] }, function ( instance ) {
        suite.instance = instance;
        callback();
      } );
    },
    tests: {
      main: function ( suite ) {
        if ( !suite.instance.element.querySelector( '#questions' ) ) return suite.failed( 'missing "questions" container' );
        if ( !suite.instance.element.querySelector( '#prev' ) ) return suite.failed( 'missing "prev" container' );
        if ( !suite.instance.element.querySelector( '#next' ) ) return suite.failed( 'missing "next" container' );
        if ( !suite.instance.element.querySelector( '#finish' ) ) return suite.failed( 'missing "finish" container' );
        suite.passed();
      }
    }
  },
  dependencies: {
    tests: {
      loggedInUser: function ( suite ) {
        suite.component.start( {
          user: [ 'ccm.instance', './../../ccm-components/user/ccm.user.js' ],
          onfinish: function ( instance ) {
            suite.assertTrue( instance.user.isLoggedIn() );
          }
        }, function ( instance ) {
          if ( instance.user.isLoggedIn() ) suite.failed( 'user is already logged in' );
          instance.element.querySelector( 'button' ).click();
        } );
      },
      logStartEvent: function ( suite ) {
        suite.component.start( {
          logger: [ 'ccm.instance', './../../ccm-components/log/ccm.log.js', { onfinish: function ( instance, results ) {
            suite.assertSame( 'start', results.event );
          } } ]
        } );
      },
      logFinishEvent: function ( suite ) {
        suite.component.start( {
          logger: [ 'ccm.instance', './../../ccm-components/log/ccm.log.js', {
            events: { finish: true },
            onfinish: function ( instance, results ) {
              suite.assertSame( 'finish', results.event );
            }
          } ]
        }, function ( instance ) {
          instance.element.querySelector( 'button' ).click();
        } );
      }
    }
  },
  uniform_data_structure: {
    tests: {
      singleQuestion: function ( suite ) {
        suite.component.start( {
          questions: {},
          logger: [ 'ccm.instance', './../../ccm-components/log/ccm.log.js', {
            logging: { data: true },
            onfinish: function ( instance, results ) {
              suite.assertSame( 1, results.data.questions.length );
            }
          } ]
        } );
      },
      defaultsByConfig: function ( suite ) {
        suite.component.start( {
          text: true, description: true, answers: true, input: true, attributes: true, swap: true, encode: true, random: true, feedback: true, correct: true,
          questions: {},
          logger: [ 'ccm.instance', './../../ccm-components/log/ccm.log.js', {
            logging: { data: true },
            onfinish: function ( instance, results ) {

              var data = results.data;
              if ( data.text        ) return suite.failed( 'text property not deleted' );
              if ( data.description ) return suite.failed( 'description property not deleted' );
              if ( data.answers     ) return suite.failed( 'answers property not deleted' );
              if ( data.input       ) return suite.failed( 'input property not deleted' );
              if ( data.attributes  ) return suite.failed( 'attributes property not deleted' );
              if ( data.swap        ) return suite.failed( 'swap property not deleted' );
              if ( data.encode      ) return suite.failed( 'encode property not deleted' );
              if ( data.random      ) return suite.failed( 'random property not deleted' );
              if ( data.feedback    ) return suite.failed( 'feedback property not deleted' );
              if ( data.correct     ) return suite.failed( 'correct property not deleted' );

              var question = data.questions[ 0 ];
              if ( !question.text        ) return suite.failed( 'missing text property' );
              if ( !question.description ) return suite.failed( 'missing description property' );
              if ( !question.answers     ) return suite.failed( 'missing answers property' );
              if ( !question.input       ) return suite.failed( 'missing input property' );
              if ( !question.random      ) return suite.failed( 'missing random property' );
              if ( !question.feedback    ) return suite.failed( 'missing feedback property' );
              if ( !question.correct     ) return suite.failed( 'missing correct property' );

              var answer = question.answers[ 0 ];
              if ( !answer.attributes  ) return suite.failed( 'missing attributes property' );
              if ( !answer.swap        ) return suite.failed( 'missing swap property' );
              if ( !answer.encode      ) return suite.failed( 'missing encode property' );

              suite.passed();
            }
          } ]
        } );
      },
      defaultInput: function ( suite ) {
        suite.component.start( {
          questions: {},
          logger: [ 'ccm.instance', './../../ccm-components/log/ccm.log.js', {
            logging: { data: true },
            onfinish: function ( instance, results ) {
              suite.assertSame( 'checkbox', results.data.questions[ 0 ].input );
            }
          } ]
        } );
      },
      singleAnswer: function ( suite ) {
        suite.component.start( {
          questions: { answers: {} },
          logger: [ 'ccm.instance', './../../ccm-components/log/ccm.log.js', {
            logging: { data: true },
            onfinish: function ( instance, results ) {
              suite.assertSame( 1, results.data.questions[ 0 ].answers.length );
            }
          } ]
        } );
      },
      stringAnswers: function ( suite ) {
        suite.component.start( {
          questions: { answers: [ 'foo', {}, 'bar' ] },
          logger: [ 'ccm.instance', './../../ccm-components/log/ccm.log.js', {
            logging: { data: true },
            onfinish: function ( instance, results ) {
              suite.assertEquals( [ { text: 'foo' }, {}, { text: 'bar' } ], results.data.questions[ 0 ].answers );
            }
          } ]
        } );
      }
    }
  },
  finally: function ( suite, callback ) {
    document.body.removeChild( suite.container );
    callback();
  }
};

ccm.components.testsuite.quiz = ccm.files[ 'ccm.quiz.tests.js' ];<|endoftext|>


<commit_before>/**
 * A extension of javascript-state-machine's StateMachine
 *
 * Added features:
 *  - States can automatically timeout via @cfg.timeouts
 *  - FSM's have a fsm.states that is an array that contains a list of unique states
 *
 * @class HtStateMachine
 * @extends StateMachine
 *
 * @author justin.fiedler
 * @since 0.0.1
 *
 * @copyright (c) 2013 Hightail Inc. All Rights Reserved
 */

'use strict';

(function(window, _) {

    //Make HtStateMachine an extension of StateMachine
    var HtStateMachine = _.extend({}, StateMachine);

    /**
     * Override StateMachine's create method add custom functionality
     *
     * @public
     * @method create
     * @param cfg
     * @param target
     *
     * @return Object - A New StateMachine.
     */
    HtStateMachine.create = function(cfg, target) {
        var addEvents = false;
        var fsm = null;

        // Removes the default invalid state change errors from the console
        cfg.error = cfg.error || function() { };

        if (!addEvents) {
            addTimeoutCallbacks(cfg);
            fsm = StateMachine.create(cfg, target);
        } else {
            //Warning: This is not working right now
            fsm = createEventStateMachine(cfg, target);
            addTimeoutEventListeners(fsm, cfg);
        }

        fsm.states = HtStateMachine.getStates(cfg);

        //console.log('fsm.states');
        //console.log(fsm.states);

        return fsm;
    };

    /**
     * Modifies StateMachine cfg to support timeouts from cfg.timeouts values
     *
     * e.g.
     * cfg.timeouts: [
     *    {state: 'Opened', duration: 3000, timeoutEvent: 'close', refreshEvent: 'open'}
     * ]
     *
     * @private
     * @method addTimeoutCallbacks
     * @param cfg
     */
    function addTimeoutCallbacks(cfg) {
        //private vars
        var callbacks = cfg.callbacks || {};
        var timeouts = cfg.timeouts || [];
        var _setTimeout = cfg.setTimeout;// || setTimeout;
        var _clearTimeout = cfg.clearTimeout;// || clearTimeout;

        _.each(timeouts, function(timeout) {
            //console.log('addTimeoutCallbacks' + timeout.state);

            var callbackName = 'onenter' + timeout.state;
            callbacks[callbackName] = HtStateMachine.preprendCallback(callbacks, callbackName, function(name, from, to) {
                var fsm = this;

                var timeoutCallback = function() {
                    //console.log('Timeout(' + cfg.blah + '):' + to);
                    //console.log(fsm);
                    fsm[timeout.timeoutEvent]();
                };

                _clearTimeout(fsm.curTimeout);
                fsm.curTimeout = _setTimeout(timeoutCallback, timeout.duration);
            });

            //Add LEAVE STATE callback to set timeout
            callbackName = 'onleave' + timeout.state;
            callbacks[callbackName] = HtStateMachine.preprendCallback(callbacks, callbackName, function() {
                var fsm = this;
                _clearTimeout(fsm.curTimeout);
            });

            if (timeout.refreshEvent) {
                //Add REFRESH EVENT callbacks
                callbackName = 'onbefore' + timeout.refreshEvent;
                callbacks[callbackName] = HtStateMachine.preprendCallback(callbacks, callbackName, function(name, from, to, args) {
                    if (from === timeout.state) {
                        //console.log('Reset Callback called for:' + callbackName + ' from:' + from + ' to:' + to);
                        var fsm = this;

                        fsm['onenter' + timeout.state](name, from, to, args);
                    }
                });
            }
        });

        cfg.callbacks = callbacks;
    }

    /**
     * Returns a StateMachine callback function that first runs newCallback
     * and then calls the preexiting callback (if there is one)
     *
     * @public
     * @method prependCallback
     * @param callbacks         The callbacks object
     * @param callbackName      The callback name to prepend to
     * @param newCallback       The new callback function
     *
     * @returns Function - The merged callback
     */
    HtStateMachine.preprendCallback = function(callbacks, callbackName, newCallback) {
        var origCallback = callbacks[callbackName];

        var mergedCallback = function(name, from, to, args) {
            var fsm = this;

            //call new callback
            newCallback.apply(fsm, [name, from, to, args]);

            //call original callback
            if (origCallback) {
                origCallback.apply(fsm, [name, from, to, args]);
            }
        };

        return mergedCallback;
    };

    /**
     * Returns an unique array of all States in the given config.
     *
     * @public
     * @method getStates
     * @param cfg
     */
    HtStateMachine.getStates = function(cfg) {
        var states = [];
        var events = cfg.events || [];

        function appendStates(stateArray) {
            if (!_.isArray(stateArray)) {
                stateArray = [stateArray];
            }
            states = states.concat(stateArray);
        }

        //Add all states from the events collection
        _.each(events, function(event) {
            appendStates(event.to);
            appendStates(event.from);
        });

        //make the list unique
        states = _.uniq(states);

        return states;
    };

    /**
     * Returns true if stateName exists in the config.
     *
     * @public
     * @method hasState
     * @param cfg
     * @param stateName
     *
     * @return boolean - true if stateName exists.
     */
    HtStateMachine.hasState = function(cfg, stateName) {
        var states = HtStateMachine.getStates(cfg);
        if (_.indexOf(states, stateName) >= 0) {
            return true;
        }
        return false;
    };

    /**
     * WARNING: This is NOT WORKING. Fix before using.
     *
     * Given a @cfg returns a new StateMachine that will dispatch events for all
     * generic 'events' ('onbeforeevent', 'onleavestate', 'onenterstate', 'onafterevent')
     *
     * Events follow the EventTarget.js interface (on, off, trigger)
     *
     * @private
     * @method createEventStateMachine
     * @param cfg
     * @param target
     *
     * @returns Object - Event based StateMachine object.
     */
    function createEventStateMachine(cfg, target) {
        var callbacks = cfg.callbacks || {};
        var eventCallbacks = {};

        var eventDispatcher = new EventTarget();
        //Create events for all General callbacks
        var eventCallbackNames = ['onbeforeevent', 'onleavestate', 'onenterstate', 'onafterevent'];
        _.each(eventCallbackNames, function(callbackName) {

            (function(origCallback) {
                //change the original callbacks to use events
                if (origCallback) {
                    eventDispatcher.on(callbackName, function(event) {
                        origCallback(event.name, event.from, event.to, event.args);
                    });
                }
            })(callbacks[callbackName]);

            //create a callback that dispatches an event
            eventCallbacks[callbackName] = function(name, from, to, args) {
                //console.log('Event Callback (' + name + '): ' + callbackName);
                eventDispatcher.trigger({   type: callbackName,
                    name: name,
                    from: from,
                    to: to,
                    args: args
                });
            };

            callbacks[callbackName] = eventCallbacks[callbackName];
        });

        //Create StateMachine and add events to it
        var fsm = StateMachine.create(cfg, target);
        fsm = _.extend(eventDispatcher, fsm);

        return fsm;
    }

    /**
     * WARNING: This is dependant on createEventStateMachine() which is currently broken
     *
     * Adds timeout listers to a Event Statemachine created by createEventStateMachine()
     *
     * @private
     * @method addTimeoutEventListeners
     * @param fsm
     * @param cfg
     */
    function addTimeoutEventListeners(fsm, cfg) {
        //This is the timeout id or promise
        var curTimeout;

        var timeouts = cfg.timeouts || [];
        var _setTimeout = cfg.setTimeout || setTimeout;
        var _clearTimeout = cfg.clearTimeout || clearTimeout;

        //add timeout listeners
        fsm.on('onenterstate', function(event) {
            var timeout = _.find(timeouts, {state: event.to});
            if (timeout) {
                console.log('Timeout found for:' + event.to);
                curTimeout = _setTimeout(function() {
                                console.log('Timeout:' + event.to);
                                fsm[timeout.timeoutEvent]();
                            }, timeout.duration);
            }
        });

        fsm.on('onleavestate', function() {
            _clearTimeout(curTimeout);
        });
    }

    //Set Global instance var
    window.HtStateMachine = HtStateMachine;

})(this, _);
<commit_msg>Tidied up HtStateMachine.<commit_after>/**
 * A extension of javascript-state-machine's StateMachine
 *
 * Added features:
 *  - States can automatically timeout via @cfg.timeouts
 *  - FSM's have a fsm.states that is an array that contains a list of unique states
 *
 * @class HtStateMachine
 * @extends StateMachine
 *
 * @author justin.fiedler
 * @author hunter.novak
 * @since 0.0.1
 *
 * @copyright (c) 2013 Hightail Inc. All Rights Reserved
 */

'use strict';

(function(window, _) {

  // Make HtStateMachine an extension of StateMachine
  var HtStateMachine = _.extend({}, window.StateMachine);

  /**
   * Override StateMachine's create method add custom functionality
   *
   * @public
   * @method create
   * @param cfg
   * @param target
   *
   * @return Object - A New StateMachine.
   */
  HtStateMachine.create = function htsmCreate(cfg, target) {
    cfg.error = cfg.error || function() { };  // Default invalid state change error to a noop

    decorateTimeoutCallbacks(cfg);

    var fsm     = StateMachine.create(cfg, target);
    fsm.states  = HtStateMachine.getStates(cfg);

    return fsm;
  };

  /**
   * Returns a StateMachine callback function that first runs newCallback
   * and then calls the pre-exiting callback (if there is one)
   *
   * @public
   * @method prependCallback
   * @param callbacks         The callbacks object
   * @param callbackName      The callback name to prepend to
   * @param newCallback       The new callback function
   *
   * @returns Function - The merged callback
   */
  HtStateMachine.preprendCallback = function htsmPrependCallback(callbacks, callbackName, newCallback) {
    var origCallback = callbacks[callbackName];

    var mergedCallback = function(name, from, to, args) {
      // Fire new callback
      newCallback.apply(this, [name, from, to, args]);

      // Fire original callback
      if (origCallback) { origCallback.apply(this, [name, from, to, args]); }
    };

    return mergedCallback;
  };

  /**
   * Returns an unique array of all States in the given config.
   *
   * @public
   * @method getStates
   * @param cfg
   */
  HtStateMachine.getStates = function htsmGetStates(cfg) {
    var states = [];
    var events = cfg.events || [];

    function appendStates(stateArray) {
      if (!_.isArray(stateArray)) { stateArray = [stateArray]; }
      states = states.concat(stateArray);
    }

    // Add all states from the events collection
    _.each(events, function(event) {
      appendStates(event.to);
      appendStates(event.from);
    });

    // Make the list unique
    states = _.uniq(states);

    return states;
  };

  /**
   * Returns true if stateName exists in the config.
   *
   * @public
   * @method hasState
   * @param cfg
   * @param stateName
   *
   * @return boolean - true if stateName exists.
   */
  HtStateMachine.hasState = function htsmHasState(cfg, stateName) {
    var states = HtStateMachine.getStates(cfg);
    return (_.indexOf(states, stateName) >= 0) ? true : false;
  };

  /**
   * Modifies StateMachine cfg to support timeouts from cfg.timeouts values
   *
   * e.g.
   * cfg.timeouts: [
   *    {state: 'Opened', duration: 3000, timeoutEvent: 'close', refreshEvent: 'open'}
   * ]
   *
   * @private
   * @method addTimeoutCallbacks
   * @param cfg
   */
  function decorateTimeoutCallbacks(cfg) {

    var callbacks     = cfg.callbacks     || {};
    var timeouts      = cfg.timeouts      || [];
    var _setTimeout   = cfg.setTimeout    || setTimeout;
    var _clearTimeout = cfg.clearTimeout  || clearTimeout;

    // Decorate Handlers for each timeout
    _.each(timeouts, function(timeout) {

      // Add ENTER STATE callback to set timeout
      var callbackName = 'onenter' + timeout.state;
      callbacks[callbackName] = HtStateMachine.preprendCallback(callbacks, callbackName, function(name, from, to) {
        var fsm             = this;
        var timeoutCallback = function() { fsm[timeout.timeoutEvent](); };

        _clearTimeout(fsm.curTimeout);
        fsm.curTimeout = _setTimeout(timeoutCallback, timeout.duration);
      });

      // Add LEAVE STATE callback to set timeout
      callbackName = 'onleave' + timeout.state;
      callbacks[callbackName] = HtStateMachine.preprendCallback(callbacks, callbackName, function() {
        var fsm = this;
        _clearTimeout(fsm.curTimeout);
      });

      if (timeout.refreshEvent) {
        //Add REFRESH EVENT callbacks
        callbackName = 'onbefore' + timeout.refreshEvent;
        callbacks[callbackName] = HtStateMachine.preprendCallback(callbacks, callbackName, function(name, from, to, args) {
          if (from === timeout.state) {
            var fsm = this;
            fsm['onenter' + timeout.state](name, from, to, args);
          }
        });
      }
    });

    cfg.callbacks = callbacks;
  }

  // Set Global instance var
  window.HtStateMachine = HtStateMachine;

})(this, _);
<|endoftext|>


<commit_before>//= require leaflet/map
//= require map/sidebar
//= require leaflet-easy-button/easy-button
//= require map/routes

var slidePanel;

var sidebarBuilding = L.control.sidebar('sidebar', {
    position: 'left'
});

map.addControl(sidebarBuilding);

$(document).ready(function() {
    $('label').click(function() {

        if ($(this).hasClass('active')) {
            $(this).removeClass('active');
            $('input').removeClass('slideInRight').addClass('slideOutRight').one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function() {
                $('input').css('visibility', 'hidden');
            });
        } else {
            $('input').removeClass('slideOutRight').addClass('animated slideInRight').one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function() {
                $('input').css('visibility', 'visible');
            });
            $(this).addClass('active');
        }
    });
    slidePanel = {
        panel: $('.slide-panel'),
        content: function() {

        },
        show: function(url) {
            this.panel.load(url, function() {
                $(this).removeClass('slideOutLeft').addClass('slideInLeft').one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function() {
                    $(this).css('visibility', 'visible');
                });
            });
        },
        hide: function() {
            this.panel.removeClass('slideInLeft').addClass('slideOutLeft').one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function() {
                $(this).css('visibility', 'hidden');
            });
        }
    };
});

var infoLabel = {
    show: function(marker) {
        $('.info-label').text(marker.name);
        $('.info-label').css('visibility', 'visible');
    },
    hide: function() {
        $('.info-label').css('visibility', 'hidden');
    }
}

$(document).ready(function () {
    $("a").click(function () {
        var test = caller.id;
        alert(test.val());
    });
});

const $building_geo_data = {
  element: $('#building_geo_data'),

  save: function(geo_json){
    this.element.val(JSON.stringify(geo_json.toGeoJSON()));
  },
  load: function(){
    const $geo_json = this.element.val();
    console.log($geo_json)
    if ($geo_json) {
        drawnLayer.addData(JSON.parse($geo_json));
    }
  }
};

function onEachFeature(feature,layer){
    //console.log(layer.bindPopup(feature.properties.description));

  layer.on('click', function(){

      if (sidebarBuilding.isVisible()){
        sidebarBuilding.hide();
      }
      else {
        $("#sidebar").load( "/map/building", function() {
         sidebarBuilding.show();
        });
      }

    L.Routing.control({
      waypoints: [
        L.latLng(-15.762023, -47.867114),
        L.latLng(-15.761096, -47.867648)
      ],
     router: L.Routing.mapzen('mapzen-CEq2eYW', {
       costing:'pedestrian'
     }),
     formatter: new L.Routing.mapzenFormatter()
    }).addTo(map);
    var visible = sidebar.isVisible();
    var actualBuildingKey = this.feature.geometry.coordinates[0].key;
    console.log("#ActualBuildingId");
    console.log(actualBuildingKey);
    console.log("");

    //Takes the actual Latitude for the selected building
    var actualBuildingLat = this._latlngs[0][length].lat;

    //Takes the actual Longitude for the selected building
    var actualBuildingLng = this._latlngs[0][length].lng;
    console.log("#This Lat");
    console.log(actualBuildingLat);
    console.log("#This Lng");
    console.log(actualBuildingLng);
    console.log("");

    var promiseThisBuilding = $.getJSON("/map/data");
    promiseThisBuilding.then(function(data) {

        var validKeyBuilding = false;

        $.each(data, function (key, val){
            var geo_json = JSON.parse(val.geo_data);
            var dataLat = geo_json;

            //Takes each Latitude from saved buildings
            var dataLat = geo_json.features[0].geometry.coordinates[0][length][1];

            //Takes each Longitude from saved buildings
            var dataLng = geo_json.features[0].geometry.coordinates[0][length][0];

            console.log("Building number " + String(key));
            console.log("Lat " + String(dataLat));
            console.log("Lng " + String(dataLng));

            if(dataLat === actualBuildingLat && dataLng === actualBuildingLng){
                console.log("Esse é o prédio " + String(key));
                validKeyBuilding = true;
            }

        });

        console.log("#0.1");
        console.log(data);
     if (sidebarBuilding.isVisible()){
        sidebarBuilding.hide();
      } else {
        if(validKeyBuilding){
            var numberToBuilding = '/map/building/' +(actualBuildingKey+1);
            $("#sidebar").load( numberToBuilding, function() {
         sidebarBuilding.show();
        });
        }else{
            console.log("Invalid id to building selected");
        }

      }

    });

  });
}

L.easyButton('fa-map-marker', function(btn, map){

  slidePanel.show("/map/routes");
}).addTo(map);

L.marker(centerMap).addTo(map).bindPopup('Onde É? UnB');

var buildingLayer = L.geoJSON('', {
  onEachFeature: onEachFeature
}).addTo(map); //adding the building layers to the map
map.addLayer(buildingLayer);

$.getJSON( "/map/data", function(data) { //getting the json data
    var items = [];
    $.each(data, function (key, val){

    var geo_json = JSON.parse(val.geo_data);
    geo_json.features[0].geometry.coordinates[0].key = key;
    //console.log(geo_json);
    //console.log("Minha key" + key);
    //console.log("Meu geo json" + geo_json.properties);
    buildingLayer.addData(geo_json); //adding the json data to the building layer

    });

});

map.on('click', function(e) {
  //slidePanel.hide();
});
<commit_msg>Refatoring map slidebar<commit_after>//= require leaflet/map
//= require map/sidebar
//= require leaflet-easy-button/easy-button
//= require map/routes

var slidePanel;

var sidebarBuilding = L.control.sidebar('sidebar', {
    position: 'left'
});

map.addControl(sidebarBuilding);

$(document).ready(function() {
    $('label').click(function() {

        if ($(this).hasClass('active')) {
            $(this).removeClass('active');
            $('input').removeClass('slideInRight').addClass('slideOutRight').one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function() {
                $('input').css('visibility', 'hidden');
            });
        } else {
            $('input').removeClass('slideOutRight').addClass('animated slideInRight').one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function() {
                $('input').css('visibility', 'visible');
            });
            $(this).addClass('active');
        }
    });
    slidePanel = {
        panel: $('.slide-panel'),
        content: function() {

        },
        show: function(url) {
            this.panel.load(url, function() {
                $(this).removeClass('slideOutLeft').addClass('slideInLeft').one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function() {
                    $(this).css('visibility', 'visible');
                });
            });
        },
        hide: function() {
            this.panel.removeClass('slideInLeft').addClass('slideOutLeft').one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function() {
                $(this).css('visibility', 'hidden');
            });
        }
    };
});

var infoLabel = {
    show: function(marker) {
        $('.info-label').text(marker.name);
        $('.info-label').css('visibility', 'visible');
    },
    hide: function() {
        $('.info-label').css('visibility', 'hidden');
    }
}

$(document).ready(function () {
    $("a").click(function () {
        var test = caller.id;
        alert(test.val());
    });
});

const $building_geo_data = {
  element: $('#building_geo_data'),

  save: function(geo_json){
    this.element.val(JSON.stringify(geo_json.toGeoJSON()));
  },
  load: function(){
    const $geo_json = this.element.val();
    console.log($geo_json)
    if ($geo_json) {
        drawnLayer.addData(JSON.parse($geo_json));
    }
  }
};

function setValidBuilding(data){
    console.log("Funcao mostrar slidebar");
};

function hideAndShowSlideBar(sidebar){
    if (sidebar.isVisible()){
        sidebar.hide();
    } else {
        $("#sidebar").load( "/map/building", function() {
            sidebar.show();
        });
    }
};

function onEachFeature(feature,layer){
    layer.on('click', function(){

        hideAndShowSlideBar(sidebarBuilding);

        var visible = sidebar.isVisible();

        var buildingKey = this.feature.geometry.coordinates[0].key;

        //var polygon = L.polygon(this._latlngs, {color: 'red'}).addTo(map);

        if(sidebarBuilding.isVisible()){
            sidebarBuilding.hide();
        } else {
            var numberToBuilding = '/map/building/' +(buildingKey);
            $("#sidebar").load( numberToBuilding, function() {
                hideAndShowSlideBar(sidebarBuilding);
            });
        }
  });
}

L.easyButton('fa-map-marker', function(btn, map){

  slidePanel.show("/map/routes");
}).addTo(map);

L.marker(centerMap).addTo(map).bindPopup('Onde É? UnB');

var buildingLayer = L.geoJSON('', {
  onEachFeature: onEachFeature
}).addTo(map); //adding the building layers to the map
map.addLayer(buildingLayer);

$.getJSON( "/map/data", function(data) { //getting the json data
    var items = [];
    $.each(data, function (key, val){
        var geo_json = JSON.parse(val.geo_data);
        geo_json.features[0].geometry.coordinates[0].key = val.id;
        var a = true;
        if(a){
            buildingLayer.addData(geo_json); //adding the json data to the building layer
        }else{

        }
    });
});

map.on('click', function(e) {
  //slidePanel.hide();
});
<|endoftext|>


<commit_before>import csjs from 'csjs-inject';
import React, { createElement as r } from 'react';

import { Button, Modal, Spacer } from './index.js';

export default class NewAddressModal extends React.Component {

  static propTypes = {
    show: React.PropTypes.bool.isRequired,
    onCancel: React.PropTypes.func.isRequired,
    onSave: React.PropTypes.func.isRequired
  };

  render () {
    const className = styles.input;

    return this.props.show ? r(Modal, { title: 'new address' },
      r('input', { className, ref: 'addressName', placeholder: 'name', autoCapitalize: 'words' }),
      r('input', { className, ref: 'addressLine1', placeholder: 'address line 1', autoCapitalize: 'words' }),
      r('input', { className, ref: 'addressLine2', placeholder: 'address line 2', autoCapitalize: 'words' }),
      r('input', { className, ref: 'addressCity', placeholder: 'city', autoCapitalize: 'words' }),
      r('input', { className, ref: 'addressState', placeholder: 'state abbreviation', autoCapitalize: 'characters' }),
      r('input', { className, ref: 'addressZip', placeholder: 'zip', type: 'number' }),

      r(Spacer),
      r(Button, { onClick: this.handleCancelClick.bind(this) }, 'cancel'),
      r(Button, { onClick: this.handleSaveClick.bind(this) }, 'save')
    ) : null;
  }

  handleCancelClick () {
    this.props.onCancel();
  }

  handleSaveClick () {
    this.props.onSave({
      addressName: this.refs.addressName.value,
      addressLine1: this.refs.addressLine1.value,
      addressLine2: this.refs.addressLine2.value,
      addressCountry: 'US',
      addressCity: this.refs.addressCity.value,
      addressState: this.refs.addressState.value,
      addressZip: this.refs.addressZip.value
    });
  }

}

export const styles = csjs`
  .input {
    width: 100%;
  }
`;
<commit_msg>Removed autoCapitalize for all but state abbreviation, and added autoComplete attributes<commit_after>import csjs from 'csjs-inject';
import React, { createElement as r } from 'react';

import { Button, Modal, Spacer } from './index.js';

export default class NewAddressModal extends React.Component {

  static propTypes = {
    show: React.PropTypes.bool.isRequired,
    onCancel: React.PropTypes.func.isRequired,
    onSave: React.PropTypes.func.isRequired
  };

  render () {
    const className = styles.input;

    return this.props.show ? r(Modal, { title: 'new address' },
      r('input', { className, ref: 'addressName', placeholder: 'name', autoComplete: 'shipping name' }),
      r('input', { className, ref: 'addressLine1', placeholder: 'address line 1', autoComplete: 'shipping address-line1' }),
      r('input', { className, ref: 'addressLine2', placeholder: 'address line 2', autoComplete: 'shipping address-line2' }),
      r('input', { className, ref: 'addressCity', placeholder: 'city', autoComplete: 'shipping address-level2' }),
      r('input', { className, ref: 'addressState', placeholder: 'state abbreviation', autoCapitalize: 'characters', autoComplete: 'shipping address-level1' }),
      r('input', { className, ref: 'addressZip', placeholder: 'zip', type: 'number', autoComplete: 'shipping postal-code' }),

      r(Spacer),
      r(Button, { onClick: this.handleCancelClick.bind(this) }, 'cancel'),
      r(Button, { onClick: this.handleSaveClick.bind(this) }, 'save')
    ) : null;
  }

  handleCancelClick () {
    this.props.onCancel();
  }

  handleSaveClick () {
    this.props.onSave({
      addressName: this.refs.addressName.value,
      addressLine1: this.refs.addressLine1.value,
      addressLine2: this.refs.addressLine2.value,
      addressCountry: 'US',
      addressCity: this.refs.addressCity.value,
      addressState: this.refs.addressState.value,
      addressZip: this.refs.addressZip.value
    });
  }

}

export const styles = csjs`
  .input {
    width: 100%;
  }
`;
<|endoftext|>


<commit_before>//Storage handler
// storage -> spawns and extensions
var mod = new RoleObj(C.FILLER);
module.exports = mod;

mod.roleConfig = {
    inStack: [Action.Withdraw],
    outStack: [Action.Fill],
};

mod.loop = function(creep) {
    if(creep.memory.filling && creep.carry.energy == 0) {
        creep.memory.filling = false;
    }
    if(!creep.memory.filling && creep.carry.energy === creep.carryCapacity) {
        //We have enough energy, go to working!
        creep.memory.filling = true;
    }

    this.loop0(creep, creep.memory.filling);
};
<commit_msg>if no fill target, then filler should put energy to storage so it can keep spawnLink empty<commit_after>//Storage handler
// storage -> spawns and extensions
var mod = new RoleObj(C.FILLER);
module.exports = mod;

mod.roleConfig = {
    inStack: [Action.Withdraw],
    //If no fill target, then put energy to storage
    // thought that, filler can keep spawnLink empty
    // so sourceLinks won't block
    outStack: [Action.Fill, Action.Store],
};

mod.loop = function(creep) {
    if(creep.memory.filling && creep.carry.energy == 0) {
        creep.memory.filling = false;
    }
    if(!creep.memory.filling && creep.carry.energy === creep.carryCapacity) {
        //We have enough energy, go to working!
        creep.memory.filling = true;
    }

    this.loop0(creep, creep.memory.filling);
};
<|endoftext|>


<commit_before>#!/usr/bin/env node
// Copyright (c) 2013 Tom Steele
// See the file license.txt for copying permission

var fs = require('fs');
var async = require('async');
var webshot = require('webshot');
var request = require('request');
var color = require('colors');

var argv = require('optimist')
  .demand(1)
  .describe('c', 'Amount of concurrent requests')
  .options('c', {
           alias: 'concurrency',
           default: 10
   })
  .describe('u', 'User-Agent string')
  .options('u', {
           alias: 'useragent',
           default: 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.60 Safari/537.17'
  })
  .describe('h', 'Screenshot height')
  .options('h', {
           alias: 'height',
           default: 400
  })
  .describe('w', 'Screenshot width')
  .options('w', {
           alias: 'width',
           default: 400
  })
  .describe('p', 'phantomjs path')
  .options('p', {
           alias: 'phantom',
           default: 'phantomjs'
  })
  .describe('t', 'Timeout in milliseconds')
  .options('t', {
           alias: 'timeout',
           default: 10000
  })
  .boolean('j')
  .describe('j', 'Output JSON object')
  .alias('j', 'json')
  .describe('o', 'Output file')
  .options('o', {
    alias: 'out',
    default: 'index.html'
  })
  .describe('a', 'Append to file')
  .alias('a', 'append')
  .check(checkArgs)
  .usage("$0 [options] <url file>").argv;

// really should never do this, but there is some wonkyness in the webshot callback with errors.
// it can callback with an error, and then still emit events.
process.on('uncaughtException', function(err) {
});

// phantomjs webshot options
var options = {
  screenSize: {
    width: argv.w,
    height: argv.h
  },
  phantomConfig: {
    'ignore-ssl-errors': 'true'
  },
  userAgent: argv.u,
  phantomPath: argv.p,
  timeout: argv.t
};

// read file in and create list of urls
var urls = fs.readFileSync(argv._[0], {encoding: 'utf8'}).trim().split("\n");
var results = [];
var pace = require('pace')(urls.length);

async.eachLimit(urls, argv.c, getScreenShot, complete);

function getScreenShot(url, cb) {
  var img = '';
  // request the page once first to get around phantomjs 401 bug
  var ropts = {'url': url, 'strictSSL': false, headers:{'User-Agent': argv.u}, timeout: argv.t};
  request(ropts, function(err, res) {
     // if response was not 401 grab a screenshot
     if (!err && res.statusCode !== 401) {
      var href = res.request['uri'].href;
      webshot(href, options, function(err, rs) {
        if (err) {
          pace.op();
          cb();
        }
        else {
          rs.on('data', function(data) {
            var string = data.toString('base64');
            if (!string.match(/Error/)) {
              img += data.toString('base64');
            }
          });
         rs.on('error', function(err) {
            pace.op();
            cb();
          });
          rs.on('end', function() {
            pace.op();
            results.push({"url": url, "href": href, "img": img});
            cb();
          });
        }
      });
    }
    // else if error or a 401 just skip it
    else {
      pace.op();
      cb();
    }
  });
 }

// append or write to file
function complete(err) {
  console.log('\n');
  if (argv.a) {
    console.log('appending to file', argv.a);
  }
  else {
    console.log('saving results to file', argv.o);
  }

  if (argv.j) {
    jsonOut(results);
  }
  else {
    htmlOut(results);
  }
  process.exit(0);
}

// output the results object as json
function jsonOut(results) {
  var string = JSON.stringify(results, null, " ");
  if (argv.o !== 'index.html') {
    fs.writeFileSync(argv.o, string);
  }
  else if (argv.a) {
    fs.appendFileSync(argv.a, string);
  }
  else {
    console.log(string);
  }
}

// create a html file with the results
function htmlOut(results) {
  // gentle css for styling
  var css = ".outline {border: 1px solid black;} html,body {padding: 10px;}"

  if (!argv.a) {
    var string = ''
  }

  results.forEach(function(r) {
    string += '
' + r.url + "
";
    if (r.href !== r.url) {
       string += '
=> ' + r.href + "
";
    }
    string += '
';
  });

  if (!argv.a) {
    string += '';
  }
  if (argv.a) {
    fs.appendFileSync(argv.a, string);
  }
  else {
    fs.writeFileSync(argv.o, string);
  }
}

// check argv arguments for errors
function checkArgs(argv) {
  if (!fs.existsSync(argv._[0])) {
    throw 'url file does not exist'.red;
  }
  if (argv.a && !fs.existsSync(argv.a)) {
    throw 'append file does not exist'.red;
  }
}
<commit_msg>Major updates<commit_after>#!/usr/bin/env node
// Copyright (c) 2013 Tom Steele
// See the file license.txt for copying permission

var fs = require('fs');
var async = require('async');
var webshot = require('webshot');
var request = require('request');
var color = require('colors');
var winston = require('winston');

var argv = require('optimist')
  .demand(1)
  .describe('c', 'Amount of concurrent requests')
  .options('c', {
           alias: 'concurrency',
           default: 10
   })
  .describe('u', 'User-Agent string')
  .options('u', {
           alias: 'useragent',
           default: 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.60 Safari/537.17'
  })
  .describe('h', 'Screenshot height')
  .options('h', {
           alias: 'height',
           default: 400
  })
  .describe('w', 'Screenshot width')
  .options('w', {
           alias: 'width',
           default: 400
  })
  .describe('p', 'phantomjs path')
  .options('p', {
           alias: 'phantom',
           default: 'phantomjs'
  })
  .describe('t', 'Timeout in milliseconds')
  .options('t', {
           alias: 'timeout',
           default: 10000
  })
  .boolean('j')
  .describe('j', 'Output JSON object')
  .alias('j', 'json')
  .describe('o', 'Output file')
  .options('o', {
    alias: 'out',
    default: 'index.html'
  })
  .describe('a', 'Append to file')
  .alias('a', 'append')
  .check(checkArgs)
  .usage("$0 [options] <url file>").argv;

process.on('uncaughtException', function(err) {
  winston.error('Uncaught Exception', err.message);
});

// phantomjs webshot options
var wopts = {
  screenSize: {
    width: argv.w,
    height: argv.h
  },
  phantomConfig: {
    'ignore-ssl-errors': 'true'
  },
  userAgent: argv.u,
  phantomPath: argv.p,
  timeout: argv.t
};

// read file in and create list of urls
var urls = fs.readFileSync(argv._[0], {encoding: 'utf8'}).trim().split("\n");
var results = [];
var pace = require('pace')(urls.length);

async.eachLimit(urls, argv.c, makeRequest, complete);

function makeRequest(url, cb) {
  // request the page once first to get around phantomjs 401 bug
  var opts = {'url': url, 'strictSSL': false, headers:{'User-Agent': argv.u}, timeout: argv.t};
  href = '';
  request(opts, handleResponse);

  function handleResponse(err, res) {
    if (!err && res.statusCode !== 401) {
      href = res.request.uri.href;
      webshot(href, wopts, handleWebshot);
    } else {
      pace.op();
      cb();
    }
  }

  function handleWebshot(err, rs) {
    var img = '';
    var cbCalled = false;
    if (err) {
      handleError();
    } else {
      rs.on('error', handleError);
      rs.on('data', function(data) {
        var string = data.toString('base64');
        if (!string.match(/Error/)) {
          img += data.toString('base64');
        }
      });
      rs.on('end', function() {
        process.nextTick(pushResult);
      });
    }

    function handleError() {
      if (!cbCalled) {
        cbCalled = true;
        pace.op();
        cb();
      }
    }

    function pushResult() {
      results.push({"url": url, "href": href, "img": img});
      if (!cbCalled) {
        cbCalled = true;
        pace.op();
        cb();
      }
    }
  }
 }

function complete(err) {
  console.log('\n');
  if (argv.a) {
    console.log('appending to file', argv.a);
  }
  else {
    console.log('saving results to file', argv.o);
  }

  if (argv.j) {
    jsonOut(results);
  }
  else {
    htmlOut(results);
  }
  process.exit(0);
}

function jsonOut(results) {
  var string = JSON.stringify(results, null, " ");
  if (argv.o !== 'index.html') {
    fs.writeFileSync(argv.o, string);
  }
  else if (argv.a) {
    fs.appendFileSync(argv.a, string);
  }
  else {
    console.log(string);
  }
}

function htmlOut(results) {
  var css = '.outline {border: 1px solid black;} html,body {padding: 10px;}';
  var string = '';
  if (!argv.a) {
    string += '';
  }

  results.forEach(function(r) {
    string += '
' + r.url + '
';
    if (r.href !== r.url) {
       string += '
=> ' + r.href + '
';
    }
    string += '
';
  });

  if (!argv.a) {
    string += '';
  }
  if (argv.a) {
    fs.appendFileSync(argv.a, string);
  }
  else {
    fs.writeFileSync(argv.o, string);
  }
}

function checkArgs(argv) {
  if (!fs.existsSync(argv._[0])) {
    throw 'url file does not exist'.red;
  }
  if (argv.a && !fs.existsSync(argv.a)) {
    throw 'append file does not exist'.red;
  }
}
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** This file is part of the Qt Build Suite.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. For further information
** use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file.  Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights.  These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

var FileInfo = loadExtension("qbs.FileInfo");

/**
  * Returns the numeric identifier corresponding to an Apple device name
  * (i.e. for use by TARGETED_DEVICE_FAMILY).
  */
function appleDeviceNumber(deviceName) {
    if (deviceName === "mac") {
        return undefined; // only iOS devices have an ID
    } else if (deviceName === "iphone") {
        return 1;
    } else if (deviceName === "ipad") {
        return 2;
    } else if (deviceName === "tv") {
        return 3;
    } else if (deviceName === "watch") {
        return 4;
    } else if (deviceName === "car") {
        return 5;
    }
}

/**
  * Returns the list of target devices available for the given qbs target OS list.
  */
function targetDevices(targetOS) {
    if (targetOS.contains("osx"))
        return ["mac"];
    if (targetOS.contains("ios"))
        return ["iphone", "ipad"];
    if (targetOS.contains("tvos"))
        return ["tv"];
    if (targetOS.contains("watchos"))
        return ["watch"];
}

/**
  * Returns the TARGETED_DEVICE_FAMILY string given a list of target device names.
  */
function targetedDeviceFamily(deviceNames) {
    return deviceNames.map(function (deviceName) {
        return DarwinTools.appleDeviceNumber(deviceName);
    }).join(",");
}

/**
  * Returns the most appropriate Apple platform name given a targetOS list.
  */
function applePlatformName(targetOSList) {
    if (targetOSList.contains("ios-simulator"))
        return "iphonesimulator";
    else if (targetOSList.contains("ios"))
        return "iphoneos";
    else if (targetOSList.contains("osx"))
        return "macosx";
    else if (targetOSList.contains("tvos-simulator"))
        return "appletvsimulator";
    else if (targetOSList.contains("tvos"))
        return "appletvos";
    else if (targetOSList.contains("watchos-simulator"))
        return "watchsimulator";
    else if (targetOSList.contains("watchos"))
        return "watchos";
    throw("No Apple platform corresponds to target OS list: " + targetOSList);
}

/**
  * Replace characters unsafe for use in a domain name with a '-' character (RFC 1034).
  */
function rfc1034(inStr) {
    // ### Remove in Qbs 1.5
    console.warn("DarwinTools.rfc1034 is deprecated; use qbs.rfc1034Identifier instead");
    return qbs.rfc1034Identifier(inStr);
}

/**
  * Returns the localization of the resource at the given path,
  * or undefined if the path does not contain an {xx}.lproj path segment.
  */
function localizationKey(path) {
    return _resourceFileProperties(path)[0];
}

/**
  * Returns the path of a localized resource at the given path,
  * relative to its containing {xx}.lproj directory, or '.'
  * if the resource is unlocalized (not contained in an lproj directory).
  */
function relativeResourcePath(path) {
    return _resourceFileProperties(path)[1];
}

function _resourceFileProperties(path) {
    var lprojKey = ".lproj/";
    var lproj = path.indexOf(lprojKey);
    if (lproj >= 0) {
        // The slash preceding XX.lproj
        var slashIndex = path.slice(0, lproj).lastIndexOf('/');
        if (slashIndex >= 0) {
            var localizationKey = path.slice(slashIndex + 1, lproj);
            var relativeResourcePath = FileInfo.path(path.slice(lproj + lprojKey.length));
            return [ localizationKey, relativeResourcePath ];
        }
    }

    return [ undefined, '.' ];
}

/**
  * Recursively perform variable replacements in an environment dictionary.
  *
  * JSON.stringify(expandPlistEnvironmentVariables({a:"$(x)3$$(y)",b:{t:"%$(y) $(k)"}},
  *                                                {x:"X",y:"Y"}, true))
  *    Warning undefined variable  k  in variable expansion
  * => {"a":"X3$Y","b":{"t":"%Y $(k)"}}
  */
function expandPlistEnvironmentVariables(obj, env, warn) {
    // Possible syntaxes for wrapping an environment variable name
    var syntaxes = [
        {"open": "${", "close": "}"},
        {"open": "$(", "close": ")"},
        {"open": "@",  "close": "@"}
    ];

    /**
      * Finds the first index of a replacement starting with one of the supported syntaxes
      * This is needed so we don't do recursive substitutions
      */
    function indexOfReplacementStart(syntaxes, str, offset) {
        var syntax;
        var idx = str.length;
        for (var i in syntaxes) {
            var j = str.indexOf(syntaxes[i].open, offset);
            if (j !== -1 && j < idx) {
                syntax = syntaxes[i];
                idx = j;
            }
        }
        return { "syntax": syntax, "index": idx === str.length ? -1 : idx };
    }

    function expandRecursive(obj, env, checked) {
        checked.push(obj);
        for (var key in obj) {
            var value = obj[key];
            var type = typeof(value);
            if (type === "object") {
                if (checked.indexOf(value) !== -1)
                    continue;
                expandRecursive(value, env, checked);
            }
            if (type !== "string")
                continue;
            var repl = indexOfReplacementStart(syntaxes, value);
            var i = repl.index;
            var changes = false;
            while (i !== -1) {
                var j = value.indexOf(repl.syntax.close, i + repl.syntax.open.length);
                if (j === -1)
                    break;
                var varParts = value.slice(i + repl.syntax.open.length, j).split(':');
                var varName = varParts[0];
                var varFormatter = varParts[1];
                var varValue = env[varName];
                if (undefined === varValue) {
                    // skip replacement
                    if (warn)
                        console.warn("undefined variable " + varName + " in variable expansion");
                } else {
                    changes = true;
                    varValue = String(varValue);
                    if (varFormatter !== undefined)
                        varFormatter = varFormatter.toLowerCase();
                    if (varFormatter === "rfc1034identifier")
                        varValue = qbs.rfc1034Identifier(varValue);
                    value = value.slice(0, i) + varValue + value.slice(j + repl.syntax.close.length);
                    // avoid recursive substitutions to avoid potentially infinite loops
                    i += varValue.length;
                }
                repl = indexOfReplacementStart(syntaxes, value, i);
                i = repl.index;
            }
            if (changes)
                obj[key] = value;
        }
    }
    expandRecursive(obj, env, []);
    return obj;
}

/**
  * Recursively removes any undefined, null, or empty string values from the property list.
  */
function cleanPropertyList(plist) {
    if (typeof(plist) !== "object")
        return;

    for (var key in plist) {
        if (plist[key] === undefined || plist[key] === null || plist[key] === "")
            delete plist[key];
        else
            cleanPropertyList(plist[key]);
    }
}

function _codeSignTimestampFlags(product) {
    // If signingTimestamp is undefined, do not specify the flag at all -
    // this uses the system-specific default behavior
    var signingTimestamp = product.moduleProperty("xcode", "signingTimestamp");
    if (signingTimestamp !== undefined) {
        // If signingTimestamp is an empty string, specify the flag but do
        // not specify a value - this uses a default Apple-provided server
        var flag = "--timestamp";
        if (signingTimestamp)
            flag += "=" + signingTimestamp;
        return [flag];
    }

    return [];
}
<commit_msg>Remove dead code from darwin-tools.js<commit_after>/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** This file is part of the Qt Build Suite.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. For further information
** use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file.  Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights.  These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

var FileInfo = loadExtension("qbs.FileInfo");

/**
  * Returns the numeric identifier corresponding to an Apple device name
  * (i.e. for use by TARGETED_DEVICE_FAMILY).
  */
function appleDeviceNumber(deviceName) {
    if (deviceName === "mac") {
        return undefined; // only iOS devices have an ID
    } else if (deviceName === "iphone") {
        return 1;
    } else if (deviceName === "ipad") {
        return 2;
    } else if (deviceName === "tv") {
        return 3;
    } else if (deviceName === "watch") {
        return 4;
    } else if (deviceName === "car") {
        return 5;
    }
}

/**
  * Returns the list of target devices available for the given qbs target OS list.
  */
function targetDevices(targetOS) {
    if (targetOS.contains("osx"))
        return ["mac"];
    if (targetOS.contains("ios"))
        return ["iphone", "ipad"];
    if (targetOS.contains("tvos"))
        return ["tv"];
    if (targetOS.contains("watchos"))
        return ["watch"];
}

/**
  * Returns the TARGETED_DEVICE_FAMILY string given a list of target device names.
  */
function targetedDeviceFamily(deviceNames) {
    return deviceNames.map(function (deviceName) {
        return appleDeviceNumber(deviceName);
    }).join(",");
}

/**
  * Returns the most appropriate Apple platform name given a targetOS list.
  */
function applePlatformName(targetOSList) {
    if (targetOSList.contains("ios-simulator"))
        return "iphonesimulator";
    else if (targetOSList.contains("ios"))
        return "iphoneos";
    else if (targetOSList.contains("osx"))
        return "macosx";
    else if (targetOSList.contains("tvos-simulator"))
        return "appletvsimulator";
    else if (targetOSList.contains("tvos"))
        return "appletvos";
    else if (targetOSList.contains("watchos-simulator"))
        return "watchsimulator";
    else if (targetOSList.contains("watchos"))
        return "watchos";
    throw("No Apple platform corresponds to target OS list: " + targetOSList);
}

/**
  * Returns the localization of the resource at the given path,
  * or undefined if the path does not contain an {xx}.lproj path segment.
  */
function localizationKey(path) {
    return _resourceFileProperties(path)[0];
}

/**
  * Returns the path of a localized resource at the given path,
  * relative to its containing {xx}.lproj directory, or '.'
  * if the resource is unlocalized (not contained in an lproj directory).
  */
function relativeResourcePath(path) {
    return _resourceFileProperties(path)[1];
}

function _resourceFileProperties(path) {
    var lprojKey = ".lproj/";
    var lproj = path.indexOf(lprojKey);
    if (lproj >= 0) {
        // The slash preceding XX.lproj
        var slashIndex = path.slice(0, lproj).lastIndexOf('/');
        if (slashIndex >= 0) {
            var localizationKey = path.slice(slashIndex + 1, lproj);
            var relativeResourcePath = FileInfo.path(path.slice(lproj + lprojKey.length));
            return [ localizationKey, relativeResourcePath ];
        }
    }

    return [ undefined, '.' ];
}

/**
  * Recursively perform variable replacements in an environment dictionary.
  *
  * JSON.stringify(expandPlistEnvironmentVariables({a:"$(x)3$$(y)",b:{t:"%$(y) $(k)"}},
  *                                                {x:"X",y:"Y"}, true))
  *    Warning undefined variable  k  in variable expansion
  * => {"a":"X3$Y","b":{"t":"%Y $(k)"}}
  */
function expandPlistEnvironmentVariables(obj, env, warn) {
    // Possible syntaxes for wrapping an environment variable name
    var syntaxes = [
        {"open": "${", "close": "}"},
        {"open": "$(", "close": ")"},
        {"open": "@",  "close": "@"}
    ];

    /**
      * Finds the first index of a replacement starting with one of the supported syntaxes
      * This is needed so we don't do recursive substitutions
      */
    function indexOfReplacementStart(syntaxes, str, offset) {
        var syntax;
        var idx = str.length;
        for (var i in syntaxes) {
            var j = str.indexOf(syntaxes[i].open, offset);
            if (j !== -1 && j < idx) {
                syntax = syntaxes[i];
                idx = j;
            }
        }
        return { "syntax": syntax, "index": idx === str.length ? -1 : idx };
    }

    function expandRecursive(obj, env, checked) {
        checked.push(obj);
        for (var key in obj) {
            var value = obj[key];
            var type = typeof(value);
            if (type === "object") {
                if (checked.indexOf(value) !== -1)
                    continue;
                expandRecursive(value, env, checked);
            }
            if (type !== "string")
                continue;
            var repl = indexOfReplacementStart(syntaxes, value);
            var i = repl.index;
            var changes = false;
            while (i !== -1) {
                var j = value.indexOf(repl.syntax.close, i + repl.syntax.open.length);
                if (j === -1)
                    break;
                var varParts = value.slice(i + repl.syntax.open.length, j).split(':');
                var varName = varParts[0];
                var varFormatter = varParts[1];
                var varValue = env[varName];
                if (undefined === varValue) {
                    // skip replacement
                    if (warn)
                        console.warn("undefined variable " + varName + " in variable expansion");
                } else {
                    changes = true;
                    varValue = String(varValue);
                    if (varFormatter !== undefined)
                        varFormatter = varFormatter.toLowerCase();
                    if (varFormatter === "rfc1034identifier")
                        varValue = qbs.rfc1034Identifier(varValue);
                    value = value.slice(0, i) + varValue + value.slice(j + repl.syntax.close.length);
                    // avoid recursive substitutions to avoid potentially infinite loops
                    i += varValue.length;
                }
                repl = indexOfReplacementStart(syntaxes, value, i);
                i = repl.index;
            }
            if (changes)
                obj[key] = value;
        }
    }
    expandRecursive(obj, env, []);
    return obj;
}

/**
  * Recursively removes any undefined, null, or empty string values from the property list.
  */
function cleanPropertyList(plist) {
    if (typeof(plist) !== "object")
        return;

    for (var key in plist) {
        if (plist[key] === undefined || plist[key] === null || plist[key] === "")
            delete plist[key];
        else
            cleanPropertyList(plist[key]);
    }
}

function _codeSignTimestampFlags(product) {
    // If signingTimestamp is undefined, do not specify the flag at all -
    // this uses the system-specific default behavior
    var signingTimestamp = product.moduleProperty("xcode", "signingTimestamp");
    if (signingTimestamp !== undefined) {
        // If signingTimestamp is an empty string, specify the flag but do
        // not specify a value - this uses a default Apple-provided server
        var flag = "--timestamp";
        if (signingTimestamp)
            flag += "=" + signingTimestamp;
        return [flag];
    }

    return [];
}
<|endoftext|>