<commit_before>// Copyright 2008 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @fileoverview Defines the goog.module.ModuleInfo class.
 *
 */

goog.provide('goog.module.ModuleInfo');

goog.require('goog.Disposable');
goog.require('goog.async.throwException');
goog.require('goog.functions');
goog.require('goog.html.TrustedResourceUrl');
/** @suppress {extraRequire} */
goog.require('goog.module');
goog.require('goog.module.BaseModule');
goog.require('goog.module.ModuleLoadCallback');

goog.forwardDeclare('goog.loader.AbstractModuleManager.FailureType');

/**
 * A ModuleInfo object is used by the ModuleManager to hold information about a
 * module of js code that may or may not yet be loaded into the environment.
 *
 * @param {Array<string>} deps Ids of the modules that must be loaded before
 *     this one. The ids must be in dependency order (i.e. if the ith module
 *     depends on the jth module, then i > j).
 * @param {string} id The module's ID.
 * @constructor
 * @extends {goog.Disposable}
 * @final
 */
goog.module.ModuleInfo = function(deps, id) {
  goog.Disposable.call(this);

  /**
   * A list of the ids of the modules that must be loaded before this module.
   * @type {Array<string>}
   * @private
   */
  this.deps_ = deps;

  /**
   * The module's ID.
   * @type {string}
   * @private
   */
  this.id_ = id;

  /**
   * Callbacks to execute once this module is loaded.
   * @type {Array<goog.module.ModuleLoadCallback>}
   * @private
   */
  this.onloadCallbacks_ = [];

  /**
   * Callbacks to execute if the module load errors.
   * @type {Array<goog.module.ModuleLoadCallback>}
   * @private
   */
  this.onErrorCallbacks_ = [];

  /**
   * Early callbacks to execute once this module is loaded. Called after
   * module initialization but before regular onload callbacks.
   * @type {Array<goog.module.ModuleLoadCallback>}
   * @private
   */
  this.earlyOnloadCallbacks_ = [];
};
goog.inherits(goog.module.ModuleInfo, goog.Disposable);

/**
 * The uris that can be used to retrieve this module's code.
 * @type {?Array<!goog.html.TrustedResourceUrl>}
 * @private
 */
goog.module.ModuleInfo.prototype.uris_ = null;

/**
 * The constructor to use to instantiate the module object after the module
 * code is loaded. This must be either goog.module.BaseModule or a subclass of
 * it.
 * @type {Function}
 * @private
 */
goog.module.ModuleInfo.prototype.moduleConstructor_ = goog.module.BaseModule;

/**
 * The module object. This will be null until the module is loaded.
 * @type {goog.module.BaseModule?}
 * @private
 */
goog.module.ModuleInfo.prototype.module_ = null;

/**
 * Gets the dependencies of this module.
 * @return {Array<string>} The ids of the modules that this module depends on.
 */
goog.module.ModuleInfo.prototype.getDependencies = function() {
  return this.deps_;
};

/**
 * Gets the ID of this module.
 * @return {string} The ID.
 */
goog.module.ModuleInfo.prototype.getId = function() {
  return this.id_;
};

/**
 * Sets the uris of this module.
 * @param {!Array<!goog.html.TrustedResourceUrl>} uris Uris for this module's
 *     code.
 */
goog.module.ModuleInfo.prototype.setTrustedUris = function(uris) {
  this.uris_ = uris;
};

/**
 * Gets the uris of this module.
 * @return {!Array<!goog.html.TrustedResourceUrl>} Uris for this module's code.
 */
goog.module.ModuleInfo.prototype.getUris = function() {
  if (!this.uris_) {
    this.uris_ = [];
  }
  return this.uris_;
};

/**
 * Sets the constructor to use to instantiate the module object after the
 * module code is loaded.
 * @param {Function} constructor The constructor of a goog.module.BaseModule
 *     subclass.
 */
goog.module.ModuleInfo.prototype.setModuleConstructor = function(constructor) {
  if (this.moduleConstructor_ === goog.module.BaseModule) {
    this.moduleConstructor_ = constructor;
  } else {
    throw new Error('Cannot set module constructor more than once.');
  }
};

/**
 * Registers a function that should be called after the module is loaded. These
 * early callbacks are called after {@link Module#initialize} is called but
 * before the other callbacks are called.
 * @param {Function} fn A callback function that takes a single argument which
 *    is the module context.
 * @param {Object=} opt_handler Optional handler under whose scope to execute
 *     the callback.
 * @return {!goog.module.ModuleLoadCallback} Reference to the callback
 *     object.
 */
goog.module.ModuleInfo.prototype.registerEarlyCallback = function(
    fn, opt_handler) {
  return this.registerCallback_(this.earlyOnloadCallbacks_, fn, opt_handler);
};

/**
 * Registers a function that should be called after the module is loaded.
 * @param {Function} fn A callback function that takes a single argument which
 *    is the module context.
 * @param {Object=} opt_handler Optional handler under whose scope to execute
 *     the callback.
 * @return {!goog.module.ModuleLoadCallback} Reference to the callback
 *     object.
 */
goog.module.ModuleInfo.prototype.registerCallback = function(fn, opt_handler) {
  return this.registerCallback_(this.onloadCallbacks_, fn, opt_handler);
};

/**
 * Registers a function that should be called if the module load fails.
 * @param {Function} fn A callback function that takes a single argument which
 *    is the failure type.
 * @param {Object=} opt_handler Optional handler under whose scope to execute
 *     the callback.
 * @return {!goog.module.ModuleLoadCallback} Reference to the callback
 *     object.
 */
goog.module.ModuleInfo.prototype.registerErrback = function(fn, opt_handler) {
  return this.registerCallback_(this.onErrorCallbacks_, fn, opt_handler);
};

/**
 * Registers a function that should be called after the module is loaded.
 * @param {Array<goog.module.ModuleLoadCallback>} callbacks The array to
 *     add the callback to.
 * @param {Function} fn A callback function that takes a single argument which
 *     is the module context.
 * @param {Object=} opt_handler Optional handler under whose scope to execute
 *     the callback.
 * @return {!goog.module.ModuleLoadCallback} Reference to the callback
 *     object.
 * @private
 */
goog.module.ModuleInfo.prototype.registerCallback_ = function(
    callbacks, fn, opt_handler) {
  var callback = new goog.module.ModuleLoadCallback(fn, opt_handler);
  callbacks.push(callback);
  return callback;
};

/**
 * Determines whether the module has been loaded.
 * @return {boolean} Whether the module has been loaded.
 */
goog.module.ModuleInfo.prototype.isLoaded = function() {
  return !!this.module_;
};

/**
 * Gets the module.
 * @return {goog.module.BaseModule?} The module if it has been loaded.
 *     Otherwise, null.
 */
goog.module.ModuleInfo.prototype.getModule = function() {
  return this.module_;
};

/**
 * Sets this module as loaded.
 * @param {function() : Object} contextProvider A function that provides the
 *     module context.
 * @return {boolean} Whether any errors occurred while executing the onload
 *     callbacks.
 */
goog.module.ModuleInfo.prototype.onLoad = function(contextProvider) {
  // Instantiate and initialize the module object.
  var module = new this.moduleConstructor_;
  module.initialize(contextProvider());

  // Keep an internal reference to the module.
  this.module_ = module;

  // Fire any early callbacks that were waiting for the module to be loaded.
  var errors =
      !!this.callCallbacks_(this.earlyOnloadCallbacks_, contextProvider());

  // Fire any callbacks that were waiting for the module to be loaded.
  errors =
      errors || !!this.callCallbacks_(this.onloadCallbacks_, contextProvider());

  if (!errors) {
    // Clear the errbacks.
    this.onErrorCallbacks_.length = 0;
  }

  return errors;
};

/**
 * Calls the error callbacks for the module.
 * @param {goog.loader.AbstractModuleManager.FailureType} cause What caused the
 *     error.
 */
goog.module.ModuleInfo.prototype.onError = function(cause) {
  var result = this.callCallbacks_(this.onErrorCallbacks_, cause);
  if (result) {
    // Throw an exception asynchronously. Do not let the exception leak
    // up to the caller, or it will blow up the module loading framework.
    window.setTimeout(
        goog.functions.error('Module errback failures: ' + result), 0);
  }
  this.earlyOnloadCallbacks_.length = 0;
  this.onloadCallbacks_.length = 0;
};

/**
 * Helper to call the callbacks after module load.
 * @param {Array<goog.module.ModuleLoadCallback>} callbacks The callbacks
 *     to call and then clear.
 * @param {*} context The module context.
 * @return {Array<*>} Any errors encountered while calling the callbacks,
 *     or null if there were no errors.
 * @private
 */
goog.module.ModuleInfo.prototype.callCallbacks_ = function(callbacks, context) {
  // NOTE(nicksantos):
  // In practice, there are two error-handling scenarios:
  // 1) The callback does some mandatory initialization of the module.
  // 2) The callback is for completion of some optional UI event.
  // There's no good way to handle both scenarios.
  //
  // Our strategy here is to protect module manager from exceptions, so that
  // the failure of one module doesn't affect the loading of other modules.
  // Errors are thrown outside of the current stack frame, so they still
  // get reported but don't interrupt execution.

  // Call each callback in the order they were registered
  var errors = [];
  for (var i = 0; i < callbacks.length; i++) {
    try {
      callbacks[i].execute(context);
    } catch (e) {
      goog.async.throwException(e);
      errors.push(e);
    }
  }

  // Clear the list of callbacks.
  callbacks.length = 0;
  return errors.length ? errors : null;
};

/** @override */
goog.module.ModuleInfo.prototype.disposeInternal = function() {
  goog.module.ModuleInfo.superClass_.disposeInternal.call(this);
  goog.dispose(this.module_);
};
<commit_msg>When we need to fallback to positive module loading, also tell the module manager that all the loaded modules have already been loaded. Also modified the test to verify this behavior.<commit_after>// Copyright 2008 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @fileoverview Defines the goog.module.ModuleInfo class.
 *
 */

goog.provide('goog.module.ModuleInfo');

goog.require('goog.Disposable');
goog.require('goog.async.throwException');
goog.require('goog.functions');
goog.require('goog.html.TrustedResourceUrl');
/** @suppress {extraRequire} */
goog.require('goog.module');
goog.require('goog.module.BaseModule');
goog.require('goog.module.ModuleLoadCallback');

goog.forwardDeclare('goog.loader.AbstractModuleManager.FailureType');

/**
 * A ModuleInfo object is used by the ModuleManager to hold information about a
 * module of js code that may or may not yet be loaded into the environment.
 *
 * @param {Array<string>} deps Ids of the modules that must be loaded before
 *     this one. The ids must be in dependency order (i.e. if the ith module
 *     depends on the jth module, then i > j).
 * @param {string} id The module's ID.
 * @constructor
 * @extends {goog.Disposable}
 * @final
 */
goog.module.ModuleInfo = function(deps, id) {
  goog.Disposable.call(this);

  /**
   * A list of the ids of the modules that must be loaded before this module.
   * @type {Array<string>}
   * @private
   */
  this.deps_ = deps;

  /**
   * The module's ID.
   * @type {string}
   * @private
   */
  this.id_ = id;

  /**
   * Callbacks to execute once this module is loaded.
   * @type {Array<goog.module.ModuleLoadCallback>}
   * @private
   */
  this.onloadCallbacks_ = [];

  /**
   * Callbacks to execute if the module load errors.
   * @type {Array<goog.module.ModuleLoadCallback>}
   * @private
   */
  this.onErrorCallbacks_ = [];

  /**
   * Early callbacks to execute once this module is loaded. Called after
   * module initialization but before regular onload callbacks.
   * @type {Array<goog.module.ModuleLoadCallback>}
   * @private
   */
  this.earlyOnloadCallbacks_ = [];
};
goog.inherits(goog.module.ModuleInfo, goog.Disposable);

/**
 * The uris that can be used to retrieve this module's code.
 * @type {?Array<!goog.html.TrustedResourceUrl>}
 * @private
 */
goog.module.ModuleInfo.prototype.uris_ = null;

/**
 * The constructor to use to instantiate the module object after the module
 * code is loaded. This must be either goog.module.BaseModule or a subclass of
 * it.
 * @type {Function}
 * @private
 */
goog.module.ModuleInfo.prototype.moduleConstructor_ = goog.module.BaseModule;

/**
 * The module object. This will be null until the module is loaded.
 * @type {goog.module.BaseModule?}
 * @private
 */
goog.module.ModuleInfo.prototype.module_ = null;

/**
 * Gets the dependencies of this module.
 * @return {Array<string>} The ids of the modules that this module depends on.
 */
goog.module.ModuleInfo.prototype.getDependencies = function() {
  return this.deps_;
};

/**
 * Gets the ID of this module.
 * @return {string} The ID.
 */
goog.module.ModuleInfo.prototype.getId = function() {
  return this.id_;
};

/**
 * Sets the uris of this module.
 * @param {!Array<!goog.html.TrustedResourceUrl>} uris Uris for this module's
 *     code.
 */
goog.module.ModuleInfo.prototype.setTrustedUris = function(uris) {
  this.uris_ = uris;
};

/**
 * Gets the uris of this module.
 * @return {!Array<!goog.html.TrustedResourceUrl>} Uris for this module's code.
 */
goog.module.ModuleInfo.prototype.getUris = function() {
  if (!this.uris_) {
    this.uris_ = [];
  }
  return this.uris_;
};

/**
 * Sets the constructor to use to instantiate the module object after the
 * module code is loaded.
 * @param {Function} constructor The constructor of a goog.module.BaseModule
 *     subclass.
 */
goog.module.ModuleInfo.prototype.setModuleConstructor = function(constructor) {
  if (this.moduleConstructor_ === goog.module.BaseModule) {
    this.moduleConstructor_ = constructor;
  } else {
    throw new Error('Cannot set module constructor more than once.');
  }
};

/**
 * Registers a function that should be called after the module is loaded. These
 * early callbacks are called after {@link Module#initialize} is called but
 * before the other callbacks are called.
 * @param {Function} fn A callback function that takes a single argument which
 *    is the module context.
 * @param {Object=} opt_handler Optional handler under whose scope to execute
 *     the callback.
 * @return {!goog.module.ModuleLoadCallback} Reference to the callback
 *     object.
 */
goog.module.ModuleInfo.prototype.registerEarlyCallback = function(
    fn, opt_handler) {
  return this.registerCallback_(this.earlyOnloadCallbacks_, fn, opt_handler);
};

/**
 * Registers a function that should be called after the module is loaded.
 * @param {Function} fn A callback function that takes a single argument which
 *    is the module context.
 * @param {Object=} opt_handler Optional handler under whose scope to execute
 *     the callback.
 * @return {!goog.module.ModuleLoadCallback} Reference to the callback
 *     object.
 */
goog.module.ModuleInfo.prototype.registerCallback = function(fn, opt_handler) {
  return this.registerCallback_(this.onloadCallbacks_, fn, opt_handler);
};

/**
 * Registers a function that should be called if the module load fails.
 * @param {Function} fn A callback function that takes a single argument which
 *    is the failure type.
 * @param {Object=} opt_handler Optional handler under whose scope to execute
 *     the callback.
 * @return {!goog.module.ModuleLoadCallback} Reference to the callback
 *     object.
 */
goog.module.ModuleInfo.prototype.registerErrback = function(fn, opt_handler) {
  return this.registerCallback_(this.onErrorCallbacks_, fn, opt_handler);
};

/**
 * Registers a function that should be called after the module is loaded.
 * @param {Array<goog.module.ModuleLoadCallback>} callbacks The array to
 *     add the callback to.
 * @param {Function} fn A callback function that takes a single argument which
 *     is the module context.
 * @param {Object=} opt_handler Optional handler under whose scope to execute
 *     the callback.
 * @return {!goog.module.ModuleLoadCallback} Reference to the callback
 *     object.
 * @private
 */
goog.module.ModuleInfo.prototype.registerCallback_ = function(
    callbacks, fn, opt_handler) {
  var callback = new goog.module.ModuleLoadCallback(fn, opt_handler);
  callbacks.push(callback);
  return callback;
};

/**
 * Determines whether the module has been loaded.
 * @return {boolean} Whether the module has been loaded.
 */
goog.module.ModuleInfo.prototype.isLoaded = function() {
  return !!this.module_;
};

/**
 * Marks the current module as loaded. This is useful for subtractive module
 * loading, where occasionally we need to fallback to normal module loading,
 * and re-fetch the module graph. In this case, we need a way to tell the module
 * manager to mark all modules that are already loaded.
 */
goog.module.ModuleInfo.prototype.setLoaded = function() {
  this.module_ = new goog.module.BaseModule();
};

/**
 * Gets the module.
 * @return {goog.module.BaseModule?} The module if it has been loaded.
 *     Otherwise, null.
 */
goog.module.ModuleInfo.prototype.getModule = function() {
  return this.module_;
};

/**
 * Sets this module as loaded.
 * @param {function() : Object} contextProvider A function that provides the
 *     module context.
 * @return {boolean} Whether any errors occurred while executing the onload
 *     callbacks.
 */
goog.module.ModuleInfo.prototype.onLoad = function(contextProvider) {
  // Instantiate and initialize the module object.
  var module = new this.moduleConstructor_;
  module.initialize(contextProvider());

  // Keep an internal reference to the module.
  this.module_ = module;

  // Fire any early callbacks that were waiting for the module to be loaded.
  var errors =
      !!this.callCallbacks_(this.earlyOnloadCallbacks_, contextProvider());

  // Fire any callbacks that were waiting for the module to be loaded.
  errors =
      errors || !!this.callCallbacks_(this.onloadCallbacks_, contextProvider());

  if (!errors) {
    // Clear the errbacks.
    this.onErrorCallbacks_.length = 0;
  }

  return errors;
};

/**
 * Calls the error callbacks for the module.
 * @param {goog.loader.AbstractModuleManager.FailureType} cause What caused the
 *     error.
 */
goog.module.ModuleInfo.prototype.onError = function(cause) {
  var result = this.callCallbacks_(this.onErrorCallbacks_, cause);
  if (result) {
    // Throw an exception asynchronously. Do not let the exception leak
    // up to the caller, or it will blow up the module loading framework.
    window.setTimeout(
        goog.functions.error('Module errback failures: ' + result), 0);
  }
  this.earlyOnloadCallbacks_.length = 0;
  this.onloadCallbacks_.length = 0;
};

/**
 * Helper to call the callbacks after module load.
 * @param {Array<goog.module.ModuleLoadCallback>} callbacks The callbacks
 *     to call and then clear.
 * @param {*} context The module context.
 * @return {Array<*>} Any errors encountered while calling the callbacks,
 *     or null if there were no errors.
 * @private
 */
goog.module.ModuleInfo.prototype.callCallbacks_ = function(callbacks, context) {
  // NOTE(nicksantos):
  // In practice, there are two error-handling scenarios:
  // 1) The callback does some mandatory initialization of the module.
  // 2) The callback is for completion of some optional UI event.
  // There's no good way to handle both scenarios.
  //
  // Our strategy here is to protect module manager from exceptions, so that
  // the failure of one module doesn't affect the loading of other modules.
  // Errors are thrown outside of the current stack frame, so they still
  // get reported but don't interrupt execution.

  // Call each callback in the order they were registered
  var errors = [];
  for (var i = 0; i < callbacks.length; i++) {
    try {
      callbacks[i].execute(context);
    } catch (e) {
      goog.async.throwException(e);
      errors.push(e);
    }
  }

  // Clear the list of callbacks.
  callbacks.length = 0;
  return errors.length ? errors : null;
};

/** @override */
goog.module.ModuleInfo.prototype.disposeInternal = function() {
  goog.module.ModuleInfo.superClass_.disposeInternal.call(this);
  goog.dispose(this.module_);
};
<|endoftext|>


<commit_before>function initialize_records_form() {
    $('#diskDiameters_lbl').hide();
    $('#reelDiameters_lbl').hide();
    $('#mediaDiameters_lbl').hide();
    $('#tapeThickness_lbl').hide();
    $('#trackTypes_lbl').hide();
    $('#cassetteSize_lbl').hide();
    $("#formatVersion_lbl").hide();
    $('.new #mediaType option[value="' + selectedMediaType + '"]').attr("selected", "selected");
    showUpdateFields();
    $.mask.definitions['y'] = '[1-2,x]';
    $.mask.definitions['m'] = '[0-1,x]';
    $.mask.definitions['d'] = '[0-3,x]';
    $.mask.definitions['g'] = '[0-9,x]';
    $("#creationDate, #contentDate").mask("yggg-mg-dg", {optional: true});
    updateFormat();
    onChangeMediaType();
    onChangeFormat();
}
function updateFormat() {
    /// call to get base dropdown options
    if (selectedFormat) {
        url = baseUrl + 'getFormat/' + $("#mediaType").val() + '/' + selectedFormat;
    } else {
        url = baseUrl + 'getFormat/' + $("#mediaType").val();
    }
    $.ajax({
        type: "GET",
        url: url,
        success: function (response) {
            if (response != "") {
                $("#format").html(response);
            } else {
            }
        }

    }); // Ajax Call
}

function showUpdateFields() {
    $('#format').change(function () {
        var showDiskDiameter = [16, 17, 18, 19, 20, 28];
        var showMediaDiameter = [1, 2, 3, 4, 5, 24];
        var showTapeThickness = [1, 2, 3, 4, 5];
        var showTrackType = [1, 2, 3, 4, 5];
        var showCassetteSize = [59, 60, 33, 34, 35, 43, 44, 46, 47, 48, 52, 53, 54, 55, 57];
        var hideRecordingSpeedFormat = [37, 39, 40, 41];
        var hideIfFormat = [24, 25, 26];

        if (jQuery.inArray(parseInt($(this).val()), showDiskDiameter) >= 0) {
            $('#diskDiameters_lbl').show();
        } else {
            $('#diskDiameters_lbl').hide();
        }

        if (jQuery.inArray(parseInt($(this).val()), showMediaDiameter) >= 0) {
            $('#mediaDiameters_lbl').show();
        } else {
            $('#mediaDiameters_lbl').hide();
        }

        if (jQuery.inArray(parseInt($(this).val()), showTapeThickness) >= 0) {
            $('#tapeThickness_lbl').show();
        } else {
            $('#tapeThickness_lbl').hide();
        }

        if (jQuery.inArray(parseInt($(this).val()), showTrackType) >= 0) {
            $('#trackTypes_lbl').show();
        } else {
            $('#trackTypes_lbl').hide();
        }

        if (jQuery.inArray(parseInt($(this).val()), showCassetteSize) >= 0) {
            $('#cassetteSize_lbl').show();
        } else {
            $('#cassetteSize_lbl').hide();
        }

        if (jQuery.inArray(parseInt($(this).val()), hideIfFormat) >= 0) {
            $('#slides_lbl, #monoStereo_lbl, #noiceReduction_lbl').hide();
        } else {
            $('#slides_lbl, #monoStereo_lbl, #noiceReduction_lbl').show();
        }
        getBaseOptions();
        /// call to get reel diameters dropdown options
        $.ajax({
            type: "GET",
            url: baseUrl + 'getReelDiameter/' + $(this).val() + '/' + $("#mediaType").val(),
            success: function (response) {
                if (response != "") {
                    $("#reelDiameters_lbl").show();
                    $("#reelDiameters").html(response);
                } else {
                    $("#reelDiameters_lbl").hide();
                }
            }

        }); // Ajax Call
        if (jQuery.inArray(parseInt($(this).val()), hideRecordingSpeedFormat) >= 0) {
            $('#recordingSpeed_lbl').hide();
        } else {
            $('#recordingSpeed_lbl').show();
            /// call to get recording speed dropdown options
            $.ajax({
                type: "GET",
                url: baseUrl + 'getRecordingSpeed/' + $(this).val() + '/' + $("#mediaType").val(),
                success: function (response) {
                    if (response != "") {
                        $("#recordingSpeed_lbl").show();
                        $("#recordingSpeed").html(response);
                    } else {
                        $("#recordingSpeed_lbl").hide();
                    }
                }

            }); // Ajax Call
        }
        /// call to get formatversion dropdown options
        $.ajax({
            type: "GET",
            url: baseUrl + 'getFormatVersion/' + $(this).val(),
            success: function (response) {
                if (response != "") {
                    $("#formatVersion_lbl").show();
                    $("#formatVersion").html(response);
                } else {
                    $("#formatVersion_lbl").hide();
                }
            }

        }); // Ajax Call
    }).change();

}

function onChangeMediaType() {
    $(".new #mediaType").change(function () {
        console.log($(this).val());
        if ($(this).val() == 3) {
            window.location.href = baseUrl + 'video/new';
        } else if ($(this).val() == 2) {
            window.location.href = baseUrl + 'film/new';
            ;
        } else if ($(this).val() == 1) {
            window.location.href = baseUrl + 'audio/new';
            ;
        }
    });
}

function getBaseOptions() {
    /// call to get base dropdown options
    $.ajax({
        type: "GET",
        url: baseUrl + 'getBase/' + $('#format').val(),
        success: function (response) {
            if (response != "") {
                $("#bases_lbl").show();
                $("#bases").html(response);
            } else {
                $("#bases_lbl").hide();
            }
        }

    }); // Ajax Call
}
function onChangeFormat() {
    console.log($("#format").val());
    $("#format").change(function () {
        getBaseOptions();
    }).change();
}
<commit_msg>bug fixing<commit_after>function initialize_records_form() {
    $('#diskDiameters_lbl').hide();
    $('#reelDiameters_lbl').hide();
    $('#mediaDiameters_lbl').hide();
    $('#tapeThickness_lbl').hide();
    $('#trackTypes_lbl').hide();
    $('#cassetteSize_lbl').hide();
    $("#formatVersion_lbl").hide();
    $('.new #mediaType option[value="' + selectedMediaType + '"]').attr("selected", "selected");
    showUpdateFields();
    $.mask.definitions['y'] = '[1-2,x]';
    $.mask.definitions['m'] = '[0-1,x]';
    $.mask.definitions['d'] = '[0-3,x]';
    $.mask.definitions['g'] = '[0-9,x]';
    $("#creationDate, #contentDate").mask("yggg-mg-dg", {optional: true});
    updateFormat();
    onChangeMediaType();
    onChangeFormat();
}
function updateFormat() {
    /// call to get base dropdown options
    if (selectedFormat) {
        url = baseUrl + 'getFormat/' + $("#mediaType").val() + '/' + selectedFormat;
    } else {
        url = baseUrl + 'getFormat/' + $("#mediaType").val();
    }
    $.ajax({
        type: "GET",
        url: url,
        success: function (response) {
            if (response != "") {
                $("#format").html(response);
                $("#format").change();
            } else {
            }
        }

    }); // Ajax Call
}

function showUpdateFields() {
    $('#format').change(function () {
        var showDiskDiameter = [16, 17, 18, 19, 20, 28];
        var showMediaDiameter = [1, 2, 3, 4, 5, 24];
        var showTapeThickness = [1, 2, 3, 4, 5];
        var showTrackType = [1, 2, 3, 4, 5];
        var showCassetteSize = [59, 60, 33, 34, 35, 43, 44, 46, 47, 48, 52, 53, 54, 55, 57];
        var hideRecordingSpeedFormat = [37, 39, 40, 41];
        var hideIfFormat = [24, 25, 26];

        if (jQuery.inArray(parseInt($(this).val()), showDiskDiameter) >= 0) {
            $('#diskDiameters_lbl').show();
        } else {
            $('#diskDiameters_lbl').hide();
        }

        if (jQuery.inArray(parseInt($(this).val()), showMediaDiameter) >= 0) {
            $('#mediaDiameters_lbl').show();
        } else {
            $('#mediaDiameters_lbl').hide();
        }

        if (jQuery.inArray(parseInt($(this).val()), showTapeThickness) >= 0) {
            $('#tapeThickness_lbl').show();
        } else {
            $('#tapeThickness_lbl').hide();
        }

        if (jQuery.inArray(parseInt($(this).val()), showTrackType) >= 0) {
            $('#trackTypes_lbl').show();
        } else {
            $('#trackTypes_lbl').hide();
        }

        if (jQuery.inArray(parseInt($(this).val()), showCassetteSize) >= 0) {
            $('#cassetteSize_lbl').show();
        } else {
            $('#cassetteSize_lbl').hide();
        }

        if (jQuery.inArray(parseInt($(this).val()), hideIfFormat) >= 0) {
            $('#slides_lbl, #monoStereo_lbl, #noiceReduction_lbl').hide();
        } else {
            $('#slides_lbl, #monoStereo_lbl, #noiceReduction_lbl').show();
        }
        getBaseOptions();
        /// call to get reel diameters dropdown options
        $.ajax({
            type: "GET",
            url: baseUrl + 'getReelDiameter/' + $(this).val() + '/' + $("#mediaType").val(),
            success: function (response) {
                if (response != "") {
                    $("#reelDiameters_lbl").show();
                    $("#reelDiameters").html(response);
                } else {
                    $("#reelDiameters_lbl").hide();
                }
            }

        }); // Ajax Call
        if (jQuery.inArray(parseInt($(this).val()), hideRecordingSpeedFormat) >= 0) {
            $('#recordingSpeed_lbl').hide();
        } else {
            $('#recordingSpeed_lbl').show();
            /// call to get recording speed dropdown options
            $.ajax({
                type: "GET",
                url: baseUrl + 'getRecordingSpeed/' + $(this).val() + '/' + $("#mediaType").val(),
                success: function (response) {
                    if (response != "") {
                        $("#recordingSpeed_lbl").show();
                        $("#recordingSpeed").html(response);
                    } else {
                        $("#recordingSpeed_lbl").hide();
                    }
                }

            }); // Ajax Call
        }
        /// call to get formatversion dropdown options
        $.ajax({
            type: "GET",
            url: baseUrl + 'getFormatVersion/' + $(this).val(),
            success: function (response) {
                if (response != "") {
                    $("#formatVersion_lbl").show();
                    $("#formatVersion").html(response);
                } else {
                    $("#formatVersion_lbl").hide();
                }
            }

        }); // Ajax Call
    }).change();

}

function onChangeMediaType() {
    $(".new #mediaType").change(function () {
        console.log($(this).val());
        if ($(this).val() == 3) {
            window.location.href = baseUrl + 'video/new';
        } else if ($(this).val() == 2) {
            window.location.href = baseUrl + 'film/new';
            ;
        } else if ($(this).val() == 1) {
            window.location.href = baseUrl + 'audio/new';
            ;
        }
    });
}

function getBaseOptions() {
    /// call to get base dropdown options
    $.ajax({
        type: "GET",
        url: baseUrl + 'getBase/' + $('#format').val(),
        success: function (response) {
            if (response != "") {
                $("#bases_lbl").show();
                $("#bases").html(response);
            } else {
                $("#bases_lbl").hide();
            }
        }

    }); // Ajax Call
}
function onChangeFormat() {
    console.log($("#format").val());
    $("#format").change(function () {
        getBaseOptions();
    }).change();
}
<|endoftext|>


<commit_before>class PortfolioIndexService {
  constructor () {
    'ngInject';

    this.data = [
      {
        title : 'E.ON Homebuyer',
      	image : 'assets/images/projects/eon-homebuyers/eon-homebuyers-thumbnail.jpg',
        state  : 'eon-homebuyers'
      },
      // {
      //   title : 'TrailLink',
      // 	image : 'assets/images/projects/sony-wheel/sony-wheel-thumbnail.jpg',
      //   state  : 'trail-link'
      // },
      {
        title : 'Banners',
      	image : 'assets/images/projects/sapient-banners/sapient-banners-thumbnail.jpg',
        state  : 'sapient-banners'
      },
      {
        title : 'Sony Wheel',
      	image : 'assets/images/projects/sony-wheel/sony-wheel-thumbnail.jpg',
        state  : 'sony-wheel'
      },
      {
        title : 'Digital Room',
      	image : 'assets/images/projects/haygarth-digital-room/haygarth-digital-room-thumbnail.jpg',
        state  : 'haygarth-digital-room'
      },
      // {
      //   title : 'Think Differently',
      // 	image : 'assets/images/projects/think-differently/think-differently-thumbnail.jpg',
      //   state  : 'think-differently'
      // },
      {
        title : 'YSL Rock Chick',
      	image : 'assets/images/projects/ysl-rock-chick/ysl-rock-chick-thumbnail.jpg',
        state  : 'ysl-rock-chick'
      },
      // {
      //   title : 'Gulp Emails',
      // 	image : 'assets/images/projects/gulp-emails/gulp-emails-thumbnail.jpg',
      //   state  : 'gulp-emails'
      // },
      {
        title : 'Haygarth',
      	image : 'assets/images/projects/haygarth/haygarth-thumbnail.jpg',
        state  : 'haygarth'
      },
      {
        title : 'Sony Demo Bay',
      	image : 'assets/images/projects/sony-demo-bay/sony-demo-bay-thumbnail.jpg',
        state  : 'sony-demo-bay'
      },
      {
        title : 'Giles Deacon',
      	image : 'assets/images/projects/giles-deacon/giles-deacon-thumbnail.jpg',
        state  : 'giles-deacon'
      },
      // {
      //   title : 'Toni & Guy',
      // 	image : 'assets/images/projects/toni-and-guy/toni-and-guy-thumbnail.png',
      //   state  : 'toni-and-guy'
      // },
      // {
      //   title : 'Louise & Daniel',
      // 	image : 'assets/images/projects/louise-and-daniel/louise-and-daniel-thumbnail.jpg',
      //   state  : 'louise-and-daniel'
      // },
      // {
      //   title : 'Dumfries House',
      // 	image : 'assets/images/projects/dumfries-house/dumfries-house-thumbnail.jpg',
      //   state  : 'dumfries-house'
      // },
      // {
      //   title : 'Lambeth Advice Network',
      // 	image : 'assets/images/projects/lambeth/lambeth-thumbnail.jpg',
      //   state  : 'lambeth'
      // },
      {
        title : 'AMBR Media',
      	image : 'assets/images/projects/ambr/ambr-thumbnail.png',
        state  : 'ambr'
      },
      {
        title : 'Layla Moran',
      	image : 'assets/images/projects/layla/layla-thumbnail.png',
        state  : 'layla-moran'
      },
      {
        title : 'Lancastrians',
      	image : 'assets/images/projects/lancastrians/lancastrians-thumbnail.jpg',
        state  : 'lancastrians'
      },
      {
        title : 'EUFN',
      	image : 'assets/images/projects/eufn/eufn-thumbnail.png',
        state  : 'eufn'
      }
      // {
      //   title : 'Waterleaf',
      // 	image : 'assets/images/projects/waterleaf/waterleaf-thumbnail.png',
      //   state  : 'waterleaf'
      // }
    ];
  }

  getPortfolioIndexContent() {
    return this.data;
  }
}

export default PortfolioIndexService;
<commit_msg>Update project title<commit_after>class PortfolioIndexService {
  constructor () {
    'ngInject';

    this.data = [
      {
        title : 'E.ON',
      	image : 'assets/images/projects/eon-homebuyers/eon-homebuyers-thumbnail.jpg',
        state  : 'eon-homebuyers'
      },
      // {
      //   title : 'TrailLink',
      // 	image : 'assets/images/projects/sony-wheel/sony-wheel-thumbnail.jpg',
      //   state  : 'trail-link'
      // },
      {
        title : 'Banners',
      	image : 'assets/images/projects/sapient-banners/sapient-banners-thumbnail.jpg',
        state  : 'sapient-banners'
      },
      {
        title : 'Sony Wheel',
      	image : 'assets/images/projects/sony-wheel/sony-wheel-thumbnail.jpg',
        state  : 'sony-wheel'
      },
      {
        title : 'Digital Room',
      	image : 'assets/images/projects/haygarth-digital-room/haygarth-digital-room-thumbnail.jpg',
        state  : 'haygarth-digital-room'
      },
      // {
      //   title : 'Think Differently',
      // 	image : 'assets/images/projects/think-differently/think-differently-thumbnail.jpg',
      //   state  : 'think-differently'
      // },
      {
        title : 'YSL Rock Chick',
      	image : 'assets/images/projects/ysl-rock-chick/ysl-rock-chick-thumbnail.jpg',
        state  : 'ysl-rock-chick'
      },
      // {
      //   title : 'Gulp Emails',
      // 	image : 'assets/images/projects/gulp-emails/gulp-emails-thumbnail.jpg',
      //   state  : 'gulp-emails'
      // },
      {
        title : 'Haygarth',
      	image : 'assets/images/projects/haygarth/haygarth-thumbnail.jpg',
        state  : 'haygarth'
      },
      {
        title : 'Sony Demo Bay',
      	image : 'assets/images/projects/sony-demo-bay/sony-demo-bay-thumbnail.jpg',
        state  : 'sony-demo-bay'
      },
      {
        title : 'Giles Deacon',
      	image : 'assets/images/projects/giles-deacon/giles-deacon-thumbnail.jpg',
        state  : 'giles-deacon'
      },
      // {
      //   title : 'Toni & Guy',
      // 	image : 'assets/images/projects/toni-and-guy/toni-and-guy-thumbnail.png',
      //   state  : 'toni-and-guy'
      // },
      // {
      //   title : 'Louise & Daniel',
      // 	image : 'assets/images/projects/louise-and-daniel/louise-and-daniel-thumbnail.jpg',
      //   state  : 'louise-and-daniel'
      // },
      // {
      //   title : 'Dumfries House',
      // 	image : 'assets/images/projects/dumfries-house/dumfries-house-thumbnail.jpg',
      //   state  : 'dumfries-house'
      // },
      // {
      //   title : 'Lambeth Advice Network',
      // 	image : 'assets/images/projects/lambeth/lambeth-thumbnail.jpg',
      //   state  : 'lambeth'
      // },
      {
        title : 'AMBR Media',
      	image : 'assets/images/projects/ambr/ambr-thumbnail.png',
        state  : 'ambr'
      },
      {
        title : 'Layla Moran',
      	image : 'assets/images/projects/layla/layla-thumbnail.png',
        state  : 'layla-moran'
      },
      {
        title : 'Lancastrians',
      	image : 'assets/images/projects/lancastrians/lancastrians-thumbnail.jpg',
        state  : 'lancastrians'
      },
      {
        title : 'EUFN',
      	image : 'assets/images/projects/eufn/eufn-thumbnail.png',
        state  : 'eufn'
      }
      // {
      //   title : 'Waterleaf',
      // 	image : 'assets/images/projects/waterleaf/waterleaf-thumbnail.png',
      //   state  : 'waterleaf'
      // }
    ];
  }

  getPortfolioIndexContent() {
    return this.data;
  }
}

export default PortfolioIndexService;
<|endoftext|>


<commit_before>/**
 * Created by liuxh04 on 2016/6/30.
 */

"use strict";

var hashes = [], uploadedImage = 0,
    uploader,
    panoramaUrl = $('.jumpToPanorama').val()
    ;

var component = {
    picName : $('.pic-name'),                       // 图片标题输入框
    padResult: $('.pad-result'),                    // 上传后显示结果的框
    textStatus: $('.pad-status .status'),
    linkStatus: $('.pad-status .link'),

    padMain: $('.pad-main'),                        // 上传操作主要框
    zoneUploadedPics:$('.zone-uploaded-pics'),      // 显示上传全景图区域
    zoneDefault: $('.zone-default')                 // 没有上传全景图片是显示的默认图片
};

var methods = {
    reset: function(){
        uploader.reset();
        component.picName.val('');
        component.zoneUploadedPics.empty().addClass('hidden');
        component.zoneDefault.removeClass('hidden');
    }
}

// 文件上传
jQuery(function() {
    var $ = jQuery,
        $list = $('#thelist'),
        $btn = $('.btn-publish'),
        $wrap = $('.zone-uploaded-pics'),
        state = 'pending';

    var isSupportBase64 = ( function() {
        var data = new Image();
        var support = true;
        data.onload = data.onerror = function() {
            if( this.width != 1 || this.height != 1 ) {
                support = false;
            }
        }
        data.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
        return support;
    })();

    $('.webuploader-pick').next('div').css({});
    uploader = WebUploader.create({
        // 不压缩image
        resize: false,

        // swf文件路径
        swf: './dist/webuploader/Uploader.swf',

        fileVal :"pano",

        chunkSize: 512 * 1024 * 100,

        // 文件接收服务端。
        server: '/admin/material/upload',

        // 选择文件的按钮。可选。
        // 内部根据当前运行是创建，可能是input元素，也可能是flash.
        pick: {id:'#picker',multiple :true}
    });

    // 当有文件添加进来的时候
    uploader.on( 'fileQueued', function( file ) {
        $wrap.removeClass('hidden').siblings('.zone-default').addClass('hidden');
        uploader.makeThumb( file, function( error, src ) {
            if(file._info.width/file._info.height==2){

                // $list.append( '
' +
                //     '
' + file.name + '
' +
                //     '
等待上传...
' +
                // '
' );

                uploader.makeThumb( file, function( error, src ) {
                    var img;
                    if ( error ) {
                        $wrap.text( '不能预览' );
                        return;
                    }
                    if( isSupportBase64 ) {
                        console.log(file);
                        $wrap.append(
                                        '
 ' +
                                        '
 ' +
                                        '        ' +
                                        '
' +
                                        '           已上传0%' +
                                        '           ' +
                                        '
'+
                                        '
' +
                                        '
 ' +
                                        '       ' + file.name + '' +
                                        '       删除' +
                                        '
' +
                                        '
'
                                    );
                        uploadedImage++;
                    } else {
                        $.ajax('/admin/material/upload', {
                            method: 'POST',
                            data: src,
                            dataType:'json'
                        }).done(function( response ) {
                            if (response.result) {
                                $wrap.append(
                                        '
 ' +
                                        '
 ' +
                                        '        ' +
                                        '
' +
                                        '           已上传0%' +
                                        '           ' +
                                        '
'+
                                        '
' +
                                        '
' +
                                        '       ' + file.name + '' +
                                        '       删除 ' +
                                        '
 ' +
                                        '
'
                                    );
                            } else {
                                $wrap.text("预览出错");
                            }
                        });
                    }
                }, 200, 200 );
            }else{
                alert("该图片的宽高比例不是 2:1 ");
                uploader.reset();
            }
        }, 100, 100 );
    });

    // 文件上传过程中创建进度条实时显示。
    uploader.on( 'uploadProgress', function( file, percentage ) {
        var $progress = $( '.pre-img-progress[data-id="'+file.id+'"]');
        var $progressBar = $progress.find('.progress-bar').eq(0),
            $progressText = $progress.find('.progress-text').eq(0);
        $progress.removeClass('hidden');
        $progressText.text('已上传' + ( percentage * 100 ) +  '%');
        $progressBar.css( 'width', percentage * 100 + '%' );
    });

    uploader.on( 'uploadSuccess', function( file , response) {
        var $progressText = $( '.pre-img-progress[data-id="'+file.id+'"]').find('.progress-text').eq(0);
        $progressText.text('上传成功');

        // 将上传给后台的全景图片hash值保存在全局中
        hashes.push(response.data.hs);

        uploadedImage--;

        console.log(uploadedImage);

        if(uploadedImage === 0){
            $.ajax('/admin/material/generate', {
                data:{
                    title: component.picName.val(),
                    hashes: hashes
                },
                method: 'POST',
                dataType: 'json'
            }).done(function(res){
                hashes = [];
                uploadedImage = 0;
                if(res.result){
                    component.textStatus.text('发布成功');
                    component.linkStatus.html('您可以在作品管理中进行更多操作');
                }else{
                    component.textStatus.text('发布失败').css('color', '#ff2e34');
                    component.linkStatus.html('点击重新发布再来一次');
                }
                component.padMain.addClass('hidden');
                component.padResult.removeClass('hidden');
            });
        }

        //$list.html("");
    });

    uploader.on( 'uploadError', function( file ) {
        $( '#'+file.id ).find('p.state').text('上传出错');
    });

    uploader.on( 'uploadComplete', function( file ) {
        $( '#'+file.id ).find('.progress').fadeOut();
    });

    uploader.on( 'all', function( type ) {
        if ( type === 'startUpload' ) {
            state = 'uploading';
        } else if ( type === 'stopUpload' ) {
            state = 'paused';
        } else if ( type === 'uploadFinished' ) {
            state = 'done';
        }
        if ( state === 'uploading' ) {
            $btn.text('暂停上传');
        } else {
            $btn.text('开始上传');
        }
    });

    $("body").on("click",".pre-img-dele",function(){
        $(this).parent().parent().remove();
        uploader.removeFile( $(this).attr("data-id") ,true);
    }).on('click', '.btn-publish', function(){
        // 判断是否为空
        if(component.picName.val() === ''){
            component.picName.addClass('error').val('请输入标题');
        }else{
            if ( state === 'uploading' ) {
                uploader.stop();
            } else {
                uploader.upload();
            }
        }

    });

});

//绑定时间
var bindEvent = function(){
    component.picName.focus(function(){
        var _this = $(this);
        _this.hasClass('error') &&
        _this.removeClass('error').val('');
    })
    component.padResult.on('click', '.try_again', function(){
        component.padResult.addClass('hidden');
        methods.reset();
        component.padMain.removeClass('hidden');

    })
}();
<commit_msg>dunt compress<commit_after>/**
 * Created by liuxh04 on 2016/6/30.
 */

"use strict";

var hashes = [], uploadedImage = 0,
    uploader,
    panoramaUrl = $('.jumpToPanorama').val()
    ;

var component = {
    picName : $('.pic-name'),                       // 图片标题输入框
    padResult: $('.pad-result'),                    // 上传后显示结果的框
    textStatus: $('.pad-status .status'),
    linkStatus: $('.pad-status .link'),

    padMain: $('.pad-main'),                        // 上传操作主要框
    zoneUploadedPics:$('.zone-uploaded-pics'),      // 显示上传全景图区域
    zoneDefault: $('.zone-default')                 // 没有上传全景图片是显示的默认图片
};

var methods = {
    reset: function(){
        uploader.reset();
        component.picName.val('');
        component.zoneUploadedPics.empty().addClass('hidden');
        component.zoneDefault.removeClass('hidden');
    }
}

// 文件上传
jQuery(function() {
    var $ = jQuery,
        $list = $('#thelist'),
        $btn = $('.btn-publish'),
        $wrap = $('.zone-uploaded-pics'),
        state = 'pending';

    var isSupportBase64 = ( function() {
        var data = new Image();
        var support = true;
        data.onload = data.onerror = function() {
            if( this.width != 1 || this.height != 1 ) {
                support = false;
            }
        }
        data.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
        return support;
    })();

    $('.webuploader-pick').next('div').css({});
    uploader = WebUploader.create({
        // 不压缩image
        resize: false,

        compress:false,

        // swf文件路径
        swf: './dist/webuploader/Uploader.swf',

        fileVal :"pano",

        chunkSize: 512 * 1024 * 100,

        // 文件接收服务端。
        server: '/admin/material/upload',

        // 选择文件的按钮。可选。
        // 内部根据当前运行是创建，可能是input元素，也可能是flash.
        pick: {id:'#picker',multiple :true}
    });

    // 当有文件添加进来的时候
    uploader.on( 'fileQueued', function( file ) {
        $wrap.removeClass('hidden').siblings('.zone-default').addClass('hidden');
        uploader.makeThumb( file, function( error, src ) {
            if(file._info.width/file._info.height==2){

                // $list.append( '
' +
                //     '
' + file.name + '
' +
                //     '
等待上传...
' +
                // '
' );

                uploader.makeThumb( file, function( error, src ) {
                    var img;
                    if ( error ) {
                        $wrap.text( '不能预览' );
                        return;
                    }
                    if( isSupportBase64 ) {
                        console.log(file);
                        $wrap.append(
                                        '
 ' +
                                        '
 ' +
                                        '        ' +
                                        '
' +
                                        '           已上传0%' +
                                        '           ' +
                                        '
'+
                                        '
' +
                                        '
 ' +
                                        '       ' + file.name + '' +
                                        '       删除' +
                                        '
' +
                                        '
'
                                    );
                        uploadedImage++;
                    } else {
                        $.ajax('/admin/material/upload', {
                            method: 'POST',
                            data: src,
                            dataType:'json'
                        }).done(function( response ) {
                            if (response.result) {
                                $wrap.append(
                                        '
 ' +
                                        '
 ' +
                                        '        ' +
                                        '
' +
                                        '           已上传0%' +
                                        '           ' +
                                        '
'+
                                        '
' +
                                        '
' +
                                        '       ' + file.name + '' +
                                        '       删除 ' +
                                        '
 ' +
                                        '
'
                                    );
                            } else {
                                $wrap.text("预览出错");
                            }
                        });
                    }
                }, 200, 200 );
            }else{
                alert("该图片的宽高比例不是 2:1 ");
                uploader.reset();
            }
        }, 100, 100 );
    });

    // 文件上传过程中创建进度条实时显示。
    uploader.on( 'uploadProgress', function( file, percentage ) {
        var $progress = $( '.pre-img-progress[data-id="'+file.id+'"]');
        var $progressBar = $progress.find('.progress-bar').eq(0),
            $progressText = $progress.find('.progress-text').eq(0);
        $progress.removeClass('hidden');
        $progressText.text('已上传' + ( percentage * 100 ) +  '%');
        $progressBar.css( 'width', percentage * 100 + '%' );
    });

    uploader.on( 'uploadSuccess', function( file , response) {
        var $progressText = $( '.pre-img-progress[data-id="'+file.id+'"]').find('.progress-text').eq(0);
        $progressText.text('上传成功');

        // 将上传给后台的全景图片hash值保存在全局中
        hashes.push(response.data.hs);

        uploadedImage--;

        console.log(uploadedImage);

        if(uploadedImage === 0){
            $.ajax('/admin/material/generate', {
                data:{
                    title: component.picName.val(),
                    hashes: hashes
                },
                method: 'POST',
                dataType: 'json'
            }).done(function(res){
                hashes = [];
                uploadedImage = 0;
                if(res.result){
                    component.textStatus.text('发布成功');
                    component.linkStatus.html('您可以在作品管理中进行更多操作');
                }else{
                    component.textStatus.text('发布失败').css('color', '#ff2e34');
                    component.linkStatus.html('点击重新发布再来一次');
                }
                component.padMain.addClass('hidden');
                component.padResult.removeClass('hidden');
            });
        }

        //$list.html("");
    });

    uploader.on( 'uploadError', function( file ) {
        $( '#'+file.id ).find('p.state').text('上传出错');
    });

    uploader.on( 'uploadComplete', function( file ) {
        $( '#'+file.id ).find('.progress').fadeOut();
    });

    uploader.on( 'all', function( type ) {
        if ( type === 'startUpload' ) {
            state = 'uploading';
        } else if ( type === 'stopUpload' ) {
            state = 'paused';
        } else if ( type === 'uploadFinished' ) {
            state = 'done';
        }
        if ( state === 'uploading' ) {
            $btn.text('暂停上传');
        } else {
            $btn.text('开始上传');
        }
    });

    $("body").on("click",".pre-img-dele",function(){
        $(this).parent().parent().remove();
        uploader.removeFile( $(this).attr("data-id") ,true);
    }).on('click', '.btn-publish', function(){
        // 判断是否为空
        if(component.picName.val() === ''){
            component.picName.addClass('error').val('请输入标题');
        }else{
            if ( state === 'uploading' ) {
                uploader.stop();
            } else {
                uploader.upload();
            }
        }

    });

});

//绑定时间
var bindEvent = function(){
    component.picName.focus(function(){
        var _this = $(this);
        _this.hasClass('error') &&
        _this.removeClass('error').val('');
    })
    component.padResult.on('click', '.try_again', function(){
        component.padResult.addClass('hidden');
        methods.reset();
        component.padMain.removeClass('hidden');

    })
}();
<|endoftext|>


<commit_before>/*  __  __    _    _  _______    ____ _   _    _    _   _  ____ _____ ____  _
   |  \/  |  / \  | |/ / ____|  / ___| | | |  / \  | \ | |/ ___| ____/ ___|| |
   | |\/| | / _ \ | ' /|  _|   | |   | |_| | / _ \ |  \| | |  _|  _| \___ \| |
   | |  | |/ ___ \| . \| |___  | |___|  _  |/ ___ \| |\  | |_| | |___ ___) |_|
   |_|  |_/_/   \_\_|\_\_____|  \____|_| |_/_/   \_\_| \_|\____|_____|____/(_)

   There is a 100% chance that this project can use improvements.
   Pull requests are ALWAYS welcome, even if just amounts to a conversation.  */

'use strict';

var fs = require('fs');
var fsExtra = require('fs-extra');
var path = require('path');
var ospath = require('ospath');
var request = require('request');
var uuid = require('uuid');
var gunzip = require('gunzip-maybe');
var tar = require('tar-fs');
var isDirectory = require('is-directory').sync;

var fetchGitHub = function (state, callback) {
    var tmpPath = ospath.tmp() + '/' + uuid.v1(),
        input = state.template.input;

    // setup the tmp path
    fs.mkdir(tmpPath, function () {
        // get the default branch
        var query = (process.env.token) ? { access_token: process.env.token } : {};

        request({
            url: 'https://api.github.com/repos/' + input,
            qs: query,
            headers: {
                'User-Agent': 'request'
            }
        }, function (err, response) {
            var repoDetails;

            if (err) {
                callback(err);
                return;
            }

            repoDetails = JSON.parse(response.body);

            request
                .get('https://github.com/' + input + '/archive/' + repoDetails.default_branch + '.tar.gz')
                .pipe(gunzip())
                .pipe(tar.extract(tmpPath))
                .on('finish', function () {
                    state.template.tmp = tmpPath + '/' + repoDetails.name + '-' + repoDetails.default_branch;
                    callback(null, state);
                });
        });
    });
};

var fetchDirectory = function (state, callback) {
    var input = state.template.input,
        tmpPath = ospath.tmp() + '/' + uuid.v1();

    state.template.tmp = tmpPath;

    // setup the tmp path
    fsExtra.mkdirs(tmpPath, function (err) {
        if (err) {
            callback(err);
            return;
        }
        fsExtra.copy(input, tmpPath, function (err) {
            if (err) {
                callback(err);
                return;
            }
            if (isDirectory(tmpPath + '/.git')) {
                fsExtra.remove(tmpPath + '/.git', function (err) {
                    if (err) {
                        callback(err);
                        return;
                    }
                    callback(null, state);
                });
            } else {
                callback(null, state);
            }
        });
    });
};

var fetchGit = function (state, callback) {
    var exec = require('child_process').exec,
        tmpPath = ospath.tmp() + '/' + uuid.v1(),
        input = state.template.input,
        command = 'git clone ' + input + ' ' + tmpPath;

    state.template.tmp = tmpPath;

    exec(command, function (err) {
        if (err) {
            callback(err);
            return;
        }
        if (isDirectory(tmpPath + '/.git')) {
            fsExtra.remove(tmpPath + '/.git', function (err) {
                if (err) {
                    callback(err);
                    return;
                }
                callback(null, state);
            });
        } else {
            callback(null, state);
        }
    });
};

var fetchURL = function (state, callback) {
    var tmpPath = ospath.tmp() + '/' + uuid.v1(),
        input = state.project.input,
        response = request(input);

    state.project.tmp = tmpPath;

    // setup the tmp path
    fs.mkdir(tmpPath, function (err) {
        if (err) {
            callback(err);
            return;
        }

        state.project.tmp = tmpPath + '/data.json';

        response
            .pipe(fs.createWriteStream(tmpPath + '/data.json'))
            .on('finish', function () {
                callback(null, state);
            });
    });
};

var fetchJSON = function (state, callback) {
    callback(null, state);
};

var fetchFile = function (state, callback) {
    var tmpPath = ospath.tmp() + '/' + uuid.v1(),
        input = state.project.input;

    // setup the tmp path
    fs.mkdir(tmpPath, function (err) {
        if (err) {
            callback(err);
            return;
        }

        state.project.tmp = tmpPath + '/data.json';

        fs.createReadStream(input)
            .pipe(fs.createWriteStream(tmpPath + '/data.json'))
            .on('finish', function () {
                callback(null, state);
            });
    });
};

var fetchTemplate = function (state, callback) {
    switch (state.template.source) {
    case 'github':
        fetchGitHub(state, callback);
        break;
    case 'directory':
        fetchDirectory(state, callback);
        break;
    case 'git':
        fetchGit(state, callback);
        break;
    }
};

var fetchProject = function (state, callback) {
    switch (state.project.source) {
    case 'url':
        fetchURL(state, callback);
        break;
    case 'json':
        fetchJSON(state, callback);
        break;
    case 'file':
        fetchFile(state, callback);
        break;
    }
};

module.exports = function (state, callback) {
    fetchTemplate(state, function (err, state) {
        if (err) {
            callback(err);
            return;
        }
        if (state.project !== undefined) {
            fetchProject(state, function (err, state) {
                if (err) {
                    callback(err);
                    return;
                }
                callback(null, state);
            });
        } else {
            callback(null, state);
        }
    });
};

<commit_msg>Updating GitHub fetch method with optional commit ref<commit_after>/*  __  __    _    _  _______    ____ _   _    _    _   _  ____ _____ ____  _
   |  \/  |  / \  | |/ / ____|  / ___| | | |  / \  | \ | |/ ___| ____/ ___|| |
   | |\/| | / _ \ | ' /|  _|   | |   | |_| | / _ \ |  \| | |  _|  _| \___ \| |
   | |  | |/ ___ \| . \| |___  | |___|  _  |/ ___ \| |\  | |_| | |___ ___) |_|
   |_|  |_/_/   \_\_|\_\_____|  \____|_| |_/_/   \_\_| \_|\____|_____|____/(_)

   There is a 100% chance that this project can use improvements.
   Pull requests are ALWAYS welcome, even if just amounts to a conversation.  */

'use strict';

var fs = require('fs');
var fsExtra = require('fs-extra');
var path = require('path');
var ospath = require('ospath');
var request = require('request');
var uuid = require('uuid');
var gunzip = require('gunzip-maybe');
var tar = require('tar-fs');
var isDirectory = require('is-directory').sync;

var fetchGitHub = function (state, callback) {
    var tmpPath = ospath.tmp() + '/' + uuid.v1(),
        inputUrl = state.template.input.split('#')[0],
        inputRef = state.template.input.split('#')[1];

    // setup the tmp path
    fs.mkdir(tmpPath, function () {
        // get the default branch
        var query = (process.env.token) ? { access_token: process.env.token } : {};

        request({
            url: 'https://api.github.com/repos/' + inputUrl,
            qs: query,
            headers: {
                'User-Agent': 'request'
            }
        }, function (err, response) {
            var repoDetails, gitRef;

            if (err) {
                callback(err);
                return;
            }

            repoDetails = JSON.parse(response.body);
            gitRef = inputRef || repoDetails.default_branch;

            request
                .get('https://github.com/' + inputUrl + '/archive/' + gitRef + '.tar.gz')
                .pipe(gunzip())
                .pipe(tar.extract(tmpPath))
                .on('finish', function () {
                    state.template.tmp = tmpPath + '/' + repoDetails.name + '-' + gitRef;
                    callback(null, state);
                });
        });
    });
};

var fetchDirectory = function (state, callback) {
    var input = state.template.input,
        tmpPath = ospath.tmp() + '/' + uuid.v1();

    state.template.tmp = tmpPath;

    // setup the tmp path
    fsExtra.mkdirs(tmpPath, function (err) {
        if (err) {
            callback(err);
            return;
        }
        fsExtra.copy(input, tmpPath, function (err) {
            if (err) {
                callback(err);
                return;
            }
            if (isDirectory(tmpPath + '/.git')) {
                fsExtra.remove(tmpPath + '/.git', function (err) {
                    if (err) {
                        callback(err);
                        return;
                    }
                    callback(null, state);
                });
            } else {
                callback(null, state);
            }
        });
    });
};

var fetchGit = function (state, callback) {
    var exec = require('child_process').exec,
        tmpPath = ospath.tmp() + '/' + uuid.v1(),
        input = state.template.input,
        command = 'git clone ' + input + ' ' + tmpPath;

    state.template.tmp = tmpPath;

    exec(command, function (err) {
        if (err) {
            callback(err);
            return;
        }
        if (isDirectory(tmpPath + '/.git')) {
            fsExtra.remove(tmpPath + '/.git', function (err) {
                if (err) {
                    callback(err);
                    return;
                }
                callback(null, state);
            });
        } else {
            callback(null, state);
        }
    });
};

var fetchURL = function (state, callback) {
    var tmpPath = ospath.tmp() + '/' + uuid.v1(),
        input = state.project.input,
        response = request(input);

    state.project.tmp = tmpPath;

    // setup the tmp path
    fs.mkdir(tmpPath, function (err) {
        if (err) {
            callback(err);
            return;
        }

        state.project.tmp = tmpPath + '/data.json';

        response
            .pipe(fs.createWriteStream(tmpPath + '/data.json'))
            .on('finish', function () {
                callback(null, state);
            });
    });
};

var fetchJSON = function (state, callback) {
    callback(null, state);
};

var fetchFile = function (state, callback) {
    var tmpPath = ospath.tmp() + '/' + uuid.v1(),
        input = state.project.input;

    // setup the tmp path
    fs.mkdir(tmpPath, function (err) {
        if (err) {
            callback(err);
            return;
        }

        state.project.tmp = tmpPath + '/data.json';

        fs.createReadStream(input)
            .pipe(fs.createWriteStream(tmpPath + '/data.json'))
            .on('finish', function () {
                callback(null, state);
            });
    });
};

var fetchTemplate = function (state, callback) {
    switch (state.template.source) {
    case 'github':
        fetchGitHub(state, callback);
        break;
    case 'directory':
        fetchDirectory(state, callback);
        break;
    case 'git':
        fetchGit(state, callback);
        break;
    }
};

var fetchProject = function (state, callback) {
    switch (state.project.source) {
    case 'url':
        fetchURL(state, callback);
        break;
    case 'json':
        fetchJSON(state, callback);
        break;
    case 'file':
        fetchFile(state, callback);
        break;
    }
};

module.exports = function (state, callback) {
    fetchTemplate(state, function (err, state) {
        if (err) {
            callback(err);
            return;
        }
        if (state.project !== undefined) {
            fetchProject(state, function (err, state) {
                if (err) {
                    callback(err);
                    return;
                }
                callback(null, state);
            });
        } else {
            callback(null, state);
        }
    });
};

<|endoftext|>


<commit_before>var spawn = require("co-child-process"),
    co = require("co"),
    watch = require("watch"),
    fs = require("fs"),
    coFsPlus = require("co-fs-plus"),
    path = require("path"),
    simhash = require("simhash")("md5"),
    crypto = require('crypto'),
    moment = require('moment'),
    isBinaryFile = require("isbinaryfile");

var hammingDistance = function(arr1, arr2) {
    var d = 0;
    arr1.forEach(function(a, i) {
        if(a ^ arr2[i]) d++;
    });
    return d;
}

var coSimhash = function(file) {
    return function(callback) {
        fs.readFile(file.path, {encoding: 'UTF-8'}, function(err, content) {
            var re = /[ \n,.'":，．：＇、#/\(\)＂]/,
                tokens = content.split(re);
            tokens = tokens.filter(function(token) {
                return token.length > 0;
            });
            file.simhash = simhash(tokens);
            callback(null, file);
        });
    }
}

module.exports = function(app) {
    app.when(function *() {

        return this.config && this.storage;

    }).use(function *(next) {

        var sourceDir = this.config.source || "source/",
            argv = this.argv,
            cmd = argv[2],
            logger = this.logger;

        if(cmd === "build" || cmd === "rebuild") {

            var filePaths = yield coFsPlus.walk(sourceDir);

            // calc simhash
            var files = yield filePaths.map(function(path) {
                return coSimhash({path: path});
            });

            // load cached files
            var cachedFiles = this.storage.getItem('files');
            cachedFiles = cachedFiles ? JSON.parse(cachedFiles) : [];
            var cachedFilesObj = {};
            cachedFiles.forEach(function(file) {
                cachedFilesObj[file.path] = file;
            });

            var removedFiles = cachedFiles.filter(function(file) {
                return filePaths.indexOf(file.path) < 0;
            });

            var newFiles = [],
                changedFiles = [],
                unchangedFiles = [];

            var now = moment().format('YYYY-MM-DD H:mm:ss Z');
            files.forEach(function(file) {
                var cachedFile = cachedFilesObj[file.path];
                if(!cachedFile) {
                    file.creationTime = now;
                    file.modificationTime = now;
                    newFiles.push(file);
                    return;
                }
                if(hammingDistance(cachedFile.simhash, file.simhash) === 0) {
                    unchangedFiles.push(cachedFile);
                } else {
                    file.modificationTime = now;
                    file.creationTime = cachedFile.creationTime;
                    file.simhash = cachedFile.simhash;
                    changedFiles.push(file);
                }
            });

            // Rename Detection
            // using Locality Sensitive Hashing (simhash)

            newFiles = newFiles.map(function(file) {

                if(isBinaryFile(file.path)) {
                    return file;
                }

                removedFiles.forEach(function(removedFile) {
                    if(!file.simhash || !removedFile.simhash) return;
                    var d = hammingDistance(file.simhash, removedFile.simhash);
                    if(d < 20) {
                        logger.info("Rename Detected: " + removedFile.path + " -> " + file.path + ", hamming distance = " + d);
                        logger.info("Set file.creationTime to: " + removedFile.creationTime);
                        file.creationTime = removedFile.creationTime;
                    }
                });
                return file;
            });

            if(cmd === "rebuild") {
                newFiles = changedFiles.concat(unchangedFiles).map(function(file) {
                    return {
                        path: file.path,
                        simhash: file.simhash,
                        creationTime: file.creationTime,
                        modificationTime: file.modificationTime
                    }
                }).concat(newFiles);
                changedFiles = [];
                unchangedFiles = [];
            }

            this.newFiles = newFiles;
            this.changedFiles = changedFiles;
            this.unchangedFiles = unchangedFiles;
            this.removedFiles = removedFiles;

            console.log(this);

            yield next;

            files = this.newFiles.concat(this.changedFiles, this.unchangedFiles);
            this.storage.setItem('files', JSON.stringify(files));
        }

        if(cmd === "watch") {
            watch.watchTree(sourceDir, function (f, curr, prev) {
                if (typeof f == "object" && prev === null && curr === null) {
                    // nothing changed
                } else {
                    logger.info("Change detected: " + f + ", rebuild now.");
                    co(function *() {
                        var output = yield spawn(argv[0], process.execArgv.concat([argv[1], 'build']));
                        logger.info(output);
                    })();
                }
            })
        }
    });
}
<commit_msg>update rename detection, fixes #56<commit_after>var spawn = require("co-child-process"),
    co = require("co"),
    watch = require("watch"),
    fs = require("fs"),
    coFsPlus = require("co-fs-plus"),
    path = require("path"),
    simhash = require("simhash")("md5"),
    crypto = require('crypto'),
    moment = require('moment'),
    isBinaryFile = require("isbinaryfile");

var hammingDistance = function(arr1, arr2) {
    var d = 0;
    arr1.forEach(function(a, i) {
        if(a ^ arr2[i]) d++;
    });
    return d;
}

var coSimhash = function(file) {
    return function(callback) {
        fs.readFile(file.path, {encoding: 'UTF-8'}, function(err, content) {
            var re = /[\n]/,
                tokens = content.split(re);
            tokens = tokens.filter(function(token) {
                return token.length > 0;
            });
            file.simhash = simhash(tokens);
            callback(null, file);
        });
    }
}

module.exports = function(app) {
    app.when(function *() {

        return this.config && this.storage;

    }).use(function *(next) {

        var sourceDir = this.config.source || "source/",
            argv = this.argv,
            cmd = argv[2],
            logger = this.logger;

        if(cmd === "build" || cmd === "rebuild") {

            var filePaths = yield coFsPlus.walk(sourceDir);

            // calc simhash
            var files = yield filePaths.map(function(path) {
                return coSimhash({path: path});
            });

            // load cached files
            var cachedFiles = this.storage.getItem('files');
            cachedFiles = cachedFiles ? JSON.parse(cachedFiles) : [];
            var cachedFilesObj = {};
            cachedFiles.forEach(function(file) {
                cachedFilesObj[file.path] = file;
            });

            var removedFiles = cachedFiles.filter(function(file) {
                return filePaths.indexOf(file.path) < 0;
            });

            var newFiles = [],
                changedFiles = [],
                unchangedFiles = [];

            var now = moment().format('YYYY-MM-DD H:mm:ss Z');
            files.forEach(function(file) {
                var cachedFile = cachedFilesObj[file.path];
                if(!cachedFile) {
                    file.creationTime = now;
                    file.modificationTime = now;
                    newFiles.push(file);
                    return;
                }
                if(hammingDistance(cachedFile.simhash, file.simhash) === 0) {
                    unchangedFiles.push(cachedFile);
                } else {
                    file.modificationTime = now;
                    file.creationTime = cachedFile.creationTime;
                    file.simhash = cachedFile.simhash;
                    changedFiles.push(file);
                }
            });

            // Rename Detection
            // using Locality Sensitive Hashing (simhash)

            newFiles = newFiles.map(function(file) {

                if(isBinaryFile(file.path)) {
                    return file;
                }

                removedFiles.forEach(function(removedFile) {
                    if(!file.simhash || !removedFile.simhash) return;
                    var d = hammingDistance(file.simhash, removedFile.simhash);
                    if(d < 32) {
                        logger.debug("Hamming Distance: " + d + " / 128");
                        logger.info("Rename Detected: " + removedFile.path + " -> " + file.path);
                        logger.info("Set file.creationTime to: " + removedFile.creationTime);
                        file.creationTime = removedFile.creationTime;
                    }
                });
                return file;
            });

            if(cmd === "rebuild") {
                newFiles = changedFiles.concat(unchangedFiles).map(function(file) {
                    return {
                        path: file.path,
                        simhash: file.simhash,
                        creationTime: file.creationTime,
                        modificationTime: file.modificationTime
                    }
                }).concat(newFiles);
                changedFiles = [];
                unchangedFiles = [];
            }

            this.newFiles = newFiles;
            this.changedFiles = changedFiles;
            this.unchangedFiles = unchangedFiles;
            this.removedFiles = removedFiles;

            console.log(this);

            yield next;

            files = this.newFiles.concat(this.changedFiles, this.unchangedFiles);
            this.storage.setItem('files', JSON.stringify(files));
        }

        if(cmd === "watch") {
            watch.watchTree(sourceDir, function (f, curr, prev) {
                if (typeof f == "object" && prev === null && curr === null) {
                    // nothing changed
                } else {
                    logger.info("Change detected: " + f + ", rebuild now.");
                    co(function *() {
                        var output = yield spawn(argv[0], process.execArgv.concat([argv[1], 'build']));
                        logger.info(output);
                    })();
                }
            })
        }
    });
}
<|endoftext|>


<commit_before>YUI.add('files', function(Y) {

/**
* Ported fileutils methods from [Selleck](http://github.com/rgrove/selleck)
* @class Files
* @module yuidoc
*/

Y.Files = {};

/*
Selleck
Copyright (c) 2011 Yahoo! Inc.
Licensed under the BSD License.
*/

var fs = require('graceful-fs');
	fsPath   = require('path'),
	nodeUtil = require('util'),
	useFS = (fs.exists) ? fs : fsPath;

var exists = function(file, cb) {
	if (cb) {
		useFS.exists(file, cb);
	} else {
		return useFS.existsSync(file);
	}
};

Y.Files.exists = exists;

/**
* Copy a directory from one location to another
* @method copyDirectory
* @param {Path} source The source directory
* @param {Path} dest The destination directory
* @param {Boolean} [overwrite=false] Whether or not to overwrite destination files
  if they already exist.
* @param {Function} callback The callback to be executed when complete.
**/
function copyDirectory(source, dest, overwrite, callback) {
	// Allow callback as third arg.
	if (typeof overwrite === 'function') {
		callback = overwrite;
		overwrite = null;
	}

	fs.stat(source, afterSourceStat);

	function afterSourceStat(err, stats) {
		if (err) { return callback(err); }

		if (!stats.isDirectory()) {
			return callback(new Error("Source is not a directory: " + source));
		}

		fs.lstat(dest, afterDestStat);
	}

	function afterDestStat(err, stats) {
		if (err && err.code !== 'ENOENT') { return callback(err); }

		if (stats) {
			// If the destination is a file or a link, either delete it or
			// bubble an error if overwrite isn't true.
			if (stats.isFile() || stats.isSymbolicLink()) {
				if (overwrite) {
					deletePath(dest); // TODO: make this async
				} else {
					callback(new Error("Destination already exists: " + dest));
					return;
				}
			}

			afterMkDir();
		} else {
			fs.mkdir(dest, 0755, afterMkDir);
		}
	}

	function afterMkDir(err) {
		if (err && err.code !== 'EEXIST') { return callback(err); }
		fs.readdir(source, afterReadDir);
	}

	function afterReadDir(err, files) {
		if (err) { return callback(err); }

		var pending = files.length,
			filename;

		if (!pending) { return callback(); }

		while ((filename = files.shift())) {
			copyPath(fsPath.join(source, filename), fsPath.join(dest, filename), overwrite, function (err) {
				if (err) { return callback(err); }

				pending -= 1;

				if (!pending) {
					callback();
				}
			});
		}
	}
}
Y.Files.copyDirectory = copyDirectory;

/**
* Copy a file from one location to another
* @method copyFile
* @param {Path} source The source file
* @param {Path} dest The destination file
* @param {Boolean} [overwrite=false] Whether or not to overwrite destination files
  if they already exist.
* @param {Callback} callback The callback to be executed when complete.
* @param {Error} callback.err The Error returned from Node
**/
function copyFile(source, dest, overwrite, callback) {
	// Allow callback as third arg.
	if (typeof overwrite === 'function') {
		callback = overwrite;
		overwrite = null;
	}

	fs.lstat(source, function (err, sourceStats) {
		if (err) { return callback(err); }

		if (!sourceStats.isFile()) {
			return callback(new Error("Source is not a file: " + source));
		}

		fs.lstat(dest, function (err, destStats) {
			if (err && err.code !== 'ENOENT') { return callback(err); }

			if (destStats) {
				if (overwrite) {
					deletePath(dest); // TODO: make this async
				} else {
					callback(new Error("Destination already exists: " + dest));
					return;
				}
			}

			nodeUtil.pump(fs.createReadStream(source),
					fs.createWriteStream(dest, {mode: 0655}), callback);
		});
	});
}
Y.Files.copyFile = copyFile;

/**
If _source_ is a file, copies it to _dest_. If it's a directory, recursively
copies it and all files and directories it contains to _dest_.

Note that when attempting to copy a file into a directory, you should specify
the full path to the new file (including the new filename). Otherwise, it will
be interpreted as an attempt to copy the _source_ file *over* the _dest_
directory instead of *into* it.

Known issues:
- Doesn't preserve ownership or permissions on copied files/directories.

@method copyPath
@param {String} source Source path.
@param {String} dest Destination path.
@param {Boolean} [overwrite=false] Whether or not to overwrite destination files
if they already exist.
@param {Callback} callback The callback to execute when completed.
@param {Error} callback.err
**/
function copyPath(source, dest, overwrite, callback) {
	var destStats   = statSync(dest),
		sourceStats = statSync(source);

	// Allow callback as third arg.
	if (typeof overwrite === 'function') {
		callback = overwrite;
		overwrite = null;
	}

	if (!sourceStats) {
		callback(new Error("Source not found: " + source));
		return;
	}

	if (sourceStats.isFile()) {
		copyFile(source, dest, overwrite, callback);
	} else if (sourceStats.isDirectory()) {
		copyDirectory(source, dest, overwrite, callback);
	} else {
		callback(new Error("Source is neither a file nor a directory: " + source));
	}
}
Y.Files.copyPath = copyPath;

// TODO: copySymbolicLink()?

/**
If _path_ is a file, deletes it. If _path_ is a directory, recursively deletes
it and all files and directories it contains.

This method is synchronous.

@method deletePath
@param {String} path File or directory to delete.
**/
function deletePath(path) {
	var stats = fs.lstatSync(path);

	if (stats.isFile() || stats.isSymbolicLink()) {
		fs.unlinkSync(path);
	} else if (stats.isDirectory()) {
		fs.readdirSync(path).forEach(function (filename) {
			deletePath(fsPath.join(path, filename));
		});

		fs.rmdirSync(path);
	}
}
Y.Files.deletePath = deletePath;

/**
Check to see if this is a directory
@method isDirectory
@param {Path} path The path to check
@param {Boolean} [link=false] Also validate a symlink
@return {Boolean} True if it is a directory
**/
function isDirectory(path, link) {
	var i = false;
	link = (link === false) ? false : true;
	try {
		var stat = fs.lstatSync(path);

		if (stat) {
			if (stat.isSymbolicLink() && link) {
				stat = fs.statSync(path);
			}
			i = stat.isDirectory();
		}
	} catch (e) {
		i = false;
	}

	return i;
};

Y.Files.isDirectory = isDirectory;

/**
Check to see if this is a File
@method isFile
@param {Path} path The path to check
@param {Boolean} [link=false] Also validate a symlink
@return {Boolean} True if it is a file
**/
function isFile(path, link) {
	var i = false;
	try {
		var stat = fs.lstatSync(path);

		if (stat) {
			if (stat.isSymbolicLink() && link) {
				stat = fs.statSync(path);
			}
			i = stat.isFile();
		}
	} catch (e) {
		i = false;
	}

	return i;
}
Y.Files.isFile = isFile;

/**
Check to see if this is a SymLink
@method isSymbolicLink
@param {Path} path The path to check
@return {Boolean} True if it is a link
**/
function isSymbolicLink(path) {
	var stats = lstatSync(path);
	return stats ? stats.isSymbolicLink() : false;
}
Y.Files.isSymbolicLink = isSymbolicLink;

/**
Like `fs.lstatSync()`, but returns `null` instead of throwing when _path_
doesn't exist. Will still throw on other types of errors.

@method lstatSync
@param {String} path Path to stat.
@return {fs.Stats|null} `fs.Stats` object, or `null` if _path_ doesn't exist.
**/
function lstatSync(path) {
	try {
		return fs.lstatSync(path);
	} catch (ex) {
		if (ex.code === 'ENOENT') {
			return null;
		}

		throw ex;
	}
}
Y.Files.lstatSync = lstatSync;

/**
Like `fs.statSync()`, but returns `null` instead of throwing when _path_
doesn't exist. Will still throw on other types of errors.

@method statSync
@param {String} path Path to stat.
@return {fs.Stats|null} `fs.Stats` object, or `null` if _path_ doesn't exist.
**/
function statSync(path) {
	try {
		return fs.statSync(path);
	} catch (ex) {
		if (ex.code === 'ENOENT') {
			return null;
		}

		throw ex;
	}
}
Y.Files.statSync = statSync;

/**
Copy the theme assets directory
@method copyAssets
@param {Path} from The source directory
@param {Path} dest The destination directory
@param {Boolean} deleteFirst Should the directory be deleted if it exists
@param {Function} callback The callback to be executed
*/
function copyAssets() {
	var args        = Array.prototype.slice.call(arguments),
		callback    = args.pop(),
		from        = args.shift(),
		to          = args.shift(),
		deleteFirst = args.shift();

	if (from[0] === from[1]) {
		if (isDirectory(from[0])) {
			if (deleteFirst && isDirectory(to)) {
				deletePath(to);
			}

			copyPath(from[0], to, true, callback);
		} else {
			callback();
		}
	} else {
		if (isDirectory(from[0])) {
			if (deleteFirst && isDirectory(to)) {
				deletePath(to);
			}

			copyPath(from[0], to, true, function() {
				if (isDirectory(from[1])) {
					copyPath(from[1], to, true, callback)
				} else {
					callback();
				}
			});
		} else {
			callback();
		}

	}
}

Y.Files.copyAssets = copyAssets;

/**
* Helper method for getting JSON data from a local file
* @method getJSON
* @param {Path} filename The filename to parse JSON from
* @return {Object} The JSON data
*/
Y.Files.getJSON = function(filename) {
	var data = {};
	if (exists(filename)) {
		data = JSON.parse(fs.readFileSync(filename, "utf8"));
	};
	return data;
};

/**
* Helper method for writing files to disk. It wraps the NodeJS file API
* @method writeFile
* @param {Path} file The filename to write to
* @param {String} data The data to write
* @param {Callback} callback*
*/

var writeFileTimer = 100,
	readFileTimer = 100;

var writeFile = function(file, data, cb) {
	var flags = {
		flags: "w", encoding: "utf8", mode: 0644
	}
	var args = arguments;
	if (cb) {
		fs.writeFile(file, data, flags, function(err) {
			if (err && err.message.match(/^EMFILE, Too many open files/)) {
				Y.log('Writefile failed, too many open files (' + args[0] + '). Trying again.', 'warn', 'files');
				writeFileTimer++;
				Y.later(writeFileTimer, Y, writeFile, args);
				return;
			}
			cb();
		});
	} else {
		var out = fs.createWriteStream(file, flags);
		out.write(data);
		out.end();
	}
};

Y.Files.writeFile = writeFile;

var readFile = function(file, enc, cb) {
	var args = arguments;
	fs.readFile(file, enc, function(err, data) {
		if (err && err.message.match(/^EMFILE, Too many open files/)) {
			Y.log('Readfile failed, too many open files (' + args[0] + '). Trying again.', 'warn', 'files');
			readFileTimer++;
			Y.later(readFileTimer, Y, readFile, args);
			return;
		}
		cb(err, data);
	});
};

Y.Files.readFile = readFile;

});
<commit_msg>.svn 폴더는 가만 냅둬<commit_after>YUI.add('files', function(Y) {

/**
* Ported fileutils methods from [Selleck](http://github.com/rgrove/selleck)
* @class Files
* @module yuidoc
*/

Y.Files = {};

/*
Selleck
Copyright (c) 2011 Yahoo! Inc.
Licensed under the BSD License.
*/

var fs = require('graceful-fs');
	fsPath   = require('path'),
	nodeUtil = require('util'),
	useFS = (fs.exists) ? fs : fsPath;

var exists = function(file, cb) {
	if (cb) {
		useFS.exists(file, cb);
	} else {
		return useFS.existsSync(file);
	}
};

Y.Files.exists = exists;

/**
* Copy a directory from one location to another
* @method copyDirectory
* @param {Path} source The source directory
* @param {Path} dest The destination directory
* @param {Boolean} [overwrite=false] Whether or not to overwrite destination files
  if they already exist.
* @param {Function} callback The callback to be executed when complete.
**/
function copyDirectory(source, dest, overwrite, callback) {
	// Allow callback as third arg.
	if (typeof overwrite === 'function') {
		callback = overwrite;
		overwrite = null;
	}

	fs.stat(source, afterSourceStat);

	function afterSourceStat(err, stats) {
		if (err) { return callback(err); }

		if (!stats.isDirectory()) {
			return callback(new Error("Source is not a directory: " + source));
		}

		fs.lstat(dest, afterDestStat);
	}

	function afterDestStat(err, stats) {
		if (err && err.code !== 'ENOENT') { return callback(err); }

		if (stats) {
			// If the destination is a file or a link, either delete it or
			// bubble an error if overwrite isn't true.
			if (stats.isFile() || stats.isSymbolicLink()) {
				if (overwrite) {
					deletePath(dest); // TODO: make this async
				} else {
					callback(new Error("Destination already exists: " + dest));
					return;
				}
			}

			afterMkDir();
		} else {
			fs.mkdir(dest, 0755, afterMkDir);
		}
	}

	function afterMkDir(err) {
		if (err && err.code !== 'EEXIST') { return callback(err); }
		fs.readdir(source, afterReadDir);
	}

	function afterReadDir(err, files) {
		if (err) { return callback(err); }

		var pending = files.length,
			filename;

		if (!pending) { return callback(); }

		while ((filename = files.shift())) {

			if (filename === '.svn') {

				pending -= 1;

				if (!pending) {
					callback();
				}

				continue;

			}

			copyPath(fsPath.join(source, filename), fsPath.join(dest, filename), overwrite, function (err) {
				if (err) { return callback(err); }

				pending -= 1;

				if (!pending) {
					callback();
				}
			});
		}
	}
}
Y.Files.copyDirectory = copyDirectory;

/**
* Copy a file from one location to another
* @method copyFile
* @param {Path} source The source file
* @param {Path} dest The destination file
* @param {Boolean} [overwrite=false] Whether or not to overwrite destination files
  if they already exist.
* @param {Callback} callback The callback to be executed when complete.
* @param {Error} callback.err The Error returned from Node
**/
function copyFile(source, dest, overwrite, callback) {

	// Allow callback as third arg.
	if (typeof overwrite === 'function') {
		callback = overwrite;
		overwrite = null;
	}

	fs.lstat(source, function (err, sourceStats) {
		if (err) { return callback(err); }

		if (!sourceStats.isFile()) {
			return callback(new Error("Source is not a file: " + source));
		}

		fs.lstat(dest, function (err, destStats) {
			if (err && err.code !== 'ENOENT') { return callback(err); }

			if (destStats) {
				if (overwrite) {
					deletePath(dest); // TODO: make this async
				} else {
					callback(new Error("Destination already exists: " + dest));
					return;
				}
			}

			nodeUtil.pump(fs.createReadStream(source),
					fs.createWriteStream(dest, {mode: 0655}), callback);
		});
	});
}
Y.Files.copyFile = copyFile;

/**
If _source_ is a file, copies it to _dest_. If it's a directory, recursively
copies it and all files and directories it contains to _dest_.

Note that when attempting to copy a file into a directory, you should specify
the full path to the new file (including the new filename). Otherwise, it will
be interpreted as an attempt to copy the _source_ file *over* the _dest_
directory instead of *into* it.

Known issues:
- Doesn't preserve ownership or permissions on copied files/directories.

@method copyPath
@param {String} source Source path.
@param {String} dest Destination path.
@param {Boolean} [overwrite=false] Whether or not to overwrite destination files
if they already exist.
@param {Callback} callback The callback to execute when completed.
@param {Error} callback.err
**/
function copyPath(source, dest, overwrite, callback) {
	var destStats   = statSync(dest),
		sourceStats = statSync(source);

	// Allow callback as third arg.
	if (typeof overwrite === 'function') {
		callback = overwrite;
		overwrite = null;
	}

	if (!sourceStats) {
		callback(new Error("Source not found: " + source));
		return;
	}

	if (sourceStats.isFile()) {
		copyFile(source, dest, overwrite, callback);
	} else if (sourceStats.isDirectory()) {
		copyDirectory(source, dest, overwrite, callback);
	} else {
		callback(new Error("Source is neither a file nor a directory: " + source));
	}
}
Y.Files.copyPath = copyPath;

// TODO: copySymbolicLink()?

/**
If _path_ is a file, deletes it. If _path_ is a directory, recursively deletes
it and all files and directories it contains.

This method is synchronous.

@method deletePath
@param {String} path File or directory to delete.
**/
function deletePath(path) {
	var stats = fs.lstatSync(path);

	if (stats.isFile() || stats.isSymbolicLink()) {
		fs.unlinkSync(path);
	} else if (stats.isDirectory()) {
		fs.readdirSync(path).forEach(function (filename) {
			deletePath(fsPath.join(path, filename));
		});

		fs.rmdirSync(path);
	}
}
Y.Files.deletePath = deletePath;

/**
Check to see if this is a directory
@method isDirectory
@param {Path} path The path to check
@param {Boolean} [link=false] Also validate a symlink
@return {Boolean} True if it is a directory
**/
function isDirectory(path, link) {
	var i = false;
	link = (link === false) ? false : true;
	try {
		var stat = fs.lstatSync(path);

		if (stat) {
			if (stat.isSymbolicLink() && link) {
				stat = fs.statSync(path);
			}
			i = stat.isDirectory();
		}
	} catch (e) {
		i = false;
	}

	return i;
};

Y.Files.isDirectory = isDirectory;

/**
Check to see if this is a File
@method isFile
@param {Path} path The path to check
@param {Boolean} [link=false] Also validate a symlink
@return {Boolean} True if it is a file
**/
function isFile(path, link) {
	var i = false;
	try {
		var stat = fs.lstatSync(path);

		if (stat) {
			if (stat.isSymbolicLink() && link) {
				stat = fs.statSync(path);
			}
			i = stat.isFile();
		}
	} catch (e) {
		i = false;
	}

	return i;
}
Y.Files.isFile = isFile;

/**
Check to see if this is a SymLink
@method isSymbolicLink
@param {Path} path The path to check
@return {Boolean} True if it is a link
**/
function isSymbolicLink(path) {
	var stats = lstatSync(path);
	return stats ? stats.isSymbolicLink() : false;
}
Y.Files.isSymbolicLink = isSymbolicLink;

/**
Like `fs.lstatSync()`, but returns `null` instead of throwing when _path_
doesn't exist. Will still throw on other types of errors.

@method lstatSync
@param {String} path Path to stat.
@return {fs.Stats|null} `fs.Stats` object, or `null` if _path_ doesn't exist.
**/
function lstatSync(path) {
	try {
		return fs.lstatSync(path);
	} catch (ex) {
		if (ex.code === 'ENOENT') {
			return null;
		}

		throw ex;
	}
}
Y.Files.lstatSync = lstatSync;

/**
Like `fs.statSync()`, but returns `null` instead of throwing when _path_
doesn't exist. Will still throw on other types of errors.

@method statSync
@param {String} path Path to stat.
@return {fs.Stats|null} `fs.Stats` object, or `null` if _path_ doesn't exist.
**/
function statSync(path) {
	try {
		return fs.statSync(path);
	} catch (ex) {
		if (ex.code === 'ENOENT') {
			return null;
		}

		throw ex;
	}
}
Y.Files.statSync = statSync;

/**
Copy the theme assets directory
@method copyAssets
@param {Path} from The source directory
@param {Path} dest The destination directory
@param {Boolean} deleteFirst Should the directory be deleted if it exists
@param {Function} callback The callback to be executed
*/
function copyAssets() {
	var args        = Array.prototype.slice.call(arguments),
		callback    = args.pop(),
		from        = args.shift(),
		to          = args.shift(),
		deleteFirst = args.shift();

	if (from[0] === from[1]) {
		if (isDirectory(from[0])) {
			if (deleteFirst && isDirectory(to)) {
				deletePath(to);
			}

			copyPath(from[0], to, true, callback);
		} else {
			callback();
		}
	} else {
		if (isDirectory(from[0])) {
			if (deleteFirst && isDirectory(to)) {
				deletePath(to);
			}

			copyPath(from[0], to, true, function() {
				if (isDirectory(from[1])) {
					copyPath(from[1], to, true, callback)
				} else {
					callback();
				}
			});
		} else {
			callback();
		}

	}
}

Y.Files.copyAssets = copyAssets;

/**
* Helper method for getting JSON data from a local file
* @method getJSON
* @param {Path} filename The filename to parse JSON from
* @return {Object} The JSON data
*/
Y.Files.getJSON = function(filename) {
	var data = {};
	if (exists(filename)) {
		data = JSON.parse(fs.readFileSync(filename, "utf8"));
	};
	return data;
};

/**
* Helper method for writing files to disk. It wraps the NodeJS file API
* @method writeFile
* @param {Path} file The filename to write to
* @param {String} data The data to write
* @param {Callback} callback*
*/

var writeFileTimer = 100,
	readFileTimer = 100;

var writeFile = function(file, data, cb) {
	var flags = {
		flags: "w", encoding: "utf8", mode: 0644
	}
	var args = arguments;
	if (cb) {
		fs.writeFile(file, data, flags, function(err) {
			if (err && err.message.match(/^EMFILE, Too many open files/)) {
				Y.log('Writefile failed, too many open files (' + args[0] + '). Trying again.', 'warn', 'files');
				writeFileTimer++;
				Y.later(writeFileTimer, Y, writeFile, args);
				return;
			}
			cb();
		});
	} else {
		var out = fs.createWriteStream(file, flags);
		out.write(data);
		out.end();
	}
};

Y.Files.writeFile = writeFile;

var readFile = function(file, enc, cb) {
	var args = arguments;
	fs.readFile(file, enc, function(err, data) {
		if (err && err.message.match(/^EMFILE, Too many open files/)) {
			Y.log('Readfile failed, too many open files (' + args[0] + '). Trying again.', 'warn', 'files');
			readFileTimer++;
			Y.later(readFileTimer, Y, readFile, args);
			return;
		}
		cb(err, data);
	});
};

Y.Files.readFile = readFile;

});
<|endoftext|>