From f5d0c61b0d052072ed11c4f2700d9e7b3e001acb Mon Sep 17 00:00:00 2001 From: Paul Manias Date: Tue, 3 Dec 2024 19:20:26 +0000 Subject: [PATCH 1/9] [Build] ** Moved scripts/dev/ folder to tools/ --- CMakeLists.txt | 12 +++--- src/core/CMakeLists.txt | 4 +- {scripts/dev => tools}/flute.fluid | 0 {scripts/dev => tools}/hash.fluid | 0 .../dev => tools}/idl/common-graphics.fdl | 0 {scripts/dev => tools}/idl/common.fdl | 41 ++++++++++--------- {scripts/dev => tools}/idl/idl-c.fluid | 4 +- {scripts/dev => tools}/idl/idl-compile.fluid | 0 {scripts/dev => tools}/idl/idl-doc.fluid | 0 {scripts/dev => tools}/idl/idl-types.fluid | 0 {scripts/dev => tools}/parka.fluid | 0 {scripts/dev => tools}/rsakey.fluid | 0 12 files changed, 32 insertions(+), 29 deletions(-) rename {scripts/dev => tools}/flute.fluid (100%) rename {scripts/dev => tools}/hash.fluid (100%) rename {scripts/dev => tools}/idl/common-graphics.fdl (100%) rename {scripts/dev => tools}/idl/common.fdl (92%) rename {scripts/dev => tools}/idl/idl-c.fluid (99%) rename {scripts/dev => tools}/idl/idl-compile.fluid (100%) rename {scripts/dev => tools}/idl/idl-doc.fluid (100%) rename {scripts/dev => tools}/idl/idl-types.fluid (100%) rename {scripts/dev => tools}/parka.fluid (100%) rename {scripts/dev => tools}/rsakey.fluid (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index b8e5f3516..ed2cc7c75 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -152,9 +152,9 @@ int main() { find_program (XXD_CMD "xxd") find_program (PARASOL_CMD "parasol" NO_DEFAULT_PATH PATHS "${PARASOL_CMD_PATH}") -find_file (IDL_C_SCRIPT "idl-c.fluid" PATHS "${PROJECT_SOURCE_DIR}/scripts/dev/idl") -find_file (IDL_COMPILE_SCRIPT "idl-compile.fluid" PATHS "${PROJECT_SOURCE_DIR}/scripts/dev/idl") -find_file (FLUTE_SCRIPT "flute.fluid" PATHS "${PROJECT_SOURCE_DIR}/scripts/dev") +find_file (IDL_C_SCRIPT "idl-c.fluid" PATHS "${PROJECT_SOURCE_DIR}/tools/idl") +find_file (IDL_COMPILE_SCRIPT "idl-compile.fluid" PATHS "${PROJECT_SOURCE_DIR}/tools/idl") +find_file (FLUTE_SCRIPT "flute.fluid" PATHS "${PROJECT_SOURCE_DIR}/tools") if (PARASOL_CMD STREQUAL "PARASOL_CMD-NOTFOUND") message (STATUS "Definitions will not be built and tests are disabled.") @@ -171,15 +171,15 @@ if (BUILD_TESTS) endif () if (IDL_C_SCRIPT STREQUAL "IDL_C_SCRIPT-NOTFOUND") - message (FATAL_ERROR "The idl-c.fluid script was not found in ${PROJECT_SOURCE_DIR}/scripts/dev/idl") + message (FATAL_ERROR "The idl-c.fluid script was not found in ${PROJECT_SOURCE_DIR}/tools/idl") endif () if (IDL_COMPILE_SCRIPT STREQUAL "IDL_COMPILE_SCRIPT-NOTFOUND") - message (FATAL_ERROR "The idl-compile.fluid script was not found in ${PROJECT_SOURCE_DIR}/scripts/dev/idl") + message (FATAL_ERROR "The idl-compile.fluid script was not found in ${PROJECT_SOURCE_DIR}/tools/idl") endif () if (FLUTE_SCRIPT STREQUAL "FLUTE_SCRIPT-NOTFOUND") - message (FATAL_ERROR "The flute.fluid script was not found in ${PROJECT_SOURCE_DIR}/scripts/dev") + message (FATAL_ERROR "The flute.fluid script was not found in ${PROJECT_SOURCE_DIR}/tools") endif () if (NOT MSVC) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index aa527aa19..1d28f92ef 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -58,7 +58,7 @@ if (BUILD_DEFS) "${CMAKE_CURRENT_SOURCE_DIR}/defs/errors.fdl" "${CMAKE_CURRENT_SOURCE_DIR}/defs/registry.fdl" "${CMAKE_CURRENT_SOURCE_DIR}/defs/fields.fdl" - "${CMAKE_CURRENT_SOURCE_DIR}/../../scripts/dev/idl/common.fdl" + "${CMAKE_CURRENT_SOURCE_DIR}/../../tools/idl/common.fdl" ${FUNCTIONS} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMMENT "Producing definition files for the Core library" @@ -74,7 +74,7 @@ if (BUILD_DEFS) "${CMAKE_CURRENT_SOURCE_DIR}/defs/errors.fdl" "${CMAKE_CURRENT_SOURCE_DIR}/defs/registry.fdl" "${CMAKE_CURRENT_SOURCE_DIR}/defs/fields.fdl" - "${CMAKE_CURRENT_SOURCE_DIR}/../../scripts/dev/idl/common.fdl") + "${CMAKE_CURRENT_SOURCE_DIR}/../../tools/idl/common.fdl") add_dependencies (build_headers core_defs) endif () diff --git a/scripts/dev/flute.fluid b/tools/flute.fluid similarity index 100% rename from scripts/dev/flute.fluid rename to tools/flute.fluid diff --git a/scripts/dev/hash.fluid b/tools/hash.fluid similarity index 100% rename from scripts/dev/hash.fluid rename to tools/hash.fluid diff --git a/scripts/dev/idl/common-graphics.fdl b/tools/idl/common-graphics.fdl similarity index 100% rename from scripts/dev/idl/common-graphics.fdl rename to tools/idl/common-graphics.fdl diff --git a/scripts/dev/idl/common.fdl b/tools/idl/common.fdl similarity index 92% rename from scripts/dev/idl/common.fdl rename to tools/idl/common.fdl index 7191acadd..282f873d5 100644 --- a/scripts/dev/idl/common.fdl +++ b/tools/idl/common.fdl @@ -192,30 +192,33 @@ flags("JTYPE", { comment="JTYPE flags are used to categorise input types.", modu "REPEATED: Input is a repeated entry (i.e. user is holding down a button and a repetition timer is being triggered)", "DRAG_ITEM: This special flag is set by the input system if the pointer is click-dragging an object at the time of the event.") +flags("CON", { comment="Gamepad controller buttons.", module="core" }, + "GAMEPAD_S: South button (A)", + "GAMEPAD_E: East button (B)", + "GAMEPAD_W: West button (X)", + "GAMEPAD_N: North button (Y)", + "DPAD_UP: Directional pad up.", + "DPAD_DOWN: Directional pad down.", + "DPAD_LEFT: Directional pad left.", + "DPAD_RIGHT: Directional pad right.", + "START: Gamepad start button.", + "SELECT: Gamepad select or back button.", + "LEFT_BUMPER_1: Gamepad left-hand bumper 1 (top, primary).", + "LEFT_BUMPER_2: Gamepad left-hand bumper 2 (lower).", + "RIGHT_BUMPER_1: Gamepad right-hand bumper 1 (top, primary).", + "RIGHT_BUMPER_2: Gamepad right-hand bumper 2 (lower).") + enum("JET", { type="int", start=1, comment="JET constants are documented in GetInputEvent()", module="Core" }, - "DIGITAL_XY: Digital movement from a relative location. Value is +/- n, where n is the number of units moved horizontally. Mouse movement will normally exceed a value of 1, whereas gamepad movement is limited to a value of +/- 1 except in the case of successive presses.", - "BUTTON_1|LMB: Left mouse button, XBox A button, PS square button. Value is pressure sensitive, ranging between 0 - 1.0 (0 is released, 1.0 is fully depressed).", - "BUTTON_2|RMB: Right mouse button, XBox X button, PS cross button.", - "BUTTON_3|MMB: Middle mouse button, XBox Y button, PS triangle.", - "BUTTON_4: XBox B button, PS circle.", - "BUTTON_5: Left analog stick depressed.", - "BUTTON_6: Right analog stick depressed.", + "BUTTON_1|LMB: Left mouse button; XBox A button, PS square button. Value is pressure sensitive, ranging between 0 - 1.0 (0 is released, 1.0 is fully depressed).", + "BUTTON_2|RMB: Right mouse button; XBox X button, PS cross button.", + "BUTTON_3|MMB: Middle mouse button; XBox Y button, PS triangle.", + "BUTTON_4: Alt. mouse button 1; XBox B button, PS circle.", + "BUTTON_5: Alt. mouse button 2.", + "BUTTON_6: Non-specific button assignment.", "BUTTON_7: Non-specific button assignment.", "BUTTON_8: Non-specific button assignment.", "BUTTON_9: Non-specific button assignment.", "BUTTON_10: Non-specific button assignment.", - "TRIGGER_LEFT: Gamepad left-hand trigger - value is between 0 - 1.0 (0 is released, 1.0 is fully depressed).", - "TRIGGER_RIGHT: Gamepad right-hand trigger.", - "BUTTON_START: Gamepad start button - value is 0 or 1.", - "BUTTON_SELECT: Gamepad select button - value is 0 or 1.", - "LEFT_BUMPER_1: Gamepad left-hand bumper 1 (top) - pressure sensitive value from 0 - 1.0.", - "LEFT_BUMPER_2: Gamepad left-hand bumper 2 (lower) - pressure sensitive value from 0 - 1.0.", - "RIGHT_BUMPER_1: Gamepad right-hand bumper 1 (top) - pressure sensitive value from 0 - 1.0.", - "RIGHT_BUMPER_2: Gamepad right-hand bumper 2 (lower) - pressure sensitive value from 0 - 1.0.", - "ANALOG_XY: Position for the default analog control (on gamepads this is the left analog control). Analog values range between -1.0 and 1.0. A value of zero indicates that the control is at rest.", - "ANALOG_Z: 3D or yoke position for the default analog control. A negative value indicates that the control has been pulled out and a positive value indicates that it has been pushed in.", - "ANALOG2_XY: As for `ANALOG_XY`, this type covers a second analog stick if present.", - "ANALOG2_Z: As for `ANALOG_Z`, this type covers a second analog stick if present.", "WHEEL: Mouse wheel rotation - the value generally reflects the number of 'clicks' rotated on the wheel.", "WHEEL_TILT: Some mouse wheels can be tilted to the left or right. Ranges from -1.0 to +1.0", "PEN_TILT_XY: For pen-based input, this type indicates the vertical tilt of the pen device. A value of 0 indicates that the pen is laid flat with nib at the bottom, 0.5 is 90 degrees, 1.0 is laid flat with nib at the top.", diff --git a/scripts/dev/idl/idl-c.fluid b/tools/idl/idl-c.fluid similarity index 99% rename from scripts/dev/idl/idl-c.fluid rename to tools/idl/idl-c.fluid index 860049cde..424bb74aa 100644 --- a/scripts/dev/idl/idl-c.fluid +++ b/tools/idl/idl-c.fluid @@ -1,7 +1,7 @@ -- This program produces C++ headers, auto-generated values and documentation from Parasol FDL files. -- --- Usage: parasol sdk:scripts/dev/idl/idl-c.fluid src=source.fdl --- Example: parasol sdk:scripts/dev/idl/idl-c.fluid src=sdk:core/modules/core/core.fdl +-- Usage: parasol sdk:tools/idl/idl-c.fluid src=source.fdl +-- Example: parasol sdk:tools/idl/idl-c.fluid src=sdk:core/modules/core/core.fdl include 'core' include 'xml' diff --git a/scripts/dev/idl/idl-compile.fluid b/tools/idl/idl-compile.fluid similarity index 100% rename from scripts/dev/idl/idl-compile.fluid rename to tools/idl/idl-compile.fluid diff --git a/scripts/dev/idl/idl-doc.fluid b/tools/idl/idl-doc.fluid similarity index 100% rename from scripts/dev/idl/idl-doc.fluid rename to tools/idl/idl-doc.fluid diff --git a/scripts/dev/idl/idl-types.fluid b/tools/idl/idl-types.fluid similarity index 100% rename from scripts/dev/idl/idl-types.fluid rename to tools/idl/idl-types.fluid diff --git a/scripts/dev/parka.fluid b/tools/parka.fluid similarity index 100% rename from scripts/dev/parka.fluid rename to tools/parka.fluid diff --git a/scripts/dev/rsakey.fluid b/tools/rsakey.fluid similarity index 100% rename from scripts/dev/rsakey.fluid rename to tools/rsakey.fluid From 0eb2546781883ac1be4a4d78bf9f8907d07337f7 Mon Sep 17 00:00:00 2001 From: Paul Manias Date: Tue, 3 Dec 2024 20:03:39 +0000 Subject: [PATCH 2/9] Refactored the JTYPE flags; Created new CON flags for controllers --- docs/xml/modules/classes/surface.xml | 25 ++------ docs/xml/modules/classes/xml.xml | 2 +- docs/xml/modules/core.xml | 42 +++++++------ docs/xml/modules/display.xml | 25 ++------ include/parasol/modules/core.h | 83 ++++++++++++++----------- include/parasol/system/registry.h | 1 + src/core/defs/registry.fdl | 3 +- src/core/idl.h | 2 +- src/core/lib_fields_read.cpp | 10 +-- src/display/class_pointer.cpp | 8 --- src/display/class_surface/surface_def.c | 59 +++++++----------- src/display/display-driver.cpp | 34 ++-------- src/display/win32/windows.cpp | 10 +-- 13 files changed, 123 insertions(+), 181 deletions(-) diff --git a/docs/xml/modules/classes/surface.xml b/docs/xml/modules/classes/surface.xml index eda63c53e..75fc56bc5 100644 --- a/docs/xml/modules/classes/surface.xml +++ b/docs/xml/modules/classes/surface.xml @@ -984,36 +984,23 @@ the surface area first). The X, Y values are defined as absolute coordinates, relative to the top-left of the display. - As for ANALOG_XY, this type covers a second analog stick if present. - As for ANALOG_Z, this type covers a second analog stick if present. - Position for the default analog control (on gamepads this is the left analog control). Analog values range between -1.0 and 1.0. A value of zero indicates that the control is at rest. - 3D or yoke position for the default analog control. A negative value indicates that the control has been pulled out and a positive value indicates that it has been pushed in. - Left mouse button, XBox A button, PS square button. Value is pressure sensitive, ranging between 0 - 1.0 (0 is released, 1.0 is fully depressed). + Left mouse button; XBox A button, PS square button. Value is pressure sensitive, ranging between 0 - 1.0 (0 is released, 1.0 is fully depressed). Non-specific button assignment. - Right mouse button, XBox X button, PS cross button. - Middle mouse button, XBox Y button, PS triangle. - XBox B button, PS circle. - Left analog stick depressed. - Right analog stick depressed. + Right mouse button; XBox X button, PS cross button. + Middle mouse button; XBox Y button, PS triangle. + Alt. mouse button 1; XBox B button, PS circle. + Alt. mouse button 2. + Non-specific button assignment. Non-specific button assignment. Non-specific button assignment. Non-specific button assignment. - Gamepad select button - value is 0 or 1. - Gamepad start button - value is 0 or 1. This message is sent by the input system when the mouse pointer enters an area for the first time. The message value refers to the object ID of the container being monitored for movement. This message is sent by the input system when the mouse pointer leaves an area. The message value refers to the object ID of the container being monitored for movement. Controller tilted on the X/Y axis. Value indicates angle, -ve = left, +ve = right Controller is rising or falling. Value expressed as 'speed', - Digital movement from a relative location. Value is +/- n, where n is the number of units moved horizontally. Mouse movement will normally exceed a value of 1, whereas gamepad movement is limited to a value of +/- 1 except in the case of successive presses. Recently supplied input occurred at the edge of the display. - Gamepad left-hand bumper 1 (top) - pressure sensitive value from 0 - 1.0. - Gamepad left-hand bumper 2 (lower) - pressure sensitive value from 0 - 1.0. For pen-based input, this type indicates the vertical tilt of the pen device. A value of 0 indicates that the pen is laid flat with nib at the bottom, 0.5 is 90 degrees, 1.0 is laid flat with nib at the top. Amount of pressure applied, ranges from 0 (none) to 1.0 (normal) and possibly higher if user presses hard enough - Gamepad right-hand bumper 1 (top) - pressure sensitive value from 0 - 1.0. - Gamepad right-hand bumper 2 (lower) - pressure sensitive value from 0 - 1.0. - Gamepad left-hand trigger - value is between 0 - 1.0 (0 is released, 1.0 is fully depressed). - Gamepad right-hand trigger. Mouse wheel rotation - the value generally reflects the number of 'clicks' rotated on the wheel. Some mouse wheels can be tilted to the left or right. Ranges from -1.0 to +1.0 diff --git a/docs/xml/modules/classes/xml.xml b/docs/xml/modules/classes/xml.xml index 95c382e78..3192d5a58 100644 --- a/docs/xml/modules/classes/xml.xml +++ b/docs/xml/modules/classes/xml.xml @@ -8,7 +8,7 @@ XML Provides XML data management services. *.xml - XML File + Extendable Markup Language (XML) 1 0b88bfd6 ID_XML diff --git a/docs/xml/modules/core.xml b/docs/xml/modules/core.xml index 666e47f73..7cb7d740b 100644 --- a/docs/xml/modules/core.xml +++ b/docs/xml/modules/core.xml @@ -2105,6 +2105,23 @@ SetField(Object, FID_Statement|TSTR, "string"); Removes quotes from key values that are quote-encapsulated. + + Directional pad down. + Directional pad left. + Directional pad right. + Directional pad up. + East button (B) + North button (Y) + South button (A) + West button (X) + Gamepad left-hand bumper 1 (top, primary). + Gamepad left-hand bumper 2 (lower). + Gamepad right-hand bumper 1 (top, primary). + Gamepad right-hand bumper 2 (lower). + Gamepad select or back button. + Gamepad start button. + + Audio file data, recognised by the Sound class Document content (between XML tags) - sent by document objects only @@ -2333,36 +2350,23 @@ SetField(Object, FID_Statement|TSTR, "string"); The X, Y values are defined as absolute coordinates, relative to the top-left of the display. - As for ANALOG_XY, this type covers a second analog stick if present. - As for ANALOG_Z, this type covers a second analog stick if present. - Position for the default analog control (on gamepads this is the left analog control). Analog values range between -1.0 and 1.0. A value of zero indicates that the control is at rest. - 3D or yoke position for the default analog control. A negative value indicates that the control has been pulled out and a positive value indicates that it has been pushed in. - Left mouse button, XBox A button, PS square button. Value is pressure sensitive, ranging between 0 - 1.0 (0 is released, 1.0 is fully depressed). + Left mouse button; XBox A button, PS square button. Value is pressure sensitive, ranging between 0 - 1.0 (0 is released, 1.0 is fully depressed). Non-specific button assignment. - Right mouse button, XBox X button, PS cross button. - Middle mouse button, XBox Y button, PS triangle. - XBox B button, PS circle. - Left analog stick depressed. - Right analog stick depressed. + Right mouse button; XBox X button, PS cross button. + Middle mouse button; XBox Y button, PS triangle. + Alt. mouse button 1; XBox B button, PS circle. + Alt. mouse button 2. + Non-specific button assignment. Non-specific button assignment. Non-specific button assignment. Non-specific button assignment. - Gamepad select button - value is 0 or 1. - Gamepad start button - value is 0 or 1. This message is sent by the input system when the mouse pointer enters an area for the first time. The message value refers to the object ID of the container being monitored for movement. This message is sent by the input system when the mouse pointer leaves an area. The message value refers to the object ID of the container being monitored for movement. Controller tilted on the X/Y axis. Value indicates angle, -ve = left, +ve = right Controller is rising or falling. Value expressed as 'speed', - Digital movement from a relative location. Value is +/- n, where n is the number of units moved horizontally. Mouse movement will normally exceed a value of 1, whereas gamepad movement is limited to a value of +/- 1 except in the case of successive presses. Recently supplied input occurred at the edge of the display. - Gamepad left-hand bumper 1 (top) - pressure sensitive value from 0 - 1.0. - Gamepad left-hand bumper 2 (lower) - pressure sensitive value from 0 - 1.0. For pen-based input, this type indicates the vertical tilt of the pen device. A value of 0 indicates that the pen is laid flat with nib at the bottom, 0.5 is 90 degrees, 1.0 is laid flat with nib at the top. Amount of pressure applied, ranges from 0 (none) to 1.0 (normal) and possibly higher if user presses hard enough - Gamepad right-hand bumper 1 (top) - pressure sensitive value from 0 - 1.0. - Gamepad right-hand bumper 2 (lower) - pressure sensitive value from 0 - 1.0. - Gamepad left-hand trigger - value is between 0 - 1.0 (0 is released, 1.0 is fully depressed). - Gamepad right-hand trigger. Mouse wheel rotation - the value generally reflects the number of 'clicks' rotated on the wheel. Some mouse wheels can be tilted to the left or right. Ranges from -1.0 to +1.0 diff --git a/docs/xml/modules/display.xml b/docs/xml/modules/display.xml index 28c4b6457..485fbb4f7 100644 --- a/docs/xml/modules/display.xml +++ b/docs/xml/modules/display.xml @@ -1091,36 +1091,23 @@ Alpha = CFUnpackAlpha(Format,Colour) The X, Y values are defined as absolute coordinates, relative to the top-left of the display. - As for ANALOG_XY, this type covers a second analog stick if present. - As for ANALOG_Z, this type covers a second analog stick if present. - Position for the default analog control (on gamepads this is the left analog control). Analog values range between -1.0 and 1.0. A value of zero indicates that the control is at rest. - 3D or yoke position for the default analog control. A negative value indicates that the control has been pulled out and a positive value indicates that it has been pushed in. - Left mouse button, XBox A button, PS square button. Value is pressure sensitive, ranging between 0 - 1.0 (0 is released, 1.0 is fully depressed). + Left mouse button; XBox A button, PS square button. Value is pressure sensitive, ranging between 0 - 1.0 (0 is released, 1.0 is fully depressed). Non-specific button assignment. - Right mouse button, XBox X button, PS cross button. - Middle mouse button, XBox Y button, PS triangle. - XBox B button, PS circle. - Left analog stick depressed. - Right analog stick depressed. + Right mouse button; XBox X button, PS cross button. + Middle mouse button; XBox Y button, PS triangle. + Alt. mouse button 1; XBox B button, PS circle. + Alt. mouse button 2. + Non-specific button assignment. Non-specific button assignment. Non-specific button assignment. Non-specific button assignment. - Gamepad select button - value is 0 or 1. - Gamepad start button - value is 0 or 1. This message is sent by the input system when the mouse pointer enters an area for the first time. The message value refers to the object ID of the container being monitored for movement. This message is sent by the input system when the mouse pointer leaves an area. The message value refers to the object ID of the container being monitored for movement. Controller tilted on the X/Y axis. Value indicates angle, -ve = left, +ve = right Controller is rising or falling. Value expressed as 'speed', - Digital movement from a relative location. Value is +/- n, where n is the number of units moved horizontally. Mouse movement will normally exceed a value of 1, whereas gamepad movement is limited to a value of +/- 1 except in the case of successive presses. Recently supplied input occurred at the edge of the display. - Gamepad left-hand bumper 1 (top) - pressure sensitive value from 0 - 1.0. - Gamepad left-hand bumper 2 (lower) - pressure sensitive value from 0 - 1.0. For pen-based input, this type indicates the vertical tilt of the pen device. A value of 0 indicates that the pen is laid flat with nib at the bottom, 0.5 is 90 degrees, 1.0 is laid flat with nib at the top. Amount of pressure applied, ranges from 0 (none) to 1.0 (normal) and possibly higher if user presses hard enough - Gamepad right-hand bumper 1 (top) - pressure sensitive value from 0 - 1.0. - Gamepad right-hand bumper 2 (lower) - pressure sensitive value from 0 - 1.0. - Gamepad left-hand trigger - value is between 0 - 1.0 (0 is released, 1.0 is fully depressed). - Gamepad right-hand trigger. Mouse wheel rotation - the value generally reflects the number of 'clicks' rotated on the wheel. Some mouse wheels can be tilted to the left or right. Ranges from -1.0 to +1.0 diff --git a/include/parasol/modules/core.h b/include/parasol/modules/core.h index 62c45addf..8eb3905a6 100644 --- a/include/parasol/modules/core.h +++ b/include/parasol/modules/core.h @@ -347,47 +347,56 @@ enum class JTYPE : ULONG { DEFINE_ENUM_FLAG_OPERATORS(JTYPE) +// Gamepad controller buttons. + +enum class CON : ULONG { + NIL = 0, + GAMEPAD_S = 0x00000001, + GAMEPAD_E = 0x00000002, + GAMEPAD_W = 0x00000004, + GAMEPAD_N = 0x00000008, + DPAD_UP = 0x00000010, + DPAD_DOWN = 0x00000020, + DPAD_LEFT = 0x00000040, + DPAD_RIGHT = 0x00000080, + START = 0x00000100, + SELECT = 0x00000200, + LEFT_BUMPER_1 = 0x00000400, + LEFT_BUMPER_2 = 0x00000800, + RIGHT_BUMPER_1 = 0x00001000, + RIGHT_BUMPER_2 = 0x00002000, +}; + +DEFINE_ENUM_FLAG_OPERATORS(CON) + // JET constants are documented in GetInputEvent() enum class JET : LONG { NIL = 0, - DIGITAL_XY = 1, - BUTTON_1 = 2, - LMB = 2, - BUTTON_2 = 3, - RMB = 3, - BUTTON_3 = 4, - MMB = 4, - BUTTON_4 = 5, - BUTTON_5 = 6, - BUTTON_6 = 7, - BUTTON_7 = 8, - BUTTON_8 = 9, - BUTTON_9 = 10, - BUTTON_10 = 11, - TRIGGER_LEFT = 12, - TRIGGER_RIGHT = 13, - BUTTON_START = 14, - BUTTON_SELECT = 15, - LEFT_BUMPER_1 = 16, - LEFT_BUMPER_2 = 17, - RIGHT_BUMPER_1 = 18, - RIGHT_BUMPER_2 = 19, - ANALOG_XY = 20, - ANALOG_Z = 21, - ANALOG2_XY = 22, - ANALOG2_Z = 23, - WHEEL = 24, - WHEEL_TILT = 25, - PEN_TILT_XY = 26, - ABS_XY = 27, - CROSSED_IN = 28, - CROSSED_OUT = 29, - PRESSURE = 30, - DEVICE_TILT_XY = 31, - DEVICE_TILT_Z = 32, - DISPLAY_EDGE = 33, - END = 34, + BUTTON_1 = 1, + LMB = 1, + BUTTON_2 = 2, + RMB = 2, + BUTTON_3 = 3, + MMB = 3, + BUTTON_4 = 4, + BUTTON_5 = 5, + BUTTON_6 = 6, + BUTTON_7 = 7, + BUTTON_8 = 8, + BUTTON_9 = 9, + BUTTON_10 = 10, + WHEEL = 11, + WHEEL_TILT = 12, + PEN_TILT_XY = 13, + ABS_XY = 14, + CROSSED_IN = 15, + CROSSED_OUT = 16, + PRESSURE = 17, + DEVICE_TILT_XY = 18, + DEVICE_TILT_Z = 19, + DISPLAY_EDGE = 20, + END = 21, }; // Field descriptors. diff --git a/include/parasol/system/registry.h b/include/parasol/system/registry.h index 4a6b68dfd..33694fdf3 100644 --- a/include/parasol/system/registry.h +++ b/include/parasol/system/registry.h @@ -108,5 +108,6 @@ enum class CLASSID : ULONG { SPOTLIGHTFX = 0x9e7a51c1UL, SOURCEFX = 0x16f8c294UL, FILTEREFFECT = 0x79e93e58UL, + CONTROLLER = 0xbf67c809UL, }; diff --git a/src/core/defs/registry.fdl b/src/core/defs/registry.fdl index 727d251ec..dc1048509 100644 --- a/src/core/defs/registry.fdl +++ b/src/core/defs/registry.fdl @@ -104,5 +104,6 @@ header({ path="system/registry", copyright="Paul Manias 1996-2024" }, function() "REMAPFX", "SPOTLIGHTFX", "SOURCEFX", - "FILTEREFFECT") + "FILTEREFFECT", + "CONTROLLER") end) diff --git a/src/core/idl.h b/src/core/idl.h index 4648f3012..4ed3ef056 100644 --- a/src/core/idl.h +++ b/src/core/idl.h @@ -1 +1 @@ -char glIDL[] = { 115,46,73,110,112,117,116,69,118,101,110,116,58,112,78,101,120,116,58,73,110,112,117,116,69,118,101,110,116,44,100,86,97,108,117,101,44,120,84,105,109,101,115,116,97,109,112,44,108,82,101,99,105,112,105,101,110,116,73,68,44,108,79,118,101,114,73,68,44,100,65,98,115,88,44,100,65,98,115,89,44,100,88,44,100,89,44,108,68,101,118,105,99,101,73,68,44,108,84,121,112,101,44,108,70,108,97,103,115,44,108,77,97,115,107,10,115,46,100,99,82,101,113,117,101,115,116,58,108,73,116,101,109,44,99,80,114,101,102,101,114,101,110,99,101,91,52,93,10,115,46,100,99,65,117,100,105,111,58,108,83,105,122,101,44,108,70,111,114,109,97,116,10,115,46,100,99,75,101,121,69,110,116,114,121,58,108,70,108,97,103,115,44,108,86,97,108,117,101,44,120,84,105,109,101,115,116,97,109,112,44,108,85,110,105,99,111,100,101,10,115,46,100,99,68,101,118,105,99,101,73,110,112,117,116,58,100,86,97,108,117,101,115,91,50,93,44,120,84,105,109,101,115,116,97,109,112,44,108,68,101,118,105,99,101,73,68,44,108,70,108,97,103,115,44,108,84,121,112,101,10,115,46,68,97,116,101,84,105,109,101,58,119,89,101,97,114,44,99,77,111,110,116,104,44,99,68,97,121,44,99,72,111,117,114,44,99,77,105,110,117,116,101,44,99,83,101,99,111,110,100,44,99,84,105,109,101,90,111,110,101,10,115,46,72,83,86,58,100,72,117,101,44,100,83,97,116,117,114,97,116,105,111,110,44,100,86,97,108,117,101,44,100,65,108,112,104,97,10,115,46,70,82,71,66,58,102,82,101,100,44,102,71,114,101,101,110,44,102,66,108,117,101,44,102,65,108,112,104,97,10,115,46,82,71,66,56,58,117,99,82,101,100,44,117,99,71,114,101,101,110,44,117,99,66,108,117,101,44,117,99,65,108,112,104,97,10,115,46,82,71,66,49,54,58,117,119,82,101,100,44,117,119,71,114,101,101,110,44,117,119,66,108,117,101,44,117,119,65,108,112,104,97,10,115,46,82,71,66,51,50,58,117,108,82,101,100,44,117,108,71,114,101,101,110,44,117,108,66,108,117,101,44,117,108,65,108,112,104,97,10,115,46,82,71,66,80,97,108,101,116,116,101,58,108,65,109,116,67,111,108,111,117,114,115,44,101,67,111,108,58,82,71,66,56,91,50,53,54,93,10,115,46,67,111,108,111,117,114,70,111,114,109,97,116,58,117,99,82,101,100,83,104,105,102,116,44,117,99,71,114,101,101,110,83,104,105,102,116,44,117,99,66,108,117,101,83,104,105,102,116,44,117,99,65,108,112,104,97,83,104,105,102,116,44,117,99,82,101,100,77,97,115,107,44,117,99,71,114,101,101,110,77,97,115,107,44,117,99,66,108,117,101,77,97,115,107,44,117,99,65,108,112,104,97,77,97,115,107,44,117,99,82,101,100,80,111,115,44,117,99,71,114,101,101,110,80,111,115,44,117,99,66,108,117,101,80,111,115,44,117,99,65,108,112,104,97,80,111,115,44,117,99,66,105,116,115,80,101,114,80,105,120,101,108,10,115,46,67,108,105,112,82,101,99,116,97,110,103,108,101,58,108,76,101,102,116,44,108,84,111,112,44,108,82,105,103,104,116,44,108,66,111,116,116,111,109,10,115,46,69,100,103,101,115,58,108,76,101,102,116,44,108,84,111,112,44,108,82,105,103,104,116,44,108,66,111,116,116,111,109,10,115,46,79,98,106,101,99,116,83,105,103,110,97,108,58,111,79,98,106,101,99,116,10,115,46,70,117,110,99,116,105,111,110,70,105,101,108,100,58,115,78,97,109,101,44,117,108,84,121,112,101,10,115,46,70,117,110,99,116,105,111,110,58,112,65,100,100,114,101,115,115,44,115,78,97,109,101,44,112,65,114,103,115,58,70,117,110,99,116,105,111,110,70,105,101,108,100,10,115,46,70,105,101,108,100,65,114,114,97,121,58,115,78,97,109,101,44,112,71,101,116,70,105,101,108,100,44,112,83,101,116,70,105,101,108,100,44,109,65,114,103,44,117,108,70,108,97,103,115,10,115,46,70,105,101,108,100,68,101,102,58,115,78,97,109,101,44,108,86,97,108,117,101,10,115,46,83,121,115,116,101,109,83,116,97,116,101,58,115,80,108,97,116,102,111,114,109,44,108,67,111,110,115,111,108,101,70,68,44,108,83,116,97,103,101,10,115,46,85,110,105,116,58,100,86,97,108,117,101,44,117,108,84,121,112,101,10,115,46,65,99,116,105,111,110,65,114,114,97,121,58,112,82,111,117,116,105,110,101,44,108,65,99,116,105,111,110,67,111,100,101,10,115,46,65,99,116,105,111,110,84,97,98,108,101,58,117,108,72,97,115,104,44,108,83,105,122,101,44,115,78,97,109,101,44,112,65,114,103,115,58,70,117,110,99,116,105,111,110,70,105,101,108,100,10,115,46,67,104,105,108,100,69,110,116,114,121,58,108,79,98,106,101,99,116,73,68,44,117,108,67,108,97,115,115,73,68,10,115,46,77,101,115,115,97,103,101,58,120,84,105,109,101,44,108,85,73,68,44,108,84,121,112,101,44,108,83,105,122,101,10,115,46,77,101,109,73,110,102,111,58,112,83,116,97,114,116,44,108,79,98,106,101,99,116,73,68,44,117,108,83,105,122,101,44,108,70,108,97,103,115,44,108,77,101,109,111,114,121,73,68,44,119,65,99,99,101,115,115,67,111,117,110,116,10,115,46,67,111,109,112,114,101,115,115,105,111,110,70,101,101,100,98,97,99,107,58,108,70,101,101,100,98,97,99,107,73,68,44,108,73,110,100,101,120,44,115,80,97,116,104,44,115,68,101,115,116,44,120,80,114,111,103,114,101,115,115,44,120,79,114,105,103,105,110,97,108,83,105,122,101,44,120,67,111,109,112,114,101,115,115,101,100,83,105,122,101,44,119,89,101,97,114,44,119,77,111,110,116,104,44,119,68,97,121,44,119,72,111,117,114,44,119,77,105,110,117,116,101,44,119,83,101,99,111,110,100,10,115,46,67,111,109,112,114,101,115,115,101,100,73,116,101,109,58,120,79,114,105,103,105,110,97,108,83,105,122,101,44,120,67,111,109,112,114,101,115,115,101,100,83,105,122,101,44,112,78,101,120,116,58,67,111,109,112,114,101,115,115,101,100,73,116,101,109,44,115,80,97,116,104,44,108,80,101,114,109,105,115,115,105,111,110,115,44,108,85,115,101,114,73,68,44,108,71,114,111,117,112,73,68,44,108,79,116,104,101,114,115,73,68,44,108,70,108,97,103,115,44,101,67,114,101,97,116,101,100,58,68,97,116,101,84,105,109,101,44,101,77,111,100,105,102,105,101,100,58,68,97,116,101,84,105,109,101,10,115,46,70,105,108,101,73,110,102,111,58,120,83,105,122,101,44,120,84,105,109,101,83,116,97,109,112,44,112,78,101,120,116,58,70,105,108,101,73,110,102,111,44,115,78,97,109,101,44,108,70,108,97,103,115,44,108,80,101,114,109,105,115,115,105,111,110,115,44,108,85,115,101,114,73,68,44,108,71,114,111,117,112,73,68,44,101,67,114,101,97,116,101,100,58,68,97,116,101,84,105,109,101,44,101,77,111,100,105,102,105,101,100,58,68,97,116,101,84,105,109,101,10,115,46,68,105,114,73,110,102,111,58,112,73,110,102,111,58,70,105,108,101,73,110,102,111,10,115,46,70,105,108,101,70,101,101,100,98,97,99,107,58,120,83,105,122,101,44,120,80,111,115,105,116,105,111,110,44,115,80,97,116,104,44,115,68,101,115,116,44,108,70,101,101,100,98,97,99,107,73,68,44,99,82,101,115,101,114,118,101,100,91,51,50,93,10,115,46,70,105,101,108,100,58,109,65,114,103,44,112,71,101,116,86,97,108,117,101,44,112,83,101,116,86,97,108,117,101,44,112,87,114,105,116,101,86,97,108,117,101,44,115,78,97,109,101,44,117,108,70,105,101,108,100,73,68,44,117,119,79,102,102,115,101,116,44,117,119,73,110,100,101,120,44,117,108,70,108,97,103,115,10,99,46,65,67,58,65,99,116,105,118,97,116,101,61,48,120,50,44,67,108,101,97,114,61,48,120,52,44,67,108,105,112,98,111,97,114,100,61,48,120,50,100,44,67,111,112,121,68,97,116,97,61,48,120,55,44,68,97,116,97,70,101,101,100,61,48,120,56,44,68,101,97,99,116,105,118,97,116,101,61,48,120,57,44,68,105,115,97,98,108,101,61,48,120,50,102,44,68,114,97,103,68,114,111,112,61,48,120,49,48,44,68,114,97,119,61,48,120,97,44,69,78,68,61,48,120,51,49,44,69,110,97,98,108,101,61,48,120,54,44,70,108,117,115,104,61,48,120,98,44,70,111,99,117,115,61,48,120,99,44,70,114,101,101,61,48,120,100,44,70,114,101,101,87,97,114,110,105,110,103,61,48,120,53,44,71,101,116,75,101,121,61,48,120,102,44,72,105,100,101,61,48,120,49,49,44,73,110,105,116,61,48,120,49,50,44,76,111,99,107,61,48,120,49,51,44,76,111,115,116,70,111,99,117,115,61,48,120,49,52,44,77,111,118,101,61,48,120,49,53,44,77,111,118,101,84,111,66,97,99,107,61,48,120,49,54,44,77,111,118,101,84,111,70,114,111,110,116,61,48,120,49,55,44,77,111,118,101,84,111,80,111,105,110,116,61,48,120,50,51,44,78,101,119,67,104,105,108,100,61,48,120,49,56,44,78,101,119,79,98,106,101,99,116,61,48,120,49,97,44,78,101,119,79,119,110,101,114,61,48,120,49,57,44,78,101,119,80,108,97,99,101,109,101,110,116,61,48,120,51,48,44,78,101,120,116,61,48,120,50,57,44,80,114,101,118,61,48,120,50,97,44,81,117,101,114,121,61,48,120,49,99,44,82,101,97,100,61,48,120,49,100,44,82,101,100,105,109,101,110,115,105,111,110,61,48,120,51,44,82,101,100,111,61,48,120,49,98,44,82,101,102,114,101,115,104,61,48,120,50,101,44,82,101,110,97,109,101,61,48,120,49,101,44,82,101,115,101,116,61,48,120,49,102,44,82,101,115,105,122,101,61,48,120,50,48,44,83,97,118,101,73,109,97,103,101,61,48,120,50,49,44,83,97,118,101,83,101,116,116,105,110,103,115,61,48,120,101,44,83,97,118,101,84,111,79,98,106,101,99,116,61,48,120,50,50,44,83,101,101,107,61,48,120,50,52,44,83,101,116,70,105,101,108,100,61,48,120,50,99,44,83,101,116,75,101,121,61,48,120,50,53,44,83,104,111,119,61,48,120,50,54,44,83,105,103,110,97,108,61,48,120,49,44,85,110,100,111,61,48,120,50,55,44,85,110,108,111,99,107,61,48,120,50,56,44,87,114,105,116,101,61,48,120,50,98,10,99,46,65,76,73,71,78,58,66,79,84,84,79,77,61,48,120,50,48,44,67,69,78,84,69,82,61,48,120,99,44,72,79,82,73,90,79,78,84,65,76,61,48,120,52,44,76,69,70,84,61,48,120,49,44,77,73,68,68,76,69,61,48,120,99,44,82,73,71,72,84,61,48,120,50,44,84,79,80,61,48,120,49,48,44,86,69,82,84,73,67,65,76,61,48,120,56,10,99,46,67,67,70,58,65,85,68,73,79,61,48,120,56,48,44,67,79,77,77,65,78,68,61,48,120,49,44,68,65,84,65,61,48,120,49,48,48,44,70,73,76,69,83,89,83,84,69,77,61,48,120,50,44,71,82,65,80,72,73,67,83,61,48,120,52,44,71,85,73,61,48,120,56,44,73,79,61,48,120,49,48,44,77,73,83,67,61,48,120,50,48,48,44,77,85,76,84,73,77,69,68,73,65,61,48,120,56,48,48,44,78,69,84,87,79,82,75,61,48,120,52,48,48,44,83,89,83,84,69,77,61,48,120,50,48,44,84,79,79,76,61,48,120,52,48,10,99,46,67,70,58,68,69,70,76,65,84,69,61,48,120,51,44,71,90,73,80,61,48,120,49,44,90,76,73,66,61,48,120,50,10,99,46,67,76,70,58,73,78,72,69,82,73,84,95,76,79,67,65,76,61,48,120,49,44,78,79,95,79,87,78,69,82,83,72,73,80,61,48,120,50,10,99,46,67,76,73,80,77,79,68,69,58,67,79,80,89,61,48,120,50,44,67,85,84,61,48,120,49,44,80,65,83,84,69,61,48,120,52,10,99,46,67,77,70,58,65,80,80,76,89,95,83,69,67,85,82,73,84,89,61,48,120,50,48,44,67,82,69,65,84,69,95,70,73,76,69,61,48,120,52,44,78,69,87,61,48,120,50,44,78,79,95,76,73,78,75,83,61,48,120,49,48,44,80,65,83,83,87,79,82,68,61,48,120,49,44,82,69,65,68,95,79,78,76,89,61,48,120,56,10,99,46,67,78,70,58,65,85,84,79,95,83,65,86,69,61,48,120,50,44,78,69,87,61,48,120,56,44,79,80,84,73,79,78,65,76,95,70,73,76,69,83,61,48,120,52,44,83,84,82,73,80,95,81,85,79,84,69,83,61,48,120,49,10,99,46,68,65,84,65,58,65,85,68,73,79,61,48,120,53,44,67,79,78,84,69,78,84,61,48,120,98,44,68,69,86,73,67,69,95,73,78,80,85,84,61,48,120,51,44,70,73,76,69,61,48,120,97,44,73,77,65,71,69,61,48,120,55,44,73,78,80,85,84,95,82,69,65,68,89,61,48,120,99,44,82,65,87,61,48,120,50,44,82,69,67,69,73,80,84,61,48,120,57,44,82,69,67,79,82,68,61,48,120,54,44,82,69,81,85,69,83,84,61,48,120,56,44,84,69,88,84,61,48,120,49,44,88,77,76,61,48,120,52,10,99,46,68,69,86,73,67,69,58,66,79,79,75,77,65,82,75,61,48,120,52,48,48,48,48,44,67,79,77,80,65,67,84,95,68,73,83,67,61,48,120,49,44,70,73,88,69,68,61,48,120,56,48,48,48,44,70,76,79,80,80,89,95,68,73,83,75,61,48,120,52,44,72,65,82,68,95,68,73,83,75,61,48,120,50,44,77,69,77,79,82,89,61,48,120,49,48,48,48,44,77,79,68,69,77,61,48,120,50,48,48,48,44,78,69,84,87,79,82,75,61,48,120,56,48,44,80,82,73,78,84,69,82,61,48,120,50,48,48,44,80,82,73,78,84,69,82,95,51,68,61,48,120,49,48,48,48,48,44,82,69,65,68,61,48,120,56,44,82,69,77,79,86,65,66,76,69,61,48,120,50,48,44,82,69,77,79,86,69,65,66,76,69,61,48,120,50,48,44,83,67,65,78,78,69,82,61,48,120,52,48,48,44,83,67,65,78,78,69,82,95,51,68,61,48,120,50,48,48,48,48,44,83,79,70,84,87,65,82,69,61,48,120,52,48,44,84,65,80,69,61,48,120,49,48,48,44,84,69,77,80,79,82,65,82,89,61,48,120,56,48,48,44,85,83,66,61,48,120,52,48,48,48,44,87,82,73,84,69,61,48,120,49,48,10,99,46,68,77,70,58,70,73,88,69,68,95,67,69,78,84,69,82,95,88,61,48,120,49,48,48,48,48,48,44,70,73,88,69,68,95,67,69,78,84,69,82,95,89,61,48,120,50,48,48,48,48,48,44,70,73,88,69,68,95,68,69,80,84,72,61,48,120,49,48,48,48,44,70,73,88,69,68,95,72,69,73,71,72,84,61,48,120,49,48,48,44,70,73,88,69,68,95,82,65,68,73,85,83,95,88,61,48,120,50,48,48,48,48,44,70,73,88,69,68,95,82,65,68,73,85,83,95,89,61,48,120,50,48,48,48,48,48,48,44,70,73,88,69,68,95,87,73,68,84,72,61,48,120,50,48,48,44,70,73,88,69,68,95,88,61,48,120,52,44,70,73,88,69,68,95,88,95,79,70,70,83,69,84,61,48,120,52,48,44,70,73,88,69,68,95,89,61,48,120,56,44,70,73,88,69,68,95,89,95,79,70,70,83,69,84,61,48,120,56,48,44,70,73,88,69,68,95,90,61,48,120,52,48,48,48,44,83,67,65,76,69,68,95,67,69,78,84,69,82,95,88,61,48,120,52,48,48,48,48,44,83,67,65,76,69,68,95,67,69,78,84,69,82,95,89,61,48,120,56,48,48,48,48,44,83,67,65,76,69,68,95,68,69,80,84,72,61,48,120,50,48,48,48,44,83,67,65,76,69,68,95,72,69,73,71,72,84,61,48,120,52,48,48,44,83,67,65,76,69,68,95,82,65,68,73,85,83,95,88,61,48,120,49,48,48,48,48,44,83,67,65,76,69,68,95,82,65,68,73,85,83,95,89,61,48,120,49,48,48,48,48,48,48,44,83,67,65,76,69,68,95,87,73,68,84,72,61,48,120,56,48,48,44,83,67,65,76,69,68,95,88,61,48,120,49,44,83,67,65,76,69,68,95,88,95,79,70,70,83,69,84,61,48,120,49,48,44,83,67,65,76,69,68,95,89,61,48,120,50,44,83,67,65,76,69,68,95,89,95,79,70,70,83,69,84,61,48,120,50,48,44,83,67,65,76,69,68,95,90,61,48,120,56,48,48,48,44,83,84,65,84,85,83,95,67,72,65,78,71,69,95,72,61,48,120,52,48,48,48,48,48,44,83,84,65,84,85,83,95,67,72,65,78,71,69,95,86,61,48,120,56,48,48,48,48,48,10,99,46,68,82,76,58,68,79,87,78,61,48,120,49,44,69,65,83,84,61,48,120,50,44,76,69,70,84,61,48,120,51,44,78,79,82,84,72,61,48,120,48,44,78,79,82,84,72,95,69,65,83,84,61,48,120,52,44,78,79,82,84,72,95,87,69,83,84,61,48,120,53,44,82,73,71,72,84,61,48,120,50,44,83,79,85,84,72,61,48,120,49,44,83,79,85,84,72,95,69,65,83,84,61,48,120,54,44,83,79,85,84,72,95,87,69,83,84,61,48,120,55,44,85,80,61,48,120,48,44,87,69,83,84,61,48,120,51,10,99,46,69,68,71,69,58,65,76,76,61,48,120,102,102,44,66,79,84,84,79,77,61,48,120,56,44,66,79,84,84,79,77,95,76,69,70,84,61,48,120,52,48,44,66,79,84,84,79,77,95,82,73,71,72,84,61,48,120,56,48,44,76,69,70,84,61,48,120,50,44,82,73,71,72,84,61,48,120,52,44,84,79,80,61,48,120,49,44,84,79,80,95,76,69,70,84,61,48,120,49,48,44,84,79,80,95,82,73,71,72,84,61,48,120,50,48,10,99,46,69,82,70,58,78,111,116,105,102,105,101,100,61,48,120,52,48,48,48,48,48,48,48,10,99,46,69,82,82,58,65,99,99,101,115,115,77,101,109,111,114,121,61,48,120,52,98,44,65,99,99,101,115,115,79,98,106,101,99,116,61,48,120,53,51,44,65,99,99,101,115,115,83,101,109,97,112,104,111,114,101,61,48,120,55,51,44,65,99,116,105,118,97,116,101,61,48,120,52,50,44,65,100,100,67,108,97,115,115,61,48,120,52,49,44,65,108,108,111,99,77,101,109,111,114,121,61,48,120,53,52,44,65,108,108,111,99,83,101,109,97,112,104,111,114,101,61,48,120,55,50,44,65,108,114,101,97,100,121,68,101,102,105,110,101,100,61,48,120,98,54,44,65,108,114,101,97,100,121,76,111,99,107,101,100,61,48,120,57,99,44,65,114,103,115,61,48,120,49,52,44,65,114,114,97,121,70,117,108,108,61,48,120,50,100,44,66,117,102,102,101,114,79,118,101,114,102,108,111,119,61,48,120,53,99,44,66,117,115,121,61,48,120,56,98,44,67,97,110,99,101,108,108,101,100,61,48,120,51,44,67,97,114,100,82,101,97,100,101,114,85,110,97,118,97,105,108,97,98,108,101,61,48,120,57,102,44,67,97,114,100,82,101,97,100,101,114,85,110,107,110,111,119,110,61,48,120,57,100,44,67,111,109,112,114,101,115,115,105,111,110,61,48,120,97,100,44,67,111,110,110,101,99,116,105,111,110,65,98,111,114,116,101,100,61,48,120,56,99,44,67,111,110,110,101,99,116,105,111,110,82,101,102,117,115,101,100,61,48,120,56,51,44,67,111,110,115,116,114,97,105,110,116,86,105,111,108,97,116,105,111,110,61,48,120,56,56,44,67,111,110,116,105,110,117,101,61,48,120,53,44,67,111,114,101,86,101,114,115,105,111,110,61,48,120,50,54,44,67,114,101,97,116,101,70,105,108,101,61,48,120,55,52,44,67,114,101,97,116,101,79,98,106,101,99,116,61,48,120,54,53,44,67,114,101,97,116,101,82,101,115,111,117,114,99,101,61,48,120,98,50,44,68,97,116,97,83,105,122,101,61,48,120,56,97,44,68,101,97,99,116,105,118,97,116,101,100,61,48,120,57,97,44,68,101,97,100,76,111,99,107,61,48,120,51,101,44,68,101,99,111,109,112,114,101,115,115,105,111,110,61,48,120,97,99,44,68,101,108,101,116,101,70,105,108,101,61,48,120,55,53,44,68,105,114,69,109,112,116,121,61,48,120,56,44,68,105,115,99,111,110,110,101,99,116,101,100,61,48,120,56,54,44,68,111,78,111,116,69,120,112,117,110,103,101,61,48,120,51,48,44,68,111,101,115,78,111,116,69,120,105,115,116,61,48,120,55,56,44,68,111,117,98,108,101,73,110,105,116,61,48,120,52,51,44,68,114,97,119,61,48,120,52,56,44,69,78,68,61,48,120,98,101,44,69,109,112,116,121,83,116,114,105,110,103,61,48,120,54,100,44,69,110,100,79,102,70,105,108,101,61,48,120,55,101,44,69,110,116,114,121,77,105,115,115,105,110,103,72,101,97,100,101,114,61,48,120,51,97,44,69,120,97,109,105,110,101,70,97,105,108,101,100,61,48,120,49,57,44,69,120,99,101,112,116,105,111,110,61,48,120,97,51,44,69,120,99,101,112,116,105,111,110,84,104,114,101,115,104,111,108,100,61,48,120,57,44,69,120,99,108,117,115,105,118,101,68,101,110,105,101,100,61,48,120,53,51,44,69,120,101,99,86,105,111,108,97,116,105,111,110,61,48,120,56,102,44,69,120,105,115,116,115,61,48,120,55,97,44,69,120,112,101,99,116,101,100,70,105,108,101,61,48,120,54,102,44,69,120,112,101,99,116,101,100,70,111,108,100,101,114,61,48,120,97,101,44,70,97,105,108,101,100,61,48,120,100,44,70,97,108,115,101,61,48,120,49,44,70,105,101,108,100,78,111,116,83,101,116,61,48,120,52,52,44,70,105,101,108,100,83,101,97,114,99,104,61,48,120,51,50,44,70,105,101,108,100,84,121,112,101,77,105,115,109,97,116,99,104,61,48,120,53,97,44,70,105,108,101,61,48,120,101,44,70,105,108,101,68,111,101,115,78,111,116,69,120,105,115,116,61,48,120,49,50,44,70,105,108,101,69,120,105,115,116,115,61,48,120,54,51,44,70,105,108,101,78,111,116,70,111,117,110,100,61,48,120,49,50,44,70,105,108,101,82,101,97,100,70,108,97,103,61,48,120,52,54,44,70,105,108,101,87,114,105,116,101,70,108,97,103,61,48,120,52,55,44,70,105,110,105,115,104,101,100,61,48,120,55,101,44,70,117,110,99,116,105,111,110,61,48,120,98,53,44,71,101,116,70,105,101,108,100,61,48,120,53,54,44,71,101,116,83,117,114,102,97,99,101,73,110,102,111,61,48,120,55,100,44,72,111,115,116,78,111,116,70,111,117,110,100,61,48,120,56,49,44,72,111,115,116,85,110,114,101,97,99,104,97,98,108,101,61,48,120,56,53,44,73,100,101,110,116,105,99,97,108,80,97,116,104,115,61,48,120,55,57,44,73,108,108,101,103,97,108,65,99,116,105,111,110,65,116,116,101,109,112,116,61,48,120,51,57,44,73,108,108,101,103,97,108,65,99,116,105,111,110,73,68,61,48,120,51,55,44,73,108,108,101,103,97,108,65,100,100,114,101,115,115,61,48,120,57,49,44,73,108,108,101,103,97,108,77,101,116,104,111,100,73,68,61,48,120,51,54,44,73,109,109,117,116,97,98,108,101,61,48,120,97,102,44,73,110,85,115,101,61,48,120,99,44,73,110,105,116,61,48,120,50,49,44,73,110,105,116,77,111,100,117,108,101,61,48,120,49,49,44,73,110,112,117,116,79,117,116,112,117,116,61,48,120,57,52,44,73,110,116,101,103,114,105,116,121,86,105,111,108,97,116,105,111,110,61,48,120,56,56,44,73,110,118,97,108,105,100,68,97,116,97,61,48,120,102,44,73,110,118,97,108,105,100,68,105,109,101,110,115,105,111,110,61,48,120,53,57,44,73,110,118,97,108,105,100,72,84,84,80,82,101,115,112,111,110,115,101,61,48,120,97,49,44,73,110,118,97,108,105,100,72,97,110,100,108,101,61,48,120,57,54,44,73,110,118,97,108,105,100,79,98,106,101,99,116,61,48,120,56,101,44,73,110,118,97,108,105,100,80,97,116,104,61,48,120,51,51,44,73,110,118,97,108,105,100,82,101,102,101,114,101,110,99,101,61,48,120,97,50,44,73,110,118,97,108,105,100,83,116,97,116,101,61,48,120,56,48,44,73,110,118,97,108,105,100,85,82,73,61,48,120,56,50,44,73,110,118,97,108,105,100,86,97,108,117,101,61,48,120,57,56,44,76,105,109,105,116,101,100,83,117,99,99,101,115,115,61,48,120,50,44,76,105,115,116,67,104,105,108,100,114,101,110,61,48,120,54,97,44,76,111,97,100,77,111,100,117,108,101,61,48,120,57,53,44,76,111,99,107,61,48,120,49,56,44,76,111,99,107,70,97,105,108,101,100,61,48,120,49,56,44,76,111,99,107,77,117,116,101,120,61,48,120,97,97,44,76,111,99,107,82,101,113,117,105,114,101,100,61,48,120,57,98,44,76,111,99,107,101,100,61,48,120,57,99,44,76,111,111,112,61,48,120,54,50,44,76,111,115,116,67,108,97,115,115,61,48,120,49,97,44,76,111,115,116,79,119,110,101,114,61,48,120,50,102,44,76,111,119,67,97,112,97,99,105,116,121,61,48,120,50,48,44,77,97,114,107,101,100,70,111,114,68,101,108,101,116,105,111,110,61,48,120,51,53,44,77,101,109,111,114,121,61,48,120,49,100,44,77,101,109,111,114,121,67,111,114,114,117,112,116,61,48,120,51,49,44,77,101,109,111,114,121,68,111,101,115,78,111,116,69,120,105,115,116,61,48,120,51,100,44,77,101,109,111,114,121,73,110,102,111,61,48,120,54,54,44,77,105,115,109,97,116,99,104,61,48,120,53,101,44,77,105,115,115,105,110,103,67,108,97,115,115,61,48,120,52,53,44,77,105,115,115,105,110,103,67,108,97,115,115,78,97,109,101,61,48,120,50,97,44,77,105,115,115,105,110,103,80,97,116,104,61,48,120,52,99,44,77,111,100,117,108,101,73,110,105,116,70,97,105,108,101,100,61,48,120,51,99,44,77,111,100,117,108,101,77,105,115,115,105,110,103,73,110,105,116,61,48,120,51,98,44,77,111,100,117,108,101,77,105,115,115,105,110,103,78,97,109,101,61,48,120,52,48,44,77,111,100,117,108,101,79,112,101,110,70,97,105,108,101,100,61,48,120,51,56,44,78,101,101,100,79,119,110,101,114,61,48,120,50,52,44,78,101,101,100,87,105,100,116,104,72,101,105,103,104,116,61,48,120,50,55,44,78,101,103,97,116,105,118,101,67,108,97,115,115,73,68,61,48,120,50,57,44,78,101,103,97,116,105,118,101,83,117,98,67,108,97,115,115,73,68,61,48,120,50,56,44,78,101,116,119,111,114,107,85,110,114,101,97,99,104,97,98,108,101,61,48,120,56,52,44,78,101,119,79,98,106,101,99,116,61,48,120,53,53,44,78,111,65,99,116,105,111,110,61,48,120,49,98,44,78,111,68,97,116,97,61,48,120,49,53,44,78,111,70,105,101,108,100,65,99,99,101,115,115,61,48,120,53,55,44,78,111,77,97,116,99,104,105,110,103,79,98,106,101,99,116,61,48,120,52,97,44,78,111,77,101,100,105,97,73,110,115,101,114,116,101,100,61,48,120,57,101,44,78,111,77,101,109,111,114,121,61,48,120,97,44,78,111,77,101,116,104,111,100,115,61,48,120,52,57,44,78,111,80,101,114,109,105,115,115,105,111,110,61,48,120,50,50,44,78,111,80,111,105,110,116,101,114,61,48,120,98,44,78,111,83,101,97,114,99,104,82,101,115,117,108,116,61,48,120,52,101,44,78,111,83,116,97,116,115,61,48,120,49,102,44,78,111,83,117,112,112,111,114,116,61,48,120,49,99,44,78,111,116,70,111,117,110,100,61,48,120,49,48,44,78,111,116,73,110,105,116,105,97,108,105,115,101,100,61,48,120,54,55,44,78,111,116,76,111,99,107,101,100,61,48,120,52,100,44,78,111,116,80,111,115,115,105,98,108,101,61,48,120,98,51,44,78,111,116,104,105,110,103,68,111,110,101,61,48,120,52,44,78,111,116,105,102,105,101,100,61,48,120,52,48,48,48,48,48,48,48,44,78,117,108,108,65,114,103,115,61,48,120,56,100,44,79,98,106,101,99,116,67,111,114,114,117,112,116,61,48,120,53,48,44,79,98,106,101,99,116,69,120,105,115,116,115,61,48,120,54,101,44,79,98,115,111,108,101,116,101,61,48,120,98,49,44,79,98,116,97,105,110,77,101,116,104,111,100,61,48,120,50,99,44,79,107,97,121,61,48,120,48,44,79,112,101,110,70,105,108,101,61,48,120,55,54,44,79,112,101,110,71,76,61,48,120,97,53,44,79,117,116,79,102,66,111,117,110,100,115,61,48,120,53,102,44,79,117,116,79,102,68,97,116,97,61,48,120,55,101,44,79,117,116,79,102,82,97,110,103,101,61,48,120,50,98,44,79,117,116,79,102,83,112,97,99,101,61,48,120,55,99,44,79,117,116,115,105,100,101,77,97,105,110,84,104,114,101,97,100,61,48,120,97,54,44,79,119,110,101,114,78,101,101,100,115,66,105,116,109,97,112,61,48,120,50,53,44,79,119,110,101,114,80,97,115,115,84,104,114,111,117,103,104,61,48,120,53,49,44,80,101,114,109,105,115,115,105,111,110,68,101,110,105,101,100,61,48,120,50,50,44,80,101,114,109,105,115,115,105,111,110,115,61,48,120,50,50,44,80,114,111,120,121,83,83,76,84,117,110,110,101,108,61,48,120,97,48,44,81,117,101,114,121,61,48,120,50,101,44,82,101,97,100,61,48,120,49,54,44,82,101,97,100,70,105,108,101,84,111,66,117,102,102,101,114,61,48,120,98,48,44,82,101,97,100,79,110,108,121,61,48,120,55,55,44,82,101,97,108,108,111,99,77,101,109,111,114,121,61,48,120,54,49,44,82,101,99,117,114,115,105,111,110,61,48,120,57,48,44,82,101,100,105,109,101,110,115,105,111,110,61,48,120,55,49,44,82,101,102,114,101,115,104,61,48,120,54,57,44,82,101,115,105,122,101,61,48,120,55,48,44,82,101,115,111,108,118,101,80,97,116,104,61,48,120,54,52,44,82,101,115,111,108,118,101,83,121,109,98,111,108,61,48,120,98,52,44,82,101,115,111,117,114,99,101,69,120,105,115,116,115,61,48,120,54,56,44,82,101,116,114,121,61,48,120,55,44,83,97,110,105,116,121,70,97,105,108,117,114,101,61,48,120,55,98,44,83,99,104,101,109,97,86,105,111,108,97,116,105,111,110,61,48,120,56,57,44,83,101,97,114,99,104,61,48,120,49,48,44,83,101,99,117,114,105,116,121,61,48,120,57,55,44,83,101,101,107,61,48,120,54,48,44,83,101,114,118,105,99,101,85,110,97,118,97,105,108,97,98,108,101,61,48,120,57,57,44,83,101,116,70,105,101,108,100,61,48,120,51,52,44,83,101,116,86,97,108,117,101,78,111,116,65,114,114,97,121,61,48,120,98,99,44,83,101,116,86,97,108,117,101,78,111,116,70,117,110,99,116,105,111,110,61,48,120,98,97,44,83,101,116,86,97,108,117,101,78,111,116,76,111,111,107,117,112,61,48,120,98,100,44,83,101,116,86,97,108,117,101,78,111,116,78,117,109,101,114,105,99,61,48,120,98,55,44,83,101,116,86,97,108,117,101,78,111,116,79,98,106,101,99,116,61,48,120,98,57,44,83,101,116,86,97,108,117,101,78,111,116,80,111,105,110,116,101,114,61,48,120,98,98,44,83,101,116,86,97,108,117,101,78,111,116,83,116,114,105,110,103,61,48,120,98,56,44,83,101,116,86,111,108,117,109,101,61,48,120,97,98,44,83,107,105,112,61,48,120,54,44,83,109,97,108,108,77,97,115,107,61,48,120,54,99,44,83,116,97,116,101,109,101,110,116,85,110,115,97,116,105,115,102,105,101,100,61,48,120,52,102,44,83,116,114,105,110,103,70,111,114,109,97,116,61,48,120,55,102,44,83,121,110,116,97,120,61,48,120,55,102,44,83,121,115,116,101,109,67,97,108,108,61,48,120,54,98,44,83,121,115,116,101,109,67,111,114,114,117,112,116,61,48,120,50,51,44,83,121,115,116,101,109,76,111,99,107,101,100,61,48,120,51,102,44,84,97,115,107,83,116,105,108,108,69,120,105,115,116,115,61,48,120,56,55,44,84,101,114,109,105,110,97,116,101,61,48,120,57,44,84,104,114,101,97,100,65,108,114,101,97,100,121,65,99,116,105,118,101,61,48,120,97,52,44,84,104,114,101,97,100,78,111,116,76,111,99,107,101,100,61,48,120,97,57,44,84,105,109,101,79,117,116,61,48,120,49,101,44,84,114,117,101,61,48,120,48,44,85,110,98,97,108,97,110,99,101,100,88,77,76,61,48,120,57,50,44,85,110,100,101,102,105,110,101,100,70,105,101,108,100,61,48,120,52,52,44,85,110,114,101,99,111,103,110,105,115,101,100,70,105,101,108,100,84,121,112,101,61,48,120,53,98,44,85,110,115,117,112,112,111,114,116,101,100,70,105,101,108,100,61,48,120,53,100,44,85,110,115,117,112,112,111,114,116,101,100,79,119,110,101,114,61,48,120,53,50,44,85,115,101,83,117,98,67,108,97,115,115,61,48,120,97,55,44,86,105,114,116,117,97,108,86,111,108,117,109,101,61,48,120,53,56,44,87,111,117,108,100,66,108,111,99,107,61,48,120,57,51,44,87,114,105,116,101,61,48,120,49,55,44,87,114,111,110,103,67,108,97,115,115,61,48,120,56,101,44,87,114,111,110,103,79,98,106,101,99,116,84,121,112,101,61,48,120,56,101,44,87,114,111,110,103,84,121,112,101,61,48,120,97,56,44,87,114,111,110,103,86,101,114,115,105,111,110,61,48,120,49,51,10,99,46,69,86,71,58,65,78,68,82,79,73,68,61,48,120,100,44,65,80,80,61,48,120,99,44,65,85,68,73,79,61,48,120,56,44,67,76,65,83,83,61,48,120,98,44,68,73,83,80,76,65,89,61,48,120,53,44,69,78,68,61,48,120,101,44,70,73,76,69,83,89,83,84,69,77,61,48,120,49,44,71,85,73,61,48,120,52,44,72,65,82,68,87,65,82,69,61,48,120,55,44,73,79,61,48,120,54,44,78,69,84,87,79,82,75,61,48,120,50,44,80,79,87,69,82,61,48,120,97,44,83,89,83,84,69,77,61,48,120,51,44,85,83,69,82,61,48,120,57,10,99,46,70,66,75,58,67,79,80,89,95,70,73,76,69,61,48,120,50,44,68,69,76,69,84,69,95,70,73,76,69,61,48,120,51,44,77,79,86,69,95,70,73,76,69,61,48,120,49,10,99,46,70,68,58,65,76,76,79,67,61,48,120,50,48,44,65,82,82,65,89,61,48,120,49,48,48,48,44,65,82,82,65,89,83,73,90,69,61,48,120,56,48,44,66,85,70,70,69,82,61,48,120,50,48,48,44,66,85,70,83,73,90,69,61,48,120,56,48,44,66,89,84,69,61,48,120,49,48,48,48,48,48,48,44,67,80,80,61,48,120,52,48,48,48,44,67,85,83,84,79,77,61,48,120,56,48,48,48,44,68,79,85,66,76,69,61,48,120,56,48,48,48,48,48,48,48,44,68,79,85,66,76,69,82,69,83,85,76,84,61,48,120,56,48,48,48,48,49,48,48,44,69,82,82,79,82,61,48,120,56,48,48,44,70,76,65,71,83,61,48,120,52,48,44,70,76,79,65,84,61,48,120,49,48,48,48,48,48,48,48,44,70,85,78,67,84,73,79,78,61,48,120,50,48,48,48,48,48,48,44,70,85,78,67,84,73,79,78,80,84,82,61,48,120,97,48,48,48,48,48,48,44,73,61,48,120,52,48,48,44,73,78,73,84,61,48,120,52,48,48,44,76,65,82,71,69,61,48,120,52,48,48,48,48,48,48,44,76,65,82,71,69,82,69,83,85,76,84,61,48,120,52,48,48,48,49,48,48,44,76,79,67,65,76,61,48,120,50,44,76,79,78,71,61,48,120,52,48,48,48,48,48,48,48,44,76,79,78,71,82,69,83,85,76,84,61,48,120,52,48,48,48,48,49,48,48,44,76,79,79,75,85,80,61,48,120,56,48,44,79,66,74,69,67,84,61,48,120,49,44,79,66,74,69,67,84,73,68,61,48,120,52,48,48,48,48,48,48,49,44,79,66,74,69,67,84,80,84,82,61,48,120,56,48,48,48,48,48,49,44,80,79,73,78,84,69,82,61,48,120,56,48,48,48,48,48,48,44,80,82,73,86,65,84,69,61,48,120,49,48,48,48,48,44,80,84,82,61,48,120,56,48,48,48,48,48,48,44,80,84,82,66,85,70,70,69,82,61,48,120,56,48,48,48,50,48,48,44,80,84,82,82,69,83,85,76,84,61,48,120,56,48,48,48,49,48,48,44,80,84,82,83,73,90,69,61,48,120,56,48,44,80,84,82,95,68,79,85,66,76,69,82,69,83,85,76,84,61,48,120,56,56,48,48,48,49,48,48,44,80,84,82,95,76,65,82,71,69,82,69,83,85,76,84,61,48,120,99,48,48,48,49,48,48,44,80,84,82,95,76,79,78,71,82,69,83,85,76,84,61,48,120,52,56,48,48,48,49,48,48,44,82,61,48,120,49,48,48,44,82,69,65,68,61,48,120,49,48,48,44,82,69,83,79,85,82,67,69,61,48,120,50,48,48,48,44,82,69,83,85,76,84,61,48,120,49,48,48,44,82,71,66,61,48,120,56,48,48,48,48,44,82,73,61,48,120,53,48,48,44,82,87,61,48,120,51,48,48,44,83,67,65,76,69,68,61,48,120,50,48,48,48,48,48,44,83,84,82,61,48,120,56,48,48,48,48,48,44,83,84,82,73,78,71,61,48,120,56,48,48,48,48,48,44,83,84,82,82,69,83,85,76,84,61,48,120,56,48,48,49,48,48,44,83,84,82,85,67,84,61,48,120,49,48,44,83,89,78,79,78,89,77,61,48,120,50,48,48,48,48,44,83,89,83,84,69,77,61,48,120,49,48,48,48,48,44,84,65,71,83,61,48,120,52,48,48,44,85,78,73,84,61,48,120,50,48,48,48,48,48,48,48,44,85,78,83,73,71,78,69,68,61,48,120,52,48,48,48,48,44,86,65,82,84,65,71,83,61,48,120,52,48,44,86,73,82,84,85,65,76,61,48,120,56,44,86,79,73,68,61,48,120,48,44,86,79,76,65,84,73,76,69,61,48,120,48,44,87,61,48,120,50,48,48,44,87,79,82,68,61,48,120,52,48,48,48,48,48,44,87,82,73,84,69,61,48,120,50,48,48,10,99,46,70,68,66,58,67,79,77,80,82,69,83,83,95,70,73,76,69,61,48,120,50,44,68,69,67,79,77,80,82,69,83,83,95,70,73,76,69,61,48,120,49,44,68,69,67,79,77,80,82,69,83,83,95,79,66,74,69,67,84,61,48,120,52,44,82,69,77,79,86,69,95,70,73,76,69,61,48,120,51,10,99,46,70,68,76,58,70,69,69,68,66,65,67,75,61,48,120,49,10,99,46,70,68,84,58,65,67,67,69,83,83,69,68,61,48,120,50,44,65,82,67,72,73,86,69,68,61,48,120,51,44,67,82,69,65,84,69,68,61,48,120,49,44,77,79,68,73,70,73,69,68,61,48,120,48,10,99,46,70,70,82,58,65,66,79,82,84,61,48,120,50,44,67,79,78,84,73,78,85,69,61,48,120,48,44,79,75,65,89,61,48,120,48,44,83,75,73,80,61,48,120,49,10,99,46,70,76,58,65,80,80,82,79,88,73,77,65,84,69,61,48,120,49,48,44,66,85,70,70,69,82,61,48,120,52,48,44,68,69,86,73,67,69,61,48,120,52,48,48,44,68,73,82,69,67,84,79,82,89,61,48,120,56,44,69,88,67,76,85,68,69,95,70,73,76,69,83,61,48,120,49,48,48,48,44,69,88,67,76,85,68,69,95,70,79,76,68,69,82,83,61,48,120,50,48,48,48,44,70,73,76,69,61,48,120,49,48,48,44,70,79,76,68,69,82,61,48,120,56,44,76,73,78,75,61,48,120,50,48,44,76,79,79,80,61,48,120,56,48,44,78,69,87,61,48,120,50,44,82,69,65,68,61,48,120,52,44,82,69,83,69,84,95,68,65,84,69,61,48,120,50,48,48,44,83,84,82,69,65,77,61,48,120,56,48,48,44,87,82,73,84,69,61,48,120,49,10,99,46,70,79,70,58,83,77,65,82,84,95,78,65,77,69,83,61,48,120,49,10,99,46,73,68,84,89,80,69,58,70,85,78,67,84,73,79,78,61,48,120,51,44,71,76,79,66,65,76,61,48,120,50,44,77,69,83,83,65,71,69,61,48,120,49,10,99,46,74,69,84,58,65,66,83,95,88,89,61,48,120,49,98,44,65,78,65,76,79,71,50,95,88,89,61,48,120,49,54,44,65,78,65,76,79,71,50,95,90,61,48,120,49,55,44,65,78,65,76,79,71,95,88,89,61,48,120,49,52,44,65,78,65,76,79,71,95,90,61,48,120,49,53,44,66,85,84,84,79,78,95,49,61,48,120,50,44,66,85,84,84,79,78,95,49,48,61,48,120,98,44,66,85,84,84,79,78,95,50,61,48,120,51,44,66,85,84,84,79,78,95,51,61,48,120,52,44,66,85,84,84,79,78,95,52,61,48,120,53,44,66,85,84,84,79,78,95,53,61,48,120,54,44,66,85,84,84,79,78,95,54,61,48,120,55,44,66,85,84,84,79,78,95,55,61,48,120,56,44,66,85,84,84,79,78,95,56,61,48,120,57,44,66,85,84,84,79,78,95,57,61,48,120,97,44,66,85,84,84,79,78,95,83,69,76,69,67,84,61,48,120,102,44,66,85,84,84,79,78,95,83,84,65,82,84,61,48,120,101,44,67,82,79,83,83,69,68,95,73,78,61,48,120,49,99,44,67,82,79,83,83,69,68,95,79,85,84,61,48,120,49,100,44,68,69,86,73,67,69,95,84,73,76,84,95,88,89,61,48,120,49,102,44,68,69,86,73,67,69,95,84,73,76,84,95,90,61,48,120,50,48,44,68,73,71,73,84,65,76,95,88,89,61,48,120,49,44,68,73,83,80,76,65,89,95,69,68,71,69,61,48,120,50,49,44,69,78,68,61,48,120,50,50,44,76,69,70,84,95,66,85,77,80,69,82,95,49,61,48,120,49,48,44,76,69,70,84,95,66,85,77,80,69,82,95,50,61,48,120,49,49,44,76,77,66,61,48,120,50,44,77,77,66,61,48,120,52,44,80,69,78,95,84,73,76,84,95,88,89,61,48,120,49,97,44,80,82,69,83,83,85,82,69,61,48,120,49,101,44,82,73,71,72,84,95,66,85,77,80,69,82,95,49,61,48,120,49,50,44,82,73,71,72,84,95,66,85,77,80,69,82,95,50,61,48,120,49,51,44,82,77,66,61,48,120,51,44,84,82,73,71,71,69,82,95,76,69,70,84,61,48,120,99,44,84,82,73,71,71,69,82,95,82,73,71,72,84,61,48,120,100,44,87,72,69,69,76,61,48,120,49,56,44,87,72,69,69,76,95,84,73,76,84,61,48,120,49,57,10,99,46,74,84,89,80,69,58,65,78,65,76,79,71,61,48,120,50,48,44,65,78,67,72,79,82,69,68,61,48,120,50,44,66,85,84,84,79,78,61,48,120,56,48,44,67,82,79,83,83,73,78,71,61,48,120,56,44,68,66,76,95,67,76,73,67,75,61,48,120,50,48,48,44,68,73,71,73,84,65,76,61,48,120,49,48,44,68,82,65,71,71,69,68,61,48,120,52,44,68,82,65,71,95,73,84,69,77,61,48,120,56,48,48,44,69,88,84,95,77,79,86,69,77,69,78,84,61,48,120,52,48,44,77,79,86,69,77,69,78,84,61,48,120,49,48,48,44,82,69,80,69,65,84,69,68,61,48,120,52,48,48,44,83,69,67,79,78,68,65,82,89,61,48,120,49,10,99,46,75,69,89,58,65,61,48,120,49,44,65,80,79,83,84,82,79,80,72,69,61,48,120,50,98,44,65,84,61,48,120,56,97,44,66,61,48,120,50,44,66,65,67,75,61,48,120,56,54,44,66,65,67,75,83,80,65,67,69,61,48,120,54,57,44,66,65,67,75,95,83,76,65,83,72,61,48,120,50,102,44,66,82,69,65,75,61,48,120,55,98,44,67,61,48,120,51,44,67,65,76,76,61,48,120,56,55,44,67,65,77,69,82,65,61,48,120,56,57,44,67,65,78,67,69,76,61,48,120,55,97,44,67,65,80,83,95,76,79,67,75,61,48,120,52,54,44,67,76,69,65,82,61,48,120,54,101,44,67,79,77,77,65,61,48,120,50,99,44,68,61,48,120,52,44,68,69,76,69,84,69,61,48,120,54,100,44,68,79,84,61,48,120,50,100,44,68,79,87,78,61,48,120,54,49,44,69,61,48,120,53,44,69,73,71,72,84,61,48,120,50,50,44,69,78,68,61,48,120,55,50,44,69,78,68,95,67,65,76,76,61,48,120,56,56,44,69,78,84,69,82,61,48,120,54,98,44,69,81,85,65,76,83,61,48,120,50,55,44,69,83,67,65,80,69,61,48,120,54,99,44,69,88,69,67,85,84,69,61,48,120,55,52,44,70,61,48,120,54,44,70,49,61,48,120,52,99,44,70,49,48,61,48,120,53,53,44,70,49,49,61,48,120,53,54,44,70,49,50,61,48,120,53,55,44,70,49,51,61,48,120,53,56,44,70,49,52,61,48,120,53,57,44,70,49,53,61,48,120,53,97,44,70,49,54,61,48,120,53,98,44,70,49,55,61,48,120,53,99,44,70,49,56,61,48,120,56,48,44,70,49,57,61,48,120,56,49,44,70,50,61,48,120,52,100,44,70,50,48,61,48,120,56,50,44,70,51,61,48,120,52,101,44,70,52,61,48,120,52,102,44,70,53,61,48,120,53,48,44,70,54,61,48,120,53,49,44,70,55,61,48,120,53,50,44,70,56,61,48,120,53,51,44,70,57,61,48,120,53,52,44,70,73,78,68,61,48,120,55,57,44,70,73,86,69,61,48,120,49,102,44,70,79,82,87,65,82,68,61,48,120,57,48,44,70,79,85,82,61,48,120,49,101,44,71,61,48,120,55,44,72,61,48,120,56,44,72,69,76,80,61,48,120,52,51,44,72,79,77,69,61,48,120,54,102,44,73,61,48,120,57,44,73,78,83,69,82,84,61,48,120,55,53,44,74,61,48,120,97,44,75,61,48,120,98,44,76,61,48,120,99,44,76,69,70,84,61,48,120,54,51,44,76,69,78,83,95,70,79,67,85,83,61,48,120,56,99,44,76,69,83,83,95,71,82,69,65,84,69,82,61,48,120,53,102,44,76,73,83,84,95,69,78,68,61,48,120,57,54,44,76,95,65,76,84,61,48,120,52,56,44,76,95,67,79,77,77,65,78,68,61,48,120,52,97,44,76,95,67,79,78,84,82,79,76,61,48,120,52,49,44,76,95,83,72,73,70,84,61,48,120,52,52,44,76,95,83,81,85,65,82,69,61,48,120,50,56,44,77,61,48,120,100,44,77,65,67,82,79,61,48,120,53,100,44,77,69,78,85,61,48,120,55,56,44,77,73,78,85,83,61,48,120,50,54,44,77,85,84,69,61,48,120,57,50,44,78,61,48,120,101,44,78,69,88,84,61,48,120,56,101,44,78,73,78,69,61,48,120,50,51,44,78,80,95,48,61,48,120,51,49,44,78,80,95,49,61,48,120,51,50,44,78,80,95,50,61,48,120,51,51,44,78,80,95,51,61,48,120,51,52,44,78,80,95,52,61,48,120,51,53,44,78,80,95,53,61,48,120,51,54,44,78,80,95,54,61,48,120,51,55,44,78,80,95,55,61,48,120,51,56,44,78,80,95,56,61,48,120,51,57,44,78,80,95,57,61,48,120,51,97,44,78,80,95,66,65,82,61,48,120,51,100,44,78,80,95,68,69,67,73,77,65,76,61,48,120,51,102,44,78,80,95,68,73,86,73,68,69,61,48,120,52,48,44,78,80,95,68,79,84,61,48,120,51,102,44,78,80,95,69,78,84,69,82,61,48,120,55,101,44,78,80,95,77,73,78,85,83,61,48,120,51,101,44,78,80,95,77,85,76,84,73,80,76,89,61,48,120,51,98,44,78,80,95,80,76,85,83,61,48,120,51,99,44,78,80,95,80,76,85,83,95,77,73,78,85,83,61,48,120,53,101,44,78,80,95,83,69,80,65,82,65,84,79,82,61,48,120,51,100,44,78,85,77,95,76,79,67,75,61,48,120,55,99,44,79,61,48,120,102,44,79,78,69,61,48,120,49,98,44,80,61,48,120,49,48,44,80,65,71,69,95,68,79,87,78,61,48,120,55,49,44,80,65,71,69,95,85,80,61,48,120,55,48,44,80,65,85,83,69,61,48,120,54,53,44,80,69,82,73,79,68,61,48,120,50,100,44,80,76,65,89,61,48,120,57,53,44,80,76,85,83,61,48,120,56,98,44,80,79,85,78,68,61,48,120,57,52,44,80,79,87,69,82,61,48,120,54,56,44,80,82,69,86,73,79,85,83,61,48,120,56,102,44,80,82,73,78,84,61,48,120,52,55,44,80,82,84,95,83,67,82,61,48,120,55,100,44,81,61,48,120,49,49,44,82,61,48,120,49,50,44,82,69,68,79,61,48,120,55,55,44,82,69,86,69,82,83,69,95,81,85,79,84,69,61,48,120,50,53,44,82,69,87,73,78,68,61,48,120,57,49,44,82,73,71,72,84,61,48,120,54,50,44,82,95,65,76,84,61,48,120,52,57,44,82,95,67,79,77,77,65,78,68,61,48,120,52,98,44,82,95,67,79,78,84,82,79,76,61,48,120,52,50,44,82,95,83,72,73,70,84,61,48,120,52,53,44,82,95,83,81,85,65,82,69,61,48,120,50,57,44,83,61,48,120,49,51,44,83,67,82,95,76,79,67,75,61,48,120,54,52,44,83,69,76,69,67,84,61,48,120,55,51,44,83,69,77,73,95,67,79,76,79,78,61,48,120,50,97,44,83,69,86,69,78,61,48,120,50,49,44,83,73,88,61,48,120,50,48,44,83,76,65,83,72,61,48,120,50,101,44,83,76,69,69,80,61,48,120,54,55,44,83,80,65,67,69,61,48,120,51,48,44,83,84,65,82,61,48,120,57,51,44,83,84,79,80,61,48,120,56,100,44,83,89,83,82,81,61,48,120,55,102,44,84,61,48,120,49,52,44,84,65,66,61,48,120,54,97,44,84,72,82,69,69,61,48,120,49,100,44,84,87,79,61,48,120,49,99,44,85,61,48,120,49,53,44,85,78,68,79,61,48,120,55,54,44,85,80,61,48,120,54,48,44,86,61,48,120,49,54,44,86,79,76,85,77,69,95,68,79,87,78,61,48,120,56,53,44,86,79,76,85,77,69,95,85,80,61,48,120,56,52,44,87,61,48,120,49,55,44,87,65,75,69,61,48,120,54,54,44,87,73,78,95,67,79,78,84,82,79,76,61,48,120,56,51,44,88,61,48,120,49,56,44,89,61,48,120,49,57,44,90,61,48,120,49,97,44,90,69,82,79,61,48,120,50,52,10,99,46,75,81,58,65,76,84,61,48,120,54,48,44,65,76,84,71,82,61,48,120,52,48,44,67,65,80,83,95,76,79,67,75,61,48,120,52,44,67,79,77,77,65,78,68,61,48,120,49,56,48,44,67,79,78,84,82,79,76,61,48,120,49,56,44,67,84,82,76,61,48,120,49,56,44,68,69,65,68,95,75,69,89,61,48,120,49,48,48,48,48,44,73,78,70,79,61,48,120,51,99,48,52,44,73,78,83,84,82,85,67,84,73,79,78,95,75,69,89,83,61,48,120,55,56,44,76,95,65,76,84,61,48,120,50,48,44,76,95,67,79,77,77,65,78,68,61,48,120,56,48,44,76,95,67,79,78,84,82,79,76,61,48,120,56,44,76,95,67,84,82,76,61,48,120,56,44,76,95,83,72,73,70,84,61,48,120,49,44,78,79,84,95,80,82,73,78,84,65,66,76,69,61,48,120,50,48,48,48,44,78,85,77,95,76,79,67,75,61,48,120,56,48,48,48,44,78,85,77,95,80,65,68,61,48,120,50,48,48,44,80,82,69,83,83,69,68,61,48,120,49,48,48,48,44,81,85,65,76,73,70,73,69,82,83,61,48,120,49,102,98,44,82,69,76,69,65,83,69,68,61,48,120,56,48,48,44,82,69,80,69,65,84,61,48,120,52,48,48,44,82,95,65,76,84,61,48,120,52,48,44,82,95,67,79,77,77,65,78,68,61,48,120,49,48,48,44,82,95,67,79,78,84,82,79,76,61,48,120,49,48,44,82,95,67,84,82,76,61,48,120,49,48,44,82,95,83,72,73,70,84,61,48,120,50,44,83,67,82,95,76,79,67,75,61,48,120,52,48,48,48,44,83,72,73,70,84,61,48,120,51,44,87,73,78,95,67,79,78,84,82,79,76,61,48,120,50,48,48,48,48,10,99,46,76,65,89,79,85,84,58,66,65,67,75,71,82,79,85,78,68,61,48,120,56,44,69,77,66,69,68,68,69,68,61,48,120,50,48,44,70,79,82,69,71,82,79,85,78,68,61,48,120,49,48,44,73,71,78,79,82,69,95,67,85,82,83,79,82,61,48,120,56,48,44,76,69,70,84,61,48,120,50,44,76,79,67,75,61,48,120,52,48,44,82,73,71,72,84,61,48,120,52,44,83,81,85,65,82,69,61,48,120,48,44,84,73,71,72,84,61,48,120,49,44,84,73,76,69,61,48,120,49,48,48,44,87,73,68,69,61,48,120,54,10,99,46,76,68,70,58,67,72,69,67,75,95,69,88,73,83,84,83,61,48,120,49,10,99,46,76,79,67,58,68,73,82,69,67,84,79,82,89,61,48,120,49,44,70,73,76,69,61,48,120,51,44,70,79,76,68,69,82,61,48,120,49,44,86,79,76,85,77,69,61,48,120,50,10,99,46,77,65,88,58,70,73,76,69,78,65,77,69,61,48,120,49,48,48,44,78,65,77,69,95,76,69,78,61,48,120,49,102,10,99,46,77,69,77,58,65,85,68,73,79,61,48,120,56,44,67,65,76,76,69,82,61,48,120,56,48,48,48,48,48,44,67,79,68,69,61,48,120,49,48,44,67,79,76,76,69,67,84,61,48,120,49,48,48,48,44,68,65,84,65,61,48,120,48,44,69,88,67,76,85,83,73,86,69,61,48,120,56,48,48,44,72,73,68,68,69,78,61,48,120,49,48,48,48,48,48,44,77,65,78,65,71,69,68,61,48,120,49,44,78,79,95,66,76,79,67,75,61,48,120,50,48,48,48,44,78,79,95,66,76,79,67,75,73,78,71,61,48,120,50,48,48,48,44,78,79,95,67,76,69,65,82,61,48,120,52,48,48,48,48,44,78,79,95,76,79,67,75,61,48,120,52,48,48,44,78,79,95,80,79,79,76,61,48,120,50,48,44,79,66,74,69,67,84,61,48,120,50,48,48,44,82,69,65,68,61,48,120,49,48,48,48,48,44,82,69,65,68,95,87,82,73,84,69,61,48,120,51,48,48,48,48,44,83,84,82,73,78,71,61,48,120,49,48,48,44,84,69,88,84,85,82,69,61,48,120,52,44,84,77,80,95,76,79,67,75,61,48,120,52,48,44,85,78,84,82,65,67,75,69,68,61,48,120,56,48,44,86,73,68,69,79,61,48,120,50,44,87,82,73,84,69,61,48,120,50,48,48,48,48,10,99,46,77,70,70,58,65,84,84,82,73,66,61,48,120,50,48,44,67,76,79,83,69,68,61,48,120,56,48,44,67,82,69,65,84,69,61,48,120,52,44,68,69,69,80,61,48,120,49,48,48,48,44,68,69,76,69,84,69,61,48,120,56,44,70,73,76,69,61,48,120,52,48,48,44,70,79,76,68,69,82,61,48,120,50,48,48,44,77,79,68,73,70,89,61,48,120,50,44,77,79,86,69,68,61,48,120,49,48,44,79,80,69,78,69,68,61,48,120,52,48,44,82,69,65,68,61,48,120,49,44,82,69,78,65,77,69,61,48,120,49,48,44,83,69,76,70,61,48,120,56,48,48,44,85,78,77,79,85,78,84,61,48,120,49,48,48,44,87,82,73,84,69,61,48,120,50,10,99,46,77,72,70,58,68,69,70,65,85,76,84,61,48,120,50,44,83,84,65,84,73,67,61,48,120,49,44,83,84,82,85,67,84,85,82,69,61,48,120,50,10,99,46,77,79,70,58,76,73,78,75,95,76,73,66,82,65,82,89,61,48,120,49,44,83,84,65,84,73,67,61,48,120,50,44,83,89,83,84,69,77,95,80,82,79,66,69,61,48,120,52,10,99,46,77,79,86,69,58,65,76,76,61,48,120,102,44,68,79,87,78,61,48,120,49,44,76,69,70,84,61,48,120,52,44,82,73,71,72,84,61,48,120,56,44,85,80,61,48,120,50,10,99,46,77,83,70,58,65,68,68,61,48,120,56,44,65,68,68,82,69,83,83,61,48,120,49,48,44,77,69,83,83,65,71,69,95,73,68,61,48,120,50,48,44,78,79,95,68,85,80,76,73,67,65,84,69,61,48,120,52,44,85,80,68,65,84,69,61,48,120,50,44,87,65,73,84,61,48,120,49,10,99,46,77,83,71,73,68,58,65,67,84,73,79,78,61,48,120,54,51,44,66,82,69,65,75,61,48,120,54,52,44,67,79,77,77,65,78,68,61,48,120,54,53,44,67,79,82,69,95,69,78,68,61,48,120,54,52,44,68,69,66,85,71,61,48,120,53,102,44,69,86,69,78,84,61,48,120,53,101,44,70,82,69,69,61,48,120,54,50,44,81,85,73,84,61,48,120,51,101,56,44,84,72,82,69,65,68,95,65,67,84,73,79,78,61,48,120,53,98,44,84,72,82,69,65,68,95,67,65,76,76,66,65,67,75,61,48,120,53,99,44,86,65,76,73,68,65,84,69,95,80,82,79,67,69,83,83,61,48,120,53,100,44,87,65,73,84,95,70,79,82,95,79,66,74,69,67,84,83,61,48,120,53,97,10,99,46,77,84,70,58,65,78,73,77,61,48,120,56,44,82,69,76,65,84,73,86,69,61,48,120,49,48,44,88,61,48,120,49,44,89,61,48,120,50,44,90,61,48,120,52,10,99,46,78,69,84,77,83,71,58,69,78,68,61,48,120,49,44,83,84,65,82,84,61,48,120,48,10,99,46,78,70,58,67,79,76,76,69,67,84,61,48,120,56,48,44,70,82,69,69,61,48,120,49,48,44,70,82,69,69,95,79,78,95,85,78,76,79,67,75,61,48,120,56,44,73,78,73,84,73,65,76,73,83,69,68,61,48,120,50,44,76,79,67,65,76,61,48,120,52,44,77,69,83,83,65,71,69,61,48,120,50,48,48,44,78,65,77,69,61,48,120,56,48,48,48,48,48,48,48,44,80,82,73,86,65,84,69,61,48,120,48,44,82,69,67,76,65,83,83,69,68,61,48,120,49,48,48,44,83,73,71,78,65,76,76,69,68,61,48,120,52,48,48,44,83,85,80,80,82,69,83,83,95,76,79,71,61,48,120,52,48,44,84,73,77,69,82,95,83,85,66,61,48,120,50,48,44,85,78,73,81,85,69,61,48,120,52,48,48,48,48,48,48,48,44,85,78,84,82,65,67,75,69,68,61,48,120,49,10,99,46,79,80,70,58,65,82,71,83,61,48,120,52,48,44,68,69,84,65,73,76,61,48,120,52,44,69,82,82,79,82,61,48,120,56,48,44,77,65,88,95,68,69,80,84,72,61,48,120,50,44,77,79,68,85,76,69,95,80,65,84,72,61,48,120,52,48,48,44,79,80,84,73,79,78,83,61,48,120,49,44,80,82,73,86,73,76,69,71,69,68,61,48,120,49,48,48,44,82,79,79,84,95,80,65,84,72,61,48,120,56,48,48,44,83,67,65,78,95,77,79,68,85,76,69,83,61,48,120,49,48,48,48,44,83,72,79,87,95,69,82,82,79,82,83,61,48,120,50,48,44,83,72,79,87,95,73,79,61,48,120,49,48,44,83,72,79,87,95,77,69,77,79,82,89,61,48,120,56,44,83,89,83,84,69,77,95,80,65,84,72,61,48,120,50,48,48,10,99,46,80,69,82,77,73,84,58,65,76,76,95,68,69,76,69,84,69,61,48,120,56,56,56,44,65,76,76,95,69,88,69,67,61,48,120,52,52,52,44,65,76,76,95,82,69,65,68,61,48,120,49,49,49,44,65,76,76,95,87,82,73,84,69,61,48,120,50,50,50,44,65,82,67,72,73,86,69,61,48,120,50,48,48,48,44,68,69,76,69,84,69,61,48,120,56,44,69,86,69,82,89,79,78,69,95,65,67,67,69,83,83,61,48,120,102,102,102,44,69,86,69,82,89,79,78,69,95,68,69,76,69,84,69,61,48,120,56,56,56,44,69,86,69,82,89,79,78,69,95,69,88,69,67,61,48,120,52,52,52,44,69,86,69,82,89,79,78,69,95,82,69,65,68,61,48,120,49,49,49,44,69,86,69,82,89,79,78,69,95,82,69,65,68,87,82,73,84,69,61,48,120,51,51,51,44,69,86,69,82,89,79,78,69,95,87,82,73,84,69,61,48,120,50,50,50,44,69,88,69,67,61,48,120,52,44,71,82,79,85,80,61,48,120,102,48,44,71,82,79,85,80,73,68,61,48,120,49,48,48,48,48,44,71,82,79,85,80,95,68,69,76,69,84,69,61,48,120,56,48,44,71,82,79,85,80,95,69,88,69,67,61,48,120,52,48,44,71,82,79,85,80,95,82,69,65,68,61,48,120,49,48,44,71,82,79,85,80,95,87,82,73,84,69,61,48,120,50,48,44,72,73,68,68,69,78,61,48,120,49,48,48,48,44,73,78,72,69,82,73,84,61,48,120,50,48,48,48,48,44,78,69,84,87,79,82,75,61,48,120,56,48,48,48,48,44,79,70,70,76,73,78,69,61,48,120,52,48,48,48,48,44,79,84,72,69,82,83,61,48,120,102,48,48,44,79,84,72,69,82,83,95,68,69,76,69,84,69,61,48,120,56,48,48,44,79,84,72,69,82,83,95,69,88,69,67,61,48,120,52,48,48,44,79,84,72,69,82,83,95,82,69,65,68,61,48,120,49,48,48,44,79,84,72,69,82,83,95,87,82,73,84,69,61,48,120,50,48,48,44,80,65,83,83,87,79,82,68,61,48,120,52,48,48,48,44,82,69,65,68,61,48,120,49,44,85,83,69,82,61,48,120,102,44,85,83,69,82,73,68,61,48,120,56,48,48,48,44,85,83,69,82,95,69,88,69,67,61,48,120,52,44,85,83,69,82,95,82,69,65,68,61,48,120,49,44,85,83,69,82,95,87,82,73,84,69,61,48,120,50,44,87,82,73,84,69,61,48,120,50,10,99,46,80,77,70,58,83,89,83,84,69,77,95,78,79,95,66,82,69,65,75,61,48,120,49,10,99,46,80,84,67,58,67,82,79,83,83,72,65,73,82,61,48,120,97,44,67,85,83,84,79,77,61,48,120,49,55,44,68,69,70,65,85,76,84,61,48,120,49,44,68,82,65,71,71,65,66,76,69,61,48,120,49,56,44,69,78,68,61,48,120,49,57,44,72,65,78,68,61,48,120,49,48,44,72,65,78,68,95,76,69,70,84,61,48,120,49,49,44,72,65,78,68,95,82,73,71,72,84,61,48,120,49,50,44,73,78,86,73,83,73,66,76,69,61,48,120,49,54,44,77,65,71,78,73,70,73,69,82,61,48,120,102,44,78,79,95,67,72,65,78,71,69,61,48,120,48,44,80,65,73,78,84,66,82,85,83,72,61,48,120,49,52,44,83,73,90,69,95,66,79,84,84,79,77,61,48,120,57,44,83,73,90,69,95,66,79,84,84,79,77,95,76,69,70,84,61,48,120,50,44,83,73,90,69,95,66,79,84,84,79,77,95,82,73,71,72,84,61,48,120,51,44,83,73,90,69,95,76,69,70,84,61,48,120,54,44,83,73,90,69,95,82,73,71,72,84,61,48,120,55,44,83,73,90,69,95,84,79,80,61,48,120,56,44,83,73,90,69,95,84,79,80,95,76,69,70,84,61,48,120,52,44,83,73,90,69,95,84,79,80,95,82,73,71,72,84,61,48,120,53,44,83,73,90,73,78,71,61,48,120,99,44,83,76,69,69,80,61,48,120,98,44,83,80,76,73,84,95,72,79,82,73,90,79,78,84,65,76,61,48,120,101,44,83,80,76,73,84,95,86,69,82,84,73,67,65,76,61,48,120,100,44,83,84,79,80,61,48,120,49,53,44,84,69,88,84,61,48,120,49,51,10,99,46,82,68,70,58,65,82,67,72,73,86,69,61,48,120,50,48,48,48,44,68,65,84,69,61,48,120,50,44,70,73,76,69,61,48,120,56,44,70,73,76,69,83,61,48,120,56,44,70,79,76,68,69,82,61,48,120,49,48,44,70,79,76,68,69,82,83,61,48,120,49,48,44,72,73,68,68,69,78,61,48,120,49,48,48,44,76,73,78,75,61,48,120,52,48,44,79,80,69,78,68,73,82,61,48,120,52,48,48,48,44,80,69,82,77,73,83,83,73,79,78,83,61,48,120,52,44,81,85,65,76,73,70,73,69,68,61,48,120,50,48,48,44,81,85,65,76,73,70,89,61,48,120,50,48,48,44,82,69,65,68,95,65,76,76,61,48,120,49,102,44,82,69,65,68,95,79,78,76,89,61,48,120,49,48,48,48,44,83,73,90,69,61,48,120,49,44,83,84,82,69,65,77,61,48,120,56,48,48,44,84,65,71,83,61,48,120,56,48,44,84,73,77,69,61,48,120,50,44,86,73,82,84,85,65,76,61,48,120,52,48,48,44,86,79,76,85,77,69,61,48,120,50,48,10,99,46,82,69,83,58,67,79,78,83,79,76,69,95,70,68,61,48,120,50,44,67,79,82,69,95,73,68,76,61,48,120,56,44,67,80,85,95,83,80,69,69,68,61,48,120,49,54,44,68,73,83,80,76,65,89,95,68,82,73,86,69,82,61,48,120,53,44,69,88,67,69,80,84,73,79,78,95,72,65,78,68,76,69,82,61,48,120,49,49,44,70,82,69,69,95,77,69,77,79,82,89,61,48,120,49,55,44,70,82,69,69,95,83,87,65,80,61,48,120,49,44,74,78,73,95,69,78,86,61,48,120,101,44,75,69,89,95,83,84,65,84,69,61,48,120,51,44,76,79,71,95,68,69,80,84,72,61,48,120,100,44,76,79,71,95,76,69,86,69,76,61,48,120,97,44,77,65,88,95,80,82,79,67,69,83,83,69,83,61,48,120,99,44,78,69,84,95,80,82,79,67,69,83,83,73,78,71,61,48,120,49,50,44,79,80,69,78,95,73,78,70,79,61,48,120,49,48,44,80,82,73,86,73,76,69,71,69,68,61,48,120,55,44,80,82,73,86,73,76,69,71,69,68,95,85,83,69,82,61,48,120,54,44,80,82,79,67,69,83,83,95,83,84,65,84,69,61,48,120,49,51,44,83,84,65,84,73,67,95,66,85,73,76,68,61,48,120,57,44,84,72,82,69,65,68,95,73,68,61,48,120,102,44,84,79,84,65,76,95,77,69,77,79,82,89,61,48,120,49,52,44,84,79,84,65,76,95,83,72,65,82,69,68,95,77,69,77,79,82,89,61,48,120,98,44,84,79,84,65,76,95,83,87,65,80,61,48,120,49,53,44,85,83,69,82,95,73,68,61,48,120,52,10,99,46,82,70,68,58,65,76,76,79,87,95,82,69,67,85,82,83,73,79,78,61,48,120,50,48,44,65,76,87,65,89,83,95,67,65,76,76,61,48,120,49,48,48,44,69,88,67,69,80,84,61,48,120,50,44,82,69,65,68,61,48,120,52,44,82,69,67,65,76,76,61,48,120,56,48,44,82,69,77,79,86,69,61,48,120,56,44,83,79,67,75,69,84,61,48,120,52,48,44,83,84,79,80,95,82,69,67,85,82,83,69,61,48,120,49,48,44,87,82,73,84,69,61,48,120,49,10,99,46,82,80,58,77,79,68,85,76,69,95,80,65,84,72,61,48,120,49,44,82,79,79,84,95,80,65,84,72,61,48,120,51,44,83,89,83,84,69,77,95,80,65,84,72,61,48,120,50,10,99,46,82,83,70,58,65,80,80,82,79,88,73,77,65,84,69,61,48,120,52,44,67,65,83,69,95,83,69,78,83,73,84,73,86,69,61,48,120,50,48,44,67,72,69,67,75,95,86,73,82,84,85,65,76,61,48,120,50,44,78,79,95,68,69,69,80,95,83,67,65,78,61,48,120,56,44,78,79,95,70,73,76,69,95,67,72,69,67,75,61,48,120,49,44,80,65,84,72,61,48,120,49,48,10,99,46,83,67,70,58,69,88,73,84,95,79,78,95,69,82,82,79,82,61,48,120,49,44,76,79,71,95,65,76,76,61,48,120,50,10,99,46,83,69,69,75,58,67,85,82,82,69,78,84,61,48,120,49,44,69,78,68,61,48,120,50,44,82,69,76,65,84,73,86,69,61,48,120,51,44,83,84,65,82,84,61,48,120,48,10,99,46,83,84,82,58,67,65,83,69,61,48,120,49,44,77,65,84,67,72,95,67,65,83,69,61,48,120,49,44,77,65,84,67,72,95,76,69,78,61,48,120,50,10,99,46,83,84,84,58,70,76,79,65,84,61,48,120,50,44,72,69,88,61,48,120,51,44,78,85,77,66,69,82,61,48,120,49,44,83,84,82,73,78,71,61,48,120,52,10,99,46,84,72,70,58,65,85,84,79,95,70,82,69,69,61,48,120,49,10,99,46,84,79,73,58,65,78,68,82,79,73,68,95,65,83,83,69,84,77,71,82,61,48,120,52,44,65,78,68,82,79,73,68,95,67,76,65,83,83,61,48,120,51,44,65,78,68,82,79,73,68,95,69,78,86,61,48,120,50,44,76,79,67,65,76,95,67,65,67,72,69,61,48,120,48,44,76,79,67,65,76,95,83,84,79,82,65,71,69,61,48,120,49,10,99,46,84,83,70,58,65,84,84,65,67,72,69,68,61,48,120,49,48,48,44,68,69,84,65,67,72,69,68,61,48,120,56,48,44,70,79,82,69,73,71,78,61,48,120,49,44,76,79,71,95,65,76,76,61,48,120,50,48,44,80,73,80,69,61,48,120,50,48,48,44,80,82,73,86,73,76,69,71,69,68,61,48,120,56,44,81,85,73,69,84,61,48,120,52,48,44,82,69,83,69,84,95,80,65,84,72,61,48,120,52,44,83,72,69,76,76,61,48,120,49,48,44,87,65,73,84,61,48,120,50,10,99,46,84,83,84,65,84,69,58,80,65,85,83,69,68,61,48,120,49,44,82,85,78,78,73,78,71,61,48,120,48,44,83,84,79,80,80,73,78,71,61,48,120,50,44,84,69,82,77,73,78,65,84,69,68,61,48,120,51,10,99,46,86,65,83,58,67,65,83,69,95,83,69,78,83,73,84,73,86,69,61,48,120,102,44,67,76,79,83,69,95,68,73,82,61,48,120,54,44,67,82,69,65,84,69,95,76,73,78,75,61,48,120,49,49,44,68,69,76,69,84,69,61,48,120,51,44,68,69,82,69,71,73,83,84,69,82,61,48,120,49,44,68,82,73,86,69,82,95,83,73,90,69,61,48,120,49,50,44,71,69,84,95,68,69,86,73,67,69,95,73,78,70,79,61,48,120,98,44,71,69,84,95,73,78,70,79,61,48,120,97,44,73,68,69,78,84,73,70,89,95,70,73,76,69,61,48,120,99,44,73,71,78,79,82,69,95,70,73,76,69,61,48,120,57,44,77,65,75,69,95,68,73,82,61,48,120,100,44,79,80,69,78,95,68,73,82,61,48,120,53,44,82,69,65,68,95,76,73,78,75,61,48,120,49,48,44,82,69,78,65,77,69,61,48,120,52,44,83,65,77,69,95,70,73,76,69,61,48,120,101,44,83,67,65,78,95,68,73,82,61,48,120,50,44,84,69,83,84,95,80,65,84,72,61,48,120,55,44,87,65,84,67,72,95,80,65,84,72,61,48,120,56,10,99,46,86,76,70,58,65,80,73,61,48,120,50,48,44,66,82,65,78,67,72,61,48,120,49,44,67,82,73,84,73,67,65,76,61,48,120,56,44,68,69,84,65,73,76,61,48,120,52,48,44,69,82,82,79,82,61,48,120,50,44,70,85,78,67,84,73,79,78,61,48,120,49,48,48,44,73,78,70,79,61,48,120,49,48,44,84,82,65,67,69,61,48,120,56,48,44,87,65,82,78,73,78,71,61,48,120,52,10,99,46,86,79,76,85,77,69,58,72,73,68,68,69,78,61,48,120,52,44,80,82,73,79,82,73,84,89,61,48,120,50,44,82,69,80,76,65,67,69,61,48,120,49,44,83,89,83,84,69,77,61,48,120,56,10,0 }; +char glIDL[] = { 115,46,73,110,112,117,116,69,118,101,110,116,58,112,78,101,120,116,58,73,110,112,117,116,69,118,101,110,116,44,100,86,97,108,117,101,44,120,84,105,109,101,115,116,97,109,112,44,108,82,101,99,105,112,105,101,110,116,73,68,44,108,79,118,101,114,73,68,44,100,65,98,115,88,44,100,65,98,115,89,44,100,88,44,100,89,44,108,68,101,118,105,99,101,73,68,44,108,84,121,112,101,44,108,70,108,97,103,115,44,108,77,97,115,107,10,115,46,100,99,82,101,113,117,101,115,116,58,108,73,116,101,109,44,99,80,114,101,102,101,114,101,110,99,101,91,52,93,10,115,46,100,99,65,117,100,105,111,58,108,83,105,122,101,44,108,70,111,114,109,97,116,10,115,46,100,99,75,101,121,69,110,116,114,121,58,108,70,108,97,103,115,44,108,86,97,108,117,101,44,120,84,105,109,101,115,116,97,109,112,44,108,85,110,105,99,111,100,101,10,115,46,100,99,68,101,118,105,99,101,73,110,112,117,116,58,100,86,97,108,117,101,115,91,50,93,44,120,84,105,109,101,115,116,97,109,112,44,108,68,101,118,105,99,101,73,68,44,108,70,108,97,103,115,44,108,84,121,112,101,10,115,46,68,97,116,101,84,105,109,101,58,119,89,101,97,114,44,99,77,111,110,116,104,44,99,68,97,121,44,99,72,111,117,114,44,99,77,105,110,117,116,101,44,99,83,101,99,111,110,100,44,99,84,105,109,101,90,111,110,101,10,115,46,72,83,86,58,100,72,117,101,44,100,83,97,116,117,114,97,116,105,111,110,44,100,86,97,108,117,101,44,100,65,108,112,104,97,10,115,46,70,82,71,66,58,102,82,101,100,44,102,71,114,101,101,110,44,102,66,108,117,101,44,102,65,108,112,104,97,10,115,46,82,71,66,56,58,117,99,82,101,100,44,117,99,71,114,101,101,110,44,117,99,66,108,117,101,44,117,99,65,108,112,104,97,10,115,46,82,71,66,49,54,58,117,119,82,101,100,44,117,119,71,114,101,101,110,44,117,119,66,108,117,101,44,117,119,65,108,112,104,97,10,115,46,82,71,66,51,50,58,117,108,82,101,100,44,117,108,71,114,101,101,110,44,117,108,66,108,117,101,44,117,108,65,108,112,104,97,10,115,46,82,71,66,80,97,108,101,116,116,101,58,108,65,109,116,67,111,108,111,117,114,115,44,101,67,111,108,58,82,71,66,56,91,50,53,54,93,10,115,46,67,111,108,111,117,114,70,111,114,109,97,116,58,117,99,82,101,100,83,104,105,102,116,44,117,99,71,114,101,101,110,83,104,105,102,116,44,117,99,66,108,117,101,83,104,105,102,116,44,117,99,65,108,112,104,97,83,104,105,102,116,44,117,99,82,101,100,77,97,115,107,44,117,99,71,114,101,101,110,77,97,115,107,44,117,99,66,108,117,101,77,97,115,107,44,117,99,65,108,112,104,97,77,97,115,107,44,117,99,82,101,100,80,111,115,44,117,99,71,114,101,101,110,80,111,115,44,117,99,66,108,117,101,80,111,115,44,117,99,65,108,112,104,97,80,111,115,44,117,99,66,105,116,115,80,101,114,80,105,120,101,108,10,115,46,67,108,105,112,82,101,99,116,97,110,103,108,101,58,108,76,101,102,116,44,108,84,111,112,44,108,82,105,103,104,116,44,108,66,111,116,116,111,109,10,115,46,69,100,103,101,115,58,108,76,101,102,116,44,108,84,111,112,44,108,82,105,103,104,116,44,108,66,111,116,116,111,109,10,115,46,79,98,106,101,99,116,83,105,103,110,97,108,58,111,79,98,106,101,99,116,10,115,46,70,117,110,99,116,105,111,110,70,105,101,108,100,58,115,78,97,109,101,44,117,108,84,121,112,101,10,115,46,70,117,110,99,116,105,111,110,58,112,65,100,100,114,101,115,115,44,115,78,97,109,101,44,112,65,114,103,115,58,70,117,110,99,116,105,111,110,70,105,101,108,100,10,115,46,70,105,101,108,100,65,114,114,97,121,58,115,78,97,109,101,44,112,71,101,116,70,105,101,108,100,44,112,83,101,116,70,105,101,108,100,44,109,65,114,103,44,117,108,70,108,97,103,115,10,115,46,70,105,101,108,100,68,101,102,58,115,78,97,109,101,44,108,86,97,108,117,101,10,115,46,83,121,115,116,101,109,83,116,97,116,101,58,115,80,108,97,116,102,111,114,109,44,108,67,111,110,115,111,108,101,70,68,44,108,83,116,97,103,101,10,115,46,85,110,105,116,58,100,86,97,108,117,101,44,117,108,84,121,112,101,10,115,46,65,99,116,105,111,110,65,114,114,97,121,58,112,82,111,117,116,105,110,101,44,108,65,99,116,105,111,110,67,111,100,101,10,115,46,65,99,116,105,111,110,84,97,98,108,101,58,117,108,72,97,115,104,44,108,83,105,122,101,44,115,78,97,109,101,44,112,65,114,103,115,58,70,117,110,99,116,105,111,110,70,105,101,108,100,10,115,46,67,104,105,108,100,69,110,116,114,121,58,108,79,98,106,101,99,116,73,68,44,117,108,67,108,97,115,115,73,68,10,115,46,77,101,115,115,97,103,101,58,120,84,105,109,101,44,108,85,73,68,44,108,84,121,112,101,44,108,83,105,122,101,10,115,46,77,101,109,73,110,102,111,58,112,83,116,97,114,116,44,108,79,98,106,101,99,116,73,68,44,117,108,83,105,122,101,44,108,70,108,97,103,115,44,108,77,101,109,111,114,121,73,68,44,119,65,99,99,101,115,115,67,111,117,110,116,10,115,46,67,111,109,112,114,101,115,115,105,111,110,70,101,101,100,98,97,99,107,58,108,70,101,101,100,98,97,99,107,73,68,44,108,73,110,100,101,120,44,115,80,97,116,104,44,115,68,101,115,116,44,120,80,114,111,103,114,101,115,115,44,120,79,114,105,103,105,110,97,108,83,105,122,101,44,120,67,111,109,112,114,101,115,115,101,100,83,105,122,101,44,119,89,101,97,114,44,119,77,111,110,116,104,44,119,68,97,121,44,119,72,111,117,114,44,119,77,105,110,117,116,101,44,119,83,101,99,111,110,100,10,115,46,67,111,109,112,114,101,115,115,101,100,73,116,101,109,58,120,79,114,105,103,105,110,97,108,83,105,122,101,44,120,67,111,109,112,114,101,115,115,101,100,83,105,122,101,44,112,78,101,120,116,58,67,111,109,112,114,101,115,115,101,100,73,116,101,109,44,115,80,97,116,104,44,108,80,101,114,109,105,115,115,105,111,110,115,44,108,85,115,101,114,73,68,44,108,71,114,111,117,112,73,68,44,108,79,116,104,101,114,115,73,68,44,108,70,108,97,103,115,44,101,67,114,101,97,116,101,100,58,68,97,116,101,84,105,109,101,44,101,77,111,100,105,102,105,101,100,58,68,97,116,101,84,105,109,101,10,115,46,70,105,108,101,73,110,102,111,58,120,83,105,122,101,44,120,84,105,109,101,83,116,97,109,112,44,112,78,101,120,116,58,70,105,108,101,73,110,102,111,44,115,78,97,109,101,44,108,70,108,97,103,115,44,108,80,101,114,109,105,115,115,105,111,110,115,44,108,85,115,101,114,73,68,44,108,71,114,111,117,112,73,68,44,101,67,114,101,97,116,101,100,58,68,97,116,101,84,105,109,101,44,101,77,111,100,105,102,105,101,100,58,68,97,116,101,84,105,109,101,10,115,46,68,105,114,73,110,102,111,58,112,73,110,102,111,58,70,105,108,101,73,110,102,111,10,115,46,70,105,108,101,70,101,101,100,98,97,99,107,58,120,83,105,122,101,44,120,80,111,115,105,116,105,111,110,44,115,80,97,116,104,44,115,68,101,115,116,44,108,70,101,101,100,98,97,99,107,73,68,44,99,82,101,115,101,114,118,101,100,91,51,50,93,10,115,46,70,105,101,108,100,58,109,65,114,103,44,112,71,101,116,86,97,108,117,101,44,112,83,101,116,86,97,108,117,101,44,112,87,114,105,116,101,86,97,108,117,101,44,115,78,97,109,101,44,117,108,70,105,101,108,100,73,68,44,117,119,79,102,102,115,101,116,44,117,119,73,110,100,101,120,44,117,108,70,108,97,103,115,10,99,46,65,67,58,65,99,116,105,118,97,116,101,61,48,120,50,44,67,108,101,97,114,61,48,120,52,44,67,108,105,112,98,111,97,114,100,61,48,120,50,100,44,67,111,112,121,68,97,116,97,61,48,120,55,44,68,97,116,97,70,101,101,100,61,48,120,56,44,68,101,97,99,116,105,118,97,116,101,61,48,120,57,44,68,105,115,97,98,108,101,61,48,120,50,102,44,68,114,97,103,68,114,111,112,61,48,120,49,48,44,68,114,97,119,61,48,120,97,44,69,78,68,61,48,120,51,49,44,69,110,97,98,108,101,61,48,120,54,44,70,108,117,115,104,61,48,120,98,44,70,111,99,117,115,61,48,120,99,44,70,114,101,101,61,48,120,100,44,70,114,101,101,87,97,114,110,105,110,103,61,48,120,53,44,71,101,116,75,101,121,61,48,120,102,44,72,105,100,101,61,48,120,49,49,44,73,110,105,116,61,48,120,49,50,44,76,111,99,107,61,48,120,49,51,44,76,111,115,116,70,111,99,117,115,61,48,120,49,52,44,77,111,118,101,61,48,120,49,53,44,77,111,118,101,84,111,66,97,99,107,61,48,120,49,54,44,77,111,118,101,84,111,70,114,111,110,116,61,48,120,49,55,44,77,111,118,101,84,111,80,111,105,110,116,61,48,120,50,51,44,78,101,119,67,104,105,108,100,61,48,120,49,56,44,78,101,119,79,98,106,101,99,116,61,48,120,49,97,44,78,101,119,79,119,110,101,114,61,48,120,49,57,44,78,101,119,80,108,97,99,101,109,101,110,116,61,48,120,51,48,44,78,101,120,116,61,48,120,50,57,44,80,114,101,118,61,48,120,50,97,44,81,117,101,114,121,61,48,120,49,99,44,82,101,97,100,61,48,120,49,100,44,82,101,100,105,109,101,110,115,105,111,110,61,48,120,51,44,82,101,100,111,61,48,120,49,98,44,82,101,102,114,101,115,104,61,48,120,50,101,44,82,101,110,97,109,101,61,48,120,49,101,44,82,101,115,101,116,61,48,120,49,102,44,82,101,115,105,122,101,61,48,120,50,48,44,83,97,118,101,73,109,97,103,101,61,48,120,50,49,44,83,97,118,101,83,101,116,116,105,110,103,115,61,48,120,101,44,83,97,118,101,84,111,79,98,106,101,99,116,61,48,120,50,50,44,83,101,101,107,61,48,120,50,52,44,83,101,116,70,105,101,108,100,61,48,120,50,99,44,83,101,116,75,101,121,61,48,120,50,53,44,83,104,111,119,61,48,120,50,54,44,83,105,103,110,97,108,61,48,120,49,44,85,110,100,111,61,48,120,50,55,44,85,110,108,111,99,107,61,48,120,50,56,44,87,114,105,116,101,61,48,120,50,98,10,99,46,65,76,73,71,78,58,66,79,84,84,79,77,61,48,120,50,48,44,67,69,78,84,69,82,61,48,120,99,44,72,79,82,73,90,79,78,84,65,76,61,48,120,52,44,76,69,70,84,61,48,120,49,44,77,73,68,68,76,69,61,48,120,99,44,82,73,71,72,84,61,48,120,50,44,84,79,80,61,48,120,49,48,44,86,69,82,84,73,67,65,76,61,48,120,56,10,99,46,67,67,70,58,65,85,68,73,79,61,48,120,56,48,44,67,79,77,77,65,78,68,61,48,120,49,44,68,65,84,65,61,48,120,49,48,48,44,70,73,76,69,83,89,83,84,69,77,61,48,120,50,44,71,82,65,80,72,73,67,83,61,48,120,52,44,71,85,73,61,48,120,56,44,73,79,61,48,120,49,48,44,77,73,83,67,61,48,120,50,48,48,44,77,85,76,84,73,77,69,68,73,65,61,48,120,56,48,48,44,78,69,84,87,79,82,75,61,48,120,52,48,48,44,83,89,83,84,69,77,61,48,120,50,48,44,84,79,79,76,61,48,120,52,48,10,99,46,67,70,58,68,69,70,76,65,84,69,61,48,120,51,44,71,90,73,80,61,48,120,49,44,90,76,73,66,61,48,120,50,10,99,46,67,76,70,58,73,78,72,69,82,73,84,95,76,79,67,65,76,61,48,120,49,44,78,79,95,79,87,78,69,82,83,72,73,80,61,48,120,50,10,99,46,67,76,73,80,77,79,68,69,58,67,79,80,89,61,48,120,50,44,67,85,84,61,48,120,49,44,80,65,83,84,69,61,48,120,52,10,99,46,67,77,70,58,65,80,80,76,89,95,83,69,67,85,82,73,84,89,61,48,120,50,48,44,67,82,69,65,84,69,95,70,73,76,69,61,48,120,52,44,78,69,87,61,48,120,50,44,78,79,95,76,73,78,75,83,61,48,120,49,48,44,80,65,83,83,87,79,82,68,61,48,120,49,44,82,69,65,68,95,79,78,76,89,61,48,120,56,10,99,46,67,78,70,58,65,85,84,79,95,83,65,86,69,61,48,120,50,44,78,69,87,61,48,120,56,44,79,80,84,73,79,78,65,76,95,70,73,76,69,83,61,48,120,52,44,83,84,82,73,80,95,81,85,79,84,69,83,61,48,120,49,10,99,46,67,79,78,58,68,80,65,68,95,68,79,87,78,61,48,120,50,48,44,68,80,65,68,95,76,69,70,84,61,48,120,52,48,44,68,80,65,68,95,82,73,71,72,84,61,48,120,56,48,44,68,80,65,68,95,85,80,61,48,120,49,48,44,71,65,77,69,80,65,68,95,69,61,48,120,50,44,71,65,77,69,80,65,68,95,78,61,48,120,56,44,71,65,77,69,80,65,68,95,83,61,48,120,49,44,71,65,77,69,80,65,68,95,87,61,48,120,52,44,76,69,70,84,95,66,85,77,80,69,82,95,49,61,48,120,52,48,48,44,76,69,70,84,95,66,85,77,80,69,82,95,50,61,48,120,56,48,48,44,82,73,71,72,84,95,66,85,77,80,69,82,95,49,61,48,120,49,48,48,48,44,82,73,71,72,84,95,66,85,77,80,69,82,95,50,61,48,120,50,48,48,48,44,83,69,76,69,67,84,61,48,120,50,48,48,44,83,84,65,82,84,61,48,120,49,48,48,10,99,46,68,65,84,65,58,65,85,68,73,79,61,48,120,53,44,67,79,78,84,69,78,84,61,48,120,98,44,68,69,86,73,67,69,95,73,78,80,85,84,61,48,120,51,44,70,73,76,69,61,48,120,97,44,73,77,65,71,69,61,48,120,55,44,73,78,80,85,84,95,82,69,65,68,89,61,48,120,99,44,82,65,87,61,48,120,50,44,82,69,67,69,73,80,84,61,48,120,57,44,82,69,67,79,82,68,61,48,120,54,44,82,69,81,85,69,83,84,61,48,120,56,44,84,69,88,84,61,48,120,49,44,88,77,76,61,48,120,52,10,99,46,68,69,86,73,67,69,58,66,79,79,75,77,65,82,75,61,48,120,52,48,48,48,48,44,67,79,77,80,65,67,84,95,68,73,83,67,61,48,120,49,44,70,73,88,69,68,61,48,120,56,48,48,48,44,70,76,79,80,80,89,95,68,73,83,75,61,48,120,52,44,72,65,82,68,95,68,73,83,75,61,48,120,50,44,77,69,77,79,82,89,61,48,120,49,48,48,48,44,77,79,68,69,77,61,48,120,50,48,48,48,44,78,69,84,87,79,82,75,61,48,120,56,48,44,80,82,73,78,84,69,82,61,48,120,50,48,48,44,80,82,73,78,84,69,82,95,51,68,61,48,120,49,48,48,48,48,44,82,69,65,68,61,48,120,56,44,82,69,77,79,86,65,66,76,69,61,48,120,50,48,44,82,69,77,79,86,69,65,66,76,69,61,48,120,50,48,44,83,67,65,78,78,69,82,61,48,120,52,48,48,44,83,67,65,78,78,69,82,95,51,68,61,48,120,50,48,48,48,48,44,83,79,70,84,87,65,82,69,61,48,120,52,48,44,84,65,80,69,61,48,120,49,48,48,44,84,69,77,80,79,82,65,82,89,61,48,120,56,48,48,44,85,83,66,61,48,120,52,48,48,48,44,87,82,73,84,69,61,48,120,49,48,10,99,46,68,77,70,58,70,73,88,69,68,95,67,69,78,84,69,82,95,88,61,48,120,49,48,48,48,48,48,44,70,73,88,69,68,95,67,69,78,84,69,82,95,89,61,48,120,50,48,48,48,48,48,44,70,73,88,69,68,95,68,69,80,84,72,61,48,120,49,48,48,48,44,70,73,88,69,68,95,72,69,73,71,72,84,61,48,120,49,48,48,44,70,73,88,69,68,95,82,65,68,73,85,83,95,88,61,48,120,50,48,48,48,48,44,70,73,88,69,68,95,82,65,68,73,85,83,95,89,61,48,120,50,48,48,48,48,48,48,44,70,73,88,69,68,95,87,73,68,84,72,61,48,120,50,48,48,44,70,73,88,69,68,95,88,61,48,120,52,44,70,73,88,69,68,95,88,95,79,70,70,83,69,84,61,48,120,52,48,44,70,73,88,69,68,95,89,61,48,120,56,44,70,73,88,69,68,95,89,95,79,70,70,83,69,84,61,48,120,56,48,44,70,73,88,69,68,95,90,61,48,120,52,48,48,48,44,83,67,65,76,69,68,95,67,69,78,84,69,82,95,88,61,48,120,52,48,48,48,48,44,83,67,65,76,69,68,95,67,69,78,84,69,82,95,89,61,48,120,56,48,48,48,48,44,83,67,65,76,69,68,95,68,69,80,84,72,61,48,120,50,48,48,48,44,83,67,65,76,69,68,95,72,69,73,71,72,84,61,48,120,52,48,48,44,83,67,65,76,69,68,95,82,65,68,73,85,83,95,88,61,48,120,49,48,48,48,48,44,83,67,65,76,69,68,95,82,65,68,73,85,83,95,89,61,48,120,49,48,48,48,48,48,48,44,83,67,65,76,69,68,95,87,73,68,84,72,61,48,120,56,48,48,44,83,67,65,76,69,68,95,88,61,48,120,49,44,83,67,65,76,69,68,95,88,95,79,70,70,83,69,84,61,48,120,49,48,44,83,67,65,76,69,68,95,89,61,48,120,50,44,83,67,65,76,69,68,95,89,95,79,70,70,83,69,84,61,48,120,50,48,44,83,67,65,76,69,68,95,90,61,48,120,56,48,48,48,44,83,84,65,84,85,83,95,67,72,65,78,71,69,95,72,61,48,120,52,48,48,48,48,48,44,83,84,65,84,85,83,95,67,72,65,78,71,69,95,86,61,48,120,56,48,48,48,48,48,10,99,46,68,82,76,58,68,79,87,78,61,48,120,49,44,69,65,83,84,61,48,120,50,44,76,69,70,84,61,48,120,51,44,78,79,82,84,72,61,48,120,48,44,78,79,82,84,72,95,69,65,83,84,61,48,120,52,44,78,79,82,84,72,95,87,69,83,84,61,48,120,53,44,82,73,71,72,84,61,48,120,50,44,83,79,85,84,72,61,48,120,49,44,83,79,85,84,72,95,69,65,83,84,61,48,120,54,44,83,79,85,84,72,95,87,69,83,84,61,48,120,55,44,85,80,61,48,120,48,44,87,69,83,84,61,48,120,51,10,99,46,69,68,71,69,58,65,76,76,61,48,120,102,102,44,66,79,84,84,79,77,61,48,120,56,44,66,79,84,84,79,77,95,76,69,70,84,61,48,120,52,48,44,66,79,84,84,79,77,95,82,73,71,72,84,61,48,120,56,48,44,76,69,70,84,61,48,120,50,44,82,73,71,72,84,61,48,120,52,44,84,79,80,61,48,120,49,44,84,79,80,95,76,69,70,84,61,48,120,49,48,44,84,79,80,95,82,73,71,72,84,61,48,120,50,48,10,99,46,69,82,70,58,78,111,116,105,102,105,101,100,61,48,120,52,48,48,48,48,48,48,48,10,99,46,69,82,82,58,65,99,99,101,115,115,77,101,109,111,114,121,61,48,120,52,98,44,65,99,99,101,115,115,79,98,106,101,99,116,61,48,120,53,51,44,65,99,99,101,115,115,83,101,109,97,112,104,111,114,101,61,48,120,55,51,44,65,99,116,105,118,97,116,101,61,48,120,52,50,44,65,100,100,67,108,97,115,115,61,48,120,52,49,44,65,108,108,111,99,77,101,109,111,114,121,61,48,120,53,52,44,65,108,108,111,99,83,101,109,97,112,104,111,114,101,61,48,120,55,50,44,65,108,114,101,97,100,121,68,101,102,105,110,101,100,61,48,120,98,54,44,65,108,114,101,97,100,121,76,111,99,107,101,100,61,48,120,57,99,44,65,114,103,115,61,48,120,49,52,44,65,114,114,97,121,70,117,108,108,61,48,120,50,100,44,66,117,102,102,101,114,79,118,101,114,102,108,111,119,61,48,120,53,99,44,66,117,115,121,61,48,120,56,98,44,67,97,110,99,101,108,108,101,100,61,48,120,51,44,67,97,114,100,82,101,97,100,101,114,85,110,97,118,97,105,108,97,98,108,101,61,48,120,57,102,44,67,97,114,100,82,101,97,100,101,114,85,110,107,110,111,119,110,61,48,120,57,100,44,67,111,109,112,114,101,115,115,105,111,110,61,48,120,97,100,44,67,111,110,110,101,99,116,105,111,110,65,98,111,114,116,101,100,61,48,120,56,99,44,67,111,110,110,101,99,116,105,111,110,82,101,102,117,115,101,100,61,48,120,56,51,44,67,111,110,115,116,114,97,105,110,116,86,105,111,108,97,116,105,111,110,61,48,120,56,56,44,67,111,110,116,105,110,117,101,61,48,120,53,44,67,111,114,101,86,101,114,115,105,111,110,61,48,120,50,54,44,67,114,101,97,116,101,70,105,108,101,61,48,120,55,52,44,67,114,101,97,116,101,79,98,106,101,99,116,61,48,120,54,53,44,67,114,101,97,116,101,82,101,115,111,117,114,99,101,61,48,120,98,50,44,68,97,116,97,83,105,122,101,61,48,120,56,97,44,68,101,97,99,116,105,118,97,116,101,100,61,48,120,57,97,44,68,101,97,100,76,111,99,107,61,48,120,51,101,44,68,101,99,111,109,112,114,101,115,115,105,111,110,61,48,120,97,99,44,68,101,108,101,116,101,70,105,108,101,61,48,120,55,53,44,68,105,114,69,109,112,116,121,61,48,120,56,44,68,105,115,99,111,110,110,101,99,116,101,100,61,48,120,56,54,44,68,111,78,111,116,69,120,112,117,110,103,101,61,48,120,51,48,44,68,111,101,115,78,111,116,69,120,105,115,116,61,48,120,55,56,44,68,111,117,98,108,101,73,110,105,116,61,48,120,52,51,44,68,114,97,119,61,48,120,52,56,44,69,78,68,61,48,120,98,101,44,69,109,112,116,121,83,116,114,105,110,103,61,48,120,54,100,44,69,110,100,79,102,70,105,108,101,61,48,120,55,101,44,69,110,116,114,121,77,105,115,115,105,110,103,72,101,97,100,101,114,61,48,120,51,97,44,69,120,97,109,105,110,101,70,97,105,108,101,100,61,48,120,49,57,44,69,120,99,101,112,116,105,111,110,61,48,120,97,51,44,69,120,99,101,112,116,105,111,110,84,104,114,101,115,104,111,108,100,61,48,120,57,44,69,120,99,108,117,115,105,118,101,68,101,110,105,101,100,61,48,120,53,51,44,69,120,101,99,86,105,111,108,97,116,105,111,110,61,48,120,56,102,44,69,120,105,115,116,115,61,48,120,55,97,44,69,120,112,101,99,116,101,100,70,105,108,101,61,48,120,54,102,44,69,120,112,101,99,116,101,100,70,111,108,100,101,114,61,48,120,97,101,44,70,97,105,108,101,100,61,48,120,100,44,70,97,108,115,101,61,48,120,49,44,70,105,101,108,100,78,111,116,83,101,116,61,48,120,52,52,44,70,105,101,108,100,83,101,97,114,99,104,61,48,120,51,50,44,70,105,101,108,100,84,121,112,101,77,105,115,109,97,116,99,104,61,48,120,53,97,44,70,105,108,101,61,48,120,101,44,70,105,108,101,68,111,101,115,78,111,116,69,120,105,115,116,61,48,120,49,50,44,70,105,108,101,69,120,105,115,116,115,61,48,120,54,51,44,70,105,108,101,78,111,116,70,111,117,110,100,61,48,120,49,50,44,70,105,108,101,82,101,97,100,70,108,97,103,61,48,120,52,54,44,70,105,108,101,87,114,105,116,101,70,108,97,103,61,48,120,52,55,44,70,105,110,105,115,104,101,100,61,48,120,55,101,44,70,117,110,99,116,105,111,110,61,48,120,98,53,44,71,101,116,70,105,101,108,100,61,48,120,53,54,44,71,101,116,83,117,114,102,97,99,101,73,110,102,111,61,48,120,55,100,44,72,111,115,116,78,111,116,70,111,117,110,100,61,48,120,56,49,44,72,111,115,116,85,110,114,101,97,99,104,97,98,108,101,61,48,120,56,53,44,73,100,101,110,116,105,99,97,108,80,97,116,104,115,61,48,120,55,57,44,73,108,108,101,103,97,108,65,99,116,105,111,110,65,116,116,101,109,112,116,61,48,120,51,57,44,73,108,108,101,103,97,108,65,99,116,105,111,110,73,68,61,48,120,51,55,44,73,108,108,101,103,97,108,65,100,100,114,101,115,115,61,48,120,57,49,44,73,108,108,101,103,97,108,77,101,116,104,111,100,73,68,61,48,120,51,54,44,73,109,109,117,116,97,98,108,101,61,48,120,97,102,44,73,110,85,115,101,61,48,120,99,44,73,110,105,116,61,48,120,50,49,44,73,110,105,116,77,111,100,117,108,101,61,48,120,49,49,44,73,110,112,117,116,79,117,116,112,117,116,61,48,120,57,52,44,73,110,116,101,103,114,105,116,121,86,105,111,108,97,116,105,111,110,61,48,120,56,56,44,73,110,118,97,108,105,100,68,97,116,97,61,48,120,102,44,73,110,118,97,108,105,100,68,105,109,101,110,115,105,111,110,61,48,120,53,57,44,73,110,118,97,108,105,100,72,84,84,80,82,101,115,112,111,110,115,101,61,48,120,97,49,44,73,110,118,97,108,105,100,72,97,110,100,108,101,61,48,120,57,54,44,73,110,118,97,108,105,100,79,98,106,101,99,116,61,48,120,56,101,44,73,110,118,97,108,105,100,80,97,116,104,61,48,120,51,51,44,73,110,118,97,108,105,100,82,101,102,101,114,101,110,99,101,61,48,120,97,50,44,73,110,118,97,108,105,100,83,116,97,116,101,61,48,120,56,48,44,73,110,118,97,108,105,100,85,82,73,61,48,120,56,50,44,73,110,118,97,108,105,100,86,97,108,117,101,61,48,120,57,56,44,76,105,109,105,116,101,100,83,117,99,99,101,115,115,61,48,120,50,44,76,105,115,116,67,104,105,108,100,114,101,110,61,48,120,54,97,44,76,111,97,100,77,111,100,117,108,101,61,48,120,57,53,44,76,111,99,107,61,48,120,49,56,44,76,111,99,107,70,97,105,108,101,100,61,48,120,49,56,44,76,111,99,107,77,117,116,101,120,61,48,120,97,97,44,76,111,99,107,82,101,113,117,105,114,101,100,61,48,120,57,98,44,76,111,99,107,101,100,61,48,120,57,99,44,76,111,111,112,61,48,120,54,50,44,76,111,115,116,67,108,97,115,115,61,48,120,49,97,44,76,111,115,116,79,119,110,101,114,61,48,120,50,102,44,76,111,119,67,97,112,97,99,105,116,121,61,48,120,50,48,44,77,97,114,107,101,100,70,111,114,68,101,108,101,116,105,111,110,61,48,120,51,53,44,77,101,109,111,114,121,61,48,120,49,100,44,77,101,109,111,114,121,67,111,114,114,117,112,116,61,48,120,51,49,44,77,101,109,111,114,121,68,111,101,115,78,111,116,69,120,105,115,116,61,48,120,51,100,44,77,101,109,111,114,121,73,110,102,111,61,48,120,54,54,44,77,105,115,109,97,116,99,104,61,48,120,53,101,44,77,105,115,115,105,110,103,67,108,97,115,115,61,48,120,52,53,44,77,105,115,115,105,110,103,67,108,97,115,115,78,97,109,101,61,48,120,50,97,44,77,105,115,115,105,110,103,80,97,116,104,61,48,120,52,99,44,77,111,100,117,108,101,73,110,105,116,70,97,105,108,101,100,61,48,120,51,99,44,77,111,100,117,108,101,77,105,115,115,105,110,103,73,110,105,116,61,48,120,51,98,44,77,111,100,117,108,101,77,105,115,115,105,110,103,78,97,109,101,61,48,120,52,48,44,77,111,100,117,108,101,79,112,101,110,70,97,105,108,101,100,61,48,120,51,56,44,78,101,101,100,79,119,110,101,114,61,48,120,50,52,44,78,101,101,100,87,105,100,116,104,72,101,105,103,104,116,61,48,120,50,55,44,78,101,103,97,116,105,118,101,67,108,97,115,115,73,68,61,48,120,50,57,44,78,101,103,97,116,105,118,101,83,117,98,67,108,97,115,115,73,68,61,48,120,50,56,44,78,101,116,119,111,114,107,85,110,114,101,97,99,104,97,98,108,101,61,48,120,56,52,44,78,101,119,79,98,106,101,99,116,61,48,120,53,53,44,78,111,65,99,116,105,111,110,61,48,120,49,98,44,78,111,68,97,116,97,61,48,120,49,53,44,78,111,70,105,101,108,100,65,99,99,101,115,115,61,48,120,53,55,44,78,111,77,97,116,99,104,105,110,103,79,98,106,101,99,116,61,48,120,52,97,44,78,111,77,101,100,105,97,73,110,115,101,114,116,101,100,61,48,120,57,101,44,78,111,77,101,109,111,114,121,61,48,120,97,44,78,111,77,101,116,104,111,100,115,61,48,120,52,57,44,78,111,80,101,114,109,105,115,115,105,111,110,61,48,120,50,50,44,78,111,80,111,105,110,116,101,114,61,48,120,98,44,78,111,83,101,97,114,99,104,82,101,115,117,108,116,61,48,120,52,101,44,78,111,83,116,97,116,115,61,48,120,49,102,44,78,111,83,117,112,112,111,114,116,61,48,120,49,99,44,78,111,116,70,111,117,110,100,61,48,120,49,48,44,78,111,116,73,110,105,116,105,97,108,105,115,101,100,61,48,120,54,55,44,78,111,116,76,111,99,107,101,100,61,48,120,52,100,44,78,111,116,80,111,115,115,105,98,108,101,61,48,120,98,51,44,78,111,116,104,105,110,103,68,111,110,101,61,48,120,52,44,78,111,116,105,102,105,101,100,61,48,120,52,48,48,48,48,48,48,48,44,78,117,108,108,65,114,103,115,61,48,120,56,100,44,79,98,106,101,99,116,67,111,114,114,117,112,116,61,48,120,53,48,44,79,98,106,101,99,116,69,120,105,115,116,115,61,48,120,54,101,44,79,98,115,111,108,101,116,101,61,48,120,98,49,44,79,98,116,97,105,110,77,101,116,104,111,100,61,48,120,50,99,44,79,107,97,121,61,48,120,48,44,79,112,101,110,70,105,108,101,61,48,120,55,54,44,79,112,101,110,71,76,61,48,120,97,53,44,79,117,116,79,102,66,111,117,110,100,115,61,48,120,53,102,44,79,117,116,79,102,68,97,116,97,61,48,120,55,101,44,79,117,116,79,102,82,97,110,103,101,61,48,120,50,98,44,79,117,116,79,102,83,112,97,99,101,61,48,120,55,99,44,79,117,116,115,105,100,101,77,97,105,110,84,104,114,101,97,100,61,48,120,97,54,44,79,119,110,101,114,78,101,101,100,115,66,105,116,109,97,112,61,48,120,50,53,44,79,119,110,101,114,80,97,115,115,84,104,114,111,117,103,104,61,48,120,53,49,44,80,101,114,109,105,115,115,105,111,110,68,101,110,105,101,100,61,48,120,50,50,44,80,101,114,109,105,115,115,105,111,110,115,61,48,120,50,50,44,80,114,111,120,121,83,83,76,84,117,110,110,101,108,61,48,120,97,48,44,81,117,101,114,121,61,48,120,50,101,44,82,101,97,100,61,48,120,49,54,44,82,101,97,100,70,105,108,101,84,111,66,117,102,102,101,114,61,48,120,98,48,44,82,101,97,100,79,110,108,121,61,48,120,55,55,44,82,101,97,108,108,111,99,77,101,109,111,114,121,61,48,120,54,49,44,82,101,99,117,114,115,105,111,110,61,48,120,57,48,44,82,101,100,105,109,101,110,115,105,111,110,61,48,120,55,49,44,82,101,102,114,101,115,104,61,48,120,54,57,44,82,101,115,105,122,101,61,48,120,55,48,44,82,101,115,111,108,118,101,80,97,116,104,61,48,120,54,52,44,82,101,115,111,108,118,101,83,121,109,98,111,108,61,48,120,98,52,44,82,101,115,111,117,114,99,101,69,120,105,115,116,115,61,48,120,54,56,44,82,101,116,114,121,61,48,120,55,44,83,97,110,105,116,121,70,97,105,108,117,114,101,61,48,120,55,98,44,83,99,104,101,109,97,86,105,111,108,97,116,105,111,110,61,48,120,56,57,44,83,101,97,114,99,104,61,48,120,49,48,44,83,101,99,117,114,105,116,121,61,48,120,57,55,44,83,101,101,107,61,48,120,54,48,44,83,101,114,118,105,99,101,85,110,97,118,97,105,108,97,98,108,101,61,48,120,57,57,44,83,101,116,70,105,101,108,100,61,48,120,51,52,44,83,101,116,86,97,108,117,101,78,111,116,65,114,114,97,121,61,48,120,98,99,44,83,101,116,86,97,108,117,101,78,111,116,70,117,110,99,116,105,111,110,61,48,120,98,97,44,83,101,116,86,97,108,117,101,78,111,116,76,111,111,107,117,112,61,48,120,98,100,44,83,101,116,86,97,108,117,101,78,111,116,78,117,109,101,114,105,99,61,48,120,98,55,44,83,101,116,86,97,108,117,101,78,111,116,79,98,106,101,99,116,61,48,120,98,57,44,83,101,116,86,97,108,117,101,78,111,116,80,111,105,110,116,101,114,61,48,120,98,98,44,83,101,116,86,97,108,117,101,78,111,116,83,116,114,105,110,103,61,48,120,98,56,44,83,101,116,86,111,108,117,109,101,61,48,120,97,98,44,83,107,105,112,61,48,120,54,44,83,109,97,108,108,77,97,115,107,61,48,120,54,99,44,83,116,97,116,101,109,101,110,116,85,110,115,97,116,105,115,102,105,101,100,61,48,120,52,102,44,83,116,114,105,110,103,70,111,114,109,97,116,61,48,120,55,102,44,83,121,110,116,97,120,61,48,120,55,102,44,83,121,115,116,101,109,67,97,108,108,61,48,120,54,98,44,83,121,115,116,101,109,67,111,114,114,117,112,116,61,48,120,50,51,44,83,121,115,116,101,109,76,111,99,107,101,100,61,48,120,51,102,44,84,97,115,107,83,116,105,108,108,69,120,105,115,116,115,61,48,120,56,55,44,84,101,114,109,105,110,97,116,101,61,48,120,57,44,84,104,114,101,97,100,65,108,114,101,97,100,121,65,99,116,105,118,101,61,48,120,97,52,44,84,104,114,101,97,100,78,111,116,76,111,99,107,101,100,61,48,120,97,57,44,84,105,109,101,79,117,116,61,48,120,49,101,44,84,114,117,101,61,48,120,48,44,85,110,98,97,108,97,110,99,101,100,88,77,76,61,48,120,57,50,44,85,110,100,101,102,105,110,101,100,70,105,101,108,100,61,48,120,52,52,44,85,110,114,101,99,111,103,110,105,115,101,100,70,105,101,108,100,84,121,112,101,61,48,120,53,98,44,85,110,115,117,112,112,111,114,116,101,100,70,105,101,108,100,61,48,120,53,100,44,85,110,115,117,112,112,111,114,116,101,100,79,119,110,101,114,61,48,120,53,50,44,85,115,101,83,117,98,67,108,97,115,115,61,48,120,97,55,44,86,105,114,116,117,97,108,86,111,108,117,109,101,61,48,120,53,56,44,87,111,117,108,100,66,108,111,99,107,61,48,120,57,51,44,87,114,105,116,101,61,48,120,49,55,44,87,114,111,110,103,67,108,97,115,115,61,48,120,56,101,44,87,114,111,110,103,79,98,106,101,99,116,84,121,112,101,61,48,120,56,101,44,87,114,111,110,103,84,121,112,101,61,48,120,97,56,44,87,114,111,110,103,86,101,114,115,105,111,110,61,48,120,49,51,10,99,46,69,86,71,58,65,78,68,82,79,73,68,61,48,120,100,44,65,80,80,61,48,120,99,44,65,85,68,73,79,61,48,120,56,44,67,76,65,83,83,61,48,120,98,44,68,73,83,80,76,65,89,61,48,120,53,44,69,78,68,61,48,120,101,44,70,73,76,69,83,89,83,84,69,77,61,48,120,49,44,71,85,73,61,48,120,52,44,72,65,82,68,87,65,82,69,61,48,120,55,44,73,79,61,48,120,54,44,78,69,84,87,79,82,75,61,48,120,50,44,80,79,87,69,82,61,48,120,97,44,83,89,83,84,69,77,61,48,120,51,44,85,83,69,82,61,48,120,57,10,99,46,70,66,75,58,67,79,80,89,95,70,73,76,69,61,48,120,50,44,68,69,76,69,84,69,95,70,73,76,69,61,48,120,51,44,77,79,86,69,95,70,73,76,69,61,48,120,49,10,99,46,70,68,58,65,76,76,79,67,61,48,120,50,48,44,65,82,82,65,89,61,48,120,49,48,48,48,44,65,82,82,65,89,83,73,90,69,61,48,120,56,48,44,66,85,70,70,69,82,61,48,120,50,48,48,44,66,85,70,83,73,90,69,61,48,120,56,48,44,66,89,84,69,61,48,120,49,48,48,48,48,48,48,44,67,80,80,61,48,120,52,48,48,48,44,67,85,83,84,79,77,61,48,120,56,48,48,48,44,68,79,85,66,76,69,61,48,120,56,48,48,48,48,48,48,48,44,68,79,85,66,76,69,82,69,83,85,76,84,61,48,120,56,48,48,48,48,49,48,48,44,69,82,82,79,82,61,48,120,56,48,48,44,70,76,65,71,83,61,48,120,52,48,44,70,76,79,65,84,61,48,120,49,48,48,48,48,48,48,48,44,70,85,78,67,84,73,79,78,61,48,120,50,48,48,48,48,48,48,44,70,85,78,67,84,73,79,78,80,84,82,61,48,120,97,48,48,48,48,48,48,44,73,61,48,120,52,48,48,44,73,78,73,84,61,48,120,52,48,48,44,76,65,82,71,69,61,48,120,52,48,48,48,48,48,48,44,76,65,82,71,69,82,69,83,85,76,84,61,48,120,52,48,48,48,49,48,48,44,76,79,67,65,76,61,48,120,50,44,76,79,78,71,61,48,120,52,48,48,48,48,48,48,48,44,76,79,78,71,82,69,83,85,76,84,61,48,120,52,48,48,48,48,49,48,48,44,76,79,79,75,85,80,61,48,120,56,48,44,79,66,74,69,67,84,61,48,120,49,44,79,66,74,69,67,84,73,68,61,48,120,52,48,48,48,48,48,48,49,44,79,66,74,69,67,84,80,84,82,61,48,120,56,48,48,48,48,48,49,44,80,79,73,78,84,69,82,61,48,120,56,48,48,48,48,48,48,44,80,82,73,86,65,84,69,61,48,120,49,48,48,48,48,44,80,84,82,61,48,120,56,48,48,48,48,48,48,44,80,84,82,66,85,70,70,69,82,61,48,120,56,48,48,48,50,48,48,44,80,84,82,82,69,83,85,76,84,61,48,120,56,48,48,48,49,48,48,44,80,84,82,83,73,90,69,61,48,120,56,48,44,80,84,82,95,68,79,85,66,76,69,82,69,83,85,76,84,61,48,120,56,56,48,48,48,49,48,48,44,80,84,82,95,76,65,82,71,69,82,69,83,85,76,84,61,48,120,99,48,48,48,49,48,48,44,80,84,82,95,76,79,78,71,82,69,83,85,76,84,61,48,120,52,56,48,48,48,49,48,48,44,82,61,48,120,49,48,48,44,82,69,65,68,61,48,120,49,48,48,44,82,69,83,79,85,82,67,69,61,48,120,50,48,48,48,44,82,69,83,85,76,84,61,48,120,49,48,48,44,82,71,66,61,48,120,56,48,48,48,48,44,82,73,61,48,120,53,48,48,44,82,87,61,48,120,51,48,48,44,83,67,65,76,69,68,61,48,120,50,48,48,48,48,48,44,83,84,82,61,48,120,56,48,48,48,48,48,44,83,84,82,73,78,71,61,48,120,56,48,48,48,48,48,44,83,84,82,82,69,83,85,76,84,61,48,120,56,48,48,49,48,48,44,83,84,82,85,67,84,61,48,120,49,48,44,83,89,78,79,78,89,77,61,48,120,50,48,48,48,48,44,83,89,83,84,69,77,61,48,120,49,48,48,48,48,44,84,65,71,83,61,48,120,52,48,48,44,85,78,73,84,61,48,120,50,48,48,48,48,48,48,48,44,85,78,83,73,71,78,69,68,61,48,120,52,48,48,48,48,44,86,65,82,84,65,71,83,61,48,120,52,48,44,86,73,82,84,85,65,76,61,48,120,56,44,86,79,73,68,61,48,120,48,44,86,79,76,65,84,73,76,69,61,48,120,48,44,87,61,48,120,50,48,48,44,87,79,82,68,61,48,120,52,48,48,48,48,48,44,87,82,73,84,69,61,48,120,50,48,48,10,99,46,70,68,66,58,67,79,77,80,82,69,83,83,95,70,73,76,69,61,48,120,50,44,68,69,67,79,77,80,82,69,83,83,95,70,73,76,69,61,48,120,49,44,68,69,67,79,77,80,82,69,83,83,95,79,66,74,69,67,84,61,48,120,52,44,82,69,77,79,86,69,95,70,73,76,69,61,48,120,51,10,99,46,70,68,76,58,70,69,69,68,66,65,67,75,61,48,120,49,10,99,46,70,68,84,58,65,67,67,69,83,83,69,68,61,48,120,50,44,65,82,67,72,73,86,69,68,61,48,120,51,44,67,82,69,65,84,69,68,61,48,120,49,44,77,79,68,73,70,73,69,68,61,48,120,48,10,99,46,70,70,82,58,65,66,79,82,84,61,48,120,50,44,67,79,78,84,73,78,85,69,61,48,120,48,44,79,75,65,89,61,48,120,48,44,83,75,73,80,61,48,120,49,10,99,46,70,76,58,65,80,80,82,79,88,73,77,65,84,69,61,48,120,49,48,44,66,85,70,70,69,82,61,48,120,52,48,44,68,69,86,73,67,69,61,48,120,52,48,48,44,68,73,82,69,67,84,79,82,89,61,48,120,56,44,69,88,67,76,85,68,69,95,70,73,76,69,83,61,48,120,49,48,48,48,44,69,88,67,76,85,68,69,95,70,79,76,68,69,82,83,61,48,120,50,48,48,48,44,70,73,76,69,61,48,120,49,48,48,44,70,79,76,68,69,82,61,48,120,56,44,76,73,78,75,61,48,120,50,48,44,76,79,79,80,61,48,120,56,48,44,78,69,87,61,48,120,50,44,82,69,65,68,61,48,120,52,44,82,69,83,69,84,95,68,65,84,69,61,48,120,50,48,48,44,83,84,82,69,65,77,61,48,120,56,48,48,44,87,82,73,84,69,61,48,120,49,10,99,46,70,79,70,58,83,77,65,82,84,95,78,65,77,69,83,61,48,120,49,10,99,46,73,68,84,89,80,69,58,70,85,78,67,84,73,79,78,61,48,120,51,44,71,76,79,66,65,76,61,48,120,50,44,77,69,83,83,65,71,69,61,48,120,49,10,99,46,74,69,84,58,65,66,83,95,88,89,61,48,120,101,44,66,85,84,84,79,78,95,49,61,48,120,49,44,66,85,84,84,79,78,95,49,48,61,48,120,97,44,66,85,84,84,79,78,95,50,61,48,120,50,44,66,85,84,84,79,78,95,51,61,48,120,51,44,66,85,84,84,79,78,95,52,61,48,120,52,44,66,85,84,84,79,78,95,53,61,48,120,53,44,66,85,84,84,79,78,95,54,61,48,120,54,44,66,85,84,84,79,78,95,55,61,48,120,55,44,66,85,84,84,79,78,95,56,61,48,120,56,44,66,85,84,84,79,78,95,57,61,48,120,57,44,67,82,79,83,83,69,68,95,73,78,61,48,120,102,44,67,82,79,83,83,69,68,95,79,85,84,61,48,120,49,48,44,68,69,86,73,67,69,95,84,73,76,84,95,88,89,61,48,120,49,50,44,68,69,86,73,67,69,95,84,73,76,84,95,90,61,48,120,49,51,44,68,73,83,80,76,65,89,95,69,68,71,69,61,48,120,49,52,44,69,78,68,61,48,120,49,53,44,76,77,66,61,48,120,49,44,77,77,66,61,48,120,51,44,80,69,78,95,84,73,76,84,95,88,89,61,48,120,100,44,80,82,69,83,83,85,82,69,61,48,120,49,49,44,82,77,66,61,48,120,50,44,87,72,69,69,76,61,48,120,98,44,87,72,69,69,76,95,84,73,76,84,61,48,120,99,10,99,46,74,84,89,80,69,58,65,78,65,76,79,71,61,48,120,50,48,44,65,78,67,72,79,82,69,68,61,48,120,50,44,66,85,84,84,79,78,61,48,120,56,48,44,67,82,79,83,83,73,78,71,61,48,120,56,44,68,66,76,95,67,76,73,67,75,61,48,120,50,48,48,44,68,73,71,73,84,65,76,61,48,120,49,48,44,68,82,65,71,71,69,68,61,48,120,52,44,68,82,65,71,95,73,84,69,77,61,48,120,56,48,48,44,69,88,84,95,77,79,86,69,77,69,78,84,61,48,120,52,48,44,77,79,86,69,77,69,78,84,61,48,120,49,48,48,44,82,69,80,69,65,84,69,68,61,48,120,52,48,48,44,83,69,67,79,78,68,65,82,89,61,48,120,49,10,99,46,75,69,89,58,65,61,48,120,49,44,65,80,79,83,84,82,79,80,72,69,61,48,120,50,98,44,65,84,61,48,120,56,97,44,66,61,48,120,50,44,66,65,67,75,61,48,120,56,54,44,66,65,67,75,83,80,65,67,69,61,48,120,54,57,44,66,65,67,75,95,83,76,65,83,72,61,48,120,50,102,44,66,82,69,65,75,61,48,120,55,98,44,67,61,48,120,51,44,67,65,76,76,61,48,120,56,55,44,67,65,77,69,82,65,61,48,120,56,57,44,67,65,78,67,69,76,61,48,120,55,97,44,67,65,80,83,95,76,79,67,75,61,48,120,52,54,44,67,76,69,65,82,61,48,120,54,101,44,67,79,77,77,65,61,48,120,50,99,44,68,61,48,120,52,44,68,69,76,69,84,69,61,48,120,54,100,44,68,79,84,61,48,120,50,100,44,68,79,87,78,61,48,120,54,49,44,69,61,48,120,53,44,69,73,71,72,84,61,48,120,50,50,44,69,78,68,61,48,120,55,50,44,69,78,68,95,67,65,76,76,61,48,120,56,56,44,69,78,84,69,82,61,48,120,54,98,44,69,81,85,65,76,83,61,48,120,50,55,44,69,83,67,65,80,69,61,48,120,54,99,44,69,88,69,67,85,84,69,61,48,120,55,52,44,70,61,48,120,54,44,70,49,61,48,120,52,99,44,70,49,48,61,48,120,53,53,44,70,49,49,61,48,120,53,54,44,70,49,50,61,48,120,53,55,44,70,49,51,61,48,120,53,56,44,70,49,52,61,48,120,53,57,44,70,49,53,61,48,120,53,97,44,70,49,54,61,48,120,53,98,44,70,49,55,61,48,120,53,99,44,70,49,56,61,48,120,56,48,44,70,49,57,61,48,120,56,49,44,70,50,61,48,120,52,100,44,70,50,48,61,48,120,56,50,44,70,51,61,48,120,52,101,44,70,52,61,48,120,52,102,44,70,53,61,48,120,53,48,44,70,54,61,48,120,53,49,44,70,55,61,48,120,53,50,44,70,56,61,48,120,53,51,44,70,57,61,48,120,53,52,44,70,73,78,68,61,48,120,55,57,44,70,73,86,69,61,48,120,49,102,44,70,79,82,87,65,82,68,61,48,120,57,48,44,70,79,85,82,61,48,120,49,101,44,71,61,48,120,55,44,72,61,48,120,56,44,72,69,76,80,61,48,120,52,51,44,72,79,77,69,61,48,120,54,102,44,73,61,48,120,57,44,73,78,83,69,82,84,61,48,120,55,53,44,74,61,48,120,97,44,75,61,48,120,98,44,76,61,48,120,99,44,76,69,70,84,61,48,120,54,51,44,76,69,78,83,95,70,79,67,85,83,61,48,120,56,99,44,76,69,83,83,95,71,82,69,65,84,69,82,61,48,120,53,102,44,76,73,83,84,95,69,78,68,61,48,120,57,54,44,76,95,65,76,84,61,48,120,52,56,44,76,95,67,79,77,77,65,78,68,61,48,120,52,97,44,76,95,67,79,78,84,82,79,76,61,48,120,52,49,44,76,95,83,72,73,70,84,61,48,120,52,52,44,76,95,83,81,85,65,82,69,61,48,120,50,56,44,77,61,48,120,100,44,77,65,67,82,79,61,48,120,53,100,44,77,69,78,85,61,48,120,55,56,44,77,73,78,85,83,61,48,120,50,54,44,77,85,84,69,61,48,120,57,50,44,78,61,48,120,101,44,78,69,88,84,61,48,120,56,101,44,78,73,78,69,61,48,120,50,51,44,78,80,95,48,61,48,120,51,49,44,78,80,95,49,61,48,120,51,50,44,78,80,95,50,61,48,120,51,51,44,78,80,95,51,61,48,120,51,52,44,78,80,95,52,61,48,120,51,53,44,78,80,95,53,61,48,120,51,54,44,78,80,95,54,61,48,120,51,55,44,78,80,95,55,61,48,120,51,56,44,78,80,95,56,61,48,120,51,57,44,78,80,95,57,61,48,120,51,97,44,78,80,95,66,65,82,61,48,120,51,100,44,78,80,95,68,69,67,73,77,65,76,61,48,120,51,102,44,78,80,95,68,73,86,73,68,69,61,48,120,52,48,44,78,80,95,68,79,84,61,48,120,51,102,44,78,80,95,69,78,84,69,82,61,48,120,55,101,44,78,80,95,77,73,78,85,83,61,48,120,51,101,44,78,80,95,77,85,76,84,73,80,76,89,61,48,120,51,98,44,78,80,95,80,76,85,83,61,48,120,51,99,44,78,80,95,80,76,85,83,95,77,73,78,85,83,61,48,120,53,101,44,78,80,95,83,69,80,65,82,65,84,79,82,61,48,120,51,100,44,78,85,77,95,76,79,67,75,61,48,120,55,99,44,79,61,48,120,102,44,79,78,69,61,48,120,49,98,44,80,61,48,120,49,48,44,80,65,71,69,95,68,79,87,78,61,48,120,55,49,44,80,65,71,69,95,85,80,61,48,120,55,48,44,80,65,85,83,69,61,48,120,54,53,44,80,69,82,73,79,68,61,48,120,50,100,44,80,76,65,89,61,48,120,57,53,44,80,76,85,83,61,48,120,56,98,44,80,79,85,78,68,61,48,120,57,52,44,80,79,87,69,82,61,48,120,54,56,44,80,82,69,86,73,79,85,83,61,48,120,56,102,44,80,82,73,78,84,61,48,120,52,55,44,80,82,84,95,83,67,82,61,48,120,55,100,44,81,61,48,120,49,49,44,82,61,48,120,49,50,44,82,69,68,79,61,48,120,55,55,44,82,69,86,69,82,83,69,95,81,85,79,84,69,61,48,120,50,53,44,82,69,87,73,78,68,61,48,120,57,49,44,82,73,71,72,84,61,48,120,54,50,44,82,95,65,76,84,61,48,120,52,57,44,82,95,67,79,77,77,65,78,68,61,48,120,52,98,44,82,95,67,79,78,84,82,79,76,61,48,120,52,50,44,82,95,83,72,73,70,84,61,48,120,52,53,44,82,95,83,81,85,65,82,69,61,48,120,50,57,44,83,61,48,120,49,51,44,83,67,82,95,76,79,67,75,61,48,120,54,52,44,83,69,76,69,67,84,61,48,120,55,51,44,83,69,77,73,95,67,79,76,79,78,61,48,120,50,97,44,83,69,86,69,78,61,48,120,50,49,44,83,73,88,61,48,120,50,48,44,83,76,65,83,72,61,48,120,50,101,44,83,76,69,69,80,61,48,120,54,55,44,83,80,65,67,69,61,48,120,51,48,44,83,84,65,82,61,48,120,57,51,44,83,84,79,80,61,48,120,56,100,44,83,89,83,82,81,61,48,120,55,102,44,84,61,48,120,49,52,44,84,65,66,61,48,120,54,97,44,84,72,82,69,69,61,48,120,49,100,44,84,87,79,61,48,120,49,99,44,85,61,48,120,49,53,44,85,78,68,79,61,48,120,55,54,44,85,80,61,48,120,54,48,44,86,61,48,120,49,54,44,86,79,76,85,77,69,95,68,79,87,78,61,48,120,56,53,44,86,79,76,85,77,69,95,85,80,61,48,120,56,52,44,87,61,48,120,49,55,44,87,65,75,69,61,48,120,54,54,44,87,73,78,95,67,79,78,84,82,79,76,61,48,120,56,51,44,88,61,48,120,49,56,44,89,61,48,120,49,57,44,90,61,48,120,49,97,44,90,69,82,79,61,48,120,50,52,10,99,46,75,81,58,65,76,84,61,48,120,54,48,44,65,76,84,71,82,61,48,120,52,48,44,67,65,80,83,95,76,79,67,75,61,48,120,52,44,67,79,77,77,65,78,68,61,48,120,49,56,48,44,67,79,78,84,82,79,76,61,48,120,49,56,44,67,84,82,76,61,48,120,49,56,44,68,69,65,68,95,75,69,89,61,48,120,49,48,48,48,48,44,73,78,70,79,61,48,120,51,99,48,52,44,73,78,83,84,82,85,67,84,73,79,78,95,75,69,89,83,61,48,120,55,56,44,76,95,65,76,84,61,48,120,50,48,44,76,95,67,79,77,77,65,78,68,61,48,120,56,48,44,76,95,67,79,78,84,82,79,76,61,48,120,56,44,76,95,67,84,82,76,61,48,120,56,44,76,95,83,72,73,70,84,61,48,120,49,44,78,79,84,95,80,82,73,78,84,65,66,76,69,61,48,120,50,48,48,48,44,78,85,77,95,76,79,67,75,61,48,120,56,48,48,48,44,78,85,77,95,80,65,68,61,48,120,50,48,48,44,80,82,69,83,83,69,68,61,48,120,49,48,48,48,44,81,85,65,76,73,70,73,69,82,83,61,48,120,49,102,98,44,82,69,76,69,65,83,69,68,61,48,120,56,48,48,44,82,69,80,69,65,84,61,48,120,52,48,48,44,82,95,65,76,84,61,48,120,52,48,44,82,95,67,79,77,77,65,78,68,61,48,120,49,48,48,44,82,95,67,79,78,84,82,79,76,61,48,120,49,48,44,82,95,67,84,82,76,61,48,120,49,48,44,82,95,83,72,73,70,84,61,48,120,50,44,83,67,82,95,76,79,67,75,61,48,120,52,48,48,48,44,83,72,73,70,84,61,48,120,51,44,87,73,78,95,67,79,78,84,82,79,76,61,48,120,50,48,48,48,48,10,99,46,76,65,89,79,85,84,58,66,65,67,75,71,82,79,85,78,68,61,48,120,56,44,69,77,66,69,68,68,69,68,61,48,120,50,48,44,70,79,82,69,71,82,79,85,78,68,61,48,120,49,48,44,73,71,78,79,82,69,95,67,85,82,83,79,82,61,48,120,56,48,44,76,69,70,84,61,48,120,50,44,76,79,67,75,61,48,120,52,48,44,82,73,71,72,84,61,48,120,52,44,83,81,85,65,82,69,61,48,120,48,44,84,73,71,72,84,61,48,120,49,44,84,73,76,69,61,48,120,49,48,48,44,87,73,68,69,61,48,120,54,10,99,46,76,68,70,58,67,72,69,67,75,95,69,88,73,83,84,83,61,48,120,49,10,99,46,76,79,67,58,68,73,82,69,67,84,79,82,89,61,48,120,49,44,70,73,76,69,61,48,120,51,44,70,79,76,68,69,82,61,48,120,49,44,86,79,76,85,77,69,61,48,120,50,10,99,46,77,65,88,58,70,73,76,69,78,65,77,69,61,48,120,49,48,48,44,78,65,77,69,95,76,69,78,61,48,120,49,102,10,99,46,77,69,77,58,65,85,68,73,79,61,48,120,56,44,67,65,76,76,69,82,61,48,120,56,48,48,48,48,48,44,67,79,68,69,61,48,120,49,48,44,67,79,76,76,69,67,84,61,48,120,49,48,48,48,44,68,65,84,65,61,48,120,48,44,69,88,67,76,85,83,73,86,69,61,48,120,56,48,48,44,72,73,68,68,69,78,61,48,120,49,48,48,48,48,48,44,77,65,78,65,71,69,68,61,48,120,49,44,78,79,95,66,76,79,67,75,61,48,120,50,48,48,48,44,78,79,95,66,76,79,67,75,73,78,71,61,48,120,50,48,48,48,44,78,79,95,67,76,69,65,82,61,48,120,52,48,48,48,48,44,78,79,95,76,79,67,75,61,48,120,52,48,48,44,78,79,95,80,79,79,76,61,48,120,50,48,44,79,66,74,69,67,84,61,48,120,50,48,48,44,82,69,65,68,61,48,120,49,48,48,48,48,44,82,69,65,68,95,87,82,73,84,69,61,48,120,51,48,48,48,48,44,83,84,82,73,78,71,61,48,120,49,48,48,44,84,69,88,84,85,82,69,61,48,120,52,44,84,77,80,95,76,79,67,75,61,48,120,52,48,44,85,78,84,82,65,67,75,69,68,61,48,120,56,48,44,86,73,68,69,79,61,48,120,50,44,87,82,73,84,69,61,48,120,50,48,48,48,48,10,99,46,77,70,70,58,65,84,84,82,73,66,61,48,120,50,48,44,67,76,79,83,69,68,61,48,120,56,48,44,67,82,69,65,84,69,61,48,120,52,44,68,69,69,80,61,48,120,49,48,48,48,44,68,69,76,69,84,69,61,48,120,56,44,70,73,76,69,61,48,120,52,48,48,44,70,79,76,68,69,82,61,48,120,50,48,48,44,77,79,68,73,70,89,61,48,120,50,44,77,79,86,69,68,61,48,120,49,48,44,79,80,69,78,69,68,61,48,120,52,48,44,82,69,65,68,61,48,120,49,44,82,69,78,65,77,69,61,48,120,49,48,44,83,69,76,70,61,48,120,56,48,48,44,85,78,77,79,85,78,84,61,48,120,49,48,48,44,87,82,73,84,69,61,48,120,50,10,99,46,77,72,70,58,68,69,70,65,85,76,84,61,48,120,50,44,83,84,65,84,73,67,61,48,120,49,44,83,84,82,85,67,84,85,82,69,61,48,120,50,10,99,46,77,79,70,58,76,73,78,75,95,76,73,66,82,65,82,89,61,48,120,49,44,83,84,65,84,73,67,61,48,120,50,44,83,89,83,84,69,77,95,80,82,79,66,69,61,48,120,52,10,99,46,77,79,86,69,58,65,76,76,61,48,120,102,44,68,79,87,78,61,48,120,49,44,76,69,70,84,61,48,120,52,44,82,73,71,72,84,61,48,120,56,44,85,80,61,48,120,50,10,99,46,77,83,70,58,65,68,68,61,48,120,56,44,65,68,68,82,69,83,83,61,48,120,49,48,44,77,69,83,83,65,71,69,95,73,68,61,48,120,50,48,44,78,79,95,68,85,80,76,73,67,65,84,69,61,48,120,52,44,85,80,68,65,84,69,61,48,120,50,44,87,65,73,84,61,48,120,49,10,99,46,77,83,71,73,68,58,65,67,84,73,79,78,61,48,120,54,51,44,66,82,69,65,75,61,48,120,54,52,44,67,79,77,77,65,78,68,61,48,120,54,53,44,67,79,82,69,95,69,78,68,61,48,120,54,52,44,68,69,66,85,71,61,48,120,53,102,44,69,86,69,78,84,61,48,120,53,101,44,70,82,69,69,61,48,120,54,50,44,81,85,73,84,61,48,120,51,101,56,44,84,72,82,69,65,68,95,65,67,84,73,79,78,61,48,120,53,98,44,84,72,82,69,65,68,95,67,65,76,76,66,65,67,75,61,48,120,53,99,44,86,65,76,73,68,65,84,69,95,80,82,79,67,69,83,83,61,48,120,53,100,44,87,65,73,84,95,70,79,82,95,79,66,74,69,67,84,83,61,48,120,53,97,10,99,46,77,84,70,58,65,78,73,77,61,48,120,56,44,82,69,76,65,84,73,86,69,61,48,120,49,48,44,88,61,48,120,49,44,89,61,48,120,50,44,90,61,48,120,52,10,99,46,78,69,84,77,83,71,58,69,78,68,61,48,120,49,44,83,84,65,82,84,61,48,120,48,10,99,46,78,70,58,67,79,76,76,69,67,84,61,48,120,56,48,44,70,82,69,69,61,48,120,49,48,44,70,82,69,69,95,79,78,95,85,78,76,79,67,75,61,48,120,56,44,73,78,73,84,73,65,76,73,83,69,68,61,48,120,50,44,76,79,67,65,76,61,48,120,52,44,77,69,83,83,65,71,69,61,48,120,50,48,48,44,78,65,77,69,61,48,120,56,48,48,48,48,48,48,48,44,80,82,73,86,65,84,69,61,48,120,48,44,82,69,67,76,65,83,83,69,68,61,48,120,49,48,48,44,83,73,71,78,65,76,76,69,68,61,48,120,52,48,48,44,83,85,80,80,82,69,83,83,95,76,79,71,61,48,120,52,48,44,84,73,77,69,82,95,83,85,66,61,48,120,50,48,44,85,78,73,81,85,69,61,48,120,52,48,48,48,48,48,48,48,44,85,78,84,82,65,67,75,69,68,61,48,120,49,10,99,46,79,80,70,58,65,82,71,83,61,48,120,52,48,44,68,69,84,65,73,76,61,48,120,52,44,69,82,82,79,82,61,48,120,56,48,44,77,65,88,95,68,69,80,84,72,61,48,120,50,44,77,79,68,85,76,69,95,80,65,84,72,61,48,120,52,48,48,44,79,80,84,73,79,78,83,61,48,120,49,44,80,82,73,86,73,76,69,71,69,68,61,48,120,49,48,48,44,82,79,79,84,95,80,65,84,72,61,48,120,56,48,48,44,83,67,65,78,95,77,79,68,85,76,69,83,61,48,120,49,48,48,48,44,83,72,79,87,95,69,82,82,79,82,83,61,48,120,50,48,44,83,72,79,87,95,73,79,61,48,120,49,48,44,83,72,79,87,95,77,69,77,79,82,89,61,48,120,56,44,83,89,83,84,69,77,95,80,65,84,72,61,48,120,50,48,48,10,99,46,80,69,82,77,73,84,58,65,76,76,95,68,69,76,69,84,69,61,48,120,56,56,56,44,65,76,76,95,69,88,69,67,61,48,120,52,52,52,44,65,76,76,95,82,69,65,68,61,48,120,49,49,49,44,65,76,76,95,87,82,73,84,69,61,48,120,50,50,50,44,65,82,67,72,73,86,69,61,48,120,50,48,48,48,44,68,69,76,69,84,69,61,48,120,56,44,69,86,69,82,89,79,78,69,95,65,67,67,69,83,83,61,48,120,102,102,102,44,69,86,69,82,89,79,78,69,95,68,69,76,69,84,69,61,48,120,56,56,56,44,69,86,69,82,89,79,78,69,95,69,88,69,67,61,48,120,52,52,52,44,69,86,69,82,89,79,78,69,95,82,69,65,68,61,48,120,49,49,49,44,69,86,69,82,89,79,78,69,95,82,69,65,68,87,82,73,84,69,61,48,120,51,51,51,44,69,86,69,82,89,79,78,69,95,87,82,73,84,69,61,48,120,50,50,50,44,69,88,69,67,61,48,120,52,44,71,82,79,85,80,61,48,120,102,48,44,71,82,79,85,80,73,68,61,48,120,49,48,48,48,48,44,71,82,79,85,80,95,68,69,76,69,84,69,61,48,120,56,48,44,71,82,79,85,80,95,69,88,69,67,61,48,120,52,48,44,71,82,79,85,80,95,82,69,65,68,61,48,120,49,48,44,71,82,79,85,80,95,87,82,73,84,69,61,48,120,50,48,44,72,73,68,68,69,78,61,48,120,49,48,48,48,44,73,78,72,69,82,73,84,61,48,120,50,48,48,48,48,44,78,69,84,87,79,82,75,61,48,120,56,48,48,48,48,44,79,70,70,76,73,78,69,61,48,120,52,48,48,48,48,44,79,84,72,69,82,83,61,48,120,102,48,48,44,79,84,72,69,82,83,95,68,69,76,69,84,69,61,48,120,56,48,48,44,79,84,72,69,82,83,95,69,88,69,67,61,48,120,52,48,48,44,79,84,72,69,82,83,95,82,69,65,68,61,48,120,49,48,48,44,79,84,72,69,82,83,95,87,82,73,84,69,61,48,120,50,48,48,44,80,65,83,83,87,79,82,68,61,48,120,52,48,48,48,44,82,69,65,68,61,48,120,49,44,85,83,69,82,61,48,120,102,44,85,83,69,82,73,68,61,48,120,56,48,48,48,44,85,83,69,82,95,69,88,69,67,61,48,120,52,44,85,83,69,82,95,82,69,65,68,61,48,120,49,44,85,83,69,82,95,87,82,73,84,69,61,48,120,50,44,87,82,73,84,69,61,48,120,50,10,99,46,80,77,70,58,83,89,83,84,69,77,95,78,79,95,66,82,69,65,75,61,48,120,49,10,99,46,80,84,67,58,67,82,79,83,83,72,65,73,82,61,48,120,97,44,67,85,83,84,79,77,61,48,120,49,55,44,68,69,70,65,85,76,84,61,48,120,49,44,68,82,65,71,71,65,66,76,69,61,48,120,49,56,44,69,78,68,61,48,120,49,57,44,72,65,78,68,61,48,120,49,48,44,72,65,78,68,95,76,69,70,84,61,48,120,49,49,44,72,65,78,68,95,82,73,71,72,84,61,48,120,49,50,44,73,78,86,73,83,73,66,76,69,61,48,120,49,54,44,77,65,71,78,73,70,73,69,82,61,48,120,102,44,78,79,95,67,72,65,78,71,69,61,48,120,48,44,80,65,73,78,84,66,82,85,83,72,61,48,120,49,52,44,83,73,90,69,95,66,79,84,84,79,77,61,48,120,57,44,83,73,90,69,95,66,79,84,84,79,77,95,76,69,70,84,61,48,120,50,44,83,73,90,69,95,66,79,84,84,79,77,95,82,73,71,72,84,61,48,120,51,44,83,73,90,69,95,76,69,70,84,61,48,120,54,44,83,73,90,69,95,82,73,71,72,84,61,48,120,55,44,83,73,90,69,95,84,79,80,61,48,120,56,44,83,73,90,69,95,84,79,80,95,76,69,70,84,61,48,120,52,44,83,73,90,69,95,84,79,80,95,82,73,71,72,84,61,48,120,53,44,83,73,90,73,78,71,61,48,120,99,44,83,76,69,69,80,61,48,120,98,44,83,80,76,73,84,95,72,79,82,73,90,79,78,84,65,76,61,48,120,101,44,83,80,76,73,84,95,86,69,82,84,73,67,65,76,61,48,120,100,44,83,84,79,80,61,48,120,49,53,44,84,69,88,84,61,48,120,49,51,10,99,46,82,68,70,58,65,82,67,72,73,86,69,61,48,120,50,48,48,48,44,68,65,84,69,61,48,120,50,44,70,73,76,69,61,48,120,56,44,70,73,76,69,83,61,48,120,56,44,70,79,76,68,69,82,61,48,120,49,48,44,70,79,76,68,69,82,83,61,48,120,49,48,44,72,73,68,68,69,78,61,48,120,49,48,48,44,76,73,78,75,61,48,120,52,48,44,79,80,69,78,68,73,82,61,48,120,52,48,48,48,44,80,69,82,77,73,83,83,73,79,78,83,61,48,120,52,44,81,85,65,76,73,70,73,69,68,61,48,120,50,48,48,44,81,85,65,76,73,70,89,61,48,120,50,48,48,44,82,69,65,68,95,65,76,76,61,48,120,49,102,44,82,69,65,68,95,79,78,76,89,61,48,120,49,48,48,48,44,83,73,90,69,61,48,120,49,44,83,84,82,69,65,77,61,48,120,56,48,48,44,84,65,71,83,61,48,120,56,48,44,84,73,77,69,61,48,120,50,44,86,73,82,84,85,65,76,61,48,120,52,48,48,44,86,79,76,85,77,69,61,48,120,50,48,10,99,46,82,69,83,58,67,79,78,83,79,76,69,95,70,68,61,48,120,50,44,67,79,82,69,95,73,68,76,61,48,120,56,44,67,80,85,95,83,80,69,69,68,61,48,120,49,54,44,68,73,83,80,76,65,89,95,68,82,73,86,69,82,61,48,120,53,44,69,88,67,69,80,84,73,79,78,95,72,65,78,68,76,69,82,61,48,120,49,49,44,70,82,69,69,95,77,69,77,79,82,89,61,48,120,49,55,44,70,82,69,69,95,83,87,65,80,61,48,120,49,44,74,78,73,95,69,78,86,61,48,120,101,44,75,69,89,95,83,84,65,84,69,61,48,120,51,44,76,79,71,95,68,69,80,84,72,61,48,120,100,44,76,79,71,95,76,69,86,69,76,61,48,120,97,44,77,65,88,95,80,82,79,67,69,83,83,69,83,61,48,120,99,44,78,69,84,95,80,82,79,67,69,83,83,73,78,71,61,48,120,49,50,44,79,80,69,78,95,73,78,70,79,61,48,120,49,48,44,80,82,73,86,73,76,69,71,69,68,61,48,120,55,44,80,82,73,86,73,76,69,71,69,68,95,85,83,69,82,61,48,120,54,44,80,82,79,67,69,83,83,95,83,84,65,84,69,61,48,120,49,51,44,83,84,65,84,73,67,95,66,85,73,76,68,61,48,120,57,44,84,72,82,69,65,68,95,73,68,61,48,120,102,44,84,79,84,65,76,95,77,69,77,79,82,89,61,48,120,49,52,44,84,79,84,65,76,95,83,72,65,82,69,68,95,77,69,77,79,82,89,61,48,120,98,44,84,79,84,65,76,95,83,87,65,80,61,48,120,49,53,44,85,83,69,82,95,73,68,61,48,120,52,10,99,46,82,70,68,58,65,76,76,79,87,95,82,69,67,85,82,83,73,79,78,61,48,120,50,48,44,65,76,87,65,89,83,95,67,65,76,76,61,48,120,49,48,48,44,69,88,67,69,80,84,61,48,120,50,44,82,69,65,68,61,48,120,52,44,82,69,67,65,76,76,61,48,120,56,48,44,82,69,77,79,86,69,61,48,120,56,44,83,79,67,75,69,84,61,48,120,52,48,44,83,84,79,80,95,82,69,67,85,82,83,69,61,48,120,49,48,44,87,82,73,84,69,61,48,120,49,10,99,46,82,80,58,77,79,68,85,76,69,95,80,65,84,72,61,48,120,49,44,82,79,79,84,95,80,65,84,72,61,48,120,51,44,83,89,83,84,69,77,95,80,65,84,72,61,48,120,50,10,99,46,82,83,70,58,65,80,80,82,79,88,73,77,65,84,69,61,48,120,52,44,67,65,83,69,95,83,69,78,83,73,84,73,86,69,61,48,120,50,48,44,67,72,69,67,75,95,86,73,82,84,85,65,76,61,48,120,50,44,78,79,95,68,69,69,80,95,83,67,65,78,61,48,120,56,44,78,79,95,70,73,76,69,95,67,72,69,67,75,61,48,120,49,44,80,65,84,72,61,48,120,49,48,10,99,46,83,67,70,58,69,88,73,84,95,79,78,95,69,82,82,79,82,61,48,120,49,44,76,79,71,95,65,76,76,61,48,120,50,10,99,46,83,69,69,75,58,67,85,82,82,69,78,84,61,48,120,49,44,69,78,68,61,48,120,50,44,82,69,76,65,84,73,86,69,61,48,120,51,44,83,84,65,82,84,61,48,120,48,10,99,46,83,84,82,58,67,65,83,69,61,48,120,49,44,77,65,84,67,72,95,67,65,83,69,61,48,120,49,44,77,65,84,67,72,95,76,69,78,61,48,120,50,10,99,46,83,84,84,58,70,76,79,65,84,61,48,120,50,44,72,69,88,61,48,120,51,44,78,85,77,66,69,82,61,48,120,49,44,83,84,82,73,78,71,61,48,120,52,10,99,46,84,72,70,58,65,85,84,79,95,70,82,69,69,61,48,120,49,10,99,46,84,79,73,58,65,78,68,82,79,73,68,95,65,83,83,69,84,77,71,82,61,48,120,52,44,65,78,68,82,79,73,68,95,67,76,65,83,83,61,48,120,51,44,65,78,68,82,79,73,68,95,69,78,86,61,48,120,50,44,76,79,67,65,76,95,67,65,67,72,69,61,48,120,48,44,76,79,67,65,76,95,83,84,79,82,65,71,69,61,48,120,49,10,99,46,84,83,70,58,65,84,84,65,67,72,69,68,61,48,120,49,48,48,44,68,69,84,65,67,72,69,68,61,48,120,56,48,44,70,79,82,69,73,71,78,61,48,120,49,44,76,79,71,95,65,76,76,61,48,120,50,48,44,80,73,80,69,61,48,120,50,48,48,44,80,82,73,86,73,76,69,71,69,68,61,48,120,56,44,81,85,73,69,84,61,48,120,52,48,44,82,69,83,69,84,95,80,65,84,72,61,48,120,52,44,83,72,69,76,76,61,48,120,49,48,44,87,65,73,84,61,48,120,50,10,99,46,84,83,84,65,84,69,58,80,65,85,83,69,68,61,48,120,49,44,82,85,78,78,73,78,71,61,48,120,48,44,83,84,79,80,80,73,78,71,61,48,120,50,44,84,69,82,77,73,78,65,84,69,68,61,48,120,51,10,99,46,86,65,83,58,67,65,83,69,95,83,69,78,83,73,84,73,86,69,61,48,120,102,44,67,76,79,83,69,95,68,73,82,61,48,120,54,44,67,82,69,65,84,69,95,76,73,78,75,61,48,120,49,49,44,68,69,76,69,84,69,61,48,120,51,44,68,69,82,69,71,73,83,84,69,82,61,48,120,49,44,68,82,73,86,69,82,95,83,73,90,69,61,48,120,49,50,44,71,69,84,95,68,69,86,73,67,69,95,73,78,70,79,61,48,120,98,44,71,69,84,95,73,78,70,79,61,48,120,97,44,73,68,69,78,84,73,70,89,95,70,73,76,69,61,48,120,99,44,73,71,78,79,82,69,95,70,73,76,69,61,48,120,57,44,77,65,75,69,95,68,73,82,61,48,120,100,44,79,80,69,78,95,68,73,82,61,48,120,53,44,82,69,65,68,95,76,73,78,75,61,48,120,49,48,44,82,69,78,65,77,69,61,48,120,52,44,83,65,77,69,95,70,73,76,69,61,48,120,101,44,83,67,65,78,95,68,73,82,61,48,120,50,44,84,69,83,84,95,80,65,84,72,61,48,120,55,44,87,65,84,67,72,95,80,65,84,72,61,48,120,56,10,99,46,86,76,70,58,65,80,73,61,48,120,50,48,44,66,82,65,78,67,72,61,48,120,49,44,67,82,73,84,73,67,65,76,61,48,120,56,44,68,69,84,65,73,76,61,48,120,52,48,44,69,82,82,79,82,61,48,120,50,44,70,85,78,67,84,73,79,78,61,48,120,49,48,48,44,73,78,70,79,61,48,120,49,48,44,84,82,65,67,69,61,48,120,56,48,44,87,65,82,78,73,78,71,61,48,120,52,10,99,46,86,79,76,85,77,69,58,72,73,68,68,69,78,61,48,120,52,44,80,82,73,79,82,73,84,89,61,48,120,50,44,82,69,80,76,65,67,69,61,48,120,49,44,83,89,83,84,69,77,61,48,120,56,10,0 }; diff --git a/src/core/lib_fields_read.cpp b/src/core/lib_fields_read.cpp index cc3136d7d..30cd752a7 100644 --- a/src/core/lib_fields_read.cpp +++ b/src/core/lib_fields_read.cpp @@ -520,14 +520,12 @@ ERR GetFieldVariable(OBJECTPTR Object, CSTRING FieldName, STRING Buffer, LONG Bu ERR copy_field_to_buffer(OBJECTPTR Object, Field *Field, LONG DestFlags, APTR Result, CSTRING Option, LONG *TotalElements) { - pf::Log log("GetField"); - //log.msg("[%s:%d] Name: %s, Flags: $%x", ((extMetaClass *)Object->Class)->Name, Object->UID, Field->Name, DestFlags); BYTE value[16]; // 128 bits of space APTR data; LONG array_size = -1; - LONG srcflags = Field->Flags; + auto srcflags = Field->Flags; if (!(DestFlags & (FD_UNIT|FD_LARGE|FD_LONG|FD_DOUBLE|FD_POINTER|FD_STRING|FD_ARRAY))) goto mismatch; @@ -622,6 +620,7 @@ ERR copy_field_to_buffer(OBJECTPTR Object, Field *Field, LONG DestFlags, APTR Re } else { if (array_size IS -1) { + pf::Log log("GetField"); log.warning("Array sizing not supported for field %s", Field->Name); return ERR::Failed; } @@ -732,13 +731,14 @@ ERR copy_field_to_buffer(OBJECTPTR Object, Field *Field, LONG DestFlags, APTR Re else goto mismatch; } else { - log.warning("I dont recognise field flags of $%.8x.", srcflags); - return ERR::UnrecognisedFieldType; + pf::Log log("GetField"); + return log.warning(ERR::UnrecognisedFieldType); } return ERR::Okay; mismatch: + pf::Log log("GetField"); log.warning("Mismatch while reading %s.%s (field $%.8x, requested $%.8x).", Object->className(), Field->Name, Field->Flags, DestFlags); return ERR::FieldTypeMismatch; } diff --git a/src/display/class_pointer.cpp b/src/display/class_pointer.cpp index bb7ce7e46..e32c3bfeb 100644 --- a/src/display/class_pointer.cpp +++ b/src/display/class_pointer.cpp @@ -351,14 +351,6 @@ static void process_ptr_movement(extPointer *Self, struct dcDeviceInput *Input) if (!userinput.Timestamp) userinput.Timestamp = PreciseTime(); - // All X/Y movement passed through the pointer object must be expressed in absolute coordinates. - - if ((userinput.Type IS JET::DIGITAL_XY) or (userinput.Type IS JET::ANALOG_XY)) { - userinput.Type = JET::ABS_XY; - userinput.X += Self->X; - userinput.Y += Self->Y; - } - bool moved = false, underlying_change = false; DOUBLE current_x = Self->X; DOUBLE current_y = Self->Y; diff --git a/src/display/class_surface/surface_def.c b/src/display/class_surface/surface_def.c index fb919e53c..a826a9389 100644 --- a/src/display/class_surface/surface_def.c +++ b/src/display/class_surface/surface_def.c @@ -178,42 +178,29 @@ static const struct FieldDef clSurfaceJTYPE[] = { }; static const struct FieldDef clSurfaceJET[] = { - { "DigitalXY", 0x00000001 }, - { "Button1", 0x00000002 }, - { "Lmb", 0x00000002 }, - { "Button2", 0x00000003 }, - { "Rmb", 0x00000003 }, - { "Button3", 0x00000004 }, - { "Mmb", 0x00000004 }, - { "Button4", 0x00000005 }, - { "Button5", 0x00000006 }, - { "Button6", 0x00000007 }, - { "Button7", 0x00000008 }, - { "Button8", 0x00000009 }, - { "Button9", 0x0000000a }, - { "Button10", 0x0000000b }, - { "TriggerLeft", 0x0000000c }, - { "TriggerRight", 0x0000000d }, - { "ButtonStart", 0x0000000e }, - { "ButtonSelect", 0x0000000f }, - { "LeftBumper1", 0x00000010 }, - { "LeftBumper2", 0x00000011 }, - { "RightBumper1", 0x00000012 }, - { "RightBumper2", 0x00000013 }, - { "AnalogXY", 0x00000014 }, - { "AnalogZ", 0x00000015 }, - { "Analog2XY", 0x00000016 }, - { "Analog2Z", 0x00000017 }, - { "Wheel", 0x00000018 }, - { "WheelTilt", 0x00000019 }, - { "PenTiltXY", 0x0000001a }, - { "AbsXY", 0x0000001b }, - { "CrossedIn", 0x0000001c }, - { "CrossedOut", 0x0000001d }, - { "Pressure", 0x0000001e }, - { "DeviceTiltXY", 0x0000001f }, - { "DeviceTiltZ", 0x00000020 }, - { "DisplayEdge", 0x00000021 }, + { "Button1", 0x00000001 }, + { "Lmb", 0x00000001 }, + { "Button2", 0x00000002 }, + { "Rmb", 0x00000002 }, + { "Button3", 0x00000003 }, + { "Mmb", 0x00000003 }, + { "Button4", 0x00000004 }, + { "Button5", 0x00000005 }, + { "Button6", 0x00000006 }, + { "Button7", 0x00000007 }, + { "Button8", 0x00000008 }, + { "Button9", 0x00000009 }, + { "Button10", 0x0000000a }, + { "Wheel", 0x0000000b }, + { "WheelTilt", 0x0000000c }, + { "PenTiltXY", 0x0000000d }, + { "AbsXY", 0x0000000e }, + { "CrossedIn", 0x0000000f }, + { "CrossedOut", 0x00000010 }, + { "Pressure", 0x00000011 }, + { "DeviceTiltXY", 0x00000012 }, + { "DeviceTiltZ", 0x00000013 }, + { "DisplayEdge", 0x00000014 }, { NULL, 0 } }; diff --git a/src/display/display-driver.cpp b/src/display/display-driver.cpp index 1c1e35668..9bb3ccc91 100644 --- a/src/display/display-driver.cpp +++ b/src/display/display-driver.cpp @@ -105,7 +105,6 @@ static void android_term_window(LONG); const InputType glInputType[LONG(JET::END)] = { { JTYPE::NIL, JTYPE::NIL }, // UNUSED - { JTYPE::DIGITAL|JTYPE::MOVEMENT, JTYPE::MOVEMENT }, // JET::DIGITAL_XY { JTYPE::BUTTON, JTYPE::BUTTON }, // JET::BUTTON_1 { JTYPE::BUTTON, JTYPE::BUTTON }, // JET::BUTTON_2 { JTYPE::BUTTON, JTYPE::BUTTON }, // JET::BUTTON_3 @@ -116,33 +115,20 @@ const InputType glInputType[LONG(JET::END)] = { { JTYPE::BUTTON, JTYPE::BUTTON }, // JET::BUTTON_8 { JTYPE::BUTTON, JTYPE::BUTTON }, // JET::BUTTON_9 { JTYPE::BUTTON, JTYPE::BUTTON }, // JET::BUTTON_10 - { JTYPE::BUTTON, JTYPE::BUTTON }, // JET::TRIGGER_LEFT - { JTYPE::BUTTON, JTYPE::BUTTON }, // JET::TRIGGER_RIGHT - { JTYPE::BUTTON, JTYPE::BUTTON }, // JET::BUTTON_START - { JTYPE::BUTTON, JTYPE::BUTTON }, // JET::BUTTON_SELECT - { JTYPE::BUTTON, JTYPE::BUTTON }, // JET::LEFT_BUMPER_1 - { JTYPE::BUTTON, JTYPE::BUTTON }, // JET::LEFT_BUMPER_2 - { JTYPE::BUTTON, JTYPE::BUTTON }, // JET::RIGHT_BUMPER_1 - { JTYPE::BUTTON, JTYPE::BUTTON }, // JET::RIGHT_BUMPER_2 - { JTYPE::ANALOG|JTYPE::MOVEMENT, JTYPE::MOVEMENT }, // JET::ANALOG_XY - { JTYPE::ANALOG|JTYPE::MOVEMENT, JTYPE::MOVEMENT }, // JET::ANALOG_Z - { JTYPE::ANALOG|JTYPE::MOVEMENT, JTYPE::MOVEMENT }, // JET::ANALOG2_XY - { JTYPE::ANALOG|JTYPE::MOVEMENT, JTYPE::MOVEMENT }, // JET::ANALOG2_Z { JTYPE::EXT_MOVEMENT, JTYPE::EXT_MOVEMENT }, // JET::WHEEL { JTYPE::EXT_MOVEMENT, JTYPE::EXT_MOVEMENT }, // JET::WHEEL_TILT { JTYPE::EXT_MOVEMENT, JTYPE::EXT_MOVEMENT }, // JET::PEN_TILT_XY - { JTYPE::MOVEMENT, JTYPE::MOVEMENT }, // JET::ABS_XY - { JTYPE::CROSSING, JTYPE::CROSSING }, // JET::CROSSING_IN - { JTYPE::CROSSING, JTYPE::CROSSING }, // JET::CROSSING_OUT + { JTYPE::MOVEMENT, JTYPE::MOVEMENT }, // JET::ABS_XY + { JTYPE::CROSSING, JTYPE::CROSSING }, // JET::CROSSING_IN + { JTYPE::CROSSING, JTYPE::CROSSING }, // JET::CROSSING_OUT { JTYPE::EXT_MOVEMENT, JTYPE::EXT_MOVEMENT }, // JET::PRESSURE { JTYPE::EXT_MOVEMENT, JTYPE::EXT_MOVEMENT }, // JET::DEVICE_TILT_XY { JTYPE::EXT_MOVEMENT, JTYPE::EXT_MOVEMENT }, // JET::DEVICE_TILT_Z - { JTYPE::EXT_MOVEMENT, JTYPE::EXT_MOVEMENT } // JET::DISPLAY_EDGE + { JTYPE::EXT_MOVEMENT, JTYPE::EXT_MOVEMENT } // JET::DISPLAY_EDGE }; const CSTRING glInputNames[LONG(JET::END)] = { "", - "DIGITAL_XY", "BUTTON_1", "BUTTON_2", "BUTTON_3", @@ -153,18 +139,6 @@ const CSTRING glInputNames[LONG(JET::END)] = { "BUTTON_8", "BUTTON_9", "BUTTON_10", - "TRIGGER_LEFT", - "TRIGGER_RIGHT", - "BUTTON_START", - "BUTTON_SELECT", - "LEFT_BUMPER_1", - "LEFT_BUMPER_2", - "RIGHT_BUMPER_1", - "RIGHT_BUMPER_2", - "ANALOG_XY", - "ANALOG_Z", - "ANALOG2_XY", - "ANALOG2_Z", "WHEEL", "WHEEL_TILT", "PEN_TILT_XY", diff --git a/src/display/win32/windows.cpp b/src/display/win32/windows.cpp index e25d16043..0b1756813 100644 --- a/src/display/win32/windows.cpp +++ b/src/display/win32/windows.cpp @@ -924,11 +924,11 @@ static LRESULT CALLBACK WindowProcedure(HWND window, UINT msgcode, WPARAM wParam case WM_RBUTTONUP: HandleButtonRelease(window, WIN_RMB); return 0; case WM_MBUTTONUP: HandleButtonRelease(window, WIN_MMB); return 0; - case WM_NCMOUSEMOVE: - HandleMovement(window, wParam, lParam, true); + case WM_NCMOUSEMOVE: + HandleMovement(window, wParam, lParam, true); return DefWindowProc(window, msgcode, wParam, lParam); - - case WM_NCLBUTTONDOWN: + + case WM_NCLBUTTONDOWN: // Click detected on the titlebar or resize area. Quirks in the way that Windows manages // mouse input mean that we need to signal a button press and release consecutively. MsgButtonPress(WIN_LMB|WIN_NONCLIENT, 1); @@ -938,7 +938,7 @@ static LRESULT CALLBACK WindowProcedure(HWND window, UINT msgcode, WPARAM wParam case WM_NCLBUTTONDBLCLK: // Double-click detected on the titlebar MsgButtonPress(WIN_DBL|WIN_LMB|WIN_NONCLIENT, 1); MsgButtonPress(WIN_DBL|WIN_LMB|WIN_NONCLIENT, 0); - return DefWindowProc(window, msgcode, wParam, lParam); + return DefWindowProc(window, msgcode, wParam, lParam); case WM_ICONNOTIFY: if (lParam == WM_LBUTTONDOWN) { From 28ad27dba0a8a715ace91c0fa8355c35863a30f1 Mon Sep 17 00:00:00 2001 From: Paul Manias Date: Thu, 5 Dec 2024 09:23:18 +0000 Subject: [PATCH 3/9] Support for game controllers (WIP) --- docs/xml/modules/classes/controller.xml | 97 ++++++++++++++++++++++ docs/xml/modules/classes/display.xml | 50 +++--------- docs/xml/modules/display.xml | 2 + include/parasol/modules/display.h | 45 ++++++++++- scripts/gui/window.fluid | 10 ++- src/display/CMakeLists.txt | 6 +- src/display/class_controller.cpp | 103 ++++++++++++++++++++++++ src/display/class_controller_def.c | 25 ++++++ src/display/class_display.cpp | 86 ++++---------------- src/display/class_display_def.c | 1 + src/display/defs.h | 20 ++--- src/display/display-driver.cpp | 5 +- src/display/display.fdl | 12 +++ src/display/idl.h | 2 +- src/display/win32/handlers.cpp | 15 ++++ src/display/win32/windows.cpp | 36 ++++++++- src/display/win32/windows.h | 2 + src/svg/gradients.cpp | 2 +- 18 files changed, 382 insertions(+), 137 deletions(-) create mode 100644 docs/xml/modules/classes/controller.xml create mode 100644 src/display/class_controller.cpp create mode 100644 src/display/class_controller_def.c diff --git a/docs/xml/modules/classes/controller.xml b/docs/xml/modules/classes/controller.xml new file mode 100644 index 000000000..e4db4b9b9 --- /dev/null +++ b/docs/xml/modules/classes/controller.xml @@ -0,0 +1,97 @@ + + + + + + Controller + class + Display + Provides support for reading state-based game controllers. + 1 + bf67c809 + ID_CONTROLLER + IO + modules/controller.h + Paul Manias 2003-2024 + +

Use the Controller class to read the state of game controllers that are recognised by the operating system.

+

Unlike analog devices that stream input commands (e.g. mice), gamepad controllers maintain a state that can be read at any time. Typically the controller state is read at least once per frame, which can be achieved in the main inner loop, or in a separate timer.

+

Controller input management is governed by the Display class. The GRAB_CONTROLLERS flag must be defined in the active Display's Flags field in order to ensure that controller input can be received. Failure to do so may mean that the Controller object appears to work but does not receive input.

+ + class_controller.cpp + +
+ + + + Query + Get the current controller state. + ERR acQuery(*Object) + + + + + + + Buttons + JET button values expressed as bit-fields. + Read + CON + + + + + + + LeftStickX + Left analog stick value for X axis, between -1.0 and 1.0. + Read + DOUBLE + + + + LeftStickY + Left analog stick value for Y axis, between -1.0 and 1.0. + Read + DOUBLE + + + + LeftTrigger + Left trigger value between 0.0 and 1.0. + Read + DOUBLE + + + + Port + The port number assigned to the controller. + Read/Init + INT + + + + RightStickX + Right analog stick value for X axis, between -1.0 and 1.0. + Read + DOUBLE + + + + RightStickY + Right analog stick value for Y axis, between -1.0 and 1.0. + Read + DOUBLE + + + + RightTrigger + Right trigger value between 0.0 and 1.0. + Read + DOUBLE + + + + + +
diff --git a/docs/xml/modules/classes/display.xml b/docs/xml/modules/classes/display.xml index 4a0196988..f4b2ecab1 100644 --- a/docs/xml/modules/classes/display.xml +++ b/docs/xml/modules/classes/display.xml @@ -397,22 +397,23 @@ - CertificationDate - String describing the date of the graphics driver's certification. + Chipset + String describing the graphics chipset. Get STRING -

The string in this field describes the date on which the graphics card driver was certified. If this information is not available from the driver, a NULL pointer is returned.

+

This string describes the graphic card's chipset, if known.

- Chipset - String describing the graphics chipset. + ControllerPorts + Indicates the total number of connected controllers. Get - STRING + INT -

The string in this field describes the graphic card's chipset. If this information is not retrievable, a NULL pointer is returned.

+

Read the ControllerPorts value to get the total number of controllers connected to the system. This value can be used in conjunction with the Controller class to read state from multiple controllers.

+

It is required that the GRAB_CONTROLLERS flag is set in the Flags field in order for a program to access any connected controllers.

@@ -422,7 +423,7 @@ Get STRING -

The string in this field describes the display device that is connected to the user's graphics card. If this information is not detectable, a NULL pointer is returned.

+

This string describes the display device that is connected to the user's graphics card.

@@ -432,7 +433,7 @@ Get STRING -

The string in this field returns the name of the manufacturer that created the user's display device. If this information is not detectable, a NULL pointer is returned.

+

This string names the manufacturer of the user's display device.

@@ -447,36 +448,6 @@ - - DriverCopyright - String containing copyright information on the graphics driver software. - Get - STRING - -

The string in this field returns copyright information related to the graphics driver. If this information is not available, a NULL pointer is returned.

-
-
- - - DriverVendor - String describing the vendor of the graphics driver. - Get - STRING - -

The string in this field returns the name of the vendor that supplied the graphics card driver. If this information is not available, a NULL pointer is returned.

-
-
- - - DriverVersion - String describing the version of the graphics hardware driver. - Get - STRING - -

The string in this field describes the graphic driver's version number. If this information is not detectable, a NULL pointer is returned.

-
-
- Flags Optional flag settings. @@ -783,6 +754,7 @@ The display has been created with a custom window reference. Power saving through DPMS is supported. If SCR::BUFFER is used, this flag may be set by the display manager if it is possible to flip the buffer. + Grab controllers for receiving input when the display has the focus. GTF frequency timings are supported. The display is a desktop hosted window. Special win32 flag. diff --git a/docs/xml/modules/display.xml b/docs/xml/modules/display.xml index 485fbb4f7..8b7c2503c 100644 --- a/docs/xml/modules/display.xml +++ b/docs/xml/modules/display.xml @@ -12,6 +12,7 @@ Bitmap Clipboard + Controller Display Pointer Surface @@ -1218,6 +1219,7 @@ Alpha = CFUnpackAlpha(Format,Colour) The display has been created with a custom window reference. Power saving through DPMS is supported. If SCR::BUFFER is used, this flag may be set by the display manager if it is possible to flip the buffer. + Grab controllers for receiving input when the display has the focus. GTF frequency timings are supported. The display is a desktop hosted window. Special win32 flag. diff --git a/include/parasol/modules/display.h b/include/parasol/modules/display.h index 5b20276e3..1ad7dc0a5 100644 --- a/include/parasol/modules/display.h +++ b/include/parasol/modules/display.h @@ -18,6 +18,7 @@ class objBitmap; class objDisplay; class objClipboard; +class objController; class objPointer; class objSurface; @@ -282,6 +283,7 @@ enum class SCR : ULONG { BORDERLESS = 0x00000020, COMPOSITE = 0x00000040, ALPHA_BLEND = 0x00000040, + GRAB_CONTROLLERS = 0x00000080, MAXSIZE = 0x00100000, REFRESH = 0x00200000, HOSTED = 0x02000000, @@ -1009,7 +1011,7 @@ class objDisplay : public Object { inline ERR setRefreshRate(const DOUBLE Value) noexcept { auto target = this; - auto field = &this->Class->Dictionary[43]; + auto field = &this->Class->Dictionary[40]; return field->WriteValue(target, field, FD_DOUBLE, &Value, 1); } @@ -1060,7 +1062,7 @@ class objDisplay : public Object { inline ERR setPopOver(OBJECTID Value) noexcept { auto target = this; - auto field = &this->Class->Dictionary[27]; + auto field = &this->Class->Dictionary[26]; return field->WriteValue(target, field, FD_LONG, &Value, 1); } @@ -1090,13 +1092,13 @@ class objDisplay : public Object { inline ERR setResizeFeedback(const FUNCTION Value) noexcept { auto target = this; - auto field = &this->Class->Dictionary[32]; + auto field = &this->Class->Dictionary[30]; return field->WriteValue(target, field, FD_FUNCTION, &Value, 1); } inline ERR setWindowHandle(APTR Value) noexcept { auto target = this; - auto field = &this->Class->Dictionary[11]; + auto field = &this->Class->Dictionary[12]; return field->WriteValue(target, field, 0x08000308, Value, 1); } @@ -1185,6 +1187,41 @@ class objClipboard : public Object { }; +// Controller class definition + +#define VER_CONTROLLER (1.000000) + +class objController : public Object { + public: + static constexpr CLASSID CLASS_ID = CLASSID::CONTROLLER; + static constexpr CSTRING CLASS_NAME = "Controller"; + + using create = pf::Create; + + DOUBLE LeftTrigger; // Left trigger value between 0.0 and 1.0. + DOUBLE RightTrigger; // Right trigger value between 0.0 and 1.0. + DOUBLE LeftStickX; // Left analog stick value for X axis, between -1.0 and 1.0. + DOUBLE LeftStickY; // Left analog stick value for Y axis, between -1.0 and 1.0. + DOUBLE RightStickX; // Right analog stick value for X axis, between -1.0 and 1.0. + DOUBLE RightStickY; // Right analog stick value for Y axis, between -1.0 and 1.0. + CON Buttons; // JET button values expressed as bit-fields. + LONG Port; // The port number assigned to the controller. + + // Action stubs + + inline ERR query() noexcept { return Action(AC::Query, this, NULL); } + inline ERR init() noexcept { return InitObject(this); } + + // Customised field setting + + inline ERR setPort(const LONG Value) noexcept { + if (this->initialised()) return ERR::NoFieldAccess; + this->Port = Value; + return ERR::Okay; + } + +}; + // Pointer class definition #define VER_POINTER (1.000000) diff --git a/scripts/gui/window.fluid b/scripts/gui/window.fluid index 828b5d6f8..5b78586ad 100644 --- a/scripts/gui/window.fluid +++ b/scripts/gui/window.fluid @@ -199,7 +199,7 @@ gui.window = function(Options) self.maximise = function(self, Toggle) if not self.maximiseEnabled then - msg("Maximisation for this window is turned off.") + msg('Maximisation for this window is turned off.') return end @@ -301,10 +301,10 @@ gui.window = function(Options) -- Main entry point -- - self._desktop = obj.find("desktop") + self._desktop = obj.find('desktop') self.surface = obj.new('surface', { - name = "winsurface", + name = 'winsurface', parent = self._desktop, width = nz(Options.width, DEFAULT_WIDTH), height = nz(Options.height, DEFAULT_HEIGHT), @@ -334,6 +334,10 @@ gui.window = function(Options) end)() }) + if Options.enableControllers then + self.surface.display.flags = bit.bor(self.surface.display.flags, SCR_GRAB_CONTROLLERS) + end + if Options.x then self.surface.x = Options.x else diff --git a/src/display/CMakeLists.txt b/src/display/CMakeLists.txt index 3a95220c5..1e5692e8a 100644 --- a/src/display/CMakeLists.txt +++ b/src/display/CMakeLists.txt @@ -14,12 +14,14 @@ set (CLASSES "${CMAKE_CURRENT_SOURCE_DIR}/class_bitmap.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/class_display.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/class_clipboard.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/class_controller.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/class_pointer.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/class_surface/class_surface.cpp") set (DISPLAY_DEFS # Full paths are required for add_custom_command() dependencies to work correctly "${CMAKE_CURRENT_SOURCE_DIR}/class_bitmap_def.c" "${CMAKE_CURRENT_SOURCE_DIR}/class_clipboard_def.c" + "${CMAKE_CURRENT_SOURCE_DIR}/class_controller_def.c" "${CMAKE_CURRENT_SOURCE_DIR}/class_display_def.c" "${CMAKE_CURRENT_SOURCE_DIR}/class_pointer_def.c" "${CMAKE_CURRENT_SOURCE_DIR}/class_surface/surface_def.c") @@ -29,6 +31,7 @@ if (BUILD_DEFS) # Customised idl_c() equivalent, this is for defining the output ${DISPLAY_DEFS} "${DOCS}/modules/classes/bitmap.xml" "${DOCS}/modules/classes/clipboard.xml" + "${DOCS}/modules/classes/controller.xml" "${DOCS}/modules/classes/display.xml" "${DOCS}/modules/classes/pointer.xml" "${DOCS}/modules/classes/surface.xml" @@ -77,7 +80,6 @@ if (XDGA_INSTALLED) add_definitions ("-DXDGA_ENABLED") endif () - add_library (${MOD}) set_module_defaults (${MOD}) @@ -89,7 +91,7 @@ target_link_libraries (${MOD} PUBLIC unicode) target_link_libraries (${MOD} PUBLIC linear_rgb) if (WIN32) - target_link_libraries (${MOD} PRIVATE ole32 gdi32 uuid ${MATH_LINK}) + target_link_libraries (${MOD} PRIVATE ole32 gdi32 uuid xinput ${MATH_LINK}) target_sources (${MOD} PRIVATE ${FUNCTIONS} "win32/windows.cpp" "win32/clipboard.c" ${CLASSES}) add_compile_definitions ("WIN_DRAGDROP") elseif (ANDROID) diff --git a/src/display/class_controller.cpp b/src/display/class_controller.cpp new file mode 100644 index 000000000..930162eda --- /dev/null +++ b/src/display/class_controller.cpp @@ -0,0 +1,103 @@ +/********************************************************************************************************************* + +-CLASS- +Controller: Provides support for reading state-based game controllers. + +Use the Controller class to read the state of game controllers that are recognised by the operating system. + +Unlike analog devices that stream input commands (e.g. mice), gamepad controllers maintain a state that can be read +at any time. Typically the controller state is read at least once per frame, which can be achieved in the main +inner loop, or in a separate timer. + +Controller input management is governed by the @Display class. The `GRAB_CONTROLLERS` flag must be defined in the +active Display's Flags field in order to ensure that controller input can be received. Failure to do so may mean +that the Controller object appears to work but does not receive input. + +-END- + +*********************************************************************************************************************/ + +#include "defs.h" + +#ifdef _WIN32 +using namespace display; +#endif + +/********************************************************************************************************************* +-ACTION- +Query: Get the current controller state. +-END- +*********************************************************************************************************************/ + +static ERR CONTROLLER_Query(objController *Self) +{ +#ifdef _WIN32 +// winReadController(Self->Port, (DOUBLE *)&Self->LeftTrigger); + pf::Log log; + log.msg("Control: %.2f %.2f", Self->LeftStickX, Self->LeftStickY); + return ERR::Okay; +#else + return ERR::NoSupport; +#endif +} + +/********************************************************************************************************************* + +-FIELD- +LeftTrigger: Left trigger value between 0.0 and 1.0. + +-FIELD- +RightTrigger: Right trigger value between 0.0 and 1.0. + +-FIELD- +LeftStickX: Left analog stick value for X axis, between -1.0 and 1.0. + +-FIELD- +LeftStickY: Left analog stick value for Y axis, between -1.0 and 1.0. + +-FIELD- +RightStickX: Right analog stick value for X axis, between -1.0 and 1.0. + +-FIELD- +RightStickY: Right analog stick value for Y axis, between -1.0 and 1.0. + +-FIELD- +Buttons: JET button values expressed as bit-fields. + +-FIELD- +Port: The port number assigned to the controller. + +*********************************************************************************************************************/ + +//******************************************************************************************************************** + +#include "class_controller_def.c" + +static const FieldArray clFields[] = { + { "LeftTrigger", FDF_DOUBLE|FDF_R }, + { "RightTrigger", FDF_DOUBLE|FDF_R }, + { "LeftStickX", FDF_DOUBLE|FDF_R }, + { "LeftStickY", FDF_DOUBLE|FDF_R }, + { "RightStickX", FDF_DOUBLE|FDF_R }, + { "RightStickY", FDF_DOUBLE|FDF_R }, + { "Buttons", FDF_LONG|FDF_R }, + { "Port", FDF_LONG|FDF_RI }, + END_FIELD +}; + +//******************************************************************************************************************** + +ERR create_controller_class(void) +{ + clController = objMetaClass::create::global( + fl::BaseClassID(CLASSID::CONTROLLER), + fl::ClassVersion(VER_CONTROLLER), + fl::Name("Controller"), + fl::Category(CCF::IO), + fl::Actions(clControllerActions), + fl::Fields(clFields), + fl::Size(sizeof(objController)), + fl::Path(MOD_PATH)); + + return clController ? ERR::Okay : ERR::AddClass; +} diff --git a/src/display/class_controller_def.c b/src/display/class_controller_def.c new file mode 100644 index 000000000..3f47c2b9f --- /dev/null +++ b/src/display/class_controller_def.c @@ -0,0 +1,25 @@ +// Auto-generated by idl-c.fluid + +static const struct FieldDef clControllerButtons[] = { + { "GamepadS", 0x00000001 }, + { "GamepadE", 0x00000002 }, + { "GamepadW", 0x00000004 }, + { "GamepadN", 0x00000008 }, + { "DpadUp", 0x00000010 }, + { "DpadDown", 0x00000020 }, + { "DpadLeft", 0x00000040 }, + { "DpadRight", 0x00000080 }, + { "Start", 0x00000100 }, + { "Select", 0x00000200 }, + { "LeftBumper1", 0x00000400 }, + { "LeftBumper2", 0x00000800 }, + { "RightBumper1", 0x00001000 }, + { "RightBumper2", 0x00002000 }, + { NULL, 0 } +}; + +static const struct ActionArray clControllerActions[] = { + { AC::Query, CONTROLLER_Query }, + { AC::NIL, NULL } +}; + diff --git a/src/display/class_display.cpp b/src/display/class_display.cpp index 4dd31494a..0f0c2b308 100644 --- a/src/display/class_display.cpp +++ b/src/display/class_display.cpp @@ -1955,31 +1955,33 @@ If the display is hosted in a client window, the BottomMargin indicates the numb and the bottom window edge. -FIELD- -CertificationDate: String describing the date of the graphics driver's certification. +Chipset: String describing the graphics chipset. -The string in this field describes the date on which the graphics card driver was certified. If this information is -not available from the driver, a `NULL` pointer is returned. +This string describes the graphic card's chipset, if known. *********************************************************************************************************************/ -static ERR GET_CertificationDate(extDisplay *Self, STRING *Value) +static ERR GET_Chipset(extDisplay *Self, STRING *Value) { - *Value = Self->CertificationDate; + *Value = Self->Chipset; return ERR::Okay; } /********************************************************************************************************************* -FIELD- -Chipset: String describing the graphics chipset. +ControllerPorts: Indicates the total number of connected controllers. + +Read the ControllerPorts value to get the total number of controllers connected to the system. This value can be used +in conjunction with the @Controller class to read state from multiple controllers. -The string in this field describes the graphic card's chipset. If this information is not retrievable, a `NULL` -pointer is returned. +It is required that the `GRAB_CONTROLLERS` flag is set in the #Flags field in order for a program to access any +connected controllers. *********************************************************************************************************************/ -static ERR GET_Chipset(extDisplay *Self, STRING *Value) +static ERR GET_ControllerPorts(extDisplay *Self, LONG *Value) { - *Value = Self->Chipset; + *Value = Self->ControllerPorts; return ERR::Okay; } @@ -2127,8 +2129,7 @@ static ERR SET_VDensity(extDisplay *Self, LONG Value) -FIELD- Display: String describing the display (e.g. model name of the monitor). -The string in this field describes the display device that is connected to the user's graphics card. If this -information is not detectable, a `NULL` pointer is returned. +This string describes the display device that is connected to the user's graphics card. *********************************************************************************************************************/ @@ -2144,8 +2145,7 @@ static ERR GET_Display(extDisplay *Self, CSTRING *Value) -FIELD- DisplayManufacturer: String describing the display manufacturer. -The string in this field returns the name of the manufacturer that created the user's display device. If this -information is not detectable, a `NULL` pointer is returned. +This string names the manufacturer of the user's display device. *********************************************************************************************************************/ @@ -2164,56 +2164,6 @@ DisplayType: In hosted mode, indicates the bottom margin of the client window. If the display is hosted in a client window, the #BottomMargin indicates the number of pixels between the client area and the bottom window edge. --FIELD- -DriverCopyright: String containing copyright information on the graphics driver software. - -The string in this field returns copyright information related to the graphics driver. If this information is not -available, a `NULL` pointer is returned. - -*********************************************************************************************************************/ - -static ERR GET_DriverCopyright(extDisplay *Self, CSTRING *Value) -{ - if (Self->DriverCopyright[0]) *Value = Self->DriverCopyright; - else *Value = NULL; - return ERR::Okay; -} - -/********************************************************************************************************************* - --FIELD- -DriverVersion: String describing the version of the graphics hardware driver. - -The string in this field describes the graphic driver's version number. If this information is not detectable, a `NULL` -pointer is returned. - -*********************************************************************************************************************/ - -static ERR GET_DriverVersion(extDisplay *Self, CSTRING *Value) -{ - if (Self->DriverVersion[0]) *Value = Self->DriverVersion; - else *Value = NULL; - return ERR::Okay; -} - -/********************************************************************************************************************* - --FIELD- -DriverVendor: String describing the vendor of the graphics driver. - -The string in this field returns the name of the vendor that supplied the graphics card driver. If this information is -not available, a `NULL` pointer is returned. - -*********************************************************************************************************************/ - -static ERR GET_DriverVendor(extDisplay *Self, CSTRING *Value) -{ - *Value = Self->DriverVendor; - return ERR::Okay; -} - -/********************************************************************************************************************* - -FIELD- Flags: Optional flag settings. @@ -2229,7 +2179,7 @@ static ERR SET_Flags(extDisplay *Self, SCR Value) if (Self->initialised()) { // Only flags that are explicitly supported here may be set post-initialisation. - #define ACCEPT_FLAGS (SCR::AUTO_SAVE) + static const SCR ACCEPT_FLAGS = SCR::AUTO_SAVE|SCR::GRAB_CONTROLLERS; auto accept = Value & ACCEPT_FLAGS; Self->Flags = (Self->Flags & (~ACCEPT_FLAGS)) | accept; @@ -2864,6 +2814,7 @@ void alloc_display_buffer(extDisplay *Self) #include "class_display_def.c" static const FieldArray DisplayFields[] = { + // Re-compile the FDL if making changes { "RefreshRate", FDF_DOUBLE|FDF_RW, NULL, SET_RefreshRate }, { "Bitmap", FDF_LOCAL|FDF_R, NULL, NULL, CLASSID::BITMAP }, { "Flags", FDF_LONGFLAGS|FDF_RW, NULL, SET_Flags, &clDisplayFlags }, @@ -2887,16 +2838,13 @@ static const FieldArray DisplayFields[] = { { "TopMargin", FDF_LONG|FDF_R }, { "BottomMargin", FDF_LONG|FDF_R }, // Virtual fields - { "CertificationDate", FDF_VIRTUAL|FDF_STRING|FDF_R, GET_CertificationDate }, { "Chipset", FDF_VIRTUAL|FDF_STRING|FDF_R, GET_Chipset }, + { "ControllerPorts", FDF_VIRTUAL|FDF_LONG|FDF_R, GET_ControllerPorts }, { "Gamma", FDF_VIRTUAL|FDF_DOUBLE|FDF_ARRAY|FDF_RI, GET_Gamma, SET_Gamma }, { "HDensity", FDF_VIRTUAL|FDF_LONG|FDF_RW, GET_HDensity, SET_HDensity }, { "VDensity", FDF_VIRTUAL|FDF_LONG|FDF_RW, GET_VDensity, SET_VDensity }, { "Display", FDF_VIRTUAL|FDF_STRING|FDF_R, GET_Display }, { "DisplayManufacturer", FDF_VIRTUAL|FDF_STRING|FDF_R, GET_DisplayManufacturer }, - { "DriverCopyright", FDF_VIRTUAL|FDF_STRING|FDF_R, GET_DriverCopyright }, - { "DriverVendor", FDF_VIRTUAL|FDF_STRING|FDF_R, GET_DriverVendor }, - { "DriverVersion", FDF_VIRTUAL|FDF_STRING|FDF_R, GET_DriverVersion }, { "InsideWidth", FDF_VIRTUAL|FDF_LONG|FDF_R, GET_InsideWidth }, { "InsideHeight", FDF_VIRTUAL|FDF_LONG|FDF_R, GET_InsideHeight }, { "Manufacturer", FDF_VIRTUAL|FDF_STRING|FDF_R, GET_Manufacturer }, diff --git a/src/display/class_display_def.c b/src/display/class_display_def.c index bad96b452..25445f9c9 100644 --- a/src/display/class_display_def.c +++ b/src/display/class_display_def.c @@ -10,6 +10,7 @@ static const struct FieldDef clDisplayFlags[] = { { "Borderless", 0x00000020 }, { "AlphaBlend", 0x00000040 }, { "Composite", 0x00000040 }, + { "GrabControllers", 0x00000080 }, { "Maxsize", 0x00100000 }, { "Refresh", 0x00200000 }, { "Hosted", 0x02000000 }, diff --git a/src/display/defs.h b/src/display/defs.h index 6a4d59194..7d31caf35 100644 --- a/src/display/defs.h +++ b/src/display/defs.h @@ -9,6 +9,7 @@ #define PRV_POINTER #define PRV_CLIPBOARD #define PRV_SURFACE +#define PRV_CONTROLLER //#define DBG_DRAW_ROUTINES // Use this if you want to debug any external code that is subscribed to surface drawing routines //#define FASTACCESS //#define DBG_LAYERS @@ -385,8 +386,9 @@ class extDisplay : public objDisplay { DOUBLE Gamma[3]; // Red, green, blue gamma radioactivity indicator std::vector Resolutions; FUNCTION ResizeFeedback; - LONG BmpXOffset; // X offset for scrolling - LONG BmpYOffset; // Y offset for scrolling + LONG ControllerPorts; + LONG VDensity; // Cached DPI value, if calculable. + LONG HDensity; #ifdef __xwindows__ union { APTR WindowHandle; @@ -399,26 +401,16 @@ class extDisplay : public objDisplay { APTR WindowHandle; #endif WORD Opacity; - LONG VDensity; // Cached DPI value, if calculable. - LONG HDensity; - char DriverVendor[60]; - char DriverCopyright[80]; char Manufacturer[60]; char Chipset[40]; - char DAC[32]; - char Clock[32]; - char DriverVersion[16]; - char CertificationDate[20]; char Display[32]; char DisplayManufacturer[60]; - #ifdef _WIN32 - APTR OldProcedure; - #endif }; extern void clean_clipboard(void); extern ERR create_bitmap_class(void); extern ERR create_clipboard_class(void); +extern ERR create_controller_class(void); extern ERR create_display_class(void); extern ERR create_pointer_class(void); extern ERR create_surface_class(void); @@ -462,7 +454,7 @@ extern void print_layer_list(STRING Function, SurfaceControl *Ctl, LONG POI) extern bool glSixBitDisplay; extern OBJECTPTR glModule; -extern OBJECTPTR clDisplay, clPointer, clBitmap, clClipboard, clSurface; +extern OBJECTPTR clDisplay, clPointer, clBitmap, clClipboard, clSurface, clController; extern OBJECTID glPointerID; extern DISPLAYINFO glDisplayInfo; extern APTR glDither; diff --git a/src/display/display-driver.cpp b/src/display/display-driver.cpp index 9bb3ccc91..4301036cf 100644 --- a/src/display/display-driver.cpp +++ b/src/display/display-driver.cpp @@ -181,7 +181,7 @@ struct CoreBase *CoreBase; ColourFormat glColourFormat; bool glHeadless = false; OBJECTPTR glModule = NULL; -OBJECTPTR clDisplay = NULL, clPointer = NULL, clBitmap = NULL, clClipboard = NULL, clSurface = NULL; +OBJECTPTR clDisplay = NULL, clPointer = NULL, clBitmap = NULL, clClipboard = NULL, clSurface = NULL, clController = NULL; OBJECTID glPointerID = 0; DISPLAYINFO glDisplayInfo; APTR glDither = NULL; @@ -821,6 +821,7 @@ static ERR MODInit(OBJECTPTR argModule, struct CoreBase *argCoreBase) create_bitmap_class(); create_clipboard_class(); create_surface_class(); + create_controller_class(); return ERR::Okay; } #endif @@ -1059,6 +1060,7 @@ static ERR MODInit(OBJECTPTR argModule, struct CoreBase *argCoreBase) if (create_bitmap_class() != ERR::Okay) return log.warning(ERR::AddClass); if (create_clipboard_class() != ERR::Okay) return log.warning(ERR::AddClass); if (create_surface_class() != ERR::Okay) return log.warning(ERR::AddClass); + if (create_controller_class() != ERR::Okay) return log.warning(ERR::AddClass); // Initialise 64K alpha blending table, for cutting down on multiplications. @@ -1230,6 +1232,7 @@ static ERR MODExpunge(void) if (clBitmap) { FreeResource(clBitmap); clBitmap = NULL; } if (clClipboard) { FreeResource(clClipboard); clClipboard = NULL; } if (clSurface) { FreeResource(clSurface); clSurface = NULL; } + if (clController) { FreeResource(clController); clController = NULL; } #ifdef _GLES_ free_egl(); diff --git a/src/display/display.fdl b/src/display/display.fdl index cdb598b98..3862a47b7 100644 --- a/src/display/display.fdl +++ b/src/display/display.fdl @@ -168,6 +168,7 @@ module({ name="Display", copyright="Paul Manias 2003-2024", version=1.0, status= "BIT_6: Display is limited to 6-bit output per colour gun.", "BORDERLESS: If display is hosted, create it as a popup / borderless window.", "ALPHA_BLEND|COMPOSITE: Enables alpha channel blending (if display is hosted and 32-bit).", + "GRAB_CONTROLLERS: Grab controllers for receiving input when the display has the focus.", { MAXIMISE = "0x80000000: Special win32 flag." }, { CUSTOM_WINDOW = "0x40000000: The display has been created with a custom window reference." }, { FLIPPABLE = "0x20000000: If `SCR::BUFFER` is used, this flag may be set by the display manager if it is possible to flip the buffer." }, @@ -488,6 +489,17 @@ module({ name="Display", copyright="Paul Manias 2003-2024", version=1.0, status= FUNCTION RequestHandler; ]]) + class('Controller', { src='class_controller.cpp', output='class_controller_def.c' }, [[ + double LeftTrigger # Left trigger value between 0.0 and 1.0 + double RightTrigger # Right trigger value between 0.0 and 1.0 + double LeftStickX # Left analog stick value for X axis, between -1.0 and 1.0 + double LeftStickY # Left analog stick value for Y axis, between -1.0 and 1.0 + double RightStickX # Right analog stick value for X axis, between -1.0 and 1.0 + double RightStickY # Right analog stick value for Y axis, between -1.0 and 1.0 + int(CON) Buttons # The state of available controller buttons. + int Port # The port number assigned to the controller. + ]]) + class("Pointer", { version=1.0, src="class_pointer.cpp", output="class_pointer_def.c", references={ 'PTC', 'PF' } }, [[ double Speed # Speed multiplier (%) double Acceleration # Acceleration level - keep between 0.0 and 3.0 diff --git a/src/display/idl.h b/src/display/idl.h index afe6f3665..8fb6b116b 100644 --- a/src/display/idl.h +++ b/src/display/idl.h @@ -1,2 +1,2 @@ #undef MOD_IDL -#define MOD_IDL "s.SurfaceInfo:pData,lParentID,lBitmapID,lDisplayID,lFlags,lX,lY,lWidth,lHeight,lAbsX,lAbsY,wLevel,cBitsPerPixel,cBytesPerPixel,lLineWidth\ns.SurfaceCoords:lX,lY,lWidth,lHeight,lAbsX,lAbsY\ns.xrMode:lWidth,lHeight,lDepth\ns.PixelFormat:ucRedShift,ucGreenShift,ucBlueShift,ucAlphaShift,ucRedMask,ucGreenMask,ucBlueMask,ucAlphaMask,ucRedPos,ucGreenPos,ucBluePos,ucAlphaPos\ns.DisplayInfo:lDisplay,lFlags,wWidth,wHeight,wBitsPerPixel,wBytesPerPixel,xAccelFlags,lAmtColours,ePixelFormat:PixelFormat,fMinRefresh,fMaxRefresh,fRefreshRate,lIndex,lHDensity,lVDensity\ns.CursorInfo:lWidth,lHeight,lFlags,wBitsPerPixel\ns.BitmapSurface:pData,wWidth,wHeight,lLineWidth,ucBitsPerPixel,ucBytesPerPixel,ucOpacity,ucVersion,lColour,eClip:ClipRectangle,wXOffset,wYOffset,eFormat:ColourFormat\nc.ACF:SOFTWARE_BLIT=0x2,VIDEO_BLIT=0x1\nc.BAF:BLEND=0x2,COPY=0x4,DITHER=0x1,FILL=0x1,LINEAR=0x8\nc.BDF:DITHER=0x2,REDRAW=0x1\nc.BMF:ACCELERATED_2D=0x200,ACCELERATED_3D=0x400,ALPHA_CHANNEL=0x800,BLANK_PALETTE=0x1,CLEAR=0x80,COMPRESSED=0x2,FIXED_DEPTH=0x4000,INVERSE_ALPHA=0x20,MASK=0x10,NEVER_SHRINK=0x1000,NO_BLEND=0x8000,NO_DATA=0x4,PREMUL=0x10000,QUERIED=0x40,TRANSPARENT=0x8,USER=0x100,X11_DGA=0x2000\nc.BMP:CHUNKY=0x3,PLANAR=0x2\nc.CEF:DELETE=0x1,EXTEND=0x2\nc.CLIPTYPE:AUDIO=0x2,DATA=0x1,FILE=0x8,IMAGE=0x4,OBJECT=0x10,TEXT=0x20\nc.CPF:DRAG_DROP=0x1,HISTORY_BUFFER=0x4,HOST=0x2\nc.CRF:BUFFER=0x10,LMB=0x1,MMB=0x2,NO_BUTTONS=0x20,RESTRICT=0x8,RMB=0x4\nc.CS:CIE_LAB=0x3,CIE_LCH=0x4,LINEAR_RGB=0x2,SRGB=0x1\nc.CSRF:ALPHA=0x2,CLIP=0x10,DEFAULT_FORMAT=0x8,OFFSET=0x20,TRANSLUCENT=0x4,TRANSPARENT=0x1\nc.CT:AUDIO=0x1,DATA=0x0,END=0x6,FILE=0x3,IMAGE=0x2,OBJECT=0x4,TEXT=0x5\nc.DPMS:DEFAULT=0x0,OFF=0x1,STANDBY=0x3,SUSPEND=0x2\nc.DRAG:ANCHOR=0x1,NONE=0x0,NORMAL=0x2\nc.DSF:NO_DRAW=0x1,NO_EXPOSE=0x2\nc.DT:GLES=0x4,NATIVE=0x1,WINGDI=0x3,X11=0x2\nc.EXF:ABSOLUTE=0x8,ABSOLUTE_COORDS=0x8,CHILDREN=0x1,CURSOR_SPLIT=0x10,REDRAW_VOLATILE=0x2,REDRAW_VOLATILE_OVERLAP=0x4\nc.FLIP:HORIZONTAL=0x1,VERTICAL=0x2\nc.GMF:SAVE=0x1\nc.HOST:STICK_TO_FRONT=0x3,TASKBAR=0x2,TRANSLUCENCE=0x4,TRANSPARENT=0x5,TRAY_ICON=0x1\nc.IRF:FORCE_DRAW=0x10,IGNORE_CHILDREN=0x2,IGNORE_NV_CHILDREN=0x1,REDRAWS_CHILDREN=0x20,RELATIVE=0x8,SINGLE_BITMAP=0x4\nc.LVF:EXPOSE_CHANGES=0x1\nc.MON:AUTO_DETECT=0x1,BIT_6=0x2\nc.PF:ANCHOR=0x4,UNUSED=0x1,VISIBLE=0x2\nc.RNF:AFTER_COPY=0x8000,ASPECT_RATIO=0x1000000,AUTO_QUIT=0x100,COMPOSITE=0x200000,CURSOR=0x4000,DISABLED=0x80,FIXED_BUFFER=0x10000,FIXED_DEPTH=0x80000,FULL_SCREEN=0x400000,GRAB_FOCUS=0x20,HAS_FOCUS=0x40,HOST=0x200,IGNORE_FOCUS=0x800000,INIT_ONLY=0xcb0e81,NO_FOCUS=0x40000,NO_HORIZONTAL=0x1000,NO_PRECOMPOSITE=0x200000,NO_VERTICAL=0x2000,PERVASIVE_COPY=0x20000,POINTER=0x4000,POST_COMPOSITE=0x200000,PRECOPY=0x400,READ_ONLY=0xc040,STICKY=0x10,STICK_TO_BACK=0x2,STICK_TO_FRONT=0x4,TOTAL_REDRAW=0x100000,TRANSPARENT=0x1,VIDEO=0x800,VISIBLE=0x8,VOLATILE=0xc400,WRITE_ONLY=0x800\nc.RT:ROOT=0x1\nc.SCR:ALPHA_BLEND=0x40,AUTO_SAVE=0x2,BIT_6=0x10,BORDERLESS=0x20,BUFFER=0x4,COMPOSITE=0x40,CUSTOM_WINDOW=0x40000000,DPMS_ENABLED=0x8000000,FLIPPABLE=0x20000000,GTF_ENABLED=0x10000000,HOSTED=0x2000000,MAXIMISE=0x80000000,MAXSIZE=0x100000,NO_ACCELERATION=0x8,POWERSAVE=0x4000000,READ_ONLY=0xfe300019,REFRESH=0x200000,VISIBLE=0x1\nc.SWIN:HOST=0x0,ICON_TRAY=0x2,NONE=0x3,TASKBAR=0x1\nc.WH:CLOSE=0x1\n" +#define MOD_IDL "s.SurfaceInfo:pData,lParentID,lBitmapID,lDisplayID,lFlags,lX,lY,lWidth,lHeight,lAbsX,lAbsY,wLevel,cBitsPerPixel,cBytesPerPixel,lLineWidth\ns.SurfaceCoords:lX,lY,lWidth,lHeight,lAbsX,lAbsY\ns.xrMode:lWidth,lHeight,lDepth\ns.PixelFormat:ucRedShift,ucGreenShift,ucBlueShift,ucAlphaShift,ucRedMask,ucGreenMask,ucBlueMask,ucAlphaMask,ucRedPos,ucGreenPos,ucBluePos,ucAlphaPos\ns.DisplayInfo:lDisplay,lFlags,wWidth,wHeight,wBitsPerPixel,wBytesPerPixel,xAccelFlags,lAmtColours,ePixelFormat:PixelFormat,fMinRefresh,fMaxRefresh,fRefreshRate,lIndex,lHDensity,lVDensity\ns.CursorInfo:lWidth,lHeight,lFlags,wBitsPerPixel\ns.BitmapSurface:pData,wWidth,wHeight,lLineWidth,ucBitsPerPixel,ucBytesPerPixel,ucOpacity,ucVersion,lColour,eClip:ClipRectangle,wXOffset,wYOffset,eFormat:ColourFormat\nc.ACF:SOFTWARE_BLIT=0x2,VIDEO_BLIT=0x1\nc.BAF:BLEND=0x2,COPY=0x4,DITHER=0x1,FILL=0x1,LINEAR=0x8\nc.BDF:DITHER=0x2,REDRAW=0x1\nc.BMF:ACCELERATED_2D=0x200,ACCELERATED_3D=0x400,ALPHA_CHANNEL=0x800,BLANK_PALETTE=0x1,CLEAR=0x80,COMPRESSED=0x2,FIXED_DEPTH=0x4000,INVERSE_ALPHA=0x20,MASK=0x10,NEVER_SHRINK=0x1000,NO_BLEND=0x8000,NO_DATA=0x4,PREMUL=0x10000,QUERIED=0x40,TRANSPARENT=0x8,USER=0x100,X11_DGA=0x2000\nc.BMP:CHUNKY=0x3,PLANAR=0x2\nc.CEF:DELETE=0x1,EXTEND=0x2\nc.CLIPTYPE:AUDIO=0x2,DATA=0x1,FILE=0x8,IMAGE=0x4,OBJECT=0x10,TEXT=0x20\nc.CPF:DRAG_DROP=0x1,HISTORY_BUFFER=0x4,HOST=0x2\nc.CRF:BUFFER=0x10,LMB=0x1,MMB=0x2,NO_BUTTONS=0x20,RESTRICT=0x8,RMB=0x4\nc.CS:CIE_LAB=0x3,CIE_LCH=0x4,LINEAR_RGB=0x2,SRGB=0x1\nc.CSRF:ALPHA=0x2,CLIP=0x10,DEFAULT_FORMAT=0x8,OFFSET=0x20,TRANSLUCENT=0x4,TRANSPARENT=0x1\nc.CT:AUDIO=0x1,DATA=0x0,END=0x6,FILE=0x3,IMAGE=0x2,OBJECT=0x4,TEXT=0x5\nc.DPMS:DEFAULT=0x0,OFF=0x1,STANDBY=0x3,SUSPEND=0x2\nc.DRAG:ANCHOR=0x1,NONE=0x0,NORMAL=0x2\nc.DSF:NO_DRAW=0x1,NO_EXPOSE=0x2\nc.DT:GLES=0x4,NATIVE=0x1,WINGDI=0x3,X11=0x2\nc.EXF:ABSOLUTE=0x8,ABSOLUTE_COORDS=0x8,CHILDREN=0x1,CURSOR_SPLIT=0x10,REDRAW_VOLATILE=0x2,REDRAW_VOLATILE_OVERLAP=0x4\nc.FLIP:HORIZONTAL=0x1,VERTICAL=0x2\nc.GMF:SAVE=0x1\nc.HOST:STICK_TO_FRONT=0x3,TASKBAR=0x2,TRANSLUCENCE=0x4,TRANSPARENT=0x5,TRAY_ICON=0x1\nc.IRF:FORCE_DRAW=0x10,IGNORE_CHILDREN=0x2,IGNORE_NV_CHILDREN=0x1,REDRAWS_CHILDREN=0x20,RELATIVE=0x8,SINGLE_BITMAP=0x4\nc.LVF:EXPOSE_CHANGES=0x1\nc.MON:AUTO_DETECT=0x1,BIT_6=0x2\nc.PF:ANCHOR=0x4,UNUSED=0x1,VISIBLE=0x2\nc.RNF:AFTER_COPY=0x8000,ASPECT_RATIO=0x1000000,AUTO_QUIT=0x100,COMPOSITE=0x200000,CURSOR=0x4000,DISABLED=0x80,FIXED_BUFFER=0x10000,FIXED_DEPTH=0x80000,FULL_SCREEN=0x400000,GRAB_FOCUS=0x20,HAS_FOCUS=0x40,HOST=0x200,IGNORE_FOCUS=0x800000,INIT_ONLY=0xcb0e81,NO_FOCUS=0x40000,NO_HORIZONTAL=0x1000,NO_PRECOMPOSITE=0x200000,NO_VERTICAL=0x2000,PERVASIVE_COPY=0x20000,POINTER=0x4000,POST_COMPOSITE=0x200000,PRECOPY=0x400,READ_ONLY=0xc040,STICKY=0x10,STICK_TO_BACK=0x2,STICK_TO_FRONT=0x4,TOTAL_REDRAW=0x100000,TRANSPARENT=0x1,VIDEO=0x800,VISIBLE=0x8,VOLATILE=0xc400,WRITE_ONLY=0x800\nc.RT:ROOT=0x1\nc.SCR:ALPHA_BLEND=0x40,AUTO_SAVE=0x2,BIT_6=0x10,BORDERLESS=0x20,BUFFER=0x4,COMPOSITE=0x40,CUSTOM_WINDOW=0x40000000,DPMS_ENABLED=0x8000000,FLIPPABLE=0x20000000,GRAB_CONTROLLERS=0x80,GTF_ENABLED=0x10000000,HOSTED=0x2000000,MAXIMISE=0x80000000,MAXSIZE=0x100000,NO_ACCELERATION=0x8,POWERSAVE=0x4000000,READ_ONLY=0xfe300019,REFRESH=0x200000,VISIBLE=0x1\nc.SWIN:HOST=0x0,ICON_TRAY=0x2,NONE=0x3,TASKBAR=0x1\nc.WH:CLOSE=0x1\n" diff --git a/src/display/win32/handlers.cpp b/src/display/win32/handlers.cpp index be915c1fb..6b33d3986 100644 --- a/src/display/win32/handlers.cpp +++ b/src/display/win32/handlers.cpp @@ -146,6 +146,20 @@ void MsgButtonPress(LONG button, LONG State) //******************************************************************************************************************** +void MsgTotalControllerPorts(OBJECTID SurfaceID, int Ports) +{ + if (ScopedObjectLock surface(SurfaceID, 3000); surface.granted()) { + if (ScopedObjectLock display(surface->DisplayID, 3000); display.granted()) { + if ((display->Flags & SCR::GRAB_CONTROLLERS) != SCR::NIL) { + display->ControllerPorts = Ports + 1; + } + else display->ControllerPorts = 0; + } + } +} + +//******************************************************************************************************************** + void MsgResizedWindow(OBJECTID SurfaceID, LONG WinX, LONG WinY, LONG WinWidth, LONG WinHeight, LONG ClientX, LONG ClientY, LONG ClientWidth, LONG ClientHeight) { @@ -159,6 +173,7 @@ void MsgResizedWindow(OBJECTID SurfaceID, LONG WinX, LONG WinY, LONG WinWidth, L if (ScopedObjectLock surface(SurfaceID, 3000); surface.granted()) { display_id = surface->DisplayID; if (ScopedObjectLock display(display_id, 3000); display.granted()) { + if (!display->ResizeFeedback.defined()) return; feedback = display->ResizeFeedback; display->X = WinX; display->Y = WinY; diff --git a/src/display/win32/windows.cpp b/src/display/win32/windows.cpp index 0b1756813..e480a82ab 100644 --- a/src/display/win32/windows.cpp +++ b/src/display/win32/windows.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -797,17 +798,35 @@ static LRESULT CALLBACK WindowProcedure(HWND window, UINT msgcode, WPARAM wParam return MA_NOACTIVATE; - case WM_ACTIVATEAPP: + case WM_ACTIVATEAPP: { MSG("WM_ACTIVATEAPP: Focus: %d\n", (int)wParam); + auto surface = winLookupSurfaceID(window); if (wParam) { // We have the focus - MsgFocusState(winLookupSurfaceID(window), TRUE); + MsgFocusState(surface, TRUE); + + #if (_WIN32_WINNT < _WIN32_WINNT_WIN10) + // Deprecated from Windows 10 onwards + //XInputEnable(FALSE); + #endif + + int last_port = -1; + for (DWORD i = 0; i < XUSER_MAX_COUNT; i++) { + XINPUT_CAPABILITIES cap; + if (XInputGetCapabilities(i, XINPUT_FLAG_GAMEPAD, &cap) == ERROR_SUCCESS) { + last_port = i; + } + else break; + } + + MsgTotalControllerPorts(surface, last_port); } else { // We have lost the focus - MsgFocusState(winLookupSurfaceID(window), FALSE); + MsgFocusState(surface, FALSE); } return 0; + } case WM_MOVE: { int wx, wy, wwidth, wheight, cx, cy, cwidth, cheight; @@ -1041,6 +1060,17 @@ void winDisableBatching(void) //******************************************************************************************************************** +ERR winReadController(int Port, double *Values) +{ + XINPUT_STATE state; + if (XInputGetState(Port, &state) == ERROR_SUCCESS) { + return ERR::Okay; + } + else return ERR::Failed; +} + +//******************************************************************************************************************** + int winGetDesktopSize(int *width, int *height) { *width = 800; diff --git a/src/display/win32/windows.h b/src/display/win32/windows.h index 25c22eea8..6ff926f7d 100644 --- a/src/display/win32/windows.h +++ b/src/display/win32/windows.h @@ -82,6 +82,7 @@ extern void MsgMovement(int, double, double, int, int, bool); extern void MsgWheelMovement(int, float); extern void MsgButtonPress(int, int); extern void MsgFocusState(int SurfaceID, int State); +extern void MsgTotalControllerPorts(int, int); extern void MsgResizedWindow(int, int, int, int, int, int, int, int, int); extern void MsgSetFocus(int SurfaceID); extern void MsgSwitchWindowType(HWND, int); @@ -119,6 +120,7 @@ extern void winMinimiseWindow(HWND); extern int winMoveWindow(HWND, int, int); extern void winMoveToBack(HWND); extern void winMoveToFront(HWND); +extern ERR winReadController(int Port, double *Values); extern int winReadKey(char *, char *, unsigned char *, int); extern int winResizeWindow(HWND, int, int, int, int); extern void winSetCursorPos(int X, int Y); diff --git a/src/svg/gradients.cpp b/src/svg/gradients.cpp index 2d7cdf98d..19f350419 100644 --- a/src/svg/gradients.cpp +++ b/src/svg/gradients.cpp @@ -37,7 +37,7 @@ static const std::vector process_gradient_stops(extSVG *Self, cons stop.RGB.Blue = 0; stop.RGB.Alpha = 0; - for (LONG a=1; a < LONG(scan.Attribs.size()); a++) { + for (LONG a=1; a < std::ssize(scan.Attribs); a++) { auto &name = scan.Attribs[a].Name; auto &value = scan.Attribs[a].Value; if (value.empty()) continue; From a0821e26db064c82f3669181b3a05e7e7ccea237 Mon Sep 17 00:00:00 2001 From: Paul Manias Date: Thu, 5 Dec 2024 23:42:46 +0000 Subject: [PATCH 4/9] Completed initial phase of Controller support --- docs/xml/modules/classes/controller.xml | 13 ++++++- docs/xml/modules/classes/display.xml | 11 ------ docs/xml/modules/core.xml | 2 + include/parasol/modules/core.h | 2 + include/parasol/modules/display.h | 14 +++---- src/core/idl.h | 2 +- src/display/class_controller.cpp | 31 +++++++++++++--- src/display/class_controller_def.c | 2 + src/display/class_display.cpp | 19 ---------- src/display/defs.h | 1 + src/display/display-driver.cpp | 1 + src/display/win32/handlers.cpp | 14 ------- src/display/win32/windows.cpp | 49 ++++++++++++++++++++++--- src/display/win32/windows.h | 26 ++++++++++++- tools/idl/common.fdl | 5 ++- 15 files changed, 126 insertions(+), 66 deletions(-) diff --git a/docs/xml/modules/classes/controller.xml b/docs/xml/modules/classes/controller.xml index e4db4b9b9..4a80fe82b 100644 --- a/docs/xml/modules/classes/controller.xml +++ b/docs/xml/modules/classes/controller.xml @@ -15,7 +15,7 @@ Paul Manias 2003-2024

Use the Controller class to read the state of game controllers that are recognised by the operating system.

-

Unlike analog devices that stream input commands (e.g. mice), gamepad controllers maintain a state that can be read at any time. Typically the controller state is read at least once per frame, which can be achieved in the main inner loop, or in a separate timer.

+

Unlike analog devices that stream input commands (e.g. mice), gamepad controllers maintain a state that can be read at any time. The controller state is normally read at least once per frame, which can be achieved in the main inner loop, or in a separate timer.

Controller input management is governed by the Display class. The GRAB_CONTROLLERS flag must be defined in the active Display's Flags field in order to ensure that controller input can be received. Failure to do so may mean that the Controller object appears to work but does not receive input.

class_controller.cpp @@ -68,6 +68,10 @@ The port number assigned to the controller. Read/Init INT + +

Set the port number to choose the controller that will be queried for state changes. The default of zero is assigned to the primary controller.

+

The port number can be changed at any time, so multiple controllers can be queried through one interface at the cost of overwriting the previous state. Check TotalPorts if your program supports more than one controller.

+
@@ -91,6 +95,13 @@ DOUBLE + + TotalPorts + Reports the total number of controllers connected to the system. + Get + INT + + diff --git a/docs/xml/modules/classes/display.xml b/docs/xml/modules/classes/display.xml index f4b2ecab1..7cd4f5bef 100644 --- a/docs/xml/modules/classes/display.xml +++ b/docs/xml/modules/classes/display.xml @@ -406,17 +406,6 @@ - - ControllerPorts - Indicates the total number of connected controllers. - Get - INT - -

Read the ControllerPorts value to get the total number of controllers connected to the system. This value can be used in conjunction with the Controller class to read state from multiple controllers.

-

It is required that the GRAB_CONTROLLERS flag is set in the Flags field in order for a program to access any connected controllers.

-
-
- Display String describing the display (e.g. model name of the monitor). diff --git a/docs/xml/modules/core.xml b/docs/xml/modules/core.xml index 7cb7d740b..4ccd1199c 100644 --- a/docs/xml/modules/core.xml +++ b/docs/xml/modules/core.xml @@ -2116,8 +2116,10 @@ SetField(Object, FID_Statement|TSTR, "string"); West button (X) Gamepad left-hand bumper 1 (top, primary). Gamepad left-hand bumper 2 (lower). + Left thumb stick depressed. Gamepad right-hand bumper 1 (top, primary). Gamepad right-hand bumper 2 (lower). + Right thumb stick depressed. Gamepad select or back button. Gamepad start button.
diff --git a/include/parasol/modules/core.h b/include/parasol/modules/core.h index 8eb3905a6..585ff6dc1 100644 --- a/include/parasol/modules/core.h +++ b/include/parasol/modules/core.h @@ -365,6 +365,8 @@ enum class CON : ULONG { LEFT_BUMPER_2 = 0x00000800, RIGHT_BUMPER_1 = 0x00001000, RIGHT_BUMPER_2 = 0x00002000, + LEFT_THUMB = 0x00004000, + RIGHT_THUMB = 0x00008000, }; DEFINE_ENUM_FLAG_OPERATORS(CON) diff --git a/include/parasol/modules/display.h b/include/parasol/modules/display.h index 1ad7dc0a5..5a4df4bce 100644 --- a/include/parasol/modules/display.h +++ b/include/parasol/modules/display.h @@ -1011,7 +1011,7 @@ class objDisplay : public Object { inline ERR setRefreshRate(const DOUBLE Value) noexcept { auto target = this; - auto field = &this->Class->Dictionary[40]; + auto field = &this->Class->Dictionary[39]; return field->WriteValue(target, field, FD_DOUBLE, &Value, 1); } @@ -1062,7 +1062,7 @@ class objDisplay : public Object { inline ERR setPopOver(OBJECTID Value) noexcept { auto target = this; - auto field = &this->Class->Dictionary[26]; + auto field = &this->Class->Dictionary[25]; return field->WriteValue(target, field, FD_LONG, &Value, 1); } @@ -1074,31 +1074,31 @@ class objDisplay : public Object { inline ERR setHDensity(const LONG Value) noexcept { auto target = this; - auto field = &this->Class->Dictionary[17]; + auto field = &this->Class->Dictionary[16]; return field->WriteValue(target, field, FD_LONG, &Value, 1); } inline ERR setVDensity(const LONG Value) noexcept { auto target = this; - auto field = &this->Class->Dictionary[15]; + auto field = &this->Class->Dictionary[14]; return field->WriteValue(target, field, FD_LONG, &Value, 1); } inline ERR setOpacity(const DOUBLE Value) noexcept { auto target = this; - auto field = &this->Class->Dictionary[16]; + auto field = &this->Class->Dictionary[15]; return field->WriteValue(target, field, FD_DOUBLE, &Value, 1); } inline ERR setResizeFeedback(const FUNCTION Value) noexcept { auto target = this; - auto field = &this->Class->Dictionary[30]; + auto field = &this->Class->Dictionary[29]; return field->WriteValue(target, field, FD_FUNCTION, &Value, 1); } inline ERR setWindowHandle(APTR Value) noexcept { auto target = this; - auto field = &this->Class->Dictionary[12]; + auto field = &this->Class->Dictionary[11]; return field->WriteValue(target, field, 0x08000308, Value, 1); } diff --git a/src/core/idl.h b/src/core/idl.h index 4ed3ef056..75e136836 100644 --- a/src/core/idl.h +++ b/src/core/idl.h @@ -1 +1 @@ -char glIDL[] = { 115,46,73,110,112,117,116,69,118,101,110,116,58,112,78,101,120,116,58,73,110,112,117,116,69,118,101,110,116,44,100,86,97,108,117,101,44,120,84,105,109,101,115,116,97,109,112,44,108,82,101,99,105,112,105,101,110,116,73,68,44,108,79,118,101,114,73,68,44,100,65,98,115,88,44,100,65,98,115,89,44,100,88,44,100,89,44,108,68,101,118,105,99,101,73,68,44,108,84,121,112,101,44,108,70,108,97,103,115,44,108,77,97,115,107,10,115,46,100,99,82,101,113,117,101,115,116,58,108,73,116,101,109,44,99,80,114,101,102,101,114,101,110,99,101,91,52,93,10,115,46,100,99,65,117,100,105,111,58,108,83,105,122,101,44,108,70,111,114,109,97,116,10,115,46,100,99,75,101,121,69,110,116,114,121,58,108,70,108,97,103,115,44,108,86,97,108,117,101,44,120,84,105,109,101,115,116,97,109,112,44,108,85,110,105,99,111,100,101,10,115,46,100,99,68,101,118,105,99,101,73,110,112,117,116,58,100,86,97,108,117,101,115,91,50,93,44,120,84,105,109,101,115,116,97,109,112,44,108,68,101,118,105,99,101,73,68,44,108,70,108,97,103,115,44,108,84,121,112,101,10,115,46,68,97,116,101,84,105,109,101,58,119,89,101,97,114,44,99,77,111,110,116,104,44,99,68,97,121,44,99,72,111,117,114,44,99,77,105,110,117,116,101,44,99,83,101,99,111,110,100,44,99,84,105,109,101,90,111,110,101,10,115,46,72,83,86,58,100,72,117,101,44,100,83,97,116,117,114,97,116,105,111,110,44,100,86,97,108,117,101,44,100,65,108,112,104,97,10,115,46,70,82,71,66,58,102,82,101,100,44,102,71,114,101,101,110,44,102,66,108,117,101,44,102,65,108,112,104,97,10,115,46,82,71,66,56,58,117,99,82,101,100,44,117,99,71,114,101,101,110,44,117,99,66,108,117,101,44,117,99,65,108,112,104,97,10,115,46,82,71,66,49,54,58,117,119,82,101,100,44,117,119,71,114,101,101,110,44,117,119,66,108,117,101,44,117,119,65,108,112,104,97,10,115,46,82,71,66,51,50,58,117,108,82,101,100,44,117,108,71,114,101,101,110,44,117,108,66,108,117,101,44,117,108,65,108,112,104,97,10,115,46,82,71,66,80,97,108,101,116,116,101,58,108,65,109,116,67,111,108,111,117,114,115,44,101,67,111,108,58,82,71,66,56,91,50,53,54,93,10,115,46,67,111,108,111,117,114,70,111,114,109,97,116,58,117,99,82,101,100,83,104,105,102,116,44,117,99,71,114,101,101,110,83,104,105,102,116,44,117,99,66,108,117,101,83,104,105,102,116,44,117,99,65,108,112,104,97,83,104,105,102,116,44,117,99,82,101,100,77,97,115,107,44,117,99,71,114,101,101,110,77,97,115,107,44,117,99,66,108,117,101,77,97,115,107,44,117,99,65,108,112,104,97,77,97,115,107,44,117,99,82,101,100,80,111,115,44,117,99,71,114,101,101,110,80,111,115,44,117,99,66,108,117,101,80,111,115,44,117,99,65,108,112,104,97,80,111,115,44,117,99,66,105,116,115,80,101,114,80,105,120,101,108,10,115,46,67,108,105,112,82,101,99,116,97,110,103,108,101,58,108,76,101,102,116,44,108,84,111,112,44,108,82,105,103,104,116,44,108,66,111,116,116,111,109,10,115,46,69,100,103,101,115,58,108,76,101,102,116,44,108,84,111,112,44,108,82,105,103,104,116,44,108,66,111,116,116,111,109,10,115,46,79,98,106,101,99,116,83,105,103,110,97,108,58,111,79,98,106,101,99,116,10,115,46,70,117,110,99,116,105,111,110,70,105,101,108,100,58,115,78,97,109,101,44,117,108,84,121,112,101,10,115,46,70,117,110,99,116,105,111,110,58,112,65,100,100,114,101,115,115,44,115,78,97,109,101,44,112,65,114,103,115,58,70,117,110,99,116,105,111,110,70,105,101,108,100,10,115,46,70,105,101,108,100,65,114,114,97,121,58,115,78,97,109,101,44,112,71,101,116,70,105,101,108,100,44,112,83,101,116,70,105,101,108,100,44,109,65,114,103,44,117,108,70,108,97,103,115,10,115,46,70,105,101,108,100,68,101,102,58,115,78,97,109,101,44,108,86,97,108,117,101,10,115,46,83,121,115,116,101,109,83,116,97,116,101,58,115,80,108,97,116,102,111,114,109,44,108,67,111,110,115,111,108,101,70,68,44,108,83,116,97,103,101,10,115,46,85,110,105,116,58,100,86,97,108,117,101,44,117,108,84,121,112,101,10,115,46,65,99,116,105,111,110,65,114,114,97,121,58,112,82,111,117,116,105,110,101,44,108,65,99,116,105,111,110,67,111,100,101,10,115,46,65,99,116,105,111,110,84,97,98,108,101,58,117,108,72,97,115,104,44,108,83,105,122,101,44,115,78,97,109,101,44,112,65,114,103,115,58,70,117,110,99,116,105,111,110,70,105,101,108,100,10,115,46,67,104,105,108,100,69,110,116,114,121,58,108,79,98,106,101,99,116,73,68,44,117,108,67,108,97,115,115,73,68,10,115,46,77,101,115,115,97,103,101,58,120,84,105,109,101,44,108,85,73,68,44,108,84,121,112,101,44,108,83,105,122,101,10,115,46,77,101,109,73,110,102,111,58,112,83,116,97,114,116,44,108,79,98,106,101,99,116,73,68,44,117,108,83,105,122,101,44,108,70,108,97,103,115,44,108,77,101,109,111,114,121,73,68,44,119,65,99,99,101,115,115,67,111,117,110,116,10,115,46,67,111,109,112,114,101,115,115,105,111,110,70,101,101,100,98,97,99,107,58,108,70,101,101,100,98,97,99,107,73,68,44,108,73,110,100,101,120,44,115,80,97,116,104,44,115,68,101,115,116,44,120,80,114,111,103,114,101,115,115,44,120,79,114,105,103,105,110,97,108,83,105,122,101,44,120,67,111,109,112,114,101,115,115,101,100,83,105,122,101,44,119,89,101,97,114,44,119,77,111,110,116,104,44,119,68,97,121,44,119,72,111,117,114,44,119,77,105,110,117,116,101,44,119,83,101,99,111,110,100,10,115,46,67,111,109,112,114,101,115,115,101,100,73,116,101,109,58,120,79,114,105,103,105,110,97,108,83,105,122,101,44,120,67,111,109,112,114,101,115,115,101,100,83,105,122,101,44,112,78,101,120,116,58,67,111,109,112,114,101,115,115,101,100,73,116,101,109,44,115,80,97,116,104,44,108,80,101,114,109,105,115,115,105,111,110,115,44,108,85,115,101,114,73,68,44,108,71,114,111,117,112,73,68,44,108,79,116,104,101,114,115,73,68,44,108,70,108,97,103,115,44,101,67,114,101,97,116,101,100,58,68,97,116,101,84,105,109,101,44,101,77,111,100,105,102,105,101,100,58,68,97,116,101,84,105,109,101,10,115,46,70,105,108,101,73,110,102,111,58,120,83,105,122,101,44,120,84,105,109,101,83,116,97,109,112,44,112,78,101,120,116,58,70,105,108,101,73,110,102,111,44,115,78,97,109,101,44,108,70,108,97,103,115,44,108,80,101,114,109,105,115,115,105,111,110,115,44,108,85,115,101,114,73,68,44,108,71,114,111,117,112,73,68,44,101,67,114,101,97,116,101,100,58,68,97,116,101,84,105,109,101,44,101,77,111,100,105,102,105,101,100,58,68,97,116,101,84,105,109,101,10,115,46,68,105,114,73,110,102,111,58,112,73,110,102,111,58,70,105,108,101,73,110,102,111,10,115,46,70,105,108,101,70,101,101,100,98,97,99,107,58,120,83,105,122,101,44,120,80,111,115,105,116,105,111,110,44,115,80,97,116,104,44,115,68,101,115,116,44,108,70,101,101,100,98,97,99,107,73,68,44,99,82,101,115,101,114,118,101,100,91,51,50,93,10,115,46,70,105,101,108,100,58,109,65,114,103,44,112,71,101,116,86,97,108,117,101,44,112,83,101,116,86,97,108,117,101,44,112,87,114,105,116,101,86,97,108,117,101,44,115,78,97,109,101,44,117,108,70,105,101,108,100,73,68,44,117,119,79,102,102,115,101,116,44,117,119,73,110,100,101,120,44,117,108,70,108,97,103,115,10,99,46,65,67,58,65,99,116,105,118,97,116,101,61,48,120,50,44,67,108,101,97,114,61,48,120,52,44,67,108,105,112,98,111,97,114,100,61,48,120,50,100,44,67,111,112,121,68,97,116,97,61,48,120,55,44,68,97,116,97,70,101,101,100,61,48,120,56,44,68,101,97,99,116,105,118,97,116,101,61,48,120,57,44,68,105,115,97,98,108,101,61,48,120,50,102,44,68,114,97,103,68,114,111,112,61,48,120,49,48,44,68,114,97,119,61,48,120,97,44,69,78,68,61,48,120,51,49,44,69,110,97,98,108,101,61,48,120,54,44,70,108,117,115,104,61,48,120,98,44,70,111,99,117,115,61,48,120,99,44,70,114,101,101,61,48,120,100,44,70,114,101,101,87,97,114,110,105,110,103,61,48,120,53,44,71,101,116,75,101,121,61,48,120,102,44,72,105,100,101,61,48,120,49,49,44,73,110,105,116,61,48,120,49,50,44,76,111,99,107,61,48,120,49,51,44,76,111,115,116,70,111,99,117,115,61,48,120,49,52,44,77,111,118,101,61,48,120,49,53,44,77,111,118,101,84,111,66,97,99,107,61,48,120,49,54,44,77,111,118,101,84,111,70,114,111,110,116,61,48,120,49,55,44,77,111,118,101,84,111,80,111,105,110,116,61,48,120,50,51,44,78,101,119,67,104,105,108,100,61,48,120,49,56,44,78,101,119,79,98,106,101,99,116,61,48,120,49,97,44,78,101,119,79,119,110,101,114,61,48,120,49,57,44,78,101,119,80,108,97,99,101,109,101,110,116,61,48,120,51,48,44,78,101,120,116,61,48,120,50,57,44,80,114,101,118,61,48,120,50,97,44,81,117,101,114,121,61,48,120,49,99,44,82,101,97,100,61,48,120,49,100,44,82,101,100,105,109,101,110,115,105,111,110,61,48,120,51,44,82,101,100,111,61,48,120,49,98,44,82,101,102,114,101,115,104,61,48,120,50,101,44,82,101,110,97,109,101,61,48,120,49,101,44,82,101,115,101,116,61,48,120,49,102,44,82,101,115,105,122,101,61,48,120,50,48,44,83,97,118,101,73,109,97,103,101,61,48,120,50,49,44,83,97,118,101,83,101,116,116,105,110,103,115,61,48,120,101,44,83,97,118,101,84,111,79,98,106,101,99,116,61,48,120,50,50,44,83,101,101,107,61,48,120,50,52,44,83,101,116,70,105,101,108,100,61,48,120,50,99,44,83,101,116,75,101,121,61,48,120,50,53,44,83,104,111,119,61,48,120,50,54,44,83,105,103,110,97,108,61,48,120,49,44,85,110,100,111,61,48,120,50,55,44,85,110,108,111,99,107,61,48,120,50,56,44,87,114,105,116,101,61,48,120,50,98,10,99,46,65,76,73,71,78,58,66,79,84,84,79,77,61,48,120,50,48,44,67,69,78,84,69,82,61,48,120,99,44,72,79,82,73,90,79,78,84,65,76,61,48,120,52,44,76,69,70,84,61,48,120,49,44,77,73,68,68,76,69,61,48,120,99,44,82,73,71,72,84,61,48,120,50,44,84,79,80,61,48,120,49,48,44,86,69,82,84,73,67,65,76,61,48,120,56,10,99,46,67,67,70,58,65,85,68,73,79,61,48,120,56,48,44,67,79,77,77,65,78,68,61,48,120,49,44,68,65,84,65,61,48,120,49,48,48,44,70,73,76,69,83,89,83,84,69,77,61,48,120,50,44,71,82,65,80,72,73,67,83,61,48,120,52,44,71,85,73,61,48,120,56,44,73,79,61,48,120,49,48,44,77,73,83,67,61,48,120,50,48,48,44,77,85,76,84,73,77,69,68,73,65,61,48,120,56,48,48,44,78,69,84,87,79,82,75,61,48,120,52,48,48,44,83,89,83,84,69,77,61,48,120,50,48,44,84,79,79,76,61,48,120,52,48,10,99,46,67,70,58,68,69,70,76,65,84,69,61,48,120,51,44,71,90,73,80,61,48,120,49,44,90,76,73,66,61,48,120,50,10,99,46,67,76,70,58,73,78,72,69,82,73,84,95,76,79,67,65,76,61,48,120,49,44,78,79,95,79,87,78,69,82,83,72,73,80,61,48,120,50,10,99,46,67,76,73,80,77,79,68,69,58,67,79,80,89,61,48,120,50,44,67,85,84,61,48,120,49,44,80,65,83,84,69,61,48,120,52,10,99,46,67,77,70,58,65,80,80,76,89,95,83,69,67,85,82,73,84,89,61,48,120,50,48,44,67,82,69,65,84,69,95,70,73,76,69,61,48,120,52,44,78,69,87,61,48,120,50,44,78,79,95,76,73,78,75,83,61,48,120,49,48,44,80,65,83,83,87,79,82,68,61,48,120,49,44,82,69,65,68,95,79,78,76,89,61,48,120,56,10,99,46,67,78,70,58,65,85,84,79,95,83,65,86,69,61,48,120,50,44,78,69,87,61,48,120,56,44,79,80,84,73,79,78,65,76,95,70,73,76,69,83,61,48,120,52,44,83,84,82,73,80,95,81,85,79,84,69,83,61,48,120,49,10,99,46,67,79,78,58,68,80,65,68,95,68,79,87,78,61,48,120,50,48,44,68,80,65,68,95,76,69,70,84,61,48,120,52,48,44,68,80,65,68,95,82,73,71,72,84,61,48,120,56,48,44,68,80,65,68,95,85,80,61,48,120,49,48,44,71,65,77,69,80,65,68,95,69,61,48,120,50,44,71,65,77,69,80,65,68,95,78,61,48,120,56,44,71,65,77,69,80,65,68,95,83,61,48,120,49,44,71,65,77,69,80,65,68,95,87,61,48,120,52,44,76,69,70,84,95,66,85,77,80,69,82,95,49,61,48,120,52,48,48,44,76,69,70,84,95,66,85,77,80,69,82,95,50,61,48,120,56,48,48,44,82,73,71,72,84,95,66,85,77,80,69,82,95,49,61,48,120,49,48,48,48,44,82,73,71,72,84,95,66,85,77,80,69,82,95,50,61,48,120,50,48,48,48,44,83,69,76,69,67,84,61,48,120,50,48,48,44,83,84,65,82,84,61,48,120,49,48,48,10,99,46,68,65,84,65,58,65,85,68,73,79,61,48,120,53,44,67,79,78,84,69,78,84,61,48,120,98,44,68,69,86,73,67,69,95,73,78,80,85,84,61,48,120,51,44,70,73,76,69,61,48,120,97,44,73,77,65,71,69,61,48,120,55,44,73,78,80,85,84,95,82,69,65,68,89,61,48,120,99,44,82,65,87,61,48,120,50,44,82,69,67,69,73,80,84,61,48,120,57,44,82,69,67,79,82,68,61,48,120,54,44,82,69,81,85,69,83,84,61,48,120,56,44,84,69,88,84,61,48,120,49,44,88,77,76,61,48,120,52,10,99,46,68,69,86,73,67,69,58,66,79,79,75,77,65,82,75,61,48,120,52,48,48,48,48,44,67,79,77,80,65,67,84,95,68,73,83,67,61,48,120,49,44,70,73,88,69,68,61,48,120,56,48,48,48,44,70,76,79,80,80,89,95,68,73,83,75,61,48,120,52,44,72,65,82,68,95,68,73,83,75,61,48,120,50,44,77,69,77,79,82,89,61,48,120,49,48,48,48,44,77,79,68,69,77,61,48,120,50,48,48,48,44,78,69,84,87,79,82,75,61,48,120,56,48,44,80,82,73,78,84,69,82,61,48,120,50,48,48,44,80,82,73,78,84,69,82,95,51,68,61,48,120,49,48,48,48,48,44,82,69,65,68,61,48,120,56,44,82,69,77,79,86,65,66,76,69,61,48,120,50,48,44,82,69,77,79,86,69,65,66,76,69,61,48,120,50,48,44,83,67,65,78,78,69,82,61,48,120,52,48,48,44,83,67,65,78,78,69,82,95,51,68,61,48,120,50,48,48,48,48,44,83,79,70,84,87,65,82,69,61,48,120,52,48,44,84,65,80,69,61,48,120,49,48,48,44,84,69,77,80,79,82,65,82,89,61,48,120,56,48,48,44,85,83,66,61,48,120,52,48,48,48,44,87,82,73,84,69,61,48,120,49,48,10,99,46,68,77,70,58,70,73,88,69,68,95,67,69,78,84,69,82,95,88,61,48,120,49,48,48,48,48,48,44,70,73,88,69,68,95,67,69,78,84,69,82,95,89,61,48,120,50,48,48,48,48,48,44,70,73,88,69,68,95,68,69,80,84,72,61,48,120,49,48,48,48,44,70,73,88,69,68,95,72,69,73,71,72,84,61,48,120,49,48,48,44,70,73,88,69,68,95,82,65,68,73,85,83,95,88,61,48,120,50,48,48,48,48,44,70,73,88,69,68,95,82,65,68,73,85,83,95,89,61,48,120,50,48,48,48,48,48,48,44,70,73,88,69,68,95,87,73,68,84,72,61,48,120,50,48,48,44,70,73,88,69,68,95,88,61,48,120,52,44,70,73,88,69,68,95,88,95,79,70,70,83,69,84,61,48,120,52,48,44,70,73,88,69,68,95,89,61,48,120,56,44,70,73,88,69,68,95,89,95,79,70,70,83,69,84,61,48,120,56,48,44,70,73,88,69,68,95,90,61,48,120,52,48,48,48,44,83,67,65,76,69,68,95,67,69,78,84,69,82,95,88,61,48,120,52,48,48,48,48,44,83,67,65,76,69,68,95,67,69,78,84,69,82,95,89,61,48,120,56,48,48,48,48,44,83,67,65,76,69,68,95,68,69,80,84,72,61,48,120,50,48,48,48,44,83,67,65,76,69,68,95,72,69,73,71,72,84,61,48,120,52,48,48,44,83,67,65,76,69,68,95,82,65,68,73,85,83,95,88,61,48,120,49,48,48,48,48,44,83,67,65,76,69,68,95,82,65,68,73,85,83,95,89,61,48,120,49,48,48,48,48,48,48,44,83,67,65,76,69,68,95,87,73,68,84,72,61,48,120,56,48,48,44,83,67,65,76,69,68,95,88,61,48,120,49,44,83,67,65,76,69,68,95,88,95,79,70,70,83,69,84,61,48,120,49,48,44,83,67,65,76,69,68,95,89,61,48,120,50,44,83,67,65,76,69,68,95,89,95,79,70,70,83,69,84,61,48,120,50,48,44,83,67,65,76,69,68,95,90,61,48,120,56,48,48,48,44,83,84,65,84,85,83,95,67,72,65,78,71,69,95,72,61,48,120,52,48,48,48,48,48,44,83,84,65,84,85,83,95,67,72,65,78,71,69,95,86,61,48,120,56,48,48,48,48,48,10,99,46,68,82,76,58,68,79,87,78,61,48,120,49,44,69,65,83,84,61,48,120,50,44,76,69,70,84,61,48,120,51,44,78,79,82,84,72,61,48,120,48,44,78,79,82,84,72,95,69,65,83,84,61,48,120,52,44,78,79,82,84,72,95,87,69,83,84,61,48,120,53,44,82,73,71,72,84,61,48,120,50,44,83,79,85,84,72,61,48,120,49,44,83,79,85,84,72,95,69,65,83,84,61,48,120,54,44,83,79,85,84,72,95,87,69,83,84,61,48,120,55,44,85,80,61,48,120,48,44,87,69,83,84,61,48,120,51,10,99,46,69,68,71,69,58,65,76,76,61,48,120,102,102,44,66,79,84,84,79,77,61,48,120,56,44,66,79,84,84,79,77,95,76,69,70,84,61,48,120,52,48,44,66,79,84,84,79,77,95,82,73,71,72,84,61,48,120,56,48,44,76,69,70,84,61,48,120,50,44,82,73,71,72,84,61,48,120,52,44,84,79,80,61,48,120,49,44,84,79,80,95,76,69,70,84,61,48,120,49,48,44,84,79,80,95,82,73,71,72,84,61,48,120,50,48,10,99,46,69,82,70,58,78,111,116,105,102,105,101,100,61,48,120,52,48,48,48,48,48,48,48,10,99,46,69,82,82,58,65,99,99,101,115,115,77,101,109,111,114,121,61,48,120,52,98,44,65,99,99,101,115,115,79,98,106,101,99,116,61,48,120,53,51,44,65,99,99,101,115,115,83,101,109,97,112,104,111,114,101,61,48,120,55,51,44,65,99,116,105,118,97,116,101,61,48,120,52,50,44,65,100,100,67,108,97,115,115,61,48,120,52,49,44,65,108,108,111,99,77,101,109,111,114,121,61,48,120,53,52,44,65,108,108,111,99,83,101,109,97,112,104,111,114,101,61,48,120,55,50,44,65,108,114,101,97,100,121,68,101,102,105,110,101,100,61,48,120,98,54,44,65,108,114,101,97,100,121,76,111,99,107,101,100,61,48,120,57,99,44,65,114,103,115,61,48,120,49,52,44,65,114,114,97,121,70,117,108,108,61,48,120,50,100,44,66,117,102,102,101,114,79,118,101,114,102,108,111,119,61,48,120,53,99,44,66,117,115,121,61,48,120,56,98,44,67,97,110,99,101,108,108,101,100,61,48,120,51,44,67,97,114,100,82,101,97,100,101,114,85,110,97,118,97,105,108,97,98,108,101,61,48,120,57,102,44,67,97,114,100,82,101,97,100,101,114,85,110,107,110,111,119,110,61,48,120,57,100,44,67,111,109,112,114,101,115,115,105,111,110,61,48,120,97,100,44,67,111,110,110,101,99,116,105,111,110,65,98,111,114,116,101,100,61,48,120,56,99,44,67,111,110,110,101,99,116,105,111,110,82,101,102,117,115,101,100,61,48,120,56,51,44,67,111,110,115,116,114,97,105,110,116,86,105,111,108,97,116,105,111,110,61,48,120,56,56,44,67,111,110,116,105,110,117,101,61,48,120,53,44,67,111,114,101,86,101,114,115,105,111,110,61,48,120,50,54,44,67,114,101,97,116,101,70,105,108,101,61,48,120,55,52,44,67,114,101,97,116,101,79,98,106,101,99,116,61,48,120,54,53,44,67,114,101,97,116,101,82,101,115,111,117,114,99,101,61,48,120,98,50,44,68,97,116,97,83,105,122,101,61,48,120,56,97,44,68,101,97,99,116,105,118,97,116,101,100,61,48,120,57,97,44,68,101,97,100,76,111,99,107,61,48,120,51,101,44,68,101,99,111,109,112,114,101,115,115,105,111,110,61,48,120,97,99,44,68,101,108,101,116,101,70,105,108,101,61,48,120,55,53,44,68,105,114,69,109,112,116,121,61,48,120,56,44,68,105,115,99,111,110,110,101,99,116,101,100,61,48,120,56,54,44,68,111,78,111,116,69,120,112,117,110,103,101,61,48,120,51,48,44,68,111,101,115,78,111,116,69,120,105,115,116,61,48,120,55,56,44,68,111,117,98,108,101,73,110,105,116,61,48,120,52,51,44,68,114,97,119,61,48,120,52,56,44,69,78,68,61,48,120,98,101,44,69,109,112,116,121,83,116,114,105,110,103,61,48,120,54,100,44,69,110,100,79,102,70,105,108,101,61,48,120,55,101,44,69,110,116,114,121,77,105,115,115,105,110,103,72,101,97,100,101,114,61,48,120,51,97,44,69,120,97,109,105,110,101,70,97,105,108,101,100,61,48,120,49,57,44,69,120,99,101,112,116,105,111,110,61,48,120,97,51,44,69,120,99,101,112,116,105,111,110,84,104,114,101,115,104,111,108,100,61,48,120,57,44,69,120,99,108,117,115,105,118,101,68,101,110,105,101,100,61,48,120,53,51,44,69,120,101,99,86,105,111,108,97,116,105,111,110,61,48,120,56,102,44,69,120,105,115,116,115,61,48,120,55,97,44,69,120,112,101,99,116,101,100,70,105,108,101,61,48,120,54,102,44,69,120,112,101,99,116,101,100,70,111,108,100,101,114,61,48,120,97,101,44,70,97,105,108,101,100,61,48,120,100,44,70,97,108,115,101,61,48,120,49,44,70,105,101,108,100,78,111,116,83,101,116,61,48,120,52,52,44,70,105,101,108,100,83,101,97,114,99,104,61,48,120,51,50,44,70,105,101,108,100,84,121,112,101,77,105,115,109,97,116,99,104,61,48,120,53,97,44,70,105,108,101,61,48,120,101,44,70,105,108,101,68,111,101,115,78,111,116,69,120,105,115,116,61,48,120,49,50,44,70,105,108,101,69,120,105,115,116,115,61,48,120,54,51,44,70,105,108,101,78,111,116,70,111,117,110,100,61,48,120,49,50,44,70,105,108,101,82,101,97,100,70,108,97,103,61,48,120,52,54,44,70,105,108,101,87,114,105,116,101,70,108,97,103,61,48,120,52,55,44,70,105,110,105,115,104,101,100,61,48,120,55,101,44,70,117,110,99,116,105,111,110,61,48,120,98,53,44,71,101,116,70,105,101,108,100,61,48,120,53,54,44,71,101,116,83,117,114,102,97,99,101,73,110,102,111,61,48,120,55,100,44,72,111,115,116,78,111,116,70,111,117,110,100,61,48,120,56,49,44,72,111,115,116,85,110,114,101,97,99,104,97,98,108,101,61,48,120,56,53,44,73,100,101,110,116,105,99,97,108,80,97,116,104,115,61,48,120,55,57,44,73,108,108,101,103,97,108,65,99,116,105,111,110,65,116,116,101,109,112,116,61,48,120,51,57,44,73,108,108,101,103,97,108,65,99,116,105,111,110,73,68,61,48,120,51,55,44,73,108,108,101,103,97,108,65,100,100,114,101,115,115,61,48,120,57,49,44,73,108,108,101,103,97,108,77,101,116,104,111,100,73,68,61,48,120,51,54,44,73,109,109,117,116,97,98,108,101,61,48,120,97,102,44,73,110,85,115,101,61,48,120,99,44,73,110,105,116,61,48,120,50,49,44,73,110,105,116,77,111,100,117,108,101,61,48,120,49,49,44,73,110,112,117,116,79,117,116,112,117,116,61,48,120,57,52,44,73,110,116,101,103,114,105,116,121,86,105,111,108,97,116,105,111,110,61,48,120,56,56,44,73,110,118,97,108,105,100,68,97,116,97,61,48,120,102,44,73,110,118,97,108,105,100,68,105,109,101,110,115,105,111,110,61,48,120,53,57,44,73,110,118,97,108,105,100,72,84,84,80,82,101,115,112,111,110,115,101,61,48,120,97,49,44,73,110,118,97,108,105,100,72,97,110,100,108,101,61,48,120,57,54,44,73,110,118,97,108,105,100,79,98,106,101,99,116,61,48,120,56,101,44,73,110,118,97,108,105,100,80,97,116,104,61,48,120,51,51,44,73,110,118,97,108,105,100,82,101,102,101,114,101,110,99,101,61,48,120,97,50,44,73,110,118,97,108,105,100,83,116,97,116,101,61,48,120,56,48,44,73,110,118,97,108,105,100,85,82,73,61,48,120,56,50,44,73,110,118,97,108,105,100,86,97,108,117,101,61,48,120,57,56,44,76,105,109,105,116,101,100,83,117,99,99,101,115,115,61,48,120,50,44,76,105,115,116,67,104,105,108,100,114,101,110,61,48,120,54,97,44,76,111,97,100,77,111,100,117,108,101,61,48,120,57,53,44,76,111,99,107,61,48,120,49,56,44,76,111,99,107,70,97,105,108,101,100,61,48,120,49,56,44,76,111,99,107,77,117,116,101,120,61,48,120,97,97,44,76,111,99,107,82,101,113,117,105,114,101,100,61,48,120,57,98,44,76,111,99,107,101,100,61,48,120,57,99,44,76,111,111,112,61,48,120,54,50,44,76,111,115,116,67,108,97,115,115,61,48,120,49,97,44,76,111,115,116,79,119,110,101,114,61,48,120,50,102,44,76,111,119,67,97,112,97,99,105,116,121,61,48,120,50,48,44,77,97,114,107,101,100,70,111,114,68,101,108,101,116,105,111,110,61,48,120,51,53,44,77,101,109,111,114,121,61,48,120,49,100,44,77,101,109,111,114,121,67,111,114,114,117,112,116,61,48,120,51,49,44,77,101,109,111,114,121,68,111,101,115,78,111,116,69,120,105,115,116,61,48,120,51,100,44,77,101,109,111,114,121,73,110,102,111,61,48,120,54,54,44,77,105,115,109,97,116,99,104,61,48,120,53,101,44,77,105,115,115,105,110,103,67,108,97,115,115,61,48,120,52,53,44,77,105,115,115,105,110,103,67,108,97,115,115,78,97,109,101,61,48,120,50,97,44,77,105,115,115,105,110,103,80,97,116,104,61,48,120,52,99,44,77,111,100,117,108,101,73,110,105,116,70,97,105,108,101,100,61,48,120,51,99,44,77,111,100,117,108,101,77,105,115,115,105,110,103,73,110,105,116,61,48,120,51,98,44,77,111,100,117,108,101,77,105,115,115,105,110,103,78,97,109,101,61,48,120,52,48,44,77,111,100,117,108,101,79,112,101,110,70,97,105,108,101,100,61,48,120,51,56,44,78,101,101,100,79,119,110,101,114,61,48,120,50,52,44,78,101,101,100,87,105,100,116,104,72,101,105,103,104,116,61,48,120,50,55,44,78,101,103,97,116,105,118,101,67,108,97,115,115,73,68,61,48,120,50,57,44,78,101,103,97,116,105,118,101,83,117,98,67,108,97,115,115,73,68,61,48,120,50,56,44,78,101,116,119,111,114,107,85,110,114,101,97,99,104,97,98,108,101,61,48,120,56,52,44,78,101,119,79,98,106,101,99,116,61,48,120,53,53,44,78,111,65,99,116,105,111,110,61,48,120,49,98,44,78,111,68,97,116,97,61,48,120,49,53,44,78,111,70,105,101,108,100,65,99,99,101,115,115,61,48,120,53,55,44,78,111,77,97,116,99,104,105,110,103,79,98,106,101,99,116,61,48,120,52,97,44,78,111,77,101,100,105,97,73,110,115,101,114,116,101,100,61,48,120,57,101,44,78,111,77,101,109,111,114,121,61,48,120,97,44,78,111,77,101,116,104,111,100,115,61,48,120,52,57,44,78,111,80,101,114,109,105,115,115,105,111,110,61,48,120,50,50,44,78,111,80,111,105,110,116,101,114,61,48,120,98,44,78,111,83,101,97,114,99,104,82,101,115,117,108,116,61,48,120,52,101,44,78,111,83,116,97,116,115,61,48,120,49,102,44,78,111,83,117,112,112,111,114,116,61,48,120,49,99,44,78,111,116,70,111,117,110,100,61,48,120,49,48,44,78,111,116,73,110,105,116,105,97,108,105,115,101,100,61,48,120,54,55,44,78,111,116,76,111,99,107,101,100,61,48,120,52,100,44,78,111,116,80,111,115,115,105,98,108,101,61,48,120,98,51,44,78,111,116,104,105,110,103,68,111,110,101,61,48,120,52,44,78,111,116,105,102,105,101,100,61,48,120,52,48,48,48,48,48,48,48,44,78,117,108,108,65,114,103,115,61,48,120,56,100,44,79,98,106,101,99,116,67,111,114,114,117,112,116,61,48,120,53,48,44,79,98,106,101,99,116,69,120,105,115,116,115,61,48,120,54,101,44,79,98,115,111,108,101,116,101,61,48,120,98,49,44,79,98,116,97,105,110,77,101,116,104,111,100,61,48,120,50,99,44,79,107,97,121,61,48,120,48,44,79,112,101,110,70,105,108,101,61,48,120,55,54,44,79,112,101,110,71,76,61,48,120,97,53,44,79,117,116,79,102,66,111,117,110,100,115,61,48,120,53,102,44,79,117,116,79,102,68,97,116,97,61,48,120,55,101,44,79,117,116,79,102,82,97,110,103,101,61,48,120,50,98,44,79,117,116,79,102,83,112,97,99,101,61,48,120,55,99,44,79,117,116,115,105,100,101,77,97,105,110,84,104,114,101,97,100,61,48,120,97,54,44,79,119,110,101,114,78,101,101,100,115,66,105,116,109,97,112,61,48,120,50,53,44,79,119,110,101,114,80,97,115,115,84,104,114,111,117,103,104,61,48,120,53,49,44,80,101,114,109,105,115,115,105,111,110,68,101,110,105,101,100,61,48,120,50,50,44,80,101,114,109,105,115,115,105,111,110,115,61,48,120,50,50,44,80,114,111,120,121,83,83,76,84,117,110,110,101,108,61,48,120,97,48,44,81,117,101,114,121,61,48,120,50,101,44,82,101,97,100,61,48,120,49,54,44,82,101,97,100,70,105,108,101,84,111,66,117,102,102,101,114,61,48,120,98,48,44,82,101,97,100,79,110,108,121,61,48,120,55,55,44,82,101,97,108,108,111,99,77,101,109,111,114,121,61,48,120,54,49,44,82,101,99,117,114,115,105,111,110,61,48,120,57,48,44,82,101,100,105,109,101,110,115,105,111,110,61,48,120,55,49,44,82,101,102,114,101,115,104,61,48,120,54,57,44,82,101,115,105,122,101,61,48,120,55,48,44,82,101,115,111,108,118,101,80,97,116,104,61,48,120,54,52,44,82,101,115,111,108,118,101,83,121,109,98,111,108,61,48,120,98,52,44,82,101,115,111,117,114,99,101,69,120,105,115,116,115,61,48,120,54,56,44,82,101,116,114,121,61,48,120,55,44,83,97,110,105,116,121,70,97,105,108,117,114,101,61,48,120,55,98,44,83,99,104,101,109,97,86,105,111,108,97,116,105,111,110,61,48,120,56,57,44,83,101,97,114,99,104,61,48,120,49,48,44,83,101,99,117,114,105,116,121,61,48,120,57,55,44,83,101,101,107,61,48,120,54,48,44,83,101,114,118,105,99,101,85,110,97,118,97,105,108,97,98,108,101,61,48,120,57,57,44,83,101,116,70,105,101,108,100,61,48,120,51,52,44,83,101,116,86,97,108,117,101,78,111,116,65,114,114,97,121,61,48,120,98,99,44,83,101,116,86,97,108,117,101,78,111,116,70,117,110,99,116,105,111,110,61,48,120,98,97,44,83,101,116,86,97,108,117,101,78,111,116,76,111,111,107,117,112,61,48,120,98,100,44,83,101,116,86,97,108,117,101,78,111,116,78,117,109,101,114,105,99,61,48,120,98,55,44,83,101,116,86,97,108,117,101,78,111,116,79,98,106,101,99,116,61,48,120,98,57,44,83,101,116,86,97,108,117,101,78,111,116,80,111,105,110,116,101,114,61,48,120,98,98,44,83,101,116,86,97,108,117,101,78,111,116,83,116,114,105,110,103,61,48,120,98,56,44,83,101,116,86,111,108,117,109,101,61,48,120,97,98,44,83,107,105,112,61,48,120,54,44,83,109,97,108,108,77,97,115,107,61,48,120,54,99,44,83,116,97,116,101,109,101,110,116,85,110,115,97,116,105,115,102,105,101,100,61,48,120,52,102,44,83,116,114,105,110,103,70,111,114,109,97,116,61,48,120,55,102,44,83,121,110,116,97,120,61,48,120,55,102,44,83,121,115,116,101,109,67,97,108,108,61,48,120,54,98,44,83,121,115,116,101,109,67,111,114,114,117,112,116,61,48,120,50,51,44,83,121,115,116,101,109,76,111,99,107,101,100,61,48,120,51,102,44,84,97,115,107,83,116,105,108,108,69,120,105,115,116,115,61,48,120,56,55,44,84,101,114,109,105,110,97,116,101,61,48,120,57,44,84,104,114,101,97,100,65,108,114,101,97,100,121,65,99,116,105,118,101,61,48,120,97,52,44,84,104,114,101,97,100,78,111,116,76,111,99,107,101,100,61,48,120,97,57,44,84,105,109,101,79,117,116,61,48,120,49,101,44,84,114,117,101,61,48,120,48,44,85,110,98,97,108,97,110,99,101,100,88,77,76,61,48,120,57,50,44,85,110,100,101,102,105,110,101,100,70,105,101,108,100,61,48,120,52,52,44,85,110,114,101,99,111,103,110,105,115,101,100,70,105,101,108,100,84,121,112,101,61,48,120,53,98,44,85,110,115,117,112,112,111,114,116,101,100,70,105,101,108,100,61,48,120,53,100,44,85,110,115,117,112,112,111,114,116,101,100,79,119,110,101,114,61,48,120,53,50,44,85,115,101,83,117,98,67,108,97,115,115,61,48,120,97,55,44,86,105,114,116,117,97,108,86,111,108,117,109,101,61,48,120,53,56,44,87,111,117,108,100,66,108,111,99,107,61,48,120,57,51,44,87,114,105,116,101,61,48,120,49,55,44,87,114,111,110,103,67,108,97,115,115,61,48,120,56,101,44,87,114,111,110,103,79,98,106,101,99,116,84,121,112,101,61,48,120,56,101,44,87,114,111,110,103,84,121,112,101,61,48,120,97,56,44,87,114,111,110,103,86,101,114,115,105,111,110,61,48,120,49,51,10,99,46,69,86,71,58,65,78,68,82,79,73,68,61,48,120,100,44,65,80,80,61,48,120,99,44,65,85,68,73,79,61,48,120,56,44,67,76,65,83,83,61,48,120,98,44,68,73,83,80,76,65,89,61,48,120,53,44,69,78,68,61,48,120,101,44,70,73,76,69,83,89,83,84,69,77,61,48,120,49,44,71,85,73,61,48,120,52,44,72,65,82,68,87,65,82,69,61,48,120,55,44,73,79,61,48,120,54,44,78,69,84,87,79,82,75,61,48,120,50,44,80,79,87,69,82,61,48,120,97,44,83,89,83,84,69,77,61,48,120,51,44,85,83,69,82,61,48,120,57,10,99,46,70,66,75,58,67,79,80,89,95,70,73,76,69,61,48,120,50,44,68,69,76,69,84,69,95,70,73,76,69,61,48,120,51,44,77,79,86,69,95,70,73,76,69,61,48,120,49,10,99,46,70,68,58,65,76,76,79,67,61,48,120,50,48,44,65,82,82,65,89,61,48,120,49,48,48,48,44,65,82,82,65,89,83,73,90,69,61,48,120,56,48,44,66,85,70,70,69,82,61,48,120,50,48,48,44,66,85,70,83,73,90,69,61,48,120,56,48,44,66,89,84,69,61,48,120,49,48,48,48,48,48,48,44,67,80,80,61,48,120,52,48,48,48,44,67,85,83,84,79,77,61,48,120,56,48,48,48,44,68,79,85,66,76,69,61,48,120,56,48,48,48,48,48,48,48,44,68,79,85,66,76,69,82,69,83,85,76,84,61,48,120,56,48,48,48,48,49,48,48,44,69,82,82,79,82,61,48,120,56,48,48,44,70,76,65,71,83,61,48,120,52,48,44,70,76,79,65,84,61,48,120,49,48,48,48,48,48,48,48,44,70,85,78,67,84,73,79,78,61,48,120,50,48,48,48,48,48,48,44,70,85,78,67,84,73,79,78,80,84,82,61,48,120,97,48,48,48,48,48,48,44,73,61,48,120,52,48,48,44,73,78,73,84,61,48,120,52,48,48,44,76,65,82,71,69,61,48,120,52,48,48,48,48,48,48,44,76,65,82,71,69,82,69,83,85,76,84,61,48,120,52,48,48,48,49,48,48,44,76,79,67,65,76,61,48,120,50,44,76,79,78,71,61,48,120,52,48,48,48,48,48,48,48,44,76,79,78,71,82,69,83,85,76,84,61,48,120,52,48,48,48,48,49,48,48,44,76,79,79,75,85,80,61,48,120,56,48,44,79,66,74,69,67,84,61,48,120,49,44,79,66,74,69,67,84,73,68,61,48,120,52,48,48,48,48,48,48,49,44,79,66,74,69,67,84,80,84,82,61,48,120,56,48,48,48,48,48,49,44,80,79,73,78,84,69,82,61,48,120,56,48,48,48,48,48,48,44,80,82,73,86,65,84,69,61,48,120,49,48,48,48,48,44,80,84,82,61,48,120,56,48,48,48,48,48,48,44,80,84,82,66,85,70,70,69,82,61,48,120,56,48,48,48,50,48,48,44,80,84,82,82,69,83,85,76,84,61,48,120,56,48,48,48,49,48,48,44,80,84,82,83,73,90,69,61,48,120,56,48,44,80,84,82,95,68,79,85,66,76,69,82,69,83,85,76,84,61,48,120,56,56,48,48,48,49,48,48,44,80,84,82,95,76,65,82,71,69,82,69,83,85,76,84,61,48,120,99,48,48,48,49,48,48,44,80,84,82,95,76,79,78,71,82,69,83,85,76,84,61,48,120,52,56,48,48,48,49,48,48,44,82,61,48,120,49,48,48,44,82,69,65,68,61,48,120,49,48,48,44,82,69,83,79,85,82,67,69,61,48,120,50,48,48,48,44,82,69,83,85,76,84,61,48,120,49,48,48,44,82,71,66,61,48,120,56,48,48,48,48,44,82,73,61,48,120,53,48,48,44,82,87,61,48,120,51,48,48,44,83,67,65,76,69,68,61,48,120,50,48,48,48,48,48,44,83,84,82,61,48,120,56,48,48,48,48,48,44,83,84,82,73,78,71,61,48,120,56,48,48,48,48,48,44,83,84,82,82,69,83,85,76,84,61,48,120,56,48,48,49,48,48,44,83,84,82,85,67,84,61,48,120,49,48,44,83,89,78,79,78,89,77,61,48,120,50,48,48,48,48,44,83,89,83,84,69,77,61,48,120,49,48,48,48,48,44,84,65,71,83,61,48,120,52,48,48,44,85,78,73,84,61,48,120,50,48,48,48,48,48,48,48,44,85,78,83,73,71,78,69,68,61,48,120,52,48,48,48,48,44,86,65,82,84,65,71,83,61,48,120,52,48,44,86,73,82,84,85,65,76,61,48,120,56,44,86,79,73,68,61,48,120,48,44,86,79,76,65,84,73,76,69,61,48,120,48,44,87,61,48,120,50,48,48,44,87,79,82,68,61,48,120,52,48,48,48,48,48,44,87,82,73,84,69,61,48,120,50,48,48,10,99,46,70,68,66,58,67,79,77,80,82,69,83,83,95,70,73,76,69,61,48,120,50,44,68,69,67,79,77,80,82,69,83,83,95,70,73,76,69,61,48,120,49,44,68,69,67,79,77,80,82,69,83,83,95,79,66,74,69,67,84,61,48,120,52,44,82,69,77,79,86,69,95,70,73,76,69,61,48,120,51,10,99,46,70,68,76,58,70,69,69,68,66,65,67,75,61,48,120,49,10,99,46,70,68,84,58,65,67,67,69,83,83,69,68,61,48,120,50,44,65,82,67,72,73,86,69,68,61,48,120,51,44,67,82,69,65,84,69,68,61,48,120,49,44,77,79,68,73,70,73,69,68,61,48,120,48,10,99,46,70,70,82,58,65,66,79,82,84,61,48,120,50,44,67,79,78,84,73,78,85,69,61,48,120,48,44,79,75,65,89,61,48,120,48,44,83,75,73,80,61,48,120,49,10,99,46,70,76,58,65,80,80,82,79,88,73,77,65,84,69,61,48,120,49,48,44,66,85,70,70,69,82,61,48,120,52,48,44,68,69,86,73,67,69,61,48,120,52,48,48,44,68,73,82,69,67,84,79,82,89,61,48,120,56,44,69,88,67,76,85,68,69,95,70,73,76,69,83,61,48,120,49,48,48,48,44,69,88,67,76,85,68,69,95,70,79,76,68,69,82,83,61,48,120,50,48,48,48,44,70,73,76,69,61,48,120,49,48,48,44,70,79,76,68,69,82,61,48,120,56,44,76,73,78,75,61,48,120,50,48,44,76,79,79,80,61,48,120,56,48,44,78,69,87,61,48,120,50,44,82,69,65,68,61,48,120,52,44,82,69,83,69,84,95,68,65,84,69,61,48,120,50,48,48,44,83,84,82,69,65,77,61,48,120,56,48,48,44,87,82,73,84,69,61,48,120,49,10,99,46,70,79,70,58,83,77,65,82,84,95,78,65,77,69,83,61,48,120,49,10,99,46,73,68,84,89,80,69,58,70,85,78,67,84,73,79,78,61,48,120,51,44,71,76,79,66,65,76,61,48,120,50,44,77,69,83,83,65,71,69,61,48,120,49,10,99,46,74,69,84,58,65,66,83,95,88,89,61,48,120,101,44,66,85,84,84,79,78,95,49,61,48,120,49,44,66,85,84,84,79,78,95,49,48,61,48,120,97,44,66,85,84,84,79,78,95,50,61,48,120,50,44,66,85,84,84,79,78,95,51,61,48,120,51,44,66,85,84,84,79,78,95,52,61,48,120,52,44,66,85,84,84,79,78,95,53,61,48,120,53,44,66,85,84,84,79,78,95,54,61,48,120,54,44,66,85,84,84,79,78,95,55,61,48,120,55,44,66,85,84,84,79,78,95,56,61,48,120,56,44,66,85,84,84,79,78,95,57,61,48,120,57,44,67,82,79,83,83,69,68,95,73,78,61,48,120,102,44,67,82,79,83,83,69,68,95,79,85,84,61,48,120,49,48,44,68,69,86,73,67,69,95,84,73,76,84,95,88,89,61,48,120,49,50,44,68,69,86,73,67,69,95,84,73,76,84,95,90,61,48,120,49,51,44,68,73,83,80,76,65,89,95,69,68,71,69,61,48,120,49,52,44,69,78,68,61,48,120,49,53,44,76,77,66,61,48,120,49,44,77,77,66,61,48,120,51,44,80,69,78,95,84,73,76,84,95,88,89,61,48,120,100,44,80,82,69,83,83,85,82,69,61,48,120,49,49,44,82,77,66,61,48,120,50,44,87,72,69,69,76,61,48,120,98,44,87,72,69,69,76,95,84,73,76,84,61,48,120,99,10,99,46,74,84,89,80,69,58,65,78,65,76,79,71,61,48,120,50,48,44,65,78,67,72,79,82,69,68,61,48,120,50,44,66,85,84,84,79,78,61,48,120,56,48,44,67,82,79,83,83,73,78,71,61,48,120,56,44,68,66,76,95,67,76,73,67,75,61,48,120,50,48,48,44,68,73,71,73,84,65,76,61,48,120,49,48,44,68,82,65,71,71,69,68,61,48,120,52,44,68,82,65,71,95,73,84,69,77,61,48,120,56,48,48,44,69,88,84,95,77,79,86,69,77,69,78,84,61,48,120,52,48,44,77,79,86,69,77,69,78,84,61,48,120,49,48,48,44,82,69,80,69,65,84,69,68,61,48,120,52,48,48,44,83,69,67,79,78,68,65,82,89,61,48,120,49,10,99,46,75,69,89,58,65,61,48,120,49,44,65,80,79,83,84,82,79,80,72,69,61,48,120,50,98,44,65,84,61,48,120,56,97,44,66,61,48,120,50,44,66,65,67,75,61,48,120,56,54,44,66,65,67,75,83,80,65,67,69,61,48,120,54,57,44,66,65,67,75,95,83,76,65,83,72,61,48,120,50,102,44,66,82,69,65,75,61,48,120,55,98,44,67,61,48,120,51,44,67,65,76,76,61,48,120,56,55,44,67,65,77,69,82,65,61,48,120,56,57,44,67,65,78,67,69,76,61,48,120,55,97,44,67,65,80,83,95,76,79,67,75,61,48,120,52,54,44,67,76,69,65,82,61,48,120,54,101,44,67,79,77,77,65,61,48,120,50,99,44,68,61,48,120,52,44,68,69,76,69,84,69,61,48,120,54,100,44,68,79,84,61,48,120,50,100,44,68,79,87,78,61,48,120,54,49,44,69,61,48,120,53,44,69,73,71,72,84,61,48,120,50,50,44,69,78,68,61,48,120,55,50,44,69,78,68,95,67,65,76,76,61,48,120,56,56,44,69,78,84,69,82,61,48,120,54,98,44,69,81,85,65,76,83,61,48,120,50,55,44,69,83,67,65,80,69,61,48,120,54,99,44,69,88,69,67,85,84,69,61,48,120,55,52,44,70,61,48,120,54,44,70,49,61,48,120,52,99,44,70,49,48,61,48,120,53,53,44,70,49,49,61,48,120,53,54,44,70,49,50,61,48,120,53,55,44,70,49,51,61,48,120,53,56,44,70,49,52,61,48,120,53,57,44,70,49,53,61,48,120,53,97,44,70,49,54,61,48,120,53,98,44,70,49,55,61,48,120,53,99,44,70,49,56,61,48,120,56,48,44,70,49,57,61,48,120,56,49,44,70,50,61,48,120,52,100,44,70,50,48,61,48,120,56,50,44,70,51,61,48,120,52,101,44,70,52,61,48,120,52,102,44,70,53,61,48,120,53,48,44,70,54,61,48,120,53,49,44,70,55,61,48,120,53,50,44,70,56,61,48,120,53,51,44,70,57,61,48,120,53,52,44,70,73,78,68,61,48,120,55,57,44,70,73,86,69,61,48,120,49,102,44,70,79,82,87,65,82,68,61,48,120,57,48,44,70,79,85,82,61,48,120,49,101,44,71,61,48,120,55,44,72,61,48,120,56,44,72,69,76,80,61,48,120,52,51,44,72,79,77,69,61,48,120,54,102,44,73,61,48,120,57,44,73,78,83,69,82,84,61,48,120,55,53,44,74,61,48,120,97,44,75,61,48,120,98,44,76,61,48,120,99,44,76,69,70,84,61,48,120,54,51,44,76,69,78,83,95,70,79,67,85,83,61,48,120,56,99,44,76,69,83,83,95,71,82,69,65,84,69,82,61,48,120,53,102,44,76,73,83,84,95,69,78,68,61,48,120,57,54,44,76,95,65,76,84,61,48,120,52,56,44,76,95,67,79,77,77,65,78,68,61,48,120,52,97,44,76,95,67,79,78,84,82,79,76,61,48,120,52,49,44,76,95,83,72,73,70,84,61,48,120,52,52,44,76,95,83,81,85,65,82,69,61,48,120,50,56,44,77,61,48,120,100,44,77,65,67,82,79,61,48,120,53,100,44,77,69,78,85,61,48,120,55,56,44,77,73,78,85,83,61,48,120,50,54,44,77,85,84,69,61,48,120,57,50,44,78,61,48,120,101,44,78,69,88,84,61,48,120,56,101,44,78,73,78,69,61,48,120,50,51,44,78,80,95,48,61,48,120,51,49,44,78,80,95,49,61,48,120,51,50,44,78,80,95,50,61,48,120,51,51,44,78,80,95,51,61,48,120,51,52,44,78,80,95,52,61,48,120,51,53,44,78,80,95,53,61,48,120,51,54,44,78,80,95,54,61,48,120,51,55,44,78,80,95,55,61,48,120,51,56,44,78,80,95,56,61,48,120,51,57,44,78,80,95,57,61,48,120,51,97,44,78,80,95,66,65,82,61,48,120,51,100,44,78,80,95,68,69,67,73,77,65,76,61,48,120,51,102,44,78,80,95,68,73,86,73,68,69,61,48,120,52,48,44,78,80,95,68,79,84,61,48,120,51,102,44,78,80,95,69,78,84,69,82,61,48,120,55,101,44,78,80,95,77,73,78,85,83,61,48,120,51,101,44,78,80,95,77,85,76,84,73,80,76,89,61,48,120,51,98,44,78,80,95,80,76,85,83,61,48,120,51,99,44,78,80,95,80,76,85,83,95,77,73,78,85,83,61,48,120,53,101,44,78,80,95,83,69,80,65,82,65,84,79,82,61,48,120,51,100,44,78,85,77,95,76,79,67,75,61,48,120,55,99,44,79,61,48,120,102,44,79,78,69,61,48,120,49,98,44,80,61,48,120,49,48,44,80,65,71,69,95,68,79,87,78,61,48,120,55,49,44,80,65,71,69,95,85,80,61,48,120,55,48,44,80,65,85,83,69,61,48,120,54,53,44,80,69,82,73,79,68,61,48,120,50,100,44,80,76,65,89,61,48,120,57,53,44,80,76,85,83,61,48,120,56,98,44,80,79,85,78,68,61,48,120,57,52,44,80,79,87,69,82,61,48,120,54,56,44,80,82,69,86,73,79,85,83,61,48,120,56,102,44,80,82,73,78,84,61,48,120,52,55,44,80,82,84,95,83,67,82,61,48,120,55,100,44,81,61,48,120,49,49,44,82,61,48,120,49,50,44,82,69,68,79,61,48,120,55,55,44,82,69,86,69,82,83,69,95,81,85,79,84,69,61,48,120,50,53,44,82,69,87,73,78,68,61,48,120,57,49,44,82,73,71,72,84,61,48,120,54,50,44,82,95,65,76,84,61,48,120,52,57,44,82,95,67,79,77,77,65,78,68,61,48,120,52,98,44,82,95,67,79,78,84,82,79,76,61,48,120,52,50,44,82,95,83,72,73,70,84,61,48,120,52,53,44,82,95,83,81,85,65,82,69,61,48,120,50,57,44,83,61,48,120,49,51,44,83,67,82,95,76,79,67,75,61,48,120,54,52,44,83,69,76,69,67,84,61,48,120,55,51,44,83,69,77,73,95,67,79,76,79,78,61,48,120,50,97,44,83,69,86,69,78,61,48,120,50,49,44,83,73,88,61,48,120,50,48,44,83,76,65,83,72,61,48,120,50,101,44,83,76,69,69,80,61,48,120,54,55,44,83,80,65,67,69,61,48,120,51,48,44,83,84,65,82,61,48,120,57,51,44,83,84,79,80,61,48,120,56,100,44,83,89,83,82,81,61,48,120,55,102,44,84,61,48,120,49,52,44,84,65,66,61,48,120,54,97,44,84,72,82,69,69,61,48,120,49,100,44,84,87,79,61,48,120,49,99,44,85,61,48,120,49,53,44,85,78,68,79,61,48,120,55,54,44,85,80,61,48,120,54,48,44,86,61,48,120,49,54,44,86,79,76,85,77,69,95,68,79,87,78,61,48,120,56,53,44,86,79,76,85,77,69,95,85,80,61,48,120,56,52,44,87,61,48,120,49,55,44,87,65,75,69,61,48,120,54,54,44,87,73,78,95,67,79,78,84,82,79,76,61,48,120,56,51,44,88,61,48,120,49,56,44,89,61,48,120,49,57,44,90,61,48,120,49,97,44,90,69,82,79,61,48,120,50,52,10,99,46,75,81,58,65,76,84,61,48,120,54,48,44,65,76,84,71,82,61,48,120,52,48,44,67,65,80,83,95,76,79,67,75,61,48,120,52,44,67,79,77,77,65,78,68,61,48,120,49,56,48,44,67,79,78,84,82,79,76,61,48,120,49,56,44,67,84,82,76,61,48,120,49,56,44,68,69,65,68,95,75,69,89,61,48,120,49,48,48,48,48,44,73,78,70,79,61,48,120,51,99,48,52,44,73,78,83,84,82,85,67,84,73,79,78,95,75,69,89,83,61,48,120,55,56,44,76,95,65,76,84,61,48,120,50,48,44,76,95,67,79,77,77,65,78,68,61,48,120,56,48,44,76,95,67,79,78,84,82,79,76,61,48,120,56,44,76,95,67,84,82,76,61,48,120,56,44,76,95,83,72,73,70,84,61,48,120,49,44,78,79,84,95,80,82,73,78,84,65,66,76,69,61,48,120,50,48,48,48,44,78,85,77,95,76,79,67,75,61,48,120,56,48,48,48,44,78,85,77,95,80,65,68,61,48,120,50,48,48,44,80,82,69,83,83,69,68,61,48,120,49,48,48,48,44,81,85,65,76,73,70,73,69,82,83,61,48,120,49,102,98,44,82,69,76,69,65,83,69,68,61,48,120,56,48,48,44,82,69,80,69,65,84,61,48,120,52,48,48,44,82,95,65,76,84,61,48,120,52,48,44,82,95,67,79,77,77,65,78,68,61,48,120,49,48,48,44,82,95,67,79,78,84,82,79,76,61,48,120,49,48,44,82,95,67,84,82,76,61,48,120,49,48,44,82,95,83,72,73,70,84,61,48,120,50,44,83,67,82,95,76,79,67,75,61,48,120,52,48,48,48,44,83,72,73,70,84,61,48,120,51,44,87,73,78,95,67,79,78,84,82,79,76,61,48,120,50,48,48,48,48,10,99,46,76,65,89,79,85,84,58,66,65,67,75,71,82,79,85,78,68,61,48,120,56,44,69,77,66,69,68,68,69,68,61,48,120,50,48,44,70,79,82,69,71,82,79,85,78,68,61,48,120,49,48,44,73,71,78,79,82,69,95,67,85,82,83,79,82,61,48,120,56,48,44,76,69,70,84,61,48,120,50,44,76,79,67,75,61,48,120,52,48,44,82,73,71,72,84,61,48,120,52,44,83,81,85,65,82,69,61,48,120,48,44,84,73,71,72,84,61,48,120,49,44,84,73,76,69,61,48,120,49,48,48,44,87,73,68,69,61,48,120,54,10,99,46,76,68,70,58,67,72,69,67,75,95,69,88,73,83,84,83,61,48,120,49,10,99,46,76,79,67,58,68,73,82,69,67,84,79,82,89,61,48,120,49,44,70,73,76,69,61,48,120,51,44,70,79,76,68,69,82,61,48,120,49,44,86,79,76,85,77,69,61,48,120,50,10,99,46,77,65,88,58,70,73,76,69,78,65,77,69,61,48,120,49,48,48,44,78,65,77,69,95,76,69,78,61,48,120,49,102,10,99,46,77,69,77,58,65,85,68,73,79,61,48,120,56,44,67,65,76,76,69,82,61,48,120,56,48,48,48,48,48,44,67,79,68,69,61,48,120,49,48,44,67,79,76,76,69,67,84,61,48,120,49,48,48,48,44,68,65,84,65,61,48,120,48,44,69,88,67,76,85,83,73,86,69,61,48,120,56,48,48,44,72,73,68,68,69,78,61,48,120,49,48,48,48,48,48,44,77,65,78,65,71,69,68,61,48,120,49,44,78,79,95,66,76,79,67,75,61,48,120,50,48,48,48,44,78,79,95,66,76,79,67,75,73,78,71,61,48,120,50,48,48,48,44,78,79,95,67,76,69,65,82,61,48,120,52,48,48,48,48,44,78,79,95,76,79,67,75,61,48,120,52,48,48,44,78,79,95,80,79,79,76,61,48,120,50,48,44,79,66,74,69,67,84,61,48,120,50,48,48,44,82,69,65,68,61,48,120,49,48,48,48,48,44,82,69,65,68,95,87,82,73,84,69,61,48,120,51,48,48,48,48,44,83,84,82,73,78,71,61,48,120,49,48,48,44,84,69,88,84,85,82,69,61,48,120,52,44,84,77,80,95,76,79,67,75,61,48,120,52,48,44,85,78,84,82,65,67,75,69,68,61,48,120,56,48,44,86,73,68,69,79,61,48,120,50,44,87,82,73,84,69,61,48,120,50,48,48,48,48,10,99,46,77,70,70,58,65,84,84,82,73,66,61,48,120,50,48,44,67,76,79,83,69,68,61,48,120,56,48,44,67,82,69,65,84,69,61,48,120,52,44,68,69,69,80,61,48,120,49,48,48,48,44,68,69,76,69,84,69,61,48,120,56,44,70,73,76,69,61,48,120,52,48,48,44,70,79,76,68,69,82,61,48,120,50,48,48,44,77,79,68,73,70,89,61,48,120,50,44,77,79,86,69,68,61,48,120,49,48,44,79,80,69,78,69,68,61,48,120,52,48,44,82,69,65,68,61,48,120,49,44,82,69,78,65,77,69,61,48,120,49,48,44,83,69,76,70,61,48,120,56,48,48,44,85,78,77,79,85,78,84,61,48,120,49,48,48,44,87,82,73,84,69,61,48,120,50,10,99,46,77,72,70,58,68,69,70,65,85,76,84,61,48,120,50,44,83,84,65,84,73,67,61,48,120,49,44,83,84,82,85,67,84,85,82,69,61,48,120,50,10,99,46,77,79,70,58,76,73,78,75,95,76,73,66,82,65,82,89,61,48,120,49,44,83,84,65,84,73,67,61,48,120,50,44,83,89,83,84,69,77,95,80,82,79,66,69,61,48,120,52,10,99,46,77,79,86,69,58,65,76,76,61,48,120,102,44,68,79,87,78,61,48,120,49,44,76,69,70,84,61,48,120,52,44,82,73,71,72,84,61,48,120,56,44,85,80,61,48,120,50,10,99,46,77,83,70,58,65,68,68,61,48,120,56,44,65,68,68,82,69,83,83,61,48,120,49,48,44,77,69,83,83,65,71,69,95,73,68,61,48,120,50,48,44,78,79,95,68,85,80,76,73,67,65,84,69,61,48,120,52,44,85,80,68,65,84,69,61,48,120,50,44,87,65,73,84,61,48,120,49,10,99,46,77,83,71,73,68,58,65,67,84,73,79,78,61,48,120,54,51,44,66,82,69,65,75,61,48,120,54,52,44,67,79,77,77,65,78,68,61,48,120,54,53,44,67,79,82,69,95,69,78,68,61,48,120,54,52,44,68,69,66,85,71,61,48,120,53,102,44,69,86,69,78,84,61,48,120,53,101,44,70,82,69,69,61,48,120,54,50,44,81,85,73,84,61,48,120,51,101,56,44,84,72,82,69,65,68,95,65,67,84,73,79,78,61,48,120,53,98,44,84,72,82,69,65,68,95,67,65,76,76,66,65,67,75,61,48,120,53,99,44,86,65,76,73,68,65,84,69,95,80,82,79,67,69,83,83,61,48,120,53,100,44,87,65,73,84,95,70,79,82,95,79,66,74,69,67,84,83,61,48,120,53,97,10,99,46,77,84,70,58,65,78,73,77,61,48,120,56,44,82,69,76,65,84,73,86,69,61,48,120,49,48,44,88,61,48,120,49,44,89,61,48,120,50,44,90,61,48,120,52,10,99,46,78,69,84,77,83,71,58,69,78,68,61,48,120,49,44,83,84,65,82,84,61,48,120,48,10,99,46,78,70,58,67,79,76,76,69,67,84,61,48,120,56,48,44,70,82,69,69,61,48,120,49,48,44,70,82,69,69,95,79,78,95,85,78,76,79,67,75,61,48,120,56,44,73,78,73,84,73,65,76,73,83,69,68,61,48,120,50,44,76,79,67,65,76,61,48,120,52,44,77,69,83,83,65,71,69,61,48,120,50,48,48,44,78,65,77,69,61,48,120,56,48,48,48,48,48,48,48,44,80,82,73,86,65,84,69,61,48,120,48,44,82,69,67,76,65,83,83,69,68,61,48,120,49,48,48,44,83,73,71,78,65,76,76,69,68,61,48,120,52,48,48,44,83,85,80,80,82,69,83,83,95,76,79,71,61,48,120,52,48,44,84,73,77,69,82,95,83,85,66,61,48,120,50,48,44,85,78,73,81,85,69,61,48,120,52,48,48,48,48,48,48,48,44,85,78,84,82,65,67,75,69,68,61,48,120,49,10,99,46,79,80,70,58,65,82,71,83,61,48,120,52,48,44,68,69,84,65,73,76,61,48,120,52,44,69,82,82,79,82,61,48,120,56,48,44,77,65,88,95,68,69,80,84,72,61,48,120,50,44,77,79,68,85,76,69,95,80,65,84,72,61,48,120,52,48,48,44,79,80,84,73,79,78,83,61,48,120,49,44,80,82,73,86,73,76,69,71,69,68,61,48,120,49,48,48,44,82,79,79,84,95,80,65,84,72,61,48,120,56,48,48,44,83,67,65,78,95,77,79,68,85,76,69,83,61,48,120,49,48,48,48,44,83,72,79,87,95,69,82,82,79,82,83,61,48,120,50,48,44,83,72,79,87,95,73,79,61,48,120,49,48,44,83,72,79,87,95,77,69,77,79,82,89,61,48,120,56,44,83,89,83,84,69,77,95,80,65,84,72,61,48,120,50,48,48,10,99,46,80,69,82,77,73,84,58,65,76,76,95,68,69,76,69,84,69,61,48,120,56,56,56,44,65,76,76,95,69,88,69,67,61,48,120,52,52,52,44,65,76,76,95,82,69,65,68,61,48,120,49,49,49,44,65,76,76,95,87,82,73,84,69,61,48,120,50,50,50,44,65,82,67,72,73,86,69,61,48,120,50,48,48,48,44,68,69,76,69,84,69,61,48,120,56,44,69,86,69,82,89,79,78,69,95,65,67,67,69,83,83,61,48,120,102,102,102,44,69,86,69,82,89,79,78,69,95,68,69,76,69,84,69,61,48,120,56,56,56,44,69,86,69,82,89,79,78,69,95,69,88,69,67,61,48,120,52,52,52,44,69,86,69,82,89,79,78,69,95,82,69,65,68,61,48,120,49,49,49,44,69,86,69,82,89,79,78,69,95,82,69,65,68,87,82,73,84,69,61,48,120,51,51,51,44,69,86,69,82,89,79,78,69,95,87,82,73,84,69,61,48,120,50,50,50,44,69,88,69,67,61,48,120,52,44,71,82,79,85,80,61,48,120,102,48,44,71,82,79,85,80,73,68,61,48,120,49,48,48,48,48,44,71,82,79,85,80,95,68,69,76,69,84,69,61,48,120,56,48,44,71,82,79,85,80,95,69,88,69,67,61,48,120,52,48,44,71,82,79,85,80,95,82,69,65,68,61,48,120,49,48,44,71,82,79,85,80,95,87,82,73,84,69,61,48,120,50,48,44,72,73,68,68,69,78,61,48,120,49,48,48,48,44,73,78,72,69,82,73,84,61,48,120,50,48,48,48,48,44,78,69,84,87,79,82,75,61,48,120,56,48,48,48,48,44,79,70,70,76,73,78,69,61,48,120,52,48,48,48,48,44,79,84,72,69,82,83,61,48,120,102,48,48,44,79,84,72,69,82,83,95,68,69,76,69,84,69,61,48,120,56,48,48,44,79,84,72,69,82,83,95,69,88,69,67,61,48,120,52,48,48,44,79,84,72,69,82,83,95,82,69,65,68,61,48,120,49,48,48,44,79,84,72,69,82,83,95,87,82,73,84,69,61,48,120,50,48,48,44,80,65,83,83,87,79,82,68,61,48,120,52,48,48,48,44,82,69,65,68,61,48,120,49,44,85,83,69,82,61,48,120,102,44,85,83,69,82,73,68,61,48,120,56,48,48,48,44,85,83,69,82,95,69,88,69,67,61,48,120,52,44,85,83,69,82,95,82,69,65,68,61,48,120,49,44,85,83,69,82,95,87,82,73,84,69,61,48,120,50,44,87,82,73,84,69,61,48,120,50,10,99,46,80,77,70,58,83,89,83,84,69,77,95,78,79,95,66,82,69,65,75,61,48,120,49,10,99,46,80,84,67,58,67,82,79,83,83,72,65,73,82,61,48,120,97,44,67,85,83,84,79,77,61,48,120,49,55,44,68,69,70,65,85,76,84,61,48,120,49,44,68,82,65,71,71,65,66,76,69,61,48,120,49,56,44,69,78,68,61,48,120,49,57,44,72,65,78,68,61,48,120,49,48,44,72,65,78,68,95,76,69,70,84,61,48,120,49,49,44,72,65,78,68,95,82,73,71,72,84,61,48,120,49,50,44,73,78,86,73,83,73,66,76,69,61,48,120,49,54,44,77,65,71,78,73,70,73,69,82,61,48,120,102,44,78,79,95,67,72,65,78,71,69,61,48,120,48,44,80,65,73,78,84,66,82,85,83,72,61,48,120,49,52,44,83,73,90,69,95,66,79,84,84,79,77,61,48,120,57,44,83,73,90,69,95,66,79,84,84,79,77,95,76,69,70,84,61,48,120,50,44,83,73,90,69,95,66,79,84,84,79,77,95,82,73,71,72,84,61,48,120,51,44,83,73,90,69,95,76,69,70,84,61,48,120,54,44,83,73,90,69,95,82,73,71,72,84,61,48,120,55,44,83,73,90,69,95,84,79,80,61,48,120,56,44,83,73,90,69,95,84,79,80,95,76,69,70,84,61,48,120,52,44,83,73,90,69,95,84,79,80,95,82,73,71,72,84,61,48,120,53,44,83,73,90,73,78,71,61,48,120,99,44,83,76,69,69,80,61,48,120,98,44,83,80,76,73,84,95,72,79,82,73,90,79,78,84,65,76,61,48,120,101,44,83,80,76,73,84,95,86,69,82,84,73,67,65,76,61,48,120,100,44,83,84,79,80,61,48,120,49,53,44,84,69,88,84,61,48,120,49,51,10,99,46,82,68,70,58,65,82,67,72,73,86,69,61,48,120,50,48,48,48,44,68,65,84,69,61,48,120,50,44,70,73,76,69,61,48,120,56,44,70,73,76,69,83,61,48,120,56,44,70,79,76,68,69,82,61,48,120,49,48,44,70,79,76,68,69,82,83,61,48,120,49,48,44,72,73,68,68,69,78,61,48,120,49,48,48,44,76,73,78,75,61,48,120,52,48,44,79,80,69,78,68,73,82,61,48,120,52,48,48,48,44,80,69,82,77,73,83,83,73,79,78,83,61,48,120,52,44,81,85,65,76,73,70,73,69,68,61,48,120,50,48,48,44,81,85,65,76,73,70,89,61,48,120,50,48,48,44,82,69,65,68,95,65,76,76,61,48,120,49,102,44,82,69,65,68,95,79,78,76,89,61,48,120,49,48,48,48,44,83,73,90,69,61,48,120,49,44,83,84,82,69,65,77,61,48,120,56,48,48,44,84,65,71,83,61,48,120,56,48,44,84,73,77,69,61,48,120,50,44,86,73,82,84,85,65,76,61,48,120,52,48,48,44,86,79,76,85,77,69,61,48,120,50,48,10,99,46,82,69,83,58,67,79,78,83,79,76,69,95,70,68,61,48,120,50,44,67,79,82,69,95,73,68,76,61,48,120,56,44,67,80,85,95,83,80,69,69,68,61,48,120,49,54,44,68,73,83,80,76,65,89,95,68,82,73,86,69,82,61,48,120,53,44,69,88,67,69,80,84,73,79,78,95,72,65,78,68,76,69,82,61,48,120,49,49,44,70,82,69,69,95,77,69,77,79,82,89,61,48,120,49,55,44,70,82,69,69,95,83,87,65,80,61,48,120,49,44,74,78,73,95,69,78,86,61,48,120,101,44,75,69,89,95,83,84,65,84,69,61,48,120,51,44,76,79,71,95,68,69,80,84,72,61,48,120,100,44,76,79,71,95,76,69,86,69,76,61,48,120,97,44,77,65,88,95,80,82,79,67,69,83,83,69,83,61,48,120,99,44,78,69,84,95,80,82,79,67,69,83,83,73,78,71,61,48,120,49,50,44,79,80,69,78,95,73,78,70,79,61,48,120,49,48,44,80,82,73,86,73,76,69,71,69,68,61,48,120,55,44,80,82,73,86,73,76,69,71,69,68,95,85,83,69,82,61,48,120,54,44,80,82,79,67,69,83,83,95,83,84,65,84,69,61,48,120,49,51,44,83,84,65,84,73,67,95,66,85,73,76,68,61,48,120,57,44,84,72,82,69,65,68,95,73,68,61,48,120,102,44,84,79,84,65,76,95,77,69,77,79,82,89,61,48,120,49,52,44,84,79,84,65,76,95,83,72,65,82,69,68,95,77,69,77,79,82,89,61,48,120,98,44,84,79,84,65,76,95,83,87,65,80,61,48,120,49,53,44,85,83,69,82,95,73,68,61,48,120,52,10,99,46,82,70,68,58,65,76,76,79,87,95,82,69,67,85,82,83,73,79,78,61,48,120,50,48,44,65,76,87,65,89,83,95,67,65,76,76,61,48,120,49,48,48,44,69,88,67,69,80,84,61,48,120,50,44,82,69,65,68,61,48,120,52,44,82,69,67,65,76,76,61,48,120,56,48,44,82,69,77,79,86,69,61,48,120,56,44,83,79,67,75,69,84,61,48,120,52,48,44,83,84,79,80,95,82,69,67,85,82,83,69,61,48,120,49,48,44,87,82,73,84,69,61,48,120,49,10,99,46,82,80,58,77,79,68,85,76,69,95,80,65,84,72,61,48,120,49,44,82,79,79,84,95,80,65,84,72,61,48,120,51,44,83,89,83,84,69,77,95,80,65,84,72,61,48,120,50,10,99,46,82,83,70,58,65,80,80,82,79,88,73,77,65,84,69,61,48,120,52,44,67,65,83,69,95,83,69,78,83,73,84,73,86,69,61,48,120,50,48,44,67,72,69,67,75,95,86,73,82,84,85,65,76,61,48,120,50,44,78,79,95,68,69,69,80,95,83,67,65,78,61,48,120,56,44,78,79,95,70,73,76,69,95,67,72,69,67,75,61,48,120,49,44,80,65,84,72,61,48,120,49,48,10,99,46,83,67,70,58,69,88,73,84,95,79,78,95,69,82,82,79,82,61,48,120,49,44,76,79,71,95,65,76,76,61,48,120,50,10,99,46,83,69,69,75,58,67,85,82,82,69,78,84,61,48,120,49,44,69,78,68,61,48,120,50,44,82,69,76,65,84,73,86,69,61,48,120,51,44,83,84,65,82,84,61,48,120,48,10,99,46,83,84,82,58,67,65,83,69,61,48,120,49,44,77,65,84,67,72,95,67,65,83,69,61,48,120,49,44,77,65,84,67,72,95,76,69,78,61,48,120,50,10,99,46,83,84,84,58,70,76,79,65,84,61,48,120,50,44,72,69,88,61,48,120,51,44,78,85,77,66,69,82,61,48,120,49,44,83,84,82,73,78,71,61,48,120,52,10,99,46,84,72,70,58,65,85,84,79,95,70,82,69,69,61,48,120,49,10,99,46,84,79,73,58,65,78,68,82,79,73,68,95,65,83,83,69,84,77,71,82,61,48,120,52,44,65,78,68,82,79,73,68,95,67,76,65,83,83,61,48,120,51,44,65,78,68,82,79,73,68,95,69,78,86,61,48,120,50,44,76,79,67,65,76,95,67,65,67,72,69,61,48,120,48,44,76,79,67,65,76,95,83,84,79,82,65,71,69,61,48,120,49,10,99,46,84,83,70,58,65,84,84,65,67,72,69,68,61,48,120,49,48,48,44,68,69,84,65,67,72,69,68,61,48,120,56,48,44,70,79,82,69,73,71,78,61,48,120,49,44,76,79,71,95,65,76,76,61,48,120,50,48,44,80,73,80,69,61,48,120,50,48,48,44,80,82,73,86,73,76,69,71,69,68,61,48,120,56,44,81,85,73,69,84,61,48,120,52,48,44,82,69,83,69,84,95,80,65,84,72,61,48,120,52,44,83,72,69,76,76,61,48,120,49,48,44,87,65,73,84,61,48,120,50,10,99,46,84,83,84,65,84,69,58,80,65,85,83,69,68,61,48,120,49,44,82,85,78,78,73,78,71,61,48,120,48,44,83,84,79,80,80,73,78,71,61,48,120,50,44,84,69,82,77,73,78,65,84,69,68,61,48,120,51,10,99,46,86,65,83,58,67,65,83,69,95,83,69,78,83,73,84,73,86,69,61,48,120,102,44,67,76,79,83,69,95,68,73,82,61,48,120,54,44,67,82,69,65,84,69,95,76,73,78,75,61,48,120,49,49,44,68,69,76,69,84,69,61,48,120,51,44,68,69,82,69,71,73,83,84,69,82,61,48,120,49,44,68,82,73,86,69,82,95,83,73,90,69,61,48,120,49,50,44,71,69,84,95,68,69,86,73,67,69,95,73,78,70,79,61,48,120,98,44,71,69,84,95,73,78,70,79,61,48,120,97,44,73,68,69,78,84,73,70,89,95,70,73,76,69,61,48,120,99,44,73,71,78,79,82,69,95,70,73,76,69,61,48,120,57,44,77,65,75,69,95,68,73,82,61,48,120,100,44,79,80,69,78,95,68,73,82,61,48,120,53,44,82,69,65,68,95,76,73,78,75,61,48,120,49,48,44,82,69,78,65,77,69,61,48,120,52,44,83,65,77,69,95,70,73,76,69,61,48,120,101,44,83,67,65,78,95,68,73,82,61,48,120,50,44,84,69,83,84,95,80,65,84,72,61,48,120,55,44,87,65,84,67,72,95,80,65,84,72,61,48,120,56,10,99,46,86,76,70,58,65,80,73,61,48,120,50,48,44,66,82,65,78,67,72,61,48,120,49,44,67,82,73,84,73,67,65,76,61,48,120,56,44,68,69,84,65,73,76,61,48,120,52,48,44,69,82,82,79,82,61,48,120,50,44,70,85,78,67,84,73,79,78,61,48,120,49,48,48,44,73,78,70,79,61,48,120,49,48,44,84,82,65,67,69,61,48,120,56,48,44,87,65,82,78,73,78,71,61,48,120,52,10,99,46,86,79,76,85,77,69,58,72,73,68,68,69,78,61,48,120,52,44,80,82,73,79,82,73,84,89,61,48,120,50,44,82,69,80,76,65,67,69,61,48,120,49,44,83,89,83,84,69,77,61,48,120,56,10,0 }; +char glIDL[] = { 115,46,73,110,112,117,116,69,118,101,110,116,58,112,78,101,120,116,58,73,110,112,117,116,69,118,101,110,116,44,100,86,97,108,117,101,44,120,84,105,109,101,115,116,97,109,112,44,108,82,101,99,105,112,105,101,110,116,73,68,44,108,79,118,101,114,73,68,44,100,65,98,115,88,44,100,65,98,115,89,44,100,88,44,100,89,44,108,68,101,118,105,99,101,73,68,44,108,84,121,112,101,44,108,70,108,97,103,115,44,108,77,97,115,107,10,115,46,100,99,82,101,113,117,101,115,116,58,108,73,116,101,109,44,99,80,114,101,102,101,114,101,110,99,101,91,52,93,10,115,46,100,99,65,117,100,105,111,58,108,83,105,122,101,44,108,70,111,114,109,97,116,10,115,46,100,99,75,101,121,69,110,116,114,121,58,108,70,108,97,103,115,44,108,86,97,108,117,101,44,120,84,105,109,101,115,116,97,109,112,44,108,85,110,105,99,111,100,101,10,115,46,100,99,68,101,118,105,99,101,73,110,112,117,116,58,100,86,97,108,117,101,115,91,50,93,44,120,84,105,109,101,115,116,97,109,112,44,108,68,101,118,105,99,101,73,68,44,108,70,108,97,103,115,44,108,84,121,112,101,10,115,46,68,97,116,101,84,105,109,101,58,119,89,101,97,114,44,99,77,111,110,116,104,44,99,68,97,121,44,99,72,111,117,114,44,99,77,105,110,117,116,101,44,99,83,101,99,111,110,100,44,99,84,105,109,101,90,111,110,101,10,115,46,72,83,86,58,100,72,117,101,44,100,83,97,116,117,114,97,116,105,111,110,44,100,86,97,108,117,101,44,100,65,108,112,104,97,10,115,46,70,82,71,66,58,102,82,101,100,44,102,71,114,101,101,110,44,102,66,108,117,101,44,102,65,108,112,104,97,10,115,46,82,71,66,56,58,117,99,82,101,100,44,117,99,71,114,101,101,110,44,117,99,66,108,117,101,44,117,99,65,108,112,104,97,10,115,46,82,71,66,49,54,58,117,119,82,101,100,44,117,119,71,114,101,101,110,44,117,119,66,108,117,101,44,117,119,65,108,112,104,97,10,115,46,82,71,66,51,50,58,117,108,82,101,100,44,117,108,71,114,101,101,110,44,117,108,66,108,117,101,44,117,108,65,108,112,104,97,10,115,46,82,71,66,80,97,108,101,116,116,101,58,108,65,109,116,67,111,108,111,117,114,115,44,101,67,111,108,58,82,71,66,56,91,50,53,54,93,10,115,46,67,111,108,111,117,114,70,111,114,109,97,116,58,117,99,82,101,100,83,104,105,102,116,44,117,99,71,114,101,101,110,83,104,105,102,116,44,117,99,66,108,117,101,83,104,105,102,116,44,117,99,65,108,112,104,97,83,104,105,102,116,44,117,99,82,101,100,77,97,115,107,44,117,99,71,114,101,101,110,77,97,115,107,44,117,99,66,108,117,101,77,97,115,107,44,117,99,65,108,112,104,97,77,97,115,107,44,117,99,82,101,100,80,111,115,44,117,99,71,114,101,101,110,80,111,115,44,117,99,66,108,117,101,80,111,115,44,117,99,65,108,112,104,97,80,111,115,44,117,99,66,105,116,115,80,101,114,80,105,120,101,108,10,115,46,67,108,105,112,82,101,99,116,97,110,103,108,101,58,108,76,101,102,116,44,108,84,111,112,44,108,82,105,103,104,116,44,108,66,111,116,116,111,109,10,115,46,69,100,103,101,115,58,108,76,101,102,116,44,108,84,111,112,44,108,82,105,103,104,116,44,108,66,111,116,116,111,109,10,115,46,79,98,106,101,99,116,83,105,103,110,97,108,58,111,79,98,106,101,99,116,10,115,46,70,117,110,99,116,105,111,110,70,105,101,108,100,58,115,78,97,109,101,44,117,108,84,121,112,101,10,115,46,70,117,110,99,116,105,111,110,58,112,65,100,100,114,101,115,115,44,115,78,97,109,101,44,112,65,114,103,115,58,70,117,110,99,116,105,111,110,70,105,101,108,100,10,115,46,70,105,101,108,100,65,114,114,97,121,58,115,78,97,109,101,44,112,71,101,116,70,105,101,108,100,44,112,83,101,116,70,105,101,108,100,44,109,65,114,103,44,117,108,70,108,97,103,115,10,115,46,70,105,101,108,100,68,101,102,58,115,78,97,109,101,44,108,86,97,108,117,101,10,115,46,83,121,115,116,101,109,83,116,97,116,101,58,115,80,108,97,116,102,111,114,109,44,108,67,111,110,115,111,108,101,70,68,44,108,83,116,97,103,101,10,115,46,85,110,105,116,58,100,86,97,108,117,101,44,117,108,84,121,112,101,10,115,46,65,99,116,105,111,110,65,114,114,97,121,58,112,82,111,117,116,105,110,101,44,108,65,99,116,105,111,110,67,111,100,101,10,115,46,65,99,116,105,111,110,84,97,98,108,101,58,117,108,72,97,115,104,44,108,83,105,122,101,44,115,78,97,109,101,44,112,65,114,103,115,58,70,117,110,99,116,105,111,110,70,105,101,108,100,10,115,46,67,104,105,108,100,69,110,116,114,121,58,108,79,98,106,101,99,116,73,68,44,117,108,67,108,97,115,115,73,68,10,115,46,77,101,115,115,97,103,101,58,120,84,105,109,101,44,108,85,73,68,44,108,84,121,112,101,44,108,83,105,122,101,10,115,46,77,101,109,73,110,102,111,58,112,83,116,97,114,116,44,108,79,98,106,101,99,116,73,68,44,117,108,83,105,122,101,44,108,70,108,97,103,115,44,108,77,101,109,111,114,121,73,68,44,119,65,99,99,101,115,115,67,111,117,110,116,10,115,46,67,111,109,112,114,101,115,115,105,111,110,70,101,101,100,98,97,99,107,58,108,70,101,101,100,98,97,99,107,73,68,44,108,73,110,100,101,120,44,115,80,97,116,104,44,115,68,101,115,116,44,120,80,114,111,103,114,101,115,115,44,120,79,114,105,103,105,110,97,108,83,105,122,101,44,120,67,111,109,112,114,101,115,115,101,100,83,105,122,101,44,119,89,101,97,114,44,119,77,111,110,116,104,44,119,68,97,121,44,119,72,111,117,114,44,119,77,105,110,117,116,101,44,119,83,101,99,111,110,100,10,115,46,67,111,109,112,114,101,115,115,101,100,73,116,101,109,58,120,79,114,105,103,105,110,97,108,83,105,122,101,44,120,67,111,109,112,114,101,115,115,101,100,83,105,122,101,44,112,78,101,120,116,58,67,111,109,112,114,101,115,115,101,100,73,116,101,109,44,115,80,97,116,104,44,108,80,101,114,109,105,115,115,105,111,110,115,44,108,85,115,101,114,73,68,44,108,71,114,111,117,112,73,68,44,108,79,116,104,101,114,115,73,68,44,108,70,108,97,103,115,44,101,67,114,101,97,116,101,100,58,68,97,116,101,84,105,109,101,44,101,77,111,100,105,102,105,101,100,58,68,97,116,101,84,105,109,101,10,115,46,70,105,108,101,73,110,102,111,58,120,83,105,122,101,44,120,84,105,109,101,83,116,97,109,112,44,112,78,101,120,116,58,70,105,108,101,73,110,102,111,44,115,78,97,109,101,44,108,70,108,97,103,115,44,108,80,101,114,109,105,115,115,105,111,110,115,44,108,85,115,101,114,73,68,44,108,71,114,111,117,112,73,68,44,101,67,114,101,97,116,101,100,58,68,97,116,101,84,105,109,101,44,101,77,111,100,105,102,105,101,100,58,68,97,116,101,84,105,109,101,10,115,46,68,105,114,73,110,102,111,58,112,73,110,102,111,58,70,105,108,101,73,110,102,111,10,115,46,70,105,108,101,70,101,101,100,98,97,99,107,58,120,83,105,122,101,44,120,80,111,115,105,116,105,111,110,44,115,80,97,116,104,44,115,68,101,115,116,44,108,70,101,101,100,98,97,99,107,73,68,44,99,82,101,115,101,114,118,101,100,91,51,50,93,10,115,46,70,105,101,108,100,58,109,65,114,103,44,112,71,101,116,86,97,108,117,101,44,112,83,101,116,86,97,108,117,101,44,112,87,114,105,116,101,86,97,108,117,101,44,115,78,97,109,101,44,117,108,70,105,101,108,100,73,68,44,117,119,79,102,102,115,101,116,44,117,119,73,110,100,101,120,44,117,108,70,108,97,103,115,10,99,46,65,67,58,65,99,116,105,118,97,116,101,61,48,120,50,44,67,108,101,97,114,61,48,120,52,44,67,108,105,112,98,111,97,114,100,61,48,120,50,100,44,67,111,112,121,68,97,116,97,61,48,120,55,44,68,97,116,97,70,101,101,100,61,48,120,56,44,68,101,97,99,116,105,118,97,116,101,61,48,120,57,44,68,105,115,97,98,108,101,61,48,120,50,102,44,68,114,97,103,68,114,111,112,61,48,120,49,48,44,68,114,97,119,61,48,120,97,44,69,78,68,61,48,120,51,49,44,69,110,97,98,108,101,61,48,120,54,44,70,108,117,115,104,61,48,120,98,44,70,111,99,117,115,61,48,120,99,44,70,114,101,101,61,48,120,100,44,70,114,101,101,87,97,114,110,105,110,103,61,48,120,53,44,71,101,116,75,101,121,61,48,120,102,44,72,105,100,101,61,48,120,49,49,44,73,110,105,116,61,48,120,49,50,44,76,111,99,107,61,48,120,49,51,44,76,111,115,116,70,111,99,117,115,61,48,120,49,52,44,77,111,118,101,61,48,120,49,53,44,77,111,118,101,84,111,66,97,99,107,61,48,120,49,54,44,77,111,118,101,84,111,70,114,111,110,116,61,48,120,49,55,44,77,111,118,101,84,111,80,111,105,110,116,61,48,120,50,51,44,78,101,119,67,104,105,108,100,61,48,120,49,56,44,78,101,119,79,98,106,101,99,116,61,48,120,49,97,44,78,101,119,79,119,110,101,114,61,48,120,49,57,44,78,101,119,80,108,97,99,101,109,101,110,116,61,48,120,51,48,44,78,101,120,116,61,48,120,50,57,44,80,114,101,118,61,48,120,50,97,44,81,117,101,114,121,61,48,120,49,99,44,82,101,97,100,61,48,120,49,100,44,82,101,100,105,109,101,110,115,105,111,110,61,48,120,51,44,82,101,100,111,61,48,120,49,98,44,82,101,102,114,101,115,104,61,48,120,50,101,44,82,101,110,97,109,101,61,48,120,49,101,44,82,101,115,101,116,61,48,120,49,102,44,82,101,115,105,122,101,61,48,120,50,48,44,83,97,118,101,73,109,97,103,101,61,48,120,50,49,44,83,97,118,101,83,101,116,116,105,110,103,115,61,48,120,101,44,83,97,118,101,84,111,79,98,106,101,99,116,61,48,120,50,50,44,83,101,101,107,61,48,120,50,52,44,83,101,116,70,105,101,108,100,61,48,120,50,99,44,83,101,116,75,101,121,61,48,120,50,53,44,83,104,111,119,61,48,120,50,54,44,83,105,103,110,97,108,61,48,120,49,44,85,110,100,111,61,48,120,50,55,44,85,110,108,111,99,107,61,48,120,50,56,44,87,114,105,116,101,61,48,120,50,98,10,99,46,65,76,73,71,78,58,66,79,84,84,79,77,61,48,120,50,48,44,67,69,78,84,69,82,61,48,120,99,44,72,79,82,73,90,79,78,84,65,76,61,48,120,52,44,76,69,70,84,61,48,120,49,44,77,73,68,68,76,69,61,48,120,99,44,82,73,71,72,84,61,48,120,50,44,84,79,80,61,48,120,49,48,44,86,69,82,84,73,67,65,76,61,48,120,56,10,99,46,67,67,70,58,65,85,68,73,79,61,48,120,56,48,44,67,79,77,77,65,78,68,61,48,120,49,44,68,65,84,65,61,48,120,49,48,48,44,70,73,76,69,83,89,83,84,69,77,61,48,120,50,44,71,82,65,80,72,73,67,83,61,48,120,52,44,71,85,73,61,48,120,56,44,73,79,61,48,120,49,48,44,77,73,83,67,61,48,120,50,48,48,44,77,85,76,84,73,77,69,68,73,65,61,48,120,56,48,48,44,78,69,84,87,79,82,75,61,48,120,52,48,48,44,83,89,83,84,69,77,61,48,120,50,48,44,84,79,79,76,61,48,120,52,48,10,99,46,67,70,58,68,69,70,76,65,84,69,61,48,120,51,44,71,90,73,80,61,48,120,49,44,90,76,73,66,61,48,120,50,10,99,46,67,76,70,58,73,78,72,69,82,73,84,95,76,79,67,65,76,61,48,120,49,44,78,79,95,79,87,78,69,82,83,72,73,80,61,48,120,50,10,99,46,67,76,73,80,77,79,68,69,58,67,79,80,89,61,48,120,50,44,67,85,84,61,48,120,49,44,80,65,83,84,69,61,48,120,52,10,99,46,67,77,70,58,65,80,80,76,89,95,83,69,67,85,82,73,84,89,61,48,120,50,48,44,67,82,69,65,84,69,95,70,73,76,69,61,48,120,52,44,78,69,87,61,48,120,50,44,78,79,95,76,73,78,75,83,61,48,120,49,48,44,80,65,83,83,87,79,82,68,61,48,120,49,44,82,69,65,68,95,79,78,76,89,61,48,120,56,10,99,46,67,78,70,58,65,85,84,79,95,83,65,86,69,61,48,120,50,44,78,69,87,61,48,120,56,44,79,80,84,73,79,78,65,76,95,70,73,76,69,83,61,48,120,52,44,83,84,82,73,80,95,81,85,79,84,69,83,61,48,120,49,10,99,46,67,79,78,58,68,80,65,68,95,68,79,87,78,61,48,120,50,48,44,68,80,65,68,95,76,69,70,84,61,48,120,52,48,44,68,80,65,68,95,82,73,71,72,84,61,48,120,56,48,44,68,80,65,68,95,85,80,61,48,120,49,48,44,71,65,77,69,80,65,68,95,69,61,48,120,50,44,71,65,77,69,80,65,68,95,78,61,48,120,56,44,71,65,77,69,80,65,68,95,83,61,48,120,49,44,71,65,77,69,80,65,68,95,87,61,48,120,52,44,76,69,70,84,95,66,85,77,80,69,82,95,49,61,48,120,52,48,48,44,76,69,70,84,95,66,85,77,80,69,82,95,50,61,48,120,56,48,48,44,76,69,70,84,95,84,72,85,77,66,61,48,120,52,48,48,48,44,82,73,71,72,84,95,66,85,77,80,69,82,95,49,61,48,120,49,48,48,48,44,82,73,71,72,84,95,66,85,77,80,69,82,95,50,61,48,120,50,48,48,48,44,82,73,71,72,84,95,84,72,85,77,66,61,48,120,56,48,48,48,44,83,69,76,69,67,84,61,48,120,50,48,48,44,83,84,65,82,84,61,48,120,49,48,48,10,99,46,68,65,84,65,58,65,85,68,73,79,61,48,120,53,44,67,79,78,84,69,78,84,61,48,120,98,44,68,69,86,73,67,69,95,73,78,80,85,84,61,48,120,51,44,70,73,76,69,61,48,120,97,44,73,77,65,71,69,61,48,120,55,44,73,78,80,85,84,95,82,69,65,68,89,61,48,120,99,44,82,65,87,61,48,120,50,44,82,69,67,69,73,80,84,61,48,120,57,44,82,69,67,79,82,68,61,48,120,54,44,82,69,81,85,69,83,84,61,48,120,56,44,84,69,88,84,61,48,120,49,44,88,77,76,61,48,120,52,10,99,46,68,69,86,73,67,69,58,66,79,79,75,77,65,82,75,61,48,120,52,48,48,48,48,44,67,79,77,80,65,67,84,95,68,73,83,67,61,48,120,49,44,70,73,88,69,68,61,48,120,56,48,48,48,44,70,76,79,80,80,89,95,68,73,83,75,61,48,120,52,44,72,65,82,68,95,68,73,83,75,61,48,120,50,44,77,69,77,79,82,89,61,48,120,49,48,48,48,44,77,79,68,69,77,61,48,120,50,48,48,48,44,78,69,84,87,79,82,75,61,48,120,56,48,44,80,82,73,78,84,69,82,61,48,120,50,48,48,44,80,82,73,78,84,69,82,95,51,68,61,48,120,49,48,48,48,48,44,82,69,65,68,61,48,120,56,44,82,69,77,79,86,65,66,76,69,61,48,120,50,48,44,82,69,77,79,86,69,65,66,76,69,61,48,120,50,48,44,83,67,65,78,78,69,82,61,48,120,52,48,48,44,83,67,65,78,78,69,82,95,51,68,61,48,120,50,48,48,48,48,44,83,79,70,84,87,65,82,69,61,48,120,52,48,44,84,65,80,69,61,48,120,49,48,48,44,84,69,77,80,79,82,65,82,89,61,48,120,56,48,48,44,85,83,66,61,48,120,52,48,48,48,44,87,82,73,84,69,61,48,120,49,48,10,99,46,68,77,70,58,70,73,88,69,68,95,67,69,78,84,69,82,95,88,61,48,120,49,48,48,48,48,48,44,70,73,88,69,68,95,67,69,78,84,69,82,95,89,61,48,120,50,48,48,48,48,48,44,70,73,88,69,68,95,68,69,80,84,72,61,48,120,49,48,48,48,44,70,73,88,69,68,95,72,69,73,71,72,84,61,48,120,49,48,48,44,70,73,88,69,68,95,82,65,68,73,85,83,95,88,61,48,120,50,48,48,48,48,44,70,73,88,69,68,95,82,65,68,73,85,83,95,89,61,48,120,50,48,48,48,48,48,48,44,70,73,88,69,68,95,87,73,68,84,72,61,48,120,50,48,48,44,70,73,88,69,68,95,88,61,48,120,52,44,70,73,88,69,68,95,88,95,79,70,70,83,69,84,61,48,120,52,48,44,70,73,88,69,68,95,89,61,48,120,56,44,70,73,88,69,68,95,89,95,79,70,70,83,69,84,61,48,120,56,48,44,70,73,88,69,68,95,90,61,48,120,52,48,48,48,44,83,67,65,76,69,68,95,67,69,78,84,69,82,95,88,61,48,120,52,48,48,48,48,44,83,67,65,76,69,68,95,67,69,78,84,69,82,95,89,61,48,120,56,48,48,48,48,44,83,67,65,76,69,68,95,68,69,80,84,72,61,48,120,50,48,48,48,44,83,67,65,76,69,68,95,72,69,73,71,72,84,61,48,120,52,48,48,44,83,67,65,76,69,68,95,82,65,68,73,85,83,95,88,61,48,120,49,48,48,48,48,44,83,67,65,76,69,68,95,82,65,68,73,85,83,95,89,61,48,120,49,48,48,48,48,48,48,44,83,67,65,76,69,68,95,87,73,68,84,72,61,48,120,56,48,48,44,83,67,65,76,69,68,95,88,61,48,120,49,44,83,67,65,76,69,68,95,88,95,79,70,70,83,69,84,61,48,120,49,48,44,83,67,65,76,69,68,95,89,61,48,120,50,44,83,67,65,76,69,68,95,89,95,79,70,70,83,69,84,61,48,120,50,48,44,83,67,65,76,69,68,95,90,61,48,120,56,48,48,48,44,83,84,65,84,85,83,95,67,72,65,78,71,69,95,72,61,48,120,52,48,48,48,48,48,44,83,84,65,84,85,83,95,67,72,65,78,71,69,95,86,61,48,120,56,48,48,48,48,48,10,99,46,68,82,76,58,68,79,87,78,61,48,120,49,44,69,65,83,84,61,48,120,50,44,76,69,70,84,61,48,120,51,44,78,79,82,84,72,61,48,120,48,44,78,79,82,84,72,95,69,65,83,84,61,48,120,52,44,78,79,82,84,72,95,87,69,83,84,61,48,120,53,44,82,73,71,72,84,61,48,120,50,44,83,79,85,84,72,61,48,120,49,44,83,79,85,84,72,95,69,65,83,84,61,48,120,54,44,83,79,85,84,72,95,87,69,83,84,61,48,120,55,44,85,80,61,48,120,48,44,87,69,83,84,61,48,120,51,10,99,46,69,68,71,69,58,65,76,76,61,48,120,102,102,44,66,79,84,84,79,77,61,48,120,56,44,66,79,84,84,79,77,95,76,69,70,84,61,48,120,52,48,44,66,79,84,84,79,77,95,82,73,71,72,84,61,48,120,56,48,44,76,69,70,84,61,48,120,50,44,82,73,71,72,84,61,48,120,52,44,84,79,80,61,48,120,49,44,84,79,80,95,76,69,70,84,61,48,120,49,48,44,84,79,80,95,82,73,71,72,84,61,48,120,50,48,10,99,46,69,82,70,58,78,111,116,105,102,105,101,100,61,48,120,52,48,48,48,48,48,48,48,10,99,46,69,82,82,58,65,99,99,101,115,115,77,101,109,111,114,121,61,48,120,52,98,44,65,99,99,101,115,115,79,98,106,101,99,116,61,48,120,53,51,44,65,99,99,101,115,115,83,101,109,97,112,104,111,114,101,61,48,120,55,51,44,65,99,116,105,118,97,116,101,61,48,120,52,50,44,65,100,100,67,108,97,115,115,61,48,120,52,49,44,65,108,108,111,99,77,101,109,111,114,121,61,48,120,53,52,44,65,108,108,111,99,83,101,109,97,112,104,111,114,101,61,48,120,55,50,44,65,108,114,101,97,100,121,68,101,102,105,110,101,100,61,48,120,98,54,44,65,108,114,101,97,100,121,76,111,99,107,101,100,61,48,120,57,99,44,65,114,103,115,61,48,120,49,52,44,65,114,114,97,121,70,117,108,108,61,48,120,50,100,44,66,117,102,102,101,114,79,118,101,114,102,108,111,119,61,48,120,53,99,44,66,117,115,121,61,48,120,56,98,44,67,97,110,99,101,108,108,101,100,61,48,120,51,44,67,97,114,100,82,101,97,100,101,114,85,110,97,118,97,105,108,97,98,108,101,61,48,120,57,102,44,67,97,114,100,82,101,97,100,101,114,85,110,107,110,111,119,110,61,48,120,57,100,44,67,111,109,112,114,101,115,115,105,111,110,61,48,120,97,100,44,67,111,110,110,101,99,116,105,111,110,65,98,111,114,116,101,100,61,48,120,56,99,44,67,111,110,110,101,99,116,105,111,110,82,101,102,117,115,101,100,61,48,120,56,51,44,67,111,110,115,116,114,97,105,110,116,86,105,111,108,97,116,105,111,110,61,48,120,56,56,44,67,111,110,116,105,110,117,101,61,48,120,53,44,67,111,114,101,86,101,114,115,105,111,110,61,48,120,50,54,44,67,114,101,97,116,101,70,105,108,101,61,48,120,55,52,44,67,114,101,97,116,101,79,98,106,101,99,116,61,48,120,54,53,44,67,114,101,97,116,101,82,101,115,111,117,114,99,101,61,48,120,98,50,44,68,97,116,97,83,105,122,101,61,48,120,56,97,44,68,101,97,99,116,105,118,97,116,101,100,61,48,120,57,97,44,68,101,97,100,76,111,99,107,61,48,120,51,101,44,68,101,99,111,109,112,114,101,115,115,105,111,110,61,48,120,97,99,44,68,101,108,101,116,101,70,105,108,101,61,48,120,55,53,44,68,105,114,69,109,112,116,121,61,48,120,56,44,68,105,115,99,111,110,110,101,99,116,101,100,61,48,120,56,54,44,68,111,78,111,116,69,120,112,117,110,103,101,61,48,120,51,48,44,68,111,101,115,78,111,116,69,120,105,115,116,61,48,120,55,56,44,68,111,117,98,108,101,73,110,105,116,61,48,120,52,51,44,68,114,97,119,61,48,120,52,56,44,69,78,68,61,48,120,98,101,44,69,109,112,116,121,83,116,114,105,110,103,61,48,120,54,100,44,69,110,100,79,102,70,105,108,101,61,48,120,55,101,44,69,110,116,114,121,77,105,115,115,105,110,103,72,101,97,100,101,114,61,48,120,51,97,44,69,120,97,109,105,110,101,70,97,105,108,101,100,61,48,120,49,57,44,69,120,99,101,112,116,105,111,110,61,48,120,97,51,44,69,120,99,101,112,116,105,111,110,84,104,114,101,115,104,111,108,100,61,48,120,57,44,69,120,99,108,117,115,105,118,101,68,101,110,105,101,100,61,48,120,53,51,44,69,120,101,99,86,105,111,108,97,116,105,111,110,61,48,120,56,102,44,69,120,105,115,116,115,61,48,120,55,97,44,69,120,112,101,99,116,101,100,70,105,108,101,61,48,120,54,102,44,69,120,112,101,99,116,101,100,70,111,108,100,101,114,61,48,120,97,101,44,70,97,105,108,101,100,61,48,120,100,44,70,97,108,115,101,61,48,120,49,44,70,105,101,108,100,78,111,116,83,101,116,61,48,120,52,52,44,70,105,101,108,100,83,101,97,114,99,104,61,48,120,51,50,44,70,105,101,108,100,84,121,112,101,77,105,115,109,97,116,99,104,61,48,120,53,97,44,70,105,108,101,61,48,120,101,44,70,105,108,101,68,111,101,115,78,111,116,69,120,105,115,116,61,48,120,49,50,44,70,105,108,101,69,120,105,115,116,115,61,48,120,54,51,44,70,105,108,101,78,111,116,70,111,117,110,100,61,48,120,49,50,44,70,105,108,101,82,101,97,100,70,108,97,103,61,48,120,52,54,44,70,105,108,101,87,114,105,116,101,70,108,97,103,61,48,120,52,55,44,70,105,110,105,115,104,101,100,61,48,120,55,101,44,70,117,110,99,116,105,111,110,61,48,120,98,53,44,71,101,116,70,105,101,108,100,61,48,120,53,54,44,71,101,116,83,117,114,102,97,99,101,73,110,102,111,61,48,120,55,100,44,72,111,115,116,78,111,116,70,111,117,110,100,61,48,120,56,49,44,72,111,115,116,85,110,114,101,97,99,104,97,98,108,101,61,48,120,56,53,44,73,100,101,110,116,105,99,97,108,80,97,116,104,115,61,48,120,55,57,44,73,108,108,101,103,97,108,65,99,116,105,111,110,65,116,116,101,109,112,116,61,48,120,51,57,44,73,108,108,101,103,97,108,65,99,116,105,111,110,73,68,61,48,120,51,55,44,73,108,108,101,103,97,108,65,100,100,114,101,115,115,61,48,120,57,49,44,73,108,108,101,103,97,108,77,101,116,104,111,100,73,68,61,48,120,51,54,44,73,109,109,117,116,97,98,108,101,61,48,120,97,102,44,73,110,85,115,101,61,48,120,99,44,73,110,105,116,61,48,120,50,49,44,73,110,105,116,77,111,100,117,108,101,61,48,120,49,49,44,73,110,112,117,116,79,117,116,112,117,116,61,48,120,57,52,44,73,110,116,101,103,114,105,116,121,86,105,111,108,97,116,105,111,110,61,48,120,56,56,44,73,110,118,97,108,105,100,68,97,116,97,61,48,120,102,44,73,110,118,97,108,105,100,68,105,109,101,110,115,105,111,110,61,48,120,53,57,44,73,110,118,97,108,105,100,72,84,84,80,82,101,115,112,111,110,115,101,61,48,120,97,49,44,73,110,118,97,108,105,100,72,97,110,100,108,101,61,48,120,57,54,44,73,110,118,97,108,105,100,79,98,106,101,99,116,61,48,120,56,101,44,73,110,118,97,108,105,100,80,97,116,104,61,48,120,51,51,44,73,110,118,97,108,105,100,82,101,102,101,114,101,110,99,101,61,48,120,97,50,44,73,110,118,97,108,105,100,83,116,97,116,101,61,48,120,56,48,44,73,110,118,97,108,105,100,85,82,73,61,48,120,56,50,44,73,110,118,97,108,105,100,86,97,108,117,101,61,48,120,57,56,44,76,105,109,105,116,101,100,83,117,99,99,101,115,115,61,48,120,50,44,76,105,115,116,67,104,105,108,100,114,101,110,61,48,120,54,97,44,76,111,97,100,77,111,100,117,108,101,61,48,120,57,53,44,76,111,99,107,61,48,120,49,56,44,76,111,99,107,70,97,105,108,101,100,61,48,120,49,56,44,76,111,99,107,77,117,116,101,120,61,48,120,97,97,44,76,111,99,107,82,101,113,117,105,114,101,100,61,48,120,57,98,44,76,111,99,107,101,100,61,48,120,57,99,44,76,111,111,112,61,48,120,54,50,44,76,111,115,116,67,108,97,115,115,61,48,120,49,97,44,76,111,115,116,79,119,110,101,114,61,48,120,50,102,44,76,111,119,67,97,112,97,99,105,116,121,61,48,120,50,48,44,77,97,114,107,101,100,70,111,114,68,101,108,101,116,105,111,110,61,48,120,51,53,44,77,101,109,111,114,121,61,48,120,49,100,44,77,101,109,111,114,121,67,111,114,114,117,112,116,61,48,120,51,49,44,77,101,109,111,114,121,68,111,101,115,78,111,116,69,120,105,115,116,61,48,120,51,100,44,77,101,109,111,114,121,73,110,102,111,61,48,120,54,54,44,77,105,115,109,97,116,99,104,61,48,120,53,101,44,77,105,115,115,105,110,103,67,108,97,115,115,61,48,120,52,53,44,77,105,115,115,105,110,103,67,108,97,115,115,78,97,109,101,61,48,120,50,97,44,77,105,115,115,105,110,103,80,97,116,104,61,48,120,52,99,44,77,111,100,117,108,101,73,110,105,116,70,97,105,108,101,100,61,48,120,51,99,44,77,111,100,117,108,101,77,105,115,115,105,110,103,73,110,105,116,61,48,120,51,98,44,77,111,100,117,108,101,77,105,115,115,105,110,103,78,97,109,101,61,48,120,52,48,44,77,111,100,117,108,101,79,112,101,110,70,97,105,108,101,100,61,48,120,51,56,44,78,101,101,100,79,119,110,101,114,61,48,120,50,52,44,78,101,101,100,87,105,100,116,104,72,101,105,103,104,116,61,48,120,50,55,44,78,101,103,97,116,105,118,101,67,108,97,115,115,73,68,61,48,120,50,57,44,78,101,103,97,116,105,118,101,83,117,98,67,108,97,115,115,73,68,61,48,120,50,56,44,78,101,116,119,111,114,107,85,110,114,101,97,99,104,97,98,108,101,61,48,120,56,52,44,78,101,119,79,98,106,101,99,116,61,48,120,53,53,44,78,111,65,99,116,105,111,110,61,48,120,49,98,44,78,111,68,97,116,97,61,48,120,49,53,44,78,111,70,105,101,108,100,65,99,99,101,115,115,61,48,120,53,55,44,78,111,77,97,116,99,104,105,110,103,79,98,106,101,99,116,61,48,120,52,97,44,78,111,77,101,100,105,97,73,110,115,101,114,116,101,100,61,48,120,57,101,44,78,111,77,101,109,111,114,121,61,48,120,97,44,78,111,77,101,116,104,111,100,115,61,48,120,52,57,44,78,111,80,101,114,109,105,115,115,105,111,110,61,48,120,50,50,44,78,111,80,111,105,110,116,101,114,61,48,120,98,44,78,111,83,101,97,114,99,104,82,101,115,117,108,116,61,48,120,52,101,44,78,111,83,116,97,116,115,61,48,120,49,102,44,78,111,83,117,112,112,111,114,116,61,48,120,49,99,44,78,111,116,70,111,117,110,100,61,48,120,49,48,44,78,111,116,73,110,105,116,105,97,108,105,115,101,100,61,48,120,54,55,44,78,111,116,76,111,99,107,101,100,61,48,120,52,100,44,78,111,116,80,111,115,115,105,98,108,101,61,48,120,98,51,44,78,111,116,104,105,110,103,68,111,110,101,61,48,120,52,44,78,111,116,105,102,105,101,100,61,48,120,52,48,48,48,48,48,48,48,44,78,117,108,108,65,114,103,115,61,48,120,56,100,44,79,98,106,101,99,116,67,111,114,114,117,112,116,61,48,120,53,48,44,79,98,106,101,99,116,69,120,105,115,116,115,61,48,120,54,101,44,79,98,115,111,108,101,116,101,61,48,120,98,49,44,79,98,116,97,105,110,77,101,116,104,111,100,61,48,120,50,99,44,79,107,97,121,61,48,120,48,44,79,112,101,110,70,105,108,101,61,48,120,55,54,44,79,112,101,110,71,76,61,48,120,97,53,44,79,117,116,79,102,66,111,117,110,100,115,61,48,120,53,102,44,79,117,116,79,102,68,97,116,97,61,48,120,55,101,44,79,117,116,79,102,82,97,110,103,101,61,48,120,50,98,44,79,117,116,79,102,83,112,97,99,101,61,48,120,55,99,44,79,117,116,115,105,100,101,77,97,105,110,84,104,114,101,97,100,61,48,120,97,54,44,79,119,110,101,114,78,101,101,100,115,66,105,116,109,97,112,61,48,120,50,53,44,79,119,110,101,114,80,97,115,115,84,104,114,111,117,103,104,61,48,120,53,49,44,80,101,114,109,105,115,115,105,111,110,68,101,110,105,101,100,61,48,120,50,50,44,80,101,114,109,105,115,115,105,111,110,115,61,48,120,50,50,44,80,114,111,120,121,83,83,76,84,117,110,110,101,108,61,48,120,97,48,44,81,117,101,114,121,61,48,120,50,101,44,82,101,97,100,61,48,120,49,54,44,82,101,97,100,70,105,108,101,84,111,66,117,102,102,101,114,61,48,120,98,48,44,82,101,97,100,79,110,108,121,61,48,120,55,55,44,82,101,97,108,108,111,99,77,101,109,111,114,121,61,48,120,54,49,44,82,101,99,117,114,115,105,111,110,61,48,120,57,48,44,82,101,100,105,109,101,110,115,105,111,110,61,48,120,55,49,44,82,101,102,114,101,115,104,61,48,120,54,57,44,82,101,115,105,122,101,61,48,120,55,48,44,82,101,115,111,108,118,101,80,97,116,104,61,48,120,54,52,44,82,101,115,111,108,118,101,83,121,109,98,111,108,61,48,120,98,52,44,82,101,115,111,117,114,99,101,69,120,105,115,116,115,61,48,120,54,56,44,82,101,116,114,121,61,48,120,55,44,83,97,110,105,116,121,70,97,105,108,117,114,101,61,48,120,55,98,44,83,99,104,101,109,97,86,105,111,108,97,116,105,111,110,61,48,120,56,57,44,83,101,97,114,99,104,61,48,120,49,48,44,83,101,99,117,114,105,116,121,61,48,120,57,55,44,83,101,101,107,61,48,120,54,48,44,83,101,114,118,105,99,101,85,110,97,118,97,105,108,97,98,108,101,61,48,120,57,57,44,83,101,116,70,105,101,108,100,61,48,120,51,52,44,83,101,116,86,97,108,117,101,78,111,116,65,114,114,97,121,61,48,120,98,99,44,83,101,116,86,97,108,117,101,78,111,116,70,117,110,99,116,105,111,110,61,48,120,98,97,44,83,101,116,86,97,108,117,101,78,111,116,76,111,111,107,117,112,61,48,120,98,100,44,83,101,116,86,97,108,117,101,78,111,116,78,117,109,101,114,105,99,61,48,120,98,55,44,83,101,116,86,97,108,117,101,78,111,116,79,98,106,101,99,116,61,48,120,98,57,44,83,101,116,86,97,108,117,101,78,111,116,80,111,105,110,116,101,114,61,48,120,98,98,44,83,101,116,86,97,108,117,101,78,111,116,83,116,114,105,110,103,61,48,120,98,56,44,83,101,116,86,111,108,117,109,101,61,48,120,97,98,44,83,107,105,112,61,48,120,54,44,83,109,97,108,108,77,97,115,107,61,48,120,54,99,44,83,116,97,116,101,109,101,110,116,85,110,115,97,116,105,115,102,105,101,100,61,48,120,52,102,44,83,116,114,105,110,103,70,111,114,109,97,116,61,48,120,55,102,44,83,121,110,116,97,120,61,48,120,55,102,44,83,121,115,116,101,109,67,97,108,108,61,48,120,54,98,44,83,121,115,116,101,109,67,111,114,114,117,112,116,61,48,120,50,51,44,83,121,115,116,101,109,76,111,99,107,101,100,61,48,120,51,102,44,84,97,115,107,83,116,105,108,108,69,120,105,115,116,115,61,48,120,56,55,44,84,101,114,109,105,110,97,116,101,61,48,120,57,44,84,104,114,101,97,100,65,108,114,101,97,100,121,65,99,116,105,118,101,61,48,120,97,52,44,84,104,114,101,97,100,78,111,116,76,111,99,107,101,100,61,48,120,97,57,44,84,105,109,101,79,117,116,61,48,120,49,101,44,84,114,117,101,61,48,120,48,44,85,110,98,97,108,97,110,99,101,100,88,77,76,61,48,120,57,50,44,85,110,100,101,102,105,110,101,100,70,105,101,108,100,61,48,120,52,52,44,85,110,114,101,99,111,103,110,105,115,101,100,70,105,101,108,100,84,121,112,101,61,48,120,53,98,44,85,110,115,117,112,112,111,114,116,101,100,70,105,101,108,100,61,48,120,53,100,44,85,110,115,117,112,112,111,114,116,101,100,79,119,110,101,114,61,48,120,53,50,44,85,115,101,83,117,98,67,108,97,115,115,61,48,120,97,55,44,86,105,114,116,117,97,108,86,111,108,117,109,101,61,48,120,53,56,44,87,111,117,108,100,66,108,111,99,107,61,48,120,57,51,44,87,114,105,116,101,61,48,120,49,55,44,87,114,111,110,103,67,108,97,115,115,61,48,120,56,101,44,87,114,111,110,103,79,98,106,101,99,116,84,121,112,101,61,48,120,56,101,44,87,114,111,110,103,84,121,112,101,61,48,120,97,56,44,87,114,111,110,103,86,101,114,115,105,111,110,61,48,120,49,51,10,99,46,69,86,71,58,65,78,68,82,79,73,68,61,48,120,100,44,65,80,80,61,48,120,99,44,65,85,68,73,79,61,48,120,56,44,67,76,65,83,83,61,48,120,98,44,68,73,83,80,76,65,89,61,48,120,53,44,69,78,68,61,48,120,101,44,70,73,76,69,83,89,83,84,69,77,61,48,120,49,44,71,85,73,61,48,120,52,44,72,65,82,68,87,65,82,69,61,48,120,55,44,73,79,61,48,120,54,44,78,69,84,87,79,82,75,61,48,120,50,44,80,79,87,69,82,61,48,120,97,44,83,89,83,84,69,77,61,48,120,51,44,85,83,69,82,61,48,120,57,10,99,46,70,66,75,58,67,79,80,89,95,70,73,76,69,61,48,120,50,44,68,69,76,69,84,69,95,70,73,76,69,61,48,120,51,44,77,79,86,69,95,70,73,76,69,61,48,120,49,10,99,46,70,68,58,65,76,76,79,67,61,48,120,50,48,44,65,82,82,65,89,61,48,120,49,48,48,48,44,65,82,82,65,89,83,73,90,69,61,48,120,56,48,44,66,85,70,70,69,82,61,48,120,50,48,48,44,66,85,70,83,73,90,69,61,48,120,56,48,44,66,89,84,69,61,48,120,49,48,48,48,48,48,48,44,67,80,80,61,48,120,52,48,48,48,44,67,85,83,84,79,77,61,48,120,56,48,48,48,44,68,79,85,66,76,69,61,48,120,56,48,48,48,48,48,48,48,44,68,79,85,66,76,69,82,69,83,85,76,84,61,48,120,56,48,48,48,48,49,48,48,44,69,82,82,79,82,61,48,120,56,48,48,44,70,76,65,71,83,61,48,120,52,48,44,70,76,79,65,84,61,48,120,49,48,48,48,48,48,48,48,44,70,85,78,67,84,73,79,78,61,48,120,50,48,48,48,48,48,48,44,70,85,78,67,84,73,79,78,80,84,82,61,48,120,97,48,48,48,48,48,48,44,73,61,48,120,52,48,48,44,73,78,73,84,61,48,120,52,48,48,44,76,65,82,71,69,61,48,120,52,48,48,48,48,48,48,44,76,65,82,71,69,82,69,83,85,76,84,61,48,120,52,48,48,48,49,48,48,44,76,79,67,65,76,61,48,120,50,44,76,79,78,71,61,48,120,52,48,48,48,48,48,48,48,44,76,79,78,71,82,69,83,85,76,84,61,48,120,52,48,48,48,48,49,48,48,44,76,79,79,75,85,80,61,48,120,56,48,44,79,66,74,69,67,84,61,48,120,49,44,79,66,74,69,67,84,73,68,61,48,120,52,48,48,48,48,48,48,49,44,79,66,74,69,67,84,80,84,82,61,48,120,56,48,48,48,48,48,49,44,80,79,73,78,84,69,82,61,48,120,56,48,48,48,48,48,48,44,80,82,73,86,65,84,69,61,48,120,49,48,48,48,48,44,80,84,82,61,48,120,56,48,48,48,48,48,48,44,80,84,82,66,85,70,70,69,82,61,48,120,56,48,48,48,50,48,48,44,80,84,82,82,69,83,85,76,84,61,48,120,56,48,48,48,49,48,48,44,80,84,82,83,73,90,69,61,48,120,56,48,44,80,84,82,95,68,79,85,66,76,69,82,69,83,85,76,84,61,48,120,56,56,48,48,48,49,48,48,44,80,84,82,95,76,65,82,71,69,82,69,83,85,76,84,61,48,120,99,48,48,48,49,48,48,44,80,84,82,95,76,79,78,71,82,69,83,85,76,84,61,48,120,52,56,48,48,48,49,48,48,44,82,61,48,120,49,48,48,44,82,69,65,68,61,48,120,49,48,48,44,82,69,83,79,85,82,67,69,61,48,120,50,48,48,48,44,82,69,83,85,76,84,61,48,120,49,48,48,44,82,71,66,61,48,120,56,48,48,48,48,44,82,73,61,48,120,53,48,48,44,82,87,61,48,120,51,48,48,44,83,67,65,76,69,68,61,48,120,50,48,48,48,48,48,44,83,84,82,61,48,120,56,48,48,48,48,48,44,83,84,82,73,78,71,61,48,120,56,48,48,48,48,48,44,83,84,82,82,69,83,85,76,84,61,48,120,56,48,48,49,48,48,44,83,84,82,85,67,84,61,48,120,49,48,44,83,89,78,79,78,89,77,61,48,120,50,48,48,48,48,44,83,89,83,84,69,77,61,48,120,49,48,48,48,48,44,84,65,71,83,61,48,120,52,48,48,44,85,78,73,84,61,48,120,50,48,48,48,48,48,48,48,44,85,78,83,73,71,78,69,68,61,48,120,52,48,48,48,48,44,86,65,82,84,65,71,83,61,48,120,52,48,44,86,73,82,84,85,65,76,61,48,120,56,44,86,79,73,68,61,48,120,48,44,86,79,76,65,84,73,76,69,61,48,120,48,44,87,61,48,120,50,48,48,44,87,79,82,68,61,48,120,52,48,48,48,48,48,44,87,82,73,84,69,61,48,120,50,48,48,10,99,46,70,68,66,58,67,79,77,80,82,69,83,83,95,70,73,76,69,61,48,120,50,44,68,69,67,79,77,80,82,69,83,83,95,70,73,76,69,61,48,120,49,44,68,69,67,79,77,80,82,69,83,83,95,79,66,74,69,67,84,61,48,120,52,44,82,69,77,79,86,69,95,70,73,76,69,61,48,120,51,10,99,46,70,68,76,58,70,69,69,68,66,65,67,75,61,48,120,49,10,99,46,70,68,84,58,65,67,67,69,83,83,69,68,61,48,120,50,44,65,82,67,72,73,86,69,68,61,48,120,51,44,67,82,69,65,84,69,68,61,48,120,49,44,77,79,68,73,70,73,69,68,61,48,120,48,10,99,46,70,70,82,58,65,66,79,82,84,61,48,120,50,44,67,79,78,84,73,78,85,69,61,48,120,48,44,79,75,65,89,61,48,120,48,44,83,75,73,80,61,48,120,49,10,99,46,70,76,58,65,80,80,82,79,88,73,77,65,84,69,61,48,120,49,48,44,66,85,70,70,69,82,61,48,120,52,48,44,68,69,86,73,67,69,61,48,120,52,48,48,44,68,73,82,69,67,84,79,82,89,61,48,120,56,44,69,88,67,76,85,68,69,95,70,73,76,69,83,61,48,120,49,48,48,48,44,69,88,67,76,85,68,69,95,70,79,76,68,69,82,83,61,48,120,50,48,48,48,44,70,73,76,69,61,48,120,49,48,48,44,70,79,76,68,69,82,61,48,120,56,44,76,73,78,75,61,48,120,50,48,44,76,79,79,80,61,48,120,56,48,44,78,69,87,61,48,120,50,44,82,69,65,68,61,48,120,52,44,82,69,83,69,84,95,68,65,84,69,61,48,120,50,48,48,44,83,84,82,69,65,77,61,48,120,56,48,48,44,87,82,73,84,69,61,48,120,49,10,99,46,70,79,70,58,83,77,65,82,84,95,78,65,77,69,83,61,48,120,49,10,99,46,73,68,84,89,80,69,58,70,85,78,67,84,73,79,78,61,48,120,51,44,71,76,79,66,65,76,61,48,120,50,44,77,69,83,83,65,71,69,61,48,120,49,10,99,46,74,69,84,58,65,66,83,95,88,89,61,48,120,101,44,66,85,84,84,79,78,95,49,61,48,120,49,44,66,85,84,84,79,78,95,49,48,61,48,120,97,44,66,85,84,84,79,78,95,50,61,48,120,50,44,66,85,84,84,79,78,95,51,61,48,120,51,44,66,85,84,84,79,78,95,52,61,48,120,52,44,66,85,84,84,79,78,95,53,61,48,120,53,44,66,85,84,84,79,78,95,54,61,48,120,54,44,66,85,84,84,79,78,95,55,61,48,120,55,44,66,85,84,84,79,78,95,56,61,48,120,56,44,66,85,84,84,79,78,95,57,61,48,120,57,44,67,82,79,83,83,69,68,95,73,78,61,48,120,102,44,67,82,79,83,83,69,68,95,79,85,84,61,48,120,49,48,44,68,69,86,73,67,69,95,84,73,76,84,95,88,89,61,48,120,49,50,44,68,69,86,73,67,69,95,84,73,76,84,95,90,61,48,120,49,51,44,68,73,83,80,76,65,89,95,69,68,71,69,61,48,120,49,52,44,69,78,68,61,48,120,49,53,44,76,77,66,61,48,120,49,44,77,77,66,61,48,120,51,44,80,69,78,95,84,73,76,84,95,88,89,61,48,120,100,44,80,82,69,83,83,85,82,69,61,48,120,49,49,44,82,77,66,61,48,120,50,44,87,72,69,69,76,61,48,120,98,44,87,72,69,69,76,95,84,73,76,84,61,48,120,99,10,99,46,74,84,89,80,69,58,65,78,65,76,79,71,61,48,120,50,48,44,65,78,67,72,79,82,69,68,61,48,120,50,44,66,85,84,84,79,78,61,48,120,56,48,44,67,82,79,83,83,73,78,71,61,48,120,56,44,68,66,76,95,67,76,73,67,75,61,48,120,50,48,48,44,68,73,71,73,84,65,76,61,48,120,49,48,44,68,82,65,71,71,69,68,61,48,120,52,44,68,82,65,71,95,73,84,69,77,61,48,120,56,48,48,44,69,88,84,95,77,79,86,69,77,69,78,84,61,48,120,52,48,44,77,79,86,69,77,69,78,84,61,48,120,49,48,48,44,82,69,80,69,65,84,69,68,61,48,120,52,48,48,44,83,69,67,79,78,68,65,82,89,61,48,120,49,10,99,46,75,69,89,58,65,61,48,120,49,44,65,80,79,83,84,82,79,80,72,69,61,48,120,50,98,44,65,84,61,48,120,56,97,44,66,61,48,120,50,44,66,65,67,75,61,48,120,56,54,44,66,65,67,75,83,80,65,67,69,61,48,120,54,57,44,66,65,67,75,95,83,76,65,83,72,61,48,120,50,102,44,66,82,69,65,75,61,48,120,55,98,44,67,61,48,120,51,44,67,65,76,76,61,48,120,56,55,44,67,65,77,69,82,65,61,48,120,56,57,44,67,65,78,67,69,76,61,48,120,55,97,44,67,65,80,83,95,76,79,67,75,61,48,120,52,54,44,67,76,69,65,82,61,48,120,54,101,44,67,79,77,77,65,61,48,120,50,99,44,68,61,48,120,52,44,68,69,76,69,84,69,61,48,120,54,100,44,68,79,84,61,48,120,50,100,44,68,79,87,78,61,48,120,54,49,44,69,61,48,120,53,44,69,73,71,72,84,61,48,120,50,50,44,69,78,68,61,48,120,55,50,44,69,78,68,95,67,65,76,76,61,48,120,56,56,44,69,78,84,69,82,61,48,120,54,98,44,69,81,85,65,76,83,61,48,120,50,55,44,69,83,67,65,80,69,61,48,120,54,99,44,69,88,69,67,85,84,69,61,48,120,55,52,44,70,61,48,120,54,44,70,49,61,48,120,52,99,44,70,49,48,61,48,120,53,53,44,70,49,49,61,48,120,53,54,44,70,49,50,61,48,120,53,55,44,70,49,51,61,48,120,53,56,44,70,49,52,61,48,120,53,57,44,70,49,53,61,48,120,53,97,44,70,49,54,61,48,120,53,98,44,70,49,55,61,48,120,53,99,44,70,49,56,61,48,120,56,48,44,70,49,57,61,48,120,56,49,44,70,50,61,48,120,52,100,44,70,50,48,61,48,120,56,50,44,70,51,61,48,120,52,101,44,70,52,61,48,120,52,102,44,70,53,61,48,120,53,48,44,70,54,61,48,120,53,49,44,70,55,61,48,120,53,50,44,70,56,61,48,120,53,51,44,70,57,61,48,120,53,52,44,70,73,78,68,61,48,120,55,57,44,70,73,86,69,61,48,120,49,102,44,70,79,82,87,65,82,68,61,48,120,57,48,44,70,79,85,82,61,48,120,49,101,44,71,61,48,120,55,44,72,61,48,120,56,44,72,69,76,80,61,48,120,52,51,44,72,79,77,69,61,48,120,54,102,44,73,61,48,120,57,44,73,78,83,69,82,84,61,48,120,55,53,44,74,61,48,120,97,44,75,61,48,120,98,44,76,61,48,120,99,44,76,69,70,84,61,48,120,54,51,44,76,69,78,83,95,70,79,67,85,83,61,48,120,56,99,44,76,69,83,83,95,71,82,69,65,84,69,82,61,48,120,53,102,44,76,73,83,84,95,69,78,68,61,48,120,57,54,44,76,95,65,76,84,61,48,120,52,56,44,76,95,67,79,77,77,65,78,68,61,48,120,52,97,44,76,95,67,79,78,84,82,79,76,61,48,120,52,49,44,76,95,83,72,73,70,84,61,48,120,52,52,44,76,95,83,81,85,65,82,69,61,48,120,50,56,44,77,61,48,120,100,44,77,65,67,82,79,61,48,120,53,100,44,77,69,78,85,61,48,120,55,56,44,77,73,78,85,83,61,48,120,50,54,44,77,85,84,69,61,48,120,57,50,44,78,61,48,120,101,44,78,69,88,84,61,48,120,56,101,44,78,73,78,69,61,48,120,50,51,44,78,80,95,48,61,48,120,51,49,44,78,80,95,49,61,48,120,51,50,44,78,80,95,50,61,48,120,51,51,44,78,80,95,51,61,48,120,51,52,44,78,80,95,52,61,48,120,51,53,44,78,80,95,53,61,48,120,51,54,44,78,80,95,54,61,48,120,51,55,44,78,80,95,55,61,48,120,51,56,44,78,80,95,56,61,48,120,51,57,44,78,80,95,57,61,48,120,51,97,44,78,80,95,66,65,82,61,48,120,51,100,44,78,80,95,68,69,67,73,77,65,76,61,48,120,51,102,44,78,80,95,68,73,86,73,68,69,61,48,120,52,48,44,78,80,95,68,79,84,61,48,120,51,102,44,78,80,95,69,78,84,69,82,61,48,120,55,101,44,78,80,95,77,73,78,85,83,61,48,120,51,101,44,78,80,95,77,85,76,84,73,80,76,89,61,48,120,51,98,44,78,80,95,80,76,85,83,61,48,120,51,99,44,78,80,95,80,76,85,83,95,77,73,78,85,83,61,48,120,53,101,44,78,80,95,83,69,80,65,82,65,84,79,82,61,48,120,51,100,44,78,85,77,95,76,79,67,75,61,48,120,55,99,44,79,61,48,120,102,44,79,78,69,61,48,120,49,98,44,80,61,48,120,49,48,44,80,65,71,69,95,68,79,87,78,61,48,120,55,49,44,80,65,71,69,95,85,80,61,48,120,55,48,44,80,65,85,83,69,61,48,120,54,53,44,80,69,82,73,79,68,61,48,120,50,100,44,80,76,65,89,61,48,120,57,53,44,80,76,85,83,61,48,120,56,98,44,80,79,85,78,68,61,48,120,57,52,44,80,79,87,69,82,61,48,120,54,56,44,80,82,69,86,73,79,85,83,61,48,120,56,102,44,80,82,73,78,84,61,48,120,52,55,44,80,82,84,95,83,67,82,61,48,120,55,100,44,81,61,48,120,49,49,44,82,61,48,120,49,50,44,82,69,68,79,61,48,120,55,55,44,82,69,86,69,82,83,69,95,81,85,79,84,69,61,48,120,50,53,44,82,69,87,73,78,68,61,48,120,57,49,44,82,73,71,72,84,61,48,120,54,50,44,82,95,65,76,84,61,48,120,52,57,44,82,95,67,79,77,77,65,78,68,61,48,120,52,98,44,82,95,67,79,78,84,82,79,76,61,48,120,52,50,44,82,95,83,72,73,70,84,61,48,120,52,53,44,82,95,83,81,85,65,82,69,61,48,120,50,57,44,83,61,48,120,49,51,44,83,67,82,95,76,79,67,75,61,48,120,54,52,44,83,69,76,69,67,84,61,48,120,55,51,44,83,69,77,73,95,67,79,76,79,78,61,48,120,50,97,44,83,69,86,69,78,61,48,120,50,49,44,83,73,88,61,48,120,50,48,44,83,76,65,83,72,61,48,120,50,101,44,83,76,69,69,80,61,48,120,54,55,44,83,80,65,67,69,61,48,120,51,48,44,83,84,65,82,61,48,120,57,51,44,83,84,79,80,61,48,120,56,100,44,83,89,83,82,81,61,48,120,55,102,44,84,61,48,120,49,52,44,84,65,66,61,48,120,54,97,44,84,72,82,69,69,61,48,120,49,100,44,84,87,79,61,48,120,49,99,44,85,61,48,120,49,53,44,85,78,68,79,61,48,120,55,54,44,85,80,61,48,120,54,48,44,86,61,48,120,49,54,44,86,79,76,85,77,69,95,68,79,87,78,61,48,120,56,53,44,86,79,76,85,77,69,95,85,80,61,48,120,56,52,44,87,61,48,120,49,55,44,87,65,75,69,61,48,120,54,54,44,87,73,78,95,67,79,78,84,82,79,76,61,48,120,56,51,44,88,61,48,120,49,56,44,89,61,48,120,49,57,44,90,61,48,120,49,97,44,90,69,82,79,61,48,120,50,52,10,99,46,75,81,58,65,76,84,61,48,120,54,48,44,65,76,84,71,82,61,48,120,52,48,44,67,65,80,83,95,76,79,67,75,61,48,120,52,44,67,79,77,77,65,78,68,61,48,120,49,56,48,44,67,79,78,84,82,79,76,61,48,120,49,56,44,67,84,82,76,61,48,120,49,56,44,68,69,65,68,95,75,69,89,61,48,120,49,48,48,48,48,44,73,78,70,79,61,48,120,51,99,48,52,44,73,78,83,84,82,85,67,84,73,79,78,95,75,69,89,83,61,48,120,55,56,44,76,95,65,76,84,61,48,120,50,48,44,76,95,67,79,77,77,65,78,68,61,48,120,56,48,44,76,95,67,79,78,84,82,79,76,61,48,120,56,44,76,95,67,84,82,76,61,48,120,56,44,76,95,83,72,73,70,84,61,48,120,49,44,78,79,84,95,80,82,73,78,84,65,66,76,69,61,48,120,50,48,48,48,44,78,85,77,95,76,79,67,75,61,48,120,56,48,48,48,44,78,85,77,95,80,65,68,61,48,120,50,48,48,44,80,82,69,83,83,69,68,61,48,120,49,48,48,48,44,81,85,65,76,73,70,73,69,82,83,61,48,120,49,102,98,44,82,69,76,69,65,83,69,68,61,48,120,56,48,48,44,82,69,80,69,65,84,61,48,120,52,48,48,44,82,95,65,76,84,61,48,120,52,48,44,82,95,67,79,77,77,65,78,68,61,48,120,49,48,48,44,82,95,67,79,78,84,82,79,76,61,48,120,49,48,44,82,95,67,84,82,76,61,48,120,49,48,44,82,95,83,72,73,70,84,61,48,120,50,44,83,67,82,95,76,79,67,75,61,48,120,52,48,48,48,44,83,72,73,70,84,61,48,120,51,44,87,73,78,95,67,79,78,84,82,79,76,61,48,120,50,48,48,48,48,10,99,46,76,65,89,79,85,84,58,66,65,67,75,71,82,79,85,78,68,61,48,120,56,44,69,77,66,69,68,68,69,68,61,48,120,50,48,44,70,79,82,69,71,82,79,85,78,68,61,48,120,49,48,44,73,71,78,79,82,69,95,67,85,82,83,79,82,61,48,120,56,48,44,76,69,70,84,61,48,120,50,44,76,79,67,75,61,48,120,52,48,44,82,73,71,72,84,61,48,120,52,44,83,81,85,65,82,69,61,48,120,48,44,84,73,71,72,84,61,48,120,49,44,84,73,76,69,61,48,120,49,48,48,44,87,73,68,69,61,48,120,54,10,99,46,76,68,70,58,67,72,69,67,75,95,69,88,73,83,84,83,61,48,120,49,10,99,46,76,79,67,58,68,73,82,69,67,84,79,82,89,61,48,120,49,44,70,73,76,69,61,48,120,51,44,70,79,76,68,69,82,61,48,120,49,44,86,79,76,85,77,69,61,48,120,50,10,99,46,77,65,88,58,70,73,76,69,78,65,77,69,61,48,120,49,48,48,44,78,65,77,69,95,76,69,78,61,48,120,49,102,10,99,46,77,69,77,58,65,85,68,73,79,61,48,120,56,44,67,65,76,76,69,82,61,48,120,56,48,48,48,48,48,44,67,79,68,69,61,48,120,49,48,44,67,79,76,76,69,67,84,61,48,120,49,48,48,48,44,68,65,84,65,61,48,120,48,44,69,88,67,76,85,83,73,86,69,61,48,120,56,48,48,44,72,73,68,68,69,78,61,48,120,49,48,48,48,48,48,44,77,65,78,65,71,69,68,61,48,120,49,44,78,79,95,66,76,79,67,75,61,48,120,50,48,48,48,44,78,79,95,66,76,79,67,75,73,78,71,61,48,120,50,48,48,48,44,78,79,95,67,76,69,65,82,61,48,120,52,48,48,48,48,44,78,79,95,76,79,67,75,61,48,120,52,48,48,44,78,79,95,80,79,79,76,61,48,120,50,48,44,79,66,74,69,67,84,61,48,120,50,48,48,44,82,69,65,68,61,48,120,49,48,48,48,48,44,82,69,65,68,95,87,82,73,84,69,61,48,120,51,48,48,48,48,44,83,84,82,73,78,71,61,48,120,49,48,48,44,84,69,88,84,85,82,69,61,48,120,52,44,84,77,80,95,76,79,67,75,61,48,120,52,48,44,85,78,84,82,65,67,75,69,68,61,48,120,56,48,44,86,73,68,69,79,61,48,120,50,44,87,82,73,84,69,61,48,120,50,48,48,48,48,10,99,46,77,70,70,58,65,84,84,82,73,66,61,48,120,50,48,44,67,76,79,83,69,68,61,48,120,56,48,44,67,82,69,65,84,69,61,48,120,52,44,68,69,69,80,61,48,120,49,48,48,48,44,68,69,76,69,84,69,61,48,120,56,44,70,73,76,69,61,48,120,52,48,48,44,70,79,76,68,69,82,61,48,120,50,48,48,44,77,79,68,73,70,89,61,48,120,50,44,77,79,86,69,68,61,48,120,49,48,44,79,80,69,78,69,68,61,48,120,52,48,44,82,69,65,68,61,48,120,49,44,82,69,78,65,77,69,61,48,120,49,48,44,83,69,76,70,61,48,120,56,48,48,44,85,78,77,79,85,78,84,61,48,120,49,48,48,44,87,82,73,84,69,61,48,120,50,10,99,46,77,72,70,58,68,69,70,65,85,76,84,61,48,120,50,44,83,84,65,84,73,67,61,48,120,49,44,83,84,82,85,67,84,85,82,69,61,48,120,50,10,99,46,77,79,70,58,76,73,78,75,95,76,73,66,82,65,82,89,61,48,120,49,44,83,84,65,84,73,67,61,48,120,50,44,83,89,83,84,69,77,95,80,82,79,66,69,61,48,120,52,10,99,46,77,79,86,69,58,65,76,76,61,48,120,102,44,68,79,87,78,61,48,120,49,44,76,69,70,84,61,48,120,52,44,82,73,71,72,84,61,48,120,56,44,85,80,61,48,120,50,10,99,46,77,83,70,58,65,68,68,61,48,120,56,44,65,68,68,82,69,83,83,61,48,120,49,48,44,77,69,83,83,65,71,69,95,73,68,61,48,120,50,48,44,78,79,95,68,85,80,76,73,67,65,84,69,61,48,120,52,44,85,80,68,65,84,69,61,48,120,50,44,87,65,73,84,61,48,120,49,10,99,46,77,83,71,73,68,58,65,67,84,73,79,78,61,48,120,54,51,44,66,82,69,65,75,61,48,120,54,52,44,67,79,77,77,65,78,68,61,48,120,54,53,44,67,79,82,69,95,69,78,68,61,48,120,54,52,44,68,69,66,85,71,61,48,120,53,102,44,69,86,69,78,84,61,48,120,53,101,44,70,82,69,69,61,48,120,54,50,44,81,85,73,84,61,48,120,51,101,56,44,84,72,82,69,65,68,95,65,67,84,73,79,78,61,48,120,53,98,44,84,72,82,69,65,68,95,67,65,76,76,66,65,67,75,61,48,120,53,99,44,86,65,76,73,68,65,84,69,95,80,82,79,67,69,83,83,61,48,120,53,100,44,87,65,73,84,95,70,79,82,95,79,66,74,69,67,84,83,61,48,120,53,97,10,99,46,77,84,70,58,65,78,73,77,61,48,120,56,44,82,69,76,65,84,73,86,69,61,48,120,49,48,44,88,61,48,120,49,44,89,61,48,120,50,44,90,61,48,120,52,10,99,46,78,69,84,77,83,71,58,69,78,68,61,48,120,49,44,83,84,65,82,84,61,48,120,48,10,99,46,78,70,58,67,79,76,76,69,67,84,61,48,120,56,48,44,70,82,69,69,61,48,120,49,48,44,70,82,69,69,95,79,78,95,85,78,76,79,67,75,61,48,120,56,44,73,78,73,84,73,65,76,73,83,69,68,61,48,120,50,44,76,79,67,65,76,61,48,120,52,44,77,69,83,83,65,71,69,61,48,120,50,48,48,44,78,65,77,69,61,48,120,56,48,48,48,48,48,48,48,44,80,82,73,86,65,84,69,61,48,120,48,44,82,69,67,76,65,83,83,69,68,61,48,120,49,48,48,44,83,73,71,78,65,76,76,69,68,61,48,120,52,48,48,44,83,85,80,80,82,69,83,83,95,76,79,71,61,48,120,52,48,44,84,73,77,69,82,95,83,85,66,61,48,120,50,48,44,85,78,73,81,85,69,61,48,120,52,48,48,48,48,48,48,48,44,85,78,84,82,65,67,75,69,68,61,48,120,49,10,99,46,79,80,70,58,65,82,71,83,61,48,120,52,48,44,68,69,84,65,73,76,61,48,120,52,44,69,82,82,79,82,61,48,120,56,48,44,77,65,88,95,68,69,80,84,72,61,48,120,50,44,77,79,68,85,76,69,95,80,65,84,72,61,48,120,52,48,48,44,79,80,84,73,79,78,83,61,48,120,49,44,80,82,73,86,73,76,69,71,69,68,61,48,120,49,48,48,44,82,79,79,84,95,80,65,84,72,61,48,120,56,48,48,44,83,67,65,78,95,77,79,68,85,76,69,83,61,48,120,49,48,48,48,44,83,72,79,87,95,69,82,82,79,82,83,61,48,120,50,48,44,83,72,79,87,95,73,79,61,48,120,49,48,44,83,72,79,87,95,77,69,77,79,82,89,61,48,120,56,44,83,89,83,84,69,77,95,80,65,84,72,61,48,120,50,48,48,10,99,46,80,69,82,77,73,84,58,65,76,76,95,68,69,76,69,84,69,61,48,120,56,56,56,44,65,76,76,95,69,88,69,67,61,48,120,52,52,52,44,65,76,76,95,82,69,65,68,61,48,120,49,49,49,44,65,76,76,95,87,82,73,84,69,61,48,120,50,50,50,44,65,82,67,72,73,86,69,61,48,120,50,48,48,48,44,68,69,76,69,84,69,61,48,120,56,44,69,86,69,82,89,79,78,69,95,65,67,67,69,83,83,61,48,120,102,102,102,44,69,86,69,82,89,79,78,69,95,68,69,76,69,84,69,61,48,120,56,56,56,44,69,86,69,82,89,79,78,69,95,69,88,69,67,61,48,120,52,52,52,44,69,86,69,82,89,79,78,69,95,82,69,65,68,61,48,120,49,49,49,44,69,86,69,82,89,79,78,69,95,82,69,65,68,87,82,73,84,69,61,48,120,51,51,51,44,69,86,69,82,89,79,78,69,95,87,82,73,84,69,61,48,120,50,50,50,44,69,88,69,67,61,48,120,52,44,71,82,79,85,80,61,48,120,102,48,44,71,82,79,85,80,73,68,61,48,120,49,48,48,48,48,44,71,82,79,85,80,95,68,69,76,69,84,69,61,48,120,56,48,44,71,82,79,85,80,95,69,88,69,67,61,48,120,52,48,44,71,82,79,85,80,95,82,69,65,68,61,48,120,49,48,44,71,82,79,85,80,95,87,82,73,84,69,61,48,120,50,48,44,72,73,68,68,69,78,61,48,120,49,48,48,48,44,73,78,72,69,82,73,84,61,48,120,50,48,48,48,48,44,78,69,84,87,79,82,75,61,48,120,56,48,48,48,48,44,79,70,70,76,73,78,69,61,48,120,52,48,48,48,48,44,79,84,72,69,82,83,61,48,120,102,48,48,44,79,84,72,69,82,83,95,68,69,76,69,84,69,61,48,120,56,48,48,44,79,84,72,69,82,83,95,69,88,69,67,61,48,120,52,48,48,44,79,84,72,69,82,83,95,82,69,65,68,61,48,120,49,48,48,44,79,84,72,69,82,83,95,87,82,73,84,69,61,48,120,50,48,48,44,80,65,83,83,87,79,82,68,61,48,120,52,48,48,48,44,82,69,65,68,61,48,120,49,44,85,83,69,82,61,48,120,102,44,85,83,69,82,73,68,61,48,120,56,48,48,48,44,85,83,69,82,95,69,88,69,67,61,48,120,52,44,85,83,69,82,95,82,69,65,68,61,48,120,49,44,85,83,69,82,95,87,82,73,84,69,61,48,120,50,44,87,82,73,84,69,61,48,120,50,10,99,46,80,77,70,58,83,89,83,84,69,77,95,78,79,95,66,82,69,65,75,61,48,120,49,10,99,46,80,84,67,58,67,82,79,83,83,72,65,73,82,61,48,120,97,44,67,85,83,84,79,77,61,48,120,49,55,44,68,69,70,65,85,76,84,61,48,120,49,44,68,82,65,71,71,65,66,76,69,61,48,120,49,56,44,69,78,68,61,48,120,49,57,44,72,65,78,68,61,48,120,49,48,44,72,65,78,68,95,76,69,70,84,61,48,120,49,49,44,72,65,78,68,95,82,73,71,72,84,61,48,120,49,50,44,73,78,86,73,83,73,66,76,69,61,48,120,49,54,44,77,65,71,78,73,70,73,69,82,61,48,120,102,44,78,79,95,67,72,65,78,71,69,61,48,120,48,44,80,65,73,78,84,66,82,85,83,72,61,48,120,49,52,44,83,73,90,69,95,66,79,84,84,79,77,61,48,120,57,44,83,73,90,69,95,66,79,84,84,79,77,95,76,69,70,84,61,48,120,50,44,83,73,90,69,95,66,79,84,84,79,77,95,82,73,71,72,84,61,48,120,51,44,83,73,90,69,95,76,69,70,84,61,48,120,54,44,83,73,90,69,95,82,73,71,72,84,61,48,120,55,44,83,73,90,69,95,84,79,80,61,48,120,56,44,83,73,90,69,95,84,79,80,95,76,69,70,84,61,48,120,52,44,83,73,90,69,95,84,79,80,95,82,73,71,72,84,61,48,120,53,44,83,73,90,73,78,71,61,48,120,99,44,83,76,69,69,80,61,48,120,98,44,83,80,76,73,84,95,72,79,82,73,90,79,78,84,65,76,61,48,120,101,44,83,80,76,73,84,95,86,69,82,84,73,67,65,76,61,48,120,100,44,83,84,79,80,61,48,120,49,53,44,84,69,88,84,61,48,120,49,51,10,99,46,82,68,70,58,65,82,67,72,73,86,69,61,48,120,50,48,48,48,44,68,65,84,69,61,48,120,50,44,70,73,76,69,61,48,120,56,44,70,73,76,69,83,61,48,120,56,44,70,79,76,68,69,82,61,48,120,49,48,44,70,79,76,68,69,82,83,61,48,120,49,48,44,72,73,68,68,69,78,61,48,120,49,48,48,44,76,73,78,75,61,48,120,52,48,44,79,80,69,78,68,73,82,61,48,120,52,48,48,48,44,80,69,82,77,73,83,83,73,79,78,83,61,48,120,52,44,81,85,65,76,73,70,73,69,68,61,48,120,50,48,48,44,81,85,65,76,73,70,89,61,48,120,50,48,48,44,82,69,65,68,95,65,76,76,61,48,120,49,102,44,82,69,65,68,95,79,78,76,89,61,48,120,49,48,48,48,44,83,73,90,69,61,48,120,49,44,83,84,82,69,65,77,61,48,120,56,48,48,44,84,65,71,83,61,48,120,56,48,44,84,73,77,69,61,48,120,50,44,86,73,82,84,85,65,76,61,48,120,52,48,48,44,86,79,76,85,77,69,61,48,120,50,48,10,99,46,82,69,83,58,67,79,78,83,79,76,69,95,70,68,61,48,120,50,44,67,79,82,69,95,73,68,76,61,48,120,56,44,67,80,85,95,83,80,69,69,68,61,48,120,49,54,44,68,73,83,80,76,65,89,95,68,82,73,86,69,82,61,48,120,53,44,69,88,67,69,80,84,73,79,78,95,72,65,78,68,76,69,82,61,48,120,49,49,44,70,82,69,69,95,77,69,77,79,82,89,61,48,120,49,55,44,70,82,69,69,95,83,87,65,80,61,48,120,49,44,74,78,73,95,69,78,86,61,48,120,101,44,75,69,89,95,83,84,65,84,69,61,48,120,51,44,76,79,71,95,68,69,80,84,72,61,48,120,100,44,76,79,71,95,76,69,86,69,76,61,48,120,97,44,77,65,88,95,80,82,79,67,69,83,83,69,83,61,48,120,99,44,78,69,84,95,80,82,79,67,69,83,83,73,78,71,61,48,120,49,50,44,79,80,69,78,95,73,78,70,79,61,48,120,49,48,44,80,82,73,86,73,76,69,71,69,68,61,48,120,55,44,80,82,73,86,73,76,69,71,69,68,95,85,83,69,82,61,48,120,54,44,80,82,79,67,69,83,83,95,83,84,65,84,69,61,48,120,49,51,44,83,84,65,84,73,67,95,66,85,73,76,68,61,48,120,57,44,84,72,82,69,65,68,95,73,68,61,48,120,102,44,84,79,84,65,76,95,77,69,77,79,82,89,61,48,120,49,52,44,84,79,84,65,76,95,83,72,65,82,69,68,95,77,69,77,79,82,89,61,48,120,98,44,84,79,84,65,76,95,83,87,65,80,61,48,120,49,53,44,85,83,69,82,95,73,68,61,48,120,52,10,99,46,82,70,68,58,65,76,76,79,87,95,82,69,67,85,82,83,73,79,78,61,48,120,50,48,44,65,76,87,65,89,83,95,67,65,76,76,61,48,120,49,48,48,44,69,88,67,69,80,84,61,48,120,50,44,82,69,65,68,61,48,120,52,44,82,69,67,65,76,76,61,48,120,56,48,44,82,69,77,79,86,69,61,48,120,56,44,83,79,67,75,69,84,61,48,120,52,48,44,83,84,79,80,95,82,69,67,85,82,83,69,61,48,120,49,48,44,87,82,73,84,69,61,48,120,49,10,99,46,82,80,58,77,79,68,85,76,69,95,80,65,84,72,61,48,120,49,44,82,79,79,84,95,80,65,84,72,61,48,120,51,44,83,89,83,84,69,77,95,80,65,84,72,61,48,120,50,10,99,46,82,83,70,58,65,80,80,82,79,88,73,77,65,84,69,61,48,120,52,44,67,65,83,69,95,83,69,78,83,73,84,73,86,69,61,48,120,50,48,44,67,72,69,67,75,95,86,73,82,84,85,65,76,61,48,120,50,44,78,79,95,68,69,69,80,95,83,67,65,78,61,48,120,56,44,78,79,95,70,73,76,69,95,67,72,69,67,75,61,48,120,49,44,80,65,84,72,61,48,120,49,48,10,99,46,83,67,70,58,69,88,73,84,95,79,78,95,69,82,82,79,82,61,48,120,49,44,76,79,71,95,65,76,76,61,48,120,50,10,99,46,83,69,69,75,58,67,85,82,82,69,78,84,61,48,120,49,44,69,78,68,61,48,120,50,44,82,69,76,65,84,73,86,69,61,48,120,51,44,83,84,65,82,84,61,48,120,48,10,99,46,83,84,82,58,67,65,83,69,61,48,120,49,44,77,65,84,67,72,95,67,65,83,69,61,48,120,49,44,77,65,84,67,72,95,76,69,78,61,48,120,50,10,99,46,83,84,84,58,70,76,79,65,84,61,48,120,50,44,72,69,88,61,48,120,51,44,78,85,77,66,69,82,61,48,120,49,44,83,84,82,73,78,71,61,48,120,52,10,99,46,84,72,70,58,65,85,84,79,95,70,82,69,69,61,48,120,49,10,99,46,84,79,73,58,65,78,68,82,79,73,68,95,65,83,83,69,84,77,71,82,61,48,120,52,44,65,78,68,82,79,73,68,95,67,76,65,83,83,61,48,120,51,44,65,78,68,82,79,73,68,95,69,78,86,61,48,120,50,44,76,79,67,65,76,95,67,65,67,72,69,61,48,120,48,44,76,79,67,65,76,95,83,84,79,82,65,71,69,61,48,120,49,10,99,46,84,83,70,58,65,84,84,65,67,72,69,68,61,48,120,49,48,48,44,68,69,84,65,67,72,69,68,61,48,120,56,48,44,70,79,82,69,73,71,78,61,48,120,49,44,76,79,71,95,65,76,76,61,48,120,50,48,44,80,73,80,69,61,48,120,50,48,48,44,80,82,73,86,73,76,69,71,69,68,61,48,120,56,44,81,85,73,69,84,61,48,120,52,48,44,82,69,83,69,84,95,80,65,84,72,61,48,120,52,44,83,72,69,76,76,61,48,120,49,48,44,87,65,73,84,61,48,120,50,10,99,46,84,83,84,65,84,69,58,80,65,85,83,69,68,61,48,120,49,44,82,85,78,78,73,78,71,61,48,120,48,44,83,84,79,80,80,73,78,71,61,48,120,50,44,84,69,82,77,73,78,65,84,69,68,61,48,120,51,10,99,46,86,65,83,58,67,65,83,69,95,83,69,78,83,73,84,73,86,69,61,48,120,102,44,67,76,79,83,69,95,68,73,82,61,48,120,54,44,67,82,69,65,84,69,95,76,73,78,75,61,48,120,49,49,44,68,69,76,69,84,69,61,48,120,51,44,68,69,82,69,71,73,83,84,69,82,61,48,120,49,44,68,82,73,86,69,82,95,83,73,90,69,61,48,120,49,50,44,71,69,84,95,68,69,86,73,67,69,95,73,78,70,79,61,48,120,98,44,71,69,84,95,73,78,70,79,61,48,120,97,44,73,68,69,78,84,73,70,89,95,70,73,76,69,61,48,120,99,44,73,71,78,79,82,69,95,70,73,76,69,61,48,120,57,44,77,65,75,69,95,68,73,82,61,48,120,100,44,79,80,69,78,95,68,73,82,61,48,120,53,44,82,69,65,68,95,76,73,78,75,61,48,120,49,48,44,82,69,78,65,77,69,61,48,120,52,44,83,65,77,69,95,70,73,76,69,61,48,120,101,44,83,67,65,78,95,68,73,82,61,48,120,50,44,84,69,83,84,95,80,65,84,72,61,48,120,55,44,87,65,84,67,72,95,80,65,84,72,61,48,120,56,10,99,46,86,76,70,58,65,80,73,61,48,120,50,48,44,66,82,65,78,67,72,61,48,120,49,44,67,82,73,84,73,67,65,76,61,48,120,56,44,68,69,84,65,73,76,61,48,120,52,48,44,69,82,82,79,82,61,48,120,50,44,70,85,78,67,84,73,79,78,61,48,120,49,48,48,44,73,78,70,79,61,48,120,49,48,44,84,82,65,67,69,61,48,120,56,48,44,87,65,82,78,73,78,71,61,48,120,52,10,99,46,86,79,76,85,77,69,58,72,73,68,68,69,78,61,48,120,52,44,80,82,73,79,82,73,84,89,61,48,120,50,44,82,69,80,76,65,67,69,61,48,120,49,44,83,89,83,84,69,77,61,48,120,56,10,0 }; diff --git a/src/display/class_controller.cpp b/src/display/class_controller.cpp index 930162eda..6bce08b15 100644 --- a/src/display/class_controller.cpp +++ b/src/display/class_controller.cpp @@ -6,7 +6,7 @@ Controller: Provides support for reading state-based game controllers. Use the Controller class to read the state of game controllers that are recognised by the operating system. Unlike analog devices that stream input commands (e.g. mice), gamepad controllers maintain a state that can be read -at any time. Typically the controller state is read at least once per frame, which can be achieved in the main +at any time. The controller state is normally read at least once per frame, which can be achieved in the main inner loop, or in a separate timer. Controller input management is governed by the @Display class. The `GRAB_CONTROLLERS` flag must be defined in the @@ -32,10 +32,10 @@ Query: Get the current controller state. static ERR CONTROLLER_Query(objController *Self) { #ifdef _WIN32 -// winReadController(Self->Port, (DOUBLE *)&Self->LeftTrigger); - pf::Log log; - log.msg("Control: %.2f %.2f", Self->LeftStickX, Self->LeftStickY); - return ERR::Okay; + if (auto error = winReadController(Self->Port, (DOUBLE *)&Self->LeftTrigger, Self->Buttons); error IS ERR::Okay) { + return ERR::Okay; + } + else return error; #else return ERR::NoSupport; #endif @@ -67,8 +67,28 @@ Buttons: JET button values expressed as bit-fields. -FIELD- Port: The port number assigned to the controller. +Set the port number to choose the controller that will be queried for state changes. The default of zero is assigned +to the primary controller. + +The port number can be changed at any time, so multiple controllers can be queried through one interface at the cost +of overwriting the previous state. Check #TotalPorts if your program supports more than one controller. + +-FIELD- +TotalPorts: Reports the total number of controllers connected to the system. + *********************************************************************************************************************/ +static ERR CONTROLLER_GET_TotalPorts(extSurface *Self, LONG &Value) +{ +#ifdef _WIN32 + if (glLastPort >= 0) Value = glLastPort; + else Value = 0; + return ERR::Okay; +#endif + + return ERR::NoSupport; +} + //******************************************************************************************************************** #include "class_controller_def.c" @@ -82,6 +102,7 @@ static const FieldArray clFields[] = { { "RightStickY", FDF_DOUBLE|FDF_R }, { "Buttons", FDF_LONG|FDF_R }, { "Port", FDF_LONG|FDF_RI }, + { "TotalPorts", FDF_VIRTUAL|FDF_LONG|FDF_R, CONTROLLER_GET_TotalPorts }, END_FIELD }; diff --git a/src/display/class_controller_def.c b/src/display/class_controller_def.c index 3f47c2b9f..06e821161 100644 --- a/src/display/class_controller_def.c +++ b/src/display/class_controller_def.c @@ -15,6 +15,8 @@ static const struct FieldDef clControllerButtons[] = { { "LeftBumper2", 0x00000800 }, { "RightBumper1", 0x00001000 }, { "RightBumper2", 0x00002000 }, + { "LeftThumb", 0x00004000 }, + { "RightThumb", 0x00008000 }, { NULL, 0 } }; diff --git a/src/display/class_display.cpp b/src/display/class_display.cpp index 0f0c2b308..7bc4c86fa 100644 --- a/src/display/class_display.cpp +++ b/src/display/class_display.cpp @@ -1967,24 +1967,6 @@ static ERR GET_Chipset(extDisplay *Self, STRING *Value) return ERR::Okay; } -/********************************************************************************************************************* --FIELD- -ControllerPorts: Indicates the total number of connected controllers. - -Read the ControllerPorts value to get the total number of controllers connected to the system. This value can be used -in conjunction with the @Controller class to read state from multiple controllers. - -It is required that the `GRAB_CONTROLLERS` flag is set in the #Flags field in order for a program to access any -connected controllers. - -*********************************************************************************************************************/ - -static ERR GET_ControllerPorts(extDisplay *Self, LONG *Value) -{ - *Value = Self->ControllerPorts; - return ERR::Okay; -} - /********************************************************************************************************************* -FIELD- HDensity: Returns the horizontal pixel density for the display. @@ -2839,7 +2821,6 @@ static const FieldArray DisplayFields[] = { { "BottomMargin", FDF_LONG|FDF_R }, // Virtual fields { "Chipset", FDF_VIRTUAL|FDF_STRING|FDF_R, GET_Chipset }, - { "ControllerPorts", FDF_VIRTUAL|FDF_LONG|FDF_R, GET_ControllerPorts }, { "Gamma", FDF_VIRTUAL|FDF_DOUBLE|FDF_ARRAY|FDF_RI, GET_Gamma, SET_Gamma }, { "HDensity", FDF_VIRTUAL|FDF_LONG|FDF_RW, GET_HDensity, SET_HDensity }, { "VDensity", FDF_VIRTUAL|FDF_LONG|FDF_RW, GET_VDensity, SET_VDensity }, diff --git a/src/display/defs.h b/src/display/defs.h index 7d31caf35..79002afad 100644 --- a/src/display/defs.h +++ b/src/display/defs.h @@ -474,6 +474,7 @@ extern char glpDPMS[20]; extern UBYTE *glDemultiply; extern std::array glAlphaLookup; extern std::list glClips; +extern int glLastPort; extern std::unordered_map glWindowHooks; extern std::vector glFocusList; diff --git a/src/display/display-driver.cpp b/src/display/display-driver.cpp index 4301036cf..2fb842eb5 100644 --- a/src/display/display-driver.cpp +++ b/src/display/display-driver.cpp @@ -196,6 +196,7 @@ LONG glpMaximise = FALSE, glpFullScreen = FALSE; SWIN glpWindowType = SWIN::HOST; char glpDPMS[20] = "Standby"; UBYTE *glDemultiply = NULL; +int glLastPort = -1; std::vector glFocusList; std::recursive_mutex glFocusLock; diff --git a/src/display/win32/handlers.cpp b/src/display/win32/handlers.cpp index 6b33d3986..407ce5ba2 100644 --- a/src/display/win32/handlers.cpp +++ b/src/display/win32/handlers.cpp @@ -146,20 +146,6 @@ void MsgButtonPress(LONG button, LONG State) //******************************************************************************************************************** -void MsgTotalControllerPorts(OBJECTID SurfaceID, int Ports) -{ - if (ScopedObjectLock surface(SurfaceID, 3000); surface.granted()) { - if (ScopedObjectLock display(surface->DisplayID, 3000); display.granted()) { - if ((display->Flags & SCR::GRAB_CONTROLLERS) != SCR::NIL) { - display->ControllerPorts = Ports + 1; - } - else display->ControllerPorts = 0; - } - } -} - -//******************************************************************************************************************** - void MsgResizedWindow(OBJECTID SurfaceID, LONG WinX, LONG WinY, LONG WinWidth, LONG WinHeight, LONG ClientX, LONG ClientY, LONG ClientWidth, LONG ClientHeight) { diff --git a/src/display/win32/windows.cpp b/src/display/win32/windows.cpp index e480a82ab..934aae88d 100644 --- a/src/display/win32/windows.cpp +++ b/src/display/win32/windows.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include "windows.h" @@ -73,6 +74,7 @@ typedef long long LARGE; #endif extern HINSTANCE glInstance; +extern int glLastPort; void KillMessageHook(void); static HWND glMainScreen = 0; @@ -571,7 +573,7 @@ static void HandleWheel(HWND window, WPARAM wparam, LPARAM lparam) // the main window. if (auto surface_id = winLookupSurfaceID(window)) { - double delta = -((DOUBLE)GET_WHEEL_DELTA_WPARAM(wparam) / (DOUBLE)WHEEL_DELTA) * 3.0; + double delta = -((double)GET_WHEEL_DELTA_WPARAM(wparam) / (double)WHEEL_DELTA) * 3.0; MsgWheelMovement(surface_id, delta); } } @@ -810,16 +812,14 @@ static LRESULT CALLBACK WindowProcedure(HWND window, UINT msgcode, WPARAM wParam //XInputEnable(FALSE); #endif - int last_port = -1; + glLastPort = 0; for (DWORD i = 0; i < XUSER_MAX_COUNT; i++) { XINPUT_CAPABILITIES cap; if (XInputGetCapabilities(i, XINPUT_FLAG_GAMEPAD, &cap) == ERROR_SUCCESS) { - last_port = i; + glLastPort = i; } else break; } - - MsgTotalControllerPorts(surface, last_port); } else { // We have lost the focus @@ -1060,10 +1060,47 @@ void winDisableBatching(void) //******************************************************************************************************************** -ERR winReadController(int Port, double *Values) +ERR winReadController(int Port, double *Values, CON &Buttons) { + constexpr double tolerance = 0.08; // At-rest dead zone tolerance for thumb sticks XINPUT_STATE state; if (XInputGetState(Port, &state) == ERROR_SUCCESS) { + Values[0] = double(state.Gamepad.bLeftTrigger) * (1.0 / 255.0); + Values[1] = double(state.Gamepad.bRightTrigger) * (1.0 / 255.0); + Values[2] = std::clamp(double(state.Gamepad.sThumbLX) * (1.0 / 32767.0), -1.0, 1.0); + Values[3] = std::clamp(double(state.Gamepad.sThumbLY) * (1.0 / 32767.0), -1.0, 1.0); + Values[4] = std::clamp(double(state.Gamepad.sThumbRX) * (1.0 / 32767.0), -1.0, 1.0); + Values[5] = std::clamp(double(state.Gamepad.sThumbRY) * (1.0 / 32767.0), -1.0, 1.0); + + if ((Values[2] < tolerance) and (Values[2] > -tolerance) and + (Values[3] < tolerance) and (Values[3] > -tolerance)) { + Values[2] = 0; + Values[3] = 0; + } + + if ((Values[4] < tolerance) and (Values[4] > -tolerance) and + (Values[5] < tolerance) and (Values[5] > -tolerance)) { + Values[4] = 0; + Values[5] = 0; + } + + if (state.Gamepad.wButtons) { + if (state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP) Buttons |= CON::DPAD_UP; + if (state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN) Buttons |= CON::DPAD_DOWN; + if (state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT) Buttons |= CON::DPAD_LEFT; + if (state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT) Buttons |= CON::DPAD_RIGHT; + if (state.Gamepad.wButtons & XINPUT_GAMEPAD_START) Buttons |= CON::START; + if (state.Gamepad.wButtons & XINPUT_GAMEPAD_BACK) Buttons |= CON::SELECT; + if (state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB) Buttons |= CON::LEFT_THUMB; + if (state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB) Buttons |= CON::RIGHT_THUMB; + if (state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER) Buttons |= CON::LEFT_BUMPER_1; + if (state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER) Buttons |= CON::RIGHT_BUMPER_1; + if (state.Gamepad.wButtons & XINPUT_GAMEPAD_A) Buttons |= CON::GAMEPAD_S; + if (state.Gamepad.wButtons & XINPUT_GAMEPAD_B) Buttons |= CON::GAMEPAD_E; + if (state.Gamepad.wButtons & XINPUT_GAMEPAD_X) Buttons |= CON::GAMEPAD_W; + if (state.Gamepad.wButtons & XINPUT_GAMEPAD_Y) Buttons |= CON::GAMEPAD_N; + } + else Buttons = CON::NIL; //state.Gamepad.wButtons; return ERR::Okay; } else return ERR::Failed; diff --git a/src/display/win32/windows.h b/src/display/win32/windows.h index 6ff926f7d..e4b58aa85 100644 --- a/src/display/win32/windows.h +++ b/src/display/win32/windows.h @@ -29,6 +29,30 @@ struct WinDT { void *Data; }; +#if !defined(PARASOL_MAIN_H) && defined(__cplusplus) +enum class CON : unsigned int { + NIL = 0, + GAMEPAD_S = 0x00000001, + GAMEPAD_E = 0x00000002, + GAMEPAD_W = 0x00000004, + GAMEPAD_N = 0x00000008, + DPAD_UP = 0x00000010, + DPAD_DOWN = 0x00000020, + DPAD_LEFT = 0x00000040, + DPAD_RIGHT = 0x00000080, + START = 0x00000100, + SELECT = 0x00000200, + LEFT_BUMPER_1 = 0x00000400, + LEFT_BUMPER_2 = 0x00000800, + RIGHT_BUMPER_1 = 0x00001000, + RIGHT_BUMPER_2 = 0x00002000, + LEFT_THUMB = 0x00004000, + RIGHT_THUMB = 0x00008000 +}; + +DEFINE_ENUM_FLAG_OPERATORS(CON) +#endif + #ifdef __cplusplus extern "C" { #endif @@ -120,7 +144,7 @@ extern void winMinimiseWindow(HWND); extern int winMoveWindow(HWND, int, int); extern void winMoveToBack(HWND); extern void winMoveToFront(HWND); -extern ERR winReadController(int Port, double *Values); +extern ERR winReadController(int, double *, CON &); extern int winReadKey(char *, char *, unsigned char *, int); extern int winResizeWindow(HWND, int, int, int, int); extern void winSetCursorPos(int X, int Y); diff --git a/tools/idl/common.fdl b/tools/idl/common.fdl index 282f873d5..be09b0680 100644 --- a/tools/idl/common.fdl +++ b/tools/idl/common.fdl @@ -206,7 +206,10 @@ flags("CON", { comment="Gamepad controller buttons.", module="core" }, "LEFT_BUMPER_1: Gamepad left-hand bumper 1 (top, primary).", "LEFT_BUMPER_2: Gamepad left-hand bumper 2 (lower).", "RIGHT_BUMPER_1: Gamepad right-hand bumper 1 (top, primary).", - "RIGHT_BUMPER_2: Gamepad right-hand bumper 2 (lower).") + "RIGHT_BUMPER_2: Gamepad right-hand bumper 2 (lower).", + "LEFT_THUMB: Left thumb stick depressed.", + "RIGHT_THUMB: Right thumb stick depressed." + ) enum("JET", { type="int", start=1, comment="JET constants are documented in GetInputEvent()", module="Core" }, "BUTTON_1|LMB: Left mouse button; XBox A button, PS square button. Value is pressure sensitive, ranging between 0 - 1.0 (0 is released, 1.0 is fully depressed).", From 4b10d50cd257ca298da552a250880d06b6a3da03 Mon Sep 17 00:00:00 2001 From: Paul Manias Date: Thu, 5 Dec 2024 23:56:41 +0000 Subject: [PATCH 5/9] [VectorGradient] Fixed radial gradient issues relating to focal points and radius calculations. --- .../tests/gradients/w3-pservers-grad-01-b.svg | 20 ++++ .../tests/gradients/w3-pservers-grad-02-b.svg | 19 +++ .../tests/gradients/w3-pservers-grad-07-b.svg | 30 +++++ .../tests/gradients/w3-pservers-grad-08-b.svg | 41 +++++++ .../tests/gradients/w3-pservers-grad-09-b.svg | 39 +++++++ .../tests/gradients/w3-pservers-grad-11-b.svg | 42 +++++++ .../tests/gradients/w3-pservers-grad-12-b.svg | 39 +++++++ .../tests/gradients/w3-pservers-grad-15-b.svg | 19 +++ .../tests/gradients/w3-pservers-grad-22-b.svg | 50 ++++++++ src/svg/tests/test-svg.fluid | 25 +++- src/vector/scene/scene_fill.cpp | 108 +++++++++--------- 11 files changed, 375 insertions(+), 57 deletions(-) create mode 100644 src/svg/tests/gradients/w3-pservers-grad-01-b.svg create mode 100644 src/svg/tests/gradients/w3-pservers-grad-02-b.svg create mode 100644 src/svg/tests/gradients/w3-pservers-grad-07-b.svg create mode 100644 src/svg/tests/gradients/w3-pservers-grad-08-b.svg create mode 100644 src/svg/tests/gradients/w3-pservers-grad-09-b.svg create mode 100644 src/svg/tests/gradients/w3-pservers-grad-11-b.svg create mode 100644 src/svg/tests/gradients/w3-pservers-grad-12-b.svg create mode 100644 src/svg/tests/gradients/w3-pservers-grad-15-b.svg create mode 100644 src/svg/tests/gradients/w3-pservers-grad-22-b.svg diff --git a/src/svg/tests/gradients/w3-pservers-grad-01-b.svg b/src/svg/tests/gradients/w3-pservers-grad-01-b.svg new file mode 100644 index 000000000..a34175111 --- /dev/null +++ b/src/svg/tests/gradients/w3-pservers-grad-01-b.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + Linear gradient. + + + Referencing gradient below. + + + diff --git a/src/svg/tests/gradients/w3-pservers-grad-02-b.svg b/src/svg/tests/gradients/w3-pservers-grad-02-b.svg new file mode 100644 index 000000000..61b88f1bb --- /dev/null +++ b/src/svg/tests/gradients/w3-pservers-grad-02-b.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + Radial gradient. + + + Referencing gradient below. + + + diff --git a/src/svg/tests/gradients/w3-pservers-grad-07-b.svg b/src/svg/tests/gradients/w3-pservers-grad-07-b.svg new file mode 100644 index 000000000..9cac36753 --- /dev/null +++ b/src/svg/tests/gradients/w3-pservers-grad-07-b.svg @@ -0,0 +1,30 @@ +TR/SVG11/pservers.html#Gradients"> + + + + + + + + + + Linear gradient filled rectangle + + + Linear gradient on stroke of rectangle + + + + diff --git a/src/svg/tests/gradients/w3-pservers-grad-08-b.svg b/src/svg/tests/gradients/w3-pservers-grad-08-b.svg new file mode 100644 index 000000000..9340494f5 --- /dev/null +++ b/src/svg/tests/gradients/w3-pservers-grad-08-b.svg @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + Gradient on fill + + + Gradient on stroke + + + + Linear gradient on filled text + Linear gradient on stroke of text + + + + diff --git a/src/svg/tests/gradients/w3-pservers-grad-09-b.svg b/src/svg/tests/gradients/w3-pservers-grad-09-b.svg new file mode 100644 index 000000000..b2c7f31b4 --- /dev/null +++ b/src/svg/tests/gradients/w3-pservers-grad-09-b.svg @@ -0,0 +1,39 @@ + + + Testing gradientUnits attribute + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/svg/tests/gradients/w3-pservers-grad-11-b.svg b/src/svg/tests/gradients/w3-pservers-grad-11-b.svg new file mode 100644 index 000000000..fd5a9ddbe --- /dev/null +++ b/src/svg/tests/gradients/w3-pservers-grad-11-b.svg @@ -0,0 +1,42 @@ + + + + + + + + + + Radial gradient on fill of rectangle + + + + + + + + + Radial gradient on stroke of rectangle + + + + + + + + Gradient on text fill + Radial gradient on text, black to yellow + + + + + + + + Gradient on text stroke + Radial gradient on stroke of text, black to red + + + diff --git a/src/svg/tests/gradients/w3-pservers-grad-12-b.svg b/src/svg/tests/gradients/w3-pservers-grad-12-b.svg new file mode 100644 index 000000000..a0545f2ba --- /dev/null +++ b/src/svg/tests/gradients/w3-pservers-grad-12-b.svg @@ -0,0 +1,39 @@ + + + + Testing gradientUnits attribute + + + + + + + + + Radial gradient with default attributes (from blue to yellow) + Gradient is blue at the object center and lime at the object edges + + + + + + + + + gradientUnits=objectBoundingBox + cx=.2, cy=.2, r=.5, fx=.2 fy=.2 + + + + + + + + + gradientUnits=userSpaceOnUse + Gradient is yellow to blue radial gradient from center to horizontal bounds + + + + diff --git a/src/svg/tests/gradients/w3-pservers-grad-15-b.svg b/src/svg/tests/gradients/w3-pservers-grad-15-b.svg new file mode 100644 index 000000000..3a83ca566 --- /dev/null +++ b/src/svg/tests/gradients/w3-pservers-grad-15-b.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/src/svg/tests/gradients/w3-pservers-grad-22-b.svg b/src/svg/tests/gradients/w3-pservers-grad-22-b.svg new file mode 100644 index 000000000..0fa8a118c --- /dev/null +++ b/src/svg/tests/gradients/w3-pservers-grad-22-b.svg @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/svg/tests/test-svg.fluid b/src/svg/tests/test-svg.fluid index 7d3735105..4009de8cd 100644 --- a/src/svg/tests/test-svg.fluid +++ b/src/svg/tests/test-svg.fluid @@ -66,6 +66,16 @@ function testHoneycomb() hashTestSVG('patterns/honeycomb.svg', 0x7b678a function testSnake() hashTestSVG('patterns/snake.svg', 0xbb7d40f0) end function testVStripes() hashTestSVG('patterns/vstripes.svg', 0x2f85dc21) end +function testW3Gradients01() hashTestSVG('gradients/w3-pservers-grad-01-b.svg', 0xe637a6fa) end +function testW3Gradients02() hashTestSVG('gradients/w3-pservers-grad-02-b.svg', 0x69157174) end +function testW3Gradients07() hashTestSVG('gradients/w3-pservers-grad-07-b.svg', 0xfb7be5fe) end +function testW3Gradients08() hashTestSVG('gradients/w3-pservers-grad-08-b.svg', 0x97f7b810) end +function testW3Gradients09() hashTestSVG('gradients/w3-pservers-grad-09-b.svg', 0xfd34d4f1) end +function testW3Gradients11() hashTestSVG('gradients/w3-pservers-grad-11-b.svg', 0x4f4a58f3) end +function testW3Gradients12() hashTestSVG('gradients/w3-pservers-grad-12-b.svg', 0xd59b60ce) end +function testW3Gradients15() hashTestSVG('gradients/w3-pservers-grad-15-b.svg', 0x531aca96) end +function testW3Gradients22() hashTestSVG('gradients/w3-pservers-grad-22-b.svg', 0x5477019b) end + function testCoarsePaper() hashTestSVG('filters/coarse_paper.svg', 0xc4158cf1) end function testComposite() hashTestSVG('filters/composite.svg', 0x66a96a50) end function testConvolve() hashTestSVG('filters/convolve.svg', 0x29d31e69) end @@ -123,10 +133,10 @@ function testContourGradient() hashTestSVG('misc/contour-gradient.svg', 0x4b8 function testBottleTree() hashTestSVG('images/bottletree.svg', 0xd7fb84ff) end function testButton() hashTestSVG('images/button.svg', 0x0e8f5a31) end -function testClock() hashTestSVG('images/clock.svg', 0xe5ad43cb) end -function testIceCube() hashTestSVG('images/icecube.svg', 0x86d23579) end +function testClock() hashTestSVG('images/clock.svg', 0xa2cf50e4) end +function testIceCube() hashTestSVG('images/icecube.svg', 0xc8dc1cd4) end function testTiger() hashTestSVG('images/tiger.svg', 0xa7b2c808) end -function testPod() hashTestSVG('images/pod.svg', 0x9a0fbeda) end +function testPod() hashTestSVG('images/pod.svg', 0xf51113c0) end function testClip() hashTestSVG('masks/clip.svg', 0x209c16aa) end function testClipViewBox() hashTestSVG('masks/clip-viewbox.svg', 0xd66308b7) end @@ -240,6 +250,15 @@ function testW3TextB25() hashTestSVG('text/w3-text-ws-03-t.svg', -1) end --'testW3MasksOpacity', 'testSplitCircles', 'testInheritClip', + 'testW3Gradients01', + 'testW3Gradients02', + 'testW3Gradients07', + 'testW3Gradients08', + 'testW3Gradients09', + 'testW3Gradients11', + 'testW3Gradients12', + 'testW3Gradients15', + 'testW3Gradients22', -- Patterns 'testChevrons', 'testComplex', diff --git a/src/vector/scene/scene_fill.cpp b/src/vector/scene/scene_fill.cpp index 3dddaa358..8f5516722 100644 --- a/src/vector/scene/scene_fill.cpp +++ b/src/vector/scene/scene_fill.cpp @@ -175,48 +175,48 @@ static void fill_gradient(VectorState &State, const TClipRectangle &Boun if ((Gradient.Flags & VGF::SCALED_FX) != VGF::NIL) f.x = x_offset + (c_width * Gradient.FX); else if ((Gradient.Flags & VGF::FIXED_FX) != VGF::NIL) f.x = x_offset + Gradient.FX; - else f.x = x_offset + c.x; + else f.x = c.x; if ((Gradient.Flags & VGF::SCALED_FY) != VGF::NIL) f.y = y_offset + (c_height * Gradient.FY); else if ((Gradient.Flags & VGF::FIXED_FY) != VGF::NIL) f.y = y_offset + Gradient.FY; - else f.y = y_offset + c.y; + else f.y = c.y; if ((c.x IS f.x) and (c.y IS f.y)) { // Standard radial gradient, where the focal point is the same as the gradient center - DOUBLE length = Gradient.Radius; + DOUBLE radial_col_span = Gradient.Radius; if (Gradient.Units IS VUNIT::USERSPACE) { // Coordinates are relative to the viewport if ((Gradient.Flags & VGF::SCALED_RADIUS) != VGF::NIL) { // Gradient is a ratio of the viewport's dimensions - length = (ViewWidth + ViewHeight) * Gradient.Radius * 0.5; + radial_col_span = (ViewWidth + ViewHeight) * Gradient.Radius * 0.5; } } else { // Coordinates are scaled to the bounding box if ((Gradient.Flags & VGF::SCALED_RADIUS) != VGF::NIL) { - // In AGG, an unscaled gradient will cover the entire bounding box according to the diagonal. - // In SVG a radius of 50% must result in the edge of the radius meeting the edge of the bounding box. - - DOUBLE scale_x = Gradient.Radius * (1.0 / 0.707106781); //(width * Gradient.Radius) / (sqrt((width * width) + (width * width)) * 0.5); - DOUBLE scale_y = Gradient.Radius * (1.0 / 0.707106781); //(height * Gradient.Radius) / (sqrt((height * height) + (height * height)) * 0.5); - if (c_height > c_width) scale_y *= c_height / c_width; - else if (c_width > c_height) scale_x *= c_width / c_height; - scale_x *= 100.0 / length; // Adjust the scale according to the gradient length. - scale_y *= 100.0 / length; - transform.scale(scale_x, scale_y); + // Set radial_col_span to the wider of the width/height + if (c_height > c_width) { + radial_col_span = c_height * Gradient.Radius; + transform.scale(c_width / c_height, 1.0); + } + else { + radial_col_span = c_width * Gradient.Radius; + transform.scale(1.0, c_height / c_width); + } } else { - //transform *= agg::trans_affine_scaling(Gradient.Radius * 0.01 / length); + //transform *= agg::trans_affine_scaling(Gradient.Radius * 0.01 / radial_col_span); } } - if (length < 255) { // Blending works best if the gradient span is at least 255 colours wide, so adjust it here. - transform.scale(length * (1.0 / 255.0)); - length = 255; + constexpr double MIN_SPAN = 32; + if (radial_col_span < MIN_SPAN) { // Blending looks best if it meets a minimum span (radius) value. + transform.scale(radial_col_span * (1.0 / MIN_SPAN)); + radial_col_span = MIN_SPAN; } agg::gradient_radial gradient_func; typedef agg::span_gradient span_gradient_type; typedef agg::renderer_scanline_aa renderer_gradient_type; - span_gradient_type span_gradient(span_interpolator, gradient_func, *Table, 0, length); + span_gradient_type span_gradient(span_interpolator, gradient_func, *Table, 0, radial_col_span); renderer_gradient_type solidrender_gradient(RenderBase, span_allocator, span_gradient); transform.translate(c.x, c.y); @@ -244,26 +244,26 @@ static void fill_gradient(VectorState &State, const TClipRectangle &Boun if ((Gradient.Flags & VGF::SCALED_RADIUS) != VGF::NIL) { fix_radius *= (c_width + c_height) * 0.5; // Use the average radius of the ellipse. } - DOUBLE length = fix_radius; + DOUBLE radial_col_span = fix_radius; if (Gradient.Units IS VUNIT::USERSPACE) { if ((Gradient.Flags & VGF::SCALED_RADIUS) != VGF::NIL) { - const DOUBLE scale = length * Gradient.Radius; + const DOUBLE scale = radial_col_span * Gradient.Radius; transform *= agg::trans_affine_scaling(sqrt((ViewWidth * ViewWidth) + (ViewHeight * ViewHeight)) / scale); } else transform *= agg::trans_affine_scaling(Gradient.Radius * 0.01); } else { // Bounding box if ((Gradient.Flags & VGF::SCALED_RADIUS) != VGF::NIL) { - // In AGG, an unscaled gradient will cover the entire bounding box according to the diagonal. - // In SVG a radius of 50% must result in the edge of the radius meeting the edge of the bounding box. - - auto scale = agg::point_d(Gradient.Radius * (1.0 / 0.707106781), Gradient.Radius * (1.0 / 0.707106781)); - if (c_height > c_width) scale.y *= c_height / c_width; - else if (c_width > c_height) scale.x *= c_width / c_height; - scale.x *= 100.0 / length; // Adjust the scale according to the gradient length. - scale.y *= 100.0 / length; - transform.scale(scale); + // Set radial_col_span to the wider of the width/height + if (c_height > c_width) { + radial_col_span = c_height * Gradient.Radius; + transform.scale(c_width / c_height, 1.0); + } + else { + radial_col_span = c_width * Gradient.Radius; + transform.scale(1.0, c_height / c_width); + } } else transform *= agg::trans_affine_scaling(Gradient.Radius * 0.01); } @@ -303,25 +303,25 @@ static void fill_gradient(VectorState &State, const TClipRectangle &Boun // Standard diamond gradient, where the focal point is the same as the gradient center - const DOUBLE length = 255; + DOUBLE radial_col_span = 255; if (Gradient.Units IS VUNIT::USERSPACE) { if ((Gradient.Flags & VGF::SCALED_RADIUS) != VGF::NIL) { - const DOUBLE scale = length * Gradient.Radius; + const DOUBLE scale = radial_col_span * Gradient.Radius; transform *= agg::trans_affine_scaling(sqrt((c_width * c_width) + (c_height * c_height)) / scale); } else transform *= agg::trans_affine_scaling(Gradient.Radius * 0.01); } else { // Align to vector's bounding box if ((Gradient.Flags & VGF::SCALED_RADIUS) != VGF::NIL) { - // In AGG, an unscaled gradient will cover the entire bounding box according to the diagonal. - // In SVG a radius of 50% must result in the edge of the radius meeting the edge of the bounding box. - - auto scale = agg::point_d(Gradient.Radius * (1.0 / 0.707106781), Gradient.Radius * (1.0 / 0.707106781)); - if (c_height > c_width) scale.y *= c_height / c_width; - else if (c_width > c_height) scale.x *= c_width / c_height; - scale.x *= 100.0 / length; // Adjust the scale according to the gradient length. - scale.y *= 100.0 / length; - transform.scale(scale.x, scale.y); + // Set radial_col_span to the wider of the width/height + if (c_height > c_width) { + radial_col_span = c_height * Gradient.Radius; + transform.scale(c_width / c_height, 1.0); + } + else { + radial_col_span = c_width * Gradient.Radius; + transform.scale(1.0, c_height / c_width); + } } else transform *= agg::trans_affine_scaling(Gradient.Radius * 0.01); } @@ -329,7 +329,7 @@ static void fill_gradient(VectorState &State, const TClipRectangle &Boun agg::gradient_diamond gradient_func; typedef agg::span_gradient span_gradient_type; typedef agg::renderer_scanline_aa renderer_gradient_type; - span_gradient_type span_gradient(span_interpolator, gradient_func, *Table, 0, length); + span_gradient_type span_gradient(span_interpolator, gradient_func, *Table, 0, radial_col_span); renderer_gradient_type solidrender_gradient(RenderBase, span_allocator, span_gradient); transform.translate(c); @@ -359,25 +359,25 @@ static void fill_gradient(VectorState &State, const TClipRectangle &Boun // Standard conic gradient, where the focal point is the same as the gradient center - const DOUBLE length = 255; + DOUBLE radial_col_span = 255; if (Gradient.Units IS VUNIT::USERSPACE) { if ((Gradient.Flags & VGF::SCALED_RADIUS) != VGF::NIL) { - const DOUBLE scale = length * Gradient.Radius; + const DOUBLE scale = radial_col_span * Gradient.Radius; transform *= agg::trans_affine_scaling(sqrt((c_width * c_width) + (c_height * c_height)) / scale); } else transform *= agg::trans_affine_scaling(Gradient.Radius * 0.01); } else { // Bounding box if ((Gradient.Flags & VGF::SCALED_RADIUS) != VGF::NIL) { - // In AGG, an unscaled gradient will cover the entire bounding box according to the diagonal. - // In SVG a radius of 50% must result in the edge of the radius meeting the edge of the bounding box. - - agg::point_d scale(Gradient.Radius * (1.0 / 0.707106781), Gradient.Radius * (1.0 / 0.707106781)); - if (c_height > c_width) scale.y *= c_height / c_width; - else if (c_width > c_height) scale.x *= c_width / c_height; - scale.x *= 100.0 / length; // Adjust the scale according to the gradient length. - scale.y *= 100.0 / length; - transform.scale(scale); + // Set radial_col_span to the wider of the width/height + if (c_height > c_width) { + radial_col_span = c_height * Gradient.Radius; + transform.scale(c_width / c_height, 1.0); + } + else { + radial_col_span = c_width * Gradient.Radius; + transform.scale(1.0, c_height / c_width); + } } else transform *= agg::trans_affine_scaling(Gradient.Radius * 0.01); } @@ -385,7 +385,7 @@ static void fill_gradient(VectorState &State, const TClipRectangle &Boun agg::gradient_conic gradient_func; typedef agg::span_gradient span_gradient_type; typedef agg::renderer_scanline_aa renderer_gradient_type; - span_gradient_type span_gradient(span_interpolator, gradient_func, *Table, 0, length); + span_gradient_type span_gradient(span_interpolator, gradient_func, *Table, 0, radial_col_span); renderer_gradient_type solidrender_gradient(RenderBase, span_allocator, span_gradient); transform.translate(c); From 8b7e6fb980595f669aab0fbb5042e5753c385a9b Mon Sep 17 00:00:00 2001 From: Paul Manias Date: Fri, 6 Dec 2024 17:03:18 +0000 Subject: [PATCH 6/9] [VectorGradient] Added FocalRadius field; Refactoring --- docs/xml/modules/classes/vectorgradient.xml | 43 ++++--- docs/xml/modules/classes/vectorimage.xml | 3 +- docs/xml/modules/classes/vectorscene.xml | 2 +- docs/xml/modules/vector.xml | 4 +- include/parasol/modules/vector.h | 66 ++++++----- src/svg/save_svg.cpp | 4 +- src/vector/defs/gradient.cpp | 66 ++++++++--- src/vector/defs/gradient_def.c | 20 ++-- src/vector/idl.h | 2 +- src/vector/scene/scene_fill.cpp | 118 +++++++++++--------- src/vector/vector.fdl | 11 +- 11 files changed, 209 insertions(+), 130 deletions(-) diff --git a/docs/xml/modules/classes/vectorgradient.xml b/docs/xml/modules/classes/vectorgradient.xml index 6073e902a..938dfbe5b 100644 --- a/docs/xml/modules/classes/vectorgradient.xml +++ b/docs/xml/modules/classes/vectorgradient.xml @@ -58,18 +58,30 @@ - FX - The horizontal focal point for radial gradients. + Flags + Dimension flags are stored here. + Read/Write + VGF + +

Dimension flags that indicate whether field values are fixed or scaled are defined here.

+ +
+
+ + + FocalRadius + The size of the focal radius for radial gradients. Get/Set DOUBLE -

The (FX, FY) coordinates define the focal point for radial gradients. If left undefined, the focal point will match the center of the gradient.

+

If a radial gradient has a defined focal point (by setting FocalX and FocalY) then the FocalRadius can be used to adjust the size of the focal area. The default of zero ensures that the focal area matches that defined by Radius, which is the standard maintained by SVG.

+

The FocalRadius value has no effect if the gradient is linear.

- FY - The vertical focal point for radial gradients. + FocalX + The horizontal focal point for radial gradients. Get/Set DOUBLE @@ -78,13 +90,12 @@ - Flags - Dimension flags are stored here. - Read/Write - VGF + FocalY + The vertical focal point for radial gradients. + Get/Set + DOUBLE -

Dimension flags that indicate whether field values are fixed or scaled are defined here.

- +

The (FX, FY) coordinates define the focal point for radial gradients. If left undefined, the focal point will match the center of the gradient.

@@ -94,7 +105,7 @@ Get/Set STRING -

The ID field is provided for the purpose of SVG support. Where possible we would recommend that you use the existing object name and automatically assigned ID's for identifiers.

+

The ID field is provided for the purpose of SVG support. Where possible, we recommend that you use the existing object name and automatically assigned ID's for identifiers.

@@ -136,7 +147,7 @@ Get/Set DOUBLE -

The radius of the gradient can be defined in fixed units or scaled terms to its container. A default radius of 50% (0.5) applies if this field is not set.

+

The radius of the gradient can be defined as a fixed unit or scaled relative to its container. A default radius of 50% (0.5) applies if this field is not set.

The Radius value has no effect if the gradient is linear.

@@ -147,7 +158,7 @@ Read/Write VSPREAD -

Indicates what happens if the gradient starts or ends inside the bounds of the target vector. The default is VSPREAD::PAD.

+

Indicates what happens if the gradient starts or ends inside the bounds of the target vector. The default is VSPREAD::PAD. Other valid options for gradients are REFLECT and REPEAT.

@@ -259,15 +270,17 @@ CX is fixed CY is fixed + Focal radius is fixed FX is fixed FY is fixed - is fixed + Radius is fixed X1 is fixed X2 is fixed Y1 is fixed Y2 is fixed CX is scaled CY is scaled + Focal radius is scaled FX is scaled FY is scaled Radius is scaled diff --git a/docs/xml/modules/classes/vectorimage.xml b/docs/xml/modules/classes/vectorimage.xml index 6554a9316..bc9037bd4 100644 --- a/docs/xml/modules/classes/vectorimage.xml +++ b/docs/xml/modules/classes/vectorimage.xml @@ -41,7 +41,7 @@ Read/Set *Bitmap -

This field must be set prior to initialisation. It will refer to a source bitmap that will be used by the rendering algorithm.

+

This field must be set prior to initialisation. It will refer to a source bitmap that will be used by the rendering algorithm. The source bitmap must be in a 32-bit graphics format.

@@ -63,6 +63,7 @@ *Picture

If an image bitmap is sourced from a Picture then this field may be used to refer to the Picture object. The picture will not be used directly by the VectorImage, as only the bitmap is of interest.

+

The picture bitmap must be in a 32-bit graphics format.

diff --git a/docs/xml/modules/classes/vectorscene.xml b/docs/xml/modules/classes/vectorscene.xml index f3b889401..a96fd7ec8 100644 --- a/docs/xml/modules/classes/vectorscene.xml +++ b/docs/xml/modules/classes/vectorscene.xml @@ -15,7 +15,7 @@ Paul Manias © 2010-2024

The VectorScene class acts as a container and control point for the management of vector definitions. Its main purpose is to draw the scene to a target Bitmap or Surface provided by the client.

-

Vector scenes are created by initialising multiple Vector objects such as VectorPath and VectorViewport and positioning them within a vector tree. The VectorScene must lie at the root.

+

Vector scenes are created by initialising multiple Vector objects such as VectorPath and VectorViewport and positioning them within a vector tree. The VectorScene must lie at the root of the tree.

The default mode of operation is for scenes to be manually drawn, for which the client must set the target Bitmap and call the Draw action as required. Automated drawing can be enabled by setting the target Surface prior to initialisation. In automated mode the PageWidth and PageHeight will reflect the dimensions of the target surface at all times.

Vector definitions can be saved and loaded from permanent storage by using the SVG class.

diff --git a/docs/xml/modules/vector.xml b/docs/xml/modules/vector.xml index 2a2c3b938..72a29536f 100644 --- a/docs/xml/modules/vector.xml +++ b/docs/xml/modules/vector.xml @@ -810,15 +810,17 @@ Z: Close Path CX is fixed CY is fixed + Focal radius is fixed FX is fixed FY is fixed - is fixed + Radius is fixed X1 is fixed X2 is fixed Y1 is fixed Y2 is fixed CX is scaled CY is scaled + Focal radius is scaled FX is scaled FY is scaled Radius is scaled diff --git a/include/parasol/modules/vector.h b/include/parasol/modules/vector.h index 6618f44dd..1db159ad3 100644 --- a/include/parasol/modules/vector.h +++ b/include/parasol/modules/vector.h @@ -401,15 +401,17 @@ enum class VGF : ULONG { SCALED_FX = 0x00000040, SCALED_FY = 0x00000080, SCALED_RADIUS = 0x00000100, - FIXED_X1 = 0x00000200, - FIXED_Y1 = 0x00000400, - FIXED_X2 = 0x00000800, - FIXED_Y2 = 0x00001000, - FIXED_CX = 0x00002000, - FIXED_CY = 0x00004000, - FIXED_FX = 0x00008000, - FIXED_FY = 0x00010000, - FIXED_RADIUS = 0x00020000, + SCALED_FOCAL_RADIUS = 0x00000200, + FIXED_X1 = 0x00000400, + FIXED_Y1 = 0x00000800, + FIXED_X2 = 0x00001000, + FIXED_Y2 = 0x00002000, + FIXED_CX = 0x00004000, + FIXED_CY = 0x00008000, + FIXED_FX = 0x00010000, + FIXED_FY = 0x00020000, + FIXED_RADIUS = 0x00040000, + FIXED_FOCAL_RADIUS = 0x00080000, }; DEFINE_ENUM_FLAG_OPERATORS(VGF) @@ -941,9 +943,10 @@ class objVectorGradient : public Object { DOUBLE Y2; // Final Y coordinate for the gradient. DOUBLE CenterX; // The horizontal center point of the gradient. DOUBLE CenterY; // The vertical center point of the gradient. - DOUBLE FX; // The horizontal focal point for radial gradients. - DOUBLE FY; // The vertical focal point for radial gradients. + DOUBLE FocalX; // The horizontal focal point for radial gradients. + DOUBLE FocalY; // The vertical focal point for radial gradients. DOUBLE Radius; // The radius of the gradient. + DOUBLE FocalRadius; // The size of the focal radius for radial gradients. objVectorGradient * Inherit; // Inherit attributes from the VectorGradient referenced here. VSPREAD SpreadMethod; // The behaviour to use when the gradient bounds do not match the vector path. VUNIT Units; // Defines the coordinate system for X1, Y1, X2 and Y2. @@ -960,70 +963,77 @@ class objVectorGradient : public Object { inline ERR setX1(const DOUBLE Value) noexcept { auto target = this; - auto field = &this->Class->Dictionary[3]; + auto field = &this->Class->Dictionary[5]; Unit var(Value); return field->WriteValue(target, field, FD_UNIT, &var, 1); } inline ERR setY1(const DOUBLE Value) noexcept { auto target = this; - auto field = &this->Class->Dictionary[5]; + auto field = &this->Class->Dictionary[7]; Unit var(Value); return field->WriteValue(target, field, FD_UNIT, &var, 1); } inline ERR setX2(const DOUBLE Value) noexcept { auto target = this; - auto field = &this->Class->Dictionary[4]; + auto field = &this->Class->Dictionary[6]; Unit var(Value); return field->WriteValue(target, field, FD_UNIT, &var, 1); } inline ERR setY2(const DOUBLE Value) noexcept { auto target = this; - auto field = &this->Class->Dictionary[6]; + auto field = &this->Class->Dictionary[8]; Unit var(Value); return field->WriteValue(target, field, FD_UNIT, &var, 1); } inline ERR setCenterX(const DOUBLE Value) noexcept { auto target = this; - auto field = &this->Class->Dictionary[21]; + auto field = &this->Class->Dictionary[23]; Unit var(Value); return field->WriteValue(target, field, FD_UNIT, &var, 1); } inline ERR setCenterY(const DOUBLE Value) noexcept { auto target = this; - auto field = &this->Class->Dictionary[22]; + auto field = &this->Class->Dictionary[24]; Unit var(Value); return field->WriteValue(target, field, FD_UNIT, &var, 1); } - inline ERR setFX(const DOUBLE Value) noexcept { + inline ERR setFocalX(const DOUBLE Value) noexcept { auto target = this; - auto field = &this->Class->Dictionary[0]; + auto field = &this->Class->Dictionary[28]; Unit var(Value); return field->WriteValue(target, field, FD_UNIT, &var, 1); } - inline ERR setFY(const DOUBLE Value) noexcept { + inline ERR setFocalY(const DOUBLE Value) noexcept { auto target = this; - auto field = &this->Class->Dictionary[1]; + auto field = &this->Class->Dictionary[29]; Unit var(Value); return field->WriteValue(target, field, FD_UNIT, &var, 1); } inline ERR setRadius(const DOUBLE Value) noexcept { auto target = this; - auto field = &this->Class->Dictionary[14]; + auto field = &this->Class->Dictionary[16]; + Unit var(Value); + return field->WriteValue(target, field, FD_UNIT, &var, 1); + } + + inline ERR setFocalRadius(const DOUBLE Value) noexcept { + auto target = this; + auto field = &this->Class->Dictionary[27]; Unit var(Value); return field->WriteValue(target, field, FD_UNIT, &var, 1); } inline ERR setInherit(objVectorGradient * Value) noexcept { auto target = this; - auto field = &this->Class->Dictionary[19]; + auto field = &this->Class->Dictionary[21]; return field->WriteValue(target, field, 0x08000301, Value, 1); } @@ -1057,31 +1067,31 @@ class objVectorGradient : public Object { inline ERR setMatrices(APTR Value) noexcept { auto target = this; - auto field = &this->Class->Dictionary[16]; + auto field = &this->Class->Dictionary[18]; return field->WriteValue(target, field, 0x08000318, Value, 1); } inline ERR setNumeric(const LONG Value) noexcept { auto target = this; - auto field = &this->Class->Dictionary[20]; + auto field = &this->Class->Dictionary[22]; return field->WriteValue(target, field, FD_LONG, &Value, 1); } template inline ERR setID(T && Value) noexcept { auto target = this; - auto field = &this->Class->Dictionary[2]; + auto field = &this->Class->Dictionary[4]; return field->WriteValue(target, field, 0x08800308, to_cstring(Value), 1); } inline ERR setStops(const APTR Value, LONG Elements) noexcept { auto target = this; - auto field = &this->Class->Dictionary[11]; + auto field = &this->Class->Dictionary[13]; return field->WriteValue(target, field, 0x00001318, Value, Elements); } template inline ERR setTransform(T && Value) noexcept { auto target = this; - auto field = &this->Class->Dictionary[15]; + auto field = &this->Class->Dictionary[17]; return field->WriteValue(target, field, 0x08800208, to_cstring(Value), 1); } diff --git a/src/svg/save_svg.cpp b/src/svg/save_svg.cpp index cf1b83ba0..11d6fed2a 100644 --- a/src/svg/save_svg.cpp +++ b/src/svg/save_svg.cpp @@ -96,10 +96,10 @@ static ERR save_svg_defs(extSVG *Self, objXML *XML, objVectorScene *Scene, LONG set_dimension(tag, "cy", gradient->CenterY, (gradient->Flags & VGF::SCALED_CY) != VGF::NIL); if ((error IS ERR::Okay) and ((gradient->Flags & (VGF::FIXED_FX|VGF::SCALED_FX)) != VGF::NIL)) - set_dimension(tag, "fx", gradient->FX, (gradient->Flags & VGF::SCALED_FX) != VGF::NIL); + set_dimension(tag, "fx", gradient->FocalX, (gradient->Flags & VGF::SCALED_FX) != VGF::NIL); if ((error IS ERR::Okay) and ((gradient->Flags & (VGF::FIXED_FY|VGF::SCALED_FY)) != VGF::NIL)) - set_dimension(tag, "fy", gradient->FY, (gradient->Flags & VGF::SCALED_FY) != VGF::NIL); + set_dimension(tag, "fy", gradient->FocalY, (gradient->Flags & VGF::SCALED_FY) != VGF::NIL); if ((error IS ERR::Okay) and ((gradient->Flags & (VGF::FIXED_RADIUS|VGF::SCALED_RADIUS)) != VGF::NIL)) set_dimension(tag, "r", gradient->Radius, (gradient->Flags & VGF::SCALED_RADIUS) != VGF::NIL); diff --git a/src/vector/defs/gradient.cpp b/src/vector/defs/gradient.cpp index f787e1fb1..c0244614b 100644 --- a/src/vector/defs/gradient.cpp +++ b/src/vector/defs/gradient.cpp @@ -260,50 +260,81 @@ Lookup: VGF Dimension flags that indicate whether field values are fixed or scaled are defined here. -FIELD- -FX: The horizontal focal point for radial gradients. +FocalRadius: The size of the focal radius for radial gradients. + +If a radial gradient has a defined focal point (by setting #FocalX and #FocalY) then the FocalRadius can be used to +adjust the size of the focal area. The default of zero ensures that the focal area matches that defined by #Radius, +which is the standard maintained by SVG. + +The FocalRadius value has no effect if the gradient is linear. + +*********************************************************************************************************************/ + +static ERR VECTORGRADIENT_GET_FocalRadius(extVectorGradient *Self, Unit *Value) +{ + Value->set(Self->FocalRadius); + return ERR::Okay; +} + +static ERR VECTORGRADIENT_SET_FocalRadius(extVectorGradient *Self, Unit &Value) +{ + if (Value >= 0) { + if (Value.scaled()) Self->Flags = (Self->Flags | VGF::SCALED_FOCAL_RADIUS) & (~VGF::FIXED_FOCAL_RADIUS); + else Self->Flags = (Self->Flags | VGF::FIXED_FOCAL_RADIUS) & (~VGF::SCALED_FOCAL_RADIUS); + + Self->FocalRadius = Value; + return ERR::Okay; + } + else return ERR::OutOfRange; +} + +/********************************************************************************************************************* + +-FIELD- +FocalX: The horizontal focal point for radial gradients. The `(FX, FY)` coordinates define the focal point for radial gradients. If left undefined, the focal point will match the center of the gradient. *********************************************************************************************************************/ -static ERR VECTORGRADIENT_GET_FX(extVectorGradient *Self, Unit *Value) +static ERR VECTORGRADIENT_GET_FocalX(extVectorGradient *Self, Unit *Value) { - Value->set(Self->FX); + Value->set(Self->FocalX); return ERR::Okay; } -static ERR VECTORGRADIENT_SET_FX(extVectorGradient *Self, Unit &Value) +static ERR VECTORGRADIENT_SET_FocalX(extVectorGradient *Self, Unit &Value) { if (Value.scaled()) Self->Flags = (Self->Flags | VGF::SCALED_FX) & (~VGF::FIXED_FX); else Self->Flags = (Self->Flags | VGF::FIXED_FX) & (~VGF::SCALED_FX); - Self->FX = Value; + Self->FocalX = Value; return ERR::Okay; } /********************************************************************************************************************* -FIELD- -FY: The vertical focal point for radial gradients. +FocalY: The vertical focal point for radial gradients. The `(FX, FY)` coordinates define the focal point for radial gradients. If left undefined, the focal point will match the center of the gradient. *********************************************************************************************************************/ -static ERR VECTORGRADIENT_GET_FY(extVectorGradient *Self, Unit *Value) +static ERR VECTORGRADIENT_GET_FocalY(extVectorGradient *Self, Unit *Value) { - Value->set(Self->FY); + Value->set(Self->FocalY); return ERR::Okay; } -static ERR VECTORGRADIENT_SET_FY(extVectorGradient *Self, Unit &Value) +static ERR VECTORGRADIENT_SET_FocalY(extVectorGradient *Self, Unit &Value) { if (Value.scaled()) Self->Flags = (Self->Flags | VGF::SCALED_FY) & (~VGF::FIXED_FY); else Self->Flags = (Self->Flags | VGF::FIXED_FY) & (~VGF::SCALED_FY); - Self->FY = Value; + Self->FocalY = Value; return ERR::Okay; } @@ -311,7 +342,7 @@ static ERR VECTORGRADIENT_SET_FY(extVectorGradient *Self, Unit &Value) -FIELD- ID: String identifier for a vector. -The ID field is provided for the purpose of SVG support. Where possible we would recommend that you use the +The ID field is provided for the purpose of SVG support. Where possible, we recommend that you use the existing object name and automatically assigned ID's for identifiers. *********************************************************************************************************************/ @@ -438,7 +469,7 @@ static ERR VECTORGRADIENT_SET_NumericID(extVectorGradient *Self, LONG Value) -FIELD- Radius: The radius of the gradient. -The radius of the gradient can be defined in fixed units or scaled terms to its container. A default radius of +The radius of the gradient can be defined as a fixed unit or scaled relative to its container. A default radius of 50% (0.5) applies if this field is not set. The Radius value has no effect if the gradient is linear. @@ -469,7 +500,7 @@ static ERR VECTORGRADIENT_SET_Radius(extVectorGradient *Self, Unit &Value) SpreadMethod: The behaviour to use when the gradient bounds do not match the vector path. Indicates what happens if the gradient starts or ends inside the bounds of the target vector. The default is -`VSPREAD::PAD`. +`VSPREAD::PAD`. Other valid options for gradients are `REFLECT` and `REPEAT`. -FIELD- Stops: Defines the colours to use for the gradient. @@ -676,9 +707,10 @@ static const FieldArray clGradientFields[] = { { "Y2", FDF_UNIT|FDF_DOUBLE|FDF_SCALED|FDF_RW, VECTORGRADIENT_GET_Y2, VECTORGRADIENT_SET_Y2 }, { "CenterX", FDF_UNIT|FDF_DOUBLE|FDF_SCALED|FDF_RW, VECTORGRADIENT_GET_CenterX, VECTORGRADIENT_SET_CenterX }, { "CenterY", FDF_UNIT|FDF_DOUBLE|FDF_SCALED|FDF_RW, VECTORGRADIENT_GET_CenterY, VECTORGRADIENT_SET_CenterY }, - { "FX", FDF_UNIT|FDF_DOUBLE|FDF_SCALED|FDF_RW, VECTORGRADIENT_GET_FX, VECTORGRADIENT_SET_FX }, - { "FY", FDF_UNIT|FDF_DOUBLE|FDF_SCALED|FDF_RW, VECTORGRADIENT_GET_FY, VECTORGRADIENT_SET_FY }, + { "FocalX", FDF_UNIT|FDF_DOUBLE|FDF_SCALED|FDF_RW, VECTORGRADIENT_GET_FocalX, VECTORGRADIENT_SET_FocalX }, + { "FocalY", FDF_UNIT|FDF_DOUBLE|FDF_SCALED|FDF_RW, VECTORGRADIENT_GET_FocalY, VECTORGRADIENT_SET_FocalY }, { "Radius", FDF_UNIT|FDF_DOUBLE|FDF_SCALED|FDF_RW, VECTORGRADIENT_GET_Radius, VECTORGRADIENT_SET_Radius }, + { "FocalRadius", FDF_UNIT|FDF_DOUBLE|FDF_SCALED|FDF_RW, VECTORGRADIENT_GET_FocalRadius, VECTORGRADIENT_SET_FocalRadius }, { "Inherit", FDF_OBJECT|FDF_RW, NULL, VECTORGRADIENT_SET_Inherit }, { "SpreadMethod", FDF_LONG|FDF_LOOKUP|FDF_RW, NULL, NULL, &clVectorGradientSpreadMethod }, { "Units", FDF_LONG|FDF_LOOKUP|FDF_RI, NULL, NULL, &clVectorGradientUnits }, @@ -687,6 +719,10 @@ static const FieldArray clGradientFields[] = { { "ColourSpace", FDF_LONG|FDF_RI, NULL, NULL, &clVectorGradientColourSpace }, { "TotalStops", FDF_LONG|FDF_R }, // Virtual fields + { "CX", FDF_VIRTUAL|FDF_SYNONYM|FDF_UNIT|FDF_DOUBLE|FDF_SCALED|FDF_RW, VECTORGRADIENT_GET_CenterX, VECTORGRADIENT_SET_CenterX }, + { "CY", FDF_VIRTUAL|FDF_SYNONYM|FDF_UNIT|FDF_DOUBLE|FDF_SCALED|FDF_RW, VECTORGRADIENT_GET_CenterY, VECTORGRADIENT_SET_CenterY }, + { "FX", FDF_VIRTUAL|FDF_SYNONYM|FDF_UNIT|FDF_DOUBLE|FDF_SCALED|FDF_RW, VECTORGRADIENT_GET_FocalX, VECTORGRADIENT_SET_FocalX }, + { "FY", FDF_VIRTUAL|FDF_SYNONYM|FDF_UNIT|FDF_DOUBLE|FDF_SCALED|FDF_RW, VECTORGRADIENT_GET_FocalY, VECTORGRADIENT_SET_FocalY }, { "Matrices", FDF_VIRTUAL|FDF_POINTER|FDF_STRUCT|FDF_RW, VECTORGRADIENT_GET_Matrices, VECTORGRADIENT_SET_Matrices, "VectorMatrix" }, { "NumericID", FDF_VIRTUAL|FDF_LONG|FDF_RW, VECTORGRADIENT_GET_NumericID, VECTORGRADIENT_SET_NumericID }, { "ID", FDF_VIRTUAL|FDF_STRING|FDF_RW, VECTORGRADIENT_GET_ID, VECTORGRADIENT_SET_ID }, diff --git a/src/vector/defs/gradient_def.c b/src/vector/defs/gradient_def.c index d2d2e4a3c..82183f190 100644 --- a/src/vector/defs/gradient_def.c +++ b/src/vector/defs/gradient_def.c @@ -37,15 +37,17 @@ static const struct FieldDef clVectorGradientFlags[] = { { "ScaledFX", 0x00000040 }, { "ScaledFY", 0x00000080 }, { "ScaledRadius", 0x00000100 }, - { "FixedX1", 0x00000200 }, - { "FixedY1", 0x00000400 }, - { "FixedX2", 0x00000800 }, - { "FixedY2", 0x00001000 }, - { "FixedCX", 0x00002000 }, - { "FixedCY", 0x00004000 }, - { "FixedFX", 0x00008000 }, - { "FixedFY", 0x00010000 }, - { "FixedRadius", 0x00020000 }, + { "ScaledFocalRadius", 0x00000200 }, + { "FixedX1", 0x00000400 }, + { "FixedY1", 0x00000800 }, + { "FixedX2", 0x00001000 }, + { "FixedY2", 0x00002000 }, + { "FixedCX", 0x00004000 }, + { "FixedCY", 0x00008000 }, + { "FixedFX", 0x00010000 }, + { "FixedFY", 0x00020000 }, + { "FixedRadius", 0x00040000 }, + { "FixedFocalRadius", 0x00080000 }, { NULL, 0 } }; diff --git a/src/vector/idl.h b/src/vector/idl.h index cb51c0287..05dd835dd 100644 --- a/src/vector/idl.h +++ b/src/vector/idl.h @@ -1,2 +1,2 @@ #undef MOD_IDL -#define MOD_IDL "s.GradientStop:dOffset,eRGB:FRGB\ns.Transition:dOffset,sTransform\ns.VectorPoint:dX,dY,ucBit,ucBit\ns.VectorPainter:oPattern,oImage,oGradient,eColour:FRGB\ns.PathCommand:lType,ucLargeArc,ucSweep,ucPad1,dX,dY,dAbsX,dAbsY,dX2,dY2,dX3,dY3,dAngle\ns.VectorMatrix:pNext:VectorMatrix,oVector,dScaleX,dShearY,dShearX,dScaleY,dTranslateX,dTranslateY,lTag\ns.FontMetrics:lHeight,lLineSpacing,lAscent,lDescent\ns.MergeSource:lSourceType,oEffect\nc.ARC:LARGE=0x1,SWEEP=0x2\nc.ARF:MEET=0x40,NONE=0x100,SLICE=0x80,X_MAX=0x4,X_MID=0x2,X_MIN=0x1,Y_MAX=0x20,Y_MID=0x10,Y_MIN=0x8\nc.CM:BRIGHTNESS=0x6,COLOURISE=0x9,CONTRAST=0x5,DESATURATE=0x8,HUE=0x7,HUE_ROTATE=0x3,LUMINANCE_ALPHA=0x4,MATRIX=0x1,NONE=0x0,SATURATE=0x2\nc.CMP:ALL=0xffffffff,ALPHA=0x3,BLUE=0x2,GREEN=0x1,RED=0x0\nc.EM:DUPLICATE=0x1,NONE=0x3,WRAP=0x2\nc.FM:CHILD_HAS_FOCUS=0x4,HAS_FOCUS=0x2,LOST_FOCUS=0x8,PATH_CHANGED=0x1\nc.LS:DISTANT=0x0,POINT=0x2,SPOT=0x1\nc.LT:DIFFUSE=0x0,SPECULAR=0x1\nc.MOP:DILATE=0x1,ERODE=0x0\nc.OP:ARITHMETIC=0x5,ATOP=0x3,BURN=0xe,CONTRAST=0xc,DARKEN=0x9,DIFFERENCE=0x11,DODGE=0xd,EXCLUSION=0x12,HARD_LIGHT=0xf,IN=0x1,INVERT=0xb,INVERT_RGB=0xa,LIGHTEN=0x8,MINUS=0x14,MULTIPLY=0x7,OUT=0x2,OVER=0x0,OVERLAY=0x15,PLUS=0x13,SCREEN=0x6,SOFT_LIGHT=0x10,SUBTRACT=0x14,XOR=0x4\nc.PE:Arc=0x11,ArcRel=0x12,ClosePath=0x13,Curve=0x9,CurveRel=0xa,HLine=0x5,HLineRel=0x6,Line=0x3,LineRel=0x4,Move=0x1,MoveRel=0x2,QuadCurve=0xd,QuadCurveRel=0xe,QuadSmooth=0xf,QuadSmoothRel=0x10,Smooth=0xb,SmoothRel=0xc,VLine=0x7,VLineRel=0x8\nc.RC:ALL=0x7,BASE_PATH=0x2,FINAL_PATH=0x1,TRANSFORM=0x4\nc.RQ:AUTO=0x0,BEST=0x4,CRISP=0x2,FAST=0x1,PRECISE=0x3\nc.TB:NOISE=0x1,TURBULENCE=0x0\nc.VBF:INCLUSIVE=0x1,NO_TRANSFORM=0x2\nc.VCLF:APPLY_FILLS=0x1,APPLY_STROKES=0x2\nc.VCS:INHERIT=0x0,LINEAR_RGB=0x2,SRGB=0x1\nc.VF:DISABLED=0x1,HAS_FOCUS=0x2,JOIN_PATHS=0x4\nc.VFA:MEET=0x0,NONE=0x1\nc.VFR:END=0x4,EVEN_ODD=0x2,INHERIT=0x3,NON_ZERO=0x1\nc.VGF:FIXED_CX=0x2000,FIXED_CY=0x4000,FIXED_FX=0x8000,FIXED_FY=0x10000,FIXED_RADIUS=0x20000,FIXED_X1=0x200,FIXED_X2=0x800,FIXED_Y1=0x400,FIXED_Y2=0x1000,SCALED_CX=0x10,SCALED_CY=0x20,SCALED_FX=0x40,SCALED_FY=0x80,SCALED_RADIUS=0x100,SCALED_X1=0x1,SCALED_X2=0x4,SCALED_Y1=0x2,SCALED_Y2=0x8\nc.VGT:CONIC=0x2,CONTOUR=0x4,DIAMOND=0x3,LINEAR=0x0,RADIAL=0x1\nc.VIJ:BEVEL=0x1,INHERIT=0x5,JAG=0x3,MITER=0x2,ROUND=0x4\nc.VIS:COLLAPSE=0x2,HIDDEN=0x0,INHERIT=0x3,VISIBLE=0x1\nc.VLC:BUTT=0x1,INHERIT=0x4,ROUND=0x3,SQUARE=0x2\nc.VLJ:BEVEL=0x3,INHERIT=0x5,MITER=0x0,MITER_REVERT=0x1,MITER_ROUND=0x4,ROUND=0x2\nc.VMF:AUTO_SPACING=0x2,STRETCH=0x1,X_MAX=0x10,X_MID=0x8,X_MIN=0x4,Y_MAX=0x80,Y_MID=0x40,Y_MIN=0x20\nc.VOF:HIDDEN=0x1,INHERIT=0x3,SCROLL=0x2,VISIBLE=0x0\nc.VPF:BITMAP_SIZED=0x1,OUTLINE_VIEWPORTS=0x8,RENDER_TIME=0x2,RESIZE=0x4\nc.VSM:AUTO=0x0,BESSEL=0x8,BICUBIC=0x3,BILINEAR=0x2,BLACKMAN3=0xc,BLACKMAN8=0xf,GAUSSIAN=0x7,KAISER=0x5,LANCZOS3=0xb,LANCZOS8=0xe,MITCHELL=0x9,NEIGHBOUR=0x1,QUADRIC=0x6,SINC3=0xa,SINC8=0xd,SPLINE16=0x4\nc.VSPREAD:CLIP=0x6,END=0x7,PAD=0x1,REFLECT=0x2,REFLECT_X=0x4,REFLECT_Y=0x5,REPEAT=0x3,UNDEFINED=0x0\nc.VTS:CONDENSED=0x6,EXPANDED=0x8,EXTRA_CONDENSED=0x5,EXTRA_EXPANDED=0xb,INHERIT=0x0,NARROWER=0x3,NORMAL=0x1,SEMI_CONDENSED=0x7,SEMI_EXPANDED=0x9,ULTRA_CONDENSED=0x4,ULTRA_EXPANDED=0xa,WIDER=0x2\nc.VTXF:AREA_SELECTED=0x20,BLINK=0x8,EDIT=0x10,EDITABLE=0x10,LINE_THROUGH=0x4,NO_SYS_KEYS=0x40,OVERLINE=0x2,OVERWRITE=0x80,RASTER=0x200,SECRET=0x100,UNDERLINE=0x1\nc.VUNIT:BOUNDING_BOX=0x1,END=0x3,UNDEFINED=0x0,USERSPACE=0x2\nc.WVC:BOTTOM=0x3,NONE=0x1,TOP=0x2\nc.WVS:ANGLED=0x2,CURVED=0x1,SAWTOOTH=0x3\n" +#define MOD_IDL "s.GradientStop:dOffset,eRGB:FRGB\ns.Transition:dOffset,sTransform\ns.VectorPoint:dX,dY,ucBit,ucBit\ns.VectorPainter:oPattern,oImage,oGradient,eColour:FRGB\ns.PathCommand:lType,ucLargeArc,ucSweep,ucPad1,dX,dY,dAbsX,dAbsY,dX2,dY2,dX3,dY3,dAngle\ns.VectorMatrix:pNext:VectorMatrix,oVector,dScaleX,dShearY,dShearX,dScaleY,dTranslateX,dTranslateY,lTag\ns.FontMetrics:lHeight,lLineSpacing,lAscent,lDescent\ns.MergeSource:lSourceType,oEffect\nc.ARC:LARGE=0x1,SWEEP=0x2\nc.ARF:MEET=0x40,NONE=0x100,SLICE=0x80,X_MAX=0x4,X_MID=0x2,X_MIN=0x1,Y_MAX=0x20,Y_MID=0x10,Y_MIN=0x8\nc.CM:BRIGHTNESS=0x6,COLOURISE=0x9,CONTRAST=0x5,DESATURATE=0x8,HUE=0x7,HUE_ROTATE=0x3,LUMINANCE_ALPHA=0x4,MATRIX=0x1,NONE=0x0,SATURATE=0x2\nc.CMP:ALL=0xffffffff,ALPHA=0x3,BLUE=0x2,GREEN=0x1,RED=0x0\nc.EM:DUPLICATE=0x1,NONE=0x3,WRAP=0x2\nc.FM:CHILD_HAS_FOCUS=0x4,HAS_FOCUS=0x2,LOST_FOCUS=0x8,PATH_CHANGED=0x1\nc.LS:DISTANT=0x0,POINT=0x2,SPOT=0x1\nc.LT:DIFFUSE=0x0,SPECULAR=0x1\nc.MOP:DILATE=0x1,ERODE=0x0\nc.OP:ARITHMETIC=0x5,ATOP=0x3,BURN=0xe,CONTRAST=0xc,DARKEN=0x9,DIFFERENCE=0x11,DODGE=0xd,EXCLUSION=0x12,HARD_LIGHT=0xf,IN=0x1,INVERT=0xb,INVERT_RGB=0xa,LIGHTEN=0x8,MINUS=0x14,MULTIPLY=0x7,OUT=0x2,OVER=0x0,OVERLAY=0x15,PLUS=0x13,SCREEN=0x6,SOFT_LIGHT=0x10,SUBTRACT=0x14,XOR=0x4\nc.PE:Arc=0x11,ArcRel=0x12,ClosePath=0x13,Curve=0x9,CurveRel=0xa,HLine=0x5,HLineRel=0x6,Line=0x3,LineRel=0x4,Move=0x1,MoveRel=0x2,QuadCurve=0xd,QuadCurveRel=0xe,QuadSmooth=0xf,QuadSmoothRel=0x10,Smooth=0xb,SmoothRel=0xc,VLine=0x7,VLineRel=0x8\nc.RC:ALL=0x7,BASE_PATH=0x2,FINAL_PATH=0x1,TRANSFORM=0x4\nc.RQ:AUTO=0x0,BEST=0x4,CRISP=0x2,FAST=0x1,PRECISE=0x3\nc.TB:NOISE=0x1,TURBULENCE=0x0\nc.VBF:INCLUSIVE=0x1,NO_TRANSFORM=0x2\nc.VCLF:APPLY_FILLS=0x1,APPLY_STROKES=0x2\nc.VCS:INHERIT=0x0,LINEAR_RGB=0x2,SRGB=0x1\nc.VF:DISABLED=0x1,HAS_FOCUS=0x2,JOIN_PATHS=0x4\nc.VFA:MEET=0x0,NONE=0x1\nc.VFR:END=0x4,EVEN_ODD=0x2,INHERIT=0x3,NON_ZERO=0x1\nc.VGF:FIXED_CX=0x4000,FIXED_CY=0x8000,FIXED_FOCAL_RADIUS=0x80000,FIXED_FX=0x10000,FIXED_FY=0x20000,FIXED_RADIUS=0x40000,FIXED_X1=0x400,FIXED_X2=0x1000,FIXED_Y1=0x800,FIXED_Y2=0x2000,SCALED_CX=0x10,SCALED_CY=0x20,SCALED_FOCAL_RADIUS=0x200,SCALED_FX=0x40,SCALED_FY=0x80,SCALED_RADIUS=0x100,SCALED_X1=0x1,SCALED_X2=0x4,SCALED_Y1=0x2,SCALED_Y2=0x8\nc.VGT:CONIC=0x2,CONTOUR=0x4,DIAMOND=0x3,LINEAR=0x0,RADIAL=0x1\nc.VIJ:BEVEL=0x1,INHERIT=0x5,JAG=0x3,MITER=0x2,ROUND=0x4\nc.VIS:COLLAPSE=0x2,HIDDEN=0x0,INHERIT=0x3,VISIBLE=0x1\nc.VLC:BUTT=0x1,INHERIT=0x4,ROUND=0x3,SQUARE=0x2\nc.VLJ:BEVEL=0x3,INHERIT=0x5,MITER=0x0,MITER_REVERT=0x1,MITER_ROUND=0x4,ROUND=0x2\nc.VMF:AUTO_SPACING=0x2,STRETCH=0x1,X_MAX=0x10,X_MID=0x8,X_MIN=0x4,Y_MAX=0x80,Y_MID=0x40,Y_MIN=0x20\nc.VOF:HIDDEN=0x1,INHERIT=0x3,SCROLL=0x2,VISIBLE=0x0\nc.VPF:BITMAP_SIZED=0x1,OUTLINE_VIEWPORTS=0x8,RENDER_TIME=0x2,RESIZE=0x4\nc.VSM:AUTO=0x0,BESSEL=0x8,BICUBIC=0x3,BILINEAR=0x2,BLACKMAN3=0xc,BLACKMAN8=0xf,GAUSSIAN=0x7,KAISER=0x5,LANCZOS3=0xb,LANCZOS8=0xe,MITCHELL=0x9,NEIGHBOUR=0x1,QUADRIC=0x6,SINC3=0xa,SINC8=0xd,SPLINE16=0x4\nc.VSPREAD:CLIP=0x6,END=0x7,PAD=0x1,REFLECT=0x2,REFLECT_X=0x4,REFLECT_Y=0x5,REPEAT=0x3,UNDEFINED=0x0\nc.VTS:CONDENSED=0x6,EXPANDED=0x8,EXTRA_CONDENSED=0x5,EXTRA_EXPANDED=0xb,INHERIT=0x0,NARROWER=0x3,NORMAL=0x1,SEMI_CONDENSED=0x7,SEMI_EXPANDED=0x9,ULTRA_CONDENSED=0x4,ULTRA_EXPANDED=0xa,WIDER=0x2\nc.VTXF:AREA_SELECTED=0x20,BLINK=0x8,EDIT=0x10,EDITABLE=0x10,LINE_THROUGH=0x4,NO_SYS_KEYS=0x40,OVERLINE=0x2,OVERWRITE=0x80,RASTER=0x200,SECRET=0x100,UNDERLINE=0x1\nc.VUNIT:BOUNDING_BOX=0x1,END=0x3,UNDEFINED=0x0,USERSPACE=0x2\nc.WVC:BOTTOM=0x3,NONE=0x1,TOP=0x2\nc.WVS:ANGLED=0x2,CURVED=0x1,SAWTOOTH=0x3\n" diff --git a/src/vector/scene/scene_fill.cpp b/src/vector/scene/scene_fill.cpp index 8f5516722..a3a70f15f 100644 --- a/src/vector/scene/scene_fill.cpp +++ b/src/vector/scene/scene_fill.cpp @@ -120,6 +120,24 @@ static void fill_gradient(VectorState &State, const TClipRectangle &Boun const DOUBLE y_offset = Gradient.Units IS VUNIT::USERSPACE ? 0 : Bounds.top; Path->approximation_scale(Transform.scale()); + + auto lambda = [&](S SpreadMethod, DOUBLE Span) { + typedef agg::span_gradient span_gradient_type; + typedef agg::renderer_scanline_aa renderer_gradient_type; + + span_gradient_type span_gradient(span_interpolator, SpreadMethod, *Table, 0, Span); + renderer_gradient_type solidrender_gradient(RenderBase, span_allocator, span_gradient); + + if (State.mClipStack->empty()) { + agg::scanline_u8 scanline; + agg::render_scanlines(Raster, scanline, solidrender_gradient); + } + else { // Masked gradient + agg::alpha_mask_gray8 alpha_mask(State.mClipStack->top().m_renderer); + agg::scanline_u8_am masked_scanline(alpha_mask); + agg::render_scanlines(Raster, masked_scanline, solidrender_gradient); + } + }; if (Gradient.Type IS VGT::LINEAR) { TClipRectangle area; @@ -173,12 +191,12 @@ static void fill_gradient(VectorState &State, const TClipRectangle &Boun if ((Gradient.Flags & VGF::SCALED_CY) != VGF::NIL) c.y = y_offset + (c_height * Gradient.CenterY); else c.y = y_offset + Gradient.CenterY; - if ((Gradient.Flags & VGF::SCALED_FX) != VGF::NIL) f.x = x_offset + (c_width * Gradient.FX); - else if ((Gradient.Flags & VGF::FIXED_FX) != VGF::NIL) f.x = x_offset + Gradient.FX; + if ((Gradient.Flags & VGF::SCALED_FX) != VGF::NIL) f.x = x_offset + (c_width * Gradient.FocalX); + else if ((Gradient.Flags & VGF::FIXED_FX) != VGF::NIL) f.x = x_offset + Gradient.FocalX; else f.x = c.x; - if ((Gradient.Flags & VGF::SCALED_FY) != VGF::NIL) f.y = y_offset + (c_height * Gradient.FY); - else if ((Gradient.Flags & VGF::FIXED_FY) != VGF::NIL) f.y = y_offset + Gradient.FY; + if ((Gradient.Flags & VGF::SCALED_FY) != VGF::NIL) f.y = y_offset + (c_height * Gradient.FocalY); + else if ((Gradient.Flags & VGF::FIXED_FY) != VGF::NIL) f.y = y_offset + Gradient.FocalY; else f.y = c.y; if ((c.x IS f.x) and (c.y IS f.y)) { @@ -212,84 +230,78 @@ static void fill_gradient(VectorState &State, const TClipRectangle &Boun transform.scale(radial_col_span * (1.0 / MIN_SPAN)); radial_col_span = MIN_SPAN; } - - agg::gradient_radial gradient_func; - typedef agg::span_gradient span_gradient_type; - typedef agg::renderer_scanline_aa renderer_gradient_type; - span_gradient_type span_gradient(span_interpolator, gradient_func, *Table, 0, radial_col_span); - renderer_gradient_type solidrender_gradient(RenderBase, span_allocator, span_gradient); - + transform.translate(c.x, c.y); apply_transforms(Gradient, transform); transform *= Transform; transform.invert(); + + agg::gradient_radial gradient_func; - if (State.mClipStack->empty()) { - agg::scanline_u8 scanline; - agg::render_scanlines(Raster, scanline, solidrender_gradient); + if (Gradient.SpreadMethod IS VSPREAD::REFLECT) { + agg::gradient_reflect_adaptor spread_method(gradient_func); + lambda(spread_method, radial_col_span); } - else { // Masked gradient - agg::alpha_mask_gray8 alpha_mask(State.mClipStack->top().m_renderer); - agg::scanline_u8_am masked_scanline(alpha_mask); - - agg::render_scanlines(Raster, masked_scanline, solidrender_gradient); + else if (Gradient.SpreadMethod IS VSPREAD::REPEAT) { + agg::gradient_repeat_adaptor spread_method(gradient_func); + lambda(spread_method, radial_col_span); } + else lambda(gradient_func, radial_col_span); } else { // Radial gradient with a displaced focal point (uses agg::gradient_radial_focus). NB: In early versions of - // the SVG standard, the focal point had to be within the radius. Later specifications allowed it to - // be placed outside of the radius. + // the SVG standard, the focal point had to be within the base radius. Later specifications allowed it to + // be placed outside of that radius. - DOUBLE fix_radius = Gradient.Radius; - if ((Gradient.Flags & VGF::SCALED_RADIUS) != VGF::NIL) { - fix_radius *= (c_width + c_height) * 0.5; // Use the average radius of the ellipse. - } - DOUBLE radial_col_span = fix_radius; + DOUBLE radial_col_span = Gradient.Radius; + DOUBLE focal_radius = Gradient.FocalRadius; + if (focal_radius <= 0) focal_radius = Gradient.Radius; - if (Gradient.Units IS VUNIT::USERSPACE) { - if ((Gradient.Flags & VGF::SCALED_RADIUS) != VGF::NIL) { - const DOUBLE scale = radial_col_span * Gradient.Radius; - transform *= agg::trans_affine_scaling(sqrt((ViewWidth * ViewWidth) + (ViewHeight * ViewHeight)) / scale); + if (Gradient.Units IS VUNIT::USERSPACE) { // Coordinates are relative to the viewport + if ((Gradient.Flags & VGF::SCALED_RADIUS) != VGF::NIL) { // Gradient is a ratio of the viewport's dimensions + radial_col_span = (ViewWidth + ViewHeight) * radial_col_span * 0.5; + focal_radius = (ViewWidth + ViewHeight) * focal_radius * 0.5; } - else transform *= agg::trans_affine_scaling(Gradient.Radius * 0.01); } - else { // Bounding box + else { // Coordinates are scaled to the bounding box if ((Gradient.Flags & VGF::SCALED_RADIUS) != VGF::NIL) { // Set radial_col_span to the wider of the width/height if (c_height > c_width) { - radial_col_span = c_height * Gradient.Radius; - transform.scale(c_width / c_height, 1.0); + radial_col_span = c_height * radial_col_span; + focal_radius = c_height * focal_radius; + transform.scaleX(c_width / c_height); } else { - radial_col_span = c_width * Gradient.Radius; - transform.scale(1.0, c_height / c_width); + radial_col_span = c_width * radial_col_span; + focal_radius = c_width * focal_radius; + transform.scaleY(c_height / c_width); } } - else transform *= agg::trans_affine_scaling(Gradient.Radius * 0.01); + else { + //transform *= agg::trans_affine_scaling(Gradient.Radius * 0.01 / radial_col_span); + } } - agg::gradient_radial_focus gradient_func(fix_radius, f.x - c.x, f.y - c.y); - - typedef agg::span_gradient span_gradient_type; - typedef agg::renderer_scanline_aa renderer_gradient_type; - span_gradient_type span_gradient(span_interpolator, gradient_func, *Table, 0, fix_radius); - renderer_gradient_type solidrender_gradient(RenderBase, span_allocator, span_gradient); + // Changing the focal radius allows the client to increase or decrease the border to which the focal + // calculations are being made. If not supported by the underlying implementation (e.g. SVG) then + // it must match the base radius. - transform.translate(c); + agg::gradient_radial_focus gradient_func(focal_radius, f.x - c.x, f.y - c.y); + + transform.translate(c.x, c.y); apply_transforms(Gradient, transform); transform *= Transform; transform.invert(); - - if (State.mClipStack->empty()) { - agg::scanline_u8 scanline; - agg::render_scanlines(Raster, scanline, solidrender_gradient); + + if (Gradient.SpreadMethod IS VSPREAD::REFLECT) { + agg::gradient_reflect_adaptor spread_method(gradient_func); + lambda(spread_method, radial_col_span); } - else { // Masked gradient - agg::alpha_mask_gray8 alpha_mask(State.mClipStack->top().m_renderer); - agg::scanline_u8_am masked_scanline(alpha_mask); - - agg::render_scanlines(Raster, masked_scanline, solidrender_gradient); + else if (Gradient.SpreadMethod IS VSPREAD::REPEAT) { + agg::gradient_repeat_adaptor spread_method(gradient_func); + lambda(spread_method, radial_col_span); } + else lambda(gradient_func, radial_col_span); } } else if (Gradient.Type IS VGT::DIAMOND) { diff --git a/src/vector/vector.fdl b/src/vector/vector.fdl index bad3aa3c5..71651bd9b 100644 --- a/src/vector/vector.fdl +++ b/src/vector/vector.fdl @@ -226,6 +226,7 @@ module({ name="Vector", copyright="Paul Manias © 2010-2024", version=1.0, times "SCALED_FX: FX is scaled", "SCALED_FY: FY is scaled", "SCALED_RADIUS: Radius is scaled", + "SCALED_FOCAL_RADIUS: Focal radius is scaled", "FIXED_X1: X1 is fixed", "FIXED_Y1: Y1 is fixed", "FIXED_X2: X2 is fixed", @@ -234,7 +235,8 @@ module({ name="Vector", copyright="Paul Manias © 2010-2024", version=1.0, times "FIXED_CY: CY is fixed", "FIXED_FX: FX is fixed", "FIXED_FY: FY is fixed", - "FIXED_RADIUS: is fixed") + "FIXED_RADIUS: Radius is fixed", + "FIXED_FOCAL_RADIUS: Focal radius is fixed") flags("VPF", { comment="Optional flags for the VectorScene object." }, "BITMAP_SIZED: Automatically adjust the @VectorScene.PageWidth and @VectorScene.PageHeight to match the target @Bitmap.Width and @Bitmap.Height.", @@ -444,9 +446,10 @@ module({ name="Vector", copyright="Paul Manias © 2010-2024", version=1.0, times double Y2 # Ending Y of the gradient 'line' double CenterX # Center X coordinate of radial gradient shapes. double CenterY # Center Y coordinate of radial gradient shapes. - double FX # Focal X coordinate for radial gradient shapes. - double FY # Focal Y coordinate for radial gradient shapes. - double Radius # The size of a radial gradient radius. + double FocalX # Focal X coordinate for radial gradient shapes. + double FocalY # Focal Y coordinate for radial gradient shapes. + double Radius # The radius size for radial gradients. + double FocalRadius # The size of the focal radius for radial gradients. obj(VectorGradient) Inherit # Reference to another gradient from which to inherit attributes. int(VSPREAD) SpreadMethod # Defines the spread method to use for gradient fills. int(VUNIT) Units # Defines the coordinate system for `(X1, Y1), (X2, Y2)` From 637f6a57e319da2d73bb38fc00b1d66836cf9a98 Mon Sep 17 00:00:00 2001 From: Paul Manias Date: Fri, 6 Dec 2024 20:39:45 +0000 Subject: [PATCH 7/9] [VectorGradient] Minor refactoring --- .../agg/include/agg_span_gradient_contour.h | 22 ++--- src/vector/defs/gradient.cpp | 10 +-- src/vector/scene/scene_fill.cpp | 90 +++++++------------ 3 files changed, 50 insertions(+), 72 deletions(-) diff --git a/src/vector/agg/include/agg_span_gradient_contour.h b/src/vector/agg/include/agg_span_gradient_contour.h index 4d4c17414..4c5413706 100644 --- a/src/vector/agg/include/agg_span_gradient_contour.h +++ b/src/vector/agg/include/agg_span_gradient_contour.h @@ -83,14 +83,14 @@ namespace agg static AGG_INLINE int square(int x) { return x * x; } // DT algorithm by: Pedro Felzenszwalb - void dt(float *spanf, float *spang, float *spanr, int *spann, int length) + void dt(double *spanf, double *spang, double *spanr, int *spann, int length) { int k = 0; - float s; + double s; spann[0] = 0; - spang[0] = float(-infinity); - spang[1] = float(+infinity); + spang[0] = double(-infinity); + spang[1] = double(+infinity); for (int q = 1; q <= length - 1; q++) { s = ((spanf[q ] + square(q)) - (spanf[spann[k]] + square(spann[k]))) / (2 * q - 2 * spann[k]); @@ -103,7 +103,7 @@ namespace agg k++; spann[k ] = q; spang[k ] = s; - spang[k + 1 ] = float(+infinity); + spang[k + 1 ] = double(+infinity); } k = 0; @@ -155,25 +155,25 @@ namespace agg // II. Distance Transform // Create Float Buffer + 0 vs infinity (1e20) assignment - float *image = new float[width * height]; + double *image = new double[width * height]; if (image) { for (int y=0, l=0; y < height; y++) { for (int x=0; x < width; x++, l++) { if (buffer[l] == 0) image[l] = 0.0; - else image[l] = float(infinity); + else image[l] = double(infinity); } } // DT of 2d - // SubBuff max width,height + // SubBuff max width,height int length = width; if (height > length) length = height; - float *spanf = new float[length]; - float *spang = new float[length + 1]; - float *spanr = new float[length]; + double *spanf = new double[length]; + double *spang = new double[length + 1]; + double *spanr = new double[length]; int *spann = new int[length]; if ((spanf) and (spang) and (spanr) and (spann)) { diff --git a/src/vector/defs/gradient.cpp b/src/vector/defs/gradient.cpp index c0244614b..07c240eb7 100644 --- a/src/vector/defs/gradient.cpp +++ b/src/vector/defs/gradient.cpp @@ -293,8 +293,8 @@ static ERR VECTORGRADIENT_SET_FocalRadius(extVectorGradient *Self, Unit &Value) -FIELD- FocalX: The horizontal focal point for radial gradients. -The `(FX, FY)` coordinates define the focal point for radial gradients. If left undefined, the focal point will match the -center of the gradient. +The `(FocalX, FocalY)` coordinates define the focal point for radial gradients. If left undefined, the focal point +will match the center of the gradient. *********************************************************************************************************************/ @@ -318,8 +318,8 @@ static ERR VECTORGRADIENT_SET_FocalX(extVectorGradient *Self, Unit &Value) -FIELD- FocalY: The vertical focal point for radial gradients. -The `(FX, FY)` coordinates define the focal point for radial gradients. If left undefined, the focal point will match the -center of the gradient. +The `(FocalX, FocalY)` coordinates define the focal point for radial gradients. If left undefined, the focal point +will match the center of the gradient. *********************************************************************************************************************/ @@ -714,7 +714,7 @@ static const FieldArray clGradientFields[] = { { "Inherit", FDF_OBJECT|FDF_RW, NULL, VECTORGRADIENT_SET_Inherit }, { "SpreadMethod", FDF_LONG|FDF_LOOKUP|FDF_RW, NULL, NULL, &clVectorGradientSpreadMethod }, { "Units", FDF_LONG|FDF_LOOKUP|FDF_RI, NULL, NULL, &clVectorGradientUnits }, - { "Type", FDF_LONG|FDF_LOOKUP|FDF_RI, NULL, NULL, &clVectorGradientType }, + { "Type", FDF_LONG|FDF_LOOKUP|FDF_RW, NULL, NULL, &clVectorGradientType }, { "Flags", FDF_LONGFLAGS|FDF_RW, NULL, NULL, &clVectorGradientFlags }, { "ColourSpace", FDF_LONG|FDF_RI, NULL, NULL, &clVectorGradientColourSpace }, { "TotalStops", FDF_LONG|FDF_R }, diff --git a/src/vector/scene/scene_fill.cpp b/src/vector/scene/scene_fill.cpp index a3a70f15f..684ba518e 100644 --- a/src/vector/scene/scene_fill.cpp +++ b/src/vector/scene/scene_fill.cpp @@ -74,7 +74,7 @@ static void fill_image(VectorState &State, const TClipRectangle &Bounds, Path.approximation_scale(Transform.scale()); DOUBLE x_scale, y_scale, x_offset, y_offset; - calc_aspectratio("fill_image", Image.AspectRatio, c_width, c_height, + calc_aspectratio("fill_image", Image.AspectRatio, c_width, c_height, Image.Bitmap->Width, Image.Bitmap->Height, &x_offset, &y_offset, &x_scale, &y_scale); agg::trans_affine transform; @@ -120,8 +120,8 @@ static void fill_gradient(VectorState &State, const TClipRectangle &Boun const DOUBLE y_offset = Gradient.Units IS VUNIT::USERSPACE ? 0 : Bounds.top; Path->approximation_scale(Transform.scale()); - - auto lambda = [&](S SpreadMethod, DOUBLE Span) { + + auto render_gradient = [&](S SpreadMethod, DOUBLE Span) { typedef agg::span_gradient span_gradient_type; typedef agg::renderer_scanline_aa renderer_gradient_type; @@ -213,11 +213,11 @@ static void fill_gradient(VectorState &State, const TClipRectangle &Boun // Set radial_col_span to the wider of the width/height if (c_height > c_width) { radial_col_span = c_height * Gradient.Radius; - transform.scale(c_width / c_height, 1.0); + transform.scaleX(c_width / c_height); } else { radial_col_span = c_width * Gradient.Radius; - transform.scale(1.0, c_height / c_width); + transform.scaleY(c_height / c_width); } } else { @@ -230,23 +230,23 @@ static void fill_gradient(VectorState &State, const TClipRectangle &Boun transform.scale(radial_col_span * (1.0 / MIN_SPAN)); radial_col_span = MIN_SPAN; } - - transform.translate(c.x, c.y); + + transform.translate(c); apply_transforms(Gradient, transform); transform *= Transform; transform.invert(); - + agg::gradient_radial gradient_func; if (Gradient.SpreadMethod IS VSPREAD::REFLECT) { agg::gradient_reflect_adaptor spread_method(gradient_func); - lambda(spread_method, radial_col_span); + render_gradient(spread_method, radial_col_span); } else if (Gradient.SpreadMethod IS VSPREAD::REPEAT) { agg::gradient_repeat_adaptor spread_method(gradient_func); - lambda(spread_method, radial_col_span); + render_gradient(spread_method, radial_col_span); } - else lambda(gradient_func, radial_col_span); + else render_gradient(gradient_func, radial_col_span); } else { // Radial gradient with a displaced focal point (uses agg::gradient_radial_focus). NB: In early versions of @@ -282,26 +282,26 @@ static void fill_gradient(VectorState &State, const TClipRectangle &Boun } } - // Changing the focal radius allows the client to increase or decrease the border to which the focal + // Changing the focal radius allows the client to increase or decrease the border to which the focal // calculations are being made. If not supported by the underlying implementation (e.g. SVG) then // it must match the base radius. agg::gradient_radial_focus gradient_func(focal_radius, f.x - c.x, f.y - c.y); - - transform.translate(c.x, c.y); + + transform.translate(c); apply_transforms(Gradient, transform); transform *= Transform; transform.invert(); - + if (Gradient.SpreadMethod IS VSPREAD::REFLECT) { agg::gradient_reflect_adaptor spread_method(gradient_func); - lambda(spread_method, radial_col_span); + render_gradient(spread_method, radial_col_span); } else if (Gradient.SpreadMethod IS VSPREAD::REPEAT) { agg::gradient_repeat_adaptor spread_method(gradient_func); - lambda(spread_method, radial_col_span); + render_gradient(spread_method, radial_col_span); } - else lambda(gradient_func, radial_col_span); + else render_gradient(gradient_func, radial_col_span); } } else if (Gradient.Type IS VGT::DIAMOND) { @@ -315,11 +315,10 @@ static void fill_gradient(VectorState &State, const TClipRectangle &Boun // Standard diamond gradient, where the focal point is the same as the gradient center - DOUBLE radial_col_span = 255; + DOUBLE radial_col_span = Gradient.Radius; if (Gradient.Units IS VUNIT::USERSPACE) { if ((Gradient.Flags & VGF::SCALED_RADIUS) != VGF::NIL) { - const DOUBLE scale = radial_col_span * Gradient.Radius; - transform *= agg::trans_affine_scaling(sqrt((c_width * c_width) + (c_height * c_height)) / scale); + radial_col_span = (ViewWidth + ViewHeight) * Gradient.Radius * 0.5; } else transform *= agg::trans_affine_scaling(Gradient.Radius * 0.01); } @@ -328,37 +327,32 @@ static void fill_gradient(VectorState &State, const TClipRectangle &Boun // Set radial_col_span to the wider of the width/height if (c_height > c_width) { radial_col_span = c_height * Gradient.Radius; - transform.scale(c_width / c_height, 1.0); + transform.scaleX(c_width / c_height); } else { radial_col_span = c_width * Gradient.Radius; - transform.scale(1.0, c_height / c_width); + transform.scaleY(c_height / c_width); } } else transform *= agg::trans_affine_scaling(Gradient.Radius * 0.01); } agg::gradient_diamond gradient_func; - typedef agg::span_gradient span_gradient_type; - typedef agg::renderer_scanline_aa renderer_gradient_type; - span_gradient_type span_gradient(span_interpolator, gradient_func, *Table, 0, radial_col_span); - renderer_gradient_type solidrender_gradient(RenderBase, span_allocator, span_gradient); transform.translate(c); apply_transforms(Gradient, transform); transform *= Transform; transform.invert(); - if (State.mClipStack->empty()) { - agg::scanline_u8 scanline; - agg::render_scanlines(Raster, scanline, solidrender_gradient); + if (Gradient.SpreadMethod IS VSPREAD::REFLECT) { + agg::gradient_reflect_adaptor spread_method(gradient_func); + render_gradient(spread_method, radial_col_span); } - else { // Masked gradient - agg::alpha_mask_gray8 alpha_mask(State.mClipStack->top().m_renderer); - agg::scanline_u8_am masked_scanline(alpha_mask); - - agg::render_scanlines(Raster, masked_scanline, solidrender_gradient); + else if (Gradient.SpreadMethod IS VSPREAD::REPEAT) { + agg::gradient_repeat_adaptor spread_method(gradient_func); + render_gradient(spread_method, radial_col_span); } + else render_gradient(gradient_func, radial_col_span); } else if (Gradient.Type IS VGT::CONIC) { agg::point_d c; @@ -371,11 +365,10 @@ static void fill_gradient(VectorState &State, const TClipRectangle &Boun // Standard conic gradient, where the focal point is the same as the gradient center - DOUBLE radial_col_span = 255; + DOUBLE radial_col_span = Gradient.Radius; if (Gradient.Units IS VUNIT::USERSPACE) { if ((Gradient.Flags & VGF::SCALED_RADIUS) != VGF::NIL) { - const DOUBLE scale = radial_col_span * Gradient.Radius; - transform *= agg::trans_affine_scaling(sqrt((c_width * c_width) + (c_height * c_height)) / scale); + radial_col_span = (ViewWidth + ViewHeight) * Gradient.Radius * 0.5; } else transform *= agg::trans_affine_scaling(Gradient.Radius * 0.01); } @@ -384,37 +377,23 @@ static void fill_gradient(VectorState &State, const TClipRectangle &Boun // Set radial_col_span to the wider of the width/height if (c_height > c_width) { radial_col_span = c_height * Gradient.Radius; - transform.scale(c_width / c_height, 1.0); + transform.scaleX(c_width / c_height); } else { radial_col_span = c_width * Gradient.Radius; - transform.scale(1.0, c_height / c_width); + transform.scaleY(c_height / c_width); } } else transform *= agg::trans_affine_scaling(Gradient.Radius * 0.01); } agg::gradient_conic gradient_func; - typedef agg::span_gradient span_gradient_type; - typedef agg::renderer_scanline_aa renderer_gradient_type; - span_gradient_type span_gradient(span_interpolator, gradient_func, *Table, 0, radial_col_span); - renderer_gradient_type solidrender_gradient(RenderBase, span_allocator, span_gradient); - transform.translate(c); apply_transforms(Gradient, transform); transform *= Transform; transform.invert(); - if (State.mClipStack->empty()) { - agg::scanline_u8 scanline; - agg::render_scanlines(Raster, scanline, solidrender_gradient); - } - else { // Masked gradient - agg::alpha_mask_gray8 alpha_mask(State.mClipStack->top().m_renderer); - agg::scanline_u8_am masked_scanline(alpha_mask); - - agg::render_scanlines(Raster, masked_scanline, solidrender_gradient); - } + render_gradient(gradient_func, radial_col_span); } else if (Gradient.Type IS VGT::CONTOUR) { // NOTE: Contouring requires a bounding box and is thus incompatible with UserSpaceOnUse if (Gradient.Units != VUNIT::BOUNDING_BOX) return; @@ -445,7 +424,6 @@ static void fill_gradient(VectorState &State, const TClipRectangle &Boun else { // Masked gradient agg::alpha_mask_gray8 alpha_mask(State.mClipStack->top().m_renderer); agg::scanline_u8_am masked_scanline(alpha_mask); - agg::render_scanlines(Raster, masked_scanline, solidrender_gradient); } } From e70a493dcd907d6d0ac792b0523eb69806b466bd Mon Sep 17 00:00:00 2001 From: Paul Manias Date: Fri, 6 Dec 2024 21:34:03 +0000 Subject: [PATCH 8/9] [Scripts] Added new gradients demo script --- examples/gradients.fluid | 146 +++++++++++++++++++++++++++++++++++++ scripts/gui/combobox.fluid | 2 +- 2 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 examples/gradients.fluid diff --git a/examples/gradients.fluid b/examples/gradients.fluid new file mode 100644 index 000000000..07343760e --- /dev/null +++ b/examples/gradients.fluid @@ -0,0 +1,146 @@ +--[[ +Gradient Demonstration + +This is a replica of an AGG demo that was originally built to test focal gradient capabilities. +--]] + + require 'gui/window' + require 'gui/combobox' + + local win, viewport, gradient, gradientVP + local adjust_focal = true, focal_ellipse + +---------------------------------------------------------------------------------------------------------------------- + +function buildScene() + local colours = { { offset=0, r=0, g=255, b=0 }, { offset=0.2, r=120, g=0, b=0 }, { offset=0.7, r=120, g=120, b=0 }, { offset=1, r=0, g=0, b=255 } } + local stops = { } + for _, col in pairs(colours) do + local vc = struct.new('GradientStop') + vc.offset = col.offset + vc.rgb.red = col.r / 255 + vc.rgb.green = col.g / 255 + vc.rgb.blue = col.b / 255 + vc.rgb.alpha = 1.0 + table.insert(stops, vc) + end + + gradient = viewport.scene.new('VectorGradient', { + name = 'focal', type = 'radial', stops = stops, + cX = '50%', cY = '50%', + fX = '50%', fY = '50%', focalRadius = 100, + units = 'boundingbox', radius = 100, + spreadMethod = 'reflect' + }) + + viewport.scene.mtAddDef('focal', gradient) + + gradientVP = viewport.new('VectorViewport', { x = 0, y = 20, width = '100%', height='100%' }) + local rect = gradientVP.new('VectorRectangle', { x = 0, y = 0, width='100%', height='100%', fill='url(#focal)' }) + focal_ellipse = gradientVP.new('VectorEllipse', { + cx ='50%', cy='50%', radius=100, stroke='rgb(255,255,255)', strokeWidth=1 + }) + + local cmbGradient = gui.combobox({ + target = viewport, + label = 'Gradient:', + text = 'Radial', + x = win.margins.left, + y = 10, + items = { + { item='Radial' }, + { item='Conic' }, + { item='Diamond' }, + { item='Contour' } + }, + events = { + activate = function(Widget, Text) + if Text == 'Radial' then + gradient.type = 'radial' + focal_ellipse.visibility = 'visible' + adjust_focal = true + gradient.cX = '50%' + gradient.cY = '50%' + elseif Text == 'Conic' then + focal_ellipse.visibility = 'hidden' + gradient.type = 'conic' + adjust_focal = false + elseif Text == 'Diamond' then + focal_ellipse.visibility = 'hidden' + gradient.type = 'diamond' + adjust_focal = false + elseif Text == 'Contour' then + focal_ellipse.visibility = 'hidden' + gradient.type = 'contour' + adjust_focal = false + end + gradientVP.scene.surface.mtScheduleRedraw() + end + } + }) + + local cmbSpread = gui.combobox({ + target = viewport, + label = 'Spread Method:', + text = 'Reflect', + x = cmbGradient.viewport.x + cmbGradient.viewport.width + 10, + y = 10, + items = { { item='Pad' }, { item='Repeat' }, { item='Reflect' } }, + events = { + activate = function(Widget, Text) + if Text == 'Pad' then + gradient.spreadMethod = VSPREAD_PAD + elseif Text == 'Reflect' then + gradient.spreadMethod = VSPREAD_REFLECT + elseif Text == 'Repeat' then + gradient.spreadMethod = VSPREAD_REPEAT + end + gradientVP.scene.surface.mtScheduleRedraw() + end + } + }) + + gradientVP.y = cmbGradient.viewport.y + cmbGradient.viewport.height + 12 +end + +---------------------------------------------------------------------------------------------------------------------- + + win = gui.window({ title='Focal Gradient Demo', insideWidth=1024, insideHeight=800, center=true }) + viewport = win:clientViewport({ + aspectRatio = ARF_MEET + }) + + buildScene() + + local button_held = false + check(gradientVP.mtSubscribeInput(bit.bor(JTYPE_MOVEMENT, JTYPE_BUTTON, JTYPE_REPEATED), function(Viewport, Events) + local ev = Events + while ev do + if (ev.type == JET_ABS_XY) then + if button_held == 1 then + if adjust_focal then + gradient.fX = (ev.x / gradientVP.width * 100) .. '%' + gradient.fY = (ev.y / gradientVP.height * 100) .. '%' + else + gradient.cX = (ev.x / gradientVP.width * 100) .. '%' + gradient.cY = (ev.y / gradientVP.height * 100) .. '%' + end + gradientVP.scene.surface.mtScheduleRedraw() + end + elseif (ev.type == JET_BUTTON_1) then -- LMB + button_held = ev.value + if adjust_focal then + gradient.fX = (ev.x / gradientVP.width * 100) .. '%' + gradient.fY = (ev.y / gradientVP.height * 100) .. '%' + else + gradient.cX = (ev.x / gradientVP.width * 100) .. '%' + gradient.cY = (ev.y / gradientVP.height * 100) .. '%' + end + gradientVP.scene.surface.mtScheduleRedraw() + end + ev = ev.next + end + end)) + + win:show() + processing.sleep() diff --git a/scripts/gui/combobox.fluid b/scripts/gui/combobox.fluid index f549013e8..449da7bed 100644 --- a/scripts/gui/combobox.fluid +++ b/scripts/gui/combobox.fluid @@ -162,7 +162,7 @@ gui.combobox = function(Options) }) local defaultText = Options.text - if not Options.allowCustom then + if not Options.allowCustom and not defaultText then defaultText = Options.items[1].item end From 694f206c6a72d5cdfcc5a12b0b5617935af5ad0f Mon Sep 17 00:00:00 2001 From: Paul Manias Date: Fri, 6 Dec 2024 22:24:00 +0000 Subject: [PATCH 9/9] [Scripts] Added a gamepad demo script --- examples/data/football.svg | 48 +++++++++++++++++++++++++++++++ examples/gamepad.fluid | 59 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 examples/data/football.svg create mode 100644 examples/gamepad.fluid diff --git a/examples/data/football.svg b/examples/data/football.svg new file mode 100644 index 000000000..790e92869 --- /dev/null +++ b/examples/data/football.svg @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/gamepad.fluid b/examples/gamepad.fluid new file mode 100644 index 000000000..6112dc393 --- /dev/null +++ b/examples/gamepad.fluid @@ -0,0 +1,59 @@ +--[[ +Gamepad demonstration +--]] + + require 'gui/window' + + glSelf = obj.find('self') + glPath = glSelf.workingPath + + local win = gui.window({ title='Gamepad Demo', insideWidth=600, insideHeight=400, center=true, enableControllers=true }) + local viewport = win:clientViewport({ aspectRatio = ARF_MEET }) + + local text = viewport.new('vectortext', { + x=win.margins.left, y=20, string='Use a gamepad to control the football.', face='Noto Sans', fontSize=20, fill='rgb(0,0,0)' + }) + + local txtLeftStick = viewport.new('vectortext', { + x=win.margins.left, y=50, string='Left Stick:', face='Noto Sans', fontSize=20, fill='rgb(0,0,0)' + }) + + local txtRightStick = viewport.new('vectortext', { + x=win.margins.left, y=80, string='Right Stick:', face='Noto Sans', fontSize=20, fill='rgb(0,0,0)' + }) + + local txtButtons = viewport.new('vectortext', { + x=win.margins.left, y=110, string='Buttons:', face='Noto Sans', fontSize=20, fill='rgb(0,0,0)' + }) + + local ballVP = viewport.new('VectorViewport', { + x = 260, y = 260, width = 60, height = 60 + }) + + local svg = obj.new('svg', { target=ballVP, path=glPath .. 'data/football.svg' }) + + local MAX_SPEED = 3 + local ctrl = obj.new('controller', { port=0 }) + local err, controllerTimer = mSys.SubscribeTimer(1/60, function(Subscriber, Elapsed, CurrentTime) + ctrl.acQuery() + + txtLeftStick.string = 'Left Stick: ' .. string.format('%.2f %.2f', ctrl.leftStickX, ctrl.leftStickY) + txtRightStick.string = 'Right Stick: ' .. string.format('%.2f %.2f', ctrl.rightStickX, ctrl.rightStickY) + txtButtons.string = 'Buttons: ' .. string.format('%.8x', ctrl.buttons) + + local speed = MAX_SPEED + if bit.band(ctrl.buttons, CON_GAMEPAD_S) != 0 then + speed = speed * 2 + end + + ballVP.x = ballVP.x + (ctrl.leftStickX * speed) + ballVP.y = ballVP.y - (ctrl.leftStickY * speed) + + ballVP.width = ballVP.width + ctrl.rightStickY + ballVP.height = ballVP.height + ctrl.rightStickY + + viewport.scene.surface.mtScheduleRedraw() + end) + + win:show() + processing.sleep()