/*
 * Copyright (c) 2014 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"                     : "(greška {0})",
    "NOT_FOUND_ERR"                     : "Nepostojeća datoteka.",
    "NOT_READABLE_ERR"                  : "Datoteka ne može biti učitana.",
    "NO_MODIFICATION_ALLOWED_ERR"       : "Ciljana mapa ne može biti izmijenjena.",
    "NO_MODIFICATION_ALLOWED_ERR_FILE"  : "Trenutne ovlasti vam ne dozvoljavaju da radite izmjene.",
    "CONTENTS_MODIFIED_ERR"             : "Datoteka je bila izmjenjena izvan {APP_NAME}.",
    "FILE_EXISTS_ERR"                   : "Datoteka ili mapa već postoji.",
    "FILE"                              : "datoteka",
    "DIRECTORY"                         : "direktorij",

    // Project error strings
    "ERROR_LOADING_PROJECT"             : "Greška pri učitavanju projekta",
    "OPEN_DIALOG_ERROR"                 : "Došlo je do greške prilikom prikazivanja dijaloga za otvaranje datoteke. (error {0})",
    "REQUEST_NATIVE_FILE_SYSTEM_ERROR"  : "Došlo je do greške prilikom pokušaja da se učita direktorij {0}. (error {1})",
    "READ_DIRECTORY_ENTRIES_ERROR"      : "Došlo je do greške prilikom iščitavanja sadržaja direktorija {0}. (error {1})",

    // File open/save error string
    "ERROR_OPENING_FILE_TITLE"          : "Greška pri otvaranju datoteke",
    "ERROR_OPENING_FILE"                : "Došlo je do greške prilikom pokušaja da se otvori datoteka {0}. {1}",
    "ERROR_OPENING_FILES"               : "Došlo je do greške prilikom pokušaja da se otvore sljedeće datoteke:",
    "ERROR_RELOADING_FILE_TITLE"        : "Greška pri ponovom učitavanju izmjena sa diska",
    "ERROR_RELOADING_FILE"              : "Došlo je do greške prilikom pokušaja da se ponovo učita datoteka {0}. {1}",
    "ERROR_SAVING_FILE_TITLE"           : "Greška pri spremanju datoteke",
    "ERROR_SAVING_FILE"                 : "Došlo je do greške prilikom pokušaja da se sačuva datoteka {0}. {1}",
    "ERROR_RENAMING_FILE_TITLE"         : "Greška pri preimenovanju datoteke",
    "ERROR_RENAMING_FILE"               : "Došlo je do greške prilikom pokušaja da se preimenuje datoteka {0}. {1}",
    "ERROR_DELETING_FILE_TITLE"         : "Greška pri brisanju datoteke",
    "ERROR_DELETING_FILE"               : "Došlo je do greške prilikom pokušaja da se obriše datoteka {0}. {1}",
    "INVALID_FILENAME_TITLE"            : "Ime {0} nije valjano",
    "INVALID_FILENAME_MESSAGE"          : "Imena datoteka ne smiju sadržavati sljedeće znakove: {0} ili riječi rezervirane za sistem.",
    "FILE_ALREADY_EXISTS"               : "{0} {1} već postoji.",
    "ERROR_CREATING_FILE_TITLE"         : "Greška pri kreiranju {0}",
    "ERROR_CREATING_FILE"               : "Došlo je do greške prilikom pokušaja da se kreira {0} {1}. {2}",

    // Application preferences corrupt error strings
    "ERROR_PREFS_CORRUPT_TITLE"         : "Greška kod čitanja preferencija",
    "ERROR_PREFS_CORRUPT"               : "Vaša datoteka preferencije nije valjana u JSON. Datoteka će biti otvorena tako da možete ispraviti format. Da biste vidjeli promjene, ponovo pokrenite {APP_NAME}.",

    // Application error strings
    "ERROR_IN_BROWSER_TITLE"            : "Ups! {APP_NAME} još uvijek ne radi u pregledniku.",
    "ERROR_IN_BROWSER"                  : "Aplikacija \"{APP_NAME}\" je napravljena pomoću HTML-a, ali trenutno radi kao \"desktop\" aplikacija pa je možete koristiti za izmjenu lokalnih datoteka. Molimo Vas koristite \"application shell\" na github.com/adobe/brackets-shell repozitorij za pokretanje \"{APP_NAME}\" aplikacije.",

    // ProjectManager max files error string
    "ERROR_MAX_FILES_TITLE"             : "Greška prilikom indeksiranja datoteka",
    "ERROR_MAX_FILES"                   : "Indeksiran je maksimalni broj datoteka. Akcije koje pretražuju datoteke u indeksu mogu pogrešno funkcionirati.",

    // Live Preview error strings
    "ERROR_LAUNCHING_BROWSER_TITLE"     : "Greška prilikom pokretanja web preglednika",
    "ERROR_CANT_FIND_CHROME"            : "Google Chrome preglednik nije pronađen. Molimo potvrdite da je instaliran.",
    "ERROR_LAUNCHING_BROWSER"           : "Greška prilikom pokretanja web preglednika. (error {0})",

    "LIVE_DEVELOPMENT_ERROR_TITLE"      : "Greška u živom prikazivanju",
    "LIVE_DEVELOPMENT_RELAUNCH_TITLE"   : "Povezivanje sa preglednikom",
    "LIVE_DEVELOPMENT_ERROR_MESSAGE"    : "Da bi se Prikaz Uživo povezao, potrebno je ponovo pokrenuti Chrome sa uključenim podešavanjima za remote debugging.

Da li želite ponovo pokrenuti Chrome i omogućiti remote debugging?",
    "LIVE_DEV_LOADING_ERROR_MESSAGE"    : "Nije moguće učitati živi prikaz stranice",
    "LIVE_DEV_NEED_HTML_MESSAGE"        : "Otvorite HTML datoteku ili budite sigurni da postoji index.html datoteka u vašem projektu kako bi se pokrenuo živi prikaz.",
    "LIVE_DEV_NEED_BASEURL_MESSAGE"     : "Za pokretanje prikaza uživo sa datotekom koja je na serveru, morate navesti osnovnu URL adresu za ovaj projekt.",
    "LIVE_DEV_SERVER_NOT_READY_MESSAGE" : "Greška prilikom pokretanja HTTP servera za prikaz datoteka uživo. Pokušajte ponovo.",
    "LIVE_DEVELOPMENT_INFO_TITLE"       : "Dobro došli u Prikaz Uživo!",
    "LIVE_DEVELOPMENT_INFO_MESSAGE"     : "Prikaz uživo spaja {APP_NAME} sa vašim preglednikom. On pokreće prikaz vaše HTML datoteke u pregledniku, te potom trenutno ažurira prikaz, kako Vi mijenjate vaš kôd.

U ovoj ranoj verziji aplikacije {APP_NAME}, Prikaz uživo radi samo sa Google Chrome preglednikom i ažurira prikaz dok mijenjate CSS ili HTML datoteke. Izmjene načinjene u JavaScript datotekama su automatski ponovo učitane kada ih spremite.

(Ova poruka će biti prikazana samo jednom.)",
    "LIVE_DEVELOPMENT_TROUBLESHOOTING"  : "Za više informacija, pogledajte Rješavanje grešaka u povezivanju prilikom Prikaza uživo..",

    "LIVE_DEV_STATUS_TIP_NOT_CONNECTED" : "Prikaz uživo",
    "LIVE_DEV_STATUS_TIP_PROGRESS1"     : "Prikaz uživo: Povezivanje\u2026",
    "LIVE_DEV_STATUS_TIP_PROGRESS2"     : "Prikaz uživo: Inicijalizacija\u2026",
    "LIVE_DEV_STATUS_TIP_CONNECTED"     : "Napusti Prikaz Uživo",
    "LIVE_DEV_STATUS_TIP_OUT_OF_SYNC"   : "Prikaz uživo (sačuvaj datoteku za osvježavanje)",
    "LIVE_DEV_STATUS_TIP_SYNC_ERROR"    : "Prikaz uživo (ne osvježava se zbog greške u sintaksi)",

    "LIVE_DEV_DETACHED_REPLACED_WITH_DEVTOOLS" : "Prikaz uživo je otkazan jer su u pregledniku bili otvoreni razvojni alati",
    "LIVE_DEV_DETACHED_TARGET_CLOSED"          : "Prikaz uživo je otkazan jer je stranica zatvorena u pregledniku",
    "LIVE_DEV_NAVIGATED_AWAY"                  : "Prikaz uživo je otkazan jer je preglednik otišao na stranicu koja nije dio trenutnog projekta.",
    "LIVE_DEV_CLOSED_UNKNOWN_REASON"           : "Prikaz uživo je otkazan iz nepoznatog razloga ({0})",

    "SAVE_CLOSE_TITLE"                  : "Sačuvaj promjene",
    "SAVE_CLOSE_MESSAGE"                : "Želite li sačuvati izmjene koje ste napravili u dokumentu {0}?",
    "SAVE_CLOSE_MULTI_MESSAGE"          : "Želite li sačuvati izmjene sljedećih datoteka?",
    "EXT_MODIFIED_TITLE"                : "Vanjske izmjene",
    "CONFIRM_FOLDER_DELETE_TITLE"       : "Potvrdi brisanje",
    "CONFIRM_FOLDER_DELETE"             : "Da li ste sigurni da želite obrisati mapu {0}?",
    "FILE_DELETED_TITLE"                : "Datoteka Obrisana",
    "EXT_MODIFIED_WARNING"              : "{0} je bio izmjenjen na disku.

Da li želite sačuvati datoteku i spremiti preko tih izmjena?",
    "EXT_MODIFIED_MESSAGE"              : "{0} je bila izmjenjena na disku, ali isto tako sadrži nesačuvane promjene u {APP_NAME}.

Koju verziju želite sačuvati?",
    "EXT_DELETED_MESSAGE"               : "Datoteka {0} je izbrisana na disku, ali postoje njene nesačuvane promjene u {APP_NAME}.

Želite li sačuvati te promjene?",

    // Generic dialog/button labels
    "OK"                                : "OK",
    "CANCEL"                            : "Otkaži",
    "DONT_SAVE"                         : "Nemoj sačuvati",
    "SAVE"                              : "Sačuvaj",
    "SAVE_AS"                           : "Sačuvaj kao\u2026",
    "SAVE_AND_OVERWRITE"                : "Piši preko",
    "DELETE"                            : "Izbriši",
    "BUTTON_YES"                        : "Da",
    "BUTTON_NO"                         : "Ne",

    // Find, Replace, Find in Files
    "FIND_RESULT_COUNT"                 : "{0} rezultata",
    "FIND_RESULT_COUNT_SINGLE"          : "1 rezultat",
    "FIND_NO_RESULTS"                   : "Nema rezultata",
    "REPLACE_PLACEHOLDER"               : "Zamijeni sa\u2026",
    "BUTTON_REPLACE_ALL"                : "Sve\u2026",
    "BUTTON_REPLACE"                    : "Zamijeni",
    "BUTTON_NEXT"                       : "\u25B6",
    "BUTTON_PREV"                       : "\u25C0",
    "BUTTON_NEXT_HINT"                  : "Sljedeće poklapanje",
    "BUTTON_PREV_HINT"                  : "Prethodno poklapanje",
    "BUTTON_CASESENSITIVE_HINT"         : "Poklapanje samo sa specificiranim/određenim velikim ili malim slovom",
    "BUTTON_REGEXP_HINT"                : "Regularni Izraz",

    "OPEN_FILE"                         : "Otvori datoteku",
    "SAVE_FILE_AS"                      : "Sačuvaj datoteku",
    "CHOOSE_FOLDER"                     : "Izaberi mapu",

    "RELEASE_NOTES"                     : "Obavijesti o izmjenama",
    "NO_UPDATE_TITLE"                   : "Imate aktualnu verziju!",
    "NO_UPDATE_MESSAGE"                 : "Trenutno koristite aktualnu verziju aplikacije {APP_NAME}.",

    // Replace All (in single file)
    "FIND_REPLACE_TITLE_PART1"          : "Zamijeni \"",
    "FIND_REPLACE_TITLE_PART2"          : "\" sa \"",
    "FIND_REPLACE_TITLE_PART3"          : "\" — {2} {0} {1}",

    // Find in Files
    "FIND_IN_FILES_TITLE_PART1"         : "\"",
    "FIND_IN_FILES_TITLE_PART2"         : "\" pronađen",
    "FIND_IN_FILES_TITLE_PART3"         : "— {0} {1} {2} in {3} {4}",
    "FIND_IN_FILES_SCOPED"              : "u {0}",
    "FIND_IN_FILES_NO_SCOPE"            : "u projektu",
    "FIND_IN_FILES_FILE"                : "datoteci",
    "FIND_IN_FILES_FILES"               : "datoteka",
    "FIND_IN_FILES_MATCH"               : "poklapanje",
    "FIND_IN_FILES_MATCHES"             : "poklapanja",
    "FIND_IN_FILES_MORE_THAN"           : "Preko ",
    "FIND_IN_FILES_PAGING"              : "{0}—{1}",
    "FIND_IN_FILES_FILE_PATH"           : "{0} {2} {1}",
    // We should use normal dashes on Windows instead of em dash eventually
    "FIND_IN_FILES_EXPAND_COLLAPSE"     : "Ctrl/Cmd klikni da proširiš/skupiš sve",
    "ERROR_FETCHING_UPDATE_INFO_TITLE"  : "Greška prilikom učitavanja informacija o novoj verziji",
    "ERROR_FETCHING_UPDATE_INFO_MSG"    : "Došlo je do problema prilikom preuzimanja posljednjih informacija o novoj verziji sa servera. Molimo provjerite da li ste povezani na internet i pokušajte ponovo",

    // File exclusion filters
    "NO_FILE_FILTER"                    : "Isključi datoteke\u2026",
    "EDIT_FILE_FILTER"                  : "Uredi\u2026",
    "FILE_FILTER_DIALOG"                : "Uređivački filter",
    "FILE_FILTER_INSTRUCTIONS"          : "Isključi datoteke i direktorije koji se slažu sa ijednom od sljedećih nizova / podnizova riječi ili globs. Unesi svaki niz u novi red.",
    "FILE_FILTER_LIST_PREFIX"           : "osim",
    "FILE_FILTER_CLIPPED_SUFFIX"        : "i {0} više",

    // Quick Edit
    "ERROR_QUICK_EDIT_PROVIDER_NOT_FOUND"   : "Brzo uređivanje nije dostupno za trenutnu poziciju kursora",
    "ERROR_CSSQUICKEDIT_BETWEENCLASSES"     : "Brzo CSS uređivanje: postavi kursor na pojedinačno ime klase",
    "ERROR_CSSQUICKEDIT_CLASSNOTFOUND"      : "Brzo CSS uređivanje: nepotpuno svojstvo klase",
    "ERROR_CSSQUICKEDIT_IDNOTFOUND"         : "Brzo CSS uređivanje: nepotpuno id svojstvo",
    "ERROR_CSSQUICKEDIT_UNSUPPORTEDATTR"    : "Brzo CSS uređivanje: postavi kursor na tag, klasu(class), ili id",
    "ERROR_TIMINGQUICKEDIT_INVALIDSYNTAX"   : "Brzo CSS uređivanje vremenskog raspoređivanja: nevažeća sintaksa",
    "ERROR_JSQUICKEDIT_FUNCTIONNOTFOUND"    : "Brzo JS uređivanje: postavi kursor na ime funkcije",

    // Quick Docs
    "ERROR_QUICK_DOCS_PROVIDER_NOT_FOUND"   : "Nema dostupnih brzih dokumenata za trenutnu poziciju kursora",

    /**
     * ProjectManager
     */
    "PROJECT_LOADING"   : "Učitavanje\u2026",
    "UNTITLED"          : "Neimenovan",
    "WORKING_FILES"     : "Radne datoteke",

    /**
     * Keyboard modifier names
     */
    "KEYBOARD_CTRL"   : "Ctrl",
    "KEYBOARD_SHIFT"  : "Shift",
    "KEYBOARD_SPACE"  : "Space",

    /**
     * StatusBar strings
     */
    "STATUSBAR_CURSOR_POSITION"             : "Red {0}, Stupac {1}",
    "STATUSBAR_SELECTION_CH_SINGULAR"       : " \u2014 izabran {0} stupac",
    "STATUSBAR_SELECTION_CH_PLURAL"         : " \u2014 izabrano {0} stupaca",
    "STATUSBAR_SELECTION_LINE_SINGULAR"     : " \u2014 izabrano {0} redova",
    "STATUSBAR_SELECTION_LINE_PLURAL"       : " \u2014 izabrano {0} redova",
    "STATUSBAR_INDENT_TOOLTIP_SPACES"       : "Klikni za korištenje razmaka prilikom uvlačenja kôda",
    "STATUSBAR_INDENT_TOOLTIP_TABS"         : "Klikni za korištenje tabova prilikom uvlačenja kôda*",
    "STATUSBAR_INDENT_SIZE_TOOLTIP_SPACES"  : "Klikni da promjeniš broj razmaka prilikom uvlačenja kôda",
    "STATUSBAR_INDENT_SIZE_TOOLTIP_TABS"    : "Klikni da promjeniš širinu karaktera na kartici",
    "STATUSBAR_SPACES"                      : "Razmaci:",
    "STATUSBAR_TAB_SIZE"                    : "Veličina kartice:",
    "STATUSBAR_LINE_COUNT_SINGULAR"         : "\u2014 {0} red",
    "STATUSBAR_LINE_COUNT_PLURAL"           : "\u2014 {0} redova",
    "STATUSBAR_USER_EXTENSIONS_DISABLED"    : "Extenzije onemogućene",
    "STATUSBAR_INSERT"                      : "INS",
    "STATUSBAR_OVERWRITE"                   : "OVR",

    // CodeInspection: errors/warnings
    "ERRORS_PANEL_TITLE_MULTIPLE"           : "{0} grešaka",
    "SINGLE_ERROR"                          : "1 {0} greška",
    "MULTIPLE_ERRORS"                       : "{1} {0} grešaka",
    "NO_ERRORS"                             : "Nema {0} nađenih grešaka - svaka čast!",
    "NO_ERRORS_MULTIPLE_PROVIDER"           : "Nema nađenih grešaka - bravo!",
    "LINT_DISABLED"                         : "Detektiranje sumnjivog kôda isključeno",
    "NO_LINT_AVAILABLE"                     : "Nijedan detektor sumnjivog kôda nije dostupan za {0}",
    "NOTHING_TO_LINT"                       : "Nije pronađen sumnjivi kôd",

    /**
     * Command Name Constants
     */

    // File menu commands
    "FILE_MENU"                           : "Datoteka",
    "CMD_FILE_NEW_UNTITLED"               : "Nova",
    "CMD_FILE_NEW"                        : "Nova datoteka",
    "CMD_FILE_NEW_FOLDER"                 : "Nova mapa",
    "CMD_FILE_OPEN"                       : "Otvori\u2026",
    "CMD_ADD_TO_WORKING_SET"              : "Dodaj u radni set",
    "CMD_OPEN_DROPPED_FILES"              : "Open Dropped Files",
    "CMD_OPEN_FOLDER"                     : "Otvori Mapu\u2026",
    "CMD_FILE_CLOSE"                      : "Zatvori",
    "CMD_FILE_CLOSE_ALL"                  : "Zatvori sve",
    "CMD_FILE_CLOSE_LIST"                 : "Zatvori listu",
    "CMD_FILE_CLOSE_OTHERS"               : "Zatvori druge",
    "CMD_FILE_CLOSE_ABOVE"                : "Zatvori druge iznad",
    "CMD_FILE_CLOSE_BELOW"                : "Zatvori druge ispod",
    "CMD_FILE_SAVE"                       : "Sačuvaj",
    "CMD_FILE_SAVE_ALL"                   : "Sačuvaj sve",
    "CMD_FILE_SAVE_AS"                    : "Sačuvaj kao\u2026",
    "CMD_LIVE_FILE_PREVIEW"               : "Prikaz uživo",
    "CMD_PROJECT_SETTINGS"                : "Postavke Projekta\u2026",
    "CMD_FILE_RENAME"                     : "Preimenuj",
    "CMD_FILE_DELETE"                     : "Obriši",
    "CMD_INSTALL_EXTENSION"               : "Instaliraj Extenziju\u2026",
    "CMD_EXTENSION_MANAGER"               : "Manager Extenzija\u2026",
    "CMD_FILE_REFRESH"                    : "Osvježi stablo datoteka",
    "CMD_QUIT"                            : "Prekini",
    // Used in native File menu on Windows
    "CMD_EXIT" : "Izađi",

    // Edit menu commands
    "EDIT_MENU"                           : "Uredi",
    "CMD_UNDO"                            : "Poništi",
    "CMD_REDO"                            : "Ponovi",
    "CMD_CUT"                             : "Izreži",
    "CMD_COPY"                            : "Kopiraj",
    "CMD_PASTE"                           : "Zalijepi",
    "CMD_SELECT_ALL"                      : "Odaberi sve",
    "CMD_SELECT_LINE"                     : "Odaberi red",
    "CMD_SPLIT_SEL_INTO_LINES"            : "Razdvoji odabrano u redove",
    "CMD_ADD_CUR_TO_NEXT_LINE"            : "Dodaj kursor u sljedeći red",
    "CMD_ADD_CUR_TO_PREV_LINE"            : "Dodaj kursor u prošli red",
    "CMD_FIND"                            : "Nađi",
    "CMD_FIND_FIELD_PLACEHOLDER"          : "Nađi\u2026",
    "CMD_FIND_IN_FILES"                   : "Nađi u datotekama",
    "CMD_FIND_IN_SUBTREE"                 : "Nađi u\u2026",
    "CMD_FIND_NEXT"                       : "Nađi sljedeće",
    "CMD_FIND_PREVIOUS"                   : "Nađi prethodno",
    "CMD_FIND_ALL_AND_SELECT"             : "Nađi sve i odaberi",
    "CMD_ADD_NEXT_MATCH"                  : "Dodaj sljedeće slaganje u odabir",
    "CMD_SKIP_CURRENT_MATCH"              : "Preskoči i dodaj sljedeće slaganje",
    "CMD_REPLACE"                         : "Zamijeni",
    "CMD_INDENT"                          : "Pomakni udesno",
    "CMD_UNINDENT"                        : "Pomakni ulijevo",
    "CMD_DUPLICATE"                       : "Udvostruči",
    "CMD_DELETE_LINES"                    : "Obriši red",
    "CMD_COMMENT"                         : "// Komentar reda",
    "CMD_BLOCK_COMMENT"                   : "Blok komentar /*..*/",
    "CMD_LINE_UP"                         : "Pomakni red gore",
    "CMD_LINE_DOWN"                       : "Pomakni red dolje",
    "CMD_OPEN_LINE_ABOVE"                 : "Otvori red iznad",
    "CMD_OPEN_LINE_BELOW"                 : "Otvori red ispod",
    "CMD_TOGGLE_CLOSE_BRACKETS"           : "Automatski zatvori zagrade",
    "CMD_SHOW_CODE_HINTS"                 : "Prikaži naznake (hintove) kôda",

    // View menu commands
    "VIEW_MENU"                           : "Prikaz",
    "CMD_HIDE_SIDEBAR"                    : "Sakrij bočnu traku",
    "CMD_SHOW_SIDEBAR"                    : "Prikaži bočnu traku",
    "CMD_INCREASE_FONT_SIZE"              : "Povećaj veličinu fonta",
    "CMD_DECREASE_FONT_SIZE"              : "Smanji veličinu fonta",
    "CMD_RESTORE_FONT_SIZE"               : "Vrati veličinu fonta",
    "CMD_SCROLL_LINE_UP"                  : "Pomakni red gore",
    "CMD_SCROLL_LINE_DOWN"                : "Pomakni red dolje",
    "CMD_TOGGLE_LINE_NUMBERS"             : "Brojevi redova",
    "CMD_TOGGLE_ACTIVE_LINE"              : "Označi aktivni red",
    "CMD_TOGGLE_WORD_WRAP"                : "Prijelom teksta",
    "CMD_LIVE_HIGHLIGHT"                  : "Obilježi prikaz uživo",
    "CMD_VIEW_TOGGLE_INSPECTION"          : "Prekontroliraj datoteke prilikom spremanja",
    "CMD_SORT_WORKINGSET_BY_ADDED"        : "Sortiraj po datumu",
    "CMD_SORT_WORKINGSET_BY_NAME"         : "Sortiraj po imenu",
    "CMD_SORT_WORKINGSET_BY_TYPE"         : "Sortiraj po tipu",
    "CMD_SORT_WORKINGSET_AUTO"            : "Automatsko sortiranje",

    // Navigate menu Commands
    "NAVIGATE_MENU"                       : "Navigacija",
    "CMD_QUICK_OPEN"                      : "Brzo otvori",
    "CMD_GOTO_LINE"                       : "Idi na red",
    "CMD_GOTO_DEFINITION"                 : "Brzo nađi definiciju",
    "CMD_GOTO_FIRST_PROBLEM"              : "Idi na prvu grešku/upozorenje",
    "CMD_TOGGLE_QUICK_EDIT"               : "Brzo izmjeni",
    "CMD_TOGGLE_QUICK_DOCS"               : "Brzi dokumenti",
    "CMD_QUICK_EDIT_PREV_MATCH"           : "Prethodno poklapanje",
    "CMD_QUICK_EDIT_NEXT_MATCH"           : "Sljedeće poklapanje",
    "CMD_CSS_QUICK_EDIT_NEW_RULE"         : "Novo pravilo",
    "CMD_NEXT_DOC"                        : "Sljedeći dokument",
    "CMD_PREV_DOC"                        : "Prethodni dokument",
    "CMD_SHOW_IN_TREE"                    : "Prikaži u stablu datoteka",
    "CMD_SHOW_IN_EXPLORER"                : "Prikaži u Exploreru",
    "CMD_SHOW_IN_FINDER"                  : "Prikaži u Finderu",
    "CMD_SHOW_IN_OS"                      : "Prikaži u OS-u",

    // Help menu commands
    "HELP_MENU"                           : "Pomoć",
    "CMD_CHECK_FOR_UPDATE"                : "Provjeri postoji li novija verzija",
    "CMD_HOW_TO_USE_BRACKETS"             : "Kako koristiti {APP_NAME}",
    "CMD_SUPPORT"                         : "{APP_NAME} Podrška (na engleskom)",
    "CMD_SUGGEST"                         : "Predloži mogućnost / značajku",
    "CMD_FORUM"                           : "{APP_NAME} Forum",
    "CMD_RELEASE_NOTES"                   : "Bilješke o trenutnoj verziji",
    "CMD_GET_INVOLVED"                    : "Uključi se",
    "CMD_REPORT_AN_ISSUE"                 : "Prijavi problem",
    "CMD_SHOW_EXTENSIONS_FOLDER"          : "Prikaži direktorij sa ekstenzijama",
    "CMD_TWITTER"                         : "{TWITTER_NAME} na Twitteru",
    "CMD_ABOUT"                           : "O programu {APP_TITLE}",
    "CMD_OPEN_PREFERENCES"                : "Otvori Preferencije",

    // Strings for main-view.html
    "EXPERIMENTAL_BUILD"                   : "experimentalna verzija",
    "DEVELOPMENT_BUILD"                    : "razvojna verzija",
    "RELOAD_FROM_DISK"                     : "Ponovo učitaj sa diska",
    "KEEP_CHANGES_IN_EDITOR"               : "Sačuvaj izmjene u Editoru",
    "CLOSE_DONT_SAVE"                      : "Zatvori (Nemoj sačuvati)",
    "RELAUNCH_CHROME"                      : "Ponovo pokreni Chrome",
    "ABOUT"                                : "O aplikaciji",
    "CLOSE"                                : "Zatvori",
    "ABOUT_TEXT_LINE1"                     : "sprint {VERSION_MINOR} {BUILD_TYPE} {VERSION}",
    "ABOUT_TEXT_LINE3"                     : "Obavijesti, obaveze i uvjeti korištenja koji se odnose na third party softver su locirani na {ADOBE_THIRD_PARTY} i uključeni su ovdje putem linka.",
    "ABOUT_TEXT_LINE4"                     : "Dokumentacija i izvorni kôd na https://github.com/adobe/brackets/",
    "ABOUT_TEXT_LINE5"                     : "Napravili sa \u2764 i JavaScriptom:",
    "ABOUT_TEXT_LINE6"                     : "Mnogo ljudi (ali trenutno imamo poteškoća sa učitavanjem tih podataka).",
    "ABOUT_TEXT_WEB_PLATFORM_DOCS"         : "Web Platform Docs i Web Platform graphical logo su zaštićeni pod Creative Commons Attribution licencom, CC-BY 3.0 Unported.",
    "UPDATE_NOTIFICATION_TOOLTIP"          : "Dostupna je nova verzija aplikacije {APP_NAME}! Kliknite ovdje za detalje.",
    "UPDATE_AVAILABLE_TITLE"               : "Novija verzija je dostupna",
    "UPDATE_MESSAGE"                       : "Nova verzija aplikacije {APP_NAME} je dostupna. Ovo su neka od najnovijih izmjena:",
    "GET_IT_NOW"                           : "Preuzmi sada!",
    "PROJECT_SETTINGS_TITLE"               : "Postavke projekta za: {0}",
    "PROJECT_SETTING_BASE_URL"             : "Osnovna URL adresa za prikaz uživo",
    "PROJECT_SETTING_BASE_URL_HINT"        : "Da biste koristili lokalni server unesite adresu (url) kao http://localhost:8000/",
    "BASEURL_ERROR_INVALID_PROTOCOL"       : "Prikaz uživo ne podržava protokol {0} — koristite http: or https: .",
    "BASEURL_ERROR_SEARCH_DISALLOWED"      : "Osnovna URL adresa ne smije sadržavati parametre za traženje poput \"{0}\".",
    "BASEURL_ERROR_HASH_DISALLOWED"        : "Osnovna URL adresa ne smije sadržavati hasheve (hashes) poput \"{0}\".",
    "BASEURL_ERROR_INVALID_CHAR"           : "Posebni znakovi kao '{0}' moraju biti %-enkodirani.",
    "BASEURL_ERROR_UNKNOWN_ERROR"          : "Nepoznata greška prilikom parsiranja osnovne URL adrese",

    // CSS Quick Edit
    "BUTTON_NEW_RULE"                      : "Novo Pravilo",

    // Extension Management strings
    "INSTALL"                              : "Instaliraj",
    "UPDATE"                               : "Obnovi",
    "REMOVE"                               : "Makni",
    "OVERWRITE"                            : "Piši preko",
    "CANT_REMOVE_DEV"                      : "Extenzije u \"dev\" mapi moraju biti ručno obrisane.",
    "CANT_UPDATE"                          : "Novija verzija nije kompatibilna sa trenutnom verzijom aplikacije {APP_NAME}.",
    "CANT_UPDATE_DEV"                      : "Extenzije u \"dev\" mapi ne mogu biti automatski ažurirane.",
    "INSTALL_EXTENSION_TITLE"              : "Instaliraj Extenziju",
    "UPDATE_EXTENSION_TITLE"               : "Ažuriraj Extenziju",
    "INSTALL_EXTENSION_LABEL"              : "Link Extenzije",
    "INSTALL_EXTENSION_HINT"               : "Link zip arhive extenzije ili GitHub repozitorija",
    "INSTALLING_FROM"                      : "Instaliranje extenzije sa {0}\u2026",
    "INSTALL_SUCCEEDED"                    : "Instalacija je uspjela!",
    "INSTALL_FAILED"                       : "Instalacija nije uspjela.",
    "CANCELING_INSTALL"                    : "Otkazivanje\u2026",
    "CANCELING_HUNG"                       : "Otkazivanje instalacije traje predugo. Vjerojatno je došlo do unutarnje greške.",
    "INSTALL_CANCELED"                     : "Instalacija je otkazana.",
    // These must match the error codes in ExtensionsDomain.Errors.* :
    "INVALID_ZIP_FILE"                     : "Preuzeti sadržaj nije valjana zip arhiva.",
    "INVALID_PACKAGE_JSON"                 : "package.json datoteka nije valjana (greška je bila: {0}).",
    "MISSING_PACKAGE_NAME"                 : "package.json datoteka nije navela ime paketa.",
    "BAD_PACKAGE_NAME"                     : "{0} nije valjano ime za paket.",
    "MISSING_PACKAGE_VERSION"              : "package.json datoteka nije navela verziju paketa.",
    "INVALID_VERSION_NUMBER"               : "Verzija paketa broj ({0}) nije valjana.",
    "INVALID_BRACKETS_VERSION"             : "Niz o kompatibilnosti ({0}) aplikacije {APP_NAME} nije valjan.",
    "DISALLOWED_WORDS"                     : "Riječi ({1}) nisu dozvoljene u polju {0}.",
    "API_NOT_COMPATIBLE"                   : "Ova extenzija nije kompatibilna sa ovom verzijom aplikacije {APP_NAME}. Instalirana je u vašu mapu onemogućenih extenzija.",
    "MISSING_MAIN"                         : "Paket nema main.js datoteku.",
    "EXTENSION_ALREADY_INSTALLED"          : "Instaliranjem ovog paketa ćete presnimiti prethodno instaliranu verziju. Da li želite presnimiti staru extenziju?",
    "EXTENSION_SAME_VERSION"               : "Verzija ovog paketa je ista kao verzija koja je trenutno instalirana. Da li želite presnimiti postojeću instalaciju?",
    "EXTENSION_OLDER_VERSION"              : "Ovaj paket je verzija {0} što je starije od trenutno instalirane verzije ({1}). Želite li presnimiti postojeću instalaciju?",
    "DOWNLOAD_ID_IN_USE"                   : "Unutarnja greška: ID preuzimanja je već u upotrebi.",
    "NO_SERVER_RESPONSE"                   : "Povezivanje sa serverom nije moguće.",
    "BAD_HTTP_STATUS"                      : "Datoteka nije pronađena na serveru (HTTP {0}).",
    "CANNOT_WRITE_TEMP"                    : "Nije moguće sačuvati preuzete podatke u privremenu datoteku.",
    "ERROR_LOADING"                        : "Extenzija je naišla na grešku prilikom pokretanja.",
    "MALFORMED_URL"                        : "URL nije valjan. Molimo provjerite da li ste ga unjeli točno.",
    "UNSUPPORTED_PROTOCOL"                 : "URL mora biti http or https URL.",
    "UNKNOWN_ERROR"                        : "Nepoznata unutarnja greška.",
    // For NOT_FOUND_ERR, see generic strings above
    "EXTENSION_MANAGER_TITLE"              : "Manager extenzija",
    "EXTENSION_MANAGER_ERROR_LOAD"         : "Pristupanje registru extenzije nije moguće. Pokušajte kasnije.",
    "INSTALL_FROM_URL"                     : "Instaliraj sa linka URL\u2026",
    "EXTENSION_AUTHOR"                     : "Autor",
    "EXTENSION_DATE"                       : "Datum",
    "EXTENSION_INCOMPATIBLE_NEWER"         : "Ova extenzija zahtjeva noviju verziju aplikacije {APP_NAME}.",
    "EXTENSION_INCOMPATIBLE_OLDER"         : "Ova extenzija trenutno radi samo sa starijom verzijom aplikacije {APP_NAME}.",
    "EXTENSION_LATEST_INCOMPATIBLE_NEWER"  : "Verzija {0} ove extenzije traži noviju verziju aplikacije {APP_NAME}. Ali možete instalirati raniju verziju {1}.",
    "EXTENSION_LATEST_INCOMPATIBLE_OLDER"  : "Verzija {0} ove extenzije radi samo sa starijim verzijama aplikacije {APP_NAME}. Ali možete instalirati raniju verziju {1}.",
    "EXTENSION_NO_DESCRIPTION"             : "Nema opisa",
    "EXTENSION_MORE_INFO"                  : "Više informacija...",
    "EXTENSION_ERROR"                      : "Greška u extenziji",
    "EXTENSION_KEYWORDS"                   : "Ključne riječi",
    "EXTENSION_INSTALLED"                  : "Instalirano",
    "EXTENSION_UPDATE_INSTALLED"           : "Ova verzija extenzije već je preuzeta i biti će instalirana nakon što se {APP_NAME} ponovo učita.",
    "EXTENSION_SEARCH_PLACEHOLDER"         : "Traži",
    "EXTENSION_MORE_INFO_LINK"             : "Više",
    "BROWSE_EXTENSIONS"                    : "Pretraži Extenzije",
    "EXTENSION_MANAGER_REMOVE"             : "Ukloni Extenziju",
    "EXTENSION_MANAGER_REMOVE_ERROR"       : "Nemoguće je ukloniti jednu ili više extenzija: {0}. {APP_NAME} će se svejedno ponovo učitati.",
    "EXTENSION_MANAGER_UPDATE"             : "Obnovi extenziju",
    "EXTENSION_MANAGER_UPDATE_ERROR"       : "Nije moguće obnoviti jednu ili više extenzija: {0}. {APP_NAME} će se svejedno ponovno učitati.",
    "MARKED_FOR_REMOVAL"                   : "Označeno za uklanjanje",
    "UNDO_REMOVE"                          : "Poništi",
    "MARKED_FOR_UPDATE"                    : "Označeno za ažuriranje",
    "UNDO_UPDATE"                          : "Poništi",
    "CHANGE_AND_RELOAD_TITLE"              : "Promjeni extenzije",
    "CHANGE_AND_RELOAD_MESSAGE"            : "Da biste obnovili ili uklonili označene extenzije, {APP_NAME} će se trebati ponovo učitati. Bit ćete zatraženi da sačuvate nesačuvane promjene.",
    "REMOVE_AND_RELOAD"                    : "Ukloni extenzije i ponovno učitaj",
    "CHANGE_AND_RELOAD"                    : "Promjeni extenzije i ponovo učitaj",
    "UPDATE_AND_RELOAD"                    : "Obnovi extenzije i ponovo učitaj",
    "PROCESSING_EXTENSIONS"                : "Obrađivanje promjene extenzije\u2026",
    "EXTENSION_NOT_INSTALLED"              : "Nemoguće je ukloniti extenziju {0} jer nije bila instalirana.",
    "NO_EXTENSIONS"                        : "Trenutno nema instaliranih extenzija.
Kliknite iznad na karticu Dostupno da dodate extenziju.",
    "NO_EXTENSION_MATCHES"                 : "Nijedna extenzija se ne poklapa sa unesenim parametrima pretrage.",
    "REGISTRY_SANITY_CHECK_WARNING"        : "Budite oprezni prilikom instalacije extenzija koje potječu iz nepoznatih izvora.",
    "EXTENSIONS_INSTALLED_TITLE"           : "Instalirano",
    "EXTENSIONS_AVAILABLE_TITLE"           : "Dostupno",
    "EXTENSIONS_UPDATES_TITLE"             : "Obnovljene verzije",

    "INLINE_EDITOR_NO_MATCHES"             : "Poklapanja nisu nađena.",
    "CSS_QUICK_EDIT_NO_MATCHES"            : "Nema postojećih CSS pravila koji odgovaraju vašem odabiru.
 Kliknite \"New Rule\" da biste ih stvorili.",
    "CSS_QUICK_EDIT_NO_STYLESHEETS"        : "Ne postoje stilovi u vašem projektu.
Stvorite jednu da dodate CSS pravila.",

    /**
     * Unit names
     */

    "UNIT_PIXELS"                          : "pixela",

    // extensions/default/DebugCommands
    "DEBUG_MENU"                                : "Otklanjanje grešaka",
    "CMD_SHOW_DEV_TOOLS"                        : "Prikaži razvojne alate",
    "CMD_REFRESH_WINDOW"                        : "Ponovo učitaj sa ekstenzijama",
    "CMD_RELOAD_WITHOUT_USER_EXTS"              : "Ponovo učitaj bez ekstenzija",
    "CMD_NEW_BRACKETS_WINDOW"                   : "Novi {APP_NAME} Prozor",
    "CMD_SWITCH_LANGUAGE"                       : "Promjeni jezik",
    "CMD_RUN_UNIT_TESTS"                        : "Testiraj",
    "CMD_SHOW_PERF_DATA"                        : "Prikaži podatke o performansama",
    "CMD_ENABLE_NODE_DEBUGGER"                  : "Uključi Node Debugger",
    "CMD_LOG_NODE_STATE"                        : "Zapiši u konzolu stanje Node-a",
    "CMD_RESTART_NODE"                          : "Ponovo pokreni Node",

    "LANGUAGE_TITLE"                            : "Promjeni Jezik",
    "LANGUAGE_MESSAGE"                          : "Jezik:",
    "LANGUAGE_SUBMIT"                           : "Ponovo učitaj {APP_NAME}",
    "LANGUAGE_CANCEL"                           : "Otkaži",
    "LANGUAGE_SYSTEM_DEFAULT"                   : "Zadani jezik",

    // extensions/default/InlineTimingFunctionEditor
    "INLINE_TIMING_EDITOR_TIME"                 : "Vrijeme",
    "INLINE_TIMING_EDITOR_PROGRESSION"          : "Napredak",
    "BEZIER_EDITOR_INFO"                        : "↑↓←→ Pomakni odabranu točku
Shift Pomakni za 10 jedinica
Tab Zamijeni točke.",
    "STEPS_EDITOR_INFO"                         : "↑↓ Povećaj ili smanji korake
←→ 'Početak' ili 'Kraj'",
    "INLINE_TIMING_EDITOR_INVALID"              : "Stara vrijednost {0} nije valjana, tako da je prikazana funkcija promjenjena u {1}. Dokument će biti ažuriran kod prvog uređivanja.",

    // extensions/default/InlineColorEditor
    "COLOR_EDITOR_CURRENT_COLOR_SWATCH_TIP"     : "Trenutna boja",
    "COLOR_EDITOR_ORIGINAL_COLOR_SWATCH_TIP"    : "Originalna boja",
    "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} (Korištena {1} put)",
    "COLOR_EDITOR_USED_COLOR_TIP_PLURAL"        : "{0} (Korištena {1} puta)",

    // extensions/default/JavaScriptCodeHints
    "CMD_JUMPTO_DEFINITION"                     : "Skoči na definiciju",
    "CMD_SHOW_PARAMETER_HINT"                   : "Pokaži naznake (hintove) parametara*",
    "NO_ARGUMENTS"                              : "<bez parametara>",

    // extensions/default/JSLint
    "JSLINT_NAME"                               : "JSLint",

    // extensions/default/QuickView
    "CMD_ENABLE_QUICK_VIEW"                     : "Brzi 'lebdeći' (hover) prikaz",

    // extensions/default/RecentProjects
    "CMD_TOGGLE_RECENT_PROJECTS"                : "Nedavni projekti",

    // extensions/default/WebPlatformDocs
    "DOCS_MORE_LINK"                            : "Pročitaj više"
});

/* Last translated for a57bd8888da0b44f382e591c64b394b065178277 */


function _handleListRendered(event, $dropdown) {

/*
 * Copyright (c) 2014 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, regexp: true, indent: 4, maxerr: 50 */
/*global define, $, brackets, window, Mustache */

/**
 * Utilities for managing file-set filters, as used in Find in Files.
 * Includes both UI for selecting/editing filters, as well as the actual file-filtering implementation.
 */
define(function (require, exports, module) {
    "use strict";

    var _                  = require("thirdparty/lodash"),
        ProjectManager     = require("project/ProjectManager"),
        DefaultDialogs     = require("widgets/DefaultDialogs"),
        Dialogs            = require("widgets/Dialogs"),
        DropdownButton     = require("widgets/DropdownButton").DropdownButton,
        StringUtils        = require("utils/StringUtils"),
        Strings            = require("strings"),
        PreferencesManager = require("preferences/PreferencesManager"),
        EditFilterTemplate = require("text!htmlContent/edit-filter-dialog.html"),
        FilterNameTemplate = require("text!htmlContent/filter-name.html");

    /** @type {number} Constant: first filter index in the filter dropdown list */
    var FIRST_FILTER_INDEX = 3;

    /** @type {?{label:string, promise:$.Promise}} context Info on which files the filter will be applied to.
     *          It will be initialized when createFilterPicker is called and if specified, editing UI will
     *          indicate how many files are excluded by the filter. Label should be of the form "in ..."
     */
    var _context = null;

    /** @type {DropdownButton} */
    var _picker  = null;

    /**
     * Populate the list of dropdown menu with two filter commands and
     * the list of saved filter sets.
     */
    function _doPopulate() {
        var dropdownItems = [Strings.NEW_FILE_FILTER, Strings.CLEAR_FILE_FILTER],
            filterSets = PreferencesManager.get("fileFilters") || [];

        if (filterSets.length) {
            dropdownItems.push("---");
            // FIRST_FILTER_INDEX needs to stay in sync with the number of static items (plus separator)
            // ie. the number of items populated so far before we concatenate with the actual filter sets.
            dropdownItems = dropdownItems.concat(filterSets);
        }
        _picker.items = dropdownItems;
    }

    /**
     * Find the index of a filter set in the list of saved filter sets.
     * @param {Array.<{name: string, patterns: Array.<string>}>} filterSets
     * @param {{name: string, patterns: Array.<string>}} filter
     */
    function _getFilterIndex(filterSets, filter) {
        var index = -1,
            found = false;

        if (!filter || !filterSets.length) {
            return index;
        }

        return _.findIndex(filterSets, _.partial(_.isEqual, filter));
    }

    /**
     * A search filter is an array of one or more glob strings. The filter must be 'compiled' via compile()
     * before passing to filterPath()/filterFileList().
     * @return {?{name: string, patterns: Array.<string>}}
     */
    function getActiveFilter() {
        var filterSets        = PreferencesManager.get("fileFilters") || [],
            activeFilterIndex = PreferencesManager.getViewState("activeFileFilter"),
            oldFilter         = PreferencesManager.getViewState("search.exclusions") || [],
            activeFilter      = null;

        if (activeFilterIndex === undefined && oldFilter.length) {
            activeFilter = { name: "", patterns: oldFilter };
            activeFilterIndex = _getFilterIndex(filterSets, activeFilter);

            // Migrate the old filter into the new filter storage
            if (activeFilterIndex === -1) {
                activeFilterIndex = filterSets.length;
                filterSets.push(activeFilter);
                PreferencesManager.set("fileFilters", filterSets);
            }
            PreferencesManager.setViewState("activeFileFilter", activeFilterIndex);
        } else if (activeFilterIndex > -1 && activeFilterIndex < filterSets.length) {
            activeFilter = filterSets[activeFilterIndex];
        }

        return activeFilter;
    }

    /**
     * Get the condensed form of the filter set by joining the first two in the set with
     * a comma separator and appending a short message with the number of filters being clipped.
     * @param {Array.<string>} filter
     * @param {string} condensed form of filter set
     */
    function _getCondensedForm(filter) {
        // Format filter in condensed form
        if (filter.length > 2) {
            return filter.slice(0, 2).join(", ") + " " +
                   StringUtils.format(Strings.FILE_FILTER_CLIPPED_SUFFIX, filter.length - 2);
        } else {
            return filter.join(", ");
        }
    }

    /**
     * Update the picker button label with the name/patterns of the selected filter or
     * No Files Excluded if no filter is selected.
     */
    function _updatePicker() {
        var filter = getActiveFilter();
        if (filter && filter.patterns.length) {
            var label = filter.name || _getCondensedForm(filter.patterns);
            _picker.setButtonLabel(StringUtils.format(Strings.EXCLUDE_FILE_FILTER, label));
        } else {
            _picker.setButtonLabel(Strings.NO_FILE_FILTER);
        }
    }

    /**
     * Sets and save the index of the active filter. Automatically set when editFilter() is completed.
     * If no filter is passed in, then clear the last active filter index by setting it to -1.
     *
     * @param {{name: string, patterns: Array.<string>}=} filter
     * @param {number=} index The index of the filter set in the list of saved filter sets or -1 if it is a new one
     */
    function setActiveFilter(filter, index) {
        var filterSets = PreferencesManager.get("fileFilters") || [];

        if (filter) {
            if (index === -1) {
                // Add a new filter set
                index = filterSets.length;
                filterSets.push(filter);
            } else if (index > -1 && index < filterSets.length) {
                // Update an existing filter set only if the filter set has some changes
                if (!_.isEqual(filterSets[index], filter)) {
                    filterSets[index] = filter;
                }
            } else {
                // Should not have been called with an invalid index to the available filter sets.
                console.log("setActiveFilter is called with an invalid index: " + index);
                return;
            }

            PreferencesManager.set("fileFilters", filterSets);
            PreferencesManager.setViewState("activeFileFilter", index);
        } else {
            // Explicitly set to -1 to remove the active file filter
            PreferencesManager.setViewState("activeFileFilter", -1);
        }
    }

    /**
     * Converts a user-specified filter object (as chosen in picker or retrieved from getFilters()) to a 'compiled' form
     * that can be used with filterPath()/filterFileList().
     * @param {!Array.<string>} userFilter
     * @return {!string} 'compiled' filter that can be passed to filterPath()/filterFileList().
     */
    function compile(userFilter) {
        // Automatically apply ** prefix/suffix to make writing simple substring-match filters more intuitive
        var wrappedGlobs = userFilter.map(function (glob) {
            // Automatic "**" prefix if not explicitly present
            if (glob.substr(0, 2) !== "**") {
                glob = "**" + glob;
            }
            // Automatic "**" suffix if not explicitly present and no "." in last path segment of filter string
            if (glob.substr(-2, 2) !== "**") {
                var lastSeg = glob.lastIndexOf("/");
                if (glob.indexOf(".", lastSeg + 1) === -1) {  // if no "/" present, this treats whole string as 'last segment'
                    glob += "**";
                }
            }
            return glob;
        });

        // Convert to regular expression for fast matching
        var regexStrings = wrappedGlobs.map(function (glob) {
            var reStr = "", i;
            for (i = 0; i < glob.length; i++) {
                var ch = glob[i];
                if (ch === "*") {
                    // Check for `**`
                    if (glob[i + 1] === "*") {
                        // Special case: `/**/` can collapse - that is, it shouldn't require matching both slashes
                        if (glob[i + 2] === "/" && glob[i - 1] === "/") {
                            reStr += "(.*/)?";
                            i += 2; // skip 2nd * and / after it
                        } else {
                            reStr += ".*";
                            i++;    // skip 2nd *
                        }
                    } else {
                        // Single `*`
                        reStr += "[^/]*";
                    }
                } else if (ch === "?") {
                    reStr += "[^/]";  // unlike '?' in regexp, in globs this requires exactly 1 char
                } else {
                    // Regular char with no special meaning
                    reStr += StringUtils.regexEscape(ch);
                }
            }
            return "^" + reStr + "$";
        });
        return regexStrings.join("|");
    }

    /**
     * Returns false if the given path matches any of the exclusion globs in the given filter. Returns true
     * if the path does not match any of the globs. If filtering many paths at once, use filterFileList()
     * for much better performance.
     *
     * @param {?string} compiledFilter  'Compiled' filter object as returned by compile(), or null to no-op
     * @param {!string} fullPath
     * @return {boolean}
     */
    function filterPath(compiledFilter, fullPath) {
        if (!compiledFilter) {
            return true;
        }

        var re = new RegExp(compiledFilter);
        return !fullPath.match(re);
    }

    /**
     * Returns a copy of 'files' filtered to just those that don't match any of the exclusion globs in the filter.
     *
     * @param {?string} compiledFilter  'Compiled' filter object as returned by compile(), or null to no-op
     * @param {!Array.<File>} files
     * @return {!Array.<File>}
     */
    function filterFileList(compiledFilter, files) {
        if (!compiledFilter) {
            return files;
        }

        var re = new RegExp(compiledFilter);
        return files.filter(function (f) {
            return !f.fullPath.match(re);
        });
    }

    /**
     * Opens a dialog box to edit the given filter. When editing is finished, the value of getActiveFilter() changes to
     * reflect the edits. If the dialog was canceled, the preference is left unchanged.
     * @param {!{name: string, patterns: Array.<string>}} filter
     * @param {number} index The index of the filter set to be edited or created. The value is -1 if it is for a new one
     *          to be created.
     * @return {!$.Promise} Dialog box promise
     */
    function editFilter(filter, index) {
        var lastFocus = window.document.activeElement;

        var templateVars = {
                instruction: StringUtils.format(Strings.FILE_FILTER_INSTRUCTIONS, brackets.config.glob_help_url),
                Strings: Strings
            };
        var dialog = Dialogs.showModalDialogUsingTemplate(Mustache.render(EditFilterTemplate, templateVars)),
            $nameField = dialog.getElement().find(".exclusions-name"),
            $editField = dialog.getElement().find(".exclusions-editor");

        $nameField.val(filter.name);
        $editField.val(filter.patterns.join("\n")).focus();

        function getValue() {
            var newFilter = $editField.val().split("\n");

            // Remove blank lines
            return newFilter.filter(function (glob) {
                return glob.trim().length;
            });
        }

        dialog.done(function (buttonId) {
            if (buttonId === Dialogs.DIALOG_BTN_OK) {
                // Update saved filter preference
                setActiveFilter({ name: $nameField.val(), patterns: getValue() }, index);
                _updatePicker();
                _doPopulate();
            }
            lastFocus.focus();  // restore focus to old pos
        });

        // Code to update the file count readout at bottom of dialog (if context provided)
        var $fileCount = dialog.getElement().find(".exclusions-filecount");

        function updateFileCount() {
            _context.promise.done(function (files) {
                var filter = getValue();
                if (filter.length) {
                    var filtered = filterFileList(compile(filter), files);
                    $fileCount.html(StringUtils.format(Strings.FILTER_FILE_COUNT, filtered.length, files.length, _context.label));
                } else {
                    $fileCount.html(StringUtils.format(Strings.FILTER_FILE_COUNT_ALL, files.length, _context.label));
                }
            });
        }

        if (_context) {
            $editField.on("input", _.debounce(updateFileCount, 400));
            updateFileCount();
        } else {
            $fileCount.hide();
        }

        return dialog.getPromise();
    }

    /**
     * Marks the filter picker's currently selected item as most-recently used, and returns the corresponding
     * 'compiled' filter object ready for use with filterPath().
     * @param {!jQueryObject} picker UI returned from createFilterPicker()
     * @return {!string} 'compiled' filter that can be passed to filterPath()/filterFileList().
     */
    function commitPicker(picker) {
        var filter = getActiveFilter();
        return (filter && filter.patterns.length) ? compile(filter.patterns) : "";
    }

    /**
     * Remove the target item from the filter dropdown list and update dropdown button
     * and dropdown list UI.
     * @param {!Event} e Mouse events
     */
    function _handleDeleteFilter(e) {
        // Remove the filter set from the preferences and
        // clear the active filter set index from view state.
        var filterSets        = PreferencesManager.get("fileFilters") || [],
            activeFilterIndex = PreferencesManager.getViewState("activeFileFilter"),
            filterIndex       = $(e.target).parent().data("index") - FIRST_FILTER_INDEX;

        // Don't let the click bubble upward.
        e.stopPropagation();

        filterSets.splice(filterIndex, 1);
        PreferencesManager.set("fileFilters", filterSets);

        if (activeFilterIndex === filterIndex) {
            // Removing the active filter, so clear the active filter
            // both in the view state.
            setActiveFilter(null);
        } else if (activeFilterIndex > filterIndex) {
            // Adjust the active filter index after the removal of a filter set before it.
            --activeFilterIndex;
            setActiveFilter(filterSets[activeFilterIndex], activeFilterIndex);
        }

        _updatePicker();
        _doPopulate();
        _picker.refresh();
    }

    /**
     * Close filter dropdwon list and launch edit filter dialog.
     * @param {!Event} e Mouse events
     */
    function _handleEditFilter(e) {
        var filterSets  = PreferencesManager.get("fileFilters") || [],
            filterIndex = $(e.target).parent().data("index") - FIRST_FILTER_INDEX;

        // Don't let the click bubble upward.
        e.stopPropagation();

        // Close the dropdown first before opening the edit filter dialog
        // so that it will restore focus to the DOM element that has focus
        // prior to opening it.
        _picker.closeDropdown();

        editFilter(filterSets[filterIndex], filterIndex);
    }

    /**
     * Set up mouse click event listeners for 'Delete' and 'Edit' buttons
     * when the dropdown is open. Also set check mark on the active filter.
     * @param {!Event>} event openDropdown event triggered when the dropdown is open
     * @param {!jQueryObject} $dropdown the jQuery DOM node of the dropdown list
     */
    function _handleOpenDropdown(event, $dropdown) {
        var activeFilterIndex = PreferencesManager.getViewState("activeFileFilter"),
            checkedItemIndex = (activeFilterIndex > -1) ? (activeFilterIndex + FIRST_FILTER_INDEX) : -1;
        _picker.setChecked(checkedItemIndex, true);

        $dropdown.find(".filter-trash-icon")
            .on("click", _handleDeleteFilter);

        $dropdown.find(".filter-edit-icon")
            .on("click", _handleEditFilter);
    }

    /**
     * Creates a UI element for selecting a filter, populated with a list of recently used filters, an option to
     * edit the selected filter and another option to create a new filter. The client should call commitDropdown()
     * when the UI containing the filter picker is confirmed (which updates the MRU order) and then use the
     * returned filter object as needed.
     *
     * @param {?{label:string, promise:$.Promise}} context Info on files that filter will apply to.
     *      This will be saved as _context for later use in creating a new filter or editing an
     *      existing filter in Edit Filter dialog.
     * @return {!jQueryObject} Picker UI. To retrieve the selected value, use commitPicker().
     */
    function createFilterPicker(context) {

        function itemRenderer(item, index) {
            if (index < FIRST_FILTER_INDEX) {
                // Prefix the two filter commands with 'recent-filter-name' so that
                // they also get the same margin-left as the actual filters.
                return "" + _.escape(item);
            }

            var condensedPatterns = _getCondensedForm(item.patterns),
                templateVars = {
                    "filter-name"    : _.escape(item.name || condensedPatterns),
                    "filter-patterns": item.name ? " - " + _.escape(condensedPatterns) : ""
                };

            return Mustache.render(FilterNameTemplate, templateVars);
        }

        _context = context;
        _picker = new DropdownButton("", [], itemRenderer);

        _updatePicker();
        _doPopulate();

        // Add 'file-filter-picker' to keep some margin space on the left of the button
        _picker.$button.addClass("file-filter-picker no-focus");

        // Set up mouse click event listeners for 'Delete' and 'Edit' buttons
        $(_picker).on("openDropdown", _handleOpenDropdown);

        $(_picker).on("select", function (event, item, itemIndex) {
            if (itemIndex === 0) {
                // Close the dropdown first before opening the edit filter dialog
                // so that it will restore focus to the DOM element that has focus
                // prior to opening it.
                _picker.closeDropdown();

                // Create a new filter set
                editFilter({ name: "", patterns: [] }, -1);
            } else if (itemIndex === 1) {
                // Uncheck the prior active filter in the dropdown list.
                var checkedItemIndex = getActiveFilter() + FIRST_FILTER_INDEX;
                _picker.setChecked(itemIndex, false);

                // Clear the active filter
                setActiveFilter(null);
                _updatePicker();
            } else if (itemIndex >= FIRST_FILTER_INDEX && item) {
                setActiveFilter(item, itemIndex - FIRST_FILTER_INDEX);
                _picker.setChecked(itemIndex, true);
                _updatePicker();
            }
        });

        return _picker.$button;
    }

    /**
     * Allows unit tests to open the file filter dropdown list.
     */
    function showDropdown() {
        if (_picker) {
            _picker.showDropdown();
        }
    }

    /**
     * Allows unit tests to close the file filter dropdown list.
     */
    function closeDropdown() {
        if (_picker) {
            _picker.closeDropdown();
        }
    }

    // For unit tests only
    exports.showDropdown       = showDropdown;
    exports.closeDropdown      = closeDropdown;

    exports.createFilterPicker = createFilterPicker;
    exports.commitPicker       = commitPicker;
    exports.getActiveFilter      = getActiveFilter;
    exports.setActiveFilter      = setActiveFilter;
    exports.editFilter         = editFilter;
    exports.compile            = compile;
    exports.filterPath         = filterPath;
    exports.filterFileList     = filterFileList;
});


<!DOCTYPE html>

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

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

Only if you drag me by 20 pixels, the dragging will start

Regardless of the distance, you have to drag and wait for 1000ms before dragging starts

Delay the start of dragging for a number of milliseconds with the delay option; prevent dragging until the cursor is held down and dragged a specifed number of pixels with the distance option.


Chainsaw
========

Build chainable fluent interfaces the easy way in node.js.

With this meta-module you can write modules with chainable interfaces.
Chainsaw takes care of all of the boring details and makes nested flow control
super simple too.

Just call `Chainsaw` with a constructor function like in the examples below.
In your methods, just do `saw.next()` to move along to the next event and
`saw.nest()` to create a nested chain.

Examples
========

add_do.js
---------

This silly example adds values with a chainsaw.

    var Chainsaw = require('chainsaw');

    function AddDo (sum) {
        return Chainsaw(function (saw) {
            this.add = function (n) {
                sum += n;
                saw.next();
            };

            this.do = function (cb) {
                saw.nest(cb, sum);
            };
        });
    }

    AddDo(0)
        .add(5)
        .add(10)
        .do(function (sum) {
            if (sum > 12) this.add(-10);
        })
        .do(function (sum) {
            console.log('Sum: ' + sum);
        })
    ;

Output:
    Sum: 5

prompt.js
---------

This example provides a wrapper on top of stdin with the help of
[node-lazy](https://github.com/pkrumins/node-lazy) for line-processing.

    var Chainsaw = require('chainsaw');
    var Lazy = require('lazy');

    module.exports = Prompt;
    function Prompt (stream) {
        var waiting = [];
        var lines = [];
        var lazy = Lazy(stream).lines.map(String)
            .forEach(function (line) {
                if (waiting.length) {
                    var w = waiting.shift();
                    w(line);
                }
                else lines.push(line);
            })
        ;

        var vars = {};
        return Chainsaw(function (saw) {
            this.getline = function (f) {
                var g = function (line) {
                    saw.nest(f, line, vars);
                };

                if (lines.length) g(lines.shift());
                else waiting.push(g);
            };

            this.do = function (cb) {
                saw.nest(cb, vars);
            };
        });
    }

And now for the new Prompt() module in action:

    var util = require('util');
    var stdin = process.openStdin();

    Prompt(stdin)
        .do(function () {
            util.print('x = ');
        })
        .getline(function (line, vars) {
            vars.x = parseInt(line, 10);
        })
        .do(function () {
            util.print('y = ');
        })
        .getline(function (line, vars) {
            vars.y = parseInt(line, 10);
        })
        .do(function (vars) {
            if (vars.x + vars.y < 10) {
                util.print('z = ');
                this.getline(function (line) {
                    vars.z = parseInt(line, 10);
                })
            }
            else {
                vars.z = 0;
            }
        })
        .do(function (vars) {
            console.log('x + y + z = ' + (vars.x + vars.y + vars.z));
            process.exit();
        })
    ;

Installation
============

With [npm](http://github.com/isaacs/npm), just do:
    npm install chainsaw

or clone this project on github:

    git clone http://github.com/substack/node-chainsaw.git

To run the tests with [expresso](http://github.com/visionmedia/expresso),
just do:

    expresso

Light Mode vs Full Mode
=======================

`node-chainsaw` supports two different modes. In full mode, every
action is recorded, which allows you to replay actions using the
`jump()`, `trap()` and `down()` methods.

However, if your chainsaws are long-lived, recording every action can
consume a tremendous amount of memory, so we also offer a "light" mode
where actions are not recorded and the aforementioned methods are
disabled.

To enable light mode simply use `Chainsaw.light()` to construct your
saw, instead of `Chainsaw()`.