<commit_before>var Class = require('../../utils/Class');
var BaseSound = require('../BaseSound');
var SoundEvent = require('../SoundEvent');
//  Phaser.Sound.WebAudioSound
// TODO support webkitAudioContext implementation differences
// https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API/Porting_webkitAudioContext_code_to_standards_based_AudioContext
var WebAudioSound = new Class({
    Extends: BaseSound,
    initialize: function WebAudioSound(manager, key, config) {
        if (config === void 0) { config = {}; }
        /**
         * [description]
         *
         * @private
         * @property {AudioBuffer} audioBuffer
         */
        this.audioBuffer = manager.game.cache.audio.get(key);
        if (!this.audioBuffer) {
            console.error('No audio loaded in cache with key: \'' + key + '\'!');
            return;
        }
        /**
         * [description]
         *
         * @private
         * @property {AudioBufferSourceNode} source
         */
        this.source = null;
        /**
         * [description]
         *
         * @private
         * @property {AudioBufferSourceNode} loopSource
         */
        this.loopSource = null;
        /**
         * [description]
         *
         * @private
         * @property {GainNode} muteNode
         */
        this.muteNode = manager.context.createGain();
        /**
         * [description]
         *
         * @private
         * @property {GainNode} volumeNode
         */
        this.volumeNode = manager.context.createGain();
        /**
         * The time at which the sound should have started from the beginning.
         * Based on BaseAudioContext.currentTime value.
         *
         * @private
         * @property {number} playTime
         */
        this.playTime = 0;
        /**
         * The time at which the sound source should actually start playback.
         * Based on BaseAudioContext.currentTime value.
         *
         * @private
         * @property {number} startTime
         */
        this.startTime = 0;
        /**
         * The time at which the sound loop source should actually start playback.
         * Based on BaseAudioContext.currentTime value.
         *
         * @private
         * @property {number} loopTime
         */
        this.loopTime = 0;
        /**
         * An array where we keep track of all rate updates during playback.
         *
         * @private
         * @property {{ time: number, rate: number }[]} rateUpdates
         */
        this.rateUpdates = [];
        /**
         * Used for keeping track when sound source playback has ended
         * so it's state can be updated accordingly.
         *
         * @private
         * @property {boolean} hasEnded
         */
        this.hasEnded = false;
        /**
         * Used for keeping track when sound source has looped
         * so it's state can be updated accordingly.
         *
         * @private
         * @property {boolean} hasLooped
         */
        this.hasLooped = false;
        this.muteNode.connect(this.volumeNode);
        this.volumeNode.connect(manager.destination);
        this.duration = this.audioBuffer.duration;
        this.totalDuration = this.audioBuffer.duration;
        BaseSound.call(this, manager, key, config);
    },
    play: function (markerName, config) {
        if (!BaseSound.prototype.play.call(this, markerName, config)) {
            return null;
        }
        //  \/\/\/ isPlaying = true, isPaused = false \/\/\/
        this.stopAndRemoveBufferSource();
        this.createAndStartBufferSource();
        this.events.dispatch(new SoundEvent(this, 'SOUND_PLAY'));
        return this;
    },
    pause: function () {
        if (this.manager.context.currentTime < this.startTime) {
            return false;
        }
        if (!BaseSound.prototype.pause.call(this)) {
            return false;
        }
        //  \/\/\/ isPlaying = false, isPaused = true \/\/\/
        this.currentConfig.seek = this.getCurrentTime(); // Equivalent to setting paused time
        this.stopAndRemoveBufferSource();
        this.events.dispatch(new SoundEvent(this, 'SOUND_PAUSE'));
        return true;
    },
    resume: function () {
        if (this.manager.context.currentTime < this.startTime) {
            return false;
        }
        if (!BaseSound.prototype.resume.call(this)) {
            return false;
        }
        //  \/\/\/ isPlaying = true, isPaused = false \/\/\/
        this.createAndStartBufferSource();
        this.events.dispatch(new SoundEvent(this, 'SOUND_RESUME'));
        return true;
    },
    stop: function () {
        if (!BaseSound.prototype.stop.call(this)) {
            return false;
        }
        //  \/\/\/ isPlaying = false, isPaused = false \/\/\/
        this.stopAndRemoveBufferSource();
        return true;
    },
    /**
     * Used internally to do what the name says.
     *
     * @private
     */
    createAndStartBufferSource: function () {
        var seek = this.currentConfig.seek;
        var delay = this.currentConfig.delay;
        var when = this.manager.context.currentTime + delay;
        var offset = (this.currentMarker ? this.currentMarker.start : 0) + seek;
        var duration = this.duration - seek;
        this.playTime = when - seek;
        this.startTime = when;
        this.source = this.createBufferSource();
        this.applyConfig();
        this.source.start(Math.max(0, when), Math.max(0, offset), Math.max(0, duration));
        this.resetConfig();
    },
    /**
     * Used internally to do what the name says.
     *
     * @private
     */
    createAndStartLoopBufferSource: function () {
        var when = this.getLoopTime();
        var offset = this.currentMarker ? this.currentMarker.start : 0;
        var duration = this.duration;
        this.loopTime = when;
        this.loopSource = this.createBufferSource();
        this.loopSource.playbackRate.setValueAtTime(this.totalRate, 0);
        this.loopSource.start(Math.max(0, when), Math.max(0, offset), Math.max(0, duration));
    },
    /**
     * @private
     */
    createBufferSource: function () {
        var _this = this;
        var source = this.manager.context.createBufferSource();
        source.buffer = this.audioBuffer;
        source.connect(this.muteNode);
        source.onended = function (ev) {
            if (ev.target === _this.source) {
                // sound ended
                if (_this.currentConfig.loop) {
                    _this.hasLooped = true;
                }
                else {
                    _this.hasEnded = true;
                }
            }
            // else was stopped
        };
        return source;
    },
    /**
     * Used internally to do what the name says.
     *
     * @private
     */
    stopAndRemoveBufferSource: function () {
        if (this.source) {
            this.source.stop();
            this.source = null;
        }
        this.playTime = 0;
        this.startTime = 0;
        this.stopAndRemoveLoopBufferSource();
    },
    /**
     * Used internally to do what the name says.
     *
     * @private
     */
    stopAndRemoveLoopBufferSource: function () {
        if (this.loopSource) {
            this.loopSource.stop();
            this.loopSource = null;
        }
        this.loopTime = 0;
    },
    /**
     * @protected
     */
    applyConfig: function () {
        this.rateUpdates.length = 0;
        this.rateUpdates.push({
            time: 0,
            rate: 1
        });
        BaseSound.prototype.applyConfig.call(this);
    },
    /**
     * Update method called on every game step.
     *
     * @param {number} time - The current timestamp as generated by the Request Animation Frame or SetTimeout.
     * @param {number} delta - The delta time elapsed since the last frame.
     */
    update: function (time, delta) {
        if (this.hasEnded) {
            this.hasEnded = false;
            this.stop();
        }
        else if (this.hasLooped) {
            this.hasLooped = false;
            this.source = this.loopSource;
            this.loopSource = null;
            this.playTime = this.startTime = this.loopTime;
            this.rateUpdates.length = 0;
            this.rateUpdates.push({
                time: 0,
                rate: this.totalRate
            });
            this.createAndStartLoopBufferSource();
            this.events.dispatch(new SoundEvent(this, 'SOUND_LOOP'));
        }
    },
    destroy: function () {
        BaseSound.prototype.destroy.call(this);
        this.audioBuffer = null;
        this.stopAndRemoveBufferSource();
        this.muteNode.disconnect();
        this.muteNode = null;
        this.volumeNode.disconnect();
        this.volumeNode = null;
        this.rateUpdates = null;
    },
    /**
     * @private
     */
    setRate: function () {
        BaseSound.prototype.setRate.call(this);
        var now = this.manager.context.currentTime;
        if (this.source) {
            this.source.playbackRate.setValueAtTime(this.totalRate, now);
        }
        if (this.isPlaying) {
            this.rateUpdates.push({
                time: Math.max(this.startTime, now) - this.playTime,
                rate: this.totalRate
            });
            if (this.loopSource) {
                this.stopAndRemoveLoopBufferSource();
                this.createAndStartLoopBufferSource();
            }
        }
    },
    /**
     * @private
     */
    getCurrentTime: function () {
        var currentTime = 0;
        for (var i = 0; i < this.rateUpdates.length; i++) {
            var nextTime = void 0;
            if (i < this.rateUpdates.length - 1) {
                nextTime = this.rateUpdates[i + 1].time;
            }
            else {
                nextTime = this.manager.context.currentTime - this.playTime;
            }
            currentTime += (nextTime - this.rateUpdates[i].time) * this.rateUpdates[i].rate;
        }
        return currentTime;
    },
    /**
     * @private
     */
    getLoopTime: function () {
        var lastRateUpdateCurrentTime = 0;
        for (var i = 0; i < this.rateUpdates.length - 1; i++) {
            lastRateUpdateCurrentTime +=
                (this.rateUpdates[i + 1].time - this.rateUpdates[i].time) * this.rateUpdates[i].rate;
        }
        var lastRateUpdate = this.rateUpdates[this.rateUpdates.length - 1];
        return this.playTime + lastRateUpdate.time
            + (this.duration - lastRateUpdateCurrentTime) / lastRateUpdate.rate;
    }
});
/**
 * Mute setting.
 * @property {boolean} mute
 */
Object.defineProperty(WebAudioSound.prototype, 'mute', {
    get: function () {
        return this.muteNode.gain.value === 0;
    },
    set: function (value) {
        this.currentConfig.mute = value;
        this.muteNode.gain.setValueAtTime(value ? 0 : 1, 0);
    }
});
/**
 * Volume setting.
 * @property {number} volume
 */
Object.defineProperty(WebAudioSound.prototype, 'volume', {
    get: function () {
        return this.volumeNode.gain.value;
    },
    set: function (value) {
        this.currentConfig.volume = value;
        this.volumeNode.gain.setValueAtTime(value, 0);
    }
});
/**
 * Playback rate.
 * @property {number} rate
 */
Object.defineProperty(WebAudioSound.prototype, 'rate', {
    get: function () {
        return this.currentConfig.rate;
    },
    set: function (value) {
        this.currentConfig.rate = value;
        this.setRate();
    }
});
/**
 * Detuning of sound.
 * @property {number} detune
 */
Object.defineProperty(WebAudioSound.prototype, 'detune', {
    get: function () {
        return this.currentConfig.detune;
    },
    set: function (value) {
        this.currentConfig.detune = value;
        this.setRate();
    }
});
/**
 * Current position of playing sound.
 * @property {number} seek
 */
Object.defineProperty(WebAudioSound.prototype, 'seek', {
    get: function () {
        if (this.isPlaying) {
            if (this.manager.context.currentTime < this.startTime) {
                return this.startTime - this.playTime;
            }
            return this.getCurrentTime();
        }
        else if (this.isPaused) {
            return this.currentConfig.seek;
        }
        else {
            return 0;
        }
    },
    set: function (value) {
        if (this.manager.context.currentTime < this.startTime) {
            return;
        }
        if (this.isPlaying || this.isPaused) {
            value = Math.min(Math.max(0, value), this.duration);
            this.currentConfig.seek = value;
        }
        if (this.isPlaying) {
            this.stopAndRemoveBufferSource();
            this.createAndStartBufferSource();
        }
    }
});
/**
 * Property indicating whether or not
 * the sound or current sound marker will loop.
 *
 * @property {boolean} loop
 */
Object.defineProperty(WebAudioSound.prototype, 'loop', {
    get: function () {
        return this.currentConfig.loop;
    },
    set: function (value) {
        this.currentConfig.loop = value;
        if (this.isPlaying) {
            this.stopAndRemoveLoopBufferSource();
            if (value) {
                this.createAndStartLoopBufferSource();
            }
        }
    }
});
module.exports = WebAudioSound;
<commit_msg>Dispatching event when calling stop method<commit_after>var Class = require('../../utils/Class');
var BaseSound = require('../BaseSound');
var SoundEvent = require('../SoundEvent');
//  Phaser.Sound.WebAudioSound
// TODO support webkitAudioContext implementation differences
// https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API/Porting_webkitAudioContext_code_to_standards_based_AudioContext
var WebAudioSound = new Class({
    Extends: BaseSound,
    initialize: function WebAudioSound(manager, key, config) {
        if (config === void 0) { config = {}; }
        /**
         * [description]
         *
         * @private
         * @property {AudioBuffer} audioBuffer
         */
        this.audioBuffer = manager.game.cache.audio.get(key);
        if (!this.audioBuffer) {
            console.error('No audio loaded in cache with key: \'' + key + '\'!');
            return;
        }
        /**
         * [description]
         *
         * @private
         * @property {AudioBufferSourceNode} source
         */
        this.source = null;
        /**
         * [description]
         *
         * @private
         * @property {AudioBufferSourceNode} loopSource
         */
        this.loopSource = null;
        /**
         * [description]
         *
         * @private
         * @property {GainNode} muteNode
         */
        this.muteNode = manager.context.createGain();
        /**
         * [description]
         *
         * @private
         * @property {GainNode} volumeNode
         */
        this.volumeNode = manager.context.createGain();
        /**
         * The time at which the sound should have started from the beginning.
         * Based on BaseAudioContext.currentTime value.
         *
         * @private
         * @property {number} playTime
         */
        this.playTime = 0;
        /**
         * The time at which the sound source should actually start playback.
         * Based on BaseAudioContext.currentTime value.
         *
         * @private
         * @property {number} startTime
         */
        this.startTime = 0;
        /**
         * The time at which the sound loop source should actually start playback.
         * Based on BaseAudioContext.currentTime value.
         *
         * @private
         * @property {number} loopTime
         */
        this.loopTime = 0;
        /**
         * An array where we keep track of all rate updates during playback.
         *
         * @private
         * @property {{ time: number, rate: number }[]} rateUpdates
         */
        this.rateUpdates = [];
        /**
         * Used for keeping track when sound source playback has ended
         * so it's state can be updated accordingly.
         *
         * @private
         * @property {boolean} hasEnded
         */
        this.hasEnded = false;
        /**
         * Used for keeping track when sound source has looped
         * so it's state can be updated accordingly.
         *
         * @private
         * @property {boolean} hasLooped
         */
        this.hasLooped = false;
        this.muteNode.connect(this.volumeNode);
        this.volumeNode.connect(manager.destination);
        this.duration = this.audioBuffer.duration;
        this.totalDuration = this.audioBuffer.duration;
        BaseSound.call(this, manager, key, config);
    },
    play: function (markerName, config) {
        if (!BaseSound.prototype.play.call(this, markerName, config)) {
            return null;
        }
        //  \/\/\/ isPlaying = true, isPaused = false \/\/\/
        this.stopAndRemoveBufferSource();
        this.createAndStartBufferSource();
        this.events.dispatch(new SoundEvent(this, 'SOUND_PLAY'));
        return this;
    },
    pause: function () {
        if (this.manager.context.currentTime < this.startTime) {
            return false;
        }
        if (!BaseSound.prototype.pause.call(this)) {
            return false;
        }
        //  \/\/\/ isPlaying = false, isPaused = true \/\/\/
        this.currentConfig.seek = this.getCurrentTime(); // Equivalent to setting paused time
        this.stopAndRemoveBufferSource();
        this.events.dispatch(new SoundEvent(this, 'SOUND_PAUSE'));
        return true;
    },
    resume: function () {
        if (this.manager.context.currentTime < this.startTime) {
            return false;
        }
        if (!BaseSound.prototype.resume.call(this)) {
            return false;
        }
        //  \/\/\/ isPlaying = true, isPaused = false \/\/\/
        this.createAndStartBufferSource();
        this.events.dispatch(new SoundEvent(this, 'SOUND_RESUME'));
        return true;
    },
    stop: function () {
        if (!BaseSound.prototype.stop.call(this)) {
            return false;
        }
        //  \/\/\/ isPlaying = false, isPaused = false \/\/\/
        this.stopAndRemoveBufferSource();
        this.events.dispatch(new SoundEvent(this, 'SOUND_STOP'));
        return true;
    },
    /**
     * Used internally to do what the name says.
     *
     * @private
     */
    createAndStartBufferSource: function () {
        var seek = this.currentConfig.seek;
        var delay = this.currentConfig.delay;
        var when = this.manager.context.currentTime + delay;
        var offset = (this.currentMarker ? this.currentMarker.start : 0) + seek;
        var duration = this.duration - seek;
        this.playTime = when - seek;
        this.startTime = when;
        this.source = this.createBufferSource();
        this.applyConfig();
        this.source.start(Math.max(0, when), Math.max(0, offset), Math.max(0, duration));
        this.resetConfig();
    },
    /**
     * Used internally to do what the name says.
     *
     * @private
     */
    createAndStartLoopBufferSource: function () {
        var when = this.getLoopTime();
        var offset = this.currentMarker ? this.currentMarker.start : 0;
        var duration = this.duration;
        this.loopTime = when;
        this.loopSource = this.createBufferSource();
        this.loopSource.playbackRate.setValueAtTime(this.totalRate, 0);
        this.loopSource.start(Math.max(0, when), Math.max(0, offset), Math.max(0, duration));
    },
    /**
     * @private
     */
    createBufferSource: function () {
        var _this = this;
        var source = this.manager.context.createBufferSource();
        source.buffer = this.audioBuffer;
        source.connect(this.muteNode);
        source.onended = function (ev) {
            if (ev.target === _this.source) {
                // sound ended
                if (_this.currentConfig.loop) {
                    _this.hasLooped = true;
                }
                else {
                    _this.hasEnded = true;
                }
            }
            // else was stopped
        };
        return source;
    },
    /**
     * Used internally to do what the name says.
     *
     * @private
     */
    stopAndRemoveBufferSource: function () {
        if (this.source) {
            this.source.stop();
            this.source = null;
        }
        this.playTime = 0;
        this.startTime = 0;
        this.stopAndRemoveLoopBufferSource();
    },
    /**
     * Used internally to do what the name says.
     *
     * @private
     */
    stopAndRemoveLoopBufferSource: function () {
        if (this.loopSource) {
            this.loopSource.stop();
            this.loopSource = null;
        }
        this.loopTime = 0;
    },
    /**
     * @protected
     */
    applyConfig: function () {
        this.rateUpdates.length = 0;
        this.rateUpdates.push({
            time: 0,
            rate: 1
        });
        BaseSound.prototype.applyConfig.call(this);
    },
    /**
     * Update method called on every game step.
     *
     * @param {number} time - The current timestamp as generated by the Request Animation Frame or SetTimeout.
     * @param {number} delta - The delta time elapsed since the last frame.
     */
    update: function (time, delta) {
        if (this.hasEnded) {
            this.hasEnded = false;
            this.stop();
        }
        else if (this.hasLooped) {
            this.hasLooped = false;
            this.source = this.loopSource;
            this.loopSource = null;
            this.playTime = this.startTime = this.loopTime;
            this.rateUpdates.length = 0;
            this.rateUpdates.push({
                time: 0,
                rate: this.totalRate
            });
            this.createAndStartLoopBufferSource();
            this.events.dispatch(new SoundEvent(this, 'SOUND_LOOP'));
        }
    },
    destroy: function () {
        BaseSound.prototype.destroy.call(this);
        this.audioBuffer = null;
        this.stopAndRemoveBufferSource();
        this.muteNode.disconnect();
        this.muteNode = null;
        this.volumeNode.disconnect();
        this.volumeNode = null;
        this.rateUpdates = null;
    },
    /**
     * @private
     */
    setRate: function () {
        BaseSound.prototype.setRate.call(this);
        var now = this.manager.context.currentTime;
        if (this.source) {
            this.source.playbackRate.setValueAtTime(this.totalRate, now);
        }
        if (this.isPlaying) {
            this.rateUpdates.push({
                time: Math.max(this.startTime, now) - this.playTime,
                rate: this.totalRate
            });
            if (this.loopSource) {
                this.stopAndRemoveLoopBufferSource();
                this.createAndStartLoopBufferSource();
            }
        }
    },
    /**
     * @private
     */
    getCurrentTime: function () {
        var currentTime = 0;
        for (var i = 0; i < this.rateUpdates.length; i++) {
            var nextTime = void 0;
            if (i < this.rateUpdates.length - 1) {
                nextTime = this.rateUpdates[i + 1].time;
            }
            else {
                nextTime = this.manager.context.currentTime - this.playTime;
            }
            currentTime += (nextTime - this.rateUpdates[i].time) * this.rateUpdates[i].rate;
        }
        return currentTime;
    },
    /**
     * @private
     */
    getLoopTime: function () {
        var lastRateUpdateCurrentTime = 0;
        for (var i = 0; i < this.rateUpdates.length - 1; i++) {
            lastRateUpdateCurrentTime +=
                (this.rateUpdates[i + 1].time - this.rateUpdates[i].time) * this.rateUpdates[i].rate;
        }
        var lastRateUpdate = this.rateUpdates[this.rateUpdates.length - 1];
        return this.playTime + lastRateUpdate.time
            + (this.duration - lastRateUpdateCurrentTime) / lastRateUpdate.rate;
    }
});
/**
 * Mute setting.
 * @property {boolean} mute
 */
Object.defineProperty(WebAudioSound.prototype, 'mute', {
    get: function () {
        return this.muteNode.gain.value === 0;
    },
    set: function (value) {
        this.currentConfig.mute = value;
        this.muteNode.gain.setValueAtTime(value ? 0 : 1, 0);
    }
});
/**
 * Volume setting.
 * @property {number} volume
 */
Object.defineProperty(WebAudioSound.prototype, 'volume', {
    get: function () {
        return this.volumeNode.gain.value;
    },
    set: function (value) {
        this.currentConfig.volume = value;
        this.volumeNode.gain.setValueAtTime(value, 0);
    }
});
/**
 * Playback rate.
 * @property {number} rate
 */
Object.defineProperty(WebAudioSound.prototype, 'rate', {
    get: function () {
        return this.currentConfig.rate;
    },
    set: function (value) {
        this.currentConfig.rate = value;
        this.setRate();
    }
});
/**
 * Detuning of sound.
 * @property {number} detune
 */
Object.defineProperty(WebAudioSound.prototype, 'detune', {
    get: function () {
        return this.currentConfig.detune;
    },
    set: function (value) {
        this.currentConfig.detune = value;
        this.setRate();
    }
});
/**
 * Current position of playing sound.
 * @property {number} seek
 */
Object.defineProperty(WebAudioSound.prototype, 'seek', {
    get: function () {
        if (this.isPlaying) {
            if (this.manager.context.currentTime < this.startTime) {
                return this.startTime - this.playTime;
            }
            return this.getCurrentTime();
        }
        else if (this.isPaused) {
            return this.currentConfig.seek;
        }
        else {
            return 0;
        }
    },
    set: function (value) {
        if (this.manager.context.currentTime < this.startTime) {
            return;
        }
        if (this.isPlaying || this.isPaused) {
            value = Math.min(Math.max(0, value), this.duration);
            this.currentConfig.seek = value;
        }
        if (this.isPlaying) {
            this.stopAndRemoveBufferSource();
            this.createAndStartBufferSource();
        }
    }
});
/**
 * Property indicating whether or not
 * the sound or current sound marker will loop.
 *
 * @property {boolean} loop
 */
Object.defineProperty(WebAudioSound.prototype, 'loop', {
    get: function () {
        return this.currentConfig.loop;
    },
    set: function (value) {
        this.currentConfig.loop = value;
        if (this.isPlaying) {
            this.stopAndRemoveLoopBufferSource();
            if (value) {
                this.createAndStartLoopBufferSource();
            }
        }
    }
});
module.exports = WebAudioSound;
<|endoftext|>


<commit_before>// @flow
// this file exports pre-transpiled sources of ./src
export * from './src/index.js'
<commit_msg>[phenyl-http-server] export default<commit_after>// @flow
// this file exports pre-transpiled sources of ./src
import Module from './src/index.js'
export default Module
<|endoftext|>


<commit_before>app.translator.plural = function(count) {
  if (count >= 0 && count < 2) {
    return 'one';
    }
  else {
    return 'other';
  }
};

moment.locale('nl', {
  months : 'januari_februari_maart_april_mei_junie_juli_augustus_september_oktober_november_december'.split('_'),
  monthsShort : 'jan._feb._mar._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split('_'),
  weekdays : 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split('_'),
  weekdaysShort : 'zo._ma._di._wo._do._vr._za.'.split('_'),
  weekdaysMin : 'Zo_Ma_Di_Wo_Do_Vr_Za'.split('_'),
  longDateFormat : {
    LT : 'HH:mm',
    LTS : 'HH:mm:ss',
    L : 'DD/MM/YYYY',
    LL : 'D MMMM YYYY',
    LLL : 'D MMMM YYYY HH:mm',
    LLLL : 'dddd D MMMM YYYY HH:mm'
  },
  calendar : {
    sameDay: '[Vandaag om] LT',
    nextDay: '[Morgen om] LT',
    nextWeek: 'dddd [à] LT',
    lastDay: '[Gisteren om] LT',
    lastWeek: 'dddd [om] LT',
    sameElse: 'L'
  },
  ordinalParse: /\d{1,2}(er|)/,
  ordinal : function (number) {
    return number + (number === 1 ? 'er' : '');
  },
  week : {
    dow : 1,
    doy : 4
  }
});
<commit_msg>Add relative time<commit_after>app.translator.plural = function(count) {
  if (count >= 0 && count < 2) {
    return 'one';
    }
  else {
    return 'other';
  }
};

moment.locale('nl', {
  months : 'januari_februari_maart_april_mei_junie_juli_augustus_september_oktober_november_december'.split('_'),
  monthsShort : 'jan._feb._mar._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split('_'),
  weekdays : 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split('_'),
  weekdaysShort : 'zo._ma._di._wo._do._vr._za.'.split('_'),
  weekdaysMin : 'Zo_Ma_Di_Wo_Do_Vr_Za'.split('_'),
  longDateFormat : {
    LT : 'HH:mm',
    LTS : 'HH:mm:ss',
    L : 'DD/MM/YYYY',
    LL : 'D MMMM YYYY',
    LLL : 'D MMMM YYYY HH:mm',
    LLLL : 'dddd D MMMM YYYY HH:mm'
  },
  calendar : {
    sameDay: '[Vandaag om] LT',
    nextDay: '[Morgen om] LT',
    nextWeek: 'dddd [om] LT',
    lastDay: '[Gisteren om] LT',
    lastWeek: 'dddd [om] LT',
    sameElse: 'L'
  },
  relativeTime : {
    future : 'in %s',
    past : '%s geleden',
    s : 'een paar seconden',
    m : 'een minuut',
    mm : '%d minuten',
    h : 'een uur',
    hh : '%d uur',
    d : 'een dag',
    dd : '%d dagen',
    M : 'een maand',
    MM : '%d maanden',
    y : 'een jaar',
    yy : '%d jaar'
  },
  ordinalParse: /\d{1,2}(er|)/,
  ordinal : function (number) {
    return number + (number === 1 ? 'er' : '');
  },
  week : {
    dow : 1,
    doy : 4
  }
});
<|endoftext|>


<commit_before>/**
 * Dydra.com Software Development Kit (SDK) for JavaScript.
 *
 * This is free and unencumbered software released into the public domain.
 *
 * @see http://docs.dydra.com/sdk/javascript
 */

var SPARQL = (function($) {
  /**
   * Constructs a SPARQL 1.1 Query/Update client for jQuery.
   *
   * @param {Object} config
   *
   * @see http://www.w3.org/TR/sparql11-protocol/
   * @see http://www.w3.org/TR/sparql11-results-json/
   */
  var Client = function(endpointURL, config) {
    if (config === undefined) {
      config = {};
    }

    /**
     * @param {Object} options
     */
    this.ajax = function(options) {
      $.ajax(endpointURL, $.extend({}, {
        type: 'POST',
        dataType: 'json',
        accepts: {json: 'application/sparql-results+json'},
        beforeSend: function(xhr) {
          xhr.setRequestHeader('Accept', 'application/sparql-results+json');
        }
      }, config, options));
    };

    /**
     * Executes a SPARQL Query request.
     *
     * @param {String} queryText
     * @param {Object} options
     */
    this.query = function(queryText, options) {
      this.ajax($.extend({}, options, {
        contentType: 'application/sparql-query',
        data: queryText,
        error: options.failure || options.error
      }));
    };

    /**
     * Executes a SPARQL Update request.
     *
     * @param {String} queryText
     * @param {Object} options
     */
    this.update = function(queryText, options) {
      this.ajax($.extend({}, options, {
        contentType: 'application/sparql-update',
        data: queryText,
        error: options.failure || options.error
      }));
    };
  };

  /**
   * Constructs a SPARQL Graph Store Protocol client for jQuery.
   *
   * @param {Object} config
   *
   * @see http://www.w3.org/TR/sparql11-http-rdf-update/
   */
  var Store = function(endpointURL, config) {
    if (config === undefined) {
      config = {};
    }

    /**
     * @param {Object} options
     */
    this.ajax = function(options) {
      $.ajax(endpointURL, $.extend({}, {
        type: 'POST',
        dataType: 'json',
        accepts: {json: 'application/json'},
        beforeSend: function(xhr) {
          xhr.setRequestHeader('Accept', 'application/json');
        }
      }, config, options));
    };
  };

  /**
   * Constructs a SPARQL query builder.
   *
   * @param {Object} config
   *
   * @see http://www.w3.org/TR/sparql11-query/
   */
  var Query = function(config) {
    if (config === undefined) {
      config = {};
    }

    this.form = config.form || "SELECT";
    this.variables = [];

    /**
     * Creates a boolean `ASK` query.
     *
     * @param {Object} options
     * @return `this`
     * @see http://www.w3.org/TR/sparql11-query/#ask
     */
    this.ask = function(options) {
      this.form = "ASK";
      return this;
    };

    /**
     * Creates a tuple `SELECT` query.
     *
     * @param {Array} variables
     * @param {Object} options
     * @return `this`
     * @see http://www.w3.org/TR/sparql11-query/#select
     */
    this.select = function(variables, options) {
      this.form = "SELECT";
      this.variables = variables;
      return this;
    };

    /**
     * Creates a graph `DESCRIBE` query.
     *
     * @param {Array} variables
     * @param {Object} options
     * @return `this`
     * @see http://www.w3.org/TR/sparql11-query/#describe
     */
    this.describe = function(variables, options) {
      this.form = "DESCRIBE";
      this.variables = variables;
      return this;
    };

    /**
     * Creates a graph `CONSTRUCT` query.
     *
     * @param {Array} patterns
     * @param {Object} options
     * @return `this`
     * @see http://www.w3.org/TR/sparql11-query/#construct
     */
    this.construct = function(patterns, options) {
      this.form = "CONSTRUCT";
      this.patterns = patterns;
      return this;
    };

    /**
     * @param {String} uri
     * @return `this`
     * @see http://www.w3.org/TR/sparql11-query/#specifyingDataset
     */
    this.from = function(uri) {
      this.from = uri;
      return this;
    };

    /**
     * @return `this`
     * @see http://www.w3.org/TR/sparql11-query/#modDuplicates
     */
    this.distinct = function() {
      this.modifier = "DISTINCT";
      return this;
    };

    /**
     * @return `this`
     * @see http://www.w3.org/TR/sparql11-query/#modDuplicates
     */
    this.reduced = function() {
      this.modifier = "REDUCED";
      return this;
    };
  };

  return {
    Client: Client,
    Store: Store,
    Query: Query
  };
})(jQuery);

if (typeof exports !== 'undefined') {
  module.exports = SPARQL;
}
else {
  window.SPARQL = SPARQL;
}
<commit_msg>Implemented the SPARQL.Store#insert() method.<commit_after>/**
 * Dydra.com Software Development Kit (SDK) for JavaScript.
 *
 * This is free and unencumbered software released into the public domain.
 *
 * @see http://docs.dydra.com/sdk/javascript
 */

var SPARQL = (function($) {
  /**
   * Constructs a SPARQL 1.1 Query/Update client for jQuery.
   *
   * @param {Object} config
   *
   * @see http://www.w3.org/TR/sparql11-protocol/
   * @see http://www.w3.org/TR/sparql11-results-json/
   */
  var Client = function(endpointURL, config) {
    if (config === undefined) {
      config = {};
    }

    /**
     * @param {Object} options
     */
    this.ajax = function(options) {
      $.ajax(endpointURL, $.extend({}, {
        type: 'POST',
        dataType: 'json',
        accepts: {json: 'application/sparql-results+json'},
        beforeSend: function(xhr) {
          xhr.setRequestHeader('Accept', 'application/sparql-results+json');
        }
      }, config, options));
    };

    /**
     * Executes a SPARQL Query request.
     *
     * @param {String} queryText
     * @param {Object} options
     */
    this.query = function(queryText, options) {
      this.ajax($.extend({}, options, {
        contentType: 'application/sparql-query',
        data: queryText,
        error: options.failure || options.error
      }));
    };

    /**
     * Executes a SPARQL Update request.
     *
     * @param {String} queryText
     * @param {Object} options
     */
    this.update = function(queryText, options) {
      this.ajax($.extend({}, options, {
        contentType: 'application/sparql-update',
        data: queryText,
        error: options.failure || options.error
      }));
    };
  };

  /**
   * Constructs a SPARQL Graph Store Protocol client for jQuery.
   *
   * @param {Object} config
   *
   * @see http://www.w3.org/TR/sparql11-http-rdf-update/
   */
  var Store = function(endpointURL, config) {
    if (config === undefined) {
      config = {};
    }

    /**
     * @param {Object} options
     */
    this.ajax = function(options) {
      $.ajax(endpointURL, $.extend({}, {
        type: 'POST',
        dataType: 'json',
        accepts: {json: 'application/json'},
        beforeSend: function(xhr) {
          xhr.setRequestHeader('Accept', 'application/json');
        }
      }, config, options));
    };

    /**
     * @param {Object} data in RDF/JSON format
     * @param {Object} options
     */
    this.insert = function(data, options) {
      this.ajax($.extend({}, options, {
        contentType: 'application/json',
        data: JSON.stringify(data),
        error: options.failure || options.error
      }));
    };
  };

  /**
   * Constructs a SPARQL query builder.
   *
   * @param {Object} config
   *
   * @see http://www.w3.org/TR/sparql11-query/
   */
  var Query = function(config) {
    if (config === undefined) {
      config = {};
    }

    this.form = config.form || "SELECT";
    this.variables = [];

    /**
     * Creates a boolean `ASK` query.
     *
     * @param {Object} options
     * @return `this`
     * @see http://www.w3.org/TR/sparql11-query/#ask
     */
    this.ask = function(options) {
      this.form = "ASK";
      return this;
    };

    /**
     * Creates a tuple `SELECT` query.
     *
     * @param {Array} variables
     * @param {Object} options
     * @return `this`
     * @see http://www.w3.org/TR/sparql11-query/#select
     */
    this.select = function(variables, options) {
      this.form = "SELECT";
      this.variables = variables;
      return this;
    };

    /**
     * Creates a graph `DESCRIBE` query.
     *
     * @param {Array} variables
     * @param {Object} options
     * @return `this`
     * @see http://www.w3.org/TR/sparql11-query/#describe
     */
    this.describe = function(variables, options) {
      this.form = "DESCRIBE";
      this.variables = variables;
      return this;
    };

    /**
     * Creates a graph `CONSTRUCT` query.
     *
     * @param {Array} patterns
     * @param {Object} options
     * @return `this`
     * @see http://www.w3.org/TR/sparql11-query/#construct
     */
    this.construct = function(patterns, options) {
      this.form = "CONSTRUCT";
      this.patterns = patterns;
      return this;
    };

    /**
     * @param {String} uri
     * @return `this`
     * @see http://www.w3.org/TR/sparql11-query/#specifyingDataset
     */
    this.from = function(uri) {
      this.from = uri;
      return this;
    };

    /**
     * @return `this`
     * @see http://www.w3.org/TR/sparql11-query/#modDuplicates
     */
    this.distinct = function() {
      this.modifier = "DISTINCT";
      return this;
    };

    /**
     * @return `this`
     * @see http://www.w3.org/TR/sparql11-query/#modDuplicates
     */
    this.reduced = function() {
      this.modifier = "REDUCED";
      return this;
    };
  };

  return {
    Client: Client,
    Store: Store,
    Query: Query
  };
})(jQuery);

if (typeof exports !== 'undefined') {
  module.exports = SPARQL;
}
else {
  window.SPARQL = SPARQL;
}
<|endoftext|>


<commit_before>
//chrome.exe --disable-web-security
var currentAsatWarnings = [];
var currentCatWarnings = [];
var currentMessageWarnings = [];
var currentTooltip;
var curLine = -1;

var sourceCode = (function() {

function highlight(lineNumber, type){
		   var childs = $( '.CodeMirror-code').children()
		   var child = childs[lineNumber];
		  switch(type) {
		case 'CheckStyle':
			$(child).css('background','#386938');
			$(child).find('.CodeMirror-gutter-wrapper').find('.CodeMirror-linenumber').css('background','#386938');
			break;
		case 'PMD':
			$(child).css('background','#88120a');
			$(child).find('.CodeMirror-gutter-wrapper').find('.CodeMirror-linenumber').css('background','#88120a');
			break;
		case 'FindBugs':
			$(child).css('background','#043e70');
			$(child).find('.CodeMirror-gutter-wrapper').find('.CodeMirror-linenumber').css('background','#043e70');
			break;
		  }
}

function setLabels(lineNumber, type, cat, message) {
	$( '.CodeMirror-code').children().each(function () {

		if ($(this).find('.CodeMirror-gutter-wrapper').find('.CodeMirror-linenumber').text() == lineNumber ) {

			if( curLine == $(this).find('.CodeMirror-gutter-wrapper').find('.CodeMirror-linenumber').text()) {
				currentAsatWarnings.push(type);
				currentCatWarnings.push(cat);
				currentMessageWarnings.push(message);

			} else {

				/*
				 * Creates a tooltip that will be shown on hover over a node
				 */
				var tooltip = d3.select("#chart-and-code")
				    .append("div")
					.attr("class","d3-tip2")
					.style("width", 300)
				    .style("position", "absolute")
				    .style("z-index", "10")
				    .style("visibility", "hidden");

				var textInTooltip = "Line " + lineNumber + ": ";
				for(var i = 0; i < currentAsatWarnings.length; i++) {
					textInTooltip += "
-" + currentAsatWarnings[i] + "
-" + currentCatWarnings[i] + "
-" + currentMessageWarnings[i] + "
"
				}

				$(this).mouseenter(function(){
					tooltip.html(textInTooltip);
	                tooltip.style("visibility", "visible");
				});
				$(this).mousemove(function(){
					tooltip.style("top", (event.pageY - 130) + "px").style("left", (event.pageX - 280) + "px");
				});
				$(this).mouseleave(function(){
					tooltip.style("visibility", "hidden");
				});

				curLine = $(this).find('.CodeMirror-gutter-wrapper').find('.CodeMirror-linenumber').text();
				currentAsatWarnings = [type];
				currentCatWarnings = [cat];
				currentMessageWarnings = [message];
			}
		}
	});
}
function setBackButton(fileName){
		$('#back-div').html(fileName);
		$('#back-div').click(function() {
		  sourceCode.hide();
		});
	}
function displayCode(pathID){
	for ( var i = 0; i < codeExport.length; i++){

		if (codeExport[i].path == pathID){
			var value = codeExport[i].code.substring(1, codeExport[i].code.length -2);
		}

	}
	var editor = CodeMirror(document.body.getElementsByTagName("article")[0], {
	    value: value,
	    lineNumbers: true,
	    mode: "javascript",
	    keyMap: "sublime",
		readOnly: "nocursor",
	    autoCloseBrackets: true,
	    matchBrackets: true,
	    showCursorWhenSelecting: true,
	    theme: "monokai",
	    tabSize: 2
	});
	}

return {

	readAllCode: function(){
	},
	show: function(d){
		var chartDiv = document.getElementById("code-div");
			chartDiv.style.visibility = 'visible';
			document.getElementById("chart").style.visibility = 'hidden';

			displayCode(d.filePath);
			var warnings = getWarningLines(d.fileName);
			for( var i =0 ; i < warnings.warningList.length; i ++ ){
				highlight(warnings.warningList[i].line, warnings.warningList[i].type);
			}
			setBackButton(d.fileName);
			var warnings = getWarningLines(d.fileName);
			for( var i =0 ; i < warnings.warningList.length; i ++ ){
				setLabels(warnings.warningList[i].line, warnings.warningList[i].type, warnings.warningList[i].cat, warnings.warningList[i].message);
			}
	},
	hide: function(){
		var myNode = document.getElementById("code-article");
		while (myNode.firstChild) {
			myNode.removeChild(myNode.firstChild);
		}
		var chartDiv = document.getElementById("code-div");
			chartDiv.style.visibility = 'hidden';
			document.getElementById("chart").style.visibility = 'visible';
	}
}

}());<commit_msg>Fixed source code highlight and hover<commit_after>
//chrome.exe --disable-web-security
var currentAsatWarnings = [];
var currentCatWarnings = [];
var currentMessageWarnings = [];
var currentTooltip;
var curLine = 1;

var sourceCode = (function() {

function highlight(lineNumber, type){
		   var childs = $( '.CodeMirror-code').children()
		   var child = childs[lineNumber - 1];
		  switch(type) {
		case 'CheckStyle':
			$(child).css('background','#386938');
			$(child).find('.CodeMirror-gutter-wrapper').find('.CodeMirror-linenumber').css('background','#386938');
			break;
		case 'PMD':
			$(child).css('background','#88120a');
			$(child).find('.CodeMirror-gutter-wrapper').find('.CodeMirror-linenumber').css('background','#88120a');
			break;
		case 'FindBugs':
			$(child).css('background','#043e70');
			$(child).find('.CodeMirror-gutter-wrapper').find('.CodeMirror-linenumber').css('background','#043e70');
			break;
		  }
}

function setLabels(lineNumber, type, cat, message) {
	var childs = $( '.CodeMirror-code').children()
	var child = childs[lineNumber - 1];
	var child2 = childs[curLine - 1]
		if( curLine == $(child).find('.CodeMirror-gutter-wrapper').find('.CodeMirror-linenumber').text()) {
			currentAsatWarnings.push(type);
			currentCatWarnings.push(cat);
			currentMessageWarnings.push(message);

		} else {

			/*
			 * Creates a tooltip that will be shown on hover over a node
			 */
			var tooltip = d3.select("#chart-and-code")
			    .append("div")
				.attr("class","d3-tip2")
				.style("width", 300)
			    .style("position", "absolute")
			    .style("z-index", "10")
			    .style("visibility", "hidden");

			var textInTooltip = "Line " + curLine + ": ";
			for(var i = 0; i < currentAsatWarnings.length; i++) {
				textInTooltip += "
-" + currentAsatWarnings[i] + "
-" + currentCatWarnings[i] + "
-" + currentMessageWarnings[i] + "
"
			}

			$(child2).mouseenter(function(){
				tooltip.html(textInTooltip);
                tooltip.style("visibility", "visible");
			});
			$(child2).mousemove(function(){
				tooltip.style("top", (event.pageY - 130) + "px").style("left", (event.pageX - 280) + "px");
			});
			$(child2).mouseleave(function(){
				tooltip.style("visibility", "hidden");
			});

			curLine = $(child).find('.CodeMirror-gutter-wrapper').find('.CodeMirror-linenumber').text();
			currentAsatWarnings = [type];
			currentCatWarnings = [cat];
			currentMessageWarnings = [message];
		}
}
function setBackButton(fileName){
		$('#back-div').html(fileName);
		$('#back-div').click(function() {
		  sourceCode.hide();
		});
	}
function displayCode(pathID){
	for ( var i = 0; i < codeExport.length; i++){

		if (codeExport[i].path == pathID){
			var value = codeExport[i].code.substring(1, codeExport[i].code.length -2);
		}

	}
	var editor = CodeMirror(document.body.getElementsByTagName("article")[0], {
	    value: value,
	    lineNumbers: true,
	    mode: "javascript",
	    keyMap: "sublime",
		readOnly: "nocursor",
	    autoCloseBrackets: true,
	    matchBrackets: true,
	    showCursorWhenSelecting: true,
	    theme: "monokai",
	    tabSize: 2
	});
	}

return {

	readAllCode: function(){
	},
	show: function(d){
		var chartDiv = document.getElementById("code-div");
			chartDiv.style.visibility = 'visible';
			document.getElementById("chart").style.visibility = 'hidden';

			displayCode(d.filePath);
			var warnings = getWarningLines(d.fileName);
			for( var i =0 ; i < warnings.warningList.length; i ++ ){
				highlight(warnings.warningList[i].line, warnings.warningList[i].type);
			}
			setBackButton(d.fileName);
			var warnings = getWarningLines(d.fileName);
			for( var i =0 ; i < warnings.warningList.length; i ++ ){
				setLabels(warnings.warningList[i].line, warnings.warningList[i].type, warnings.warningList[i].cat, warnings.warningList[i].message);
			}
	},
	hide: function(){
		var myNode = document.getElementById("code-article");
		while (myNode.firstChild) {
			myNode.removeChild(myNode.firstChild);
		}
		var chartDiv = document.getElementById("code-div");
			chartDiv.style.visibility = 'hidden';
			document.getElementById("chart").style.visibility = 'visible';
	}
}

}());<|endoftext|>


<commit_before>
var ref = require('ref')
var assert = require('assert')
var debug = require('debug')('ffi:ffi')

var ffi = module.exports

ffi.Bindings = require('bindings')('ffi_bindings.node')

/**
 * The extension to use on libraries.
 * i.e.  libm  ->  libm.so   on linux
 */

Object.defineProperty(ffi, 'LIB_EXT', {
    configurable: true
  , enumerable: true
  , writable: false
  , value: {
        'linux':  '.so'
      , 'linux2': '.so'
      , 'sunos':  '.so'
      , 'solaris':'.so'
      , 'darwin': '.dylib'
      , 'mac':    '.dylib'
      , 'win32':  '.dll'
    }[process.platform]
})

/**
 * Set the `ffi_type` property on the built-in types.
 */

Object.keys(ffi.Bindings.FFI_TYPES).forEach(function (name) {
  if (name === 'pointer') return
  var ffi_type = ffi.Bindings.FFI_TYPES[name]
  ref.types[name].ffi_type = ffi_type
})

// make `size_t` use the "ffi_type_pointer"
ref.types.size_t = ref.cloneType(ref.types.size_t)
ref.types.size_t.ffi_type = ffi.Bindings.FFI_TYPES.pointer

/**
 * Utf8Strings are a kind of weird thing. We say it's a sizeof(char *),
 * so that means that we have to return a Buffer that is pointer sized, and points
 * to a some utf8 string data, so we have to create a 2nd "in-between" buffer.
 *
 * Really, people should just use a proper `char *` type.
 * This is only here for legacy purposes...
 */

ffi.Utf8String = {
    size: ref.sizeof.pointer
  , ffi_type: ffi.Bindings.FFI_TYPES.pointer
  , indirection: 1
  , get: function get (buf, offset) {
      var _buf = buf.readPointer(offset)
      return _buf.readCString(0)
    }
  , set: function set (buf, offset, val) {
      var _buf = ref.allocCString(val)
      return buf.writePointer(_buf, offset)
    }
}

// libffi is weird when it comes to long data types (defaults to 64-bit),
// so we emulate here, since some platforms have 32-bit longs and some
// platforms have 64-bit longs.
switch (ref.sizeof.long) {
  case 4:
    ref.types.ulong.ffi_type = ffi.Bindings.FFI_TYPES.uint32
    ref.types.long.ffi_type = ffi.Bindings.FFI_TYPES.int32
    break;
  case 8:
    ref.types.ulong.ffi_type = ffi.Bindings.FFI_TYPES.uint64
    ref.types.long.ffi_type = ffi.Bindings.FFI_TYPES.int64
    break;
  default:
    throw new Error('unsupported "long" size: ' + ref.sizeof.long)
}

/**
 * Coerces a String or "Type" instance into a real Type instance
 */

ffi.coerceType = function coerceType (type) {
  var rtn = type
  if (typeof type === 'string') {
    if (type === 'pointer') {
      // legacy "pointer" being used :(
      console.warn('type of "pointer" should not be used...')
      console.trace()
      rtn = ref.refType(ref.types.void) // void *
    } else if (type === 'string') {
      rtn = ffi.Utf8String // char *
    } else {
      // allow string names to be passed in
      rtn = ref.types[type]
    }
  }
  assert(rtn && 'size' in rtn && 'indirection' in rtn
      , 'could not determine "type" from: ' + type)
  return rtn
}

/**
 * Returns a `ffi_type *` Buffer appropriate for the given "type".
 */

ffi.ffiType = function ffiType (type) {
  debug('ffiType()', type)
  type = ffi.coerceType(type)
  assert(type.indirection >= 1, 'invalid "type" given: ' + type)
  var rtn
  if (type.indirection === 1) {
    rtn = type.ffi_type
  } else {
    rtn = ffi.Bindings.FFI_TYPES.pointer
  }
  assert(rtn, 'Could not determine the `ffi_type` instance for type: ' + type)
  return rtn
}

// Direct exports from the bindings
ffi.CallbackInfo = ffi.Bindings.CallbackInfo

// Include our other modules
ffi.CIF = require('./cif')
ffi.ForeignFunction = require('./foreign_function')
ffi.DynamicLibrary = require('./dynamic_library')
ffi.Library = require('./library')
ffi.Callback = require('./callback')
ffi.Struct = require('./struct')
ffi.errno = require('./errno')

/**
 * Define the `FFI_TYPE` struct for use in JS.
 * This struct type is used internally to define custom struct rtn/arg types.
 */

/*ffi.FFI_TYPE = ffi.Struct(
    [ ref.types.size_t, 'size']
  , [ ref.types.ushort, 'alignment']
  , [ ref.types.ushort, 'type']
  , [ 'pointer' ,'elements']
)*/
<commit_msg>remove the "CallbackInfo" export<commit_after>
var ref = require('ref')
var assert = require('assert')
var debug = require('debug')('ffi:ffi')

var ffi = module.exports

ffi.Bindings = require('bindings')('ffi_bindings.node')

/**
 * The extension to use on libraries.
 * i.e.  libm  ->  libm.so   on linux
 */

Object.defineProperty(ffi, 'LIB_EXT', {
    configurable: true
  , enumerable: true
  , writable: false
  , value: {
        'linux':  '.so'
      , 'linux2': '.so'
      , 'sunos':  '.so'
      , 'solaris':'.so'
      , 'darwin': '.dylib'
      , 'mac':    '.dylib'
      , 'win32':  '.dll'
    }[process.platform]
})

/**
 * Set the `ffi_type` property on the built-in types.
 */

Object.keys(ffi.Bindings.FFI_TYPES).forEach(function (name) {
  if (name === 'pointer') return
  var ffi_type = ffi.Bindings.FFI_TYPES[name]
  ref.types[name].ffi_type = ffi_type
})

// make `size_t` use the "ffi_type_pointer"
ref.types.size_t = ref.cloneType(ref.types.size_t)
ref.types.size_t.ffi_type = ffi.Bindings.FFI_TYPES.pointer

/**
 * Utf8Strings are a kind of weird thing. We say it's a sizeof(char *),
 * so that means that we have to return a Buffer that is pointer sized, and points
 * to a some utf8 string data, so we have to create a 2nd "in-between" buffer.
 *
 * Really, people should just use a proper `char *` type.
 * This is only here for legacy purposes...
 */

ffi.Utf8String = {
    size: ref.sizeof.pointer
  , ffi_type: ffi.Bindings.FFI_TYPES.pointer
  , indirection: 1
  , get: function get (buf, offset) {
      var _buf = buf.readPointer(offset)
      return _buf.readCString(0)
    }
  , set: function set (buf, offset, val) {
      var _buf = ref.allocCString(val)
      return buf.writePointer(_buf, offset)
    }
}

// libffi is weird when it comes to long data types (defaults to 64-bit),
// so we emulate here, since some platforms have 32-bit longs and some
// platforms have 64-bit longs.
switch (ref.sizeof.long) {
  case 4:
    ref.types.ulong.ffi_type = ffi.Bindings.FFI_TYPES.uint32
    ref.types.long.ffi_type = ffi.Bindings.FFI_TYPES.int32
    break;
  case 8:
    ref.types.ulong.ffi_type = ffi.Bindings.FFI_TYPES.uint64
    ref.types.long.ffi_type = ffi.Bindings.FFI_TYPES.int64
    break;
  default:
    throw new Error('unsupported "long" size: ' + ref.sizeof.long)
}

/**
 * Coerces a String or "Type" instance into a real Type instance
 */

ffi.coerceType = function coerceType (type) {
  var rtn = type
  if (typeof type === 'string') {
    if (type === 'pointer') {
      // legacy "pointer" being used :(
      console.warn('type of "pointer" should not be used...')
      console.trace()
      rtn = ref.refType(ref.types.void) // void *
    } else if (type === 'string') {
      rtn = ffi.Utf8String // char *
    } else {
      // allow string names to be passed in
      rtn = ref.types[type]
    }
  }
  assert(rtn && 'size' in rtn && 'indirection' in rtn
      , 'could not determine "type" from: ' + type)
  return rtn
}

/**
 * Returns a `ffi_type *` Buffer appropriate for the given "type".
 */

ffi.ffiType = function ffiType (type) {
  debug('ffiType()', type)
  type = ffi.coerceType(type)
  assert(type.indirection >= 1, 'invalid "type" given: ' + type)
  var rtn
  if (type.indirection === 1) {
    rtn = type.ffi_type
  } else {
    rtn = ffi.Bindings.FFI_TYPES.pointer
  }
  assert(rtn, 'Could not determine the `ffi_type` instance for type: ' + type)
  return rtn
}

// Include our other modules
ffi.CIF = require('./cif')
ffi.ForeignFunction = require('./foreign_function')
ffi.DynamicLibrary = require('./dynamic_library')
ffi.Library = require('./library')
ffi.Callback = require('./callback')
ffi.Struct = require('./struct')
ffi.errno = require('./errno')

/**
 * Define the `FFI_TYPE` struct for use in JS.
 * This struct type is used internally to define custom struct rtn/arg types.
 */

/*ffi.FFI_TYPE = ffi.Struct(
    [ ref.types.size_t, 'size']
  , [ ref.types.ushort, 'alignment']
  , [ ref.types.ushort, 'type']
  , [ 'pointer' ,'elements']
)*/
<|endoftext|>


<commit_before>/*global module */

var helpers = {
  insertIntoString: function (str, offset, newstr) {
    var part1 = str.substr(0, offset);
    var part2 = str.substr(offset);

    return part1 + newstr + part2;
  },

  rmFromString: function (str, pos) {
    return str.slice(0, pos) + "".substr(0, 1) + "".slice(1) + str.slice(pos + 1);
  }
};

var Fix = {
  addSemicolon: function (str, chr) {
    return helpers.insertIntoString(str, chr, ";");
  },
  addSpace: function (str, chr) {
    return helpers.insertIntoString(str, chr, " ");
  },
  alreadyDefined: function (str) {
    return str.replace("var ", "");
  },
  anonFuncInvocation: function (str) {
    return str.replace("})()", "}())");
  },
  arrayLiteral: function (str) {
    return str.replace("new Array()", "[]");
  },
  dotNotation: function (str) {
    var rx = {
      sqb: /\[["'][a-zA-Z_$][0-9a-zA-Z_$]*["']\]/,
      dot: /[a-zA-Z_$][0-9a-zA-Z_$]*/
    };

    var sqbNotation, dotNotation;

    if (rx.sqb.test(str)) {
      sqbNotation = rx.sqb.exec(str);
      dotNotation = rx.dot.exec(sqbNotation[0]);

      str = str.replace(sqbNotation[0], "." + dotNotation[0]);
    }

    return str;
  },
  indent: function (str, indent, config) {
    if (config.auto_indent === true) {
      str = new Array(indent).join(" ") + str.trim();
    }

    return str;
  },
  invokeConstructor: function (str, chr) {
    var rx = /new ([a-zA-Z_$][0-9a-zA-Z_$]*)/;

    if (rx.test(code)) {
      result = rx.exec(code).shift();
      str = str.replace(rx, result + "()");
    }

    return str;
  },
  leadingDecimal: function (str) {
    var rx = /([\D])(\.[0-9]*)/;

    var result;

    if (rx.test(str)) {
      result = rx.exec(str);
      str = str.replace(rx, result[1] + "0" + result[2]);
    }

    return str;
  },
  lineBrk: function (str, o, n) {
    str = this.lines[o] + " " + this.lines[n].trim();
    this.lines[n] = "";
    return str;
  },
  mixedSpacesNTabs: function (str, config) {
    if (config.auto_indent === true) {
      str = str.replace("\t", new Array(config.indent).join(" "));
    }

    return str;
  },
  objectLiteral: function (str) {
    return str.replace("new Object()", "{}");
  },
  useIsNaN: function (str) {
    var rx = /([a-zA-Z_$][0-9a-zA-Z_$]*)( )*(=|!)(=|==)( )*NaN/;
    var exec;

    if (rx.test(str)) {
      exec = rx.exec(str);

      if (exec) {
        str = str.replace(exec[0], (exec[3] === "!" ? "!": "") + "isNaN(" + exec[1] + ")");
      }
    }

    return str;
  },
  rmChar: function (str, chr) {
    return helpers.rmFromString(str, chr);
  },
  rmDebugger: function () {
    return "";
  },
  rmUndefined: function (str) {
    return str.replace(/( )*=( )*undefined/, "");
  },
  trailingDecimal: function (str) {
    var rx = /([0-9]*)\.(\D)/;
    var result;

    if (rx.test(str)) {
      result = rx.exec(str);
      str = str.replace(rx, result[1] + result[2]);
    }

    return str;
  }
};

module.exports = Fix;
<commit_msg>bug fix<commit_after>/*global module */

var helpers = {
  insertIntoString: function (str, offset, newstr) {
    var part1 = str.substr(0, offset);
    var part2 = str.substr(offset);

    return part1 + newstr + part2;
  },

  rmFromString: function (str, pos) {
    return str.slice(0, pos) + "".substr(0, 1) + "".slice(1) + str.slice(pos + 1);
  }
};

var Fix = {
  addSemicolon: function (str, chr) {
    return helpers.insertIntoString(str, chr, ";");
  },
  addSpace: function (str, chr) {
    return helpers.insertIntoString(str, chr, " ");
  },
  alreadyDefined: function (str) {
    // TODO use chr positioning
    return str.replace(/var /g, "");
  },
  anonFuncInvocation: function (str) {
    return str.replace("})()", "}())");
  },
  arrayLiteral: function (str) {
    return str.replace("new Array()", "[]");
  },
  dotNotation: function (str) {
    var rx = {
      sqb: /\[["'][a-zA-Z_$][0-9a-zA-Z_$]*["']\]/,
      dot: /[a-zA-Z_$][0-9a-zA-Z_$]*/
    };

    var sqbNotation, dotNotation;

    if (rx.sqb.test(str)) {
      sqbNotation = rx.sqb.exec(str);
      dotNotation = rx.dot.exec(sqbNotation[0]);

      str = str.replace(sqbNotation[0], "." + dotNotation[0]);
    }

    return str;
  },
  indent: function (str, indent, config) {
    if (config.auto_indent === true) {
      str = new Array(indent).join(" ") + str.trim();
    }

    return str;
  },
  invokeConstructor: function (str, chr) {
    var rx = /new ([a-zA-Z_$][0-9a-zA-Z_$]*)/;

    if (rx.test(str)) {
      result = rx.exec(str).shift();
      str = str.replace(rx, result + "()");
    }

    return str;
  },
  leadingDecimal: function (str) {
    var rx = /([\D])(\.[0-9]*)/;

    var result;

    if (rx.test(str)) {
      result = rx.exec(str);
      str = str.replace(rx, result[1] + "0" + result[2]);
    }

    return str;
  },
  lineBrk: function (str, o, n) {
    str = this.lines[o] + " " + this.lines[n].trim();
    this.lines[n] = "";
    return str;
  },
  mixedSpacesNTabs: function (str, config) {
    if (config.auto_indent === true) {
      str = str.replace("\t", new Array(config.indent).join(" "));
    }

    return str;
  },
  objectLiteral: function (str) {
    return str.replace("new Object()", "{}");
  },
  useIsNaN: function (str) {
    var rx = /([a-zA-Z_$][0-9a-zA-Z_$]*)( )*(=|!)(=|==)( )*NaN/;
    var exec;

    if (rx.test(str)) {
      exec = rx.exec(str);

      if (exec) {
        str = str.replace(exec[0], (exec[3] === "!" ? "!": "") + "isNaN(" + exec[1] + ")");
      }
    }

    return str;
  },
  rmChar: function (str, chr) {
    return helpers.rmFromString(str, chr);
  },
  rmDebugger: function () {
    return "";
  },
  rmUndefined: function (str) {
    return str.replace(/( )*=( )*undefined/, "");
  },
  trailingDecimal: function (str) {
    var rx = /([0-9]*)\.(\D)/;
    var result;

    if (rx.test(str)) {
      result = rx.exec(str);
      str = str.replace(rx, result[1] + result[2]);
    }

    return str;
  }
};

module.exports = Fix;
<|endoftext|>


<commit_before>'use strict';

var co = require('co');
var path = require('path');
var util = require('util');
var debug = require('debug');
var mkdirp = require('mkdirp');
var chokidar = require('chokidar');
var Cat = require('concat-with-sourcemaps');
var assign = require('object-assign');
var flatten = require('flatten');
var expand = require('globby');
var arrify = require('arrify');
// promisify `fs` methods
var thenify = require('thenify-all');
var fs = thenify(require('fs'), {}, ['readFile', 'writeFile']);
// locals
var utils = require('./utils');
var Emitter = require('./emitter');
// shorthands
var sep = path.sep;
var _ = debug('fly');
var clear = utils.defer(require('rimraf'));

function Fly(options) {
	var self = this;

	if (!(self instanceof Fly)) {
		throw new TypeError('Fly cannot be invoked without \'new\'');
	}

	options = assign({
		file: '.',
		host: {},
		plugins: []
	}, options || {});

	// shorter aliases
	var host = options.host;
	var file = options.file;
	var plugins = options.plugins;

	// ~ `super()`
	Emitter.call(self);

	// attach files & funcs into the curr instance
	assign(self, {
		file: file,
		plugins: plugins,
		root: path.dirname(file),
		alert: utils.alert,
		error: utils.error,
		defer: utils.defer,
		log: utils.log,
		host: (typeof host === 'function') ? assign(host, {default: host}) : host,
		debug: _,
		_: {
			filters: []
		},
		tasks: Object.keys(host).reduce(function (_, key) {
			return assign(_, {[key]: host[key].bind(self)});
		}, {})
	});

	plugins.forEach(function (el) {
		if (!el.plugin) {
			throw new Error('Did you forget to `npm i -D ' + el.name + '`?');
		}
		// if (plugin.default) plugin = plugin.default
		el.plugin.call(self, debug(el.name.replace('-', ':')), _('load %o', el.name));
	});

	_('chdir %o', self.root);
	process.chdir(self.root);
}

// `Fly extends Emitter`...
util.inherits(Fly, Emitter);
module.exports = Fly;

/**
 * Compose a new, yeildable sequence.
 * Resets instance's glob, filters, and writer.
 *
 * @param  {String|Array} globs The glob selection
 * @return 											The current Fly instance.
 */
Fly.prototype.source = function (globs) {
	globs = arrify(globs);

	assign(this, {
		_: {
			filters: [],
			globs: flatten(globs)
		}
	});

	this._.cat = undefined;
	_('source %o', this._.globs);
	return this;
};

/**
 * Add filter / transform function.
 * Create a closure bound to the current Fly instance.
 *
 * @param {String|Function} name 		The name of filter || the callback
 * @param {Function} 				cb 			the function: (cb, options) => {}
*/
Fly.prototype.filter = function (name, cb) {
	var type = typeof name;

	if (type === 'function') {
		this.filter({cb: name});
	} else if (type === 'object') {
		this._.filters.push(name);
	} else {
		if (typeof this[name] === 'function') {
			throw new RangeError(name + ' method is already defined!');
		}

		this[name] = function (options) {
			var rest = [].slice.call(arguments);
			rest.shift(); // remove `options` argument

			debug('fly')(`${name} %o, %o`, options, rest);

			return this.filter({
				cb: cb,
				options: options,
				rest: rest
			});
		};
	}

	return this;
};

/**
 * Watch IO events within glob selections & run tasks
 * @param  {String} globs   The glob patterns to observe
 * @param  {String} tasks   The list of tasks to run on file changes
 * @param  {Object} options The options for `Fly.proto.start`
 * @return {void}
 */
Fly.prototype.watch = function (globs, tasks, options) {
	_('watch %o', globs);

	var self = this;
	return self.emit('fly+watch').start(tasks, options).then(function () {
		chokidar.watch(flatten(globs), {ignoreInitial: true}).on('all', function () {
			self.start(tasks, options);
		});
	});
};

/**
 * Unwrap/Expand source globs as single files, then run fn.
 * @param  {Function} onResolved  The callback to run on 'success'.
 * @param  {Function} onRejected  The callback to run on 'error'.
 * @return {Promise}
 */
Fly.prototype.unwrap = function (onResolved, onRejected) {
	var self = this;

	var p = new Promise(function (resolve, reject) {
		// unwrap all globs
		return Promise.all(self._.globs.map(function (glob) {
			return expand(glob);
		})).then(function (files) {
			// then attach 'files' array to instance
			return resolve.call(self, files.reduce(function (arr, item) {
				return arr.concat(item);
			}));
		}).catch(reject);
	});

	return p.then(onResolved).catch(onRejected);
};

/**
 * Execute a single task.
 * @param  {String} task     The name of the task
 * @param  {Mixed}  value    The initial value to pass into `task`
 * @param  {Object} instance The Fly instance `task` should be bound to
 * @return {Mixed}           The task's resulting value.
 */
Fly.prototype.exec = function * (task, value, instance) {
	instance = instance || this;

	_('run %o', task);

	try {
		var start = getTime();

		this.emit('task_start', {
			task: task
		});

		value = (yield this.host[task].call(instance, value)) || value;

		this.emit('task_complete', {
			task: task,
			duration: getTime() - start
		});
	} catch (e) {
		this.emit('task_error', {
			task: task,
			error: e
		});
	}

	return value;
};

/**
 * Run a task sequence of 1 or more.
 * Each task's return value is piped into the next task of sequence.
 *
 * @param  {Array}  tasks   The list of tasks to start
 * @param  {Object} options The options to begin.
 * @return {Promise}
 */
Fly.prototype.start = function (tasks, options) {
	tasks = arrify(tasks || 'default');
	options = assign({
		parallel: false,
		value: null
	}, options || {});

	_('start %o in ' + (options.parallel ? 'parallel' : 'sequence'), tasks);

	var self = this;
	var value = options.value;

	var fn = options.parallel ?
		function (task) {
			self.exec(task, value, Object.create(self));
		} : function * (task) {
			value = yield self.exec(task, value);
		};

	return co.call(self, function * (tasks) {
		yield tasks.map(fn);
		return value;
	}, [].concat(tasks).filter(function (task) {
		return Object.keys(self.host).indexOf(task) !== -1 || !self.emit('task_not_found', {task: task});
	}));
};

/**
 * Deferred `rimraf` wrapper
 * @param  {String|Array} paths The paths to delete
 * @return {void}
 */
Fly.prototype.clear = function (paths) {
	paths = arrify(paths);

	_('clear %o', paths);

	return flatten(paths).map(function (p) {
		clear(p);
	});
};

/**
 * Concatenate active `files` to single file.
 * @param  {String} filename  The single output file
 * @return {Fly}      				The current Fly instance.
 */
Fly.prototype.concat = function (filename) {
	this._.cat = new Cat(false, filename, '\n');
	this._.cat.base = filename;
	return this;
};

/**
 * Resolve a yieldable sequence.
 * Reduces `source` with filters and invokes writer.
 *
 * @param  {Array}  dirs    The target/destination directories
 * @param  {Object} options Target options. Depth refers to path retention
 * @return {Promise}
 */
Fly.prototype.target = function (dirs, options) {
	dirs = arrify(dirs);
	options = assign({}, {depth: -1}, options || {});

	var self = this;
	var _cat = self._.concat;
	var _filters = self._.filters;

	// @todo: utilize `unwrap` here?
	return co.call(self, function * () {
		// run thru all globs
		yield self._.globs.map(function * (glob) {
			var files = yield expand(glob);

			// run thru all files of each glob
			yield files.map(function * (file) {
				// get data & stats
				var f = path.parse(file);
				var data = yield fs.readFile(file);

				// pass files' data thru attached filters
				_filters.map(function * (filter) {
					// run the filter's closure fn w/data
					var res = yield Promise.resolve(filter.cb.apply(
						self, [data, assign({filename: f.base}, filter.options)].concat(filter.rest)
					));

					// once done, retrieve the final `data` & `ext` of output
					data = res.code || res.js || res.css || res.data || res || data;
					f.ext = res.ext || res.extension || f.ext;
				});

				if (_cat) {
					_cat.add(f.base, data);
				} else {
					// get shared dir between glob & current filepath
					var dir = path.join.apply(null, f.dir.split(sep).filter(function (filepath) {
						return glob.split(sep).indexOf(filepath) === -1;
					}));

					// complete the promise & write the output
					yield resolve(dirs, {
						data: data,
						base: path.join(dir, f.name + f.ext),
						depth: options.depth
					});
				}
			});
		});

		if (_cat) {
			yield resolve(dirs, {
				data: _cat.content,
				base: _cat.base,
				write: fs.writeFile,
				depth: options.depth
			});
		}
	});
};

/**
 * Write utility to help concat and target.
 * @param {String}   dirs  					parent directory
 * @param {String}   options.base  	directory/file
 * @param {Mixed}    options.data
 * @param {Integer}  options.depth 	number of parent directories to keep
 * @param {Function} options.write 	promisified writer function
 */
function * resolve(dirs, options) {
	var opts = options || {};
	var writer = opts.hasOwnProperty('writer') ? opts.writer : fs.writeFile;

	if (opts.depth > -1) {
		opts.base = dirpaths(opts.base, opts.depth);
	}

	yield flatten(dirs).map(function * (dir) {
		var file = path.join(dir, opts.base);
		mkdirp.sync(path.dirname(file));
		yield writer(file, opts.data);
	});
}

/**
 * Shorten a directory string to # of parent dirs
 * @param  {String}  	full    The original full path
 * @param  {Integer}  depth   The number of levels to retain
 * @return {String}
 */
function dirpaths(full, depth) {
	var arr = full.split(sep);
	var len = arr.length;

	if (depth === 0) {
		return arr[len - 1];
	} else if (depth >= len) {
		return full;
	}

	return arr.slice(len - 1 - depth).join(sep);
}

/**
 * Get the current timestamp
 * @return {Integer}
 */
function getTime() {
	return (new Date()).getTime();
}
<commit_msg>updated fly for all tests, ready for 1.0<commit_after>'use strict';

var co = require('co');
var path = require('path');
var util = require('util');
var debug = require('debug');
var mkdirp = require('mkdirp');
var chokidar = require('chokidar');
var Cat = require('concat-with-sourcemaps');
var assign = require('object-assign');
var flatten = require('flatten');
var expand = require('globby');
var arrify = require('arrify');
// promisify `fs` methods
var thenify = require('thenify-all');
var fs = thenify(require('fs'), {}, ['writeFile']);
// locals
var utils = require('./utils');
var Emitter = require('./emitter');
// shorthands
var sep = path.sep;
var _ = debug('fly');
var clear = utils.defer(require('rimraf'));

function Fly(options) {
	var self = this;

	if (!(self instanceof Fly)) {
		throw new TypeError('Fly cannot be invoked without \'new\'');
	}

	options = assign({
		file: '.',
		host: {},
		plugins: []
	}, options || {});

	// shorter aliases
	var host = options.host;
	var file = options.file;
	var plugins = options.plugins;

	// ~ `super()`
	Emitter.call(self);

	// attach files & funcs into the curr instance
	assign(self, {
		file: file,
		plugins: plugins,
		root: path.dirname(file),
		alert: utils.alert,
		error: utils.error,
		defer: utils.defer,
		log: utils.log,
		host: (typeof host === 'function') ? assign(host, {default: host}) : host,
		debug: _,
		_: {
			filters: []
		},
		tasks: Object.keys(host).reduce(function (_, key) {
			return assign(_, {[key]: host[key].bind(self)});
		}, {})
	});

	plugins.forEach(function (el) {
		if (!el.plugin) {
			throw new Error('Did you forget to `npm i -D ' + el.name + '`?');
		}
		// if (plugin.default) plugin = plugin.default
		el.plugin.call(self, debug(el.name.replace('-', ':')), _('load %o', el.name));
	});

	_('chdir %o', self.root);
	process.chdir(self.root);
}

// `Fly extends Emitter`...
util.inherits(Fly, Emitter);
module.exports = Fly;

/**
 * Compose a new, yeildable sequence.
 * Resets instance's glob, filters, and writer.
 *
 * @param  {String|Array} globs The glob selection
 * @return 											The current Fly instance.
 */
Fly.prototype.source = function (globs) {
	globs = arrify(globs);

	assign(this, {
		_: {
			filters: [],
			globs: flatten(globs)
		}
	});

	this._.cat = undefined;
	_('source %o', this._.globs);
	return this;
};

/**
 * Add filter / transform function.
 * Create a closure bound to the current Fly instance.
 *
 * @param {String|Function} name 		The name of filter || the callback
 * @param {Function} 				cb 			the function: (cb, options) => {}
*/
Fly.prototype.filter = function (name, cb) {
	var type = typeof name;

	if (type === 'function') {
		this.filter({cb: name});
	} else if (type === 'object') {
		this._.filters.push(name);
	} else {
		if (typeof this[name] === 'function') {
			throw new RangeError(name + ' method is already defined!');
		}

		this[name] = function (options) {
			var rest = [].slice.call(arguments);
			rest.shift(); // remove `options` argument

			debug('fly')(`${name} %o, %o`, options, rest);

			return this.filter({
				cb: cb,
				options: options,
				rest: rest
			});
		};
	}

	return this;
};

/**
 * Watch IO events within glob selections & run tasks
 * @param  {String} globs   The glob patterns to observe
 * @param  {String} tasks   The list of tasks to run on file changes
 * @param  {Object} options The options for `Fly.proto.start`
 * @return {void}
 */
Fly.prototype.watch = function (globs, tasks, options) {
	_('watch %o', globs);

	var self = this;
	return self.emit('fly+watch').start(tasks, options).then(function () {
		chokidar.watch(flatten(globs), {ignoreInitial: true}).on('all', function () {
			self.start(tasks, options);
		});
	});
};

/**
 * Unwrap/Expand source globs as single files, then run fn.
 * @param  {Function} onResolved  The callback to run on 'success'.
 * @param  {Function} onRejected  The callback to run on 'error'.
 * @return {Promise}
 */
Fly.prototype.unwrap = function (onResolved, onRejected) {
	var self = this;

	var p = new Promise(function (resolve, reject) {
		// unwrap all globs
		return Promise.all(self._.globs.map(function (glob) {
			return expand(glob);
		})).then(function (files) {
			// then attach 'files' array to instance
			return resolve.call(self, files.reduce(function (arr, item) {
				return arr.concat(item);
			}));
		}).catch(reject);
	});

	return p.then(onResolved).catch(onRejected);
};

/**
 * Execute a single task.
 * @param  {String} task     The name of the task
 * @param  {Mixed}  value    The initial value to pass into `task`
 * @param  {Object} instance The Fly instance `task` should be bound to
 * @return {Mixed}           The task's resulting value.
 */
Fly.prototype.exec = function * (task, value, instance) {
	instance = instance || this;

	_('run %o', task);

	try {
		var start = getTime();

		this.emit('task_start', {
			task: task
		});

		value = (yield this.host[task].call(instance, value)) || value;

		this.emit('task_complete', {
			task: task,
			duration: getTime() - start
		});
	} catch (e) {
		this.emit('task_error', {
			task: task,
			error: e
		});
	}

	return value;
};

/**
 * Run a task sequence of 1 or more.
 * Each task's return value is piped into the next task of sequence.
 *
 * @param  {Array}  tasks   The list of tasks to start
 * @param  {Object} options The options to begin.
 * @return {Promise}
 */
Fly.prototype.start = function (tasks, options) {
	tasks = arrify(tasks || 'default');
	options = assign({
		parallel: false,
		value: null
	}, options || {});

	_('start %o in ' + (options.parallel ? 'parallel' : 'sequence'), tasks);

	var self = this;
	var value = options.value;

	return co.call(self, function * (tasks) {
		if (options.parallel) {
			yield tasks.map(function (task) {
				self.exec(task, value, Object.create(self));
			});
		} else {
			for (var task of tasks) {
				value = yield self.exec(task, value);
			}
		}
		return value;
	}, [].concat(tasks).filter(function (task) {
		return Object.keys(self.host).indexOf(task) !== -1 || !self.emit('task_not_found', {task: task});
	}));
};

/**
 * Deferred `rimraf` wrapper
 * @param  {String|Array} paths The paths to delete
 * @return {void}
 */
Fly.prototype.clear = function (paths) {
	paths = arrify(paths);

	_('clear %o', paths);

	return flatten(paths).map(function (p) {
		clear(p);
	});
};

/**
 * Concatenate active `files` to single file.
 * @param  {String} filename  The single output file
 * @return {Fly}      				The current Fly instance.
 */
Fly.prototype.concat = function (filename) {
	this._.cat = new Cat(false, filename, '\n');
	this._.cat.base = filename;
	return this;
};

/**
 * Resolve a yieldable sequence.
 * Reduces `source` with filters and invokes writer.
 *
 * @param  {Array}  dirs    The target/destination directories
 * @param  {Object} options Target options. Depth refers to path retention
 * @return {Promise}
 */
Fly.prototype.target = function (dirs, options) {
	dirs = arrify(dirs);
	options = assign({}, {depth: -1}, options || {});

	var self = this;
	var _cat = self._.concat;
	var _filters = self._.filters;

	// @todo: utilize `unwrap` here?
	return co.call(self, function * () {
		// run thru all globs
		yield self._.globs.map(function * (glob) {
			var files = yield expand(glob);

			// run thru all files of each glob
			yield files.map(function * (file) {
				// get data & stats
				var f = path.parse(file);
				var data = fs.readFileSync(file);
				// var data = yield fs.readFile(file);

				// pass files' data thru attached filters
				yield _filters.map(function * (filter) {
					// run the filter's closure fn w/data
					var res = yield Promise.resolve(filter.cb.apply(
						self, [data, assign({filename: f.base}, filter.options)].concat(filter.rest)
					));

					// once done, retrieve the final `data` & `ext` of output
					data = res.code || res.js || res.css || res.data || res || data;
					f.ext = res.ext || res.extension || f.ext;
				});

				if (_cat) {
					_cat.add(f.base, data);
				} else {
					// get shared dir between glob & current filepath
					var dir = path.join.apply(null, f.dir.split(sep).filter(function (filepath) {
						return glob.split(sep).indexOf(filepath) === -1;
					}));

					// complete the promise & write the output
					yield resolve(dirs, {
						data: data,
						base: path.join(dir, f.name + f.ext),
						depth: options.depth
					});
				}
			});
		});

		if (_cat) {
			yield resolve(dirs, {
				data: _cat.content,
				base: _cat.base,
				write: fs.writeFile,
				depth: options.depth
			});
		}
	});
};

/**
 * Write utility to help concat and target.
 * @param {String}   dirs  					parent directory
 * @param {String}   options.base  	directory/file
 * @param {Mixed}    options.data
 * @param {Integer}  options.depth 	number of parent directories to keep
 * @param {Function} options.write 	promisified writer function
 */
function * resolve(dirs, options) {
	var opts = options || {};
	var writer = opts.hasOwnProperty('writer') ? opts.writer : fs.writeFile;

	if (opts.depth > -1) {
		opts.base = dirpaths(opts.base, opts.depth);
	}

	yield flatten(dirs).map(function * (dir) {
		var file = path.join(dir, opts.base);
		mkdirp.sync(path.dirname(file));
		yield writer(file, opts.data);
	});
}

/**
 * Shorten a directory string to # of parent dirs
 * @param  {String}  	full    The original full path
 * @param  {Integer}  depth   The number of levels to retain
 * @return {String}
 */
function dirpaths(full, depth) {
	var arr = full.split(sep);
	var len = arr.length;

	if (depth === 0) {
		return arr[len - 1];
	} else if (depth >= len) {
		return full;
	}

	return arr.slice(len - 1 - depth).join(sep);
}

/**
 * Get the current timestamp
 * @return {Integer}
 */
function getTime() {
	return (new Date()).getTime();
}
<|endoftext|>


<commit_before>'use strict';

// Get current license(s) & file status etc
var _ = require('lodash');
var colors = require('colors/safe');
var fs = require('fs');
var path = require('path');
var jsonFile = require('json-file-plus');
var packageJsonPath = path.join(process.cwd(), 'package.json');
var assert = require('assert');
var ini = require('node-ini');

var globalDefaults = require('../config.json');
var spdxLicensesPath = __dirname + '/../node_modules/spdx-license-list/licenses/';

// read node package.json
var packageJson;
console.log('exists file:', packageJsonPath);
if (fs.existsSync(packageJsonPath)) {
	try {
		packageJson = fs.readFileSync(packageJsonPath, 'utf8');
		packageJson = JSON.parse(packageJson);

	} catch(err) {
		console.log(colors.magenta('failed to open package.json'));
		console.log(err);
	}
}

function getCurrentAuthor() {
	if (packageJson && packageJson.author) {
		if (typeof packageJson.author === 'string') {
			var parseAuthors = require('parse-authors');
			var authors = parseAuthors(packageJson.author);
			if (authors.length) {
				return authors[0];
			}

		} else {
			return packageJson.author;
		}
	}

	if (globalDefaults.author) {
		return {
			name: globalDefaults.author,
			email: globalDefaults.email
		};
	}

	var author = {
		name: '',
		email: ''
	};

	var gitPath = path.join(process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE, '.gitconfig');
	console.log('gity path:', gitPath);
	if (fs.existsSync(gitPath)) {
		var git = ini.parseSync(gitPath);
		if (git.user) {
			author.name = git.user.name;
			author.email = git.user.email;
		}
	}

	return author;
}

function getCurrentProject() {
	if (packageJson) {
		return {
			years: new Date().getFullYear(),
			name: packageJson.name,
			desc: packageJson.description
		};
	}

	var name = path.normalize(__dirname + '/../').split(path.sep);
	assert(name[name.length -1] === '');
	name = name[name.length - 2];
	return {
		years: new Date().getFullYear(),
		name: name,
		desc: ''
	};
}

function getCurrentLicense() {
	if (packageJson && packageJson.license) {
		return packageJson.license;
	}

	if (globalDefaults.license) {
		return globalDefaults.license;
	}

	return '';
}

var currentLicense = getCurrentLicense();
var currentAuthor = getCurrentAuthor();
var currentProject = getCurrentProject();

// Combine license jsons
var licenseModelBuilder = require('./licenseModelBuilder.js');
var licenses = licenseModelBuilder({
	spdx: require('spdx-license-list'),
	common: require('../licenses.json')
});

var licenseFileConfig = {
	names: ['LICENSE', 'COPYING'],
	exts: ['', '.md', '.txt'],
	defaultFileName: globalDefaults.defaultFileName || 'LICENSE'
};

function getLicenseFileName() {
	var existing;
	_.forEach(licenseFileConfig.names, function(name) {
		_.forEach(licenseFileConfig.exts, function(ext) {
			var fileName = path.join(process.cwd(), name + ext);
			if (fs.existsSync(fileName)) {
				existing = name + ext;
			}
		});
	});
	return existing || licenseFileConfig.defaultFileName;
}

var config;
var fileName = getLicenseFileName();
var filePath = path.join(process.cwd(), fileName);

module.exports = {
	getConfig: function(spdxlicenses) {
		config = {
			global: globalDefaults,
			fileName: fileName,
			fileExists: function() {
				return fs.existsSync(filePath);
			},
			license: this.getDetails(currentLicense),
			licenses: licenses,
			hasNpmPackage: packageJson !== undefined,
			packageJson: packageJson,
			defaults: {
				license: currentLicense,
				author: currentAuthor,
				project: currentProject
			},
			update: function(opts) {
				if (opts.force) {
					this.defaults.license = globalDefaults.license;
					opts.license = globalDefaults.license;

					if (opts._[0] === 'set' && fileName !== licenseFileConfig.defaultFileName) {
						// Zie uglyness
						fs.unlinkSync(filePath);

						fileName = licenseFileConfig.defaultFileName;
						config.fileName = fileName;
						filePath = path.join(process.cwd(), fileName);
					}

				} else if (opts.license) {
					this.defaults.license = opts.license;
				}

				if (opts.author) {
					this.defaults.author.name = opts.author;
				}
				if (opts.year) {
					this.defaults.project.years = opts.year;
				}
				if (opts.email) {
					this.defaults.author.email = opts.email;
				}
				if (opts.project) {
					this.defaults.project.name = opts.project;
				}
				if (opts.desc) {
					this.defaults.project.desc = opts.desc;
				}
			}
		};

		return config;
	},
	getMatches: function(needle, returnAll) {
		needle = needle.toLowerCase();

		var i;
		var list = [];
		var descMatches = [];

		var keys = Object.keys(licenses);
		for (i = 0; i < keys.length; i++) {
			if (needle === keys[i].toLowerCase()) {
				if (returnAll) {
					list.push(keys[i]);
					continue;
				} else {
					return [keys[i]];
				}
			}

			var lic = licenses[keys[i]];
			if (lic.alias) {
				var aliasRegex = new RegExp(lic.alias, 'i');
				if (needle.match(aliasRegex)) {
					if (returnAll) {
						list.push(keys[i]);
						continue;
					} else {
						return [keys[i]];
					}
				}
			}

			if (keys[i].toLowerCase().indexOf(needle) !== -1) {
				list.push(keys[i]);
			} else {
				assert(lic.name !== undefined, "lic.name undefined. (means a licenses.json key that does not exist in the spdx json)", lic);
				if (lic.name.toLowerCase().indexOf(needle) !== -1) {
					descMatches.push(keys[i]);
				}
			}
		}

		if (returnAll || list.length === 0) {
			return descMatches.concat(list);
		}
		return list;
	},
	getDetails: function(licenseKey, getFullText) {
		getFullText = getFullText || false;

		var lic = _.merge({
			key: licenseKey,
			valid: licenses[licenseKey] !== undefined
		}, licenses[licenseKey]);

		if (getFullText && lic.valid) {
			try {
				lic.full = fs.readFileSync(spdxLicensesPath + licenseKey +'.txt').toString();
				if (lic.header) {
					lic.header = new RegExp(lic.header).exec(lic.full)[0];
					if (lic.headerClean) {
						lic.header = lic.header.replace(new RegExp(lic.headerClean, 'mg'), '');
					}
					lic.header = replacePlaceHolders(lic.match, lic.replace, lic.header);
				} else {
					lic.full = replacePlaceHolders(lic.match, lic.replace, lic.full);
				}

			} catch(err) {
				console.log('Error reading ' + licenseKey + ' license content ', err);
			}
		}

		return lic;
	},
	updatePackageJson: function(licenseKey) {
		jsonFile(packageJsonPath, function (err, file) {
			file.set({
				license: licenseKey
			});

			file.save(function(err) {

			}).then(function () {
				console.log('Node package.json updated!');
			}).catch(function (err) {
				console.log('Whoops! Error updating package.json', err);
			});
		});
	},
	readLicenseFile: function() {
		return fs.readFileSync(filePath).toString();
	},
	writeLicense: function(license) {
		var doWrite = false;
		if (!config.fileExists()) {
			doWrite = true;

		} else {
			var currentContent = this.readLicenseFile();
			if (currentContent !== license.full) {
				doWrite = true;
				console.log('Overwriting existing ' + fileName + ' file');
			} else {
				console.log(fileName + ' file was up to date');
			}
		}

		if (doWrite) {
			try {
				fs.writeFileSync(filePath, license.full, 'utf8');
				console.log(fileName + ' written');
			} catch(err) {
				console.log('Error writing license file', err);
			}
		}
	},
	setGlobal: function(opts) {
		if (opts.author) {
			globalDefaults.author = opts.author;
		}
		if (opts.email) {
			globalDefaults.email = opts.email;
		}
		if (opts.license) {
			var matched = this.getMatches(opts.license);
			if (matched.length === 1) {
				globalDefaults.license = matched[0];
			} else {
				console.log('Couldn\'t set license: ' + opts.license);
			}
		}
		if (opts.defaultFileName) {
			globalDefaults.defaultFileName = opts.defaultFileName;
		}
		try {
			var globalConfigPath = path.normalize(__dirname + '/../config.json');
			fs.writeFileSync(globalConfigPath, JSON.stringify(globalDefaults, null, 2), 'utf8');
			console.log('Global settings updated!');
		} catch(err) {
			console.log(err);
		}
	}
};

function replacePlaceHolders(matcher, replacer, licenseText) {
	if (matcher) {
		var named = require('named-regexp').named;
		var re = named(new RegExp(matcher, 'g'));

		return re.replace(licenseText, function(matched) {
			return replacer
				.replace('$years', currentProject.years)
				.replace('$author', currentAuthor.name)
				.replace('$email', currentAuthor.email)
				.replace('$url', currentProject.url)
				.replace('$project', currentProject.name + ' - ' + currentProject.desc);
		});
	}
	return licenseText;
}<commit_msg>extra logging/error handling when writing to global configuration<commit_after>'use strict';

// Get current license(s) & file status etc
var _ = require('lodash');
var colors = require('colors/safe');
var fs = require('fs');
var path = require('path');
var jsonFile = require('json-file-plus');
var packageJsonPath = path.join(process.cwd(), 'package.json');
var assert = require('assert');
var ini = require('node-ini');

var globalDefaults = require('../config.json');
var spdxLicensesPath = __dirname + '/../node_modules/spdx-license-list/licenses/';

// read node package.json
var packageJson;
console.log('exists file:', packageJsonPath);
if (fs.existsSync(packageJsonPath)) {
	try {
		packageJson = fs.readFileSync(packageJsonPath, 'utf8');
		packageJson = JSON.parse(packageJson);

	} catch(err) {
		console.log(colors.magenta('failed to open package.json'));
		console.log(err);
	}
}

function getCurrentAuthor() {
	if (packageJson && packageJson.author) {
		if (typeof packageJson.author === 'string') {
			var parseAuthors = require('parse-authors');
			var authors = parseAuthors(packageJson.author);
			if (authors.length) {
				return authors[0];
			}

		} else {
			return packageJson.author;
		}
	}

	if (globalDefaults.author) {
		return {
			name: globalDefaults.author,
			email: globalDefaults.email
		};
	}

	var author = {
		name: '',
		email: ''
	};

	var gitPath = path.join(process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE, '.gitconfig');
	console.log('gity path:', gitPath);
	if (fs.existsSync(gitPath)) {
		var git = ini.parseSync(gitPath);
		if (git.user) {
			author.name = git.user.name;
			author.email = git.user.email;
		}
	}

	return author;
}

function getCurrentProject() {
	if (packageJson) {
		return {
			years: new Date().getFullYear(),
			name: packageJson.name,
			desc: packageJson.description
		};
	}

	var name = path.normalize(__dirname + '/../').split(path.sep);
	assert(name[name.length -1] === '');
	name = name[name.length - 2];
	return {
		years: new Date().getFullYear(),
		name: name,
		desc: ''
	};
}

function getCurrentLicense() {
	if (packageJson && packageJson.license) {
		return packageJson.license;
	}

	if (globalDefaults.license) {
		return globalDefaults.license;
	}

	return '';
}

var currentLicense = getCurrentLicense();
var currentAuthor = getCurrentAuthor();
var currentProject = getCurrentProject();

// Combine license jsons
var licenseModelBuilder = require('./licenseModelBuilder.js');
var licenses = licenseModelBuilder({
	spdx: require('spdx-license-list'),
	common: require('../licenses.json')
});

var licenseFileConfig = {
	names: ['LICENSE', 'COPYING'],
	exts: ['', '.md', '.txt'],
	defaultFileName: globalDefaults.defaultFileName || 'LICENSE'
};

function getLicenseFileName() {
	var existing;
	_.forEach(licenseFileConfig.names, function(name) {
		_.forEach(licenseFileConfig.exts, function(ext) {
			var fileName = path.join(process.cwd(), name + ext);
			if (fs.existsSync(fileName)) {
				existing = name + ext;
			}
		});
	});
	return existing || licenseFileConfig.defaultFileName;
}

var config;
var fileName = getLicenseFileName();
var filePath = path.join(process.cwd(), fileName);

module.exports = {
	getConfig: function(spdxlicenses) {
		config = {
			global: globalDefaults,
			fileName: fileName,
			fileExists: function() {
				return fs.existsSync(filePath);
			},
			license: this.getDetails(currentLicense),
			licenses: licenses,
			hasNpmPackage: packageJson !== undefined,
			packageJson: packageJson,
			defaults: {
				license: currentLicense,
				author: currentAuthor,
				project: currentProject
			},
			update: function(opts) {
				if (opts.force) {
					this.defaults.license = globalDefaults.license;
					opts.license = globalDefaults.license;

					if (opts._[0] === 'set' && fileName !== licenseFileConfig.defaultFileName) {
						// Zie uglyness
						fs.unlinkSync(filePath);

						fileName = licenseFileConfig.defaultFileName;
						config.fileName = fileName;
						filePath = path.join(process.cwd(), fileName);
					}

				} else if (opts.license) {
					this.defaults.license = opts.license;
				}

				if (opts.author) {
					this.defaults.author.name = opts.author;
				}
				if (opts.year) {
					this.defaults.project.years = opts.year;
				}
				if (opts.email) {
					this.defaults.author.email = opts.email;
				}
				if (opts.project) {
					this.defaults.project.name = opts.project;
				}
				if (opts.desc) {
					this.defaults.project.desc = opts.desc;
				}
			}
		};

		return config;
	},
	getMatches: function(needle, returnAll) {
		needle = needle.toLowerCase();

		var i;
		var list = [];
		var descMatches = [];

		var keys = Object.keys(licenses);
		for (i = 0; i < keys.length; i++) {
			if (needle === keys[i].toLowerCase()) {
				if (returnAll) {
					list.push(keys[i]);
					continue;
				} else {
					return [keys[i]];
				}
			}

			var lic = licenses[keys[i]];
			if (lic.alias) {
				var aliasRegex = new RegExp(lic.alias, 'i');
				if (needle.match(aliasRegex)) {
					if (returnAll) {
						list.push(keys[i]);
						continue;
					} else {
						return [keys[i]];
					}
				}
			}

			if (keys[i].toLowerCase().indexOf(needle) !== -1) {
				list.push(keys[i]);
			} else {
				assert(lic.name !== undefined, "lic.name undefined. (means a licenses.json key that does not exist in the spdx json)", lic);
				if (lic.name.toLowerCase().indexOf(needle) !== -1) {
					descMatches.push(keys[i]);
				}
			}
		}

		if (returnAll || list.length === 0) {
			return descMatches.concat(list);
		}
		return list;
	},
	getDetails: function(licenseKey, getFullText) {
		getFullText = getFullText || false;

		var lic = _.merge({
			key: licenseKey,
			valid: licenses[licenseKey] !== undefined
		}, licenses[licenseKey]);

		if (getFullText && lic.valid) {
			try {
				lic.full = fs.readFileSync(spdxLicensesPath + licenseKey +'.txt').toString();
				if (lic.header) {
					lic.header = new RegExp(lic.header).exec(lic.full)[0];
					if (lic.headerClean) {
						lic.header = lic.header.replace(new RegExp(lic.headerClean, 'mg'), '');
					}
					lic.header = replacePlaceHolders(lic.match, lic.replace, lic.header);
				} else {
					lic.full = replacePlaceHolders(lic.match, lic.replace, lic.full);
				}

			} catch(err) {
				console.log('Error reading ' + licenseKey + ' license content ', err);
			}
		}

		return lic;
	},
	updatePackageJson: function(licenseKey) {
		jsonFile(packageJsonPath, function (err, file) {
			file.set({
				license: licenseKey
			});

			file.save(function(err) {

			}).then(function () {
				console.log('Node package.json updated!');
			}).catch(function (err) {
				console.log('Whoops! Error updating package.json', err);
			});
		});
	},
	readLicenseFile: function() {
		return fs.readFileSync(filePath).toString();
	},
	writeLicense: function(license) {
		var doWrite = false;
		if (!config.fileExists()) {
			doWrite = true;

		} else {
			var currentContent = this.readLicenseFile();
			if (currentContent !== license.full) {
				doWrite = true;
				console.log('Overwriting existing ' + fileName + ' file');
			} else {
				console.log(fileName + ' file was up to date');
			}
		}

		if (doWrite) {
			try {
				fs.writeFileSync(filePath, license.full, 'utf8');
				console.log(fileName + ' written');
			} catch(err) {
				console.log('Error writing license file', err);
			}
		}
	},
	setGlobal: function(opts) {
		if (opts.author) {
			globalDefaults.author = opts.author;
		}
		if (opts.email) {
			globalDefaults.email = opts.email;
		}
		if (opts.license) {
			var matched = this.getMatches(opts.license);
			if (matched.length === 1) {
				globalDefaults.license = matched[0];
			} else {
				console.log('Couldn\'t set license: ' + opts.license);
			}
		}
		if (opts.defaultFileName) {
			globalDefaults.defaultFileName = opts.defaultFileName;
		}
		try {
			var globalConfigPath = path.normalize(__dirname + '/../config.json');
			fs.writeFileSync(globalConfigPath, JSON.stringify(globalDefaults, null, 2), 'utf8', function(err) {
				if (err) {
					console.log('ERR writing ' + globalConfigPath, err);
				} else {
					console.log('Global settings updated!');
				}
			});
		} catch(err) {
			console.log('ERR writing ' + globalConfigPath, err);
		}
	}
};

function replacePlaceHolders(matcher, replacer, licenseText) {
	if (matcher) {
		var named = require('named-regexp').named;
		var re = named(new RegExp(matcher, 'g'));

		return re.replace(licenseText, function(matched) {
			return replacer
				.replace('$years', currentProject.years)
				.replace('$author', currentAuthor.name)
				.replace('$email', currentAuthor.email)
				.replace('$url', currentProject.url)
				.replace('$project', currentProject.name + ' - ' + currentProject.desc);
		});
	}
	return licenseText;
}<|endoftext|>


<commit_before><commit_msg>Bug correction in manager<commit_after><|endoftext|>