add commits..
This commit is contained in:
@@ -25,9 +25,6 @@ WHERE course_id IN (SELECT id FROM target_course);
|
||||
DELETE FROM course_environment_profiles
|
||||
WHERE course_id IN (SELECT id FROM target_course);
|
||||
|
||||
DELETE FROM course_week_visualization_platforms
|
||||
WHERE course_id IN (SELECT id FROM target_course);
|
||||
|
||||
DELETE FROM course_week_maps
|
||||
WHERE course_id IN (SELECT id FROM target_course);
|
||||
|
||||
@@ -153,23 +150,23 @@ WHERE w.course_id IN (SELECT id FROM target_course) AND w.week = 2;
|
||||
WITH module_definitions(category, name, folder_name, template_repository_url, prebuilt_artifacts, default_parameters, docker_image) AS (
|
||||
VALUES
|
||||
('Simulator', 'NAV2-Gazebo', '[lms-nav2-gazebo-simulator]nav2-simulator_v1.0.0_ws', 'http://localhost:3000/templates/lms-nav2-gazebo-simulator.git',
|
||||
jsonb_build_array(jsonb_build_object('url', 'https://pub-ca72c40797144462bdb7d200c215d361.r2.dev/studio-artifacts/modules/lms-nav2-gazebo-simulator/1.0.0/prebuilt/latest/lms-nav2-gazebo-simulator-build-install.tar.zst', 'type', 'build-install', 'fileName', 'lms-nav2-gazebo-simulator-build-install.tar.zst', 'architecture', 'amd64', 'required', false, 'extractPath', '.')), jsonb_build_array('gui:=false'), 'future-nav2-gazebo:humble'),
|
||||
jsonb_build_array(jsonb_build_object('url', 'https://pub-ca72c40797144462bdb7d200c215d361.r2.dev/studio-artifacts/modules/lms-nav2-gazebo-simulator/1.0.0/prebuilt/latest/lms-nav2-gazebo-simulator-build-install.tar.zst', 'type', 'build-install', 'fileName', 'lms-nav2-gazebo-simulator-build-install.tar.zst', 'checksumSha256', '7d2cfe092e81ef15a6e55525410d6f30a803d8c81bee20541dd1d7b964b1fe53', 'architecture', 'amd64', 'required', false, 'extractPath', '.')), jsonb_build_array('gui:=false'), 'future-nav2-gazebo:humble'),
|
||||
('Vehicle', 'NAV2-TurtleBot3Burger', '[lms-nav2-gazebo-vehicle]nav2-vehicle_v1.0.0_ws', 'http://localhost:3000/templates/lms-nav2-gazebo-vehicle.git',
|
||||
jsonb_build_array(jsonb_build_object('url', 'https://pub-ca72c40797144462bdb7d200c215d361.r2.dev/studio-artifacts/modules/lms-nav2-gazebo-vehicle/1.0.0/prebuilt/latest/lms-nav2-gazebo-vehicle-build-install.tar.zst', 'type', 'build-install', 'fileName', 'lms-nav2-gazebo-vehicle-build-install.tar.zst', 'architecture', 'amd64', 'required', false, 'extractPath', '.')), jsonb_build_array('sim_mode:=true', 'platform:=turtlebot3', 'level:=2d'), 'future-nav2-gazebo:humble'),
|
||||
jsonb_build_array(jsonb_build_object('url', 'https://pub-ca72c40797144462bdb7d200c215d361.r2.dev/studio-artifacts/modules/lms-nav2-gazebo-vehicle/1.0.0/prebuilt/latest/lms-nav2-gazebo-vehicle-build-install.tar.zst', 'type', 'build-install', 'fileName', 'lms-nav2-gazebo-vehicle-build-install.tar.zst', 'checksumSha256', '42e8179172c178978e5ae5d48e189164f6b8a5030fdaa0eba497ca86a97e96bb', 'architecture', 'amd64', 'required', false, 'extractPath', '.')), jsonb_build_array('sim_mode:=true', 'platform:=turtlebot3', 'level:=2d'), 'future-nav2-gazebo:humble'),
|
||||
('Map', 'NAV2-Map', '[lms-nav2-gazebo-map]nav2-map_v1.0.0_ws', 'http://localhost:3000/templates/lms-nav2-gazebo-map.git',
|
||||
jsonb_build_array(jsonb_build_object('url', 'https://pub-ca72c40797144462bdb7d200c215d361.r2.dev/studio-artifacts/modules/lms-nav2-gazebo-map/1.0.0/prebuilt/latest/lms-nav2-gazebo-map-build-install.tar.zst', 'type', 'build-install', 'fileName', 'lms-nav2-gazebo-map-build-install.tar.zst', 'architecture', 'amd64', 'required', false, 'extractPath', '.')), '[]'::jsonb, 'future-nav2-gazebo:humble'),
|
||||
jsonb_build_array(jsonb_build_object('url', 'https://pub-ca72c40797144462bdb7d200c215d361.r2.dev/studio-artifacts/modules/lms-nav2-gazebo-map/1.0.0/prebuilt/latest/lms-nav2-gazebo-map-build-install.tar.zst', 'type', 'build-install', 'fileName', 'lms-nav2-gazebo-map-build-install.tar.zst', 'checksumSha256', 'f409ce54c40aeeed8cf3fc06251c2e321887b3ec5f5827dfb74897a62780582f', 'architecture', 'amd64', 'required', false, 'extractPath', '.')), '[]'::jsonb, 'future-nav2-gazebo:humble'),
|
||||
('Localization', 'NAV2-SLAM', '[lms-nav2-gazebo-slam]nav2-slam_v1.0.0_ws', 'http://localhost:3000/templates/lms-nav2-gazebo-slam.git',
|
||||
jsonb_build_array(jsonb_build_object('url', 'https://pub-ca72c40797144462bdb7d200c215d361.r2.dev/studio-artifacts/modules/lms-nav2-gazebo-slam/1.0.0/prebuilt/latest/lms-nav2-gazebo-slam-build-install.tar.zst', 'type', 'build-install', 'fileName', 'lms-nav2-gazebo-slam-build-install.tar.zst', 'architecture', 'amd64', 'required', false, 'extractPath', '.')), '[]'::jsonb, 'future-nav2-gazebo:humble'),
|
||||
jsonb_build_array(jsonb_build_object('url', 'https://pub-ca72c40797144462bdb7d200c215d361.r2.dev/studio-artifacts/modules/lms-nav2-gazebo-slam/1.0.0/prebuilt/latest/lms-nav2-gazebo-slam-build-install.tar.zst', 'type', 'build-install', 'fileName', 'lms-nav2-gazebo-slam-build-install.tar.zst', 'checksumSha256', '186f2aa926eb41140b2783507b521083536aee3be716cf55c591a32250ec0fce', 'architecture', 'amd64', 'required', false, 'extractPath', '.')), '[]'::jsonb, 'future-nav2-gazebo:humble'),
|
||||
('Localization', 'NAV2-Localization', '[lms-nav2-gazebo-localization]nav2-localization_v1.0.0_ws', 'http://localhost:3000/templates/lms-nav2-gazebo-localization.git',
|
||||
jsonb_build_array(jsonb_build_object('url', 'https://pub-ca72c40797144462bdb7d200c215d361.r2.dev/studio-artifacts/modules/lms-nav2-gazebo-localization/1.0.0/prebuilt/latest/lms-nav2-gazebo-localization-build-install.tar.zst', 'type', 'build-install', 'fileName', 'lms-nav2-gazebo-localization-build-install.tar.zst', 'architecture', 'amd64', 'required', false, 'extractPath', '.')), jsonb_build_array('localization_mode:=slam'), 'future-nav2-gazebo:humble'),
|
||||
jsonb_build_array(jsonb_build_object('url', 'https://pub-ca72c40797144462bdb7d200c215d361.r2.dev/studio-artifacts/modules/lms-nav2-gazebo-localization/1.0.0/prebuilt/latest/lms-nav2-gazebo-localization-build-install.tar.zst', 'type', 'build-install', 'fileName', 'lms-nav2-gazebo-localization-build-install.tar.zst', 'checksumSha256', '44c8d50205f001a196870d03f44d435582b96c51eb4445e50cc8db6203b2c0c9', 'architecture', 'amd64', 'required', false, 'extractPath', '.')), jsonb_build_array('localization_mode:=amcl'), 'future-nav2-gazebo:humble'),
|
||||
('Perception', 'NAV2-Perception', '[lms-nav2-gazebo-perception]nav2-perception_v1.0.0_ws', 'http://localhost:3000/templates/lms-nav2-gazebo-perception.git',
|
||||
jsonb_build_array(jsonb_build_object('url', 'https://pub-ca72c40797144462bdb7d200c215d361.r2.dev/studio-artifacts/modules/lms-nav2-gazebo-perception/1.0.0/prebuilt/latest/lms-nav2-gazebo-perception-build-install.tar.zst', 'type', 'build-install', 'fileName', 'lms-nav2-gazebo-perception-build-install.tar.zst', 'architecture', 'amd64', 'required', false, 'extractPath', '.')), jsonb_build_array('sim_mode:=true'), 'future-nav2-gazebo:humble'),
|
||||
jsonb_build_array(jsonb_build_object('url', 'https://pub-ca72c40797144462bdb7d200c215d361.r2.dev/studio-artifacts/modules/lms-nav2-gazebo-perception/1.0.0/prebuilt/latest/lms-nav2-gazebo-perception-build-install.tar.zst', 'type', 'build-install', 'fileName', 'lms-nav2-gazebo-perception-build-install.tar.zst', 'checksumSha256', '23c6523d98506caee9e982741c1c806f9f58581aba777af58eadc7cd5fca1432', 'architecture', 'amd64', 'required', false, 'extractPath', '.')), jsonb_build_array('sim_mode:=true'), 'future-nav2-gazebo:humble'),
|
||||
('Planning', 'NAV2-Planning', '[lms-nav2-gazebo-planning]nav2-planning_v1.0.0_ws', 'http://localhost:3000/templates/lms-nav2-gazebo-planning.git',
|
||||
jsonb_build_array(jsonb_build_object('url', 'https://pub-ca72c40797144462bdb7d200c215d361.r2.dev/studio-artifacts/modules/lms-nav2-gazebo-planning/1.0.0/prebuilt/latest/lms-nav2-gazebo-planning-build-install.tar.zst', 'type', 'build-install', 'fileName', 'lms-nav2-gazebo-planning-build-install.tar.zst', 'architecture', 'amd64', 'required', false, 'extractPath', '.')), '[]'::jsonb, 'future-nav2-gazebo:humble'),
|
||||
jsonb_build_array(jsonb_build_object('url', 'https://pub-ca72c40797144462bdb7d200c215d361.r2.dev/studio-artifacts/modules/lms-nav2-gazebo-planning/1.0.0/prebuilt/latest/lms-nav2-gazebo-planning-build-install.tar.zst', 'type', 'build-install', 'fileName', 'lms-nav2-gazebo-planning-build-install.tar.zst', 'checksumSha256', 'b0c698acf54ef71915e2707868726b998fbdbb2e2ad15fe65cefc931a9afaa78', 'architecture', 'amd64', 'required', false, 'extractPath', '.')), '[]'::jsonb, 'future-nav2-gazebo:humble'),
|
||||
('Control', 'NAV2-Control', '[lms-nav2-gazebo-control]nav2-control_v1.0.0_ws', 'http://localhost:3000/templates/lms-nav2-gazebo-control.git',
|
||||
jsonb_build_array(jsonb_build_object('url', 'https://pub-ca72c40797144462bdb7d200c215d361.r2.dev/studio-artifacts/modules/lms-nav2-gazebo-control/1.0.0/prebuilt/latest/lms-nav2-gazebo-control-build-install.tar.zst', 'type', 'build-install', 'fileName', 'lms-nav2-gazebo-control-build-install.tar.zst', 'architecture', 'amd64', 'required', false, 'extractPath', '.')), jsonb_build_array('sim_mode:=true', 'robot:=turtlebot3', 'level:=2d'), 'future-nav2-gazebo:humble'),
|
||||
jsonb_build_array(jsonb_build_object('url', 'https://pub-ca72c40797144462bdb7d200c215d361.r2.dev/studio-artifacts/modules/lms-nav2-gazebo-control/1.0.0/prebuilt/latest/lms-nav2-gazebo-control-build-install.tar.zst', 'type', 'build-install', 'fileName', 'lms-nav2-gazebo-control-build-install.tar.zst', 'checksumSha256', '63b3b59377c19288f47aa5619fef9b10938f400771df1805d8ca973648ac0ed8', 'architecture', 'amd64', 'required', false, 'extractPath', '.')), jsonb_build_array('sim_mode:=true', 'robot:=turtlebot3', 'level:=2d'), 'future-nav2-gazebo:humble'),
|
||||
('Vehicle', 'NAV2-MKMini', '[lms-nav2-mkmini]nav2-mkmini_v1.0.0_ws', 'http://localhost:3000/templates/lms-nav2-mkmini.git',
|
||||
jsonb_build_array(jsonb_build_object('url', 'https://pub-ca72c40797144462bdb7d200c215d361.r2.dev/studio-artifacts/modules/lms-nav2-mkmini/1.0.0/prebuilt/amd64/lms-nav2-mkmini-build-install-amd64.tar.zst', 'type', 'build-install', 'fileName', 'lms-nav2-mkmini-build-install-amd64.tar.zst', 'checksumSha256', 'a11ac9e920fcbe5c5a54e086b72d453932ece32e0c7976858435c0a0ba73a8f9', 'architecture', 'amd64', 'required', false, 'extractPath', '.')), jsonb_build_array('sim_mode:=false', 'platform:=mkmini', 'robot:=mkmini', 'level:=2d'), 'future-nav2:humble-jetson_orin')
|
||||
jsonb_build_array(jsonb_build_object('url', 'https://pub-ca72c40797144462bdb7d200c215d361.r2.dev/studio-artifacts/modules/lms-nav2-mkmini/1.0.0/prebuilt/amd64/lms-nav2-mkmini-build-install-amd64.tar.zst', 'type', 'build-install', 'fileName', 'lms-nav2-mkmini-build-install-amd64.tar.zst', 'checksumSha256', '6094d2aa5188a28153452aec08e28870984b36c1bc0c06fec8091901f6d26856', 'architecture', 'amd64', 'required', false, 'extractPath', '.')), jsonb_build_array('sim_mode:=false', 'platform:=mkmini', 'level:=2d'), 'future-nav2:humble-jetson_orin')
|
||||
)
|
||||
INSERT INTO course_week_modules (week_id, sort_order, category, name, folder_name, template_repository_url, source_type, prebuilt_artifacts, default_parameters, docker_image)
|
||||
SELECT w.id, row_number() OVER (PARTITION BY w.id ORDER BY module_definitions.folder_name), category, name, folder_name, template_repository_url, 'GIT', prebuilt_artifacts, default_parameters, docker_image
|
||||
@@ -177,19 +174,92 @@ FROM course_weeks w
|
||||
CROSS JOIN module_definitions
|
||||
WHERE w.course_id IN (SELECT id FROM target_course) AND w.week IN (1, 2);
|
||||
|
||||
INSERT INTO course_week_visualization_platforms (course_id, week, platform_key, enabled, created_at, updated_at)
|
||||
SELECT target_course.id, weeks.week, platform.platform_key, true, now(), now()
|
||||
FROM target_course
|
||||
CROSS JOIN (VALUES (1), (2)) AS weeks(week)
|
||||
JOIN visualization_platforms platform ON platform.platform_key IN ('NAV2', 'REAL_SLAM', 'REAL_NAVIGATION');
|
||||
|
||||
INSERT INTO course_environment_profiles (course_id, week, platform_key, profile_type, name, config, enabled, created_at, updated_at)
|
||||
SELECT target_course.id, weeks.week, platform.platform_key, platform.type,
|
||||
CASE WHEN platform.platform_key = 'NAV2' THEN '로컬' ELSE platform.display_name END,
|
||||
platform.default_config, true, now(), now()
|
||||
SELECT target_course.id, weeks.week, environment.platform_key, environment.profile_type,
|
||||
environment.name, environment.config, true, now(), now()
|
||||
FROM target_course
|
||||
CROSS JOIN (VALUES (1), (2)) AS weeks(week)
|
||||
JOIN visualization_platforms platform ON platform.platform_key IN ('NAV2', 'REAL_SLAM', 'REAL_NAVIGATION');
|
||||
CROSS JOIN (
|
||||
VALUES
|
||||
(
|
||||
'NAV2',
|
||||
'NAV2',
|
||||
'로컬',
|
||||
jsonb_build_object(
|
||||
'type', 'NAV2',
|
||||
'target', 'local',
|
||||
'viewer', jsonb_build_object('stack', 'nav2'),
|
||||
'bridge', jsonb_build_object(
|
||||
'name', 'nav2-ros-bridge',
|
||||
'port', 8765,
|
||||
'image', 'slam-ros-bridge:latest',
|
||||
'env', jsonb_build_object('ROBOT_STACK', 'nav2')
|
||||
),
|
||||
'runtimeImages', jsonb_build_array(jsonb_build_object(
|
||||
'url', 'https://pub-ca72c40797144462bdb7d200c215d361.r2.dev/studio-artifacts/runtime-images/nav2/gazebo/latest/future-nav2-gazebo-humble.tar.zst',
|
||||
'image', 'future-nav2-gazebo:humble',
|
||||
'fileName', 'future-nav2-gazebo-humble.tar.zst',
|
||||
'required', true,
|
||||
'checksumSha256', '54230e039c1fa5dc82615cef3828c5acae7b8bea8e921b70cfdc5351d8301644'
|
||||
))
|
||||
)
|
||||
),
|
||||
(
|
||||
'PLATFORM',
|
||||
'PLATFORM',
|
||||
'플랫폼',
|
||||
jsonb_build_object(
|
||||
'type', 'PLATFORM',
|
||||
'target', 'remote-jetson',
|
||||
'runtimeKind', 'real',
|
||||
'viewer', jsonb_build_object('stack', 'nav2'),
|
||||
'bridge', jsonb_build_object(
|
||||
'name', 'nav2-ros-bridge',
|
||||
'port', 8765,
|
||||
'image', 'slam-ros-bridge:latest',
|
||||
'env', jsonb_build_object('ROBOT_STACK', 'nav2')
|
||||
),
|
||||
'runtimeImages', jsonb_build_array(
|
||||
jsonb_build_object(
|
||||
'url', 'https://pub-ca72c40797144462bdb7d200c215d361.r2.dev/studio-artifacts/runtime-images/slam-ros-bridge/latest/slam-ros-bridge-latest.tar.zst',
|
||||
'image', 'slam-ros-bridge:latest',
|
||||
'fileName', 'slam-ros-bridge-latest.tar.zst',
|
||||
'required', true
|
||||
),
|
||||
jsonb_build_object(
|
||||
'url', 'https://pub-ca72c40797144462bdb7d200c215d361.r2.dev/studio-artifacts/runtime-images/nav2/jetson-orin/latest/future-nav2-humble-jetson-orin.tar.zst',
|
||||
'image', 'future-nav2:humble-jetson_orin',
|
||||
'fileName', 'future-nav2-humble-jetson-orin.tar.zst',
|
||||
'required', true
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
) AS environment(platform_key, profile_type, name, config);
|
||||
|
||||
-- Viewer mode belongs to the selected map, not the platform environment.
|
||||
UPDATE course_environment_profiles profile
|
||||
SET config = profile.config::jsonb #- '{viewer,mode}'
|
||||
WHERE profile.course_id IN (SELECT id FROM target_course);
|
||||
|
||||
-- Real-platform modules need the Jetson NAV2 runtime in addition to the
|
||||
-- visualization bridge image. The desktop app downloads this artifact on
|
||||
-- demand before starting a remote module.
|
||||
UPDATE course_environment_profiles profile
|
||||
SET config = jsonb_set(
|
||||
profile.config::jsonb,
|
||||
'{runtimeImages}',
|
||||
COALESCE(profile.config::jsonb->'runtimeImages', '[]'::jsonb) || jsonb_build_array(jsonb_build_object(
|
||||
'url', 'https://pub-ca72c40797144462bdb7d200c215d361.r2.dev/studio-artifacts/runtime-images/nav2/jetson-orin/latest/future-nav2-humble-jetson-orin.tar.zst',
|
||||
'image', 'future-nav2:humble-jetson_orin',
|
||||
'fileName', 'future-nav2-humble-jetson-orin.tar.zst',
|
||||
'required', true
|
||||
)),
|
||||
true
|
||||
)
|
||||
WHERE profile.course_id IN (SELECT id FROM target_course)
|
||||
AND profile.platform_key = 'PLATFORM'
|
||||
AND NOT (COALESCE(profile.config::jsonb->'runtimeImages', '[]'::jsonb) @> '[{"image":"future-nav2:humble-jetson_orin"}]'::jsonb);
|
||||
|
||||
-- Local simulation gets all Gazebo modules. Platform profiles only receive modules applicable to their workflow.
|
||||
UPDATE course_environment_profiles profile
|
||||
@@ -204,19 +274,16 @@ SET config = profile.config::jsonb || jsonb_build_object('moduleSet', jsonb_buil
|
||||
AND week.week = profile.week
|
||||
AND (
|
||||
(profile.platform_key = 'NAV2' AND module.folder_name LIKE '[lms-nav2-gazebo-%')
|
||||
OR (profile.platform_key IN ('REAL_SLAM', 'REAL_NAVIGATION') AND module.folder_name IN (
|
||||
'[lms-nav2-mkmini]nav2-mkmini_v1.0.0_ws',
|
||||
'[lms-nav2-gazebo-map]nav2-map_v1.0.0_ws',
|
||||
'[lms-nav2-gazebo-perception]nav2-perception_v1.0.0_ws',
|
||||
'[lms-nav2-gazebo-localization]nav2-localization_v1.0.0_ws',
|
||||
'[lms-nav2-gazebo-planning]nav2-planning_v1.0.0_ws',
|
||||
'[lms-nav2-gazebo-control]nav2-control_v1.0.0_ws'
|
||||
OR (profile.platform_key = 'PLATFORM' AND module.folder_name NOT IN (
|
||||
'[lms-nav2-gazebo-simulator]nav2-simulator_v1.0.0_ws',
|
||||
'[lms-nav2-gazebo-vehicle]nav2-vehicle_v1.0.0_ws',
|
||||
'[lms-nav2-gazebo-gui]nav2-rviz2_v1.0.0_ws'
|
||||
))
|
||||
)
|
||||
), '[]'::jsonb)
|
||||
))
|
||||
WHERE profile.course_id IN (SELECT id FROM target_course)
|
||||
AND profile.platform_key IN ('NAV2', 'REAL_SLAM', 'REAL_NAVIGATION');
|
||||
AND profile.platform_key IN ('NAV2', 'PLATFORM');
|
||||
|
||||
-- Control runs with TurtleBot3/Gazebo defaults locally, but uses MK-mini and the ARM64 image on a platform.
|
||||
UPDATE course_environment_profiles profile
|
||||
@@ -238,7 +305,30 @@ SET config = jsonb_set(profile.config::jsonb, '{moduleSet,modules}', (
|
||||
) AS control_module
|
||||
), true)
|
||||
WHERE profile.course_id IN (SELECT id FROM target_course)
|
||||
AND profile.platform_key IN ('REAL_SLAM', 'REAL_NAVIGATION');
|
||||
AND profile.platform_key = 'PLATFORM';
|
||||
|
||||
-- The 2D perception module defaults to Gazebo in the course module list.
|
||||
-- Override only that value for the real platform; the other added modules
|
||||
-- retain their own compatible base parameters.
|
||||
UPDATE course_environment_profiles profile
|
||||
SET config = jsonb_set(profile.config::jsonb, '{moduleSet,modules}', (
|
||||
SELECT jsonb_agg(
|
||||
CASE WHEN item->>'id' = perception_module.id::text THEN item || jsonb_build_object(
|
||||
'defaultParameters', jsonb_build_array('sim_mode:=false')
|
||||
) ELSE item END
|
||||
)
|
||||
FROM jsonb_array_elements(profile.config->'moduleSet'->'modules') AS item
|
||||
CROSS JOIN LATERAL (
|
||||
SELECT module.id
|
||||
FROM course_weeks week
|
||||
JOIN course_week_modules module ON module.week_id = week.id
|
||||
WHERE week.course_id = profile.course_id
|
||||
AND week.week = profile.week
|
||||
AND module.name = 'NAV2-Perception'
|
||||
) AS perception_module
|
||||
), true)
|
||||
WHERE profile.course_id IN (SELECT id FROM target_course)
|
||||
AND profile.platform_key = 'PLATFORM';
|
||||
|
||||
INSERT INTO course_week_maps (id, course_id, week, map_key, sort_order, created_at, updated_at)
|
||||
SELECT gen_random_uuid(), target_course.id, weeks.week, map.map_key, map.sort_order, now(), now()
|
||||
|
||||
Reference in New Issue
Block a user