diff --git a/_maps/map_files/Delta/delta.dmm b/_maps/map_files/Delta/delta.dmm index d1afd4adf84..c5b876c8c3e 100644 --- a/_maps/map_files/Delta/delta.dmm +++ b/_maps/map_files/Delta/delta.dmm @@ -2138,7 +2138,7 @@ "aPf" = (/obj/machinery/alarm{dir = 8; pixel_x = 25; pixel_y = 0},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/security/prison) "aPg" = (/obj/machinery/atmospherics/unary/vent_scrubber{on = 1},/obj/machinery/sparker{pixel_x = -18},/turf/simulated/floor/plasteel{dir = 1; icon_state = "darkredcorners"},/area/security/execution) "aPh" = (/obj/structure/chair,/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 8},/area/security/execution) -"aPi" = (/obj/machinery/atmospherics/unary/vent_pump{on = 1},/obj/machinery/flasher{pixel_x = 22},/turf/simulated/floor/plasteel{dir = 4; icon_state = "darkredcorners"},/area/security/execution) +"aPi" = (/obj/machinery/atmospherics/unary/vent_pump{on = 1},/obj/machinery/flasher{id = "Execution"; pixel_x = 22},/turf/simulated/floor/plasteel{dir = 4; icon_state = "darkredcorners"},/area/security/execution) "aPj" = (/turf/simulated/wall/r_wall/rust,/area/security/execution) "aPk" = (/obj/machinery/door/poddoor{id_tag = "turbinevent"; name = "Turbine Vent"},/turf/simulated/floor/engine,/area/maintenance/incinerator) "aPl" = (/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/power/turbine{dir = 8; luminosity = 2},/obj/structure/sign/vacuum{pixel_y = -32},/turf/simulated/floor/engine,/area/maintenance/incinerator) @@ -2376,7 +2376,7 @@ "aTJ" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/airlock/glass{name = "Prison"},/obj/effect/decal/warning_stripes/south,/turf/simulated/floor/plasteel,/area/security/prison) "aTK" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/airlock/glass{name = "Prison"},/obj/effect/decal/warning_stripes/south,/turf/simulated/floor/plasteel,/area/security/prison) "aTL" = (/obj/machinery/status_display{pixel_y = 32},/obj/machinery/alarm{dir = 4; pixel_x = -23; pixel_y = 0},/obj/structure/table/reinforced,/obj/item/reagent_containers/glass/bottle/morphine,/obj/item/reagent_containers/glass/bottle/morphine{pixel_x = 8},/obj/item/reagent_containers/glass/bottle/facid,/obj/item/storage/backpack/duffel/security,/turf/simulated/floor/plasteel{dir = 9; icon_state = "darkred"},/area/security/execution) -"aTM" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/structure/table/reinforced,/obj/item/folder/red,/obj/item/restraints/handcuffs,/obj/item/taperecorder,/obj/machinery/camera{c_tag = "Prisoner Re-education Centre"; network = list("SS13","Security")},/turf/simulated/floor/plasteel{dir = 1; icon_state = "darkred"},/area/security/execution) +"aTM" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/structure/table/reinforced,/obj/item/folder/red,/obj/item/restraints/handcuffs,/obj/item/taperecorder,/obj/machinery/camera{c_tag = "Prisoner Re-education Centre"; network = list("SS13","Security")},/obj/machinery/flasher_button{id = "Execution"; pixel_x = 0; pixel_y = 27},/turf/simulated/floor/plasteel{dir = 1; icon_state = "darkred"},/area/security/execution) "aTN" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{dir = 1; icon_state = "darkred"},/area/security/execution) "aTO" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor/plasteel{dir = 1; icon_state = "darkred"},/area/security/execution) "aTP" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; level = 1},/obj/structure/closet/secure_closet/injection,/turf/simulated/floor/plasteel{dir = 5; icon_state = "darkred"},/area/security/execution) @@ -2532,10 +2532,10 @@ "aWJ" = (/obj/structure/closet/secure_closet/quartermaster,/obj/structure/sign/poster/official/random{pixel_x = 32},/turf/simulated/floor/plasteel{dir = 4; icon_state = "brown"},/area/quartermaster/qm) "aWK" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/table/glass,/obj/item/storage/firstaid/regular,/turf/simulated/floor/plasteel{dir = 8; icon_state = "whitered"},/area/security/prison) "aWL" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/bed/roller,/obj/machinery/iv_drip,/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitered"},/area/security/prison) -"aWM" = (/obj/machinery/atmospherics/unary/vent_scrubber{on = 1},/obj/machinery/flasher{pixel_x = -22},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{dir = 8; icon_state = "red"},/area/security/prison) +"aWM" = (/obj/machinery/atmospherics/unary/vent_scrubber{on = 1},/obj/machinery/flasher{id = "Cell 1"; pixel_x = -22},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{dir = 8; icon_state = "red"},/area/security/prison) "aWN" = (/obj/machinery/newscaster{pixel_y = -32},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel,/area/security/prison) "aWO" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; level = 1},/obj/structure/table,/obj/item/paper,/obj/item/pen,/turf/simulated/floor/plasteel{dir = 4; icon_state = "red"},/area/security/prison) -"aWP" = (/obj/machinery/atmospherics/unary/vent_scrubber{on = 1},/obj/machinery/flasher{pixel_x = -22},/turf/simulated/floor/plating,/area/security/prison) +"aWP" = (/obj/machinery/atmospherics/unary/vent_scrubber{on = 1},/obj/machinery/flasher{id = "Cell 2"; pixel_x = -22},/turf/simulated/floor/plating,/area/security/prison) "aWQ" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/plasteel{icon_state = "neutral"; dir = 1},/area/security/prison) "aWR" = (/turf/space,/obj/structure/disposalpipe/trunk{dir = 4},/obj/structure/disposaloutlet{dir = 8},/turf/simulated/floor/plating/airless/catwalk,/area/maintenance/incinerator) "aWS" = (/obj/structure/table/reinforced,/obj/item/flashlight/lamp,/obj/item/radio/intercom{dir = 8; name = "station intercom (General)"; pixel_x = -28},/turf/simulated/floor/plasteel{dir = 10; icon_state = "darkred"},/area/security/execution) @@ -2667,7 +2667,7 @@ "aZo" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/turf/simulated/floor/plasteel{dir = 2; icon_state = "brown"},/area/quartermaster/storage) "aZp" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{dir = 2; icon_state = "purple"},/area/quartermaster/storage) "aZq" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/obj/item/twohanded/required/kirbyplants,/turf/simulated/floor/plasteel{dir = 2; icon_state = "brown"},/area/quartermaster/storage) -"aZr" = (/obj/structure/table/reinforced,/obj/effect/decal/warning_stripes/yellow,/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralfull"},/area/quartermaster/office) +"aZr" = (/obj/machinery/atmospherics/unary/vent_scrubber{on = 1},/obj/machinery/flasher{id = "Cell 3"; pixel_x = -22},/turf/simulated/floor/plating,/area/security/prison) "aZs" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/firedoor,/obj/machinery/door/airlock/mining/glass{name = "Cargo Bay"; req_access_txt = "31"},/turf/simulated/floor/plasteel,/area/quartermaster/office) "aZt" = (/obj/structure/cable{d2 = 2; icon_state = "0-2"},/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24; shock_proof = 0},/obj/machinery/camera{c_tag = "Cargo Office SouthWest"; dir = 4; network = list("SS13")},/turf/simulated/floor/plasteel{dir = 8; icon_state = "brown"},/area/quartermaster/storage) "aZu" = (/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers,/turf/simulated/floor/plasteel{dir = 2; icon_state = "brown"},/area/quartermaster/storage) @@ -2689,7 +2689,7 @@ "aZK" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{dir = 2; icon_state = "redcorner"},/area/security/prison) "aZL" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/obj/machinery/status_display{pixel_y = 32},/turf/simulated/floor/plasteel{dir = 2; icon_state = "redcorner"},/area/security/prison) "aZM" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/turf/simulated/floor/plasteel{dir = 2; icon_state = "redcorner"},/area/security/prison) -"aZN" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/turf/simulated/floor/plasteel{dir = 2; icon_state = "redcorner"},/area/security/prison) +"aZN" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/flasher_button{id = "Cell 1"; pixel_x = 0; pixel_y = 27},/turf/simulated/floor/plasteel{dir = 2; icon_state = "redcorner"},/area/security/prison) "aZO" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/obj/machinery/status_display{pixel_y = 32},/turf/simulated/floor/plasteel{dir = 2; icon_state = "redcorner"},/area/security/prison) "aZP" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{dir = 2; icon_state = "redcorner"},/area/security/prison) "aZQ" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{dir = 2; icon_state = "redcorner"},/area/security/prison) @@ -3278,7 +3278,7 @@ "blb" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plasteel{dir = 8; icon_state = "greenblue"},/area/crew_quarters/sleep) "blc" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel,/area/crew_quarters/sleep) "bld" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/turf/simulated/floor/plasteel{dir = 4; icon_state = "red"},/area/crew_quarters/sleep) -"ble" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/table/reinforced,/obj/effect/decal/warning_stripes/yellow,/turf/simulated/floor/plasteel,/area/crew_quarters/kitchen) +"ble" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/obj/machinery/flasher_button{id = "Cell 2"; pixel_x = 0; pixel_y = 27},/turf/simulated/floor/plasteel{dir = 2; icon_state = "redcorner"},/area/security/prison) "blf" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/machinery/firealarm{dir = 1; pixel_y = -24},/obj/effect/decal/warning_stripes/yellow/hollow,/turf/simulated/floor/plasteel,/area/crew_quarters/kitchen) "blg" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/foodcart,/obj/effect/decal/warning_stripes/yellow,/turf/simulated/floor/plasteel,/area/crew_quarters/kitchen) "blh" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/obj/machinery/light,/obj/machinery/vending/dinnerware,/obj/machinery/status_display{pixel_y = -32},/obj/effect/decal/warning_stripes/yellow,/turf/simulated/floor/plasteel,/area/crew_quarters/kitchen) @@ -4784,7 +4784,7 @@ "bNZ" = (/obj/machinery/computer/atmos_alert,/obj/machinery/camera{c_tag = "Chief Engineer's Office"; dir = 4; network = list("Engineering","SS13"); pixel_y = -22},/obj/machinery/requests_console{announcementConsole = 1; department = "Chief Engineer's Desk"; departmentType = 7; name = "Chief Engineer Requests Console"; pixel_x = -32; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/crew_quarters/chief) "bOa" = (/turf/simulated/floor/plasteel{icon_state = "neutral"; dir = 4},/area/crew_quarters/chief) "bOb" = (/obj/structure/chair/office/dark{dir = 4},/obj/effect/landmark/start{name = "Chief Engineer"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralfull"},/area/crew_quarters/chief) -"bOc" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/structure/table/reinforced,/obj/item/folder/blue,/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralfull"},/area/crew_quarters/chief) +"bOc" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/flasher_button{id = "Cell 3"; pixel_x = 0; pixel_y = 27},/turf/simulated/floor/plasteel{dir = 2; icon_state = "redcorner"},/area/security/prison) "bOd" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutral"},/area/crew_quarters/chief) "bOe" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/light{dir = 4; icon_state = "tube1"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/crew_quarters/chief) "bOf" = (/obj/structure/sign/electricshock,/turf/simulated/wall/r_wall,/area/crew_quarters/chief) @@ -4887,10 +4887,10 @@ "bPY" = (/obj/structure/table/reinforced,/obj/machinery/cell_charger,/obj/item/stock_parts/cell/high,/obj/effect/decal/warning_stripes/yellow/hollow,/turf/simulated/floor/plasteel,/area/storage/primary) "bPZ" = (/obj/structure/table/reinforced,/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/item/radio,/obj/item/radio,/obj/item/radio,/obj/machinery/firealarm{dir = 1; pixel_y = -24},/obj/machinery/light_switch{pixel_x = 24; pixel_y = 0},/obj/effect/decal/warning_stripes/yellow/hollow,/turf/simulated/floor/plasteel,/area/storage/primary) "bQa" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/maintenance{name = "Mining Maintenance"; req_access_txt = "48"},/turf/simulated/floor/plasteel,/area/maintenance/starboard) -"bQb" = (/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plating,/area/engine/break_room) -"bQc" = (/obj/machinery/door/airlock/hatch{name = "MiniSat Transit Tube"; req_one_access_txt = "32;19"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/engine/break_room) -"bQd" = (/obj/effect/spawner/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/engine/break_room) -"bQe" = (/obj/machinery/modular_computer/console/preset/engineering,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/keycard_auth{pixel_x = -24},/obj/machinery/door_control{id = "engstorage"; name = "Engineering Secure Storage Control"; pixel_x = -38; pixel_y = 8; req_access_txt = "11"},/obj/machinery/door_control{id = "transitlock"; name = "Transit Tube Lockdown Control"; pixel_x = -38; pixel_y = -8; req_access_txt = "11"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/crew_quarters/chief) +"bQb" = (/obj/structure/table/reinforced,/obj/effect/decal/warning_stripes/yellow,/obj/machinery/door/window/westleft{dir = 1; name = "Cargo Bay Desk"; req_access_txt = "31"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralfull"},/area/quartermaster/office) +"bQc" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/table/reinforced,/obj/effect/decal/warning_stripes/yellow,/obj/machinery/door/window/eastleft{dir = 4; name = "Kitchen Desk"; req_access_txt = "28"},/turf/simulated/floor/plasteel,/area/crew_quarters/kitchen) +"bQd" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/structure/table/reinforced,/obj/item/folder/blue,/obj/item/stamp/ce,/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralfull"},/area/crew_quarters/chief) +"bQe" = (/obj/machinery/door/airlock/hatch{name = "MiniSat Transit Tube"; req_one_access_txt = "32;19"},/obj/machinery/door/poddoor{icon_state = "open"; id_tag = "transitlock"; name = "Transit Tube Blast Doors"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/engine/break_room) "bQf" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plasteel{icon_state = "neutral"; dir = 4},/area/crew_quarters/chief) "bQg" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; level = 1},/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/effect/decal/warning_stripes/yellow,/turf/simulated/floor/plasteel,/area/maintenance/starboard) "bQh" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/table/reinforced,/obj/item/clipboard,/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/item/toy/figure/ce,/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralfull"},/area/crew_quarters/chief) @@ -4995,7 +4995,7 @@ "bSc" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plasteel{icon_state = "grimy"},/area/crew_quarters/chief) "bSd" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/effect/landmark/start{name = "Chief Engineer"},/turf/simulated/floor/plasteel{icon_state = "grimy"},/area/crew_quarters/chief) "bSe" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass,/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralfull"},/area/storage/primary) -"bSf" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/crew_quarters/chief) +"bSf" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/poddoor{icon_state = "open"; id_tag = "transitlock"; name = "Transit Tube Blast Doors"},/turf/simulated/floor/plating,/area/engine/break_room) "bSg" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor,/obj/effect/decal/warning_stripes/yellow,/turf/simulated/floor/plasteel{dir = 1; icon_state = "neutralcorner"},/area/hallway/primary/central) "bSh" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/obj/item/radio/beacon,/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralfull"},/area/engine/engineering) "bSi" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/firedoor,/obj/effect/decal/warning_stripes/yellow,/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralfull"},/area/hallway/primary/central) @@ -5135,7 +5135,7 @@ "bUM" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/light{dir = 4; icon_state = "tube1"},/turf/simulated/floor/plasteel{icon_state = "neutralcorner"; dir = 2},/area/hallway/primary/central) "bUN" = (/obj/machinery/ai_status_display,/turf/simulated/wall,/area/hallway/primary/central) "bUO" = (/obj/structure/table/reinforced,/obj/item/paper_bin,/obj/item/pen,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/hallway/primary/central) -"bUP" = (/obj/structure/table/wood,/obj/item/radio/intercom{pixel_y = 26},/obj/machinery/computer/med_data/laptop,/obj/machinery/flasher_button{pixel_x = -38; pixel_y = -6},/obj/machinery/light_switch{pixel_x = -37; pixel_y = 7},/obj/machinery/door_control{id = "hopprivacy"; name = "Privacy Shutters"; pixel_x = -24; pixel_y = -6; req_one_access_txt = "18"},/obj/machinery/door_control{id = "hopqueueshutters"; name = "Queue Shutters"; pixel_x = -24; pixel_y = 6; req_one_access_txt = "18"},/turf/simulated/floor/plasteel{dir = 5; icon_state = "dark"; tag = "icon-vault (NORTHEAST)"},/area/crew_quarters/heads/hop) +"bUP" = (/obj/effect/spawner/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/poddoor{icon_state = "open"; id_tag = "transitlock"; name = "Transit Tube Blast Doors"},/turf/simulated/floor/plating,/area/engine/break_room) "bUQ" = (/obj/structure/table/wood,/obj/machinery/requests_console{announcementConsole = 1; department = "Head of Personnel's Desk"; departmentType = 5; name = "Head of Personnel Requests Console"; pixel_y = 30},/obj/item/paper_bin,/obj/item/stamp/hop,/turf/simulated/floor/plasteel{icon_state = "wood"},/area/crew_quarters/heads/hop) "bUR" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/item/twohanded/required/kirbyplants,/turf/simulated/floor/plasteel{icon_state = "wood"},/area/crew_quarters/heads/hop) "bUS" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "wood"},/area/crew_quarters/heads/hop) @@ -5209,7 +5209,7 @@ "bWi" = (/obj/item/radio/intercom{dir = 1; name = "Station Intercom (General)"; pixel_y = -29},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 8},/area/engine/break_room) "bWj" = (/obj/structure/table/reinforced,/obj/item/stack/packageWrap,/obj/item/hand_labeler,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/crew_quarters/chief) "bWk" = (/obj/structure/table/reinforced,/obj/machinery/alarm{dir = 1; pixel_y = -24},/obj/machinery/photocopier/faxmachine{department = "Chief Engineer's Office"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/crew_quarters/chief) -"bWl" = (/obj/structure/rack,/obj/machinery/newscaster{pixel_y = -32},/obj/item/storage/secure/briefcase,/obj/item/clothing/shoes/magboots/advance,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/crew_quarters/chief) +"bWl" = (/obj/machinery/modular_computer/console/preset/engineering,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/keycard_auth{pixel_x = -24},/obj/machinery/door_control{id = "engstorage"; name = "Engineering Secure Storage Control"; pixel_x = -38; pixel_y = 8; range = 100; req_access_txt = "11"},/obj/machinery/door_control{id = "transitlock"; name = "Transit Tube Lockdown Control"; pixel_x = -38; pixel_y = -8; req_access_txt = "11"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/crew_quarters/chief) "bWm" = (/obj/structure/cable,/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/crew_quarters/chief) "bWn" = (/obj/machinery/photocopier,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/crew_quarters/chief) "bWo" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id_tag = "ceprivacy"; name = "CE Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/crew_quarters/chief) @@ -5448,7 +5448,7 @@ "caN" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8; initialize_directions = 11; level = 1},/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/machinery/light{dir = 8},/turf/simulated/floor/plasteel,/area/security/brig) "caO" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/unary/vent_pump{dir = 8; external_pressure_bound = 100; on = 1; pressure_checks = 1},/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralfull"},/area/security/brig) "caP" = (/obj/structure/cable,/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/obj/machinery/camera{c_tag = "Security Armory"; dir = 1; network = list("SS13","Security")},/obj/effect/decal/warning_stripes/east,/turf/simulated/floor/plasteel,/area/security/armoury) -"caQ" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/table/reinforced,/obj/item/folder/red,/obj/item/pen,/obj/effect/decal/warning_stripes/yellow,/turf/simulated/floor/plasteel{dir = 2; icon_state = "redfull"; tag = "icon-redfull (NORTHWEST)"},/area/security/warden) +"caQ" = (/obj/structure/table/wood,/obj/item/radio/intercom{pixel_y = 26},/obj/machinery/computer/med_data/laptop,/obj/machinery/flasher_button{id = "hopflash"; pixel_x = -38; pixel_y = -6},/obj/machinery/light_switch{pixel_x = -37; pixel_y = 7},/obj/machinery/door_control{id = "hopprivacy"; name = "Privacy Shutters"; pixel_x = -24; pixel_y = -6; req_one_access_txt = "18"},/obj/machinery/door_control{id = "hopqueueshutters"; name = "Queue Shutters"; pixel_x = -24; pixel_y = 6; req_one_access_txt = "18"},/turf/simulated/floor/plasteel{dir = 5; icon_state = "dark"; tag = "icon-vault (NORTHEAST)"},/area/crew_quarters/heads/hop) "caR" = (/obj/machinery/door/poddoor/shutters{dir = 2; id_tag = "Secure Armory"; name = "Secure Armory Shutters"},/obj/effect/decal/warning_stripes/north,/obj/effect/decal/warning_stripes/south,/turf/simulated/floor/plasteel,/area/security/armoury) "caS" = (/obj/structure/table/reinforced,/obj/item/folder/red,/obj/item/pen,/obj/machinery/door/window/brigdoor{dir = 2; name = "Secure Armory"; req_access_txt = "3"},/obj/machinery/door/window/brigdoor{dir = 1; name = "Secure Armory"; req_access_txt = "3"},/obj/effect/decal/warning_stripes/yellow,/turf/simulated/floor/plasteel,/area/security/armoury) "caT" = (/obj/machinery/ai_status_display,/turf/simulated/wall/r_wall,/area/turret_protected/ai_upload) @@ -10757,6 +10757,8 @@ "dYS" = (/turf/space,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor/plating/airless/catwalk,/area/maintenance/portsolar) "dYT" = (/turf/simulated/floor/carpet,/area/chapel/office) "dYU" = (/obj/structure/table/wood,/obj/item/storage/fancy/crayons,/obj/machinery/camera{c_tag = "Chaplain's Office"; dir = 1; network = list("SS13")},/obj/machinery/requests_console{department = "Chapel"; departmentType = 2; name = "Chapel Requests Console"; pixel_y = -30},/turf/simulated/floor/carpet,/area/chapel/office) +"dYV" = (/obj/structure/rack,/obj/machinery/newscaster{pixel_y = -32},/obj/item/storage/secure/briefcase,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/crew_quarters/chief) +"dYW" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/table/reinforced,/obj/item/folder/red,/obj/item/pen,/obj/effect/decal/warning_stripes/yellow,/obj/machinery/door/window/brigdoor{dir = 2; name = "Warden's Desk"; req_access_txt = "3"},/obj/machinery/door/window/brigdoor{dir = 1; name = "Warden's Desk"; req_access_txt = "3"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "redfull"; tag = "icon-redfull (NORTHWEST)"},/area/security/warden) (1,1,1) = {" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -10850,17 +10852,17 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacFabjaNTaMyaMyaQMaQNaQOaQNaQPaQQaQRaObaQSaQTaQUaQVaQWaQXaQYaQZaUMaQZaRbaRcaRdaTTaReaRfaRgaRhaRiaPHaOgabjabjabjabjabjabjaEpalIawZaMYaRjaRkaRlaRmaRnaRoaMWaMZaOwaRpaRqaRraRqaOnaRsaRtaRvaLUaRwaRxaPXaRyaRzaRAaNiaRBaRCaRDaREaRFaRGaXRaRIaRJaRKaGKaRLaRMaRNaROaGKaRPaMbaRQaRRaRSaRTaRUaRVazLaRWaRXaRVazLazLaRYaRZaSaaSaaSaaSbaScaSdaSeaSbaSfaSgaSgaSgabjaaaabjaaaaaaaaaaaaaaaaaaabjaGTaShaSiaSjaGTaSkaSlaSmaWNaSoaSpaQEaTbaSraQFaSsaPjaMvaMvaStaSuaSvaMvaMvaMvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacFacFaWRaSxaMyaSyaMyaMyaMyaGZaSzaGZaOgaSAaSBaSCaSDaSEaSDaSFaSDaSDaSDaSGaSDaSDaSHaSIaSDaSDaSJaSKaSLaOgaSMaSNaSNaSNaSNaSNaJzalIawZaSOaSPaSPaRmaSQaSRaRmaSOaRuaSSaSUaSTaSWaSXaSVaSYaSZaTaaTcaTdaTeaTgaTfaRzaRAaNiaNiaNiaThaNiaNiaNiaZfaBCaTjaCzaGKaGKaJdaJeaTlaGKaTmaTnaToaNvaTqaTnaZtaTsaTtaDUaTuaBSaTvaTwaTxaSaaTyaTzaTAaTBaTCaTDaTEaSbaSfaSgaSgaSgabjabjabjabjabjabjabiabiabiabjaGTaTFaTGaTHaGTaMqaTIaMqaMqaMqaTJaMqaMqaMqaTKaMqaMvaTLaTMaTNaTOaTPaTQaTRaMvbaOabjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabjaaaabjaTSaZYaTUaZYaTUaZYaTUbaaabjaOgaTWaTXaTYaTZaUaaTZaUbaTZaTZaTZaUcaTZaTZaUdaUeaTZaTZaUfaUgaUhaUibaNaUkaUlaUmaUnaSNaEpamhalZaXeaUpaRmaUqaUraUsaUtaUuaUvaUwaUxaUyaUzaUyaUAaUBaUCaUDaUEaUFaUGaPWaUHaRzaRAaNiaLRaUIaUJaUIaUKaULbcwaDJaCyaCzaGKaUNaUOaUPaUQaURaUSaUTaUUaUVaUWayDaUXaUYaUZaDUaTuaBSaUZaVaaVbaVcaVdaVeaVfaVgaVhaViaVjaSbaSfaSfaSgaSfaaaabjaaaaaaabjaaaaaaaaaabjaaaaGTaVkaTGaVlaGUaVmaVnaVoaMqaVmaVpaVqaMqaVraVsaVtaMvaVuaVvaVwaVxaVyaVzaVAaPjaVBaMqaaaabiabiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabjabjabiaaaabiabjaSNaSNaSNaSNaSNaSMaOgaVCaVDaVEaVFaVGaVFaVHaVIaVJaVIaVKaVIaVLaVMaVNaVOaVFaVPbcyaPHaObaSMaVRaVSaVTaVUaSNaJzamhalZaMWaOsaVVaRoaVWaVXaOsaMWaOvaOwaVYaVZaWaaWbaWcaOxaOyaWdaLUaWeaWfaPWaPWaRzaPZaNiaLSaWgaWhaWiaWjaNiaOHaBCaWkaTkaWmaWnaWoaWpaWqaWraWraWsaWraWsaWtbaiaWvaWwaWxaWybbhaWAaWAaWAaWBbbjaWDaWEaWFbbkaWHaWIaWJaSbaSfaSfaSgaSfaaaabjaaaaaaabjaaaaaaaaaabjaaaaGTaWKaTGaWLaGTaWMbaPaWOaMqaWPaWQaWOaMqaWPbaSaWOaMvaWSaWTaWUaWVaWWaWXaWYaPjaWZaMqabjabjabjabjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabjabjabiaaaabiabjaSNaSNaSNaSNaSNaSMaOgaVCaVDaVEaVFaVGaVFaVHaVIaVJaVIaVKaVIaVLaVMaVNaVOaVFaVPbcyaPHaObaSMaVRaVSaVTaVUaSNaJzamhalZaMWaOsaVVaRoaVWaVXaOsaMWaOvaOwaVYaVZaWaaWbaWcaOxaOyaWdaLUaWeaWfaPWaPWaRzaPZaNiaLSaWgaWhaWiaWjaNiaOHaBCaWkaTkaWmaWnaWoaWpaWqaWraWraWsaWraWsaWtbaiaWvaWwaWxaWybbhaWAaWAaWAaWBbbjaWDaWEaWFbbkaWHaWIaWJaSbaSfaSfaSgaSfaaaabjaaaaaaabjaaaaaaaaaabjaaaaGTaWKaTGaWLaGTaWMbaPaWOaMqaWPaWQaWOaMqaZrbaSaWOaMvaWSaWTaWUaWVaWWaWXaWYaPjaWZaMqabjabjabjabjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabjabjabjabiabjaSNaXaaXbaXcaXdbbFaXfaXgaXhaXiaXjaXkaXlaXmaXnaXoaObaXpaObaXoaXqaXraXsaXtaXuaXvaXwaUibaNaUkaXxaUnaUnaSNaEpamhambaMWaMYaMWaMWaMWaMXaMWaMWaXyaOwaOxaOxaOxaOxaOxaOxaXzaXAaLUaXBaXCaXDaXEaXFaXGaXHaNiaLRaLRaLRaXIaNiaOHaBCaXJaWlaXKaXLaXNaXOaXPaXQaXMaXSaXQaXQaXTbcIaXVaXWaXXaXYaXZaYaaYbaYcaYdaYeaYfaYgaYgaYhaYiaViaYjaSbaSfaSgaSgaSgabjabjabjabjabjabjabjaGTaGTaGTaGTaYkaYlaYmaGTaYnaYoaMqaMqaYnaYpaMqaMqaYnaYqaMqaGTaGTaYraYsaGTaGTaGTaGTaGTaZVaMqaMqaMqaMqaMqaGTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaZaaaaaaaaaabjaaaabiaaaaSNaYuaYvaYwaVRaSMaObaTWaYxaYyaYzaYAaYBaYCaYDaYEaYFaYGaYHaXoaYIaYJaXsaYKaYLaYMaYNaYOaSMaSNaSNaSNaSNaSNaJzalIambaBoaqlaYPaCoaYQaYRawgaYSaYTaYUavOalLaEyauVaYVaYWaYXaYYaYZaZaaYZaYZaYZaYZaYZaZbaNiaNiaNiaNiaNiaZcaLUaZdaZeaEFaJdaZgaZhaZiaZjaZjaZjaZkaZjaZjaZlaZmaZnaZoaZpaZqbcJbcKbcLaZuaZvaZwaZxaZyaZzaZAaZBaZCaZDaSbaSfaSgaSgaSgabjaaaaaaaaaabjaaaaaaaGVaZEaZFaZGaZHaZIaZJaZKaZLaZMaZKaZNaZOaZPaZQaZKaZRaZSaZKaZKaZTaZPaZUaZWaZXbadaZWbdabrzbfSbabbacbprbaebaebafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaZaaaaaaaaaabjaaaabiaaaaSNaYuaYvaYwaVRaSMaObaTWaYxaYyaYzaYAaYBaYCaYDaYEaYFaYGaYHaXoaYIaYJaXsaYKaYLaYMaYNaYOaSMaSNaSNaSNaSNaSNaJzalIambaBoaqlaYPaCoaYQaYRawgaYSaYTaYUavOalLaEyauVaYVaYWaYXaYYaYZaZaaYZaYZaYZaYZaYZaZbaNiaNiaNiaNiaNiaZcaLUaZdaZeaEFaJdaZgaZhaZiaZjaZjaZjaZkaZjaZjaZlaZmaZnaZoaZpaZqbcJbcKbcLaZuaZvaZwaZxaZyaZzaZAaZBaZCaZDaSbaSfaSgaSgaSgabjaaaaaaaaaabjaaaaaaaGVaZEaZFaZGaZHaZIaZJaZNaZLaZMaZKbleaZOaZPaZQbOcaZRaZSaZKaZKaZTaZPaZUaZWaZXbadaZWbdabrzbfSbabbacbprbaebaebafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabiabjabiabjaSNaXaaXabagbahbuXbajbakbalaYybamaYAbanbaobapaObbaqbarbasaObbatbaubavbawaXubaxbayaXfbbFaXdbazbaAbaBaSNaEpamhaqFbaCbaDalZalZaOvbaEbaFbaGbaHbaIbaJbaJbaJbaJbaJaHFbaKbaLaYZbaMbaQbcsbctbcuaYZbaRaTpaTpaNiaVQbRqbaTaLUbaUaCyaCzaGKbaVbaWbaXbaYbaZbaYbbabbbbbcbbdbbebbfbbgbcObbibbebbebbebelbeyaSbbblaSaaSbaSbaScbbmaSeaSbabjabjabjabjabjaaaaaaaaaabjaaaaaabbnbbobbpbbqbbrbbsbbtbbubbubbvbbubbwbbxbbvbbybbubbsbbvbbzbbubbsbbvbbAbbBbbDbbHbbBbbEbvBbbGbcWbbGbbIbbJbbKbbLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabiaaaabiabjaSNaSNaSNaSNaSNaSMaYObbMbbNaYybambbObbPbbQbapaObbbRbbSbbTaObbbUaYJbbVaYKbbWbbXaPHaObaSMaVRbbYbbZbcaaSNaJzamhaqFbcbanyanyalZaOvbaEbccbcdbcebcfbcgbchbcibcjbckaFxbclbcmbcnbcobcpbcqbcrbcvaYZaZabcxbdTaYZbflbfoaZaaYZbfpbgwbgxaGKaGKbcAaZsaJdaGKaJdaJdaJdaZraGKbbebcDbcEbcFbcGbcHbbebfwbfCbfMbfNbfNbfNbgMbgVbgWbcPabjaaaaaabcQbcRbcSbcRbcTacFabjabjaaaaaaaGTbcUbcVaGTbcXaGVbdiaGTaGTaGTaGUbcYbcZbfTaMqbdbbdcbddaGTaJwbdeaJCaGTaGTaGTaGUaGTbdfbdgbdhbabbbGbwObaebaebdjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabiaaaabiabjaSNaSNaSNaSNaSNaSMaYObbMbbNaYybambbObbPbbQbapaObbbRbbSbbTaObbbUaYJbbVaYKbbWbbXaPHaObaSMaVRbbYbbZbcaaSNaJzamhaqFbcbanyanyalZaOvbaEbccbcdbcebcfbcgbchbcibcjbckaFxbclbcmbcnbcobcpbcqbcrbcvaYZaZabcxbdTaYZbflbfoaZaaYZbfpbgwbgxaGKaGKbcAaZsaJdaGKaJdaJdaJdbQbaGKbbebcDbcEbcFbcGbcHbbebfwbfCbfMbfNbfNbfNbgMbgVbgWbcPabjaaaaaabcQbcRbcSbcRbcTacFabjabjaaaaaaaGTbcUbcVaGTbcXaGVbdiaGTaGTaGTaGUbcYbcZbfTaMqbdbbdcbddaGTaJwbdeaJCaGTaGTaGTaGUaGTbdfbdgbdhbabbbGbwObaebaebdjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabiabjabjabjaSNbdkbdlbdmaXdbbFaXfaXgbdnbdobamaYAbanbdpbapaObbdqbdrbdsaObbataYJaXsaYKbbWbdtbdubajbuXbahbdvbaBbaBaSNaEpamhaqFalZambaqlalZaMZbaEbdwbdxbdybdzbdAbdBbdCbdDbdEbdFbdGbdHbdIbdJbdKbdLbdMbczaYZbdNbdPbdQbdRbdQbdSbdOaYZaBCaCyaCzbdUbdVbdWbdXbdYbbCbcBbcBbcBbcCbcMbbibedbeebefbegbehbbibeibejbekbhZbifbhZbembenbeobepbeqberbesbetbeubevbewbetacFaaaabjabjbexbexbexbexaGTbezbeAbeBaGTbfUbeCaGTaGTbeDaGTaGTaGTbeDaGUaGTaaaabjaaaabjabjabjabjaMqaMqbeDaMqaMqaMqaMqaMqaGTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabiaaaabiaaaaSNbeEbeFbeGaVRaSMaObaTWbeHaYybeIbeJbanbeJbeKaXobeLbeMbeNaXobeOaYJaXsaYKbePbeQbeRaYOaSMaSNaSNaSNaSNaSNaJzalIambambbeSalIawZaMZbaEbeTbeUbeVbeWbeXbeYbeZbeUbfabfbbfcbfdaYZbfebffbfgbfhbfiaYZbfjbdQbfkbgvbfmbfnbdSbgIaBCaCybhMbfqbfrbfsbftbfubfubfvbfubfubfubcCbinbfxbfybfzbfAbfBbiobfDbfEbfFbfGbfHbfIbfJbfKbfLbbiblCblDbfObcSbfPbfQbfPbcSacFaaaabjaaabexbfRbhcbisaGTbfVbfWbfXbfYbhebfZaJCaaaabjaaaabjaaaabjaaaabjabjabjabjabjaaaaaaaaaabjaaaaaaaaaabjaaaabjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabiabjabiabjaSNbdkbdkbgabahbuXbajbakbgbaYyaYJbgcbanbgdaXqaXobgebgfaObaXoaXnaXraXsbggbghbgibgjaXfbbFaXdbgkbglbgmaSNaEpamhalZbgnbgoareawZaOvbaEbaFbgpbaFbgqbaEbaFbaFbaFbaFaFxbgrbgsaYZbgtaYZbguaYZaYZaYZbgybdPbgAbgBbhNbdSbfnbgIaBCbgzbhYbjzbgCbgDbcNbdZbgGbeabdZbgGbgGbebbgJbgKbgLblEbgNbgObgJbgPbgQbgRbfAbgSbgSbgSbgTbgUblGblHblIblGbgYbfPbfPbfPbgZacFabjabjaaabhabhbblpbhdbexbhgbhfbkgbhhbhhbhibhhbhhbhhbhibhhbhhbhhbhhabjaaaabjaaaabjabjabjabjabjabjabjabjabiaaaabjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabjaaaabiabjaSNaSNaSNaSNaSNaSMaYOaVCbbNaYyaYJaXkbhjaYAbhkbhlbhmbhnbhkbhobhkaYJaXsbanbhpbhqbhraObaSMaVRbhsbhtbhuaSNaJzamhawZbgnanyaqpambaMZbaEbhvbhwbhxbhybhzbhAbhBbhCbhDbhEbhFbhGbhHbhIbdQbhJbdQbdPbhKbhLbdQbhQbhRblibfnbdSbgIbhObhPblqblrbhSbhTbecbgEbhWbgFbgHbhWbhWbgHblJbiabibbicbidbieblKbigbihbiibijbikbilbilbilbimbbiblLblMbipbcSbfQbfQbfQbcSacFaaaabjaaabiqbirbqwbtGbitbiubivbiwbhhbixbiybizbiAbiBbiCbiDbiEbiFbiGbiGbiHbiIbiJbiGbiGaaaaaaabjaaaaaaaaaabiaaaabiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabiabiabiabiabjabiabiabiabiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabiabjabiabjaSNbiKbiLbiMaXdbbFaXfaXgbiNbdoaYJbiObiPbiQbanbiRaYJbiSbiTbiTbiUbiVbiWbiXbiYbiZbjabajbuXbahbjbbgmbgmaSNaEpamhaqFambanybjcaqFbjdbaEbjebjfbdxbjgbjhbjibjjbjkbjlbjmbjnbjobjpbjqbjrbjsbjtbjubjvbjubjvbjubjwbjubjxbjybnbbjAbjBbhMbfqbjCbfubjDbjEbfubftbfubfubfubjFbbibjGbjHbfybjIbjJbbibjKbjLbjMbjNbjObjPbjQbjRbjSbjTbeqberbjUbetbjVbjWbjXbetacFaaaabjaaabjYbjZbkabkbbkcbkdbkebkfbhibmObkhbkibkibkjbkkbklbkmbknbiGbkobkpbkqbkrbksbiGbiGbiGbiGbiGbiGaaaabiaaaabiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabiaaabktbkubktbkubktaaaabiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabiaaaabiaaaaSNbkvbkwbkxaVRaSMaObaTWbkybkzbkAbkBbkBbkCbkDbkEbkFbkGbkHbkIbkJbkKbkLbkMbkNbkObkPaOgbkQaSNaSNaSNaSNaSNaJzalIbkRaCoaqlambambbjdbaEbkSbkTbkUbkVbkWbkXbkYbkZblablbblcbldbleblfblgblhbljblkbllblmbloblnbncbnebQybQyaYZaBCaCybSBbdUblsbltblublvblwblxblublyblzblAbbeblBblNbnfbnhblFbbebniboDboFbsCbbebxybHGbJsbMnblOabjaaaaaablPbcRblQbcRblRaaaabjabjabjbexblSblTblUbjYblVblWblXblYblZbmabmbbmcbmdbmebklbkmbmfbmgbmhbmhbmibmhbmhbmjbmkbmlbmmbmnbiGabjabjabjabiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabiaaabktbkubktbkubktaaaabiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabiaaaabiaaaaSNbkvbkwbkxaVRaSMaObaTWbkybkzbkAbkBbkBbkCbkDbkEbkFbkGbkHbkIbkJbkKbkLbkMbkNbkObkPaOgbkQaSNaSNaSNaSNaSNaJzalIbkRaCoaqlambambbjdbaEbkSbkTbkUbkVbkWbkXbkYbkZblablbblcbldbQcblfblgblhbljblkbllblmbloblnbncbnebQybQyaYZaBCaCybSBbdUblsbltblublvblwblxblublyblzblAbbeblBblNbnfbnhblFbbebniboDboFbsCbbebxybHGbJsbMnblOabjaaaaaablPbcRblQbcRblRaaaabjabjabjbexblSblTblUbjYblVblWblXblYblZbmabmbbmcbmdbmebklbkmbmfbmgbmhbmhbmibmhbmhbmjbmkbmlbmmbmnbiGabjabjabjabiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabjabjabiabiabiabjabiabibmobmpbmqbmqbmqbmrbmsabiabiabjabiabiabiabiabiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabiabjabjabjaSNbiKbiKbmtbahbuXbajbakbmubmvbmwbmxbmybmzbmAbmBbmCbmDbmEbmFbmGbmHbmIbmJbmKbmLbmMbmNaOWaOWaOoaOWaOoaOWbRmalIaqlalZaqpbmPaqFaEubaEbmQbkTbmRbkUbmSbmTbmUbmVbaFbmWbmXbmYaYZaYZaYZaYZaYZaYZbmZbmZbmZaZabmZbmZbmZaYZbnabyNbMabMbbndbfqbfqbhUbhVbdUbhXbhUbfqbfqbdUbbebbebbibNBbbibbebbebngbNCbQabngbngbngbngbngbnjbnkabjaaaaaaaaaaaaaaaaaaaaaabjbnlbnmbnnbnobnobnobnobnobnpbnqbnrbnsbntbnubnvbnwbnxbnybnzbnAbnBbnCbnDbnEbnFbnGbnHbnIbnJbnHbnKbnLbmgaaaabiaaaabiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabiaaabkubktbktbkubktbkubnMbnNbnObnPbnObnQbnRbkubktbktbktbktbkuaaaabiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabiaaaabiabjaSNaSNaSNaSNaSNaSMaOgbnSbnTaUibnUaUibnVbnWaObbnXaYKbnYbnZboabobbocbodboeaOgaOgaOgaOgaOgalIalIalIalIalIalIalIaqFalZarealIaqFaMZbaEbofbkTbkUbogbohboibmUbojbokbolbombonbooboobooboobopboobooboqbooborboobooboobooboobosbotboubovbovbovbovbowbgXbouboxbovbovboybozboybovboAbovboBboCboKboEbQgboGboGboHboIbngabjabjabjaaaaaaaaaaaaaaaaaaaaaabjboJboWboLboMboNboOboPboQboRboSbkfbhiboTboUboVbmdbqJboXboYboZbpabpbbpcbpdbpebpfbpgbphbpibpjbpjbpkbplabjabiaaaabiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabibpmbpnbpobpobpobpobpobpobppbpqbvvbpqbpsbpobpobpobpobpobpobptbpuabiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabiabjabiabjaSNbpvbpwbpxbahbuXbajbpybpzbpAbpBbpCbpDbpEbpFbpGbpHbpIbpJbpKbpLbpMbpNbpObpPbpQbpRbpSbpTbpUbpVbpWbpXbpYbpZbqabqbbqcbqdbqebqfbqgbaEbqhbkTbkUbqibqjbkUbmUbqkbqlbqmbqnbqobqpbqpbqpbqpbqpbqpbqpbqqbqpbqrbqpbqpbqpbqpbqpbqsbqtbqubqubqubqubqubqvdxVbqubqxbqubqubqubqubqubqubqvbqybqzbqAbngbngbngbqBbqCbqCbngbngaaaaaaabjaaabqDbqEbqFbqGbqHaaabqIbnobqLbqKbqMbqNbrubqObqPbqQbqRbqSbqTbqUbqVbqWbqXbqYbqZbrabrbbrcbrdbrebrfbrgbrhbribrjbrkbrlbrmbrnbroaaaabiabjabjaaaaaaaaaaaaaaZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -10878,13 +10880,13 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabiabiabjabibpmbz aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabiaaabktbkubnMbzubpubtdbtdbzDbIgbIhbBfbIibIjbIkbIlbImbInbIobtdbtdbpmbzubnRbkubktaaaabiabjabjabjabjabjabjabjabjabjabjabjabjabjaaaaaaabjaaaaaaabjaaaabjaaaabiabjbwNbwNbwNbwNbwNbwNbwNbwNbwNbwNbwNbwNbLXbwTbGzbIqbIrbIsbItbIubIvbIwbKibKjbIzbEWbIAbEXbIBbICbHhbIEbIFbIGbIDbIHbIIbIKbILbIMbFhbrWbINbDFbIJbIPbIObBTbIRbxhapUbBVbIQbFnbFobHbbISbFobIUbITbIVcusbvabIXbHjbIYbIZbJabJbbJcbJdbJebJfbJgbHjbJhbJhbJhbJhbJhbJibJhbJhbJhbJhbJhbHxbJjbJkbJlbJmbJnbJobJpbJqbJrbHxbuZbvabvbbngbngbngbxxbngbqCbqCbJtbJubJvbJwbJxbJybJxbJzbJAbJBbJCbJDbFSbJEbJFbHUbGabJGbJHbJIbEubJJbJKbExbJLbJMbGpbJNbJNbJNbJNbJNbJNbJNabjabjabjabjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabibmobJObJPbJPbJQbmsbtdbzvbJRbBfbJSbJTbJTbJUbJVbJTbJWbBfbzwbzvbtdbmobJXbJPbJPbJYbnRbkuaaaaaaabjaaaaaaabjaaaaaaaaaabjaaaaaaabjaaaaaaabjaaaaaaabjaaZabiabjabiabjabjabjabjabjabjabjabjabjbwPbJZbylbKabKbbKcbGzbKdbKebKfbKfbKgbKhbKkbKCbLWbKlbKmbKnbKobKpbKqbEWbIAbKrbKsbKtbIWbKvbKwbKxbIMbFhbrWbKybDFbKubIPbKzbBTbKBbxhapUbBVbKAbFnbFobKDbFobFobFqbFrbDQbDRbvabIXbKEbKFbKGbKIbKHbKKbKJbKLbKMbKNbKObJhbKPbKQbKRbKSbKTbKUbKVbKQbKWbJhbKXbKYbKZbLabLbbLcbLdbLebLfbLgbHxbuZbvabvbbLhbLibLjbLkbLlbLmbLnbLnbFSbLobLpbLqbLrbLsbLtbLubLvbLwbLxbFSbLybJFbLzbLAbLBbCSbLBbLCbubbLDbJLbLEbLFbLGbJNbLHbLIbLJbLKbLLbJNabjabiabjabjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabibpmbzubLMbrrbrsaaabtdbtdbtdbwGbLNbLObNLbCUbwLbBfbLQbwGbtdbtdbtdaaabrsbLRbLSbLTbLUbLVbUJbUJbUJbUJbUJbUJbUJbUJbUJbVfabjabjabjabjabjabjabjabjabjabjabjaaaabiabiabjabiabiabjabiabjbVsbXFbPDbPEbPFbMdbMebMfbGzbMgbMhbMibMjbMkbMlbMmbIxbNTbMobMpbMqbMrbMsbMtbMubMvbMwbMxbMybMzbMAbMBbILbIMbFhbrWbMCbDFbMDbIPbBRbBTbMEbxhbMFbBVbLZbMHbMIbMJbIUbMIbMKbMGbDQbDRbvabIXbKEbMMbMNbMPbMObMRbMQbMSbMTbMUbMVbJhbMWbMXbMXbMYbMZbMYbMXbMXbNabJhbNbbKYbLbbNcbNdbNebNfbNgbLfbNhbHxbuZbvabvbbLhbNibNjbNkbNlbTdbLnbNnbNobLpbNpbNqbNrbNsbNtbNubFSbNvbNwbFSbJEbNxbHUbGabNybNzbGdbNAbNHbLDbNIbNDbNEbNFbNGbLHbNJbPybPAbNKbJNabjabiaaaabjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabjbmobRubmsbNMbNMbNMbNMbNMbNMbNMbNNbNMbNObNPbNQbNMbNRbNMbNMbNMbNMbNMbNMbNMbmobRvbLMbrraaaaaaabjaaaaaaabjaaaaaaaaabXGaaaaaaabjaaaaaaabjaaaaaaabjaaaabjaaaabjaaaabjaaaaaaabjaaaaaabYaabjbRwbVtbVzbNWbNXbNYbGzbNZbOabObbOcbOdbOebOfbGzbGzbGzbGzbGzbGzbOgbNUbOibylbOhbMxbOkbOlbOmbMBbOnbOobOpbrWbOqbOjbOrbOsbOtbOubOwbxhbOvbBVbOxbOybOzbOAbOBbFrbPYbPZbOCbODbvabIXbKEbOEbKGbOGbOFbOIbOHbOJbOKbOLbOMbONbOObOPbMXbMYbOQbMYbMXbORbOSbOTbOUbOVbOWbOXbOYbOZbLcbPabLcbPbbHxbuZbvabPcbLhbPdbPebPfbPgbPhbLnbPibPjbPkbPlbPmbPnbPobPpbPqbFSbPrbPsbFSbJEbJFbHUbGabHVblXbPtbHYbHZbLDbJLbPubPvbPwbPxbLHbQnbPzbQobPBbJNabjabiabjabiaaaaaaaaZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabibpmbzubPCbNMbPGbPHbPObPPbPQbNMbPIbPJbSobPLbPMbPJbPIbNMbPNbQCbQDbRtbPNbNMbPRbzubPCbkubkubkubPSbPTbPUbPVbPWbPXabjbYlbUJbUJbUJbUJbUJbYmbYmbYmbYmbYmbYmbYmbYmbYmbYmbYmbYmbYmbYmbYmbYJabjbwPbwPbwPbQbbQcbQdbGzbQebQfbUqbQhbMkbMlbQibQjbQkbQlbQmbVrbGzbQqbQAbRSbQrbQsbKsbQtbQubQvbMBbILbIMbQwbrWbrWbrWbQxbUrbrWbrWbrWbxhbUtbBVbCebDQbDQbSebIVbDQbDQbOCbQBbSgbSibSzbHjbQEbQFbQGbKNbQHbQIbQJbKMbHjbHjbJhbQKbMYbMXbQLbQMbQLbMXbMYbQNbJhbHxbHxbQObQQbQPbQRbQSbHxbQTbQUbHxcoEbSibSVbQVbLhbQWbQXbQYbLhbLnbLnbLnbFSbFSbQZbRabRbbRcbFSbFSbFSbFSbFSbRdbJFbHUbGabRebRfbRgbRhbRibRjbExbRkbRlbWhbJNbRnbQnbRobQobRpbJNbWCabiabjabiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabibmobRrbRsbNMbRxbSrbTcbUDbXmbNMbRybRzbRAbRBbRCbRDbREbRFbVjbRHbRHbRIbREbRFbRJbRKbRLbRLbRLbRLbRMbRNbROabjbRPbRQbRRabjaaaaaaabjaaaaaaabjaaaaaaabjaaaaaaabjaaaaaaabjaaaaaaabjaaaaaaabjabjabjbZfbRTbNXbRUbNYbGzbRVbOabRWbRXbRYbRZbSabSbbScbSdbScbTVbSfbTWbShbTXbSjbSkbSlbSmbSnbXEbMBbILbSpbSqbVCbStbStbSubSvbStbStbSsbSwbSxbSybTYbStbStbTZbUabSAbStbSsbXybyObSCbSDbSEbSEbSEbSEbSEbSEbSFbSEbSGbSEaaabJhbSHbSIbMXbSJbSKbSLbMXbSMbSNbJhaaabHxbSObSQbSPbSRbSSbSTbSTbSTbSTbwmbwnbSUbXCbSWbSXbSYbSZbTabTbbQzbXDbTbbTbbTebTfbTbbTgbThbThbTibTbbQzbTjbTkbTlbLAbLBbLBbLBbTmbubbLDbExbTnbNEbTobNGbTpbQnbTqbQobTrbJNabjabjaaaabiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabibpmbRrbTsbTtbTubTvbTwbTxbTybTzbTAbTBbTCbTDbTEbTFbTGbTHbTIbTJbTKbTLbTGbTMbTNbTObTPbTQbTRbTSbTTbTUbZwchwchwcjlcnHcoicsrcsrcoicsrcsrcoicsrcsrcoicsrcsrcoicsrcsrcoicsrcsrcoicsrcsrcsrcsrcsyctIbUcbUdbUebUfbGzbUgbUhbUibUjbUkbUlbUmbUnbUobUpbUobWIbGzbWKbUsbWNbUubUvbUwbUxbUybUzbMBbUAbUBbUCcjAbUEbUEbUFbUGbUEbUEbUEbUHbUEbUFbWObUEbUEbUEbUEbUIbUEbUEbYBbUKbULbUMbUNbUObSEbUPbUQbURbUSbUTbUUbSEabjbJhbJhbJhbJhbJhbJhbJhbJhbJhbJhbJhabjbHxbUVbUXbUWbUYbUZbSTbVabVbbSTbVcbVdbVebYLbVgbVgbVgbVhbVgbVibVBbVgbVgbVgbVkbVlbVgbVmbVnbVobVgbVgbVBbVhbVpbVqbWebWrbWsbWebVubVvbVwbVxbVycsMbVAbXbbXobXqbVEbXrbVGbJNaaaabiabjabiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabjbmobLTbVHbVIbVJbVKbVLbVMbVNbVIbVObVPbVQbVRbVSbVPbVTbVIbVUbVKbVMbVMbVTbVIbVVbVWbpqbpqbpqbpqbVXbVYbVZabjbWabWbbWcabjaaaaaaabjaaaaaaabjaaaaaaabjaaaaaaabjaaaaaaabjaaaaaaabjaaaaaaabjabjbWdctJbWfbWgcgDbWibGzbWjbWkbWlbWmbWnbIqbGzbOfbWobWpbWqbOfbGzbYocbRcfBbWtbWubWvbWwbWxbWybMBbWzbWAbWBcpPbWDbWEbWFbWGbWDbWDbWEbWHbWDbWFcgCbWDbWDbWDbWJbWDbWDbWDchbbWLbvabWMcgEcgFbWPbWQbWRbWSbWTbWUbWVbSEaaaaaaabjaaaaaaaaaabjaaaaaaaaaabjaaaaaabHxbHxbWWbHxbWXbHxbSTbWYbWZbSTbuZbvabXaciAbXcbXdbXcbXebXcbXfbVDbXcbXcbXcbXhbXebXibXjbXkbXlbXkcazbVDbXnbXBbXpbGabXVbXWbXsbEublWbXtbXubXvbXwbXxbXXbXzbXzbXAbYCbNKbJNaaaabiaaaabjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabjbmobRubmsbNMbNMbNMbNMbNMbNMbNMbNNbNMbNObNPbNQbNMbNRbNMbNMbNMbNMbNMbNMbNMbmobRvbLMbrraaaaaaabjaaaaaaabjaaaaaaaaabXGaaaaaaabjaaaaaaabjaaaaaaabjaaaabjaaaabjaaaabjaaaaaaabjaaaaaabYaabjbRwbVtbVzbNWbNXbNYbGzbNZbOabObbQdbOdbOebOfbGzbGzbGzbGzbGzbGzbOgbNUbOibylbOhbMxbOkbOlbOmbMBbOnbOobOpbrWbOqbOjbOrbOsbOtbOubOwbxhbOvbBVbOxbOybOzbOAbOBbFrbPYbPZbOCbODbvabIXbKEbOEbKGbOGbOFbOIbOHbOJbOKbOLbOMbONbOObOPbMXbMYbOQbMYbMXbORbOSbOTbOUbOVbOWbOXbOYbOZbLcbPabLcbPbbHxbuZbvabPcbLhbPdbPebPfbPgbPhbLnbPibPjbPkbPlbPmbPnbPobPpbPqbFSbPrbPsbFSbJEbJFbHUbGabHVblXbPtbHYbHZbLDbJLbPubPvbPwbPxbLHbQnbPzbQobPBbJNabjabiabjabiaaaaaaaaZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabibpmbzubPCbNMbPGbPHbPObPPbPQbNMbPIbPJbSobPLbPMbPJbPIbNMbPNbQCbQDbRtbPNbNMbPRbzubPCbkubkubkubPSbPTbPUbPVbPWbPXabjbYlbUJbUJbUJbUJbUJbYmbYmbYmbYmbYmbYmbYmbYmbYmbYmbYmbYmbYmbYmbYmbYJabjbwPbwPbwPbSfbQebUPbGzbWlbQfbUqbQhbMkbMlbQibQjbQkbQlbQmbVrbGzbQqbQAbRSbQrbQsbKsbQtbQubQvbMBbILbIMbQwbrWbrWbrWbQxbUrbrWbrWbrWbxhbUtbBVbCebDQbDQbSebIVbDQbDQbOCbQBbSgbSibSzbHjbQEbQFbQGbKNbQHbQIbQJbKMbHjbHjbJhbQKbMYbMXbQLbQMbQLbMXbMYbQNbJhbHxbHxbQObQQbQPbQRbQSbHxbQTbQUbHxcoEbSibSVbQVbLhbQWbQXbQYbLhbLnbLnbLnbFSbFSbQZbRabRbbRcbFSbFSbFSbFSbFSbRdbJFbHUbGabRebRfbRgbRhbRibRjbExbRkbRlbWhbJNbRnbQnbRobQobRpbJNbWCabiabjabiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabibmobRrbRsbNMbRxbSrbTcbUDbXmbNMbRybRzbRAbRBbRCbRDbREbRFbVjbRHbRHbRIbREbRFbRJbRKbRLbRLbRLbRLbRMbRNbROabjbRPbRQbRRabjaaaaaaabjaaaaaaabjaaaaaaabjaaaaaaabjaaaaaaabjaaaaaaabjaaaaaaabjabjabjbZfbRTbNXbRUbNYbGzbRVbOabRWbRXbRYbRZbSabSbbScbSdbScbTVbWqbTWbShbTXbSjbSkbSlbSmbSnbXEbMBbILbSpbSqbVCbStbStbSubSvbStbStbSsbSwbSxbSybTYbStbStbTZbUabSAbStbSsbXybyObSCbSDbSEbSEbSEbSEbSEbSEbSFbSEbSGbSEaaabJhbSHbSIbMXbSJbSKbSLbMXbSMbSNbJhaaabHxbSObSQbSPbSRbSSbSTbSTbSTbSTbwmbwnbSUbXCbSWbSXbSYbSZbTabTbbQzbXDbTbbTbbTebTfbTbbTgbThbThbTibTbbQzbTjbTkbTlbLAbLBbLBbLBbTmbubbLDbExbTnbNEbTobNGbTpbQnbTqbQobTrbJNabjabjaaaabiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabibpmbRrbTsbTtbTubTvbTwbTxbTybTzbTAbTBbTCbTDbTEbTFbTGbTHbTIbTJbTKbTLbTGbTMbTNbTObTPbTQbTRbTSbTTbTUbZwchwchwcjlcnHcoicsrcsrcoicsrcsrcoicsrcsrcoicsrcsrcoicsrcsrcoicsrcsrcoicsrcsrcsrcsrcsyctIbUcbUdbUebUfbGzbUgbUhbUibUjbUkbUlbUmbUnbUobUpbUobWIbGzbWKbUsbWNbUubUvbUwbUxbUybUzbMBbUAbUBbUCcjAbUEbUEbUFbUGbUEbUEbUEbUHbUEbUFbWObUEbUEbUEbUEbUIbUEbUEbYBbUKbULbUMbUNbUObSEcaQbUQbURbUSbUTbUUbSEabjbJhbJhbJhbJhbJhbJhbJhbJhbJhbJhbJhabjbHxbUVbUXbUWbUYbUZbSTbVabVbbSTbVcbVdbVebYLbVgbVgbVgbVhbVgbVibVBbVgbVgbVgbVkbVlbVgbVmbVnbVobVgbVgbVBbVhbVpbVqbWebWrbWsbWebVubVvbVwbVxbVycsMbVAbXbbXobXqbVEbXrbVGbJNaaaabiabjabiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabjbmobLTbVHbVIbVJbVKbVLbVMbVNbVIbVObVPbVQbVRbVSbVPbVTbVIbVUbVKbVMbVMbVTbVIbVVbVWbpqbpqbpqbpqbVXbVYbVZabjbWabWbbWcabjaaaaaaabjaaaaaaabjaaaaaaabjaaaaaaabjaaaaaaabjaaaaaaabjaaaaaaabjabjbWdctJbWfbWgcgDbWibGzbWjbWkdYVbWmbWnbIqbGzbOfbWobWpbWqbOfbGzbYocbRcfBbWtbWubWvbWwbWxbWybMBbWzbWAbWBcpPbWDbWEbWFbWGbWDbWDbWEbWHbWDbWFcgCbWDbWDbWDbWJbWDbWDbWDchbbWLbvabWMcgEcgFbWPbWQbWRbWSbWTbWUbWVbSEaaaaaaabjaaaaaaaaaabjaaaaaaaaaabjaaaaaabHxbHxbWWbHxbWXbHxbSTbWYbWZbSTbuZbvabXaciAbXcbXdbXcbXebXcbXfbVDbXcbXcbXcbXhbXebXibXjbXkbXlbXkcazbVDbXnbXBbXpbGabXVbXWbXsbEublWbXtbXubXvbXwbXxbXXbXzbXzbXAbYCbNKbJNaaaabiaaaabjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabibpmbzubrqbNMccxcgIchuchEcmxbNMbPIbXHbXIbXJbPMbXKbXLbNMbPNbXMbXNbXObXPbNMbrwbzubrqbrrbrrbrrbPSbXQbXRbPVbXSbXTabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjaaaabjabjbXUbXUbXUbXUbXUbXUbXUbXUbXUbXUbXUbXUbXUbXUbXUbXUbXUbXUbXYbYccxEcxEcxFbQrbXZciabYbbQrclobMBbMBbYdbMBbMBbYebYfbYgbYhbYhbYibYhbYjbYjbYkcqHcrsbYkbYjbYjbYjbYjbYjbYjbYjbYjbYjbYnbuZbvabWMbtHcnWbYpbYqbYrbYsbYtbWUbYubSEbYvbYvbYvbYvbYvbYwbYwbYwbYxbYxbYxbYxbYxbSTbYybYzbYAcbzcfabYDbYEbYFbSTbuZbvabuWbYGbYHbYIbZibYKbYHbYHbYHbYHbYHbYHbVFbYHbYMbYMbYNbYObYNbYMbYMbYPbYQbYRbYSbYTbYUbYSbYVbnqbYWbYXbYYbYZbZabZbbZcbZdbZecaPbZgbJNabjabiabjabjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabibmobzubmsbNMbNMbNMbNMbNMbNMbNMbNMbNMbNObZhbNQbNMbNMbNMbNMbNMbNMbNMbNMbNMbmobzubmsabiaaaaaaabjaaaaaaabjaaaaaaaaaabjaaaaaaabjaaaaaaabjaaaaaaabjaaaaaaaaaaaaabjabjbXUbXUbXUbXUbZjbZjbZkbZlbZmbXUbXUbXUbZnbZlbZobZlcbcbXUbZpbZqbZrbZsbZtbZubZvbZvcbubZxbZybZzbZAbZBbZCbZDbZDbZEbXUbYhbZFbYhbYhbZGbZHbZIbYjbZJbZKbZLbZMbZNbZObYjbZPbZQbZRbYjbZSbZQbZRbYjbZTbZUbZVbtHcnWbZWbZXbWRbZYbZZbWUcaabSEcabcaccadcaebYvcafcagcahbYxcaicajcakcalbSTcamcancaocapcaqcarcascatbSTbwmbZUcaubYHcavcawcaxcayccObYKcaAcaBcaCcaDcaEcaFbYMcaGcaHcaIcaJcaKcaLbhfcaMbhfbLAbLBbLBbLBcaNcaOcgebExbJLcaQbGpbJNbJNcaRcaSbJNbJNbJNaaaabiaaaabjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabibmobzubmsbNMbNMbNMbNMbNMbNMbNMbNMbNMbNObZhbNQbNMbNMbNMbNMbNMbNMbNMbNMbNMbmobzubmsabiaaaaaaabjaaaaaaabjaaaaaaaaaabjaaaaaaabjaaaaaaabjaaaaaaabjaaaaaaaaaaaaabjabjbXUbXUbXUbXUbZjbZjbZkbZlbZmbXUbXUbXUbZnbZlbZobZlcbcbXUbZpbZqbZrbZsbZtbZubZvbZvcbubZxbZybZzbZAbZBbZCbZDbZDbZEbXUbYhbZFbYhbYhbZGbZHbZIbYjbZJbZKbZLbZMbZNbZObYjbZPbZQbZRbYjbZSbZQbZRbYjbZTbZUbZVbtHcnWbZWbZXbWRbZYbZZbWUcaabSEcabcaccadcaebYvcafcagcahbYxcaicajcakcalbSTcamcancaocapcaqcarcascatbSTbwmbZUcaubYHcavcawcaxcayccObYKcaAcaBcaCcaDcaEcaFbYMcaGcaHcaIcaJcaKcaLbhfcaMbhfbLAbLBbLBbLBcaNcaOcgebExbJLdYWbGpbJNbJNcaRcaSbJNbJNbJNaaaabiaaaabjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabibpmbzubnRbktbktbktbkuaaabJhcaTcaUcaVcaWcaXcaYcaVcaZcaTbJhaaabkubktbktbkubnMbzubpuabiabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabjabiaaacbabXUcbacbbcbbcbbcbdcbbcbebZlbZlbZlcdbcbbcbdcbbcbfcbgcbhcbicbjcbkcblcbmcbncbocbncbpcbqcbrcbscbtcfgcbvcbwcbxbXUcbycdgcbAcbBcbCcbDcbEbYjcbFcbGbZLcbHcbIcbJbYjcbKcbLcbMbYjcbNcbOcbMbYjbuZbvacbPcbQcpfbYpcbSbYrbYscbTcbUcbVbSEcbWcbYcbXcbZbYvccaccbcccbYxccdcceccfccgbSTcchcciccjcckcclccmccnccobSTbuZbvabuWbYHccpcawccqccqccqbYKccrccscctccuccvccwbXgccycczccAccBccCcaLccDccEccFbLAccGccHbhfccIccJbGgccKccLccMccNcggccPccPccQccRccSbLAaaaabiaaaabiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabjbmobJXbJPbJPbJPbJPbJYbpubJhccTbMYccUccVccWccXccYbMYccZbJhbpmbJObJPbJPbJPbJPbJQbmsabiaaaaaaabjaaaaaaabjaaaaaaaaaabjaaaaaaabjaaaaaaabjaaaaaaabjaaaaaaaaaaaaabiabjcbabXUcbaabjcdccxGcxGcxGcxGcFLcbbdtIcxGcxGcxGcxGcgBbXUbXUcddbXUcdecdfcdhcdhcdhcdjcdicdkcdlcdmceTcdncdocdpcdqbXUcdrcdscdtcducdvbZHcdwbYjcdxcdycdzbZMcdAcdBbYjbYjcdCbYjbYjbYjcdCbYjbYjbuZbvabWMbtHcnWcdDcdEbWRbZYcdFcdGcdHbSEcdIcdKcdJcdLbYvcdMcdNcdObYxcdPcdQcdRcdSbSTcdTcdUcdVcdWcdXcdYcdZceabSTbuZbvabuWbYHcebceccedceeccqbYKcefcegcehceicejcekcelcemcenceocepceqcaLcercescetbGdceucevcewcexceycezceAceBceCceDceEceFceEceGceHbHWceIabjabjabjabiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabiaaabrsbrrbrsbrrbLSbzubmsceJceKceLceMceNceOcePceQceLceRceSbmobzubLMbrrbrsbrrbrsaaaabjaaaaaaabjaaaaaaabjaaaaaaaaaabjaaaaaaabjaaaaaaabjaaaaaaabjaaaaaaabjabjabiaaacbabXUcbaaaaaaaabjaaaabjaaaacFabjacFaaaabjaaaabjaaacdcbXUceUceVceWceXceYceYceZcfccfbcfecfdceYcgHcffciXcfhcficfjcfkcflcfmcfncfobZHcfpbYjcfqcfrbZLbZMcfscftcfucfvcfwcfxcfycfzcfwcfAbYkbuZbvabWMctEcnWbYpcfCcfDbYsbYtbWUcfEbSEcfFcfHcfGcfIbYvcfJcfKcfLbYxcfMcfNcfOcfPbSTbSTbSTbSTcfQcfRbSTbSTbSTbSTbuZbvacfSbYHcayceccedcedcedcfTcfUcfVcfWcfXcfYcfZbYMcgacgbcgccgdcgScaLcgfchKcghcgicgjcgkbRgcglcgmbRjbLAcgncgocgpcgqcgrcgscgrcgoccSbLAaaaabiaaaabiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa diff --git a/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm b/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm index dcf4c217e94..0c86bf9f9ee 100644 --- a/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm +++ b/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm @@ -4321,7 +4321,7 @@ "bFe" = (/obj/item/radio/intercom{frequency = 1459; name = "Station Intercom (General)"; pixel_y = -25},/obj/machinery/camera{c_tag = "Arrivals - Middle Arm - Far"; dir = 1; network = list("SS13")},/obj/effect/decal/warning_stripes/south,/turf/simulated/floor/plasteel,/area/hallway/secondary/entry{name = "Arrivals"}) "bFf" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/machinery/computer/monitor{name = "Grid Power Monitoring Computer"},/obj/item/radio/intercom{frequency = 1459; name = "Station Intercom (General)"; pixel_x = 5; pixel_y = -26},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/turret_protected/tcomeast{name = "\improper MiniSat East Wing"}) "bFg" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/space,/area/construction/hallway{name = "\improper MiniSat Exterior"}) -"bFh" = (/obj/machinery/computer/telecomms/traffic{network = "tcommsat"},/turf/simulated/floor/plasteel{icon_state = "grimy"},/area/tcommsat/computer{name = "\improper Telecoms Control Room"}) +"bFh" = (/obj/machinery/computer/telecomms/traffic,/turf/simulated/floor/plasteel{icon_state = "grimy"},/area/tcommsat/computer{name = "\improper Telecoms Control Room"}) "bFi" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/obj/structure/chair/office/dark{dir = 1},/turf/simulated/floor/plasteel{icon_state = "grimy"},/area/tcommsat/computer{name = "\improper Telecoms Control Room"}) "bFj" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{icon_state = "grimy"},/area/tcommsat/computer{name = "\improper Telecoms Control Room"}) "bFk" = (/obj/structure/transit_tube{icon_state = "E-W-Pass"},/obj/structure/lattice,/turf/space,/area/space) @@ -8504,7 +8504,7 @@ "dhF" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/airlock/maintenance{name = "storage room"; req_access = "12"},/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) "dhG" = (/obj/item/seeds/watermelon,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) "dhI" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/mob/living/simple_animal/bot/cleanbot{name = "Mopfficer Sweepsky"; on = 0},/turf/simulated/floor/plating,/area/maintenance/fore) - + (1,1,1) = {" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa diff --git a/_maps/map_files/RandomRuins/SpaceRuins/oldstation.dmm b/_maps/map_files/RandomRuins/SpaceRuins/oldstation.dmm index c98cccae52d..a6890bdd61d 100644 --- a/_maps/map_files/RandomRuins/SpaceRuins/oldstation.dmm +++ b/_maps/map_files/RandomRuins/SpaceRuins/oldstation.dmm @@ -24,7 +24,7 @@ "ax" = (/obj/effect/decal/remains/robot{icon_state = "gib5"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/ruin/space/ancientstation/hivebot) "ay" = (/obj/structure/shuttle/engine/large{icon_state = "large_engine"; dir = 4},/turf/simulated/wall,/area/ruin/space/ancientstation/hivebot) "az" = (/turf/simulated/wall/rust,/area/ruin/space/ancientstation) -"aA" = (/obj/structure/table,/obj/effect/decal/cleanable/dirt,/obj/machinery/door_control{id = "ancient"; name = "Charlie Station Lockdown Button"},/turf/simulated/floor/plasteel,/area/ruin/space/ancientstation/comm) +"aA" = (/obj/structure/table,/obj/effect/decal/cleanable/dirt,/obj/machinery/door_control{id = "ancient"; name = "Charlie Station Lockdown Button"; range = 30},/turf/simulated/floor/plasteel,/area/ruin/space/ancientstation/comm) "aB" = (/obj/effect/decal/cleanable/dirt,/obj/structure/chair{dir = 1},/turf/simulated/floor/plasteel,/area/ruin/space/ancientstation/comm) "aC" = (/obj/structure/table,/obj/effect/decal/cleanable/dirt,/obj/item/toy/cards/deck,/obj/item/folder/blue,/obj/item/pen,/turf/simulated/floor/plasteel,/area/ruin/space/ancientstation/comm) "aD" = (/obj/machinery/door/airlock/highsecurity,/turf/simulated/floor/plating,/area/ruin/space/ancientstation/hivebot) @@ -208,7 +208,7 @@ "dZ" = (/obj/machinery/computer{desc = "A computer long since rendered non-functional due to lack of maintenance. Spitting out error messages."; name = "Broken Computer"},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{icon_state = "red"; dir = 1},/area/ruin/space/ancientstation/sec) "ea" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/firealarm{dir = 4; pixel_x = -28},/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel,/area/ruin/space/ancientstation/deltacorridor) "eb" = (/obj/machinery/light{dir = 8},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{icon_state = "white"},/area/ruin/space/ancientstation/rnd) -"ec" = (/obj/effect/decal/cleanable/dirt,/obj/machinery/computer/rdconsole/core,/turf/simulated/floor/plasteel{icon_state = "white"},/area/ruin/space/ancientstation/rnd) +"ec" = (/obj/effect/decal/cleanable/dirt,/obj/machinery/computer/rdconsole/public,/turf/simulated/floor/plasteel{icon_state = "white"},/area/ruin/space/ancientstation/rnd) "ed" = (/obj/effect/decal/cleanable/dirt,/obj/machinery/r_n_d/destructive_analyzer,/turf/simulated/floor/plasteel{icon_state = "white"},/area/ruin/space/ancientstation/rnd) "ee" = (/obj/effect/decal/cleanable/dirt,/obj/machinery/mecha_part_fabricator,/turf/simulated/floor/plasteel{icon_state = "white"},/area/ruin/space/ancientstation/rnd) "ef" = (/obj/effect/decal/cleanable/dirt,/obj/structure/table,/obj/item/stack/sheet/metal/fifty,/obj/item/stack/sheet/glass/fifty{pixel_x = 2; pixel_y = -2},/turf/simulated/floor/plasteel{icon_state = "white"},/area/ruin/space/ancientstation/rnd) @@ -660,3 +660,4 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa "} + diff --git a/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm b/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm index aebc09cfc7a..9b145bd1eb3 100644 --- a/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm @@ -23,7 +23,7 @@ var/input_pressure_min = 0 var/output_pressure_max = 0 - var/frequency = 1439 + var/frequency = ATMOS_VENTSCRUB var/id_tag = null var/datum/radio_frequency/radio_connection var/advcontrol = 0//does this device listen to the AAC @@ -249,7 +249,7 @@ /obj/machinery/atmospherics/binary/dp_vent_pump/multitool_menu(var/mob/user,var/obj/item/multitool/P) return {" diff --git a/code/ATMOSPHERICS/components/binary_devices/valve.dm b/code/ATMOSPHERICS/components/binary_devices/valve.dm index 1d7805c55b2..f8f282a55af 100644 --- a/code/ATMOSPHERICS/components/binary_devices/valve.dm +++ b/code/ATMOSPHERICS/components/binary_devices/valve.dm @@ -66,7 +66,7 @@ desc = "A digitally controlled valve." icon = 'icons/atmos/digital_valve.dmi' - var/frequency = 1439 + var/frequency = ATMOS_VENTSCRUB var/id_tag = null var/datum/radio_frequency/radio_connection settagwhitelist = list("id_tag") @@ -149,7 +149,7 @@ /obj/machinery/atmospherics/binary/valve/digital/multitool_menu(var/mob/user,var/obj/item/multitool/P) return {" "} diff --git a/code/ATMOSPHERICS/components/unary_devices/outlet_injector.dm b/code/ATMOSPHERICS/components/unary_devices/outlet_injector.dm index 345afd9921e..d597d0eb4c4 100644 --- a/code/ATMOSPHERICS/components/unary_devices/outlet_injector.dm +++ b/code/ATMOSPHERICS/components/unary_devices/outlet_injector.dm @@ -167,7 +167,7 @@ /obj/machinery/atmospherics/unary/outlet_injector/multitool_menu(var/mob/user,var/obj/item/multitool/P) return {" "} diff --git a/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm b/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm index 865490aef28..c47893fc9dd 100644 --- a/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm +++ b/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm @@ -37,7 +37,7 @@ var/welded = 0 // Added for aliens -- TLE - var/frequency = 1439 + var/frequency = ATMOS_VENTSCRUB var/datum/radio_frequency/radio_connection Mtoollink = 1 var/advcontrol = 0//does this device listen to the AAC @@ -184,7 +184,7 @@ frequency = new_frequency if(frequency) radio_connection = radio_controller.add_object(src, frequency,radio_filter_in) - if(frequency != 1439) + if(frequency != ATMOS_VENTSCRUB) initial_loc.air_vent_info -= id_tag initial_loc.air_vent_names -= id_tag name = "vent pump" @@ -211,7 +211,7 @@ "timestamp" = world.time, "sigtype" = "status" ) - if(frequency == 1439)//We're on the frequency the air alarms and stuff use + if(frequency == ATMOS_VENTSCRUB) if(!initial_loc.air_vent_names[id_tag]) var/new_name = "[initial_loc.name] Vent Pump #[initial_loc.air_vent_names.len+1]" initial_loc.air_vent_names[id_tag] = new_name @@ -227,8 +227,8 @@ ..() //some vents work his own special way - radio_filter_in = frequency==1439?(RADIO_FROM_AIRALARM):null - radio_filter_out = frequency==1439?(RADIO_TO_AIRALARM):null + radio_filter_in = frequency==ATMOS_VENTSCRUB?(RADIO_FROM_AIRALARM):null + radio_filter_out = frequency==ATMOS_VENTSCRUB?(RADIO_TO_AIRALARM):null if(frequency) set_frequency(frequency) src.broadcast_status() @@ -404,7 +404,7 @@ /obj/machinery/atmospherics/unary/vent_pump/multitool_menu(var/mob/user,var/obj/item/multitool/P) return {" @@ -419,7 +419,7 @@ var/newid = copytext(reject_bad_text(input(usr, "Specify the new ID tag for this machine", src, src.id_tag) as null|text), 1, MAX_MESSAGE_LEN) if(!newid) return - if(frequency == 1439) + if(frequency == ATMOS_VENTSCRUB) initial_loc.air_vent_info -= id_tag initial_loc.air_vent_names -= id_tag diff --git a/code/ATMOSPHERICS/components/unary_devices/vent_scrubber.dm b/code/ATMOSPHERICS/components/unary_devices/vent_scrubber.dm index 8b5c4b2afb2..e22d00c3f80 100644 --- a/code/ATMOSPHERICS/components/unary_devices/vent_scrubber.dm +++ b/code/ATMOSPHERICS/components/unary_devices/vent_scrubber.dm @@ -15,7 +15,7 @@ var/area/initial_loc var/id_tag = null - var/frequency = 1439 + var/frequency = ATMOS_VENTSCRUB var/datum/radio_frequency/radio_connection var/advcontrol = 0//does this device listen to the AAC? @@ -50,7 +50,7 @@ id_tag = num2text(uid) /obj/machinery/atmospherics/unary/vent_scrubber/Destroy() - if(initial_loc && frequency == 1439) + if(initial_loc && frequency == ATMOS_VENTSCRUB) initial_loc.air_scrub_info -= id_tag initial_loc.air_scrub_names -= id_tag if(radio_controller) @@ -130,7 +130,7 @@ radio_controller.remove_object(src, frequency) frequency = new_frequency radio_connection = radio_controller.add_object(src, frequency, radio_filter_in) - if(frequency != 1439) + if(frequency != ATMOS_VENTSCRUB) initial_loc.air_scrub_info -= id_tag initial_loc.air_scrub_names -= id_tag name = "air Scrubber" @@ -159,7 +159,7 @@ "filter_n2o" = scrub_N2O, "sigtype" = "status" ) - if(frequency == 1439)//We're on the frequency the air alarms and stuff use + if(frequency == ATMOS_VENTSCRUB) if(!initial_loc.air_scrub_names[id_tag]) var/new_name = "[initial_loc.name] Air Scrubber #[initial_loc.air_scrub_names.len+1]" initial_loc.air_scrub_names[id_tag] = new_name @@ -342,7 +342,7 @@ /obj/machinery/atmospherics/unary/vent_scrubber/multitool_menu(var/mob/user,var/obj/item/multitool/P) return {" @@ -358,7 +358,7 @@ if(!newid) return - if(frequency == 1439) + if(frequency == ATMOS_VENTSCRUB) initial_loc.air_scrub_info -= id_tag initial_loc.air_scrub_names -= id_tag diff --git a/code/__DEFINES/admin.dm b/code/__DEFINES/admin.dm index 1df551e53e7..3877ac213c5 100644 --- a/code/__DEFINES/admin.dm +++ b/code/__DEFINES/admin.dm @@ -63,3 +63,4 @@ #define AREACOORD(src) "[src ? "[get_area_name(src, TRUE)] [COORD(src)]" : "nonexistent location" ]" #define ADMIN_COORDJMP(src) "[src ? "[COORD(src)] [ADMIN_JMP(src)]" : "nonexistent location"]" #define ADMIN_VERBOSEJMP(src) "[src ? "[AREACOORD(src)] [ADMIN_JMP(src)]" : "nonexistent location"]" +#define ADMIN_SHOWDETAILS(mask, content) "[mask]" \ No newline at end of file diff --git a/code/controllers/communications.dm b/code/controllers/communications.dm index 177e670d6c9..eaf993939ea 100644 --- a/code/controllers/communications.dm +++ b/code/controllers/communications.dm @@ -61,63 +61,40 @@ */ -/* -Frequency range: 1200 to 1600 -Radiochat range: 1441 to 1489 (most devices refuse to be tune to other frequency, even during mapmaking) +var/const/DISPLAY_FREQ = 1435 //status displays +var/const/ATMOS_FIRE_FREQ = 1437 //air alarms +var/const/ENGINE_FREQ = 1438 //engine components +var/const/ATMOS_VENTSCRUB = 1439 //vents, scrubbers, atmos control +var/const/ATMOS_DISTRO_FREQ = 1443 //distro loop +var/const/ATMOS_TANKS_FREQ = 1441 //atmos supply tanks +var/const/BOT_BEACON_FREQ = 1445 //bot navigation beacons +var/const/AIRLOCK_FREQ = 1449 //airlock controls, electropack, magnets -Radio: -1459 - standard radio chat -1351 - Science -1353 - Command -1355 - Medical -1357 - Engineering -1359 - Security -1341 - Special Operations -1443 - Confession Intercom -1347 - Cargo -1349 - Service +var/const/RSD_FREQ = 1457 //radio signal device +var/const/IMPL_FREQ = 1451 //tracking implant -Devices: -1451 - Tracking Implant -1457 - RSD Default - -On the map: -1311 for prison shuttle console (in fact, it is not used) -1435 for status displays -1437 for atmospherics/fire alerts -1438 for engine components -1439 for air pumps, air scrubbers, atmo control -1441 for atmospherics - supply tanks -1443 for atmospherics - distribution loop/mixed air tank -1445 for bot nav beacons -1447 for mulebot, secbot and ed209 control -1449 for airlock controls, electropack, magnets -1451 for toxin lab access -1453 for engineering access -1455 for AI access -*/ - -var/const/RADIO_LOW_FREQ = 1200 -var/const/PUBLIC_LOW_FREQ = 1441 -var/const/PUBLIC_HIGH_FREQ = 1489 -var/const/RADIO_HIGH_FREQ = 1600 +var/const/RADIO_LOW_FREQ = 1200 //minimum radio freq +var/const/PUBLIC_LOW_FREQ = 1441 //minimum radio chat freq +var/const/PUBLIC_HIGH_FREQ = 1489 //maximum radio chat freq +var/const/RADIO_HIGH_FREQ = 1600 //maximum radio freq var/const/SYND_FREQ = 1213 var/const/SYNDTEAM_FREQ = 1244 -var/const/DTH_FREQ = 1341 +var/const/DTH_FREQ = 1341 //Special Operations var/const/AI_FREQ = 1343 var/const/ERT_FREQ = 1345 -var/const/COMM_FREQ = 1353 -var/const/BOT_FREQ = 1447 +var/const/COMM_FREQ = 1353 //Command +var/const/BOT_FREQ = 1447 //mulebot, secbot, ed209 + // department channels -var/const/PUB_FREQ = 1459 -var/const/SEC_FREQ = 1359 -var/const/ENG_FREQ = 1357 -var/const/SCI_FREQ = 1351 -var/const/MED_FREQ = 1355 -var/const/SUP_FREQ = 1347 -var/const/SRV_FREQ = 1349 +var/const/PUB_FREQ = 1459 //standard radio chat +var/const/SEC_FREQ = 1359 //security +var/const/ENG_FREQ = 1357 //engineering +var/const/SCI_FREQ = 1351 //science +var/const/MED_FREQ = 1355 //medical +var/const/SUP_FREQ = 1347 //cargo +var/const/SRV_FREQ = 1349 //service // internal department channels var/const/MED_I_FREQ = 1485 diff --git a/code/controllers/master_controller.dm b/code/controllers/master_controller.dm index 93e5780e1a7..1fd81402544 100644 --- a/code/controllers/master_controller.dm +++ b/code/controllers/master_controller.dm @@ -55,17 +55,10 @@ var/global/pipe_processing_killed = 0 space_manager.do_transition_setup() - setup_asset_cache() setupfactions() setup_economy() for(var/i=0, iYou shatter the orb! A dark essence spirals into the air, then disappears.") playsound(user.loc, 'sound/effects/Glassbr1.ogg', 50, 1) + curselimit++ qdel(src) sleep(20) var/global/list/curses @@ -270,7 +271,6 @@ "Steve repeatedly touched a lightbulb until his hands fell off. The shuttle will be delayed by two minutes.") var/message = pick(curses) command_announcement.Announce("[message]", "System Failure", 'sound/misc/notice1.ogg') - curselimit++ /obj/item/cult_shift name = "veil shifter" diff --git a/code/game/jobs/job_exp.dm b/code/game/jobs/job_exp.dm index 465af126354..bfd11066bf3 100644 --- a/code/game/jobs/job_exp.dm +++ b/code/game/jobs/job_exp.dm @@ -43,11 +43,11 @@ var/global/list/role_playtime_requirements = list( set category = "Special Verbs" set name = "Check my playtime" - if(!config.use_exp_restrictions) + if(!config.use_exp_tracking) to_chat(src, "Playtime tracking is not enabled.") return - to_chat(src, "Your playtime is [get_exp_living()].") // Admin Verbs diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm index 415f68d6afd..9446da62e3f 100644 --- a/code/game/machinery/alarm.dm +++ b/code/game/machinery/alarm.dm @@ -82,9 +82,9 @@ req_one_access = list(access_atmospherics, access_engine_equip) armor = list(melee = 0, bullet = 0, laser = 0, energy = 100, bomb = 0, bio = 100, rad = 100) var/alarm_id = null - var/frequency = 1439 + var/frequency = ATMOS_VENTSCRUB //var/skipprocess = 0 //Experimenting - var/alarm_frequency = 1437 + var/alarm_frequency = ATMOS_FIRE_FREQ var/remote_control = 0 var/rcon_setting = 2 var/rcon_time = 0 diff --git a/code/game/machinery/atmo_control.dm b/code/game/machinery/atmo_control.dm index 7ede1d7586d..2e41ec49c0a 100644 --- a/code/game/machinery/atmo_control.dm +++ b/code/game/machinery/atmo_control.dm @@ -9,7 +9,7 @@ var/bolts = 1 var/id_tag - var/frequency = 1439 + var/frequency = ATMOS_VENTSCRUB Mtoollink = 1 settagwhitelist = list("id_tag") @@ -147,7 +147,7 @@ name = "Computer" - var/frequency = 1439 + var/frequency = ATMOS_VENTSCRUB var/show_sensors=1 var/list/sensors = list() Mtoollink = 1 diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index 9d7310c1c66..24805e4c9a2 100644 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -27,7 +27,6 @@ var/centcomm_message_cooldown = 0 var/tmp_alertlevel = 0 - var/status_display_freq = "1435" var/stat_msg1 var/stat_msg2 var/display_type="blank" @@ -510,7 +509,7 @@ /proc/post_status(command, data1, data2, mob/user = null) - var/datum/radio_frequency/frequency = radio_controller.return_frequency(1435) + var/datum/radio_frequency/frequency = radio_controller.return_frequency(DISPLAY_FREQ) if(!frequency) return diff --git a/code/game/machinery/doors/airlock_control.dm b/code/game/machinery/doors/airlock_control.dm index 4199d5e8c20..7eb43cdec74 100644 --- a/code/game/machinery/doors/airlock_control.dm +++ b/code/game/machinery/doors/airlock_control.dm @@ -236,7 +236,7 @@ power_channel = ENVIRON var/master_tag - var/frequency = 1449 + var/frequency = AIRLOCK_FREQ var/command = "cycle" var/datum/radio_frequency/radio_connection diff --git a/code/game/machinery/doors/alarmlock.dm b/code/game/machinery/doors/alarmlock.dm index c2e12618d79..91591234551 100644 --- a/code/game/machinery/doors/alarmlock.dm +++ b/code/game/machinery/doors/alarmlock.dm @@ -6,7 +6,7 @@ glass = 1 autoclose = 0 var/datum/radio_frequency/air_connection - var/air_frequency = 1437 + var/air_frequency = ATMOS_FIRE_FREQ /obj/machinery/door/airlock/alarmlock/New() ..() diff --git a/code/game/machinery/magnet.dm b/code/game/machinery/magnet.dm index 7741d1ce056..6a11662fc33 100644 --- a/code/game/machinery/magnet.dm +++ b/code/game/machinery/magnet.dm @@ -16,7 +16,7 @@ use_power = IDLE_POWER_USE idle_power_usage = 50 - var/freq = 1449 // radio frequency + var/freq = AIRLOCK_FREQ // radio frequency var/electricity_level = 1 // intensity of the magnetic pull var/magnetic_field = 1 // the range of magnetic attraction var/code = 0 // frequency code, they should be different unless you have a group of magnets working together or something @@ -181,7 +181,7 @@ anchored = 1.0 use_power = IDLE_POWER_USE idle_power_usage = 45 - var/frequency = 1449 + var/frequency = AIRLOCK_FREQ var/code = 0 var/list/magnets = list() var/title = "Magnetic Control Console" diff --git a/code/game/machinery/status_display.dm b/code/game/machinery/status_display.dm index 881711ff5f6..5f875d7fdc8 100644 --- a/code/game/machinery/status_display.dm +++ b/code/game/machinery/status_display.dm @@ -30,7 +30,7 @@ var/index1 // display index for scrolling messages or 0 if non-scrolling var/index2 - var/frequency = 1435 // radio frequency + var/frequency = DISPLAY_FREQ // radio frequency var/friendc = 0 // track if Friend Computer mode var/ignore_friendc = 0 diff --git a/code/game/machinery/telecomms/ntsl2.dm b/code/game/machinery/telecomms/ntsl2.dm new file mode 100644 index 00000000000..ee9fabd272a --- /dev/null +++ b/code/game/machinery/telecomms/ntsl2.dm @@ -0,0 +1,318 @@ +GLOBAL_DATUM_INIT(nttc_config, /datum/nttc_configuration, new()) +// Custom Implementations for NTTC +/* NTTC Configuration Datum + * This is an abstract handler for the configuration loadout. It's set up like this both for ease of transfering in and out of the UI + * as well as allowing users to save and load configurations. + */ +/datum/nttc_configuration + /* Simple Toggles */ + var/toggle_activated = TRUE + var/toggle_jobs = FALSE + var/toggle_timecode = FALSE + // Hack section + var/toggle_gibberish = FALSE + var/toggle_honk = FALSE + + /* Strings */ + var/setting_language = null + + /* Tables */ + var/list/regex = list() + + /* Arrays */ + var/list/firewall = list() + + /* Meta stuff */ + // These variables requires the source computer to be hacked in order to change + var/list/requires_unlock = list( + "firewall" = TRUE, + "toggle_gibberish" = TRUE, + "toggle_honk" = TRUE, + ) + + // This is used to sanitize topic data + var/list/tables = list("regex") + var/list/arrays = list("firewall") + + // This tells the datum what is safe to serialize and what's not. It also applies to deserialization. + var/list/to_serialize = list( + "toggle_activated", + "toggle_jobs", + "toggle_timecode", + "toggle_gibberish", + "toggle_honk", + "setting_language", + "regex", + "firewall" + ) + + // This is used for sanitization. + var/list/serialize_sanitize = list( + "toggle_activated" = "bool", + "toggle_jobs" = "bool", + "toggle_timecode" = "bool", + "toggle_gibberish" = "bool", + "toggle_honk" = "bool", + "setting_language" = "string", + "regex" = "table", + "firewall" = "array" + ) + + // Used to determine what languages are allowable for conversion. Generated during runtime. + var/list/valid_languages = list("--DISABLE--") + +/datum/nttc_configuration/proc/reset() + /* Simple Toggles */ + toggle_activated = initial(toggle_activated) + toggle_jobs = initial(toggle_jobs) + toggle_timecode = initial(toggle_timecode) + // Hack section + toggle_gibberish = initial(toggle_gibberish) + toggle_honk = initial(toggle_honk) + + /* Strings */ + setting_language = initial(setting_language) + + /* Tables */ + regex = list() + + /* Arrays */ + firewall = list() + + +/datum/nttc_configuration/proc/update_languages() + for(var/language in GLOB.all_languages) + var/datum/language/L = GLOB.all_languages[language] + if(L.flags & HIVEMIND) + continue + valid_languages[language] = TRUE + +// I'd use serialize() but it's used by another system. This converts the configuration into a JSON string. +/datum/nttc_configuration/proc/nttc_serialize() + . = list() + for(var/variable in to_serialize) + .[variable] = vars[variable] + . = json_encode(.) + +// This loads a configuration from a JSON string. +// Fucking broken as shit, someone help me fix this. +/datum/nttc_configuration/proc/nttc_deserialize(text, obj/machinery/computer/telecomms/traffic/source) + var/list/var_list = json_decode(text) + for(var/variable in var_list) + if(variable in to_serialize) // Don't just accept any random vars jesus christ! + if(requires_unlock[variable] && (source && !source.unlocked)) + continue + var/sanitize_method = serialize_sanitize[variable] + var/variable_value = var_list[variable] + variable_value = nttc_sanitize(variable_value, sanitize_method) + if(variable_value != null) + vars[variable] = variable_value + +// Sanitizing user input. Don't blindly trust the JSON. +/datum/nttc_configuration/proc/nttc_sanitize(variable, sanitize_method) + if(!sanitize_method) + return null + + switch(sanitize_method) + if("bool") + return variable ? TRUE : FALSE + if("table", "array") + if(!islist(variable)) + return list() + // Insert html filtering for the regexes here if you're boring + var/newlist = json_decode(html_decode(json_encode(variable))) + if(!islist(newlist)) + return null + return newlist + if("string") + return "[variable]" + + return variable + +// Primary signal modification. This is where all of the variables behavior are actually implemented. +/datum/nttc_configuration/proc/modify_signal(datum/signal/signal) + // Servers are deliberately turned off. Mark every signal as rejected. + if(!toggle_activated) + signal.data["reject"] = TRUE + return + + // Firewall + // This must happen before anything else modifies the signal ["name"]. + if(islist(firewall) && firewall.len > 0) + if(firewall.Find(signal.data["name"])) + signal.data["reject"] = 1 + + // These two stack properly. + // Simple job indicator switch. + if(toggle_jobs) + var/new_name = signal.data["name"] + " ([signal.data["job"]]) " + signal.data["name"] = new_name + signal.data["realname"] = new_name // this is required because the broadcaster uses this directly if the speaker doesn't have a voice changer on + + // Add the current station time like a time code. + if(toggle_timecode) + var/new_name = "\[[station_time_timestamp()]] " + signal.data["name"] + signal.data["name"] = new_name + signal.data["realname"] = new_name // this is required because the broadcaster uses this directly if the speaker doesn't have a voice changer on + + // Hacks! + // Censor dat shit like nobody's business + if(toggle_gibberish) + signal.data["message"] = Gibberish(signal.data["message"], 80) + + // Replace everything with HONK! + if(toggle_honk) + var/list/split = splittext(signal.data["message"], " ") + var/honklength = split.len + var/new_message = "" + for(var/i in 1 to honklength) + new_message += pick("HoNK!", "HONK", "HOOOoONK", "HONKHONK!", "HoNnnkKK!!!", "HOOOOOOOOOOONK!!!!11!", "henk!") + " " + signal.data["message"] = new_message + + + // Language Conversion + if(setting_language && valid_languages[setting_language]) + if(setting_language == "--DISABLE--") + setting_language = null + else + signal.data["language"] = GLOB.all_languages[setting_language] + + // Regex replacements + if(islist(regex) && regex.len > 0) + var/original = signal.data["message"] + var/new_message = original + for(var/reg in regex) + var/replacePattern = pencode_to_html(regex[reg]) + var/regex/start = regex(reg, "gi") + new_message = start.Replace(new_message, replacePattern) + signal.data["message"] = new_message + + // Make sure the message is valid after we tinkered with it, otherwise reject it + if(signal.data["message"] == "" || !signal.data["message"]) + signal.data["reject"] = 1 + +/datum/nttc_configuration/Topic(mob/user, href_list, window_id, obj/machinery/computer/telecomms/traffic/source) + // Toggles + if(href_list["toggle"]) + var/var_to_toggle = href_list["toggle"] + if(requires_unlock[var_to_toggle] && !source.unlocked) + return + if(!(var_to_toggle in to_serialize)) + return + vars[var_to_toggle] = !vars[var_to_toggle] + log_action(user, "toggled NTTC variable [var_to_toggle] [vars[var_to_toggle] ? "on" : "off"]") + + // Strings + if(href_list["setting_language"]) + var/new_language = input(user, "Pick a language to convert messages to.", "Language Conversion") as null|anything in valid_languages + if(!new_language) + return + if(new_language == "--DISABLE--") + setting_language = null + to_chat(user, "Language conversion disabled.") + else + setting_language = new_language + to_chat(user, "Messages will now be converted to [new_language].") + + log_action(user, new_language == "--DISABLE--" ? "disabled NTTC language conversion" : "set NTTC language conversion to [new_language]", TRUE) + + // Tables + if(href_list["create_row"]) + if(href_list["table"] && href_list["table"] in tables) + if(requires_unlock[href_list["table"]] && !source.unlocked) + return + var/new_key = input(user, "Provide a key for the new row.", "New Row") as text|null + if(!new_key) + return + var/new_value = input(user, "Provide a new value for the key [new_key]", "New Row") as text|null + if(new_value == null) + return + var/list/table = vars[href_list["table"]] + table[new_key] = new_value + to_chat(user, "Added row [new_key] -> [new_value].") + log_action(user, "updated [href_list["table"]] - new row [new_key] -> [new_value]") + + if(href_list["delete_row"]) + if(href_list["table"] && href_list["table"] in tables) + if(requires_unlock[href_list["table"]] && !source.unlocked) + return + var/list/table = vars[href_list["table"]] + table.Remove(href_list["delete_row"]) + to_chat(user, "Removed row [href_list["delete_row"]] from [href_list["table"]]") + log_action(user, "updated [href_list["table"]] - removed row [href_list["delete_row"]]") + + // Arrays + if(href_list["create_item"]) + if(href_list["array"] && href_list["array"] in arrays) + if(requires_unlock[href_list["array"]] && !source.unlocked) + return + var/new_value = input(user, "Provide a value for the new index.", "New Index") as text|null + if(new_value == null) + return + var/list/array = vars[href_list["array"]] + array.Add(new_value) + to_chat(user, "Added row [new_value].") + log_action(user, "updated [href_list["array"]] - new value [new_value]") + + if(href_list["delete_item"]) + if(href_list["array"] && href_list["array"] in arrays) + if(requires_unlock[href_list["array"]] && !source.unlocked) + return + var/list/array = vars[href_list["array"]] + array.Remove(href_list["delete_item"]) + to_chat(user, "Removed [href_list["delete_item"]] from [href_list["array"]]") + log_action(user, "updated [href_list["array"]] - removed [href_list["delete_item"]]") + + // Spit out the serialized config to the user + if(href_list["save_config"]) + user << browse(nttc_serialize(), "window=save_nttc") + + if(href_list["load_config"]) + var/json = input(user, "Provide configuration JSON below.", "Load Config", nttc_serialize()) as message + nttc_deserialize(json, source) + log_action(user, "has uploaded a NTTC JSON configuration: [ADMIN_SHOWDETAILS("Show", json)]", TRUE) + + user << output(list2params(list(nttc_serialize())), "[window_id].browser:updateConfig") + +/datum/nttc_configuration/proc/log_action(user, msg, adminmsg = FALSE) + log_game("NTTC: [key_name(user)] [msg]") + log_investigate("[key_name(user)] [msg]", "ntsl") + if(adminmsg) + message_admins("[key_name_admin(user)] [msg]") + +/* Asset datum for the UI */ +/datum/asset/simple/nttc + assets = list( + "bundle.css" = 'html/nttc/dist/bundle.css', + "bundle.js" = 'html/nttc/dist/bundle.js', + "tab_home.html" = 'html/nttc/dist/tab_home.html', + "tab_hack.html" = 'html/nttc/dist/tab_hack.html', + "tab_filtering.html" = 'html/nttc/dist/tab_filtering.html', + "tab_firewall.html" = 'html/nttc/dist/tab_firewall.html', + "tab_regex.html" = 'html/nttc/dist/tab_regex.html', + "uiTitleFluff.png" = 'html/nttc/dist/uiTitleFluff.png' + ) + +/* Custom subtype of /datum/browser that behaves as we want for our project */ +/datum/browser/nttc + var/initial_config // Initial NTTC configuration + +/datum/browser/nttc/New(nuser, nwindow_id, ntitle = 0, nwidth = 0, nheight = 0, var/atom/nref = null, nttc_config) + . = ..() + initial_config = nttc_config +// Prevent all stylesheets from being added, we have our own CSS that's bundled with gulp +/datum/browser/nttc/add_stylesheet() + return +// No header, we're running a fully complete .html file +/datum/browser/nttc/get_header() + return +// We inject a little code at the bottom of the file, similar to NanoUI, but more limited. +// This code is used for delivering live updates of config changes & allowing the UI to provide Topic data. +/datum/browser/nttc/get_footer() + var/byondSrc = "byond://?src=[ref.UID()];" + var/dat = "" + return dat diff --git a/code/game/machinery/telecomms/telecomunications.dm b/code/game/machinery/telecomms/telecomunications.dm index c74d5364919..b38eca98817 100644 --- a/code/game/machinery/telecomms/telecomunications.dm +++ b/code/game/machinery/telecomms/telecomunications.dm @@ -435,37 +435,25 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list() var/logs = 0 // number of logs var/totaltraffic = 0 // gigabytes (if > 1024, divide by 1024 -> terrabytes) - var/list/memory = list() // stored memory - var/list/rawcode = list() // the code to compile (list of characters) - var/datum/TCS_Compiler/Compiler // the compiler that compiles and runs the code - var/autoruncode = 0 // 1 if the code is set to run every time a signal is picked up - var/encryption = "null" // encryption key: ie "password" var/salt = "null" // encryption salt: ie "123comsat" // would add up to md5("password123comsat") var/language = "human" var/obj/item/radio/headset/server_radio = null -/obj/machinery/telecomms/server/New() +/obj/machinery/telecomms/server/Initialize() ..() - Compiler = new() - Compiler.Holder = src server_radio = new() /obj/machinery/telecomms/server/receive_information(datum/signal/signal, obj/machinery/telecomms/machine_from) - if(signal.data["message"]) - if(is_freq_listening(signal)) - if(traffic > 0) totaltraffic += traffic // add current traffic to total traffic //Is this a test signal? Bypass logging if(signal.data["type"] != 4) - // If signal has a message and appropriate frequency - update_logs() var/datum/comm_log_entry/log = new @@ -508,23 +496,14 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list() var/identifier = num2text( rand(-1000,1000) + world.time ) log.name = "data packet ([md5(identifier)])" - if(Compiler && autoruncode) - Compiler.Run(signal) // execute the code + // Run NTTC against the signal + if(GLOB.nttc_config) + GLOB.nttc_config.modify_signal(signal) var/can_send = relay_information(signal, "/obj/machinery/telecomms/hub") if(!can_send) relay_information(signal, "/obj/machinery/telecomms/broadcaster") - -/obj/machinery/telecomms/server/proc/setcode(var/list/code) - if(istype(code)) - rawcode = code - -/obj/machinery/telecomms/server/proc/compile(mob/user as mob) - if(Compiler) - admin_log(user) - return Compiler.Compile(rawcode) - /obj/machinery/telecomms/server/proc/update_logs() // start deleting the very first log entry if(logs >= 400) @@ -544,16 +523,7 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list() log_entries.Add(log) update_logs() -/obj/machinery/telecomms/server/proc/admin_log(var/mob/mob) - var/msg="[key_name(mob)] has compiled a script to server [src]:" - log_game("NTSL: [msg]") - log_game("NTSL: [rawcode.Join("")]") - src.investigate_log("[msg]
[rawcode.Join("")]", "ntsl") - if(length(rawcode)) // Let's not bother the admins for empty code. - message_admins("[key_name_admin(mob)] has compiled and uploaded a NTSL script to [src.id] (JMP)") - // Simple log entry datum - /datum/comm_log_entry var/parameters = list() // carbon-copy to signal.data[] var/name = "data packet (#)" diff --git a/code/game/machinery/telecomms/traffic_control.dm b/code/game/machinery/telecomms/traffic_control.dm index 28a2809e5b4..d76debd7e34 100644 --- a/code/game/machinery/telecomms/traffic_control.dm +++ b/code/game/machinery/telecomms/traffic_control.dm @@ -1,25 +1,23 @@ /obj/machinery/computer/telecomms/traffic name = "telecommunications traffic control" - var/screen = 0 // the screen number: - var/allservers = 0 // Are all servers being edited at the same time? - var/list/servers = list() // the servers located by the computer - var/mob/editingcode - var/mob/lasteditor - var/obj/machinery/telecomms/server/SelectedServer - - var/compiling_errors = "" - - var/network = "NULL" // the network to probe - var/temp = "" // temporary feedback messages - - var/storedcode = "" // code stored - light_color = LIGHT_COLOR_DARKGREEN req_access = list(access_tcomsat) circuit = /obj/item/circuitboard/comm_traffic + // NTTC + var/window_id // mostly used to let the configuration datum update the user's UI + var/unlocked = FALSE + +/obj/machinery/computer/telecomms/traffic/attackby(obj/item/I, mob/user) + if(ismultitool(I)) + unlocked = !unlocked + to_chat(user, "This computer is now [unlocked ? "Unlocked" : "Locked"]. \ +Reopen the UI to see the difference.") + return + . = ..() + /obj/machinery/computer/telecomms/traffic/attack_hand(mob/user) interact(user) @@ -27,154 +25,19 @@ if(stat & (BROKEN|NOPOWER)) return 0 - user.set_machine(src) + if(GLOB.nttc_config.valid_languages.len == 1) + GLOB.nttc_config.update_languages() // this is silly but it has to be done because NTTC inits before languages do - if(!editingcode || editingcode && editingcode.machine != src) - editingcode = user - lasteditor = user - - var/dat = "" - - dat += "
Telecommunications Traffic Control
" - - if(screen == 0) //main menu - dat += "
[temp]
" - dat += "
Current Network: [network]
" - if(servers.len) - dat += "
Detected Telecommunication Servers:" - - dat += "
\[Flush Buffer\]" - - else - dat += "
No servers detected. Scan for servers: \[Scan\]" - - if(screen == 1) //server menu - dat += "
[temp]
" - dat += "
\[Main Menu\] \[Refresh\]
" - dat += "
Current Network: [network]" - if(allservers) - dat += "
Selected Server: All Servers

" - else - dat += "
Selected Server: [SelectedServer.id]

" - dat += "
\[Edit Code\]" - dat += "
Signal Execution: " - if(allservers) - dat += "ALWAYS NEVER" - else - if(SelectedServer.autoruncode) - dat += "ALWAYS" - else - dat += "NEVER" - - if(screen == 2) //code editor - if(editingcode == user) - dat += {"
[temp]
-
- \[Back\] - \[Main Menu\] - \[Refresh\] -
- - - -
- -
- - - Compile - Clear - -
- [compiling_errors] -
- -
- - - - -
- "} - else - dat += {"
[temp]
-
\[Refresh\]
-
- - -
-
- [compiling_errors] -
- "} //anything typed will be overridden anyways by the one who is editing the code - - var/datum/browser/popup = new(user, "traffic_control", "Telecommunication Traffic Control", 700, 500) - //codemirror - popup.add_script("codemirror-compressed", 'nano/codemirror/codemirror-compressed.js') // A custom minified JavaScript file of CodeMirror, with the following plugins: CSS Mode, NTSL Mode, CSS-hint addon, Search addon, Sublime Keymap. - popup.add_stylesheet("codemirror", 'nano/codemirror/codemirror.css') // A CSS sheet containing the basic stylings and formatting information for CodeMirror. - popup.add_stylesheet("lesser-dark", 'nano/codemirror/lesser-dark.css') // A theme for CodeMirror to use, which closely resembles the rest of the NanoUI style. - - popup.set_content(dat) - popup.open() - - temp = "" + var/datum/asset/assets = get_asset_datum(/datum/asset/simple/nttc) + assets.send(user) + var/dat = file2text("html/nttc/dist/index.html") + if(unlocked) + dat += "\n" + var/datum/browser/nttc/nt_browser = new(user, name, "NTTC", 720, 480, src, GLOB.nttc_config.nttc_serialize()) + nt_browser.set_content(dat) + nt_browser.open() + window_id = nt_browser.window_id /obj/machinery/computer/telecomms/traffic/Topic(href, href_list) if(..()) @@ -184,209 +47,4 @@ if(!istype(user) || !user.client) return 0 - if(user != editingcode) - return 0 - - var/code = href_list["cMirror"] - if(code) - storedcode = code - - var/list/codelist = href_list["cMirrorList"] - if(istext(codelist)) - codelist = json_decode(codelist) - - add_fingerprint(user) - user.set_machine(src) - - if(!allowed(user) && !emagged && !user.can_admin_interact()) - to_chat(user, "Access Denied.") - return 0 - - switch(href_list["choice"]) - if("Compile") - if(!istype(codelist)) - return 0 - if(user != editingcode) - return 0 //only one editor - - if(SelectedServer) - var/obj/machinery/telecomms/server/Server = SelectedServer - Server.setcode(codelist) - - spawn(0) - // Output all the compile-time errors - compiling_errors = "Please wait, compiling..." - updateUsrDialog() - - var/list/compileerrors = Server.compile(user) // then compile the code! - if(!telecomms_check(user)) - return - - if(compileerrors.len) - compiling_errors = "Compile Errors
" - for(var/datum/scriptError/e in compileerrors) - compiling_errors += "\t>[e.message]
" - compiling_errors += "([compileerrors.len] errors)" - - - else - compiling_errors = "TCS compilation successful!
" - compiling_errors += "(0 errors)" - - updateUsrDialog() - if(allservers) - spawn(0) - compiling_errors = "Please wait, compiling..." - updateUsrDialog() - - for(var/obj/machinery/telecomms/server/Server in servers) - Server.setcode(codelist) - var/list/compileerrors = Server.compile(user) - if(!telecomms_check(user)) - return - if(compileerrors.len) - compiling_errors = "Compile Errors
" - for(var/datum/scriptError/e in compileerrors) - compiling_errors += "\t>[e.message]
" - compiling_errors += "([compileerrors.len] errors)" - updateUsrDialog() - return // If there are errors, don't waste time compiling on other servers - compiling_errors = "TCS compilation successful!
" - compiling_errors += "(0 errors)" - updateUsrDialog() - - if("Clear") - if(!telecomms_check(user) || user != editingcode) - return 0 - - if(SelectedServer) - var/obj/machinery/telecomms/server/Server = SelectedServer - Server.memory = list() // clear the memory - - compiling_errors = "Server Memory Cleared!" - storedcode = null - updateUsrDialog() - if(allservers) - for(var/obj/machinery/telecomms/server/Server in servers) - Server.memory = list() // clear the memory - - compiling_errors = "Server Memory Cleared!" - storedcode = null - updateUsrDialog() - - if(href_list["viewserver"]) - screen = 1 - if(href_list["viewserver"] == "all") - allservers = 1 - else - allservers = 0 - for(var/obj/machinery/telecomms/T in servers) - if(T.id == href_list["viewserver"]) - SelectedServer = T - break - - if(href_list["operation"]) - switch(href_list["operation"]) - - if("release") - servers = list() - screen = 0 - - if("mainmenu") - screen = 0 - - if("codeback") - if(allservers || SelectedServer) - screen = 1 - - if("scan") - if(servers.len > 0) - temp = "- FAILED: CANNOT PROBE WHEN BUFFER FULL -" - - else - for(var/obj/machinery/telecomms/server/T in range(25, src)) - if(T.network == network) - servers.Add(T) - - if(!servers.len) - temp = "- FAILED: UNABLE TO LOCATE SERVERS IN \[[network]\] -" - else - temp = "- [servers.len] SERVERS PROBED & BUFFERED -" - - screen = 0 - - if("editcode") - screen = 2 - - if("togglerun") - SelectedServer.autoruncode = !(SelectedServer.autoruncode) - if("runon") - for(var/obj/machinery/telecomms/server/Server in servers) - Server.autoruncode = 1 - if("runoff") - for(var/obj/machinery/telecomms/server/Server in servers) - Server.autoruncode = 0 - - if(href_list["network"]) - - var/newnet = input(user, "Which network do you want to view?", "Comm Monitor", network) as null|text - - if(newnet && canAccess(user)) - if(length(newnet) > 15) - temp = "- FAILED: NETWORK TAG STRING TOO LENGHTLY -" - - else - - network = newnet - screen = 0 - servers = list() - temp = "- NEW NETWORK TAG SET IN ADDRESS \[[network]\] -" - - updateUsrDialog() - -/obj/machinery/computer/telecomms/traffic/attackby(var/obj/item/D as obj, var/mob/user as mob, params) - if(istype(D, /obj/item/screwdriver)) - playsound(get_turf(src), D.usesound, 50, 1) - if(do_after(user, 20 * D.toolspeed, target = src)) - if(src.stat & BROKEN) - to_chat(user, "The broken glass falls out.") - var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc ) - new /obj/item/shard(loc) - var/obj/item/circuitboard/comm_traffic/M = new /obj/item/circuitboard/comm_traffic( A ) - for(var/obj/C in src) - C.loc = src.loc - A.circuit = M - A.state = 3 - A.icon_state = "3" - A.anchored = 1 - qdel(src) - else - to_chat(user, "You disconnect the monitor.") - var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc ) - var/obj/item/circuitboard/comm_traffic/M = new /obj/item/circuitboard/comm_traffic( A ) - for(var/obj/C in src) - C.loc = src.loc - A.circuit = M - A.state = 4 - A.icon_state = "4" - A.anchored = 1 - qdel(src) - src.updateUsrDialog() - return - -/obj/machinery/computer/telecomms/traffic/emag_act(user as mob) - if(!emagged) - playsound(get_turf(src), 'sound/effects/sparks4.ogg', 75, 1) - emagged = 1 - to_chat(user, "You you disable the security protocols") - -/obj/machinery/computer/telecomms/traffic/proc/canAccess(var/mob/user) - if(issilicon(user) || in_range(user, src)) - return 1 - return 0 - -/obj/machinery/computer/telecomms/traffic/proc/telecomms_check(var/mob/mob) - //writepanic("[__FILE__].[__LINE__] (no type)([usr ? usr.ckey : ""]) \\/proc/telecomms_check() called tick#: [world.time]") - if(mob && istype(mob.machine, /obj/machinery/computer/telecomms/traffic) && in_range(mob.machine, mob) || issilicon(mob) && istype(mob.machine, /obj/machinery/computer/telecomms/traffic)) - return 1 - return 0 + GLOB.nttc_config.Topic(user, href_list, window_id, src) \ No newline at end of file diff --git a/code/game/machinery/transformer.dm b/code/game/machinery/transformer.dm index 7078ba83561..79bd222dc85 100644 --- a/code/game/machinery/transformer.dm +++ b/code/game/machinery/transformer.dm @@ -133,7 +133,7 @@ return // Crossed didn't like people lying down. - if(isobject(AM)) + if(isatom(AM)) AM.loc = src.loc do_transform_mime(AM) else @@ -221,7 +221,7 @@ AM.loc = src.loc irradiate(AM) - else if(isobject(AM)) + else if(isatom(AM)) AM.loc = src.loc scan(AM) diff --git a/code/game/objects/items/devices/radio/electropack.dm b/code/game/objects/items/devices/radio/electropack.dm index 71fc397a2c4..2e53e4ff06a 100644 --- a/code/game/objects/items/devices/radio/electropack.dm +++ b/code/game/objects/items/devices/radio/electropack.dm @@ -3,7 +3,7 @@ desc = "Dance my monkeys! DANCE!!!" icon_state = "electropack0" item_state = "electropack" - frequency = 1449 + frequency = AIRLOCK_FREQ flags = CONDUCT slot_flags = SLOT_BACK w_class = WEIGHT_CLASS_HUGE diff --git a/code/game/objects/items/devices/radio/intercom.dm b/code/game/objects/items/devices/radio/intercom.dm index 97855409536..63b9b00eeb0 100644 --- a/code/game/objects/items/devices/radio/intercom.dm +++ b/code/game/objects/items/devices/radio/intercom.dm @@ -18,7 +18,7 @@ /obj/item/radio/intercom/interrogation name = "station intercom (Interrogation)" - frequency = 1449 + frequency = AIRLOCK_FREQ /obj/item/radio/intercom/private name = "station intercom (Private)" diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index 6dae08febd3..5f7bf6c0442 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -392,10 +392,12 @@ var/global/list/default_medbay_channels = list( // --- Modifications to the mob's identity --- // The mob is disguising their identity: - if(ishuman(M) && M.GetVoice() != real_name) - displayname = M.GetVoice() - jobname = "Unknown" - voicemask = TRUE + if(ishuman(M)) + var/mob/living/carbon/human/H = M + displayname = H.voice + if(H.voice != real_name) + jobname = "Unknown" + voicemask = TRUE if(syndiekey && syndiekey.change_voice && connection.frequency == SYND_FREQ) displayname = syndiekey.fake_name diff --git a/code/game/objects/items/weapons/cigs.dm b/code/game/objects/items/weapons/cigs.dm index 28d216c4cbd..311f29273a8 100644 --- a/code/game/objects/items/weapons/cigs.dm +++ b/code/game/objects/items/weapons/cigs.dm @@ -64,7 +64,7 @@ LIGHTERS ARE IN LIGHTERS.DM /obj/item/clothing/mask/cigarette/fire_act() light() -/obj/item/clothing/mask/cigarette/attackby(obj/item/W as obj, mob/user as mob, mob/living/carbon/target, params) +/obj/item/clothing/mask/cigarette/attackby(obj/item/W as obj, mob/user as mob, params) ..() if(istype(W, /obj/item/weldingtool)) var/obj/item/weldingtool/WT = W @@ -107,7 +107,6 @@ LIGHTERS ARE IN LIGHTERS.DM //can't think of any other way to update the overlays :< user.update_inv_wear_mask() - target.update_inv_wear_mask() user.update_inv_l_hand() user.update_inv_r_hand() return diff --git a/code/game/objects/items/weapons/holy_weapons.dm b/code/game/objects/items/weapons/holy_weapons.dm index ea799bbcd76..56205b17997 100644 --- a/code/game/objects/items/weapons/holy_weapons.dm +++ b/code/game/objects/items/weapons/holy_weapons.dm @@ -400,6 +400,9 @@ ..() processing_objects.Add(src) +/obj/item/nullrod/rosary/Destroy() + processing_objects.Remove(src) + return ..() /obj/item/nullrod/rosary/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob) if(!iscarbon(M)) @@ -448,9 +451,8 @@ /obj/item/nullrod/rosary/process() if(ishuman(loc)) var/mob/living/carbon/human/holder = loc - if(src == holder.l_hand || src == holder.r_hand) // Holding this in your hand will - for(var/mob/living/carbon/human/H in range(5)) + for(var/mob/living/carbon/human/H in range(5, loc)) if(H.mind.vampire && !H.mind.vampire.get_ability(/datum/vampire_passive/full)) H.mind.vampire.nullified = max(5, H.mind.vampire.nullified + 2) if(prob(10)) @@ -492,8 +494,8 @@ if(ishuman(loc)) var/mob/living/carbon/human/holder = loc //would like to make the holder mime if they have it in on thier person in general - if(src == holder.l_hand || src == holder.r_hand) // Holding this in your hand will - for(var/mob/living/carbon/human/H in range(5)) + if(src == holder.l_hand || src == holder.r_hand) + for(var/mob/living/carbon/human/H in range(5, loc)) if(H.mind.assigned_role == "Clown") H.Silence(10) animate_fade_grayscale(H,20) diff --git a/code/game/objects/structures/stool_bed_chair_nest/bed.dm b/code/game/objects/structures/stool_bed_chair_nest/bed.dm index ddb29ee0566..adbeffd600d 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/bed.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/bed.dm @@ -132,6 +132,7 @@ /obj/item/roller_holder/attack_self(mob/user as mob) if(!held) to_chat(user, " The rack is empty.") + return to_chat(user, "You deploy the roller bed.") var/obj/structure/bed/roller/R = new /obj/structure/bed/roller(user.loc) diff --git a/code/modules/admin/DB ban/functions.dm b/code/modules/admin/DB ban/functions.dm index 47085a8b749..dd46725ff26 100644 --- a/code/modules/admin/DB ban/functions.dm +++ b/code/modules/admin/DB ban/functions.dm @@ -65,7 +65,7 @@ datum/admins/proc/DB_ban_record(var/bantype, var/mob/banned_mob, var/duration = var/computerid var/ip - if(ismob(banned_mob)) + if(ismob(banned_mob) && banned_mob.ckey) ckey = banned_mob.ckey if(banned_mob.client) computerid = banned_mob.client.computer_id @@ -74,6 +74,12 @@ datum/admins/proc/DB_ban_record(var/bantype, var/mob/banned_mob, var/duration = ckey = ckey(banckey) computerid = bancid ip = banip + else if(ismob(banned_mob)) + message_admins("[key_name_admin(usr)] attempted to add a ban based on a ckey-less mob, with no ckey provided. Report this bug.",1) + return + else + message_admins("[key_name_admin(usr)] attempted to add a ban based on a non-existent mob, with no ckey provided. Report this bug.",1) + return var/DBQuery/query = dbcon.NewQuery("SELECT id FROM [format_table_name("player")] WHERE ckey = '[ckey]'") query.Execute() @@ -82,7 +88,7 @@ datum/admins/proc/DB_ban_record(var/bantype, var/mob/banned_mob, var/duration = validckey = 1 if(!validckey) if(!banned_mob || (banned_mob && !IsGuestKey(banned_mob.key))) - message_admins("[key_name_admin(usr)] attempted to ban [ckey], but [ckey] has not been seen yet. Please only ban actual players.",1) + message_admins("[key_name_admin(usr)] attempted to ban [ckey], but [ckey] does not exist in the player database. Please only ban actual players.",1) return var/a_ckey diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 2c16a0feb49..c4e07ca577f 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -29,6 +29,20 @@ var/global/nologevent = 0 to_chat(C, msg) +/proc/admin_ban_mobsearch(var/mob/M, var/ckey_to_find, var/mob/admin_to_notify) + if(!M || !M.ckey) + if(ckey_to_find) + for(var/mob/O in GLOB.mob_list) + if(O.ckey && O.ckey == ckey_to_find) + if(admin_to_notify) + to_chat(admin_to_notify, "admin_ban_mobsearch: Player [ckey_to_find] is now in mob [O]. Pulling data from new mob.") + return O + if(admin_to_notify) + to_chat(admin_to_notify, "admin_ban_mobsearch: Player [ckey_to_find] does not seem to have any mob, anywhere. This is probably an error.") + else if(admin_to_notify) + to_chat(admin_to_notify, "admin_ban_mobsearch: No mob or ckey detected.") + return M + ///////////////////////////////////////////////////////////////////////////////////////////////Panels /datum/admins/proc/show_player_panel(var/mob/M in GLOB.mob_list) @@ -58,8 +72,9 @@ var/global/nologevent = 0 body += "

\[ " body += "VV - " body += "[ADMIN_TP(M,"TP")] - " - body += "PM - " - body += "[ADMIN_SM(M,"SM")] - " + if(M.client) + body += "PM - " + body += "[ADMIN_SM(M,"SM")] - " if(ishuman(M) && M.mind) body += "HM -" body += "[admin_jump_link(M)]\]
" @@ -70,12 +85,13 @@ var/global/nologevent = 0 if(M.client.related_accounts_ip.len) body += "Related accounts by IP: [jointext(M.client.related_accounts_ip, " - ")]

" - body += "Kick | " - body += "Warn | " - body += "Ban | " - body += "Jobban | " - body += "Appearance Ban | " - body += "Notes | " + if(M.ckey) + body += "Kick | " + body += "Warn | " + body += "Ban | " + body += "Jobban | " + body += "Appearance Ban | " + body += "Notes | " if(M.client) if(M.client.check_watchlist(M.client.ckey)) body += "Remove from Watchlist | " @@ -115,7 +131,9 @@ var/global/nologevent = 0 body += {" | Bless | Smite"} if(isLivingSSD(M)) - if(!istype(M.loc, /obj/machinery/cryopod)) + if(istype(M.loc, /obj/machinery/cryopod)) + body += {" | De-Spawn "} + else body += {" | Cryo "} if(M.client) diff --git a/code/modules/admin/admin_investigate.dm b/code/modules/admin/admin_investigate.dm index 4623a46d7d1..49b2f06d003 100644 --- a/code/modules/admin/admin_investigate.dm +++ b/code/modules/admin/admin_investigate.dm @@ -26,6 +26,13 @@ investigate_log_subjects |= subject F << "[time_stamp()] \ref[src] ([x],[y],[z]) || [src] [message]
" +/proc/log_investigate(message, subject) + if(!message) return + var/F = investigate_subject2file(subject) + if(!F) return + investigate_log_subjects |= subject + F << "[time_stamp()] || [message]
" + //ADMINVERBS /client/proc/investigate_show( subject in investigate_log_subjects ) set name = "Investigate" diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index dd0a67021b6..c729007bbcc 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -77,6 +77,7 @@ var/list/admin_verbs_admin = list( /client/proc/toggle_advanced_interaction, /*toggle admin ability to interact with not only machines, but also atoms such as buttons and doors*/ /client/proc/list_ssds, /client/proc/cmd_admin_headset_message, + /client/proc/spawn_floor_cluwne, ) var/list/admin_verbs_ban = list( /client/proc/unban_panel, @@ -720,7 +721,7 @@ var/list/admin_verbs_ticket = list( var/list/Lines = file2list("config/admins.txt") for(var/line in Lines) var/list/splitline = splittext(line, " - ") - if(n_lower(splitline[1]) == ckey) + if(lowertext(splitline[1]) == ckey) if(splitline.len >= 2) rank = ckeyEx(splitline[2]) break diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 3c4a1bc0ad9..870bbecbdc0 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -433,6 +433,7 @@ if(!M.ckey) //sanity to_chat(usr, "This mob has no ckey") return + var/ban_ckey_param = href_list["dbbanaddckey"] var/banreason = appearance_isbanned(M) if(banreason) @@ -455,6 +456,7 @@ var/reason = input(usr,"Please state the reason","Reason") as message|null if(!reason) return + M = admin_ban_mobsearch(M, ban_ckey_param, usr) ban_unban_log_save("[key_name(usr)] appearance banned [key_name(M)]. reason: [reason]") log_admin("[key_name(usr)] appearance banned [key_name(M)]. \nReason: [reason]") feedback_inc("ban_appearance",1) @@ -501,17 +503,17 @@ //Regular jobs //Command (Blue) jobs += "" - jobs += "" + jobs += "" for(var/jobPos in command_positions) if(!jobPos) continue var/datum/job/job = job_master.GetJob(jobPos) if(!job) continue if(jobban_isbanned(M, job.title)) - jobs += "" + jobs += "" counter++ else - jobs += "" + jobs += "" counter++ if(counter >= 6) //So things dont get squiiiiished! @@ -522,17 +524,17 @@ //Security (Red) counter = 0 jobs += "
Command Positions
Command Positions
[replacetext(job.title, " ", " ")][replacetext(job.title, " ", " ")][replacetext(job.title, " ", " ")][replacetext(job.title, " ", " ")]
" - jobs += "" + jobs += "" for(var/jobPos in security_positions) if(!jobPos) continue var/datum/job/job = job_master.GetJob(jobPos) if(!job) continue if(jobban_isbanned(M, job.title)) - jobs += "" + jobs += "" counter++ else - jobs += "" + jobs += "" counter++ if(counter >= 5) //So things dont get squiiiiished! @@ -543,17 +545,17 @@ //Engineering (Yellow) counter = 0 jobs += "
Security Positions
Security Positions
[replacetext(job.title, " ", " ")][replacetext(job.title, " ", " ")][replacetext(job.title, " ", " ")][replacetext(job.title, " ", " ")]
" - jobs += "" + jobs += "" for(var/jobPos in engineering_positions) if(!jobPos) continue var/datum/job/job = job_master.GetJob(jobPos) if(!job) continue if(jobban_isbanned(M, job.title)) - jobs += "" + jobs += "" counter++ else - jobs += "" + jobs += "" counter++ if(counter >= 5) //So things dont get squiiiiished! @@ -564,17 +566,17 @@ //Medical (White) counter = 0 jobs += "
Engineering Positions
Engineering Positions
[replacetext(job.title, " ", " ")][replacetext(job.title, " ", " ")][replacetext(job.title, " ", " ")][replacetext(job.title, " ", " ")]
" - jobs += "" + jobs += "" for(var/jobPos in medical_positions) if(!jobPos) continue var/datum/job/job = job_master.GetJob(jobPos) if(!job) continue if(jobban_isbanned(M, job.title)) - jobs += "" + jobs += "" counter++ else - jobs += "" + jobs += "" counter++ if(counter >= 5) //So things dont get squiiiiished! @@ -585,17 +587,17 @@ //Science (Purple) counter = 0 jobs += "
Medical Positions
Medical Positions
[replacetext(job.title, " ", " ")][replacetext(job.title, " ", " ")][replacetext(job.title, " ", " ")][replacetext(job.title, " ", " ")]
" - jobs += "" + jobs += "" for(var/jobPos in science_positions) if(!jobPos) continue var/datum/job/job = job_master.GetJob(jobPos) if(!job) continue if(jobban_isbanned(M, job.title)) - jobs += "" + jobs += "" counter++ else - jobs += "" + jobs += "" counter++ if(counter >= 5) //So things dont get squiiiiished! @@ -606,17 +608,17 @@ //Support (Grey) counter = 0 jobs += "
Science Positions
Science Positions
[replacetext(job.title, " ", " ")][replacetext(job.title, " ", " ")][replacetext(job.title, " ", " ")][replacetext(job.title, " ", " ")]
" - jobs += "" + jobs += "" for(var/jobPos in support_positions) if(!jobPos) continue var/datum/job/job = job_master.GetJob(jobPos) if(!job) continue if(jobban_isbanned(M, job.title)) - jobs += "" + jobs += "" counter++ else - jobs += "" + jobs += "" counter++ if(counter >= 5) //So things dont get squiiiiished! @@ -627,17 +629,17 @@ //Non-Human (Green) counter = 0 jobs += "
Support Positions
Support Positions
[replacetext(job.title, " ", " ")][replacetext(job.title, " ", " ")][replacetext(job.title, " ", " ")][replacetext(job.title, " ", " ")]
" - jobs += "" + jobs += "" for(var/jobPos in nonhuman_positions) if(!jobPos) continue var/datum/job/job = job_master.GetJob(jobPos) if(!job) continue if(jobban_isbanned(M, job.title)) - jobs += "" + jobs += "" counter++ else - jobs += "" + jobs += "" counter++ if(counter >= 5) //So things dont get squiiiiished! @@ -646,29 +648,29 @@ //Drone if(jobban_isbanned(M, "Drone")) - jobs += "" + jobs += "" else - jobs += "" + jobs += "" //pAI if(jobban_isbanned(M, "pAI")) - jobs += "" + jobs += "" else - jobs += "" + jobs += "" jobs += "
Non-human Positions
Non-human Positions
[replacetext(job.title, " ", " ")][replacetext(job.title, " ", " ")][replacetext(job.title, " ", " ")][replacetext(job.title, " ", " ")]DroneDroneDroneDronepAIpAIpAIpAI
" //Antagonist (Orange) var/isbanned_dept = jobban_isbanned(M, "Syndicate") jobs += "" - jobs += "" + jobs += "" counter = 0 for(var/role in antag_roles) if(jobban_isbanned(M, role) || isbanned_dept) - jobs += "" + jobs += "" else - jobs += "" + jobs += "" counter++ if(counter >= 5) //So things dont get squiiiiished! @@ -683,9 +685,9 @@ counter = 0 for(var/role in other_roles) if(jobban_isbanned(M, role) || isbanned_dept) - jobs += "" + jobs += "" else - jobs += "" + jobs += "" counter++ if(counter >= 5) //So things dont get squiiiiished! @@ -696,17 +698,17 @@ //Whitelisted positions counter = 0 jobs += "
Antagonist Positions
Antagonist Positions
[replacetext(role, " ", " ")][replacetext(role, " ", " ")][replacetext(role, " ", " ")][replacetext(role, " ", " ")][replacetext(role, " ", " ")][replacetext(role, " ", " ")][replacetext(role, " ", " ")][replacetext(role, " ", " ")]
" - jobs += "" + jobs += "" for(var/jobPos in whitelisted_positions) if(!jobPos) continue var/datum/job/job = job_master.GetJob(jobPos) if(!job) continue if(jobban_isbanned(M, job.title)) - jobs += "" + jobs += "" counter++ else - jobs += "" + jobs += "" counter++ if(counter >= 5) //So things dont get squiiiiished! @@ -733,6 +735,8 @@ alert("You cannot perform this action. You must be of a higher administrative rank!") return + var/ban_ckey_param = href_list["dbbanaddckey"] + if(!job_master) to_chat(usr, "Job Master has not been setup!") return @@ -800,7 +804,7 @@ //Banning comes first if(notbannedlist.len) //at least 1 unbanned job exists in joblist so we have stuff to ban. - switch(alert("Temporary Ban?",,"Yes","No", "Cancel")) + switch(alert("Temporary Ban of [M.ckey]?",,"Yes","No", "Cancel")) if("Yes") if(config.ban_legacy_system) to_chat(usr, "Your server is using the legacy banning system, which does not support temporary job bans. Consider upgrading. Aborting ban.") @@ -813,6 +817,7 @@ return var/msg + M = admin_ban_mobsearch(M, ban_ckey_param, usr) for(var/job in notbannedlist) ban_unban_log_save("[key_name(usr)] temp-jobbanned [key_name(M)] from [job] for [mins] minutes. reason: [reason]") log_admin("[key_name(usr)] temp-jobbanned [key_name(M)] from [job] for [mins] minutes") @@ -835,6 +840,7 @@ var/reason = input(usr,"Please state the reason","Reason","") as message|null if(reason) var/msg + M = admin_ban_mobsearch(M, ban_ckey_param, usr) for(var/job in notbannedlist) ban_unban_log_save("[key_name(usr)] perma-jobbanned [key_name(M)] from [job]. reason: [reason]") log_admin("[key_name(usr)] perma-banned [key_name(M)] from [job]") @@ -959,9 +965,11 @@ if(!check_rights(R_BAN)) return var/mob/M = locateUID(href_list["newban"]) - if(!ismob(M)) return + if(!ismob(M)) + return + var/ban_ckey_param = href_list["dbbanaddckey"] - switch(alert("Temporary Ban?",,"Yes","No", "Cancel")) + switch(alert("Temporary Ban of [M.ckey] / [ban_ckey_param]?",,"Yes","No", "Cancel")) if("Yes") var/mins = input(usr,"How long (in minutes)?","Ban time",1440) as num|null if(!mins) @@ -970,6 +978,7 @@ var/reason = input(usr,"Please state the reason","Reason") as message|null if(!reason) return + M = admin_ban_mobsearch(M, ban_ckey_param, usr) AddBan(M.ckey, M.computer_id, reason, usr.ckey, 1, mins) ban_unban_log_save("[usr.client.ckey] has banned [M.ckey]. - Reason: [reason] - This will be removed in [mins] minutes.") to_chat(M, "You have been banned by [usr.client.ckey].\nReason: [reason].") @@ -991,10 +1000,13 @@ if(!reason) return switch(alert(usr,"IP ban?",,"Yes","No","Cancel")) - if("Cancel") return + if("Cancel") + return if("Yes") + M = admin_ban_mobsearch(M, ban_ckey_param, usr) AddBan(M.ckey, M.computer_id, reason, usr.ckey, 0, 0, M.lastKnownIP) if("No") + M = admin_ban_mobsearch(M, ban_ckey_param, usr) AddBan(M.ckey, M.computer_id, reason, usr.ckey, 0, 0) to_chat(M, "You have been banned by [usr.client.ckey].\nReason: [reason].") to_chat(M, "This is a permanent ban.") @@ -1869,6 +1881,7 @@ ptypes += "Assassin" ptypes += "Hunter" ptypes += "Crew Traitor" + ptypes += "Floor Cluwne" var/punishment = input(owner, "How would you like to smite [M]?", "Its good to be baaaad...", "") as null|anything in ptypes if(!(punishment in ptypes)) return @@ -1978,6 +1991,12 @@ if("Gib") M.gib(FALSE) logmsg = "gibbed." + if("Floor Cluwne") + logmsg = "floor cluwne" + var/turf/T = get_turf(M) + var/mob/living/simple_animal/hostile/floor_cluwne/FC = new /mob/living/simple_animal/hostile/floor_cluwne(T) + FC.smiting = TRUE + FC.Acquire_Victim(M) if(logmsg) log_admin("[key_name(owner)] smited [key_name(M)] with: [logmsg]") message_admins("[key_name_admin(owner)] smited [key_name_admin(M)] with: [logmsg]") @@ -1991,8 +2010,12 @@ if(!isLivingSSD(H)) to_chat(usr, "This can only be used on living, SSD players.") return - var/success = cryo_ssd(H) - if(success) + if(istype(H.loc, /obj/machinery/cryopod)) + var/obj/machinery/cryopod/P = H.loc + P.despawn_occupant() + log_admin("[key_name(usr)] despawned [H.job] [H] in cryo.") + message_admins("[key_name_admin(usr)] despawned [H.job] [H] in cryo.") + else if(cryo_ssd(H)) log_admin("[key_name(usr)] sent [H.job] [H] to cryo.") message_admins("[key_name_admin(usr)] sent [H.job] [H] to cryo.") else if(href_list["FaxReplyTemplate"]) @@ -3270,6 +3293,13 @@ ticker.mode.station_goals += G modify_goals() + else if(href_list["showdetails"]) + if(!check_rights(R_ADMIN)) + return + var/text = html_decode(href_list["showdetails"]) + usr << browse("Details[replacetext(text, "\n", "
")]
", + "window=show_details;size=500x200") + // Library stuff else if(href_list["library_book_id"]) var/isbn = sanitizeSQL(href_list["library_book_id"]) diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index f944d015749..24ce21276e7 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -937,25 +937,20 @@ Traitors and the like can also be revived with the previous role mostly intact. /client/proc/reset_all_tcs() set category = "Admin" - set name = "Reset Telecomms Scripts" - set desc = "Blanks all telecomms scripts from all telecomms servers" + set name = "Reset NTTC Configuration" + set desc = "Resets NTTC to the default configuration." if(!check_rights(R_ADMIN)) return - var/confirm = alert(src, "You sure you want to blank all NTSL scripts?", "Confirm", "Yes", "No") + var/confirm = alert(src, "You sure you want to reset NTTC?", "Confirm", "Yes", "No") if(confirm != "Yes") return - for(var/obj/machinery/telecomms/server/S in telecomms_list) - var/datum/TCS_Compiler/C = S.Compiler - S.rawcode = "" - C.Compile("") - for(var/obj/machinery/computer/telecomms/traffic/T in GLOB.machines) - T.storedcode = "" - log_admin("[key_name(usr)] blanked all telecomms scripts.") - message_admins("[key_name_admin(usr)] blanked all telecomms scripts.") - feedback_add_details("admin_verb","RAT") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + GLOB.nttc_config.reset() + log_admin("[key_name(usr)] reset NTTC scripts.") + message_admins("[key_name_admin(usr)] reset NTTC scripts.") + feedback_add_details("admin_verb","RAT2") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/proc/list_ssds() set category = "Admin" @@ -984,15 +979,22 @@ Traitors and the like can also be revived with the previous role mostly intact. if(job_string in command_positions) job_string = "" + job_string + "" role_string = "-" + var/obj_count = 0 + var/obj_string = "" if(H.mind) if(H.mind.special_role) role_string = "[H.mind.special_role]" if(!H.key && H.mind.key) key_string = H.mind.key - msg += "" + for(var/datum/objective/O in all_objectives) + if(O.target == H.mind) + obj_count++ + if(obj_count > 0) + obj_string = "
Obj Target" + msg += "" msg += "" if(istype(H.loc, /obj/machinery/cryopod)) - msg += "" + msg += "" else msg += "" msg += "" diff --git a/code/modules/admin/verbs/spawnfloorcluwne.dm b/code/modules/admin/verbs/spawnfloorcluwne.dm new file mode 100644 index 00000000000..02ff9eda6e2 --- /dev/null +++ b/code/modules/admin/verbs/spawnfloorcluwne.dm @@ -0,0 +1,26 @@ +/client/proc/spawn_floor_cluwne() + set category = "Event" + set name = "Unleash Floor Cluwne" + set desc = "Pick a specific target or just let it select randomly and spawn the floor cluwne mob on the station. Be warned: spawning more than one may cause issues!" + var/target + + if(!check_rights(R_EVENT)) + return + + var/confirm = alert("Are you sure you want to release a floor cluwne and kill alot of people?", "Confirm Massacre", "Yes", "No") + if(confirm == "Yes") + + var/turf/T = get_turf(usr) + target = input("Any specific target in mind? Please note only live, non cluwned, human targets are valid.", "Target", target) as null|anything in GLOB.player_list + if(isnull(target)) + return + if(target && ishuman(target)) + var/mob/living/carbon/human/H = target + var/mob/living/simple_animal/hostile/floor_cluwne/FC = new /mob/living/simple_animal/hostile/floor_cluwne(T) + FC.Acquire_Victim(H) + else + new /mob/living/simple_animal/hostile/floor_cluwne(T) + log_admin("[key_name(usr)] spawned floor cluwne.") + message_admins("[key_name(usr)] spawned floor cluwne.") + else + return diff --git a/code/modules/assembly/signaler.dm b/code/modules/assembly/signaler.dm index a71bbba6a59..5e7c8c58a72 100644 --- a/code/modules/assembly/signaler.dm +++ b/code/modules/assembly/signaler.dm @@ -13,7 +13,7 @@ bomb_name = "remote-control bomb" var/code = 30 - var/frequency = 1457 + var/frequency = RSD_FREQ var/delay = 0 var/datum/radio_frequency/radio_connection var/airlock_wire = null diff --git a/code/modules/atmos_automation/console.dm b/code/modules/atmos_automation/console.dm index f4c3873717c..a810d3b08c5 100644 --- a/code/modules/atmos_automation/console.dm +++ b/code/modules/atmos_automation/console.dm @@ -228,7 +228,7 @@ var/injector_tag="inc_in" var/output_tag="inc_out" var/sensor_tag="inc_sensor" - frequency=1449 + frequency=AIRLOCK_FREQ var/temperature=1000 /obj/machinery/computer/general_air_control/atmos_automation/burnchamber/New() @@ -310,7 +310,7 @@ var/o2_injector_tag="air_o2_in" var/output_tag="air_out" var/sensor_tag="air_sensor" - frequency=1443 + frequency=ATMOS_DISTRO_FREQ var/temperature=1000 /obj/machinery/computer/general_air_control/atmos_automation/air_mixing/New() diff --git a/code/modules/client/asset_cache.dm b/code/modules/client/asset_cache.dm index 4c595b23411..b875301083d 100644 --- a/code/modules/client/asset_cache.dm +++ b/code/modules/client/asset_cache.dm @@ -17,8 +17,8 @@ You can set verify to TRUE if you want send() to sleep until the client has the //When sending mutiple assets, how many before we give the client a quaint little sending resources message #define ASSET_CACHE_TELL_CLIENT_AMOUNT 8 -//List of ALL assets for the above, format is list(filename = asset). -/var/global/list/asset_cache = list() +//When passively preloading assets, how many to send at once? Too high creates noticable lag where as too low can flood the client's cache with "verify" files +#define ASSET_CACHE_PRELOAD_CONCURRENT 3 /client var/list/cache = list() // List of all assets sent to this client by the asset cache. @@ -44,13 +44,10 @@ You can set verify to TRUE if you want send() to sleep until the client has the if(client.cache.Find(asset_name) || client.sending.Find(asset_name)) return 0 - client << browse_rsc(asset_cache[asset_name], asset_name) - if(!verify || !winexists(client, "asset_cache_browser")) // Can't access the asset cache browser, rip. - if(client) - client.cache += asset_name + client << browse_rsc(SSassets.cache[asset_name], asset_name) + if(!verify) // Can't access the asset cache browser, rip. + client.cache += asset_name return 1 - if(!client) - return 0 client.sending |= asset_name var/job = ++client.last_asset_job @@ -94,15 +91,13 @@ You can set verify to TRUE if you want send() to sleep until the client has the if(unreceived.len >= ASSET_CACHE_TELL_CLIENT_AMOUNT) to_chat(client, "Sending Resources...") for(var/asset in unreceived) - if(asset in asset_cache) - client << browse_rsc(asset_cache[asset], asset) + if(asset in SSassets.cache) + client << browse_rsc(SSassets.cache[asset], asset) - if(!verify || !winexists(client, "asset_cache_browser")) // Can't access the asset cache browser, rip. - if(client) - client.cache += unreceived + if(!verify) // Can't access the asset cache browser, rip. + client.cache += unreceived return 1 - if(!client) - return 0 + client.sending |= unreceived var/job = ++client.last_asset_job @@ -127,30 +122,25 @@ You can set verify to TRUE if you want send() to sleep until the client has the //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(var/client/client, var/list/files, var/register_asset = TRUE) +/proc/getFilesSlow(var/client/client, var/list/files, var/register_asset = TRUE) + var/concurrent_tracker = 1 for(var/file in files) if(!client) break if(register_asset) - register_asset(file,files[file]) - send_asset(client,file) - sleep(-1) //queuing calls like this too quickly can cause issues in some client versions + register_asset(file, files[file]) + if(concurrent_tracker >= ASSET_CACHE_PRELOAD_CONCURRENT) + concurrent_tracker = 1 + send_asset(client, file) + else + concurrent_tracker++ + send_asset(client, file, verify = FALSE) + sleep(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. //if it's an icon or something be careful, you'll have to copy it before further use. /proc/register_asset(var/asset_name, var/asset) - asset_cache[asset_name] = asset - -//From here on out it's populating the asset cache. -/proc/populate_asset_cache() - for(var/type in typesof(/datum/asset) - list(/datum/asset, /datum/asset/simple)) - var/datum/asset/A = new type() - A.register() - - for(var/client/C in GLOB.clients) - //doing this to a client too soon after they've connected can cause issues, also the proc we call sleeps - spawn(10) - getFilesSlow(C, asset_cache, FALSE) + SSassets.cache[asset_name] = asset //These datums are used to populate the asset cache, the proc "register()" does this. diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm index bff5bd23ce4..50176f96c5e 100644 --- a/code/modules/client/client procs.dm +++ b/code/modules/client/client procs.dm @@ -642,9 +642,9 @@ 'html/search.js', // Used in various non-NanoUI HTML windows for search functionality 'html/panels.css' // Used for styling certain panels, such as in the new player panel ) - spawn (10) + spawn (10) //removing this spawn causes all clients to not get verbs. //Precache the client with all other assets slowly, so as to not block other browse() calls - getFilesSlow(src, asset_cache, register_asset = FALSE) + getFilesSlow(src, SSassets.preload, register_asset = FALSE) //For debugging purposes /client/proc/list_all_languages() diff --git a/code/modules/clothing/suits/hood.dm b/code/modules/clothing/suits/hood.dm index c784306cf66..3718a16602c 100644 --- a/code/modules/clothing/suits/hood.dm +++ b/code/modules/clothing/suits/hood.dm @@ -5,6 +5,24 @@ var/obj/item/clothing/head/hood var/hoodtype = /obj/item/clothing/head/winterhood //so the chaplain hoodie or other hoodies can override this +/obj/item/clothing/head/chaplain_hood + flags = NODROP + +/obj/item/clothing/head/nun_hood + flags = NODROP + +/obj/item/clothing/head/monk_hood + flags = NODROP + +/obj/item/clothing/head/culthood + flags = NODROP + +/obj/item/clothing/head/culthood/alt + flags = NODROP + +/obj/item/clothing/head/berserkerhood + flags = NODROP + /obj/item/clothing/suit/hooded/New() MakeHood() ..() diff --git a/code/modules/events/event_container.dm b/code/modules/events/event_container.dm index 0a99ed6fd14..c90cbd12777 100644 --- a/code/modules/events/event_container.dm +++ b/code/modules/events/event_container.dm @@ -195,7 +195,8 @@ var/list/event_last_fired = list() new /datum/event_meta/alien(EVENT_LEVEL_MAJOR, "Alien Infestation", /datum/event/alien_infestation, 0, list(ASSIGNMENT_SECURITY = 15), 1), new /datum/event_meta(EVENT_LEVEL_MAJOR, "Traders", /datum/event/traders, 0, is_one_shot = 1), new /datum/event_meta(EVENT_LEVEL_MAJOR, "Terror Spiders", /datum/event/spider_terror, 0, list(ASSIGNMENT_SECURITY = 15), is_one_shot = 1), - new /datum/event_meta(EVENT_LEVEL_MAJOR, "Slaughter Demon", /datum/event/spawn_slaughter, 15, is_one_shot = 1) + new /datum/event_meta(EVENT_LEVEL_MAJOR, "Slaughter Demon", /datum/event/spawn_slaughter, 15, is_one_shot = 1), + new /datum/event_meta(EVENT_LEVEL_MAJOR, "Floor Cluwne", /datum/event/spawn_floor_cluwne, 15, is_one_shot = 1) ) diff --git a/code/modules/events/floorcluwne.dm b/code/modules/events/floorcluwne.dm new file mode 100644 index 00000000000..12c2c4aea95 --- /dev/null +++ b/code/modules/events/floorcluwne.dm @@ -0,0 +1,15 @@ +/datum/event/spawn_floor_cluwne + + +/datum/event/spawn_floor_cluwne/start() + + if(!xeno_spawn) + message_admins("No valid spawn locations found, aborting...") + return kill() + + var/turf/T = get_turf(pick(xeno_spawn)) + var/mob/living/simple_animal/hostile/floor_cluwne/S = new(T) + playsound(S, 'sound/spookoween/scary_horn.ogg', 50, 1, -1) + message_admins("A floor cluwne has been spawned at [COORD(T)][ADMIN_JMP(T)]") + log_game("A floor cluwne has been spawned at [COORD(T)]") + return 1 \ No newline at end of file diff --git a/code/modules/games/cards.dm b/code/modules/games/cards.dm index 459d8d144f5..a24f947a25a 100644 --- a/code/modules/games/cards.dm +++ b/code/modules/games/cards.dm @@ -220,24 +220,20 @@ if(M.incapacitated() || !Adjacent(M)) return - if(over_object == M) + if(over_object == M || istype(over_object, /obj/screen)) if(!remove_item_from_storage(M)) M.unEquip(src) - M.put_in_hands(src) + if(over_object != M) + switch(over_object.name) + if("r_hand") + M.put_in_r_hand(src) + if("l_hand") + M.put_in_l_hand(src) + else + M.put_in_hands(src) - else if(istype(over_object, /obj/screen)) - switch(over_object.name) - if("r_hand") - if(!remove_item_from_storage(M)) - M.unEquip(src) - M.put_in_r_hand(src) - if("l_hand") - if(!remove_item_from_storage(M)) - M.unEquip(src) - M.put_in_l_hand(src) - - add_fingerprint(M) - usr.visible_message("[usr] picks up the deck.") + add_fingerprint(M) + usr.visible_message("[usr] picks up the deck.") /obj/item/pack name = "Card Pack" diff --git a/code/modules/mob/living/silicon/robot/update_status.dm b/code/modules/mob/living/silicon/robot/update_status.dm index 352750a23ea..fafc5a4c8c3 100644 --- a/code/modules/mob/living/silicon/robot/update_status.dm +++ b/code/modules/mob/living/silicon/robot/update_status.dm @@ -34,6 +34,31 @@ // diag_hud_set_health() // update_health_hud() +/mob/living/silicon/robot/SetStunned(amount, updating = 1, force = 0) //if you REALLY need to set stun to a set amount without the whole "can't go below current stunned" + . = STATUS_UPDATE_CANMOVE + if((!!amount) == (!!stunned)) // We're not changing from + to 0 or vice versa + updating = FALSE + . = STATUS_UPDATE_NONE + + if(status_flags & CANSTUN || force) + stunned = max(amount, 0) + if(updating) + update_stat() + else + return STATUS_UPDATE_NONE + +/mob/living/silicon/robot/SetWeakened(amount, updating = 1, force = 0) + . = STATUS_UPDATE_CANMOVE + if((!!amount) == (!!weakened)) // We're not changing from + to 0 or vice versa + updating = FALSE + . = STATUS_UPDATE_NONE + if(status_flags & CANWEAKEN || force) + weakened = max(amount, 0) + if(updating) + update_stat() + else + return STATUS_UPDATE_NONE + /mob/living/silicon/robot/update_revive(updating = TRUE) . = ..(updating) if(.) diff --git a/code/modules/mob/living/simple_animal/hostile/floorcluwne.dm b/code/modules/mob/living/simple_animal/hostile/floorcluwne.dm new file mode 100644 index 00000000000..04c6220f12d --- /dev/null +++ b/code/modules/mob/living/simple_animal/hostile/floorcluwne.dm @@ -0,0 +1,423 @@ +#define STAGE_HAUNT 1 +#define STAGE_SPOOK 2 +#define STAGE_TORMENT 3 +#define STAGE_ATTACK 4 +#define MANIFEST_DELAY 9 + +/mob/living/simple_animal/hostile/floor_cluwne + name = "???" + desc = "...." + icon = 'icons/goonstation/objects/clothing/mask.dmi' + icon_state = "cursedclown" + icon_living = "cursedclown" + icon_gib = "clown_gib" + maxHealth = 200 + health = 200 + speed = -1 + attacktext = "attacks" + attack_sound = 'sound/items/bikehorn.ogg' + del_on_death = TRUE + pass_flags = PASSTABLE | PASSGRILLE | PASSMOB | LETPASSTHROW | PASSGLASS | PASSBLOB//it's practically a ghost when unmanifested (under the floor) + loot = list(/obj/item/clothing/mask/cursedclown) + a_intent = INTENT_HARM + wander = FALSE + minimum_distance = 2 + move_to_delay = 1 + environment_smash = FALSE + pixel_y = 8 + pressure_resistance = 200 + minbodytemp = 0 + maxbodytemp = 1500 + atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) + var/mob/living/carbon/human/current_victim + var/manifested = FALSE + var/switch_stage = 60 + var/stage = STAGE_HAUNT + var/interest = 0 + var/target_area + var/invalid_area_typecache = list(/area/space, /area/centcom) + var/eating = FALSE + var/smiting = FALSE + var/admincluwne = FALSE + + +/mob/living/simple_animal/hostile/floor_cluwne/New() + . = ..() + remove_from_all_data_huds() + var/obj/item/card/id/access_card = new (src) + access_card.access = get_all_accesses()//THERE IS NO ESCAPE + access_card.flags |= NODROP + invalid_area_typecache = typecacheof(invalid_area_typecache) + Manifest() + if(!current_victim) + var/turf/current_location = get_turf(src) + if(!is_admin_level(current_location.z))//admin spawned off station Z for some reason do not trigger anything else + admincluwne = TRUE + return + Acquire_Victim() + + +/mob/living/simple_animal/hostile/floor_cluwne/Destroy() + return ..() + + +/mob/living/simple_animal/hostile/floor_cluwne/attack_hand(mob/living/carbon/human/M) + ..() + playsound(src.loc, 'sound/items/bikehorn.ogg', 50, 1) + + +/mob/living/simple_animal/hostile/floor_cluwne/CanPass(atom/A, turf/target) + return TRUE + + +/mob/living/simple_animal/hostile/floor_cluwne/Life(seconds, times_fired) + do_jitter_animation(1000) + pixel_y = 8 + + if(is_type_in_typecache(get_area(src.loc), invalid_area_typecache)) + var/area = pick(teleportlocs) + var/area/tp = teleportlocs[area] + forceMove(pick(get_area_turfs(tp.type))) + + if(!current_victim && !admincluwne) + Acquire_Victim() + + if(stage && !manifested) + On_Stage() + + if(stage == STAGE_ATTACK) + playsound(src, 'sound/spookoween/ghost_whisper.ogg', 75, 1) + + if(eating) + return + + var/turf/T = get_turf(current_victim) + if(prob(5))//checks roughly every 20 ticks + if(!admincluwne) + if(current_victim.stat == DEAD || current_victim.get_int_organ(/obj/item/organ/internal/honktumor/cursed) || is_type_in_typecache(get_area(T), invalid_area_typecache)) + Acquire_Victim() + + if(get_dist(src, current_victim) > 9 && !manifested && !is_type_in_typecache(get_area(T), invalid_area_typecache))//if cluwne gets stuck he just teleports + do_teleport(src, T) + + interest++ + if(interest >= switch_stage * 4) + stage = STAGE_ATTACK + + else if(interest >= switch_stage * 2) + stage = STAGE_TORMENT + + else if(interest >= switch_stage) + stage = STAGE_SPOOK + + else if(interest < switch_stage) + stage = STAGE_HAUNT + + ..() + + +/mob/living/simple_animal/hostile/floor_cluwne/Goto(target, delay, minimum_distance) + if(!manifested && !is_type_in_typecache(get_area(current_victim.loc), invalid_area_typecache)) + walk_to(src, target, minimum_distance, delay) + else + walk_to(src,0) + + +/mob/living/simple_animal/hostile/floor_cluwne/FindTarget() + return current_victim + + +/mob/living/simple_animal/hostile/floor_cluwne/CanAttack(atom/the_target)//you will not escape + return TRUE + + +/mob/living/simple_animal/hostile/floor_cluwne/AttackingTarget() + return + + +/mob/living/simple_animal/hostile/floor_cluwne/LoseTarget() + return + + +/mob/living/simple_animal/hostile/floor_cluwne/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, tesla_shock = 0, illusion = 0, stun = TRUE)//prevents runtimes with machine fuckery + return FALSE + + +/mob/living/simple_animal/hostile/floor_cluwne/proc/Acquire_Victim(specific) + var/list/players_copy = GLOB.player_list.Copy() + while(players_copy.len) + var/mob/living/carbon/human/H = pick_n_take(players_copy) + + if(specific) + H = specific + if((!H || H.stat == DEAD) && smiting)//safety check, target somehow DIED after we sent a smite + message_admins("Smiting Floor Cluwne was deleted due to a lack of valid target. Someone killed them first, or they ceased to exist.") + qdel(src) + return + if(H.stat != DEAD && !isLivingSSD(H) && H.client && !H.get_int_organ(/obj/item/organ/internal/honktumor/cursed) && !is_type_in_typecache(get_area(H.loc), invalid_area_typecache)) + current_victim = H + return target = current_victim + + if(H && ishuman(H) && H.stat != DEAD && H != current_victim && !isLivingSSD(H) && H.client && !H.get_int_organ(/obj/item/organ/internal/honktumor/cursed) && !is_type_in_typecache(get_area(H.loc), invalid_area_typecache)) + current_victim = H + interest = 0 + return target = current_victim + + + message_admins("Floor Cluwne was deleted due to a lack of valid targets, if this was a manually targeted instance please re-evaluate your choice.") + qdel(src) + +/mob/living/simple_animal/hostile/floor_cluwne/proc/Manifest()//handles disappearing and appearance anim + if(manifested) + new /obj/effect/temp_visual/fcluwne_manifest(loc) + addtimer(CALLBACK(src, /mob/living/simple_animal/hostile/floor_cluwne/.proc/Appear), MANIFEST_DELAY) + + else + layer = GAME_PLANE + invisibility = INVISIBILITY_MAXIMUM + mouse_opacity = 0 + density = FALSE + +/mob/living/simple_animal/hostile/floor_cluwne/proc/Appear()//handled in a seperate proc so floor cluwne doesn't appear before the animation finishes + layer = MOB_LAYER + invisibility = FALSE + mouse_opacity = 1 + density = TRUE + + +/mob/living/simple_animal/hostile/floor_cluwne/proc/Reset_View(screens, color, mob/living/carbon/human/H) + if(screens) + for(var/whole_screen in screens) + animate(whole_screen, transform = matrix(), time = 5, easing = QUAD_EASING) + if(color && H) + animate(H.client, color = color, time = 5) + + +/mob/living/simple_animal/hostile/floor_cluwne/proc/On_Stage() + var/mob/living/carbon/human/H = current_victim + switch(stage) + + if(STAGE_HAUNT) + + if(prob(5)) + H.AdjustEyeBlurry(1) + + if(prob(5)) + H.playsound_local(src,'sound/spookoween/insane_low_laugh.ogg', 1) + + if(prob(8)) + H.playsound_local(src,'sound/spookoween/ghost_whisper.ogg', 5) + + if(prob(5)) + var/obj/item/I = locate() in orange(H, 8) + if(I && !I.anchored) + I.throw_at(H, 4, 3) + to_chat(H, "What threw that?") + + if(STAGE_SPOOK) + + if(prob(4)) + H.slip("???", 5, 2) + to_chat(H, "The floor shifts underneath you!") + + if(prob(3)) + H.playsound_local(src,'sound/spookoween/scary_horn.ogg', 2) + + if(prob(8)) + H.playsound_local(src,'sound/spookoween/scary_horn2.ogg', 2) + + if(prob(5)) + H.playsound_local(src,'sound/hallucinations/growl1.ogg', 10) + to_chat(H, "knoh") + + if(prob(5)) + var/obj/item/I = locate() in orange(H, 8) + if(I && !I.anchored) + I.throw_at(H, 4, 3) + to_chat(H, "What threw that?") + + if(prob(4)) + to_chat(H, "yalp ot tnaw I") + Appear() + manifested = FALSE + addtimer(CALLBACK(src, /mob/living/simple_animal/hostile/floor_cluwne/.proc/Manifest), 1) + + if(STAGE_TORMENT) + + if(prob(5)) + H.slip("???", 5, 2) + to_chat(H, "The floor shifts underneath you!") + + if(prob(5)) + playsound(src, pick('sound/spookoween/scary_horn.ogg', 'sound/spookoween/scary_horn2.ogg', 'sound/spookoween/scary_horn3.ogg'), 30, 1) + + if(prob(3)) + playsound(src, pick('sound/hallucinations/growl1.ogg', 'sound/hallucinations/growl2.ogg') , 30, 1) + + + if(prob(4)) + for(var/obj/item/I in orange(H, 5)) + if(I && !I.anchored) + I.throw_at(H, 4, 3) + to_chat(H, "What the hell?!") + + if(prob(5)) + to_chat(H, "Something feels very wrong...") + H.playsound_local(src,'sound/hallucinations/behind_you1.ogg', 25) + H.flash_eyes() + + if(prob(5)) + to_chat(H, "!?REHTOMKNOH eht esiarp uoy oD") + to_chat(H, "Something grabs your foot!") + H.playsound_local(src,'sound/hallucinations/i_see_you1.ogg', 25) + H.Stun(10) + + if(prob(5)) + to_chat(H, "!KNOH ?od nottub siht seod tahW") + for(var/obj/machinery/M in range(H, 6)) + M.attack_hand(src) + + if(prob(6)) + for(var/turf/simulated/floor/O in range(src, 6)) + O.MakeSlippery(TURF_WET_WATER, 10) + playsound(src, 'sound/effects/clownstep1.ogg', 30, 1) + + if(prob(5)) + to_chat(H, "WHAT THE FUCK IS THAT?!") + to_chat(H, ".KNOH !nuf hcum os si uoy htiw gniyalP .KNOH KNOH KNOH") + H.playsound_local(src,'sound/hallucinations/im_here1.ogg', 25) + H.reagents.add_reagent("lsd", 3) + Appear() + manifested = FALSE + addtimer(CALLBACK(src, /mob/living/simple_animal/hostile/floor_cluwne/.proc/Manifest), 2) + for(var/obj/machinery/light/L in range(H, 8)) + L.flicker() + + if(STAGE_ATTACK) + + if(!eating) + for(var/I in getline(src,H)) + var/turf/T = I + for(var/obj/structure/O in T) + if(istype(O, /obj/structure/closet)) + var/obj/structure/closet/locker = O + locker.dump_contents() + if(O.density || istype(O, /obj/machinery/door/airlock)) + forceMove(H.loc) + if(T.density) + forceMove(H.loc) + if(H.buckled) + H.buckled.unbuckle_mob() + manifested = TRUE + Manifest() + to_chat(H, "You feel the floor closing in on your feet!") + H.Weaken(30) + H.emote("scream") + H.adjustBruteLoss(10) + if(!eating) + addtimer(CALLBACK(src, /mob/living/simple_animal/hostile/floor_cluwne/.proc/Grab, H), 70) + for(var/turf/simulated/floor/O in range(src, 6)) + O.MakeSlippery(TURF_WET_LUBE, 20) + playsound(src, 'sound/effects/meteorimpact.ogg', 30, 1) + + eating = TRUE + + +/mob/living/simple_animal/hostile/floor_cluwne/proc/Grab(mob/living/carbon/human/H) + to_chat(H, "You feel a cold, gloved hand clamp down on your ankle!") + for(var/I in 1 to get_dist(src, H)) + + if(do_after(src, 10, target = H)) + step_towards(H, src) + playsound(H, pick('sound/effects/bodyscrape-01.ogg', 'sound/effects/bodyscrape-02.ogg'), 20, 1, -4) + H.emote("scream") + if(prob(25)) + playsound(src, pick('sound/hallucinations/growl1.ogg', 'sound/hallucinations/growl2.ogg', 'sound/items/bikehorn.ogg'), 50, 1) + + if(get_dist(src,H) <= 1) + visible_message("[src] begins dragging [H] under the floor!") + + if(do_after(src, 50, target = H) && eating) + H.BecomeBlind() + H.layer = GAME_PLANE + H.invisibility = INVISIBILITY_MAXIMUM + H.mouse_opacity = 0 + H.density = FALSE + H.anchored = TRUE + addtimer(CALLBACK(src, /mob/living/simple_animal/hostile/floor_cluwne/.proc/Kill, H), 100) + H.visible_message("[src] pulls [H] under the floor!") + else//some fuck pulled away our food + stage = STAGE_TORMENT + eating = FALSE + + else//STOP PULLING AWAY THE FOOD + eating = FALSE + stage = STAGE_TORMENT + + manifested = FALSE + Manifest() + + +/mob/living/simple_animal/hostile/floor_cluwne/proc/Kill(mob/living/carbon/human/H) + playsound(H, 'sound/spookoween/scary_horn2.ogg', 100, 0) + var/old_color = H.client.color + var/red_splash = list(1,0,0,0.8,0.2,0, 0.8,0,0.2,0.1,0,0) + var/pure_red = list(0,0,0,0,0,0,0,0,0,1,0,0) + H.client.color = pure_red + + animate(H.client, color = red_splash, time = 10, easing = SINE_EASING|EASE_OUT) + for(var/turf/T in orange(H, 4)) + H.add_splatter_floor(T) + if(do_after(src, 50, target = H)) + + + if(prob(50) || smiting) + H.makeCluwne() + + H.adjustBruteLoss(30) + H.adjustBrainLoss(100) + for(var/I in H.bodyparts) + var/obj/item/organ/external/O = I + if(O.name == "head")//irksome runtimes + O.droplimb() + continue + O.drop_organs() + O.droplimb() + + Reset_View(FALSE, old_color, H) + H.CureBlind() + H.layer = initial(H.layer) + H.invisibility = initial(H.invisibility) + H.mouse_opacity = initial(H.mouse_opacity) + H.density = initial(H.density) + H.anchored = initial(H.anchored) + + eating = FALSE + if(prob(2)) + switch_stage = switch_stage * 0.75 //he gets a chance to be faster after each feast + if(smiting) + playsound(loc, 'sound/spookoween/scary_horn2.ogg', 100, 0, -4) + qdel(src) + else + Acquire_Victim() + + interest = 0 + +//manifestation animation +/obj/effect/temp_visual/fcluwne_manifest + icon = 'icons/turf/floors.dmi' + icon_state = "fcluwne_manifest" + layer = TURF_LAYER + duration = 150 + randomdir = FALSE + + +/obj/effect/temp_visual/fcluwne_manifest/New() + . = ..() + playsound(src, 'sound/spookoween/scary_clown_appear.ogg', 100, 1) + +#undef STAGE_HAUNT +#undef STAGE_SPOOK +#undef STAGE_TORMENT +#undef STAGE_ATTACK +#undef MANIFEST_DELAY \ No newline at end of file diff --git a/code/modules/mob/new_player/sprite_accessories/vulpkanin/vulpkanin_facial_hair.dm b/code/modules/mob/new_player/sprite_accessories/vulpkanin/vulpkanin_facial_hair.dm index 57a409cde95..fca910b401a 100644 --- a/code/modules/mob/new_player/sprite_accessories/vulpkanin/vulpkanin_facial_hair.dm +++ b/code/modules/mob/new_player/sprite_accessories/vulpkanin/vulpkanin_facial_hair.dm @@ -3,6 +3,10 @@ species_allowed = list("Vulpkanin") gender = NEUTER +/datum/sprite_accessory/facial_hair/vulpkanin/vulp_earfluff + name = "Vulpkanin Earfluff" + icon_state = "earfluff" + /datum/sprite_accessory/facial_hair/vulpkanin/vulp_blaze name = "Blaze" icon_state = "blaze" diff --git a/code/modules/modular_computers/file_system/programs/command/comms.dm b/code/modules/modular_computers/file_system/programs/command/comms.dm index 7cfc6ad29a4..9815761bc5a 100644 --- a/code/modules/modular_computers/file_system/programs/command/comms.dm +++ b/code/modules/modular_computers/file_system/programs/command/comms.dm @@ -20,7 +20,6 @@ var/centcomm_message_cooldown = 0 var/tmp_alertlevel = 0 - var/status_display_freq = "1435" var/stat_msg1 var/stat_msg2 var/display_type="blank" diff --git a/code/modules/nano/modules/ert_manager.dm b/code/modules/nano/modules/ert_manager.dm index 080ed3d56ff..6675cd985d4 100644 --- a/code/modules/nano/modules/ert_manager.dm +++ b/code/modules/nano/modules/ert_manager.dm @@ -66,7 +66,7 @@ slots_list += "paranormal: [paranormal_slots]" if(cyborg_slots > 0) slots_list += "cyborg: [cyborg_slots]" - var slot_text = list_implode(slots_list, ", ") + var/slot_text = jointext(slots_list, ", ") notify_ghosts("An ERT is being dispatched. Open positions: [slot_text]") message_admins("[key_name_admin(usr)] dispatched a [ert_type] ERT. Slots: [slot_text]", 1) log_admin("[key_name(usr)] dispatched a [ert_type] ERT. Slots: [slot_text]") diff --git a/code/modules/pda/cart_apps.dm b/code/modules/pda/cart_apps.dm index b92253d4ae9..56ca42154bd 100644 --- a/code/modules/pda/cart_apps.dm +++ b/code/modules/pda/cart_apps.dm @@ -28,7 +28,7 @@ post_status(href_list["statdisp"]) /datum/data/pda/app/status_display/proc/post_status(var/command, var/data1, var/data2) - var/datum/radio_frequency/frequency = radio_controller.return_frequency(1435) + var/datum/radio_frequency/frequency = radio_controller.return_frequency(DISPLAY_FREQ) if(!frequency) return diff --git a/code/modules/pda/radio.dm b/code/modules/pda/radio.dm index a6328dacd6f..8ff24a183b4 100644 --- a/code/modules/pda/radio.dm +++ b/code/modules/pda/radio.dm @@ -162,7 +162,7 @@ /obj/item/integrated_radio/signal - var/frequency = 1457 + var/frequency = RSD_FREQ var/code = 30.0 var/last_transmission var/datum/radio_frequency/radio_connection diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm index ca0c4cb749a..b0ed7c14581 100644 --- a/code/modules/power/singularity/emitter.dm +++ b/code/modules/power/singularity/emitter.dm @@ -89,7 +89,7 @@ /obj/machinery/power/emitter/multitool_menu(var/mob/user,var/obj/item/multitool/P) return {" "} diff --git a/code/modules/projectiles/ammunition/energy.dm b/code/modules/projectiles/ammunition/energy.dm index 322c0931161..10579471b01 100644 --- a/code/modules/projectiles/ammunition/energy.dm +++ b/code/modules/projectiles/ammunition/energy.dm @@ -59,7 +59,7 @@ /obj/item/ammo_casing/energy/xray projectile_type = /obj/item/projectile/beam/xray - e_cost = 50 + e_cost = 100 fire_sound = 'sound/weapons/laser3.ogg' /obj/item/ammo_casing/energy/immolator diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm index 75da1fdbedd..b2a4c213d94 100644 --- a/code/modules/projectiles/guns/energy/laser.dm +++ b/code/modules/projectiles/guns/energy/laser.dm @@ -111,7 +111,7 @@ /obj/item/gun/energy/xray name = "xray laser gun" - desc = "A high-power laser gun capable of expelling concentrated xray blasts." + desc = "A high-power laser gun capable of expelling concentrated xray blasts. These blasts will penetrate solid objects, but will decrease in power the longer they have to travel." icon_state = "xray" origin_tech = "combat=6;materials=4;magnets=4;syndicate=1" ammo_type = list(/obj/item/ammo_casing/energy/xray) diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 868317177bd..39f25c5ef89 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -32,6 +32,8 @@ animate_movement = 0 var/damage = 10 + var/tile_dropoff = 0 //how much damage should be decremented as the bullet moves + var/tile_dropoff_s = 0 //same as above but for stamina var/damage_type = BRUTE //BRUTE, BURN, TOX, OXY, CLONE are the only things that should be in here var/nodamage = FALSE //Determines if the projectile will skip any damage inflictions var/flag = "bullet" //Defines what armor to use when it hits things. Must be set to bullet, laser, energy,or bomb //Cael - bio and rad are also valid @@ -60,9 +62,15 @@ return ..() /obj/item/projectile/proc/Range() - range-- - if(range <= 0 && loc) - on_range() + range-- + if(damage && tile_dropoff) + damage = max(0, damage - tile_dropoff) // decrement projectile damage based on dropoff value for each tile it moves + if(stamina && tile_dropoff_s) + stamina = max(0, stamina - tile_dropoff_s) // as above, but with stamina + if(range <= 0 && loc) + on_range() + if(!damage && !stamina && !nodamage) + on_range() /obj/item/projectile/proc/on_range() //if we want there to be effects when they reach the end of their range qdel(src) diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm index 3cd4e888b1f..b7854d90e13 100644 --- a/code/modules/projectiles/projectile/beams.dm +++ b/code/modules/projectiles/projectile/beams.dm @@ -34,6 +34,7 @@ name = "xray beam" icon_state = "xray" damage = 15 + tile_dropoff = 0.75 irradiate = 30 forcedodge = 1 range = 15 diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm index cd73c90d1cf..c4d9fe2c39f 100644 --- a/code/modules/projectiles/projectile/bullets.dm +++ b/code/modules/projectiles/projectile/bullets.dm @@ -69,17 +69,8 @@ /obj/item/projectile/bullet/pellet name = "pellet" damage = 12.5 - var/tile_dropoff = 0.75 - var/tile_dropoff_s = 1.25 - -/obj/item/projectile/bullet/pellet/Range() - ..() - if(damage > 0) - damage -= tile_dropoff - if(stamina > 0) - stamina -= tile_dropoff_s - if(damage < 0 && stamina < 0) - qdel(src) + tile_dropoff = 0.75 + tile_dropoff_s = 1.25 /obj/item/projectile/bullet/pellet/rubber name = "rubber pellet" diff --git a/code/modules/scripting/AST/AST Nodes.dm b/code/modules/scripting/AST/AST Nodes.dm deleted file mode 100644 index c8bb3ba9f78..00000000000 --- a/code/modules/scripting/AST/AST Nodes.dm +++ /dev/null @@ -1,129 +0,0 @@ -/* - File: AST Nodes - An abstract syntax tree (AST) is a representation of source code in a computer-friendly format. It is composed of nodes, - each of which represents a certain part of the source code. For example, an node represents an if statement in the - script's source code. Because it is a representation of the source code in memory, it is independent of any specific scripting language. - This allows a script in any language for which a parser exists to be run by the interpreter. - - The AST is produced by an object. It consists of a with an arbitrary amount of statements. These statements are - run in order by an object. A statement may in turn run another block (such as an if statement might if its condition is - met). - - Articles: - - -*/ -/* - Constants: Operator Precedence - OOP_OR - Logical or - OOP_AND - Logical and - OOP_BIT - Bitwise operations - OOP_EQUAL - Equality checks - OOP_COMPARE - Greater than, less then, etc - OOP_ADD - Addition and subtraction - OOP_MULTIPLY - Multiplication and division - OOP_POW - Exponents - OOP_UNARY - Unary Operators - OOP_GROUP - Parentheses -*/ -/var/const/OOP_OR = 1 //|| -/var/const/OOP_AND = OOP_OR + 1 //&& -/var/const/OOP_BIT = OOP_AND + 1 //&, | -/var/const/OOP_EQUAL = OOP_BIT + 1 //==, != -/var/const/OOP_COMPARE = OOP_EQUAL + 1 //>, <, >=, <= -/var/const/OOP_ADD = OOP_COMPARE + 1 //+, - -/var/const/OOP_MULTIPLY= OOP_ADD + 1 //*, /, % -/var/const/OOP_POW = OOP_MULTIPLY + 1 //^ -/var/const/OOP_UNARY = OOP_POW + 1 //! -/var/const/OOP_GROUP = OOP_UNARY + 1 //() - -/* - Class: node -*/ -/datum/node/proc/ToString() - return "[src.type]" -/* - Class: identifier -*/ -/datum/node/identifier - var/id_name - -/datum/node/identifier/New(id) - . = ..() - src.id_name = id - -/datum/node/identifier/ToString() - return id_name - -/* - Class: expression -*/ -/datum/node/expression -/* - Class: operator - See and for subtypes. -*/ -/datum/node/expression/operator - var/datum/node/expression/exp - var/token = "" // Used when giving type mismatches. - var/tmp/name - var/tmp/precedence - -/datum/node/expression/operator/New() - .=..() - if(!src.name) - src.name = "[src.type]" - -/datum/node/expression/operator/ToString() - return "operator: [name]" - -/* - Class: FunctionCall -*/ -/datum/node/expression/FunctionCall - //Function calls can also be expressions or statements. - var/func_name - var/datum/node/identifier/object - var/list/parameters = list() - -/* - Class: literal -*/ -/datum/node/expression/value/literal - var/value - -/datum/node/expression/value/literal/New(value) - . = ..() - src.value = value - -/datum/node/expression/value/literal/ToString() - return src.value - -/* - Class: variable -*/ -/datum/node/expression/value/variable - var/datum/node/object //Either a node/identifier or another node/expression/value/variable which points to the object - var/datum/node/identifier/id - - -/datum/node/expression/value/variable/New(ident) - . = ..() - id = ident - if(istext(id)) - id = new(id) - -/datum/node/expression/value/variable/ToString() - return src.id.ToString() - -/* - Class: reference -*/ -/datum/node/expression/value/reference - var/datum/value - -/datum/node/expression/value/reference/New(value) - . = ..() - src.value = value - -/datum/node/expression/value/reference/ToString() - return "ref: [src.value] ([src.value.type])" \ No newline at end of file diff --git a/code/modules/scripting/AST/Blocks.dm b/code/modules/scripting/AST/Blocks.dm deleted file mode 100644 index 331e49c16fe..00000000000 --- a/code/modules/scripting/AST/Blocks.dm +++ /dev/null @@ -1,45 +0,0 @@ -/* - File: Block Types -*/ -/* - Class: BlockDefinition - An object representing a set of actions to perform independently from the rest of the script. Blocks are basically just - lists of statements to execute which also contain some local variables and methods. Note that since functions are local to a block, - it is possible to have a function definition inside of any type of block (such as in an if statement or another function), - and not just in the global scope as in many languages. -*/ -/datum/node/BlockDefinition - var/list/statements = new - var/list/functions = new - var/list/initial_variables = new - -/* - Proc: SetVar - Defines a permanent variable. The variable will not be deleted when it goes out of scope. - - Notes: - Since all pre-existing temporary variables are deleted, it is not generally desirable to use this proc after the interpreter has been instantiated. - Instead, use . - - See Also: - - -*/ -/datum/node/BlockDefinition/proc/SetVar(name, value) - initial_variables[name] = value - - -/* - Class: GlobalBlock - A block object representing the global scope. -*/ -// -/datum/node/BlockDefinition/GlobalBlock/New() - initial_variables["null"] = null - return ..() - -/* - Class: FunctionBlock - A block representing a function body. -*/ -// -/datum/node/BlockDefinition/FunctionBlock \ 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 deleted file mode 100644 index 8781b6dd416..00000000000 --- a/code/modules/scripting/AST/Operators/Binary Operators.dm +++ /dev/null @@ -1,189 +0,0 @@ -/* - File: Binary Operators -*/ -/* - Class: binary - Represents a binary operator in the AST. A binary operator takes two operands (ie x and y) and returns a value. -*/ -/datum/node/expression/operator/binary - var/datum/node/expression/exp2 - -////////// Comparison Operators ////////// -/* - Class: Equal - Returns true if x = y. -*/ -// -/datum/node/expression/operator/binary/Equal - token = "==" - precedence = OOP_EQUAL - -/* -Class: NotEqual -Returns true if x and y aren't equal. -*/ -// -/datum/node/expression/operator/binary/NotEqual - token = "!=" - precedence = OOP_EQUAL - -/* -Class: Greater -Returns true if x > y. -*/ -// -/datum/node/expression/operator/binary/Greater - token = ">" - precedence = OOP_COMPARE - -/* -Class: Less -Returns true if x < y. -*/ -// -/datum/node/expression/operator/binary/Less - token = "<" - precedence = OOP_COMPARE - -/* -Class: GreaterOrEqual -Returns true if x >= y. -*/ -// -/datum/node/expression/operator/binary/GreaterOrEqual - token = ">=" - precedence = OOP_COMPARE - -/* -Class: LessOrEqual -Returns true if x <= y. -*/ -// -/datum/node/expression/operator/binary/LessOrEqual - token = "<=" - precedence = OOP_COMPARE - - -////////// Logical Operators ////////// - -/* -Class: LogicalAnd -Returns true if x and y are true. -*/ -// -/datum/node/expression/operator/binary/LogicalAnd - token = "&&" - precedence = OOP_AND - -/* -Class: LogicalOr -Returns true if x, y, or both are true. -*/ -// -/datum/node/expression/operator/binary/LogicalOr - token = "||" - precedence = OOP_OR - -/* -Class: LogicalXor -Returns true if either x or y but not both are true. -*/ -// -/datum/node/expression/operator/binary/LogicalXor //Not implemented in nS - precedence = OOP_OR - - -////////// Bitwise Operators ////////// - -/* -Class: BitwiseAnd -Performs a bitwise and operation. - -Example: -011 & 110 = 010 -*/ -// -/datum/node/expression/operator/binary/BitwiseAnd - token = "&" - precedence = OOP_BIT - -/* -Class: BitwiseOr -Performs a bitwise or operation. - -Example: -011 | 110 = 111 -*/ -// -/datum/node/expression/operator/binary/BitwiseOr - token = "|" - precedence = OOP_BIT - -/* -Class: BitwiseXor -Performs a bitwise exclusive or operation. - -Example: -011 xor 110 = 101 -*/ -// -/datum/node/expression/operator/binary/BitwiseXor - token = "`" - precedence = OOP_BIT - - -////////// Arithmetic Operators ////////// - -/* -Class: Add -Returns the sum of x and y. -*/ -// -/datum/node/expression/operator/binary/Add - token = "+" - precedence = OOP_ADD - -/* -Class: Subtract -Returns the difference of x and y. -*/ -// -/datum/node/expression/operator/binary/Subtract - token = "-" - precedence = OOP_ADD - -/* -Class: Multiply -Returns the product of x and y. -*/ -// -/datum/node/expression/operator/binary/Multiply - token = "*" - precedence = OOP_MULTIPLY - -/* -Class: Divide -Returns the quotient of x and y. -*/ -// -/datum/node/expression/operator/binary/Divide - token = "/" - precedence = OOP_MULTIPLY - -/* -Class: Power -Returns x raised to the power of y. -*/ -// -/datum/node/expression/operator/binary/Power - token = "^" - precedence = OOP_POW - -/* -Class: Modulo -Returns the remainder of x / y. -*/ -// -/datum/node/expression/operator/binary/Modulo - token = "%" - precedence = OOP_MULTIPLY diff --git a/code/modules/scripting/AST/Operators/Unary Operators.dm b/code/modules/scripting/AST/Operators/Unary Operators.dm deleted file mode 100644 index e7cd4b8489a..00000000000 --- a/code/modules/scripting/AST/Operators/Unary Operators.dm +++ /dev/null @@ -1,51 +0,0 @@ -/* - File: Unary Operators -*/ -/* - Class: unary - Represents a unary operator in the AST. Unary operators take a single operand (referred to as x below) and return a value. -*/ -/datum/node/expression/operator/unary - precedence = OOP_UNARY - -/* - Class: LogicalNot - Returns !x. - - Example: - !true = false and !false = true -*/ -// -/datum/node/expression/operator/unary/LogicalNot - name = "logical not" - -/* - Class: BitwiseNot - Returns the value of a bitwise not operation performed on x. - - Example: - ~10 (decimal 2) = 01 (decimal 1). -*/ -// -/datum/node/expression/operator/unary/BitwiseNot - name = "bitwise not" - -/* - Class: Minus - Returns -x. -*/ -// -/datum/node/expression/operator/unary/Minus - name = "minus" - -/* - Class: group - A special unary operator representing a value in parentheses. -*/ -// -/datum/node/expression/operator/unary/group - precedence = OOP_GROUP - -/datum/node/expression/operator/unary/New(var/datum/node/expression/exp) - src.exp = exp - return ..() diff --git a/code/modules/scripting/AST/Statements.dm b/code/modules/scripting/AST/Statements.dm deleted file mode 100644 index bae9f3de68c..00000000000 --- a/code/modules/scripting/AST/Statements.dm +++ /dev/null @@ -1,110 +0,0 @@ -/* - File: Statement Types -*/ -/* - Class: statement - An object representing a single instruction run by an interpreter. -*/ -/datum/node/statement -/* - Class: FunctionCall - Represents a call to a function. -*/ -// -/datum/node/statement/FunctionCall - var/func_name - var/datum/node/identifier/object - var/list/parameters = new - -/* -Class: FunctionDefinition -Defines a function. -*/ -// -/datum/node/statement/FunctionDefinition - var/func_name - var/list/parameters = new - var/datum/node/BlockDefinition/FunctionBlock/block - -/* -Class: VariableAssignment -Sets a variable in an accessible scope to the given value if one exists, otherwise initializes a new local variable to the given value. - -Notes: -If a variable with the same name exists in a higher block, the value will be assigned to it. If not, -a new variable is created in the current block. To force creation of a new variable, use . - -See Also: -- -*/ -// -/datum/node/statement/VariableAssignment - var/datum/node/identifier/object - var/datum/node/identifier/var_name - var/datum/node/expression/value - -/* -Class: VariableDeclaration -Intializes a local variable to a null value. - -See Also: -- -*/ -// -/datum/node/statement/VariableDeclaration - var/datum/node/identifier/object - var/datum/node/identifier/var_name - -/* -Class: IfStatement -*/ -// -/datum/node/statement/IfStatement - var/skip = 0 - var/datum/node/BlockDefinition/block - var/datum/node/BlockDefinition/else_block //may be null - var/datum/node/expression/cond - var/datum/node/statement/else_if - -/datum/node/statement/IfStatement/ElseIf - -/* -Class: WhileLoop -Loops while a given condition is true. -*/ -// -/datum/node/statement/WhileLoop - var/datum/node/BlockDefinition/block - var/datum/node/expression/cond - -/* -Class: ForLoop -Loops while test is true, initializing a variable, increasing the variable -*/ -/datum/node/statement/ForLoop - var/datum/node/BlockDefinition/block - var/datum/node/expression/test - var/datum/node/expression/init - var/datum/node/expression/increment - -/* -Class: BreakStatement -Ends a loop. -*/ -// -/datum/node/statement/BreakStatement - -/* -Class: ContinueStatement -Skips to the next iteration of a loop. -*/ -// -/datum/node/statement/ContinueStatement - -/* -Class: ReturnStatement -Ends the function and returns a value. -*/ -// -/datum/node/statement/ReturnStatement - var/datum/node/expression/value \ No newline at end of file diff --git a/code/modules/scripting/Errors.dm b/code/modules/scripting/Errors.dm deleted file mode 100644 index 63538c3f18f..00000000000 --- a/code/modules/scripting/Errors.dm +++ /dev/null @@ -1,169 +0,0 @@ -/* - File: Errors -*/ -/* - Class: scriptError - An error scanning or parsing the source code. -*/ -/datum/scriptError -/* - Var: message - A message describing the problem. -*/ - var/message - -/datum/scriptError/New(msg = null) - if(msg)message = msg - -/datum/scriptError/BadToken - message = "Unexpected token: " - var/datum/token/token - -/datum/scriptError/BadToken/New(datum/token/t) - token = t - if(t && t.line) - message = "[t.line]: [message]" - - if(istype(t)) - message += "[t.value]" - - else - message += "[t]" - -/datum/scriptError/InvalidID - parent_type = /datum/scriptError/BadToken - message = "Invalid identifier name: " - -/datum/scriptError/ReservedWord - parent_type = /datum/scriptError/BadToken - message = "Identifer using reserved word: " - -/datum/scriptError/BadNumber - parent_type = /datum/scriptError/BadToken - message = "Bad number: " - -/datum/scriptError/BadReturn - var/datum/token/token - message = "Unexpected return statement outside of a function." - -/datum/scriptError/BadReturn/New(datum/token/t) - src.token = t - -/datum/scriptError/EndOfFile - message = "Unexpected end of file." - -/datum/scriptError/ExpectedToken - message = "Expected: '" - -/datum/scriptError/ExpectedToken/New(id, datum/token/T) - if(T && T.line) - message = "[T.line]: [message]" - - message += "[id]'. " - - if(T) - message += "Found '[T.value]'." - - -/datum/scriptError/UnterminatedComment - message = "Unterminated multi-line comment statement: expected */" - -/datum/scriptError/DuplicateFunction/New(name, datum/token/t) - message = "Function '[name]' defined twice." - -/datum/scriptError/ParameterFunction - message = "You cannot use a function inside a parameter." - -/datum/scriptError/ParameterFunction/New(datum/token/t) - var/line = "?" - if(t) - line = t.line - message = "[line]: [message]" - -/* - Class: runtimeError - An error thrown by the interpreter in running the script. -*/ -/datum/runtimeError - var/name -/* - Var: message - A basic description as to what went wrong. -*/ - var/message - var/datum/stack/stack -/* - Proc: ToString - Returns a description of the error suitable for showing to the user. -*/ -/datum/runtimeError/proc/ToString() - . = "[name]: [message]" - if(!stack.Top()) - return - - . += "\nStack:" - while(stack.Top()) - var/datum/node/statement/FunctionCall/stmt = stack.Pop() - . += "\n\t [stmt.func_name]()" - -/datum/runtimeError/TypeMismatch - name = "TypeMismatchError" - -/datum/runtimeError/TypeMismatch/New(op, a, b) - message = "Type mismatch: '[a]' [op] '[b]'" - -/datum/runtimeError/TypeMismatch/unary/New(op, a) - message = "Type mismatch: [op]'[a]'" - -/datum/runtimeError/TypeMismatch/New(op, a, b) - message = "Type mismatch: '[a]' [op] '[b]'" - -/datum/runtimeError/UnexpectedReturn - name = "UnexpectedReturnError" - message = "Unexpected return statement." - -/datum/runtimeError/UnknownInstruction - name = "UnknownInstructionError" - message = "Unknown instruction type. This may be due to incompatible compiler and interpreter versions or a lack of implementation." - -/datum/runtimeError/UndefinedVariable - name = "UndefinedVariableError" - -/datum/runtimeError/UndefinedVariable/New(variable) - message = "Variable '[variable]' has not been declared." - -/datum/runtimeError/UndefinedFunction - name = "UndefinedFunctionError" - -/datum/runtimeError/UndefinedFunction/New(function) - message = "Function '[function]()' has not been defined." - -/datum/runtimeError/DuplicateVariableDeclaration - name = "DuplicateVariableError" - -/datum/runtimeError/DuplicateVariableDeclaration/New(variable) - message="Variable '[variable]' was already declared." - -/datum/runtimeError/IterationLimitReached - name = "MaxIterationError" - message = "A loop has reached its maximum number of iterations." - -/datum/runtimeError/RecursionLimitReached - name = "MaxRecursionError" - message = "The maximum amount of recursion has been reached." - -/datum/runtimeError/DivisionByZero - name = "DivideByZeroError" - message = "Division by zero attempted." - -/datum/runtimeError/MaxCPU - name = "MaxComputationalUse" - message = "Maximum amount of computational cycles reached (>= 1000)." - -/datum/runtimeError/VectorLimit - name = "VectorSizeOverflow" - message = "Maximum vector size reached" - -/datum/runtimeError/StringLimit - name = "StringSizeOverflow" - message = "Maximum string size reached" diff --git a/code/modules/scripting/Implementations/Telecomms.dm b/code/modules/scripting/Implementations/Telecomms.dm deleted file mode 100644 index e8fa2ed19b6..00000000000 --- a/code/modules/scripting/Implementations/Telecomms.dm +++ /dev/null @@ -1,352 +0,0 @@ -/* --- Traffic Control Scripting Language --- */ - // Nanotrasen TCS Language - Made by Doohl - -/datum/n_Interpreter/TCS_Interpreter - var/datum/TCS_Compiler/Compiler - -/datum/n_Interpreter/TCS_Interpreter/HandleError(datum/runtimeError/e) - Compiler.Holder.add_entry(e.ToString(), "Execution Error") - -/datum/n_Interpreter/TCS_Interpreter/GC() - ..() - Compiler = null - -/datum/TCS_Compiler - var/datum/n_Interpreter/TCS_Interpreter/interpreter - var/obj/machinery/telecomms/server/Holder // the server that is running the code - var/ready = 1 // 1 if ready to run code - - /* -- Set ourselves to Garbage Collect -- */ - -/datum/TCS_Compiler/proc/GC() - Holder = null - if(interpreter) - interpreter.GC() - - -//temp -/datum/TCS_Compiler - var/datum/n_scriptOptions/nS_Options/options - var/datum/n_Scanner/nS_Scanner/scanner - var/list/tokens - var/datum/n_Parser/nS_Parser/parser - var/datum/node/BlockDefinition/GlobalBlock/program - - /* -- Compile a raw block of text -- */ - -/datum/TCS_Compiler/proc/Compile(list/code) - options = new() - scanner = new(code, options) - tokens = scanner.Scan() - parser = new(tokens, options) - program = parser.Parse() - - var/list/returnerrors = list() - - returnerrors += scanner.errors - returnerrors += parser.errors - - if(returnerrors.len) - return returnerrors - - interpreter = new(program) - interpreter.persist = 1 - interpreter.Compiler= src - - return returnerrors - -/* -- Execute the compiled code -- */ - -/datum/TCS_Compiler/proc/Run(var/datum/signal/signal) - if(!ready) - return - - if(!interpreter) - return - - interpreter.container = src - - interpreter.CreateGlobalScope() // Reset the variables. - interpreter.curScope = interpreter.globalScope - - interpreter.SetVar("PI", 3.141592653) // value of pi - interpreter.SetVar("E", 2.718281828) // value of e - interpreter.SetVar("SQURT2", 1.414213562) // value of the square root of 2 - interpreter.SetVar("FALSE", 0) // boolean shortcut to 0 - interpreter.SetVar("false", 0) // boolean shortcut to 0 - interpreter.SetVar("TRUE", 1) // boolean shortcut to 1 - interpreter.SetVar("true", 1) // boolean shortcut to 1 - - interpreter.SetVar("NORTH", NORTH) // NORTH (1) - interpreter.SetVar("SOUTH", SOUTH) // SOUTH (2) - interpreter.SetVar("EAST", EAST) // EAST (4) - interpreter.SetVar("WEST", WEST) // WEST (8) - - // Channel macros - interpreter.SetVar("$common", PUB_FREQ) - interpreter.SetVar("$science", SCI_FREQ) - interpreter.SetVar("$command", COMM_FREQ) - interpreter.SetVar("$medical", MED_FREQ) - interpreter.SetVar("$engineering", ENG_FREQ) - interpreter.SetVar("$security", SEC_FREQ) - interpreter.SetVar("$supply", SUP_FREQ) - interpreter.SetVar("$service", SRV_FREQ) - - // Signal data - - interpreter.SetVar("$content", signal.data["message"]) - interpreter.SetVar("$freq", signal.frequency) - interpreter.SetVar("$source", signal.data["name"]) - interpreter.SetVar("$job", signal.data["job"]) - interpreter.SetVar("$sign", signal) - interpreter.SetVar("$pass", !(signal.data["reject"])) // if the signal isn't rejected, pass = 1; if the signal IS rejected, pass = 0 - - var/datum/language/speaking = signal.data["language"] - if(speaking) - interpreter.SetVar("$language", speaking.name) - else - interpreter.SetVar("$language", "Unknown") - - // Set up the script procs - - /* - -> Send another signal to a server - @format: broadcast(content, frequency, source, job) - - @param content: Message to broadcast - @param frequency: Frequency to broadcast to - @param source: The name of the source you wish to imitate. Must be stored in stored_names list. - @param job: The name of the job. - */ - interpreter.SetProc("broadcast", "tcombroadcast", signal, list("message", "freq", "source", "job")) - - /* - -> Store a value permanently to the server machine (not the actual game hosting machine, the ingame machine) - @format: mem(address, value) - - @param address: The memory address (string index) to store a value to - @param value: The value to store to the memory address - */ - interpreter.SetProc("mem", "mem", signal, list("address", "value")) - - /* - -> Delay code for a given amount of deciseconds - @format: sleep(time) - - @param time: time to sleep in deciseconds (1/10th second) - */ - interpreter.SetProc("sleep", "delay", signal, list("time")) - - /* - -> Replaces a string with another string - @format: replace(string, substring, replacestring) - - @param string: the string to search for substrings (best used with $content$ constant) - @param substring: the substring to search for - @param replacestring: the string to replace the substring with - - */ - interpreter.SetProc("replace", /proc/n_replacetext) - - /* - -> Locates an element/substring inside of a list or string - @format: find(haystack, needle, start = 1, end = 0) - - @param haystack: the container to search - @param needle: the element to search for - @param start: the position to start in - @param end: the position to end in - - */ - interpreter.SetProc("find", /proc/smartfind) - - /* - -> Finds the length of a string or list - @format: length(container) - - @param container: the list or container to measure - - */ - interpreter.SetProc("length", /proc/smartlength) - - /* -- Clone functions, carried from default BYOND procs --- */ - - // vector namespace - interpreter.SetProc("vector", /proc/n_list) - interpreter.SetProc("at", /proc/n_listpos) - interpreter.SetProc("copy", /proc/n_listcopy) - interpreter.SetProc("push_back", /proc/n_listadd) - interpreter.SetProc("remove", /proc/n_listremove) - interpreter.SetProc("cut", /proc/n_listcut) - interpreter.SetProc("swap", /proc/n_listswap) - interpreter.SetProc("insert", /proc/n_listinsert) - - interpreter.SetProc("pick", /proc/n_pick) - interpreter.SetProc("prob", /proc/prob_chance) - interpreter.SetProc("substr", /proc/docopytext) - - interpreter.SetProc("shuffle", /proc/shuffle) - interpreter.SetProc("uniquevector", /proc/uniquelist) - - interpreter.SetProc("text2vector", /proc/n_splittext) - interpreter.SetProc("vector2text", /proc/n_jointext) - - // Donkie~ - // Strings - interpreter.SetProc("lower", /proc/n_lower) - interpreter.SetProc("upper", /proc/n_upper) - interpreter.SetProc("explode", /proc/string_explode) - interpreter.SetProc("implode", /proc/n_jointext) - interpreter.SetProc("repeat", /proc/n_repeat) - interpreter.SetProc("reverse", /proc/reverse_text) - interpreter.SetProc("tonum", /proc/n_str2num) - interpreter.SetProc("capitalize", /proc/capitalize) - interpreter.SetProc("replacetextEx",/proc/n_replacetextEx) - - // Numbers - interpreter.SetProc("tostring", /proc/n_num2str) - interpreter.SetProc("sqrt", /proc/n_sqrt) - interpreter.SetProc("abs", /proc/n_abs) - interpreter.SetProc("floor", /proc/n_floor) - interpreter.SetProc("ceil", /proc/n_ceiling) - interpreter.SetProc("round", /proc/n_round) - interpreter.SetProc("clamp", /proc/n_clamp) - interpreter.SetProc("inrange", /proc/n_isInRange) - interpreter.SetProc("rand", /proc/rand_chance) - interpreter.SetProc("arctan", /proc/Atan2) - interpreter.SetProc("lcm", /proc/n_lcm) - interpreter.SetProc("gcd", /proc/Gcd) - interpreter.SetProc("mean", /proc/Mean) - interpreter.SetProc("root", /proc/n_root) - interpreter.SetProc("sin", /proc/n_sin) - interpreter.SetProc("cos", /proc/n_cos) - interpreter.SetProc("arcsin", /proc/n_asin) - interpreter.SetProc("arccos", /proc/n_acos) - interpreter.SetProc("tan", /proc/n_tan) - interpreter.SetProc("csc", /proc/n_csc) - interpreter.SetProc("cot", /proc/n_cot) - interpreter.SetProc("sec", /proc/n_sec) - interpreter.SetProc("todegrees", /proc/n_toDegrees) - interpreter.SetProc("toradians", /proc/n_toRadians) - interpreter.SetProc("lerp", /proc/Lerp) - interpreter.SetProc("max", /proc/n_max) - interpreter.SetProc("min", /proc/n_min) - - // End of Donkie~ - - // Time - interpreter.SetProc("time", /proc/time) - interpreter.SetProc("timestamp", /proc/gameTimestamp) - - // Run the compiled code - interpreter.Run() - - // Backwards-apply variables onto signal data - /* sanitize EVERYTHING. fucking players can't be trusted with SHIT */ - - /* Okay, so, the original 'sanitizing' code... did fucking nothing. Then PJB fixed it, which means no HTML. - But I like HTML, so back to no sanitizing.*/ - - var/message = interpreter.GetVar("$content") - var/regex/bannedTags = new ("( BYOND code procs -#define SCRIPT_MAX_REPLACEMENTS_ALLOWED 200 -// --- List operations (lists known as vectors in n_script) --- - -// Clone of list() -/proc/n_list() - //writepanic("[__FILE__].[__LINE__] (no type)([usr ? usr.ckey : ""]) \\/proc/n_list() called tick#: [world.time]") - var/list/returnlist = list() - for(var/e in args) - returnlist.Add(e) - return returnlist - -// Clone of pick() -/proc/n_pick() - //writepanic("[__FILE__].[__LINE__] (no type)([usr ? usr.ckey : ""]) \\/proc/n_pick() called tick#: [world.time]") - var/list/finalpick = list() - for(var/e in args) - if(isobject(e)) - if(istype(e, /list)) - var/list/sublist = e - for(var/sube in sublist) - finalpick.Add(sube) - continue - finalpick.Add(e) - - return pick(finalpick) - -// Clone of list[] -/proc/n_listpos(var/list/L, var/pos, var/value) - //writepanic("[__FILE__].[__LINE__] (no type)([usr ? usr.ckey : ""]) \\/proc/n_listpos() called tick#: [world.time]") - if(!istype(L, /list)) return - if(isnum(pos)) - if(!value) - if(L.len >= pos && !(pos > L.len)) - return L[pos] - else - if(L.len >= pos && !(pos > L.len)) - L[pos] = value - else if(istext(pos)) - if(!value) - return L[pos] - else - L[pos] = value - -// Clone of list.Copy() -/proc/n_listcopy(var/list/L, var/start, var/end) - //writepanic("[__FILE__].[__LINE__] (no type)([usr ? usr.ckey : ""]) \\/proc/n_listcopy() called tick#: [world.time]") - if(!istype(L, /list)) return - return L.Copy(start, end) - -// Clone of list.Add() -/proc/n_listadd() - //writepanic("[__FILE__].[__LINE__] (no type)([usr ? usr.ckey : ""]) \\/proc/n_listadd() called tick#: [world.time]") - var/list/chosenlist - var/i = 1 - for(var/e in args) - if(i == 1) - if(isobject(e)) - if(istype(e, /list)) - chosenlist = e - i = 2 - else - if(chosenlist) - chosenlist.Add(e) - -// Clone of list.Remove() -/proc/n_listremove() - //writepanic("[__FILE__].[__LINE__] (no type)([usr ? usr.ckey : ""]) \\/proc/n_listremove() called tick#: [world.time]") - var/list/chosenlist - var/i = 1 - for(var/e in args) - if(i == 1) - if(isobject(e)) - if(istype(e, /list)) - chosenlist = e - i = 2 - else - if(chosenlist) - chosenlist.Remove(e) - -// Clone of list.len = 0 -/proc/n_listcut(var/list/L, var/start, var/end) - //writepanic("[__FILE__].[__LINE__] (no type)([usr ? usr.ckey : ""]) \\/proc/n_listcut() called tick#: [world.time]") - if(!istype(L, /list)) return - return L.Cut(start, end) - -// Clone of list.Swap() -/proc/n_listswap(var/list/L, var/firstindex, var/secondindex) - //writepanic("[__FILE__].[__LINE__] (no type)([usr ? usr.ckey : ""]) \\/proc/n_listswap() called tick#: [world.time]") - if(!istype(L, /list)) return - if(L.len >= secondindex && L.len >= firstindex) - return L.Swap(firstindex, secondindex) - -// Clone of list.Insert() -/proc/n_listinsert(var/list/L, var/index, var/element) - //writepanic("[__FILE__].[__LINE__] (no type)([usr ? usr.ckey : ""]) \\/proc/n_listinsert() called tick#: [world.time]") - if(!istype(L, /list)) return - return L.Insert(index, element) - -// --- Miscellaneous functions --- - -// Clone of rand() -/proc/rand_chance(var/low = 0, var/high) - //writepanic("[__FILE__].[__LINE__] (no type)([usr ? usr.ckey : ""]) \\/proc/rand_chance() called tick#: [world.time]") - return rand(low, high) - -// Clone of prob() -/proc/prob_chance(var/chance) - //writepanic("[__FILE__].[__LINE__] (no type)([usr ? usr.ckey : ""]) \\/proc/prob_chance() called tick#: [world.time]") - return prob(chance) - -// Merge of list.Find() and findtext() -/proc/smartfind(var/haystack, var/needle, var/start = 1, var/end = 0) - //writepanic("[__FILE__].[__LINE__] (no type)([usr ? usr.ckey : ""]) \\/proc/smartfind() called tick#: [world.time]") - if(haystack && needle) - if(isobject(haystack)) - if(istype(haystack, /list)) - if(length(haystack) >= end && start > 0) - var/list/listhaystack = haystack - return listhaystack.Find(needle, start, end) - - else - if(istext(haystack)) - if(length(haystack) >= end && start > 0) - return findtext(haystack, needle, start, end) - -// Clone of copytext() -/proc/docopytext(var/string, var/start = 1, var/end = 0) - //writepanic("[__FILE__].[__LINE__] (no type)([usr ? usr.ckey : ""]) \\/proc/docopytext() called tick#: [world.time]") - if(istext(string) && isnum(start) && isnum(end)) - if(start > 0) - return copytext(string, start, end) - -// Clone of length() -/proc/smartlength(var/container) - //writepanic("[__FILE__].[__LINE__] (no type)([usr ? usr.ckey : ""]) \\/proc/smartlength() called tick#: [world.time]") - if(container) - if(istype(container, /list) || istext(container)) - return length(container) - return 0 - -// BY DONKIE~ -// String stuff -/proc/n_lower(var/string) - //writepanic("[__FILE__].[__LINE__] (no type)([usr ? usr.ckey : ""]) \\/proc/n_lower() called tick#: [world.time]") - if(istext(string)) - return lowertext(string) - -/proc/n_upper(var/string) - //writepanic("[__FILE__].[__LINE__] (no type)([usr ? usr.ckey : ""]) \\/proc/n_upper() called tick#: [world.time]") - if(istext(string)) - return uppertext(string) - -/proc/time() - //writepanic("[__FILE__].[__LINE__] (no type)([usr ? usr.ckey : ""]) \\/proc/time() called tick#: [world.time]") - return world.time + (12 HOURS) - -proc/string_explode(var/string, var/separator = "") - //writepanic("[__FILE__].[__LINE__] \\/proc/string_explode() called tick#: [world.time]") - if(istext(string) && (istext(separator) || isnull(separator))) - return splittext(string, separator) - -//Converts a list to a string -/proc/list_implode(var/list/li, var/separator) - if(istype(li) && (istext(separator) || isnull(separator))) - return jointext(li, separator) - -proc/n_repeat(var/string, var/amount) - //writepanic("[__FILE__].[__LINE__] \\/proc/n_repeat() called tick#: [world.time]") - if(istext(string) && isnum(amount)) - var/i - var/newstring = "" - if(length(newstring)*amount >=1000) - return - for(i=0, i<=amount, i++) - if(i>=1000) - break - newstring = newstring + string - - return newstring - -// I don't know if it's neccesary to make my own proc, but I think I have to to be able to check for istext. -proc/n_str2num(var/string) - //writepanic("[__FILE__].[__LINE__] \\/proc/n_str2num() called tick#: [world.time]") - if(istext(string)) - return text2num(string) - -// Clamps N between min and max -/proc/n_clamp(var/num, var/min = 0, var/max = 1) - if(isnum(num) && isnum(min) && isnum(max)) - return Clamp(num, min, max) - -// Number shit -proc/n_num2str(var/num) - //writepanic("[__FILE__].[__LINE__] \\/proc/n_num2str() called tick#: [world.time]") - if(isnum(num)) - return num2text(num) - -// Squareroot -proc/n_sqrt(var/num) - //writepanic("[__FILE__].[__LINE__] \\/proc/n_sqrt() called tick#: [world.time]") - if(isnum(num)) - return sqrt(num) - -// Magnitude of num -proc/n_abs(var/num) - //writepanic("[__FILE__].[__LINE__] \\/proc/n_abs() called tick#: [world.time]") - if(isnum(num)) - return abs(num) - -// Round down -proc/n_floor(var/num) - //writepanic("[__FILE__].[__LINE__] \\/proc/n_floor() called tick#: [world.time]") - if(isnum(num)) - return Floor(num) - -// Round up -proc/n_ceiling(var/num) - //writepanic("[__FILE__].[__LINE__] \\/proc/n_ceil() called tick#: [world.time]") - if(isnum(num)) - return Ceiling(num) - -// Round to nearest integer -proc/n_round(var/num) - //writepanic("[__FILE__].[__LINE__] \\/proc/n_round() called tick#: [world.time]") - if(isnum(num)) - if(num-round(num)<0.5) - return round(num) - return Ceiling(num) - -// END OF BY DONKIE :( - -/proc/n_sin(var/const/x) - if(isnum(x)) - return sin(x) - -/proc/n_cos(var/const/x) - if(isnum(x)) - return cos(x) - -/proc/n_tan(var/const/x) - if(isnum(x)) - return Tan(x) - -/proc/n_csc(var/const/x) - if(isnum(x)) - return Csc(x) - -/proc/n_cot(var/const/x) - if(isnum(x)) - return Cot(x) - -/proc/n_sec(var/const/x) - if(isnum(x)) - return Sec(x) - -/proc/n_asin(var/const/x) - if(isnum(x)) - return arcsin(x) - -/proc/n_acos(var/const/x) - if(isnum(x)) - return arccos(x) - -/proc/n_isInRange(var/const/x, var/const/min, var/const/max) - if(isnum(x) && isnum(min) && isnum(max)) - return IsInRange(x, min, max) - -/proc/n_lcm(var/const/a, var/const/b) - if(isnum(a) && isnum(b)) - return Lcm(a, b) - -/proc/n_root(var/const/n, var/const/x) - if(isnum(n) && isnum(x)) - return Root(n, x) - -/proc/n_toDegrees(var/const/x) - if(isnum(x)) - return ToDegrees(x) - -/proc/n_toRadians(var/const/x) - if(isnum(x)) - return ToRadians(x) - -/proc/n_max(...) - return max(arglist(args)) - -/proc/n_min(...) - return min(arglist(args)) - -/proc/n_log(var/num) - if(isnum(num) && 0 < num) - return log(num) - -/proc/n_replacetext(text, r, with) - return replacetext(text, r, with) - -/proc/n_replacetextEx(text, r, with) - return replacetextEx(text, r, with) - -/proc/n_jointext(list, glue) - return jointext(list, glue) - -/proc/n_splittext(text, delim) - return splittext(text, delim) \ No newline at end of file diff --git a/code/modules/scripting/Interpreter/Evaluation.dm b/code/modules/scripting/Interpreter/Evaluation.dm deleted file mode 100644 index 84c255fe9ad..00000000000 --- a/code/modules/scripting/Interpreter/Evaluation.dm +++ /dev/null @@ -1,203 +0,0 @@ -/proc/isobject(x) - return (istype(x, /datum) || istype(x, /list) || istype(x, /savefile) || istype(x, /client) || (x == world)) - -/datum/n_Interpreter/proc/Eval(datum/node/expression/exp) - if(istype(exp, /datum/node/expression/FunctionCall)) - return RunFunction(exp) - - else if(istype(exp, /datum/node/expression/operator)) - return EvalOperator(exp) - - else if(istype(exp, /datum/node/expression/value/literal)) - var/datum/node/expression/value/literal/lit = exp - return lit.value - - else if(istype(exp, /datum/node/expression/value/reference)) - var/datum/node/expression/value/reference/ref = exp - return ref.value - - else if(istype(exp, /datum/node/expression/value/variable)) - var/datum/node/expression/value/variable/v = exp - if(!v.object) - return Eval(GetVariable(v.id.id_name)) - else - var/datum/D - if(istype(v.object, /datum/node/identifier)) - D = GetVariable(v.object:id_name) - else - D = v.object - - D = Eval(D) - if(!isobject(D)) - return null - - if(!D.vars.Find(v.id.id_name)) - RaiseError(new/datum/runtimeError/UndefinedVariable("[v.object.ToString()].[v.id.id_name]")) - return null - - return Eval(D.vars[v.id.id_name]) - - else if(istype(exp, /datum/node/expression)) - RaiseError(new/datum/runtimeError/UnknownInstruction()) - - else - return exp - -/datum/n_Interpreter/proc/EvalOperator(datum/node/expression/operator/exp) - if(istype(exp, /datum/node/expression/operator/binary)) - var/datum/node/expression/operator/binary/bin = exp - try // This way we can forgo sanity in the actual evaluation (other than divide by 0). - switch(bin.type) - if(/datum/node/expression/operator/binary/Equal) - return Equal(Eval(bin.exp), Eval(bin.exp2)) - - if(/datum/node/expression/operator/binary/NotEqual) - return NotEqual(Eval(bin.exp), Eval(bin.exp2)) - - if(/datum/node/expression/operator/binary/Greater) - return Greater(Eval(bin.exp), Eval(bin.exp2)) - - if(/datum/node/expression/operator/binary/Less) - return Less(Eval(bin.exp), Eval(bin.exp2)) - - if(/datum/node/expression/operator/binary/GreaterOrEqual) - return GreaterOrEqual(Eval(bin.exp), Eval(bin.exp2)) - - if(/datum/node/expression/operator/binary/LessOrEqual) - return LessOrEqual(Eval(bin.exp), Eval(bin.exp2)) - - if(/datum/node/expression/operator/binary/LogicalAnd) - return LogicalAnd(Eval(bin.exp), Eval(bin.exp2)) - - if(/datum/node/expression/operator/binary/LogicalOr) - return LogicalOr(Eval(bin.exp), Eval(bin.exp2)) - - if(/datum/node/expression/operator/binary/LogicalXor) - return LogicalXor(Eval(bin.exp), Eval(bin.exp2)) - - if(/datum/node/expression/operator/binary/BitwiseAnd) - return BitwiseAnd(Eval(bin.exp), Eval(bin.exp2)) - - if(/datum/node/expression/operator/binary/BitwiseOr) - return BitwiseOr(Eval(bin.exp), Eval(bin.exp2)) - - if(/datum/node/expression/operator/binary/BitwiseXor) - return BitwiseXor(Eval(bin.exp), Eval(bin.exp2)) - - if(/datum/node/expression/operator/binary/Add) - return Add(Eval(bin.exp), Eval(bin.exp2)) - - if(/datum/node/expression/operator/binary/Subtract) - return Subtract(Eval(bin.exp), Eval(bin.exp2)) - - if(/datum/node/expression/operator/binary/Multiply) - return Multiply(Eval(bin.exp), Eval(bin.exp2)) - - if(/datum/node/expression/operator/binary/Divide) - return Divide(Eval(bin.exp), Eval(bin.exp2)) - - if(/datum/node/expression/operator/binary/Power) - return Power(Eval(bin.exp), Eval(bin.exp2)) - - if(/datum/node/expression/operator/binary/Modulo) - return Modulo(Eval(bin.exp), Eval(bin.exp2)) - - else - RaiseError(new/datum/runtimeError/UnknownInstruction()) - - catch - RaiseError(new/datum/runtimeError/TypeMismatch(bin.token, Eval(bin.exp), Eval(bin.exp2))) - - else - try - switch(exp.type) - if(/datum/node/expression/operator/unary/Minus) - return Minus(Eval(exp.exp)) - - if(/datum/node/expression/operator/unary/LogicalNot) - return LogicalNot(Eval(exp.exp)) - - if(/datum/node/expression/operator/unary/BitwiseNot) - return BitwiseNot(Eval(exp.exp)) - - if(/datum/node/expression/operator/unary/group) - return Eval(exp.exp) - - else - RaiseError(new/datum/runtimeError/UnknownInstruction()) - catch - RaiseError(new/datum/runtimeError/TypeMismatch/unary(exp.token, Eval(exp.exp))) - -//Binary// -//Comparison operators -/datum/n_Interpreter/proc/Equal(a, b) - return a == b - -/datum/n_Interpreter/proc/NotEqual(a, b) - return a != b //LogicalNot(Equal(a, b)) - -/datum/n_Interpreter/proc/Greater(a, b) - return a > b - -/datum/n_Interpreter/proc/Less(a, b) - return a < b - -/datum/n_Interpreter/proc/GreaterOrEqual(a, b) - return a >= b - -/datum/n_Interpreter/proc/LessOrEqual(a, b) - return a <= b - -//Logical Operators -/datum/n_Interpreter/proc/LogicalAnd(a, b) - return a && b - -/datum/n_Interpreter/proc/LogicalOr(a, b) - return a || b - -/datum/n_Interpreter/proc/LogicalXor(a, b) - return (a || b) && !(a && b) - -//Bitwise Operators -/datum/n_Interpreter/proc/BitwiseAnd(a, b) - return a & b - -/datum/n_Interpreter/proc/BitwiseOr(a, b) - return a | b - -/datum/n_Interpreter/proc/BitwiseXor(a, b) - return a ^ b - -//Arithmetic Operators -/datum/n_Interpreter/proc/Add(a, b) - return a + b - -/datum/n_Interpreter/proc/Subtract(a, b) - return a - b - -/datum/n_Interpreter/proc/Divide(a, b) - if(b == 0) - RaiseError(new/datum/runtimeError/DivisionByZero()) - return null - - return a / b - -/datum/n_Interpreter/proc/Multiply(a, b) - return a * b - -/datum/n_Interpreter/proc/Modulo(a, b) - - return a % b - -/datum/n_Interpreter/proc/Power(a, b) - return a ** b - -//Unary// -/datum/n_Interpreter/proc/Minus(a) - return -a - -/datum/n_Interpreter/proc/LogicalNot(a) - return !a - -/datum/n_Interpreter/proc/BitwiseNot(a) - return ~a diff --git a/code/modules/scripting/Interpreter/Interaction.dm b/code/modules/scripting/Interpreter/Interaction.dm deleted file mode 100644 index ffcf8f716d8..00000000000 --- a/code/modules/scripting/Interpreter/Interaction.dm +++ /dev/null @@ -1,157 +0,0 @@ -/* - File: Interpreter (Public) - Contains methods for interacting with the interpreter. -*/ -/* - Class: n_Interpreter - Procedures allowing for interaction with the script that is being run by the interpreter object. -*/ - -/* - Proc: Load - Loads a 'compiled' script into memory. - - Parameters: - program - A object which represents the script's global scope. -*/ -/datum/n_Interpreter/proc/Load(var/datum/node/BlockDefinition/GlobalBlock/program) - ASSERT(program) - src.program = program - CreateGlobalScope() - alertadmins = 0 // reset admin alerts - -/* -Proc: Run -Runs the script. -*/ -/datum/n_Interpreter/proc/Run() - cur_recursion = 0 // reset recursion - cur_statements = 0 // reset CPU tracking - - ASSERT(src.program) - RunBlock(src.program) - -/* -Proc: SetVar -Defines a global variable for the duration of the next execution of a script. - -Notes: -This differs from in that variables set using this procedure only last for the session, -while those defined from the block object persist if it is ran multiple times. - -See Also: -- -*/ -/datum/n_Interpreter/proc/SetVar(name, value) - if(!istext(name)) - //CRASH("Invalid variable name") - return - - AssignVariable(name, value) - -/* -Proc: SetProc -Defines a procedure to be available to the script. - -Parameters: -name - The name of the procedure as exposed to the script. -path - The typepath of a proc to be called when the function call is read by the interpreter, or, if object is specified, a string representing the procedure's name. -object - (Optional) An object which will the be target of a function call. -params - Only required if object is not null, a list of the names of parameters the proc takes. -*/ -/datum/n_Interpreter/proc/SetProc(name, path, object = null, list/params = null) - if(!istext(name)) - //CRASH("Invalid function name") - return - - if(!object) - globalScope.functions[name] = path - - else - var/datum/node/statement/FunctionDefinition/S = new() - S.func_name = name - S.parameters = params - S.block = new() - S.block.SetVar("src", object) - var/datum/node/expression/FunctionCall/C = new() - C.func_name = path - C.object = new("src") - for(var/p in params) - C.parameters += new/datum/node/expression/value/variable(p) - - var/datum/node/statement/ReturnStatement/R = new() - R.value = C - S.block.statements += R - globalScope.functions[name] = S -/* -Proc: VarExists -Checks whether a global variable with the specified name exists. -*/ -/datum/n_Interpreter/proc/VarExists(name) - return globalScope.variables.Find(name) //convert to 1/0 first? - -/* -Proc: ProcExists -Checks whether a global function with the specified name exists. -*/ -/datum/n_Interpreter/proc/ProcExists(name) - return globalScope.functions.Find(name) - -/* -Proc: GetVar -Returns the value of a global variable in the script. Remember to ensure that the variable exists before calling this procedure. - -See Also: -- -*/ -/datum/n_Interpreter/proc/GetVar(name) - if(!VarExists(name)) - //CRASH("No variable named '[name]'.") - return - var/x = globalScope.variables[name] - return Eval(x) - -/* -Proc: GetCleanVar -Returns the value of a global variable in the script and cleans it (sanitizes). -*/ - -/datum/n_Interpreter/proc/GetCleanVar(name, compare) - var/x = GetVar(name) - if(istext(x) && compare && x != compare) // Was changed - x = sanitize(x) - return x - -/* -Proc: CallProc -Calls a global function defined in the script and, amazingly enough, returns its return value. Remember to ensure that the function -exists before calling this procedure. - -See Also: -- -*/ -/datum/n_Interpreter/proc/CallProc(name, params[]=null) - if(!ProcExists(name)) - //CRASH("No function named '[name]'.") - return - - var/datum/node/statement/FunctionDefinition/func = globalScope.functions[name] - - if(istype(func)) - var/datum/node/statement/FunctionCall/stmt = new - stmt.func_name = func.func_name - stmt.parameters = params - return RunFunction(stmt) - - else - return call(func)(arglist(params)) - //CRASH("Unknown function type '[name]'.") - -/* -Event: HandleError -Called when the interpreter throws a runtime error. - -See Also: -- -*/ -/datum/n_Interpreter/proc/HandleError(var/datum/runtimeError/e) diff --git a/code/modules/scripting/Interpreter/Interpreter.dm b/code/modules/scripting/Interpreter/Interpreter.dm deleted file mode 100644 index c24e9ba5e3a..00000000000 --- a/code/modules/scripting/Interpreter/Interpreter.dm +++ /dev/null @@ -1,380 +0,0 @@ -/* - File: Interpreter (Internal) -*/ -/* - Class: n_Interpreter -*/ -/* - Macros: Status Macros - RETURNING - Indicates that the current function is returning a value. - BREAKING - Indicates that the current loop is being terminated. - CONTINUING - Indicates that the rest of the current iteration of a loop is being skipped. -*/ -#define RETURNING 1 -#define BREAKING 2 -#define CONTINUING 4 - -/datum/n_Interpreter - var/datum/scope/curScope - var/datum/scope/globalScope - - var/datum/node/BlockDefinition/program - var/datum/node/statement/FunctionDefinition/curFunction - var/datum/stack/scopes = new() - var/datum/stack/functions = new() - - var/datum/container // associated container for interpeter -/* - Var: status - A variable indicating that the rest of the current block should be skipped. This may be set to any combination of . -*/ - var/status = 0 - var/returnVal - - var/max_statements = 900 // maximum amount of statements that can be called in one execution. this is to prevent massive crashes and exploitation - var/cur_statements = 0 // current amount of statements called - var/alertadmins = 0 // set to 1 if the admins shouldn't be notified of anymore issues - var/max_iterations = 100 // max number of uninterrupted loops possible - var/max_recursion = 10 // max recursions without returning anything (or completing the code block) - var/cur_recursion = 0 // current amount of recursion -/* - Var: persist - If 0, global variables will be reset after Run() finishes. -*/ - var/persist = 1 - var/paused = 0 - -/* - Constructor: New - Calls with the given parameters. -*/ -/datum/n_Interpreter/New(datum/node/BlockDefinition/GlobalBlock/program = null) - . = ..() - if(program) - Load(program) - -/* - Set ourselves to Garbage Collect -*/ -/datum/n_Interpreter/proc/GC() - ..() - container = null - -/* - Proc: RaiseError - Raises a runtime error. -*/ -/datum/n_Interpreter/proc/RaiseError(datum/runtimeError/e) - e.stack = functions.Copy() - e.stack.Push(curFunction) - src.HandleError(e) - -/datum/n_Interpreter/proc/CreateScope(datum/node/BlockDefinition/B) - var/datum/scope/S = new(B, curScope) - scopes.Push(curScope) - curScope = S - return S - -/datum/n_Interpreter/proc/CreateGlobalScope() - scopes.Clear() - var/datum/scope/S = new(program, null) - globalScope = S - return S - -/* -Proc: AlertAdmins -Alerts the admins of a script that is bad. -*/ -/datum/n_Interpreter/proc/AlertAdmins() - if(container && !alertadmins) - if(istype(container, /datum/TCS_Compiler)) - var/datum/TCS_Compiler/Compiler = container - var/obj/machinery/telecomms/server/Holder = Compiler.Holder - var/message = "Potential crash-inducing NTSL script detected at telecommunications server [Compiler.Holder] ([Holder.x], [Holder.y], [Holder.z])." - - alertadmins = 1 - message_admins(message, 1) -/* -Proc: RunBlock -Runs each statement in a block of code. -*/ -/datum/n_Interpreter/proc/RunBlock(var/datum/node/BlockDefinition/Block, var/datum/scope/scope = null) - var/is_global = istype(Block, /datum/node/BlockDefinition/GlobalBlock) - if(!is_global) - if(scope) - curScope = scope - else - CreateScope(Block) - else - if(!persist) - CreateGlobalScope() - - curScope = globalScope - - if(cur_statements < max_statements) - for(var/datum/node/statement/S in Block.statements) - while(paused) sleep(10) - - cur_statements++ - if(cur_statements >= max_statements) - RaiseError(new/datum/runtimeError/MaxCPU()) - AlertAdmins() - break - - if(istype(S, /datum/node/statement/VariableAssignment)) - var/datum/node/statement/VariableAssignment/stmt = S - var/name = stmt.var_name.id_name - - if(!stmt.object) - // Below we assign the variable first to null if it doesn't already exist. - // This is necessary for assignments like +=, and when the variable is used in a function - // If the variable already exists in a different block, then AssignVariable will automatically use that one. - if(!IsVariableAccessible(name)) - AssignVariable(name, null) - - AssignVariable(name, Eval(stmt.value)) - else - var/datum/D = Eval(GetVariable(stmt.object.id_name)) - if(!D) - return - - D.vars[stmt.var_name.id_name] = Eval(stmt.value) - - else if(istype(S, /datum/node/statement/VariableDeclaration)) - //VariableDeclaration nodes are used to forcibly declare a local variable so that one in a higher scope isn't used by default. - var/datum/node/statement/VariableDeclaration/dec=S - if(!dec.object) - AssignVariable(dec.var_name.id_name, null, curScope) - else - var/datum/D = Eval(GetVariable(dec.object.id_name)) - if(!D) - return - - D.vars[dec.var_name.id_name] = null - - else if(istype(S, /datum/node/statement/FunctionCall)) - RunFunction(S) - - else if(istype(S, /datum/node/statement/FunctionDefinition)) - //do nothing - - else if(istype(S, /datum/node/statement/WhileLoop)) - RunWhile(S) - - else if(istype(S, /datum/node/statement/IfStatement)) - RunIf(S) - - else if(istype(S, /datum/node/statement/ReturnStatement)) - if(!curFunction) - RaiseError(new/datum/runtimeError/UnexpectedReturn()) - continue - - status |= RETURNING - returnVal = Eval(S:value) - break - - else if(istype(S, /datum/node/statement/BreakStatement)) - status |= BREAKING - break - - else if(istype(S, /datum/node/statement/ContinueStatement)) - status |= CONTINUING - break - - else - RaiseError(new/datum/runtimeError/UnknownInstruction()) - - CHECK_TICK - - if(status) - break - - curScope = scopes.Pop() - -/* -Proc: RunFunction -Runs a function block or a proc with the arguments specified in the script. -*/ -/datum/n_Interpreter/proc/RunFunction(var/datum/node/statement/FunctionCall/stmt) - //Note that anywhere /datum/node/statement/FunctionCall/stmt is used so may /datum/node/expression/FunctionCall - - // If recursion gets too high (max 50 nested functions) throw an error - if(cur_recursion >= max_recursion) - AlertAdmins() - RaiseError(new/datum/runtimeError/RecursionLimitReached()) - return 0 - - var/datum/node/statement/FunctionDefinition/def - if(!stmt.object) //A scope's function is being called, stmt.object is null - def = GetFunction(stmt.func_name) - - else if(istype(stmt.object)) //A method of an object exposed as a variable is being called, stmt.object is a /node/identifier - var/O = GetVariable(stmt.object.id_name) //Gets a reference to the object which is the target of the function call. - if(!O) return //Error already thrown in GetVariable() - def = Eval(O) - - if(!def) - return - - cur_recursion++ // add recursion - if(istype(def)) - if(curFunction) functions.Push(curFunction) - var/datum/scope/S = CreateScope(def.block) - - for(var/i = 1 to def.parameters.len) - var/val - if(stmt.parameters.len >= i) - val = stmt.parameters[i] - //else - // unspecified param - AssignVariable(def.parameters[i], new/datum/node/expression/value/literal(Eval(val)), S) - - curFunction = stmt - RunBlock(def.block, S) - - //Handle return value - . = returnVal - status &= ~RETURNING - returnVal = null - curFunction = functions.Pop() - cur_recursion-- - - else - cur_recursion-- - var/list/params = new - for(var/datum/node/expression/P in stmt.parameters) - params += list(Eval(P)) - - if(isobject(def)) //def is an object which is the target of a function call - if(!hascall(def, stmt.func_name)) - RaiseError(new/datum/runtimeError/UndefinedFunction("[stmt.object.id_name].[stmt.func_name]")) - return - - return call(def, stmt.func_name)(arglist(params)) - - else //def is a path to a global proc - return call(def)(arglist(params)) - //else - // RaiseError(new/runtimeError/UnknownInstruction()) - -/* -Proc: RunIf -Checks a condition and runs either the if block or else block. -*/ -/datum/n_Interpreter/proc/RunIf(var/datum/node/statement/IfStatement/stmt) - if(!stmt.skip) - if(Eval(stmt.cond)) - RunBlock(stmt.block) - // Loop through the if else chain and tell them to be skipped. - var/datum/node/statement/IfStatement/i = stmt.else_if - var/fail_safe = 800 - - while(i && fail_safe) - fail_safe -= 1 - i.skip = 1 - i = i.else_if - - else if(stmt.else_block) - RunBlock(stmt.else_block) - - // We don't need to skip you anymore. - stmt.skip = 0 - -/* -Proc: RunWhile -Runs a while loop. -*/ - -/datum/n_Interpreter/proc/RunWhile(var/datum/node/statement/WhileLoop/stmt) - var/i = 1 - while(Eval(stmt.cond) && Iterate(stmt.block, i++)) - continue - - status &= ~BREAKING - -/* -Proc:Iterate -Runs a single iteration of a loop. Returns a value indicating whether or not to continue looping. -*/ - -/datum/n_Interpreter/proc/Iterate(var/datum/node/BlockDefinition/block, count) - RunBlock(block) - if(max_iterations > 0 && count >= max_iterations) - RaiseError(new/datum/runtimeError/IterationLimitReached()) - return 0 - - if(status & (BREAKING|RETURNING)) - return 0 - - status &= ~CONTINUING - return 1 - -/* -Proc: GetFunction -Finds a function in an accessible scope with the given name. Returns a . -*/ - -/datum/n_Interpreter/proc/GetFunction(name) - var/datum/scope/S = curScope - while(S) - if(S.functions.Find(name)) - return S.functions[name] - S = S.parent - - RaiseError(new/datum/runtimeError/UndefinedFunction(name)) - -/* -Proc: GetVariable -Finds a variable in an accessible scope and returns its value. -*/ - -/datum/n_Interpreter/proc/GetVariable(name) - var/datum/scope/S = curScope - while(S) - if(S.variables.Find(name)) - return S.variables[name] - S = S.parent - - RaiseError(new/datum/runtimeError/UndefinedVariable(name)) - -/datum/n_Interpreter/proc/GetVariableScope(name) //needed for when you reassign a variable in a higher scope - var/datum/scope/S = curScope - while(S) - if(S.variables.Find(name)) - return S - - S = S.parent - - -/datum/n_Interpreter/proc/IsVariableAccessible(name) - var/datum/scope/S = curScope - while(S) - if(S.variables.Find(name)) - return TRUE - S = S.parent - - return FALSE - - -/* -Proc: AssignVariable -Assigns a value to a variable in a specific block. - -Parameters: -name - The name of the variable to assign. -value - The value to assign to it. -S - The scope the variable resides in. If it is null, a scope with the variable already existing is found. If no scopes have a variable of the given name, the current scope is used. -*/ - -/datum/n_Interpreter/proc/AssignVariable(name, datum/node/expression/value, var/datum/scope/S = null) - if(!S) S = GetVariableScope(name) - if(!S) S = curScope - if(!S) S = globalScope - - ASSERT(istype(S)) - if(istext(value) || isnum(value) || isnull(value)) value = new/datum/node/expression/value/literal(value) - else if(!istype(value) && isobject(value)) value = new/datum/node/expression/value/reference(value) - //TODO: check for invalid name - S.variables["[name]"] = value - - diff --git a/code/modules/scripting/Interpreter/Scope.dm b/code/modules/scripting/Interpreter/Scope.dm deleted file mode 100644 index 24b3fbf727d..00000000000 --- a/code/modules/scripting/Interpreter/Scope.dm +++ /dev/null @@ -1,16 +0,0 @@ -/* - Class: scope - A runtime instance of a block. Used internally by the interpreter. -*/ -/datum/scope - var/datum/scope/parent = null - var/datum/node/BlockDefinition/block - var/list/functions - var/list/variables - -/datum/scope/New(var/datum/node/BlockDefinition/B, var/datum/scope/parent) - src.block = B - src.parent = parent - src.variables = B.initial_variables.Copy() - src.functions = B.functions.Copy() - . = ..() diff --git a/code/modules/scripting/Options.dm b/code/modules/scripting/Options.dm deleted file mode 100644 index be471756359..00000000000 --- a/code/modules/scripting/Options.dm +++ /dev/null @@ -1,122 +0,0 @@ -/* -File: Options -*/ -// Ascii values of characters -/var/const/ascii_A = 65 -/var/const/ascii_Z = 90 -/var/const/ascii_a = 97 -/var/const/ascii_z = 122 -/var/const/ascii_DOLLAR = 36 // $ -/var/const/ascii_ZERO = 48 -/var/const/ascii_NINE = 57 -/var/const/ascii_UNDERSCORE = 95 // _ - -/* - Class: n_scriptOptions -*/ -/datum/n_scriptOptions/proc/CanStartID(char) //returns true if the character can start a variable, function, or keyword name (by default letters or an underscore) - if(!isnum(char)) - char = text2ascii(char) - - return (char in ascii_A to ascii_Z) || (char in ascii_a to ascii_z) || char == ascii_UNDERSCORE || char == ascii_DOLLAR - -/datum/n_scriptOptions/proc/IsValidIDChar(char) //returns true if the character can be in the body of a variable, function, or keyword name (by default letters, numbers, and underscore) - if(!isnum(char)) - char = text2ascii(char) - - return CanStartID(char) || IsDigit(char) - -/datum/n_scriptOptions/proc/IsDigit(char) - if(!isnum(char)) - char = text2ascii(char) - - return char in ascii_ZERO to ascii_NINE - -/datum/n_scriptOptions/proc/IsValidID(id) //returns true if all the characters in the string are okay to be in an identifier name - if(!CanStartID(id)) //don't need to grab first char in id, since text2ascii does it automatically - return 0 - - var/list/charmap = string2charlist(id) - if(charmap.len == 1) - return 1 - - for(var/i = 2 to charmap.len) - if(!IsValidIDChar(charmap[i])) - return 0 - return 1 - -/* - Class: nS_Options - An implementation of for the n_Script language. -*/ -/datum/n_scriptOptions/nS_Options - var/list/symbols = list( - "(", - ")", - "\[", - "]", - ";", - ",", - "{", - "}" - ) //scanner - Characters that can be in symbols -/* -Var: keywords -An associative list used by the parser to parse keywords. Indices are strings which will trigger the keyword when parsed and the -associated values are types of which the proc will be called. -*/ - var/list/keywords = list( - "if" = /datum/n_Keyword/nS_Keyword/kwIf, - "else" = /datum/n_Keyword/nS_Keyword/kwElse, - "elseif" = /datum/n_Keyword/nS_Keyword/kwElseIf, - "while" = /datum/n_Keyword/nS_Keyword/kwWhile, - "break" = /datum/n_Keyword/nS_Keyword/kwBreak, - "continue" = /datum/n_Keyword/nS_Keyword/kwContinue, - "return" = /datum/n_Keyword/nS_Keyword/kwReturn, - "def" = /datum/n_Keyword/nS_Keyword/kwDef - ) - - var/list/assign_operators = list( - "=" = null, - "&=" = "&", - "|=" = "|", - "`=" = "`", - "+=" = "+", - "-=" = "-", - "*=" = "*", - "/=" = "/", - "^=" = "^", - "%=" = "%" - ) - - var/list/unary_operators = list( - "!" = /datum/node/expression/operator/unary/LogicalNot, - "~" = /datum/node/expression/operator/unary/BitwiseNot, - "-" = /datum/node/expression/operator/unary/Minus - ) - - var/list/binary_operators = list( - "==" = /datum/node/expression/operator/binary/Equal, - "!=" = /datum/node/expression/operator/binary/NotEqual, - ">" = /datum/node/expression/operator/binary/Greater, - "<" = /datum/node/expression/operator/binary/Less, - ">=" = /datum/node/expression/operator/binary/GreaterOrEqual, - "<=" = /datum/node/expression/operator/binary/LessOrEqual, - "&&" = /datum/node/expression/operator/binary/LogicalAnd, - "||" = /datum/node/expression/operator/binary/LogicalOr, - "&" = /datum/node/expression/operator/binary/BitwiseAnd, - "|" = /datum/node/expression/operator/binary/BitwiseOr, - "`" = /datum/node/expression/operator/binary/BitwiseXor, - "+" = /datum/node/expression/operator/binary/Add, - "-" = /datum/node/expression/operator/binary/Subtract, - "*" = /datum/node/expression/operator/binary/Multiply, - "/" = /datum/node/expression/operator/binary/Divide, - "^" = /datum/node/expression/operator/binary/Power, - "%" = /datum/node/expression/operator/binary/Modulo - ) - -/datum/n_scriptOptions/nS_Options/New() - . = ..() - for(var/O in assign_operators + binary_operators + unary_operators) - 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 deleted file mode 100644 index f0712fc5aa6..00000000000 --- a/code/modules/scripting/Parser/Expressions.dm +++ /dev/null @@ -1,371 +0,0 @@ -/* - File: Expressions - Procedures for parsing expressions. -*/ - -/* - Macros: Expression Macros - OPERATOR - A value indicating the parser currently expects a binary operator. - VALUE - A value indicating the parser currently expects a value. - SHIFT - Tells the parser to push the current operator onto the stack. - REDUCE - Tells the parser to reduce the stack. -*/ -#define OPERATOR 1 -#define VALUE 2 -#define SHIFT 0 -#define REDUCE 1 - -/* - Class: nS_Parser -*/ -/datum/n_Parser/nS_Parser -/* - Var: expecting - A variable which keeps track of whether an operator or value is expected. It should be either or . See - for more information. -*/ - var/expecting = VALUE - -/* - Proc: Precedence - Compares two operators, decides which is higher in the order of operations, and returns or . -*/ -/datum/n_Parser/nS_Parser/proc/Precedence(var/datum/node/expression/operator/top, var/datum/node/expression/operator/input) - if(istype(top)) - top = top.precedence - - if(istype(input)) - - input = input:precedence - - if(top >= input) - return REDUCE - - return SHIFT - -/* - Proc: GetExpression - Takes a token expected to represent a value and returns an node. -*/ -/datum/n_Parser/nS_Parser/proc/GetExpression(var/datum/token/T) - if(!T) - return - - if(istype(T, /datum/node/expression)) - return T - - switch(T.type) - if(/datum/token/word) - return new/datum/node/expression/value/variable(T.value) - - if(/datum/token/accessor) - var/datum/token/accessor/A = T - var/datum/node/expression/value/variable/E// = new(A.member) - var/datum/stack/S = new() - - while(istype(A.object, /datum/token/accessor)) - S.Push(A) - A = A.object - - ASSERT(istext(A.object)) - - while(A) - var/datum/node/expression/value/variable/V = new() - V.id = new(A.member) - if(E) - V.object = E - else - V.object = new/datum/node/identifier(A.object) - - E = V - A = S.Pop() - return E - - if(/datum/token/number, /datum/token/string) - return new/datum/node/expression/value/literal(T.value) - -/* - Proc: GetOperator - Gets a path related to a token or string and returns an instance of the given type. This is used to get an instance of either a binary or unary - operator from a token. - - Parameters: - O - The input value. If this is a token, O is reset to the token's value. - When O is a string and is in L, its associated value is used as the path to instantiate. - type - The desired type of the returned object. - L - The list in which to search for O. - - See Also: - - - - -*/ -/datum/n_Parser/nS_Parser/proc/GetOperator(O, type = /datum/node/expression/operator, L[]) - if(istype(O, type)) - return O //O is already the desired type - - if(istype(O, /datum/token)) - O = O:value //sets O to text - - if(istext(O)) //sets O to path - if(L.Find(O)) - O = L[O] - else - return null - - if(ispath(O)) - O = new O //catches path from last check - - else - return null //Unknown type - - return O - -/* - Proc: GetBinaryOperator - Uses to search for an instance of a binary operator type with which the given string is associated. For example, if - O is set to "+", an node is returned. - - See Also: - - - - -*/ -/datum/n_Parser/nS_Parser/proc/GetBinaryOperator(O) - return GetOperator(O, /datum/node/expression/operator/binary, options.binary_operators) - -/* - Proc: GetUnaryOperator - Uses to search for an instance of a unary operator type with which the given string is associated. For example, if - O is set to "!", a node is returned. - - See Also: - - - - -*/ -/datum/n_Parser/nS_Parser/proc/GetUnaryOperator(O) - return GetOperator(O, /datum/node/expression/operator/unary, options.unary_operators) - -/* - Proc: Reduce - Takes the operator on top of the opr stack and assigns its operand(s). Then this proc pushes the value of that operation to the top - of the val stack. -*/ -/datum/n_Parser/nS_Parser/proc/Reduce(var/datum/stack/opr, var/datum/stack/val) - var/datum/node/expression/operator/O = opr.Pop() - if(!O) - return - - if(!istype(O)) - errors += new/datum/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, /datum/node/expression/operator/binary)) - var/datum/node/expression/operator/binary/B=O - B.exp2 = val.Pop() - B.exp = val.Pop() - val.Push(B) - - else - O.exp=val.Pop() - val.Push(O) - -/* - Proc: EndOfExpression - Returns true if the current token represents the end of an expression. - - Parameters: - end - A list of values to compare the current token to. -*/ -/datum/n_Parser/nS_Parser/proc/EndOfExpression(end[]) - if(!curToken) - return 1 - if(istype(curToken, /datum/token/symbol) && end.Find(curToken.value)) - return 1 - if(istype(curToken, /datum/token/end) && end.Find(/datum/token/end)) - return 1 - return 0 - -/* - Proc: ParseExpression - Uses the Shunting-yard algorithm to parse expressions. - - Notes: - - When an opening parenthesis is found, then is called to handle it. - - The variable helps distinguish unary operators from binary operators (for cases like the - operator, which can be either). - - Articles: - - - - - - See Also: - - - - - - -*/ - -/datum/n_Parser/nS_Parser/proc/ParseExpression(var/list/end = list(/datum/token/end), list/ErrChars = list("{", "}"), check_functions = 0) - var/datum/stack/opr = new - var/datum/stack/val = new - src.expecting = VALUE - var/loop = 0 - for() - loop++ - if(loop > 800) - errors += new/datum/scriptError("Too many nested tokens.") - return - - if(EndOfExpression(end)) - break - - if(istype(curToken, /datum/token/symbol) && ErrChars.Find(curToken.value)) - errors += new/datum/scriptError/BadToken(curToken) - break - - if(index > tokens.len) //End of File - errors += new/datum/scriptError/EndOfFile() - break - - var/datum/token/ntok - if(index + 1 <= tokens.len) - ntok = tokens[index + 1] - - if(istype(curToken, /datum/token/symbol) && curToken.value == "(") //Parse parentheses expression - if(expecting != VALUE) - errors += new/datum/scriptError/ExpectedToken("operator", curToken) - NextToken() - continue - - val.Push(ParseParenExpression()) - - else if(istype(curToken, /datum/token/symbol)) //Operator found. - var/datum/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) - errors += new/datum/scriptError/ExpectedToken("operator", curToken) - NextToken() - continue - else - curOperator = GetUnaryOperator(curToken) - if(!curOperator) //given symbol isn't a unary operator - errors += new/datum/scriptError/ExpectedToken("expression", curToken) - NextToken() - continue - - if(opr.Top() && Precedence(opr.Top(), curOperator) == REDUCE) //Check order of operations and reduce if necessary - Reduce(opr, val) - continue - - opr.Push(curOperator) - src.expecting = VALUE - - else if(ntok && ntok.value == "(" && istype(ntok, /datum/token/symbol)\ - && istype(curToken, /datum/token/word)) //Parse function call - - if(!check_functions) - - var/datum/token/preToken = curToken - var/old_expect = src.expecting - var/fex = ParseFunctionExpression() - if(old_expect != VALUE) - errors += new/datum/scriptError/ExpectedToken("operator", preToken) - NextToken() - continue - - val.Push(fex) - else - errors += new/datum/scriptError/ParameterFunction(curToken) - break - - else if(istype(curToken, /datum/token/keyword)) //inline keywords - var/datum/n_Keyword/kw = options.keywords[curToken.value] - kw = new kw(inline=1) - if(kw) - if(!kw.Parse(src)) - return - else - errors += new/datum/scriptError/BadToken(curToken) - - else if(istype(curToken, /datum/token/end)) //semicolon found where it wasn't expected - errors += new/datum/scriptError/BadToken(curToken) - NextToken() - continue - else - if(expecting != VALUE) - errors += new/datum/scriptError/ExpectedToken("operator", curToken) - NextToken() - continue - - val.Push(GetExpression(curToken)) - src.expecting = OPERATOR - - NextToken() - - while(opr.Top()) - Reduce(opr, val) - //Reduce the value stack completely - . = val.Pop() //Return what should be the last value on the stack - - if(val.Top()) // - var/datum/node/N = val.Pop() - errors += new/datum/scriptError("Error parsing expression. Unexpected value left on stack: [N.ToString()].") - return null - -/* - Proc: ParseFunctionExpression - Parses a function call inside of an expression. - - See Also: - - -*/ - -/datum/n_Parser/nS_Parser/proc/ParseFunctionExpression() - var/datum/node/expression/FunctionCall/exp = new - exp.func_name = curToken.value - NextToken() //skip function name - NextToken() //skip open parenthesis, already found - var/loops = 0 - - for() - loops++ - if(loops >= 800) - errors += new/datum/scriptError("Too many nested expressions.") - break - //CRASH("Something TERRIBLE has gone wrong in ParseFunctionExpression ;__;") - - if(istype(curToken, /datum/token/symbol) && curToken.value == ")") - return exp - exp.parameters += ParseParamExpression() - if(errors.len) - return exp - - if(curToken.value == "," && istype(curToken, /datum/token/symbol)) - NextToken() //skip comma - - if(istype(curToken, /datum/token/end)) //Prevents infinite loop... - errors += new/datum/scriptError/ExpectedToken(")") - return exp - -/* - Proc: ParseParenExpression - Parses an expression that ends with a close parenthesis. This is used for parsing expressions inside of parentheses. - - See Also: - - -*/ -/datum/n_Parser/nS_Parser/proc/ParseParenExpression() - if(!CheckToken("(", /datum/token/symbol)) - return - return new/datum/node/expression/operator/unary/group(ParseExpression(list(")"))) - -/* - Proc: ParseParamExpression - Parses an expression that ends with either a comma or close parenthesis. This is used for parsing the parameters passed to a function call. - - See Also: - - -*/ -/datum/n_Parser/nS_Parser/proc/ParseParamExpression(var/check_functions = 0) - var/cf = check_functions - return ParseExpression(list(",", ")"), check_functions = cf) \ No newline at end of file diff --git a/code/modules/scripting/Parser/Keywords.dm b/code/modules/scripting/Parser/Keywords.dm deleted file mode 100644 index cef9a065213..00000000000 --- a/code/modules/scripting/Parser/Keywords.dm +++ /dev/null @@ -1,204 +0,0 @@ -/* - File: Keywords -*/ -var/const/KW_FAIL = 0 //Fatal error; stop parsing entire script. -var/const/KW_PASS = 1 //OK -var/const/KW_ERR = 2 //Non-fatal error, keyword couldn't be handled properly. Ignore keyword but continue on. -var/const/KW_WARN = 3 //Warning - -/* -var/const/Class: n_Keyword -var/const/Represents a special statement in the code triggered by a keyword. -*/ -/datum/n_Keyword -/* - Var: inline - 1 if the keyword is in an expression (e.g. the new keyword in many languages), 0 otherwise (such as the if and else keywords). -*/ - var/inline - -/datum/n_Keyword/New(inline = 0) - src.inline = inline - return ..() - -/* - Proc: Parse - Called when the parser finds a keyword in the code. - - Parameters: - parser - The parser that created this object. You can use the parameter to manipulate the parser in order to add statements and blocks - to its AST. -*/ -/datum/n_Keyword/proc/Parse(var/datum/n_Parser/parser) - return -/* - Class: nS_Keyword - A keyword in n_Script. By default these include return, if, else, while, and def. To enable or disable a keyword, change the - list. - - Behavior: - When a parser is expecting a new statement, and a keyword listed in is found, it will call the keyword's - proc. -*/ -/datum/n_Keyword/nS_Keyword/New(var/inline = 0) - if(inline) - del src - -/datum/n_Keyword/nS_Keyword/kwReturn/Parse(var/datum/n_Parser/nS_Parser/parser) - . = KW_PASS - if(istype(parser.curBlock, /datum/node/BlockDefinition/GlobalBlock)) // Exit out of the program by setting the tokens list size to the same as index. - parser.tokens.len = parser.index - return - - var/datum/node/statement/ReturnStatement/stmt = new - parser.NextToken() //skip 'return' token - stmt.value = parser.ParseExpression() - parser.curBlock.statements += stmt - -/datum/n_Keyword/nS_Keyword/kwIf/Parse(var/datum/n_Parser/nS_Parser/parser) - . = KW_PASS - var/datum/node/statement/IfStatement/stmt = new - parser.NextToken() //skip 'if' token - stmt.cond = parser.ParseParenExpression() - if(!parser.CheckToken(")", /datum/token/symbol)) - return KW_FAIL - - if(!parser.CheckToken("{", /datum/token/symbol, skip=0)) //Token needs to be preserved for parse loop, so skip=0 - return KW_ERR - - parser.curBlock.statements += stmt - stmt.block = new - parser.AddBlock(stmt.block) - -/datum/n_Keyword/nS_Keyword/kwElseIf/Parse(var/datum/n_Parser/nS_Parser/parser) - . = KW_PASS - var/list/L = parser.curBlock.statements - var/datum/node/statement/IfStatement/ifstmt - - if(L && L.len) - ifstmt = L[L.len] //Get the last statement in the current block - - if(!ifstmt || !istype(ifstmt) || ifstmt.else_if) - to_chat(usr, "NTSL: ELSE IF FAILED: [!ifstmt], [!istype(ifstmt)], [!istype(ifstmt) || ifstmt.else_if]")// Usr is unsafe as SHIT but JUST incase I forget this debug line like the fucking asset cache... - - parser.errors += new/datum/scriptError/ExpectedToken("if statement", parser.curToken) - return KW_FAIL - - var/datum/node/statement/IfStatement/ElseIf/stmt = new - parser.NextToken() //skip 'if' token - stmt.cond = parser.ParseParenExpression() - if(!parser.CheckToken(")", /datum/token/symbol)) - return KW_FAIL - - if(!parser.CheckToken("{", /datum/token/symbol, skip = 0)) //Token needs to be preserved for parse loop, so skip=0 - return KW_ERR - - parser.curBlock.statements += stmt - stmt.block = new - ifstmt.else_if = stmt - parser.AddBlock(stmt.block) - -/datum/n_Keyword/nS_Keyword/kwElse/Parse(var/datum/n_Parser/nS_Parser/parser) - . = KW_PASS - var/list/L = parser.curBlock.statements - var/datum/node/statement/IfStatement/stmt - - if(L && L.len) - stmt = L[L.len] //Get the last statement in the current block - - if(!stmt || !istype(stmt) || stmt.else_block) //Ensure that it is an if statement - to_chat(usr, "NTSL: ELSE IF FAILED: [!stmt], [!istype(stmt)], [!istype(stmt) || stmt.else_block]")// Usr is unsafe as SHIT but JUST incase I forget this debug line like the fucking asset cache... - - parser.errors += new/datum/scriptError/ExpectedToken("if statement", parser.curToken) - return KW_FAIL - - parser.NextToken() //skip 'else' token - if(!parser.CheckToken("{", /datum/token/symbol, skip = 0)) - return KW_ERR - - stmt.else_block = new() - parser.AddBlock(stmt.else_block) - -/datum/n_Keyword/nS_Keyword/kwWhile/Parse(var/datum/n_Parser/nS_Parser/parser) - . = KW_PASS - var/datum/node/statement/WhileLoop/stmt = new - parser.NextToken() //skip 'while' token - stmt.cond = parser.ParseParenExpression() - if(!parser.CheckToken(")", /datum/token/symbol)) - return KW_FAIL - - if(!parser.CheckToken("{", /datum/token/symbol, skip=0)) - return KW_ERR - - parser.curBlock.statements += stmt - stmt.block = new - parser.AddBlock(stmt.block) - -/datum/n_Keyword/nS_Keyword/kwBreak/Parse(var/datum/n_Parser/nS_Parser/parser) - . = KW_PASS - if(istype(parser.curBlock, /datum/node/BlockDefinition/GlobalBlock)) - parser.errors += new/datum/scriptError/BadToken(parser.curToken) - . = KW_WARN - - var/datum/node/statement/BreakStatement/stmt = new - parser.NextToken() //skip 'break' token - parser.curBlock.statements += stmt - -/datum/n_Keyword/nS_Keyword/kwContinue/Parse(var/datum/n_Parser/nS_Parser/parser) - . = KW_PASS - if(istype(parser.curBlock, /datum/node/BlockDefinition/GlobalBlock)) - parser.errors += new/datum/scriptError/BadToken(parser.curToken) - . = KW_WARN - - var/datum/node/statement/ContinueStatement/stmt = new - parser.NextToken() //skip 'break' token - parser.curBlock.statements += stmt - -/datum/n_Keyword/nS_Keyword/kwDef/Parse(var/datum/n_Parser/nS_Parser/parser) - . = KW_PASS - var/datum/node/statement/FunctionDefinition/def = new - parser.NextToken() //skip 'def' token - - if(!parser.options.IsValidID(parser.curToken.value)) - parser.errors += new/datum/scriptError/InvalidID(parser.curToken) - return KW_FAIL - - def.func_name = parser.curToken.value - parser.NextToken() - - if(!parser.CheckToken("(", /datum/token/symbol)) - return KW_FAIL - - for() //for now parameters can be separated by whitespace - they don't need a comma in between - if(istype(parser.curToken, /datum/token/symbol)) - switch(parser.curToken.value) - if(",") - parser.NextToken() - if(")") - break - else - parser.errors += new/datum/scriptError/BadToken(parser.curToken) - return KW_ERR - - else if(istype(parser.curToken, /datum/token/word)) - def.parameters += parser.curToken.value - parser.NextToken() - - else - parser.errors += new/datum/scriptError/InvalidID(parser.curToken) - return KW_ERR - - if(!parser.CheckToken(")", /datum/token/symbol)) - return KW_FAIL - - if(istype(parser.curToken, /datum/token/end)) //Function prototype - parser.curBlock.statements += def - - else if(parser.curToken.value == "{" && istype(parser.curToken, /datum/token/symbol)) - def.block = new - parser.curBlock.statements += def - parser.curBlock.functions[def.func_name] = def - parser.AddBlock(def.block) - else - parser.errors += new/datum/scriptError/BadToken(parser.curToken) - return KW_FAIL diff --git a/code/modules/scripting/Parser/Parser.dm b/code/modules/scripting/Parser/Parser.dm deleted file mode 100644 index d9c737e7ea8..00000000000 --- a/code/modules/scripting/Parser/Parser.dm +++ /dev/null @@ -1,205 +0,0 @@ -/* - File: Parser -*/ -/* - Class: n_Parser - An object that reads tokens and produces an AST (abstract syntax tree). -*/ -/datum/n_Parser -/* - Var: index - The parser's current position in the token's list. -*/ - var/index = 1 -/* - Var: tokens - A list of tokens in the source code generated by a scanner. -*/ - var/list/tokens = new -/* - Var: errors - A list of fatal errors found by the parser. If there are any items in this list, then it is not safe to run the returned AST. - - See Also: - - -*/ - var/list/errors = new -/* - Var: warnings - A list of non-fatal problems in the script. -*/ - var/list/warnings = new -/* - Var: curToken - The token at in . -*/ - var/datum/token/curToken - var/datum/stack/blocks = new - var/datum/node/BlockDefinition/GlobalBlock/global_block = new - var/datum/node/BlockDefinition/GlobalBlock/curBlock - -/* - Proc: Parse - Reads the tokens and returns the AST's node. Be sure to populate the tokens list before calling this procedure. -*/ -/datum/n_Parser/proc/Parse() - return -/* - Proc: NextToken - Sets to the next token in the list, or null if there are no more tokens. -*/ -/datum/n_Parser/proc/NextToken() - if(index >= tokens.len) - curToken = null - else - curToken = tokens[++index] - return curToken - -/* - Class: nS_Parser - An implmentation of a parser for n_Script. -*/ -/datum/n_Parser/nS_Parser - var/datum/n_scriptOptions/nS_Options/options -/* - Constructor: New - - Parameters: - tokens - A list of tokens to parse. - options - An object used for configuration. -*/ -/datum/n_Parser/nS_Parser/New(tokens[], var/datum/n_scriptOptions/options) - src.tokens = tokens - src.options = options - curBlock = global_block - return ..() - -/datum/n_Parser/nS_Parser/Parse() - ASSERT(tokens) - for(,src.index <= src.tokens.len, src.index++) - curToken = tokens[index] - switch(curToken.type) - if(/datum/token/keyword) - var/datum/n_Keyword/kw = options.keywords[curToken.value] - kw = new kw() - if(kw) - if(!kw.Parse(src)) - return - - if(/datum/token/word) - var/datum/token/ntok - if(index + 1 > tokens.len) - errors += new/datum/scriptError/BadToken(curToken) - continue - - ntok = tokens[index + 1] - - if(!istype(ntok, /datum/token/symbol)) - errors += new/datum/scriptError/BadToken(ntok) - continue - - if(ntok.value == "(") - ParseFunctionStatement() - - else if(options.assign_operators.Find(ntok.value)) - ParseAssignment() - - else - errors += new/datum/scriptError/BadToken(ntok) - continue - - if(!istype(curToken, /datum/token/end)) - errors += new/datum/scriptError/ExpectedToken(";", curToken) - continue - - if(/datum/token/symbol) - if(curToken.value == "}") - if(!EndBlock()) - errors += new/datum/scriptError/BadToken(curToken) - continue - - else - errors += new/datum/scriptError/BadToken(curToken) - continue - - if(/datum/token/end) - warnings += new/datum/scriptError/BadToken(curToken) - continue - - else - errors += new/datum/scriptError/BadToken(curToken) - return - - return global_block - -/datum/n_Parser/nS_Parser/proc/CheckToken(val, type, err = 1, skip = 1) - if(curToken.value != val || !istype(curToken, type)) - if(err) - errors += new/datum/scriptError/ExpectedToken(val, curToken) - return 0 - if(skip) - NextToken() - - return 1 - -/datum/n_Parser/nS_Parser/proc/AddBlock(var/datum/node/BlockDefinition/B) - blocks.Push(curBlock) - curBlock = B - -/datum/n_Parser/nS_Parser/proc/EndBlock() - if(curBlock == global_block) - return 0 - - curBlock = blocks.Pop() - return 1 - -/datum/n_Parser/nS_Parser/proc/ParseAssignment() - var/name = curToken.value - if(!options.IsValidID(name)) - errors += new/datum/scriptError/InvalidID(curToken) - return - - NextToken() - var/t = options.binary_operators[options.assign_operators[curToken.value]] - var/datum/node/statement/VariableAssignment/stmt = new() - stmt.var_name = new(name) - NextToken() - - if(t) - stmt.value = new t() - stmt.value:exp = new/datum/node/expression/value/variable(stmt.var_name) - stmt.value:exp2 = ParseExpression() - else - stmt.value = ParseExpression() - - curBlock.statements += stmt - -/datum/n_Parser/nS_Parser/proc/ParseFunctionStatement() - if(!istype(curToken, /datum/token/word)) - errors += new/datum/scriptError("Bad identifier in function call.") - return - - var/datum/node/statement/FunctionCall/stmt=new - stmt.func_name = curToken.value - NextToken() //skip function name - if(!CheckToken("(", /datum/token/symbol)) //Check for and skip open parenthesis - return - var/loops = 0 - for() - loops++ - if(loops >= 800) - errors +=new/datum/scriptError("Cannot find ending params.") - return - - if(!curToken) - errors+=new/datum/scriptError/EndOfFile() - return - if(istype(curToken, /datum/token/symbol) && curToken.value == ")") - curBlock.statements += stmt - NextToken() //Skip close parenthesis - return - - var/datum/node/expression/P = ParseParamExpression(check_functions = 1) - stmt.parameters += P - if(istype(curToken, /datum/token/symbol) && curToken.value == ",") - NextToken() diff --git a/code/modules/scripting/Scanner/Scanner.dm b/code/modules/scripting/Scanner/Scanner.dm deleted file mode 100644 index da6a2c04803..00000000000 --- a/code/modules/scripting/Scanner/Scanner.dm +++ /dev/null @@ -1,293 +0,0 @@ -/* - File: Scanner -*/ -/* - Class: n_Scanner - An object responsible for breaking up source code into tokens for use by the parser. -*/ -/datum/n_Scanner - var/list/code -/* - Var: errors - A list of fatal errors found by the scanner. If there are any items in this list, then it is not safe to parse the returned tokens. - - See Also: - - -*/ - var/list/errors = new -/* - Var: warnings - A list of non-fatal problems in the source code found by the scanner. -*/ - var/list/warnings = new - -/* - Proc: LoadCode - Loads source code. -*/ -/datum/n_Scanner/proc/LoadCode(var/list/c) - code=c - -/* - Proc: LoadCodeFromFile - Gets the code from a file and calls . -*/ -/datum/n_Scanner/proc/LoadCodeFromFile(var/f) - LoadCode(file2text(f)) - -/* - Proc: Scan - Runs the scanner and returns the resulting list of tokens. Ensure that has been called first. -*/ -/datum/n_Scanner/proc/Scan() - -/* - Class: nS_Scanner - A scanner implementation for n_Script. -*/ -/datum/n_Scanner/nS_Scanner -/* - Variable: codepos - The scanner's position in the source code. -*/ - var/codepos = 1 - var/line = 1 - var/linepos = 0 //column=codepos-linepos - var/datum/n_scriptOptions/nS_Options/options - - var/commenting = 0 - // 1: single-line - // 2: multi-line -/* - Variable: ignore - A list of characters that are ignored by the scanner. - - Default Value: - Whitespace -*/ - var/list/ignore = list(" ", "\t", "\n") //Don't add tokens for whitespace -/* - Variable: end_stmt - A list of characters that end a statement. Each item may only be one character long. - - Default Value: - Semicolon -*/ - var/list/end_stmt = list(";") -/* - Variable: string_delim - A list of characters that can start and end strings. - - Default Value: - Double and single quotes. -*/ - var/list/string_delim = list("\"", "'") -/* - Variable: delim - A list of characters that denote the start of a new token. This list is automatically populated. -*/ - var/list/delim = new - -/* - Macro: COL - The current column number. -*/ - #define COL codepos-linepos - -/* - Constructor: New - Parameters: - code - The source code to tokenize. - options - An object used to configure the scanner. -*/ -/datum/n_Scanner/nS_Scanner/New(var/list/c, var/datum/n_scriptOptions/nS_Options/options) - . = ..() - ignore += ascii2text(13) //Carriage return - delim += ignore + options.symbols + end_stmt + string_delim - src.options = options - LoadCode(c) - -/datum/n_Scanner/nS_Scanner/Scan() //Creates a list of tokens from source code - var/list/tokens = new - for(, src.codepos <= code.len, src.codepos++) - var/char = code[codepos] - var/nextchar = TCOMMS_SAFE_INDEX(code, codepos + 1) - if(char == "\n") - line++ - linepos = codepos - - if(char in ignore) - continue - - else if(char == "/" && (nextchar == "*" || nextchar == "/")) - ReadComment() - - else if(end_stmt.Find(char)) - tokens += new/datum/token/end(char, line, COL) - - else if(string_delim.Find(char)) - codepos++ //skip string delimiter - tokens += ReadString(char) - - else if(options.CanStartID(char)) - tokens += ReadWord() - - else if(options.IsDigit(char)) - tokens += ReadNumber() - - else if(options.symbols.Find(char)) - tokens += ReadSymbol() - - CHECK_TICK - - codepos = initial(codepos) - line = initial(line) - linepos = initial(linepos) - return tokens - - -/* - Proc: ReadString - Reads a string in the source code into a token. - - Parameters: - start - The character used to start the string. -*/ -/datum/n_Scanner/nS_Scanner/proc/ReadString(start) - var/buf - for(, codepos <= code.len, codepos++)//codepos to length(code)) - var/char = code[codepos] - switch(char) - if("\\") //Backslash (\) encountered in string - codepos++ //Skip next character in string, since it was escaped by a backslash - char = TCOMMS_SAFE_INDEX(code, codepos) - switch(char) - if("\\") //Double backslash - buf += "\\" - if("n") //\n Newline - buf += "\n" - else - if(char == start) //\" Doublequote - buf += start - else //Unknown escaped text - buf += char - if("\n") - . = new/datum/token/string(buf, line, COL) - errors += new/datum/scriptError("Unterminated string. Newline reached.", .) - line++ - linepos = codepos - break - else - if(char == start) //string delimiter found, end string - break - else - buf += char //Just a normal character in a string - if(!.) - return new/datum/token/string(buf, line, COL) - -/* - Proc: ReadWord - Reads characters separated by an item in into a token. -*/ -/datum/n_Scanner/nS_Scanner/proc/ReadWord() - var/char = code[codepos] - var/buf - - while(!delim.Find(char)) - buf += char - if(++codepos > code.len) break - char = code[codepos] - - codepos-- //allow main Scan() proc to read the delimiter - if(options.keywords.Find(buf)) - return new/datum/token/keyword(buf, line, COL) - else - return new/datum/token/word(buf, line, COL) - -/* - Proc: ReadSymbol - Reads a symbol into a token. -*/ -/datum/n_Scanner/nS_Scanner/proc/ReadSymbol() - var/char = code[codepos] - var/buf - - while(options.symbols.Find(buf + char)) - buf += char - if(++codepos > code.len) break - char = code[codepos] - - codepos-- //allow main Scan() proc to read the next character - return new /datum/token/symbol(buf, line, COL) - -/* - Proc: ReadNumber - Reads a number into a token. -*/ -/datum/n_Scanner/nS_Scanner/proc/ReadNumber() - var/char = code[codepos] - var/buf - var/dec = 0 - - while(options.IsDigit(char) || (char == "." && !dec)) - if(char == ".") - dec = 1 - - buf += char - codepos++ - char = TCOMMS_SAFE_INDEX(code, codepos) - - var/datum/token/number/T = new(buf, line, COL) - if(isnull(text2num(buf))) - errors += new/datum/scriptError("Bad number: ", T) - T.value = 0 - - codepos-- //allow main Scan() proc to read the next character - return T - -/* - Proc: ReadComment - Reads a comment and outputs the type of comment -*/ - -/datum/n_Scanner/nS_Scanner/proc/ReadComment() - var/char = code[codepos] - var/nextchar = TCOMMS_SAFE_INDEX(code, codepos + 1) - var/charstring = char + nextchar - var/comm = 1 - // 1: single-line comment - // 2: multi-line comment - var/expectedend = 0 - - if(charstring == "//" || charstring == "/*") - if(charstring == "/*") - comm = 2 // starts a multi-line comment - - while(comm) - if(++codepos > code.len) - break - - if(expectedend) // ending statement expected... - char = code[codepos] - if(char == "/") // ending statement found - beak the comment - comm = 0 - break - - if(comm == 2) - // multi-line comments are broken by ending statements - char = code[codepos] - if(char == "*") - expectedend = 1 - continue - else - char = code[codepos] - if(char == "\n") - comm = 0 - break - - if(expectedend) - expectedend = 0 - - if(comm == 2) - errors += new/datum/scriptError/UnterminatedComment() - diff --git a/code/modules/scripting/Scanner/Tokens.dm b/code/modules/scripting/Scanner/Tokens.dm deleted file mode 100644 index acf7bbbad99..00000000000 --- a/code/modules/scripting/Scanner/Tokens.dm +++ /dev/null @@ -1,40 +0,0 @@ -/* - Class: Token - Represents an entity and position in the source code. -*/ -/datum/token - var/value - var/line - var/column - -/datum/token/New(v, l = 0, c = 0) - value = v - line = l - column = c - -/datum/token/string - -/datum/token/symbol - -/datum/token/word - -/datum/token/keyword - -/datum/token/number/New() - . = ..() - if(!isnum(value)) - value = text2num(value) - ASSERT(!isnull(value)) - -/datum/token/accessor - var/object - var/member - -/datum/token/accessor/New(object, member, l = 0, c = 0) - src.object = object - src.member = member - src.value = "[object].[member]" //for debugging only - src.line = l - src.column = c - -/datum/token/end diff --git a/code/modules/scripting/__defines.dm b/code/modules/scripting/__defines.dm deleted file mode 100644 index 52f30e68fdc..00000000000 --- a/code/modules/scripting/__defines.dm +++ /dev/null @@ -1 +0,0 @@ -#define TCOMMS_SAFE_INDEX(list, index) list.len > index ? list[index] : null diff --git a/code/modules/shuttle/supply.dm b/code/modules/shuttle/supply.dm index 4254f5dd130..a6baec94d26 100644 --- a/code/modules/shuttle/supply.dm +++ b/code/modules/shuttle/supply.dm @@ -739,7 +739,7 @@ return 1 /obj/machinery/computer/supplycomp/proc/post_signal(var/command) - var/datum/radio_frequency/frequency = radio_controller.return_frequency(1435) + var/datum/radio_frequency/frequency = radio_controller.return_frequency(DISPLAY_FREQ) if(!frequency) return diff --git a/code/modules/surgery/organs/blood.dm b/code/modules/surgery/organs/blood.dm index 327e0a7d268..2464c0d795f 100644 --- a/code/modules/surgery/organs/blood.dm +++ b/code/modules/surgery/organs/blood.dm @@ -85,7 +85,7 @@ bleed_rate = max(bleed_rate - 0.5, temp_bleed)//if no wounds, other bleed effects (heparin) naturally decreases if(internal_bleeding_rate && !(status_flags & FAKEDEATH)) - bleed(internal_bleeding_rate) + bleed_internal(internal_bleeding_rate) if(bleed_rate && !bleedsuppress && !(status_flags & FAKEDEATH)) bleed(bleed_rate) @@ -108,6 +108,26 @@ if(istype(R) && isturf(loc)) R.reaction_turf(get_turf(src), amt * EXOTIC_BLEED_MULTIPLIER) +/mob/living/carbon/proc/bleed_internal(amt) // Return 1 if we've coughed blood up, 2 if we're vomited it. + if(blood_volume) + blood_volume = max(blood_volume - amt, 0) + if (prob(10 * amt)) // +5% chance per internal bleeding site that we'll cough up blood on a given tick. + custom_emote(1, "coughs up blood!") + add_splatter_floor(loc, 1) + return 1 + else if (amt >= 1 && prob(5 * amt)) // +2.5% chance per internal bleeding site that we'll cough up blood on a given tick. Must be bleeding internally in more than one place to have a chance at this. + vomit(0, 1) + return 2 + return 0 + +/mob/living/carbon/human/bleed_internal(amt) + if(!(NO_BLOOD in dna.species.species_traits)) + .=..() + if(dna.species.exotic_blood && .) // Do we have exotic blood, and have we left any on the ground? + var/datum/reagent/R = GLOB.chemical_reagents_list[get_blood_id()] + if(istype(R) && isturf(loc)) + R.reaction_turf(get_turf(src), amt * EXOTIC_BLEED_MULTIPLIER) + /mob/living/proc/restore_blood() blood_volume = initial(blood_volume) diff --git a/html/changelog.html b/html/changelog.html index a8e540b74a0..5b68ec39ce1 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -56,6 +56,109 @@ -->
+

16 November 2018

+

Azule Utama updated:

+
    +
  • Changed falloff damage to be usable on any desired projectile rather than just shotgun pellets. balance: X-ray lasers now use 100 charge per shot (previously 50). balance: X-ray laser guns now have falloff damage. The longer the laser is in the air, the lower its damage becomes.
  • +
  • Slight addition to X-ray laser's description.
  • +
+

Certhic updated:

+
    +
  • Replaces radio freq magic numbers with constants
  • +
+

Farie82 updated:

+
    +
  • Borgs can't get perma stunned anymore by goliaths and slings and such
  • +
+

Fethas updated:

+
    +
  • The floors are not safe! HONK!
  • +
+

Jazz23 updated:

+
    +
  • Added flasher buttons in perma brig as well as windoors in botany, the wardens office, and cargo. Also added blast doors to transit tube.
  • +
  • HoP's flasher button not working, CE's secure shutter button and transit tube lockdown button not working.
  • +
+

Kyep updated:

+
    +
  • The admin verb to list SSD players now highlights players who are another player's antag target. Additionally it lets you despawn players whose body is already in cryo.
  • +
  • Fixed a bug which caused banning to fail in rare situations.
  • +
+

Mitchs98 updated:

+
    +
  • You can no longer rip the hood part of a hoodie off of someone's head.
  • +
  • Bee Costume and Monk Robe icons now show up properly in your inventory.
  • +
+

Triiodine updated:

+
    +
  • Hotfixes taser projectiles being borked due to X-Ray re-work.
  • +
+

tigercat2000 updated:

+
    +
  • SPEEEEEEEED to the asset cache, making preloaded UI assets transfer much faster.
  • +
  • NTTC deserializing works again
  • +
  • NTTC regex works again
  • +
  • NTTC no longer spams admins
  • +
  • NTSL2 no more, it is officially NTTC
  • +
  • NanoUI's fancy mode is hot shit again!
  • +
  • NanoUI's fancy mode is no longer broken as hell!
  • +
  • 512 support for Nano dev tools
  • +
+ +

15 November 2018

+

Azule Utama updated:

+
    +
  • Fixed an exploit which allowed cultists to curse the shuttle more than twice. Steve can only take so much punishment ya know...
  • +
+

Certhic updated:

+
    +
  • The scrollbar of NanoUI now looks more Nano-ish
  • +
  • The title bar of NanoUI now sticks while scrolling
  • +
  • changed the mouse hover behavior on the fancy NanoUI buttons
  • +
+

Dave-TH updated:

+
    +
  • Internal bleeding is now represented by coughing (And occasionally vomiting) blood! Nifty!
  • +
+

uc_guy updated:

+
    +
  • Fixed the passive effects of prayer beads and prayer bread.
  • +
+ +

14 November 2018

+

KasparoVy updated:

+
    +
  • Vulpkanin Earfluff can be selected in facial hair again.
  • +
  • Vulpine Fluff and Earfluff head accessories and facial hair now have correct icon states.
  • +
+

uc_guy updated:

+
    +
  • Borgs no longer have infinite roller beds.
  • +
+ +

13 November 2018

+

Birdtalon updated:

+
    +
  • Fixes playtime self checker.
  • +
+

Certhic updated:

+
    +
  • fixed a cigs runtime error
  • +
+

TDSSS updated:

+
    +
  • Ancient station's lockdown is now lifted correctly.
  • +
  • Ancient station RD console can now be used.
  • +
+

craftxbox updated:

+
    +
  • use mob voice instead of mob name for radios broadcasting signals.
  • +
+

datlo updated:

+
    +
  • Prevent wizards from casting rod form inside the wizard den.
  • +
+

12 November 2018

Azule Utama updated:

    diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 31fc05ced0b..abfebe36265 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -8021,3 +8021,73 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. been separated and refactored. Report missing hairstyle / screen / horns / frills / tails etc. - tweak: Desolate's peacekeeper fluff cyborg sprite is now his service sprite. +2018-11-13: + Birdtalon: + - bugfix: Fixes playtime self checker. + Certhic: + - bugfix: fixed a cigs runtime error + TDSSS: + - bugfix: Ancient station's lockdown is now lifted correctly. + - bugfix: Ancient station RD console can now be used. + craftxbox: + - bugfix: use mob voice instead of mob name for radios broadcasting signals. + datlo: + - bugfix: Prevent wizards from casting rod form inside the wizard den. +2018-11-14: + KasparoVy: + - bugfix: Vulpkanin Earfluff can be selected in facial hair again. + - bugfix: Vulpine Fluff and Earfluff head accessories and facial hair now have correct + icon states. + uc_guy: + - bugfix: Borgs no longer have infinite roller beds. +2018-11-15: + Azule Utama: + - bugfix: Fixed an exploit which allowed cultists to curse the shuttle more than + twice. Steve can only take so much punishment ya know... + Certhic: + - rscadd: The scrollbar of NanoUI now looks more Nano-ish + - rscadd: The title bar of NanoUI now sticks while scrolling + - tweak: changed the mouse hover behavior on the fancy NanoUI buttons + Dave-TH: + - tweak: Internal bleeding is now represented by coughing (And occasionally vomiting) + blood! Nifty! + uc_guy: + - bugfix: Fixed the passive effects of prayer beads and prayer bread. +2018-11-16: + Azule Utama: + - tweak: 'Changed falloff damage to be usable on any desired projectile rather than + just shotgun pellets. balance: X-ray lasers now use 100 charge per shot (previously + 50). balance: X-ray laser guns now have falloff damage. The longer the laser + is in the air, the lower its damage becomes.' + - spellcheck: Slight addition to X-ray laser's description. + Certhic: + - tweak: Replaces radio freq magic numbers with constants + Farie82: + - bugfix: Borgs can't get perma stunned anymore by goliaths and slings and such + Fethas: + - rscadd: The floors are not safe! HONK! + Jazz23: + - rscadd: Added flasher buttons in perma brig as well as windoors in botany, the + wardens office, and cargo. Also added blast doors to transit tube. + - bugfix: HoP's flasher button not working, CE's secure shutter button and transit + tube lockdown button not working. + Kyep: + - rscadd: The admin verb to list SSD players now highlights players who are another + player's antag target. Additionally it lets you despawn players whose body is + already in cryo. + - bugfix: Fixed a bug which caused banning to fail in rare situations. + Mitchs98: + - bugfix: You can no longer rip the hood part of a hoodie off of someone's head. + - bugfix: Bee Costume and Monk Robe icons now show up properly in your inventory. + Triiodine: + - bugfix: Hotfixes taser projectiles being borked due to X-Ray re-work. + tigercat2000: + - rscadd: SPEEEEEEEED to the asset cache, making preloaded UI assets transfer much + faster. + - bugfix: NTTC deserializing works again + - bugfix: NTTC regex works again + - bugfix: NTTC no longer spams admins + - spellcheck: NTSL2 no more, it is officially NTTC + - rscadd: NanoUI's fancy mode is hot shit again! + - bugfix: NanoUI's fancy mode is no longer broken as hell! + - bugfix: 512 support for Nano dev tools diff --git a/html/nttc/.gitignore b/html/nttc/.gitignore new file mode 100644 index 00000000000..c2658d7d1b3 --- /dev/null +++ b/html/nttc/.gitignore @@ -0,0 +1 @@ +node_modules/ diff --git a/html/nttc/dist/bundle.css b/html/nttc/dist/bundle.css new file mode 100644 index 00000000000..293fb16a941 --- /dev/null +++ b/html/nttc/dist/bundle.css @@ -0,0 +1,154 @@ +/* Global */ +html, body { + background-color: #272727; + font-family: Verdana, Geneva, sans-serif; + font-size: 12px; + color: #fff; + margin: 0; + padding: 0; +} + +/* Navbar */ +#navbar { + background: #383838; + border-bottom: 2px solid #161616; + list-style-type: none; + height: 28px; + margin: 0; + padding: 0; +} + +#navbar > div { + background: #40628a; + border-radius: 5px 5px 0 0; + color: #ffffff; + display: block; + height: 80%; + float: left; + text-decoration: none; + padding: 0 7px 0 5px; + margin: 6px 0 0 5px; +} + +#navbar > div:hover { + background: #ffffff; + color: #40628a; + cursor: pointer; +} + +#navbar > img { + float: left; + margin: 2px 10px 2px 0; + height: 24px; +} + +#navbar > .title { + color: #a7a7a7; + float: right; + background: none; + font-size: 1.5em; + font-family: Helvetica; + text-decoration: bold; + padding: 0; + padding-right: 10px; + margin: 0; +} + +#navbar > .title:hover { + background: none; + color: #a7a7a7; + cursor: default; +} + +.btnActive { + background: #2f943c !important; + color: #fff !important; +} + +/* Content */ +#content { + min-height: 75%; + line-height: 1.5; + margin: 10px; +} + +/* Links */ +.link, .linkOn, .linkOff { + background: #40628a; + border: 1px solid #161616; + color: #ffffff; + cursor: pointer; + display: inline; + margin: 0 2px 0px 0; + min-width: 15px; + padding: 0px 4px 0px 4px; + text-align: center; + text-decoration: none; + user-select: none; + white-space: nowrap; +} + +.linkOn, .linkOn:link, .linkOn:visited, .linkOn:active, .linkOn:hover +{ + color: #ffffff; + background: #2f943c; + border-color: #24722e; +} + +.linkOff, .linkOff:link, .linkOff:visited, .linkOff:active, .linkOff:hover +{ + color: #ffffff; + background: #999999; + border-color: #666666; +} + +.linkActive:hover { + background: #507aac; +} + +.linkActive:active { + background: #2f943c; +} + +/* Config Tables */ +.tblConfig td { + padding-right: 40px; +} + +.tables { + border: 1px solid black; + text-align: center; +} + +.tables th { + border-bottom: 2px solid black; +} + +.tables th, .tables td { + border-right: 2px dotted black; + min-width: 70px; +} + +/* Footer */ +.footer { + height: 15px; + position: absolute; + right: 10px; + bottom: 10px; +} + +/* Hacking stuff. */ +.hack { + color: #fff; + text-shadow: 1px 1px #300; + font-size: 1.12em; +} +.hackBtn { + background-color: #a00 !important; +} +.hackBtn:hover { + background-color: #fff !important; +} +.hackBtn:hover .hack { + color: #000 !important; +} \ No newline at end of file diff --git a/html/nttc/dist/bundle.js b/html/nttc/dist/bundle.js new file mode 100644 index 00000000000..f91bf62551c --- /dev/null +++ b/html/nttc/dist/bundle.js @@ -0,0 +1,10907 @@ +(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i\u20D2|\u205F\u200A|\u219D\u0338|\u2202\u0338|\u2220\u20D2|\u2229\uFE00|\u222A\uFE00|\u223C\u20D2|\u223D\u0331|\u223E\u0333|\u2242\u0338|\u224B\u0338|\u224D\u20D2|\u224E\u0338|\u224F\u0338|\u2250\u0338|\u2261\u20E5|\u2264\u20D2|\u2265\u20D2|\u2266\u0338|\u2267\u0338|\u2268\uFE00|\u2269\uFE00|\u226A\u0338|\u226A\u20D2|\u226B\u0338|\u226B\u20D2|\u227F\u0338|\u2282\u20D2|\u2283\u20D2|\u228A\uFE00|\u228B\uFE00|\u228F\u0338|\u2290\u0338|\u2293\uFE00|\u2294\uFE00|\u22B4\u20D2|\u22B5\u20D2|\u22D8\u0338|\u22D9\u0338|\u22DA\uFE00|\u22DB\uFE00|\u22F5\u0338|\u22F9\u0338|\u2933\u0338|\u29CF\u0338|\u29D0\u0338|\u2A6D\u0338|\u2A70\u0338|\u2A7D\u0338|\u2A7E\u0338|\u2AA1\u0338|\u2AA2\u0338|\u2AAC\uFE00|\u2AAD\uFE00|\u2AAF\u0338|\u2AB0\u0338|\u2AC5\u0338|\u2AC6\u0338|\u2ACB\uFE00|\u2ACC\uFE00|\u2AFD\u20E5|[\xA0-\u0113\u0116-\u0122\u0124-\u012B\u012E-\u014D\u0150-\u017E\u0192\u01B5\u01F5\u0237\u02C6\u02C7\u02D8-\u02DD\u0311\u0391-\u03A1\u03A3-\u03A9\u03B1-\u03C9\u03D1\u03D2\u03D5\u03D6\u03DC\u03DD\u03F0\u03F1\u03F5\u03F6\u0401-\u040C\u040E-\u044F\u0451-\u045C\u045E\u045F\u2002-\u2005\u2007-\u2010\u2013-\u2016\u2018-\u201A\u201C-\u201E\u2020-\u2022\u2025\u2026\u2030-\u2035\u2039\u203A\u203E\u2041\u2043\u2044\u204F\u2057\u205F-\u2063\u20AC\u20DB\u20DC\u2102\u2105\u210A-\u2113\u2115-\u211E\u2122\u2124\u2127-\u2129\u212C\u212D\u212F-\u2131\u2133-\u2138\u2145-\u2148\u2153-\u215E\u2190-\u219B\u219D-\u21A7\u21A9-\u21AE\u21B0-\u21B3\u21B5-\u21B7\u21BA-\u21DB\u21DD\u21E4\u21E5\u21F5\u21FD-\u2205\u2207-\u2209\u220B\u220C\u220F-\u2214\u2216-\u2218\u221A\u221D-\u2238\u223A-\u2257\u2259\u225A\u225C\u225F-\u2262\u2264-\u228B\u228D-\u229B\u229D-\u22A5\u22A7-\u22B0\u22B2-\u22BB\u22BD-\u22DB\u22DE-\u22E3\u22E6-\u22F7\u22F9-\u22FE\u2305\u2306\u2308-\u2310\u2312\u2313\u2315\u2316\u231C-\u231F\u2322\u2323\u232D\u232E\u2336\u233D\u233F\u237C\u23B0\u23B1\u23B4-\u23B6\u23DC-\u23DF\u23E2\u23E7\u2423\u24C8\u2500\u2502\u250C\u2510\u2514\u2518\u251C\u2524\u252C\u2534\u253C\u2550-\u256C\u2580\u2584\u2588\u2591-\u2593\u25A1\u25AA\u25AB\u25AD\u25AE\u25B1\u25B3-\u25B5\u25B8\u25B9\u25BD-\u25BF\u25C2\u25C3\u25CA\u25CB\u25EC\u25EF\u25F8-\u25FC\u2605\u2606\u260E\u2640\u2642\u2660\u2663\u2665\u2666\u266A\u266D-\u266F\u2713\u2717\u2720\u2736\u2758\u2772\u2773\u27C8\u27C9\u27E6-\u27ED\u27F5-\u27FA\u27FC\u27FF\u2902-\u2905\u290C-\u2913\u2916\u2919-\u2920\u2923-\u292A\u2933\u2935-\u2939\u293C\u293D\u2945\u2948-\u294B\u294E-\u2976\u2978\u2979\u297B-\u297F\u2985\u2986\u298B-\u2996\u299A\u299C\u299D\u29A4-\u29B7\u29B9\u29BB\u29BC\u29BE-\u29C5\u29C9\u29CD-\u29D0\u29DC-\u29DE\u29E3-\u29E5\u29EB\u29F4\u29F6\u2A00-\u2A02\u2A04\u2A06\u2A0C\u2A0D\u2A10-\u2A17\u2A22-\u2A27\u2A29\u2A2A\u2A2D-\u2A31\u2A33-\u2A3C\u2A3F\u2A40\u2A42-\u2A4D\u2A50\u2A53-\u2A58\u2A5A-\u2A5D\u2A5F\u2A66\u2A6A\u2A6D-\u2A75\u2A77-\u2A9A\u2A9D-\u2AA2\u2AA4-\u2AB0\u2AB3-\u2AC8\u2ACB\u2ACC\u2ACF-\u2ADB\u2AE4\u2AE6-\u2AE9\u2AEB-\u2AF3\u2AFD\uFB00-\uFB04]|\uD835[\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDCCF\uDD04\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDD6B]/g; + var encodeMap = {'\xAD':'shy','\u200C':'zwnj','\u200D':'zwj','\u200E':'lrm','\u2063':'ic','\u2062':'it','\u2061':'af','\u200F':'rlm','\u200B':'ZeroWidthSpace','\u2060':'NoBreak','\u0311':'DownBreve','\u20DB':'tdot','\u20DC':'DotDot','\t':'Tab','\n':'NewLine','\u2008':'puncsp','\u205F':'MediumSpace','\u2009':'thinsp','\u200A':'hairsp','\u2004':'emsp13','\u2002':'ensp','\u2005':'emsp14','\u2003':'emsp','\u2007':'numsp','\xA0':'nbsp','\u205F\u200A':'ThickSpace','\u203E':'oline','_':'lowbar','\u2010':'dash','\u2013':'ndash','\u2014':'mdash','\u2015':'horbar',',':'comma',';':'semi','\u204F':'bsemi',':':'colon','\u2A74':'Colone','!':'excl','\xA1':'iexcl','?':'quest','\xBF':'iquest','.':'period','\u2025':'nldr','\u2026':'mldr','\xB7':'middot','\'':'apos','\u2018':'lsquo','\u2019':'rsquo','\u201A':'sbquo','\u2039':'lsaquo','\u203A':'rsaquo','"':'quot','\u201C':'ldquo','\u201D':'rdquo','\u201E':'bdquo','\xAB':'laquo','\xBB':'raquo','(':'lpar',')':'rpar','[':'lsqb',']':'rsqb','{':'lcub','}':'rcub','\u2308':'lceil','\u2309':'rceil','\u230A':'lfloor','\u230B':'rfloor','\u2985':'lopar','\u2986':'ropar','\u298B':'lbrke','\u298C':'rbrke','\u298D':'lbrkslu','\u298E':'rbrksld','\u298F':'lbrksld','\u2990':'rbrkslu','\u2991':'langd','\u2992':'rangd','\u2993':'lparlt','\u2994':'rpargt','\u2995':'gtlPar','\u2996':'ltrPar','\u27E6':'lobrk','\u27E7':'robrk','\u27E8':'lang','\u27E9':'rang','\u27EA':'Lang','\u27EB':'Rang','\u27EC':'loang','\u27ED':'roang','\u2772':'lbbrk','\u2773':'rbbrk','\u2016':'Vert','\xA7':'sect','\xB6':'para','@':'commat','*':'ast','/':'sol','undefined':null,'&':'amp','#':'num','%':'percnt','\u2030':'permil','\u2031':'pertenk','\u2020':'dagger','\u2021':'Dagger','\u2022':'bull','\u2043':'hybull','\u2032':'prime','\u2033':'Prime','\u2034':'tprime','\u2057':'qprime','\u2035':'bprime','\u2041':'caret','`':'grave','\xB4':'acute','\u02DC':'tilde','^':'Hat','\xAF':'macr','\u02D8':'breve','\u02D9':'dot','\xA8':'die','\u02DA':'ring','\u02DD':'dblac','\xB8':'cedil','\u02DB':'ogon','\u02C6':'circ','\u02C7':'caron','\xB0':'deg','\xA9':'copy','\xAE':'reg','\u2117':'copysr','\u2118':'wp','\u211E':'rx','\u2127':'mho','\u2129':'iiota','\u2190':'larr','\u219A':'nlarr','\u2192':'rarr','\u219B':'nrarr','\u2191':'uarr','\u2193':'darr','\u2194':'harr','\u21AE':'nharr','\u2195':'varr','\u2196':'nwarr','\u2197':'nearr','\u2198':'searr','\u2199':'swarr','\u219D':'rarrw','\u219D\u0338':'nrarrw','\u219E':'Larr','\u219F':'Uarr','\u21A0':'Rarr','\u21A1':'Darr','\u21A2':'larrtl','\u21A3':'rarrtl','\u21A4':'mapstoleft','\u21A5':'mapstoup','\u21A6':'map','\u21A7':'mapstodown','\u21A9':'larrhk','\u21AA':'rarrhk','\u21AB':'larrlp','\u21AC':'rarrlp','\u21AD':'harrw','\u21B0':'lsh','\u21B1':'rsh','\u21B2':'ldsh','\u21B3':'rdsh','\u21B5':'crarr','\u21B6':'cularr','\u21B7':'curarr','\u21BA':'olarr','\u21BB':'orarr','\u21BC':'lharu','\u21BD':'lhard','\u21BE':'uharr','\u21BF':'uharl','\u21C0':'rharu','\u21C1':'rhard','\u21C2':'dharr','\u21C3':'dharl','\u21C4':'rlarr','\u21C5':'udarr','\u21C6':'lrarr','\u21C7':'llarr','\u21C8':'uuarr','\u21C9':'rrarr','\u21CA':'ddarr','\u21CB':'lrhar','\u21CC':'rlhar','\u21D0':'lArr','\u21CD':'nlArr','\u21D1':'uArr','\u21D2':'rArr','\u21CF':'nrArr','\u21D3':'dArr','\u21D4':'iff','\u21CE':'nhArr','\u21D5':'vArr','\u21D6':'nwArr','\u21D7':'neArr','\u21D8':'seArr','\u21D9':'swArr','\u21DA':'lAarr','\u21DB':'rAarr','\u21DD':'zigrarr','\u21E4':'larrb','\u21E5':'rarrb','\u21F5':'duarr','\u21FD':'loarr','\u21FE':'roarr','\u21FF':'hoarr','\u2200':'forall','\u2201':'comp','\u2202':'part','\u2202\u0338':'npart','\u2203':'exist','\u2204':'nexist','\u2205':'empty','\u2207':'Del','\u2208':'in','\u2209':'notin','\u220B':'ni','\u220C':'notni','\u03F6':'bepsi','\u220F':'prod','\u2210':'coprod','\u2211':'sum','+':'plus','\xB1':'pm','\xF7':'div','\xD7':'times','<':'lt','\u226E':'nlt','<\u20D2':'nvlt','=':'equals','\u2260':'ne','=\u20E5':'bne','\u2A75':'Equal','>':'gt','\u226F':'ngt','>\u20D2':'nvgt','\xAC':'not','|':'vert','\xA6':'brvbar','\u2212':'minus','\u2213':'mp','\u2214':'plusdo','\u2044':'frasl','\u2216':'setmn','\u2217':'lowast','\u2218':'compfn','\u221A':'Sqrt','\u221D':'prop','\u221E':'infin','\u221F':'angrt','\u2220':'ang','\u2220\u20D2':'nang','\u2221':'angmsd','\u2222':'angsph','\u2223':'mid','\u2224':'nmid','\u2225':'par','\u2226':'npar','\u2227':'and','\u2228':'or','\u2229':'cap','\u2229\uFE00':'caps','\u222A':'cup','\u222A\uFE00':'cups','\u222B':'int','\u222C':'Int','\u222D':'tint','\u2A0C':'qint','\u222E':'oint','\u222F':'Conint','\u2230':'Cconint','\u2231':'cwint','\u2232':'cwconint','\u2233':'awconint','\u2234':'there4','\u2235':'becaus','\u2236':'ratio','\u2237':'Colon','\u2238':'minusd','\u223A':'mDDot','\u223B':'homtht','\u223C':'sim','\u2241':'nsim','\u223C\u20D2':'nvsim','\u223D':'bsim','\u223D\u0331':'race','\u223E':'ac','\u223E\u0333':'acE','\u223F':'acd','\u2240':'wr','\u2242':'esim','\u2242\u0338':'nesim','\u2243':'sime','\u2244':'nsime','\u2245':'cong','\u2247':'ncong','\u2246':'simne','\u2248':'ap','\u2249':'nap','\u224A':'ape','\u224B':'apid','\u224B\u0338':'napid','\u224C':'bcong','\u224D':'CupCap','\u226D':'NotCupCap','\u224D\u20D2':'nvap','\u224E':'bump','\u224E\u0338':'nbump','\u224F':'bumpe','\u224F\u0338':'nbumpe','\u2250':'doteq','\u2250\u0338':'nedot','\u2251':'eDot','\u2252':'efDot','\u2253':'erDot','\u2254':'colone','\u2255':'ecolon','\u2256':'ecir','\u2257':'cire','\u2259':'wedgeq','\u225A':'veeeq','\u225C':'trie','\u225F':'equest','\u2261':'equiv','\u2262':'nequiv','\u2261\u20E5':'bnequiv','\u2264':'le','\u2270':'nle','\u2264\u20D2':'nvle','\u2265':'ge','\u2271':'nge','\u2265\u20D2':'nvge','\u2266':'lE','\u2266\u0338':'nlE','\u2267':'gE','\u2267\u0338':'ngE','\u2268\uFE00':'lvnE','\u2268':'lnE','\u2269':'gnE','\u2269\uFE00':'gvnE','\u226A':'ll','\u226A\u0338':'nLtv','\u226A\u20D2':'nLt','\u226B':'gg','\u226B\u0338':'nGtv','\u226B\u20D2':'nGt','\u226C':'twixt','\u2272':'lsim','\u2274':'nlsim','\u2273':'gsim','\u2275':'ngsim','\u2276':'lg','\u2278':'ntlg','\u2277':'gl','\u2279':'ntgl','\u227A':'pr','\u2280':'npr','\u227B':'sc','\u2281':'nsc','\u227C':'prcue','\u22E0':'nprcue','\u227D':'sccue','\u22E1':'nsccue','\u227E':'prsim','\u227F':'scsim','\u227F\u0338':'NotSucceedsTilde','\u2282':'sub','\u2284':'nsub','\u2282\u20D2':'vnsub','\u2283':'sup','\u2285':'nsup','\u2283\u20D2':'vnsup','\u2286':'sube','\u2288':'nsube','\u2287':'supe','\u2289':'nsupe','\u228A\uFE00':'vsubne','\u228A':'subne','\u228B\uFE00':'vsupne','\u228B':'supne','\u228D':'cupdot','\u228E':'uplus','\u228F':'sqsub','\u228F\u0338':'NotSquareSubset','\u2290':'sqsup','\u2290\u0338':'NotSquareSuperset','\u2291':'sqsube','\u22E2':'nsqsube','\u2292':'sqsupe','\u22E3':'nsqsupe','\u2293':'sqcap','\u2293\uFE00':'sqcaps','\u2294':'sqcup','\u2294\uFE00':'sqcups','\u2295':'oplus','\u2296':'ominus','\u2297':'otimes','\u2298':'osol','\u2299':'odot','\u229A':'ocir','\u229B':'oast','\u229D':'odash','\u229E':'plusb','\u229F':'minusb','\u22A0':'timesb','\u22A1':'sdotb','\u22A2':'vdash','\u22AC':'nvdash','\u22A3':'dashv','\u22A4':'top','\u22A5':'bot','\u22A7':'models','\u22A8':'vDash','\u22AD':'nvDash','\u22A9':'Vdash','\u22AE':'nVdash','\u22AA':'Vvdash','\u22AB':'VDash','\u22AF':'nVDash','\u22B0':'prurel','\u22B2':'vltri','\u22EA':'nltri','\u22B3':'vrtri','\u22EB':'nrtri','\u22B4':'ltrie','\u22EC':'nltrie','\u22B4\u20D2':'nvltrie','\u22B5':'rtrie','\u22ED':'nrtrie','\u22B5\u20D2':'nvrtrie','\u22B6':'origof','\u22B7':'imof','\u22B8':'mumap','\u22B9':'hercon','\u22BA':'intcal','\u22BB':'veebar','\u22BD':'barvee','\u22BE':'angrtvb','\u22BF':'lrtri','\u22C0':'Wedge','\u22C1':'Vee','\u22C2':'xcap','\u22C3':'xcup','\u22C4':'diam','\u22C5':'sdot','\u22C6':'Star','\u22C7':'divonx','\u22C8':'bowtie','\u22C9':'ltimes','\u22CA':'rtimes','\u22CB':'lthree','\u22CC':'rthree','\u22CD':'bsime','\u22CE':'cuvee','\u22CF':'cuwed','\u22D0':'Sub','\u22D1':'Sup','\u22D2':'Cap','\u22D3':'Cup','\u22D4':'fork','\u22D5':'epar','\u22D6':'ltdot','\u22D7':'gtdot','\u22D8':'Ll','\u22D8\u0338':'nLl','\u22D9':'Gg','\u22D9\u0338':'nGg','\u22DA\uFE00':'lesg','\u22DA':'leg','\u22DB':'gel','\u22DB\uFE00':'gesl','\u22DE':'cuepr','\u22DF':'cuesc','\u22E6':'lnsim','\u22E7':'gnsim','\u22E8':'prnsim','\u22E9':'scnsim','\u22EE':'vellip','\u22EF':'ctdot','\u22F0':'utdot','\u22F1':'dtdot','\u22F2':'disin','\u22F3':'isinsv','\u22F4':'isins','\u22F5':'isindot','\u22F5\u0338':'notindot','\u22F6':'notinvc','\u22F7':'notinvb','\u22F9':'isinE','\u22F9\u0338':'notinE','\u22FA':'nisd','\u22FB':'xnis','\u22FC':'nis','\u22FD':'notnivc','\u22FE':'notnivb','\u2305':'barwed','\u2306':'Barwed','\u230C':'drcrop','\u230D':'dlcrop','\u230E':'urcrop','\u230F':'ulcrop','\u2310':'bnot','\u2312':'profline','\u2313':'profsurf','\u2315':'telrec','\u2316':'target','\u231C':'ulcorn','\u231D':'urcorn','\u231E':'dlcorn','\u231F':'drcorn','\u2322':'frown','\u2323':'smile','\u232D':'cylcty','\u232E':'profalar','\u2336':'topbot','\u233D':'ovbar','\u233F':'solbar','\u237C':'angzarr','\u23B0':'lmoust','\u23B1':'rmoust','\u23B4':'tbrk','\u23B5':'bbrk','\u23B6':'bbrktbrk','\u23DC':'OverParenthesis','\u23DD':'UnderParenthesis','\u23DE':'OverBrace','\u23DF':'UnderBrace','\u23E2':'trpezium','\u23E7':'elinters','\u2423':'blank','\u2500':'boxh','\u2502':'boxv','\u250C':'boxdr','\u2510':'boxdl','\u2514':'boxur','\u2518':'boxul','\u251C':'boxvr','\u2524':'boxvl','\u252C':'boxhd','\u2534':'boxhu','\u253C':'boxvh','\u2550':'boxH','\u2551':'boxV','\u2552':'boxdR','\u2553':'boxDr','\u2554':'boxDR','\u2555':'boxdL','\u2556':'boxDl','\u2557':'boxDL','\u2558':'boxuR','\u2559':'boxUr','\u255A':'boxUR','\u255B':'boxuL','\u255C':'boxUl','\u255D':'boxUL','\u255E':'boxvR','\u255F':'boxVr','\u2560':'boxVR','\u2561':'boxvL','\u2562':'boxVl','\u2563':'boxVL','\u2564':'boxHd','\u2565':'boxhD','\u2566':'boxHD','\u2567':'boxHu','\u2568':'boxhU','\u2569':'boxHU','\u256A':'boxvH','\u256B':'boxVh','\u256C':'boxVH','\u2580':'uhblk','\u2584':'lhblk','\u2588':'block','\u2591':'blk14','\u2592':'blk12','\u2593':'blk34','\u25A1':'squ','\u25AA':'squf','\u25AB':'EmptyVerySmallSquare','\u25AD':'rect','\u25AE':'marker','\u25B1':'fltns','\u25B3':'xutri','\u25B4':'utrif','\u25B5':'utri','\u25B8':'rtrif','\u25B9':'rtri','\u25BD':'xdtri','\u25BE':'dtrif','\u25BF':'dtri','\u25C2':'ltrif','\u25C3':'ltri','\u25CA':'loz','\u25CB':'cir','\u25EC':'tridot','\u25EF':'xcirc','\u25F8':'ultri','\u25F9':'urtri','\u25FA':'lltri','\u25FB':'EmptySmallSquare','\u25FC':'FilledSmallSquare','\u2605':'starf','\u2606':'star','\u260E':'phone','\u2640':'female','\u2642':'male','\u2660':'spades','\u2663':'clubs','\u2665':'hearts','\u2666':'diams','\u266A':'sung','\u2713':'check','\u2717':'cross','\u2720':'malt','\u2736':'sext','\u2758':'VerticalSeparator','\u27C8':'bsolhsub','\u27C9':'suphsol','\u27F5':'xlarr','\u27F6':'xrarr','\u27F7':'xharr','\u27F8':'xlArr','\u27F9':'xrArr','\u27FA':'xhArr','\u27FC':'xmap','\u27FF':'dzigrarr','\u2902':'nvlArr','\u2903':'nvrArr','\u2904':'nvHarr','\u2905':'Map','\u290C':'lbarr','\u290D':'rbarr','\u290E':'lBarr','\u290F':'rBarr','\u2910':'RBarr','\u2911':'DDotrahd','\u2912':'UpArrowBar','\u2913':'DownArrowBar','\u2916':'Rarrtl','\u2919':'latail','\u291A':'ratail','\u291B':'lAtail','\u291C':'rAtail','\u291D':'larrfs','\u291E':'rarrfs','\u291F':'larrbfs','\u2920':'rarrbfs','\u2923':'nwarhk','\u2924':'nearhk','\u2925':'searhk','\u2926':'swarhk','\u2927':'nwnear','\u2928':'toea','\u2929':'tosa','\u292A':'swnwar','\u2933':'rarrc','\u2933\u0338':'nrarrc','\u2935':'cudarrr','\u2936':'ldca','\u2937':'rdca','\u2938':'cudarrl','\u2939':'larrpl','\u293C':'curarrm','\u293D':'cularrp','\u2945':'rarrpl','\u2948':'harrcir','\u2949':'Uarrocir','\u294A':'lurdshar','\u294B':'ldrushar','\u294E':'LeftRightVector','\u294F':'RightUpDownVector','\u2950':'DownLeftRightVector','\u2951':'LeftUpDownVector','\u2952':'LeftVectorBar','\u2953':'RightVectorBar','\u2954':'RightUpVectorBar','\u2955':'RightDownVectorBar','\u2956':'DownLeftVectorBar','\u2957':'DownRightVectorBar','\u2958':'LeftUpVectorBar','\u2959':'LeftDownVectorBar','\u295A':'LeftTeeVector','\u295B':'RightTeeVector','\u295C':'RightUpTeeVector','\u295D':'RightDownTeeVector','\u295E':'DownLeftTeeVector','\u295F':'DownRightTeeVector','\u2960':'LeftUpTeeVector','\u2961':'LeftDownTeeVector','\u2962':'lHar','\u2963':'uHar','\u2964':'rHar','\u2965':'dHar','\u2966':'luruhar','\u2967':'ldrdhar','\u2968':'ruluhar','\u2969':'rdldhar','\u296A':'lharul','\u296B':'llhard','\u296C':'rharul','\u296D':'lrhard','\u296E':'udhar','\u296F':'duhar','\u2970':'RoundImplies','\u2971':'erarr','\u2972':'simrarr','\u2973':'larrsim','\u2974':'rarrsim','\u2975':'rarrap','\u2976':'ltlarr','\u2978':'gtrarr','\u2979':'subrarr','\u297B':'suplarr','\u297C':'lfisht','\u297D':'rfisht','\u297E':'ufisht','\u297F':'dfisht','\u299A':'vzigzag','\u299C':'vangrt','\u299D':'angrtvbd','\u29A4':'ange','\u29A5':'range','\u29A6':'dwangle','\u29A7':'uwangle','\u29A8':'angmsdaa','\u29A9':'angmsdab','\u29AA':'angmsdac','\u29AB':'angmsdad','\u29AC':'angmsdae','\u29AD':'angmsdaf','\u29AE':'angmsdag','\u29AF':'angmsdah','\u29B0':'bemptyv','\u29B1':'demptyv','\u29B2':'cemptyv','\u29B3':'raemptyv','\u29B4':'laemptyv','\u29B5':'ohbar','\u29B6':'omid','\u29B7':'opar','\u29B9':'operp','\u29BB':'olcross','\u29BC':'odsold','\u29BE':'olcir','\u29BF':'ofcir','\u29C0':'olt','\u29C1':'ogt','\u29C2':'cirscir','\u29C3':'cirE','\u29C4':'solb','\u29C5':'bsolb','\u29C9':'boxbox','\u29CD':'trisb','\u29CE':'rtriltri','\u29CF':'LeftTriangleBar','\u29CF\u0338':'NotLeftTriangleBar','\u29D0':'RightTriangleBar','\u29D0\u0338':'NotRightTriangleBar','\u29DC':'iinfin','\u29DD':'infintie','\u29DE':'nvinfin','\u29E3':'eparsl','\u29E4':'smeparsl','\u29E5':'eqvparsl','\u29EB':'lozf','\u29F4':'RuleDelayed','\u29F6':'dsol','\u2A00':'xodot','\u2A01':'xoplus','\u2A02':'xotime','\u2A04':'xuplus','\u2A06':'xsqcup','\u2A0D':'fpartint','\u2A10':'cirfnint','\u2A11':'awint','\u2A12':'rppolint','\u2A13':'scpolint','\u2A14':'npolint','\u2A15':'pointint','\u2A16':'quatint','\u2A17':'intlarhk','\u2A22':'pluscir','\u2A23':'plusacir','\u2A24':'simplus','\u2A25':'plusdu','\u2A26':'plussim','\u2A27':'plustwo','\u2A29':'mcomma','\u2A2A':'minusdu','\u2A2D':'loplus','\u2A2E':'roplus','\u2A2F':'Cross','\u2A30':'timesd','\u2A31':'timesbar','\u2A33':'smashp','\u2A34':'lotimes','\u2A35':'rotimes','\u2A36':'otimesas','\u2A37':'Otimes','\u2A38':'odiv','\u2A39':'triplus','\u2A3A':'triminus','\u2A3B':'tritime','\u2A3C':'iprod','\u2A3F':'amalg','\u2A40':'capdot','\u2A42':'ncup','\u2A43':'ncap','\u2A44':'capand','\u2A45':'cupor','\u2A46':'cupcap','\u2A47':'capcup','\u2A48':'cupbrcap','\u2A49':'capbrcup','\u2A4A':'cupcup','\u2A4B':'capcap','\u2A4C':'ccups','\u2A4D':'ccaps','\u2A50':'ccupssm','\u2A53':'And','\u2A54':'Or','\u2A55':'andand','\u2A56':'oror','\u2A57':'orslope','\u2A58':'andslope','\u2A5A':'andv','\u2A5B':'orv','\u2A5C':'andd','\u2A5D':'ord','\u2A5F':'wedbar','\u2A66':'sdote','\u2A6A':'simdot','\u2A6D':'congdot','\u2A6D\u0338':'ncongdot','\u2A6E':'easter','\u2A6F':'apacir','\u2A70':'apE','\u2A70\u0338':'napE','\u2A71':'eplus','\u2A72':'pluse','\u2A73':'Esim','\u2A77':'eDDot','\u2A78':'equivDD','\u2A79':'ltcir','\u2A7A':'gtcir','\u2A7B':'ltquest','\u2A7C':'gtquest','\u2A7D':'les','\u2A7D\u0338':'nles','\u2A7E':'ges','\u2A7E\u0338':'nges','\u2A7F':'lesdot','\u2A80':'gesdot','\u2A81':'lesdoto','\u2A82':'gesdoto','\u2A83':'lesdotor','\u2A84':'gesdotol','\u2A85':'lap','\u2A86':'gap','\u2A87':'lne','\u2A88':'gne','\u2A89':'lnap','\u2A8A':'gnap','\u2A8B':'lEg','\u2A8C':'gEl','\u2A8D':'lsime','\u2A8E':'gsime','\u2A8F':'lsimg','\u2A90':'gsiml','\u2A91':'lgE','\u2A92':'glE','\u2A93':'lesges','\u2A94':'gesles','\u2A95':'els','\u2A96':'egs','\u2A97':'elsdot','\u2A98':'egsdot','\u2A99':'el','\u2A9A':'eg','\u2A9D':'siml','\u2A9E':'simg','\u2A9F':'simlE','\u2AA0':'simgE','\u2AA1':'LessLess','\u2AA1\u0338':'NotNestedLessLess','\u2AA2':'GreaterGreater','\u2AA2\u0338':'NotNestedGreaterGreater','\u2AA4':'glj','\u2AA5':'gla','\u2AA6':'ltcc','\u2AA7':'gtcc','\u2AA8':'lescc','\u2AA9':'gescc','\u2AAA':'smt','\u2AAB':'lat','\u2AAC':'smte','\u2AAC\uFE00':'smtes','\u2AAD':'late','\u2AAD\uFE00':'lates','\u2AAE':'bumpE','\u2AAF':'pre','\u2AAF\u0338':'npre','\u2AB0':'sce','\u2AB0\u0338':'nsce','\u2AB3':'prE','\u2AB4':'scE','\u2AB5':'prnE','\u2AB6':'scnE','\u2AB7':'prap','\u2AB8':'scap','\u2AB9':'prnap','\u2ABA':'scnap','\u2ABB':'Pr','\u2ABC':'Sc','\u2ABD':'subdot','\u2ABE':'supdot','\u2ABF':'subplus','\u2AC0':'supplus','\u2AC1':'submult','\u2AC2':'supmult','\u2AC3':'subedot','\u2AC4':'supedot','\u2AC5':'subE','\u2AC5\u0338':'nsubE','\u2AC6':'supE','\u2AC6\u0338':'nsupE','\u2AC7':'subsim','\u2AC8':'supsim','\u2ACB\uFE00':'vsubnE','\u2ACB':'subnE','\u2ACC\uFE00':'vsupnE','\u2ACC':'supnE','\u2ACF':'csub','\u2AD0':'csup','\u2AD1':'csube','\u2AD2':'csupe','\u2AD3':'subsup','\u2AD4':'supsub','\u2AD5':'subsub','\u2AD6':'supsup','\u2AD7':'suphsub','\u2AD8':'supdsub','\u2AD9':'forkv','\u2ADA':'topfork','\u2ADB':'mlcp','\u2AE4':'Dashv','\u2AE6':'Vdashl','\u2AE7':'Barv','\u2AE8':'vBar','\u2AE9':'vBarv','\u2AEB':'Vbar','\u2AEC':'Not','\u2AED':'bNot','\u2AEE':'rnmid','\u2AEF':'cirmid','\u2AF0':'midcir','\u2AF1':'topcir','\u2AF2':'nhpar','\u2AF3':'parsim','\u2AFD':'parsl','\u2AFD\u20E5':'nparsl','\u266D':'flat','\u266E':'natur','\u266F':'sharp','\xA4':'curren','\xA2':'cent','$':'dollar','\xA3':'pound','\xA5':'yen','\u20AC':'euro','\xB9':'sup1','\xBD':'half','\u2153':'frac13','\xBC':'frac14','\u2155':'frac15','\u2159':'frac16','\u215B':'frac18','\xB2':'sup2','\u2154':'frac23','\u2156':'frac25','\xB3':'sup3','\xBE':'frac34','\u2157':'frac35','\u215C':'frac38','\u2158':'frac45','\u215A':'frac56','\u215D':'frac58','\u215E':'frac78','\uD835\uDCB6':'ascr','\uD835\uDD52':'aopf','\uD835\uDD1E':'afr','\uD835\uDD38':'Aopf','\uD835\uDD04':'Afr','\uD835\uDC9C':'Ascr','\xAA':'ordf','\xE1':'aacute','\xC1':'Aacute','\xE0':'agrave','\xC0':'Agrave','\u0103':'abreve','\u0102':'Abreve','\xE2':'acirc','\xC2':'Acirc','\xE5':'aring','\xC5':'angst','\xE4':'auml','\xC4':'Auml','\xE3':'atilde','\xC3':'Atilde','\u0105':'aogon','\u0104':'Aogon','\u0101':'amacr','\u0100':'Amacr','\xE6':'aelig','\xC6':'AElig','\uD835\uDCB7':'bscr','\uD835\uDD53':'bopf','\uD835\uDD1F':'bfr','\uD835\uDD39':'Bopf','\u212C':'Bscr','\uD835\uDD05':'Bfr','\uD835\uDD20':'cfr','\uD835\uDCB8':'cscr','\uD835\uDD54':'copf','\u212D':'Cfr','\uD835\uDC9E':'Cscr','\u2102':'Copf','\u0107':'cacute','\u0106':'Cacute','\u0109':'ccirc','\u0108':'Ccirc','\u010D':'ccaron','\u010C':'Ccaron','\u010B':'cdot','\u010A':'Cdot','\xE7':'ccedil','\xC7':'Ccedil','\u2105':'incare','\uD835\uDD21':'dfr','\u2146':'dd','\uD835\uDD55':'dopf','\uD835\uDCB9':'dscr','\uD835\uDC9F':'Dscr','\uD835\uDD07':'Dfr','\u2145':'DD','\uD835\uDD3B':'Dopf','\u010F':'dcaron','\u010E':'Dcaron','\u0111':'dstrok','\u0110':'Dstrok','\xF0':'eth','\xD0':'ETH','\u2147':'ee','\u212F':'escr','\uD835\uDD22':'efr','\uD835\uDD56':'eopf','\u2130':'Escr','\uD835\uDD08':'Efr','\uD835\uDD3C':'Eopf','\xE9':'eacute','\xC9':'Eacute','\xE8':'egrave','\xC8':'Egrave','\xEA':'ecirc','\xCA':'Ecirc','\u011B':'ecaron','\u011A':'Ecaron','\xEB':'euml','\xCB':'Euml','\u0117':'edot','\u0116':'Edot','\u0119':'eogon','\u0118':'Eogon','\u0113':'emacr','\u0112':'Emacr','\uD835\uDD23':'ffr','\uD835\uDD57':'fopf','\uD835\uDCBB':'fscr','\uD835\uDD09':'Ffr','\uD835\uDD3D':'Fopf','\u2131':'Fscr','\uFB00':'fflig','\uFB03':'ffilig','\uFB04':'ffllig','\uFB01':'filig','fj':'fjlig','\uFB02':'fllig','\u0192':'fnof','\u210A':'gscr','\uD835\uDD58':'gopf','\uD835\uDD24':'gfr','\uD835\uDCA2':'Gscr','\uD835\uDD3E':'Gopf','\uD835\uDD0A':'Gfr','\u01F5':'gacute','\u011F':'gbreve','\u011E':'Gbreve','\u011D':'gcirc','\u011C':'Gcirc','\u0121':'gdot','\u0120':'Gdot','\u0122':'Gcedil','\uD835\uDD25':'hfr','\u210E':'planckh','\uD835\uDCBD':'hscr','\uD835\uDD59':'hopf','\u210B':'Hscr','\u210C':'Hfr','\u210D':'Hopf','\u0125':'hcirc','\u0124':'Hcirc','\u210F':'hbar','\u0127':'hstrok','\u0126':'Hstrok','\uD835\uDD5A':'iopf','\uD835\uDD26':'ifr','\uD835\uDCBE':'iscr','\u2148':'ii','\uD835\uDD40':'Iopf','\u2110':'Iscr','\u2111':'Im','\xED':'iacute','\xCD':'Iacute','\xEC':'igrave','\xCC':'Igrave','\xEE':'icirc','\xCE':'Icirc','\xEF':'iuml','\xCF':'Iuml','\u0129':'itilde','\u0128':'Itilde','\u0130':'Idot','\u012F':'iogon','\u012E':'Iogon','\u012B':'imacr','\u012A':'Imacr','\u0133':'ijlig','\u0132':'IJlig','\u0131':'imath','\uD835\uDCBF':'jscr','\uD835\uDD5B':'jopf','\uD835\uDD27':'jfr','\uD835\uDCA5':'Jscr','\uD835\uDD0D':'Jfr','\uD835\uDD41':'Jopf','\u0135':'jcirc','\u0134':'Jcirc','\u0237':'jmath','\uD835\uDD5C':'kopf','\uD835\uDCC0':'kscr','\uD835\uDD28':'kfr','\uD835\uDCA6':'Kscr','\uD835\uDD42':'Kopf','\uD835\uDD0E':'Kfr','\u0137':'kcedil','\u0136':'Kcedil','\uD835\uDD29':'lfr','\uD835\uDCC1':'lscr','\u2113':'ell','\uD835\uDD5D':'lopf','\u2112':'Lscr','\uD835\uDD0F':'Lfr','\uD835\uDD43':'Lopf','\u013A':'lacute','\u0139':'Lacute','\u013E':'lcaron','\u013D':'Lcaron','\u013C':'lcedil','\u013B':'Lcedil','\u0142':'lstrok','\u0141':'Lstrok','\u0140':'lmidot','\u013F':'Lmidot','\uD835\uDD2A':'mfr','\uD835\uDD5E':'mopf','\uD835\uDCC2':'mscr','\uD835\uDD10':'Mfr','\uD835\uDD44':'Mopf','\u2133':'Mscr','\uD835\uDD2B':'nfr','\uD835\uDD5F':'nopf','\uD835\uDCC3':'nscr','\u2115':'Nopf','\uD835\uDCA9':'Nscr','\uD835\uDD11':'Nfr','\u0144':'nacute','\u0143':'Nacute','\u0148':'ncaron','\u0147':'Ncaron','\xF1':'ntilde','\xD1':'Ntilde','\u0146':'ncedil','\u0145':'Ncedil','\u2116':'numero','\u014B':'eng','\u014A':'ENG','\uD835\uDD60':'oopf','\uD835\uDD2C':'ofr','\u2134':'oscr','\uD835\uDCAA':'Oscr','\uD835\uDD12':'Ofr','\uD835\uDD46':'Oopf','\xBA':'ordm','\xF3':'oacute','\xD3':'Oacute','\xF2':'ograve','\xD2':'Ograve','\xF4':'ocirc','\xD4':'Ocirc','\xF6':'ouml','\xD6':'Ouml','\u0151':'odblac','\u0150':'Odblac','\xF5':'otilde','\xD5':'Otilde','\xF8':'oslash','\xD8':'Oslash','\u014D':'omacr','\u014C':'Omacr','\u0153':'oelig','\u0152':'OElig','\uD835\uDD2D':'pfr','\uD835\uDCC5':'pscr','\uD835\uDD61':'popf','\u2119':'Popf','\uD835\uDD13':'Pfr','\uD835\uDCAB':'Pscr','\uD835\uDD62':'qopf','\uD835\uDD2E':'qfr','\uD835\uDCC6':'qscr','\uD835\uDCAC':'Qscr','\uD835\uDD14':'Qfr','\u211A':'Qopf','\u0138':'kgreen','\uD835\uDD2F':'rfr','\uD835\uDD63':'ropf','\uD835\uDCC7':'rscr','\u211B':'Rscr','\u211C':'Re','\u211D':'Ropf','\u0155':'racute','\u0154':'Racute','\u0159':'rcaron','\u0158':'Rcaron','\u0157':'rcedil','\u0156':'Rcedil','\uD835\uDD64':'sopf','\uD835\uDCC8':'sscr','\uD835\uDD30':'sfr','\uD835\uDD4A':'Sopf','\uD835\uDD16':'Sfr','\uD835\uDCAE':'Sscr','\u24C8':'oS','\u015B':'sacute','\u015A':'Sacute','\u015D':'scirc','\u015C':'Scirc','\u0161':'scaron','\u0160':'Scaron','\u015F':'scedil','\u015E':'Scedil','\xDF':'szlig','\uD835\uDD31':'tfr','\uD835\uDCC9':'tscr','\uD835\uDD65':'topf','\uD835\uDCAF':'Tscr','\uD835\uDD17':'Tfr','\uD835\uDD4B':'Topf','\u0165':'tcaron','\u0164':'Tcaron','\u0163':'tcedil','\u0162':'Tcedil','\u2122':'trade','\u0167':'tstrok','\u0166':'Tstrok','\uD835\uDCCA':'uscr','\uD835\uDD66':'uopf','\uD835\uDD32':'ufr','\uD835\uDD4C':'Uopf','\uD835\uDD18':'Ufr','\uD835\uDCB0':'Uscr','\xFA':'uacute','\xDA':'Uacute','\xF9':'ugrave','\xD9':'Ugrave','\u016D':'ubreve','\u016C':'Ubreve','\xFB':'ucirc','\xDB':'Ucirc','\u016F':'uring','\u016E':'Uring','\xFC':'uuml','\xDC':'Uuml','\u0171':'udblac','\u0170':'Udblac','\u0169':'utilde','\u0168':'Utilde','\u0173':'uogon','\u0172':'Uogon','\u016B':'umacr','\u016A':'Umacr','\uD835\uDD33':'vfr','\uD835\uDD67':'vopf','\uD835\uDCCB':'vscr','\uD835\uDD19':'Vfr','\uD835\uDD4D':'Vopf','\uD835\uDCB1':'Vscr','\uD835\uDD68':'wopf','\uD835\uDCCC':'wscr','\uD835\uDD34':'wfr','\uD835\uDCB2':'Wscr','\uD835\uDD4E':'Wopf','\uD835\uDD1A':'Wfr','\u0175':'wcirc','\u0174':'Wcirc','\uD835\uDD35':'xfr','\uD835\uDCCD':'xscr','\uD835\uDD69':'xopf','\uD835\uDD4F':'Xopf','\uD835\uDD1B':'Xfr','\uD835\uDCB3':'Xscr','\uD835\uDD36':'yfr','\uD835\uDCCE':'yscr','\uD835\uDD6A':'yopf','\uD835\uDCB4':'Yscr','\uD835\uDD1C':'Yfr','\uD835\uDD50':'Yopf','\xFD':'yacute','\xDD':'Yacute','\u0177':'ycirc','\u0176':'Ycirc','\xFF':'yuml','\u0178':'Yuml','\uD835\uDCCF':'zscr','\uD835\uDD37':'zfr','\uD835\uDD6B':'zopf','\u2128':'Zfr','\u2124':'Zopf','\uD835\uDCB5':'Zscr','\u017A':'zacute','\u0179':'Zacute','\u017E':'zcaron','\u017D':'Zcaron','\u017C':'zdot','\u017B':'Zdot','\u01B5':'imped','\xFE':'thorn','\xDE':'THORN','\u0149':'napos','\u03B1':'alpha','\u0391':'Alpha','\u03B2':'beta','\u0392':'Beta','\u03B3':'gamma','\u0393':'Gamma','\u03B4':'delta','\u0394':'Delta','\u03B5':'epsi','\u03F5':'epsiv','\u0395':'Epsilon','\u03DD':'gammad','\u03DC':'Gammad','\u03B6':'zeta','\u0396':'Zeta','\u03B7':'eta','\u0397':'Eta','\u03B8':'theta','\u03D1':'thetav','\u0398':'Theta','\u03B9':'iota','\u0399':'Iota','\u03BA':'kappa','\u03F0':'kappav','\u039A':'Kappa','\u03BB':'lambda','\u039B':'Lambda','\u03BC':'mu','\xB5':'micro','\u039C':'Mu','\u03BD':'nu','\u039D':'Nu','\u03BE':'xi','\u039E':'Xi','\u03BF':'omicron','\u039F':'Omicron','\u03C0':'pi','\u03D6':'piv','\u03A0':'Pi','\u03C1':'rho','\u03F1':'rhov','\u03A1':'Rho','\u03C3':'sigma','\u03A3':'Sigma','\u03C2':'sigmaf','\u03C4':'tau','\u03A4':'Tau','\u03C5':'upsi','\u03A5':'Upsilon','\u03D2':'Upsi','\u03C6':'phi','\u03D5':'phiv','\u03A6':'Phi','\u03C7':'chi','\u03A7':'Chi','\u03C8':'psi','\u03A8':'Psi','\u03C9':'omega','\u03A9':'ohm','\u0430':'acy','\u0410':'Acy','\u0431':'bcy','\u0411':'Bcy','\u0432':'vcy','\u0412':'Vcy','\u0433':'gcy','\u0413':'Gcy','\u0453':'gjcy','\u0403':'GJcy','\u0434':'dcy','\u0414':'Dcy','\u0452':'djcy','\u0402':'DJcy','\u0435':'iecy','\u0415':'IEcy','\u0451':'iocy','\u0401':'IOcy','\u0454':'jukcy','\u0404':'Jukcy','\u0436':'zhcy','\u0416':'ZHcy','\u0437':'zcy','\u0417':'Zcy','\u0455':'dscy','\u0405':'DScy','\u0438':'icy','\u0418':'Icy','\u0456':'iukcy','\u0406':'Iukcy','\u0457':'yicy','\u0407':'YIcy','\u0439':'jcy','\u0419':'Jcy','\u0458':'jsercy','\u0408':'Jsercy','\u043A':'kcy','\u041A':'Kcy','\u045C':'kjcy','\u040C':'KJcy','\u043B':'lcy','\u041B':'Lcy','\u0459':'ljcy','\u0409':'LJcy','\u043C':'mcy','\u041C':'Mcy','\u043D':'ncy','\u041D':'Ncy','\u045A':'njcy','\u040A':'NJcy','\u043E':'ocy','\u041E':'Ocy','\u043F':'pcy','\u041F':'Pcy','\u0440':'rcy','\u0420':'Rcy','\u0441':'scy','\u0421':'Scy','\u0442':'tcy','\u0422':'Tcy','\u045B':'tshcy','\u040B':'TSHcy','\u0443':'ucy','\u0423':'Ucy','\u045E':'ubrcy','\u040E':'Ubrcy','\u0444':'fcy','\u0424':'Fcy','\u0445':'khcy','\u0425':'KHcy','\u0446':'tscy','\u0426':'TScy','\u0447':'chcy','\u0427':'CHcy','\u045F':'dzcy','\u040F':'DZcy','\u0448':'shcy','\u0428':'SHcy','\u0449':'shchcy','\u0429':'SHCHcy','\u044A':'hardcy','\u042A':'HARDcy','\u044B':'ycy','\u042B':'Ycy','\u044C':'softcy','\u042C':'SOFTcy','\u044D':'ecy','\u042D':'Ecy','\u044E':'yucy','\u042E':'YUcy','\u044F':'yacy','\u042F':'YAcy','\u2135':'aleph','\u2136':'beth','\u2137':'gimel','\u2138':'daleth'}; + + var regexEscape = /["&'<>`]/g; + var escapeMap = { + '"': '"', + '&': '&', + '\'': ''', + '<': '<', + // See https://mathiasbynens.be/notes/ambiguous-ampersands: in HTML, the + // following is not strictly necessary unless it’s part of a tag or an + // unquoted attribute value. We’re only escaping it to support those + // situations, and for XML support. + '>': '>', + // In Internet Explorer ≤ 8, the backtick character can be used + // to break out of (un)quoted attribute values or HTML comments. + // See http://html5sec.org/#102, http://html5sec.org/#108, and + // http://html5sec.org/#133. + '`': '`' + }; + + var regexInvalidEntity = /&#(?:[xX][^a-fA-F0-9]|[^0-9xX])/; + var regexInvalidRawCodePoint = /[\0-\x08\x0B\x0E-\x1F\x7F-\x9F\uFDD0-\uFDEF\uFFFE\uFFFF]|[\uD83F\uD87F\uD8BF\uD8FF\uD93F\uD97F\uD9BF\uD9FF\uDA3F\uDA7F\uDABF\uDAFF\uDB3F\uDB7F\uDBBF\uDBFF][\uDFFE\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/; + var regexDecode = /&(CounterClockwiseContourIntegral|DoubleLongLeftRightArrow|ClockwiseContourIntegral|NotNestedGreaterGreater|NotSquareSupersetEqual|DiacriticalDoubleAcute|NotRightTriangleEqual|NotSucceedsSlantEqual|NotPrecedesSlantEqual|CloseCurlyDoubleQuote|NegativeVeryThinSpace|DoubleContourIntegral|FilledVerySmallSquare|CapitalDifferentialD|OpenCurlyDoubleQuote|EmptyVerySmallSquare|NestedGreaterGreater|DoubleLongRightArrow|NotLeftTriangleEqual|NotGreaterSlantEqual|ReverseUpEquilibrium|DoubleLeftRightArrow|NotSquareSubsetEqual|NotDoubleVerticalBar|RightArrowLeftArrow|NotGreaterFullEqual|NotRightTriangleBar|SquareSupersetEqual|DownLeftRightVector|DoubleLongLeftArrow|leftrightsquigarrow|LeftArrowRightArrow|NegativeMediumSpace|blacktriangleright|RightDownVectorBar|PrecedesSlantEqual|RightDoubleBracket|SucceedsSlantEqual|NotLeftTriangleBar|RightTriangleEqual|SquareIntersection|RightDownTeeVector|ReverseEquilibrium|NegativeThickSpace|longleftrightarrow|Longleftrightarrow|LongLeftRightArrow|DownRightTeeVector|DownRightVectorBar|GreaterSlantEqual|SquareSubsetEqual|LeftDownVectorBar|LeftDoubleBracket|VerticalSeparator|rightleftharpoons|NotGreaterGreater|NotSquareSuperset|blacktriangleleft|blacktriangledown|NegativeThinSpace|LeftDownTeeVector|NotLessSlantEqual|leftrightharpoons|DoubleUpDownArrow|DoubleVerticalBar|LeftTriangleEqual|FilledSmallSquare|twoheadrightarrow|NotNestedLessLess|DownLeftTeeVector|DownLeftVectorBar|RightAngleBracket|NotTildeFullEqual|NotReverseElement|RightUpDownVector|DiacriticalTilde|NotSucceedsTilde|circlearrowright|NotPrecedesEqual|rightharpoondown|DoubleRightArrow|NotSucceedsEqual|NonBreakingSpace|NotRightTriangle|LessEqualGreater|RightUpTeeVector|LeftAngleBracket|GreaterFullEqual|DownArrowUpArrow|RightUpVectorBar|twoheadleftarrow|GreaterEqualLess|downharpoonright|RightTriangleBar|ntrianglerighteq|NotSupersetEqual|LeftUpDownVector|DiacriticalAcute|rightrightarrows|vartriangleright|UpArrowDownArrow|DiacriticalGrave|UnderParenthesis|EmptySmallSquare|LeftUpVectorBar|leftrightarrows|DownRightVector|downharpoonleft|trianglerighteq|ShortRightArrow|OverParenthesis|DoubleLeftArrow|DoubleDownArrow|NotSquareSubset|bigtriangledown|ntrianglelefteq|UpperRightArrow|curvearrowright|vartriangleleft|NotLeftTriangle|nleftrightarrow|LowerRightArrow|NotHumpDownHump|NotGreaterTilde|rightthreetimes|LeftUpTeeVector|NotGreaterEqual|straightepsilon|LeftTriangleBar|rightsquigarrow|ContourIntegral|rightleftarrows|CloseCurlyQuote|RightDownVector|LeftRightVector|nLeftrightarrow|leftharpoondown|circlearrowleft|SquareSuperset|OpenCurlyQuote|hookrightarrow|HorizontalLine|DiacriticalDot|NotLessGreater|ntriangleright|DoubleRightTee|InvisibleComma|InvisibleTimes|LowerLeftArrow|DownLeftVector|NotSubsetEqual|curvearrowleft|trianglelefteq|NotVerticalBar|TildeFullEqual|downdownarrows|NotGreaterLess|RightTeeVector|ZeroWidthSpace|looparrowright|LongRightArrow|doublebarwedge|ShortLeftArrow|ShortDownArrow|RightVectorBar|GreaterGreater|ReverseElement|rightharpoonup|LessSlantEqual|leftthreetimes|upharpoonright|rightarrowtail|LeftDownVector|Longrightarrow|NestedLessLess|UpperLeftArrow|nshortparallel|leftleftarrows|leftrightarrow|Leftrightarrow|LeftRightArrow|longrightarrow|upharpoonleft|RightArrowBar|ApplyFunction|LeftTeeVector|leftarrowtail|NotEqualTilde|varsubsetneqq|varsupsetneqq|RightTeeArrow|SucceedsEqual|SucceedsTilde|LeftVectorBar|SupersetEqual|hookleftarrow|DifferentialD|VerticalTilde|VeryThinSpace|blacktriangle|bigtriangleup|LessFullEqual|divideontimes|leftharpoonup|UpEquilibrium|ntriangleleft|RightTriangle|measuredangle|shortparallel|longleftarrow|Longleftarrow|LongLeftArrow|DoubleLeftTee|Poincareplane|PrecedesEqual|triangleright|DoubleUpArrow|RightUpVector|fallingdotseq|looparrowleft|PrecedesTilde|NotTildeEqual|NotTildeTilde|smallsetminus|Proportional|triangleleft|triangledown|UnderBracket|NotHumpEqual|exponentiale|ExponentialE|NotLessTilde|HilbertSpace|RightCeiling|blacklozenge|varsupsetneq|HumpDownHump|GreaterEqual|VerticalLine|LeftTeeArrow|NotLessEqual|DownTeeArrow|LeftTriangle|varsubsetneq|Intersection|NotCongruent|DownArrowBar|LeftUpVector|LeftArrowBar|risingdotseq|GreaterTilde|RoundImplies|SquareSubset|ShortUpArrow|NotSuperset|quaternions|precnapprox|backepsilon|preccurlyeq|OverBracket|blacksquare|MediumSpace|VerticalBar|circledcirc|circleddash|CircleMinus|CircleTimes|LessGreater|curlyeqprec|curlyeqsucc|diamondsuit|UpDownArrow|Updownarrow|RuleDelayed|Rrightarrow|updownarrow|RightVector|nRightarrow|nrightarrow|eqslantless|LeftCeiling|Equilibrium|SmallCircle|expectation|NotSucceeds|thickapprox|GreaterLess|SquareUnion|NotPrecedes|NotLessLess|straightphi|succnapprox|succcurlyeq|SubsetEqual|sqsupseteq|Proportion|Laplacetrf|ImaginaryI|supsetneqq|NotGreater|gtreqqless|NotElement|ThickSpace|TildeEqual|TildeTilde|Fouriertrf|rmoustache|EqualTilde|eqslantgtr|UnderBrace|LeftVector|UpArrowBar|nLeftarrow|nsubseteqq|subsetneqq|nsupseteqq|nleftarrow|succapprox|lessapprox|UpTeeArrow|upuparrows|curlywedge|lesseqqgtr|varepsilon|varnothing|RightFloor|complement|CirclePlus|sqsubseteq|Lleftarrow|circledast|RightArrow|Rightarrow|rightarrow|lmoustache|Bernoullis|precapprox|mapstoleft|mapstodown|longmapsto|dotsquare|downarrow|DoubleDot|nsubseteq|supsetneq|leftarrow|nsupseteq|subsetneq|ThinSpace|ngeqslant|subseteqq|HumpEqual|NotSubset|triangleq|NotCupCap|lesseqgtr|heartsuit|TripleDot|Leftarrow|Coproduct|Congruent|varpropto|complexes|gvertneqq|LeftArrow|LessTilde|supseteqq|MinusPlus|CircleDot|nleqslant|NotExists|gtreqless|nparallel|UnionPlus|LeftFloor|checkmark|CenterDot|centerdot|Mellintrf|gtrapprox|bigotimes|OverBrace|spadesuit|therefore|pitchfork|rationals|PlusMinus|Backslash|Therefore|DownBreve|backsimeq|backprime|DownArrow|nshortmid|Downarrow|lvertneqq|eqvparsl|imagline|imagpart|infintie|integers|Integral|intercal|LessLess|Uarrocir|intlarhk|sqsupset|angmsdaf|sqsubset|llcorner|vartheta|cupbrcap|lnapprox|Superset|SuchThat|succnsim|succneqq|angmsdag|biguplus|curlyvee|trpezium|Succeeds|NotTilde|bigwedge|angmsdah|angrtvbd|triminus|cwconint|fpartint|lrcorner|smeparsl|subseteq|urcorner|lurdshar|laemptyv|DDotrahd|approxeq|ldrushar|awconint|mapstoup|backcong|shortmid|triangle|geqslant|gesdotol|timesbar|circledR|circledS|setminus|multimap|naturals|scpolint|ncongdot|RightTee|boxminus|gnapprox|boxtimes|andslope|thicksim|angmsdaa|varsigma|cirfnint|rtriltri|angmsdab|rppolint|angmsdac|barwedge|drbkarow|clubsuit|thetasym|bsolhsub|capbrcup|dzigrarr|doteqdot|DotEqual|dotminus|UnderBar|NotEqual|realpart|otimesas|ulcorner|hksearow|hkswarow|parallel|PartialD|elinters|emptyset|plusacir|bbrktbrk|angmsdad|pointint|bigoplus|angmsdae|Precedes|bigsqcup|varkappa|notindot|supseteq|precneqq|precnsim|profalar|profline|profsurf|leqslant|lesdotor|raemptyv|subplus|notnivb|notnivc|subrarr|zigrarr|vzigzag|submult|subedot|Element|between|cirscir|larrbfs|larrsim|lotimes|lbrksld|lbrkslu|lozenge|ldrdhar|dbkarow|bigcirc|epsilon|simrarr|simplus|ltquest|Epsilon|luruhar|gtquest|maltese|npolint|eqcolon|npreceq|bigodot|ddagger|gtrless|bnequiv|harrcir|ddotseq|equivDD|backsim|demptyv|nsqsube|nsqsupe|Upsilon|nsubset|upsilon|minusdu|nsucceq|swarrow|nsupset|coloneq|searrow|boxplus|napprox|natural|asympeq|alefsym|congdot|nearrow|bigstar|diamond|supplus|tritime|LeftTee|nvinfin|triplus|NewLine|nvltrie|nvrtrie|nwarrow|nexists|Diamond|ruluhar|Implies|supmult|angzarr|suplarr|suphsub|questeq|because|digamma|Because|olcross|bemptyv|omicron|Omicron|rotimes|NoBreak|intprod|angrtvb|orderof|uwangle|suphsol|lesdoto|orslope|DownTee|realine|cudarrl|rdldhar|OverBar|supedot|lessdot|supdsub|topfork|succsim|rbrkslu|rbrksld|pertenk|cudarrr|isindot|planckh|lessgtr|pluscir|gesdoto|plussim|plustwo|lesssim|cularrp|rarrsim|Cayleys|notinva|notinvb|notinvc|UpArrow|Uparrow|uparrow|NotLess|dwangle|precsim|Product|curarrm|Cconint|dotplus|rarrbfs|ccupssm|Cedilla|cemptyv|notniva|quatint|frac35|frac38|frac45|frac56|frac58|frac78|tridot|xoplus|gacute|gammad|Gammad|lfisht|lfloor|bigcup|sqsupe|gbreve|Gbreve|lharul|sqsube|sqcups|Gcedil|apacir|llhard|lmidot|Lmidot|lmoust|andand|sqcaps|approx|Abreve|spades|circeq|tprime|divide|topcir|Assign|topbot|gesdot|divonx|xuplus|timesd|gesles|atilde|solbar|SOFTcy|loplus|timesb|lowast|lowbar|dlcorn|dlcrop|softcy|dollar|lparlt|thksim|lrhard|Atilde|lsaquo|smashp|bigvee|thinsp|wreath|bkarow|lsquor|lstrok|Lstrok|lthree|ltimes|ltlarr|DotDot|simdot|ltrPar|weierp|xsqcup|angmsd|sigmav|sigmaf|zeetrf|Zcaron|zcaron|mapsto|vsupne|thetav|cirmid|marker|mcomma|Zacute|vsubnE|there4|gtlPar|vsubne|bottom|gtrarr|SHCHcy|shchcy|midast|midcir|middot|minusb|minusd|gtrdot|bowtie|sfrown|mnplus|models|colone|seswar|Colone|mstpos|searhk|gtrsim|nacute|Nacute|boxbox|telrec|hairsp|Tcedil|nbumpe|scnsim|ncaron|Ncaron|ncedil|Ncedil|hamilt|Scedil|nearhk|hardcy|HARDcy|tcedil|Tcaron|commat|nequiv|nesear|tcaron|target|hearts|nexist|varrho|scedil|Scaron|scaron|hellip|Sacute|sacute|hercon|swnwar|compfn|rtimes|rthree|rsquor|rsaquo|zacute|wedgeq|homtht|barvee|barwed|Barwed|rpargt|horbar|conint|swarhk|roplus|nltrie|hslash|hstrok|Hstrok|rmoust|Conint|bprime|hybull|hyphen|iacute|Iacute|supsup|supsub|supsim|varphi|coprod|brvbar|agrave|Supset|supset|igrave|Igrave|notinE|Agrave|iiiint|iinfin|copysr|wedbar|Verbar|vangrt|becaus|incare|verbar|inodot|bullet|drcorn|intcal|drcrop|cularr|vellip|Utilde|bumpeq|cupcap|dstrok|Dstrok|CupCap|cupcup|cupdot|eacute|Eacute|supdot|iquest|easter|ecaron|Ecaron|ecolon|isinsv|utilde|itilde|Itilde|curarr|succeq|Bumpeq|cacute|ulcrop|nparsl|Cacute|nprcue|egrave|Egrave|nrarrc|nrarrw|subsup|subsub|nrtrie|jsercy|nsccue|Jsercy|kappav|kcedil|Kcedil|subsim|ulcorn|nsimeq|egsdot|veebar|kgreen|capand|elsdot|Subset|subset|curren|aacute|lacute|Lacute|emptyv|ntilde|Ntilde|lagran|lambda|Lambda|capcap|Ugrave|langle|subdot|emsp13|numero|emsp14|nvdash|nvDash|nVdash|nVDash|ugrave|ufisht|nvHarr|larrfs|nvlArr|larrhk|larrlp|larrpl|nvrArr|Udblac|nwarhk|larrtl|nwnear|oacute|Oacute|latail|lAtail|sstarf|lbrace|odblac|Odblac|lbrack|udblac|odsold|eparsl|lcaron|Lcaron|ograve|Ograve|lcedil|Lcedil|Aacute|ssmile|ssetmn|squarf|ldquor|capcup|ominus|cylcty|rharul|eqcirc|dagger|rfloor|rfisht|Dagger|daleth|equals|origof|capdot|equest|dcaron|Dcaron|rdquor|oslash|Oslash|otilde|Otilde|otimes|Otimes|urcrop|Ubreve|ubreve|Yacute|Uacute|uacute|Rcedil|rcedil|urcorn|parsim|Rcaron|Vdashl|rcaron|Tstrok|percnt|period|permil|Exists|yacute|rbrack|rbrace|phmmat|ccaron|Ccaron|planck|ccedil|plankv|tstrok|female|plusdo|plusdu|ffilig|plusmn|ffllig|Ccedil|rAtail|dfisht|bernou|ratail|Rarrtl|rarrtl|angsph|rarrpl|rarrlp|rarrhk|xwedge|xotime|forall|ForAll|Vvdash|vsupnE|preceq|bigcap|frac12|frac13|frac14|primes|rarrfs|prnsim|frac15|Square|frac16|square|lesdot|frac18|frac23|propto|prurel|rarrap|rangle|puncsp|frac25|Racute|qprime|racute|lesges|frac34|abreve|AElig|eqsim|utdot|setmn|urtri|Equal|Uring|seArr|uring|searr|dashv|Dashv|mumap|nabla|iogon|Iogon|sdote|sdotb|scsim|napid|napos|equiv|natur|Acirc|dblac|erarr|nbump|iprod|erDot|ucirc|awint|esdot|angrt|ncong|isinE|scnap|Scirc|scirc|ndash|isins|Ubrcy|nearr|neArr|isinv|nedot|ubrcy|acute|Ycirc|iukcy|Iukcy|xutri|nesim|caret|jcirc|Jcirc|caron|twixt|ddarr|sccue|exist|jmath|sbquo|ngeqq|angst|ccaps|lceil|ngsim|UpTee|delta|Delta|rtrif|nharr|nhArr|nhpar|rtrie|jukcy|Jukcy|kappa|rsquo|Kappa|nlarr|nlArr|TSHcy|rrarr|aogon|Aogon|fflig|xrarr|tshcy|ccirc|nleqq|filig|upsih|nless|dharl|nlsim|fjlig|ropar|nltri|dharr|robrk|roarr|fllig|fltns|roang|rnmid|subnE|subne|lAarr|trisb|Ccirc|acirc|ccups|blank|VDash|forkv|Vdash|langd|cedil|blk12|blk14|laquo|strns|diams|notin|vDash|larrb|blk34|block|disin|uplus|vdash|vBarv|aelig|starf|Wedge|check|xrArr|lates|lbarr|lBarr|notni|lbbrk|bcong|frasl|lbrke|frown|vrtri|vprop|vnsup|gamma|Gamma|wedge|xodot|bdquo|srarr|doteq|ldquo|boxdl|boxdL|gcirc|Gcirc|boxDl|boxDL|boxdr|boxdR|boxDr|TRADE|trade|rlhar|boxDR|vnsub|npart|vltri|rlarr|boxhd|boxhD|nprec|gescc|nrarr|nrArr|boxHd|boxHD|boxhu|boxhU|nrtri|boxHu|clubs|boxHU|times|colon|Colon|gimel|xlArr|Tilde|nsime|tilde|nsmid|nspar|THORN|thorn|xlarr|nsube|nsubE|thkap|xhArr|comma|nsucc|boxul|boxuL|nsupe|nsupE|gneqq|gnsim|boxUl|boxUL|grave|boxur|boxuR|boxUr|boxUR|lescc|angle|bepsi|boxvh|varpi|boxvH|numsp|Theta|gsime|gsiml|theta|boxVh|boxVH|boxvl|gtcir|gtdot|boxvL|boxVl|boxVL|crarr|cross|Cross|nvsim|boxvr|nwarr|nwArr|sqsup|dtdot|Uogon|lhard|lharu|dtrif|ocirc|Ocirc|lhblk|duarr|odash|sqsub|Hacek|sqcup|llarr|duhar|oelig|OElig|ofcir|boxvR|uogon|lltri|boxVr|csube|uuarr|ohbar|csupe|ctdot|olarr|olcir|harrw|oline|sqcap|omacr|Omacr|omega|Omega|boxVR|aleph|lneqq|lnsim|loang|loarr|rharu|lobrk|hcirc|operp|oplus|rhard|Hcirc|orarr|Union|order|ecirc|Ecirc|cuepr|szlig|cuesc|breve|reals|eDDot|Breve|hoarr|lopar|utrif|rdquo|Umacr|umacr|efDot|swArr|ultri|alpha|rceil|ovbar|swarr|Wcirc|wcirc|smtes|smile|bsemi|lrarr|aring|parsl|lrhar|bsime|uhblk|lrtri|cupor|Aring|uharr|uharl|slarr|rbrke|bsolb|lsime|rbbrk|RBarr|lsimg|phone|rBarr|rbarr|icirc|lsquo|Icirc|emacr|Emacr|ratio|simne|plusb|simlE|simgE|simeq|pluse|ltcir|ltdot|empty|xharr|xdtri|iexcl|Alpha|ltrie|rarrw|pound|ltrif|xcirc|bumpe|prcue|bumpE|asymp|amacr|cuvee|Sigma|sigma|iiint|udhar|iiota|ijlig|IJlig|supnE|imacr|Imacr|prime|Prime|image|prnap|eogon|Eogon|rarrc|mdash|mDDot|cuwed|imath|supne|imped|Amacr|udarr|prsim|micro|rarrb|cwint|raquo|infin|eplus|range|rangd|Ucirc|radic|minus|amalg|veeeq|rAarr|epsiv|ycirc|quest|sharp|quot|zwnj|Qscr|race|qscr|Qopf|qopf|qint|rang|Rang|Zscr|zscr|Zopf|zopf|rarr|rArr|Rarr|Pscr|pscr|prop|prod|prnE|prec|ZHcy|zhcy|prap|Zeta|zeta|Popf|popf|Zdot|plus|zdot|Yuml|yuml|phiv|YUcy|yucy|Yscr|yscr|perp|Yopf|yopf|part|para|YIcy|Ouml|rcub|yicy|YAcy|rdca|ouml|osol|Oscr|rdsh|yacy|real|oscr|xvee|andd|rect|andv|Xscr|oror|ordm|ordf|xscr|ange|aopf|Aopf|rHar|Xopf|opar|Oopf|xopf|xnis|rhov|oopf|omid|xmap|oint|apid|apos|ogon|ascr|Ascr|odot|odiv|xcup|xcap|ocir|oast|nvlt|nvle|nvgt|nvge|nvap|Wscr|wscr|auml|ntlg|ntgl|nsup|nsub|nsim|Nscr|nscr|nsce|Wopf|ring|npre|wopf|npar|Auml|Barv|bbrk|Nopf|nopf|nmid|nLtv|beta|ropf|Ropf|Beta|beth|nles|rpar|nleq|bnot|bNot|nldr|NJcy|rscr|Rscr|Vscr|vscr|rsqb|njcy|bopf|nisd|Bopf|rtri|Vopf|nGtv|ngtr|vopf|boxh|boxH|boxv|nges|ngeq|boxV|bscr|scap|Bscr|bsim|Vert|vert|bsol|bull|bump|caps|cdot|ncup|scnE|ncap|nbsp|napE|Cdot|cent|sdot|Vbar|nang|vBar|chcy|Mscr|mscr|sect|semi|CHcy|Mopf|mopf|sext|circ|cire|mldr|mlcp|cirE|comp|shcy|SHcy|vArr|varr|cong|copf|Copf|copy|COPY|malt|male|macr|lvnE|cscr|ltri|sime|ltcc|simg|Cscr|siml|csub|Uuml|lsqb|lsim|uuml|csup|Lscr|lscr|utri|smid|lpar|cups|smte|lozf|darr|Lopf|Uscr|solb|lopf|sopf|Sopf|lneq|uscr|spar|dArr|lnap|Darr|dash|Sqrt|LJcy|ljcy|lHar|dHar|Upsi|upsi|diam|lesg|djcy|DJcy|leqq|dopf|Dopf|dscr|Dscr|dscy|ldsh|ldca|squf|DScy|sscr|Sscr|dsol|lcub|late|star|Star|Uopf|Larr|lArr|larr|uopf|dtri|dzcy|sube|subE|Lang|lang|Kscr|kscr|Kopf|kopf|KJcy|kjcy|KHcy|khcy|DZcy|ecir|edot|eDot|Jscr|jscr|succ|Jopf|jopf|Edot|uHar|emsp|ensp|Iuml|iuml|eopf|isin|Iscr|iscr|Eopf|epar|sung|epsi|escr|sup1|sup2|sup3|Iota|iota|supe|supE|Iopf|iopf|IOcy|iocy|Escr|esim|Esim|imof|Uarr|QUOT|uArr|uarr|euml|IEcy|iecy|Idot|Euml|euro|excl|Hscr|hscr|Hopf|hopf|TScy|tscy|Tscr|hbar|tscr|flat|tbrk|fnof|hArr|harr|half|fopf|Fopf|tdot|gvnE|fork|trie|gtcc|fscr|Fscr|gdot|gsim|Gscr|gscr|Gopf|gopf|gneq|Gdot|tosa|gnap|Topf|topf|geqq|toea|GJcy|gjcy|tint|gesl|mid|Sfr|ggg|top|ges|gla|glE|glj|geq|gne|gEl|gel|gnE|Gcy|gcy|gap|Tfr|tfr|Tcy|tcy|Hat|Tau|Ffr|tau|Tab|hfr|Hfr|ffr|Fcy|fcy|icy|Icy|iff|ETH|eth|ifr|Ifr|Eta|eta|int|Int|Sup|sup|ucy|Ucy|Sum|sum|jcy|ENG|ufr|Ufr|eng|Jcy|jfr|els|ell|egs|Efr|efr|Jfr|uml|kcy|Kcy|Ecy|ecy|kfr|Kfr|lap|Sub|sub|lat|lcy|Lcy|leg|Dot|dot|lEg|leq|les|squ|div|die|lfr|Lfr|lgE|Dfr|dfr|Del|deg|Dcy|dcy|lne|lnE|sol|loz|smt|Cup|lrm|cup|lsh|Lsh|sim|shy|map|Map|mcy|Mcy|mfr|Mfr|mho|gfr|Gfr|sfr|cir|Chi|chi|nap|Cfr|vcy|Vcy|cfr|Scy|scy|ncy|Ncy|vee|Vee|Cap|cap|nfr|scE|sce|Nfr|nge|ngE|nGg|vfr|Vfr|ngt|bot|nGt|nis|niv|Rsh|rsh|nle|nlE|bne|Bfr|bfr|nLl|nlt|nLt|Bcy|bcy|not|Not|rlm|wfr|Wfr|npr|nsc|num|ocy|ast|Ocy|ofr|xfr|Xfr|Ofr|ogt|ohm|apE|olt|Rho|ape|rho|Rfr|rfr|ord|REG|ang|reg|orv|And|and|AMP|Rcy|amp|Afr|ycy|Ycy|yen|yfr|Yfr|rcy|par|pcy|Pcy|pfr|Pfr|phi|Phi|afr|Acy|acy|zcy|Zcy|piv|acE|acd|zfr|Zfr|pre|prE|psi|Psi|qfr|Qfr|zwj|Or|ge|Gg|gt|gg|el|oS|lt|Lt|LT|Re|lg|gl|eg|ne|Im|it|le|DD|wp|wr|nu|Nu|dd|lE|Sc|sc|pi|Pi|ee|af|ll|Ll|rx|gE|xi|pm|Xi|ic|pr|Pr|in|ni|mp|mu|ac|Mu|or|ap|Gt|GT|ii);|&(Aacute|Agrave|Atilde|Ccedil|Eacute|Egrave|Iacute|Igrave|Ntilde|Oacute|Ograve|Oslash|Otilde|Uacute|Ugrave|Yacute|aacute|agrave|atilde|brvbar|ccedil|curren|divide|eacute|egrave|frac12|frac14|frac34|iacute|igrave|iquest|middot|ntilde|oacute|ograve|oslash|otilde|plusmn|uacute|ugrave|yacute|AElig|Acirc|Aring|Ecirc|Icirc|Ocirc|THORN|Ucirc|acirc|acute|aelig|aring|cedil|ecirc|icirc|iexcl|laquo|micro|ocirc|pound|raquo|szlig|thorn|times|ucirc|Auml|COPY|Euml|Iuml|Ouml|QUOT|Uuml|auml|cent|copy|euml|iuml|macr|nbsp|ordf|ordm|ouml|para|quot|sect|sup1|sup2|sup3|uuml|yuml|AMP|ETH|REG|amp|deg|eth|not|reg|shy|uml|yen|GT|LT|gt|lt)(?!;)([=a-zA-Z0-9]?)|&#([0-9]+)(;?)|&#[xX]([a-fA-F0-9]+)(;?)|&([0-9a-zA-Z]+)/g; + var decodeMap = {'aacute':'\xE1','Aacute':'\xC1','abreve':'\u0103','Abreve':'\u0102','ac':'\u223E','acd':'\u223F','acE':'\u223E\u0333','acirc':'\xE2','Acirc':'\xC2','acute':'\xB4','acy':'\u0430','Acy':'\u0410','aelig':'\xE6','AElig':'\xC6','af':'\u2061','afr':'\uD835\uDD1E','Afr':'\uD835\uDD04','agrave':'\xE0','Agrave':'\xC0','alefsym':'\u2135','aleph':'\u2135','alpha':'\u03B1','Alpha':'\u0391','amacr':'\u0101','Amacr':'\u0100','amalg':'\u2A3F','amp':'&','AMP':'&','and':'\u2227','And':'\u2A53','andand':'\u2A55','andd':'\u2A5C','andslope':'\u2A58','andv':'\u2A5A','ang':'\u2220','ange':'\u29A4','angle':'\u2220','angmsd':'\u2221','angmsdaa':'\u29A8','angmsdab':'\u29A9','angmsdac':'\u29AA','angmsdad':'\u29AB','angmsdae':'\u29AC','angmsdaf':'\u29AD','angmsdag':'\u29AE','angmsdah':'\u29AF','angrt':'\u221F','angrtvb':'\u22BE','angrtvbd':'\u299D','angsph':'\u2222','angst':'\xC5','angzarr':'\u237C','aogon':'\u0105','Aogon':'\u0104','aopf':'\uD835\uDD52','Aopf':'\uD835\uDD38','ap':'\u2248','apacir':'\u2A6F','ape':'\u224A','apE':'\u2A70','apid':'\u224B','apos':'\'','ApplyFunction':'\u2061','approx':'\u2248','approxeq':'\u224A','aring':'\xE5','Aring':'\xC5','ascr':'\uD835\uDCB6','Ascr':'\uD835\uDC9C','Assign':'\u2254','ast':'*','asymp':'\u2248','asympeq':'\u224D','atilde':'\xE3','Atilde':'\xC3','auml':'\xE4','Auml':'\xC4','awconint':'\u2233','awint':'\u2A11','backcong':'\u224C','backepsilon':'\u03F6','backprime':'\u2035','backsim':'\u223D','backsimeq':'\u22CD','Backslash':'\u2216','Barv':'\u2AE7','barvee':'\u22BD','barwed':'\u2305','Barwed':'\u2306','barwedge':'\u2305','bbrk':'\u23B5','bbrktbrk':'\u23B6','bcong':'\u224C','bcy':'\u0431','Bcy':'\u0411','bdquo':'\u201E','becaus':'\u2235','because':'\u2235','Because':'\u2235','bemptyv':'\u29B0','bepsi':'\u03F6','bernou':'\u212C','Bernoullis':'\u212C','beta':'\u03B2','Beta':'\u0392','beth':'\u2136','between':'\u226C','bfr':'\uD835\uDD1F','Bfr':'\uD835\uDD05','bigcap':'\u22C2','bigcirc':'\u25EF','bigcup':'\u22C3','bigodot':'\u2A00','bigoplus':'\u2A01','bigotimes':'\u2A02','bigsqcup':'\u2A06','bigstar':'\u2605','bigtriangledown':'\u25BD','bigtriangleup':'\u25B3','biguplus':'\u2A04','bigvee':'\u22C1','bigwedge':'\u22C0','bkarow':'\u290D','blacklozenge':'\u29EB','blacksquare':'\u25AA','blacktriangle':'\u25B4','blacktriangledown':'\u25BE','blacktriangleleft':'\u25C2','blacktriangleright':'\u25B8','blank':'\u2423','blk12':'\u2592','blk14':'\u2591','blk34':'\u2593','block':'\u2588','bne':'=\u20E5','bnequiv':'\u2261\u20E5','bnot':'\u2310','bNot':'\u2AED','bopf':'\uD835\uDD53','Bopf':'\uD835\uDD39','bot':'\u22A5','bottom':'\u22A5','bowtie':'\u22C8','boxbox':'\u29C9','boxdl':'\u2510','boxdL':'\u2555','boxDl':'\u2556','boxDL':'\u2557','boxdr':'\u250C','boxdR':'\u2552','boxDr':'\u2553','boxDR':'\u2554','boxh':'\u2500','boxH':'\u2550','boxhd':'\u252C','boxhD':'\u2565','boxHd':'\u2564','boxHD':'\u2566','boxhu':'\u2534','boxhU':'\u2568','boxHu':'\u2567','boxHU':'\u2569','boxminus':'\u229F','boxplus':'\u229E','boxtimes':'\u22A0','boxul':'\u2518','boxuL':'\u255B','boxUl':'\u255C','boxUL':'\u255D','boxur':'\u2514','boxuR':'\u2558','boxUr':'\u2559','boxUR':'\u255A','boxv':'\u2502','boxV':'\u2551','boxvh':'\u253C','boxvH':'\u256A','boxVh':'\u256B','boxVH':'\u256C','boxvl':'\u2524','boxvL':'\u2561','boxVl':'\u2562','boxVL':'\u2563','boxvr':'\u251C','boxvR':'\u255E','boxVr':'\u255F','boxVR':'\u2560','bprime':'\u2035','breve':'\u02D8','Breve':'\u02D8','brvbar':'\xA6','bscr':'\uD835\uDCB7','Bscr':'\u212C','bsemi':'\u204F','bsim':'\u223D','bsime':'\u22CD','bsol':'\\','bsolb':'\u29C5','bsolhsub':'\u27C8','bull':'\u2022','bullet':'\u2022','bump':'\u224E','bumpe':'\u224F','bumpE':'\u2AAE','bumpeq':'\u224F','Bumpeq':'\u224E','cacute':'\u0107','Cacute':'\u0106','cap':'\u2229','Cap':'\u22D2','capand':'\u2A44','capbrcup':'\u2A49','capcap':'\u2A4B','capcup':'\u2A47','capdot':'\u2A40','CapitalDifferentialD':'\u2145','caps':'\u2229\uFE00','caret':'\u2041','caron':'\u02C7','Cayleys':'\u212D','ccaps':'\u2A4D','ccaron':'\u010D','Ccaron':'\u010C','ccedil':'\xE7','Ccedil':'\xC7','ccirc':'\u0109','Ccirc':'\u0108','Cconint':'\u2230','ccups':'\u2A4C','ccupssm':'\u2A50','cdot':'\u010B','Cdot':'\u010A','cedil':'\xB8','Cedilla':'\xB8','cemptyv':'\u29B2','cent':'\xA2','centerdot':'\xB7','CenterDot':'\xB7','cfr':'\uD835\uDD20','Cfr':'\u212D','chcy':'\u0447','CHcy':'\u0427','check':'\u2713','checkmark':'\u2713','chi':'\u03C7','Chi':'\u03A7','cir':'\u25CB','circ':'\u02C6','circeq':'\u2257','circlearrowleft':'\u21BA','circlearrowright':'\u21BB','circledast':'\u229B','circledcirc':'\u229A','circleddash':'\u229D','CircleDot':'\u2299','circledR':'\xAE','circledS':'\u24C8','CircleMinus':'\u2296','CirclePlus':'\u2295','CircleTimes':'\u2297','cire':'\u2257','cirE':'\u29C3','cirfnint':'\u2A10','cirmid':'\u2AEF','cirscir':'\u29C2','ClockwiseContourIntegral':'\u2232','CloseCurlyDoubleQuote':'\u201D','CloseCurlyQuote':'\u2019','clubs':'\u2663','clubsuit':'\u2663','colon':':','Colon':'\u2237','colone':'\u2254','Colone':'\u2A74','coloneq':'\u2254','comma':',','commat':'@','comp':'\u2201','compfn':'\u2218','complement':'\u2201','complexes':'\u2102','cong':'\u2245','congdot':'\u2A6D','Congruent':'\u2261','conint':'\u222E','Conint':'\u222F','ContourIntegral':'\u222E','copf':'\uD835\uDD54','Copf':'\u2102','coprod':'\u2210','Coproduct':'\u2210','copy':'\xA9','COPY':'\xA9','copysr':'\u2117','CounterClockwiseContourIntegral':'\u2233','crarr':'\u21B5','cross':'\u2717','Cross':'\u2A2F','cscr':'\uD835\uDCB8','Cscr':'\uD835\uDC9E','csub':'\u2ACF','csube':'\u2AD1','csup':'\u2AD0','csupe':'\u2AD2','ctdot':'\u22EF','cudarrl':'\u2938','cudarrr':'\u2935','cuepr':'\u22DE','cuesc':'\u22DF','cularr':'\u21B6','cularrp':'\u293D','cup':'\u222A','Cup':'\u22D3','cupbrcap':'\u2A48','cupcap':'\u2A46','CupCap':'\u224D','cupcup':'\u2A4A','cupdot':'\u228D','cupor':'\u2A45','cups':'\u222A\uFE00','curarr':'\u21B7','curarrm':'\u293C','curlyeqprec':'\u22DE','curlyeqsucc':'\u22DF','curlyvee':'\u22CE','curlywedge':'\u22CF','curren':'\xA4','curvearrowleft':'\u21B6','curvearrowright':'\u21B7','cuvee':'\u22CE','cuwed':'\u22CF','cwconint':'\u2232','cwint':'\u2231','cylcty':'\u232D','dagger':'\u2020','Dagger':'\u2021','daleth':'\u2138','darr':'\u2193','dArr':'\u21D3','Darr':'\u21A1','dash':'\u2010','dashv':'\u22A3','Dashv':'\u2AE4','dbkarow':'\u290F','dblac':'\u02DD','dcaron':'\u010F','Dcaron':'\u010E','dcy':'\u0434','Dcy':'\u0414','dd':'\u2146','DD':'\u2145','ddagger':'\u2021','ddarr':'\u21CA','DDotrahd':'\u2911','ddotseq':'\u2A77','deg':'\xB0','Del':'\u2207','delta':'\u03B4','Delta':'\u0394','demptyv':'\u29B1','dfisht':'\u297F','dfr':'\uD835\uDD21','Dfr':'\uD835\uDD07','dHar':'\u2965','dharl':'\u21C3','dharr':'\u21C2','DiacriticalAcute':'\xB4','DiacriticalDot':'\u02D9','DiacriticalDoubleAcute':'\u02DD','DiacriticalGrave':'`','DiacriticalTilde':'\u02DC','diam':'\u22C4','diamond':'\u22C4','Diamond':'\u22C4','diamondsuit':'\u2666','diams':'\u2666','die':'\xA8','DifferentialD':'\u2146','digamma':'\u03DD','disin':'\u22F2','div':'\xF7','divide':'\xF7','divideontimes':'\u22C7','divonx':'\u22C7','djcy':'\u0452','DJcy':'\u0402','dlcorn':'\u231E','dlcrop':'\u230D','dollar':'$','dopf':'\uD835\uDD55','Dopf':'\uD835\uDD3B','dot':'\u02D9','Dot':'\xA8','DotDot':'\u20DC','doteq':'\u2250','doteqdot':'\u2251','DotEqual':'\u2250','dotminus':'\u2238','dotplus':'\u2214','dotsquare':'\u22A1','doublebarwedge':'\u2306','DoubleContourIntegral':'\u222F','DoubleDot':'\xA8','DoubleDownArrow':'\u21D3','DoubleLeftArrow':'\u21D0','DoubleLeftRightArrow':'\u21D4','DoubleLeftTee':'\u2AE4','DoubleLongLeftArrow':'\u27F8','DoubleLongLeftRightArrow':'\u27FA','DoubleLongRightArrow':'\u27F9','DoubleRightArrow':'\u21D2','DoubleRightTee':'\u22A8','DoubleUpArrow':'\u21D1','DoubleUpDownArrow':'\u21D5','DoubleVerticalBar':'\u2225','downarrow':'\u2193','Downarrow':'\u21D3','DownArrow':'\u2193','DownArrowBar':'\u2913','DownArrowUpArrow':'\u21F5','DownBreve':'\u0311','downdownarrows':'\u21CA','downharpoonleft':'\u21C3','downharpoonright':'\u21C2','DownLeftRightVector':'\u2950','DownLeftTeeVector':'\u295E','DownLeftVector':'\u21BD','DownLeftVectorBar':'\u2956','DownRightTeeVector':'\u295F','DownRightVector':'\u21C1','DownRightVectorBar':'\u2957','DownTee':'\u22A4','DownTeeArrow':'\u21A7','drbkarow':'\u2910','drcorn':'\u231F','drcrop':'\u230C','dscr':'\uD835\uDCB9','Dscr':'\uD835\uDC9F','dscy':'\u0455','DScy':'\u0405','dsol':'\u29F6','dstrok':'\u0111','Dstrok':'\u0110','dtdot':'\u22F1','dtri':'\u25BF','dtrif':'\u25BE','duarr':'\u21F5','duhar':'\u296F','dwangle':'\u29A6','dzcy':'\u045F','DZcy':'\u040F','dzigrarr':'\u27FF','eacute':'\xE9','Eacute':'\xC9','easter':'\u2A6E','ecaron':'\u011B','Ecaron':'\u011A','ecir':'\u2256','ecirc':'\xEA','Ecirc':'\xCA','ecolon':'\u2255','ecy':'\u044D','Ecy':'\u042D','eDDot':'\u2A77','edot':'\u0117','eDot':'\u2251','Edot':'\u0116','ee':'\u2147','efDot':'\u2252','efr':'\uD835\uDD22','Efr':'\uD835\uDD08','eg':'\u2A9A','egrave':'\xE8','Egrave':'\xC8','egs':'\u2A96','egsdot':'\u2A98','el':'\u2A99','Element':'\u2208','elinters':'\u23E7','ell':'\u2113','els':'\u2A95','elsdot':'\u2A97','emacr':'\u0113','Emacr':'\u0112','empty':'\u2205','emptyset':'\u2205','EmptySmallSquare':'\u25FB','emptyv':'\u2205','EmptyVerySmallSquare':'\u25AB','emsp':'\u2003','emsp13':'\u2004','emsp14':'\u2005','eng':'\u014B','ENG':'\u014A','ensp':'\u2002','eogon':'\u0119','Eogon':'\u0118','eopf':'\uD835\uDD56','Eopf':'\uD835\uDD3C','epar':'\u22D5','eparsl':'\u29E3','eplus':'\u2A71','epsi':'\u03B5','epsilon':'\u03B5','Epsilon':'\u0395','epsiv':'\u03F5','eqcirc':'\u2256','eqcolon':'\u2255','eqsim':'\u2242','eqslantgtr':'\u2A96','eqslantless':'\u2A95','Equal':'\u2A75','equals':'=','EqualTilde':'\u2242','equest':'\u225F','Equilibrium':'\u21CC','equiv':'\u2261','equivDD':'\u2A78','eqvparsl':'\u29E5','erarr':'\u2971','erDot':'\u2253','escr':'\u212F','Escr':'\u2130','esdot':'\u2250','esim':'\u2242','Esim':'\u2A73','eta':'\u03B7','Eta':'\u0397','eth':'\xF0','ETH':'\xD0','euml':'\xEB','Euml':'\xCB','euro':'\u20AC','excl':'!','exist':'\u2203','Exists':'\u2203','expectation':'\u2130','exponentiale':'\u2147','ExponentialE':'\u2147','fallingdotseq':'\u2252','fcy':'\u0444','Fcy':'\u0424','female':'\u2640','ffilig':'\uFB03','fflig':'\uFB00','ffllig':'\uFB04','ffr':'\uD835\uDD23','Ffr':'\uD835\uDD09','filig':'\uFB01','FilledSmallSquare':'\u25FC','FilledVerySmallSquare':'\u25AA','fjlig':'fj','flat':'\u266D','fllig':'\uFB02','fltns':'\u25B1','fnof':'\u0192','fopf':'\uD835\uDD57','Fopf':'\uD835\uDD3D','forall':'\u2200','ForAll':'\u2200','fork':'\u22D4','forkv':'\u2AD9','Fouriertrf':'\u2131','fpartint':'\u2A0D','frac12':'\xBD','frac13':'\u2153','frac14':'\xBC','frac15':'\u2155','frac16':'\u2159','frac18':'\u215B','frac23':'\u2154','frac25':'\u2156','frac34':'\xBE','frac35':'\u2157','frac38':'\u215C','frac45':'\u2158','frac56':'\u215A','frac58':'\u215D','frac78':'\u215E','frasl':'\u2044','frown':'\u2322','fscr':'\uD835\uDCBB','Fscr':'\u2131','gacute':'\u01F5','gamma':'\u03B3','Gamma':'\u0393','gammad':'\u03DD','Gammad':'\u03DC','gap':'\u2A86','gbreve':'\u011F','Gbreve':'\u011E','Gcedil':'\u0122','gcirc':'\u011D','Gcirc':'\u011C','gcy':'\u0433','Gcy':'\u0413','gdot':'\u0121','Gdot':'\u0120','ge':'\u2265','gE':'\u2267','gel':'\u22DB','gEl':'\u2A8C','geq':'\u2265','geqq':'\u2267','geqslant':'\u2A7E','ges':'\u2A7E','gescc':'\u2AA9','gesdot':'\u2A80','gesdoto':'\u2A82','gesdotol':'\u2A84','gesl':'\u22DB\uFE00','gesles':'\u2A94','gfr':'\uD835\uDD24','Gfr':'\uD835\uDD0A','gg':'\u226B','Gg':'\u22D9','ggg':'\u22D9','gimel':'\u2137','gjcy':'\u0453','GJcy':'\u0403','gl':'\u2277','gla':'\u2AA5','glE':'\u2A92','glj':'\u2AA4','gnap':'\u2A8A','gnapprox':'\u2A8A','gne':'\u2A88','gnE':'\u2269','gneq':'\u2A88','gneqq':'\u2269','gnsim':'\u22E7','gopf':'\uD835\uDD58','Gopf':'\uD835\uDD3E','grave':'`','GreaterEqual':'\u2265','GreaterEqualLess':'\u22DB','GreaterFullEqual':'\u2267','GreaterGreater':'\u2AA2','GreaterLess':'\u2277','GreaterSlantEqual':'\u2A7E','GreaterTilde':'\u2273','gscr':'\u210A','Gscr':'\uD835\uDCA2','gsim':'\u2273','gsime':'\u2A8E','gsiml':'\u2A90','gt':'>','Gt':'\u226B','GT':'>','gtcc':'\u2AA7','gtcir':'\u2A7A','gtdot':'\u22D7','gtlPar':'\u2995','gtquest':'\u2A7C','gtrapprox':'\u2A86','gtrarr':'\u2978','gtrdot':'\u22D7','gtreqless':'\u22DB','gtreqqless':'\u2A8C','gtrless':'\u2277','gtrsim':'\u2273','gvertneqq':'\u2269\uFE00','gvnE':'\u2269\uFE00','Hacek':'\u02C7','hairsp':'\u200A','half':'\xBD','hamilt':'\u210B','hardcy':'\u044A','HARDcy':'\u042A','harr':'\u2194','hArr':'\u21D4','harrcir':'\u2948','harrw':'\u21AD','Hat':'^','hbar':'\u210F','hcirc':'\u0125','Hcirc':'\u0124','hearts':'\u2665','heartsuit':'\u2665','hellip':'\u2026','hercon':'\u22B9','hfr':'\uD835\uDD25','Hfr':'\u210C','HilbertSpace':'\u210B','hksearow':'\u2925','hkswarow':'\u2926','hoarr':'\u21FF','homtht':'\u223B','hookleftarrow':'\u21A9','hookrightarrow':'\u21AA','hopf':'\uD835\uDD59','Hopf':'\u210D','horbar':'\u2015','HorizontalLine':'\u2500','hscr':'\uD835\uDCBD','Hscr':'\u210B','hslash':'\u210F','hstrok':'\u0127','Hstrok':'\u0126','HumpDownHump':'\u224E','HumpEqual':'\u224F','hybull':'\u2043','hyphen':'\u2010','iacute':'\xED','Iacute':'\xCD','ic':'\u2063','icirc':'\xEE','Icirc':'\xCE','icy':'\u0438','Icy':'\u0418','Idot':'\u0130','iecy':'\u0435','IEcy':'\u0415','iexcl':'\xA1','iff':'\u21D4','ifr':'\uD835\uDD26','Ifr':'\u2111','igrave':'\xEC','Igrave':'\xCC','ii':'\u2148','iiiint':'\u2A0C','iiint':'\u222D','iinfin':'\u29DC','iiota':'\u2129','ijlig':'\u0133','IJlig':'\u0132','Im':'\u2111','imacr':'\u012B','Imacr':'\u012A','image':'\u2111','ImaginaryI':'\u2148','imagline':'\u2110','imagpart':'\u2111','imath':'\u0131','imof':'\u22B7','imped':'\u01B5','Implies':'\u21D2','in':'\u2208','incare':'\u2105','infin':'\u221E','infintie':'\u29DD','inodot':'\u0131','int':'\u222B','Int':'\u222C','intcal':'\u22BA','integers':'\u2124','Integral':'\u222B','intercal':'\u22BA','Intersection':'\u22C2','intlarhk':'\u2A17','intprod':'\u2A3C','InvisibleComma':'\u2063','InvisibleTimes':'\u2062','iocy':'\u0451','IOcy':'\u0401','iogon':'\u012F','Iogon':'\u012E','iopf':'\uD835\uDD5A','Iopf':'\uD835\uDD40','iota':'\u03B9','Iota':'\u0399','iprod':'\u2A3C','iquest':'\xBF','iscr':'\uD835\uDCBE','Iscr':'\u2110','isin':'\u2208','isindot':'\u22F5','isinE':'\u22F9','isins':'\u22F4','isinsv':'\u22F3','isinv':'\u2208','it':'\u2062','itilde':'\u0129','Itilde':'\u0128','iukcy':'\u0456','Iukcy':'\u0406','iuml':'\xEF','Iuml':'\xCF','jcirc':'\u0135','Jcirc':'\u0134','jcy':'\u0439','Jcy':'\u0419','jfr':'\uD835\uDD27','Jfr':'\uD835\uDD0D','jmath':'\u0237','jopf':'\uD835\uDD5B','Jopf':'\uD835\uDD41','jscr':'\uD835\uDCBF','Jscr':'\uD835\uDCA5','jsercy':'\u0458','Jsercy':'\u0408','jukcy':'\u0454','Jukcy':'\u0404','kappa':'\u03BA','Kappa':'\u039A','kappav':'\u03F0','kcedil':'\u0137','Kcedil':'\u0136','kcy':'\u043A','Kcy':'\u041A','kfr':'\uD835\uDD28','Kfr':'\uD835\uDD0E','kgreen':'\u0138','khcy':'\u0445','KHcy':'\u0425','kjcy':'\u045C','KJcy':'\u040C','kopf':'\uD835\uDD5C','Kopf':'\uD835\uDD42','kscr':'\uD835\uDCC0','Kscr':'\uD835\uDCA6','lAarr':'\u21DA','lacute':'\u013A','Lacute':'\u0139','laemptyv':'\u29B4','lagran':'\u2112','lambda':'\u03BB','Lambda':'\u039B','lang':'\u27E8','Lang':'\u27EA','langd':'\u2991','langle':'\u27E8','lap':'\u2A85','Laplacetrf':'\u2112','laquo':'\xAB','larr':'\u2190','lArr':'\u21D0','Larr':'\u219E','larrb':'\u21E4','larrbfs':'\u291F','larrfs':'\u291D','larrhk':'\u21A9','larrlp':'\u21AB','larrpl':'\u2939','larrsim':'\u2973','larrtl':'\u21A2','lat':'\u2AAB','latail':'\u2919','lAtail':'\u291B','late':'\u2AAD','lates':'\u2AAD\uFE00','lbarr':'\u290C','lBarr':'\u290E','lbbrk':'\u2772','lbrace':'{','lbrack':'[','lbrke':'\u298B','lbrksld':'\u298F','lbrkslu':'\u298D','lcaron':'\u013E','Lcaron':'\u013D','lcedil':'\u013C','Lcedil':'\u013B','lceil':'\u2308','lcub':'{','lcy':'\u043B','Lcy':'\u041B','ldca':'\u2936','ldquo':'\u201C','ldquor':'\u201E','ldrdhar':'\u2967','ldrushar':'\u294B','ldsh':'\u21B2','le':'\u2264','lE':'\u2266','LeftAngleBracket':'\u27E8','leftarrow':'\u2190','Leftarrow':'\u21D0','LeftArrow':'\u2190','LeftArrowBar':'\u21E4','LeftArrowRightArrow':'\u21C6','leftarrowtail':'\u21A2','LeftCeiling':'\u2308','LeftDoubleBracket':'\u27E6','LeftDownTeeVector':'\u2961','LeftDownVector':'\u21C3','LeftDownVectorBar':'\u2959','LeftFloor':'\u230A','leftharpoondown':'\u21BD','leftharpoonup':'\u21BC','leftleftarrows':'\u21C7','leftrightarrow':'\u2194','Leftrightarrow':'\u21D4','LeftRightArrow':'\u2194','leftrightarrows':'\u21C6','leftrightharpoons':'\u21CB','leftrightsquigarrow':'\u21AD','LeftRightVector':'\u294E','LeftTee':'\u22A3','LeftTeeArrow':'\u21A4','LeftTeeVector':'\u295A','leftthreetimes':'\u22CB','LeftTriangle':'\u22B2','LeftTriangleBar':'\u29CF','LeftTriangleEqual':'\u22B4','LeftUpDownVector':'\u2951','LeftUpTeeVector':'\u2960','LeftUpVector':'\u21BF','LeftUpVectorBar':'\u2958','LeftVector':'\u21BC','LeftVectorBar':'\u2952','leg':'\u22DA','lEg':'\u2A8B','leq':'\u2264','leqq':'\u2266','leqslant':'\u2A7D','les':'\u2A7D','lescc':'\u2AA8','lesdot':'\u2A7F','lesdoto':'\u2A81','lesdotor':'\u2A83','lesg':'\u22DA\uFE00','lesges':'\u2A93','lessapprox':'\u2A85','lessdot':'\u22D6','lesseqgtr':'\u22DA','lesseqqgtr':'\u2A8B','LessEqualGreater':'\u22DA','LessFullEqual':'\u2266','LessGreater':'\u2276','lessgtr':'\u2276','LessLess':'\u2AA1','lesssim':'\u2272','LessSlantEqual':'\u2A7D','LessTilde':'\u2272','lfisht':'\u297C','lfloor':'\u230A','lfr':'\uD835\uDD29','Lfr':'\uD835\uDD0F','lg':'\u2276','lgE':'\u2A91','lHar':'\u2962','lhard':'\u21BD','lharu':'\u21BC','lharul':'\u296A','lhblk':'\u2584','ljcy':'\u0459','LJcy':'\u0409','ll':'\u226A','Ll':'\u22D8','llarr':'\u21C7','llcorner':'\u231E','Lleftarrow':'\u21DA','llhard':'\u296B','lltri':'\u25FA','lmidot':'\u0140','Lmidot':'\u013F','lmoust':'\u23B0','lmoustache':'\u23B0','lnap':'\u2A89','lnapprox':'\u2A89','lne':'\u2A87','lnE':'\u2268','lneq':'\u2A87','lneqq':'\u2268','lnsim':'\u22E6','loang':'\u27EC','loarr':'\u21FD','lobrk':'\u27E6','longleftarrow':'\u27F5','Longleftarrow':'\u27F8','LongLeftArrow':'\u27F5','longleftrightarrow':'\u27F7','Longleftrightarrow':'\u27FA','LongLeftRightArrow':'\u27F7','longmapsto':'\u27FC','longrightarrow':'\u27F6','Longrightarrow':'\u27F9','LongRightArrow':'\u27F6','looparrowleft':'\u21AB','looparrowright':'\u21AC','lopar':'\u2985','lopf':'\uD835\uDD5D','Lopf':'\uD835\uDD43','loplus':'\u2A2D','lotimes':'\u2A34','lowast':'\u2217','lowbar':'_','LowerLeftArrow':'\u2199','LowerRightArrow':'\u2198','loz':'\u25CA','lozenge':'\u25CA','lozf':'\u29EB','lpar':'(','lparlt':'\u2993','lrarr':'\u21C6','lrcorner':'\u231F','lrhar':'\u21CB','lrhard':'\u296D','lrm':'\u200E','lrtri':'\u22BF','lsaquo':'\u2039','lscr':'\uD835\uDCC1','Lscr':'\u2112','lsh':'\u21B0','Lsh':'\u21B0','lsim':'\u2272','lsime':'\u2A8D','lsimg':'\u2A8F','lsqb':'[','lsquo':'\u2018','lsquor':'\u201A','lstrok':'\u0142','Lstrok':'\u0141','lt':'<','Lt':'\u226A','LT':'<','ltcc':'\u2AA6','ltcir':'\u2A79','ltdot':'\u22D6','lthree':'\u22CB','ltimes':'\u22C9','ltlarr':'\u2976','ltquest':'\u2A7B','ltri':'\u25C3','ltrie':'\u22B4','ltrif':'\u25C2','ltrPar':'\u2996','lurdshar':'\u294A','luruhar':'\u2966','lvertneqq':'\u2268\uFE00','lvnE':'\u2268\uFE00','macr':'\xAF','male':'\u2642','malt':'\u2720','maltese':'\u2720','map':'\u21A6','Map':'\u2905','mapsto':'\u21A6','mapstodown':'\u21A7','mapstoleft':'\u21A4','mapstoup':'\u21A5','marker':'\u25AE','mcomma':'\u2A29','mcy':'\u043C','Mcy':'\u041C','mdash':'\u2014','mDDot':'\u223A','measuredangle':'\u2221','MediumSpace':'\u205F','Mellintrf':'\u2133','mfr':'\uD835\uDD2A','Mfr':'\uD835\uDD10','mho':'\u2127','micro':'\xB5','mid':'\u2223','midast':'*','midcir':'\u2AF0','middot':'\xB7','minus':'\u2212','minusb':'\u229F','minusd':'\u2238','minusdu':'\u2A2A','MinusPlus':'\u2213','mlcp':'\u2ADB','mldr':'\u2026','mnplus':'\u2213','models':'\u22A7','mopf':'\uD835\uDD5E','Mopf':'\uD835\uDD44','mp':'\u2213','mscr':'\uD835\uDCC2','Mscr':'\u2133','mstpos':'\u223E','mu':'\u03BC','Mu':'\u039C','multimap':'\u22B8','mumap':'\u22B8','nabla':'\u2207','nacute':'\u0144','Nacute':'\u0143','nang':'\u2220\u20D2','nap':'\u2249','napE':'\u2A70\u0338','napid':'\u224B\u0338','napos':'\u0149','napprox':'\u2249','natur':'\u266E','natural':'\u266E','naturals':'\u2115','nbsp':'\xA0','nbump':'\u224E\u0338','nbumpe':'\u224F\u0338','ncap':'\u2A43','ncaron':'\u0148','Ncaron':'\u0147','ncedil':'\u0146','Ncedil':'\u0145','ncong':'\u2247','ncongdot':'\u2A6D\u0338','ncup':'\u2A42','ncy':'\u043D','Ncy':'\u041D','ndash':'\u2013','ne':'\u2260','nearhk':'\u2924','nearr':'\u2197','neArr':'\u21D7','nearrow':'\u2197','nedot':'\u2250\u0338','NegativeMediumSpace':'\u200B','NegativeThickSpace':'\u200B','NegativeThinSpace':'\u200B','NegativeVeryThinSpace':'\u200B','nequiv':'\u2262','nesear':'\u2928','nesim':'\u2242\u0338','NestedGreaterGreater':'\u226B','NestedLessLess':'\u226A','NewLine':'\n','nexist':'\u2204','nexists':'\u2204','nfr':'\uD835\uDD2B','Nfr':'\uD835\uDD11','nge':'\u2271','ngE':'\u2267\u0338','ngeq':'\u2271','ngeqq':'\u2267\u0338','ngeqslant':'\u2A7E\u0338','nges':'\u2A7E\u0338','nGg':'\u22D9\u0338','ngsim':'\u2275','ngt':'\u226F','nGt':'\u226B\u20D2','ngtr':'\u226F','nGtv':'\u226B\u0338','nharr':'\u21AE','nhArr':'\u21CE','nhpar':'\u2AF2','ni':'\u220B','nis':'\u22FC','nisd':'\u22FA','niv':'\u220B','njcy':'\u045A','NJcy':'\u040A','nlarr':'\u219A','nlArr':'\u21CD','nldr':'\u2025','nle':'\u2270','nlE':'\u2266\u0338','nleftarrow':'\u219A','nLeftarrow':'\u21CD','nleftrightarrow':'\u21AE','nLeftrightarrow':'\u21CE','nleq':'\u2270','nleqq':'\u2266\u0338','nleqslant':'\u2A7D\u0338','nles':'\u2A7D\u0338','nless':'\u226E','nLl':'\u22D8\u0338','nlsim':'\u2274','nlt':'\u226E','nLt':'\u226A\u20D2','nltri':'\u22EA','nltrie':'\u22EC','nLtv':'\u226A\u0338','nmid':'\u2224','NoBreak':'\u2060','NonBreakingSpace':'\xA0','nopf':'\uD835\uDD5F','Nopf':'\u2115','not':'\xAC','Not':'\u2AEC','NotCongruent':'\u2262','NotCupCap':'\u226D','NotDoubleVerticalBar':'\u2226','NotElement':'\u2209','NotEqual':'\u2260','NotEqualTilde':'\u2242\u0338','NotExists':'\u2204','NotGreater':'\u226F','NotGreaterEqual':'\u2271','NotGreaterFullEqual':'\u2267\u0338','NotGreaterGreater':'\u226B\u0338','NotGreaterLess':'\u2279','NotGreaterSlantEqual':'\u2A7E\u0338','NotGreaterTilde':'\u2275','NotHumpDownHump':'\u224E\u0338','NotHumpEqual':'\u224F\u0338','notin':'\u2209','notindot':'\u22F5\u0338','notinE':'\u22F9\u0338','notinva':'\u2209','notinvb':'\u22F7','notinvc':'\u22F6','NotLeftTriangle':'\u22EA','NotLeftTriangleBar':'\u29CF\u0338','NotLeftTriangleEqual':'\u22EC','NotLess':'\u226E','NotLessEqual':'\u2270','NotLessGreater':'\u2278','NotLessLess':'\u226A\u0338','NotLessSlantEqual':'\u2A7D\u0338','NotLessTilde':'\u2274','NotNestedGreaterGreater':'\u2AA2\u0338','NotNestedLessLess':'\u2AA1\u0338','notni':'\u220C','notniva':'\u220C','notnivb':'\u22FE','notnivc':'\u22FD','NotPrecedes':'\u2280','NotPrecedesEqual':'\u2AAF\u0338','NotPrecedesSlantEqual':'\u22E0','NotReverseElement':'\u220C','NotRightTriangle':'\u22EB','NotRightTriangleBar':'\u29D0\u0338','NotRightTriangleEqual':'\u22ED','NotSquareSubset':'\u228F\u0338','NotSquareSubsetEqual':'\u22E2','NotSquareSuperset':'\u2290\u0338','NotSquareSupersetEqual':'\u22E3','NotSubset':'\u2282\u20D2','NotSubsetEqual':'\u2288','NotSucceeds':'\u2281','NotSucceedsEqual':'\u2AB0\u0338','NotSucceedsSlantEqual':'\u22E1','NotSucceedsTilde':'\u227F\u0338','NotSuperset':'\u2283\u20D2','NotSupersetEqual':'\u2289','NotTilde':'\u2241','NotTildeEqual':'\u2244','NotTildeFullEqual':'\u2247','NotTildeTilde':'\u2249','NotVerticalBar':'\u2224','npar':'\u2226','nparallel':'\u2226','nparsl':'\u2AFD\u20E5','npart':'\u2202\u0338','npolint':'\u2A14','npr':'\u2280','nprcue':'\u22E0','npre':'\u2AAF\u0338','nprec':'\u2280','npreceq':'\u2AAF\u0338','nrarr':'\u219B','nrArr':'\u21CF','nrarrc':'\u2933\u0338','nrarrw':'\u219D\u0338','nrightarrow':'\u219B','nRightarrow':'\u21CF','nrtri':'\u22EB','nrtrie':'\u22ED','nsc':'\u2281','nsccue':'\u22E1','nsce':'\u2AB0\u0338','nscr':'\uD835\uDCC3','Nscr':'\uD835\uDCA9','nshortmid':'\u2224','nshortparallel':'\u2226','nsim':'\u2241','nsime':'\u2244','nsimeq':'\u2244','nsmid':'\u2224','nspar':'\u2226','nsqsube':'\u22E2','nsqsupe':'\u22E3','nsub':'\u2284','nsube':'\u2288','nsubE':'\u2AC5\u0338','nsubset':'\u2282\u20D2','nsubseteq':'\u2288','nsubseteqq':'\u2AC5\u0338','nsucc':'\u2281','nsucceq':'\u2AB0\u0338','nsup':'\u2285','nsupe':'\u2289','nsupE':'\u2AC6\u0338','nsupset':'\u2283\u20D2','nsupseteq':'\u2289','nsupseteqq':'\u2AC6\u0338','ntgl':'\u2279','ntilde':'\xF1','Ntilde':'\xD1','ntlg':'\u2278','ntriangleleft':'\u22EA','ntrianglelefteq':'\u22EC','ntriangleright':'\u22EB','ntrianglerighteq':'\u22ED','nu':'\u03BD','Nu':'\u039D','num':'#','numero':'\u2116','numsp':'\u2007','nvap':'\u224D\u20D2','nvdash':'\u22AC','nvDash':'\u22AD','nVdash':'\u22AE','nVDash':'\u22AF','nvge':'\u2265\u20D2','nvgt':'>\u20D2','nvHarr':'\u2904','nvinfin':'\u29DE','nvlArr':'\u2902','nvle':'\u2264\u20D2','nvlt':'<\u20D2','nvltrie':'\u22B4\u20D2','nvrArr':'\u2903','nvrtrie':'\u22B5\u20D2','nvsim':'\u223C\u20D2','nwarhk':'\u2923','nwarr':'\u2196','nwArr':'\u21D6','nwarrow':'\u2196','nwnear':'\u2927','oacute':'\xF3','Oacute':'\xD3','oast':'\u229B','ocir':'\u229A','ocirc':'\xF4','Ocirc':'\xD4','ocy':'\u043E','Ocy':'\u041E','odash':'\u229D','odblac':'\u0151','Odblac':'\u0150','odiv':'\u2A38','odot':'\u2299','odsold':'\u29BC','oelig':'\u0153','OElig':'\u0152','ofcir':'\u29BF','ofr':'\uD835\uDD2C','Ofr':'\uD835\uDD12','ogon':'\u02DB','ograve':'\xF2','Ograve':'\xD2','ogt':'\u29C1','ohbar':'\u29B5','ohm':'\u03A9','oint':'\u222E','olarr':'\u21BA','olcir':'\u29BE','olcross':'\u29BB','oline':'\u203E','olt':'\u29C0','omacr':'\u014D','Omacr':'\u014C','omega':'\u03C9','Omega':'\u03A9','omicron':'\u03BF','Omicron':'\u039F','omid':'\u29B6','ominus':'\u2296','oopf':'\uD835\uDD60','Oopf':'\uD835\uDD46','opar':'\u29B7','OpenCurlyDoubleQuote':'\u201C','OpenCurlyQuote':'\u2018','operp':'\u29B9','oplus':'\u2295','or':'\u2228','Or':'\u2A54','orarr':'\u21BB','ord':'\u2A5D','order':'\u2134','orderof':'\u2134','ordf':'\xAA','ordm':'\xBA','origof':'\u22B6','oror':'\u2A56','orslope':'\u2A57','orv':'\u2A5B','oS':'\u24C8','oscr':'\u2134','Oscr':'\uD835\uDCAA','oslash':'\xF8','Oslash':'\xD8','osol':'\u2298','otilde':'\xF5','Otilde':'\xD5','otimes':'\u2297','Otimes':'\u2A37','otimesas':'\u2A36','ouml':'\xF6','Ouml':'\xD6','ovbar':'\u233D','OverBar':'\u203E','OverBrace':'\u23DE','OverBracket':'\u23B4','OverParenthesis':'\u23DC','par':'\u2225','para':'\xB6','parallel':'\u2225','parsim':'\u2AF3','parsl':'\u2AFD','part':'\u2202','PartialD':'\u2202','pcy':'\u043F','Pcy':'\u041F','percnt':'%','period':'.','permil':'\u2030','perp':'\u22A5','pertenk':'\u2031','pfr':'\uD835\uDD2D','Pfr':'\uD835\uDD13','phi':'\u03C6','Phi':'\u03A6','phiv':'\u03D5','phmmat':'\u2133','phone':'\u260E','pi':'\u03C0','Pi':'\u03A0','pitchfork':'\u22D4','piv':'\u03D6','planck':'\u210F','planckh':'\u210E','plankv':'\u210F','plus':'+','plusacir':'\u2A23','plusb':'\u229E','pluscir':'\u2A22','plusdo':'\u2214','plusdu':'\u2A25','pluse':'\u2A72','PlusMinus':'\xB1','plusmn':'\xB1','plussim':'\u2A26','plustwo':'\u2A27','pm':'\xB1','Poincareplane':'\u210C','pointint':'\u2A15','popf':'\uD835\uDD61','Popf':'\u2119','pound':'\xA3','pr':'\u227A','Pr':'\u2ABB','prap':'\u2AB7','prcue':'\u227C','pre':'\u2AAF','prE':'\u2AB3','prec':'\u227A','precapprox':'\u2AB7','preccurlyeq':'\u227C','Precedes':'\u227A','PrecedesEqual':'\u2AAF','PrecedesSlantEqual':'\u227C','PrecedesTilde':'\u227E','preceq':'\u2AAF','precnapprox':'\u2AB9','precneqq':'\u2AB5','precnsim':'\u22E8','precsim':'\u227E','prime':'\u2032','Prime':'\u2033','primes':'\u2119','prnap':'\u2AB9','prnE':'\u2AB5','prnsim':'\u22E8','prod':'\u220F','Product':'\u220F','profalar':'\u232E','profline':'\u2312','profsurf':'\u2313','prop':'\u221D','Proportion':'\u2237','Proportional':'\u221D','propto':'\u221D','prsim':'\u227E','prurel':'\u22B0','pscr':'\uD835\uDCC5','Pscr':'\uD835\uDCAB','psi':'\u03C8','Psi':'\u03A8','puncsp':'\u2008','qfr':'\uD835\uDD2E','Qfr':'\uD835\uDD14','qint':'\u2A0C','qopf':'\uD835\uDD62','Qopf':'\u211A','qprime':'\u2057','qscr':'\uD835\uDCC6','Qscr':'\uD835\uDCAC','quaternions':'\u210D','quatint':'\u2A16','quest':'?','questeq':'\u225F','quot':'"','QUOT':'"','rAarr':'\u21DB','race':'\u223D\u0331','racute':'\u0155','Racute':'\u0154','radic':'\u221A','raemptyv':'\u29B3','rang':'\u27E9','Rang':'\u27EB','rangd':'\u2992','range':'\u29A5','rangle':'\u27E9','raquo':'\xBB','rarr':'\u2192','rArr':'\u21D2','Rarr':'\u21A0','rarrap':'\u2975','rarrb':'\u21E5','rarrbfs':'\u2920','rarrc':'\u2933','rarrfs':'\u291E','rarrhk':'\u21AA','rarrlp':'\u21AC','rarrpl':'\u2945','rarrsim':'\u2974','rarrtl':'\u21A3','Rarrtl':'\u2916','rarrw':'\u219D','ratail':'\u291A','rAtail':'\u291C','ratio':'\u2236','rationals':'\u211A','rbarr':'\u290D','rBarr':'\u290F','RBarr':'\u2910','rbbrk':'\u2773','rbrace':'}','rbrack':']','rbrke':'\u298C','rbrksld':'\u298E','rbrkslu':'\u2990','rcaron':'\u0159','Rcaron':'\u0158','rcedil':'\u0157','Rcedil':'\u0156','rceil':'\u2309','rcub':'}','rcy':'\u0440','Rcy':'\u0420','rdca':'\u2937','rdldhar':'\u2969','rdquo':'\u201D','rdquor':'\u201D','rdsh':'\u21B3','Re':'\u211C','real':'\u211C','realine':'\u211B','realpart':'\u211C','reals':'\u211D','rect':'\u25AD','reg':'\xAE','REG':'\xAE','ReverseElement':'\u220B','ReverseEquilibrium':'\u21CB','ReverseUpEquilibrium':'\u296F','rfisht':'\u297D','rfloor':'\u230B','rfr':'\uD835\uDD2F','Rfr':'\u211C','rHar':'\u2964','rhard':'\u21C1','rharu':'\u21C0','rharul':'\u296C','rho':'\u03C1','Rho':'\u03A1','rhov':'\u03F1','RightAngleBracket':'\u27E9','rightarrow':'\u2192','Rightarrow':'\u21D2','RightArrow':'\u2192','RightArrowBar':'\u21E5','RightArrowLeftArrow':'\u21C4','rightarrowtail':'\u21A3','RightCeiling':'\u2309','RightDoubleBracket':'\u27E7','RightDownTeeVector':'\u295D','RightDownVector':'\u21C2','RightDownVectorBar':'\u2955','RightFloor':'\u230B','rightharpoondown':'\u21C1','rightharpoonup':'\u21C0','rightleftarrows':'\u21C4','rightleftharpoons':'\u21CC','rightrightarrows':'\u21C9','rightsquigarrow':'\u219D','RightTee':'\u22A2','RightTeeArrow':'\u21A6','RightTeeVector':'\u295B','rightthreetimes':'\u22CC','RightTriangle':'\u22B3','RightTriangleBar':'\u29D0','RightTriangleEqual':'\u22B5','RightUpDownVector':'\u294F','RightUpTeeVector':'\u295C','RightUpVector':'\u21BE','RightUpVectorBar':'\u2954','RightVector':'\u21C0','RightVectorBar':'\u2953','ring':'\u02DA','risingdotseq':'\u2253','rlarr':'\u21C4','rlhar':'\u21CC','rlm':'\u200F','rmoust':'\u23B1','rmoustache':'\u23B1','rnmid':'\u2AEE','roang':'\u27ED','roarr':'\u21FE','robrk':'\u27E7','ropar':'\u2986','ropf':'\uD835\uDD63','Ropf':'\u211D','roplus':'\u2A2E','rotimes':'\u2A35','RoundImplies':'\u2970','rpar':')','rpargt':'\u2994','rppolint':'\u2A12','rrarr':'\u21C9','Rrightarrow':'\u21DB','rsaquo':'\u203A','rscr':'\uD835\uDCC7','Rscr':'\u211B','rsh':'\u21B1','Rsh':'\u21B1','rsqb':']','rsquo':'\u2019','rsquor':'\u2019','rthree':'\u22CC','rtimes':'\u22CA','rtri':'\u25B9','rtrie':'\u22B5','rtrif':'\u25B8','rtriltri':'\u29CE','RuleDelayed':'\u29F4','ruluhar':'\u2968','rx':'\u211E','sacute':'\u015B','Sacute':'\u015A','sbquo':'\u201A','sc':'\u227B','Sc':'\u2ABC','scap':'\u2AB8','scaron':'\u0161','Scaron':'\u0160','sccue':'\u227D','sce':'\u2AB0','scE':'\u2AB4','scedil':'\u015F','Scedil':'\u015E','scirc':'\u015D','Scirc':'\u015C','scnap':'\u2ABA','scnE':'\u2AB6','scnsim':'\u22E9','scpolint':'\u2A13','scsim':'\u227F','scy':'\u0441','Scy':'\u0421','sdot':'\u22C5','sdotb':'\u22A1','sdote':'\u2A66','searhk':'\u2925','searr':'\u2198','seArr':'\u21D8','searrow':'\u2198','sect':'\xA7','semi':';','seswar':'\u2929','setminus':'\u2216','setmn':'\u2216','sext':'\u2736','sfr':'\uD835\uDD30','Sfr':'\uD835\uDD16','sfrown':'\u2322','sharp':'\u266F','shchcy':'\u0449','SHCHcy':'\u0429','shcy':'\u0448','SHcy':'\u0428','ShortDownArrow':'\u2193','ShortLeftArrow':'\u2190','shortmid':'\u2223','shortparallel':'\u2225','ShortRightArrow':'\u2192','ShortUpArrow':'\u2191','shy':'\xAD','sigma':'\u03C3','Sigma':'\u03A3','sigmaf':'\u03C2','sigmav':'\u03C2','sim':'\u223C','simdot':'\u2A6A','sime':'\u2243','simeq':'\u2243','simg':'\u2A9E','simgE':'\u2AA0','siml':'\u2A9D','simlE':'\u2A9F','simne':'\u2246','simplus':'\u2A24','simrarr':'\u2972','slarr':'\u2190','SmallCircle':'\u2218','smallsetminus':'\u2216','smashp':'\u2A33','smeparsl':'\u29E4','smid':'\u2223','smile':'\u2323','smt':'\u2AAA','smte':'\u2AAC','smtes':'\u2AAC\uFE00','softcy':'\u044C','SOFTcy':'\u042C','sol':'/','solb':'\u29C4','solbar':'\u233F','sopf':'\uD835\uDD64','Sopf':'\uD835\uDD4A','spades':'\u2660','spadesuit':'\u2660','spar':'\u2225','sqcap':'\u2293','sqcaps':'\u2293\uFE00','sqcup':'\u2294','sqcups':'\u2294\uFE00','Sqrt':'\u221A','sqsub':'\u228F','sqsube':'\u2291','sqsubset':'\u228F','sqsubseteq':'\u2291','sqsup':'\u2290','sqsupe':'\u2292','sqsupset':'\u2290','sqsupseteq':'\u2292','squ':'\u25A1','square':'\u25A1','Square':'\u25A1','SquareIntersection':'\u2293','SquareSubset':'\u228F','SquareSubsetEqual':'\u2291','SquareSuperset':'\u2290','SquareSupersetEqual':'\u2292','SquareUnion':'\u2294','squarf':'\u25AA','squf':'\u25AA','srarr':'\u2192','sscr':'\uD835\uDCC8','Sscr':'\uD835\uDCAE','ssetmn':'\u2216','ssmile':'\u2323','sstarf':'\u22C6','star':'\u2606','Star':'\u22C6','starf':'\u2605','straightepsilon':'\u03F5','straightphi':'\u03D5','strns':'\xAF','sub':'\u2282','Sub':'\u22D0','subdot':'\u2ABD','sube':'\u2286','subE':'\u2AC5','subedot':'\u2AC3','submult':'\u2AC1','subne':'\u228A','subnE':'\u2ACB','subplus':'\u2ABF','subrarr':'\u2979','subset':'\u2282','Subset':'\u22D0','subseteq':'\u2286','subseteqq':'\u2AC5','SubsetEqual':'\u2286','subsetneq':'\u228A','subsetneqq':'\u2ACB','subsim':'\u2AC7','subsub':'\u2AD5','subsup':'\u2AD3','succ':'\u227B','succapprox':'\u2AB8','succcurlyeq':'\u227D','Succeeds':'\u227B','SucceedsEqual':'\u2AB0','SucceedsSlantEqual':'\u227D','SucceedsTilde':'\u227F','succeq':'\u2AB0','succnapprox':'\u2ABA','succneqq':'\u2AB6','succnsim':'\u22E9','succsim':'\u227F','SuchThat':'\u220B','sum':'\u2211','Sum':'\u2211','sung':'\u266A','sup':'\u2283','Sup':'\u22D1','sup1':'\xB9','sup2':'\xB2','sup3':'\xB3','supdot':'\u2ABE','supdsub':'\u2AD8','supe':'\u2287','supE':'\u2AC6','supedot':'\u2AC4','Superset':'\u2283','SupersetEqual':'\u2287','suphsol':'\u27C9','suphsub':'\u2AD7','suplarr':'\u297B','supmult':'\u2AC2','supne':'\u228B','supnE':'\u2ACC','supplus':'\u2AC0','supset':'\u2283','Supset':'\u22D1','supseteq':'\u2287','supseteqq':'\u2AC6','supsetneq':'\u228B','supsetneqq':'\u2ACC','supsim':'\u2AC8','supsub':'\u2AD4','supsup':'\u2AD6','swarhk':'\u2926','swarr':'\u2199','swArr':'\u21D9','swarrow':'\u2199','swnwar':'\u292A','szlig':'\xDF','Tab':'\t','target':'\u2316','tau':'\u03C4','Tau':'\u03A4','tbrk':'\u23B4','tcaron':'\u0165','Tcaron':'\u0164','tcedil':'\u0163','Tcedil':'\u0162','tcy':'\u0442','Tcy':'\u0422','tdot':'\u20DB','telrec':'\u2315','tfr':'\uD835\uDD31','Tfr':'\uD835\uDD17','there4':'\u2234','therefore':'\u2234','Therefore':'\u2234','theta':'\u03B8','Theta':'\u0398','thetasym':'\u03D1','thetav':'\u03D1','thickapprox':'\u2248','thicksim':'\u223C','ThickSpace':'\u205F\u200A','thinsp':'\u2009','ThinSpace':'\u2009','thkap':'\u2248','thksim':'\u223C','thorn':'\xFE','THORN':'\xDE','tilde':'\u02DC','Tilde':'\u223C','TildeEqual':'\u2243','TildeFullEqual':'\u2245','TildeTilde':'\u2248','times':'\xD7','timesb':'\u22A0','timesbar':'\u2A31','timesd':'\u2A30','tint':'\u222D','toea':'\u2928','top':'\u22A4','topbot':'\u2336','topcir':'\u2AF1','topf':'\uD835\uDD65','Topf':'\uD835\uDD4B','topfork':'\u2ADA','tosa':'\u2929','tprime':'\u2034','trade':'\u2122','TRADE':'\u2122','triangle':'\u25B5','triangledown':'\u25BF','triangleleft':'\u25C3','trianglelefteq':'\u22B4','triangleq':'\u225C','triangleright':'\u25B9','trianglerighteq':'\u22B5','tridot':'\u25EC','trie':'\u225C','triminus':'\u2A3A','TripleDot':'\u20DB','triplus':'\u2A39','trisb':'\u29CD','tritime':'\u2A3B','trpezium':'\u23E2','tscr':'\uD835\uDCC9','Tscr':'\uD835\uDCAF','tscy':'\u0446','TScy':'\u0426','tshcy':'\u045B','TSHcy':'\u040B','tstrok':'\u0167','Tstrok':'\u0166','twixt':'\u226C','twoheadleftarrow':'\u219E','twoheadrightarrow':'\u21A0','uacute':'\xFA','Uacute':'\xDA','uarr':'\u2191','uArr':'\u21D1','Uarr':'\u219F','Uarrocir':'\u2949','ubrcy':'\u045E','Ubrcy':'\u040E','ubreve':'\u016D','Ubreve':'\u016C','ucirc':'\xFB','Ucirc':'\xDB','ucy':'\u0443','Ucy':'\u0423','udarr':'\u21C5','udblac':'\u0171','Udblac':'\u0170','udhar':'\u296E','ufisht':'\u297E','ufr':'\uD835\uDD32','Ufr':'\uD835\uDD18','ugrave':'\xF9','Ugrave':'\xD9','uHar':'\u2963','uharl':'\u21BF','uharr':'\u21BE','uhblk':'\u2580','ulcorn':'\u231C','ulcorner':'\u231C','ulcrop':'\u230F','ultri':'\u25F8','umacr':'\u016B','Umacr':'\u016A','uml':'\xA8','UnderBar':'_','UnderBrace':'\u23DF','UnderBracket':'\u23B5','UnderParenthesis':'\u23DD','Union':'\u22C3','UnionPlus':'\u228E','uogon':'\u0173','Uogon':'\u0172','uopf':'\uD835\uDD66','Uopf':'\uD835\uDD4C','uparrow':'\u2191','Uparrow':'\u21D1','UpArrow':'\u2191','UpArrowBar':'\u2912','UpArrowDownArrow':'\u21C5','updownarrow':'\u2195','Updownarrow':'\u21D5','UpDownArrow':'\u2195','UpEquilibrium':'\u296E','upharpoonleft':'\u21BF','upharpoonright':'\u21BE','uplus':'\u228E','UpperLeftArrow':'\u2196','UpperRightArrow':'\u2197','upsi':'\u03C5','Upsi':'\u03D2','upsih':'\u03D2','upsilon':'\u03C5','Upsilon':'\u03A5','UpTee':'\u22A5','UpTeeArrow':'\u21A5','upuparrows':'\u21C8','urcorn':'\u231D','urcorner':'\u231D','urcrop':'\u230E','uring':'\u016F','Uring':'\u016E','urtri':'\u25F9','uscr':'\uD835\uDCCA','Uscr':'\uD835\uDCB0','utdot':'\u22F0','utilde':'\u0169','Utilde':'\u0168','utri':'\u25B5','utrif':'\u25B4','uuarr':'\u21C8','uuml':'\xFC','Uuml':'\xDC','uwangle':'\u29A7','vangrt':'\u299C','varepsilon':'\u03F5','varkappa':'\u03F0','varnothing':'\u2205','varphi':'\u03D5','varpi':'\u03D6','varpropto':'\u221D','varr':'\u2195','vArr':'\u21D5','varrho':'\u03F1','varsigma':'\u03C2','varsubsetneq':'\u228A\uFE00','varsubsetneqq':'\u2ACB\uFE00','varsupsetneq':'\u228B\uFE00','varsupsetneqq':'\u2ACC\uFE00','vartheta':'\u03D1','vartriangleleft':'\u22B2','vartriangleright':'\u22B3','vBar':'\u2AE8','Vbar':'\u2AEB','vBarv':'\u2AE9','vcy':'\u0432','Vcy':'\u0412','vdash':'\u22A2','vDash':'\u22A8','Vdash':'\u22A9','VDash':'\u22AB','Vdashl':'\u2AE6','vee':'\u2228','Vee':'\u22C1','veebar':'\u22BB','veeeq':'\u225A','vellip':'\u22EE','verbar':'|','Verbar':'\u2016','vert':'|','Vert':'\u2016','VerticalBar':'\u2223','VerticalLine':'|','VerticalSeparator':'\u2758','VerticalTilde':'\u2240','VeryThinSpace':'\u200A','vfr':'\uD835\uDD33','Vfr':'\uD835\uDD19','vltri':'\u22B2','vnsub':'\u2282\u20D2','vnsup':'\u2283\u20D2','vopf':'\uD835\uDD67','Vopf':'\uD835\uDD4D','vprop':'\u221D','vrtri':'\u22B3','vscr':'\uD835\uDCCB','Vscr':'\uD835\uDCB1','vsubne':'\u228A\uFE00','vsubnE':'\u2ACB\uFE00','vsupne':'\u228B\uFE00','vsupnE':'\u2ACC\uFE00','Vvdash':'\u22AA','vzigzag':'\u299A','wcirc':'\u0175','Wcirc':'\u0174','wedbar':'\u2A5F','wedge':'\u2227','Wedge':'\u22C0','wedgeq':'\u2259','weierp':'\u2118','wfr':'\uD835\uDD34','Wfr':'\uD835\uDD1A','wopf':'\uD835\uDD68','Wopf':'\uD835\uDD4E','wp':'\u2118','wr':'\u2240','wreath':'\u2240','wscr':'\uD835\uDCCC','Wscr':'\uD835\uDCB2','xcap':'\u22C2','xcirc':'\u25EF','xcup':'\u22C3','xdtri':'\u25BD','xfr':'\uD835\uDD35','Xfr':'\uD835\uDD1B','xharr':'\u27F7','xhArr':'\u27FA','xi':'\u03BE','Xi':'\u039E','xlarr':'\u27F5','xlArr':'\u27F8','xmap':'\u27FC','xnis':'\u22FB','xodot':'\u2A00','xopf':'\uD835\uDD69','Xopf':'\uD835\uDD4F','xoplus':'\u2A01','xotime':'\u2A02','xrarr':'\u27F6','xrArr':'\u27F9','xscr':'\uD835\uDCCD','Xscr':'\uD835\uDCB3','xsqcup':'\u2A06','xuplus':'\u2A04','xutri':'\u25B3','xvee':'\u22C1','xwedge':'\u22C0','yacute':'\xFD','Yacute':'\xDD','yacy':'\u044F','YAcy':'\u042F','ycirc':'\u0177','Ycirc':'\u0176','ycy':'\u044B','Ycy':'\u042B','yen':'\xA5','yfr':'\uD835\uDD36','Yfr':'\uD835\uDD1C','yicy':'\u0457','YIcy':'\u0407','yopf':'\uD835\uDD6A','Yopf':'\uD835\uDD50','yscr':'\uD835\uDCCE','Yscr':'\uD835\uDCB4','yucy':'\u044E','YUcy':'\u042E','yuml':'\xFF','Yuml':'\u0178','zacute':'\u017A','Zacute':'\u0179','zcaron':'\u017E','Zcaron':'\u017D','zcy':'\u0437','Zcy':'\u0417','zdot':'\u017C','Zdot':'\u017B','zeetrf':'\u2128','ZeroWidthSpace':'\u200B','zeta':'\u03B6','Zeta':'\u0396','zfr':'\uD835\uDD37','Zfr':'\u2128','zhcy':'\u0436','ZHcy':'\u0416','zigrarr':'\u21DD','zopf':'\uD835\uDD6B','Zopf':'\u2124','zscr':'\uD835\uDCCF','Zscr':'\uD835\uDCB5','zwj':'\u200D','zwnj':'\u200C'}; + var decodeMapLegacy = {'aacute':'\xE1','Aacute':'\xC1','acirc':'\xE2','Acirc':'\xC2','acute':'\xB4','aelig':'\xE6','AElig':'\xC6','agrave':'\xE0','Agrave':'\xC0','amp':'&','AMP':'&','aring':'\xE5','Aring':'\xC5','atilde':'\xE3','Atilde':'\xC3','auml':'\xE4','Auml':'\xC4','brvbar':'\xA6','ccedil':'\xE7','Ccedil':'\xC7','cedil':'\xB8','cent':'\xA2','copy':'\xA9','COPY':'\xA9','curren':'\xA4','deg':'\xB0','divide':'\xF7','eacute':'\xE9','Eacute':'\xC9','ecirc':'\xEA','Ecirc':'\xCA','egrave':'\xE8','Egrave':'\xC8','eth':'\xF0','ETH':'\xD0','euml':'\xEB','Euml':'\xCB','frac12':'\xBD','frac14':'\xBC','frac34':'\xBE','gt':'>','GT':'>','iacute':'\xED','Iacute':'\xCD','icirc':'\xEE','Icirc':'\xCE','iexcl':'\xA1','igrave':'\xEC','Igrave':'\xCC','iquest':'\xBF','iuml':'\xEF','Iuml':'\xCF','laquo':'\xAB','lt':'<','LT':'<','macr':'\xAF','micro':'\xB5','middot':'\xB7','nbsp':'\xA0','not':'\xAC','ntilde':'\xF1','Ntilde':'\xD1','oacute':'\xF3','Oacute':'\xD3','ocirc':'\xF4','Ocirc':'\xD4','ograve':'\xF2','Ograve':'\xD2','ordf':'\xAA','ordm':'\xBA','oslash':'\xF8','Oslash':'\xD8','otilde':'\xF5','Otilde':'\xD5','ouml':'\xF6','Ouml':'\xD6','para':'\xB6','plusmn':'\xB1','pound':'\xA3','quot':'"','QUOT':'"','raquo':'\xBB','reg':'\xAE','REG':'\xAE','sect':'\xA7','shy':'\xAD','sup1':'\xB9','sup2':'\xB2','sup3':'\xB3','szlig':'\xDF','thorn':'\xFE','THORN':'\xDE','times':'\xD7','uacute':'\xFA','Uacute':'\xDA','ucirc':'\xFB','Ucirc':'\xDB','ugrave':'\xF9','Ugrave':'\xD9','uml':'\xA8','uuml':'\xFC','Uuml':'\xDC','yacute':'\xFD','Yacute':'\xDD','yen':'\xA5','yuml':'\xFF'}; + var decodeMapNumeric = {'0':'\uFFFD','128':'\u20AC','130':'\u201A','131':'\u0192','132':'\u201E','133':'\u2026','134':'\u2020','135':'\u2021','136':'\u02C6','137':'\u2030','138':'\u0160','139':'\u2039','140':'\u0152','142':'\u017D','145':'\u2018','146':'\u2019','147':'\u201C','148':'\u201D','149':'\u2022','150':'\u2013','151':'\u2014','152':'\u02DC','153':'\u2122','154':'\u0161','155':'\u203A','156':'\u0153','158':'\u017E','159':'\u0178'}; + var invalidReferenceCodePoints = [1,2,3,4,5,6,7,8,11,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,64976,64977,64978,64979,64980,64981,64982,64983,64984,64985,64986,64987,64988,64989,64990,64991,64992,64993,64994,64995,64996,64997,64998,64999,65000,65001,65002,65003,65004,65005,65006,65007,65534,65535,131070,131071,196606,196607,262142,262143,327678,327679,393214,393215,458750,458751,524286,524287,589822,589823,655358,655359,720894,720895,786430,786431,851966,851967,917502,917503,983038,983039,1048574,1048575,1114110,1114111]; + + /*--------------------------------------------------------------------------*/ + + var stringFromCharCode = String.fromCharCode; + + var object = {}; + var hasOwnProperty = object.hasOwnProperty; + var has = function(object, propertyName) { + return hasOwnProperty.call(object, propertyName); + }; + + var contains = function(array, value) { + var index = -1; + var length = array.length; + while (++index < length) { + if (array[index] == value) { + return true; + } + } + return false; + }; + + var merge = function(options, defaults) { + if (!options) { + return defaults; + } + var result = {}; + var key; + for (key in defaults) { + // A `hasOwnProperty` check is not needed here, since only recognized + // option names are used anyway. Any others are ignored. + result[key] = has(options, key) ? options[key] : defaults[key]; + } + return result; + }; + + // Modified version of `ucs2encode`; see https://mths.be/punycode. + var codePointToSymbol = function(codePoint, strict) { + var output = ''; + if ((codePoint >= 0xD800 && codePoint <= 0xDFFF) || codePoint > 0x10FFFF) { + // See issue #4: + // “Otherwise, if the number is in the range 0xD800 to 0xDFFF or is + // greater than 0x10FFFF, then this is a parse error. Return a U+FFFD + // REPLACEMENT CHARACTER.” + if (strict) { + parseError('character reference outside the permissible Unicode range'); + } + return '\uFFFD'; + } + if (has(decodeMapNumeric, codePoint)) { + if (strict) { + parseError('disallowed character reference'); + } + return decodeMapNumeric[codePoint]; + } + if (strict && contains(invalidReferenceCodePoints, codePoint)) { + parseError('disallowed character reference'); + } + if (codePoint > 0xFFFF) { + codePoint -= 0x10000; + output += stringFromCharCode(codePoint >>> 10 & 0x3FF | 0xD800); + codePoint = 0xDC00 | codePoint & 0x3FF; + } + output += stringFromCharCode(codePoint); + return output; + }; + + var hexEscape = function(codePoint) { + return '&#x' + codePoint.toString(16).toUpperCase() + ';'; + }; + + var decEscape = function(codePoint) { + return '&#' + codePoint + ';'; + }; + + var parseError = function(message) { + throw Error('Parse error: ' + message); + }; + + /*--------------------------------------------------------------------------*/ + + var encode = function(string, options) { + options = merge(options, encode.options); + var strict = options.strict; + if (strict && regexInvalidRawCodePoint.test(string)) { + parseError('forbidden code point'); + } + var encodeEverything = options.encodeEverything; + var useNamedReferences = options.useNamedReferences; + var allowUnsafeSymbols = options.allowUnsafeSymbols; + var escapeCodePoint = options.decimal ? decEscape : hexEscape; + + var escapeBmpSymbol = function(symbol) { + return escapeCodePoint(symbol.charCodeAt(0)); + }; + + if (encodeEverything) { + // Encode ASCII symbols. + string = string.replace(regexAsciiWhitelist, function(symbol) { + // Use named references if requested & possible. + if (useNamedReferences && has(encodeMap, symbol)) { + return '&' + encodeMap[symbol] + ';'; + } + return escapeBmpSymbol(symbol); + }); + // Shorten a few escapes that represent two symbols, of which at least one + // is within the ASCII range. + if (useNamedReferences) { + string = string + .replace(/>\u20D2/g, '>⃒') + .replace(/<\u20D2/g, '<⃒') + .replace(/fj/g, 'fj'); + } + // Encode non-ASCII symbols. + if (useNamedReferences) { + // Encode non-ASCII symbols that can be replaced with a named reference. + string = string.replace(regexEncodeNonAscii, function(string) { + // Note: there is no need to check `has(encodeMap, string)` here. + return '&' + encodeMap[string] + ';'; + }); + } + // Note: any remaining non-ASCII symbols are handled outside of the `if`. + } else if (useNamedReferences) { + // Apply named character references. + // Encode `<>"'&` using named character references. + if (!allowUnsafeSymbols) { + string = string.replace(regexEscape, function(string) { + return '&' + encodeMap[string] + ';'; // no need to check `has()` here + }); + } + // Shorten escapes that represent two symbols, of which at least one is + // `<>"'&`. + string = string + .replace(/>\u20D2/g, '>⃒') + .replace(/<\u20D2/g, '<⃒'); + // Encode non-ASCII symbols that can be replaced with a named reference. + string = string.replace(regexEncodeNonAscii, function(string) { + // Note: there is no need to check `has(encodeMap, string)` here. + return '&' + encodeMap[string] + ';'; + }); + } else if (!allowUnsafeSymbols) { + // Encode `<>"'&` using hexadecimal escapes, now that they’re not handled + // using named character references. + string = string.replace(regexEscape, escapeBmpSymbol); + } + return string + // Encode astral symbols. + .replace(regexAstralSymbols, function($0) { + // https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae + var high = $0.charCodeAt(0); + var low = $0.charCodeAt(1); + var codePoint = (high - 0xD800) * 0x400 + low - 0xDC00 + 0x10000; + return escapeCodePoint(codePoint); + }) + // Encode any remaining BMP symbols that are not printable ASCII symbols + // using a hexadecimal escape. + .replace(regexBmpWhitelist, escapeBmpSymbol); + }; + // Expose default options (so they can be overridden globally). + encode.options = { + 'allowUnsafeSymbols': false, + 'encodeEverything': false, + 'strict': false, + 'useNamedReferences': false, + 'decimal' : false + }; + + var decode = function(html, options) { + options = merge(options, decode.options); + var strict = options.strict; + if (strict && regexInvalidEntity.test(html)) { + parseError('malformed character reference'); + } + return html.replace(regexDecode, function($0, $1, $2, $3, $4, $5, $6, $7, $8) { + var codePoint; + var semicolon; + var decDigits; + var hexDigits; + var reference; + var next; + + if ($1) { + reference = $1; + // Note: there is no need to check `has(decodeMap, reference)`. + return decodeMap[reference]; + } + + if ($2) { + // Decode named character references without trailing `;`, e.g. `&`. + // This is only a parse error if it gets converted to `&`, or if it is + // followed by `=` in an attribute context. + reference = $2; + next = $3; + if (next && options.isAttributeValue) { + if (strict && next == '=') { + parseError('`&` did not start a character reference'); + } + return $0; + } else { + if (strict) { + parseError( + 'named character reference was not terminated by a semicolon' + ); + } + // Note: there is no need to check `has(decodeMapLegacy, reference)`. + return decodeMapLegacy[reference] + (next || ''); + } + } + + if ($4) { + // Decode decimal escapes, e.g. `𝌆`. + decDigits = $4; + semicolon = $5; + if (strict && !semicolon) { + parseError('character reference was not terminated by a semicolon'); + } + codePoint = parseInt(decDigits, 10); + return codePointToSymbol(codePoint, strict); + } + + if ($6) { + // Decode hexadecimal escapes, e.g. `𝌆`. + hexDigits = $6; + semicolon = $7; + if (strict && !semicolon) { + parseError('character reference was not terminated by a semicolon'); + } + codePoint = parseInt(hexDigits, 16); + return codePointToSymbol(codePoint, strict); + } + + // If we’re still here, `if ($7)` is implied; it’s an ambiguous + // ampersand for sure. https://mths.be/notes/ambiguous-ampersands + if (strict) { + parseError( + 'named character reference was not terminated by a semicolon' + ); + } + return $0; + }); + }; + // Expose default options (so they can be overridden globally). + decode.options = { + 'isAttributeValue': false, + 'strict': false + }; + + var escape = function(string) { + return string.replace(regexEscape, function($0) { + // Note: there is no need to check `has(escapeMap, $0)` here. + return escapeMap[$0]; + }); + }; + + /*--------------------------------------------------------------------------*/ + + var he = { + 'version': '1.2.0', + 'encode': encode, + 'decode': decode, + 'escape': escape, + 'unescape': decode + }; + + // Some AMD build optimizers, like r.js, check for specific condition patterns + // like the following: + if ( + typeof define == 'function' && + typeof define.amd == 'object' && + define.amd + ) { + define(function() { + return he; + }); + } else if (freeExports && !freeExports.nodeType) { + if (freeModule) { // in Node.js, io.js, or RingoJS v0.8.0+ + freeModule.exports = he; + } else { // in Narwhal or RingoJS v0.7.0- + for (var key in he) { + has(he, key) && (freeExports[key] = he[key]); + } + } + } else { // in Rhino or a web browser + root.he = he; + } + +}(this)); + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{}],2:[function(require,module,exports){ +/*! + * jQuery JavaScript Library v3.3.1 + * https://jquery.com/ + * + * Includes Sizzle.js + * https://sizzlejs.com/ + * + * Copyright JS Foundation and other contributors + * Released under the MIT license + * https://jquery.org/license + * + * Date: 2018-01-20T17:24Z + */ +( function( global, factory ) { + + "use strict"; + + if ( typeof module === "object" && typeof module.exports === "object" ) { + + // For CommonJS and CommonJS-like environments where a proper `window` + // is present, execute the factory and get jQuery. + // For environments that do not have a `window` with a `document` + // (such as Node.js), expose a factory as module.exports. + // This accentuates the need for the creation of a real `window`. + // e.g. var jQuery = require("jquery")(window); + // See ticket #14549 for more info. + module.exports = global.document ? + factory( global, true ) : + function( w ) { + if ( !w.document ) { + throw new Error( "jQuery requires a window with a document" ); + } + return factory( w ); + }; + } else { + factory( global ); + } + +// Pass this if window is not defined yet +} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { + +// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 +// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode +// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common +// enough that all such attempts are guarded in a try block. +"use strict"; + +var arr = []; + +var document = window.document; + +var getProto = Object.getPrototypeOf; + +var slice = arr.slice; + +var concat = arr.concat; + +var push = arr.push; + +var indexOf = arr.indexOf; + +var class2type = {}; + +var toString = class2type.toString; + +var hasOwn = class2type.hasOwnProperty; + +var fnToString = hasOwn.toString; + +var ObjectFunctionString = fnToString.call( Object ); + +var support = {}; + +var isFunction = function isFunction( obj ) { + + // Support: Chrome <=57, Firefox <=52 + // In some browsers, typeof returns "function" for HTML elements + // (i.e., `typeof document.createElement( "object" ) === "function"`). + // We don't want to classify *any* DOM node as a function. + return typeof obj === "function" && typeof obj.nodeType !== "number"; + }; + + +var isWindow = function isWindow( obj ) { + return obj != null && obj === obj.window; + }; + + + + + var preservedScriptAttributes = { + type: true, + src: true, + noModule: true + }; + + function DOMEval( code, doc, node ) { + doc = doc || document; + + var i, + script = doc.createElement( "script" ); + + script.text = code; + if ( node ) { + for ( i in preservedScriptAttributes ) { + if ( node[ i ] ) { + script[ i ] = node[ i ]; + } + } + } + doc.head.appendChild( script ).parentNode.removeChild( script ); + } + + +function toType( obj ) { + if ( obj == null ) { + return obj + ""; + } + + // Support: Android <=2.3 only (functionish RegExp) + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call( obj ) ] || "object" : + typeof obj; +} +/* global Symbol */ +// Defining this global in .eslintrc.json would create a danger of using the global +// unguarded in another place, it seems safer to define global only for this module + + + +var + version = "3.3.1", + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }, + + // Support: Android <=4.0 only + // Make sure we trim BOM and NBSP + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g; + +jQuery.fn = jQuery.prototype = { + + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + + // Return all the elements in a clean array + if ( num == null ) { + return slice.call( this ); + } + + // Return just the one element from the set + return num < 0 ? this[ num + this.length ] : this[ num ]; + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + each: function( callback ) { + return jQuery.each( this, callback ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map( this, function( elem, i ) { + return callback.call( elem, i, elem ); + } ) ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); + }, + + end: function() { + return this.prevObject || this.constructor(); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: arr.sort, + splice: arr.splice +}; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[ 0 ] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // Skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !isFunction( target ) ) { + target = {}; + } + + // Extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + + // Only deal with non-null/undefined values + if ( ( options = arguments[ i ] ) != null ) { + + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject( copy ) || + ( copyIsArray = Array.isArray( copy ) ) ) ) { + + if ( copyIsArray ) { + copyIsArray = false; + clone = src && Array.isArray( src ) ? src : []; + + } else { + clone = src && jQuery.isPlainObject( src ) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend( { + + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), + + // Assume jQuery is ready without the ready module + isReady: true, + + error: function( msg ) { + throw new Error( msg ); + }, + + noop: function() {}, + + isPlainObject: function( obj ) { + var proto, Ctor; + + // Detect obvious negatives + // Use toString instead of jQuery.type to catch host objects + if ( !obj || toString.call( obj ) !== "[object Object]" ) { + return false; + } + + proto = getProto( obj ); + + // Objects with no prototype (e.g., `Object.create( null )`) are plain + if ( !proto ) { + return true; + } + + // Objects with prototype are plain iff they were constructed by a global Object function + Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; + return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; + }, + + isEmptyObject: function( obj ) { + + /* eslint-disable no-unused-vars */ + // See https://github.com/eslint/eslint/issues/6125 + var name; + + for ( name in obj ) { + return false; + } + return true; + }, + + // Evaluates a script in a global context + globalEval: function( code ) { + DOMEval( code ); + }, + + each: function( obj, callback ) { + var length, i = 0; + + if ( isArrayLike( obj ) ) { + length = obj.length; + for ( ; i < length; i++ ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } else { + for ( i in obj ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } + + return obj; + }, + + // Support: Android <=4.0 only + trim: function( text ) { + return text == null ? + "" : + ( text + "" ).replace( rtrim, "" ); + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArrayLike( Object( arr ) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + return arr == null ? -1 : indexOf.call( arr, elem, i ); + }, + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; + + for ( ; j < len; j++ ) { + first[ i++ ] = second[ j ]; + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var length, value, + i = 0, + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArrayLike( elems ) ) { + length = elems.length; + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support +} ); + +if ( typeof Symbol === "function" ) { + jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; +} + +// Populate the class2type map +jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), +function( i, name ) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +} ); + +function isArrayLike( obj ) { + + // Support: real iOS 8.2 only (not reproducible in simulator) + // `in` check used to prevent JIT error (gh-2145) + // hasOwn isn't used here due to false negatives + // regarding Nodelist length in IE + var length = !!obj && "length" in obj && obj.length, + type = toType( obj ); + + if ( isFunction( obj ) || isWindow( obj ) ) { + return false; + } + + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; +} +var Sizzle = +/*! + * Sizzle CSS Selector Engine v2.3.3 + * https://sizzlejs.com/ + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2016-08-08 + */ +(function( window ) { + +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + 1 * new Date(), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // Instance methods + hasOwn = ({}).hasOwnProperty, + arr = [], + pop = arr.pop, + push_native = arr.push, + push = arr.push, + slice = arr.slice, + // Use a stripped-down indexOf as it's faster than native + // https://jsperf.com/thor-indexof-vs-for/5 + indexOf = function( list, elem ) { + var i = 0, + len = list.length; + for ( ; i < len; i++ ) { + if ( list[i] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + + // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+", + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + + "*\\]", + + pseudos = ":(" + identifier + ")(?:\\((" + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rwhitespace = new RegExp( whitespace + "+", "g" ), + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), + + rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + identifier + ")" ), + "CLASS": new RegExp( "^\\.(" + identifier + ")" ), + "TAG": new RegExp( "^(" + identifier + "|[*])" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + + // CSS escapes + // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), + funescape = function( _, escaped, escapedWhitespace ) { + var high = "0x" + escaped - 0x10000; + // NaN means non-codepoint + // Support: Firefox<24 + // Workaround erroneous numeric interpretation of +"0x" + return high !== high || escapedWhitespace ? + escaped : + high < 0 ? + // BMP codepoint + String.fromCharCode( high + 0x10000 ) : + // Supplemental Plane codepoint (surrogate pair) + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }, + + // CSS string/identifier serialization + // https://drafts.csswg.org/cssom/#common-serializing-idioms + rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, + fcssescape = function( ch, asCodePoint ) { + if ( asCodePoint ) { + + // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER + if ( ch === "\0" ) { + return "\uFFFD"; + } + + // Control characters and (dependent upon position) numbers get escaped as code points + return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; + } + + // Other potentially-special ASCII characters get backslash-escaped + return "\\" + ch; + }, + + // Used for iframes + // See setDocument() + // Removing the function wrapper causes a "Permission Denied" + // error in IE + unloadHandler = function() { + setDocument(); + }, + + disabledAncestor = addCombinator( + function( elem ) { + return elem.disabled === true && ("form" in elem || "label" in elem); + }, + { dir: "parentNode", next: "legend" } + ); + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + (arr = slice.call( preferredDoc.childNodes )), + preferredDoc.childNodes + ); + // Support: Android<4.0 + // Detect silently failing push.apply + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + push_native.apply( target, slice.call(els) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + // Can't trust NodeList.length + while ( (target[j++] = els[i++]) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var m, i, elem, nid, match, groups, newSelector, + newContext = context && context.ownerDocument, + + // nodeType defaults to 9, since context defaults to document + nodeType = context ? context.nodeType : 9; + + results = results || []; + + // Return early from calls with invalid selector or context + if ( typeof selector !== "string" || !selector || + nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { + + return results; + } + + // Try to shortcut find operations (as opposed to filters) in HTML documents + if ( !seed ) { + + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { + setDocument( context ); + } + context = context || document; + + if ( documentIsHTML ) { + + // If the selector is sufficiently simple, try using a "get*By*" DOM method + // (excepting DocumentFragment context, where the methods don't exist) + if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { + + // ID selector + if ( (m = match[1]) ) { + + // Document context + if ( nodeType === 9 ) { + if ( (elem = context.getElementById( m )) ) { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + + // Element context + } else { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( newContext && (elem = newContext.getElementById( m )) && + contains( context, elem ) && + elem.id === m ) { + + results.push( elem ); + return results; + } + } + + // Type selector + } else if ( match[2] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Class selector + } else if ( (m = match[3]) && support.getElementsByClassName && + context.getElementsByClassName ) { + + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // Take advantage of querySelectorAll + if ( support.qsa && + !compilerCache[ selector + " " ] && + (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { + + if ( nodeType !== 1 ) { + newContext = context; + newSelector = selector; + + // qSA looks outside Element context, which is not what we want + // Thanks to Andrew Dupont for this workaround technique + // Support: IE <=8 + // Exclude object elements + } else if ( context.nodeName.toLowerCase() !== "object" ) { + + // Capture the context ID, setting it first if necessary + if ( (nid = context.getAttribute( "id" )) ) { + nid = nid.replace( rcssescape, fcssescape ); + } else { + context.setAttribute( "id", (nid = expando) ); + } + + // Prefix every selector in the list + groups = tokenize( selector ); + i = groups.length; + while ( i-- ) { + groups[i] = "#" + nid + " " + toSelector( groups[i] ); + } + newSelector = groups.join( "," ); + + // Expand context for sibling selectors + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || + context; + } + + if ( newSelector ) { + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch ( qsaError ) { + } finally { + if ( nid === expando ) { + context.removeAttribute( "id" ); + } + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {function(string, object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return (cache[ key + " " ] = value); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created element and returns a boolean result + */ +function assert( fn ) { + var el = document.createElement("fieldset"); + + try { + return !!fn( el ); + } catch (e) { + return false; + } finally { + // Remove from its parent by default + if ( el.parentNode ) { + el.parentNode.removeChild( el ); + } + // release memory in IE + el = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split("|"), + i = arr.length; + + while ( i-- ) { + Expr.attrHandle[ arr[i] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + a.sourceIndex - b.sourceIndex; + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( (cur = cur.nextSibling) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for :enabled/:disabled + * @param {Boolean} disabled true for :disabled; false for :enabled + */ +function createDisabledPseudo( disabled ) { + + // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable + return function( elem ) { + + // Only certain elements can match :enabled or :disabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled + if ( "form" in elem ) { + + // Check for inherited disabledness on relevant non-disabled elements: + // * listed form-associated elements in a disabled fieldset + // https://html.spec.whatwg.org/multipage/forms.html#category-listed + // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled + // * option elements in a disabled optgroup + // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled + // All such elements have a "form" property. + if ( elem.parentNode && elem.disabled === false ) { + + // Option elements defer to a parent optgroup if present + if ( "label" in elem ) { + if ( "label" in elem.parentNode ) { + return elem.parentNode.disabled === disabled; + } else { + return elem.disabled === disabled; + } + } + + // Support: IE 6 - 11 + // Use the isDisabled shortcut property to check for disabled fieldset ancestors + return elem.isDisabled === disabled || + + // Where there is no isDisabled, check manually + /* jshint -W018 */ + elem.isDisabled !== !disabled && + disabledAncestor( elem ) === disabled; + } + + return elem.disabled === disabled; + + // Try to winnow out elements that can't be disabled before trusting the disabled property. + // Some victims get caught in our net (label, legend, menu, track), but it shouldn't + // even exist on them, let alone have a boolean value. + } else if ( "label" in elem ) { + return elem.disabled === disabled; + } + + // Remaining elements are neither :enabled nor :disabled + return false; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); +} + +/** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ +function testContext( context ) { + return context && typeof context.getElementsByTagName !== "undefined" && context; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ +isXML = Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = elem && (elem.ownerDocument || elem).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, subWindow, + doc = node ? node.ownerDocument || node : preferredDoc; + + // Return early if doc is invalid or already selected + if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Update global variables + document = doc; + docElem = document.documentElement; + documentIsHTML = !isXML( document ); + + // Support: IE 9-11, Edge + // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) + if ( preferredDoc !== document && + (subWindow = document.defaultView) && subWindow.top !== subWindow ) { + + // Support: IE 11, Edge + if ( subWindow.addEventListener ) { + subWindow.addEventListener( "unload", unloadHandler, false ); + + // Support: IE 9 - 10 only + } else if ( subWindow.attachEvent ) { + subWindow.attachEvent( "onunload", unloadHandler ); + } + } + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties + // (excepting IE8 booleans) + support.attributes = assert(function( el ) { + el.className = "i"; + return !el.getAttribute("className"); + }); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert(function( el ) { + el.appendChild( document.createComment("") ); + return !el.getElementsByTagName("*").length; + }); + + // Support: IE<9 + support.getElementsByClassName = rnative.test( document.getElementsByClassName ); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programmatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert(function( el ) { + docElem.appendChild( el ).id = expando; + return !document.getElementsByName || !document.getElementsByName( expando ).length; + }); + + // ID filter and find + if ( support.getById ) { + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute("id") === attrId; + }; + }; + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var elem = context.getElementById( id ); + return elem ? [ elem ] : []; + } + }; + } else { + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== "undefined" && + elem.getAttributeNode("id"); + return node && node.value === attrId; + }; + }; + + // Support: IE 6 - 7 only + // getElementById is not reliable as a find shortcut + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var node, i, elems, + elem = context.getElementById( id ); + + if ( elem ) { + + // Verify the id attribute + node = elem.getAttributeNode("id"); + if ( node && node.value === id ) { + return [ elem ]; + } + + // Fall back on getElementsByName + elems = context.getElementsByName( id ); + i = 0; + while ( (elem = elems[i++]) ) { + node = elem.getAttributeNode("id"); + if ( node && node.value === id ) { + return [ elem ]; + } + } + } + + return []; + } + }; + } + + // Tag + Expr.find["TAG"] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( tag ); + + // DocumentFragment nodes don't have gEBTN + } else if ( support.qsa ) { + return context.querySelectorAll( tag ); + } + } : + + function( tag, context ) { + var elem, + tmp = [], + i = 0, + // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( (elem = results[i++]) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See https://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( (support.qsa = rnative.test( document.querySelectorAll )) ) { + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( el ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // https://bugs.jquery.com/ticket/12359 + docElem.appendChild( el ).innerHTML = "" + + ""; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if ( el.querySelectorAll("[msallowcapture^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !el.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ + if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { + rbuggyQSA.push("~="); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !el.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + + // Support: Safari 8+, iOS 8+ + // https://bugs.webkit.org/show_bug.cgi?id=136851 + // In-page `selector#id sibling-combinator selector` fails + if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { + rbuggyQSA.push(".#.+[+~]"); + } + }); + + assert(function( el ) { + el.innerHTML = "" + + ""; + + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = document.createElement("input"); + input.setAttribute( "type", "hidden" ); + el.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( el.querySelectorAll("[name=d]").length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( el.querySelectorAll(":enabled").length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: IE9-11+ + // IE's :disabled selector does not pick up the children of disabled fieldsets + docElem.appendChild( el ).disabled = true; + if ( el.querySelectorAll(":disabled").length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Opera 10-11 does not throw on post-comma invalid pseudos + el.querySelectorAll("*,:x"); + rbuggyQSA.push(",.*:"); + }); + } + + if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector) )) ) { + + assert(function( el ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( el, "*" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( el, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + }); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully self-exclusive + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + )); + } : + function( a, b ) { + if ( b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // Calculate position if both inputs belong to the same document + compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { + + // Choose the first element that is related to our preferred document + if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { + return -1; + } + if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + return a === document ? -1 : + b === document ? 1 : + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( (cur = cur.parentNode) ) { + ap.unshift( cur ); + } + cur = b; + while ( (cur = cur.parentNode) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[i] === bp[i] ) { + i++; + } + + return i ? + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[i], bp[i] ) : + + // Otherwise nodes in our document sort first + ap[i] === preferredDoc ? -1 : + bp[i] === preferredDoc ? 1 : + 0; + }; + + return document; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + // Make sure that attribute selectors are quoted + expr = expr.replace( rattributeQuotes, "='$1']" ); + + if ( support.matchesSelector && documentIsHTML && + !compilerCache[ expr + " " ] && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch (e) {} + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + // Set document vars if needed + if ( ( context.ownerDocument || context ) !== document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val !== undefined ? + val : + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + (val = elem.getAttributeNode(name)) && val.specified ? + val.value : + null; +}; + +Sizzle.escape = function( sel ) { + return (sel + "").replace( rcssescape, fcssescape ); +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( (elem = results[i++]) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + // If no nodeType, this is expected to be an array + while ( (node = elem[i++]) ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[1] = match[1].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); + + if ( match[2] === "~=" ) { + match[3] = " " + match[3] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1].slice( 0, 3 ) === "nth" ) { + // nth-* requires argument + if ( !match[3] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); + match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); + + // other types prohibit arguments + } else if ( match[3] ) { + Sizzle.error( match[0] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[6] && match[2]; + + if ( matchExpr["CHILD"].test( match[0] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[3] ) { + match[2] = match[4] || match[5] || ""; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + match[0] = match[0].slice( 0, excess ); + match[2] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { return true; } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && + classCache( className, function( elem ) { + return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" ); + }); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + }; + }, + + "CHILD": function( type, what, argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, context, xml ) { + var cache, uniqueCache, outerCache, node, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType, + diff = false; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( (node = node[ dir ]) ) { + if ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) { + + return false; + } + } + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + + // Seek `elem` from a previously-cached index + + // ...in a gzip-friendly way + node = parent; + outerCache = node[ expando ] || (node[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex && cache[ 2 ]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( (node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + (diff = nodeIndex = 0) || start.pop()) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + } else { + // Use previously-cached element index if available + if ( useCache ) { + // ...in a gzip-friendly way + node = elem; + outerCache = node[ expando ] || (node[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex; + } + + // xml :nth-child(...) + // or :nth-last-child(...) or :nth(-last)?-of-type(...) + if ( diff === false ) { + // Use the same loop as above to seek `elem` from the start + while ( (node = ++nodeIndex && node && node[ dir ] || + (diff = nodeIndex = 0) || start.pop()) ) { + + if ( ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) && + ++diff ) { + + // Cache the index of each encountered element + if ( useCache ) { + outerCache = node[ expando ] || (node[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); + + uniqueCache[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction(function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + // Potentially complex pseudos + "not": markFunction(function( selector ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction(function( seed, matches, context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + // Don't keep the element (issue #299) + input[0] = null; + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + text = text.replace( runescape, funescape ); + return function( elem ) { + return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + // lang value must be a valid identifier + if ( !ridentifier.test(lang || "") ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( (elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); + return false; + }; + }), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + }, + + // Boolean properties + "enabled": createDisabledPseudo( false ), + "disabled": createDisabledPseudo( true ), + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "selected": function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos["empty"]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); + }, + + // Position-in-collection + "first": createPositionalPseudo(function() { + return [ 0 ]; + }), + + "last": createPositionalPseudo(function( matchIndexes, length ) { + return [ length - 1 ]; + }), + + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + }), + + "even": createPositionalPseudo(function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "odd": createPositionalPseudo(function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }) + } +}; + +Expr.pseudos["nth"] = Expr.pseudos["eq"]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +tokenize = Sizzle.tokenize = function( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + // Don't consume trailing commas as valid + soFar = soFar.slice( match[0].length ) || soFar; + } + groups.push( (tokens = []) ); + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + matched = match.shift(); + tokens.push({ + value: matched, + // Cast descendant combinators to space + type: match[0].replace( rtrim, " " ) + }); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + (match = preFilters[ type ]( match ))) ) { + matched = match.shift(); + tokens.push({ + value: matched, + type: type, + matches: match + }); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +}; + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[i].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + skip = combinator.next, + key = skip || dir, + checkNonElements = base && key === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + return false; + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, uniqueCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching + if ( xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || (elem[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {}); + + if ( skip && skip === elem.nodeName.toLowerCase() ) { + elem = elem[ dir ] || elem; + } else if ( (oldCache = uniqueCache[ key ]) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return (newCache[ 2 ] = oldCache[ 2 ]); + } else { + // Reuse newcache so results back-propagate to previous elements + uniqueCache[ key ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { + return true; + } + } + } + } + } + return false; + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[i]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[0]; +} + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[i], results ); + } + return results; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( (elem = unmatched[i]) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction(function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( (elem = temp[i]) ) { + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) ) { + // Restore matcherIn since elem is not yet a final match + temp.push( (matcherIn[i] = elem) ); + } + } + postFinder( null, (matcherOut = []), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) && + (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) { + + seed[temp] = !(results[temp] = elem); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + }); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[0].type ], + implicitRelative = leadingRelative || Expr.relative[" "], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + (checkContext = context).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + // Avoid hanging onto element (issue #299) + checkContext = null; + return ret; + } ]; + + for ( ; i < len; i++ ) { + if ( (matcher = Expr.relative[ tokens[i].type ]) ) { + matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; + } else { + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[j].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, outermost ) { + var elem, j, matcher, + matchedCount = 0, + i = "0", + unmatched = seed && [], + setMatched = [], + contextBackup = outermostContext, + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), + len = elems.length; + + if ( outermost ) { + outermostContext = context === document || context || outermost; + } + + // Add elements passing elementMatchers directly to results + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id + for ( ; i !== len && (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + if ( !context && elem.ownerDocument !== document ) { + setDocument( elem ); + xml = !documentIsHTML; + } + while ( (matcher = elementMatchers[j++]) ) { + if ( matcher( elem, context || document, xml) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + // They will have gone through all possible matchers + if ( (elem = !matcher && elem) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // `i` is now the count of elements visited above, and adding it to `matchedCount` + // makes the latter nonnegative. + matchedCount += i; + + // Apply set filters to unmatched elements + // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` + // equals `i`), unless we didn't visit _any_ elements in the above loop because we have + // no element matchers and no seed. + // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that + // case, which will result in a "00" `matchedCount` that differs from `i` but is also + // numerically zero. + if ( bySet && i !== matchedCount ) { + j = 0; + while ( (matcher = setMatchers[j++]) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !(unmatched[i] || setMatched[i]) ) { + setMatched[i] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element + if ( !match ) { + match = tokenize( selector ); + } + i = match.length; + while ( i-- ) { + cached = matcherFromTokens( match[i] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + + // Save selector and tokenization + cached.selector = selector; + } + return cached; +}; + +/** + * A low-level selection function that works with Sizzle's compiled + * selector functions + * @param {String|Function} selector A selector or a pre-compiled + * selector function built with Sizzle.compile + * @param {Element} context + * @param {Array} [results] + * @param {Array} [seed] A set of elements to match against + */ +select = Sizzle.select = function( selector, context, results, seed ) { + var i, tokens, token, type, find, + compiled = typeof selector === "function" && selector, + match = !seed && tokenize( (selector = compiled.selector || selector) ); + + results = results || []; + + // Try to minimize operations if there is only one selector in the list and no seed + // (the latter of which guarantees us context) + if ( match.length === 1 ) { + + // Reduce context if the leading compound selector is an ID + tokens = match[0] = match[0].slice( 0 ); + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && + context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[1].type ] ) { + + context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; + if ( !context ) { + return results; + + // Precompiled matchers will still verify ancestry, so step up a level + } else if ( compiled ) { + context = context.parentNode; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[i]; + + // Abort if we hit a combinator + if ( Expr.relative[ (type = token.type) ] ) { + break; + } + if ( (find = Expr.find[ type ]) ) { + // Search, expanding context for leading sibling combinators + if ( (seed = find( + token.matches[0].replace( runescape, funescape ), + rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context + )) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + + // Compile and execute a filtering function if one is not provided + // Provide `match` to avoid retokenization if we modified the selector above + ( compiled || compile( selector, match ) )( + seed, + context, + !documentIsHTML, + results, + !context || rsibling.test( selector ) && testContext( context.parentNode ) || context + ); + return results; +}; + +// One-time assignments + +// Sort stability +support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; + +// Support: Chrome 14-35+ +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = !!hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert(function( el ) { + // Should return 1, but returns 4 (following) + return el.compareDocumentPosition( document.createElement("fieldset") ) & 1; +}); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert(function( el ) { + el.innerHTML = ""; + return el.firstChild.getAttribute("href") === "#" ; +}) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + }); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert(function( el ) { + el.innerHTML = ""; + el.firstChild.setAttribute( "value", "" ); + return el.firstChild.getAttribute( "value" ) === ""; +}) ) { + addHandle( "value", function( elem, name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + }); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert(function( el ) { + return el.getAttribute("disabled") == null; +}) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return elem[ name ] === true ? name.toLowerCase() : + (val = elem.getAttributeNode( name )) && val.specified ? + val.value : + null; + } + }); +} + +return Sizzle; + +})( window ); + + + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; + +// Deprecated +jQuery.expr[ ":" ] = jQuery.expr.pseudos; +jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; +jQuery.escapeSelector = Sizzle.escape; + + + + +var dir = function( elem, dir, until ) { + var matched = [], + truncate = until !== undefined; + + while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { + if ( elem.nodeType === 1 ) { + if ( truncate && jQuery( elem ).is( until ) ) { + break; + } + matched.push( elem ); + } + } + return matched; +}; + + +var siblings = function( n, elem ) { + var matched = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + matched.push( n ); + } + } + + return matched; +}; + + +var rneedsContext = jQuery.expr.match.needsContext; + + + +function nodeName( elem, name ) { + + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + +}; +var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); + + + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + return !!qualifier.call( elem, i, elem ) !== not; + } ); + } + + // Single element + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + } ); + } + + // Arraylike of elements (jQuery, arguments, Array) + if ( typeof qualifier !== "string" ) { + return jQuery.grep( elements, function( elem ) { + return ( indexOf.call( qualifier, elem ) > -1 ) !== not; + } ); + } + + // Filtered directly for both simple and complex selectors + return jQuery.filter( qualifier, elements, not ); +} + +jQuery.filter = function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + if ( elems.length === 1 && elem.nodeType === 1 ) { + return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; + } + + return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + } ) ); +}; + +jQuery.fn.extend( { + find: function( selector ) { + var i, ret, + len = this.length, + self = this; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter( function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + } ) ); + } + + ret = this.pushStack( [] ); + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + return len > 1 ? jQuery.uniqueSort( ret ) : ret; + }, + filter: function( selector ) { + return this.pushStack( winnow( this, selector || [], false ) ); + }, + not: function( selector ) { + return this.pushStack( winnow( this, selector || [], true ) ); + }, + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + } +} ); + + +// Initialize a jQuery object + + +// A central reference to the root jQuery(document) +var rootjQuery, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + // Shortcut simple #id case for speed + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, + + init = jQuery.fn.init = function( selector, context, root ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Method init() accepts an alternate rootjQuery + // so migrate can support jQuery.sub (gh-2101) + root = root || rootjQuery; + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector[ 0 ] === "<" && + selector[ selector.length - 1 ] === ">" && + selector.length >= 3 ) { + + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && ( match[ 1 ] || !context ) ) { + + // HANDLE: $(html) -> $(array) + if ( match[ 1 ] ) { + context = context instanceof jQuery ? context[ 0 ] : context; + + // Option to run scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge( this, jQuery.parseHTML( + match[ 1 ], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + + // Properties of context are called as methods if possible + if ( isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[ 2 ] ); + + if ( elem ) { + + // Inject the element directly into the jQuery object + this[ 0 ] = elem; + this.length = 1; + } + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || root ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this[ 0 ] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( isFunction( selector ) ) { + return root.ready !== undefined ? + root.ready( selector ) : + + // Execute immediately if ready is not present + selector( jQuery ); + } + + return jQuery.makeArray( selector, this ); + }; + +// Give the init function the jQuery prototype for later instantiation +init.prototype = jQuery.fn; + +// Initialize central reference +rootjQuery = jQuery( document ); + + +var rparentsprev = /^(?:parents|prev(?:Until|All))/, + + // Methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend( { + has: function( target ) { + var targets = jQuery( target, this ), + l = targets.length; + + return this.filter( function() { + var i = 0; + for ( ; i < l; i++ ) { + if ( jQuery.contains( this, targets[ i ] ) ) { + return true; + } + } + } ); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + matched = [], + targets = typeof selectors !== "string" && jQuery( selectors ); + + // Positional selectors never match, since there's no _selection_ context + if ( !rneedsContext.test( selectors ) ) { + for ( ; i < l; i++ ) { + for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { + + // Always skip document fragments + if ( cur.nodeType < 11 && ( targets ? + targets.index( cur ) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector( cur, selectors ) ) ) { + + matched.push( cur ); + break; + } + } + } + } + + return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); + }, + + // Determine the position of an element within the set + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; + } + + // Index in selector + if ( typeof elem === "string" ) { + return indexOf.call( jQuery( elem ), this[ 0 ] ); + } + + // Locate the position of the desired element + return indexOf.call( this, + + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[ 0 ] : elem + ); + }, + + add: function( selector, context ) { + return this.pushStack( + jQuery.uniqueSort( + jQuery.merge( this.get(), jQuery( selector, context ) ) + ) + ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter( selector ) + ); + } +} ); + +function sibling( cur, dir ) { + while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} + return cur; +} + +jQuery.each( { + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return siblings( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return siblings( elem.firstChild ); + }, + contents: function( elem ) { + if ( nodeName( elem, "iframe" ) ) { + return elem.contentDocument; + } + + // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only + // Treat the template element as a regular one in browsers that + // don't support it. + if ( nodeName( elem, "template" ) ) { + elem = elem.content || elem; + } + + return jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var matched = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + matched = jQuery.filter( selector, matched ); + } + + if ( this.length > 1 ) { + + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + jQuery.uniqueSort( matched ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + matched.reverse(); + } + } + + return this.pushStack( matched ); + }; +} ); +var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); + + + +// Convert String-formatted options into Object-formatted ones +function createOptions( options ) { + var object = {}; + jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { + object[ flag ] = true; + } ); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + createOptions( options ) : + jQuery.extend( {}, options ); + + var // Flag to know if list is currently firing + firing, + + // Last fire value for non-forgettable lists + memory, + + // Flag to know if list was already fired + fired, + + // Flag to prevent firing + locked, + + // Actual callback list + list = [], + + // Queue of execution data for repeatable lists + queue = [], + + // Index of currently firing callback (modified by add/remove as needed) + firingIndex = -1, + + // Fire callbacks + fire = function() { + + // Enforce single-firing + locked = locked || options.once; + + // Execute callbacks for all pending executions, + // respecting firingIndex overrides and runtime changes + fired = firing = true; + for ( ; queue.length; firingIndex = -1 ) { + memory = queue.shift(); + while ( ++firingIndex < list.length ) { + + // Run callback and check for early termination + if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && + options.stopOnFalse ) { + + // Jump to end and forget the data so .add doesn't re-fire + firingIndex = list.length; + memory = false; + } + } + } + + // Forget the data if we're done with it + if ( !options.memory ) { + memory = false; + } + + firing = false; + + // Clean up if we're done firing for good + if ( locked ) { + + // Keep an empty list if we have data for future add calls + if ( memory ) { + list = []; + + // Otherwise, this object is spent + } else { + list = ""; + } + } + }, + + // Actual Callbacks object + self = { + + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + + // If we have memory from a past run, we should fire after adding + if ( memory && !firing ) { + firingIndex = list.length - 1; + queue.push( memory ); + } + + ( function add( args ) { + jQuery.each( args, function( _, arg ) { + if ( isFunction( arg ) ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && toType( arg ) !== "string" ) { + + // Inspect recursively + add( arg ); + } + } ); + } )( arguments ); + + if ( memory && !firing ) { + fire(); + } + } + return this; + }, + + // Remove a callback from the list + remove: function() { + jQuery.each( arguments, function( _, arg ) { + var index; + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + + // Handle firing indexes + if ( index <= firingIndex ) { + firingIndex--; + } + } + } ); + return this; + }, + + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? + jQuery.inArray( fn, list ) > -1 : + list.length > 0; + }, + + // Remove all callbacks from the list + empty: function() { + if ( list ) { + list = []; + } + return this; + }, + + // Disable .fire and .add + // Abort any current/pending executions + // Clear all callbacks and values + disable: function() { + locked = queue = []; + list = memory = ""; + return this; + }, + disabled: function() { + return !list; + }, + + // Disable .fire + // Also disable .add unless we have memory (since it would have no effect) + // Abort any pending executions + lock: function() { + locked = queue = []; + if ( !memory && !firing ) { + list = memory = ""; + } + return this; + }, + locked: function() { + return !!locked; + }, + + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( !locked ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + queue.push( args ); + if ( !firing ) { + fire(); + } + } + return this; + }, + + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + +function Identity( v ) { + return v; +} +function Thrower( ex ) { + throw ex; +} + +function adoptValue( value, resolve, reject, noValue ) { + var method; + + try { + + // Check for promise aspect first to privilege synchronous behavior + if ( value && isFunction( ( method = value.promise ) ) ) { + method.call( value ).done( resolve ).fail( reject ); + + // Other thenables + } else if ( value && isFunction( ( method = value.then ) ) ) { + method.call( value, resolve, reject ); + + // Other non-thenables + } else { + + // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: + // * false: [ value ].slice( 0 ) => resolve( value ) + // * true: [ value ].slice( 1 ) => resolve() + resolve.apply( undefined, [ value ].slice( noValue ) ); + } + + // For Promises/A+, convert exceptions into rejections + // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in + // Deferred#then to conditionally suppress rejection. + } catch ( value ) { + + // Support: Android 4.0 only + // Strict mode functions invoked without .call/.apply get global-object context + reject.apply( undefined, [ value ] ); + } +} + +jQuery.extend( { + + Deferred: function( func ) { + var tuples = [ + + // action, add listener, callbacks, + // ... .then handlers, argument index, [final state] + [ "notify", "progress", jQuery.Callbacks( "memory" ), + jQuery.Callbacks( "memory" ), 2 ], + [ "resolve", "done", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 0, "resolved" ], + [ "reject", "fail", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 1, "rejected" ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + "catch": function( fn ) { + return promise.then( null, fn ); + }, + + // Keep pipe for back-compat + pipe: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + + return jQuery.Deferred( function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + + // Map tuples (progress, done, fail) to arguments (done, fail, progress) + var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; + + // deferred.progress(function() { bind to newDefer or newDefer.notify }) + // deferred.done(function() { bind to newDefer or newDefer.resolve }) + // deferred.fail(function() { bind to newDefer or newDefer.reject }) + deferred[ tuple[ 1 ] ]( function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && isFunction( returned.promise ) ) { + returned.promise() + .progress( newDefer.notify ) + .done( newDefer.resolve ) + .fail( newDefer.reject ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( + this, + fn ? [ returned ] : arguments + ); + } + } ); + } ); + fns = null; + } ).promise(); + }, + then: function( onFulfilled, onRejected, onProgress ) { + var maxDepth = 0; + function resolve( depth, deferred, handler, special ) { + return function() { + var that = this, + args = arguments, + mightThrow = function() { + var returned, then; + + // Support: Promises/A+ section 2.3.3.3.3 + // https://promisesaplus.com/#point-59 + // Ignore double-resolution attempts + if ( depth < maxDepth ) { + return; + } + + returned = handler.apply( that, args ); + + // Support: Promises/A+ section 2.3.1 + // https://promisesaplus.com/#point-48 + if ( returned === deferred.promise() ) { + throw new TypeError( "Thenable self-resolution" ); + } + + // Support: Promises/A+ sections 2.3.3.1, 3.5 + // https://promisesaplus.com/#point-54 + // https://promisesaplus.com/#point-75 + // Retrieve `then` only once + then = returned && + + // Support: Promises/A+ section 2.3.4 + // https://promisesaplus.com/#point-64 + // Only check objects and functions for thenability + ( typeof returned === "object" || + typeof returned === "function" ) && + returned.then; + + // Handle a returned thenable + if ( isFunction( then ) ) { + + // Special processors (notify) just wait for resolution + if ( special ) { + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ) + ); + + // Normal processors (resolve) also hook into progress + } else { + + // ...and disregard older resolution values + maxDepth++; + + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ), + resolve( maxDepth, deferred, Identity, + deferred.notifyWith ) + ); + } + + // Handle all other returned values + } else { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Identity ) { + that = undefined; + args = [ returned ]; + } + + // Process the value(s) + // Default process is resolve + ( special || deferred.resolveWith )( that, args ); + } + }, + + // Only normal processors (resolve) catch and reject exceptions + process = special ? + mightThrow : + function() { + try { + mightThrow(); + } catch ( e ) { + + if ( jQuery.Deferred.exceptionHook ) { + jQuery.Deferred.exceptionHook( e, + process.stackTrace ); + } + + // Support: Promises/A+ section 2.3.3.3.4.1 + // https://promisesaplus.com/#point-61 + // Ignore post-resolution exceptions + if ( depth + 1 >= maxDepth ) { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Thrower ) { + that = undefined; + args = [ e ]; + } + + deferred.rejectWith( that, args ); + } + } + }; + + // Support: Promises/A+ section 2.3.3.3.1 + // https://promisesaplus.com/#point-57 + // Re-resolve promises immediately to dodge false rejection from + // subsequent errors + if ( depth ) { + process(); + } else { + + // Call an optional hook to record the stack, in case of exception + // since it's otherwise lost when execution goes async + if ( jQuery.Deferred.getStackHook ) { + process.stackTrace = jQuery.Deferred.getStackHook(); + } + window.setTimeout( process ); + } + }; + } + + return jQuery.Deferred( function( newDefer ) { + + // progress_handlers.add( ... ) + tuples[ 0 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onProgress ) ? + onProgress : + Identity, + newDefer.notifyWith + ) + ); + + // fulfilled_handlers.add( ... ) + tuples[ 1 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onFulfilled ) ? + onFulfilled : + Identity + ) + ); + + // rejected_handlers.add( ... ) + tuples[ 2 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onRejected ) ? + onRejected : + Thrower + ) + ); + } ).promise(); + }, + + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 5 ]; + + // promise.progress = list.add + // promise.done = list.add + // promise.fail = list.add + promise[ tuple[ 1 ] ] = list.add; + + // Handle state + if ( stateString ) { + list.add( + function() { + + // state = "resolved" (i.e., fulfilled) + // state = "rejected" + state = stateString; + }, + + // rejected_callbacks.disable + // fulfilled_callbacks.disable + tuples[ 3 - i ][ 2 ].disable, + + // rejected_handlers.disable + // fulfilled_handlers.disable + tuples[ 3 - i ][ 3 ].disable, + + // progress_callbacks.lock + tuples[ 0 ][ 2 ].lock, + + // progress_handlers.lock + tuples[ 0 ][ 3 ].lock + ); + } + + // progress_handlers.fire + // fulfilled_handlers.fire + // rejected_handlers.fire + list.add( tuple[ 3 ].fire ); + + // deferred.notify = function() { deferred.notifyWith(...) } + // deferred.resolve = function() { deferred.resolveWith(...) } + // deferred.reject = function() { deferred.rejectWith(...) } + deferred[ tuple[ 0 ] ] = function() { + deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); + return this; + }; + + // deferred.notifyWith = list.fireWith + // deferred.resolveWith = list.fireWith + // deferred.rejectWith = list.fireWith + deferred[ tuple[ 0 ] + "With" ] = list.fireWith; + } ); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( singleValue ) { + var + + // count of uncompleted subordinates + remaining = arguments.length, + + // count of unprocessed arguments + i = remaining, + + // subordinate fulfillment data + resolveContexts = Array( i ), + resolveValues = slice.call( arguments ), + + // the master Deferred + master = jQuery.Deferred(), + + // subordinate callback factory + updateFunc = function( i ) { + return function( value ) { + resolveContexts[ i ] = this; + resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; + if ( !( --remaining ) ) { + master.resolveWith( resolveContexts, resolveValues ); + } + }; + }; + + // Single- and empty arguments are adopted like Promise.resolve + if ( remaining <= 1 ) { + adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject, + !remaining ); + + // Use .then() to unwrap secondary thenables (cf. gh-3000) + if ( master.state() === "pending" || + isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { + + return master.then(); + } + } + + // Multiple arguments are aggregated like Promise.all array elements + while ( i-- ) { + adoptValue( resolveValues[ i ], updateFunc( i ), master.reject ); + } + + return master.promise(); + } +} ); + + +// These usually indicate a programmer mistake during development, +// warn about them ASAP rather than swallowing them by default. +var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; + +jQuery.Deferred.exceptionHook = function( error, stack ) { + + // Support: IE 8 - 9 only + // Console exists when dev tools are open, which can happen at any time + if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { + window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack ); + } +}; + + + + +jQuery.readyException = function( error ) { + window.setTimeout( function() { + throw error; + } ); +}; + + + + +// The deferred used on DOM ready +var readyList = jQuery.Deferred(); + +jQuery.fn.ready = function( fn ) { + + readyList + .then( fn ) + + // Wrap jQuery.readyException in a function so that the lookup + // happens at the time of error handling instead of callback + // registration. + .catch( function( error ) { + jQuery.readyException( error ); + } ); + + return this; +}; + +jQuery.extend( { + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + } +} ); + +jQuery.ready.then = readyList.then; + +// The ready event handler and self cleanup method +function completed() { + document.removeEventListener( "DOMContentLoaded", completed ); + window.removeEventListener( "load", completed ); + jQuery.ready(); +} + +// Catch cases where $(document).ready() is called +// after the browser event has already occurred. +// Support: IE <=9 - 10 only +// Older IE sometimes signals "interactive" too soon +if ( document.readyState === "complete" || + ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { + + // Handle it asynchronously to allow scripts the opportunity to delay ready + window.setTimeout( jQuery.ready ); + +} else { + + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed ); +} + + + + +// Multifunctional method to get and set values of a collection +// The value/s can optionally be executed if it's a function +var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + len = elems.length, + bulk = key == null; + + // Sets many values + if ( toType( key ) === "object" ) { + chainable = true; + for ( i in key ) { + access( elems, fn, i, key[ i ], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < len; i++ ) { + fn( + elems[ i ], key, raw ? + value : + value.call( elems[ i ], i, fn( elems[ i ], key ) ) + ); + } + } + } + + if ( chainable ) { + return elems; + } + + // Gets + if ( bulk ) { + return fn.call( elems ); + } + + return len ? fn( elems[ 0 ], key ) : emptyGet; +}; + + +// Matches dashed string for camelizing +var rmsPrefix = /^-ms-/, + rdashAlpha = /-([a-z])/g; + +// Used by camelCase as callback to replace() +function fcamelCase( all, letter ) { + return letter.toUpperCase(); +} + +// Convert dashed to camelCase; used by the css and data modules +// Support: IE <=9 - 11, Edge 12 - 15 +// Microsoft forgot to hump their vendor prefix (#9572) +function camelCase( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); +} +var acceptData = function( owner ) { + + // Accepts only: + // - Node + // - Node.ELEMENT_NODE + // - Node.DOCUMENT_NODE + // - Object + // - Any + return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); +}; + + + + +function Data() { + this.expando = jQuery.expando + Data.uid++; +} + +Data.uid = 1; + +Data.prototype = { + + cache: function( owner ) { + + // Check if the owner object already has a cache + var value = owner[ this.expando ]; + + // If not, create one + if ( !value ) { + value = {}; + + // We can accept data for non-element nodes in modern browsers, + // but we should not, see #8335. + // Always return an empty object. + if ( acceptData( owner ) ) { + + // If it is a node unlikely to be stringify-ed or looped over + // use plain assignment + if ( owner.nodeType ) { + owner[ this.expando ] = value; + + // Otherwise secure it in a non-enumerable property + // configurable must be true to allow the property to be + // deleted when data is removed + } else { + Object.defineProperty( owner, this.expando, { + value: value, + configurable: true + } ); + } + } + } + + return value; + }, + set: function( owner, data, value ) { + var prop, + cache = this.cache( owner ); + + // Handle: [ owner, key, value ] args + // Always use camelCase key (gh-2257) + if ( typeof data === "string" ) { + cache[ camelCase( data ) ] = value; + + // Handle: [ owner, { properties } ] args + } else { + + // Copy the properties one-by-one to the cache object + for ( prop in data ) { + cache[ camelCase( prop ) ] = data[ prop ]; + } + } + return cache; + }, + get: function( owner, key ) { + return key === undefined ? + this.cache( owner ) : + + // Always use camelCase key (gh-2257) + owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; + }, + access: function( owner, key, value ) { + + // In cases where either: + // + // 1. No key was specified + // 2. A string key was specified, but no value provided + // + // Take the "read" path and allow the get method to determine + // which value to return, respectively either: + // + // 1. The entire cache object + // 2. The data stored at the key + // + if ( key === undefined || + ( ( key && typeof key === "string" ) && value === undefined ) ) { + + return this.get( owner, key ); + } + + // When the key is not a string, or both a key and value + // are specified, set or extend (existing objects) with either: + // + // 1. An object of properties + // 2. A key and value + // + this.set( owner, key, value ); + + // Since the "set" path can have two possible entry points + // return the expected data based on which path was taken[*] + return value !== undefined ? value : key; + }, + remove: function( owner, key ) { + var i, + cache = owner[ this.expando ]; + + if ( cache === undefined ) { + return; + } + + if ( key !== undefined ) { + + // Support array or space separated string of keys + if ( Array.isArray( key ) ) { + + // If key is an array of keys... + // We always set camelCase keys, so remove that. + key = key.map( camelCase ); + } else { + key = camelCase( key ); + + // If a key with the spaces exists, use it. + // Otherwise, create an array by matching non-whitespace + key = key in cache ? + [ key ] : + ( key.match( rnothtmlwhite ) || [] ); + } + + i = key.length; + + while ( i-- ) { + delete cache[ key[ i ] ]; + } + } + + // Remove the expando if there's no more data + if ( key === undefined || jQuery.isEmptyObject( cache ) ) { + + // Support: Chrome <=35 - 45 + // Webkit & Blink performance suffers when deleting properties + // from DOM nodes, so set to undefined instead + // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) + if ( owner.nodeType ) { + owner[ this.expando ] = undefined; + } else { + delete owner[ this.expando ]; + } + } + }, + hasData: function( owner ) { + var cache = owner[ this.expando ]; + return cache !== undefined && !jQuery.isEmptyObject( cache ); + } +}; +var dataPriv = new Data(); + +var dataUser = new Data(); + + + +// Implementation Summary +// +// 1. Enforce API surface and semantic compatibility with 1.9.x branch +// 2. Improve the module's maintainability by reducing the storage +// paths to a single mechanism. +// 3. Use the same single mechanism to support "private" and "user" data. +// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) +// 5. Avoid exposing implementation details on user objects (eg. expando properties) +// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 + +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, + rmultiDash = /[A-Z]/g; + +function getData( data ) { + if ( data === "true" ) { + return true; + } + + if ( data === "false" ) { + return false; + } + + if ( data === "null" ) { + return null; + } + + // Only convert to a number if it doesn't change the string + if ( data === +data + "" ) { + return +data; + } + + if ( rbrace.test( data ) ) { + return JSON.parse( data ); + } + + return data; +} + +function dataAttr( elem, key, data ) { + var name; + + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = getData( data ); + } catch ( e ) {} + + // Make sure we set the data so it isn't changed later + dataUser.set( elem, key, data ); + } else { + data = undefined; + } + } + return data; +} + +jQuery.extend( { + hasData: function( elem ) { + return dataUser.hasData( elem ) || dataPriv.hasData( elem ); + }, + + data: function( elem, name, data ) { + return dataUser.access( elem, name, data ); + }, + + removeData: function( elem, name ) { + dataUser.remove( elem, name ); + }, + + // TODO: Now that all calls to _data and _removeData have been replaced + // with direct calls to dataPriv methods, these can be deprecated. + _data: function( elem, name, data ) { + return dataPriv.access( elem, name, data ); + }, + + _removeData: function( elem, name ) { + dataPriv.remove( elem, name ); + } +} ); + +jQuery.fn.extend( { + data: function( key, value ) { + var i, name, data, + elem = this[ 0 ], + attrs = elem && elem.attributes; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = dataUser.get( elem ); + + if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { + i = attrs.length; + while ( i-- ) { + + // Support: IE 11 only + // The attrs elements can be null (#14894) + if ( attrs[ i ] ) { + name = attrs[ i ].name; + if ( name.indexOf( "data-" ) === 0 ) { + name = camelCase( name.slice( 5 ) ); + dataAttr( elem, name, data[ name ] ); + } + } + } + dataPriv.set( elem, "hasDataAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each( function() { + dataUser.set( this, key ); + } ); + } + + return access( this, function( value ) { + var data; + + // The calling jQuery object (element matches) is not empty + // (and therefore has an element appears at this[ 0 ]) and the + // `value` parameter was not undefined. An empty jQuery object + // will result in `undefined` for elem = this[ 0 ] which will + // throw an exception if an attempt to read a data cache is made. + if ( elem && value === undefined ) { + + // Attempt to get data from the cache + // The key will always be camelCased in Data + data = dataUser.get( elem, key ); + if ( data !== undefined ) { + return data; + } + + // Attempt to "discover" the data in + // HTML5 custom data-* attrs + data = dataAttr( elem, key ); + if ( data !== undefined ) { + return data; + } + + // We tried really hard, but the data doesn't exist. + return; + } + + // Set the data... + this.each( function() { + + // We always store the camelCased key + dataUser.set( this, key, value ); + } ); + }, null, value, arguments.length > 1, null, true ); + }, + + removeData: function( key ) { + return this.each( function() { + dataUser.remove( this, key ); + } ); + } +} ); + + +jQuery.extend( { + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = dataPriv.get( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || Array.isArray( data ) ) { + queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // Clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // Not public - generate a queueHooks object, or return the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { + empty: jQuery.Callbacks( "once memory" ).add( function() { + dataPriv.remove( elem, [ type + "queue", key ] ); + } ) + } ); + } +} ); + +jQuery.fn.extend( { + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[ 0 ], type ); + } + + return data === undefined ? + this : + this.each( function() { + var queue = jQuery.queue( this, type, data ); + + // Ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + } ); + }, + dequeue: function( type ) { + return this.each( function() { + jQuery.dequeue( this, type ); + } ); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while ( i-- ) { + tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +} ); +var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; + +var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); + + +var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; + +var isHiddenWithinTree = function( elem, el ) { + + // isHiddenWithinTree might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + + // Inline style trumps all + return elem.style.display === "none" || + elem.style.display === "" && + + // Otherwise, check computed style + // Support: Firefox <=43 - 45 + // Disconnected elements can have computed display: none, so first confirm that elem is + // in the document. + jQuery.contains( elem.ownerDocument, elem ) && + + jQuery.css( elem, "display" ) === "none"; + }; + +var swap = function( elem, options, callback, args ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.apply( elem, args || [] ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; +}; + + + + +function adjustCSS( elem, prop, valueParts, tween ) { + var adjusted, scale, + maxIterations = 20, + currentValue = tween ? + function() { + return tween.cur(); + } : + function() { + return jQuery.css( elem, prop, "" ); + }, + initial = currentValue(), + unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), + + // Starting value computation is required for potential unit mismatches + initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && + rcssNum.exec( jQuery.css( elem, prop ) ); + + if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { + + // Support: Firefox <=54 + // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) + initial = initial / 2; + + // Trust units reported by jQuery.css + unit = unit || initialInUnit[ 3 ]; + + // Iteratively approximate from a nonzero starting point + initialInUnit = +initial || 1; + + while ( maxIterations-- ) { + + // Evaluate and update our best guess (doubling guesses that zero out). + // Finish if the scale equals or crosses 1 (making the old*new product non-positive). + jQuery.style( elem, prop, initialInUnit + unit ); + if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) { + maxIterations = 0; + } + initialInUnit = initialInUnit / scale; + + } + + initialInUnit = initialInUnit * 2; + jQuery.style( elem, prop, initialInUnit + unit ); + + // Make sure we update the tween properties later on + valueParts = valueParts || []; + } + + if ( valueParts ) { + initialInUnit = +initialInUnit || +initial || 0; + + // Apply relative offset (+=/-=) if specified + adjusted = valueParts[ 1 ] ? + initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : + +valueParts[ 2 ]; + if ( tween ) { + tween.unit = unit; + tween.start = initialInUnit; + tween.end = adjusted; + } + } + return adjusted; +} + + +var defaultDisplayMap = {}; + +function getDefaultDisplay( elem ) { + var temp, + doc = elem.ownerDocument, + nodeName = elem.nodeName, + display = defaultDisplayMap[ nodeName ]; + + if ( display ) { + return display; + } + + temp = doc.body.appendChild( doc.createElement( nodeName ) ); + display = jQuery.css( temp, "display" ); + + temp.parentNode.removeChild( temp ); + + if ( display === "none" ) { + display = "block"; + } + defaultDisplayMap[ nodeName ] = display; + + return display; +} + +function showHide( elements, show ) { + var display, elem, + values = [], + index = 0, + length = elements.length; + + // Determine new display value for elements that need to change + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + + display = elem.style.display; + if ( show ) { + + // Since we force visibility upon cascade-hidden elements, an immediate (and slow) + // check is required in this first loop unless we have a nonempty display value (either + // inline or about-to-be-restored) + if ( display === "none" ) { + values[ index ] = dataPriv.get( elem, "display" ) || null; + if ( !values[ index ] ) { + elem.style.display = ""; + } + } + if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { + values[ index ] = getDefaultDisplay( elem ); + } + } else { + if ( display !== "none" ) { + values[ index ] = "none"; + + // Remember what we're overwriting + dataPriv.set( elem, "display", display ); + } + } + } + + // Set the display of the elements in a second loop to avoid constant reflow + for ( index = 0; index < length; index++ ) { + if ( values[ index ] != null ) { + elements[ index ].style.display = values[ index ]; + } + } + + return elements; +} + +jQuery.fn.extend( { + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state ) { + if ( typeof state === "boolean" ) { + return state ? this.show() : this.hide(); + } + + return this.each( function() { + if ( isHiddenWithinTree( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + } ); + } +} ); +var rcheckableType = ( /^(?:checkbox|radio)$/i ); + +var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]+)/i ); + +var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i ); + + + +// We have to close these tags to support XHTML (#13200) +var wrapMap = { + + // Support: IE <=9 only + option: [ 1, "" ], + + // XHTML parsers do not magically insert elements in the + // same way that tag soup parsers do. So we cannot shorten + // this by omitting
or other required elements. + thead: [ 1, "
Whitelisted Positions
Whitelisted Positions
[replacetext(job.title, " ", " ")][replacetext(job.title, " ", " ")][replacetext(job.title, " ", " ")][replacetext(job.title, " ", " ")]
[key_string][H.real_name][job_string][mins_ssd][role_string]
[key_string][H.real_name][job_string][mins_ssd][role_string][obj_string][get_area(H)][ADMIN_PP(H,"PP")]In CryoDe-SpawnCryo
", "
" ], + col: [ 2, "", "
" ], + tr: [ 2, "", "
" ], + td: [ 3, "", "
" ], + + _default: [ 0, "", "" ] +}; + +// Support: IE <=9 only +wrapMap.optgroup = wrapMap.option; + +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + + +function getAll( context, tag ) { + + // Support: IE <=9 - 11 only + // Use typeof to avoid zero-argument method invocation on host objects (#15151) + var ret; + + if ( typeof context.getElementsByTagName !== "undefined" ) { + ret = context.getElementsByTagName( tag || "*" ); + + } else if ( typeof context.querySelectorAll !== "undefined" ) { + ret = context.querySelectorAll( tag || "*" ); + + } else { + ret = []; + } + + if ( tag === undefined || tag && nodeName( context, tag ) ) { + return jQuery.merge( [ context ], ret ); + } + + return ret; +} + + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + dataPriv.set( + elems[ i ], + "globalEval", + !refElements || dataPriv.get( refElements[ i ], "globalEval" ) + ); + } +} + + +var rhtml = /<|&#?\w+;/; + +function buildFragment( elems, context, scripts, selection, ignored ) { + var elem, tmp, tag, wrap, contains, j, + fragment = context.createDocumentFragment(), + nodes = [], + i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( toType( elem ) === "object" ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); + + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; + + // Descend through wrappers to the right content + j = wrap[ 0 ]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, tmp.childNodes ); + + // Remember the top-level container + tmp = fragment.firstChild; + + // Ensure the created nodes are orphaned (#12392) + tmp.textContent = ""; + } + } + } + + // Remove wrapper from fragment + fragment.textContent = ""; + + i = 0; + while ( ( elem = nodes[ i++ ] ) ) { + + // Skip elements already in the context collection (trac-4087) + if ( selection && jQuery.inArray( elem, selection ) > -1 ) { + if ( ignored ) { + ignored.push( elem ); + } + continue; + } + + contains = jQuery.contains( elem.ownerDocument, elem ); + + // Append to fragment + tmp = getAll( fragment.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( contains ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( ( elem = tmp[ j++ ] ) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + return fragment; +} + + +( function() { + var fragment = document.createDocumentFragment(), + div = fragment.appendChild( document.createElement( "div" ) ), + input = document.createElement( "input" ); + + // Support: Android 4.0 - 4.3 only + // Check state lost if the name is set (#11217) + // Support: Windows Web Apps (WWA) + // `name` and `type` must use .setAttribute for WWA (#14901) + input.setAttribute( "type", "radio" ); + input.setAttribute( "checked", "checked" ); + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + + // Support: Android <=4.1 only + // Older WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE <=11 only + // Make sure textarea (and checkbox) defaultValue is properly cloned + div.innerHTML = ""; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; +} )(); +var documentElement = document.documentElement; + + + +var + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +// Support: IE <=9 only +// See #13393 for more info +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +function on( elem, types, selector, data, fn, one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + on( elem, type, selector, data, types[ type ], one ); + } + return elem; + } + + if ( data == null && fn == null ) { + + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return elem; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return elem.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + } ); +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + + var handleObjIn, eventHandle, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.get( elem ); + + // Don't attach events to noData or text/comment nodes (but allow plain objects) + if ( !elemData ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Ensure that invalid selectors throw exceptions at attach time + // Evaluate against documentElement in case elem is a non-element node (e.g., document) + if ( selector ) { + jQuery.find.matchesSelector( documentElement, selector ); + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !( events = elemData.events ) ) { + events = elemData.events = {}; + } + if ( !( eventHandle = elemData.handle ) ) { + eventHandle = elemData.handle = function( e ) { + + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? + jQuery.event.dispatch.apply( elem, arguments ) : undefined; + }; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend( { + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join( "." ) + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !( handlers = events[ type ] ) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener if the special events handler returns false + if ( !special.setup || + special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var j, origCount, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); + + if ( !elemData || !( events = elemData.events ) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[ 2 ] && + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || + selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || + special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove data and the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + dataPriv.remove( elem, "handle events" ); + } + }, + + dispatch: function( nativeEvent ) { + + // Make a writable jQuery.Event from the native event object + var event = jQuery.event.fix( nativeEvent ); + + var i, j, ret, matched, handleObj, handlerQueue, + args = new Array( arguments.length ), + handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[ 0 ] = event; + + for ( i = 1; i < arguments.length; i++ ) { + args[ i ] = arguments[ i ]; + } + + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( ( handleObj = matched.handlers[ j++ ] ) && + !event.isImmediatePropagationStopped() ) { + + // Triggered event must either 1) have no namespace, or 2) have namespace(s) + // a subset or equal to those in the bound event (both can have no namespace). + if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || + handleObj.handler ).apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( ( event.result = ret ) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var i, handleObj, sel, matchedHandlers, matchedSelectors, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + if ( delegateCount && + + // Support: IE <=9 + // Black-hole SVG instance trees (trac-13180) + cur.nodeType && + + // Support: Firefox <=42 + // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) + // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click + // Support: IE 11 only + // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) + !( event.type === "click" && event.button >= 1 ) ) { + + for ( ; cur !== this; cur = cur.parentNode || this ) { + + // Don't check non-elements (#13208) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { + matchedHandlers = []; + matchedSelectors = {}; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matchedSelectors[ sel ] === undefined ) { + matchedSelectors[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) > -1 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matchedSelectors[ sel ] ) { + matchedHandlers.push( handleObj ); + } + } + if ( matchedHandlers.length ) { + handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); + } + } + } + } + + // Add the remaining (directly-bound) handlers + cur = this; + if ( delegateCount < handlers.length ) { + handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); + } + + return handlerQueue; + }, + + addProp: function( name, hook ) { + Object.defineProperty( jQuery.Event.prototype, name, { + enumerable: true, + configurable: true, + + get: isFunction( hook ) ? + function() { + if ( this.originalEvent ) { + return hook( this.originalEvent ); + } + } : + function() { + if ( this.originalEvent ) { + return this.originalEvent[ name ]; + } + }, + + set: function( value ) { + Object.defineProperty( this, name, { + enumerable: true, + configurable: true, + writable: true, + value: value + } ); + } + } ); + }, + + fix: function( originalEvent ) { + return originalEvent[ jQuery.expando ] ? + originalEvent : + new jQuery.Event( originalEvent ); + }, + + special: { + load: { + + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + focus: { + + // Fire native event if possible so blur/focus sequence is correct + trigger: function() { + if ( this !== safeActiveElement() && this.focus ) { + this.focus(); + return false; + } + }, + delegateType: "focusin" + }, + blur: { + trigger: function() { + if ( this === safeActiveElement() && this.blur ) { + this.blur(); + return false; + } + }, + delegateType: "focusout" + }, + click: { + + // For checkbox, fire native event so checked state will be right + trigger: function() { + if ( this.type === "checkbox" && this.click && nodeName( this, "input" ) ) { + this.click(); + return false; + } + }, + + // For cross-browser consistency, don't fire native .click() on links + _default: function( event ) { + return nodeName( event.target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Support: Firefox 20+ + // Firefox doesn't alert if the returnValue field is not set. + if ( event.result !== undefined && event.originalEvent ) { + event.originalEvent.returnValue = event.result; + } + } + } + } +}; + +jQuery.removeEvent = function( elem, type, handle ) { + + // This "if" is needed for plain objects + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle ); + } +}; + +jQuery.Event = function( src, props ) { + + // Allow instantiation without the 'new' keyword + if ( !( this instanceof jQuery.Event ) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented || + src.defaultPrevented === undefined && + + // Support: Android <=2.3 only + src.returnValue === false ? + returnTrue : + returnFalse; + + // Create target properties + // Support: Safari <=6 - 7 only + // Target should not be a text node (#504, #13143) + this.target = ( src.target && src.target.nodeType === 3 ) ? + src.target.parentNode : + src.target; + + this.currentTarget = src.currentTarget; + this.relatedTarget = src.relatedTarget; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || Date.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + constructor: jQuery.Event, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + isSimulated: false, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + + if ( e && !this.isSimulated ) { + e.preventDefault(); + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopPropagation(); + } + }, + stopImmediatePropagation: function() { + var e = this.originalEvent; + + this.isImmediatePropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopImmediatePropagation(); + } + + this.stopPropagation(); + } +}; + +// Includes all common event props including KeyEvent and MouseEvent specific props +jQuery.each( { + altKey: true, + bubbles: true, + cancelable: true, + changedTouches: true, + ctrlKey: true, + detail: true, + eventPhase: true, + metaKey: true, + pageX: true, + pageY: true, + shiftKey: true, + view: true, + "char": true, + charCode: true, + key: true, + keyCode: true, + button: true, + buttons: true, + clientX: true, + clientY: true, + offsetX: true, + offsetY: true, + pointerId: true, + pointerType: true, + screenX: true, + screenY: true, + targetTouches: true, + toElement: true, + touches: true, + + which: function( event ) { + var button = event.button; + + // Add which for key events + if ( event.which == null && rkeyEvent.test( event.type ) ) { + return event.charCode != null ? event.charCode : event.keyCode; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) { + if ( button & 1 ) { + return 1; + } + + if ( button & 2 ) { + return 3; + } + + if ( button & 4 ) { + return 2; + } + + return 0; + } + + return event.which; + } +}, jQuery.event.addProp ); + +// Create mouseenter/leave events using mouseover/out and event-time checks +// so that event delegation works in jQuery. +// Do the same for pointerenter/pointerleave and pointerover/pointerout +// +// Support: Safari 7 only +// Safari sends mouseenter too often; see: +// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 +// for the description of the bug (it existed in older Chrome versions as well). +jQuery.each( { + mouseenter: "mouseover", + mouseleave: "mouseout", + pointerenter: "pointerover", + pointerleave: "pointerout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mouseenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +} ); + +jQuery.fn.extend( { + + on: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn ); + }, + one: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? + handleObj.origType + "." + handleObj.namespace : + handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each( function() { + jQuery.event.remove( this, types, fn, selector ); + } ); + } +} ); + + +var + + /* eslint-disable max-len */ + + // See https://github.com/eslint/eslint/issues/3229 + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi, + + /* eslint-enable */ + + // Support: IE <=10 - 11, Edge 12 - 13 only + // In IE/Edge using regex groups here causes severe slowdowns. + // See https://connect.microsoft.com/IE/feedback/details/1736512/ + rnoInnerhtml = /\s*$/g; + +// Prefer a tbody over its parent table for containing new rows +function manipulationTarget( elem, content ) { + if ( nodeName( elem, "table" ) && + nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { + + return jQuery( elem ).children( "tbody" )[ 0 ] || elem; + } + + return elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { + elem.type = elem.type.slice( 5 ); + } else { + elem.removeAttribute( "type" ); + } + + return elem; +} + +function cloneCopyEvent( src, dest ) { + var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; + + if ( dest.nodeType !== 1 ) { + return; + } + + // 1. Copy private data: events, handlers, etc. + if ( dataPriv.hasData( src ) ) { + pdataOld = dataPriv.access( src ); + pdataCur = dataPriv.set( dest, pdataOld ); + events = pdataOld.events; + + if ( events ) { + delete pdataCur.handle; + pdataCur.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + } + + // 2. Copy user data + if ( dataUser.hasData( src ) ) { + udataOld = dataUser.access( src ); + udataCur = jQuery.extend( {}, udataOld ); + + dataUser.set( dest, udataCur ); + } +} + +// Fix IE bugs, see support tests +function fixInput( src, dest ) { + var nodeName = dest.nodeName.toLowerCase(); + + // Fails to persist the checked state of a cloned checkbox or radio button. + if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + dest.checked = src.checked; + + // Fails to return the selected option to the default selected state when cloning options + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +function domManip( collection, args, callback, ignored ) { + + // Flatten any nested arrays + args = concat.apply( [], args ); + + var fragment, first, scripts, hasScripts, node, doc, + i = 0, + l = collection.length, + iNoClone = l - 1, + value = args[ 0 ], + valueIsFunction = isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( valueIsFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return collection.each( function( index ) { + var self = collection.eq( index ); + if ( valueIsFunction ) { + args[ 0 ] = value.call( this, index, self.html() ); + } + domManip( self, args, callback, ignored ); + } ); + } + + if ( l ) { + fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + // Require either new content or an interest in ignored elements to invoke the callback + if ( first || ignored ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item + // instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( collection[ i ], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !dataPriv.access( node, "globalEval" ) && + jQuery.contains( doc, node ) ) { + + if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { + + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl ) { + jQuery._evalUrl( node.src ); + } + } else { + DOMEval( node.textContent.replace( rcleanScript, "" ), doc, node ); + } + } + } + } + } + } + + return collection; +} + +function remove( elem, selector, keepData ) { + var node, + nodes = selector ? jQuery.filter( selector, elem ) : elem, + i = 0; + + for ( ; ( node = nodes[ i ] ) != null; i++ ) { + if ( !keepData && node.nodeType === 1 ) { + jQuery.cleanData( getAll( node ) ); + } + + if ( node.parentNode ) { + if ( keepData && jQuery.contains( node.ownerDocument, node ) ) { + setGlobalEval( getAll( node, "script" ) ); + } + node.parentNode.removeChild( node ); + } + } + + return elem; +} + +jQuery.extend( { + htmlPrefilter: function( html ) { + return html.replace( rxhtmlTag, "<$1>" ); + }, + + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var i, l, srcElements, destElements, + clone = elem.cloneNode( true ), + inPage = jQuery.contains( elem.ownerDocument, elem ); + + // Fix IE cloning issues + if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && + !jQuery.isXMLDoc( elem ) ) { + + // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + fixInput( srcElements[ i ], destElements[ i ] ); + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + cloneCopyEvent( srcElements[ i ], destElements[ i ] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + // Return the cloned set + return clone; + }, + + cleanData: function( elems ) { + var data, elem, type, + special = jQuery.event.special, + i = 0; + + for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { + if ( acceptData( elem ) ) { + if ( ( data = elem[ dataPriv.expando ] ) ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataPriv.expando ] = undefined; + } + if ( elem[ dataUser.expando ] ) { + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataUser.expando ] = undefined; + } + } + } + } +} ); + +jQuery.fn.extend( { + detach: function( selector ) { + return remove( this, selector, true ); + }, + + remove: function( selector ) { + return remove( this, selector ); + }, + + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().each( function() { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + this.textContent = value; + } + } ); + }, null, value, arguments.length ); + }, + + append: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + } ); + }, + + prepend: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + } ); + }, + + before: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + } ); + }, + + after: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + } ); + }, + + empty: function() { + var elem, + i = 0; + + for ( ; ( elem = this[ i ] ) != null; i++ ) { + if ( elem.nodeType === 1 ) { + + // Prevent memory leaks + jQuery.cleanData( getAll( elem, false ) ); + + // Remove any remaining nodes + elem.textContent = ""; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + } ); + }, + + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; + + if ( value === undefined && elem.nodeType === 1 ) { + return elem.innerHTML; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { + + value = jQuery.htmlPrefilter( value ); + + try { + for ( ; i < l; i++ ) { + elem = this[ i ] || {}; + + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch ( e ) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var ignored = []; + + // Make the changes, replacing each non-ignored context element with the new content + return domManip( this, arguments, function( elem ) { + var parent = this.parentNode; + + if ( jQuery.inArray( this, ignored ) < 0 ) { + jQuery.cleanData( getAll( this ) ); + if ( parent ) { + parent.replaceChild( elem, this ); + } + } + + // Force callback invocation + }, ignored ); + } +} ); + +jQuery.each( { + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1, + i = 0; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone( true ); + jQuery( insert[ i ] )[ original ]( elems ); + + // Support: Android <=4.0 only, PhantomJS 1 only + // .get() because push.apply(_, arraylike) throws on ancient WebKit + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +} ); +var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); + +var getStyles = function( elem ) { + + // Support: IE <=11 only, Firefox <=30 (#15098, #14150) + // IE throws on elements created in popups + // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" + var view = elem.ownerDocument.defaultView; + + if ( !view || !view.opener ) { + view = window; + } + + return view.getComputedStyle( elem ); + }; + +var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); + + + +( function() { + + // Executing both pixelPosition & boxSizingReliable tests require only one layout + // so they're executed at the same time to save the second computation. + function computeStyleTests() { + + // This is a singleton, we need to execute it only once + if ( !div ) { + return; + } + + container.style.cssText = "position:absolute;left:-11111px;width:60px;" + + "margin-top:1px;padding:0;border:0"; + div.style.cssText = + "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + + "margin:auto;border:1px;padding:1px;" + + "width:60%;top:1%"; + documentElement.appendChild( container ).appendChild( div ); + + var divStyle = window.getComputedStyle( div ); + pixelPositionVal = divStyle.top !== "1%"; + + // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 + reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; + + // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 + // Some styles come back with percentage values, even though they shouldn't + div.style.right = "60%"; + pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; + + // Support: IE 9 - 11 only + // Detect misreporting of content dimensions for box-sizing:border-box elements + boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; + + // Support: IE 9 only + // Detect overflow:scroll screwiness (gh-3699) + div.style.position = "absolute"; + scrollboxSizeVal = div.offsetWidth === 36 || "absolute"; + + documentElement.removeChild( container ); + + // Nullify the div so it wouldn't be stored in the memory and + // it will also be a sign that checks already performed + div = null; + } + + function roundPixelMeasures( measure ) { + return Math.round( parseFloat( measure ) ); + } + + var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, + reliableMarginLeftVal, + container = document.createElement( "div" ), + div = document.createElement( "div" ); + + // Finish early in limited (non-browser) environments + if ( !div.style ) { + return; + } + + // Support: IE <=9 - 11 only + // Style of cloned element affects source element cloned (#8908) + div.style.backgroundClip = "content-box"; + div.cloneNode( true ).style.backgroundClip = ""; + support.clearCloneStyle = div.style.backgroundClip === "content-box"; + + jQuery.extend( support, { + boxSizingReliable: function() { + computeStyleTests(); + return boxSizingReliableVal; + }, + pixelBoxStyles: function() { + computeStyleTests(); + return pixelBoxStylesVal; + }, + pixelPosition: function() { + computeStyleTests(); + return pixelPositionVal; + }, + reliableMarginLeft: function() { + computeStyleTests(); + return reliableMarginLeftVal; + }, + scrollboxSize: function() { + computeStyleTests(); + return scrollboxSizeVal; + } + } ); +} )(); + + +function curCSS( elem, name, computed ) { + var width, minWidth, maxWidth, ret, + + // Support: Firefox 51+ + // Retrieving style before computed somehow + // fixes an issue with getting wrong values + // on detached elements + style = elem.style; + + computed = computed || getStyles( elem ); + + // getPropertyValue is needed for: + // .css('filter') (IE 9 only, #12537) + // .css('--customProperty) (#3144) + if ( computed ) { + ret = computed.getPropertyValue( name ) || computed[ name ]; + + if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Android Browser returns percentage for some values, + // but width seems to be reliably pixels. + // This is against the CSSOM draft spec: + // https://drafts.csswg.org/cssom/#resolved-values + if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { + + // Remember the original values + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + // Put in the new values to get a computed value out + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + // Revert the changed values + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret !== undefined ? + + // Support: IE <=9 - 11 only + // IE returns zIndex value as an integer. + ret + "" : + ret; +} + + +function addGetHookIf( conditionFn, hookFn ) { + + // Define the hook, we'll check on the first run if it's really needed. + return { + get: function() { + if ( conditionFn() ) { + + // Hook not needed (or it's not possible to use it due + // to missing dependency), remove it. + delete this.get; + return; + } + + // Hook needed; redefine it so that the support test is not executed again. + return ( this.get = hookFn ).apply( this, arguments ); + } + }; +} + + +var + + // Swappable if display is none or starts with table + // except "table", "table-cell", or "table-caption" + // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rcustomProp = /^--/, + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: "0", + fontWeight: "400" + }, + + cssPrefixes = [ "Webkit", "Moz", "ms" ], + emptyStyle = document.createElement( "div" ).style; + +// Return a css property mapped to a potentially vendor prefixed property +function vendorPropName( name ) { + + // Shortcut for names that are not vendor prefixed + if ( name in emptyStyle ) { + return name; + } + + // Check for vendor prefixed names + var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in emptyStyle ) { + return name; + } + } +} + +// Return a property mapped along what jQuery.cssProps suggests or to +// a vendor prefixed property. +function finalPropName( name ) { + var ret = jQuery.cssProps[ name ]; + if ( !ret ) { + ret = jQuery.cssProps[ name ] = vendorPropName( name ) || name; + } + return ret; +} + +function setPositiveNumber( elem, value, subtract ) { + + // Any relative (+/-) values have already been + // normalized at this point + var matches = rcssNum.exec( value ); + return matches ? + + // Guard against undefined "subtract", e.g., when used as in cssHooks + Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : + value; +} + +function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { + var i = dimension === "width" ? 1 : 0, + extra = 0, + delta = 0; + + // Adjustment may not be necessary + if ( box === ( isBorderBox ? "border" : "content" ) ) { + return 0; + } + + for ( ; i < 4; i += 2 ) { + + // Both box models exclude margin + if ( box === "margin" ) { + delta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); + } + + // If we get here with a content-box, we're seeking "padding" or "border" or "margin" + if ( !isBorderBox ) { + + // Add padding + delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + + // For "border" or "margin", add border + if ( box !== "padding" ) { + delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + + // But still keep track of it otherwise + } else { + extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + + // If we get here with a border-box (content + padding + border), we're seeking "content" or + // "padding" or "margin" + } else { + + // For "content", subtract padding + if ( box === "content" ) { + delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + } + + // For "content" or "padding", subtract border + if ( box !== "margin" ) { + delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } + } + + // Account for positive content-box scroll gutter when requested by providing computedVal + if ( !isBorderBox && computedVal >= 0 ) { + + // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border + // Assuming integer scroll gutter, subtract the rest and round down + delta += Math.max( 0, Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + computedVal - + delta - + extra - + 0.5 + ) ); + } + + return delta; +} + +function getWidthOrHeight( elem, dimension, extra ) { + + // Start with computed style + var styles = getStyles( elem ), + val = curCSS( elem, dimension, styles ), + isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + valueIsBorderBox = isBorderBox; + + // Support: Firefox <=54 + // Return a confounding non-pixel value or feign ignorance, as appropriate. + if ( rnumnonpx.test( val ) ) { + if ( !extra ) { + return val; + } + val = "auto"; + } + + // Check for style in case a browser which returns unreliable values + // for getComputedStyle silently falls back to the reliable elem.style + valueIsBorderBox = valueIsBorderBox && + ( support.boxSizingReliable() || val === elem.style[ dimension ] ); + + // Fall back to offsetWidth/offsetHeight when value is "auto" + // This happens for inline elements with no explicit setting (gh-3571) + // Support: Android <=4.1 - 4.3 only + // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) + if ( val === "auto" || + !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) { + + val = elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ]; + + // offsetWidth/offsetHeight provide border-box values + valueIsBorderBox = true; + } + + // Normalize "" and auto + val = parseFloat( val ) || 0; + + // Adjust for the element's box model + return ( val + + boxModelAdjustment( + elem, + dimension, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox, + styles, + + // Provide the current computed size to request scroll gutter calculation (gh-3589) + val + ) + ) + "px"; +} + +jQuery.extend( { + + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + } + } + } + }, + + // Don't automatically add "px" to these possibly-unitless properties + cssNumber: { + "animationIterationCount": true, + "columnCount": true, + "fillOpacity": true, + "flexGrow": true, + "flexShrink": true, + "fontWeight": true, + "lineHeight": true, + "opacity": true, + "order": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: {}, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ), + style = elem.style; + + // Make sure that we're working with the right name. We don't + // want to query the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Gets hook for the prefixed version, then unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // Convert "+=" or "-=" to relative numbers (#7345) + if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { + value = adjustCSS( elem, name, ret ); + + // Fixes bug #9237 + type = "number"; + } + + // Make sure that null and NaN values aren't set (#7116) + if ( value == null || value !== value ) { + return; + } + + // If a number was passed in, add the unit (except for certain CSS properties) + if ( type === "number" ) { + value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); + } + + // background-* props affect original clone's values + if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { + style[ name ] = "inherit"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !( "set" in hooks ) || + ( value = hooks.set( elem, value, extra ) ) !== undefined ) { + + if ( isCustomProp ) { + style.setProperty( name, value ); + } else { + style[ name ] = value; + } + } + + } else { + + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && + ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { + + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, extra, styles ) { + var val, num, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ); + + // Make sure that we're working with the right name. We don't + // want to modify the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Try prefixed name followed by the unprefixed name + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name, styles ); + } + + // Convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Make numeric if forced or a qualifier was provided and val looks numeric + if ( extra === "" || extra ) { + num = parseFloat( val ); + return extra === true || isFinite( num ) ? num || 0 : val; + } + + return val; + } +} ); + +jQuery.each( [ "height", "width" ], function( i, dimension ) { + jQuery.cssHooks[ dimension ] = { + get: function( elem, computed, extra ) { + if ( computed ) { + + // Certain elements can have dimension info if we invisibly show them + // but it must have a current display style that would benefit + return rdisplayswap.test( jQuery.css( elem, "display" ) ) && + + // Support: Safari 8+ + // Table columns in Safari have non-zero offsetWidth & zero + // getBoundingClientRect().width unless display is changed. + // Support: IE <=11 only + // Running getBoundingClientRect on a disconnected node + // in IE throws an error. + ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? + swap( elem, cssShow, function() { + return getWidthOrHeight( elem, dimension, extra ); + } ) : + getWidthOrHeight( elem, dimension, extra ); + } + }, + + set: function( elem, value, extra ) { + var matches, + styles = getStyles( elem ), + isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + subtract = extra && boxModelAdjustment( + elem, + dimension, + extra, + isBorderBox, + styles + ); + + // Account for unreliable border-box dimensions by comparing offset* to computed and + // faking a content-box to get border and padding (gh-3699) + if ( isBorderBox && support.scrollboxSize() === styles.position ) { + subtract -= Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + parseFloat( styles[ dimension ] ) - + boxModelAdjustment( elem, dimension, "border", false, styles ) - + 0.5 + ); + } + + // Convert to pixels if value adjustment is needed + if ( subtract && ( matches = rcssNum.exec( value ) ) && + ( matches[ 3 ] || "px" ) !== "px" ) { + + elem.style[ dimension ] = value; + value = jQuery.css( elem, dimension ); + } + + return setPositiveNumber( elem, value, subtract ); + } + }; +} ); + +jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, + function( elem, computed ) { + if ( computed ) { + return ( parseFloat( curCSS( elem, "marginLeft" ) ) || + elem.getBoundingClientRect().left - + swap( elem, { marginLeft: 0 }, function() { + return elem.getBoundingClientRect().left; + } ) + ) + "px"; + } + } +); + +// These hooks are used by animate to expand properties +jQuery.each( { + margin: "", + padding: "", + border: "Width" +}, function( prefix, suffix ) { + jQuery.cssHooks[ prefix + suffix ] = { + expand: function( value ) { + var i = 0, + expanded = {}, + + // Assumes a single number if not a string + parts = typeof value === "string" ? value.split( " " ) : [ value ]; + + for ( ; i < 4; i++ ) { + expanded[ prefix + cssExpand[ i ] + suffix ] = + parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; + } + + return expanded; + } + }; + + if ( prefix !== "margin" ) { + jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; + } +} ); + +jQuery.fn.extend( { + css: function( name, value ) { + return access( this, function( elem, name, value ) { + var styles, len, + map = {}, + i = 0; + + if ( Array.isArray( name ) ) { + styles = getStyles( elem ); + len = name.length; + + for ( ; i < len; i++ ) { + map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); + } + + return map; + } + + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + } +} ); + + +function Tween( elem, options, prop, end, easing ) { + return new Tween.prototype.init( elem, options, prop, end, easing ); +} +jQuery.Tween = Tween; + +Tween.prototype = { + constructor: Tween, + init: function( elem, options, prop, end, easing, unit ) { + this.elem = elem; + this.prop = prop; + this.easing = easing || jQuery.easing._default; + this.options = options; + this.start = this.now = this.cur(); + this.end = end; + this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + }, + cur: function() { + var hooks = Tween.propHooks[ this.prop ]; + + return hooks && hooks.get ? + hooks.get( this ) : + Tween.propHooks._default.get( this ); + }, + run: function( percent ) { + var eased, + hooks = Tween.propHooks[ this.prop ]; + + if ( this.options.duration ) { + this.pos = eased = jQuery.easing[ this.easing ]( + percent, this.options.duration * percent, 0, 1, this.options.duration + ); + } else { + this.pos = eased = percent; + } + this.now = ( this.end - this.start ) * eased + this.start; + + if ( this.options.step ) { + this.options.step.call( this.elem, this.now, this ); + } + + if ( hooks && hooks.set ) { + hooks.set( this ); + } else { + Tween.propHooks._default.set( this ); + } + return this; + } +}; + +Tween.prototype.init.prototype = Tween.prototype; + +Tween.propHooks = { + _default: { + get: function( tween ) { + var result; + + // Use a property on the element directly when it is not a DOM element, + // or when there is no matching style property that exists. + if ( tween.elem.nodeType !== 1 || + tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { + return tween.elem[ tween.prop ]; + } + + // Passing an empty string as a 3rd parameter to .css will automatically + // attempt a parseFloat and fallback to a string if the parse fails. + // Simple values such as "10px" are parsed to Float; + // complex values such as "rotate(1rad)" are returned as-is. + result = jQuery.css( tween.elem, tween.prop, "" ); + + // Empty strings, null, undefined and "auto" are converted to 0. + return !result || result === "auto" ? 0 : result; + }, + set: function( tween ) { + + // Use step hook for back compat. + // Use cssHook if its there. + // Use .style if available and use plain properties where available. + if ( jQuery.fx.step[ tween.prop ] ) { + jQuery.fx.step[ tween.prop ]( tween ); + } else if ( tween.elem.nodeType === 1 && + ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || + jQuery.cssHooks[ tween.prop ] ) ) { + jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); + } else { + tween.elem[ tween.prop ] = tween.now; + } + } + } +}; + +// Support: IE <=9 only +// Panic based approach to setting things on disconnected nodes +Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { + set: function( tween ) { + if ( tween.elem.nodeType && tween.elem.parentNode ) { + tween.elem[ tween.prop ] = tween.now; + } + } +}; + +jQuery.easing = { + linear: function( p ) { + return p; + }, + swing: function( p ) { + return 0.5 - Math.cos( p * Math.PI ) / 2; + }, + _default: "swing" +}; + +jQuery.fx = Tween.prototype.init; + +// Back compat <1.8 extension point +jQuery.fx.step = {}; + + + + +var + fxNow, inProgress, + rfxtypes = /^(?:toggle|show|hide)$/, + rrun = /queueHooks$/; + +function schedule() { + if ( inProgress ) { + if ( document.hidden === false && window.requestAnimationFrame ) { + window.requestAnimationFrame( schedule ); + } else { + window.setTimeout( schedule, jQuery.fx.interval ); + } + + jQuery.fx.tick(); + } +} + +// Animations created synchronously will run synchronously +function createFxNow() { + window.setTimeout( function() { + fxNow = undefined; + } ); + return ( fxNow = Date.now() ); +} + +// Generate parameters to create a standard animation +function genFx( type, includeWidth ) { + var which, + i = 0, + attrs = { height: type }; + + // If we include width, step value is 1 to do all cssExpand values, + // otherwise step value is 2 to skip over Left and Right + includeWidth = includeWidth ? 1 : 0; + for ( ; i < 4; i += 2 - includeWidth ) { + which = cssExpand[ i ]; + attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; + } + + if ( includeWidth ) { + attrs.opacity = attrs.width = type; + } + + return attrs; +} + +function createTween( value, prop, animation ) { + var tween, + collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), + index = 0, + length = collection.length; + for ( ; index < length; index++ ) { + if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { + + // We're done with this property + return tween; + } + } +} + +function defaultPrefilter( elem, props, opts ) { + var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, + isBox = "width" in props || "height" in props, + anim = this, + orig = {}, + style = elem.style, + hidden = elem.nodeType && isHiddenWithinTree( elem ), + dataShow = dataPriv.get( elem, "fxshow" ); + + // Queue-skipping animations hijack the fx hooks + if ( !opts.queue ) { + hooks = jQuery._queueHooks( elem, "fx" ); + if ( hooks.unqueued == null ) { + hooks.unqueued = 0; + oldfire = hooks.empty.fire; + hooks.empty.fire = function() { + if ( !hooks.unqueued ) { + oldfire(); + } + }; + } + hooks.unqueued++; + + anim.always( function() { + + // Ensure the complete handler is called before this completes + anim.always( function() { + hooks.unqueued--; + if ( !jQuery.queue( elem, "fx" ).length ) { + hooks.empty.fire(); + } + } ); + } ); + } + + // Detect show/hide animations + for ( prop in props ) { + value = props[ prop ]; + if ( rfxtypes.test( value ) ) { + delete props[ prop ]; + toggle = toggle || value === "toggle"; + if ( value === ( hidden ? "hide" : "show" ) ) { + + // Pretend to be hidden if this is a "show" and + // there is still data from a stopped show/hide + if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { + hidden = true; + + // Ignore all other no-op show/hide data + } else { + continue; + } + } + orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); + } + } + + // Bail out if this is a no-op like .hide().hide() + propTween = !jQuery.isEmptyObject( props ); + if ( !propTween && jQuery.isEmptyObject( orig ) ) { + return; + } + + // Restrict "overflow" and "display" styles during box animations + if ( isBox && elem.nodeType === 1 ) { + + // Support: IE <=9 - 11, Edge 12 - 15 + // Record all 3 overflow attributes because IE does not infer the shorthand + // from identically-valued overflowX and overflowY and Edge just mirrors + // the overflowX value there. + opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; + + // Identify a display type, preferring old show/hide data over the CSS cascade + restoreDisplay = dataShow && dataShow.display; + if ( restoreDisplay == null ) { + restoreDisplay = dataPriv.get( elem, "display" ); + } + display = jQuery.css( elem, "display" ); + if ( display === "none" ) { + if ( restoreDisplay ) { + display = restoreDisplay; + } else { + + // Get nonempty value(s) by temporarily forcing visibility + showHide( [ elem ], true ); + restoreDisplay = elem.style.display || restoreDisplay; + display = jQuery.css( elem, "display" ); + showHide( [ elem ] ); + } + } + + // Animate inline elements as inline-block + if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { + if ( jQuery.css( elem, "float" ) === "none" ) { + + // Restore the original display value at the end of pure show/hide animations + if ( !propTween ) { + anim.done( function() { + style.display = restoreDisplay; + } ); + if ( restoreDisplay == null ) { + display = style.display; + restoreDisplay = display === "none" ? "" : display; + } + } + style.display = "inline-block"; + } + } + } + + if ( opts.overflow ) { + style.overflow = "hidden"; + anim.always( function() { + style.overflow = opts.overflow[ 0 ]; + style.overflowX = opts.overflow[ 1 ]; + style.overflowY = opts.overflow[ 2 ]; + } ); + } + + // Implement show/hide animations + propTween = false; + for ( prop in orig ) { + + // General show/hide setup for this element animation + if ( !propTween ) { + if ( dataShow ) { + if ( "hidden" in dataShow ) { + hidden = dataShow.hidden; + } + } else { + dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); + } + + // Store hidden/visible for toggle so `.stop().toggle()` "reverses" + if ( toggle ) { + dataShow.hidden = !hidden; + } + + // Show elements before animating them + if ( hidden ) { + showHide( [ elem ], true ); + } + + /* eslint-disable no-loop-func */ + + anim.done( function() { + + /* eslint-enable no-loop-func */ + + // The final step of a "hide" animation is actually hiding the element + if ( !hidden ) { + showHide( [ elem ] ); + } + dataPriv.remove( elem, "fxshow" ); + for ( prop in orig ) { + jQuery.style( elem, prop, orig[ prop ] ); + } + } ); + } + + // Per-property setup + propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); + if ( !( prop in dataShow ) ) { + dataShow[ prop ] = propTween.start; + if ( hidden ) { + propTween.end = propTween.start; + propTween.start = 0; + } + } + } +} + +function propFilter( props, specialEasing ) { + var index, name, easing, value, hooks; + + // camelCase, specialEasing and expand cssHook pass + for ( index in props ) { + name = camelCase( index ); + easing = specialEasing[ name ]; + value = props[ index ]; + if ( Array.isArray( value ) ) { + easing = value[ 1 ]; + value = props[ index ] = value[ 0 ]; + } + + if ( index !== name ) { + props[ name ] = value; + delete props[ index ]; + } + + hooks = jQuery.cssHooks[ name ]; + if ( hooks && "expand" in hooks ) { + value = hooks.expand( value ); + delete props[ name ]; + + // Not quite $.extend, this won't overwrite existing keys. + // Reusing 'index' because we have the correct "name" + for ( index in value ) { + if ( !( index in props ) ) { + props[ index ] = value[ index ]; + specialEasing[ index ] = easing; + } + } + } else { + specialEasing[ name ] = easing; + } + } +} + +function Animation( elem, properties, options ) { + var result, + stopped, + index = 0, + length = Animation.prefilters.length, + deferred = jQuery.Deferred().always( function() { + + // Don't match elem in the :animated selector + delete tick.elem; + } ), + tick = function() { + if ( stopped ) { + return false; + } + var currentTime = fxNow || createFxNow(), + remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), + + // Support: Android 2.3 only + // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) + temp = remaining / animation.duration || 0, + percent = 1 - temp, + index = 0, + length = animation.tweens.length; + + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( percent ); + } + + deferred.notifyWith( elem, [ animation, percent, remaining ] ); + + // If there's more to do, yield + if ( percent < 1 && length ) { + return remaining; + } + + // If this was an empty animation, synthesize a final progress notification + if ( !length ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + } + + // Resolve the animation and report its conclusion + deferred.resolveWith( elem, [ animation ] ); + return false; + }, + animation = deferred.promise( { + elem: elem, + props: jQuery.extend( {}, properties ), + opts: jQuery.extend( true, { + specialEasing: {}, + easing: jQuery.easing._default + }, options ), + originalProperties: properties, + originalOptions: options, + startTime: fxNow || createFxNow(), + duration: options.duration, + tweens: [], + createTween: function( prop, end ) { + var tween = jQuery.Tween( elem, animation.opts, prop, end, + animation.opts.specialEasing[ prop ] || animation.opts.easing ); + animation.tweens.push( tween ); + return tween; + }, + stop: function( gotoEnd ) { + var index = 0, + + // If we are going to the end, we want to run all the tweens + // otherwise we skip this part + length = gotoEnd ? animation.tweens.length : 0; + if ( stopped ) { + return this; + } + stopped = true; + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( 1 ); + } + + // Resolve when we played the last frame; otherwise, reject + if ( gotoEnd ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + deferred.resolveWith( elem, [ animation, gotoEnd ] ); + } else { + deferred.rejectWith( elem, [ animation, gotoEnd ] ); + } + return this; + } + } ), + props = animation.props; + + propFilter( props, animation.opts.specialEasing ); + + for ( ; index < length; index++ ) { + result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); + if ( result ) { + if ( isFunction( result.stop ) ) { + jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = + result.stop.bind( result ); + } + return result; + } + } + + jQuery.map( props, createTween, animation ); + + if ( isFunction( animation.opts.start ) ) { + animation.opts.start.call( elem, animation ); + } + + // Attach callbacks from options + animation + .progress( animation.opts.progress ) + .done( animation.opts.done, animation.opts.complete ) + .fail( animation.opts.fail ) + .always( animation.opts.always ); + + jQuery.fx.timer( + jQuery.extend( tick, { + elem: elem, + anim: animation, + queue: animation.opts.queue + } ) + ); + + return animation; +} + +jQuery.Animation = jQuery.extend( Animation, { + + tweeners: { + "*": [ function( prop, value ) { + var tween = this.createTween( prop, value ); + adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); + return tween; + } ] + }, + + tweener: function( props, callback ) { + if ( isFunction( props ) ) { + callback = props; + props = [ "*" ]; + } else { + props = props.match( rnothtmlwhite ); + } + + var prop, + index = 0, + length = props.length; + + for ( ; index < length; index++ ) { + prop = props[ index ]; + Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; + Animation.tweeners[ prop ].unshift( callback ); + } + }, + + prefilters: [ defaultPrefilter ], + + prefilter: function( callback, prepend ) { + if ( prepend ) { + Animation.prefilters.unshift( callback ); + } else { + Animation.prefilters.push( callback ); + } + } +} ); + +jQuery.speed = function( speed, easing, fn ) { + var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { + complete: fn || !fn && easing || + isFunction( speed ) && speed, + duration: speed, + easing: fn && easing || easing && !isFunction( easing ) && easing + }; + + // Go to the end state if fx are off + if ( jQuery.fx.off ) { + opt.duration = 0; + + } else { + if ( typeof opt.duration !== "number" ) { + if ( opt.duration in jQuery.fx.speeds ) { + opt.duration = jQuery.fx.speeds[ opt.duration ]; + + } else { + opt.duration = jQuery.fx.speeds._default; + } + } + } + + // Normalize opt.queue - true/undefined/null -> "fx" + if ( opt.queue == null || opt.queue === true ) { + opt.queue = "fx"; + } + + // Queueing + opt.old = opt.complete; + + opt.complete = function() { + if ( isFunction( opt.old ) ) { + opt.old.call( this ); + } + + if ( opt.queue ) { + jQuery.dequeue( this, opt.queue ); + } + }; + + return opt; +}; + +jQuery.fn.extend( { + fadeTo: function( speed, to, easing, callback ) { + + // Show any hidden elements after setting opacity to 0 + return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() + + // Animate to the value specified + .end().animate( { opacity: to }, speed, easing, callback ); + }, + animate: function( prop, speed, easing, callback ) { + var empty = jQuery.isEmptyObject( prop ), + optall = jQuery.speed( speed, easing, callback ), + doAnimation = function() { + + // Operate on a copy of prop so per-property easing won't be lost + var anim = Animation( this, jQuery.extend( {}, prop ), optall ); + + // Empty animations, or finishing resolves immediately + if ( empty || dataPriv.get( this, "finish" ) ) { + anim.stop( true ); + } + }; + doAnimation.finish = doAnimation; + + return empty || optall.queue === false ? + this.each( doAnimation ) : + this.queue( optall.queue, doAnimation ); + }, + stop: function( type, clearQueue, gotoEnd ) { + var stopQueue = function( hooks ) { + var stop = hooks.stop; + delete hooks.stop; + stop( gotoEnd ); + }; + + if ( typeof type !== "string" ) { + gotoEnd = clearQueue; + clearQueue = type; + type = undefined; + } + if ( clearQueue && type !== false ) { + this.queue( type || "fx", [] ); + } + + return this.each( function() { + var dequeue = true, + index = type != null && type + "queueHooks", + timers = jQuery.timers, + data = dataPriv.get( this ); + + if ( index ) { + if ( data[ index ] && data[ index ].stop ) { + stopQueue( data[ index ] ); + } + } else { + for ( index in data ) { + if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { + stopQueue( data[ index ] ); + } + } + } + + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && + ( type == null || timers[ index ].queue === type ) ) { + + timers[ index ].anim.stop( gotoEnd ); + dequeue = false; + timers.splice( index, 1 ); + } + } + + // Start the next in the queue if the last step wasn't forced. + // Timers currently will call their complete callbacks, which + // will dequeue but only if they were gotoEnd. + if ( dequeue || !gotoEnd ) { + jQuery.dequeue( this, type ); + } + } ); + }, + finish: function( type ) { + if ( type !== false ) { + type = type || "fx"; + } + return this.each( function() { + var index, + data = dataPriv.get( this ), + queue = data[ type + "queue" ], + hooks = data[ type + "queueHooks" ], + timers = jQuery.timers, + length = queue ? queue.length : 0; + + // Enable finishing flag on private data + data.finish = true; + + // Empty the queue first + jQuery.queue( this, type, [] ); + + if ( hooks && hooks.stop ) { + hooks.stop.call( this, true ); + } + + // Look for any active animations, and finish them + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && timers[ index ].queue === type ) { + timers[ index ].anim.stop( true ); + timers.splice( index, 1 ); + } + } + + // Look for any animations in the old queue and finish them + for ( index = 0; index < length; index++ ) { + if ( queue[ index ] && queue[ index ].finish ) { + queue[ index ].finish.call( this ); + } + } + + // Turn off finishing flag + delete data.finish; + } ); + } +} ); + +jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) { + var cssFn = jQuery.fn[ name ]; + jQuery.fn[ name ] = function( speed, easing, callback ) { + return speed == null || typeof speed === "boolean" ? + cssFn.apply( this, arguments ) : + this.animate( genFx( name, true ), speed, easing, callback ); + }; +} ); + +// Generate shortcuts for custom animations +jQuery.each( { + slideDown: genFx( "show" ), + slideUp: genFx( "hide" ), + slideToggle: genFx( "toggle" ), + fadeIn: { opacity: "show" }, + fadeOut: { opacity: "hide" }, + fadeToggle: { opacity: "toggle" } +}, function( name, props ) { + jQuery.fn[ name ] = function( speed, easing, callback ) { + return this.animate( props, speed, easing, callback ); + }; +} ); + +jQuery.timers = []; +jQuery.fx.tick = function() { + var timer, + i = 0, + timers = jQuery.timers; + + fxNow = Date.now(); + + for ( ; i < timers.length; i++ ) { + timer = timers[ i ]; + + // Run the timer and safely remove it when done (allowing for external removal) + if ( !timer() && timers[ i ] === timer ) { + timers.splice( i--, 1 ); + } + } + + if ( !timers.length ) { + jQuery.fx.stop(); + } + fxNow = undefined; +}; + +jQuery.fx.timer = function( timer ) { + jQuery.timers.push( timer ); + jQuery.fx.start(); +}; + +jQuery.fx.interval = 13; +jQuery.fx.start = function() { + if ( inProgress ) { + return; + } + + inProgress = true; + schedule(); +}; + +jQuery.fx.stop = function() { + inProgress = null; +}; + +jQuery.fx.speeds = { + slow: 600, + fast: 200, + + // Default speed + _default: 400 +}; + + +// Based off of the plugin by Clint Helfers, with permission. +// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ +jQuery.fn.delay = function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = window.setTimeout( next, time ); + hooks.stop = function() { + window.clearTimeout( timeout ); + }; + } ); +}; + + +( function() { + var input = document.createElement( "input" ), + select = document.createElement( "select" ), + opt = select.appendChild( document.createElement( "option" ) ); + + input.type = "checkbox"; + + // Support: Android <=4.3 only + // Default value for a checkbox should be "on" + support.checkOn = input.value !== ""; + + // Support: IE <=11 only + // Must access selectedIndex to make default options select + support.optSelected = opt.selected; + + // Support: IE <=11 only + // An input loses its value after becoming a radio + input = document.createElement( "input" ); + input.value = "t"; + input.type = "radio"; + support.radioValue = input.value === "t"; +} )(); + + +var boolHook, + attrHandle = jQuery.expr.attrHandle; + +jQuery.fn.extend( { + attr: function( name, value ) { + return access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each( function() { + jQuery.removeAttr( this, name ); + } ); + } +} ); + +jQuery.extend( { + attr: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set attributes on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + // Attribute hooks are determined by the lowercase version + // Grab necessary hook if one is defined + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + hooks = jQuery.attrHooks[ name.toLowerCase() ] || + ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); + } + + if ( value !== undefined ) { + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + } + + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + elem.setAttribute( name, value + "" ); + return value; + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + ret = jQuery.find.attr( elem, name ); + + // Non-existent attributes return null, we normalize to undefined + return ret == null ? undefined : ret; + }, + + attrHooks: { + type: { + set: function( elem, value ) { + if ( !support.radioValue && value === "radio" && + nodeName( elem, "input" ) ) { + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + } + }, + + removeAttr: function( elem, value ) { + var name, + i = 0, + + // Attribute names can contain non-HTML whitespace characters + // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 + attrNames = value && value.match( rnothtmlwhite ); + + if ( attrNames && elem.nodeType === 1 ) { + while ( ( name = attrNames[ i++ ] ) ) { + elem.removeAttribute( name ); + } + } + } +} ); + +// Hooks for boolean attributes +boolHook = { + set: function( elem, value, name ) { + if ( value === false ) { + + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + elem.setAttribute( name, name ); + } + return name; + } +}; + +jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) { + var getter = attrHandle[ name ] || jQuery.find.attr; + + attrHandle[ name ] = function( elem, name, isXML ) { + var ret, handle, + lowercaseName = name.toLowerCase(); + + if ( !isXML ) { + + // Avoid an infinite loop by temporarily removing this function from the getter + handle = attrHandle[ lowercaseName ]; + attrHandle[ lowercaseName ] = ret; + ret = getter( elem, name, isXML ) != null ? + lowercaseName : + null; + attrHandle[ lowercaseName ] = handle; + } + return ret; + }; +} ); + + + + +var rfocusable = /^(?:input|select|textarea|button)$/i, + rclickable = /^(?:a|area)$/i; + +jQuery.fn.extend( { + prop: function( name, value ) { + return access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + return this.each( function() { + delete this[ jQuery.propFix[ name ] || name ]; + } ); + } +} ); + +jQuery.extend( { + prop: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set properties on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + return ( elem[ name ] = value ); + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + return elem[ name ]; + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + + // Support: IE <=9 - 11 only + // elem.tabIndex doesn't always return the + // correct value when it hasn't been explicitly set + // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + // Use proper attribute retrieval(#12072) + var tabindex = jQuery.find.attr( elem, "tabindex" ); + + if ( tabindex ) { + return parseInt( tabindex, 10 ); + } + + if ( + rfocusable.test( elem.nodeName ) || + rclickable.test( elem.nodeName ) && + elem.href + ) { + return 0; + } + + return -1; + } + } + }, + + propFix: { + "for": "htmlFor", + "class": "className" + } +} ); + +// Support: IE <=11 only +// Accessing the selectedIndex property +// forces the browser to respect setting selected +// on the option +// The getter ensures a default option is selected +// when in an optgroup +// eslint rule "no-unused-expressions" is disabled for this code +// since it considers such accessions noop +if ( !support.optSelected ) { + jQuery.propHooks.selected = { + get: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent && parent.parentNode ) { + parent.parentNode.selectedIndex; + } + return null; + }, + set: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent ) { + parent.selectedIndex; + + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + } + }; +} + +jQuery.each( [ + "tabIndex", + "readOnly", + "maxLength", + "cellSpacing", + "cellPadding", + "rowSpan", + "colSpan", + "useMap", + "frameBorder", + "contentEditable" +], function() { + jQuery.propFix[ this.toLowerCase() ] = this; +} ); + + + + + // Strip and collapse whitespace according to HTML spec + // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace + function stripAndCollapse( value ) { + var tokens = value.match( rnothtmlwhite ) || []; + return tokens.join( " " ); + } + + +function getClass( elem ) { + return elem.getAttribute && elem.getAttribute( "class" ) || ""; +} + +function classesToArray( value ) { + if ( Array.isArray( value ) ) { + return value; + } + if ( typeof value === "string" ) { + return value.match( rnothtmlwhite ) || []; + } + return []; +} + +jQuery.fn.extend( { + addClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + classes = classesToArray( value ); + + if ( classes.length ) { + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + if ( cur.indexOf( " " + clazz + " " ) < 0 ) { + cur += clazz + " "; + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + if ( !arguments.length ) { + return this.attr( "class", "" ); + } + + classes = classesToArray( value ); + + if ( classes.length ) { + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + + // This expression is here for better compressibility (see addClass) + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + + // Remove *all* instances + while ( cur.indexOf( " " + clazz + " " ) > -1 ) { + cur = cur.replace( " " + clazz + " ", " " ); + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isValidValue = type === "string" || Array.isArray( value ); + + if ( typeof stateVal === "boolean" && isValidValue ) { + return stateVal ? this.addClass( value ) : this.removeClass( value ); + } + + if ( isFunction( value ) ) { + return this.each( function( i ) { + jQuery( this ).toggleClass( + value.call( this, i, getClass( this ), stateVal ), + stateVal + ); + } ); + } + + return this.each( function() { + var className, i, self, classNames; + + if ( isValidValue ) { + + // Toggle individual class names + i = 0; + self = jQuery( this ); + classNames = classesToArray( value ); + + while ( ( className = classNames[ i++ ] ) ) { + + // Check each className given, space separated list + if ( self.hasClass( className ) ) { + self.removeClass( className ); + } else { + self.addClass( className ); + } + } + + // Toggle whole class name + } else if ( value === undefined || type === "boolean" ) { + className = getClass( this ); + if ( className ) { + + // Store className if set + dataPriv.set( this, "__className__", className ); + } + + // If the element has a class name or if we're passed `false`, + // then remove the whole classname (if there was one, the above saved it). + // Otherwise bring back whatever was previously saved (if anything), + // falling back to the empty string if nothing was stored. + if ( this.setAttribute ) { + this.setAttribute( "class", + className || value === false ? + "" : + dataPriv.get( this, "__className__" ) || "" + ); + } + } + } ); + }, + + hasClass: function( selector ) { + var className, elem, + i = 0; + + className = " " + selector + " "; + while ( ( elem = this[ i++ ] ) ) { + if ( elem.nodeType === 1 && + ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { + return true; + } + } + + return false; + } +} ); + + + + +var rreturn = /\r/g; + +jQuery.fn.extend( { + val: function( value ) { + var hooks, ret, valueIsFunction, + elem = this[ 0 ]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || + jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && + "get" in hooks && + ( ret = hooks.get( elem, "value" ) ) !== undefined + ) { + return ret; + } + + ret = elem.value; + + // Handle most common string cases + if ( typeof ret === "string" ) { + return ret.replace( rreturn, "" ); + } + + // Handle cases where value is null/undef or number + return ret == null ? "" : ret; + } + + return; + } + + valueIsFunction = isFunction( value ); + + return this.each( function( i ) { + var val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( valueIsFunction ) { + val = value.call( this, i, jQuery( this ).val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + + } else if ( typeof val === "number" ) { + val += ""; + + } else if ( Array.isArray( val ) ) { + val = jQuery.map( val, function( value ) { + return value == null ? "" : value + ""; + } ); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + } ); + } +} ); + +jQuery.extend( { + valHooks: { + option: { + get: function( elem ) { + + var val = jQuery.find.attr( elem, "value" ); + return val != null ? + val : + + // Support: IE <=10 - 11 only + // option.text throws exceptions (#14686, #14858) + // Strip and collapse whitespace + // https://html.spec.whatwg.org/#strip-and-collapse-whitespace + stripAndCollapse( jQuery.text( elem ) ); + } + }, + select: { + get: function( elem ) { + var value, option, i, + options = elem.options, + index = elem.selectedIndex, + one = elem.type === "select-one", + values = one ? null : [], + max = one ? index + 1 : options.length; + + if ( index < 0 ) { + i = max; + + } else { + i = one ? index : 0; + } + + // Loop through all the selected options + for ( ; i < max; i++ ) { + option = options[ i ]; + + // Support: IE <=9 only + // IE8-9 doesn't update selected after form reset (#2551) + if ( ( option.selected || i === index ) && + + // Don't return options that are disabled or in a disabled optgroup + !option.disabled && + ( !option.parentNode.disabled || + !nodeName( option.parentNode, "optgroup" ) ) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + }, + + set: function( elem, value ) { + var optionSet, option, + options = elem.options, + values = jQuery.makeArray( value ), + i = options.length; + + while ( i-- ) { + option = options[ i ]; + + /* eslint-disable no-cond-assign */ + + if ( option.selected = + jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 + ) { + optionSet = true; + } + + /* eslint-enable no-cond-assign */ + } + + // Force browsers to behave consistently when non-matching value is set + if ( !optionSet ) { + elem.selectedIndex = -1; + } + return values; + } + } + } +} ); + +// Radios and checkboxes getter/setter +jQuery.each( [ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + set: function( elem, value ) { + if ( Array.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); + } + } + }; + if ( !support.checkOn ) { + jQuery.valHooks[ this ].get = function( elem ) { + return elem.getAttribute( "value" ) === null ? "on" : elem.value; + }; + } +} ); + + + + +// Return jQuery for attributes-only inclusion + + +support.focusin = "onfocusin" in window; + + +var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + stopPropagationCallback = function( e ) { + e.stopPropagation(); + }; + +jQuery.extend( jQuery.event, { + + trigger: function( event, data, elem, onlyHandlers ) { + + var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, + eventPath = [ elem || document ], + type = hasOwn.call( event, "type" ) ? event.type : event, + namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; + + cur = lastElement = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "." ) > -1 ) { + + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split( "." ); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf( ":" ) < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join( "." ); + event.rnamespace = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === ( elem.ownerDocument || document ) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { + lastElement = cur; + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] && + dataPriv.get( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && handle.apply && acceptData( cur ) ) { + event.result = handle.apply( cur, data ); + if ( event.result === false ) { + event.preventDefault(); + } + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( ( !special._default || + special._default.apply( eventPath.pop(), data ) === false ) && + acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name as the event. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + + if ( event.isPropagationStopped() ) { + lastElement.addEventListener( type, stopPropagationCallback ); + } + + elem[ type ](); + + if ( event.isPropagationStopped() ) { + lastElement.removeEventListener( type, stopPropagationCallback ); + } + + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + // Piggyback on a donor event to simulate a different one + // Used only for `focus(in | out)` events + simulate: function( type, elem, event ) { + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true + } + ); + + jQuery.event.trigger( e, null, elem ); + } + +} ); + +jQuery.fn.extend( { + + trigger: function( type, data ) { + return this.each( function() { + jQuery.event.trigger( type, data, this ); + } ); + }, + triggerHandler: function( type, data ) { + var elem = this[ 0 ]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +} ); + + +// Support: Firefox <=44 +// Firefox doesn't have focus(in | out) events +// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 +// +// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 +// focus(in | out) events fire after focus & blur events, +// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order +// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 +if ( !support.focusin ) { + jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler on the document while someone wants focusin/focusout + var handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + var doc = this.ownerDocument || this, + attaches = dataPriv.access( doc, fix ); + + if ( !attaches ) { + doc.addEventListener( orig, handler, true ); + } + dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); + }, + teardown: function() { + var doc = this.ownerDocument || this, + attaches = dataPriv.access( doc, fix ) - 1; + + if ( !attaches ) { + doc.removeEventListener( orig, handler, true ); + dataPriv.remove( doc, fix ); + + } else { + dataPriv.access( doc, fix, attaches ); + } + } + }; + } ); +} +var location = window.location; + +var nonce = Date.now(); + +var rquery = ( /\?/ ); + + + +// Cross-browser xml parsing +jQuery.parseXML = function( data ) { + var xml; + if ( !data || typeof data !== "string" ) { + return null; + } + + // Support: IE 9 - 11 only + // IE throws on parseFromString with invalid input. + try { + xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); + } catch ( e ) { + xml = undefined; + } + + if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; +}; + + +var + rbracket = /\[\]$/, + rCRLF = /\r?\n/g, + rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, + rsubmittable = /^(?:input|select|textarea|keygen)/i; + +function buildParams( prefix, obj, traditional, add ) { + var name; + + if ( Array.isArray( obj ) ) { + + // Serialize array item. + jQuery.each( obj, function( i, v ) { + if ( traditional || rbracket.test( prefix ) ) { + + // Treat each array item as a scalar. + add( prefix, v ); + + } else { + + // Item is non-scalar (array or object), encode its numeric index. + buildParams( + prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", + v, + traditional, + add + ); + } + } ); + + } else if ( !traditional && toType( obj ) === "object" ) { + + // Serialize object item. + for ( name in obj ) { + buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); + } + + } else { + + // Serialize scalar item. + add( prefix, obj ); + } +} + +// Serialize an array of form elements or a set of +// key/values into a query string +jQuery.param = function( a, traditional ) { + var prefix, + s = [], + add = function( key, valueOrFunction ) { + + // If value is a function, invoke it and use its return value + var value = isFunction( valueOrFunction ) ? + valueOrFunction() : + valueOrFunction; + + s[ s.length ] = encodeURIComponent( key ) + "=" + + encodeURIComponent( value == null ? "" : value ); + }; + + // If an array was passed in, assume that it is an array of form elements. + if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { + + // Serialize the form elements + jQuery.each( a, function() { + add( this.name, this.value ); + } ); + + } else { + + // If traditional, encode the "old" way (the way 1.3.2 or older + // did it), otherwise encode params recursively. + for ( prefix in a ) { + buildParams( prefix, a[ prefix ], traditional, add ); + } + } + + // Return the resulting serialization + return s.join( "&" ); +}; + +jQuery.fn.extend( { + serialize: function() { + return jQuery.param( this.serializeArray() ); + }, + serializeArray: function() { + return this.map( function() { + + // Can add propHook for "elements" to filter or add form elements + var elements = jQuery.prop( this, "elements" ); + return elements ? jQuery.makeArray( elements ) : this; + } ) + .filter( function() { + var type = this.type; + + // Use .is( ":disabled" ) so that fieldset[disabled] works + return this.name && !jQuery( this ).is( ":disabled" ) && + rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && + ( this.checked || !rcheckableType.test( type ) ); + } ) + .map( function( i, elem ) { + var val = jQuery( this ).val(); + + if ( val == null ) { + return null; + } + + if ( Array.isArray( val ) ) { + return jQuery.map( val, function( val ) { + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ); + } + + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ).get(); + } +} ); + + +var + r20 = /%20/g, + rhash = /#.*$/, + rantiCache = /([?&])_=[^&]*/, + rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, + + // #7653, #8125, #8152: local protocol detection + rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, + rnoContent = /^(?:GET|HEAD)$/, + rprotocol = /^\/\//, + + /* Prefilters + * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) + * 2) These are called: + * - BEFORE asking for a transport + * - AFTER param serialization (s.data is a string if s.processData is true) + * 3) key is the dataType + * 4) the catchall symbol "*" can be used + * 5) execution will start with transport dataType and THEN continue down to "*" if needed + */ + prefilters = {}, + + /* Transports bindings + * 1) key is the dataType + * 2) the catchall symbol "*" can be used + * 3) selection will start with transport dataType and THEN go to "*" if needed + */ + transports = {}, + + // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression + allTypes = "*/".concat( "*" ), + + // Anchor tag for parsing the document origin + originAnchor = document.createElement( "a" ); + originAnchor.href = location.href; + +// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport +function addToPrefiltersOrTransports( structure ) { + + // dataTypeExpression is optional and defaults to "*" + return function( dataTypeExpression, func ) { + + if ( typeof dataTypeExpression !== "string" ) { + func = dataTypeExpression; + dataTypeExpression = "*"; + } + + var dataType, + i = 0, + dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; + + if ( isFunction( func ) ) { + + // For each dataType in the dataTypeExpression + while ( ( dataType = dataTypes[ i++ ] ) ) { + + // Prepend if requested + if ( dataType[ 0 ] === "+" ) { + dataType = dataType.slice( 1 ) || "*"; + ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); + + // Otherwise append + } else { + ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); + } + } + } + }; +} + +// Base inspection function for prefilters and transports +function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { + + var inspected = {}, + seekingTransport = ( structure === transports ); + + function inspect( dataType ) { + var selected; + inspected[ dataType ] = true; + jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { + var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); + if ( typeof dataTypeOrTransport === "string" && + !seekingTransport && !inspected[ dataTypeOrTransport ] ) { + + options.dataTypes.unshift( dataTypeOrTransport ); + inspect( dataTypeOrTransport ); + return false; + } else if ( seekingTransport ) { + return !( selected = dataTypeOrTransport ); + } + } ); + return selected; + } + + return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); +} + +// A special extend for ajax options +// that takes "flat" options (not to be deep extended) +// Fixes #9887 +function ajaxExtend( target, src ) { + var key, deep, + flatOptions = jQuery.ajaxSettings.flatOptions || {}; + + for ( key in src ) { + if ( src[ key ] !== undefined ) { + ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; + } + } + if ( deep ) { + jQuery.extend( true, target, deep ); + } + + return target; +} + +/* Handles responses to an ajax request: + * - finds the right dataType (mediates between content-type and expected dataType) + * - returns the corresponding response + */ +function ajaxHandleResponses( s, jqXHR, responses ) { + + var ct, type, finalDataType, firstDataType, + contents = s.contents, + dataTypes = s.dataTypes; + + // Remove auto dataType and get content-type in the process + while ( dataTypes[ 0 ] === "*" ) { + dataTypes.shift(); + if ( ct === undefined ) { + ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); + } + } + + // Check if we're dealing with a known content-type + if ( ct ) { + for ( type in contents ) { + if ( contents[ type ] && contents[ type ].test( ct ) ) { + dataTypes.unshift( type ); + break; + } + } + } + + // Check to see if we have a response for the expected dataType + if ( dataTypes[ 0 ] in responses ) { + finalDataType = dataTypes[ 0 ]; + } else { + + // Try convertible dataTypes + for ( type in responses ) { + if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { + finalDataType = type; + break; + } + if ( !firstDataType ) { + firstDataType = type; + } + } + + // Or just use first one + finalDataType = finalDataType || firstDataType; + } + + // If we found a dataType + // We add the dataType to the list if needed + // and return the corresponding response + if ( finalDataType ) { + if ( finalDataType !== dataTypes[ 0 ] ) { + dataTypes.unshift( finalDataType ); + } + return responses[ finalDataType ]; + } +} + +/* Chain conversions given the request and the original response + * Also sets the responseXXX fields on the jqXHR instance + */ +function ajaxConvert( s, response, jqXHR, isSuccess ) { + var conv2, current, conv, tmp, prev, + converters = {}, + + // Work with a copy of dataTypes in case we need to modify it for conversion + dataTypes = s.dataTypes.slice(); + + // Create converters map with lowercased keys + if ( dataTypes[ 1 ] ) { + for ( conv in s.converters ) { + converters[ conv.toLowerCase() ] = s.converters[ conv ]; + } + } + + current = dataTypes.shift(); + + // Convert to each sequential dataType + while ( current ) { + + if ( s.responseFields[ current ] ) { + jqXHR[ s.responseFields[ current ] ] = response; + } + + // Apply the dataFilter if provided + if ( !prev && isSuccess && s.dataFilter ) { + response = s.dataFilter( response, s.dataType ); + } + + prev = current; + current = dataTypes.shift(); + + if ( current ) { + + // There's only work to do if current dataType is non-auto + if ( current === "*" ) { + + current = prev; + + // Convert response if prev dataType is non-auto and differs from current + } else if ( prev !== "*" && prev !== current ) { + + // Seek a direct converter + conv = converters[ prev + " " + current ] || converters[ "* " + current ]; + + // If none found, seek a pair + if ( !conv ) { + for ( conv2 in converters ) { + + // If conv2 outputs current + tmp = conv2.split( " " ); + if ( tmp[ 1 ] === current ) { + + // If prev can be converted to accepted input + conv = converters[ prev + " " + tmp[ 0 ] ] || + converters[ "* " + tmp[ 0 ] ]; + if ( conv ) { + + // Condense equivalence converters + if ( conv === true ) { + conv = converters[ conv2 ]; + + // Otherwise, insert the intermediate dataType + } else if ( converters[ conv2 ] !== true ) { + current = tmp[ 0 ]; + dataTypes.unshift( tmp[ 1 ] ); + } + break; + } + } + } + } + + // Apply converter (if not an equivalence) + if ( conv !== true ) { + + // Unless errors are allowed to bubble, catch and return them + if ( conv && s.throws ) { + response = conv( response ); + } else { + try { + response = conv( response ); + } catch ( e ) { + return { + state: "parsererror", + error: conv ? e : "No conversion from " + prev + " to " + current + }; + } + } + } + } + } + } + + return { state: "success", data: response }; +} + +jQuery.extend( { + + // Counter for holding the number of active queries + active: 0, + + // Last-Modified header cache for next request + lastModified: {}, + etag: {}, + + ajaxSettings: { + url: location.href, + type: "GET", + isLocal: rlocalProtocol.test( location.protocol ), + global: true, + processData: true, + async: true, + contentType: "application/x-www-form-urlencoded; charset=UTF-8", + + /* + timeout: 0, + data: null, + dataType: null, + username: null, + password: null, + cache: null, + throws: false, + traditional: false, + headers: {}, + */ + + accepts: { + "*": allTypes, + text: "text/plain", + html: "text/html", + xml: "application/xml, text/xml", + json: "application/json, text/javascript" + }, + + contents: { + xml: /\bxml\b/, + html: /\bhtml/, + json: /\bjson\b/ + }, + + responseFields: { + xml: "responseXML", + text: "responseText", + json: "responseJSON" + }, + + // Data converters + // Keys separate source (or catchall "*") and destination types with a single space + converters: { + + // Convert anything to text + "* text": String, + + // Text to html (true = no transformation) + "text html": true, + + // Evaluate text as a json expression + "text json": JSON.parse, + + // Parse text as xml + "text xml": jQuery.parseXML + }, + + // For options that shouldn't be deep extended: + // you can add your own custom options here if + // and when you create one that shouldn't be + // deep extended (see ajaxExtend) + flatOptions: { + url: true, + context: true + } + }, + + // Creates a full fledged settings object into target + // with both ajaxSettings and settings fields. + // If target is omitted, writes into ajaxSettings. + ajaxSetup: function( target, settings ) { + return settings ? + + // Building a settings object + ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : + + // Extending ajaxSettings + ajaxExtend( jQuery.ajaxSettings, target ); + }, + + ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), + ajaxTransport: addToPrefiltersOrTransports( transports ), + + // Main method + ajax: function( url, options ) { + + // If url is an object, simulate pre-1.5 signature + if ( typeof url === "object" ) { + options = url; + url = undefined; + } + + // Force options to be an object + options = options || {}; + + var transport, + + // URL without anti-cache param + cacheURL, + + // Response headers + responseHeadersString, + responseHeaders, + + // timeout handle + timeoutTimer, + + // Url cleanup var + urlAnchor, + + // Request state (becomes false upon send and true upon completion) + completed, + + // To know if global events are to be dispatched + fireGlobals, + + // Loop variable + i, + + // uncached part of the url + uncached, + + // Create the final options object + s = jQuery.ajaxSetup( {}, options ), + + // Callbacks context + callbackContext = s.context || s, + + // Context for global events is callbackContext if it is a DOM node or jQuery collection + globalEventContext = s.context && + ( callbackContext.nodeType || callbackContext.jquery ) ? + jQuery( callbackContext ) : + jQuery.event, + + // Deferreds + deferred = jQuery.Deferred(), + completeDeferred = jQuery.Callbacks( "once memory" ), + + // Status-dependent callbacks + statusCode = s.statusCode || {}, + + // Headers (they are sent all at once) + requestHeaders = {}, + requestHeadersNames = {}, + + // Default abort message + strAbort = "canceled", + + // Fake xhr + jqXHR = { + readyState: 0, + + // Builds headers hashtable if needed + getResponseHeader: function( key ) { + var match; + if ( completed ) { + if ( !responseHeaders ) { + responseHeaders = {}; + while ( ( match = rheaders.exec( responseHeadersString ) ) ) { + responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ]; + } + } + match = responseHeaders[ key.toLowerCase() ]; + } + return match == null ? null : match; + }, + + // Raw string + getAllResponseHeaders: function() { + return completed ? responseHeadersString : null; + }, + + // Caches the header + setRequestHeader: function( name, value ) { + if ( completed == null ) { + name = requestHeadersNames[ name.toLowerCase() ] = + requestHeadersNames[ name.toLowerCase() ] || name; + requestHeaders[ name ] = value; + } + return this; + }, + + // Overrides response content-type header + overrideMimeType: function( type ) { + if ( completed == null ) { + s.mimeType = type; + } + return this; + }, + + // Status-dependent callbacks + statusCode: function( map ) { + var code; + if ( map ) { + if ( completed ) { + + // Execute the appropriate callbacks + jqXHR.always( map[ jqXHR.status ] ); + } else { + + // Lazy-add the new callbacks in a way that preserves old ones + for ( code in map ) { + statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; + } + } + } + return this; + }, + + // Cancel the request + abort: function( statusText ) { + var finalText = statusText || strAbort; + if ( transport ) { + transport.abort( finalText ); + } + done( 0, finalText ); + return this; + } + }; + + // Attach deferreds + deferred.promise( jqXHR ); + + // Add protocol if not provided (prefilters might expect it) + // Handle falsy url in the settings object (#10093: consistency with old signature) + // We also use the url parameter if available + s.url = ( ( url || s.url || location.href ) + "" ) + .replace( rprotocol, location.protocol + "//" ); + + // Alias method option to type as per ticket #12004 + s.type = options.method || options.type || s.method || s.type; + + // Extract dataTypes list + s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; + + // A cross-domain request is in order when the origin doesn't match the current origin. + if ( s.crossDomain == null ) { + urlAnchor = document.createElement( "a" ); + + // Support: IE <=8 - 11, Edge 12 - 15 + // IE throws exception on accessing the href property if url is malformed, + // e.g. http://example.com:80x/ + try { + urlAnchor.href = s.url; + + // Support: IE <=8 - 11 only + // Anchor's host property isn't correctly set when s.url is relative + urlAnchor.href = urlAnchor.href; + s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== + urlAnchor.protocol + "//" + urlAnchor.host; + } catch ( e ) { + + // If there is an error parsing the URL, assume it is crossDomain, + // it can be rejected by the transport if it is invalid + s.crossDomain = true; + } + } + + // Convert data if not already a string + if ( s.data && s.processData && typeof s.data !== "string" ) { + s.data = jQuery.param( s.data, s.traditional ); + } + + // Apply prefilters + inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); + + // If request was aborted inside a prefilter, stop there + if ( completed ) { + return jqXHR; + } + + // We can fire global events as of now if asked to + // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) + fireGlobals = jQuery.event && s.global; + + // Watch for a new set of requests + if ( fireGlobals && jQuery.active++ === 0 ) { + jQuery.event.trigger( "ajaxStart" ); + } + + // Uppercase the type + s.type = s.type.toUpperCase(); + + // Determine if request has content + s.hasContent = !rnoContent.test( s.type ); + + // Save the URL in case we're toying with the If-Modified-Since + // and/or If-None-Match header later on + // Remove hash to simplify url manipulation + cacheURL = s.url.replace( rhash, "" ); + + // More options handling for requests with no content + if ( !s.hasContent ) { + + // Remember the hash so we can put it back + uncached = s.url.slice( cacheURL.length ); + + // If data is available and should be processed, append data to url + if ( s.data && ( s.processData || typeof s.data === "string" ) ) { + cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; + + // #9682: remove data so that it's not used in an eventual retry + delete s.data; + } + + // Add or update anti-cache param if needed + if ( s.cache === false ) { + cacheURL = cacheURL.replace( rantiCache, "$1" ); + uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce++ ) + uncached; + } + + // Put hash and anti-cache on the URL that will be requested (gh-1732) + s.url = cacheURL + uncached; + + // Change '%20' to '+' if this is encoded form body content (gh-2658) + } else if ( s.data && s.processData && + ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { + s.data = s.data.replace( r20, "+" ); + } + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + if ( jQuery.lastModified[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); + } + if ( jQuery.etag[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); + } + } + + // Set the correct header, if data is being sent + if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { + jqXHR.setRequestHeader( "Content-Type", s.contentType ); + } + + // Set the Accepts header for the server, depending on the dataType + jqXHR.setRequestHeader( + "Accept", + s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? + s.accepts[ s.dataTypes[ 0 ] ] + + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : + s.accepts[ "*" ] + ); + + // Check for headers option + for ( i in s.headers ) { + jqXHR.setRequestHeader( i, s.headers[ i ] ); + } + + // Allow custom headers/mimetypes and early abort + if ( s.beforeSend && + ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { + + // Abort if not done already and return + return jqXHR.abort(); + } + + // Aborting is no longer a cancellation + strAbort = "abort"; + + // Install callbacks on deferreds + completeDeferred.add( s.complete ); + jqXHR.done( s.success ); + jqXHR.fail( s.error ); + + // Get transport + transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); + + // If no transport, we auto-abort + if ( !transport ) { + done( -1, "No Transport" ); + } else { + jqXHR.readyState = 1; + + // Send global event + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); + } + + // If request was aborted inside ajaxSend, stop there + if ( completed ) { + return jqXHR; + } + + // Timeout + if ( s.async && s.timeout > 0 ) { + timeoutTimer = window.setTimeout( function() { + jqXHR.abort( "timeout" ); + }, s.timeout ); + } + + try { + completed = false; + transport.send( requestHeaders, done ); + } catch ( e ) { + + // Rethrow post-completion exceptions + if ( completed ) { + throw e; + } + + // Propagate others as results + done( -1, e ); + } + } + + // Callback for when everything is done + function done( status, nativeStatusText, responses, headers ) { + var isSuccess, success, error, response, modified, + statusText = nativeStatusText; + + // Ignore repeat invocations + if ( completed ) { + return; + } + + completed = true; + + // Clear timeout if it exists + if ( timeoutTimer ) { + window.clearTimeout( timeoutTimer ); + } + + // Dereference transport for early garbage collection + // (no matter how long the jqXHR object will be used) + transport = undefined; + + // Cache response headers + responseHeadersString = headers || ""; + + // Set readyState + jqXHR.readyState = status > 0 ? 4 : 0; + + // Determine if successful + isSuccess = status >= 200 && status < 300 || status === 304; + + // Get response data + if ( responses ) { + response = ajaxHandleResponses( s, jqXHR, responses ); + } + + // Convert no matter what (that way responseXXX fields are always set) + response = ajaxConvert( s, response, jqXHR, isSuccess ); + + // If successful, handle type chaining + if ( isSuccess ) { + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + modified = jqXHR.getResponseHeader( "Last-Modified" ); + if ( modified ) { + jQuery.lastModified[ cacheURL ] = modified; + } + modified = jqXHR.getResponseHeader( "etag" ); + if ( modified ) { + jQuery.etag[ cacheURL ] = modified; + } + } + + // if no content + if ( status === 204 || s.type === "HEAD" ) { + statusText = "nocontent"; + + // if not modified + } else if ( status === 304 ) { + statusText = "notmodified"; + + // If we have data, let's convert it + } else { + statusText = response.state; + success = response.data; + error = response.error; + isSuccess = !error; + } + } else { + + // Extract error from statusText and normalize for non-aborts + error = statusText; + if ( status || !statusText ) { + statusText = "error"; + if ( status < 0 ) { + status = 0; + } + } + } + + // Set data for the fake xhr object + jqXHR.status = status; + jqXHR.statusText = ( nativeStatusText || statusText ) + ""; + + // Success/Error + if ( isSuccess ) { + deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); + } else { + deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); + } + + // Status-dependent callbacks + jqXHR.statusCode( statusCode ); + statusCode = undefined; + + if ( fireGlobals ) { + globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", + [ jqXHR, s, isSuccess ? success : error ] ); + } + + // Complete + completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); + + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); + + // Handle the global AJAX counter + if ( !( --jQuery.active ) ) { + jQuery.event.trigger( "ajaxStop" ); + } + } + } + + return jqXHR; + }, + + getJSON: function( url, data, callback ) { + return jQuery.get( url, data, callback, "json" ); + }, + + getScript: function( url, callback ) { + return jQuery.get( url, undefined, callback, "script" ); + } +} ); + +jQuery.each( [ "get", "post" ], function( i, method ) { + jQuery[ method ] = function( url, data, callback, type ) { + + // Shift arguments if data argument was omitted + if ( isFunction( data ) ) { + type = type || callback; + callback = data; + data = undefined; + } + + // The url can be an options object (which then must have .url) + return jQuery.ajax( jQuery.extend( { + url: url, + type: method, + dataType: type, + data: data, + success: callback + }, jQuery.isPlainObject( url ) && url ) ); + }; +} ); + + +jQuery._evalUrl = function( url ) { + return jQuery.ajax( { + url: url, + + // Make this explicit, since user can override this through ajaxSetup (#11264) + type: "GET", + dataType: "script", + cache: true, + async: false, + global: false, + "throws": true + } ); +}; + + +jQuery.fn.extend( { + wrapAll: function( html ) { + var wrap; + + if ( this[ 0 ] ) { + if ( isFunction( html ) ) { + html = html.call( this[ 0 ] ); + } + + // The elements to wrap the target around + wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); + + if ( this[ 0 ].parentNode ) { + wrap.insertBefore( this[ 0 ] ); + } + + wrap.map( function() { + var elem = this; + + while ( elem.firstElementChild ) { + elem = elem.firstElementChild; + } + + return elem; + } ).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( isFunction( html ) ) { + return this.each( function( i ) { + jQuery( this ).wrapInner( html.call( this, i ) ); + } ); + } + + return this.each( function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + } ); + }, + + wrap: function( html ) { + var htmlIsFunction = isFunction( html ); + + return this.each( function( i ) { + jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); + } ); + }, + + unwrap: function( selector ) { + this.parent( selector ).not( "body" ).each( function() { + jQuery( this ).replaceWith( this.childNodes ); + } ); + return this; + } +} ); + + +jQuery.expr.pseudos.hidden = function( elem ) { + return !jQuery.expr.pseudos.visible( elem ); +}; +jQuery.expr.pseudos.visible = function( elem ) { + return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); +}; + + + + +jQuery.ajaxSettings.xhr = function() { + try { + return new window.XMLHttpRequest(); + } catch ( e ) {} +}; + +var xhrSuccessStatus = { + + // File protocol always yields status code 0, assume 200 + 0: 200, + + // Support: IE <=9 only + // #1450: sometimes IE returns 1223 when it should be 204 + 1223: 204 + }, + xhrSupported = jQuery.ajaxSettings.xhr(); + +support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); +support.ajax = xhrSupported = !!xhrSupported; + +jQuery.ajaxTransport( function( options ) { + var callback, errorCallback; + + // Cross domain only allowed if supported through XMLHttpRequest + if ( support.cors || xhrSupported && !options.crossDomain ) { + return { + send: function( headers, complete ) { + var i, + xhr = options.xhr(); + + xhr.open( + options.type, + options.url, + options.async, + options.username, + options.password + ); + + // Apply custom fields if provided + if ( options.xhrFields ) { + for ( i in options.xhrFields ) { + xhr[ i ] = options.xhrFields[ i ]; + } + } + + // Override mime type if needed + if ( options.mimeType && xhr.overrideMimeType ) { + xhr.overrideMimeType( options.mimeType ); + } + + // X-Requested-With header + // For cross-domain requests, seeing as conditions for a preflight are + // akin to a jigsaw puzzle, we simply never set it to be sure. + // (it can always be set on a per-request basis or even using ajaxSetup) + // For same-domain requests, won't change header if already provided. + if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { + headers[ "X-Requested-With" ] = "XMLHttpRequest"; + } + + // Set headers + for ( i in headers ) { + xhr.setRequestHeader( i, headers[ i ] ); + } + + // Callback + callback = function( type ) { + return function() { + if ( callback ) { + callback = errorCallback = xhr.onload = + xhr.onerror = xhr.onabort = xhr.ontimeout = + xhr.onreadystatechange = null; + + if ( type === "abort" ) { + xhr.abort(); + } else if ( type === "error" ) { + + // Support: IE <=9 only + // On a manual native abort, IE9 throws + // errors on any property access that is not readyState + if ( typeof xhr.status !== "number" ) { + complete( 0, "error" ); + } else { + complete( + + // File: protocol always yields status 0; see #8605, #14207 + xhr.status, + xhr.statusText + ); + } + } else { + complete( + xhrSuccessStatus[ xhr.status ] || xhr.status, + xhr.statusText, + + // Support: IE <=9 only + // IE9 has no XHR2 but throws on binary (trac-11426) + // For XHR2 non-text, let the caller handle it (gh-2498) + ( xhr.responseType || "text" ) !== "text" || + typeof xhr.responseText !== "string" ? + { binary: xhr.response } : + { text: xhr.responseText }, + xhr.getAllResponseHeaders() + ); + } + } + }; + }; + + // Listen to events + xhr.onload = callback(); + errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); + + // Support: IE 9 only + // Use onreadystatechange to replace onabort + // to handle uncaught aborts + if ( xhr.onabort !== undefined ) { + xhr.onabort = errorCallback; + } else { + xhr.onreadystatechange = function() { + + // Check readyState before timeout as it changes + if ( xhr.readyState === 4 ) { + + // Allow onerror to be called first, + // but that will not handle a native abort + // Also, save errorCallback to a variable + // as xhr.onerror cannot be accessed + window.setTimeout( function() { + if ( callback ) { + errorCallback(); + } + } ); + } + }; + } + + // Create the abort callback + callback = callback( "abort" ); + + try { + + // Do send the request (this may raise an exception) + xhr.send( options.hasContent && options.data || null ); + } catch ( e ) { + + // #14683: Only rethrow if this hasn't been notified as an error yet + if ( callback ) { + throw e; + } + } + }, + + abort: function() { + if ( callback ) { + callback(); + } + } + }; + } +} ); + + + + +// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) +jQuery.ajaxPrefilter( function( s ) { + if ( s.crossDomain ) { + s.contents.script = false; + } +} ); + +// Install script dataType +jQuery.ajaxSetup( { + accepts: { + script: "text/javascript, application/javascript, " + + "application/ecmascript, application/x-ecmascript" + }, + contents: { + script: /\b(?:java|ecma)script\b/ + }, + converters: { + "text script": function( text ) { + jQuery.globalEval( text ); + return text; + } + } +} ); + +// Handle cache's special case and crossDomain +jQuery.ajaxPrefilter( "script", function( s ) { + if ( s.cache === undefined ) { + s.cache = false; + } + if ( s.crossDomain ) { + s.type = "GET"; + } +} ); + +// Bind script tag hack transport +jQuery.ajaxTransport( "script", function( s ) { + + // This transport only deals with cross domain requests + if ( s.crossDomain ) { + var script, callback; + return { + send: function( _, complete ) { + script = jQuery( " + + + + + + +
+ +
+ + + + \ No newline at end of file diff --git a/html/nttc/dist/tab_filtering.html b/html/nttc/dist/tab_filtering.html new file mode 100644 index 00000000000..ee9797c51a9 --- /dev/null +++ b/html/nttc/dist/tab_filtering.html @@ -0,0 +1,17 @@ +
+

Filtering Settings

+ + + + + + + + + + + + + +
Announce Jobs?
Announce Timecodes?
Language Conversion?
+
diff --git a/html/nttc/dist/tab_firewall.html b/html/nttc/dist/tab_firewall.html new file mode 100644 index 00000000000..db8ee8a0f73 --- /dev/null +++ b/html/nttc/dist/tab_firewall.html @@ -0,0 +1,4 @@ +
+

FIREWALL

+ +
\ No newline at end of file diff --git a/html/nttc/dist/tab_hack.html b/html/nttc/dist/tab_hack.html new file mode 100644 index 00000000000..189ac836954 --- /dev/null +++ b/html/nttc/dist/tab_hack.html @@ -0,0 +1,22 @@ +
+

1337 HAaCCkEr MeNU!

+ + + + + + + + + +
H*lp Tr%%ait0r i* $c/e#ce
HoNKKk!!11!
+
+ \ No newline at end of file diff --git a/html/nttc/dist/tab_home.html b/html/nttc/dist/tab_home.html new file mode 100644 index 00000000000..eb98b18a4db --- /dev/null +++ b/html/nttc/dist/tab_home.html @@ -0,0 +1,9 @@ +
+

Home

+ + + + + +
Telecomms Activated?
+
diff --git a/html/nttc/dist/tab_regex.html b/html/nttc/dist/tab_regex.html new file mode 100644 index 00000000000..3e3d0d90229 --- /dev/null +++ b/html/nttc/dist/tab_regex.html @@ -0,0 +1,4 @@ +
+

Regex

+ +
\ No newline at end of file diff --git a/html/nttc/dist/uiTitleFluff.png b/html/nttc/dist/uiTitleFluff.png new file mode 100644 index 00000000000..513ba0c4965 Binary files /dev/null and b/html/nttc/dist/uiTitleFluff.png differ diff --git a/html/nttc/gulpfile.js b/html/nttc/gulpfile.js new file mode 100644 index 00000000000..710ebdf3e43 --- /dev/null +++ b/html/nttc/gulpfile.js @@ -0,0 +1,106 @@ +/* Dependencies */ + +// Regular node dependencies +var child_process = require("child_process"); +var fs = require("fs"); +var path = require("path"); + +// Main compilers +var browserify = require("browserify"); +var gulp = require("gulp"); + +// Extras +var del = require("del"); +var concat = require("gulp-concat"); +var flatten = require("gulp-flatten"); +var rename = require("gulp-rename"); +var buffer = require("vinyl-buffer"); +var source = require("vinyl-source-stream"); + +/* Configuration */ +const watch_targets = [ + "./src/index.js", + "./src/css/*", + "./src/js/*", + "./src/html/**/*" +] + +const output = { + "css": "bundle.css", + "dest": "./dist/", + "js": "bundle.js" +}; + +/* Clean out the dist directory to get rid of any old build artifacts. */ +gulp.task("clean", function () { + del(output.dest + "*"); +}); + +/* This uses browserify to compress every single require() into a single javascript file. */ +gulp.task("browserify", ["clean"], function () { + var bundleStream = browserify("./src/index.js").bundle(); + + bundleStream + .pipe(source("index.js")) + .pipe(rename("bundle.js")) + .pipe(buffer()) + .pipe(gulp.dest(output.dest)) +}); + + +/* CSS concatenation and output. */ +gulp.task("css", ["clean"], function () { + gulp.src("./src/css/*.css") + .pipe(concat(output.css)) + .pipe(buffer()) + .pipe(gulp.dest(output.dest)) +}); + +/* Basically just copy-paste the html files into the dest, but flatten the directory structure. */ +gulp.task("etc", ["clean"], function () { + gulp.src("./src/html/**/*.html") + .pipe(flatten()) + .pipe(buffer()) + .pipe(gulp.dest(output.dest)); + gulp.src("./src/img/*") + .pipe(buffer()) + .pipe(gulp.dest(output.dest)); +}); + +// This runs all of the other defined tasks on "gulp" +gulp.task("default", ["css", "etc", "browserify"]) + +// Autoreload +gulp.task("reload", ["default"], function() { + child_process.exec("reload.bat", function (err, stdout) { + if (err) + throw err; + + var byond_cache = path.join(stdout.trim(), "BYOND", "cache"); + var files = fs.readdirSync(byond_cache); + for (let file of files) { + let filepath = path.join(byond_cache, file); + let stats = fs.statSync(filepath) + if (file.startsWith("tmp") && stats.isDirectory()) { + var tmpFiles = fs.readdirSync(filepath); + if (tmpFiles.includes("bundle.js")) { + setTimeout(function () {transfer_files(filepath)}, 500); + } + } + } + }); +}); + +function transfer_files(target) { + console.log("transfer_files") + let filesToTransfer = fs.readdirSync(path.join(".", "dist")); + for (let file of filesToTransfer) { + console.log(file, path.join(target, file)) + let filepath = path.join(".", "dist", file); + fs.createReadStream(filepath).pipe(fs.createWriteStream(path.join(target, file))) + } +} + +gulp.task("watch", function () { + gulp.watch(watch_targets, ["reload"]); +}); \ No newline at end of file diff --git a/html/nttc/package.json b/html/nttc/package.json new file mode 100644 index 00000000000..c1d547905c7 --- /dev/null +++ b/html/nttc/package.json @@ -0,0 +1,25 @@ +{ + "name": "nttc", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "Tigercat2000", + "license": "AGPL-3.0-only", + "dependencies": { + "del": "^3.0.0", + "gulp-flatten": "^0.4.0", + "he": "^1.2.0", + "jquery": "^3.3.1" + }, + "devDependencies": { + "browserify": "^16.2.3", + "gulp": "^3.9.1", + "gulp-concat": "^2.6.1", + "gulp-rename": "^1.4.0", + "vinyl-buffer": "^1.0.1", + "vinyl-source-stream": "^2.0.0" + } +} diff --git a/html/nttc/reload.bat b/html/nttc/reload.bat new file mode 100644 index 00000000000..39ad27c8815 --- /dev/null +++ b/html/nttc/reload.bat @@ -0,0 +1,9 @@ +@echo off + +for /f "tokens=3* delims= " %%a in ( + 'reg query "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" /v "Personal"' +) do ( + set documents=%%a +) + +echo %documents% \ No newline at end of file diff --git a/html/nttc/src/css/index.css b/html/nttc/src/css/index.css new file mode 100644 index 00000000000..293fb16a941 --- /dev/null +++ b/html/nttc/src/css/index.css @@ -0,0 +1,154 @@ +/* Global */ +html, body { + background-color: #272727; + font-family: Verdana, Geneva, sans-serif; + font-size: 12px; + color: #fff; + margin: 0; + padding: 0; +} + +/* Navbar */ +#navbar { + background: #383838; + border-bottom: 2px solid #161616; + list-style-type: none; + height: 28px; + margin: 0; + padding: 0; +} + +#navbar > div { + background: #40628a; + border-radius: 5px 5px 0 0; + color: #ffffff; + display: block; + height: 80%; + float: left; + text-decoration: none; + padding: 0 7px 0 5px; + margin: 6px 0 0 5px; +} + +#navbar > div:hover { + background: #ffffff; + color: #40628a; + cursor: pointer; +} + +#navbar > img { + float: left; + margin: 2px 10px 2px 0; + height: 24px; +} + +#navbar > .title { + color: #a7a7a7; + float: right; + background: none; + font-size: 1.5em; + font-family: Helvetica; + text-decoration: bold; + padding: 0; + padding-right: 10px; + margin: 0; +} + +#navbar > .title:hover { + background: none; + color: #a7a7a7; + cursor: default; +} + +.btnActive { + background: #2f943c !important; + color: #fff !important; +} + +/* Content */ +#content { + min-height: 75%; + line-height: 1.5; + margin: 10px; +} + +/* Links */ +.link, .linkOn, .linkOff { + background: #40628a; + border: 1px solid #161616; + color: #ffffff; + cursor: pointer; + display: inline; + margin: 0 2px 0px 0; + min-width: 15px; + padding: 0px 4px 0px 4px; + text-align: center; + text-decoration: none; + user-select: none; + white-space: nowrap; +} + +.linkOn, .linkOn:link, .linkOn:visited, .linkOn:active, .linkOn:hover +{ + color: #ffffff; + background: #2f943c; + border-color: #24722e; +} + +.linkOff, .linkOff:link, .linkOff:visited, .linkOff:active, .linkOff:hover +{ + color: #ffffff; + background: #999999; + border-color: #666666; +} + +.linkActive:hover { + background: #507aac; +} + +.linkActive:active { + background: #2f943c; +} + +/* Config Tables */ +.tblConfig td { + padding-right: 40px; +} + +.tables { + border: 1px solid black; + text-align: center; +} + +.tables th { + border-bottom: 2px solid black; +} + +.tables th, .tables td { + border-right: 2px dotted black; + min-width: 70px; +} + +/* Footer */ +.footer { + height: 15px; + position: absolute; + right: 10px; + bottom: 10px; +} + +/* Hacking stuff. */ +.hack { + color: #fff; + text-shadow: 1px 1px #300; + font-size: 1.12em; +} +.hackBtn { + background-color: #a00 !important; +} +.hackBtn:hover { + background-color: #fff !important; +} +.hackBtn:hover .hack { + color: #000 !important; +} \ No newline at end of file diff --git a/html/nttc/src/html/index.html b/html/nttc/src/html/index.html new file mode 100644 index 00000000000..80e7a40ac81 --- /dev/null +++ b/html/nttc/src/html/index.html @@ -0,0 +1,31 @@ + + + + + + NTSL + + + + + + + +
+ +
+ + + + \ No newline at end of file diff --git a/html/nttc/src/html/tabs/tab_filtering.html b/html/nttc/src/html/tabs/tab_filtering.html new file mode 100644 index 00000000000..ee9797c51a9 --- /dev/null +++ b/html/nttc/src/html/tabs/tab_filtering.html @@ -0,0 +1,17 @@ +
+

Filtering Settings

+ + + + + + + + + + + + + +
Announce Jobs?
Announce Timecodes?
Language Conversion?
+
diff --git a/html/nttc/src/html/tabs/tab_firewall.html b/html/nttc/src/html/tabs/tab_firewall.html new file mode 100644 index 00000000000..db8ee8a0f73 --- /dev/null +++ b/html/nttc/src/html/tabs/tab_firewall.html @@ -0,0 +1,4 @@ +
+

FIREWALL

+ +
\ No newline at end of file diff --git a/html/nttc/src/html/tabs/tab_hack.html b/html/nttc/src/html/tabs/tab_hack.html new file mode 100644 index 00000000000..189ac836954 --- /dev/null +++ b/html/nttc/src/html/tabs/tab_hack.html @@ -0,0 +1,22 @@ +
+

1337 HAaCCkEr MeNU!

+ + + + + + + + + +
H*lp Tr%%ait0r i* $c/e#ce
HoNKKk!!11!
+
+ \ No newline at end of file diff --git a/html/nttc/src/html/tabs/tab_home.html b/html/nttc/src/html/tabs/tab_home.html new file mode 100644 index 00000000000..eb98b18a4db --- /dev/null +++ b/html/nttc/src/html/tabs/tab_home.html @@ -0,0 +1,9 @@ +
+

Home

+ + + + + +
Telecomms Activated?
+
diff --git a/html/nttc/src/html/tabs/tab_regex.html b/html/nttc/src/html/tabs/tab_regex.html new file mode 100644 index 00000000000..3e3d0d90229 --- /dev/null +++ b/html/nttc/src/html/tabs/tab_regex.html @@ -0,0 +1,4 @@ +
+

Regex

+ +
\ No newline at end of file diff --git a/html/nttc/src/img/uiTitleFluff.png b/html/nttc/src/img/uiTitleFluff.png new file mode 100644 index 00000000000..513ba0c4965 Binary files /dev/null and b/html/nttc/src/img/uiTitleFluff.png differ diff --git a/html/nttc/src/index.js b/html/nttc/src/index.js new file mode 100644 index 00000000000..d6040629e53 --- /dev/null +++ b/html/nttc/src/index.js @@ -0,0 +1 @@ +var main = require("./js/main.js") \ No newline at end of file diff --git a/html/nttc/src/js/link_loader.js b/html/nttc/src/js/link_loader.js new file mode 100644 index 00000000000..6e5a26f78fe --- /dev/null +++ b/html/nttc/src/js/link_loader.js @@ -0,0 +1,14 @@ +var $ = require("jquery"); + +module.exports.reload = function () { + $(".linkActive") + .off("click") + .on("click", function (event) { + event.preventDefault(); + var href = $(this).data("href"); + if (href) { + href = window.byondSrc + href; + window.location.href = href; + } + }) +}; \ No newline at end of file diff --git a/html/nttc/src/js/main.js b/html/nttc/src/js/main.js new file mode 100644 index 00000000000..99a553b061b --- /dev/null +++ b/html/nttc/src/js/main.js @@ -0,0 +1,42 @@ +var $ = require("jquery"); +var he = require("he"); +var templater = require("./templater.js") + +$(document).ready(function () { + if(window.originalConfig) { + window.config = JSON.parse(he.decode(window.originalConfig)) + } + + var current_tab = "home"; + + function tab(tabname) { + console.log(tabname) + loadtab(tabname); + } + + function loadtab(tabname) { + current_tab = tabname; + $.when($.ajax({ + url: "tab_" + tabname + ".html", + cache: false, + dataType: 'html'})) + .done(function (tabdata) { + $("#content").html(tabdata); + templater.parseCurrentPage(); + }); + } + + window.reload_tab = function() { + loadtab(current_tab) + } + + loadtab("home"); + $(".navBtn[data-tab='home']").addClass("btnActive"); + + $(".navBtn").click(function () { + $(".navBtn").removeClass("btnActive") + var toSwitch = $(this).data("tab"); + $(this).addClass("btnActive"); + tab(toSwitch); + }); +}); \ No newline at end of file diff --git a/html/nttc/src/js/templater.js b/html/nttc/src/js/templater.js new file mode 100644 index 00000000000..14efb3d865c --- /dev/null +++ b/html/nttc/src/js/templater.js @@ -0,0 +1,145 @@ +var $ = require("jquery"); + +function createLink(href, text) { + let $link = $("
"); + $link.addClass("link linkActive"); + $link.data("href", href); + $link.attr("unselectable", "on") + $link.text(text); + return $link; +} + +function link_onClick(event) { + event.preventDefault(); + let href = $(this).data("href") + if (href) { + href = window.byondSrc + href; + window.location.href = href; + } +} + +module.exports.parseCurrentPage = function () { + $("listBoat").each(function () { + var config_attr = $(this).data("config"); + if (!config_attr) + return; + + let th = $(this).data("header"); + + let dataList = config[config_attr]; + $(this).replaceWith(""); + + if (th) { + let assembledString = ""; + let split = th.split("|"); + for (let header in split) { + assembledString += ""; + } + assembledString += ""; + $("#WORK").append(assembledString); + } + + for (let key in dataList) { + let value = dataList[key]; + let $tr = $(""); + $tr.append($("\s*$/g, + + // We have to close these tags to support XHTML (#13200) + wrapMap = { + option: [ 1, "" ], + legend: [ 1, "
", "
" ], + area: [ 1, "", "" ], + param: [ 1, "", "" ], + thead: [ 1, "
"; + assembledString += split[header]; + assembledString += "
").text(key)); + $tr.append($("").text(value)); + let $td = $(""); + $td.append(createLink('table='+config_attr+';delete_row='+key, "X")) + $tr.append($td); + $("#WORK").append($tr); + } + + $(createLink('table='+config_attr+';create_row=1', "New")).insertAfter("#WORK").click(link_onClick); + $("#WORK .link").click(link_onClick); + $("#WORK").attr("id", null); + }); + + $("arrayBoat").each(function () { + var config_attr = $(this).data("config"); + if (!config_attr) + return; + + let th = $(this).data("header"); + + let dataList = config[config_attr]; + $(this).replaceWith(""); + + if (th) { + let assembledString = ""; + let split = th.split("|"); + for (let header in split) { + assembledString += ""; + } + assembledString += ""; + $("#WORK").append(assembledString); + } + + for (var i = 0; i < dataList.length; i++) { + let value = dataList[i]; + let $tr = $(""); + $tr.append($("\s*$/g,Ue={option:[1,""],legend:[1,"
","
"],area:[1,"",""],param:[1,"",""],thead:[1,"
"; + assembledString += split[header]; + assembledString += "
").text(value)); + let $td = $(""); + $td.append(createLink('array='+config_attr+';delete_item='+value, "X")) + $tr.append($td); + $("#WORK").append($tr); + } + + $(createLink('array='+config_attr+';create_item=1', "New")).insertAfter("#WORK").click(link_onClick); + $("#WORK .link").click(link_onClick); + $("#WORK").attr("id", null); + }); + + $("activeLink").each(function () { + let href = $(this).data("href"); + let simple_config = $(this).data("sconfig"); + let advanced_config = $(this).data("aconfig"); + let internalText = $(this).text(); + + $(this).replaceWith("
") + $("#WORK") + .addClass("link linkActive") + .data("href", href) + .text(internalText) + .on("click", link_onClick) + .attr("unselectable", "on") + + if (simple_config) { + if (window.config[simple_config]) { + $("#WORK") + .addClass("linkOn") + .text("Enabled") + } else { + $("#WORK") + .text("Disabled") + } + } + + if (advanced_config) { + if (window.config[advanced_config]) + $("#WORK").text(window.config[advanced_config]) + else + $("#WORK").text("Unset") + } + + $("#WORK").attr("id", null); + }); + + if (!window.secretsunlocked) { + $("div[data-locked='1']").hide() + } else { + $("div[data-locked='1']").show() + } + + $("configRead").each(function () { + let seeked = $(this).data("config"); + $(this).replaceWith("") + $("#WORK") + .text(window.config[seeked]) + .attr("id", null); + }); +} \ No newline at end of file diff --git a/html/nttc/src/package.json b/html/nttc/src/package.json new file mode 100644 index 00000000000..a40efa7ba1c --- /dev/null +++ b/html/nttc/src/package.json @@ -0,0 +1,15 @@ +{ + "name": "nttc-src", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "Tigercat2000", + "license": "AGPL-3.0-only", + "dependencies": { + "he": "^1.1.1", + "jquery": "^3.3.1" + } +} diff --git a/icons/mob/sprite_accessories/vulpkanin/vulpkanin_facial_hair.dmi b/icons/mob/sprite_accessories/vulpkanin/vulpkanin_facial_hair.dmi index ad992fbdfd7..f38ba3fbb60 100644 Binary files a/icons/mob/sprite_accessories/vulpkanin/vulpkanin_facial_hair.dmi and b/icons/mob/sprite_accessories/vulpkanin/vulpkanin_facial_hair.dmi differ diff --git a/icons/obj/clothing/hats.dmi b/icons/obj/clothing/hats.dmi index 70b427e0335..5166e198e64 100644 Binary files a/icons/obj/clothing/hats.dmi and b/icons/obj/clothing/hats.dmi differ diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi index 156419b1bf8..049d5d93f6f 100644 Binary files a/icons/obj/clothing/suits.dmi and b/icons/obj/clothing/suits.dmi differ diff --git a/icons/turf/floors.dmi b/icons/turf/floors.dmi index 2f493a8acc1..135266854fc 100644 Binary files a/icons/turf/floors.dmi and b/icons/turf/floors.dmi differ diff --git a/nano/Gulpfile.js b/nano/Gulpfile.js index d0683ca2b4b..81e7edcdcca 100644 --- a/nano/Gulpfile.js +++ b/nano/Gulpfile.js @@ -30,6 +30,8 @@ const output = { /* Dependencies */ var bower = require("main-bower-files"); var child_process = require("child_process"); +var fs = require("fs"); +var path = require("path"); var del = require("del"); var gulp = require("gulp"); var merge = require("merge-stream"); @@ -50,7 +52,7 @@ const glob = function (path) { return `${path}/*`; }; -var minify = util.env["min"]; +var minify = ((process.env.NODE_ENV || 'development').trim().toLowerCase() === 'production'); /*------Task Section------*/ @@ -58,7 +60,9 @@ var minify = util.env["min"]; * Type: Default/Main * Just runs the rest of the compilation tasks. */ -gulp.task("default", ["fonts", "scripts", "styles"]); +gulp.task("default", ["fonts", "scripts", "styles"], function () { + console.log("Finished...", (minify ? "With minification" : "")) +}); /* Task: Clean * Type: Dependency. @@ -91,12 +95,41 @@ gulp.task("watch", function () { * Run whenever a file is changed. Recompiles and pushes all changes directly to the local BYOND client cache. */ gulp.task("reload", ["default"], function () { - child_process.exec("reload.bat", function (err, stdout, stderr) { - if(err) - return console.log(err); + child_process.exec("reload.bat", function (err, stdout) { + if (err) + throw err; + + var byond_cache = path.join(stdout.trim(), "BYOND", "cache"); + var files = fs.readdirSync(byond_cache); + for (let file of files) { + let filepath = path.join(byond_cache, file); + let stats = fs.statSync(filepath) + if (file.startsWith("tmp") && stats.isDirectory()) { + var tmpFiles = fs.readdirSync(filepath); + if (tmpFiles.includes(output.scripts.main)) { + setTimeout(function () {transfer_files(filepath)}, 500); + } + } + } }); }); +function transfer_files(target) { + let transfer = [input.images, input.layouts, input.templates, output._dir]; + for (let trf of transfer) { + let files = fs.readdirSync(trf) + for (let file of files) { + let fileData = fs.statSync(path.join(trf, file)) + if (fileData.isFile()) + transfer_file(path.join(trf, file), path.join(target, file)) + } + } +} + +function transfer_file(input, target) { + fs.createReadStream(input).pipe(fs.createWriteStream(target)) +} + /*---Buildtasks---*/ /* Task: Fonts diff --git a/nano/README.md b/nano/README.md index 1c009de80a4..12451bfefcd 100644 --- a/nano/README.md +++ b/nano/README.md @@ -101,5 +101,5 @@ of the `Gulpfile.js` and `Gulpfile.coffee` files to perform compilation tasks. In order to build an un-minified version of NanoUI, you may simply run `gulp` in the `nanoui` directory. However, this should only be used while testing, and you should run -the command `gulp --min` before commiting changes, in order to produce minified +the command `export NODE_ENV=production; gulp` before commiting changes, in order to produce minified JavaScript. diff --git a/nano/assets/libraries.min.js b/nano/assets/libraries.min.js index bdd52655aba..0cb56a0002f 100644 --- a/nano/assets/libraries.min.js +++ b/nano/assets/libraries.min.js @@ -1 +1,14598 @@ -!function(e,t){"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(e,t){function n(e){var t="length"in e&&e.length,n=ne.type(e);return"function"!==n&&!ne.isWindow(e)&&(!(1!==e.nodeType||!t)||("array"===n||0===t||"number"==typeof t&&t>0&&t-1 in e))}function i(e,t,n){if(ne.isFunction(t))return ne.grep(e,function(e,i){return!!t.call(e,i,e)!==n});if(t.nodeType)return ne.grep(e,function(e){return e===t!==n});if("string"==typeof t){if(ce.test(t))return ne.filter(t,e,n);t=ne.filter(t,e)}return ne.grep(e,function(e){return ne.inArray(e,t)>=0!==n})}function o(e,t){do{e=e[t]}while(e&&1!==e.nodeType);return e}function r(e){var t=ve[e]={};return ne.each(e.match(me)||[],function(e,n){t[n]=!0}),t}function s(){pe.addEventListener?(pe.removeEventListener("DOMContentLoaded",a,!1),e.removeEventListener("load",a,!1)):(pe.detachEvent("onreadystatechange",a),e.detachEvent("onload",a))}function a(){(pe.addEventListener||"load"===event.type||"complete"===pe.readyState)&&(s(),ne.ready())}function l(e,t,n){if(void 0===n&&1===e.nodeType){var i="data-"+t.replace(Te,"-$1").toLowerCase();if("string"==typeof(n=e.getAttribute(i))){try{n="true"===n||"false"!==n&&("null"===n?null:+n+""===n?+n:we.test(n)?ne.parseJSON(n):n)}catch(e){}ne.data(e,t,n)}else n=void 0}return n}function u(e){var t;for(t in e)if(("data"!==t||!ne.isEmptyObject(e[t]))&&"toJSON"!==t)return!1;return!0}function c(e,t,n,i){if(ne.acceptData(e)){var o,r,s=ne.expando,a=e.nodeType,l=a?ne.cache:e,u=a?e[s]:e[s]&&s;if(u&&l[u]&&(i||l[u].data)||void 0!==n||"string"!=typeof t)return u||(u=a?e[s]=Q.pop()||ne.guid++:s),l[u]||(l[u]=a?{}:{toJSON:ne.noop}),"object"!=typeof t&&"function"!=typeof t||(i?l[u]=ne.extend(l[u],t):l[u].data=ne.extend(l[u].data,t)),r=l[u],i||(r.data||(r.data={}),r=r.data),void 0!==n&&(r[ne.camelCase(t)]=n),"string"==typeof t?null==(o=r[t])&&(o=r[ne.camelCase(t)]):o=r,o}}function f(e,t,n){if(ne.acceptData(e)){var i,o,r=e.nodeType,s=r?ne.cache:e,a=r?e[ne.expando]:ne.expando;if(s[a]){if(t&&(i=n?s[a]:s[a].data)){o=(t=ne.isArray(t)?t.concat(ne.map(t,ne.camelCase)):t in i?[t]:(t=ne.camelCase(t))in i?[t]:t.split(" ")).length;for(;o--;)delete i[t[o]];if(n?!u(i):!ne.isEmptyObject(i))return}(n||(delete s[a].data,u(s[a])))&&(r?ne.cleanData([e],!0):te.deleteExpando||s!=s.window?delete s[a]:s[a]=null)}}}function p(){return!0}function d(){return!1}function h(){try{return pe.activeElement}catch(e){}}function g(e){var t=je.split("|"),n=e.createDocumentFragment();if(n.createElement)for(;t.length;)n.createElement(t.pop());return n}function m(e,t){var n,i,o=0,r=typeof e.getElementsByTagName!==xe?e.getElementsByTagName(t||"*"):typeof e.querySelectorAll!==xe?e.querySelectorAll(t||"*"):void 0;if(!r)for(r=[],n=e.childNodes||e;null!=(i=n[o]);o++)!t||ne.nodeName(i,t)?r.push(i):ne.merge(r,m(i,t));return void 0===t||t&&ne.nodeName(e,t)?ne.merge([e],r):r}function v(e){ke.test(e.type)&&(e.defaultChecked=e.checked)}function y(e,t){return ne.nodeName(e,"table")&&ne.nodeName(11!==t.nodeType?t:t.firstChild,"tr")?e.getElementsByTagName("tbody")[0]||e.appendChild(e.ownerDocument.createElement("tbody")):e}function b(e){return e.type=(null!==ne.find.attr(e,"type"))+"/"+e.type,e}function x(e){var t=$e.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function w(e,t){for(var n,i=0;null!=(n=e[i]);i++)ne._data(n,"globalEval",!t||ne._data(t[i],"globalEval"))}function T(e,t){if(1===t.nodeType&&ne.hasData(e)){var n,i,o,r=ne._data(e),s=ne._data(t,r),a=r.events;if(a){delete s.handle,s.events={};for(n in a)for(i=0,o=a[n].length;i")).appendTo(t.documentElement))[0].contentWindow||Ye[0].contentDocument).document).write(),t.close(),n=_(e,t),Ye.detach()),Ve[e]=n),n}function E(e,t){return{get:function(){var n=e();if(null!=n){if(!n)return(this.get=t).apply(this,arguments);delete this.get}}}}function k(e,t){if(t in e)return t;for(var n=t.charAt(0).toUpperCase()+t.slice(1),i=t,o=lt.length;o--;)if((t=lt[o]+n)in e)return t;return i}function S(e,t){for(var n,i,o,r=[],s=0,a=e.length;s=0&&n=0},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},isPlainObject:function(e){var t;if(!e||"object"!==ne.type(e)||e.nodeType||ne.isWindow(e))return!1;try{if(e.constructor&&!ee.call(e,"constructor")&&!ee.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(e){return!1}if(te.ownLast)for(t in e)return ee.call(e,t);for(t in e);return void 0===t||ee.call(e,t)},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?J[Z.call(e)]||"object":typeof e},globalEval:function(t){t&&ne.trim(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(oe,"ms-").replace(re,se)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t,i){var o=0,r=e.length,s=n(e);if(i){if(s)for(;ox.cacheLength&&delete e[t.shift()],e[n+" "]=i}var t=[];return e}function i(e){return e[I]=!0,e}function o(e){var t=A.createElement("div");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function r(e,t){for(var n=e.split("|"),i=e.length;i--;)x.attrHandle[n[i]]=t}function s(e,t){var n=t&&e,i=n&&1===e.nodeType&&1===t.nodeType&&(~t.sourceIndex||X)-(~e.sourceIndex||X);if(i)return i;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function a(e){return i(function(t){return t=+t,i(function(n,i){for(var o,r=e([],n.length,t),s=r.length;s--;)n[o=r[s]]&&(n[o]=!(i[o]=n[o]))})})}function l(e){return e&&void 0!==e.getElementsByTagName&&e}function u(){}function c(e){for(var t=0,n=e.length,i="";t1?function(t,n,i){for(var o=e.length;o--;)if(!e[o](t,n,i))return!1;return!0}:e[0]}function d(e,n,i){for(var o=0,r=n.length;o-1&&(i[u]=!(s[u]=f))}}else b=h(b===s?b.splice(m,b.length):b),r?r(null,s,b,l):G.apply(s,b)})}function m(e){for(var t,n,i,o=e.length,r=x.relative[e[0].type],s=r||x.relative[" "],a=r?1:0,l=f(function(e){return e===t},s,!0),u=f(function(e){return J(t,e)>-1},s,!0),d=[function(e,n,i){var o=!r&&(i||n!==E)||((t=n).nodeType?l(e,n,i):u(e,n,i));return t=null,o}];a1&&p(d),a>1&&c(e.slice(0,a-1).concat({value:" "===e[a-2].type?"*":""})).replace(se,"$1"),n,a0,r=e.length>0,s=function(i,s,a,l,u){var c,f,p,d=0,g="0",m=i&&[],v=[],y=E,b=i||r&&x.find.TAG("*",u),w=F+=null==y?1:Math.random()||.1,T=b.length;for(u&&(E=s!==A&&s);g!==T&&null!=(c=b[g]);g++){if(r&&c){for(f=0;p=e[f++];)if(p(c,s,a)){l.push(c);break}u&&(F=w)}o&&((c=!p&&c)&&d--,i&&m.push(c))}if(d+=g,o&&g!==d){for(f=0;p=n[f++];)p(m,v,s,a);if(i){if(d>0)for(;g--;)m[g]||v[g]||(v[g]=Y.call(l));v=h(v)}G.apply(l,v),u&&!i&&v.length>0&&d+n.length>1&&t.uniqueSort(l)}return u&&(F=w,E=y),m};return o?i(s):s}var y,b,x,w,T,C,_,N,E,k,S,D,A,H,P,j,L,M,W,I="sizzle"+1*new Date,O=e.document,F=0,q=0,R=n(),B=n(),z=n(),$=function(e,t){return e===t&&(S=!0),0},X=1<<31,U={}.hasOwnProperty,Q=[],Y=Q.pop,V=Q.push,G=Q.push,K=Q.slice,J=function(e,t){for(var n=0,i=e.length;n+~]|"+ee+")"+ee+"*"),ue=new RegExp("="+ee+"*([^\\]'\"]*?)"+ee+"*\\]","g"),ce=new RegExp(oe),fe=new RegExp("^"+ne+"$"),pe={ID:new RegExp("^#("+te+")"),CLASS:new RegExp("^\\.("+te+")"),TAG:new RegExp("^("+te.replace("w","w*")+")"),ATTR:new RegExp("^"+ie),PSEUDO:new RegExp("^"+oe),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+ee+"*(even|odd|(([+-]|)(\\d*)n|)"+ee+"*(?:([+-]|)"+ee+"*(\\d+)|))"+ee+"*\\)|)","i"),bool:new RegExp("^(?:"+Z+")$","i"),needsContext:new RegExp("^"+ee+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+ee+"*((?:-\\d)?\\d*)"+ee+"*\\)|)(?=[^-]|$)","i")},de=/^(?:input|select|textarea|button)$/i,he=/^h\d$/i,ge=/^[^{]+\{\s*\[native \w/,me=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ve=/[+~]/,ye=/'|\\/g,be=new RegExp("\\\\([\\da-f]{1,6}"+ee+"?|("+ee+")|.)","ig"),xe=function(e,t,n){var i="0x"+t-65536;return i!==i||n?t:i<0?String.fromCharCode(i+65536):String.fromCharCode(i>>10|55296,1023&i|56320)},we=function(){D()};try{G.apply(Q=K.call(O.childNodes),O.childNodes),Q[O.childNodes.length].nodeType}catch(e){G={apply:Q.length?function(e,t){V.apply(e,K.call(t))}:function(e,t){for(var n=e.length,i=0;e[n++]=t[i++];);e.length=n-1}}}b=t.support={},T=t.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return!!t&&"HTML"!==t.nodeName},D=t.setDocument=function(e){var t,n,i=e?e.ownerDocument||e:O;return i!==A&&9===i.nodeType&&i.documentElement?(A=i,H=i.documentElement,(n=i.defaultView)&&n!==n.top&&(n.addEventListener?n.addEventListener("unload",we,!1):n.attachEvent&&n.attachEvent("onunload",we)),P=!T(i),b.attributes=o(function(e){return e.className="i",!e.getAttribute("className")}),b.getElementsByTagName=o(function(e){return e.appendChild(i.createComment("")),!e.getElementsByTagName("*").length}),b.getElementsByClassName=ge.test(i.getElementsByClassName),b.getById=o(function(e){return H.appendChild(e).id=I,!i.getElementsByName||!i.getElementsByName(I).length}),b.getById?(x.find.ID=function(e,t){if(void 0!==t.getElementById&&P){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},x.filter.ID=function(e){var t=e.replace(be,xe);return function(e){return e.getAttribute("id")===t}}):(delete x.find.ID,x.filter.ID=function(e){var t=e.replace(be,xe);return function(e){var n=void 0!==e.getAttributeNode&&e.getAttributeNode("id");return n&&n.value===t}}),x.find.TAG=b.getElementsByTagName?function(e,t){return void 0!==t.getElementsByTagName?t.getElementsByTagName(e):b.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,i=[],o=0,r=t.getElementsByTagName(e);if("*"===e){for(;n=r[o++];)1===n.nodeType&&i.push(n);return i}return r},x.find.CLASS=b.getElementsByClassName&&function(e,t){if(P)return t.getElementsByClassName(e)},L=[],j=[],(b.qsa=ge.test(i.querySelectorAll))&&(o(function(e){H.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&j.push("[*^$]="+ee+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||j.push("\\["+ee+"*(?:value|"+Z+")"),e.querySelectorAll("[id~="+I+"-]").length||j.push("~="),e.querySelectorAll(":checked").length||j.push(":checked"),e.querySelectorAll("a#"+I+"+*").length||j.push(".#.+[+~]")}),o(function(e){var t=i.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&j.push("name"+ee+"*[*^$|!~]?="),e.querySelectorAll(":enabled").length||j.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),j.push(",.*:")})),(b.matchesSelector=ge.test(M=H.matches||H.webkitMatchesSelector||H.mozMatchesSelector||H.oMatchesSelector||H.msMatchesSelector))&&o(function(e){b.disconnectedMatch=M.call(e,"div"),M.call(e,"[s!='']:x"),L.push("!=",oe)}),j=j.length&&new RegExp(j.join("|")),L=L.length&&new RegExp(L.join("|")),t=ge.test(H.compareDocumentPosition),W=t||ge.test(H.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,i=t&&t.parentNode;return e===i||!(!i||1!==i.nodeType||!(n.contains?n.contains(i):e.compareDocumentPosition&&16&e.compareDocumentPosition(i)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},$=t?function(e,t){if(e===t)return S=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!b.sortDetached&&t.compareDocumentPosition(e)===n?e===i||e.ownerDocument===O&&W(O,e)?-1:t===i||t.ownerDocument===O&&W(O,t)?1:k?J(k,e)-J(k,t):0:4&n?-1:1)}:function(e,t){if(e===t)return S=!0,0;var n,o=0,r=e.parentNode,a=t.parentNode,l=[e],u=[t];if(!r||!a)return e===i?-1:t===i?1:r?-1:a?1:k?J(k,e)-J(k,t):0;if(r===a)return s(e,t);for(n=e;n=n.parentNode;)l.unshift(n);for(n=t;n=n.parentNode;)u.unshift(n);for(;l[o]===u[o];)o++;return o?s(l[o],u[o]):l[o]===O?-1:u[o]===O?1:0},i):A},t.matches=function(e,n){return t(e,null,null,n)},t.matchesSelector=function(e,n){if((e.ownerDocument||e)!==A&&D(e),n=n.replace(ue,"='$1']"),b.matchesSelector&&P&&(!L||!L.test(n))&&(!j||!j.test(n)))try{var i=M.call(e,n);if(i||b.disconnectedMatch||e.document&&11!==e.document.nodeType)return i}catch(e){}return t(n,A,null,[e]).length>0},t.contains=function(e,t){return(e.ownerDocument||e)!==A&&D(e),W(e,t)},t.attr=function(e,t){(e.ownerDocument||e)!==A&&D(e);var n=x.attrHandle[t.toLowerCase()],i=n&&U.call(x.attrHandle,t.toLowerCase())?n(e,t,!P):void 0;return void 0!==i?i:b.attributes||!P?e.getAttribute(t):(i=e.getAttributeNode(t))&&i.specified?i.value:null},t.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},t.uniqueSort=function(e){var t,n=[],i=0,o=0;if(S=!b.detectDuplicates,k=!b.sortStable&&e.slice(0),e.sort($),S){for(;t=e[o++];)t===e[o]&&(i=n.push(o));for(;i--;)e.splice(n[i],1)}return k=null,e},w=t.getText=function(e){var t,n="",i=0,o=e.nodeType;if(o){if(1===o||9===o||11===o){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=w(e)}else if(3===o||4===o)return e.nodeValue}else for(;t=e[i++];)n+=w(t);return n},(x=t.selectors={cacheLength:50,createPseudo:i,match:pe,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(be,xe),e[3]=(e[3]||e[4]||e[5]||"").replace(be,xe),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||t.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&t.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return pe.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&ce.test(n)&&(t=C(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(be,xe).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=R[e+" "];return t||(t=new RegExp("(^|"+ee+")"+e+"("+ee+"|$)"))&&R(e,function(e){return t.test("string"==typeof e.className&&e.className||void 0!==e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(e,n,i){return function(o){var r=t.attr(o,e);return null==r?"!="===n:!n||(r+="","="===n?r===i:"!="===n?r!==i:"^="===n?i&&0===r.indexOf(i):"*="===n?i&&r.indexOf(i)>-1:"$="===n?i&&r.slice(-i.length)===i:"~="===n?(" "+r.replace(re," ")+" ").indexOf(i)>-1:"|="===n&&(r===i||r.slice(0,i.length+1)===i+"-"))}},CHILD:function(e,t,n,i,o){var r="nth"!==e.slice(0,3),s="last"!==e.slice(-4),a="of-type"===t;return 1===i&&0===o?function(e){return!!e.parentNode}:function(t,n,l){var u,c,f,p,d,h,g=r!==s?"nextSibling":"previousSibling",m=t.parentNode,v=a&&t.nodeName.toLowerCase(),y=!l&&!a;if(m){if(r){for(;g;){for(f=t;f=f[g];)if(a?f.nodeName.toLowerCase()===v:1===f.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[s?m.firstChild:m.lastChild],s&&y){for(d=(u=(c=m[I]||(m[I]={}))[e]||[])[0]===F&&u[1],p=u[0]===F&&u[2],f=d&&m.childNodes[d];f=++d&&f&&f[g]||(p=d=0)||h.pop();)if(1===f.nodeType&&++p&&f===t){c[e]=[F,d,p];break}}else if(y&&(u=(t[I]||(t[I]={}))[e])&&u[0]===F)p=u[1];else for(;(f=++d&&f&&f[g]||(p=d=0)||h.pop())&&((a?f.nodeName.toLowerCase()!==v:1!==f.nodeType)||!++p||(y&&((f[I]||(f[I]={}))[e]=[F,p]),f!==t)););return(p-=o)===i||p%i==0&&p/i>=0}}},PSEUDO:function(e,n){var o,r=x.pseudos[e]||x.setFilters[e.toLowerCase()]||t.error("unsupported pseudo: "+e);return r[I]?r(n):r.length>1?(o=[e,e,"",n],x.setFilters.hasOwnProperty(e.toLowerCase())?i(function(e,t){for(var i,o=r(e,n),s=o.length;s--;)e[i=J(e,o[s])]=!(t[i]=o[s])}):function(e){return r(e,0,o)}):r}},pseudos:{not:i(function(e){var t=[],n=[],o=_(e.replace(se,"$1"));return o[I]?i(function(e,t,n,i){for(var r,s=o(e,null,i,[]),a=e.length;a--;)(r=s[a])&&(e[a]=!(t[a]=r))}):function(e,i,r){return t[0]=e,o(t,null,r,n),t[0]=null,!n.pop()}}),has:i(function(e){return function(n){return t(e,n).length>0}}),contains:i(function(e){return e=e.replace(be,xe),function(t){return(t.textContent||t.innerText||w(t)).indexOf(e)>-1}}),lang:i(function(e){return fe.test(e||"")||t.error("unsupported lang: "+e),e=e.replace(be,xe).toLowerCase(),function(t){var n;do{if(n=P?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return(n=n.toLowerCase())===e||0===n.indexOf(e+"-")}while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===H},focus:function(e){return e===A.activeElement&&(!A.hasFocus||A.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return!1===e.disabled},disabled:function(e){return!0===e.disabled},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!x.pseudos.empty(e)},header:function(e){return he.test(e.nodeName)},input:function(e){return de.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:a(function(){return[0]}),last:a(function(e,t){return[t-1]}),eq:a(function(e,t,n){return[n<0?n+t:n]}),even:a(function(e,t){for(var n=0;n=0;)e.push(i);return e}),gt:a(function(e,t,n){for(var i=n<0?n+t:n;++i2&&"ID"===(s=r[0]).type&&b.getById&&9===t.nodeType&&P&&x.relative[r[1].type]){if(!(t=(x.find.ID(s.matches[0].replace(be,xe),t)||[])[0]))return n;f&&(t=t.parentNode),e=e.slice(r.shift().value.length)}for(o=pe.needsContext.test(e)?0:r.length;o--&&(s=r[o],!x.relative[a=s.type]);)if((u=x.find[a])&&(i=u(s.matches[0].replace(be,xe),ve.test(r[0].type)&&l(t.parentNode)||t))){if(r.splice(o,1),!(e=i.length&&c(r)))return G.apply(n,i),n;break}}return(f||_(e,p))(i,t,!P,n,ve.test(e)&&l(t.parentNode)||t),n},b.sortStable=I.split("").sort($).join("")===I,b.detectDuplicates=!!S,D(),b.sortDetached=o(function(e){return 1&e.compareDocumentPosition(A.createElement("div"))}),o(function(e){return e.innerHTML="","#"===e.firstChild.getAttribute("href")})||r("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),b.attributes&&o(function(e){return e.innerHTML="",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||r("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),o(function(e){return null==e.getAttribute("disabled")})||r(Z,function(e,t,n){var i;if(!n)return!0===e[t]?t.toLowerCase():(i=e.getAttributeNode(t))&&i.specified?i.value:null}),t}(e);ne.find=ae,ne.expr=ae.selectors,ne.expr[":"]=ne.expr.pseudos,ne.unique=ae.uniqueSort,ne.text=ae.getText,ne.isXMLDoc=ae.isXML,ne.contains=ae.contains;var le=ne.expr.match.needsContext,ue=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,ce=/^.[^:#\[\.,]*$/;ne.filter=function(e,t,n){var i=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===i.nodeType?ne.find.matchesSelector(i,e)?[i]:[]:ne.find.matches(e,ne.grep(t,function(e){return 1===e.nodeType}))},ne.fn.extend({find:function(e){var t,n=[],i=this,o=i.length;if("string"!=typeof e)return this.pushStack(ne(e).filter(function(){for(t=0;t1?ne.unique(n):n),n.selector=this.selector?this.selector+" "+e:e,n},filter:function(e){return this.pushStack(i(this,e||[],!1))},not:function(e){return this.pushStack(i(this,e||[],!0))},is:function(e){return!!i(this,"string"==typeof e&&le.test(e)?ne(e):e||[],!1).length}});var fe,pe=e.document,de=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/;(ne.fn.init=function(e,t){var n,i;if(!e)return this;if("string"==typeof e){if(!(n="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:de.exec(e))||!n[1]&&t)return!t||t.jquery?(t||fe).find(e):this.constructor(t).find(e);if(n[1]){if(t=t instanceof ne?t[0]:t,ne.merge(this,ne.parseHTML(n[1],t&&t.nodeType?t.ownerDocument||t:pe,!0)),ue.test(n[1])&&ne.isPlainObject(t))for(n in t)ne.isFunction(this[n])?this[n](t[n]):this.attr(n,t[n]);return this}if((i=pe.getElementById(n[2]))&&i.parentNode){if(i.id!==n[2])return fe.find(e);this.length=1,this[0]=i}return this.context=pe,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):ne.isFunction(e)?void 0!==fe.ready?fe.ready(e):e(ne):(void 0!==e.selector&&(this.selector=e.selector,this.context=e.context),ne.makeArray(e,this))}).prototype=ne.fn,fe=ne(pe);var he=/^(?:parents|prev(?:Until|All))/,ge={children:!0,contents:!0,next:!0,prev:!0};ne.extend({dir:function(e,t,n){for(var i=[],o=e[t];o&&9!==o.nodeType&&(void 0===n||1!==o.nodeType||!ne(o).is(n));)1===o.nodeType&&i.push(o),o=o[t];return i},sibling:function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}}),ne.fn.extend({has:function(e){var t,n=ne(e,this),i=n.length;return this.filter(function(){for(t=0;t-1:1===n.nodeType&&ne.find.matchesSelector(n,e))){r.push(n);break}return this.pushStack(r.length>1?ne.unique(r):r)},index:function(e){return e?"string"==typeof e?ne.inArray(this[0],ne(e)):ne.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(ne.unique(ne.merge(this.get(),ne(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),ne.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return ne.dir(e,"parentNode")},parentsUntil:function(e,t,n){return ne.dir(e,"parentNode",n)},next:function(e){return o(e,"nextSibling")},prev:function(e){return o(e,"previousSibling")},nextAll:function(e){return ne.dir(e,"nextSibling")},prevAll:function(e){return ne.dir(e,"previousSibling")},nextUntil:function(e,t,n){return ne.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return ne.dir(e,"previousSibling",n)},siblings:function(e){return ne.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return ne.sibling(e.firstChild)},contents:function(e){return ne.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:ne.merge([],e.childNodes)}},function(e,t){ne.fn[e]=function(n,i){var o=ne.map(this,t,n);return"Until"!==e.slice(-5)&&(i=n),i&&"string"==typeof i&&(o=ne.filter(i,o)),this.length>1&&(ge[e]||(o=ne.unique(o)),he.test(e)&&(o=o.reverse())),this.pushStack(o)}});var me=/\S+/g,ve={};ne.Callbacks=function(e){var t,n,i,o,s,a,l=[],u=!(e="string"==typeof e?ve[e]||r(e):ne.extend({},e)).once&&[],c=function(r){for(n=e.memory&&r,i=!0,s=a||0,a=0,o=l.length,t=!0;l&&s-1;)l.splice(i,1),t&&(i<=o&&o--,i<=s&&s--)}),this},has:function(e){return e?ne.inArray(e,l)>-1:!(!l||!l.length)},empty:function(){return l=[],o=0,this},disable:function(){return l=u=n=void 0,this},disabled:function(){return!l},lock:function(){return u=void 0,n||f.disable(),this},locked:function(){return!u},fireWith:function(e,n){return!l||i&&!u||(n=[e,(n=n||[]).slice?n.slice():n],t?u.push(n):c(n)),this},fire:function(){return f.fireWith(this,arguments),this},fired:function(){return!!i}};return f},ne.extend({Deferred:function(e){var t=[["resolve","done",ne.Callbacks("once memory"),"resolved"],["reject","fail",ne.Callbacks("once memory"),"rejected"],["notify","progress",ne.Callbacks("memory")]],n="pending",i={state:function(){return n},always:function(){return o.done(arguments).fail(arguments),this},then:function(){var e=arguments;return ne.Deferred(function(n){ne.each(t,function(t,r){var s=ne.isFunction(e[t])&&e[t];o[r[1]](function(){var e=s&&s.apply(this,arguments);e&&ne.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[r[0]+"With"](this===i?n.promise():this,s?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?ne.extend(e,i):i}},o={};return i.pipe=i.then,ne.each(t,function(e,r){var s=r[2],a=r[3];i[r[1]]=s.add,a&&s.add(function(){n=a},t[1^e][2].disable,t[2][2].lock),o[r[0]]=function(){return o[r[0]+"With"](this===o?i:this,arguments),this},o[r[0]+"With"]=s.fireWith}),i.promise(o),e&&e.call(o,o),o},when:function(e){var t,n,i,o=0,r=Y.call(arguments),s=r.length,a=1!==s||e&&ne.isFunction(e.promise)?s:0,l=1===a?e:ne.Deferred(),u=function(e,n,i){return function(o){n[e]=this,i[e]=arguments.length>1?Y.call(arguments):o,i===t?l.notifyWith(n,i):--a||l.resolveWith(n,i)}};if(s>1)for(t=new Array(s),n=new Array(s),i=new Array(s);o0||(ye.resolveWith(pe,[ne]),ne.fn.triggerHandler&&(ne(pe).triggerHandler("ready"),ne(pe).off("ready")))}}}),ne.ready.promise=function(t){if(!ye)if(ye=ne.Deferred(),"complete"===pe.readyState)setTimeout(ne.ready);else if(pe.addEventListener)pe.addEventListener("DOMContentLoaded",a,!1),e.addEventListener("load",a,!1);else{pe.attachEvent("onreadystatechange",a),e.attachEvent("onload",a);var n=!1;try{n=null==e.frameElement&&pe.documentElement}catch(e){}n&&n.doScroll&&function e(){if(!ne.isReady){try{n.doScroll("left")}catch(t){return setTimeout(e,50)}s(),ne.ready()}}()}return ye.promise(t)};var be,xe="undefined";for(be in ne(te))break;te.ownLast="0"!==be,te.inlineBlockNeedsLayout=!1,ne(function(){var e,t,n,i;(n=pe.getElementsByTagName("body")[0])&&n.style&&(t=pe.createElement("div"),(i=pe.createElement("div")).style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",n.appendChild(i).appendChild(t),typeof t.style.zoom!==xe&&(t.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",te.inlineBlockNeedsLayout=e=3===t.offsetWidth,e&&(n.style.zoom=1)),n.removeChild(i))}),function(){var e=pe.createElement("div");if(null==te.deleteExpando){te.deleteExpando=!0;try{delete e.test}catch(e){te.deleteExpando=!1}}e=null}(),ne.acceptData=function(e){var t=ne.noData[(e.nodeName+" ").toLowerCase()],n=+e.nodeType||1;return(1===n||9===n)&&(!t||!0!==t&&e.getAttribute("classid")===t)};var we=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Te=/([A-Z])/g;ne.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(e){return!!(e=e.nodeType?ne.cache[e[ne.expando]]:e[ne.expando])&&!u(e)},data:function(e,t,n){return c(e,t,n)},removeData:function(e,t){return f(e,t)},_data:function(e,t,n){return c(e,t,n,!0)},_removeData:function(e,t){return f(e,t,!0)}}),ne.fn.extend({data:function(e,t){var n,i,o,r=this[0],s=r&&r.attributes;if(void 0===e){if(this.length&&(o=ne.data(r),1===r.nodeType&&!ne._data(r,"parsedAttrs"))){for(n=s.length;n--;)s[n]&&0===(i=s[n].name).indexOf("data-")&&l(r,i=ne.camelCase(i.slice(5)),o[i]);ne._data(r,"parsedAttrs",!0)}return o}return"object"==typeof e?this.each(function(){ne.data(this,e)}):arguments.length>1?this.each(function(){ne.data(this,e,t)}):r?l(r,e,ne.data(r,e)):void 0},removeData:function(e){return this.each(function(){ne.removeData(this,e)})}}),ne.extend({queue:function(e,t,n){var i;if(e)return t=(t||"fx")+"queue",i=ne._data(e,t),n&&(!i||ne.isArray(n)?i=ne._data(e,t,ne.makeArray(n)):i.push(n)),i||[]},dequeue:function(e,t){t=t||"fx";var n=ne.queue(e,t),i=n.length,o=n.shift(),r=ne._queueHooks(e,t);"inprogress"===o&&(o=n.shift(),i--),o&&("fx"===t&&n.unshift("inprogress"),delete r.stop,o.call(e,function(){ne.dequeue(e,t)},r)),!i&&r&&r.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return ne._data(e,n)||ne._data(e,n,{empty:ne.Callbacks("once memory").add(function(){ne._removeData(e,t+"queue"),ne._removeData(e,n)})})}}),ne.fn.extend({queue:function(e,t){var n=2;return"string"!=typeof e&&(t=e,e="fx",n--),arguments.length
a",te.leadingWhitespace=3===t.firstChild.nodeType,te.tbody=!t.getElementsByTagName("tbody").length,te.htmlSerialize=!!t.getElementsByTagName("link").length,te.html5Clone="<:nav>"!==pe.createElement("nav").cloneNode(!0).outerHTML,e.type="checkbox",e.checked=!0,n.appendChild(e),te.appendChecked=e.checked,t.innerHTML="",te.noCloneChecked=!!t.cloneNode(!0).lastChild.defaultValue,n.appendChild(t),t.innerHTML="",te.checkClone=t.cloneNode(!0).cloneNode(!0).lastChild.checked,te.noCloneEvent=!0,t.attachEvent&&(t.attachEvent("onclick",function(){te.noCloneEvent=!1}),t.cloneNode(!0).click()),null==te.deleteExpando){te.deleteExpando=!0;try{delete t.test}catch(e){te.deleteExpando=!1}}}(),function(){var t,n,i=pe.createElement("div");for(t in{submit:!0,change:!0,focusin:!0})n="on"+t,(te[t+"Bubbles"]=n in e)||(i.setAttribute(n,"t"),te[t+"Bubbles"]=!1===i.attributes[n].expando);i=null}();var Se=/^(?:input|select|textarea)$/i,De=/^key/,Ae=/^(?:mouse|pointer|contextmenu)|click/,He=/^(?:focusinfocus|focusoutblur)$/,Pe=/^([^.]*)(?:\.(.+)|)$/;ne.event={global:{},add:function(e,t,n,i,o){var r,s,a,l,u,c,f,p,d,h,g,m=ne._data(e);if(m){for(n.handler&&(n=(l=n).handler,o=l.selector),n.guid||(n.guid=ne.guid++),(s=m.events)||(s=m.events={}),(c=m.handle)||((c=m.handle=function(e){return typeof ne===xe||e&&ne.event.triggered===e.type?void 0:ne.event.dispatch.apply(c.elem,arguments)}).elem=e),a=(t=(t||"").match(me)||[""]).length;a--;)d=g=(r=Pe.exec(t[a])||[])[1],h=(r[2]||"").split(".").sort(),d&&(u=ne.event.special[d]||{},d=(o?u.delegateType:u.bindType)||d,u=ne.event.special[d]||{},f=ne.extend({type:d,origType:g,data:i,handler:n,guid:n.guid,selector:o,needsContext:o&&ne.expr.match.needsContext.test(o),namespace:h.join(".")},l),(p=s[d])||((p=s[d]=[]).delegateCount=0,u.setup&&!1!==u.setup.call(e,i,h,c)||(e.addEventListener?e.addEventListener(d,c,!1):e.attachEvent&&e.attachEvent("on"+d,c))),u.add&&(u.add.call(e,f),f.handler.guid||(f.handler.guid=n.guid)),o?p.splice(p.delegateCount++,0,f):p.push(f),ne.event.global[d]=!0);e=null}},remove:function(e,t,n,i,o){var r,s,a,l,u,c,f,p,d,h,g,m=ne.hasData(e)&&ne._data(e);if(m&&(c=m.events)){for(u=(t=(t||"").match(me)||[""]).length;u--;)if(a=Pe.exec(t[u])||[],d=g=a[1],h=(a[2]||"").split(".").sort(),d){for(f=ne.event.special[d]||{},p=c[d=(i?f.delegateType:f.bindType)||d]||[],a=a[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),l=r=p.length;r--;)s=p[r],!o&&g!==s.origType||n&&n.guid!==s.guid||a&&!a.test(s.namespace)||i&&i!==s.selector&&("**"!==i||!s.selector)||(p.splice(r,1),s.selector&&p.delegateCount--,f.remove&&f.remove.call(e,s));l&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,m.handle)||ne.removeEvent(e,d,m.handle),delete c[d])}else for(d in c)ne.event.remove(e,d+t[u],n,i,!0);ne.isEmptyObject(c)&&(delete m.handle,ne._removeData(e,"events"))}},trigger:function(t,n,i,o){var r,s,a,l,u,c,f,p=[i||pe],d=ee.call(t,"type")?t.type:t,h=ee.call(t,"namespace")?t.namespace.split("."):[];if(a=c=i=i||pe,3!==i.nodeType&&8!==i.nodeType&&!He.test(d+ne.event.triggered)&&(d.indexOf(".")>=0&&(d=(h=d.split(".")).shift(),h.sort()),s=d.indexOf(":")<0&&"on"+d,t=t[ne.expando]?t:new ne.Event(d,"object"==typeof t&&t),t.isTrigger=o?2:3,t.namespace=h.join("."),t.namespace_re=t.namespace?new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,t.result=void 0,t.target||(t.target=i),n=null==n?[t]:ne.makeArray(n,[t]),u=ne.event.special[d]||{},o||!u.trigger||!1!==u.trigger.apply(i,n))){if(!o&&!u.noBubble&&!ne.isWindow(i)){for(l=u.delegateType||d,He.test(l+d)||(a=a.parentNode);a;a=a.parentNode)p.push(a),c=a;c===(i.ownerDocument||pe)&&p.push(c.defaultView||c.parentWindow||e)}for(f=0;(a=p[f++])&&!t.isPropagationStopped();)t.type=f>1?l:u.bindType||d,(r=(ne._data(a,"events")||{})[t.type]&&ne._data(a,"handle"))&&r.apply(a,n),(r=s&&a[s])&&r.apply&&ne.acceptData(a)&&(t.result=r.apply(a,n),!1===t.result&&t.preventDefault());if(t.type=d,!o&&!t.isDefaultPrevented()&&(!u._default||!1===u._default.apply(p.pop(),n))&&ne.acceptData(i)&&s&&i[d]&&!ne.isWindow(i)){(c=i[s])&&(i[s]=null),ne.event.triggered=d;try{i[d]()}catch(e){}ne.event.triggered=void 0,c&&(i[s]=c)}return t.result}},dispatch:function(e){e=ne.event.fix(e);var t,n,i,o,r,s=[],a=Y.call(arguments),l=(ne._data(this,"events")||{})[e.type]||[],u=ne.event.special[e.type]||{};if(a[0]=e,e.delegateTarget=this,!u.preDispatch||!1!==u.preDispatch.call(this,e)){for(s=ne.event.handlers.call(this,e,l),t=0;(o=s[t++])&&!e.isPropagationStopped();)for(e.currentTarget=o.elem,r=0;(i=o.handlers[r++])&&!e.isImmediatePropagationStopped();)e.namespace_re&&!e.namespace_re.test(i.namespace)||(e.handleObj=i,e.data=i.data,void 0!==(n=((ne.event.special[i.origType]||{}).handle||i.handler).apply(o.elem,a))&&!1===(e.result=n)&&(e.preventDefault(),e.stopPropagation()));return u.postDispatch&&u.postDispatch.call(this,e),e.result}},handlers:function(e,t){var n,i,o,r,s=[],a=t.delegateCount,l=e.target;if(a&&l.nodeType&&(!e.button||"click"!==e.type))for(;l!=this;l=l.parentNode||this)if(1===l.nodeType&&(!0!==l.disabled||"click"!==e.type)){for(o=[],r=0;r=0:ne.find(n,this,null,[l]).length),o[n]&&o.push(i);o.length&&s.push({elem:l,handlers:o})}return a]","i"),We=/^\s+/,Ie=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,Oe=/<([\w:]+)/,Fe=/
","
"],tr:[2,"","
"],col:[2,"","
"],td:[3,"","
"],_default:te.htmlSerialize?[0,"",""]:[1,"X
","
"]},Qe=g(pe).appendChild(pe.createElement("div"));Ue.optgroup=Ue.option,Ue.tbody=Ue.tfoot=Ue.colgroup=Ue.caption=Ue.thead,Ue.th=Ue.td,ne.extend({clone:function(e,t,n){var i,o,r,s,a,l=ne.contains(e.ownerDocument,e);if(te.html5Clone||ne.isXMLDoc(e)||!Me.test("<"+e.nodeName+">")?r=e.cloneNode(!0):(Qe.innerHTML=e.outerHTML,Qe.removeChild(r=Qe.firstChild)),!(te.noCloneEvent&&te.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||ne.isXMLDoc(e)))for(i=m(r),a=m(e),s=0;null!=(o=a[s]);++s)i[s]&&C(o,i[s]);if(t)if(n)for(a=a||m(e),i=i||m(r),s=0;null!=(o=a[s]);s++)T(o,i[s]);else T(e,r);return(i=m(r,"script")).length>0&&w(i,!l&&m(e,"script")),i=a=o=null,r},buildFragment:function(e,t,n,i){for(var o,r,s,a,l,u,c,f=e.length,p=g(t),d=[],h=0;h")+c[2],o=c[0];o--;)a=a.lastChild;if(!te.leadingWhitespace&&We.test(r)&&d.push(t.createTextNode(We.exec(r)[0])),!te.tbody)for(o=(r="table"!==l||Fe.test(r)?""!==c[1]||Fe.test(r)?0:a:a.firstChild)&&r.childNodes.length;o--;)ne.nodeName(u=r.childNodes[o],"tbody")&&!u.childNodes.length&&r.removeChild(u);for(ne.merge(d,a.childNodes),a.textContent="";a.firstChild;)a.removeChild(a.firstChild);a=p.lastChild}else d.push(t.createTextNode(r));for(a&&p.removeChild(a),te.appendChecked||ne.grep(m(d,"input"),v),h=0;r=d[h++];)if((!i||-1===ne.inArray(r,i))&&(s=ne.contains(r.ownerDocument,r),a=m(p.appendChild(r),"script"),s&&w(a),n))for(o=0;r=a[o++];)ze.test(r.type||"")&&n.push(r);return a=null,p},cleanData:function(e,t){for(var n,i,o,r,s=0,a=ne.expando,l=ne.cache,u=te.deleteExpando,c=ne.event.special;null!=(n=e[s]);s++)if((t||ne.acceptData(n))&&(o=n[a],r=o&&l[o])){if(r.events)for(i in r.events)c[i]?ne.event.remove(n,i):ne.removeEvent(n,i,r.handle);l[o]&&(delete l[o],u?delete n[a]:typeof n.removeAttribute!==xe?n.removeAttribute(a):n[a]=null,Q.push(o))}}}),ne.fn.extend({text:function(e){return Ee(this,function(e){return void 0===e?ne.text(this):this.empty().append((this[0]&&this[0].ownerDocument||pe).createTextNode(e))},null,e,arguments.length)},append:function(){return this.domManip(arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||y(this,e).appendChild(e)})},prepend:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=y(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},remove:function(e,t){for(var n,i=e?ne.filter(e,this):this,o=0;null!=(n=i[o]);o++)t||1!==n.nodeType||ne.cleanData(m(n)),n.parentNode&&(t&&ne.contains(n.ownerDocument,n)&&w(m(n,"script")),n.parentNode.removeChild(n));return this},empty:function(){for(var e,t=0;null!=(e=this[t]);t++){for(1===e.nodeType&&ne.cleanData(m(e,!1));e.firstChild;)e.removeChild(e.firstChild);e.options&&ne.nodeName(e,"select")&&(e.options.length=0)}return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return ne.clone(this,e,t)})},html:function(e){return Ee(this,function(e){var t=this[0]||{},n=0,i=this.length;if(void 0===e)return 1===t.nodeType?t.innerHTML.replace(Le,""):void 0;if("string"==typeof e&&!Re.test(e)&&(te.htmlSerialize||!Me.test(e))&&(te.leadingWhitespace||!We.test(e))&&!Ue[(Oe.exec(e)||["",""])[1].toLowerCase()]){e=e.replace(Ie,"<$1>");try{for(;n1&&"string"==typeof p&&!te.checkClone&&Be.test(p))return this.each(function(n){var i=c.eq(n);d&&(e[0]=p.call(this,n,i.html())),i.domManip(e,t)});if(u&&(a=ne.buildFragment(e,this[0].ownerDocument,!1,this),n=a.firstChild,1===a.childNodes.length&&(a=n),n)){for(o=(r=ne.map(m(a,"script"),b)).length;l
t
",(o=t.getElementsByTagName("td"))[0].style.cssText="margin:0;border:0;padding:0;display:none",(a=0===o[0].offsetHeight)&&(o[0].style.display="",o[1].style.display="none",a=0===o[0].offsetHeight),n.removeChild(i))}var n,i,o,r,s,a,l;(n=pe.createElement("div")).innerHTML="
a",(i=(o=n.getElementsByTagName("a")[0])&&o.style)&&(i.cssText="float:left;opacity:.5",te.opacity="0.5"===i.opacity,te.cssFloat=!!i.cssFloat,n.style.backgroundClip="content-box",n.cloneNode(!0).style.backgroundClip="",te.clearCloneStyle="content-box"===n.style.backgroundClip,te.boxSizing=""===i.boxSizing||""===i.MozBoxSizing||""===i.WebkitBoxSizing,ne.extend(te,{reliableHiddenOffsets:function(){return null==a&&t(),a},boxSizingReliable:function(){return null==s&&t(),s},pixelPosition:function(){return null==r&&t(),r},reliableMarginRight:function(){return null==l&&t(),l}}))}(),ne.swap=function(e,t,n,i){var o,r,s={};for(r in t)s[r]=e.style[r],e.style[r]=t[r];o=n.apply(e,i||[]);for(r in t)e.style[r]=s[r];return o};var tt=/alpha\([^)]*\)/i,nt=/opacity\s*=\s*([^)]*)/,it=/^(none|table(?!-c[ea]).+)/,ot=new RegExp("^("+Ce+")(.*)$","i"),rt=new RegExp("^([+-])=("+Ce+")","i"),st={position:"absolute",visibility:"hidden",display:"block"},at={letterSpacing:"0",fontWeight:"400"},lt=["Webkit","O","Moz","ms"];ne.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Ke(e,"opacity");return""===n?"1":n}}}},cssNumber:{columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{float:te.cssFloat?"cssFloat":"styleFloat"},style:function(e,t,n,i){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var o,r,s,a=ne.camelCase(t),l=e.style;if(t=ne.cssProps[a]||(ne.cssProps[a]=k(l,a)),s=ne.cssHooks[t]||ne.cssHooks[a],void 0===n)return s&&"get"in s&&void 0!==(o=s.get(e,!1,i))?o:l[t];if("string"==(r=typeof n)&&(o=rt.exec(n))&&(n=(o[1]+1)*o[2]+parseFloat(ne.css(e,t)),r="number"),null!=n&&n===n&&("number"!==r||ne.cssNumber[a]||(n+="px"),te.clearCloneStyle||""!==n||0!==t.indexOf("background")||(l[t]="inherit"),!(s&&"set"in s&&void 0===(n=s.set(e,n,i)))))try{l[t]=n}catch(e){}}},css:function(e,t,n,i){var o,r,s,a=ne.camelCase(t);return t=ne.cssProps[a]||(ne.cssProps[a]=k(e.style,a)),(s=ne.cssHooks[t]||ne.cssHooks[a])&&"get"in s&&(r=s.get(e,!0,n)),void 0===r&&(r=Ke(e,t,i)),"normal"===r&&t in at&&(r=at[t]),""===n||n?(o=parseFloat(r),!0===n||ne.isNumeric(o)?o||0:r):r}}),ne.each(["height","width"],function(e,t){ne.cssHooks[t]={get:function(e,n,i){if(n)return it.test(ne.css(e,"display"))&&0===e.offsetWidth?ne.swap(e,st,function(){return H(e,t,i)}):H(e,t,i)},set:function(e,n,i){var o=i&&Ge(e);return D(0,n,i?A(e,t,i,te.boxSizing&&"border-box"===ne.css(e,"boxSizing",!1,o),o):0)}}}),te.opacity||(ne.cssHooks.opacity={get:function(e,t){return nt.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var n=e.style,i=e.currentStyle,o=ne.isNumeric(t)?"alpha(opacity="+100*t+")":"",r=i&&i.filter||n.filter||"";n.zoom=1,(t>=1||""===t)&&""===ne.trim(r.replace(tt,""))&&n.removeAttribute&&(n.removeAttribute("filter"),""===t||i&&!i.filter)||(n.filter=tt.test(r)?r.replace(tt,o):r+" "+o)}}),ne.cssHooks.marginRight=E(te.reliableMarginRight,function(e,t){if(t)return ne.swap(e,{display:"inline-block"},Ke,[e,"marginRight"])}),ne.each({margin:"",padding:"",border:"Width"},function(e,t){ne.cssHooks[e+t]={expand:function(n){for(var i=0,o={},r="string"==typeof n?n.split(" "):[n];i<4;i++)o[e+_e[i]+t]=r[i]||r[i-2]||r[0];return o}},Je.test(e)||(ne.cssHooks[e+t].set=D)}),ne.fn.extend({css:function(e,t){return Ee(this,function(e,t,n){var i,o,r={},s=0;if(ne.isArray(t)){for(i=Ge(e),o=t.length;s1)},show:function(){return S(this,!0)},hide:function(){return S(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){Ne(this)?ne(this).show():ne(this).hide()})}}),ne.Tween=P,P.prototype={constructor:P,init:function(e,t,n,i,o,r){this.elem=e,this.prop=n,this.easing=o||"swing",this.options=t,this.start=this.now=this.cur(),this.end=i,this.unit=r||(ne.cssNumber[n]?"":"px")},cur:function(){var e=P.propHooks[this.prop];return e&&e.get?e.get(this):P.propHooks._default.get(this)},run:function(e){var t,n=P.propHooks[this.prop];return this.options.duration?this.pos=t=ne.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):P.propHooks._default.set(this),this}},P.prototype.init.prototype=P.prototype,P.propHooks={_default:{get:function(e){var t;return null==e.elem[e.prop]||e.elem.style&&null!=e.elem.style[e.prop]?(t=ne.css(e.elem,e.prop,""))&&"auto"!==t?t:0:e.elem[e.prop]},set:function(e){ne.fx.step[e.prop]?ne.fx.step[e.prop](e):e.elem.style&&(null!=e.elem.style[ne.cssProps[e.prop]]||ne.cssHooks[e.prop])?ne.style(e.elem,e.prop,e.now+e.unit):e.elem[e.prop]=e.now}}},P.propHooks.scrollTop=P.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},ne.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2}},ne.fx=P.prototype.init,ne.fx.step={};var ut,ct,ft=/^(?:toggle|show|hide)$/,pt=new RegExp("^(?:([+-])=|)("+Ce+")([a-z%]*)$","i"),dt=/queueHooks$/,ht=[function(e,t,n){var i,o,r,s,a,l,u,c=this,f={},p=e.style,d=e.nodeType&&Ne(e),h=ne._data(e,"fxshow");n.queue||(null==(a=ne._queueHooks(e,"fx")).unqueued&&(a.unqueued=0,l=a.empty.fire,a.empty.fire=function(){a.unqueued||l()}),a.unqueued++,c.always(function(){c.always(function(){a.unqueued--,ne.queue(e,"fx").length||a.empty.fire()})})),1===e.nodeType&&("height"in t||"width"in t)&&(n.overflow=[p.overflow,p.overflowX,p.overflowY],"inline"===("none"===(u=ne.css(e,"display"))?ne._data(e,"olddisplay")||N(e.nodeName):u)&&"none"===ne.css(e,"float")&&(te.inlineBlockNeedsLayout&&"inline"!==N(e.nodeName)?p.zoom=1:p.display="inline-block")),n.overflow&&(p.overflow="hidden",te.shrinkWrapBlocks()||c.always(function(){p.overflow=n.overflow[0],p.overflowX=n.overflow[1],p.overflowY=n.overflow[2]}));for(i in t)if(o=t[i],ft.exec(o)){if(delete t[i],r=r||"toggle"===o,o===(d?"hide":"show")){if("show"!==o||!h||void 0===h[i])continue;d=!0}f[i]=h&&h[i]||ne.style(e,i)}else u=void 0;if(ne.isEmptyObject(f))"inline"===("none"===u?N(e.nodeName):u)&&(p.display=u);else{h?"hidden"in h&&(d=h.hidden):h=ne._data(e,"fxshow",{}),r&&(h.hidden=!d),d?ne(e).show():c.done(function(){ne(e).hide()}),c.done(function(){var t;ne._removeData(e,"fxshow");for(t in f)ne.style(e,t,f[t])});for(i in f)s=M(d?h[i]:0,i,c),i in h||(h[i]=s.start,d&&(s.end=s.start,s.start="width"===i||"height"===i?1:0))}}],gt={"*":[function(e,t){var n=this.createTween(e,t),i=n.cur(),o=pt.exec(t),r=o&&o[3]||(ne.cssNumber[e]?"":"px"),s=(ne.cssNumber[e]||"px"!==r&&+i)&&pt.exec(ne.css(n.elem,e)),a=1,l=20;if(s&&s[3]!==r){r=r||s[3],o=o||[],s=+i||1;do{s/=a=a||".5",ne.style(n.elem,e,s+r)}while(a!==(a=n.cur()/i)&&1!==a&&--l)}return o&&(s=n.start=+s||+i||0,n.unit=r,n.end=o[1]?s+(o[1]+1)*o[2]:+o[2]),n}]};ne.Animation=ne.extend(I,{tweener:function(e,t){ne.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");for(var n,i=0,o=e.length;i
a",i=t.getElementsByTagName("a")[0],o=(n=pe.createElement("select")).appendChild(pe.createElement("option")),e=t.getElementsByTagName("input")[0],i.style.cssText="top:1px",te.getSetAttribute="t"!==t.className,te.style=/top/.test(i.getAttribute("style")),te.hrefNormalized="/a"===i.getAttribute("href"),te.checkOn=!!e.value,te.optSelected=o.selected,te.enctype=!!pe.createElement("form").enctype,n.disabled=!0,te.optDisabled=!o.disabled,(e=pe.createElement("input")).setAttribute("value",""),te.input=""===e.getAttribute("value"),e.value="t",e.setAttribute("type","radio"),te.radioValue="t"===e.value}();var mt=/\r/g;ne.fn.extend({val:function(e){var t,n,i,o=this[0];{if(arguments.length)return i=ne.isFunction(e),this.each(function(n){var o;1===this.nodeType&&(null==(o=i?e.call(this,n,ne(this).val()):e)?o="":"number"==typeof o?o+="":ne.isArray(o)&&(o=ne.map(o,function(e){return null==e?"":e+""})),(t=ne.valHooks[this.type]||ne.valHooks[this.nodeName.toLowerCase()])&&"set"in t&&void 0!==t.set(this,o,"value")||(this.value=o))});if(o)return(t=ne.valHooks[o.type]||ne.valHooks[o.nodeName.toLowerCase()])&&"get"in t&&void 0!==(n=t.get(o,"value"))?n:"string"==typeof(n=o.value)?n.replace(mt,""):null==n?"":n}}}),ne.extend({valHooks:{option:{get:function(e){var t=ne.find.attr(e,"value");return null!=t?t:ne.trim(ne.text(e))}},select:{get:function(e){for(var t,n,i=e.options,o=e.selectedIndex,r="select-one"===e.type||o<0,s=r?null:[],a=r?o+1:i.length,l=o<0?a:r?o:0;l=0)try{i.selected=n=!0}catch(e){i.scrollHeight}else i.selected=!1;return n||(e.selectedIndex=-1),o}}}}),ne.each(["radio","checkbox"],function(){ne.valHooks[this]={set:function(e,t){if(ne.isArray(t))return e.checked=ne.inArray(ne(e).val(),t)>=0}},te.checkOn||(ne.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})});var vt,yt,bt=ne.expr.attrHandle,xt=/^(?:checked|selected)$/i,wt=te.getSetAttribute,Tt=te.input;ne.fn.extend({attr:function(e,t){return Ee(this,ne.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){ne.removeAttr(this,e)})}}),ne.extend({attr:function(e,t,n){var i,o,r=e.nodeType;if(e&&3!==r&&8!==r&&2!==r)return typeof e.getAttribute===xe?ne.prop(e,t,n):(1===r&&ne.isXMLDoc(e)||(t=t.toLowerCase(),i=ne.attrHooks[t]||(ne.expr.match.bool.test(t)?yt:vt)),void 0===n?i&&"get"in i&&null!==(o=i.get(e,t))?o:null==(o=ne.find.attr(e,t))?void 0:o:null!==n?i&&"set"in i&&void 0!==(o=i.set(e,n,t))?o:(e.setAttribute(t,n+""),n):void ne.removeAttr(e,t))},removeAttr:function(e,t){var n,i,o=0,r=t&&t.match(me);if(r&&1===e.nodeType)for(;n=r[o++];)i=ne.propFix[n]||n,ne.expr.match.bool.test(n)?Tt&&wt||!xt.test(n)?e[i]=!1:e[ne.camelCase("default-"+n)]=e[i]=!1:ne.attr(e,n,""),e.removeAttribute(wt?n:i)},attrHooks:{type:{set:function(e,t){if(!te.radioValue&&"radio"===t&&ne.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}}}),yt={set:function(e,t,n){return!1===t?ne.removeAttr(e,n):Tt&&wt||!xt.test(n)?e.setAttribute(!wt&&ne.propFix[n]||n,n):e[ne.camelCase("default-"+n)]=e[n]=!0,n}},ne.each(ne.expr.match.bool.source.match(/\w+/g),function(e,t){var n=bt[t]||ne.find.attr;bt[t]=Tt&&wt||!xt.test(t)?function(e,t,i){var o,r;return i||(r=bt[t],bt[t]=o,o=null!=n(e,t,i)?t.toLowerCase():null,bt[t]=r),o}:function(e,t,n){if(!n)return e[ne.camelCase("default-"+t)]?t.toLowerCase():null}}),Tt&&wt||(ne.attrHooks.value={set:function(e,t,n){if(!ne.nodeName(e,"input"))return vt&&vt.set(e,t,n);e.defaultValue=t}}),wt||(vt={set:function(e,t,n){var i=e.getAttributeNode(n);if(i||e.setAttributeNode(i=e.ownerDocument.createAttribute(n)),i.value=t+="","value"===n||t===e.getAttribute(n))return t}},bt.id=bt.name=bt.coords=function(e,t,n){var i;if(!n)return(i=e.getAttributeNode(t))&&""!==i.value?i.value:null},ne.valHooks.button={get:function(e,t){var n=e.getAttributeNode(t);if(n&&n.specified)return n.value},set:vt.set},ne.attrHooks.contenteditable={set:function(e,t,n){vt.set(e,""!==t&&t,n)}},ne.each(["width","height"],function(e,t){ne.attrHooks[t]={set:function(e,n){if(""===n)return e.setAttribute(t,"auto"),n}}})),te.style||(ne.attrHooks.style={get:function(e){return e.style.cssText||void 0},set:function(e,t){return e.style.cssText=t+""}});var Ct=/^(?:input|select|textarea|button|object)$/i,_t=/^(?:a|area)$/i;ne.fn.extend({prop:function(e,t){return Ee(this,ne.prop,e,t,arguments.length>1)},removeProp:function(e){return e=ne.propFix[e]||e,this.each(function(){try{this[e]=void 0,delete this[e]}catch(e){}})}}),ne.extend({propFix:{for:"htmlFor",class:"className"},prop:function(e,t,n){var i,o,r=e.nodeType;if(e&&3!==r&&8!==r&&2!==r)return(1!==r||!ne.isXMLDoc(e))&&(t=ne.propFix[t]||t,o=ne.propHooks[t]),void 0!==n?o&&"set"in o&&void 0!==(i=o.set(e,n,t))?i:e[t]=n:o&&"get"in o&&null!==(i=o.get(e,t))?i:e[t]},propHooks:{tabIndex:{get:function(e){var t=ne.find.attr(e,"tabindex");return t?parseInt(t,10):Ct.test(e.nodeName)||_t.test(e.nodeName)&&e.href?0:-1}}}}),te.hrefNormalized||ne.each(["href","src"],function(e,t){ne.propHooks[t]={get:function(e){return e.getAttribute(t,4)}}}),te.optSelected||(ne.propHooks.selected={get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null}}),ne.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){ne.propFix[this.toLowerCase()]=this}),te.enctype||(ne.propFix.enctype="encoding");var Nt=/[\t\r\n\f]/g;ne.fn.extend({addClass:function(e){var t,n,i,o,r,s,a=0,l=this.length,u="string"==typeof e&&e;if(ne.isFunction(e))return this.each(function(t){ne(this).addClass(e.call(this,t,this.className))});if(u)for(t=(e||"").match(me)||[];a=0;)i=i.replace(" "+o+" "," ");s=e?ne.trim(i):"",n.className!==s&&(n.className=s)}return this},toggleClass:function(e,t){var n=typeof e;return"boolean"==typeof t&&"string"===n?t?this.addClass(e):this.removeClass(e):ne.isFunction(e)?this.each(function(n){ne(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if("string"===n)for(var t,i=0,o=ne(this),r=e.match(me)||[];t=r[i++];)o.hasClass(t)?o.removeClass(t):o.addClass(t);else n!==xe&&"boolean"!==n||(this.className&&ne._data(this,"__className__",this.className),this.className=this.className||!1===e?"":ne._data(this,"__className__")||"")})},hasClass:function(e){for(var t=" "+e+" ",n=0,i=this.length;n=0)return!0;return!1}}),ne.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(e,t){ne.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),ne.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,i){return this.on(t,e,n,i)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)}});var Et=ne.now(),kt=/\?/,St=/^[\],:{}\s]*$/,Dt=/(?:^|:|,)(?:\s*\[)+/g,At=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,Ht=/"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g;ne.parseJSON=function(t){return e.JSON&&e.JSON.parse?e.JSON.parse(t):null===t?t:"string"==typeof t&&(t=ne.trim(t))&&St.test(t.replace(At,"@").replace(Ht,"]").replace(Dt,""))?new Function("return "+t)():void ne.error("Invalid JSON: "+t)},ne.parseXML=function(t){var n,i;if(!t||"string"!=typeof t)return null;try{e.DOMParser?(i=new DOMParser,n=i.parseFromString(t,"text/xml")):((n=new ActiveXObject("Microsoft.XMLDOM")).async="false",n.loadXML(t))}catch(e){n=void 0}return n&&n.documentElement&&!n.getElementsByTagName("parsererror").length||ne.error("Invalid XML: "+t),n};var Pt,jt,Lt=/#.*$/,Mt=/([?&])_=[^&]*/,Wt=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,It=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Ot=/^(?:GET|HEAD)$/,Ft=/^\/\//,qt=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Rt={},Bt={},zt="*/".concat("*");try{jt=location.href}catch(e){(jt=pe.createElement("a")).href="",jt=jt.href}Pt=qt.exec(jt.toLowerCase())||[],ne.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:jt,type:"GET",isLocal:It.test(Pt[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":zt,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":ne.parseJSON,"text xml":ne.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?q(q(e,ne.ajaxSettings),t):q(ne.ajaxSettings,e)},ajaxPrefilter:O(Rt),ajaxTransport:O(Bt),ajax:function(e,t){function n(e,t,n,i){var o,c,v,y,x,T=t;2!==b&&(b=2,a&&clearTimeout(a),u=void 0,s=i||"",w.readyState=e>0?4:0,o=e>=200&&e<300||304===e,n&&(y=R(f,w,n)),y=B(f,y,w,o),o?(f.ifModified&&((x=w.getResponseHeader("Last-Modified"))&&(ne.lastModified[r]=x),(x=w.getResponseHeader("etag"))&&(ne.etag[r]=x)),204===e||"HEAD"===f.type?T="nocontent":304===e?T="notmodified":(T=y.state,c=y.data,o=!(v=y.error))):(v=T,!e&&T||(T="error",e<0&&(e=0))),w.status=e,w.statusText=(t||T)+"",o?h.resolveWith(p,[c,T,w]):h.rejectWith(p,[w,T,v]),w.statusCode(m),m=void 0,l&&d.trigger(o?"ajaxSuccess":"ajaxError",[w,f,o?c:v]),g.fireWith(p,[w,T]),l&&(d.trigger("ajaxComplete",[w,f]),--ne.active||ne.event.trigger("ajaxStop")))}"object"==typeof e&&(t=e,e=void 0),t=t||{};var i,o,r,s,a,l,u,c,f=ne.ajaxSetup({},t),p=f.context||f,d=f.context&&(p.nodeType||p.jquery)?ne(p):ne.event,h=ne.Deferred(),g=ne.Callbacks("once memory"),m=f.statusCode||{},v={},y={},b=0,x="canceled",w={readyState:0,getResponseHeader:function(e){var t;if(2===b){if(!c)for(c={};t=Wt.exec(s);)c[t[1].toLowerCase()]=t[2];t=c[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return 2===b?s:null},setRequestHeader:function(e,t){var n=e.toLowerCase();return b||(e=y[n]=y[n]||e,v[e]=t),this},overrideMimeType:function(e){return b||(f.mimeType=e),this},statusCode:function(e){var t;if(e)if(b<2)for(t in e)m[t]=[m[t],e[t]];else w.always(e[w.status]);return this},abort:function(e){var t=e||x;return u&&u.abort(t),n(0,t),this}};if(h.promise(w).complete=g.add,w.success=w.done,w.error=w.fail,f.url=((e||f.url||jt)+"").replace(Lt,"").replace(Ft,Pt[1]+"//"),f.type=t.method||t.type||f.method||f.type,f.dataTypes=ne.trim(f.dataType||"*").toLowerCase().match(me)||[""],null==f.crossDomain&&(i=qt.exec(f.url.toLowerCase()),f.crossDomain=!(!i||i[1]===Pt[1]&&i[2]===Pt[2]&&(i[3]||("http:"===i[1]?"80":"443"))===(Pt[3]||("http:"===Pt[1]?"80":"443")))),f.data&&f.processData&&"string"!=typeof f.data&&(f.data=ne.param(f.data,f.traditional)),F(Rt,f,t,w),2===b)return w;(l=ne.event&&f.global)&&0==ne.active++&&ne.event.trigger("ajaxStart"),f.type=f.type.toUpperCase(),f.hasContent=!Ot.test(f.type),r=f.url,f.hasContent||(f.data&&(r=f.url+=(kt.test(r)?"&":"?")+f.data,delete f.data),!1===f.cache&&(f.url=Mt.test(r)?r.replace(Mt,"$1_="+Et++):r+(kt.test(r)?"&":"?")+"_="+Et++)),f.ifModified&&(ne.lastModified[r]&&w.setRequestHeader("If-Modified-Since",ne.lastModified[r]),ne.etag[r]&&w.setRequestHeader("If-None-Match",ne.etag[r])),(f.data&&f.hasContent&&!1!==f.contentType||t.contentType)&&w.setRequestHeader("Content-Type",f.contentType),w.setRequestHeader("Accept",f.dataTypes[0]&&f.accepts[f.dataTypes[0]]?f.accepts[f.dataTypes[0]]+("*"!==f.dataTypes[0]?", "+zt+"; q=0.01":""):f.accepts["*"]);for(o in f.headers)w.setRequestHeader(o,f.headers[o]);if(f.beforeSend&&(!1===f.beforeSend.call(p,w,f)||2===b))return w.abort();x="abort";for(o in{success:1,error:1,complete:1})w[o](f[o]);if(u=F(Bt,f,t,w)){w.readyState=1,l&&d.trigger("ajaxSend",[w,f]),f.async&&f.timeout>0&&(a=setTimeout(function(){w.abort("timeout")},f.timeout));try{b=1,u.send(v,n)}catch(e){if(!(b<2))throw e;n(-1,e)}}else n(-1,"No Transport");return w},getJSON:function(e,t,n){return ne.get(e,t,n,"json")},getScript:function(e,t){return ne.get(e,void 0,t,"script")}}),ne.each(["get","post"],function(e,t){ne[t]=function(e,n,i,o){return ne.isFunction(n)&&(o=o||i,i=n,n=void 0),ne.ajax({url:e,type:t,dataType:o,data:n,success:i})}}),ne._evalUrl=function(e){return ne.ajax({url:e,type:"GET",dataType:"script",async:!1,global:!1,throws:!0})},ne.fn.extend({wrapAll:function(e){if(ne.isFunction(e))return this.each(function(t){ne(this).wrapAll(e.call(this,t))});if(this[0]){var t=ne(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){for(var e=this;e.firstChild&&1===e.firstChild.nodeType;)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return ne.isFunction(e)?this.each(function(t){ne(this).wrapInner(e.call(this,t))}):this.each(function(){var t=ne(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=ne.isFunction(e);return this.each(function(n){ne(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){ne.nodeName(this,"body")||ne(this).replaceWith(this.childNodes)}).end()}}),ne.expr.filters.hidden=function(e){return e.offsetWidth<=0&&e.offsetHeight<=0||!te.reliableHiddenOffsets()&&"none"===(e.style&&e.style.display||ne.css(e,"display"))},ne.expr.filters.visible=function(e){return!ne.expr.filters.hidden(e)};var $t=/%20/g,Xt=/\[\]$/,Ut=/\r?\n/g,Qt=/^(?:submit|button|image|reset|file)$/i,Yt=/^(?:input|select|textarea|keygen)/i;ne.param=function(e,t){var n,i=[],o=function(e,t){t=ne.isFunction(t)?t():null==t?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};if(void 0===t&&(t=ne.ajaxSettings&&ne.ajaxSettings.traditional),ne.isArray(e)||e.jquery&&!ne.isPlainObject(e))ne.each(e,function(){o(this.name,this.value)});else for(n in e)z(n,e[n],t,o);return i.join("&").replace($t,"+")},ne.fn.extend({serialize:function(){return ne.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=ne.prop(this,"elements");return e?ne.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!ne(this).is(":disabled")&&Yt.test(this.nodeName)&&!Qt.test(e)&&(this.checked||!ke.test(e))}).map(function(e,t){var n=ne(this).val();return null==n?null:ne.isArray(n)?ne.map(n,function(e){return{name:t.name,value:e.replace(Ut,"\r\n")}}):{name:t.name,value:n.replace(Ut,"\r\n")}}).get()}}),ne.ajaxSettings.xhr=void 0!==e.ActiveXObject?function(){return!this.isLocal&&/^(get|post|head|put|delete|options)$/i.test(this.type)&&$()||X()}:$;var Vt=0,Gt={},Kt=ne.ajaxSettings.xhr();e.attachEvent&&e.attachEvent("onunload",function(){for(var e in Gt)Gt[e](void 0,!0)}),te.cors=!!Kt&&"withCredentials"in Kt,(Kt=te.ajax=!!Kt)&&ne.ajaxTransport(function(e){if(!e.crossDomain||te.cors){var t;return{send:function(n,i){var o,r=e.xhr(),s=++Vt;if(r.open(e.type,e.url,e.async,e.username,e.password),e.xhrFields)for(o in e.xhrFields)r[o]=e.xhrFields[o];e.mimeType&&r.overrideMimeType&&r.overrideMimeType(e.mimeType),e.crossDomain||n["X-Requested-With"]||(n["X-Requested-With"]="XMLHttpRequest");for(o in n)void 0!==n[o]&&r.setRequestHeader(o,n[o]+"");r.send(e.hasContent&&e.data||null),t=function(n,o){var a,l,u;if(t&&(o||4===r.readyState))if(delete Gt[s],t=void 0,r.onreadystatechange=ne.noop,o)4!==r.readyState&&r.abort();else{u={},a=r.status,"string"==typeof r.responseText&&(u.text=r.responseText);try{l=r.statusText}catch(e){l=""}a||!e.isLocal||e.crossDomain?1223===a&&(a=204):a=u.text?200:404}u&&i(a,l,u,r.getAllResponseHeaders())},e.async?4===r.readyState?setTimeout(t):r.onreadystatechange=Gt[s]=t:t()},abort:function(){t&&t(void 0,!0)}}}}),ne.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(e){return ne.globalEval(e),e}}}),ne.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),ne.ajaxTransport("script",function(e){if(e.crossDomain){var t,n=pe.head||ne("head")[0]||pe.documentElement;return{send:function(i,o){(t=pe.createElement("script")).async=!0,e.scriptCharset&&(t.charset=e.scriptCharset),t.src=e.url,t.onload=t.onreadystatechange=function(e,n){(n||!t.readyState||/loaded|complete/.test(t.readyState))&&(t.onload=t.onreadystatechange=null,t.parentNode&&t.parentNode.removeChild(t),t=null,n||o(200,"success"))},n.insertBefore(t,n.firstChild)},abort:function(){t&&t.onload(void 0,!0)}}}});var Jt=[],Zt=/(=)\?(?=&|$)|\?\?/;ne.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Jt.pop()||ne.expando+"_"+Et++;return this[e]=!0,e}}),ne.ajaxPrefilter("json jsonp",function(t,n,i){var o,r,s,a=!1!==t.jsonp&&(Zt.test(t.url)?"url":"string"==typeof t.data&&!(t.contentType||"").indexOf("application/x-www-form-urlencoded")&&Zt.test(t.data)&&"data");if(a||"jsonp"===t.dataTypes[0])return o=t.jsonpCallback=ne.isFunction(t.jsonpCallback)?t.jsonpCallback():t.jsonpCallback,a?t[a]=t[a].replace(Zt,"$1"+o):!1!==t.jsonp&&(t.url+=(kt.test(t.url)?"&":"?")+t.jsonp+"="+o),t.converters["script json"]=function(){return s||ne.error(o+" was not called"),s[0]},t.dataTypes[0]="json",r=e[o],e[o]=function(){s=arguments},i.always(function(){e[o]=r,t[o]&&(t.jsonpCallback=n.jsonpCallback,Jt.push(o)),s&&ne.isFunction(r)&&r(s[0]),s=r=void 0}),"script"}),ne.parseHTML=function(e,t,n){if(!e||"string"!=typeof e)return null;"boolean"==typeof t&&(n=t,t=!1),t=t||pe;var i=ue.exec(e),o=!n&&[];return i?[t.createElement(i[1])]:(i=ne.buildFragment([e],t,o),o&&o.length&&ne(o).remove(),ne.merge([],i.childNodes))};var en=ne.fn.load;ne.fn.load=function(e,t,n){if("string"!=typeof e&&en)return en.apply(this,arguments);var i,o,r,s=this,a=e.indexOf(" ");return a>=0&&(i=ne.trim(e.slice(a,e.length)),e=e.slice(0,a)),ne.isFunction(t)?(n=t,t=void 0):t&&"object"==typeof t&&(r="POST"),s.length>0&&ne.ajax({url:e,type:r,dataType:"html",data:t}).done(function(e){o=arguments,s.html(i?ne("
").append(ne.parseHTML(e)).find(i):e)}).complete(n&&function(e,t){s.each(n,o||[e.responseText,t,e])}),this},ne.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){ne.fn[t]=function(e){return this.on(t,e)}}),ne.expr.filters.animated=function(e){return ne.grep(ne.timers,function(t){return e===t.elem}).length};var tn=e.document.documentElement;ne.offset={setOffset:function(e,t,n){var i,o,r,s,a,l,u=ne.css(e,"position"),c=ne(e),f={};"static"===u&&(e.style.position="relative"),a=c.offset(),r=ne.css(e,"top"),l=ne.css(e,"left"),("absolute"===u||"fixed"===u)&&ne.inArray("auto",[r,l])>-1?(s=(i=c.position()).top,o=i.left):(s=parseFloat(r)||0,o=parseFloat(l)||0),ne.isFunction(t)&&(t=t.call(e,n,a)),null!=t.top&&(f.top=t.top-a.top+s),null!=t.left&&(f.left=t.left-a.left+o),"using"in t?t.using.call(e,f):c.css(f)}},ne.fn.extend({offset:function(e){if(arguments.length)return void 0===e?this:this.each(function(t){ne.offset.setOffset(this,e,t)});var t,n,i={top:0,left:0},o=this[0],r=o&&o.ownerDocument;if(r)return t=r.documentElement,ne.contains(t,o)?(typeof o.getBoundingClientRect!==xe&&(i=o.getBoundingClientRect()),n=U(r),{top:i.top+(n.pageYOffset||t.scrollTop)-(t.clientTop||0),left:i.left+(n.pageXOffset||t.scrollLeft)-(t.clientLeft||0)}):i},position:function(){if(this[0]){var e,t,n={top:0,left:0},i=this[0];return"fixed"===ne.css(i,"position")?t=i.getBoundingClientRect():(e=this.offsetParent(),t=this.offset(),ne.nodeName(e[0],"html")||(n=e.offset()),n.top+=ne.css(e[0],"borderTopWidth",!0),n.left+=ne.css(e[0],"borderLeftWidth",!0)),{top:t.top-n.top-ne.css(i,"marginTop",!0),left:t.left-n.left-ne.css(i,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){for(var e=this.offsetParent||tn;e&&!ne.nodeName(e,"html")&&"static"===ne.css(e,"position");)e=e.offsetParent;return e||tn})}}),ne.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,t){var n=/Y/.test(t);ne.fn[e]=function(i){return Ee(this,function(e,i,o){var r=U(e);if(void 0===o)return r?t in r?r[t]:r.document.documentElement[i]:e[i];r?r.scrollTo(n?ne(r).scrollLeft():o,n?o:ne(r).scrollTop()):e[i]=o},e,i,arguments.length,null)}}),ne.each(["top","left"],function(e,t){ne.cssHooks[t]=E(te.pixelPosition,function(e,n){if(n)return n=Ke(e,t),Ze.test(n)?ne(e).position()[t]+"px":n})}),ne.each({Height:"height",Width:"width"},function(e,t){ne.each({padding:"inner"+e,content:t,"":"outer"+e},function(n,i){ne.fn[i]=function(i,o){var r=arguments.length&&(n||"boolean"!=typeof i),s=n||(!0===i||!0===o?"margin":"border");return Ee(this,function(t,n,i){var o;return ne.isWindow(t)?t.document.documentElement["client"+e]:9===t.nodeType?(o=t.documentElement,Math.max(t.body["scroll"+e],o["scroll"+e],t.body["offset"+e],o["offset"+e],o["client"+e])):void 0===i?ne.css(t,n,s):ne.style(t,n,i,s)},t,r?i:void 0,r,null)}})}),ne.fn.size=function(){return this.length},ne.fn.andSelf=ne.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return ne});var nn=e.jQuery,on=e.$;return ne.noConflict=function(t){return e.$===ne&&(e.$=on),t&&e.jQuery===ne&&(e.jQuery=nn),ne},typeof t===xe&&(e.jQuery=e.$=ne),ne}),function(e){"function"==typeof define&&define.amd?define(["jquery"],e):e(jQuery)}(function(e){function t(t,i){var o,r,s,a=t.nodeName.toLowerCase();return"area"===a?(o=t.parentNode,r=o.name,!(!t.href||!r||"map"!==o.nodeName.toLowerCase())&&(!!(s=e("img[usemap='#"+r+"']")[0])&&n(s))):(/^(input|select|textarea|button|object)$/.test(a)?!t.disabled:"a"===a?t.href||i:i)&&n(t)}function n(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 n=this.css("position"),i="absolute"===n,o=t?/(auto|scroll|hidden)/:/(auto|scroll)/,r=this.parents().filter(function(){var t=e(this);return(!i||"static"!==t.css("position"))&&o.test(t.css("overflow")+t.css("overflow-y")+t.css("overflow-x"))}).eq(0);return"fixed"!==n&&r.length?r: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(n){return!!e.data(n,t)}}):function(t,n,i){return!!e.data(t,i[3])},focusable:function(n){return t(n,!isNaN(e.attr(n,"tabindex")))},tabbable:function(n){var i=e.attr(n,"tabindex"),o=isNaN(i);return(o||i>=0)&&t(n,!o)}}),e("").outerWidth(1).jquery||e.each(["Width","Height"],function(t,n){function i(t,n,i,r){return e.each(o,function(){n-=parseFloat(e.css(t,"padding"+this))||0,i&&(n-=parseFloat(e.css(t,"border"+this+"Width"))||0),r&&(n-=parseFloat(e.css(t,"margin"+this))||0)}),n}var o="Width"===n?["Left","Right"]:["Top","Bottom"],r=n.toLowerCase(),s={innerWidth:e.fn.innerWidth,innerHeight:e.fn.innerHeight,outerWidth:e.fn.outerWidth,outerHeight:e.fn.outerHeight};e.fn["inner"+n]=function(t){return void 0===t?s["inner"+n].call(this):this.each(function(){e(this).css(r,i(this,t)+"px")})},e.fn["outer"+n]=function(t,o){return"number"!=typeof t?s["outer"+n].call(this,t):this.each(function(){e(this).css(r,i(this,t,!0,o)+"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(n){return arguments.length?t.call(this,e.camelCase(n)):t.call(this)}}(e.fn.removeData)),e.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase()),e.fn.extend({focus:function(t){return function(n,i){return"number"==typeof n?this.each(function(){var t=this;setTimeout(function(){e(t).focus(),i&&i.call(t)},n)}):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 n,i,o=e(this[0]);o.length&&o[0]!==document;){if(("absolute"===(n=o.css("position"))||"relative"===n||"fixed"===n)&&(i=parseInt(o.css("zIndex"),10),!isNaN(i)&&0!==i))return i;o=o.parent()}return 0}}),e.ui.plugin={add:function(t,n,i){var o,r=e.ui[t].prototype;for(o in i)r.plugins[o]=r.plugins[o]||[],r.plugins[o].push([n,i[o]])},call:function(e,t,n,i){var o,r=e.plugins[t];if(r&&(i||e.element[0].parentNode&&11!==e.element[0].parentNode.nodeType))for(o=0;o",options:{disabled:!1,create:null},_createWidget:function(t,n){n=e(n||this.defaultElement||this)[0],this.element=e(n),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=e(),this.hoverable=e(),this.focusable=e(),n!==this&&(e.data(n,this.widgetFullName,this),this._on(!0,this.element,{remove:function(e){e.target===n&&this.destroy()}}),this.document=e(n.style?n.ownerDocument:n.document||n),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,n){var i,o,r,s=t;if(0===arguments.length)return e.widget.extend({},this.options);if("string"==typeof t)if(s={},i=t.split("."),t=i.shift(),i.length){for(o=s[t]=e.widget.extend({},this.options[t]),r=0;r=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}});!function(){function t(e,t,n){return[parseFloat(e[0])*(d.test(e[0])?t/100:1),parseFloat(e[1])*(d.test(e[1])?n/100:1)]}function n(t,n){return parseInt(e.css(t,n),10)||0}function i(t){var n=t[0];return 9===n.nodeType?{width:t.width(),height:t.height(),offset:{top:0,left:0}}:e.isWindow(n)?{width:t.width(),height:t.height(),offset:{top:t.scrollTop(),left:t.scrollLeft()}}:n.preventDefault?{width:0,height:0,offset:{top:n.pageY,left:n.pageX}}:{width:t.outerWidth(),height:t.outerHeight(),offset:t.offset()}}e.ui=e.ui||{};var o,r,s=Math.max,a=Math.abs,l=Math.round,u=/left|center|right/,c=/top|center|bottom/,f=/[\+\-]\d+(\.[\d]+)?%?/,p=/^\w+/,d=/%$/,h=e.fn.position;e.position={scrollbarWidth:function(){if(void 0!==o)return o;var t,n,i=e("
"),r=i.children()[0];return e("body").append(i),t=r.offsetWidth,i.css("overflow","scroll"),n=r.offsetWidth,t===n&&(n=i[0].clientWidth),i.remove(),o=t-n},getScrollInfo:function(t){var n=t.isWindow||t.isDocument?"":t.element.css("overflow-x"),i=t.isWindow||t.isDocument?"":t.element.css("overflow-y"),o="scroll"===n||"auto"===n&&t.width0?"right":"center",vertical:r<0?"top":i>0?"bottom":"middle"};gs(a(i),a(r))?l.important="horizontal":l.important="vertical",o.using.call(this,e,l)}),c.offset(e.extend(k,{using:u}))})},e.ui.position={fit:{left:function(e,t){var n,i=t.within,o=i.isWindow?i.scrollLeft:i.offset.left,r=i.width,a=e.left-t.collisionPosition.marginLeft,l=o-a,u=a+t.collisionWidth-r-o;t.collisionWidth>r?l>0&&u<=0?(n=e.left+l+t.collisionWidth-r-o,e.left+=l-n):e.left=u>0&&l<=0?o:l>u?o+r-t.collisionWidth:o:l>0?e.left+=l:u>0?e.left-=u:e.left=s(e.left-a,e.left)},top:function(e,t){var n,i=t.within,o=i.isWindow?i.scrollTop:i.offset.top,r=t.within.height,a=e.top-t.collisionPosition.marginTop,l=o-a,u=a+t.collisionHeight-r-o;t.collisionHeight>r?l>0&&u<=0?(n=e.top+l+t.collisionHeight-r-o,e.top+=l-n):e.top=u>0&&l<=0?o:l>u?o+r-t.collisionHeight:o:l>0?e.top+=l:u>0?e.top-=u:e.top=s(e.top-a,e.top)}},flip:{left:function(e,t){var n,i,o=t.within,r=o.offset.left+o.scrollLeft,s=o.width,l=o.isWindow?o.scrollLeft:o.offset.left,u=e.left-t.collisionPosition.marginLeft,c=u-l,f=u+t.collisionWidth-s-l,p="left"===t.my[0]?-t.elemWidth:"right"===t.my[0]?t.elemWidth:0,d="left"===t.at[0]?t.targetWidth:"right"===t.at[0]?-t.targetWidth:0,h=-2*t.offset[0];c<0?((n=e.left+p+d+h+t.collisionWidth-s-r)<0||n0&&((i=e.left-t.collisionPosition.marginLeft+p+d+h-l)>0||a(i)0&&((n=e.top-t.collisionPosition.marginTop+p+d+h-l)>0||a(n)10&&o<11,t.innerHTML="",n.removeChild(t)}()}();e.ui.position;e.widget("ui.draggable",e.ui.mouse,{version:"1.11.4",widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1,drag:null,start:null,stop:null},_create:function(){"original"===this.options.helper&&this._setPositionRelative(),this.options.addClasses&&this.element.addClass("ui-draggable"),this.options.disabled&&this.element.addClass("ui-draggable-disabled"),this._setHandleClassName(),this._mouseInit()},_setOption:function(e,t){this._super(e,t),"handle"===e&&(this._removeHandleClassName(),this._setHandleClassName())},_destroy:function(){(this.helper||this.element).is(".ui-draggable-dragging")?this.destroyOnClear=!0:(this.element.removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled"),this._removeHandleClassName(),this._mouseDestroy())},_mouseCapture:function(t){var n=this.options;return this._blurActiveElement(t),!(this.helper||n.disabled||e(t.target).closest(".ui-resizable-handle").length>0)&&(this.handle=this._getHandle(t),!!this.handle&&(this._blockFrames(!0===n.iframeFix?"iframe":n.iframeFix),!0))},_blockFrames:function(t){this.iframeBlocks=this.document.find(t).map(function(){var t=e(this);return e("
").css("position","absolute").appendTo(t.parent()).outerWidth(t.outerWidth()).outerHeight(t.outerHeight()).offset(t.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_blurActiveElement:function(t){var n=this.document[0];if(this.handleElement.is(t.target))try{n.activeElement&&"body"!==n.activeElement.nodeName.toLowerCase()&&e(n.activeElement).blur()}catch(e){}},_mouseStart:function(t){var n=this.options;return this.helper=this._createHelper(t),this.helper.addClass("ui-draggable-dragging"),this._cacheHelperProportions(),e.ui.ddmanager&&(e.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(!0),this.offsetParent=this.helper.offsetParent(),this.hasFixedAncestor=this.helper.parents().filter(function(){return"fixed"===e(this).css("position")}).length>0,this.positionAbs=this.element.offset(),this._refreshOffsets(t),this.originalPosition=this.position=this._generatePosition(t,!1),this.originalPageX=t.pageX,this.originalPageY=t.pageY,n.cursorAt&&this._adjustOffsetFromHelper(n.cursorAt),this._setContainment(),!1===this._trigger("start",t)?(this._clear(),!1):(this._cacheHelperProportions(),e.ui.ddmanager&&!n.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t),this._normalizeRightBottom(),this._mouseDrag(t,!0),e.ui.ddmanager&&e.ui.ddmanager.dragStart(this,t),!0)},_refreshOffsets:function(e){this.offset={top:this.positionAbs.top-this.margins.top,left:this.positionAbs.left-this.margins.left,scroll:!1,parent:this._getParentOffset(),relative:this._getRelativeOffset()},this.offset.click={left:e.pageX-this.offset.left,top:e.pageY-this.offset.top}},_mouseDrag:function(t,n){if(this.hasFixedAncestor&&(this.offset.parent=this._getParentOffset()),this.position=this._generatePosition(t,!0),this.positionAbs=this._convertPositionTo("absolute"),!n){var i=this._uiHash();if(!1===this._trigger("drag",t,i))return this._mouseUp({}),!1;this.position=i.position}return this.helper[0].style.left=this.position.left+"px",this.helper[0].style.top=this.position.top+"px",e.ui.ddmanager&&e.ui.ddmanager.drag(this,t),!1},_mouseStop:function(t){var n=this,i=!1;return e.ui.ddmanager&&!this.options.dropBehaviour&&(i=e.ui.ddmanager.drop(this,t)),this.dropped&&(i=this.dropped,this.dropped=!1),"invalid"===this.options.revert&&!i||"valid"===this.options.revert&&i||!0===this.options.revert||e.isFunction(this.options.revert)&&this.options.revert.call(this.element,i)?e(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){!1!==n._trigger("stop",t)&&n._clear()}):!1!==this._trigger("stop",t)&&this._clear(),!1},_mouseUp:function(t){return this._unblockFrames(),e.ui.ddmanager&&e.ui.ddmanager.dragStop(this,t),this.handleElement.is(t.target)&&this.element.focus(),e.ui.mouse.prototype._mouseUp.call(this,t)},cancel:function(){return this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear(),this},_getHandle:function(t){return!this.options.handle||!!e(t.target).closest(this.element.find(this.options.handle)).length},_setHandleClassName:function(){this.handleElement=this.options.handle?this.element.find(this.options.handle):this.element,this.handleElement.addClass("ui-draggable-handle")},_removeHandleClassName:function(){this.handleElement.removeClass("ui-draggable-handle")},_createHelper:function(t){var n=this.options,i=e.isFunction(n.helper),o=i?e(n.helper.apply(this.element[0],[t])):"clone"===n.helper?this.element.clone().removeAttr("id"):this.element;return o.parents("body").length||o.appendTo("parent"===n.appendTo?this.element[0].parentNode:n.appendTo),i&&o[0]===this.element[0]&&this._setPositionRelative(),o[0]===this.element[0]||/(fixed|absolute)/.test(o.css("position"))||o.css("position","absolute"),o},_setPositionRelative:function(){/^(?:r|a|f)/.test(this.element.css("position"))||(this.element[0].style.position="relative")},_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)},_isRootNode:function(e){return/(html|body)/i.test(e.tagName)||e===this.document[0]},_getParentOffset:function(){var t=this.offsetParent.offset(),n=this.document[0];return"absolute"===this.cssPosition&&this.scrollParent[0]!==n&&e.contains(this.scrollParent[0],this.offsetParent[0])&&(t.left+=this.scrollParent.scrollLeft(),t.top+=this.scrollParent.scrollTop()),this._isRootNode(this.offsetParent[0])&&(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)return{top:0,left:0};var e=this.element.position(),t=this._isRootNode(this.scrollParent[0]);return{top:e.top-(parseInt(this.helper.css("top"),10)||0)+(t?0:this.scrollParent.scrollTop()),left:e.left-(parseInt(this.helper.css("left"),10)||0)+(t?0:this.scrollParent.scrollLeft())}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var t,n,i,o=this.options,r=this.document[0];this.relativeContainer=null,o.containment?"window"!==o.containment?"document"!==o.containment?o.containment.constructor!==Array?("parent"===o.containment&&(o.containment=this.helper[0].parentNode),(i=(n=e(o.containment))[0])&&(t=/(scroll|auto)/.test(n.css("overflow")),this.containment=[(parseInt(n.css("borderLeftWidth"),10)||0)+(parseInt(n.css("paddingLeft"),10)||0),(parseInt(n.css("borderTopWidth"),10)||0)+(parseInt(n.css("paddingTop"),10)||0),(t?Math.max(i.scrollWidth,i.offsetWidth):i.offsetWidth)-(parseInt(n.css("borderRightWidth"),10)||0)-(parseInt(n.css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(t?Math.max(i.scrollHeight,i.offsetHeight):i.offsetHeight)-(parseInt(n.css("borderBottomWidth"),10)||0)-(parseInt(n.css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relativeContainer=n)):this.containment=o.containment:this.containment=[0,0,e(r).width()-this.helperProportions.width-this.margins.left,(e(r).height()||r.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]:this.containment=[e(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,e(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,e(window).scrollLeft()+e(window).width()-this.helperProportions.width-this.margins.left,e(window).scrollTop()+(e(window).height()||r.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]:this.containment=null},_convertPositionTo:function(e,t){t||(t=this.position);var n="absolute"===e?1:-1,i=this._isRootNode(this.scrollParent[0]);return{top:t.top+this.offset.relative.top*n+this.offset.parent.top*n-("fixed"===this.cssPosition?-this.offset.scroll.top:i?0:this.offset.scroll.top)*n,left:t.left+this.offset.relative.left*n+this.offset.parent.left*n-("fixed"===this.cssPosition?-this.offset.scroll.left:i?0:this.offset.scroll.left)*n}},_generatePosition:function(e,t){var n,i,o,r,s=this.options,a=this._isRootNode(this.scrollParent[0]),l=e.pageX,u=e.pageY;return a&&this.offset.scroll||(this.offset.scroll={top:this.scrollParent.scrollTop(),left:this.scrollParent.scrollLeft()}),t&&(this.containment&&(this.relativeContainer?(i=this.relativeContainer.offset(),n=[this.containment[0]+i.left,this.containment[1]+i.top,this.containment[2]+i.left,this.containment[3]+i.top]):n=this.containment,e.pageX-this.offset.click.leftn[2]&&(l=n[2]+this.offset.click.left),e.pageY-this.offset.click.top>n[3]&&(u=n[3]+this.offset.click.top)),s.grid&&(o=s.grid[1]?this.originalPageY+Math.round((u-this.originalPageY)/s.grid[1])*s.grid[1]:this.originalPageY,u=n?o-this.offset.click.top>=n[1]||o-this.offset.click.top>n[3]?o:o-this.offset.click.top>=n[1]?o-s.grid[1]:o+s.grid[1]:o,r=s.grid[0]?this.originalPageX+Math.round((l-this.originalPageX)/s.grid[0])*s.grid[0]:this.originalPageX,l=n?r-this.offset.click.left>=n[0]||r-this.offset.click.left>n[2]?r:r-this.offset.click.left>=n[0]?r-s.grid[0]:r+s.grid[0]:r),"y"===s.axis&&(l=this.originalPageX),"x"===s.axis&&(u=this.originalPageY)),{top:u-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.offset.scroll.top:a?0:this.offset.scroll.top),left:l-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.offset.scroll.left:a?0:this.offset.scroll.left)}},_clear:function(){this.helper.removeClass("ui-draggable-dragging"),this.helper[0]===this.element[0]||this.cancelHelperRemoval||this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1,this.destroyOnClear&&this.destroy()},_normalizeRightBottom:function(){"y"!==this.options.axis&&"auto"!==this.helper.css("right")&&(this.helper.width(this.helper.width()),this.helper.css("right","auto")),"x"!==this.options.axis&&"auto"!==this.helper.css("bottom")&&(this.helper.height(this.helper.height()),this.helper.css("bottom","auto"))},_trigger:function(t,n,i){return i=i||this._uiHash(),e.ui.plugin.call(this,t,[n,i,this],!0),/^(drag|start|stop)/.test(t)&&(this.positionAbs=this._convertPositionTo("absolute"),i.offset=this.positionAbs),e.Widget.prototype._trigger.call(this,t,n,i)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),e.ui.plugin.add("draggable","connectToSortable",{start:function(t,n,i){var o=e.extend({},n,{item:i.element});i.sortables=[],e(i.options.connectToSortable).each(function(){var n=e(this).sortable("instance");n&&!n.options.disabled&&(i.sortables.push(n),n.refreshPositions(),n._trigger("activate",t,o))})},stop:function(t,n,i){var o=e.extend({},n,{item:i.element});i.cancelHelperRemoval=!1,e.each(i.sortables,function(){var e=this;e.isOver?(e.isOver=0,i.cancelHelperRemoval=!0,e.cancelHelperRemoval=!1,e._storedCSS={position:e.placeholder.css("position"),top:e.placeholder.css("top"),left:e.placeholder.css("left")},e._mouseStop(t),e.options.helper=e.options._helper):(e.cancelHelperRemoval=!0,e._trigger("deactivate",t,o))})},drag:function(t,n,i){e.each(i.sortables,function(){var o=!1,r=this;r.positionAbs=i.positionAbs,r.helperProportions=i.helperProportions,r.offset.click=i.offset.click,r._intersectsWith(r.containerCache)&&(o=!0,e.each(i.sortables,function(){return this.positionAbs=i.positionAbs,this.helperProportions=i.helperProportions,this.offset.click=i.offset.click,this!==r&&this._intersectsWith(this.containerCache)&&e.contains(r.element[0],this.element[0])&&(o=!1),o})),o?(r.isOver||(r.isOver=1,i._parent=n.helper.parent(),r.currentItem=n.helper.appendTo(r.element).data("ui-sortable-item",!0),r.options._helper=r.options.helper,r.options.helper=function(){return n.helper[0]},t.target=r.currentItem[0],r._mouseCapture(t,!0),r._mouseStart(t,!0,!0),r.offset.click.top=i.offset.click.top,r.offset.click.left=i.offset.click.left,r.offset.parent.left-=i.offset.parent.left-r.offset.parent.left,r.offset.parent.top-=i.offset.parent.top-r.offset.parent.top,i._trigger("toSortable",t),i.dropped=r.element,e.each(i.sortables,function(){this.refreshPositions()}),i.currentItem=i.element,r.fromOutside=i),r.currentItem&&(r._mouseDrag(t),n.position=r.position)):r.isOver&&(r.isOver=0,r.cancelHelperRemoval=!0,r.options._revert=r.options.revert,r.options.revert=!1,r._trigger("out",t,r._uiHash(r)),r._mouseStop(t,!0),r.options.revert=r.options._revert,r.options.helper=r.options._helper,r.placeholder&&r.placeholder.remove(),n.helper.appendTo(i._parent),i._refreshOffsets(t),n.position=i._generatePosition(t,!0),i._trigger("fromSortable",t),i.dropped=!1,e.each(i.sortables,function(){this.refreshPositions()}))})}}),e.ui.plugin.add("draggable","cursor",{start:function(t,n,i){var o=e("body"),r=i.options;o.css("cursor")&&(r._cursor=o.css("cursor")),o.css("cursor",r.cursor)},stop:function(t,n,i){var o=i.options;o._cursor&&e("body").css("cursor",o._cursor)}}),e.ui.plugin.add("draggable","opacity",{start:function(t,n,i){var o=e(n.helper),r=i.options;o.css("opacity")&&(r._opacity=o.css("opacity")),o.css("opacity",r.opacity)},stop:function(t,n,i){var o=i.options;o._opacity&&e(n.helper).css("opacity",o._opacity)}}),e.ui.plugin.add("draggable","scroll",{start:function(e,t,n){n.scrollParentNotHidden||(n.scrollParentNotHidden=n.helper.scrollParent(!1)),n.scrollParentNotHidden[0]!==n.document[0]&&"HTML"!==n.scrollParentNotHidden[0].tagName&&(n.overflowOffset=n.scrollParentNotHidden.offset())},drag:function(t,n,i){var o=i.options,r=!1,s=i.scrollParentNotHidden[0],a=i.document[0];s!==a&&"HTML"!==s.tagName?(o.axis&&"x"===o.axis||(i.overflowOffset.top+s.offsetHeight-t.pageY=0;p--)u=(l=i.snapElements[p].left-i.margins.left)+i.snapElements[p].width,f=(c=i.snapElements[p].top-i.margins.top)+i.snapElements[p].height,vu+g||bf+g||!e.contains(i.snapElements[p].item.ownerDocument,i.snapElements[p].item)?(i.snapElements[p].snapping&&i.options.snap.release&&i.options.snap.release.call(i.element,t,e.extend(i._uiHash(),{snapItem:i.snapElements[p].item})),i.snapElements[p].snapping=!1):("inner"!==h.snapMode&&(o=Math.abs(c-b)<=g,r=Math.abs(f-y)<=g,s=Math.abs(l-v)<=g,a=Math.abs(u-m)<=g,o&&(n.position.top=i._convertPositionTo("relative",{top:c-i.helperProportions.height,left:0}).top),r&&(n.position.top=i._convertPositionTo("relative",{top:f,left:0}).top),s&&(n.position.left=i._convertPositionTo("relative",{top:0,left:l-i.helperProportions.width}).left),a&&(n.position.left=i._convertPositionTo("relative",{top:0,left:u}).left)),d=o||r||s||a,"outer"!==h.snapMode&&(o=Math.abs(c-y)<=g,r=Math.abs(f-b)<=g,s=Math.abs(l-m)<=g,a=Math.abs(u-v)<=g,o&&(n.position.top=i._convertPositionTo("relative",{top:c,left:0}).top),r&&(n.position.top=i._convertPositionTo("relative",{top:f-i.helperProportions.height,left:0}).top),s&&(n.position.left=i._convertPositionTo("relative",{top:0,left:l}).left),a&&(n.position.left=i._convertPositionTo("relative",{top:0,left:u-i.helperProportions.width}).left)),!i.snapElements[p].snapping&&(o||r||s||a||d)&&i.options.snap.snap&&i.options.snap.snap.call(i.element,t,e.extend(i._uiHash(),{snapItem:i.snapElements[p].item})),i.snapElements[p].snapping=o||r||s||a||d)}}),e.ui.plugin.add("draggable","stack",{start:function(t,n,i){var o,r=i.options,s=e.makeArray(e(r.stack)).sort(function(t,n){return(parseInt(e(t).css("zIndex"),10)||0)-(parseInt(e(n).css("zIndex"),10)||0)});s.length&&(o=parseInt(e(s[0]).css("zIndex"),10)||0,e(s).each(function(t){e(this).css("zIndex",o+t)}),this.css("zIndex",o+s.length))}}),e.ui.plugin.add("draggable","zIndex",{start:function(t,n,i){var o=e(n.helper),r=i.options;o.css("zIndex")&&(r._zIndex=o.css("zIndex")),o.css("zIndex",r.zIndex)},stop:function(t,n,i){var o=i.options;o._zIndex&&e(n.helper).css("zIndex",o._zIndex)}});e.ui.draggable;var s=e;e.effects={effect:{}},function(e,t){function n(e,t,n){var i=c[t.type]||{};return null==e?n||!t.def?null:t.def:(e=i.floor?~~e:parseFloat(e),isNaN(e)?t.def:i.mod?(e+i.mod)%i.mod:0>e?0:i.max")[0],d=e.each;p.style.cssText="background-color:rgba(1,1,1,.5)",f.rgba=p.style.backgroundColor.indexOf("rgba")>-1,d(u,function(e,t){t.cache="_"+e,t.props.alpha={idx:3,type:"percent",def:1}}),l.fn=e.extend(l.prototype,{parse:function(t,o,s,a){if(void 0===t)return this._rgba=[null,null,null,null],this;(t.jquery||t.nodeType)&&(t=e(t).css(o),o=void 0);var c=this,f=e.type(t),p=this._rgba=[];return void 0!==o&&(t=[t,o,s,a],f="array"),"string"===f?this.parse(i(t)||r._default):"array"===f?(d(u.rgba.props,function(e,i){p[i.idx]=n(t[i.idx],i)}),this):"object"===f?(t instanceof l?d(u,function(e,n){t[n.cache]&&(c[n.cache]=t[n.cache].slice())}):d(u,function(i,o){var r=o.cache;d(o.props,function(e,i){if(!c[r]&&o.to){if("alpha"===e||null==t[e])return;c[r]=o.to(c._rgba)}c[r][i.idx]=n(t[e],i,!0)}),c[r]&&e.inArray(null,c[r].slice(0,3))<0&&(c[r][3]=1,o.from&&(c._rgba=o.from(c[r])))}),this):void 0},is:function(e){var t=l(e),n=!0,i=this;return d(u,function(e,o){var r,s=t[o.cache];return s&&(r=i[o.cache]||o.to&&o.to(i._rgba)||[],d(o.props,function(e,t){if(null!=s[t.idx])return n=s[t.idx]===r[t.idx]})),n}),n},_space:function(){var e=[],t=this;return d(u,function(n,i){t[i.cache]&&e.push(n)}),e.pop()},transition:function(e,t){var i=l(e),o=i._space(),r=u[o],s=0===this.alpha()?l("transparent"):this,a=s[r.cache]||r.to(s._rgba),f=a.slice();return i=i[r.cache],d(r.props,function(e,o){var r=o.idx,s=a[r],l=i[r],u=c[o.type]||{};null!==l&&(null===s?f[r]=l:(u.mod&&(l-s>u.mod/2?s+=u.mod:s-l>u.mod/2&&(s-=u.mod)),f[r]=n((l-s)*t+s,o)))}),this[o](f)},blend:function(t){if(1===this._rgba[3])return this;var n=this._rgba.slice(),i=n.pop(),o=l(t)._rgba;return l(e.map(n,function(e,t){return(1-i)*o[t]+i*e}))},toRgbaString:function(){var t="rgba(",n=e.map(this._rgba,function(e,t){return null==e?t>2?1:0:e});return 1===n[3]&&(n.pop(),t="rgb("),t+n.join()+")"},toHslaString:function(){var t="hsla(",n=e.map(this.hsla(),function(e,t){return null==e&&(e=t>2?1:0),t&&t<3&&(e=Math.round(100*e)+"%"),e});return 1===n[3]&&(n.pop(),t="hsl("),t+n.join()+")"},toHexString:function(t){var n=this._rgba.slice(),i=n.pop();return t&&n.push(~~(255*i)),"#"+e.map(n,function(e){return 1===(e=(e||0).toString(16)).length?"0"+e:e}).join("")},toString:function(){return 0===this._rgba[3]?"transparent":this.toRgbaString()}}),l.fn.parse.prototype=l.fn,u.hsla.to=function(e){if(null==e[0]||null==e[1]||null==e[2])return[null,null,null,e[3]];var t,n,i=e[0]/255,o=e[1]/255,r=e[2]/255,s=e[3],a=Math.max(i,o,r),l=Math.min(i,o,r),u=a-l,c=a+l,f=.5*c;return t=l===a?0:i===a?60*(o-r)/u+360:o===a?60*(r-i)/u+120:60*(i-o)/u+240,n=0===u?0:f<=.5?u/c:u/(2-c),[Math.round(t)%360,n,f,null==s?1:s]},u.hsla.from=function(e){if(null==e[0]||null==e[1]||null==e[2])return[null,null,null,e[3]];var t=e[0]/360,n=e[1],i=e[2],r=e[3],s=i<=.5?i*(1+n):i+n-i*n,a=2*i-s;return[Math.round(255*o(a,s,t+1/3)),Math.round(255*o(a,s,t)),Math.round(255*o(a,s,t-1/3)),r]},d(u,function(t,i){var o=i.props,r=i.cache,a=i.to,u=i.from;l.fn[t]=function(t){if(a&&!this[r]&&(this[r]=a(this._rgba)),void 0===t)return this[r].slice();var i,s=e.type(t),c="array"===s||"object"===s?t:arguments,f=this[r].slice();return d(o,function(e,t){var i=c["object"===s?e:t.idx];null==i&&(i=f[t.idx]),f[t.idx]=n(i,t)}),u?(i=l(u(f)),i[r]=f,i):l(f)},d(o,function(n,i){l.fn[n]||(l.fn[n]=function(o){var r,a=e.type(o),l="alpha"===n?this._hsla?"hsla":"rgba":t,u=this[l](),c=u[i.idx];return"undefined"===a?c:("function"===a&&(o=o.call(this,c),a=e.type(o)),null==o&&i.empty?this:("string"===a&&(r=s.exec(o))&&(o=c+parseFloat(r[2])*("+"===r[1]?1:-1)),u[i.idx]=o,this[l](u)))})})}),l.hook=function(t){var n=t.split(" ");d(n,function(t,n){e.cssHooks[n]={set:function(t,o){var r,s,a="";if("transparent"!==o&&("string"!==e.type(o)||(r=i(o)))){if(o=l(r||o),!f.rgba&&1!==o._rgba[3]){for(s="backgroundColor"===n?t.parentNode:t;(""===a||"transparent"===a)&&s&&s.style;)try{a=e.css(s,"backgroundColor"),s=s.parentNode}catch(e){}o=o.blend(a&&"transparent"!==a?a:"_default")}o=o.toRgbaString()}try{t.style[n]=o}catch(e){}}},e.fx.step[n]=function(t){t.colorInit||(t.start=l(t.elem,n),t.end=l(t.end),t.colorInit=!0),e.cssHooks[n].set(t.elem,t.start.transition(t.end,t.pos))}})},l.hook("backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor"),e.cssHooks.borderColor={expand:function(e){var t={};return d(["Top","Right","Bottom","Left"],function(n,i){t["border"+i+"Color"]=e}),t}},r=e.Color.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff"}}(s),function(){function t(t){var n,i,o=t.ownerDocument.defaultView?t.ownerDocument.defaultView.getComputedStyle(t,null):t.currentStyle,r={};if(o&&o.length&&o[0]&&o[o[0]])for(i=o.length;i--;)"string"==typeof o[n=o[i]]&&(r[e.camelCase(n)]=o[n]);else for(n in o)"string"==typeof o[n]&&(r[n]=o[n]);return r}function n(t,n){var i,r,s={};for(i in n)r=n[i],t[i]!==r&&(o[i]||!e.fx.step[i]&&isNaN(parseFloat(r))||(s[i]=r));return s}var i=["add","remove","toggle"],o={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};e.each(["borderLeftStyle","borderRightStyle","borderBottomStyle","borderTopStyle"],function(t,n){e.fx.step[n]=function(e){("none"!==e.end&&!e.setAttr||1===e.pos&&!e.setAttr)&&(s.style(e.elem,n,e.end),e.setAttr=!0)}}),e.fn.addBack||(e.fn.addBack=function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}),e.effects.animateClass=function(o,r,s,a){var l=e.speed(r,s,a);return this.queue(function(){var r,s=e(this),a=s.attr("class")||"",u=l.children?s.find("*").addBack():s;u=u.map(function(){return{el:e(this),start:t(this)}}),(r=function(){e.each(i,function(e,t){o[t]&&s[t+"Class"](o[t])})})(),u=u.map(function(){return this.end=t(this.el[0]),this.diff=n(this.start,this.end),this}),s.attr("class",a),u=u.map(function(){var t=this,n=e.Deferred(),i=e.extend({},l,{queue:!1,complete:function(){n.resolve(t)}});return this.el.animate(this.diff,i),n.promise()}),e.when.apply(e,u.get()).done(function(){r(),e.each(arguments,function(){var t=this.el;e.each(this.diff,function(e){t.css(e,"")})}),l.complete.call(s[0])})})},e.fn.extend({addClass:function(t){return function(n,i,o,r){return i?e.effects.animateClass.call(this,{add:n},i,o,r):t.apply(this,arguments)}}(e.fn.addClass),removeClass:function(t){return function(n,i,o,r){return arguments.length>1?e.effects.animateClass.call(this,{remove:n},i,o,r):t.apply(this,arguments)}}(e.fn.removeClass),toggleClass:function(t){return function(n,i,o,r,s){return"boolean"==typeof i||void 0===i?o?e.effects.animateClass.call(this,i?{add:n}:{remove:n},o,r,s):t.apply(this,arguments):e.effects.animateClass.call(this,{toggle:n},i,o,r)}}(e.fn.toggleClass),switchClass:function(t,n,i,o,r){return e.effects.animateClass.call(this,{add:n,remove:t},i,o,r)}})}(),function(){function t(t,n,i,o){return e.isPlainObject(t)&&(n=t,t=t.effect),t={effect:t},null==n&&(n={}),e.isFunction(n)&&(o=n,i=null,n={}),("number"==typeof n||e.fx.speeds[n])&&(o=i,i=n,n={}),e.isFunction(i)&&(o=i,i=null),n&&e.extend(t,n),i=i||n.duration,t.duration=e.fx.off?0:"number"==typeof i?i:i in e.fx.speeds?e.fx.speeds[i]:e.fx.speeds._default,t.complete=o||n.complete,t}function n(t){return!(t&&"number"!=typeof t&&!e.fx.speeds[t])||("string"==typeof t&&!e.effects.effect[t]||(!!e.isFunction(t)||"object"==typeof t&&!t.effect))}e.extend(e.effects,{version:"1.11.4",save:function(e,t){for(var n=0;n
").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),o={width:t.width(),height:t.height()},r=document.activeElement;try{r.id}catch(e){r=document.body}return t.wrap(i),(t[0]===r||e.contains(t[0],r))&&e(r).focus(),i=t.parent(),"static"===t.css("position")?(i.css({position:"relative"}),t.css({position:"relative"})):(e.extend(n,{position:t.css("position"),zIndex:t.css("z-index")}),e.each(["top","left","bottom","right"],function(e,i){n[i]=t.css(i),isNaN(parseInt(n[i],10))&&(n[i]="auto")}),t.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),t.css(o),i.css(n).show()},removeWrapper:function(t){var n=document.activeElement;return t.parent().is(".ui-effects-wrapper")&&(t.parent().replaceWith(t),(t[0]===n||e.contains(t[0],n))&&e(n).focus()),t},setTransition:function(t,n,i,o){return o=o||{},e.each(n,function(e,n){var r=t.cssUnit(n);r[0]>0&&(o[n]=r[0]*i+r[1])}),o}}),e.fn.extend({effect:function(){function n(t){function n(){e.isFunction(r)&&r.call(o[0]),e.isFunction(t)&&t()}var o=e(this),r=i.complete,a=i.mode;(o.is(":hidden")?"hide"===a:"show"===a)?(o[a](),n()):s.call(o[0],i,n)}var i=t.apply(this,arguments),o=i.mode,r=i.queue,s=e.effects.effect[i.effect];return e.fx.off||!s?o?this[o](i.duration,i.complete):this.each(function(){i.complete&&i.complete.call(this)}):!1===r?this.each(n):this.queue(r||"fx",n)},show:function(e){return function(i){if(n(i))return e.apply(this,arguments);var o=t.apply(this,arguments);return o.mode="show",this.effect.call(this,o)}}(e.fn.show),hide:function(e){return function(i){if(n(i))return e.apply(this,arguments);var o=t.apply(this,arguments);return o.mode="hide",this.effect.call(this,o)}}(e.fn.hide),toggle:function(e){return function(i){if(n(i)||"boolean"==typeof i)return e.apply(this,arguments);var o=t.apply(this,arguments);return o.mode="toggle",this.effect.call(this,o)}}(e.fn.toggle),cssUnit:function(t){var n=this.css(t),i=[];return e.each(["em","px","%","pt"],function(e,t){n.indexOf(t)>0&&(i=[parseFloat(n),t])}),i}})}(),function(){var t={};e.each(["Quad","Cubic","Quart","Quint","Expo"],function(e,n){t[n]=function(t){return Math.pow(t,e+2)}}),e.extend(t,{Sine:function(e){return 1-Math.cos(e*Math.PI/2)},Circ:function(e){return 1-Math.sqrt(1-e*e)},Elastic:function(e){return 0===e||1===e?e:-Math.pow(2,8*(e-1))*Math.sin((80*(e-1)-7.5)*Math.PI/15)},Back:function(e){return e*e*(3*e-2)},Bounce:function(e){for(var t,n=4;e<((t=Math.pow(2,--n))-1)/11;);return 1/Math.pow(4,3-n)-7.5625*Math.pow((3*t-2)/22-e,2)}}),e.each(t,function(t,n){e.easing["easeIn"+t]=n,e.easing["easeOut"+t]=function(e){return 1-n(1-e)},e.easing["easeInOut"+t]=function(e){return e<.5?n(2*e)/2:1-n(-2*e+2)/2}})}();e.effects}),jQuery.fn.extend({everyTime:function(e,t,n,i){return this.each(function(){jQuery.timer.add(this,e,t,n,i)})},oneTime:function(e,t,n){return this.each(function(){jQuery.timer.add(this,e,t,n,1)})},stopTime:function(e,t){return this.each(function(){jQuery.timer.remove(this,e,t)})}}),jQuery.extend({timer:{global:[],guid:1,dataKey:"jQuery.timer",regex:/^([0-9]+(?:\.[0-9]*)?)\s*(.*s)?$/,powers:{ms:1,cs:10,ds:100,s:1e3,das:1e4,hs:1e5,ks:1e6},timeParse:function(e){if(void 0==e||null==e)return null;var t=this.regex.exec(jQuery.trim(e.toString()));return t[2]?parseFloat(t[1])*(this.powers[t[2]]||1):e},add:function(e,t,n,i,o){var r=0;if(jQuery.isFunction(n)&&(o||(o=i),i=n,n=t),!("number"!=typeof(t=jQuery.timer.timeParse(t))||isNaN(t)||t<0)){("number"!=typeof o||isNaN(o)||o<0)&&(o=0),o=o||0;var s=jQuery.data(e,this.dataKey)||jQuery.data(e,this.dataKey,{});s[n]||(s[n]={}),i.timerID=i.timerID||this.guid++;var a=function(){(++r>o&&0!==o||!1===i.call(e,r))&&jQuery.timer.remove(e,n,i)};a.timerID=i.timerID,s[n][i.timerID]||(s[n][i.timerID]=window.setInterval(a,t)),this.global.push(e)}},remove:function(e,t,n){var i,o=jQuery.data(e,this.dataKey);if(o){if(t){if(o[t]){if(n)n.timerID&&(window.clearInterval(o[t][n.timerID]),delete o[t][n.timerID]);else for(var n in o[t])window.clearInterval(o[t][n]),delete o[t][n];for(i in o[t])break;i||(i=null,delete o[t])}}else for(t in o)this.remove(e,t,n);for(i in o)break;i||jQuery.removeData(e,this.dataKey)}}}}),jQuery(window).bind("unload",function(){jQuery.each(jQuery.timer.global,function(e,t){jQuery.timer.remove(t)})}),function(){"use strict";function e(){var e={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"},t=/&(?!#?\w+;)|<|>|"|'|\//g;return function(){return this?this.replace(t,function(t){return e[t]||t}):this}}function t(e,n,i){return("string"==typeof n?n:n.toString()).replace(e.define||r,function(t,n,o,r){return 0===n.indexOf("def.")&&(n=n.substring(4)),n in i||(":"===o?(e.defineParams&&r.replace(e.defineParams,function(e,t,o){i[n]={arg:t,text:o}}),n in i||(i[n]=r)):new Function("def","def['"+n+"']="+r)(i)),""}).replace(e.use||r,function(n,o){e.useParams&&(o=o.replace(e.useParams,function(e,t,n,o){if(i[n]&&i[n].arg&&o){var r=(n+":"+o).replace(/'|\\/g,"_");return i.__exp=i.__exp||{},i.__exp[r]=i[n].text.replace(new RegExp("(^|[^\\w$])"+i[n].arg+"([^\\w$])","g"),"$1"+o+"$2"),t+"def.__exp['"+r+"']"}}));var r=new Function("def","return "+o)(i);return r?t(e,r,i):r})}function n(e){return e.replace(/\\('|\\)/g,"$1").replace(/[\r\t\n]/g," ")}var i={version:"1.0.1-nanoui",templateSettings:{evaluate:/\{\{([\s\S]+?)\}\}/g,interpolate:/\{\{:([\s\S]+?)\}\}/g,encode:/\{\{>([\s\S]+?)\}\}/g,use:/\{\{#([\s\S]+?)\}\}/g,define:/\{\{##\s*([\w\.$]+)\s*(\:|=)([\s\S]+?)#\}\}/g,conditional:/\{\{\/?if\s*([\s\S]*?)\s*\}\}/g,conditionalElse:/\{\{else\s*([\s\S]*?)\s*\}\}/g,iterate:/\{\{\/?for\s*(?:\}\}|([\s\S]+?)\s*(?:\:\s*([\w$]+))?\s*(?:\:\s*([\w$]+))?\s*\}\})/g,props:/\{\{\/?props\s*(?:\}\}|([\s\S]+?)\s*(?:\:\s*([\w$]+))?\s*(?:\:\s*([\w$]+))?\s*\}\})/g,empty:/\{\{empty\}\}/g,varname:"data, config, helper",strip:!0,append:!0,selfcontained:!1},template:void 0,compile:void 0};"undefined"!=typeof module&&module.exports?module.exports=i:"function"==typeof define&&define.amd?define(function(){return i}):(function(){return this||(0,eval)("this")}()).doT=i,String.prototype.encodeHTML=e();var o={append:{start:"'+(",end:")+'",endencode:"||'').toString().encodeHTML()+'"},split:{start:"';out+=(",end:");out+='",endencode:"||'').toString().encodeHTML();out+='"}},r=/$^/;i.template=function(s,a,l){var u,c=(a=a||i.templateSettings).append?o.append:o.split,f=0,p=a.use||a.define?t(a,s,l||{}):s;p=("var out='"+(a.strip?p.replace(/(^|\r|\n)\t* +| +\t*(\r|\n|$)/g," ").replace(/\r|\n|\t|\/\*[\s\S]*?\*\//g,""):p).replace(/'|\\/g,"\\$&").replace(a.interpolate||r,function(e,t){return c.start+n(t)+c.end}).replace(a.encode||r,function(e,t){return u=!0,c.start+n(t)+c.endencode}).replace(a.conditional||r,function(e,t){return t?"';if("+n(t)+"){out+='":"';}out+='"}).replace(a.conditionalElse||r,function(e,t){return t?"';}else if("+n(t)+"){out+='":"';}else{out+='"}).replace(a.iterate||r,function(e,t,i,o){if(!t)return"';} } out+='";f+=1,i=i||"value",o=o||"index",t=n(t);var r="arr"+f;return"';var "+r+"="+t+";if("+r+" && "+r+".length > 0){var "+i+","+o+"=-1,l"+f+"="+r+".length-1;while("+o+" 0){var "+i+";for( var "+o+" in "+r+"){ if (!"+r+".hasOwnProperty("+o+")) continue; "+i+"="+r+"["+o+"];out+='"}).replace(a.empty||r,function(e){return"';}}else{if(true){out+='"}).replace(a.evaluate||r,function(e,t){return"';"+n(t)+"out+='"})+"';return out;").replace(/\n/g,"\\n").replace(/\t/g,"\\t").replace(/\r/g,"\\r").replace(/(\s|;|\}|^|\{)out\+='';/g,"$1").replace(/\+''/g,"").replace(/(\s|;|\}|^|\{)out\+=''\+/g,"$1out+="),u&&a.selfcontained&&(p="String.prototype.encodeHTML=("+e.toString()+"());"+p);try{return new Function(a.varname,p)}catch(e){throw"undefined"!=typeof console&&console.log("Could not create a template function: "+p),e}},i.compile=function(e,t){return i.template(e,null,t)}}(),function(e){"use strict";function t(e){var t={path:!0,query:!0,hash:!0};return e?(/^[a-z]+:/.test(e)&&(t.protocol=!0,t.host=!0,/[-a-z0-9]+(\.[-a-z0-9])*:\d+/i.test(e)&&(t.port=!0),/\/\/(.*?)(?::(.*?))?@/.test(e)&&(t.user=!0,t.pass=!0)),t):t}function n(e,n,i){var f,p,d,h=a?"file://"+(process.platform.match(/^win/i)?"/":"")+l("fs").realpathSync("."):document.location.href;n||(n=h),a?f=l("url").parse(n):(f=document.createElement("a"),f.href=n);var g=t(n);d=n.match(/\/\/(.*?)(?::(.*?))?@/)||[];for(p in u)e[p]=g[p]?f[u[p]]||"":"";if(e.protocol=e.protocol.replace(/:$/,""),e.query=e.query.replace(/^\?/,""),e.hash=o(e.hash.replace(/^#/,"")),e.user=o(d[1]||""),e.pass=o(d[2]||""),e.port=c[e.protocol]==e.port||0==e.port?"":e.port,!g.protocol&&/[^\/#?]/.test(n.charAt(0))&&(e.path=n.split("?")[0].split("#")[0]),!g.protocol&&i){var m=new s(h.match(/(.*\/)/)[0]),v=m.path.split("/"),y=e.path.split("/"),b=["protocol","user","pass","host","port"],x=b.length;for(v.pop(),p=0;x>p;p++)e[b[p]]=m[b[p]];for(;".."===y[0];)v.pop(),y.shift();e.path=("/"!==n.charAt(0)?v.join("/"):"")+"/"+y.join("/")}e.path=e.path.replace(/^\/{2,}/,"/"),e.paths(("/"===e.path.charAt(0)?e.path.slice(1):e.path).split("/")),e.query=new r(e.query)}function i(e){return encodeURIComponent(e).replace(/'/g,"%27")}function o(e){return e=e.replace(/\+/g," "),e=e.replace(/%([ef][0-9a-f])%([89ab][0-9a-f])%([89ab][0-9a-f])/gi,function(e,t,n,i){var o=parseInt(t,16)-224,r=parseInt(n,16)-128;if(0===o&&32>r)return e;var s=(o<<12)+(r<<6)+(parseInt(i,16)-128);return s>65535?e:String.fromCharCode(s)}),(e=e.replace(/%([cd][0-9a-f])%([89ab][0-9a-f])/gi,function(e,t,n){var i=parseInt(t,16)-192;if(2>i)return e;var o=parseInt(n,16)-128;return String.fromCharCode((i<<6)+o)})).replace(/%([0-7][0-9a-f])/gi,function(e,t){return String.fromCharCode(parseInt(t,16))})}function r(e){for(var t,n=/([^=&]+)(=([^&]*))?/g;t=n.exec(e);){var i=decodeURIComponent(t[1].replace(/\+/g," ")),r=t[3]?o(t[3]):"";void 0!==this[i]&&null!==this[i]?(this[i]instanceof Array||(this[i]=[this[i]]),this[i].push(r)):this[i]=r}}function s(e,t){n(this,e,!t)}var a="undefined"==typeof window&&"undefined"!=typeof global&&"function"==typeof require,l=a?e.require:null,u={protocol:"protocol",host:"hostname",port:"port",path:"pathname",query:"search",hash:"hash"},c={ftp:21,gopher:70,http:80,https:443,ws:80,wss:443};r.prototype.toString=function(){var e,t,n="",o=i;for(e in this)if(!(this[e]instanceof Function||null===this[e]))if(this[e]instanceof Array){var r=this[e].length;if(r)for(t=0;r>t;t++)n+=n?"&":"",n+=o(e)+"="+o(this[e][t]);else n+=(n?"&":"")+o(e)+"="}else n+=n?"&":"",n+=o(e)+"="+o(this[e]);return n},s.prototype.clearQuery=function(){for(var e in this.query)this.query[e]instanceof Function||delete this.query[e];return this},s.prototype.queryLength=function(){var e,t=0;for(e in this)this[e]instanceof Function||t++;return t},s.prototype.isEmptyQuery=function(){return 0===this.queryLength()},s.prototype.paths=function(e){var t,n="",r=0;if(e&&e.length&&e+""!==e){for(this.isAbsolute()&&(n="/"),t=e.length;t>r;r++)e[r]=!r&&e[r].match(/^\w:$/)?e[r]:i(e[r]);this.path=n+e.join("/")}for(r=0,t=(e=("/"===this.path.charAt(0)?this.path.slice(1):this.path).split("/")).length;t>r;r++)e[r]=o(e[r]);return e},s.prototype.encode=i,s.prototype.decode=o,s.prototype.isAbsolute=function(){return this.protocol||"/"===this.path.charAt(0)},s.prototype.toString=function(){return(this.protocol&&this.protocol+"://")+(this.user&&i(this.user)+(this.pass&&":"+i(this.pass))+"@")+(this.host&&this.host)+(this.port&&":"+this.port)+(this.path&&this.path)+(this.query.toString()&&"?"+this.query)+(this.hash&&"#"+i(this.hash))},e[e.exports?"exports":"Url"]=s}("undefined"!=typeof module&&module.exports?module:window); \ No newline at end of file +/*! + * jQuery JavaScript Library v1.11.3 + * http://jquery.com/ + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * + * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2015-04-28T16:19Z + */ + +(function( global, factory ) { + + if ( typeof module === "object" && typeof module.exports === "object" ) { + // For CommonJS and CommonJS-like environments where a proper window is present, + // execute the factory and get jQuery + // For environments that do not inherently posses a window with a document + // (such as Node.js), expose a jQuery-making factory as module.exports + // This accentuates the need for the creation of a real window + // e.g. var jQuery = require("jquery")(window); + // See ticket #14549 for more info + module.exports = global.document ? + factory( global, true ) : + function( w ) { + if ( !w.document ) { + throw new Error( "jQuery requires a window with a document" ); + } + return factory( w ); + }; + } else { + factory( global ); + } + +// Pass this if window is not defined yet +}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) { + +// Can't do this because several apps including ASP.NET trace +// the stack via arguments.caller.callee and Firefox dies if +// you try to trace through "use strict" call chains. (#13335) +// Support: Firefox 18+ +// + +var deletedIds = []; + +var slice = deletedIds.slice; + +var concat = deletedIds.concat; + +var push = deletedIds.push; + +var indexOf = deletedIds.indexOf; + +var class2type = {}; + +var toString = class2type.toString; + +var hasOwn = class2type.hasOwnProperty; + +var support = {}; + + + +var + version = "1.11.3", + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }, + + // Support: Android<4.1, IE<9 + // Make sure we trim BOM and NBSP + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, + + // Matches dashed string for camelizing + rmsPrefix = /^-ms-/, + rdashAlpha = /-([\da-z])/gi, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return letter.toUpperCase(); + }; + +jQuery.fn = jQuery.prototype = { + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // Start with an empty selector + selector: "", + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num != null ? + + // Return just the one element from the set + ( num < 0 ? this[ num + this.length ] : this[ num ] ) : + + // Return all the elements in a clean array + slice.call( this ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + ret.context = this.context; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function( elem, i ) { + return callback.call( elem, i, elem ); + })); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] ); + }, + + end: function() { + return this.prevObject || this.constructor(null); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: deletedIds.sort, + splice: deletedIds.splice +}; + +jQuery.extend = jQuery.fn.extend = function() { + var src, copyIsArray, copy, name, options, clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction(target) ) { + target = {}; + } + + // extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) { + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray(src) ? src : []; + + } else { + clone = src && jQuery.isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend({ + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), + + // Assume jQuery is ready without the ready module + isReady: true, + + error: function( msg ) { + throw new Error( msg ); + }, + + noop: function() {}, + + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return jQuery.type(obj) === "function"; + }, + + isArray: Array.isArray || function( obj ) { + return jQuery.type(obj) === "array"; + }, + + isWindow: function( obj ) { + /* jshint eqeqeq: false */ + return obj != null && obj == obj.window; + }, + + isNumeric: function( obj ) { + // parseFloat NaNs numeric-cast false positives (null|true|false|"") + // ...but misinterprets leading-number strings, particularly hex literals ("0x...") + // subtraction forces infinities to NaN + // adding 1 corrects loss of precision from parseFloat (#15100) + return !jQuery.isArray( obj ) && (obj - parseFloat( obj ) + 1) >= 0; + }, + + isEmptyObject: function( obj ) { + var name; + for ( name in obj ) { + return false; + } + return true; + }, + + isPlainObject: function( obj ) { + var key; + + // Must be an Object. + // Because of IE, we also have to check the presence of the constructor property. + // Make sure that DOM nodes and window objects don't pass through, as well + if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + try { + // Not own constructor property must be Object + if ( obj.constructor && + !hasOwn.call(obj, "constructor") && + !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { + return false; + } + } catch ( e ) { + // IE8,9 Will throw exceptions on certain host objects #9897 + return false; + } + + // Support: IE<9 + // Handle iteration over inherited properties before own properties. + if ( support.ownLast ) { + for ( key in obj ) { + return hasOwn.call( obj, key ); + } + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + for ( key in obj ) {} + + return key === undefined || hasOwn.call( obj, key ); + }, + + type: function( obj ) { + if ( obj == null ) { + return obj + ""; + } + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call(obj) ] || "object" : + typeof obj; + }, + + // Evaluates a script in a global context + // Workarounds based on findings by Jim Driscoll + // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context + globalEval: function( data ) { + if ( data && jQuery.trim( data ) ) { + // We use execScript on Internet Explorer + // We use an anonymous function so that context is window + // rather than jQuery in Firefox + ( window.execScript || function( data ) { + window[ "eval" ].call( window, data ); + } )( data ); + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + }, + + // args is for internal usage only + each: function( obj, callback, args ) { + var value, + i = 0, + length = obj.length, + isArray = isArraylike( obj ); + + if ( args ) { + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback.apply( obj[ i ], args ); + + if ( value === false ) { + break; + } + } + } else { + for ( i in obj ) { + value = callback.apply( obj[ i ], args ); + + if ( value === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback.call( obj[ i ], i, obj[ i ] ); + + if ( value === false ) { + break; + } + } + } else { + for ( i in obj ) { + value = callback.call( obj[ i ], i, obj[ i ] ); + + if ( value === false ) { + break; + } + } + } + } + + return obj; + }, + + // Support: Android<4.1, IE<9 + trim: function( text ) { + return text == null ? + "" : + ( text + "" ).replace( rtrim, "" ); + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArraylike( Object(arr) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + var len; + + if ( arr ) { + if ( indexOf ) { + return indexOf.call( arr, elem, i ); + } + + len = arr.length; + i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; + + for ( ; i < len; i++ ) { + // Skip accessing in sparse arrays + if ( i in arr && arr[ i ] === elem ) { + return i; + } + } + } + + return -1; + }, + + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; + + while ( j < len ) { + first[ i++ ] = second[ j++ ]; + } + + // Support: IE<9 + // Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists) + if ( len !== len ) { + while ( second[j] !== undefined ) { + first[ i++ ] = second[ j++ ]; + } + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var value, + i = 0, + length = elems.length, + isArray = isArraylike( elems ), + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + var args, proxy, tmp; + + if ( typeof context === "string" ) { + tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + args = slice.call( arguments, 2 ); + proxy = function() { + return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || jQuery.guid++; + + return proxy; + }, + + now: function() { + return +( new Date() ); + }, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support +}); + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +function isArraylike( obj ) { + + // Support: iOS 8.2 (not reproducible in simulator) + // `in` check used to prevent JIT error (gh-2145) + // hasOwn isn't used here due to false negatives + // regarding Nodelist length in IE + var length = "length" in obj && obj.length, + type = jQuery.type( obj ); + + if ( type === "function" || jQuery.isWindow( obj ) ) { + return false; + } + + if ( obj.nodeType === 1 && length ) { + return true; + } + + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; +} +var Sizzle = +/*! + * Sizzle CSS Selector Engine v2.2.0-pre + * http://sizzlejs.com/ + * + * Copyright 2008, 2014 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2014-12-16 + */ +(function( window ) { + +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + 1 * new Date(), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // General-purpose constants + MAX_NEGATIVE = 1 << 31, + + // Instance methods + hasOwn = ({}).hasOwnProperty, + arr = [], + pop = arr.pop, + push_native = arr.push, + push = arr.push, + slice = arr.slice, + // Use a stripped-down indexOf as it's faster than native + // http://jsperf.com/thor-indexof-vs-for/5 + indexOf = function( list, elem ) { + var i = 0, + len = list.length; + for ( ; i < len; i++ ) { + if ( list[i] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + // http://www.w3.org/TR/css3-syntax/#characters + characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", + + // Loosely modeled on CSS identifier characters + // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors + // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = characterEncoding.replace( "w", "w#" ), + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + + "*\\]", + + pseudos = ":(" + characterEncoding + ")(?:\\((" + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rwhitespace = new RegExp( whitespace + "+", "g" ), + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), + + rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + characterEncoding + ")" ), + "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), + "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + rescape = /'|\\/g, + + // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), + funescape = function( _, escaped, escapedWhitespace ) { + var high = "0x" + escaped - 0x10000; + // NaN means non-codepoint + // Support: Firefox<24 + // Workaround erroneous numeric interpretation of +"0x" + return high !== high || escapedWhitespace ? + escaped : + high < 0 ? + // BMP codepoint + String.fromCharCode( high + 0x10000 ) : + // Supplemental Plane codepoint (surrogate pair) + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }, + + // Used for iframes + // See setDocument() + // Removing the function wrapper causes a "Permission Denied" + // error in IE + unloadHandler = function() { + setDocument(); + }; + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + (arr = slice.call( preferredDoc.childNodes )), + preferredDoc.childNodes + ); + // Support: Android<4.0 + // Detect silently failing push.apply + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + push_native.apply( target, slice.call(els) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + // Can't trust NodeList.length + while ( (target[j++] = els[i++]) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var match, elem, m, nodeType, + // QSA vars + i, groups, old, nid, newContext, newSelector; + + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { + setDocument( context ); + } + + context = context || document; + results = results || []; + nodeType = context.nodeType; + + if ( typeof selector !== "string" || !selector || + nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { + + return results; + } + + if ( !seed && documentIsHTML ) { + + // Try to shortcut find operations when possible (e.g., not under DocumentFragment) + if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { + // Speed-up: Sizzle("#ID") + if ( (m = match[1]) ) { + if ( nodeType === 9 ) { + elem = context.getElementById( m ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document (jQuery #6963) + if ( elem && elem.parentNode ) { + // Handle the case where IE, Opera, and Webkit return items + // by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + } else { + // Context is not a document + if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && + contains( context, elem ) && elem.id === m ) { + results.push( elem ); + return results; + } + } + + // Speed-up: Sizzle("TAG") + } else if ( match[2] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Speed-up: Sizzle(".CLASS") + } else if ( (m = match[3]) && support.getElementsByClassName ) { + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // QSA path + if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { + nid = old = expando; + newContext = context; + newSelector = nodeType !== 1 && selector; + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + groups = tokenize( selector ); + + if ( (old = context.getAttribute("id")) ) { + nid = old.replace( rescape, "\\$&" ); + } else { + context.setAttribute( "id", nid ); + } + nid = "[id='" + nid + "'] "; + + i = groups.length; + while ( i-- ) { + groups[i] = nid + toSelector( groups[i] ); + } + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context; + newSelector = groups.join(","); + } + + if ( newSelector ) { + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch(qsaError) { + } finally { + if ( !old ) { + context.removeAttribute("id"); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {Function(string, Object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return (cache[ key + " " ] = value); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created div and expects a boolean result + */ +function assert( fn ) { + var div = document.createElement("div"); + + try { + return !!fn( div ); + } catch (e) { + return false; + } finally { + // Remove from its parent by default + if ( div.parentNode ) { + div.parentNode.removeChild( div ); + } + // release memory in IE + div = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split("|"), + i = attrs.length; + + while ( i-- ) { + Expr.attrHandle[ arr[i] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + ( ~b.sourceIndex || MAX_NEGATIVE ) - + ( ~a.sourceIndex || MAX_NEGATIVE ); + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( (cur = cur.nextSibling) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); +} + +/** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ +function testContext( context ) { + return context && typeof context.getElementsByTagName !== "undefined" && context; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ +isXML = Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = elem && (elem.ownerDocument || elem).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, parent, + doc = node ? node.ownerDocument || node : preferredDoc; + + // If no document and documentElement is available, return + if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Set our document + document = doc; + docElem = doc.documentElement; + parent = doc.defaultView; + + // Support: IE>8 + // If iframe document is assigned to "document" variable and if iframe has been reloaded, + // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936 + // IE6-8 do not support the defaultView property so parent will be undefined + if ( parent && parent !== parent.top ) { + // IE11 does not have attachEvent, so all must suffer + if ( parent.addEventListener ) { + parent.addEventListener( "unload", unloadHandler, false ); + } else if ( parent.attachEvent ) { + parent.attachEvent( "onunload", unloadHandler ); + } + } + + /* Support tests + ---------------------------------------------------------------------- */ + documentIsHTML = !isXML( doc ); + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties + // (excepting IE8 booleans) + support.attributes = assert(function( div ) { + div.className = "i"; + return !div.getAttribute("className"); + }); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert(function( div ) { + div.appendChild( doc.createComment("") ); + return !div.getElementsByTagName("*").length; + }); + + // Support: IE<9 + support.getElementsByClassName = rnative.test( doc.getElementsByClassName ); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert(function( div ) { + docElem.appendChild( div ).id = expando; + return !doc.getElementsByName || !doc.getElementsByName( expando ).length; + }); + + // ID find and filter + if ( support.getById ) { + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var m = context.getElementById( id ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [ m ] : []; + } + }; + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute("id") === attrId; + }; + }; + } else { + // Support: IE6/7 + // getElementById is not reliable as a find shortcut + delete Expr.find["ID"]; + + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); + return node && node.value === attrId; + }; + }; + } + + // Tag + Expr.find["TAG"] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( tag ); + + // DocumentFragment nodes don't have gEBTN + } else if ( support.qsa ) { + return context.querySelectorAll( tag ); + } + } : + + function( tag, context ) { + var elem, + tmp = [], + i = 0, + // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( (elem = results[i++]) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { + if ( documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See http://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) { + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( div ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // http://bugs.jquery.com/ticket/12359 + docElem.appendChild( div ).innerHTML = "
" + + ""; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if ( div.querySelectorAll("[msallowcapture^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !div.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Support: Chrome<29, Android<4.2+, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.7+ + if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) { + rbuggyQSA.push("~="); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + + // Support: Safari 8+, iOS 8+ + // https://bugs.webkit.org/show_bug.cgi?id=136851 + // In-page `selector#id sibing-combinator selector` fails + if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) { + rbuggyQSA.push(".#.+[+~]"); + } + }); + + assert(function( div ) { + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = doc.createElement("input"); + input.setAttribute( "type", "hidden" ); + div.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( div.querySelectorAll("[name=d]").length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":enabled").length ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Opera 10-11 does not throw on post-comma invalid pseudos + div.querySelectorAll("*,:x"); + rbuggyQSA.push(",.*:"); + }); + } + + if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector) )) ) { + + assert(function( div ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( div, "div" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( div, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + }); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully does not implement inclusive descendent + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + )); + } : + function( a, b ) { + if ( b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // Calculate position if both inputs belong to the same document + compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { + + // Choose the first element that is related to our preferred document + if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { + return -1; + } + if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + return a === doc ? -1 : + b === doc ? 1 : + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( (cur = cur.parentNode) ) { + ap.unshift( cur ); + } + cur = b; + while ( (cur = cur.parentNode) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[i] === bp[i] ) { + i++; + } + + return i ? + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[i], bp[i] ) : + + // Otherwise nodes in our document sort first + ap[i] === preferredDoc ? -1 : + bp[i] === preferredDoc ? 1 : + 0; + }; + + return doc; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + // Make sure that attribute selectors are quoted + expr = expr.replace( rattributeQuotes, "='$1']" ); + + if ( support.matchesSelector && documentIsHTML && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch (e) {} + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + // Set document vars if needed + if ( ( context.ownerDocument || context ) !== document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val !== undefined ? + val : + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + (val = elem.getAttributeNode(name)) && val.specified ? + val.value : + null; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( (elem = results[i++]) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + // If no nodeType, this is expected to be an array + while ( (node = elem[i++]) ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[1] = match[1].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); + + if ( match[2] === "~=" ) { + match[3] = " " + match[3] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1].slice( 0, 3 ) === "nth" ) { + // nth-* requires argument + if ( !match[3] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); + match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); + + // other types prohibit arguments + } else if ( match[3] ) { + Sizzle.error( match[0] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[6] && match[2]; + + if ( matchExpr["CHILD"].test( match[0] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[3] ) { + match[2] = match[4] || match[5] || ""; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + match[0] = match[0].slice( 0, excess ); + match[2] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { return true; } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && + classCache( className, function( elem ) { + return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" ); + }); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + }; + }, + + "CHILD": function( type, what, argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, context, xml ) { + var cache, outerCache, node, diff, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( (node = node[ dir ]) ) { + if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { + return false; + } + } + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + // Seek `elem` from a previously-cached index + outerCache = parent[ expando ] || (parent[ expando ] = {}); + cache = outerCache[ type ] || []; + nodeIndex = cache[0] === dirruns && cache[1]; + diff = cache[0] === dirruns && cache[2]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( (node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + (diff = nodeIndex = 0) || start.pop()) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + outerCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + // Use previously-cached element index if available + } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) { + diff = cache[1]; + + // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...) + } else { + // Use the same loop as above to seek `elem` from the start + while ( (node = ++nodeIndex && node && node[ dir ] || + (diff = nodeIndex = 0) || start.pop()) ) { + + if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) { + // Cache the index of each encountered element + if ( useCache ) { + (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction(function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + // Potentially complex pseudos + "not": markFunction(function( selector ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction(function( seed, matches, context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + // Don't keep the element (issue #299) + input[0] = null; + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + text = text.replace( runescape, funescape ); + return function( elem ) { + return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + // lang value must be a valid identifier + if ( !ridentifier.test(lang || "") ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( (elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); + return false; + }; + }), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + }, + + // Boolean properties + "enabled": function( elem ) { + return elem.disabled === false; + }, + + "disabled": function( elem ) { + return elem.disabled === true; + }, + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "selected": function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos["empty"]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); + }, + + // Position-in-collection + "first": createPositionalPseudo(function() { + return [ 0 ]; + }), + + "last": createPositionalPseudo(function( matchIndexes, length ) { + return [ length - 1 ]; + }), + + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + }), + + "even": createPositionalPseudo(function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "odd": createPositionalPseudo(function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }) + } +}; + +Expr.pseudos["nth"] = Expr.pseudos["eq"]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +tokenize = Sizzle.tokenize = function( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + // Don't consume trailing commas as valid + soFar = soFar.slice( match[0].length ) || soFar; + } + groups.push( (tokens = []) ); + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + matched = match.shift(); + tokens.push({ + value: matched, + // Cast descendant combinators to space + type: match[0].replace( rtrim, " " ) + }); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + (match = preFilters[ type ]( match ))) ) { + matched = match.shift(); + tokens.push({ + value: matched, + type: type, + matches: match + }); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +}; + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[i].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + checkNonElements = base && dir === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching + if ( xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || (elem[ expando ] = {}); + if ( (oldCache = outerCache[ dir ]) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return (newCache[ 2 ] = oldCache[ 2 ]); + } else { + // Reuse newcache so results back-propagate to previous elements + outerCache[ dir ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { + return true; + } + } + } + } + } + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[i]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[0]; +} + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[i], results ); + } + return results; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( (elem = unmatched[i]) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction(function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( (elem = temp[i]) ) { + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) ) { + // Restore matcherIn since elem is not yet a final match + temp.push( (matcherIn[i] = elem) ); + } + } + postFinder( null, (matcherOut = []), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) && + (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) { + + seed[temp] = !(results[temp] = elem); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + }); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[0].type ], + implicitRelative = leadingRelative || Expr.relative[" "], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + (checkContext = context).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + // Avoid hanging onto element (issue #299) + checkContext = null; + return ret; + } ]; + + for ( ; i < len; i++ ) { + if ( (matcher = Expr.relative[ tokens[i].type ]) ) { + matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; + } else { + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[j].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, outermost ) { + var elem, j, matcher, + matchedCount = 0, + i = "0", + unmatched = seed && [], + setMatched = [], + contextBackup = outermostContext, + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), + len = elems.length; + + if ( outermost ) { + outermostContext = context !== document && context; + } + + // Add elements passing elementMatchers directly to results + // Keep `i` a string if there are no elements so `matchedCount` will be "00" below + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id + for ( ; i !== len && (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + while ( (matcher = elementMatchers[j++]) ) { + if ( matcher( elem, context, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + // They will have gone through all possible matchers + if ( (elem = !matcher && elem) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // Apply set filters to unmatched elements + matchedCount += i; + if ( bySet && i !== matchedCount ) { + j = 0; + while ( (matcher = setMatchers[j++]) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !(unmatched[i] || setMatched[i]) ) { + setMatched[i] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element + if ( !match ) { + match = tokenize( selector ); + } + i = match.length; + while ( i-- ) { + cached = matcherFromTokens( match[i] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + + // Save selector and tokenization + cached.selector = selector; + } + return cached; +}; + +/** + * A low-level selection function that works with Sizzle's compiled + * selector functions + * @param {String|Function} selector A selector or a pre-compiled + * selector function built with Sizzle.compile + * @param {Element} context + * @param {Array} [results] + * @param {Array} [seed] A set of elements to match against + */ +select = Sizzle.select = function( selector, context, results, seed ) { + var i, tokens, token, type, find, + compiled = typeof selector === "function" && selector, + match = !seed && tokenize( (selector = compiled.selector || selector) ); + + results = results || []; + + // Try to minimize operations if there is no seed and only one group + if ( match.length === 1 ) { + + // Take a shortcut and set the context if the root selector is an ID + tokens = match[0] = match[0].slice( 0 ); + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && + support.getById && context.nodeType === 9 && documentIsHTML && + Expr.relative[ tokens[1].type ] ) { + + context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; + if ( !context ) { + return results; + + // Precompiled matchers will still verify ancestry, so step up a level + } else if ( compiled ) { + context = context.parentNode; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[i]; + + // Abort if we hit a combinator + if ( Expr.relative[ (type = token.type) ] ) { + break; + } + if ( (find = Expr.find[ type ]) ) { + // Search, expanding context for leading sibling combinators + if ( (seed = find( + token.matches[0].replace( runescape, funescape ), + rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context + )) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + + // Compile and execute a filtering function if one is not provided + // Provide `match` to avoid retokenization if we modified the selector above + ( compiled || compile( selector, match ) )( + seed, + context, + !documentIsHTML, + results, + rsibling.test( selector ) && testContext( context.parentNode ) || context + ); + return results; +}; + +// One-time assignments + +// Sort stability +support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; + +// Support: Chrome 14-35+ +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = !!hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert(function( div1 ) { + // Should return 1, but returns 4 (following) + return div1.compareDocumentPosition( document.createElement("div") ) & 1; +}); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert(function( div ) { + div.innerHTML = ""; + return div.firstChild.getAttribute("href") === "#" ; +}) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + }); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert(function( div ) { + div.innerHTML = ""; + div.firstChild.setAttribute( "value", "" ); + return div.firstChild.getAttribute( "value" ) === ""; +}) ) { + addHandle( "value", function( elem, name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + }); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert(function( div ) { + return div.getAttribute("disabled") == null; +}) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return elem[ name ] === true ? name.toLowerCase() : + (val = elem.getAttributeNode( name )) && val.specified ? + val.value : + null; + } + }); +} + +return Sizzle; + +})( window ); + + + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.pseudos; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + + +var rneedsContext = jQuery.expr.match.needsContext; + +var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/); + + + +var risSimple = /^.[^:#\[\.,]*$/; + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + /* jshint -W018 */ + return !!qualifier.call( elem, i, elem ) !== not; + }); + + } + + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + }); + + } + + if ( typeof qualifier === "string" ) { + if ( risSimple.test( qualifier ) ) { + return jQuery.filter( qualifier, elements, not ); + } + + qualifier = jQuery.filter( qualifier, elements ); + } + + return jQuery.grep( elements, function( elem ) { + return ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not; + }); +} + +jQuery.filter = function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 && elem.nodeType === 1 ? + jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : + jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + })); +}; + +jQuery.fn.extend({ + find: function( selector ) { + var i, + ret = [], + self = this, + len = self.length; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter(function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }) ); + } + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + // Needed because $( selector, context ) becomes $( context ).find( selector ) + ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); + ret.selector = this.selector ? this.selector + " " + selector : selector; + return ret; + }, + filter: function( selector ) { + return this.pushStack( winnow(this, selector || [], false) ); + }, + not: function( selector ) { + return this.pushStack( winnow(this, selector || [], true) ); + }, + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + } +}); + + +// Initialize a jQuery object + + +// A central reference to the root jQuery(document) +var rootjQuery, + + // Use the correct document accordingly with window argument (sandbox) + document = window.document, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, + + init = jQuery.fn.init = function( selector, context ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + + // scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge( this, jQuery.parseHTML( + match[1], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + // Properties of context are called as methods if possible + if ( jQuery.isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[2] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id !== match[2] ) { + return rootjQuery.find( selector ); + } + + // Otherwise, we inject the element directly into the jQuery object + this.length = 1; + this[0] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || rootjQuery ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return typeof rootjQuery.ready !== "undefined" ? + rootjQuery.ready( selector ) : + // Execute immediately if ready is not present + selector( jQuery ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }; + +// Give the init function the jQuery prototype for later instantiation +init.prototype = jQuery.fn; + +// Initialize central reference +rootjQuery = jQuery( document ); + + +var rparentsprev = /^(?:parents|prev(?:Until|All))/, + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.extend({ + dir: function( elem, dir, until ) { + var matched = [], + cur = elem[ dir ]; + + while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { + if ( cur.nodeType === 1 ) { + matched.push( cur ); + } + cur = cur[dir]; + } + return matched; + }, + + sibling: function( n, elem ) { + var r = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + r.push( n ); + } + } + + return r; + } +}); + +jQuery.fn.extend({ + has: function( target ) { + var i, + targets = jQuery( target, this ), + len = targets.length; + + return this.filter(function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( this, targets[i] ) ) { + return true; + } + } + }); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + matched = [], + pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( ; i < l; i++ ) { + for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) { + // Always skip document fragments + if ( cur.nodeType < 11 && (pos ? + pos.index(cur) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector(cur, selectors)) ) { + + matched.push( cur ); + break; + } + } + } + + return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return jQuery.inArray( this[0], jQuery( elem ) ); + } + + // Locate the position of the desired element + return jQuery.inArray( + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[0] : elem, this ); + }, + + add: function( selector, context ) { + return this.pushStack( + jQuery.unique( + jQuery.merge( this.get(), jQuery( selector, context ) ) + ) + ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter(selector) + ); + } +}); + +function sibling( cur, dir ) { + do { + cur = cur[ dir ]; + } while ( cur && cur.nodeType !== 1 ); + + return cur; +} + +jQuery.each({ + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return jQuery.dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return jQuery.dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return jQuery.dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return jQuery.dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return jQuery.dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return jQuery.dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return jQuery.sibling( elem.firstChild ); + }, + contents: function( elem ) { + return jQuery.nodeName( elem, "iframe" ) ? + elem.contentDocument || elem.contentWindow.document : + jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var ret = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + ret = jQuery.filter( selector, ret ); + } + + if ( this.length > 1 ) { + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + ret = jQuery.unique( ret ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + ret = ret.reverse(); + } + } + + return this.pushStack( ret ); + }; +}); +var rnotwhite = (/\S+/g); + + + +// String to Object options format cache +var optionsCache = {}; + +// Convert String-formatted options into Object-formatted ones and store in cache +function createOptions( options ) { + var object = optionsCache[ options ] = {}; + jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) { + object[ flag ] = true; + }); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + ( optionsCache[ options ] || createOptions( options ) ) : + jQuery.extend( {}, options ); + + var // Flag to know if list is currently firing + firing, + // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list was already fired + fired, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // First callback to fire (used internally by add and fireWith) + firingStart, + // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = !options.once && [], + // Fire callbacks + fire = function( data ) { + memory = options.memory && data; + fired = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + firing = true; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { + memory = false; // To prevent further calls using add + break; + } + } + firing = false; + if ( list ) { + if ( stack ) { + if ( stack.length ) { + fire( stack.shift() ); + } + } else if ( memory ) { + list = []; + } else { + self.disable(); + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + // First, we save the current length + var start = list.length; + (function add( args ) { + jQuery.each( args, function( _, arg ) { + var type = jQuery.type( arg ); + if ( type === "function" ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && type !== "string" ) { + // Inspect recursively + add( arg ); + } + }); + })( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away + } else if ( memory ) { + firingStart = start; + fire( memory ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + jQuery.each( arguments, function( _, arg ) { + var index; + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + // Handle firing indexes + if ( firing ) { + if ( index <= firingLength ) { + firingLength--; + } + if ( index <= firingIndex ) { + firingIndex--; + } + } + } + }); + } + return this; + }, + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length ); + }, + // Remove all callbacks from the list + empty: function() { + list = []; + firingLength = 0; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( list && ( !fired || stack ) ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + if ( firing ) { + stack.push( args ); + } else { + fire( args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + +jQuery.extend({ + + Deferred: function( func ) { + var tuples = [ + // action, add listener, listener list, final state + [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], + [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], + [ "notify", "progress", jQuery.Callbacks("memory") ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + then: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + return jQuery.Deferred(function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; + // deferred[ done | fail | progress ] for forwarding actions to newDefer + deferred[ tuple[1] ](function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .done( newDefer.resolve ) + .fail( newDefer.reject ) + .progress( newDefer.notify ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); + } + }); + }); + fns = null; + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Keep pipe for back-compat + promise.pipe = promise.then; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 3 ]; + + // promise[ done | fail | progress ] = list.add + promise[ tuple[1] ] = list.add; + + // Handle state + if ( stateString ) { + list.add(function() { + // state = [ resolved | rejected ] + state = stateString; + + // [ reject_list | resolve_list ].disable; progress_list.lock + }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); + } + + // deferred[ resolve | reject | notify ] + deferred[ tuple[0] ] = function() { + deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments ); + return this; + }; + deferred[ tuple[0] + "With" ] = list.fireWith; + }); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( subordinate /* , ..., subordinateN */ ) { + var i = 0, + resolveValues = slice.call( arguments ), + length = resolveValues.length, + + // the count of uncompleted subordinates + remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, + + // the master Deferred. If resolveValues consist of only a single Deferred, just use that. + deferred = remaining === 1 ? subordinate : jQuery.Deferred(), + + // Update function for both resolve and progress values + updateFunc = function( i, contexts, values ) { + return function( value ) { + contexts[ i ] = this; + values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; + if ( values === progressValues ) { + deferred.notifyWith( contexts, values ); + + } else if ( !(--remaining) ) { + deferred.resolveWith( contexts, values ); + } + }; + }, + + progressValues, progressContexts, resolveContexts; + + // add listeners to Deferred subordinates; treat others as resolved + if ( length > 1 ) { + progressValues = new Array( length ); + progressContexts = new Array( length ); + resolveContexts = new Array( length ); + for ( ; i < length; i++ ) { + if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { + resolveValues[ i ].promise() + .done( updateFunc( i, resolveContexts, resolveValues ) ) + .fail( deferred.reject ) + .progress( updateFunc( i, progressContexts, progressValues ) ); + } else { + --remaining; + } + } + } + + // if we're not waiting on anything, resolve the master + if ( !remaining ) { + deferred.resolveWith( resolveContexts, resolveValues ); + } + + return deferred.promise(); + } +}); + + +// The deferred used on DOM ready +var readyList; + +jQuery.fn.ready = function( fn ) { + // Add the callback + jQuery.ready.promise().done( fn ); + + return this; +}; + +jQuery.extend({ + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( !document.body ) { + return setTimeout( jQuery.ready ); + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.triggerHandler ) { + jQuery( document ).triggerHandler( "ready" ); + jQuery( document ).off( "ready" ); + } + } +}); + +/** + * Clean-up method for dom ready events + */ +function detach() { + if ( document.addEventListener ) { + document.removeEventListener( "DOMContentLoaded", completed, false ); + window.removeEventListener( "load", completed, false ); + + } else { + document.detachEvent( "onreadystatechange", completed ); + window.detachEvent( "onload", completed ); + } +} + +/** + * The ready event handler and self cleanup method + */ +function completed() { + // readyState === "complete" is good enough for us to call the dom ready in oldIE + if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) { + detach(); + jQuery.ready(); + } +} + +jQuery.ready.promise = function( obj ) { + if ( !readyList ) { + + readyList = jQuery.Deferred(); + + // Catch cases where $(document).ready() is called after the browser event has already occurred. + // we once tried to use readyState "interactive" here, but it caused issues like the one + // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + setTimeout( jQuery.ready ); + + // Standards-based browsers support DOMContentLoaded + } else if ( document.addEventListener ) { + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed, false ); + + // If IE event model is used + } else { + // Ensure firing before onload, maybe late but safe also for iframes + document.attachEvent( "onreadystatechange", completed ); + + // A fallback to window.onload, that will always work + window.attachEvent( "onload", completed ); + + // If IE and not a frame + // continually check to see if the document is ready + var top = false; + + try { + top = window.frameElement == null && document.documentElement; + } catch(e) {} + + if ( top && top.doScroll ) { + (function doScrollCheck() { + if ( !jQuery.isReady ) { + + try { + // Use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + top.doScroll("left"); + } catch(e) { + return setTimeout( doScrollCheck, 50 ); + } + + // detach all dom ready events + detach(); + + // and execute any waiting functions + jQuery.ready(); + } + })(); + } + } + } + return readyList.promise( obj ); +}; + + +var strundefined = typeof undefined; + + + +// Support: IE<9 +// Iteration over object's inherited properties before its own +var i; +for ( i in jQuery( support ) ) { + break; +} +support.ownLast = i !== "0"; + +// Note: most support tests are defined in their respective modules. +// false until the test is run +support.inlineBlockNeedsLayout = false; + +// Execute ASAP in case we need to set body.style.zoom +jQuery(function() { + // Minified: var a,b,c,d + var val, div, body, container; + + body = document.getElementsByTagName( "body" )[ 0 ]; + if ( !body || !body.style ) { + // Return for frameset docs that don't have a body + return; + } + + // Setup + div = document.createElement( "div" ); + container = document.createElement( "div" ); + container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px"; + body.appendChild( container ).appendChild( div ); + + if ( typeof div.style.zoom !== strundefined ) { + // Support: IE<8 + // Check if natively block-level elements act like inline-block + // elements when setting their display to 'inline' and giving + // them layout + div.style.cssText = "display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1"; + + support.inlineBlockNeedsLayout = val = div.offsetWidth === 3; + if ( val ) { + // Prevent IE 6 from affecting layout for positioned elements #11048 + // Prevent IE from shrinking the body in IE 7 mode #12869 + // Support: IE<8 + body.style.zoom = 1; + } + } + + body.removeChild( container ); +}); + + + + +(function() { + var div = document.createElement( "div" ); + + // Execute the test only if not already executed in another module. + if (support.deleteExpando == null) { + // Support: IE<9 + support.deleteExpando = true; + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + } + + // Null elements to avoid leaks in IE. + div = null; +})(); + + +/** + * Determines whether an object can have data + */ +jQuery.acceptData = function( elem ) { + var noData = jQuery.noData[ (elem.nodeName + " ").toLowerCase() ], + nodeType = +elem.nodeType || 1; + + // Do not set data on non-element DOM nodes because it will not be cleared (#8335). + return nodeType !== 1 && nodeType !== 9 ? + false : + + // Nodes accept data unless otherwise specified; rejection can be conditional + !noData || noData !== true && elem.getAttribute("classid") === noData; +}; + + +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, + rmultiDash = /([A-Z])/g; + +function dataAttr( elem, key, data ) { + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + + var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + // Only convert to a number if it doesn't change the string + +data + "" === data ? +data : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + jQuery.data( elem, key, data ); + + } else { + data = undefined; + } + } + + return data; +} + +// checks a cache object for emptiness +function isEmptyDataObject( obj ) { + var name; + for ( name in obj ) { + + // if the public data object is empty, the private is still empty + if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { + continue; + } + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} + +function internalData( elem, name, data, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var ret, thisCache, + internalKey = jQuery.expando, + + // We have to handle DOM nodes and JS objects differently because IE6-7 + // can't GC object references properly across the DOM-JS boundary + isNode = elem.nodeType, + + // Only DOM nodes need the global jQuery cache; JS object data is + // attached directly to the object so GC can occur automatically + cache = isNode ? jQuery.cache : elem, + + // Only defining an ID for JS objects if its cache already exists allows + // the code to shortcut on the same path as a DOM node with no cache + id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey; + + // Avoid doing any more work than we need to when trying to get data on an + // object that has no data at all + if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && data === undefined && typeof name === "string" ) { + return; + } + + if ( !id ) { + // Only DOM nodes need a new unique ID for each element since their data + // ends up in the global cache + if ( isNode ) { + id = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++; + } else { + id = internalKey; + } + } + + if ( !cache[ id ] ) { + // Avoid exposing jQuery metadata on plain JS objects when the object + // is serialized using JSON.stringify + cache[ id ] = isNode ? {} : { toJSON: jQuery.noop }; + } + + // An object can be passed to jQuery.data instead of a key/value pair; this gets + // shallow copied over onto the existing cache + if ( typeof name === "object" || typeof name === "function" ) { + if ( pvt ) { + cache[ id ] = jQuery.extend( cache[ id ], name ); + } else { + cache[ id ].data = jQuery.extend( cache[ id ].data, name ); + } + } + + thisCache = cache[ id ]; + + // jQuery data() is stored in a separate object inside the object's internal data + // cache in order to avoid key collisions between internal data and user-defined + // data. + if ( !pvt ) { + if ( !thisCache.data ) { + thisCache.data = {}; + } + + thisCache = thisCache.data; + } + + if ( data !== undefined ) { + thisCache[ jQuery.camelCase( name ) ] = data; + } + + // Check for both converted-to-camel and non-converted data property names + // If a data property was specified + if ( typeof name === "string" ) { + + // First Try to find as-is property data + ret = thisCache[ name ]; + + // Test for null|undefined property data + if ( ret == null ) { + + // Try to find the camelCased property + ret = thisCache[ jQuery.camelCase( name ) ]; + } + } else { + ret = thisCache; + } + + return ret; +} + +function internalRemoveData( elem, name, pvt ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, i, + isNode = elem.nodeType, + + // See jQuery.data for more information + cache = isNode ? jQuery.cache : elem, + id = isNode ? elem[ jQuery.expando ] : jQuery.expando; + + // If there is already no cache entry for this object, there is no + // purpose in continuing + if ( !cache[ id ] ) { + return; + } + + if ( name ) { + + thisCache = pvt ? cache[ id ] : cache[ id ].data; + + if ( thisCache ) { + + // Support array or space separated string names for data keys + if ( !jQuery.isArray( name ) ) { + + // try the string as a key before any manipulation + if ( name in thisCache ) { + name = [ name ]; + } else { + + // split the camel cased version by spaces unless a key with the spaces exists + name = jQuery.camelCase( name ); + if ( name in thisCache ) { + name = [ name ]; + } else { + name = name.split(" "); + } + } + } else { + // If "name" is an array of keys... + // When data is initially created, via ("key", "val") signature, + // keys will be converted to camelCase. + // Since there is no way to tell _how_ a key was added, remove + // both plain key and camelCase key. #12786 + // This will only penalize the array argument path. + name = name.concat( jQuery.map( name, jQuery.camelCase ) ); + } + + i = name.length; + while ( i-- ) { + delete thisCache[ name[i] ]; + } + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache) ) { + return; + } + } + } + + // See jQuery.data for more information + if ( !pvt ) { + delete cache[ id ].data; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !isEmptyDataObject( cache[ id ] ) ) { + return; + } + } + + // Destroy the cache + if ( isNode ) { + jQuery.cleanData( [ elem ], true ); + + // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080) + /* jshint eqeqeq: false */ + } else if ( support.deleteExpando || cache != cache.window ) { + /* jshint eqeqeq: true */ + delete cache[ id ]; + + // When all else fails, null + } else { + cache[ id ] = null; + } +} + +jQuery.extend({ + cache: {}, + + // The following elements (space-suffixed to avoid Object.prototype collisions) + // throw uncatchable exceptions if you attempt to set expando properties + noData: { + "applet ": true, + "embed ": true, + // ...but Flash objects (which have this classid) *can* handle expandos + "object ": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" + }, + + hasData: function( elem ) { + elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; + return !!elem && !isEmptyDataObject( elem ); + }, + + data: function( elem, name, data ) { + return internalData( elem, name, data ); + }, + + removeData: function( elem, name ) { + return internalRemoveData( elem, name ); + }, + + // For internal use only. + _data: function( elem, name, data ) { + return internalData( elem, name, data, true ); + }, + + _removeData: function( elem, name ) { + return internalRemoveData( elem, name, true ); + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var i, name, data, + elem = this[0], + attrs = elem && elem.attributes; + + // Special expections of .data basically thwart jQuery.access, + // so implement the relevant behavior ourselves + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = jQuery.data( elem ); + + if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { + i = attrs.length; + while ( i-- ) { + + // Support: IE11+ + // The attrs elements can be null (#14894) + if ( attrs[ i ] ) { + name = attrs[ i ].name; + if ( name.indexOf( "data-" ) === 0 ) { + name = jQuery.camelCase( name.slice(5) ); + dataAttr( elem, name, data[ name ] ); + } + } + } + jQuery._data( elem, "parsedAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each(function() { + jQuery.data( this, key ); + }); + } + + return arguments.length > 1 ? + + // Sets one value + this.each(function() { + jQuery.data( this, key, value ); + }) : + + // Gets one value + // Try to fetch any internally stored data first + elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined; + }, + + removeData: function( key ) { + return this.each(function() { + jQuery.removeData( this, key ); + }); + } +}); + + +jQuery.extend({ + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = jQuery._data( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || jQuery.isArray(data) ) { + queue = jQuery._data( elem, type, jQuery.makeArray(data) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // not intended for public consumption - generates a queueHooks object, or returns the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return jQuery._data( elem, key ) || jQuery._data( elem, key, { + empty: jQuery.Callbacks("once memory").add(function() { + jQuery._removeData( elem, type + "queue" ); + jQuery._removeData( elem, key ); + }) + }); + } +}); + +jQuery.fn.extend({ + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[0], type ); + } + + return data === undefined ? + this : + this.each(function() { + var queue = jQuery.queue( this, type, data ); + + // ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[0] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + }); + }, + dequeue: function( type ) { + return this.each(function() { + jQuery.dequeue( this, type ); + }); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while ( i-- ) { + tmp = jQuery._data( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +}); +var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source; + +var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; + +var isHidden = function( elem, el ) { + // isHidden might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); + }; + + + +// Multifunctional method to get and set values of a collection +// The value/s can optionally be executed if it's a function +var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + length = elems.length, + bulk = key == null; + + // Sets many values + if ( jQuery.type( key ) === "object" ) { + chainable = true; + for ( i in key ) { + jQuery.access( elems, fn, i, key[i], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !jQuery.isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < length; i++ ) { + fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) ); + } + } + } + + return chainable ? + elems : + + // Gets + bulk ? + fn.call( elems ) : + length ? fn( elems[0], key ) : emptyGet; +}; +var rcheckableType = (/^(?:checkbox|radio)$/i); + + + +(function() { + // Minified: var a,b,c + var input = document.createElement( "input" ), + div = document.createElement( "div" ), + fragment = document.createDocumentFragment(); + + // Setup + div.innerHTML = "
a"; + + // IE strips leading whitespace when .innerHTML is used + support.leadingWhitespace = div.firstChild.nodeType === 3; + + // Make sure that tbody elements aren't automatically inserted + // IE will insert them into empty tables + support.tbody = !div.getElementsByTagName( "tbody" ).length; + + // Make sure that link elements get serialized correctly by innerHTML + // This requires a wrapper element in IE + support.htmlSerialize = !!div.getElementsByTagName( "link" ).length; + + // Makes sure cloning an html5 element does not cause problems + // Where outerHTML is undefined, this still works + support.html5Clone = + document.createElement( "nav" ).cloneNode( true ).outerHTML !== "<:nav>"; + + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + input.type = "checkbox"; + input.checked = true; + fragment.appendChild( input ); + support.appendChecked = input.checked; + + // Make sure textarea (and checkbox) defaultValue is properly cloned + // Support: IE6-IE11+ + div.innerHTML = ""; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; + + // #11217 - WebKit loses check when the name is after the checked attribute + fragment.appendChild( div ); + div.innerHTML = ""; + + // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3 + // old WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE<9 + // Opera does not clone events (and typeof div.attachEvent === undefined). + // IE9-10 clones events bound via attachEvent, but they don't trigger with .click() + support.noCloneEvent = true; + if ( div.attachEvent ) { + div.attachEvent( "onclick", function() { + support.noCloneEvent = false; + }); + + div.cloneNode( true ).click(); + } + + // Execute the test only if not already executed in another module. + if (support.deleteExpando == null) { + // Support: IE<9 + support.deleteExpando = true; + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + } +})(); + + +(function() { + var i, eventName, + div = document.createElement( "div" ); + + // Support: IE<9 (lack submit/change bubble), Firefox 23+ (lack focusin event) + for ( i in { submit: true, change: true, focusin: true }) { + eventName = "on" + i; + + if ( !(support[ i + "Bubbles" ] = eventName in window) ) { + // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP) + div.setAttribute( eventName, "t" ); + support[ i + "Bubbles" ] = div.attributes[ eventName ].expando === false; + } + } + + // Null elements to avoid leaks in IE. + div = null; +})(); + + +var rformElems = /^(?:input|select|textarea)$/i, + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|pointer|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)$/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + var tmp, events, t, handleObjIn, + special, eventHandle, handleObj, + handlers, type, namespaces, origType, + elemData = jQuery._data( elem ); + + // Don't attach events to noData or text/comment nodes (but allow plain objects) + if ( !elemData ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !(events = elemData.events) ) { + events = elemData.events = {}; + } + if ( !(eventHandle = elemData.handle) ) { + eventHandle = elemData.handle = function( e ) { + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== strundefined && (!e || jQuery.event.triggered !== e.type) ? + jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : + undefined; + }; + // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events + eventHandle.elem = elem; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( rnotwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend({ + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join(".") + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !(handlers = events[ type ]) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener/attachEvent if the special events handler returns false + if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + // Bind the global event handler to the element + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + // Nullify elem to prevent memory leaks in IE + elem = null; + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + var j, handleObj, tmp, + origCount, t, events, + special, handlers, type, + namespaces, origType, + elemData = jQuery.hasData( elem ) && jQuery._data( elem ); + + if ( !elemData || !(events = elemData.events) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( rnotwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + delete elemData.handle; + + // removeData also checks for emptiness and clears the expando if empty + // so use it instead of delete + jQuery._removeData( elem, "events" ); + } + }, + + trigger: function( event, data, elem, onlyHandlers ) { + var handle, ontype, cur, + bubbleType, special, tmp, i, + eventPath = [ elem || document ], + type = hasOwn.call( event, "type" ) ? event.type : event, + namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : []; + + cur = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf(".") >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf(":") < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join("."); + event.namespace_re = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === (elem.ownerDocument || document) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) { + + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && handle.apply && jQuery.acceptData( cur ) ) { + event.result = handle.apply( cur, data ); + if ( event.result === false ) { + event.preventDefault(); + } + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) && + jQuery.acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name name as the event. + // Can't use an .isFunction() check here because IE6/7 fails that test. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + try { + elem[ type ](); + } catch ( e ) { + // IE<9 dies on focus/blur to hidden element (#1486,#12518) + // only reproducible on winXP IE8 native, not IE9 in IE8 mode + } + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event ); + + var i, ret, handleObj, matched, j, + handlerQueue = [], + args = slice.call( arguments ), + handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[0] = event; + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) { + + // Triggered event must either 1) have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). + if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) + .apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( (event.result = ret) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var sel, handleObj, matches, i, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + // Black-hole SVG instance trees (#13180) + // Avoid non-left-click bubbling in Firefox (#3861) + if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) { + + /* jshint eqeqeq: false */ + for ( ; cur != this; cur = cur.parentNode || this ) { + /* jshint eqeqeq: true */ + + // Don't check non-elements (#13208) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== "click") ) { + matches = []; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matches[ sel ] === undefined ) { + matches[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) >= 0 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matches[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, handlers: matches }); + } + } + } + } + + // Add the remaining (directly-bound) handlers + if ( delegateCount < handlers.length ) { + handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) }); + } + + return handlerQueue; + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, copy, + type = event.type, + originalEvent = event, + fixHook = this.fixHooks[ type ]; + + if ( !fixHook ) { + this.fixHooks[ type ] = fixHook = + rmouseEvent.test( type ) ? this.mouseHooks : + rkeyEvent.test( type ) ? this.keyHooks : + {}; + } + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = new jQuery.Event( originalEvent ); + + i = copy.length; + while ( i-- ) { + prop = copy[ i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Support: IE<9 + // Fix target property (#1925) + if ( !event.target ) { + event.target = originalEvent.srcElement || document; + } + + // Support: Chrome 23+, Safari? + // Target should not be a text node (#504, #13143) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // Support: IE<9 + // For mouse/key events, metaKey==false if it's undefined (#3368, #11328) + event.metaKey = !!event.metaKey; + + return fixHook.filter ? fixHook.filter( event, originalEvent ) : event; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split(" "), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function( event, original ) { + var body, eventDoc, doc, + button = original.button, + fromElement = original.fromElement; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && fromElement ) { + event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + special: { + load: { + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + focus: { + // Fire native event if possible so blur/focus sequence is correct + trigger: function() { + if ( this !== safeActiveElement() && this.focus ) { + try { + this.focus(); + return false; + } catch ( e ) { + // Support: IE<9 + // If we error on focus to hidden element (#1486, #12518), + // let .trigger() run the handlers + } + } + }, + delegateType: "focusin" + }, + blur: { + trigger: function() { + if ( this === safeActiveElement() && this.blur ) { + this.blur(); + return false; + } + }, + delegateType: "focusout" + }, + click: { + // For checkbox, fire native event so checked state will be right + trigger: function() { + if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) { + this.click(); + return false; + } + }, + + // For cross-browser consistency, don't fire native .click() on links + _default: function( event ) { + return jQuery.nodeName( event.target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Support: Firefox 20+ + // Firefox doesn't alert if the returnValue field is not set. + if ( event.result !== undefined && event.originalEvent ) { + event.originalEvent.returnValue = event.result; + } + } + } + }, + + simulate: function( type, elem, event, bubble ) { + // Piggyback on a donor event to simulate a different one. + // Fake originalEvent to avoid donor's stopPropagation, but if the + // simulated event prevents default then we do the same on the donor. + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true, + originalEvent: {} + } + ); + if ( bubble ) { + jQuery.event.trigger( e, null, elem ); + } else { + jQuery.event.dispatch.call( elem, e ); + } + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +jQuery.removeEvent = document.removeEventListener ? + function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } + } : + function( elem, type, handle ) { + var name = "on" + type; + + if ( elem.detachEvent ) { + + // #8545, #7054, preventing memory leaks for custom events in IE6-8 + // detachEvent needed property on element, by name of that event, to properly expose it to GC + if ( typeof elem[ name ] === strundefined ) { + elem[ name ] = null; + } + + elem.detachEvent( name, handle ); + } + }; + +jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !(this instanceof jQuery.Event) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented || + src.defaultPrevented === undefined && + // Support: IE < 9, Android < 4.0 + src.returnValue === false ? + returnTrue : + returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + if ( !e ) { + return; + } + + // If preventDefault exists, run it on the original event + if ( e.preventDefault ) { + e.preventDefault(); + + // Support: IE + // Otherwise set the returnValue property of the original event to false + } else { + e.returnValue = false; + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + if ( !e ) { + return; + } + // If stopPropagation exists, run it on the original event + if ( e.stopPropagation ) { + e.stopPropagation(); + } + + // Support: IE + // Set the cancelBubble property of the original event to true + e.cancelBubble = true; + }, + stopImmediatePropagation: function() { + var e = this.originalEvent; + + this.isImmediatePropagationStopped = returnTrue; + + if ( e && e.stopImmediatePropagation ) { + e.stopImmediatePropagation(); + } + + this.stopPropagation(); + } +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout", + pointerenter: "pointerover", + pointerleave: "pointerout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || (related !== target && !jQuery.contains( target, related )) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +}); + +// IE submit delegation +if ( !support.submitBubbles ) { + + jQuery.event.special.submit = { + setup: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Lazy-add a submit handler when a descendant form may potentially be submitted + jQuery.event.add( this, "click._submit keypress._submit", function( e ) { + // Node name check avoids a VML-related crash in IE (#9807) + var elem = e.target, + form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; + if ( form && !jQuery._data( form, "submitBubbles" ) ) { + jQuery.event.add( form, "submit._submit", function( event ) { + event._submit_bubble = true; + }); + jQuery._data( form, "submitBubbles", true ); + } + }); + // return undefined since we don't need an event listener + }, + + postDispatch: function( event ) { + // If form was submitted by the user, bubble the event up the tree + if ( event._submit_bubble ) { + delete event._submit_bubble; + if ( this.parentNode && !event.isTrigger ) { + jQuery.event.simulate( "submit", this.parentNode, event, true ); + } + } + }, + + teardown: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Remove delegated handlers; cleanData eventually reaps submit handlers attached above + jQuery.event.remove( this, "._submit" ); + } + }; +} + +// IE change delegation and checkbox/radio fix +if ( !support.changeBubbles ) { + + jQuery.event.special.change = { + + setup: function() { + + if ( rformElems.test( this.nodeName ) ) { + // IE doesn't fire change on a check/radio until blur; trigger it on click + // after a propertychange. Eat the blur-change in special.change.handle. + // This still fires onchange a second time for check/radio after blur. + if ( this.type === "checkbox" || this.type === "radio" ) { + jQuery.event.add( this, "propertychange._change", function( event ) { + if ( event.originalEvent.propertyName === "checked" ) { + this._just_changed = true; + } + }); + jQuery.event.add( this, "click._change", function( event ) { + if ( this._just_changed && !event.isTrigger ) { + this._just_changed = false; + } + // Allow triggered, simulated change events (#11500) + jQuery.event.simulate( "change", this, event, true ); + }); + } + return false; + } + // Delegated event; lazy-add a change handler on descendant inputs + jQuery.event.add( this, "beforeactivate._change", function( e ) { + var elem = e.target; + + if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "changeBubbles" ) ) { + jQuery.event.add( elem, "change._change", function( event ) { + if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { + jQuery.event.simulate( "change", this.parentNode, event, true ); + } + }); + jQuery._data( elem, "changeBubbles", true ); + } + }); + }, + + handle: function( event ) { + var elem = event.target; + + // Swallow native change events from checkbox/radio, we already triggered them above + if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { + return event.handleObj.handler.apply( this, arguments ); + } + }, + + teardown: function() { + jQuery.event.remove( this, "._change" ); + + return !rformElems.test( this.nodeName ); + } + }; +} + +// Create "bubbling" focus and blur events +if ( !support.focusinBubbles ) { + jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler on the document while someone wants focusin/focusout + var handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + var doc = this.ownerDocument || this, + attaches = jQuery._data( doc, fix ); + + if ( !attaches ) { + doc.addEventListener( orig, handler, true ); + } + jQuery._data( doc, fix, ( attaches || 0 ) + 1 ); + }, + teardown: function() { + var doc = this.ownerDocument || this, + attaches = jQuery._data( doc, fix ) - 1; + + if ( !attaches ) { + doc.removeEventListener( orig, handler, true ); + jQuery._removeData( doc, fix ); + } else { + jQuery._data( doc, fix, attaches ); + } + } + }; + }); +} + +jQuery.fn.extend({ + + on: function( types, selector, data, fn, /*INTERNAL*/ one ) { + var type, origFn; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return this.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on( types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + jQuery.event.remove( this, types, fn, selector ); + }); + }, + + trigger: function( type, data ) { + return this.each(function() { + jQuery.event.trigger( type, data, this ); + }); + }, + triggerHandler: function( type, data ) { + var elem = this[0]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +}); + + +function createSafeFragment( document ) { + var list = nodeNames.split( "|" ), + safeFrag = document.createDocumentFragment(); + + if ( safeFrag.createElement ) { + while ( list.length ) { + safeFrag.createElement( + list.pop() + ); + } + } + return safeFrag; +} + +var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" + + "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", + rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g, + rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"), + rleadingWhitespace = /^\s+/, + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, + rtagName = /<([\w:]+)/, + rtbody = /
", "
" ], + tr: [ 2, "", "
" ], + col: [ 2, "", "
" ], + td: [ 3, "", "
" ], + + // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags, + // unless wrapped in a div with non-breaking characters in front of it. + _default: support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X
", "
" ] + }, + safeFragment = createSafeFragment( document ), + fragmentDiv = safeFragment.appendChild( document.createElement("div") ); + +wrapMap.optgroup = wrapMap.option; +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +function getAll( context, tag ) { + var elems, elem, + i = 0, + found = typeof context.getElementsByTagName !== strundefined ? context.getElementsByTagName( tag || "*" ) : + typeof context.querySelectorAll !== strundefined ? context.querySelectorAll( tag || "*" ) : + undefined; + + if ( !found ) { + for ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) { + if ( !tag || jQuery.nodeName( elem, tag ) ) { + found.push( elem ); + } else { + jQuery.merge( found, getAll( elem, tag ) ); + } + } + } + + return tag === undefined || tag && jQuery.nodeName( context, tag ) ? + jQuery.merge( [ context ], found ) : + found; +} + +// Used in buildFragment, fixes the defaultChecked property +function fixDefaultChecked( elem ) { + if ( rcheckableType.test( elem.type ) ) { + elem.defaultChecked = elem.checked; + } +} + +// Support: IE<8 +// Manipulating tables requires a tbody +function manipulationTarget( elem, content ) { + return jQuery.nodeName( elem, "table" ) && + jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ? + + elem.getElementsByTagName("tbody")[0] || + elem.appendChild( elem.ownerDocument.createElement("tbody") ) : + elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = (jQuery.find.attr( elem, "type" ) !== null) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + var match = rscriptTypeMasked.exec( elem.type ); + if ( match ) { + elem.type = match[1]; + } else { + elem.removeAttribute("type"); + } + return elem; +} + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var elem, + i = 0; + for ( ; (elem = elems[i]) != null; i++ ) { + jQuery._data( elem, "globalEval", !refElements || jQuery._data( refElements[i], "globalEval" ) ); + } +} + +function cloneCopyEvent( src, dest ) { + + if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) { + return; + } + + var type, i, l, + oldData = jQuery._data( src ), + curData = jQuery._data( dest, oldData ), + events = oldData.events; + + if ( events ) { + delete curData.handle; + curData.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + + // make the cloned public data object a copy from the original + if ( curData.data ) { + curData.data = jQuery.extend( {}, curData.data ); + } +} + +function fixCloneNodeIssues( src, dest ) { + var nodeName, e, data; + + // We do not need to do anything for non-Elements + if ( dest.nodeType !== 1 ) { + return; + } + + nodeName = dest.nodeName.toLowerCase(); + + // IE6-8 copies events bound via attachEvent when using cloneNode. + if ( !support.noCloneEvent && dest[ jQuery.expando ] ) { + data = jQuery._data( dest ); + + for ( e in data.events ) { + jQuery.removeEvent( dest, e, data.handle ); + } + + // Event data gets referenced instead of copied if the expando gets copied too + dest.removeAttribute( jQuery.expando ); + } + + // IE blanks contents when cloning scripts, and tries to evaluate newly-set text + if ( nodeName === "script" && dest.text !== src.text ) { + disableScript( dest ).text = src.text; + restoreScript( dest ); + + // IE6-10 improperly clones children of object elements using classid. + // IE10 throws NoModificationAllowedError if parent is null, #12132. + } else if ( nodeName === "object" ) { + if ( dest.parentNode ) { + dest.outerHTML = src.outerHTML; + } + + // This path appears unavoidable for IE9. When cloning an object + // element in IE9, the outerHTML strategy above is not sufficient. + // If the src has innerHTML and the destination does not, + // copy the src.innerHTML into the dest.innerHTML. #10324 + if ( support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) { + dest.innerHTML = src.innerHTML; + } + + } else if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + // IE6-8 fails to persist the checked state of a cloned checkbox + // or radio button. Worse, IE6-7 fail to give the cloned element + // a checked appearance if the defaultChecked value isn't also set + + dest.defaultChecked = dest.checked = src.checked; + + // IE6-7 get confused and end up setting the value of a cloned + // checkbox/radio button to an empty string instead of "on" + if ( dest.value !== src.value ) { + dest.value = src.value; + } + + // IE6-8 fails to return the selected option to the default selected + // state when cloning options + } else if ( nodeName === "option" ) { + dest.defaultSelected = dest.selected = src.defaultSelected; + + // IE6-8 fails to set the defaultValue to the correct value when + // cloning other types of input fields + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +jQuery.extend({ + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var destElements, node, clone, i, srcElements, + inPage = jQuery.contains( elem.ownerDocument, elem ); + + if ( support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { + clone = elem.cloneNode( true ); + + // IE<=8 does not properly clone detached, unknown element nodes + } else { + fragmentDiv.innerHTML = elem.outerHTML; + fragmentDiv.removeChild( clone = fragmentDiv.firstChild ); + } + + if ( (!support.noCloneEvent || !support.noCloneChecked) && + (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { + + // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + // Fix all IE cloning issues + for ( i = 0; (node = srcElements[i]) != null; ++i ) { + // Ensure that the destination node is not null; Fixes #9587 + if ( destElements[i] ) { + fixCloneNodeIssues( node, destElements[i] ); + } + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0; (node = srcElements[i]) != null; i++ ) { + cloneCopyEvent( node, destElements[i] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + destElements = srcElements = node = null; + + // Return the cloned set + return clone; + }, + + buildFragment: function( elems, context, scripts, selection ) { + var j, elem, contains, + tmp, tag, tbody, wrap, + l = elems.length, + + // Ensure a safe fragment + safe = createSafeFragment( context ), + + nodes = [], + i = 0; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( jQuery.type( elem ) === "object" ) { + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || safe.appendChild( context.createElement("div") ); + + // Deserialize a standard representation + tag = (rtagName.exec( elem ) || [ "", "" ])[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + + tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, "<$1>" ) + wrap[2]; + + // Descend through wrappers to the right content + j = wrap[0]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Manually add leading whitespace removed by IE + if ( !support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { + nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) ); + } + + // Remove IE's autoinserted from table fragments + if ( !support.tbody ) { + + // String was a , *may* have spurious + elem = tag === "table" && !rtbody.test( elem ) ? + tmp.firstChild : + + // String was a bare or + wrap[1] === "
" && !rtbody.test( elem ) ? + tmp : + 0; + + j = elem && elem.childNodes.length; + while ( j-- ) { + if ( jQuery.nodeName( (tbody = elem.childNodes[j]), "tbody" ) && !tbody.childNodes.length ) { + elem.removeChild( tbody ); + } + } + } + + jQuery.merge( nodes, tmp.childNodes ); + + // Fix #12392 for WebKit and IE > 9 + tmp.textContent = ""; + + // Fix #12392 for oldIE + while ( tmp.firstChild ) { + tmp.removeChild( tmp.firstChild ); + } + + // Remember the top-level container for proper cleanup + tmp = safe.lastChild; + } + } + } + + // Fix #11356: Clear elements from fragment + if ( tmp ) { + safe.removeChild( tmp ); + } + + // Reset defaultChecked for any radios and checkboxes + // about to be appended to the DOM in IE 6/7 (#8060) + if ( !support.appendChecked ) { + jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked ); + } + + i = 0; + while ( (elem = nodes[ i++ ]) ) { + + // #4087 - If origin and destination elements are the same, and this is + // that element, do not do anything + if ( selection && jQuery.inArray( elem, selection ) !== -1 ) { + continue; + } + + contains = jQuery.contains( elem.ownerDocument, elem ); + + // Append to fragment + tmp = getAll( safe.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( contains ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( (elem = tmp[ j++ ]) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + tmp = null; + + return safe; + }, + + cleanData: function( elems, /* internal */ acceptData ) { + var elem, type, id, data, + i = 0, + internalKey = jQuery.expando, + cache = jQuery.cache, + deleteExpando = support.deleteExpando, + special = jQuery.event.special; + + for ( ; (elem = elems[i]) != null; i++ ) { + if ( acceptData || jQuery.acceptData( elem ) ) { + + id = elem[ internalKey ]; + data = id && cache[ id ]; + + if ( data ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Remove cache only if it was not already removed by jQuery.event.remove + if ( cache[ id ] ) { + + delete cache[ id ]; + + // IE does not allow us to delete expando properties from nodes, + // nor does it have a removeAttribute function on Document nodes; + // we must handle all of these cases + if ( deleteExpando ) { + delete elem[ internalKey ]; + + } else if ( typeof elem.removeAttribute !== strundefined ) { + elem.removeAttribute( internalKey ); + + } else { + elem[ internalKey ] = null; + } + + deletedIds.push( id ); + } + } + } + } + } +}); + +jQuery.fn.extend({ + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) ); + }, null, value, arguments.length ); + }, + + append: function() { + return this.domManip( arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + }); + }, + + prepend: function() { + return this.domManip( arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + }); + }, + + before: function() { + return this.domManip( arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + }); + }, + + after: function() { + return this.domManip( arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + }); + }, + + remove: function( selector, keepData /* Internal Use Only */ ) { + var elem, + elems = selector ? jQuery.filter( selector, this ) : this, + i = 0; + + for ( ; (elem = elems[i]) != null; i++ ) { + + if ( !keepData && elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem ) ); + } + + if ( elem.parentNode ) { + if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) { + setGlobalEval( getAll( elem, "script" ) ); + } + elem.parentNode.removeChild( elem ); + } + } + + return this; + }, + + empty: function() { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + } + + // Remove any remaining nodes + while ( elem.firstChild ) { + elem.removeChild( elem.firstChild ); + } + + // If this is a select, ensure that it displays empty (#12336) + // Support: IE<9 + if ( elem.options && jQuery.nodeName( elem, "select" ) ) { + elem.options.length = 0; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map(function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + }); + }, + + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; + + if ( value === undefined ) { + return elem.nodeType === 1 ? + elem.innerHTML.replace( rinlinejQuery, "" ) : + undefined; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + ( support.htmlSerialize || !rnoshimcache.test( value ) ) && + ( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) && + !wrapMap[ (rtagName.exec( value ) || [ "", "" ])[ 1 ].toLowerCase() ] ) { + + value = value.replace( rxhtmlTag, "<$1>" ); + + try { + for (; i < l; i++ ) { + // Remove element nodes and prevent memory leaks + elem = this[i] || {}; + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch(e) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var arg = arguments[ 0 ]; + + // Make the changes, replacing each context element with the new content + this.domManip( arguments, function( elem ) { + arg = this.parentNode; + + jQuery.cleanData( getAll( this ) ); + + if ( arg ) { + arg.replaceChild( elem, this ); + } + }); + + // Force removal if there was no new content (e.g., from empty arguments) + return arg && (arg.length || arg.nodeType) ? this : this.remove(); + }, + + detach: function( selector ) { + return this.remove( selector, true ); + }, + + domManip: function( args, callback ) { + + // Flatten any nested arrays + args = concat.apply( [], args ); + + var first, node, hasScripts, + scripts, doc, fragment, + i = 0, + l = this.length, + set = this, + iNoClone = l - 1, + value = args[0], + isFunction = jQuery.isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( isFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return this.each(function( index ) { + var self = set.eq( index ); + if ( isFunction ) { + args[0] = value.call( this, index, self.html() ); + } + self.domManip( args, callback ); + }); + } + + if ( l ) { + fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + if ( first ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( this[i], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !jQuery._data( node, "globalEval" ) && jQuery.contains( doc, node ) ) { + + if ( node.src ) { + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl ) { + jQuery._evalUrl( node.src ); + } + } else { + jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || "" ).replace( rcleanScript, "" ) ); + } + } + } + } + + // Fix #11809: Avoid leaking memory + fragment = first = null; + } + } + + return this; + } +}); + +jQuery.each({ + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + i = 0, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone(true); + jQuery( insert[i] )[ original ]( elems ); + + // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get() + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +}); + + +var iframe, + elemdisplay = {}; + +/** + * Retrieve the actual display of a element + * @param {String} name nodeName of the element + * @param {Object} doc Document object + */ +// Called only from within defaultDisplay +function actualDisplay( name, doc ) { + var style, + elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ), + + // getDefaultComputedStyle might be reliably used only on attached element + display = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ? + + // Use of this method is a temporary fix (more like optmization) until something better comes along, + // since it was removed from specification and supported only in FF + style.display : jQuery.css( elem[ 0 ], "display" ); + + // We don't have any data stored on the element, + // so use "detach" method as fast way to get rid of the element + elem.detach(); + + return display; +} + +/** + * Try to determine the default display value of an element + * @param {String} nodeName + */ +function defaultDisplay( nodeName ) { + var doc = document, + display = elemdisplay[ nodeName ]; + + if ( !display ) { + display = actualDisplay( nodeName, doc ); + + // If the simple way fails, read from inside an iframe + if ( display === "none" || !display ) { + + // Use the already-created iframe if possible + iframe = (iframe || jQuery( "