_                   = require("thirdparty/lodash");

keep keep keep keep keep replace replace replace keep keep 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, forin: true, maxerr: 50, regexp: true */
/*global define, $, brackets */

/**
 * HTMLDocument manages a single HTML source document
 *
 * # EDITING
 *
 * Editing the document will cause the corresponding node to be updated
 * by calling `applyChanges` on the DOMAgent. This will only work for
 * altering text nodes and will break when attempting to change DOM elements
 * or inserting or deleting nodes.
 *
 * # HIGHLIGHTING
 *
 * HTMLDocument supports highlighting nodes from the HighlightAgent and
 * highlighting the DOMNode corresponding to the cursor position in the
 * editor.
 */
define(function HTMLDocumentModule(require, exports, module) {
    "use strict";

    var DocumentManager     = require("document/DocumentManager"),
        DOMAgent            = require("LiveDevelopment/Agents/DOMAgent"),
        HighlightAgent      = require("LiveDevelopment/Agents/HighlightAgent"),
        HTMLInstrumentation = require("language/HTMLInstrumentation"),
        Inspector           = require("LiveDevelopment/Inspector/Inspector"),
        LiveDevelopment     = require("LiveDevelopment/LiveDevelopment"),
        PerfUtils           = require("utils/PerfUtils"),
        RemoteAgent         = require("LiveDevelopment/Agents/RemoteAgent"),
        StringUtils         = require("utils/StringUtils"),
        _                   = require("thirdparty/lodash");

    /**
     * Constructor
     * @param {!DocumentManager.Document} doc the source document from Brackets
     * @param {editor=} editor
     */
    var HTMLDocument = function HTMLDocument(doc, editor) {
        var self = this;

        this.doc = doc;
        if (!editor) {
            return;
        }
        this.editor = editor;
        this._instrumentationEnabled = false;

        // Performance optimization to use closures instead of Function.bind()
        // to improve responsiveness during cursor movement and keyboard events
        $(this.editor).on("cursorActivity.HTMLDocument", function (event, editor) {
            self._onCursorActivity(event, editor);
        });

        $(this.editor).on("change.HTMLDocument", function (event, editor, change) {
            self._onChange(event, editor, change);
        });

        // Experimental code
        if (LiveDevelopment.config.experimental) {
            $(HighlightAgent).on("highlight.HTMLDocument", function (event, node) {
                self._onHighlight(event, node);
            });
        }
    };

    /**
     * Enable instrumented HTML
     * @param enabled {boolean}
     */
    HTMLDocument.prototype.setInstrumentationEnabled = function setInstrumentationEnabled(enabled) {
        if (enabled && !this._instrumentationEnabled) {
            HTMLInstrumentation.scanDocument(this.doc);
            HTMLInstrumentation._markText(this.editor);
        }

        this._instrumentationEnabled = enabled;
    };

    /**
     * Returns true if document edits appear live in the connected browser
     * @return {boolean}
     */
    HTMLDocument.prototype.isLiveEditingEnabled = function () {
        return this._instrumentationEnabled;
    };

    /**
     * Returns a JSON object with HTTP response overrides
     * @return {{body: string}}
     */
    HTMLDocument.prototype.getResponseData = function getResponseData(enabled) {
        var body;
        if (this._instrumentationEnabled) {
            body = HTMLInstrumentation.generateInstrumentedHTML(this.editor);
        }

        return {
            body: body || this.doc.getText()
        };
    };

    /** Close the document */
    HTMLDocument.prototype.close = function close() {
        if (!this.editor) {
            return;
        }

        $(this.editor).off(".HTMLDocument");

        // Experimental code
        if (LiveDevelopment.config.experimental) {
            // Force highlight teardown
            this._onHighlight();
        }
    };

    /** Update the highlight */
    HTMLDocument.prototype.updateHighlight = function () {
        var editor = this.editor,
            codeMirror = editor._codeMirror,
            ids = [];
        if (Inspector.config.highlight) {
            _.each(this.editor.getSelections(), function (sel) {
                var tagID = HTMLInstrumentation._getTagIDAtDocumentPos(
                    editor,
                    sel.reversed ? sel.end : sel.start
                );
                if (tagID !== -1) {
                    ids.push(tagID);
                }
            });

            if (!ids.length) {
                HighlightAgent.hide();
            } else {
                HighlightAgent.domElement(ids);
            }
        }
    };

    /** Event Handlers *******************************************************/

    /** Triggered on cursor activity by the editor */
    HTMLDocument.prototype._onCursorActivity = function (event, editor) {
        if (!this.editor) {
            return;
        }
        this.updateHighlight();
    };

    /**
     * @private
     * For the given editor change, compare the resulting browser DOM with the
     * in-editor DOM. If there are any diffs, a warning is logged to the
     * console along with each diff.
     * @param {Object} change CodeMirror editor change data
     */
    HTMLDocument.prototype._compareWithBrowser = function (change) {
        var self = this;

        RemoteAgent.call("getSimpleDOM").done(function (res) {
            var browserSimpleDOM = JSON.parse(res.result.value),
                edits,
                node,
                result;

            try {
                result = HTMLInstrumentation._getBrowserDiff(self.editor, browserSimpleDOM);
            } catch (err) {
                console.error("Error comparing in-browser DOM to in-editor DOM");
                console.error(err.stack);
                return;
            }

            edits = result.diff.filter(function (delta) {
                // ignore textDelete in html root element
                node = result.browser.nodeMap[delta.parentID];

                if (node && node.tag === "html" && delta.type === "textDelete") {
                    return false;
                }

                return true;
            });

            if (edits.length > 0) {
                console.warn("Browser DOM does not match after change: " + JSON.stringify(change));

                edits.forEach(function (delta) {
                    console.log(delta);
                });
            }
        });
    };

    /** Triggered on change by the editor */
    HTMLDocument.prototype._onChange = function (event, editor, change) {
        // Make sure LiveHTML is turned on
        if (!this._instrumentationEnabled) {
            return;
        }

        // Apply DOM edits is async, so previous PerfUtils timer may still be
        // running. PerfUtils does not support running multiple timers with same
        // name, so do not start another timer in this case.
        var perfTimerName   = "HTMLDocument applyDOMEdits",
            isNestedTimer   = PerfUtils.isActive(perfTimerName);
        if (!isNestedTimer) {
            PerfUtils.markStart(perfTimerName);
        }

        // Only handles attribute changes currently.
        // TODO: text changes should be easy to add
        // TODO: if new tags are added, need to instrument them
        var self                = this,
            result              = HTMLInstrumentation.getUnappliedEditList(editor, change),
            applyEditsPromise;

        if (result.edits) {
            applyEditsPromise = RemoteAgent.call("applyDOMEdits", result.edits);

            applyEditsPromise.always(function () {
                if (!isNestedTimer) {
                    PerfUtils.addMeasurement(perfTimerName);
                }
            });
        }

        this.errors = result.errors || [];
        $(this).triggerHandler("statusChanged", [this]);

        // Debug-only: compare in-memory vs. in-browser DOM
        // edit this file or set a conditional breakpoint at the top of this function:
        //     "this._debug = true, false"
        if (this._debug) {
            console.log("Edits applied to browser were:");
            console.log(JSON.stringify(result.edits, null, 2));
            applyEditsPromise.done(function () {
                self._compareWithBrowser(change);
            });
        }

//        var marker = HTMLInstrumentation._getMarkerAtDocumentPos(
//            this.editor,
//            editor.getCursorPos()
//        );
//
//        if (marker && marker.tagID) {
//            var range   = marker.find(),
//                text    = marker.doc.getRange(range.from, range.to);
//
//            // HACK maintain ID
//            text = text.replace(">", " data-brackets-id='" + marker.tagID + "'>");
//
//            // FIXME incorrectly replaces body elements with content only, missing body element
//            RemoteAgent.remoteElement(marker.tagID).replaceWith(text);
//        }

        // if (!this.editor) {
        //     return;
        // }
        // var codeMirror = this.editor._codeMirror;
        // while (change) {
        //     var from = codeMirror.indexFromPos(change.from);
        //     var to = codeMirror.indexFromPos(change.to);
        //     var text = change.text.join("\n");
        //     DOMAgent.applyChange(from, to, text);
        //     change = change.next;
        // }
    };

    /** Triggered by the HighlightAgent to highlight a node in the editor */
    HTMLDocument.prototype._onHighlight = function (event, node) {
        if (!node || !node.location || !this.editor) {
            if (this._highlight) {
                this._highlight.clear();
                delete this._highlight;
            }
            return;
        }
        var codeMirror = this.editor._codeMirror;
        var to, from = codeMirror.posFromIndex(node.location);
        if (node.closeLocation) {
            to = node.closeLocation + node.closeLength;
        } else {
            to = node.location + node.length;
        }
        to = codeMirror.posFromIndex(to);
        if (this._highlight) {
            this._highlight.clear();
        }
        this._highlight = codeMirror.markText(from, to, { className: "highlight" });
    };

    // Export the class
    module.exports = HTMLDocument;
});


* @param {!Document} doc The source document from Brackets

* @param {!Editor} editor The editor for this document

var buf = new Buffer([ 97, 98, 99, 100, 101, 102, 0 ]);

var binary = require('binary');
var vars = binary.parse(buf)
    .word16ls('ab')
    .word32bu('cf')
    .word8('x')
    .vars
;
console.dir(vars);


// Copyright Joyent, Inc. and other Node contributors.
//
// 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.

module.exports = Readable;
Readable.ReadableState = ReadableState;

var EE = require('events').EventEmitter;
if (!EE.listenerCount) EE.listenerCount = function(emitter, type) {
  return emitter.listeners(type).length;
};

if (!global.setImmediate) global.setImmediate = function setImmediate(fn) {
  return setTimeout(fn, 0);
};
if (!global.clearImmediate) global.clearImmediate = function clearImmediate(i) {
  return clearTimeout(i);
};

var Stream = require('stream');
var util = require('util');
if (!util.isUndefined) {
  var utilIs = require('core-util-is');
  for (var f in utilIs) {
    util[f] = utilIs[f];
  }
}
var StringDecoder;
var debug;
if (util.debuglog)
  debug = util.debuglog('stream');
else try {
  debug = require('debuglog')('stream');
} catch (er) {
  debug = function() {};
}

util.inherits(Readable, Stream);

function ReadableState(options, stream) {
  options = options || {};

  // the point at which it stops calling _read() to fill the buffer
  // Note: 0 is a valid value, means "don't call _read preemptively ever"
  var hwm = options.highWaterMark;
  this.highWaterMark = (hwm || hwm === 0) ? hwm : 16 * 1024;

  // cast to ints.
  this.highWaterMark = ~~this.highWaterMark;

  this.buffer = [];
  this.length = 0;
  this.pipes = null;
  this.pipesCount = 0;
  this.flowing = null;
  this.ended = false;
  this.endEmitted = false;
  this.reading = false;

  // a flag to be able to tell if the onwrite cb is called immediately,
  // or on a later tick.  We set this to true at first, because any
  // actions that shouldn't happen until "later" should generally also
  // not happen before the first write call.
  this.sync = true;

  // whenever we return null, then we set a flag to say
  // that we're awaiting a 'readable' event emission.
  this.needReadable = false;
  this.emittedReadable = false;
  this.readableListening = false;

  // object stream flag. Used to make read(n) ignore n and to
  // make all the buffer merging and length checks go away
  this.objectMode = !!options.objectMode;

  // Crypto is kind of old and crusty.  Historically, its default string
  // encoding is 'binary' so we have to make this configurable.
  // Everything else in the universe uses 'utf8', though.
  this.defaultEncoding = options.defaultEncoding || 'utf8';

  // when piping, we only care about 'readable' events that happen
  // after read()ing all the bytes and not getting any pushback.
  this.ranOut = false;

  // the number of writers that are awaiting a drain event in .pipe()s
  this.awaitDrain = 0;

  // if true, a maybeReadMore has been scheduled
  this.readingMore = false;

  this.decoder = null;
  this.encoding = null;
  if (options.encoding) {
    if (!StringDecoder)
      StringDecoder = require('string_decoder').StringDecoder;
    this.decoder = new StringDecoder(options.encoding);
    this.encoding = options.encoding;
  }
}

function Readable(options) {
  if (!(this instanceof Readable))
    return new Readable(options);

  this._readableState = new ReadableState(options, this);

  // legacy
  this.readable = true;

  Stream.call(this);
}

// Manually shove something into the read() buffer.
// This returns true if the highWaterMark has not been hit yet,
// similar to how Writable.write() returns true if you should
// write() some more.
Readable.prototype.push = function(chunk, encoding) {
  var state = this._readableState;

  if (util.isString(chunk) && !state.objectMode) {
    encoding = encoding || state.defaultEncoding;
    if (encoding !== state.encoding) {
      chunk = new Buffer(chunk, encoding);
      encoding = '';
    }
  }

  return readableAddChunk(this, state, chunk, encoding, false);
};

// Unshift should *always* be something directly out of read()
Readable.prototype.unshift = function(chunk) {
  var state = this._readableState;
  return readableAddChunk(this, state, chunk, '', true);
};

function readableAddChunk(stream, state, chunk, encoding, addToFront) {
  var er = chunkInvalid(state, chunk);
  if (er) {
    stream.emit('error', er);
  } else if (util.isNullOrUndefined(chunk)) {
    state.reading = false;
    if (!state.ended)
      onEofChunk(stream, state);
  } else if (state.objectMode || chunk && chunk.length > 0) {
    if (state.ended && !addToFront) {
      var e = new Error('stream.push() after EOF');
      stream.emit('error', e);
    } else if (state.endEmitted && addToFront) {
      var e = new Error('stream.unshift() after end event');
      stream.emit('error', e);
    } else {
      if (state.decoder && !addToFront && !encoding)
        chunk = state.decoder.write(chunk);

      if (!addToFront)
        state.reading = false;

      // if we want the data now, just emit it.
      if (state.flowing && state.length === 0 && !state.sync) {
        stream.emit('data', chunk);
        stream.read(0);
      } else {
        // update the buffer info.
        state.length += state.objectMode ? 1 : chunk.length;
        if (addToFront)
          state.buffer.unshift(chunk);
        else
          state.buffer.push(chunk);

        if (state.needReadable)
          emitReadable(stream);
      }

      maybeReadMore(stream, state);
    }
  } else if (!addToFront) {
    state.reading = false;
  }

  return needMoreData(state);
}

// if it's past the high water mark, we can push in some more.
// Also, if we have no data yet, we can stand some
// more bytes.  This is to work around cases where hwm=0,
// such as the repl.  Also, if the push() triggered a
// readable event, and the user called read(largeNumber) such that
// needReadable was set, then we ought to push more, so that another
// 'readable' event will be triggered.
function needMoreData(state) {
  return !state.ended &&
         (state.needReadable ||
          state.length < state.highWaterMark ||
          state.length === 0);
}

// backwards compatibility.
Readable.prototype.setEncoding = function(enc) {
  if (!StringDecoder)
    StringDecoder = require('string_decoder').StringDecoder;
  this._readableState.decoder = new StringDecoder(enc);
  this._readableState.encoding = enc;
};

// Don't raise the hwm > 128MB
var MAX_HWM = 0x800000;
function roundUpToNextPowerOf2(n) {
  if (n >= MAX_HWM) {
    n = MAX_HWM;
  } else {
    // Get the next highest power of 2
    n--;
    for (var p = 1; p < 32; p <<= 1) n |= n >> p;
    n++;
  }
  return n;
}

function howMuchToRead(n, state) {
  if (state.length === 0 && state.ended)
    return 0;

  if (state.objectMode)
    return n === 0 ? 0 : 1;

  if (isNaN(n) || util.isNull(n)) {
    // only flow one buffer at a time
    if (state.flowing && state.buffer.length)
      return state.buffer[0].length;
    else
      return state.length;
  }

  if (n <= 0)
    return 0;

  // If we're asking for more than the target buffer level,
  // then raise the water mark.  Bump up to the next highest
  // power of 2, to prevent increasing it excessively in tiny
  // amounts.
  if (n > state.highWaterMark)
    state.highWaterMark = roundUpToNextPowerOf2(n);

  // don't have that much.  return null, unless we've ended.
  if (n > state.length) {
    if (!state.ended) {
      state.needReadable = true;
      return 0;
    } else
      return state.length;
  }

  return n;
}

// you can override either this method, or the async _read(n) below.
Readable.prototype.read = function(n) {
  debug('read', n);
  var state = this._readableState;
  var nOrig = n;

  if (!util.isNumber(n) || n > 0)
    state.emittedReadable = false;

  // if we're doing read(0) to trigger a readable event, but we
  // already have a bunch of data in the buffer, then just trigger
  // the 'readable' event and move on.
  if (n === 0 &&
      state.needReadable &&
      (state.length >= state.highWaterMark || state.ended)) {
    debug('read: emitReadable', state.length, state.ended);
    if (state.length === 0 && state.ended)
      endReadable(this);
    else
      emitReadable(this);
    return null;
  }

  n = howMuchToRead(n, state);

  // if we've ended, and we're now clear, then finish it up.
  if (n === 0 && state.ended) {
    if (state.length === 0)
      endReadable(this);
    return null;
  }

  // All the actual chunk generation logic needs to be
  // *below* the call to _read.  The reason is that in certain
  // synthetic stream cases, such as passthrough streams, _read
  // may be a completely synchronous operation which may change
  // the state of the read buffer, providing enough data when
  // before there was *not* enough.
  //
  // So, the steps are:
  // 1. Figure out what the state of things will be after we do
  // a read from the buffer.
  //
  // 2. If that resulting state will trigger a _read, then call _read.
  // Note that this may be asynchronous, or synchronous.  Yes, it is
  // deeply ugly to write APIs this way, but that still doesn't mean
  // that the Readable class should behave improperly, as streams are
  // designed to be sync/async agnostic.
  // Take note if the _read call is sync or async (ie, if the read call
  // has returned yet), so that we know whether or not it's safe to emit
  // 'readable' etc.
  //
  // 3. Actually pull the requested chunks out of the buffer and return.

  // if we need a readable event, then we need to do some reading.
  var doRead = state.needReadable;
  debug('need readable', doRead);

  // if we currently have less than the highWaterMark, then also read some
  if (state.length === 0 || state.length - n < state.highWaterMark) {
    doRead = true;
    debug('length less than watermark', doRead);
  }

  // however, if we've ended, then there's no point, and if we're already
  // reading, then it's unnecessary.
  if (state.ended || state.reading) {
    doRead = false;
    debug('reading or ended', doRead);
  }

  if (doRead) {
    debug('do read');
    state.reading = true;
    state.sync = true;
    // if the length is currently zero, then we *need* a readable event.
    if (state.length === 0)
      state.needReadable = true;
    // call internal read method
    this._read(state.highWaterMark);
    state.sync = false;
  }

  // If _read pushed data synchronously, then `reading` will be false,
  // and we need to re-evaluate how much data we can return to the user.
  if (doRead && !state.reading)
    n = howMuchToRead(nOrig, state);

  var ret;
  if (n > 0)
    ret = fromList(n, state);
  else
    ret = null;

  if (util.isNull(ret)) {
    state.needReadable = true;
    n = 0;
  }

  state.length -= n;

  // If we have nothing in the buffer, then we want to know
  // as soon as we *do* get something into the buffer.
  if (state.length === 0 && !state.ended)
    state.needReadable = true;

  // If we tried to read() past the EOF, then emit end on the next tick.
  if (nOrig !== n && state.ended && state.length === 0)
    endReadable(this);

  if (!util.isNull(ret))
    this.emit('data', ret);

  return ret;
};

function chunkInvalid(state, chunk) {
  var er = null;
  if (!util.isBuffer(chunk) &&
      !util.isString(chunk) &&
      !util.isNullOrUndefined(chunk) &&
      !state.objectMode &&
      !er) {
    er = new TypeError('Invalid non-string/buffer chunk');
  }
  return er;
}

function onEofChunk(stream, state) {
  if (state.decoder && !state.ended && state.decoder.end) {
    var chunk = state.decoder.end();
    if (chunk && chunk.length) {
      state.buffer.push(chunk);
      state.length += state.objectMode ? 1 : chunk.length;
    }
  }
  state.ended = true;

  // emit 'readable' now to make sure it gets picked up.
  emitReadable(stream);
}

// Don't emit readable right away in sync mode, because this can trigger
// another read() call => stack overflow.  This way, it might trigger
// a nextTick recursion warning, but that's not so bad.
function emitReadable(stream) {
  var state = stream._readableState;
  state.needReadable = false;
  if (!state.emittedReadable) {
    debug('emitReadable', state.flowing);
    state.emittedReadable = true;
    if (state.sync)
      process.nextTick(function() {
        emitReadable_(stream);
      });
    else
      emitReadable_(stream);
  }
}

function emitReadable_(stream) {
  debug('emit readable');
  stream.emit('readable');
  flow(stream);
}

// at this point, the user has presumably seen the 'readable' event,
// and called read() to consume some data.  that may have triggered
// in turn another _read(n) call, in which case reading = true if
// it's in progress.
// However, if we're not ended, or reading, and the length < hwm,
// then go ahead and try to read some more preemptively.
function maybeReadMore(stream, state) {
  if (!state.readingMore) {
    state.readingMore = true;
    process.nextTick(function() {
      maybeReadMore_(stream, state);
    });
  }
}

function maybeReadMore_(stream, state) {
  var len = state.length;
  while (!state.reading && !state.flowing && !state.ended &&
         state.length < state.highWaterMark) {
    debug('maybeReadMore read 0');
    stream.read(0);
    if (len === state.length)
      // didn't get any data, stop spinning.
      break;
    else
      len = state.length;
  }
  state.readingMore = false;
}

// abstract method.  to be overridden in specific implementation classes.
// call cb(er, data) where data is <= n in length.
// for virtual (non-string, non-buffer) streams, "length" is somewhat
// arbitrary, and perhaps not very meaningful.
Readable.prototype._read = function(n) {
  this.emit('error', new Error('not implemented'));
};

Readable.prototype.pipe = function(dest, pipeOpts) {
  var src = this;
  var state = this._readableState;

  switch (state.pipesCount) {
    case 0:
      state.pipes = dest;
      break;
    case 1:
      state.pipes = [state.pipes, dest];
      break;
    default:
      state.pipes.push(dest);
      break;
  }
  state.pipesCount += 1;
  debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts);

  var doEnd = (!pipeOpts || pipeOpts.end !== false) &&
              dest !== process.stdout &&
              dest !== process.stderr;

  var endFn = doEnd ? onend : cleanup;
  if (state.endEmitted)
    process.nextTick(endFn);
  else
    src.once('end', endFn);

  dest.on('unpipe', onunpipe);
  function onunpipe(readable) {
    debug('onunpipe');
    if (readable === src) {
      cleanup();
    }
  }

  function onend() {
    debug('onend');
    dest.end();
  }

  // when the dest drains, it reduces the awaitDrain counter
  // on the source.  This would be more elegant with a .once()
  // handler in flow(), but adding and removing repeatedly is
  // too slow.
  var ondrain = pipeOnDrain(src);
  dest.on('drain', ondrain);

  function cleanup() {
    debug('cleanup');
    // cleanup event handlers once the pipe is broken
    dest.removeListener('close', onclose);
    dest.removeListener('finish', onfinish);
    dest.removeListener('drain', ondrain);
    dest.removeListener('error', onerror);
    dest.removeListener('unpipe', onunpipe);
    src.removeListener('end', onend);
    src.removeListener('end', cleanup);
    src.removeListener('data', ondata);

    // if the reader is waiting for a drain event from this
    // specific writer, then it would cause it to never start
    // flowing again.
    // So, if this is awaiting a drain, then we just call it now.
    // If we don't know, then assume that we are waiting for one.
    if (state.awaitDrain &&
        (!dest._writableState || dest._writableState.needDrain))
      ondrain();
  }

  src.on('data', ondata);
  function ondata(chunk) {
    debug('ondata');
    var ret = dest.write(chunk);
    if (false === ret) {
      debug('false write response, pause',
            src._readableState.awaitDrain);
      src._readableState.awaitDrain++;
      src.pause();
    }
  }

  // if the dest has an error, then stop piping into it.
  // however, don't suppress the throwing behavior for this.
  function onerror(er) {
    debug('onerror', er);
    unpipe();
    dest.removeListener('error', onerror);
    if (EE.listenerCount(dest, 'error') === 0)
      dest.emit('error', er);
  }
  // This is a brutally ugly hack to make sure that our error handler
  // is attached before any userland ones.  NEVER DO THIS.
  if (!dest._events.error)
    dest.on('error', onerror);
  else if (Array.isArray(dest._events.error))
    dest._events.error.unshift(onerror);
  else
    dest._events.error = [onerror, dest._events.error];

  // Both close and finish should trigger unpipe, but only once.
  function onclose() {
    dest.removeListener('finish', onfinish);
    unpipe();
  }
  dest.once('close', onclose);
  function onfinish() {
    debug('onfinish');
    dest.removeListener('close', onclose);
    unpipe();
  }
  dest.once('finish', onfinish);

  function unpipe() {
    debug('unpipe');
    src.unpipe(dest);
  }

  // tell the dest that it's being piped to
  dest.emit('pipe', src);

  // start the flow if it hasn't been started already.
  if (!state.flowing) {
    debug('pipe resume');
    src.resume();
  }

  return dest;
};

function pipeOnDrain(src) {
  return function() {
    var state = src._readableState;
    debug('pipeOnDrain', state.awaitDrain);
    if (state.awaitDrain)
      state.awaitDrain--;
    if (state.awaitDrain === 0 && EE.listenerCount(src, 'data')) {
      state.flowing = true;
      flow(src);
    }
  };
}

Readable.prototype.unpipe = function(dest) {
  var state = this._readableState;

  // if we're not piping anywhere, then do nothing.
  if (state.pipesCount === 0)
    return this;

  // just one destination.  most common case.
  if (state.pipesCount === 1) {
    // passed in one, but it's not the right one.
    if (dest && dest !== state.pipes)
      return this;

    if (!dest)
      dest = state.pipes;

    // got a match.
    state.pipes = null;
    state.pipesCount = 0;
    state.flowing = false;
    if (dest)
      dest.emit('unpipe', this);
    return this;
  }

  // slow case. multiple pipe destinations.

  if (!dest) {
    // remove all.
    var dests = state.pipes;
    var len = state.pipesCount;
    state.pipes = null;
    state.pipesCount = 0;
    state.flowing = false;

    for (var i = 0; i < len; i++)
      dests[i].emit('unpipe', this);
    return this;
  }

  // try to find the right one.
  var i = state.pipes.indexOf(dest);
  if (i === -1)
    return this;

  state.pipes.splice(i, 1);
  state.pipesCount -= 1;
  if (state.pipesCount === 1)
    state.pipes = state.pipes[0];

  dest.emit('unpipe', this);

  return this;
};

// set up data events if they are asked for
// Ensure readable listeners eventually get something
Readable.prototype.on = function(ev, fn) {
  var res = Stream.prototype.on.call(this, ev, fn);

  // If listening to data, and it has not explicitly been paused,
  // then call resume to start the flow of data on the next tick.
  if (ev === 'data' && false !== this._readableState.flowing) {
    this.resume();
  }

  if (ev === 'readable' && this.readable) {
    var state = this._readableState;
    if (!state.readableListening) {
      state.readableListening = true;
      state.emittedReadable = false;
      state.needReadable = true;
      if (!state.reading) {
        var self = this;
        process.nextTick(function() {
          debug('readable nexttick read 0');
          self.read(0);
        });
      } else if (state.length) {
        emitReadable(this, state);
      }
    }
  }

  return res;
};
Readable.prototype.addListener = Readable.prototype.on;

// pause() and resume() are remnants of the legacy readable stream API
// If the user uses them, then switch into old mode.
Readable.prototype.resume = function() {
  var state = this._readableState;
  if (!state.flowing) {
    debug('resume');
    state.flowing = true;
    if (!state.reading) {
      debug('resume read 0');
      this.read(0);
    }
    resume(this, state);
  }
};

function resume(stream, state) {
  if (!state.resumeScheduled) {
    state.resumeScheduled = true;
    process.nextTick(function() {
      resume_(stream, state);
    });
  }
}

function resume_(stream, state) {
  state.resumeScheduled = false;
  stream.emit('resume');
  flow(stream);
  if (state.flowing && !state.reading)
    stream.read(0);
}

Readable.prototype.pause = function() {
  debug('call pause flowing=%j', this._readableState.flowing);
  if (false !== this._readableState.flowing) {
    debug('pause');
    this._readableState.flowing = false;
    this.emit('pause');
  }
};

function flow(stream) {
  var state = stream._readableState;
  debug('flow', state.flowing);
  if (state.flowing) {
    do {
      var chunk = stream.read();
    } while (null !== chunk && state.flowing);
  }
}

// wrap an old-style stream as the async data source.
// This is *not* part of the readable stream interface.
// It is an ugly unfortunate mess of history.
Readable.prototype.wrap = function(stream) {
  var state = this._readableState;
  var paused = false;

  var self = this;
  stream.on('end', function() {
    debug('wrapped end');
    if (state.decoder && !state.ended) {
      var chunk = state.decoder.end();
      if (chunk && chunk.length)
        self.push(chunk);
    }

    self.push(null);
  });

  stream.on('data', function(chunk) {
    debug('wrapped data');
    if (state.decoder)
      chunk = state.decoder.write(chunk);
    if (!chunk || !state.objectMode && !chunk.length)
      return;

    var ret = self.push(chunk);
    if (!ret) {
      paused = true;
      stream.pause();
    }
  });

  // proxy all the other methods.
  // important when wrapping filters and duplexes.
  for (var i in stream) {
    if (util.isFunction(stream[i]) && util.isUndefined(this[i])) {
      this[i] = function(method) { return function() {
        return stream[method].apply(stream, arguments);
      }}(i);
    }
  }

  // proxy certain important events.
  var events = ['error', 'close', 'destroy', 'pause', 'resume'];
  events.forEach(function(ev) {
    stream.on(ev, self.emit.bind(self, ev));
  });

  // when we try to consume some more bytes, simply unpause the
  // underlying stream.
  self._read = function(n) {
    debug('wrapped _read', n);
    if (paused) {
      paused = false;
      stream.resume();
    }
  };

  return self;
};

// exposed for testing purposes only.
Readable._fromList = fromList;

// Pluck off n bytes from an array of buffers.
// Length is the combined lengths of all the buffers in the list.
function fromList(n, state) {
  var list = state.buffer;
  var length = state.length;
  var stringMode = !!state.decoder;
  var objectMode = !!state.objectMode;
  var ret;

  // nothing in the list, definitely empty.
  if (list.length === 0)
    return null;

  if (length === 0)
    ret = null;
  else if (objectMode)
    ret = list.shift();
  else if (!n || n >= length) {
    // read it all, truncate the array.
    if (stringMode)
      ret = list.join('');
    else
      ret = Buffer.concat(list, length);
    list.length = 0;
  } else {
    // read just some of it.
    if (n < list[0].length) {
      // just take a part of the first list item.
      // slice is the same for buffers and strings.
      var buf = list[0];
      ret = buf.slice(0, n);
      list[0] = buf.slice(n);
    } else if (n === list[0].length) {
      // first list is a perfect match
      ret = list.shift();
    } else {
      // complex case.
      // we have enough to cover it, but it spans past the first buffer.
      if (stringMode)
        ret = '';
      else
        ret = new Buffer(n);

      var c = 0;
      for (var i = 0, l = list.length; i < l && c < n; i++) {
        var buf = list[0];
        var cpy = Math.min(n - c, buf.length);

        if (stringMode)
          ret += buf.slice(0, cpy);
        else
          buf.copy(ret, c, 0, cpy);

        if (cpy < buf.length)
          list[0] = buf.slice(cpy);
        else
          list.shift();

        c += cpy;
      }
    }
  }

  return ret;
}

function endReadable(stream) {
  var state = stream._readableState;

  // If we get here before consuming all the bytes, then that is a
  // bug in node.  Should never happen.
  if (state.length > 0)
    throw new Error('endReadable called on non-empty stream');

  if (!state.endEmitted) {
    state.ended = true;
    process.nextTick(function() {
      // Check that we didn't get one last unshift.
      if (!state.endEmitted && state.length === 0) {
        state.endEmitted = true;
        stream.readable = false;
        stream.emit('end');
      }
    });
  }
}


<!DOCTYPE html>

	<meta charset="utf-8">
	<title>jQuery UI Datepicker - Display month & year menus</title>
	<link rel="stylesheet" href="../../themes/base/jquery.ui.all.css">

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

Date: <input type="text" id="datepicker">

Show month and year dropdowns in place of the static month/year header to facilitate navigation through large timeframes.  Add the boolean changeMonth and changeYear options.


var ScriptAgent = require("LiveDevelopment/Agents/ScriptAgent");

var HighlightAgent = require("LiveDevelopment/Agents/HighlightAgent");

var JSDocument = function JSDocument(doc, editor) {

keep keep keep replace replace 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 require, define, brackets: true, $, window, navigator, Mustache */

/**
 * brackets is the root of the Brackets codebase. This file pulls in all other modules as
 * dependencies (or dependencies thereof), initializes the UI, and binds global menus & keyboard
 * shortcuts to their Commands.
 *
 * TODO: (issue #264) break out the definition of brackets into a separate module from the application controller logic
 *
 * Unlike other modules, this one can be accessed without an explicit require() because it exposes
 * a global object, window.brackets.
 */
define(function (require, exports, module) {
    "use strict";

    // Load dependent non-module scripts
    require("widgets/bootstrap-dropdown");
    require("widgets/bootstrap-modal");
    require("widgets/bootstrap-twipsy-mod");
    require("thirdparty/path-utils/path-utils.min");
    require("thirdparty/smart-auto-complete-local/jquery.smart_autocomplete");

    // Load CodeMirror add-ons--these attach themselves to the CodeMirror module
    require("thirdparty/CodeMirror2/addon/fold/xml-fold");
    require("thirdparty/CodeMirror2/addon/edit/matchtags");
    require("thirdparty/CodeMirror2/addon/edit/matchbrackets");
    require("thirdparty/CodeMirror2/addon/edit/closebrackets");
    require("thirdparty/CodeMirror2/addon/edit/closetag");
    require("thirdparty/CodeMirror2/addon/scroll/scrollpastend");
    require("thirdparty/CodeMirror2/addon/selection/active-line");
    require("thirdparty/CodeMirror2/addon/mode/multiplex");
    require("thirdparty/CodeMirror2/addon/mode/overlay");
    require("thirdparty/CodeMirror2/addon/search/match-highlighter");
    require("thirdparty/CodeMirror2/addon/search/searchcursor");
    require("thirdparty/CodeMirror2/keymap/sublime");

    // Load dependent modules
    var Global                  = require("utils/Global"),
        AppInit                 = require("utils/AppInit"),
        LanguageManager         = require("language/LanguageManager"),
        ProjectManager          = require("project/ProjectManager"),
        DocumentManager         = require("document/DocumentManager"),
        EditorManager           = require("editor/EditorManager"),
        CSSInlineEditor         = require("editor/CSSInlineEditor"),
        JSUtils                 = require("language/JSUtils"),
        WorkingSetView          = require("project/WorkingSetView"),
        WorkingSetSort          = require("project/WorkingSetSort"),
        DocumentCommandHandlers = require("document/DocumentCommandHandlers"),
        FileViewController      = require("project/FileViewController"),
        FileSyncManager         = require("project/FileSyncManager"),
        KeyBindingManager       = require("command/KeyBindingManager"),
        Commands                = require("command/Commands"),
        CommandManager          = require("command/CommandManager"),
        CodeHintManager         = require("editor/CodeHintManager"),
        PerfUtils               = require("utils/PerfUtils"),
        FileSystem              = require("filesystem/FileSystem"),
        QuickOpen               = require("search/QuickOpen"),
        Menus                   = require("command/Menus"),
        FileUtils               = require("file/FileUtils"),
        MainViewHTML            = require("text!htmlContent/main-view.html"),
        Strings                 = require("strings"),
        Dialogs                 = require("widgets/Dialogs"),
        DefaultDialogs          = require("widgets/DefaultDialogs"),
        ExtensionLoader         = require("utils/ExtensionLoader"),
        SidebarView             = require("project/SidebarView"),
        Async                   = require("utils/Async"),
        UpdateNotification      = require("utils/UpdateNotification"),
        UrlParams               = require("utils/UrlParams").UrlParams,
        PreferencesManager      = require("preferences/PreferencesManager"),
        Resizer                 = require("utils/Resizer"),
        LiveDevelopmentMain     = require("LiveDevelopment/main"),
        NodeConnection          = require("utils/NodeConnection"),
        NodeDomain              = require("utils/NodeDomain"),
        ExtensionUtils          = require("utils/ExtensionUtils"),
        DragAndDrop             = require("utils/DragAndDrop"),
        ColorUtils              = require("utils/ColorUtils"),
        CodeInspection          = require("language/CodeInspection"),
        NativeApp               = require("utils/NativeApp"),
        DeprecationWarning      = require("utils/DeprecationWarning"),
        ViewCommandHandlers     = require("view/ViewCommandHandlers"),
        _                       = require("thirdparty/lodash");

    // DEPRECATED: In future we want to remove the global CodeMirror, but for now we
    // expose our required CodeMirror globally so as to avoid breaking extensions in the
    // interim.
    var CodeMirror = require("thirdparty/CodeMirror2/lib/codemirror");

    Object.defineProperty(window, "CodeMirror", {
        get: function () {
            DeprecationWarning.deprecationWarning('Use brackets.getModule("thirdparty/CodeMirror2/lib/codemirror") instead of global CodeMirror.', true);
            return CodeMirror;
        }
    });

    // Load modules that self-register and just need to get included in the main project
    require("command/DefaultMenus");
    require("document/ChangedDocumentTracker");
    require("editor/EditorStatusBar");
    require("editor/EditorCommandHandlers");
    require("editor/EditorOptionHandlers");
    require("help/HelpCommandHandlers");
    require("search/FindInFiles");
    require("search/FindReplace");
    require("extensibility/InstallExtensionDialog");
    require("extensibility/ExtensionManagerDialog");
    require("editor/ImageViewer");

    // Deprecated modules loaded just so extensions can still use them for now
    require("utils/CollectionUtils");
    // Compatibility shims for filesystem API migration
    require("project/FileIndexManager");
    require("file/NativeFileSystem");
    require("file/NativeFileError");

    PerfUtils.addMeasurement("brackets module dependencies resolved");

    // Local variables
    var params = new UrlParams();

    // read URL params
    params.parse();

    function _initTest() {
        // TODO: (issue #265) Make sure the "test" object is not included in final builds
        // All modules that need to be tested from the context of the application
        // must to be added to this object. The unit tests cannot just pull
        // in the modules since they would run in context of the unit test window,
        // and would not have access to the app html/css.
        brackets.test = {
            CodeHintManager         : CodeHintManager,
            CodeInspection          : CodeInspection,
            CommandManager          : CommandManager,
            Commands                : Commands,
            CSSUtils                : require("language/CSSUtils"),
            DefaultDialogs          : DefaultDialogs,
            Dialogs                 : Dialogs,
            DocumentCommandHandlers : DocumentCommandHandlers,
            DocumentManager         : DocumentManager,
            DOMAgent                : require("LiveDevelopment/Agents/DOMAgent"),
            DragAndDrop             : DragAndDrop,
            EditorManager           : EditorManager,
            ExtensionLoader         : ExtensionLoader,
            ExtensionUtils          : ExtensionUtils,
            FileFilters             : require("search/FileFilters"),
            FileSyncManager         : FileSyncManager,
            FileSystem              : FileSystem,
            FileViewController      : FileViewController,
            FindInFiles             : require("search/FindInFiles"),
            HTMLInstrumentation     : require("language/HTMLInstrumentation"),
            Inspector               : require("LiveDevelopment/Inspector/Inspector"),
            InstallExtensionDialog  : require("extensibility/InstallExtensionDialog"),
            JSUtils                 : JSUtils,
            KeyBindingManager       : KeyBindingManager,
            LanguageManager         : LanguageManager,
            LiveDevelopment         : require("LiveDevelopment/LiveDevelopment"),
            LiveDevServerManager    : require("LiveDevelopment/LiveDevServerManager"),
            Menus                   : Menus,
            MultiRangeInlineEditor  : require("editor/MultiRangeInlineEditor").MultiRangeInlineEditor,
            NativeApp               : NativeApp,
            PerfUtils               : PerfUtils,
            PreferencesManager      : PreferencesManager,
            ProjectManager          : ProjectManager,
            RemoteAgent             : require("LiveDevelopment/Agents/RemoteAgent"),
            ScrollTrackMarkers      : require("search/ScrollTrackMarkers"),
            UpdateNotification      : require("utils/UpdateNotification"),
            WorkingSetView          : WorkingSetView,

            doneLoading             : false
        };

        AppInit.appReady(function () {
            brackets.test.doneLoading = true;
        });
    }

    function _onReady() {
        PerfUtils.addMeasurement("window.document Ready");

        EditorManager.setEditorHolder($("#editor-holder"));

        // Let the user know Brackets doesn't run in a web browser yet
        if (brackets.inBrowser) {
            Dialogs.showModalDialog(
                DefaultDialogs.DIALOG_ID_ERROR,
                Strings.ERROR_IN_BROWSER_TITLE,
                Strings.ERROR_IN_BROWSER
            );
        }

        // Use quiet scrollbars if we aren't on Lion. If we're on Lion, only
        // use native scroll bars when the mouse is not plugged in or when
        // using the "Always" scroll bar setting.
        var osxMatch = /Mac OS X 10\D([\d+])\D/.exec(navigator.userAgent);
        if (osxMatch && osxMatch[1] && Number(osxMatch[1]) >= 7) {
            // test a scrolling div for scrollbars
            var $testDiv = $("

").appendTo(window.document.body);

            if ($testDiv.outerWidth() === $testDiv.get(0).clientWidth) {
                $(".sidebar").removeClass("quiet-scrollbars");
            }

            $testDiv.remove();
        }

        // Load default languages and preferences
        Async.waitForAll([LanguageManager.ready, PreferencesManager.ready]).always(function () {
            // Load all extensions. This promise will complete even if one or more
            // extensions fail to load.
            var extensionPathOverride = params.get("extensions");  // used by unit tests
            var extensionLoaderPromise = ExtensionLoader.init(extensionPathOverride ? extensionPathOverride.split(",") : null);

            // Load the initial project after extensions have loaded
            extensionLoaderPromise.always(function () {
                // Finish UI initialization
                ViewCommandHandlers.restoreFontSize();
                var initialProjectPath = ProjectManager.getInitialProjectPath();
                ProjectManager.openProject(initialProjectPath).always(function () {
                    _initTest();

                    // If this is the first launch, and we have an index.html file in the project folder (which should be
                    // the samples folder on first launch), open it automatically. (We explicitly check for the
                    // samples folder in case this is the first time we're launching Brackets after upgrading from
                    // an old version that might not have set the "afterFirstLaunch" pref.)
                    var deferred = new $.Deferred();

                    if (!params.get("skipSampleProjectLoad") && !PreferencesManager.getViewState("afterFirstLaunch")) {
                        PreferencesManager.setViewState("afterFirstLaunch", "true");
                        if (ProjectManager.isWelcomeProjectPath(initialProjectPath)) {
                            FileSystem.resolve(initialProjectPath + "index.html", function (err, file) {
                                if (!err) {
                                    var promise = CommandManager.execute(Commands.FILE_ADD_TO_WORKING_SET, { fullPath: file.fullPath });
                                    promise.then(deferred.resolve, deferred.reject);
                                } else {
                                    deferred.reject();
                                }
                            });
                        } else {
                            deferred.resolve();
                        }
                    } else {
                        deferred.resolve();
                    }

                    deferred.always(function () {
                        // Signal that Brackets is loaded
                        AppInit._dispatchReady(AppInit.APP_READY);

                        PerfUtils.addMeasurement("Application Startup");

                        if (PreferencesManager._isUserScopeCorrupt()) {
                            Dialogs.showModalDialog(
                                DefaultDialogs.DIALOG_ID_ERROR,
                                Strings.ERROR_PREFS_CORRUPT_TITLE,
                                Strings.ERROR_PREFS_CORRUPT
                            )
                                .done(function () {
                                    CommandManager.execute(Commands.FILE_OPEN_PREFERENCES);
                                });
                        }

                    });

                    // See if any startup files were passed to the application
                    if (brackets.app.getPendingFilesToOpen) {
                        brackets.app.getPendingFilesToOpen(function (err, files) {
                            DragAndDrop.openDroppedFiles(files);
                        });
                    }
                });
            });
        });

        // Check for updates
        if (!params.get("skipUpdateCheck") && !brackets.inBrowser) {
            AppInit.appReady(function () {
                // launches periodic checks for updates cca every 24 hours
                UpdateNotification.launchAutomaticUpdate();
            });
        }
    }

    /**
     * Setup event handlers prior to dispatching AppInit.HTML_READY
     */
    function _beforeHTMLReady() {
        // Add the platform (mac or win) to the body tag so we can have platform-specific CSS rules
        $("body").addClass("platform-" + brackets.platform);

        // Browser-hosted version may also have different CSS (e.g. since '#titlebar' is shown)
        if (brackets.inBrowser) {
            $("body").addClass("in-browser");
        } else {
            $("body").addClass("in-appshell");
        }

        // Enable/Disable HTML Menus
        if (brackets.nativeMenus) {
            $("body").addClass("has-appshell-menus");
        } else {
            // (issue #5310) workaround for bootstrap dropdown: prevent the menu item to grab
            // the focus -- override jquery focus implementation for top-level menu items
            (function () {
                var defaultFocus = $.fn.focus;
                $.fn.focus = function () {
                    if (!this.hasClass("dropdown-toggle")) {
                        return defaultFocus.apply(this, arguments);
                    }
                };
            }());
        }

        // Localize MainViewHTML and inject into  tag
        $("body").html(Mustache.render(MainViewHTML, Strings));

        // Update title
        $("title").text(brackets.config.app_title);

        // Prevent unhandled drag and drop of files into the browser from replacing
        // the entire Brackets app. This doesn't prevent children from choosing to
        // handle drops.
        $(window.document.body)
            .on("dragover", function (event) {
                var dropEffect = "none";
                if (event.originalEvent.dataTransfer.files) {
                    event.stopPropagation();
                    event.preventDefault();
                    // Don't allow drag-and-drop of files/folders when a modal dialog is showing.
                    if ($(".modal.instance").length === 0 &&
                            DragAndDrop.isValidDrop(event.originalEvent.dataTransfer.items)) {
                        dropEffect = "copy";
                    }
                    event.originalEvent.dataTransfer.dropEffect = dropEffect;
                }
            })
            .on("drop", function (event) {
                if (event.originalEvent.dataTransfer.files) {
                    event.stopPropagation();
                    event.preventDefault();
                    brackets.app.getDroppedFiles(function (err, files) {
                        if (!err) {
                            DragAndDrop.openDroppedFiles(files);
                        }
                    });
                }
            });

        // TODO: (issue 269) to support IE, need to listen to document instead (and even then it may not work when focus is in an input field?)
        $(window).focus(function () {
            // This call to syncOpenDocuments() *should* be a no-op now that we have
            // file watchers, but is still here as a safety net.
            FileSyncManager.syncOpenDocuments();
        });

        // Prevent unhandled middle button clicks from triggering native behavior
        // Example: activating AutoScroll (see #510)
        $("html").on("mousedown", ".inline-widget", function (e) {
            if (e.button === 1) {
                e.preventDefault();
            }
        });

        // The .no-focus style is added to clickable elements that should
        // not steal focus. Calling preventDefault() on mousedown prevents
        // focus from going to the click target.
        $("html").on("mousedown", ".no-focus", function (e) {
            // Text fields should always be focusable.
            var $target = $(e.target),
                isTextField =
                    $target.is("input[type=text]") ||
                    $target.is("input[type=number]") ||
                    $target.is("input[type=password]") ||
                    $target.is("input:not([type])") || // input with no type attribute defaults to text
                    $target.is("textarea");

            if (!isTextField) {
                e.preventDefault();
            }
        });

        // Prevent clicks on any link from navigating to a different page (which could lose unsaved
        // changes). We can't use a simple .on("click", "a") because of http://bugs.jquery.com/ticket/3861:
        // jQuery hides non-left clicks from such event handlers, yet middle-clicks still cause CEF to
        // navigate. Also, a capture handler is more reliable than bubble.
        window.document.body.addEventListener("click", function (e) {
            // Check parents too, in case link has inline formatting tags
            var node = e.target, url;
            while (node) {
                if (node.tagName === "A") {
                    url = node.getAttribute("href");
                    if (url && !url.match(/^#/)) {
                        NativeApp.openURLInDefaultBrowser(url);
                    }
                    e.preventDefault();
                    break;
                }
                node = node.parentElement;
            }
        }, true);
    }

    // Wait for view state to load.
    var viewStateTimer = PerfUtils.markStart("User viewstate loading");
    PreferencesManager._smUserScopeLoading.always(function () {
        PerfUtils.addMeasurement(viewStateTimer);
        // Dispatch htmlReady event
        _beforeHTMLReady();
        AppInit._dispatchReady(AppInit.HTML_READY);
        $(window.document).ready(_onReady);
    });
});


/* Kazakh (UTF-8) initialisation for the jQuery UI date picker plugin. */
/* Written by Dmitriy Karasyov (dmitriy.karasyov@gmail.com). */
jQuery(function($){
	$.datepicker.regional['kk'] = {
		closeText: 'Жабу',
		prevText: '<Алдыңғы',
		nextText: 'Келесі>',
		currentText: 'Бүгін',
		monthNames: ['Қаңтар','Ақпан','Наурыз','Сәуір','Мамыр','Маусым',
		'Шілде','Тамыз','Қыркүйек','Қазан','Қараша','Желтоқсан'],
		monthNamesShort: ['Қаң','Ақп','Нау','Сәу','Мам','Мау',
		'Шіл','Там','Қыр','Қаз','Қар','Жел'],
		dayNames: ['Жексенбі','Дүйсенбі','Сейсенбі','Сәрсенбі','Бейсенбі','Жұма','Сенбі'],
		dayNamesShort: ['жкс','дсн','ссн','срс','бсн','жма','снб'],
		dayNamesMin: ['Жк','Дс','Сс','Ср','Бс','Жм','Сн'],
		weekHeader: 'Не',
		dateFormat: 'dd.mm.yy',
		firstDay: 1,
		isRTL: false,
		showMonthAfterYear: false,
		yearSuffix: ''};
	$.datepicker.setDefaults($.datepicker.regional['kk']);
});


<!DOCTYPE html>

	<meta charset="utf-8">
	<title>jQuery UI Resizable - Constrain resize area</title>
	<link rel="stylesheet" href="../../themes/base/jquery.ui.all.css">

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

Containment

Resizable

Define the boundaries of the resizable area. Use the containment option to specify a parent DOM element or a jQuery selector, like 'document.'


/*
 * Copyright (c) 2013 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.
 *
 */

/**

    This class parses configuration values from a JSON object. The expected
    name of the file is “.jscodehints” but this class does not actually read
    the file, it just provides a constant, FILE_NAME.

    The following properties are supported:

     "excluded-directories" - An array of directory strings that match
     directories that will be excluded from analysis. Directories may be
     excluded if they contain automated tests that aren’t relevant for code hinting.
     The wildcards “*” and “?” are supported in strings.

     "excluded-files" - An array of file strings that match files that will
     be excluded from analysis. Files are typically excluded because
     their API is in a JSON file or they are known to cause problems with either
     stability or performance. The wildcards “*” and “?” are supported in strings.

     "max-file-count" - Limits the total number of files that can be processed for
     hints.

     "max-file-size" - Files larger than this number of bytes will not be parsed.

     The strings in "excluded-directories" or "excluded-files" will be treated as a
     regular expression if the first and last characters of the string are the '/'
     character. Note the '\' character in a regular expression needs to be escaped
     to be valid in a JSON formatted file. For example "/[\d]/" becomes "/[\\d]/".

     Example file:

     {
     "excluded-directories" : ["/ex[\\w]*ed/"],
     "excluded-files" : ["require.js", "jquery*.js", "less*.min.js", "ember*.js", "d2?.js", "d3*"],
     "max-file-count": 100,
     "max-file-size": 524288
     }

 */

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

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

    var StringUtils      = brackets.getModule("utils/StringUtils");

    /**
     *  Convert an array of strings with optional wildcards, to an equivalent
     *  regular expression.
     *
     * @param {Array.<string|RegExp>} settings
     * @param {?RegExp} defaultRegExp - default regular expression to use
     * if none if provided.
     * @return {RegExp} Regular expression that captures the array of string
     * with optional wildcards.
     */
    function settingsToRegExp(settings, defaultRegExp) {
        var regExpString = "";

        if (settings instanceof Array && settings.length > 0) {

            // Append default settings to user settings. The default
            // settings are builtin and cannot be overridden.
            if (defaultRegExp) {
                settings.push("/" + defaultRegExp.source + "/");
            }

            // convert each string, with optional wildcards to an equivalent
            // string in a regular expression.
            settings.forEach(function (value, index) {

                if (typeof value === "string") {
                    var isRegExp = value[0] === '/' && value[value.length - 1] === '/';

                    if (isRegExp) {
                        value = value.substring(1, value.length - 1);
                    } else {
                        value = StringUtils.regexEscape(value);

                        // convert user input wildcard, "*" or "?", to a regular
                        // expression. We can just replace the escaped "*" or "?"
                        // since we know it is a wildcard.
                        value = value.replace("\\?", ".?");
                        value = value.replace("\\*", ".*");

                        // Add "^" and "$" to prevent matching in the middle of strings.
                        value = "^" + value + "$";
                    }

                    if (index > 0) {
                        regExpString += "|";
                    }

                    regExpString = regExpString.concat(value);
                }
            });
        }

        if (!regExpString) {
            return defaultRegExp;
        }

        return new RegExp(regExpString);
    }

    /**
     * Constructor to create a default preference object.
     *
     * @constructor
     * @param {Object=} prefs - preference object
     */
    function Preferences(prefs) {
        var DEFAULT_EXCLUDED_DIRECTORIES = null, /* no exclusions */
            // exclude require and jquery since we have special knowledge of those
            // temporarily exclude less*min.js because it is causing instability in tern.
            // exclude ember*.js as it is currently causing problems
            DEFAULT_EXCLUDED_FILES = /^require.*\.js$|^jquery.*\.js$|^less.*\.min\.js$/,
            DEFAULT_MAX_FILE_COUNT = 100,
            DEFAULT_MAX_FILE_SIZE = 512 * 1024;

        if (prefs) {
            this._excludedDirectories = settingsToRegExp(prefs["excluded-directories"],
                DEFAULT_EXCLUDED_DIRECTORIES);
            this._excludedFiles = settingsToRegExp(prefs["excluded-files"],
                DEFAULT_EXCLUDED_FILES);
            this._maxFileCount = prefs["max-file-count"];
            this._maxFileSize = prefs["max-file-size"];

            // sanity check values
            if (!this._maxFileCount || this._maxFileCount < 0) {
                this._maxFileCount = DEFAULT_MAX_FILE_COUNT;
            }

            if (!this._maxFileSize || this._maxFileSize < 0) {
                this._maxFileSize = DEFAULT_MAX_FILE_SIZE;
            }

        } else {
            this._excludedDirectories = DEFAULT_EXCLUDED_DIRECTORIES;
            this._excludedFiles = DEFAULT_EXCLUDED_FILES;
            this._maxFileCount = DEFAULT_MAX_FILE_COUNT;
            this._maxFileSize = DEFAULT_MAX_FILE_SIZE;
        }
    }

    Preferences.FILE_NAME = ".jscodehints";

    /**
     * Get the regular expression for excluded directories.
     *
     * @return {?RegExp} Regular expression matching the directories that should
     * be excluded. Returns null if no directories are excluded.
     */
    Preferences.prototype.getExcludedDirectories = function () {
        return this._excludedDirectories;
    };

    /**
     * Get the regular expression for excluded files.
     *
     * @return {?RegExp} Regular expression matching the files that should
     * be excluded. Returns null if no files are excluded.
     */
    Preferences.prototype.getExcludedFiles = function () {
        return this._excludedFiles;
    };

    /**
     * Get the maximum number of files that will be analyzed.
     *
     * @return {number}
     */
    Preferences.prototype.getMaxFileCount = function () {
        return this._maxFileCount;
    };

    /**
     * Get the maximum size of a file that will be analyzed. Files that are
     * larger will be ignored.
     *
     * @return {number}
     */
    Preferences.prototype.getMaxFileSize = function () {
        return this._maxFileSize;
    };

    module.exports = Preferences;

});


// TODO: (issue #265) Make sure the "test" object is not included in final builds

// All modules that need to be tested from the context of the application

// must to be added to this object. The unit tests cannot just pull


var assert = require('assert');
var Traverse = require('traverse');

exports['interface map'] = function () {
    var obj = { a : [ 5,6,7 ], b : { c : [8] } };

    assert.deepEqual(
        Traverse.paths(obj)
            .sort()
            .map(function (path) { return path.join('/') })
            .slice(1)
            .join(' ')
         ,
         'a a/0 a/1 a/2 b b/c b/c/0'
    );

    assert.deepEqual(
        Traverse.nodes(obj),
        [
            { a: [ 5, 6, 7 ], b: { c: [ 8 ] } },
            [ 5, 6, 7 ], 5, 6, 7,
            { c: [ 8 ] }, [ 8 ], 8
        ]
    );

    assert.deepEqual(
        Traverse.map(obj, function (node) {
            if (typeof node == 'number') {
                return node + 1000;
            }
            else if (Array.isArray(node)) {
                return node.join(' ');
            }
        }),
        { a: '5 6 7', b: { c: '8' } }
    );

    var nodes = 0;
    Traverse.forEach(obj, function (node) { nodes ++ });
    assert.deepEqual(nodes, 8);
};


stream-counter

keeps track of how many bytes have been written to a stream

# stream-counter

Keep track of how many bytes have been written to a stream.

## Usage

```js
var StreamCounter = require('stream-counter');
var counter = new StreamCounter();
counter.on('progress', function() {
  console.log("progress", counter.bytes);
});
fs.createReadStream('foo.txt').pipe(counter);
```


<!doctype html>

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

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

jQuery UI Core Test Suite


keep keep keep keep keep replace keep 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, brackets, FileError */

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

    var Async           = require("utils/Async"),
        FileSystemError = require("filesystem/FileSystemError");

    /**
     * @private
     * Map an fs error code to a FileError.
     */
    function _browserErrToFileError(err) {
        if (err === brackets.fs.ERR_NOT_FOUND) {
            return FileSystemError.NOT_FOUND;
        }

        // All other errors are mapped to the generic "unknown" error
        return FileSystemError.UNKNOWN;
    }

    var liveBrowserOpenedPIDs = [];

    /** openLiveBrowser
     * Open the given URL in the user's system browser, optionally enabling debugging.
     * @param {string} url The URL to open.
     * @param {boolean=} enableRemoteDebugging Whether to turn on remote debugging. Default false.
     * @return {$.Promise}
     */
    function openLiveBrowser(url, enableRemoteDebugging) {
        var result = new $.Deferred();

        brackets.app.openLiveBrowser(url, !!enableRemoteDebugging, function onRun(err, pid) {
            if (!err) {
                // Undefined ids never get removed from list, so don't push them on
                if (pid !== undefined) {
                    liveBrowserOpenedPIDs.push(pid);
                }
                result.resolve(pid);
            } else {
                result.reject(_browserErrToFileError(err));
            }
        });

        return result.promise();
    }

    /** closeLiveBrowser
     *
     * @return {$.Promise}
     */
    function closeLiveBrowser(pid) {
        var result = new $.Deferred();

        if (isNaN(pid)) {
            pid = 0;
        }
        brackets.app.closeLiveBrowser(function (err) {
            if (!err) {
                var i = liveBrowserOpenedPIDs.indexOf(pid);
                if (i !== -1) {
                    liveBrowserOpenedPIDs.splice(i, 1);
                }
                result.resolve();
            } else {
                result.reject(_browserErrToFileError(err));
            }
        }, pid);

        return result.promise();
    }

    /** closeAllLiveBrowsers
     * Closes all the browsers that were tracked on open
     * TODO: does not seem to work on Windows
     * @return {$.Promise}
     */
    function closeAllLiveBrowsers() {
        //make a copy incase the array is edited as we iterate
        var closeIDs = liveBrowserOpenedPIDs.concat();
        return Async.doSequentially(closeIDs, closeLiveBrowser, false);
    }

    /**
     * Opens a URL in the system default browser
     */
    function openURLInDefaultBrowser(url) {
        brackets.app.openURLInDefaultBrowser(url);
    }

    // Define public API
    exports.openLiveBrowser = openLiveBrowser;
    exports.closeLiveBrowser = closeLiveBrowser;
    exports.closeAllLiveBrowsers = closeAllLiveBrowsers;
    exports.openURLInDefaultBrowser = openURLInDefaultBrowser;
});


/*
 * 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, forin: true, maxerr: 50, regexp: true */
/*global define, $ */

/**
 * HighlightAgent dispatches events for highlight requests from in-browser
 * highlight requests, and allows highlighting nodes and rules in the browser.
 *
 * Trigger "highlight" when a node should be highlighted
 */
define(function HighlightAgent(require, exports, module) {
    "use strict";

    var DOMAgent        = require("LiveDevelopment/Agents/DOMAgent"),
        Inspector       = require("LiveDevelopment/Inspector/Inspector"),
        LiveDevelopment = require("LiveDevelopment/LiveDevelopment"),
        RemoteAgent     = require("LiveDevelopment/Agents/RemoteAgent"),
        _               = require("thirdparty/lodash");

    var _highlight = {}; // active highlight

    // Remote Event: Highlight
    function _onRemoteHighlight(event, res) {
        var node;
        if (res.value === "1") {
            node = DOMAgent.nodeWithId(res.nodeId);
        }
        $(exports).triggerHandler("highlight", [node]);
    }

    /** Hide in-browser highlighting */
    function hide() {
        switch (_highlight.type) {
        case "node":
            Inspector.DOM.hideHighlight();
            break;
        case "css":
            RemoteAgent.call("hideHighlight");
            break;
        }
        _highlight = {};
    }

    /** Highlight a single node using DOM.highlightNode
     * @param {DOMNode} node
     */
    function node(n) {
        if (!LiveDevelopment.config.experimental) {
            return;
        }

        if (!Inspector.config.highlight) {
            return;
        }

        // go to the parent of a text node
        if (n && n.type === 3) {
            n = n.parent;
        }

        // node cannot be highlighted
        if (!n || !n.nodeId || n.type !== 1) {
            return hide();
        }

        // node is already highlighted
        if (_highlight.type === "node" && _highlight.ref === n.nodeId) {
            return;
        }

        // highlight the node
        _highlight = {type: "node", ref: n.nodeId};
        Inspector.DOM.highlightNode(n.nodeId, Inspector.config.highlightConfig);
    }

    /** Highlight all nodes affected by a CSS rule
     * @param {string} rule selector
     */
    function rule(name) {
        if (_highlight.ref === name) {
            return;
        }
        hide();
        _highlight = {type: "css", ref: name};
        RemoteAgent.call("highlightRule", name);
    }

    /** Highlight all nodes with 'data-brackets-id' value
     * that matches id, or if id is an array, matches any of the given ids.
     * @param {string|Array<string>} value of the 'data-brackets-id' to match,
     * or an array of such.
     */
    function domElement(ids) {
        var selector = "";
        if (!Array.isArray(ids)) {
            ids = [ids];
        }
        _.each(ids, function (id) {
            if (selector !== "") {
                selector += ",";
            }
            selector += "[data-brackets-id='" + id + "']";
        });
        rule(selector);
    }

    /**
     * Redraw active highlights
     */
    function redraw() {
        RemoteAgent.call("redrawHighlights");
    }

    /** Initialize the agent */
    function load() {
        if (LiveDevelopment.config.experimental) {
            $(RemoteAgent).on("highlight.HighlightAgent", _onRemoteHighlight);
        }
    }

    /** Clean up */
    function unload() {
        if (LiveDevelopment.config.experimental) {
            $(RemoteAgent).off(".HighlightAgent");
        }
    }

    // Export public functions
    exports.hide = hide;
    exports.node = node;
    exports.rule = rule;
    exports.domElement = domElement;
    exports.redraw = redraw;
    exports.load = load;
    exports.unload = unload;
});


/*
 * 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.
 *
 */

/* Styles for jsTree control */
/* (these are based on jsTree's default theme .css file, so they are not very LESS-like) */

.jstree-brackets li,
.jstree-brackets ins { background-image:url("images/jsTreeSprites.svg"); background-repeat:no-repeat; background-color:transparent; }
.jstree-brackets li { background-position:-90px 0; background-repeat:repeat-y; }
.jstree-brackets li.jstree-last { background:transparent; }
.jstree-brackets .jstree-open > ins { background-position:-72px 0; }
.jstree-brackets .jstree-closed > ins { background-position:-54px 0; }
.jstree-brackets .jstree-leaf > ins { background-position:-36px 0; }

@jstree-icon-backindent: 12px;

/* Make the links in the JS tree the width of the container
 * by shifting the off the screen by negative margin and moving the
 * content back by pushing the padding. The icons are positioned absolute
 * relative to the containing list item so they sit above the a's background.
 * This also means we need to include the size of the sprite in the padding
 * so the text ends up back in the same spot visually
 */
.jstree-brackets li > a {
    @jstree-icon-text-overlap: 2px;
    padding-left: (@jstree-sprite-size - @jstree-icon-backindent - @jstree-icon-text-overlap + 10000px);
    margin-left: -10000px;
    display: block;
}

.jstree li {
    position: relative;
}

.jstree-brackets li {
    line-height: 10px;
    vertical-align: baseline;
    a {
        color: @project-panel-text-1;
        font-size: 13px;
        cursor: default;

        &.jstree-clicked, &.jstree-clicked .extension {
            color: @open-working-file-name-highlight;
        }
    }
    .extension {
        color: @project-panel-text-2;
    }
    &.jstree-closed, &.jstree-open {
        margin-left: 10px;
        > a {
            color: @project-panel-text-2;
        }
    }
    &.jstree-leaf {
        margin-left: 10px;
    }
}

.jstree ins {
    position: absolute;
}
ins.jstree-icon {
    left: -@jstree-icon-backindent !important;
}

.jstree-brackets a .jstree-icon { background-position:-56px -19px; }
.jstree-brackets a.jstree-loading .jstree-icon { background:url("images/throbber.gif") center center no-repeat !important; }

.jstree-brackets li > a {
    padding-top: 3px;
    padding-bottom: 3px;
}
.jstree-brackets li > ins {
    margin-top: 2px;
    margin-bottom: 2px;
}

// These styles control the expand/collapse arrow icons. Most other styles in this file with background-position are unused.
.jstree-brackets .jstree-no-dots li,
.jstree-brackets .jstree-no-dots .jstree-leaf > ins { background:transparent; }
.jstree-brackets .jstree-no-dots .jstree-open > ins { background-position:-18px 0; }
.jstree-brackets .jstree-no-dots .jstree-closed > ins { background-position:0 0; }

.jstree-brackets .jstree-no-icons a .jstree-icon { display:none; }

.jstree-brackets .jstree-search { font-style:italic; }

.jstree-brackets .jstree-no-icons .jstree-checkbox { display:inline-block; }
.jstree-brackets .jstree-no-checkboxes .jstree-checkbox { display:none !important; }
.jstree-brackets .jstree-checked > a > .jstree-checkbox { background-position:-38px -19px; }
.jstree-brackets .jstree-unchecked > a > .jstree-checkbox { background-position:-2px -19px; }
.jstree-brackets .jstree-undetermined > a > .jstree-checkbox { background-position:-20px -19px; }
.jstree-brackets .jstree-checked > a > .jstree-checkbox:hover { background-position:-38px -37px; }
.jstree-brackets .jstree-unchecked > a > .jstree-checkbox:hover { background-position:-2px -37px; }
.jstree-brackets .jstree-undetermined > a > .jstree-checkbox:hover { background-position:-20px -37px; }

#vakata-dragged.jstree-brackets ins { background:transparent !important; }
#vakata-dragged.jstree-brackets .jstree-ok { background:url("images/jsTreeSprites.svg") -2px -53px no-repeat !important; }
#vakata-dragged.jstree-brackets .jstree-invalid { background:url("images/jsTreeSprites.svg") -18px -53px no-repeat !important; }
#jstree-marker.jstree-brackets { background:url("images/jsTreeSprites.svg") -41px -57px no-repeat !important; text-indent:-100px; }

.jstree-brackets a.jstree-search { color:aqua; }
.jstree-brackets .jstree-locked a { color:silver; cursor:default; }

.jstree-brackets .jstree-rename-input {
    background: @bc-black;
    border: 1px solid @bc-black;
    border-radius: 2px;
    box-shadow: @tc-call-to-action-down-shadow;
    color: @bc-white;
    font-style: normal;
    font-weight: 400;
    left: 3px !important;
    padding: 0;
    position: absolute;
    top: 2px;
    width: 150px;
}

.jstree-brackets .jstree-rename-input:focus {
    border: 1px solid @tc-gray-component-focused-border;
    box-shadow: @tc-input-glow;
    outline: none;
}

#vakata-contextmenu.jstree-brackets-context,
#vakata-contextmenu.jstree-brackets-context li ul { background:#f0f0f0; border:1px solid #979797; -moz-box-shadow: 1px 1px 2px #999; -webkit-box-shadow: 1px 1px 2px #999; box-shadow: 1px 1px 2px #999; }
#vakata-contextmenu.jstree-brackets-context li { }
#vakata-contextmenu.jstree-brackets-context a { color:black; }
#vakata-contextmenu.jstree-brackets-context a:hover,
#vakata-contextmenu.jstree-brackets-context .vakata-hover > a { padding:0 5px; background:#e8eff7; border:1px solid #aecff7; color:black; -moz-border-radius:2px; -webkit-border-radius:2px; border-radius:2px; }
#vakata-contextmenu.jstree-brackets-context li.jstree-contextmenu-disabled a,
#vakata-contextmenu.jstree-brackets-context li.jstree-contextmenu-disabled a:hover { color:silver; background:transparent; border:0; padding:1px 4px; }
#vakata-contextmenu.jstree-brackets-context li.vakata-separator { background:white; border-top:1px solid #e0e0e0; margin:0; }
#vakata-contextmenu.jstree-brackets-context li ul { margin-left:-4px; }


/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2018 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

var CanvasPool = require('../../display/canvas/CanvasPool');
var Class = require('../../utils/Class');
var Components = require('../components');
var GameObject = require('../GameObject');
var GetPowerOfTwo = require('../../math/pow2/GetPowerOfTwo');
var TileSpriteRender = require('./TileSpriteRender');

/**
 * @classdesc
 * [description]
 *
 * @class TileSprite
 * @extends Phaser.GameObjects.GameObject
 * @memberOf Phaser.GameObjects
 * @constructor
 * @since 3.0.0
 *
 * @extends Phaser.GameObjects.Components.Alpha
 * @extends Phaser.GameObjects.Components.BlendMode
 * @extends Phaser.GameObjects.Components.Depth
 * @extends Phaser.GameObjects.Components.Flip
 * @extends Phaser.GameObjects.Components.GetBounds
 * @extends Phaser.GameObjects.Components.Origin
 * @extends Phaser.GameObjects.Components.Pipeline
 * @extends Phaser.GameObjects.Components.ScaleMode
 * @extends Phaser.GameObjects.Components.ScrollFactor
 * @extends Phaser.GameObjects.Components.Size
 * @extends Phaser.GameObjects.Components.Texture
 * @extends Phaser.GameObjects.Components.Tint
 * @extends Phaser.GameObjects.Components.Transform
 * @extends Phaser.GameObjects.Components.Visible
 *
 * @param {Phaser.Scene} scene - The Scene to which this Game Object belongs. A Game Object can only belong to one Scene at a time.
 * @param {number} x - The horizontal position of this Game Object in the world.
 * @param {number} y - The vertical position of this Game Object in the world.
 * @param {number} width - The width of the Game Object.
 * @param {number} height - The height of the Game Object.
 * @param {string} texture - The key of the Texture this Game Object will use to render with, as stored in the Texture Manager.
 * @param {string|integer} [frame] - An optional frame from the Texture this Game Object is rendering with.
 */
var TileSprite = new Class({

    Extends: GameObject,

    Mixins: [
        Components.Alpha,
        Components.BlendMode,
        Components.Depth,
        Components.Flip,
        Components.GetBounds,
        Components.Origin,
        Components.Pipeline,
        Components.ScaleMode,
        Components.ScrollFactor,
        Components.Size,
        Components.Texture,
        Components.Tint,
        Components.Transform,
        Components.Visible,
        TileSpriteRender
    ],

    initialize:

    function TileSprite (scene, x, y, width, height, texture, frame)
    {
        var renderer = scene.sys.game.renderer;

        GameObject.call(this, scene, 'TileSprite');

        /**
         * [description]
         *
         * @name Phaser.GameObjects.TileSprite#tilePositionX
         * @type {number}
         * @default 0
         * @since 3.0.0
         */
        this.tilePositionX = 0;

        /**
         * [description]
         *
         * @name Phaser.GameObjects.TileSprite#tilePositionY
         * @type {number}
         * @default 0
         * @since 3.0.0
         */
        this.tilePositionY = 0;

        /**
         * [description]
         *
         * @name Phaser.GameObjects.TileSprite#dirty
         * @type {boolean}
         * @default true
         * @since 3.0.0
         */
        this.dirty = true;

        /**
         * [description]
         *
         * @name Phaser.GameObjects.TileSprite#tileTexture
         * @type {?[type]}
         * @default null
         * @since 3.0.0
         */
        this.tileTexture = null;

        /**
         * [description]
         *
         * @name Phaser.GameObjects.TileSprite#renderer
         * @type {[type]}
         * @since 3.0.0
         */
        this.renderer = renderer;

        this.setTexture(texture, frame);
        this.setPosition(x, y);
        this.setSize(width, height);
        this.setOriginFromFrame();
        this.initPipeline('TextureTintPipeline');

        /**
         * The next power of two value from the width of the Frame.
         *
         * @name Phaser.GameObjects.TileSprite#potWidth
         * @type {integer}
         * @since 3.0.0
         */
        this.potWidth = GetPowerOfTwo(this.frame.width);

        /**
         * The next power of two value from the height of the Frame.
         *
         * @name Phaser.GameObjects.TileSprite#potHeight
         * @type {integer}
         * @since 3.0.0
         */
        this.potHeight = GetPowerOfTwo(this.frame.height);

        /**
         * [description]
         *
         * @name Phaser.GameObjects.TileSprite#canvasPattern
         * @type {?CanvasPattern}
         * @default null
         * @since 3.0.0
         */
        this.canvasPattern = null;

        /**
         * [description]
         *
         * @name Phaser.GameObjects.TileSprite#canvasBuffer
         * @type {HTMLCanvasElement}
         * @since 3.0.0
         */
        this.canvasBuffer = CanvasPool.create2D(null, this.potWidth, this.potHeight);

        /**
         * [description]
         *
         * @name Phaser.GameObjects.TileSprite#canvasBufferCtx
         * @type {CanvasRenderingContext2D}
         * @since 3.0.0
         */
        this.canvasBufferCtx = this.canvasBuffer.getContext('2d');

        this.updateTileTexture();

        scene.sys.game.renderer.onContextRestored(function (renderer)
        {
            var gl = renderer.gl;
            this.tileTexture = null;
            this.dirty = true;
            this.tileTexture = renderer.createTexture2D(0, gl.LINEAR, gl.LINEAR, gl.REPEAT, gl.REPEAT, gl.RGBA, this.canvasBuffer, this.potWidth, this.potHeight);
        }, this);
    },

    /**
     * [description]
     *
     * @method Phaser.GameObjects.TileSprite#updateTileTexture
     * @since 3.0.0
     */
    updateTileTexture: function ()
    {
        if (!this.dirty)
        {
            return;
        }

        this.canvasBufferCtx.drawImage(
            this.frame.source.image,
            this.frame.cutX, this.frame.cutY,
            this.frame.cutWidth, this.frame.cutHeight,
            0, 0,
            this.potWidth, this.potHeight
        );

        if (this.renderer.gl)
        {
            this.tileTexture = this.renderer.canvasToTexture(this.canvasBuffer, this.tileTexture, (this.tileTexture === null), this.scaleMode);
        }
        else
        {
            this.canvasPattern = this.canvasBufferCtx.createPattern(this.canvasBuffer, 'repeat');
        }

        this.dirty = false;
    },

    /**
     * [description]
     *
     * @method Phaser.GameObjects.TileSprite#destroy
     * @since 3.0.0
     */
    destroy: function ()
    {
        if (this.renderer)
        {
            this.renderer.deleteTexture(this.tileTexture);
        }

        CanvasPool.remove(this.canvasBuffer);

        this.canvasPattern = null;
        this.canvasBufferCtx = null;
        this.canvasBuffer = null;

        this.renderer = null;
        this.visible = false;
    }

});

module.exports = TileSprite;


/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2018 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

/**
 * [description]
 *
 * @function Phaser.Geom.Point.Equals
 * @since 3.0.0
 *
 * @param {Phaser.Geom.Point} point - [description]
 * @param {Phaser.Geom.Point} toCompare - [description]
 *
 * @return {boolean} [description]
 */
var Equals = function (point, toCompare)
{
    return (point.x === toCompare.x && point.y === toCompare.y);
};

module.exports = Equals;


/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2018 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

var BuildGameObject = require('../BuildGameObject');
var BuildGameObjectAnimation = require('../BuildGameObjectAnimation');
var GameObjectCreator = require('../GameObjectCreator');
var GetAdvancedValue = require('../../utils/object/GetAdvancedValue');
var Sprite = require('./Sprite');

/**
 * Creates a new Sprite Game Object and returns it.
 *
 * Note: This method will only be available if the Sprite Game Object has been built into Phaser.
 *
 * @method Phaser.GameObjects.GameObjectCreator#sprite
 * @since 3.0.0
 *
 * @param {object} config - [description]
 *
 * @return {Phaser.GameObjects.Sprite} The Game Object that was created.
 */
GameObjectCreator.register('sprite', function (config)
{
    var key = GetAdvancedValue(config, 'key', null);
    var frame = GetAdvancedValue(config, 'frame', null);

    var sprite = new Sprite(this.scene, 0, 0, key, frame);

    BuildGameObject(this.scene, sprite, config);

    //  Sprite specific config options:

    BuildGameObjectAnimation(sprite, config);

    //  Physics, Input, etc to follow ...

    return sprite;
});

//  When registering a factory function 'this' refers to the GameObjectCreator context.


/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2018 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

/**
 * Searches the entire map layer for the first tile matching the given index, then returns that Tile
 * object. If no match is found, it returns null. The search starts from the top-left tile and
 * continues horizontally until it hits the end of the row, then it drops down to the next column.
 * If the reverse boolean is true, it scans starting from the bottom-right corner traveling up to
 * the top-left.
 *
 * @function Phaser.Tilemaps.Components.FindByIndex
 * @since 3.0.0
 *
 * @param {integer} index - The tile index value to search for.
 * @param {integer} [skip=0] - The number of times to skip a matching tile before returning.
 * @param {boolean} [reverse=false] - If true it will scan the layer in reverse, starting at the
 * bottom-right. Otherwise it scans from the top-left.
 * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon.
 *
 * @return {Phaser.Tilemaps.Tile|null} The first (or n skipped) tile with the matching index.
 */
var FindByIndex = function (findIndex, skip, reverse, layer)
{
    if (skip === undefined) { skip = 0; }
    if (reverse === undefined) { reverse = false; }

    var count = 0;
    var tx;
    var ty;
    var tile;

    if (reverse)
    {
        for (ty = layer.height - 1; ty >= 0; ty--)
        {
            for (tx = layer.width - 1; tx >= 0; tx--)
            {
                tile = layer.data[ty][tx];
                if (tile && tile.index === findIndex)
                {
                    if (count === skip)
                    {
                        return tile;
                    }
                    else
                    {
                        count += 1;
                    }
                }
            }
        }
    }
    else
    {
        for (ty = 0; ty < layer.height; ty++)
        {
            for (tx = 0; tx < layer.width; tx++)
            {
                tile = layer.data[ty][tx];
                if (tile && tile.index === findIndex)
                {
                    if (count === skip)
                    {
                        return tile;
                    }
                    else
                    {
                        count += 1;
                    }
                }
            }
        }
    }

    return null;
};

module.exports = FindByIndex;


*/
updateTileTexture: function ()
{
if (!this.dirty)
{
return;
}

if (!this.dirty && this.oldFrame == this.frame)