<commit_before>/**
 * Element with a button.
 *
 * @abstract
 * @class
 *
 * @constructor
 * @param {jQuery} $button Button node, assigned to #$button
 * @param {Object} [config] Configuration options
 * @cfg {boolean} [frameless] Render button without a frame
 * @cfg {number} [tabIndex=0] Button's tab index, use -1 to prevent tab focusing
 * @cfg {string} [accessKey] Button's access key
 */
OO.ui.ButtonedElement = function OoUiButtonedElement( $button, config ) {
	// Configuration initialization
	config = config || {};

	// Properties
	this.$button = $button;
	this.tabIndex = null;
	this.active = false;
	this.onMouseUpHandler = OO.ui.bind( this.onMouseUp, this );

	// Events
	this.$button.on( 'mousedown', OO.ui.bind( this.onMouseDown, this ) );

	// Initialization
	this.$element
		.addClass( 'oo-ui-buttonedElement' )
		.prop( 'tabIndex', config.tabIndex || 0 );
	this.$button
		.addClass( 'oo-ui-buttonedElement-button' )
		.attr( 'role', 'button' );
	if ( config.frameless ) {
		this.$element.addClass( 'oo-ui-buttonedElement-frameless' );
	} else {
		this.$element.addClass( 'oo-ui-buttonedElement-framed' );
	}
	this.setAccessKey( config.accessKey );
};

/* Setup */

OO.initClass( OO.ui.ButtonedElement );

/* Static Properties */

/**
 * Cancel mouse down events.
 *
 * @static
 * @inheritable
 * @property {boolean}
 */
OO.ui.ButtonedElement.static.cancelButtonMouseDownEvents = true;

/* Methods */

/**
 * Handles mouse down events.
 *
 * @param {jQuery.Event} e Mouse down event
 */
OO.ui.ButtonedElement.prototype.onMouseDown = function ( e ) {
	if ( this.isDisabled() || e.which !== 1 ) {
		return false;
	}
	// tabIndex should generally be interacted with via the property, but it's not possible to
	// reliably unset a tabIndex via a property so we use the (lowercase) "tabindex" attribute
	this.tabIndex = this.$button.attr( 'tabindex' );
	this.$button
		// Remove the tab-index while the button is down to prevent the button from stealing focus
		.removeAttr( 'tabindex' )
		.addClass( 'oo-ui-buttonedElement-pressed' );
	// Run the mouseup handler no matter where the mouse is when the button is let go, so we can
	// reliably reapply the tabindex and remove the pressed class
	this.getElementDocument().addEventListener( 'mouseup', this.onMouseUpHandler, true );
	// Prevent change of focus unless specifically configured otherwise
	if ( this.constructor.static.cancelButtonMouseDownEvents ) {
		return false;
	}
};

/**
 * Handles mouse up events.
 *
 * @param {jQuery.Event} e Mouse up event
 */
OO.ui.ButtonedElement.prototype.onMouseUp = function ( e ) {
	if ( this.isDisabled() || e.which !== 1 ) {
		return false;
	}
	this.$button
		// Restore the tab-index after the button is up to restore the button's accesssibility
		.attr( 'tabindex', this.tabIndex )
		.removeClass( 'oo-ui-buttonedElement-pressed' );
	// Stop listening for mouseup, since we only needed this once
	this.getElementDocument().removeEventListener( 'mouseup', this.onMouseUpHandler, true );
};

/**
 * Set access key
 *
 * @param {string} accessKey Button's access key, use empty string to remove
 * @chainable
 */
OO.ui.ButtonedElement.prototype.setAccessKey = function ( accessKey ) {
	if ( typeof accessKey === 'string' && accessKey.length ) {
		this.$button.attr( 'accesskey', accessKey );
	} else {
		this.$button.removeAttr( 'accesskey' );
	}
	return this;
};

/**
 * Set active state.
 *
 * @param {boolean} [value] Make button active
 * @chainable
 */
OO.ui.ButtonedElement.prototype.setActive = function ( value ) {
	this.$button.toggleClass( 'oo-ui-buttonedElement-active', !!value );
	return this;
};
<commit_msg>Add API for tabIndex to OO.ui.ButtonedElement<commit_after>/**
 * Element with a button.
 *
 * @abstract
 * @class
 *
 * @constructor
 * @param {jQuery} $button Button node, assigned to #$button
 * @param {Object} [config] Configuration options
 * @cfg {boolean} [frameless] Render button without a frame
 * @cfg {number} [tabIndex=0] Button's tab index, use null to have no tabIndex
 * @cfg {string} [accessKey] Button's access key
 */
OO.ui.ButtonedElement = function OoUiButtonedElement( $button, config ) {
	// Configuration initialization
	config = config || {};

	// Properties
	this.$button = $button;
	this.tabIndex = null;
	this.active = false;
	this.onMouseUpHandler = OO.ui.bind( this.onMouseUp, this );

	// Events
	this.$button.on( 'mousedown', OO.ui.bind( this.onMouseDown, this ) );

	// Initialization
	this.$element.addClass( 'oo-ui-buttonedElement' );
	this.$button
		.addClass( 'oo-ui-buttonedElement-button' )
		.attr( 'role', 'button' );
	if ( config.frameless ) {
		this.$element.addClass( 'oo-ui-buttonedElement-frameless' );
	} else {
		this.$element.addClass( 'oo-ui-buttonedElement-framed' );
	}
	this.setTabIndex( config.tabIndex || 0 );
	this.setAccessKey( config.accessKey );
};

/* Setup */

OO.initClass( OO.ui.ButtonedElement );

/* Static Properties */

/**
 * Cancel mouse down events.
 *
 * @static
 * @inheritable
 * @property {boolean}
 */
OO.ui.ButtonedElement.static.cancelButtonMouseDownEvents = true;

/* Methods */

/**
 * Handles mouse down events.
 *
 * @param {jQuery.Event} e Mouse down event
 */
OO.ui.ButtonedElement.prototype.onMouseDown = function ( e ) {
	if ( this.isDisabled() || e.which !== 1 ) {
		return false;
	}
	// tabIndex should generally be interacted with via the property, but it's not possible to
	// reliably unset a tabIndex via a property so we use the (lowercase) "tabindex" attribute
	this.tabIndex = this.$button.attr( 'tabindex' );
	this.$button
		// Remove the tab-index while the button is down to prevent the button from stealing focus
		.removeAttr( 'tabindex' )
		.addClass( 'oo-ui-buttonedElement-pressed' );
	// Run the mouseup handler no matter where the mouse is when the button is let go, so we can
	// reliably reapply the tabindex and remove the pressed class
	this.getElementDocument().addEventListener( 'mouseup', this.onMouseUpHandler, true );
	// Prevent change of focus unless specifically configured otherwise
	if ( this.constructor.static.cancelButtonMouseDownEvents ) {
		return false;
	}
};

/**
 * Handles mouse up events.
 *
 * @param {jQuery.Event} e Mouse up event
 */
OO.ui.ButtonedElement.prototype.onMouseUp = function ( e ) {
	if ( this.isDisabled() || e.which !== 1 ) {
		return false;
	}
	this.$button
		// Restore the tab-index after the button is up to restore the button's accesssibility
		.attr( 'tabindex', this.tabIndex )
		.removeClass( 'oo-ui-buttonedElement-pressed' );
	// Stop listening for mouseup, since we only needed this once
	this.getElementDocument().removeEventListener( 'mouseup', this.onMouseUpHandler, true );
};

/**
 * Set tab index.
 *
 * @param {number|null} tabIndex Button's tab index, use null to remove
 * @chainable
 */
OO.ui.ButtonedElement.prototype.setTabIndex = function ( tabIndex ) {
	if ( typeof tabIndex === 'number' && tabIndex >= 0 ) {
		this.$button.attr( 'tabindex', tabIndex );
	} else {
		this.$button.removeAttr( 'tabindex' );
	}
	return this;
};

/**
 * Set access key
 *
 * @param {string} accessKey Button's access key, use empty string to remove
 * @chainable
 */
OO.ui.ButtonedElement.prototype.setAccessKey = function ( accessKey ) {
	if ( typeof accessKey === 'string' && accessKey.length ) {
		this.$button.attr( 'accesskey', accessKey );
	} else {
		this.$button.removeAttr( 'accesskey' );
	}
	return this;
};

/**
 * Set active state.
 *
 * @param {boolean} [value] Make button active
 * @chainable
 */
OO.ui.ButtonedElement.prototype.setActive = function ( value ) {
	this.$button.toggleClass( 'oo-ui-buttonedElement-active', !!value );
	return this;
};
<|endoftext|>


<commit_before>/**
 * GetProperty
 *
 * @param {string} property
 * @param {object} source
 */
Validation.prototype.getProperty = function(property, source) {
  var tree = property.match(/([a-zA-Z0-9\s]+)/g);
  return tree.reduce(function(previousValue, currentValue, index) {
    return (previousValue && isDefined(previousValue[currentValue])) ? previousValue[currentValue] : undefined;
  }, source);
};<commit_msg>Fix the ‘getProperty’ method, it's now safe to use special characters in property name<commit_after>/**
 * GetProperty
 *
 * @param {string} property
 * @param {object} source
 */
Validation.prototype.getProperty = function(property, source) {
  if (source) {
    return (source[property]) ? source[property] : undefined;
  } else {
    return undefined;
  }
};<|endoftext|>


<commit_before>import { identity, functor } from './fn';
import { mean } from 'd3-array';

export default function() {

    let value = identity;
    let period = () => 9;

    const initialMovingAverageAccumulator = period => {
        const values = [];
        return value => {
            let movingAverage;
            if (values.length < period && value != null) {
                values.push(value);
            }
            if (values.length >= period) {
                movingAverage = mean(values);
            }
            return movingAverage;
        };
    };
    const exponentialMovingAverage = function(data) {
        const size = period.apply(this, arguments);
        const alpha = 2 / (size + 1);
        const initialAccumulator = initialMovingAverageAccumulator(size);
        let previous;
        let initialMovingAverage;

        return data.map((d, i) => {
            const v = value(d, i);
            let ema;
            if (initialMovingAverage === undefined) {
                ema = initialMovingAverage = initialAccumulator(v);
            } else {
                ema = v * alpha + (1 - alpha) * previous;
            }
            previous = ema;
            return ema;
        });
    };

    exponentialMovingAverage.period = (...args) => {
        if (!args.length) {
            return period;
        }
        period = functor(args[0]);
        return exponentialMovingAverage;
    };

    exponentialMovingAverage.value = (...args) => {
        if (!args.length) {
            return value;
        }
        value = args[0];
        return exponentialMovingAverage;
    };

    return exponentialMovingAverage;
}
<commit_msg>fix: require ema to have period number of consecutive defined values for initial moving average calculation<commit_after>import { identity, functor, convertNaN } from './fn';
import { mean } from 'd3-array';

export default function() {

    let value = identity;
    let period = () => 9;

    const initialMovingAverageAccumulator = period => {
        let values = [];
        return value => {
            let movingAverage;
            if (values.length < period) {
                if (value != null) {
                    values.push(value);
                } else {
                    values = [];
                }
            }
            if (values.length >= period) {
                movingAverage = mean(values);
            }
            return movingAverage;
        };
    };
    const exponentialMovingAverage = function(data) {
        const size = period.apply(this, arguments);
        const alpha = 2 / (size + 1);
        const initialAccumulator = initialMovingAverageAccumulator(size);
        let ema;
        return data.map((d, i) => {
            const v = value(d, i);
            if (ema === undefined) {
                ema = initialAccumulator(v);
            } else {
                ema = v * alpha + (1 - alpha) * ema;
            }
            return convertNaN(ema);
        });
    };

    exponentialMovingAverage.period = (...args) => {
        if (!args.length) {
            return period;
        }
        period = functor(args[0]);
        return exponentialMovingAverage;
    };

    exponentialMovingAverage.value = (...args) => {
        if (!args.length) {
            return value;
        }
        value = args[0];
        return exponentialMovingAverage;
    };

    return exponentialMovingAverage;
}
<|endoftext|>


<commit_before>"use strict";

/*
*   Sir Trevor Uploader
*   Generic Upload implementation that can be extended for blocks
*/

var _ = require('../lodash');
var config = require('../config');
var utils = require('../utils');
var Ajax = require('../packages/ajax');

var EventBus = require('../event-bus');

module.exports = function(block, file, success, error) {

  EventBus.trigger('onUploadStart');

  var uid  = [block.blockID, (new Date()).getTime(), 'raw'].join('-');
  var data = new FormData();
  var attachmentName = block.attachmentName || config.defaults.attachmentName;
  var attachmentFile = block.attachmentFile || config.defaults.attachmentFile;
  var attachmentUid = block.attachmentUid || config.defaults.attachmentUid;

  data.append(attachmentName, file.name);
  data.append(attachmentFile, file);
  data.append(attachmentUid, uid);

  block.resetMessages();

  var callbackSuccess = function(data) {
    utils.log('Upload callback called');
    EventBus.trigger('onUploadStop', data);

    if (!_.isUndefined(success) && _.isFunction(success)) {
      success.apply(block, arguments, data);
    }

    block.removeQueuedItem(uid);
  };

  var callbackError = function(jqXHR, status, errorThrown) {
    utils.log('Upload callback error called');
    EventBus.trigger('onUploadStop', undefined, errorThrown, status, jqXHR);

    if (!_.isUndefined(error) && _.isFunction(error)) {
      error.call(block, status);
    }

    block.removeQueuedItem(uid);
  };

  var url = block.uploadUrl || config.defaults.uploadUrl;

  var xhr = Ajax.fetch(url, {
    body: data,
    method: 'POST',
    dataType: 'json'
  });

  block.addQueuedItem(uid, xhr);

  xhr.then(callbackSuccess)
     .catch(callbackError);

  return xhr;
};
<commit_msg>Pass formdata to onUploadStart event to be manipulated<commit_after>"use strict";

/*
*   Sir Trevor Uploader
*   Generic Upload implementation that can be extended for blocks
*/

var _ = require('../lodash');
var config = require('../config');
var utils = require('../utils');
var Ajax = require('../packages/ajax');

var EventBus = require('../event-bus');

module.exports = function(block, file, success, error) {
  var uid  = [block.blockID, (new Date()).getTime(), 'raw'].join('-');
  var data = new FormData();
  var attachmentName = block.attachmentName || config.defaults.attachmentName;
  var attachmentFile = block.attachmentFile || config.defaults.attachmentFile;
  var attachmentUid = block.attachmentUid || config.defaults.attachmentUid;

  data.append(attachmentName, file.name);
  data.append(attachmentFile, file);
  data.append(attachmentUid, uid);

  EventBus.trigger('onUploadStart', data);

  block.resetMessages();

  var callbackSuccess = function(data) {
    utils.log('Upload callback called');
    EventBus.trigger('onUploadStop', data);

    if (!_.isUndefined(success) && _.isFunction(success)) {
      success.apply(block, arguments, data);
    }

    block.removeQueuedItem(uid);
  };

  var callbackError = function(jqXHR, status, errorThrown) {
    utils.log('Upload callback error called');
    EventBus.trigger('onUploadStop', undefined, errorThrown, status, jqXHR);

    if (!_.isUndefined(error) && _.isFunction(error)) {
      error.call(block, status);
    }

    block.removeQueuedItem(uid);
  };

  var url = block.uploadUrl || config.defaults.uploadUrl;

  var xhr = Ajax.fetch(url, {
    body: data,
    method: 'POST',
    dataType: 'json'
  });

  block.addQueuedItem(uid, xhr);

  xhr.then(callbackSuccess)
     .catch(callbackError);

  return xhr;
};
<|endoftext|>


<commit_before>import { addPlugin } from './plugins';

// CSS:after content fix. Turns 'value' into ''value'';
addPlugin(
  'parseKeyValue',
  (k, v) => k === 'content' && v === '' && [k, `'${v}'`]
);
<commit_msg>adding a condition for RN<commit_after>import { addPlugin } from './plugins';

if (navigator.product != 'ReactNative') {
  // CSS:after content fix. Turns 'value' into ''value'';
  addPlugin(
    'parseKeyValue',
    (k, v) => k === 'content' && v === '' && [k, `'${v}'`]
  );
}
<|endoftext|>


<commit_before>/* -*- Mode: js; js-indent-level: 2; indent-tabs-mode: nil; tab-width: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
/*
 * Copyright 2013 Mozilla Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*global renderDisplayObject, RenderVisitor */

var BitmapDataDefinition = (function () {
  var def = {
    __class__: 'flash.display.BitmapData',

    initialize: function () {
      if (this.symbol) {
        this._img = this.symbol.img;
        this._skipCopyToCanvas = this.symbol.skipCopyToCanvas;
      }
    },

    _checkCanvas: function() {
      if (this._drawable === null)
        throw ArgumentError();
    },

    ctor: function(width, height, transparent, backgroundColor) {
      if (this._img) {
        // the image can be HTML image or canvas
        width = this._img.naturalWidth || this._img.width;
        height = this._img.naturalHeight || this._img.height;
      } else if (isNaN(width + height) || width <= 0 || height <= 0) {
        throw ArgumentError();
      }

      this._transparent = transparent === undefined ? true : !!transparent;
      this._backgroundColor = backgroundColor | 0;

      if (this._skipCopyToCanvas) {
        this._drawable = this._img;
      } else {
        var canvas = document.createElement('canvas');
        this._ctx = canvas.getContext('kanvas-2d');
        canvas.width = width | 0;
        canvas.height = height | 0;
        this._drawable = canvas;
        if (!transparent || this._backgroundColor)
          this.fillRect(new flash.geom.Rectangle(0, 0, width | 0, height | 0), backgroundColor);
        if (this._img)
          this._ctx.drawImage(this._img, 0, 0);
      }
    },
    dispose: function() {
      this._ctx = null;
      this._drawable.width = 0;
      this._drawable.height = 0;
      this._drawable = null;
    },
    draw: function(source, matrix, colorTransform, blendMode, clipRect, smoothing) {
      this._checkCanvas();
      this._ctx.save();
      this._ctx.beginPath();
      if (clipRect) {
        this._ctx.rect(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
        this._ctx.clip();
      }
      if (matrix) {
        this._ctx.transform(matrix.a, matrix.b, matrix.c, matrix.d, matrix.tx, matrix.ty);
      }
      (new RenderVisitor(source, this._ctx, true)).startFragment();
      this._ctx.restore();
    },
    fillRect: function(rect, color) {
      this._checkCanvas();
      if (!this._transparent) {
        color |= 0xff000000;
      }
      var ctx = this._ctx;
      ctx.fillStyle = ARGBtoCSSColor(color);
      ctx.fillRect(rect.x, rect.y, rect.width, rect.height);
    },
    getPixel: function(x, y) {
      this._checkCanvas();
      var data = this._ctx.getImageData(x, y, 1, 1).data;
      return dataToRGB(data);
    },
    getPixel32: function(x, y) {
      this._checkCanvas();
      var data = this._ctx.getImageData(x, y, 1, 1).data;
      return dataToARGB(data);
    },
    setPixel: function(x, y, color) {
      this.fillRect({ x: x, y: y, width: 1, height: 1 }, color | 0xFF000000);
    },
    setPixel32: function(x, y, color) {
      this.fillRect({ x: x, y: y, width: 1, height: 1 }, color);
    },
    /**
     * Provides a fast routine to perform pixel manipulation between images with no stretching, rotation, or color effects.
     */
    copyPixels: function copyPixels(sourceBitmapData, sourceRect, destPoint, alphaBitmapData, alphaPoint, mergeAlpha) {
      if (alphaBitmapData) {
        notImplemented("BitmapData.copyPixels w/ alpha");
      }
      var dx = destPoint.x;
      var dy = destPoint.y;
      var dw = sourceRect.width;
      var dh = sourceRect.height;
      var sx = sourceRect.x;
      var sy = sourceRect.y;
      this._ctx.drawImage(sourceBitmapData._drawable, dx, dy, dw, dh, sx, sy, dw, dh);
    },
    /**
     * Locks an image so that any objects that reference the BitmapData object, such as Bitmap objects,
     * are not updated when this BitmapData object changes.
     */
    lock: function lock() { // (void) -> void
      somewhatImplemented("BitmapData.lock");
    },
    /**
     * Unlocks an image so that any objects that reference the BitmapData object, such as Bitmap
     * objects, are updated when this BitmapData object changes.
     */
    unlock: function unlock(changeRect) { // (changeRect:Rectangle = null) -> void
      somewhatImplemented("BitmapData.unlock");
    },
    clone: function() {
      this._checkCanvas();
      var bd = new flash.display.BitmapData(this._drawable.width, this._drawable.height, true, 0);
      bd._ctx.drawImage(this._drawable, 0, 0);
      return bd;
    },
    scroll: function(x, y) {
      this._checkCanvas();
      this._ctx.draw(this._drawable, x, y);
      this._ctx.save();
      this._ctx.fillStyle = ARGBtoCSSColor(this._backgroundColor);
      var w = this._drawable.width;
      var h = this._drawable.height;
      if (x > 0) {
        this._ctx.fillRect(0, 0, x, h);
      } else if (x < 0) {
        this._ctx.fillRect(x, 0, w, h);
      }
      if (y > 0) {
        this._ctx.fillRect(x, y, w, h);
      } else if (y < 0) {
        this._ctx.fillRect(0, y, w, h);
      }
      this._ctx.restore();
    },
    get width() {
      return this._drawable.width;
    },
    get height() {
      return this._drawable.height;
    }
  };

  var desc = Object.getOwnPropertyDescriptor;

  def.__glue__ = {
    native: {
      instance: {
        ctor : def.ctor,
        fillRect : def.fillRect,
        dispose : def.dispose,
        getPixel : def.getPixel,
        getPixel32 : def.getPixel32,
        setPixel : def.setPixel,
        setPixel32 : def.setPixel32,
        copyPixels: def.copyPixels,
        lock: def.lock,
        unlock: def.unlock,
        draw : def.draw,
        clone : def.clone,
        scroll : def.scroll,
        width : desc(def, "width"),
        height : desc(def, "height")
      }
    }
  };

  return def;
}).call(this);

function dataToRGB(data) {
  return data[0] << 16 | data[1] << 8 | data[2];
}
function dataToARGB(data) {
  return data[3] << 24 | dataToRGB(data);
}
function ARGBtoRGBA(argb) {
  return (argb >>> 24 | argb << 8) >>> 0;
}
function ARGBtoCSSColor(argb) {
  return 'rgba(' + (argb >>> 16 & 0xff) + ',' + (argb >>> 8 & 0xff) + ',' +
               (argb & 0xff) + ',' + (argb >>> 24 & 0xff) / 0xff + ')';
}
<commit_msg>Correct order of arguments.<commit_after>/* -*- Mode: js; js-indent-level: 2; indent-tabs-mode: nil; tab-width: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
/*
 * Copyright 2013 Mozilla Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*global renderDisplayObject, RenderVisitor */

var BitmapDataDefinition = (function () {
  var def = {
    __class__: 'flash.display.BitmapData',

    initialize: function () {
      if (this.symbol) {
        this._img = this.symbol.img;
        this._skipCopyToCanvas = this.symbol.skipCopyToCanvas;
      }
    },

    _checkCanvas: function() {
      if (this._drawable === null)
        throw ArgumentError();
    },

    ctor: function(width, height, transparent, backgroundColor) {
      if (this._img) {
        // the image can be HTML image or canvas
        width = this._img.naturalWidth || this._img.width;
        height = this._img.naturalHeight || this._img.height;
      } else if (isNaN(width + height) || width <= 0 || height <= 0) {
        throw ArgumentError();
      }

      this._transparent = transparent === undefined ? true : !!transparent;
      this._backgroundColor = backgroundColor | 0;

      if (this._skipCopyToCanvas) {
        this._drawable = this._img;
      } else {
        var canvas = document.createElement('canvas');
        this._ctx = canvas.getContext('kanvas-2d');
        canvas.width = width | 0;
        canvas.height = height | 0;
        this._drawable = canvas;
        if (!transparent || this._backgroundColor)
          this.fillRect(new flash.geom.Rectangle(0, 0, width | 0, height | 0), backgroundColor);
        if (this._img)
          this._ctx.drawImage(this._img, 0, 0);
      }
    },
    dispose: function() {
      this._ctx = null;
      this._drawable.width = 0;
      this._drawable.height = 0;
      this._drawable = null;
    },
    draw: function(source, matrix, colorTransform, blendMode, clipRect, smoothing) {
      this._checkCanvas();
      this._ctx.save();
      this._ctx.beginPath();
      if (clipRect) {
        this._ctx.rect(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
        this._ctx.clip();
      }
      if (matrix) {
        this._ctx.transform(matrix.a, matrix.b, matrix.c, matrix.d, matrix.tx, matrix.ty);
      }
      (new RenderVisitor(source, this._ctx, true)).startFragment();
      this._ctx.restore();
    },
    fillRect: function(rect, color) {
      this._checkCanvas();
      if (!this._transparent) {
        color |= 0xff000000;
      }
      var ctx = this._ctx;
      ctx.fillStyle = ARGBtoCSSColor(color);
      ctx.fillRect(rect.x, rect.y, rect.width, rect.height);
    },
    getPixel: function(x, y) {
      this._checkCanvas();
      var data = this._ctx.getImageData(x, y, 1, 1).data;
      return dataToRGB(data);
    },
    getPixel32: function(x, y) {
      this._checkCanvas();
      var data = this._ctx.getImageData(x, y, 1, 1).data;
      return dataToARGB(data);
    },
    setPixel: function(x, y, color) {
      this.fillRect({ x: x, y: y, width: 1, height: 1 }, color | 0xFF000000);
    },
    setPixel32: function(x, y, color) {
      this.fillRect({ x: x, y: y, width: 1, height: 1 }, color);
    },
    /**
     * Provides a fast routine to perform pixel manipulation between images with no stretching, rotation, or color effects.
     */
    copyPixels: function copyPixels(sourceBitmapData, sourceRect, destPoint, alphaBitmapData, alphaPoint, mergeAlpha) {
      if (alphaBitmapData) {
        notImplemented("BitmapData.copyPixels w/ alpha");
      }
      var w = sourceRect.width;
      var h = sourceRect.height;
      var sx = sourceRect.x;
      var sy = sourceRect.y;
      var dx = destPoint.x;
      var dy = destPoint.y;
      this._ctx.drawImage(sourceBitmapData._drawable, sx, sy, w, h, dx, dy, w, h);
    },
    /**
     * Locks an image so that any objects that reference the BitmapData object, such as Bitmap objects,
     * are not updated when this BitmapData object changes.
     */
    lock: function lock() { // (void) -> void
      somewhatImplemented("BitmapData.lock");
    },
    /**
     * Unlocks an image so that any objects that reference the BitmapData object, such as Bitmap
     * objects, are updated when this BitmapData object changes.
     */
    unlock: function unlock(changeRect) { // (changeRect:Rectangle = null) -> void
      somewhatImplemented("BitmapData.unlock");
    },
    clone: function() {
      this._checkCanvas();
      var bd = new flash.display.BitmapData(this._drawable.width, this._drawable.height, true, 0);
      bd._ctx.drawImage(this._drawable, 0, 0);
      return bd;
    },
    scroll: function(x, y) {
      this._checkCanvas();
      this._ctx.draw(this._drawable, x, y);
      this._ctx.save();
      this._ctx.fillStyle = ARGBtoCSSColor(this._backgroundColor);
      var w = this._drawable.width;
      var h = this._drawable.height;
      if (x > 0) {
        this._ctx.fillRect(0, 0, x, h);
      } else if (x < 0) {
        this._ctx.fillRect(x, 0, w, h);
      }
      if (y > 0) {
        this._ctx.fillRect(x, y, w, h);
      } else if (y < 0) {
        this._ctx.fillRect(0, y, w, h);
      }
      this._ctx.restore();
    },
    get width() {
      return this._drawable.width;
    },
    get height() {
      return this._drawable.height;
    }
  };

  var desc = Object.getOwnPropertyDescriptor;

  def.__glue__ = {
    native: {
      instance: {
        ctor : def.ctor,
        fillRect : def.fillRect,
        dispose : def.dispose,
        getPixel : def.getPixel,
        getPixel32 : def.getPixel32,
        setPixel : def.setPixel,
        setPixel32 : def.setPixel32,
        copyPixels: def.copyPixels,
        lock: def.lock,
        unlock: def.unlock,
        draw : def.draw,
        clone : def.clone,
        scroll : def.scroll,
        width : desc(def, "width"),
        height : desc(def, "height")
      }
    }
  };

  return def;
}).call(this);

function dataToRGB(data) {
  return data[0] << 16 | data[1] << 8 | data[2];
}
function dataToARGB(data) {
  return data[3] << 24 | dataToRGB(data);
}
function ARGBtoRGBA(argb) {
  return (argb >>> 24 | argb << 8) >>> 0;
}
function ARGBtoCSSColor(argb) {
  return 'rgba(' + (argb >>> 16 & 0xff) + ',' + (argb >>> 8 & 0xff) + ',' +
               (argb & 0xff) + ',' + (argb >>> 24 & 0xff) / 0xff + ')';
}
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2017 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.nanos.client',
  name: 'Client',

  documentation: 'Client for connecting to NANOS server.',

  requires: [
    'foam.dao.EasyDAO',
    'foam.nanos.auth.Country',
    'foam.nanos.auth.Group',
    'foam.nanos.auth.Language',
    'foam.nanos.auth.Permission',
    'foam.nanos.auth.Region',
    'foam.nanos.auth.User',
    'foam.nanos.boot.NSpec',
    'foam.nanos.cron.Cron',
    'foam.nanos.export.DriverRegistry',
    'foam.nanos.menu.Menu',
    'foam.nanos.script.Script',
    'foam.nanos.test.Test'
  ],

  exports: [
    'countryDAO',
    'cronDAO',
    'groupDAO',
    'exportDriverRegistryDAO',
    'languageDAO',
    'menuDAO',
    'nSpecDAO',
    'permissionDAO',
    'regionDAO',
    'scriptDAO',
    'testDAO',
    'userDAO'
  ],

  properties: [
    {
      name: 'nSpecDAO',
      factory: function() {
        return this.createDAO({
          of: this.NSpec,
          seqNo: true,
          testData: [
            { name: 'http',   serve: false, serviceClass: 'foam.nanos.http.NanoHttpServer' },
            { name: 'log',    serve: false, serviceClass: 'foam.nanos.log.FileLogger' },
            { name: 'pmlog',  serve: false, serviceClass: 'foam.nanos.pm.DAOPMLogger' },
            { name: 'auth',   serve: true,  serviceClass: 'foam.nanos.auth.UserAndGroupAuthService' },
            { name: 'test',   serve: true,  serviceClass: 'foam.nanos.test.TestRunner' },
            { name: 'script', serve: true,  serviceClass: 'foam.nanos.script.ScriptRunner' },
            { name: 'cron',   serve: true,  serviceClass: 'foam.nanos.cron.CronRunner' }
          ]
        });
      }
    },

    {
      name: 'countryDAO',
      factory: function() {
        return this.createDAO({
          of: this.Country,
          testData: [
            { code: 'BR', name: 'Brazil' },
            { code: 'CA', name: 'Canada' },
            { code: 'CN', name: 'China' },
            { code: 'IN', name: 'India' },
            { code: 'JM', name: 'Jamacia' },
            { code: 'LB', name: 'Lebanon' },
            { code: 'MX', name: 'Mexico' },
            { code: 'RS', name: 'Serbia' },
            { code: 'TT', name: 'Trinidad and Tobago' },
            { code: 'UK', name: 'United Kingdom' },
            { code: 'US', name: 'USA' },
            { code: 'ZA', name: 'South Africa' }
          ]
        });
      }
    },

    // TODO: change to client DAO
    {
      name: 'exportDriverRegistryDAO',
      factory: function() {
        return this.createDAO({
          of: this.DriverRegistry,
          testData: [
            { id: 'CSV',  driverName: 'net.nanopay.export.CSVDriver' },
            { id: 'JSON', driverName: 'net.nanopay.export.JSONDriver' },
            { id: 'XML',  driverName: 'net.nanopay.export.XMLDriver' }
          ]
        });
      }
    },

    {
      name: 'regionDAO',
      factory: function() {
        return this.createDAO({
          of: this.Region,
          testData: [
            { countryId: 'CA', code: 'ON', name: 'Ontario' },
            { countryId: 'CA', code: 'PQ', name: 'Quebec' }
          ]
        });
      }
    },

    {
      name: 'menuDAO',
      factory: function() {
        return this.createDAO({

          of: this.Menu,
          testData: [
            { id: 'admin',                           label: 'Admin',          handler: { class: 'foam.nanos.menu.TabsMenu' /*SubMenu*/ } },
              { parent: 'admin', id: 'auth',         label: 'Authentication', handler: { class: 'foam.nanos.menu.TabsMenu' } },
                { parent: 'auth', id: 'users',       label: 'Users',          handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'userDAO' } },
                { parent: 'auth', id: 'groups',      label: 'Groups',         handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'groupDAO' } },
                { parent: 'auth', id: 'permissions', label: 'Permissions',    handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'permissionDAO' }  },
                { parent: 'auth', id: 'countries',   label: 'Countries',      handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'countryDAO' } },
                { parent: 'auth', id: 'regions',     label: 'Regions',        handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'regionDAO' } },
                { parent: 'auth', id: 'lang',        label: 'Languages',      handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'languageDAO' } },
              { parent: 'admin', id: 'nspec',        label: 'Nano Services',  handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'nSpecDAO' }  },
              { parent: 'admin', id: 'export',        label: 'Export Drivers',  handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'exportDriverRegistryDAO' }  },
              { parent: 'admin', id: 'menus',        label: 'Menus',          handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'menuDAO', summaryView: { class: 'foam.u2.view.TreeView', relationship: MenuRelationship, formatter: function() { this.add(this.data.label); } }  } },
              { parent: 'admin', id: 'scripts',      label: 'Scripts',        handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'scriptDAO' }  },
              { parent: 'admin', id: 'tests',        label: 'Tests',          handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'testDAO' }  },
              { parent: 'admin', id: 'cron',         label: 'Cron Jobs',      handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'cronDAO' }  },
              { parent: 'admin', id: 'pm',           label: 'Performance' },
              { parent: 'admin', id: 'log',          label: 'View Logs' },
              /*
            { id: 'support',                         label: 'Support',         handler: { class: 'foam.nanos.menu.TabsMenu' } },
              { parent: 'support', id: 'api',        label: 'API Reference' },
              { parent: 'support', id: 'context',    label: 'Context Walker' }
              */
          ]
        }).orderBy(this.Menu.ORDER, this.Menu.ID);
      }
    },

    {
      name: 'userDAO',
      factory: function() {
        return this.createDAO({
          of: this.User,
          seqNo: true,
          testData: [
            { id: 1, firstName: 'Simon', lastName: 'Alexander', phone: '16133195312' }
          ]
        });
      }
    },

    {
      name: 'languageDAO',
      factory: function() {
        return this.createDAO({
          of: this.Language,
          testData: [
            { code: 'en', name: 'English' },
            { code: 'fr', name: 'French' }
          ]
        });
      }
    },

    {
      name: 'groupDAO',
      factory: function() {
        return this.createDAO({
          of: this.Group,
          seqNo: true,
          testData: [
            { id: 1, firstName: 'nanoPay Admin', lastName: 'nanoPay administration users' },
            { id: 2, firstName: 'Admin',         lastName: 'Administration users' },
            { id: 3, firstName: 'Tester',        lastName: 'Testers' },
            { id: 3, firstName: 'End User',      lastName: 'End users' }
          ]
        });
      }
    },

      {
        name: 'permissionDAO',
        factory: function() {
          return this.createDAO({
            of: this.Permission,
            testData: [
              { id: '*',         description: 'Do anything global permission.' },
              { id: 'menu.auth', description: 'Perform authentication related configuration.' }
            ]
          });
        }
      },

        {
          name: 'scriptDAO',
          factory: function() {
            return this.createDAO({
              of: this.Script,
              seqNo: true,
              testData: [
              ]
            });
          }
        },

        {
          name: 'cronDAO',
          factory: function() {
            return this.createDAO({
              of: this.Cron,
              seqNo: true,
              testData: [
              ]
            });
          }
        },

        {
          name: 'testDAO',
          factory: function() {
            return this.createDAO({
              of: this.Test,
              seqNo: true,
              testData: [
              ]
            });
          }
        }

  ],

  methods: [
    function createDAO(config) {
      config.daoType = 'MDAO'; // 'IDB';
      config.cache   = true;

      return this.EasyDAO.create(config);
    }
  ]
});
<commit_msg>Ordering<commit_after>/**
 * @license
 * Copyright 2017 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.nanos.client',
  name: 'Client',

  documentation: 'Client for connecting to NANOS server.',

  requires: [
    'foam.dao.EasyDAO',
    'foam.nanos.auth.Country',
    'foam.nanos.auth.Group',
    'foam.nanos.auth.Language',
    'foam.nanos.auth.Permission',
    'foam.nanos.auth.Region',
    'foam.nanos.auth.User',
    'foam.nanos.boot.NSpec',
    'foam.nanos.cron.Cron',
    'foam.nanos.export.DriverRegistry',
    'foam.nanos.menu.Menu',
    'foam.nanos.script.Script',
    'foam.nanos.test.Test'
  ],

  exports: [
    'countryDAO',
    'cronDAO',
    'exportDriverRegistryDAO',
    'groupDAO',
    'languageDAO',
    'menuDAO',
    'nSpecDAO',
    'permissionDAO',
    'regionDAO',
    'scriptDAO',
    'testDAO',
    'userDAO'
  ],

  properties: [
    {
      name: 'nSpecDAO',
      factory: function() {
        return this.createDAO({
          of: this.NSpec,
          seqNo: true,
          testData: [
            { name: 'http',   serve: false, serviceClass: 'foam.nanos.http.NanoHttpServer' },
            { name: 'log',    serve: false, serviceClass: 'foam.nanos.log.FileLogger' },
            { name: 'pmlog',  serve: false, serviceClass: 'foam.nanos.pm.DAOPMLogger' },
            { name: 'auth',   serve: true,  serviceClass: 'foam.nanos.auth.UserAndGroupAuthService' },
            { name: 'test',   serve: true,  serviceClass: 'foam.nanos.test.TestRunner' },
            { name: 'script', serve: true,  serviceClass: 'foam.nanos.script.ScriptRunner' },
            { name: 'cron',   serve: true,  serviceClass: 'foam.nanos.cron.CronRunner' }
          ]
        });
      }
    },

    {
      name: 'countryDAO',
      factory: function() {
        return this.createDAO({
          of: this.Country,
          testData: [
            { code: 'BR', name: 'Brazil' },
            { code: 'CA', name: 'Canada' },
            { code: 'CN', name: 'China' },
            { code: 'IN', name: 'India' },
            { code: 'JM', name: 'Jamacia' },
            { code: 'LB', name: 'Lebanon' },
            { code: 'MX', name: 'Mexico' },
            { code: 'RS', name: 'Serbia' },
            { code: 'TT', name: 'Trinidad and Tobago' },
            { code: 'UK', name: 'United Kingdom' },
            { code: 'US', name: 'USA' },
            { code: 'ZA', name: 'South Africa' }
          ]
        });
      }
    },

    // TODO: change to client DAO
    {
      name: 'exportDriverRegistryDAO',
      factory: function() {
        return this.createDAO({
          of: this.DriverRegistry,
          testData: [
            { id: 'CSV',  driverName: 'net.nanopay.export.CSVDriver' },
            { id: 'JSON', driverName: 'net.nanopay.export.JSONDriver' },
            { id: 'XML',  driverName: 'net.nanopay.export.XMLDriver' }
          ]
        });
      }
    },

    {
      name: 'regionDAO',
      factory: function() {
        return this.createDAO({
          of: this.Region,
          testData: [
            { countryId: 'CA', code: 'ON', name: 'Ontario' },
            { countryId: 'CA', code: 'PQ', name: 'Quebec' }
          ]
        });
      }
    },

    {
      name: 'menuDAO',
      factory: function() {
        return this.createDAO({

          of: this.Menu,
          testData: [
            { id: 'admin',                           label: 'Admin',          handler: { class: 'foam.nanos.menu.TabsMenu' /*SubMenu*/ } },
              { parent: 'admin', id: 'auth',         label: 'Authentication', handler: { class: 'foam.nanos.menu.TabsMenu' } },
                { parent: 'auth', id: 'users',       label: 'Users',          handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'userDAO' } },
                { parent: 'auth', id: 'groups',      label: 'Groups',         handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'groupDAO' } },
                { parent: 'auth', id: 'permissions', label: 'Permissions',    handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'permissionDAO' }  },
                { parent: 'auth', id: 'countries',   label: 'Countries',      handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'countryDAO' } },
                { parent: 'auth', id: 'regions',     label: 'Regions',        handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'regionDAO' } },
                { parent: 'auth', id: 'lang',        label: 'Languages',      handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'languageDAO' } },
              { parent: 'admin', id: 'nspec',        label: 'Nano Services',  handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'nSpecDAO' }  },
              { parent: 'admin', id: 'export',        label: 'Export Drivers',  handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'exportDriverRegistryDAO' }  },
              { parent: 'admin', id: 'menus',        label: 'Menus',          handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'menuDAO', summaryView: { class: 'foam.u2.view.TreeView', relationship: MenuRelationship, formatter: function() { this.add(this.data.label); } }  } },
              { parent: 'admin', id: 'scripts',      label: 'Scripts',        handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'scriptDAO' }  },
              { parent: 'admin', id: 'tests',        label: 'Tests',          handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'testDAO' }  },
              { parent: 'admin', id: 'cron',         label: 'Cron Jobs',      handler: { class: 'foam.nanos.menu.DAOMenu', daoKey: 'cronDAO' }  },
              { parent: 'admin', id: 'pm',           label: 'Performance' },
              { parent: 'admin', id: 'log',          label: 'View Logs' },
              /*
            { id: 'support',                         label: 'Support',         handler: { class: 'foam.nanos.menu.TabsMenu' } },
              { parent: 'support', id: 'api',        label: 'API Reference' },
              { parent: 'support', id: 'context',    label: 'Context Walker' }
              */
          ]
        }).orderBy(this.Menu.ORDER, this.Menu.ID);
      }
    },

    {
      name: 'userDAO',
      factory: function() {
        return this.createDAO({
          of: this.User,
          seqNo: true,
          testData: [
            { id: 1, firstName: 'Simon', lastName: 'Alexander', phone: '16133195312' }
          ]
        });
      }
    },

    {
      name: 'languageDAO',
      factory: function() {
        return this.createDAO({
          of: this.Language,
          testData: [
            { code: 'en', name: 'English' },
            { code: 'fr', name: 'French' }
          ]
        });
      }
    },

    {
      name: 'groupDAO',
      factory: function() {
        return this.createDAO({
          of: this.Group,
          seqNo: true,
          testData: [
            { id: 1, firstName: 'nanoPay Admin', lastName: 'nanoPay administration users' },
            { id: 2, firstName: 'Admin',         lastName: 'Administration users' },
            { id: 3, firstName: 'Tester',        lastName: 'Testers' },
            { id: 3, firstName: 'End User',      lastName: 'End users' }
          ]
        });
      }
    },

      {
        name: 'permissionDAO',
        factory: function() {
          return this.createDAO({
            of: this.Permission,
            testData: [
              { id: '*',         description: 'Do anything global permission.' },
              { id: 'menu.auth', description: 'Perform authentication related configuration.' }
            ]
          });
        }
      },

        {
          name: 'scriptDAO',
          factory: function() {
            return this.createDAO({
              of: this.Script,
              seqNo: true,
              testData: [
              ]
            });
          }
        },

        {
          name: 'cronDAO',
          factory: function() {
            return this.createDAO({
              of: this.Cron,
              seqNo: true,
              testData: [
              ]
            });
          }
        },

        {
          name: 'testDAO',
          factory: function() {
            return this.createDAO({
              of: this.Test,
              seqNo: true,
              testData: [
              ]
            });
          }
        }

  ],

  methods: [
    function createDAO(config) {
      config.daoType = 'MDAO'; // 'IDB';
      config.cache   = true;

      return this.EasyDAO.create(config);
    }
  ]
});
<|endoftext|>


<commit_before>exports.defaultFormat = defaultFormat;

const regExpPatterns = {
  dependencies: /".*?dependencies"[\s]*?:[\s]*?\{([\s\S]*?)\}/gim,
  dependency: /"(.*?)"([\s]*?:[\s]*?)"(.*?)"/gim,
  version: /^(\D)?(\d*?)(?:\.(\d*?)(?:\.(\d*?))?(?:-[0-9A-Za-z.+-]*?)?)?$/,
};

function defaultFormat(textToFormat, settings) {
  const dependenciesRegExp = new RegExp(regExpPatterns.dependencies);
  return textToFormat.replace(dependenciesRegExp, formatBlocks(settings));
}

function formatBlocks(settings) {
  return (matchedString) => {
    const dependencyRegExp = new RegExp(regExpPatterns.dependency);
    return matchedString.replace(dependencyRegExp, formatVersions(settings));
  };
}

function formatVersions(settings) {
  return (matchedString, dependencyName, dependencySeparator, dependencyVer) => {
    const versionRegExp = regExpPatterns.version;
    const formattedDependencyVer = dependencyVer.replace(versionRegExp, replaceVersion(settings));
    return `"${dependencyName}"${dependencySeparator}"${formattedDependencyVer}"`;
  };
}

function replaceVersion(settings) {
  return (fullVersion, verRange, majorVer, minorVer, patchVer) => {
    const formattedVer = [];
    switch (settings.lastPart) {
      case 'patch': {
        unshiftIfExist(formattedVer, patchVer);
      } // falls through
      case 'minor': {
        unshiftIfExist(formattedVer, minorVer);
      } // falls through
      case 'major': {
        unshiftIfExist(formattedVer, majorVer);
        break;
      }
      default: {
        unshiftIfExist(formattedVer, minorVer, majorVer);
        break;
      }
    }
    let rangeSymbol;
    switch (settings.preferredRange) {
      case 'caret': {
        rangeSymbol = '^';
        break;
      }
      case 'tilde':
      default: {
        rangeSymbol = '~';
        break;
      }
    }
    return `${rangeSymbol}${formattedVer.join('.')}`;
  };
}

function unshiftIfExist(array, ...items) {
  items.forEach((item) => {
    if (item !== undefined) {
      array.unshift(item);
    }
  });
}
<commit_msg>Split complex replaceVersion function<commit_after>exports.defaultFormat = defaultFormat;

const regExpPatterns = {
  dependencies: /".*?dependencies"[\s]*?:[\s]*?\{([\s\S]*?)\}/gim,
  dependency: /"(.*?)"([\s]*?:[\s]*?)"(.*?)"/gim,
  version: /^(\D)?(\d*?)(?:\.(\d*?)(?:\.(\d*?))?(?:-[0-9A-Za-z.+-]*?)?)?$/,
};

function defaultFormat(textToFormat, settings) {
  const dependenciesRegExp = new RegExp(regExpPatterns.dependencies);
  return textToFormat.replace(dependenciesRegExp, formatBlocks(settings));
}

function formatBlocks(settings) {
  return (matchedString) => {
    const dependencyRegExp = new RegExp(regExpPatterns.dependency);
    return matchedString.replace(dependencyRegExp, formatVersions(settings));
  };
}

function formatVersions(settings) {
  return (matchedString, dependencyName, dependencySeparator, dependencyVer) => {
    const versionRegExp = regExpPatterns.version;
    const formattedDependencyVer = dependencyVer.replace(versionRegExp, replaceVersion(settings));
    return `"${dependencyName}"${dependencySeparator}"${formattedDependencyVer}"`;
  };
}

function replaceVersion(settings) {
  return (fullVersion, verRange, majorVer, minorVer, patchVer) => {
    let version = '';
    version = formatNumber(settings, majorVer, minorVer, patchVer);
    version = formatRange(settings, version);
    return version;
  };
}

function formatNumber(settings, majorVer, minorVer, patchVer) {
  const formattedVer = [];
  switch (settings.lastPart) {
    case 'patch': {
      unshiftIfExist(formattedVer, patchVer);
    } // falls through
    case 'minor': {
      unshiftIfExist(formattedVer, minorVer);
    } // falls through
    case 'major': {
      unshiftIfExist(formattedVer, majorVer);
      break;
    }
    default: {
      unshiftIfExist(formattedVer, minorVer, majorVer);
      break;
    }
  }
  return formattedVer.join('.');
}

function formatRange(settings, versionNumber) {
  switch (settings.preferredRange) {
    case 'caret': {
      return `^${versionNumber}`;
    }
    case 'tilde':
    default: {
      return `~${versionNumber}`;
    }
  }
}

function unshiftIfExist(array, ...items) {
  items.forEach((item) => {
    if (item !== undefined) {
      array.unshift(item);
    }
  });
}
<|endoftext|>


<commit_before>var GetAspectRatio = require('./GetAspectRatio');

//  Fits the target rectangle into the source rectangle.
//  Preserves aspect ratio.
//  Scales and centers the target rectangle to the source rectangle

/**
 * [description]
 *
 * @function Phaser.Geom.Rectangle.FitInside
 * @since 3.0.0
 *
 * @param {Phaser.Geom.Rectangle} target - [description]
 * @param {Phaser.Geom.Rectangle} source - [description]
 *
 * @return {Phaser.Geom.Rectangle} [description]
 */
var FitInside = function (target, source)
{
    var ratio = GetAspectRatio(target);

    if (ratio < GetAspectRatio(source))
    {
        //  Taller than Wide
        target.setSize(source.height * ratio, source.height);
    }
    else
    {
        //  Wider than Tall
        target.setSize(source.width, source.width * ratio);
    }

    return target.setPosition(
        (source.right / 2) - (target.width / 2),
        (source.bottom / 2) - (target.height / 2)
    );
};

module.exports = FitInside;
<commit_msg>Fixed rectangle/FitInside.<commit_after>var GetAspectRatio = require('./GetAspectRatio');

//  Fits the target rectangle into the source rectangle.
//  Preserves aspect ratio.
//  Scales and centers the target rectangle to the source rectangle

/**
 * [description]
 *
 * @function Phaser.Geom.Rectangle.FitInside
 * @since 3.0.0
 *
 * @param {Phaser.Geom.Rectangle} target - [description]
 * @param {Phaser.Geom.Rectangle} source - [description]
 *
 * @return {Phaser.Geom.Rectangle} [description]
 */
var FitInside = function (target, source)
{
    var ratio = GetAspectRatio(target);

    if (ratio < GetAspectRatio(source))
    {
        //  Taller than Wide
        target.setSize(source.height * ratio, source.height);
    }
    else
    {
        //  Wider than Tall
        target.setSize(source.width, source.width / ratio);
    }

    return target.setPosition(
        source.centerX - (target.width / 2),
        source.centerY - (target.height / 2)
    );
};

module.exports = FitInside;
<|endoftext|>


<commit_before>import {Component} from 'react';

function canBeReactComponent(component) {
  return typeof component === 'string'
    || typeof component === 'function'
    || component.prototype === Component
}

function isInDefault(component) {
  return !canBeReactComponent(component)
    && canBeReactComponent(component.default)
}

export default function resolveComponent(component) {
  const resolvedComponent = isInDefault(component) ? component.default : component

  return resolvedComponent.WrappedComponent
    ? resolvedComponent.WrappedComponent
    : resolvedComponent
}
<commit_msg>Fix resolving component<commit_after>import React, {Component} from 'react';

class InvalidComponent extends Component {
  render() {
    return (
      <div>
        Invalid component exported
      </div>
    )
  }
}

function canBeReactComponent(component) {
  return typeof component === 'string'
    || typeof component === 'function'
    || (component && component.prototype === Component)
}

function isInDefault(component) {
  return !canBeReactComponent(component)
    && canBeReactComponent(component.default)
}

export default function resolveComponent(component) {
  if (!component)
    return InvalidComponent

  const resolvedComponent = isInDefault(component) ? component.default : component

  return resolvedComponent.WrappedComponent
    ? resolvedComponent.WrappedComponent
    : resolvedComponent
}
<|endoftext|>


<commit_before>// Description:
//   Search your Google drive using hubot
//
// Dependencies:
//   google-api-nodejs-client --> npm googleapis
//
// Commands:
//   hubot drive set code <code>
//          -  used to authenticate the bot initially (see setCode and generateAuthUrl)
//
//   hubot drive tokens
//          -  shows the refresh token, access token, and expiration time for the access token
//
//   hubot drive search [title=<title-string>] [contains=<any-text>]
//          - returns links to files found in google drive if title contains the title-string and if file contains any-text
//          - both title and contains are not required you can provide one or both
//          - if using both put title first
//
//   hubot drive search query=<query-string>
//          - returns links to files found in google drive matching the query string
//          - see more about query strings at: https://developers.google.com/drive/v2/web/search-parameters
//
// Author:
//  Andrew Schmitt

var CLIENT_ID = process.env.HUBOT_DRIVE_CLIENT_ID,
    CLIENT_SECRET = process.env.HUBOT_DRIVE_CLIENT_SECRET,
    REDIRECT_URL = process.env.HUBOT_DRIVE_REDIRECT_URL,
    SCOPES = 'https://www.googleapis.com/auth/drive';

// We'll initialize the google auth in the module.exports functions
// since this is when we have access to the brain
var HubotGoogleAuth = require('hubot-google-auth');
var auth;

/**
 * Lists files and links for the given queryString
 * For more info on constructing query strings see: https://developers.google.com/drive/v2/web/search-parameters
 * This will not handle any paging and will only return the top search results given by the drive api
 *
 * @param  query     a query string
 * @param  cb        the callback function (err, [array of file objects])
 */
var search = function(queryString, cb) {

    var tokens = auth.getTokens(),
        authUrl = auth.generateAuthUrl(),
        authMsg = `Authorize this app by visiting this url :\n ${authUrl}` +
        '\nThen use @hubot drive set code <code>';

    // If there are no existing refresh tokens then the user will need to manually authenticate
    if (!tokens.refresh_token) {
        cb({
            err: null,
            msg: authMsg
        });
        return;
    }

    auth.validateToken(function(err, resp) {
        if (err) {
            cb({
                err: err,
                msg: authMsg
            });
            return;
        }

        auth.google.drive('v2').files.list({
            q: queryString
        }, function(err, resp) {
            if (err) {
                cb({
                    err: err,
                    msg: 'Drive Api Error: encountered an error while fetching file list'
                });
                return;
            }

            // Drive api may return either a drive#fileList or a drive#file
            var kind = resp.kind;
            var files = null;
            if (kind == 'drive#file') {
                files = [resp];
            } else if (kind == 'drive#fileList') {
                files = resp.items;
            }

            if (!files || !(files.length > 0)) {
                cb({
                    err: err,
                    msg: 'Drive Search Error: failed to get a list of files for given parameters'
                });
                return;
            }

            cb(null, files);
        });
    });

}

/**
 * Formats the search results obtained from search
 *
 * @param  results  the array of files returned from search
 */
var formatSearchRes = function(results) {
    var res = '';
    // limit to 5 results
    for (var i = 0; i < 5 && i < results.length; i++) {
        res += `${i+1}.) ${results[i].title} \n${results[i].alternateLink}\n`;
    }

    return res;
}

// Export robot functions
var initialBrainLoad = true;
module.exports = function(robot) {

    auth = new HubotGoogleAuth('HUBOT_DRIVE', CLIENT_ID, CLIENT_SECRET, REDIRECT_URL, SCOPES, robot.brain);

    robot.respond(/drive(\s+set)?\s+code\s+([^\s]+)/i, {
        id: 'drive.set-code'
    }, function(msg) {
        var code = msg.match[2];
        msg.send('Attempting to set code...')
        auth.setCode(code, function(err, resp) {
            if (err) {
                msg.send(err.msg);
                return;
            }

            msg.send("Hubot drive code successfully set!");
        });
    });

    robot.respond(/drive tokens/i, {
        id: 'drive.show-tokens'
    }, function(msg) {
        var tokens = auth.getTokens();
        for (var name in tokens) {
            msg.send(`${name}: ${tokens[name]}`);
        }
    });

    robot.respond(/drive search query=(.)+/i, {
        id: 'drive.search-query'
    }, function(msg) {
        var queryStr = msg.match[1];

        search(queryStr, function(err, resp) {
            if (err) {
                msg.send(err.msg);
                return;
            }

            msg.send(formatSearchRes(resp));
        });
    });

    var searchRe = /drive search (title=((?:.(?!contains=))+))?\s*(contains=(.+))?/i;
    robot.respond(searchRe, {
        id: 'drive.search-title-contains'
    }, function(msg) {
        var titleStr = msg.match[2],
            containsStr = msg.match[4],
            titleQuery = `title contains '${titleStr}'`,
            containsQuery = `fullText contains '${containsStr}'`,
            queryStr = `${titleQuery} and ${containsQuery}`;

        if (!containsStr && !titleStr) {
            msg.send('Must provide either a title or contains parameter to search.');
            return;
        } else if (!containsStr) {
            queryStr = titleQuery;
        } else if (!titleStr) {
            queryStr = containsQuery;
        }

        search(queryStr, function(err, resp) {
            if (err) {
                msg.send(err.msg);
                return;
            }

            msg.send(formatSearchRes(resp));
        });
    });
}<commit_msg>trying to debug. I need a better way to do this.?<commit_after>// Description:
//   Search your Google drive using hubot
//
// Dependencies:
//   google-api-nodejs-client --> npm googleapis
//
// Commands:
//   hubot drive set code <code>
//          -  used to authenticate the bot initially (see setCode and generateAuthUrl)
//
//   hubot drive tokens
//          -  shows the refresh token, access token, and expiration time for the access token
//
//   hubot drive search [title=<title-string>] [contains=<any-text>]
//          - returns links to files found in google drive if title contains the title-string and if file contains any-text
//          - both title and contains are not required you can provide one or both
//          - if using both put title first
//
//   hubot drive search query=<query-string>
//          - returns links to files found in google drive matching the query string
//          - see more about query strings at: https://developers.google.com/drive/v2/web/search-parameters
//
// Author:
//  Andrew Schmitt

var CLIENT_ID = process.env.HUBOT_DRIVE_CLIENT_ID,
    CLIENT_SECRET = process.env.HUBOT_DRIVE_CLIENT_SECRET,
    REDIRECT_URL = process.env.HUBOT_DRIVE_REDIRECT_URL,
    SCOPES = 'https://www.googleapis.com/auth/drive';

// We'll initialize the google auth in the module.exports functions
// since this is when we have access to the brain
var HubotGoogleAuth = require('hubot-google-auth');
var auth;

/**
 * Lists files and links for the given queryString
 * For more info on constructing query strings see: https://developers.google.com/drive/v2/web/search-parameters
 * This will not handle any paging and will only return the top search results given by the drive api
 *
 * @param  query     a query string
 * @param  cb        the callback function (err, [array of file objects])
 */
var search = function(queryString, cb) {

    var tokens = auth.getTokens(),
        authUrl = auth.generateAuthUrl(),
        authMsg = `Authorize this app by visiting this url :\n ${authUrl}` +
        '\nThen use @hubot drive set code <code>';

    // If there are no existing refresh tokens then the user will need to manually authenticate
    if (!tokens.refresh_token) {
        cb({
            err: null,
            msg: authMsg
        });
        return;
    }

    auth.validateToken(function(err, resp) {

        if (err) {
            console.log(err);
            cb({
                err: err,
                msg: authMsg
            });
            return;
        }

        auth.google.drive('v2').files.list({
            q: queryString
        }, function(err, resp) {
            if (err) {
                cb({
                    err: err,
                    msg: 'Drive Api Error: encountered an error while fetching file list'
                });
                return;
            }

            // Drive api may return either a drive#fileList or a drive#file
            var kind = resp.kind;
            var files = null;
            if (kind == 'drive#file') {
                files = [resp];
            } else if (kind == 'drive#fileList') {
                files = resp.items;
            }

            if (!files || !(files.length > 0)) {
                cb({
                    err: err,
                    msg: 'Drive Search Error: failed to get a list of files for given parameters'
                });
                return;
            }

            cb(null, files);
        });
    });

}

/**
 * Formats the search results obtained from search
 *
 * @param  results  the array of files returned from search
 */
var formatSearchRes = function(results) {
    var res = '';
    // limit to 5 results
    for (var i = 0; i < 5 && i < results.length; i++) {
        res += `${i+1}.) ${results[i].title} \n${results[i].alternateLink}\n`;
    }

    return res;
}

// Export robot functions
var initialBrainLoad = true;
module.exports = function(robot) {

    auth = new HubotGoogleAuth('HUBOT_DRIVE', CLIENT_ID, CLIENT_SECRET, REDIRECT_URL, SCOPES, robot.brain);

    robot.respond(/drive(\s+set)?\s+code\s+([^\s]+)/i, {
        id: 'drive.set-code'
    }, function(msg) {
        var code = msg.match[2];
        msg.send('Attempting to set code...')
        auth.setCode(code, function(err, resp) {
            if (err) {
                msg.send(err.msg);
                return;
            }

            msg.send("Hubot drive code successfully set!");
        });
    });

    robot.respond(/drive tokens/i, {
        id: 'drive.show-tokens'
    }, function(msg) {
        var tokens = auth.getTokens();
        for (var name in tokens) {
            msg.send(`${name}: ${tokens[name]}`);
        }
    });

    robot.respond(/drive search query=(.)+/i, {
        id: 'drive.search-query'
    }, function(msg) {
        var queryStr = msg.match[1];

        search(queryStr, function(err, resp) {
            if (err) {
                msg.send(err.msg);
                return;
            }

            msg.send(formatSearchRes(resp));
        });
    });

    var searchRe = /drive search (title=((?:.(?!contains=))+))?\s*(contains=(.+))?/i;
    robot.respond(searchRe, {
        id: 'drive.search-title-contains'
    }, function(msg) {
        var titleStr = msg.match[2],
            containsStr = msg.match[4],
            titleQuery = `title contains '${titleStr}'`,
            containsQuery = `fullText contains '${containsStr}'`,
            queryStr = `${titleQuery} and ${containsQuery}`;

        if (!containsStr && !titleStr) {
            msg.send('Must provide either a title or contains parameter to search.');
            return;
        } else if (!containsStr) {
            queryStr = titleQuery;
        } else if (!titleStr) {
            queryStr = containsQuery;
        }

        search(queryStr, function(err, resp) {
            if (err) {
                msg.send(err.msg);
                return;
            }

            msg.send(formatSearchRes(resp));
        });
    });
}<|endoftext|>


<commit_before>import {vec3, mat4} from 'gl-matrix';

class Interval {
	constructor() {
		this.begin = vec3.create();
		this.end = vec3.create();
	}
	Render(ctx, camera, vprect) {
		var width = vprect.width, height = vprect.height;
		var mtx = mat4.create();
		mat4.mul(mtx, camera.projection, camera.view);
		mat4.mul(mtx, mat4.fromTranslation(mat4.create(), [1, -1, 1]), mtx);
		mat4.mul(mtx, mat4.fromScaling(mat4.create(), [width * .5, -height * .5, .5]), mtx);
		var begin = vec3.transformMat4(vec3.create(), this.begin, mtx);
		var end = vec3.transformMat4(vec3.create(), this.end, mtx);
		ctx.save();
		ctx.beginPath();
		ctx.moveTo(begin[0], begin[1]);
		ctx.lineTo(end[0], end[1]);
		ctx.strokeStyle = "red";
		ctx.stroke();
		ctx.restore();
	}
}

export {Interval};
<commit_msg>text drawing<commit_after>import {vec2, vec3, mat4} from 'gl-matrix';

class Interval {
	constructor() {
		this.begin = vec3.create();
		this.end = vec3.create();
	}
	Render(ctx, camera, vprect) {
		var width = vprect.width, height = vprect.height;
		var mtx = mat4.create();
		mat4.mul(mtx, camera.projection, camera.view);
		mat4.mul(mtx, mat4.fromTranslation(mat4.create(), [1, -1, 1]), mtx);
		mat4.mul(mtx, mat4.fromScaling(mat4.create(), [width * .5, -height * .5, .5]), mtx);
		var begin = vec3.transformMat4(vec3.create(), this.begin, mtx);
		var end = vec3.transformMat4(vec3.create(), this.end, mtx);
		var anchor = vec3.lerp(vec3.create(), begin, end, 0.5);
		var dir = vec2.normalize(vec2.create(), vec2.sub(vec2.create(), end, begin));

		var text = vec2.len(vec2.sub(vec2.create(), end, begin)).toFixed(1);

		var tpx_ = 0;
		var tpy_ = 20;
		var tpx = anchor[0] + dir[0] * tpx_ + dir[1] * tpy_;
		var tpy = anchor[1] + dir[1] * tpx_ - dir[0] * tpy_;

		ctx.save();

		ctx.beginPath();
		ctx.moveTo(begin[0], begin[1]);
		ctx.lineTo(end[0], end[1]);
		ctx.strokeStyle = "red";
		ctx.stroke();

		ctx.beginPath();
		ctx.moveTo(anchor[0], anchor[1]);
		ctx.lineTo(tpx, tpy);
		ctx.strokeStyle = "red";
		ctx.setLineDash([5]);
		ctx.stroke();

		var tw = ctx.measureText(text).width;
		var th = ctx.measureText("M").width * 1.2;

		ctx.fillStyle = "rgba(128, 128, 128, 1)";
		ctx.fillRect(tpx - tw / 2, tpy - th / 2, tw, th);

		ctx.textBaseline = "middle";
		ctx.textAlign = "center";
		ctx.fillStyle = "#FFFFFF";
		ctx.fillText(text, tpx, tpy);

		ctx.restore();
	}
}

export {Interval};
<|endoftext|>


<commit_before>// tipsy, facebook style tooltips for jquery
// version 1.0.0a
// (c) 2008-2010 jason frame [jason@onehackoranother.com]
// released under the MIT license

define([
    "jquery",
    "lodash"
], function($, _) {

    function maybeCall(thing, ctx) {
        return (typeof thing == 'function') ? (thing.call(ctx)) : thing;
    }

    function isElementInDOM(ele) {
        while (ele == ele.parentNode) {
            if (ele == document) {
                return true;
            }
        }
        return false;
    }

    function Tipsy(element, leave, options) {
        _.bindAll(this, "clearCloseTimer");
        this.leave = leave;
        this.$element = $(element);
        this.timeoutId = 0;
        this.options = options;
        this.enabled = true;
        this.fixTitle();
    }

    Tipsy.prototype = {
        show: function() {
            var title = this.getTitle();
            if (title && this.enabled) {
                var $tip = this.tip();

                // don't pop again if already showing
                if($tip.is(":visible")){
                    return;
                }

                $tip.find('.tipsy-inner')[this.options.html ? 'html' : 'text'](title);
                $tip[0].className = 'tipsy'; // reset classname in case of dynamic gravity
                $tip.remove().css({
                    top: 0,
                    left: 0,
                    visibility: 'hidden',
                    display: 'block'
                });

                // Detect existing tooltips. If found then insert the new one after the last fount tip.
                // This ensures that the newest tooltip is lowest in the DOM so it will appear above the others.
                var existingtip = $('.tipsy').filter(':last');
                if (existingtip[0] !== undefined) {
                    $tip.insertAfter(existingtip);
                } else {
                    $tip.prependTo(document.body);
                }

                this.positionTip();
                this.positionTip(); // Run twice. If wordwrap causes tooltip to change size this will fix positioning before render.

                var that = this;
                if (this.options.fade) {
                    $tip.stop().css({
                        opacity: 0,
                        display: 'block',
                        visibility: 'visible'
                    }).animate({
                        opacity: this.options.opacity
                    }, 300, function(){
                        that.options.onOpen(that);
                    });
                } else {
                    $tip.css({
                        visibility: 'visible',
                        opacity: this.options.opacity
                    }).addClass('tip-animate');

                    this.options.onOpen(this);
                }

                if(this.options.interactive){
                    this.$tip.on("mouseenter.tip", this.clearCloseTimer);
                    this.$tip.on("mouseleave.tip", _.bind(this.leave, this.$element[0]));
                }
            }
        },

        positionTip: function() {
            var tip = this.$tip;
            var pos = $.extend({}, this.$element.offset(), {
                    width: this.$element[0].offsetWidth,
                    height: this.$element[0].offsetHeight
                }),
                tp,
                actualWidth = tip[0].offsetWidth,
                actualHeight = tip[0].offsetHeight,
                gravity = maybeCall(this.options.gravity, this.$element[0]);

            switch (gravity.charAt(0)) {
                case 'n':
                    tp = {
                        top: pos.top + pos.height + this.options.offset,
                        left: pos.left + pos.width / 2 - actualWidth / 2
                    };
                    break;
                case 's':
                    tp = {
                        top: pos.top - actualHeight - this.options.offset,
                        left: pos.left + pos.width / 2 - actualWidth / 2
                    };
                    break;
                case 'e':
                    tp = {
                        top: pos.top + pos.height / 2 - actualHeight / 2,
                        left: pos.left - actualWidth - this.options.offset
                    };
                    break;
                case 'w':
                    tp = {
                        top: pos.top + pos.height / 2 - actualHeight / 2,
                        left: pos.left + pos.width + this.options.offset
                    };
                    break;
            }

            var styleTipWidth = tip.find('.tipsy-arrow').outerWidth(),
                tipPointTargetFromLeft = Math.round(pos.left + (this.$element.outerWidth() / 2) ),
                tipPointTargetFromRight = Math.round( $(window).width() - (pos.left + (this.$element.outerWidth() / 2) ) ),
                tipsyPaddingWE = (tip.outerWidth() - tip.width()) / 2,
                minTipCenterOffset = this.options.styleTipOffsetWE + ( styleTipWidth / 2 );

            if (gravity.length == 2) {
                var adjust;

                if (gravity.charAt(1) == 'w') {
                    tp.left = pos.left + pos.width / 2 - 30;
                    if (tipPointTargetFromLeft < minTipCenterOffset) {
                        // reposition if too close to the edge. Account for padding as well.
                        adjust = ( ( tipPointTargetFromLeft - styleTipWidth / 2 ) >= tipsyPaddingWE ? ( tipPointTargetFromLeft - styleTipWidth / 2 ) : tipsyPaddingWE );
                        tip.find('.tipsy-arrow, .tipsy-arrow-border').css('left', adjust);
                    }
                } else {
                    tp.left = pos.left + pos.width / 2 - actualWidth + 30;
                    if (tipPointTargetFromRight < minTipCenterOffset) {
                        adjust = ( ( tipPointTargetFromRight - styleTipWidth / 2 ) >= tipsyPaddingWE ? ( tipPointTargetFromRight - styleTipWidth / 2 ) : tipsyPaddingWE );
                        tip.find('.tipsy-arrow, .tipsy-arrow-border').css('right', adjust);
                    }
                }
            }

            if (tp.left < 0) { tp.left = 0; } // Dont let the tooltip have negative left position

            tip.css(tp).addClass('tipsy-' + gravity);
            tip.find('.tipsy-arrow')[0].className = 'tipsy-arrow tipsy-arrow-' + gravity.charAt(0);
            tip.find('.tipsy-arrow-border')[0].className = 'tipsy-arrow-border tipsy-arrow-border-' + gravity.charAt(0);

            if (this.options.className) {
                this.$tip.addClass(maybeCall(this.options.className, this.$element[0]));
            }
        },

        hide: function() {
            if (this.options.fade) {
                this.tip().stop().fadeOut(function() {
                    $(this).remove();
                });
            } else {
                this.tip().remove();
            }
        },

        fixTitle: function() {
            var $e = this.$element;
            if ($e.attr('title') || typeof($e.attr('data-title')) != 'string') {
                $e.attr('data-title', $e.attr('title') || '').removeAttr('title');
            }
        },

        getTitle: function() {
            var title,
                $e = this.$element,
                o = this.options;

            this.fixTitle();

            if (typeof o.title == 'string') {
                if(o.title == 'data-title' || o.title == 'title'){
                    title = $e.attr(o.title == 'title' ? 'data-title' : o.title);
                } else {
                    title = o.title;
                }
            } else if (typeof o.title == 'function') {
                title = o.title.call($e[0]);
            }

            var template = o.templateMethod(title || o.fallback, $e.attr("data-template") || o.template);

            this.options.onCreate(template);
            return template;
        },

        tip: function() {
            if (!this.$tip) {
                this.$tip = this.options.tipTemplate();

                this.$tip.data('tipsy-pointee', this.$element[0]);
            }
            return this.$tip;
        },

        validate: function() {
            if (!this.$element[0].parentNode) {
                this.remove();
            }
        },

        remove: function(){
            this.hide();
            this.$element.removeData("tipsy");
            this.$element.off(".tip");
            this.$element = null;
            this.options.onClose(this);
            this.options = null;
        },

        clearCloseTimer: function(){
            if(this.timeoutId){
                clearTimeout(this.timeoutId);
                this.timeoutId = 0;
            }
        },

        enable: function() {
            this.enabled = true;
        },
        disable: function() {
            this.enabled = false;
        },
        toggleEnabled: function() {
            this.enabled = !this.enabled;
        }
    };

    $.fn.tipsy = function(options) {

        if (options === true) {
            return this.data('tipsy');
        } else if (typeof options == 'string') {
            var tipsy = this.data('tipsy');
            if (tipsy) tipsy[options]();
            return this;
        }

        options = $.extend({}, $.fn.tipsy.defaults, options);

        function get(ele) {
            var tipsy = $.data(ele, 'tipsy');
            if (!tipsy) {
                tipsy = new Tipsy(ele, leave, $.fn.tipsy.elementOptions(ele, options));
                $.data(ele, 'tipsy', tipsy);
            }
            return tipsy;
        }

        function enter() {
            var tipsy = get(this);

            tipsy.hoverState = 'in';
            if (options.delayIn === 0) {
                tipsy.show();
            } else {
                tipsy.fixTitle();
                setTimeout(function() {
                    if (tipsy.hoverState == 'in') tipsy.show();
                }, options.delayIn);
            }
        }

        function leave() {
            var tipsy = get(this);
            tipsy.hoverState = 'out';

            if (options.delayOut === 0) {
                tipsy.hide();
            } else {
                tipsy.clearCloseTimer();
                tipsy.timeoutId = setTimeout(function() {
                    if (tipsy.hoverState == 'out') tipsy.hide();
                }, options.delayOut);
            }
        }

        if (!options.live) this.each(function() {
            get(this);
        });

        if (options.trigger != 'manual') {
            var eventIn = options.trigger == 'hover' ? 'mouseenter' : 'focus',
                eventOut = options.trigger == 'hover' ? 'mouseleave' : 'blur';

            if (options.live) {
                $(this.context).on(eventIn + ".tip", this.selector, enter);

                if(!options.stayOpen){
                    $(this.context).on(eventOut + ".tip", this.selector, leave);
                }
            } else {
                this.on(eventIn + ".tip", enter);

                if(!options.stayOpen)
                    this.on(eventOut + ".tip", leave);
            }
        }

        return this;
    };

    // Overwrite this method to provide options on a per-element basis.
    // For example, you could store the gravity in a 'tipsy-gravity' attribute:
    // return $.extend({}, options, {gravity: $(ele).attr('tipsy-gravity') || 'n' });
    // (remember - do not modify 'options' in place!)
    $.fn.tipsy.elementOptions = function(ele, options) {
        return $.metadata ? $.extend({}, options, $(ele).metadata()) : options;
    };

    $.fn.tipsy.autoNS = function() {
        return $(this).offset().top > ($(document).scrollTop() + $(window).height() / 2) ? 's' : 'n';
    };

    $.fn.tipsy.autoWE = function() {
        return $(this).offset().left > ($(document).scrollLeft() + $(window).width() / 2) ? 'e' : 'w';
    };

    $.fn.tipsy.autoSEW = function() {
        var $elm = $(this);
        var $ew = $elm.offset().left > ($(document).scrollLeft() + $(window).width() / 2) ? 'e' : 'w';
        return 's'+$ew;
    };

    $.fn.tipsy.defaults = {
        className: null,
        delayIn: 0,
        delayOut: 0,
        fade: false,
        fallback: '',
        gravity: $.fn.tipsy.autoSEW,
        html: true,
        live: false,
        stayOpen: false,
        offset: 6, // offset from element
        opacity: 1,
        title: 'title',
        trigger: 'hover',
        templateMethod: null, // used to output all tip views
        template: "title",
        tipTemplate: null,
        styleTipOffsetWE: 22,
        onCreate: function(){

        },
        onOpen: function(){

        },
        onClose: function(){

        },
        interactive: false // will let you mouse over the tooltip
    };

    $.fn.tipsy.revalidate = function() {
        $('.tipsy').each(function() {
            var pointee = $.data(this, 'tipsy-pointee');
            if (!pointee || !isElementInDOM(pointee)) {
                $(this).remove();
            }
        });
    };

    /**
     * Improved version of autoBounds for automatic placement of chunky tips
     * The original autoBounds failed in two regards: 1. it would never return a 'w' or 'e', gravity even if they
     * were preferred and/or optimal, 2. it only respected the margin between the left hand side of an element and
     * left hand side of the viewport, and the top of an element and the top of the viewport. This version checks
     * to see if the bottom of an element is too close to the bottom of the screen, similarly for the right hand side
     */
    $.fn.tipsy.autoBounds = function(margin, prefer) {
        return function() {
            var dir = {},
                boundTop = $(document).scrollTop() + margin,
                boundLeft = $(document).scrollLeft() + margin,
                $this = $(this);

            // bi-directional string (ne, se, sw, etc...)
            if (prefer.length > 1) {
                dir.ns = prefer[0];
                dir.ew = prefer[1];
            } else {
                // single direction string (e, w, n or s)
                if (prefer[0] == 'e' || prefer[0] == 'w') {
                    dir.ew = prefer[0];
                } else {
                    dir.ns = prefer[0];
                }
            }

            if ($this.offset().top < boundTop) dir.ns = 'n';
            if ($this.offset().left < boundLeft) dir.ew = 'w';
            if ($(window).width() + $(document).scrollLeft() - ($this.offset().left + $this.width()) < margin) dir.ew = 'e';
            if ($(window).height() + $(document).scrollTop() - ($this.offset().top + $this.height()) < margin) dir.ns = 's';

            if (dir.ns) {
                return dir.ns + (dir.ew ? dir.ew : '');
            }
            return dir.ew;
        };
    };

});
<commit_msg>- Add strict declaration<commit_after>// tipsy, facebook style tooltips for jquery
// version 1.0.0a
// (c) 2008-2010 jason frame [jason@onehackoranother.com]
// released under the MIT license

define([
    "jquery",
    "lodash"
], function($, _) {

    'use strict';

    function maybeCall(thing, ctx) {
        return (typeof thing == 'function') ? (thing.call(ctx)) : thing;
    }

    function isElementInDOM(ele) {
        while (ele == ele.parentNode) {
            if (ele == document) {
                return true;
            }
        }
        return false;
    }

    function Tipsy(element, leave, options) {
        _.bindAll(this, "clearCloseTimer");
        this.leave = leave;
        this.$element = $(element);
        this.timeoutId = 0;
        this.options = options;
        this.enabled = true;
        this.fixTitle();
    }

    Tipsy.prototype = {
        show: function() {
            var title = this.getTitle();
            if (title && this.enabled) {
                var $tip = this.tip();

                // don't pop again if already showing
                if($tip.is(":visible")){
                    return;
                }

                $tip.find('.tipsy-inner')[this.options.html ? 'html' : 'text'](title);
                $tip[0].className = 'tipsy'; // reset classname in case of dynamic gravity
                $tip.remove().css({
                    top: 0,
                    left: 0,
                    visibility: 'hidden',
                    display: 'block'
                });

                // Detect existing tooltips. If found then insert the new one after the last fount tip.
                // This ensures that the newest tooltip is lowest in the DOM so it will appear above the others.
                var existingtip = $('.tipsy').filter(':last');
                if (existingtip[0] !== undefined) {
                    $tip.insertAfter(existingtip);
                } else {
                    $tip.prependTo(document.body);
                }

                this.positionTip();
                this.positionTip(); // Run twice. If wordwrap causes tooltip to change size this will fix positioning before render.

                var that = this;
                if (this.options.fade) {
                    $tip.stop().css({
                        opacity: 0,
                        display: 'block',
                        visibility: 'visible'
                    }).animate({
                        opacity: this.options.opacity
                    }, 300, function(){
                        that.options.onOpen(that);
                    });
                } else {
                    $tip.css({
                        visibility: 'visible',
                        opacity: this.options.opacity
                    }).addClass('tip-animate');

                    this.options.onOpen(this);
                }

                if(this.options.interactive){
                    this.$tip.on("mouseenter.tip", this.clearCloseTimer);
                    this.$tip.on("mouseleave.tip", _.bind(this.leave, this.$element[0]));
                }
            }
        },

        positionTip: function() {
            var tip = this.$tip;
            var pos = $.extend({}, this.$element.offset(), {
                    width: this.$element[0].offsetWidth,
                    height: this.$element[0].offsetHeight
                }),
                tp,
                actualWidth = tip[0].offsetWidth,
                actualHeight = tip[0].offsetHeight,
                gravity = maybeCall(this.options.gravity, this.$element[0]);

            switch (gravity.charAt(0)) {
                case 'n':
                    tp = {
                        top: pos.top + pos.height + this.options.offset,
                        left: pos.left + pos.width / 2 - actualWidth / 2
                    };
                    break;
                case 's':
                    tp = {
                        top: pos.top - actualHeight - this.options.offset,
                        left: pos.left + pos.width / 2 - actualWidth / 2
                    };
                    break;
                case 'e':
                    tp = {
                        top: pos.top + pos.height / 2 - actualHeight / 2,
                        left: pos.left - actualWidth - this.options.offset
                    };
                    break;
                case 'w':
                    tp = {
                        top: pos.top + pos.height / 2 - actualHeight / 2,
                        left: pos.left + pos.width + this.options.offset
                    };
                    break;
            }

            var styleTipWidth = tip.find('.tipsy-arrow').outerWidth(),
                tipPointTargetFromLeft = Math.round(pos.left + (this.$element.outerWidth() / 2) ),
                tipPointTargetFromRight = Math.round( $(window).width() - (pos.left + (this.$element.outerWidth() / 2) ) ),
                tipsyPaddingWE = (tip.outerWidth() - tip.width()) / 2,
                minTipCenterOffset = this.options.styleTipOffsetWE + ( styleTipWidth / 2 );

            if (gravity.length == 2) {
                var adjust;

                if (gravity.charAt(1) == 'w') {
                    tp.left = pos.left + pos.width / 2 - 30;
                    if (tipPointTargetFromLeft < minTipCenterOffset) {
                        // reposition if too close to the edge. Account for padding as well.
                        adjust = ( ( tipPointTargetFromLeft - styleTipWidth / 2 ) >= tipsyPaddingWE ? ( tipPointTargetFromLeft - styleTipWidth / 2 ) : tipsyPaddingWE );
                        tip.find('.tipsy-arrow, .tipsy-arrow-border').css('left', adjust);
                    }
                } else {
                    tp.left = pos.left + pos.width / 2 - actualWidth + 30;
                    if (tipPointTargetFromRight < minTipCenterOffset) {
                        adjust = ( ( tipPointTargetFromRight - styleTipWidth / 2 ) >= tipsyPaddingWE ? ( tipPointTargetFromRight - styleTipWidth / 2 ) : tipsyPaddingWE );
                        tip.find('.tipsy-arrow, .tipsy-arrow-border').css('right', adjust);
                    }
                }
            }

            if (tp.left < 0) { tp.left = 0; } // Dont let the tooltip have negative left position

            tip.css(tp).addClass('tipsy-' + gravity);
            tip.find('.tipsy-arrow')[0].className = 'tipsy-arrow tipsy-arrow-' + gravity.charAt(0);
            tip.find('.tipsy-arrow-border')[0].className = 'tipsy-arrow-border tipsy-arrow-border-' + gravity.charAt(0);

            if (this.options.className) {
                this.$tip.addClass(maybeCall(this.options.className, this.$element[0]));
            }
        },

        hide: function() {
            if (this.options.fade) {
                this.tip().stop().fadeOut(function() {
                    $(this).remove();
                });
            } else {
                this.tip().remove();
            }
        },

        fixTitle: function() {
            var $e = this.$element;
            if ($e.attr('title') || typeof($e.attr('data-title')) != 'string') {
                $e.attr('data-title', $e.attr('title') || '').removeAttr('title');
            }
        },

        getTitle: function() {
            var title,
                $e = this.$element,
                o = this.options;

            this.fixTitle();

            if (typeof o.title == 'string') {
                if(o.title == 'data-title' || o.title == 'title'){
                    title = $e.attr(o.title == 'title' ? 'data-title' : o.title);
                } else {
                    title = o.title;
                }
            } else if (typeof o.title == 'function') {
                title = o.title.call($e[0]);
            }

            var template = o.templateMethod(title || o.fallback, $e.attr("data-template") || o.template);

            this.options.onCreate(template);
            return template;
        },

        tip: function() {
            if (!this.$tip) {
                this.$tip = this.options.tipTemplate();

                this.$tip.data('tipsy-pointee', this.$element[0]);
            }
            return this.$tip;
        },

        validate: function() {
            if (!this.$element[0].parentNode) {
                this.remove();
            }
        },

        remove: function(){
            this.hide();
            this.$element.removeData("tipsy");
            this.$element.off(".tip");
            this.$element = null;
            this.options.onClose(this);
            this.options = null;
        },

        clearCloseTimer: function(){
            if(this.timeoutId){
                clearTimeout(this.timeoutId);
                this.timeoutId = 0;
            }
        },

        enable: function() {
            this.enabled = true;
        },
        disable: function() {
            this.enabled = false;
        },
        toggleEnabled: function() {
            this.enabled = !this.enabled;
        }
    };

    $.fn.tipsy = function(options) {

        if (options === true) {
            return this.data('tipsy');
        } else if (typeof options == 'string') {
            var tipsy = this.data('tipsy');
            if (tipsy) {
                tipsy[options]();
            }
            return this;
        }

        options = $.extend({}, $.fn.tipsy.defaults, options);

        function get(ele) {
            var tipsy = $.data(ele, 'tipsy');
            if (!tipsy) {
                tipsy = new Tipsy(ele, leave, $.fn.tipsy.elementOptions(ele, options));
                $.data(ele, 'tipsy', tipsy);
            }
            return tipsy;
        }

        function enter() {
            var tipsy = get(this);

            tipsy.hoverState = 'in';
            if (options.delayIn === 0) {
                tipsy.show();
            } else {
                tipsy.fixTitle();
                setTimeout(function() {
                    if (tipsy.hoverState == 'in') {
                        tipsy.show();
                    }
                }, options.delayIn);
            }
        }

        function leave() {
            var tipsy = get(this);
            tipsy.hoverState = 'out';

            if (options.delayOut === 0) {
                tipsy.hide();
            } else {
                tipsy.clearCloseTimer();
                tipsy.timeoutId = setTimeout(function() {
                    if (tipsy.hoverState == 'out') {
                        tipsy.hide();
                    }
                }, options.delayOut);
            }
        }

        if (!options.live) this.each(function() {
            get(this);
        });

        if (options.trigger != 'manual') {
            var eventIn = options.trigger == 'hover' ? 'mouseenter' : 'focus',
                eventOut = options.trigger == 'hover' ? 'mouseleave' : 'blur';

            if (options.live) {
                $(this.context).on(eventIn + ".tip", this.selector, enter);

                if(!options.stayOpen){
                    $(this.context).on(eventOut + ".tip", this.selector, leave);
                }
            } else {
                this.on(eventIn + ".tip", enter);

                if(!options.stayOpen) {
                    this.on(eventOut + ".tip", leave);
                }
            }
        }

        return this;
    };

    // Overwrite this method to provide options on a per-element basis.
    // For example, you could store the gravity in a 'tipsy-gravity' attribute:
    // return $.extend({}, options, {gravity: $(ele).attr('tipsy-gravity') || 'n' });
    // (remember - do not modify 'options' in place!)
    $.fn.tipsy.elementOptions = function(ele, options) {
        return $.metadata ? $.extend({}, options, $(ele).metadata()) : options;
    };

    $.fn.tipsy.autoNS = function() {
        return $(this).offset().top > ($(document).scrollTop() + $(window).height() / 2) ? 's' : 'n';
    };

    $.fn.tipsy.autoWE = function() {
        return $(this).offset().left > ($(document).scrollLeft() + $(window).width() / 2) ? 'e' : 'w';
    };

    $.fn.tipsy.autoSEW = function() {
        var $elm = $(this);
        var $ew = $elm.offset().left > ($(document).scrollLeft() + $(window).width() / 2) ? 'e' : 'w';
        return 's'+$ew;
    };

    $.fn.tipsy.defaults = {
        className: null,
        delayIn: 0,
        delayOut: 0,
        fade: false,
        fallback: '',
        gravity: $.fn.tipsy.autoSEW,
        html: true,
        live: false,
        stayOpen: false,
        offset: 6, // offset from element
        opacity: 1,
        title: 'title',
        trigger: 'hover',
        templateMethod: null, // used to output all tip views
        template: "title",
        tipTemplate: null,
        styleTipOffsetWE: 22,
        onCreate: function(){

        },
        onOpen: function(){

        },
        onClose: function(){

        },
        interactive: false // will let you mouse over the tooltip
    };

    $.fn.tipsy.revalidate = function() {
        $('.tipsy').each(function() {
            var pointee = $.data(this, 'tipsy-pointee');
            if (!pointee || !isElementInDOM(pointee)) {
                $(this).remove();
            }
        });
    };

    /**
     * Improved version of autoBounds for automatic placement of chunky tips
     * The original autoBounds failed in two regards: 1. it would never return a 'w' or 'e', gravity even if they
     * were preferred and/or optimal, 2. it only respected the margin between the left hand side of an element and
     * left hand side of the viewport, and the top of an element and the top of the viewport. This version checks
     * to see if the bottom of an element is too close to the bottom of the screen, similarly for the right hand side
     */
    $.fn.tipsy.autoBounds = function(margin, prefer) {
        return function() {
            var dir = {},
                boundTop = $(document).scrollTop() + margin,
                boundLeft = $(document).scrollLeft() + margin,
                $this = $(this);

            // bi-directional string (ne, se, sw, etc...)
            if (prefer.length > 1) {
                dir.ns = prefer[0];
                dir.ew = prefer[1];
            } else {
                // single direction string (e, w, n or s)
                if (prefer[0] == 'e' || prefer[0] == 'w') {
                    dir.ew = prefer[0];
                } else {
                    dir.ns = prefer[0];
                }
            }

            if ($this.offset().top < boundTop) {
                dir.ns = 'n';
            }
            if ($this.offset().left < boundLeft) {
                dir.ew = 'w';
            }
            if ($(window).width() + $(document).scrollLeft() - ($this.offset().left + $this.width()) < margin) {
                dir.ew = 'e';
            }
            if ($(window).height() + $(document).scrollTop() - ($this.offset().top + $this.height()) < margin) {
                dir.ns = 's';
            }

            if (dir.ns) {
                return dir.ns + (dir.ew ? dir.ew : '');
            }
            return dir.ew;
        };
    };

});
<|endoftext|>