Authors ordered by first contribution
A list of current team members is available at http://jqueryui.com/about

Paul Bakaus <paul.bakaus@googlemail.com>
Richard Worth <rdworth@gmail.com>
Yehuda Katz <wycats@gmail.com>
Sean Catchpole <littlecooldude@gmail.com>
John Resig <jeresig@gmail.com>
Tane Piper <tane@tanepiper.com>
Dmitri Gaskin <dmitrig01@gmail.com>
Klaus Hartl <klaus.hartl@googlemail.com>
Stefan Petre <stefan.petre@gmail.com>
Gilles van den Hoven <gilles@webunity.nl>
Micheil Smith <micheil@brandedcode.com>
Jörn Zaefferer <joern.zaefferer@gmail.com>
Marc Grabanski <m@marcgrabanski.com>
Keith Wood <kbwood.au@gmail.com>
Brandon Aaron <brandon.aaron@gmail.com>
Scott González <scott.gonzalez@gmail.com>
Eduardo Lundgren <eduardolundgren@gmail.com>
Aaron Eisenberger <aaronchi@gmail.com>
Joan Piedra <theneojp@gmail.com>
Bruno Basto <b.basto@gmail.com>
Remy Sharp <remy@leftlogic.com>
Bohdan Ganicky <bohdan.ganicky@gmail.com>
David Bolter <david.bolter@gmail.com>
Chi Cheng <cloudream@gmail.com>
Ca-Phun Ung <pazu2k@gmail.com>
Ariel Flesler <aflesler@gmail.com>
Maggie Costello Wachs <fg.maggie@gmail.com>
Scott Jehl <scott@scottjehl.com>
Todd Parker <fg.todd@gmail.com>
Andrew Powell <powella@gmail.com>
Brant Burnett <btburnett3@gmail.com>
Douglas Neiner <doug@pixelgraphics.us>
Paul Irish <paul.irish@gmail.com>
Ralph Whitbeck <ralph.whitbeck@gmail.com>
Thibault Duplessis <thibault.duplessis@gmail.com>
Dominique Vincent <dominique.vincent@toitl.com>
Jack Hsu <jack.hsu@gmail.com>
Adam Sontag <ajpiano@ajpiano.com>
Carl Fürstenberg <carl@excito.com>
Kevin Dalman <development@allpro.net>
Alberto Fernández Capel <afcapel@gmail.com>
Jacek Jędrzejewski <jacek.jedrzejewski@gmail.com>
Ting Kuei <ting@kuei.com>
Samuel Cormier-Iijima <sam@chide.it>
Jon Palmer <jonspalmer@gmail.com>
Ben Hollis <bhollis@amazon.com>
Justin MacCarthy <Justin@Rubystars.biz>
Eyal Kobrigo <kobrigo@hotmail.com>
Tiago Freire <tiago.freire@gmail.com>
Diego Tres <diegotres@gmail.com>
Holger Rüprich <holger@rueprich.de>
Ziling Zhao <zizhao@cisco.com>
Mike Alsup <malsup@gmail.com>
Robson Braga Araujo <robsonbraga@gmail.com>
Pierre-Henri Ausseil <ph.ausseil@gmail.com>
Christopher McCulloh <cmcculloh@gmail.com>
Andrew Newcomb <ext.github@preceptsoftware.co.uk>
Lim Chee Aun <cheeaun@gmail.com>
Jorge Barreiro <yortx.barry@gmail.com>
Daniel Steigerwald <daniel@steigerwald.cz>
John Firebaugh <john_firebaugh@bigfix.com>
John Enters <github@darkdark.net>
Andrey Kapitcyn <ru.m157y@gmail.com>
Dmitry Petrov <dpetroff@gmail.com>
Eric Hynds <eric@hynds.net>
Chairat Sunthornwiphat <pipo@sixhead.com>
Josh Varner <josh.varner@gmail.com>
Stéphane Raimbault <stephane.raimbault@gmail.com>
Jay Merrifield <fracmak@gmail.com>
J. Ryan Stinnett <jryans@gmail.com>
Peter Heiberg <peter@heiberg.se>
Alex Dovenmuehle <adovenmuehle@gmail.com>
Jamie Gegerson <git@jamiegegerson.com>
Raymond Schwartz <skeetergraphics@gmail.com>
Phillip Barnes <philbar@gmail.com>
Kyle Wilkinson <kai@wikyd.org>
Khaled AlHourani <me@khaledalhourani.com>
Marian Rudzynski <mr@impaled.org>
Jean-Francois Remy <jfremy@virtuoz.com>
Doug Blood <dougblood@gmail.com>
Filippo Cavallarin <poplix@papuasia.org>
Heiko Henning <h.henning@educa.ch>
Aliaxandr Rahalevich <saksmlz@gmail.com>
Mario Visic <mario@mariovisic.com>
Xavi Ramirez <xavi.rmz@gmail.com>
Max Schnur <max.schnur@gmail.com>
Saji Nediyanchath <saji89@gmail.com>
Corey Frang <gnarf@gnarf.net>
Aaron Peterson <aaronp123@yahoo.com>
Ivan Peters <ivan@ivanpeters.com>
Mohamed Cherif Bouchelaghem <cherifbouchelaghem@yahoo.fr>
Marcos Sousa <marcos.sousa@corp.globo.com>
Michael DellaNoce <mdellanoce@mailtrust.com>
George Marshall <echosx@gmail.com>
Tobias Brunner <tobias@strongswan.org>
Martin Solli <msolli@gmail.com>
David Petersen <public@petersendidit.com>
Dan Heberden <danheberden@gmail.com>
William Kevin Manire <williamkmanire@gmail.com>
Gilmore Davidson <gilmoreorless@gmail.com>
Michael Wu <michaelmwu@gmail.com>
Adam Parod <mystic414@gmail.com>
Guillaume Gautreau <guillaume+github@ghusse.com>
Marcel Toele <EleotleCram@gmail.com>
Dan Streetman <ddstreet@ieee.org>
Matt Hoskins <furlined@cat-basket.org>
Giovanni Giacobbi <giovanni@giacobbi.net>
Kyle Florence <kyle.florence@gmail.com>
Pavol Hluchý <lopo@losys.sk>
Hans Hillen <hans.hillen@gmail.com>
Mark Johnson <virgofx@live.com>
Trey Hunner <treyhunner@gmail.com>
Shane Whittet <whittet@gmail.com>
Edward Faulkner <ef@alum.mit.edu>
Adam Baratz <adam.baratz@gmail.com>
Kato Kazuyoshi <kato.kazuyoshi@gmail.com>
Eike Send <eike.send@gmail.com>
Kris Borchers <kris.borchers@gmail.com>
Eddie Monge <eddie@eddiemonge.com>
Israel Tsadok <itsadok@gmail.com>
Carson McDonald <carson@ioncannon.net>
Jason Davies <jason@jasondavies.com>
Garrison Locke <gplocke@gmail.com>
David Murdoch <musicisair@yahoo.com>
Ben Boyle <benjamins.boyle@gmail.com>
Jesse Baird <jebaird@gmail.com>
Jonathan Vingiano <jvingiano@gmail.com>
Dylan Just <dev@ephox.com>
Tomy Kaira <tomykaira@gmail.com>
Glenn Goodrich <glenn.goodrich@gmail.com>
Ashek Elahi <mail.ashek@gmail.com>
Ryan Neufeld <ryan@neufeldmail.com>
Marc Neuwirth <marc.neuwirth@gmail.com>
Philip Graham <philip.robert.graham@gmail.com>
Benjamin Sterling <benjamin.sterling@kenzomedia.com>
Wesley Walser <wwalser@atlassian.com>
Kouhei Sutou <kou@clear-code.com>
Karl Kirch <karl.ctr.kirch@faa.gov>
Chris Kelly <ckdake@ckdake.com>
Jay Oster <jay@loyalize.com>
Alex Polomoshnov <alex.polomoshnov@gmail.com>
David Leal <dgleal@gmail.com>
igor milla <igor.fsp.milla@gmail.com>
Dave Methvin <dave.methvin@gmail.com>
Florian Gutmann <blackfeet@gmx.at>
Marwan Al Jubeh <marwan.aljubeh@gmail.com>
Milan Broum <midlis@googlemail.com>
Sebastian Sauer <info@dynpages.de>
Gaëtan Muller <m.gaetan89@gmail.com>
Michel Weimerskirch <michel@weimerskirch.net>
William Griffiths <william@ycymro.com>
Stojce Slavkovski <stojce@gmail.com>
David Soms <david.soms@gmail.com>
David De Sloovere <david.desloovere@hotmail.com>
Michael P. Jung <michael.jung@terreon.de>
Shannon Pekary <spekary@gmail.com>
Matthew Hutton <meh@corefiling.co.uk>
James Khoury <james@jameskhoury.com>
Rob Loach <robloach@gmail.com>
Alberto Monteiro <betimbrasil@gmail.com>
Alex Rhea <alex.rhea@gmail.com>
Krzysztof Rosiński <rozwell69@gmail.com>
Ryan Olton <oltonr@gmail.com>
Genie <386@mail.com>
Rick Waldron <waldron.rick@gmail.com>
Ian Simpson <spoonlikesham@gmail.com>
Lev Kitsis <spam4lev@gmail.com>
TJ VanToll <tj.vantoll@gmail.com>
Justin Domnitz <jdomnitz@gmail.com>
Douglas Cerna <replaceafill@system76.(none)>
Bert ter Heide <bertjh@hotmail.com>
Jasvir Nagra <jasvir@gmail.com>
Petr Hromadko <yuriy@tokyoscale.com>
Harri Kilpiö <harri.kilpio@gmail.com>
Lado Lomidze <lado.lomidze@gmail.com>
Amir E. Aharoni <amir.aharoni@mail.huji.ac.il>
Simon Sattes <simon.sattes@gmail.com>
Jo Liss <joliss42@gmail.com>
Guntupalli Karunakar <karunakarg@yahoo.com>
Shahyar Ghobadpour <shahyar@gmail.com>
Lukasz Lipinski <uzza17@gmail.com>
Timo Tijhof <krinklemail@gmail.com>
Jason Moon <jmoon@socialcast.com>
Martin Frost <martinf55@hotmail.com>
Eneko Illarramendi <eneko@illarra.com>
EungJun Yi <semtlenori@gmail.com>


* @return None. This is an asynchronous call that sends all return information to the callback.

NativeFileSystem.Entry.prototype.remove = function (successCallback, errorCallback) {

brackets.fs.unlink(this.fullPath, function (err) {

keep keep keep replace replace keep keep keep keep

brackets.fs.moveToTrash(this.fullPath, function (err) {

/*
 * 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, browser: true, nomen: true, indent: 4, maxerr: 50 */
/*global define: false, describe: false, it: false, xit: false, expect: false, beforeEach: false, afterEach: false, waitsFor: false, runs: false, $: false, HTMLElement: false */

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

    var MultiRangeInlineEditor  = require("editor/MultiRangeInlineEditor").MultiRangeInlineEditor,
        InlineTextEditor        = require("editor/InlineTextEditor").InlineTextEditor,
        InlineWidget            = require("editor/InlineWidget").InlineWidget,
        Editor                  = require("editor/Editor").Editor,
        EditorManager           = require("editor/EditorManager"),
        SpecRunnerUtils         = require("spec/SpecRunnerUtils");

    describe("MultiRangeInlineEditor", function () {

        var inlineEditor,
            $editorHolder,
            hostEditor,
            doc;

        beforeEach(function () {
            // create dummy Document and Editor
            var mocks = SpecRunnerUtils.createMockEditor("hostEditor", "");
            doc = mocks.doc;
            hostEditor = mocks.editor;
        });

        afterEach(function () {
            SpecRunnerUtils.destroyMockEditor(doc);
            hostEditor = null;
        });

        it("should initialize to a default state", function () {
            inlineEditor = new MultiRangeInlineEditor([]);

            expect(inlineEditor instanceof InlineTextEditor).toBe(true);
            expect(inlineEditor instanceof InlineWidget).toBe(true);
            expect(inlineEditor.editors.length).toBe(0);
            expect(inlineEditor.htmlContent instanceof HTMLElement).toBe(true);
            expect(inlineEditor.height).toBe(0);
            expect(inlineEditor.id).toBeNull();
            expect(inlineEditor.hostEditor).toBeNull();
        });

        it("should load a single rule and initialize htmlContent and editor", function () {
            var inlineDoc = SpecRunnerUtils.createMockDocument("inlineDoc\nstartLine\nendLine\n");
            var mockRange = {
                document: inlineDoc,
                lineStart: 1,
                lineEnd: 2
            };

            inlineEditor = new MultiRangeInlineEditor([mockRange]);
            inlineEditor.load(hostEditor);

            expect(inlineEditor.editors.length).toBe(1);
            expect(inlineEditor.editors[0].document).toBe(inlineDoc);
        });

        it("should contain a rule list widget displaying info for each rule", function () {
            var inlineDoc = SpecRunnerUtils.createMockDocument("div{}\n.foo{}\n");

            var mockRanges = [
                {
                    document: inlineDoc,
                    name: "div",
                    lineStart: 0,
                    lineEnd: 0
                },
                {
                    document: inlineDoc,
                    name: ".foo",
                    lineStart: 1,
                    lineEnd: 1
                }
            ];

            inlineEditor = new MultiRangeInlineEditor(mockRanges);
            inlineEditor.load(hostEditor);

            var $ruleListItems = $(inlineEditor.htmlContent).find("li");
            expect($($ruleListItems.get(0)).text()).toBe("div _unitTestDummyFile_.js : 1");
            expect($($ruleListItems.get(1)).text()).toBe(".foo _unitTestDummyFile_.js : 2");
        });

        it("should change selection to the next rule", function () {
            var inlineDoc = SpecRunnerUtils.createMockDocument("div{}\n.foo{}\n");

            var mockRanges = [
                {
                    document: inlineDoc,
                    name: "div",
                    lineStart: 0,
                    lineEnd: 0
                },
                {
                    document: inlineDoc,
                    name: ".foo",
                    lineStart: 1,
                    lineEnd: 1
                }
            ];

            inlineEditor = new MultiRangeInlineEditor(mockRanges);
            inlineEditor.load(hostEditor);
            inlineEditor._selectNextRange();

            var $selection = $(inlineEditor.htmlContent).find(".selection");
            var $ruleListItems = $(inlineEditor.htmlContent).find("li");
            expect($selection.position().top).toBe($($ruleListItems.get(0)).position().top);
        });

        it("should change selection to the previous rule", function () {
            var inlineDoc = SpecRunnerUtils.createMockDocument("div{}\n.foo{}\n");

            var mockRanges = [
                {
                    document: inlineDoc,
                    name: "div",
                    lineStart: 0,
                    lineEnd: 0
                },
                {
                    document: inlineDoc,
                    name: ".foo",
                    lineStart: 1,
                    lineEnd: 1
                }
            ];

            inlineEditor = new MultiRangeInlineEditor(mockRanges);
            inlineEditor.load(hostEditor);

            // select .foo
            inlineEditor.setSelectedIndex(1);

            // verify selection moves
            var $selection = $(inlineEditor.htmlContent).find(".selection");
            var $ruleListItems = $(inlineEditor.htmlContent).find("li");
            expect($selection.position().top).toBe($($ruleListItems.get(1)).position().top);

            // select div
            inlineEditor._selectPreviousRange();

            // verify selection moves again
            expect($selection.position().top).toBe($($ruleListItems.get(0)).position().top);
        });

        function expectResultItemToEqual(resultItem, mockRange) {
            expect(resultItem.name).toBe(mockRange.name);
            expect(resultItem.textRange.startLine).toBe(mockRange.lineStart);
            expect(resultItem.textRange.endLine).toBe(mockRange.lineEnd);
        }

        it("should retreive all rules", function () {
            var inlineDoc = SpecRunnerUtils.createMockDocument("div{}\n.foo{}\n");
            var mockRanges = [
                {
                    document: inlineDoc,
                    name: "div",
                    lineStart: 0,
                    lineEnd: 0
                },
                {
                    document: inlineDoc,
                    name: ".foo",
                    lineStart: 1,
                    lineEnd: 1
                }
            ];

            inlineEditor = new MultiRangeInlineEditor(mockRanges);

            expect(inlineEditor._getRanges().length).toEqual(mockRanges.length);
            expectResultItemToEqual(inlineEditor._getRanges()[0], mockRanges[0]);
            expectResultItemToEqual(inlineEditor._getRanges()[1], mockRanges[1]);
        });

        it("should retreive the selected rule", function () {
            var inlineDoc = SpecRunnerUtils.createMockDocument("div{}\n.foo{}\n");

            var mockRanges = [
                {
                    document: inlineDoc,
                    name: "div",
                    lineStart: 0,
                    lineEnd: 0
                },
                {
                    document: inlineDoc,
                    name: ".foo",
                    lineStart: 1,
                    lineEnd: 1
                }
            ];

            inlineEditor = new MultiRangeInlineEditor(mockRanges);
            inlineEditor.load(hostEditor);

            // "div" rule should be selected by default
            expectResultItemToEqual(inlineEditor._getSelectedRange(), mockRanges[0]);

            // select ".foo" rule - should be next
            inlineEditor._selectNextRange();
            expectResultItemToEqual(inlineEditor._getSelectedRange(), mockRanges[1]);
        });

        it("should close and return to the host editor", function () {
            var inlineDoc = SpecRunnerUtils.createMockDocument("div{}\n.foo{}\n");

            var mockRanges = [
                {
                    document: inlineDoc,
                    name: "div",
                    lineStart: 0,
                    lineEnd: 0
                }
            ];

            inlineEditor = new MultiRangeInlineEditor(mockRanges);
            inlineEditor.load(hostEditor);

            // add widget directly, bypass _openInlineWidget
            hostEditor.addInlineWidget({line: 0, ch: 0}, inlineEditor);

            // verify it was added
            expect(hostEditor.hasFocus()).toBe(false);
            expect(hostEditor.getInlineWidgets().length).toBe(1);

            // close the inline editor directly, should call EditorManager and removeInlineWidget
            inlineEditor.close();

            // verify no editors
            expect(hostEditor.getInlineWidgets().length).toBe(0);
            expect(hostEditor.hasFocus()).toBe(true);
        });

    });
});


This directory contains extensions that should be disabled by default, but
that we want to add to the repo. This might include things like examples and
test cases.

(README also serves as a dummy file so this directory can be added to git.)


"NOT_READABLE_ERR"                  : "The file could not be read.",

"NO_MODIFICATION_ALLOWED_ERR"       : "The target directory cannot be modified.",

"NO_MODIFICATION_ALLOWED_ERR_FILE"  : "The permissions do not allow you to make modifications.",

"FILE_EXISTS_ERR"                   : "The file already exists.",

"ERROR_LOADING_PROJECT"             : "Error loading project",

"OPEN_DIALOG_ERROR"                 : "An error occurred when showing the open file dialog. (error {0})",

keep keep keep replace keep keep keep keep

"FILE_EXISTS_ERR"                   : "The file or directory already exists.",

/*
 * 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, InvalidateStateError, window */

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

    //define FileError as currently ONLY Chrome implements the File API W3C Working Draft
    window.FileError = window.FileError || {
        NOT_FOUND_ERR: 1,
        SECURITY_ERR: 2,
        ABORT_ERR: 3,
        NOT_READABLE_ERR: 4,
        ENCODING_ERR: 5,
        NO_MODIFICATION_ALLOWED_ERR: 6,
        INVALID_STATE_ERR: 7,
        SYNTAX_ERR: 8,
        INVALID_MODIFICATION_ERR: 9,
        QUOTA_EXCEEDED_ERR: 10,
        TYPE_MISMATCH_ERR: 11,
        PATH_EXISTS_ERR: 12
    };

    var Async = require("utils/Async");

    /*
     * Generally NativeFileSystem mimics the File API working draft
     * http://www.w3.org/TR/file-system-api/. The w3 entry point
     * requestFileSystem is replaced with our own requestNativeFileSystem.
     *
     * The current implementation is incomplete and noteably does not
     * support the Blob data type and synchronous APIs. DirectoryEntry
     * and FileEntry read/write capabilities are mostly implemented, but
     * delete is not. File writing is limited to UTF-8 text.
     */
    var NativeFileSystem = {

        /**
         * Amount of time we wait for async calls to return (in milliseconds)
         * Not all async calls are wrapped with something that times out and
         * calls the error callback. Timeouts are not specified in the W3C spec.
         * @const
         * @type {number}
         */
        ASYNC_TIMEOUT: 2000,

        /** showOpenDialog
         *
         * @param {bool} allowMultipleSelection
         * @param {bool} chooseDirectories
         * @param {string} title
         * @param {string} initialPath
         * @param {Array.<string>} fileTypes
         * @param {!function(Array.<string>)} successCallback
         * @param {!function(number)} errorCallback (TODO #2057: should this pass a FileError?)
         * @constructor
         */
        showOpenDialog: function (allowMultipleSelection,
                                  chooseDirectories,
                                  title,
                                  initialPath,
                                  fileTypes,
                                  successCallback,
                                  errorCallback) {
            if (!successCallback) {
                return;
            }

            var files = brackets.fs.showOpenDialog(
                allowMultipleSelection,
                chooseDirectories,
                title,
                initialPath,
                fileTypes,
                function (err, data) {
                    if (!err) {
                        successCallback(data);
                    } else if (errorCallback) {
                        errorCallback(NativeFileSystem._nativeToFileError(err));
                    }
                }
            );
        },

        /** requestNativeFileSystem
         *
         * @param {!string} path
         * @param {!function(DirectoryEntry)} successCallback
         * @param {!function(number)} errorCallback (TODO #2057: should pass a FileError)
         */
        requestNativeFileSystem: function (path, successCallback, errorCallback) {
            brackets.fs.stat(path, function (err, data) {
                if (!err) {
                    // FIXME (issue #247): return a NativeFileSystem object
                    var root = new NativeFileSystem.DirectoryEntry(path);
                    successCallback(root);
                } else if (errorCallback) {
                    errorCallback(NativeFileSystem._nativeToFileError(err));
                }
            });
        },

        /**
         * Converts a brackets.fs.ERR_* error code to a FileError.* error code
         * @param {number} nativeErr
         * @return {number}
         */
        _nativeToFileError: function (nativeErr) {
            var error;

            switch (nativeErr) {
                // We map ERR_UNKNOWN and ERR_INVALID_PARAMS to SECURITY_ERR,
                // since there aren't specific mappings for these.
            case brackets.fs.ERR_UNKNOWN:
            case brackets.fs.ERR_INVALID_PARAMS:
                error = FileError.SECURITY_ERR;
                break;
            case brackets.fs.ERR_NOT_FOUND:
                error = FileError.NOT_FOUND_ERR;
                break;
            case brackets.fs.ERR_CANT_READ:
                error = FileError.NOT_READABLE_ERR;
                break;
            // It might seem like you should use FileError.ENCODING_ERR for this,
            // but according to the spec that's for malformed URLs.
            case brackets.fs.ERR_UNSUPPORTED_ENCODING:
                error = FileError.SECURITY_ERR;
                break;
            case brackets.fs.ERR_CANT_WRITE:
                error = FileError.NO_MODIFICATION_ALLOWED_ERR;
                break;
            case brackets.fs.ERR_OUT_OF_SPACE:
                error = FileError.QUOTA_EXCEEDED_ERR;
                break;
            case brackets.fs.PATH_EXISTS_ERR:
                error = FileError.PATH_EXISTS_ERR;
                break;
            default:
                // The HTML file spec says SECURITY_ERR is a catch-all to be used in situations
                // not covered by other error codes.
                error = FileError.SECURITY_ERR;
            }
            return new NativeFileSystem.FileError(error);
        }
    };

    /** class: Encodings
     *
     * Static class that contains constants for file
     * encoding types.
     */
    NativeFileSystem.Encodings = {};
    NativeFileSystem.Encodings.UTF8 = "UTF-8";
    NativeFileSystem.Encodings.UTF16 = "UTF-16";

    /** class: _FSEncodings
     *
     * Internal static class that contains constants for file
     * encoding types to be used by internal file system
     * implimentation.
    */
    NativeFileSystem._FSEncodings = {};
    NativeFileSystem._FSEncodings.UTF8 = "utf8";
    NativeFileSystem._FSEncodings.UTF16 = "utf16";

    /**
     * Converts an IANA encoding name to internal encoding name.
     * http://www.iana.org/assignments/character-sets
     *
     * @param {String} encoding The IANA encoding string.
     */
    NativeFileSystem.Encodings._IANAToFS = function (encoding) {
        //IANA names are case-insensitive
        encoding = encoding.toUpperCase();

        switch (encoding) {
        case (NativeFileSystem.Encodings.UTF8):
            return NativeFileSystem._FSEncodings.UTF8;
        case (NativeFileSystem.Encodings.UTF16):
            return NativeFileSystem._FSEncodings.UTF16;
        default:
            return undefined;
        }
    };

    var Encodings = NativeFileSystem.Encodings;
    var _FSEncodings = NativeFileSystem._FSEncodings;

    /** class: Entry
     *
     * @param {string} name
     * @param {string} isFile
     * @constructor
     */
    NativeFileSystem.Entry = function (fullPath, isDirectory) {
        this.isDirectory = isDirectory;
        this.isFile = !isDirectory;

        if (fullPath) {
            // add trailing "/" to directory paths
            if (isDirectory && (fullPath.charAt(fullPath.length - 1) !== "/")) {
                fullPath = fullPath.concat("/");
            }
        }

        this.fullPath = fullPath;

        this.name = null; // default if extraction fails
        if (fullPath) {
            var pathParts = fullPath.split("/");

            // Extract name from the end of the fullPath (account for trailing slash(es))
            while (!this.name && pathParts.length) {
                this.name = pathParts.pop();
            }
        }

        // TODO (issue #241)
        // http://www.w3.org/TR/2011/WD-file-system-api-20110419/#widl-Entry-filesystem
        this.filesystem = null;
    };

    NativeFileSystem.Entry.prototype.moveTo = function (parent, newName, successCallback, errorCallback) {
        // TODO (issue #241)
        // http://www.w3.org/TR/2011/WD-file-system-api-20110419/#widl-Entry-moveTo
    };

    NativeFileSystem.Entry.prototype.copyTo = function (parent, newName, successCallback, errorCallback) {
        // TODO (issue #241)
        // http://www.w3.org/TR/2011/WD-file-system-api-20110419/#widl-Entry-copyTo
    };

    NativeFileSystem.Entry.prototype.toURL = function (mimeType) {
        // TODO (issue #241)
        // http://www.w3.org/TR/2011/WD-file-system-api-20110419/#widl-Entry-toURL
    };

    /**
     * Deletes a file or directory. It is an error to attempt to delete a directory that is not empty. It is an error to attempt to delete the root directory of a filesystem.
     *
     * @param {function} successCallback A callback that is called on success.
     * @param {function} errorCallback A callback that is called when errors happen.
     *
     * @return None. This is an asynchronous call that sends all return information to the callback.
     **/
    NativeFileSystem.Entry.prototype.remove = function (successCallback, errorCallback) {
        brackets.fs.unlink(this.fullPath, function (err) {
            if(err === brackets.fs.NO_ERROR) {
                successCallback();
            } else {
                errorCallback(err);
            }
        });
    };

    NativeFileSystem.Entry.prototype.getParent = function (successCallback, errorCallback) {
        // TODO (issue #241)
        // http://www.w3.org/TR/2011/WD-file-system-api-20110419/#widl-Entry-remove
    };

    /**
     * @param {!function(Metadata)} successCallBack
     * @param {!function(number)} errorCallback (TODO #2057: should pass a FileError)
     */
    NativeFileSystem.Entry.prototype.getMetadata = function (successCallBack, errorCallback) {
        brackets.fs.stat(this.fullPath, function (err, stat) {
            if (err === brackets.fs.NO_ERROR) {
                var metadata = new NativeFileSystem.Metadata(stat.mtime);
                successCallBack(metadata);
            } else {
                errorCallback(NativeFileSystem._nativeToFileError(err));
            }
        });
    };

    /**
     * Stores information about a FileEntry
    */
    NativeFileSystem.Metadata = function (modificationTime) {
        // modificationTime is read only
        this.modificationTime = modificationTime;
    };

    /** class: FileEntry
     * This interface represents a file on a file system.
     *
     * @param {string} name
     * @constructor
     * @extends {Entry}
     */
    NativeFileSystem.FileEntry = function (name) {
        NativeFileSystem.Entry.call(this, name, false);
    };
    NativeFileSystem.FileEntry.prototype = new NativeFileSystem.Entry();

    NativeFileSystem.FileEntry.prototype.toString = function () {
        return "[FileEntry " + this.fullPath + "]";
    };

    /**
     * Creates a new FileWriter associated with the file that this FileEntry represents.
     *
     * @param {!function(FileWriter)} successCallback
     * @param {!function(number)} errorCallback (TODO #2057: should pass a FileError)
     */
    NativeFileSystem.FileEntry.prototype.createWriter = function (successCallback, errorCallback) {
        var fileEntry = this;

        // [NoInterfaceObject]
        // interface FileWriter : FileSaver
        var FileWriter = function (data) {
            NativeFileSystem.FileSaver.call(this, data);

            // FileWriter private memeber vars
            this._length = 0;
            this._position = 0;
        };

        FileWriter.prototype.length = function () {
            return this._length;
        };

        FileWriter.prototype.position = function () {
            return this._position;
        };

        // TODO (issue #241): handle Blob data instead of string
        FileWriter.prototype.write = function (data) {
            if (data === null || data === undefined) {
                throw new Error();
            }

            if (this.readyState === NativeFileSystem.FileSaver.WRITING) {
                throw new NativeFileSystem.FileException(NativeFileSystem.FileException.INVALID_STATE_ERR);
            }

            this._readyState = NativeFileSystem.FileSaver.WRITING;

            if (this.onwritestart) {
                // TODO (issue #241): progressevent
                this.onwritestart();
            }

            var self = this;

            brackets.fs.writeFile(fileEntry.fullPath, data, _FSEncodings.UTF8, function (err) {

                if ((err !== brackets.fs.NO_ERROR) && self.onerror) {
                    var fileError = NativeFileSystem._nativeToFileError(err);

                    // TODO (issue #241): set readonly FileSaver.error attribute
                    // self._error = fileError;
                    self.onerror(fileError);

                    // TODO (issue #241): partial write, update length and position
                }
                // else {
                    // TODO (issue #241): After changing data argument to Blob, use
                    // Blob.size to update position and length upon successful
                    // completion of a write.

                    // self.position = ;
                    // self.length = ;
                // }

                // DONE is set regardless of error
                self._readyState = NativeFileSystem.FileSaver.DONE;

                if (self.onwrite) {
                    // TODO (issue #241): progressevent
                    self.onwrite();
                }

                if (self.onwriteend) {
                    // TODO (issue #241): progressevent
                    self.onwriteend();
                }
            });
        };

        FileWriter.prototype.seek = function (offset) {
        };

        FileWriter.prototype.truncate = function (size) {
        };

        var fileWriter = new FileWriter();

        // initialize file length
        var result = new $.Deferred();
        brackets.fs.readFile(fileEntry.fullPath, _FSEncodings.UTF8, function (err, contents) {
            // Ignore "file not found" errors. It's okay if the file doesn't exist yet.
            if (err !== brackets.fs.ERR_NOT_FOUND) {
                fileWriter._err = err;
            }

            if (contents) {
                fileWriter._length = contents.length;
            }

            result.resolve();
        });

        result.done(function () {
            if (fileWriter._err && (errorCallback !== undefined)) {
                errorCallback(NativeFileSystem._nativeToFileError(fileWriter._err));
            } else if (successCallback !== undefined) {
                successCallback(fileWriter);
            }
        });
    };

    /**
     * Obtains the File objecte for a FileEntry object
     *
     * @param {!function(File)} successCallback
     * @param {!function(FileError)} errorCallback
     */
    NativeFileSystem.FileEntry.prototype.file = function (successCallback, errorCallback) {
        var newFile = new NativeFileSystem.File(this);
        successCallback(newFile);

        // TODO (issue #241): errorCallback
    };

    /**
     * This interface extends the FileException interface described in to add
     * several new error codes. Any errors that need to be reported synchronously,
     * including all that occur during use of the synchronous filesystem methods,
     * are reported using the FileException exception.
     *
     * @param {number} code The code attribute, on getting, must return one of the
     * constants of the FileException exception, which must be the most appropriate
     * code from the table below.
     */
    NativeFileSystem.FileException = function (code) {
        this.code = code || 0;
    };

    // FileException constants
    Object.defineProperties(
        NativeFileSystem.FileException,
        {
            NOT_FOUND_ERR:                { value: 1, writable: false },
            SECURITY_ERR:                 { value: 2, writable: false },
            ABORT_ERR:                    { value: 3, writable: false },
            NOT_READABLE_ERR:             { value: 4, writable: false },
            ENCODING_ERR:                 { value: 5, writable: false },
            NO_MODIFICATION_ALLOWED_ERR:  { value: 6, writable: false },
            INVALID_STATE_ERR:            { value: 7, writable: false },
            SYNTAX_ERR:                   { value: 8, writable: false },
            QUOTA_EXCEEDED_ERR:           { value: 10, writable: false }
        }
    );

    /**
     * This interface provides methods to monitor the asynchronous writing of blobs
     * to disk using progress events and event handler attributes.
     *
     * This interface is specified to be used within the context of the global
     * object (Window) and within Web Workers.
     *
     * @param {Blob} data
     * @constructor
     */
    NativeFileSystem.FileSaver = function (data) {
        // FileSaver private member vars
        this._data = data;
        this._readyState = NativeFileSystem.FileSaver.INIT;
        this._error = null;
    };

    // FileSaver constants
    Object.defineProperties(
        NativeFileSystem.FileSaver,
        {
            INIT:     { value: 1, writable: false },
            WRITING:  { value: 2, writable: false },
            DONE:     { value: 3, writable: false }
        }
    );

    // FileSaver methods

    /**
     *
     */
    NativeFileSystem.FileSaver.prototype.readyState = function () {
        return this._readyState;
    };

    // TODO (issue #241): http://dev.w3.org/2009/dap/file-system/file-writer.html#widl-FileSaver-abort-void
    NativeFileSystem.FileSaver.prototype.abort = function () {
        // If readyState is DONE or INIT, terminate this overall series of steps without doing anything else..
        if (this._readyState === NativeFileSystem.FileSaver.INIT || this._readyState === NativeFileSystem.FileSaver.DONE) {
            return;
        }

        // TODO (issue #241): Terminate any steps having to do with writing a file.

        // Set the error attribute to a FileError object with the code ABORT_ERR.
        this._error = new NativeFileSystem.FileError(FileError.ABORT_ERR);

        // Set readyState to DONE.
        this._readyState = NativeFileSystem.FileSaver.DONE;

        /*
        TODO (issue #241):
        Dispatch a progress event called abort
        Dispatch a progress event called writeend
        Stop dispatching any further progress events.
        Terminate this overall set of steps.
        */
    };

    /**
     * This interface represents a directory on a file system.
     *
     * @constructor
     * @param {string} name
     * @extends {Entry}
     */
    NativeFileSystem.DirectoryEntry = function (name) {
        NativeFileSystem.Entry.call(this, name, true);

        // TODO (issue #241): void removeRecursively (VoidCallback successCallback, optional ErrorCallback errorCallback);
    };
    NativeFileSystem.DirectoryEntry.prototype = new NativeFileSystem.Entry();

    NativeFileSystem.DirectoryEntry.prototype.toString = function () {
        return "[DirectoryEntry " + this.fullPath + "]";
    };

    /**
     * @param {!string} path
     * @param {!{create:?boolean, exclusive:?boolean}} options
     * @param {!function(DirectoryEntry)} successCallback
     * @param {!function(FileError|number)} errorCallback (TODO #2057: should consistently pass a FileError)
     */
    NativeFileSystem.DirectoryEntry.prototype.getDirectory = function (path, options, successCallback, errorCallback) {
        var directoryFullPath = path;

        function isRelativePath(path) {
            // If the path contains a colons it must be a full path on Windows (colons are
            // not valid path characters on mac or in URIs)
            if (path.indexOf(":") !== -1) {
                return false;
            }

            // For everyone else, absolute paths start with a "/"
            return path[0] !== "/";
        }

        // resolve relative paths relative to the DirectoryEntry
        if (isRelativePath(path)) {
            directoryFullPath = this.fullPath + path;
        }

        var createDirectoryEntry = function () {
            if (successCallback) {
                successCallback(new NativeFileSystem.DirectoryEntry(directoryFullPath));
            }
        };

        var createDirectoryError = function (err) {
            if (errorCallback) {
                errorCallback(NativeFileSystem._nativeToFileError(err));
            }
        };

        // Use stat() to check if file exists
        brackets.fs.stat(directoryFullPath, function (err, stats) {
            if ((err === brackets.fs.NO_ERROR)) {
                // NO_ERROR implies the path already exists

                // throw error if the file the path is not a directory
                if (!stats.isDirectory()) {
                    if (errorCallback) {
                        errorCallback(new NativeFileSystem.FileError(FileError.TYPE_MISMATCH_ERR));
                    }

                    return;
                }

                // throw error if the file exists but create is exclusive
                if (options.create && options.exclusive) {
                    if (errorCallback) {
                        errorCallback(new NativeFileSystem.FileError(FileError.PATH_EXISTS_ERR));
                    }

                    return;
                }

                // Create a file entry for the existing directory. If create == true,
                // a file entry is created without error.
                createDirectoryEntry();
            } else if (err === brackets.fs.ERR_NOT_FOUND) {
                // ERR_NOT_FOUND implies we write a new, empty file

                // create the file
                if (options.create) {
                    // TODO: Pass permissions. The current implementation of fs.makedir() always
                    // creates the directory with the full permissions available to the current user.
                    brackets.fs.makedir(directoryFullPath, 0, function (err) {
                        if (err) {
                            createDirectoryError(err);
                        } else {
                            createDirectoryEntry();
                        }
                    });
                    return;
                }

                // throw error if file not found and the create == false
                if (errorCallback) {
                    errorCallback(new NativeFileSystem.FileError(FileError.NOT_FOUND_ERR));
                }
            } else {
                // all other brackets.fs.stat() errors
                createDirectoryError(err);
            }
        });
    };

    NativeFileSystem.DirectoryEntry.prototype.removeRecursively = function (successCallback, errorCallback) {
        // TODO (issue #241)
        // http://www.w3.org/TR/2011/WD-file-system-api-20110419/#widl-DirectoryEntry-removeRecursively
    };

    NativeFileSystem.DirectoryEntry.prototype.createReader = function () {
        var dirReader = new NativeFileSystem.DirectoryReader();
        dirReader._directory = this;

        return dirReader;
    };

    /**
     * Creates or looks up a file.
     *
     * @param {string} path Either an absolute path or a relative path from this
     *        DirectoryEntry to the file to be looked up or created. It is an error
     *        to attempt to create a file whose immediate parent does not yet
     *        exist.
     * @param {!{create:?boolean, exclusive:?boolean}} options
     * @param {!function(FileEntry)} successCallback
     * @param {!function(FileError|number)} errorCallback  (TODO #2057: should consistently pass a FileError)
     */
    NativeFileSystem.DirectoryEntry.prototype.getFile = function (path, options, successCallback, errorCallback) {
        var fileFullPath = path;

        function isRelativePath(path) {
            // If the path contains a colons it must be a full path on Windows (colons are
            // not valid path characters on mac or in URIs)
            if (path.indexOf(":") !== -1) {
                return false;
            }

            // For everyone else, absolute paths start with a "/"
            return path[0] !== "/";
        }

        // resolve relative paths relative to the DirectoryEntry
        if (isRelativePath(path)) {
            fileFullPath = this.fullPath + path;
        }

        var createFileEntry = function () {
            if (successCallback) {
                successCallback(new NativeFileSystem.FileEntry(fileFullPath));
            }
        };

        var createFileError = function (err) {
            if (errorCallback) {
                errorCallback(NativeFileSystem._nativeToFileError(err));
            }
        };

        // Use stat() to check if file exists
        brackets.fs.stat(fileFullPath, function (err, stats) {
            if ((err === brackets.fs.NO_ERROR)) {
                // NO_ERROR implies the path already exists

                // throw error if the file the path is a directory
                if (stats.isDirectory()) {
                    if (errorCallback) {
                        errorCallback(new NativeFileSystem.FileError(FileError.TYPE_MISMATCH_ERR));
                    }

                    return;
                }

                // throw error if the file exists but create is exclusive
                if (options.create && options.exclusive) {
                    if (errorCallback) {
                        errorCallback(new NativeFileSystem.FileError(FileError.PATH_EXISTS_ERR));
                    }

                    return;
                }

                // Create a file entry for the existing file. If create == true,
                // a file entry is created without error.
                createFileEntry();
            } else if (err === brackets.fs.ERR_NOT_FOUND) {
                // ERR_NOT_FOUND implies we write a new, empty file

                // create the file
                if (options.create) {
                    brackets.fs.writeFile(fileFullPath, "", _FSEncodings.UTF8, function (err) {
                        if (err) {
                            createFileError(err);
                        } else {
                            createFileEntry();
                        }
                    });

                    return;
                }

                // throw error if file not found and the create == false
                if (errorCallback) {
                    errorCallback(new NativeFileSystem.FileError(FileError.NOT_FOUND_ERR));
                }
            } else {
                // all other brackets.fs.stat() errors
                createFileError(err);
            }
        });
    };

    /** class: DirectoryReader
     */
    NativeFileSystem.DirectoryReader = function () {

    };

    /** readEntries
     *
     * @param {!function(Array.<Entry>)} successCallback
     * @param {!function(FileError|number)} errorCallback (TODO #2057: should consistently pass a FileError)
     * @returns {Array.<Entry>}
     */
    NativeFileSystem.DirectoryReader.prototype.readEntries = function (successCallback, errorCallback) {
        var rootPath = this._directory.fullPath;
        brackets.fs.readdir(rootPath, function (err, filelist) {
            if (!err) {
                var entries = [];
                var lastError = null;

                // stat() to determine type of each entry, then populare entries array with objects
                var masterPromise = Async.doInParallel(filelist, function (filename, index) {

                    var deferred = new $.Deferred();
                    var itemFullPath = rootPath + filelist[index];

                    brackets.fs.stat(itemFullPath, function (statErr, statData) {
                        if (!statErr) {
                            if (statData.isDirectory()) {
                                entries[index] = new NativeFileSystem.DirectoryEntry(itemFullPath);
                            } else if (statData.isFile()) {
                                entries[index] = new NativeFileSystem.FileEntry(itemFullPath);
                            } else {
                                entries[index] = null;  // neither a file nor a dir, so don't include it
                            }
                            deferred.resolve();
                        } else {
                            lastError = NativeFileSystem._nativeToFileError(statErr);
                            deferred.reject(lastError);
                        }
                    });

                    return deferred.promise();
                }, true);

                // We want the error callback to get called after some timeout (in case some deferreds don't return).
                // So, we need to wrap masterPromise in another deferred that has this timeout functionality
                var timeoutWrapper = Async.withTimeout(masterPromise, NativeFileSystem.ASYNC_TIMEOUT);

                // Add the callbacks to this top-level Promise, which wraps all the individual deferred objects
                timeoutWrapper.then(
                    function () { // success
                        // The entries array may have null values if stat returned things that were
                        // neither a file nor a dir. So, we need to clean those out.
                        var cleanedEntries = [], i;
                        for (i = 0; i < entries.length; i++) {
                            if (entries[i]) {
                                cleanedEntries.push(entries[i]);
                            }
                        }
                        successCallback(cleanedEntries);
                    },
                    function (err) { // error
                        if (err === Async.ERROR_TIMEOUT) {
                            // SECURITY_ERR is the HTML5 File catch-all error, and there isn't anything
                            // more fitting for a timeout.
                            err = new NativeFileSystem.FileError(FileError.SECURITY_ERR);
                        } else {
                            err = lastError;
                        }

                        if (errorCallback) {
                            errorCallback(err);
                        }
                    }
                );

            } else { // There was an error reading the initial directory.
                errorCallback(NativeFileSystem._nativeToFileError(err));
            }
        });
    };

    /** class: FileReader
     *
     * @extends {EventTarget}
     */
    NativeFileSystem.FileReader = function () {
        // TODO (issue #241): this classes should extend EventTarget

        // states
        this.EMPTY = 0;
        this.LOADING = 1;
        this.DONE = 2;

        // readyState is read only
        this.readyState = this.EMPTY;

        // File or Blob data
        // TODO (issue #241): readonly attribute any result;
        // TODO (issue #241): readonly attribute DOMError error;

        // event handler attributes
        this.onloadstart = null;
        this.onprogress = null;
        this.onload = null;
        this.onabort = null;
        this.onerror = null;
        this.onloadend = null;
    };
    // TODO (issue #241): extend EventTarget (draft status, not implememnted in webkit)
    // NativeFileSystem.FileReader.prototype = new NativeFileSystem.EventTarget()

    NativeFileSystem.FileReader.prototype.readAsArrayBuffer = function (blob) {
        // TODO (issue #241): implement
        // http://www.w3.org/TR/2011/WD-FileAPI-20111020/#dfn-readAsArrayBuffer
    };

    NativeFileSystem.FileReader.prototype.readAsBinaryString = function (blob) {
        // TODO (issue #241): implement
        // http://www.w3.org/TR/2011/WD-FileAPI-20111020/#dfn-readAsBinaryStringAsync
    };

    NativeFileSystem.FileReader.prototype.readAsDataURL = function (blob) {
        // TODO (issue #241): implement
        // http://www.w3.org/TR/2011/WD-FileAPI-20111020/#dfn-readAsDataURL
    };

    NativeFileSystem.FileReader.prototype.abort = function () {
        // TODO (issue #241): implement
        // http://www.w3.org/TR/2011/WD-FileAPI-20111020/#dfn-abort
    };

    /** readAsText
     *
     * @param {Blob} blob
     * @param {string} encoding (IANA Encoding Name)
     */
    NativeFileSystem.FileReader.prototype.readAsText = function (blob, encoding) {
        var self = this;

        if (!encoding) {
            encoding = Encodings.UTF8;
        }

        var internalEncoding  = Encodings._IANAToFS(encoding);

        if (this.readyState === this.LOADING) {
            throw new InvalidateStateError();
        }

        this.readyState = this.LOADING;

        if (this.onloadstart) {
            this.onloadstart(); // TODO (issue #241): progressevent
        }

        brackets.fs.readFile(blob._fullPath, internalEncoding, function (err, data) {

            // TODO (issue #241): the event objects passed to these event handlers is fake and incomplete right now
            var fakeEvent = {
                loaded: 0,
                total: 0
            };

            // The target for this event is the FileReader and the data/err result is stored in the FileReader
            fakeEvent.target = self;
            self.result = data;
            self.error = NativeFileSystem._nativeToFileError(err);

            if (err) {
                self.readyState = self.DONE;
                if (self.onerror) {
                    self.onerror(fakeEvent);
                }
            } else {
                self.readyState = self.DONE;

                // TODO (issue #241): this should be the file/blob size, but we don't have code to get that yet, so for know assume a file size of 1
                // and since we read the file in one go, assume 100% after the first read
                fakeEvent.loaded = 1;
                fakeEvent.total = 1;

                if (self.onprogress) {
                    self.onprogress(fakeEvent);
                }

                // TODO (issue #241): onabort not currently supported since our native implementation doesn't support it
                // if (self.onabort)
                //    self.onabort(fakeEvent);

                if (self.onload) {
                    self.onload(fakeEvent);
                }

                if (self.onloadend) {
                    self.onloadend();
                }
            }

        });
    };

    /** class: Blob
     *
     * @constructor
     * param {Entry} entry
     */
    NativeFileSystem.Blob = function (fullPath) {
        this._fullPath = fullPath;

        // TODO (issue #241): implement, readonly
        this.size = 0;

        // TODO (issue #241): implement, readonly
        this.type = null;
    };

    NativeFileSystem.Blob.prototype.slice = function (start, end, contentType) {
        // TODO (issue #241): implement
        // http://www.w3.org/TR/2011/WD-FileAPI-20111020/#dfn-slice
    };

    /** class: File
     *
     * @constructor
     * param {Entry} entry
     * @extends {Blob}
     */
    NativeFileSystem.File = function (entry) {
        NativeFileSystem.Blob.call(this, entry.fullPath);

        // TODO (issue #241): implement, readonly
        this.name = "";

        // TODO (issue #241): implement, readonly
        this.lastModifiedDate = null;
    };

    /** class: FileError
     *
     * Implementation of HTML file API error code return class. Note that we don't
     * actually define the error codes here--we rely on the browser's built-in FileError
     * class's constants. In other words, external clients of this API should always
     * use FileError.<constant-name>, not NativeFileSystem.FileError.<constant-name>.
     *
     * @constructor
     * @param {number} code The error code to return with this FileError. Must be
     * one of the codes defined in the FileError class.
     */
    NativeFileSystem.FileError = function (code) {
        this.code = code || 0;
    };

    // Define public API
    exports.NativeFileSystem    = NativeFileSystem;
});


<!DOCTYPE html>

	<meta charset="utf-8">
	<title>jQuery UI Progressbar - Default functionality</title>
	<link rel="stylesheet" href="../../themes/base/jquery.ui.all.css">

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

Default determinate progress bar.


<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="9px" height="8px">
	<defs>
		<filter id="blur" x="-10" y="-10" width="12" height="12">
			<feGaussianBlur in="SourceGraphic" stdDeviation=".25"/>
		</filter>
	</defs>

	<polyline points="4.5,7 8,1 1,1 " filter="url(#blur)" opacity=".5" transform="translate(0, 1)"/>
	<polyline fill="#a0a0a0" points="4.5,7 8,1 1,1 "/>
</svg>


/*
 * jsTree default-rtl theme 1.0
 * Supported features: dots/no-dots, icons/no-icons, focused, loading
 * Supported plugins: ui (hovered, clicked), checkbox, contextmenu, search
 */

.jstree-default-rtl li,
.jstree-default-rtl ins { background-image:url("d.png"); background-repeat:no-repeat; background-color:transparent; }
.jstree-default-rtl li { background-position:-90px 0; background-repeat:repeat-y; }
.jstree-default-rtl li.jstree-last { background:transparent; }
.jstree-default-rtl .jstree-open > ins { background-position:-72px 0; }
.jstree-default-rtl .jstree-closed > ins { background-position:-54px 0; }
.jstree-default-rtl .jstree-leaf > ins { background-position:-36px 0; }

.jstree-default-rtl .jstree-hovered { background:#e7f4f9; border:1px solid #d8f0fa; padding:0 2px 0 1px; }
.jstree-default-rtl .jstree-clicked { background:#beebff; border:1px solid #99defd; padding:0 2px 0 1px; }
.jstree-default-rtl a .jstree-icon { background-position:-56px -19px; }
.jstree-default-rtl a.jstree-loading .jstree-icon { background:url("throbber.gif") center center no-repeat !important; }

.jstree-default-rtl.jstree-focused { background:#ffffee; }

.jstree-default-rtl .jstree-no-dots li,
.jstree-default-rtl .jstree-no-dots .jstree-leaf > ins { background:transparent; }
.jstree-default-rtl .jstree-no-dots .jstree-open > ins { background-position:-18px 0; }
.jstree-default-rtl .jstree-no-dots .jstree-closed > ins { background-position:0 0; }

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

.jstree-default-rtl .jstree-search { font-style:italic; }

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

#vakata-dragged.jstree-default-rtl ins { background:transparent !important; }
#vakata-dragged.jstree-default-rtl .jstree-ok { background:url("d.png") -2px -53px no-repeat !important; }
#vakata-dragged.jstree-default-rtl .jstree-invalid { background:url("d.png") -18px -53px no-repeat !important; }
#jstree-marker.jstree-default-rtl { background:url("d.png") -41px -57px no-repeat !important; text-indent:-100px; }

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

#vakata-contextmenu.jstree-default-rtl-context,
#vakata-contextmenu.jstree-default-rtl-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-default-rtl-context li { }
#vakata-contextmenu.jstree-default-rtl-context a { color:black; }
#vakata-contextmenu.jstree-default-rtl-context a:hover,
#vakata-contextmenu.jstree-default-rtl-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-default-rtl-context li.jstree-contextmenu-disabled a,
#vakata-contextmenu.jstree-default-rtl-context li.jstree-contextmenu-disabled a:hover { color:silver; background:transparent; border:0; padding:1px 4px; }
#vakata-contextmenu.jstree-default-rtl-context li.vakata-separator { background:white; border-top:1px solid #e0e0e0; margin:0; }
#vakata-contextmenu.jstree-default-rtl-context li ul { margin-left:-4px; }

/* IE6 BEGIN */
.jstree-default-rtl li,
.jstree-default-rtl ins,
#vakata-dragged.jstree-default-rtl .jstree-invalid,
#vakata-dragged.jstree-default-rtl .jstree-ok,
#jstree-marker.jstree-default-rtl { _background-image:url("d.gif"); }
.jstree-default-rtl .jstree-open ins { _background-position:-72px 0; }
.jstree-default-rtl .jstree-closed ins { _background-position:-54px 0; }
.jstree-default-rtl .jstree-leaf ins { _background-position:-36px 0; }
.jstree-default-rtl a ins.jstree-icon { _background-position:-56px -19px; }
#vakata-contextmenu.jstree-default-rtl-context ins { _display:none; }
#vakata-contextmenu.jstree-default-rtl-context li { _zoom:1; }
.jstree-default-rtl .jstree-undetermined a .jstree-checkbox { _background-position:-18px -19px; }
.jstree-default-rtl .jstree-checked a .jstree-checkbox { _background-position:-36px -19px; }
.jstree-default-rtl .jstree-unchecked a .jstree-checkbox { _background-position:0px -19px; }
/* IE6 END */

/* RTL part */
.jstree-default-rtl .jstree-hovered, .jstree-default-rtl .jstree-clicked { padding:0 1px 0 2px; }
.jstree-default-rtl li { background-image:url("dots.gif"); background-position: 100% 0px; }
.jstree-default-rtl .jstree-checked > a > .jstree-checkbox { background-position:-36px -19px; margin-left:2px; }
.jstree-default-rtl .jstree-unchecked > a > .jstree-checkbox { background-position:0px -19px; margin-left:2px; }
.jstree-default-rtl .jstree-undetermined > a > .jstree-checkbox { background-position:-18px -19px; margin-left:2px; }
.jstree-default-rtl .jstree-checked > a > .jstree-checkbox:hover { background-position:-36px -37px; }
.jstree-default-rtl .jstree-unchecked > a > .jstree-checkbox:hover { background-position:0px -37px; }
.jstree-default-rtl .jstree-undetermined > a > .jstree-checkbox:hover { background-position:-18px -37px; }


* Run this method to handle project menu open behaviors

// Initialize variables and listeners that depend on the HTML DOM

keep keep keep keep keep replace replace replace 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, maxerr: 50 */
/*global define */

define({
    /**
     * Errors
     */

    // General file io error strings
    "GENERIC_ERROR"                     : "(error {0})",
    "NOT_FOUND_ERR"                     : "The file could not be found.",
    "NOT_READABLE_ERR"                  : "The file could not be read.",
    "NO_MODIFICATION_ALLOWED_ERR"       : "The target directory cannot be modified.",
    "NO_MODIFICATION_ALLOWED_ERR_FILE"  : "The permissions do not allow you to make modifications.",
    "FILE_EXISTS_ERR"                   : "The file already exists.",

    // Project error strings
    "ERROR_LOADING_PROJECT"             : "Error loading project",
    "OPEN_DIALOG_ERROR"                 : "An error occurred when showing the open file dialog. (error {0})",
    "REQUEST_NATIVE_FILE_SYSTEM_ERROR"  : "An error occurred when trying to load the directory {0}. (error {1})",
    "READ_DIRECTORY_ENTRIES_ERROR"      : "An error occurred when reading the contents of the directory {0}. (error {1})",

    // File open/save error string
    "ERROR_OPENING_FILE_TITLE"          : "Error opening file",
    "ERROR_OPENING_FILE"                : "An error occurred when trying to open the file {0}. {1}",
    "ERROR_RELOADING_FILE_TITLE"        : "Error reloading changes from disk",
    "ERROR_RELOADING_FILE"              : "An error occurred when trying to reload the file {0}. {1}",
    "ERROR_SAVING_FILE_TITLE"           : "Error saving file",
    "ERROR_SAVING_FILE"                 : "An error occurred when trying to save the file {0}. {1}",
    "ERROR_RENAMING_FILE_TITLE"         : "Error renaming file",
    "ERROR_RENAMING_FILE"               : "An error occurred when trying to rename the file {0}. {1}",
    "ERROR_DELETING_FILE_TITLE"         : "Error deleting file",
    "ERROR_DELETING_FILE"               : "An error occurred when trying to delete the file {0}. {1}",
    "INVALID_FILENAME_TITLE"            : "Invalid file name",
    "INVALID_FILENAME_MESSAGE"          : "Filenames cannot contain the following characters: /?*:;{}<>\\|",
    "FILE_ALREADY_EXISTS"               : "The file {0} already exists.",
    "ERROR_CREATING_FILE_TITLE"         : "Error creating file",
    "ERROR_CREATING_FILE"               : "An error occurred when trying to create the file {0}. {1}",

    // Application error strings
    "ERROR_IN_BROWSER_TITLE"            : "Oops! {APP_NAME} doesn't run in browsers yet.",
    "ERROR_IN_BROWSER"                  : "{APP_NAME} is built in HTML, but right now it runs as a desktop app so you can use it to edit local files. Please use the application shell in the github.com/adobe/brackets-shell repo to run {APP_NAME}.",

    // FileIndexManager error string
    "ERROR_MAX_FILES_TITLE"             : "Error Indexing Files",
    "ERROR_MAX_FILES"                   : "The maximum number of files have been indexed. Actions that look up files in the index may function incorrectly.",

    // Live Development error strings
    "ERROR_LAUNCHING_BROWSER_TITLE"     : "Error launching browser",
    "ERROR_CANT_FIND_CHROME"            : "The Google Chrome browser could not be found. Please make sure it is installed.",
    "ERROR_LAUNCHING_BROWSER"           : "An error occurred when launching the browser. (error {0})",

    "LIVE_DEVELOPMENT_ERROR_TITLE"      : "Live Preview Error",
    "LIVE_DEVELOPMENT_RELAUNCH_TITLE"   : "Connecting to Browser",
    "LIVE_DEVELOPMENT_ERROR_MESSAGE"    : "In order for Live Preview to connect, Chrome needs to be relaunched with remote debugging enabled.

Would you like to relaunch Chrome and enable remote debugging?",
    "LIVE_DEV_NEED_HTML_MESSAGE"        : "Open an HTML file in order to launch live preview.",
    "LIVE_DEV_NEED_BASEURL_MESSAGE"     : "To launch live preview with a server-side file, you need to specify a Base URL for this project.",
    "LIVE_DEVELOPMENT_INFO_TITLE"       : "Welcome to Live Preview!",
    "LIVE_DEVELOPMENT_INFO_MESSAGE"     : "Live Preview connects {APP_NAME} to your browser. It launches a preview of your HTML file in the browser, then updates the preview instantly as you edit your code.

In this early version of {APP_NAME}, Live Preview only works with Google Chrome and updates live as you edit CSS files. Changes to HTML or JavaScript files are automatically reloaded when you save.

(You'll only see this message once.)",
    "LIVE_DEVELOPMENT_TROUBLESHOOTING"  : "For more information, see Troubleshooting Live Development connection errors.",

    "LIVE_DEV_STATUS_TIP_NOT_CONNECTED" : "Live Preview",
    "LIVE_DEV_STATUS_TIP_PROGRESS1"     : "Live Preview: Connecting\u2026",
    "LIVE_DEV_STATUS_TIP_PROGRESS2"     : "Live Preview: Initializing\u2026",
    "LIVE_DEV_STATUS_TIP_CONNECTED"     : "Disconnect Live Preview",
    "LIVE_DEV_STATUS_TIP_OUT_OF_SYNC"   : "Live Preview: Click to disconnect (Save file to update)",

    "SAVE_CLOSE_TITLE"                  : "Save Changes",
    "SAVE_CLOSE_MESSAGE"                : "Do you want to save the changes you made in the document {0}?",
    "SAVE_CLOSE_MULTI_MESSAGE"          : "Do you want to save your changes to the following files?",
    "EXT_MODIFIED_TITLE"                : "External Changes",
    "EXT_MODIFIED_MESSAGE"              : "{0} has been modified on disk, but also has unsaved changes in {APP_NAME}.

Which version do you want to keep?",
    "EXT_DELETED_MESSAGE"               : "{0} has been deleted on disk, but has unsaved changes in {APP_NAME}.

Do you want to keep your changes?",

    // Find, Replace, Find in Files
    "SEARCH_REGEXP_INFO"                : "Use /re/ syntax for regexp search",
    "WITH"                              : "With",
    "BUTTON_YES"                        : "Yes",
    "BUTTON_NO"                         : "No",
    "BUTTON_STOP"                       : "Stop",

    "OPEN_FILE"                         : "Open File",
    "CHOOSE_FOLDER"                     : "Choose a folder",

    "RELEASE_NOTES"                     : "Release Notes",
    "NO_UPDATE_TITLE"                   : "You're up to date!",
    "NO_UPDATE_MESSAGE"                 : "You are running the latest version of {APP_NAME}.",

    "FIND_IN_FILES_TITLE"               : "for \"{4}\" {5} - {0} {1} in {2} {3}",
    "FIND_IN_FILES_SCOPED"              : "in {0}",
    "FIND_IN_FILES_NO_SCOPE"            : "in project",
    "FIND_IN_FILES_FILE"                : "file",
    "FIND_IN_FILES_FILES"               : "files",
    "FIND_IN_FILES_MATCH"               : "match",
    "FIND_IN_FILES_MATCHES"             : "matches",
    "FIND_IN_FILES_MORE_THAN"           : "More than ",
    "FIND_IN_FILES_MAX"                 : " (showing the first {0} matches)",
    "FIND_IN_FILES_FILE_PATH"           : "File: {0}",
    "FIND_IN_FILES_LINE"                : "line: {0}",

    "ERROR_FETCHING_UPDATE_INFO_TITLE"  : "Error getting update info",
    "ERROR_FETCHING_UPDATE_INFO_MSG"    : "There was a problem getting the latest update information from the server. Please make sure you are connected to the internet and try again.",

    // Switch language
    "LANGUAGE_TITLE"                    : "Switch Language",
    "LANGUAGE_MESSAGE"                  : "Please select the desired language from the list below:",
    "LANGUAGE_SUBMIT"                   : "Reload {APP_NAME}",
    "LANGUAGE_CANCEL"                   : "Cancel",

    /**
     * ProjectManager
     */

    "UNTITLED" : "Untitled",

    /**
     * Keyboard modifier names
     */

    "KEYBOARD_CTRL"   : "Ctrl",
    "KEYBOARD_SHIFT"  : "Shift",
    "KEYBOARD_SPACE"  : "Space",

    /**
     * StatusBar strings
     */
    "STATUSBAR_CURSOR_POSITION"             : "Line {0}, Column {1}",
    "STATUSBAR_INDENT_TOOLTIP_SPACES"       : "Click to switch indentation to spaces",
    "STATUSBAR_INDENT_TOOLTIP_TABS"         : "Click to switch indentation to tabs",
    "STATUSBAR_INDENT_SIZE_TOOLTIP_SPACES"  : "Click to change number of spaces used when indenting",
    "STATUSBAR_INDENT_SIZE_TOOLTIP_TABS"    : "Click to change tab character width",
    "STATUSBAR_SPACES"                      : "Spaces",
    "STATUSBAR_TAB_SIZE"                    : "Tab Size",
    "STATUSBAR_LINE_COUNT"                  : "{0} Lines",

    /**
     * Command Name Constants
     */

    // File menu commands
    "FILE_MENU"                           : "File",
    "CMD_FILE_NEW"                        : "New File",
    "CMD_FILE_NEW_FOLDER"                 : "New Folder",
    "CMD_FILE_OPEN"                       : "Open\u2026",
    "CMD_ADD_TO_WORKING_SET"              : "Add To Working Set",
    "CMD_OPEN_FOLDER"                     : "Open Folder\u2026",
    "CMD_FILE_CLOSE"                      : "Close",
    "CMD_FILE_CLOSE_ALL"                  : "Close All",
    "CMD_FILE_SAVE"                       : "Save",
    "CMD_FILE_SAVE_ALL"                   : "Save All",
    "CMD_LIVE_FILE_PREVIEW"               : "Live Preview",
    "CMD_LIVE_HIGHLIGHT"                  : "Live Highlight",
    "CMD_PROJECT_SETTINGS"                : "Project Settings\u2026",
    "CMD_FILE_RENAME"                     : "Rename",
    "CMD_FILE_DELETE"                     : "Delete",
    "CMD_QUIT"                            : "Quit",

    // Edit menu commands
    "EDIT_MENU"                           : "Edit",
    "CMD_SELECT_ALL"                      : "Select All",
    "CMD_SELECT_LINE"                     : "Select Line",
    "CMD_FIND"                            : "Find",
    "CMD_FIND_IN_FILES"                   : "Find in Files",
    "CMD_FIND_IN_SUBTREE"                 : "Find in...",
    "CMD_FIND_NEXT"                       : "Find Next",
    "CMD_FIND_PREVIOUS"                   : "Find Previous",
    "CMD_REPLACE"                         : "Replace",
    "CMD_INDENT"                          : "Indent",
    "CMD_UNINDENT"                        : "Unindent",
    "CMD_DUPLICATE"                       : "Duplicate",
    "CMD_DELETE_LINES"                    : "Delete Line",
    "CMD_COMMENT"                         : "Toggle Line Comment",
    "CMD_BLOCK_COMMENT"                   : "Toggle Block Comment",
    "CMD_LINE_UP"                         : "Move Line Up",
    "CMD_LINE_DOWN"                       : "Move Line Down",

    // View menu commands
    "VIEW_MENU"                           : "View",
    "CMD_HIDE_SIDEBAR"                    : "Hide Sidebar",
    "CMD_SHOW_SIDEBAR"                    : "Show Sidebar",
    "CMD_INCREASE_FONT_SIZE"              : "Increase Font Size",
    "CMD_DECREASE_FONT_SIZE"              : "Decrease Font Size",
    "CMD_RESTORE_FONT_SIZE"               : "Restore Font Size",
    "CMD_SORT_WORKINGSET_BY_ADDED"        : "Sort by Added",
    "CMD_SORT_WORKINGSET_BY_NAME"         : "Sort by Name",
    "CMD_SORT_WORKINGSET_BY_TYPE"         : "Sort by Type",
    "CMD_SORT_WORKINGSET_AUTO"            : "Automatic Sort",

    // Navigate menu Commands
    "NAVIGATE_MENU"                       : "Navigate",
    "CMD_QUICK_OPEN"                      : "Quick Open",
    "CMD_GOTO_LINE"                       : "Go to Line",
    "CMD_GOTO_DEFINITION"                 : "Go to Definition",
    "CMD_TOGGLE_QUICK_EDIT"               : "Quick Edit",
    "CMD_QUICK_EDIT_PREV_MATCH"           : "Previous Match",
    "CMD_QUICK_EDIT_NEXT_MATCH"           : "Next Match",
    "CMD_NEXT_DOC"                        : "Next Document",
    "CMD_PREV_DOC"                        : "Previous Document",
    "CMD_SHOW_IN_TREE"                    : "Show in File Tree",

    // Debug menu commands
    "DEBUG_MENU"                          : "Debug",
    "CMD_REFRESH_WINDOW"                  : "Reload {APP_NAME}",
    "CMD_SHOW_DEV_TOOLS"                  : "Show Developer Tools",
    "CMD_RUN_UNIT_TESTS"                  : "Run Tests",
    "CMD_JSLINT"                          : "Enable JSLint",
    "CMD_SHOW_PERF_DATA"                  : "Show Performance Data",
    "CMD_NEW_BRACKETS_WINDOW"             : "New {APP_NAME} Window",
    "CMD_SHOW_EXTENSIONS_FOLDER"          : "Show Extensions Folder",
    "CMD_SWITCH_LANGUAGE"                 : "Switch Language",
    "CMD_CHECK_FOR_UPDATE"                : "Check for Updates",

    // Help menu commands
    "HELP_MENU"                           : "Help",
    "CMD_ABOUT"                           : "About {APP_TITLE}",
    "CMD_FORUM"                           : "{APP_NAME} Forum",

    // Special commands invoked by the native shell
    "CMD_CLOSE_WINDOW"                    : "Close Window",
    "CMD_ABORT_QUIT"                      : "Abort Quit",

    // Strings for main-view.html
    "EXPERIMENTAL_BUILD"                   : "Experimental Build",
    "JSLINT_ERRORS"                        : "JSLint Errors",
    "JSLINT_ERROR_INFORMATION"             : "1 JSLint Error",
    "JSLINT_ERRORS_INFORMATION"            : "{0} JSLint Errors",
    "JSLINT_NO_ERRORS"                     : "No JSLint errors - good job!",
    "JSLINT_DISABLED"                      : "JSLint disabled or not working for the current file",
    "SEARCH_RESULTS"                       : "Search Results",
    "OK"                                   : "OK",
    "DONT_SAVE"                            : "Don't Save",
    "SAVE"                                 : "Save",
    "CANCEL"                               : "Cancel",
    "RELOAD_FROM_DISK"                     : "Reload from Disk",
    "KEEP_CHANGES_IN_EDITOR"               : "Keep Changes in Editor",
    "CLOSE_DONT_SAVE"                      : "Close (Don't Save)",
    "RELAUNCH_CHROME"                      : "Relaunch Chrome",
    "ABOUT"                                : "About",
    "APP_NAME"                             : "Brackets",
    "CLOSE"                                : "Close",
    "ABOUT_TEXT_LINE1"                     : "sprint {VERSION_MINOR} experimental build {VERSION}",
    "ABOUT_TEXT_LINE3"                     : "Notices, terms and conditions pertaining to third party software are located at http://www.adobe.com/go/thirdparty/ and incorporated by reference herein.",
    "ABOUT_TEXT_LINE4"                     : "Documentation and source at https://github.com/adobe/brackets/",
    "UPDATE_NOTIFICATION_TOOLTIP"          : "There's a new build of {APP_NAME} available! Click here for details.",
    "UPDATE_AVAILABLE_TITLE"               : "Update Available",
    "UPDATE_MESSAGE"                       : "Hey, there's a new build of {APP_NAME} available. Here are some of the new features:",
    "GET_IT_NOW"                           : "Get it now!",
    "PROJECT_SETTINGS_TOOLTIP"             : "Project Settings",
    "PROJECT_SETTINGS_TITLE"               : "Project Settings for: {0}",
    "PROJECT_SETTING_BASE_URL"             : "Live Preview Base URL",
    "PROJECT_SETTING_BASE_URL_HINT"        : "(leave blank for file url)",
    "BASEURL_ERROR_INVALID_PROTOCOL"       : "The {0} protocol isn't supported by Live Preview—please use http: or https: .",
    "BASEURL_ERROR_SEARCH_DISALLOWED"      : "The base URL can't contain search parameters like \"{0}\".",
    "BASEURL_ERROR_HASH_DISALLOWED"        : "The base URL can't contain hashes like \"{0}\".",
    "BASEURL_ERROR_INVALID_CHAR"           : "Special characters like '{0}' must be %-encoded.",
    "BASEURL_ERROR_UNKOWN_ERROR"           : "Unknown error parsing Base URL",

    // extensions/default/InlineColorEditor
    "COLOR_EDITOR_SELECTION_FIELD_TIP"          : "Saturation (x) and Brightness (y)",
    "COLOR_EDITOR_HUE_SLIDER_TIP"               : "Hue",
    "COLOR_EDITOR_OPACITY_SLIDER_TIP"           : "Opacity",
    "COLOR_EDITOR_CURRENT_COLOR_SWATCH_TIP"     : "Current Color",
    "COLOR_EDITOR_ORIGINAL_COLOR_SWATCH_TIP"    : "Original Color",
    "COLOR_EDITOR_COLOR_INPUT_TIP"              : "Color Value",
    "COLOR_EDITOR_RGBA_BUTTON_TIP"              : "RGBa Format",
    "COLOR_EDITOR_HEX_BUTTON_TIP"               : "Hex Format",
    "COLOR_EDITOR_HSLA_BUTTON_TIP"              : "HSLa Format",
    "COLOR_EDITOR_USED_COLOR_TIP_SINGULAR"      : "{0} (Used {1} time)",
    "COLOR_EDITOR_USED_COLOR_TIP_PLURAL"        : "{0} (Used {1} times)"
});


/*!
 * jQuery UI CSS Framework @VERSION
 *
 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Theming
 */
@import "jquery.ui.base.css";
@import "jquery.ui.theme.css";


<!DOCTYPE html>

	<meta charset="utf-8">
	<title>jQuery UI Draggable - Cursor style</title>
	<link rel="stylesheet" href="../../themes/base/jquery.ui.all.css">

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

I will always stick to the center (relative to the mouse)

My cursor is at left -5 and top -5

My cursor position is only controlled for the 'bottom' value

Position the cursor while dragging the object. By default the cursor appears in the center of the dragged object; use the cursorAt option to specify another location relative to the draggable (specify a pixel value from the top, right, bottom, and/or left).  Customize the cursor's appearance by supplying the cursor option with a valid CSS cursor value: default, move, pointer, crosshair, etc.


/*!
 * jQuery UI @VERSION
 *
 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI
 */
(function( $, undefined ) {

var uuid = 0,
	runiqueId = /^ui-id-\d+$/;

// prevent duplicate loading
// this is only a problem because we proxy existing functions
// and we don't want to double proxy them
$.ui = $.ui || {};
if ( $.ui.version ) {
	return;
}

$.extend( $.ui, {
	version: "@VERSION",

	keyCode: {
		BACKSPACE: 8,
		COMMA: 188,
		DELETE: 46,
		DOWN: 40,
		END: 35,
		ENTER: 13,
		ESCAPE: 27,
		HOME: 36,
		LEFT: 37,
		NUMPAD_ADD: 107,
		NUMPAD_DECIMAL: 110,
		NUMPAD_DIVIDE: 111,
		NUMPAD_ENTER: 108,
		NUMPAD_MULTIPLY: 106,
		NUMPAD_SUBTRACT: 109,
		PAGE_DOWN: 34,
		PAGE_UP: 33,
		PERIOD: 190,
		RIGHT: 39,
		SPACE: 32,
		TAB: 9,
		UP: 38
	}
});

// plugins
$.fn.extend({
	_focus: $.fn.focus,
	focus: function( delay, fn ) {
		return typeof delay === "number" ?
			this.each(function() {
				var elem = this;
				setTimeout(function() {
					$( elem ).focus();
					if ( fn ) {
						fn.call( elem );
					}
				}, delay );
			}) :
			this._focus.apply( this, arguments );
	},

	scrollParent: function() {
		var scrollParent;
		if (($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
			scrollParent = this.parents().filter(function() {
				return (/(relative|absolute|fixed)/).test($.css(this,'position')) && (/(auto|scroll)/).test($.css(this,'overflow')+$.css(this,'overflow-y')+$.css(this,'overflow-x'));
			}).eq(0);
		} else {
			scrollParent = this.parents().filter(function() {
				return (/(auto|scroll)/).test($.css(this,'overflow')+$.css(this,'overflow-y')+$.css(this,'overflow-x'));
			}).eq(0);
		}

		return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
	},

	zIndex: function( zIndex ) {
		if ( zIndex !== undefined ) {
			return this.css( "zIndex", zIndex );
		}

		if ( this.length ) {
			var elem = $( this[ 0 ] ), position, value;
			while ( elem.length && elem[ 0 ] !== document ) {
				// Ignore z-index if position is set to a value where z-index is ignored by the browser
				// This makes behavior of this function consistent across browsers
				// WebKit always returns auto if the element is positioned
				position = elem.css( "position" );
				if ( position === "absolute" || position === "relative" || position === "fixed" ) {
					// IE returns 0 when zIndex is not specified
					// other browsers return a string
					// we ignore the case of nested elements with an explicit value of 0
					//

					value = parseInt( elem.css( "zIndex" ), 10 );
					if ( !isNaN( value ) && value !== 0 ) {
						return value;
					}
				}
				elem = elem.parent();
			}
		}

		return 0;
	},

	uniqueId: function() {
		return this.each(function() {
			if ( !this.id ) {
				this.id = "ui-id-" + (++uuid);
			}
		});
	},

	removeUniqueId: function() {
		return this.each(function() {
			if ( runiqueId.test( this.id ) ) {
				$( this ).removeAttr( "id" );
			}
		});
	},

	disableSelection: function() {
		return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
			".ui-disableSelection", function( event ) {
				event.preventDefault();
			});
	},

	enableSelection: function() {
		return this.unbind( ".ui-disableSelection" );
	}
});

// support: jQuery <1.8
if ( !$( "" ).outerWidth( 1 ).jquery ) {
	$.each( [ "Width", "Height" ], function( i, name ) {
		var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
			type = name.toLowerCase(),
			orig = {
				innerWidth: $.fn.innerWidth,
				innerHeight: $.fn.innerHeight,
				outerWidth: $.fn.outerWidth,
				outerHeight: $.fn.outerHeight
			};

		function reduce( elem, size, border, margin ) {
			$.each( side, function() {
				size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
				if ( border ) {
					size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
				}
				if ( margin ) {
					size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
				}
			});
			return size;
		}

		$.fn[ "inner" + name ] = function( size ) {
			if ( size === undefined ) {
				return orig[ "inner" + name ].call( this );
			}

			return this.each(function() {
				$( this ).css( type, reduce( this, size ) + "px" );
			});
		};

		$.fn[ "outer" + name] = function( size, margin ) {
			if ( typeof size !== "number" ) {
				return orig[ "outer" + name ].call( this, size );
			}

			return this.each(function() {
				$( this).css( type, reduce( this, size, true, margin ) + "px" );
			});
		};
	});
}

// selectors
function focusable( element, isTabIndexNotNaN ) {
	var map, mapName, img,
		nodeName = element.nodeName.toLowerCase();
	if ( "area" === nodeName ) {
		map = element.parentNode;
		mapName = map.name;
		if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
			return false;
		}
		img = $( "img[usemap=#" + mapName + "]" )[0];
		return !!img && visible( img );
	}
	return ( /input|select|textarea|button|object/.test( nodeName ) ?
		!element.disabled :
		"a" === nodeName ?
			element.href || isTabIndexNotNaN :
			isTabIndexNotNaN) &&
		// the element and all of its ancestors must be visible
		visible( element );
}

function visible( element ) {
	return !$( element ).parents().andSelf().filter(function() {
		return $.css( this, "visibility" ) === "hidden" ||
			$.expr.filters.hidden( this );
	}).length;
}

$.extend( $.expr[ ":" ], {
	data: function( elem, i, match ) {
		return !!$.data( elem, match[ 3 ] );
	},

	focusable: function( element ) {
		return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
	},

	tabbable: function( element ) {
		var tabIndex = $.attr( element, "tabindex" ),
			isTabIndexNaN = isNaN( tabIndex );
		return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
	}
});

// support
$(function() {
	var body = document.body,
		div = body.appendChild( div = document.createElement( "div" ) );

	// access offsetHeight before setting the style to prevent a layout bug
	// in IE 9 which causes the element to continue to take up space even
	// after it is removed from the DOM (#8026)
	div.offsetHeight;

	$.extend( div.style, {
		minHeight: "100px",
		height: "auto",
		padding: 0,
		borderWidth: 0
	});

	$.support.minHeight = div.offsetHeight === 100;
	$.support.selectstart = "onselectstart" in div;

	// set display to none to avoid a layout bug in IE
	// http://dev.jquery.com/ticket/4014
	body.removeChild( div ).style.display = "none";
});

// deprecated
$.extend( $.ui, {
	// $.ui.plugin is deprecated.  Use the proxy pattern instead.
	plugin: {
		add: function( module, option, set ) {
			var i,
				proto = $.ui[ module ].prototype;
			for ( i in set ) {
				proto.plugins[ i ] = proto.plugins[ i ] || [];
				proto.plugins[ i ].push( [ option, set[ i ] ] );
			}
		},
		call: function( instance, name, args ) {
			var i,
				set = instance.plugins[ name ];
			if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) {
				return;
			}

			for ( i = 0; i < set.length; i++ ) {
				if ( instance.options[ set[ i ][ 0 ] ] ) {
					set[ i ][ 1 ].apply( instance.element, args );
				}
			}
		}
	},

	contains: $.contains,

	// only used by resizable
	hasScroll: function( el, a ) {

		//If overflow is hidden, the element might have extra content, but the user wants to hide it
		if ( $( el ).css( "overflow" ) === "hidden") {
			return false;
		}

		var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
			has = false;

		if ( el[ scroll ] > 0 ) {
			return true;
		}

		// TODO: determine which cases actually cause this to happen
		// if the element doesn't have the scroll set, see if it's possible to
		// set the scroll
		el[ scroll ] = 1;
		has = ( el[ scroll ] > 0 );
		el[ scroll ] = 0;
		return has;
	},

	// these are odd functions, fix the API or move into individual plugins
	isOverAxis: function( x, reference, size ) {
		//Determines when x coordinate is over "b" element axis
		return ( x > reference ) && ( x < ( reference + size ) );
	},
	isOver: function( y, x, top, left, height, width ) {
		//Determines when x, y coordinates is over "b" element
		return $.ui.isOverAxis( y, top, height ) && $.ui.isOverAxis( x, left, width );
	}
});

})( jQuery );


* @param {Phaser.Game} game - Game reference to the currently running game.

* @param {Phaser.Tilemap} tilemap - The tilemap to which this layer belongs.

* @param {integer} index - The index of the TileLayer to render within the Tilemap.

* @param {number} width - Width of the renderable area of the layer.

* @param {number} height - Height of the renderable area of the layer.

Phaser.TilemapLayer = function (game, tilemap, index, width, height) {

keep keep keep replace replace keep keep keep

* @param {integer} width - Width of the renderable area of the layer (in pixels).

* @param {integer} height - Height of the renderable area of the layer (in pixels).

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

/**
* A Tile set is a combination of an image containing the tiles and collision data per tile.
*
* Tilesets are normally created automatically when Tiled data is loaded.
*
* @class Phaser.Tileset
* @constructor
* @param {string} name - The name of the tileset in the map data.
* @param {integer} firstgid - The first tile index this tileset contains.
* @param {integer} [width=32] - Width of each tile (in pixels).
* @param {integer} [height=32] - Height of each tile (in pixels).
* @param {integer} [margin=0] - The margin around all tiles in the sheet (in pixels).
* @param {integer} [spacing=0] - The spacing between each tile in the sheet (in pixels).
* @param {object} [properties={}] - Custom Tileset properties.
*/
Phaser.Tileset = function (name, firstgid, width, height, margin, spacing, properties) {

    if (typeof width === 'undefined' || width <= 0) { width = 32; }
    if (typeof height === 'undefined' || height <= 0) { height = 32; }
    if (typeof margin === 'undefined') { margin = 0; }
    if (typeof spacing === 'undefined') { spacing = 0; }

    /**
    * The name of the Tileset.
    * @member {string}
    */
    this.name = name;

    /**
    * The Tiled firstgid value.
    * This is the starting index of the first tile index this Tileset contains.
    * @member {integer}
    */
    this.firstgid = firstgid | 0;

    /**
    * The width of each tile (in pixels).
    * @member {integer}
    */
    this.tileWidth = width | 0;

    /**
    * The height of each tile (in pixels).
    * @member {integer}
    */
    this.tileHeight = height | 0;

    /**
    * The margin around the tiles in the sheet (in pixels).
    * @member {integer}
    */
    this.tileMargin = margin | 0;

    /**
    * The spacing between each tile in the sheet (in pixels).
    * @member {integer}
    */
    this.tileSpacing = spacing | 0;

    /**
    * Tileset-specific properties that are typically defined in the Tiled editor.
    * @member {object}
    */
    this.properties = properties || {};

    /**
    * The cached image that contains the individual tiles. Use `setImage` to set.
    * @member {?object}
    */
    // Modified internally
    this.image = null;

    /**
    * The number of rows in the tile sheet.
    * @member {integer}
    * @readonly
    */
    // Modified internally
    this.rows = 0;

    /**
    * The number of columns in the sheet.
    * @member {integer}
    * @readonly
    */
    // Modified internally
    this.columns = 0;

    /**
    * The total number of tiles in the sheet.
    * @member {integer}
    * @readonly
    */
    // Modified internally
    this.total = 0;

    /**
    * The look-up table to specific tile image offsets.
    * The coordinates are interlaced such that it is [x0, y0, x1, y1 .. xN, yN] and the tile with the index of firstgid is found at indices 0/1.
    * @member {integer[]}
    * @private
    */
    this.drawCoords = [];

};

Phaser.Tileset.prototype = {

    /**
    * Draws a tile from this Tileset at the given coordinates on the context.
    *
    * @method Phaser.Tileset#draw
    * @param {CanvasRenderingContext2D} context - The context to draw the tile onto.
    * @param {number} x - The x coordinate to draw to.
    * @param {number} y - The y coordinate to draw to.
    * @param {integer} index - The index of the tile within the set to draw.
    */
    draw: function (context, x, y, index) {

        //  Correct the tile index for the set and bias for interlacing
        var coordIndex = (index - this.firstgid) << 1;

        if (coordIndex >= 0 && (coordIndex + 1) < this.drawCoords.length)
        {
            context.drawImage(
                this.image,
                this.drawCoords[coordIndex],
                this.drawCoords[coordIndex + 1],
                this.tileWidth,
                this.tileHeight,
                x,
                y,
                this.tileWidth,
                this.tileHeight
            );
        }

    },

    /**
    * Returns true if and only if this tileset contains the given tile index.
    *
    * @public
    * @return {boolean} True if this tileset contains the given index.
    */
    containsTileIndex: function (tileIndex)
    {

        return (
            tileIndex >= this.firstgid &&
            tileIndex < (this.firstgid + this.total)
        );

    },

    /**
    * Set the image associated with this Tileset and update the tile data.
    *
    * @public
    * @param {Image} image - The image that contains the tiles.
    */
    setImage: function (image) {

        this.image = image;
        this.updateTileData();

    },

    /**
    * Sets tile spacing and margins.
    *
    * @public
    * @param {integer} tileMargin - The margin around the tiles in the sheet (in pixels).
    * @param {integer} tileSpacing - The spacing between the tiles in the sheet (in pixels).
    */
    setSpacing: function (margin, spacing) {

        this.tileMargin = margin | 0;
        this.tileSpacing = spacing | 0;

        this.updateTileData();

    },

    /**
    * Updates tile coordinates and tileset data.
    *
    * @protected
    */
    updateTileData: function () {

        this.rows = Math.round((image.height - this.tileMargin) / (this.tileHeight + this.tileSpacing));
        this.columns = Math.round((image.width - this.tileMargin) / (this.tileWidth + this.tileSpacing));
        this.total = this.rows * this.columns;

        this.drawCoords.length = 0;

        var tx = this.tileMargin;
        var ty = this.tileMargin;

        for (var y = 0; y < this.rows; y++)
        {
            for (var x = 0; x < this.columns; x++)
            {
                this.drawCoords.push(tx);
                this.drawCoords.push(ty);
                tx += this.tileWidth + this.tileSpacing;
            }

            tx = this.tileMargin;
            ty += this.tileHeight + this.tileSpacing;
        }

    }

};

Phaser.Tileset.prototype.constructor = Phaser.Tileset;


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

/**
* WARNING: This is an EXPERIMENTAL class. The API will change significantly in the coming versions and is incomplete.
* Please try to avoid using in production games with a long time to build.
* This is also why the documentation is incomplete.
*
* A responsive grid layer.
*
* @class Phaser.FlexLayer
* @extends Phaser.Group
* @constructor
* @param {Phaser.ScaleManager} manager - The ScaleManager.
* @param {Phaser.Point} position - A reference to the Point object used for positioning.
* @param {Phaser.Rectangle} bounds - A reference to the Rectangle used for the layer bounds.
* @param {Phaser.Point} scale - A reference to the Point object used for layer scaling.
*/
Phaser.FlexLayer = function (manager, position, bounds, scale) {

    Phaser.Group.call(this, manager.game, null, '__flexLayer' + manager.game.rnd.uuid(), false);

    /**
    * @property {Phaser.ScaleManager} scale - A reference to the ScaleManager.
    */
    this.manager = manager.manager;

    /**
    * @property {Phaser.FlexGrid} grid - A reference to the FlexGrid that owns this layer.
    */
    this.grid = manager;

    /**
     * Should the FlexLayer remain through a State swap?
     *
     * @type {boolean}
     */
    this.persist = false;

    //  Bound to the grid
    this.position = position;
    this.bounds = bounds;
    this.scale = scale;

    this.topLeft = bounds.topLeft;
    this.topMiddle = new Phaser.Point(bounds.halfWidth, 0);
    this.topRight = bounds.topRight;

    this.bottomLeft = bounds.bottomLeft;
    this.bottomMiddle = new Phaser.Point(bounds.halfWidth, bounds.bottom);
    this.bottomRight = bounds.bottomRight;

};

Phaser.FlexLayer.prototype = Object.create(Phaser.Group.prototype);
Phaser.FlexLayer.prototype.constructor = Phaser.FlexLayer;

Phaser.FlexLayer.prototype.resize = function () {
};

Phaser.FlexLayer.prototype.debug = function () {

    this.game.debug.text(this.bounds.width + ' x ' + this.bounds.height, this.bounds.x + 4, this.bounds.y + 16);
    this.game.debug.geom(this.bounds, 'rgba(0,0,255,0.9', false);

    this.game.debug.geom(this.topLeft, 'rgba(255,255,255,0.9');
    this.game.debug.geom(this.topMiddle, 'rgba(255,255,255,0.9');
    this.game.debug.geom(this.topRight, 'rgba(255,255,255,0.9');

};


PIXI.ColorMatrixFilter

The ColorMatrixFilter class lets you apply a 4x4 matrix transformation on the RGBA\ncolor and alpha values of every pixel on your displayObject to produce a result\nwith a new set of RGBA color and alpha values. It's pretty powerful!

syncUniforms

Syncs the uniforms between the class object and the shaders.

matrix

Sets the matrix of the color matrix filter