diff --git a/.gitignore b/.gitignore index ac15789110b..fdca68f06ec 100644 --- a/.gitignore +++ b/.gitignore @@ -19,7 +19,6 @@ data/ /_maps/map_files/**/backup/* /_maps/map_files/**/*.dmm.backup /_maps/quicksave/* -/nano/debug.html **/__pycache__/* *.db stddef.dm diff --git a/.travis.yml b/.travis.yml index 9f47e8c0236..6b9a0f017e3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,7 +20,6 @@ jobs: script: - find . -name "*.php" -print0 | xargs -0 -n1 php -l - find . -name "*.json" -not -path "*/node_modules/*" -print0 | xargs -0 python3 ./tools/travis/json_verifier.py - - tools/travis/build_nanoui.sh - tools/travis/build_tgui.sh - tools/travis/check_grep.sh - python3 tools/travis/check_line_endings.py diff --git a/code/__DEFINES/stat.dm b/code/__DEFINES/stat.dm index 9c115bed86f..95ed3e10f6a 100644 --- a/code/__DEFINES/stat.dm +++ b/code/__DEFINES/stat.dm @@ -3,7 +3,7 @@ #define UNCONSCIOUS 1 #define DEAD 2 -// NanoUI & TGUI flags +// TGUI flags #define STATUS_INTERACTIVE 2 // GREEN Visability #define STATUS_UPDATE 1 // ORANGE Visability #define STATUS_DISABLED 0 // RED Visability diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index 9376c8dd010..1c2640fbdb2 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -112,7 +112,7 @@ #define FIRE_PRIORITY_PARALLAX 65 #define FIRE_PRIORITY_FLIGHTPACKS 80 #define FIRE_PRIORITY_MOBS 100 -#define FIRE_PRIORITY_NANOUI 110 +#define FIRE_PRIORITY_TGUI 110 #define FIRE_PRIORITY_TICKER 200 #define FIRE_PRIORITY_RUNECHAT 410 // I hate how high the fire priority on this is -aa #define FIRE_PRIORITY_OVERLAYS 500 diff --git a/code/controllers/subsystem/nanoui.dm b/code/controllers/subsystem/nanoui.dm deleted file mode 100644 index ef1b6ee03fe..00000000000 --- a/code/controllers/subsystem/nanoui.dm +++ /dev/null @@ -1,34 +0,0 @@ -SUBSYSTEM_DEF(nanoui) - name = "Nanoui" - wait = 9 - flags = SS_NO_INIT - priority = FIRE_PRIORITY_NANOUI - runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT - offline_implications = "All NanoUIs will no longer process. Shuttle call recommended." - - var/list/currentrun = list() - var/list/open_uis = list() // A list of open UIs, grouped by src_object and ui_key. - var/list/processing_uis = list() // A list of processing UIs, ungrouped. - -/datum/controller/subsystem/nanoui/Shutdown() - close_all_uis() - -/datum/controller/subsystem/nanoui/stat_entry() - ..("P:[processing_uis.len]") - -/datum/controller/subsystem/nanoui/fire(resumed = 0) - if(!resumed) - src.currentrun = processing_uis.Copy() - //cache for sanic speed (lists are references anyways) - var/list/currentrun = src.currentrun - - while(currentrun.len) - var/datum/nanoui/ui = currentrun[currentrun.len] - currentrun.len-- - if(ui && ui.user && ui.src_object) - ui.process() - else - processing_uis.Remove(ui) - if(MC_TICK_CHECK) - return - diff --git a/code/controllers/subsystem/tgui.dm b/code/controllers/subsystem/tgui.dm index 5c4c6ec6ff3..0acaf130301 100644 --- a/code/controllers/subsystem/tgui.dm +++ b/code/controllers/subsystem/tgui.dm @@ -9,7 +9,7 @@ SUBSYSTEM_DEF(tgui) name = "TGUI" wait = 9 flags = SS_NO_INIT - priority = FIRE_PRIORITY_NANOUI // Yes I am aware that this is TGUI and I used the nanoUI fire priority. Dont @ me. + priority = FIRE_PRIORITY_TGUI runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT offline_implications = "All TGUIs will no longer process. Shuttle call recommended." diff --git a/code/datums/components/_component.dm b/code/datums/components/_component.dm index f895b8d81b1..45b71a0e381 100644 --- a/code/datums/components/_component.dm +++ b/code/datums/components/_component.dm @@ -533,5 +533,5 @@ /** * Return the object that is the host of any UI's that this component has */ -/datum/component/nano_host() +/datum/component/tgui_host(mob/user) return parent diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm index 1042d9a8ddd..6ee2ea3674f 100644 --- a/code/datums/datacore.dm +++ b/code/datums/datacore.dm @@ -129,7 +129,7 @@ /* -We can't just insert in HTML into the nanoUI so we need the raw data to play with. +We can't just insert in HTML into the TGUI so we need the raw data to play with. Instead of creating this list over and over when someone leaves their PDA open to the page we'll only update it when it changes. The PDA_Manifest global list is zeroed out upon any change using /datum/datacore/proc/manifest_inject(), or manifest_insert() diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 4f6a1e71a98..53e643f6e55 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -100,7 +100,6 @@ current.mind = null leave_all_huds() //leave all the huds in the old body, so it won't get huds if somebody else enters it - SSnanoui.user_transferred(current, new_character) SStgui.on_transfer(current, new_character) if(new_character.mind) //remove any mind currently in our new body's mind variable diff --git a/code/game/machinery/atmoalter/scrubber.dm b/code/game/machinery/atmoalter/scrubber.dm index 6bfb5e07274..6f2d19b31a5 100644 --- a/code/game/machinery/atmoalter/scrubber.dm +++ b/code/game/machinery/atmoalter/scrubber.dm @@ -117,7 +117,7 @@ ui.open() ui.set_autoupdate(TRUE) -/obj/machinery/portable_atmospherics/scrubber/tgui_data(mob/user, ui_key = "main", datum/topic_state/state = GLOB.physical_state) +/obj/machinery/portable_atmospherics/scrubber/tgui_data(mob/user) var/list/data = list( "on" = on, "port_connected" = connected_port ? TRUE : FALSE, diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm index d091b07d4cb..b1a1e8a5b88 100644 --- a/code/game/machinery/computer/security.dm +++ b/code/game/machinery/computer/security.dm @@ -79,7 +79,7 @@ ui.open() ui.set_autoupdate(FALSE) -/obj/machinery/computer/secure_data/tgui_data(mob/user, ui_key = "main", datum/topic_state/state = GLOB.default_state) +/obj/machinery/computer/secure_data/tgui_data(mob/user) var/list/data = list() data["currentPage"] = current_page data["isPrinting"] = is_printing diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index b9eb3f5dd70..7196798b559 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -315,7 +315,7 @@ Class Procs: update_multitool_menu(usr) return TRUE -/obj/machinery/Topic(href, href_list, var/nowindow = 0, var/datum/topic_state/state = GLOB.default_state) +/obj/machinery/Topic(href, href_list, var/nowindow = 0, var/datum/tgui_state/state = GLOB.tgui_default_state) if(..(href, href_list, nowindow, state)) return 1 @@ -329,7 +329,7 @@ Class Procs: /obj/machinery/proc/inoperable(var/additional_flags = 0) return (stat & (NOPOWER|BROKEN|additional_flags)) -/obj/machinery/CanUseTopic(var/mob/user) +/obj/machinery/tgui_status(mob/user, datum/tgui_state/state) if(!interact_offline && (stat & (NOPOWER|BROKEN))) return STATUS_CLOSE diff --git a/code/game/objects/items/devices/aicard.dm b/code/game/objects/items/devices/aicard.dm index 7eb1dc9fd56..fcba936a7b3 100644 --- a/code/game/objects/items/devices/aicard.dm +++ b/code/game/objects/items/devices/aicard.dm @@ -47,7 +47,7 @@ ui.open() -/obj/item/aicard/tgui_data(mob/user, ui_key = "main", datum/topic_state/state = GLOB.inventory_state) +/obj/item/aicard/tgui_data(mob/user) var/data[0] var/mob/living/silicon/ai/AI = locate() in src diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 1a4f0691e21..b658623de26 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -50,14 +50,14 @@ else if(!istype(armor, /datum/armor)) stack_trace("Invalid type [armor.type] found in .armor during /obj Initialize()") -/obj/Topic(href, href_list, nowindow = FALSE, datum/topic_state/state = GLOB.default_state) +/obj/Topic(href, href_list, nowindow = FALSE, datum/tgui_state/state = GLOB.tgui_default_state) // Calling Topic without a corresponding window open causes runtime errors if(!nowindow && ..()) return TRUE // In the far future no checks are made in an overriding Topic() beyond if(..()) return // Instead any such checks are made in CanUseTopic() - if(CanUseTopic(usr, state, href_list) == STATUS_INTERACTIVE) + if(tgui_status(usr, state, href_list) == STATUS_INTERACTIVE) CouldUseTopic(usr) return FALSE @@ -65,7 +65,7 @@ return TRUE /obj/proc/CouldUseTopic(mob/user) - var/atom/host = nano_host() + var/atom/host = tgui_host() host.add_fingerprint(user) /obj/proc/CouldNotUseTopic(mob/user) @@ -77,7 +77,6 @@ STOP_PROCESSING(SSobj, src) // TODO: Have a processing bitflag to reduce on unnecessary loops through the processing lists else STOP_PROCESSING(SSfastprocess, src) - SSnanoui.close_uis(src) SStgui.close_uis(src) return ..() diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm index 2f2894906ee..4a5c7f1c992 100644 --- a/code/game/objects/structures/mirror.dm +++ b/code/game/objects/structures/mirror.dm @@ -155,7 +155,7 @@ if(voice_choice) curse(user) -/obj/structure/mirror/magic/on_ui_close(mob/user) +/obj/structure/mirror/magic/tgui_close(mob/user) curse(user) /obj/structure/mirror/magic/attackby(obj/item/I, mob/living/user, params) diff --git a/code/modules/client/asset_cache.dm b/code/modules/client/asset_cache.dm index 969afc3ba53..f1dcb1cc0a8 100644 --- a/code/modules/client/asset_cache.dm +++ b/code/modules/client/asset_cache.dm @@ -221,77 +221,10 @@ GLOBAL_LIST_EMPTY(asset_datums) "rook_white.png" = 'icons/chess_pieces/rook_white.png', "sprites.png" = 'icons/chess_pieces/sprites.png', "blank.gif" = 'icons/chess_pieces/blank.gif', - "background.png" = 'nano/images/uiBackground.png', "garbochess.js" = 'html/browser/garbochess.js', "boardui.js" = 'html/browser/boardui.js' ) -/datum/asset/simple/headers - assets = list( - "alarm_green.gif" = 'icons/program_icons/alarm_green.gif', - "alarm_red.gif" = 'icons/program_icons/alarm_red.gif', - "batt_5.gif" = 'icons/program_icons/batt_5.gif', - "batt_20.gif" = 'icons/program_icons/batt_20.gif', - "batt_40.gif" = 'icons/program_icons/batt_40.gif', - "batt_60.gif" = 'icons/program_icons/batt_60.gif', - "batt_80.gif" = 'icons/program_icons/batt_80.gif', - "batt_100.gif" = 'icons/program_icons/batt_100.gif', - "charging.gif" = 'icons/program_icons/charging.gif', - "downloader_finished.gif" = 'icons/program_icons/downloader_finished.gif', - "downloader_running.gif" = 'icons/program_icons/downloader_running.gif', - "ntnrc_idle.gif" = 'icons/program_icons/ntnrc_idle.gif', - "ntnrc_new.gif" = 'icons/program_icons/ntnrc_new.gif', - "power_norm.gif" = 'icons/program_icons/power_norm.gif', - "power_warn.gif" = 'icons/program_icons/power_warn.gif', - "sig_high.gif" = 'icons/program_icons/sig_high.gif', - "sig_low.gif" = 'icons/program_icons/sig_low.gif', - "sig_lan.gif" = 'icons/program_icons/sig_lan.gif', - "sig_none.gif" = 'icons/program_icons/sig_none.gif', - "smmon_0.gif" = 'icons/program_icons/smmon_0.gif', - "smmon_1.gif" = 'icons/program_icons/smmon_1.gif', - "smmon_2.gif" = 'icons/program_icons/smmon_2.gif', - "smmon_3.gif" = 'icons/program_icons/smmon_3.gif', - "smmon_4.gif" = 'icons/program_icons/smmon_4.gif', - "smmon_5.gif" = 'icons/program_icons/smmon_5.gif', - "smmon_6.gif" = 'icons/program_icons/smmon_6.gif', - ) - -/datum/asset/nanoui - var/list/common = list() - - var/list/common_dirs = list( - "nano/assets/", - "nano/codemirror/", - "nano/layouts/" - ) - var/list/uncommon_dirs = list( - "nano/templates/" - ) - -/datum/asset/nanoui/register() - // Crawl the directories to find files. - for(var/path in common_dirs) - var/list/filenames = flist(path) - for(var/filename in filenames) - if(copytext(filename, length(filename)) != "/") // Ignore directories. - if(fexists(path + filename)) - common[filename] = fcopy_rsc(path + filename) - register_asset(filename, common[filename]) - for(var/path in uncommon_dirs) - var/list/filenames = flist(path) - for(var/filename in filenames) - if(copytext(filename, length(filename)) != "/") // Ignore directories. - if(fexists(path + filename)) - register_asset(filename, fcopy_rsc(path + filename)) - -/datum/asset/nanoui/send(client, uncommon) - if(!islist(uncommon)) - uncommon = list(uncommon) - - send_asset_list(client, uncommon) - send_asset_list(client, common) - - //Pill sprites for UIs /datum/asset/chem_master var/assets = list() diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm index 70e50610352..c52bfc66d53 100644 --- a/code/modules/client/client_defines.dm +++ b/code/modules/client/client_defines.dm @@ -60,8 +60,6 @@ var/karma_spent = 0 var/karma_tab = 0 - var/topic_debugging = 0 //if set to true, allows client to see nanoUI errors -- yes i realize this is messy but it'll make live testing infinitely easier - control_freak = CONTROL_FREAK_ALL | CONTROL_FREAK_SKIN | CONTROL_FREAK_MACROS var/ip_intel = "Disabled" diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index 8458ac77595..2bc4110181b 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -51,12 +51,6 @@ to_chat(world, "[src]'s Topic: [href] destined for [hsrc].") #endif - if(href_list["nano_err"]) //nano throwing errors - if(topic_debugging) - to_chat(src, "## NanoUI: " + html_decode(href_list["nano_err"]))//NANO DEBUG HOOK - - - if(href_list["asset_cache_confirm_arrival"]) // to_chat(src, "ASSET JOB [href_list["asset_cache_confirm_arrival"]] ARRIVED.") var/job = text2num(href_list["asset_cache_confirm_arrival"]) @@ -834,7 +828,7 @@ preload_rsc = 1 // If config.resource_urls is not set, preload like normal. // Most assets are now handled through global_cache.dm getFiles( - 'html/search.js', // Used in various non-NanoUI HTML windows for search functionality + 'html/search.js', // Used in various non-TGUI HTML windows for search functionality 'html/panels.css' // Used for styling certain panels, such as in the new player panel ) spawn (10) //removing this spawn causes all clients to not get verbs. @@ -955,18 +949,15 @@ to_chat(usr, "You requested your UI resource files too quickly. Please try again in [(last_ui_resource_send - world.time)/10] seconds.") return - var/choice = alert(usr, "This will reload your NanoUI and TGUI resources. If you have any open UIs this may break them. Are you sure?", "Resource Reloading", "Yes", "No") + var/choice = alert(usr, "This will reload your TGUI resources. If you have any open UIs this may break them. Are you sure?", "Resource Reloading", "Yes", "No") if(choice == "Yes") // 600 deciseconds = 1 minute last_ui_resource_send = world.time + 60 SECONDS // Close their open UIs - SSnanoui.close_user_uis(usr) SStgui.close_user_uis(usr) // Resend the resources - var/datum/asset/nano_assets = get_asset_datum(/datum/asset/nanoui) - nano_assets.register() var/datum/asset/tgui_assets = get_asset_datum(/datum/asset/simple/tgui) tgui_assets.register() diff --git a/code/modules/client/preference/preferences.dm b/code/modules/client/preference/preferences.dm index 0bf474aca01..6d3d65fb045 100644 --- a/code/modules/client/preference/preferences.dm +++ b/code/modules/client/preference/preferences.dm @@ -450,7 +450,7 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts dat += "Deadchat Anonymity: [toggles2 & PREFTOGGLE_2_ANONDCHAT ? "Anonymous" : "Not Anonymous"]
" if(user.client.donator_level > 0) dat += "Donator Publicity: [(toggles & PREFTOGGLE_DONATOR_PUBLIC) ? "Public" : "Hidden"]
" - dat += "Fancy NanoUI: [(toggles2 & PREFTOGGLE_2_FANCYUI) ? "Yes" : "No"]
" + dat += "Fancy TGUI: [(toggles2 & PREFTOGGLE_2_FANCYUI) ? "Yes" : "No"]
" dat += "FPS: [clientfps]
" dat += "Ghost Ears: [(toggles & PREFTOGGLE_CHAT_GHOSTEARS) ? "All Speech" : "Nearest Creatures"]
" dat += "Ghost Radio: [(toggles & PREFTOGGLE_CHAT_GHOSTRADIO) ? "All Chatter" : "Nearest Speakers"]
" @@ -2001,7 +2001,7 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts var/mob/living/carbon/human/H = usr H.remake_hud() - if("nanoui") + if("tgui") toggles2 ^= PREFTOGGLE_2_FANCYUI if("ghost_att_anim") diff --git a/code/modules/crafting/craft.dm b/code/modules/crafting/craft.dm index 1a994123cee..a6a858b20b6 100644 --- a/code/modules/crafting/craft.dm +++ b/code/modules/crafting/craft.dm @@ -304,7 +304,7 @@ ui.open() /datum/personal_crafting/proc/close(mob/user) - var/datum/nanoui/ui = SStgui.get_open_ui(user, src, "main") + var/datum/tgui/ui = SStgui.get_open_ui(user, src, "main") if(ui) ui.close() diff --git a/code/modules/economy/ATM.dm b/code/modules/economy/ATM.dm index fa07c0c4085..c188b7f94db 100644 --- a/code/modules/economy/ATM.dm +++ b/code/modules/economy/ATM.dm @@ -51,7 +51,7 @@ log transactions linked_db = null authenticated_account = null visible_message("[bicon(src)][src] buzzes rudely, \"Connection to remote database lost.\"") - SSnanoui.update_uis(src) + SStgui.update_uis(src) if(ticks_left_timeout > 0) ticks_left_timeout-- @@ -91,7 +91,7 @@ log transactions held_card = I if(authenticated_account && held_card.associated_account_number != authenticated_account.account_number) authenticated_account = null - SSnanoui.update_uis(src) + SStgui.update_uis(src) else if(authenticated_account) if(istype(I, /obj/item/stack/spacecash)) //consume the money @@ -103,7 +103,7 @@ log transactions authenticated_account.credit(C.amount, "Credit deposit", machine_id, authenticated_account.owner_name) to_chat(user, "You insert [C] into [src].") - SSnanoui.update_uis(src) + SStgui.update_uis(src) C.use(C.amount) else return ..() diff --git a/code/modules/economy/Accounts_DB.dm b/code/modules/economy/Accounts_DB.dm index dccab690af3..5b196e16a44 100644 --- a/code/modules/economy/Accounts_DB.dm +++ b/code/modules/economy/Accounts_DB.dm @@ -64,7 +64,7 @@ GLOBAL_VAR(current_date_string) ui = new(user, src, ui_key, "AccountsUplinkTerminal", name, 800, 600, master_ui, state) ui.open() -/obj/machinery/computer/account_database/tgui_data(mob/user, ui_key = "main", datum/topic_state/state = GLOB.default_state) +/obj/machinery/computer/account_database/tgui_data(mob/user) var/list/data = list() data["currentPage"] = current_page data["is_printing"] = (next_print > world.time) diff --git a/code/modules/mining/equipment/marker_beacons.dm b/code/modules/mining/equipment/marker_beacons.dm index 3df1699c7c1..be2a1d4ad35 100644 --- a/code/modules/mining/equipment/marker_beacons.dm +++ b/code/modules/mining/equipment/marker_beacons.dm @@ -58,10 +58,10 @@ GLOBAL_LIST_INIT(marker_beacon_colors, list( transfer_fingerprints_to(M) /obj/item/stack/marker_beacon/AltClick(mob/living/user) - if(!istype(user) || CanUseTopic(user, GLOB.physical_state) != STATUS_INTERACTIVE) + if(!istype(user) || tgui_status(user, GLOB.tgui_physical_state) != STATUS_INTERACTIVE) return var/input_color = input(user, "Choose a color.", "Beacon Color") as null|anything in GLOB.marker_beacon_colors - if(!istype(user) || CanUseTopic(user, GLOB.physical_state) != STATUS_INTERACTIVE) + if(!istype(user) || tgui_status(user, GLOB.tgui_physical_state) != STATUS_INTERACTIVE) return if(input_color) picked_color = input_color @@ -130,10 +130,10 @@ GLOBAL_LIST_INIT(marker_beacon_colors, list( /obj/structure/marker_beacon/AltClick(mob/living/user) ..() - if(!istype(user) || CanUseTopic(user, GLOB.physical_state) != STATUS_INTERACTIVE) + if(!istype(user) || tgui_status(user, GLOB.tgui_physical_state) != STATUS_INTERACTIVE) return var/input_color = input(user, "Choose a color.", "Beacon Color") as null|anything in GLOB.marker_beacon_colors - if(!istype(user) || CanUseTopic(user, GLOB.physical_state) != STATUS_INTERACTIVE) + if(!istype(user) || tgui_status(user, GLOB.tgui_physical_state) != STATUS_INTERACTIVE) return if(input_color) picked_color = input_color diff --git a/code/modules/mining/machine_processing.dm b/code/modules/mining/machine_processing.dm index 579df861c19..b63234eafdf 100644 --- a/code/modules/mining/machine_processing.dm +++ b/code/modules/mining/machine_processing.dm @@ -31,16 +31,15 @@ return INITIALIZE_HINT_QDEL /obj/machinery/mineral/processing_unit_console/attack_ghost(mob/user) - return ui_interact(user) + return open_ui(user) /obj/machinery/mineral/processing_unit_console/attack_hand(mob/user) if(..()) return TRUE - return ui_interact(user) + return open_ui(user) -/obj/machinery/mineral/processing_unit_console/ui_interact(mob/user) - . = ..() +/obj/machinery/mineral/processing_unit_console/proc/open_ui(mob/user) if(!machine) return diff --git a/code/modules/mob/living/carbon/brain/MMI.dm b/code/modules/mob/living/carbon/brain/MMI.dm index 7443e4edbe3..051d0274468 100644 --- a/code/modules/mob/living/carbon/brain/MMI.dm +++ b/code/modules/mob/living/carbon/brain/MMI.dm @@ -278,18 +278,8 @@ return 1 // As a synthetic, the only limit on visibility is view range -/obj/item/mmi/contents_nano_distance(var/src_object, var/mob/living/user) +/obj/item/mmi/contents_tgui_distance(src_object, mob/living/user) + . = ..() if((src_object in view(src)) && get_dist(src_object, src) <= user.client.view) return STATUS_INTERACTIVE // interactive (green visibility) - return user.shared_living_nano_distance(src_object) - -// For now the only thing that is helped by this is radio access -// Later a more intricate system for MMI UI interaction can be established -/obj/item/mmi/contents_nano_interact(var/src_object, var/mob/living/user) - if(!istype(user, /mob/living/carbon/brain)) - log_runtime(EXCEPTION("Somehow a non-brain mob is inside an MMI!"), user) - return ..() - var/mob/living/carbon/brain/BM = user - if(BM.container == src && src_object == radio) - return STATUS_INTERACTIVE - return ..() + return user.shared_living_tgui_distance() diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 2b476a4e043..a71c9733b70 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -455,7 +455,6 @@ GLOBAL_LIST_INIT(robot_verbs_default, list( notify_ai(2) uneq_all() - SSnanoui.close_user_uis(src) SStgui.close_user_uis(src) sight_mode = null update_sight() diff --git a/code/modules/mob/logout.dm b/code/modules/mob/logout.dm index 041fa87807b..fa490c05f0c 100644 --- a/code/modules/mob/logout.dm +++ b/code/modules/mob/logout.dm @@ -1,5 +1,4 @@ /mob/Logout() - SSnanoui.user_logout(src) // this is used to clean up (remove) this user's Nano UIs SStgui.on_logout(src) // Cleanup any TGUIs the user has open unset_machine() GLOB.player_list -= src diff --git a/code/modules/nano/interaction/admin.dm b/code/modules/nano/interaction/admin.dm deleted file mode 100644 index 9223e1e0763..00000000000 --- a/code/modules/nano/interaction/admin.dm +++ /dev/null @@ -1,7 +0,0 @@ -/* - This state checks that the user is an admin, end of story -*/ -GLOBAL_DATUM_INIT(admin_state, /datum/topic_state/admin_state, new()) - -/datum/topic_state/admin_state/can_use_topic(var/src_object, var/mob/user) - return check_rights(R_ADMIN, 0, user) ? STATUS_INTERACTIVE : STATUS_CLOSE diff --git a/code/modules/nano/interaction/base.dm b/code/modules/nano/interaction/base.dm deleted file mode 100644 index e7f06137781..00000000000 --- a/code/modules/nano/interaction/base.dm +++ /dev/null @@ -1,41 +0,0 @@ -/datum/proc/nano_host() - return src - -/datum/proc/CanUseTopic(var/mob/user, var/datum/topic_state/state) - var/src_object = nano_host() - return state.can_use_topic(src_object, user) - -/datum/topic_state/proc/href_list(var/mob/user) - return list() - -/datum/topic_state/proc/can_use_topic(var/src_object, var/mob/user) - return STATUS_CLOSE - -/mob/proc/shared_nano_interaction() - if(stat || !client) - return STATUS_CLOSE // no updates, close the interface - else if(incapacitated()) - return STATUS_UPDATE // update only (orange visibility) - return STATUS_INTERACTIVE - -/mob/dead/observer/shared_nano_interaction() - if(check_rights(R_ADMIN, 0, src)) - return STATUS_INTERACTIVE // Admins are more equal - return STATUS_UPDATE // Ghosts can view updates - -/mob/living/silicon/ai/shared_nano_interaction() - if(apc_override) - return STATUS_INTERACTIVE - if(lacks_power()) - return STATUS_CLOSE - if(check_unable(1, 0)) - return STATUS_CLOSE - return ..() - -/mob/living/silicon/robot/shared_nano_interaction() - . = STATUS_INTERACTIVE - if(!cell || cell.charge <= 0) - return STATUS_CLOSE - if(lockcharge) - . = STATUS_DISABLED - return min(., ..()) diff --git a/code/modules/nano/interaction/conscious.dm b/code/modules/nano/interaction/conscious.dm deleted file mode 100644 index e4b478dced6..00000000000 --- a/code/modules/nano/interaction/conscious.dm +++ /dev/null @@ -1,7 +0,0 @@ -/* - This state only checks if user is conscious. -*/ -GLOBAL_DATUM_INIT(conscious_state, /datum/topic_state/conscious_state, new()) - -/datum/topic_state/conscious_state/can_use_topic(var/src_object, var/mob/user) - return user.stat == CONSCIOUS ? STATUS_INTERACTIVE : STATUS_CLOSE diff --git a/code/modules/nano/interaction/contained.dm b/code/modules/nano/interaction/contained.dm deleted file mode 100644 index 03ac30d07ad..00000000000 --- a/code/modules/nano/interaction/contained.dm +++ /dev/null @@ -1,18 +0,0 @@ -/* - This state checks if user is somewhere within src_object, as well as the default NanoUI interaction. -*/ -GLOBAL_DATUM_INIT(contained_state, /datum/topic_state/contained_state, new()) - -/datum/topic_state/contained_state/can_use_topic(var/atom/src_object, var/mob/user) - if(!src_object.contains(user)) - return STATUS_CLOSE - - return user.shared_nano_interaction() - -/atom/proc/contains(var/atom/location) - if(!location) - return 0 - if(location == src) - return 1 - - return contains(location.loc) diff --git a/code/modules/nano/interaction/default.dm b/code/modules/nano/interaction/default.dm deleted file mode 100644 index fed18f989f5..00000000000 --- a/code/modules/nano/interaction/default.dm +++ /dev/null @@ -1,119 +0,0 @@ -GLOBAL_DATUM_INIT(default_state, /datum/topic_state/default, new()) - -/datum/topic_state/default/href_list(var/mob/user) - return list() - -/datum/topic_state/default/can_use_topic(var/src_object, var/mob/user) - return user.default_can_use_topic(src_object) - -/mob/proc/default_can_use_topic(var/src_object) - return STATUS_CLOSE // By default no mob can do anything with NanoUI - -/mob/dead/observer/default_can_use_topic() - if(can_admin_interact()) - return STATUS_INTERACTIVE // Admins are more equal - return STATUS_UPDATE // Ghosts can view updates - -/mob/living/silicon/pai/default_can_use_topic(var/src_object) - if((src_object == src || src_object == radio) && stat == CONSCIOUS) - return STATUS_INTERACTIVE - else - return ..() - -/mob/living/silicon/robot/default_can_use_topic(var/src_object) - . = shared_nano_interaction() - if(. <= STATUS_DISABLED) - return - - // robots can interact with things they can see within their view range - if((src_object in view(src)) && get_dist(src_object, src) <= src.client.view) - return STATUS_INTERACTIVE // interactive (green visibility) - return STATUS_DISABLED // no updates, completely disabled (red visibility) - -/mob/living/silicon/ai/default_can_use_topic(var/src_object) - . = shared_nano_interaction() - // Fix the weird hacking blurb to actually let them restore power - if(aiRestorePowerRoutine == 3 && istype(src_object, /obj/machinery/power/apc)) - return STATUS_INTERACTIVE - if(. != STATUS_INTERACTIVE) - return - - // Prevents the AI from using Topic on admin levels (by for example viewing through the court/thunderdome cameras) - // unless it's on the same level as the object it's interacting with. - var/turf/T = get_turf(src_object) - if(!T || !(atoms_share_level(src,T) || is_level_reachable(T.z))) - return STATUS_CLOSE - - // If an object is in view then we can interact with it - if(src_object in view(client.view, src)) - return STATUS_INTERACTIVE - - // If we're installed in a chassi, rather than transfered to an inteliCard or other container, then check if we have camera view - if(is_in_chassis()) - //stop AIs from leaving windows open and using then after they lose vision - if(GLOB.cameranet && !GLOB.cameranet.checkTurfVis(get_turf(src_object))) - return STATUS_CLOSE - return STATUS_INTERACTIVE - else if(get_dist(src_object, src) <= client.view) // View does not return what one would expect while installed in an inteliCard - return STATUS_INTERACTIVE - - return STATUS_CLOSE - -//Some atoms such as vehicles might have special limitations for how mobs inside them interact with NanoUI. -/atom/proc/contents_nano_distance(var/src_object, var/mob/living/user) - return user.shared_living_nano_distance(src_object) - -//Some atoms such as vehicles might have special benefits for how mobs inside them interact with NanoUI. -/atom/proc/contents_nano_interact(var/src_object, var/mob/living/user) - return STATUS_CLOSE // No help at all by default - -/mob/living/proc/shared_living_nano_distance(var/atom/movable/src_object) - if(!(src_object in view(4, src))) // If the src object is not in visable, disable updates - return STATUS_CLOSE - - var/dist = get_dist(src_object, src) - if(dist <= 1) - return STATUS_INTERACTIVE // interactive (green visibility) - else if(dist <= 2) - return STATUS_UPDATE // update only (orange visibility) - else if(dist <= 4) - return STATUS_DISABLED // no updates, completely disabled (red visibility) - return STATUS_CLOSE - -/mob/living/default_can_use_topic(var/src_object) - . = shared_nano_interaction(src_object) - if(. != STATUS_CLOSE) - if(loc) - . = min(., loc.contents_nano_distance(src_object, src)) - if(. == STATUS_INTERACTIVE) - return STATUS_UPDATE - -/mob/living/carbon/brain/default_can_use_topic(var/src_object) - . = shared_nano_interaction(src_object) - if(. <= STATUS_DISABLED) - return - // Maybe add a handler here to call an "interaction state" thing on the MMI, - // later - if(loc) - . = max(., loc.contents_nano_interact(src_object, src)) // This is an "augment" on interaction - . = min(., loc.contents_nano_distance(src_object, src)) // This is a "limit" on interaction - -/mob/living/carbon/human/default_can_use_topic(var/src_object) - . = shared_nano_interaction(src_object) - if(. != STATUS_CLOSE) - . = min(., shared_living_nano_distance(src_object)) - if(. == STATUS_UPDATE && (TK in mutations)) // If we have telekinesis and remain close enough, allow interaction. - return STATUS_INTERACTIVE - -/mob/living/carbon/alien/default_can_use_topic(var/src_object) - . = shared_nano_interaction(src_object) - if(. != STATUS_CLOSE) - . = min(., shared_living_nano_distance(src_object)) - if(!IsAdvancedToolUser()) - . = STATUS_CLOSE - -/mob/living/simple_animal/bot/default_can_use_topic(var/src_object) - . = shared_nano_interaction(src_object) - if(. != STATUS_CLOSE) - if(!(src_object in contents)) - . = STATUS_CLOSE diff --git a/code/modules/nano/interaction/ghost.dm b/code/modules/nano/interaction/ghost.dm deleted file mode 100644 index bb435b33896..00000000000 --- a/code/modules/nano/interaction/ghost.dm +++ /dev/null @@ -1,14 +0,0 @@ -/* - This checks that the user is a ghost or alternatively an admin. Used for the mob spawner. - We don't want any living people somehow getting the menu open and reincarnating while alive -*/ - -GLOBAL_DATUM_INIT(ghost_state, /datum/topic_state/ghost_state, new()) - -/datum/topic_state/ghost_state/can_use_topic(var/src_object, var/mob/user) - if(user.stat == DEAD) - return STATUS_INTERACTIVE - if(check_rights(R_ADMIN, 0, src)) - return STATUS_INTERACTIVE - return STATUS_CLOSE - diff --git a/code/modules/nano/interaction/inventory.dm b/code/modules/nano/interaction/inventory.dm deleted file mode 100644 index bd0e12ea5a1..00000000000 --- a/code/modules/nano/interaction/inventory.dm +++ /dev/null @@ -1,10 +0,0 @@ -/* - This state checks that the src_object is somewhere in the user's first-level inventory (in hands, on ear, etc.), but not further down (such as in bags). -*/ -GLOBAL_DATUM_INIT(inventory_state, /datum/topic_state/inventory_state, new()) - -/datum/topic_state/inventory_state/can_use_topic(var/src_object, var/mob/user) - if(!((src_object in user) || user.is_in_active_hand(src_object) || user.is_in_inactive_hand(src_object))) - return STATUS_CLOSE - - return user.shared_nano_interaction() diff --git a/code/modules/nano/interaction/inventory_deep.dm b/code/modules/nano/interaction/inventory_deep.dm deleted file mode 100644 index 6d6e3667675..00000000000 --- a/code/modules/nano/interaction/inventory_deep.dm +++ /dev/null @@ -1,10 +0,0 @@ -/* - This state checks if src_object is contained anywhere in the user's inventory, including bags, etc. -*/ -GLOBAL_DATUM_INIT(deep_inventory_state, /datum/topic_state/deep_inventory_state, new()) - -/datum/topic_state/deep_inventory_state/can_use_topic(var/src_object, var/mob/user) - if(!user.contains(src_object)) - return STATUS_CLOSE - - return user.shared_nano_interaction() diff --git a/code/modules/nano/interaction/not_incapacitated.dm b/code/modules/nano/interaction/not_incapacitated.dm deleted file mode 100644 index 8539315f3c6..00000000000 --- a/code/modules/nano/interaction/not_incapacitated.dm +++ /dev/null @@ -1,24 +0,0 @@ - /** - * This state only checks if the user isn't incapacitated - **/ - -GLOBAL_DATUM_INIT(not_incapacitated_state, /datum/topic_state/not_incapacitated_state, new()) - - /** - * This state checks if the user isn't incapacitated and that their loc is a turf - **/ -GLOBAL_DATUM_INIT(not_incapacitated_turf_state, /datum/topic_state/not_incapacitated_state, new(no_turfs = TRUE)) - -/datum/topic_state/not_incapacitated_state - var/turf_check = FALSE - -/datum/topic_state/not_incapacitated_state/New(loc, no_turfs = FALSE) - ..() - turf_check = no_turfs - -/datum/topic_state/not_incapacitated_state/can_use_topic(src_object, mob/user) - if(user.stat) - return STATUS_CLOSE - if(user.incapacitated() || user.lying || (turf_check && !isturf(user.loc))) - return STATUS_DISABLED - return STATUS_INTERACTIVE diff --git a/code/modules/nano/interaction/physical.dm b/code/modules/nano/interaction/physical.dm deleted file mode 100644 index 193f8c094c1..00000000000 --- a/code/modules/nano/interaction/physical.dm +++ /dev/null @@ -1,18 +0,0 @@ -GLOBAL_DATUM_INIT(physical_state, /datum/topic_state/physical, new()) - -/datum/topic_state/physical/can_use_topic(var/src_object, var/mob/user) - . = user.shared_nano_interaction(src_object) - if(. > STATUS_CLOSE) - return min(., user.check_physical_distance(src_object)) - -/mob/proc/check_physical_distance(var/src_object) - return STATUS_CLOSE - -/mob/dead/observer/check_physical_distance(var/src_object) - return default_can_use_topic(src_object) - -/mob/living/check_physical_distance(var/src_object) - return shared_living_nano_distance(src_object) - -/mob/living/silicon/check_physical_distance(var/src_object) - return max(STATUS_UPDATE, shared_living_nano_distance(src_object)) diff --git a/code/modules/nano/interaction/self.dm b/code/modules/nano/interaction/self.dm deleted file mode 100644 index a3d94457135..00000000000 --- a/code/modules/nano/interaction/self.dm +++ /dev/null @@ -1,9 +0,0 @@ -/* - This state checks that the src_object is the same the as user -*/ -GLOBAL_DATUM_INIT(self_state, /datum/topic_state/self_state, new()) - -/datum/topic_state/self_state/can_use_topic(var/src_object, var/mob/user) - if(src_object != user) - return STATUS_CLOSE - return user.shared_nano_interaction() diff --git a/code/modules/nano/interaction/zlevel.dm b/code/modules/nano/interaction/zlevel.dm deleted file mode 100644 index feeb617cd49..00000000000 --- a/code/modules/nano/interaction/zlevel.dm +++ /dev/null @@ -1,13 +0,0 @@ -/* - This state checks that the user is on the same Z-level as src_object -*/ - -GLOBAL_DATUM_INIT(z_state, /datum/topic_state/z_state, new()) - -/datum/topic_state/z_state/can_use_topic(var/src_object, var/mob/user) - var/turf/turf_obj = get_turf(src_object) - var/turf/turf_usr = get_turf(user) - if(!turf_obj || !turf_usr) - return STATUS_CLOSE - - return turf_obj.z == turf_usr.z ? STATUS_INTERACTIVE : STATUS_CLOSE diff --git a/code/modules/nano/modules/nano_module.dm b/code/modules/nano/modules/nano_module.dm deleted file mode 100644 index a9afc94f69b..00000000000 --- a/code/modules/nano/modules/nano_module.dm +++ /dev/null @@ -1,16 +0,0 @@ -/datum/nano_module - var/name - var/datum/host - -/datum/nano_module/New(var/host) - src.host = host - -/datum/nano_module/nano_host() - return host ? host : src - -/datum/nano_module/on_ui_close(mob/user) - if(host) - host.on_ui_close(user) - -/datum/nano_module/proc/can_still_topic(var/datum/topic_state/state = GLOB.default_state) - return CanUseTopic(usr, state) == STATUS_INTERACTIVE diff --git a/code/modules/nano/nanoexternal.dm b/code/modules/nano/nanoexternal.dm deleted file mode 100644 index f57014496fd..00000000000 --- a/code/modules/nano/nanoexternal.dm +++ /dev/null @@ -1,64 +0,0 @@ - // This file contains all Nano procs/definitions for external classes/objects - - /** - * Called when a Nano UI window is closed - * This is how Nano handles closed windows - * It must be a verb so that it can be called using winset - * - * @return nothing - */ -/client/verb/nanoclose(var/uiref as text) - set hidden = 1 // hide this verb from the user's panel - set name = "nanoclose" - - var/datum/nanoui/ui = locate(uiref) - - if(istype(ui)) - ui.close() - - if(ui.ref) - var/href = "close=1" - src.Topic(href, params2list(href), ui.ref) // this will direct to the atom's Topic() proc via client.Topic() - else if(ui.on_close_logic) - // no atomref specified (or not found) - // so just reset the user mob's machine var - if(src && src.mob) - src.mob.unset_machine() - - /** - * The ui_interact proc is used to open and update Nano UIs - * If ui_interact is not used then the UI will not update correctly - * ui_interact is currently defined for /datum - * - * @param user /mob The mob who is interacting with this ui - * @param ui_key string A string key to use for this ui. Allows for multiple unique uis on one obj/mob (defaut value "main") - * @param ui /datum/nanoui This parameter is passed by the nanoui process() proc when updating an open ui - * @param force_open boolean Force the UI to (re)open, even if it's already open - * - * @return nothing - */ -/datum/proc/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/nanoui/master_ui = null, var/datum/topic_state/state = GLOB.default_state) - return - -/** - * The UI-close proc is called when the UI is closed. - * - * @param user /mob The mob who was interacting with this UI. - */ -/datum/proc/on_ui_close(mob/user) - return - -/** - * The ui_data proc is used to get data for the interface - * - * @param user /mob The mob who is viewing this ui - * @param ui_key string A string key to use for this ui. Allows for multiple unique uis on one obj/mob (defaut value "main") - * @param state /datum/topic_state Current topic state of the UI - * - * @return list() - */ -/datum/proc/ui_data(mob/user, ui_key = "main", datum/topic_state/state = GLOB.default_state) - return list() - -// Used by the Nano UI Manager (/datum/nanomanager) to track UIs opened by this mob -/mob/var/list/open_uis = list() diff --git a/code/modules/nano/nanoui.dm b/code/modules/nano/nanoui.dm deleted file mode 100644 index 23d84fda4d1..00000000000 --- a/code/modules/nano/nanoui.dm +++ /dev/null @@ -1,532 +0,0 @@ -/********************************************************** -NANO UI FRAMEWORK - -nanoui class (or whatever Byond calls classes) - -nanoui is used to open and update nano browser uis -**********************************************************/ - -/datum/nanoui - // the user who opened this ui - var/mob/user - // the object this ui "belongs" to - var/datum/src_object - // the title of this ui - var/title - // the key of this ui, this is to allow multiple (different) uis for each src_object - var/ui_key - // window_id is used as the window name/identifier for browse and onclose - var/window_id - // the browser window width - var/width = 0 - // the browser window height - var/height = 0 - // whether to use extra logic when window closes - var/on_close_logic = 1 - // an extra ref to use when the window is closed, usually null - var/atom/ref = null - // options for modifying window behaviour - var/window_options = "focus=0;can_close=1;can_minimize=1;can_maximize=0;can_resize=1;titlebar=1;" // window option is set using window_id - // the list of stylesheets to apply to this ui - var/list/stylesheets = list() - // the list of javascript scripts to use for this ui - var/list/scripts = list() - // a list of templates which can be used with this ui - var/templates[0] - // the layout key for this ui (this is used on the frontend, leave it as "default" unless you know what you're doing) - var/layout_key = "default" - // this sets whether to re-render the ui layout with each update (default 0, turning on will break the map ui if it's in use) - var/auto_update_layout = 0 - // this sets whether to re-render the ui content with each update (default 1) - var/auto_update_content = 1 - // the default state to use for this ui (this is used on the frontend, leave it as "default" unless you know what you're doing) - var/state_key = "default" - // show the map ui, this is used by the default layout - var/show_map = 0 - // the map z level to display - var/map_z_level = 1 - // initial data, containing the full data structure, must be sent to the ui (the data structure cannot be extended later on) - var/list/initial_data = null // Initialize as null for proper ! usage in initial set up - // set to 1 to update the ui automatically every master_controller tick - var/is_auto_updating = 0 - // the current status/visibility of the ui - var/status = STATUS_INTERACTIVE - - // Relationship between a master interface and its children. Used in update_status - var/datum/nanoui/master_ui - var/list/datum/nanoui/children = list() - var/datum/topic_state/state = null - - /** - * Create a new nanoui instance. - * - * @param nuser /mob The mob who has opened/owns this ui - * @param nsrc_object /obj|/mob The obj or mob which this ui belongs to - * @param nui_key string A string key to use for this ui. Allows for multiple unique uis on one src_oject - * @param ntemplate string The filename of the template file from /nano/templates (e.g. "my_template.tmpl") - * @param ntitle string The title of this ui - * @param nwidth int the width of the ui window - * @param nheight int the height of the ui window - * @param nref /atom A custom ref to use if "on_close_logic" is set to 1 - * - * @return /nanoui new nanoui object - */ -/datum/nanoui/New(nuser, nsrc_object, nui_key, ntemplate_filename, ntitle = 0, nwidth = 0, nheight = 0, var/atom/nref = null, var/datum/nanoui/master_ui = null, var/datum/topic_state/state = GLOB.default_state) - user = nuser - src_object = nsrc_object - ui_key = nui_key - window_id = "[ui_key]\ref[src_object]" - - src.master_ui = master_ui - if(master_ui) - master_ui.children += src - src.state = state - - // add the passed template filename as the "main" template, this is required - add_template("main", ntemplate_filename) - - if(ntitle) - title = ntitle - if(nwidth) - width = nwidth - if(nheight) - height = nheight - if(nref) - ref = nref - - add_common_assets() - - var/datum/asset/assets = get_asset_datum(/datum/asset/nanoui) - assets.send(user, ntemplate_filename) - - /** - * Use this proc to add assets which are common to (and required by) all nano uis - * - * @return nothing - */ -/datum/nanoui/proc/add_common_assets() - add_script("libraries.min.js") // A JS file comprising of jQuery, doT.js and jQuery Timer libraries (compressed together) - add_script("nano.js") // A JS file of the NanoUI JavaScript compressed into one file. - add_stylesheet("nanoui.css") // Concatenated CSS sheet common to all UIs, contains all of the standard NanoUI styling. - - // CodeMirror - add_script("codemirror-compressed.js") // A custom minified JavaScript file of CodeMirror, with the following plugins: CSS Mode, NTSL Mode, CSS-hint addon, Search addon, Sublime Keymap. - - /** - * Set the current status (also known as visibility) of this ui. - * - * @param state int The status to set, see the defines at the top of this file - * @param push_update int (bool) Push an update to the ui to update it's status (an update is always sent if the status has changed to red (0)) - * - * @return nothing - */ -/datum/nanoui/proc/set_status(state, push_update) - if(state != status) // Only update if it is different - if(status == STATUS_DISABLED) - status = state - if(push_update) - update() - else - status = state - if(push_update || status == 0) - push_data(null, 1) // Update the UI, force the update in case the status is 0, data is null so that previous data is used - - /** - * Update the status (visibility) of this ui based on the user's status - * - * @param push_update int (bool) Push an update to the ui to update it's status. This is set to 0/false if an update is going to be pushed anyway (to avoid unnessary updates) - * - * @return nothing - */ -/datum/nanoui/proc/update_status(var/push_update = 0) - var/new_status = src_object.CanUseTopic(user, state) - if(master_ui) - new_status = min(new_status, master_ui.status) - - set_status(new_status, push_update) - if(new_status == STATUS_CLOSE) - close() - - /** - * Set the ui to auto update (every master_controller tick) - * - * @param state int (bool) Set auto update to 1 or 0 (true/false) - * - * @return nothing - */ -/datum/nanoui/proc/set_auto_update(nstate = 1) - is_auto_updating = nstate - - /** - * Set the initial data for the ui. This is vital as the data structure set here cannot be changed when pushing new updates. - * - * @param data /list The list of data for this ui - * - * @return nothing - */ -/datum/nanoui/proc/set_initial_data(list/data) - initial_data = data - - /** - * Get config data to sent to the ui. - * - * @return /list config data - */ -/datum/nanoui/proc/get_config_data() - var/name = "[src_object]" - var/list/config_data = list( - "title" = title, - "map" = (GLOB.using_map && GLOB.using_map.name) ? GLOB.using_map.name : "Unknown", - "srcObject" = list("name" = name), - "stateKey" = state_key, - "status" = status, - "autoUpdateLayout" = auto_update_layout, - "autoUpdateContent" = auto_update_content, - "showMap" = show_map, - "mapZLevel" = map_z_level, - "user" = list( - "name" = user.name, - "fancy" = user.client.prefs.toggles2 & PREFTOGGLE_2_FANCYUI - ), - "window" = list( - "width" = width, - "height" = height, - "ref" = window_id - ) - ) - return config_data - - /** - * Get data to sent to the ui. - * - * @param data /list The list of general data for this ui (can be null to use previous data sent) - * - * @return /list data to send to the ui - */ -/datum/nanoui/proc/get_send_data(var/list/data) - var/list/config_data = get_config_data() - - var/list/send_data = list("config" = config_data) - - if(!isnull(data)) - send_data["data"] = data - - return send_data - - /** - * Set the browser window options for this ui - * - * @param nwindow_options string The new window options - * - * @return nothing - */ -/datum/nanoui/proc/set_window_options(nwindow_options) - window_options = nwindow_options - - /** - * Add a CSS stylesheet to this UI - * These must be added before the UI has been opened, adding after that will have no effect - * - * @param file string The name of the CSS file from /nano/css (e.g. "my_style.css") - * - * @return nothing - */ -/datum/nanoui/proc/add_stylesheet(file) - stylesheets.Add(file) - - /** - * Add a JavsScript script to this UI - * These must be added before the UI has been opened, adding after that will have no effect - * - * @param file string The name of the JavaScript file from /nano/js (e.g. "my_script.js") - * - * @return nothing - */ -/datum/nanoui/proc/add_script(file) - scripts.Add(file) - - /** - * Add a template for this UI - * Templates are combined with the data sent to the UI to create the rendered view - * These must be added before the UI has been opened, adding after that will have no effect - * - * @param key string The key which is used to reference this template in the frontend - * @param filename string The name of the template file from /nano/templates (e.g. "my_template.tmpl") - * - * @return nothing - */ -/datum/nanoui/proc/add_template(key, filename) - templates[key] = filename - - /** - * Set the layout key for use in the frontend Javascript - * The layout key is the basic layout key for the page - * Two files are loaded on the client based on the layout key varable: - * -> a template in /nano/templates with the filename "layout_.tmpl - * -> a CSS stylesheet in /nano/css with the filename "layout_.css - * - * @param nlayout string The layout key to use - * - * @return nothing - */ -/datum/nanoui/proc/set_layout_key(nlayout_key) - layout_key = lowertext(nlayout_key) - - /** - * Set the ui to update the layout (re-render it) on each update, turning this on will break the map ui (if it's being used) - * - * @param state int (bool) Set update to 1 or 0 (true/false) (default 0) - * - * @return nothing - */ -/datum/nanoui/proc/set_auto_update_layout(nstate) - auto_update_layout = nstate - - /** - * Set the ui to update the main content (re-render it) on each update - * - * @param state int (bool) Set update to 1 or 0 (true/false) (default 1) - * - * @return nothing - */ -/datum/nanoui/proc/set_auto_update_content(nstate) - auto_update_content = nstate - - /** - * Set the state key for use in the frontend Javascript - * - * @param nstate_key string The key of the state to use - * - * @return nothing - */ -/datum/nanoui/proc/set_state_key(nstate_key) - state_key = nstate_key - - /** - * Toggle showing the map ui - * - * @param nstate_key boolean 1 to show map, 0 to hide (default is 0) - * - * @return nothing - */ -/datum/nanoui/proc/set_show_map(nstate) - show_map = nstate - - /** - * Toggle showing the map ui - * - * @param nstate_key boolean 1 to show map, 0 to hide (default is 0) - * - * @return nothing - */ -/datum/nanoui/proc/set_map_z_level(nz) - map_z_level = nz - - /** - * Set whether or not to use the "old" on close logic (mainly unset_machine()) - * - * @param state int (bool) Set on_close_logic to 1 or 0 (true/false) - * - * @return nothing - */ -/datum/nanoui/proc/use_on_close_logic(state) - on_close_logic = state - - /** - * Return the HTML for this UI - * - * @return string HTML for the UI - */ -/datum/nanoui/proc/get_html() - - // before the UI opens, add the layout files based on the layout key - add_template("layout", "layout_[layout_key].tmpl") - - var/head_content = "" - - for(var/filename in scripts) - head_content += " " - - for(var/filename in stylesheets) - head_content += " " - - var/template_data_json = "{}" // An empty JSON object - if(templates.len > 0) - template_data_json = json_encode(templates) - - var/list/send_data = get_send_data(initial_data) - var/initial_data_json = replacetext(replacetext(json_encode(send_data), """, "&#34;"), "'", "'") - - var/url_parameters_json = json_encode(list("src" = UID())) - - return {" - - - - - - - [head_content] - - -
-
- - - - "} - - /** - * Open this UI - * - * @return nothing - */ -/datum/nanoui/proc/open() - if(!user.client) - return - - var/window_size = "" - if(width && height) - window_size = "size=[width]x[height];" - - update_status(0) - if(status == STATUS_CLOSE) - return - - if(!initial_data) - set_initial_data(src_object.ui_data(user, ui_key, state)) // Get the UI data. - - // Preset the can_rezie and titlebar values on uis if the user has fancy uis set - // Prevents the ui from flickering when opened - if(user.client.prefs.toggles2 & PREFTOGGLE_2_FANCYUI) - set_window_options("focus=0;can_close=1;can_minimize=1;can_maximize=0;can_resize=0;titlebar=0;") - - user << browse(get_html(), "window=[window_id];[window_size][window_options]") - winset(user, "mapwindow.map", "focus=true") // return keyboard focus to map - on_close_winset() - //onclose(user, window_id) - SSnanoui.ui_opened(src) - -/** - * Reinitialize the UI with - */ -/datum/nanoui/proc/reinitialize(template, list/data) - if(template) - add_template("main", template) - if(data) - set_initial_data(data) - open() - - /** - * Close this UI - * - * @return nothing - */ -/datum/nanoui/proc/close() - is_auto_updating = 0 - SSnanoui.ui_closed(src) - user << browse(null, "window=[window_id]") - for(var/datum/nanoui/child in children) - child.close() - - src_object.on_ui_close(user) - - /** - * Set the UI window to call the nanoclose verb when the window is closed - * This allows Nano to handle closed windows - * - * @return nothing - */ -/datum/nanoui/proc/on_close_winset() - if(!user.client) - return - var/params = "\ref[src]" - - winset(user, window_id, "on-close=\"nanoclose [params]\"") - - /** - * Push data to an already open UI window - * - * @return nothing - */ -/datum/nanoui/proc/push_data(data, force_push = 0) - update_status(0) - if(status == STATUS_DISABLED && !force_push) - return // Cannot update UI, no visibility - - var/list/send_data = get_send_data(data) - -// to_chat(user, list2json_usecache(send_data))// used for debugging //NANO DEBUG HOOK - - user << output(list2params(list(json_encode(send_data))),"[window_id].browser:receiveUpdateData") - - /** - * This Topic() proc is called whenever a user clicks on a link within a Nano UI - * If the UI status is currently STATUS_INTERACTIVE then call the src_object Topic() - * If the src_object Topic() returns 1 (true) then update all UIs attached to src_object - * - * @return nothing - */ -/datum/nanoui/Topic(href, href_list) - update_status(0) // update the status - if(status != STATUS_INTERACTIVE || user != usr) // If UI is not interactive or usr calling Topic is not the UI user - return - - // This is used to toggle the nano map ui - var/map_update = 0 - if(href_list["showMap"]) - set_show_map(text2num(href_list["showMap"])) - map_update = 1 - - if(href_list["mapZLevel"]) - set_map_z_level(text2num(href_list["mapZLevel"])) - map_update = 1 - - if((src_object && src_object.Topic(href, href_list, 0, state)) || map_update) - SSnanoui.update_uis(src_object) // update all UIs attached to src_object - - /** - * Process this UI, updating the entire UI or just the status (aka visibility) - * This process proc is called by the master_controller - * - * @param update string For this UI to update - * - * @return nothing - */ -/datum/nanoui/process(update = 0) - if(!src_object || !user) - close() - return - - if(status && (update || is_auto_updating)) - update() // Update the UI (update_status() is called whenever a UI is updated) - else - update_status(1) // Not updating UI, so lets check here if status has changed - - /** - * Update the UI - * - * @return nothing - */ -/datum/nanoui/proc/update(var/force_open = 0) - src_object.ui_interact(user, ui_key, src, force_open, master_ui, state) diff --git a/code/modules/nano/subsystem.dm b/code/modules/nano/subsystem.dm deleted file mode 100644 index f2f86c02a3c..00000000000 --- a/code/modules/nano/subsystem.dm +++ /dev/null @@ -1,237 +0,0 @@ - /** - * Get an open /nanoui ui for the current user, src_object and ui_key and try to update it with data - * - * @param user /mob The mob who opened/owns the ui - * @param src_object /datum The datum which the ui belongs to - * @param ui_key string A string key used for the ui - * @param ui /datum/nanoui An existing instance of the ui (can be null) - * @param data list The data to be passed to the ui, if it exists - * @param force_open boolean The ui is being forced to (re)open, so close ui if it exists (instead of updating) - * - * @return /nanoui Returns the found ui, for null if none exists - */ -/datum/controller/subsystem/nanoui/proc/try_update_ui(var/mob/user, var/datum/src_object, ui_key, var/datum/nanoui/ui, var/force_open = 0) - if(isnull(ui)) // no ui has been passed, so we'll search for one - ui = get_open_ui(user, src_object, ui_key) - - if(!isnull(ui)) - var/data = src_object.ui_data(user, ui_key, ui.state) // Get data from src_object. - if(!force_open) - ui.push_data(data) - else - ui.reinitialize(null, data) - return ui - return null - - /** - * Get an open /nanoui ui for the current user, src_object and ui_key - * - * @param user /mob The mob who opened/owns the ui - * @param src_object /obj|/mob The obj or mob which the ui belongs to - * @param ui_key string A string key used for the ui - * - * @return /nanoui Returns the found ui, or null if none exists - */ -/datum/controller/subsystem/nanoui/proc/get_open_ui(var/mob/user, src_object, ui_key) - var/src_object_key = "\ref[src_object]" - if(isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list)) - //testing("nanomanager/get_open_ui mob [user.name] [src_object:name] [ui_key] - there are no uis open") - return null - else if(isnull(open_uis[src_object_key][ui_key]) || !istype(open_uis[src_object_key][ui_key], /list)) - //testing("nanomanager/get_open_ui mob [user.name] [src_object:name] [ui_key] - there are no uis open for this object") - return null - - for(var/datum/nanoui/ui in open_uis[src_object_key][ui_key]) - if(ui.user == user) - return ui - - //testing("nanomanager/get_open_ui mob [user.name] [src_object:name] [ui_key] - ui not found") - return null - - /** - * Update all /nanoui uis attached to src_object - * - * @param src_object /obj|/mob The obj or mob which the uis are attached to - * - * @return int The number of uis updated - */ -/datum/controller/subsystem/nanoui/proc/update_uis(src_object) - var/src_object_key = "\ref[src_object]" - if(isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list)) - return 0 - - var/update_count = 0 - for(var/ui_key in open_uis[src_object_key]) - for(var/datum/nanoui/ui in open_uis[src_object_key][ui_key]) - if(ui && ui.src_object && ui.user && ui.src_object.nano_host()) - ui.process(1) - update_count++ - return update_count - - /** - * Close all /nanoui uis attached to src_object - * - * @param src_object /obj|/mob The obj or mob which the uis are attached to - * - * @return int The number of uis close - */ -/datum/controller/subsystem/nanoui/proc/close_uis(src_object) - var/src_object_key = "\ref[src_object]" - if(isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list)) - return 0 - - var/close_count = 0 - for(var/ui_key in open_uis[src_object_key]) - for(var/datum/nanoui/ui in open_uis[src_object_key][ui_key]) - if(ui && ui.src_object && ui.user && ui.src_object.nano_host()) - ui.close() - close_count++ - return close_count - - /** - * private - * - * Close *ALL* UIs - * - * return int The number of UIs closed. - **/ -/datum/controller/subsystem/nanoui/proc/close_all_uis() - var/close_count = 0 - for(var/src_object_key in open_uis) - for(var/ui_key in open_uis[src_object_key]) - for(var/datum/nanoui/ui in open_uis[src_object_key][ui_key]) - if(ui && ui.src_object && ui.user && ui.src_object.nano_host()) // Check the UI is valid. - ui.close() // Close the UI. - close_count++ // Count each UI we close. - return close_count - - /** - * Update /nanoui uis belonging to user - * - * @param user /mob The mob who owns the uis - * @param src_object /obj|/mob If src_object is provided, only update uis which are attached to src_object (optional) - * @param ui_key string If ui_key is provided, only update uis with a matching ui_key (optional) - * - * @return int The number of uis updated - */ -/datum/controller/subsystem/nanoui/proc/update_user_uis(var/mob/user, src_object = null, ui_key = null) - if(isnull(user.open_uis) || !istype(user.open_uis, /list) || open_uis.len == 0) - return 0 // has no open uis - - var/update_count = 0 - for(var/datum/nanoui/ui in user.open_uis) - if((isnull(src_object) || !isnull(src_object) && ui.src_object == src_object) && (isnull(ui_key) || !isnull(ui_key) && ui.ui_key == ui_key)) - ui.process(1) - update_count++ - - return update_count - - /** - * Close /nanoui uis belonging to user - * - * @param user /mob The mob who owns the uis - * @param src_object /obj|/mob If src_object is provided, only close uis which are attached to src_object (optional) - * @param ui_key string If ui_key is provided, only close uis with a matching ui_key (optional) - * - * @return int The number of uis closed - */ -/datum/controller/subsystem/nanoui/proc/close_user_uis(var/mob/user, src_object = null, ui_key = null) - if(isnull(user.open_uis) || !istype(user.open_uis, /list) || open_uis.len == 0) - //testing("nanomanager/close_user_uis mob [user.name] has no open uis") - return 0 // has no open uis - - var/close_count = 0 - for(var/datum/nanoui/ui in user.open_uis) - if((isnull(src_object) || !isnull(src_object) && ui.src_object == src_object) && (isnull(ui_key) || !isnull(ui_key) && ui.ui_key == ui_key)) - ui.close() - close_count++ - - //testing("nanomanager/close_user_uis mob [user.name] closed [open_uis.len] of [close_count] uis") - - return close_count - - /** - * Add a /nanoui ui to the list of open uis - * This is called by the /nanoui open() proc - * - * @param ui /nanoui The ui to add - * - * @return nothing - */ -/datum/controller/subsystem/nanoui/proc/ui_opened(var/datum/nanoui/ui) - var/src_object_key = "\ref[ui.src_object]" - if(isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list)) - open_uis[src_object_key] = list(ui.ui_key = list()) - else if(isnull(open_uis[src_object_key][ui.ui_key]) || !istype(open_uis[src_object_key][ui.ui_key], /list)) - open_uis[src_object_key][ui.ui_key] = list() - - ui.user.open_uis.Add(ui) - var/list/uis = open_uis[src_object_key][ui.ui_key] - uis.Add(ui) - processing_uis.Add(ui) - //testing("nanomanager/ui_opened mob [ui.user.name] [ui.src_object:name] [ui.ui_key] - user.open_uis [ui.user.open_uis.len] | uis [uis.len] | processing_uis [processing_uis.len]") - - /** - * Remove a /nanoui ui from the list of open uis - * This is called by the /nanoui close() proc - * - * @param ui /nanoui The ui to remove - * - * @return int 0 if no ui was removed, 1 if removed successfully - */ -/datum/controller/subsystem/nanoui/proc/ui_closed(var/datum/nanoui/ui) - var/src_object_key = "\ref[ui.src_object]" - if(isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list)) - return 0 // wasn't open - else if(isnull(open_uis[src_object_key][ui.ui_key]) || !istype(open_uis[src_object_key][ui.ui_key], /list)) - return 0 // wasn't open - - processing_uis.Remove(ui) - if(ui.user) // Sanity check in case a user has been deleted (say a blown up borg watching the alarm interface) - ui.user.open_uis.Remove(ui) - var/list/uis = open_uis[src_object_key][ui.ui_key] - uis.Remove(ui) - - //testing("nanomanager/ui_closed mob [ui.user.name] [ui.src_object:name] [ui.ui_key] - user.open_uis [ui.user.open_uis.len] | uis [uis.len] | processing_uis [processing_uis.len]") - - return 1 - - /** - * This is called on user logout - * Closes/clears all uis attached to the user's /mob - * - * @param user /mob The user's mob - * - * @return nothing - */ - -// -/datum/controller/subsystem/nanoui/proc/user_logout(var/mob/user) - //testing("nanomanager/user_logout user [user.name]") - return close_user_uis(user) - - /** - * This is called when a player transfers from one mob to another - * Transfers all open UIs to the new mob - * - * @param oldMob /mob The user's old mob - * @param newMob /mob The user's new mob - * - * @return nothing - */ -/datum/controller/subsystem/nanoui/proc/user_transferred(var/mob/oldMob, var/mob/newMob) - //testing("nanomanager/user_transferred from mob [oldMob.name] to mob [newMob.name]") - if(!oldMob || isnull(oldMob.open_uis) || !istype(oldMob.open_uis, /list) || open_uis.len == 0) - //testing("nanomanager/user_transferred mob [oldMob.name] has no open uis") - return 0 // has no open uis - - if(isnull(newMob.open_uis) || !istype(newMob.open_uis, /list)) - newMob.open_uis = list() - - for(var/datum/nanoui/ui in oldMob.open_uis) - ui.user = newMob - newMob.open_uis.Add(ui) - - oldMob.open_uis.Cut() - - return 1 // success diff --git a/code/modules/pda/app.dm b/code/modules/pda/app.dm index 82047a073c4..bd9a01ca8b0 100644 --- a/code/modules/pda/app.dm +++ b/code/modules/pda/app.dm @@ -35,7 +35,7 @@ if(L) to_chat(L, "[bicon(pda)] [message]") - SSnanoui.update_user_uis(L, pda) // Update the receiving user's PDA UI so that they can see the new message + SStgui.update_user_uis(L, pda) // Update the receiving user's PDA UI so that they can see the new message if(!notify_silent) pda.play_ringtone() diff --git a/code/modules/telesci/gps.dm b/code/modules/telesci/gps.dm index 0d9acc07207..fdd67da76d3 100644 --- a/code/modules/telesci/gps.dm +++ b/code/modules/telesci/gps.dm @@ -38,7 +38,7 @@ GLOBAL_LIST_EMPTY(GPS_list) overlays += "working" /obj/item/gps/AltClick(mob/user) - if(CanUseTopic(user, GLOB.inventory_state) != STATUS_INTERACTIVE) + if(tgui_status(user, GLOB.tgui_inventory_state) != STATUS_INTERACTIVE) return 1 //user not valid to use gps if(emped) to_chat(user, "It's busted!") diff --git a/code/modules/tgui/states/contained.dm b/code/modules/tgui/states/contained.dm index c2fbd0b6b06..15853787d48 100644 --- a/code/modules/tgui/states/contained.dm +++ b/code/modules/tgui/states/contained.dm @@ -10,3 +10,11 @@ GLOBAL_DATUM_INIT(tgui_contained_state, /datum/tgui_state/contained_state, new) if(!src_object.contains(user)) return STATUS_CLOSE return user.shared_tgui_interaction(src_object) + +/atom/proc/contains(atom/location) + if(!location) + return FALSE + if(location == src) + return TRUE + + return contains(location.loc) diff --git a/nano/.gitignore b/nano/.gitignore deleted file mode 100644 index 68b9e27759d..00000000000 --- a/nano/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -node_modules/ -bower_components/ diff --git a/nano/Gulpfile.js b/nano/Gulpfile.js deleted file mode 100644 index 3730c78a862..00000000000 --- a/nano/Gulpfile.js +++ /dev/null @@ -1,212 +0,0 @@ -/* - * NanoUI Buildscript v2.0 - * Fuck the old buildscript edition - */ - -// Node Dependencies -const child_process = require('child_process') -const fs = require('fs-extra') -const path = require('path') - -/* Configuration */ -const INPUT = { - 'fonts': path.join(__dirname, 'node_modules', 'font-awesome', 'fonts', '*.{eot,woff2}'), - 'images': path.join(__dirname, 'images'), - 'styles': { - '_dir': path.join(__dirname, 'styles'), - 'nano': path.join(__dirname, 'styles', 'nanoui.less'), - 'fa': path.join(__dirname, 'node_modules', 'font-awesome', 'less', 'font-awesome.less'), - }, - 'scripts': { - 'lib': path.join(__dirname, 'scripts', 'libraries', '*.js'), - 'main': path.join(__dirname, 'scripts', 'nano', '*.js'), - 'es5shim': path.join(__dirname, 'node_modules', 'es5-shim', 'es5-shim.js'), - 'domurl': path.join(__dirname, 'node_modules', 'domurl', 'url.js'), - }, - 'layouts': path.join(__dirname, 'layouts'), - 'templates': path.join(__dirname, 'templates'), - // The story here is: Fucking shitty ass libraries - 'watch': [ - 'images/**/*', - 'scripts/**/*', - 'styles/**/*', - 'layouts/**/*', - 'templates/**/*' - ] -} - -const OUTPUT = { - '_dir': path.join(__dirname, 'assets'), - 'scripts': { - 'lib': 'libraries.min.js', - 'main': 'nano.js' - } -} - -/*** Gulp Dependencies ***/ -const gulp = require('gulp') -const concat = require('gulp-concat') -const cleancss = require('gulp-clean-css') -const order = require('gulp-order') -const replace = require('gulp-replace') -const postcss = require('gulp-postcss') -const postcssFilters = { - gradient: require('postcss-filter-gradient'), - opacity: require('postcss-opacity'), - rgba: require('postcss-color-rgba-fallback'), - plsfilters: require("pleeease-filters") -} -const sourcemaps = require('gulp-sourcemaps') -const uglify = require('gulp-uglify') -const merge = require('merge-stream') - -const less = require('gulp-less') -var autoprefix = new (require('less-plugin-autoprefix'))({ browsers: ['IE 8-11'] }) - -/*** Tasks ***/ - -/* Task: Clean - * Type: Build-Dep - * This empties the output directory to prepare for new files. By default, this is nano/assets/. - */ -function clean(cb) { - fs.emptyDir(OUTPUT._dir, function (err) { - if (err) - return console.error(err) - cb() - }) -} - -/* Task: CSS - * Type: Build-Step - * This compiles all of the LESS styles we require and runs a few IE-friendly CSS filters over the output. - */ -function css() { - // Get both of our LESS components - let faLESS = gulp.src(INPUT.styles.fa) - let nanoLESS = gulp.src(INPUT.styles.nano) - - // Then haphazardly smash them together and hope it works out - return merge(faLESS, nanoLESS) - .pipe(sourcemaps.init()) - .pipe(less({ - plugins: [autoprefix], - paths: [INPUT.images] - })) - .pipe(replace('../fonts/', '')) - .pipe(concat('nanoui.css')) - .pipe(postcss([ // IE8+ support garbage - postcssFilters.gradient, - postcssFilters.opacity, - postcssFilters.rgba, - postcssFilters.plsfilters({oldIE: true}) - ])) - .pipe(cleancss({ - compatibility: 'ie8', - level: { - 1: { - all: false, - cleanupCharsets: true, - specialComments: 0 - } - } - })) - .pipe(sourcemaps.write()) // Hey look sourcemaps that IE can't use (piece of shit) - .pipe(gulp.dest(OUTPUT._dir)) -} - -/* Task: JS - * Type: Build-Step - * This builds both our libraries and nano JS files. It uglifies them for performance. - */ -function js() { - let lib = gulp.src(INPUT.scripts.lib) - let es5shim = gulp.src(INPUT.scripts.es5shim) - let domurl = gulp.src(INPUT.scripts.domurl) - - // Combine all of the library scripts into one file - merge(lib, es5shim, domurl) - .pipe(order(["jquery.js", "jquery*.js", "*.js"])) // Make sure jQuery is the first damn thing in there - .pipe(concat(OUTPUT.scripts.lib)) - .pipe(sourcemaps.init()) - .pipe(uglify()) - .pipe(sourcemaps.write()) - .pipe(gulp.dest(OUTPUT._dir)) - - // Combine all of the nano scripts into one - return gulp.src(INPUT.scripts.main) - .pipe(order(["nano_utility.js", "nano_state_manager.js", "*.js"])) // Ensure Nano Util and state manager are always loaded first - .pipe(concat(OUTPUT.scripts.main)) - .pipe(sourcemaps.init()) - .pipe(uglify()) - .pipe(sourcemaps.write()) - .pipe(gulp.dest(OUTPUT._dir)) -} - -/* Task: Fonts - * Type: Build-Step - * This literally just copy-pastes the FontAwesome fonts into the build directory. We need them there. - * If we ever use any other icon fonts (e.x. Material Icons), copy their asses here too. - */ -function fonts() { - return gulp.src(INPUT.fonts) - .pipe(gulp.dest(OUTPUT._dir)) -} - -/* Task: Reload - * Type: Main - * This injects all the changed files directly into the client cache. - */ -function reload(cb) { - child_process.exec("reload.bat", function (err, stdout) { - if (err) - throw err - var byond_cache = path.join(stdout.trim(), "BYOND", "cache") - var files = fs.readdirSync(byond_cache) - for (let file of files) { - let filepath = path.join(byond_cache, file) - let stats = fs.statSync(filepath) - if (file.startsWith("tmp") && stats.isDirectory()) { - var tmpFiles = fs.readdirSync(filepath) - if (tmpFiles.includes(OUTPUT.scripts.main)) { - setTimeout(function () {transfer_files(filepath)}, 500) - } - } - } - cb() - }) -} - -function transfer_files(target) { - let transfer = [INPUT.images, INPUT.layouts, INPUT.templates, OUTPUT._dir] - for (let trf of transfer) { - let files = fs.readdirSync(trf) - for (let file of files) { - let fileData = fs.statSync(path.join(trf, file)) - if (fileData.isFile()) - transfer_file(path.join(trf, file), path.join(target, file)) - } - } -} -function transfer_file(input, target) { - fs.createReadStream(input).pipe(fs.createWriteStream(target)) -} - -/* Task: Watch - * Type: Main - * This is just an alias to trigger all the gulp watch shit - */ -function watch(cb) { - // Alright, so here's some fucking stupid bullshit we have to work around: - // Gulp 4.0 uses an updated version of chokidar for watching files. - // This version of chokidar doesn't fucking support windows path seperators. - // So, we have to only use relative paths with forward slashes. - let watchTask = gulp.series(exports.default, reload) - // Watch files. - gulp.watch(INPUT.watch, watchTask) - cb() -} - -/* This shit is a Gulp v4 design. You use exports to define tasks now, instead of gulp.tasks. */ -exports.default = gulp.series(clean, gulp.parallel(css, js, fonts)) -exports.watch = watch \ No newline at end of file diff --git a/nano/README.md b/nano/README.md deleted file mode 100644 index 0732d7d2bd9..00000000000 --- a/nano/README.md +++ /dev/null @@ -1,107 +0,0 @@ -# NanoUI - -NanoUI is a user interface library, used for over 100 different interfaces, and rising. -It is more complicated than the other two UI systems in use, the `/datum/browser` and -`browse()` systems, but offers pre-made libraries, JavaScript, and a modified doT -template engine. - -This README is not yet complete, but gives a basic rundown of how the folder structure -works. I'll get around to finishing it one day. - -## Contributors - -This section is for listing the contributors to NanoUI. - - - -tg-station/Neersighted - - Special thanks goes to Neersighted for creating most of the newest and best features - of NanoUI. Everything between using the Gulp build system to switching to LESS styles - has been directly adapated and/or copied from his original work for -tg-station and - their UI system, tgui. - - Systems ported/adapted from -tg-station and Neersighted include, but are not limited - to: - - - NanoUI's JavaScript controlling the "fancy" borderless window mode. - - The NanoTrasen.svg logo (Licensed under CC 3.0 BY-SA). - - The packages in bower.json and packages.json files were hand-picked by Neersighted - for usage in compiling NanoUI. - - A considerable amount of this README is adapated from Neersighted's documentation. - - The concepts following: Using FontAwesome instead of icon16, Using LESS to expand - NanoUI's CSS style. - -NanoUI is licensed under AGPLv3. This applies to it's serverside `DM` code as well as it's -clientside `JavaScript` and `LESS` code. The file `nano/images/nanotrasen.svg` is licensed -under CC 3.0 BY-SA, and was created by Neersighted. All other image files in the -`nano/images/` directory are subject to the standard image license applied to the Paradise -repository icons. - -## Folder Rundown - -### /assets -The assets folder is used by the Gulp compiling system, and stores the minified version of -the NanoUI JavaScript Library and prerequisites. Everything within this folder is sent to -the client as-is. - -### /codemirror -This folder contains all of the JavaScript and CSS for CodeMirror. It is sent to the -client as-is. CodeMirror only has it's own folder due to the fact that it can't be -directly compiled into the NanoUI files. - -### /images -This folder is used to store any image files. It is sent to the client as-is. - -### /layouts -This folder is used for the central "layout" template files, which is loaded before the -UI's actual template file. It is sent to the client as-is. - -### /scripts -This folder is used for anything that will be compiled by the Gulp compilation system. -Currently, it is split into two folders. The file names must start with a number, as this -is how Gulp decides what order to put the concatenated and possibly minified files in. -Anything within this folder is not sent to the client directly. - -#### /scripts/libraries -This folder is used to store the source code of the prerequisites of NanoUI. Currently, -it contains jQuery, jQuery UI, jQuery timers, and the doT template system. - -#### /scripts/nano -This folder contains the primary JavaScript for NanoUI. - -### /styles -This folder is used for NanoUI's LESS styles. These are compiled via gulp into the file -`nanoui.css`. LESS is a system that expands upon CSS in order to make it better, as well -as less complicated. - -Any LESS file that is prefixed with the `_` character will be ignored during compilation. -These files are still included, however, via `@import`, view the file -[`nanoui.less`](http://github.com/ParadiseSS13/Paradise/blob/master/nano/styles/nanoui.less) to see how this works. - - -### /templates -This folder is used to store the .tmpl files which are later compiled by the NanoUtility -JavaScript, using a modified version of the doT template engine. It is sent to the client -as-is. - -## Compiling -To compile any changes to the NanoUI JavaScript, you must first setup the building -environment. - -### Prerequisites -You will first need to install the primary prerequisite of NanoUI, [Node.js](https://nodejs.org). - -If you don't want to rip out all of your hair and you're on Windows, you should also have some linux-emulating terminal. -The easiest to install, and something you can use for managing this git repo, is [git-scm](https://git-scm.com/) - -Node.js is used to obtain all of the remaining prerequisites to compile NanoUI. This is -done by running the following commands. - - `npm install -g gulp-cli` - - `npm install` - -### Running Gulp -NanoUI is built using the `gulp` task automation system. This system uses the contents -of the `Gulpfile.js` file to perform compilation tasks. - -In order to build an un-minified version of NanoUI, you may simply run `gulp` in the -`nanoui` directory. However, this should only be used while testing, and you should run -the command `gulp --min` before commiting changes, in order to produce minified -JavaScript. diff --git a/nano/assets/fontawesome-webfont.eot b/nano/assets/fontawesome-webfont.eot deleted file mode 100644 index e9f60ca953f..00000000000 Binary files a/nano/assets/fontawesome-webfont.eot and /dev/null differ diff --git a/nano/assets/fontawesome-webfont.woff2 b/nano/assets/fontawesome-webfont.woff2 deleted file mode 100644 index 4d13fc60404..00000000000 Binary files a/nano/assets/fontawesome-webfont.woff2 and /dev/null differ diff --git a/nano/assets/libraries.min.js b/nano/assets/libraries.min.js deleted file mode 100644 index 7dff02479a9..00000000000 --- a/nano/assets/libraries.min.js +++ /dev/null @@ -1,2 +0,0 @@ -!function(e,t){"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(d,e){function t(e,t){return t.toUpperCase()}var f=[],c=f.slice,g=f.concat,a=f.push,r=f.indexOf,n={},i=n.toString,m=n.hasOwnProperty,v={},o="1.11.3",C=function(e,t){return new C.fn.init(e,t)},s=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,l=/^-ms-/,u=/-([\da-z])/gi;function p(e){var t="length"in e&&e.length,n=C.type(e);return"function"!==n&&!C.isWindow(e)&&(!(1!==e.nodeType||!t)||("array"===n||0===t||"number"==typeof t&&0>10|55296,1023&i|56320)}function i(){v()}var e,d,x,o,r,g,p,m,w,u,c,v,T,s,y,b,a,h,C,_="sizzle"+ +new Date,E=n.document,S=0,N=0,l=oe(),D=oe(),k=oe(),j=function(e,t){return e===t&&(c=!0),0},A={}.hasOwnProperty,t=[],P=t.pop,H=t.push,M=t.push,L=t.slice,O=function(e,t){for(var n=0,i=e.length;n+~]|"+F+")"+F+"*"),Y=new RegExp("="+F+"*([^\\]'\"]*?)"+F+"*\\]","g"),Q=new RegExp($),J=new RegExp("^"+q+"$"),V={ID:new RegExp("^#("+W+")"),CLASS:new RegExp("^\\.("+W+")"),TAG:new RegExp("^("+W.replace("w","w*")+")"),ATTR:new RegExp("^"+R),PSEUDO:new RegExp("^"+$),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+F+"*(even|odd|(([+-]|)(\\d*)n|)"+F+"*(?:([+-]|)"+F+"*(\\d+)|))"+F+"*\\)|)","i"),bool:new RegExp("^(?:"+I+")$","i"),needsContext:new RegExp("^"+F+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+F+"*((?:-\\d)?\\d*)"+F+"*\\)|)(?=[^-]|$)","i")},G=/^(?:input|select|textarea|button)$/i,K=/^h\d$/i,Z=/^[^{]+\{\s*\[native \w/,ee=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,te=/[+~]/,ne=/'|\\/g,ie=new RegExp("\\\\([\\da-f]{1,6}"+F+"?|("+F+")|.)","ig");try{M.apply(t=L.call(E.childNodes),E.childNodes),t[E.childNodes.length].nodeType}catch(e){M={apply:t.length?function(e,t){H.apply(e,L.call(t))}:function(e,t){for(var n=e.length,i=0;e[n++]=t[i++];);e.length=n-1}}}function re(e,t,n,i){var r,o,s,a,l,u,c,f,p,h;if((t?t.ownerDocument||t:E)!==T&&v(t),n=n||[],a=(t=t||T).nodeType,"string"!=typeof e||!e||1!==a&&9!==a&&11!==a)return n;if(!i&&y){if(11!==a&&(r=ee.exec(e)))if(s=r[1]){if(9===a){if(!(o=t.getElementById(s))||!o.parentNode)return n;if(o.id===s)return n.push(o),n}else if(t.ownerDocument&&(o=t.ownerDocument.getElementById(s))&&C(t,o)&&o.id===s)return n.push(o),n}else{if(r[2])return M.apply(n,t.getElementsByTagName(e)),n;if((s=r[3])&&d.getElementsByClassName)return M.apply(n,t.getElementsByClassName(s)),n}if(d.qsa&&(!b||!b.test(e))){if(f=c=_,p=t,h=1!==a&&e,1===a&&"object"!==t.nodeName.toLowerCase()){for(u=g(e),(c=t.getAttribute("id"))?f=c.replace(ne,"\\$&"):t.setAttribute("id",f),f="[id='"+f+"'] ",l=u.length;l--;)u[l]=f+ge(u[l]);p=te.test(e)&&he(t.parentNode)||t,h=u.join(",")}if(h)try{return M.apply(n,p.querySelectorAll(h)),n}catch(e){}finally{c||t.removeAttribute("id")}}}return m(e.replace(z,"$1"),t,n,i)}function oe(){var i=[];return function e(t,n){return i.push(t+" ")>x.cacheLength&&delete e[i.shift()],e[t+" "]=n}}function se(e){return e[_]=!0,e}function ae(e){var t=T.createElement("div");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function le(e,t){for(var n=e.split("|"),i=e.length;i--;)x.attrHandle[n[i]]=t}function ue(e,t){var n=t&&e,i=n&&1===e.nodeType&&1===t.nodeType&&(~t.sourceIndex||1<<31)-(~e.sourceIndex||1<<31);if(i)return i;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function ce(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function fe(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function pe(s){return se(function(o){return o=+o,se(function(e,t){for(var n,i=s([],e.length,o),r=i.length;r--;)e[n=i[r]]&&(e[n]=!(t[n]=e[n]))})})}function he(e){return e&&void 0!==e.getElementsByTagName&&e}for(e in d=re.support={},r=re.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return!!t&&"HTML"!==t.nodeName},v=re.setDocument=function(e){var t,n,l=e?e.ownerDocument||e:E;return l!==T&&9===l.nodeType&&l.documentElement?(s=(T=l).documentElement,(n=l.defaultView)&&n!==n.top&&(n.addEventListener?n.addEventListener("unload",i,!1):n.attachEvent&&n.attachEvent("onunload",i)),y=!r(l),d.attributes=ae(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ae(function(e){return e.appendChild(l.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=Z.test(l.getElementsByClassName),d.getById=ae(function(e){return s.appendChild(e).id=_,!l.getElementsByName||!l.getElementsByName(_).length}),d.getById?(x.find.ID=function(e,t){if(void 0!==t.getElementById&&y){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},x.filter.ID=function(e){var t=e.replace(ie,f);return function(e){return e.getAttribute("id")===t}}):(delete x.find.ID,x.filter.ID=function(e){var n=e.replace(ie,f);return function(e){var t=void 0!==e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}}),x.find.TAG=d.getElementsByTagName?function(e,t){return void 0!==t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,i=[],r=0,o=t.getElementsByTagName(e);if("*"!==e)return o;for(;n=o[r++];)1===n.nodeType&&i.push(n);return i},x.find.CLASS=d.getElementsByClassName&&function(e,t){if(y)return t.getElementsByClassName(e)},a=[],b=[],(d.qsa=Z.test(l.querySelectorAll))&&(ae(function(e){s.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&b.push("[*^$]="+F+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||b.push("\\["+F+"*(?:value|"+I+")"),e.querySelectorAll("[id~="+_+"-]").length||b.push("~="),e.querySelectorAll(":checked").length||b.push(":checked"),e.querySelectorAll("a#"+_+"+*").length||b.push(".#.+[+~]")}),ae(function(e){var t=l.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&b.push("name"+F+"*[*^$|!~]?="),e.querySelectorAll(":enabled").length||b.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),b.push(",.*:")})),(d.matchesSelector=Z.test(h=s.matches||s.webkitMatchesSelector||s.mozMatchesSelector||s.oMatchesSelector||s.msMatchesSelector))&&ae(function(e){d.disconnectedMatch=h.call(e,"div"),h.call(e,"[s!='']:x"),a.push("!=",$)}),b=b.length&&new RegExp(b.join("|")),a=a.length&&new RegExp(a.join("|")),t=Z.test(s.compareDocumentPosition),C=t||Z.test(s.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,i=t&&t.parentNode;return e===i||!(!i||1!==i.nodeType||!(n.contains?n.contains(i):e.compareDocumentPosition&&16&e.compareDocumentPosition(i)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return c=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e===l||e.ownerDocument===E&&C(E,e)?-1:t===l||t.ownerDocument===E&&C(E,t)?1:u?O(u,e)-O(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return c=!0,0;var n,i=0,r=e.parentNode,o=t.parentNode,s=[e],a=[t];if(!r||!o)return e===l?-1:t===l?1:r?-1:o?1:u?O(u,e)-O(u,t):0;if(r===o)return ue(e,t);for(n=e;n=n.parentNode;)s.unshift(n);for(n=t;n=n.parentNode;)a.unshift(n);for(;s[i]===a[i];)i++;return i?ue(s[i],a[i]):s[i]===E?-1:a[i]===E?1:0},l):T},re.matches=function(e,t){return re(e,null,null,t)},re.matchesSelector=function(e,t){if((e.ownerDocument||e)!==T&&v(e),t=t.replace(Y,"='$1']"),d.matchesSelector&&y&&(!a||!a.test(t))&&(!b||!b.test(t)))try{var n=h.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(ie,f),e[3]=(e[3]||e[4]||e[5]||"").replace(ie,f),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||re.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&re.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return V.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&Q.test(n)&&(t=g(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(ie,f).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=l[e+" "];return t||(t=new RegExp("(^|"+F+")"+e+"("+F+"|$)"))&&l(e,function(e){return t.test("string"==typeof e.className&&e.className||void 0!==e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,i,r){return function(e){var t=re.attr(e,n);return null==t?"!="===i:!i||(t+="","="===i?t===r:"!="===i?t!==r:"^="===i?r&&0===t.indexOf(r):"*="===i?r&&-1(?:<\/\1>|)$/,x=/^.[^:#\[\.,]*$/;function w(e,n,i){if(C.isFunction(n))return C.grep(e,function(e,t){return!!n.call(e,t,e)!==i});if(n.nodeType)return C.grep(e,function(e){return e===n!==i});if("string"==typeof n){if(x.test(n))return C.filter(n,e,i);n=C.filter(n,e)}return C.grep(e,function(e){return 0<=C.inArray(e,n)!==i})}C.filter=function(e,t,n){var i=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===i.nodeType?C.find.matchesSelector(i,e)?[i]:[]:C.find.matches(e,C.grep(t,function(e){return 1===e.nodeType}))},C.fn.extend({find:function(e){var t,n=[],i=this,r=i.length;if("string"!=typeof e)return this.pushStack(C(e).filter(function(){for(t=0;t)[^>]*|#([\w-]*))$/;(C.fn.init=function(e,t){var n,i;if(!e)return this;if("string"!=typeof e)return e.nodeType?(this.context=this[0]=e,this.length=1,this):C.isFunction(e)?void 0!==T.ready?T.ready(e):e(C):(void 0!==e.selector&&(this.selector=e.selector,this.context=e.context),C.makeArray(e,this));if(!(n="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&3<=e.length?[null,e,null]:E.exec(e))||!n[1]&&t)return!t||t.jquery?(t||T).find(e):this.constructor(t).find(e);if(n[1]){if(t=t instanceof C?t[0]:t,C.merge(this,C.parseHTML(n[1],t&&t.nodeType?t.ownerDocument||t:_,!0)),b.test(n[1])&&C.isPlainObject(t))for(n in t)C.isFunction(this[n])?this[n](t[n]):this.attr(n,t[n]);return this}if((i=_.getElementById(n[2]))&&i.parentNode){if(i.id!==n[2])return T.find(e);this.length=1,this[0]=i}return this.context=_,this.selector=e,this}).prototype=C.fn,T=C(_);var S=/^(?:parents|prev(?:Until|All))/,N={children:!0,contents:!0,next:!0,prev:!0};function D(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}C.extend({dir:function(e,t,n){for(var i=[],r=e[t];r&&9!==r.nodeType&&(void 0===n||1!==r.nodeType||!C(r).is(n));)1===r.nodeType&&i.push(r),r=r[t];return i},sibling:function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}}),C.fn.extend({has:function(e){var t,n=C(e,this),i=n.length;return this.filter(function(){for(t=0;t
a",v.leadingWhitespace=3===t.firstChild.nodeType,v.tbody=!t.getElementsByTagName("tbody").length,v.htmlSerialize=!!t.getElementsByTagName("link").length,v.html5Clone="<:nav>"!==_.createElement("nav").cloneNode(!0).outerHTML,e.type="checkbox",e.checked=!0,n.appendChild(e),v.appendChecked=e.checked,t.innerHTML="",v.noCloneChecked=!!t.cloneNode(!0).lastChild.defaultValue,n.appendChild(t),t.innerHTML="",v.checkClone=t.cloneNode(!0).cloneNode(!0).lastChild.checked,v.noCloneEvent=!0,t.attachEvent&&(t.attachEvent("onclick",function(){v.noCloneEvent=!1}),t.cloneNode(!0).click()),null==v.deleteExpando){v.deleteExpando=!0;try{delete t.test}catch(e){v.deleteExpando=!1}}}(),function(){var e,t,n=_.createElement("div");for(e in{submit:!0,change:!0,focusin:!0})t="on"+e,(v[e+"Bubbles"]=t in d)||(n.setAttribute(t,"t"),v[e+"Bubbles"]=!1===n.attributes[t].expando);n=null}();var Y=/^(?:input|select|textarea)$/i,Q=/^key/,J=/^(?:mouse|pointer|contextmenu)|click/,V=/^(?:focusinfocus|focusoutblur)$/,G=/^([^.]*)(?:\.(.+)|)$/;function K(){return!0}function Z(){return!1}function ee(){try{return _.activeElement}catch(e){}}function te(e){var t=ne.split("|"),n=e.createDocumentFragment();if(n.createElement)for(;t.length;)n.createElement(t.pop());return n}C.event={global:{},add:function(e,t,n,i,r){var o,s,a,l,u,c,f,p,h,d,g,m=C._data(e);if(m){for(n.handler&&(n=(l=n).handler,r=l.selector),n.guid||(n.guid=C.guid++),(s=m.events)||(s=m.events={}),(c=m.handle)||((c=m.handle=function(e){return typeof C===L||e&&C.event.triggered===e.type?void 0:C.event.dispatch.apply(c.elem,arguments)}).elem=e),a=(t=(t||"").match(j)||[""]).length;a--;)h=g=(o=G.exec(t[a])||[])[1],d=(o[2]||"").split(".").sort(),h&&(u=C.event.special[h]||{},h=(r?u.delegateType:u.bindType)||h,u=C.event.special[h]||{},f=C.extend({type:h,origType:g,data:i,handler:n,guid:n.guid,selector:r,needsContext:r&&C.expr.match.needsContext.test(r),namespace:d.join(".")},l),(p=s[h])||((p=s[h]=[]).delegateCount=0,u.setup&&!1!==u.setup.call(e,i,d,c)||(e.addEventListener?e.addEventListener(h,c,!1):e.attachEvent&&e.attachEvent("on"+h,c))),u.add&&(u.add.call(e,f),f.handler.guid||(f.handler.guid=n.guid)),r?p.splice(p.delegateCount++,0,f):p.push(f),C.event.global[h]=!0);e=null}},remove:function(e,t,n,i,r){var o,s,a,l,u,c,f,p,h,d,g,m=C.hasData(e)&&C._data(e);if(m&&(c=m.events)){for(u=(t=(t||"").match(j)||[""]).length;u--;)if(h=g=(a=G.exec(t[u])||[])[1],d=(a[2]||"").split(".").sort(),h){for(f=C.event.special[h]||{},p=c[h=(i?f.delegateType:f.bindType)||h]||[],a=a[2]&&new RegExp("(^|\\.)"+d.join("\\.(?:.*\\.|)")+"(\\.|$)"),l=o=p.length;o--;)s=p[o],!r&&g!==s.origType||n&&n.guid!==s.guid||a&&!a.test(s.namespace)||i&&i!==s.selector&&("**"!==i||!s.selector)||(p.splice(o,1),s.selector&&p.delegateCount--,f.remove&&f.remove.call(e,s));l&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,d,m.handle)||C.removeEvent(e,h,m.handle),delete c[h])}else for(h in c)C.event.remove(e,h+t[u],n,i,!0);C.isEmptyObject(c)&&(delete m.handle,C._removeData(e,"events"))}},trigger:function(e,t,n,i){var r,o,s,a,l,u,c,f=[n||_],p=m.call(e,"type")?e.type:e,h=m.call(e,"namespace")?e.namespace.split("."):[];if(s=u=n=n||_,3!==n.nodeType&&8!==n.nodeType&&!V.test(p+C.event.triggered)&&(0<=p.indexOf(".")&&(p=(h=p.split(".")).shift(),h.sort()),o=p.indexOf(":")<0&&"on"+p,(e=e[C.expando]?e:new C.Event(p,"object"==typeof e&&e)).isTrigger=i?2:3,e.namespace=h.join("."),e.namespace_re=e.namespace?new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,e.result=void 0,e.target||(e.target=n),t=null==t?[e]:C.makeArray(t,[e]),l=C.event.special[p]||{},i||!l.trigger||!1!==l.trigger.apply(n,t))){if(!i&&!l.noBubble&&!C.isWindow(n)){for(a=l.delegateType||p,V.test(a+p)||(s=s.parentNode);s;s=s.parentNode)f.push(s),u=s;u===(n.ownerDocument||_)&&f.push(u.defaultView||u.parentWindow||d)}for(c=0;(s=f[c++])&&!e.isPropagationStopped();)e.type=1]","i"),oe=/^\s+/,se=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,ae=/<([\w:]+)/,le=/\s*$/g,ge={option:[1,""],legend:[1,"
","
"],area:[1,"",""],param:[1,"",""],thead:[1,"","
"],tr:[2,"","
"],col:[2,"","
"],td:[3,"","
"],_default:v.htmlSerialize?[0,"",""]:[1,"X
","
"]},me=te(_).appendChild(_.createElement("div"));function ve(e,t){var n,i,r=0,o=typeof e.getElementsByTagName!==L?e.getElementsByTagName(t||"*"):typeof e.querySelectorAll!==L?e.querySelectorAll(t||"*"):void 0;if(!o)for(o=[],n=e.childNodes||e;null!=(i=n[r]);r++)!t||C.nodeName(i,t)?o.push(i):C.merge(o,ve(i,t));return void 0===t||t&&C.nodeName(e,t)?C.merge([e],o):o}function ye(e){X.test(e.type)&&(e.defaultChecked=e.checked)}function be(e,t){return C.nodeName(e,"table")&&C.nodeName(11!==t.nodeType?t:t.firstChild,"tr")?e.getElementsByTagName("tbody")[0]||e.appendChild(e.ownerDocument.createElement("tbody")):e}function xe(e){return e.type=(null!==C.find.attr(e,"type"))+"/"+e.type,e}function we(e){var t=he.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function Te(e,t){for(var n,i=0;null!=(n=e[i]);i++)C._data(n,"globalEval",!t||C._data(t[i],"globalEval"))}function Ce(e,t){if(1===t.nodeType&&C.hasData(e)){var n,i,r,o=C._data(e),s=C._data(t,o),a=o.events;if(a)for(n in delete s.handle,s.events={},a)for(i=0,r=a[n].length;i")?o=e.cloneNode(!0):(me.innerHTML=e.outerHTML,me.removeChild(o=me.firstChild)),!(v.noCloneEvent&&v.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||C.isXMLDoc(e)))for(i=ve(o),a=ve(e),s=0;null!=(r=a[s]);++s)i[s]&&_e(r,i[s]);if(t)if(n)for(a=a||ve(e),i=i||ve(o),s=0;null!=(r=a[s]);s++)Ce(r,i[s]);else Ce(e,o);return 0<(i=ve(o,"script")).length&&Te(i,!l&&ve(e,"script")),i=a=r=null,o},buildFragment:function(e,t,n,i){for(var r,o,s,a,l,u,c,f=e.length,p=te(t),h=[],d=0;d")+c[2],r=c[0];r--;)a=a.lastChild;if(!v.leadingWhitespace&&oe.test(o)&&h.push(t.createTextNode(oe.exec(o)[0])),!v.tbody)for(r=(o="table"!==l||le.test(o)?""!==c[1]||le.test(o)?0:a:a.firstChild)&&o.childNodes.length;r--;)C.nodeName(u=o.childNodes[r],"tbody")&&!u.childNodes.length&&o.removeChild(u);for(C.merge(h,a.childNodes),a.textContent="";a.firstChild;)a.removeChild(a.firstChild);a=p.lastChild}else h.push(t.createTextNode(o));for(a&&p.removeChild(a),v.appendChecked||C.grep(ve(h,"input"),ye),d=0;o=h[d++];)if((!i||-1===C.inArray(o,i))&&(s=C.contains(o.ownerDocument,o),a=ve(p.appendChild(o),"script"),s&&Te(a),n))for(r=0;o=a[r++];)pe.test(o.type||"")&&n.push(o);return a=null,p},cleanData:function(e,t){for(var n,i,r,o,s=0,a=C.expando,l=C.cache,u=v.deleteExpando,c=C.event.special;null!=(n=e[s]);s++)if((t||C.acceptData(n))&&(o=(r=n[a])&&l[r])){if(o.events)for(i in o.events)c[i]?C.event.remove(n,i):C.removeEvent(n,i,o.handle);l[r]&&(delete l[r],u?delete n[a]:typeof n.removeAttribute!==L?n.removeAttribute(a):n[a]=null,f.push(r))}}}),C.fn.extend({text:function(e){return U(this,function(e){return void 0===e?C.text(this):this.empty().append((this[0]&&this[0].ownerDocument||_).createTextNode(e))},null,e,arguments.length)},append:function(){return this.domManip(arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||be(this,e).appendChild(e)})},prepend:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=be(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},remove:function(e,t){for(var n,i=e?C.filter(e,this):this,r=0;null!=(n=i[r]);r++)t||1!==n.nodeType||C.cleanData(ve(n)),n.parentNode&&(t&&C.contains(n.ownerDocument,n)&&Te(ve(n,"script")),n.parentNode.removeChild(n));return this},empty:function(){for(var e,t=0;null!=(e=this[t]);t++){for(1===e.nodeType&&C.cleanData(ve(e,!1));e.firstChild;)e.removeChild(e.firstChild);e.options&&C.nodeName(e,"select")&&(e.options.length=0)}return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return C.clone(this,e,t)})},html:function(e){return U(this,function(e){var t=this[0]||{},n=0,i=this.length;if(void 0===e)return 1===t.nodeType?t.innerHTML.replace(ie,""):void 0;if("string"==typeof e&&!ce.test(e)&&(v.htmlSerialize||!re.test(e))&&(v.leadingWhitespace||!oe.test(e))&&!ge[(ae.exec(e)||["",""])[1].toLowerCase()]){e=e.replace(se,"<$1>");try{for(;n")).appendTo(t.documentElement))[0].contentWindow||Ee[0].contentDocument).document).write(),t.close(),n=De(e,t),Ee.detach()),Ne[e]=n),n}v.shrinkWrapBlocks=function(){return null!=Se?Se:(Se=!1,(t=_.getElementsByTagName("body")[0])&&t.style?(e=_.createElement("div"),(n=_.createElement("div")).style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",t.appendChild(n).appendChild(e),typeof e.style.zoom!==L&&(e.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1",e.appendChild(_.createElement("div")).style.width="5px",Se=3!==e.offsetWidth),t.removeChild(n),Se):void 0);var e,t,n};var je,Ae,Pe,He,Me,Le,Oe,Ie,Fe,We=/^margin/,qe=new RegExp("^("+B+")(?!px)[a-z%]+$","i"),Re=/^(top|right|bottom|left)$/;function $e(t,n){return{get:function(){var e=t();if(null!=e){if(!e)return(this.get=n).apply(this,arguments);delete this.get}}}}function Be(){var e,t,n,i;(t=_.getElementsByTagName("body")[0])&&t.style&&(e=_.createElement("div"),(n=_.createElement("div")).style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",t.appendChild(n).appendChild(e),e.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;margin-top:1%;top:1%;border:1px;padding:1px;width:4px;position:absolute",Le=Oe=!1,Fe=!0,d.getComputedStyle&&(Le="1%"!==(d.getComputedStyle(e,null)||{}).top,Oe="4px"===(d.getComputedStyle(e,null)||{width:"4px"}).width,(i=e.appendChild(_.createElement("div"))).style.cssText=e.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",i.style.marginRight=i.style.width="0",e.style.width="1px",Fe=!parseFloat((d.getComputedStyle(i,null)||{}).marginRight),e.removeChild(i)),e.innerHTML="
t
",(i=e.getElementsByTagName("td"))[0].style.cssText="margin:0;border:0;padding:0;display:none",(Ie=0===i[0].offsetHeight)&&(i[0].style.display="",i[1].style.display="none",Ie=0===i[0].offsetHeight),t.removeChild(n))}d.getComputedStyle?(je=function(e){return e.ownerDocument.defaultView.opener?e.ownerDocument.defaultView.getComputedStyle(e,null):d.getComputedStyle(e,null)},Ae=function(e,t,n){var i,r,o,s,a=e.style;return s=(n=n||je(e))?n.getPropertyValue(t)||n[t]:void 0,n&&(""!==s||C.contains(e.ownerDocument,e)||(s=C.style(e,t)),qe.test(s)&&We.test(t)&&(i=a.width,r=a.minWidth,o=a.maxWidth,a.minWidth=a.maxWidth=a.width=s,s=n.width,a.width=i,a.minWidth=r,a.maxWidth=o)),void 0===s?s:s+""}):_.documentElement.currentStyle&&(je=function(e){return e.currentStyle},Ae=function(e,t,n){var i,r,o,s,a=e.style;return null==(s=(n=n||je(e))?n[t]:void 0)&&a&&a[t]&&(s=a[t]),qe.test(s)&&!Re.test(t)&&(i=a.left,(o=(r=e.runtimeStyle)&&r.left)&&(r.left=e.currentStyle.left),a.left="fontSize"===t?"1em":s,s=a.pixelLeft+"px",a.left=i,o&&(r.left=o)),void 0===s?s:s+""||"auto"}),(Pe=_.createElement("div")).innerHTML="
a",(He=(Me=Pe.getElementsByTagName("a")[0])&&Me.style)&&(He.cssText="float:left;opacity:.5",v.opacity="0.5"===He.opacity,v.cssFloat=!!He.cssFloat,Pe.style.backgroundClip="content-box",Pe.cloneNode(!0).style.backgroundClip="",v.clearCloneStyle="content-box"===Pe.style.backgroundClip,v.boxSizing=""===He.boxSizing||""===He.MozBoxSizing||""===He.WebkitBoxSizing,C.extend(v,{reliableHiddenOffsets:function(){return null==Ie&&Be(),Ie},boxSizingReliable:function(){return null==Oe&&Be(),Oe},pixelPosition:function(){return null==Le&&Be(),Le},reliableMarginRight:function(){return null==Fe&&Be(),Fe}})),C.swap=function(e,t,n,i){var r,o,s={};for(o in t)s[o]=e.style[o],e.style[o]=t[o];for(o in r=n.apply(e,i||[]),t)e.style[o]=s[o];return r};var ze=/alpha\([^)]*\)/i,Ue=/opacity\s*=\s*([^)]*)/,Xe=/^(none|table(?!-c[ea]).+)/,Ye=new RegExp("^("+B+")(.*)$","i"),Qe=new RegExp("^([+-])=("+B+")","i"),Je={position:"absolute",visibility:"hidden",display:"block"},Ve={letterSpacing:"0",fontWeight:"400"},Ge=["Webkit","O","Moz","ms"];function Ke(e,t){if(t in e)return t;for(var n=t.charAt(0).toUpperCase()+t.slice(1),i=t,r=Ge.length;r--;)if((t=Ge[r]+n)in e)return t;return i}function Ze(e,t){for(var n,i,r,o=[],s=0,a=e.length;s
a",ut=at.getElementsByTagName("a")[0],ct=(lt=_.createElement("select")).appendChild(_.createElement("option")),st=at.getElementsByTagName("input")[0],ut.style.cssText="top:1px",v.getSetAttribute="t"!==at.className,v.style=/top/.test(ut.getAttribute("style")),v.hrefNormalized="/a"===ut.getAttribute("href"),v.checkOn=!!st.value,v.optSelected=ct.selected,v.enctype=!!_.createElement("form").enctype,lt.disabled=!0,v.optDisabled=!ct.disabled,(st=_.createElement("input")).setAttribute("value",""),v.input=""===st.getAttribute("value"),st.value="t",st.setAttribute("type","radio"),v.radioValue="t"===st.value;var xt=/\r/g;C.fn.extend({val:function(n){var i,e,r,t=this[0];return arguments.length?(r=C.isFunction(n),this.each(function(e){var t;1===this.nodeType&&(null==(t=r?n.call(this,e,C(this).val()):n)?t="":"number"==typeof t?t+="":C.isArray(t)&&(t=C.map(t,function(e){return null==e?"":e+""})),(i=C.valHooks[this.type]||C.valHooks[this.nodeName.toLowerCase()])&&"set"in i&&void 0!==i.set(this,t,"value")||(this.value=t))})):t?(i=C.valHooks[t.type]||C.valHooks[t.nodeName.toLowerCase()])&&"get"in i&&void 0!==(e=i.get(t,"value"))?e:"string"==typeof(e=t.value)?e.replace(xt,""):null==e?"":e:void 0}}),C.extend({valHooks:{option:{get:function(e){var t=C.find.attr(e,"value");return null!=t?t:C.trim(C.text(e))}},select:{get:function(e){for(var t,n,i=e.options,r=e.selectedIndex,o="select-one"===e.type||r<0,s=o?null:[],a=o?r+1:i.length,l=r<0?a:o?r:0;l").append(C.parseHTML(e)).find(i):e)}).complete(n&&function(e,t){s.each(n,r||[e.responseText,t,e])}),this},C.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){C.fn[t]=function(e){return this.on(t,e)}}),C.expr.filters.animated=function(t){return C.grep(C.timers,function(e){return t===e.elem}).length};var cn=d.document.documentElement;function fn(e){return C.isWindow(e)?e:9===e.nodeType&&(e.defaultView||e.parentWindow)}C.offset={setOffset:function(e,t,n){var i,r,o,s,a,l,u=C.css(e,"position"),c=C(e),f={};"static"===u&&(e.style.position="relative"),a=c.offset(),o=C.css(e,"top"),l=C.css(e,"left"),r=("absolute"===u||"fixed"===u)&&-1").outerWidth(1).jquery||D.each(["Width","Height"],function(e,n){var r="Width"===n?["Left","Right"]:["Top","Bottom"],i=n.toLowerCase(),o={innerWidth:D.fn.innerWidth,innerHeight:D.fn.innerHeight,outerWidth:D.fn.outerWidth,outerHeight:D.fn.outerHeight};function s(e,t,n,i){return D.each(r,function(){t-=parseFloat(D.css(e,"padding"+this))||0,n&&(t-=parseFloat(D.css(e,"border"+this+"Width"))||0),i&&(t-=parseFloat(D.css(e,"margin"+this))||0)}),t}D.fn["inner"+n]=function(e){return void 0===e?o["inner"+n].call(this):this.each(function(){D(this).css(i,s(this,e)+"px")})},D.fn["outer"+n]=function(e,t){return"number"!=typeof e?o["outer"+n].call(this,e):this.each(function(){D(this).css(i,s(this,e,!0,t)+"px")})}}),D.fn.addBack||(D.fn.addBack=function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}),D("").data("a-b","a").removeData("a-b").data("a-b")&&(D.fn.removeData=(t=D.fn.removeData,function(e){return arguments.length?t.call(this,D.camelCase(e)):t.call(this)})),D.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase()),D.fn.extend({focus:(i=D.fn.focus,function(t,n){return"number"==typeof t?this.each(function(){var e=this;setTimeout(function(){D(e).focus(),n&&n.call(e)},t)}):i.apply(this,arguments)}),disableSelection:(n="onselectstart"in document.createElement("div")?"selectstart":"mousedown",function(){return this.bind(n+".ui-disableSelection",function(e){e.preventDefault()})}),enableSelection:function(){return this.unbind(".ui-disableSelection")},zIndex:function(e){if(void 0!==e)return this.css("zIndex",e);if(this.length)for(var t,n,i=D(this[0]);i.length&&i[0]!==document;){if(("absolute"===(t=i.css("position"))||"relative"===t||"fixed"===t)&&(n=parseInt(i.css("zIndex"),10),!isNaN(n)&&0!==n))return n;i=i.parent()}return 0}}),D.ui.plugin={add:function(e,t,n){var i,r=D.ui[e].prototype;for(i in n)r.plugins[i]=r.plugins[i]||[],r.plugins[i].push([t,n[i]])},call:function(e,t,n,i){var r,o=e.plugins[t];if(o&&(i||e.element[0].parentNode&&11!==e.element[0].parentNode.nodeType))for(r=0;r",options:{disabled:!1,create:null},_createWidget:function(e,t){t=D(t||this.defaultElement||this)[0],this.element=D(t),this.uuid=a++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=D(),this.hoverable=D(),this.focusable=D(),t!==this&&(D.data(t,this.widgetFullName,this),this._on(!0,this.element,{remove:function(e){e.target===t&&this.destroy()}}),this.document=D(t.style?t.ownerDocument:t.document||t),this.window=D(this.document[0].defaultView||this.document[0].parentWindow)),this.options=D.widget.extend({},this.options,this._getCreateOptions(),e),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:D.noop,_getCreateEventData:D.noop,_create:D.noop,_init:D.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetFullName).removeData(D.camelCase(this.widgetFullName)),this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled ui-state-disabled"),this.bindings.unbind(this.eventNamespace),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")},_destroy:D.noop,widget:function(){return this.element},option:function(e,t){var n,i,r,o=e;if(0===arguments.length)return D.widget.extend({},this.options);if("string"==typeof e)if(o={},e=(n=e.split(".")).shift(),n.length){for(i=o[e]=D.widget.extend({},this.options[e]),r=0;r=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}});!function(){D.ui=D.ui||{};var r,T,C=Math.max,_=Math.abs,E=Math.round,i=/left|center|right/,o=/top|center|bottom/,s=/[\+\-]\d+(\.[\d]+)?%?/,a=/^\w+/,l=/%$/,u=D.fn.position;function S(e,t,n){return[parseFloat(e[0])*(l.test(e[0])?t/100:1),parseFloat(e[1])*(l.test(e[1])?n/100:1)]}function N(e,t){return parseInt(D.css(e,t),10)||0}D.position={scrollbarWidth:function(){if(void 0!==r)return r;var e,t,n=D("
"),i=n.children()[0];return D("body").append(n),e=i.offsetWidth,n.css("overflow","scroll"),e===(t=i.offsetWidth)&&(t=n[0].clientWidth),n.remove(),r=e-t},getScrollInfo:function(e){var t=e.isWindow||e.isDocument?"":e.element.css("overflow-x"),n=e.isWindow||e.isDocument?"":e.element.css("overflow-y"),i="scroll"===t||"auto"===t&&e.widthC(_(i),_(r))?o.important="horizontal":o.important="vertical",f.using.call(this,e,o)}),s.offset(D.extend(u,{using:e}))})},D.ui.position={fit:{left:function(e,t){var n,i=t.within,r=i.isWindow?i.scrollLeft:i.offset.left,o=i.width,s=e.left-t.collisionPosition.marginLeft,a=r-s,l=s+t.collisionWidth-o-r;t.collisionWidth>o?0o?0").css("position","absolute").appendTo(e.parent()).outerWidth(e.outerWidth()).outerHeight(e.outerHeight()).offset(e.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_blurActiveElement:function(e){var t=this.document[0];if(this.handleElement.is(e.target))try{t.activeElement&&"body"!==t.activeElement.nodeName.toLowerCase()&&D(t.activeElement).blur()}catch(e){}},_mouseStart:function(e){var t=this.options;return this.helper=this._createHelper(e),this.helper.addClass("ui-draggable-dragging"),this._cacheHelperProportions(),D.ui.ddmanager&&(D.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(!0),this.offsetParent=this.helper.offsetParent(),this.hasFixedAncestor=0n[2]&&(l=n[2]+this.offset.click.left),e.pageY-this.offset.click.top>n[3]&&(u=n[3]+this.offset.click.top)),s.grid&&(r=s.grid[1]?this.originalPageY+Math.round((u-this.originalPageY)/s.grid[1])*s.grid[1]:this.originalPageY,u=!n||r-this.offset.click.top>=n[1]||r-this.offset.click.top>n[3]?r:r-this.offset.click.top>=n[1]?r-s.grid[1]:r+s.grid[1],o=s.grid[0]?this.originalPageX+Math.round((l-this.originalPageX)/s.grid[0])*s.grid[0]:this.originalPageX,l=!n||o-this.offset.click.left>=n[0]||o-this.offset.click.left>n[2]?o:o-this.offset.click.left>=n[0]?o-s.grid[0]:o+s.grid[0]),"y"===s.axis&&(l=this.originalPageX),"x"===s.axis&&(u=this.originalPageY)),{top:u-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.offset.scroll.top:a?0:this.offset.scroll.top),left:l-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.offset.scroll.left:a?0:this.offset.scroll.left)}},_clear:function(){this.helper.removeClass("ui-draggable-dragging"),this.helper[0]===this.element[0]||this.cancelHelperRemoval||this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1,this.destroyOnClear&&this.destroy()},_normalizeRightBottom:function(){"y"!==this.options.axis&&"auto"!==this.helper.css("right")&&(this.helper.width(this.helper.width()),this.helper.css("right","auto")),"x"!==this.options.axis&&"auto"!==this.helper.css("bottom")&&(this.helper.height(this.helper.height()),this.helper.css("bottom","auto"))},_trigger:function(e,t,n){return n=n||this._uiHash(),D.ui.plugin.call(this,e,[t,n,this],!0),/^(drag|start|stop)/.test(e)&&(this.positionAbs=this._convertPositionTo("absolute"),n.offset=this.positionAbs),D.Widget.prototype._trigger.call(this,e,t,n)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),D.ui.plugin.add("draggable","connectToSortable",{start:function(t,e,n){var i=D.extend({},e,{item:n.element});n.sortables=[],D(n.options.connectToSortable).each(function(){var e=D(this).sortable("instance");e&&!e.options.disabled&&(n.sortables.push(e),e.refreshPositions(),e._trigger("activate",t,i))})},stop:function(t,e,n){var i=D.extend({},e,{item:n.element});n.cancelHelperRemoval=!1,D.each(n.sortables,function(){var e=this;e.isOver?(e.isOver=0,n.cancelHelperRemoval=!0,e.cancelHelperRemoval=!1,e._storedCSS={position:e.placeholder.css("position"),top:e.placeholder.css("top"),left:e.placeholder.css("left")},e._mouseStop(t),e.options.helper=e.options._helper):(e.cancelHelperRemoval=!0,e._trigger("deactivate",t,i))})},drag:function(n,i,r){D.each(r.sortables,function(){var e=!1,t=this;t.positionAbs=r.positionAbs,t.helperProportions=r.helperProportions,t.offset.click=r.offset.click,t._intersectsWith(t.containerCache)&&(e=!0,D.each(r.sortables,function(){return this.positionAbs=r.positionAbs,this.helperProportions=r.helperProportions,this.offset.click=r.offset.click,this!==t&&this._intersectsWith(this.containerCache)&&D.contains(t.element[0],this.element[0])&&(e=!1),e})),e?(t.isOver||(t.isOver=1,r._parent=i.helper.parent(),t.currentItem=i.helper.appendTo(t.element).data("ui-sortable-item",!0),t.options._helper=t.options.helper,t.options.helper=function(){return i.helper[0]},n.target=t.currentItem[0],t._mouseCapture(n,!0),t._mouseStart(n,!0,!0),t.offset.click.top=r.offset.click.top,t.offset.click.left=r.offset.click.left,t.offset.parent.left-=r.offset.parent.left-t.offset.parent.left,t.offset.parent.top-=r.offset.parent.top-t.offset.parent.top,r._trigger("toSortable",n),r.dropped=t.element,D.each(r.sortables,function(){this.refreshPositions()}),r.currentItem=r.element,t.fromOutside=r),t.currentItem&&(t._mouseDrag(n),i.position=t.position)):t.isOver&&(t.isOver=0,t.cancelHelperRemoval=!0,t.options._revert=t.options.revert,t.options.revert=!1,t._trigger("out",n,t._uiHash(t)),t._mouseStop(n,!0),t.options.revert=t.options._revert,t.options.helper=t.options._helper,t.placeholder&&t.placeholder.remove(),i.helper.appendTo(r._parent),r._refreshOffsets(n),i.position=r._generatePosition(n,!0),r._trigger("fromSortable",n),r.dropped=!1,D.each(r.sortables,function(){this.refreshPositions()}))})}}),D.ui.plugin.add("draggable","cursor",{start:function(e,t,n){var i=D("body"),r=n.options;i.css("cursor")&&(r._cursor=i.css("cursor")),i.css("cursor",r.cursor)},stop:function(e,t,n){var i=n.options;i._cursor&&D("body").css("cursor",i._cursor)}}),D.ui.plugin.add("draggable","opacity",{start:function(e,t,n){var i=D(t.helper),r=n.options;i.css("opacity")&&(r._opacity=i.css("opacity")),i.css("opacity",r.opacity)},stop:function(e,t,n){var i=n.options;i._opacity&&D(t.helper).css("opacity",i._opacity)}}),D.ui.plugin.add("draggable","scroll",{start:function(e,t,n){n.scrollParentNotHidden||(n.scrollParentNotHidden=n.helper.scrollParent(!1)),n.scrollParentNotHidden[0]!==n.document[0]&&"HTML"!==n.scrollParentNotHidden[0].tagName&&(n.overflowOffset=n.scrollParentNotHidden.offset())},drag:function(e,t,n){var i=n.options,r=!1,o=n.scrollParentNotHidden[0],s=n.document[0];o!==s&&"HTML"!==o.tagName?(i.axis&&"x"===i.axis||(n.overflowOffset.top+o.offsetHeight-e.pageY")[0],x=c.each,b.style.cssText="background-color:rgba(1,1,1,.5)",y.rgba=-1").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),t={width:n.width(),height:n.height()},r=document.activeElement;try{r.id}catch(e){r=document.body}return n.wrap(e),n[0]!==r&&!D.contains(n[0],r)||D(r).focus(),e=n.parent(),"static"===n.css("position")?(e.css({position:"relative"}),n.css({position:"relative"})):(D.extend(i,{position:n.css("position"),zIndex:n.css("z-index")}),D.each(["top","left","bottom","right"],function(e,t){i[t]=n.css(t),isNaN(parseInt(i[t],10))&&(i[t]="auto")}),n.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),n.css(t),e.css(i).show()},removeWrapper:function(e){var t=document.activeElement;return e.parent().is(".ui-effects-wrapper")&&(e.parent().replaceWith(e),e[0]!==t&&!D.contains(e[0],t)||D(t).focus()),e},setTransition:function(i,e,r,o){return o=o||{},D.each(e,function(e,t){var n=i.cssUnit(t);0r&&0!==r||!1===i.call(e,o))&&jQuery.timer.remove(e,n,i)}a.timerID=i.timerID,s[n][i.timerID]||(s[n][i.timerID]=window.setInterval(a,t)),this.global.push(e)}},remove:function(e,t,n){var i,r=jQuery.data(e,this.dataKey);if(r){if(t){if(r[t]){if(n)n.timerID&&(window.clearInterval(r[t][n.timerID]),delete r[t][n.timerID]);else for(var n in r[t])window.clearInterval(r[t][n]),delete r[t][n];for(i in r[t])break;i||(i=null,delete r[t])}}else for(t in r)this.remove(e,t,n);for(i in r)break;i||jQuery.removeData(e,this.dataKey)}}}}),jQuery(window).bind("unload",function(){jQuery.each(jQuery.timer.global,function(e,t){jQuery.timer.remove(t)})}),function(){"use strict";var a={version:"1.0.1-nanoui",templateSettings:{evaluate:/\{\{([\s\S]+?)\}\}/g,interpolate:/\{\{:([\s\S]+?)\}\}/g,encode:/\{\{>([\s\S]+?)\}\}/g,use:/\{\{#([\s\S]+?)\}\}/g,define:/\{\{##\s*([\w\.$]+)\s*(\:|=)([\s\S]+?)#\}\}/g,conditional:/\{\{\/?if\s*([\s\S]*?)\s*\}\}/g,conditionalElse:/\{\{else\s*([\s\S]*?)\s*\}\}/g,iterate:/\{\{\/?for\s*(?:\}\}|([\s\S]+?)\s*(?:\:\s*([\w$]+))?\s*(?:\:\s*([\w$]+))?\s*\}\})/g,props:/\{\{\/?props\s*(?:\}\}|([\s\S]+?)\s*(?:\:\s*([\w$]+))?\s*(?:\:\s*([\w$]+))?\s*\}\})/g,empty:/\{\{empty\}\}/g,varname:"data, config, helper",strip:!0,append:!0,selfcontained:!1},template:void 0,compile:void 0};function l(){var t={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"},e=/&(?!#?\w+;)|<|>|"|'|\//g;return function(){return this?this.replace(e,function(e){return t[e]||e}):this}}"undefined"!=typeof module&&module.exports?module.exports=a:"function"==typeof define&&define.amd?define(function(){return a}):function(){return this||(0,eval)("this")}().doT=a,String.prototype.encodeHTML=l();var u={append:{start:"'+(",end:")+'",endencode:"||'').toString().encodeHTML()+'"},split:{start:"';out+=(",end:");out+='",endencode:"||'').toString().encodeHTML();out+='"}},c=/$^/;function f(e){return e.replace(/\\('|\\)/g,"$1").replace(/[\r\t\n]/g," ")}a.template=function(e,t,n){var i,r=(t=t||a.templateSettings).append?u.append:u.split,o=0,s=t.use||t.define?function i(r,e,o){return("string"==typeof e?e:e.toString()).replace(r.define||c,function(e,i,t,n){return 0===i.indexOf("def.")&&(i=i.substring(4)),i in o||(":"===t?(r.defineParams&&n.replace(r.defineParams,function(e,t,n){o[i]={arg:t,text:n}}),i in o||(o[i]=n)):new Function("def","def['"+i+"']="+n)(o)),""}).replace(r.use||c,function(e,t){r.useParams&&(t=t.replace(r.useParams,function(e,t,n,i){if(o[n]&&o[n].arg&&i){var r=(n+":"+i).replace(/'|\\/g,"_");return o.__exp=o.__exp||{},o.__exp[r]=o[n].text.replace(new RegExp("(^|[^\\w$])"+o[n].arg+"([^\\w$])","g"),"$1"+i+"$2"),t+"def.__exp['"+r+"']"}}));var n=new Function("def","return "+t)(o);return n?i(r,n,o):n})}(t,e,n||{}):e;s=("var out='"+(t.strip?s.replace(/(^|\r|\n)\t* +| +\t*(\r|\n|$)/g," ").replace(/\r|\n|\t|\/\*[\s\S]*?\*\//g,""):s).replace(/'|\\/g,"\\$&").replace(t.interpolate||c,function(e,t){return r.start+f(t)+r.end}).replace(t.encode||c,function(e,t){return i=!0,r.start+f(t)+r.endencode}).replace(t.conditional||c,function(e,t){return t?"';if("+f(t)+"){out+='":"';}out+='"}).replace(t.conditionalElse||c,function(e,t){return t?"';}else if("+f(t)+"){out+='":"';}else{out+='"}).replace(t.iterate||c,function(e,t,n,i){if(!t)return"';} } out+='";o+=1,n=n||"value",i=i||"index",t=f(t);var r="arr"+o;return"';var "+r+"="+t+";if("+r+" && "+r+".length > 0){var "+n+","+i+"=-1,l"+o+"="+r+".length-1;while("+i+" 0){var "+n+";for( var "+i+" in "+r+"){ if (!"+r+".hasOwnProperty("+i+")) continue; "+n+"="+r+"["+i+"];out+='"}).replace(t.empty||c,function(e){return"';}}else{if(true){out+='"}).replace(t.evaluate||c,function(e,t){return"';"+f(t)+"out+='"})+"';return out;").replace(/\n/g,"\\n").replace(/\t/g,"\\t").replace(/\r/g,"\\r").replace(/(\s|;|\}|^|\{)out\+='';/g,"$1").replace(/\+''/g,"").replace(/(\s|;|\}|^|\{)out\+=''\+/g,"$1out+="),i&&t.selfcontained&&(s="String.prototype.encodeHTML=("+l.toString()+"());"+s);try{return new Function(t.varname,s)}catch(e){throw"undefined"!=typeof console&&console.log("Could not create a template function: "+s),e}},a.compile=function(e,t){return a.template(e,null,t)}}(),function(e,t){"use strict";"function"==typeof define&&define.amd?define(t):"object"==typeof exports?module.exports=t():e.returnExports=t()}(this,function(){function n(e){try{var t=S.call(e).replace(/\/\/.*\n/g,"").replace(/\/\*[.\s\S]*\*\//g,"").replace(/\n/gm," ").replace(/ {2}/g," ");return N.test(t)}catch(e){return}}function p(e){if(!e)return!1;if("function"!=typeof e&&"object"!=typeof e)return!1;if(E)return function(e){try{return n(e)?!1:(S.call(e),!0)}catch(e){return!1}}(e);if(n(e))return!1;var t=_.call(e);return"[object Function]"===t||"[object GeneratorFunction]"===t}var h,d,l=Array,e=l.prototype,a=Object,t=a.prototype,u=Function,i=u.prototype,v=String,r=v.prototype,y=Number,o=y.prototype,c=e.slice,s=e.splice,g=e.push,f=e.unshift,m=e.concat,b=e.join,x=i.call,w=i.apply,T=Math.max,C=Math.min,_=t.toString,E="function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag,S=Function.prototype.toString,N=/^\s*class /,D=RegExp.prototype.exec;h=function(e){return"object"==typeof e&&(E?function(e){try{return D.call(e),!0}catch(e){return!1}}(e):"[object RegExp]"===_.call(e))};var k=String.prototype.valueOf;d=function(e){return"string"==typeof e||"object"==typeof e&&(E?function(e){try{return k.call(e),!0}catch(e){return!1}}(e):"[object String]"===_.call(e))};function j(e){var t=typeof e;return null===e||"object"!=t&&"function"!=t}function A(){}var P,H,M=a.defineProperty&&function(){try{var e={};for(var t in a.defineProperty(e,"x",{enumerable:!1,value:e}),e)return!1;return e.x===e}catch(e){return!1}}(),L=(P=t.hasOwnProperty,H=M?function(e,t,n,i){!i&&t in e||a.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:!0,value:n})}:function(e,t,n,i){!i&&t in e||(e[t]=n)},function(e,t,n){for(var i in t)P.call(t,i)&&H(e,i,t[i],n)}),O=y.isNaN||function(e){return e!=e},I=function(e){var t=+e;return O(t)?t=0:0!==t&&t!==1/0&&t!==-1/0&&(t=(0>>0};L(i,{bind:function(t){var n=this;if(!p(n))throw new TypeError("Function.prototype.bind called on incompatible "+n);for(var i,r=c.call(arguments,1),e=T(0,n.length-r.length),o=[],s=0;s=r)throw new TypeError("reduce of empty array with no initial value")}for(;sError name: "+e.name+"
Error Message: "+e.message)}t.hasOwnProperty("data")||(a&&a.hasOwnProperty("data")?t.data=a.data:t.data={}),n?l(t):a=t}(e)},addBeforeUpdateCallback:function(e,t){r[e]=t},addBeforeUpdateCallbacks:function(e){for(var t in e)e.hasOwnProperty(t)&&NanoStateManager.addBeforeUpdateCallback(t,e[t])},removeBeforeUpdateCallback:function(e){r.hasOwnProperty(e)&&delete r[e]},executeBeforeUpdateCallbacks:function(e){return t(r,e)},addAfterUpdateCallback:function(e,t){o[e]=t},addAfterUpdateCallbacks:function(e){for(var t in e)e.hasOwnProperty(t)&&NanoStateManager.addAfterUpdateCallback(t,e[t])},removeAfterUpdateCallback:function(e){o.hasOwnProperty(e)&&delete o[e]},executeAfterUpdateCallbacks:function(e){return t(o,e)},addState:function(e){e instanceof NanoStateClass?e.key?i[e.key]=e:reportError("ERROR: Attempted to add a state with an invalid stateKey"):reportError("ERROR: Attempted to add a state which is not instanceof NanoStateClass")},setCurrentState:function(e){if(void 0===e||!e)return reportError("ERROR: No state key was passed!"),!1;if(!i.hasOwnProperty(e))return reportError("ERROR: Attempted to set a current state which does not exist: "+e),!1;var t=s;return s=i[e],null!=t&&t.onRemove(s),s.onAdd(t),!0},getCurrentState:function(){return s},getData:function(){return a}}}(),NanoBaseCallbacks=function(){var a=!0,t={},n={status:function(n){var e;return 2==n.config.status?(e="good",$(".linkActive").removeClass("inactive")):(e=1==n.config.status?"average":"bad",$(".linkActive").addClass("inactive")),$(".statusicon").removeClass("good bad average").addClass(e),$(".linkActive").stopTime("linkPending"),$(".linkActive").removeClass("linkPending"),$(".linkActive").off("click").on("click",function(e){e.preventDefault();var t=$(this).data("href");null!=t&&a&&(a=!1,$("body").oneTime(300,"enableClick",function(){a=!0}),2==n.config.status&&$(this).oneTime(300,"linkPending",function(){$(this).addClass("linkPending")}),window.location.href=t)}),n},nanomap:function(e){return $(".mapIcon").off("mouseenter mouseleave").on("mouseenter",function(e){$("#uiMapTooltip").html($(this).children(".tooltip").html()).show().stopTime().oneTime(5e3,"hideTooltip",function(){$(this).fadeOut(500)})}),$(".zoomLink").off("click").on("click",function(e){e.preventDefault();var t=$(this).data("zoomLevel"),n=$("#uiMap"),a=n.width()*t,r=n.height()*t;n.css({zoom:t,left:"50%",top:"50%",marginLeft:"-"+Math.floor(a/2)+"px",marginTop:"-"+Math.floor(r/2)+"px"})}),$("#uiMapImage").attr("src",e.config.map+"_nanomap_z"+e.config.mapZLevel+".png"),e}};return{addCallbacks:function(){NanoStateManager.addBeforeUpdateCallbacks(t),NanoStateManager.addAfterUpdateCallbacks(n)},removeCallbacks:function(){for(var e in t)t.hasOwnProperty(e)&&NanoStateManager.removeBeforeUpdateCallback(e);for(var e in n)n.hasOwnProperty(e)&&NanoStateManager.removeAfterUpdateCallback(e)}}}(),NanoBaseHelpers=function(){var t={syndicateMode:function(){return $(".mainBG").css("background","url('syndicate.png') no-repeat fixed center/50% 50%, linear-gradient(to bottom, #8f1414 0%, #4B0A0A 100%) no-repeat fixed center;"),$("#uiTitleFluff").css("background-image","url('uiTitleFluff-Syndicate.png')"),$("#uiTitleFluff").css("background-position","50% 50%"),$("#uiTitleFluff").css("background-repeat","no-repeat"),""},combine:function(e,t){return e&&t?e.concat(t):e||t},dump:function(e){return JSON.stringify(e)},link:function(e,t,n,a,r,o){var i="",s="noIcon";void 0!==t&&t&&(i='
',s="hasIcon"),void 0!==r&&r||(r="link");var l="";void 0!==o&&o&&(l='id="'+o+'"');var c=NanoTransition.allocID(l+"_"+e.toString().replace(/[^a-z0-9_]/gi,"_")+"_"+t);return void 0!==a&&a?''; - } - - return '
' + iconHtml + text + '
'; - }, - - xor: function (number,bit) { - return number ^ bit; - }, - - precisionRound: function (value, places) { - if(places == 0){ - return Math.round(number); - } - var multiplier = Math.pow(10, places); - return (Math.round(value * multiplier) / multiplier); - }, - - // Round a number to the nearest integer - round: function(number) { - return Math.round(number); - }, - fixed: function(number) { - return Math.round(number * 10) / 10; - }, - // Round a number down to integer - floor: function(number) { - return Math.floor(number); - }, - // Round a number up to integer - ceil: function(number) { - return Math.ceil(number); - }, - - // Format a string (~string("Hello {0}, how are {1}?", 'Martin', 'you') becomes "Hello Martin, how are you?") - string: function() { - if (arguments.length == 0) - { - return ''; - } - else if (arguments.length == 1) - { - return arguments[0]; - } - else if (arguments.length > 1) - { - stringArgs = []; - for (var i = 1; i < arguments.length; i++) - { - stringArgs.push(arguments[i]); - } - return arguments[0].format(stringArgs); - } - return ''; - }, - formatNumber: function(x) { - // From http://stackoverflow.com/questions/2901102/how-to-print-a-number-with-commas-as-thousands-separators-in-javascript - var parts = x.toString().split("."); - parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ","); - return parts.join("."); - }, - // Capitalize the first letter of a string. From http://stackoverflow.com/questions/1026069/capitalize-the-first-letter-of-string-in-javascript - capitalizeFirstLetter: function( string ) { - return string.charAt(0).toUpperCase() + string.slice(1); - }, - // Display a bar. Used to show health, capacity, etc. - displayBar: function( value, rangeMin, rangeMax, styleClass, showText ) { - - if (rangeMin < rangeMax) - { - if (value < rangeMin) - { - value = rangeMin; - } - else if (value > rangeMax) - { - value = rangeMax; - } - } - else - { - if (value > rangeMin) - { - value = rangeMin; - } - else if (value < rangeMax) - { - value = rangeMax; - } - } - - if (typeof styleClass == 'undefined' || !styleClass) - { - styleClass = ''; - } - - if (typeof showText == 'undefined' || !showText) - { - showText = ''; - } - - var percentage = Math.round((value - rangeMin) / (rangeMax - rangeMin) * 100); - var tid = NanoTransition.allocID(rangeMin + "_" + rangeMax); - - return '
' + showText + '
'; - }, - // Convert danger level to class (for the air alarm) - dangerToClass: function(level) { - if(level == 0) return 'good'; - if(level == 1) return 'average'; - return 'bad'; - }, - dangerToSpan: function(level) { - if(level == 0) return '"Good"'; - if(level == 1) return '"Minor Alert"'; - return '"Major Alert"'; - }, - generateHref: function (parameters) { - var body = $('body'); // For some fucking reason, data is stored in the body tag. - _urlParameters = body.data('urlParameters'); - var queryString = '?'; - - for (var key in _urlParameters) - { - if (_urlParameters.hasOwnProperty(key)) - { - if (queryString !== '?') - { - queryString += ';'; - } - queryString += key + '=' + _urlParameters[key]; - } - } - - for (var key in parameters) - { - if (parameters.hasOwnProperty(key)) - { - if (queryString !== '?') - { - queryString += ';'; - } - queryString += key + '=' + parameters[key]; - } - } - return queryString; - }, - // Display DNA Blocks (for the DNA Modifier UI) - displayDNABlocks: function(dnaString, selectedBlock, selectedSubblock, blockSize, paramKey) { - if (!dnaString) - { - return '
Please place a valid subject into the DNA modifier.
'; - } - - var characters = dnaString.split(''); - - var html = '
'; - var block = 1; - var subblock = 1; - for (var index in characters) { - if (!characters.hasOwnProperty(index) || typeof characters[index] === 'object') - { - continue; - } - - var parameters; - if (paramKey.toUpperCase() == 'UI'){ - parameters = { 'selectUIBlock' : block, 'selectUISubblock' : subblock }; - } else { - parameters = { 'selectSEBlock' : block, 'selectSESubblock' : subblock }; - } - - var status = 'linkActive'; - if (block == selectedBlock && subblock == selectedSubblock) { - status = 'selected'; - } - - html += ''; - - index++; - if (index % blockSize == 0 && index < characters.length) { - block++; - subblock = 1; - html += '
'; - } else { - subblock++; - } - } - - html += '
'; - - return html; - }, - cMirror: function(textbox) { - var editor = CodeMirror.fromTextArea(document.getElementById(textbox), { - lineNumbers: true, - indentUnit: 4, - indentWithTabs: true, - theme: "lesser-dark" - }); - }, - smoothNumber: function(number) { - var tid = NanoTransition.allocID("n"); - - return ''; - }, - smoothRound: function(number, places) { - var tid = NanoTransition.allocID(places); - if(places === undefined) - placed = 0; - - return ''; - } - }; - - return { - addHelpers: function () - { - NanoTemplate.addHelpers(_baseHelpers); - }, - - removeHelpers: function () - { - for (var helperKey in _baseHelpers) - { - if (_baseHelpers.hasOwnProperty(helperKey)) - { - NanoTemplate.removeHelper(helperKey); - } - } - } - }; -}(); diff --git a/nano/scripts/nano/nano_state.js b/nano/scripts/nano/nano_state.js deleted file mode 100644 index db7fcf92a11..00000000000 --- a/nano/scripts/nano/nano_state.js +++ /dev/null @@ -1,107 +0,0 @@ -// This is the base state class, it is not to be used directly - -function NanoStateClass() {} - -NanoStateClass.prototype.key = null; -NanoStateClass.prototype.layoutRendered = false; -NanoStateClass.prototype.contentRendered = false; -NanoStateClass.prototype.mapInitialised = false; - -NanoStateClass.prototype.isCurrent = function () { - return NanoStateManager.getCurrentState() == this; -}; - -NanoStateClass.prototype.onAdd = function (previousState) { - // Do not add code here, add it to the 'default' state (nano_state_defaut.js) or create a new state and override this function - - NanoBaseCallbacks.addCallbacks(); - NanoBaseHelpers.addHelpers(); -}; - -NanoStateClass.prototype.onRemove = function (nextState) { - // Do not add code here, add it to the 'default' state (nano_state_defaut.js) or create a new state and override this function - - NanoBaseCallbacks.removeCallbacks(); - NanoBaseHelpers.removeHelpers(); -}; - -NanoStateClass.prototype.onBeforeUpdate = function (data) { - // Do not add code here, add it to the 'default' state (nano_state_defaut.js) or create a new state and override this function - - data = NanoStateManager.executeBeforeUpdateCallbacks(data); - - return data; // Return data to continue, return false to prevent onUpdate and onAfterUpdate -}; - -NanoStateClass.prototype.onUpdate = function (data) { - // Do not add code here, add it to the 'default' state (nano_state_defaut.js) or create a new state and override this function - - try - { - if (!this.layoutRendered || (data['config'].hasOwnProperty('autoUpdateLayout') && data['config']['autoUpdateLayout'])) - { - $("#uiLayout").html(NanoTemplate.parse('layout', data)); // render the 'mail' template to the #mainTemplate div - this.layoutRendered = true; - } - if (!this.contentRendered || (data['config'].hasOwnProperty('autoUpdateContent') && data['config']['autoUpdateContent'])) - { - $("#uiContent").html(NanoTemplate.parse('main', data)); // render the 'mail' template to the #mainTemplate div - this.contentRendered = true; - } - if (NanoTemplate.templateExists('mapContent')) - { - if (!this.mapInitialised) - { - // Add drag functionality to the map ui - $('#uiMap').draggable(); - - $('#uiMapTooltip') - .off('click') - .on('click', function (event) { - event.preventDefault(); - $(this).fadeOut(400); - }); - - this.mapInitialised = true; - } - - $("#uiMapContent").html(NanoTemplate.parse('mapContent', data)); // render the 'mapContent' template to the #uiMapContent div - - if (data['config'].hasOwnProperty('showMap') && data['config']['showMap']) - { - $('#uiContent').addClass('hidden'); - $('#uiMapWrapper').removeClass('hidden'); - } - else - { - $('#uiMapWrapper').addClass('hidden'); - $('#uiContent').removeClass('hidden'); - } - } - if (NanoTemplate.templateExists('mapHeader')) - { - $("#uiMapHeader").html(NanoTemplate.parse('mapHeader', data)); // render the 'mapHeader' template to the #uiMapHeader div - } - if (NanoTemplate.templateExists('mapFooter')) - { - $("#uiMapFooter").html(NanoTemplate.parse('mapFooter', data)); // render the 'mapFooter' template to the #uiMapFooter div - } - } - catch(error) - { - reportError('ERROR: An error occurred while rendering the UI: ' + error.message); - return; - } -}; - -NanoStateClass.prototype.onAfterUpdate = function (data) { - // Do not add code here, add it to the 'default' state (nano_state_defaut.js) or create a new state and override this function - - NanoStateManager.executeAfterUpdateCallbacks(data); -}; - -NanoStateClass.prototype.alertText = function (text) { - // Do not add code here, add it to the 'default' state (nano_state_defaut.js) or create a new state and override this function - - alert(text); -}; diff --git a/nano/scripts/nano/nano_state_default.js b/nano/scripts/nano/nano_state_default.js deleted file mode 100644 index ee7bd521e63..00000000000 --- a/nano/scripts/nano/nano_state_default.js +++ /dev/null @@ -1,14 +0,0 @@ - -NanoStateDefaultClass.inheritsFrom(NanoStateClass); -var NanoStateDefault = new NanoStateDefaultClass(); - -function NanoStateDefaultClass() { - - this.key = 'default'; - - //this.parent.constructor.call(this); - - this.key = this.key.toLowerCase(); - - NanoStateManager.addState(this); -} diff --git a/nano/scripts/nano/nano_state_manager.js b/nano/scripts/nano/nano_state_manager.js deleted file mode 100644 index 88f08dd277d..00000000000 --- a/nano/scripts/nano/nano_state_manager.js +++ /dev/null @@ -1,226 +0,0 @@ -// NanoStateManager handles data from the server and uses it to render templates -NanoStateManager = function () -{ - // _isInitialised is set to true when all of this ui's templates have been processed/rendered - var _isInitialised = false; - // the data for this ui - var _data = null; - - // this is an array of callbacks which are called when new data arrives, before it is processed - var _beforeUpdateCallbacks = {}; - // this is an array of callbacks which are called when new data arrives, before it is processed - var _afterUpdateCallbacks = {}; - - // this is an array of state objects, these can be used to provide custom javascript logic - var _states = {}; - var _currentState = null; - - // the init function is called when the ui has loaded - // this function sets up the templates and base functionality - var init = function () - { - // We store initialData and templateData in the body tag, it's as good a place as any - _data = $('body').data('initialData'); - - if (_data == null || !_data.hasOwnProperty('config') || !_data.hasOwnProperty('data')) - { - reportError('Error: Initial data did not load correctly.' + JSON.stringify(_data)); - } - - var stateKey = 'default'; - if (_data['config'].hasOwnProperty('stateKey') && _data['config']['stateKey']) - { - stateKey = _data['config']['stateKey'].toLowerCase(); - } - - NanoStateManager.setCurrentState(stateKey); - - $(document).on('templatesLoaded', function () { - doUpdate(_data); - - _isInitialised = true; - }); - }; - - // Receive update data from the server - var receiveUpdateData = function (jsonString) - { - var updateData; - - // reportError("recieveUpdateData called." + "
Type: " + typeof jsonString); //debug hook - try - { - // parse the JSON string from the server into a JSON object - updateData = jQuery.parseJSON(jsonString); - } - catch (error) - { - reportError("recieveUpdateData failed. " + "
Error name: " + error.name + "
Error Message: " + error.message); - return; - } - - // reportError("recieveUpdateData passed trycatch block."); //debug hook - - if (!updateData.hasOwnProperty('data')) - { - if (_data && _data.hasOwnProperty('data')) - { - updateData['data'] = _data['data']; - } - else - { - updateData['data'] = {}; - } - } - - if (_isInitialised) // all templates have been registered, so render them - { - doUpdate(updateData); - } - else - { - _data = updateData; // all templates have not been registered. We set _data directly here which will be applied after the template is loaded with the initial data - } - }; - - // This function does the update by calling the methods on the current state - var doUpdate = function (data) - { - if (_currentState == null) - { - return; - } - - data = _currentState.onBeforeUpdate(data); - - if (data === false) - { - reportError('data is false, return'); - return; // A beforeUpdateCallback returned a false value, this prevents the render from occuring - } - - _data = data; - - _currentState.onUpdate(_data); - - _currentState.onAfterUpdate(_data); - }; - - // Execute all callbacks in the callbacks array/object provided, updateData is passed to them for processing and potential modification - var executeCallbacks = function (callbacks, data) - { - for (var key in callbacks) - { - if (callbacks.hasOwnProperty(key) && jQuery.isFunction(callbacks[key])) - { - data = callbacks[key].call(this, data); - } - } - - return data; - }; - - return { - init: function () - { - init(); - }, - receiveUpdateData: function (jsonString) - { - receiveUpdateData(jsonString); - }, - addBeforeUpdateCallback: function (key, callbackFunction) - { - _beforeUpdateCallbacks[key] = callbackFunction; - }, - addBeforeUpdateCallbacks: function (callbacks) { - for (var callbackKey in callbacks) { - if (!callbacks.hasOwnProperty(callbackKey)) - { - continue; - } - NanoStateManager.addBeforeUpdateCallback(callbackKey, callbacks[callbackKey]); - } - }, - removeBeforeUpdateCallback: function (key) - { - if (_beforeUpdateCallbacks.hasOwnProperty(key)) - { - delete _beforeUpdateCallbacks[key]; - } - }, - executeBeforeUpdateCallbacks: function (data) { - return executeCallbacks(_beforeUpdateCallbacks, data); - }, - addAfterUpdateCallback: function (key, callbackFunction) - { - _afterUpdateCallbacks[key] = callbackFunction; - }, - addAfterUpdateCallbacks: function (callbacks) { - for (var callbackKey in callbacks) { - if (!callbacks.hasOwnProperty(callbackKey)) - { - continue; - } - NanoStateManager.addAfterUpdateCallback(callbackKey, callbacks[callbackKey]); - } - }, - removeAfterUpdateCallback: function (key) - { - if (_afterUpdateCallbacks.hasOwnProperty(key)) - { - delete _afterUpdateCallbacks[key]; - } - }, - executeAfterUpdateCallbacks: function (data) { - return executeCallbacks(_afterUpdateCallbacks, data); - }, - addState: function (state) - { - if (!(state instanceof NanoStateClass)) - { - reportError('ERROR: Attempted to add a state which is not instanceof NanoStateClass'); - return; - } - if (!state.key) - { - reportError('ERROR: Attempted to add a state with an invalid stateKey'); - return; - } - _states[state.key] = state; - }, - setCurrentState: function (stateKey) - { - if (typeof stateKey == 'undefined' || !stateKey) { - reportError('ERROR: No state key was passed!'); - return false; - } - if (!_states.hasOwnProperty(stateKey)) - { - reportError('ERROR: Attempted to set a current state which does not exist: ' + stateKey); - return false; - } - - var previousState = _currentState; - - _currentState = _states[stateKey]; - - if (previousState != null) { - previousState.onRemove(_currentState); - } - - _currentState.onAdd(previousState); - - return true; - }, - getCurrentState: function () - { - return _currentState; - }, - getData: function () - { - return _data; - } - }; -} (); - \ No newline at end of file diff --git a/nano/scripts/nano/nano_state_pda.js b/nano/scripts/nano/nano_state_pda.js deleted file mode 100644 index d46419bfeaf..00000000000 --- a/nano/scripts/nano/nano_state_pda.js +++ /dev/null @@ -1,53 +0,0 @@ -NanoStatePDAClass.inheritsFrom(NanoStateClass); -var NanoStatePDA = new NanoStatePDAClass(); - -function NanoStatePDAClass() { - this.key = 'pda'; - this.key = this.key.toLowerCase(); - this.current_template = ""; - - NanoStateManager.addState(this); -} - -NanoStatePDAClass.prototype.onUpdate = function(data) { - NanoStateClass.prototype.onUpdate.call(this, data); - var state = this; - - try { - if(data['data']['app'] != null) { - var template = data['data']['app']['template']; - if(template != null && template != state.current_template) { - $.when($.ajax({ - url: template + '.tmpl', - cache: false, - dataType: 'text' - })) - .done(function(templateMarkup) { - templateMarkup += '
'; - - try { - NanoTemplate.addTemplate('app', templateMarkup); - NanoTemplate.resetTemplate('app'); - $("#uiApp").html(NanoTemplate.parse('app', data)); - state.current_template = template; - - state.onAfterUpdate(data); - } catch(error) { - reportError('ERROR: An error occurred while loading the PDA App UI: ' + error.message); - return; - } - }) - .fail( function () { - reportError('ERROR: Loading template app(' + template + ') failed!'); - }); - } else { - if (NanoTemplate.templateExists('app')) { - $("#uiApp").html(NanoTemplate.parse('app', data)); - } - } - } - } catch(error) { - reportError('ERROR: An error occurred while rendering the PDA App UI: ' + error.message); - return; - } -} \ No newline at end of file diff --git a/nano/scripts/nano/nano_template.js b/nano/scripts/nano/nano_template.js deleted file mode 100644 index e37724f1bb4..00000000000 --- a/nano/scripts/nano/nano_template.js +++ /dev/null @@ -1,132 +0,0 @@ - -var NanoTemplate = function () { - - var _templateData = {}; - - var _templates = {}; - var _compiledTemplates = {}; - - var _helpers = {}; - - var init = function () { - // We store templateData in the body tag, it's as good a place as any - _templateData = $('body').data('templateData'); - - if (_templateData == null) - { - reportError('Error: Template data did not load correctly.'); - } - - loadNextTemplate(); - }; - - var loadNextTemplate = function () { - // we count the number of templates for this ui so that we know when they've all been rendered - var templateCount = Object.size(_templateData); - - if (!templateCount) - { - $(document).trigger('templatesLoaded'); - return; - } - - // load markup for each template and register it - for (var key in _templateData) - { - if (!_templateData.hasOwnProperty(key)) - { - continue; - } - - $.when($.ajax({ - url: _templateData[key], - cache: false, - dataType: 'text' - })) - .done( function(templateMarkup) { - - templateMarkup += '
'; - - try { - NanoTemplate.addTemplate(key, templateMarkup); - } - catch(error) { - reportError('ERROR: An error occurred while loading the UI: ' + error.message); - return; - } - - delete _templateData[key]; - loadNextTemplate(); - }) - .fail( function () { - reportError('ERROR: Loading template ' + key + '(' + _templateData[key] + ') failed!'); - }); - - return; - } - }; - - var compileTemplates = function () { - for (var key in _templates) { - try { - _compiledTemplates[key] = doT.template(_templates[key], null, _templates); - } - catch (error) { - reportError(error.message); - } - } - }; - - return { - init: function () { - init(); - }, - addTemplate: function (key, templateString) { - _templates[key] = templateString; - }, - templateExists: function (key) { - return _templates.hasOwnProperty(key); - }, - resetTemplate: function (key) { - _compiledTemplates[key] = null; - }, - parse: function (templateKey, data) { - if (!_compiledTemplates.hasOwnProperty(templateKey) || !_compiledTemplates[templateKey]) { - if (!_templates.hasOwnProperty(templateKey)) { - reportError('ERROR: Template "' + templateKey + '" does not exist in _compiledTemplates!'); - return '

Template error (does not exist)

'; - } - compileTemplates(); - } - if (typeof _compiledTemplates[templateKey] != 'function') { - reportError(_compiledTemplates[templateKey]); - reportError('ERROR: Template "' + templateKey + '" failed to compile!'); - return '

Template error (failed to compile)

'; - } - return _compiledTemplates[templateKey].call(this, data['data'], data['config'], _helpers); - }, - addHelper: function (helperName, helperFunction) { - if (!jQuery.isFunction(helperFunction)) { - reportError('NanoTemplate.addHelper failed to add ' + helperName + ' as it is not a function.'); - return; - } - - _helpers[helperName] = helperFunction; - }, - addHelpers: function (helpers) { - for (var helperName in helpers) { - if (!helpers.hasOwnProperty(helperName)) - { - continue; - } - NanoTemplate.addHelper(helperName, helpers[helperName]); - } - }, - removeHelper: function (helperName) { - if (helpers.hasOwnProperty(helperName)) - { - delete _helpers[helperName]; - } - } - }; -}(); diff --git a/nano/scripts/nano/nano_transition.js b/nano/scripts/nano/nano_transition.js deleted file mode 100644 index ab124cc75f7..00000000000 --- a/nano/scripts/nano/nano_transition.js +++ /dev/null @@ -1,182 +0,0 @@ -NanoTransition = function() { - var idCache = {}; - var stateCache = {}; - var currentID = 0; - - NanoStateManager.addBeforeUpdateCallback("TransitionReset", function(updateData) { - currentID = 0; - return updateData; - }); - - // get a transition handle, add this to your element's class - var _allocID = function(uniqueID) { - if(uniqueID == "_Hide_Map_close") // hack because nano does weird thing on first tick - return "transition__map"; - - if(uniqueID === undefined) - uniqueID = ""; - return "transition__" + (currentID++) + "_" + uniqueID.toString(); - } - - // setup transitions, call this exactly once a refresh, returns old state - var _updateElement = function(id, newState, merge) { - var cache = idCache[id]; - var oldState; - - if(merge === undefined) - merge = false; - - var element = $("." + id); - if(element.length == 0) - return newState; - - // verify that the id still points to the same thing - // and get old state - element = element[0]; - if(cache - && cache.tagName == element.tagName - && cache.tabIndex == element.tabIndex - && cache.parent == element.parentNode.tagName - && cache.children == element.children.length) { - - // yep, this is continuation of old object - oldState = stateCache[id]; - - if(merge) { - var newStateCopy = {}; - for(k in oldState) - newStateCopy[k] = oldState[k]; - for(k in newState) - newStateCopy[k] = newState[k]; - newState = newStateCopy; - } - } else { - // nop! - oldState = newState; - - idCache[id] = { - tagName: element.tagName, - tabIndex: element.tabIndex, - parent: element.parentNode.tagName, - children: element.children.length - }; - } - - // save new state for next cycle - stateCache[id] = newState; - return oldState; - } - - var _resolveTarget = function(id, filter) { - var element = $("." + id); - - return filter ? $(element).children(filter) : $(element); - } - - // animate a state change - var _animateElement = function(id, filter, oldState, newState, time) { - var target = _resolveTarget(id, filter); - - if(time === undefined) - time = 1900; - - // do the animation - target - .css(oldState) - .animate(newState, { - duration: time, - queue: false - }); - - // maybe class too? - var oldClass = oldState["..class"]; - var newClass = newState["..class"]; - if(oldClass && newClass) { - target.addClass(oldClass); - if(oldClass != newClass) { - // strip classes that are in both - var oldClass = oldClass.split(" "); - var newClass = newClass.split(" "); - - var filteredOldClass = oldClass.filter(function(x) { return newClass.indexOf(x) == -1; }); - var filteredNewClass = newClass.filter(function(x) { return oldClass.indexOf(x) == -1; }); - - oldClass = filteredOldClass.join(" "); - newClass = filteredNewClass.join(" "); - - target.switchClass(oldClass, newClass, { - duration: time, - queue: false - }); - } - } - } - - var _animateTextValue = function(id, filter, places, oldValue, newValue, time) { - var target = _resolveTarget(id, filter); - - if(time === undefined) - time = 1900; - - if(places == -1) - target.text(oldValue.toString());//oldValue.toString()); - else - target.text(oldValue.toFixed(places));//oldValue.toFixed(places)); - - if(oldValue != newValue) - target.animate({i: 1}, { - duration: time, - queue: false, - step: function(now, fx) { - if(places == -1) { - fx.elem.textContent = (oldValue * (1 - now) + newValue * now).toString(); - } else { - fx.elem.textContent = (oldValue * (1 - now) + newValue * now).toFixed(places); - } - } - }); - } - - var _animateHover = function(id, filter, oldState, newState, time) { - var target = _resolveTarget(id, filter); - - if(time === undefined) - time = 200; - - if(oldState["..hover"]) - target.addClass("hover"); - - target.hover( - function() { - target.stop(1, 1).addClass("hover", { - duration: time, - queue: false - }); - _updateElement(id, {"..hover": true}, true); - }, - function() { - target.stop(1, 1).removeClass("hover", { - duration: time, - queue: false - }); - _updateElement(id, {"..hover": false}, true); - } - ); - } - - // helper for most common use - var _transitionElement = function(id, filter, state, time) { - var old = _updateElement(id, state); - _animateElement(id, filter, old, state, time); - return old; - } - - return { - allocID: _allocID, - updateElement: _updateElement, - animateElement: _animateElement, - animateTextValue: _animateTextValue, - animateHover: _animateHover, - transitionElement: _transitionElement - }; -}(); diff --git a/nano/scripts/nano/nano_utility.js b/nano/scripts/nano/nano_utility.js deleted file mode 100644 index 9e003042469..00000000000 --- a/nano/scripts/nano/nano_utility.js +++ /dev/null @@ -1,202 +0,0 @@ -// NanoUtility is the place to store utility functions -var NanoUtility = function () { - var _urlParameters = {}; // This is populated with the base url parameters (used by all links), which is probaby just the "src" parameter - - return { - init: function () { - var body = $('body'); // We store data in the body tag, it's as good a place as any - _urlParameters = body.data('urlParameters'); - }, - // generate a Byond href, combines _urlParameters with parameters - generateHref: function (parameters) { - var queryString = '?'; - - for (var key in _urlParameters) { - if (_urlParameters.hasOwnProperty(key)) { - if (queryString !== '?') { - queryString += ';'; - } - queryString += key + '=' + _urlParameters[key]; - } - } - - for (var key in parameters) - { - if (parameters.hasOwnProperty(key)) { - if (queryString !== '?') { - queryString += ';'; - } - queryString += key + '=' + parameters[key]; - } - } - return queryString; - }, - winset: function (key, value, window) { - var obj, params, winsetRef; - if (window == null) { - window = NanoStateManager.getData().config.window.ref; - } - params = ( - obj = {}, - obj[window + "." + key] = value, - obj - ); - return location.href = NanoUtility.href("winset", params); - }, - extend: function(first, second) { - Object.keys(second).forEach(function(key) { - var secondVal; - secondVal = second[key]; - if (secondVal && Object.prototype.toString.call(secondVal) === "[object Object]") { - first[key] = first[key] || {}; - return NanoUtility.extend(first[key], secondVal); - } else { - return first[key] = secondVal; - } - }); - return first; - }, - href: function(url, params) { - if (url == null) { - url = ""; - } - if (params == null) { - params = {}; - } - url = new Url("byond://" + url); - NanoUtility.extend(url.query, params); - return url; - }, - close: function() { - var params; - params = { - command: "nanoclose " + _urlParameters.src - }; - this.winset("is-visible", "false"); - return location.href = NanoUtility.href("winset", params); - } - } -} (); - -if (typeof jQuery == 'undefined') { - reportError('ERROR: Javascript library failed to load!'); -} -if (typeof doT == 'undefined') { - reportError('ERROR: Template engine failed to load!'); -} - -var reportError = function (str) { - window.location = "byond://?nano_err=" + encodeURIComponent(str); - alert(str); -} - -// All scripts are initialised here, this allows control of init order -$(document).ready(function () { - NanoUtility.init(); - NanoStateManager.init(); - NanoTemplate.init(); - NanoWindow.init(); -}); - -if (!Array.prototype.indexOf) -{ - Array.prototype.indexOf = function(elt /*, from*/) - { - var len = this.length; - - var from = Number(arguments[1]) || 0; - from = (from < 0) - ? Math.ceil(from) - : Math.floor(from); - if (from < 0) - from += len; - - for (; from < len; from++) - { - if (from in this && - this[from] === elt) - return from; - } - return -1; - }; -}; - -if (!String.prototype.format) -{ - String.prototype.format = function (args) { - var str = this; - return str.replace(String.prototype.format.regex, function(item) { - var intVal = parseInt(item.substring(1, item.length - 1)); - var replace; - if (intVal >= 0) { - replace = args[intVal]; - } else if (intVal === -1) { - replace = "{"; - } else if (intVal === -2) { - replace = "}"; - } else { - replace = ""; - } - return replace; - }); - }; - String.prototype.format.regex = new RegExp("{-?[0-9]+}", "g"); -}; - -Object.size = function(obj) { - var size = 0, key; - for (var key in obj) { - if (obj.hasOwnProperty(key)) size++; - } - return size; -}; - -if(!window.console) { - window.console = { - log : function(str) { - return false; - } - }; -}; - -String.prototype.toTitleCase = function () { - var smallWords = /^(a|an|and|as|at|but|by|en|for|if|in|of|on|or|the|to|vs?\.?|via)$/i; - - return this.replace(/([^\W_]+[^\s-]*) */g, function (match, p1, index, title) { - if (index > 0 && index + p1.length !== title.length && - p1.search(smallWords) > -1 && title.charAt(index - 2) !== ":" && - title.charAt(index - 1).search(/[^\s-]/) < 0) { - return match.toLowerCase(); - } - - if (p1.substr(1).search(/[A-Z]|\../) > -1) { - return match; - } - - return match.charAt(0).toUpperCase() + match.substr(1); - }); -}; - -$.ajaxSetup({ - cache: false -}); - -Function.prototype.inheritsFrom = function (parentClassOrObject) { - this.prototype = new parentClassOrObject; - this.prototype.constructor = this; - this.prototype.parent = parentClassOrObject.prototype; - return this; -}; - -if (!String.prototype.trim) { - String.prototype.trim = function () { - return this.replace(/^\s+|\s+$/g, ''); - }; -} - -// Replicate the ckey proc from BYOND -if (!String.prototype.ckey) { - String.prototype.ckey = function () { - return this.replace(/\W/g, '').toLowerCase(); - }; -} \ No newline at end of file diff --git a/nano/scripts/nano/nano_window.js b/nano/scripts/nano/nano_window.js deleted file mode 100644 index 7a863331152..00000000000 --- a/nano/scripts/nano/nano_window.js +++ /dev/null @@ -1,213 +0,0 @@ -var NanoWindow = function () -{ - var offsetX, offsetY; - var minWidth = 280; - var minHeight = 140; - - var setPos = function (x, y) { - NanoUtility.winset("pos", x + "," + y); - }; - var setSize = function (w, h) { - NanoUtility.winset("size", w + "," + h); - }; - - var obeyLimits = function () { - // Alignment (Thanks Goon (CC BY-NC-SA v3)) - var prevX = window.screenLeft; - var prevY = window.screenTop; - //Put the window at top left - setPos(0, 0); - //Get any offsets still present - offsetX = window.screenLeft; - offsetY = window.screenTop; - // Clamp it to the viewport - var clampedX = prevX - offsetX; - var clampedY = prevY - offsetY; - clampedX = clampedX < offsetX ? 0 : clampedX; - clampedY = clampedY < offsetY ? 0 : clampedY; - // Put it back - setPos(clampedX, clampedY) - // Done with alignment - - // Size constraints - var height = $(window).height(); - var width = $(window).width(); - if($("body").height() >= ($(window).height() - 29)) { // Scrollbar!!! - width += 17 // 17 pixels is the width of a scrollbar - } - if($(document).width() > $(window).width()) { // Horizontal Scrollbar!!! - height += 17 - } - var newWidth = Math.max(minWidth, width); - var newHeight = Math.max(minHeight, height); - setSize(newWidth, newHeight); - }; - - var init = function () { - /* We want nanoUI windows to obey the limits regardless, - and we're hijacking this library to do so, even if fancy mode is turned off. - To be fair, this doesn't stop the user from shrinking them past their intended limit when they're not in fancy mode, - but it's a nice safeguard against shoddily-coded UIs. */ - obeyLimits(); - - if(!NanoStateManager.getData().config.user.fancy) { - return - } - - fancyChrome(); - // ... but when fancy mode is turned on, we have to do it again to make sure - // that the window offsets are correct for the slightly different window. - obeyLimits(); - - attachButtons(); - attachDragAndResize(); - }; - - var fancyChrome = function() { - NanoUtility.winset("titlebar", 0); - NanoUtility.winset("can-resize", 0); - NanoUtility.winset("transparent-color", "#FF00E4") - $('.fancy').show(); - $('#uiTitleFluff').css("right", "72px"); - $('.statusicon').css("left", "34px"); - $('#uiTitleText').css("left", "66px"); - }; - - var attachButtons = function() { - var close = function() { - return NanoUtility.close(); - }; - var minimize = function() { - return NanoUtility.winset("is-minimized", "true"); - }; - $(".close").on("click", function (event) { - close(); - }); - $(".minimize").on("click", function (event) { - minimize(); - }); - }; - - var attachDragAndResize = function() { - /* Drag */ - $("body").on("mousemove", "#uiTitleWrapper", function (ev) { - drag(ev); - }); - - $("body").on("mousedown", "#uiTitleWrapper", function () { - dragging = true; - if ($(this)[0].setCapture) { $(this)[0].setCapture(); } - }); - - $("body").on("mouseup", "#uiTitleWrapper", function () { - dragging = false; - if ($(this)[0].releaseCapture) { $(this)[0].releaseCapture(); } - }); - - /* Resize */ - $("body").on("mousemove", "div.resizeArea", function (ev) { - resize.call(this, ev); - }); - - $("body").on("mousedown", "div.resizeArea", function () { - resizing = true; - if (this.setCapture) { this.setCapture(); } - }) - - $("body").on("mouseup", "div.resizeArea", function () { - resizing = false; - if (this.releaseCapture) { this.releaseCapture(); } - }); - }; - - /* Stolen Goon code ftw (CC BY-NC-SA v3.0) */ - var dragging, lastX, lastY; - var drag = function (ev) { - ev = ev || window.event; - if (lastX === ev.screenX && lastY === ev.screenY) { - return - } - - if (lastX === undefined) { - lastX = ev.screenX; - lastY = ev.clientY; - } - - if (dragging) { - var dx = (ev.screenX - lastX); - var dy = (ev.screenY - lastY); - dx += window.screenLeft - offsetX; - dy += window.screenTop - offsetY; - - setPos(dx, dy); - } - - lastX = ev.screenX; - lastY = ev.screenY; - } - - var resizing, resizeWorking - var resize = function (ev) { - if (resizeWorking) { - return; - } - - resizeWorking = true; - ev = ev || window.event; - - if (lastX === undefined) { - lastX = ev.screenX - offsetX; - lastY = ev.screenY - offsetY; - } - - if (resizing) { - var width = $(window).width(); - var height = $(window).height(); - - if($("body").height() >= ($(window).height() - 29)) { // Vertical Scrollbar!!! - width += 17 // 17 pixels is the width of a scrollbar - } - - if($(document).width() > $(window).width()) { // Horizontal Scrollbar!!! - height += 17 - } - - var rx = Number($(this).attr("rx")); - var ry = Number($(this).attr("ry")); - - var dx = ((ev.screenX-offsetX) - lastX); - var dy = ((ev.screenY-offsetY) - lastY); - - var newX = window.screenLeft - offsetX; - var newY = window.screenTop - offsetY; - - var newW = width + (dx * rx); - if(rx == -1){ - newX += dx; - } - var newH = height + (dy * ry); - if(ry == -1){ - newY += dy; - } - - newW = Math.max(minWidth, newW); - newH = Math.max(minHeight, newH); - setPos(newX, newY); - setSize(newW, newH); - } - - lastX = ev.screenX - offsetX; - lastY = ev.screenY - offsetY; - - resizeWorking = false; - }; - /* End stolen Goon code */ - - return { - init: function () { //crazy but ensures correct load order (nanoutil - nanotemplate - nanowindow) - $(document).on('templatesLoaded', function () { - init(); - }); - } - }; -}(); \ No newline at end of file diff --git a/nano/styles/_bars.less b/nano/styles/_bars.less deleted file mode 100644 index 90eb3557144..00000000000 --- a/nano/styles/_bars.less +++ /dev/null @@ -1,77 +0,0 @@ -.displayBar { - position: relative; - width: 236px; - height: 16px; - border: 1px solid #666666; - float: left; - margin: 0 5px 0 0; - overflow: hidden; - background: #000000; -} - -.displayBarText { - position: absolute; - top: -2px; - left: 5px; - width: 100%; - height: 100%; - color: #ffffff; - font-weight: normal; -} - -.displayBarFill { - width: 0%; - height: 100%; - background: #40628a; - overflow: hidden; - float: left; -} - -.displayBarFill.alignRight { - float: right; -} - -.displayBarText.good { - color: white; -} - -.displayBarText.notgood { - color: white; -} - -.displayBarText.average { - color: white; -} - -.displayBarText.bad { - color: white; -} - -.displayBarText.highlight { - color: black; -} - -.displayBarFill.good { - color: #ffffff; - background: @good-color; -} - -.displayBarFill.notgood { - color: #ffffff; - background: #ffb400; -} - -.displayBarFill.average { - color: #ffffff; - background: @average-color; -} - -.displayBarFill.bad { - color: #ffffff; - background: @bad-color; -} - -.displayBarFill.highlight { - color: #ffffff; - background: @highlight-color; -} diff --git a/nano/styles/_color.less b/nano/styles/_color.less deleted file mode 100644 index 68fc1d89c5b..00000000000 --- a/nano/styles/_color.less +++ /dev/null @@ -1,121 +0,0 @@ -@import "_config"; - -.white { - color: white; - font-weight: bold; -} - -.good { - color: @good-color; - font-weight: bold; -} - -.average { - color: @average-color; - font-weight: bold; -} - -.bad { - color: @bad-color; - font-weight: bold; -} - -.idle { - color: @dark-color; - font-weight: bold; -} - -.redButton { - background: #ea0000; -} - -.yellowButton { - background: #cacc00; -} - -.highlight { - color: @highlight-color; -} - -.dark { - color: @dark-color; -} - -/* Damage colors for crew monitoring computer */ -.burn { - color: orange; -} - -.brute { - color: red; -} - -.toxin { - color: green; -} - -.toxin_light { - color: #3ADF00; -} - -.oxyloss { - color: blue; -} - -.oxyloss_light { - color: #6698FF; -} - -/* Wire colors for nuclear bomb defusion */ -.Red { - color: #FF0000; -} - -.Blue { - color: #0000FF; -} - -.Green { - color: #00FF00; -} - -.Marigold { - color: #FDA505; -} - -.Fuschia { - color: #FF0080; -} - -.Black { - color: #000000; -} - -.Pearl { - color: #C6CACB; -} - -/* Status bar colors for sleeper temperatures */ -.cold1 { - color: #94B8FF; -} - -.cold2 { - color: #6699FF; -} - -.cold3 { - color: #293D66; -} - -.hot1 { - color: #FF9966; -} - -.hot2 { - color: #993D00; -} - -.hot3 { - color: #FF6600; -} \ No newline at end of file diff --git a/nano/styles/_config.less b/nano/styles/_config.less deleted file mode 100644 index dffcc37331c..00000000000 --- a/nano/styles/_config.less +++ /dev/null @@ -1,15 +0,0 @@ -// Fonts -@font: Verdana, Geneva, sans-serif; -@fontsize: 12px; - -// Body Colors -@background-start: #2a2a2a; -@background-end: #202020; - -// Element Colors -@good-color: #4f7529; -@average-color: #cd6500; -@bad-color: #ee0000; - -@highlight-color: #8BA5C4; -@dark-color: #272727; \ No newline at end of file diff --git a/nano/styles/_display.less b/nano/styles/_display.less deleted file mode 100644 index eb7c6216c24..00000000000 --- a/nano/styles/_display.less +++ /dev/null @@ -1,29 +0,0 @@ -div.display { - padding: 4px; - margin: 6px 0; - - background-color: rgba(0, 0, 0, 0.33); - box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.5); -} - -div.display header { - display: block; - position: relative; - width: 98.5%; - padding: 0 4px; - margin-bottom: 6px; - color: #FFFFFF; - border-bottom: 2px solid #40628a; -} - -div.display header .buttonRight { - position: absolute; - bottom: 6px; - right: 4px; -} - -div.display article { - display: table; - width: 100%; - border-collapse: collapse; -} \ No newline at end of file diff --git a/nano/styles/_fancy.less b/nano/styles/_fancy.less deleted file mode 100644 index 91ed656be82..00000000000 --- a/nano/styles/_fancy.less +++ /dev/null @@ -1,77 +0,0 @@ -.corner() { - position: fixed; - z-index: 101; - min-width: 30px; - min-height: 30px; -} - -#uiCornerTL { - .corner; - top: 0; - left: 0; - background: data-uri('tl.png') no-repeat; -} - -/* Resizing (Stolen from Goon CC-BY-NC-SA) */ -@resize: 5px; -.resizeArea { - position: absolute; - z-index: 99999; -} -.resizeArea.top { - top: 0; - left: 10px; - right: 10px; - height: @resize; - cursor: n-resize; -} -.resizeArea.tr { - top: 0; - right: 0; - height: 10px; - width: 10px; - cursor: ne-resize; -} -.resizeArea.right { - top: 10px; - right: 0; - bottom: 10px; - width: @resize; - cursor: e-resize; -} -.resizeArea.br { - bottom: 0; - right: 0; - height: 10px; - width: 10px; - cursor: se-resize; -} -.resizeArea.bottom { - bottom: 0; - left: 10px; - right: 10px; - height: @resize; - cursor: s-resize; -} -.resizeArea.bl { - bottom: 0; - left: 0; - height: 10px; - width: 10px; - cursor: sw-resize; -} -.resizeArea.left { - top: 10px; - left: 0; - bottom: 10px; - width: @resize; - cursor: w-resize; -} -.resizeArea.tl { - top: 0; - left: 0; - height: 10px; - width: 10px; - cursor: nw-resize; -} -/* End Resizing */ \ No newline at end of file diff --git a/nano/styles/_formatting.less b/nano/styles/_formatting.less deleted file mode 100644 index 06ee38dbc28..00000000000 --- a/nano/styles/_formatting.less +++ /dev/null @@ -1,197 +0,0 @@ -.itemGroup { - border: 1px solid #e9c183; - background: #2c2c2c; - padding: 4px; - clear: both; -} - - -.item { - width: 100%; - margin: 4px 0 0 0; - clear: both; - overflow: auto; -} - -.itemContentNarrow, .itemContent { - float: left; -} - -.itemContentNarrow { - width: 30%; -} - -.itemContent { - width: 69%; -} - -.itemLabelNarrow, .itemLabel, .itemLabelWide, .itemLabelWider, .itemLabelWidest { - float: left; - color: #e9c183; -} - -.itemLabelNarrow { - width: 20%; -} - -.itemLabel { - width: 30%; -} - -.itemLabelWide { - width: 45%; -} - -.itemLabelWider { - width: 69%; -} - -.itemLabelWidest { - width: 100%; -} - -.itemContentWide { - float: left; - width: 79%; -} - -.itemContentSmall { - float: left; - width: 33%; -} - -.itemContentMedium { - float: left; - width: 55%; -} - -.block { - padding: 8px; - margin: 10px 4px 4px 4px; - border: 1px solid #40628a; - background-color: #202020; -} - -.block h3 { - padding: 0; -} - -.clearBoth { - clear: both; -} - -.clearLeft { - clear: left; -} - -.clearRight { - clear: right; -} - -.line { - width: 100%; - clear: both; -} - -.fixedLeft { - width: 110px; - float: left; -} - -.fixedLeftWide { - width: 165px; - float: left; -} - -.fixedLeftWider { - width: 220px; - float: left; -} - -.fixedLeftWidest { - width: 250px; - float: left; -} - -.floatRight { - float: right; -} - -.floatLeft { - float: left; -} - -.hidden { - display: none; -} - - -.statusDisplay { - background: rgba(0, 0, 0, 0.5); - color: #ffffff; - border: 1px solid #40628a; - padding: 4px; - margin: 3px 0; - overflow: hidden; -} - -.statusDisplayRecords { - background: rgba(0, 0, 0, 0.5); - color: #ffffff; - border: 1px solid #40628a; - padding: 4px; - margin: 3px 0; - overflow-x: hidden; - overflow-y: auto; -} - -.statusLabel { - width: 138px; - float: left; - overflow: hidden; - color: #98B0C3; -} - -.statusValue { - float: left; -} - -.jobValues { - float: left; - width: 30%; -} - -// CHROMELESS STUFF - -.fancy { - display: none; -} - -i.fancy { - display: none; -} - -.titlebutton() { - color: #E9C183; - // Since we're on some hilariously outdated libraries, the below is an issue - // https://github.com/FortAwesome/Font-Awesome/issues/1274 - // Using the !important directive is necessary to override the FA styles - cursor: pointer !important; - z-index: 102; // This is for the corners - makes sure the buttons render on top - - &:hover { - color: lighten(#98b0c3, 10%); - } -} -.minimize { - .titlebutton; - position: absolute; - top: 6px; - right: 46px; -} -.close { - .titlebutton; - position: absolute; - top: 4px; - right: 12px; -} \ No newline at end of file diff --git a/nano/styles/_icon.less b/nano/styles/_icon.less deleted file mode 100644 index 7de6544e0e3..00000000000 --- a/nano/styles/_icon.less +++ /dev/null @@ -1,62 +0,0 @@ -/* Icons -----------------------------------*/ - -/* states and images */ -.uiLinkPendingIcon { - display: none; - float: left; - width: 16px; - height: 16px; - margin: 2px 2px 0 2px; - background-image: url(uiLinkPendingIcon.gif); -} - -.linkPending .fa { - display: none; -} - -.linkPending .uiLinkPendingIcon { - display: block; -} - -.mapIcon16 { - position: absolute; - width: 16px; - height: 16px; - background-image: url(uiIcons16Green.png); - background-position: -144px -96px; - background-repeat: no-repeat; - zoom: 0.125; - margin-left: -1px; - /*margin-bottom: -1px;*/ -} -.mapIcon16.dead { background-image: url(uiIcons16Red.png); } -.mapIcon16.bad { background-image: url(uiIcons16Red.png); } -.mapIcon16.average { background-image: url(uiIcons16Orange.png); } -.mapIcon16.good { background-image: url(uiIcons16Green.png); } -/* AirAlarm */ -.mapIcon16.icon-airalarm { background-position: 0 -144px; } -/* Command Positions */ -.mapIcon16.rank-captain { background-position: -224px -112px; } -.mapIcon16.rank-headofpersonnel { background-position: -112px -96px; } -.mapIcon16.rank-headofsecurity { background-position: -112px -128px; } -.mapIcon16.rank-chiefengineer { background-position: -176px -112px; } -.mapIcon16.rank-researchdirector { background-position: -128px -128px; } -.mapIcon16.rank-chiefmedicalofficer { background-position: -32px -128px; } -/* Engineering Positions */ -.mapIcon16.rank-stationengineer { background-position: -176px -112px; } -.mapIcon16.rank-atmospherictechnician { background-position: -176px -112px; } -/* Medical Positions */ -.mapIcon16.rank-medicaldoctor {background-position: -32px -128px; } -.mapIcon16.rank-geneticist {background-position: -32px -128px; } -.mapIcon16.rank-psychiatrist {background-position: -32px -128px; } -.mapIcon16.rank-chemist { background-position: -32px -128px; } -/* Science Positions */ -.mapIcon16.rank-scientist { background-position: -128px -128px; } -.mapIcon16.rank-geneticist { background-position: -128px -128px; } -.mapIcon16.rank-roboticist { background-position: -128px -128px; } -.mapIcon16.rank-xenobiologist { background-position: -128px -128px; } -/* Security Positions */ -.mapIcon16.rank-warden { background-position: -112px -128px; } -.mapIcon16.rank-detective { background-position: -112px -128px; } -.mapIcon16.rank-securityofficer { background-position: -112px -128px; } \ No newline at end of file diff --git a/nano/styles/_link.less b/nano/styles/_link.less deleted file mode 100644 index 5a3d7fa267e..00000000000 --- a/nano/styles/_link.less +++ /dev/null @@ -1,110 +0,0 @@ -.link, .linkOn, .linkOff, .selected, .disabled, .yellowButton, .redButton, .linkEncourage, .linkDiscourage { - float: left; - min-width: 15px; - height: 16px; - text-align: center; - color: #ffffff; - text-decoration: none; - background: #40628a; - border: 1px solid #161616; - padding: 0px 4px 4px 4px; - margin: 0 2px 2px 0; - cursor: default; - white-space: nowrap; -} - -.hasIcon { - padding: 0px 4px 4px 0px; -} - -a.hover, .zoomLink.hover, .linkActive.hover { - background: #507aac; -} - -@keyframes pendingAnimation { - to { - color: #ffffff; - background: #507aac; - } -} - -.linkPending, .linkPending.hover { - animation-name: pendingAnimation; - animation-duration: 0.25s; -} - -a.white, a.white:link, a.white:visited, a.white:active { - color: #40628a; - text-decoration: none; - background: #ffffff; - border: 1px solid #161616; - padding: 1px 4px 1px 4px; - margin: 0 2px 0 0; - cursor: default; -} - -a.white.hover { - color: #ffffff; - background: #40628a; -} - -.linkOn, a.linkOn:link, a.linkOn:visited, a.linkOn:active, a.linkOn.hover, .selected, a.selected:link, a.selected:visited, a.selected:active, a.selected.hover { - color: #ffffff; - background: #2f943c; -} - -.linkOff, a.linkOff:link, a.linkOff:visited, a.linkOff:active, a.linkOff.hover, .disabled, a.disabled:link, a.disabled:visited, a.disabled:active, a.disabled.hover { - color: #ffffff; - background: #999999; - border-color: #666666; -} - -a.icon, .linkOn.icon, .linkOff.icon, .selected.icon, .disabled.icon { - position: relative; - padding: 1px 4px 2px 20px; -} - -a.icon img, .linkOn.icon img, .linkOff.icon img, .selected.icon img, .disabled.icon img { - position: absolute; - top: 0; - left: 0; - width: 18px; - height: 18px; -} - -.linkDanger, a.linkDanger:link, a.linkDanger:visited, a.linkDanger:active { - color: #ffffff; - background-color: #ff0000; - border-color: #aa0000; -} - -.linkDanger.hover { - background-color: #ff6666; -} - -.linkEncourage, a.linkEncourage:link, a.linkEncourage:visited, a.linkEncourage:active { - color: #99ff33; - background-color: #40628a; - border-color: #161616; -} - -.linkEncourage.hover { - background-color: #507aac; -} - -.linkDiscourage, a.linkDiscourage:link, a.linkDiscourage:visited, a.linkDiscourage:active { - color: #8c8c8c; - background-color: #40628a; - border-color: #161616; -} - -.linkDiscourage.hover { - color: #ff0000; - background-color: #507aac; -} - -.inactive, a.inactive:link, a.inactive:visited, a.inactive:active, a.inactive.hover { - color: #ffffff; - background: #999999; - border-color: #666666; -} \ No newline at end of file diff --git a/nano/styles/_lists.less b/nano/styles/_lists.less deleted file mode 100644 index 75ec81911bd..00000000000 --- a/nano/styles/_lists.less +++ /dev/null @@ -1,88 +0,0 @@ -ul { - padding: 4px 0 0 10px; - margin: 0; - list-style-type: none; -} - -li { - padding: 0 0 2px 0; -} - -table.fixed { - table-layout:fixed; -} - -table.fixed td { - overflow: hidden; -} - -/* Table styling for the power monitor */ -table.pmon { - border: 2px solid RoyalBlue; -} - -table.pmon td, table.pmon th { - border-bottom: 1px dotted black; - padding: 0px 5px 0px 5px; -} - -/* Table styling for the crew manifest */ -.manifest-header(@color: #666) { - background: @color; - font-weight: bold; - color: #ffffff; -} - -th.command { - .manifest-header(#3333FF); -} - -th.sec { - .manifest-header(#8e0000); -} - -th.med { - .manifest-header(#006600); -} - -th.eng { - .manifest-header(#b27300); -} - -th.sci { - .manifest-header(#a65ba6); -} - -th.ser { - .manifest-header(#7100AA); -} - -th.sup { - .manifest-header(#666621); -} - -th.civ { - .manifest-header(#a32800); -} - -th.misc { - .manifest-header; -} - -span.qm-job { - color: mix(@highlight-color, @average-color, 33%); - font-weight: bold; -} - -/* Striped lines for tables and divs */ -.striped { - .striped-base() { - background-color: #404040; - } - tr:nth-child(even) { - .striped-base; - } - &:not(table) > :nth-child(even) { - .striped-base; - } -} \ No newline at end of file diff --git a/nano/styles/_misc.less b/nano/styles/_misc.less deleted file mode 100644 index 17af95368ce..00000000000 --- a/nano/styles/_misc.less +++ /dev/null @@ -1,179 +0,0 @@ -#uiNoScript { - position: fixed; - top: 50%; - left: 50%; - margin: -60px 0 0 -150px; - width: 280px; - height: 120px; - background: #ffffff; - border: 2px solid #ff0000; - color: #000000; - font-size: 10px; - font-weight: bold; - z-index: 9999; - padding: 0px 10px; - text-align: center; -} - -/********************************** - .notice | Caution Stripes -**********************************/ -.notice { - position: relative; - background: url(uiNoticeBackground.jpg) 50% 50%; - color: #000000; - font-size: 12px; - font-style: italic; - font-weight: bold; - padding: 3px 4px 3px 4px; - margin: 4px 0 4px 0; -} - -.noticePlaceholder { - position: relative; - font-size: 12px; - font-style: italic; - font-weight: bold; - padding: 3px 4px 3px 4px; - margin: 4px 0 4px 0; -} - -.notice.icon { - padding: 2px 4px 0 20px; -} - -.notice img { - position: absolute; - top: 0; - left: 0; - width: 16px; - height: 16px; -} - -div.notice { - clear: both; -} -/********************\ -\********************/ - - -/********************************** - PDA, DNA Modifier styles - Don't fit anywhere else. -**********************************/ - -/* PDA styling */ -.wholeScreen { - position: absolute; - color: #517087; - font-size: 16px; - font-weight: bold; - text-align: center; -} - -.pdalink { - float: left; - white-space: nowrap; - cursor: default !important; - - &.disabled { - background: none; - border: none; - color: #999; - text-align: left; - } -} - -.pdanote { - color: #cd6500; - font-weight: bold; -} - -.item.mainmenu { - padding-bottom: 0.5em; -} - -div.clock { - color: white; - font-weight: bold; - float: right; - padding-right: 2em; -} - -#pdaFooter { - position: fixed; - left: 0; - bottom: 0; - width: 100%; - background: @dark-color; -} - -.pdaFooterButton { - width: 33%; - padding: 0.5em 0; - font-size: 200%; - border: none; - background: none; - color: #fff; - - &.hover { - background: #507aac; - } - - &.disabled { - background: none !important; - color: #555 !important; - } - - .uiLinkPendingIcon { - position: absolute; - width: 33%; - background-repeat: no-repeat; - background-position: center; - } -} - -/* DNA Modifier styling */ -.dnaBlock { - float: left; - width: 90px; - padding: 0 0 5px 0; -} - -.dnaBlockNumber { - font-family: Fixed, monospace; - float: left; - color: #ffffff; - background: #363636; - min-width: 20px; - height: 20px; - padding: 0; - text-align: center; -} - -.dnaSubBlock { - font-family: Fixed, monospace; - float: left; - padding: 0; - min-width: 16px; - height: 20px; - text-align: center; -} - -.mask { - position: fixed; - left: 0; - top: 0; - width: 100%; - height: 100%; - background: url(uiMaskBackground.png); -} - -.maskContent { - width: 100%; - height: 200px; - margin: 200px 0; - text-align: center; -} -/********************\ -\********************/ \ No newline at end of file diff --git a/nano/styles/_native.less b/nano/styles/_native.less deleted file mode 100644 index 86a6b106e54..00000000000 --- a/nano/styles/_native.less +++ /dev/null @@ -1,43 +0,0 @@ -@import "_config"; - -body { - color: #ffffff; - font-family: @font; - font-size: @fontsize; - line-height: 170%; - margin: 0; - padding: 0; -} - -hr { - background-color: #40628a; - height: 1px; - border: none; -} - -img, a img { - border-style: none; -} - -h1, h2, h3, h4, h5, h6 { - margin: 0; - padding: 12px 0 6px 0; - color: #FFFFFF; - clear: both; -} - -h1 { - font-size: 18px; -} - -h2 { - font-size: 16px; -} - -h3 { - font-size: 14px; -} - -h4 { - font-size: 12px; -} \ No newline at end of file diff --git a/nano/styles/_tooltip.less b/nano/styles/_tooltip.less deleted file mode 100644 index a1384664eab..00000000000 --- a/nano/styles/_tooltip.less +++ /dev/null @@ -1,64 +0,0 @@ -*[data-tooltip] { - position: relative; - - &::after { - position: absolute; - display: block; - z-index: 2; - width: 250px; - padding: 10px; - transform: translateX(-50%); - - visibility: hidden; - opacity: 0; - - white-space: normal; - text-align: left; - content: attr(data-tooltip); - - transition: all .5s; - border: 1px solid #999999; - background-color: #363636; - } - - &:hover::after { - visibility: visible; - opacity: 1; - } - - &.tooltipTop::after { - bottom: 100%; - left: 50%; - transform: translateX(-50%) translateY(8px); - } - &.tooltipTop:hover::after { - transform: translateX(-50%) translateY(-8px); - } - - &.tooltipBottom::after { - top: 100%; - left: 50%; - transform: translateX(-50%) translateY(-8px); - } - &.tooltipBottom:hover::after { - transform: translateX(-50%) translateY(8px); - } - - &.tooltipLeft::after { - top: 50%; - right: 100%; - transform: translateX(8px) translateY(-50%); - } - &.tooltipLeft:hover::after { - transform: translateX(-8px) translateY(-50%); - } - - &.tooltipRight::after { - top: 50%; - left: 100%; - transform: translateX(-8px) translateY(-50%); - } - &.tooltipRight:hover::after { - transform: translateX(8px) translateY(-50%); - } -} \ No newline at end of file diff --git a/nano/styles/nanoui.less b/nano/styles/nanoui.less deleted file mode 100644 index d12026e05ff..00000000000 --- a/nano/styles/nanoui.less +++ /dev/null @@ -1,176 +0,0 @@ -@charset "utf-8"; - -@import "_bars"; -@import "_link"; -@import "_color"; -@import "_config"; -@import "_display"; -@import "_formatting"; -@import "_fancy"; -@import "_icon"; -@import "_lists"; -@import "_misc"; -@import "_native"; -@import "_tooltip"; - - -.mainBG { - position: fixed; - z-index: -1; - top: 30px; - left: 0px; - right: 0px; - bottom: 0px; - background: data-uri('nanotrasen.svg') no-repeat fixed center/70% 70%, - linear-gradient(to bottom, - @background-start 0%, - @background-end 100%) no-repeat fixed center/100% 100%; -} - -//nano scrollbar styling -html,body { - scrollbar-face-color:#666666; - scrollbar-arrow-color:#E9C183; - scrollbar-track-color:#363636; - scrollbar-shadow-color:#555555; -} - -#uiWrapper { - width: 100%; - height: 100%; - -ms-user-select: none; - user-select: none; -} - -#uiTitleWrapper { - position: fixed; - min-height: 30px; - min-width: 100%; - background-color: #363636; - left: 0px; - top: 0px; - right: 0px; - overflow: hidden; - z-index: 100; - & > div { - cursor: default; - } - & > i { - cursor: default; - } -} - -#uiTitleText { - position: absolute; - top: 6px; - left: 44px; - width: 66%; - overflow: hidden; - color: #E9C183; - font-size: 16px; -} - -#uiTitle.icon { - padding: 6px 8px 6px 42px; - background-position: 2px 50%; - background-repeat: no-repeat; -} - -#uiTitleFluff { - position: absolute; - top: 4px; - right: 12px; - width: 42px; - height: 24px; - background: data-uri('nanotrasen.svg') 50% 50% no-repeat; -} - -.statusicon { - position: absolute; - top: 4px; - left: 12px; -} - -#uiMapWrapper { - clear: both; - padding: 8px; - margin-top: 30px; -} - -#uiMapHeader { - position: relative; - clear: both; -} - -#uiMapContainer { - position: relative; - width: 100%; - height: 600px; - overflow: hidden; - border: 1px solid #40628a; - background: url(nanomapBackground.png); -} - -#uiMap { - position: absolute; - top: 50%; - left: 50%; - margin: -512px 0 0 -512px; - width: 256px; - height: 256px; - overflow: hidden; - zoom: 4; -} - -#uiMapImage { - position: absolute; - bottom: 1px; - left: 1px; - width: 256px; - height: 256px; -} - -#uiMapContent { - position: absolute; - bottom: -13.5px; - left: 0px; - width: 256px; - height: 256px; -} - -#uiMapFooter { - position: relative; - clear: both; -} - -#uiContent { - clear: both; - padding: 8px; - margin-top: 30px; -} - -#uiMapTooltip { - position: absolute; - right: 10px; - top: 10px; - border: 1px solid #40628a; - background-color: #272727; - padding: 8px; - display: none; - z-index: 9999; -} - -#uiLoadingNotice { - position: relative; - background: url(uiNoticeBackground.jpg) 50% 50%; - color: #000000; - font-size: 14px; - font-style: italic; - font-weight: bold; - padding: 3px 4px 3px 4px; - margin: 4px 0 4px 0; -} - -.underTitle { - margin-top: 30px; -} \ No newline at end of file diff --git a/nano/templates/TemplatesGuide.txt b/nano/templates/TemplatesGuide.txt deleted file mode 100644 index 3b042edd0b0..00000000000 --- a/nano/templates/TemplatesGuide.txt +++ /dev/null @@ -1,10 +0,0 @@ --------------------------------- -Nano UI Template Guide --------------------------------- - -Nano UI uses templates, which are comprised of HTML and a markup syntax. The markup allows you -to easily add conditionals (if statements), loops (for loops) and custom formatting (using helpers). - -Templates are stored in the /nano/templates folder and the file extension is .tmpl. - -This guide is being replaced with a wiki entry, found here: http://baystation12.net/wiki/index.php?title=NanoUI \ No newline at end of file diff --git a/paradise.dme b/paradise.dme index 5281e747d8f..e4193e3b19e 100644 --- a/paradise.dme +++ b/paradise.dme @@ -241,7 +241,6 @@ #include "code\controllers\subsystem\medals.dm" #include "code\controllers\subsystem\mobs.dm" #include "code\controllers\subsystem\nano_mob_hunter.dm" -#include "code\controllers\subsystem\nanoui.dm" #include "code\controllers\subsystem\nightshift.dm" #include "code\controllers\subsystem\npcpool.dm" #include "code\controllers\subsystem\overlays.dm" @@ -2095,22 +2094,6 @@ #include "code\modules\mob\new_player\sprite_accessories\vulpkanin\vulpkanin_head_markings.dm" #include "code\modules\mob\new_player\sprite_accessories\vulpkanin\vulpkanin_tail_markings.dm" #include "code\modules\mob\new_player\sprite_accessories\wryn\wryn_face.dm" -#include "code\modules\nano\nanoexternal.dm" -#include "code\modules\nano\nanoui.dm" -#include "code\modules\nano\subsystem.dm" -#include "code\modules\nano\interaction\admin.dm" -#include "code\modules\nano\interaction\base.dm" -#include "code\modules\nano\interaction\conscious.dm" -#include "code\modules\nano\interaction\contained.dm" -#include "code\modules\nano\interaction\default.dm" -#include "code\modules\nano\interaction\ghost.dm" -#include "code\modules\nano\interaction\inventory.dm" -#include "code\modules\nano\interaction\inventory_deep.dm" -#include "code\modules\nano\interaction\not_incapacitated.dm" -#include "code\modules\nano\interaction\physical.dm" -#include "code\modules\nano\interaction\self.dm" -#include "code\modules\nano\interaction\zlevel.dm" -#include "code\modules\nano\modules\nano_module.dm" #include "code\modules\newscaster\datums.dm" #include "code\modules\newscaster\defines.dm" #include "code\modules\newscaster\obj\newscaster.dm" diff --git a/tgui/docs/converting-old-nano-interfaces.md b/tgui/docs/converting-old-nano-interfaces.md deleted file mode 100644 index 83d44220b1a..00000000000 --- a/tgui/docs/converting-old-nano-interfaces.md +++ /dev/null @@ -1,321 +0,0 @@ -# Converting old NanoUI interfaces to TGUI - -This guide is going to assume you already know roughly how tgui-next works, how to make new uis, etc. It's mostly aimed at helping translate concepts between nano and tgui-next, and clarify some confusing parts of the transition. - -## Backend - -Backend in almost every case does not require any changes. In particularly heavy ui cases, something to be aware of is the new `tgui_static_data()` proc. This proc allows you to split some data sent to the interface off into data that will only be sent on ui initialize and when manually updated by elsewhere in the code. Useful for things like cargo where you have a very large set of mostly identical code. - -Keep in mind that for uis where *all* data doesn't need to be live updating, you can just toggle off autoupdate for the ui instead of messing with static data. - -## Frontend - -The very first thing to note is the name of the `tmpl` file containing the old interface. Whatever the name is (minus the extension) is going to be what the route key is going to be. - -One thing I like to do before starting work on a conversion is screenshot what the old interface looks like so I have something to reference to make sure that the styling can line up as well. - -## General syntax changes - -Ractive has a fairly different templating syntax from React. - -### `data` - -You likely already know that React data inserts look like this - -```jsx -{data.example_data} -``` - -Ractive looks very similar, the only real difference is that React uses one paranthesis instead of two. - -```tmpl -{{data.example_data}} -``` - -However, you may occasionally come across data inserts that instead of referencing the `data` var or things contained within it instead reference `adata`. `adata` was short for animated data, and was used for smooth number animations in interfaces. instead of having a seperate data structure for this. tgui-next instead uses a component, which is `AnimatedNumber`. - -`AnimatedNumber` is used like this - -```jsx - -``` - -Make sure you don't forget to import it. - -### Conditionals - -Template conditionals look very different from React conditionals. - -A template `if` (only render if result of expression is true) looks like this - -```tmpl -{{#if data.condition}} - Example Render -{{/if}} -``` - -The equivalent React would be - -```jsx -{!!data.condition && ( - Example Render -)} -``` - -This might look a bit intimidating compared to the reactive part but it's not as complicated as it seems: - -1. A new jsx context is opened with `{}` -2. jsx contexts like this always render whatever the return value is, so we can use `&&` to return a value we want. `&&` returns the last true value (or not "falsey" because this is js). -3. jsx tags are never "falsey", so a conditioned paired with a jsx tag will mean the condition being true will continue on and return the tag. `()` is just used to contain the tag -4. The `!!` is not a special operator, it is a literal double negation. This is because most `false` values coming from byond are going to actually be `0`, which would be rendered if the condition is false. Negating `0` returns `true`, negating `true` returns `false`, which isn't rendered. -5. `Fragment` is actually a true "dead tag". It's similar to `span` in that it just contains things without providing functionality, but it's unwrapped before the final render and children of it are injected into its parent. In a case where you only need to render text without any styling, it's probably better to just return a string literal (`"Example Render"`), but this was just to illustrate that you can put any tag in this expression. - -You don't really need to know all this to understand how to use it, but I find it helps with understanding when things go wrong. - -Template conditionals can have an `else` as well -```tmpl -{{#if data.condition}} - value -{{else}} - other value -{{/if}} -``` - -Similarly to the previous example, just add a `||` operator to handle the -"falsy" condition: - -```jsx -{!!data.condition && ( - - value - -) || ( - - other value - -)} -``` - -There's also our good old friend - the ternary: - -```jsx -{data.condition ? 'value' : 'other value'} -``` - -Keep in mind you can also use tags here like the conditional example, -and you can mix string literals, values, and tags as well. - -```jsx -{data.is_robot ? ( -