/* ==========================================================
 * bootstrap-twipsy.js v1.4.0
 * http://twitter.github.com/bootstrap/javascript.html#twipsy
 * Adapted from the original jQuery.tipsy by Jason Frame
 * Adjusted for Brackets
 * ==========================================================
 * Copyright 2011 Twitter, Inc.
 *
 * 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.
 * ========================================================== */

!function( $ ) {

  "use strict"

  /***** [changed for Brackets] *****/
  // Undefined until the focus state changed once
  var _windowHasFocus;

  $(window)
    .focus(function _onWindowGainedFocus() {
      _windowHasFocus = true;
    })
    .blur(function _onWindowLostFocus() {
      _windowHasFocus = false;
    });
  /***** [/changed for Brackets] *****/

 /* CSS TRANSITION SUPPORT (https://gist.github.com/373874)
  * ======================================================= */

  var transitionEnd

  $(document).ready(function () {

    $.support.transition = (function () {

      var transitionEnd = (function () {

        var el = document.createElement('bootstrap')
          , transEndEventNames = {
               'WebkitTransition' : 'webkitTransitionEnd'
            ,  'MozTransition'    : 'transitionend'
            ,  'OTransition'      : 'oTransitionEnd'
            ,  'msTransition'     : 'MSTransitionEnd'
            ,  'transition'       : 'transitionend'
            }
          , name

        for (name in transEndEventNames){
          if (el.style[name] !== undefined) {
            return transEndEventNames[name]
          }
        }

      }())

      return transitionEnd && {
        end: transitionEnd
      }

    })()

    // set CSS transition event type
    if ( $.support.transition ) {
      transitionEnd = $.support.transition.end
    }

  })

 /* TWIPSY PUBLIC CLASS DEFINITION
  * ============================== */

  var Twipsy = function ( element, options ) {
    this.$element = $(element)
    this.options = options
    this.enabled = true
    /***** [changed for Brackets] *****/
    this.autoHideTimeout = null;
    /***** [/changed for Brackets] *****/
    this.fixTitle()
  }

  Twipsy.prototype = {

    show: function() {
      /***** [changed for Brackets: moved some variables to updatePosition()] *****/
      var $tip
        , that = this;
      /***** [/changed for Brackets] *****/

      if (this.hasContent() && this.enabled) {
        $tip = this.tip()
        this.setContent()

        if (this.options.animate) {
          $tip.addClass('fade')
        }

        $tip
          .remove()
          .css({ top: 0, left: 0, display: 'block' })
          .prependTo(document.body)

/***** [changed for Brackets] *****/
        this.updatePosition();

        $(window).off("resize", this.resizeHandler);
        this.resizeHandler = function(e) {
          that.updatePosition();
        };
        $(window).on("resize", this.resizeHandler);

        if (this.options.autoHideDelay) {
          var startAutoHide = function () {
            window.clearTimeout(that.autoHideTimeout);
            that.autoHideTimeout = window.setTimeout(function () {
              that.hide();
            }, that.options.autoHideDelay);
          }
          if (_windowHasFocus) {
            startAutoHide();
          } else {
            $(window).one("focus", startAutoHide);
          }
        }

        $tip.addClass('in');
      }
    }

  , updatePosition: function () {
      var pos
        , actualWidth
        , actualHeight
        , paddingLeft
        , paddingRight
        , surplusRight
        , shiftArrow
        , placement
        , $tip
        , $arrow
        , tp
        , that = this

      $tip = this.tip()

      pos = $.extend({}, this.$element.offset(), {
        width: this.$element[0].offsetWidth
      , height: this.$element[0].offsetHeight
      })

      paddingLeft  = parseInt(this.$element.css("padding-left"),  10);
      paddingRight = parseInt(this.$element.css("padding-right"), 10);

      pos.left += paddingLeft;
      pos.width -= (paddingLeft + paddingRight);

      actualWidth = $tip[0].offsetWidth
      actualHeight = $tip[0].offsetHeight

      placement = maybeCall(this.options.placement, this, [ $tip[0], this.$element[0] ])
      // Add the placement class so the arrow's margin can be determined
      $tip.addClass(placement)

      switch (placement) {
        case 'below':
          tp = {top: pos.top + pos.height + this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2}
          break
        case 'above':
          tp = {top: pos.top - actualHeight - this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2}
          break
        case 'left':
          tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth - this.options.offset}
          break
        case 'right':
          tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width + this.options.offset}
          break
      }

      shiftArrow = 0;

      surplusRight = (tp.left + actualWidth - $(document.body).width());
      if (surplusRight > 0) {
        shiftArrow = surplusRight;
        tp.left -= surplusRight;
      } else if (tp.left < 0) {
        shiftArrow = tp.left;
        tp.left = 0;
      }

      if (surplusRight > 0) {
        $arrow = $tip.find(".tooltip-arrow");
        if (! this.defaultMargin) {
          this.defaultMargin = parseInt($arrow.css("margin-left"), 10);
        }
        $arrow.css("margin-left", this.defaultMargin + shiftArrow);
      }

      $tip.css(tp);
    }
/***** [/changed for Brackets] *****/

  , setContent: function () {
      var $tip = this.tip()
      $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](this.getTitle())
      $tip[0].className = 'tooltip'
    }

  , hide: function() {
      var that = this
        , $tip = this.tip()

      $tip.removeClass('in')

      function removeElement () {
        $tip.remove()
      }

      $.support.transition && this.$tip.hasClass('fade') ?
        $tip.bind(transitionEnd, removeElement) :
        removeElement()

      /***** [changed for Brackets] *****/
      window.clearTimeout(this.autoHideTimeout);
      $(window).off("resize", this.resizeHandler)
      /***** [/changed for Brackets] *****/
    }

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

  , hasContent: function () {
      return this.getTitle()
    }

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

        this.fixTitle()

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

        title = ('' + title).replace(/(^\s*|\s*$)/, "")

        return title || o.fallback
    }

  , tip: function() {
      return this.$tip = this.$tip || $('
').html(this.options.template)
    }

  , validate: function() {
      if (!this.$element[0].parentNode) {
        this.hide()
        this.$element = null
        this.options = null
      }
    }

  , enable: function() {
      this.enabled = true
    }

  , disable: function() {
      this.enabled = false
    }

  , toggleEnabled: function() {
      this.enabled = !this.enabled
    }

  , toggle: function () {
      this[this.tip().hasClass('in') ? 'hide' : 'show']()
    }

  }

 /* TWIPSY PRIVATE METHODS
  * ====================== */

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

 /* TWIPSY PLUGIN DEFINITION
  * ======================== */

  $.fn.twipsy = function (options) {
    $.fn.twipsy.initWith.call(this, options, Twipsy, 'twipsy')
    return this
  }

  $.fn.twipsy.initWith = function (options, Constructor, name) {
    var twipsy
      , binder
      , eventIn
      , eventOut

    if (options === true) {
      return this.data(name)
    } else if (typeof options == 'string') {
      twipsy = this.data(name)
      if (twipsy) {
        twipsy[options]()
      }
      return this
    }

    options = $.extend({}, $.fn[name].defaults, options)

    function get(ele) {
      var twipsy = $.data(ele, name)

      if (!twipsy) {
        twipsy = new Constructor(ele, $.fn.twipsy.elementOptions(ele, options))
        $.data(ele, name, twipsy)
      }

      return twipsy
    }

    function enter() {
      var twipsy = get(this)
      twipsy.hoverState = 'in'

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

    function leave() {
      var twipsy = get(this)
      twipsy.hoverState = 'out'
      if (options.delayOut == 0) {
        twipsy.hide()
      } else {
        setTimeout(function() {
          if (twipsy.hoverState == 'out') {
            twipsy.hide()
          }
        }, options.delayOut)
      }
    }

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

    if (options.trigger != 'manual') {
      binder   = options.live ? 'live' : 'bind'
      eventIn  = options.trigger == 'hover' ? 'mouseenter' : 'focus'
      eventOut = options.trigger == 'hover' ? 'mouseleave' : 'blur'
      this[binder](eventIn, enter)[binder](eventOut, leave)
    }

    return this
  }

  $.fn.twipsy.Twipsy = Twipsy

  $.fn.twipsy.defaults = {
    animate: true
  , delayIn: 0
  , delayOut: 0
  , fallback: ''
  , placement: 'above'
  , html: false
  , live: false
  , offset: 0
  , title: 'title'
  , trigger: 'hover'
  , template: '

'
  }

  $.fn.twipsy.rejectAttrOptions = [ 'title' ]

  $.fn.twipsy.elementOptions = function(ele, options) {
    var data = $(ele).data()
      , rejects = $.fn.twipsy.rejectAttrOptions
      , i = rejects.length

    while (i--) {
      delete data[rejects[i]]
    }

    return $.extend({}, options, data)
  }

}( window.jQuery || window.ender );


keep keep keep keep replace keep keep keep

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

/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */
/*global define, window, $, brackets, PathUtils, Mustache, document */
/*unittests: Install Extension Dialog*/

define(function (require, exports, module) {
    "use strict";

    require("thirdparty/path-utils/path-utils.min");

    var Dialogs                = require("widgets/Dialogs"),
        StringUtils            = require("utils/StringUtils"),
        Strings                = require("strings"),
        Commands               = require("command/Commands"),
        CommandManager         = require("command/CommandManager"),
        KeyEvent               = require("utils/KeyEvent"),
        Package                = require("extensibility/Package"),
        NativeApp              = require("utils/NativeApp"),
        InstallDialogTemplate  = require("text!htmlContent/install-extension-dialog.html");

    var STATE_CLOSED            = 0,
        STATE_START             = 1,
        STATE_VALID_URL         = 2,
        STATE_INSTALLING        = 3,
        STATE_INSTALLED         = 4,
        STATE_INSTALL_FAILED    = 5,
        STATE_CANCELING_INSTALL = 6,
        STATE_CANCELING_HUNG    = 7,
        STATE_INSTALL_CANCELED  = 8,
        STATE_ALREADY_INSTALLED = 9,
        STATE_NEEDS_UPDATE      = 10;

    /**
     * @constructor
     * Creates a new extension installer dialog.
     * @param {{install: function(url), cancel: function()}} installer The installer backend to use.
     */
    function InstallExtensionDialog(installer) {
        this._installer = installer;
        this._state = STATE_CLOSED;
        this._installResult = null;

        // Timeout before we allow user to leave STATE_INSTALL_CANCELING without waiting for a resolution
        // (per-instance so we can poke it for unit testing)
        this._cancelTimeout = 10 * 1000;
    }

    /** @type {jQuery} The dialog root. */
    InstallExtensionDialog.prototype.$dlg = null;

    /** @type {jQuery} The url input field. */
    InstallExtensionDialog.prototype.$url = null;

    /** @type {jQuery} The ok button. */
    InstallExtensionDialog.prototype.$okButton = null;

    /** @type {jQuery} The cancel button. */
    InstallExtensionDialog.prototype.$cancelButton = null;

    /** @type {jQuery} The area containing the url input label and field. */
    InstallExtensionDialog.prototype.$inputArea = null;

    /** @type {jQuery} The area containing the installation message and spinner. */
    InstallExtensionDialog.prototype.$msgArea = null;

    /** @type {jQuery} The span containing the installation message. */
    InstallExtensionDialog.prototype.$msg = null;

    /** @type {jQuery} The "Browse Extensions" button. */
    InstallExtensionDialog.prototype.$browseExtensionsButton = null;

    /** @type {$.Deferred} A deferred that's resolved/rejected when the dialog is closed and
        something has/hasn't been installed successfully. */
    InstallExtensionDialog.prototype._dialogDeferred = null;

    /** @type {{install: function(url), cancel: function()}} installer The installer backend for this dialog. */
    InstallExtensionDialog.prototype._installer = null;

    /** @type {number} The current state of the dialog; one of the STATE_* constants above. */
    InstallExtensionDialog.prototype._state = null;

    /**
     * @private
     * Transitions the dialog into a new state as the installation proceeds.
     * @param {number} newState The state to transition into; one of the STATE_* variables.
     */
    InstallExtensionDialog.prototype._enterState = function (newState) {
        var url,
            msg,
            self = this,
            prevState = this._state;

        // Store the new state up front in case some of the processing below ends up changing
        // the state again immediately.
        this._state = newState;

        switch (newState) {
        case STATE_START:
            // This should match the default appearance of the dialog when it first opens.
            this.$msg.find(".spinner").remove();
            this.$msgArea.hide();
            this.$inputArea.show();
            this.$okButton
                .prop("disabled", true)
                .text(Strings.INSTALL);
            break;

        case STATE_VALID_URL:
            this.$okButton.prop("disabled", false);
            break;

        case STATE_INSTALLING:
            url = this.$url.val();
            this.$inputArea.hide();
            this.$browseExtensionsButton.hide();
            this.$msg.text(StringUtils.format(Strings.INSTALLING_FROM, url))
                .append("<span class='spinner spin'/>");
            this.$msgArea.show();
            this.$okButton.prop("disabled", true);
            this._installer.install(url)
                .done(function (result) {
                    self._installResult = result;
                    if (result.installationStatus === Package.InstallationStatuses.ALREADY_INSTALLED ||
                            result.installationStatus === Package.InstallationStatuses.OLDER_VERSION ||
                            result.installationStatus === Package.InstallationStatuses.SAME_VERSION) {
                        self._enterState(STATE_ALREADY_INSTALLED);
                    } else if (result.installationStatus === Package.InstallationStatuses.NEEDS_UPDATE) {
                        self._enterState(STATE_NEEDS_UPDATE);
                    } else {
                        self._enterState(STATE_INSTALLED);
                    }
                })
                .fail(function (err) {
                    // If the "failure" is actually a user-requested cancel, don't show an error UI
                    if (err === "CANCELED") {
                        console.assert(self._state === STATE_CANCELING_INSTALL || self._state === STATE_CANCELING_HUNG);
                        self._enterState(STATE_INSTALL_CANCELED);
                    } else {
                        self._errorMessage = Package.formatError(err);
                        self._enterState(STATE_INSTALL_FAILED);
                    }
                });
            break;

        case STATE_CANCELING_INSTALL:
            // This should call back the STATE_INSTALLING fail() handler above, unless it's too late to cancel
            // in which case we'll still jump to STATE_INSTALLED after this
            this.$cancelButton.prop("disabled", true);
            this.$msg.text(Strings.CANCELING_INSTALL);
            this._installer.cancel();
            window.setTimeout(function () {
                if (self._state === STATE_CANCELING_INSTALL) {
                    self._enterState(STATE_CANCELING_HUNG);
                }
            }, this._cancelTimeout);
            break;

        case STATE_CANCELING_HUNG:
            this.$msg.text(Strings.CANCELING_HUNG);
            this.$okButton
                .removeAttr("disabled")
                .text(Strings.CLOSE);
            break;

        case STATE_INSTALLED:
        case STATE_INSTALL_FAILED:
        case STATE_INSTALL_CANCELED:
            if (newState === STATE_INSTALLED) {
                msg = Strings.INSTALL_SUCCEEDED;
            } else if (newState === STATE_INSTALL_FAILED) {
                msg = Strings.INSTALL_FAILED;
            } else {
                msg = Strings.INSTALL_CANCELED;
            }
            this.$msg.html($("<strong/>").text(msg));
            if (this._errorMessage) {
                this.$msg.append($("<p/>").text(this._errorMessage));
            }
            this.$okButton
                .removeAttr("disabled")
                .text(Strings.CLOSE);
            this.$cancelButton.hide();
            break;

        case STATE_ALREADY_INSTALLED:
            var installResult = this._installResult;
            var status = installResult.installationStatus;
            var msgText = Strings["EXTENSION_" + status];
            if (status === Package.InstallationStatuses.OLDER_VERSION) {
                msgText = StringUtils.format(msgText, installResult.metadata.version, installResult.installedVersion);
            }
            this.$msg.text(msgText);
            this.$okButton
                .prop("disabled", false)
                .text(Strings.OVERWRITE);
            break;

        // When we identify that an update needs to be installed (something that
        // happens at quitting time), we just dismiss the dialog.
        case STATE_NEEDS_UPDATE:
            self._enterState(STATE_CLOSED);
            break;

        case STATE_CLOSED:
            $(document.body).off(".installDialog");

           // Only resolve as successful if we actually installed something.
            Dialogs.cancelModalDialogIfOpen("install-extension-dialog");
            if (prevState === STATE_INSTALLED || prevState === STATE_NEEDS_UPDATE) {
                this._dialogDeferred.resolve(this._installResult);
            } else {
                this._dialogDeferred.reject();
            }
            break;
        }
    };

    /**
     * @private
     * Handle a click on the Cancel button, which either cancels an ongoing installation (leaving
     * the dialog open), or closes the dialog if no installation is in progress.
     */
    InstallExtensionDialog.prototype._handleCancel = function () {
        if (this._state === STATE_INSTALLING) {
            this._enterState(STATE_CANCELING_INSTALL);
        } else if (this._state === STATE_ALREADY_INSTALLED) {
            // If we were prompting the user about overwriting a previous installation,
            // and the user cancels, we can delete the downloaded file.
            if (this._installResult && this._installResult.localPath) {
                var filename = this._installResult.localPath;
                brackets.fs.unlink(filename, function () {
                    // ignore the result
                });
            }
            this._enterState(STATE_CLOSED);
        } else if (this._state !== STATE_CANCELING_INSTALL) {
            this._enterState(STATE_CLOSED);
        }
    };

    /**
     * @private
     * Handle a click on the default button, which is "Install" while we're waiting for the
     * user to enter a URL, and "Close" once we've successfully finished installation.
     */
    InstallExtensionDialog.prototype._handleOk = function () {
        if (this._state === STATE_INSTALLED ||
                this._state === STATE_INSTALL_FAILED ||
                this._state === STATE_INSTALL_CANCELED ||
                this._state === STATE_CANCELING_HUNG) {
            // In these end states, this is a "Close" button: just close the dialog and indicate
            // success.
            this._enterState(STATE_CLOSED);
        } else if (this._state === STATE_VALID_URL) {
            this._enterState(STATE_INSTALLING);
        } else if (this._state === STATE_ALREADY_INSTALLED) {
            this._enterState(STATE_NEEDS_UPDATE);
        }
    };

    /**
     * @private
     * Handle key up events on the document. We use this to detect the Esc key.
     */
    InstallExtensionDialog.prototype._handleKeyUp = function (e) {
        if (e.keyCode === KeyEvent.DOM_VK_ESCAPE) {
            this._handleCancel();
        }
    };

    /**
     * @private
     * Handle typing in the URL field.
     */
    InstallExtensionDialog.prototype._handleUrlInput = function () {
        var url = this.$url.val(),
            valid = (url !== "");
        if (!valid && this._state === STATE_VALID_URL) {
            this._enterState(STATE_START);
        } else if (valid && this._state === STATE_START) {
            this._enterState(STATE_VALID_URL);
        }
    };

    /**
     * @private
     * Closes the dialog if it's not already closed. For unit testing only.
     */
    InstallExtensionDialog.prototype._close = function () {
        if (this._state !== STATE_CLOSED) {
            this._enterState(STATE_CLOSED);
        }
    };

    /**
     * Initialize and show the dialog.
     * @param {string=} urlToInstall If specified, immediately starts installing the given file as if the user had
     *     specified it.
     * @return {$.Promise} A promise object that will be resolved when the selected extension
     *     has finished installing, or rejected if the dialog is cancelled.
     */
    InstallExtensionDialog.prototype.show = function (urlToInstall) {
        if (this._state !== STATE_CLOSED) {
            // Somehow the dialog got invoked twice. Just ignore this.
            return this._dialogDeferred.promise();
        }

        // We ignore the promise returned by showModalDialogUsingTemplate, since we're managing the
        // lifecycle of the dialog ourselves.
        Dialogs.showModalDialogUsingTemplate(Mustache.render(InstallDialogTemplate, Strings), false);

        this.$dlg          = $(".install-extension-dialog.instance");
        this.$url          = this.$dlg.find(".url").focus();
        this.$okButton     = this.$dlg.find(".dialog-button[data-button-id='ok']");
        this.$cancelButton = this.$dlg.find(".dialog-button[data-button-id='cancel']");
        this.$inputArea    = this.$dlg.find(".input-field");
        this.$msgArea      = this.$dlg.find(".message-field");
        this.$msg          = this.$msgArea.find(".message");
        this.$browseExtensionsButton = this.$dlg.find(".browse-extensions");

        this.$okButton.on("click", this._handleOk.bind(this));
        this.$cancelButton.on("click", this._handleCancel.bind(this));
        this.$url.on("input", this._handleUrlInput.bind(this));
        this.$browseExtensionsButton.on("click", function () {
            NativeApp.openURLInDefaultBrowser(brackets.config.extension_wiki_url);
        });
        $(document.body).on("keyup.installDialog", this._handleKeyUp.bind(this));

        this._enterState(STATE_START);
        if (urlToInstall) {
            // Act as if the user had manually entered the URL.
            this.$url.val(urlToInstall);
            this._enterState(STATE_VALID_URL);
            this._enterState(STATE_INSTALLING);
        }

        this._dialogDeferred = new $.Deferred();
        return this._dialogDeferred.promise();
    };

    /** Mediates between this module and the Package extension-installation utils. Mockable for unit-testing. */
    function InstallerFacade() { }
    InstallerFacade.prototype.install = function (url) {
        if (this.pendingInstall) {
            console.error("Extension installation already pending");
            return new $.Deferred().reject("DOWNLOAD_ID_IN_USE").promise();
        }
        this.pendingInstall = Package.installFromURL(url);

        // Store now since we'll null pendingInstall immediately if the promise was resolved synchronously
        var promise = this.pendingInstall.promise;

        var self = this;
        this.pendingInstall.promise.always(function () {
            self.pendingInstall = null;
        });

        return promise;
    };
    InstallerFacade.prototype.cancel = function () {
        this.pendingInstall.cancel();
    };

    /**
     * @private
     * Show a dialog that allows the user to enter the URL of an extension ZIP file to install.
     * @return {$.Promise} A promise object that will be resolved when the selected extension
     *     has finished installing, or rejected if the dialog is cancelled.
     */
    function showDialog() {
        var dlg = new InstallExtensionDialog(new InstallerFacade());
        return dlg.show();
    }

    /**
     * @private
     * Show the installation dialog and automatically begin installing the given URL.
     * @param {string=} urlToInstall If specified, immediately starts installing the given file as if the user had
     *     specified it.
     * @return {$.Promise} A promise object that will be resolved when the selected extension
     *     has finished installing, or rejected if the dialog is cancelled.
     */
    function installUsingDialog(urlToInstall) {
        var dlg = new InstallExtensionDialog(new InstallerFacade());
        return dlg.show(urlToInstall);
    }

    exports.showDialog = showDialog;
    exports.installUsingDialog = installUsingDialog;

    // Exposed for unit testing only
    exports._Dialog = InstallExtensionDialog;
});


/*!
 * knox - auth
 * Copyright(c) 2010 LearnBoost <dev@learnboost.com>
 * MIT Licensed
 */

/**
 * Module dependencies.
 */

var crypto = require('crypto')
  , parse = require('url').parse
  ;

/**
 * Valid keys.
 */

var keys =
  [ 'acl'
  , 'location'
  , 'logging'
  , 'notification'
  , 'partNumber'
  , 'policy'
  , 'requestPayment'
  , 'torrent'
  , 'uploadId'
  , 'uploads'
  , 'versionId'
  , 'versioning'
  , 'versions'
  , 'website'
  ]

/**
 * Return an "Authorization" header value with the given `options`
 * in the form of "AWS <key>:<signature>"
 *
 * @param {Object} options
 * @return {String}
 * @api private
 */

function authorization (options) {
  return 'AWS ' + options.key + ':' + sign(options)
}

module.exports = authorization
module.exports.authorization = authorization

/**
 * Simple HMAC-SHA1 Wrapper
 *
 * @param {Object} options
 * @return {String}
 * @api private
 */

function hmacSha1 (options) {
  return crypto.createHmac('sha1', options.secret).update(options.message).digest('base64')
}

module.exports.hmacSha1 = hmacSha1

/**
 * Create a base64 sha1 HMAC for `options`.
 *
 * @param {Object} options
 * @return {String}
 * @api private
 */

function sign (options) {
  options.message = stringToSign(options)
  return hmacSha1(options)
}
module.exports.sign = sign

/**
 * Create a base64 sha1 HMAC for `options`.
 *
 * Specifically to be used with S3 presigned URLs
 *
 * @param {Object} options
 * @return {String}
 * @api private
 */

function signQuery (options) {
  options.message = queryStringToSign(options)
  return hmacSha1(options)
}
module.exports.signQuery= signQuery

/**
 * Return a string for sign() with the given `options`.
 *
 * Spec:
 *
 *    <verb>\n
 *    <md5>\n
 *    <content-type>\n
 *    <date>\n
 *    [headers\n]
 *    <resource>
 *
 * @param {Object} options
 * @return {String}
 * @api private
 */

function stringToSign (options) {
  var headers = options.amazonHeaders || ''
  if (headers) headers += '\n'
  var r =
    [ options.verb
    , options.md5
    , options.contentType
    , options.date.toUTCString()
    , headers + options.resource
    ]
  return r.join('\n')
}
module.exports.queryStringToSign = stringToSign

/**
 * Return a string for sign() with the given `options`, but is meant exclusively
 * for S3 presigned URLs
 *
 * Spec:
 *
 *    <date>\n
 *    <resource>
 *
 * @param {Object} options
 * @return {String}
 * @api private
 */

function queryStringToSign (options){
  return 'GET\n\n\n' + options.date + '\n' + options.resource
}
module.exports.queryStringToSign = queryStringToSign

/**
 * Perform the following:
 *
 *  - ignore non-amazon headers
 *  - lowercase fields
 *  - sort lexicographically
 *  - trim whitespace between ":"
 *  - join with newline
 *
 * @param {Object} headers
 * @return {String}
 * @api private
 */

function canonicalizeHeaders (headers) {
  var buf = []
    , fields = Object.keys(headers)
    ;
  for (var i = 0, len = fields.length; i < len; ++i) {
    var field = fields[i]
      , val = headers[field]
      , field = field.toLowerCase()
      ;
    if (0 !== field.indexOf('x-amz')) continue
    buf.push(field + ':' + val)
  }
  return buf.sort().join('\n')
}
module.exports.canonicalizeHeaders = canonicalizeHeaders

/**
 * Perform the following:
 *
 *  - ignore non sub-resources
 *  - sort lexicographically
 *
 * @param {String} resource
 * @return {String}
 * @api private
 */

function canonicalizeResource (resource) {
  var url = parse(resource, true)
    , path = url.pathname
    , buf = []
    ;

  Object.keys(url.query).forEach(function(key){
    if (!~keys.indexOf(key)) return
    var val = '' == url.query[key] ? '' : '=' + encodeURIComponent(url.query[key])
    buf.push(key + val)
  })

  return path + (buf.length ? '?' + buf.sort().join('&') : '')
}
module.exports.canonicalizeResource = canonicalizeResource


(function( $ ) {

var disabled = TestHelpers.tabs.disabled,
	equalHeight = TestHelpers.tabs.equalHeight,
	state = TestHelpers.tabs.state;

module( "tabs: options" );

test( "{ active: default }", function() {
	expect( 4 );

	var element = $( "#tabs1" ).tabs();
	equal( element.tabs( "option", "active" ), 0, "should be 0 by default" );
	state( element, 1, 0, 0 );
	element.tabs( "destroy" );

	location.hash = "#fragment-3";
	element = $( "#tabs1" ).tabs();
	equal( element.tabs( "option", "active" ), 2, "should be 2 based on URL" );
	state( element, 0, 0, 1 );
	element.tabs( "destroy" );
	location.hash = "#";
});

test( "{ active: false }", function() {
	expect( 7 );

	var element = $( "#tabs1" ).tabs({
		active: false,
		collapsible: true
	});
	state( element, 0, 0, 0 );
	equal( element.find( ".ui-tabs-nav .ui-state-active" ).length, 0, "no tabs selected" );
	strictEqual( element.tabs( "option", "active" ), false );

	element.tabs( "option", "collapsible", false );
	state( element, 1, 0, 0 );
	equal( element.tabs( "option", "active" ), 0 );

	element.tabs( "destroy" );
	element.tabs({
		active: false
	});
	state( element, 1, 0, 0 );
	strictEqual( element.tabs( "option", "active" ), 0 );
});

test( "{ active: Number }", function() {
	expect( 8 );

	var element = $( "#tabs1" ).tabs({
		active: 2
	});
	equal( element.tabs( "option", "active" ), 2 );
	state( element, 0, 0, 1 );

	element.tabs( "option", "active", 0 );
	equal( element.tabs( "option", "active" ), 0 );
	state( element, 1, 0, 0 );

	element.find( ".ui-tabs-nav .ui-tabs-anchor" ).eq( 1 ).click();
	equal( element.tabs( "option", "active" ), 1 );
	state( element, 0, 1, 0 );

	element.tabs( "option", "active", 10 );
	equal( element.tabs( "option", "active" ), 1 );
	state( element, 0, 1, 0 );
});

if ( $.uiBackCompat === false ) {
	test( "{ active: -Number }", function() {
		var element = $( "#tabs1" ).tabs({
			active: -1
		});
		equal( element.tabs( "option", "active" ), 2 );
		state( element, 0, 0, 1 );

		element.tabs( "option", "active", -2 );
		equal( element.tabs( "option", "active" ), 1 );
		state( element, 0, 1, 0 );

		element.tabs( "option", "active", -10 );
		equal( element.tabs( "option", "active" ), 1 );
		state( element, 0, 1, 0 );

		element.tabs( "option", "active", -3 );
		equal( element.tabs( "option", "active" ), 0 );
		state( element, 1, 0, 0 );
	});
}

test( "active - mismatched tab/panel order", function() {
	expect( 3 );

	location.hash = "#tabs7-2";
	var element = $( "#tabs7" ).tabs();
	equal( element.tabs( "option", "active" ), 1, "should be 1 based on URL" );
	state( element, 0, 1 );
	element.tabs( "option", "active", 0 );
	state( element, 1, 0 );
	location.hash = "#";
});

test( "{ collapsible: false }", function() {
	expect( 4 );

	var element = $( "#tabs1" ).tabs({
		active: 1
	});
	element.tabs( "option", "active", false );
	equal( element.tabs( "option", "active" ), 1 );
	state( element, 0, 1, 0 );

	element.find( ".ui-state-active .ui-tabs-anchor" ).eq( 1 ).click();
	equal( element.tabs( "option", "active" ), 1 );
	state( element, 0, 1, 0 );
});

test( "{ collapsible: true }", function() {
	expect( 6 );

	var element = $( "#tabs1" ).tabs({
		active: 1,
		collapsible: true
	});

	element.tabs( "option", "active", false );
	equal( element.tabs( "option", "active" ), false );
	state( element, 0, 0, 0 );

	element.tabs( "option", "active", 1 );
	equal( element.tabs( "option", "active" ), 1 );
	state( element, 0, 1, 0 );

	element.find( ".ui-state-active .ui-tabs-anchor" ).click();
	equal( element.tabs( "option", "active" ), false );
	state( element, 0, 0, 0 );
});

test( "disabled", function() {
	expect( 10 );

	// fully enabled by default
	var element = $( "#tabs1" ).tabs();
	disabled( element, false );

	// disable single tab
	element.tabs( "option", "disabled", [ 1 ] );
	disabled( element, [ 1 ] );

	// disabled active tab
	element.tabs( "option", "disabled", [ 0, 1 ] );
	disabled( element, [ 0, 1 ] );

	// disable all tabs
	element.tabs( "option", "disabled", [ 0, 1, 2 ] );
	disabled( element, true );

	// enable all tabs
	element.tabs( "option", "disabled", [] );
	disabled( element, false );
});

test( "{ event: null }", function() {
	expect( 5 );

	var element = $( "#tabs1" ).tabs({
		event: null
	});
	state( element, 1, 0, 0 );

	element.tabs( "option", "active", 1 );
	equal( element.tabs( "option", "active" ), 1 );
	state( element, 0, 1, 0 );

	// ensure default click handler isn't bound
	element.find( ".ui-tabs-nav .ui-tabs-anchor" ).eq( 2 ).click();
	equal( element.tabs( "option", "active" ), 1 );
	state( element, 0, 1, 0 );
});

test( "{ event: custom }", function() {
	expect( 11 );

	var element = $( "#tabs1" ).tabs({
		event: "custom1 custom2"
	});
	state( element, 1, 0, 0 );

	element.find( ".ui-tabs-nav .ui-tabs-anchor" ).eq( 1 ).trigger( "custom1" );
	equal( element.tabs( "option", "active" ), 1 );
	state( element, 0, 1, 0 );

	// ensure default click handler isn't bound
	element.find( ".ui-tabs-nav .ui-tabs-anchor" ).eq( 2 ).trigger( "click" );
	equal( element.tabs( "option", "active" ), 1 );
	state( element, 0, 1, 0 );

	element.find( ".ui-tabs-nav .ui-tabs-anchor" ).eq( 2 ).trigger( "custom2" );
	equal( element.tabs( "option", "active" ), 2 );
	state( element, 0, 0, 1 );

	element.tabs( "option", "event", "custom3" );

	// ensure old event handlers are unbound
	element.find( ".ui-tabs-nav .ui-tabs-anchor" ).eq( 1 ).trigger( "custom1" );
	equal( element.tabs( "option", "active" ), 2 );
	state( element, 0, 0, 1 );

	element.find( ".ui-tabs-nav .ui-tabs-anchor" ).eq( 1 ).trigger( "custom3" );
	equal( element.tabs( "option", "active" ), 1 );
	state( element, 0, 1, 0 );
});

test( "{ heightStyle: 'auto' }", function() {
	expect( 2 );
	var element = $( "#tabs8" ).tabs({ heightStyle: "auto" });
	equalHeight( element, 45 );
});

test( "{ heightStyle: 'content' }", function() {
	expect( 2 );
	var element = $( "#tabs8" ).tabs({ heightStyle: "content" }),
		sizes = element.find( ".ui-tabs-panel" ).map(function() {
			return $( this ).height();
		}).get();
	equal( sizes[ 0 ], 45 );
	equal( sizes[ 1 ], 15 );
});

test( "{ heightStyle: 'fill' }", function() {
	expect( 2 );
	$( "#tabs8Wrapper" ).height( 500 );
	var element = $( "#tabs8" ).tabs({ heightStyle: "fill" });
	equalHeight( element, 485 );
});

test( "{ heightStyle: 'fill' } with sibling", function() {
	expect( 2 );
	$( "#tabs8Wrapper" ).height( 500 );
	$( "
Lorem Ipsum
" )
		.css({
			height: 50,
			marginTop: 20,
			marginBottom: 30
		})
		.prependTo( "#tabs8Wrapper" );
	var element = $( "#tabs8" ).tabs({ heightStyle: "fill" });
	equalHeight( element, 385 );
});

test( "{ heightStyle: 'fill' } with multiple siblings", function() {
	expect( 2 );
	$( "#tabs8Wrapper" ).height( 500 );
	$( "
Lorem Ipsum
" )
		.css({
			height: 50,
			marginTop: 20,
			marginBottom: 30
		})
		.prependTo( "#tabs8Wrapper" );
	$( "
Lorem Ipsum
" )
		.css({
			height: 50,
			marginTop: 20,
			marginBottom: 30,
			position: "absolute"
		})
		.prependTo( "#tabs8Wrapper" );
	$( "
Lorem Ipsum
" )
		.css({
			height: 25,
			marginTop: 10,
			marginBottom: 15
		})
		.prependTo( "#tabs8Wrapper" );
	var element = $( "#tabs8" ).tabs({ heightStyle: "fill" });
	equalHeight( element, 335 );
});

// TODO: add animation tests

}( jQuery ) );


var mkdirp = require('../');
var path = require('path');
var fs = require('fs');
var test = require('tap').test;

test('rel', function (t) {
    t.plan(2);
    var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
    var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
    var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16);

    var cwd = process.cwd();
    process.chdir('/tmp');

    var file = [x,y,z].join('/');

    mkdirp(file, 0755, function (err) {
        if (err) t.fail(err);
        else path.exists(file, function (ex) {
            if (!ex) t.fail('file not created')
            else fs.stat(file, function (err, stat) {
                if (err) t.fail(err)
                else {
                    process.chdir(cwd);
                    t.equal(stat.mode & 0777, 0755);
                    t.ok(stat.isDirectory(), 'target not a directory');
                    t.end();
                }
            })
        })
    });
});


keep keep keep keep keep replace replace replace keep keep keep keep keep


traverse

traverse
========

Traverse and transform objects by visiting every node on a recursive walk.

examples
========

transform negative numbers in-place
-----------------------------------

negative.js

````javascript
var traverse = require('traverse');
var obj = [ 5, 6, -3, [ 7, 8, -2, 1 ], { f : 10, g : -13 } ];

traverse(obj).forEach(function (x) {
    if (x < 0) this.update(x + 128);
});

console.dir(obj);
````

Output:

    [ 5, 6, 125, [ 7, 8, 126, 1 ], { f: 10, g: 115 } ]

collect leaf nodes
------------------

leaves.js

````javascript
var traverse = require('traverse');

var obj = {
    a : [1,2,3],
    b : 4,
    c : [5,6],
    d : { e : [7,8], f : 9 },
};

var leaves = traverse(obj).reduce(function (acc, x) {
    if (this.isLeaf) acc.push(x);
    return acc;
}, []);

console.dir(leaves);
````

Output:

    [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]

context
=======

Each method that takes a callback has a context (its `this` object) with these
attributes:

this.node
---------

The present node on the recursive walk

this.path
---------

An array of string keys from the root to the present node

this.parent
-----------

The context of the node's parent.
This is `undefined` for the root node.

this.key
--------

The name of the key of the present node in its parent.
This is `undefined` for the root node.

this.isRoot, this.notRoot
-------------------------

Whether the present node is the root node

this.isLeaf, this.notLeaf
-------------------------

Whether or not the present node is a leaf node (has no children)

this.level
----------

Depth of the node within the traversal

this.circular
-------------

If the node equals one of its parents, the `circular` attribute is set to the
context of that parent and the traversal progresses no deeper.

this.update(value)
------------------

Set a new value for the present node.

this.remove()
-------------

Remove the current element from the output. If the node is in an Array it will
be spliced off. Otherwise it will be deleted from its parent.

this.delete()
-------------

Delete the current element from its parent in the output. Calls `delete` even on
Arrays.

this.before(fn)
---------------

Call this function before any of the children are traversed.

this.after(fn)
--------------

Call this function after any of the children are traversed.

this.pre(fn)
------------

Call this function before each of the children are traversed.

this.post(fn)
-------------

Call this function after each of the children are traversed.

methods
=======

.map(fn)
--------

Execute `fn` for each node in the object and return a new object with the
results of the walk. To update nodes in the result use `this.update(value)`.

.forEach(fn)
------------

Execute `fn` for each node in the object but unlike `.map()`, when
`this.update()` is called it updates the object in-place.

.reduce(fn, acc)
----------------

For each node in the object, perform a
[left-fold](http://en.wikipedia.org/wiki/Fold_(higher-order_function))
with the return value of `fn(acc, node)`.

If `acc` isn't specified, `acc` is set to the root object for the first step
and the root element is skipped.

.deepEqual(obj)
---------------

Returns a boolean, whether the instance value is equal to the supplied object
along a deep traversal using some opinionated choices.

Some notes:

* RegExps are equal if their .toString()s match, but not functions since
functions can close over different variables.

* Date instances are compared using `.getTime()` just like `assert.deepEqual()`.

* Circular references must refer to the same paths within the data structure for
both objects. For instance, in this snippet:

````javascript
var a = [1];
a.push(a); // a = [ 1, *a ]

var b = [1];
b.push(a); // b = [ 1, [ 1, *a ] ]
````

`a` is not the same as `b` since even though the expansion is the same, the
circular references in each refer to different paths into the data structure.

However, in:

````javascript
var c = [1];
c.push(c); // c = [ 1, *c ];
````

`c` is equal to `a` in a `deepEqual()` because they have the same terminal node
structure.

* Arguments objects are not arrays and neither are they the same as regular
objects.

* Instances created with `new` of String, Boolean, and Number types are never
equal to the native versions.

.paths()
--------

Return an `Array` of every possible non-cyclic path in the object.
Paths are `Array`s of string keys.

.nodes()
--------

Return an `Array` of every node in the object.

.clone()
--------

Create a deep clone of the object.

installation
============

Using npm:
    npm install traverse

Or check out the repository and link your development copy:
    git clone http://github.com/substack/js-traverse.git
    cd js-traverse
    npm link .

You can test traverse with "expresso":http://github.com/visionmedia/expresso
(`npm install expresso`):
    js-traverse $ expresso

    100% wahoo, your stuff is not broken!

hash transforms
===============

This library formerly had a hash transformation component. It has been
[moved to the hashish package](https://github.com/substack/node-hashish).


This content was generated from LowLevelFileIO-test.js


<!DOCTYPE html>

	<meta charset="utf-8">
	<title>jQuery UI Dialog Demos</title>
	<link rel="stylesheet" href="../demos.css">

Examples

Default functionality

Animated dialog

Modal dialog

Modal message

Modal confirmation

Modal form


it("should pass installation result when update is needed", function () {

keep keep keep add keep keep keep keep keep


node-uuid

Rigorous implementation of RFC4122 (v1 and v4) UUIDs.

# node-uuid

Simple, fast generation of [RFC4122](http://www.ietf.org/rfc/rfc4122.txt) UUIDS.

Features:

* Generate RFC4122 version 1 or version 4 UUIDs
* Runs in node.js and all browsers.
* Cryptographically strong random # generation on supporting platforms
* 1.1K minified and gzip'ed  (Want something smaller?  Check this [crazy shit](https://gist.github.com/982883) out! )
* [Annotated source code](http://broofa.github.com/node-uuid/docs/uuid.html)

## Getting Started

Install it in your browser:

```html
<script src="uuid.js"></script>
```

Or in node.js:

```
npm install node-uuid
```

```javascript
var uuid = require('node-uuid');
```

Then create some ids ...

```javascript
// Generate a v1 (time-based) id
uuid.v1(); // -> '6c84fb90-12c4-11e1-840d-7b25c5ee775a'

// Generate a v4 (random) id
uuid.v4(); // -> '110ec58a-a0f2-4ac4-8393-c866d813b8d1'
```

## API

### uuid.v1([`options` [, `buffer` [, `offset`]]])

Generate and return a RFC4122 v1 (timestamp-based) UUID.

* `options` - (Object) Optional uuid state to apply. Properties may include:

  * `node` - (Array) Node id as Array of 6 bytes (per 4.1.6). Default: Randomly generated ID.  See note 1.
  * `clockseq` - (Number between 0 - 0x3fff) RFC clock sequence.  Default: An internally maintained clockseq is used.
  * `msecs` - (Number | Date) Time in milliseconds since unix Epoch.  Default: The current time is used.
  * `nsecs` - (Number between 0-9999) additional time, in 100-nanosecond units. Ignored if `msecs` is unspecified. Default: internal uuid counter is used, as per 4.2.1.2.

* `buffer` - (Array | Buffer) Array or buffer where UUID bytes are to be written.
* `offset` - (Number) Starting index in `buffer` at which to begin writing.

Returns `buffer`, if specified, otherwise the string form of the UUID

Notes:

1. The randomly generated node id is only guaranteed to stay constant for the lifetime of the current JS runtime. (Future versions of this module may use persistent storage mechanisms to extend this guarantee.)

Example: Generate string UUID with fully-specified options

```javascript
uuid.v1({
  node: [0x01, 0x23, 0x45, 0x67, 0x89, 0xab],
  clockseq: 0x1234,
  msecs: new Date('2011-11-01').getTime(),
  nsecs: 5678
});   // -> "710b962e-041c-11e1-9234-0123456789ab"
```

Example: In-place generation of two binary IDs

```javascript
// Generate two ids in an array
var arr = new Array(32); // -> []
uuid.v1(null, arr, 0);   // -> [02 a2 ce 90 14 32 11 e1 85 58 0b 48 8e 4f c1 15]
uuid.v1(null, arr, 16);  // -> [02 a2 ce 90 14 32 11 e1 85 58 0b 48 8e 4f c1 15 02 a3 1c b0 14 32 11 e1 85 58 0b 48 8e 4f c1 15]

// Optionally use uuid.unparse() to get stringify the ids
uuid.unparse(buffer);    // -> '02a2ce90-1432-11e1-8558-0b488e4fc115'
uuid.unparse(buffer, 16) // -> '02a31cb0-1432-11e1-8558-0b488e4fc115'
```

### uuid.v4([`options` [, `buffer` [, `offset`]]])

Generate and return a RFC4122 v4 UUID.

* `options` - (Object) Optional uuid state to apply. Properties may include:

  * `random` - (Number[16]) Array of 16 numbers (0-255) to use in place of randomly generated values
  * `rng` - (Function) Random # generator to use.  Set to one of the built-in generators - `uuid.mathRNG` (all platforms), `uuid.nodeRNG` (node.js only), `uuid.whatwgRNG` (WebKit only) - or a custom function that returns an array[16] of byte values.

* `buffer` - (Array | Buffer) Array or buffer where UUID bytes are to be written.
* `offset` - (Number) Starting index in `buffer` at which to begin writing.

Returns `buffer`, if specified, otherwise the string form of the UUID

Example: Generate string UUID with fully-specified options

```javascript
uuid.v4({
  random: [
    0x10, 0x91, 0x56, 0xbe, 0xc4, 0xfb, 0xc1, 0xea,
    0x71, 0xb4, 0xef, 0xe1, 0x67, 0x1c, 0x58, 0x36
  ]
});
// -> "109156be-c4fb-41ea-b1b4-efe1671c5836"
```

Example: Generate two IDs in a single buffer

```javascript
var buffer = new Array(32); // (or 'new Buffer' in node.js)
uuid.v4(null, buffer, 0);
uuid.v4(null, buffer, 16);
```

### uuid.parse(id[, buffer[, offset]])
### uuid.unparse(buffer[, offset])

Parse and unparse UUIDs

  * `id` - (String) UUID(-like) string
  * `buffer` - (Array | Buffer) Array or buffer where UUID bytes are to be written. Default: A new Array or Buffer is used
  * `offset` - (Number) Starting index in `buffer` at which to begin writing. Default: 0

Example parsing and unparsing a UUID string

```javascript
var bytes = uuid.parse('797ff043-11eb-11e1-80d6-510998755d10'); // -> <Buffer 79 7f f0 43 11 eb 11 e1 80 d6 51 09 98 75 5d 10>
var string = uuid.unparse(bytes); // -> '797ff043-11eb-11e1-80d6-510998755d10'
```

### uuid.noConflict()

(Browsers only) Set `uuid` property back to it's previous value.

Returns the node-uuid object.

Example:

```javascript
var myUuid = uuid.noConflict();
myUuid.v1(); // -> '6c84fb90-12c4-11e1-840d-7b25c5ee775a'
```

## Deprecated APIs

Support for the following v1.2 APIs is available in v1.3, but is deprecated and will be removed in the next major version.

### uuid([format [, buffer [, offset]]])

uuid() has become uuid.v4(), and the `format` argument is now implicit in the `buffer` argument. (i.e. if you specify a buffer, the format is assumed to be binary).

### uuid.BufferClass

The class of container created when generating binary uuid data if no buffer argument is specified.  This is expected to go away, with no replacement API.

## Testing

In node.js

```
> cd test
> node test.js
```

In Browser

```
open test/test.html
```

### Benchmarking

Requires node.js

```
npm install uuid uuid-js
node benchmark/benchmark.js
```

For a more complete discussion of node-uuid performance, please see the `benchmark/README.md` file, and the [benchmark wiki](https://github.com/broofa/node-uuid/wiki/Benchmark)

For browser performance [checkout the JSPerf tests](http://jsperf.com/node-uuid-performance).

## Release notes

v1.4
* Improved module context detection
* Removed public RNG functions

v1.3.2:
* Improve tests and handling of v1() options (Issue #24)
* Expose RNG option to allow for perf testing with different generators

v1.3:
* Support for version 1 ids, thanks to [@ctavan](https://github.com/ctavan)!
* Support for node.js crypto API
* De-emphasizing performance in favor of a) cryptographic quality PRNGs where available and b) more manageable code


<!doctype html>

	<meta charset="utf-8">
	<title>jQuery UI Menu Test Suite</title>

	<link rel="stylesheet" href="../../../external/qunit.css">
	<link rel="stylesheet" href="../qunit-composite.css">

jQuery UI Menu Test Suite


<!doctype html>

<title>Simple Test</title>
<link rel="stylesheet" href="test.css">

Brackets is awesome! Brackets is awesome! Brackets is awesome! Brackets is awesome! Brackets is awesome! Brackets is awesome! Brackets is awesome! Brackets is awesome! Brackets is awesome! Brackets is awesome! Brackets is awesome! Brackets is awesome! Brackets is awesome! Brackets is awesome! Brackets is awesome! Brackets is awesome! Brackets is awesome! Brackets is awesome! Brackets is awesome! Brackets is awesome!

Brackets is awesome!


keep keep keep replace keep keep keep keep


<!DOCTYPE html>

	<meta charset="utf-8">
	<title>jQuery UI Tabs - Open on mouseover</title>
	<link rel="stylesheet" href="../../themes/base/jquery.ui.all.css">

	<link rel="stylesheet" href="../demos.css">

Nunc tincidunt

Proin dolor

Aenean lacinia

Proin elit arcu, rutrum commodo, vehicula tempus, commodo a, risus. Curabitur nec arcu. Donec sollicitudin mi sit amet mauris. Nam elementum quam ullamcorper ante. Etiam aliquet massa et lorem. Mauris dapibus lacus auctor risus. Aenean tempor ullamcorper leo. Vivamus sed magna quis ligula eleifend adipiscing. Duis orci. Aliquam sodales tortor vitae ipsum. Aliquam nulla. Duis aliquam molestie erat. Ut et mauris vel pede varius sollicitudin. Sed ut dolor nec orci tincidunt interdum. Phasellus ipsum. Nunc tristique tempus lectus.

Morbi tincidunt, dui sit amet facilisis feugiat, odio metus gravida ante, ut pharetra massa metus id nunc. Duis scelerisque molestie turpis. Sed fringilla, massa eget luctus malesuada, metus eros molestie lectus, ut tempus eros massa ut dolor. Aenean aliquet fringilla sem. Suspendisse sed ligula in ligula suscipit aliquam. Praesent in eros vestibulum mi adipiscing adipiscing. Morbi facilisis. Curabitur ornare consequat nunc. Aenean vel metus. Ut posuere viverra nulla. Aliquam erat volutpat. Pellentesque convallis. Maecenas feugiat, tellus pellentesque pretium posuere, felis lorem euismod felis, eu ornare leo nisi vel felis. Mauris consectetur tortor et purus.

Mauris eleifend est et turpis. Duis id erat. Suspendisse potenti. Aliquam vulputate, pede vel vehicula accumsan, mi neque rutrum erat, eu congue orci lorem eget lorem. Vestibulum non ante. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce sodales. Quisque eu urna vel enim commodo pellentesque. Praesent eu risus hendrerit ligula tempus pretium. Curabitur lorem enim, pretium nec, feugiat nec, luctus a, lacus.

Duis cursus. Maecenas ligula eros, blandit nec, pharetra at, semper at, magna. Nullam ac lacus. Nulla facilisi. Praesent viverra justo vitae neque. Praesent blandit adipiscing velit. Suspendisse potenti. Donec mattis, pede vel pharetra blandit, magna ligula faucibus eros, id euismod lacus dolor eget odio. Nam scelerisque. Donec non libero sed nulla mattis commodo. Ut sagittis. Donec nisi lectus, feugiat porttitor, tempor ac, tempor vitae, pede. Aenean vehicula velit eu tellus interdum rutrum. Maecenas commodo. Pellentesque nec elit. Fusce in lacus. Vivamus a libero vitae lectus hendrerit hendrerit.

Toggle sections open/closed on mouseover with the event option. The default value for event is "click."

event: 'mouseover'


[![build status](https://secure.travis-ci.org/jprichardson/node-fs-extra.png)](http://travis-ci.org/jprichardson/node-fs-extra)

Node.js: fs-extra
=================

This module adds a few extra file system methods that aren't included in the native `fs` module. It is a drop in replacement for `fs`.

Why?
----

I got tired of including `mkdirp`, `rimraf`, and `cp -r` in most of my projects.

Installation
------------

    npm install fs-extra

Usage
-----

```javascript
var fs = require('fs-extra');
```

Methods
-------

**NOTE:** You can still use the native Node.js methods. They are copied over to `fs-extra`.

### copy(src, dest, callback)

Copy a file or directory. The directory can have contents. Like `cp -r`. There isn't a synchronous version implemented yet.

Sync: (none)

Examples:

```javascript
var fs = require('fs-extra');

fs.copy('/tmp/myfile', '/tmp/mynewfile', function(err){
  if (err) {
    console.error(err);
  }
  else {
    console.log("success!")
  }
}); //copies file

fs.copy('/tmp/mydir', '/tmp/mynewdir', function(err){
  if (err) {
    console.error(err);
  }
  else {
    console.log("success!")
  }
}); //copies directory, even if it has subdirectories or files
```

### createFile(file, callback)

Creates a file. If the file that is requested to be created is in directories that do not exist, these directories are created. If the file already exists, it is **NOT MODIFIED**.

Sync: `createFileSync()`

Example:

```javascript
var fs = require('fs-extra')
  , file = '/tmp/this/path/does/not/exist/file.txt'

fs.createFile(file, function(err) {
  console.log(err); //null

  //file has now been created, including the directory it is to be placed in
})
```

### exists() / existsSync()

These methods are actually from `path` in v0.6. But in Node v0.8 they are moved from `path` to `fs`. So you can use this module to help make your modules v0.6 and v0.8 compatible.

### mkdirs(dir, callback)

Creates a directory. If the parent hierarchy doesn't exist, it's created. Like `mkdir -p`.

Alias: `mkdirp()`

Sync: `mkdirsSync()` / `mkdirpSync()`

Examples:

```javascript
var fs = require('fs-extra');

fs.mkdirs('/tmp/some/long/path/that/prob/doesnt/exist', function(err){
  if (err) {
    console.error(err);
  }
  else {
    console.log("success!")
  }
});

fs.mkdirsSync('/tmp/another/path');
```

### outputFile(file, data, callback)

Almost the same as `writeFile`, except that if the directory does not exist, it's created.

Sync: `outputFileSync()`

Example:

```javascript
var fs = require('fs-extra')
  , file = '/tmp/this/path/does/not/exist/file.txt'

fs.outputFile(file, 'hello!' function(err) {
  console.log(err); //null

  fs.readFile(file, 'utf8', function(err, data) {
    console.log(data); //hello!
  })
})
```

### readJson(file, callback)

Reads a JSON file and then parses it into an object.

Alias: `readJSON()`

Sync: `readJsonSync()`, `readJSONSync()`

Example:

```javascript
var fs = require('fs-extra');

fs.readJson('./package.json', function(err, packageObj) {
  console.log(packageObj.version); //0.1.3
});
```

### remove(dir, callback)

Removes a file or directory. The directory can have contents. Like `rm -rf`.

Alias: `delete()`

Sync: `removeSync()` / `deleteSync()`

Examples:

```javascript
var fs = require('fs-extra');

fs.remove('/tmp/myfile', function(err){
  if (err) {
    console.error(err);
  }
  else {
    console.log("success!")
  }
});

fs.removeSync('/home/jprichardson'); //I just deleted my entire HOME directory.
```

### writeJson(file, object, callback)

Writes an object to a JSON file.

Alias: `writeJSON()`

Sync: `writeJsonSync()`, `writeJSONSync()`

Example:

```javascript
var fs = require('fs-extra');
fs.writeJson('./package.json', {name: 'fs-extra'}, function(err){
  console.log(err);
});
```

Roadmap
-------

This contains items that I'm considering doing. I'd love community feedback.

* File system walker. I really like this one: https://github.com/daaku/nodejs-walker
* File/directory tree watcher. There are quite a few.
* Method to move files.
* Copy sync.
* Thinking about moving `rimraf`, `ncp`, and `mkdirps` code into this library. I'd like fs-extra to be a stable library that module authors
can depend upon. A bunch of other dependencies kinda sucks for modules/libraries.
* Change documentation to use the `fse` prefix instead of `fs`. This may encourage people to start using `fse` as a prefix and hence make their code clearer that they're not using the native `fs`. I'm very undecided on this one since `fs-extra` is a drop in replacement for the native `fs`.

Naming
------

I put a lot of thought into the naming of these function. Inspired by @coolaj86's request. So he deserves much of the credit for raising the issue. See discussion(s) here:

* https://github.com/jprichardson/node-fs-extra/issues/2
* https://github.com/flatiron/utile/issues/11
* https://github.com/ryanmcgrath/wrench-js/issues/29
* https://github.com/substack/node-mkdirp/issues/17

First, I believe that in as many cases as possible, the [Node.js naming schemes](http://nodejs.org/api/fs.html) should be chosen. However, there are problems with the Node.js own naming schemes.

For example, `fs.readFile()` and `fs.readdir()`: the **F** is capitalized in *File* and the **d** is not capitalized in *dir*. Perhaps a bit pedantic, but they should still be consistent. Also, Node.js has chosen a lot of POSIX naming schemes, which I believe is great. See: `fs.mkdir()`, `fs.rmdir()`, `fs.chown()`, etc.

We have a dilemma though. How do you consistently name methods that perform the following POSIX commands: `cp`, `cp -r`, `mkdir -p`, and `rm -rf`?

My perspective: when in doubt, err on the side of simplicity. Consider that for a moment. A directory is just a hierarchical grouping of directories and files. So when you want to copy it or remove it, in most cases you'll want to copy or remove all of its contents. When you want to create a directory, if the directory that it's suppose to be contained in does not exist, then in most cases you'll want to create that too.

So, if you want to remove a file or a directory regardless of whether it has contents, just call `fs.remove(path)` or its alias `fs.delete(path)`. If you want to copy a file or a directory whether it has contents, just call `fs.copy(source, destination)`. If you want to create a directory regardless of whether its parent directories exist, just call `fs.mkdirs(path)` or `fs.mkdirp(path)`.

Author
------

`node-fs-extra` was written by [JP Richardson][aboutjp]. You should follow him on Twitter [@jprichardson][twitter]. Also read his coding blog [Procbits][procbits]. If you write software with others, you should checkout [Gitpilot][gitpilot] to make collaboration with Git simple.

License
-------

Licensed under MIT

Copyright (c) 2011-2013 JP Richardson

[1]: http://nodejs.org/docs/latest/api/fs.html

[jsonfile]: https://github.com/jprichardson/node-jsonfile

[aboutjp]: http://about.me/jprichardson
[twitter]: http://twitter.com/jprichardson
[procbits]: http://procbits.com
[gitpilot]: http://gitpilot.com


var common = require('../common');
var assert = common.assert;
var CombinedStream = common.CombinedStream;
var util = require('util');
var Stream = require('stream').Stream;

var s = CombinedStream.create();

function StringStream(){
  this.writable=true;
  this.str=""
}
util.inherits(StringStream,Stream);

StringStream.prototype.write=function(chunk,encoding){
  this.str+=chunk.toString();
  this.emit('data',chunk);
}

StringStream.prototype.end=function(chunk,encoding){
  this.emit('end');
}

StringStream.prototype.toString=function(){
  return this.str;
}

s.append("foo.");
s.append("");
s.append("bar");

var ss = new StringStream();

s.pipe(ss);
s.resume();

assert.equal(ss.toString(),"foo.bar");


// firstly, check that input is a string or not.

return new TypeError('Argument is not a string.')

throw new TypeError('Argument is not a string.')

import { CheckPascalCase } from '../CheckPascalCase'

test('CheckPascalCase(TheAlgorithms) -> true', () => {
  const word = 'TheAlgorithms'
  const res = CheckPascalCase(word)
  expect(res).toBeTruthy()
})

test('CheckPascalCase(theAlgorithms) -> false', () => {
  const word = 'theAlgorithms'
  const res = CheckPascalCase(word)
  expect(res).toBeFalsy()
})

test('CheckPascalCase(The Algorithms) -> false', () => {
  const word = 'The Algorithms'
  const res = CheckPascalCase(word)
  expect(res).toBeFalsy()
})


function decimalToOctal(num) {
  let oct = 0
  let c = 0
  while (num > 0) {
    const r = num % 8
    oct = oct + r * Math.pow(10, c++)
    num = Math.floor(num / 8) // basically /= 8 without remainder if any
  }
  return oct
}

export { decimalToOctal }

// > decimalToOctal(2)
// 2

// > decimalToOctal(8)
// 10

// > decimalToOctal(65)
// 101

// > decimalToOctal(216)
// 330

// > decimalToOctal(512)
// 1000


/*
  Returns the sum of a geometric progression
  Article on Geometric Progression: https://en.wikipedia.org/wiki/Geometric_series
  Examples:
  > sumOfGeometricProgression(2, 0.5, 6)
  3.9375
  > sumOfGeometricProgression(0.5, 10, 3)
  55.5
  > sumOfGeometricProgression(0.5, 10, Infinity)
  Error: The geometric progression is diverging, and its sum cannot be calculated
*/

/**
 *
 * @param {Number} firstTerm The first term of the geometric progression
 * @param {Number} commonRatio The common ratio of the geometric progression
 * @param {Number} numOfTerms The number of terms in the progression
 */
function sumOfGeometricProgression(firstTerm, commonRatio, numOfTerms) {
  if (!Number.isFinite(numOfTerms)) {
    /*
      If the number of Terms is Infinity, the common ratio needs to be less than 1 to be a convergent geometric progression
      Article on Convergent Series: https://en.wikipedia.org/wiki/Convergent_series
    */
    if (Math.abs(commonRatio) < 1) return firstTerm / (1 - commonRatio)
    throw new Error(
      'The geometric progression is diverging, and its sum cannot be calculated'
    )
  }

  if (commonRatio === 1) return firstTerm * numOfTerms

  return (
    (firstTerm * (Math.pow(commonRatio, numOfTerms) - 1)) / (commonRatio - 1)
  )
}

export { sumOfGeometricProgression }


* @returns `Boolean` return true if the string is in kebab-case, else return false.

return pat.test(varName) && !varName.includes('_')

keep keep keep keep keep replace keep keep keep keep

import { CheckKebabCase } from '../CheckKebabCase'

test('CheckKebabCase(The-Algorithms) -> true', () => {
  const word = 'The-Algorithms'
  const res = CheckKebabCase(word)
  expect(res).toBeTruthy()
})

test('CheckKebabCase(The Algorithms) -> false', () => {
  const word = 'The Algorithms'
  const res = CheckKebabCase(word)
  expect(res).toBeFalsy()
})


/*
 * Wiggle sort sorts the array into a wave like array.
 * An array ‘arr[0..n-1]’ is sorted in wave form if arr[0] <= arr[1] >= arr[2] <= arr[3] >= arr[4] <= …..
 * KEEP IN MIND: there are also more strict definitions of wiggle sort which use
 * the rule arr[0] < arr[1] > arr[2] < arr[3] > arr[4] < … but this function
 * allows for equality of values next to each other.
 */
import { quickSelectSearch } from '../Search/QuickSelectSearch.js'

export const simplifiedWiggleSort = function (arr) {
  // find Median using QuickSelect
  let median = quickSelectSearch(arr, Math.floor(arr.length / 2.0))
  median = median[Math.floor(arr.length / 2.0)]

  const sorted = new Array(arr.length)

  let smallerThanMedianIndx = 0
  let greaterThanMedianIndx = arr.length - 1 - (arr.length % 2)

  for (let i = 0; i < arr.length; i++) {
    if (arr[i] > median) {
      sorted[greaterThanMedianIndx] = arr[i]
      greaterThanMedianIndx -= 2
    } else {
      if (smallerThanMedianIndx < arr.length) {
        sorted[smallerThanMedianIndx] = arr[i]
        smallerThanMedianIndx += 2
      } else {
        sorted[greaterThanMedianIndx] = arr[i]
        greaterThanMedianIndx -= 2
      }
    }
  }

  return sorted
}


import {
  PalindromeRecursive,
  PalindromeIterative,
  checkPalindrome
} from '../Palindrome'

describe('Palindrome', () => {
  it('should return true for a palindrome for PalindromeRecursive', () => {
    expect(PalindromeRecursive('mom')).toBeTruthy()
  })
  it('should return true  for a palindrome for PalindromeIterative', () => {
    expect(PalindromeIterative('mom')).toBeTruthy()
  })
  it('should return false for a non-palindrome for PalindromeRecursive', () => {
    expect(PalindromeRecursive('Algorithms')).toBeFalsy()
  })
  it('should return true  for a non-palindrome for PalindromeIterative', () => {
    expect(PalindromeIterative('JavaScript')).toBeFalsy()
  })

  it.each([
    ['radar', true],
    ['hello', false],
    ['r', true],
    ['   racecar   ', true]
  ])('should return value is palindrome or not', (value, expected) => {
    expect(checkPalindrome(value)).toBe(expected)
  })
})


* @returns `Boolean` return true if the string is in PascalCase, else return false.

keep keep keep keep keep replace keep keep keep

import { checkFlatCase } from '../CheckFlatCase'

describe('checkFlatCase function', () => {
  it('should return false when the input string is not in flatcase', () => {
    const actual = checkFlatCase('this is not in flatcase')
    expect(actual).toBe(false)
  })

  it('should return true when the input string is a single letter character', () => {
    const actual = checkFlatCase('a')
    expect(actual).toBe(true)
  })

  it('should return true when the input string is a string of lowercase letter characters with no spaces', () => {
    const actual = checkFlatCase('abcdefghijklmnopqrstuvwxyz')
    expect(actual).toBe(true)
  })
})


function euclideanGCDRecursive(first, second) {
  /*
    Calculates GCD of two numbers using Euclidean Recursive Algorithm
    :param first: First number
    :param second: Second number
    :return: GCD of the numbers
    */
  if (second === 0) {
    return first
  } else {
    return euclideanGCDRecursive(second, first % second)
  }
}

function euclideanGCDIterative(first, second) {
  /*
    Calculates GCD of two numbers using Euclidean Iterative Algorithm
    :param first: First number
    :param second: Second number
    :return: GCD of the numbers
    */
  while (second !== 0) {
    const temp = second
    second = first % second
    first = temp
  }
  return first
}

export { euclideanGCDIterative, euclideanGCDRecursive }


import { EulersTotient } from '../EulersTotient'

describe('EulersTotient', () => {
  it('should return 6 as 1, 2, 4, 5, 7, and 8 are coprime to 9', () => {
    expect(EulersTotient(9)).toBe(6)
  })

  it('should return 4 as 1, 3, 7, and 9 are coprime to 10', () => {
    expect(EulersTotient(10)).toBe(4)
  })
})


import { fibonacci } from '../FibonacciNumberRecursive'

describe('FibonacciNumberRecursive', () => {
  it('should return 0', () => {
    expect(fibonacci(0)).toBe(0)
  })

  it('should return 1', () => {
    expect(fibonacci(1)).toBe(1)
  })

  it('should return 5', () => {
    expect(fibonacci(5)).toBe(5)
  })

  it('should return 9', () => {
    expect(fibonacci(9)).toBe(34)
  })
})


it('should throw when input is not a string', () => {

// checkFlatCase method checks if the given string is in flatcase or not. Flatcase is a convention
// where all letters are in lowercase, and there are no spaces between words.
// thisvariable is an example of flatcase. In camelCase it would be thisVariable, snake_case this_variable and so on.

// Problem Source & Explanation: https://en.wikipedia.org/wiki/Naming_convention_(programming)

/**
 * checkFlatCase method returns true if the string in flatcase, else return the false.
 * @param {string} varname the name of the variable to check.
 * @returns {boolean} return true if the string is in flatcase, else return false.
 */
const checkFlatCase = (varname) => {
  // firstly, check that input is a string or not.
  if (typeof varname !== 'string') {
    return new TypeError('Argument is not a string.')
  }

  const pat = /^[a-z]*$/
  return pat.test(varname)
}

export { checkFlatCase }


/**
 * @function isPalindromeIntegerNumber
 * @param { Number } x
 * @returns {boolean} - input integer is palindrome or not
 *
 * time complexity : O(log_10(N))
 * space complexity : O(1)
 */
export function isPalindromeIntegerNumber(x) {
  if (typeof x !== 'number') {
    throw new TypeError('Input must be a integer number')
  }
  // check x is integer
  if (!Number.isInteger(x)) {
    return false
  }

  // if it has '-' it cannot be palindrome
  if (x < 0) return false

  // make x reverse
  let reversed = 0
  let num = x

  while (num > 0) {
    const lastDigit = num % 10
    reversed = reversed * 10 + lastDigit
    num = Math.floor(num / 10)
  }

  // compare origin x and reversed are same
  return x === reversed
}


/*
The density of a network is a measure of how many edges exist proportional to
how many edges would exist in a complete network (where all possible edges).
https://networkx.org/documentation/networkx-1.9/reference/generated/networkx.classes.function.density.html
*/
function density(numberOfNodes, numberOfEdges, isDirected = false) {
  const multi = isDirected ? 1 : 2
  return (multi * numberOfEdges) / (numberOfNodes * (numberOfNodes - 1))
}

export { density }


it('should return true when the input string is a string of lowercase letter characters with no spaces', () => {

const actual = checkFlatCase('abcdefghijklmnopqrstuvwxyz')


import * as volume from '../Volume'

test('Testing on volCuboid', () => {
  const volCuboid = volume.volCuboid(2.0, 5.0, 3)
  expect(volCuboid).toBe(30.0)
})

test('Testing on volCube', () => {
  const volCube = volume.volCube(2.0)
  expect(volCube).toBe(8.0)
})

test('Testing on volCone', () => {
  const volCone = volume.volCone(3.0, 8.0)
  expect(volCone).toBe(75.39822368615503)
})

test('Testing on volPyramid', () => {
  const volPyramid = volume.volPyramid(2.0, 3.0, 8.0)
  expect(volPyramid).toBe(16.0)
})

test('Testing on volCylinder', () => {
  const volCylinder = volume.volCylinder(3.0, 8.0)
  expect(volCylinder).toBe(226.1946710584651)
})

test('Testing on volTriangularPrism', () => {
  const volTriangularPrism = volume.volTriangularPrism(3.0, 6.0, 8.0)
  expect(volTriangularPrism).toBe(72.0)
})

test('Testing on volPentagonalPrism', () => {
  const volPentagonalPrism = volume.volPentagonalPrism(1.0, 4.0, 8.0)
  expect(volPentagonalPrism).toBe(80.0)
})

test('Testing on volSphere', () => {
  const volSphere = volume.volSphere(4.0)
  expect(volSphere).toBe(268.082573106329)
})

test('Testing on volHemisphere', () => {
  const volHemisphere = volume.volHemisphere(4.0)
  expect(volHemisphere).toBe(134.0412865531645)
})


const res = CheckKebabCase(word)
expect(res).toBeFalsy()
})

test('CheckKebabCase throws when input is not a string', () => {


/**
 * @function BinaryConvert
 * @description Convert the decimal to binary.
 * @param {Integer} num - The input integer
 * @return {Integer} - Binary of num.
 * @see [BinaryConvert](https://www.programiz.com/javascript/examples/decimal-binary)
 * @example BinaryConvert(12) = 1100
 * @example BinaryConvert(12 + 2) = 1110
 */

const BinaryConvert = (num) => {
  let power = 1
  let binary = 0

  while (num) {
    const rem = num % 2
    num = Math.floor(num / 2)
    binary = rem * power + binary
    power *= 10
  }

  return binary
}

export { BinaryConvert }


name: Other issue
description: Use this for any other issues. Do NOT create blank issues
title: "[OTHER]: "
labels: ["awaiting triage"]
body:
  - type: textarea
    id: description
    attributes:
      label: What would you like to share?
      description: Provide a clear and concise explanation of your issue.
    validations:
      required: true
  - type: textarea
    id: extrainfo
    attributes:
      label: Additional information
      description: Is there anything else we should know about this issue?
    validations:
      required: false


test('CheckPascalCase(The Algorithms) -> false', () => {

test('CheckPascalCase throws when input is not a string', () => {


import { findBinomialCoefficient } from '../BinomialCoefficient.js'

describe('Testing findBinomialCoefficient function', () => {
  it('should return 56', () => {
    const binomialCoefficient = findBinomialCoefficient(8, 3)
    expect(binomialCoefficient).toBe(56)
  })

  it('should return 10', () => {
    const binomialCoefficient = findBinomialCoefficient(5, 2)
    expect(binomialCoefficient).toBe(10)
  })

  it('should throw error when supplied arguments other than number', () => {
    expect(() => {
      findBinomialCoefficient('eight', 'three')
    }).toThrow(Error)
  })

  it('should throw error when n is less than zero', () => {
    expect(() => {
      findBinomialCoefficient(-1, 3)
    }).toThrow(Error)
  })

  it('should throw error when k is less than zero', () => {
    expect(() => {
      findBinomialCoefficient(1, -3)
    }).toThrow(Error)
  })

  it('should throw error when n and k are less than zero', () => {
    expect(() => {
      findBinomialCoefficient(-1, -3)
    }).toThrow(Error)
  })
})


import { palindrome } from './Palindrome'

/*
 * Given a string s, return all possible palindrome partitionings of s.
 * A palindrome partitioning partitions a string into palindromic substrings.
 * @see https://www.cs.columbia.edu/~sedwards/classes/2021/4995-fall/proposals/Palindrome.pdf
 */
const partitionPalindrome = (s) => {
  const result = []
  backtrack(s, [], result)
  return result
}

const backtrack = (s, path, result) => {
  if (s.length === 0) {
    result.push([...path])
    return
  }

  for (let i = 0; i < s.length; i++) {
    const prefix = s.substring(0, i + 1)
    if (palindrome(prefix)) {
      path.push(prefix)
      backtrack(s.substring(i + 1), path, result)
      path.pop()
    }
  }
}

export default partitionPalindrome


import maxCharacter from '../MaxCharacter'

describe('Testing the maxCharacter function', () => {
  it('Expect throw with wrong arg', () => {
    expect(() => maxCharacter(123)).toThrow()
    expect(() => maxCharacter('')).toThrow()
  })

  it('Check the max character in string', () => {
    const theString = "I can't do that"
    const maxCharInAllCount = maxCharacter(theString)
    const maxChar = maxCharacter(theString, /\s/)

    expect(maxCharInAllCount).toBe(' ')
    expect(maxChar).toBe('t')

    expect(maxCharacter('!!!Hello, World!!!', /[a-z]/)).toBe('!')

    expect(maxCharacter('!!!Hello, World!!!', /[^a-z]/i)).toBe('l')
  })
})