Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/cmss13-devs/cmss13-pve in…
Browse files Browse the repository at this point in the history
…to sharps
  • Loading branch information
AndroBetel committed Aug 5, 2024
2 parents 69aa5b4 + a3a6f00 commit 53d49ca
Show file tree
Hide file tree
Showing 777 changed files with 33,621 additions and 23,442 deletions.
5 changes: 5 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# We don't want prettier to run on anything outside of the TGUI folder, so we have to do this.
/*

# We want it to run into the TGUI folder, however.
!/tgui
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"eslint.nodePath": "./tgui/.yarn/sdks",
"eslint.workingDirectories": ["./tgui"],
"prettier.prettierPath": "./tgui/.yarn/sdks/prettier/index.js",
"prettier.prettierPath": "./tgui/.yarn/sdks/prettier/index.cjs",
"typescript.tsdk": "./tgui/.yarn/sdks/typescript/lib",
"typescript.enablePromptUseWorkspaceTsdk": true,
"search.exclude": {
Expand All @@ -14,6 +14,7 @@
"files.eol": "\n",
"files.insertFinalNewline": true,
"gitlens.advanced.blame.customArguments": ["-w"],
"tgstationTestExplorer.project.resultsType": "json",
"[javascript]": {
"editor.rulers": [80],
"editor.defaultFormatter": "esbenp.prettier-vscode",
Expand Down
7 changes: 1 addition & 6 deletions code/__DEFINES/__game.dm
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
#define RANGE_TURFS(RADIUS, CENTER) \
block( \
locate(max(CENTER.x-(RADIUS),1), max(CENTER.y-(RADIUS),1), CENTER.z), \
locate(min(CENTER.x+(RADIUS),world.maxx), min(CENTER.y+(RADIUS),world.maxy), CENTER.z) \
)

//Admin perms are in global.dm.

/// To make it even more clear that something is a bitfield.
Expand Down Expand Up @@ -396,6 +390,7 @@ block( \
#define FIRE_MISSION_WEAPON_REMOVED 8
#define FIRE_MISSION_WEAPON_UNUSABLE 16
#define FIRE_MISSION_WEAPON_OUT_OF_AMMO 32
#define FIRE_MISSION_BAD_DIRECTION 64
#define FIRE_MISSION_NOT_EXECUTABLE -1

//Defines for firemission state
Expand Down
2 changes: 2 additions & 0 deletions code/__DEFINES/_math.dm
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@

#define CEILING(x, y) ( -round(-(x) / (y)) * (y) )

#define ROUND_UP(x) ( -round(-(x)))

// round() acts like floor(x, 1) by default but can't handle other values
#define FLOOR(x, y) ( round((x) / (y)) * (y) )

Expand Down
7 changes: 7 additions & 0 deletions code/__DEFINES/alerts.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#define ALERT_BUCKLED "buckled"
#define ALERT_HANDCUFFED "handcuffed"
#define ALERT_LEGCUFFED "legcuffed"
#define ALERT_FLOORED "floored"
#define ALERT_INCAPACITATED "incapacitated"
#define ALERT_KNOCKEDOUT "knockedout"
#define ALERT_IMMOBILIZED "immobilized"
5 changes: 0 additions & 5 deletions code/__DEFINES/dcs/signals/atom/mob/living/signals_living.dm
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,6 @@
#define COMSIG_LIVING_SPEAK "living_speak"
#define COMPONENT_OVERRIDE_SPEAK (1<<0)

#define COMSIG_LIVING_APPLY_EFFECT "living_apply_effect"
#define COMSIG_LIVING_ADJUST_EFFECT "living_adjust_effect"
#define COMSIG_LIVING_SET_EFFECT "living_set_effect"
#define COMPONENT_CANCEL_EFFECT (1<<0)

/// From /obj/structure/proc/do_climb(var/mob/living/user, mods)
#define COMSIG_LIVING_CLIMB_STRUCTURE "climb_over_structure"
/// From /mob/living/Collide(): (atom/A)
Expand Down
3 changes: 3 additions & 0 deletions code/__DEFINES/dcs/signals/atom/mob/signals_mob.dm
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@
#define COMSIG_MOB_MOVE_OR_LOOK "mob_move_or_look"
#define COMPONENT_OVERRIDE_MOB_MOVE_OR_LOOK (1<<0)

///from rejuv
#define COMSIG_LIVING_POST_FULLY_HEAL "living_post_fully_heal"

///from /mob/living/emote(): ()
#define COMSIG_MOB_EMOTE "mob_emote"

Expand Down
3 changes: 2 additions & 1 deletion code/__DEFINES/dcs/signals/atom/signals_atom.dm
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/// From /atom/proc/Decorate
#define COMSIG_ATOM_DECORATED "atom_decorated"

//from SSatoms InitAtom - Only if the atom was not deleted or failed initialization and has a loc
#define COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZED_ON "atom_init_success_on"
///from base of atom/setDir(): (old_dir, new_dir). Called before the direction changes.
#define COMSIG_ATOM_DIR_CHANGE "atom_dir_change"

Expand Down
10 changes: 10 additions & 0 deletions code/__DEFINES/dcs/signals/atom/signals_item.dm
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,13 @@

//Additional procs on items that will be triggered right after the human finishes spawns in
#define COMSIG_POST_SPAWN_UPDATE "post_spawn_update"

#define COMSIG_CAMERA_MAPNAME_ASSIGNED "camera_manager_mapname_assigned"
#define COMSIG_CAMERA_REGISTER_UI "camera_manager_register_ui"
#define COMSIG_CAMERA_UNREGISTER_UI "camera_manager_unregister_ui"
#define COMSIG_CAMERA_SET_NVG "camera_manager_set_nvg"
#define COMSIG_CAMERA_CLEAR_NVG "camera_manager_clear_nvg"
#define COMSIG_CAMERA_SET_TARGET "camera_manager_set_target"
#define COMSIG_CAMERA_SET_AREA "camera_manager_set_area"
#define COMSIG_CAMERA_CLEAR "camera_manager_clear_target"
#define COMSIG_CAMERA_REFRESH "camera_manager_refresh"
2 changes: 2 additions & 0 deletions code/__DEFINES/dcs/signals/atom/signals_obj.dm
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,6 @@
/// from /obj/proc/afterbuckle()
#define COSMIG_OBJ_AFTER_BUCKLE "signal_obj_after_buckle"

#define COMSIG_DROPSHIP_ADD_EQUIPMENT "dropship_add_equipment"
#define COMSIG_DROPSHIP_REMOVE_EQUIPMENT "dropship_remove_equipment"
#define COMSIG_STRUCTURE_CRATE_SQUAD_LAUNCHED "structure_crate_squad_launched"
3 changes: 3 additions & 0 deletions code/__DEFINES/dcs/signals/atom/signals_turf.dm
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,6 @@

///from /turf/closed/wall/proc/place_poster
#define COMSIG_POSTER_PLACED "poster_placed"

///from base of /datum/turf_reservation/proc/Release: (datum/turf_reservation/reservation)
#define COMSIG_TURF_RESERVATION_RELEASED "turf_reservation_released"
2 changes: 2 additions & 0 deletions code/__DEFINES/dcs/signals/signals_global.dm
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

///from base of datum/controller/subsystem/mapping/proc/add_new_zlevel(): (list/args)
#define COMSIG_GLOB_NEW_Z "!new_z"
/// sent after world.maxx and/or world.maxy are expanded: (has_exapnded_world_maxx, has_expanded_world_maxy)
#define COMSIG_GLOB_EXPANDED_WORLD_BOUNDS "!expanded_world_bounds"
///from base of datum/controller/subsystem/mapping/proc/add_new_zlevel(): (list/args)
#define COMSIG_GLOB_VEHICLE_ORDERED "!vehicle_ordered"
/// from /datum/controller/subsystem/ticker/fire
Expand Down
12 changes: 8 additions & 4 deletions code/__DEFINES/equipment.dm
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@
#define ANIMATED_SURGICAL_TOOL (1<<12)
/// Has heat source but isn't 'on fire' and thus can be stored
#define IGNITING_ITEM (1<<13)
/// Overrides NODROP in some cases (stripping)
#define FORCEDROP_CONDITIONAL (1<<14)
/// Overrides smartgunner not being able to wear backpacks
#define SMARTGUNNER_BACKPACK_OVERRIDE (1<<15)
//==========================================================================================


Expand Down Expand Up @@ -550,10 +554,10 @@ var/global/list/uniform_categories = list(
#define PHONE_UPP_SOLDIER "Soldier"
#define PHONE_IO "IO"

#define PHONE_DO_NOT_DISTURB_FORCED 2
#define PHONE_DO_NOT_DISTURB_ON 1
#define PHONE_DO_NOT_DISTURB_OFF 0
#define PHONE_DO_NOT_DISTURB_FORBIDDEN -1
#define PHONE_DND_FORCED 2
#define PHONE_DND_ON 1
#define PHONE_DND_OFF 0
#define PHONE_DND_FORBIDDEN -1

#define PHONE_ON_BASE_UNIT_ICON_STATE "[initial(icon_state)]"
#define PHONE_OFF_BASE_UNIT_ICON_STATE "[initial(icon_state)]_ear"
Expand Down
1 change: 1 addition & 0 deletions code/__DEFINES/layers.dm
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@
///--------------- FULLSCREEN RUNECHAT BUBBLES ------------
#define LIGHTING_PLANE 100
#define EXTERIOR_LIGHTING_PLANE 101
#define NVG_PLANE 110

///Popup Chat Messages
#define RUNECHAT_PLANE 501
Expand Down
7 changes: 2 additions & 5 deletions code/__DEFINES/maps.dm
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,5 @@ require only minor tweaks.
#define MAP_ARMOR_STYLE_JUNGLE "jungle"
#define MAP_ARMOR_STYLE_PRISON "prison"

//turf-only flags
#define NOJAUNT_1 (1<<0)
#define UNUSED_RESERVATION_TURF (1<<1)
/// If a turf can be made dirty at roundstart. This is also used in areas.
#define CAN_BE_DIRTY_1 (1<<2)
/// A map key that corresponds to being one exclusively for Space.
#define SPACE_KEY "space"
1 change: 1 addition & 0 deletions code/__DEFINES/mob_hud.dm
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#define STATUS_HUD_XENO_CULTIST "24" // Whether they are a xeno cultist or not
#define HUNTER_CLAN "25" //Displays a colored icon to represent ingame Hunter Clans
#define HUNTER_HUD "26" //Displays various statuses on mobs for Hunters to identify targets
#define HOLOCARD_HUD "27" //Displays the holocards set by medical personnel

//data HUD (medhud, sechud) defines
#define MOB_HUD_SECURITY_BASIC 1
Expand Down
7 changes: 4 additions & 3 deletions code/__DEFINES/mobs.dm
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/// Multiplier for Stun/KD/KO/etc durations in new backend, due to old system being based on life ticks
#define GLOBAL_STATUS_MULTIPLIER 20 // each in-code unit is worth 20ds of duration

#define HEALTH_THRESHOLD_DEAD -200
#define HEALTH_THRESHOLD_CRIT -50

Expand Down Expand Up @@ -44,9 +47,7 @@

//disabilities
#define NEARSIGHTED (1<<0)
#define EPILEPSY (1<<1)
#define COUGHING (1<<2)
#define TOURETTES (1<<3)

#define NERVOUS (1<<4)
#define OPIATE_RECEPTOR_DEFICIENCY (1<<5)
//=================================================
Expand Down
5 changes: 5 additions & 0 deletions code/__DEFINES/objects.dm
Original file line number Diff line number Diff line change
Expand Up @@ -173,3 +173,8 @@ var/list/RESTRICTED_CAMERA_NETWORKS = list( //Those networks can only be accesse
#define CHECKS_PASSED 1
#define STILL_ON_COOLDOWN 2
#define NO_LIGHT_STATE_CHANGE 3

//tool capabilities or something i don't know
#define REMOVE_CROWBAR (1<<0)
#define BREAK_CROWBAR (1<<1)
#define REMOVE_SCREWDRIVER (1<<2)
2 changes: 1 addition & 1 deletion code/__DEFINES/shuttles.dm
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
#define TRANSIT_REQUEST 1
#define TRANSIT_READY 2

#define SHUTTLE_TRANSIT_BORDER 8
#define SHUTTLE_TRANSIT_BORDER 16

#define PARALLAX_LOOP_TIME 25
#define HYPERSPACE_END_TIME 5
Expand Down
25 changes: 25 additions & 0 deletions code/__DEFINES/status_effects.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
///if it allows multiple instances of the effect
#define STATUS_EFFECT_MULTIPLE 0
///if it allows only one, preventing new instances
#define STATUS_EFFECT_UNIQUE 1
///if it allows only one, but new instances replace
#define STATUS_EFFECT_REPLACE 2
/// if it only allows one, and new instances just instead refresh the timer
#define STATUS_EFFECT_REFRESH 3

///Processing flags - used to define the speed at which the status will work
///This is fast - 0.2s between ticks (I believe!)
#define STATUS_EFFECT_FAST_PROCESS 0
///This is slower and better for more intensive status effects - 1s between ticks
#define STATUS_EFFECT_NORMAL_PROCESS 1

//Incapacitated status effect flags
/// If the incapacitated status effect will ignore a mob in restraints (handcuffs)
#define IGNORE_RESTRAINTS (1<<0)
/// If the incapacitated status effect will ignore a mob in stasis (stasis beds)
#define IGNORE_STASIS (1<<1)
/// If the incapacitated status effect will ignore a mob being agressively grabbed
#define IGNORE_GRAB (1<<2)

/// Time threshold after which we launch ending timer - this should be higher than the slowest processing rate
#define STATUS_EFFECT_TIME_THRESHOLD (2 SECONDS)
4 changes: 3 additions & 1 deletion code/__DEFINES/subsystems.dm
Original file line number Diff line number Diff line change
Expand Up @@ -182,9 +182,11 @@
#define SS_PRIORITY_FAST_OBJECTS 105
#define SS_PRIORITY_OBJECTS 104
#define SS_PRIORITY_DECORATOR 99
#define SS_PRIORITY_EFFECTS 97
#define SS_PRIORITY_FASTEFFECTS 96
#define SS_PRIORITY_HIJACK 97
#define SS_PRIORITY_POWER 95
#define SS_PRIORITY_EFFECTS 92
#define SS_PRIORITY_OLDEFFECTS 92
#define SS_PRIORITY_MACHINERY 90
#define SS_PRIORITY_FZ_TRANSITIONS 88
#define SS_PRIORITY_ROUND_RECORDING 83
Expand Down
6 changes: 6 additions & 0 deletions code/__DEFINES/tgui.dm
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@
"%7b%22type%22%3a%22[type]%22%2c%22payload%22%3a[url_encode(json_encode(payload))]%7d" \
)

/// Creates a message packet for sending via output() specifically for opening tgsay using an embedded winget
// This is {"type":"open","payload":{"channel":channel,"mapfocus":[[map.focus]]}}, but pre-encoded.
#define TGUI_CREATE_OPEN_MESSAGE(channel) ( \
"%7b%22type%22%3a%22open%22%2c%22payload%22%3a%7B%22channel%22%3a%22[channel]%22%2c%22mapfocus%22%3a\[\[map.focus\]\]%7d%7d" \
)

/*
*Defines for the TGUI health analyser interface
*The higher the level, the more information you can see
Expand Down
8 changes: 8 additions & 0 deletions code/__DEFINES/traits.dm
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@
#define TRAIT_FORCED_STANDING "forcedstanding"
/// Stuns preventing movement and using objects but without further impairement
#define TRAIT_INCAPACITATED "incapacitated"
/// Disoriented. Unable to talk properly, and unable to use some skills as Xeno
#define TRAIT_DAZED "dazed"
/// Apply this to identify a mob as merged with weeds
#define TRAIT_MERGED_WITH_WEEDS "merged_with_weeds"

Expand Down Expand Up @@ -310,6 +312,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_IMMOBILIZED" = TRAIT_IMMOBILIZED,
"TRAIT_INCAPACITATED" = TRAIT_INCAPACITATED,
"TRAIT_FLOORED" = TRAIT_FLOORED,
"TRAIT_DAZED" = TRAIT_DAZED,
"TRAIT_UNDENSE" = TRAIT_UNDENSE,
"TRAIT_YAUTJA_TECH" = TRAIT_YAUTJA_TECH,
"TRAIT_SUPER_STRONG" = TRAIT_SUPER_STRONG,
Expand All @@ -336,6 +339,8 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_VULTURE_USER" = TRAIT_VULTURE_USER,
"TRAIT_CLOAKED" = TRAIT_CLOAKED,
),
// /mob/living/carbon/human = list(
// ),
/mob/living/carbon/xenomorph = list(
"TRAIT_ABILITY_NO_PLASMA_TRANSFER" = TRAIT_ABILITY_NO_PLASMA_TRANSFER,
"TRAIT_ABILITY_OVIPOSITOR" = TRAIT_ABILITY_OVIPOSITOR,
Expand Down Expand Up @@ -411,6 +416,7 @@ GLOBAL_LIST(trait_name_map)
#define TRAIT_SOURCE_ATTACHMENT(slot) "t_s_attachment_[slot]"
///Status trait coming from ability
#define TRAIT_SOURCE_ABILITY(ability) "t_s_ability_[ability]"
#define TRAIT_SOURCE_LIMB(limb) "t_s_limb_[limb]"
///Status trait forced by the xeno action charge
#define TRAIT_SOURCE_XENO_ACTION_CHARGE "t_s_xeno_action_charge"
///Status trait coming from a xeno nest
Expand Down Expand Up @@ -449,6 +455,8 @@ GLOBAL_LIST(trait_name_map)
#define XENO_WEED_TRAIT "xeno_weed"
/// traits associated with actively interacted machinery
#define INTERACTION_TRAIT "interaction"
/// traits associated with interacting with a dropship
#define TRAIT_SOURCE_DROPSHIP_INTERACTION "dropship_interaction"
/// traits bound by stunned status effects
#define STUNNED_TRAIT "stunned"
/// traits bound by knocked_down status effect
Expand Down
18 changes: 9 additions & 9 deletions code/__DEFINES/turf_flags.dm
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
//turf_flags values
/// Marks a turf as organic. Used for alien wall and membranes.
#define TURF_ORGANIC (1<<0)
/// If a turf is an usused reservation turf awaiting assignment
#define UNUSED_RESERVATION_TURF (1<<1)
/// If a turf is a reserved turf
#define RESERVATION_TURF (1<<2)

//ChangeTurf options to change its behavior
#define CHANGETURF_DEFER_CHANGE (1<<0)
/// This flag prevents changeturf from gathering air from nearby turfs to fill the new turf with an approximation of local air
#define CHANGETURF_IGNORE_AIR (1<<1)
#define CHANGETURF_FORCEOP (1<<2)
/// A flag for PlaceOnTop to just instance the new turf instead of calling ChangeTurf. Used for uninitialized turfs NOTHING ELSE
#define CHANGETURF_SKIP (1<<3)

#define IS_OPAQUE_TURF(turf) (turf.directional_opacity == ALL_CARDINALS)

/// Marks a turf as organic. Used for alien wall and membranes.
#define TURF_ORGANIC (1<<0)


#define REMOVE_CROWBAR (1<<0)
#define BREAK_CROWBAR (1<<1)
#define REMOVE_SCREWDRIVER (1<<2)
29 changes: 29 additions & 0 deletions code/__DEFINES/turfs.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#define RANGE_TURFS(RADIUS, CENTER) \
block( \
locate(max(CENTER.x-(RADIUS),1), max(CENTER.y-(RADIUS),1), CENTER.z), \
locate(min(CENTER.x+(RADIUS),world.maxx), min(CENTER.y+(RADIUS),world.maxy), CENTER.z) \
)

#define RECT_TURFS(H_RADIUS, V_RADIUS, CENTER) \
block( \
locate(max((CENTER).x-(H_RADIUS),1), max((CENTER).y-(V_RADIUS),1), (CENTER).z), \
locate(min((CENTER).x+(H_RADIUS),world.maxx), min((CENTER).y+(V_RADIUS),world.maxy), (CENTER).z) \
)

///Returns all turfs in a zlevel
#define Z_TURFS(ZLEVEL) block(locate(1,1,ZLEVEL), locate(world.maxx, world.maxy, ZLEVEL))

/// Returns a list of turfs in the rectangle specified by BOTTOM LEFT corner and height/width, checks for being outside the world border for you
#define CORNER_BLOCK(corner, width, height) CORNER_BLOCK_OFFSET(corner, width, height, 0, 0)

/// Returns a list of turfs similar to CORNER_BLOCK but with offsets
#define CORNER_BLOCK_OFFSET(corner, width, height, offset_x, offset_y) ((block(locate(corner.x + offset_x, corner.y + offset_y, corner.z), locate(min(corner.x + (width - 1) + offset_x, world.maxx), min(corner.y + (height - 1) + offset_y, world.maxy), corner.z))))

/// Returns an outline (neighboring turfs) of the given block
#define CORNER_OUTLINE(corner, width, height) ( \
CORNER_BLOCK_OFFSET(corner, width + 2, 1, -1, -1) + \
CORNER_BLOCK_OFFSET(corner, width + 2, 1, -1, height) + \
CORNER_BLOCK_OFFSET(corner, 1, height, -1, 0) + \
CORNER_BLOCK_OFFSET(corner, 1, height, width, 0))

#define TURF_FROM_COORDS_LIST(List) (locate(List[1], List[2], List[3]))
1 change: 1 addition & 0 deletions code/__DEFINES/typecheck/generic_types.dm
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#define ismovableatom(A) (ismovable(A))
#define isatom(A) (isloc(A))
#define isfloorturf(A) (istype(A, /turf/open/floor))
#define isclosedturf(A) (istype(A, /turf/closed))
#define isweakref(D) (istype(D, /datum/weakref))
#define isgenerator(A) (istype(A, /generator))

Expand Down
2 changes: 2 additions & 0 deletions code/__HELPERS/lighting.dm
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#define IS_OPAQUE_TURF(turf) (turf.directional_opacity == ALL_CARDINALS)

/// Produces a mutable appearance glued to the [EMISSIVE_PLANE] dyed to be the [EMISSIVE_COLOR].
/proc/emissive_appearance(icon, icon_state = "", layer = FLOAT_LAYER, alpha = 255, appearance_flags = NONE)
var/mutable_appearance/appearance = mutable_appearance(icon, icon_state, layer, EMISSIVE_PLANE, alpha, appearance_flags | EMISSIVE_APPEARANCE_FLAGS)
Expand Down
Loading

0 comments on commit 53d49ca

Please sign in to comment.