<commit_before>var _ = require('./index')
var config = require('../config')
var extend = _.extend

/**
 * Option overwriting strategies are functions that handle
 * how to merge a parent option value and a child option
 * value into the final value.
 *
 * All strategy functions follow the same signature:
 *
 * @param {*} parentVal
 * @param {*} childVal
 * @param {Vue} [vm]
 */

var strats = Object.create(null)

/**
 * Helper that recursively merges two data objects together.
 */

function mergeData (to, from) {
  var key, toVal, fromVal
  for (key in from) {
    toVal = to[key]
    fromVal = from[key]
    if (!to.hasOwnProperty(key)) {
      to.$add(key, fromVal)
    } else if (_.isObject(toVal) && _.isObject(fromVal)) {
      mergeData(toVal, fromVal)
    }
  }
  return to
}

/**
 * Data
 */

strats.data = function (parentVal, childVal, vm) {
  if (!vm) {
    // in a Vue.extend merge, both should be functions
    if (!childVal) {
      return parentVal
    }
    if (typeof childVal !== 'function') {
      process.env.NODE_ENV !== 'production' && _.warn(
        'The "data" option should be a function ' +
        'that returns a per-instance value in component ' +
        'definitions.'
      )
      return parentVal
    }
    if (!parentVal) {
      return childVal
    }
    // when parentVal & childVal are both present,
    // we need to return a function that returns the
    // merged result of both functions... no need to
    // check if parentVal is a function here because
    // it has to be a function to pass previous merges.
    return function mergedDataFn () {
      return mergeData(
        childVal.call(this),
        parentVal.call(this)
      )
    }
  } else if (parentVal || childVal) {
    return function mergedInstanceDataFn () {
      // instance merge
      var instanceData = typeof childVal === 'function'
        ? childVal.call(vm)
        : childVal
      var defaultData = typeof parentVal === 'function'
        ? parentVal.call(vm)
        : undefined
      if (instanceData) {
        return mergeData(instanceData, defaultData)
      } else {
        return defaultData
      }
    }
  }
}

/**
 * El
 */

strats.el = function (parentVal, childVal, vm) {
  if (!vm && childVal && typeof childVal !== 'function') {
    process.env.NODE_ENV !== 'production' && _.warn(
      'The "el" option should be a function ' +
      'that returns a per-instance value in component ' +
      'definitions.'
    )
    return
  }
  var ret = childVal || parentVal
  // invoke the element factory if this is instance merge
  return vm && typeof ret === 'function'
    ? ret.call(vm)
    : ret
}

/**
 * Hooks and param attributes are merged as arrays.
 */

strats.created =
strats.ready =
strats.attached =
strats.detached =
strats.beforeCompile =
strats.compiled =
strats.beforeDestroy =
strats.destroyed =
strats.props = function (parentVal, childVal) {
  return childVal
    ? parentVal
      ? parentVal.concat(childVal)
      : _.isArray(childVal)
        ? childVal
        : [childVal]
    : parentVal
}

/**
 * 0.11 deprecation warning
 */

strats.paramAttributes = function () {
  /* istanbul ignore next */
  process.env.NODE_ENV !== 'production' && _.warn(
    '"paramAttributes" option has been deprecated in 0.12. ' +
    'Use "props" instead.'
  )
}

/**
 * Assets
 *
 * When a vm is present (instance creation), we need to do
 * a three-way merge between constructor options, instance
 * options and parent options.
 */

function mergeAssets (parentVal, childVal) {
  var res = Object.create(parentVal)
  return childVal
    ? extend(res, guardArrayAssets(childVal))
    : res
}

config._assetTypes.forEach(function (type) {
  strats[type + 's'] = mergeAssets
})

/**
 * Events & Watchers.
 *
 * Events & watchers hashes should not overwrite one
 * another, so we merge them as arrays.
 */

strats.watch =
strats.events = function (parentVal, childVal) {
  if (!childVal) return parentVal
  if (!parentVal) return childVal
  var ret = {}
  extend(ret, parentVal)
  for (var key in childVal) {
    var parent = ret[key]
    var child = childVal[key]
    if (parent && !_.isArray(parent)) {
      parent = [parent]
    }
    ret[key] = parent
      ? parent.concat(child)
      : [child]
  }
  return ret
}

/**
 * Other object hashes.
 */

strats.methods =
strats.computed = function (parentVal, childVal) {
  if (!childVal) return parentVal
  if (!parentVal) return childVal
  var ret = Object.create(parentVal)
  extend(ret, childVal)
  return ret
}

/**
 * Default strategy.
 */

var defaultStrat = function (parentVal, childVal) {
  return childVal === undefined
    ? parentVal
    : childVal
}

/**
 * Make sure component options get converted to actual
 * constructors.
 *
 * @param {Object} options
 */

function guardComponents (options) {
  if (options.components) {
    var components = options.components =
      guardArrayAssets(options.components)
    var def
    var ids = Object.keys(components)
    for (var i = 0, l = ids.length; i < l; i++) {
      var key = ids[i]
      if (_.commonTagRE.test(key)) {
        process.env.NODE_ENV !== 'production' && _.warn(
          'Do not use built-in HTML elements as component ' +
          'id: ' + key
        )
        continue
      }
      def = components[key]
      if (_.isPlainObject(def)) {
        def.id = def.id || key
        components[key] = def._Ctor || (def._Ctor = _.Vue.extend(def))
      }
    }
  }
}

/**
 * Ensure all props option syntax are normalized into the
 * Object-based format.
 *
 * @param {Object} options
 */

function guardProps (options) {
  var props = options.props
  if (_.isPlainObject(props)) {
    options.props = Object.keys(props).map(function (key) {
      var val = props[key]
      if (!_.isPlainObject(val)) {
        val = { type: val }
      }
      val.name = key
      return val
    })
  } else if (_.isArray(props)) {
    options.props = props.map(function (prop) {
      return typeof prop === 'string'
        ? { name: prop }
        : prop
    })
  }
}

/**
 * Guard an Array-format assets option and converted it
 * into the key-value Object format.
 *
 * @param {Object|Array} assets
 * @return {Object}
 */

function guardArrayAssets (assets) {
  if (_.isArray(assets)) {
    var res = {}
    var i = assets.length
    var asset
    while (i--) {
      asset = assets[i]
      var id = asset.id || (asset.options && asset.options.id)
      if (!id) {
        process.env.NODE_ENV !== 'production' && _.warn(
          'Array-syntax assets must provide an id field.'
        )
      } else {
        res[id] = asset
      }
    }
    return res
  }
  return assets
}

/**
 * Merge two option objects into a new one.
 * Core utility used in both instantiation and inheritance.
 *
 * @param {Object} parent
 * @param {Object} child
 * @param {Vue} [vm] - if vm is present, indicates this is
 *                     an instantiation merge.
 */

exports.mergeOptions = function merge (parent, child, vm) {
  guardComponents(child)
  guardProps(child)
  var options = {}
  var key
  if (child.mixins) {
    for (var i = 0, l = child.mixins.length; i < l; i++) {
      parent = merge(parent, child.mixins[i], vm)
    }
  }
  for (key in parent) {
    mergeField(key)
  }
  for (key in child) {
    if (!(parent.hasOwnProperty(key))) {
      mergeField(key)
    }
  }
  function mergeField (key) {
    var strat = strats[key] || defaultStrat
    options[key] = strat(parent[key], child[key], vm, key)
  }
  return options
}

/**
 * Resolve an asset.
 * This function is used because child instances need access
 * to assets defined in its ancestor chain.
 *
 * @param {Object} options
 * @param {String} type
 * @param {String} id
 * @return {Object|Function}
 */

exports.resolveAsset = function resolve (options, type, id) {
  var camelizedId = _.camelize(id)
  var pascalizedId = camelizedId.charAt(0).toUpperCase() + camelizedId.slice(1)
  var assets = options[type]
  var asset = assets[id] || assets[camelizedId] || assets[pascalizedId]
  while (
    !asset &&
    options._parent &&
    (!config.strict || options._repeat)
  ) {
    options = (options._context || options._parent).$options
    assets = options[type]
    asset = assets[id] || assets[camelizedId] || assets[pascalizedId]
  }
  return asset
}
<commit_msg>expose option merge strategies<commit_after>var _ = require('./index')
var config = require('../config')
var extend = _.extend

/**
 * Option overwriting strategies are functions that handle
 * how to merge a parent option value and a child option
 * value into the final value.
 *
 * All strategy functions follow the same signature:
 *
 * @param {*} parentVal
 * @param {*} childVal
 * @param {Vue} [vm]
 */

var strats = config.optionMergeStrategies = Object.create(null)

/**
 * Helper that recursively merges two data objects together.
 */

function mergeData (to, from) {
  var key, toVal, fromVal
  for (key in from) {
    toVal = to[key]
    fromVal = from[key]
    if (!to.hasOwnProperty(key)) {
      to.$add(key, fromVal)
    } else if (_.isObject(toVal) && _.isObject(fromVal)) {
      mergeData(toVal, fromVal)
    }
  }
  return to
}

/**
 * Data
 */

strats.data = function (parentVal, childVal, vm) {
  if (!vm) {
    // in a Vue.extend merge, both should be functions
    if (!childVal) {
      return parentVal
    }
    if (typeof childVal !== 'function') {
      process.env.NODE_ENV !== 'production' && _.warn(
        'The "data" option should be a function ' +
        'that returns a per-instance value in component ' +
        'definitions.'
      )
      return parentVal
    }
    if (!parentVal) {
      return childVal
    }
    // when parentVal & childVal are both present,
    // we need to return a function that returns the
    // merged result of both functions... no need to
    // check if parentVal is a function here because
    // it has to be a function to pass previous merges.
    return function mergedDataFn () {
      return mergeData(
        childVal.call(this),
        parentVal.call(this)
      )
    }
  } else if (parentVal || childVal) {
    return function mergedInstanceDataFn () {
      // instance merge
      var instanceData = typeof childVal === 'function'
        ? childVal.call(vm)
        : childVal
      var defaultData = typeof parentVal === 'function'
        ? parentVal.call(vm)
        : undefined
      if (instanceData) {
        return mergeData(instanceData, defaultData)
      } else {
        return defaultData
      }
    }
  }
}

/**
 * El
 */

strats.el = function (parentVal, childVal, vm) {
  if (!vm && childVal && typeof childVal !== 'function') {
    process.env.NODE_ENV !== 'production' && _.warn(
      'The "el" option should be a function ' +
      'that returns a per-instance value in component ' +
      'definitions.'
    )
    return
  }
  var ret = childVal || parentVal
  // invoke the element factory if this is instance merge
  return vm && typeof ret === 'function'
    ? ret.call(vm)
    : ret
}

/**
 * Hooks and param attributes are merged as arrays.
 */

strats.created =
strats.ready =
strats.attached =
strats.detached =
strats.beforeCompile =
strats.compiled =
strats.beforeDestroy =
strats.destroyed =
strats.props = function (parentVal, childVal) {
  return childVal
    ? parentVal
      ? parentVal.concat(childVal)
      : _.isArray(childVal)
        ? childVal
        : [childVal]
    : parentVal
}

/**
 * 0.11 deprecation warning
 */

strats.paramAttributes = function () {
  /* istanbul ignore next */
  process.env.NODE_ENV !== 'production' && _.warn(
    '"paramAttributes" option has been deprecated in 0.12. ' +
    'Use "props" instead.'
  )
}

/**
 * Assets
 *
 * When a vm is present (instance creation), we need to do
 * a three-way merge between constructor options, instance
 * options and parent options.
 */

function mergeAssets (parentVal, childVal) {
  var res = Object.create(parentVal)
  return childVal
    ? extend(res, guardArrayAssets(childVal))
    : res
}

config._assetTypes.forEach(function (type) {
  strats[type + 's'] = mergeAssets
})

/**
 * Events & Watchers.
 *
 * Events & watchers hashes should not overwrite one
 * another, so we merge them as arrays.
 */

strats.watch =
strats.events = function (parentVal, childVal) {
  if (!childVal) return parentVal
  if (!parentVal) return childVal
  var ret = {}
  extend(ret, parentVal)
  for (var key in childVal) {
    var parent = ret[key]
    var child = childVal[key]
    if (parent && !_.isArray(parent)) {
      parent = [parent]
    }
    ret[key] = parent
      ? parent.concat(child)
      : [child]
  }
  return ret
}

/**
 * Other object hashes.
 */

strats.methods =
strats.computed = function (parentVal, childVal) {
  if (!childVal) return parentVal
  if (!parentVal) return childVal
  var ret = Object.create(parentVal)
  extend(ret, childVal)
  return ret
}

/**
 * Default strategy.
 */

var defaultStrat = function (parentVal, childVal) {
  return childVal === undefined
    ? parentVal
    : childVal
}

/**
 * Make sure component options get converted to actual
 * constructors.
 *
 * @param {Object} options
 */

function guardComponents (options) {
  if (options.components) {
    var components = options.components =
      guardArrayAssets(options.components)
    var def
    var ids = Object.keys(components)
    for (var i = 0, l = ids.length; i < l; i++) {
      var key = ids[i]
      if (_.commonTagRE.test(key)) {
        process.env.NODE_ENV !== 'production' && _.warn(
          'Do not use built-in HTML elements as component ' +
          'id: ' + key
        )
        continue
      }
      def = components[key]
      if (_.isPlainObject(def)) {
        def.id = def.id || key
        components[key] = def._Ctor || (def._Ctor = _.Vue.extend(def))
      }
    }
  }
}

/**
 * Ensure all props option syntax are normalized into the
 * Object-based format.
 *
 * @param {Object} options
 */

function guardProps (options) {
  var props = options.props
  if (_.isPlainObject(props)) {
    options.props = Object.keys(props).map(function (key) {
      var val = props[key]
      if (!_.isPlainObject(val)) {
        val = { type: val }
      }
      val.name = key
      return val
    })
  } else if (_.isArray(props)) {
    options.props = props.map(function (prop) {
      return typeof prop === 'string'
        ? { name: prop }
        : prop
    })
  }
}

/**
 * Guard an Array-format assets option and converted it
 * into the key-value Object format.
 *
 * @param {Object|Array} assets
 * @return {Object}
 */

function guardArrayAssets (assets) {
  if (_.isArray(assets)) {
    var res = {}
    var i = assets.length
    var asset
    while (i--) {
      asset = assets[i]
      var id = asset.id || (asset.options && asset.options.id)
      if (!id) {
        process.env.NODE_ENV !== 'production' && _.warn(
          'Array-syntax assets must provide an id field.'
        )
      } else {
        res[id] = asset
      }
    }
    return res
  }
  return assets
}

/**
 * Merge two option objects into a new one.
 * Core utility used in both instantiation and inheritance.
 *
 * @param {Object} parent
 * @param {Object} child
 * @param {Vue} [vm] - if vm is present, indicates this is
 *                     an instantiation merge.
 */

exports.mergeOptions = function merge (parent, child, vm) {
  guardComponents(child)
  guardProps(child)
  var options = {}
  var key
  if (child.mixins) {
    for (var i = 0, l = child.mixins.length; i < l; i++) {
      parent = merge(parent, child.mixins[i], vm)
    }
  }
  for (key in parent) {
    mergeField(key)
  }
  for (key in child) {
    if (!(parent.hasOwnProperty(key))) {
      mergeField(key)
    }
  }
  function mergeField (key) {
    var strat = strats[key] || defaultStrat
    options[key] = strat(parent[key], child[key], vm, key)
  }
  return options
}

/**
 * Resolve an asset.
 * This function is used because child instances need access
 * to assets defined in its ancestor chain.
 *
 * @param {Object} options
 * @param {String} type
 * @param {String} id
 * @return {Object|Function}
 */

exports.resolveAsset = function resolve (options, type, id) {
  var camelizedId = _.camelize(id)
  var pascalizedId = camelizedId.charAt(0).toUpperCase() + camelizedId.slice(1)
  var assets = options[type]
  var asset = assets[id] || assets[camelizedId] || assets[pascalizedId]
  while (
    !asset &&
    options._parent &&
    (!config.strict || options._repeat)
  ) {
    options = (options._context || options._parent).$options
    assets = options[type]
    asset = assets[id] || assets[camelizedId] || assets[pascalizedId]
  }
  return asset
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2012 Adobe Systems Incorporated. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */
/*global define */

/**
 * Initializes the global "brackets" variable and it's properties.
 * Modules should not access the global.brackets object until either
 * (a) the module requires this module, i.e. require("utils/Global") or
 * (b) the module receives a "ready" callback from the utils/AppReady module.
 */
define(function (require, exports, module) {
    "use strict";

    var packageJSON = require("text!package.json");

    // Define core brackets namespace if it isn't already defined
    //
    // We can't simply do 'brackets = {}' to define it in the global namespace because
    // we're in "use strict" mode. Most likely, 'window' will always point to the global
    // object when this code is running. However, in case it isn't (e.g. if we're running
    // inside Node for CI testing) we use this trick to get the global object.
    //
    // Taken from:
    //   http://stackoverflow.com/questions/3277182/how-to-get-the-global-object-in-javascript
    var Fn = Function, global = (new Fn("return this"))();
    if (!global.brackets) {
        global.brackets = {};
    }

    // Parse src/config.json
    try {
        global.brackets.metadata = JSON.parse(packageJSON);
        global.brackets.config = global.brackets.metadata.config;
    } catch (err) {
        console.log(err);
    }

    // Uncomment the following line to force all low level file i/o routines to complete
    // asynchronously. This should only be done for testing/debugging.
    // NOTE: Make sure this line is commented out again before committing!
    //brackets.forceAsyncCallbacks = true;

    // Load native shell when brackets is run in a native shell rather than the browser
    // TODO: (issue #266) load conditionally
    global.brackets.shellAPI = require("utils/ShellAPI");

    global.brackets.inBrowser = !global.brackets.hasOwnProperty("fs");

    if (global.navigator.platform === "MacIntel" || global.navigator.platform === "MacPPC") {
        global.brackets.platform = "mac";
    } else if (global.navigator.platform.indexOf("Linux") >= 0) {
        global.brackets.platform = "linux";
    } else {
        global.brackets.platform = "win";
    }

    global.brackets.getLocale = function () {
        // By default use the locale that was determined in brackets.js
        return global.localStorage.getItem("locale") || global.require.s.contexts._.config.locale;
    };

    global.brackets.setLocale = function (locale) {
        if (locale) {
            global.localStorage.setItem("locale", locale);
        } else {
            global.localStorage.removeItem("locale");
        }
    };

    // Loading extensions requires creating new require.js contexts, which
    // requires access to the global 'require' object that always gets hidden
    // by the 'require' in the AMD wrapper. We store this in the brackets
    // object here so that the ExtensionLoader doesn't have to have access to
    // the global object.
    global.brackets.libRequire = global.require;

    // Also store our current require.js context (the one that loads brackets
    // core modules) so that extensions can use it.
    // Note: we change the name to "getModule" because this won't do exactly
    // the same thing as 'require' in AMD-wrapped modules. The extension will
    // only be able to load modules that have already been loaded once.
    global.brackets.getModule = require;

    exports.global = global;
});
<commit_msg>shims for app.showDeveloperTools and app.getElapsedMilliseconds so that brackets can initialize in-browser<commit_after>/*
 * Copyright (c) 2012 Adobe Systems Incorporated. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */
/*global define */

/**
 * Initializes the global "brackets" variable and it's properties.
 * Modules should not access the global.brackets object until either
 * (a) the module requires this module, i.e. require("utils/Global") or
 * (b) the module receives a "ready" callback from the utils/AppReady module.
 */
define(function (require, exports, module) {
    "use strict";

    var packageJSON = require("text!package.json");

    // Define core brackets namespace if it isn't already defined
    //
    // We can't simply do 'brackets = {}' to define it in the global namespace because
    // we're in "use strict" mode. Most likely, 'window' will always point to the global
    // object when this code is running. However, in case it isn't (e.g. if we're running
    // inside Node for CI testing) we use this trick to get the global object.
    //
    // Taken from:
    //   http://stackoverflow.com/questions/3277182/how-to-get-the-global-object-in-javascript
    var Fn = Function, global = (new Fn("return this"))();
    if (!global.brackets) {
        global.brackets = {};
    }

    // Parse src/config.json
    try {
        global.brackets.metadata = JSON.parse(packageJSON);
        global.brackets.config = global.brackets.metadata.config;
    } catch (err) {
        console.log(err);
    }

    // Uncomment the following line to force all low level file i/o routines to complete
    // asynchronously. This should only be done for testing/debugging.
    // NOTE: Make sure this line is commented out again before committing!
    //brackets.forceAsyncCallbacks = true;

    // Load native shell when brackets is run in a native shell rather than the browser
    // TODO: (issue #266) load conditionally
    global.brackets.shellAPI = require("utils/ShellAPI");

    global.brackets.inBrowser = !global.brackets.hasOwnProperty("fs");

    if (global.navigator.platform === "MacIntel" || global.navigator.platform === "MacPPC") {
        global.brackets.platform = "mac";
    } else if (global.navigator.platform.indexOf("Linux") >= 0) {
        global.brackets.platform = "linux";
    } else {
        global.brackets.platform = "win";
    }

    global.brackets.getLocale = function () {
        // By default use the locale that was determined in brackets.js
        return global.localStorage.getItem("locale") || global.require.s.contexts._.config.locale;
    };

    global.brackets.setLocale = function (locale) {
        if (locale) {
            global.localStorage.setItem("locale", locale);
        } else {
            global.localStorage.removeItem("locale");
        }
    };

    // Shims for brackets.app when running in-browser
    if (!global.brackets.app) {
        var app = {},
            startTime = new Date().getMilliseconds();

        app.showDeveloperTools = false;

        app.getElapsedMilliseconds = function () {
            return new Date().getMilliseconds() - startTime;
        };

        global.brackets.app = app;
    }

    // Loading extensions requires creating new require.js contexts, which
    // requires access to the global 'require' object that always gets hidden
    // by the 'require' in the AMD wrapper. We store this in the brackets
    // object here so that the ExtensionLoader doesn't have to have access to
    // the global object.
    global.brackets.libRequire = global.require;

    // Also store our current require.js context (the one that loads brackets
    // core modules) so that extensions can use it.
    // Note: we change the name to "getModule" because this won't do exactly
    // the same thing as 'require' in AMD-wrapped modules. The extension will
    // only be able to load modules that have already been loaded once.
    global.brackets.getModule = require;

    exports.global = global;
});
<|endoftext|>


<commit_before>module.exports = {
  siteName: 'AntD Admin',
  copyright: 'Ant Design Admin  © 2018 zuiidea',
  logoPath: '/logo.svg',
  apiPrefix: '/api/v1',
  fixedHeader: true, // sticky primary layout header

  /* Layout configuration, specify which layout to use for route. */
  layouts: [
    {
      name: 'primary',
      include: [/.*/],
      exlude: [/(\/(en|zh))*\/login/],
    },
  ],

  /* I18n configuration, `languages` and `defaultLanguage` are required currently. */
  i18n: {
    /* Countrys flags: https://www.flaticon.com/packs/countrys-flags */
    languages: [
      {
        key: 'pt-br',
        title: 'Português',
        flag: '/brazil.svg',
      },
      {
        key: 'en',
        title: 'English',
        flag: '/america.svg',
      },
      {
        key: 'zh',
        title: '中文',
        flag: '/china.svg',
      },
    ],
    defaultLanguage: 'pt-br',
  },
}
<commit_msg>reset default lang to en<commit_after>module.exports = {
  siteName: 'AntD Admin',
  copyright: 'Ant Design Admin  © 2018 zuiidea',
  logoPath: '/logo.svg',
  apiPrefix: '/api/v1',
  fixedHeader: true, // sticky primary layout header

  /* Layout configuration, specify which layout to use for route. */
  layouts: [
    {
      name: 'primary',
      include: [/.*/],
      exlude: [/(\/(en|zh))*\/login/],
    },
  ],

  /* I18n configuration, `languages` and `defaultLanguage` are required currently. */
  i18n: {
    /* Countrys flags: https://www.flaticon.com/packs/countrys-flags */
    languages: [
      {
        key: 'pt-br',
        title: 'Português',
        flag: '/brazil.svg',
      },
      {
        key: 'en',
        title: 'English',
        flag: '/america.svg',
      },
      {
        key: 'zh',
        title: '中文',
        flag: '/china.svg',
      },
    ],
    defaultLanguage: 'en',
  },
}
<|endoftext|>


<commit_before>module.exports = {
	user:{
		name:{type:String,required:true},
		password:{type:String,required:true},
                sex:{type:String,required:false}
	},
        question:{
                title:{type:String,required:true},
                content:{type:String,required:true}
        }
};
<commit_msg>new object<commit_after>module.exports = {
	user:{
		name:{type:String,required:true},
		password:{type:String,required:true},
                sex:{type:String,required:false}
	},
        question:{
                title:{type:String,required:true},
                content:{type:String,required:true},
             	time:{type:String,required:true},
		name:{type:String,required:true}
        }
};
<|endoftext|>


<commit_before>/*
    Redshift jQuery plugin

    Provides access to .play, .move and .track properties on an jQuery object.
    Uses that jQuery object to store a unqiue Redshift instance.

    .redshift() method used for other Redshift functions, ie $('#element').redshift('stop')
*/
"use strict";

var loadPlugins = function (redshift) {
    var KEY = require('../opts/keys.js'),
        utils = require('../utils/utils.js'),

        /*
            Get Redshift instance from jQuery object

            @param [jQuery element]
        */
        getInstance = function ($element) {
            var instance = $element.data(KEY.REDSHIFT);

            if (!instance) {
                instance = redshift.get();
                instance.data(KEY.JQUERY_ELEMENT, $element);
                $element.data(KEY.REDSHIFT, instance);
            }

            return instance;
        },

        /*
            Execute Action function

            @param [jQuery element]: jQuery element to check for Redshift instance
            @param [string]: Action function to call
            @param [...arguments]
        */
        execute = function ($element, action, arg1, arg2, arg3) {
            $element.each(function () {
                getInstance($(this))[action](arg1, arg2, arg3);
            });
        };

    $.fn.play = function () {
        execute(this, 'play', arguments[0], arguments[1]);

        return this;
    };

    $.fn.run = function () {
        execute(this, 'run', arguments[0], arguments[1]);

        return this;
    };

    $.fn.track = function () {
        execute(this, 'track', arguments[0], arguments[1], arguments[2]);

        return this;
    };

    $.fn.redshift = function (action) {
        if (action) {
            execute(this, action, arguments[1], arguments[2]);
            return this;
        } else {
            return getInstance(this);
        }
    };
};

module.exports = {
    featureCheck: function (redshift) {
        if (window.jQuery) {
            loadPlugins(redshift);
        }
    }
};<commit_msg>.redshift() returns action<commit_after>/*
    Redshift jQuery plugin

    Provides access to .play, .move and .track properties on an jQuery object.
    Uses that jQuery object to store a unqiue Redshift instance.

    .redshift() method used for other Redshift functions, ie $('#element').redshift('stop')
*/
"use strict";

var loadPlugins = function (redshift) {
    var KEY = require('../opts/keys.js'),
        utils = require('../utils/utils.js'),

        /*
            Get Redshift instance from jQuery object

            @param [jQuery element]
        */
        getInstance = function ($element) {
            var instance = $element.data(KEY.REDSHIFT);

            if (!instance) {
                instance = redshift.get();
                instance.data(KEY.JQUERY_ELEMENT, $element);
                $element.data(KEY.REDSHIFT, instance);
            }

            return instance;
        },

        /*
            Execute Action function

            @param [jQuery element]: jQuery element to check for Redshift instance
            @param [string]: Action function to call
            @param [...arguments]
        */
        execute = function ($element, action, arg1, arg2, arg3) {
            $element.each(function () {
                getInstance($(this))[action](arg1, arg2, arg3);
            });
        };

    $.fn.play = function () {
        execute(this, 'play', arguments[0], arguments[1]);

        return this;
    };

    $.fn.run = function () {
        execute(this, 'run', arguments[0], arguments[1]);

        return this;
    };

    $.fn.track = function () {
        execute(this, 'track', arguments[0], arguments[1], arguments[2]);

        return this;
    };

    $.fn.redshift = function (action) {
        if (action) {
            execute(this, action, arguments[1], arguments[2]);
            return this;
        } else {
            return getInstance($(this));
        }
    };
};

module.exports = {
    featureCheck: function (redshift) {
        if (window.jQuery) {
            loadPlugins(redshift);
        }
    }
};<|endoftext|>


<commit_before>const combinePaths = (...paths) => {
  return paths.join('/').replace(/\/+/g, '/');
}

const flattenTabNestedRoutes = (pageRoute, tabRoute, tabNestedRoutes) => {
	return tabNestedRoutes.map(tabNestedRoute => {
    return {
      path: combinePaths(pageRoute.path, tabRoute.path, tabNestedRoute.path),
      pagePath: pageRoute.path,
      component: pageRoute.component,
      tab: {
        tabId: tabRoute.tabId,
        component: tabNestedRoute.component
      }
    }
	});
};

const flattenTabRoutes = (pageRoute, tabRoutes) => {
	return tabRoutes.reduce((accumulatedFlattenedRoutes, nextTabRoute) => {
		let flattenedTabRoutes;

		if (nextTabRoute.routes) {
			flattenedTabRoutes = flattenTabNestedRoutes(pageRoute, nextTabRoute, nextTabRoute.routes);
		} else {
			flattenedTabRoutes = [{
        path: combinePaths(pageRoute.path, nextTabRoute.path),
        pagePath: pageRoute.path,
				component: pageRoute.component,
				tab: {
					tabId: nextTabRoute.tabId,
					component: nextTabRoute.component
				}
			}];
		}

		return  [
			...accumulatedFlattenedRoutes,
			...flattenedTabRoutes
		];
	}, []);
};

const flattenRoutes = (routes) => {
	return routes.reduce((accumulatedFlattenedRoutes, nextRoute) => {
		let flattenedNextRoute;

		if (nextRoute.tabs) {
			flattenedNextRoute = flattenTabRoutes(nextRoute, nextRoute.tabs);
		} else {
			flattenedNextRoute = [Object.assign({}, nextRoute, {
        pagePath: nextRoute.path
      })];
		}

		return [
			...accumulatedFlattenedRoutes,
			...flattenedNextRoute
		];
	}, []);
};

const parseRoute = str => {
  var parts = [];
  str.split('/').forEach(function (part) {
    if (part !== '') {
      if (part.indexOf(':') === 0) {
        parts.push({name: part.replace(':', '')});
      }
      else parts.push(part);
    }
  });
  return parts;
}

function handleRouteChangeFromFramework7(view, options, changeRouteCallback) {
  if (!view.allowPageChange) return false;

  var url = options.url;
  var pageElement = options.pageElement;

  if (url && pageElement || !url || url === '#') {
    return true;
  }

  var inHistory = view.history.indexOf(url) >= 0;
  var inDomCache = view.pagesCache[url];

  if (inHistory && inDomCache) return true;

  return changeRouteCallback(url, view, options);
}

export default class Framework7Router {
  constructor(originalRoutes, framework7, dom7) {
    this.routeChangeHandler = null;
    this.routes = flattenRoutes(originalRoutes);
    this.framework7 = framework7;
    this.dom7 = dom7;

    //Hook router into Framework7 routing events
    const initialPreroute = framework7.params.preroute;

    framework7.params.routes = originalRoutes;
    framework7.params.routerRemoveTimeout = true;
    framework7.params.preroute = (view, options) => {
      var passToVueRouter = true;

      if (initialPreroute) {
        passToVueRouter = initialPreroute(view, options);
      }

      if (passToVueRouter) {
        return handleRouteChangeFromFramework7(view, options, this.changeRoute.bind(this));
      } else {
        return false;
      }
    };
  }

  setRouteChangeHandler(routeChangeHandler) {
    this.routeChangeHandler = routeChangeHandler;
  }

  changeRoute(url, view = null, options) {
    const getMainView = () => this.framework7.views && this.framework7.views.reduce((mainView, nextView) => {
        if (nextView.main) {
            return nextView;
        } else {
            return mainView;
        }
    }, null);

    const matchingRoute = this.findMatchingRoute(url);

    if (!matchingRoute) return true;

    return this.routeChangeHandler(
      Object.assign({}, matchingRoute, {
        view: view || getMainView(),
        options,
        router: this
      })
    );
  }

  findMatchingRoute(url) {
    var matchingRoute;
    if (!url) return matchingRoute;

    var routes = this.routes;
    var query = this.dom7.parseUrlQuery(url);
    var hash = url.split('#')[1];
    var params = {};
    var path = url.split('#')[0].split('?')[0];
    var urlParts = path.split('/').filter(function (part) {
      if (part !== '') return part;
    });

    var i, j, k;
    for (i = 0; i < routes.length; i++) {
      if (matchingRoute) continue;
      var route = routes[i];
      var parsedRoute = parseRoute(route.path);
      if (parsedRoute.length !== urlParts.length) continue;
      var matchedParts = 0;
      for (j = 0; j < parsedRoute.length; j++) {
          if (typeof parsedRoute[j] === 'string' && urlParts[j] === parsedRoute[j]) matchedParts ++;
          if (typeof parsedRoute[j] === 'object') {
            params[parsedRoute[j].name] = urlParts[j];
            matchedParts ++;
          }
      }
      if (matchedParts === urlParts.length) {
        matchingRoute = {
          query: query,
          hash: hash,
          params: params,
          url: url,
          path: path,
          route: route
        };
      }
    }
    return matchingRoute;
  }
}<commit_msg>fixes #96, routes fall back to default parameters if not initialized<commit_after>const combinePaths = (...paths) => {
  return paths.join('/').replace(/\/+/g, '/');
}

const flattenTabNestedRoutes = (pageRoute, tabRoute, tabNestedRoutes) => {
	return tabNestedRoutes.map(tabNestedRoute => {
    return {
      path: combinePaths(pageRoute.path, tabRoute.path, tabNestedRoute.path),
      pagePath: pageRoute.path,
      component: pageRoute.component,
      tab: {
        tabId: tabRoute.tabId,
        component: tabNestedRoute.component
      }
    }
	});
};

const flattenTabRoutes = (pageRoute, tabRoutes) => {
	return tabRoutes.reduce((accumulatedFlattenedRoutes, nextTabRoute) => {
		let flattenedTabRoutes;

		if (nextTabRoute.routes) {
			flattenedTabRoutes = flattenTabNestedRoutes(pageRoute, nextTabRoute, nextTabRoute.routes);
		} else {
			flattenedTabRoutes = [{
        path: combinePaths(pageRoute.path, nextTabRoute.path),
        pagePath: pageRoute.path,
				component: pageRoute.component,
				tab: {
					tabId: nextTabRoute.tabId,
					component: nextTabRoute.component
				}
			}];
		}

		return  [
			...accumulatedFlattenedRoutes,
			...flattenedTabRoutes
		];
	}, []);
};

const flattenRoutes = (routes = []) => {
	return routes.reduce((accumulatedFlattenedRoutes, nextRoute) => {
		let flattenedNextRoute;

		if (nextRoute.tabs) {
			flattenedNextRoute = flattenTabRoutes(nextRoute, nextRoute.tabs);
		} else {
			flattenedNextRoute = [Object.assign({}, nextRoute, {
        pagePath: nextRoute.path
      })];
		}

		return [
			...accumulatedFlattenedRoutes,
			...flattenedNextRoute
		];
	}, []);
};

const parseRoute = str => {
  var parts = [];
  str.split('/').forEach(function (part) {
    if (part !== '') {
      if (part.indexOf(':') === 0) {
        parts.push({name: part.replace(':', '')});
      }
      else parts.push(part);
    }
  });
  return parts;
}

function handleRouteChangeFromFramework7(view, options, changeRouteCallback) {
  if (!view.allowPageChange) return false;

  var url = options.url;
  var pageElement = options.pageElement;

  if (url && pageElement || !url || url === '#') {
    return true;
  }

  var inHistory = view.history.indexOf(url) >= 0;
  var inDomCache = view.pagesCache[url];

  if (inHistory && inDomCache) return true;

  return changeRouteCallback(url, view, options);
}

export default class Framework7Router {
  constructor(originalRoutes, framework7, dom7) {
    this.routeChangeHandler = null;
    this.routes = flattenRoutes(originalRoutes);
    this.framework7 = framework7;
    this.dom7 = dom7;

    //Hook router into Framework7 routing events
    const initialPreroute = framework7.params.preroute;

    framework7.params.routes = originalRoutes;
    framework7.params.routerRemoveTimeout = true;
    framework7.params.preroute = (view, options) => {
      var passToVueRouter = true;

      if (initialPreroute) {
        passToVueRouter = initialPreroute(view, options);
      }

      if (passToVueRouter) {
        return handleRouteChangeFromFramework7(view, options, this.changeRoute.bind(this));
      } else {
        return false;
      }
    };
  }

  setRouteChangeHandler(routeChangeHandler) {
    this.routeChangeHandler = routeChangeHandler;
  }

  changeRoute(url, view = null, options) {
    const getMainView = () => this.framework7.views && this.framework7.views.reduce((mainView, nextView) => {
        if (nextView.main) {
            return nextView;
        } else {
            return mainView;
        }
    }, null);

    const matchingRoute = this.findMatchingRoute(url);

    if (!matchingRoute) return true;

    return this.routeChangeHandler(
      Object.assign({}, matchingRoute, {
        view: view || getMainView(),
        options,
        router: this
      })
    );
  }

  findMatchingRoute(url) {
    var matchingRoute;
    if (!url) return matchingRoute;

    var routes = this.routes;
    var query = this.dom7.parseUrlQuery(url);
    var hash = url.split('#')[1];
    var params = {};
    var path = url.split('#')[0].split('?')[0];
    var urlParts = path.split('/').filter(function (part) {
      if (part !== '') return part;
    });

    var i, j, k;
    for (i = 0; i < routes.length; i++) {
      if (matchingRoute) continue;
      var route = routes[i];
      var parsedRoute = parseRoute(route.path);
      if (parsedRoute.length !== urlParts.length) continue;
      var matchedParts = 0;
      for (j = 0; j < parsedRoute.length; j++) {
          if (typeof parsedRoute[j] === 'string' && urlParts[j] === parsedRoute[j]) matchedParts ++;
          if (typeof parsedRoute[j] === 'object') {
            params[parsedRoute[j].name] = urlParts[j];
            matchedParts ++;
          }
      }
      if (matchedParts === urlParts.length) {
        matchingRoute = {
          query: query,
          hash: hash,
          params: params,
          url: url,
          path: path,
          route: route
        };
      }
    }
    return matchingRoute;
  }
}<|endoftext|>


<commit_before>export default {
  active: {
    borderStyle: 'solid',
    backgroundColor: '#eee'
  },
  accepted: {
    borderStyle: 'solid',
    borderColor: '#6c6',
    backgroundColor: '#eee'
  },
  rejected: {
    borderStyle: 'solid',
    borderColor: '#c66',
    backgroundColor: '#eee'
  },
  default: {
    width: 200,
    height: 200,
    borderWidth: 2,
    borderColor: '#666',
    borderStyle: 'dashed',
    borderRadius: 5
  },
  disabled: {
    opacity: 0.5
  }
}
<commit_msg>refactor: remove dead code<commit_after><|endoftext|>


<commit_before>/* @flow */
import curry from './curry'
import reduce from './reduce'

/**
 *
 * @param {string} prop the property to be updated
 * @param {*} val the new value to be applied
 * @param {Array|Object} obj the list or object to update on
 * @returns {Array|Object} returns an updated object or list
 * @example
 *
 *    set(1, 3, [1, 2]) // [1, 3]
 *    set('id', 2, {id: 1}) // {id: 2}
 */
function set(prop: string|number, val: any, obj: Object|Array<any>): Object|Array<any> {
  const cloned = reduce((o, v, k) => {
    o[k] = v
    return o
  }, Array.isArray(obj) ? [] : {}, obj)
  cloned[prop] = val
  return cloned
}

/**
 *
 * @param {Array} path The path to find the value to be updated
 * @param {*} val the new value to be applied
 * @param {Array|Object} obj the list or object to update on
 * @returns {Array|Object} returns an updated object or list
 * @example
 *
 *    update(0, 3, [1, 2]) // [3, 2]
 *    update([1, 2], 3, [1, [1, 2]]) // [1, [1, 2, 3]]
 *    update(['a', 'b'], 2, {a: {b: 1}}) // {a: {b: 2}}
 *
 */
function update(path: Array<string|number>|number|string, val: any, obj: Object|Array<any>): Object|Array<any> {
  if (typeof path === 'string' || typeof path === 'number') {
    return set(path, val, obj)
  }
  if (!Array.isArray(path) || path.length < 1) {
    return obj
  }

  const [idx, ...rest] = path
  if (path.length > 1) {
    const next = (obj && obj.hasOwnProperty(idx)) ? obj[idx] : (typeof idx === 'number') ? [] : {}
    val = update(rest, val, next)
  }

  return set(idx, val, obj)

}

export default curry(update)<commit_msg>Minor change<commit_after>/* @flow */
import curry from './curry'
import reduce from './reduce'

/**
 *
 * @param {string} key the property to be updated
 * @param {*} val the new value to be applied
 * @param {Array|Object} obj the list or object to update on
 * @returns {Array|Object} returns an updated object or list
 * @example
 *
 *    set(1, 3, [1, 2]) // [1, 3]
 *    set('id', 2, {id: 1}) // {id: 2}
 */
function set(key: string|number, val: any, obj: Object|Array<any>): Object|Array<any> {
  const cloned = reduce((o, v, k) => {
    o[k] = v
    return o
  }, Array.isArray(obj) ? [] : {}, obj)
  cloned[key] = val
  return cloned
}

/**
 *
 * @param {Array} path The path to find the value to be updated
 * @param {*} val the new value to be applied
 * @param {Array|Object} obj the list or object to update on
 * @returns {Array|Object} returns an updated object or list
 * @example
 *
 *    update(0, 3, [1, 2]) // [3, 2]
 *    update([1, 2], 3, [1, [1, 2]]) // [1, [1, 2, 3]]
 *    update(['a', 'b'], 2, {a: {b: 1}}) // {a: {b: 2}}
 *
 */
function update(path: Array<string|number>|number|string, val: any, obj: Object|Array<any>): Object|Array<any> {
  if (typeof path === 'string' || typeof path === 'number') {
    return set(path, val, obj)
  }
  if (!Array.isArray(path) || path.length < 1) {
    return obj
  }

  const [idx, ...rest] = path
  if (path.length > 1) {
    const next = (obj && obj.hasOwnProperty(idx)) ? obj[idx] : (typeof idx === 'number') ? [] : {}
    val = update(rest, val, next)
  }

  return set(idx, val, obj)

}

export default curry(update)<|endoftext|>


<commit_before>/**
* @version: 1.0
* @author: Dan Grossman http://www.dangrossman.info/
* @date: 2012-08-20
* @copyright: Copyright (c) 2012 Dan Grossman. All rights reserved.
* @license: Licensed under Apache License v2.0. See http://www.apache.org/licenses/LICENSE-2.0
* @website: http://www.improvely.com/
*/
!function ($) {

    var DateRangePicker = function (element, options, cb) {
        var hasOptions = typeof options == 'object'
        var localeObject;

        //state
        this.startDate = Date.today();
        this.endDate = Date.today();
        this.changed = false;
        this.ranges = {};
        this.opens = 'right';
        this.cb = function () { };
        this.format = 'MM/dd/yyyy';
        this.locale = {
            applyLabel:"Apply",
            fromLabel:"From",
            toLabel:"To",
            customRangeLabel:"Custom Range",
            daysOfWeek:['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr','Sa']
        };

        localeObject = this.locale;

        this.leftCalendar = {
            month: Date.today().set({ day: 1, month: this.startDate.getMonth(), year: this.startDate.getFullYear() }),
            calendar: Array()
        };

        this.rightCalendar = {
            month: Date.today().set({ day: 1, month: this.endDate.getMonth(), year: this.endDate.getFullYear() }),
            calendar: Array()
        };

        //element that triggered the date range picker
        this.element = $(element);

        if (this.element.hasClass('pull-right'))
            this.opens = 'left';

        if (this.element.is('input')) {
            this.element.on({
                click: $.proxy(this.show, this),
                focus: $.proxy(this.show, this),
                blur: $.proxy(this.hide, this)
            });
        } else {
            this.element.on('click', $.proxy(this.show, this));
        }

        if (hasOptions) {
            if(typeof options.locale == 'object') {
                $.each(localeObject, function (property, value) {
                    localeObject[property] = options.locale[property] || value;
                });
            }
        }

        var DRPTemplate = '
' +
                '

' +
                '

' +
                '
' +
                  '
' +
                    '
' +
                      '' + this.locale.fromLabel + '' +
                      '<input class="input-mini" type="text" name="daterangepicker_start" value="" disabled="disabled" />' +
                    '
' +
                    '
' +
                      '' + this.locale.toLabel + '' +
                      '<input class="input-mini" type="text" name="daterangepicker_end" value="" disabled="disabled" />' +
                    '
' +
                    '<button class="btn btn-small btn-success" disabled="disabled">' + this.locale.applyLabel + '</button>' +
                  '
' +
                '
' +
              '
';

        //the date range picker
        this.container = $(DRPTemplate).appendTo('body');

        if (hasOptions) {
            if (typeof options.ranges == 'object') {
                for (var range in options.ranges) {

                    var start = options.ranges[range][0];
                    var end = options.ranges[range][1];

                    if (typeof start == 'string')
                        start = Date.parse(start);
                    if (typeof end == 'string')
                        end = Date.parse(end);

                    this.ranges[range] = [start, end];
                }

                var list = '
';
                for (var range in this.ranges) {
                    list += '
' + range + '
';
                }
                list += '
' + this.locale.customRangeLabel + '
';
                list += '
';
                this.container.find('.ranges').prepend(list);
            }

            if (typeof options.format == 'string')
                this.format = options.format;

            if (typeof options.startDate == 'string')
                this.startDate = Date.parse(options.startDate, this.format);

            if (typeof options.endDate == 'string')
                this.endDate = Date.parse(options.endDate, this.format);

            if (typeof options.opens == 'string')
                this.opens = options.opens;
        }

        if (this.opens == 'right') {
            //swap calendar positions
            var left = this.container.find('.calendar.left');
            var right = this.container.find('.calendar.right');
            left.removeClass('left').addClass('right');
            right.removeClass('right').addClass('left');
        }

        if (typeof options == 'undefined' || typeof options.ranges == 'undefined')
            this.container.find('.calendar').show();

        if (typeof cb == 'function')
            this.cb = cb;

        this.container.addClass('opens' + this.opens);

        //event listeners
        this.container.on('mousedown', $.proxy(this.mousedown, this));
        this.container.find('.calendar').on('click', '.prev', $.proxy(this.clickPrev, this));
        this.container.find('.calendar').on('click', '.next', $.proxy(this.clickNext, this));
        this.container.find('.ranges').on('click', 'button', $.proxy(this.clickApply, this));

        this.container.find('.calendar').on('click', 'td', $.proxy(this.clickDate, this));
        this.container.find('.calendar').on('mouseenter', 'td', $.proxy(this.enterDate, this));
        this.container.find('.calendar').on('mouseleave', 'td', $.proxy(this.updateView, this));

        this.container.find('.ranges').on('click', 'li', $.proxy(this.clickRange, this));
        this.container.find('.ranges').on('mouseenter', 'li', $.proxy(this.enterRange, this));
        this.container.find('.ranges').on('mouseleave', 'li', $.proxy(this.updateView, this));

        this.element.on('keyup', $.proxy(this.updateFromControl, this));

        this.updateView();
        this.updateCalendars();

    };

    DateRangePicker.prototype = {

        constructor: DateRangePicker,

        mousedown: function (e) {
            e.stopPropagation();
            e.preventDefault();
        },

        updateView: function () {
            this.leftCalendar.month.set({ month: this.startDate.getMonth(), year: this.startDate.getFullYear() });
            this.rightCalendar.month.set({ month: this.endDate.getMonth(), year: this.endDate.getFullYear() });

            this.container.find('input[name=daterangepicker_start]').val(this.startDate.toString(this.format));
            this.container.find('input[name=daterangepicker_end]').val(this.endDate.toString(this.format));

            if (this.startDate.equals(this.endDate) || this.startDate.isBefore(this.endDate)) {
                this.container.find('button').removeAttr('disabled');
            } else {
                this.container.find('button').attr('disabled', 'disabled');
            }
        },

        updateFromControl: function () {
            if (!this.element.is('input')) return;

            var dateString = this.element.val().split(" - ");
            var start = Date.parseExact(dateString[0], this.format);
            var end = Date.parseExact(dateString[1], this.format);

            if (start == null || end == null) return;
            if (end.isBefore(start)) return;

            this.startDate = start;
            this.endDate = end;

            this.updateView();
            this.cb(this.startDate, this.endDate);
            this.updateCalendars();
        },

        notify: function () {
            this.updateView();

            if (this.element.is('input')) {
                this.element.val(this.startDate.toString(this.format) + ' - ' + this.endDate.toString(this.format));
            }
            this.cb(this.startDate, this.endDate);
        },

        move: function () {
            if (this.opens == 'left') {
                this.container.css({
                    top: this.element.offset().top + this.element.outerHeight(),
                    right: $(window).width() - this.element.offset().left - this.element.outerWidth(),
                    left: 'auto'
                });
            } else {
                this.container.css({
                    top: this.element.offset().top + this.element.outerHeight(),
                    left: this.element.offset().left,
                    right: 'auto'
                });
            }
        },

        show: function (e) {
            this.container.show();
            this.move();

            if (e) {
                e.stopPropagation();
                e.preventDefault();
            }

            this.changed = false;

            $(document).on('mousedown', $.proxy(this.hide, this));
        },

        hide: function (e) {
            this.container.hide();
            $(document).off('mousedown', this.hide);

            if (this.changed)
                this.notify();
        },

        enterRange: function (e) {
            var label = e.target.innerHTML;
            if (label == this.locale.customRangeLabel) {
                this.updateView();
            } else {
                var dates = this.ranges[label];
                this.container.find('input[name=daterangepicker_start]').val(dates[0].toString(this.format));
                this.container.find('input[name=daterangepicker_end]').val(dates[1].toString(this.format));
            }
        },

        clickRange: function (e) {
            var label = e.target.innerHTML;
            if (label == this.locale.customRangeLabel) {
                this.container.find('.calendar').show();
            } else {
                var dates = this.ranges[label];

                this.startDate = dates[0];
                this.endDate = dates[1];

                this.leftCalendar.month.set({ month: this.startDate.getMonth(), year: this.startDate.getFullYear() });
                this.rightCalendar.month.set({ month: this.endDate.getMonth(), year: this.endDate.getFullYear() });
                this.updateCalendars();

                this.changed = true;

                this.container.find('.calendar').hide();
                this.hide();
            }
        },

        clickPrev: function (e) {
            var cal = $(e.target).parents('.calendar');
            if (cal.hasClass('left')) {
                this.leftCalendar.month.add({ months: -1 });
            } else {
                this.rightCalendar.month.add({ months: -1 });
            }
            this.updateCalendars();
        },

        clickNext: function (e) {
            var cal = $(e.target).parents('.calendar');
            if (cal.hasClass('left')) {
                this.leftCalendar.month.add({ months: 1 });
            } else {
                this.rightCalendar.month.add({ months: 1 });
            }
            this.updateCalendars();
        },

        enterDate: function (e) {

            var title = $(e.target).attr('title');
            var row = title.substr(1, 1);
            var col = title.substr(3, 1);
            var cal = $(e.target).parents('.calendar');

            if (cal.hasClass('left')) {
                this.container.find('input[name=daterangepicker_start]').val(this.leftCalendar.calendar[row][col].toString(this.format));
            } else {
                this.container.find('input[name=daterangepicker_end]').val(this.rightCalendar.calendar[row][col].toString(this.format));
            }

        },

        clickDate: function (e) {
            var title = $(e.target).attr('title');
            var row = title.substr(1, 1);
            var col = title.substr(3, 1);
            var cal = $(e.target).parents('.calendar');

            if (cal.hasClass('left')) {
                startDate = this.leftCalendar.calendar[row][col];
                endDate = this.endDate;
            } else {
                startDate = this.startDate;
                endDate = this.rightCalendar.calendar[row][col];
            }

            cal.find('td').removeClass('active');

            if (startDate.equals(endDate) || startDate.isBefore(endDate)) {
                $(e.target).addClass('active');
                if (!startDate.equals(this.startDate) || !endDate.equals(this.endDate))
                    this.changed = true;
                this.startDate = startDate;
                this.endDate = endDate;
            }
        },

        clickApply: function (e) {
            this.hide();
        },

        updateCalendars: function () {

            this.leftCalendar.calendar = this.buildCalendar(this.leftCalendar.month.getMonth(), this.leftCalendar.month.getFullYear());
            this.rightCalendar.calendar = this.buildCalendar(this.rightCalendar.month.getMonth(), this.rightCalendar.month.getFullYear());
            this.container.find('.calendar.left').html(this.renderCalendar(this.leftCalendar.calendar, this.startDate));
            this.container.find('.calendar.right').html(this.renderCalendar(this.rightCalendar.calendar, this.endDate));

        },

        buildCalendar: function (month, year) {

            var firstDay = Date.today().set({ day: 1, month: month, year: year });
            var lastMonth = firstDay.clone().add(-1).day().getMonth();
            var lastYear = firstDay.clone().add(-1).day().getFullYear();

            var daysInMonth = Date.getDaysInMonth(year, month);
            var daysInLastMonth = Date.getDaysInMonth(lastYear, lastMonth);

            var dayOfWeek = firstDay.getDay();

            //initialize a 6 rows x 7 columns array for the calendar
            var calendar = Array();
            for (var i = 0; i < 6; i++) {
                calendar[i] = Array();
            }

            //populate the calendar with date objects
            var startDay = daysInLastMonth - dayOfWeek + 1;
            if (dayOfWeek == 0)
                startDay = daysInLastMonth - 6;

            var curDate = Date.today().set({ day: startDay, month: lastMonth, year: lastYear });
            for (var i = 0, col = 0, row = 0; i < 42; i++, col++, curDate = curDate.clone().add(1).day()) {
                if (i > 0 && col % 7 == 0) {
                    col = 0;
                    row++;
                }
                calendar[row][col] = curDate;
            }

            return calendar;

        },

        renderCalendar: function (calendar, selected) {

            var html = '
';
            html += '
';
            html += '
';
            html += '	';
            html += '' + calendar[1][1].toString("MMMM yyyy") + '	';
            html += '	';
            html += '
';
            html += '
';

            $.each(this.locale.daysOfWeek, function (index, dayOfWeek) {
                html += '' + dayOfWeek + '	';
            });

            html += '
';
            html += '
';
            html += '
';

            for (var row = 0; row < 6; row++) {
                html += '
';
                for (var col = 0; col < 7; col++) {
                    var cname = (calendar[row][col].getMonth() == calendar[1][1].getMonth()) ? '' : 'off';
                    if (calendar[row][col].equals(selected))
                        cname = 'active';
                    var title = 'r' + row + 'c' + col;
                    html += '' + calendar[row][col].getDate() + '	';
                }
                html += '
';
            }

            html += '
';
            html += '
';

            return html;

        }

    };

    $.fn.daterangepicker = function (options, cb) {
      this.each(function() {
        new DateRangePicker($(this), options, cb);
      });
      return this;
    };

} (window.jQuery);
<commit_msg>Add the daterangepicker instance to the element's data attribues<commit_after>/**
* @version: 1.0
* @author: Dan Grossman http://www.dangrossman.info/
* @date: 2012-08-20
* @copyright: Copyright (c) 2012 Dan Grossman. All rights reserved.
* @license: Licensed under Apache License v2.0. See http://www.apache.org/licenses/LICENSE-2.0
* @website: http://www.improvely.com/
*/
!function ($) {

    var DateRangePicker = function (element, options, cb) {
        var hasOptions = typeof options == 'object'
        var localeObject;

        //state
        this.startDate = Date.today();
        this.endDate = Date.today();
        this.changed = false;
        this.ranges = {};
        this.opens = 'right';
        this.cb = function () { };
        this.format = 'MM/dd/yyyy';
        this.locale = {
            applyLabel:"Apply",
            fromLabel:"From",
            toLabel:"To",
            customRangeLabel:"Custom Range",
            daysOfWeek:['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr','Sa']
        };

        localeObject = this.locale;

        this.leftCalendar = {
            month: Date.today().set({ day: 1, month: this.startDate.getMonth(), year: this.startDate.getFullYear() }),
            calendar: Array()
        };

        this.rightCalendar = {
            month: Date.today().set({ day: 1, month: this.endDate.getMonth(), year: this.endDate.getFullYear() }),
            calendar: Array()
        };

        //element that triggered the date range picker
        this.element = $(element);

        if (this.element.hasClass('pull-right'))
            this.opens = 'left';

        if (this.element.is('input')) {
            this.element.on({
                click: $.proxy(this.show, this),
                focus: $.proxy(this.show, this),
                blur: $.proxy(this.hide, this)
            });
        } else {
            this.element.on('click', $.proxy(this.show, this));
        }

        if (hasOptions) {
            if(typeof options.locale == 'object') {
                $.each(localeObject, function (property, value) {
                    localeObject[property] = options.locale[property] || value;
                });
            }
        }

        var DRPTemplate = '
' +
                '

' +
                '

' +
                '
' +
                  '
' +
                    '
' +
                      '' + this.locale.fromLabel + '' +
                      '<input class="input-mini" type="text" name="daterangepicker_start" value="" disabled="disabled" />' +
                    '
' +
                    '
' +
                      '' + this.locale.toLabel + '' +
                      '<input class="input-mini" type="text" name="daterangepicker_end" value="" disabled="disabled" />' +
                    '
' +
                    '<button class="btn btn-small btn-success" disabled="disabled">' + this.locale.applyLabel + '</button>' +
                  '
' +
                '
' +
              '
';

        //the date range picker
        this.container = $(DRPTemplate).appendTo('body');

        if (hasOptions) {
            if (typeof options.ranges == 'object') {
                for (var range in options.ranges) {

                    var start = options.ranges[range][0];
                    var end = options.ranges[range][1];

                    if (typeof start == 'string')
                        start = Date.parse(start);
                    if (typeof end == 'string')
                        end = Date.parse(end);

                    this.ranges[range] = [start, end];
                }

                var list = '
';
                for (var range in this.ranges) {
                    list += '
' + range + '
';
                }
                list += '
' + this.locale.customRangeLabel + '
';
                list += '
';
                this.container.find('.ranges').prepend(list);
            }

            if (typeof options.format == 'string')
                this.format = options.format;

            if (typeof options.startDate == 'string')
                this.startDate = Date.parse(options.startDate, this.format);

            if (typeof options.endDate == 'string')
                this.endDate = Date.parse(options.endDate, this.format);

            if (typeof options.opens == 'string')
                this.opens = options.opens;
        }

        if (this.opens == 'right') {
            //swap calendar positions
            var left = this.container.find('.calendar.left');
            var right = this.container.find('.calendar.right');
            left.removeClass('left').addClass('right');
            right.removeClass('right').addClass('left');
        }

        if (typeof options == 'undefined' || typeof options.ranges == 'undefined')
            this.container.find('.calendar').show();

        if (typeof cb == 'function')
            this.cb = cb;

        this.container.addClass('opens' + this.opens);

        //event listeners
        this.container.on('mousedown', $.proxy(this.mousedown, this));
        this.container.find('.calendar').on('click', '.prev', $.proxy(this.clickPrev, this));
        this.container.find('.calendar').on('click', '.next', $.proxy(this.clickNext, this));
        this.container.find('.ranges').on('click', 'button', $.proxy(this.clickApply, this));

        this.container.find('.calendar').on('click', 'td', $.proxy(this.clickDate, this));
        this.container.find('.calendar').on('mouseenter', 'td', $.proxy(this.enterDate, this));
        this.container.find('.calendar').on('mouseleave', 'td', $.proxy(this.updateView, this));

        this.container.find('.ranges').on('click', 'li', $.proxy(this.clickRange, this));
        this.container.find('.ranges').on('mouseenter', 'li', $.proxy(this.enterRange, this));
        this.container.find('.ranges').on('mouseleave', 'li', $.proxy(this.updateView, this));

        this.element.on('keyup', $.proxy(this.updateFromControl, this));

        this.updateView();
        this.updateCalendars();

    };

    DateRangePicker.prototype = {

        constructor: DateRangePicker,

        mousedown: function (e) {
            e.stopPropagation();
            e.preventDefault();
        },

        updateView: function () {
            this.leftCalendar.month.set({ month: this.startDate.getMonth(), year: this.startDate.getFullYear() });
            this.rightCalendar.month.set({ month: this.endDate.getMonth(), year: this.endDate.getFullYear() });

            this.container.find('input[name=daterangepicker_start]').val(this.startDate.toString(this.format));
            this.container.find('input[name=daterangepicker_end]').val(this.endDate.toString(this.format));

            if (this.startDate.equals(this.endDate) || this.startDate.isBefore(this.endDate)) {
                this.container.find('button').removeAttr('disabled');
            } else {
                this.container.find('button').attr('disabled', 'disabled');
            }
        },

        updateFromControl: function () {
            if (!this.element.is('input')) return;

            var dateString = this.element.val().split(" - ");
            var start = Date.parseExact(dateString[0], this.format);
            var end = Date.parseExact(dateString[1], this.format);

            if (start == null || end == null) return;
            if (end.isBefore(start)) return;

            this.startDate = start;
            this.endDate = end;

            this.updateView();
            this.cb(this.startDate, this.endDate);
            this.updateCalendars();
        },

        notify: function () {
            this.updateView();

            if (this.element.is('input')) {
                this.element.val(this.startDate.toString(this.format) + ' - ' + this.endDate.toString(this.format));
            }
            this.cb(this.startDate, this.endDate);
        },

        move: function () {
            if (this.opens == 'left') {
                this.container.css({
                    top: this.element.offset().top + this.element.outerHeight(),
                    right: $(window).width() - this.element.offset().left - this.element.outerWidth(),
                    left: 'auto'
                });
            } else {
                this.container.css({
                    top: this.element.offset().top + this.element.outerHeight(),
                    left: this.element.offset().left,
                    right: 'auto'
                });
            }
        },

        show: function (e) {
            this.container.show();
            this.move();

            if (e) {
                e.stopPropagation();
                e.preventDefault();
            }

            this.changed = false;

            $(document).on('mousedown', $.proxy(this.hide, this));
        },

        hide: function (e) {
            this.container.hide();
            $(document).off('mousedown', this.hide);

            if (this.changed)
                this.notify();
        },

        enterRange: function (e) {
            var label = e.target.innerHTML;
            if (label == this.locale.customRangeLabel) {
                this.updateView();
            } else {
                var dates = this.ranges[label];
                this.container.find('input[name=daterangepicker_start]').val(dates[0].toString(this.format));
                this.container.find('input[name=daterangepicker_end]').val(dates[1].toString(this.format));
            }
        },

        clickRange: function (e) {
            var label = e.target.innerHTML;
            if (label == this.locale.customRangeLabel) {
                this.container.find('.calendar').show();
            } else {
                var dates = this.ranges[label];

                this.startDate = dates[0];
                this.endDate = dates[1];

                this.leftCalendar.month.set({ month: this.startDate.getMonth(), year: this.startDate.getFullYear() });
                this.rightCalendar.month.set({ month: this.endDate.getMonth(), year: this.endDate.getFullYear() });
                this.updateCalendars();

                this.changed = true;

                this.container.find('.calendar').hide();
                this.hide();
            }
        },

        clickPrev: function (e) {
            var cal = $(e.target).parents('.calendar');
            if (cal.hasClass('left')) {
                this.leftCalendar.month.add({ months: -1 });
            } else {
                this.rightCalendar.month.add({ months: -1 });
            }
            this.updateCalendars();
        },

        clickNext: function (e) {
            var cal = $(e.target).parents('.calendar');
            if (cal.hasClass('left')) {
                this.leftCalendar.month.add({ months: 1 });
            } else {
                this.rightCalendar.month.add({ months: 1 });
            }
            this.updateCalendars();
        },

        enterDate: function (e) {

            var title = $(e.target).attr('title');
            var row = title.substr(1, 1);
            var col = title.substr(3, 1);
            var cal = $(e.target).parents('.calendar');

            if (cal.hasClass('left')) {
                this.container.find('input[name=daterangepicker_start]').val(this.leftCalendar.calendar[row][col].toString(this.format));
            } else {
                this.container.find('input[name=daterangepicker_end]').val(this.rightCalendar.calendar[row][col].toString(this.format));
            }

        },

        clickDate: function (e) {
            var title = $(e.target).attr('title');
            var row = title.substr(1, 1);
            var col = title.substr(3, 1);
            var cal = $(e.target).parents('.calendar');

            if (cal.hasClass('left')) {
                startDate = this.leftCalendar.calendar[row][col];
                endDate = this.endDate;
            } else {
                startDate = this.startDate;
                endDate = this.rightCalendar.calendar[row][col];
            }

            cal.find('td').removeClass('active');

            if (startDate.equals(endDate) || startDate.isBefore(endDate)) {
                $(e.target).addClass('active');
                if (!startDate.equals(this.startDate) || !endDate.equals(this.endDate))
                    this.changed = true;
                this.startDate = startDate;
                this.endDate = endDate;
            }
        },

        clickApply: function (e) {
            this.hide();
        },

        updateCalendars: function () {

            this.leftCalendar.calendar = this.buildCalendar(this.leftCalendar.month.getMonth(), this.leftCalendar.month.getFullYear());
            this.rightCalendar.calendar = this.buildCalendar(this.rightCalendar.month.getMonth(), this.rightCalendar.month.getFullYear());
            this.container.find('.calendar.left').html(this.renderCalendar(this.leftCalendar.calendar, this.startDate));
            this.container.find('.calendar.right').html(this.renderCalendar(this.rightCalendar.calendar, this.endDate));

        },

        buildCalendar: function (month, year) {

            var firstDay = Date.today().set({ day: 1, month: month, year: year });
            var lastMonth = firstDay.clone().add(-1).day().getMonth();
            var lastYear = firstDay.clone().add(-1).day().getFullYear();

            var daysInMonth = Date.getDaysInMonth(year, month);
            var daysInLastMonth = Date.getDaysInMonth(lastYear, lastMonth);

            var dayOfWeek = firstDay.getDay();

            //initialize a 6 rows x 7 columns array for the calendar
            var calendar = Array();
            for (var i = 0; i < 6; i++) {
                calendar[i] = Array();
            }

            //populate the calendar with date objects
            var startDay = daysInLastMonth - dayOfWeek + 1;
            if (dayOfWeek == 0)
                startDay = daysInLastMonth - 6;

            var curDate = Date.today().set({ day: startDay, month: lastMonth, year: lastYear });
            for (var i = 0, col = 0, row = 0; i < 42; i++, col++, curDate = curDate.clone().add(1).day()) {
                if (i > 0 && col % 7 == 0) {
                    col = 0;
                    row++;
                }
                calendar[row][col] = curDate;
            }

            return calendar;

        },

        renderCalendar: function (calendar, selected) {

            var html = '
';
            html += '
';
            html += '
';
            html += '	';
            html += '' + calendar[1][1].toString("MMMM yyyy") + '	';
            html += '	';
            html += '
';
            html += '
';

            $.each(this.locale.daysOfWeek, function (index, dayOfWeek) {
                html += '' + dayOfWeek + '	';
            });

            html += '
';
            html += '
';
            html += '
';

            for (var row = 0; row < 6; row++) {
                html += '
';
                for (var col = 0; col < 7; col++) {
                    var cname = (calendar[row][col].getMonth() == calendar[1][1].getMonth()) ? '' : 'off';
                    if (calendar[row][col].equals(selected))
                        cname = 'active';
                    var title = 'r' + row + 'c' + col;
                    html += '' + calendar[row][col].getDate() + '	';
                }
                html += '
';
            }

            html += '
';
            html += '
';

            return html;

        }

    };

    $.fn.daterangepicker = function (options, cb) {
      this.each(function() {
        var el = $(this);
        el.data('daterangepicker', new DateRangePicker(el, options, cb));
      });
      return this;
    };

} (window.jQuery);
<|endoftext|>