diff --git a/_build_dependencies.sh b/_build_dependencies.sh index 04dcb4aaa22..b251bfbe325 100644 --- a/_build_dependencies.sh +++ b/_build_dependencies.sh @@ -1,11 +1,11 @@ # This file has all the information on what versions of libraries are thrown into the code # For dreamchecker -export SPACEMAN_DMM_VERSION=suite-1.8 +export SPACEMAN_DMM_VERSION=suite-1.7 # For NanoUI + TGUI export NODE_VERSION=16 # Byond Major -export BYOND_MAJOR=515 +export BYOND_MAJOR=514 # Byond Minor -export BYOND_MINOR=1630 +export BYOND_MINOR=1589 # Macro Count export MACRO_COUNT=4 diff --git a/code/__byond_version_compat.dm b/code/__byond_version_compat.dm index 6604aea70ba..086360e5e2e 100644 --- a/code/__byond_version_compat.dm +++ b/code/__byond_version_compat.dm @@ -1,3 +1,8 @@ +#if DM_VERSION >= 515 +#error PLEASE MAKE SURE THAT 515 IS PROPERLY TESTED AND WORKS. ESPECIALLY THE SAVE-FILES HAVE TO WORK. +#error Additionally: Make sure that the GitHub Workflow was updated to BYOND 515 as well. +#endif + // These defines are from __513_compatibility.dm -- Please Sort #define CLAMP(CLVALUE, CLMIN, CLMAX) clamp(CLVALUE, CLMIN, CLMAX) #define TAN(x) tan(x) diff --git a/code/__defines/dcs/signals.dm b/code/__defines/dcs/signals.dm index ad7c9b4f346..06fb819b075 100644 --- a/code/__defines/dcs/signals.dm +++ b/code/__defines/dcs/signals.dm @@ -779,20 +779,3 @@ #define ELEMENT_CONFLICT_FOUND (1<<0) //From reagents touch_x. #define COMSIG_REAGENTS_TOUCH "reagent_touch" - - -//Moved observer stuff to DCS -#define COMSIG_OBSERVER_MOVED "observer_move" -#define COMSIG_OBSERVER_DESTROYED "observer_destroyed" -#define COMSIG_OBSERVER_SHUTTLE_ADDED "observer_shuttle_added" -#define COMSIG_OBSERVER_SHUTTLE_PRE_MOVE "observer_shuttle_premove" -#define COMSIG_OBSERVER_SHUTTLE_MOVED "observer_shuttle_moved" -#define COMSIG_OBSERVER_TURF_ENTERED "observer_turf_entered" -#define COMSIG_OBSERVER_TURF_EXITED "observer_turf_exited" -#define COMSIG_OBSERVER_Z_MOVED "observer_z_moved" -#define COMSIG_OBSERVER_MOB_EQUIPPED "observer_mob_equipped" -#define COMSIG_OBSERVER_ITEM_EQUIPPED "observer_item_equipped" -#define COMSIG_OBSERVER_MOB_UNEQUIPPED "observer_mob_unequipped" -#define COMSIG_OBSERVER_ITEM_UNEQUIPPED "observer_item_unequipped" -#define COMSIG_OBSERVER_APC "observer_apc" -#define COMSIG_OBSERVER_GLOBALMOVED "observer_global_move" diff --git a/code/__defines/qdel.dm b/code/__defines/qdel.dm index 7d815fe0f3d..cf1afe492e7 100644 --- a/code/__defines/qdel.dm +++ b/code/__defines/qdel.dm @@ -1,6 +1,4 @@ -//! Defines that give qdel hints. -//! -//! These can be given as a return in [/atom/proc/Destroy] or by calling [/proc/qdel]. +//defines that give qdel hints. these can be given as a return in destory() or by calling /// `qdel` should queue the object for deletion. #define QDEL_HINT_QUEUE 0 @@ -13,56 +11,41 @@ // Qdel should assume this object won't gc, and hard delete it posthaste. #define QDEL_HINT_HARDDEL_NOW 4 - #ifdef REFERENCE_TRACKING /** If REFERENCE_TRACKING is enabled, qdel will call this object's find_references() verb. * * Functionally identical to [QDEL_HINT_QUEUE] if [GC_FAILURE_HARD_LOOKUP] is not enabled in _compiler_options.dm. */ -#warn TG0001 qdel REFERENCE_TRACKING enabled #define QDEL_HINT_FINDREFERENCE 5 /// Behavior as [QDEL_HINT_FINDREFERENCE], but only if the GC fails and a hard delete is forced. #define QDEL_HINT_IFFAIL_FINDREFERENCE 6 #endif -// Defines for the ssgarbage queues -#define GC_QUEUE_FILTER 1 //! short queue to filter out quick gc successes so they don't hang around in the main queue for 5 minutes -#define GC_QUEUE_CHECK 2 //! main queue that waits 5 minutes because thats the longest byond can hold a reference to our shit. -#define GC_QUEUE_HARDDELETE 3 //! short queue for things that hard delete instead of going thru the gc subsystem, this is purely so if they *can* softdelete, they will soft delete rather then wasting time with a hard delete. -#define GC_QUEUE_COUNT 3 //! Number of queues, used for allocating the nested lists. Don't forget to increase this if you add a new queue stage - - -// Defines for the ssgarbage queue items -#define GC_QUEUE_ITEM_QUEUE_TIME 1 //! Time this item entered the queue -#define GC_QUEUE_ITEM_REF 2 //! Ref to the item -#define GC_QUEUE_ITEM_GCD_DESTROYED 3 //! Item's gc_destroyed var value. Used to detect ref reuse. -#define GC_QUEUE_ITEM_INDEX_COUNT 3 //! Number of item indexes, used for allocating the nested lists. Don't forget to increase this if you add a new queue item index - -// Defines for the time an item has to get its reference cleaned before it fails the queue and moves to the next. -#define GC_FILTER_QUEUE (1 SECONDS) -#define GC_CHECK_QUEUE (5 MINUTES) -#define GC_DEL_QUEUE (10 SECONDS) - +#define GC_QUEUE_CHECK 1 +#define GC_QUEUE_HARDDELETE 2 +#define GC_QUEUE_COUNT 2 //increase this when adding more steps. #define QDEL_ITEM_ADMINS_WARNED (1<<0) //! Set when admins are told about lag causing qdels in this type. #define QDEL_ITEM_SUSPENDED_FOR_LAG (1<<1) //! Set when a type can no longer be hard deleted on failure because of lag it causes while this happens. // Defines for the [gc_destroyed][/datum/var/gc_destroyed] var. +#define GC_QUEUED_FOR_QUEUING -1 #define GC_CURRENTLY_BEING_QDELETED -2 #define QDELING(X) (X.gc_destroyed) -#define QDELETED(X) (isnull(X) || QDELING(X)) +#define QDELETED(X) (!X || X.gc_destroyed) #define QDESTROYING(X) (!X || X.gc_destroyed == GC_CURRENTLY_BEING_QDELETED) -// This is a bit hacky, we do it to avoid people relying on a return value for the macro -// If you need that you should use QDEL_IN_STOPPABLE instead -#define QDEL_IN(item, time) addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(qdel), (time) > GC_FILTER_QUEUE ? WEAKREF(item) : item), time); -#define QDEL_IN_STOPPABLE(item, time) addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(qdel), (time) > GC_FILTER_QUEUE ? WEAKREF(item) : item), time, TIMER_STOPPABLE) +//Qdel helper macros. +#define QDEL_IN(item, time) addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(qdel), item), time, TIMER_STOPPABLE) #define QDEL_IN_CLIENT_TIME(item, time) addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(qdel), item), time, TIMER_STOPPABLE | TIMER_CLIENT_TIME) -#define QDEL_NULL(item) qdel(item); item = null +#define QDEL_NULL(item) if(item) {qdel(item); item = null} #define QDEL_NULL_LIST QDEL_LIST_NULL #define QDEL_LIST_NULL(x) if(x) { for(var/y in x) { qdel(y) } ; x = null } #define QDEL_LIST(L) if(L) { for(var/I in L) qdel(I); L.Cut(); } #define QDEL_LIST_IN(L, time) addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(______qdel_list_wrapper), L), time, TIMER_STOPPABLE) #define QDEL_LIST_ASSOC(L) if(L) { for(var/I in L) { qdel(L[I]); qdel(I); } L.Cut(); } #define QDEL_LIST_ASSOC_VAL(L) if(L) { for(var/I in L) qdel(L[I]); L.Cut(); } + +/proc/______qdel_list_wrapper(list/L) //the underscores are to encourage people not to use this directly. + QDEL_LIST(L) diff --git a/code/__defines/subsystems.dm b/code/__defines/subsystems.dm index 84c6fbd8a7c..6474a946ef1 100644 --- a/code/__defines/subsystems.dm +++ b/code/__defines/subsystems.dm @@ -127,7 +127,6 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G #define FIRE_PRIORITY_PING 10 #define FIRE_PRIORITY_AI 10 #define FIRE_PRIORITY_GARBAGE 15 -#define FIRE_PRIORITY_ASSETS 20 #define FIRE_PRIORITY_ALARM 20 #define FIRE_PRIORITY_CHARSETUP 25 #define FIRE_PRIORITY_AIRFLOW 30 diff --git a/code/_global_vars/misc.dm b/code/_global_vars/misc.dm index e767e04d97a..6ece6be2d7f 100644 --- a/code/_global_vars/misc.dm +++ b/code/_global_vars/misc.dm @@ -1,9 +1,9 @@ GLOBAL_LIST_EMPTY(error_last_seen) GLOBAL_LIST_EMPTY(error_cooldown) -//GLOBAL_DATUM_INIT(all_observable_events, /datum/all_observable_events, new) // This is a datum. It is not a list. -//GLOBAL_DATUM_INIT(destroyed_event, /decl/observ/destroyed, new()) +GLOBAL_DATUM_INIT(all_observable_events, /datum/all_observable_events, new) // This is a datum. It is not a list. +GLOBAL_DATUM_INIT(destroyed_event, /decl/observ/destroyed, new()) GLOBAL_VAR_INIT(timezoneOffset, 0) // The difference betwen midnight (of the host computer) and 0 world.ticks. -GLOBAL_VAR_INIT(TAB, "    ") +GLOBAL_VAR_INIT(TAB, "    ") \ No newline at end of file diff --git a/code/_helpers/_lists.dm b/code/_helpers/_lists.dm index 26124773229..76299d48797 100644 --- a/code/_helpers/_lists.dm +++ b/code/_helpers/_lists.dm @@ -53,7 +53,7 @@ // atoms/items/objects can be pretty and whatnot var/atom/A = item if(output_icons && isicon(A.icon) && !ismob(A)) // mobs tend to have unusable icons - item_str += "[bicon(A)] " + item_str += "\icon[A][bicon(A)] " switch(determiners) if(DET_NONE) item_str += A.name if(DET_DEFINITE) item_str += "\the [A]" diff --git a/code/_helpers/global_lists.dm b/code/_helpers/global_lists.dm index 1d3f8ed8d4f..a160069be49 100644 --- a/code/_helpers/global_lists.dm +++ b/code/_helpers/global_lists.dm @@ -327,32 +327,3 @@ GLOBAL_LIST_EMPTY(mannequins) */ //Hexidecimal numbers var/global/list/hexNums = list("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F") - -// Many global vars aren't GLOB type. This puts them there to be more easily inspected. -GLOBAL_LIST_EMPTY(legacy_globals) - -/proc/populate_legacy_globals() - //Note: these lists cannot be changed to a new list anywhere in code! - //If they are, these will cause the old list to stay around! - //Check by searching for " =" in the entire codebase - GLOB.legacy_globals["player_list"] = player_list - GLOB.legacy_globals["mob_list"] = mob_list - GLOB.legacy_globals["human_mob_list"] = human_mob_list - GLOB.legacy_globals["silicon_mob_list"] = silicon_mob_list - GLOB.legacy_globals["ai_list"] = ai_list - GLOB.legacy_globals["living_mob_list"] = living_mob_list - GLOB.legacy_globals["dead_mob_list"] = dead_mob_list - GLOB.legacy_globals["observer_mob_list"] = observer_mob_list - GLOB.legacy_globals["listening_objects"] = listening_objects - GLOB.legacy_globals["cleanbot_reserved_turfs"] = cleanbot_reserved_turfs - GLOB.legacy_globals["cable_list"] = cable_list - GLOB.legacy_globals["landmarks_list"] = landmarks_list - GLOB.legacy_globals["event_triggers"] = event_triggers - GLOB.legacy_globals["side_effects"] = side_effects - GLOB.legacy_globals["mechas_list"] = mechas_list - GLOB.legacy_globals["mannequins_"] = mannequins_ - //visual nets - GLOB.legacy_globals["visual_nets"] = visual_nets - GLOB.legacy_globals["cameranet"] = cameranet - GLOB.legacy_globals["cultnet"] = cultnet - GLOB.legacy_globals["existing_solargrubs"] = existing_solargrubs diff --git a/code/_helpers/icons.dm b/code/_helpers/icons.dm index b80e85c8299..9fd9e185002 100644 --- a/code/_helpers/icons.dm +++ b/code/_helpers/icons.dm @@ -536,13 +536,6 @@ GLOBAL_LIST_EMPTY(cached_examine_icons) CRASH("get_dummy_savefile failed to create a dummy savefile: '[error]'") return get_dummy_savefile(from_failure = TRUE) - -/// Generate a filename for this asset -/// The same asset will always lead to the same asset name -/// (Generated names do not include file extention.) -/proc/generate_asset_name(file) - return "asset.[md5(fcopy_rsc(file))]" - /** * Converts an icon to base64. Operates by putting the icon in the iconCache savefile, * exporting it as text, and then parsing the base64 from that. @@ -662,12 +655,12 @@ GLOBAL_LIST_EMPTY(cached_examine_icons) //var/name = SANITIZE_FILENAME("[generate_asset_name(thing)].png") var/name = "[generate_asset_name(thing)].png" if (!SSassets.cache[name]) - SSassets.transport.register_asset(name, thing) + register_asset(name, thing) for (var/thing2 in targets) - SSassets.transport.send_assets(thing2, name) + send_asset(thing2, name) if(sourceonly) - return SSassets.transport.get_asset_url(name) - return "" + return get_asset_url(name) + return "" //its either an atom, image, or mutable_appearance, we want its icon var icon2collapse = thing.icon @@ -704,12 +697,12 @@ GLOBAL_LIST_EMPTY(cached_examine_icons) key = "[name_and_ref[3]].png" if(!SSassets.cache[key]) - SSassets.transport.register_asset(key, rsc_ref, file_hash, icon_path) + register_asset(key, rsc_ref, file_hash, icon_path) for (var/client_target in targets) - SSassets.transport.send_assets(client_target, key) + send_asset(client_target, key) if(sourceonly) - return SSassets.transport.get_asset_url(key) - return "" + return get_asset_url(key) + return "" /proc/icon2base64html(target, var/custom_classes = "") if (!target) diff --git a/code/_helpers/sorts/TimSort.dm b/code/_helpers/sorts/TimSort.dm index f3b065f2fd9..cfa55f0dfa3 100644 --- a/code/_helpers/sorts/TimSort.dm +++ b/code/_helpers/sorts/TimSort.dm @@ -8,14 +8,10 @@ if(toIndex <= 0) toIndex += L.len + 1 - var/datum/sort_instance/SI = GLOB.sortInstance - if(!SI) - SI = new + sortInstance.L = L + sortInstance.cmp = cmp + sortInstance.associative = associative - SI.L = L - SI.cmp = cmp - SI.associative = associative - - SI.timSort(fromIndex, toIndex) + sortInstance.timSort(fromIndex, toIndex) return L diff --git a/code/_helpers/sorts/__main.dm b/code/_helpers/sorts/__main.dm index 41b5b7e7490..7fd0a505c70 100644 --- a/code/_helpers/sorts/__main.dm +++ b/code/_helpers/sorts/__main.dm @@ -9,13 +9,13 @@ #define MIN_GALLOP 7 //This is a global instance to allow much of this code to be reused. The interfaces are kept separately -GLOBAL_DATUM_INIT(sortInstance, /datum/sort_instance, new()) -/datum/sort_instance +var/datum/sortInstance/sortInstance = new() +/datum/sortInstance //The array being sorted. var/list/L //The comparator proc-reference - var/cmp = GLOBAL_PROC_REF(cmp_numeric_asc) + var/cmp = /proc/cmp_numeric_asc //whether we are sorting list keys (0: L[i]) or associated values (1: L[L[i]]) var/associative = 0 @@ -32,7 +32,7 @@ GLOBAL_DATUM_INIT(sortInstance, /datum/sort_instance, new()) var/list/runLens = list() -/datum/sort_instance/proc/timSort(start, end) +/datum/sortInstance/proc/timSort(start, end) runBases.Cut() runLens.Cut() @@ -97,7 +97,7 @@ lo the index of the first element in the range to be sorted hi the index after the last element in the range to be sorted start the index of the first element in the range that is not already known to be sorted */ -/datum/sort_instance/proc/binarySort(lo, hi, start) +/datum/sortInstance/proc/binarySort(lo, hi, start) //ASSERT(lo <= start && start <= hi) if(start <= lo) start = lo + 1 @@ -135,7 +135,7 @@ For its intended use in a stable mergesort, the strictness of the definition of "descending" is needed so that the call can safely reverse a descending sequence without violating stability. */ -/datum/sort_instance/proc/countRunAndMakeAscending(lo, hi) +/datum/sortInstance/proc/countRunAndMakeAscending(lo, hi) //ASSERT(lo < hi) var/runHi = lo + 1 @@ -165,7 +165,7 @@ reverse a descending sequence without violating stability. //Returns the minimum acceptable run length for an array of the specified length. //Natural runs shorter than this will be extended with binarySort -/datum/sort_instance/proc/minRunLength(n) +/datum/sortInstance/proc/minRunLength(n) //ASSERT(n >= 0) var/r = 0 //becomes 1 if any bits are shifted off while(n >= MIN_MERGE) @@ -178,7 +178,7 @@ reverse a descending sequence without violating stability. // runLen[i-2] > runLen[i-1] //This method is called each time a new run is pushed onto the stack. //So the invariants are guaranteed to hold for i= 2) var/n = runBases.len - 1 if(n > 1 && runLens[n-1] <= runLens[n] + runLens[n+1]) @@ -193,7 +193,7 @@ reverse a descending sequence without violating stability. //Merges all runs on the stack until only one remains. //Called only once, to finalise the sort -/datum/sort_instance/proc/mergeForceCollapse() +/datum/sortInstance/proc/mergeForceCollapse() while(runBases.len >= 2) var/n = runBases.len - 1 if(n > 1 && runLens[n-1] < runLens[n+1]) @@ -204,7 +204,7 @@ reverse a descending sequence without violating stability. //Merges the two consecutive runs at stack indices i and i+1 //Run i must be the penultimate or antepenultimate run on the stack //In other words, i must be equal to stackSize-2 or stackSize-3 -/datum/sort_instance/proc/mergeAt(i) +/datum/sortInstance/proc/mergeAt(i) //ASSERT(runBases.len >= 2) //ASSERT(i >= 1) //ASSERT(i == runBases.len - 1 || i == runBases.len - 2) @@ -258,7 +258,7 @@ reverse a descending sequence without violating stability. Returns the index at which to insert element 'key' */ -/datum/sort_instance/proc/gallopLeft(key, base, len, hint) +/datum/sortInstance/proc/gallopLeft(key, base, len, hint) //ASSERT(len > 0 && hint >= 0 && hint < len) var/lastOffset = 0 @@ -317,7 +317,7 @@ reverse a descending sequence without violating stability. * @param c the comparator used to order the range, and to search * @return the int k, 0 <= k <= n such that a[b + k - 1] <= key < a[b + k] */ -/datum/sort_instance/proc/gallopRight(key, base, len, hint) +/datum/sortInstance/proc/gallopRight(key, base, len, hint) //ASSERT(len > 0 && hint >= 0 && hint < len) var/offset = 1 @@ -369,7 +369,7 @@ reverse a descending sequence without violating stability. //Merges two adjacent runs in-place in a stable fashion. //For performance this method should only be called when len1 <= len2! -/datum/sort_instance/proc/mergeLo(base1, len1, base2, len2) +/datum/sortInstance/proc/mergeLo(base1, len1, base2, len2) //ASSERT(len1 > 0 && len2 > 0 && base1 + len1 == base2) var/cursor1 = base1 @@ -471,7 +471,7 @@ reverse a descending sequence without violating stability. //ASSERT(len1 > 1) -/datum/sort_instance/proc/mergeHi(base1, len1, base2, len2) +/datum/sortInstance/proc/mergeHi(base1, len1, base2, len2) //ASSERT(len1 > 0 && len2 > 0 && base1 + len1 == base2) var/cursor1 = base1 + len1 - 1 //start at end of sublists @@ -571,7 +571,7 @@ reverse a descending sequence without violating stability. //ASSERT(len2 > 0) -/datum/sort_instance/proc/mergeSort(start, end) +/datum/sortInstance/proc/mergeSort(start, end) var/remaining = end - start //If array is small, do an insertion sort @@ -616,7 +616,7 @@ reverse a descending sequence without violating stability. return L -/datum/sort_instance/proc/mergeAt2(i) +/datum/sortInstance/proc/mergeAt2(i) var/cursor1 = runBases[i] var/cursor2 = runBases[i+1] diff --git a/code/_helpers/text.dm b/code/_helpers/text.dm index 1cda5c811f0..571bf281ce6 100644 --- a/code/_helpers/text.dm +++ b/code/_helpers/text.dm @@ -348,10 +348,10 @@ return tagdesc if(!text_tag_cache[tagname]) var/icon/tag = icon(text_tag_icons, tagname) - text_tag_cache[tagname] = tag + text_tag_cache[tagname] = bicon(tag, TRUE, "text_tag") if(!C.tgui_panel.is_ready() || C.tgui_panel.oldchat) return "[tagdesc]" - return icon2html(text_tag_cache[tagname], C, extra_classes = "text_tag") + return text_tag_cache[tagname] /proc/create_text_tag_old(var/tagname, var/tagdesc = tagname, var/client/C = null) if(!(C && C.is_preference_enabled(/datum/client_preference/chat_tags))) diff --git a/code/_helpers/type2type.dm b/code/_helpers/type2type.dm index 9a54776afd1..8bd45bbfc76 100644 --- a/code/_helpers/type2type.dm +++ b/code/_helpers/type2type.dm @@ -423,9 +423,3 @@ catch(var/exception/E) if(error_on_invalid_return) error("Exception when loading file as string: [E]") - - -/// Return html to load a url. -/// for use inside of browse() calls to html assets that might be loaded on a cdn. -/proc/url2htmlloader(url) - return {""} diff --git a/code/_onclick/hud/ability_screen_objects.dm b/code/_onclick/hud/ability_screen_objects.dm index 7690b9d2033..cb500b4fe3a 100644 --- a/code/_onclick/hud/ability_screen_objects.dm +++ b/code/_onclick/hud/ability_screen_objects.dm @@ -183,13 +183,6 @@ if(!ability_master) //VOREStation Edit: S H A D E K I N ability_master = new /obj/screen/movable/ability_master(src) - -/mob/Destroy() - ..() - if(ability_master) - QDEL_NULL(ability_master) - - ///////////ACTUAL ABILITIES//////////// //This is what you click to do things// /////////////////////////////////////// @@ -390,4 +383,4 @@ A.name = object_given.name ability_objects.Add(A) if(my_mob.client) - toggle_open(2) //forces the icons to refresh on screen + toggle_open(2) //forces the icons to refresh on screen \ No newline at end of file diff --git a/code/_onclick/observer.dm b/code/_onclick/observer.dm index 50906085047..f89d4001476 100644 --- a/code/_onclick/observer.dm +++ b/code/_onclick/observer.dm @@ -24,8 +24,7 @@ ManualFollow(A) // Otherwise jump else - if(following) - stop_following() + following = null forceMove(get_turf(A)) /mob/observer/dead/ClickOn(var/atom/A, var/params) @@ -69,9 +68,9 @@ // VOREStation Edit Begin -/obj/machinery/gateway/centerstation/attack_ghost(mob/user as mob) - if(awaygate) - if(user.client.holder) +/obj/machinery/gateway/centerstation/attack_ghost(mob/user as mob) + if(awaygate) + if(user.client.holder) user.loc = awaygate.loc else if(active) user.loc = awaygate.loc diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index 9553b02ff4c..b4b5d955e76 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -304,18 +304,6 @@ var/list/gamemode_cache = list() var/static/invoke_youtubedl = null - var/static/asset_transport - - var/static/cache_assets = FALSE - - var/static/save_spritesheets = FALSE - - var/static/asset_simple_preload = FALSE - - var/static/asset_cdn_webroot - - var/static/asset_cdn_url - /datum/configuration/New() var/list/L = subtypesof(/datum/game_mode) for (var/T in L) @@ -991,24 +979,6 @@ var/list/gamemode_cache = list() if("invoke_youtubedl") config.invoke_youtubedl = value - if("asset_transport") - config.asset_transport = value - - if("cache_assets") - config.cache_assets = TRUE - - if("save_spritesheets") - config.save_spritesheets = TRUE - - if("asset_simple_preload") - config.asset_simple_preload = TRUE - - if("asset_cdn_webroot") - config.asset_cdn_webroot = value - - if("asset_cdn_url") - config.asset_cdn_url = value - else log_misc("Unknown setting in configuration: '[name]'") diff --git a/code/controllers/globals.dm b/code/controllers/globals.dm index cd6e7544dd4..6b7c0b41376 100644 --- a/code/controllers/globals.dm +++ b/code/controllers/globals.dm @@ -62,5 +62,3 @@ GLOBAL_REAL(GLOB, /datum/controller/global_vars) var/end_tick = world.time if(end_tick - start_tick) warning("Global [replacetext("[I]", "InitGlobal", "")] slept during initialization!") - - populate_legacy_globals() diff --git a/code/controllers/master.dm b/code/controllers/master.dm index 9b2df0d24ff..6d66e04789e 100644 --- a/code/controllers/master.dm +++ b/code/controllers/master.dm @@ -278,7 +278,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new //(higher subsystems will be sooner in the queue, adding them later in the loop means we don't have to loop thru them next queue add) sortTim(tickersubsystems, GLOBAL_PROC_REF(cmp_subsystem_priority)) for(var/I in runlevel_sorted_subsystems) - sortTim(I, GLOBAL_PROC_REF(cmp_subsystem_priority)) + sortTim(runlevel_sorted_subsystems, GLOBAL_PROC_REF(cmp_subsystem_priority)) I += tickersubsystems var/cached_runlevel = current_runlevel diff --git a/code/controllers/subsystems/asset_loading.dm b/code/controllers/subsystems/asset_loading.dm deleted file mode 100644 index 2d2939de4b2..00000000000 --- a/code/controllers/subsystems/asset_loading.dm +++ /dev/null @@ -1,28 +0,0 @@ -/// Allows us to lazyload asset datums -/// Anything inserted here will fully load if directly gotten -/// So this just serves to remove the requirement to load assets fully during init -SUBSYSTEM_DEF(asset_loading) - name = "Asset Loading" - priority = FIRE_PRIORITY_ASSETS - flags = SS_NO_INIT - runlevels = RUNLEVEL_LOBBY|RUNLEVELS_DEFAULT - var/list/datum/asset/generate_queue = list() - -/datum/controller/subsystem/asset_loading/fire(resumed) - while(length(generate_queue)) - var/datum/asset/to_load = generate_queue[generate_queue.len] - - to_load.queued_generation() - - if(MC_TICK_CHECK) - return - generate_queue.len-- - -/datum/controller/subsystem/asset_loading/proc/queue_asset(datum/asset/queue) -#ifdef DO_NOT_DEFER_ASSETS - stack_trace("We queued an instance of [queue.type] for lateloading despite not allowing it") -#endif - generate_queue += queue - -/datum/controller/subsystem/asset_loading/proc/dequeue_asset(datum/asset/queue) - generate_queue -= queue diff --git a/code/controllers/subsystems/assets.dm b/code/controllers/subsystems/assets.dm index 49e8a8f5781..522deae1776 100644 --- a/code/controllers/subsystems/assets.dm +++ b/code/controllers/subsystems/assets.dm @@ -2,39 +2,17 @@ SUBSYSTEM_DEF(assets) name = "Assets" init_order = INIT_ORDER_ASSETS flags = SS_NO_FIRE - var/list/datum/asset_cache_item/cache = list() + var/list/cache = list() var/list/preload = list() - var/datum/asset_transport/transport = new() -/datum/controller/subsystem/assets/proc/OnConfigLoad() - var/newtransporttype = /datum/asset_transport - switch (config.asset_transport) - if ("webroot") - newtransporttype = /datum/asset_transport/webroot +/datum/controller/subsystem/assets/Initialize(timeofday) + for(var/typepath in typesof(/datum/asset)) + var/datum/asset/A = typepath + if (typepath != initial(A._abstract)) + get_asset_datum(typepath) - if (newtransporttype == transport.type) - return + preload = cache.Copy() //don't preload assets generated during the round - var/datum/asset_transport/newtransport = new newtransporttype () - if (newtransport.validate_config()) - transport = newtransport - transport.Load() - - - -/datum/controller/subsystem/assets/Initialize() - OnConfigLoad() - - for(var/type in typesof(/datum/asset)) - var/datum/asset/A = type - if (type != initial(A._abstract)) - load_asset_datum(type) - - transport.Initialize(cache) - - subsystem_initialized = TRUE - return SS_INIT_SUCCESS - -/datum/controller/subsystem/assets/Recover() - cache = SSassets.cache - preload = SSassets.preload + for(var/client/C in GLOB.clients) + addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(getFilesSlow), C, preload, FALSE), 10) + return ..() diff --git a/code/controllers/subsystems/garbage.dm b/code/controllers/subsystems/garbage.dm index a4bc5ee17d1..400a61b0f94 100644 --- a/code/controllers/subsystems/garbage.dm +++ b/code/controllers/subsystems/garbage.dm @@ -1,26 +1,3 @@ -/*! -## Debugging GC issues - -In order to debug `qdel()` failures, there are several tools available. -To enable these tools, define `TESTING` in [_compile_options.dm](https://github.com/tgstation/-tg-station/blob/master/code/_compile_options.dm). - -First is a verb called "Find References", which lists **every** refererence to an object in the world. This allows you to track down any indirect or obfuscated references that you might have missed. - -Complementing this is another verb, "qdel() then Find References". -This does exactly what you'd expect; it calls `qdel()` on the object and then it finds all references remaining. -This is great, because it means that `Destroy()` will have been called before it starts to find references, -so the only references you'll find will be the ones preventing the object from `qdel()`ing gracefully. - -If you have a datum or something you are not destroying directly (say via the singulo), -the next tool is `QDEL_HINT_FINDREFERENCE`. You can return this in `Destroy()` (where you would normally `return ..()`), -to print a list of references once it enters the GC queue. - -Finally is a verb, "Show qdel() Log", which shows the deletion log that the garbage subsystem keeps. This is helpful if you are having race conditions or need to review the order of deletions. - -Note that for any of these tools to work `TESTING` must be defined. -By using these methods of finding references, you can make your life far, far easier when dealing with `qdel()` failures. -*/ - SUBSYSTEM_DEF(garbage) name = "Garbage" priority = FIRE_PRIORITY_GARBAGE @@ -28,9 +5,8 @@ SUBSYSTEM_DEF(garbage) flags = SS_POST_FIRE_TIMING|SS_BACKGROUND|SS_NO_INIT runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY init_order = INIT_ORDER_GARBAGE -// init_stage = INITSTAGE_EARLY - var/list/collection_timeout = list(GC_FILTER_QUEUE, GC_CHECK_QUEUE, GC_DEL_QUEUE) // deciseconds to wait before moving something up in the queue to the next level + var/list/collection_timeout = list(2 MINUTES, 10 SECONDS) // deciseconds to wait before moving something up in the queue to the next level //Stat tracking var/delslasttick = 0 // number of del()'s we've done this tick @@ -50,16 +26,18 @@ SUBSYSTEM_DEF(garbage) var/list/queues #ifdef REFERENCE_TRACKING var/list/reference_find_on_fail = list() - #ifdef REFERENCE_TRACKING_DEBUG - //Should we save found refs. Used for unit testing - var/should_save_refs = FALSE - #endif var/find_reference_on_fail_global_toggle = FALSE #endif /datum/controller/subsystem/garbage/PreInit() - InitQueues() + queues = new(GC_QUEUE_COUNT) + pass_counts = new(GC_QUEUE_COUNT) + fail_counts = new(GC_QUEUE_COUNT) + for(var/i in 1 to GC_QUEUE_COUNT) + queues[i] = list() + pass_counts[i] = 0 + fail_counts[i] = 0 /datum/controller/subsystem/garbage/stat_entry(msg) var/list/counts = list() @@ -83,48 +61,39 @@ SUBSYSTEM_DEF(garbage) /datum/controller/subsystem/garbage/Shutdown() //Adds the del() log to the qdel log file - var/list/del_log = list() + var/list/dellog = list() //sort by how long it's wasted hard deleting sortTim(items, cmp=/proc/cmp_qdel_item_time, associative = TRUE) for(var/path in items) var/datum/qdel_item/I = items[path] - var/list/entry = list() - del_log[path] = entry - + dellog += "Path: [path]" if (I.qdel_flags & QDEL_ITEM_SUSPENDED_FOR_LAG) - entry["SUSPENDED FOR LAG"] = TRUE + dellog += "\tSUSPENDED FOR LAG" if (I.failures) - entry["Failures"] = I.failures - entry["qdel() Count"] = I.qdels - entry["Destroy() Cost (ms)"] = I.destroy_time - + dellog += "\tFailures: [I.failures]" + dellog += "\tqdel() Count: [I.qdels]" + dellog += "\tDestroy() Cost: [I.destroy_time]ms" if (I.hard_deletes) - entry["Total Hard Deletes"] = I.hard_deletes - entry["Time Spend Hard Deleting (ms)"] = I.hard_delete_time - entry["Highest Time Spend Hard Deleting (ms)"] = I.hard_delete_max + dellog += "\tTotal Hard Deletes: [I.hard_deletes]" + dellog += "\tTime Spent Hard Deleting: [I.hard_delete_time]ms" + dellog += "\tHighest Time Spent Hard Deleting: [I.hard_delete_max]ms" if (I.hard_deletes_over_threshold) - entry["Hard Deletes Over Threshold"] = I.hard_deletes_over_threshold + dellog += "\tHard Deletes Over Threshold: [I.hard_deletes_over_threshold]" if (I.slept_destroy) - entry["Total Sleeps"] = I.slept_destroy + dellog += "\tSleeps: [I.slept_destroy]" if (I.no_respect_force) - entry["Total Ignored Force"] = I.no_respect_force + dellog += "\tIgnored force: [I.no_respect_force] times" if (I.no_hint) - entry["Total No Hint"] = I.no_hint - if(LAZYLEN(I.extra_details)) - entry["Deleted Metadata"] = I.extra_details - - log_debug("", del_log) + dellog += "\tNo hint: [I.no_hint] times" + text2file(dellog.Join(), "[log_path]-qdel.log") /datum/controller/subsystem/garbage/fire() //the fact that this resets its processing each fire (rather then resume where it left off) is intentional. - var/queue = GC_QUEUE_FILTER + var/queue = GC_QUEUE_CHECK while (state == SS_RUNNING) switch (queue) - if (GC_QUEUE_FILTER) - HandleQueue(GC_QUEUE_FILTER) - queue = GC_QUEUE_FILTER+1 if (GC_QUEUE_CHECK) HandleQueue(GC_QUEUE_CHECK) queue = GC_QUEUE_CHECK+1 @@ -134,21 +103,8 @@ SUBSYSTEM_DEF(garbage) state = SS_RUNNING break - - -/datum/controller/subsystem/garbage/proc/InitQueues() - if (isnull(queues)) // Only init the queues if they don't already exist, prevents overriding of recovered lists - queues = new(GC_QUEUE_COUNT) - pass_counts = new(GC_QUEUE_COUNT) - fail_counts = new(GC_QUEUE_COUNT) - for(var/i in 1 to GC_QUEUE_COUNT) - queues[i] = list() - pass_counts[i] = 0 - fail_counts[i] = 0 - - -/datum/controller/subsystem/garbage/proc/HandleQueue(level = GC_QUEUE_FILTER) - if (level == GC_QUEUE_FILTER) +/datum/controller/subsystem/garbage/proc/HandleQueue(level = GC_QUEUE_CHECK) + if (level == GC_QUEUE_CHECK) delslasttick = 0 gcedlasttick = 0 var/cut_off_time = world.time - collection_timeout[level] //ignore entries newer then this @@ -163,33 +119,30 @@ SUBSYSTEM_DEF(garbage) lastlevel = level -// 1 from the hard reference in the queue, and 1 from the variable used before this -#define REFS_WE_EXPECT 2 - - //We do this rather then for(var/list/ref_info in queue) because that sort of for loop copies the whole list. + //We do this rather then for(var/refID in queue) because that sort of for loop copies the whole list. //Normally this isn't expensive, but the gc queue can grow to 40k items, and that gets costly/causes overrun. for (var/i in 1 to length(queue)) var/list/L = queue[i] - if (length(L) < GC_QUEUE_ITEM_INDEX_COUNT) + if (length(L) < 2) count++ if (MC_TICK_CHECK) return continue - var/queued_at_time = L[GC_QUEUE_ITEM_QUEUE_TIME] - if(queued_at_time > cut_off_time) + var/GCd_at_time = L[1] + if(GCd_at_time > cut_off_time) break // Everything else is newer, skip them count++ + var/refID = L[2] + var/datum/D + D = locate(refID) - var/datum/D = L[GC_QUEUE_ITEM_REF] - - // If that's all we've got, send er off - if (refcount(D) == REFS_WE_EXPECT) + if (!D || D.gc_destroyed != GCd_at_time) // So if something else coincidently gets the same ref, it's not deleted by mistake ++gcedlasttick ++totalgcs pass_counts[level]++ #ifdef REFERENCE_TRACKING - reference_find_on_fail -= ref(D) //It's deleted we don't care anymore. + reference_find_on_fail -= refID //It's deleted we don't care anymore. #endif if (MC_TICK_CHECK) return @@ -205,33 +158,22 @@ SUBSYSTEM_DEF(garbage) switch (level) if (GC_QUEUE_CHECK) #ifdef REFERENCE_TRACKING - // Decides how many refs to look for (potentially) - // Based off the remaining and the ones we can account for - var/remaining_refs = refcount(D) - REFS_WE_EXPECT - if(reference_find_on_fail[ref(D)]) - INVOKE_ASYNC(D, TYPE_PROC_REF(/datum,find_references), remaining_refs) + if(reference_find_on_fail[refID]) + INVOKE_ASYNC(D, /datum/proc/find_references) ref_searching = TRUE #ifdef GC_FAILURE_HARD_LOOKUP else - INVOKE_ASYNC(D, TYPE_PROC_REF(/datum,find_references), remaining_refs) + INVOKE_ASYNC(D, /datum/proc/find_references) ref_searching = TRUE #endif - reference_find_on_fail -= ref(D) + reference_find_on_fail -= refID #endif var/type = D.type var/datum/qdel_item/I = items[type] - var/message = "## TESTING: GC: -- [ref(D)] | [type] was unable to be GC'd --" - message = "[message] (ref count of [refcount(D)])" - log_world(message) - - /*var/detail = D.dump_harddel_info() - if(detail) - LAZYADD(I.extra_details, detail)*/ - + log_world("## TESTING: GC: -- \ref[D] | [type] was unable to be GC'd --") #ifdef TESTING - for(var/c in GLOB.admins) //Using testing() here would fill the logs with ADMIN_VV garbage - var/client/admin = c + for(var/client/admin as anything in GLOB.admins) //Using testing() here would fill the logs with ADMIN_VV garbage if(!check_rights_for(admin, R_ADMIN)) continue to_chat(admin, "## TESTING: GC: -- [ADMIN_VV(D)] | [type] was unable to be GC'd --") @@ -263,41 +205,36 @@ SUBSYSTEM_DEF(garbage) queue.Cut(1,count+1) count = 0 -#undef REFS_WE_EXPECT - -/datum/controller/subsystem/garbage/proc/Queue(datum/D, level = GC_QUEUE_FILTER) +/datum/controller/subsystem/garbage/proc/Queue(datum/D, level = GC_QUEUE_CHECK) if (isnull(D)) return if (level > GC_QUEUE_COUNT) HardDelete(D) return - var/queue_time = world.time - - if (D.gc_destroyed <= 0) - D.gc_destroyed = queue_time + var/gctime = world.time + var/refid = "\ref[D]" + D.gc_destroyed = gctime var/list/queue = queues[level] - queue[++queue.len] = list(queue_time, D, D.gc_destroyed) // not += for byond reasons + + queue[++queue.len] = list(gctime, refid) // not += for byond reasons //this is mainly to separate things profile wise. /datum/controller/subsystem/garbage/proc/HardDelete(datum/D) ++delslasttick ++totaldels var/type = D.type - var/refID = ref(D) - var/datum/qdel_item/type_info = items[type] - /*var/detail = D.dump_harddel_info() - if(detail) - LAZYADD(type_info.extra_details, detail)*/ + var/refID = "\ref[D]" var/tick_usage = TICK_USAGE del(D) tick_usage = TICK_USAGE_TO_MS(tick_usage) - type_info.hard_deletes++ - type_info.hard_delete_time += tick_usage - if (tick_usage > type_info.hard_delete_max) - type_info.hard_delete_max = tick_usage + var/datum/qdel_item/I = items[type] + I.hard_deletes++ + I.hard_delete_time += tick_usage + if (tick_usage > I.hard_delete_max) + I.hard_delete_max = tick_usage if (tick_usage > highest_del_ms) highest_del_ms = tick_usage highest_del_type_string = "[type]" @@ -308,17 +245,15 @@ SUBSYSTEM_DEF(garbage) postpone(time) var/threshold = 0.5 // Default, make a config if (threshold && (time > threshold SECONDS)) - if (!(type_info.qdel_flags & QDEL_ITEM_ADMINS_WARNED)) - log_game("Error: [type]([refID]) took longer than [threshold] seconds to delete (took [round(time/10, 0.1)] seconds to delete)") - message_admins("Error: [type]([refID]) took longer than [threshold] seconds to delete (took [round(time/10, 0.1)] seconds to delete).") - type_info.qdel_flags |= QDEL_ITEM_ADMINS_WARNED - type_info.hard_deletes_over_threshold++ + if (!(I.qdel_flags & QDEL_ITEM_ADMINS_WARNED)) + log_and_message_admins("Error: [type]([refID]) took longer than [threshold] seconds to delete (took [round(time/10, 0.1)] seconds to delete)") + I.qdel_flags |= QDEL_ITEM_ADMINS_WARNED + I.hard_deletes_over_threshold++ var/overrun_limit = 0 // Default, make a config - if (overrun_limit && type_info.hard_deletes_over_threshold >= overrun_limit) - type_info.qdel_flags |= QDEL_ITEM_SUSPENDED_FOR_LAG + if (overrun_limit && I.hard_deletes_over_threshold >= overrun_limit) + I.qdel_flags |= QDEL_ITEM_SUSPENDED_FOR_LAG /datum/controller/subsystem/garbage/Recover() - InitQueues() //We first need to create the queues before recovering data if (istype(SSgarbage.queues)) for (var/i in 1 to SSgarbage.queues.len) queues[i] |= SSgarbage.queues[i] @@ -337,85 +272,79 @@ SUBSYSTEM_DEF(garbage) var/no_hint = 0 //!Number of times it's not even bother to give a qdel hint var/slept_destroy = 0 //!Number of times it's slept in its destroy var/qdel_flags = 0 //!Flags related to this type's trip thru qdel. - var/list/extra_details //!Lazylist of string metadata about the deleted objects /datum/qdel_item/New(mytype) name = "[mytype]" + /// Should be treated as a replacement for the 'del' keyword. /// /// Datums passed to this will be given a chance to clean up references to allow the GC to collect them. -/proc/qdel(datum/to_delete, force = FALSE) - if(!istype(to_delete)) - del(to_delete) +/proc/qdel(datum/D, force=FALSE, ...) + if(!istype(D)) + del(D) return - var/datum/qdel_item/trash = SSgarbage.items[to_delete.type] - if (isnull(trash)) - trash = SSgarbage.items[to_delete.type] = new /datum/qdel_item(to_delete.type) - trash.qdels++ + var/datum/qdel_item/I = SSgarbage.items[D.type] + if (!I) + I = SSgarbage.items[D.type] = new /datum/qdel_item(D.type) + I.qdels++ - if(!isnull(to_delete.gc_destroyed)) - if(to_delete.gc_destroyed == GC_CURRENTLY_BEING_QDELETED) - CRASH("[to_delete.type] destroy proc was called multiple times, likely due to a qdel loop in the Destroy logic") - return - - if (SEND_SIGNAL(to_delete, COMSIG_PARENT_PREQDELETED, force)) // Give the components a chance to prevent their parent from being deleted - return - - to_delete.gc_destroyed = GC_CURRENTLY_BEING_QDELETED - var/start_time = world.time - var/start_tick = world.tick_usage - SEND_SIGNAL(to_delete, COMSIG_PARENT_QDELETING, force) // Let the (remaining) components know about the result of Destroy - var/hint = to_delete.Destroy(force) // Let our friend know they're about to get fucked up. - - if(world.time != start_time) - trash.slept_destroy++ - else - trash.destroy_time += TICK_USAGE_TO_MS(start_tick) - - if(isnull(to_delete)) - return - - switch(hint) - if (QDEL_HINT_QUEUE) //qdel should queue the object for deletion. - SSgarbage.Queue(to_delete) - if (QDEL_HINT_IWILLGC) - to_delete.gc_destroyed = world.time + if(isnull(D.gc_destroyed)) + if (SEND_SIGNAL(D, COMSIG_PARENT_PREQDELETED, force)) // Give the components a chance to prevent their parent from being deleted return - if (QDEL_HINT_LETMELIVE) //qdel should let the object live after calling destory. - if(!force) - to_delete.gc_destroyed = null //clear the gc variable (important!) - return - // Returning LETMELIVE after being told to force destroy - // indicates the objects Destroy() does not respect force - #ifdef TESTING - if(!trash.no_respect_force) - testing("WARNING: [to_delete.type] has been force deleted, but is \ - returning an immortal QDEL_HINT, indicating it does \ - not respect the force flag for qdel(). It has been \ - placed in the queue, further instances of this type \ - will also be queued.") - #endif - trash.no_respect_force++ - - SSgarbage.Queue(to_delete) - if (QDEL_HINT_HARDDEL) //qdel should assume this object won't gc, and queue a hard delete - SSgarbage.Queue(to_delete, GC_QUEUE_HARDDELETE) - if (QDEL_HINT_HARDDEL_NOW) //qdel should assume this object won't gc, and hard del it post haste. - SSgarbage.HardDelete(to_delete) - #ifdef REFERENCE_TRACKING - if (QDEL_HINT_FINDREFERENCE) //qdel will, if REFERENCE_TRACKING is enabled, display all references to this object, then queue the object for deletion. - SSgarbage.Queue(to_delete) - INVOKE_ASYNC(to_delete, TYPE_PROC_REF(/datum, find_references)) - if (QDEL_HINT_IFFAIL_FINDREFERENCE) //qdel will, if REFERENCE_TRACKING is enabled and the object fails to collect, display all references to this object. - SSgarbage.Queue(to_delete) - SSgarbage.reference_find_on_fail[ref(to_delete)] = TRUE - #endif + D.gc_destroyed = GC_CURRENTLY_BEING_QDELETED + var/start_time = world.time + var/start_tick = world.tick_usage + SEND_SIGNAL(D, COMSIG_PARENT_QDELETING, force) // Let the (remaining) components know about the result of Destroy + var/hint = D.Destroy(arglist(args.Copy(2))) // Let our friend know they're about to get fucked up. + if(world.time != start_time) + I.slept_destroy++ else - #ifdef TESTING - if(!trash.no_hint) - testing("WARNING: [to_delete.type] is not returning a qdel hint. It is being placed in the queue. Further instances of this type will also be queued.") + I.destroy_time += TICK_USAGE_TO_MS(start_tick) + if(!D) + return + switch(hint) + if (QDEL_HINT_QUEUE) //qdel should queue the object for deletion. + SSgarbage.Queue(D) + if (QDEL_HINT_IWILLGC) + D.gc_destroyed = world.time + return + if (QDEL_HINT_LETMELIVE) //qdel should let the object live after calling destory. + if(!force) + D.gc_destroyed = null //clear the gc variable (important!) + return + // Returning LETMELIVE after being told to force destroy + // indicates the objects Destroy() does not respect force + #ifdef TESTING + if(!I.no_respect_force) + testing("WARNING: [D.type] has been force deleted, but is \ + returning an immortal QDEL_HINT, indicating it does \ + not respect the force flag for qdel(). It has been \ + placed in the queue, further instances of this type \ + will also be queued.") + #endif + I.no_respect_force++ + + SSgarbage.Queue(D) + if (QDEL_HINT_HARDDEL) //qdel should assume this object won't gc, and queue a hard delete + SSgarbage.Queue(D, GC_QUEUE_HARDDELETE) + if (QDEL_HINT_HARDDEL_NOW) //qdel should assume this object won't gc, and hard del it post haste. + SSgarbage.HardDelete(D) + #ifdef REFERENCE_TRACKING + if (QDEL_HINT_FINDREFERENCE) //qdel will, if REFERENCE_TRACKING is enabled, display all references to this object, then queue the object for deletion. + SSgarbage.Queue(D) + D.find_references() + if (QDEL_HINT_IFFAIL_FINDREFERENCE) //qdel will, if REFERENCE_TRACKING is enabled and the object fails to collect, display all references to this object. + SSgarbage.Queue(D) + SSgarbage.reference_find_on_fail["\ref[D]"] = TRUE #endif - trash.no_hint++ - SSgarbage.Queue(to_delete) + else + #ifdef TESTING + if(!I.no_hint) + testing("WARNING: [D.type] is not returning a qdel hint. It is being placed in the queue. Further instances of this type will also be queued.") + #endif + I.no_hint++ + SSgarbage.Queue(D) + else if(D.gc_destroyed == GC_CURRENTLY_BEING_QDELETED) + CRASH("[D.type] destroy proc was called multiple times, likely due to a qdel loop in the Destroy logic") diff --git a/code/controllers/subsystems/overlays.dm b/code/controllers/subsystems/overlays.dm index 9d840933cb7..25dbfbd62a6 100644 --- a/code/controllers/subsystems/overlays.dm +++ b/code/controllers/subsystems/overlays.dm @@ -77,31 +77,23 @@ SUBSYSTEM_DEF(overlays) var/list/result = list() var/icon/icon = subject.icon for (var/atom/entry as anything in sources) - AppearanceListEntry(entry, result, icon) + if (!entry) + continue + else if (istext(entry)) + result += GetStateAppearance(icon, entry) + else if (isicon(entry)) + result += GetIconAppearance(entry) + else + if (isloc(entry)) + if (entry.flags & OVERLAY_QUEUED) + entry.ImmediateOverlayUpdate() + if (!ispath(entry)) + result += entry.appearance + else + var/image/image = entry + result += image.appearance return result -//Fixes runtime with overlays present in 515 -/datum/controller/subsystem/overlays/proc/AppearanceListEntry(var/atom/entry,var/list/result,var/icon/icon) - if (!entry) - return - else if(islist(entry)) - var/list/entry_list = entry - for(var/entry_item in entry_list) - AppearanceListEntry(entry_item) - else if (istext(entry)) - result += GetStateAppearance(icon, entry) - else if (isicon(entry)) - result += GetIconAppearance(entry) - else - if (isloc(entry)) - if (entry.flags & OVERLAY_QUEUED) - entry.ImmediateOverlayUpdate() - if (!ispath(entry)) - if(entry.appearance) - result += entry.appearance - else - var/image/image = entry - result += image.appearance /// Enqueues the atom for an overlay update if not already queued /atom/proc/QueueOverlayUpdate() diff --git a/code/datums/chat_message.dm b/code/datums/chat_message.dm index 3a95ba1db59..d5540bd7903 100644 --- a/code/datums/chat_message.dm +++ b/code/datums/chat_message.dm @@ -147,14 +147,14 @@ var/list/runechat_image_cache = list() // Append prefixes if(extra_classes.Find("virtual-speaker")) - LAZYADD(prefixes, "[icon2html(runechat_image_cache["radio"],owner.client)]") + LAZYADD(prefixes, "\icon[runechat_image_cache["radio"]]") if(extra_classes.Find("emote")) // Icon on both ends? //var/image/I = runechat_image_cache["emote"] - //text = "icon2html(I)[text]icon2html(I)" + //text = "\icon[I][text]\icon[I]" // Icon on one end? - //LAZYADD(prefixes, "icon2html(runechat_image_cache["emote")]") + //LAZYADD(prefixes, "\icon[runechat_image_cache["emote"]]") // Asterisks instead? text = "* [text] *" diff --git a/code/datums/components/recursive_move.dm b/code/datums/components/recursive_move.dm deleted file mode 100644 index cf26942495b..00000000000 --- a/code/datums/components/recursive_move.dm +++ /dev/null @@ -1,119 +0,0 @@ -/** - * Recursive move listener - * Can be added willy-nilly to anything where the COMSIG_OBSERVER_MOVE signal should also trigger on a parent moving. - * Previously there was a system where COMSIG_OBSERVER_MOVE was always recursively propogated, but that was unnecessary bloat. - */ -/datum/component/recursive_move - dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS //This makes it so pretty much nothing happens when a duplicate component is created since we don't actually override InheritComponent - var/atom/movable/holder - var/list/parents = list() - var/noparents = FALSE - -/datum/component/recursive_move/RegisterWithParent() - . = ..() - holder = parent - RegisterSignal(holder, COMSIG_PARENT_QDELETING, PROC_REF(on_holder_qdel)) - spawn(0) // Delayed action if our holder is spawned in nullspace and then loc = target, hopefully this catches it. VV Add item does this, for example. - if(!QDELETED(src)) - setup_parents() - -/datum/component/recursive_move/proc/setup_parents() - if(length(parents)) // safety check just incase this was called without clearing - reset_parents() - var/atom/movable/cur_parent = holder?.loc // first loc could be null - var/recursion = 0 // safety check - max iterations - while(istype(cur_parent) && (recursion < 64)) - if(cur_parent == cur_parent.loc) //safety check incase a thing is somehow inside itself, cancel - log_debug("RECURSIVE_MOVE: Parent is inside itself. ([holder]) ([holder.type])") - reset_parents() - break - if(cur_parent in parents) //safety check incase of circular contents. (A inside B, B inside C, C inside A), cancel - log_debug("RECURSIVE_MOVE: Parent is inside a circular inventory. ([holder]) ([holder.type])") - reset_parents() - break - recursion++ - parents += cur_parent - RegisterSignal(cur_parent, COMSIG_ATOM_EXITED, PROC_REF(heirarchy_changed)) - RegisterSignal(cur_parent, COMSIG_PARENT_QDELETING, PROC_REF(on_qdel)) - - cur_parent = cur_parent.loc - - if(recursion >= 64) // If we escaped due to iteration limit, cancel - log_debug("RECURSIVE_MOVE: Parent hit recursion limit. ([holder]) ([holder.type])") - reset_parents() - parents.Cut() - - if(length(parents)) - //Only need to watch top parent for movement. Everything is covered by Exited - RegisterSignal(parents[parents.len], COMSIG_ATOM_ENTERING, PROC_REF(top_moved)) - - //If we have no parents of type atom/movable then we wait to see if that changes, checking every time our holder moves. - if(!length(parents) && !noparents) - noparents = TRUE - RegisterSignal(holder, COMSIG_ATOM_ENTERING, PROC_REF(setup_parents)) - - if(length(parents) && noparents) - noparents = FALSE - UnregisterSignal(holder, COMSIG_ATOM_ENTERING) - - -/datum/component/recursive_move/proc/unregister_signals() - if(noparents) // safety check - noparents = FALSE - UnregisterSignal(holder, COMSIG_ATOM_ENTERING) - if(!length(parents)) - return - for(var/atom/movable/cur_parent in parents) - UnregisterSignal(cur_parent, COMSIG_PARENT_QDELETING) - UnregisterSignal(cur_parent, COMSIG_ATOM_EXITED) - - UnregisterSignal(parents[parents.len], COMSIG_ATOM_ENTERING) - -//Parent at top of heirarchy moved. -/datum/component/recursive_move/proc/top_moved(var/atom/movable/am, var/atom/new_loc, var/atom/old_loc) - SIGNAL_HANDLER - SEND_SIGNAL(holder, COMSIG_OBSERVER_MOVED, old_loc, new_loc) - -//One of the parents other than the top parent moved. -/datum/component/recursive_move/proc/heirarchy_changed(var/atom/old_loc, var/atom/movable/am, var/atom/new_loc) - SIGNAL_HANDLER - SEND_SIGNAL(holder, COMSIG_OBSERVER_MOVED, old_loc, new_loc) - //Rebuild our list of parents - reset_parents() - setup_parents() - -//Some things will move their contents on qdel so we should prepare ourselves to be moved. -//If this qdel does destroy our holder, on_holder_qdel will handle preperations for GC -/datum/component/recursive_move/proc/on_qdel() - reset_parents() - noparents = TRUE - RegisterSignal(holder, COMSIG_ATOM_ENTERING, PROC_REF(setup_parents)) - -/datum/component/recursive_move/proc/on_holder_qdel() - UnregisterSignal(holder, COMSIG_PARENT_QDELETING) - reset_parents() - holder = null - qdel(src) - -/datum/component/recursive_move/Destroy() - . = ..() - reset_parents() - if(holder) UnregisterSignal(holder, COMSIG_PARENT_QDELETING) - holder = null - -/datum/component/recursive_move/proc/reset_parents() - unregister_signals() - parents.Cut() - -//the banana peel of testing stays -/obj/item/weapon/bananapeel/testing - name = "banana peel of testing" - desc = "spams world log with debugging information" - -/obj/item/weapon/bananapeel/testing/proc/shmove(var/atom/source, var/atom/old_loc, var/atom/new_loc) - world.log << "the [source] moved from [old_loc]([old_loc.x],[old_loc.y],[old_loc.z]) to [new_loc]([new_loc.x],[new_loc.y],[new_loc.z])" - -/obj/item/weapon/bananapeel/testing/Initialize() - . = ..() - AddComponent(/datum/component/recursive_move) - RegisterSignal(src, COMSIG_OBSERVER_MOVED, PROC_REF(shmove)) diff --git a/code/datums/observation/_debug.dm b/code/datums/observation/_debug.dm new file mode 100644 index 00000000000..5b805aa9302 --- /dev/null +++ b/code/datums/observation/_debug.dm @@ -0,0 +1,10 @@ +/**************** +* Debug Support * +****************/ + +/datum/all_observable_events + var/list/events + +/datum/all_observable_events/New() + events = list() + ..() diff --git a/code/datums/observation/_defines.dm b/code/datums/observation/_defines.dm new file mode 100644 index 00000000000..902d6558709 --- /dev/null +++ b/code/datums/observation/_defines.dm @@ -0,0 +1 @@ +#define CANCEL_MOVE_EVENT -55 diff --git a/code/datums/observation/destroyed.dm b/code/datums/observation/destroyed.dm index 9846eda6daf..650909f86d8 100644 --- a/code/datums/observation/destroyed.dm +++ b/code/datums/observation/destroyed.dm @@ -5,12 +5,11 @@ // // Arguments that the called proc should expect: // /datum/destroyed_instance: The instance that was destroyed. -/* + /decl/observ/destroyed name = "Destroyed" -*/ -//Deprecated in favor of Comsigs /datum/Destroy() - SEND_SIGNAL(src,COMSIG_OBSERVER_DESTROYED) + if(GLOB.destroyed_event) + GLOB.destroyed_event.raise_event(src) . = ..() diff --git a/code/datums/observation/dir_set.dm b/code/datums/observation/dir_set.dm new file mode 100644 index 00000000000..a626a07c4b3 --- /dev/null +++ b/code/datums/observation/dir_set.dm @@ -0,0 +1,35 @@ +// Observer Pattern Implementation: Direction Set +// Registration type: /atom +// +// Raised when: An /atom changes dir using the set_dir() proc. +// +// Arguments that the called proc should expect: +// /atom/dir_changer: The instance that changed direction +// /old_dir: The dir before the change. +// /new_dir: The dir after the change. + +GLOBAL_DATUM_INIT(dir_set_event, /decl/observ/dir_set, new) + +/decl/observ/dir_set + name = "Direction Set" + expected_type = /atom + +/decl/observ/dir_set/register(var/atom/dir_changer, var/datum/listener, var/proc_call) + . = ..() + + // Listen to the parent if possible. + if(. && istype(dir_changer.loc, /atom/movable)) // We don't care about registering to turfs. + register(dir_changer.loc, dir_changer, /atom/proc/recursive_dir_set) + +/********************* +* Direction Handling * +*********************/ + +/atom/movable/Entered(var/atom/movable/am, atom/old_loc) + . = ..() + if(. != CANCEL_MOVE_EVENT && GLOB.dir_set_event.has_listeners(am)) + GLOB.dir_set_event.register(src, am, /atom/proc/recursive_dir_set) + +/atom/movable/Exited(var/atom/movable/am, atom/old_loc) + . = ..() + GLOB.dir_set_event.unregister(src, am, /atom/proc/recursive_dir_set) diff --git a/code/datums/observation/equipped.dm b/code/datums/observation/equipped.dm index a64d1e76df4..4142050a356 100644 --- a/code/datums/observation/equipped.dm +++ b/code/datums/observation/equipped.dm @@ -7,7 +7,6 @@ // /mob/equipper: The mob that equipped the item. // /obj/item/item: The equipped item. // slot: The slot equipped to. -/* GLOBAL_DATUM_INIT(mob_equipped_event, /decl/observ/mob_equipped, new) /decl/observ/mob_equipped @@ -28,13 +27,12 @@ GLOBAL_DATUM_INIT(item_equipped_event, /decl/observ/item_equipped, new) /decl/observ/item_equipped name = "Item Equipped" expected_type = /obj/item -*/ -//Deprecated in favor of comsigs + /******************** * Equipped Handling * ********************/ /obj/item/equipped(var/mob/user, var/slot) . = ..() - SEND_SIGNAL(user, COMSIG_OBSERVER_MOB_EQUIPPED, src, slot) - SEND_SIGNAL(src, COMSIG_OBSERVER_ITEM_EQUIPPED, user, slot) + GLOB.mob_equipped_event.raise_event(user, src, slot) + GLOB.item_equipped_event.raise_event(src, user, slot) diff --git a/code/datums/observation/helpers.dm b/code/datums/observation/helpers.dm index bc1091c6687..12feeba16df 100644 --- a/code/datums/observation/helpers.dm +++ b/code/datums/observation/helpers.dm @@ -1,7 +1,6 @@ -/* /atom/movable/proc/recursive_move(var/atom/movable/am, var/old_loc, var/new_loc) - SEND_SIGNAL(src,COMSIG_OBSERVER_MOVED, old_loc, new_loc) -*/ + GLOB.moved_event.raise_event(src, old_loc, new_loc) + /atom/movable/proc/move_to_destination(var/atom/movable/am, var/old_loc, var/new_loc) var/turf/T = get_turf(new_loc) if(T && T != loc) @@ -13,12 +12,10 @@ /datum/proc/qdel_self() qdel(src) -/* -/proc/register_all_movement(var/event_source, var/datum/listener) - listener.RegisterSignal(event_source,COMSIG_OBSERVER_MOVED, /atom/movable/proc/recursive_move) - //GLOB.dir_set_event.register(event_source, listener, /atom/proc/recursive_dir_set) +/proc/register_all_movement(var/event_source, var/listener) + GLOB.moved_event.register(event_source, listener, /atom/movable/proc/recursive_move) + GLOB.dir_set_event.register(event_source, listener, /atom/proc/recursive_dir_set) -/proc/unregister_all_movement(var/event_source, var/datum/listener) - listener.UnregisterSignal(event_source,COMSIG_OBSERVER_MOVED) - //GLOB.dir_set_event.unregister(event_source, listener, /atom/proc/recursive_dir_set) -*/ +/proc/unregister_all_movement(var/event_source, var/listener) + GLOB.moved_event.unregister(event_source, listener, /atom/movable/proc/recursive_move) + GLOB.dir_set_event.unregister(event_source, listener, /atom/proc/recursive_dir_set) diff --git a/code/datums/observation/logged_in.dm b/code/datums/observation/logged_in.dm new file mode 100644 index 00000000000..c59e146a485 --- /dev/null +++ b/code/datums/observation/logged_in.dm @@ -0,0 +1,21 @@ +// Observer Pattern Implementation: Logged in +// Registration type: /mob +// +// Raised when: A mob logs in (not client) +// +// Arguments that the called proc should expect: +// /mob/joiner: The mob that has logged in + +GLOBAL_DATUM_INIT(logged_in_event, /decl/observ/logged_in, new) + +/decl/observ/logged_in + name = "Logged In" + expected_type = /mob + +/***************** +* Login Handling * +*****************/ + +/mob/Login() + ..() + GLOB.logged_in_event.raise_event(src) diff --git a/code/datums/observation/moved.dm b/code/datums/observation/moved.dm index f6ba4668369..3cd61c1cc6f 100644 --- a/code/datums/observation/moved.dm +++ b/code/datums/observation/moved.dm @@ -8,9 +8,8 @@ // /atom/old_loc: The loc before the move. // /atom/new_loc: The loc after the move. -/* -GLOBAL_DATUM_INIT(moved_event, /decl/observ/moved, new) +GLOBAL_DATUM_INIT(moved_event, /decl/observ/moved, new) /decl/observ/moved name = "Moved" @@ -22,30 +21,28 @@ GLOBAL_DATUM_INIT(moved_event, /decl/observ/moved, new) // Listen to the parent if possible. if(. && istype(mover.loc, expected_type)) register(mover.loc, mover, /atom/movable/proc/recursive_move) -*/ -//Deprecated in favor of comsigs /******************** * Movement Handling * ********************/ -/* /atom/movable/Entered(var/atom/movable/am, atom/old_loc) . = ..() - am.RegisterSignal(src,COMSIG_OBSERVER_MOVED, /atom/movable/proc/recursive_move, override = TRUE) + if(GLOB.moved_event.has_listeners(am)) + GLOB.moved_event.register(src, am, /atom/movable/proc/recursive_move) /atom/movable/Exited(var/atom/movable/am, atom/old_loc) . = ..() - am.UnregisterSignal(src,COMSIG_OBSERVER_MOVED) -*/ + GLOB.moved_event.unregister(src, am, /atom/movable/proc/recursive_move) + // Entered() typically lifts the moved event, but in the case of null-space we'll have to handle it. /atom/movable/Move() var/old_loc = loc . = ..() if(. && !loc) - SEND_SIGNAL(src,COMSIG_OBSERVER_MOVED, old_loc, null) + GLOB.moved_event.raise_event(src, old_loc, null) /atom/movable/forceMove(atom/destination) var/old_loc = loc . = ..() if(. && !loc) - SEND_SIGNAL(src,COMSIG_OBSERVER_MOVED, old_loc, null) + GLOB.moved_event.raise_event(src, old_loc, null) diff --git a/code/datums/observation/observation.dm b/code/datums/observation/observation.dm new file mode 100644 index 00000000000..db1f9e0d6ea --- /dev/null +++ b/code/datums/observation/observation.dm @@ -0,0 +1,238 @@ +// +// Observer Pattern Implementation +// +// Implements a basic observer pattern with the following main procs: +// +// /decl/observ/proc/is_listening(var/event_source, var/datum/listener, var/proc_call) +// event_source: The instance which is generating events. +// listener: The instance which may be listening to events by event_source +// proc_call: Optional. The specific proc to call when the event is raised. +// +// Returns true if listener is listening for events by event_source, and proc_call supplied is either null or one of the proc that will be called when an event is raised. +// +// /decl/observ/proc/has_listeners(var/event_source) +// event_source: The instance which is generating events. +// +// Returns true if the given event_source has any listeners at all, globally or to specific event sources. +// +// /decl/observ/proc/register(var/event_source, var/datum/listener, var/proc_call) +// event_source: The instance you wish to receive events from. +// listener: The instance/owner of the proc to call when an event is raised by the event_source. +// proc_call: The proc to call when an event is raised. +// +// It is possible to register the same listener to the same event_source multiple times as long as it is using different proc_calls. +// Registering again using the same event_source, listener, and proc_call that has been registered previously will have no additional effect. +// I.e.: The proc_call will still only be called once per raised event. That particular proc_call will only have to be unregistered once. +// +// When proc_call is called the first argument is always the source of the event (event_source). +// Additional arguments may or may not be supplied, see individual event definition files (destroyed.dm, moved.dm, etc.) for details. +// +// The instance making the register() call is also responsible for calling unregister(), see below for additonal details, including when event_source is destroyed. +// This can be handled by listening to the event_source's destroyed event, unregistering in the listener's Destroy() proc, etc. +// +// /decl/observ/proc/unregister(var/event_source, var/datum/listener, var/proc_call) +// event_source: The instance you wish to stop receiving events from. +// listener: The instance which will no longer receive the events. +// proc_call: Optional: The proc_call to unregister. +// +// Unregisters the listener from the event_source. +// If a proc_call has been supplied only that particular proc_call will be unregistered. If the proc_call isn't currently registered there will be no effect. +// If no proc_call has been supplied, the listener will have all registrations made to the given event_source undone. +// +// /decl/observ/proc/register_global(var/datum/listener, var/proc_call) +// listener: The instance/owner of the proc to call when an event is raised by any and all sources. +// proc_call: The proc to call when an event is raised. +// +// Works very much the same as register(), only the listener/proc_call will receive all relevant events from all event sources. +// Global registrations can overlap with registrations made to specific event sources and these will not affect each other. +// +// /decl/observ/proc/unregister_global(var/datum/listener, var/proc_call) +// listener: The instance/owner of the proc which will no longer receive the events. +// proc_call: Optional: The proc_call to unregister. +// +// Works very much the same as unregister(), only it undoes global registrations instead. +// +// /decl/observ/proc/raise_event(src, ...) +// Should never be called unless implementing a new event type. +// The first argument shall always be the event_source belonging to the event. Beyond that there are no restrictions. + +/decl/observ + var/name = "Unnamed Event" // The name of this event, used mainly for debug/VV purposes. The list of event managers can be reached through the "Debug Controller" verb, selecting the "Observation" entry. + var/expected_type = /datum // The expected event source for this event. register() will CRASH() if it receives an unexpected type. + var/list/event_sources = list() // Associative list of event sources, each with their own associative list. This associative list contains an instance/list of procs to call when the event is raised. + var/list/global_listeners = list() // Associative list of instances that listen to all events of this type (as opposed to events belonging to a specific source) and the proc to call. + +/decl/observ/New() + GLOB.all_observable_events.events += src + . = ..() + +/decl/observ/proc/is_listening(var/event_source, var/datum/listener, var/proc_call) + // Return whether there are global listeners unless the event source is given. + if (!event_source) + return !!global_listeners.len + + // Return whether anything is listening to a source, if no listener is given. + if (!listener) + return global_listeners.len || (event_source in event_sources) + + // Return false if nothing is associated with that source. + if (!(event_source in event_sources)) + return FALSE + + // Get and check the listeners for the reuqested event. + var/listeners = event_sources[event_source] + if (!(listener in listeners)) + return FALSE + + // Return true unless a specific callback needs checked. + if (!proc_call) + return TRUE + + // Check if the specific callback exists. + var/list/callback = listeners[listener] + if (!callback) + return FALSE + + return (proc_call in callback) + +/decl/observ/proc/has_listeners(var/event_source) + return is_listening(event_source) + +/decl/observ/proc/register(var/datum/event_source, var/datum/listener, var/proc_call) + // Sanity checking. + if (!(event_source && listener && proc_call)) + return FALSE + if (istype(event_source, /decl/observ)) + return FALSE + + // Crash if the event source is the wrong type. + if (!istype(event_source, expected_type)) + CRASH("Unexpected type. Expected [expected_type], was [event_source.type]") + + // Setup the listeners for this source if needed. + var/list/listeners = event_sources[event_source] + if (!listeners) + listeners = list() + event_sources[event_source] = listeners + + // Make sure the callbacks are a list. + var/list/callbacks = listeners[listener] + if (!callbacks) + callbacks = list() + listeners[listener] = callbacks + + // If the proc_call is already registered skip + if(proc_call in callbacks) + return FALSE + + // Add the callback, and return true. + callbacks += proc_call + return TRUE + +/decl/observ/proc/unregister(var/event_source, var/datum/listener, var/proc_call) + // Sanity. + if (!(event_source && listener && (event_source in event_sources))) + return FALSE + + // Return false if nothing is listening for this event. + var/list/listeners = event_sources[event_source] + if (!listeners) + return FALSE + + // Remove all callbacks if no specific one is given. + if (!proc_call) + if(listeners.Remove(listener)) + // Perform some cleanup and return true. + if (!listeners.len) + event_sources -= event_source + return TRUE + return FALSE + + // See if the listener is registered. + var/list/callbacks = listeners[listener] + if (!callbacks) + return FALSE + + // See if the callback exists. + if(!callbacks.Remove(proc_call)) + return FALSE + + if (!callbacks.len) + listeners -= listener + if (!listeners.len) + event_sources -= event_source + return TRUE + +/decl/observ/proc/register_global(var/datum/listener, var/proc_call) + // Sanity. + if (!(listener && proc_call)) + return FALSE + + // Make sure the callbacks are setup. + var/list/callbacks = global_listeners[listener] + if (!callbacks) + callbacks = list() + global_listeners[listener] = callbacks + + // Add the callback and return true. + callbacks |= proc_call + return TRUE + +/decl/observ/proc/unregister_global(var/datum/listener, var/proc_call) + // Return false unless the listener is set as a global listener. + if (!(listener && (listener in global_listeners))) + return FALSE + + // Remove all callbacks if no specific one is given. + if (!proc_call) + global_listeners -= listener + return TRUE + + // See if the listener is registered. + var/list/callbacks = global_listeners[listener] + if (!callbacks) + return FALSE + + // See if the callback exists. + if(!callbacks.Remove(proc_call)) + return FALSE + + if (!callbacks.len) + global_listeners -= listener + return TRUE + +/decl/observ/proc/raise_event() + // Sanity + if (!args.len) + return FALSE + + // Call the global listeners. + for (var/datum/listener in global_listeners) + var/list/callbacks = global_listeners[listener] + for (var/proc_call in callbacks) + + // If the callback crashes, record the error and remove it. + try + call(listener, proc_call)(arglist(args)) + catch (var/exception/e) + error("[e.name] - [e.file] - [e.line]") + error(e.desc) + unregister_global(listener, proc_call) + + // Call the listeners for this specific event source, if they exist. + var/source = args[1] + if (source in event_sources) + var/list/listeners = event_sources[source] + for (var/datum/listener in listeners) + var/list/callbacks = listeners[listener] + for (var/proc_call in callbacks) + + // If the callback crashes, record the error and remove it. + try + call(listener, proc_call)(arglist(args)) + catch (var/exception/e) + error("[e.name] - [e.file] - [e.line]") + error(e.desc) + unregister(source, listener, proc_call) + + return TRUE diff --git a/code/datums/observation/power_change.dm b/code/datums/observation/power_change.dm index 2a5ef3b5791..4581dab84ac 100644 --- a/code/datums/observation/power_change.dm +++ b/code/datums/observation/power_change.dm @@ -5,7 +5,7 @@ // // Arguments that the called proc should expect: // /area: The area experiencing the power change -/* + GLOBAL_DATUM_INIT(apc_event, /decl/observ/area_power_change, new) /decl/observ/area_power_change @@ -15,9 +15,7 @@ GLOBAL_DATUM_INIT(apc_event, /decl/observ/area_power_change, new) /******************** * Movement Handling * ********************/ -*/ -//Deprecated in favor of comsigs /area/power_change() . = ..() - SEND_SIGNAL(src,COMSIG_OBSERVER_APC) + GLOB.apc_event.raise_event(src) diff --git a/code/datums/observation/shuttle_added.dm b/code/datums/observation/shuttle_added.dm index 2dd865a5437..dfd95170a03 100644 --- a/code/datums/observation/shuttle_added.dm +++ b/code/datums/observation/shuttle_added.dm @@ -5,14 +5,12 @@ // // Arguments that the called proc should expect: // /datum/shuttle/shuttle: the new shuttle -/* + GLOBAL_DATUM_INIT(shuttle_added, /decl/observ/shuttle_added, new) /decl/observ/shuttle_added name = "Shuttle Added" expected_type = /datum/shuttle -*/ -//Deprecated in favor of comsigs /***************************** * Shuttle Added Handling * @@ -21,4 +19,4 @@ GLOBAL_DATUM_INIT(shuttle_added, /decl/observ/shuttle_added, new) /datum/controller/subsystem/shuttles/initialize_shuttle() . = ..() if(.) - SEND_SIGNAL(SSshuttles,COMSIG_OBSERVER_SHUTTLE_ADDED,.) + GLOB.shuttle_added.raise_event(.) \ No newline at end of file diff --git a/code/datums/observation/shuttle_moved.dm b/code/datums/observation/shuttle_moved.dm new file mode 100644 index 00000000000..35bff0d6b92 --- /dev/null +++ b/code/datums/observation/shuttle_moved.dm @@ -0,0 +1,38 @@ +// Observer Pattern Implementation: Shuttle Moved +// Registration type: /datum/shuttle/autodock +// +// Raised when: A shuttle has moved to a new landmark. +// +// Arguments that the called proc should expect: +// /datum/shuttle/shuttle: the shuttle moving +// /obj/effect/shuttle_landmark/old_location: the old location's shuttle landmark +// /obj/effect/shuttle_landmark/new_location: the new location's shuttle landmark + +// Observer Pattern Implementation: Shuttle Pre Move +// Registration type: /datum/shuttle/autodock +// +// Raised when: A shuttle is about to move to a new landmark. +// +// Arguments that the called proc should expect: +// /datum/shuttle/shuttle: the shuttle moving +// /obj/effect/shuttle_landmark/old_location: the old location's shuttle landmark +// /obj/effect/shuttle_landmark/new_location: the new location's shuttle landmark + +GLOBAL_DATUM_INIT(shuttle_moved_event, /decl/observ/shuttle_moved, new) + +/decl/observ/shuttle_moved + name = "Shuttle Moved" + expected_type = /datum/shuttle + +GLOBAL_DATUM_INIT(shuttle_pre_move_event, /decl/observ/shuttle_pre_move, new) + +/decl/observ/shuttle_pre_move + name = "Shuttle Pre Move" + expected_type = /datum/shuttle + +/***************** +* Shuttle Moved/Pre Move Handling * +*****************/ + +// Located in modules/shuttle/shuttle.dm +// Proc: /datum/shuttle/proc/attempt_move() \ No newline at end of file diff --git a/code/datums/observation/stat_set.dm b/code/datums/observation/stat_set.dm index c818a505320..6bc6ea45f05 100644 --- a/code/datums/observation/stat_set.dm +++ b/code/datums/observation/stat_set.dm @@ -7,14 +7,12 @@ // /mob/living/stat_mob: The mob whose stat changed // /old_stat: Status before the change. // /new_stat: Status after the change. -/* -stat_set_event, /decl/observ/stat_set, new) + +GLOBAL_DATUM_INIT(stat_set_event, /decl/observ/stat_set, new) /decl/observ/stat_set name = "Stat Set" expected_type = /mob/living -*/ -//Deprecated in favor of Comsigs /**************** * Stat Handling * @@ -23,7 +21,7 @@ stat_set_event, /decl/observ/stat_set, new) var/old_stat = stat . = ..() if(stat != old_stat) - SEND_SIGNAL(src, COMSIG_MOB_STATCHANGE, old_stat, new_stat) + GLOB.stat_set_event.raise_event(src, old_stat, new_stat) if(isbelly(src.loc)) var/obj/belly/ourbelly = src.loc diff --git a/code/datums/observation/turf_changed.dm b/code/datums/observation/turf_changed.dm new file mode 100644 index 00000000000..0bb0ed91158 --- /dev/null +++ b/code/datums/observation/turf_changed.dm @@ -0,0 +1,28 @@ +// Observer Pattern Implementation: Turf Changed +// Registration type: /turf +// +// Raised when: A turf has been changed using the ChangeTurf proc. +// +// Arguments that the called proc should expect: +// /turf/affected: The turf that has changed +// /old_density: Density before the change +// /new_density: Density after the change +// /old_opacity: Opacity before the change +// /new_opacity: Opacity after the change + +var/decl/observ/turf_changed/turf_changed_event = new() + +/decl/observ/turf_changed + name = "Turf Changed" + expected_type = /turf + +/************************ +* Turf Changed Handling * +************************/ + +/turf/ChangeTurf(var/turf/N, var/tell_universe, var/force_lighting_update, var/preserve_outdoors) + var/old_density = density + var/old_opacity = opacity + . = ..(N, tell_universe, force_lighting_update, preserve_outdoors) + if(.) + turf_changed_event.raise_event(src, old_density, density, old_opacity, opacity) \ No newline at end of file diff --git a/code/datums/observation/turf_enterexit.dm b/code/datums/observation/turf_enterexit.dm index 3f591986f07..30cec0c39d2 100644 --- a/code/datums/observation/turf_enterexit.dm +++ b/code/datums/observation/turf_enterexit.dm @@ -8,7 +8,7 @@ // /atom/movable/moving_instance: The instance that entered/exited // /atom/old_loc / /atom/new_loc: The previous/new loc of the mover -/* + GLOBAL_DATUM_INIT(turf_entered_event, /decl/observ/turf_entered, new) GLOBAL_DATUM_INIT(turf_exited_event, /decl/observ/turf_exited, new) @@ -20,18 +20,14 @@ GLOBAL_DATUM_INIT(turf_exited_event, /decl/observ/turf_exited, new) name = "Turf Exited" expected_type = /turf -*/ -//Deprecated in favor of Comsigs - /******************** * Movement Handling * ********************/ - /turf/Entered(var/atom/movable/am, var/atom/old_loc) . = ..() - SEND_SIGNAL(src, COMSIG_OBSERVER_TURF_ENTERED, am, old_loc) + GLOB.turf_entered_event.raise_event(src, am, old_loc) /turf/Exited(var/atom/movable/am, var/atom/new_loc) . = ..() - SEND_SIGNAL(src, COMSIG_OBSERVER_TURF_EXITED, am, new_loc) + GLOB.turf_exited_event.raise_event(src, am, new_loc) \ No newline at end of file diff --git a/code/datums/observation/unequipped.dm b/code/datums/observation/unequipped.dm index 353332de022..6ad8d8eca03 100644 --- a/code/datums/observation/unequipped.dm +++ b/code/datums/observation/unequipped.dm @@ -6,7 +6,7 @@ // Arguments that the called proc should expect: // /mob/equipped: The mob that unequipped/dropped the item. // /obj/item/item: The unequipped item. -/* + GLOBAL_DATUM_INIT(mob_unequipped_event, /decl/observ/mob_unequipped, new) /decl/observ/mob_unequipped @@ -27,8 +27,6 @@ GLOBAL_DATUM_INIT(item_unequipped_event, /decl/observ/item_unequipped, new) /decl/observ/item_unequipped name = "Item Unequipped" expected_type = /obj/item -*/ -//Deprecated in favor of comsigs /********************** * Unequipped Handling * @@ -36,10 +34,5 @@ GLOBAL_DATUM_INIT(item_unequipped_event, /decl/observ/item_unequipped, new) /obj/item/dropped(var/mob/user) ..() - //SEND_SIGNAL(user, COMSIG_OBSERVER_MOB_UNEQUIPPED, src) - //SEND_SIGNAL(src, COMSIG_OBSERVER_ITEM_UNEQUIPPED, user) - if(user) // Cannot always guarantee that user won't be null - SEND_SIGNAL(user, COMSIG_OBSERVER_MOB_UNEQUIPPED, src) - SEND_SIGNAL(src, COMSIG_OBSERVER_ITEM_UNEQUIPPED, user) - else - SEND_SIGNAL(src, COMSIG_OBSERVER_ITEM_UNEQUIPPED) + GLOB.mob_unequipped_event.raise_event(user, src) + GLOB.item_unequipped_event.raise_event(src, user) diff --git a/code/datums/observation/z_moved.dm b/code/datums/observation/z_moved.dm new file mode 100644 index 00000000000..ba30df374c6 --- /dev/null +++ b/code/datums/observation/z_moved.dm @@ -0,0 +1,16 @@ +// Observer Pattern Implementation: Z_Moved +// Registration type: /atom/movable +// +// Raised when: An /atom/movable instance has changed z-levels by any means. +// +// Arguments that the called proc should expect: +// /atom/movable/moving_instance: The instance that moved +// old_z: The z number before the move. +// new_z: The z number after the move. + + +GLOBAL_DATUM_INIT(z_moved_event, /decl/observ/z_moved, new) + +/decl/observ/z_moved + name = "Z_Moved" + expected_type = /atom/movable diff --git a/code/datums/observation/~cleanup.dm b/code/datums/observation/~cleanup.dm new file mode 100644 index 00000000000..da902052bdd --- /dev/null +++ b/code/datums/observation/~cleanup.dm @@ -0,0 +1,67 @@ +GLOBAL_LIST_EMPTY(global_listen_count) +GLOBAL_LIST_EMPTY(event_sources_count) +GLOBAL_LIST_EMPTY(event_listen_count) + +/decl/observ/destroyed/raise_event() + . = ..() + if(!.) + return + var/source = args[1] + + if(GLOB.global_listen_count[source]) + cleanup_global_listener(source, GLOB.global_listen_count[source]) + if(GLOB.event_sources_count[source]) + cleanup_source_listeners(source, GLOB.event_sources_count[source]) + if(GLOB.event_listen_count[source]) + cleanup_event_listener(source, GLOB.event_listen_count[source]) + + +/decl/observ/register(var/datum/event_source, var/datum/listener, var/proc_call) + . = ..() + if(.) + GLOB.event_sources_count[event_source] += 1 + GLOB.event_listen_count[listener] += 1 + +/decl/observ/unregister(var/datum/event_source, var/datum/listener, var/proc_call) + . = ..() + if(.) + GLOB.event_sources_count[event_source] -= 1 + GLOB.event_listen_count[listener] -= 1 + +/decl/observ/register_global(var/datum/listener, var/proc_call) + . = ..() + if(.) + GLOB.global_listen_count[listener] += 1 + +/decl/observ/unregister_global(var/datum/listener, var/proc_call) + . = ..() + if(.) + GLOB.global_listen_count[listener] -= 1 + +/decl/observ/destroyed/proc/cleanup_global_listener(listener, listen_count) + GLOB.global_listen_count -= listener + for(var/decl/observ/event as anything in GLOB.all_observable_events.events) + if(event.unregister_global(listener)) + // log_debug("[event] - [listener] was deleted while still registered to global events.") // TODO: Apply axe, reimplement with datum component listeners + if(!(--listen_count)) + return + +/decl/observ/destroyed/proc/cleanup_source_listeners(event_source, source_listener_count) + GLOB.event_sources_count -= event_source + for(var/decl/observ/event as anything in GLOB.all_observable_events.events) + var/proc_owners = event.event_sources[event_source] + if(proc_owners) + for(var/proc_owner in proc_owners) + if(event.unregister(event_source, proc_owner)) + // log_debug("[event] - [event_source] was deleted while still being listened to by [proc_owner].") // TODO: Apply axe, reimplement with datum component listeners + if(!(--source_listener_count)) + return + +/decl/observ/destroyed/proc/cleanup_event_listener(listener, listener_count) + GLOB.event_listen_count -= listener + for(var/decl/observ/event as anything in GLOB.all_observable_events.events) + for(var/event_source in event.event_sources) + if(event.unregister(event_source, listener)) + // log_debug("[event] - [listener] was deleted while still listening to [event_source].") // TODO: Apply axe, reimplement with datum component listeners + if(!(--listener_count)) + return \ No newline at end of file diff --git a/code/datums/orbit.dm b/code/datums/orbit.dm index 745d16053e1..adbd166d25a 100644 --- a/code/datums/orbit.dm +++ b/code/datums/orbit.dm @@ -105,7 +105,7 @@ /atom/movable/proc/stop_orbit() SpinAnimation(0,0) - QDEL_NULL(orbiting) + qdel(orbiting) /atom/Destroy(force = FALSE) . = ..() diff --git a/code/datums/uplink/badassery.dm b/code/datums/uplink/badassery.dm index 2541bac5045..8208894af4f 100644 --- a/code/datums/uplink/badassery.dm +++ b/code/datums/uplink/badassery.dm @@ -91,4 +91,4 @@ var/obj/structure/largecrate/C = /obj/structure/largecrate icon = image(initial(C.icon), initial(C.icon_state)) - return "[bicon(icon)]" + return "\icon[icon][bicon(icon)]" \ No newline at end of file diff --git a/code/datums/uplink/uplink_items.dm b/code/datums/uplink/uplink_items.dm index 7b4fbded2b5..7fcdbd8dc2a 100644 --- a/code/datums/uplink/uplink_items.dm +++ b/code/datums/uplink/uplink_items.dm @@ -130,7 +130,7 @@ var/datum/uplink/uplink = new() /datum/uplink_item/item/log_icon() var/obj/I = path - return "[bicon(I)]" + return "\icon[I][bicon(I)]" /******************************** * * @@ -144,7 +144,7 @@ var/datum/uplink/uplink = new() if(!default_abstract_uplink_icon) default_abstract_uplink_icon = image('icons/obj/pda.dmi', "pda-syn") - return "[bicon(default_abstract_uplink_icon)]" + return "\icon[default_abstract_uplink_icon][bicon(default_abstract_uplink_icon)]" /* * Crated goods. @@ -174,7 +174,7 @@ var/datum/uplink/uplink = new() /datum/uplink_item/crated/log_icon() var/obj/I = crate_path - return "[bicon(I)]" + return "\icon[I]" /**************** * Support procs * diff --git a/code/datums/wires/camera.dm b/code/datums/wires/camera.dm index 322478688c3..c572ad8d27c 100644 --- a/code/datums/wires/camera.dm +++ b/code/datums/wires/camera.dm @@ -57,7 +57,7 @@ C.light_disabled = !C.light_disabled if(WIRE_CAM_ALARM) - C.visible_message("[icon2html(C,viewers(holder))] *beep*", "[icon2html(C,viewers(holder))] *beep*") + C.visible_message("\icon[C][bicon(C)] *beep*", "\icon[C][bicon(C)] *beep*") ..() /datum/wires/camera/proc/CanDeconstruct() diff --git a/code/datums/wires/jukebox.dm b/code/datums/wires/jukebox.dm index 5f46a3deb96..cec0f4d370b 100644 --- a/code/datums/wires/jukebox.dm +++ b/code/datums/wires/jukebox.dm @@ -31,16 +31,16 @@ var/obj/machinery/media/jukebox/A = holder switch(wire) if(WIRE_MAIN_POWER1) - holder.visible_message("[icon2html(A,viewers(holder))] The power light flickers.") + holder.visible_message("\icon[holder][bicon(holder)] The power light flickers.") A.shock(usr, 90) if(WIRE_JUKEBOX_HACK) - holder.visible_message("[icon2html(A,viewers(holder))] The parental guidance light flickers.") + holder.visible_message("\icon[holder][bicon(holder)] The parental guidance light flickers.") if(WIRE_REVERSE) - holder.visible_message("[icon2html(A,viewers(holder))] The data light blinks ominously.") + holder.visible_message("\icon[holder][bicon(holder)] The data light blinks ominously.") if(WIRE_SPEEDUP) - holder.visible_message("[icon2html(A,viewers(holder))] The speakers squeaks.") + holder.visible_message("\icon[holder][bicon(holder)] The speakers squeaks.") if(WIRE_SPEEDDOWN) - holder.visible_message("[icon2html(A,viewers(holder))] The speakers rumble.") + holder.visible_message("\icon[holder][bicon(holder)] The speakers rumble.") if(WIRE_START) A.StartPlaying() if(WIRE_STOP) diff --git a/code/datums/wires/mines.dm b/code/datums/wires/mines.dm index 229ce682be8..55ea718c3f4 100644 --- a/code/datums/wires/mines.dm +++ b/code/datums/wires/mines.dm @@ -21,15 +21,15 @@ switch(wire) if(WIRE_EXPLODE) - C.visible_message("[icon2html(C,viewers(holder))] *BEEE-*", "[icon2html(C,viewers(holder))] *BEEE-*") + C.visible_message("\icon[C][bicon(C)] *BEEE-*", "\icon[C][bicon(C)] *BEEE-*") C.explode() if(WIRE_EXPLODE_DELAY) - C.visible_message("[icon2html(C,viewers(holder))] *BEEE-*", "[icon2html(C,viewers(holder))] *BEEE-*") + C.visible_message("\icon[C][bicon(C)] *BEEE-*", "\icon[C][bicon(C)] *BEEE-*") C.explode() if(WIRE_DISARM) - C.visible_message("[icon2html(C,viewers(holder))] *click!*", "[icon2html(C,viewers(holder))] *click!*") + C.visible_message("\icon[C][bicon(C)] *click!*", "\icon[C][bicon(C)] *click!*") var/obj/effect/mine/MI = new C.mineitemtype(get_turf(C)) if(C.trap) @@ -41,15 +41,15 @@ qdel(C) if(WIRE_BADDISARM) - C.visible_message("[icon2html(C,viewers(holder))] *BEEPBEEPBEEP*", "[icon2html(C,viewers(holder))] *BEEPBEEPBEEP*") + C.visible_message("\icon[C][bicon(C)] *BEEPBEEPBEEP*", "\icon[C][bicon(C)] *BEEPBEEPBEEP*") spawn(20) C.explode() if(WIRE_TRAP) - C.visible_message("[icon2html(C,viewers(holder))] *click!*", "[icon2html(C,viewers(holder))] *click!*") + C.visible_message("\icon[C][bicon(C)] *click!*", "\icon[C][bicon(C)] *click!*") if(mend) - C.visible_message("[icon2html(C,viewers(holder))] - The mine recalibrates[C.camo_net ? ", revealing \the [C.trap] inside." : "."]") + C.visible_message("\icon[C][bicon(C)] - The mine recalibrates[C.camo_net ? ", revealing \the [C.trap] inside." : "."]") C.alpha = 255 @@ -61,21 +61,21 @@ return switch(wire) if(WIRE_EXPLODE) - C.visible_message("[icon2html(C,viewers(holder))] *beep*", "[icon2html(C,viewers(holder))] *beep*") + C.visible_message("\icon[C][bicon(C)] *beep*", "\icon[C][bicon(C)] *beep*") if(WIRE_EXPLODE_DELAY) - C.visible_message("[icon2html(C,viewers(holder))] *BEEPBEEPBEEP*", "[icon2html(C,viewers(holder))] *BEEPBEEPBEEP*") + C.visible_message("\icon[C][bicon(C)] *BEEPBEEPBEEP*", "\icon[C][bicon(C)] *BEEPBEEPBEEP*") spawn(20) C.explode() if(WIRE_DISARM) - C.visible_message("[icon2html(C,viewers(holder))] *ping*", "[icon2html(C,viewers(holder))] *ping*") + C.visible_message("\icon[C][bicon(C)] *ping*", "\icon[C][bicon(C)] *ping*") if(WIRE_BADDISARM) - C.visible_message("[icon2html(C,viewers(holder))] *ping*", "[icon2html(C,viewers(holder))] *ping*") + C.visible_message("\icon[C][bicon(C)] *ping*", "\icon[C][bicon(C)] *ping*") if(WIRE_TRAP) - C.visible_message("[icon2html(C,viewers(holder))] *ping*", "[icon2html(C,viewers(holder))] *ping*") + C.visible_message("\icon[C][bicon(C)] *ping*", "\icon[C][bicon(C)] *ping*") ..() diff --git a/code/datums/wires/particle_accelerator.dm b/code/datums/wires/particle_accelerator.dm index 1b1f03bd193..1787039622b 100644 --- a/code/datums/wires/particle_accelerator.dm +++ b/code/datums/wires/particle_accelerator.dm @@ -26,7 +26,7 @@ C.interface_control = !C.interface_control if(WIRE_PARTICLE_POWER_LIMIT) - C.visible_message("[icon2html(C,viewers(holder))][C] makes a large whirring noise.") + C.visible_message("\icon[C][bicon(C)][C] makes a large whirring noise.") /datum/wires/particle_acc/control_box/on_cut(wire, mend) var/obj/machinery/particle_accelerator/control_box/C = holder diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 5cbbe16b9c3..9490a0af464 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -153,7 +153,7 @@ ASSERT(isturf(loc)) var/list/turfs = trange(range, src) for(var/turf/T as anything in turfs) - RegisterSignal(T, COMSIG_OBSERVER_TURF_ENTERED, callback) + GLOB.turf_entered_event.register(T, src, callback) //Unregister from prox listening in a certain range. You should do this BEFORE you move, but if you // really can't, then you can set the center where you moved from. @@ -161,7 +161,7 @@ ASSERT(isturf(center) || isturf(loc)) var/list/turfs = trange(range, center ? center : src) for(var/turf/T as anything in turfs) - UnregisterSignal(T, COMSIG_OBSERVER_TURF_ENTERED) + GLOB.turf_entered_event.unregister(T, src, callback) /atom/proc/emp_act(var/severity) @@ -228,7 +228,7 @@ else f_name += "oil-stained [name][infix]." - var/list/output = list("[icon2html(src,user.client)] That's [f_name] [suffix]", get_examine_desc()) + var/list/output = list("\icon[src.examine_icon()][bicon(src)] That's [f_name] [suffix]", get_examine_desc()) if(user.client?.prefs.examine_text_mode == EXAMINE_MODE_INCLUDE_USAGE) output += description_info @@ -705,7 +705,7 @@ /atom/Entered(atom/movable/AM, atom/old_loc) . = ..() - SEND_SIGNAL(AM, COMSIG_OBSERVER_MOVED, old_loc, AM.loc) + GLOB.moved_event.raise_event(AM, old_loc, AM.loc) SEND_SIGNAL(src, COMSIG_ATOM_ENTERED, AM, old_loc) SEND_SIGNAL(AM, COMSIG_ATOM_ENTERING, src, old_loc) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index af31b4f6983..757283f00fa 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -372,7 +372,7 @@ return TRUE /atom/movable/proc/onTransitZ(old_z,new_z) - SEND_SIGNAL(src, COMSIG_OBSERVER_Z_MOVED, old_z, new_z) + GLOB.z_moved_event.raise_event(src, old_z, new_z) SEND_SIGNAL(src, COMSIG_MOVABLE_Z_CHANGED, old_z, new_z) for(var/atom/movable/AM as anything in src) // Notify contents of Z-transition. This can be overridden IF we know the items contents do not care. AM.onTransitZ(old_z,new_z) @@ -637,4 +637,4 @@ return selfimage /atom/movable/proc/get_cell() - return + return \ No newline at end of file diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm index d6dd254de14..1834971be2d 100644 --- a/code/game/machinery/computer/arcade.dm +++ b/code/game/machinery/computer/arcade.dm @@ -1125,7 +1125,7 @@ // This is not a status display message, since it's something the character // themselves is meant to see BEFORE putting the money in - to_chat(usr, "[icon2html(cashmoney,user.client)] That is not enough money.") + to_chat(usr, "\icon[cashmoney][bicon(cashmoney)] That is not enough money.") return 0 if(istype(cashmoney, /obj/item/weapon/spacecash)) @@ -1338,4 +1338,4 @@ to_chat(user, "You turn in 2 tickets to the [src] and claim a prize!") return else - ..() //You can now actually deconstruct these. + ..() //You can now actually deconstruct these. \ No newline at end of file diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index 174fdf630d6..b275821a593 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -284,7 +284,7 @@ Class Procs: /obj/machinery/proc/state(var/msg) for(var/mob/O in hearers(src, null)) - O.show_message("[icon2html(src,O.client)] [msg]", 2) + O.show_message("\icon[src][bicon(src)] [msg]", 2) /obj/machinery/proc/ping(text=null) if(!text) diff --git a/code/game/machinery/machinery_power.dm b/code/game/machinery/machinery_power.dm index c5c6c6c03c7..0f4c2ef01b1 100644 --- a/code/game/machinery/machinery_power.dm +++ b/code/game/machinery/machinery_power.dm @@ -73,18 +73,14 @@ // Do not do power stuff in New/Initialize until after ..() /obj/machinery/Initialize() . = ..() - RegisterSignal(src, COMSIG_OBSERVER_MOVED, PROC_REF(update_power_on_move)) - AddComponent(/datum/component/recursive_move) var/power = POWER_CONSUMPTION REPORT_POWER_CONSUMPTION_CHANGE(0, power) power_init_complete = TRUE // Or in Destroy at all, but especially after the ..(). /obj/machinery/Destroy() - /* if(ismovable(loc)) - UnregisterSignal(loc, COMSIG_OBSERVER_MOVED) // Unregister just in case - */ + GLOB.moved_event.unregister(loc, src, PROC_REF(update_power_on_move)) // Unregister just in case var/power = POWER_CONSUMPTION REPORT_POWER_CONSUMPTION_CHANGE(power, 0) . = ..() @@ -94,12 +90,10 @@ /obj/machinery/Moved(atom/old_loc, direction, forced = FALSE) . = ..() update_power_on_move(src, old_loc, loc) - /* No - if(ismovable(old_loc)) // Unregister recursive movement. - UnregisterSignal(old_loc, COMSIG_OBSERVER_MOVED) if(ismovable(loc)) // Register for recursive movement (if the thing we're inside moves) - RegisterSignal(loc, COMSIG_OBSERVER_MOVED, PROC_REF(update_power_on_move), override = TRUE) - */ + GLOB.moved_event.register(loc, src, PROC_REF(update_power_on_move)) + if(ismovable(old_loc)) // Unregister recursive movement. + GLOB.moved_event.unregister(old_loc, src, PROC_REF(update_power_on_move)) /obj/machinery/proc/update_power_on_move(atom/movable/mover, atom/old_loc, atom/new_loc) var/area/old_area = get_area(old_loc) diff --git a/code/game/machinery/overview.dm b/code/game/machinery/overview.dm index 027de127b26..058abb899d7 100644 --- a/code/game/machinery/overview.dm +++ b/code/game/machinery/overview.dm @@ -138,7 +138,7 @@ var/icon/I = imap[1+(ix + icx*iy)*2] var/icon/I2 = imap[2+(ix + icx*iy)*2] - //to_world("icon: [icon2html(I)]") + //to_world("icon: \icon[I][bicon(I)]") I.DrawBox(colour, rx, ry, rx+1, ry+1) @@ -153,7 +153,7 @@ H.screen_loc = "[5 + i%icx],[6+ round(i/icx)]" - //to_world("[icon2html(I)] at [H.screen_loc]") + //to_world("\icon[I][bicon(I)] at [H.screen_loc]") H.name = (i==0)?"maprefresh":"map" @@ -266,7 +266,7 @@ //to_world("trying [ix],[iy] : [ix+icx*iy]") var/icon/I = imap[1+(ix + icx*iy)] - //to_world("icon: [icon2html(I)]") + //to_world("icon: \icon[I][bicon(I)]") I.DrawBox(colour, rx, ry, rx, ry) @@ -279,7 +279,7 @@ H.screen_loc = "[5 + i%icx],[6+ round(i/icx)]" - //to_world("[icon2html(I)] at [H.screen_loc]") + //to_world("\icon[I][bicon(I)] at [H.screen_loc]") H.name = (i==0)?"maprefresh":"map" @@ -332,4 +332,4 @@ qdel(O) mapobjs = null - src.unset_machine() + src.unset_machine() \ No newline at end of file diff --git a/code/game/machinery/partslathe_vr.dm b/code/game/machinery/partslathe_vr.dm index aef7fc1ee34..3fe7074b419 100644 --- a/code/game/machinery/partslathe_vr.dm +++ b/code/game/machinery/partslathe_vr.dm @@ -163,7 +163,7 @@ removeFromQueue(1) update_icon() else if(busy) - visible_message("[icon2html(src,viewers(src))] flashes: insufficient materials: [getLackingMaterials(D)].") + visible_message("\icon [src] flashes: insufficient materials: [getLackingMaterials(D)].") busy = 0 update_use_power(USE_POWER_IDLE) update_icon() @@ -279,7 +279,7 @@ var/datum/category_item/partslathe/current = queue[1] data["building"] = current.name data["buildPercent"] = (progress / current.time * 100) - + data["error"] = null if(queue.len > 0 && !canBuild(queue[1])) data["error"] = getLackingMaterials(queue[1]) diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm index 451472c7bf6..0a9def34461 100644 --- a/code/game/machinery/portable_turret.dm +++ b/code/game/machinery/portable_turret.dm @@ -254,6 +254,9 @@ if(get_dist(src, L) > 7) //if it's too far away, why bother? return TURRET_NOT_TARGET + if(!(L in check_trajectory(L, src))) //check if we have true line of sight + return TURRET_NOT_TARGET + if(L.lying) //Don't need to stun-lock the players return TURRET_NOT_TARGET @@ -723,6 +726,9 @@ if(get_dist(src, L) > 7) //if it's too far away, why bother? return TURRET_NOT_TARGET + if(!(L in check_trajectory(L, src))) //check if we have true line of sight + return TURRET_NOT_TARGET + if(emagged) // If emagged not even the dead get a rest return L.stat ? TURRET_SECONDARY_TARGET : TURRET_PRIORITY_TARGET @@ -835,14 +841,13 @@ if(disabled) return FALSE if(target) - if(target in check_trajectory(target, src)) //Finally, check if we can actually hit the target - last_target = target - popUp() //pop the turret up if it's not already up. - set_dir(get_dir(src, target)) //even if you can't shoot, follow the target - playsound(src, 'sound/machines/turrets/turret_rotate.ogg', 100, 1) // Play rotating sound - spawn() - shootAt(target) - return TRUE + last_target = target + popUp() //pop the turret up if it's not already up. + set_dir(get_dir(src, target)) //even if you can't shoot, follow the target + playsound(src, 'sound/machines/turrets/turret_rotate.ogg', 100, 1) // Play rotating sound + spawn() + shootAt(target) + return TRUE return FALSE /obj/machinery/porta_turret/proc/shootAt(var/mob/living/target) diff --git a/code/game/machinery/requests_console.dm b/code/game/machinery/requests_console.dm index 11eb234e26d..9e9e8786468 100644 --- a/code/game/machinery/requests_console.dm +++ b/code/game/machinery/requests_console.dm @@ -198,7 +198,7 @@ var/list/obj/machinery/requests_console/allConsoles = list() screen = RCS_SENTPASS message_log += list(list("Message sent to [recipient]", "[message]")) else - audible_message(text("[icon2html(src,viewers(src))] *The Requests Console beeps: 'NOTICE: No server detected!'"),,4) + audible_message(text("\icon[src][bicon(src)] *The Requests Console beeps: 'NOTICE: No server detected!'"),,4) . = TRUE //Handle printing diff --git a/code/game/machinery/suit_storage/suit_cycler.dm b/code/game/machinery/suit_storage/suit_cycler.dm index 6803194eef7..cdd6b45dc29 100644 --- a/code/game/machinery/suit_storage/suit_cycler.dm +++ b/code/game/machinery/suit_storage/suit_cycler.dm @@ -477,7 +477,7 @@ GLOBAL_LIST_EMPTY(suit_cycler_typecache) /obj/machinery/suit_cycler/proc/finished_job() var/turf/T = get_turf(src) - T.visible_message("[icon2html(src,viewers(src))]The [src] beeps several times.") + T.visible_message("\icon[src][bicon(src)]The [src] beeps several times.") icon_state = initial(icon_state) active = 0 playsound(src, 'sound/machines/boobeebeep.ogg', 50) @@ -543,5 +543,5 @@ GLOBAL_LIST_EMPTY(suit_cycler_typecache) if(target_species.can_refit_to(helmet, suit, suit?.helmet)) target_species.do_refit_to(helmet, suit, suit?.helmet) else - visible_message("[icon2html(src,viewers(src))]Unable to apply specified cosmetics with specified species. Please try again with a different species or cosmetic option selected.") + visible_message("\icon[src][bicon(src)]Unable to apply specified cosmetics with specified species. Please try again with a different species or cosmetic option selected.") return diff --git a/code/game/machinery/telecomms/broadcaster.dm b/code/game/machinery/telecomms/broadcaster.dm index 5fee77b9e3d..36ffd8f8bc4 100644 --- a/code/game/machinery/telecomms/broadcaster.dm +++ b/code/game/machinery/telecomms/broadcaster.dm @@ -455,7 +455,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept if(data == DATA_ANTAG) // intercepted radio message part_b_extra = " (Intercepted)" var/part_a = "" - var/part_b = "[icon2html(radio, heard_masked + heard_normal + heard_voice + heard_garbled + heard_gibberish)]\[[freq_text]\][part_b_extra] " // goes in the actual output + var/part_b = "\icon[radio][bicon(radio)]\[[freq_text]\][part_b_extra] " // goes in the actual output // --- Some more pre-message formatting --- var/part_c = " " // Tweaked for security headsets -- TLE @@ -658,7 +658,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept // Create a radio headset for the sole purpose of using its icon var/obj/item/device/radio/headset/radio = new - var/part_b = "[icon2html(radio, heard_normal + heard_garbled + heard_gibberish)]\[[freq_text]\][part_b_extra] " // Tweaked for security headsets -- TLE + var/part_b = "\icon[radio][bicon(radio)]\[[freq_text]\][part_b_extra] " // Tweaked for security headsets -- TLE var/part_blackbox_b = " \[[freq_text]\] " // Tweaked for security headsets -- TLE var/part_c = "" diff --git a/code/game/mecha/equipment/mecha_equipment.dm b/code/game/mecha/equipment/mecha_equipment.dm index 80c16c4a654..e4a178034ea 100644 --- a/code/game/mecha/equipment/mecha_equipment.dm +++ b/code/game/mecha/equipment/mecha_equipment.dm @@ -272,7 +272,7 @@ /obj/item/mecha_parts/mecha_equipment/proc/occupant_message(message) if(chassis) - chassis.occupant_message("[icon2html(src, chassis.occupant.client)] [message]") + chassis.occupant_message("\icon[src][bicon(src)] [message]") return /obj/item/mecha_parts/mecha_equipment/proc/log_message(message) diff --git a/code/game/mecha/equipment/tools/shield_omni.dm b/code/game/mecha/equipment/tools/shield_omni.dm index 3d41a1cf2e3..8ee24a77556 100644 --- a/code/game/mecha/equipment/tools/shield_omni.dm +++ b/code/game/mecha/equipment/tools/shield_omni.dm @@ -77,8 +77,7 @@ /obj/item/shield_projector/rectangle/mecha/Initialize() . = ..() my_mech = loc - RegisterSignal(my_mech, COMSIG_OBSERVER_MOVED, /obj/item/shield_projector/proc/update_shield_positions) - my_mech.AddComponent(/datum/component/recursive_move) + GLOB.moved_event.register(my_mech, src, /obj/item/shield_projector/proc/update_shield_positions) update_shift(my_mech) /obj/item/shield_projector/rectangle/mecha/proc/update_shift(atom/movable/mech) @@ -89,7 +88,7 @@ shift_y = round(y_dif, 1) /obj/item/shield_projector/rectangle/mecha/Destroy() - UnregisterSignal(my_mech, COMSIG_OBSERVER_MOVED) + GLOB.moved_event.unregister(my_mech, src, /obj/item/shield_projector/proc/update_shield_positions) my_mech = null ..() diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm index 34395e0dcf7..ebc1e22aa14 100644 --- a/code/game/mecha/mech_fabricator.dm +++ b/code/game/mecha/mech_fabricator.dm @@ -664,20 +664,20 @@ switch(emagged) if(0) emagged = 0.5 - visible_message("[icon2html(src,viewers(src))] [src] beeps: \"DB error \[Code 0x00F1\]\"") + visible_message("\icon[src][bicon(src)] [src] beeps: \"DB error \[Code 0x00F1\]\"") sleep(10) - visible_message("[icon2html(src,viewers(src))] [src] beeps: \"Attempting auto-repair\"") + visible_message("\icon[src][bicon(src)] [src] beeps: \"Attempting auto-repair\"") sleep(15) - visible_message("[icon2html(src,viewers(src))] [src] beeps: \"User DB corrupted \[Code 0x00FA\]. Truncating data structure...\"") + visible_message("\icon[src][bicon(src)] [src] beeps: \"User DB corrupted \[Code 0x00FA\]. Truncating data structure...\"") sleep(30) - visible_message("[icon2html(src,viewers(src))] [src] beeps: \"User DB truncated. Please contact your [using_map.company_name] system operator for future assistance.\"") + visible_message("\icon[src][bicon(src)] [src] beeps: \"User DB truncated. Please contact your [using_map.company_name] system operator for future assistance.\"") req_access = null emagged = 1 return 1 if(0.5) - visible_message("[icon2html(src,viewers(src))] [src] beeps: \"DB not responding \[Code 0x0003\]...\"") + visible_message("\icon[src][bicon(src)] [src] beeps: \"DB not responding \[Code 0x0003\]...\"") if(1) - visible_message("[icon2html(src,viewers(src))] [src] beeps: \"No records in User DB\"") + visible_message("\icon[src][bicon(src)] [src] beeps: \"No records in User DB\"") /obj/machinery/mecha_part_fabricator/proc/eject_materials(var/material, var/amount) // 0 amount = 0 means ejecting a full stack; -1 means eject everything var/recursive = amount == -1 ? TRUE : FALSE diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 1e054279cab..07bba04dc1d 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -538,7 +538,7 @@ if(equipment?.len) . += "It's equipped with:" for(var/obj/item/mecha_parts/mecha_equipment/ME in equipment) - . += "[icon2html(ME,user.client)] [ME]" + . += "\icon[ME][bicon(ME)] [ME]" /obj/mecha/proc/drop_item()//Derpfix, but may be useful in future for engineering exosuits. return @@ -2439,7 +2439,7 @@ /obj/mecha/proc/occupant_message(message as text) if(message) if(src.occupant && src.occupant.client) - to_chat(src.occupant, "[icon2html(src, src.occupant.client)] [message]") + to_chat(src.occupant, "\icon[src][bicon(src)] [message]") return /obj/mecha/proc/log_message(message as text,red=null) diff --git a/code/game/objects/effects/temporary_visuals/temporary_visual.dm b/code/game/objects/effects/temporary_visuals/temporary_visual.dm index 5bbb7a19f1d..84e8e1c031c 100644 --- a/code/game/objects/effects/temporary_visuals/temporary_visual.dm +++ b/code/game/objects/effects/temporary_visuals/temporary_visual.dm @@ -13,7 +13,7 @@ . = ..() if(randomdir) dir = pick(list(NORTH, SOUTH, EAST, WEST)) - timerid = QDEL_IN_STOPPABLE(src, duration) + timerid = QDEL_IN(src, duration) /obj/effect/temp_visual/Destroy() . = ..() @@ -35,3 +35,4 @@ if(set_dir) dir = set_dir . = ..() + diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 83844f79958..609822a7562 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -703,14 +703,7 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. //Looking through a scope or binoculars should /not/ improve your periphereal vision. Still, increase viewsize a tiny bit so that sniping isn't as restricted to NSEW /obj/item/var/ignore_visor_zoom_restriction = FALSE -/obj/item/proc/zoom(var/mob/living/M, var/tileoffset = 14,var/viewsize = 9) //tileoffset is client view offset in the direction the user is facing. viewsize is how far out this thing zooms. 7 is normal view - - if(isliving(usr)) //Always prefer usr if set - M = usr - - if(!isliving(M)) - return 0 - +/obj/item/proc/zoom(var/tileoffset = 14,var/viewsize = 9) //tileoffset is client view offset in the direction the user is facing. viewsize is how far out this thing zooms. 7 is normal view var/devicename @@ -721,26 +714,25 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. var/cannotzoom - if((M.stat && !zoom) || !(istype(M,/mob/living/carbon/human))) - to_chat(M, "You are unable to focus through the [devicename].") + if((usr.stat && !zoom) || !(istype(usr,/mob/living/carbon/human))) + to_chat(usr, "You are unable to focus through the [devicename].") cannotzoom = 1 - else if(!zoom && (global_hud.darkMask[1] in M.client.screen)) - to_chat(M, "Your visor gets in the way of looking through the [devicename].") + else if(!zoom && (global_hud.darkMask[1] in usr.client.screen)) + to_chat(usr, "Your visor gets in the way of looking through the [devicename].") cannotzoom = 1 - else if(!zoom && M.get_active_hand() != src) - to_chat(M, "You are too distracted to look through the [devicename], perhaps if it was in your active hand this might work better.") + else if(!zoom && usr.get_active_hand() != src) + to_chat(usr, "You are too distracted to look through the [devicename], perhaps if it was in your active hand this might work better.") cannotzoom = 1 //We checked above if they are a human and returned already if they weren't. - var/mob/living/carbon/human/H = M + var/mob/living/carbon/human/H = usr if(!zoom && !cannotzoom) if(H.hud_used.hud_shown) H.toggle_zoom_hud() // If the user has already limited their HUD this avoids them having a HUD when they zoom in H.set_viewsize(viewsize) zoom = 1 - H.AddComponent(/datum/component/recursive_move) - RegisterSignal(H, COMSIG_OBSERVER_MOVED, PROC_REF(zoom), override = TRUE) + GLOB.moved_event.register(H, src, PROC_REF(zoom)) var/tilesize = 32 var/viewoffset = tilesize * tileoffset @@ -759,7 +751,7 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. H.client.pixel_x = -viewoffset H.client.pixel_y = 0 - H.visible_message("[M] peers through the [zoomdevicename ? "[zoomdevicename] of the [src.name]" : "[src.name]"].") + H.visible_message("[usr] peers through the [zoomdevicename ? "[zoomdevicename] of the [src.name]" : "[src.name]"].") if(!ignore_visor_zoom_restriction) H.looking_elsewhere = TRUE H.handle_vision() @@ -769,7 +761,7 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. if(!H.hud_used.hud_shown) H.toggle_zoom_hud() zoom = 0 - UnregisterSignal(H, COMSIG_OBSERVER_MOVED) + GLOB.moved_event.unregister(H, src, PROC_REF(zoom)) H.client.pixel_x = 0 H.client.pixel_y = 0 @@ -777,7 +769,7 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. H.handle_vision() if(!cannotzoom) - M.visible_message("[zoomdevicename ? "[M] looks up from the [src.name]" : "[M] lowers the [src.name]"].") + usr.visible_message("[zoomdevicename ? "[usr] looks up from the [src.name]" : "[usr] lowers the [src.name]"].") return diff --git a/code/game/objects/items/devices/ai_detector.dm b/code/game/objects/items/devices/ai_detector.dm index d5ca5aaa521..7bb92bf2168 100644 --- a/code/game/objects/items/devices/ai_detector.dm +++ b/code/game/objects/items/devices/ai_detector.dm @@ -94,22 +94,22 @@ if(new_state != old_state) switch(new_state) if(PROXIMITY_OFF_CAMERANET) - to_chat(carrier, "[icon2html(src, carrier.client)] Now outside of camera network.") + to_chat(carrier, "\icon[src][bicon(src)] Now outside of camera network.") carrier << 'sound/machines/defib_failed.ogg' if(PROXIMITY_NONE) - to_chat(carrier, "[icon2html(src, carrier.client)] Now within camera network, AI and cameras unfocused.") + to_chat(carrier, "\icon[src][bicon(src)] Now within camera network, AI and cameras unfocused.") carrier << 'sound/machines/defib_safetyOff.ogg' if(PROXIMITY_NEAR) - to_chat(carrier, "[icon2html(src, carrier.client)] Warning: AI focus at nearby location.") + to_chat(carrier, "\icon[src][bicon(src)] Warning: AI focus at nearby location.") carrier << 'sound/machines/defib_SafetyOn.ogg' if(PROXIMITY_ON_SCREEN) - to_chat(carrier, "[icon2html(src, carrier.client)] Alert: AI or camera focused at current location!") + to_chat(carrier, "\icon[src][bicon(src)] Alert: AI or camera focused at current location!") carrier <<'sound/machines/defib_ready.ogg' if(PROXIMITY_TRACKING) - to_chat(carrier, "[icon2html(src, carrier.client)] Danger: AI is actively tracking you!") + to_chat(carrier, "\icon[src][bicon(src)] Danger: AI is actively tracking you!") carrier << 'sound/machines/defib_success.ogg' if(PROXIMITY_TRACKING_FAIL) - to_chat(carrier, "[icon2html(src, carrier.client)] Danger: AI is attempting to actively track you, but you are outside of the camera network!") + to_chat(carrier, "\icon[src][bicon(src)] Danger: AI is attempting to actively track you, but you are outside of the camera network!") carrier <<'sound/machines/defib_ready.ogg' @@ -118,4 +118,4 @@ #undef PROXIMITY_NEAR #undef PROXIMITY_ON_SCREEN #undef PROXIMITY_TRACKING -#undef PROXIMITY_TRACKING_FAIL +#undef PROXIMITY_TRACKING_FAIL \ No newline at end of file diff --git a/code/game/objects/items/devices/communicator/UI_tgui.dm b/code/game/objects/items/devices/communicator/UI_tgui.dm index fb59fd2a323..2f4e73c5eb5 100644 --- a/code/game/objects/items/devices/communicator/UI_tgui.dm +++ b/code/game/objects/items/devices/communicator/UI_tgui.dm @@ -382,7 +382,7 @@ im_list += list(list("address" = exonet.address, "to_address" = their_address, "im" = text)) log_pda("(COMM: [src]) sent \"[text]\" to [exonet.get_atom_from_address(their_address)]", usr) var/obj/item/device/communicator/comm = exonet.get_atom_from_address(their_address) - to_chat(usr, "[icon2html(src, usr.client)] Sent message to [istype(comm, /obj/item/device/communicator) ? comm.owner : comm.name], \"[text]\" (Reply)") + to_chat(usr, "\icon[src][bicon(src)] Sent message to [istype(comm, /obj/item/device/communicator) ? comm.owner : comm.name], \"[text]\" (Reply)") for(var/mob/M in player_list) if(M.stat == DEAD && M.is_preference_enabled(/datum/client_preference/ghost_ears)) if(istype(M, /mob/new_player) || M.forbid_seeing_deadchat) diff --git a/code/game/objects/items/devices/communicator/communicator.dm b/code/game/objects/items/devices/communicator/communicator.dm index caece035daf..d4fb3ff04ab 100644 --- a/code/game/objects/items/devices/communicator/communicator.dm +++ b/code/game/objects/items/devices/communicator/communicator.dm @@ -302,7 +302,7 @@ var/global/list/obj/item/device/communicator/all_communicators = list() /obj/item/device/communicator/Destroy() for(var/mob/living/voice/voice in contents) voice_mobs.Remove(voice) - to_chat(voice, "[icon2html(src, voice.client)] Connection timed out with remote host.") + to_chat(voice, "\icon[src][bicon(src)] Connection timed out with remote host.") qdel(voice) close_connection(reason = "Connection timed out") diff --git a/code/game/objects/items/devices/communicator/messaging.dm b/code/game/objects/items/devices/communicator/messaging.dm index 84c930479e6..2f9249dd5dc 100644 --- a/code/game/objects/items/devices/communicator/messaging.dm +++ b/code/game/objects/items/devices/communicator/messaging.dm @@ -34,7 +34,7 @@ if(src in comm.voice_invites) comm.open_connection(src) return - to_chat(src, "[icon2html(origin_atom,src.client)] Receiving communicator request from [origin_atom]. To answer, use the Call Communicator \ + to_chat(src, "\icon[origin_atom][bicon(origin_atom)] Receiving communicator request from [origin_atom]. To answer, use the Call Communicator \ verb, and select that name to answer the call.") src << 'sound/machines/defib_SafetyOn.ogg' comm.voice_invites |= src @@ -44,7 +44,7 @@ random = random / 10 exonet.send_message(origin_address, "64 bytes received from [exonet.address] ecmp_seq=1 ttl=51 time=[random] ms") if(message == "text") - to_chat(src, "[icon2html(origin_atom,src.client)] Received text message from [origin_atom]: \"[text]\"") + to_chat(src, "\icon[origin_atom][bicon(origin_atom)] Received text message from [origin_atom]: \"[text]\"") src << 'sound/machines/defib_safetyOff.ogg' exonet_messages.Add("From [origin_atom]:
[text]") return @@ -84,7 +84,7 @@ playsound(src, S, 50, 1) for (var/mob/O in hearers(2, loc)) - O.show_message(text("[icon2html(src,O.client)] *[ttone]*")) + O.show_message(text("\icon[src][bicon(src)] *[ttone]*")) alert_called = 1 update_icon() @@ -95,7 +95,7 @@ L = loc if(L) - to_chat(L, "[icon2html(src,L.client)] Message from [who]: \"[text]\" (Reply)") + to_chat(L, "\icon[src][bicon(src)] Message from [who]: \"[text]\" (Reply)") // This is the only Topic the communicators really uses /obj/item/device/communicator/Topic(href, href_list) @@ -108,7 +108,7 @@ exonet.send_message(comm.exonet.address, "text", message) im_list += list(list("address" = exonet.address, "to_address" = comm.exonet.address, "im" = message)) log_pda("(COMM: [src]) sent \"[message]\" to [exonet.get_atom_from_address(comm.exonet.address)]", usr) - to_chat(usr, "[icon2html(src,usr.client)] Sent message to [istype(comm, /obj/item/device/communicator) ? comm.owner : comm.name], \"[message]\" (Reply)") + to_chat(usr, "\icon[src][bicon(src)] Sent message to [istype(comm, /obj/item/device/communicator) ? comm.owner : comm.name], \"[message]\" (Reply)") // Verb: text_communicator() // Parameters: None diff --git a/code/game/objects/items/devices/communicator/phone.dm b/code/game/objects/items/devices/communicator/phone.dm index 76ec48aa5b4..bbf91d1ead1 100644 --- a/code/game/objects/items/devices/communicator/phone.dm +++ b/code/game/objects/items/devices/communicator/phone.dm @@ -39,15 +39,15 @@ comm.voice_requests.Remove(src) if(user) - comm.visible_message("[icon2html(src,viewers(src))] Connecting to [src].") - to_chat(user, "[icon2html(src,user.client)] Attempting to call [comm].") + comm.visible_message("\icon[src][bicon(src)] Connecting to [src].") + to_chat(user, "\icon[src][bicon(src)] Attempting to call [comm].") sleep(10) - to_chat(user, "[icon2html(src,user.client)] Dialing internally from [station_name()], [system_name()].") + to_chat(user, "\icon[src][bicon(src)] Dialing internally from [station_name()], [system_name()].") sleep(20) //If they don't have an exonet something is very wrong and we want a runtime. - to_chat(user, "[icon2html(src,user.client)] Connection re-routed to [comm] at [comm.exonet.address].") + to_chat(user, "\icon[src][bicon(src)] Connection re-routed to [comm] at [comm.exonet.address].") sleep(40) - to_chat(user, "[icon2html(src,user.client)] Connection to [comm] at [comm.exonet.address] established.") - comm.visible_message("[icon2html(src,viewers(src))] Connection to [src] at [exonet.address] established.") + to_chat(user, "\icon[src][bicon(src)] Connection to [comm] at [comm.exonet.address] established.") + comm.visible_message("\icon[src][bicon(src)] Connection to [src] at [exonet.address] established.") sleep(20) src.add_communicating(comm) @@ -86,28 +86,28 @@ //Now for some connection fluff. if(user) - to_chat(user, "[icon2html(src,user.client)] Connecting to [candidate].") - to_chat(new_voice, "[icon2html(src,new_voice.client)] Attempting to call [src].") + to_chat(user, "\icon[src][bicon(src)] Connecting to [candidate].") + to_chat(new_voice, "\icon[src][bicon(src)] Attempting to call [src].") sleep(10) - to_chat(new_voice, "[icon2html(src,new_voice.client)] Dialing to [station_name()], Kara Subsystem, [system_name()].") + to_chat(new_voice, "\icon[src][bicon(src)] Dialing to [station_name()], Kara Subsystem, [system_name()].") sleep(20) - to_chat(new_voice, "[icon2html(src,new_voice.client)] Connecting to [station_name()] telecommunications array.") + to_chat(new_voice, "\icon[src][bicon(src)] Connecting to [station_name()] telecommunications array.") sleep(40) - to_chat(new_voice, "[icon2html(src,new_voice.client)] Connection to [station_name()] telecommunications array established. Redirecting signal to [src].") + to_chat(new_voice, "\icon[src][bicon(src)] Connection to [station_name()] telecommunications array established. Redirecting signal to [src].") sleep(20) //We're connected, no need to hide everything. new_voice.client.screen.Remove(blackness) qdel(blackness) - to_chat(new_voice, "[icon2html(src,new_voice.client)] Connection to [src] established.") + to_chat(new_voice, "\icon[src][bicon(src)] Connection to [src] established.") to_chat(new_voice, "To talk to the person on the other end of the call, just talk normally.") to_chat(new_voice, "If you want to end the call, use the 'Hang Up' verb. The other person can also hang up at any time.") to_chat(new_voice, "Remember, your character does not know anything you've learned from observing!") if(new_voice.mind) new_voice.mind.assigned_role = "Disembodied Voice" if(user) - to_chat(user, "[icon2html(src,new_voice.client)] Your communicator is now connected to [candidate]'s communicator.") + to_chat(user, "\icon[src][bicon(src)] Your communicator is now connected to [candidate]'s communicator.") // Proc: close_connection() // Parameters: 3 (user - the user who initiated the disconnect, target - the mob or device being disconnected, reason - string shown when disconnected) @@ -120,8 +120,8 @@ for(var/mob/living/voice/voice in voice_mobs) //Handle ghost-callers if(target && voice != target) //If no target is inputted, it deletes all of them. continue - to_chat(voice, "[icon2html(src,voice.client)] [reason].") - visible_message("[icon2html(src,viewers(src))] [reason].") + to_chat(voice, "\icon[src][bicon(src)] [reason].") + visible_message("\icon[src][bicon(src)] [reason].") voice_mobs.Remove(voice) qdel(voice) update_icon() @@ -131,8 +131,8 @@ continue src.del_communicating(comm) comm.del_communicating(src) - comm.visible_message("[icon2html(src,viewers(src))] [reason].") - visible_message("[icon2html(src,viewers(src))] [reason].") + comm.visible_message("\icon[src][bicon(src)] [reason].") + visible_message("\icon[src][bicon(src)] [reason].") if(comm.camera && video_source == comm.camera) //We hung up on the person on video end_video() if(camera && comm.video_source == camera) //We hung up on them while they were watching us @@ -163,7 +163,7 @@ if(ringer) playsound(src, 'sound/machines/twobeep.ogg', 50, 1) for (var/mob/O in hearers(2, loc)) - O.show_message(text("[icon2html(src,O.client)] *beep*")) + O.show_message(text("\icon[src][bicon(src)] *beep*")) alert_called = 1 update_icon() @@ -174,7 +174,7 @@ L = loc if(L) - to_chat(L, "[icon2html(src,L.client)] Communications request from [who].") + to_chat(L, "\icon[src][bicon(src)] Communications request from [who].") // Proc: del_request() // Parameters: 1 (candidate - the ghost or communicator to be declined) @@ -197,13 +197,13 @@ us = loc if(us) - to_chat(us, "[icon2html(src,us.client)] Declined request.") + to_chat(us, "\icon[src][bicon(src)] Declined request.") // Proc: see_emote() // Parameters: 2 (M - the mob the emote originated from, text - the emote's contents) // Description: Relays the emote to all linked communicators. /obj/item/device/communicator/see_emote(mob/living/M, text) - + var/rendered = "\icon[src][bicon(src)] [text]" for(var/obj/item/device/communicator/comm in communicating) var/turf/T = get_turf(comm) if(!T) return @@ -216,7 +216,7 @@ var/list/in_range = get_mobs_and_objs_in_view_fast(T,world.view,0) //Range of 3 since it's a tiny video display mobs_to_relay = in_range["mobs"] //VOREStation Edit End - var/rendered = "[icon2html(src,mobs_to_relay)] [text]" + for(var/mob/mob in mobs_to_relay) //We can't use visible_message(), or else we will get an infinite loop if two communicators hear each other. var/dst = get_dist(get_turf(mob),get_turf(comm)) if(dst <= video_range) @@ -250,20 +250,20 @@ var/message = combined["formatted"] var/name_used = M.GetVoice() var/rendered = null - rendered = "[icon2html(src,mobs_to_relay)] [name_used] [message]" + rendered = "\icon[src][bicon(src)] [name_used] [message]" mob.show_message(rendered, 2) // Proc: show_message() // Parameters: 4 (msg - the message, type - number to determine if message is visible or audible, alt - unknown, alt_type - unknown) // Description: Relays the message to all linked communicators. /obj/item/device/communicator/show_message(msg, type, alt, alt_type) - + var/rendered = "\icon[src][bicon(src)] [msg]" for(var/obj/item/device/communicator/comm in communicating) var/turf/T = get_turf(comm) if(!T) return var/list/in_range = get_mobs_and_objs_in_view_fast(T,world.view,0) var/list/mobs_to_relay = in_range["mobs"] - var/rendered = "[icon2html(src, mobs_to_relay)] [msg]" + for(var/mob/mob in mobs_to_relay) mob.show_message(rendered) ..() @@ -339,29 +339,28 @@ return if(!(src in comm.communicating) || !comm.camera) //You called someone with a broken communicator or one that's fake or yourself or something - to_chat(user, "[icon2html(src, user.client)]ERROR: Video failed. Either bandwidth is too low, or the other communicator is malfunctioning.") + to_chat(user, "\icon[src][bicon(src)]ERROR: Video failed. Either bandwidth is too low, or the other communicator is malfunctioning.") return - to_chat(user, "[icon2html(src, user.client)] Attempting to start video over existing call.") + to_chat(user, "\icon[src][bicon(src)] Attempting to start video over existing call.") sleep(30) - to_chat(user, "[icon2html(src, user.client)] Please wait...") + to_chat(user, "\icon[src][bicon(src)] Please wait...") video_source = comm.camera - comm.visible_message("[icon2html(src,viewers(src))] New video connection from [comm].") + comm.visible_message("\icon[src][bicon(src)] New video connection from [comm].") update_active_camera_screen() - RegisterSignal(video_source, COMSIG_OBSERVER_MOVED, PROC_REF(update_active_camera_screen)) - video_source.AddComponent(/datum/component/recursive_move) + GLOB.moved_event.register(video_source, src, PROC_REF(update_active_camera_screen)) update_icon() // Proc: end_video() // Parameters: reason - the text reason to print for why it ended // Description: Ends the video call by clearing video_source /obj/item/device/communicator/proc/end_video(var/reason) - UnregisterSignal(video_source, COMSIG_OBSERVER_MOVED) + GLOB.moved_event.unregister(video_source, src, PROC_REF(update_active_camera_screen)) show_static() video_source = null - . = "[bicon(src)] [reason ? reason : "Video session ended"]." + . = "\icon[src][bicon(src)] [reason ? reason : "Video session ended"]." visible_message(.) update_icon() diff --git a/code/game/objects/items/devices/geiger.dm b/code/game/objects/items/devices/geiger.dm index d12833ba6f2..d127fe9404f 100644 --- a/code/game/objects/items/devices/geiger.dm +++ b/code/game/objects/items/devices/geiger.dm @@ -65,7 +65,7 @@ STOP_PROCESSING(SSobj, src) update_icon() update_sound() - to_chat(user, "[icon2html(src, user.client)] You switch [scanning ? "on" : "off"] \the [src].") + to_chat(user, "\icon[src][bicon(src)] You switch [scanning ? "on" : "off"] \the [src].") /obj/item/device/geiger/update_icon() if(!scanning) @@ -120,7 +120,7 @@ scanning = !scanning update_icon() update_sound() - to_chat(user, "[icon2html(src, user.client)] You switch [scanning ? "on" : "off"] \the [src].") + to_chat(user, "\icon[src] You switch [scanning ? "on" : "off"] \the [src].") /obj/item/device/geiger/wall/update_icon() if(!scanning) @@ -165,4 +165,4 @@ /obj/item/device/geiger/wall/west pixel_x = -28 - dir = WEST + dir = WEST \ No newline at end of file diff --git a/code/game/objects/items/devices/gps.dm b/code/game/objects/items/devices/gps.dm index df2ce116b16..1861694fae9 100644 --- a/code/game/objects/items/devices/gps.dm +++ b/code/game/objects/items/devices/gps.dm @@ -38,16 +38,15 @@ var/list/GPS_list = list() /obj/item/device/gps/proc/update_holder() if(holder && loc != holder) - UnregisterSignal(holder, COMSIG_OBSERVER_MOVED) - //GLOB.dir_set_event.unregister(holder, src) + GLOB.moved_event.unregister(holder, src) + GLOB.dir_set_event.unregister(holder, src) holder.client?.screen -= compass holder = null if(istype(loc, /mob)) holder = loc - RegisterSignal(holder, COMSIG_OBSERVER_MOVED, PROC_REF(update_compass), override = TRUE) - holder.AddComponent(/datum/component/recursive_move) - //GLOB.dir_set_event.register(holder, src, PROC_REF(update_compass)) + GLOB.moved_event.register(holder, src, PROC_REF(update_compass)) + GLOB.dir_set_event.register(holder, src, PROC_REF(update_compass)) if(holder && tracking) if(!is_in_processing_list) diff --git a/code/game/objects/items/devices/hacktool.dm b/code/game/objects/items/devices/hacktool.dm index f27ec959859..38f1c2afdf6 100644 --- a/code/game/objects/items/devices/hacktool.dm +++ b/code/game/objects/items/devices/hacktool.dm @@ -71,12 +71,12 @@ to_chat(user, "You are already hacking!") return 0 if(!is_type_in_list(target, supported_types)) - to_chat(user, "[icon2html(src, user.client)] Unable to hack this target, invalid target type.") + to_chat(user, "\icon[src][bicon(src)] Unable to hack this target, invalid target type.") return 0 var/obj/machinery/door/airlock/D = target if(D.security_level > max_level) - to_chat(user, "[icon2html(src, user.client)] Target's electronic security is too complex.") + to_chat(user, "\icon[src][bicon(src)] Target's electronic security is too complex.") return 0 var/found = known_targets.Find(D) diff --git a/code/game/objects/items/devices/radio/intercom.dm b/code/game/objects/items/devices/radio/intercom.dm index 004692f2a9a..86a1af1d727 100644 --- a/code/game/objects/items/devices/radio/intercom.dm +++ b/code/game/objects/items/devices/radio/intercom.dm @@ -20,15 +20,13 @@ . = ..() var/area/A = get_area(src) if(A) - RegisterSignal(A, COMSIG_OBSERVER_APC, /atom/proc/update_icon) + GLOB.apc_event.register(A, src, /atom/proc/update_icon) update_icon() /obj/item/device/radio/intercom/Destroy() var/area/A = get_area(src) if(A) - UnregisterSignal(A, COMSIG_OBSERVER_APC) - if(circuit) - QDEL_NULL(circuit) + GLOB.apc_event.unregister(A, src, /atom/proc/update_icon) return ..() /obj/item/device/radio/intercom/custom diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index 26af181ae92..616ce62b456 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -496,7 +496,7 @@ GLOBAL_DATUM(autospeaker, /mob/living/silicon/ai/announcer) distance = 99 else distance = jamming["distance"] - to_chat(M, "[icon2html(src, M.client)] You hear the [distance <= 2 ? "loud hiss" : "soft hiss"] of static.") + to_chat(M, "\icon[src][bicon(src)] You hear the [distance <= 2 ? "loud hiss" : "soft hiss"] of static.") return FALSE // First, we want to generate a new radio signal diff --git a/code/game/objects/items/devices/text_to_speech.dm b/code/game/objects/items/devices/text_to_speech.dm index d2fa720e6a1..55b744f0dc3 100644 --- a/code/game/objects/items/devices/text_to_speech.dm +++ b/code/game/objects/items/devices/text_to_speech.dm @@ -24,7 +24,7 @@ var/message = sanitize(tgui_input_text(user,"Choose a message to relay to those around you.")) if(message) - audible_message("[icon2html(src, user.client)] \The [src.name] states, \"[message]\"", runemessage = "synthesized speech") + audible_message("\icon[src][bicon(src)] \The [src.name] states, \"[message]\"", runemessage = "synthesized speech") if(ismob(loc)) loc.runechat_message("\[TTS Voice\] [message]") diff --git a/code/game/objects/items/toys/toys.dm b/code/game/objects/items/toys/toys.dm index 9dadaff977c..2331485fd17 100644 --- a/code/game/objects/items/toys/toys.dm +++ b/code/game/objects/items/toys/toys.dm @@ -716,7 +716,7 @@ if(stored_item && opened && !searching) searching = TRUE if(do_after(user, 10)) - to_chat(user, "You find [icon2html(stored_item, user.client)] [stored_item] in [src]!") + to_chat(user, "You find \icon[stored_item] [stored_item] in [src]!") stored_item.forceMove(get_turf(src)) stored_item = null searching = FALSE @@ -813,7 +813,7 @@ if(stored_item && opened && !searching) searching = TRUE if(do_after(user, 10)) - to_chat(user, "You find [icon2html(stored_item, user.client)] [stored_item] in [src]!") + to_chat(user, "You find \icon[stored_item] [stored_item] in [src]!") stored_item.forceMove(get_turf(src)) stored_item = null searching = FALSE @@ -1434,4 +1434,4 @@ /obj/structure/balloon/ghost name = "giant ghost balloon" desc = "Oh no, it's a ghost! Oh wait, it's just a balloon. Phew!" - icon_state = "ghostballoon" + icon_state = "ghostballoon" \ No newline at end of file diff --git a/code/game/objects/items/toys/toys_vr.dm b/code/game/objects/items/toys/toys_vr.dm index a5a08d16358..12ce075114b 100644 --- a/code/game/objects/items/toys/toys_vr.dm +++ b/code/game/objects/items/toys/toys_vr.dm @@ -667,7 +667,7 @@ /obj/item/toy/minigibber/attackby(obj/O, mob/user, params) if(istype(O,/obj/item/toy/figure) || istype(O,/obj/item/toy/character) && O.loc == user) - to_chat(user, "You start feeding \the [O] [icon2html(O, user.client)] into \the [src]'s mini-input.") + to_chat(user, "You start feeding \the [O] \icon[O][bicon(O)] into \the [src]'s mini-input.") if(do_after(user, 10, target = src)) if(O.loc != user) to_chat(user, "\The [O] is too far away to feed into \the [src]!") diff --git a/code/game/objects/items/weapons/capture_crystal.dm b/code/game/objects/items/weapons/capture_crystal.dm index 0439fb1aa89..450a2c6e39e 100644 --- a/code/game/objects/items/weapons/capture_crystal.dm +++ b/code/game/objects/items/weapons/capture_crystal.dm @@ -399,7 +399,9 @@ active = TRUE else //Shoot, it didn't work and now it's mad!!! S.ai_holder.go_wake() - S.ai_holder.give_target(user, urgent = TRUE) + S.ai_holder.target = user + S.ai_holder.track_target_position() + S.ai_holder.set_stance(STANCE_FIGHT) user.visible_message("\The [src] bonks into \the [S], angering it!") playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1) to_chat(user, "\The [src] clicks unsatisfyingly.") diff --git a/code/game/objects/items/weapons/circuitboards/frame.dm b/code/game/objects/items/weapons/circuitboards/frame.dm index 15644652944..c9bed28a5ea 100644 --- a/code/game/objects/items/weapons/circuitboards/frame.dm +++ b/code/game/objects/items/weapons/circuitboards/frame.dm @@ -62,13 +62,6 @@ board_type = new /datum/frame/frame_types/intercom matter = list(MAT_STEEL = 50, MAT_GLASS = 50) - -/obj/item/weapon/circuitboard/intercom/Destroy() - if(istype(loc, /obj/item/device/radio/intercom)) - var/obj/item/device/radio/intercom/my_machine = loc - my_machine.circuit = null - . = ..() - /obj/item/weapon/circuitboard/keycard_auth name = T_BOARD("keycard authenticator") build_path = /obj/machinery/keycard_auth diff --git a/code/game/objects/items/weapons/id cards/station_ids.dm b/code/game/objects/items/weapons/id cards/station_ids.dm index fe35bdc4534..f7b1f3b1972 100644 --- a/code/game/objects/items/weapons/id cards/station_ids.dm +++ b/code/game/objects/items/weapons/id cards/station_ids.dm @@ -93,8 +93,8 @@ return data /obj/item/weapon/card/id/attack_self(mob/user as mob) - user.visible_message("\The [user] shows you: [icon2html(src,viewers(src))] [src.name]. The assignment on the card: [src.assignment]",\ - "You flash your ID card: [icon2html(src, user.client)] [src.name]. The assignment on the card: [src.assignment]") + user.visible_message("\The [user] shows you: \icon[src][bicon(src)] [src.name]. The assignment on the card: [src.assignment]",\ + "You flash your ID card: \icon[src][bicon(src)] [src.name]. The assignment on the card: [src.assignment]") src.add_fingerprint(user) return @@ -110,7 +110,7 @@ set category = "Object" set src in usr - to_chat(usr, "[icon2html(src, usr.client)] [src.name]: The current assignment on the card is [src.assignment].") + to_chat(usr, "\icon[src][bicon(src)] [src.name]: The current assignment on the card is [src.assignment].") to_chat(usr, "The blood type on the card is [blood_type].") to_chat(usr, "The DNA hash on the card is [dna_hash].") to_chat(usr, "The fingerprint hash on the card is [fingerprint_hash].") diff --git a/code/game/objects/items/weapons/storage/bags.dm b/code/game/objects/items/weapons/storage/bags.dm index 3d26e518a19..a7137dded17 100644 --- a/code/game/objects/items/weapons/storage/bags.dm +++ b/code/game/objects/items/weapons/storage/bags.dm @@ -206,16 +206,14 @@ /obj/item/weapon/storage/bag/ore/equipped(mob/user) ..() if(user.get_inventory_slot(src) == slot_wear_suit || slot_l_hand || slot_l_hand || slot_belt) //Basically every place they can go. Makes sure it doesn't unregister if moved to other slots. - user.AddComponent(/datum/component/recursive_move) - RegisterSignal(user, COMSIG_OBSERVER_MOVED, /obj/item/weapon/storage/bag/ore/proc/autoload, user, override = TRUE) + GLOB.moved_event.register(user, src, /obj/item/weapon/storage/bag/ore/proc/autoload, user) /obj/item/weapon/storage/bag/ore/dropped(mob/user) ..() if(user.get_inventory_slot(src) == slot_wear_suit || slot_l_hand || slot_l_hand || slot_belt) //See above. This should really be a define. - user.AddComponent(/datum/component/recursive_move) - RegisterSignal(user, COMSIG_OBSERVER_MOVED, /obj/item/weapon/storage/bag/ore/proc/autoload, user, override = TRUE) + GLOB.moved_event.register(user, src, /obj/item/weapon/storage/bag/ore/proc/autoload, user) else - UnregisterSignal(user, COMSIG_OBSERVER_MOVED) + GLOB.moved_event.unregister(user, src) /obj/item/weapon/storage/bag/ore/proc/autoload(mob/user) var/obj/item/weapon/ore/O = locate() in get_turf(src) @@ -494,4 +492,4 @@ max_storage_space = ITEMSIZE_COST_NORMAL * 15 max_w_class = ITEMSIZE_NORMAL w_class = ITEMSIZE_SMALL - can_hold = list(/obj/item/weapon/forensics/swab,/obj/item/weapon/sample/print,/obj/item/weapon/sample/fibers,/obj/item/weapon/evidencebag) + can_hold = list(/obj/item/weapon/forensics/swab,/obj/item/weapon/sample/print,/obj/item/weapon/sample/fibers,/obj/item/weapon/evidencebag) \ No newline at end of file diff --git a/code/game/objects/items/weapons/syndie.dm b/code/game/objects/items/weapons/syndie.dm index a5cb000f715..5e519f8f4f0 100644 --- a/code/game/objects/items/weapons/syndie.dm +++ b/code/game/objects/items/weapons/syndie.dm @@ -50,7 +50,7 @@ icon_state = "c-4[size]_1" playsound(src, 'sound/weapons/armbomb.ogg', 75, 1) for(var/mob/O in hearers(src, null)) - O.show_message("[icon2html(src, O.client)] The [src.name] beeps! ") + O.show_message("\icon[src][bicon(src)] The [src.name] beeps! ") sleep(50) explosion(get_turf(src), devastate, heavy_impact, light_impact, flash_range) for(var/dirn in cardinal) //This is to guarantee that C4 at least breaks down all immediately adjacent walls and doors. diff --git a/code/game/objects/items/weapons/tanks/tanks.dm b/code/game/objects/items/weapons/tanks/tanks.dm index c1cb09fecba..8c176ecbbb3 100644 --- a/code/game/objects/items/weapons/tanks/tanks.dm +++ b/code/game/objects/items/weapons/tanks/tanks.dm @@ -455,7 +455,7 @@ var/list/global/tank_gauge_cache = list() return T.assume_air(air_contents) playsound(src, 'sound/weapons/Gunshot_shotgun.ogg', 20, 1) - visible_message("[icon2html(src,viewers(src))] \The [src] flies apart!", "You hear a bang!") + visible_message("\icon[src][bicon(src)] \The [src] flies apart!", "You hear a bang!") T.hotspot_expose(air_contents.temperature, 70, 1) @@ -500,7 +500,7 @@ var/list/global/tank_gauge_cache = list() T.assume_air(leaked_gas) if(!leaking) - visible_message("[icon2html(src,viewers(src))] \The [src] relief valve flips open with a hiss!", "You hear hissing.") + visible_message("\icon[src][bicon(src)] \The [src] relief valve flips open with a hiss!", "You hear hissing.") playsound(src, 'sound/effects/spray.ogg', 10, 1, -3) leaking = 1 #ifdef FIREDBG diff --git a/code/game/objects/items/weapons/tools/combitool.dm b/code/game/objects/items/weapons/tools/combitool.dm index bfc4baeb858..2f2ddbf4a5a 100644 --- a/code/game/objects/items/weapons/tools/combitool.dm +++ b/code/game/objects/items/weapons/tools/combitool.dm @@ -29,7 +29,7 @@ if(loc == user && tools.len) . += "It has the following fittings:" for(var/obj/item/tool in tools) - . += "[icon2html(tool,)] - [tool.name][tools[current_tool]==tool?" (selected)":""]") + . += "\icon[tool][bicon(tool)] - [tool.name][tools[current_tool]==tool?" (selected)":""]") /obj/item/weapon/combitool/New() ..() diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 11667d2f53e..21b78b9a49e 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -57,7 +57,7 @@ /obj/CanUseTopic(var/mob/user, var/datum/tgui_state/state = GLOB.tgui_default_state) if(user.CanUseObjTopic(src)) return ..() - to_chat(user, "[icon2html(src, user.client)]Access Denied!") + to_chat(user, "\icon[src][bicon(src)]Access Denied!") return STATUS_CLOSE /mob/living/silicon/CanUseObjTopic(var/obj/O) diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm index 8e5b177ab9c..e63debb8efe 100644 --- a/code/game/objects/structures/bedsheet_bin.dm +++ b/code/game/objects/structures/bedsheet_bin.dm @@ -181,12 +181,11 @@ LINEN BINS . += "There are [amount] bed sheets in the bin." /obj/structure/bedsheetbin/update_icon() - if(amount == 0) - icon_state = "linenbin-empty" - else if(amount <= (amount / 2)) - icon_state = "linenbin-half" - else - icon_state = "linenbin-full" + switch(amount) + if(0) icon_state = "linenbin-empty" + if(1 to amount / 2) icon_state = "linenbin-half" + else icon_state = "linenbin-full" + /obj/structure/bedsheetbin/attackby(obj/item/I as obj, mob/user as mob) if(istype(I, /obj/item/weapon/bedsheet)) diff --git a/code/game/objects/structures/flora/flora.dm b/code/game/objects/structures/flora/flora.dm index d665ca5ab80..fe69c9f30fc 100644 --- a/code/game/objects/structures/flora/flora.dm +++ b/code/game/objects/structures/flora/flora.dm @@ -300,7 +300,7 @@ user.drop_from_inventory(I, src) I.forceMove(src) stored_item = I - src.visible_message("[icon2html(src,viewers(src))] [icon2html(I,viewers(src))] [user] places [I] into [src].") + src.visible_message("\icon[src][bicon(src)] \icon[I][bicon(I)] [user] places [I] into [src].") return else to_chat(user, "You refrain from putting things into the plant pot.") @@ -311,7 +311,7 @@ to_chat(user, "You see nothing of interest in [src]...") else if(do_after(user, 10)) - to_chat(user, "You find [icon2html(stored_item, user.client)] [stored_item] in [src]!") + to_chat(user, "You find \icon[stored_item][bicon(stored_item)] [stored_item] in [src]!") stored_item.forceMove(get_turf(src)) stored_item = null ..() @@ -684,3 +684,4 @@ /obj/structure/flora/underwater/grass4 icon_state = "grass-4" + diff --git a/code/game/objects/structures/janicart.dm b/code/game/objects/structures/janicart.dm index 370d494f357..8450a219b5f 100644 --- a/code/game/objects/structures/janicart.dm +++ b/code/game/objects/structures/janicart.dm @@ -119,9 +119,9 @@ GLOBAL_LIST_BOILERPLATE(all_janitorial_carts, /obj/structure/janitorialcart) . = ..(user) if(istype(mybucket)) var/contains = mybucket.reagents.total_volume - . += "[icon2html(src, user.client)] The bucket contains [contains] unit\s of liquid!" + . += "\icon[src][bicon(src)] The bucket contains [contains] unit\s of liquid!" else - . += "[icon2html(src, user.client)] There is no bucket mounted on it!" + . += "\icon[src][bicon(src)] There is no bucket mounted on it!" /obj/structure/janitorialcart/MouseDrop_T(atom/movable/O as mob|obj, mob/living/user as mob) if (istype(O, /obj/structure/mopbucket) && !mybucket) diff --git a/code/game/world.dm b/code/game/world.dm index 5a20d43b71c..0087ae27e58 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -1,19 +1,5 @@ -/proc/prof_init() - var/lib - - switch(world.system_type) - if(MS_WINDOWS) lib = "prof.dll" - if(UNIX) lib = "libprof.so" - else CRASH("unsupported platform") - - var/init = LIBCALL(lib, "init")() - if("0" != init) CRASH("[lib] init error: [init]") - #define RECOMMENDED_VERSION 513 /world/New() - #ifdef TRACY - prof_init() - #endif world_startup_time = world.timeofday rollover_safety_date = world.realtime - world.timeofday // 00:00 today (ish, since floating point error with world.realtime) of today to_world_log("Map Loading Complete") diff --git a/code/modules/admin/verbs/modify_robot.dm b/code/modules/admin/verbs/modify_robot.dm index e7f4f246e12..e90e06bd27d 100644 --- a/code/modules/admin/verbs/modify_robot.dm +++ b/code/modules/admin/verbs/modify_robot.dm @@ -43,17 +43,14 @@ var/list/all_modules = robot.module.modules all_modules += robot.module.emag while(TRUE) - var/add_item_select = tgui_input_list(usr, "Please select the module to add", "Modules", all_modules)//ChompEDIT - if(!istype(add_item_select, /obj/item/))//ChompEDIT + var/add_item = tgui_input_list(usr, "Please select the module to add", "Modules", all_modules) + if(!istype(add_item, /obj/item/)) break - var/obj/item/add_item = add_item_select//ChompEDIT robot.module.emag.Remove(add_item) robot.module.modules.Remove(add_item) robot.module.contents.Remove(add_item) target.module.modules.Add(add_item) target.module.contents.Add(add_item) - spawn(0) //ChompEDIT Must be after to allow the movement to finish - SEND_SIGNAL(add_item, COMSIG_OBSERVER_MOVED)//ChompEDIT - report the movement since setting loc doesn't call Move or Moved target.hud_used.update_robot_modules_display() to_chat(usr, "You added \"[add_item]\" to [target].") if(istype(add_item, /obj/item/stack/)) diff --git a/code/modules/admin/verbs/pray.dm b/code/modules/admin/verbs/pray.dm index d4a405e35c0..7725ad92728 100644 --- a/code/modules/admin/verbs/pray.dm +++ b/code/modules/admin/verbs/pray.dm @@ -17,7 +17,7 @@ return var/icon/cross = icon('icons/obj/storage.dmi',"bible") - var/msg = "" + span_blue("[icon2html(cross, GLOB.admins)] " + span_purple("PRAY: ") + "[key_name(src, 1)] [ADMIN_QUE(src)] [ADMIN_PP(src)] [ADMIN_VV(src)] [ADMIN_SM(src)] ([admin_jump_link(src, src)]) [ADMIN_CA(src)] [ADMIN_SC(src)] [ADMIN_SMITE(src)]: [raw_msg]") + "" + var/msg = "" + span_blue("\icon[cross][bicon(cross)] " + span_purple("PRAY: ") + "[key_name(src, 1)] [ADMIN_QUE(src)] [ADMIN_PP(src)] [ADMIN_VV(src)] [ADMIN_SM(src)] ([admin_jump_link(src, src)]) [ADMIN_CA(src)] [ADMIN_SC(src)] [ADMIN_SMITE(src)]: [raw_msg]") + "" for(var/client/C in GLOB.admins) if(R_ADMIN|R_EVENT & C.holder.rights) diff --git a/code/modules/ai/ai_holder.dm b/code/modules/ai/ai_holder.dm index f8bf5cd9dcc..78e85bfa3e0 100644 --- a/code/modules/ai/ai_holder.dm +++ b/code/modules/ai/ai_holder.dm @@ -20,13 +20,7 @@ return ..() /mob/living/Destroy() - if(ai_holder) - ai_holder.holder = null - ai_holder.UnregisterSignal(src,COMSIG_MOB_STATCHANGE) - if(ai_holder.faction_friends && ai_holder.faction_friends.len) //This list is shared amongst the faction - ai_holder.faction_friends -= src - ai_holder.faction_friends = null - QDEL_NULL(ai_holder) + QDEL_NULL(ai_holder) return ..() /mob/living/Login() @@ -228,7 +222,7 @@ holder = new_holder home_turf = get_turf(holder) manage_processing(AI_PROCESSING) - RegisterSignal(holder, COMSIG_MOB_STATCHANGE, PROC_REF(holder_stat_change)) + GLOB.stat_set_event.register(holder, src, PROC_REF(holder_stat_change)) ..() /datum/ai_holder/Destroy() diff --git a/code/modules/ai/ai_holder_cooperation.dm b/code/modules/ai/ai_holder_cooperation.dm index 97f3781ad5c..dd6228f4600 100644 --- a/code/modules/ai/ai_holder_cooperation.dm +++ b/code/modules/ai/ai_holder_cooperation.dm @@ -18,9 +18,8 @@ build_faction_friends() /datum/ai_holder/Destroy() - if(faction_friends) - if(faction_friends.len) //This list is shared amongst the faction - faction_friends -= src + if(faction_friends.len) //This list is shared amongst the faction + faction_friends -= src return ..() // Handles everything about that list. @@ -115,3 +114,4 @@ add_attacker(their_target) // We won't wait and 'warn' them while they're stabbing our ally set_follow(friend, 10 SECONDS) ai_log("help_requested() : Exiting.", AI_LOG_DEBUG) + diff --git a/code/modules/ai/ai_holder_subtypes/simple_mob_ai.dm b/code/modules/ai/ai_holder_subtypes/simple_mob_ai.dm index 4455b47072b..c23a4d92e6e 100644 --- a/code/modules/ai/ai_holder_subtypes/simple_mob_ai.dm +++ b/code/modules/ai/ai_holder_subtypes/simple_mob_ai.dm @@ -187,7 +187,7 @@ /datum/ai_holder/simple_mob/humanoid/hostile/post_ranged_attack(atom/A) //Pick a random turf to step into var/turf/T = get_step(holder, pick(alldirs)) - if((A in check_trajectory(A, T))) // Can we even hit them from there? + if(check_trajectory(A, T)) // Can we even hit them from there? holder.IMove(T) holder.face_atom(A) @@ -197,3 +197,4 @@ /datum/ai_holder/simple_mob/passive/speedy base_wander_delay = 1 + diff --git a/code/modules/ai/ai_holder_targeting.dm b/code/modules/ai/ai_holder_targeting.dm index b918321f8b3..8c0a38b4ff0 100644 --- a/code/modules/ai/ai_holder_targeting.dm +++ b/code/modules/ai/ai_holder_targeting.dm @@ -82,8 +82,6 @@ target = new_target - RegisterSignal(target, COMSIG_PARENT_QDELETING, PROC_REF(remove_target)) - if(target != null) lose_target_time = 0 track_target_position() @@ -191,7 +189,6 @@ ai_log("lose_target() : Entering.", AI_LOG_TRACE) if(target) ai_log("lose_target() : Had a target, setting to null and LTT.", AI_LOG_DEBUG) - UnregisterSignal(target, COMSIG_PARENT_QDELETING, PROC_REF(remove_target)) target = null lose_target_time = world.time @@ -207,7 +204,6 @@ /datum/ai_holder/proc/remove_target() ai_log("remove_target() : Entering.", AI_LOG_TRACE) if(target) - UnregisterSignal(target, COMSIG_PARENT_QDELETING, PROC_REF(remove_target)) target = null lose_target_time = 0 diff --git a/code/modules/ai/say_list.dm b/code/modules/ai/say_list.dm index fb4e66651ef..f2bd5c028ed 100644 --- a/code/modules/ai/say_list.dm +++ b/code/modules/ai/say_list.dm @@ -134,4 +134,4 @@ emote_hear = list("hisses") /datum/say_list/crab - emote_hear = list("hisses") + emote_hear = list("hisses") \ No newline at end of file diff --git a/code/modules/assembly/holder.dm b/code/modules/assembly/holder.dm index 32ee55d553c..110a9cee35f 100644 --- a/code/modules/assembly/holder.dm +++ b/code/modules/assembly/holder.dm @@ -151,7 +151,7 @@ if(!D) return 0 if(!secured) - visible_message("[icon2html(src,viewers(src))] *beep* *beep*", "*beep* *beep*") + visible_message("\icon[src][bicon(src)] *beep* *beep*", "*beep* *beep*") if((normal) && (a_right) && (a_left)) if(a_right != D) a_right.pulsed(0) diff --git a/code/modules/assembly/infrared.dm b/code/modules/assembly/infrared.dm index 7c6ce614589..fb5566504ef 100644 --- a/code/modules/assembly/infrared.dm +++ b/code/modules/assembly/infrared.dm @@ -98,7 +98,7 @@ pulse(0) QDEL_LIST_NULL(i_beams) //They will get recreated next process() if the situation is still appropriate if(!holder) - visible_message("[icon2html(src,viewers(src))] *beep* *beep*") + visible_message("\icon[src][bicon(src)] *beep* *beep*") /obj/item/device/assembly/infra/tgui_interact(mob/user, datum/tgui/ui) if(!secured) @@ -178,4 +178,4 @@ return if(istype(AM, /obj/effect/beam)) return - hit() + hit() \ No newline at end of file diff --git a/code/modules/assembly/proximity.dm b/code/modules/assembly/proximity.dm index 959d4566d24..7c12d5fb039 100644 --- a/code/modules/assembly/proximity.dm +++ b/code/modules/assembly/proximity.dm @@ -47,7 +47,7 @@ var/turf/mainloc = get_turf(src) pulse(0) if(!holder) - mainloc.visible_message("[icon2html(src,viewers(src))] *beep* *beep*", "*beep* *beep*") + mainloc.visible_message("\icon[src][bicon(src)] *beep* *beep*", "*beep* *beep*") /obj/item/device/assembly/prox_sensor/process() if(scanning) diff --git a/code/modules/assembly/signaler.dm b/code/modules/assembly/signaler.dm index 3232e602d06..a87a13a5765 100644 --- a/code/modules/assembly/signaler.dm +++ b/code/modules/assembly/signaler.dm @@ -116,7 +116,7 @@ if(!holder) for(var/mob/O in hearers(1, src.loc)) - O.show_message("[icon2html(src, O.client)] *beep* *beep*", 3, "*beep* *beep*", 2) + O.show_message("\icon[src][bicon(src)] *beep* *beep*", 3, "*beep* *beep*", 2) /obj/item/device/assembly/signaler/proc/set_frequency(new_frequency) if(!frequency) diff --git a/code/modules/assembly/timer.dm b/code/modules/assembly/timer.dm index fb47a020c32..dd13a1e4a21 100644 --- a/code/modules/assembly/timer.dm +++ b/code/modules/assembly/timer.dm @@ -44,7 +44,7 @@ return 0 pulse(0) if(!holder) - visible_message("[icon2html(src,viewers(src))] *beep* *beep*", "*beep* *beep*") + visible_message("\icon[src][bicon(src)] *beep* *beep*", "*beep* *beep*") /obj/item/device/assembly/timer/process() if(timing && time-- <= 0) diff --git a/code/modules/assembly/voice.dm b/code/modules/assembly/voice.dm index 2783f92b767..7c8eee7fdfb 100644 --- a/code/modules/assembly/voice.dm +++ b/code/modules/assembly/voice.dm @@ -13,7 +13,7 @@ recorded = msg listening = 0 var/turf/T = get_turf(src) //otherwise it won't work in hand - T.visible_message("[icon2html(src,viewers(src))] beeps, \"Activation message is '[recorded]'.\"") + T.visible_message("\icon[src][bicon(src)] beeps, \"Activation message is '[recorded]'.\"") else if(findtext(msg, recorded)) pulse(0) @@ -23,7 +23,7 @@ if(!holder) listening = !listening var/turf/T = get_turf(src) - T.visible_message("[icon2html(src,viewers(src))] beeps, \"[listening ? "Now" : "No longer"] recording input.\"") + T.visible_message("\icon[src][bicon(src)] beeps, \"[listening ? "Now" : "No longer"] recording input.\"") /obj/item/device/assembly/voice/attack_self(mob/user) @@ -34,4 +34,4 @@ /obj/item/device/assembly/voice/toggle_secure() . = ..() - listening = 0 + listening = 0 \ No newline at end of file diff --git a/code/modules/asset_cache/asset_cache.dm b/code/modules/asset_cache/asset_cache.dm new file mode 100644 index 00000000000..53a30d4299a --- /dev/null +++ b/code/modules/asset_cache/asset_cache.dm @@ -0,0 +1,110 @@ +/* +Asset cache quick users guide: + +Make a datum in asset_list_items.dm with your assets for your thing. +Checkout asset_list.dm for the helper subclasses +The simple subclass will most like be of use for most cases. +Then call get_asset_datum() with the type of the datum you created and store the return +Then call .send(client) on that stored return value. + +Note: If your code uses output() with assets you will need to call asset_flush on the client and wait for it to return before calling output(). You only need do this if .send(client) returned TRUE +*/ + +//When sending mutiple assets, how many before we give the client a quaint little sending resources message +#define ASSET_CACHE_TELL_CLIENT_AMOUNT 8 + +//This proc sends the asset to the client, but only if it needs it. +//This proc blocks(sleeps) unless verify is set to false +/proc/send_asset(client/client, asset_name) + return send_asset_list(client, list(asset_name)) + +/// Sends a list of assets to a client +/// This proc will no longer block, use client.asset_flush() if you to need know when the client has all assets (such as for output()). (This is not required for browse() calls as they use the same message queue as asset sends) +/// client - a client or mob +/// asset_list - A list of asset filenames to be sent to the client. +/// Returns TRUE if any assets were sent. +/proc/send_asset_list(client/client, list/asset_list) + if(!istype(client)) + if(ismob(client)) + var/mob/M = client + if(M.client) + client = M.client + else + return + else + return + + var/list/unreceived = list() + + for (var/asset_name in asset_list) + var/datum/asset_cache_item/asset = SSassets.cache[asset_name] + if (!asset) + continue + var/asset_file = asset.resource + if (!asset_file) + continue + + var/asset_md5 = asset.md5 + if (client.sent_assets[asset_name] == asset_md5) + continue + unreceived[asset_name] = asset_md5 + + if (unreceived.len) + if (unreceived.len >= ASSET_CACHE_TELL_CLIENT_AMOUNT) + to_chat(client, "Sending Resources...") + + for(var/asset in unreceived) + var/datum/asset_cache_item/ACI + if ((ACI = SSassets.cache[asset])) + log_asset("Sending asset [asset] to client [client]") + client << browse_rsc(ACI.resource, asset) + + client.sent_assets |= unreceived + addtimer(CALLBACK(client, /client/proc/asset_cache_update_json), 1 SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE) + return TRUE + return FALSE + +//This proc will download the files without clogging up the browse() queue, used for passively sending files on connection start. +//The proc calls procs that sleep for long times. +/proc/getFilesSlow(client/client, list/files, register_asset = TRUE, filerate = 3) + var/startingfilerate = filerate + for(var/file in files) + if (!client) + break + if (register_asset) + register_asset(file, files[file]) + + if (send_asset(client, file)) + if (!(--filerate)) + filerate = startingfilerate + client.asset_flush() + stoplag(0) //queuing calls like this too quickly can cause issues in some client versions + +//This proc "registers" an asset, it adds it to the cache for further use, you cannot touch it from this point on or you'll fuck things up. +//icons and virtual assets get copied to the dyn rsc before use +/proc/register_asset(asset_name, asset) + var/datum/asset_cache_item/ACI = new(asset_name, asset) + + //this is technically never something that was supported and i want metrics on how often it happens if at all. + if (SSassets.cache[asset_name]) + var/datum/asset_cache_item/OACI = SSassets.cache[asset_name] + if (OACI.md5 != ACI.md5) + stack_trace("ERROR: new asset added to the asset cache with the same name as another asset: [asset_name] existing asset md5: [OACI.md5] new asset md5:[ACI.md5]") + else + var/list/stacktrace = gib_stack_trace() + log_asset("WARNING: dupe asset added to the asset cache: [asset_name] existing asset md5: [OACI.md5] new asset md5:[ACI.md5]\n[stacktrace.Join("\n")]") + SSassets.cache[asset_name] = ACI + return ACI + +/// Returns the url of the asset, currently this is just its name, here to allow further work cdn'ing assets. +/// Can be given an asset as well, this is just a work around for buggy edge cases where two assets may have the same name, doesn't matter now, but it will when the cdn comes. +/proc/get_asset_url(asset_name, asset = null) + var/datum/asset_cache_item/ACI = SSassets.cache[asset_name] + return ACI?.url + +//Generated names do not include file extention. +//Used mainly for code that deals with assets in a generic way +//The same asset will always lead to the same asset name +/proc/generate_asset_name(file) + return "asset.[md5(fcopy_rsc(file))]" + diff --git a/code/modules/asset_cache/asset_cache_client.dm b/code/modules/asset_cache/asset_cache_client.dm index 3cff8cb41f3..e25b9969863 100644 --- a/code/modules/asset_cache/asset_cache_client.dm +++ b/code/modules/asset_cache/asset_cache_client.dm @@ -1,5 +1,5 @@ -/// Process asset cache client topic calls for `"asset_cache_confirm_arrival=[INT]"` +/// Process asset cache client topic calls for "asset_cache_confirm_arrival=[INT]" /client/proc/asset_cache_confirm_arrival(job_id) var/asset_cache_job = round(text2num(job_id)) //because we skip the limiter, we have to make sure this is a valid arrival and not somebody tricking us into letting them append to a list without limit. @@ -10,9 +10,17 @@ return asset_cache_job || TRUE -/// Process asset cache client topic calls for `"asset_cache_preload_data=[HTML+JSON_STRING]"` +/// Process asset cache client topic calls for "asset_cache_preload_data=[HTML+JSON_STRING] /client/proc/asset_cache_preload_data(data) + /*var/jsonend = findtextEx(data, "{{{ENDJSONDATA}}}") + if (!jsonend) + CRASH("invalid asset_cache_preload_data, no jsonendmarker")*/ + //var/json = html_decode(copytext(data, 1, jsonend)) var/json = data + + // This is a stupid workaround to BYOND injecting this pngfix mess into IE7 clients browse() + json = replacetext(json, "", "") + var/list/preloaded_assets = json_decode(json) for (var/preloaded_asset in preloaded_assets) @@ -22,17 +30,19 @@ sent_assets |= preloaded_assets -/// Updates the client side stored json file used to keep track of what assets the client has between restarts/reconnects. -/client/proc/asset_cache_update_json() +/// Updates the client side stored html/json combo file used to keep track of what assets the client has between restarts/reconnects. +/client/proc/asset_cache_update_json(verify = FALSE, list/new_assets = list()) if (world.time - connection_time < 10 SECONDS) //don't override the existing data file on a new connection return + if (!islist(new_assets)) + new_assets = list("[new_assets]" = md5(SSassets.cache[new_assets])) - src << browse(json_encode(sent_assets), "file=asset_data.json&display=0") + src << browse(json_encode(new_assets|sent_assets), "file=asset_data.json&display=0") -/// Blocks until all currently sending browse and browse_rsc assets have been sent. +/// Blocks until all currently sending browser assets have been sent. /// Due to byond limitations, this proc will sleep for 1 client round trip even if the client has no pending asset sends. /// This proc will return an untrue value if it had to return before confirming the send, such as timeout or the client going away. -/client/proc/browse_queue_flush(timeout = 50) +/client/proc/asset_flush(timeout = 50) var/job = ++last_asset_job var/t = 0 var/timeout_time = timeout diff --git a/code/modules/asset_cache/asset_cache_item.dm b/code/modules/asset_cache/asset_cache_item.dm index ad4596bdedc..5f02e561c6f 100644 --- a/code/modules/asset_cache/asset_cache_item.dm +++ b/code/modules/asset_cache/asset_cache_item.dm @@ -1,54 +1,23 @@ /** - * # asset_cache_item - * - * An internal datum containing info on items in the asset cache. Mainly used to cache md5 info for speed. - */ + * # asset_cache_item + * + * An internal datum containing info on items in the asset cache. Mainly used to cache md5 info for speed. +**/ /datum/asset_cache_item - /// the name of this asset item, becomes the key in SSassets.cache list var/name - /// md5() of the file this asset item represents. - var/hash - /// the file this asset represents + var/url + var/md5 var/resource - /// our file extension e.g. .png, .gif, etc - var/ext = "" - /// Should this file also be sent via the legacy browse_rsc system - /// when cdn transports are enabled? - var/legacy = FALSE - /// Used by the cdn system to keep legacy css assets with their parent - /// css file. (css files resolve urls relative to the css file, so the - /// legacy system can't be used if the css file itself could go out over - /// the cdn) - var/namespace = null - /// True if this is the parent css or html file for an asset's namespace - var/namespace_parent = FALSE - /// TRUE for keeping local asset names when browse_rsc backend is used - var/keep_local_name = FALSE -///pass in a valid file_hash if you have one to save it from needing to do it again. -///pass in a valid dmi file path string e.g. "icons/path/to/dmi_file.dmi" to make generating the hash less expensive -/datum/asset_cache_item/New(name, file, file_hash, dmi_file_path) +/datum/asset_cache_item/New(name, file) if (!isfile(file)) file = fcopy_rsc(file) - - hash = file_hash - - //the given file is directly from a dmi file and is thus in the rsc already, we know that its file_hash will be correct - if(!hash) - if(dmi_file_path) - hash = md5(file) - else - hash = md5asfile(file) //icons sent to the rsc md5 incorrectly when theyre given incorrect data - if (!hash) - CRASH("invalid asset sent to asset cache") + md5 = md5(file) + if (!md5) + md5 = md5(fcopy_rsc(file)) + if (!md5) + CRASH("invalid asset sent to asset cache") + log_world("asset cache unexpected success of second fcopy_rsc") src.name = name - var/extstart = findlasttext(name, ".") - if (extstart) - ext = ".[copytext(name, extstart+1)]" + url = name resource = file - -/datum/asset_cache_item/vv_edit_var(var_name, var_value) - return FALSE - -/datum/asset_cache_item/CanProcCall(procname) - return FALSE diff --git a/code/modules/asset_cache/asset_list.dm b/code/modules/asset_cache/asset_list.dm index c9e02cb9276..4ce9dcf6fc0 100644 --- a/code/modules/asset_cache/asset_list.dm +++ b/code/modules/asset_cache/asset_list.dm @@ -1,4 +1,3 @@ -#define ASSET_CROSS_ROUND_CACHE_DIRECTORY "tmp/assets" //These datums are used to populate the asset cache, the proc "register()" does this. //Place any asset datums you create in asset_list_items.dm @@ -7,101 +6,46 @@ GLOBAL_LIST_EMPTY(asset_datums) //get an assetdatum or make a new one -//does NOT ensure it's filled, if you want that use get_asset_datum() -/proc/load_asset_datum(type) - return GLOB.asset_datums[type] || new type() - /proc/get_asset_datum(type) - var/datum/asset/loaded_asset = GLOB.asset_datums[type] || new type() - return loaded_asset.ensure_ready() + return GLOB.asset_datums[type] || new type() /datum/asset var/_abstract = /datum/asset - var/cached_serialized_url_mappings - var/cached_serialized_url_mappings_transport_type - - /// Whether or not this asset should be loaded in the "early assets" SS - var/early = FALSE - - /// Whether or not this asset can be cached across rounds of the same commit under the `CACHE_ASSETS` config. - /// This is not a *guarantee* the asset will be cached. Not all asset subtypes respect this field, and the - /// config can, of course, be disabled. - /// Disable this if your asset can change between rounds on the same exact version of the code. - var/cross_round_cachable = FALSE /datum/asset/New() GLOB.asset_datums[type] = src register() -/// Stub that allows us to react to something trying to get us -/// Not useful here, more handy for sprite sheets -/datum/asset/proc/ensure_ready() - return src - -/// Stub to hook into if your asset is having its generation queued by SSasset_loading -/datum/asset/proc/queued_generation() - CRASH("[type] inserted into SSasset_loading despite not implementing /proc/queued_generation") - /datum/asset/proc/get_url_mappings() return list() -/// Returns a cached tgui message of URL mappings -/datum/asset/proc/get_serialized_url_mappings() - if (isnull(cached_serialized_url_mappings) || cached_serialized_url_mappings_transport_type != SSassets.transport.type) - cached_serialized_url_mappings = TGUI_CREATE_MESSAGE("asset/mappings", get_url_mappings()) - cached_serialized_url_mappings_transport_type = SSassets.transport.type - - return cached_serialized_url_mappings - /datum/asset/proc/register() return /datum/asset/proc/send(client) return -/// Returns whether or not the asset should attempt to read from cache -/datum/asset/proc/should_refresh() - return !cross_round_cachable || !config.cache_assets -/// Simply takes any generated file and saves it to the round-specific /logs folder. Useful for debugging potential issues with spritesheet generation/display. -/// Only called when the SAVE_SPRITESHEETS config option is uncommented. -/datum/asset/proc/save_to_logs(file_name, file_location) - var/asset_path = "[log_path]/generated_assets/[file_name]" - fdel(asset_path) // just in case, sadly we can't use rust_g stuff here. - fcopy(file_location, asset_path) - -/// If you don't need anything complicated. +//If you don't need anything complicated. /datum/asset/simple _abstract = /datum/asset/simple - /// list of assets for this datum in the form of: - /// asset_filename = asset_file. At runtime the asset_file will be - /// converted into a asset_cache datum. var/assets = list() - /// Set to true to have this asset also be sent via the legacy browse_rsc - /// system when cdn transports are enabled? - var/legacy = FALSE - /// TRUE for keeping local asset names when browse_rsc backend is used - var/keep_local_name = FALSE /datum/asset/simple/register() for(var/asset_name in assets) - var/datum/asset_cache_item/ACI = SSassets.transport.register_asset(asset_name, assets[asset_name]) - if (!ACI) - log_asset("ERROR: Invalid asset: [type]:[asset_name]:[ACI]") - continue - if (legacy) - ACI.legacy = legacy - if (keep_local_name) - ACI.keep_local_name = keep_local_name - assets[asset_name] = ACI + assets[asset_name] = register_asset(asset_name, assets[asset_name]) /datum/asset/simple/send(client) - . = SSassets.transport.send_assets(client, assets) + . = send_asset_list(client, assets) /datum/asset/simple/get_url_mappings() . = list() for (var/asset_name in assets) - .[asset_name] = SSassets.transport.get_asset_url(asset_name, assets[asset_name]) + var/datum/asset_cache_item/ACI = assets[asset_name] + if (!ACI) + continue + .[asset_name] = ACI.url + // For registering or sending multiple others at once /datum/asset/group @@ -110,7 +54,7 @@ GLOBAL_LIST_EMPTY(asset_datums) /datum/asset/group/register() for(var/type in children) - load_asset_datum(type) + get_asset_datum(type) /datum/asset/group/send(client/C) for(var/type in children) @@ -134,122 +78,40 @@ GLOBAL_LIST_EMPTY(asset_datums) /datum/asset/spritesheet _abstract = /datum/asset/spritesheet - cross_round_cachable = TRUE var/name - /// List of arguments to pass into queuedInsert - /// Exists so we can queue icon insertion, mostly for stuff like preferences - var/list/to_generate = list() var/list/sizes = list() // "32x32" -> list(10, icon/normal, icon/stripped) var/list/sprites = list() // "foo_bar" -> list("32x32", 5) - var/list/cached_spritesheets_needed - var/generating_cache = FALSE - var/fully_generated = FALSE - /// If this asset should be fully loaded on new - /// Defaults to false so we can process this stuff nicely - var/load_immediately = FALSE - VAR_PRIVATE - // Kept in state so that the result is the same, even when the files are created, for this run - should_refresh = null - -/datum/asset/spritesheet/proc/should_load_immediately() -#ifdef DO_NOT_DEFER_ASSETS - return TRUE -#else - return load_immediately -#endif - - -/datum/asset/spritesheet/should_refresh() - if (..()) - return TRUE - - if (isnull(should_refresh)) - // `fexists` seems to always fail on static-time - should_refresh = !fexists(css_cache_filename()) || !fexists(data_cache_filename()) - - return should_refresh /datum/asset/spritesheet/register() - SHOULD_NOT_OVERRIDE(TRUE) - if (!name) CRASH("spritesheet [type] cannot register without a name") - - if (!should_refresh() && read_from_cache()) - fully_generated = TRUE - return - - // If it's cached, may as well load it now, while the loading is cheap - if(config.cache_assets && cross_round_cachable) - load_immediately = TRUE - - create_spritesheets() - if(should_load_immediately()) - realize_spritesheets(yield = FALSE) - else - SSasset_loading.queue_asset(src) - -/datum/asset/spritesheet/proc/realize_spritesheets(yield) - if(fully_generated) - return - while(length(to_generate)) - var/list/stored_args = to_generate[to_generate.len] - to_generate.len-- - queuedInsert(arglist(stored_args)) - if(yield && TICK_CHECK) - return - ensure_stripped() for(var/size_id in sizes) var/size = sizes[size_id] - SSassets.transport.register_asset("[name]_[size_id].png", size[SPRSZ_STRIPPED]) - var/css_name = "spritesheet_[name].css" - var/file_directory = "data/spritesheets/[css_name]" - fdel(file_directory) - text2file(generate_css(), file_directory) - SSassets.transport.register_asset(css_name, fcopy_rsc(file_directory)) + register_asset("[name]_[size_id].png", size[SPRSZ_STRIPPED]) + var/res_name = "spritesheet_[name].css" + var/fname = "data/spritesheets/[res_name]" + fdel(fname) + text2file(generate_css(), fname) + register_asset(res_name, fcopy_rsc(fname)) + fdel(fname) - if(config.save_spritesheets) - save_to_logs(file_name = css_name, file_location = file_directory) - - fdel(file_directory) - - if (config.cache_assets && cross_round_cachable) - write_to_cache() - fully_generated = TRUE - // If we were ever in there, remove ourselves - SSasset_loading.dequeue_asset(src) - -/datum/asset/spritesheet/queued_generation() - realize_spritesheets(yield = TRUE) - -/datum/asset/spritesheet/ensure_ready() - if(!fully_generated) - realize_spritesheets(yield = FALSE) - return ..() - -/datum/asset/spritesheet/send(client/client) +/datum/asset/spritesheet/send(client/C) if (!name) return - - if (!should_refresh()) - return send_from_cache(client) - var/all = list("spritesheet_[name].css") for(var/size_id in sizes) all += "[name]_[size_id].png" - . = SSassets.transport.send_assets(client, all) + . = send_asset_list(C, all) /datum/asset/spritesheet/get_url_mappings() if (!name) return - - if (!should_refresh()) - return get_cached_url_mappings() - - . = list("spritesheet_[name].css" = SSassets.transport.get_asset_url("spritesheet_[name].css")) + . = list("spritesheet_[name].css" = get_asset_url("spritesheet_[name].css")) for(var/size_id in sizes) - .["[name]_[size_id].png"] = SSassets.transport.get_asset_url("[name]_[size_id].png") + .["[name]_[size_id].png"] = get_asset_url("[name]_[size_id].png") + + /datum/asset/spritesheet/proc/ensure_stripped(sizes_to_strip = sizes) for(var/size_id in sizes_to_strip) @@ -258,19 +120,13 @@ GLOBAL_LIST_EMPTY(asset_datums) continue // save flattened version - var/png_name = "[name]_[size_id].png" - var/file_directory = "data/spritesheets/[png_name]" - fcopy(size[SPRSZ_ICON], file_directory) - var/error = rustg_dmi_strip_metadata(file_directory) + var/fname = "data/spritesheets/[name]_[size_id].png" + fcopy(size[SPRSZ_ICON], fname) + var/error = rustg_dmi_strip_metadata(fname) if(length(error)) - stack_trace("Failed to strip [png_name]: [error]") - size[SPRSZ_STRIPPED] = icon(file_directory) - - // this is useful here for determining if weird sprite issues (like having a white background) are a cause of what we're doing DM-side or not since we can see the full flattened thing at-a-glance. - if(config.save_spritesheets) - save_to_logs(file_name = png_name, file_location = file_directory) - - fdel(file_directory) + stack_trace("Failed to strip [name]_[size_id].png: [error]") + size[SPRSZ_STRIPPED] = icon(fname) + fdel(fname) /datum/asset/spritesheet/proc/generate_css() var/list/out = list() @@ -278,7 +134,7 @@ GLOBAL_LIST_EMPTY(asset_datums) for (var/size_id in sizes) var/size = sizes[size_id] var/icon/tiny = size[SPRSZ_ICON] - out += ".[name][size_id]{display:inline-block;width:[tiny.Width()]px;height:[tiny.Height()]px;background:url('[get_background_url("[name]_[size_id].png")]') no-repeat;}" + out += ".[name][size_id]{display:inline-block;width:[tiny.Width()]px;height:[tiny.Height()]px;background:url('[get_asset_url("[name]_[size_id].png")]') no-repeat;}" for (var/sprite_id in sprites) var/sprite = sprites[sprite_id] @@ -296,109 +152,10 @@ GLOBAL_LIST_EMPTY(asset_datums) return out.Join("\n") -/datum/asset/spritesheet/proc/css_cache_filename() - return "[ASSET_CROSS_ROUND_CACHE_DIRECTORY]/spritesheet.[name].css" - -/datum/asset/spritesheet/proc/data_cache_filename() - return "[ASSET_CROSS_ROUND_CACHE_DIRECTORY]/spritesheet.[name].json" - -/datum/asset/spritesheet/proc/read_from_cache() - return read_css_from_cache() && read_data_from_cache() - -/datum/asset/spritesheet/proc/read_css_from_cache() - var/replaced_css = file2text(css_cache_filename()) - - var/regex/find_background_urls = regex(@"background:url\('%(.+?)%'\)", "g") - while (find_background_urls.Find(replaced_css)) - var/asset_id = find_background_urls.group[1] - var/asset_cache_item = SSassets.transport.register_asset(asset_id, "[ASSET_CROSS_ROUND_CACHE_DIRECTORY]/spritesheet.[asset_id]") - var/asset_url = SSassets.transport.get_asset_url(asset_cache_item = asset_cache_item) - replaced_css = replacetext(replaced_css, find_background_urls.match, "background:url('[asset_url]')") - LAZYADD(cached_spritesheets_needed, asset_id) - - var/finalized_name = "spritesheet_[name].css" - var/replaced_css_filename = "data/spritesheets/[finalized_name]" - rustg_file_write(replaced_css, replaced_css_filename) - SSassets.transport.register_asset(finalized_name, replaced_css_filename) - - if(config.save_spritesheets) - save_to_logs(file_name = finalized_name, file_location = replaced_css_filename) - - fdel(replaced_css_filename) - - return TRUE - -/datum/asset/spritesheet/proc/read_data_from_cache() - var/json = json_decode(file2text(data_cache_filename())) - - if (islist(json["sprites"])) - sprites = json["sprites"] - - return TRUE - -/datum/asset/spritesheet/proc/send_from_cache(client/client) - if (isnull(cached_spritesheets_needed)) - stack_trace("cached_spritesheets_needed was null when sending assets from [type] from cache") - cached_spritesheets_needed = list() - - return SSassets.transport.send_assets(client, cached_spritesheets_needed + "spritesheet_[name].css") - -/// Returns the URL to put in the background:url of the CSS asset -/datum/asset/spritesheet/proc/get_background_url(asset) - if (generating_cache) - return "%[asset]%" - else - return SSassets.transport.get_asset_url(asset) - -/datum/asset/spritesheet/proc/write_to_cache() - write_css_to_cache() - write_data_to_cache() - -/datum/asset/spritesheet/proc/write_css_to_cache() - for (var/size_id in sizes) - fcopy(SSassets.cache["[name]_[size_id].png"].resource, "[ASSET_CROSS_ROUND_CACHE_DIRECTORY]/spritesheet.[name]_[size_id].png") - - generating_cache = TRUE - var/mock_css = generate_css() - generating_cache = FALSE - - rustg_file_write(mock_css, css_cache_filename()) - -/datum/asset/spritesheet/proc/write_data_to_cache() - rustg_file_write(json_encode(list( - "sprites" = sprites, - )), data_cache_filename()) - -/datum/asset/spritesheet/proc/get_cached_url_mappings() - var/list/mappings = list() - mappings["spritesheet_[name].css"] = SSassets.transport.get_asset_url("spritesheet_[name].css") - - for (var/asset_name in cached_spritesheets_needed) - mappings[asset_name] = SSassets.transport.get_asset_url(asset_name) - - return mappings - -/// Override this in order to start the creation of the spritehseet. -/// This is where all your Insert, InsertAll, etc calls should be inside. -/datum/asset/spritesheet/proc/create_spritesheets() - SHOULD_CALL_PARENT(FALSE) - CRASH("create_spritesheets() not implemented for [type]!") - /datum/asset/spritesheet/proc/Insert(sprite_name, icon/I, icon_state="", dir=SOUTH, frame=1, moving=FALSE) - if(should_load_immediately()) - queuedInsert(sprite_name, I, icon_state, dir, frame, moving) - else - to_generate += list(args.Copy()) - -/datum/asset/spritesheet/proc/queuedInsert(sprite_name, icon/I, icon_state="", dir=SOUTH, frame=1, moving=FALSE) I = icon(I, icon_state=icon_state, dir=dir, frame=frame, moving=moving) if (!I || !length(icon_states(I))) // that direction or state doesn't exist return - - //var/start_usage = world.tick_usage - - //any sprite modifications we want to do (aka, coloring a greyscaled asset) - I = ModifyInserted(I) var/size_id = "[I.Width()]x[I.Height()]" var/size = sizes[size_id] @@ -407,34 +164,14 @@ GLOBAL_LIST_EMPTY(asset_datums) if (size) var/position = size[SPRSZ_COUNT]++ - // Icons are essentially representations of files + modifications - // Because of this, byond keeps them in a cache. It does this in a really dumb way tho - // It's essentially a FIFO queue. So after we do icon() some amount of times, our old icons go out of cache - // When this happens it becomes impossible to modify them, trying to do so will instead throw a - // "bad icon" error. - // What we're doing here is ensuring our icon is in the cache by refreshing it, so we can modify it w/o runtimes. var/icon/sheet = size[SPRSZ_ICON] - var/icon/sheet_copy = icon(sheet) size[SPRSZ_STRIPPED] = null - sheet_copy.Insert(I, icon_state=sprite_name) - size[SPRSZ_ICON] = sheet_copy - + sheet.Insert(I, icon_state=sprite_name) sprites[sprite_name] = list(size_id, position) else sizes[size_id] = size = list(1, I, null) sprites[sprite_name] = list(size_id, 0) - //SSblackbox.record_feedback("tally", "spritesheet_queued_insert_time", TICK_USAGE_TO_MS(start_usage), name) - -/** - * A simple proc handing the Icon for you to modify before it gets turned into an asset. - * - * Arguments: - * * I: icon being turned into an asset - */ -/datum/asset/spritesheet/proc/ModifyInserted(icon/pre_asset) - return pre_asset - /datum/asset/spritesheet/proc/InsertAll(prefix, icon/I, list/directions) if (length(prefix)) prefix = "[prefix]-" @@ -451,14 +188,14 @@ GLOBAL_LIST_EMPTY(asset_datums) return {""} /datum/asset/spritesheet/proc/css_filename() - return SSassets.transport.get_asset_url("spritesheet_[name].css") + return get_asset_url("spritesheet_[name].css") /datum/asset/spritesheet/proc/icon_tag(sprite_name) var/sprite = sprites[sprite_name] if (!sprite) return null var/size_id = sprite[SPR_SIZE] - return {""} + return {""} /datum/asset/spritesheet/proc/icon_class_name(sprite_name) var/sprite = sprites[sprite_name] @@ -467,19 +204,6 @@ GLOBAL_LIST_EMPTY(asset_datums) var/size_id = sprite[SPR_SIZE] return {"[name][size_id] [sprite_name]"} -/** - * Returns the size class (ex design32x32) for a given sprite's icon - * - * Arguments: - * * sprite_name - The sprite to get the size of - */ -/datum/asset/spritesheet/proc/icon_size_id(sprite_name) - var/sprite = sprites[sprite_name] - if (!sprite) - return null - var/size_id = sprite[SPR_SIZE] - return "[name][size_id]" - #undef SPR_SIZE #undef SPR_IDX #undef SPRSZ_COUNT @@ -487,31 +211,14 @@ GLOBAL_LIST_EMPTY(asset_datums) #undef SPRSZ_STRIPPED -/datum/asset/changelog_item - _abstract = /datum/asset/changelog_item - var/item_filename - -/datum/asset/changelog_item/New(date) - item_filename = sanitize_filename("[date].yml") - SSassets.transport.register_asset(item_filename, file("html/changelogs_ch/archive/" + item_filename)) - -/datum/asset/changelog_item/send(client) - if (!item_filename) - return - . = SSassets.transport.send_assets(client, item_filename) - -/datum/asset/changelog_item/get_url_mappings() - if (!item_filename) - return - . = list("[item_filename]" = SSassets.transport.get_asset_url(item_filename)) - /datum/asset/spritesheet/simple _abstract = /datum/asset/spritesheet/simple var/list/assets -/datum/asset/spritesheet/simple/create_spritesheets() +/datum/asset/spritesheet/simple/register() for (var/key in assets) Insert(key, assets[key]) + ..() //Generates assets based on iconstates of a single icon /datum/asset/simple/icon_states @@ -536,7 +243,7 @@ GLOBAL_LIST_EMPTY(asset_datums) if (generic_icon_names) asset_name = "[generate_asset_name(asset)].png" - SSassets.transport.register_asset(asset_name, asset) + register_asset(asset_name, asset) /datum/asset/simple/icon_states/multiple_icons _abstract = /datum/asset/simple/icon_states/multiple_icons @@ -546,79 +253,4 @@ GLOBAL_LIST_EMPTY(asset_datums) for(var/i in icons) ..(i) -/// Namespace'ed assets (for static css and html files) -/// When sent over a cdn transport, all assets in the same asset datum will exist in the same folder, as their plain names. -/// Used to ensure css files can reference files by url() without having to generate the css at runtime, both the css file and the files it depends on must exist in the same namespace asset datum. (Also works for html) -/// For example `blah.css` with asset `blah.png` will get loaded as `namespaces/a3d..14f/f12..d3c.css` and `namespaces/a3d..14f/blah.png`. allowing the css file to load `blah.png` by a relative url rather then compute the generated url with get_url_mappings(). -/// The namespace folder's name will change if any of the assets change. (excluding parent assets) -/datum/asset/simple/namespaced - _abstract = /datum/asset/simple/namespaced - /// parents - list of the parent asset or assets (in name = file assoicated format) for this namespace. - /// parent assets must be referenced by their generated url, but if an update changes a parent asset, it won't change the namespace's identity. - var/list/parents = list() -/datum/asset/simple/namespaced/register() - if (legacy) - assets |= parents - var/list/hashlist = list() - var/list/sorted_assets = sortList(assets) - - for (var/asset_name in sorted_assets) - var/datum/asset_cache_item/ACI = new(asset_name, sorted_assets[asset_name]) - if (!ACI?.hash) - log_asset("ERROR: Invalid asset: [type]:[asset_name]:[ACI]") - continue - hashlist += ACI.hash - sorted_assets[asset_name] = ACI - var/namespace = md5(hashlist.Join()) - - for (var/asset_name in parents) - var/datum/asset_cache_item/ACI = new(asset_name, parents[asset_name]) - if (!ACI?.hash) - log_asset("ERROR: Invalid asset: [type]:[asset_name]:[ACI]") - continue - ACI.namespace_parent = TRUE - sorted_assets[asset_name] = ACI - - for (var/asset_name in sorted_assets) - var/datum/asset_cache_item/ACI = sorted_assets[asset_name] - if (!ACI?.hash) - log_asset("ERROR: Invalid asset: [type]:[asset_name]:[ACI]") - continue - ACI.namespace = namespace - - assets = sorted_assets - ..() - -/// Get a html string that will load a html asset. -/// Needed because byond doesn't allow you to browse() to a url. -/datum/asset/simple/namespaced/proc/get_htmlloader(filename) - return url2htmlloader(SSassets.transport.get_asset_url(filename, assets[filename])) - -/// A subtype to generate a JSON file from a list -/datum/asset/json - _abstract = /datum/asset/json - /// The filename, will be suffixed with ".json" - var/name - -/datum/asset/json/send(client) - return SSassets.transport.send_assets(client, "[name].json") - -/datum/asset/json/get_url_mappings() - return list( - "[name].json" = SSassets.transport.get_asset_url("[name].json"), - ) - -/datum/asset/json/register() - var/filename = "data/[name].json" - fdel(filename) - text2file(json_encode(generate()), filename) - SSassets.transport.register_asset("[name].json", fcopy_rsc(filename)) - fdel(filename) - -/// Returns the data that will be JSON encoded -/datum/asset/json/proc/generate() - SHOULD_CALL_PARENT(FALSE) - CRASH("generate() not implemented for [type]!") - -#undef ASSET_CROSS_ROUND_CACHE_DIRECTORY diff --git a/code/modules/asset_cache/asset_list_items.dm b/code/modules/asset_cache/asset_list_items.dm index de961a96afa..71cd0286aae 100644 --- a/code/modules/asset_cache/asset_list_items.dm +++ b/code/modules/asset_cache/asset_list_items.dm @@ -258,26 +258,29 @@ /datum/asset/spritesheet/pipes name = "pipes" -/datum/asset/spritesheet/pipes/create_spritesheets() +/datum/asset/spritesheet/pipes/register() for(var/each in list('icons/obj/pipe-item.dmi', 'icons/obj/pipes/disposal.dmi')) InsertAll("", each, global.alldirs) + ..() //VOREStation Add /datum/asset/spritesheet/vore name = "vore" -/datum/asset/spritesheet/vore/create_spritesheets() +/datum/asset/spritesheet/vore/register() var/icon/downscaled = icon('icons/mob/screen_full_vore.dmi') downscaled.Scale(240, 240) InsertAll("", downscaled) + ..() /datum/asset/spritesheet/vore_colorized //This should be getting loaded in the TGUI vore panel but the game refuses to do so, for some reason. It only loads the vore spritesheet. name = "colorizedvore" -/datum/asset/spritesheet/vore_colorized/create_spritesheets() +/datum/asset/spritesheet/vore_colorized/register() var/icon/downscaledVC = icon('icons/mob/screen_full_colorized_vore.dmi') downscaledVC.Scale(240, 240) InsertAll("", downscaledVC) + ..() //VOREStation Add End @@ -343,7 +346,7 @@ /datum/asset/spritesheet/vending name = "vending" -/datum/asset/spritesheet/vending/create_spritesheets() +/datum/asset/spritesheet/vending/register() populate_vending_products() for(var/atom/item as anything in GLOB.vending_products) if(!ispath(item, /atom)) @@ -381,6 +384,7 @@ var/imgid = replacetext(replacetext("[item]", "/obj/item/", ""), "/", "-") Insert(imgid, I) + return ..() // this is cursed but necessary or else vending product icons can be missing // basically, if there's any vending machines that aren't already mapped in, our register() will not know @@ -438,10 +442,10 @@ assets["bottle-[i].png"] = icon('icons/obj/chemical.dmi', "bottle-[i]") for(var/asset_name in assets) - SSassets.transport.register_asset(asset_name, assets[asset_name]) + register_asset(asset_name, assets[asset_name]) /datum/asset/chem_master/send(client) - SSassets.transport.send_assets(client, assets, verify) + send_asset_list(client, assets, verify) //Cloning pod sprites for UIs /datum/asset/cloning @@ -453,10 +457,10 @@ assets["pod_cloning.gif"] = icon('icons/obj/cloning.dmi', "pod_cloning") assets["pod_mess.gif"] = icon('icons/obj/cloning.dmi', "pod_mess") for(var/asset_name in assets) - SSassets.transport.register_asset(asset_name, assets[asset_name]) + register_asset(asset_name, assets[asset_name]) /datum/asset/cloning/send(client) - SSassets.transport.send_assets(client, assets, verify) + send_asset_list(client, assets, verify) // VOREStation Add /datum/asset/cloning/resleeving @@ -467,14 +471,15 @@ assets["synthprinter.gif"] = icon('icons/obj/machines/synthpod.dmi', "pod_0") assets["synthprinter_working.gif"] = icon('icons/obj/machines/synthpod.dmi', "pod_1") for(var/asset_name in assets) - SSassets.transport.register_asset(asset_name, assets[asset_name]) + register_asset(asset_name, assets[asset_name]) // VOREStation Add End /datum/asset/spritesheet/sheetmaterials name = "sheetmaterials" -/datum/asset/spritesheet/sheetmaterials/create_spritesheets() +/datum/asset/spritesheet/sheetmaterials/register() InsertAll("", 'icons/obj/stacks.dmi') + ..() // Nanomaps /datum/asset/simple/nanomaps diff --git a/code/modules/asset_cache/assets/chat.dm b/code/modules/asset_cache/assets/chat.dm index 0853ea542c7..328beaca9d0 100644 --- a/code/modules/asset_cache/assets/chat.dm +++ b/code/modules/asset_cache/assets/chat.dm @@ -1,6 +1,2 @@ /datum/asset/spritesheet/chat name = "chat" - -/datum/asset/spritesheet/chat/create_spritesheets() - //honk - //This function has to be overridden otherwise it will generate runtimes diff --git a/code/modules/asset_cache/assets/fontawesome.dm b/code/modules/asset_cache/assets/fontawesome.dm index 6f5441ab42d..72af739f4e1 100644 --- a/code/modules/asset_cache/assets/fontawesome.dm +++ b/code/modules/asset_cache/assets/fontawesome.dm @@ -1,8 +1,9 @@ -/datum/asset/simple/namespaced/fontawesome +/datum/asset/simple/fontawesome assets = list( - "fa-regular-400.ttf" = 'html/font-awesome/webfonts/fa-regular-400.ttf', - "fa-solid-900.ttf" = 'html/font-awesome/webfonts/fa-solid-900.ttf', - "fa-v4compatibility.ttf" = 'html/font-awesome/webfonts/fa-v4compatibility.ttf', - "v4shim.css" = 'html/font-awesome/css/v4-shims.min.css', + "fa-regular-400.eot" = 'html/font-awesome/webfonts/fa-regular-400.eot', + "fa-regular-400.woff" = 'html/font-awesome/webfonts/fa-regular-400.woff', + "fa-solid-900.eot" = 'html/font-awesome/webfonts/fa-solid-900.eot', + "fa-solid-900.woff" = 'html/font-awesome/webfonts/fa-solid-900.woff', + "font-awesome.css" = 'html/font-awesome/css/all.min.css', + "v4shim.css" = 'html/font-awesome/css/v4-shims.min.css' ) - parents = list("font-awesome.css" = 'html/font-awesome/css/all.min.css') diff --git a/code/modules/asset_cache/assets/jquery.dm b/code/modules/asset_cache/assets/jquery.dm index b7241fdb61d..2a28293fbb3 100644 --- a/code/modules/asset_cache/assets/jquery.dm +++ b/code/modules/asset_cache/assets/jquery.dm @@ -1,5 +1,4 @@ /datum/asset/simple/jquery - legacy = TRUE assets = list( - "jquery.min.js" = 'html/jquery/jquery.min.js', + "jquery.min.js" = 'code/modules/tooltip/jquery.min.js', ) diff --git a/code/modules/asset_cache/assets/tgfont.dm b/code/modules/asset_cache/assets/tgfont.dm index 1d9df4282c8..48db3e4e676 100644 --- a/code/modules/asset_cache/assets/tgfont.dm +++ b/code/modules/asset_cache/assets/tgfont.dm @@ -1,8 +1,6 @@ -/datum/asset/simple/namespaced/tgfont +/datum/asset/simple/tgfont assets = list( "tgfont.eot" = file("tgui/packages/tgfont/dist/tgfont.eot"), "tgfont.woff2" = file("tgui/packages/tgfont/dist/tgfont.woff2"), - ) - parents = list( "tgfont.css" = file("tgui/packages/tgfont/dist/tgfont.css"), ) diff --git a/code/modules/asset_cache/readme.md b/code/modules/asset_cache/readme.md deleted file mode 100644 index 82e6bea896c..00000000000 --- a/code/modules/asset_cache/readme.md +++ /dev/null @@ -1,37 +0,0 @@ -# Asset cache system - -## Framework for managing browser assets (javascript,css,images,etc) - -This manages getting the asset to the client without doing unneeded re-sends, as well as utilizing any configured cdns. - -There are two frameworks for using this system: - -### Asset datum: - -Make a datum in asset_list_items.dm with your browser assets for your thing. - -Checkout asset_list.dm for the helper subclasses - -The `simple` subclass will most likely be of use for most cases. - -Call get_asset_datum() with the type of the datum you created to get your asset cache datum - -Call .send(client|usr) on that datum to send the asset to the client. Depending on the asset transport this may or may not block. - -Call .get_url_mappings() to get an associated list with the urls your assets can be found at. - -### Manual backend: - -See the documentation for `/datum/asset_transport` for the backend api the asset datums utilize. - -The global variable `SSassets.transport` contains the currently configured transport. - - - -### Notes: - -Because byond browse() calls use non-blocking queues, if your code uses output() (which bypasses all of these queues) to invoke javascript functions you will need to first have the javascript announce to the server it has loaded before trying to invoke js functions. - -To make your code work with any CDNs configured by the server, you must make sure assets are referenced from the url returned by `get_url_mappings()` or by asset_transport's `get_asset_url()`. (TGUI also has helpers for this.) If this can not be easily done, you can bypass the cdn using legacy assets, see the simple asset datum for details. - -CSS files that use url() can be made to use the CDN without needing to rewrite all url() calls in code by using the namespaced helper datum. See the documentation for `/datum/asset/simple/namespaced` for details. diff --git a/code/modules/asset_cache/transports/asset_transport.dm b/code/modules/asset_cache/transports/asset_transport.dm deleted file mode 100644 index 5be975a385e..00000000000 --- a/code/modules/asset_cache/transports/asset_transport.dm +++ /dev/null @@ -1,162 +0,0 @@ -/// When sending mutiple assets, how many before we give the client a quaint little sending resources message -#define ASSET_CACHE_TELL_CLIENT_AMOUNT 8 - -/// Base browse_rsc asset transport -/datum/asset_transport - var/name = "Simple browse_rsc asset transport" - var/static/list/preload - /// Don't mutate the filename of assets when sending via browse_rsc. - /// This is to make it easier to debug issues with assets, and allow server operators to bypass issues that make it to production. - /// If turning this on fixes asset issues, something isn't using get_asset_url and the asset isn't marked legacy, fix one of those. - var/dont_mutate_filenames = FALSE - -/// Called when the transport is loaded by the config controller, not called on the default transport unless it gets loaded by a config change. -/datum/asset_transport/proc/Load() - if (config.asset_simple_preload) - for(var/client/C in GLOB.clients) - addtimer(CALLBACK(src, PROC_REF(send_assets_slow), C, preload), 1 SECONDS) - -/// Initialize - Called when SSassets initializes. -/datum/asset_transport/proc/Initialize(list/assets) - preload = assets.Copy() - if (!config.asset_simple_preload) - return - for(var/client/C in GLOB.clients) - addtimer(CALLBACK(src, PROC_REF(send_assets_slow), C, preload), 1 SECONDS) - - -/** - * Register a browser asset with the asset cache system. - * returns a /datum/asset_cache_item. - * mutiple calls to register the same asset under the same asset_name return the same datum. - * - * Arguments: - * * asset_name - the identifier of the asset. - * * asset - the actual asset file (or an asset_cache_item datum). - * * file_hash - optional, a hash of the contents of the asset files contents. used so asset_cache_item doesnt have to hash it again - * * dmi_file_path - optional, means that the given asset is from the rsc and thus we dont need to do some expensive operations - */ -/datum/asset_transport/proc/register_asset(asset_name, asset, file_hash, dmi_file_path) - var/datum/asset_cache_item/ACI = asset - if (!istype(ACI)) - ACI = new(asset_name, asset, file_hash, dmi_file_path) - if (!ACI || !ACI.hash) - CRASH("ERROR: Invalid asset: [asset_name]:[asset]:[ACI]") - if (SSassets.cache[asset_name]) - var/datum/asset_cache_item/OACI = SSassets.cache[asset_name] - OACI.legacy = ACI.legacy = (ACI.legacy|OACI.legacy) - OACI.namespace_parent = ACI.namespace_parent = (ACI.namespace_parent | OACI.namespace_parent) - OACI.namespace = OACI.namespace || ACI.namespace - if (OACI.hash != ACI.hash) - var/error_msg = "ERROR: new asset added to the asset cache with the same name as another asset: [asset_name] existing asset hash: [OACI.hash] new asset hash:[ACI.hash]" - stack_trace(error_msg) - log_asset(error_msg) - else - if (length(ACI.namespace)) - return ACI - return OACI - - SSassets.cache[asset_name] = ACI - return ACI - - -/// Returns a url for a given asset. -/// asset_name - Name of the asset. -/// asset_cache_item - asset cache item datum for the asset, optional, overrides asset_name -/datum/asset_transport/proc/get_asset_url(asset_name, datum/asset_cache_item/asset_cache_item) - if (!istype(asset_cache_item)) - asset_cache_item = SSassets.cache[asset_name] - // To ensure code that breaks on cdns breaks in local testing, we only - // use the normal filename on legacy assets and name space assets. - var/keep_local_name = dont_mutate_filenames \ - || asset_cache_item.legacy \ - || asset_cache_item.keep_local_name \ - || (asset_cache_item.namespace && !asset_cache_item.namespace_parent) - if (keep_local_name) - return url_encode(asset_cache_item.name) - return url_encode("asset.[asset_cache_item.hash][asset_cache_item.ext]") - - -/// Sends a list of browser assets to a client -/// client - a client or mob -/// asset_list - A list of asset filenames to be sent to the client. Can optionally be assoicated with the asset's asset_cache_item datum. -/// Returns TRUE if any assets were sent. -/datum/asset_transport/proc/send_assets(client/client, list/asset_list) - if (!istype(client)) - if (ismob(client)) - var/mob/M = client - if (M.client) - client = M.client - else //no stacktrace because this will mainly happen because the client went away - return - else - CRASH("Invalid argument: client: `[client]`") - if (!islist(asset_list)) - asset_list = list(asset_list) - var/list/unreceived = list() - - for (var/asset_name in asset_list) - var/datum/asset_cache_item/ACI = asset_list[asset_name] - if (!istype(ACI) && !(ACI = SSassets.cache[asset_name])) - log_asset("ERROR: can't send asset `[asset_name]`: unregistered or invalid state: `[ACI]`") - continue - var/asset_file = ACI.resource - if (!asset_file) - log_asset("ERROR: can't send asset `[asset_name]`: invalid registered resource: `[ACI.resource]`") - continue - - var/asset_hash = ACI.hash - var/new_asset_name = asset_name - var/keep_local_name = dont_mutate_filenames \ - || ACI.legacy \ - || ACI.keep_local_name \ - || (ACI.namespace && !ACI.namespace_parent) - if (!keep_local_name) - new_asset_name = "asset.[ACI.hash][ACI.ext]" - if (client.sent_assets[new_asset_name] == asset_hash) - /*if (GLOB.Debug2) - log_asset("DEBUG: Skipping send of `[asset_name]` (as `[new_asset_name]`) for `[client]` because it already exists in the client's sent_assets list")*/ - continue - unreceived[asset_name] = ACI - - if (unreceived.len) - if (unreceived.len >= ASSET_CACHE_TELL_CLIENT_AMOUNT) - to_chat(client, "Sending Resources...") - - for (var/asset_name in unreceived) - var/new_asset_name = asset_name - var/datum/asset_cache_item/ACI = unreceived[asset_name] - var/keep_local_name = dont_mutate_filenames \ - || ACI.legacy \ - || ACI.keep_local_name \ - || (ACI.namespace && !ACI.namespace_parent) - if (!keep_local_name) - new_asset_name = "asset.[ACI.hash][ACI.ext]" - log_asset("Sending asset `[asset_name]` to client `[client]` as `[new_asset_name]`") - client << browse_rsc(ACI.resource, new_asset_name) - - client.sent_assets[new_asset_name] = ACI.hash - - addtimer(CALLBACK(client, TYPE_PROC_REF(/client, asset_cache_update_json)), 1 SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE) - return TRUE - return FALSE - - -/// Precache files without clogging up the browse() queue, used for passively sending files on connection start. -/datum/asset_transport/proc/send_assets_slow(client/client, list/files, filerate = 6) - var/startingfilerate = filerate - for (var/file in files) - if (!client) - break - if (send_assets(client, file)) - if (!(--filerate)) - filerate = startingfilerate - client.browse_queue_flush() - stoplag(0) //queuing calls like this too quickly can cause issues in some client versions - -/// Check the config is valid to load this transport -/// Returns TRUE or FALSE -/datum/asset_transport/proc/validate_config(log = TRUE) - return TRUE - -#undef ASSET_CACHE_TELL_CLIENT_AMOUNT diff --git a/code/modules/asset_cache/transports/webroot_transport.dm b/code/modules/asset_cache/transports/webroot_transport.dm deleted file mode 100644 index 9ee8768efd4..00000000000 --- a/code/modules/asset_cache/transports/webroot_transport.dm +++ /dev/null @@ -1,87 +0,0 @@ -/// CDN Webroot asset transport. -/datum/asset_transport/webroot - name = "CDN Webroot asset transport" - -/datum/asset_transport/webroot/Load() - if (validate_config(log = FALSE)) - load_existing_assets() - -/// Processes thru any assets that were registered before we were loaded as a transport. -/datum/asset_transport/webroot/proc/load_existing_assets() - for (var/asset_name in SSassets.cache) - var/datum/asset_cache_item/ACI = SSassets.cache[asset_name] - save_asset_to_webroot(ACI) - -/// Register a browser asset with the asset cache system -/// We also save it to the CDN webroot at this step instead of waiting for send_assets() -/// asset_name - the identifier of the asset -/// asset - the actual asset file or an asset_cache_item datum. -/datum/asset_transport/webroot/register_asset(asset_name, asset) - . = ..() - var/datum/asset_cache_item/ACI = . - - if (istype(ACI) && ACI.hash) - save_asset_to_webroot(ACI) - -/// Saves the asset to the webroot taking into account namespaces and hashes. -/datum/asset_transport/webroot/proc/save_asset_to_webroot(datum/asset_cache_item/ACI) - var/webroot = config.asset_cdn_webroot - var/newpath = "[webroot][get_asset_suffex(ACI)]" - if (fexists(newpath)) - return - if (fexists("[newpath].gz")) //its a common pattern in webhosting to save gzip'ed versions of text files and let the webserver serve them up as gzip compressed normal files, sometimes without keeping the original version. - return - return fcopy(ACI.resource, newpath) - -/// Returns a url for a given asset. -/// asset_name - Name of the asset. -/// asset_cache_item - asset cache item datum for the asset, optional, overrides asset_name -/datum/asset_transport/webroot/get_asset_url(asset_name, datum/asset_cache_item/asset_cache_item) - if (!istype(asset_cache_item)) - asset_cache_item = SSassets.cache[asset_name] - var/url = config.asset_cdn_url //config loading will handle making sure this ends in a / - return "[url][get_asset_suffex(asset_cache_item)]" - -/datum/asset_transport/webroot/proc/get_asset_suffex(datum/asset_cache_item/asset_cache_item) - var/base = "[copytext(asset_cache_item.hash, 1, 3)]/" - var/filename = "asset.[asset_cache_item.hash][asset_cache_item.ext]" - if (length(asset_cache_item.namespace)) - base = "namespaces/[copytext(asset_cache_item.namespace, 1, 3)]/[asset_cache_item.namespace]/" - if (!asset_cache_item.namespace_parent) - filename = "[asset_cache_item.name]" - return base + filename - - -/// webroot asset sending - does nothing unless passed legacy assets -/datum/asset_transport/webroot/send_assets(client/client, list/asset_list) - . = FALSE - var/list/legacy_assets = list() - if (!islist(asset_list)) - asset_list = list(asset_list) - for (var/asset_name in asset_list) - var/datum/asset_cache_item/ACI = asset_list[asset_name] - if (!istype(ACI)) - ACI = SSassets.cache[asset_name] - if (!ACI) - legacy_assets += asset_name //pass it on to base send_assets so it can output an error - continue - if (ACI.legacy) - legacy_assets[asset_name] = ACI - if (length(legacy_assets)) - . = ..(client, legacy_assets) - - -/// webroot slow asset sending - does nothing. -/datum/asset_transport/webroot/send_assets_slow(client/client, list/files, filerate) - return FALSE - -/datum/asset_transport/webroot/validate_config(log = TRUE) - if (!config.asset_cdn_url) - if (log) - log_asset("ERROR: [type]: Invalid Config: ASSET_CDN_URL") - return FALSE - if (!config.asset_cdn_webroot) - if (log) - log_asset("ERROR: [type]: Invalid Config: ASSET_CDN_WEBROOT") - return FALSE - return TRUE diff --git a/code/modules/asset_cache/validate_assets.html b/code/modules/asset_cache/validate_assets.html index 78bcbb92a1a..b27a266c00d 100644 --- a/code/modules/asset_cache/validate_assets.html +++ b/code/modules/asset_cache/validate_assets.html @@ -26,4 +26,4 @@ - + \ No newline at end of file diff --git a/code/modules/blob2/core_chunk.dm b/code/modules/blob2/core_chunk.dm index b499f6dc675..15db91e89ec 100644 --- a/code/modules/blob2/core_chunk.dm +++ b/code/modules/blob2/core_chunk.dm @@ -86,7 +86,7 @@ /obj/item/weapon/blobcore_chunk/attack_self(var/mob/user) if(blob_type && world.time > active_ability_cooldown + last_active_use) last_active_use = world.time - to_chat(user, "[icon2html(src, user.client)] \The [src] gesticulates.") + to_chat(user, "\icon [src] \The [src] gesticulates.") blob_type.on_chunk_use(src, user) else to_chat(user, "\The [src] doesn't seem to respond.") diff --git a/code/modules/blob2/overmind/types/ectoplasmic_horror.dm b/code/modules/blob2/overmind/types/ectoplasmic_horror.dm index d453c87ac90..a528ce83889 100644 --- a/code/modules/blob2/overmind/types/ectoplasmic_horror.dm +++ b/code/modules/blob2/overmind/types/ectoplasmic_horror.dm @@ -94,7 +94,7 @@ break if(!beamtarget_exists && GetAnomalySusceptibility(L) >= 0.5) - carrier.visible_message("[icon2html(B,viewers(carrier))] \The [B] lashes out at \the [L]!") + carrier.visible_message("\icon [B] \The [B] lashes out at \the [L]!") var/datum/beam/drain_beam = carrier.Beam(L, icon_state = "drain_life", time = 10 SECONDS) active_beams |= drain_beam spawn(9 SECONDS) diff --git a/code/modules/blob2/overmind/types/ravenous_macrophage.dm b/code/modules/blob2/overmind/types/ravenous_macrophage.dm index a97eb2df716..b6b3b65a4f0 100644 --- a/code/modules/blob2/overmind/types/ravenous_macrophage.dm +++ b/code/modules/blob2/overmind/types/ravenous_macrophage.dm @@ -41,10 +41,10 @@ /datum/blob_type/ravenous_macrophage/on_chunk_tick(obj/item/weapon/blobcore_chunk/B) var/mob/living/L = locate() in range(world.view, B) if(prob(5) && !L.stat) // There's some active living thing nearby, produce offgas. - B.visible_message("[icon2html(B,viewers(B))] \The [B] disgorches a cloud of noxious gas!") + B.visible_message("\icon [B] \The [B] disgorches a cloud of noxious gas!") var/turf/T = get_turf(B) var/datum/effect/effect/system/smoke_spread/noxious/BS = new /datum/effect/effect/system/smoke_spread/noxious BS.attach(T) BS.set_up(3, 0, T) playsound(T, 'sound/effects/smoke.ogg', 50, 1, -3) - BS.start() + BS.start() \ No newline at end of file diff --git a/code/modules/blob2/overmind/types/reactive_spines.dm b/code/modules/blob2/overmind/types/reactive_spines.dm index f52d4e38128..0d0021f2439 100644 --- a/code/modules/blob2/overmind/types/reactive_spines.dm +++ b/code/modules/blob2/overmind/types/reactive_spines.dm @@ -55,11 +55,5 @@ return /datum/blob_type/reactive_spines/chunk_setup(obj/item/weapon/blobcore_chunk/B) - B.RegisterSignal(SSmobs, COMSIG_OBSERVER_GLOBALMOVED, /obj/item/weapon/blobcore_chunk/proc/call_chunk_unique) - return - -//I'm putting this here so everybody knows that it's this shitty code that is why that comsig exists. -//I'm just reimplementing the way it worked before but with comsigs. I don't have the patience to refactor this. -/mob/living/Moved() - . = ..() - SEND_SIGNAL(SSmobs, COMSIG_OBSERVER_GLOBALMOVED) + GLOB.moved_event.register_global(B, /obj/item/weapon/blobcore_chunk/proc/call_chunk_unique) + return \ No newline at end of file diff --git a/code/modules/blob2/overmind/types/roiling_mold.dm b/code/modules/blob2/overmind/types/roiling_mold.dm index 8a2534ebb54..4594ad1c9f6 100644 --- a/code/modules/blob2/overmind/types/roiling_mold.dm +++ b/code/modules/blob2/overmind/types/roiling_mold.dm @@ -28,7 +28,7 @@ return var/mob/living/L = locate() in (view(world.view + 3, get_turf(B)) - view(2,get_turf(B)) - previous_targets) // No adjacent mobs. - if(!(L in check_trajectory(L, B, PASSTABLE))) + if(!check_trajectory(L, B, PASSTABLE)) if(!LAZYLEN(previous_targets)) previous_targets = list() @@ -53,12 +53,12 @@ if(istype(user) && user == L) continue - if(!(L in check_trajectory(L, B, PASSTABLE))) // Can't fire at things on the other side of walls / windows. + if(!check_trajectory(L, B, PASSTABLE)) // Can't fire at things on the other side of walls / windows. continue var/obj/item/projectile/P = new spore_projectile(get_turf(B)) - user.visible_message("[icon2html(B,viewers(user))] \The [B] discharges energy toward \the [L]!") + user.visible_message("\icon [B] \The [B] discharges energy toward \the [L]!") P.launch_projectile(L, BP_TORSO, user) - return + return \ No newline at end of file diff --git a/code/modules/blob2/overmind/types/synchronous_mesh.dm b/code/modules/blob2/overmind/types/synchronous_mesh.dm index 1e32ebb40f6..acf9441b71a 100644 --- a/code/modules/blob2/overmind/types/synchronous_mesh.dm +++ b/code/modules/blob2/overmind/types/synchronous_mesh.dm @@ -68,5 +68,5 @@ carrier.adjustFireLoss(-3 / nearby_mobs.len) if(need_beam) - carrier.visible_message("[icon2html(B,viewers(carrier))] \The [B] sends noxious spores toward \the [victim]!") - carrier.Beam(victim, icon_state = "lichbeam", time = 2 SECONDS) + carrier.visible_message("\icon [B] \The [B] sends noxious spores toward \the [victim]!") + carrier.Beam(victim, icon_state = "lichbeam", time = 2 SECONDS) \ No newline at end of file diff --git a/code/modules/casino/casino_prize_vendor.dm b/code/modules/casino/casino_prize_vendor.dm index df7bebcefcf..18ffd62b7d1 100644 --- a/code/modules/casino/casino_prize_vendor.dm +++ b/code/modules/casino/casino_prize_vendor.dm @@ -211,7 +211,7 @@ /obj/machinery/casino_prize_dispenser/proc/pay_with_chips(var/obj/item/weapon/spacecasinocash/cashmoney, mob/user, var/price) //"cashmoney_:[cashmoney] user:[user] currently_vending:[currently_vending]" if(price > cashmoney.worth) - to_chat(usr, "[icon2html(cashmoney, user.client)] That is not enough chips.") + to_chat(usr, "\icon[cashmoney] That is not enough chips.") return 0 if(istype(cashmoney, /obj/item/weapon/spacecasinocash)) diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm index f3b7c76106c..122ef0bb45d 100644 --- a/code/modules/client/client procs.dm +++ b/code/modules/client/client procs.dm @@ -459,8 +459,7 @@ src << browse('code/modules/asset_cache/validate_assets.html', "window=asset_cache_browser") //Precache the client with all other assets slowly, so as to not block other browse() calls - if (config.asset_simple_preload) - addtimer(CALLBACK(SSassets.transport, TYPE_PROC_REF(/datum/asset_transport, send_assets_slow), src, SSassets.transport.preload), 5 SECONDS) + addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(getFilesSlow), src, SSassets.preload, FALSE), 5 SECONDS) /mob/proc/MayRespawn() return 0 diff --git a/code/modules/clothing/spacesuits/rig/modules/specific/pat_module_vr.dm b/code/modules/clothing/spacesuits/rig/modules/specific/pat_module_vr.dm index 86880b897ed..7c7e8453d6b 100644 --- a/code/modules/clothing/spacesuits/rig/modules/specific/pat_module_vr.dm +++ b/code/modules/clothing/spacesuits/rig/modules/specific/pat_module_vr.dm @@ -38,8 +38,7 @@ var/mob/living/carbon/human/H = holder.wearer to_chat(H,"You activate the P.A.T. module.") - H.AddComponent(/datum/component/recursive_move) - RegisterSignal(H, COMSIG_OBSERVER_MOVED, /obj/item/rig_module/pat_module/proc/boop) + GLOB.moved_event.register(H, src, /obj/item/rig_module/pat_module/proc/boop) /obj/item/rig_module/pat_module/deactivate() if(!..()) @@ -47,7 +46,7 @@ var/mob/living/carbon/human/H = holder.wearer to_chat(H,"Your disable the P.A.T. module.") - UnregisterSignal(H, COMSIG_OBSERVER_MOVED) + GLOB.moved_event.unregister(H, src) /obj/item/rig_module/pat_module/proc/boop(var/mob/living/carbon/human/user,var/turf/To,var/turf/Tn) if(!istype(user) || !istype(To) || !istype(Tn)) diff --git a/code/modules/clothing/spacesuits/rig/rig.dm b/code/modules/clothing/spacesuits/rig/rig.dm index 62967ad138f..742a10ffabc 100644 --- a/code/modules/clothing/spacesuits/rig/rig.dm +++ b/code/modules/clothing/spacesuits/rig/rig.dm @@ -177,13 +177,13 @@ spark_system = null return ..() -/obj/item/weapon/rig/examine(mob/user) +/obj/item/weapon/rig/examine() . = ..() if(wearer) for(var/obj/item/piece in list(helmet,gloves,chest,boots)) if(!piece || piece.loc != wearer) continue - . += "[icon2html(piece, user.client)] \The [piece] [piece.gender == PLURAL ? "are" : "is"] deployed." + . += "\icon[piece][bicon(piece)] \The [piece] [piece.gender == PLURAL ? "are" : "is"] deployed." if(src.loc == usr) . += "The access panel is [locked? "locked" : "unlocked"]." diff --git a/code/modules/clothing/suits/hooded.dm b/code/modules/clothing/suits/hooded.dm index d56f6c590d3..60d7f53b736 100644 --- a/code/modules/clothing/suits/hooded.dm +++ b/code/modules/clothing/suits/hooded.dm @@ -15,7 +15,7 @@ ..() /obj/item/clothing/suit/storage/hooded/Destroy() - QDEL_NULL(hood) + qdel(hood) return ..() /obj/item/clothing/suit/storage/hooded/proc/MakeHood() @@ -34,13 +34,12 @@ /obj/item/clothing/suit/storage/hooded/proc/RemoveHood() hood_up = FALSE update_icon() - if(hood) - hood.canremove = TRUE // This shouldn't matter anyways but just incase. - if(ishuman(hood.loc)) - var/mob/living/carbon/H = hood.loc - H.unEquip(hood, 1) - H.update_inv_wear_suit() - hood.forceMove(src) + hood.canremove = TRUE // This shouldn't matter anyways but just incase. + if(ishuman(hood.loc)) + var/mob/living/carbon/H = hood.loc + H.unEquip(hood, 1) + H.update_inv_wear_suit() + hood.forceMove(src) /obj/item/clothing/suit/storage/hooded/dropped() RemoveHood() diff --git a/code/modules/detectivework/microscope/dnascanner.dm b/code/modules/detectivework/microscope/dnascanner.dm index 340158eba82..ba8f247443a 100644 --- a/code/modules/detectivework/microscope/dnascanner.dm +++ b/code/modules/detectivework/microscope/dnascanner.dm @@ -105,7 +105,7 @@ last_process_worldtime = world.time /obj/machinery/dnaforensics/proc/complete_scan() - visible_message("[icon2html(src,viewers(src))] makes an insistent chime.", 2) + visible_message("\icon[src][bicon(src)] makes an insistent chime.", 2) update_icon() if(bloodsamp) var/obj/item/weapon/paper/P = new(src) @@ -142,4 +142,4 @@ else if(bloodsamp) icon_state = "dnaclosed" else - icon_state = "dnaopen" + icon_state = "dnaopen" \ No newline at end of file diff --git a/code/modules/economy/ATM.dm b/code/modules/economy/ATM.dm index 4c310c4a538..5d77b215f33 100644 --- a/code/modules/economy/ATM.dm +++ b/code/modules/economy/ATM.dm @@ -76,7 +76,7 @@ log transactions //display a message to the user var/response = pick("Initiating withdraw. Have a nice day!", "CRITICAL ERROR: Activating cash chamber panic siphon.","PIN Code accepted! Emptying account balance.", "Jackpot!") - to_chat(user, "[icon2html(src, user.client)] The [src] beeps: \"[response]\"") + to_chat(user, "\icon[src][bicon(src)] The [src] beeps: \"[response]\"") return 1 /obj/machinery/atm/attackby(obj/item/I as obj, mob/user as mob) @@ -85,7 +85,7 @@ log transactions if(istype(I, /obj/item/weapon/card)) if(emagged > 0) //prevent inserting id into an emagged ATM - to_chat(user, span_red("[icon2html(src, user.client)] CARD READER ERROR. This system has been compromised!")) + to_chat(user, span_red("\icon[src][bicon(src)] CARD READER ERROR. This system has been compromised!")) return else if(istype(I,/obj/item/weapon/card/emag)) I.resolve_attackby(src, user) @@ -234,7 +234,7 @@ log transactions var/target_account_number = text2num(href_list["target_acc_number"]) var/transfer_purpose = href_list["purpose"] if(charge_to_account(target_account_number, authenticated_account.owner_name, transfer_purpose, machine_id, transfer_amount)) - to_chat(usr, "[icon2html(src, usr.client)]Funds transfer successful.") + to_chat(usr, "\icon[src][bicon(src)]Funds transfer successful.") authenticated_account.money -= transfer_amount //create an entry in the account transaction log @@ -247,10 +247,10 @@ log transactions T.amount = "([transfer_amount])" authenticated_account.transaction_log.Add(T) else - to_chat(usr, "[icon2html(src, usr.client)]Funds transfer failed.") + to_chat(usr, "\icon[src][bicon(src)]Funds transfer failed.") else - to_chat(usr, "[icon2html(src, usr.client)]You don't have enough funds to do that!") + to_chat(usr, "\icon[src][bicon(src)]You don't have enough funds to do that!") if("view_screen") view_screen = text2num(href_list["view_screen"]) if("change_security_level") @@ -288,11 +288,11 @@ log transactions T.time = stationtime2text() failed_account.transaction_log.Add(T) else - to_chat(usr, span_red("[icon2html(src, usr.client)] Incorrect pin/account combination entered, [max_pin_attempts - number_incorrect_tries] attempts remaining.")) + to_chat(usr, span_red("\icon[src][bicon(src)] Incorrect pin/account combination entered, [max_pin_attempts - number_incorrect_tries] attempts remaining.")) previous_account_number = tried_account_num playsound(src, 'sound/machines/buzz-sigh.ogg', 50, 1) else - to_chat(usr, span_red("[icon2html(src, usr.client)] incorrect pin/account combination entered.")) + to_chat(usr, span_red("\icon[src][bicon(src)] incorrect pin/account combination entered.")) number_incorrect_tries = 0 else playsound(src, 'sound/machines/twobeep.ogg', 50, 1) @@ -308,7 +308,7 @@ log transactions T.time = stationtime2text() authenticated_account.transaction_log.Add(T) - to_chat(usr, span_blue("[icon2html(src, usr.client)] Access granted. Welcome user '[authenticated_account.owner_name].'")) + to_chat(usr, span_blue("\icon[src][bicon(src)] Access granted. Welcome user '[authenticated_account.owner_name].'")) previous_account_number = tried_account_num if("e_withdrawal") @@ -336,7 +336,7 @@ log transactions T.time = stationtime2text() authenticated_account.transaction_log.Add(T) else - to_chat(usr, "[icon2html(src, usr.client)]You don't have enough funds to do that!") + to_chat(usr, "\icon[src][bicon(src)]You don't have enough funds to do that!") if("withdrawal") var/amount = max(text2num(href_list["funds_amount"]),0) amount = round(amount, 0.01) @@ -361,7 +361,7 @@ log transactions T.time = stationtime2text() authenticated_account.transaction_log.Add(T) else - to_chat(usr, "[icon2html(src, usr.client)]You don't have enough funds to do that!") + to_chat(usr, "\icon[src][bicon(src)]You don't have enough funds to do that!") if("balance_statement") if(authenticated_account) var/obj/item/weapon/paper/R = new(src.loc) @@ -433,7 +433,7 @@ log transactions if(!held_card) //this might happen if the user had the browser window open when somebody emagged it if(emagged > 0) - to_chat(usr, span_red("[icon2html(src, usr.client)] The ATM card reader rejected your ID because this machine has been sabotaged!")) + to_chat(usr, span_red("\icon[src][bicon(src)] The ATM card reader rejected your ID because this machine has been sabotaged!")) else var/obj/item/I = usr.get_active_hand() if (istype(I, /obj/item/weapon/card/id)) diff --git a/code/modules/economy/EFTPOS.dm b/code/modules/economy/EFTPOS.dm index e8fca4633ba..3673f67814f 100644 --- a/code/modules/economy/EFTPOS.dm +++ b/code/modules/economy/EFTPOS.dm @@ -107,7 +107,7 @@ if(linked_account) scan_card(I, O) else - to_chat(usr, "[icon2html(src, usr.client)]Unable to connect to linked account.") + to_chat(usr, "\icon[src][bicon(src)]Unable to connect to linked account.") else if (istype(O, /obj/item/weapon/spacecash/ewallet)) var/obj/item/weapon/spacecash/ewallet/E = O if (linked_account) @@ -115,7 +115,7 @@ if(transaction_locked && !transaction_paid) if(transaction_amount <= E.worth) playsound(src, 'sound/machines/chime.ogg', 50, 1) - src.visible_message("[icon2html(src,viewers(src))] \The [src] chimes.") + src.visible_message("\icon[src][bicon(src)] \The [src] chimes.") transaction_paid = 1 //transfer the money @@ -132,11 +132,11 @@ T.time = stationtime2text() linked_account.transaction_log.Add(T) else - to_chat(usr, "[icon2html(src, usr.client)]\The [O] doesn't have that much money!") + to_chat(usr, "\icon[src][bicon(src)]\The [O] doesn't have that much money!") else - to_chat(usr, "[icon2html(src, usr.client)]Connected account has been suspended.") + to_chat(usr, "\icon[src][bicon(src)]Connected account has been suspended.") else - to_chat(usr, "[icon2html(src, usr.client)]EFTPOS is not connected to an account.") + to_chat(usr, "\icon[src][bicon(src)]EFTPOS is not connected to an account.") else ..() @@ -154,14 +154,14 @@ tgui_alert_async(usr, "That is not a valid code!") print_reference() else - to_chat(usr, "[icon2html(src, usr.client)]Incorrect code entered.") + to_chat(usr, "\icon[src][bicon(src)]Incorrect code entered.") if("change_id") var/attempt_code = text2num(input(usr, "Re-enter the current EFTPOS access code", "Confirm EFTPOS code")) if(attempt_code == access_code) eftpos_name = sanitize(input(usr, "Enter a new terminal ID for this device", "Enter new EFTPOS ID"), MAX_NAME_LEN) + " EFTPOS scanner" print_reference() else - to_chat(usr, "[icon2html(src, usr.client)]Incorrect code entered.") + to_chat(usr, "\icon[src][bicon(src)]Incorrect code entered.") if("link_account") var/attempt_account_num = tgui_input_number(usr, "Enter account number to pay EFTPOS charges into", "New account number") var/attempt_pin = tgui_input_number(usr, "Enter pin code", "Account pin") @@ -169,9 +169,9 @@ if(linked_account) if(linked_account.suspended) linked_account = null - to_chat(usr, "[icon2html(src, usr.client)]Account has been suspended.") + to_chat(usr, "\icon[src][bicon(src)]Account has been suspended.") else - to_chat(usr, "[icon2html(src, usr.client)]Account not found.") + to_chat(usr, "\icon[src][bicon(src)]Account not found.") if("trans_purpose") var/choice = sanitize(input(usr, "Enter reason for EFTPOS transaction", "Transaction purpose")) if(choice) transaction_purpose = choice @@ -194,14 +194,14 @@ else if(linked_account) transaction_locked = 1 else - to_chat(usr, "[icon2html(src, usr.client)]No account connected to send transactions to.") + to_chat(usr, "\icon[src][bicon(src)]No account connected to send transactions to.") if("scan_card") if(linked_account) var/obj/item/I = usr.get_active_hand() if (istype(I, /obj/item/weapon/card)) scan_card(I) else - to_chat(usr, "[icon2html(src, usr.client)]Unable to link accounts.") + to_chat(usr, "\icon[src][bicon(src)]Unable to link accounts.") if("reset") //reset the access code - requires HoP/captain access var/obj/item/I = usr.get_active_hand() @@ -209,10 +209,10 @@ var/obj/item/weapon/card/id/C = I if((access_cent_captain in C.access) || (access_hop in C.access) || (access_captain in C.access)) access_code = 0 - to_chat(usr, "[icon2html(src, usr.client)]Access code reset to 0.") + to_chat(usr, "\icon[src][bicon(src)]Access code reset to 0.") else if (istype(I, /obj/item/weapon/card/emag)) access_code = 0 - to_chat(usr, "[icon2html(src, usr.client)]Access code reset to 0.") + to_chat(usr, "\icon[src][bicon(src)]Access code reset to 0.") src.attack_self(usr) @@ -236,7 +236,7 @@ if(!D.suspended) if(transaction_amount <= D.money) playsound(src, 'sound/machines/chime.ogg', 50, 1) - src.visible_message("[icon2html(src,viewers(src))] \The [src] chimes.") + src.visible_message("\icon[src][bicon(src)] \The [src] chimes.") transaction_paid = 1 //transfer the money @@ -265,25 +265,25 @@ T.time = stationtime2text() linked_account.transaction_log.Add(T) else - to_chat(usr, "[icon2html(src, usr.client)]You don't have that much money!") + to_chat(usr, "\icon[src][bicon(src)]You don't have that much money!") else - to_chat(usr, "[icon2html(src, usr.client)]Your account has been suspended.") + to_chat(usr, "\icon[src][bicon(src)]Your account has been suspended.") else - to_chat(usr, "[icon2html(src, usr.client)]Unable to access account. Check security settings and try again.") + to_chat(usr, "\icon[src][bicon(src)]Unable to access account. Check security settings and try again.") else - to_chat(usr, "[icon2html(src, usr.client)]Connected account has been suspended.") + to_chat(usr, "\icon[src][bicon(src)]Connected account has been suspended.") else - to_chat(usr, "[icon2html(src, usr.client)]EFTPOS is not connected to an account.") + to_chat(usr, "\icon[src][bicon(src)]EFTPOS is not connected to an account.") else if (istype(I, /obj/item/weapon/card/emag)) if(transaction_locked) if(transaction_paid) - to_chat(usr, "[icon2html(src, usr.client)]You stealthily swipe \the [I] through \the [src].") + to_chat(usr, "\icon[src][bicon(src)]You stealthily swipe \the [I] through \the [src].") transaction_locked = 0 transaction_paid = 0 else usr.visible_message("\The [usr] swipes a card through \the [src].") playsound(src, 'sound/machines/chime.ogg', 50, 1) - src.visible_message("[icon2html(src,viewers(src))] \The [src] chimes.") + src.visible_message("\icon[src][bicon(src)] \The [src] chimes.") transaction_paid = 1 //emag? diff --git a/code/modules/economy/cash_register.dm b/code/modules/economy/cash_register.dm index f48404af0e1..ae2479d6130 100644 --- a/code/modules/economy/cash_register.dm +++ b/code/modules/economy/cash_register.dm @@ -103,7 +103,7 @@ if(allowed(usr)) locked = !locked else - to_chat(usr, "[icon2html(src, usr.client)]Insufficient access.") + to_chat(usr, "\icon[src][bicon(src)]Insufficient access.") if("toggle_cash_lock") cash_locked = !cash_locked if("link_account") @@ -113,9 +113,9 @@ if(linked_account) if(linked_account.suspended) linked_account = null - src.visible_message("[icon2html(src,viewers(src))]Account has been suspended.") + src.visible_message("\icon[src][bicon(src)]Account has been suspended.") else - to_chat(usr, "[icon2html(src, usr.client)]Account not found.") + to_chat(usr, "\icon[src][bicon(src)]Account not found.") if("custom_order") var/t_purpose = sanitize(tgui_input_text(usr, "Enter purpose", "New purpose")) if (!t_purpose || !Adjacent(usr)) return @@ -126,7 +126,7 @@ transaction_amount += t_amount price_list += t_amount playsound(src, 'sound/machines/twobeep.ogg', 25) - src.visible_message("[icon2html(src,viewers(src))][transaction_purpose]: [t_amount] Thaler\s.") + src.visible_message("\icon[src][bicon(src)][transaction_purpose]: [t_amount] Thaler\s.") if("set_amount") var/item_name = locate(href_list["item"]) var/n_amount = round(tgui_input_number(usr, "Enter amount", "New amount", 0, 20, 0)) @@ -163,7 +163,7 @@ price_list.Cut() if("reset_log") transaction_logs.Cut() - to_chat(usr, "[icon2html(src, usr.client)]Transaction log reset.") + to_chat(usr, "\icon[src][bicon(src)]Transaction log reset.") updateDialog() @@ -208,7 +208,7 @@ return 1 else confirm_item = I - src.visible_message("[icon2html(src,viewers(src))]Total price: [transaction_amount] Thaler\s. Swipe again to confirm.") + src.visible_message("\icon[src][bicon(src)]Total price: [transaction_amount] Thaler\s. Swipe again to confirm.") playsound(src, 'sound/machines/twobeep.ogg', 25) return 0 @@ -219,14 +219,14 @@ if (cash_open) playsound(src, 'sound/machines/buzz-sigh.ogg', 25) - to_chat(usr, "[icon2html(src, usr.client)]The cash box is open.") + to_chat(usr, "\icon[src][bicon(src)]The cash box is open.") return if((item_list.len > 1 || item_list[item_list[1]] > 1) && !confirm(I)) return if (!linked_account) - usr.visible_message("[icon2html(src,viewers(src))]Unable to connect to linked account.") + usr.visible_message("\icon[src][bicon(src)]Unable to connect to linked account.") return // Access account for transaction @@ -239,13 +239,13 @@ D = attempt_account_access(I.associated_account_number, attempt_pin, 2) if(!D) - src.visible_message("[icon2html(src,viewers(src))]Unable to access account. Check security settings and try again.") + src.visible_message("\icon[src][bicon(src)]Unable to access account. Check security settings and try again.") else if(D.suspended) - src.visible_message("[icon2html(src,viewers(src))]Your account has been suspended.") + src.visible_message("\icon[src][bicon(src)]Your account has been suspended.") else if(transaction_amount > D.money) - src.visible_message("[icon2html(src,viewers(src))]Not enough funds.") + src.visible_message("\icon[src][bicon(src)]Not enough funds.") else // Transfer the money D.money -= transaction_amount @@ -284,7 +284,7 @@ if (cash_open) playsound(src, 'sound/machines/buzz-sigh.ogg', 25) - to_chat(usr, "[icon2html(src, usr.client)]The cash box is open.") + to_chat(usr, "\icon[src][bicon(src)]The cash box is open.") return if((item_list.len > 1 || item_list[item_list[1]] > 1) && !confirm(E)) @@ -293,7 +293,7 @@ // Access account for transaction if(check_account()) if(transaction_amount > E.worth) - src.visible_message("[icon2html(src,viewers(src))]Not enough funds.") + src.visible_message("\icon[src][bicon(src)]Not enough funds.") else // Transfer the money E.worth -= transaction_amount @@ -322,14 +322,14 @@ if (cash_open) playsound(src, 'sound/machines/buzz-sigh.ogg', 25) - to_chat(usr, "[icon2html(src, usr.client)]The cash box is open.") + to_chat(usr, "\icon[src][bicon(src)]The cash box is open.") return if((item_list.len > 1 || item_list[item_list[1]] > 1) && !confirm(SC)) return if(transaction_amount > SC.worth) - src.visible_message("[icon2html(src,viewers(src))]Not enough money.") + src.visible_message("\icon[src][bicon(src)]Not enough money.") else // Insert cash into magical slot SC.worth -= transaction_amount @@ -351,20 +351,20 @@ /obj/machinery/cash_register/proc/scan_item_price(obj/O) if(!istype(O)) return if(item_list.len > 10) - src.visible_message("[icon2html(src,viewers(src))]Only up to ten different items allowed per purchase.") + src.visible_message("\icon[src][bicon(src)]Only up to ten different items allowed per purchase.") return if (cash_open) playsound(src, 'sound/machines/buzz-sigh.ogg', 25) - to_chat(usr, "[icon2html(src, usr.client)]The cash box is open.") + to_chat(usr, "\icon[src][bicon(src)]The cash box is open.") return // First check if item has a valid price var/price = O.get_item_cost() if(isnull(price)) - src.visible_message("[icon2html(src,viewers(src))]Unable to find item in database.") + src.visible_message("\icon[src][bicon(src)]Unable to find item in database.") return // Call out item cost - src.visible_message("[icon2html(src,viewers(src))]\A [O]: [price ? "[price] Thaler\s" : "free of charge"].") + src.visible_message("\icon[src][bicon(src)]\A [O]: [price ? "[price] Thaler\s" : "free of charge"].") // Note the transaction purpose for later use if(transaction_purpose) transaction_purpose += "
" @@ -432,11 +432,11 @@ /obj/machinery/cash_register/proc/check_account() if (!linked_account) - usr.visible_message("[icon2html(src,viewers(src))]Unable to connect to linked account.") + usr.visible_message("\icon[src][bicon(src)]Unable to connect to linked account.") return 0 if(linked_account.suspended) - src.visible_message("[icon2html(src,viewers(src))]Connected account has been suspended.") + src.visible_message("\icon[src][bicon(src)]Connected account has been suspended.") return 0 return 1 @@ -444,7 +444,7 @@ /obj/machinery/cash_register/proc/transaction_complete() /// Visible confirmation playsound(src, 'sound/machines/chime.ogg', 25) - src.visible_message("[icon2html(src,viewers(src))]Transaction complete.") + src.visible_message("\icon[src][bicon(src)]Transaction complete.") flick("register_approve", src) reset_memory() updateDialog() diff --git a/code/modules/economy/retail_scanner.dm b/code/modules/economy/retail_scanner.dm index 5632203dd88..d2ab5884ae1 100644 --- a/code/modules/economy/retail_scanner.dm +++ b/code/modules/economy/retail_scanner.dm @@ -99,7 +99,7 @@ if(allowed(usr)) locked = !locked else - to_chat(usr, "[icon2html(src, usr.client)]Insufficient access.") + to_chat(usr, "\icon[src][bicon(src)]Insufficient access.") if("link_account") var/attempt_account_num = tgui_input_number(usr, "Enter account number", "New account number") var/attempt_pin = tgui_input_number(usr, "Enter PIN", "Account PIN") @@ -107,9 +107,9 @@ if(linked_account) if(linked_account.suspended) linked_account = null - src.visible_message("[icon2html(src,viewers(src))]Account has been suspended.") + src.visible_message("\icon[src][bicon(src)]Account has been suspended.") else - to_chat(usr, "[icon2html(src, usr.client)]Account not found.") + to_chat(usr, "\icon[src][bicon(src)]Account not found.") if("custom_order") var/t_purpose = sanitize(tgui_input_text(usr, "Enter purpose", "New purpose")) if (!t_purpose || !Adjacent(usr)) return @@ -120,7 +120,7 @@ transaction_amount += t_amount price_list += t_amount playsound(src, 'sound/machines/twobeep.ogg', 25) - src.visible_message("[icon2html(src,viewers(src))][transaction_purpose]: [t_amount] Thaler\s.") + src.visible_message("\icon[src][bicon(src)][transaction_purpose]: [t_amount] Thaler\s.") if("set_amount") var/item_name = locate(href_list["item"]) var/n_amount = round(tgui_input_number(usr, "Enter amount", "New amount", 0, 20, 0)) @@ -157,7 +157,7 @@ price_list.Cut() if("reset_log") transaction_logs.Cut() - to_chat(usr, "[icon2html(src, usr.client)]Transaction log reset.") + to_chat(usr, "\icon[src][bicon(src)]Transaction log reset.") updateDialog() @@ -190,7 +190,7 @@ return 1 else confirm_item = I - src.visible_message("[icon2html(src,viewers(src))]Total price: [transaction_amount] Thaler\s. Swipe again to confirm.") + src.visible_message("\icon[src][bicon(src)]Total price: [transaction_amount] Thaler\s. Swipe again to confirm.") playsound(src, 'sound/machines/twobeep.ogg', 25) return 0 @@ -203,7 +203,7 @@ return if (!linked_account) - usr.visible_message("[icon2html(src,viewers(src))]Unable to connect to linked account.") + usr.visible_message("\icon[src][bicon(src)]Unable to connect to linked account.") return // Access account for transaction @@ -216,13 +216,13 @@ D = attempt_account_access(I.associated_account_number, attempt_pin, 2) if(!D) - src.visible_message("[icon2html(src,viewers(src))]Unable to access account. Check security settings and try again.") + src.visible_message("\icon[src][bicon(src)]Unable to access account. Check security settings and try again.") else if(D.suspended) - src.visible_message("[icon2html(src,viewers(src))]Your account has been suspended.") + src.visible_message("\icon[src][bicon(src)]Your account has been suspended.") else if(transaction_amount > D.money) - src.visible_message("[icon2html(src,viewers(src))]Not enough funds.") + src.visible_message("\icon[src][bicon(src)]Not enough funds.") else // Transfer the money D.money -= transaction_amount @@ -265,7 +265,7 @@ // Access account for transaction if(check_account()) if(transaction_amount > E.worth) - src.visible_message("[icon2html(src,viewers(src))]Not enough funds.") + src.visible_message("\icon[src][bicon(src)]Not enough funds.") else // Transfer the money E.worth -= transaction_amount @@ -291,16 +291,16 @@ /obj/item/device/retail_scanner/proc/scan_item_price(var/obj/O) if(!istype(O)) return if(item_list.len > 10) - src.visible_message("[icon2html(src,viewers(src))]Only up to ten different items allowed per purchase.") + src.visible_message("\icon[src][bicon(src)]Only up to ten different items allowed per purchase.") return // First check if item has a valid price var/price = O.get_item_cost() if(isnull(price)) - src.visible_message("[icon2html(src,viewers(src))]Unable to find item in database.") + src.visible_message("\icon[src][bicon(src)]Unable to find item in database.") return // Call out item cost - src.visible_message("[icon2html(src,viewers(src))]\A [O]: [price ? "[price] Thaler\s" : "free of charge"].") + src.visible_message("\icon[src][bicon(src)]\A [O]: [price ? "[price] Thaler\s" : "free of charge"].") // Note the transaction purpose for later use if(transaction_purpose) transaction_purpose += "
" @@ -368,11 +368,11 @@ /obj/item/device/retail_scanner/proc/check_account() if (!linked_account) - usr.visible_message("[icon2html(src,viewers(src))]Unable to connect to linked account.") + usr.visible_message("\icon[src][bicon(src)]Unable to connect to linked account.") return 0 if(linked_account.suspended) - src.visible_message("[icon2html(src,viewers(src))]Connected account has been suspended.") + src.visible_message("\icon[src][bicon(src)]Connected account has been suspended.") return 0 return 1 @@ -380,7 +380,7 @@ /obj/item/device/retail_scanner/proc/transaction_complete() /// Visible confirmation playsound(src, 'sound/machines/chime.ogg', 25) - src.visible_message("[icon2html(src,viewers(src))]Transaction complete.") + src.visible_message("\icon[src][bicon(src)]Transaction complete.") flick("retail_approve", src) reset_memory() updateDialog() diff --git a/code/modules/economy/vending.dm b/code/modules/economy/vending.dm index 17747948eea..a11a6768dde 100644 --- a/code/modules/economy/vending.dm +++ b/code/modules/economy/vending.dm @@ -270,7 +270,7 @@ GLOBAL_LIST_EMPTY(vending_products) // This is not a status display message, since it's something the character // themselves is meant to see BEFORE putting the money in - to_chat(usr, "[icon2html(cashmoney, user.client)] That is not enough money.") + to_chat(usr, "\icon[cashmoney][bicon(cashmoney)] That is not enough money.") return 0 if(istype(cashmoney, /obj/item/weapon/spacecash)) diff --git a/code/modules/events/carp_migration.dm b/code/modules/events/carp_migration.dm index 467f5e25e23..f098533a3b7 100644 --- a/code/modules/events/carp_migration.dm +++ b/code/modules/events/carp_migration.dm @@ -71,7 +71,7 @@ // Spawn a single carp at given location. /datum/event/carp_migration/proc/spawn_one_carp(var/loc) var/mob/living/simple_mob/animal/M = new /mob/living/simple_mob/animal/space/carp/event(loc) - RegisterSignal(M, COMSIG_OBSERVER_DESTROYED, PROC_REF(on_carp_destruction)) + GLOB.destroyed_event.register(M, src, PROC_REF(on_carp_destruction)) spawned_carp.Add(M) return M @@ -85,7 +85,7 @@ // If carp is bomphed, remove it from the list. /datum/event/carp_migration/proc/on_carp_destruction(var/mob/M) spawned_carp -= M - UnregisterSignal(M, COMSIG_OBSERVER_DESTROYED) + GLOB.destroyed_event.unregister(M, src, PROC_REF(on_carp_destruction)) /datum/event/carp_migration/end() . = ..() diff --git a/code/modules/events/gnat_migration.dm b/code/modules/events/gnat_migration.dm index 535b3d81f62..e8b7696cb60 100644 --- a/code/modules/events/gnat_migration.dm +++ b/code/modules/events/gnat_migration.dm @@ -71,7 +71,7 @@ // Spawn a single gnat at given location. /datum/event/gnat_migration/proc/spawn_one_gnat(var/loc) var/mob/living/simple_mob/animal/M = new /mob/living/simple_mob/animal/space/gnat(loc) - RegisterSignal(M, COMSIG_OBSERVER_DESTROYED, PROC_REF(on_gnat_destruction)) + GLOB.destroyed_event.register(M, src, PROC_REF(on_gnat_destruction)) spawned_gnat.Add(M) return M @@ -85,7 +85,7 @@ // If gnat is bomphed, remove it from the list. /datum/event/gnat_migration/proc/on_gnat_destruction(var/mob/M) spawned_gnat -= M - UnregisterSignal(M, COMSIG_OBSERVER_DESTROYED) + GLOB.destroyed_event.unregister(M, src, PROC_REF(on_gnat_destruction)) /datum/event/gnat_migration/end() . = ..() diff --git a/code/modules/events/infestation.dm b/code/modules/events/infestation.dm index b5b8f6876f4..17fcdec8d67 100644 --- a/code/modules/events/infestation.dm +++ b/code/modules/events/infestation.dm @@ -53,7 +53,7 @@ // Spawn a single vermin at given location. /datum/event/infestation/proc/spawn_one_vermin(var/loc) var/mob/living/simple_mob/animal/M = new spawn_types(loc) - RegisterSignal(M, COMSIG_OBSERVER_DESTROYED, PROC_REF(on_vermin_destruction)) + GLOB.destroyed_event.register(M, src, PROC_REF(on_vermin_destruction)) spawned_vermin.Add(M) return M @@ -67,7 +67,7 @@ // If vermin is kill, remove it from the list. /datum/event/infestation/proc/on_vermin_destruction(var/mob/M) spawned_vermin -= M - UnregisterSignal(M, COMSIG_OBSERVER_DESTROYED) + GLOB.destroyed_event.unregister(M, src, PROC_REF(on_vermin_destruction)) diff --git a/code/modules/events/jellyfish_migration.dm b/code/modules/events/jellyfish_migration.dm index 1fd08b1364f..aecf7267391 100644 --- a/code/modules/events/jellyfish_migration.dm +++ b/code/modules/events/jellyfish_migration.dm @@ -71,7 +71,7 @@ // Spawn a single jellyfish at given location. /datum/event/jellyfish_migration/proc/spawn_one_jellyfish(var/loc) var/mob/living/simple_mob/animal/M = new /mob/living/simple_mob/vore/alienanimals/space_jellyfish(loc) - RegisterSignal(M, COMSIG_OBSERVER_DESTROYED, PROC_REF(on_jellyfish_destruction)) + GLOB.destroyed_event.register(M, src, PROC_REF(on_jellyfish_destruction)) spawned_jellyfish.Add(M) return M @@ -85,7 +85,7 @@ // If jellyfish is bomphed, remove it from the list. /datum/event/jellyfish_migration/proc/on_jellyfish_destruction(var/mob/M) spawned_jellyfish -= M - UnregisterSignal(M, COMSIG_OBSERVER_DESTROYED) + GLOB.destroyed_event.unregister(M, src, PROC_REF(on_jellyfish_destruction)) /datum/event/jellyfish_migration/end() . = ..() diff --git a/code/modules/events/ray_migration.dm b/code/modules/events/ray_migration.dm index 8603205d523..94674c75224 100644 --- a/code/modules/events/ray_migration.dm +++ b/code/modules/events/ray_migration.dm @@ -71,7 +71,7 @@ // Spawn a single ray at given location. /datum/event/ray_migration/proc/spawn_one_ray(var/loc) var/mob/living/simple_mob/animal/M = new /mob/living/simple_mob/animal/space/ray(loc) - RegisterSignal(M, COMSIG_OBSERVER_DESTROYED, PROC_REF(on_ray_destruction)) + GLOB.destroyed_event.register(M, src, PROC_REF(on_ray_destruction)) spawned_ray.Add(M) return M @@ -85,7 +85,7 @@ // If ray is bomphed, remove it from the list. /datum/event/ray_migration/proc/on_ray_destruction(var/mob/M) spawned_ray -= M - UnregisterSignal(M, COMSIG_OBSERVER_DESTROYED) + GLOB.destroyed_event.unregister(M, src, PROC_REF(on_ray_destruction)) /datum/event/ray_migration/end() . = ..() diff --git a/code/modules/events/shark_migration.dm b/code/modules/events/shark_migration.dm index c36dd28cb2a..fd5d152f44c 100644 --- a/code/modules/events/shark_migration.dm +++ b/code/modules/events/shark_migration.dm @@ -71,7 +71,7 @@ // Spawn a single shark at given location. /datum/event/shark_migration/proc/spawn_one_shark(var/loc) var/mob/living/simple_mob/animal/M = new /mob/living/simple_mob/animal/space/shark/event(loc) - RegisterSignal(M, COMSIG_OBSERVER_DESTROYED, PROC_REF(on_shark_destruction)) + GLOB.destroyed_event.register(M, src, PROC_REF(on_shark_destruction)) spawned_shark.Add(M) return M @@ -85,7 +85,7 @@ // If shark is bomphed, remove it from the list. /datum/event/shark_migration/proc/on_shark_destruction(var/mob/M) spawned_shark -= M - UnregisterSignal(M, COMSIG_OBSERVER_DESTROYED) + GLOB.destroyed_event.unregister(M, src, PROC_REF(on_shark_destruction)) /datum/event/shark_migration/end() . = ..() diff --git a/code/modules/events/spacefish_migration.dm b/code/modules/events/spacefish_migration.dm index 75a435bd8c5..e25ae3a3cb6 100644 --- a/code/modules/events/spacefish_migration.dm +++ b/code/modules/events/spacefish_migration.dm @@ -86,7 +86,7 @@ // Spawn a single fish at given location. /datum/event/spacefish_migration/proc/spawn_one_fish(var/loc) var/mob/living/simple_mob/animal/M = new fish_type(loc) - RegisterSignal(M, COMSIG_OBSERVER_DESTROYED, PROC_REF(on_fish_destruction)) + GLOB.destroyed_event.register(M, src, PROC_REF(on_fish_destruction)) spawned_fish.Add(M) return M @@ -100,7 +100,7 @@ // If fish is bomphed, remove it from the list. /datum/event/spacefish_migration/proc/on_fish_destruction(var/mob/M) spawned_fish -= M - UnregisterSignal(M, COMSIG_OBSERVER_DESTROYED) + GLOB.destroyed_event.unregister(M, src, PROC_REF(on_fish_destruction)) /datum/event/spacefish_migration/end() . = ..() diff --git a/code/modules/examine/descriptions/armor.dm b/code/modules/examine/descriptions/armor.dm index b1cf96af6ed..2ea8c4e4a04 100644 --- a/code/modules/examine/descriptions/armor.dm +++ b/code/modules/examine/descriptions/armor.dm @@ -24,7 +24,7 @@ switch(slowdown) if(-INFINITY to -0.1) return "It looks like it might actually make you faster!" - if(0,null) + if(0 || null) return "It doesn't look like it'll impede your mobility." if(0.5) return "It might slow you down a little bit." diff --git a/code/modules/examine/examine.dm b/code/modules/examine/examine.dm index 9d4f8a9c0be..949afd4a6f8 100644 --- a/code/modules/examine/examine.dm +++ b/code/modules/examine/examine.dm @@ -34,7 +34,7 @@ // Quickly adds the boilerplate code to add an image and padding for the image. /proc/desc_panel_image(var/icon_state) - return "[bicon(description_icons[icon_state])][EXAMINE_PANEL_PADDING]" + return "\icon[description_icons[icon_state]][EXAMINE_PANEL_PADDING]" /mob/living/get_description_fluff() if(flavor_text) //Get flavor text for the green text. @@ -56,7 +56,7 @@ description_holders["interactions"] = A.get_description_interaction() description_holders["name"] = "[A.name]" - description_holders["icon"] = "[icon2html(A.examine_icon(),src)]" + description_holders["icon"] = "\icon[A.examine_icon()]" description_holders["desc"] = A.desc /mob/Stat() diff --git a/code/modules/food/kitchen/icecream.dm b/code/modules/food/kitchen/icecream.dm index 93b43035d7a..e92bd32254b 100644 --- a/code/modules/food/kitchen/icecream.dm +++ b/code/modules/food/kitchen/icecream.dm @@ -92,7 +92,7 @@ var/obj/item/weapon/reagent_containers/food/snacks/icecream/I = O if(!I.ice_creamed) if(product_types[dispense_flavour] > 0) - src.visible_message("[icon2html(src,viewers(src))] [user] scoops delicious [flavour_name] icecream into [I].") + src.visible_message("\icon[src][bicon(src)] [user] scoops delicious [flavour_name] icecream into [I].") product_types[dispense_flavour] -= 1 I.add_ice_cream(flavour_name) // if(beaker) @@ -192,4 +192,4 @@ #undef ICECREAM_STRAWBERRY #undef ICECREAM_BLUE #undef CONE_WAFFLE -#undef CONE_CHOC +#undef CONE_CHOC \ No newline at end of file diff --git a/code/modules/gamemaster/event2/events/mob_spawning.dm b/code/modules/gamemaster/event2/events/mob_spawning.dm index 828947a07d5..16ed6a31500 100644 --- a/code/modules/gamemaster/event2/events/mob_spawning.dm +++ b/code/modules/gamemaster/event2/events/mob_spawning.dm @@ -80,7 +80,7 @@ /datum/event2/event/mob_spawning/proc/spawn_one_mob(new_loc, mob_type) var/mob/living/simple_mob/M = new mob_type(new_loc) - RegisterSignal(M, COMSIG_OBSERVER_DESTROYED, PROC_REF(on_mob_destruction)) + GLOB.destroyed_event.register(M, src, PROC_REF(on_mob_destruction)) spawned_mobs += M return M @@ -94,4 +94,4 @@ // If simple_mob is bomphed, remove it from the list. /datum/event2/event/mob_spawning/proc/on_mob_destruction(mob/M) spawned_mobs -= M - UnregisterSignal(M, COMSIG_OBSERVER_DESTROYED) + GLOB.destroyed_event.unregister(M, src, PROC_REF(on_mob_destruction)) diff --git a/code/modules/holomap/station_holomap.dm b/code/modules/holomap/station_holomap.dm index 1358625caa9..b997948a5ac 100644 --- a/code/modules/holomap/station_holomap.dm +++ b/code/modules/holomap/station_holomap.dm @@ -112,10 +112,9 @@ user.client.images |= holomap_datum.station_map watching_mob = user - watching_mob.AddComponent(/datum/component/recursive_move) - RegisterSignal(watching_mob, COMSIG_OBSERVER_MOVED, /obj/machinery/station_map/proc/checkPosition) - //GLOB.dir_set_event.register(watching_mob, src, /obj/machinery/station_map/proc/checkPosition) - RegisterSignal(watching_mob, COMSIG_OBSERVER_DESTROYED, /obj/machinery/station_map/proc/stopWatching) + GLOB.moved_event.register(watching_mob, src, /obj/machinery/station_map/proc/checkPosition) + GLOB.dir_set_event.register(watching_mob, src, /obj/machinery/station_map/proc/checkPosition) + GLOB.destroyed_event.register(watching_mob, src, /obj/machinery/station_map/proc/stopWatching) update_use_power(USE_POWER_ACTIVE) if(bogus) @@ -142,9 +141,9 @@ var/mob/M = watching_mob spawn(5) //we give it time to fade out M.client.images -= holomap_datum.station_map - UnregisterSignal(watching_mob, COMSIG_OBSERVER_MOVED) - //GLOB.dir_set_event.unregister(watching_mob, src) - UnregisterSignal(watching_mob, COMSIG_OBSERVER_DESTROYED) + GLOB.moved_event.unregister(watching_mob, src) + GLOB.dir_set_event.unregister(watching_mob, src) + GLOB.destroyed_event.unregister(watching_mob, src) watching_mob = null update_use_power(USE_POWER_IDLE) @@ -164,7 +163,7 @@ /obj/machinery/station_map/update_icon() if(!holomap_datum) return //Not yet. - + cut_overlays() if(stat & BROKEN) icon_state = "station_mapb" diff --git a/code/modules/hydroponics/seed_machines.dm b/code/modules/hydroponics/seed_machines.dm index e81d5606d3e..128c1dc7450 100644 --- a/code/modules/hydroponics/seed_machines.dm +++ b/code/modules/hydroponics/seed_machines.dm @@ -68,15 +68,15 @@ active = 0 if(failed_task) failed_task = 0 - visible_message("[icon2html(src,viewers(src))] [src] pings unhappily, flashing a red warning light.") + visible_message("\icon[src][bicon(src)] [src] pings unhappily, flashing a red warning light.") else - visible_message("[icon2html(src,viewers(src))] [src] pings happily.") + visible_message("\icon[src][bicon(src)] [src] pings happily.") if(eject_disk) eject_disk = 0 if(loaded_disk) loaded_disk.loc = get_turf(src) - visible_message("[icon2html(src,viewers(src))] [src] beeps and spits out [loaded_disk].") + visible_message("\icon[src][bicon(src)] [src] beeps and spits out [loaded_disk].") loaded_disk = null /obj/machinery/botany/attackby(obj/item/weapon/W as obj, mob/user as mob) @@ -190,7 +190,7 @@ SSplants.seeds[seed.seed.name] = seed.seed seed.update_seed() - visible_message("[icon2html(src,viewers(src))] [src] beeps and spits out [seed].") + visible_message("\icon[src][bicon(src)] [src] beeps and spits out [seed].") seed = null return TRUE @@ -199,7 +199,7 @@ if(!loaded_disk) return loaded_disk.forceMove(get_turf(src)) - visible_message("[icon2html(src,viewers(src))] [src] beeps and spits out [loaded_disk].") + visible_message("\icon[src][bicon(src)] [src] beeps and spits out [loaded_disk].") loaded_disk = null return TRUE diff --git a/code/modules/integrated_electronics/subtypes/input.dm b/code/modules/integrated_electronics/subtypes/input.dm index 42b1acb554c..13bb7675799 100644 --- a/code/modules/integrated_electronics/subtypes/input.dm +++ b/code/modules/integrated_electronics/subtypes/input.dm @@ -415,7 +415,7 @@ if(loc) for(var/mob/O in hearers(1, get_turf(src))) - O.show_message("[icon2html(src, usr.client)] *beep* *beep*", 3, "*beep* *beep*", 2) + O.show_message("\icon[src][bicon(src)] *beep* *beep*", 3, "*beep* *beep*", 2) /obj/item/integrated_circuit/input/EPv2 name = "\improper EPv2 circuit" diff --git a/code/modules/integrated_electronics/subtypes/manipulation.dm b/code/modules/integrated_electronics/subtypes/manipulation.dm index 65691369948..143ed465448 100644 --- a/code/modules/integrated_electronics/subtypes/manipulation.dm +++ b/code/modules/integrated_electronics/subtypes/manipulation.dm @@ -188,14 +188,14 @@ // These procs do not relocate the grenade, that's the callers responsibility /obj/item/integrated_circuit/manipulation/grenade/proc/attach_grenade(var/obj/item/weapon/grenade/G) attached_grenade = G - RegisterSignal(attached_grenade, COMSIG_OBSERVER_DESTROYED, /obj/item/integrated_circuit/manipulation/grenade/proc/detach_grenade) + GLOB.destroyed_event.register(attached_grenade, src, /obj/item/integrated_circuit/manipulation/grenade/proc/detach_grenade) size += G.w_class desc += " \An [attached_grenade] is attached to it!" /obj/item/integrated_circuit/manipulation/grenade/proc/detach_grenade() if(!attached_grenade) return - UnregisterSignal(attached_grenade, COMSIG_OBSERVER_DESTROYED) + GLOB.destroyed_event.unregister(attached_grenade, src, /obj/item/integrated_circuit/manipulation/grenade/proc/detach_grenade) attached_grenade = null size = initial(size) desc = initial(desc) diff --git a/code/modules/integrated_electronics/subtypes/output.dm b/code/modules/integrated_electronics/subtypes/output.dm index 06e03856a3b..a20a02c8f1c 100644 --- a/code/modules/integrated_electronics/subtypes/output.dm +++ b/code/modules/integrated_electronics/subtypes/output.dm @@ -43,7 +43,7 @@ var/list/nearby_things = range(0, get_turf(src)) for(var/mob/M in nearby_things) var/obj/O = assembly ? assembly : src - to_chat(M, "[icon2html(O,M.client)] [stuff_to_display]") + to_chat(M, "\icon[O][bicon(O)] [stuff_to_display]") /obj/item/integrated_circuit/output/screen/large name = "large screen" @@ -56,7 +56,7 @@ /obj/item/integrated_circuit/output/screen/large/do_work() ..() var/obj/O = assembly ? loc : assembly - O.visible_message("[icon2html(O,viewers(O))] [stuff_to_display]") + O.visible_message("\icon[O][bicon(O)] [stuff_to_display]") /obj/item/integrated_circuit/output/light name = "light" @@ -134,7 +134,7 @@ text = get_pin_data(IC_INPUT, 1) if(!isnull(text)) var/obj/O = assembly ? loc : assembly - audible_message("[icon2html(O,hearers(src))] \The [O.name] states, \"[text]\"", runemessage = text) + audible_message("\icon[O][bicon(O)] \The [O.name] states, \"[text]\"", runemessage = text) /obj/item/integrated_circuit/output/text_to_speech/advanced name = "advanced text-to-speech circuit" @@ -444,12 +444,11 @@ /obj/item/integrated_circuit/output/holographic_projector/Initialize() . = ..() - AddComponent(/datum/component/recursive_move) - RegisterSignal(src, COMSIG_OBSERVER_MOVED, PROC_REF(on_moved)) + GLOB.moved_event.register(src, src, PROC_REF(on_moved)) /obj/item/integrated_circuit/output/holographic_projector/Destroy() destroy_hologram() - UnregisterSignal(src, COMSIG_OBSERVER_MOVED) + GLOB.moved_event.unregister(src, src, PROC_REF(on_moved)) return ..() /obj/item/integrated_circuit/output/holographic_projector/do_work() diff --git a/code/modules/mining/abandonedcrates_vr.dm b/code/modules/mining/abandonedcrates_vr.dm index fc69d2a31f1..166c5d05ed3 100644 --- a/code/modules/mining/abandonedcrates_vr.dm +++ b/code/modules/mining/abandonedcrates_vr.dm @@ -41,7 +41,7 @@ list(/obj/item/toy/syndicateballoon, 3) = 2, list(/obj/item/clothing/suit/ianshirt, 3) = 2, list(/obj/item/clothing/head/bearpelt, 4) = 2, - //list(/obj/item/weapon/archaeological_find, 3) = 2, //ChompREMOVE - causes runtimes + list(/obj/item/weapon/archaeological_find, 3) = 2, list(pick(subtypesof(/obj/item/toy/mecha)), 4) = 2, list(pick(subtypesof(/obj/item/toy/figure)), 4) = 2, list(pick(subtypesof(/obj/item/toy/plushie)), 4) = 2, @@ -171,4 +171,4 @@ /obj/item/weapon/storage/backpack/sport/hyd/catchemall/Initialize() //gotta have your starter 'mon too (or an improved way to catch one) ..() var/path = pick(subtypesof(/obj/item/capture_crystal)) - contents += new path() + contents += new path() \ No newline at end of file diff --git a/code/modules/mining/drilling/scanner.dm b/code/modules/mining/drilling/scanner.dm index e8f88a0f883..34c0c2f99cc 100644 --- a/code/modules/mining/drilling/scanner.dm +++ b/code/modules/mining/drilling/scanner.dm @@ -51,7 +51,7 @@ if(ore_type) metals[ore_type] += T.resources[metal] - var/message = "[icon2html(src, user.client)] The scanner beeps and displays a readout." + var/message = "\icon[src][bicon(src)] The scanner beeps and displays a readout." for(var/ore_type in metals) var/result = "no sign" @@ -87,4 +87,4 @@ var/custom_range = tgui_input_list(usr, "Scanner Range","Pick a range to scan. ", list(0,1,2,3,4,5,6,7)) if(custom_range) range = custom_range - to_chat(usr, "Scanner will now look up to [range] tile(s) away.") + to_chat(usr, "Scanner will now look up to [range] tile(s) away.") \ No newline at end of file diff --git a/code/modules/mob/dead/observer/logout.dm b/code/modules/mob/dead/observer/logout.dm index 5e1be92091f..bf7db4bf87d 100644 --- a/code/modules/mob/dead/observer/logout.dm +++ b/code/modules/mob/dead/observer/logout.dm @@ -4,4 +4,4 @@ if(src && !key) //we've transferred to another mob. This ghost should be deleted. qdel(src) else - cleanup_timer = QDEL_IN_STOPPABLE(src, 10 MINUTES) + cleanup_timer = QDEL_IN(src, 10 MINUTES) diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index dc7c1cbbdde..32ec266f4c9 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -460,8 +460,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp if(target != src) if(following && following == target) return - if(following) - src.stop_following() following = target to_chat(src, "Now following [target]") if(ismob(target)) diff --git a/code/modules/mob/living/bot/secbot.dm b/code/modules/mob/living/bot/secbot.dm index 0d327055426..a0f485df78f 100644 --- a/code/modules/mob/living/bot/secbot.dm +++ b/code/modules/mob/living/bot/secbot.dm @@ -213,18 +213,17 @@ say("Down on the floor, [suspect_name]! You have [SECBOT_WAIT_TIME*2] seconds to comply.") playsound(src, pick(preparing_arrest_sounds), 50) // Register to be told when the target moves - target.AddComponent(/datum/component/recursive_move) - RegisterSignal(target, COMSIG_OBSERVER_MOVED, /mob/living/bot/secbot/proc/target_moved) + GLOB.moved_event.register(target, src, /mob/living/bot/secbot/proc/target_moved) // Callback invoked if the registered target moves /mob/living/bot/secbot/proc/target_moved(atom/movable/moving_instance, atom/old_loc, atom/new_loc) if(get_dist(get_turf(src), get_turf(target)) >= 1) awaiting_surrender = INFINITY // Done waiting! - UnregisterSignal(moving_instance, COMSIG_OBSERVER_MOVED) + GLOB.moved_event.unregister(moving_instance, src) /mob/living/bot/secbot/resetTarget() ..() - UnregisterSignal(target, COMSIG_OBSERVER_MOVED) + GLOB.moved_event.unregister(target, src) awaiting_surrender = 0 attacked = FALSE walk_to(src, 0) @@ -478,4 +477,4 @@ return if(!in_range(src, user) && loc != user) return - created_name = t + created_name = t \ No newline at end of file diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 4a1d9748fd5..316f314860d 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -18,11 +18,13 @@ germ_level++ /mob/living/carbon/Destroy() - QDEL_NULL(ingested) - QDEL_NULL(touching) + qdel(ingested) + qdel(touching) // We don't qdel(bloodstr) because it's the same as qdel(reagents) - bloodstr = null - QDEL_NULL_LIST(stomach_contents) + for(var/guts in internal_organs) + qdel(guts) + for(var/food in stomach_contents) + qdel(food) return ..() /mob/living/carbon/rejuvenate() diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 76083f014de..c7f3fe1f26e 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -101,7 +101,7 @@ else if(species.name != "Human") name_ender = ", \a [species.get_examine_name()]![species.get_additional_examine_text(src)]" - var/list/msg = list("*---------*","This is [icon2html(src, user.client)] [src.name][name_ender]") + var/list/msg = list("*---------*","This is \icon[src.examine_icon()][bicon(src)] [src.name][name_ender]") //uniform if(w_uniform && !(skip_gear & EXAMINE_SKIPJUMPSUIT) && w_uniform.show_examine) @@ -125,16 +125,16 @@ tie_msg += " [lowertext(english_list(accessory_descs))]." if(w_uniform.blood_DNA) - msg += "[T.He] [T.is] wearing [icon2html(w_uniform,user.client)] [w_uniform.gender==PLURAL?"some":"a"] [(w_uniform.blood_color != "#030303") ? "blood" : "oil"]-stained [w_uniform.name]![tie_msg]" + msg += "[T.He] [T.is] wearing \icon[w_uniform][bicon(w_uniform)] [w_uniform.gender==PLURAL?"some":"a"] [(w_uniform.blood_color != "#030303") ? "blood" : "oil"]-stained [w_uniform.name]![tie_msg]" else - msg += "[T.He] [T.is] wearing [icon2html(w_uniform,user.client)] \a [w_uniform].[tie_msg]" + msg += "[T.He] [T.is] wearing [bicon(w_uniform)] \a [w_uniform].[tie_msg]" //head if(head && !(skip_gear & EXAMINE_SKIPHELMET) && head.show_examine) if(head.blood_DNA) - msg += "[T.He] [T.is] wearing [icon2html(head,user.client)] [head.gender==PLURAL?"some":"a"] [(head.blood_color != "#030303") ? "blood" : "oil"]-stained [head.name] on [T.his] head!" + msg += "[T.He] [T.is] wearing \icon[w_uniform][bicon(head)] [head.gender==PLURAL?"some":"a"] [(head.blood_color != "#030303") ? "blood" : "oil"]-stained [head.name] on [T.his] head!" else - msg += "[T.He] [T.is] wearing [icon2html(head,user.client)] \a [head] on [T.his] head." + msg += "[T.He] [T.is] wearing [bicon(head)] \a [head] on [T.his] head." //suit/armour if(wear_suit) @@ -151,71 +151,71 @@ tie_msg += " [lowertext(english_list(accessory_descs))]." if(wear_suit.blood_DNA) - msg += "[T.He] [T.is] wearing [icon2html(wear_suit,user.client)] [wear_suit.gender==PLURAL?"some":"a"] [(wear_suit.blood_color != "#030303") ? "blood" : "oil"]-stained [wear_suit.name]![tie_msg]" + msg += "[T.He] [T.is] wearing \icon[wear_suit][bicon(wear_suit)] [wear_suit.gender==PLURAL?"some":"a"] [(wear_suit.blood_color != "#030303") ? "blood" : "oil"]-stained [wear_suit.name]![tie_msg]" else - msg += "[T.He] [T.is] wearing [icon2html(wear_suit,user.client)] \a [wear_suit].[tie_msg]" + msg += "[T.He] [T.is] wearing \icon[wear_suit][bicon(wear_suit)] \a [wear_suit].[tie_msg]" //suit/armour storage if(s_store && !(skip_gear & EXAMINE_SKIPSUITSTORAGE) && s_store.show_examine) if(s_store.blood_DNA) - msg += "[T.He] [T.is] carrying [icon2html(s_store,user.client)] [s_store.gender==PLURAL?"some":"a"] [(s_store.blood_color != "#030303") ? "blood" : "oil"]-stained [s_store.name] on [T.his] [wear_suit.name]!" + msg += "[T.He] [T.is] carrying \icon[s_store][bicon(s_store)] [s_store.gender==PLURAL?"some":"a"] [(s_store.blood_color != "#030303") ? "blood" : "oil"]-stained [s_store.name] on [T.his] [wear_suit.name]!" else - msg += "[T.He] [T.is] carrying [icon2html(s_store,user.client)] \a [s_store] on [T.his] [wear_suit.name]." + msg += "[T.He] [T.is] carrying \icon[s_store][bicon(s_store)] \a [s_store] on [T.his] [wear_suit.name]." //back if(back && !(skip_gear & EXAMINE_SKIPBACKPACK) && back.show_examine) if(back.blood_DNA) - msg += "[T.He] [T.has] [icon2html(back,user.client)] [back.gender==PLURAL?"some":"a"] [(back.blood_color != "#030303") ? "blood" : "oil"]-stained [back] on [T.his] back." + msg += "[T.He] [T.has] \icon[back][bicon(back)] [back.gender==PLURAL?"some":"a"] [(back.blood_color != "#030303") ? "blood" : "oil"]-stained [back] on [T.his] back." else - msg += "[T.He] [T.has] [icon2html(back,user.client)] \a [back] on [T.his] back." + msg += "[T.He] [T.has] \icon[back][bicon(back)] \a [back] on [T.his] back." //left hand if(l_hand && l_hand.show_examine) if(l_hand.blood_DNA) - msg += "[T.He] [T.is] holding [icon2html(l_hand,user.client)] [l_hand.gender==PLURAL?"some":"a"] [(l_hand.blood_color != "#030303") ? "blood" : "oil"]-stained [l_hand.name] in [T.his] left hand!" + msg += "[T.He] [T.is] holding \icon[l_hand][bicon(l_hand)] [l_hand.gender==PLURAL?"some":"a"] [(l_hand.blood_color != "#030303") ? "blood" : "oil"]-stained [l_hand.name] in [T.his] left hand!" else - msg += "[T.He] [T.is] holding [icon2html(l_hand,user.client)] \a [l_hand] in [T.his] left hand." + msg += "[T.He] [T.is] holding \icon[l_hand][bicon(l_hand)] \a [l_hand] in [T.his] left hand." //right hand if(r_hand && r_hand.show_examine) if(r_hand.blood_DNA) - msg += "[T.He] [T.is] holding [icon2html(r_hand,user.client)] [r_hand.gender==PLURAL?"some":"a"] [(r_hand.blood_color != "#030303") ? "blood" : "oil"]-stained [r_hand.name] in [T.his] right hand!" + msg += "[T.He] [T.is] holding \icon[r_hand][bicon(r_hand)] [r_hand.gender==PLURAL?"some":"a"] [(r_hand.blood_color != "#030303") ? "blood" : "oil"]-stained [r_hand.name] in [T.his] right hand!" else - msg += "[T.He] [T.is] holding [icon2html(r_hand,user.client)] \a [r_hand] in [T.his] right hand." + msg += "[T.He] [T.is] holding \icon[r_hand][bicon(r_hand)] \a [r_hand] in [T.his] right hand." //gloves if(gloves && !(skip_gear & EXAMINE_SKIPGLOVES) && gloves.show_examine) if(gloves.blood_DNA) - msg += "[T.He] [T.has] [icon2html(gloves,user.client)] [gloves.gender==PLURAL?"some":"a"] [(gloves.blood_color != "#030303") ? "blood" : "oil"]-stained [gloves.name] on [T.his] hands!" + msg += "[T.He] [T.has] \icon[gloves][bicon(gloves)] [gloves.gender==PLURAL?"some":"a"] [(gloves.blood_color != "#030303") ? "blood" : "oil"]-stained [gloves.name] on [T.his] hands!" else - msg += "[T.He] [T.has] [icon2html(gloves,user.client)] \a [gloves] on [T.his] hands." + msg += "[T.He] [T.has] \icon[gloves][bicon(gloves)] \a [gloves] on [T.his] hands." else if(blood_DNA && !(skip_body & EXAMINE_SKIPHANDS)) msg += "[T.He] [T.has] [(hand_blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained hands!" //handcuffed? if(handcuffed && handcuffed.show_examine) if(istype(handcuffed, /obj/item/weapon/handcuffs/cable)) - msg += "[T.He] [T.is] [icon2html(handcuffed,user.client)] restrained with cable!" + msg += "[T.He] [T.is] \icon[handcuffed][bicon(handcuffed)] restrained with cable!" else - msg += "[T.He] [T.is] [icon2html(handcuffed,user.client)] handcuffed!" + msg += "[T.He] [T.is] \icon[handcuffed][bicon(handcuffed)] handcuffed!" //buckled if(buckled) - msg += "[T.He] [T.is] [icon2html(buckled,user.client)] buckled to [buckled]!" + msg += "[T.He] [T.is] \icon[buckled][bicon(buckled)] buckled to [buckled]!" //belt if(belt && !(skip_gear & EXAMINE_SKIPBELT) && belt.show_examine) if(belt.blood_DNA) - msg += "[T.He] [T.has] [icon2html(belt,user.client)] [belt.gender==PLURAL?"some":"a"] [(belt.blood_color != "#030303") ? "blood" : "oil"]-stained [belt.name] about [T.his] waist!" + msg += "[T.He] [T.has] \icon[belt][bicon(belt)] [belt.gender==PLURAL?"some":"a"] [(belt.blood_color != "#030303") ? "blood" : "oil"]-stained [belt.name] about [T.his] waist!" else - msg += "[T.He] [T.has] [icon2html(belt,user.client)] \a [belt] about [T.his] waist." + msg += "[T.He] [T.has] \icon[belt][bicon(belt)] \a [belt] about [T.his] waist." //shoes if(shoes && !(skip_gear & EXAMINE_SKIPSHOES) && shoes.show_examine) if(shoes.blood_DNA) - msg += "[T.He] [T.is] wearing [icon2html(shoes,user.client)] [shoes.gender==PLURAL?"some":"a"] [(shoes.blood_color != "#030303") ? "blood" : "oil"]-stained [shoes.name] on [T.his] feet!" + msg += "[T.He] [T.is] wearing \icon[shoes][bicon(shoes)] [shoes.gender==PLURAL?"some":"a"] [(shoes.blood_color != "#030303") ? "blood" : "oil"]-stained [shoes.name] on [T.his] feet!" else - msg += "[T.He] [T.is] wearing [icon2html(shoes,user.client)] \a [shoes] on [T.his] feet." + msg += "[T.He] [T.is] wearing \icon[shoes][bicon(shoes)] \a [shoes] on [T.his] feet." else if(feet_blood_DNA && !(skip_body & EXAMINE_SKIPHANDS)) msg += "[T.He] [T.has] [(feet_blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained feet!" @@ -226,28 +226,28 @@ descriptor = "in [T.his] mouth" if(wear_mask.blood_DNA) - msg += "[T.He] [T.has] [icon2html(wear_mask,user.client)] [wear_mask.gender==PLURAL?"some":"a"] [(wear_mask.blood_color != "#030303") ? "blood" : "oil"]-stained [wear_mask.name] [descriptor]!" + msg += "[T.He] [T.has] \icon[wear_mask][bicon(wear_mask)] [wear_mask.gender==PLURAL?"some":"a"] [(wear_mask.blood_color != "#030303") ? "blood" : "oil"]-stained [wear_mask.name] [descriptor]!" else - msg += "[T.He] [T.has] [icon2html(wear_mask,user.client)] \a [wear_mask] [descriptor]." + msg += "[T.He] [T.has] \icon[wear_mask][bicon(wear_mask)] \a [wear_mask] [descriptor]." //eyes if(glasses && !(skip_gear & EXAMINE_SKIPEYEWEAR) && glasses.show_examine) if(glasses.blood_DNA) - msg += "[T.He] [T.has] [icon2html(glasses,user.client)] [glasses.gender==PLURAL?"some":"a"] [(glasses.blood_color != "#030303") ? "blood" : "oil"]-stained [glasses] covering [T.his] eyes!" + msg += "[T.He] [T.has] \icon[glasses][bicon(glasses)] [glasses.gender==PLURAL?"some":"a"] [(glasses.blood_color != "#030303") ? "blood" : "oil"]-stained [glasses] covering [T.his] eyes!" else - msg += "[T.He] [T.has] [icon2html(glasses,user.client)] \a [glasses] covering [T.his] eyes." + msg += "[T.He] [T.has] \icon[glasses][bicon(glasses)] \a [glasses] covering [T.his] eyes." //left ear if(l_ear && !(skip_gear & EXAMINE_SKIPEARS) && l_ear.show_examine) - msg += "[T.He] [T.has] [icon2html(l_ear,user.client)] \a [l_ear] on [T.his] left ear." + msg += "[T.He] [T.has] \icon[l_ear][bicon(l_ear)] \a [l_ear] on [T.his] left ear." //right ear if(r_ear && !(skip_gear & EXAMINE_SKIPEARS) && r_ear.show_examine) - msg += "[T.He] [T.has] [icon2html(r_ear,user.client)] \a [r_ear] on [T.his] right ear." + msg += "[T.He] [T.has] \icon[r_ear][bicon(r_ear)] \a [r_ear] on [T.his] right ear." //ID if(wear_id && wear_id.show_examine) - msg += "[T.He] [T.is] wearing [icon2html(wear_id,user.client)]\a [wear_id]." + msg += "[T.He] [T.is] wearing \icon[wear_id][bicon(wear_id)]\a [wear_id]." //Jitters if(is_jittery) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index fce4a9f9880..308d2479ef0 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -57,17 +57,10 @@ /mob/living/carbon/human/Destroy() human_mob_list -= src - /* //Chomp REMOVE - this is done on mob/living/Destroy for(var/organ in organs) qdel(organ) - */ - if(nif) - QDEL_NULL(nif) //VOREStation Add + QDEL_NULL(nif) //VOREStation Add worn_clothing.Cut() - - - if(vessel) - QDEL_NULL(vessel) return ..() /mob/living/carbon/human/Stat() diff --git a/code/modules/mob/living/carbon/human/human_modular_limbs.dm b/code/modules/mob/living/carbon/human/human_modular_limbs.dm index b9c783a8b17..481c9e57341 100644 --- a/code/modules/mob/living/carbon/human/human_modular_limbs.dm +++ b/code/modules/mob/living/carbon/human/human_modular_limbs.dm @@ -73,13 +73,13 @@ // Called in robotize(), replaced() and removed() to update our modular limb verbs. /mob/living/carbon/human/proc/refresh_modular_limb_verbs() if(length(get_modular_limbs(return_first_found = TRUE, validate_proc = /obj/item/organ/external/proc/can_attach_modular_limb_here))) - verbs |= /mob/living/carbon/human/proc/attach_limb_verb + verbs |= PROC_REF(attach_limb_verb) else - verbs -= /mob/living/carbon/human/proc/attach_limb_verb + verbs -= PROC_REF(attach_limb_verb) if(length(get_modular_limbs(return_first_found = TRUE, validate_proc = /obj/item/organ/external/proc/can_remove_modular_limb))) - verbs |= /mob/living/carbon/human/proc/detach_limb_verb + verbs |= PROC_REF(detach_limb_verb) else - verbs -= /mob/living/carbon/human/proc/detach_limb_verb + verbs -= PROC_REF(detach_limb_verb) // Proc helper for attachment verb. /mob/living/carbon/human/proc/check_can_attach_modular_limb(var/obj/item/organ/external/E) diff --git a/code/modules/mob/living/carbon/human/human_vr.dm b/code/modules/mob/living/carbon/human/human_vr.dm index cfbfc387ba7..1fd36d32ff8 100644 --- a/code/modules/mob/living/carbon/human/human_vr.dm +++ b/code/modules/mob/living/carbon/human/human_vr.dm @@ -7,6 +7,7 @@ img.override = TRUE add_alt_appearance("animals", img, displayTo = alt_farmanimals) + /mob/living/carbon/human/Destroy() alt_farmanimals -= src @@ -17,3 +18,4 @@ /mob/living/carbon/human/get_digestion_efficiency_modifier() return species.digestion_efficiency + diff --git a/code/modules/mob/living/carbon/human/species/species_vr.dm b/code/modules/mob/living/carbon/human/species/species_vr.dm index 99cd1fd8775..9ca4008d83a 100644 --- a/code/modules/mob/living/carbon/human/species/species_vr.dm +++ b/code/modules/mob/living/carbon/human/species/species_vr.dm @@ -99,15 +99,20 @@ return new_copy -//We REALLY don't need to go through every variable. Doing so makes this lag like hell on 515 /datum/species/proc/copy_variables(var/datum/species/S, var/list/whitelist) //List of variables to ignore, trying to copy type will runtime. - //var/list/blacklist = list("type", "loc", "client", "ckey") + var/list/blacklist = list("type", "loc", "client", "ckey") //Makes thorough copy of species datum. - for(var/i in whitelist) + for(var/i in vars) if(!(i in S.vars)) //Don't copy incompatible vars. continue if(S.vars[i] != vars[i] && !islist(vars[i])) //If vars are same, no point in copying. + if(i in blacklist) + continue + if(whitelist)//If whitelist is provided, only vars in the list will be copied. + if(i in whitelist) + S.vars[i] = vars[i] + continue S.vars[i] = vars[i] /datum/species/get_bodytype() diff --git a/code/modules/mob/living/carbon/human/species/station/prommie_blob.dm b/code/modules/mob/living/carbon/human/species/station/prommie_blob.dm index 73a9a10fc54..7006dd9968a 100644 --- a/code/modules/mob/living/carbon/human/species/station/prommie_blob.dm +++ b/code/modules/mob/living/carbon/human/species/station/prommie_blob.dm @@ -78,7 +78,8 @@ if(stored_blob) stored_blob.drop_l_hand() stored_blob.drop_r_hand() - QDEL_NULL(stored_blob) + stored_blob = null + qdel(stored_blob) return ..() /mob/living/simple_mob/slime/promethean/Stat() diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 18a2a90d0f0..7abf8601aa1 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -50,17 +50,14 @@ B.owner = tf_mob_holder tf_mob_holder.vore_organs |= B vore_organs -= B + if(tf_mob_holder) tf_mob_holder = null //VOREStation Addition End - if(hud_list) //prune out images in hud_list - for(var/item in hud_list) - if(item) - item = null - if(selected_image) - selected_image = null - //QDEL_NULL(vorePanel) //VOREStation Add commented and moved to /mob - //QDEL_LIST_NULL(vore_organs) //VOREStation Add commented and moved to /mob + + qdel(selected_image) + QDEL_NULL(vorePanel) //VOREStation Add + QDEL_LIST_NULL(vore_organs) //VOREStation Add temp_language_sources = null //VOREStation Add temp_languages = null //VOREStation Add @@ -1297,7 +1294,7 @@ /datum/component/character_setup/proc/character_setup_click(source, location, control, params, user) var/mob/owner = user if(owner.client?.prefs) - INVOKE_ASYNC(owner.client.prefs, TYPE_PROC_REF(/datum/preferences, ShowChoices), owner) + INVOKE_ASYNC(owner.client.prefs, /datum/preferences/proc/ShowChoices, owner) /** * Screen object for vore panel diff --git a/code/modules/mob/living/silicon/pai/software_modules.dm b/code/modules/mob/living/silicon/pai/software_modules.dm index 3f527a06f37..5fceeceb335 100644 --- a/code/modules/mob/living/silicon/pai/software_modules.dm +++ b/code/modules/mob/living/silicon/pai/software_modules.dm @@ -491,7 +491,7 @@ spawn(0) R.send_signal("ACTIVATE") for(var/mob/O in hearers(1, R.loc)) - O.show_message("[icon2html(R,O.client)] *beep* *beep*", 3, "*beep* *beep*", 2) + O.show_message("\icon[R][bicon(R)] *beep* *beep*", 3, "*beep* *beep*", 2) if("freq") var/frequency = unformat_frequency(params["freq"]) frequency = sanitize_frequency(frequency, RADIO_LOW_FREQ, RADIO_HIGH_FREQ) diff --git a/code/modules/mob/living/silicon/robot/life.dm b/code/modules/mob/living/silicon/robot/life.dm index 347c4e5b8ad..276ab699a3e 100644 --- a/code/modules/mob/living/silicon/robot/life.dm +++ b/code/modules/mob/living/silicon/robot/life.dm @@ -227,20 +227,21 @@ else src.healths.icon_state = "health6" else - if(health >= 200) - src.healths.icon_state = "health0" - else if(health >= 150) - src.healths.icon_state = "health1" - else if(health >= 100) - src.healths.icon_state = "health2" - else if(health >= 50) - src.healths.icon_state = "health3" - else if(health >= 0) - src.healths.icon_state = "health4" - else if(health >= config.health_threshold_dead) - src.healths.icon_state = "health5" - else - src.healths.icon_state = "health6" + switch(health) + if(200 to INFINITY) + src.healths.icon_state = "health0" + if(150 to 200) + src.healths.icon_state = "health1" + if(100 to 150) + src.healths.icon_state = "health2" + if(50 to 100) + src.healths.icon_state = "health3" + if(0 to 50) + src.healths.icon_state = "health4" + if(config.health_threshold_dead to 0) + src.healths.icon_state = "health5" + else + src.healths.icon_state = "health6" else src.healths.icon_state = "health7" diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/alien animals/catslug.dm b/code/modules/mob/living/simple_mob/subtypes/animal/alien animals/catslug.dm index ec2f45c9f00..d203d129492 100644 --- a/code/modules/mob/living/simple_mob/subtypes/animal/alien animals/catslug.dm +++ b/code/modules/mob/living/simple_mob/subtypes/animal/alien animals/catslug.dm @@ -224,7 +224,9 @@ return visible_message("\The [src] pushes [M]'s hand away from their tummy and furrows their brow!") if(prob(5)) - ai_holder.give_target(M, urgent = TRUE) + ai_holder.target = M + ai_holder.track_target_position() + ai_holder.set_stance(STANCE_FIGHT) else return ..() @@ -451,7 +453,9 @@ return visible_message("\The [src] pushes [M]'s hand away from their tummy and furrows their brow, frantically pressing at the buttons [M] so carelessly pushed!") if(prob(5)) - ai_holder.give_target(M, urgent = TRUE) + ai_holder.target = M + ai_holder.track_target_position() + ai_holder.set_stance(STANCE_FIGHT) else return ..() @@ -551,7 +555,9 @@ return visible_message("\The [src] pushes [M]'s hand away from their tummy and furrows their brow!") if(prob(5)) - ai_holder.give_target(M, urgent = TRUE) + ai_holder.target = M + ai_holder.track_target_position() + ai_holder.set_stance(STANCE_FIGHT) else return ..() diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/passive/mouse.dm b/code/modules/mob/living/simple_mob/subtypes/animal/passive/mouse.dm index cb63b48cff8..dd6b6db3cf5 100644 --- a/code/modules/mob/living/simple_mob/subtypes/animal/passive/mouse.dm +++ b/code/modules/mob/living/simple_mob/subtypes/animal/passive/mouse.dm @@ -79,7 +79,7 @@ if( ishuman(AM) ) if(!stat) var/mob/M = AM - M.visible_message(span_blue("[icon2html(src,viewers(src))] Squeek!")) + M.visible_message(span_blue("\icon[src][bicon(src)] Squeek!")) playsound(src, 'sound/effects/mouse_squeak.ogg', 35, 1) ..() diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/solargrub_larva.dm b/code/modules/mob/living/simple_mob/subtypes/vore/solargrub_larva.dm index ac5d53e86a5..db748e732ae 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/solargrub_larva.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/solargrub_larva.dm @@ -143,7 +143,7 @@ var/global/list/grub_machine_overlays = list() sparks.start() if(machine_effect) QDEL_NULL(machine_effect) - ai_holder.remove_target() + ai_holder.target = null powermachine.draining = 1 spawn(30) set_AI_busy(FALSE) diff --git a/code/modules/mob/living/voice/voice.dm b/code/modules/mob/living/voice/voice.dm index 77558211f0d..901807583a4 100644 --- a/code/modules/mob/living/voice/voice.dm +++ b/code/modules/mob/living/voice/voice.dm @@ -83,7 +83,7 @@ var/new_name = sanitizeSafe(tgui_input_text(src, "Who would you like to be now?", "Communicator", src.client.prefs.real_name, MAX_NAME_LEN), MAX_NAME_LEN) if(new_name) if(comm) - comm.visible_message("[icon2html(comm,viewers(comm))] [src.name] has left, and now you see [new_name].") + comm.visible_message("\icon[comm][bicon(comm)] [src.name] has left, and now you see [new_name].") //Do a bit of logging in-case anyone tries to impersonate other characters for whatever reason. var/msg = "[src.client.key] ([src]) has changed their communicator identity's name to [new_name]." message_admins(msg) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 643ad28105f..ea52bc47604 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -2,42 +2,20 @@ mob_list -= src dead_mob_list -= src living_mob_list -= src - player_list -= src unset_machine() - QDEL_NULL(hud_used) + qdel(hud_used) clear_fullscreen() if(client) for(var/obj/screen/movable/spell_master/spell_master in spell_masters) qdel(spell_master) remove_screen_obj_references() - client.screen.Cut() + client.screen = list() if(mind && mind.current == src) spellremove(src) ghostize() - if(focus) - focus = null - if(plane_holder) - QDEL_NULL(plane_holder) - - if(pulling) - stop_pulling() //TG does this on atom/movable but our stop_pulling proc is here so whatever - - vore_selected = null - if(vore_organs) - QDEL_NULL_LIST(vore_organs) - if(vorePanel) - QDEL_NULL(vorePanel) - - - if(mind) - if(mind.current == src) - mind.current = null - if(mind.original == src) - mind.original = null - - . = ..() - update_client_z(null) - //return QDEL_HINT_HARDDEL_NOW + QDEL_NULL(plane_holder) + ..() + return QDEL_HINT_HARDDEL_NOW /mob/proc/remove_screen_obj_references() hands = null @@ -65,8 +43,7 @@ set_focus(src) // VOREStation Add - Key Handling hook_vr("mob_new",list(src)) //VOREStation Code update_transform() // Some mobs may start bigger or smaller than normal. - . = ..() - //return QDEL_HINT_HARDDEL_NOW Just keep track of mob references. They delete SO much faster now. + return ..() /mob/proc/show_message(msg, type, alt, alt_type)//Message, type of message (1 or 2), alternative message, alt message type (1 or 2) var/time = say_timestamp() @@ -1239,15 +1216,6 @@ . = ..() - -/obj/Destroy() - if(istype(src.loc, /mob)) - var/mob/holder = src.loc - if(src in holder.exploit_addons) - holder.exploit_addons -= src - . = ..() - - /client/proc/check_has_body_select() return mob && mob.hud_used && istype(mob.zone_sel, /obj/screen/zone_sel) diff --git a/code/modules/mob/mob_planes_vr.dm b/code/modules/mob/mob_planes_vr.dm index b23067733f3..1c47b13e720 100644 --- a/code/modules/mob/mob_planes_vr.dm +++ b/code/modules/mob/mob_planes_vr.dm @@ -5,7 +5,7 @@ plane_masters[VIS_CH_BACKUP] = new /obj/screen/plane_master{plane = PLANE_CH_BACKUP} //Backup implant status plane_masters[VIS_CH_VANTAG] = new /obj/screen/plane_master{plane = PLANE_CH_VANTAG} //Vore Antags - plane_masters[VIS_AUGMENTED] = new /obj/screen/plane_master/augmented(M = my_mob) //Augmented reality + plane_masters[VIS_AUGMENTED] = new /obj/screen/plane_master/augmented(my_mob) //Augmented reality ..() ///////////////// @@ -15,7 +15,7 @@ var/state = FALSE //Saves cost with the lists var/mob/my_mob -/obj/screen/plane_master/augmented/New(null, var/mob/M) +/obj/screen/plane_master/augmented/New(var/mob/M) ..() my_mob = M diff --git a/code/modules/mob/new_player/logout.dm b/code/modules/mob/new_player/logout.dm index bbffe5e9baf..37e7d535ec1 100644 --- a/code/modules/mob/new_player/logout.dm +++ b/code/modules/mob/new_player/logout.dm @@ -8,8 +8,8 @@ ..() - //if(created_for) - //del_mannequin(created_for) No need to delete this, honestly. It saves up hardly any memory in the long run and fucks the GC in the short run. + if(created_for) + del_mannequin(created_for) if(!spawning)//Here so that if they are spawning and log out, the other procs can play out and they will have a mob to come back to. key = null//We null their key before deleting the mob, so they are properly kicked out. diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index 851d43f5b1b..a8ea47ae0a8 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -25,12 +25,6 @@ verbs |= /mob/proc/insidePanel initialized = TRUE // Explicitly don't use Initialize(). New players join super early and use New() - -/mob/new_player/Destroy() - if(panel) - QDEL_NULL(panel) - . = ..() - /mob/new_player/verb/new_player_panel() set src = usr new_player_panel_proc() @@ -165,11 +159,11 @@ if(!client) return 1 //Make a new mannequin quickly, and allow the observer to take the appearance - var/mob/living/carbon/human/dummy/mannequin = get_mannequin(client.ckey) + var/mob/living/carbon/human/dummy/mannequin = new() client.prefs.dress_preview_mob(mannequin) var/mob/observer/dead/observer = new(mannequin) observer.moveToNullspace() //Let's not stay in our doomed mannequin - //qdel(mannequin) + qdel(mannequin) spawning = 1 if(client.media) diff --git a/code/modules/multiz/movement_vr.dm b/code/modules/multiz/movement_vr.dm index fa000ef4b7e..c77ab2c0412 100644 --- a/code/modules/multiz/movement_vr.dm +++ b/code/modules/multiz/movement_vr.dm @@ -177,14 +177,15 @@ climb_time += 10 SECONDS if(climbing_delay_min > 1.0) climb_time += 2.5 SECONDS - if(L.nutrition >= 100 && L.nutrition <= 200) - to_chat(L, SPAN_NOTICE("Climbing while [L.isSynthetic() ? "low on power" : "hungry"] slows you down")) - climb_time += 1 SECONDS - else if(L.nutrition >= nutrition_cost && L.nutrition <= 100) - to_chat(L, SPAN_DANGER("You [L.isSynthetic() ? "lack enough power" : "are too hungry"] to climb safely!")) - climb_time +=3 SECONDS - if(fall_chance < 30) - fall_chance = 30 + switch(L.nutrition) //Values are 50 lower than the warning icon appearing + if(100 to 200) + to_chat(L, SPAN_NOTICE("Climbing while [L.isSynthetic() ? "low on power" : "hungry"] slows you down")) + climb_time += 1 SECONDS + if(nutrition_cost to 100) + to_chat(L, SPAN_DANGER("You [L.isSynthetic() ? "lack enough power" : "are too hungry"] to climb safely!")) + climb_time +=3 SECONDS + if(fall_chance < 30) + fall_chance = 30 L.visible_message(message = "[L] begins to climb up on \The [src]", self_message = "You begin to clumb up on \The [src]", \ blind_message = "You hear the sounds of climbing!", runemessage = "Tap Tap") var/oops_time = world.time @@ -293,14 +294,15 @@ climb_time += 10 SECONDS if(climbing_delay_min > 1.0) climb_time += 2.5 SECONDS - if(nutrition >= 100 && nutrition <= 200) //Values are 50 lower than the warning icon appearing - to_chat(src, SPAN_NOTICE("Climbing while [isSynthetic() ? "low on power" : "hungry"] slows you down")) - climb_time += 1 SECONDS - else if(nutrition >= nutrition_cost && nutrition <= 100) - to_chat(src, SPAN_DANGER("You [isSynthetic() ? "lack enough power" : "are too hungry"] to climb safely!")) - climb_time +=3 SECONDS - if(fall_chance < 30) - fall_chance = 30 + switch(nutrition) //Values are 50 lower than the warning icon appearing + if(100 to 200) + to_chat(src, SPAN_NOTICE("Climbing while [isSynthetic() ? "low on power" : "hungry"] slows you down")) + climb_time += 1 SECONDS + if(nutrition_cost to 100) + to_chat(src, SPAN_DANGER("You [isSynthetic() ? "lack enough power" : "are too hungry"] to climb safely!")) + climb_time +=3 SECONDS + if(fall_chance < 30) + fall_chance = 30 if(!climbing_surface.climbable) to_chat(src, SPAN_DANGER("\The [climbing_surface] is not suitable for climbing! Even for a master climber, this is risky!")) diff --git a/code/modules/nifsoft/nif.dm b/code/modules/nifsoft/nif.dm index bc84f214c7f..7890e522067 100644 --- a/code/modules/nifsoft/nif.dm +++ b/code/modules/nifsoft/nif.dm @@ -383,7 +383,7 @@ You can also set the stat of a NIF to NIF_TEMPFAIL without any issues to disable last_notification = message // TGUI Hook - to_chat(human,"\[[icon2html(src.big_icon, human.client)]NIF\] displays, \"[message]\"") + to_chat(human,"\[\icon[src.big_icon][bicon(src.big_icon)]NIF\] displays, \"[message]\"") if(prob(1)) human.visible_message("\The [human] [pick(look_messages)].") if(alert) human << bad_sound diff --git a/code/modules/nifsoft/software/13_soulcatcher.dm b/code/modules/nifsoft/software/13_soulcatcher.dm index 5c0bad42948..20172ac9241 100644 --- a/code/modules/nifsoft/software/13_soulcatcher.dm +++ b/code/modules/nifsoft/software/13_soulcatcher.dm @@ -74,13 +74,13 @@ to_chat(nif.human, type = MESSAGE_TYPE_NIF, - html = "\[[icon2html(nif.big_icon, nif.human)]NIF\] Soulcatcher displays, \"[message]\"") + html = "\[\icon[nif.big_icon][bicon(nif.big_icon)]NIF\] Soulcatcher displays, \"[message]\"") nif.human << sound for(var/mob/living/carbon/brain/caught_soul/CS as anything in brainmobs) to_chat(CS, type = MESSAGE_TYPE_NIF, - html = "\[[icon2html(nif.big_icon, CS.client)]NIF\] Soulcatcher displays, \"[message]\"") + html = "\[\icon[nif.big_icon][bicon(nif.big_icon)]NIF\] Soulcatcher displays, \"[message]\"") CS << sound /datum/nifsoft/soulcatcher/proc/say_into(var/message, var/mob/living/sender, var/mob/eyeobj) @@ -94,11 +94,11 @@ else to_chat(nif.human, type = MESSAGE_TYPE_NIF, - html = "\[[icon2html(nif.big_icon, nif.human.client)]NIF\] [sender_name] speaks, \"[message]\"") + html = "\[\icon[nif.big_icon][bicon(nif.big_icon)]NIF\] [sender_name] speaks, \"[message]\"") for(var/mob/living/carbon/brain/caught_soul/CS as anything in brainmobs) to_chat(CS, type = MESSAGE_TYPE_NIF, - html = "\[[icon2html(nif.big_icon, CS.client)]NIF\] [sender_name] speaks, \"[message]\"") + html = "\[\icon[nif.big_icon][bicon(nif.big_icon)]NIF\] [sender_name] speaks, \"[message]\"") log_nsay(message,nif.human.real_name,sender) @@ -113,11 +113,11 @@ else to_chat(nif.human, type = MESSAGE_TYPE_NIF, - html = "\[[icon2html(nif.big_icon,nif.human.client)]NIF\] [sender_name] [message]") + html = "\[\icon[nif.big_icon][bicon(nif.big_icon)]NIF\] [sender_name] [message]") for(var/mob/living/carbon/brain/caught_soul/CS as anything in brainmobs) to_chat(CS, type = MESSAGE_TYPE_NIF, - html = "\[[icon2html(nif.big_icon,CS.client)]NIF\] [sender_name] [message]") + html = "\[\icon[nif.big_icon][bicon(nif.big_icon)]NIF\] [sender_name] [message]") log_nme(message,nif.human.real_name,sender) @@ -420,8 +420,7 @@ real_name = brainmob.real_name //And the OTHER name forceMove(get_turf(parent_human)) - parent_human.AddComponent(/datum/component/recursive_move) - RegisterSignal(parent_human, COMSIG_OBSERVER_MOVED, /mob/observer/eye/ar_soul/proc/human_moved) + GLOB.moved_event.register(parent_human, src, /mob/observer/eye/ar_soul/proc/human_moved) //Time to play dressup if(brainmob.client.prefs) @@ -436,7 +435,7 @@ /mob/observer/eye/ar_soul/Destroy() if(parent_human) //It's POSSIBLE they've been deleted before the NIF somehow - UnregisterSignal(parent_human, COMSIG_OBSERVER_MOVED) + GLOB.moved_event.unregister(parent_human, src) parent_human = null return ..() diff --git a/code/modules/nifsoft/software/14_commlink.dm b/code/modules/nifsoft/software/14_commlink.dm index 79cac60fa98..47b602e184c 100644 --- a/code/modules/nifsoft/software/14_commlink.dm +++ b/code/modules/nifsoft/software/14_commlink.dm @@ -81,7 +81,7 @@ var/message = combined["formatted"] var/name_used = M.GetVoice() var/rendered = null - rendered = "[icon2html(icon_object,mob.client)] [name_used] [message]" + rendered = "\icon[icon_object][bicon(icon_object)] [name_used] [message]" mob.show_message(rendered, 2) //Not supported by the internal one diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm index 7ca9cde39ed..76283cdf513 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -87,21 +87,16 @@ if(parent && parent.children) parent.children -= src - parent = null if(children) for(var/obj/item/organ/external/C in children) - children -= C - C.parent = null qdel(C) if(internal_organs) for(var/obj/item/organ/O in internal_organs) - internal_organs -= O qdel(O) if(splinted && splinted.loc == src) - splinted.loc = null qdel(splinted) splinted = null diff --git a/code/modules/overmap/disperser/disperser_console.dm b/code/modules/overmap/disperser/disperser_console.dm index 2135d8830b6..a173163c17e 100644 --- a/code/modules/overmap/disperser/disperser_console.dm +++ b/code/modules/overmap/disperser/disperser_console.dm @@ -55,9 +55,9 @@ middle = M back = B if(is_valid_setup()) - RegisterSignal(F, COMSIG_OBSERVER_DESTROYED, PROC_REF(release_links)) - RegisterSignal(M, COMSIG_OBSERVER_DESTROYED, PROC_REF(release_links)) - RegisterSignal(B, COMSIG_OBSERVER_DESTROYED, PROC_REF(release_links)) + GLOB.destroyed_event.register(F, src, PROC_REF(release_links)) + GLOB.destroyed_event.register(M, src, PROC_REF(release_links)) + GLOB.destroyed_event.register(B, src, PROC_REF(release_links)) return TRUE return FALSE @@ -69,9 +69,9 @@ return FALSE /obj/machinery/computer/ship/disperser/proc/release_links() - UnregisterSignal(front, COMSIG_OBSERVER_DESTROYED) - UnregisterSignal(middle, COMSIG_OBSERVER_DESTROYED) - UnregisterSignal(back, COMSIG_OBSERVER_DESTROYED) + GLOB.destroyed_event.unregister(front, src, PROC_REF(release_links)) + GLOB.destroyed_event.unregister(middle, src, PROC_REF(release_links)) + GLOB.destroyed_event.unregister(back, src, PROC_REF(release_links)) front = null middle = null back = null diff --git a/code/modules/overmap/ships/computers/ship.dm b/code/modules/overmap/ships/computers/ship.dm index 31f6d39168b..8f52fdbe0b1 100644 --- a/code/modules/overmap/ships/computers/ship.dm +++ b/code/modules/overmap/ships/computers/ship.dm @@ -77,8 +77,7 @@ somewhere on that shuttle. Subtypes of these can be then used to perform ship ov L.looking_elsewhere = 1 L.handle_vision() user.set_viewsize(world.view + extra_view) - user.AddComponent(/datum/component/recursive_move) - RegisterSignal(user, COMSIG_OBSERVER_MOVED, /obj/machinery/computer/ship/proc/unlook, override = TRUE) //This needs override or else it will spam runtimes because it is called repeatedly. + GLOB.moved_event.register(user, src, /obj/machinery/computer/ship/proc/unlook) // TODO GLOB.stat_set_event.register(user, src, /obj/machinery/computer/ship/proc/unlook) LAZYDISTINCTADD(viewers, WEAKREF(user)) @@ -91,7 +90,7 @@ somewhere on that shuttle. Subtypes of these can be then used to perform ship ov L.looking_elsewhere = 0 L.handle_vision() user.set_viewsize() // reset to default - UnregisterSignal(user, COMSIG_OBSERVER_MOVED) + GLOB.moved_event.unregister(user, src, /obj/machinery/computer/ship/proc/unlook) // TODO GLOB.stat_set_event.unregister(user, src, /obj/machinery/computer/ship/proc/unlook) LAZYREMOVE(viewers, WEAKREF(user)) diff --git a/code/modules/overmap/ships/landable.dm b/code/modules/overmap/ships/landable.dm index 6c2e3e6e0b5..45c8386da53 100644 --- a/code/modules/overmap/ships/landable.dm +++ b/code/modules/overmap/ships/landable.dm @@ -10,8 +10,8 @@ icon_state = "shuttle_nosprite" /obj/effect/overmap/visitable/ship/landable/Destroy() - UnregisterSignal(SSshuttles.shuttles[shuttle], COMSIG_OBSERVER_SHUTTLE_PRE_MOVE) - UnregisterSignal(SSshuttles.shuttles[shuttle], COMSIG_OBSERVER_SHUTTLE_MOVED) + GLOB.shuttle_pre_move_event.unregister(SSshuttles.shuttles[shuttle], src) + GLOB.shuttle_moved_event.unregister(SSshuttles.shuttles[shuttle], src) return ..() /obj/effect/overmap/visitable/ship/landable/can_burn() @@ -71,8 +71,8 @@ if(istype(shuttle_datum,/datum/shuttle/autodock/overmap)) var/datum/shuttle/autodock/overmap/oms = shuttle_datum oms.myship = src - RegisterSignal(shuttle_datum, COMSIG_OBSERVER_SHUTTLE_PRE_MOVE, PROC_REF(pre_shuttle_jump)) - RegisterSignal(shuttle_datum, COMSIG_OBSERVER_SHUTTLE_MOVED, PROC_REF(on_shuttle_jump)) + GLOB.shuttle_pre_move_event.register(shuttle_datum, src, PROC_REF(pre_shuttle_jump)) + GLOB.shuttle_moved_event.register(shuttle_datum, src, PROC_REF(on_shuttle_jump)) on_landing(landmark, shuttle_datum.current_location) // We "land" at round start to properly place ourselves on the overmap. @@ -123,11 +123,11 @@ core_landmark = master name = _name landmark_tag = master.shuttle_name + _name - RegisterSignal(master, COMSIG_OBSERVER_DESTROYED, /datum/proc/qdel_self) + GLOB.destroyed_event.register(master, src, /datum/proc/qdel_self) . = ..() /obj/effect/shuttle_landmark/visiting_shuttle/Destroy() - UnregisterSignal(core_landmark, COMSIG_OBSERVER_DESTROYED) + GLOB.destroyed_event.unregister(core_landmark, src) LAZYREMOVE(core_landmark.visitors, src) core_landmark = null . = ..() @@ -144,11 +144,11 @@ /obj/effect/shuttle_landmark/visiting_shuttle/shuttle_arrived(datum/shuttle/shuttle) LAZYSET(core_landmark.visitors, src, shuttle) - RegisterSignal(shuttle, COMSIG_OBSERVER_SHUTTLE_MOVED, PROC_REF(shuttle_left)) + GLOB.shuttle_moved_event.register(shuttle, src, PROC_REF(shuttle_left)) /obj/effect/shuttle_landmark/visiting_shuttle/proc/shuttle_left(datum/shuttle/shuttle, obj/effect/shuttle_landmark/old_landmark, obj/effect/shuttle_landmark/new_landmark) if(old_landmark == src) - UnregisterSignal(shuttle, COMSIG_OBSERVER_SHUTTLE_MOVED) + GLOB.shuttle_moved_event.unregister(shuttle, src) LAZYREMOVE(core_landmark.visitors, src) // @@ -160,7 +160,7 @@ return if(into == landmark) setup_overmap_location() // They're coming boys, better actually exist! - UnregisterSignal(SSshuttles.shuttles[shuttle], COMSIG_OBSERVER_SHUTTLE_PRE_MOVE) + GLOB.shuttle_pre_move_event.unregister(SSshuttles.shuttles[shuttle], src) /obj/effect/overmap/visitable/ship/landable/proc/on_shuttle_jump(datum/shuttle/given_shuttle, obj/effect/shuttle_landmark/from, obj/effect/shuttle_landmark/into) if(given_shuttle != SSshuttles.shuttles[shuttle]) diff --git a/code/modules/paperwork/paper_sticky.dm b/code/modules/paperwork/paper_sticky.dm index 32f92cea6f6..ba2a9195b3b 100644 --- a/code/modules/paperwork/paper_sticky.dm +++ b/code/modules/paperwork/paper_sticky.dm @@ -97,8 +97,7 @@ /obj/item/weapon/paper/sticky/Initialize() . = ..() - AddComponent(/datum/component/recursive_move) - RegisterSignal(src, COMSIG_OBSERVER_MOVED, /obj/item/weapon/paper/sticky/proc/reset_persistence_tracking) + GLOB.moved_event.register(src, src, /obj/item/weapon/paper/sticky/proc/reset_persistence_tracking) /obj/item/weapon/paper/sticky/proc/reset_persistence_tracking() SSpersistence.forget_value(src, /datum/persistent/paper/sticky) @@ -107,7 +106,7 @@ /obj/item/weapon/paper/sticky/Destroy() reset_persistence_tracking() - UnregisterSignal(src, COMSIG_OBSERVER_MOVED) + GLOB.moved_event.unregister(src, src) . = ..() /obj/item/weapon/paper/sticky/update_icon() @@ -150,4 +149,4 @@ if(dir_offset & NORTH) pixel_y += 32 else if(dir_offset & SOUTH) - pixel_y -= 32 + pixel_y -= 32 \ No newline at end of file diff --git a/code/modules/pda/app.dm b/code/modules/pda/app.dm index 4e508838e9f..c86f9e507d1 100644 --- a/code/modules/pda/app.dm +++ b/code/modules/pda/app.dm @@ -34,7 +34,7 @@ L = get(pda, /mob/living/silicon) if(L) - to_chat(L, "[icon2html(pda,L.client)] [message]") + to_chat(L, "\icon[pda][bicon(pda)] [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) diff --git a/code/modules/pda/messenger.dm b/code/modules/pda/messenger.dm index 29810e398c8..829fc9a431a 100644 --- a/code/modules/pda/messenger.dm +++ b/code/modules/pda/messenger.dm @@ -181,7 +181,7 @@ SStgui.update_user_uis(U, P) // Update the sending user's PDA UI so that they can see the new message log_pda("(PDA: [src.name]) sent \"[t]\" to [P.name]", usr) - to_chat(U, "[icon2html(pda,U.client)] Sent message to [P.owner] ([P.ownjob]), \"[t]\"") + to_chat(U, "\icon[pda][bicon(pda)] Sent message to [P.owner] ([P.ownjob]), \"[t]\"") else to_chat(U, "ERROR: Messaging server is not responding.") diff --git a/code/modules/pda/pda.dm b/code/modules/pda/pda.dm index daad415ef7a..cd9d011e406 100644 --- a/code/modules/pda/pda.dm +++ b/code/modules/pda/pda.dm @@ -112,7 +112,7 @@ var/global/list/obj/item/device/pda/PDAs = list() S = 'sound/machines/twobeep.ogg' playsound(loc, S, 50, 1) for(var/mob/O in hearers(3, loc)) - O.show_message(text("[icon2html(src, O.client)] *[ttone]*")) + O.show_message(text("\icon[src][bicon(src)] *[ttone]*")) /obj/item/device/pda/proc/set_ringtone() var/t = tgui_input_text(usr, "Please enter new ringtone", name, ttone) @@ -145,7 +145,7 @@ var/global/list/obj/item/device/pda/PDAs = list() model_name = "Thinktronic 5230 Personal Data Assistant" if(2) icon = 'icons/obj/pda_slim.dmi' - model_name = "Ward-Takahashi SlimFit� Personal Data Assistant" + model_name = "Ward-Takahashi SlimFit™ Personal Data Assistant" if(3) icon = 'icons/obj/pda_old.dmi' model_name = "Thinktronic 5120 Personal Data Assistant" @@ -172,7 +172,7 @@ var/global/list/obj/item/device/pda/PDAs = list() ) if(7) icon = 'icons/obj/pda_slider.dmi' //VOREStation edit - model_name = "Slider� Personal Data Assistant" + model_name = "Slider® Personal Data Assistant" if(8) icon = 'icons/obj/pda_vintage.dmi' model_name = "\[ERR:INVALID_MANUFACTURER_ID\] Personal Data Assistant" diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 6c2aafb0c8d..87b480576a5 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -523,7 +523,7 @@ return 2 //just assume we can shoot through glass and stuff. No big deal, the player can just choose to not target someone //on the other side of a window if it makes a difference. Or if they run behind a window, too bad. - if(target in check_trajectory(target, user)) + if(check_trajectory(target, user)) return 1 // Magic numbers are fun. //called if there was no projectile to shoot diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index fe438ead6d7..a73c6337959 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -41,7 +41,6 @@ var/ricochets_max = 2 var/ricochet_chance = 30 var/can_miss = TRUE - var/bump_targets = TRUE //Should we bump and/or attack objects we hit? Used only for 'raytraces' e.g. subtype /test //Hitscan var/hitscan = FALSE //Whether this is hitscan. If it is, speed is basically ignored. @@ -146,14 +145,6 @@ var/hud_state = "unknown" // What HUD state we use when we have ammunition. var/hud_state_empty = "unknown" // The empty state. DON'T USE _FLASH IN THE NAME OF THE EMPTY STATE STRING, THAT IS ADDED BY THE CODE. - var/obj/item/ammo_casing/my_case = null - - -/obj/item/projectile/New() - if(istype(loc, /obj/item/ammo_casing)) - my_case = loc - . = ..() - /obj/item/projectile/proc/Range() range-- if(range <= 0 && loc) @@ -240,7 +231,7 @@ after_move() if(can_hit_target(original, permutated)) Bump(original) - if(!hitscanning && !forcemoved && trajectory) + if(!hitscanning && !forcemoved) pixel_x = trajectory.return_px() - trajectory.mpx * trajectory_multiplier * SSprojectiles.global_iterations_per_move pixel_y = trajectory.return_py() - trajectory.mpy * trajectory_multiplier * SSprojectiles.global_iterations_per_move animate(src, pixel_x = trajectory.return_px(), pixel_y = trajectory.return_py(), time = 1, flags = ANIMATION_END_NOW) @@ -329,8 +320,7 @@ /obj/item/projectile/proc/fire(angle, atom/direct_target) //If no angle needs to resolve it from xo/yo! if(direct_target) - if(bump_targets) - direct_target.bullet_act(src, def_zone) + direct_target.bullet_act(src, def_zone) qdel(src) return if(isnum(angle)) @@ -469,16 +459,7 @@ impacted_mobs.Cut() impacted_mobs = null - trajectory = null - beam_index = null - beam_components = null - - - if(my_case) - if(my_case.BB == src) - my_case.BB = null - my_case = null - + qdel(trajectory) return ..() /obj/item/projectile/proc/cleanup_beam_segments() @@ -584,31 +565,25 @@ var/shield_chance = min(80, (30 * (M.mob_size / 10))) //Small mobs have a harder time keeping a dead body as a shield than a human-sized one. Unathi would have an easier job, if they are made to be SIZE_LARGE in the future. -Mech if(prob(shield_chance)) visible_message("\The [M] uses [G.affecting] as a shield!") - if(bump_targets) - if(Bump(G.affecting)) - return + if(Bump(G.affecting)) + return else visible_message("\The [M] tries to use [G.affecting] as a shield, but fails!") else visible_message("\The [M] uses [G.affecting] as a shield!") - if(bump_targets) - if(Bump(G.affecting)) - return //If Bump() returns 0 (keep going) then we continue on to attack M. + if(Bump(G.affecting)) + return //If Bump() returns 0 (keep going) then we continue on to attack M. - if(bump_targets) - passthrough = !attack_mob(M, distance) - else - passthrough = 1 //Projectiles that don't bump (raytraces) always pass through + passthrough = !attack_mob(M, distance) else passthrough = 1 //so ghosts don't stop bullets else passthrough = (A.bullet_act(src, def_zone) == PROJECTILE_CONTINUE) //backwards compatibility - if(bump_targets) // only attack/act a turf's contents if our projectile is not a raytrace - if(isturf(A)) - for(var/obj/O in A) - O.bullet_act(src) - for(var/mob/living/M in A) - attack_mob(M, distance) + if(isturf(A)) + for(var/obj/O in A) + O.bullet_act(src) + for(var/mob/living/M in A) + attack_mob(M, distance) //penetrating projectiles can pass through things that otherwise would not let them if(!passthrough && penetrating > 0) @@ -623,7 +598,7 @@ trajectory_ignore_forcemove = FALSE return FALSE - if(A && bump_targets) + if(A) on_impact(A) qdel(src) return TRUE @@ -666,9 +641,7 @@ return 1 /obj/item/projectile/proc/check_fire(atom/target as mob, mob/living/user as mob) //Checks if you can hit them or not. - if(target in check_trajectory(target, user, pass_flags, flags)) - return TRUE - return FALSE + check_trajectory(target, user, pass_flags, flags) /obj/item/projectile/CanPass() return TRUE diff --git a/code/modules/projectiles/projectile/trace.dm b/code/modules/projectiles/projectile/trace.dm index ccb13ad7beb..aaf7b9a7b6d 100644 --- a/code/modules/projectiles/projectile/trace.dm +++ b/code/modules/projectiles/projectile/trace.dm @@ -14,9 +14,7 @@ return trace.launch_projectile(target) //Test it! /obj/item/projectile/proc/_check_fire(atom/target as mob, var/mob/living/user as mob) //Checks if you can hit them or not. - if(target in check_trajectory(target, user, pass_flags, flags)) - return TRUE - return FALSE + check_trajectory(target, user, pass_flags, flags) //"Tracing" projectile /obj/item/projectile/test //Used to see if you can hit them. @@ -24,7 +22,6 @@ hitscan = TRUE nodamage = TRUE damage = 0 - bump_targets = FALSE var/list/hit = list() /obj/item/projectile/test/process_hitscan() @@ -36,24 +33,7 @@ /obj/item/projectile/test/Bump(atom/A) if(A != src) hit |= A - if(isturf(A)) - for(var/obj/O in A) - hit |= A - for(var/mob/living/M in A) - hit |= A return ..() -/obj/item/projectile/test/fire(angle, atom/direct_target) - . = ..() - if(direct_target) - if(direct_target != src) - hit |= direct_target - . = hit - - /obj/item/projectile/test/attack_mob() return - -//Don't generate tracers - they are generated on Destroy() -/obj/item/projectile/test/finalize_hitscan_and_generate_tracers() - return diff --git a/code/modules/reagents/Chemistry-Metabolism.dm b/code/modules/reagents/Chemistry-Metabolism.dm index d979b5cc173..671e8110f1d 100644 --- a/code/modules/reagents/Chemistry-Metabolism.dm +++ b/code/modules/reagents/Chemistry-Metabolism.dm @@ -31,4 +31,4 @@ metabolism_speed = 0.5 /datum/reagents/metabolism/touch - metabolism_class = CHEM_TOUCH + metabolism_class = CHEM_TOUCH \ No newline at end of file diff --git a/code/modules/reagents/reactions/_reactions.dm b/code/modules/reagents/reactions/_reactions.dm index b3e242ba702..61c926153ec 100644 --- a/code/modules/reagents/reactions/_reactions.dm +++ b/code/modules/reagents/reactions/_reactions.dm @@ -119,10 +119,10 @@ var/list/seen = viewers(4, T) for(var/mob/M in seen) if(M.client) - M.show_message("[icon2html(container,M.client)] [mix_message]", 1) + M.show_message("\icon[container][bicon(container)] [mix_message]", 1) playsound(T, reaction_sound, 80, 1) //obtains any special data that will be provided to the reaction products //this is called just before reactants are removed. /decl/chemical_reaction/proc/send_data(var/datum/reagents/holder, var/reaction_limit) - return null + return null \ No newline at end of file diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm index 8eff337f577..693f8cbeef4 100644 --- a/code/modules/recycling/disposal.dm +++ b/code/modules/recycling/disposal.dm @@ -747,15 +747,7 @@ return /obj/structure/disposalholder/Destroy() - QDEL_NULL(gas) - if(contents.len) - var/turf/qdelloc = get_turf(src) - if(qdelloc) - for(var/atom/movable/AM in contents) - AM.loc = qdelloc - else - log_and_message_admins("A disposal holder was deleted with contents in nullspace") //ideally, this should never happen - + qdel(gas) active = 0 return ..() diff --git a/code/modules/research/circuitprinter.dm b/code/modules/research/circuitprinter.dm index 2f45135a239..6a74b9829c8 100644 --- a/code/modules/research/circuitprinter.dm +++ b/code/modules/research/circuitprinter.dm @@ -60,7 +60,7 @@ using metal and glass, it uses glass and reagents (usually sulphuric acid). update_icon() else if(busy) - visible_message("[icon2html(src,viewers(src))] flashes: insufficient materials: [getLackingMaterials(D)].") + visible_message("\icon [src] flashes: insufficient materials: [getLackingMaterials(D)].") busy = 0 update_icon() diff --git a/code/modules/research/message_server.dm b/code/modules/research/message_server.dm index 5d65c6f9a23..23516eeb17a 100644 --- a/code/modules/research/message_server.dm +++ b/code/modules/research/message_server.dm @@ -131,12 +131,12 @@ var/global/list/obj/machinery/message_server/message_servers = list() if(2) if(!Console.silent) playsound(Console, 'sound/machines/twobeep.ogg', 50, 1) - Console.audible_message(text("[icon2html(Console,hearers(Console))] *The Requests Console beeps: 'PRIORITY Alert in [sender]'"),,5, runemessage = "beep! beep!") + Console.audible_message(text("\icon[Console][bicon(Console)] *The Requests Console beeps: 'PRIORITY Alert in [sender]'"),,5, runemessage = "beep! beep!") Console.message_log += list(list("High Priority message from [sender]", "[authmsg]")) else if(!Console.silent) playsound(Console, 'sound/machines/twobeep.ogg', 50, 1) - Console.audible_message(text("[icon2html(Console,hearers(Console))] *The Requests Console beeps: 'Message from [sender]'"),,4, runemessage = "beep beep") + Console.audible_message(text("\icon[Console][bicon(Console)] *The Requests Console beeps: 'Message from [sender]'"),,4, runemessage = "beep beep") Console.message_log += list(list("Message from [sender]", "[authmsg]")) Console.set_light(2) diff --git a/code/modules/research/protolathe.dm b/code/modules/research/protolathe.dm index 57474f3bc1b..b00b98523ea 100644 --- a/code/modules/research/protolathe.dm +++ b/code/modules/research/protolathe.dm @@ -75,7 +75,7 @@ update_icon() else if(busy) - visible_message("[icon2html(src,viewers(src))] flashes: insufficient materials: [getLackingMaterials(D)].") + visible_message("\icon [src] flashes: insufficient materials: [getLackingMaterials(D)].") busy = 0 update_icon() @@ -270,7 +270,7 @@ // Reduce our amount stored materials[matstring] -= ejected * S.perunit - + // Recurse if we have enough left for more sheets if(recursive && materials[matstring] >= S.perunit) eject_materials(matstring, -1) diff --git a/code/modules/scripting/AST/AST Nodes.dm b/code/modules/scripting/AST/AST Nodes.dm index ceeacdcdc30..941d63ba135 100644 --- a/code/modules/scripting/AST/AST Nodes.dm +++ b/code/modules/scripting/AST/AST Nodes.dm @@ -64,16 +64,16 @@ var Class: operator See and for subtypes. */ -/node/expression/op +/node/expression/operator var/node/expression/exp var/tmp/name var/tmp/precedence -/node/expression/op/New() +/node/expression/operator/New() .=..() if(!src.name) src.name="[src.type]" -/node/expression/op/ToString() +/node/expression/operator/ToString() return "operator: [name]" /* @@ -125,4 +125,4 @@ var src.value=value /node/expression/value/reference/ToString() - return "ref: [src.value] ([src.value.type])" + return "ref: [src.value] ([src.value.type])" \ No newline at end of file diff --git a/code/modules/scripting/AST/Operators/Binary Operators.dm b/code/modules/scripting/AST/Operators/Binary Operators.dm index 71d9517197d..42e00db0c78 100644 --- a/code/modules/scripting/AST/Operators/Binary Operators.dm +++ b/code/modules/scripting/AST/Operators/Binary Operators.dm @@ -7,7 +7,7 @@ Class: binary Represents a binary operator in the AST. A binary operator takes two operands (ie x and y) and returns a value. */ -/node/expression/op/binary +/node/expression/operator/binary var/node/expression/exp2 ////////// Comparison Operators ////////// @@ -16,7 +16,7 @@ Returns true if x = y. */ // -/node/expression/op/binary/Equal +/node/expression/operator/binary/Equal precedence=OOP_EQUAL /* @@ -24,7 +24,7 @@ Returns true if x and y aren't equal. */ // -/node/expression/op/binary/NotEqual +/node/expression/operator/binary/NotEqual precedence=OOP_EQUAL /* @@ -32,7 +32,7 @@ Returns true if x > y. */ // -/node/expression/op/binary/Greater +/node/expression/operator/binary/Greater precedence=OOP_COMPARE /* @@ -40,7 +40,7 @@ Returns true if x < y. */ // -/node/expression/op/binary/Less +/node/expression/operator/binary/Less precedence=OOP_COMPARE /* @@ -48,7 +48,7 @@ Returns true if x >= y. */ // -/node/expression/op/binary/GreaterOrEqual +/node/expression/operator/binary/GreaterOrEqual precedence=OOP_COMPARE /* @@ -56,7 +56,7 @@ Returns true if x <= y. */ // -/node/expression/op/binary/LessOrEqual +/node/expression/operator/binary/LessOrEqual precedence=OOP_COMPARE @@ -67,7 +67,7 @@ Returns true if x and y are true. */ // -/node/expression/op/binary/LogicalAnd +/node/expression/operator/binary/LogicalAnd precedence=OOP_AND /* @@ -75,7 +75,7 @@ Returns true if x, y, or both are true. */ // -/node/expression/op/binary/LogicalOr +/node/expression/operator/binary/LogicalOr precedence=OOP_OR /* @@ -83,7 +83,7 @@ Returns true if either x or y but not both are true. */ // -/node/expression/op/binary/LogicalXor //Not implemented in nS +/node/expression/operator/binary/LogicalXor //Not implemented in nS precedence=OOP_OR @@ -97,7 +97,7 @@ 011 & 110 = 010 */ // -/node/expression/op/binary/BitwiseAnd +/node/expression/operator/binary/BitwiseAnd precedence=OOP_BIT /* @@ -108,7 +108,7 @@ 011 | 110 = 111 */ // -/node/expression/op/binary/BitwiseOr +/node/expression/operator/binary/BitwiseOr precedence=OOP_BIT /* @@ -119,7 +119,7 @@ 011 xor 110 = 101 */ // -/node/expression/op/binary/BitwiseXor +/node/expression/operator/binary/BitwiseXor precedence=OOP_BIT @@ -130,7 +130,7 @@ Returns the sum of x and y. */ // -/node/expression/op/binary/Add +/node/expression/operator/binary/Add precedence=OOP_ADD /* @@ -138,7 +138,7 @@ Returns the difference of x and y. */ // -/node/expression/op/binary/Subtract +/node/expression/operator/binary/Subtract precedence=OOP_ADD /* @@ -146,7 +146,7 @@ Returns the product of x and y. */ // -/node/expression/op/binary/Multiply +/node/expression/operator/binary/Multiply precedence=OOP_MULTIPLY /* @@ -154,7 +154,7 @@ Returns the quotient of x and y. */ // -/node/expression/op/binary/Divide +/node/expression/operator/binary/Divide precedence=OOP_MULTIPLY /* @@ -162,7 +162,7 @@ Returns x raised to the power of y. */ // -/node/expression/op/binary/Power +/node/expression/operator/binary/Power precedence=OOP_POW /* @@ -170,5 +170,5 @@ Returns the remainder of x / y. */ // -/node/expression/op/binary/Modulo +/node/expression/operator/binary/Modulo precedence=OOP_MULTIPLY diff --git a/code/modules/scripting/AST/Operators/Unary Operators.dm b/code/modules/scripting/AST/Operators/Unary Operators.dm index 07bb79a8c5b..ccfbc3ca3b1 100644 --- a/code/modules/scripting/AST/Operators/Unary Operators.dm +++ b/code/modules/scripting/AST/Operators/Unary Operators.dm @@ -5,7 +5,7 @@ Class: unary Represents a unary operator in the AST. Unary operators take a single operand (referred to as x below) and return a value. */ -/node/expression/op/unary +/node/expression/operator/unary precedence=OOP_UNARY /* @@ -16,7 +16,7 @@ !true = false and !false = true */ // -/node/expression/op/unary/LogicalNot +/node/expression/operator/unary/LogicalNot name="logical not" /* @@ -27,7 +27,7 @@ ~10 (decimal 2) = 01 (decimal 1). */ // -/node/expression/op/unary/BitwiseNot +/node/expression/operator/unary/BitwiseNot name="bitwise not" /* @@ -35,7 +35,7 @@ Returns -x. */ // -/node/expression/op/unary/Minus +/node/expression/operator/unary/Minus name="minus" /* @@ -43,9 +43,9 @@ A special unary operator representing a value in parentheses. */ // -/node/expression/op/unary/group +/node/expression/operator/unary/group precedence=OOP_GROUP -/node/expression/op/unary/New(node/expression/exp) +/node/expression/operator/unary/New(node/expression/exp) src.exp=exp return ..() diff --git a/code/modules/scripting/Interpreter/Evaluation.dm b/code/modules/scripting/Interpreter/Evaluation.dm index be488c9ddba..2cc90506b4f 100644 --- a/code/modules/scripting/Interpreter/Evaluation.dm +++ b/code/modules/scripting/Interpreter/Evaluation.dm @@ -4,7 +4,7 @@ /n_Interpreter/proc/Eval(node/expression/exp) if(istype(exp, /node/expression/FunctionCall)) return RunFunction(exp) - else if(istype(exp, /node/expression/op)) + else if(istype(exp, /node/expression/operator)) return EvalOperator(exp) else if(istype(exp, /node/expression/value/literal)) var/node/expression/value/literal/lit=exp @@ -34,57 +34,57 @@ else return exp -/n_Interpreter/proc/EvalOperator(node/expression/op/exp) - if(istype(exp, /node/expression/op/binary)) - var/node/expression/op/binary/bin=exp +/n_Interpreter/proc/EvalOperator(node/expression/operator/exp) + if(istype(exp, /node/expression/operator/binary)) + var/node/expression/operator/binary/bin=exp switch(bin.type) - if(/node/expression/op/binary/Equal) + if(/node/expression/operator/binary/Equal) return Equal(Eval(bin.exp), Eval(bin.exp2)) - if(/node/expression/op/binary/NotEqual) + if(/node/expression/operator/binary/NotEqual) return NotEqual(Eval(bin.exp), Eval(bin.exp2)) - if(/node/expression/op/binary/Greater) + if(/node/expression/operator/binary/Greater) return Greater(Eval(bin.exp), Eval(bin.exp2)) - if(/node/expression/op/binary/Less) + if(/node/expression/operator/binary/Less) return Less(Eval(bin.exp), Eval(bin.exp2)) - if(/node/expression/op/binary/GreaterOrEqual) + if(/node/expression/operator/binary/GreaterOrEqual) return GreaterOrEqual(Eval(bin.exp), Eval(bin.exp2)) - if(/node/expression/op/binary/LessOrEqual) + if(/node/expression/operator/binary/LessOrEqual) return LessOrEqual(Eval(bin.exp), Eval(bin.exp2)) - if(/node/expression/op/binary/LogicalAnd) + if(/node/expression/operator/binary/LogicalAnd) return LogicalAnd(Eval(bin.exp), Eval(bin.exp2)) - if(/node/expression/op/binary/LogicalOr) + if(/node/expression/operator/binary/LogicalOr) return LogicalOr(Eval(bin.exp), Eval(bin.exp2)) - if(/node/expression/op/binary/LogicalXor) + if(/node/expression/operator/binary/LogicalXor) return LogicalXor(Eval(bin.exp), Eval(bin.exp2)) - if(/node/expression/op/binary/BitwiseAnd) + if(/node/expression/operator/binary/BitwiseAnd) return BitwiseAnd(Eval(bin.exp), Eval(bin.exp2)) - if(/node/expression/op/binary/BitwiseOr) + if(/node/expression/operator/binary/BitwiseOr) return BitwiseOr(Eval(bin.exp), Eval(bin.exp2)) - if(/node/expression/op/binary/BitwiseXor) + if(/node/expression/operator/binary/BitwiseXor) return BitwiseXor(Eval(bin.exp), Eval(bin.exp2)) - if(/node/expression/op/binary/Add) + if(/node/expression/operator/binary/Add) return Add(Eval(bin.exp), Eval(bin.exp2)) - if(/node/expression/op/binary/Subtract) + if(/node/expression/operator/binary/Subtract) return Subtract(Eval(bin.exp), Eval(bin.exp2)) - if(/node/expression/op/binary/Multiply) + if(/node/expression/operator/binary/Multiply) return Multiply(Eval(bin.exp), Eval(bin.exp2)) - if(/node/expression/op/binary/Divide) + if(/node/expression/operator/binary/Divide) return Divide(Eval(bin.exp), Eval(bin.exp2)) - if(/node/expression/op/binary/Power) + if(/node/expression/operator/binary/Power) return Power(Eval(bin.exp), Eval(bin.exp2)) - if(/node/expression/op/binary/Modulo) + if(/node/expression/operator/binary/Modulo) return Modulo(Eval(bin.exp), Eval(bin.exp2)) else RaiseError(new/runtimeError/UnknownInstruction()) return switch(exp.type) - if(/node/expression/op/unary/Minus) + if(/node/expression/operator/unary/Minus) return Minus(Eval(exp.exp)) - if(/node/expression/op/unary/LogicalNot) + if(/node/expression/operator/unary/LogicalNot) return LogicalNot(Eval(exp.exp)) - if(/node/expression/op/unary/BitwiseNot) + if(/node/expression/operator/unary/BitwiseNot) return BitwiseNot(Eval(exp.exp)) - if(/node/expression/op/unary/group) + if(/node/expression/operator/unary/group) return Eval(exp.exp) else RaiseError(new/runtimeError/UnknownInstruction()) @@ -164,4 +164,4 @@ //Unary// /n_Interpreter/proc/Minus(a) return -a /n_Interpreter/proc/LogicalNot(a) return !a -/n_Interpreter/proc/BitwiseNot(a) return ~a +/n_Interpreter/proc/BitwiseNot(a) return ~a \ No newline at end of file diff --git a/code/modules/scripting/Options.dm b/code/modules/scripting/Options.dm index 1dd35da43b9..cc9e0308ca3 100644 --- a/code/modules/scripting/Options.dm +++ b/code/modules/scripting/Options.dm @@ -70,31 +70,31 @@ associated values are types of which the proc w ) var/list/unary_operators =list( - "!" = /node/expression/op/unary/LogicalNot, - "~" = /node/expression/op/unary/BitwiseNot, - "-" = /node/expression/op/unary/Minus + "!" = /node/expression/operator/unary/LogicalNot, + "~" = /node/expression/operator/unary/BitwiseNot, + "-" = /node/expression/operator/unary/Minus ) var/list/binary_operators=list( - "==" = /node/expression/op/binary/Equal, - "!=" = /node/expression/op/binary/NotEqual, - ">" = /node/expression/op/binary/Greater, - "<" = /node/expression/op/binary/Less, - ">=" = /node/expression/op/binary/GreaterOrEqual, - "<=" = /node/expression/op/binary/LessOrEqual, - "&&" = /node/expression/op/binary/LogicalAnd, - "||" = /node/expression/op/binary/LogicalOr, - "&" = /node/expression/op/binary/BitwiseAnd, - "|" = /node/expression/op/binary/BitwiseOr, - "`" = /node/expression/op/binary/BitwiseXor, - "+" = /node/expression/op/binary/Add, - "-" = /node/expression/op/binary/Subtract, - "*" = /node/expression/op/binary/Multiply, - "/" = /node/expression/op/binary/Divide, - "^" = /node/expression/op/binary/Power, - "%" = /node/expression/op/binary/Modulo) + "==" = /node/expression/operator/binary/Equal, + "!=" = /node/expression/operator/binary/NotEqual, + ">" = /node/expression/operator/binary/Greater, + "<" = /node/expression/operator/binary/Less, + ">=" = /node/expression/operator/binary/GreaterOrEqual, + "<=" = /node/expression/operator/binary/LessOrEqual, + "&&" = /node/expression/operator/binary/LogicalAnd, + "||" = /node/expression/operator/binary/LogicalOr, + "&" = /node/expression/operator/binary/BitwiseAnd, + "|" = /node/expression/operator/binary/BitwiseOr, + "`" = /node/expression/operator/binary/BitwiseXor, + "+" = /node/expression/operator/binary/Add, + "-" = /node/expression/operator/binary/Subtract, + "*" = /node/expression/operator/binary/Multiply, + "/" = /node/expression/operator/binary/Divide, + "^" = /node/expression/operator/binary/Power, + "%" = /node/expression/operator/binary/Modulo) /n_scriptOptions/nS_Options/New() .=..() for(var/O in assign_operators+binary_operators+unary_operators) - if(!symbols.Find(O)) symbols+=O + if(!symbols.Find(O)) symbols+=O \ No newline at end of file diff --git a/code/modules/scripting/Parser/Expressions.dm b/code/modules/scripting/Parser/Expressions.dm index 1e25c9be698..c90a08254e6 100644 --- a/code/modules/scripting/Parser/Expressions.dm +++ b/code/modules/scripting/Parser/Expressions.dm @@ -30,7 +30,7 @@ Proc: Precedence Compares two operators, decides which is higher in the order of operations, and returns or . */ -/n_Parser/nS_Parser/proc/Precedence(node/expression/op/top, node/expression/op/input) +/n_Parser/nS_Parser/proc/Precedence(node/expression/operator/top, node/expression/operator/input) if(istype(top)) top=top.precedence if(istype(input)) @@ -88,7 +88,7 @@ See Also: - - */ -/n_Parser/nS_Parser/proc/GetOperator(O, type=/node/expression/op, L[]) +/n_Parser/nS_Parser/proc/GetOperator(O, type=/node/expression/operator, L[]) if(istype(O, type)) return O //O is already the desired type if(istype(O, /token)) O=O:value //sets O to text if(istext(O)) //sets O to path @@ -108,7 +108,7 @@ See Also: - */ /n_Parser/nS_Parser/proc/GetBinaryOperator(O) - return GetOperator(O, /node/expression/op/binary, options.binary_operators) + return GetOperator(O, /node/expression/operator/binary, options.binary_operators) /* Proc: GetUnaryOperator @@ -120,7 +120,7 @@ See Also: - */ /n_Parser/nS_Parser/proc/GetUnaryOperator(O) - return GetOperator(O, /node/expression/op/unary, options.unary_operators) + return GetOperator(O, /node/expression/operator/unary, options.unary_operators) /* Proc: Reduce @@ -128,15 +128,15 @@ Takes the operator on top of the opr stack and assigns its operand(s). Then this of the val stack. */ /n_Parser/nS_Parser/proc/Reduce(stack/opr, stack/val) - var/node/expression/op/O=opr.Pop() + var/node/expression/operator/O=opr.Pop() if(!O) return if(!istype(O)) errors+=new/scriptError("Error reducing expression - invalid operator.") return //Take O and assign its operands, popping one or two values from the val stack //depending on whether O is a binary or unary operator. - if(istype(O, /node/expression/op/binary)) - var/node/expression/op/binary/B=O + if(istype(O, /node/expression/operator/binary)) + var/node/expression/operator/binary/B=O B.exp2=val.Pop() B.exp =val.Pop() val.Push(B) @@ -203,7 +203,7 @@ See Also: continue val.Push(ParseParenExpression()) else if(istype(curToken, /token/symbol)) //Operator found. - var/node/expression/op/curOperator //Figure out whether it is unary or binary and get a new instance. + var/node/expression/operator/curOperator //Figure out whether it is unary or binary and get a new instance. if(src.expecting==OPERATOR) curOperator=GetBinaryOperator(curToken) if(!curOperator) @@ -297,7 +297,7 @@ See Also: /n_Parser/nS_Parser/proc/ParseParenExpression() if(!CheckToken("(", /token/symbol)) return - return new/node/expression/op/unary/group(ParseExpression(list(")"))) + return new/node/expression/operator/unary/group(ParseExpression(list(")"))) /* Proc: ParseParamExpression @@ -307,4 +307,4 @@ See Also: - */ /n_Parser/nS_Parser/proc/ParseParamExpression() - return ParseExpression(list(",", ")")) + return ParseExpression(list(",", ")")) \ No newline at end of file diff --git a/code/modules/shieldgen/directional_shield.dm b/code/modules/shieldgen/directional_shield.dm index 204f47b0003..6754878674f 100644 --- a/code/modules/shieldgen/directional_shield.dm +++ b/code/modules/shieldgen/directional_shield.dm @@ -100,20 +100,15 @@ /obj/item/shield_projector/Initialize() START_PROCESSING(SSobj, src) - AddComponent(/datum/component/recursive_move) - RegisterSignal(src, COMSIG_OBSERVER_MOVED, PROC_REF(moved_event)) - //ChompEDIT START - shields on init if(always_on) - spawn(0) - if(!QDELETED(src)) - create_shields() - //ChompEDIT END + create_shields() + GLOB.moved_event.register(src, src, PROC_REF(moved_event)) return ..() /obj/item/shield_projector/Destroy() destroy_shields() STOP_PROCESSING(SSobj, src) - UnregisterSignal(src, COMSIG_OBSERVER_MOVED) + GLOB.moved_event.unregister(src, src, PROC_REF(moved_event)) return ..() /obj/item/shield_projector/proc/moved_event() diff --git a/code/modules/shieldgen/emergency_shield.dm b/code/modules/shieldgen/emergency_shield.dm index a7f9b851b6f..49610cbcd07 100644 --- a/code/modules/shieldgen/emergency_shield.dm +++ b/code/modules/shieldgen/emergency_shield.dm @@ -259,14 +259,14 @@ return if (src.active) - user.visible_message(span_blue("[icon2html(src,viewers(src))] [user] deactivated the shield generator."), \ - span_blue("[icon2html(src,user.client)] You deactivate the shield generator."), \ + user.visible_message(span_blue("\icon[src][bicon(src)] [user] deactivated the shield generator."), \ + span_blue("\icon[src][bicon(src)] You deactivate the shield generator."), \ "You hear heavy droning fade out.") src.shields_down() else if(anchored) - user.visible_message(span_blue("[icon2html(src,viewers(src))] [user] activated the shield generator."), \ - span_blue("[icon2html(src, user.client)] You activate the shield generator."), \ + user.visible_message(span_blue("\icon[src][bicon(src)] [user] activated the shield generator."), \ + span_blue("\icon[src][bicon(src)] You activate the shield generator."), \ "You hear heavy droning.") src.shields_up() else diff --git a/code/modules/shieldgen/shield_capacitor.dm b/code/modules/shieldgen/shield_capacitor.dm index f650a3d15b9..6ec477ceb27 100644 --- a/code/modules/shieldgen/shield_capacitor.dm +++ b/code/modules/shieldgen/shield_capacitor.dm @@ -49,7 +49,7 @@ else if(W.has_tool_quality(TOOL_WRENCH)) src.anchored = !src.anchored playsound(src, W.usesound, 75, 1) - src.visible_message(span_blue("[icon2html(src,viewers(src))] [src] has been [anchored ? "bolted to the floor" : "unbolted from the floor"] by [user].")) + src.visible_message(span_blue("\icon[src][bicon(src)] [src] has been [anchored ? "bolted to the floor" : "unbolted from the floor"] by [user].")) if(anchored) spawn(0) diff --git a/code/modules/shieldgen/shield_gen.dm b/code/modules/shieldgen/shield_gen.dm index 2e2888a4be9..5a2cfc2616a 100644 --- a/code/modules/shieldgen/shield_gen.dm +++ b/code/modules/shieldgen/shield_gen.dm @@ -69,7 +69,7 @@ else if(W.has_tool_quality(TOOL_WRENCH)) src.anchored = !src.anchored playsound(src, W.usesound, 75, 1) - src.visible_message(span_blue("[icon2html(src,viewers(src))] [src] has been [anchored?"bolted to the floor":"unbolted from the floor"] by [user].")) + src.visible_message(span_blue("\icon[src][bicon(src)] [src] has been [anchored?"bolted to the floor":"unbolted from the floor"] by [user].")) if(active) toggle() @@ -242,7 +242,7 @@ covered_turfs = null for(var/mob/M in view(5,src)) - to_chat(M, "[icon2html(src, M.client)] You hear heavy droning start up.") + to_chat(M, "\icon[src][bicon(src)] You hear heavy droning start up.") for(var/obj/effect/energy_field/E in field) // Update the icons here to ensure all the shields have been made already. E.update_icon() else @@ -252,7 +252,7 @@ qdel(D) for(var/mob/M in view(5,src)) - to_chat(M, "[icon2html(src, M.client)] You hear heavy droning fade out.") + to_chat(M, "\icon[src][bicon(src)] You hear heavy droning fade out.") /obj/machinery/shield_gen/update_icon() if(stat & BROKEN) diff --git a/code/modules/shuttles/shuttle.dm b/code/modules/shuttles/shuttle.dm index d8b44e9d613..f1d23995c4b 100644 --- a/code/modules/shuttles/shuttle.dm +++ b/code/modules/shuttles/shuttle.dm @@ -257,7 +257,7 @@ // Observer pattern pre-move var/old_location = current_location - SEND_SIGNAL(src, COMSIG_OBSERVER_SHUTTLE_PRE_MOVE, old_location, destination) + GLOB.shuttle_pre_move_event.raise_event(src, old_location, destination) current_location.shuttle_departed(src) if(debug_logging) @@ -273,7 +273,7 @@ // Observer pattern post-move destination.shuttle_arrived(src) - SEND_SIGNAL(src, COMSIG_OBSERVER_SHUTTLE_MOVED, old_location, destination) + GLOB.shuttle_moved_event.raise_event(src, old_location, destination) return TRUE diff --git a/code/modules/shuttles/shuttles_web.dm b/code/modules/shuttles/shuttles_web.dm index 5dd9666178b..0b0bc59a51b 100644 --- a/code/modules/shuttles/shuttles_web.dm +++ b/code/modules/shuttles/shuttles_web.dm @@ -409,10 +409,10 @@ /obj/shuttle_connector/Initialize() . = ..() - RegisterSignal(SSshuttles,COMSIG_OBSERVER_SHUTTLE_ADDED,PROC_REF(setup_routes)) + GLOB.shuttle_added.register_global(src, PROC_REF(setup_routes)) /obj/shuttle_connector/Destroy() - UnregisterSignal(SSshuttles,COMSIG_OBSERVER_SHUTTLE_ADDED) + GLOB.shuttle_added.unregister_global(src, PROC_REF(setup_routes)) . = ..() // This is called whenever a shuttle is initialized. If its our shuttle, do our thing! diff --git a/code/modules/tgui/modules/appearance_changer.dm b/code/modules/tgui/modules/appearance_changer.dm index e55296c902f..659e77c3014 100644 --- a/code/modules/tgui/modules/appearance_changer.dm +++ b/code/modules/tgui/modules/appearance_changer.dm @@ -65,14 +65,13 @@ owner = H if(owner) - owner.AddComponent(/datum/component/recursive_move) - RegisterSignal(owner, COMSIG_OBSERVER_MOVED, PROC_REF(update_active_camera_screen)) + GLOB.moved_event.register(owner, src, PROC_REF(update_active_camera_screen)) check_whitelist = check_species_whitelist whitelist = species_whitelist blacklist = species_blacklist /datum/tgui_module/appearance_changer/Destroy() - UnregisterSignal(owner, COMSIG_OBSERVER_MOVED) + GLOB.moved_event.unregister(owner, src, PROC_REF(update_active_camera_screen)) last_camera_turf = null qdel(cam_screen) QDEL_LIST(cam_plane_masters) diff --git a/code/modules/tgui/modules/camera.dm b/code/modules/tgui/modules/camera.dm index 1614a6c5519..7954b189f58 100644 --- a/code/modules/tgui/modules/camera.dm +++ b/code/modules/tgui/modules/camera.dm @@ -68,7 +68,7 @@ /datum/tgui_module/camera/Destroy() if(active_camera) - UnregisterSignal(active_camera, COMSIG_OBSERVER_MOVED) + GLOB.moved_event.unregister(active_camera, src, PROC_REF(update_active_camera_screen)) active_camera = null last_camera_turf = null qdel(cam_screen) @@ -142,10 +142,9 @@ var/list/cameras = get_available_cameras(usr) var/obj/machinery/camera/C = cameras["[ckey(c_tag)]"] if(active_camera) - UnregisterSignal(active_camera, COMSIG_OBSERVER_MOVED) + GLOB.moved_event.unregister(active_camera, src, PROC_REF(update_active_camera_screen)) active_camera = C - active_camera.AddComponent(/datum/component/recursive_move) - RegisterSignal(active_camera, COMSIG_OBSERVER_MOVED, PROC_REF(update_active_camera_screen)) + GLOB.moved_event.register(active_camera, src, PROC_REF(update_active_camera_screen)) playsound(tgui_host(), get_sfx("terminal_type"), 25, FALSE) update_active_camera_screen() return TRUE @@ -170,10 +169,9 @@ if(target) if(active_camera) - UnregisterSignal(active_camera, COMSIG_OBSERVER_MOVED) + GLOB.moved_event.unregister(active_camera, src, PROC_REF(update_active_camera_screen)) active_camera = target - active_camera.AddComponent(/datum/component/recursive_move) - RegisterSignal(active_camera, COMSIG_OBSERVER_MOVED, PROC_REF(update_active_camera_screen)) + GLOB.moved_event.register(active_camera, src, PROC_REF(update_active_camera_screen)) playsound(tgui_host(), get_sfx("terminal_type"), 25, FALSE) update_active_camera_screen() . = TRUE @@ -278,7 +276,7 @@ // Turn off the console if(length(concurrent_users) == 0 && is_living) if(active_camera) - UnregisterSignal(active_camera, COMSIG_OBSERVER_MOVED) + GLOB.moved_event.unregister(active_camera, src, PROC_REF(update_active_camera_screen)) active_camera = null playsound(tgui_host(), 'sound/machines/terminal_off.ogg', 25, FALSE) diff --git a/code/modules/tgui/modules/overmap.dm b/code/modules/tgui/modules/overmap.dm index a1d03753122..28e935e3d00 100644 --- a/code/modules/tgui/modules/overmap.dm +++ b/code/modules/tgui/modules/overmap.dm @@ -55,14 +55,13 @@ user.set_machine(src) user.reset_view(linked) user.set_viewsize(world.view + extra_view) - user.AddComponent(/datum/component/recursive_move) - RegisterSignal(user, COMSIG_OBSERVER_MOVED, /datum/tgui_module/ship/proc/unlook) + GLOB.moved_event.register(user, src, /datum/tgui_module/ship/proc/unlook) LAZYDISTINCTADD(viewers, WEAKREF(user)) /datum/tgui_module/ship/proc/unlook(var/mob/user) user.reset_view() user.set_viewsize() // reset to default - UnregisterSignal(user, COMSIG_OBSERVER_MOVED) + GLOB.moved_event.unregister(user, src, /datum/tgui_module/ship/proc/unlook) LAZYREMOVE(viewers, WEAKREF(user)) /datum/tgui_module/ship/proc/viewing_overmap(mob/user) diff --git a/code/modules/tgui/tgui.dm b/code/modules/tgui/tgui.dm index 42dcae7dccb..e85b10092ac 100644 --- a/code/modules/tgui/tgui.dm +++ b/code/modules/tgui/tgui.dm @@ -110,7 +110,10 @@ )) else window.send_message("ping") - send_assets() + window.send_asset(get_asset_datum(/datum/asset/simple/fontawesome)) + window.send_asset(get_asset_datum(/datum/asset/simple/tgfont)) + for(var/datum/asset/asset in src_object.ui_assets(user)) + window.send_asset(asset) window.send_message("update", get_payload( with_data = TRUE, with_static_data = TRUE)) @@ -120,17 +123,6 @@ return TRUE - -/datum/tgui/proc/send_assets() - var/flush_queue = window.send_asset(get_asset_datum( - /datum/asset/simple/namespaced/fontawesome)) - flush_queue |= window.send_asset(get_asset_datum( - /datum/asset/simple/namespaced/tgfont)) - for(var/datum/asset/asset in src_object.ui_assets(user)) - flush_queue |= window.send_asset(asset) - if (flush_queue) - user.client.browse_queue_flush() - /** * public * diff --git a/code/modules/tgui_panel/tgui_panel.dm b/code/modules/tgui_panel/tgui_panel.dm index 2f3ff060d31..4fecdd077fd 100644 --- a/code/modules/tgui_panel/tgui_panel.dm +++ b/code/modules/tgui_panel/tgui_panel.dm @@ -48,8 +48,8 @@ assets = list( get_asset_datum(/datum/asset/simple/tgui_panel), )) - window.send_asset(get_asset_datum(/datum/asset/simple/namespaced/fontawesome)) - window.send_asset(get_asset_datum(/datum/asset/simple/namespaced/tgfont)) + window.send_asset(get_asset_datum(/datum/asset/simple/fontawesome)) + window.send_asset(get_asset_datum(/datum/asset/simple/tgfont)) window.send_asset(get_asset_datum(/datum/asset/spritesheet/chat)) // Other setup request_telemetry() diff --git a/code/modules/vchat/vchat_client.dm b/code/modules/vchat/vchat_client.dm index a20f5fa1eb5..7768830a2eb 100644 --- a/code/modules/vchat/vchat_client.dm +++ b/code/modules/vchat/vchat_client.dm @@ -291,7 +291,7 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("data/iconCache.sav")) //Cache of ic return FALSE GLOBAL_LIST_EMPTY(bicon_cache) // Cache of the tag results, not the icons -/proc/icon2html(var/obj, var/use_class = 1, var/custom_classes = "") +/proc/bicon(var/obj, var/use_class = 1, var/custom_classes = "") var/class = use_class ? "class='icon misc [custom_classes]'" : null if(!obj) return diff --git a/code/modules/virus2/biohazard destroyer.dm b/code/modules/virus2/biohazard destroyer.dm index 2be7c17d1e4..71705147ca4 100644 --- a/code/modules/virus2/biohazard destroyer.dm +++ b/code/modules/virus2/biohazard destroyer.dm @@ -17,4 +17,4 @@ I.loc = src.loc for(var/mob/O in hearers(src, null)) - O.show_message(span_blue("[icon2html(src, O.client)] The [src.name] beeps."), 2) + O.show_message(span_blue("\icon[src][bicon(src)] The [src.name] beeps."), 2) diff --git a/code/modules/virus2/items_devices.dm b/code/modules/virus2/items_devices.dm index 208e2d3a01b..a5744d3c5b2 100644 --- a/code/modules/virus2/items_devices.dm +++ b/code/modules/virus2/items_devices.dm @@ -31,7 +31,7 @@ report("Antibodies detected: [antigens2string(C.antibodies)]", user) /obj/item/device/antibody_scanner/proc/report(var/text, mob/user as mob) - to_chat(user, "[span_blue("[icon2html(src, user.client)] \The [src] beeps,")] \"[span_blue("[text]")]\"") + to_chat(user, "[span_blue("\icon[src][bicon(src)] \The [src] beeps,")] \"[span_blue("[text]")]\"") ///////////////VIRUS DISH/////////////// diff --git a/code/modules/vore/eating/simple_animal_vr.dm b/code/modules/vore/eating/simple_animal_vr.dm index 876ddce783e..e18d93fe360 100644 --- a/code/modules/vore/eating/simple_animal_vr.dm +++ b/code/modules/vore/eating/simple_animal_vr.dm @@ -79,7 +79,7 @@ update_icon() set_AI_busy(FALSE) else if(!ai_holder.target) // no using this to clear a retaliate mob's target - ai_holder.give_target(user) //just because you're not tasty doesn't mean you get off the hook. A swat for a swat. + ai_holder.target = user //just because you're not tasty doesn't mean you get off the hook. A swat for a swat. //AttackTarget() //VOREStation AI Temporary Removal //LoseTarget() // only make one attempt at an attack rather than going into full rage mode else diff --git a/code/modules/vore/fluffstuff/custom_clothes_vr.dm b/code/modules/vore/fluffstuff/custom_clothes_vr.dm index baf34bc916c..16631c9446c 100644 --- a/code/modules/vore/fluffstuff/custom_clothes_vr.dm +++ b/code/modules/vore/fluffstuff/custom_clothes_vr.dm @@ -2097,14 +2097,14 @@ Departamental Swimsuits, for general use translocator_unequip(translocator, user) T.forceMove(src) translocator = T - user.show_message("[icon2html(src, user.client)]*click!*") + user.show_message("\icon[src][bicon(src)]*click!*") playsound(src, 'sound/machines/click.ogg', 30, 1) /obj/item/clothing/head/fluff/nikki/proc/translocator_unequip(var/obj/item/device/perfect_tele/T, var/mob/living/carbon/human/user) if (translocator) if (user) user.put_in_hands(T) - user.show_message("[icon2html(src, user.client)]*click!*") + user.show_message("\icon[src][bicon(src)]*click!*") else translocator.forceMove(get_turf(src)) translocator = null diff --git a/code/modules/vore/fluffstuff/custom_items_vr.dm b/code/modules/vore/fluffstuff/custom_items_vr.dm index bda7d2d669c..39985e01f48 100644 --- a/code/modules/vore/fluffstuff/custom_items_vr.dm +++ b/code/modules/vore/fluffstuff/custom_items_vr.dm @@ -1531,7 +1531,7 @@ if(stored_item && opened && !searching) searching = TRUE if(do_after(user, 10)) - to_chat(user, "You find [icon2html(stored_item, user.client)] [stored_item] in [src]!") + to_chat(user, "You find \icon[stored_item] [stored_item] in [src]!") stored_item.forceMove(get_turf(src)) stored_item = null searching = FALSE diff --git a/code/modules/vore/resizing/sizegun_vr.dm b/code/modules/vore/resizing/sizegun_vr.dm index 4bbaaff0433..982d5185f98 100644 --- a/code/modules/vore/resizing/sizegun_vr.dm +++ b/code/modules/vore/resizing/sizegun_vr.dm @@ -25,8 +25,8 @@ /obj/item/weapon/gun/energy/sizegun/New() ..() - verbs += /obj/item/weapon/gun/energy/sizegun/proc/select_size - verbs += /obj/item/weapon/gun/energy/sizegun/proc/spin_dial + verbs += PROC_REF(select_size) + verbs += PROC_REF(spin_dial) /obj/item/weapon/gun/energy/sizegun/attack_self(mob/user) . = ..() diff --git a/code/modules/xenoarcheaology/artifacts/artifact.dm b/code/modules/xenoarcheaology/artifacts/artifact.dm index 52c871a7b98..7a2d73474a0 100644 --- a/code/modules/xenoarcheaology/artifacts/artifact.dm +++ b/code/modules/xenoarcheaology/artifacts/artifact.dm @@ -12,16 +12,6 @@ var/being_used = 0 - -/obj/machinery/artifact/Destroy() - if(artifact_master) - var/datum/component/artifact_master/arti_mstr = artifact_master - arti_mstr.RemoveComponent() - artifact_master = null - if(!QDELETED(arti_mstr)) - qdel(arti_mstr) - . = ..() - /obj/machinery/artifact/New() ..() diff --git a/code/modules/xenoarcheaology/artifacts/autocloner.dm b/code/modules/xenoarcheaology/artifacts/autocloner.dm index 61f4975a029..0fdd3ef3f3e 100644 --- a/code/modules/xenoarcheaology/artifacts/autocloner.dm +++ b/code/modules/xenoarcheaology/artifacts/autocloner.dm @@ -45,17 +45,17 @@ if(!previous_power_state) previous_power_state = 1 icon_state = "cellold1" - src.visible_message("[icon2html(src,viewers(src))] [src] suddenly comes to life!") + src.visible_message("\icon[src][bicon(src)] [src] suddenly comes to life!") //slowly grow a mob if(prob(5)) - src.visible_message("[icon2html(src,viewers(src))] [src] [pick("gloops","glugs","whirrs","whooshes","hisses","purrs","hums","gushes")].") + src.visible_message("\icon[src][bicon(src)] [src] [pick("gloops","glugs","whirrs","whooshes","hisses","purrs","hums","gushes")].") //if we've finished growing... if(time_spent_spawning >= time_per_spawn) time_spent_spawning = 0 update_use_power(USE_POWER_IDLE) - src.visible_message("[icon2html(src,viewers(src))] [src] pings!") + src.visible_message("\icon[src][bicon(src)] [src] pings!") icon_state = "cellold1" desc = "It's full of a bubbling viscous liquid, and is lit by a mysterious glow." if(spawn_type) @@ -76,7 +76,7 @@ if(previous_power_state) previous_power_state = 0 icon_state = "cellold0" - src.visible_message("[icon2html(src,viewers(src))] [src] suddenly shuts down.") + src.visible_message("\icon[src][bicon(src)] [src] suddenly shuts down.") //cloned mob slowly breaks down time_spent_spawning = max(time_spent_spawning + last_process - world.time, 0) diff --git a/code/modules/xenoarcheaology/artifacts/replicator.dm b/code/modules/xenoarcheaology/artifacts/replicator.dm index 39972aaa5e5..06c411fab93 100644 --- a/code/modules/xenoarcheaology/artifacts/replicator.dm +++ b/code/modules/xenoarcheaology/artifacts/replicator.dm @@ -98,7 +98,7 @@ "foreground" = colors[color], ))) - fail_message = "[bicon(src)] a [pick("loud","soft","sinister","eery","triumphant","depressing","cheerful","angry")] \ + fail_message = "\icon[src][bicon(src)] a [pick("loud","soft","sinister","eery","triumphant","depressing","cheerful","angry")] \ [pick("horn","beep","bing","bleep","blat","honk","hrumph","ding")] sounds and a \ [pick("yellow","purple","green","blue","red","orange","white")] \ [pick("light","dial","meter","window","protrusion","knob","antenna","swirly thing")] \ @@ -110,7 +110,7 @@ if(spawning_types.len && powered()) spawn_progress_time += world.time - last_process_time if(spawn_progress_time > max_spawn_time) - src.visible_message("[icon2html(src,viewers(src))] [src] pings!") + src.visible_message("\icon[src][bicon(src)] [src] pings!") var/obj/source_material = pop(stored_materials) var/spawn_type = pop(spawning_types) @@ -133,7 +133,7 @@ icon_state = "borgcharger0(old)" else if(prob(5)) - src.visible_message("[icon2html(src,viewers(src))] [src] [pick("clicks","whizzes","whirrs","whooshes","clanks","clongs","clonks","bangs")].") + src.visible_message("\icon[src][bicon(src)] [src] [pick("clicks","whizzes","whirrs","whooshes","clanks","clongs","clonks","bangs")].") last_process_time = world.time @@ -161,9 +161,9 @@ if(key in construction) if(LAZYLEN(stored_materials) > LAZYLEN(spawning_types)) if(LAZYLEN(spawning_types)) - visible_message("[icon2html(src,viewers(src))] a [pick("light","dial","display","meter","pad")] on [src]'s front [pick("blinks","flashes")] [pick("red","yellow","blue","orange","purple","green","white")].") + visible_message("\icon[src][bicon(src)] a [pick("light","dial","display","meter","pad")] on [src]'s front [pick("blinks","flashes")] [pick("red","yellow","blue","orange","purple","green","white")].") else - visible_message("[icon2html(src,viewers(src))] [src]'s front compartment slides shut.") + visible_message("\icon[src][bicon(src)] [src]'s front compartment slides shut.") spawning_types.Add(construction[key]) spawn_progress_time = 0 update_use_power(USE_POWER_ACTIVE) diff --git a/code/modules/xenoarcheaology/artifacts/replicator_vr.dm b/code/modules/xenoarcheaology/artifacts/replicator_vr.dm index 9a31b13a75d..f92b94ade7c 100644 --- a/code/modules/xenoarcheaology/artifacts/replicator_vr.dm +++ b/code/modules/xenoarcheaology/artifacts/replicator_vr.dm @@ -71,7 +71,7 @@ if(spawning_types.len && powered()) spawn_progress_time += world.time - last_process_time if(spawn_progress_time > max_spawn_time) - src.visible_message("[icon2html(src,viewers(src))] [src] pings!") + src.visible_message("\icon[src][bicon(src)] [src] pings!") var/obj/source_material = pop(stored_materials) var/spawn_type = pop(spawning_types) @@ -200,7 +200,7 @@ icon_state = "borgcharger0(old)" else if(prob(5)) - src.visible_message("[icon2html(src,viewers(src))] [src] [pick("clicks","whizzes","whirrs","whooshes","clanks","clongs","clonks","bangs")].") + src.visible_message("\icon[src][bicon(src)] [src] [pick("clicks","whizzes","whirrs","whooshes","clanks","clongs","clonks","bangs")].") last_process_time = world.time @@ -313,9 +313,9 @@ if(key in created_mobs) if(LAZYLEN(stored_materials) > LAZYLEN(spawning_types)) if(LAZYLEN(spawning_types)) - visible_message("[icon2html(src,viewers(src))] a [pick("light","dial","display","meter","pad")] on [src]'s front [pick("blinks","flashes")] [pick("red","yellow","blue","orange","purple","green","white")].") + visible_message("\icon[src][bicon(src)] a [pick("light","dial","display","meter","pad")] on [src]'s front [pick("blinks","flashes")] [pick("red","yellow","blue","orange","purple","green","white")].") else - visible_message("[icon2html(src,viewers(src))] [src]'s front compartment slides shut.") + visible_message("\icon[src][bicon(src)] [src]'s front compartment slides shut.") spawning_types.Add(created_mobs[key]) spawn_progress_time = 0 update_use_power(USE_POWER_ACTIVE) @@ -424,7 +424,7 @@ if(spawning_types.len && powered()) spawn_progress_time += world.time - last_process_time if(spawn_progress_time > max_spawn_time) - src.visible_message("[icon2html(src,viewers(src))] [src] pings!") + src.visible_message("\icon[src][bicon(src)] [src] pings!") var/obj/source_material = pop(stored_materials) var/spawn_type = pop(spawning_types) @@ -469,7 +469,7 @@ icon_state = "borgcharger0(old)" else if(prob(5)) - src.visible_message("[icon2html(src,viewers(src))] [src] [pick("clicks","whizzes","whirrs","whooshes","clanks","clongs","clonks","bangs")].") + src.visible_message("\icon[src][bicon(src)] [src] [pick("clicks","whizzes","whirrs","whooshes","clanks","clongs","clonks","bangs")].") last_process_time = world.time @@ -586,9 +586,9 @@ if(key in created_items) if(LAZYLEN(stored_materials) > LAZYLEN(spawning_types)) if(LAZYLEN(spawning_types)) - visible_message("[icon2html(src,viewers(src))] a [pick("light","dial","display","meter","pad")] on [src]'s front [pick("blinks","flashes")] [pick("red","yellow","blue","orange","purple","green","white")].") + visible_message("\icon[src][bicon(src)] a [pick("light","dial","display","meter","pad")] on [src]'s front [pick("blinks","flashes")] [pick("red","yellow","blue","orange","purple","green","white")].") else - visible_message("[icon2html(src,viewers(src))] [src]'s front compartment slides shut.") + visible_message("\icon[src][bicon(src)] [src]'s front compartment slides shut.") spawning_types.Add(created_items[key]) spawn_progress_time = 0 update_use_power(USE_POWER_ACTIVE) diff --git a/code/modules/xenoarcheaology/effect.dm b/code/modules/xenoarcheaology/effect.dm index bf6932b2d31..966e55d05d5 100644 --- a/code/modules/xenoarcheaology/effect.dm +++ b/code/modules/xenoarcheaology/effect.dm @@ -92,7 +92,7 @@ var/atom/toplevelholder = target while(!istype(toplevelholder.loc, /turf)) toplevelholder = toplevelholder.loc - toplevelholder.visible_message("[span_red("[icon2html(toplevelholder, viewers(toplevelholder))] [toplevelholder] [display_msg]")]") + toplevelholder.visible_message("[span_red("\icon[toplevelholder][bicon(toplevelholder)] [toplevelholder] [display_msg]")]") /datum/artifact_effect/proc/DoEffectTouch(var/mob/user) /datum/artifact_effect/proc/DoEffectAura(var/atom/holder) diff --git a/code/modules/xenoarcheaology/effect_master.dm b/code/modules/xenoarcheaology/effect_master.dm index 97696b637da..ddb77f661a6 100644 --- a/code/modules/xenoarcheaology/effect_master.dm +++ b/code/modules/xenoarcheaology/effect_master.dm @@ -118,7 +118,6 @@ holder = null for(var/datum/artifact_effect/AE in my_effects) AE.master = null - my_effects -= AE qdel(AE) STOP_PROCESSING(SSobj,src) diff --git a/code/modules/xenoarcheaology/effects/vampire.dm b/code/modules/xenoarcheaology/effects/vampire.dm index 746a17961d7..757f02889a8 100644 --- a/code/modules/xenoarcheaology/effects/vampire.dm +++ b/code/modules/xenoarcheaology/effects/vampire.dm @@ -83,7 +83,7 @@ if(charges >= 0.1) if(prob(5)) - holder.visible_message("[icon2html(holder,viewers(holder))] \The [holder] gleams a bloody red!") + holder.visible_message("\icon[holder] \The [holder] gleams a bloody red!") charges -= 0.1 /datum/artifact_effect/vampire/DoEffectPulse() diff --git a/code/modules/xenoarcheaology/finds/find_spawning.dm b/code/modules/xenoarcheaology/finds/find_spawning.dm index 11c5c0fe040..354c160a8a6 100644 --- a/code/modules/xenoarcheaology/finds/find_spawning.dm +++ b/code/modules/xenoarcheaology/finds/find_spawning.dm @@ -708,13 +708,3 @@ if(become_anomalous) become_anomalous() - - -/obj/item/weapon/archaeological_find/Destroy() - if(src.is_anomalous()) - var/datum/component/artifact_master/arti_mstr = GetComponent(/datum/component/artifact_master) - arti_mstr.RemoveComponent() - if(!QDELETED(arti_mstr)) - qdel(arti_mstr) - - . = ..() diff --git a/code/modules/xenoarcheaology/finds/fossils.dm b/code/modules/xenoarcheaology/finds/fossils.dm index 3c3a182a32c..0ad06af4687 100644 --- a/code/modules/xenoarcheaology/finds/fossils.dm +++ b/code/modules/xenoarcheaology/finds/fossils.dm @@ -77,7 +77,7 @@ ..() else if(istype(W,/obj/item/weapon/pen)) plaque_contents = sanitize(tgui_input_text(usr, "What would you like to write on the plaque:","Skeleton plaque","")) - user.visible_message("[user] writes something on the base of [src].","You relabel the plaque on the base of [icon2html(src,viewers(src))] [src].") + user.visible_message("[user] writes something on the base of [src].","You relabel the plaque on the base of \icon[src][bicon(src)] [src].") if(src.contents.Find(/obj/item/weapon/fossil/skull/horned)) src.desc = "A creature made of [src.contents.len-1] assorted bones and a horned skull. The plaque reads \'[plaque_contents]\'." else diff --git a/code/modules/xenoarcheaology/finds/special.dm b/code/modules/xenoarcheaology/finds/special.dm index a71f742ca15..cf6c21546d8 100644 --- a/code/modules/xenoarcheaology/finds/special.dm +++ b/code/modules/xenoarcheaology/finds/special.dm @@ -99,7 +99,7 @@ if(charges >= 0.1) if(prob(5)) - src.visible_message(span_red("[icon2html(src,viewers(src))] [src]'s eyes glow ruby red for a moment!")) + src.visible_message(span_red("\icon[src][bicon(src)] [src]'s eyes glow ruby red for a moment!")) charges -= 0.1 //check on our shadow wights diff --git a/code/modules/xenoarcheaology/finds/talking.dm b/code/modules/xenoarcheaology/finds/talking.dm index 138ffca5d48..2d6b23508af 100644 --- a/code/modules/xenoarcheaology/finds/talking.dm +++ b/code/modules/xenoarcheaology/finds/talking.dm @@ -54,7 +54,7 @@ var/list/options = list("[holder_atom] seems to be listening intently to [source]...",\ "[holder_atom] seems to be focusing on [source]...",\ "[holder_atom] seems to turn it's attention to [source]...") - holder_atom.loc.visible_message(span_blue("[icon2html(holder_atom,viewers(holder_atom.loc))] [pick(options)]")) + holder_atom.loc.visible_message(span_blue("\icon[holder_atom][bicon(holder_atom)] [pick(options)]")) if(prob(20)) spawn(2) @@ -111,5 +111,5 @@ var/list/listening = viewers(holder_atom) for(var/mob/M in listening) - to_chat(M, "[icon2html(holder_atom,M.client)] [holder_atom] reverberates, \"[span_blue(msg)]\"") + to_chat(M, "\icon[holder_atom][bicon(holder_atom)] [holder_atom] reverberates, \"[span_blue(msg)]\"") last_talk_time = world.time diff --git a/code/modules/xenoarcheaology/tools/ano_device_battery.dm b/code/modules/xenoarcheaology/tools/ano_device_battery.dm index ac9fc9b4db1..7fb51a0a4a6 100644 --- a/code/modules/xenoarcheaology/tools/ano_device_battery.dm +++ b/code/modules/xenoarcheaology/tools/ano_device_battery.dm @@ -103,7 +103,7 @@ if("startup") if(inserted_battery && inserted_battery.battery_effect && (inserted_battery.stored_charge > 0)) activated = TRUE - visible_message(span_blue("[icon2html(src,viewers(src))] [src] whirrs."), span_blue("[icon2html(src,viewers(src))]You hear something whirr.")) + visible_message(span_blue("\icon[src][bicon(src)] [src] whirrs."), span_blue("\icon[src][bicon(src)]You hear something whirr.")) if(!inserted_battery.battery_effect.activated) inserted_battery.battery_effect.ToggleActivate(1) time_end = world.time + duration @@ -146,9 +146,9 @@ if(interval > 0) //apply the touch effect to the holder if(holder) - to_chat(holder, "the [icon2html(src,holder.client)] [src] held by [holder] shudders in your grasp.") + to_chat(holder, "the \icon[src][bicon(src)] [src] held by [holder] shudders in your grasp.") else - src.loc.visible_message("the [icon2html(src,viewers(src))] [src] shudders.") + src.loc.visible_message("the \icon[src][bicon(src)] [src] shudders.") //consume power inserted_battery.use_power(energy_consumed_on_touch) @@ -175,13 +175,13 @@ //work out if we need to shutdown if(inserted_battery.stored_charge <= 0) - src.loc.visible_message(span_blue("[icon2html(src,viewers(src))] [src] buzzes."), span_blue("[icon2html(src,viewers(src))] You hear something buzz.")) + src.loc.visible_message(span_blue("\icon[src][bicon(src)] [src] buzzes."), span_blue("\icon[src][bicon(src)] You hear something buzz.")) shutdown_emission() else if(world.time > time_end) - src.loc.visible_message(span_blue("[icon2html(src,viewers(src))] [src] chimes."), span_blue("[icon2html(src,viewers(src))] You hear something chime.")) + src.loc.visible_message(span_blue("\icon[src][bicon(src)] [src] chimes."), span_blue("\icon[src][bicon(src)] You hear something chime.")) shutdown_emission() else - src.visible_message(span_blue("[icon2html(src,viewers(src))] [src] buzzes."), span_blue("[icon2html(src,viewers(src))] You hear something buzz.")) + src.visible_message(span_blue("\icon[src][bicon(src)] [src] buzzes."), span_blue("\icon[src][bicon(src)] You hear something buzz.")) shutdown_emission() last_process = world.time diff --git a/code/modules/xenoarcheaology/tools/artifact_analyser.dm b/code/modules/xenoarcheaology/tools/artifact_analyser.dm index 41d4ad1bc20..6e0e1ceb19f 100644 --- a/code/modules/xenoarcheaology/tools/artifact_analyser.dm +++ b/code/modules/xenoarcheaology/tools/artifact_analyser.dm @@ -125,7 +125,7 @@ P.name = "[src] report #[++report_num]" P.info = "[src] analysis report #[report_num]
" P.info += "
" - P.info += "[bicon(scanned_object)] [results]" + P.info += "\icon[scanned_object][bicon(scanned_object)] [results]" P.stamped = list(/obj/item/weapon/stamp) P.add_overlay("paper_stamped") diff --git a/code/modules/xenoarcheaology/tools/geosample_scanner.dm b/code/modules/xenoarcheaology/tools/geosample_scanner.dm index bd79af08eb1..53733810c61 100644 --- a/code/modules/xenoarcheaology/tools/geosample_scanner.dm +++ b/code/modules/xenoarcheaology/tools/geosample_scanner.dm @@ -268,16 +268,16 @@ //emergency stop if seal integrity reaches 0 if(scanner_seal_integrity <= 0 || (scanner_temperature >= 1273 && !rad_shield)) stop_scanning() - src.visible_message(span_blue("[icon2html(src,viewers(src))] buzzes unhappily. It has failed mid-scan!"), 2) + src.visible_message(span_blue("\icon[src][bicon(src)] buzzes unhappily. It has failed mid-scan!"), 2) if(prob(5)) - src.visible_message(span_blue("[icon2html(src,viewers(src))] [pick("whirrs","chuffs","clicks")][pick(" excitedly"," energetically"," busily")]."), 2) + src.visible_message(span_blue("\icon[src][bicon(src)] [pick("whirrs","chuffs","clicks")][pick(" excitedly"," energetically"," busily")]."), 2) else //gradually cool down over time if(scanner_temperature > 0) scanner_temperature = max(scanner_temperature - 5 - 10 * rand(), 0) if(prob(0.75)) - src.visible_message(span_blue("[icon2html(src,viewers(src))] [pick("plinks","hisses")][pick(" quietly"," softly"," sadly"," plaintively")]."), 2) + src.visible_message(span_blue("\icon[src][bicon(src)] [pick("plinks","hisses")][pick(" quietly"," softly"," sadly"," plaintively")]."), 2) playsound(src, 'sound/effects/ding.ogg', 25) last_process_worldtime = world.time @@ -296,7 +296,7 @@ used_coolant = 0 /obj/machinery/radiocarbon_spectrometer/proc/complete_scan() - src.visible_message(span_blue("[icon2html(src,viewers(src))] makes an insistent chime."), 2) + src.visible_message(span_blue("\icon[src][bicon(src)] makes an insistent chime."), 2) if(scanned_item) //create report diff --git a/code/modules/xenoarcheaology/tools/suspension_generator.dm b/code/modules/xenoarcheaology/tools/suspension_generator.dm index b420435bb3f..51f23f8b0ad 100644 --- a/code/modules/xenoarcheaology/tools/suspension_generator.dm +++ b/code/modules/xenoarcheaology/tools/suspension_generator.dm @@ -150,10 +150,10 @@ for(var/mob/living/M in T) M.Weaken(5) - M.visible_message(span_blue("[icon2html(M,viewers(M))] [M] begins to float in the air!"),"You feel tingly and light, but it is difficult to move.") + M.visible_message(span_blue("[bicon(M)] [M] begins to float in the air!"),"You feel tingly and light, but it is difficult to move.") suspension_field = new(T) - visible_message(span_blue("[icon2html(src,viewers(src))] [src] activates with a low hum.")) + visible_message(span_blue("[bicon(src)] [src] activates with a low hum.")) icon_state = "suspension_on" playsound(loc, 'sound/machines/quiet_beep.ogg', 40) update_icon() @@ -165,7 +165,7 @@ if(collected) suspension_field.icon_state = "energynet" add_overlay("shield2") - visible_message(span_blue("[icon2html(suspension_field,viewers(src))] [suspension_field] gently absconds [collected > 1 ? "something" : "several things"].")) + visible_message(span_blue("[bicon(suspension_field)] [suspension_field] gently absconds [collected > 1 ? "something" : "several things"].")) else if(istype(T,/turf/simulated/mineral) || istype(T,/turf/simulated/wall)) suspension_field.icon_state = "shieldsparkles" @@ -180,7 +180,7 @@ to_chat(M, "You no longer feel like floating.") M.Weaken(3) - visible_message(span_blue("[icon2html(src,viewers(src))] [src] deactivates with a gentle shudder.")) + visible_message(span_blue("[bicon(src)] [src] deactivates with a gentle shudder.")) qdel(suspension_field) suspension_field = null icon_state = "suspension_wrenched" diff --git a/code/modules/xenoarcheaology/tools/tools.dm b/code/modules/xenoarcheaology/tools/tools.dm index ee145433a77..75e42a0b1b0 100644 --- a/code/modules/xenoarcheaology/tools/tools.dm +++ b/code/modules/xenoarcheaology/tools/tools.dm @@ -131,7 +131,7 @@ positive_locations.Add(D) - to_chat(user, "[icon2html(src, user.client)] [src] pings.") + to_chat(user, "\icon[src][bicon(src)] [src] pings.") else if(istype(A, /obj/structure/boulder)) var/obj/structure/boulder/B = A @@ -149,7 +149,7 @@ positive_locations.Add(D) - to_chat(user, "[icon2html(src, user.client)] [src] pings [pick("madly","wildly","excitedly","crazily")]!") + to_chat(user, "\icon[src][bicon(src)] [src] pings [pick("madly","wildly","excitedly","crazily")]!") /obj/item/device/depth_scanner/attack_self(var/mob/living/user) tgui_interact(user) @@ -269,9 +269,9 @@ scan_ticks = 0 var/turf/T = get_turf(src) if(target_radio) - T.visible_message("[icon2html(src,viewers(src))] [src] [pick("chirps","chirrups","cheeps")] happily.") + T.visible_message("\icon[src][bicon(src)] [src] [pick("chirps","chirrups","cheeps")] happily.") else - T.visible_message("[icon2html(src,viewers(src))] [src] [pick("chirps","chirrups","cheeps")] sadly.") + T.visible_message("\icon[src][bicon(src)] [src] [pick("chirps","chirrups","cheeps")] sadly.") else icon_state = "pinoff" @@ -352,3 +352,4 @@ set name = "Scan for Anomalies" set desc = "Scan for artifacts and anomalies within your vicinity." anomaly_scanner.interact(user) + diff --git a/code/modules/xenobio/items/extracts.dm b/code/modules/xenobio/items/extracts.dm index 3ad6f852c70..c5ec91d2397 100644 --- a/code/modules/xenobio/items/extracts.dm +++ b/code/modules/xenobio/items/extracts.dm @@ -55,7 +55,7 @@ var/obj/item/slime_extract/T = holder.my_atom T.uses-- if(T.uses <= 0) - T.visible_message("[icon2html(T,viewers(T))]\The [T] goes inert.") + T.visible_message("\icon[T][bicon(T)]\The [T] goes inert.") T.name = "inert [initial(T.name)]" @@ -988,3 +988,6 @@ /decl/chemical_reaction/instant/slime/rainbow_unity/on_reaction(var/datum/reagents/holder) new /obj/item/slimepotion/unity(get_turf(holder.my_atom)) ..() + + + diff --git a/code/modules/xenobio/items/extracts_vr.dm b/code/modules/xenobio/items/extracts_vr.dm index 1866e879f87..bd232c153af 100644 --- a/code/modules/xenobio/items/extracts_vr.dm +++ b/code/modules/xenobio/items/extracts_vr.dm @@ -60,7 +60,7 @@ var/obj/item/slime_extract/T = holder.my_atom T.uses-- if(T.uses <= 0) - T.visible_message("[icon2html(T,viewers(T))]\The [T] goes inert.") + T.visible_message("\icon[T][bicon(T)]\The [T] goes inert.") T.name = "inert [initial(T.name)]" @@ -1658,4 +1658,4 @@ /decl/chemical_reaction/instant/slime/rainbow_unity/on_reaction(var/datum/reagents/holder) new /obj/item/slimepotion/unity(get_turf(holder.my_atom)) - ..() + ..() \ No newline at end of file diff --git a/code/modules/xenobio2/machinery/core_extractor.dm b/code/modules/xenobio2/machinery/core_extractor.dm index 51526cb0cc2..8f55143be27 100644 --- a/code/modules/xenobio2/machinery/core_extractor.dm +++ b/code/modules/xenobio2/machinery/core_extractor.dm @@ -93,7 +93,7 @@ /obj/machinery/slime/extractor/proc/extract_cores() if(!src.occupant) - src.visible_message("[icon2html(src,viewers(src))] [src] pings unhappily.") + src.visible_message("\icon[src][bicon(src)] [src] pings unhappily.") else if(inuse) return diff --git a/code/modules/xenobio2/machinery/gene_manipulators.dm b/code/modules/xenobio2/machinery/gene_manipulators.dm index 2132b7e0bd1..b8e5cfc616a 100644 --- a/code/modules/xenobio2/machinery/gene_manipulators.dm +++ b/code/modules/xenobio2/machinery/gene_manipulators.dm @@ -102,15 +102,15 @@ in_use = 0 if(failed_task) failed_task = 0 - visible_message("[icon2html(src,viewers(src))] [src] pings unhappily, flashing a red warning light.") + visible_message("\icon[src][bicon(src)] [src] pings unhappily, flashing a red warning light.") else - visible_message("[icon2html(src,viewers(src))] [src] pings happily.") + visible_message("\icon[src][bicon(src)] [src] pings happily.") if(eject_disk) eject_disk = 0 if(loaded_disk) loaded_disk.forceMove(get_turf(src)) - visible_message("[icon2html(src,viewers(src))] [src] beeps and spits out [loaded_disk].") + visible_message("\icon[src][bicon(src)] [src] beeps and spits out [loaded_disk].") loaded_disk = null /obj/machinery/xenobio/extractor @@ -183,7 +183,7 @@ /obj/machinery/xenobio/proc/eject_disk() if(!loaded_disk) return loaded_disk.forceMove(loc) - visible_message("[icon2html(src,viewers(src))] [src] beeps and spits out [loaded_disk].") + visible_message("\icon[src][bicon(src)] [src] beeps and spits out [loaded_disk].") loaded_disk = null /obj/machinery/xenobio/extractor/Topic(href, href_list) @@ -195,7 +195,7 @@ if(!product) return product.forceMove(get_turf(src)) - visible_message("[icon2html(src,viewers(src))] [src] beeps and spits out [product].") + visible_message("\icon[src][bicon(src)] [src] beeps and spits out [product].") product = null if(href_list["eject_disk"]) diff --git a/code/modules/xenobio2/machinery/slime_replicator.dm b/code/modules/xenobio2/machinery/slime_replicator.dm index f402ad3193e..c7b7b3c567f 100644 --- a/code/modules/xenobio2/machinery/slime_replicator.dm +++ b/code/modules/xenobio2/machinery/slime_replicator.dm @@ -57,7 +57,7 @@ /obj/machinery/slime/replicator/proc/replicate_slime() if(!src.core) - src.visible_message("[icon2html(src,viewers(src))] [src] pings unhappily.") + src.visible_message("\icon[src][bicon(src)] [src] pings unhappily.") else if(inuse) return @@ -140,3 +140,4 @@ /obj/item/weapon/stock_parts/matter_bin = 1, /obj/item/weapon/stock_parts/micro_laser = 1 ) + diff --git a/config/example/config.txt b/config/example/config.txt index 82778e3fb5f..3baae3f215d 100644 --- a/config/example/config.txt +++ b/config/example/config.txt @@ -602,42 +602,3 @@ JUKEBOX_TRACK_FILES config/jukebox.json #SUGGESTED_BYOND_VERSION 514 # Suggested BYOND client build (minor component, e.g. 1560) #SUGGESTED_BYOND_BUILD 1561 - - -#### Asset settings #### -## Asset Transport -## The normal way of getting assets to clients is to use the internal byond system. This can be slow and delay the opening of interface windows. It also doesn't allow the internal IE windows byond uses to cache anything. -## You can instead have the server save them to a website via a folder within the game server that the web server can read. This could be a simple webserver or something backed by a CDN. -## Valid values: simple, webroot. Simple is the default. -#ASSET_TRANSPORT webroot - - -### Simple asset transport configurable values. - -## Uncomment this to have the server passively send all browser assets to each client in the background. (instead of waiting for them to be needed) -## This should be uncommented in production and commented in development -#ASSET_SIMPLE_PRELOAD - - -### Webroot asset transport configurable values. - -## Local folder to save assets to. -## Assets will be saved in the format of asset.MD5HASH.EXT or in namespaces/hash/ as ASSET_FILE_NAME or asset.MD5HASH.EXT -#ASSET_CDN_WEBROOT data/asset-store/ - -## URL the folder from above can be accessed from. -## for best results the webserver powering this should return a long cache validity time, as all assets sent via this transport use hash based urls -## Encryption (https) is supported here, but linux clients will have issues if you require higher then tls 1.0. Windows clients down to windows 7 can handle tls 1.2 no issue. -## if you want to test this locally, you simpily run the `localhost-asset-webroot-server.py` python3 script to host assets stored in `data/asset-store/` via http://localhost:58715/ -#ASSET_CDN_URL http://localhost:58715/ - -## Assets can opt-in to caching their results into `cache/`. -## The cache is assumed to be cleared by TGS recompiling, which deletes `cache/`. -## This should be disabled on development, -## but enabled on production (the default). -#CACHE_ASSETS - -## If this is uncommented, we will save all associated spritesheet PNGs and CSS files to a folder in the round-specific logs folder. -## Useful for developers to debug potential spritesheet issues to determine where the issue is cropping up (either in DM-side sprite generation or in the TGUI-side display of said spritesheet). -## Will only seek to waste disk space if ran on production. -#SAVE_SPRITESHEETS diff --git a/html/font-awesome/css/all.min.css b/html/font-awesome/css/all.min.css index 7a283f087ca..a5e67e693dd 100644 --- a/html/font-awesome/css/all.min.css +++ b/html/font-awesome/css/all.min.css @@ -1,6 +1,5 @@ /*! - * Font Awesome Free 6.1.2 by @fontawesome - https://fontawesome.com + * Font Awesome Free 5.14.0 by @fontawesome - https://fontawesome.com * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) - * Copyright 2022 Fonticons, Inc. */ -.fa{font-family:"Font Awesome 6 Free";font-weight:900}.fa,.fa-brands,.fa-duotone,.fa-light,.fa-regular,.fa-solid,.fa-thin,.fab,.fad,.fal,.far,.fas,.fat{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:inline-block;font-style:normal;font-variant:normal;line-height:1;text-rendering:auto}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-2xs{font-size:.625em;line-height:.1em;vertical-align:.225em}.fa-xs{font-size:.75em;line-height:.08333em;vertical-align:.125em}.fa-sm{font-size:.875em;line-height:.07143em;vertical-align:.05357em}.fa-lg{font-size:1.25em;line-height:.05em;vertical-align:-.075em}.fa-xl{font-size:1.5em;line-height:.04167em;vertical-align:-.125em}.fa-2xl{font-size:2em;line-height:.03125em;vertical-align:-.1875em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.fa-ul>li{position:relative}.fa-li{left:calc( 2em*-1);position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border-radius:.1em;border:.08em solid #eee;padding:.2em .25em .15em}.fa-pull-left{float:left;margin-right:.3em}.fa-pull-right{float:right;margin-left:.3em}.fa-beat{-webkit-animation-name:fa-beat;animation-name:fa-beat;-webkit-animation-delay:0;animation-delay:0;-webkit-animation-direction:normal;animation-direction:normal;-webkit-animation-duration:1s;animation-duration:1s;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}.fa-bounce{-webkit-animation-name:fa-bounce;animation-name:fa-bounce;-webkit-animation-delay:0;animation-delay:0;-webkit-animation-direction:normal;animation-direction:normal;-webkit-animation-duration:1s;animation-duration:1s;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;-webkit-animation-timing-function:cubic-bezier(.28,.84,.42,1);animation-timing-function:cubic-bezier(.28,.84,.42,1)}.fa-fade{-webkit-animation-name:fa-fade;animation-name:fa-fade;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;-webkit-animation-timing-function:cubic-bezier(.4,0,.6,1);animation-timing-function:cubic-bezier(.4,0,.6,1)}.fa-beat-fade,.fa-fade{-webkit-animation-delay:0;animation-delay:0;-webkit-animation-direction:normal;animation-direction:normal;-webkit-animation-duration:1s;animation-duration:1s}.fa-beat-fade{-webkit-animation-name:fa-beat-fade;animation-name:fa-beat-fade;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;-webkit-animation-timing-function:cubic-bezier(.4,0,.6,1);animation-timing-function:cubic-bezier(.4,0,.6,1)}.fa-flip{-webkit-animation-name:fa-flip;animation-name:fa-flip;-webkit-animation-delay:0;animation-delay:0;-webkit-animation-direction:normal;animation-direction:normal;-webkit-animation-duration:1s;animation-duration:1s;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}.fa-shake{-webkit-animation-name:fa-shake;animation-name:fa-shake;-webkit-animation-duration:1s;animation-duration:1s;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;-webkit-animation-timing-function:linear;animation-timing-function:linear}.fa-shake,.fa-spin{-webkit-animation-delay:0;animation-delay:0;-webkit-animation-direction:normal;animation-direction:normal}.fa-spin{-webkit-animation-name:fa-spin;animation-name:fa-spin;-webkit-animation-duration:2s;animation-duration:2s;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;-webkit-animation-timing-function:linear;animation-timing-function:linear}.fa-spin-reverse{--fa-animation-direction:reverse}.fa-pulse,.fa-spin-pulse{-webkit-animation-name:fa-spin;animation-name:fa-spin;-webkit-animation-direction:normal;animation-direction:normal;-webkit-animation-duration:1s;animation-duration:1s;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;-webkit-animation-timing-function:steps(8);animation-timing-function:steps(8)}@media (prefers-reduced-motion:reduce){.fa-beat,.fa-beat-fade,.fa-bounce,.fa-fade,.fa-flip,.fa-pulse,.fa-shake,.fa-spin,.fa-spin-pulse{-webkit-animation-delay:-1ms;animation-delay:-1ms;-webkit-animation-duration:1ms;animation-duration:1ms;-webkit-animation-iteration-count:1;animation-iteration-count:1;transition-delay:0s;transition-duration:0s}}@-webkit-keyframes fa-beat{0%,90%{-webkit-transform:scale(1);transform:scale(1)}45%{-webkit-transform:scale(1.25);transform:scale(1.25)}}@keyframes fa-beat{0%,90%{-webkit-transform:scale(1);transform:scale(1)}45%{-webkit-transform:scale(1.25);transform:scale(1.25)}}@-webkit-keyframes fa-bounce{0%{-webkit-transform:scale(1) translateY(0);transform:scale(1) translateY(0)}10%{-webkit-transform:scale(1.1,.9) translateY(0);transform:scale(1.1,.9) translateY(0)}30%{-webkit-transform:scale(.9,1.1) translateY(-.5em);transform:scale(.9,1.1) translateY(-.5em)}50%{-webkit-transform:scale(1.05,.95) translateY(0);transform:scale(1.05,.95) translateY(0)}57%{-webkit-transform:scale(1) translateY(-.125em);transform:scale(1) translateY(-.125em)}64%{-webkit-transform:scale(1) translateY(0);transform:scale(1) translateY(0)}to{-webkit-transform:scale(1) translateY(0);transform:scale(1) translateY(0)}}@keyframes fa-bounce{0%{-webkit-transform:scale(1) translateY(0);transform:scale(1) translateY(0)}10%{-webkit-transform:scale(1.1,.9) translateY(0);transform:scale(1.1,.9) translateY(0)}30%{-webkit-transform:scale(.9,1.1) translateY(-.5em);transform:scale(.9,1.1) translateY(-.5em)}50%{-webkit-transform:scale(1.05,.95) translateY(0);transform:scale(1.05,.95) translateY(0)}57%{-webkit-transform:scale(1) translateY(-.125em);transform:scale(1) translateY(-.125em)}64%{-webkit-transform:scale(1) translateY(0);transform:scale(1) translateY(0)}to{-webkit-transform:scale(1) translateY(0);transform:scale(1) translateY(0)}}@-webkit-keyframes fa-fade{50%{opacity:.4}}@keyframes fa-fade{50%{opacity:.4}}@-webkit-keyframes fa-beat-fade{0%,to{opacity:.4;-webkit-transform:scale(1);transform:scale(1)}50%{opacity:1;-webkit-transform:scale(1.125);transform:scale(1.125)}}@keyframes fa-beat-fade{0%,to{opacity:.4;-webkit-transform:scale(1);transform:scale(1)}50%{opacity:1;-webkit-transform:scale(1.125);transform:scale(1.125)}}@-webkit-keyframes fa-flip{50%{-webkit-transform:rotate3d(0,1,0,-180deg);transform:rotate3d(0,1,0,-180deg)}}@keyframes fa-flip{50%{-webkit-transform:rotate3d(0,1,0,-180deg);transform:rotate3d(0,1,0,-180deg)}}@-webkit-keyframes fa-shake{0%{-webkit-transform:rotate(-15deg);transform:rotate(-15deg)}4%{-webkit-transform:rotate(15deg);transform:rotate(15deg)}8%,24%{-webkit-transform:rotate(-18deg);transform:rotate(-18deg)}12%,28%{-webkit-transform:rotate(18deg);transform:rotate(18deg)}16%{-webkit-transform:rotate(-22deg);transform:rotate(-22deg)}20%{-webkit-transform:rotate(22deg);transform:rotate(22deg)}32%{-webkit-transform:rotate(-12deg);transform:rotate(-12deg)}36%{-webkit-transform:rotate(12deg);transform:rotate(12deg)}40%,to{-webkit-transform:rotate(0deg);transform:rotate(0deg)}}@keyframes fa-shake{0%{-webkit-transform:rotate(-15deg);transform:rotate(-15deg)}4%{-webkit-transform:rotate(15deg);transform:rotate(15deg)}8%,24%{-webkit-transform:rotate(-18deg);transform:rotate(-18deg)}12%,28%{-webkit-transform:rotate(18deg);transform:rotate(18deg)}16%{-webkit-transform:rotate(-22deg);transform:rotate(-22deg)}20%{-webkit-transform:rotate(22deg);transform:rotate(22deg)}32%{-webkit-transform:rotate(-12deg);transform:rotate(-12deg)}36%{-webkit-transform:rotate(12deg);transform:rotate(12deg)}40%,to{-webkit-transform:rotate(0deg);transform:rotate(0deg)}}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.fa-rotate-90{-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-webkit-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-webkit-transform:scaleY(-1);transform:scaleY(-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{-webkit-transform:scale(-1);transform:scale(-1)}.fa-rotate-by{-webkit-transform:rotate(none);transform:rotate(none)}.fa-stack{display:inline-block;height:2em;line-height:2em;position:relative;vertical-align:middle;width:2.5em}.fa-stack-1x,.fa-stack-2x{left:0;position:absolute;text-align:center;width:100%;z-index:auto}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-0:before{content:"\30"}.fa-1:before{content:"\31"}.fa-2:before{content:"\32"}.fa-3:before{content:"\33"}.fa-4:before{content:"\34"}.fa-5:before{content:"\35"}.fa-6:before{content:"\36"}.fa-7:before{content:"\37"}.fa-8:before{content:"\38"}.fa-9:before{content:"\39"}.fa-a:before{content:"\41"}.fa-address-book:before,.fa-contact-book:before{content:"\f2b9"}.fa-address-card:before,.fa-contact-card:before,.fa-vcard:before{content:"\f2bb"}.fa-align-center:before{content:"\f037"}.fa-align-justify:before{content:"\f039"}.fa-align-left:before{content:"\f036"}.fa-align-right:before{content:"\f038"}.fa-anchor:before{content:"\f13d"}.fa-anchor-circle-check:before{content:"\e4aa"}.fa-anchor-circle-exclamation:before{content:"\e4ab"}.fa-anchor-circle-xmark:before{content:"\e4ac"}.fa-anchor-lock:before{content:"\e4ad"}.fa-angle-down:before{content:"\f107"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-double-down:before,.fa-angles-down:before{content:"\f103"}.fa-angle-double-left:before,.fa-angles-left:before{content:"\f100"}.fa-angle-double-right:before,.fa-angles-right:before{content:"\f101"}.fa-angle-double-up:before,.fa-angles-up:before{content:"\f102"}.fa-ankh:before{content:"\f644"}.fa-apple-alt:before,.fa-apple-whole:before{content:"\f5d1"}.fa-archway:before{content:"\f557"}.fa-arrow-down:before{content:"\f063"}.fa-arrow-down-1-9:before,.fa-sort-numeric-asc:before,.fa-sort-numeric-down:before{content:"\f162"}.fa-arrow-down-9-1:before,.fa-sort-numeric-desc:before,.fa-sort-numeric-down-alt:before{content:"\f886"}.fa-arrow-down-a-z:before,.fa-sort-alpha-asc:before,.fa-sort-alpha-down:before{content:"\f15d"}.fa-arrow-down-long:before,.fa-long-arrow-down:before{content:"\f175"}.fa-arrow-down-short-wide:before,.fa-sort-amount-desc:before,.fa-sort-amount-down-alt:before{content:"\f884"}.fa-arrow-down-up-across-line:before{content:"\e4af"}.fa-arrow-down-up-lock:before{content:"\e4b0"}.fa-arrow-down-wide-short:before,.fa-sort-amount-asc:before,.fa-sort-amount-down:before{content:"\f160"}.fa-arrow-down-z-a:before,.fa-sort-alpha-desc:before,.fa-sort-alpha-down-alt:before{content:"\f881"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-left-long:before,.fa-long-arrow-left:before{content:"\f177"}.fa-arrow-pointer:before,.fa-mouse-pointer:before{content:"\f245"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-right-arrow-left:before,.fa-exchange:before{content:"\f0ec"}.fa-arrow-right-from-bracket:before,.fa-sign-out:before{content:"\f08b"}.fa-arrow-right-long:before,.fa-long-arrow-right:before{content:"\f178"}.fa-arrow-right-to-bracket:before,.fa-sign-in:before{content:"\f090"}.fa-arrow-right-to-city:before{content:"\e4b3"}.fa-arrow-left-rotate:before,.fa-arrow-rotate-back:before,.fa-arrow-rotate-backward:before,.fa-arrow-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-arrow-right-rotate:before,.fa-arrow-rotate-forward:before,.fa-arrow-rotate-right:before,.fa-redo:before{content:"\f01e"}.fa-arrow-trend-down:before{content:"\e097"}.fa-arrow-trend-up:before{content:"\e098"}.fa-arrow-turn-down:before,.fa-level-down:before{content:"\f149"}.fa-arrow-turn-up:before,.fa-level-up:before{content:"\f148"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-up-1-9:before,.fa-sort-numeric-up:before{content:"\f163"}.fa-arrow-up-9-1:before,.fa-sort-numeric-up-alt:before{content:"\f887"}.fa-arrow-up-a-z:before,.fa-sort-alpha-up:before{content:"\f15e"}.fa-arrow-up-from-bracket:before{content:"\e09a"}.fa-arrow-up-from-ground-water:before{content:"\e4b5"}.fa-arrow-up-from-water-pump:before{content:"\e4b6"}.fa-arrow-up-long:before,.fa-long-arrow-up:before{content:"\f176"}.fa-arrow-up-right-dots:before{content:"\e4b7"}.fa-arrow-up-right-from-square:before,.fa-external-link:before{content:"\f08e"}.fa-arrow-up-short-wide:before,.fa-sort-amount-up-alt:before{content:"\f885"}.fa-arrow-up-wide-short:before,.fa-sort-amount-up:before{content:"\f161"}.fa-arrow-up-z-a:before,.fa-sort-alpha-up-alt:before{content:"\f882"}.fa-arrows-down-to-line:before{content:"\e4b8"}.fa-arrows-down-to-people:before{content:"\e4b9"}.fa-arrows-h:before,.fa-arrows-left-right:before{content:"\f07e"}.fa-arrows-left-right-to-line:before{content:"\e4ba"}.fa-arrows-rotate:before,.fa-refresh:before,.fa-sync:before{content:"\f021"}.fa-arrows-spin:before{content:"\e4bb"}.fa-arrows-split-up-and-left:before{content:"\e4bc"}.fa-arrows-to-circle:before{content:"\e4bd"}.fa-arrows-to-dot:before{content:"\e4be"}.fa-arrows-to-eye:before{content:"\e4bf"}.fa-arrows-turn-right:before{content:"\e4c0"}.fa-arrows-turn-to-dots:before{content:"\e4c1"}.fa-arrows-up-down:before,.fa-arrows-v:before{content:"\f07d"}.fa-arrows-up-down-left-right:before,.fa-arrows:before{content:"\f047"}.fa-arrows-up-to-line:before{content:"\e4c2"}.fa-asterisk:before{content:"\2a"}.fa-at:before{content:"\40"}.fa-atom:before{content:"\f5d2"}.fa-audio-description:before{content:"\f29e"}.fa-austral-sign:before{content:"\e0a9"}.fa-award:before{content:"\f559"}.fa-b:before{content:"\42"}.fa-baby:before{content:"\f77c"}.fa-baby-carriage:before,.fa-carriage-baby:before{content:"\f77d"}.fa-backward:before{content:"\f04a"}.fa-backward-fast:before,.fa-fast-backward:before{content:"\f049"}.fa-backward-step:before,.fa-step-backward:before{content:"\f048"}.fa-bacon:before{content:"\f7e5"}.fa-bacteria:before{content:"\e059"}.fa-bacterium:before{content:"\e05a"}.fa-bag-shopping:before,.fa-shopping-bag:before{content:"\f290"}.fa-bahai:before,.fa-haykal:before{content:"\f666"}.fa-baht-sign:before{content:"\e0ac"}.fa-ban:before,.fa-cancel:before{content:"\f05e"}.fa-ban-smoking:before,.fa-smoking-ban:before{content:"\f54d"}.fa-band-aid:before,.fa-bandage:before{content:"\f462"}.fa-barcode:before{content:"\f02a"}.fa-bars:before,.fa-navicon:before{content:"\f0c9"}.fa-bars-progress:before,.fa-tasks-alt:before{content:"\f828"}.fa-bars-staggered:before,.fa-reorder:before,.fa-stream:before{content:"\f550"}.fa-baseball-ball:before,.fa-baseball:before{content:"\f433"}.fa-baseball-bat-ball:before{content:"\f432"}.fa-basket-shopping:before,.fa-shopping-basket:before{content:"\f291"}.fa-basketball-ball:before,.fa-basketball:before{content:"\f434"}.fa-bath:before,.fa-bathtub:before{content:"\f2cd"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-battery-5:before,.fa-battery-full:before,.fa-battery:before{content:"\f240"}.fa-battery-3:before,.fa-battery-half:before{content:"\f242"}.fa-battery-2:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-4:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-bed:before{content:"\f236"}.fa-bed-pulse:before,.fa-procedures:before{content:"\f487"}.fa-beer-mug-empty:before,.fa-beer:before{content:"\f0fc"}.fa-bell:before{content:"\f0f3"}.fa-bell-concierge:before,.fa-concierge-bell:before{content:"\f562"}.fa-bell-slash:before{content:"\f1f6"}.fa-bezier-curve:before{content:"\f55b"}.fa-bicycle:before{content:"\f206"}.fa-binoculars:before{content:"\f1e5"}.fa-biohazard:before{content:"\f780"}.fa-bitcoin-sign:before{content:"\e0b4"}.fa-blender:before{content:"\f517"}.fa-blender-phone:before{content:"\f6b6"}.fa-blog:before{content:"\f781"}.fa-bold:before{content:"\f032"}.fa-bolt:before,.fa-zap:before{content:"\f0e7"}.fa-bolt-lightning:before{content:"\e0b7"}.fa-bomb:before{content:"\f1e2"}.fa-bone:before{content:"\f5d7"}.fa-bong:before{content:"\f55c"}.fa-book:before{content:"\f02d"}.fa-atlas:before,.fa-book-atlas:before{content:"\f558"}.fa-bible:before,.fa-book-bible:before{content:"\f647"}.fa-book-bookmark:before{content:"\e0bb"}.fa-book-journal-whills:before,.fa-journal-whills:before{content:"\f66a"}.fa-book-medical:before{content:"\f7e6"}.fa-book-open:before{content:"\f518"}.fa-book-open-reader:before,.fa-book-reader:before{content:"\f5da"}.fa-book-quran:before,.fa-quran:before{content:"\f687"}.fa-book-dead:before,.fa-book-skull:before{content:"\f6b7"}.fa-book-tanakh:before,.fa-tanakh:before{content:"\f827"}.fa-bookmark:before{content:"\f02e"}.fa-border-all:before{content:"\f84c"}.fa-border-none:before{content:"\f850"}.fa-border-style:before,.fa-border-top-left:before{content:"\f853"}.fa-bore-hole:before{content:"\e4c3"}.fa-bottle-droplet:before{content:"\e4c4"}.fa-bottle-water:before{content:"\e4c5"}.fa-bowl-food:before{content:"\e4c6"}.fa-bowl-rice:before{content:"\e2eb"}.fa-bowling-ball:before{content:"\f436"}.fa-box:before{content:"\f466"}.fa-archive:before,.fa-box-archive:before{content:"\f187"}.fa-box-open:before{content:"\f49e"}.fa-box-tissue:before{content:"\e05b"}.fa-boxes-packing:before{content:"\e4c7"}.fa-boxes-alt:before,.fa-boxes-stacked:before,.fa-boxes:before{content:"\f468"}.fa-braille:before{content:"\f2a1"}.fa-brain:before{content:"\f5dc"}.fa-brazilian-real-sign:before{content:"\e46c"}.fa-bread-slice:before{content:"\f7ec"}.fa-bridge:before{content:"\e4c8"}.fa-bridge-circle-check:before{content:"\e4c9"}.fa-bridge-circle-exclamation:before{content:"\e4ca"}.fa-bridge-circle-xmark:before{content:"\e4cb"}.fa-bridge-lock:before{content:"\e4cc"}.fa-bridge-water:before{content:"\e4ce"}.fa-briefcase:before{content:"\f0b1"}.fa-briefcase-medical:before{content:"\f469"}.fa-broom:before{content:"\f51a"}.fa-broom-ball:before,.fa-quidditch-broom-ball:before,.fa-quidditch:before{content:"\f458"}.fa-brush:before{content:"\f55d"}.fa-bucket:before{content:"\e4cf"}.fa-bug:before{content:"\f188"}.fa-bug-slash:before{content:"\e490"}.fa-bugs:before{content:"\e4d0"}.fa-building:before{content:"\f1ad"}.fa-building-circle-arrow-right:before{content:"\e4d1"}.fa-building-circle-check:before{content:"\e4d2"}.fa-building-circle-exclamation:before{content:"\e4d3"}.fa-building-circle-xmark:before{content:"\e4d4"}.fa-bank:before,.fa-building-columns:before,.fa-institution:before,.fa-museum:before,.fa-university:before{content:"\f19c"}.fa-building-flag:before{content:"\e4d5"}.fa-building-lock:before{content:"\e4d6"}.fa-building-ngo:before{content:"\e4d7"}.fa-building-shield:before{content:"\e4d8"}.fa-building-un:before{content:"\e4d9"}.fa-building-user:before{content:"\e4da"}.fa-building-wheat:before{content:"\e4db"}.fa-bullhorn:before{content:"\f0a1"}.fa-bullseye:before{content:"\f140"}.fa-burger:before,.fa-hamburger:before{content:"\f805"}.fa-burst:before{content:"\e4dc"}.fa-bus:before{content:"\f207"}.fa-bus-alt:before,.fa-bus-simple:before{content:"\f55e"}.fa-briefcase-clock:before,.fa-business-time:before{content:"\f64a"}.fa-c:before{content:"\43"}.fa-cable-car:before,.fa-tram:before{content:"\f7da"}.fa-birthday-cake:before,.fa-cake-candles:before,.fa-cake:before{content:"\f1fd"}.fa-calculator:before{content:"\f1ec"}.fa-calendar:before{content:"\f133"}.fa-calendar-check:before{content:"\f274"}.fa-calendar-day:before{content:"\f783"}.fa-calendar-alt:before,.fa-calendar-days:before{content:"\f073"}.fa-calendar-minus:before{content:"\f272"}.fa-calendar-plus:before{content:"\f271"}.fa-calendar-week:before{content:"\f784"}.fa-calendar-times:before,.fa-calendar-xmark:before{content:"\f273"}.fa-camera-alt:before,.fa-camera:before{content:"\f030"}.fa-camera-retro:before{content:"\f083"}.fa-camera-rotate:before{content:"\e0d8"}.fa-campground:before{content:"\f6bb"}.fa-candy-cane:before{content:"\f786"}.fa-cannabis:before{content:"\f55f"}.fa-capsules:before{content:"\f46b"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-battery-car:before,.fa-car-battery:before{content:"\f5df"}.fa-car-burst:before,.fa-car-crash:before{content:"\f5e1"}.fa-car-on:before{content:"\e4dd"}.fa-car-alt:before,.fa-car-rear:before{content:"\f5de"}.fa-car-side:before{content:"\f5e4"}.fa-car-tunnel:before{content:"\e4de"}.fa-caravan:before{content:"\f8ff"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-caret-up:before{content:"\f0d8"}.fa-carrot:before{content:"\f787"}.fa-cart-arrow-down:before{content:"\f218"}.fa-cart-flatbed:before,.fa-dolly-flatbed:before{content:"\f474"}.fa-cart-flatbed-suitcase:before,.fa-luggage-cart:before{content:"\f59d"}.fa-cart-plus:before{content:"\f217"}.fa-cart-shopping:before,.fa-shopping-cart:before{content:"\f07a"}.fa-cash-register:before{content:"\f788"}.fa-cat:before{content:"\f6be"}.fa-cedi-sign:before{content:"\e0df"}.fa-cent-sign:before{content:"\e3f5"}.fa-certificate:before{content:"\f0a3"}.fa-chair:before{content:"\f6c0"}.fa-blackboard:before,.fa-chalkboard:before{content:"\f51b"}.fa-chalkboard-teacher:before,.fa-chalkboard-user:before{content:"\f51c"}.fa-champagne-glasses:before,.fa-glass-cheers:before{content:"\f79f"}.fa-charging-station:before{content:"\f5e7"}.fa-area-chart:before,.fa-chart-area:before{content:"\f1fe"}.fa-bar-chart:before,.fa-chart-bar:before{content:"\f080"}.fa-chart-column:before{content:"\e0e3"}.fa-chart-gantt:before{content:"\e0e4"}.fa-chart-line:before,.fa-line-chart:before{content:"\f201"}.fa-chart-pie:before,.fa-pie-chart:before{content:"\f200"}.fa-chart-simple:before{content:"\e473"}.fa-check:before{content:"\f00c"}.fa-check-double:before{content:"\f560"}.fa-check-to-slot:before,.fa-vote-yea:before{content:"\f772"}.fa-cheese:before{content:"\f7ef"}.fa-chess:before{content:"\f439"}.fa-chess-bishop:before{content:"\f43a"}.fa-chess-board:before{content:"\f43c"}.fa-chess-king:before{content:"\f43f"}.fa-chess-knight:before{content:"\f441"}.fa-chess-pawn:before{content:"\f443"}.fa-chess-queen:before{content:"\f445"}.fa-chess-rook:before{content:"\f447"}.fa-chevron-down:before{content:"\f078"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-chevron-up:before{content:"\f077"}.fa-child:before{content:"\f1ae"}.fa-child-dress:before{content:"\e59c"}.fa-child-reaching:before{content:"\e59d"}.fa-child-rifle:before{content:"\e4e0"}.fa-children:before{content:"\e4e1"}.fa-church:before{content:"\f51d"}.fa-circle:before{content:"\f111"}.fa-arrow-circle-down:before,.fa-circle-arrow-down:before{content:"\f0ab"}.fa-arrow-circle-left:before,.fa-circle-arrow-left:before{content:"\f0a8"}.fa-arrow-circle-right:before,.fa-circle-arrow-right:before{content:"\f0a9"}.fa-arrow-circle-up:before,.fa-circle-arrow-up:before{content:"\f0aa"}.fa-check-circle:before,.fa-circle-check:before{content:"\f058"}.fa-chevron-circle-down:before,.fa-circle-chevron-down:before{content:"\f13a"}.fa-chevron-circle-left:before,.fa-circle-chevron-left:before{content:"\f137"}.fa-chevron-circle-right:before,.fa-circle-chevron-right:before{content:"\f138"}.fa-chevron-circle-up:before,.fa-circle-chevron-up:before{content:"\f139"}.fa-circle-dollar-to-slot:before,.fa-donate:before{content:"\f4b9"}.fa-circle-dot:before,.fa-dot-circle:before{content:"\f192"}.fa-arrow-alt-circle-down:before,.fa-circle-down:before{content:"\f358"}.fa-circle-exclamation:before,.fa-exclamation-circle:before{content:"\f06a"}.fa-circle-h:before,.fa-hospital-symbol:before{content:"\f47e"}.fa-adjust:before,.fa-circle-half-stroke:before{content:"\f042"}.fa-circle-info:before,.fa-info-circle:before{content:"\f05a"}.fa-arrow-alt-circle-left:before,.fa-circle-left:before{content:"\f359"}.fa-circle-minus:before,.fa-minus-circle:before{content:"\f056"}.fa-circle-nodes:before{content:"\e4e2"}.fa-circle-notch:before{content:"\f1ce"}.fa-circle-pause:before,.fa-pause-circle:before{content:"\f28b"}.fa-circle-play:before,.fa-play-circle:before{content:"\f144"}.fa-circle-plus:before,.fa-plus-circle:before{content:"\f055"}.fa-circle-question:before,.fa-question-circle:before{content:"\f059"}.fa-circle-radiation:before,.fa-radiation-alt:before{content:"\f7ba"}.fa-arrow-alt-circle-right:before,.fa-circle-right:before{content:"\f35a"}.fa-circle-stop:before,.fa-stop-circle:before{content:"\f28d"}.fa-arrow-alt-circle-up:before,.fa-circle-up:before{content:"\f35b"}.fa-circle-user:before,.fa-user-circle:before{content:"\f2bd"}.fa-circle-xmark:before,.fa-times-circle:before,.fa-xmark-circle:before{content:"\f057"}.fa-city:before{content:"\f64f"}.fa-clapperboard:before{content:"\e131"}.fa-clipboard:before{content:"\f328"}.fa-clipboard-check:before{content:"\f46c"}.fa-clipboard-list:before{content:"\f46d"}.fa-clipboard-question:before{content:"\e4e3"}.fa-clipboard-user:before{content:"\f7f3"}.fa-clock-four:before,.fa-clock:before{content:"\f017"}.fa-clock-rotate-left:before,.fa-history:before{content:"\f1da"}.fa-clone:before{content:"\f24d"}.fa-closed-captioning:before{content:"\f20a"}.fa-cloud:before{content:"\f0c2"}.fa-cloud-arrow-down:before,.fa-cloud-download-alt:before,.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-arrow-up:before,.fa-cloud-upload-alt:before,.fa-cloud-upload:before{content:"\f0ee"}.fa-cloud-bolt:before,.fa-thunderstorm:before{content:"\f76c"}.fa-cloud-meatball:before{content:"\f73b"}.fa-cloud-moon:before{content:"\f6c3"}.fa-cloud-moon-rain:before{content:"\f73c"}.fa-cloud-rain:before{content:"\f73d"}.fa-cloud-showers-heavy:before{content:"\f740"}.fa-cloud-showers-water:before{content:"\e4e4"}.fa-cloud-sun:before{content:"\f6c4"}.fa-cloud-sun-rain:before{content:"\f743"}.fa-clover:before{content:"\e139"}.fa-code:before{content:"\f121"}.fa-code-branch:before{content:"\f126"}.fa-code-commit:before{content:"\f386"}.fa-code-compare:before{content:"\e13a"}.fa-code-fork:before{content:"\e13b"}.fa-code-merge:before{content:"\f387"}.fa-code-pull-request:before{content:"\e13c"}.fa-coins:before{content:"\f51e"}.fa-colon-sign:before{content:"\e140"}.fa-comment:before{content:"\f075"}.fa-comment-dollar:before{content:"\f651"}.fa-comment-dots:before,.fa-commenting:before{content:"\f4ad"}.fa-comment-medical:before{content:"\f7f5"}.fa-comment-slash:before{content:"\f4b3"}.fa-comment-sms:before,.fa-sms:before{content:"\f7cd"}.fa-comments:before{content:"\f086"}.fa-comments-dollar:before{content:"\f653"}.fa-compact-disc:before{content:"\f51f"}.fa-compass:before{content:"\f14e"}.fa-compass-drafting:before,.fa-drafting-compass:before{content:"\f568"}.fa-compress:before{content:"\f066"}.fa-computer:before{content:"\e4e5"}.fa-computer-mouse:before,.fa-mouse:before{content:"\f8cc"}.fa-cookie:before{content:"\f563"}.fa-cookie-bite:before{content:"\f564"}.fa-copy:before{content:"\f0c5"}.fa-copyright:before{content:"\f1f9"}.fa-couch:before{content:"\f4b8"}.fa-cow:before{content:"\f6c8"}.fa-credit-card-alt:before,.fa-credit-card:before{content:"\f09d"}.fa-crop:before{content:"\f125"}.fa-crop-alt:before,.fa-crop-simple:before{content:"\f565"}.fa-cross:before{content:"\f654"}.fa-crosshairs:before{content:"\f05b"}.fa-crow:before{content:"\f520"}.fa-crown:before{content:"\f521"}.fa-crutch:before{content:"\f7f7"}.fa-cruzeiro-sign:before{content:"\e152"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-cubes-stacked:before{content:"\e4e6"}.fa-d:before{content:"\44"}.fa-database:before{content:"\f1c0"}.fa-backspace:before,.fa-delete-left:before{content:"\f55a"}.fa-democrat:before{content:"\f747"}.fa-desktop-alt:before,.fa-desktop:before{content:"\f390"}.fa-dharmachakra:before{content:"\f655"}.fa-diagram-next:before{content:"\e476"}.fa-diagram-predecessor:before{content:"\e477"}.fa-diagram-project:before,.fa-project-diagram:before{content:"\f542"}.fa-diagram-successor:before{content:"\e47a"}.fa-diamond:before{content:"\f219"}.fa-diamond-turn-right:before,.fa-directions:before{content:"\f5eb"}.fa-dice:before{content:"\f522"}.fa-dice-d20:before{content:"\f6cf"}.fa-dice-d6:before{content:"\f6d1"}.fa-dice-five:before{content:"\f523"}.fa-dice-four:before{content:"\f524"}.fa-dice-one:before{content:"\f525"}.fa-dice-six:before{content:"\f526"}.fa-dice-three:before{content:"\f527"}.fa-dice-two:before{content:"\f528"}.fa-disease:before{content:"\f7fa"}.fa-display:before{content:"\e163"}.fa-divide:before{content:"\f529"}.fa-dna:before{content:"\f471"}.fa-dog:before{content:"\f6d3"}.fa-dollar-sign:before,.fa-dollar:before,.fa-usd:before{content:"\24"}.fa-dolly-box:before,.fa-dolly:before{content:"\f472"}.fa-dong-sign:before{content:"\e169"}.fa-door-closed:before{content:"\f52a"}.fa-door-open:before{content:"\f52b"}.fa-dove:before{content:"\f4ba"}.fa-compress-alt:before,.fa-down-left-and-up-right-to-center:before{content:"\f422"}.fa-down-long:before,.fa-long-arrow-alt-down:before{content:"\f309"}.fa-download:before{content:"\f019"}.fa-dragon:before{content:"\f6d5"}.fa-draw-polygon:before{content:"\f5ee"}.fa-droplet:before,.fa-tint:before{content:"\f043"}.fa-droplet-slash:before,.fa-tint-slash:before{content:"\f5c7"}.fa-drum:before{content:"\f569"}.fa-drum-steelpan:before{content:"\f56a"}.fa-drumstick-bite:before{content:"\f6d7"}.fa-dumbbell:before{content:"\f44b"}.fa-dumpster:before{content:"\f793"}.fa-dumpster-fire:before{content:"\f794"}.fa-dungeon:before{content:"\f6d9"}.fa-e:before{content:"\45"}.fa-deaf:before,.fa-deafness:before,.fa-ear-deaf:before,.fa-hard-of-hearing:before{content:"\f2a4"}.fa-assistive-listening-systems:before,.fa-ear-listen:before{content:"\f2a2"}.fa-earth-africa:before,.fa-globe-africa:before{content:"\f57c"}.fa-earth-america:before,.fa-earth-americas:before,.fa-earth:before,.fa-globe-americas:before{content:"\f57d"}.fa-earth-asia:before,.fa-globe-asia:before{content:"\f57e"}.fa-earth-europe:before,.fa-globe-europe:before{content:"\f7a2"}.fa-earth-oceania:before,.fa-globe-oceania:before{content:"\e47b"}.fa-egg:before{content:"\f7fb"}.fa-eject:before{content:"\f052"}.fa-elevator:before{content:"\e16d"}.fa-ellipsis-h:before,.fa-ellipsis:before{content:"\f141"}.fa-ellipsis-v:before,.fa-ellipsis-vertical:before{content:"\f142"}.fa-envelope:before{content:"\f0e0"}.fa-envelope-circle-check:before{content:"\e4e8"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-text:before{content:"\f658"}.fa-envelopes-bulk:before,.fa-mail-bulk:before{content:"\f674"}.fa-equals:before{content:"\3d"}.fa-eraser:before{content:"\f12d"}.fa-ethernet:before{content:"\f796"}.fa-eur:before,.fa-euro-sign:before,.fa-euro:before{content:"\f153"}.fa-exclamation:before{content:"\21"}.fa-expand:before{content:"\f065"}.fa-explosion:before{content:"\e4e9"}.fa-eye:before{content:"\f06e"}.fa-eye-dropper-empty:before,.fa-eye-dropper:before,.fa-eyedropper:before{content:"\f1fb"}.fa-eye-low-vision:before,.fa-low-vision:before{content:"\f2a8"}.fa-eye-slash:before{content:"\f070"}.fa-f:before{content:"\46"}.fa-angry:before,.fa-face-angry:before{content:"\f556"}.fa-dizzy:before,.fa-face-dizzy:before{content:"\f567"}.fa-face-flushed:before,.fa-flushed:before{content:"\f579"}.fa-face-frown:before,.fa-frown:before{content:"\f119"}.fa-face-frown-open:before,.fa-frown-open:before{content:"\f57a"}.fa-face-grimace:before,.fa-grimace:before{content:"\f57f"}.fa-face-grin:before,.fa-grin:before{content:"\f580"}.fa-face-grin-beam:before,.fa-grin-beam:before{content:"\f582"}.fa-face-grin-beam-sweat:before,.fa-grin-beam-sweat:before{content:"\f583"}.fa-face-grin-hearts:before,.fa-grin-hearts:before{content:"\f584"}.fa-face-grin-squint:before,.fa-grin-squint:before{content:"\f585"}.fa-face-grin-squint-tears:before,.fa-grin-squint-tears:before{content:"\f586"}.fa-face-grin-stars:before,.fa-grin-stars:before{content:"\f587"}.fa-face-grin-tears:before,.fa-grin-tears:before{content:"\f588"}.fa-face-grin-tongue:before,.fa-grin-tongue:before{content:"\f589"}.fa-face-grin-tongue-squint:before,.fa-grin-tongue-squint:before{content:"\f58a"}.fa-face-grin-tongue-wink:before,.fa-grin-tongue-wink:before{content:"\f58b"}.fa-face-grin-wide:before,.fa-grin-alt:before{content:"\f581"}.fa-face-grin-wink:before,.fa-grin-wink:before{content:"\f58c"}.fa-face-kiss:before,.fa-kiss:before{content:"\f596"}.fa-face-kiss-beam:before,.fa-kiss-beam:before{content:"\f597"}.fa-face-kiss-wink-heart:before,.fa-kiss-wink-heart:before{content:"\f598"}.fa-face-laugh:before,.fa-laugh:before{content:"\f599"}.fa-face-laugh-beam:before,.fa-laugh-beam:before{content:"\f59a"}.fa-face-laugh-squint:before,.fa-laugh-squint:before{content:"\f59b"}.fa-face-laugh-wink:before,.fa-laugh-wink:before{content:"\f59c"}.fa-face-meh:before,.fa-meh:before{content:"\f11a"}.fa-face-meh-blank:before,.fa-meh-blank:before{content:"\f5a4"}.fa-face-rolling-eyes:before,.fa-meh-rolling-eyes:before{content:"\f5a5"}.fa-face-sad-cry:before,.fa-sad-cry:before{content:"\f5b3"}.fa-face-sad-tear:before,.fa-sad-tear:before{content:"\f5b4"}.fa-face-smile:before,.fa-smile:before{content:"\f118"}.fa-face-smile-beam:before,.fa-smile-beam:before{content:"\f5b8"}.fa-face-smile-wink:before,.fa-smile-wink:before{content:"\f4da"}.fa-face-surprise:before,.fa-surprise:before{content:"\f5c2"}.fa-face-tired:before,.fa-tired:before{content:"\f5c8"}.fa-fan:before{content:"\f863"}.fa-faucet:before{content:"\e005"}.fa-faucet-drip:before{content:"\e006"}.fa-fax:before{content:"\f1ac"}.fa-feather:before{content:"\f52d"}.fa-feather-alt:before,.fa-feather-pointed:before{content:"\f56b"}.fa-ferry:before{content:"\e4ea"}.fa-file:before{content:"\f15b"}.fa-file-arrow-down:before,.fa-file-download:before{content:"\f56d"}.fa-file-arrow-up:before,.fa-file-upload:before{content:"\f574"}.fa-file-audio:before{content:"\f1c7"}.fa-file-circle-check:before{content:"\e5a0"}.fa-file-circle-exclamation:before{content:"\e4eb"}.fa-file-circle-minus:before{content:"\e4ed"}.fa-file-circle-plus:before{content:"\e494"}.fa-file-circle-question:before{content:"\e4ef"}.fa-file-circle-xmark:before{content:"\e5a1"}.fa-file-code:before{content:"\f1c9"}.fa-file-contract:before{content:"\f56c"}.fa-file-csv:before{content:"\f6dd"}.fa-file-excel:before{content:"\f1c3"}.fa-arrow-right-from-file:before,.fa-file-export:before{content:"\f56e"}.fa-file-image:before{content:"\f1c5"}.fa-arrow-right-to-file:before,.fa-file-import:before{content:"\f56f"}.fa-file-invoice:before{content:"\f570"}.fa-file-invoice-dollar:before{content:"\f571"}.fa-file-alt:before,.fa-file-lines:before,.fa-file-text:before{content:"\f15c"}.fa-file-medical:before{content:"\f477"}.fa-file-pdf:before{content:"\f1c1"}.fa-file-edit:before,.fa-file-pen:before{content:"\f31c"}.fa-file-powerpoint:before{content:"\f1c4"}.fa-file-prescription:before{content:"\f572"}.fa-file-shield:before{content:"\e4f0"}.fa-file-signature:before{content:"\f573"}.fa-file-video:before{content:"\f1c8"}.fa-file-medical-alt:before,.fa-file-waveform:before{content:"\f478"}.fa-file-word:before{content:"\f1c2"}.fa-file-archive:before,.fa-file-zipper:before{content:"\f1c6"}.fa-fill:before{content:"\f575"}.fa-fill-drip:before{content:"\f576"}.fa-film:before{content:"\f008"}.fa-filter:before{content:"\f0b0"}.fa-filter-circle-dollar:before,.fa-funnel-dollar:before{content:"\f662"}.fa-filter-circle-xmark:before{content:"\e17b"}.fa-fingerprint:before{content:"\f577"}.fa-fire:before{content:"\f06d"}.fa-fire-burner:before{content:"\e4f1"}.fa-fire-extinguisher:before{content:"\f134"}.fa-fire-alt:before,.fa-fire-flame-curved:before{content:"\f7e4"}.fa-burn:before,.fa-fire-flame-simple:before{content:"\f46a"}.fa-fish:before{content:"\f578"}.fa-fish-fins:before{content:"\e4f2"}.fa-flag:before{content:"\f024"}.fa-flag-checkered:before{content:"\f11e"}.fa-flag-usa:before{content:"\f74d"}.fa-flask:before{content:"\f0c3"}.fa-flask-vial:before{content:"\e4f3"}.fa-floppy-disk:before,.fa-save:before{content:"\f0c7"}.fa-florin-sign:before{content:"\e184"}.fa-folder-blank:before,.fa-folder:before{content:"\f07b"}.fa-folder-closed:before{content:"\e185"}.fa-folder-minus:before{content:"\f65d"}.fa-folder-open:before{content:"\f07c"}.fa-folder-plus:before{content:"\f65e"}.fa-folder-tree:before{content:"\f802"}.fa-font:before{content:"\f031"}.fa-football-ball:before,.fa-football:before{content:"\f44e"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before,.fa-forward-fast:before{content:"\f050"}.fa-forward-step:before,.fa-step-forward:before{content:"\f051"}.fa-franc-sign:before{content:"\e18f"}.fa-frog:before{content:"\f52e"}.fa-futbol-ball:before,.fa-futbol:before,.fa-soccer-ball:before{content:"\f1e3"}.fa-g:before{content:"\47"}.fa-gamepad:before{content:"\f11b"}.fa-gas-pump:before{content:"\f52f"}.fa-dashboard:before,.fa-gauge-med:before,.fa-gauge:before,.fa-tachometer-alt-average:before{content:"\f624"}.fa-gauge-high:before,.fa-tachometer-alt-fast:before,.fa-tachometer-alt:before{content:"\f625"}.fa-gauge-simple-med:before,.fa-gauge-simple:before,.fa-tachometer-average:before{content:"\f629"}.fa-gauge-simple-high:before,.fa-tachometer-fast:before,.fa-tachometer:before{content:"\f62a"}.fa-gavel:before,.fa-legal:before{content:"\f0e3"}.fa-cog:before,.fa-gear:before{content:"\f013"}.fa-cogs:before,.fa-gears:before{content:"\f085"}.fa-gem:before{content:"\f3a5"}.fa-genderless:before{content:"\f22d"}.fa-ghost:before{content:"\f6e2"}.fa-gift:before{content:"\f06b"}.fa-gifts:before{content:"\f79c"}.fa-glass-water:before{content:"\e4f4"}.fa-glass-water-droplet:before{content:"\e4f5"}.fa-glasses:before{content:"\f530"}.fa-globe:before{content:"\f0ac"}.fa-golf-ball-tee:before,.fa-golf-ball:before{content:"\f450"}.fa-gopuram:before{content:"\f664"}.fa-graduation-cap:before,.fa-mortar-board:before{content:"\f19d"}.fa-greater-than:before{content:"\3e"}.fa-greater-than-equal:before{content:"\f532"}.fa-grip-horizontal:before,.fa-grip:before{content:"\f58d"}.fa-grip-lines:before{content:"\f7a4"}.fa-grip-lines-vertical:before{content:"\f7a5"}.fa-grip-vertical:before{content:"\f58e"}.fa-group-arrows-rotate:before{content:"\e4f6"}.fa-guarani-sign:before{content:"\e19a"}.fa-guitar:before{content:"\f7a6"}.fa-gun:before{content:"\e19b"}.fa-h:before{content:"\48"}.fa-hammer:before{content:"\f6e3"}.fa-hamsa:before{content:"\f665"}.fa-hand-paper:before,.fa-hand:before{content:"\f256"}.fa-hand-back-fist:before,.fa-hand-rock:before{content:"\f255"}.fa-allergies:before,.fa-hand-dots:before{content:"\f461"}.fa-fist-raised:before,.fa-hand-fist:before{content:"\f6de"}.fa-hand-holding:before{content:"\f4bd"}.fa-hand-holding-dollar:before,.fa-hand-holding-usd:before{content:"\f4c0"}.fa-hand-holding-droplet:before,.fa-hand-holding-water:before{content:"\f4c1"}.fa-hand-holding-hand:before{content:"\e4f7"}.fa-hand-holding-heart:before{content:"\f4be"}.fa-hand-holding-medical:before{content:"\e05c"}.fa-hand-lizard:before{content:"\f258"}.fa-hand-middle-finger:before{content:"\f806"}.fa-hand-peace:before{content:"\f25b"}.fa-hand-point-down:before{content:"\f0a7"}.fa-hand-point-left:before{content:"\f0a5"}.fa-hand-point-right:before{content:"\f0a4"}.fa-hand-point-up:before{content:"\f0a6"}.fa-hand-pointer:before{content:"\f25a"}.fa-hand-scissors:before{content:"\f257"}.fa-hand-sparkles:before{content:"\e05d"}.fa-hand-spock:before{content:"\f259"}.fa-handcuffs:before{content:"\e4f8"}.fa-hands:before,.fa-sign-language:before,.fa-signing:before{content:"\f2a7"}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before,.fa-hands-american-sign-language-interpreting:before,.fa-hands-asl-interpreting:before{content:"\f2a3"}.fa-hands-bound:before{content:"\e4f9"}.fa-hands-bubbles:before,.fa-hands-wash:before{content:"\e05e"}.fa-hands-clapping:before{content:"\e1a8"}.fa-hands-holding:before{content:"\f4c2"}.fa-hands-holding-child:before{content:"\e4fa"}.fa-hands-holding-circle:before{content:"\e4fb"}.fa-hands-praying:before,.fa-praying-hands:before{content:"\f684"}.fa-handshake:before{content:"\f2b5"}.fa-hands-helping:before,.fa-handshake-angle:before{content:"\f4c4"}.fa-handshake-alt:before,.fa-handshake-simple:before{content:"\f4c6"}.fa-handshake-alt-slash:before,.fa-handshake-simple-slash:before{content:"\e05f"}.fa-handshake-slash:before{content:"\e060"}.fa-hanukiah:before{content:"\f6e6"}.fa-hard-drive:before,.fa-hdd:before{content:"\f0a0"}.fa-hashtag:before{content:"\23"}.fa-hat-cowboy:before{content:"\f8c0"}.fa-hat-cowboy-side:before{content:"\f8c1"}.fa-hat-wizard:before{content:"\f6e8"}.fa-head-side-cough:before{content:"\e061"}.fa-head-side-cough-slash:before{content:"\e062"}.fa-head-side-mask:before{content:"\e063"}.fa-head-side-virus:before{content:"\e064"}.fa-header:before,.fa-heading:before{content:"\f1dc"}.fa-headphones:before{content:"\f025"}.fa-headphones-alt:before,.fa-headphones-simple:before{content:"\f58f"}.fa-headset:before{content:"\f590"}.fa-heart:before{content:"\f004"}.fa-heart-circle-bolt:before{content:"\e4fc"}.fa-heart-circle-check:before{content:"\e4fd"}.fa-heart-circle-exclamation:before{content:"\e4fe"}.fa-heart-circle-minus:before{content:"\e4ff"}.fa-heart-circle-plus:before{content:"\e500"}.fa-heart-circle-xmark:before{content:"\e501"}.fa-heart-broken:before,.fa-heart-crack:before{content:"\f7a9"}.fa-heart-pulse:before,.fa-heartbeat:before{content:"\f21e"}.fa-helicopter:before{content:"\f533"}.fa-helicopter-symbol:before{content:"\e502"}.fa-hard-hat:before,.fa-hat-hard:before,.fa-helmet-safety:before{content:"\f807"}.fa-helmet-un:before{content:"\e503"}.fa-highlighter:before{content:"\f591"}.fa-hill-avalanche:before{content:"\e507"}.fa-hill-rockslide:before{content:"\e508"}.fa-hippo:before{content:"\f6ed"}.fa-hockey-puck:before{content:"\f453"}.fa-holly-berry:before{content:"\f7aa"}.fa-horse:before{content:"\f6f0"}.fa-horse-head:before{content:"\f7ab"}.fa-hospital-alt:before,.fa-hospital-wide:before,.fa-hospital:before{content:"\f0f8"}.fa-hospital-user:before{content:"\f80d"}.fa-hot-tub-person:before,.fa-hot-tub:before{content:"\f593"}.fa-hotdog:before{content:"\f80f"}.fa-hotel:before{content:"\f594"}.fa-hourglass-empty:before,.fa-hourglass:before{content:"\f254"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-home-alt:before,.fa-home-lg-alt:before,.fa-home:before,.fa-house:before{content:"\f015"}.fa-home-lg:before,.fa-house-chimney:before{content:"\e3af"}.fa-house-chimney-crack:before,.fa-house-damage:before{content:"\f6f1"}.fa-clinic-medical:before,.fa-house-chimney-medical:before{content:"\f7f2"}.fa-house-chimney-user:before{content:"\e065"}.fa-house-chimney-window:before{content:"\e00d"}.fa-house-circle-check:before{content:"\e509"}.fa-house-circle-exclamation:before{content:"\e50a"}.fa-house-circle-xmark:before{content:"\e50b"}.fa-house-crack:before{content:"\e3b1"}.fa-house-fire:before{content:"\e50c"}.fa-house-flag:before{content:"\e50d"}.fa-house-flood-water:before{content:"\e50e"}.fa-house-flood-water-circle-arrow-right:before{content:"\e50f"}.fa-house-laptop:before,.fa-laptop-house:before{content:"\e066"}.fa-house-lock:before{content:"\e510"}.fa-house-medical:before{content:"\e3b2"}.fa-house-medical-circle-check:before{content:"\e511"}.fa-house-medical-circle-exclamation:before{content:"\e512"}.fa-house-medical-circle-xmark:before{content:"\e513"}.fa-house-medical-flag:before{content:"\e514"}.fa-house-signal:before{content:"\e012"}.fa-house-tsunami:before{content:"\e515"}.fa-home-user:before,.fa-house-user:before{content:"\e1b0"}.fa-hryvnia-sign:before,.fa-hryvnia:before{content:"\f6f2"}.fa-hurricane:before{content:"\f751"}.fa-i:before{content:"\49"}.fa-i-cursor:before{content:"\f246"}.fa-ice-cream:before{content:"\f810"}.fa-icicles:before{content:"\f7ad"}.fa-heart-music-camera-bolt:before,.fa-icons:before{content:"\f86d"}.fa-id-badge:before{content:"\f2c1"}.fa-drivers-license:before,.fa-id-card:before{content:"\f2c2"}.fa-id-card-alt:before,.fa-id-card-clip:before{content:"\f47f"}.fa-igloo:before{content:"\f7ae"}.fa-image:before{content:"\f03e"}.fa-image-portrait:before,.fa-portrait:before{content:"\f3e0"}.fa-images:before{content:"\f302"}.fa-inbox:before{content:"\f01c"}.fa-indent:before{content:"\f03c"}.fa-indian-rupee-sign:before,.fa-indian-rupee:before,.fa-inr:before{content:"\e1bc"}.fa-industry:before{content:"\f275"}.fa-infinity:before{content:"\f534"}.fa-info:before{content:"\f129"}.fa-italic:before{content:"\f033"}.fa-j:before{content:"\4a"}.fa-jar:before{content:"\e516"}.fa-jar-wheat:before{content:"\e517"}.fa-jedi:before{content:"\f669"}.fa-fighter-jet:before,.fa-jet-fighter:before{content:"\f0fb"}.fa-jet-fighter-up:before{content:"\e518"}.fa-joint:before{content:"\f595"}.fa-jug-detergent:before{content:"\e519"}.fa-k:before{content:"\4b"}.fa-kaaba:before{content:"\f66b"}.fa-key:before{content:"\f084"}.fa-keyboard:before{content:"\f11c"}.fa-khanda:before{content:"\f66d"}.fa-kip-sign:before{content:"\e1c4"}.fa-first-aid:before,.fa-kit-medical:before{content:"\f479"}.fa-kitchen-set:before{content:"\e51a"}.fa-kiwi-bird:before{content:"\f535"}.fa-l:before{content:"\4c"}.fa-land-mine-on:before{content:"\e51b"}.fa-landmark:before{content:"\f66f"}.fa-landmark-alt:before,.fa-landmark-dome:before{content:"\f752"}.fa-landmark-flag:before{content:"\e51c"}.fa-language:before{content:"\f1ab"}.fa-laptop:before{content:"\f109"}.fa-laptop-code:before{content:"\f5fc"}.fa-laptop-file:before{content:"\e51d"}.fa-laptop-medical:before{content:"\f812"}.fa-lari-sign:before{content:"\e1c8"}.fa-layer-group:before{content:"\f5fd"}.fa-leaf:before{content:"\f06c"}.fa-left-long:before,.fa-long-arrow-alt-left:before{content:"\f30a"}.fa-arrows-alt-h:before,.fa-left-right:before{content:"\f337"}.fa-lemon:before{content:"\f094"}.fa-less-than:before{content:"\3c"}.fa-less-than-equal:before{content:"\f537"}.fa-life-ring:before{content:"\f1cd"}.fa-lightbulb:before{content:"\f0eb"}.fa-lines-leaning:before{content:"\e51e"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-chain-broken:before,.fa-chain-slash:before,.fa-link-slash:before,.fa-unlink:before{content:"\f127"}.fa-lira-sign:before{content:"\f195"}.fa-list-squares:before,.fa-list:before{content:"\f03a"}.fa-list-check:before,.fa-tasks:before{content:"\f0ae"}.fa-list-1-2:before,.fa-list-numeric:before,.fa-list-ol:before{content:"\f0cb"}.fa-list-dots:before,.fa-list-ul:before{content:"\f0ca"}.fa-litecoin-sign:before{content:"\e1d3"}.fa-location-arrow:before{content:"\f124"}.fa-location-crosshairs:before,.fa-location:before{content:"\f601"}.fa-location-dot:before,.fa-map-marker-alt:before{content:"\f3c5"}.fa-location-pin:before,.fa-map-marker:before{content:"\f041"}.fa-location-pin-lock:before{content:"\e51f"}.fa-lock:before{content:"\f023"}.fa-lock-open:before{content:"\f3c1"}.fa-locust:before{content:"\e520"}.fa-lungs:before{content:"\f604"}.fa-lungs-virus:before{content:"\e067"}.fa-m:before{content:"\4d"}.fa-magnet:before{content:"\f076"}.fa-magnifying-glass:before,.fa-search:before{content:"\f002"}.fa-magnifying-glass-arrow-right:before{content:"\e521"}.fa-magnifying-glass-chart:before{content:"\e522"}.fa-magnifying-glass-dollar:before,.fa-search-dollar:before{content:"\f688"}.fa-magnifying-glass-location:before,.fa-search-location:before{content:"\f689"}.fa-magnifying-glass-minus:before,.fa-search-minus:before{content:"\f010"}.fa-magnifying-glass-plus:before,.fa-search-plus:before{content:"\f00e"}.fa-manat-sign:before{content:"\e1d5"}.fa-map:before{content:"\f279"}.fa-map-location:before,.fa-map-marked:before{content:"\f59f"}.fa-map-location-dot:before,.fa-map-marked-alt:before{content:"\f5a0"}.fa-map-pin:before{content:"\f276"}.fa-marker:before{content:"\f5a1"}.fa-mars:before{content:"\f222"}.fa-mars-and-venus:before{content:"\f224"}.fa-mars-and-venus-burst:before{content:"\e523"}.fa-mars-double:before{content:"\f227"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-h:before,.fa-mars-stroke-right:before{content:"\f22b"}.fa-mars-stroke-up:before,.fa-mars-stroke-v:before{content:"\f22a"}.fa-glass-martini-alt:before,.fa-martini-glass:before{content:"\f57b"}.fa-cocktail:before,.fa-martini-glass-citrus:before{content:"\f561"}.fa-glass-martini:before,.fa-martini-glass-empty:before{content:"\f000"}.fa-mask:before{content:"\f6fa"}.fa-mask-face:before{content:"\e1d7"}.fa-mask-ventilator:before{content:"\e524"}.fa-masks-theater:before,.fa-theater-masks:before{content:"\f630"}.fa-mattress-pillow:before{content:"\e525"}.fa-expand-arrows-alt:before,.fa-maximize:before{content:"\f31e"}.fa-medal:before{content:"\f5a2"}.fa-memory:before{content:"\f538"}.fa-menorah:before{content:"\f676"}.fa-mercury:before{content:"\f223"}.fa-comment-alt:before,.fa-message:before{content:"\f27a"}.fa-meteor:before{content:"\f753"}.fa-microchip:before{content:"\f2db"}.fa-microphone:before{content:"\f130"}.fa-microphone-alt:before,.fa-microphone-lines:before{content:"\f3c9"}.fa-microphone-alt-slash:before,.fa-microphone-lines-slash:before{content:"\f539"}.fa-microphone-slash:before{content:"\f131"}.fa-microscope:before{content:"\f610"}.fa-mill-sign:before{content:"\e1ed"}.fa-compress-arrows-alt:before,.fa-minimize:before{content:"\f78c"}.fa-minus:before,.fa-subtract:before{content:"\f068"}.fa-mitten:before{content:"\f7b5"}.fa-mobile-android:before,.fa-mobile-phone:before,.fa-mobile:before{content:"\f3ce"}.fa-mobile-button:before{content:"\f10b"}.fa-mobile-retro:before{content:"\e527"}.fa-mobile-android-alt:before,.fa-mobile-screen:before{content:"\f3cf"}.fa-mobile-alt:before,.fa-mobile-screen-button:before{content:"\f3cd"}.fa-money-bill:before{content:"\f0d6"}.fa-money-bill-1:before,.fa-money-bill-alt:before{content:"\f3d1"}.fa-money-bill-1-wave:before,.fa-money-bill-wave-alt:before{content:"\f53b"}.fa-money-bill-transfer:before{content:"\e528"}.fa-money-bill-trend-up:before{content:"\e529"}.fa-money-bill-wave:before{content:"\f53a"}.fa-money-bill-wheat:before{content:"\e52a"}.fa-money-bills:before{content:"\e1f3"}.fa-money-check:before{content:"\f53c"}.fa-money-check-alt:before,.fa-money-check-dollar:before{content:"\f53d"}.fa-monument:before{content:"\f5a6"}.fa-moon:before{content:"\f186"}.fa-mortar-pestle:before{content:"\f5a7"}.fa-mosque:before{content:"\f678"}.fa-mosquito:before{content:"\e52b"}.fa-mosquito-net:before{content:"\e52c"}.fa-motorcycle:before{content:"\f21c"}.fa-mound:before{content:"\e52d"}.fa-mountain:before{content:"\f6fc"}.fa-mountain-city:before{content:"\e52e"}.fa-mountain-sun:before{content:"\e52f"}.fa-mug-hot:before{content:"\f7b6"}.fa-coffee:before,.fa-mug-saucer:before{content:"\f0f4"}.fa-music:before{content:"\f001"}.fa-n:before{content:"\4e"}.fa-naira-sign:before{content:"\e1f6"}.fa-network-wired:before{content:"\f6ff"}.fa-neuter:before{content:"\f22c"}.fa-newspaper:before{content:"\f1ea"}.fa-not-equal:before{content:"\f53e"}.fa-notdef:before{content:"\e1fe"}.fa-note-sticky:before,.fa-sticky-note:before{content:"\f249"}.fa-notes-medical:before{content:"\f481"}.fa-o:before{content:"\4f"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-oil-can:before{content:"\f613"}.fa-oil-well:before{content:"\e532"}.fa-om:before{content:"\f679"}.fa-otter:before{content:"\f700"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-p:before{content:"\50"}.fa-pager:before{content:"\f815"}.fa-paint-roller:before{content:"\f5aa"}.fa-paint-brush:before,.fa-paintbrush:before{content:"\f1fc"}.fa-palette:before{content:"\f53f"}.fa-pallet:before{content:"\f482"}.fa-panorama:before{content:"\e209"}.fa-paper-plane:before{content:"\f1d8"}.fa-paperclip:before{content:"\f0c6"}.fa-parachute-box:before{content:"\f4cd"}.fa-paragraph:before{content:"\f1dd"}.fa-passport:before{content:"\f5ab"}.fa-file-clipboard:before,.fa-paste:before{content:"\f0ea"}.fa-pause:before{content:"\f04c"}.fa-paw:before{content:"\f1b0"}.fa-peace:before{content:"\f67c"}.fa-pen:before{content:"\f304"}.fa-pen-alt:before,.fa-pen-clip:before{content:"\f305"}.fa-pen-fancy:before{content:"\f5ac"}.fa-pen-nib:before{content:"\f5ad"}.fa-pen-ruler:before,.fa-pencil-ruler:before{content:"\f5ae"}.fa-edit:before,.fa-pen-to-square:before{content:"\f044"}.fa-pencil-alt:before,.fa-pencil:before{content:"\f303"}.fa-people-arrows-left-right:before,.fa-people-arrows:before{content:"\e068"}.fa-people-carry-box:before,.fa-people-carry:before{content:"\f4ce"}.fa-people-group:before{content:"\e533"}.fa-people-line:before{content:"\e534"}.fa-people-pulling:before{content:"\e535"}.fa-people-robbery:before{content:"\e536"}.fa-people-roof:before{content:"\e537"}.fa-pepper-hot:before{content:"\f816"}.fa-percent:before,.fa-percentage:before{content:"\25"}.fa-male:before,.fa-person:before{content:"\f183"}.fa-person-arrow-down-to-line:before{content:"\e538"}.fa-person-arrow-up-from-line:before{content:"\e539"}.fa-biking:before,.fa-person-biking:before{content:"\f84a"}.fa-person-booth:before{content:"\f756"}.fa-person-breastfeeding:before{content:"\e53a"}.fa-person-burst:before{content:"\e53b"}.fa-person-cane:before{content:"\e53c"}.fa-person-chalkboard:before{content:"\e53d"}.fa-person-circle-check:before{content:"\e53e"}.fa-person-circle-exclamation:before{content:"\e53f"}.fa-person-circle-minus:before{content:"\e540"}.fa-person-circle-plus:before{content:"\e541"}.fa-person-circle-question:before{content:"\e542"}.fa-person-circle-xmark:before{content:"\e543"}.fa-digging:before,.fa-person-digging:before{content:"\f85e"}.fa-diagnoses:before,.fa-person-dots-from-line:before{content:"\f470"}.fa-female:before,.fa-person-dress:before{content:"\f182"}.fa-person-dress-burst:before{content:"\e544"}.fa-person-drowning:before{content:"\e545"}.fa-person-falling:before{content:"\e546"}.fa-person-falling-burst:before{content:"\e547"}.fa-person-half-dress:before{content:"\e548"}.fa-person-harassing:before{content:"\e549"}.fa-hiking:before,.fa-person-hiking:before{content:"\f6ec"}.fa-person-military-pointing:before{content:"\e54a"}.fa-person-military-rifle:before{content:"\e54b"}.fa-person-military-to-person:before{content:"\e54c"}.fa-person-praying:before,.fa-pray:before{content:"\f683"}.fa-person-pregnant:before{content:"\e31e"}.fa-person-rays:before{content:"\e54d"}.fa-person-rifle:before{content:"\e54e"}.fa-person-running:before,.fa-running:before{content:"\f70c"}.fa-person-shelter:before{content:"\e54f"}.fa-person-skating:before,.fa-skating:before{content:"\f7c5"}.fa-person-skiing:before,.fa-skiing:before{content:"\f7c9"}.fa-person-skiing-nordic:before,.fa-skiing-nordic:before{content:"\f7ca"}.fa-person-snowboarding:before,.fa-snowboarding:before{content:"\f7ce"}.fa-person-swimming:before,.fa-swimmer:before{content:"\f5c4"}.fa-person-through-window:before{content:"\e5a9"}.fa-person-walking:before,.fa-walking:before{content:"\f554"}.fa-person-walking-arrow-loop-left:before{content:"\e551"}.fa-person-walking-arrow-right:before{content:"\e552"}.fa-person-walking-dashed-line-arrow-right:before{content:"\e553"}.fa-person-walking-luggage:before{content:"\e554"}.fa-blind:before,.fa-person-walking-with-cane:before{content:"\f29d"}.fa-peseta-sign:before{content:"\e221"}.fa-peso-sign:before{content:"\e222"}.fa-phone:before{content:"\f095"}.fa-phone-alt:before,.fa-phone-flip:before{content:"\f879"}.fa-phone-slash:before{content:"\f3dd"}.fa-phone-volume:before,.fa-volume-control-phone:before{content:"\f2a0"}.fa-photo-film:before,.fa-photo-video:before{content:"\f87c"}.fa-piggy-bank:before{content:"\f4d3"}.fa-pills:before{content:"\f484"}.fa-pizza-slice:before{content:"\f818"}.fa-place-of-worship:before{content:"\f67f"}.fa-plane:before{content:"\f072"}.fa-plane-arrival:before{content:"\f5af"}.fa-plane-circle-check:before{content:"\e555"}.fa-plane-circle-exclamation:before{content:"\e556"}.fa-plane-circle-xmark:before{content:"\e557"}.fa-plane-departure:before{content:"\f5b0"}.fa-plane-lock:before{content:"\e558"}.fa-plane-slash:before{content:"\e069"}.fa-plane-up:before{content:"\e22d"}.fa-plant-wilt:before{content:"\e5aa"}.fa-plate-wheat:before{content:"\e55a"}.fa-play:before{content:"\f04b"}.fa-plug:before{content:"\f1e6"}.fa-plug-circle-bolt:before{content:"\e55b"}.fa-plug-circle-check:before{content:"\e55c"}.fa-plug-circle-exclamation:before{content:"\e55d"}.fa-plug-circle-minus:before{content:"\e55e"}.fa-plug-circle-plus:before{content:"\e55f"}.fa-plug-circle-xmark:before{content:"\e560"}.fa-add:before,.fa-plus:before{content:"\2b"}.fa-plus-minus:before{content:"\e43c"}.fa-podcast:before{content:"\f2ce"}.fa-poo:before{content:"\f2fe"}.fa-poo-bolt:before,.fa-poo-storm:before{content:"\f75a"}.fa-poop:before{content:"\f619"}.fa-power-off:before{content:"\f011"}.fa-prescription:before{content:"\f5b1"}.fa-prescription-bottle:before{content:"\f485"}.fa-prescription-bottle-alt:before,.fa-prescription-bottle-medical:before{content:"\f486"}.fa-print:before{content:"\f02f"}.fa-pump-medical:before{content:"\e06a"}.fa-pump-soap:before{content:"\e06b"}.fa-puzzle-piece:before{content:"\f12e"}.fa-q:before{content:"\51"}.fa-qrcode:before{content:"\f029"}.fa-question:before{content:"\3f"}.fa-quote-left-alt:before,.fa-quote-left:before{content:"\f10d"}.fa-quote-right-alt:before,.fa-quote-right:before{content:"\f10e"}.fa-r:before{content:"\52"}.fa-radiation:before{content:"\f7b9"}.fa-radio:before{content:"\f8d7"}.fa-rainbow:before{content:"\f75b"}.fa-ranking-star:before{content:"\e561"}.fa-receipt:before{content:"\f543"}.fa-record-vinyl:before{content:"\f8d9"}.fa-ad:before,.fa-rectangle-ad:before{content:"\f641"}.fa-list-alt:before,.fa-rectangle-list:before{content:"\f022"}.fa-rectangle-times:before,.fa-rectangle-xmark:before,.fa-times-rectangle:before,.fa-window-close:before{content:"\f410"}.fa-recycle:before{content:"\f1b8"}.fa-registered:before{content:"\f25d"}.fa-repeat:before{content:"\f363"}.fa-mail-reply:before,.fa-reply:before{content:"\f3e5"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-republican:before{content:"\f75e"}.fa-restroom:before{content:"\f7bd"}.fa-retweet:before{content:"\f079"}.fa-ribbon:before{content:"\f4d6"}.fa-right-from-bracket:before,.fa-sign-out-alt:before{content:"\f2f5"}.fa-exchange-alt:before,.fa-right-left:before{content:"\f362"}.fa-long-arrow-alt-right:before,.fa-right-long:before{content:"\f30b"}.fa-right-to-bracket:before,.fa-sign-in-alt:before{content:"\f2f6"}.fa-ring:before{content:"\f70b"}.fa-road:before{content:"\f018"}.fa-road-barrier:before{content:"\e562"}.fa-road-bridge:before{content:"\e563"}.fa-road-circle-check:before{content:"\e564"}.fa-road-circle-exclamation:before{content:"\e565"}.fa-road-circle-xmark:before{content:"\e566"}.fa-road-lock:before{content:"\e567"}.fa-road-spikes:before{content:"\e568"}.fa-robot:before{content:"\f544"}.fa-rocket:before{content:"\f135"}.fa-rotate:before,.fa-sync-alt:before{content:"\f2f1"}.fa-rotate-back:before,.fa-rotate-backward:before,.fa-rotate-left:before,.fa-undo-alt:before{content:"\f2ea"}.fa-redo-alt:before,.fa-rotate-forward:before,.fa-rotate-right:before{content:"\f2f9"}.fa-route:before{content:"\f4d7"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-rouble:before,.fa-rub:before,.fa-ruble-sign:before,.fa-ruble:before{content:"\f158"}.fa-rug:before{content:"\e569"}.fa-ruler:before{content:"\f545"}.fa-ruler-combined:before{content:"\f546"}.fa-ruler-horizontal:before{content:"\f547"}.fa-ruler-vertical:before{content:"\f548"}.fa-rupee-sign:before,.fa-rupee:before{content:"\f156"}.fa-rupiah-sign:before{content:"\e23d"}.fa-s:before{content:"\53"}.fa-sack-dollar:before{content:"\f81d"}.fa-sack-xmark:before{content:"\e56a"}.fa-sailboat:before{content:"\e445"}.fa-satellite:before{content:"\f7bf"}.fa-satellite-dish:before{content:"\f7c0"}.fa-balance-scale:before,.fa-scale-balanced:before{content:"\f24e"}.fa-balance-scale-left:before,.fa-scale-unbalanced:before{content:"\f515"}.fa-balance-scale-right:before,.fa-scale-unbalanced-flip:before{content:"\f516"}.fa-school:before{content:"\f549"}.fa-school-circle-check:before{content:"\e56b"}.fa-school-circle-exclamation:before{content:"\e56c"}.fa-school-circle-xmark:before{content:"\e56d"}.fa-school-flag:before{content:"\e56e"}.fa-school-lock:before{content:"\e56f"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-screwdriver:before{content:"\f54a"}.fa-screwdriver-wrench:before,.fa-tools:before{content:"\f7d9"}.fa-scroll:before{content:"\f70e"}.fa-scroll-torah:before,.fa-torah:before{content:"\f6a0"}.fa-sd-card:before{content:"\f7c2"}.fa-section:before{content:"\e447"}.fa-seedling:before,.fa-sprout:before{content:"\f4d8"}.fa-server:before{content:"\f233"}.fa-shapes:before,.fa-triangle-circle-square:before{content:"\f61f"}.fa-arrow-turn-right:before,.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-share-from-square:before,.fa-share-square:before{content:"\f14d"}.fa-share-alt:before,.fa-share-nodes:before{content:"\f1e0"}.fa-sheet-plastic:before{content:"\e571"}.fa-ils:before,.fa-shekel-sign:before,.fa-shekel:before,.fa-sheqel-sign:before,.fa-sheqel:before{content:"\f20b"}.fa-shield-blank:before,.fa-shield:before{content:"\f132"}.fa-shield-cat:before{content:"\e572"}.fa-shield-dog:before{content:"\e573"}.fa-shield-alt:before,.fa-shield-halved:before{content:"\f3ed"}.fa-shield-heart:before{content:"\e574"}.fa-shield-virus:before{content:"\e06c"}.fa-ship:before{content:"\f21a"}.fa-shirt:before,.fa-t-shirt:before,.fa-tshirt:before{content:"\f553"}.fa-shoe-prints:before{content:"\f54b"}.fa-shop:before,.fa-store-alt:before{content:"\f54f"}.fa-shop-lock:before{content:"\e4a5"}.fa-shop-slash:before,.fa-store-alt-slash:before{content:"\e070"}.fa-shower:before{content:"\f2cc"}.fa-shrimp:before{content:"\e448"}.fa-random:before,.fa-shuffle:before{content:"\f074"}.fa-shuttle-space:before,.fa-space-shuttle:before{content:"\f197"}.fa-sign-hanging:before,.fa-sign:before{content:"\f4d9"}.fa-signal-5:before,.fa-signal-perfect:before,.fa-signal:before{content:"\f012"}.fa-signature:before{content:"\f5b7"}.fa-map-signs:before,.fa-signs-post:before{content:"\f277"}.fa-sim-card:before{content:"\f7c4"}.fa-sink:before{content:"\e06d"}.fa-sitemap:before{content:"\f0e8"}.fa-skull:before{content:"\f54c"}.fa-skull-crossbones:before{content:"\f714"}.fa-slash:before{content:"\f715"}.fa-sleigh:before{content:"\f7cc"}.fa-sliders-h:before,.fa-sliders:before{content:"\f1de"}.fa-smog:before{content:"\f75f"}.fa-smoking:before{content:"\f48d"}.fa-snowflake:before{content:"\f2dc"}.fa-snowman:before{content:"\f7d0"}.fa-snowplow:before{content:"\f7d2"}.fa-soap:before{content:"\e06e"}.fa-socks:before{content:"\f696"}.fa-solar-panel:before{content:"\f5ba"}.fa-sort:before,.fa-unsorted:before{content:"\f0dc"}.fa-sort-desc:before,.fa-sort-down:before{content:"\f0dd"}.fa-sort-asc:before,.fa-sort-up:before{content:"\f0de"}.fa-spa:before{content:"\f5bb"}.fa-pastafarianism:before,.fa-spaghetti-monster-flying:before{content:"\f67b"}.fa-spell-check:before{content:"\f891"}.fa-spider:before{content:"\f717"}.fa-spinner:before{content:"\f110"}.fa-splotch:before{content:"\f5bc"}.fa-spoon:before,.fa-utensil-spoon:before{content:"\f2e5"}.fa-spray-can:before{content:"\f5bd"}.fa-air-freshener:before,.fa-spray-can-sparkles:before{content:"\f5d0"}.fa-square:before{content:"\f0c8"}.fa-external-link-square:before,.fa-square-arrow-up-right:before{content:"\f14c"}.fa-caret-square-down:before,.fa-square-caret-down:before{content:"\f150"}.fa-caret-square-left:before,.fa-square-caret-left:before{content:"\f191"}.fa-caret-square-right:before,.fa-square-caret-right:before{content:"\f152"}.fa-caret-square-up:before,.fa-square-caret-up:before{content:"\f151"}.fa-check-square:before,.fa-square-check:before{content:"\f14a"}.fa-envelope-square:before,.fa-square-envelope:before{content:"\f199"}.fa-square-full:before{content:"\f45c"}.fa-h-square:before,.fa-square-h:before{content:"\f0fd"}.fa-minus-square:before,.fa-square-minus:before{content:"\f146"}.fa-square-nfi:before{content:"\e576"}.fa-parking:before,.fa-square-parking:before{content:"\f540"}.fa-pen-square:before,.fa-pencil-square:before,.fa-square-pen:before{content:"\f14b"}.fa-square-person-confined:before{content:"\e577"}.fa-phone-square:before,.fa-square-phone:before{content:"\f098"}.fa-phone-square-alt:before,.fa-square-phone-flip:before{content:"\f87b"}.fa-plus-square:before,.fa-square-plus:before{content:"\f0fe"}.fa-poll-h:before,.fa-square-poll-horizontal:before{content:"\f682"}.fa-poll:before,.fa-square-poll-vertical:before{content:"\f681"}.fa-square-root-alt:before,.fa-square-root-variable:before{content:"\f698"}.fa-rss-square:before,.fa-square-rss:before{content:"\f143"}.fa-share-alt-square:before,.fa-square-share-nodes:before{content:"\f1e1"}.fa-external-link-square-alt:before,.fa-square-up-right:before{content:"\f360"}.fa-square-virus:before{content:"\e578"}.fa-square-xmark:before,.fa-times-square:before,.fa-xmark-square:before{content:"\f2d3"}.fa-rod-asclepius:before,.fa-rod-snake:before,.fa-staff-aesculapius:before,.fa-staff-snake:before{content:"\e579"}.fa-stairs:before{content:"\e289"}.fa-stamp:before{content:"\f5bf"}.fa-stapler:before{content:"\e5af"}.fa-star:before{content:"\f005"}.fa-star-and-crescent:before{content:"\f699"}.fa-star-half:before{content:"\f089"}.fa-star-half-alt:before,.fa-star-half-stroke:before{content:"\f5c0"}.fa-star-of-david:before{content:"\f69a"}.fa-star-of-life:before{content:"\f621"}.fa-gbp:before,.fa-pound-sign:before,.fa-sterling-sign:before{content:"\f154"}.fa-stethoscope:before{content:"\f0f1"}.fa-stop:before{content:"\f04d"}.fa-stopwatch:before{content:"\f2f2"}.fa-stopwatch-20:before{content:"\e06f"}.fa-store:before{content:"\f54e"}.fa-store-slash:before{content:"\e071"}.fa-street-view:before{content:"\f21d"}.fa-strikethrough:before{content:"\f0cc"}.fa-stroopwafel:before{content:"\f551"}.fa-subscript:before{content:"\f12c"}.fa-suitcase:before{content:"\f0f2"}.fa-medkit:before,.fa-suitcase-medical:before{content:"\f0fa"}.fa-suitcase-rolling:before{content:"\f5c1"}.fa-sun:before{content:"\f185"}.fa-sun-plant-wilt:before{content:"\e57a"}.fa-superscript:before{content:"\f12b"}.fa-swatchbook:before{content:"\f5c3"}.fa-synagogue:before{content:"\f69b"}.fa-syringe:before{content:"\f48e"}.fa-t:before{content:"\54"}.fa-table:before{content:"\f0ce"}.fa-table-cells:before,.fa-th:before{content:"\f00a"}.fa-table-cells-large:before,.fa-th-large:before{content:"\f009"}.fa-columns:before,.fa-table-columns:before{content:"\f0db"}.fa-table-list:before,.fa-th-list:before{content:"\f00b"}.fa-ping-pong-paddle-ball:before,.fa-table-tennis-paddle-ball:before,.fa-table-tennis:before{content:"\f45d"}.fa-tablet-android:before,.fa-tablet:before{content:"\f3fb"}.fa-tablet-button:before{content:"\f10a"}.fa-tablet-alt:before,.fa-tablet-screen-button:before{content:"\f3fa"}.fa-tablets:before{content:"\f490"}.fa-digital-tachograph:before,.fa-tachograph-digital:before{content:"\f566"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-tape:before{content:"\f4db"}.fa-tarp:before{content:"\e57b"}.fa-tarp-droplet:before{content:"\e57c"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-teeth:before{content:"\f62e"}.fa-teeth-open:before{content:"\f62f"}.fa-temperature-arrow-down:before,.fa-temperature-down:before{content:"\e03f"}.fa-temperature-arrow-up:before,.fa-temperature-up:before{content:"\e040"}.fa-temperature-0:before,.fa-temperature-empty:before,.fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\f2cb"}.fa-temperature-4:before,.fa-temperature-full:before,.fa-thermometer-4:before,.fa-thermometer-full:before{content:"\f2c7"}.fa-temperature-2:before,.fa-temperature-half:before,.fa-thermometer-2:before,.fa-thermometer-half:before{content:"\f2c9"}.fa-temperature-high:before{content:"\f769"}.fa-temperature-low:before{content:"\f76b"}.fa-temperature-1:before,.fa-temperature-quarter:before,.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\f2ca"}.fa-temperature-3:before,.fa-temperature-three-quarters:before,.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-tenge-sign:before,.fa-tenge:before{content:"\f7d7"}.fa-tent:before{content:"\e57d"}.fa-tent-arrow-down-to-line:before{content:"\e57e"}.fa-tent-arrow-left-right:before{content:"\e57f"}.fa-tent-arrow-turn-left:before{content:"\e580"}.fa-tent-arrows-down:before{content:"\e581"}.fa-tents:before{content:"\e582"}.fa-terminal:before{content:"\f120"}.fa-text-height:before{content:"\f034"}.fa-remove-format:before,.fa-text-slash:before{content:"\f87d"}.fa-text-width:before{content:"\f035"}.fa-thermometer:before{content:"\f491"}.fa-thumbs-down:before{content:"\f165"}.fa-thumbs-up:before{content:"\f164"}.fa-thumb-tack:before,.fa-thumbtack:before{content:"\f08d"}.fa-ticket:before{content:"\f145"}.fa-ticket-alt:before,.fa-ticket-simple:before{content:"\f3ff"}.fa-timeline:before{content:"\e29c"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-toilet:before{content:"\f7d8"}.fa-toilet-paper:before{content:"\f71e"}.fa-toilet-paper-slash:before{content:"\e072"}.fa-toilet-portable:before{content:"\e583"}.fa-toilets-portable:before{content:"\e584"}.fa-toolbox:before{content:"\f552"}.fa-tooth:before{content:"\f5c9"}.fa-torii-gate:before{content:"\f6a1"}.fa-tornado:before{content:"\f76f"}.fa-broadcast-tower:before,.fa-tower-broadcast:before{content:"\f519"}.fa-tower-cell:before{content:"\e585"}.fa-tower-observation:before{content:"\e586"}.fa-tractor:before{content:"\f722"}.fa-trademark:before{content:"\f25c"}.fa-traffic-light:before{content:"\f637"}.fa-trailer:before{content:"\e041"}.fa-train:before{content:"\f238"}.fa-subway:before,.fa-train-subway:before{content:"\f239"}.fa-train-tram:before{content:"\e5b4"}.fa-transgender-alt:before,.fa-transgender:before{content:"\f225"}.fa-trash:before{content:"\f1f8"}.fa-trash-arrow-up:before,.fa-trash-restore:before{content:"\f829"}.fa-trash-alt:before,.fa-trash-can:before{content:"\f2ed"}.fa-trash-can-arrow-up:before,.fa-trash-restore-alt:before{content:"\f82a"}.fa-tree:before{content:"\f1bb"}.fa-tree-city:before{content:"\e587"}.fa-exclamation-triangle:before,.fa-triangle-exclamation:before,.fa-warning:before{content:"\f071"}.fa-trophy:before{content:"\f091"}.fa-trowel:before{content:"\e589"}.fa-trowel-bricks:before{content:"\e58a"}.fa-truck:before{content:"\f0d1"}.fa-truck-arrow-right:before{content:"\e58b"}.fa-truck-droplet:before{content:"\e58c"}.fa-shipping-fast:before,.fa-truck-fast:before{content:"\f48b"}.fa-truck-field:before{content:"\e58d"}.fa-truck-field-un:before{content:"\e58e"}.fa-truck-front:before{content:"\e2b7"}.fa-ambulance:before,.fa-truck-medical:before{content:"\f0f9"}.fa-truck-monster:before{content:"\f63b"}.fa-truck-moving:before{content:"\f4df"}.fa-truck-pickup:before{content:"\f63c"}.fa-truck-plane:before{content:"\e58f"}.fa-truck-loading:before,.fa-truck-ramp-box:before{content:"\f4de"}.fa-teletype:before,.fa-tty:before{content:"\f1e4"}.fa-try:before,.fa-turkish-lira-sign:before,.fa-turkish-lira:before{content:"\e2bb"}.fa-level-down-alt:before,.fa-turn-down:before{content:"\f3be"}.fa-level-up-alt:before,.fa-turn-up:before{content:"\f3bf"}.fa-television:before,.fa-tv-alt:before,.fa-tv:before{content:"\f26c"}.fa-u:before{content:"\55"}.fa-umbrella:before{content:"\f0e9"}.fa-umbrella-beach:before{content:"\f5ca"}.fa-underline:before{content:"\f0cd"}.fa-universal-access:before{content:"\f29a"}.fa-unlock:before{content:"\f09c"}.fa-unlock-alt:before,.fa-unlock-keyhole:before{content:"\f13e"}.fa-arrows-alt-v:before,.fa-up-down:before{content:"\f338"}.fa-arrows-alt:before,.fa-up-down-left-right:before{content:"\f0b2"}.fa-long-arrow-alt-up:before,.fa-up-long:before{content:"\f30c"}.fa-expand-alt:before,.fa-up-right-and-down-left-from-center:before{content:"\f424"}.fa-external-link-alt:before,.fa-up-right-from-square:before{content:"\f35d"}.fa-upload:before{content:"\f093"}.fa-user:before{content:"\f007"}.fa-user-astronaut:before{content:"\f4fb"}.fa-user-check:before{content:"\f4fc"}.fa-user-clock:before{content:"\f4fd"}.fa-user-doctor:before,.fa-user-md:before{content:"\f0f0"}.fa-user-cog:before,.fa-user-gear:before{content:"\f4fe"}.fa-user-graduate:before{content:"\f501"}.fa-user-friends:before,.fa-user-group:before{content:"\f500"}.fa-user-injured:before{content:"\f728"}.fa-user-alt:before,.fa-user-large:before{content:"\f406"}.fa-user-alt-slash:before,.fa-user-large-slash:before{content:"\f4fa"}.fa-user-lock:before{content:"\f502"}.fa-user-minus:before{content:"\f503"}.fa-user-ninja:before{content:"\f504"}.fa-user-nurse:before{content:"\f82f"}.fa-user-edit:before,.fa-user-pen:before{content:"\f4ff"}.fa-user-plus:before{content:"\f234"}.fa-user-secret:before{content:"\f21b"}.fa-user-shield:before{content:"\f505"}.fa-user-slash:before{content:"\f506"}.fa-user-tag:before{content:"\f507"}.fa-user-tie:before{content:"\f508"}.fa-user-times:before,.fa-user-xmark:before{content:"\f235"}.fa-users:before{content:"\f0c0"}.fa-users-between-lines:before{content:"\e591"}.fa-users-cog:before,.fa-users-gear:before{content:"\f509"}.fa-users-line:before{content:"\e592"}.fa-users-rays:before{content:"\e593"}.fa-users-rectangle:before{content:"\e594"}.fa-users-slash:before{content:"\e073"}.fa-users-viewfinder:before{content:"\e595"}.fa-cutlery:before,.fa-utensils:before{content:"\f2e7"}.fa-v:before{content:"\56"}.fa-shuttle-van:before,.fa-van-shuttle:before{content:"\f5b6"}.fa-vault:before{content:"\e2c5"}.fa-vector-square:before{content:"\f5cb"}.fa-venus:before{content:"\f221"}.fa-venus-double:before{content:"\f226"}.fa-venus-mars:before{content:"\f228"}.fa-vest:before{content:"\e085"}.fa-vest-patches:before{content:"\e086"}.fa-vial:before{content:"\f492"}.fa-vial-circle-check:before{content:"\e596"}.fa-vial-virus:before{content:"\e597"}.fa-vials:before{content:"\f493"}.fa-video-camera:before,.fa-video:before{content:"\f03d"}.fa-video-slash:before{content:"\f4e2"}.fa-vihara:before{content:"\f6a7"}.fa-virus:before{content:"\e074"}.fa-virus-covid:before{content:"\e4a8"}.fa-virus-covid-slash:before{content:"\e4a9"}.fa-virus-slash:before{content:"\e075"}.fa-viruses:before{content:"\e076"}.fa-voicemail:before{content:"\f897"}.fa-volcano:before{content:"\f770"}.fa-volleyball-ball:before,.fa-volleyball:before{content:"\f45f"}.fa-volume-high:before,.fa-volume-up:before{content:"\f028"}.fa-volume-down:before,.fa-volume-low:before{content:"\f027"}.fa-volume-off:before{content:"\f026"}.fa-volume-mute:before,.fa-volume-times:before,.fa-volume-xmark:before{content:"\f6a9"}.fa-vr-cardboard:before{content:"\f729"}.fa-w:before{content:"\57"}.fa-walkie-talkie:before{content:"\f8ef"}.fa-wallet:before{content:"\f555"}.fa-magic:before,.fa-wand-magic:before{content:"\f0d0"}.fa-magic-wand-sparkles:before,.fa-wand-magic-sparkles:before{content:"\e2ca"}.fa-wand-sparkles:before{content:"\f72b"}.fa-warehouse:before{content:"\f494"}.fa-water:before{content:"\f773"}.fa-ladder-water:before,.fa-swimming-pool:before,.fa-water-ladder:before{content:"\f5c5"}.fa-wave-square:before{content:"\f83e"}.fa-weight-hanging:before{content:"\f5cd"}.fa-weight-scale:before,.fa-weight:before{content:"\f496"}.fa-wheat-alt:before,.fa-wheat-awn:before{content:"\e2cd"}.fa-wheat-awn-circle-exclamation:before{content:"\e598"}.fa-wheelchair:before{content:"\f193"}.fa-wheelchair-alt:before,.fa-wheelchair-move:before{content:"\e2ce"}.fa-glass-whiskey:before,.fa-whiskey-glass:before{content:"\f7a0"}.fa-wifi-3:before,.fa-wifi-strong:before,.fa-wifi:before{content:"\f1eb"}.fa-wind:before{content:"\f72e"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-wine-bottle:before{content:"\f72f"}.fa-wine-glass:before{content:"\f4e3"}.fa-wine-glass-alt:before,.fa-wine-glass-empty:before{content:"\f5ce"}.fa-krw:before,.fa-won-sign:before,.fa-won:before{content:"\f159"}.fa-worm:before{content:"\e599"}.fa-wrench:before{content:"\f0ad"}.fa-x:before{content:"\58"}.fa-x-ray:before{content:"\f497"}.fa-close:before,.fa-multiply:before,.fa-remove:before,.fa-times:before,.fa-xmark:before{content:"\f00d"}.fa-xmarks-lines:before{content:"\e59a"}.fa-y:before{content:"\59"}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen-sign:before,.fa-yen:before{content:"\f157"}.fa-yin-yang:before{content:"\f6ad"}.fa-z:before{content:"\5a"}.fa-sr-only,.fa-sr-only-focusable:not(:focus),.sr-only,.sr-only-focusable:not(:focus){position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}:host,:root{--fa-font-brands:normal 400 1em/1 "Font Awesome 6 Brands"}.fa-brands,.fab{font-family:"Font Awesome 6 Brands";font-weight:400}.fa-42-group:before,.fa-innosoft:before{content:"\e080"}.fa-500px:before{content:"\f26e"}.fa-accessible-icon:before{content:"\f368"}.fa-accusoft:before{content:"\f369"}.fa-adn:before{content:"\f170"}.fa-adversal:before{content:"\f36a"}.fa-affiliatetheme:before{content:"\f36b"}.fa-airbnb:before{content:"\f834"}.fa-algolia:before{content:"\f36c"}.fa-alipay:before{content:"\f642"}.fa-amazon:before{content:"\f270"}.fa-amazon-pay:before{content:"\f42c"}.fa-amilia:before{content:"\f36d"}.fa-android:before{content:"\f17b"}.fa-angellist:before{content:"\f209"}.fa-angrycreative:before{content:"\f36e"}.fa-angular:before{content:"\f420"}.fa-app-store:before{content:"\f36f"}.fa-app-store-ios:before{content:"\f370"}.fa-apper:before{content:"\f371"}.fa-apple:before{content:"\f179"}.fa-apple-pay:before{content:"\f415"}.fa-artstation:before{content:"\f77a"}.fa-asymmetrik:before{content:"\f372"}.fa-atlassian:before{content:"\f77b"}.fa-audible:before{content:"\f373"}.fa-autoprefixer:before{content:"\f41c"}.fa-avianex:before{content:"\f374"}.fa-aviato:before{content:"\f421"}.fa-aws:before{content:"\f375"}.fa-bandcamp:before{content:"\f2d5"}.fa-battle-net:before{content:"\f835"}.fa-behance:before{content:"\f1b4"}.fa-bilibili:before{content:"\e3d9"}.fa-bimobject:before{content:"\f378"}.fa-bitbucket:before{content:"\f171"}.fa-bitcoin:before{content:"\f379"}.fa-bity:before{content:"\f37a"}.fa-black-tie:before{content:"\f27e"}.fa-blackberry:before{content:"\f37b"}.fa-blogger:before{content:"\f37c"}.fa-blogger-b:before{content:"\f37d"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-bootstrap:before{content:"\f836"}.fa-bots:before{content:"\e340"}.fa-btc:before{content:"\f15a"}.fa-buffer:before{content:"\f837"}.fa-buromobelexperte:before{content:"\f37f"}.fa-buy-n-large:before{content:"\f8a6"}.fa-buysellads:before{content:"\f20d"}.fa-canadian-maple-leaf:before{content:"\f785"}.fa-cc-amazon-pay:before{content:"\f42d"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-apple-pay:before{content:"\f416"}.fa-cc-diners-club:before{content:"\f24c"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-cc-visa:before{content:"\f1f0"}.fa-centercode:before{content:"\f380"}.fa-centos:before{content:"\f789"}.fa-chrome:before{content:"\f268"}.fa-chromecast:before{content:"\f838"}.fa-cloudflare:before{content:"\e07d"}.fa-cloudscale:before{content:"\f383"}.fa-cloudsmith:before{content:"\f384"}.fa-cloudversify:before{content:"\f385"}.fa-cmplid:before{content:"\e360"}.fa-codepen:before{content:"\f1cb"}.fa-codiepie:before{content:"\f284"}.fa-confluence:before{content:"\f78d"}.fa-connectdevelop:before{content:"\f20e"}.fa-contao:before{content:"\f26d"}.fa-cotton-bureau:before{content:"\f89e"}.fa-cpanel:before{content:"\f388"}.fa-creative-commons:before{content:"\f25e"}.fa-creative-commons-by:before{content:"\f4e7"}.fa-creative-commons-nc:before{content:"\f4e8"}.fa-creative-commons-nc-eu:before{content:"\f4e9"}.fa-creative-commons-nc-jp:before{content:"\f4ea"}.fa-creative-commons-nd:before{content:"\f4eb"}.fa-creative-commons-pd:before{content:"\f4ec"}.fa-creative-commons-pd-alt:before{content:"\f4ed"}.fa-creative-commons-remix:before{content:"\f4ee"}.fa-creative-commons-sa:before{content:"\f4ef"}.fa-creative-commons-sampling:before{content:"\f4f0"}.fa-creative-commons-sampling-plus:before{content:"\f4f1"}.fa-creative-commons-share:before{content:"\f4f2"}.fa-creative-commons-zero:before{content:"\f4f3"}.fa-critical-role:before{content:"\f6c9"}.fa-css3:before{content:"\f13c"}.fa-css3-alt:before{content:"\f38b"}.fa-cuttlefish:before{content:"\f38c"}.fa-d-and-d:before{content:"\f38d"}.fa-d-and-d-beyond:before{content:"\f6ca"}.fa-dailymotion:before{content:"\e052"}.fa-dashcube:before{content:"\f210"}.fa-deezer:before{content:"\e077"}.fa-delicious:before{content:"\f1a5"}.fa-deploydog:before{content:"\f38e"}.fa-deskpro:before{content:"\f38f"}.fa-dev:before{content:"\f6cc"}.fa-deviantart:before{content:"\f1bd"}.fa-dhl:before{content:"\f790"}.fa-diaspora:before{content:"\f791"}.fa-digg:before{content:"\f1a6"}.fa-digital-ocean:before{content:"\f391"}.fa-discord:before{content:"\f392"}.fa-discourse:before{content:"\f393"}.fa-dochub:before{content:"\f394"}.fa-docker:before{content:"\f395"}.fa-draft2digital:before{content:"\f396"}.fa-dribbble:before{content:"\f17d"}.fa-dropbox:before{content:"\f16b"}.fa-drupal:before{content:"\f1a9"}.fa-dyalog:before{content:"\f399"}.fa-earlybirds:before{content:"\f39a"}.fa-ebay:before{content:"\f4f4"}.fa-edge:before{content:"\f282"}.fa-edge-legacy:before{content:"\e078"}.fa-elementor:before{content:"\f430"}.fa-ello:before{content:"\f5f1"}.fa-ember:before{content:"\f423"}.fa-empire:before{content:"\f1d1"}.fa-envira:before{content:"\f299"}.fa-erlang:before{content:"\f39d"}.fa-ethereum:before{content:"\f42e"}.fa-etsy:before{content:"\f2d7"}.fa-evernote:before{content:"\f839"}.fa-expeditedssl:before{content:"\f23e"}.fa-facebook:before{content:"\f09a"}.fa-facebook-f:before{content:"\f39e"}.fa-facebook-messenger:before{content:"\f39f"}.fa-fantasy-flight-games:before{content:"\f6dc"}.fa-fedex:before{content:"\f797"}.fa-fedora:before{content:"\f798"}.fa-figma:before{content:"\f799"}.fa-firefox:before{content:"\f269"}.fa-firefox-browser:before{content:"\e007"}.fa-first-order:before{content:"\f2b0"}.fa-first-order-alt:before{content:"\f50a"}.fa-firstdraft:before{content:"\f3a1"}.fa-flickr:before{content:"\f16e"}.fa-flipboard:before{content:"\f44d"}.fa-fly:before{content:"\f417"}.fa-font-awesome-flag:before,.fa-font-awesome-logo-full:before,.fa-font-awesome:before{content:"\f2b4"}.fa-fonticons:before{content:"\f280"}.fa-fonticons-fi:before{content:"\f3a2"}.fa-fort-awesome:before{content:"\f286"}.fa-fort-awesome-alt:before{content:"\f3a3"}.fa-forumbee:before{content:"\f211"}.fa-foursquare:before{content:"\f180"}.fa-free-code-camp:before{content:"\f2c5"}.fa-freebsd:before{content:"\f3a4"}.fa-fulcrum:before{content:"\f50b"}.fa-galactic-republic:before{content:"\f50c"}.fa-galactic-senate:before{content:"\f50d"}.fa-get-pocket:before{content:"\f265"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-git:before{content:"\f1d3"}.fa-git-alt:before{content:"\f841"}.fa-github:before{content:"\f09b"}.fa-github-alt:before{content:"\f113"}.fa-gitkraken:before{content:"\f3a6"}.fa-gitlab:before{content:"\f296"}.fa-gitter:before{content:"\f426"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-gofore:before{content:"\f3a7"}.fa-golang:before{content:"\e40f"}.fa-goodreads:before{content:"\f3a8"}.fa-goodreads-g:before{content:"\f3a9"}.fa-google:before{content:"\f1a0"}.fa-google-drive:before{content:"\f3aa"}.fa-google-pay:before{content:"\e079"}.fa-google-play:before{content:"\f3ab"}.fa-google-plus:before{content:"\f2b3"}.fa-google-plus-g:before{content:"\f0d5"}.fa-google-wallet:before{content:"\f1ee"}.fa-gratipay:before{content:"\f184"}.fa-grav:before{content:"\f2d6"}.fa-gripfire:before{content:"\f3ac"}.fa-grunt:before{content:"\f3ad"}.fa-guilded:before{content:"\e07e"}.fa-gulp:before{content:"\f3ae"}.fa-hacker-news:before{content:"\f1d4"}.fa-hackerrank:before{content:"\f5f7"}.fa-hashnode:before{content:"\e499"}.fa-hips:before{content:"\f452"}.fa-hire-a-helper:before{content:"\f3b0"}.fa-hive:before{content:"\e07f"}.fa-hooli:before{content:"\f427"}.fa-hornbill:before{content:"\f592"}.fa-hotjar:before{content:"\f3b1"}.fa-houzz:before{content:"\f27c"}.fa-html5:before{content:"\f13b"}.fa-hubspot:before{content:"\f3b2"}.fa-ideal:before{content:"\e013"}.fa-imdb:before{content:"\f2d8"}.fa-instagram:before{content:"\f16d"}.fa-instalod:before{content:"\e081"}.fa-intercom:before{content:"\f7af"}.fa-internet-explorer:before{content:"\f26b"}.fa-invision:before{content:"\f7b0"}.fa-ioxhost:before{content:"\f208"}.fa-itch-io:before{content:"\f83a"}.fa-itunes:before{content:"\f3b4"}.fa-itunes-note:before{content:"\f3b5"}.fa-java:before{content:"\f4e4"}.fa-jedi-order:before{content:"\f50e"}.fa-jenkins:before{content:"\f3b6"}.fa-jira:before{content:"\f7b1"}.fa-joget:before{content:"\f3b7"}.fa-joomla:before{content:"\f1aa"}.fa-js:before{content:"\f3b8"}.fa-jsfiddle:before{content:"\f1cc"}.fa-kaggle:before{content:"\f5fa"}.fa-keybase:before{content:"\f4f5"}.fa-keycdn:before{content:"\f3ba"}.fa-kickstarter:before{content:"\f3bb"}.fa-kickstarter-k:before{content:"\f3bc"}.fa-korvue:before{content:"\f42f"}.fa-laravel:before{content:"\f3bd"}.fa-lastfm:before{content:"\f202"}.fa-leanpub:before{content:"\f212"}.fa-less:before{content:"\f41d"}.fa-line:before{content:"\f3c0"}.fa-linkedin:before{content:"\f08c"}.fa-linkedin-in:before{content:"\f0e1"}.fa-linode:before{content:"\f2b8"}.fa-linux:before{content:"\f17c"}.fa-lyft:before{content:"\f3c3"}.fa-magento:before{content:"\f3c4"}.fa-mailchimp:before{content:"\f59e"}.fa-mandalorian:before{content:"\f50f"}.fa-markdown:before{content:"\f60f"}.fa-mastodon:before{content:"\f4f6"}.fa-maxcdn:before{content:"\f136"}.fa-mdb:before{content:"\f8ca"}.fa-medapps:before{content:"\f3c6"}.fa-medium-m:before,.fa-medium:before{content:"\f23a"}.fa-medrt:before{content:"\f3c8"}.fa-meetup:before{content:"\f2e0"}.fa-megaport:before{content:"\f5a3"}.fa-mendeley:before{content:"\f7b3"}.fa-meta:before{content:"\e49b"}.fa-microblog:before{content:"\e01a"}.fa-microsoft:before{content:"\f3ca"}.fa-mix:before{content:"\f3cb"}.fa-mixcloud:before{content:"\f289"}.fa-mixer:before{content:"\e056"}.fa-mizuni:before{content:"\f3cc"}.fa-modx:before{content:"\f285"}.fa-monero:before{content:"\f3d0"}.fa-napster:before{content:"\f3d2"}.fa-neos:before{content:"\f612"}.fa-nfc-directional:before{content:"\e530"}.fa-nfc-symbol:before{content:"\e531"}.fa-nimblr:before{content:"\f5a8"}.fa-node:before{content:"\f419"}.fa-node-js:before{content:"\f3d3"}.fa-npm:before{content:"\f3d4"}.fa-ns8:before{content:"\f3d5"}.fa-nutritionix:before{content:"\f3d6"}.fa-octopus-deploy:before{content:"\e082"}.fa-odnoklassniki:before{content:"\f263"}.fa-old-republic:before{content:"\f510"}.fa-opencart:before{content:"\f23d"}.fa-openid:before{content:"\f19b"}.fa-opera:before{content:"\f26a"}.fa-optin-monster:before{content:"\f23c"}.fa-orcid:before{content:"\f8d2"}.fa-osi:before{content:"\f41a"}.fa-padlet:before{content:"\e4a0"}.fa-page4:before{content:"\f3d7"}.fa-pagelines:before{content:"\f18c"}.fa-palfed:before{content:"\f3d8"}.fa-patreon:before{content:"\f3d9"}.fa-paypal:before{content:"\f1ed"}.fa-perbyte:before{content:"\e083"}.fa-periscope:before{content:"\f3da"}.fa-phabricator:before{content:"\f3db"}.fa-phoenix-framework:before{content:"\f3dc"}.fa-phoenix-squadron:before{content:"\f511"}.fa-php:before{content:"\f457"}.fa-pied-piper:before{content:"\f2ae"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-pied-piper-hat:before{content:"\f4e5"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-p:before{content:"\f231"}.fa-pix:before{content:"\e43a"}.fa-playstation:before{content:"\f3df"}.fa-product-hunt:before{content:"\f288"}.fa-pushed:before{content:"\f3e1"}.fa-python:before{content:"\f3e2"}.fa-qq:before{content:"\f1d6"}.fa-quinscape:before{content:"\f459"}.fa-quora:before{content:"\f2c4"}.fa-r-project:before{content:"\f4f7"}.fa-raspberry-pi:before{content:"\f7bb"}.fa-ravelry:before{content:"\f2d9"}.fa-react:before{content:"\f41b"}.fa-reacteurope:before{content:"\f75d"}.fa-readme:before{content:"\f4d5"}.fa-rebel:before{content:"\f1d0"}.fa-red-river:before{content:"\f3e3"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-alien:before{content:"\f281"}.fa-redhat:before{content:"\f7bc"}.fa-renren:before{content:"\f18b"}.fa-replyd:before{content:"\f3e6"}.fa-researchgate:before{content:"\f4f8"}.fa-resolving:before{content:"\f3e7"}.fa-rev:before{content:"\f5b2"}.fa-rocketchat:before{content:"\f3e8"}.fa-rockrms:before{content:"\f3e9"}.fa-rust:before{content:"\e07a"}.fa-safari:before{content:"\f267"}.fa-salesforce:before{content:"\f83b"}.fa-sass:before{content:"\f41e"}.fa-schlix:before{content:"\f3ea"}.fa-screenpal:before{content:"\e570"}.fa-scribd:before{content:"\f28a"}.fa-searchengin:before{content:"\f3eb"}.fa-sellcast:before{content:"\f2da"}.fa-sellsy:before{content:"\f213"}.fa-servicestack:before{content:"\f3ec"}.fa-shirtsinbulk:before{content:"\f214"}.fa-shopify:before{content:"\e057"}.fa-shopware:before{content:"\f5b5"}.fa-simplybuilt:before{content:"\f215"}.fa-sistrix:before{content:"\f3ee"}.fa-sith:before{content:"\f512"}.fa-sitrox:before{content:"\e44a"}.fa-sketch:before{content:"\f7c6"}.fa-skyatlas:before{content:"\f216"}.fa-skype:before{content:"\f17e"}.fa-slack-hash:before,.fa-slack:before{content:"\f198"}.fa-slideshare:before{content:"\f1e7"}.fa-snapchat-ghost:before,.fa-snapchat:before{content:"\f2ab"}.fa-soundcloud:before{content:"\f1be"}.fa-sourcetree:before{content:"\f7d3"}.fa-space-awesome:before{content:"\e5ac"}.fa-speakap:before{content:"\f3f3"}.fa-speaker-deck:before{content:"\f83c"}.fa-spotify:before{content:"\f1bc"}.fa-behance-square:before,.fa-square-behance:before{content:"\f1b5"}.fa-dribbble-square:before,.fa-square-dribbble:before{content:"\f397"}.fa-facebook-square:before,.fa-square-facebook:before{content:"\f082"}.fa-square-font-awesome:before{content:"\e5ad"}.fa-font-awesome-alt:before,.fa-square-font-awesome-stroke:before{content:"\f35c"}.fa-git-square:before,.fa-square-git:before{content:"\f1d2"}.fa-github-square:before,.fa-square-github:before{content:"\f092"}.fa-gitlab-square:before,.fa-square-gitlab:before{content:"\e5ae"}.fa-google-plus-square:before,.fa-square-google-plus:before{content:"\f0d4"}.fa-hacker-news-square:before,.fa-square-hacker-news:before{content:"\f3af"}.fa-instagram-square:before,.fa-square-instagram:before{content:"\e055"}.fa-js-square:before,.fa-square-js:before{content:"\f3b9"}.fa-lastfm-square:before,.fa-square-lastfm:before{content:"\f203"}.fa-odnoklassniki-square:before,.fa-square-odnoklassniki:before{content:"\f264"}.fa-pied-piper-square:before,.fa-square-pied-piper:before{content:"\e01e"}.fa-pinterest-square:before,.fa-square-pinterest:before{content:"\f0d3"}.fa-reddit-square:before,.fa-square-reddit:before{content:"\f1a2"}.fa-snapchat-square:before,.fa-square-snapchat:before{content:"\f2ad"}.fa-square-steam:before,.fa-steam-square:before{content:"\f1b7"}.fa-square-tumblr:before,.fa-tumblr-square:before{content:"\f174"}.fa-square-twitter:before,.fa-twitter-square:before{content:"\f081"}.fa-square-viadeo:before,.fa-viadeo-square:before{content:"\f2aa"}.fa-square-vimeo:before,.fa-vimeo-square:before{content:"\f194"}.fa-square-whatsapp:before,.fa-whatsapp-square:before{content:"\f40c"}.fa-square-xing:before,.fa-xing-square:before{content:"\f169"}.fa-square-youtube:before,.fa-youtube-square:before{content:"\f431"}.fa-squarespace:before{content:"\f5be"}.fa-stack-exchange:before{content:"\f18d"}.fa-stack-overflow:before{content:"\f16c"}.fa-stackpath:before{content:"\f842"}.fa-staylinked:before{content:"\f3f5"}.fa-steam:before{content:"\f1b6"}.fa-steam-symbol:before{content:"\f3f6"}.fa-sticker-mule:before{content:"\f3f7"}.fa-strava:before{content:"\f428"}.fa-stripe:before{content:"\f429"}.fa-stripe-s:before{content:"\f42a"}.fa-studiovinari:before{content:"\f3f8"}.fa-stumbleupon:before{content:"\f1a4"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-superpowers:before{content:"\f2dd"}.fa-supple:before{content:"\f3f9"}.fa-suse:before{content:"\f7d6"}.fa-swift:before{content:"\f8e1"}.fa-symfony:before{content:"\f83d"}.fa-teamspeak:before{content:"\f4f9"}.fa-telegram-plane:before,.fa-telegram:before{content:"\f2c6"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-the-red-yeti:before{content:"\f69d"}.fa-themeco:before{content:"\f5c6"}.fa-themeisle:before{content:"\f2b2"}.fa-think-peaks:before{content:"\f731"}.fa-tiktok:before{content:"\e07b"}.fa-trade-federation:before{content:"\f513"}.fa-trello:before{content:"\f181"}.fa-tumblr:before{content:"\f173"}.fa-twitch:before{content:"\f1e8"}.fa-twitter:before{content:"\f099"}.fa-typo3:before{content:"\f42b"}.fa-uber:before{content:"\f402"}.fa-ubuntu:before{content:"\f7df"}.fa-uikit:before{content:"\f403"}.fa-umbraco:before{content:"\f8e8"}.fa-uncharted:before{content:"\e084"}.fa-uniregistry:before{content:"\f404"}.fa-unity:before{content:"\e049"}.fa-unsplash:before{content:"\e07c"}.fa-untappd:before{content:"\f405"}.fa-ups:before{content:"\f7e0"}.fa-usb:before{content:"\f287"}.fa-usps:before{content:"\f7e1"}.fa-ussunnah:before{content:"\f407"}.fa-vaadin:before{content:"\f408"}.fa-viacoin:before{content:"\f237"}.fa-viadeo:before{content:"\f2a9"}.fa-viber:before{content:"\f409"}.fa-vimeo:before{content:"\f40a"}.fa-vimeo-v:before{content:"\f27d"}.fa-vine:before{content:"\f1ca"}.fa-vk:before{content:"\f189"}.fa-vnv:before{content:"\f40b"}.fa-vuejs:before{content:"\f41f"}.fa-watchman-monitoring:before{content:"\e087"}.fa-waze:before{content:"\f83f"}.fa-weebly:before{content:"\f5cc"}.fa-weibo:before{content:"\f18a"}.fa-weixin:before{content:"\f1d7"}.fa-whatsapp:before{content:"\f232"}.fa-whmcs:before{content:"\f40d"}.fa-wikipedia-w:before{content:"\f266"}.fa-windows:before{content:"\f17a"}.fa-wirsindhandwerk:before,.fa-wsh:before{content:"\e2d0"}.fa-wix:before{content:"\f5cf"}.fa-wizards-of-the-coast:before{content:"\f730"}.fa-wodu:before{content:"\e088"}.fa-wolf-pack-battalion:before{content:"\f514"}.fa-wordpress:before{content:"\f19a"}.fa-wordpress-simple:before{content:"\f411"}.fa-wpbeginner:before{content:"\f297"}.fa-wpexplorer:before{content:"\f2de"}.fa-wpforms:before{content:"\f298"}.fa-rendact:before,.fa-wpressr:before{content:"\f3e4"}.fa-xbox:before{content:"\f412"}.fa-xing:before{content:"\f168"}.fa-y-combinator:before{content:"\f23b"}.fa-yahoo:before{content:"\f19e"}.fa-yammer:before{content:"\f840"}.fa-yandex:before{content:"\f413"}.fa-yandex-international:before{content:"\f414"}.fa-yarn:before{content:"\f7e3"}.fa-yelp:before{content:"\f1e9"}.fa-yoast:before{content:"\f2b1"}.fa-youtube:before{content:"\f167"}.fa-zhihu:before{content:"\f63f"}:host,:root{--fa-font-regular:normal 400 1em/1 "Font Awesome 6 Free"}@font-face{font-family:"Font Awesome 6 Free";font-style:normal;font-weight:400;font-display:block;src:url(fa-regular-400.ttf) format("truetype")}.fa-regular,.far{font-family:"Font Awesome 6 Free";font-weight:400}:host,:root{--fa-font-solid:normal 900 1em/1 "Font Awesome 6 Free"}@font-face{font-family:"Font Awesome 6 Free";font-style:normal;font-weight:900;font-display:block;src:url(fa-solid-900.ttf) format("truetype")}.fa-solid,.fas{font-family:"Font Awesome 6 Free";font-weight:900}@font-face{font-family:"Font Awesome 5 Free";font-display:block;font-weight:900;src:url(fa-solid-900.ttf) format("truetype")}@font-face{font-family:"Font Awesome 5 Free";font-display:block;font-weight:400;src:url(fa-regular-400.ttf) format("truetype")}@font-face{font-family:"FontAwesome";font-display:block;src:url(fa-solid-900.ttf) format("truetype")}@font-face{font-family:"FontAwesome";font-display:block;src:url(fa-regular-400.ttf) format("truetype");unicode-range:u+f003,u+f006,u+f014,u+f016-f017,u+f01a-f01b,u+f01d,u+f022,u+f03e,u+f044,u+f046,u+f05c-f05d,u+f06e,u+f070,u+f087-f088,u+f08a,u+f094,u+f096-f097,u+f09d,u+f0a0,u+f0a2,u+f0a4-f0a7,u+f0c5,u+f0c7,u+f0e5-f0e6,u+f0eb,u+f0f6-f0f8,u+f10c,u+f114-f115,u+f118-f11a,u+f11c-f11d,u+f133,u+f147,u+f14e,u+f150-f152,u+f185-f186,u+f18e,u+f190-f192,u+f196,u+f1c1-f1c9,u+f1d9,u+f1db,u+f1e3,u+f1ea,u+f1f7,u+f1f9,u+f20a,u+f247-f248,u+f24a,u+f24d,u+f255-f25b,u+f25d,u+f271-f274,u+f278,u+f27b,u+f28c,u+f28e,u+f29c,u+f2b5,u+f2b7,u+f2ba,u+f2bc,u+f2be,u+f2c0-f2c1,u+f2c3,u+f2d0,u+f2d2,u+f2d4,u+f2dc}@font-face{font-family:"FontAwesome";font-display:block;src:url(fa-v4compatibility.ttf) format("truetype");unicode-range:u+f041,u+f047,u+f065-f066,u+f07d-f07e,u+f080,u+f08b,u+f08e,u+f090,u+f09a,u+f0ac,u+f0ae,u+f0b2,u+f0d0,u+f0d6,u+f0e4,u+f0ec,u+f10a-f10b,u+f123,u+f13e,u+f148-f149,u+f14c,u+f156,u+f15e,u+f160-f161,u+f163,u+f175-f178,u+f195,u+f1f8,u+f219,u+f27a} +.fa,.fab,.fad,.fal,.far,.fas{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;line-height:1}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-.0667em}.fa-xs{font-size:.75em}.fa-sm{font-size:.875em}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.fa-ul>li{position:relative}.fa-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border:.08em solid #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.fab.fa-pull-left,.fal.fa-pull-left,.far.fa-pull-left,.fas.fa-pull-left{margin-right:.3em}.fa.fa-pull-right,.fab.fa-pull-right,.fal.fa-pull-right,.far.fa-pull-right,.fas.fa-pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-webkit-transform:scaleY(-1);transform:scaleY(-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical,.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{-webkit-transform:scale(-1);transform:scale(-1)}:root .fa-flip-both,:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{-webkit-filter:none;filter:none}.fa-stack{display:inline-block;height:2em;line-height:2em;position:relative;vertical-align:middle;width:2.5em}.fa-stack-1x,.fa-stack-2x{left:0;position:absolute;text-align:center;width:100%}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-500px:before{content:"\f26e"}.fa-accessible-icon:before{content:"\f368"}.fa-accusoft:before{content:"\f369"}.fa-acquisitions-incorporated:before{content:"\f6af"}.fa-ad:before{content:"\f641"}.fa-address-book:before{content:"\f2b9"}.fa-address-card:before{content:"\f2bb"}.fa-adjust:before{content:"\f042"}.fa-adn:before{content:"\f170"}.fa-adobe:before{content:"\f778"}.fa-adversal:before{content:"\f36a"}.fa-affiliatetheme:before{content:"\f36b"}.fa-air-freshener:before{content:"\f5d0"}.fa-airbnb:before{content:"\f834"}.fa-algolia:before{content:"\f36c"}.fa-align-center:before{content:"\f037"}.fa-align-justify:before{content:"\f039"}.fa-align-left:before{content:"\f036"}.fa-align-right:before{content:"\f038"}.fa-alipay:before{content:"\f642"}.fa-allergies:before{content:"\f461"}.fa-amazon:before{content:"\f270"}.fa-amazon-pay:before{content:"\f42c"}.fa-ambulance:before{content:"\f0f9"}.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-amilia:before{content:"\f36d"}.fa-anchor:before{content:"\f13d"}.fa-android:before{content:"\f17b"}.fa-angellist:before{content:"\f209"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-down:before{content:"\f107"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angry:before{content:"\f556"}.fa-angrycreative:before{content:"\f36e"}.fa-angular:before{content:"\f420"}.fa-ankh:before{content:"\f644"}.fa-app-store:before{content:"\f36f"}.fa-app-store-ios:before{content:"\f370"}.fa-apper:before{content:"\f371"}.fa-apple:before{content:"\f179"}.fa-apple-alt:before{content:"\f5d1"}.fa-apple-pay:before{content:"\f415"}.fa-archive:before{content:"\f187"}.fa-archway:before{content:"\f557"}.fa-arrow-alt-circle-down:before{content:"\f358"}.fa-arrow-alt-circle-left:before{content:"\f359"}.fa-arrow-alt-circle-right:before{content:"\f35a"}.fa-arrow-alt-circle-up:before{content:"\f35b"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-down:before{content:"\f063"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrows-alt:before{content:"\f0b2"}.fa-arrows-alt-h:before{content:"\f337"}.fa-arrows-alt-v:before{content:"\f338"}.fa-artstation:before{content:"\f77a"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asterisk:before{content:"\f069"}.fa-asymmetrik:before{content:"\f372"}.fa-at:before{content:"\f1fa"}.fa-atlas:before{content:"\f558"}.fa-atlassian:before{content:"\f77b"}.fa-atom:before{content:"\f5d2"}.fa-audible:before{content:"\f373"}.fa-audio-description:before{content:"\f29e"}.fa-autoprefixer:before{content:"\f41c"}.fa-avianex:before{content:"\f374"}.fa-aviato:before{content:"\f421"}.fa-award:before{content:"\f559"}.fa-aws:before{content:"\f375"}.fa-baby:before{content:"\f77c"}.fa-baby-carriage:before{content:"\f77d"}.fa-backspace:before{content:"\f55a"}.fa-backward:before{content:"\f04a"}.fa-bacon:before{content:"\f7e5"}.fa-bacteria:before{content:"\e059"}.fa-bacterium:before{content:"\e05a"}.fa-bahai:before{content:"\f666"}.fa-balance-scale:before{content:"\f24e"}.fa-balance-scale-left:before{content:"\f515"}.fa-balance-scale-right:before{content:"\f516"}.fa-ban:before{content:"\f05e"}.fa-band-aid:before{content:"\f462"}.fa-bandcamp:before{content:"\f2d5"}.fa-barcode:before{content:"\f02a"}.fa-bars:before{content:"\f0c9"}.fa-baseball-ball:before{content:"\f433"}.fa-basketball-ball:before{content:"\f434"}.fa-bath:before{content:"\f2cd"}.fa-battery-empty:before{content:"\f244"}.fa-battery-full:before{content:"\f240"}.fa-battery-half:before{content:"\f242"}.fa-battery-quarter:before{content:"\f243"}.fa-battery-three-quarters:before{content:"\f241"}.fa-battle-net:before{content:"\f835"}.fa-bed:before{content:"\f236"}.fa-beer:before{content:"\f0fc"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-bell:before{content:"\f0f3"}.fa-bell-slash:before{content:"\f1f6"}.fa-bezier-curve:before{content:"\f55b"}.fa-bible:before{content:"\f647"}.fa-bicycle:before{content:"\f206"}.fa-biking:before{content:"\f84a"}.fa-bimobject:before{content:"\f378"}.fa-binoculars:before{content:"\f1e5"}.fa-biohazard:before{content:"\f780"}.fa-birthday-cake:before{content:"\f1fd"}.fa-bitbucket:before{content:"\f171"}.fa-bitcoin:before{content:"\f379"}.fa-bity:before{content:"\f37a"}.fa-black-tie:before{content:"\f27e"}.fa-blackberry:before{content:"\f37b"}.fa-blender:before{content:"\f517"}.fa-blender-phone:before{content:"\f6b6"}.fa-blind:before{content:"\f29d"}.fa-blog:before{content:"\f781"}.fa-blogger:before{content:"\f37c"}.fa-blogger-b:before{content:"\f37d"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-bold:before{content:"\f032"}.fa-bolt:before{content:"\f0e7"}.fa-bomb:before{content:"\f1e2"}.fa-bone:before{content:"\f5d7"}.fa-bong:before{content:"\f55c"}.fa-book:before{content:"\f02d"}.fa-book-dead:before{content:"\f6b7"}.fa-book-medical:before{content:"\f7e6"}.fa-book-open:before{content:"\f518"}.fa-book-reader:before{content:"\f5da"}.fa-bookmark:before{content:"\f02e"}.fa-bootstrap:before{content:"\f836"}.fa-border-all:before{content:"\f84c"}.fa-border-none:before{content:"\f850"}.fa-border-style:before{content:"\f853"}.fa-bowling-ball:before{content:"\f436"}.fa-box:before{content:"\f466"}.fa-box-open:before{content:"\f49e"}.fa-box-tissue:before{content:"\e05b"}.fa-boxes:before{content:"\f468"}.fa-braille:before{content:"\f2a1"}.fa-brain:before{content:"\f5dc"}.fa-bread-slice:before{content:"\f7ec"}.fa-briefcase:before{content:"\f0b1"}.fa-briefcase-medical:before{content:"\f469"}.fa-broadcast-tower:before{content:"\f519"}.fa-broom:before{content:"\f51a"}.fa-brush:before{content:"\f55d"}.fa-btc:before{content:"\f15a"}.fa-buffer:before{content:"\f837"}.fa-bug:before{content:"\f188"}.fa-building:before{content:"\f1ad"}.fa-bullhorn:before{content:"\f0a1"}.fa-bullseye:before{content:"\f140"}.fa-burn:before{content:"\f46a"}.fa-buromobelexperte:before{content:"\f37f"}.fa-bus:before{content:"\f207"}.fa-bus-alt:before{content:"\f55e"}.fa-business-time:before{content:"\f64a"}.fa-buy-n-large:before{content:"\f8a6"}.fa-buysellads:before{content:"\f20d"}.fa-calculator:before{content:"\f1ec"}.fa-calendar:before{content:"\f133"}.fa-calendar-alt:before{content:"\f073"}.fa-calendar-check:before{content:"\f274"}.fa-calendar-day:before{content:"\f783"}.fa-calendar-minus:before{content:"\f272"}.fa-calendar-plus:before{content:"\f271"}.fa-calendar-times:before{content:"\f273"}.fa-calendar-week:before{content:"\f784"}.fa-camera:before{content:"\f030"}.fa-camera-retro:before{content:"\f083"}.fa-campground:before{content:"\f6bb"}.fa-canadian-maple-leaf:before{content:"\f785"}.fa-candy-cane:before{content:"\f786"}.fa-cannabis:before{content:"\f55f"}.fa-capsules:before{content:"\f46b"}.fa-car:before{content:"\f1b9"}.fa-car-alt:before{content:"\f5de"}.fa-car-battery:before{content:"\f5df"}.fa-car-crash:before{content:"\f5e1"}.fa-car-side:before{content:"\f5e4"}.fa-caravan:before{content:"\f8ff"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-caret-square-down:before{content:"\f150"}.fa-caret-square-left:before{content:"\f191"}.fa-caret-square-right:before{content:"\f152"}.fa-caret-square-up:before{content:"\f151"}.fa-caret-up:before{content:"\f0d8"}.fa-carrot:before{content:"\f787"}.fa-cart-arrow-down:before{content:"\f218"}.fa-cart-plus:before{content:"\f217"}.fa-cash-register:before{content:"\f788"}.fa-cat:before{content:"\f6be"}.fa-cc-amazon-pay:before{content:"\f42d"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-apple-pay:before{content:"\f416"}.fa-cc-diners-club:before{content:"\f24c"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-cc-visa:before{content:"\f1f0"}.fa-centercode:before{content:"\f380"}.fa-centos:before{content:"\f789"}.fa-certificate:before{content:"\f0a3"}.fa-chair:before{content:"\f6c0"}.fa-chalkboard:before{content:"\f51b"}.fa-chalkboard-teacher:before{content:"\f51c"}.fa-charging-station:before{content:"\f5e7"}.fa-chart-area:before{content:"\f1fe"}.fa-chart-bar:before{content:"\f080"}.fa-chart-line:before{content:"\f201"}.fa-chart-pie:before{content:"\f200"}.fa-check:before{content:"\f00c"}.fa-check-circle:before{content:"\f058"}.fa-check-double:before{content:"\f560"}.fa-check-square:before{content:"\f14a"}.fa-cheese:before{content:"\f7ef"}.fa-chess:before{content:"\f439"}.fa-chess-bishop:before{content:"\f43a"}.fa-chess-board:before{content:"\f43c"}.fa-chess-king:before{content:"\f43f"}.fa-chess-knight:before{content:"\f441"}.fa-chess-pawn:before{content:"\f443"}.fa-chess-queen:before{content:"\f445"}.fa-chess-rook:before{content:"\f447"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-down:before{content:"\f078"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-chevron-up:before{content:"\f077"}.fa-child:before{content:"\f1ae"}.fa-chrome:before{content:"\f268"}.fa-chromecast:before{content:"\f838"}.fa-church:before{content:"\f51d"}.fa-circle:before{content:"\f111"}.fa-circle-notch:before{content:"\f1ce"}.fa-city:before{content:"\f64f"}.fa-clinic-medical:before{content:"\f7f2"}.fa-clipboard:before{content:"\f328"}.fa-clipboard-check:before{content:"\f46c"}.fa-clipboard-list:before{content:"\f46d"}.fa-clock:before{content:"\f017"}.fa-clone:before{content:"\f24d"}.fa-closed-captioning:before{content:"\f20a"}.fa-cloud:before{content:"\f0c2"}.fa-cloud-download-alt:before{content:"\f381"}.fa-cloud-meatball:before{content:"\f73b"}.fa-cloud-moon:before{content:"\f6c3"}.fa-cloud-moon-rain:before{content:"\f73c"}.fa-cloud-rain:before{content:"\f73d"}.fa-cloud-showers-heavy:before{content:"\f740"}.fa-cloud-sun:before{content:"\f6c4"}.fa-cloud-sun-rain:before{content:"\f743"}.fa-cloud-upload-alt:before{content:"\f382"}.fa-cloudscale:before{content:"\f383"}.fa-cloudsmith:before{content:"\f384"}.fa-cloudversify:before{content:"\f385"}.fa-cocktail:before{content:"\f561"}.fa-code:before{content:"\f121"}.fa-code-branch:before{content:"\f126"}.fa-codepen:before{content:"\f1cb"}.fa-codiepie:before{content:"\f284"}.fa-coffee:before{content:"\f0f4"}.fa-cog:before{content:"\f013"}.fa-cogs:before{content:"\f085"}.fa-coins:before{content:"\f51e"}.fa-columns:before{content:"\f0db"}.fa-comment:before{content:"\f075"}.fa-comment-alt:before{content:"\f27a"}.fa-comment-dollar:before{content:"\f651"}.fa-comment-dots:before{content:"\f4ad"}.fa-comment-medical:before{content:"\f7f5"}.fa-comment-slash:before{content:"\f4b3"}.fa-comments:before{content:"\f086"}.fa-comments-dollar:before{content:"\f653"}.fa-compact-disc:before{content:"\f51f"}.fa-compass:before{content:"\f14e"}.fa-compress:before{content:"\f066"}.fa-compress-alt:before{content:"\f422"}.fa-compress-arrows-alt:before{content:"\f78c"}.fa-concierge-bell:before{content:"\f562"}.fa-confluence:before{content:"\f78d"}.fa-connectdevelop:before{content:"\f20e"}.fa-contao:before{content:"\f26d"}.fa-cookie:before{content:"\f563"}.fa-cookie-bite:before{content:"\f564"}.fa-copy:before{content:"\f0c5"}.fa-copyright:before{content:"\f1f9"}.fa-cotton-bureau:before{content:"\f89e"}.fa-couch:before{content:"\f4b8"}.fa-cpanel:before{content:"\f388"}.fa-creative-commons:before{content:"\f25e"}.fa-creative-commons-by:before{content:"\f4e7"}.fa-creative-commons-nc:before{content:"\f4e8"}.fa-creative-commons-nc-eu:before{content:"\f4e9"}.fa-creative-commons-nc-jp:before{content:"\f4ea"}.fa-creative-commons-nd:before{content:"\f4eb"}.fa-creative-commons-pd:before{content:"\f4ec"}.fa-creative-commons-pd-alt:before{content:"\f4ed"}.fa-creative-commons-remix:before{content:"\f4ee"}.fa-creative-commons-sa:before{content:"\f4ef"}.fa-creative-commons-sampling:before{content:"\f4f0"}.fa-creative-commons-sampling-plus:before{content:"\f4f1"}.fa-creative-commons-share:before{content:"\f4f2"}.fa-creative-commons-zero:before{content:"\f4f3"}.fa-credit-card:before{content:"\f09d"}.fa-critical-role:before{content:"\f6c9"}.fa-crop:before{content:"\f125"}.fa-crop-alt:before{content:"\f565"}.fa-cross:before{content:"\f654"}.fa-crosshairs:before{content:"\f05b"}.fa-crow:before{content:"\f520"}.fa-crown:before{content:"\f521"}.fa-crutch:before{content:"\f7f7"}.fa-css3:before{content:"\f13c"}.fa-css3-alt:before{content:"\f38b"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-cut:before{content:"\f0c4"}.fa-cuttlefish:before{content:"\f38c"}.fa-d-and-d:before{content:"\f38d"}.fa-d-and-d-beyond:before{content:"\f6ca"}.fa-dailymotion:before{content:"\e052"}.fa-dashcube:before{content:"\f210"}.fa-database:before{content:"\f1c0"}.fa-deaf:before{content:"\f2a4"}.fa-deezer:before{content:"\e077"}.fa-delicious:before{content:"\f1a5"}.fa-democrat:before{content:"\f747"}.fa-deploydog:before{content:"\f38e"}.fa-deskpro:before{content:"\f38f"}.fa-desktop:before{content:"\f108"}.fa-dev:before{content:"\f6cc"}.fa-deviantart:before{content:"\f1bd"}.fa-dharmachakra:before{content:"\f655"}.fa-dhl:before{content:"\f790"}.fa-diagnoses:before{content:"\f470"}.fa-diaspora:before{content:"\f791"}.fa-dice:before{content:"\f522"}.fa-dice-d20:before{content:"\f6cf"}.fa-dice-d6:before{content:"\f6d1"}.fa-dice-five:before{content:"\f523"}.fa-dice-four:before{content:"\f524"}.fa-dice-one:before{content:"\f525"}.fa-dice-six:before{content:"\f526"}.fa-dice-three:before{content:"\f527"}.fa-dice-two:before{content:"\f528"}.fa-digg:before{content:"\f1a6"}.fa-digital-ocean:before{content:"\f391"}.fa-digital-tachograph:before{content:"\f566"}.fa-directions:before{content:"\f5eb"}.fa-discord:before{content:"\f392"}.fa-discourse:before{content:"\f393"}.fa-disease:before{content:"\f7fa"}.fa-divide:before{content:"\f529"}.fa-dizzy:before{content:"\f567"}.fa-dna:before{content:"\f471"}.fa-dochub:before{content:"\f394"}.fa-docker:before{content:"\f395"}.fa-dog:before{content:"\f6d3"}.fa-dollar-sign:before{content:"\f155"}.fa-dolly:before{content:"\f472"}.fa-dolly-flatbed:before{content:"\f474"}.fa-donate:before{content:"\f4b9"}.fa-door-closed:before{content:"\f52a"}.fa-door-open:before{content:"\f52b"}.fa-dot-circle:before{content:"\f192"}.fa-dove:before{content:"\f4ba"}.fa-download:before{content:"\f019"}.fa-draft2digital:before{content:"\f396"}.fa-drafting-compass:before{content:"\f568"}.fa-dragon:before{content:"\f6d5"}.fa-draw-polygon:before{content:"\f5ee"}.fa-dribbble:before{content:"\f17d"}.fa-dribbble-square:before{content:"\f397"}.fa-dropbox:before{content:"\f16b"}.fa-drum:before{content:"\f569"}.fa-drum-steelpan:before{content:"\f56a"}.fa-drumstick-bite:before{content:"\f6d7"}.fa-drupal:before{content:"\f1a9"}.fa-dumbbell:before{content:"\f44b"}.fa-dumpster:before{content:"\f793"}.fa-dumpster-fire:before{content:"\f794"}.fa-dungeon:before{content:"\f6d9"}.fa-dyalog:before{content:"\f399"}.fa-earlybirds:before{content:"\f39a"}.fa-ebay:before{content:"\f4f4"}.fa-edge:before{content:"\f282"}.fa-edge-legacy:before{content:"\e078"}.fa-edit:before{content:"\f044"}.fa-egg:before{content:"\f7fb"}.fa-eject:before{content:"\f052"}.fa-elementor:before{content:"\f430"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-ello:before{content:"\f5f1"}.fa-ember:before{content:"\f423"}.fa-empire:before{content:"\f1d1"}.fa-envelope:before{content:"\f0e0"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-text:before{content:"\f658"}.fa-envelope-square:before{content:"\f199"}.fa-envira:before{content:"\f299"}.fa-equals:before{content:"\f52c"}.fa-eraser:before{content:"\f12d"}.fa-erlang:before{content:"\f39d"}.fa-ethereum:before{content:"\f42e"}.fa-ethernet:before{content:"\f796"}.fa-etsy:before{content:"\f2d7"}.fa-euro-sign:before{content:"\f153"}.fa-evernote:before{content:"\f839"}.fa-exchange-alt:before{content:"\f362"}.fa-exclamation:before{content:"\f12a"}.fa-exclamation-circle:before{content:"\f06a"}.fa-exclamation-triangle:before{content:"\f071"}.fa-expand:before{content:"\f065"}.fa-expand-alt:before{content:"\f424"}.fa-expand-arrows-alt:before{content:"\f31e"}.fa-expeditedssl:before{content:"\f23e"}.fa-external-link-alt:before{content:"\f35d"}.fa-external-link-square-alt:before{content:"\f360"}.fa-eye:before{content:"\f06e"}.fa-eye-dropper:before{content:"\f1fb"}.fa-eye-slash:before{content:"\f070"}.fa-facebook:before{content:"\f09a"}.fa-facebook-f:before{content:"\f39e"}.fa-facebook-messenger:before{content:"\f39f"}.fa-facebook-square:before{content:"\f082"}.fa-fan:before{content:"\f863"}.fa-fantasy-flight-games:before{content:"\f6dc"}.fa-fast-backward:before{content:"\f049"}.fa-fast-forward:before{content:"\f050"}.fa-faucet:before{content:"\e005"}.fa-fax:before{content:"\f1ac"}.fa-feather:before{content:"\f52d"}.fa-feather-alt:before{content:"\f56b"}.fa-fedex:before{content:"\f797"}.fa-fedora:before{content:"\f798"}.fa-female:before{content:"\f182"}.fa-fighter-jet:before{content:"\f0fb"}.fa-figma:before{content:"\f799"}.fa-file:before{content:"\f15b"}.fa-file-alt:before{content:"\f15c"}.fa-file-archive:before{content:"\f1c6"}.fa-file-audio:before{content:"\f1c7"}.fa-file-code:before{content:"\f1c9"}.fa-file-contract:before{content:"\f56c"}.fa-file-csv:before{content:"\f6dd"}.fa-file-download:before{content:"\f56d"}.fa-file-excel:before{content:"\f1c3"}.fa-file-export:before{content:"\f56e"}.fa-file-image:before{content:"\f1c5"}.fa-file-import:before{content:"\f56f"}.fa-file-invoice:before{content:"\f570"}.fa-file-invoice-dollar:before{content:"\f571"}.fa-file-medical:before{content:"\f477"}.fa-file-medical-alt:before{content:"\f478"}.fa-file-pdf:before{content:"\f1c1"}.fa-file-powerpoint:before{content:"\f1c4"}.fa-file-prescription:before{content:"\f572"}.fa-file-signature:before{content:"\f573"}.fa-file-upload:before{content:"\f574"}.fa-file-video:before{content:"\f1c8"}.fa-file-word:before{content:"\f1c2"}.fa-fill:before{content:"\f575"}.fa-fill-drip:before{content:"\f576"}.fa-film:before{content:"\f008"}.fa-filter:before{content:"\f0b0"}.fa-fingerprint:before{content:"\f577"}.fa-fire:before{content:"\f06d"}.fa-fire-alt:before{content:"\f7e4"}.fa-fire-extinguisher:before{content:"\f134"}.fa-firefox:before{content:"\f269"}.fa-firefox-browser:before{content:"\e007"}.fa-first-aid:before{content:"\f479"}.fa-first-order:before{content:"\f2b0"}.fa-first-order-alt:before{content:"\f50a"}.fa-firstdraft:before{content:"\f3a1"}.fa-fish:before{content:"\f578"}.fa-fist-raised:before{content:"\f6de"}.fa-flag:before{content:"\f024"}.fa-flag-checkered:before{content:"\f11e"}.fa-flag-usa:before{content:"\f74d"}.fa-flask:before{content:"\f0c3"}.fa-flickr:before{content:"\f16e"}.fa-flipboard:before{content:"\f44d"}.fa-flushed:before{content:"\f579"}.fa-fly:before{content:"\f417"}.fa-folder:before{content:"\f07b"}.fa-folder-minus:before{content:"\f65d"}.fa-folder-open:before{content:"\f07c"}.fa-folder-plus:before{content:"\f65e"}.fa-font:before{content:"\f031"}.fa-font-awesome:before{content:"\f2b4"}.fa-font-awesome-alt:before{content:"\f35c"}.fa-font-awesome-flag:before{content:"\f425"}.fa-font-awesome-logo-full:before{content:"\f4e6"}.fa-fonticons:before{content:"\f280"}.fa-fonticons-fi:before{content:"\f3a2"}.fa-football-ball:before{content:"\f44e"}.fa-fort-awesome:before{content:"\f286"}.fa-fort-awesome-alt:before{content:"\f3a3"}.fa-forumbee:before{content:"\f211"}.fa-forward:before{content:"\f04e"}.fa-foursquare:before{content:"\f180"}.fa-free-code-camp:before{content:"\f2c5"}.fa-freebsd:before{content:"\f3a4"}.fa-frog:before{content:"\f52e"}.fa-frown:before{content:"\f119"}.fa-frown-open:before{content:"\f57a"}.fa-fulcrum:before{content:"\f50b"}.fa-funnel-dollar:before{content:"\f662"}.fa-futbol:before{content:"\f1e3"}.fa-galactic-republic:before{content:"\f50c"}.fa-galactic-senate:before{content:"\f50d"}.fa-gamepad:before{content:"\f11b"}.fa-gas-pump:before{content:"\f52f"}.fa-gavel:before{content:"\f0e3"}.fa-gem:before{content:"\f3a5"}.fa-genderless:before{content:"\f22d"}.fa-get-pocket:before{content:"\f265"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-ghost:before{content:"\f6e2"}.fa-gift:before{content:"\f06b"}.fa-gifts:before{content:"\f79c"}.fa-git:before{content:"\f1d3"}.fa-git-alt:before{content:"\f841"}.fa-git-square:before{content:"\f1d2"}.fa-github:before{content:"\f09b"}.fa-github-alt:before{content:"\f113"}.fa-github-square:before{content:"\f092"}.fa-gitkraken:before{content:"\f3a6"}.fa-gitlab:before{content:"\f296"}.fa-gitter:before{content:"\f426"}.fa-glass-cheers:before{content:"\f79f"}.fa-glass-martini:before{content:"\f000"}.fa-glass-martini-alt:before{content:"\f57b"}.fa-glass-whiskey:before{content:"\f7a0"}.fa-glasses:before{content:"\f530"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-globe:before{content:"\f0ac"}.fa-globe-africa:before{content:"\f57c"}.fa-globe-americas:before{content:"\f57d"}.fa-globe-asia:before{content:"\f57e"}.fa-globe-europe:before{content:"\f7a2"}.fa-gofore:before{content:"\f3a7"}.fa-golf-ball:before{content:"\f450"}.fa-goodreads:before{content:"\f3a8"}.fa-goodreads-g:before{content:"\f3a9"}.fa-google:before{content:"\f1a0"}.fa-google-drive:before{content:"\f3aa"}.fa-google-pay:before{content:"\e079"}.fa-google-play:before{content:"\f3ab"}.fa-google-plus:before{content:"\f2b3"}.fa-google-plus-g:before{content:"\f0d5"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-wallet:before{content:"\f1ee"}.fa-gopuram:before{content:"\f664"}.fa-graduation-cap:before{content:"\f19d"}.fa-gratipay:before{content:"\f184"}.fa-grav:before{content:"\f2d6"}.fa-greater-than:before{content:"\f531"}.fa-greater-than-equal:before{content:"\f532"}.fa-grimace:before{content:"\f57f"}.fa-grin:before{content:"\f580"}.fa-grin-alt:before{content:"\f581"}.fa-grin-beam:before{content:"\f582"}.fa-grin-beam-sweat:before{content:"\f583"}.fa-grin-hearts:before{content:"\f584"}.fa-grin-squint:before{content:"\f585"}.fa-grin-squint-tears:before{content:"\f586"}.fa-grin-stars:before{content:"\f587"}.fa-grin-tears:before{content:"\f588"}.fa-grin-tongue:before{content:"\f589"}.fa-grin-tongue-squint:before{content:"\f58a"}.fa-grin-tongue-wink:before{content:"\f58b"}.fa-grin-wink:before{content:"\f58c"}.fa-grip-horizontal:before{content:"\f58d"}.fa-grip-lines:before{content:"\f7a4"}.fa-grip-lines-vertical:before{content:"\f7a5"}.fa-grip-vertical:before{content:"\f58e"}.fa-gripfire:before{content:"\f3ac"}.fa-grunt:before{content:"\f3ad"}.fa-guitar:before{content:"\f7a6"}.fa-gulp:before{content:"\f3ae"}.fa-h-square:before{content:"\f0fd"}.fa-hacker-news:before{content:"\f1d4"}.fa-hacker-news-square:before{content:"\f3af"}.fa-hackerrank:before{content:"\f5f7"}.fa-hamburger:before{content:"\f805"}.fa-hammer:before{content:"\f6e3"}.fa-hamsa:before{content:"\f665"}.fa-hand-holding:before{content:"\f4bd"}.fa-hand-holding-heart:before{content:"\f4be"}.fa-hand-holding-medical:before{content:"\e05c"}.fa-hand-holding-usd:before{content:"\f4c0"}.fa-hand-holding-water:before{content:"\f4c1"}.fa-hand-lizard:before{content:"\f258"}.fa-hand-middle-finger:before{content:"\f806"}.fa-hand-paper:before{content:"\f256"}.fa-hand-peace:before{content:"\f25b"}.fa-hand-point-down:before{content:"\f0a7"}.fa-hand-point-left:before{content:"\f0a5"}.fa-hand-point-right:before{content:"\f0a4"}.fa-hand-point-up:before{content:"\f0a6"}.fa-hand-pointer:before{content:"\f25a"}.fa-hand-rock:before{content:"\f255"}.fa-hand-scissors:before{content:"\f257"}.fa-hand-sparkles:before{content:"\e05d"}.fa-hand-spock:before{content:"\f259"}.fa-hands:before{content:"\f4c2"}.fa-hands-helping:before{content:"\f4c4"}.fa-hands-wash:before{content:"\e05e"}.fa-handshake:before{content:"\f2b5"}.fa-handshake-alt-slash:before{content:"\e05f"}.fa-handshake-slash:before{content:"\e060"}.fa-hanukiah:before{content:"\f6e6"}.fa-hard-hat:before{content:"\f807"}.fa-hashtag:before{content:"\f292"}.fa-hat-cowboy:before{content:"\f8c0"}.fa-hat-cowboy-side:before{content:"\f8c1"}.fa-hat-wizard:before{content:"\f6e8"}.fa-hdd:before{content:"\f0a0"}.fa-head-side-cough:before{content:"\e061"}.fa-head-side-cough-slash:before{content:"\e062"}.fa-head-side-mask:before{content:"\e063"}.fa-head-side-virus:before{content:"\e064"}.fa-heading:before{content:"\f1dc"}.fa-headphones:before{content:"\f025"}.fa-headphones-alt:before{content:"\f58f"}.fa-headset:before{content:"\f590"}.fa-heart:before{content:"\f004"}.fa-heart-broken:before{content:"\f7a9"}.fa-heartbeat:before{content:"\f21e"}.fa-helicopter:before{content:"\f533"}.fa-highlighter:before{content:"\f591"}.fa-hiking:before{content:"\f6ec"}.fa-hippo:before{content:"\f6ed"}.fa-hips:before{content:"\f452"}.fa-hire-a-helper:before{content:"\f3b0"}.fa-history:before{content:"\f1da"}.fa-hockey-puck:before{content:"\f453"}.fa-holly-berry:before{content:"\f7aa"}.fa-home:before{content:"\f015"}.fa-hooli:before{content:"\f427"}.fa-hornbill:before{content:"\f592"}.fa-horse:before{content:"\f6f0"}.fa-horse-head:before{content:"\f7ab"}.fa-hospital:before{content:"\f0f8"}.fa-hospital-alt:before{content:"\f47d"}.fa-hospital-symbol:before{content:"\f47e"}.fa-hospital-user:before{content:"\f80d"}.fa-hot-tub:before{content:"\f593"}.fa-hotdog:before{content:"\f80f"}.fa-hotel:before{content:"\f594"}.fa-hotjar:before{content:"\f3b1"}.fa-hourglass:before{content:"\f254"}.fa-hourglass-end:before{content:"\f253"}.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-start:before{content:"\f251"}.fa-house-damage:before{content:"\f6f1"}.fa-house-user:before{content:"\e065"}.fa-houzz:before{content:"\f27c"}.fa-hryvnia:before{content:"\f6f2"}.fa-html5:before{content:"\f13b"}.fa-hubspot:before{content:"\f3b2"}.fa-i-cursor:before{content:"\f246"}.fa-ice-cream:before{content:"\f810"}.fa-icicles:before{content:"\f7ad"}.fa-icons:before{content:"\f86d"}.fa-id-badge:before{content:"\f2c1"}.fa-id-card:before{content:"\f2c2"}.fa-id-card-alt:before{content:"\f47f"}.fa-ideal:before{content:"\e013"}.fa-igloo:before{content:"\f7ae"}.fa-image:before{content:"\f03e"}.fa-images:before{content:"\f302"}.fa-imdb:before{content:"\f2d8"}.fa-inbox:before{content:"\f01c"}.fa-indent:before{content:"\f03c"}.fa-industry:before{content:"\f275"}.fa-infinity:before{content:"\f534"}.fa-info:before{content:"\f129"}.fa-info-circle:before{content:"\f05a"}.fa-instagram:before{content:"\f16d"}.fa-instagram-square:before{content:"\e055"}.fa-intercom:before{content:"\f7af"}.fa-internet-explorer:before{content:"\f26b"}.fa-invision:before{content:"\f7b0"}.fa-ioxhost:before{content:"\f208"}.fa-italic:before{content:"\f033"}.fa-itch-io:before{content:"\f83a"}.fa-itunes:before{content:"\f3b4"}.fa-itunes-note:before{content:"\f3b5"}.fa-java:before{content:"\f4e4"}.fa-jedi:before{content:"\f669"}.fa-jedi-order:before{content:"\f50e"}.fa-jenkins:before{content:"\f3b6"}.fa-jira:before{content:"\f7b1"}.fa-joget:before{content:"\f3b7"}.fa-joint:before{content:"\f595"}.fa-joomla:before{content:"\f1aa"}.fa-journal-whills:before{content:"\f66a"}.fa-js:before{content:"\f3b8"}.fa-js-square:before{content:"\f3b9"}.fa-jsfiddle:before{content:"\f1cc"}.fa-kaaba:before{content:"\f66b"}.fa-kaggle:before{content:"\f5fa"}.fa-key:before{content:"\f084"}.fa-keybase:before{content:"\f4f5"}.fa-keyboard:before{content:"\f11c"}.fa-keycdn:before{content:"\f3ba"}.fa-khanda:before{content:"\f66d"}.fa-kickstarter:before{content:"\f3bb"}.fa-kickstarter-k:before{content:"\f3bc"}.fa-kiss:before{content:"\f596"}.fa-kiss-beam:before{content:"\f597"}.fa-kiss-wink-heart:before{content:"\f598"}.fa-kiwi-bird:before{content:"\f535"}.fa-korvue:before{content:"\f42f"}.fa-landmark:before{content:"\f66f"}.fa-language:before{content:"\f1ab"}.fa-laptop:before{content:"\f109"}.fa-laptop-code:before{content:"\f5fc"}.fa-laptop-house:before{content:"\e066"}.fa-laptop-medical:before{content:"\f812"}.fa-laravel:before{content:"\f3bd"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-laugh:before{content:"\f599"}.fa-laugh-beam:before{content:"\f59a"}.fa-laugh-squint:before{content:"\f59b"}.fa-laugh-wink:before{content:"\f59c"}.fa-layer-group:before{content:"\f5fd"}.fa-leaf:before{content:"\f06c"}.fa-leanpub:before{content:"\f212"}.fa-lemon:before{content:"\f094"}.fa-less:before{content:"\f41d"}.fa-less-than:before{content:"\f536"}.fa-less-than-equal:before{content:"\f537"}.fa-level-down-alt:before{content:"\f3be"}.fa-level-up-alt:before{content:"\f3bf"}.fa-life-ring:before{content:"\f1cd"}.fa-lightbulb:before{content:"\f0eb"}.fa-line:before{content:"\f3c0"}.fa-link:before{content:"\f0c1"}.fa-linkedin:before{content:"\f08c"}.fa-linkedin-in:before{content:"\f0e1"}.fa-linode:before{content:"\f2b8"}.fa-linux:before{content:"\f17c"}.fa-lira-sign:before{content:"\f195"}.fa-list:before{content:"\f03a"}.fa-list-alt:before{content:"\f022"}.fa-list-ol:before{content:"\f0cb"}.fa-list-ul:before{content:"\f0ca"}.fa-location-arrow:before{content:"\f124"}.fa-lock:before{content:"\f023"}.fa-lock-open:before{content:"\f3c1"}.fa-long-arrow-alt-down:before{content:"\f309"}.fa-long-arrow-alt-left:before{content:"\f30a"}.fa-long-arrow-alt-right:before{content:"\f30b"}.fa-long-arrow-alt-up:before{content:"\f30c"}.fa-low-vision:before{content:"\f2a8"}.fa-luggage-cart:before{content:"\f59d"}.fa-lungs:before{content:"\f604"}.fa-lungs-virus:before{content:"\e067"}.fa-lyft:before{content:"\f3c3"}.fa-magento:before{content:"\f3c4"}.fa-magic:before{content:"\f0d0"}.fa-magnet:before{content:"\f076"}.fa-mail-bulk:before{content:"\f674"}.fa-mailchimp:before{content:"\f59e"}.fa-male:before{content:"\f183"}.fa-mandalorian:before{content:"\f50f"}.fa-map:before{content:"\f279"}.fa-map-marked:before{content:"\f59f"}.fa-map-marked-alt:before{content:"\f5a0"}.fa-map-marker:before{content:"\f041"}.fa-map-marker-alt:before{content:"\f3c5"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-markdown:before{content:"\f60f"}.fa-marker:before{content:"\f5a1"}.fa-mars:before{content:"\f222"}.fa-mars-double:before{content:"\f227"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mask:before{content:"\f6fa"}.fa-mastodon:before{content:"\f4f6"}.fa-maxcdn:before{content:"\f136"}.fa-mdb:before{content:"\f8ca"}.fa-medal:before{content:"\f5a2"}.fa-medapps:before{content:"\f3c6"}.fa-medium:before{content:"\f23a"}.fa-medium-m:before{content:"\f3c7"}.fa-medkit:before{content:"\f0fa"}.fa-medrt:before{content:"\f3c8"}.fa-meetup:before{content:"\f2e0"}.fa-megaport:before{content:"\f5a3"}.fa-meh:before{content:"\f11a"}.fa-meh-blank:before{content:"\f5a4"}.fa-meh-rolling-eyes:before{content:"\f5a5"}.fa-memory:before{content:"\f538"}.fa-mendeley:before{content:"\f7b3"}.fa-menorah:before{content:"\f676"}.fa-mercury:before{content:"\f223"}.fa-meteor:before{content:"\f753"}.fa-microblog:before{content:"\e01a"}.fa-microchip:before{content:"\f2db"}.fa-microphone:before{content:"\f130"}.fa-microphone-alt:before{content:"\f3c9"}.fa-microphone-alt-slash:before{content:"\f539"}.fa-microphone-slash:before{content:"\f131"}.fa-microscope:before{content:"\f610"}.fa-microsoft:before{content:"\f3ca"}.fa-minus:before{content:"\f068"}.fa-minus-circle:before{content:"\f056"}.fa-minus-square:before{content:"\f146"}.fa-mitten:before{content:"\f7b5"}.fa-mix:before{content:"\f3cb"}.fa-mixcloud:before{content:"\f289"}.fa-mixer:before{content:"\e056"}.fa-mizuni:before{content:"\f3cc"}.fa-mobile:before{content:"\f10b"}.fa-mobile-alt:before{content:"\f3cd"}.fa-modx:before{content:"\f285"}.fa-monero:before{content:"\f3d0"}.fa-money-bill:before{content:"\f0d6"}.fa-money-bill-alt:before{content:"\f3d1"}.fa-money-bill-wave:before{content:"\f53a"}.fa-money-bill-wave-alt:before{content:"\f53b"}.fa-money-check:before{content:"\f53c"}.fa-money-check-alt:before{content:"\f53d"}.fa-monument:before{content:"\f5a6"}.fa-moon:before{content:"\f186"}.fa-mortar-pestle:before{content:"\f5a7"}.fa-mosque:before{content:"\f678"}.fa-motorcycle:before{content:"\f21c"}.fa-mountain:before{content:"\f6fc"}.fa-mouse:before{content:"\f8cc"}.fa-mouse-pointer:before{content:"\f245"}.fa-mug-hot:before{content:"\f7b6"}.fa-music:before{content:"\f001"}.fa-napster:before{content:"\f3d2"}.fa-neos:before{content:"\f612"}.fa-network-wired:before{content:"\f6ff"}.fa-neuter:before{content:"\f22c"}.fa-newspaper:before{content:"\f1ea"}.fa-nimblr:before{content:"\f5a8"}.fa-node:before{content:"\f419"}.fa-node-js:before{content:"\f3d3"}.fa-not-equal:before{content:"\f53e"}.fa-notes-medical:before{content:"\f481"}.fa-npm:before{content:"\f3d4"}.fa-ns8:before{content:"\f3d5"}.fa-nutritionix:before{content:"\f3d6"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-oil-can:before{content:"\f613"}.fa-old-republic:before{content:"\f510"}.fa-om:before{content:"\f679"}.fa-opencart:before{content:"\f23d"}.fa-openid:before{content:"\f19b"}.fa-opera:before{content:"\f26a"}.fa-optin-monster:before{content:"\f23c"}.fa-orcid:before{content:"\f8d2"}.fa-osi:before{content:"\f41a"}.fa-otter:before{content:"\f700"}.fa-outdent:before{content:"\f03b"}.fa-page4:before{content:"\f3d7"}.fa-pagelines:before{content:"\f18c"}.fa-pager:before{content:"\f815"}.fa-paint-brush:before{content:"\f1fc"}.fa-paint-roller:before{content:"\f5aa"}.fa-palette:before{content:"\f53f"}.fa-palfed:before{content:"\f3d8"}.fa-pallet:before{content:"\f482"}.fa-paper-plane:before{content:"\f1d8"}.fa-paperclip:before{content:"\f0c6"}.fa-parachute-box:before{content:"\f4cd"}.fa-paragraph:before{content:"\f1dd"}.fa-parking:before{content:"\f540"}.fa-passport:before{content:"\f5ab"}.fa-pastafarianism:before{content:"\f67b"}.fa-paste:before{content:"\f0ea"}.fa-patreon:before{content:"\f3d9"}.fa-pause:before{content:"\f04c"}.fa-pause-circle:before{content:"\f28b"}.fa-paw:before{content:"\f1b0"}.fa-paypal:before{content:"\f1ed"}.fa-peace:before{content:"\f67c"}.fa-pen:before{content:"\f304"}.fa-pen-alt:before{content:"\f305"}.fa-pen-fancy:before{content:"\f5ac"}.fa-pen-nib:before{content:"\f5ad"}.fa-pen-square:before{content:"\f14b"}.fa-pencil-alt:before{content:"\f303"}.fa-pencil-ruler:before{content:"\f5ae"}.fa-penny-arcade:before{content:"\f704"}.fa-people-arrows:before{content:"\e068"}.fa-people-carry:before{content:"\f4ce"}.fa-pepper-hot:before{content:"\f816"}.fa-percent:before{content:"\f295"}.fa-percentage:before{content:"\f541"}.fa-periscope:before{content:"\f3da"}.fa-person-booth:before{content:"\f756"}.fa-phabricator:before{content:"\f3db"}.fa-phoenix-framework:before{content:"\f3dc"}.fa-phoenix-squadron:before{content:"\f511"}.fa-phone:before{content:"\f095"}.fa-phone-alt:before{content:"\f879"}.fa-phone-slash:before{content:"\f3dd"}.fa-phone-square:before{content:"\f098"}.fa-phone-square-alt:before{content:"\f87b"}.fa-phone-volume:before{content:"\f2a0"}.fa-photo-video:before{content:"\f87c"}.fa-php:before{content:"\f457"}.fa-pied-piper:before{content:"\f2ae"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-pied-piper-hat:before{content:"\f4e5"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-square:before{content:"\e01e"}.fa-piggy-bank:before{content:"\f4d3"}.fa-pills:before{content:"\f484"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-p:before{content:"\f231"}.fa-pinterest-square:before{content:"\f0d3"}.fa-pizza-slice:before{content:"\f818"}.fa-place-of-worship:before{content:"\f67f"}.fa-plane:before{content:"\f072"}.fa-plane-arrival:before{content:"\f5af"}.fa-plane-departure:before{content:"\f5b0"}.fa-plane-slash:before{content:"\e069"}.fa-play:before{content:"\f04b"}.fa-play-circle:before{content:"\f144"}.fa-playstation:before{content:"\f3df"}.fa-plug:before{content:"\f1e6"}.fa-plus:before{content:"\f067"}.fa-plus-circle:before{content:"\f055"}.fa-plus-square:before{content:"\f0fe"}.fa-podcast:before{content:"\f2ce"}.fa-poll:before{content:"\f681"}.fa-poll-h:before{content:"\f682"}.fa-poo:before{content:"\f2fe"}.fa-poo-storm:before{content:"\f75a"}.fa-poop:before{content:"\f619"}.fa-portrait:before{content:"\f3e0"}.fa-pound-sign:before{content:"\f154"}.fa-power-off:before{content:"\f011"}.fa-pray:before{content:"\f683"}.fa-praying-hands:before{content:"\f684"}.fa-prescription:before{content:"\f5b1"}.fa-prescription-bottle:before{content:"\f485"}.fa-prescription-bottle-alt:before{content:"\f486"}.fa-print:before{content:"\f02f"}.fa-procedures:before{content:"\f487"}.fa-product-hunt:before{content:"\f288"}.fa-project-diagram:before{content:"\f542"}.fa-pump-medical:before{content:"\e06a"}.fa-pump-soap:before{content:"\e06b"}.fa-pushed:before{content:"\f3e1"}.fa-puzzle-piece:before{content:"\f12e"}.fa-python:before{content:"\f3e2"}.fa-qq:before{content:"\f1d6"}.fa-qrcode:before{content:"\f029"}.fa-question:before{content:"\f128"}.fa-question-circle:before{content:"\f059"}.fa-quidditch:before{content:"\f458"}.fa-quinscape:before{content:"\f459"}.fa-quora:before{content:"\f2c4"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-quran:before{content:"\f687"}.fa-r-project:before{content:"\f4f7"}.fa-radiation:before{content:"\f7b9"}.fa-radiation-alt:before{content:"\f7ba"}.fa-rainbow:before{content:"\f75b"}.fa-random:before{content:"\f074"}.fa-raspberry-pi:before{content:"\f7bb"}.fa-ravelry:before{content:"\f2d9"}.fa-react:before{content:"\f41b"}.fa-reacteurope:before{content:"\f75d"}.fa-readme:before{content:"\f4d5"}.fa-rebel:before{content:"\f1d0"}.fa-receipt:before{content:"\f543"}.fa-record-vinyl:before{content:"\f8d9"}.fa-recycle:before{content:"\f1b8"}.fa-red-river:before{content:"\f3e3"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-alien:before{content:"\f281"}.fa-reddit-square:before{content:"\f1a2"}.fa-redhat:before{content:"\f7bc"}.fa-redo:before{content:"\f01e"}.fa-redo-alt:before{content:"\f2f9"}.fa-registered:before{content:"\f25d"}.fa-remove-format:before{content:"\f87d"}.fa-renren:before{content:"\f18b"}.fa-reply:before{content:"\f3e5"}.fa-reply-all:before{content:"\f122"}.fa-replyd:before{content:"\f3e6"}.fa-republican:before{content:"\f75e"}.fa-researchgate:before{content:"\f4f8"}.fa-resolving:before{content:"\f3e7"}.fa-restroom:before{content:"\f7bd"}.fa-retweet:before{content:"\f079"}.fa-rev:before{content:"\f5b2"}.fa-ribbon:before{content:"\f4d6"}.fa-ring:before{content:"\f70b"}.fa-road:before{content:"\f018"}.fa-robot:before{content:"\f544"}.fa-rocket:before{content:"\f135"}.fa-rocketchat:before{content:"\f3e8"}.fa-rockrms:before{content:"\f3e9"}.fa-route:before{content:"\f4d7"}.fa-rss:before{content:"\f09e"}.fa-rss-square:before{content:"\f143"}.fa-ruble-sign:before{content:"\f158"}.fa-ruler:before{content:"\f545"}.fa-ruler-combined:before{content:"\f546"}.fa-ruler-horizontal:before{content:"\f547"}.fa-ruler-vertical:before{content:"\f548"}.fa-running:before{content:"\f70c"}.fa-rupee-sign:before{content:"\f156"}.fa-rust:before{content:"\e07a"}.fa-sad-cry:before{content:"\f5b3"}.fa-sad-tear:before{content:"\f5b4"}.fa-safari:before{content:"\f267"}.fa-salesforce:before{content:"\f83b"}.fa-sass:before{content:"\f41e"}.fa-satellite:before{content:"\f7bf"}.fa-satellite-dish:before{content:"\f7c0"}.fa-save:before{content:"\f0c7"}.fa-schlix:before{content:"\f3ea"}.fa-school:before{content:"\f549"}.fa-screwdriver:before{content:"\f54a"}.fa-scribd:before{content:"\f28a"}.fa-scroll:before{content:"\f70e"}.fa-sd-card:before{content:"\f7c2"}.fa-search:before{content:"\f002"}.fa-search-dollar:before{content:"\f688"}.fa-search-location:before{content:"\f689"}.fa-search-minus:before{content:"\f010"}.fa-search-plus:before{content:"\f00e"}.fa-searchengin:before{content:"\f3eb"}.fa-seedling:before{content:"\f4d8"}.fa-sellcast:before{content:"\f2da"}.fa-sellsy:before{content:"\f213"}.fa-server:before{content:"\f233"}.fa-servicestack:before{content:"\f3ec"}.fa-shapes:before{content:"\f61f"}.fa-share:before{content:"\f064"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-share-square:before{content:"\f14d"}.fa-shekel-sign:before{content:"\f20b"}.fa-shield-alt:before{content:"\f3ed"}.fa-shield-virus:before{content:"\e06c"}.fa-ship:before{content:"\f21a"}.fa-shipping-fast:before{content:"\f48b"}.fa-shirtsinbulk:before{content:"\f214"}.fa-shoe-prints:before{content:"\f54b"}.fa-shopify:before{content:"\e057"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-shopping-cart:before{content:"\f07a"}.fa-shopware:before{content:"\f5b5"}.fa-shower:before{content:"\f2cc"}.fa-shuttle-van:before{content:"\f5b6"}.fa-sign:before{content:"\f4d9"}.fa-sign-in-alt:before{content:"\f2f6"}.fa-sign-language:before{content:"\f2a7"}.fa-sign-out-alt:before{content:"\f2f5"}.fa-signal:before{content:"\f012"}.fa-signature:before{content:"\f5b7"}.fa-sim-card:before{content:"\f7c4"}.fa-simplybuilt:before{content:"\f215"}.fa-sink:before{content:"\e06d"}.fa-sistrix:before{content:"\f3ee"}.fa-sitemap:before{content:"\f0e8"}.fa-sith:before{content:"\f512"}.fa-skating:before{content:"\f7c5"}.fa-sketch:before{content:"\f7c6"}.fa-skiing:before{content:"\f7c9"}.fa-skiing-nordic:before{content:"\f7ca"}.fa-skull:before{content:"\f54c"}.fa-skull-crossbones:before{content:"\f714"}.fa-skyatlas:before{content:"\f216"}.fa-skype:before{content:"\f17e"}.fa-slack:before{content:"\f198"}.fa-slack-hash:before{content:"\f3ef"}.fa-slash:before{content:"\f715"}.fa-sleigh:before{content:"\f7cc"}.fa-sliders-h:before{content:"\f1de"}.fa-slideshare:before{content:"\f1e7"}.fa-smile:before{content:"\f118"}.fa-smile-beam:before{content:"\f5b8"}.fa-smile-wink:before{content:"\f4da"}.fa-smog:before{content:"\f75f"}.fa-smoking:before{content:"\f48d"}.fa-smoking-ban:before{content:"\f54d"}.fa-sms:before{content:"\f7cd"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-snowboarding:before{content:"\f7ce"}.fa-snowflake:before{content:"\f2dc"}.fa-snowman:before{content:"\f7d0"}.fa-snowplow:before{content:"\f7d2"}.fa-soap:before{content:"\e06e"}.fa-socks:before{content:"\f696"}.fa-solar-panel:before{content:"\f5ba"}.fa-sort:before{content:"\f0dc"}.fa-sort-alpha-down:before{content:"\f15d"}.fa-sort-alpha-down-alt:before{content:"\f881"}.fa-sort-alpha-up:before{content:"\f15e"}.fa-sort-alpha-up-alt:before{content:"\f882"}.fa-sort-amount-down:before{content:"\f160"}.fa-sort-amount-down-alt:before{content:"\f884"}.fa-sort-amount-up:before{content:"\f161"}.fa-sort-amount-up-alt:before{content:"\f885"}.fa-sort-down:before{content:"\f0dd"}.fa-sort-numeric-down:before{content:"\f162"}.fa-sort-numeric-down-alt:before{content:"\f886"}.fa-sort-numeric-up:before{content:"\f163"}.fa-sort-numeric-up-alt:before{content:"\f887"}.fa-sort-up:before{content:"\f0de"}.fa-soundcloud:before{content:"\f1be"}.fa-sourcetree:before{content:"\f7d3"}.fa-spa:before{content:"\f5bb"}.fa-space-shuttle:before{content:"\f197"}.fa-speakap:before{content:"\f3f3"}.fa-speaker-deck:before{content:"\f83c"}.fa-spell-check:before{content:"\f891"}.fa-spider:before{content:"\f717"}.fa-spinner:before{content:"\f110"}.fa-splotch:before{content:"\f5bc"}.fa-spotify:before{content:"\f1bc"}.fa-spray-can:before{content:"\f5bd"}.fa-square:before{content:"\f0c8"}.fa-square-full:before{content:"\f45c"}.fa-square-root-alt:before{content:"\f698"}.fa-squarespace:before{content:"\f5be"}.fa-stack-exchange:before{content:"\f18d"}.fa-stack-overflow:before{content:"\f16c"}.fa-stackpath:before{content:"\f842"}.fa-stamp:before{content:"\f5bf"}.fa-star:before{content:"\f005"}.fa-star-and-crescent:before{content:"\f699"}.fa-star-half:before{content:"\f089"}.fa-star-half-alt:before{content:"\f5c0"}.fa-star-of-david:before{content:"\f69a"}.fa-star-of-life:before{content:"\f621"}.fa-staylinked:before{content:"\f3f5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-steam-symbol:before{content:"\f3f6"}.fa-step-backward:before{content:"\f048"}.fa-step-forward:before{content:"\f051"}.fa-stethoscope:before{content:"\f0f1"}.fa-sticker-mule:before{content:"\f3f7"}.fa-sticky-note:before{content:"\f249"}.fa-stop:before{content:"\f04d"}.fa-stop-circle:before{content:"\f28d"}.fa-stopwatch:before{content:"\f2f2"}.fa-stopwatch-20:before{content:"\e06f"}.fa-store:before{content:"\f54e"}.fa-store-alt:before{content:"\f54f"}.fa-store-alt-slash:before{content:"\e070"}.fa-store-slash:before{content:"\e071"}.fa-strava:before{content:"\f428"}.fa-stream:before{content:"\f550"}.fa-street-view:before{content:"\f21d"}.fa-strikethrough:before{content:"\f0cc"}.fa-stripe:before{content:"\f429"}.fa-stripe-s:before{content:"\f42a"}.fa-stroopwafel:before{content:"\f551"}.fa-studiovinari:before{content:"\f3f8"}.fa-stumbleupon:before{content:"\f1a4"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-subscript:before{content:"\f12c"}.fa-subway:before{content:"\f239"}.fa-suitcase:before{content:"\f0f2"}.fa-suitcase-rolling:before{content:"\f5c1"}.fa-sun:before{content:"\f185"}.fa-superpowers:before{content:"\f2dd"}.fa-superscript:before{content:"\f12b"}.fa-supple:before{content:"\f3f9"}.fa-surprise:before{content:"\f5c2"}.fa-suse:before{content:"\f7d6"}.fa-swatchbook:before{content:"\f5c3"}.fa-swift:before{content:"\f8e1"}.fa-swimmer:before{content:"\f5c4"}.fa-swimming-pool:before{content:"\f5c5"}.fa-symfony:before{content:"\f83d"}.fa-synagogue:before{content:"\f69b"}.fa-sync:before{content:"\f021"}.fa-sync-alt:before{content:"\f2f1"}.fa-syringe:before{content:"\f48e"}.fa-table:before{content:"\f0ce"}.fa-table-tennis:before{content:"\f45d"}.fa-tablet:before{content:"\f10a"}.fa-tablet-alt:before{content:"\f3fa"}.fa-tablets:before{content:"\f490"}.fa-tachometer-alt:before{content:"\f3fd"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-tape:before{content:"\f4db"}.fa-tasks:before{content:"\f0ae"}.fa-taxi:before{content:"\f1ba"}.fa-teamspeak:before{content:"\f4f9"}.fa-teeth:before{content:"\f62e"}.fa-teeth-open:before{content:"\f62f"}.fa-telegram:before{content:"\f2c6"}.fa-telegram-plane:before{content:"\f3fe"}.fa-temperature-high:before{content:"\f769"}.fa-temperature-low:before{content:"\f76b"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-tenge:before{content:"\f7d7"}.fa-terminal:before{content:"\f120"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-th:before{content:"\f00a"}.fa-th-large:before{content:"\f009"}.fa-th-list:before{content:"\f00b"}.fa-the-red-yeti:before{content:"\f69d"}.fa-theater-masks:before{content:"\f630"}.fa-themeco:before{content:"\f5c6"}.fa-themeisle:before{content:"\f2b2"}.fa-thermometer:before{content:"\f491"}.fa-thermometer-empty:before{content:"\f2cb"}.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-think-peaks:before{content:"\f731"}.fa-thumbs-down:before{content:"\f165"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbtack:before{content:"\f08d"}.fa-ticket-alt:before{content:"\f3ff"}.fa-tiktok:before{content:"\e07b"}.fa-times:before{content:"\f00d"}.fa-times-circle:before{content:"\f057"}.fa-tint:before{content:"\f043"}.fa-tint-slash:before{content:"\f5c7"}.fa-tired:before{content:"\f5c8"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-toilet:before{content:"\f7d8"}.fa-toilet-paper:before{content:"\f71e"}.fa-toilet-paper-slash:before{content:"\e072"}.fa-toolbox:before{content:"\f552"}.fa-tools:before{content:"\f7d9"}.fa-tooth:before{content:"\f5c9"}.fa-torah:before{content:"\f6a0"}.fa-torii-gate:before{content:"\f6a1"}.fa-tractor:before{content:"\f722"}.fa-trade-federation:before{content:"\f513"}.fa-trademark:before{content:"\f25c"}.fa-traffic-light:before{content:"\f637"}.fa-trailer:before{content:"\e041"}.fa-train:before{content:"\f238"}.fa-tram:before{content:"\f7da"}.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-trash:before{content:"\f1f8"}.fa-trash-alt:before{content:"\f2ed"}.fa-trash-restore:before{content:"\f829"}.fa-trash-restore-alt:before{content:"\f82a"}.fa-tree:before{content:"\f1bb"}.fa-trello:before{content:"\f181"}.fa-tripadvisor:before{content:"\f262"}.fa-trophy:before{content:"\f091"}.fa-truck:before{content:"\f0d1"}.fa-truck-loading:before{content:"\f4de"}.fa-truck-monster:before{content:"\f63b"}.fa-truck-moving:before{content:"\f4df"}.fa-truck-pickup:before{content:"\f63c"}.fa-tshirt:before{content:"\f553"}.fa-tty:before{content:"\f1e4"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-tv:before{content:"\f26c"}.fa-twitch:before{content:"\f1e8"}.fa-twitter:before{content:"\f099"}.fa-twitter-square:before{content:"\f081"}.fa-typo3:before{content:"\f42b"}.fa-uber:before{content:"\f402"}.fa-ubuntu:before{content:"\f7df"}.fa-uikit:before{content:"\f403"}.fa-umbraco:before{content:"\f8e8"}.fa-umbrella:before{content:"\f0e9"}.fa-umbrella-beach:before{content:"\f5ca"}.fa-underline:before{content:"\f0cd"}.fa-undo:before{content:"\f0e2"}.fa-undo-alt:before{content:"\f2ea"}.fa-uniregistry:before{content:"\f404"}.fa-unity:before{content:"\e049"}.fa-universal-access:before{content:"\f29a"}.fa-university:before{content:"\f19c"}.fa-unlink:before{content:"\f127"}.fa-unlock:before{content:"\f09c"}.fa-unlock-alt:before{content:"\f13e"}.fa-unsplash:before{content:"\e07c"}.fa-untappd:before{content:"\f405"}.fa-upload:before{content:"\f093"}.fa-ups:before{content:"\f7e0"}.fa-usb:before{content:"\f287"}.fa-user:before{content:"\f007"}.fa-user-alt:before{content:"\f406"}.fa-user-alt-slash:before{content:"\f4fa"}.fa-user-astronaut:before{content:"\f4fb"}.fa-user-check:before{content:"\f4fc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-clock:before{content:"\f4fd"}.fa-user-cog:before{content:"\f4fe"}.fa-user-edit:before{content:"\f4ff"}.fa-user-friends:before{content:"\f500"}.fa-user-graduate:before{content:"\f501"}.fa-user-injured:before{content:"\f728"}.fa-user-lock:before{content:"\f502"}.fa-user-md:before{content:"\f0f0"}.fa-user-minus:before{content:"\f503"}.fa-user-ninja:before{content:"\f504"}.fa-user-nurse:before{content:"\f82f"}.fa-user-plus:before{content:"\f234"}.fa-user-secret:before{content:"\f21b"}.fa-user-shield:before{content:"\f505"}.fa-user-slash:before{content:"\f506"}.fa-user-tag:before{content:"\f507"}.fa-user-tie:before{content:"\f508"}.fa-user-times:before{content:"\f235"}.fa-users:before{content:"\f0c0"}.fa-users-cog:before{content:"\f509"}.fa-users-slash:before{content:"\e073"}.fa-usps:before{content:"\f7e1"}.fa-ussunnah:before{content:"\f407"}.fa-utensil-spoon:before{content:"\f2e5"}.fa-utensils:before{content:"\f2e7"}.fa-vaadin:before{content:"\f408"}.fa-vector-square:before{content:"\f5cb"}.fa-venus:before{content:"\f221"}.fa-venus-double:before{content:"\f226"}.fa-venus-mars:before{content:"\f228"}.fa-viacoin:before{content:"\f237"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-vial:before{content:"\f492"}.fa-vials:before{content:"\f493"}.fa-viber:before{content:"\f409"}.fa-video:before{content:"\f03d"}.fa-video-slash:before{content:"\f4e2"}.fa-vihara:before{content:"\f6a7"}.fa-vimeo:before{content:"\f40a"}.fa-vimeo-square:before{content:"\f194"}.fa-vimeo-v:before{content:"\f27d"}.fa-vine:before{content:"\f1ca"}.fa-virus:before{content:"\e074"}.fa-virus-slash:before{content:"\e075"}.fa-viruses:before{content:"\e076"}.fa-vk:before{content:"\f189"}.fa-vnv:before{content:"\f40b"}.fa-voicemail:before{content:"\f897"}.fa-volleyball-ball:before{content:"\f45f"}.fa-volume-down:before{content:"\f027"}.fa-volume-mute:before{content:"\f6a9"}.fa-volume-off:before{content:"\f026"}.fa-volume-up:before{content:"\f028"}.fa-vote-yea:before{content:"\f772"}.fa-vr-cardboard:before{content:"\f729"}.fa-vuejs:before{content:"\f41f"}.fa-walking:before{content:"\f554"}.fa-wallet:before{content:"\f555"}.fa-warehouse:before{content:"\f494"}.fa-water:before{content:"\f773"}.fa-wave-square:before{content:"\f83e"}.fa-waze:before{content:"\f83f"}.fa-weebly:before{content:"\f5cc"}.fa-weibo:before{content:"\f18a"}.fa-weight:before{content:"\f496"}.fa-weight-hanging:before{content:"\f5cd"}.fa-weixin:before{content:"\f1d7"}.fa-whatsapp:before{content:"\f232"}.fa-whatsapp-square:before{content:"\f40c"}.fa-wheelchair:before{content:"\f193"}.fa-whmcs:before{content:"\f40d"}.fa-wifi:before{content:"\f1eb"}.fa-wikipedia-w:before{content:"\f266"}.fa-wind:before{content:"\f72e"}.fa-window-close:before{content:"\f410"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-windows:before{content:"\f17a"}.fa-wine-bottle:before{content:"\f72f"}.fa-wine-glass:before{content:"\f4e3"}.fa-wine-glass-alt:before{content:"\f5ce"}.fa-wix:before{content:"\f5cf"}.fa-wizards-of-the-coast:before{content:"\f730"}.fa-wolf-pack-battalion:before{content:"\f514"}.fa-won-sign:before{content:"\f159"}.fa-wordpress:before{content:"\f19a"}.fa-wordpress-simple:before{content:"\f411"}.fa-wpbeginner:before{content:"\f297"}.fa-wpexplorer:before{content:"\f2de"}.fa-wpforms:before{content:"\f298"}.fa-wpressr:before{content:"\f3e4"}.fa-wrench:before{content:"\f0ad"}.fa-x-ray:before{content:"\f497"}.fa-xbox:before{content:"\f412"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-y-combinator:before{content:"\f23b"}.fa-yahoo:before{content:"\f19e"}.fa-yammer:before{content:"\f840"}.fa-yandex:before{content:"\f413"}.fa-yandex-international:before{content:"\f414"}.fa-yarn:before{content:"\f7e3"}.fa-yelp:before{content:"\f1e9"}.fa-yen-sign:before{content:"\f157"}.fa-yin-yang:before{content:"\f6ad"}.fa-yoast:before{content:"\f2b1"}.fa-youtube:before{content:"\f167"}.fa-youtube-square:before{content:"\f431"}.fa-zhihu:before{content:"\f63f"}.sr-only{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}@font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:400;font-display:auto;src:url(fa-regular-400.eot);src:url(fa-regular-400.eot?#iefix) format("embedded-opentype"),url(fa-regular-400.woff) format("woff")}.far{font-weight:400}@font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:900;font-display:auto;src:url(fa-solid-900.eot);src:url(fa-solid-900.eot?#iefix) format("embedded-opentype"),url(fa-solid-900.woff) format("woff")}.fa,.far,.fas{font-family:"Font Awesome 5 Free"}.fa,.fas{font-weight:900} \ No newline at end of file diff --git a/html/font-awesome/css/v4-shims.min.css b/html/font-awesome/css/v4-shims.min.css index 2f6252b52a1..ee29a2c92db 100644 --- a/html/font-awesome/css/v4-shims.min.css +++ b/html/font-awesome/css/v4-shims.min.css @@ -1,6 +1,5 @@ /*! - * Font Awesome Free 6.1.2 by @fontawesome - https://fontawesome.com + * Font Awesome Free 5.14.0 by @fontawesome - https://fontawesome.com * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) - * Copyright 2022 Fonticons, Inc. */ -.fa.fa-glass:before{content:"\f000"}.fa.fa-envelope-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-envelope-o:before{content:"\f0e0"}.fa.fa-star-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-star-o:before{content:"\f005"}.fa.fa-close:before,.fa.fa-remove:before{content:"\f00d"}.fa.fa-gear:before{content:"\f013"}.fa.fa-trash-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-trash-o:before{content:"\f2ed"}.fa.fa-home:before{content:"\f015"}.fa.fa-file-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-o:before{content:"\f15b"}.fa.fa-clock-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-clock-o:before{content:"\f017"}.fa.fa-arrow-circle-o-down{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-arrow-circle-o-down:before{content:"\f358"}.fa.fa-arrow-circle-o-up{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-arrow-circle-o-up:before{content:"\f35b"}.fa.fa-play-circle-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-play-circle-o:before{content:"\f144"}.fa.fa-repeat:before,.fa.fa-rotate-right:before{content:"\f01e"}.fa.fa-refresh:before{content:"\f021"}.fa.fa-list-alt{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-list-alt:before{content:"\f022"}.fa.fa-dedent:before{content:"\f03b"}.fa.fa-video-camera:before{content:"\f03d"}.fa.fa-picture-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-picture-o:before{content:"\f03e"}.fa.fa-photo{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-photo:before{content:"\f03e"}.fa.fa-image{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-image:before{content:"\f03e"}.fa.fa-map-marker:before{content:"\f3c5"}.fa.fa-pencil-square-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-pencil-square-o:before{content:"\f044"}.fa.fa-edit{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-edit:before{content:"\f044"}.fa.fa-share-square-o:before{content:"\f14d"}.fa.fa-check-square-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-check-square-o:before{content:"\f14a"}.fa.fa-arrows:before{content:"\f0b2"}.fa.fa-times-circle-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-times-circle-o:before{content:"\f057"}.fa.fa-check-circle-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-check-circle-o:before{content:"\f058"}.fa.fa-mail-forward:before{content:"\f064"}.fa.fa-expand:before{content:"\f424"}.fa.fa-compress:before{content:"\f422"}.fa.fa-eye,.fa.fa-eye-slash{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-warning:before{content:"\f071"}.fa.fa-calendar:before{content:"\f073"}.fa.fa-arrows-v:before{content:"\f338"}.fa.fa-arrows-h:before{content:"\f337"}.fa.fa-bar-chart-o:before,.fa.fa-bar-chart:before{content:"\e0e3"}.fa.fa-twitter-square{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-twitter-square:before{content:"\f081"}.fa.fa-facebook-square{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-facebook-square:before{content:"\f082"}.fa.fa-gears:before{content:"\f085"}.fa.fa-thumbs-o-up{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-thumbs-o-up:before{content:"\f164"}.fa.fa-thumbs-o-down{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-thumbs-o-down:before{content:"\f165"}.fa.fa-heart-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-heart-o:before{content:"\f004"}.fa.fa-sign-out:before{content:"\f2f5"}.fa.fa-linkedin-square{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-linkedin-square:before{content:"\f08c"}.fa.fa-thumb-tack:before{content:"\f08d"}.fa.fa-external-link:before{content:"\f35d"}.fa.fa-sign-in:before{content:"\f2f6"}.fa.fa-github-square{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-github-square:before{content:"\f092"}.fa.fa-lemon-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-lemon-o:before{content:"\f094"}.fa.fa-square-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-square-o:before{content:"\f0c8"}.fa.fa-bookmark-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-bookmark-o:before{content:"\f02e"}.fa.fa-facebook,.fa.fa-twitter{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-facebook:before{content:"\f39e"}.fa.fa-facebook-f{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-facebook-f:before{content:"\f39e"}.fa.fa-github{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-credit-card{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-feed:before{content:"\f09e"}.fa.fa-hdd-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hdd-o:before{content:"\f0a0"}.fa.fa-hand-o-right{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hand-o-right:before{content:"\f0a4"}.fa.fa-hand-o-left{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hand-o-left:before{content:"\f0a5"}.fa.fa-hand-o-up{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hand-o-up:before{content:"\f0a6"}.fa.fa-hand-o-down{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hand-o-down:before{content:"\f0a7"}.fa.fa-globe:before{content:"\f57d"}.fa.fa-tasks:before{content:"\f828"}.fa.fa-arrows-alt:before{content:"\f31e"}.fa.fa-group:before{content:"\f0c0"}.fa.fa-chain:before{content:"\f0c1"}.fa.fa-cut:before{content:"\f0c4"}.fa.fa-files-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-files-o:before{content:"\f0c5"}.fa.fa-floppy-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-floppy-o:before{content:"\f0c7"}.fa.fa-save{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-save:before{content:"\f0c7"}.fa.fa-navicon:before,.fa.fa-reorder:before{content:"\f0c9"}.fa.fa-magic:before{content:"\e2ca"}.fa.fa-pinterest,.fa.fa-pinterest-square{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-pinterest-square:before{content:"\f0d3"}.fa.fa-google-plus-square{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-google-plus-square:before{content:"\f0d4"}.fa.fa-google-plus{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-google-plus:before{content:"\f0d5"}.fa.fa-money:before{content:"\f3d1"}.fa.fa-unsorted:before{content:"\f0dc"}.fa.fa-sort-desc:before{content:"\f0dd"}.fa.fa-sort-asc:before{content:"\f0de"}.fa.fa-linkedin{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-linkedin:before{content:"\f0e1"}.fa.fa-rotate-left:before{content:"\f0e2"}.fa.fa-legal:before{content:"\f0e3"}.fa.fa-dashboard:before,.fa.fa-tachometer:before{content:"\f625"}.fa.fa-comment-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-comment-o:before{content:"\f075"}.fa.fa-comments-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-comments-o:before{content:"\f086"}.fa.fa-flash:before{content:"\f0e7"}.fa.fa-clipboard:before{content:"\f0ea"}.fa.fa-lightbulb-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-lightbulb-o:before{content:"\f0eb"}.fa.fa-exchange:before{content:"\f362"}.fa.fa-cloud-download:before{content:"\f0ed"}.fa.fa-cloud-upload:before{content:"\f0ee"}.fa.fa-bell-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-bell-o:before{content:"\f0f3"}.fa.fa-cutlery:before{content:"\f2e7"}.fa.fa-file-text-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-text-o:before{content:"\f15c"}.fa.fa-building-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-building-o:before{content:"\f1ad"}.fa.fa-hospital-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hospital-o:before{content:"\f0f8"}.fa.fa-tablet:before{content:"\f3fa"}.fa.fa-mobile-phone:before,.fa.fa-mobile:before{content:"\f3cd"}.fa.fa-circle-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-circle-o:before{content:"\f111"}.fa.fa-mail-reply:before{content:"\f3e5"}.fa.fa-github-alt{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-folder-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-folder-o:before{content:"\f07b"}.fa.fa-folder-open-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-folder-open-o:before{content:"\f07c"}.fa.fa-smile-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-smile-o:before{content:"\f118"}.fa.fa-frown-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-frown-o:before{content:"\f119"}.fa.fa-meh-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-meh-o:before{content:"\f11a"}.fa.fa-keyboard-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-keyboard-o:before{content:"\f11c"}.fa.fa-flag-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-flag-o:before{content:"\f024"}.fa.fa-mail-reply-all:before{content:"\f122"}.fa.fa-star-half-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-star-half-o:before{content:"\f5c0"}.fa.fa-star-half-empty{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-star-half-empty:before{content:"\f5c0"}.fa.fa-star-half-full{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-star-half-full:before{content:"\f5c0"}.fa.fa-code-fork:before{content:"\f126"}.fa.fa-chain-broken:before,.fa.fa-unlink:before{content:"\f127"}.fa.fa-calendar-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-calendar-o:before{content:"\f133"}.fa.fa-css3,.fa.fa-html5,.fa.fa-maxcdn{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-unlock-alt:before{content:"\f09c"}.fa.fa-minus-square-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-minus-square-o:before{content:"\f146"}.fa.fa-level-up:before{content:"\f3bf"}.fa.fa-level-down:before{content:"\f3be"}.fa.fa-pencil-square:before{content:"\f14b"}.fa.fa-external-link-square:before{content:"\f360"}.fa.fa-compass{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-caret-square-o-down{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-caret-square-o-down:before{content:"\f150"}.fa.fa-toggle-down{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-toggle-down:before{content:"\f150"}.fa.fa-caret-square-o-up{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-caret-square-o-up:before{content:"\f151"}.fa.fa-toggle-up{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-toggle-up:before{content:"\f151"}.fa.fa-caret-square-o-right{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-caret-square-o-right:before{content:"\f152"}.fa.fa-toggle-right{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-toggle-right:before{content:"\f152"}.fa.fa-eur:before,.fa.fa-euro:before{content:"\f153"}.fa.fa-gbp:before{content:"\f154"}.fa.fa-dollar:before,.fa.fa-usd:before{content:"\24"}.fa.fa-inr:before,.fa.fa-rupee:before{content:"\e1bc"}.fa.fa-cny:before,.fa.fa-jpy:before,.fa.fa-rmb:before,.fa.fa-yen:before{content:"\f157"}.fa.fa-rouble:before,.fa.fa-rub:before,.fa.fa-ruble:before{content:"\f158"}.fa.fa-krw:before,.fa.fa-won:before{content:"\f159"}.fa.fa-bitcoin,.fa.fa-btc{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-bitcoin:before{content:"\f15a"}.fa.fa-file-text:before{content:"\f15c"}.fa.fa-sort-alpha-asc:before{content:"\f15d"}.fa.fa-sort-alpha-desc:before{content:"\f881"}.fa.fa-sort-amount-asc:before{content:"\f884"}.fa.fa-sort-amount-desc:before{content:"\f160"}.fa.fa-sort-numeric-asc:before{content:"\f162"}.fa.fa-sort-numeric-desc:before{content:"\f886"}.fa.fa-youtube-square{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-youtube-square:before{content:"\f431"}.fa.fa-xing,.fa.fa-xing-square,.fa.fa-youtube{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-xing-square:before{content:"\f169"}.fa.fa-youtube-play{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-youtube-play:before{content:"\f167"}.fa.fa-adn,.fa.fa-bitbucket,.fa.fa-bitbucket-square,.fa.fa-dropbox,.fa.fa-flickr,.fa.fa-instagram,.fa.fa-stack-overflow{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-bitbucket-square:before{content:"\f171"}.fa.fa-tumblr,.fa.fa-tumblr-square{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-tumblr-square:before{content:"\f174"}.fa.fa-long-arrow-down:before{content:"\f309"}.fa.fa-long-arrow-up:before{content:"\f30c"}.fa.fa-long-arrow-left:before{content:"\f30a"}.fa.fa-long-arrow-right:before{content:"\f30b"}.fa.fa-android,.fa.fa-apple,.fa.fa-dribbble,.fa.fa-foursquare,.fa.fa-gittip,.fa.fa-gratipay,.fa.fa-linux,.fa.fa-skype,.fa.fa-trello,.fa.fa-windows{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-gittip:before{content:"\f184"}.fa.fa-sun-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-sun-o:before{content:"\f185"}.fa.fa-moon-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-moon-o:before{content:"\f186"}.fa.fa-pagelines,.fa.fa-renren,.fa.fa-stack-exchange,.fa.fa-vk,.fa.fa-weibo{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-arrow-circle-o-right{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-arrow-circle-o-right:before{content:"\f35a"}.fa.fa-arrow-circle-o-left{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-arrow-circle-o-left:before{content:"\f359"}.fa.fa-caret-square-o-left{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-caret-square-o-left:before{content:"\f191"}.fa.fa-toggle-left{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-toggle-left:before{content:"\f191"}.fa.fa-dot-circle-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-dot-circle-o:before{content:"\f192"}.fa.fa-vimeo-square{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-vimeo-square:before{content:"\f194"}.fa.fa-try:before,.fa.fa-turkish-lira:before{content:"\e2bb"}.fa.fa-plus-square-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-plus-square-o:before{content:"\f0fe"}.fa.fa-openid,.fa.fa-slack,.fa.fa-wordpress{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-bank:before,.fa.fa-institution:before{content:"\f19c"}.fa.fa-mortar-board:before{content:"\f19d"}.fa.fa-google,.fa.fa-reddit,.fa.fa-reddit-square,.fa.fa-yahoo{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-reddit-square:before{content:"\f1a2"}.fa.fa-behance,.fa.fa-behance-square,.fa.fa-delicious,.fa.fa-digg,.fa.fa-drupal,.fa.fa-joomla,.fa.fa-pied-piper-alt,.fa.fa-pied-piper-pp,.fa.fa-stumbleupon,.fa.fa-stumbleupon-circle{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-behance-square:before{content:"\f1b5"}.fa.fa-steam,.fa.fa-steam-square{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-steam-square:before{content:"\f1b7"}.fa.fa-automobile:before{content:"\f1b9"}.fa.fa-cab:before{content:"\f1ba"}.fa.fa-deviantart,.fa.fa-soundcloud,.fa.fa-spotify{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-file-pdf-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-pdf-o:before{content:"\f1c1"}.fa.fa-file-word-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-word-o:before{content:"\f1c2"}.fa.fa-file-excel-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-excel-o:before{content:"\f1c3"}.fa.fa-file-powerpoint-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-powerpoint-o:before{content:"\f1c4"}.fa.fa-file-image-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-image-o:before{content:"\f1c5"}.fa.fa-file-photo-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-photo-o:before{content:"\f1c5"}.fa.fa-file-picture-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-picture-o:before{content:"\f1c5"}.fa.fa-file-archive-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-archive-o:before{content:"\f1c6"}.fa.fa-file-zip-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-zip-o:before{content:"\f1c6"}.fa.fa-file-audio-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-audio-o:before{content:"\f1c7"}.fa.fa-file-sound-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-sound-o:before{content:"\f1c7"}.fa.fa-file-video-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-video-o:before{content:"\f1c8"}.fa.fa-file-movie-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-movie-o:before{content:"\f1c8"}.fa.fa-file-code-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-code-o:before{content:"\f1c9"}.fa.fa-codepen,.fa.fa-jsfiddle,.fa.fa-vine{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-life-bouy:before,.fa.fa-life-buoy:before,.fa.fa-life-saver:before,.fa.fa-support:before{content:"\f1cd"}.fa.fa-circle-o-notch:before{content:"\f1ce"}.fa.fa-ra,.fa.fa-rebel{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-ra:before{content:"\f1d0"}.fa.fa-resistance{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-resistance:before{content:"\f1d0"}.fa.fa-empire,.fa.fa-ge{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-ge:before{content:"\f1d1"}.fa.fa-git-square{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-git-square:before{content:"\f1d2"}.fa.fa-git,.fa.fa-hacker-news,.fa.fa-y-combinator-square{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-y-combinator-square:before{content:"\f1d4"}.fa.fa-yc-square{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-yc-square:before{content:"\f1d4"}.fa.fa-qq,.fa.fa-tencent-weibo,.fa.fa-wechat,.fa.fa-weixin{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-wechat:before{content:"\f1d7"}.fa.fa-send:before{content:"\f1d8"}.fa.fa-paper-plane-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-paper-plane-o:before{content:"\f1d8"}.fa.fa-send-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-send-o:before{content:"\f1d8"}.fa.fa-circle-thin{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-circle-thin:before{content:"\f111"}.fa.fa-header:before{content:"\f1dc"}.fa.fa-futbol-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-futbol-o:before{content:"\f1e3"}.fa.fa-soccer-ball-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-soccer-ball-o:before{content:"\f1e3"}.fa.fa-slideshare,.fa.fa-twitch,.fa.fa-yelp{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-newspaper-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-newspaper-o:before{content:"\f1ea"}.fa.fa-cc-amex,.fa.fa-cc-discover,.fa.fa-cc-mastercard,.fa.fa-cc-paypal,.fa.fa-cc-stripe,.fa.fa-cc-visa,.fa.fa-google-wallet,.fa.fa-paypal{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-bell-slash-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-bell-slash-o:before{content:"\f1f6"}.fa.fa-trash:before{content:"\f2ed"}.fa.fa-copyright{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-eyedropper:before{content:"\f1fb"}.fa.fa-area-chart:before{content:"\f1fe"}.fa.fa-pie-chart:before{content:"\f200"}.fa.fa-line-chart:before{content:"\f201"}.fa.fa-lastfm,.fa.fa-lastfm-square{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-lastfm-square:before{content:"\f203"}.fa.fa-angellist,.fa.fa-ioxhost{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-cc{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-cc:before{content:"\f20a"}.fa.fa-ils:before,.fa.fa-shekel:before,.fa.fa-sheqel:before{content:"\f20b"}.fa.fa-buysellads,.fa.fa-connectdevelop,.fa.fa-dashcube,.fa.fa-forumbee,.fa.fa-leanpub,.fa.fa-sellsy,.fa.fa-shirtsinbulk,.fa.fa-simplybuilt,.fa.fa-skyatlas{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-diamond{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-diamond:before{content:"\f3a5"}.fa.fa-intersex:before,.fa.fa-transgender:before{content:"\f224"}.fa.fa-transgender-alt:before{content:"\f225"}.fa.fa-facebook-official{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-facebook-official:before{content:"\f09a"}.fa.fa-pinterest-p,.fa.fa-whatsapp{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-hotel:before{content:"\f236"}.fa.fa-medium,.fa.fa-viacoin,.fa.fa-y-combinator,.fa.fa-yc{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-yc:before{content:"\f23b"}.fa.fa-expeditedssl,.fa.fa-opencart,.fa.fa-optin-monster{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-battery-4:before,.fa.fa-battery:before{content:"\f240"}.fa.fa-battery-3:before{content:"\f241"}.fa.fa-battery-2:before{content:"\f242"}.fa.fa-battery-1:before{content:"\f243"}.fa.fa-battery-0:before{content:"\f244"}.fa.fa-object-group,.fa.fa-object-ungroup,.fa.fa-sticky-note-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-sticky-note-o:before{content:"\f249"}.fa.fa-cc-diners-club,.fa.fa-cc-jcb{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-clone{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hourglass-o:before{content:"\f254"}.fa.fa-hourglass-1:before{content:"\f251"}.fa.fa-hourglass-2:before{content:"\f252"}.fa.fa-hourglass-3:before{content:"\f253"}.fa.fa-hand-rock-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hand-rock-o:before{content:"\f255"}.fa.fa-hand-grab-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hand-grab-o:before{content:"\f255"}.fa.fa-hand-paper-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hand-paper-o:before{content:"\f256"}.fa.fa-hand-stop-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hand-stop-o:before{content:"\f256"}.fa.fa-hand-scissors-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hand-scissors-o:before{content:"\f257"}.fa.fa-hand-lizard-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hand-lizard-o:before{content:"\f258"}.fa.fa-hand-spock-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hand-spock-o:before{content:"\f259"}.fa.fa-hand-pointer-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hand-pointer-o:before{content:"\f25a"}.fa.fa-hand-peace-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hand-peace-o:before{content:"\f25b"}.fa.fa-registered{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-creative-commons,.fa.fa-gg,.fa.fa-gg-circle,.fa.fa-odnoklassniki,.fa.fa-odnoklassniki-square{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-odnoklassniki-square:before{content:"\f264"}.fa.fa-chrome,.fa.fa-firefox,.fa.fa-get-pocket,.fa.fa-internet-explorer,.fa.fa-opera,.fa.fa-safari,.fa.fa-wikipedia-w{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-television:before{content:"\f26c"}.fa.fa-500px,.fa.fa-amazon,.fa.fa-contao{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-calendar-plus-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-calendar-plus-o:before{content:"\f271"}.fa.fa-calendar-minus-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-calendar-minus-o:before{content:"\f272"}.fa.fa-calendar-times-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-calendar-times-o:before{content:"\f273"}.fa.fa-calendar-check-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-calendar-check-o:before{content:"\f274"}.fa.fa-map-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-map-o:before{content:"\f279"}.fa.fa-commenting:before{content:"\f4ad"}.fa.fa-commenting-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-commenting-o:before{content:"\f4ad"}.fa.fa-houzz,.fa.fa-vimeo{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-vimeo:before{content:"\f27d"}.fa.fa-black-tie,.fa.fa-edge,.fa.fa-fonticons,.fa.fa-reddit-alien{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-credit-card-alt:before{content:"\f09d"}.fa.fa-codiepie,.fa.fa-fort-awesome,.fa.fa-mixcloud,.fa.fa-modx,.fa.fa-product-hunt,.fa.fa-scribd,.fa.fa-usb{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-pause-circle-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-pause-circle-o:before{content:"\f28b"}.fa.fa-stop-circle-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-stop-circle-o:before{content:"\f28d"}.fa.fa-bluetooth,.fa.fa-bluetooth-b,.fa.fa-envira,.fa.fa-gitlab,.fa.fa-wheelchair-alt,.fa.fa-wpbeginner,.fa.fa-wpforms{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-wheelchair-alt:before{content:"\f368"}.fa.fa-question-circle-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-question-circle-o:before{content:"\f059"}.fa.fa-volume-control-phone:before{content:"\f2a0"}.fa.fa-asl-interpreting:before{content:"\f2a3"}.fa.fa-deafness:before,.fa.fa-hard-of-hearing:before{content:"\f2a4"}.fa.fa-glide,.fa.fa-glide-g{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-signing:before{content:"\f2a7"}.fa.fa-viadeo,.fa.fa-viadeo-square{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-viadeo-square:before{content:"\f2aa"}.fa.fa-snapchat,.fa.fa-snapchat-ghost{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-snapchat-ghost:before{content:"\f2ab"}.fa.fa-snapchat-square{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-snapchat-square:before{content:"\f2ad"}.fa.fa-first-order,.fa.fa-google-plus-official,.fa.fa-pied-piper,.fa.fa-themeisle,.fa.fa-yoast{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-google-plus-official:before{content:"\f2b3"}.fa.fa-google-plus-circle{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-google-plus-circle:before{content:"\f2b3"}.fa.fa-fa,.fa.fa-font-awesome{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-fa:before{content:"\f2b4"}.fa.fa-handshake-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-handshake-o:before{content:"\f2b5"}.fa.fa-envelope-open-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-envelope-open-o:before{content:"\f2b6"}.fa.fa-linode{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-address-book-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-address-book-o:before{content:"\f2b9"}.fa.fa-vcard:before{content:"\f2bb"}.fa.fa-address-card-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-address-card-o:before{content:"\f2bb"}.fa.fa-vcard-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-vcard-o:before{content:"\f2bb"}.fa.fa-user-circle-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-user-circle-o:before{content:"\f2bd"}.fa.fa-user-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-user-o:before{content:"\f007"}.fa.fa-id-badge{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-drivers-license:before{content:"\f2c2"}.fa.fa-id-card-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-id-card-o:before{content:"\f2c2"}.fa.fa-drivers-license-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-drivers-license-o:before{content:"\f2c2"}.fa.fa-free-code-camp,.fa.fa-quora,.fa.fa-telegram{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-thermometer-4:before,.fa.fa-thermometer:before{content:"\f2c7"}.fa.fa-thermometer-3:before{content:"\f2c8"}.fa.fa-thermometer-2:before{content:"\f2c9"}.fa.fa-thermometer-1:before{content:"\f2ca"}.fa.fa-thermometer-0:before{content:"\f2cb"}.fa.fa-bathtub:before,.fa.fa-s15:before{content:"\f2cd"}.fa.fa-window-maximize,.fa.fa-window-restore{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-times-rectangle:before{content:"\f410"}.fa.fa-window-close-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-window-close-o:before{content:"\f410"}.fa.fa-times-rectangle-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-times-rectangle-o:before{content:"\f410"}.fa.fa-bandcamp,.fa.fa-eercast,.fa.fa-etsy,.fa.fa-grav,.fa.fa-imdb,.fa.fa-ravelry{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-eercast:before{content:"\f2da"}.fa.fa-snowflake-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-snowflake-o:before{content:"\f2dc"}.fa.fa-meetup,.fa.fa-superpowers,.fa.fa-wpexplorer{font-family:"Font Awesome 6 Brands";font-weight:400} \ No newline at end of file +.fa.fa-glass:before{content:"\f000"}.fa.fa-meetup{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-star-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-star-o:before{content:"\f005"}.fa.fa-close:before,.fa.fa-remove:before{content:"\f00d"}.fa.fa-gear:before{content:"\f013"}.fa.fa-trash-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-trash-o:before{content:"\f2ed"}.fa.fa-file-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-o:before{content:"\f15b"}.fa.fa-clock-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-clock-o:before{content:"\f017"}.fa.fa-arrow-circle-o-down{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-arrow-circle-o-down:before{content:"\f358"}.fa.fa-arrow-circle-o-up{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-arrow-circle-o-up:before{content:"\f35b"}.fa.fa-play-circle-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-play-circle-o:before{content:"\f144"}.fa.fa-repeat:before,.fa.fa-rotate-right:before{content:"\f01e"}.fa.fa-refresh:before{content:"\f021"}.fa.fa-list-alt{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-dedent:before{content:"\f03b"}.fa.fa-video-camera:before{content:"\f03d"}.fa.fa-picture-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-picture-o:before{content:"\f03e"}.fa.fa-photo{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-photo:before{content:"\f03e"}.fa.fa-image{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-image:before{content:"\f03e"}.fa.fa-pencil:before{content:"\f303"}.fa.fa-map-marker:before{content:"\f3c5"}.fa.fa-pencil-square-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-pencil-square-o:before{content:"\f044"}.fa.fa-share-square-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-share-square-o:before{content:"\f14d"}.fa.fa-check-square-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-check-square-o:before{content:"\f14a"}.fa.fa-arrows:before{content:"\f0b2"}.fa.fa-times-circle-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-times-circle-o:before{content:"\f057"}.fa.fa-check-circle-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-check-circle-o:before{content:"\f058"}.fa.fa-mail-forward:before{content:"\f064"}.fa.fa-expand:before{content:"\f424"}.fa.fa-compress:before{content:"\f422"}.fa.fa-eye,.fa.fa-eye-slash{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-warning:before{content:"\f071"}.fa.fa-calendar:before{content:"\f073"}.fa.fa-arrows-v:before{content:"\f338"}.fa.fa-arrows-h:before{content:"\f337"}.fa.fa-bar-chart{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-bar-chart:before{content:"\f080"}.fa.fa-bar-chart-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-bar-chart-o:before{content:"\f080"}.fa.fa-facebook-square,.fa.fa-twitter-square{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-gears:before{content:"\f085"}.fa.fa-thumbs-o-up{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-thumbs-o-up:before{content:"\f164"}.fa.fa-thumbs-o-down{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-thumbs-o-down:before{content:"\f165"}.fa.fa-heart-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-heart-o:before{content:"\f004"}.fa.fa-sign-out:before{content:"\f2f5"}.fa.fa-linkedin-square{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-linkedin-square:before{content:"\f08c"}.fa.fa-thumb-tack:before{content:"\f08d"}.fa.fa-external-link:before{content:"\f35d"}.fa.fa-sign-in:before{content:"\f2f6"}.fa.fa-github-square{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-lemon-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-lemon-o:before{content:"\f094"}.fa.fa-square-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-square-o:before{content:"\f0c8"}.fa.fa-bookmark-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-bookmark-o:before{content:"\f02e"}.fa.fa-facebook,.fa.fa-twitter{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-facebook:before{content:"\f39e"}.fa.fa-facebook-f{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-facebook-f:before{content:"\f39e"}.fa.fa-github{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-credit-card{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-feed:before{content:"\f09e"}.fa.fa-hdd-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hdd-o:before{content:"\f0a0"}.fa.fa-hand-o-right{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-o-right:before{content:"\f0a4"}.fa.fa-hand-o-left{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-o-left:before{content:"\f0a5"}.fa.fa-hand-o-up{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-o-up:before{content:"\f0a6"}.fa.fa-hand-o-down{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-o-down:before{content:"\f0a7"}.fa.fa-arrows-alt:before{content:"\f31e"}.fa.fa-group:before{content:"\f0c0"}.fa.fa-chain:before{content:"\f0c1"}.fa.fa-scissors:before{content:"\f0c4"}.fa.fa-files-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-files-o:before{content:"\f0c5"}.fa.fa-floppy-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-floppy-o:before{content:"\f0c7"}.fa.fa-navicon:before,.fa.fa-reorder:before{content:"\f0c9"}.fa.fa-google-plus,.fa.fa-google-plus-square,.fa.fa-pinterest,.fa.fa-pinterest-square{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-google-plus:before{content:"\f0d5"}.fa.fa-money{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-money:before{content:"\f3d1"}.fa.fa-unsorted:before{content:"\f0dc"}.fa.fa-sort-desc:before{content:"\f0dd"}.fa.fa-sort-asc:before{content:"\f0de"}.fa.fa-linkedin{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-linkedin:before{content:"\f0e1"}.fa.fa-rotate-left:before{content:"\f0e2"}.fa.fa-legal:before{content:"\f0e3"}.fa.fa-dashboard:before,.fa.fa-tachometer:before{content:"\f3fd"}.fa.fa-comment-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-comment-o:before{content:"\f075"}.fa.fa-comments-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-comments-o:before{content:"\f086"}.fa.fa-flash:before{content:"\f0e7"}.fa.fa-clipboard,.fa.fa-paste{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-paste:before{content:"\f328"}.fa.fa-lightbulb-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-lightbulb-o:before{content:"\f0eb"}.fa.fa-exchange:before{content:"\f362"}.fa.fa-cloud-download:before{content:"\f381"}.fa.fa-cloud-upload:before{content:"\f382"}.fa.fa-bell-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-bell-o:before{content:"\f0f3"}.fa.fa-cutlery:before{content:"\f2e7"}.fa.fa-file-text-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-text-o:before{content:"\f15c"}.fa.fa-building-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-building-o:before{content:"\f1ad"}.fa.fa-hospital-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hospital-o:before{content:"\f0f8"}.fa.fa-tablet:before{content:"\f3fa"}.fa.fa-mobile-phone:before,.fa.fa-mobile:before{content:"\f3cd"}.fa.fa-circle-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-circle-o:before{content:"\f111"}.fa.fa-mail-reply:before{content:"\f3e5"}.fa.fa-github-alt{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-folder-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-folder-o:before{content:"\f07b"}.fa.fa-folder-open-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-folder-open-o:before{content:"\f07c"}.fa.fa-smile-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-smile-o:before{content:"\f118"}.fa.fa-frown-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-frown-o:before{content:"\f119"}.fa.fa-meh-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-meh-o:before{content:"\f11a"}.fa.fa-keyboard-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-keyboard-o:before{content:"\f11c"}.fa.fa-flag-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-flag-o:before{content:"\f024"}.fa.fa-mail-reply-all:before{content:"\f122"}.fa.fa-star-half-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-star-half-o:before{content:"\f089"}.fa.fa-star-half-empty{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-star-half-empty:before{content:"\f089"}.fa.fa-star-half-full{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-star-half-full:before{content:"\f089"}.fa.fa-code-fork:before{content:"\f126"}.fa.fa-chain-broken:before{content:"\f127"}.fa.fa-shield:before{content:"\f3ed"}.fa.fa-calendar-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-calendar-o:before{content:"\f133"}.fa.fa-css3,.fa.fa-html5,.fa.fa-maxcdn{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-ticket:before{content:"\f3ff"}.fa.fa-minus-square-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-minus-square-o:before{content:"\f146"}.fa.fa-level-up:before{content:"\f3bf"}.fa.fa-level-down:before{content:"\f3be"}.fa.fa-pencil-square:before{content:"\f14b"}.fa.fa-external-link-square:before{content:"\f360"}.fa.fa-compass{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-caret-square-o-down{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-caret-square-o-down:before{content:"\f150"}.fa.fa-toggle-down{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-toggle-down:before{content:"\f150"}.fa.fa-caret-square-o-up{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-caret-square-o-up:before{content:"\f151"}.fa.fa-toggle-up{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-toggle-up:before{content:"\f151"}.fa.fa-caret-square-o-right{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-caret-square-o-right:before{content:"\f152"}.fa.fa-toggle-right{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-toggle-right:before{content:"\f152"}.fa.fa-eur:before,.fa.fa-euro:before{content:"\f153"}.fa.fa-gbp:before{content:"\f154"}.fa.fa-dollar:before,.fa.fa-usd:before{content:"\f155"}.fa.fa-inr:before,.fa.fa-rupee:before{content:"\f156"}.fa.fa-cny:before,.fa.fa-jpy:before,.fa.fa-rmb:before,.fa.fa-yen:before{content:"\f157"}.fa.fa-rouble:before,.fa.fa-rub:before,.fa.fa-ruble:before{content:"\f158"}.fa.fa-krw:before,.fa.fa-won:before{content:"\f159"}.fa.fa-bitcoin,.fa.fa-btc{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-bitcoin:before{content:"\f15a"}.fa.fa-file-text:before{content:"\f15c"}.fa.fa-sort-alpha-asc:before{content:"\f15d"}.fa.fa-sort-alpha-desc:before{content:"\f881"}.fa.fa-sort-amount-asc:before{content:"\f160"}.fa.fa-sort-amount-desc:before{content:"\f884"}.fa.fa-sort-numeric-asc:before{content:"\f162"}.fa.fa-sort-numeric-desc:before{content:"\f886"}.fa.fa-xing,.fa.fa-xing-square,.fa.fa-youtube,.fa.fa-youtube-play,.fa.fa-youtube-square{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-youtube-play:before{content:"\f167"}.fa.fa-adn,.fa.fa-bitbucket,.fa.fa-bitbucket-square,.fa.fa-dropbox,.fa.fa-flickr,.fa.fa-instagram,.fa.fa-stack-overflow{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-bitbucket-square:before{content:"\f171"}.fa.fa-tumblr,.fa.fa-tumblr-square{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-long-arrow-down:before{content:"\f309"}.fa.fa-long-arrow-up:before{content:"\f30c"}.fa.fa-long-arrow-left:before{content:"\f30a"}.fa.fa-long-arrow-right:before{content:"\f30b"}.fa.fa-android,.fa.fa-apple,.fa.fa-dribbble,.fa.fa-foursquare,.fa.fa-gittip,.fa.fa-gratipay,.fa.fa-linux,.fa.fa-skype,.fa.fa-trello,.fa.fa-windows{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-gittip:before{content:"\f184"}.fa.fa-sun-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-sun-o:before{content:"\f185"}.fa.fa-moon-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-moon-o:before{content:"\f186"}.fa.fa-pagelines,.fa.fa-renren,.fa.fa-stack-exchange,.fa.fa-vk,.fa.fa-weibo{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-arrow-circle-o-right{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-arrow-circle-o-right:before{content:"\f35a"}.fa.fa-arrow-circle-o-left{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-arrow-circle-o-left:before{content:"\f359"}.fa.fa-caret-square-o-left{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-caret-square-o-left:before{content:"\f191"}.fa.fa-toggle-left{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-toggle-left:before{content:"\f191"}.fa.fa-dot-circle-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-dot-circle-o:before{content:"\f192"}.fa.fa-vimeo-square{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-try:before,.fa.fa-turkish-lira:before{content:"\f195"}.fa.fa-plus-square-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-plus-square-o:before{content:"\f0fe"}.fa.fa-openid,.fa.fa-slack,.fa.fa-wordpress{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-bank:before,.fa.fa-institution:before{content:"\f19c"}.fa.fa-mortar-board:before{content:"\f19d"}.fa.fa-delicious,.fa.fa-digg,.fa.fa-drupal,.fa.fa-google,.fa.fa-joomla,.fa.fa-pied-piper-alt,.fa.fa-pied-piper-pp,.fa.fa-reddit,.fa.fa-reddit-square,.fa.fa-stumbleupon,.fa.fa-stumbleupon-circle,.fa.fa-yahoo{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-spoon:before{content:"\f2e5"}.fa.fa-behance,.fa.fa-behance-square,.fa.fa-steam,.fa.fa-steam-square{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-automobile:before{content:"\f1b9"}.fa.fa-envelope-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-envelope-o:before{content:"\f0e0"}.fa.fa-deviantart,.fa.fa-soundcloud,.fa.fa-spotify{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-file-pdf-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-pdf-o:before{content:"\f1c1"}.fa.fa-file-word-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-word-o:before{content:"\f1c2"}.fa.fa-file-excel-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-excel-o:before{content:"\f1c3"}.fa.fa-file-powerpoint-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-powerpoint-o:before{content:"\f1c4"}.fa.fa-file-image-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-image-o:before{content:"\f1c5"}.fa.fa-file-photo-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-photo-o:before{content:"\f1c5"}.fa.fa-file-picture-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-picture-o:before{content:"\f1c5"}.fa.fa-file-archive-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-archive-o:before{content:"\f1c6"}.fa.fa-file-zip-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-zip-o:before{content:"\f1c6"}.fa.fa-file-audio-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-audio-o:before{content:"\f1c7"}.fa.fa-file-sound-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-sound-o:before{content:"\f1c7"}.fa.fa-file-video-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-video-o:before{content:"\f1c8"}.fa.fa-file-movie-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-movie-o:before{content:"\f1c8"}.fa.fa-file-code-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-code-o:before{content:"\f1c9"}.fa.fa-codepen,.fa.fa-jsfiddle,.fa.fa-vine{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-life-bouy,.fa.fa-life-ring{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-life-bouy:before{content:"\f1cd"}.fa.fa-life-buoy{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-life-buoy:before{content:"\f1cd"}.fa.fa-life-saver{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-life-saver:before{content:"\f1cd"}.fa.fa-support{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-support:before{content:"\f1cd"}.fa.fa-circle-o-notch:before{content:"\f1ce"}.fa.fa-ra,.fa.fa-rebel{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-ra:before{content:"\f1d0"}.fa.fa-resistance{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-resistance:before{content:"\f1d0"}.fa.fa-empire,.fa.fa-ge{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-ge:before{content:"\f1d1"}.fa.fa-git,.fa.fa-git-square,.fa.fa-hacker-news,.fa.fa-y-combinator-square{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-y-combinator-square:before{content:"\f1d4"}.fa.fa-yc-square{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-yc-square:before{content:"\f1d4"}.fa.fa-qq,.fa.fa-tencent-weibo,.fa.fa-wechat,.fa.fa-weixin{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-wechat:before{content:"\f1d7"}.fa.fa-send:before{content:"\f1d8"}.fa.fa-paper-plane-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-paper-plane-o:before{content:"\f1d8"}.fa.fa-send-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-send-o:before{content:"\f1d8"}.fa.fa-circle-thin{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-circle-thin:before{content:"\f111"}.fa.fa-header:before{content:"\f1dc"}.fa.fa-sliders:before{content:"\f1de"}.fa.fa-futbol-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-futbol-o:before{content:"\f1e3"}.fa.fa-soccer-ball-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-soccer-ball-o:before{content:"\f1e3"}.fa.fa-slideshare,.fa.fa-twitch,.fa.fa-yelp{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-newspaper-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-newspaper-o:before{content:"\f1ea"}.fa.fa-cc-amex,.fa.fa-cc-discover,.fa.fa-cc-mastercard,.fa.fa-cc-paypal,.fa.fa-cc-stripe,.fa.fa-cc-visa,.fa.fa-google-wallet,.fa.fa-paypal{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-bell-slash-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-bell-slash-o:before{content:"\f1f6"}.fa.fa-trash:before{content:"\f2ed"}.fa.fa-copyright{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-eyedropper:before{content:"\f1fb"}.fa.fa-area-chart:before{content:"\f1fe"}.fa.fa-pie-chart:before{content:"\f200"}.fa.fa-line-chart:before{content:"\f201"}.fa.fa-angellist,.fa.fa-ioxhost,.fa.fa-lastfm,.fa.fa-lastfm-square{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-cc{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-cc:before{content:"\f20a"}.fa.fa-ils:before,.fa.fa-shekel:before,.fa.fa-sheqel:before{content:"\f20b"}.fa.fa-meanpath{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-meanpath:before{content:"\f2b4"}.fa.fa-buysellads,.fa.fa-connectdevelop,.fa.fa-dashcube,.fa.fa-forumbee,.fa.fa-leanpub,.fa.fa-sellsy,.fa.fa-shirtsinbulk,.fa.fa-simplybuilt,.fa.fa-skyatlas{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-diamond{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-diamond:before{content:"\f3a5"}.fa.fa-intersex:before{content:"\f224"}.fa.fa-facebook-official{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-facebook-official:before{content:"\f09a"}.fa.fa-pinterest-p,.fa.fa-whatsapp{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-hotel:before{content:"\f236"}.fa.fa-medium,.fa.fa-viacoin,.fa.fa-y-combinator,.fa.fa-yc{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-yc:before{content:"\f23b"}.fa.fa-expeditedssl,.fa.fa-opencart,.fa.fa-optin-monster{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-battery-4:before,.fa.fa-battery:before{content:"\f240"}.fa.fa-battery-3:before{content:"\f241"}.fa.fa-battery-2:before{content:"\f242"}.fa.fa-battery-1:before{content:"\f243"}.fa.fa-battery-0:before{content:"\f244"}.fa.fa-object-group,.fa.fa-object-ungroup,.fa.fa-sticky-note-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-sticky-note-o:before{content:"\f249"}.fa.fa-cc-diners-club,.fa.fa-cc-jcb{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-clone,.fa.fa-hourglass-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hourglass-o:before{content:"\f254"}.fa.fa-hourglass-1:before{content:"\f251"}.fa.fa-hourglass-2:before{content:"\f252"}.fa.fa-hourglass-3:before{content:"\f253"}.fa.fa-hand-rock-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-rock-o:before{content:"\f255"}.fa.fa-hand-grab-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-grab-o:before{content:"\f255"}.fa.fa-hand-paper-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-paper-o:before{content:"\f256"}.fa.fa-hand-stop-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-stop-o:before{content:"\f256"}.fa.fa-hand-scissors-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-scissors-o:before{content:"\f257"}.fa.fa-hand-lizard-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-lizard-o:before{content:"\f258"}.fa.fa-hand-spock-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-spock-o:before{content:"\f259"}.fa.fa-hand-pointer-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-pointer-o:before{content:"\f25a"}.fa.fa-hand-peace-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-peace-o:before{content:"\f25b"}.fa.fa-registered{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-chrome,.fa.fa-creative-commons,.fa.fa-firefox,.fa.fa-get-pocket,.fa.fa-gg,.fa.fa-gg-circle,.fa.fa-internet-explorer,.fa.fa-odnoklassniki,.fa.fa-odnoklassniki-square,.fa.fa-opera,.fa.fa-safari,.fa.fa-tripadvisor,.fa.fa-wikipedia-w{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-television:before{content:"\f26c"}.fa.fa-500px,.fa.fa-amazon,.fa.fa-contao{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-calendar-plus-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-calendar-plus-o:before{content:"\f271"}.fa.fa-calendar-minus-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-calendar-minus-o:before{content:"\f272"}.fa.fa-calendar-times-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-calendar-times-o:before{content:"\f273"}.fa.fa-calendar-check-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-calendar-check-o:before{content:"\f274"}.fa.fa-map-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-map-o:before{content:"\f279"}.fa.fa-commenting:before{content:"\f4ad"}.fa.fa-commenting-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-commenting-o:before{content:"\f4ad"}.fa.fa-houzz,.fa.fa-vimeo{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-vimeo:before{content:"\f27d"}.fa.fa-black-tie,.fa.fa-edge,.fa.fa-fonticons,.fa.fa-reddit-alien{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-credit-card-alt:before{content:"\f09d"}.fa.fa-codiepie,.fa.fa-fort-awesome,.fa.fa-mixcloud,.fa.fa-modx,.fa.fa-product-hunt,.fa.fa-scribd,.fa.fa-usb{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-pause-circle-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-pause-circle-o:before{content:"\f28b"}.fa.fa-stop-circle-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-stop-circle-o:before{content:"\f28d"}.fa.fa-bluetooth,.fa.fa-bluetooth-b,.fa.fa-envira,.fa.fa-gitlab,.fa.fa-wheelchair-alt,.fa.fa-wpbeginner,.fa.fa-wpforms{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-wheelchair-alt:before{content:"\f368"}.fa.fa-question-circle-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-question-circle-o:before{content:"\f059"}.fa.fa-volume-control-phone:before{content:"\f2a0"}.fa.fa-asl-interpreting:before{content:"\f2a3"}.fa.fa-deafness:before,.fa.fa-hard-of-hearing:before{content:"\f2a4"}.fa.fa-glide,.fa.fa-glide-g{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-signing:before{content:"\f2a7"}.fa.fa-first-order,.fa.fa-google-plus-official,.fa.fa-pied-piper,.fa.fa-snapchat,.fa.fa-snapchat-ghost,.fa.fa-snapchat-square,.fa.fa-themeisle,.fa.fa-viadeo,.fa.fa-viadeo-square,.fa.fa-yoast{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-google-plus-official:before{content:"\f2b3"}.fa.fa-google-plus-circle{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-google-plus-circle:before{content:"\f2b3"}.fa.fa-fa,.fa.fa-font-awesome{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-fa:before{content:"\f2b4"}.fa.fa-handshake-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-handshake-o:before{content:"\f2b5"}.fa.fa-envelope-open-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-envelope-open-o:before{content:"\f2b6"}.fa.fa-linode{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-address-book-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-address-book-o:before{content:"\f2b9"}.fa.fa-vcard:before{content:"\f2bb"}.fa.fa-address-card-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-address-card-o:before{content:"\f2bb"}.fa.fa-vcard-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-vcard-o:before{content:"\f2bb"}.fa.fa-user-circle-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-user-circle-o:before{content:"\f2bd"}.fa.fa-user-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-user-o:before{content:"\f007"}.fa.fa-id-badge{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-drivers-license:before{content:"\f2c2"}.fa.fa-id-card-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-id-card-o:before{content:"\f2c2"}.fa.fa-drivers-license-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-drivers-license-o:before{content:"\f2c2"}.fa.fa-free-code-camp,.fa.fa-quora,.fa.fa-telegram{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-thermometer-4:before,.fa.fa-thermometer:before{content:"\f2c7"}.fa.fa-thermometer-3:before{content:"\f2c8"}.fa.fa-thermometer-2:before{content:"\f2c9"}.fa.fa-thermometer-1:before{content:"\f2ca"}.fa.fa-thermometer-0:before{content:"\f2cb"}.fa.fa-bathtub:before,.fa.fa-s15:before{content:"\f2cd"}.fa.fa-window-maximize,.fa.fa-window-restore{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-times-rectangle:before{content:"\f410"}.fa.fa-window-close-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-window-close-o:before{content:"\f410"}.fa.fa-times-rectangle-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-times-rectangle-o:before{content:"\f410"}.fa.fa-bandcamp,.fa.fa-eercast,.fa.fa-etsy,.fa.fa-grav,.fa.fa-imdb,.fa.fa-ravelry{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-eercast:before{content:"\f2da"}.fa.fa-snowflake-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-snowflake-o:before{content:"\f2dc"}.fa.fa-superpowers,.fa.fa-wpexplorer{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-cab:before{content:"\f1ba"} \ No newline at end of file diff --git a/html/font-awesome/webfonts/fa-regular-400.ttf b/html/font-awesome/webfonts/fa-regular-400.ttf deleted file mode 100644 index c5ac0095777..00000000000 Binary files a/html/font-awesome/webfonts/fa-regular-400.ttf and /dev/null differ diff --git a/html/font-awesome/webfonts/fa-solid-900.ttf b/html/font-awesome/webfonts/fa-solid-900.ttf deleted file mode 100644 index 43ba1cc7d94..00000000000 Binary files a/html/font-awesome/webfonts/fa-solid-900.ttf and /dev/null differ diff --git a/html/font-awesome/webfonts/fa-v4compatibility.ttf b/html/font-awesome/webfonts/fa-v4compatibility.ttf deleted file mode 100644 index 243bc25bd5e..00000000000 Binary files a/html/font-awesome/webfonts/fa-v4compatibility.ttf and /dev/null differ diff --git a/html/jquery/jquery-ui.custom-core-widgit-mouse-sortable.min.js b/html/jquery/jquery-ui.custom-core-widgit-mouse-sortable.min.js deleted file mode 100644 index fe9bba7a51c..00000000000 --- a/html/jquery/jquery-ui.custom-core-widgit-mouse-sortable.min.js +++ /dev/null @@ -1,7 +0,0 @@ -/*! jQuery UI - v1.11.4 - 2016-07-05 -* http://jqueryui.com -* Includes: core.js, widget.js, mouse.js, sortable.js -* Copyright jQuery Foundation and other contributors; Licensed MIT */ - -(function(e){"function"==typeof define&&define.amd?define(["jquery"],e):e(jQuery)})(function(e){function t(t,s){var n,a,o,r=t.nodeName.toLowerCase();return"area"===r?(n=t.parentNode,a=n.name,t.href&&a&&"map"===n.nodeName.toLowerCase()?(o=e("img[usemap='#"+a+"']")[0],!!o&&i(o)):!1):(/^(input|select|textarea|button|object)$/.test(r)?!t.disabled:"a"===r?t.href||s:s)&&i(t)}function i(t){return e.expr.filters.visible(t)&&!e(t).parents().addBack().filter(function(){return"hidden"===e.css(this,"visibility")}).length}e.ui=e.ui||{},e.extend(e.ui,{version:"1.11.4",keyCode:{BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38}}),e.fn.extend({scrollParent:function(t){var i=this.css("position"),s="absolute"===i,n=t?/(auto|scroll|hidden)/:/(auto|scroll)/,a=this.parents().filter(function(){var t=e(this);return s&&"static"===t.css("position")?!1:n.test(t.css("overflow")+t.css("overflow-y")+t.css("overflow-x"))}).eq(0);return"fixed"!==i&&a.length?a:e(this[0].ownerDocument||document)},uniqueId:function(){var e=0;return function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++e)})}}(),removeUniqueId:function(){return this.each(function(){/^ui-id-\d+$/.test(this.id)&&e(this).removeAttr("id")})}}),e.extend(e.expr[":"],{data:e.expr.createPseudo?e.expr.createPseudo(function(t){return function(i){return!!e.data(i,t)}}):function(t,i,s){return!!e.data(t,s[3])},focusable:function(i){return t(i,!isNaN(e.attr(i,"tabindex")))},tabbable:function(i){var s=e.attr(i,"tabindex"),n=isNaN(s);return(n||s>=0)&&t(i,!n)}}),e("").outerWidth(1).jquery||e.each(["Width","Height"],function(t,i){function s(t,i,s,a){return e.each(n,function(){i-=parseFloat(e.css(t,"padding"+this))||0,s&&(i-=parseFloat(e.css(t,"border"+this+"Width"))||0),a&&(i-=parseFloat(e.css(t,"margin"+this))||0)}),i}var n="Width"===i?["Left","Right"]:["Top","Bottom"],a=i.toLowerCase(),o={innerWidth:e.fn.innerWidth,innerHeight:e.fn.innerHeight,outerWidth:e.fn.outerWidth,outerHeight:e.fn.outerHeight};e.fn["inner"+i]=function(t){return void 0===t?o["inner"+i].call(this):this.each(function(){e(this).css(a,s(this,t)+"px")})},e.fn["outer"+i]=function(t,n){return"number"!=typeof t?o["outer"+i].call(this,t):this.each(function(){e(this).css(a,s(this,t,!0,n)+"px")})}}),e.fn.addBack||(e.fn.addBack=function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}),e("").data("a-b","a").removeData("a-b").data("a-b")&&(e.fn.removeData=function(t){return function(i){return arguments.length?t.call(this,e.camelCase(i)):t.call(this)}}(e.fn.removeData)),e.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase()),e.fn.extend({focus:function(t){return function(i,s){return"number"==typeof i?this.each(function(){var t=this;setTimeout(function(){e(t).focus(),s&&s.call(t)},i)}):t.apply(this,arguments)}}(e.fn.focus),disableSelection:function(){var e="onselectstart"in document.createElement("div")?"selectstart":"mousedown";return function(){return this.bind(e+".ui-disableSelection",function(e){e.preventDefault()})}}(),enableSelection:function(){return this.unbind(".ui-disableSelection")},zIndex:function(t){if(void 0!==t)return this.css("zIndex",t);if(this.length)for(var i,s,n=e(this[0]);n.length&&n[0]!==document;){if(i=n.css("position"),("absolute"===i||"relative"===i||"fixed"===i)&&(s=parseInt(n.css("zIndex"),10),!isNaN(s)&&0!==s))return s;n=n.parent()}return 0}}),e.ui.plugin={add:function(t,i,s){var n,a=e.ui[t].prototype;for(n in s)a.plugins[n]=a.plugins[n]||[],a.plugins[n].push([i,s[n]])},call:function(e,t,i,s){var n,a=e.plugins[t];if(a&&(s||e.element[0].parentNode&&11!==e.element[0].parentNode.nodeType))for(n=0;a.length>n;n++)e.options[a[n][0]]&&a[n][1].apply(e.element,i)}};var s=0,n=Array.prototype.slice;e.cleanData=function(t){return function(i){var s,n,a;for(a=0;null!=(n=i[a]);a++)try{s=e._data(n,"events"),s&&s.remove&&e(n).triggerHandler("remove")}catch(o){}t(i)}}(e.cleanData),e.widget=function(t,i,s){var n,a,o,r,h={},l=t.split(".")[0];return t=t.split(".")[1],n=l+"-"+t,s||(s=i,i=e.Widget),e.expr[":"][n.toLowerCase()]=function(t){return!!e.data(t,n)},e[l]=e[l]||{},a=e[l][t],o=e[l][t]=function(e,t){return this._createWidget?(arguments.length&&this._createWidget(e,t),void 0):new o(e,t)},e.extend(o,a,{version:s.version,_proto:e.extend({},s),_childConstructors:[]}),r=new i,r.options=e.widget.extend({},r.options),e.each(s,function(t,s){return e.isFunction(s)?(h[t]=function(){var e=function(){return i.prototype[t].apply(this,arguments)},n=function(e){return i.prototype[t].apply(this,e)};return function(){var t,i=this._super,a=this._superApply;return this._super=e,this._superApply=n,t=s.apply(this,arguments),this._super=i,this._superApply=a,t}}(),void 0):(h[t]=s,void 0)}),o.prototype=e.widget.extend(r,{widgetEventPrefix:a?r.widgetEventPrefix||t:t},h,{constructor:o,namespace:l,widgetName:t,widgetFullName:n}),a?(e.each(a._childConstructors,function(t,i){var s=i.prototype;e.widget(s.namespace+"."+s.widgetName,o,i._proto)}),delete a._childConstructors):i._childConstructors.push(o),e.widget.bridge(t,o),o},e.widget.extend=function(t){for(var i,s,a=n.call(arguments,1),o=0,r=a.length;r>o;o++)for(i in a[o])s=a[o][i],a[o].hasOwnProperty(i)&&void 0!==s&&(t[i]=e.isPlainObject(s)?e.isPlainObject(t[i])?e.widget.extend({},t[i],s):e.widget.extend({},s):s);return t},e.widget.bridge=function(t,i){var s=i.prototype.widgetFullName||t;e.fn[t]=function(a){var o="string"==typeof a,r=n.call(arguments,1),h=this;return o?this.each(function(){var i,n=e.data(this,s);return"instance"===a?(h=n,!1):n?e.isFunction(n[a])&&"_"!==a.charAt(0)?(i=n[a].apply(n,r),i!==n&&void 0!==i?(h=i&&i.jquery?h.pushStack(i.get()):i,!1):void 0):e.error("no such method '"+a+"' for "+t+" widget instance"):e.error("cannot call methods on "+t+" prior to initialization; "+"attempted to call method '"+a+"'")}):(r.length&&(a=e.widget.extend.apply(null,[a].concat(r))),this.each(function(){var t=e.data(this,s);t?(t.option(a||{}),t._init&&t._init()):e.data(this,s,new i(a,this))})),h}},e.Widget=function(){},e.Widget._childConstructors=[],e.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"
",options:{disabled:!1,create:null},_createWidget:function(t,i){i=e(i||this.defaultElement||this)[0],this.element=e(i),this.uuid=s++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=e(),this.hoverable=e(),this.focusable=e(),i!==this&&(e.data(i,this.widgetFullName,this),this._on(!0,this.element,{remove:function(e){e.target===i&&this.destroy()}}),this.document=e(i.style?i.ownerDocument:i.document||i),this.window=e(this.document[0].defaultView||this.document[0].parentWindow)),this.options=e.widget.extend({},this.options,this._getCreateOptions(),t),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:e.noop,_getCreateEventData:e.noop,_create:e.noop,_init:e.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetFullName).removeData(e.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:e.noop,widget:function(){return this.element},option:function(t,i){var s,n,a,o=t;if(0===arguments.length)return e.widget.extend({},this.options);if("string"==typeof t)if(o={},s=t.split("."),t=s.shift(),s.length){for(n=o[t]=e.widget.extend({},this.options[t]),a=0;s.length-1>a;a++)n[s[a]]=n[s[a]]||{},n=n[s[a]];if(t=s.pop(),1===arguments.length)return void 0===n[t]?null:n[t];n[t]=i}else{if(1===arguments.length)return void 0===this.options[t]?null:this.options[t];o[t]=i}return this._setOptions(o),this},_setOptions:function(e){var t;for(t in e)this._setOption(t,e[t]);return this},_setOption:function(e,t){return this.options[e]=t,"disabled"===e&&(this.widget().toggleClass(this.widgetFullName+"-disabled",!!t),t&&(this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus"))),this},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_on:function(t,i,s){var n,a=this;"boolean"!=typeof t&&(s=i,i=t,t=!1),s?(i=n=e(i),this.bindings=this.bindings.add(i)):(s=i,i=this.element,n=this.widget()),e.each(s,function(s,o){function r(){return t||a.options.disabled!==!0&&!e(this).hasClass("ui-state-disabled")?("string"==typeof o?a[o]:o).apply(a,arguments):void 0}"string"!=typeof o&&(r.guid=o.guid=o.guid||r.guid||e.guid++);var h=s.match(/^([\w:-]*)\s*(.*)$/),l=h[1]+a.eventNamespace,u=h[2];u?n.delegate(u,l,r):i.bind(l,r)})},_off:function(t,i){i=(i||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,t.unbind(i).undelegate(i),this.bindings=e(this.bindings.not(t).get()),this.focusable=e(this.focusable.not(t).get()),this.hoverable=e(this.hoverable.not(t).get())},_delay:function(e,t){function i(){return("string"==typeof e?s[e]:e).apply(s,arguments)}var s=this;return setTimeout(i,t||0)},_hoverable:function(t){this.hoverable=this.hoverable.add(t),this._on(t,{mouseenter:function(t){e(t.currentTarget).addClass("ui-state-hover")},mouseleave:function(t){e(t.currentTarget).removeClass("ui-state-hover")}})},_focusable:function(t){this.focusable=this.focusable.add(t),this._on(t,{focusin:function(t){e(t.currentTarget).addClass("ui-state-focus")},focusout:function(t){e(t.currentTarget).removeClass("ui-state-focus")}})},_trigger:function(t,i,s){var n,a,o=this.options[t];if(s=s||{},i=e.Event(i),i.type=(t===this.widgetEventPrefix?t:this.widgetEventPrefix+t).toLowerCase(),i.target=this.element[0],a=i.originalEvent)for(n in a)n in i||(i[n]=a[n]);return this.element.trigger(i,s),!(e.isFunction(o)&&o.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},e.each({show:"fadeIn",hide:"fadeOut"},function(t,i){e.Widget.prototype["_"+t]=function(s,n,a){"string"==typeof n&&(n={effect:n});var o,r=n?n===!0||"number"==typeof n?i:n.effect||i:t;n=n||{},"number"==typeof n&&(n={duration:n}),o=!e.isEmptyObject(n),n.complete=a,n.delay&&s.delay(n.delay),o&&e.effects&&e.effects.effect[r]?s[t](n):r!==t&&s[r]?s[r](n.duration,n.easing,a):s.queue(function(i){e(this)[t](),a&&a.call(s[0]),i()})}}),e.widget;var a=!1;e(document).mouseup(function(){a=!1}),e.widget("ui.mouse",{version:"1.11.4",options:{cancel:"input,textarea,button,select,option",distance:1,delay:0},_mouseInit:function(){var t=this;this.element.bind("mousedown."+this.widgetName,function(e){return t._mouseDown(e)}).bind("click."+this.widgetName,function(i){return!0===e.data(i.target,t.widgetName+".preventClickEvent")?(e.removeData(i.target,t.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):void 0}),this.started=!1},_mouseDestroy:function(){this.element.unbind("."+this.widgetName),this._mouseMoveDelegate&&this.document.unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(t){if(!a){this._mouseMoved=!1,this._mouseStarted&&this._mouseUp(t),this._mouseDownEvent=t;var i=this,s=1===t.which,n="string"==typeof this.options.cancel&&t.target.nodeName?e(t.target).closest(this.options.cancel).length:!1;return s&&!n&&this._mouseCapture(t)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){i.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(t)&&this._mouseDelayMet(t)&&(this._mouseStarted=this._mouseStart(t)!==!1,!this._mouseStarted)?(t.preventDefault(),!0):(!0===e.data(t.target,this.widgetName+".preventClickEvent")&&e.removeData(t.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(e){return i._mouseMove(e)},this._mouseUpDelegate=function(e){return i._mouseUp(e)},this.document.bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate),t.preventDefault(),a=!0,!0)):!0}},_mouseMove:function(t){if(this._mouseMoved){if(e.ui.ie&&(!document.documentMode||9>document.documentMode)&&!t.button)return this._mouseUp(t);if(!t.which)return this._mouseUp(t)}return(t.which||t.button)&&(this._mouseMoved=!0),this._mouseStarted?(this._mouseDrag(t),t.preventDefault()):(this._mouseDistanceMet(t)&&this._mouseDelayMet(t)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,t)!==!1,this._mouseStarted?this._mouseDrag(t):this._mouseUp(t)),!this._mouseStarted)},_mouseUp:function(t){return this.document.unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,t.target===this._mouseDownEvent.target&&e.data(t.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(t)),a=!1,!1},_mouseDistanceMet:function(e){return Math.max(Math.abs(this._mouseDownEvent.pageX-e.pageX),Math.abs(this._mouseDownEvent.pageY-e.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),e.widget("ui.sortable",e.ui.mouse,{version:"1.11.4",widgetEventPrefix:"sort",ready:!1,options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3,activate:null,beforeStop:null,change:null,deactivate:null,out:null,over:null,receive:null,remove:null,sort:null,start:null,stop:null,update:null},_isOverAxis:function(e,t,i){return e>=t&&t+i>e},_isFloating:function(e){return/left|right/.test(e.css("float"))||/inline|table-cell/.test(e.css("display"))},_create:function(){this.containerCache={},this.element.addClass("ui-sortable"),this.refresh(),this.offset=this.element.offset(),this._mouseInit(),this._setHandleClassName(),this.ready=!0},_setOption:function(e,t){this._super(e,t),"handle"===e&&this._setHandleClassName()},_setHandleClassName:function(){this.element.find(".ui-sortable-handle").removeClass("ui-sortable-handle"),e.each(this.items,function(){(this.instance.options.handle?this.item.find(this.instance.options.handle):this.item).addClass("ui-sortable-handle")})},_destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled").find(".ui-sortable-handle").removeClass("ui-sortable-handle"),this._mouseDestroy();for(var e=this.items.length-1;e>=0;e--)this.items[e].item.removeData(this.widgetName+"-item");return this},_mouseCapture:function(t,i){var s=null,n=!1,a=this;return this.reverting?!1:this.options.disabled||"static"===this.options.type?!1:(this._refreshItems(t),e(t.target).parents().each(function(){return e.data(this,a.widgetName+"-item")===a?(s=e(this),!1):void 0}),e.data(t.target,a.widgetName+"-item")===a&&(s=e(t.target)),s?!this.options.handle||i||(e(this.options.handle,s).find("*").addBack().each(function(){this===t.target&&(n=!0)}),n)?(this.currentItem=s,this._removeCurrentsFromItems(),!0):!1:!1)},_mouseStart:function(t,i,s){var n,a,o=this.options;if(this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(t),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},e.extend(this.offset,{click:{left:t.pageX-this.offset.left,top:t.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),this.originalPosition=this._generatePosition(t),this.originalPageX=t.pageX,this.originalPageY=t.pageY,o.cursorAt&&this._adjustOffsetFromHelper(o.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!==this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),o.containment&&this._setContainment(),o.cursor&&"auto"!==o.cursor&&(a=this.document.find("body"),this.storedCursor=a.css("cursor"),a.css("cursor",o.cursor),this.storedStylesheet=e("").appendTo(a)),o.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",o.opacity)),o.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",o.zIndex)),this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",t,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions(),!s)for(n=this.containers.length-1;n>=0;n--)this.containers[n]._trigger("activate",t,this._uiHash(this));return e.ui.ddmanager&&(e.ui.ddmanager.current=this),e.ui.ddmanager&&!o.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t),this.dragging=!0,this.helper.addClass("ui-sortable-helper"),this._mouseDrag(t),!0},_mouseDrag:function(t){var i,s,n,a,o=this.options,r=!1;for(this.position=this._generatePosition(t),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs),this.options.scroll&&(this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-t.pageY=0;i--)if(s=this.items[i],n=s.item[0],a=this._intersectsWithPointer(s),a&&s.instance===this.currentContainer&&n!==this.currentItem[0]&&this.placeholder[1===a?"next":"prev"]()[0]!==n&&!e.contains(this.placeholder[0],n)&&("semi-dynamic"===this.options.type?!e.contains(this.element[0],n):!0)){if(this.direction=1===a?"down":"up","pointer"!==this.options.tolerance&&!this._intersectsWithSides(s))break;this._rearrange(t,s),this._trigger("change",t,this._uiHash());break}return this._contactContainers(t),e.ui.ddmanager&&e.ui.ddmanager.drag(this,t),this._trigger("sort",t,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(t,i){if(t){if(e.ui.ddmanager&&!this.options.dropBehaviour&&e.ui.ddmanager.drop(this,t),this.options.revert){var s=this,n=this.placeholder.offset(),a=this.options.axis,o={};a&&"x"!==a||(o.left=n.left-this.offset.parent.left-this.margins.left+(this.offsetParent[0]===this.document[0].body?0:this.offsetParent[0].scrollLeft)),a&&"y"!==a||(o.top=n.top-this.offset.parent.top-this.margins.top+(this.offsetParent[0]===this.document[0].body?0:this.offsetParent[0].scrollTop)),this.reverting=!0,e(this.helper).animate(o,parseInt(this.options.revert,10)||500,function(){s._clear(t)})}else this._clear(t,i);return!1}},cancel:function(){if(this.dragging){this._mouseUp({target:null}),"original"===this.options.helper?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var t=this.containers.length-1;t>=0;t--)this.containers[t]._trigger("deactivate",null,this._uiHash(this)),this.containers[t].containerCache.over&&(this.containers[t]._trigger("out",null,this._uiHash(this)),this.containers[t].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),"original"!==this.options.helper&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),e.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?e(this.domPosition.prev).after(this.currentItem):e(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(t){var i=this._getItemsAsjQuery(t&&t.connected),s=[];return t=t||{},e(i).each(function(){var i=(e(t.item||this).attr(t.attribute||"id")||"").match(t.expression||/(.+)[\-=_](.+)/);i&&s.push((t.key||i[1]+"[]")+"="+(t.key&&t.expression?i[1]:i[2]))}),!s.length&&t.key&&s.push(t.key+"="),s.join("&")},toArray:function(t){var i=this._getItemsAsjQuery(t&&t.connected),s=[];return t=t||{},i.each(function(){s.push(e(t.item||this).attr(t.attribute||"id")||"")}),s},_intersectsWith:function(e){var t=this.positionAbs.left,i=t+this.helperProportions.width,s=this.positionAbs.top,n=s+this.helperProportions.height,a=e.left,o=a+e.width,r=e.top,h=r+e.height,l=this.offset.click.top,u=this.offset.click.left,c="x"===this.options.axis||s+l>r&&h>s+l,d="y"===this.options.axis||t+u>a&&o>t+u,p=c&&d;return"pointer"===this.options.tolerance||this.options.forcePointerForContainers||"pointer"!==this.options.tolerance&&this.helperProportions[this.floating?"width":"height"]>e[this.floating?"width":"height"]?p:t+this.helperProportions.width/2>a&&o>i-this.helperProportions.width/2&&s+this.helperProportions.height/2>r&&h>n-this.helperProportions.height/2},_intersectsWithPointer:function(e){var t="x"===this.options.axis||this._isOverAxis(this.positionAbs.top+this.offset.click.top,e.top,e.height),i="y"===this.options.axis||this._isOverAxis(this.positionAbs.left+this.offset.click.left,e.left,e.width),s=t&&i,n=this._getDragVerticalDirection(),a=this._getDragHorizontalDirection();return s?this.floating?a&&"right"===a||"down"===n?2:1:n&&("down"===n?2:1):!1},_intersectsWithSides:function(e){var t=this._isOverAxis(this.positionAbs.top+this.offset.click.top,e.top+e.height/2,e.height),i=this._isOverAxis(this.positionAbs.left+this.offset.click.left,e.left+e.width/2,e.width),s=this._getDragVerticalDirection(),n=this._getDragHorizontalDirection();return this.floating&&n?"right"===n&&i||"left"===n&&!i:s&&("down"===s&&t||"up"===s&&!t)},_getDragVerticalDirection:function(){var e=this.positionAbs.top-this.lastPositionAbs.top;return 0!==e&&(e>0?"down":"up")},_getDragHorizontalDirection:function(){var e=this.positionAbs.left-this.lastPositionAbs.left;return 0!==e&&(e>0?"right":"left")},refresh:function(e){return this._refreshItems(e),this._setHandleClassName(),this.refreshPositions(),this},_connectWith:function(){var e=this.options;return e.connectWith.constructor===String?[e.connectWith]:e.connectWith},_getItemsAsjQuery:function(t){function i(){r.push(this)}var s,n,a,o,r=[],h=[],l=this._connectWith();if(l&&t)for(s=l.length-1;s>=0;s--)for(a=e(l[s],this.document[0]),n=a.length-1;n>=0;n--)o=e.data(a[n],this.widgetFullName),o&&o!==this&&!o.options.disabled&&h.push([e.isFunction(o.options.items)?o.options.items.call(o.element):e(o.options.items,o.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),o]);for(h.push([e.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):e(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]),s=h.length-1;s>=0;s--)h[s][0].each(i);return e(r)},_removeCurrentsFromItems:function(){var t=this.currentItem.find(":data("+this.widgetName+"-item)");this.items=e.grep(this.items,function(e){for(var i=0;t.length>i;i++)if(t[i]===e.item[0])return!1;return!0})},_refreshItems:function(t){this.items=[],this.containers=[this];var i,s,n,a,o,r,h,l,u=this.items,c=[[e.isFunction(this.options.items)?this.options.items.call(this.element[0],t,{item:this.currentItem}):e(this.options.items,this.element),this]],d=this._connectWith();if(d&&this.ready)for(i=d.length-1;i>=0;i--)for(n=e(d[i],this.document[0]),s=n.length-1;s>=0;s--)a=e.data(n[s],this.widgetFullName),a&&a!==this&&!a.options.disabled&&(c.push([e.isFunction(a.options.items)?a.options.items.call(a.element[0],t,{item:this.currentItem}):e(a.options.items,a.element),a]),this.containers.push(a));for(i=c.length-1;i>=0;i--)for(o=c[i][1],r=c[i][0],s=0,l=r.length;l>s;s++)h=e(r[s]),h.data(this.widgetName+"-item",o),u.push({item:h,instance:o,width:0,height:0,left:0,top:0})},refreshPositions:function(t){this.floating=this.items.length?"x"===this.options.axis||this._isFloating(this.items[0].item):!1,this.offsetParent&&this.helper&&(this.offset.parent=this._getParentOffset());var i,s,n,a;for(i=this.items.length-1;i>=0;i--)s=this.items[i],s.instance!==this.currentContainer&&this.currentContainer&&s.item[0]!==this.currentItem[0]||(n=this.options.toleranceElement?e(this.options.toleranceElement,s.item):s.item,t||(s.width=n.outerWidth(),s.height=n.outerHeight()),a=n.offset(),s.left=a.left,s.top=a.top);if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(i=this.containers.length-1;i>=0;i--)a=this.containers[i].element.offset(),this.containers[i].containerCache.left=a.left,this.containers[i].containerCache.top=a.top,this.containers[i].containerCache.width=this.containers[i].element.outerWidth(),this.containers[i].containerCache.height=this.containers[i].element.outerHeight();return this},_createPlaceholder:function(t){t=t||this;var i,s=t.options;s.placeholder&&s.placeholder.constructor!==String||(i=s.placeholder,s.placeholder={element:function(){var s=t.currentItem[0].nodeName.toLowerCase(),n=e("<"+s+">",t.document[0]).addClass(i||t.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper");return"tbody"===s?t._createTrPlaceholder(t.currentItem.find("tr").eq(0),e("",t.document[0]).appendTo(n)):"tr"===s?t._createTrPlaceholder(t.currentItem,n):"img"===s&&n.attr("src",t.currentItem.attr("src")),i||n.css("visibility","hidden"),n},update:function(e,n){(!i||s.forcePlaceholderSize)&&(n.height()||n.height(t.currentItem.innerHeight()-parseInt(t.currentItem.css("paddingTop")||0,10)-parseInt(t.currentItem.css("paddingBottom")||0,10)),n.width()||n.width(t.currentItem.innerWidth()-parseInt(t.currentItem.css("paddingLeft")||0,10)-parseInt(t.currentItem.css("paddingRight")||0,10)))}}),t.placeholder=e(s.placeholder.element.call(t.element,t.currentItem)),t.currentItem.after(t.placeholder),s.placeholder.update(t,t.placeholder)},_createTrPlaceholder:function(t,i){var s=this;t.children().each(function(){e(" ",s.document[0]).attr("colspan",e(this).attr("colspan")||1).appendTo(i)})},_contactContainers:function(t){var i,s,n,a,o,r,h,l,u,c,d=null,p=null;for(i=this.containers.length-1;i>=0;i--)if(!e.contains(this.currentItem[0],this.containers[i].element[0]))if(this._intersectsWith(this.containers[i].containerCache)){if(d&&e.contains(this.containers[i].element[0],d.element[0]))continue;d=this.containers[i],p=i}else this.containers[i].containerCache.over&&(this.containers[i]._trigger("out",t,this._uiHash(this)),this.containers[i].containerCache.over=0);if(d)if(1===this.containers.length)this.containers[p].containerCache.over||(this.containers[p]._trigger("over",t,this._uiHash(this)),this.containers[p].containerCache.over=1);else{for(n=1e4,a=null,u=d.floating||this._isFloating(this.currentItem),o=u?"left":"top",r=u?"width":"height",c=u?"clientX":"clientY",s=this.items.length-1;s>=0;s--)e.contains(this.containers[p].element[0],this.items[s].item[0])&&this.items[s].item[0]!==this.currentItem[0]&&(h=this.items[s].item.offset()[o],l=!1,t[c]-h>this.items[s][r]/2&&(l=!0),n>Math.abs(t[c]-h)&&(n=Math.abs(t[c]-h),a=this.items[s],this.direction=l?"up":"down"));if(!a&&!this.options.dropOnEmpty)return;if(this.currentContainer===this.containers[p])return this.currentContainer.containerCache.over||(this.containers[p]._trigger("over",t,this._uiHash()),this.currentContainer.containerCache.over=1),void 0;a?this._rearrange(t,a,null,!0):this._rearrange(t,null,this.containers[p].element,!0),this._trigger("change",t,this._uiHash()),this.containers[p]._trigger("change",t,this._uiHash(this)),this.currentContainer=this.containers[p],this.options.placeholder.update(this.currentContainer,this.placeholder),this.containers[p]._trigger("over",t,this._uiHash(this)),this.containers[p].containerCache.over=1}},_createHelper:function(t){var i=this.options,s=e.isFunction(i.helper)?e(i.helper.apply(this.element[0],[t,this.currentItem])):"clone"===i.helper?this.currentItem.clone():this.currentItem;return s.parents("body").length||e("parent"!==i.appendTo?i.appendTo:this.currentItem[0].parentNode)[0].appendChild(s[0]),s[0]===this.currentItem[0]&&(this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")}),(!s[0].style.width||i.forceHelperSize)&&s.width(this.currentItem.width()),(!s[0].style.height||i.forceHelperSize)&&s.height(this.currentItem.height()),s},_adjustOffsetFromHelper:function(t){"string"==typeof t&&(t=t.split(" ")),e.isArray(t)&&(t={left:+t[0],top:+t[1]||0}),"left"in t&&(this.offset.click.left=t.left+this.margins.left),"right"in t&&(this.offset.click.left=this.helperProportions.width-t.right+this.margins.left),"top"in t&&(this.offset.click.top=t.top+this.margins.top),"bottom"in t&&(this.offset.click.top=this.helperProportions.height-t.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var t=this.offsetParent.offset();return"absolute"===this.cssPosition&&this.scrollParent[0]!==this.document[0]&&e.contains(this.scrollParent[0],this.offsetParent[0])&&(t.left+=this.scrollParent.scrollLeft(),t.top+=this.scrollParent.scrollTop()),(this.offsetParent[0]===this.document[0].body||this.offsetParent[0].tagName&&"html"===this.offsetParent[0].tagName.toLowerCase()&&e.ui.ie)&&(t={top:0,left:0}),{top:t.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:t.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"===this.cssPosition){var e=this.currentItem.position();return{top:e.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:e.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var t,i,s,n=this.options;"parent"===n.containment&&(n.containment=this.helper[0].parentNode),("document"===n.containment||"window"===n.containment)&&(this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,"document"===n.containment?this.document.width():this.window.width()-this.helperProportions.width-this.margins.left,("document"===n.containment?this.document.width():this.window.height()||this.document[0].body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]),/^(document|window|parent)$/.test(n.containment)||(t=e(n.containment)[0],i=e(n.containment).offset(),s="hidden"!==e(t).css("overflow"),this.containment=[i.left+(parseInt(e(t).css("borderLeftWidth"),10)||0)+(parseInt(e(t).css("paddingLeft"),10)||0)-this.margins.left,i.top+(parseInt(e(t).css("borderTopWidth"),10)||0)+(parseInt(e(t).css("paddingTop"),10)||0)-this.margins.top,i.left+(s?Math.max(t.scrollWidth,t.offsetWidth):t.offsetWidth)-(parseInt(e(t).css("borderLeftWidth"),10)||0)-(parseInt(e(t).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,i.top+(s?Math.max(t.scrollHeight,t.offsetHeight):t.offsetHeight)-(parseInt(e(t).css("borderTopWidth"),10)||0)-(parseInt(e(t).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top]) -},_convertPositionTo:function(t,i){i||(i=this.position);var s="absolute"===t?1:-1,n="absolute"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,a=/(html|body)/i.test(n[0].tagName);return{top:i.top+this.offset.relative.top*s+this.offset.parent.top*s-("fixed"===this.cssPosition?-this.scrollParent.scrollTop():a?0:n.scrollTop())*s,left:i.left+this.offset.relative.left*s+this.offset.parent.left*s-("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():a?0:n.scrollLeft())*s}},_generatePosition:function(t){var i,s,n=this.options,a=t.pageX,o=t.pageY,r="absolute"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,h=/(html|body)/i.test(r[0].tagName);return"relative"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&this.scrollParent[0]!==this.offsetParent[0]||(this.offset.relative=this._getRelativeOffset()),this.originalPosition&&(this.containment&&(t.pageX-this.offset.click.leftthis.containment[2]&&(a=this.containment[2]+this.offset.click.left),t.pageY-this.offset.click.top>this.containment[3]&&(o=this.containment[3]+this.offset.click.top)),n.grid&&(i=this.originalPageY+Math.round((o-this.originalPageY)/n.grid[1])*n.grid[1],o=this.containment?i-this.offset.click.top>=this.containment[1]&&i-this.offset.click.top<=this.containment[3]?i:i-this.offset.click.top>=this.containment[1]?i-n.grid[1]:i+n.grid[1]:i,s=this.originalPageX+Math.round((a-this.originalPageX)/n.grid[0])*n.grid[0],a=this.containment?s-this.offset.click.left>=this.containment[0]&&s-this.offset.click.left<=this.containment[2]?s:s-this.offset.click.left>=this.containment[0]?s-n.grid[0]:s+n.grid[0]:s)),{top:o-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():h?0:r.scrollTop()),left:a-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():h?0:r.scrollLeft())}},_rearrange:function(e,t,i,s){i?i[0].appendChild(this.placeholder[0]):t.item[0].parentNode.insertBefore(this.placeholder[0],"down"===this.direction?t.item[0]:t.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var n=this.counter;this._delay(function(){n===this.counter&&this.refreshPositions(!s)})},_clear:function(e,t){function i(e,t,i){return function(s){i._trigger(e,s,t._uiHash(t))}}this.reverting=!1;var s,n=[];if(!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null,this.helper[0]===this.currentItem[0]){for(s in this._storedCSS)("auto"===this._storedCSS[s]||"static"===this._storedCSS[s])&&(this._storedCSS[s]="");this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else this.currentItem.show();for(this.fromOutside&&!t&&n.push(function(e){this._trigger("receive",e,this._uiHash(this.fromOutside))}),!this.fromOutside&&this.domPosition.prev===this.currentItem.prev().not(".ui-sortable-helper")[0]&&this.domPosition.parent===this.currentItem.parent()[0]||t||n.push(function(e){this._trigger("update",e,this._uiHash())}),this!==this.currentContainer&&(t||(n.push(function(e){this._trigger("remove",e,this._uiHash())}),n.push(function(e){return function(t){e._trigger("receive",t,this._uiHash(this))}}.call(this,this.currentContainer)),n.push(function(e){return function(t){e._trigger("update",t,this._uiHash(this))}}.call(this,this.currentContainer)))),s=this.containers.length-1;s>=0;s--)t||n.push(i("deactivate",this,this.containers[s])),this.containers[s].containerCache.over&&(n.push(i("out",this,this.containers[s])),this.containers[s].containerCache.over=0);if(this.storedCursor&&(this.document.find("body").css("cursor",this.storedCursor),this.storedStylesheet.remove()),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex","auto"===this._storedZIndex?"":this._storedZIndex),this.dragging=!1,t||this._trigger("beforeStop",e,this._uiHash()),this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.cancelHelperRemoval||(this.helper[0]!==this.currentItem[0]&&this.helper.remove(),this.helper=null),!t){for(s=0;n.length>s;s++)n[s].call(this,e);this._trigger("stop",e,this._uiHash())}return this.fromOutside=!1,!this.cancelHelperRemoval},_trigger:function(){e.Widget.prototype._trigger.apply(this,arguments)===!1&&this.cancel()},_uiHash:function(t){var i=t||this;return{helper:i.helper,placeholder:i.placeholder||e([]),position:i.position,originalPosition:i.originalPosition,offset:i.positionAbs,item:i.currentItem,sender:t?t.element:null}}})}); \ No newline at end of file diff --git a/html/jquery/jquery.min.js b/html/jquery/jquery.min.js deleted file mode 100644 index ab28a24729b..00000000000 --- a/html/jquery/jquery.min.js +++ /dev/null @@ -1,4 +0,0 @@ -/*! jQuery v1.11.1 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */ -!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l="1.11.1",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},m.extend=m.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=r(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=r(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function r(a){var b=a.length,c=m.type(a);return"function"===c||m.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var s=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+-new Date,v=a.document,w=0,x=0,y=gb(),z=gb(),A=gb(),B=function(a,b){return a===b&&(l=!0),0},C="undefined",D=1<<31,E={}.hasOwnProperty,F=[],G=F.pop,H=F.push,I=F.push,J=F.slice,K=F.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},L="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",N="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",O=N.replace("w","w#"),P="\\["+M+"*("+N+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+O+"))|)"+M+"*\\]",Q=":("+N+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+P+")*)|.*)\\)|)",R=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),S=new RegExp("^"+M+"*,"+M+"*"),T=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp("="+M+"*([^\\]'\"]*?)"+M+"*\\]","g"),V=new RegExp(Q),W=new RegExp("^"+O+"$"),X={ID:new RegExp("^#("+N+")"),CLASS:new RegExp("^\\.("+N+")"),TAG:new RegExp("^("+N.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+Q),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+L+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ab=/[+~]/,bb=/'|\\/g,cb=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),db=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{I.apply(F=J.call(v.childNodes),v.childNodes),F[v.childNodes.length].nodeType}catch(eb){I={apply:F.length?function(a,b){H.apply(a,J.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fb(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],!a||"string"!=typeof a)return d;if(1!==(k=b.nodeType)&&9!==k)return[];if(p&&!e){if(f=_.exec(a))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return I.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return I.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=9===k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(bb,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+qb(o[l]);w=ab.test(a)&&ob(b.parentNode)||b,x=o.join(",")}if(x)try{return I.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function gb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function hb(a){return a[u]=!0,a}function ib(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function jb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function kb(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||D)-(~a.sourceIndex||D);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function lb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function mb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function nb(a){return hb(function(b){return b=+b,hb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function ob(a){return a&&typeof a.getElementsByTagName!==C&&a}c=fb.support={},f=fb.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fb.setDocument=function(a){var b,e=a?a.ownerDocument||a:v,g=e.defaultView;return e!==n&&9===e.nodeType&&e.documentElement?(n=e,o=e.documentElement,p=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){m()},!1):g.attachEvent&&g.attachEvent("onunload",function(){m()})),c.attributes=ib(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ib(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(e.getElementsByClassName)&&ib(function(a){return a.innerHTML="
",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=ib(function(a){return o.appendChild(a).id=u,!e.getElementsByName||!e.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==C&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){var c=typeof a.getAttributeNode!==C&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==C?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==C&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(e.querySelectorAll))&&(ib(function(a){a.innerHTML="",a.querySelectorAll("[msallowclip^='']").length&&q.push("[*^$]="+M+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+M+"*(?:value|"+L+")"),a.querySelectorAll(":checked").length||q.push(":checked")}),ib(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+M+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ib(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",Q)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===v&&t(v,a)?-1:b===e||b.ownerDocument===v&&t(v,b)?1:k?K.call(k,a)-K.call(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],i=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:k?K.call(k,a)-K.call(k,b):0;if(f===g)return kb(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?kb(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},e):n},fb.matches=function(a,b){return fb(a,null,null,b)},fb.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fb(b,n,null,[a]).length>0},fb.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fb.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&E.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fb.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fb.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fb.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fb.selectors={cacheLength:50,createPseudo:hb,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(cb,db),a[3]=(a[3]||a[4]||a[5]||"").replace(cb,db),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fb.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fb.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(cb,db).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+M+")"+a+"("+M+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==C&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fb.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fb.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?hb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=K.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:hb(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?hb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:hb(function(a){return function(b){return fb(a,b).length>0}}),contains:hb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:hb(function(a){return W.test(a||"")||fb.error("unsupported lang: "+a),a=a.replace(cb,db).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:nb(function(){return[0]}),last:nb(function(a,b){return[b-1]}),eq:nb(function(a,b,c){return[0>c?c+b:c]}),even:nb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:nb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:nb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:nb(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function rb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function sb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function tb(a,b,c){for(var d=0,e=b.length;e>d;d++)fb(a,b[d],c);return c}function ub(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function vb(a,b,c,d,e,f){return d&&!d[u]&&(d=vb(d)),e&&!e[u]&&(e=vb(e,f)),hb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||tb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ub(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ub(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?K.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ub(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):I.apply(g,r)})}function wb(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=rb(function(a){return a===b},h,!0),l=rb(function(a){return K.call(b,a)>-1},h,!0),m=[function(a,c,d){return!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>i;i++)if(c=d.relative[a[i].type])m=[rb(sb(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return vb(i>1&&sb(m),i>1&&qb(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&wb(a.slice(i,e)),f>e&&wb(a=a.slice(e)),f>e&&qb(a))}m.push(c)}return sb(m)}function xb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=G.call(i));s=ub(s)}I.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&fb.uniqueSort(i)}return k&&(w=v,j=t),r};return c?hb(f):f}return h=fb.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wb(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xb(e,d)),f.selector=a}return f},i=fb.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(cb,db),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(cb,db),ab.test(j[0].type)&&ob(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qb(j),!a)return I.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,ab.test(a)&&ob(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ib(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ib(function(a){return a.innerHTML="
","#"===a.firstChild.getAttribute("href")})||jb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ib(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||jb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ib(function(a){return null==a.getAttribute("disabled")})||jb(L,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fb}(a);m.find=s,m.expr=s.selectors,m.expr[":"]=m.expr.pseudos,m.unique=s.uniqueSort,m.text=s.getText,m.isXMLDoc=s.isXML,m.contains=s.contains;var t=m.expr.match.needsContext,u=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,v=/^.[^:#\[\.,]*$/;function w(a,b,c){if(m.isFunction(b))return m.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return m.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(v.test(b))return m.filter(b,a,c);b=m.filter(b,a)}return m.grep(a,function(a){return m.inArray(a,b)>=0!==c})}m.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?m.find.matchesSelector(d,a)?[d]:[]:m.find.matches(a,m.grep(b,function(a){return 1===a.nodeType}))},m.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(m(a).filter(function(){for(b=0;e>b;b++)if(m.contains(d[b],this))return!0}));for(b=0;e>b;b++)m.find(a,d[b],c);return c=this.pushStack(e>1?m.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(w(this,a||[],!1))},not:function(a){return this.pushStack(w(this,a||[],!0))},is:function(a){return!!w(this,"string"==typeof a&&t.test(a)?m(a):a||[],!1).length}});var x,y=a.document,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=m.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||x).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof m?b[0]:b,m.merge(this,m.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:y,!0)),u.test(c[1])&&m.isPlainObject(b))for(c in b)m.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=y.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return x.find(a);this.length=1,this[0]=d}return this.context=y,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):m.isFunction(a)?"undefined"!=typeof x.ready?x.ready(a):a(m):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),m.makeArray(a,this))};A.prototype=m.fn,x=m(y);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};m.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!m(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),m.fn.extend({has:function(a){var b,c=m(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(m.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=t.test(a)||"string"!=typeof a?m(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&m.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?m.unique(f):f)},index:function(a){return a?"string"==typeof a?m.inArray(this[0],m(a)):m.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(m.unique(m.merge(this.get(),m(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}m.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return m.dir(a,"parentNode")},parentsUntil:function(a,b,c){return m.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return m.dir(a,"nextSibling")},prevAll:function(a){return m.dir(a,"previousSibling")},nextUntil:function(a,b,c){return m.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return m.dir(a,"previousSibling",c)},siblings:function(a){return m.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return m.sibling(a.firstChild)},contents:function(a){return m.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:m.merge([],a.childNodes)}},function(a,b){m.fn[a]=function(c,d){var e=m.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=m.filter(d,e)),this.length>1&&(C[a]||(e=m.unique(e)),B.test(a)&&(e=e.reverse())),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return m.each(a.match(E)||[],function(a,c){b[c]=!0}),b}m.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):m.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){m.each(b,function(b,c){var d=m.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&m.each(arguments,function(a,c){var d;while((d=m.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?m.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},m.extend({Deferred:function(a){var b=[["resolve","done",m.Callbacks("once memory"),"resolved"],["reject","fail",m.Callbacks("once memory"),"rejected"],["notify","progress",m.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return m.Deferred(function(c){m.each(b,function(b,f){var g=m.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&m.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?m.extend(a,d):d}},e={};return d.pipe=d.then,m.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&m.isFunction(a.promise)?e:0,g=1===f?a:m.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&m.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;m.fn.ready=function(a){return m.ready.promise().done(a),this},m.extend({isReady:!1,readyWait:1,holdReady:function(a){a?m.readyWait++:m.ready(!0)},ready:function(a){if(a===!0?!--m.readyWait:!m.isReady){if(!y.body)return setTimeout(m.ready);m.isReady=!0,a!==!0&&--m.readyWait>0||(H.resolveWith(y,[m]),m.fn.triggerHandler&&(m(y).triggerHandler("ready"),m(y).off("ready")))}}});function I(){y.addEventListener?(y.removeEventListener("DOMContentLoaded",J,!1),a.removeEventListener("load",J,!1)):(y.detachEvent("onreadystatechange",J),a.detachEvent("onload",J))}function J(){(y.addEventListener||"load"===event.type||"complete"===y.readyState)&&(I(),m.ready())}m.ready.promise=function(b){if(!H)if(H=m.Deferred(),"complete"===y.readyState)setTimeout(m.ready);else if(y.addEventListener)y.addEventListener("DOMContentLoaded",J,!1),a.addEventListener("load",J,!1);else{y.attachEvent("onreadystatechange",J),a.attachEvent("onload",J);var c=!1;try{c=null==a.frameElement&&y.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!m.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}I(),m.ready()}}()}return H.promise(b)};var K="undefined",L;for(L in m(k))break;k.ownLast="0"!==L,k.inlineBlockNeedsLayout=!1,m(function(){var a,b,c,d;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",k.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(d))}),function(){var a=y.createElement("div");if(null==k.deleteExpando){k.deleteExpando=!0;try{delete a.test}catch(b){k.deleteExpando=!1}}a=null}(),m.acceptData=function(a){var b=m.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var M=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,N=/([A-Z])/g;function O(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(N,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:M.test(c)?m.parseJSON(c):c}catch(e){}m.data(a,b,c)}else c=void 0}return c}function P(a){var b;for(b in a)if(("data"!==b||!m.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h; -if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=m.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthh;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML="
a",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML="",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(k[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),k[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\.(.+)|)$/;function ab(){return!0}function bb(){return!1}function cb(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=m.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof m===K||a&&m.event.triggered===a.type?void 0:m.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(E)||[""],h=b.length;while(h--)f=_.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=m.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=m.event.special[o]||{},l=m.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&m.expr.match.needsContext.test(e),namespace:p.join(".")},i),(n=g[o])||(n=g[o]=[],n.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?n.splice(n.delegateCount++,0,l):n.push(l),m.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m.hasData(a)&&m._data(a);if(r&&(k=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=_.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=m.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,n=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=n.length;while(f--)g=n[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(n.splice(f,1),g.selector&&n.delegateCount--,l.remove&&l.remove.call(a,g));i&&!n.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||m.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)m.event.remove(a,o+b[j],c,d,!0);m.isEmptyObject(k)&&(delete r.handle,m._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,n,o=[d||y],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||y,3!==d.nodeType&&8!==d.nodeType&&!$.test(p+m.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[m.expando]?b:new m.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:m.makeArray(c,[b]),k=m.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!m.isWindow(d)){for(i=k.delegateType||p,$.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||y)&&o.push(l.defaultView||l.parentWindow||a)}n=0;while((h=o[n++])&&!b.isPropagationStopped())b.type=n>1?i:k.bindType||p,f=(m._data(h,"events")||{})[b.type]&&m._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&m.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&m.acceptData(d)&&g&&d[p]&&!m.isWindow(d)){l=d[g],l&&(d[g]=null),m.event.triggered=p;try{d[p]()}catch(r){}m.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=m.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(m._data(this,"events")||{})[a.type]||[],k=m.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=m.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((m.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?m(c,this).index(i)>=0:m.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h]","i"),hb=/^\s+/,ib=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,jb=/<([\w:]+)/,kb=/\s*$/g,rb={option:[1,""],legend:[1,"
","
"],area:[1,"",""],param:[1,"",""],thead:[1,"","
"],tr:[2,"","
"],col:[2,"","
"],td:[3,"","
"],_default:k.htmlSerialize?[0,"",""]:[1,"X
","
"]},sb=db(y),tb=sb.appendChild(y.createElement("div"));rb.optgroup=rb.option,rb.tbody=rb.tfoot=rb.colgroup=rb.caption=rb.thead,rb.th=rb.td;function ub(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==K?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==K?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||m.nodeName(d,b)?f.push(d):m.merge(f,ub(d,b));return void 0===b||b&&m.nodeName(a,b)?m.merge([a],f):f}function vb(a){W.test(a.type)&&(a.defaultChecked=a.checked)}function wb(a,b){return m.nodeName(a,"table")&&m.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function xb(a){return a.type=(null!==m.find.attr(a,"type"))+"/"+a.type,a}function yb(a){var b=pb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function zb(a,b){for(var c,d=0;null!=(c=a[d]);d++)m._data(c,"globalEval",!b||m._data(b[d],"globalEval"))}function Ab(a,b){if(1===b.nodeType&&m.hasData(a)){var c,d,e,f=m._data(a),g=m._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)m.event.add(b,c,h[c][d])}g.data&&(g.data=m.extend({},g.data))}}function Bb(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!k.noCloneEvent&&b[m.expando]){e=m._data(b);for(d in e.events)m.removeEvent(b,d,e.handle);b.removeAttribute(m.expando)}"script"===c&&b.text!==a.text?(xb(b).text=a.text,yb(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),k.html5Clone&&a.innerHTML&&!m.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&W.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}m.extend({clone:function(a,b,c){var d,e,f,g,h,i=m.contains(a.ownerDocument,a);if(k.html5Clone||m.isXMLDoc(a)||!gb.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(tb.innerHTML=a.outerHTML,tb.removeChild(f=tb.firstChild)),!(k.noCloneEvent&&k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||m.isXMLDoc(a)))for(d=ub(f),h=ub(a),g=0;null!=(e=h[g]);++g)d[g]&&Bb(e,d[g]);if(b)if(c)for(h=h||ub(a),d=d||ub(f),g=0;null!=(e=h[g]);g++)Ab(e,d[g]);else Ab(a,f);return d=ub(f,"script"),d.length>0&&zb(d,!i&&ub(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,l,n=a.length,o=db(b),p=[],q=0;n>q;q++)if(f=a[q],f||0===f)if("object"===m.type(f))m.merge(p,f.nodeType?[f]:f);else if(lb.test(f)){h=h||o.appendChild(b.createElement("div")),i=(jb.exec(f)||["",""])[1].toLowerCase(),l=rb[i]||rb._default,h.innerHTML=l[1]+f.replace(ib,"<$1>")+l[2],e=l[0];while(e--)h=h.lastChild;if(!k.leadingWhitespace&&hb.test(f)&&p.push(b.createTextNode(hb.exec(f)[0])),!k.tbody){f="table"!==i||kb.test(f)?""!==l[1]||kb.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)m.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}m.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),k.appendChecked||m.grep(ub(p,"input"),vb),q=0;while(f=p[q++])if((!d||-1===m.inArray(f,d))&&(g=m.contains(f.ownerDocument,f),h=ub(o.appendChild(f),"script"),g&&zb(h),c)){e=0;while(f=h[e++])ob.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=m.expando,j=m.cache,l=k.deleteExpando,n=m.event.special;null!=(d=a[h]);h++)if((b||m.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)n[e]?m.event.remove(d,e):m.removeEvent(d,e,g.handle);j[f]&&(delete j[f],l?delete d[i]:typeof d.removeAttribute!==K?d.removeAttribute(i):d[i]=null,c.push(f))}}}),m.fn.extend({text:function(a){return V(this,function(a){return void 0===a?m.text(this):this.empty().append((this[0]&&this[0].ownerDocument||y).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?m.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||m.cleanData(ub(c)),c.parentNode&&(b&&m.contains(c.ownerDocument,c)&&zb(ub(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&m.cleanData(ub(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&m.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return m.clone(this,a,b)})},html:function(a){return V(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(fb,""):void 0;if(!("string"!=typeof a||mb.test(a)||!k.htmlSerialize&&gb.test(a)||!k.leadingWhitespace&&hb.test(a)||rb[(jb.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(ib,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(m.cleanData(ub(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,m.cleanData(ub(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,n=this,o=l-1,p=a[0],q=m.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&nb.test(p))return this.each(function(c){var d=n.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(i=m.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=m.map(ub(i,"script"),xb),f=g.length;l>j;j++)d=i,j!==o&&(d=m.clone(d,!0,!0),f&&m.merge(g,ub(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,m.map(g,yb),j=0;f>j;j++)d=g[j],ob.test(d.type||"")&&!m._data(d,"globalEval")&&m.contains(h,d)&&(d.src?m._evalUrl&&m._evalUrl(d.src):m.globalEval((d.text||d.textContent||d.innerHTML||"").replace(qb,"")));i=c=null}return this}}),m.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){m.fn[a]=function(a){for(var c,d=0,e=[],g=m(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),m(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Cb,Db={};function Eb(b,c){var d,e=m(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:m.css(e[0],"display");return e.detach(),f}function Fb(a){var b=y,c=Db[a];return c||(c=Eb(a,b),"none"!==c&&c||(Cb=(Cb||m("