<commit_before>(function() {
    'use strict';

    // Check we have sweet alert js included
    if (angular.isUndefined(window.swal)) {
        throw "Please make sure Sweet Alert 2 is included! https://github.com/limonte/sweetalert2";
    }

    angular.module('swangular', [])
        .provider('swangular', function ProvideSwangular(){

            return({
                setDefaults: setDefaults,
                $get: ['$compile', '$http', '$rootScope', '$q', '$controller', '$injector', '$templateCache', instantiateSwangular]
            });

            function setDefaults(options) {
                swal.setDefaults(options);
            }

            function instantiateSwangular($compile, $http, $rootScope, $q, $controller, $injector, $templateCache) {

                /*
                 *
                 * Sweet Alert functions
                 * The four functions below are just convenience methods
                 *
                 * ex. Swangular.alert("This is a warning message");
                 *
                 */
                function swal_alert(message, customOptions) {

                    var options = angular.extend({
                        title: "Alert",
                        text: message,
                        type: "warning",
                        showCancelButton: false
                    }, customOptions);

                    return swal(options);

                }

                function swal_info(message, customOptions) {

                    var options = angular.extend({
                        title: "Info",
                        text: message,
                        type: "info",
                        showCancelButton: false
                    }, customOptions);

                    return swal(options);

                }

                function swal_success(message, customOptions) {

                    var options = angular.extend({
                        title: "Success",
                        text: message,
                        type: "success",
                        showCancelButton: false
                    }, customOptions);

                    return swal(options);

                }

                function swal_confirm(message, customOptions) {

                    var options = angular.extend({
                        title: "Alert",
                        text: message,
                        type: "warning"
                    }, customOptions);

                    return swal(options);

                }

                /*
                 *
                 * HTML Sweet Alert function
                 * Use this for for passing html that will be compiled to Angular
                 * You can pass an HTML string directly via 'html' option, or you can pass a link to template via 'templateHtml' option.
                 *
                 *  ex. Swangular.html({title: "Please fill in!",scope: $scope,templateHtml: '/templates/template.html'})
                 *         .then(function() { console.log("Done"); })
                 *
                 */
                function swal_open(options){

                    var resolve = angular.extend({}, options.resolve);

                    angular.forEach(resolve, function (value, key) {
                        resolve[key] = angular.isString(value) ? $injector.get(value) : $injector.invoke(value, null, null, key);
                    });

                    return $q.all({
                        html: _getHtml(options),
                        locals: $q.all(resolve)
                    }).then(function(setup){

                        var scope = options.scope,
                            controller = options.controller,
                            controllerAsOption = options.controllerAs,
                            preConfirm = options.preConfirm;

                        delete options.html;
                        delete options.htmlTemplate;
                        delete options.resolve;
                        delete options.scope;
                        delete options.controller;
                        delete options.controllerAs;
                        delete options.preConfirm;

                        var locals = setup.locals;

                        options.html = setup.html;

                        scope = scope ? scope.$new() : $rootScope.$new();

                        function transform(func){
                            return function(){
                                return func().then(function (result){
                                    return {resolved: true, value: result};
                                },function(reason){
                                    return {resolved: false, value: reason};
                                });
                            };
                        }

                        function transformBack(result){
                            if (result.resolved) {
                                return result.value;
                            }
                            return Promise.reject(result.value);
                        }

                        if (controller){

                            var controllerAs;

                            if (controllerAsOption && angular.isString(controllerAsOption)) {
                                controllerAs = controllerAsOption;
                            }

                            var controllerInstance = $controller(controller, angular.extend(
                                locals,
                                {
                                    $scope: scope
                                }), false, controllerAs);

                            if (typeof preConfirm === 'string'){
                                options.preConfirm = function(){
                                    return scope.$apply(transform(controllerInstance[preConfirm])).then(transformBack);
                                };
                            }

                        }

                        if (typeof preConfirm === 'function'){
                            options.preConfirm = function(){
                                return scope.$apply(transform(preConfirm)).then(transformBack)
                            };
                        }

                        var prom = $q.when(swal(options));
                        var html = document.getElementsByClassName('swal2-modal')[0];

                        // If there is a form, trigger the button on press of enter button
                        var form = html.getElementsByTagName('form');
                        if(form[0]) {
                            form[0].onkeyup = function(event) {
                                event.stopPropagation();
                                if (event.keyCode === 13) {
                                    html.querySelector('.swal2-confirm').click();
                                }
                            };
                        }

                        $compile(html)(scope);

                        return prom;

                    });

                }

                function _getHtml(options){

                    if(options.htmlTemplate) {
                        return _getTemplate(options.htmlTemplate)
                    } else {
                        return options.html;
                    }

                }

                function _getTemplate(tmpl) {
                    return $http.get(tmpl, {cache: $templateCache}).then(function(res) {
                        return res.data || '';
                    });
                }

                /*
                 *
                 * Base Sweet Alert function
                 * Use this for for a direct mapping to sweetalert,
                 * by either passing an options object or by passing up to 3 string arguments
                 *
                 * ex. 1: Swangular.swal("Good job!", "You clicked the button!", "success")
                 *
                 * ex. 2: Swangular.swal({title: "Auto close alert!", text: "I will close in 2 seconds.", timer: 2000});
                 *
                 */
                function swal_base(arg1, arg2, arg3) {

                    // In case of options
                    if(arg1 !== null && typeof arg1 === 'object') {
                        return swal(arg1)
                    }

                    // In case of: title, text, type
                    else {
                        return swal(arg1, arg2, arg3);
                    }
                }

                /*
                 * SweetAlert2 Global Methods
                 */

                function close() {
                    $rootScope.$evalAsync(function(){
                        swal.close();
                    });
                }

                function disableButtons() {
                    $rootScope.$evalAsync(function(){
                        swal.disableButtons();
                    });
                }

                function enableButtons() {
                    $rootScope.$evalAsync(function(){
                        swal.enableButtons();
                    });
                }

                function disableConfirmButton() {
                    $rootScope.$evalAsync(function(){
                        swal.disableConfirmButton();
                    });
                }

                function enableConfirmButton() {
                    $rootScope.$evalAsync(function(){
                        swal.enableConfirmButton();
                    });
                }

                function clickConfirm() {
                    $rootScope.$evalAsync(function(){
                        swal.clickConfirm();
                    });
                }

                function clickCancel() {
                    $rootScope.$evalAsync(function(){
                        swal.showLoading();
                    });
                }

                function showLoading() {
                    $rootScope.$evalAsync(function(){
                        swal.clickCancel();
                    });
                }

                function hideLoading() {
                    $rootScope.$evalAsync(function(){
                        swal.hideLoading();
                    });
                }

                function setDefaults(options) {
                    $rootScope.$evalAsync(function(){
                        swal.setDefaults(options);
                    });
                }

                return {
                    alert: swal_alert,
                    confirm: swal_confirm,
                    info: swal_info,
                    success: swal_success,
                    open: swal_open,
                    swal: swal_base,
                    closeModal: close,
                    close: close,
                    disableButtons: disableButtons,
                    enableButtons: enableButtons,
                    disableConfirmButton: disableConfirmButton,
                    enableConfirmButton: enableConfirmButton,
                    clickConfirm: clickConfirm,
                    clickCancel: clickCancel,
                    showLoading: showLoading,
                    enableLoading: showLoading,
                    hideLoading: hideLoading,
                    disableLoading: hideLoading,
                    setDefaults: setDefaults
                }

            }

        });

})();
<commit_msg>Fix function naming<commit_after>(function() {
    'use strict';

    // Check we have sweet alert js included
    if (angular.isUndefined(window.swal)) {
        throw "Please make sure Sweet Alert 2 is included! https://github.com/limonte/sweetalert2";
    }

    angular.module('swangular', [])
        .provider('swangular', function ProvideSwangular(){

            return({
                setDefaults: setDefaults,
                $get: ['$compile', '$http', '$rootScope', '$q', '$controller', '$injector', '$templateCache', instantiateSwangular]
            });

            function setDefaults(options) {
                swal.setDefaults(options);
            }

            function instantiateSwangular($compile, $http, $rootScope, $q, $controller, $injector, $templateCache) {

                /*
                 *
                 * Sweet Alert functions
                 * The four functions below are just convenience methods
                 *
                 * ex. Swangular.alert("This is a warning message");
                 *
                 */
                function swal_alert(message, customOptions) {

                    var options = angular.extend({
                        title: "Alert",
                        text: message,
                        type: "warning",
                        showCancelButton: false
                    }, customOptions);

                    return swal(options);

                }

                function swal_info(message, customOptions) {

                    var options = angular.extend({
                        title: "Info",
                        text: message,
                        type: "info",
                        showCancelButton: false
                    }, customOptions);

                    return swal(options);

                }

                function swal_success(message, customOptions) {

                    var options = angular.extend({
                        title: "Success",
                        text: message,
                        type: "success",
                        showCancelButton: false
                    }, customOptions);

                    return swal(options);

                }

                function swal_confirm(message, customOptions) {

                    var options = angular.extend({
                        title: "Alert",
                        text: message,
                        type: "warning"
                    }, customOptions);

                    return swal(options);

                }

                /*
                 *
                 * HTML Sweet Alert function
                 * Use this for for passing html that will be compiled to Angular
                 * You can pass an HTML string directly via 'html' option, or you can pass a link to template via 'templateHtml' option.
                 *
                 *  ex. Swangular.html({title: "Please fill in!",scope: $scope,templateHtml: '/templates/template.html'})
                 *         .then(function() { console.log("Done"); })
                 *
                 */
                function swal_open(options){

                    var resolve = angular.extend({}, options.resolve);

                    angular.forEach(resolve, function (value, key) {
                        resolve[key] = angular.isString(value) ? $injector.get(value) : $injector.invoke(value, null, null, key);
                    });

                    return $q.all({
                        html: _getHtml(options),
                        locals: $q.all(resolve)
                    }).then(function(setup){

                        var scope = options.scope,
                            controller = options.controller,
                            controllerAsOption = options.controllerAs,
                            preConfirm = options.preConfirm;

                        delete options.html;
                        delete options.htmlTemplate;
                        delete options.resolve;
                        delete options.scope;
                        delete options.controller;
                        delete options.controllerAs;
                        delete options.preConfirm;

                        var locals = setup.locals;

                        options.html = setup.html;

                        scope = scope ? scope.$new() : $rootScope.$new();

                        function transform(func){
                            return function(){
                                return func().then(function (result){
                                    return {resolved: true, value: result};
                                },function(reason){
                                    return {resolved: false, value: reason};
                                });
                            };
                        }

                        function transformBack(result){
                            if (result.resolved) {
                                return result.value;
                            }
                            return Promise.reject(result.value);
                        }

                        if (controller){

                            var controllerAs;

                            if (controllerAsOption && angular.isString(controllerAsOption)) {
                                controllerAs = controllerAsOption;
                            }

                            var controllerInstance = $controller(controller, angular.extend(
                                locals,
                                {
                                    $scope: scope
                                }), false, controllerAs);

                            if (typeof preConfirm === 'string'){
                                options.preConfirm = function(){
                                    return scope.$apply(transform(controllerInstance[preConfirm])).then(transformBack);
                                };
                            }

                        }

                        if (typeof preConfirm === 'function'){
                            options.preConfirm = function(){
                                return scope.$apply(transform(preConfirm)).then(transformBack)
                            };
                        }

                        var prom = $q.when(swal(options));
                        var html = document.getElementsByClassName('swal2-modal')[0];

                        // If there is a form, trigger the button on press of enter button
                        var form = html.getElementsByTagName('form');
                        if(form[0]) {
                            form[0].onkeyup = function(event) {
                                event.stopPropagation();
                                if (event.keyCode === 13) {
                                    html.querySelector('.swal2-confirm').click();
                                }
                            };
                        }

                        $compile(html)(scope);

                        return prom;

                    });

                }

                function _getHtml(options){

                    if(options.htmlTemplate) {
                        return _getTemplate(options.htmlTemplate)
                    } else {
                        return options.html;
                    }

                }

                function _getTemplate(tmpl) {
                    return $http.get(tmpl, {cache: $templateCache}).then(function(res) {
                        return res.data || '';
                    });
                }

                /*
                 *
                 * Base Sweet Alert function
                 * Use this for for a direct mapping to sweetalert,
                 * by either passing an options object or by passing up to 3 string arguments
                 *
                 * ex. 1: Swangular.swal("Good job!", "You clicked the button!", "success")
                 *
                 * ex. 2: Swangular.swal({title: "Auto close alert!", text: "I will close in 2 seconds.", timer: 2000});
                 *
                 */
                function swal_base(arg1, arg2, arg3) {

                    // In case of options
                    if(arg1 !== null && typeof arg1 === 'object') {
                        return swal(arg1)
                    }

                    // In case of: title, text, type
                    else {
                        return swal(arg1, arg2, arg3);
                    }
                }

                /*
                 * SweetAlert2 Global Methods
                 */

                function close() {
                    $rootScope.$evalAsync(function(){
                        swal.close();
                    });
                }

                function disableButtons() {
                    $rootScope.$evalAsync(function(){
                        swal.disableButtons();
                    });
                }

                function enableButtons() {
                    $rootScope.$evalAsync(function(){
                        swal.enableButtons();
                    });
                }

                function disableConfirmButton() {
                    $rootScope.$evalAsync(function(){
                        swal.disableConfirmButton();
                    });
                }

                function enableConfirmButton() {
                    $rootScope.$evalAsync(function(){
                        swal.enableConfirmButton();
                    });
                }

                function clickConfirm() {
                    $rootScope.$evalAsync(function(){
                        swal.clickConfirm();
                    });
                }

                function showLoading() {
                    $rootScope.$evalAsync(function(){
                        swal.showLoading();
                    });
                }

                function clickCancel() {
                    $rootScope.$evalAsync(function(){
                        swal.clickCancel();
                    });
                }

                function hideLoading() {
                    $rootScope.$evalAsync(function(){
                        swal.hideLoading();
                    });
                }

                function setDefaults(options) {
                    $rootScope.$evalAsync(function(){
                        swal.setDefaults(options);
                    });
                }

                return {
                    alert: swal_alert,
                    confirm: swal_confirm,
                    info: swal_info,
                    success: swal_success,
                    open: swal_open,
                    swal: swal_base,
                    closeModal: close,
                    close: close,
                    disableButtons: disableButtons,
                    enableButtons: enableButtons,
                    disableConfirmButton: disableConfirmButton,
                    enableConfirmButton: enableConfirmButton,
                    clickConfirm: clickConfirm,
                    clickCancel: clickCancel,
                    showLoading: showLoading,
                    enableLoading: showLoading,
                    hideLoading: hideLoading,
                    disableLoading: hideLoading,
                    setDefaults: setDefaults
                }

            }

        });

})();
<|endoftext|>


<commit_before>#!/usr/bin/env node
import path from 'node:path'
import process from 'node:process'
import {
  authenticate,
  createRepo,
  addSecretToRepo,
} from '../../lib/github/index.js'
import {getConfig, commitChanges, pushChanges} from '../../lib/git/index.js'
import {writeTemplate} from '../../lib/template/index.js'
import {
  readme,
  license,
  gitignore,
  packagejson,
  npmignore,
  main,
  test,
  githubactions,
  dependabotAction,
  dependabot,
} from '../templates/index.js'
import {usev2, addPackages} from '../../lib/yarn/index.js'

async function run() {
  const repoName = process.argv[2]
  const githubToken = process.env.GITHUB_TOKEN
  const npmToken = process.env.NPM_TOKEN

  console.log('\n')

  if (!repoName || !githubToken || !npmToken) {
    console.log('Usage: GITHUB_TOKEN=? NPM_TOKEN=? yarn create user/repo')
    return
  }

  const [, packageName] = repoName.split('/')
  const branchName = (await getConfig('init.defaultBranch')) || 'master'

  console.log('Creating GitHub Repository')
  const githubApi = await authenticate(githubToken)
  await createRepo(githubApi, repoName)

  console.log('Adding NPM Token to GitHub Repository')
  await addSecretToRepo(githubApi, repoName, 'NPM_TOKEN', npmToken)

  console.log('Writing project files')
  const today = new Date()
  const authorName = await getConfig('user.name')
  const authorEmail = await getConfig('user.email')
  const projectDirectory = path.resolve(packageName)

  await writeTemplate(projectDirectory, readme({repoName}))
  await writeTemplate(projectDirectory, license({authorName, today}))
  await writeTemplate(projectDirectory, gitignore({}))
  await writeTemplate(
    projectDirectory,
    packagejson({repoName, authorName, authorEmail, branchName}),
  )
  await writeTemplate(projectDirectory, npmignore({}))
  await writeTemplate(projectDirectory, main({}))
  await writeTemplate(projectDirectory, test({}))
  await writeTemplate(projectDirectory, githubactions({branchName}))
  await writeTemplate(projectDirectory, dependabotAction({}))
  await writeTemplate(projectDirectory, dependabot({}))

  console.log('Installing npm Packages')
  await usev2(projectDirectory)
  await addPackages(projectDirectory, 'development', [
    'ava',
    'xo',
    'semantic-release',
  ])

  console.log('Committing Changes')
  await commitChanges(
    projectDirectory,
    `feat(${packageName}): Bootstrap project`,
  )

  console.log('Pushing Changes')
  await pushChanges(projectDirectory, repoName, branchName, githubToken)
}

run()
<commit_msg>fix(create-npm): Fix bad import statement<commit_after>#!/usr/bin/env node
import path from 'node:path'
import process from 'node:process'
import {
  authenticate,
  createRepo,
  addSecretToRepo,
} from '../../lib/github/index.js'
import {getConfig, commitChanges, pushChanges} from '../../lib/git/index.js'
import {writeTemplate} from '../../lib/template/index.js'
import {
  readme,
  license,
  gitignore,
  packagejson,
  npmignore,
  main,
  test,
  ciAction,
  dependabotAction,
  dependabot,
} from '../templates/index.js'
import {usev2, addPackages} from '../../lib/yarn/index.js'

async function run() {
  const repoName = process.argv[2]
  const githubToken = process.env.GITHUB_TOKEN
  const npmToken = process.env.NPM_TOKEN

  console.log('\n')

  if (!repoName || !githubToken || !npmToken) {
    console.log('Usage: GITHUB_TOKEN=? NPM_TOKEN=? yarn create user/repo')
    return
  }

  const [, packageName] = repoName.split('/')
  const branchName = (await getConfig('init.defaultBranch')) || 'master'

  console.log('Creating GitHub Repository')
  const githubApi = await authenticate(githubToken)
  await createRepo(githubApi, repoName)

  console.log('Adding NPM Token to GitHub Repository')
  await addSecretToRepo(githubApi, repoName, 'NPM_TOKEN', npmToken)

  console.log('Writing project files')
  const today = new Date()
  const authorName = await getConfig('user.name')
  const authorEmail = await getConfig('user.email')
  const projectDirectory = path.resolve(packageName)

  await writeTemplate(projectDirectory, readme({repoName}))
  await writeTemplate(projectDirectory, license({authorName, today}))
  await writeTemplate(projectDirectory, gitignore({}))
  await writeTemplate(
    projectDirectory,
    packagejson({repoName, authorName, authorEmail, branchName}),
  )
  await writeTemplate(projectDirectory, npmignore({}))
  await writeTemplate(projectDirectory, main({}))
  await writeTemplate(projectDirectory, test({}))
  await writeTemplate(projectDirectory, ciAction({branchName}))
  await writeTemplate(projectDirectory, dependabotAction({}))
  await writeTemplate(projectDirectory, dependabot({}))

  console.log('Installing npm Packages')
  await usev2(projectDirectory)
  await addPackages(projectDirectory, 'development', [
    'ava',
    'xo',
    'semantic-release',
  ])

  console.log('Committing Changes')
  await commitChanges(
    projectDirectory,
    `feat(${packageName}): Bootstrap project`,
  )

  console.log('Pushing Changes')
  await pushChanges(projectDirectory, repoName, branchName, githubToken)
}

run()
<|endoftext|>


<commit_before>import Em from 'ember';
var get = Em.get;
var computed = Em.computed;

var DEFAULT_OFFSET = 0;

var ArrayOffset = Em.ArrayProxy.extend({
	content: computed({
		get: function () {
			return Em.A();
		}
	}),

	offset: computed({
		get: function () {
			return DEFAULT_OFFSET;
		},
		set: function (name, offset, old) {
			offset = Number(offset); // ensure offset is number
			offset = Math.max(offset, 0); // do not allow negative offset
			if (old === undefined) {
				// being set for first time, no need to update
				return offset;
			}
			var diff = offset - old;
			if (diff === 0) {
				// no need to continue if no difference
				return offset;
			}
			var arranged = this.get('arrangedContent');
			// offset added, remove items
			if (diff > 0) {
				var arrangedLength = get(arranged, 'length');
				var removeCount = Math.min(diff, arrangedLength);
				arranged.replace(0, removeCount);
			}
			// offset removed, add items
			else {
				var content = this.get('content');
				var toAdd = content.slice(offset, old);
				arranged.replace(0, 0, toAdd);
			}
			return offset;
		}
	}),

	arrangedContent: computed('content', {
		get: function () {
			var content = this.get('content');
			var offset = this.get('offset');
			var slice = content.slice(offset);
			return Em.A(slice);
		}
	}),

	// process items removed
	contentArrayWillChange: function (arr, idx, removedCount/*, addedCount*/) {
		var arrangedContent = this.get('arrangedContent');
		var arrangedContentLength = this.get('arrangedContent.length');
		var offset = this.get('offset');
		var start = Math.max(idx - offset, 0);
		var end = Math.min(arrangedContentLength - start, removedCount);
		if (start < arrangedContentLength) {
			arrangedContent.replace(start, end);
		}
	},

	// process items added
	contentArrayDidChange: function (arr, idx, removedCount, addedCount) {
		var offset = this.get('offset');
		if (idx + addedCount > offset) {
			var toAdd = arr.slice(idx, idx + addedCount);
			var arrangedContent = this.get('arrangedContent');
			var start = idx - offset;
			arrangedContent.replace(start, 0, toAdd);
		}
	}
});

export default ArrayOffset;
<commit_msg>Alias Math max and min functions<commit_after>import Em from 'ember';
var get = Em.get;
var computed = Em.computed;
var min = Math.min, max = Math.max;

var DEFAULT_OFFSET = 0;

var ArrayOffset = Em.ArrayProxy.extend({
	content: computed({
		get: function () {
			return Em.A();
		}
	}),

	offset: computed({
		get: function () {
			return DEFAULT_OFFSET;
		},
		set: function (name, offset, old) {
			offset = Number(offset); // ensure offset is number
			offset = max(offset, 0); // do not allow negative offset
			if (old === undefined) {
				// being set for first time, no need to update
				return offset;
			}
			var diff = offset - old;
			if (diff === 0) {
				// no need to continue if no difference
				return offset;
			}
			var arranged = this.get('arrangedContent');
			// offset added, remove items
			if (diff > 0) {
				var arrangedLength = get(arranged, 'length');
				var removeCount = min(diff, arrangedLength);
				arranged.replace(0, removeCount);
			}
			// offset removed, add items
			else {
				var content = this.get('content');
				var toAdd = content.slice(offset, old);
				arranged.replace(0, 0, toAdd);
			}
			return offset;
		}
	}),

	arrangedContent: computed('content', {
		get: function () {
			var content = this.get('content');
			var offset = this.get('offset');
			var slice = content.slice(offset);
			return Em.A(slice);
		}
	}),

	// process items removed
	contentArrayWillChange: function (arr, idx, removedCount/*, addedCount*/) {
		var arrangedContent = this.get('arrangedContent');
		var arrangedContentLength = this.get('arrangedContent.length');
		var offset = this.get('offset');
		var start = max(idx - offset, 0);
		var end = min(arrangedContentLength - start, removedCount);
		if (start < arrangedContentLength) {
			arrangedContent.replace(start, end);
		}
	},

	// process items added
	contentArrayDidChange: function (arr, idx, removedCount, addedCount) {
		var offset = this.get('offset');
		if (idx + addedCount > offset) {
			var toAdd = arr.slice(idx, idx + addedCount);
			var arrangedContent = this.get('arrangedContent');
			var start = idx - offset;
			arrangedContent.replace(start, 0, toAdd);
		}
	}
});

export default ArrayOffset;
<|endoftext|>


<commit_before>import Ember from 'ember';

var forEach = Ember.EnumerableUtils.forEach,
    // fmt = Ember.String.fmt,
    get = Ember.get;

/**
 * `LayerMixin` provides basic functionality for the Ember
 * wrapper of Leaflet layers, including instantiating child and parent layers.
 *
 * @class LayerMixin
 * @extends Ember.Mixin
 */
export default Ember.Mixin.create({
  _layer: null,
  _parentLayer: null,
  isVirtual: false,
  _childLayers: [],

  /**
   List of all supported events. EmberLeaflet will automatically create
   and register event handler functions with the same name for events
   listed in this property.
   Define this property in a derived view to add your own custom events.
   @property events
   @protected
   @type Array
  */
  concatenatedProperties: ['events'],

  /**
    Reference to parent layer. Never set directly.
    @property childLayers
    @type Array
    @private
    @default []
  */
  parentLayer: Ember.computed.alias('_parentLayer').readOnly(),

  layer: Ember.computed(function() { return this._layer; }).property(),

  /**
   Create and return the layer instance for the view.
   This needs to be implemented for any new type of view.
   @protected
  */
  _newLayer: Ember.required(Function),

  /**
   This gets called by the view just before the layer is created.
   @protected
  */
  willCreateLayer: Ember.K,

  /**
   This get called by the view after it has created the layer.
   Override this in your derived view to gain access to newly created
   layer (via `get("layer")`) for any custom functionality you may want
   to add.
   @protected
  */
  didCreateLayer: Ember.K,

  willDestroyLayer: Ember.K,
  didDestroyLayer: Ember.K,

  events: [],

  _createLayer: function() {
    Ember.assert("Layer must not already be created.", !this._layer);
    Ember.assert("Layer must have a parent", !!this._parentLayer);
    Ember.assert("Parent layer must be in leaflet.",
      !!this._parentLayer._layer);
    this.willCreateLayer();
    if(!this.isVirtual) {
      this.propertyWillChange('layer');
      this._layer = this._newLayer();
      this._addEventListeners();
      this._addToParent();
      this.propertyDidChange('layer');
    }
    this.didCreateLayer();
  },

  _destroyLayer: function() {
    this.willDestroyLayer();
    if(!this.isVirtual) {
      Ember.assert("Layer must exist.", !!this._layer);
      this.propertyWillChange('layer');
      this._removeEventListeners();
      this._removeFromParent();
      this._layer = null;
      this.propertyDidChange('layer');
    }
    this.didDestroyLayer();
  },

  _addToParent: function() {
    this._parentLayer._addChild(this._layer);
  },

  _removeFromParent: function() {
    this._parentLayer._removeChild(this._layer);
  },

  _addChild: function(layer) {
    this._layer.addLayer(layer);
  },

  _removeChild: function(layer) {
    this._layer.removeLayer(layer);
  },

  _addEventListeners: function() {
    this._eventHandlers = {};
    forEach(get(this, 'events'), function(eventName) {
      if(typeof this[eventName] === 'function') {
        // create an event handler that runs the function inside an event loop.
        this._eventHandlers[eventName] = function(e) {
          Ember.run(this, this[eventName], e);
        };
        this._layer.addEventListener(eventName,
          this._eventHandlers[eventName], this);
      }
    }, this);
  },

  _removeEventListeners: function() {
    forEach(get(this, 'events'), function(eventName) {
      if(typeof this[eventName] === 'function') {
        this._layer.removeEventListener(eventName,
          this._eventHandlers[eventName], this);
        delete this._eventHandlers[eventName];
      }
    }, this);
  }

});
<commit_msg>Adapt for Ember 1.12<commit_after>import Ember from 'ember';

var forEach = Ember.EnumerableUtils.forEach,
    // fmt = Ember.String.fmt,
    get = Ember.get;

/**
 * `LayerMixin` provides basic functionality for the Ember
 * wrapper of Leaflet layers, including instantiating child and parent layers.
 *
 * @class LayerMixin
 * @extends Ember.Mixin
 */
export default Ember.Mixin.create({
  _layer: null,
  _parentLayer: null,
  isVirtual: false,
  _childLayers: [],

  /**
   List of all supported events. EmberLeaflet will automatically create
   and register event handler functions with the same name for events
   listed in this property.
   Define this property in a derived view to add your own custom events.
   @property events
   @protected
   @type Array
  */
  concatenatedProperties: ['events'],

  /**
    Reference to parent layer. Never set directly.
    @property childLayers
    @type Array
    @private
    @default []
  */
  parentLayer: Ember.computed.alias('_parentLayer').readOnly(),

  layer: Ember.computed(function() { return this._layer; }),

  /**
   Create and return the layer instance for the view.
   This needs to be implemented for any new type of view.
   @protected
  */
  _newLayer: null,

  /**
   This gets called by the view just before the layer is created.
   @protected
  */
  willCreateLayer: Ember.K,

  /**
   This get called by the view after it has created the layer.
   Override this in your derived view to gain access to newly created
   layer (via `get("layer")`) for any custom functionality you may want
   to add.
   @protected
  */
  didCreateLayer: Ember.K,

  willDestroyLayer: Ember.K,
  didDestroyLayer: Ember.K,

  events: [],

  _createLayer: function() {
    Ember.assert("Layer must not already be created.", !this._layer);
    Ember.assert("Layer must have a parent", !!this._parentLayer);
    Ember.assert("Parent layer must be in leaflet.",
      !!this._parentLayer._layer);
    this.willCreateLayer();
    if(!this.isVirtual) {
      this.propertyWillChange('layer');
      this._layer = this._newLayer();
      this._addEventListeners();
      this._addToParent();
      this.propertyDidChange('layer');
    }
    this.didCreateLayer();
  },

  _destroyLayer: function() {
    this.willDestroyLayer();
    if(!this.isVirtual) {
      Ember.assert("Layer must exist.", !!this._layer);
      this.propertyWillChange('layer');
      this._removeEventListeners();
      this._removeFromParent();
      this._layer = null;
      this.propertyDidChange('layer');
    }
    this.didDestroyLayer();
  },

  _addToParent: function() {
    this._parentLayer._addChild(this._layer);
  },

  _removeFromParent: function() {
    this._parentLayer._removeChild(this._layer);
  },

  _addChild: function(layer) {
    this._layer.addLayer(layer);
  },

  _removeChild: function(layer) {
    this._layer.removeLayer(layer);
  },

  _addEventListeners: function() {
    this._eventHandlers = {};
    forEach(get(this, 'events'), function(eventName) {
      if(typeof this[eventName] === 'function') {
        // create an event handler that runs the function inside an event loop.
        this._eventHandlers[eventName] = function(e) {
          Ember.run(this, this[eventName], e);
        };
        this._layer.addEventListener(eventName,
          this._eventHandlers[eventName], this);
      }
    }, this);
  },

  _removeEventListeners: function() {
    forEach(get(this, 'events'), function(eventName) {
      if(typeof this[eventName] === 'function') {
        this._layer.removeEventListener(eventName,
          this._eventHandlers[eventName], this);
        delete this._eventHandlers[eventName];
      }
    }, this);
  }

});
<|endoftext|>


<commit_before>/**
orm model
@module mixins
@submodule model
*/

/**

@example
    import Ember from 'ember';
    import model, {DS} from 'ember-easy-orm/mixins/model'

    const {attr} = DS;

    export default Ember.Object.extend(model, {
        url: '/v1/pic',
        model: {
            'refer': attr('string'),
            'desc': attr('string'),
        }
    });

*/

import Ember from 'ember';
import ajax from './ajax';

export const DS = {
    attr(type, hash){
        if(typeof type === 'object'){
            hash = type;
            type = undefined;
        }

        if(typeof hash === 'object'){
            if(hash.hasOwnProperty('defaultValue')){
                return hash.defaultValue;
            }
        }

        switch(type){
            case 'string':
                return ''
            case 'boolean':
                return true;
            case 'number':
                return 0
            case 'array':
                return Ember.A;
        }

        return null;
    }
}

/**
mixin in ORM model
@public
@class model
**/
export default Ember.Mixin.create(ajax, Ember.Evented, {
    /**
     The api host, default is current host
     @property {String} host
     @default  ""
     */
    host: '',

    /**
     The api namespace  like /v1  /v2
     @property {String} namespace
     @default  ""
     */
    namespace: '',

    /**
     The response data business logic root key like: {'code': 0, 'resp':{'user':[]}, 'msg':''}, the resp is is the rootKey
     @property {String} rootKey
     @default  ""
     */
    rootKey: '',

    /**
     The api url. If rootURL ends with slash , the url should not starts with slash
     @property {String} url
     @default  ""
     */
    url: '',

    /**
     The model object primary key
     @property {String} primaryKey
     @default  "_id"
     */
    primaryKey: '_id',

    /**
     The object is for extract response data {user: [], comment:[], avatar: {}}
     @property {Object} displayModel
     @default  null
     */
    displayModel: null,

    /**
     url for find request
     @method urlForFind
     @default  /host/namespace/?key=params[key]
     @return String
     */
    urlForFind: function() {
        return this.get('api');
    },

    /**
     url for findOne request
     @method urlForFindOne
     @default  /{host}/{namespace}/{id}
     @return String
     */
    urlForFindOne: function(id) {
        return this.get('api') + '/' + id;
    },
    /**
     url for save request
     @method urlForSave
     @default  /{host}/{namespace}/{id}/
     @return String
     */
    urlForSave: function(id) {
        return id ? this.get('api') + '/' + id : this.get('api');
    },

    /**
     url for delete request
     @method urlForDelete
     @default  /{host}/{namespace}/{id}
     @return String
     */
    urlForDelete: function(id) {
        return id ? this.get('api') + '/' + id : this.get('api');
    },
    /**
     make api with host, namespace, url
     @method api
     @property {String} api
     @return  {host}{namespace}{url}
     */
    api: Ember.computed('host', 'namespace', 'url', function() {
        return this.host + this.namespace + this.url;
    }),
    /**
     save the record to backend
     @method save
     @param model model needed to save
     @return  {Promise}
     */
    save: function(model) {
        let self = this,
            primaryKey = this.primaryKey,
            url = this.urlForSave(model[primaryKey], model),
            record = {},
            model_keys = Object.keys(this.model);

        //filter model data
        for (var i = model_keys.length - 1; i >= 0; i--) {
            let key = model_keys[i];
            record[key] = model[key] !== undefined ? model[key] : self.model[key];
        }

        //check if is new data
        if (model[primaryKey]) {
            record[primaryKey] = model[primaryKey];
            return this.request.put(url, {'data': record}).then(function(data) {
                try{
                    return self.saveSerializer(data);
                }catch(e){
                    throw(e);
                }
            }, function(reason) {
                throw(reason);
            });
        }

        return this.request.post(url, {'data': record}).then(function(data) {
            try{
                return self.saveSerializer(data);
            }catch(e){
                throw(e);
            }
        }, function(reason) {
            throw(reason);
        });
    },

    /**
     create new model with init options and model property
     @method createRecord
     @param {Object} init init data
     @return Object current model
     */
    createRecord: function(init) {
        let record = Ember.Object.create();
        for(let property in this.model){
            if(this.model.hasOwnProperty(property)){
                let v = this.model[property];
                if(typeof v === 'function'){
                    record.set(property, v.apply());
                }else {
                    record.set(property, v);
                }
            }
        }

        if (typeof init === 'object') {
            Ember.merge(record, init);
        }

        return record;
    },

    /**
    delete the record from backend
    @method deleteRecord
    @param {Object} model
    @param {Object} data passed to backend server as extra params
    @return  Promise
     */
    deleteRecord: function(model, data) {
        let self = this,
            _id = typeof model ==='string' || typeof model ==='number' ? model : model[this.primaryKey],
            url = this.urlForDelete(_id, data),
            options = data ? {data: data} : {};

        return this.request.delete(url, options).then(function(data) {
            try{
                return self.deleteSerializer(data);
            }catch(e){
                throw(e);
            }
        }, function(reason) {
            throw(reason);
        });
    },
    /**
     find the records from backend according to params
     @method find
     @param {Object} params query params
     @return  Promise
    */
    find: function(params) {
        let self = this,
            url = this.urlForFind(params),
            filterParams = this._filterParams(params),
            options = filterParams ? {data: filterParams} : {};

        return this.request.get(url, options).then(function(data) {
            try{
                return self.findSerializer(data);
            }catch(e){
                throw(e);
            }
        }, function(reason) {
            throw(reason);
        });
    },

    /**
    find only one according to primary id
    @method findOne
    @param {String} id
    @param {Object} data
    @return Promise
    */
    findOne: function(id, data) {
        let url = this.urlForFindOne(id, data),
            self = this,
            options = data ? {data: data} : {};

        return this.request.get(url, options).then(function(data) {
            try{
                return self.findOneSerializer(data);
            }catch(e){
                throw(e);
            }
        }, function(reason) {
            throw(reason);
        });
    },
    /**
    filter request params
    @private
    @method _filterParams
    @param {Object} params
    @return Object filtered params
    */
    _filterParams: function(params) {
        if (!params) {
            return;
        }
        for (let k in params) {
            if (params.hasOwnProperty(k) && Ember.isBlank(params[k])) {
                delete params[k];
            }
        }
        return params;
    },
    /**
    find serializer
    @method findSerializer
    @param {Object} data response data
    @return serializer data
    */
    findSerializer: function(data) {
        let result = {};
        if(this.displayModel){
            let objectKeys = Object.keys(this.displayModel);
            for (let i = 0; i < objectKeys.length; i++) {
                let key = objectKeys[i];
                let keyAttr = this.displayModel[key];
                if(keyAttr==='array'){
                    result[key] = this.to_array(data[key]);
                    continue;
                }
                if(keyAttr==='object'){
                    result[key] = this.to_object(data[key]);
                    continue;
                }
                result[key] = data[key];
            }
            return result;
        }

        //data is null or undefined
        if (Ember.isNone(data)) {
            Ember.Logger.error('findSerializer response data is null');
            return this.to_array();
        }

        // rootKey is empty
        if (!this.rootKey) {
            return this.to_array(data);
        }

        // response data must be array
        if (!Ember.isArray(data[this.rootKey])) {
            Ember.Logger.error('findSerializer parsedData is not array');
            Ember.Logger.warn(data);
            Ember.Logger.warn(this.rootKey);
            return this.to_array();
        }

        return this.to_array(data[this.rootKey]);
    },
    /**
    find serializer
    @method findOneSerializer
    @param {Object} data response data
    @return serializer data
    */
    findOneSerializer: function(data) {
        //data is null or undefined
        if (Ember.isNone(data)) {
            Ember.Logger.error('findOneSerializer response data is null');
            return this.to_object();
        }

        // rootKey is empty
        if (!this.rootKey) {
            return data;
        }

        // parsedObject must be object
        if (Ember.isNone(data[this.rootKey])) {
            Ember.Logger.error('findOneSerializer parsedObject is null');
            return this.to_object();
        }

        return this.to_object(data[this.rootKey]);
    },
    to_array: function(data){
        return Ember.A(data || []);
    },
    to_object: function(data){
        return Ember.Object.create(data || {});
    },
    /**
    save serializer
    @method saveSerializer
    @param {Object} data response data
    @return serializer data
    */
    saveSerializer: function(data) {
        Ember.Logger.info('subclass override saveSerializer for response data serializer');
        return data;
    },
    /**
    delete serializer
    @method deleteSerializer
    @param {Object} data response data
    @return serializer data
    */
    deleteSerializer: function(data) {
        Ember.Logger.info('subclass override deleteSerializer for response data serializer');
        return data;
    },
    init: function(){
        this._super(...arguments);
        if(typeof this.rootKey !== 'string'){
            throw new Error(`rootKey only allow string type, now is ${this.rootKey}`);
        }
    }
});<commit_msg>fix #18<commit_after>/**
orm model
@module mixins
@submodule model
*/

/**

@example
    import Ember from 'ember';
    import model, {DS} from 'ember-easy-orm/mixins/model'

    const {attr} = DS;

    export default Ember.Object.extend(model, {
        url: '/v1/pic',
        model: {
            'refer': attr('string'),
            'desc': attr('string'),
        }
    });

*/

import Ember from 'ember';
import ajax from './ajax';

export const DS = {
    attr(type, hash){
        if(typeof type === 'object'){
            hash = type;
            type = undefined;
        }

        if(typeof hash === 'object'){
            if(hash.hasOwnProperty('defaultValue')){
                return hash.defaultValue;
            }
        }

        switch(type){
            case 'string':
                return ''
            case 'boolean':
                return true;
            case 'number':
                return 0
            case 'array':
                return Ember.A;
        }

        return null;
    }
}

/**
mixin in ORM model
@public
@class model
**/
export default Ember.Mixin.create(ajax, Ember.Evented, {
    /**
     The api host, default is current host
     @property {String} host
     @default  ""
     */
    host: '',

    /**
     The api namespace  like /v1  /v2
     @property {String} namespace
     @default  ""
     */
    namespace: '',

    /**
     The response data business logic root key like: {'code': 0, 'resp':{'user':[]}, 'msg':''}, the resp is is the rootKey
     @property {String} rootKey
     @default  ""
     */
    rootKey: '',

    /**
     The api url. If rootURL ends with slash , the url should not starts with slash
     @property {String} url
     @default  ""
     */
    url: '',

    /**
     The model object primary key
     @property {String} primaryKey
     @default  "_id"
     */
    primaryKey: '_id',

    /**
     The object is for extract response data {user: [], comment:[], avatar: {}}
     @property {Object} displayModel
     @default  null
     */
    displayModel: null,

    /**
     url for find request
     @method urlForFind
     @default  /host/namespace/?key=params[key]
     @return String
     */
    urlForFind: function() {
        return this.get('api');
    },

    /**
     url for findOne request
     @method urlForFindOne
     @default  /{host}/{namespace}/{id}
     @return String
     */
    urlForFindOne: function(id) {
        return this.get('api') + '/' + id;
    },
    /**
     url for save request
     @method urlForSave
     @default  /{host}/{namespace}/{id}/
     @return String
     */
    urlForSave: function(id) {
        return id ? this.get('api') + '/' + id : this.get('api');
    },

    /**
     url for delete request
     @method urlForDelete
     @default  /{host}/{namespace}/{id}
     @return String
     */
    urlForDelete: function(id) {
        return id ? this.get('api') + '/' + id : this.get('api');
    },
    /**
     make api with host, namespace, url
     @method api
     @property {String} api
     @return  {host}{namespace}{url}
     */
    api: Ember.computed('host', 'namespace', 'url', function() {
        return this.host + this.namespace + this.url;
    }),
    /**
     save the record to backend
     @method save
     @param model model needed to save
     @return  {Promise}
     */
    save: function(model) {
        let self = this,
            primaryKey = this.primaryKey,
            url = this.urlForSave(model[primaryKey], model),
            record = {},
            model_keys = Object.keys(this.model);

        //filter model data
        for (var i = model_keys.length - 1; i >= 0; i--) {
            let key = model_keys[i];
            if(typeof self.model[key] === 'function'){
                if(typeof model[key] === 'object' && !Ember.isArray(model[key])){
                    record[key] = JSON.stringify(model[key]);
                    continue;
                }
            }
            record[key] = model[key] !== undefined ? model[key] : self.model[key];
        }

        //check if is new data
        if (model[primaryKey]) {
            record[primaryKey] = model[primaryKey];
            return this.request.put(url, {'data': record}).then(function(data) {
                try{
                    return self.saveSerializer(data);
                }catch(e){
                    throw(e);
                }
            }, function(reason) {
                throw(reason);
            });
        }

        return this.request.post(url, {'data': record}).then(function(data) {
            try{
                return self.saveSerializer(data);
            }catch(e){
                throw(e);
            }
        }, function(reason) {
            throw(reason);
        });
    },

    /**
     create new model with init options and model property
     @method createRecord
     @param {Object} init init data
     @return Object current model
     */
    createRecord: function(init) {
        let record = Ember.Object.create();
        for(let property in this.model){
            if(this.model.hasOwnProperty(property)){
                let v = this.model[property];
                if(typeof v === 'function'){
                    record.set(property, v.apply());
                }else {
                    record.set(property, v);
                }
            }
        }

        if (typeof init === 'object') {
            Ember.merge(record, init);
        }

        return record;
    },

    /**
    delete the record from backend
    @method deleteRecord
    @param {Object} model
    @param {Object} data passed to backend server as extra params
    @return  Promise
     */
    deleteRecord: function(model, data) {
        let self = this,
            _id = typeof model ==='string' || typeof model ==='number' ? model : model[this.primaryKey],
            url = this.urlForDelete(_id, data),
            options = data ? {data: data} : {};

        return this.request.delete(url, options).then(function(data) {
            try{
                return self.deleteSerializer(data);
            }catch(e){
                throw(e);
            }
        }, function(reason) {
            throw(reason);
        });
    },
    /**
     find the records from backend according to params
     @method find
     @param {Object} params query params
     @return  Promise
    */
    find: function(params) {
        let self = this,
            url = this.urlForFind(params),
            filterParams = this._filterParams(params),
            options = filterParams ? {data: filterParams} : {};

        return this.request.get(url, options).then(function(data) {
            try{
                return self.findSerializer(data);
            }catch(e){
                throw(e);
            }
        }, function(reason) {
            throw(reason);
        });
    },

    /**
    find only one according to primary id
    @method findOne
    @param {String} id
    @param {Object} data
    @return Promise
    */
    findOne: function(id, data) {
        let url = this.urlForFindOne(id, data),
            self = this,
            options = data ? {data: data} : {};

        return this.request.get(url, options).then(function(data) {
            try{
                return self.findOneSerializer(data);
            }catch(e){
                throw(e);
            }
        }, function(reason) {
            throw(reason);
        });
    },
    /**
    filter request params
    @private
    @method _filterParams
    @param {Object} params
    @return Object filtered params
    */
    _filterParams: function(params) {
        if (!params) {
            return;
        }
        for (let k in params) {
            if (params.hasOwnProperty(k) && Ember.isBlank(params[k])) {
                delete params[k];
            }
        }
        return params;
    },
    /**
    find serializer
    @method findSerializer
    @param {Object} data response data
    @return serializer data
    */
    findSerializer: function(data) {
        let result = {};
        if(this.displayModel){
            let objectKeys = Object.keys(this.displayModel);
            for (let i = 0; i < objectKeys.length; i++) {
                let key = objectKeys[i];
                let keyAttr = this.displayModel[key];
                if(keyAttr==='array'){
                    result[key] = this.to_array(data[key]);
                    continue;
                }
                if(keyAttr==='object'){
                    result[key] = this.to_object(data[key]);
                    continue;
                }
                result[key] = data[key];
            }
            return result;
        }

        //data is null or undefined
        if (Ember.isNone(data)) {
            Ember.Logger.error('findSerializer response data is null');
            return this.to_array();
        }

        // rootKey is empty
        if (!this.rootKey) {
            return this.to_array(data);
        }

        // response data must be array
        if (!Ember.isArray(data[this.rootKey])) {
            Ember.Logger.error('findSerializer parsedData is not array');
            Ember.Logger.warn(data);
            Ember.Logger.warn(this.rootKey);
            return this.to_array();
        }

        return this.to_array(data[this.rootKey]);
    },
    /**
    find serializer
    @method findOneSerializer
    @param {Object} data response data
    @return serializer data
    */
    findOneSerializer: function(data) {
        //data is null or undefined
        if (Ember.isNone(data)) {
            Ember.Logger.error('findOneSerializer response data is null');
            return this.to_object();
        }

        // rootKey is empty
        if (!this.rootKey) {
            return data;
        }

        // parsedObject must be object
        if (Ember.isNone(data[this.rootKey])) {
            Ember.Logger.error('findOneSerializer parsedObject is null');
            return this.to_object();
        }

        return this.to_object(data[this.rootKey]);
    },
    to_array: function(data){
        return Ember.A(data || []);
    },
    to_object: function(data){
        return Ember.Object.create(data || {});
    },
    /**
    save serializer
    @method saveSerializer
    @param {Object} data response data
    @return serializer data
    */
    saveSerializer: function(data) {
        Ember.Logger.info('subclass override saveSerializer for response data serializer');
        return data;
    },
    /**
    delete serializer
    @method deleteSerializer
    @param {Object} data response data
    @return serializer data
    */
    deleteSerializer: function(data) {
        Ember.Logger.info('subclass override deleteSerializer for response data serializer');
        return data;
    },
    init: function(){
        this._super(...arguments);
        if(typeof this.rootKey !== 'string'){
            throw new Error(`rootKey only allow string type, now is ${this.rootKey}`);
        }
    }
});<|endoftext|>


<commit_before>import Ember from 'ember';

const {Object: EmberObject} = Ember;

function serverResponseError(res) {
  if (res && ((res.errors && res.errors.length && res.errors[0].status) || res.isAdapterError)) {
    const isServerValidationError = res.errors && res.errors.length && res.errors[0].status === '422';
    return new EmberObject({
      isAdapterError: true,
      isServerValidationError,
      response: res,
      name: isServerValidationError ? 'Server validation error' : 'Error'
    });
  }

  return res;
}

function catchServerResponseError(err) {
  if (err && err.isAdapterError) {
    return err;
  }
  throw err;
}

export {
  serverResponseError,
  catchServerResponseError
}
<commit_msg>Add catchServerValidationError util<commit_after>import Ember from 'ember';
import {every} from 'ember-form-object/utils/core';

const {Object: EmberObject} = Ember;

function serverResponseError(res) {
  if (res && ((res.errors && res.errors.length && res.errors[0].status) || res.isAdapterError)) {
    const isServerValidationError = res.errors && res.errors.length && res.errors[0].status === '422';
    return new EmberObject({
      isAdapterError: true,
      isServerValidationError,
      response: res,
      name: isServerValidationError ? 'Server validation error' : 'Error'
    });
  }

  return res;
}

function catchServerResponseError(err) {
  if (err && err.isAdapterError) {
    return err;
  }
  throw err;
}

function catchServerValidationError(err) {
  if (err && err.isAdapterError && every(err.errors, (e) => e.status === '422')) {
    return err;
  }
  throw err;
}

export {
  serverResponseError,
  catchServerResponseError,
  catchServerValidationError
}
<|endoftext|>


<commit_before>/* eslint-disable no-throw-literal, no-use-before-define, no-restricted-syntax, no-underscore-dangle */
const Discord = require("discord.js");
const path = require("path");
const now = require("performance-now");
const CommandMessage = require("./commandMessage");
const Loader = require("./loader");
const ArgResolver = require("./argResolver");
const PermLevels = require("./permLevels");
const Settings = require("./settingsCache");
const merge = require("../functions/mergeConfig");

const defaultPermStructure = new PermLevels()
  .addLevel(0, false, () => true)
  .addLevel(2, false, (client, msg) => {
    if (!msg.guild || !msg.guild.settings.modRole) return false;
    const modRole = msg.guild.roles.get(msg.guild.settings.modRole);
    return modRole && msg.member.roles.has(modRole.id);
  })
  .addLevel(3, false, (client, msg) => {
    if (!msg.guild || !msg.guild.settings.adminRole) return false;
    const adminRole = msg.guild.roles.get(msg.guild.settings.adminRole);
    return adminRole && msg.member.roles.has(adminRole.id);
  })
  .addLevel(4, false, (client, msg) => msg.guild && msg.author.id === msg.guild.owner.id)
  .addLevel(9, true, (client, msg) => msg.author.id === client.config.ownerID)
  .addLevel(10, false, (client, msg) => msg.author.id === client.config.ownerID);

/**
 * @typedef  {object}   OptionsDisabled
 * @property {string[]} [commands=Array]    Disabled Commands
 * @property {string[]} [events=Array]      Disabled Events
 * @property {string[]} [functions=Array]   Disabled Functions
 * @property {string[]} [inhibitors=Array]  Disabled Inhibitors
 * @property {string[]} [finalizers=Array]  Disabled Finalizers
 * @property {string[]} [monitors=Array]    Disabled Monitors
 * @property {string[]} [providers=Array]   Disabled Providers
 * @property {string[]} [extendables=Array] Disabled Extendables
 * @memberof Komada
 */

/**
 * @typedef  {object} OptionsProviders
 * @property {string} [engine=json] The Provider Engine SettingGateway will use to store and access to the persistent data.
 * @property {string} [cache=js]    The Provider Cache Engine CacheManager from SettingGateway will use to cache the data.
 * @memberof Komada
 */

/**
 * @typedef  {object}  Options
 * @property {string}  [prefix=?] The prefix for Komada. Defaults to '?'.
 * @property {string}  [ownerID=String] The bot owner's ID, Komada will autofetch it if it's not specified.
 *
 * @property {Komada.OptionsDisabled}  [disabled={}] The disabled pieces.
 * @property {PermissionLevels|Array<{}>} [permStructure=Array<{}>] The PermStructure for Komada.
 *
 * @property {boolean} [selfbot=boolean] Whether the bot is a selfbot or not. Komada detects this automatically.
 * @property {string}  [readyMessage=String] A custom string message Komada will use when firing the ready event message.
 * @property {number}  [commandMessageLifetime=1800] The lifetime for the command messages, in milliseconds.
 * @property {number}  [commandMessageSweep=900] How frequent should Komada sweep the command messages.
 *
 * @property {boolean} [disableLogTimestamps=false] Whether the komada logger should show the timestamps.
 * @property {boolean} [disableLogColor=false] Whether the komada logger should show colours.
 *
 * @property {boolean} [cmdEditing=false] Whether Komada should consider edited messages as potential messages able to fire new commands.
 * @property {boolean} [cmdPrompt=false] Whether Komada should prompt missing/invalid arguments at failed command execution.
 *
 * @property {Komada.OptionsProviders}  [provider={}] The engines for SettingGateway, 'engine' for Persistent Data, 'cache' for Cache Engine (defaults to Collection)
 * @memberof Komada
 */

/**
 * The class for the magic behind Komada
 * @extends external:Client
 */
class Komada extends Discord.Client {

  /**
   * Creates a new instance of Komada
   * @param  {Komada.Options} [config={}] The configuration options to provide to Komada
   */
  constructor(config = {}) {
    if (typeof config !== "object") throw new TypeError("Configuration for Komada must be an object.");
    super(config.clientOptions);
    /**
     * The configuration used to create Komada
     * @type {Komada.Options}
     */

    this.config = merge(config);

    /**
     * The location of where the core files of Komada rely in, typically inside node_modules
     * @type {String}
     */
    this.coreBaseDir = path.join(__dirname, "../");

    /**
     * The location of where you installed Komada, whether its from an enviroment variable named clientDir or where you run the node file from.
     * @type {String}
     */
    this.clientBaseDir = `${process.env.clientDir || process.cwd()}${path.sep}`;

    /**
     * An object containing all the functions within Komada
     * @type {Loader}
     */
    this.funcs = new Loader(this);

    /**
     * The resolver that resolves arguments in commands into their expected results
     * @type {ArgResolver}
     */
    this.argResolver = new ArgResolver(this);

    /**
     * The collection of commands available for use in Komada
     * @type external:Collection
     */
    this.commands = new Discord.Collection();

    /**
     * The collection of aliases that point to commands in Komada
     * @type external:Collection
     */
    this.aliases = new Discord.Collection();

    /**
     * The collection of inhibitors ran on commands
     * @type external:Collection
     */
    this.commandInhibitors = new Discord.Collection();

    /**
     * The collection of finalizers ran on succcesful commands.
     * @type external:Collection
     */
    this.commandFinalizers = new Discord.Collection();

    /**
     * The collection of monitors that are ran are specific or all messages.
     * @type external:Collection
     */
    this.messageMonitors = new Discord.Collection();

    /**
     * The collection of providers that can be used in Komada
     * @type external:Collection
     */
    this.providers = new Discord.Collection();

    /**
     * The collection of event handlers in Komada, used for reloading
     * @type external:Collection
     */
    this.eventHandlers = new Discord.Collection();

    /**
     * The permStructure Komada will take into account when commands are ran and permLevel is calculated.
     * @type {PermissionStructure}
     */
    this.permStructure = this.validatePermStructure();

    /**
     * The command message class.
     * @type {CommandMessage}
     */
    this.CommandMessage = CommandMessage;

    /**
     * The collection of stored command messages
     * @type external:Collection
     */
    this.commandMessages = new Discord.Collection();

    /**
     * The lifetime of command messages before they are removed from the cache and not editable anymore.
     * @type {Number}
     */
    this.commandMessageLifetime = config.commandMessageLifetime || 1800;

    /**
     * The amount of time in between each command message sweep in Komada.
     * @type {Number}
     */
    this.commandMessageSweep = config.commandMessageSweep || 900;

    /**
     * Whether or not Komada is completely ready to accept commands from users or not. This will be true after everything is initialized correctly.
     * @type {Boolean}
     */
    this.ready = false;

    /**
     * Additional methods to be used elsewhere in the bot
     * @type {Object}
     * @property {Class} Collection A discord.js collection
     * @property {Class} Embed A discord.js Message Embed
     * @property {Class} MessageCollector A discord.js MessageCollector
     * @property {Class} Webhook A discord.js WebhookClient
     * @property {Function} escapeMarkdown A discord.js escape markdown function
     * @property {Function} splitMessage A discord.js split message function
     */
    this.methods = {
      Collection: Discord.Collection,
      Embed: Discord.MessageEmbed,
      MessageCollector: Discord.MessageCollector,
      Webhook: Discord.WebhookClient,
      escapeMarkdown: Discord.escapeMarkdown,
      splitMessage: Discord.splitMessage,
    };

    /**
     * The object where the gateways are stored settings
     * @type {Object}
     */
    this.settings = null;

    /**
     * The oauth bots application. This will either be a full application object when Komada has finally loaded or null if the bot is a selfbot.
     * @type {Object}
     */
    this.application = null;

    this.once("ready", this._ready.bind(this));
  }

  /**
   * The invite link for the bot
   * @readonly
   * @returns {string}
   */
  get invite() {
    if (!this.user.bot) throw "Why would you need an invite link for a selfbot...";
    const permissions = Discord.Permissions.resolve([...new Set(this.commands.reduce((a, b) => a.concat(b.conf.botPerms), ["VIEW_CHANNEL", "SEND_MESSAGES"]))]);
    return `https://discordapp.com/oauth2/authorize?client_id=${this.application.id}&permissions=${permissions}&scope=bot`;
  }

  /**
   * The owner for this bot
   * @readonly
   * @type {external:User}
   */
  get owner() {
    return this.users.get(this.config.ownerID);
  }

  /**
   * Validates the permission structure passed to the client
   * @private
   * @returns {validPermStructure}
   */
  validatePermStructure() {
    const structure = this.config.permStructure instanceof PermLevels ? this.config.permStructure.structure : null;
    const permStructure = structure || this.config.permStructure || defaultPermStructure.structure;
    if (!Array.isArray(permStructure)) throw "PermStructure must be an array.";
    if (permStructure.some(perm => typeof perm !== "object" || typeof perm.check !== "function" || typeof perm.break !== "boolean")) {
      throw "Perms must be an object with a check function and a break boolean.";
    }
    if (permStructure.length !== 11) throw "Permissions 0-10 must all be defined.";
    return permStructure;
  }

  /**
   * Use this to login to Discord with your bot
   * @param {string} token Your bot token
   */
  async login(token) {
    const start = now();
    await this.funcs.loadAll(this);
    this.settings = new Settings(this);
    this.emit("log", `Loaded in ${(now() - start).toFixed(2)}ms.`);
    super.login(token);
  }

  /**
   * The once ready function for the client to init all pieces
   * @private
   */
  async _ready() {
    this.config.prefixMention = new RegExp(`^<@!?${this.user.id}>`);
    if (this.user.bot) this.application = await super.fetchApplication();
    if (!this.config.ownerID) this.config.ownerID = this.user.bot ? this.application.owner.id : this.user.id;
    await Promise.all(this.providers.map((piece) => {
      if (piece.init) return piece.init(this);
      return true;
    }));
    await Promise.all(Object.keys(this.settings).map((key) => {
      if (this.settings[key].init) return this.settings[key].init();
      return true;
    }));
    await Promise.all(Object.keys(this.funcs).map((key) => {
      if (this.funcs[key].init) return this.funcs[key].init(this);
      return true;
    }));
    await Promise.all(this.commands.map((piece) => {
      if (piece.init) return piece.init(this);
      return true;
    }));
    await Promise.all(this.commandInhibitors.map((piece) => {
      if (piece.init) return piece.init(this);
      return true;
    }));
    await Promise.all(this.commandFinalizers.map((piece) => {
      if (piece.init) return piece.init(this);
      return true;
    }));
    await Promise.all(this.messageMonitors.map((piece) => {
      if (piece.init) return piece.init(this);
      return true;
    }));
    this.setInterval(this.sweepCommandMessages.bind(this), this.commandMessageLifetime);
    this.ready = true;
    this.emit("log", this.config.readyMessage(this));
  }

  /**
   * Sweeps command messages based on the lifetime parameter
   * @param {number} lifetime The threshold for how old command messages can be before sweeping since the last edit in seconds
   * @returns {number} The amount of messages swept
   */
  sweepCommandMessages(lifetime = this.commandMessageLifetime) {
    if (typeof lifetime !== "number" || Number.isNaN(lifetime)) throw new TypeError("The lifetime must be a number.");
    if (lifetime <= 0) {
      this.emit("debug", "Didn't sweep messages - lifetime is unlimited");
      return -1;
    }

    const lifetimeMs = lifetime * 1000;
    const rightNow = Date.now();
    const messages = this.commandMessages.size;

    for (const [key, message] of this.commandMessages) {
      if (rightNow - (message.trigger.editedTimestamp || message.trigger.createdTimestamp) > lifetimeMs) this.commandMessages.delete(key);
    }

    this.emit("debug", `Swept ${messages - this.commandMessages.size} commandMessages older than ${lifetime} seconds.`);
    return messages - this.commandMessages.size;
  }

}

module.exports = Komada;

process.on("unhandledRejection", (err) => {
  if (!err) return;
  console.error(`Uncaught Promise Error: \n${err.stack || err}`);
});
<commit_msg>fix documentation for readyMessage<commit_after>/* eslint-disable no-throw-literal, no-use-before-define, no-restricted-syntax, no-underscore-dangle */
const Discord = require("discord.js");
const path = require("path");
const now = require("performance-now");
const CommandMessage = require("./commandMessage");
const Loader = require("./loader");
const ArgResolver = require("./argResolver");
const PermLevels = require("./permLevels");
const Settings = require("./settingsCache");
const merge = require("../functions/mergeConfig");

const defaultPermStructure = new PermLevels()
  .addLevel(0, false, () => true)
  .addLevel(2, false, (client, msg) => {
    if (!msg.guild || !msg.guild.settings.modRole) return false;
    const modRole = msg.guild.roles.get(msg.guild.settings.modRole);
    return modRole && msg.member.roles.has(modRole.id);
  })
  .addLevel(3, false, (client, msg) => {
    if (!msg.guild || !msg.guild.settings.adminRole) return false;
    const adminRole = msg.guild.roles.get(msg.guild.settings.adminRole);
    return adminRole && msg.member.roles.has(adminRole.id);
  })
  .addLevel(4, false, (client, msg) => msg.guild && msg.author.id === msg.guild.owner.id)
  .addLevel(9, true, (client, msg) => msg.author.id === client.config.ownerID)
  .addLevel(10, false, (client, msg) => msg.author.id === client.config.ownerID);

/**
 * @typedef  {object}   OptionsDisabled
 * @property {string[]} [commands=Array]    Disabled Commands
 * @property {string[]} [events=Array]      Disabled Events
 * @property {string[]} [functions=Array]   Disabled Functions
 * @property {string[]} [inhibitors=Array]  Disabled Inhibitors
 * @property {string[]} [finalizers=Array]  Disabled Finalizers
 * @property {string[]} [monitors=Array]    Disabled Monitors
 * @property {string[]} [providers=Array]   Disabled Providers
 * @property {string[]} [extendables=Array] Disabled Extendables
 * @memberof Komada
 */

/**
 * @typedef  {object} OptionsProviders
 * @property {string} [engine=json] The Provider Engine SettingGateway will use to store and access to the persistent data.
 * @property {string} [cache=js]    The Provider Cache Engine CacheManager from SettingGateway will use to cache the data.
 * @memberof Komada
 */

/**
 * @typedef  {object}  Options
 * @property {string}  [prefix=?] The prefix for Komada. Defaults to '?'.
 * @property {string}  [ownerID=String] The bot owner's ID, Komada will autofetch it if it's not specified.
 *
 * @property {Komada.OptionsDisabled}  [disabled={}] The disabled pieces.
 * @property {PermissionLevels|Array<{}>} [permStructure=Array<{}>] The PermStructure for Komada.
 *
 * @property {boolean} [selfbot=boolean] Whether the bot is a selfbot or not. Komada detects this automatically.
 * @property {function}  [readyMessage=function] A custom function with a client argument that allows you to customize the ready string when Komada logs in.
 * @property {number}  [commandMessageLifetime=1800] The lifetime for the command messages, in milliseconds.
 * @property {number}  [commandMessageSweep=900] How frequent should Komada sweep the command messages.
 *
 * @property {boolean} [disableLogTimestamps=false] Whether the komada logger should show the timestamps.
 * @property {boolean} [disableLogColor=false] Whether the komada logger should show colours.
 *
 * @property {boolean} [cmdEditing=false] Whether Komada should consider edited messages as potential messages able to fire new commands.
 * @property {boolean} [cmdPrompt=false] Whether Komada should prompt missing/invalid arguments at failed command execution.
 *
 * @property {Komada.OptionsProviders}  [provider={}] The engines for SettingGateway, 'engine' for Persistent Data, 'cache' for Cache Engine (defaults to Collection)
 * @memberof Komada
 */

/**
 * The class for the magic behind Komada
 * @extends external:Client
 */
class Komada extends Discord.Client {

  /**
   * Creates a new instance of Komada
   * @param  {Komada.Options} [config={}] The configuration options to provide to Komada
   */
  constructor(config = {}) {
    if (typeof config !== "object") throw new TypeError("Configuration for Komada must be an object.");
    super(config.clientOptions);
    /**
     * The configuration used to create Komada
     * @type {Komada.Options}
     */

    this.config = merge(config);

    /**
     * The location of where the core files of Komada rely in, typically inside node_modules
     * @type {String}
     */
    this.coreBaseDir = path.join(__dirname, "../");

    /**
     * The location of where you installed Komada, whether its from an enviroment variable named clientDir or where you run the node file from.
     * @type {String}
     */
    this.clientBaseDir = `${process.env.clientDir || process.cwd()}${path.sep}`;

    /**
     * An object containing all the functions within Komada
     * @type {Loader}
     */
    this.funcs = new Loader(this);

    /**
     * The resolver that resolves arguments in commands into their expected results
     * @type {ArgResolver}
     */
    this.argResolver = new ArgResolver(this);

    /**
     * The collection of commands available for use in Komada
     * @type external:Collection
     */
    this.commands = new Discord.Collection();

    /**
     * The collection of aliases that point to commands in Komada
     * @type external:Collection
     */
    this.aliases = new Discord.Collection();

    /**
     * The collection of inhibitors ran on commands
     * @type external:Collection
     */
    this.commandInhibitors = new Discord.Collection();

    /**
     * The collection of finalizers ran on succcesful commands.
     * @type external:Collection
     */
    this.commandFinalizers = new Discord.Collection();

    /**
     * The collection of monitors that are ran are specific or all messages.
     * @type external:Collection
     */
    this.messageMonitors = new Discord.Collection();

    /**
     * The collection of providers that can be used in Komada
     * @type external:Collection
     */
    this.providers = new Discord.Collection();

    /**
     * The collection of event handlers in Komada, used for reloading
     * @type external:Collection
     */
    this.eventHandlers = new Discord.Collection();

    /**
     * The permStructure Komada will take into account when commands are ran and permLevel is calculated.
     * @type {PermissionStructure}
     */
    this.permStructure = this.validatePermStructure();

    /**
     * The command message class.
     * @type {CommandMessage}
     */
    this.CommandMessage = CommandMessage;

    /**
     * The collection of stored command messages
     * @type external:Collection
     */
    this.commandMessages = new Discord.Collection();

    /**
     * The lifetime of command messages before they are removed from the cache and not editable anymore.
     * @type {Number}
     */
    this.commandMessageLifetime = config.commandMessageLifetime || 1800;

    /**
     * The amount of time in between each command message sweep in Komada.
     * @type {Number}
     */
    this.commandMessageSweep = config.commandMessageSweep || 900;

    /**
     * Whether or not Komada is completely ready to accept commands from users or not. This will be true after everything is initialized correctly.
     * @type {Boolean}
     */
    this.ready = false;

    /**
     * Additional methods to be used elsewhere in the bot
     * @type {Object}
     * @property {Class} Collection A discord.js collection
     * @property {Class} Embed A discord.js Message Embed
     * @property {Class} MessageCollector A discord.js MessageCollector
     * @property {Class} Webhook A discord.js WebhookClient
     * @property {Function} escapeMarkdown A discord.js escape markdown function
     * @property {Function} splitMessage A discord.js split message function
     */
    this.methods = {
      Collection: Discord.Collection,
      Embed: Discord.MessageEmbed,
      MessageCollector: Discord.MessageCollector,
      Webhook: Discord.WebhookClient,
      escapeMarkdown: Discord.escapeMarkdown,
      splitMessage: Discord.splitMessage,
    };

    /**
     * The object where the gateways are stored settings
     * @type {Object}
     */
    this.settings = null;

    /**
     * The oauth bots application. This will either be a full application object when Komada has finally loaded or null if the bot is a selfbot.
     * @type {Object}
     */
    this.application = null;

    this.once("ready", this._ready.bind(this));
  }

  /**
   * The invite link for the bot
   * @readonly
   * @returns {string}
   */
  get invite() {
    if (!this.user.bot) throw "Why would you need an invite link for a selfbot...";
    const permissions = Discord.Permissions.resolve([...new Set(this.commands.reduce((a, b) => a.concat(b.conf.botPerms), ["VIEW_CHANNEL", "SEND_MESSAGES"]))]);
    return `https://discordapp.com/oauth2/authorize?client_id=${this.application.id}&permissions=${permissions}&scope=bot`;
  }

  /**
   * The owner for this bot
   * @readonly
   * @type {external:User}
   */
  get owner() {
    return this.users.get(this.config.ownerID);
  }

  /**
   * Validates the permission structure passed to the client
   * @private
   * @returns {validPermStructure}
   */
  validatePermStructure() {
    const structure = this.config.permStructure instanceof PermLevels ? this.config.permStructure.structure : null;
    const permStructure = structure || this.config.permStructure || defaultPermStructure.structure;
    if (!Array.isArray(permStructure)) throw "PermStructure must be an array.";
    if (permStructure.some(perm => typeof perm !== "object" || typeof perm.check !== "function" || typeof perm.break !== "boolean")) {
      throw "Perms must be an object with a check function and a break boolean.";
    }
    if (permStructure.length !== 11) throw "Permissions 0-10 must all be defined.";
    return permStructure;
  }

  /**
   * Use this to login to Discord with your bot
   * @param {string} token Your bot token
   */
  async login(token) {
    const start = now();
    await this.funcs.loadAll(this);
    this.settings = new Settings(this);
    this.emit("log", `Loaded in ${(now() - start).toFixed(2)}ms.`);
    super.login(token);
  }

  /**
   * The once ready function for the client to init all pieces
   * @private
   */
  async _ready() {
    this.config.prefixMention = new RegExp(`^<@!?${this.user.id}>`);
    if (this.user.bot) this.application = await super.fetchApplication();
    if (!this.config.ownerID) this.config.ownerID = this.user.bot ? this.application.owner.id : this.user.id;
    await Promise.all(this.providers.map((piece) => {
      if (piece.init) return piece.init(this);
      return true;
    }));
    await Promise.all(Object.keys(this.settings).map((key) => {
      if (this.settings[key].init) return this.settings[key].init();
      return true;
    }));
    await Promise.all(Object.keys(this.funcs).map((key) => {
      if (this.funcs[key].init) return this.funcs[key].init(this);
      return true;
    }));
    await Promise.all(this.commands.map((piece) => {
      if (piece.init) return piece.init(this);
      return true;
    }));
    await Promise.all(this.commandInhibitors.map((piece) => {
      if (piece.init) return piece.init(this);
      return true;
    }));
    await Promise.all(this.commandFinalizers.map((piece) => {
      if (piece.init) return piece.init(this);
      return true;
    }));
    await Promise.all(this.messageMonitors.map((piece) => {
      if (piece.init) return piece.init(this);
      return true;
    }));
    this.setInterval(this.sweepCommandMessages.bind(this), this.commandMessageLifetime);
    this.ready = true;
    this.emit("log", this.config.readyMessage(this));
  }

  /**
   * Sweeps command messages based on the lifetime parameter
   * @param {number} lifetime The threshold for how old command messages can be before sweeping since the last edit in seconds
   * @returns {number} The amount of messages swept
   */
  sweepCommandMessages(lifetime = this.commandMessageLifetime) {
    if (typeof lifetime !== "number" || Number.isNaN(lifetime)) throw new TypeError("The lifetime must be a number.");
    if (lifetime <= 0) {
      this.emit("debug", "Didn't sweep messages - lifetime is unlimited");
      return -1;
    }

    const lifetimeMs = lifetime * 1000;
    const rightNow = Date.now();
    const messages = this.commandMessages.size;

    for (const [key, message] of this.commandMessages) {
      if (rightNow - (message.trigger.editedTimestamp || message.trigger.createdTimestamp) > lifetimeMs) this.commandMessages.delete(key);
    }

    this.emit("debug", `Swept ${messages - this.commandMessages.size} commandMessages older than ${lifetime} seconds.`);
    return messages - this.commandMessages.size;
  }

}

module.exports = Komada;

process.on("unhandledRejection", (err) => {
  if (!err) return;
  console.error(`Uncaught Promise Error: \n${err.stack || err}`);
});
<|endoftext|>


<commit_before>module.exports = function (config) {
  'use strict'

  config.set({
    frameworks: ['jspm', 'mocha', 'chai', 'sinon'],

    jspm: {
      config: 'src/jspm.conf.js',
      loadFiles: [
        'node_modules/es6-shim/es6-shim.js',
        'test/**/*.spec.js'
      ],
      serveFiles: [
        'node_modules/es6-shim/es6-shim.js',
        'src/**/*.js',
        'test/stubs.js'
      ],
      meta: {
        'src/*': { format: 'register' }
      }
    },
    proxies: {
      '/node_modules/': '/base/node_modules/',
      '/jspm_packages/': '/base/src/jspm_packages/',
      '/src/': '/base/src/',
      '/test/': '/base/test/'
    },

    autoWatchBatchDelay: 10000,
    singleRun: true,
    browsers: ['PhantomJS'],

    preprocessors: {
      'src/!(jspm.conf).js': ['coverage', 'sourcemap'],
      'src/app/**/*.js': ['coverage', 'sourcemap']
    },
    reporters: ['progress', 'coverage', 'appveyor'],
    coverageReporter: {
      dir: '../reports',
      includeAllSources: true,
      reporters: [
        {
          type: 'json',
          subdir: '.',
          file: 'coverage-js.json'
        }
      ]
    }
  })
}
<commit_msg>Increase some timeouts. Hopefully that resolves some "Disconnected" issues on AppVeyor.<commit_after>module.exports = function (config) {
  'use strict'

  config.set({
    frameworks: ['jspm', 'mocha', 'chai', 'sinon'],

    jspm: {
      config: 'src/jspm.conf.js',
      loadFiles: [
        'node_modules/es6-shim/es6-shim.js',
        'test/**/*.spec.js'
      ],
      serveFiles: [
        'node_modules/es6-shim/es6-shim.js',
        'src/**/*.js',
        'test/stubs.js'
      ],
      meta: {
        'src/*': { format: 'register' }
      }
    },
    proxies: {
      '/node_modules/': '/base/node_modules/',
      '/jspm_packages/': '/base/src/jspm_packages/',
      '/src/': '/base/src/',
      '/test/': '/base/test/'
    },

    autoWatchBatchDelay: 10000,
    singleRun: true,
    browsers: ['PhantomJS'],
    captureTimeout: 2000,
    browserDisconnectTimeout: 2000,
    browserDisconnectTolerance: 3,
    browserNoActivityTimeout: 10000,

    preprocessors: {
      'src/!(jspm.conf).js': ['coverage', 'sourcemap'],
      'src/app/**/*.js': ['coverage', 'sourcemap']
    },
    reporters: ['progress', 'coverage', 'appveyor'],
    coverageReporter: {
      dir: '../reports',
      includeAllSources: true,
      reporters: [
        {
          type: 'json',
          subdir: '.',
          file: 'coverage-js.json'
        }
      ]
    }
  })
}
<|endoftext|>


<commit_before>/* @flow */

type ListenerFunction = (el: Element, name: string, ev: Event) => void;
type Listeners = {[name: string]: ListenerFunction[]}

export default class Actions {
  rootElement: Element;
  listeners: Listeners;
  boundListener: Function;

  constructor(el: Element) {
    this.rootElement = el
    this.listeners = {}
  }

  activate() {
    this.boundListener = this.handleClick.bind(this)
    this.rootElement.addEventListener('click', this.boundListener)
  }

  deactivate() {
    if (this.boundListener) {
      this.rootElement.removeEventListener('click', this.boundListener)
    }

    delete this.boundListener
    delete this.rootElement
    this.listeners = {}
  }

  add<T>(name: string, listener: ListenerFunction, thisObj: T): Actions {
    if (!this.listeners[name]) {
      this.listeners[name] = []
    }

    this.listeners[name].push(listener.bind(thisObj))
    return this
  }

  handleClick(ev: Event) {
    let target = ev.target

    if (!(target instanceof Element)) {
      return
    }

    if (target instanceof HTMLElement) {
      if (target.nodeName == 'BUTTON' && target.getAttribute('type') == 'submit') {
        return
      }
    }

    let root = this.rootElement.parentNode
    while (target && target != root && target != document) {
      if (target instanceof HTMLElement) {
        let name = target.getAttribute('data-click')

        // If the element doesn't have a data-click property but is something
        // you'd want to click on (like a text field), return without firing.
        if (this.isClickable(target) && !name) {
          return
        }

        if (name) {
          this.fire(name, target, ev)
          return
        }
      }

      target = target.parentNode
    }
  }

  isClickable(el: HTMLElement) {
    switch (el.nodeName) {
      case 'BUTTON':
      case 'LINK':
      case 'INPUT':
      case 'TEXTAREA':
        return true
    }

    return false
  }

  fire(name: string, target: Element, ev: Event) {
    if (!this.listeners[name]) {
      return
    }

    this.listeners[name].forEach((fn: ListenerFunction) => {
      fn(target, name, ev)
    })

    ev.stopPropagation()
    ev.preventDefault()
  }
}
<commit_msg>Treat content-editable DIVs as clickable items<commit_after>/* @flow */

type ListenerFunction = (el: Element, name: string, ev: Event) => void;
type Listeners = {[name: string]: ListenerFunction[]}

export default class Actions {
  rootElement: Element;
  listeners: Listeners;
  boundListener: Function;

  constructor(el: Element) {
    this.rootElement = el
    this.listeners = {}
  }

  activate() {
    this.boundListener = this.handleClick.bind(this)
    this.rootElement.addEventListener('click', this.boundListener)
  }

  deactivate() {
    if (this.boundListener) {
      this.rootElement.removeEventListener('click', this.boundListener)
    }

    delete this.boundListener
    delete this.rootElement
    this.listeners = {}
  }

  add<T>(name: string, listener: ListenerFunction, thisObj: T): Actions {
    if (!this.listeners[name]) {
      this.listeners[name] = []
    }

    this.listeners[name].push(listener.bind(thisObj))
    return this
  }

  handleClick(ev: Event) {
    let target = ev.target

    if (!(target instanceof Element)) {
      return
    }

    if (target instanceof HTMLElement) {
      if (target.nodeName == 'BUTTON' && target.getAttribute('type') == 'submit') {
        return
      }
    }

    let root = this.rootElement.parentNode
    while (target && target != root && target != document) {
      if (target instanceof HTMLElement) {
        let name = target.getAttribute('data-click')

        // If the element doesn't have a data-click property but is something
        // you'd want to click on (like a text field), return without firing.
        if (this.isClickable(target) && !name) {
          return
        }

        if (name) {
          this.fire(name, target, ev)
          return
        }
      }

      target = target.parentNode
    }
  }

  isClickable(el: HTMLElement) {
    switch (el.nodeName) {
      case 'BUTTON':
      case 'LINK':
      case 'INPUT':
      case 'TEXTAREA':
        return true
      default:
        if (el.getAttribute('contenteditable')) {
          return true
        }
    }

    return false
  }

  fire(name: string, target: Element, ev: Event) {
    if (!this.listeners[name]) {
      return
    }

    this.listeners[name].forEach((fn: ListenerFunction) => {
      fn(target, name, ev)
    })

    ev.stopPropagation()
    ev.preventDefault()
  }
}
<|endoftext|>


<commit_before>var express = require('express');
var router = express.Router();
var config = require('../../config');
var passport = require('passport');
var userService = require('../services/user-service');

var app = express();

router.get('/', function(req, res){
  console.log('user', req.user);
  if (req.user) {
    userName = req.user.firstName + ' ' + req.user.lastName;
    return res.render('index', {
      title: config.siteName,
      username: userName
    });
  };

  res.redirect('/admin/login');

});

router.get('/login', function(req, res){
  res.render('login', {
    title: config.siteName,
    error: req.flash('error')
  });
});

router.get('/create', function(req, res){
  res.render('signup', {
    title: config.siteName
  })
});

router.post('/create', function(req, res, next) {
  userService.addUser(req.body, function(err) {
    if (err) {
      var vm = {
        title: 'Create an account',
        input: req.body,
        error: err
      };
      delete vm.input.password;
      return res.render('signup', vm);
    }
    req.login(req.body, function(err) {
      res.redirect('/admin');
    });
  });
});

router.post('/login', function(req, res, next) {
  passport.authenticate('local', function(err, user, info) {
    if (err) { return next(err); }
    if (!user) { return res.redirect('/admin/login'); }

    req.logIn(user, function(err) {
      if (err) { return next(err); }
      return res.redirect('/admin');
    });
  })(req, res, next);
});

router.get('/logout', function(req, res, next) {
  req.session.destroy();
  req.logout();
  res.redirect('/admin/login');
});

module.exports = router;<commit_msg>v0.1.2: Removed log<commit_after>var express = require('express');
var router = express.Router();
var config = require('../../config');
var passport = require('passport');
var userService = require('../services/user-service');

var app = express();

router.get('/', function(req, res){
  if (req.user) {
    userName = req.user.firstName + ' ' + req.user.lastName;
    return res.render('index', {
      title: config.siteName,
      username: userName
    });
  };

  res.redirect('/admin/login');

});

router.get('/login', function(req, res){
  res.render('login', {
    title: config.siteName,
    error: req.flash('error')
  });
});

router.get('/create', function(req, res){
  res.render('signup', {
    title: config.siteName
  })
});

router.post('/create', function(req, res, next) {
  userService.addUser(req.body, function(err) {
    if (err) {
      var vm = {
        title: 'Create an account',
        input: req.body,
        error: err
      };
      delete vm.input.password;
      return res.render('signup', vm);
    }
    req.login(req.body, function(err) {
      res.redirect('/admin');
    });
  });
});

router.post('/login', function(req, res, next) {
  passport.authenticate('local', function(err, user, info) {
    if (err) { return next(err); }
    if (!user) { return res.redirect('/admin/login'); }

    req.logIn(user, function(err) {
      if (err) { return next(err); }
      return res.redirect('/admin');
    });
  })(req, res, next);
});

router.get('/logout', function(req, res, next) {
  req.session.destroy();
  req.logout();
  res.redirect('/admin/login');
});

module.exports = router;<|endoftext|>