rapid-router 5.4.1__py2.py3-none-any.whl → 7.6.8__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- example_project/rapid_router_test_settings.py +164 -0
- example_project/settings.py +152 -0
- example_project/urls.py +15 -0
- example_project/{example_project/wsgi.py → wsgi.py} +2 -1
- game/__init__.py +1 -1
- game/admin.py +43 -4
- game/app_settings.py +3 -7
- game/character.py +26 -18
- game/decor.py +172 -97
- game/end_to_end_tests/base_game_test.py +44 -33
- game/end_to_end_tests/editor_page.py +17 -2
- game/end_to_end_tests/game_page.py +127 -45
- game/end_to_end_tests/selenium_test_case.py +1 -20
- game/end_to_end_tests/test_cow_crashes.py +3 -5
- game/end_to_end_tests/test_language_dropdown.py +14 -0
- game/end_to_end_tests/test_level_editor.py +290 -0
- game/end_to_end_tests/test_level_failures.py +1 -1
- game/end_to_end_tests/test_level_selection.py +79 -0
- game/end_to_end_tests/test_play_through.py +240 -102
- game/end_to_end_tests/test_python_levels.py +44 -13
- game/end_to_end_tests/test_saving_workspace.py +22 -0
- game/forms.py +9 -2
- game/level_management.py +38 -29
- game/messages.py +1218 -203
- game/migrations/0001_squashed_0025_levels_ordering_pt1.py +19 -1
- game/migrations/0026_levels_pt2.py +13 -2
- game/migrations/0032_cannot_turn_left_level.py +13 -2
- game/migrations/0033_recursion_level.py +13 -2
- game/migrations/0034_joes_level.py +13 -2
- game/migrations/0035_disable_route_score_level_70.py +0 -2
- game/migrations/0036_level_score_73.py +0 -2
- game/migrations/0037_level_score_79.py +0 -2
- game/migrations/0038_level_score_40.py +0 -1
- game/migrations/0042_level_score_73.py +0 -2
- game/migrations/0048_add_cow_field_and_blocks.py +0 -2
- game/migrations/0049_level_score_34.py +0 -2
- game/migrations/0050_level_score_40.py +0 -2
- game/migrations/0051_level_score_49.py +0 -1
- game/migrations/0076_level_locked_for_class.py +19 -0
- game/migrations/0077_alter_level_next_level.py +52 -0
- game/migrations/0078_add_block_types.py +23 -0
- game/migrations/0079_populate_block_type_add_cow_blocks.py +60 -0
- game/migrations/0080_level_disable_algorithm_score.py +18 -0
- game/migrations/0081_first_12_levels_no_algo_score.py +29 -0
- game/migrations/0082_level_43_solution.py +16 -0
- game/migrations/0083_add_cows_to_existing_levels.py +195 -0
- game/migrations/0084_alter_block_block_type.py +18 -0
- game/migrations/0085_add_new_blocks.py +53 -0
- game/migrations/0086_loop_levels.py +482 -0
- game/migrations/0087_workspace_python_view_enabled.py +18 -0
- game/migrations/0088_rename_episodes.py +35 -0
- game/migrations/0089_episodes_in_development.py +30 -0
- game/migrations/0090_add_missing_model_solutions.py +144 -0
- game/migrations/0091_disable_algo_score_if_no_model_solution.py +46 -0
- game/migrations/0092_disable_algo_score_in_custom_levels.py +28 -0
- game/migrations/0093_alter_level_character_name.py +18 -0
- game/migrations/0094_add_hint_lesson_subtitle_to_levels.py +28 -0
- game/migrations/0095_level_commands.py +18 -0
- game/migrations/0096_alter_level_commands.py +18 -0
- game/migrations/0097_add_python_den_levels.py +1515 -0
- game/migrations/0098_add_episode_link_fields.py +44 -0
- game/migrations/0099_python_episodes_links.py +103 -0
- game/migrations/0100_reorder_python_levels.py +179 -0
- game/migrations/0101_rename_episodes.py +45 -0
- game/migrations/0102_reoder_episodes_13_14.py +136 -0
- game/migrations/0103_level_1015_solution.py +26 -0
- game/migrations/0104_remove_level_direct_drive.py +17 -0
- game/migrations/0105_delete_invalid_attempts.py +18 -0
- game/migrations/0106_fields_to_snake_case.py +48 -0
- game/migrations/0107_rename_worksheet_link_episode_student_worksheet_link.py +18 -0
- game/migrations/0108_episode_indy_worksheet_link.py +18 -0
- game/migrations/0109_create_episodes_23_and_24.py +99 -0
- game/migrations/0110_remove_episode_indy_worksheet_link_and_more.py +100 -0
- game/migrations/0111_create_worksheets.py +149 -0
- game/migrations/0112_worksheet_locked_classes.py +21 -0
- game/migrations/0113_level_needs_approval.py +18 -0
- game/migrations/0114_default_and_non_student_levels_no_approval.py +31 -0
- game/migrations/0115_level_level__default_does_not_need_approval.py +22 -0
- game/migrations/0116_update_worksheet_video_links.py +68 -0
- game/migrations/0117_update_solutions_to_if_else.py +61 -0
- game/models.py +157 -16
- game/permissions.py +34 -19
- game/python_den_urls.py +26 -0
- game/random_road.py +43 -127
- game/serializers.py +12 -17
- game/static/django_reverse_js/js/reverse.js +171 -0
- game/static/game/css/LilitaOne-Regular.ttf +0 -0
- game/static/game/css/backgrounds.css +14 -10
- game/static/game/css/dataTables.custom.css +4 -2
- game/static/game/css/dataTables.jqueryui.css +561 -320
- game/static/game/css/editor.css +47 -0
- game/static/game/css/game.css +43 -49
- game/static/game/css/game_screen.css +116 -53
- game/static/game/css/jquery.dataTables.css +455 -251
- game/static/game/css/level_editor.css +10 -1
- game/static/game/css/level_selection.css +32 -3
- game/static/game/css/level_share.css +6 -5
- game/static/game/css/skulpt/codemirror.css +1 -0
- game/static/game/image/Python_Den_hero_student.png +0 -0
- game/static/game/image/Python_levels_page.svg +1954 -0
- game/static/game/image/characters/front_view/Electric_van.svg +448 -0
- game/static/game/image/characters/top_view/Electric_van.svg +448 -0
- game/static/game/image/characters/top_view/Sleigh.svg +436 -0
- game/static/game/image/decor/city/solar_panel.svg +1200 -0
- game/static/game/image/decor/farm/solar_panel.svg +86 -0
- game/static/game/image/decor/grass/solar_panel.svg +86 -0
- game/static/game/image/decor/snow/barn.svg +1788 -0
- game/static/game/image/decor/snow/cfc.svg +1050 -147
- game/static/game/image/decor/snow/crops.svg +7370 -0
- game/static/game/image/decor/snow/hospital.svg +1220 -0
- game/static/game/image/decor/snow/house1.svg +971 -0
- game/static/game/image/decor/snow/house2.svg +1574 -0
- game/static/game/image/decor/snow/school.svg +1071 -0
- game/static/game/image/decor/snow/shop.svg +3211 -0
- game/static/game/image/decor/snow/solar_panel.svg +173 -0
- game/static/game/image/electric_van.svg +448 -0
- game/static/game/image/icons/add_house.svg +26 -0
- game/static/game/image/icons/delete_house.svg +26 -0
- game/static/game/image/icons/description.svg +1 -0
- game/static/game/image/icons/hint.svg +1 -0
- game/static/game/image/icons/if_else.svg +3 -0
- game/static/game/image/icons/python.svg +1 -1
- game/static/game/image/if_else_example.png +0 -0
- game/static/game/image/pigeon.svg +684 -0
- game/static/game/image/python_den_header.svg +19 -0
- game/static/game/js/animation.js +84 -28
- game/static/game/js/blockly/msg/js/bg.js +52 -1
- game/static/game/js/blockly/msg/js/ca.js +52 -1
- game/static/game/js/blockly/msg/js/en-gb.js +52 -1
- game/static/game/js/blockly/msg/js/en.js +52 -1
- game/static/game/js/blockly/msg/js/es.js +52 -1
- game/static/game/js/blockly/msg/js/fr.js +52 -1
- game/static/game/js/blockly/msg/js/hi.js +52 -1
- game/static/game/js/blockly/msg/js/it.js +52 -1
- game/static/game/js/blockly/msg/js/pl.js +52 -1
- game/static/game/js/blockly/msg/js/pt-br.js +52 -1
- game/static/game/js/blockly/msg/js/ru.js +52 -1
- game/static/game/js/blockly/msg/js/ur.js +52 -1
- game/static/game/js/blocklyCompiler.js +550 -392
- game/static/game/js/blocklyControl.js +335 -302
- game/static/game/js/blocklyCustomBlocks.js +691 -458
- game/static/game/js/blocklyCustomisations.js +3 -1
- game/static/game/js/button.js +12 -0
- game/static/game/js/cow.js +15 -130
- game/static/game/js/drawing.js +313 -201
- game/static/game/js/editor.js +23 -0
- game/static/game/js/game.js +148 -139
- game/static/game/js/jquery.dataTables.min.js +3 -159
- game/static/game/js/level_editor.js +823 -448
- game/static/game/js/level_moderation.js +33 -2
- game/static/game/js/level_selection.js +62 -25
- game/static/game/js/loadLanguages.js +21 -0
- game/static/game/js/map.js +106 -36
- game/static/game/js/model.js +55 -107
- game/static/game/js/pathFinder.js +73 -72
- game/static/game/js/program.js +184 -193
- game/static/game/js/pythonControl.js +14 -1
- game/static/game/js/scoreboard.js +0 -37
- game/static/game/js/scoreboardSharedLevels.js +48 -0
- game/static/game/js/sharing.js +22 -10
- game/static/game/js/skulpt/codemirror.js +5 -4
- game/static/game/js/skulpt/skulpt-stdlib.js +1 -1
- game/static/game/js/sound.js +52 -5
- game/static/game/js/van.js +0 -7
- game/static/game/raphael_image/characters/top_view/Electric_van.svg +448 -0
- game/static/game/raphael_image/characters/top_view/Sleigh.svg +436 -0
- game/static/game/raphael_image/decor/city/solar_panel.svg +1200 -0
- game/static/game/raphael_image/decor/farm/solar_panel.svg +86 -0
- game/static/game/raphael_image/decor/grass/solar_panel.svg +86 -0
- game/static/game/raphael_image/decor/snow/barn.svg +1788 -0
- game/static/game/raphael_image/decor/snow/cfc.svg +1050 -147
- game/static/game/raphael_image/decor/snow/crops.svg +7370 -0
- game/static/game/raphael_image/decor/snow/hospital.svg +1220 -0
- game/static/game/raphael_image/decor/snow/house1.svg +971 -0
- game/static/game/raphael_image/decor/snow/house2.svg +1574 -0
- game/static/game/raphael_image/decor/snow/school.svg +1071 -0
- game/static/game/raphael_image/decor/snow/shop.svg +3211 -0
- game/static/game/raphael_image/decor/snow/solar_panel.svg +173 -0
- game/static/game/raphael_image/pigeon.svg +685 -0
- game/static/game/raphael_image/sleigh_wreckage.svg +430 -0
- game/static/game/sass/game.scss +22 -6
- game/static/game/sound/clown_horn.mp3 +0 -0
- game/static/game/sound/clown_horn.ogg +0 -0
- game/static/game/sound/electric_van_starting.mp3 +0 -0
- game/static/game/sound/electric_van_starting.ogg +0 -0
- game/static/game/sound/pigeon.mp3 +0 -0
- game/static/game/sound/pigeon.ogg +0 -0
- game/static/game/sound/sleigh_bells.mp3 +0 -0
- game/static/game/sound/sleigh_bells.ogg +0 -0
- game/static/game/sound/sleigh_crash.mp3 +0 -0
- game/static/game/sound/sleigh_crash.ogg +0 -0
- game/templates/game/base.html +35 -15
- game/templates/game/basenonav.html +23 -17
- game/templates/game/game.html +236 -111
- game/templates/game/level_editor.html +353 -275
- game/templates/game/level_moderation.html +19 -6
- game/templates/game/level_selection.html +75 -62
- game/templates/game/python_den_level_selection.html +291 -0
- game/templates/game/python_den_worksheet.html +101 -0
- game/templates/game/scoreboard.html +88 -65
- game/tests/test_level_editor.py +210 -35
- game/tests/test_level_moderation.py +6 -20
- game/tests/test_level_selection.py +332 -11
- game/tests/test_python_den_worksheet.py +85 -0
- game/tests/test_scoreboard.py +258 -66
- game/tests/utils/level.py +43 -3
- game/tests/utils/teacher.py +2 -2
- game/theme.py +21 -21
- game/urls.py +125 -78
- game/views/language_code_conversions.py +90 -0
- game/views/level.py +201 -63
- game/views/level_editor.py +109 -48
- game/views/level_moderation.py +29 -6
- game/views/level_selection.py +179 -56
- game/views/level_solutions.py +600 -106
- game/views/scoreboard.py +181 -66
- game/views/worksheet.py +25 -0
- rapid_router-7.6.8.dist-info/METADATA +174 -0
- {rapid_router-5.4.1.dist-info → rapid_router-7.6.8.dist-info}/RECORD +222 -242
- {rapid_router-5.4.1.dist-info → rapid_router-7.6.8.dist-info}/WHEEL +1 -1
- rapid_router-7.6.8.dist-info/licenses/LICENSE.md +3 -0
- example_project/example_project/__init__.py +0 -1
- example_project/example_project/settings.py +0 -54
- example_project/example_project/urls.py +0 -16
- example_project/manage.py +0 -10
- game/autoconfig.py +0 -59
- game/csp_config.py +0 -23
- game/locale/ar_SA/LC_MESSAGES/django.mo +0 -0
- game/locale/ar_SA/LC_MESSAGES/django.po +0 -405
- game/locale/ar_SA/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/ar_SA/LC_MESSAGES/djangojs.po +0 -743
- game/locale/bg_BG/LC_MESSAGES/django.mo +0 -0
- game/locale/bg_BG/LC_MESSAGES/django.po +0 -405
- game/locale/bg_BG/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/bg_BG/LC_MESSAGES/djangojs.po +0 -739
- game/locale/ca_ES/LC_MESSAGES/django.mo +0 -0
- game/locale/ca_ES/LC_MESSAGES/django.po +0 -405
- game/locale/ca_ES/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/ca_ES/LC_MESSAGES/djangojs.po +0 -740
- game/locale/cs_CZ/LC_MESSAGES/django.mo +0 -0
- game/locale/cs_CZ/LC_MESSAGES/django.po +0 -405
- game/locale/cs_CZ/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/cs_CZ/LC_MESSAGES/djangojs.po +0 -741
- game/locale/cy_GB/LC_MESSAGES/django.mo +0 -0
- game/locale/cy_GB/LC_MESSAGES/django.po +0 -405
- game/locale/cy_GB/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/cy_GB/LC_MESSAGES/djangojs.po +0 -743
- game/locale/de_DE/LC_MESSAGES/django.mo +0 -0
- game/locale/de_DE/LC_MESSAGES/django.po +0 -405
- game/locale/de_DE/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/de_DE/LC_MESSAGES/djangojs.po +0 -739
- game/locale/el_GR/LC_MESSAGES/django.mo +0 -0
- game/locale/el_GR/LC_MESSAGES/django.po +0 -405
- game/locale/el_GR/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/el_GR/LC_MESSAGES/djangojs.po +0 -739
- game/locale/en_GB/LC_MESSAGES/django.mo +0 -0
- game/locale/en_GB/LC_MESSAGES/django.po +0 -405
- game/locale/en_GB/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/en_GB/LC_MESSAGES/djangojs.po +0 -739
- game/locale/es_ES/LC_MESSAGES/django.mo +0 -0
- game/locale/es_ES/LC_MESSAGES/django.po +0 -405
- game/locale/es_ES/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/es_ES/LC_MESSAGES/djangojs.po +0 -739
- game/locale/fi_FI/LC_MESSAGES/django.mo +0 -0
- game/locale/fi_FI/LC_MESSAGES/django.po +0 -405
- game/locale/fi_FI/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/fi_FI/LC_MESSAGES/djangojs.po +0 -739
- game/locale/fr_FR/LC_MESSAGES/django.mo +0 -0
- game/locale/fr_FR/LC_MESSAGES/django.po +0 -405
- game/locale/fr_FR/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/fr_FR/LC_MESSAGES/djangojs.po +0 -739
- game/locale/gu_IN/LC_MESSAGES/django.mo +0 -0
- game/locale/gu_IN/LC_MESSAGES/django.po +0 -405
- game/locale/gu_IN/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/gu_IN/LC_MESSAGES/djangojs.po +0 -739
- game/locale/hi_IN/LC_MESSAGES/django.mo +0 -0
- game/locale/hi_IN/LC_MESSAGES/django.po +0 -405
- game/locale/hi_IN/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/hi_IN/LC_MESSAGES/djangojs.po +0 -739
- game/locale/id_ID/LC_MESSAGES/django.mo +0 -0
- game/locale/id_ID/LC_MESSAGES/django.po +0 -405
- game/locale/id_ID/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/id_ID/LC_MESSAGES/djangojs.po +0 -738
- game/locale/it_IT/LC_MESSAGES/django.mo +0 -0
- game/locale/it_IT/LC_MESSAGES/django.po +0 -405
- game/locale/it_IT/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/it_IT/LC_MESSAGES/djangojs.po +0 -739
- game/locale/ja_JP/LC_MESSAGES/django.mo +0 -0
- game/locale/ja_JP/LC_MESSAGES/django.po +0 -405
- game/locale/ja_JP/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/ja_JP/LC_MESSAGES/djangojs.po +0 -738
- game/locale/lol_US/LC_MESSAGES/django.mo +0 -0
- game/locale/lol_US/LC_MESSAGES/django.po +0 -405
- game/locale/lol_US/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/lol_US/LC_MESSAGES/djangojs.po +0 -739
- game/locale/nb_NO/LC_MESSAGES/django.mo +0 -0
- game/locale/nb_NO/LC_MESSAGES/django.po +0 -405
- game/locale/nb_NO/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/nb_NO/LC_MESSAGES/djangojs.po +0 -739
- game/locale/nl_NL/LC_MESSAGES/django.mo +0 -0
- game/locale/nl_NL/LC_MESSAGES/django.po +0 -405
- game/locale/nl_NL/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/nl_NL/LC_MESSAGES/djangojs.po +0 -739
- game/locale/pl_PL/LC_MESSAGES/django.mo +0 -0
- game/locale/pl_PL/LC_MESSAGES/django.po +0 -405
- game/locale/pl_PL/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/pl_PL/LC_MESSAGES/djangojs.po +0 -741
- game/locale/pt_BR/LC_MESSAGES/django.mo +0 -0
- game/locale/pt_BR/LC_MESSAGES/django.po +0 -405
- game/locale/pt_BR/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/pt_BR/LC_MESSAGES/djangojs.po +0 -739
- game/locale/pt_PT/LC_MESSAGES/django.mo +0 -0
- game/locale/pt_PT/LC_MESSAGES/django.po +0 -405
- game/locale/pt_PT/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/pt_PT/LC_MESSAGES/djangojs.po +0 -739
- game/locale/ro_RO/LC_MESSAGES/django.mo +0 -0
- game/locale/ro_RO/LC_MESSAGES/django.po +0 -405
- game/locale/ro_RO/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/ro_RO/LC_MESSAGES/djangojs.po +0 -740
- game/locale/ru_RU/LC_MESSAGES/django.mo +0 -0
- game/locale/ru_RU/LC_MESSAGES/django.po +0 -405
- game/locale/ru_RU/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/ru_RU/LC_MESSAGES/djangojs.po +0 -741
- game/locale/sv_SE/LC_MESSAGES/django.mo +0 -0
- game/locale/sv_SE/LC_MESSAGES/django.po +0 -405
- game/locale/sv_SE/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/sv_SE/LC_MESSAGES/djangojs.po +0 -739
- game/locale/tl_PH/LC_MESSAGES/django.mo +0 -0
- game/locale/tl_PH/LC_MESSAGES/django.po +0 -405
- game/locale/tl_PH/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/tl_PH/LC_MESSAGES/djangojs.po +0 -739
- game/locale/tlh_AA/LC_MESSAGES/django.mo +0 -0
- game/locale/tlh_AA/LC_MESSAGES/django.po +0 -405
- game/locale/tlh_AA/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/tlh_AA/LC_MESSAGES/djangojs.po +0 -739
- game/locale/tr_TR/LC_MESSAGES/django.mo +0 -0
- game/locale/tr_TR/LC_MESSAGES/django.po +0 -405
- game/locale/tr_TR/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/tr_TR/LC_MESSAGES/djangojs.po +0 -740
- game/locale/ur_IN/LC_MESSAGES/django.mo +0 -0
- game/locale/ur_IN/LC_MESSAGES/django.po +0 -405
- game/locale/ur_IN/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/ur_IN/LC_MESSAGES/djangojs.po +0 -739
- game/locale/ur_PK/LC_MESSAGES/django.mo +0 -0
- game/locale/ur_PK/LC_MESSAGES/django.po +0 -405
- game/locale/ur_PK/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/ur_PK/LC_MESSAGES/djangojs.po +0 -739
- game/static/game/image/actions/go.svg +0 -18
- game/static/game/image/icons/destination.svg +0 -9
- game/static/game/js/pqselect.min.js +0 -9
- game/static/game/js/widget-scroller.js +0 -906
- rapid_router-5.4.1.dist-info/LICENSE.md +0 -577
- rapid_router-5.4.1.dist-info/METADATA +0 -24
- {rapid_router-5.4.1.dist-info → rapid_router-7.6.8.dist-info}/top_level.txt +0 -0
game/random_road.py
CHANGED
|
@@ -1,20 +1,15 @@
|
|
|
1
1
|
from __future__ import absolute_import
|
|
2
|
-
|
|
3
|
-
from builtins import range
|
|
4
|
-
from past.utils import old_div
|
|
5
|
-
from django.core.cache import cache
|
|
2
|
+
|
|
6
3
|
import json
|
|
7
4
|
import math
|
|
8
5
|
import random
|
|
9
|
-
|
|
10
|
-
from . import level_management
|
|
11
|
-
|
|
6
|
+
from builtins import range
|
|
12
7
|
from collections import defaultdict, namedtuple
|
|
13
|
-
from .models import Level, Block
|
|
14
8
|
|
|
15
9
|
from game.decor import get_decor_element
|
|
16
10
|
from game.theme import get_theme
|
|
17
|
-
|
|
11
|
+
from . import level_management
|
|
12
|
+
from .models import Level, Block
|
|
18
13
|
|
|
19
14
|
Node = namedtuple("Node", ["x", "y"])
|
|
20
15
|
|
|
@@ -53,12 +48,7 @@ def decor_data():
|
|
|
53
48
|
|
|
54
49
|
def decor_sum():
|
|
55
50
|
data = decor_data()
|
|
56
|
-
return
|
|
57
|
-
data["bush"]["ratio"]
|
|
58
|
-
+ data["pond"]["ratio"]
|
|
59
|
-
+ data["tree1"]["ratio"]
|
|
60
|
-
+ data["tree2"]["ratio"]
|
|
61
|
-
)
|
|
51
|
+
return data["bush"]["ratio"] + data["pond"]["ratio"] + data["tree1"]["ratio"] + data["tree2"]["ratio"]
|
|
62
52
|
|
|
63
53
|
|
|
64
54
|
def create(episode=None):
|
|
@@ -68,22 +58,18 @@ def create(episode=None):
|
|
|
68
58
|
loopiness = episode.r_loopiness if episode else DEFAULT_LOOPINESS
|
|
69
59
|
curviness = episode.r_curviness if episode else DEFAULT_CURVINESS
|
|
70
60
|
blocks = episode.r_blocks.all() if episode else Block.objects.all()
|
|
71
|
-
traffic_lights = episode.
|
|
61
|
+
traffic_lights = episode.r_traffic_lights if episode else DEFAULT_TRAFFIC_LIGHTS
|
|
72
62
|
cows = episode.r_cows if episode else DEFAULT_TRAFFIC_LIGHTS
|
|
73
63
|
decor = DEFAULT_DECOR
|
|
74
64
|
|
|
75
|
-
level_data = generate_random_map_data(
|
|
76
|
-
num_tiles, branchiness, loopiness, curviness, traffic_lights, cows, decor
|
|
77
|
-
)
|
|
65
|
+
level_data = generate_random_map_data(num_tiles, branchiness, loopiness, curviness, traffic_lights, cows, decor)
|
|
78
66
|
|
|
79
67
|
level_data["max_fuel"] = DEFAULT_MAX_FUEL
|
|
80
68
|
level_data["theme"] = 1
|
|
81
|
-
level_data["name"] = (
|
|
82
|
-
("Random level for " + episode.name) if episode else "Default random level"
|
|
83
|
-
)
|
|
69
|
+
level_data["name"] = ("Random level for " + episode.name) if episode else "Default random level"
|
|
84
70
|
level_data["character"] = 1
|
|
85
|
-
level_data["
|
|
86
|
-
level_data["
|
|
71
|
+
level_data["blockly_enabled"] = episode.r_blockly_enabled if episode else True
|
|
72
|
+
level_data["python_enabled"] = episode.r_python_enabled if episode else False
|
|
87
73
|
level_data["blocks"] = [{"type": block.type} for block in blocks]
|
|
88
74
|
|
|
89
75
|
level = Level(default=False, anonymous=True)
|
|
@@ -93,13 +79,7 @@ def create(episode=None):
|
|
|
93
79
|
|
|
94
80
|
|
|
95
81
|
def generate_random_map_data(
|
|
96
|
-
num_tiles,
|
|
97
|
-
branchiness,
|
|
98
|
-
loopiness,
|
|
99
|
-
curviness,
|
|
100
|
-
traffic_lights_enabled,
|
|
101
|
-
decor_enabled,
|
|
102
|
-
cows_enabled,
|
|
82
|
+
num_tiles, branchiness, loopiness, curviness, traffic_lights_enabled, decor_enabled, cows_enabled
|
|
103
83
|
):
|
|
104
84
|
path = generate_random_path(num_tiles, branchiness, loopiness, curviness)
|
|
105
85
|
traffic_lights = generate_traffic_lights(path) if traffic_lights_enabled else []
|
|
@@ -118,9 +98,7 @@ def generate_random_map_data(
|
|
|
118
98
|
}
|
|
119
99
|
|
|
120
100
|
|
|
121
|
-
def generate_random_path(
|
|
122
|
-
num_road_tiles, branchiness_factor, loopiness_factor, curviness_factor
|
|
123
|
-
):
|
|
101
|
+
def generate_random_path(num_road_tiles, branchiness_factor, loopiness_factor, curviness_factor):
|
|
124
102
|
def pick_adjacent_node(nodes, connections, branchiness_factor, curviness_factor):
|
|
125
103
|
for attempts in range(5):
|
|
126
104
|
origin = pick_origin_node(nodes, connections, branchiness_factor)
|
|
@@ -134,12 +112,7 @@ def generate_random_path(
|
|
|
134
112
|
possibles.append(node)
|
|
135
113
|
|
|
136
114
|
if possibles:
|
|
137
|
-
return (
|
|
138
|
-
origin,
|
|
139
|
-
pick_destination_node(
|
|
140
|
-
nodes, connections, origin, possibles, curviness_factor
|
|
141
|
-
),
|
|
142
|
-
)
|
|
115
|
+
return (origin, pick_destination_node(nodes, connections, origin, possibles, curviness_factor))
|
|
143
116
|
|
|
144
117
|
return None, None
|
|
145
118
|
|
|
@@ -150,22 +123,13 @@ def generate_random_path(
|
|
|
150
123
|
return nodes[-1]
|
|
151
124
|
|
|
152
125
|
def pick_destination_node(nodes, connections, origin, possibles, curviness_factor):
|
|
153
|
-
existing_connections = [
|
|
154
|
-
|
|
155
|
-
]
|
|
156
|
-
existing_connection_directions = [
|
|
157
|
-
(node.x - origin.x, node.y - origin.y) for node in existing_connections
|
|
158
|
-
]
|
|
126
|
+
existing_connections = [nodes[nodeIndex] for nodeIndex in connections[nodes.index(origin)]]
|
|
127
|
+
existing_connection_directions = [(node.x - origin.x, node.y - origin.y) for node in existing_connections]
|
|
159
128
|
linear = [
|
|
160
|
-
node
|
|
161
|
-
for node in possibles
|
|
162
|
-
if (origin.x - node.x, origin.y - node.y) in existing_connection_directions
|
|
129
|
+
node for node in possibles if (origin.x - node.x, origin.y - node.y) in existing_connection_directions
|
|
163
130
|
]
|
|
164
131
|
curved = [
|
|
165
|
-
node
|
|
166
|
-
for node in possibles
|
|
167
|
-
if (origin.x - node.x, origin.y - node.y)
|
|
168
|
-
not in existing_connection_directions
|
|
132
|
+
node for node in possibles if (origin.x - node.x, origin.y - node.y) not in existing_connection_directions
|
|
169
133
|
]
|
|
170
134
|
|
|
171
135
|
if linear and curved:
|
|
@@ -179,9 +143,7 @@ def generate_random_path(
|
|
|
179
143
|
return random.choice(pick_from)
|
|
180
144
|
|
|
181
145
|
def join_up_loops(nodes, connections, loopiness_factor):
|
|
182
|
-
nodes_by_location = {
|
|
183
|
-
(node.x, node.y): (index, node) for index, node in enumerate(nodes)
|
|
184
|
-
}
|
|
146
|
+
nodes_by_location = {(node.x, node.y): (index, node) for index, node in enumerate(nodes)}
|
|
185
147
|
n = len(nodes)
|
|
186
148
|
|
|
187
149
|
# Floyd-Warshall algorithm to find distances between all nodes
|
|
@@ -211,10 +173,7 @@ def generate_random_path(
|
|
|
211
173
|
for location in get_neighbouring_locations(node):
|
|
212
174
|
if location in nodes_by_location:
|
|
213
175
|
adjacent_node_index, adjacent_node = nodes_by_location[location]
|
|
214
|
-
if
|
|
215
|
-
adjacent_node_index > node_index
|
|
216
|
-
and adjacent_node != nodes[0]
|
|
217
|
-
):
|
|
176
|
+
if adjacent_node_index > node_index and adjacent_node != nodes[0]:
|
|
218
177
|
if adjacent_node_index not in connections[node_index]:
|
|
219
178
|
possible_loops.append((node_index, adjacent_node_index))
|
|
220
179
|
|
|
@@ -227,7 +186,7 @@ def generate_random_path(
|
|
|
227
186
|
# Now join up loops (does not dynamically update distances, but still get required effect)
|
|
228
187
|
max_loop_distance = max([distances[s][d] for s, d in possible_loops])
|
|
229
188
|
for origin, destination in possible_loops:
|
|
230
|
-
distance_factor =
|
|
189
|
+
distance_factor = distances[origin][destination] // max_loop_distance
|
|
231
190
|
adjusted_loopiness_factor = loopiness_factor * (
|
|
232
191
|
(1 - loopiness_deviation) + loopiness_deviation * distance_factor
|
|
233
192
|
)
|
|
@@ -251,9 +210,7 @@ def generate_random_path(
|
|
|
251
210
|
return math.atan2(node_2.y - node_1.y, node_2.x - node_1.x)
|
|
252
211
|
|
|
253
212
|
def is_possible(node, nodes):
|
|
254
|
-
return (
|
|
255
|
-
(node not in nodes) and 0 < node.x < WIDTH - 1 and 0 < node.y < HEIGHT - 1
|
|
256
|
-
)
|
|
213
|
+
return (node not in nodes) and 0 < node.x < WIDTH - 1 and 0 < node.y < HEIGHT - 1
|
|
257
214
|
|
|
258
215
|
def get_neighbouring_locations(node):
|
|
259
216
|
squares = []
|
|
@@ -270,15 +227,11 @@ def generate_random_path(
|
|
|
270
227
|
connections = defaultdict(list)
|
|
271
228
|
|
|
272
229
|
for _ in range(num_road_tiles - 1):
|
|
273
|
-
(previous_node, new_node) = pick_adjacent_node(
|
|
274
|
-
nodes, connections, branchiness_factor, curviness_factor
|
|
275
|
-
)
|
|
230
|
+
(previous_node, new_node) = pick_adjacent_node(nodes, connections, branchiness_factor, curviness_factor)
|
|
276
231
|
if new_node:
|
|
277
232
|
nodes.append(new_node)
|
|
278
233
|
index_by_node[new_node] = len(nodes) - 1
|
|
279
|
-
connections = add_new_connections(
|
|
280
|
-
connections, len(nodes) - 1, index_by_node[previous_node]
|
|
281
|
-
)
|
|
234
|
+
connections = add_new_connections(connections, len(nodes) - 1, index_by_node[previous_node])
|
|
282
235
|
|
|
283
236
|
connections = join_up_loops(nodes, connections, loopiness_factor)
|
|
284
237
|
result = []
|
|
@@ -287,9 +240,7 @@ def generate_random_path(
|
|
|
287
240
|
{
|
|
288
241
|
"coordinate": node,
|
|
289
242
|
"connectedNodes": sorted(
|
|
290
|
-
connections[index],
|
|
291
|
-
key=lambda conn: calculate_node_angle(node, nodes[conn]),
|
|
292
|
-
reverse=True,
|
|
243
|
+
connections[index], key=lambda conn: calculate_node_angle(node, nodes[conn]), reverse=True
|
|
293
244
|
),
|
|
294
245
|
}
|
|
295
246
|
)
|
|
@@ -301,10 +252,7 @@ def get_origin(path):
|
|
|
301
252
|
node = path[1]
|
|
302
253
|
neighbour = path[0]
|
|
303
254
|
direction = get_direction(node, neighbour)
|
|
304
|
-
return {
|
|
305
|
-
"coordinate": [neighbour["coordinate"].x, neighbour["coordinate"].y],
|
|
306
|
-
"direction": direction,
|
|
307
|
-
}
|
|
255
|
+
return {"coordinate": [neighbour["coordinate"].x, neighbour["coordinate"].y], "direction": direction}
|
|
308
256
|
|
|
309
257
|
|
|
310
258
|
def generate_traffic_lights(path):
|
|
@@ -323,15 +271,12 @@ def generate_traffic_lights(path):
|
|
|
323
271
|
else:
|
|
324
272
|
candidateNodes = degree2Nodes
|
|
325
273
|
|
|
326
|
-
numberOfJunctions = max(
|
|
327
|
-
int(len(candidateNodes) * PERCENTAGE_OF_JUNCTIONS_WITH_TRAFFIC_LIGHTS / 100.0),
|
|
328
|
-
1,
|
|
329
|
-
)
|
|
274
|
+
numberOfJunctions = max(int(len(candidateNodes) * PERCENTAGE_OF_JUNCTIONS_WITH_TRAFFIC_LIGHTS / 100.0), 1)
|
|
330
275
|
|
|
331
276
|
random.shuffle(candidateNodes)
|
|
332
277
|
nodesSelected = candidateNodes[:numberOfJunctions]
|
|
333
278
|
|
|
334
|
-
|
|
279
|
+
traffic_lights = []
|
|
335
280
|
for node in nodesSelected:
|
|
336
281
|
|
|
337
282
|
controlledNeighbours = []
|
|
@@ -346,12 +291,9 @@ def generate_traffic_lights(path):
|
|
|
346
291
|
|
|
347
292
|
direction = get_direction(node, neighbour)
|
|
348
293
|
|
|
349
|
-
|
|
294
|
+
traffic_lights.append(
|
|
350
295
|
{
|
|
351
|
-
"sourceCoordinate": {
|
|
352
|
-
"x": neighbour["coordinate"].x,
|
|
353
|
-
"y": neighbour["coordinate"].y,
|
|
354
|
-
},
|
|
296
|
+
"sourceCoordinate": {"x": neighbour["coordinate"].x, "y": neighbour["coordinate"].y},
|
|
355
297
|
"direction": direction,
|
|
356
298
|
"startTime": 0 if counter == 0 else 2 * (counter - 1),
|
|
357
299
|
"startingState": "GREEN" if counter == 0 else "RED",
|
|
@@ -361,7 +303,7 @@ def generate_traffic_lights(path):
|
|
|
361
303
|
)
|
|
362
304
|
counter += 1
|
|
363
305
|
|
|
364
|
-
return
|
|
306
|
+
return traffic_lights
|
|
365
307
|
|
|
366
308
|
|
|
367
309
|
def generate_cows(path):
|
|
@@ -388,11 +330,7 @@ def generate_decor(path, num_tiles):
|
|
|
388
330
|
def find_node_by_coordinate(x, y, dec, nodes):
|
|
389
331
|
for node in nodes:
|
|
390
332
|
coord = node["coordinate"]
|
|
391
|
-
if (
|
|
392
|
-
coord.x == x
|
|
393
|
-
and coord.y == y
|
|
394
|
-
or (dec == "pond" and coord.x == x + 1 and coord.y == y)
|
|
395
|
-
):
|
|
333
|
+
if coord.x == x and coord.y == y or (dec == "pond" and coord.x == x + 1 and coord.y == y):
|
|
396
334
|
return True
|
|
397
335
|
return False
|
|
398
336
|
|
|
@@ -402,21 +340,13 @@ def generate_decor(path, num_tiles):
|
|
|
402
340
|
|
|
403
341
|
# if there is a decor occupying this grid or neighbouring one in case of the pond
|
|
404
342
|
if (
|
|
405
|
-
|
|
406
|
-
and
|
|
343
|
+
coord["x"] // GRID_SIZE == x
|
|
344
|
+
and coord["y"] // GRID_SIZE == y
|
|
407
345
|
or (
|
|
408
346
|
elem == "pond"
|
|
409
|
-
and (
|
|
410
|
-
old_div(coord["x"], GRID_SIZE) == x + 1
|
|
411
|
-
and old_div(coord["y"], GRID_SIZE) == y
|
|
412
|
-
or x + 1 < WIDTH
|
|
413
|
-
)
|
|
414
|
-
)
|
|
415
|
-
or (
|
|
416
|
-
dec["decorName"] == "pond"
|
|
417
|
-
and old_div(coord["x"], GRID_SIZE) + 1 == x
|
|
418
|
-
and old_div(coord["y"], GRID_SIZE) == y
|
|
347
|
+
and (coord["x"] // GRID_SIZE == x + 1 and coord["y"] // GRID_SIZE == y or x + 1 < WIDTH)
|
|
419
348
|
)
|
|
349
|
+
or (dec["decor_name"] == "pond" and coord["x"] // GRID_SIZE + 1 == x and coord["y"] // GRID_SIZE == y)
|
|
420
350
|
):
|
|
421
351
|
return True
|
|
422
352
|
|
|
@@ -438,13 +368,7 @@ def generate_decor(path, num_tiles):
|
|
|
438
368
|
x = x * GRID_SIZE + int((GRID_SIZE - decor_object.width) * 0.5 * (1 - dx))
|
|
439
369
|
y = y * GRID_SIZE + int((GRID_SIZE - decor_object.height) * 0.5 * (1 - dy))
|
|
440
370
|
|
|
441
|
-
decor.append(
|
|
442
|
-
{
|
|
443
|
-
"coordinate": {"x": x, "y": y},
|
|
444
|
-
"decorName": dec,
|
|
445
|
-
"height": decor_object.height,
|
|
446
|
-
}
|
|
447
|
-
)
|
|
371
|
+
decor.append({"coordinate": {"x": x, "y": y}, "decor_name": dec, "height": decor_object.height})
|
|
448
372
|
|
|
449
373
|
def place_near_road(elem, decor, path):
|
|
450
374
|
for i in range(1, len(path) - 1):
|
|
@@ -452,33 +376,25 @@ def generate_decor(path, num_tiles):
|
|
|
452
376
|
for (dx, dy) in DIRECTIONS:
|
|
453
377
|
x = node["coordinate"].x + dx
|
|
454
378
|
y = node["coordinate"].y + dy
|
|
455
|
-
if not (
|
|
456
|
-
find_decor_by_coordinate(x, y, elem, decor)
|
|
457
|
-
or find_node_by_coordinate(x, y, dec, path)
|
|
458
|
-
):
|
|
379
|
+
if not (find_decor_by_coordinate(x, y, elem, decor) or find_node_by_coordinate(x, y, dec, path)):
|
|
459
380
|
return append_decor(decor, x, y, elem, dx, dy)
|
|
460
381
|
|
|
461
382
|
def place_randomly(dec, decor):
|
|
462
383
|
x = random.randint(0, 9)
|
|
463
384
|
y = random.randint(0, 7)
|
|
464
385
|
|
|
465
|
-
if not (
|
|
466
|
-
find_decor_by_coordinate(x, y, dec, decor)
|
|
467
|
-
or find_node_by_coordinate(x, y, dec, path)
|
|
468
|
-
):
|
|
386
|
+
if not (find_decor_by_coordinate(x, y, dec, decor) or find_node_by_coordinate(x, y, dec, path)):
|
|
469
387
|
return append_decor(decor, x, y, dec)
|
|
470
388
|
|
|
471
389
|
def place_bush(elem, decor, nodes):
|
|
472
390
|
bush_exists = False
|
|
473
391
|
for dec in decor:
|
|
474
|
-
if dec["
|
|
392
|
+
if dec["decor_name"] == elem:
|
|
475
393
|
bush_exists = True
|
|
476
394
|
for (dx, dy) in DIRECTIONS:
|
|
477
|
-
x =
|
|
478
|
-
y =
|
|
479
|
-
if near_road(x, y, nodes) and not find_decor_by_coordinate(
|
|
480
|
-
x, y, elem, decor
|
|
481
|
-
):
|
|
395
|
+
x = dec["coordinate"]["x"] // GRID_SIZE + dx
|
|
396
|
+
y = dec["coordinate"]["y"] // GRID_SIZE + dy
|
|
397
|
+
if near_road(x, y, nodes) and not find_decor_by_coordinate(x, y, elem, decor):
|
|
482
398
|
return append_decor(decor, x, y, elem, dx, dy)
|
|
483
399
|
|
|
484
400
|
if not bush_exists:
|
|
@@ -487,7 +403,7 @@ def generate_decor(path, num_tiles):
|
|
|
487
403
|
decor = []
|
|
488
404
|
decor_count = 0
|
|
489
405
|
for dec in DECOR_DATA:
|
|
490
|
-
for i in range(0,
|
|
406
|
+
for i in range(0, DECOR_DATA[dec]["ratio"] * num_tiles // DECOR_SUM):
|
|
491
407
|
if decor_count + num_tiles < WIDTH * HEIGHT:
|
|
492
408
|
if dec == "bush":
|
|
493
409
|
place_bush(dec, decor, path)
|
game/serializers.py
CHANGED
|
@@ -5,7 +5,6 @@ from builtins import object
|
|
|
5
5
|
from rest_framework import serializers
|
|
6
6
|
|
|
7
7
|
from game import messages
|
|
8
|
-
from game.messages import description_level_default, hint_level_default
|
|
9
8
|
from game.theme import get_theme, get_themes_url
|
|
10
9
|
from .models import Workspace, Level, Episode, LevelDecor, LevelBlock, Block
|
|
11
10
|
|
|
@@ -27,8 +26,8 @@ class LevelListSerializer(serializers.HyperlinkedModelSerializer):
|
|
|
27
26
|
"name",
|
|
28
27
|
"title",
|
|
29
28
|
"default",
|
|
30
|
-
"
|
|
31
|
-
"
|
|
29
|
+
"blockly_enabled",
|
|
30
|
+
"python_enabled",
|
|
32
31
|
)
|
|
33
32
|
|
|
34
33
|
def get_title(self, obj):
|
|
@@ -43,6 +42,7 @@ class LevelDetailSerializer(serializers.HyperlinkedModelSerializer):
|
|
|
43
42
|
title = serializers.SerializerMethodField()
|
|
44
43
|
description = serializers.SerializerMethodField()
|
|
45
44
|
hint = serializers.SerializerMethodField()
|
|
45
|
+
commands = serializers.SerializerMethodField()
|
|
46
46
|
levelblock_set = serializers.HyperlinkedIdentityField(
|
|
47
47
|
view_name="levelblock-for-level", read_only=True
|
|
48
48
|
)
|
|
@@ -67,9 +67,9 @@ class LevelDetailSerializer(serializers.HyperlinkedModelSerializer):
|
|
|
67
67
|
"levelblock_set",
|
|
68
68
|
"map",
|
|
69
69
|
"mode",
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
"
|
|
70
|
+
"blockly_enabled",
|
|
71
|
+
"python_enabled",
|
|
72
|
+
"python_view_enabled",
|
|
73
73
|
)
|
|
74
74
|
|
|
75
75
|
def get_title(self, obj):
|
|
@@ -80,18 +80,13 @@ class LevelDetailSerializer(serializers.HyperlinkedModelSerializer):
|
|
|
80
80
|
return "Custom Level"
|
|
81
81
|
|
|
82
82
|
def get_description(self, obj):
|
|
83
|
-
if obj.default
|
|
84
|
-
description = getattr(messages, "description_level" + obj.name)()
|
|
85
|
-
return description
|
|
86
|
-
else:
|
|
87
|
-
return description_level_default()
|
|
83
|
+
return getattr(messages, "description_level" + obj.name)() if obj.default else obj.description
|
|
88
84
|
|
|
89
85
|
def get_hint(self, obj):
|
|
90
|
-
if obj.default
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
else
|
|
94
|
-
return hint_level_default()
|
|
86
|
+
return getattr(messages, "hint_level" + obj.name)() if obj.default else obj.hint
|
|
87
|
+
|
|
88
|
+
def get_commands(self, obj):
|
|
89
|
+
return getattr(messages, "commands_level" + obj.name)() if obj.default else obj.commands
|
|
95
90
|
|
|
96
91
|
def get_leveldecor_set(self, obj):
|
|
97
92
|
leveldecors = LevelDecor.objects.filter(level__id=obj.id)
|
|
@@ -106,7 +101,7 @@ class LevelDetailSerializer(serializers.HyperlinkedModelSerializer):
|
|
|
106
101
|
class LevelModeSerializer(serializers.HyperlinkedModelSerializer):
|
|
107
102
|
class Meta(object):
|
|
108
103
|
model = Level
|
|
109
|
-
fields = ("
|
|
104
|
+
fields = ("blockly_enabled", "python_enabled", "python_view_enabled")
|
|
110
105
|
|
|
111
106
|
|
|
112
107
|
class LevelMapListSerializer(serializers.HyperlinkedModelSerializer):
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
this.Urls = (function () {
|
|
2
|
+
var data = {"urls": [["about", [["about", []]]], ["admin:app_list", [["administration/%(app_label)s/", ["app_label"]]]], ["admin:auth_group_add", [["administration/auth/group/add/", []]]], ["admin:auth_group_change", [["administration/auth/group/%(object_id)s/change/", ["object_id"]]]], ["admin:auth_group_changelist", [["administration/auth/group/", []]]], ["admin:auth_group_delete", [["administration/auth/group/%(object_id)s/delete/", ["object_id"]]]], ["admin:auth_group_history", [["administration/auth/group/%(object_id)s/history/", ["object_id"]]]], ["admin:auth_user_add", [["administration/auth/user/add/", []]]], ["admin:auth_user_change", [["administration/auth/user/%(object_id)s/change/", ["object_id"]]]], ["admin:auth_user_changelist", [["administration/auth/user/", []]]], ["admin:auth_user_delete", [["administration/auth/user/%(object_id)s/delete/", ["object_id"]]]], ["admin:auth_user_history", [["administration/auth/user/%(object_id)s/history/", ["object_id"]]]], ["admin:auth_user_password_change", [["administration/auth/user/%(id)s/password/", ["id"]]]], ["admin:autocomplete", [["administration/autocomplete/", []]]], ["admin:common_class_add", [["administration/common/class/add/", []]]], ["admin:common_class_change", [["administration/common/class/%(object_id)s/change/", ["object_id"]]]], ["admin:common_class_changelist", [["administration/common/class/", []]]], ["admin:common_class_delete", [["administration/common/class/%(object_id)s/delete/", ["object_id"]]]], ["admin:common_class_history", [["administration/common/class/%(object_id)s/history/", ["object_id"]]]], ["admin:common_dailyactivity_add", [["administration/common/dailyactivity/add/", []]]], ["admin:common_dailyactivity_change", [["administration/common/dailyactivity/%(object_id)s/change/", ["object_id"]]]], ["admin:common_dailyactivity_changelist", [["administration/common/dailyactivity/", []]]], ["admin:common_dailyactivity_delete", [["administration/common/dailyactivity/%(object_id)s/delete/", ["object_id"]]]], ["admin:common_dailyactivity_history", [["administration/common/dailyactivity/%(object_id)s/history/", ["object_id"]]]], ["admin:common_dynamicelement_add", [["administration/common/dynamicelement/add/", []]]], ["admin:common_dynamicelement_change", [["administration/common/dynamicelement/%(object_id)s/change/", ["object_id"]]]], ["admin:common_dynamicelement_changelist", [["administration/common/dynamicelement/", []]]], ["admin:common_dynamicelement_delete", [["administration/common/dynamicelement/%(object_id)s/delete/", ["object_id"]]]], ["admin:common_dynamicelement_history", [["administration/common/dynamicelement/%(object_id)s/history/", ["object_id"]]]], ["admin:common_school_add", [["administration/common/school/add/", []]]], ["admin:common_school_change", [["administration/common/school/%(object_id)s/change/", ["object_id"]]]], ["admin:common_school_changelist", [["administration/common/school/", []]]], ["admin:common_school_delete", [["administration/common/school/%(object_id)s/delete/", ["object_id"]]]], ["admin:common_school_history", [["administration/common/school/%(object_id)s/history/", ["object_id"]]]], ["admin:common_schoolteacherinvitation_add", [["administration/common/schoolteacherinvitation/add/", []]]], ["admin:common_schoolteacherinvitation_change", [["administration/common/schoolteacherinvitation/%(object_id)s/change/", ["object_id"]]]], ["admin:common_schoolteacherinvitation_changelist", [["administration/common/schoolteacherinvitation/", []]]], ["admin:common_schoolteacherinvitation_delete", [["administration/common/schoolteacherinvitation/%(object_id)s/delete/", ["object_id"]]]], ["admin:common_schoolteacherinvitation_history", [["administration/common/schoolteacherinvitation/%(object_id)s/history/", ["object_id"]]]], ["admin:common_student_add", [["administration/common/student/add/", []]]], ["admin:common_student_change", [["administration/common/student/%(object_id)s/change/", ["object_id"]]]], ["admin:common_student_changelist", [["administration/common/student/", []]]], ["admin:common_student_delete", [["administration/common/student/%(object_id)s/delete/", ["object_id"]]]], ["admin:common_student_history", [["administration/common/student/%(object_id)s/history/", ["object_id"]]]], ["admin:common_teacher_add", [["administration/common/teacher/add/", []]]], ["admin:common_teacher_change", [["administration/common/teacher/%(object_id)s/change/", ["object_id"]]]], ["admin:common_teacher_changelist", [["administration/common/teacher/", []]]], ["admin:common_teacher_delete", [["administration/common/teacher/%(object_id)s/delete/", ["object_id"]]]], ["admin:common_teacher_history", [["administration/common/teacher/%(object_id)s/history/", ["object_id"]]]], ["admin:common_totalactivity_add", [["administration/common/totalactivity/add/", []]]], ["admin:common_totalactivity_change", [["administration/common/totalactivity/%(object_id)s/change/", ["object_id"]]]], ["admin:common_totalactivity_changelist", [["administration/common/totalactivity/", []]]], ["admin:common_totalactivity_delete", [["administration/common/totalactivity/%(object_id)s/delete/", ["object_id"]]]], ["admin:common_totalactivity_history", [["administration/common/totalactivity/%(object_id)s/history/", ["object_id"]]]], ["admin:common_userprofile_add", [["administration/common/userprofile/add/", []]]], ["admin:common_userprofile_change", [["administration/common/userprofile/%(object_id)s/change/", ["object_id"]]]], ["admin:common_userprofile_changelist", [["administration/common/userprofile/", []]]], ["admin:common_userprofile_delete", [["administration/common/userprofile/%(object_id)s/delete/", ["object_id"]]]], ["admin:common_userprofile_history", [["administration/common/userprofile/%(object_id)s/history/", ["object_id"]]]], ["admin:game_attempt_add", [["administration/game/attempt/add/", []]]], ["admin:game_attempt_change", [["administration/game/attempt/%(object_id)s/change/", ["object_id"]]]], ["admin:game_attempt_changelist", [["administration/game/attempt/", []]]], ["admin:game_attempt_delete", [["administration/game/attempt/%(object_id)s/delete/", ["object_id"]]]], ["admin:game_attempt_history", [["administration/game/attempt/%(object_id)s/history/", ["object_id"]]]], ["admin:game_block_add", [["administration/game/block/add/", []]]], ["admin:game_block_change", [["administration/game/block/%(object_id)s/change/", ["object_id"]]]], ["admin:game_block_changelist", [["administration/game/block/", []]]], ["admin:game_block_delete", [["administration/game/block/%(object_id)s/delete/", ["object_id"]]]], ["admin:game_block_history", [["administration/game/block/%(object_id)s/history/", ["object_id"]]]], ["admin:game_episode_add", [["administration/game/episode/add/", []]]], ["admin:game_episode_change", [["administration/game/episode/%(object_id)s/change/", ["object_id"]]]], ["admin:game_episode_changelist", [["administration/game/episode/", []]]], ["admin:game_episode_delete", [["administration/game/episode/%(object_id)s/delete/", ["object_id"]]]], ["admin:game_episode_history", [["administration/game/episode/%(object_id)s/history/", ["object_id"]]]], ["admin:game_level_add", [["administration/game/level/add/", []]]], ["admin:game_level_change", [["administration/game/level/%(object_id)s/change/", ["object_id"]]]], ["admin:game_level_changelist", [["administration/game/level/", []]]], ["admin:game_level_delete", [["administration/game/level/%(object_id)s/delete/", ["object_id"]]]], ["admin:game_level_history", [["administration/game/level/%(object_id)s/history/", ["object_id"]]]], ["admin:game_leveldecor_add", [["administration/game/leveldecor/add/", []]]], ["admin:game_leveldecor_change", [["administration/game/leveldecor/%(object_id)s/change/", ["object_id"]]]], ["admin:game_leveldecor_changelist", [["administration/game/leveldecor/", []]]], ["admin:game_leveldecor_delete", [["administration/game/leveldecor/%(object_id)s/delete/", ["object_id"]]]], ["admin:game_leveldecor_history", [["administration/game/leveldecor/%(object_id)s/history/", ["object_id"]]]], ["admin:game_workspace_add", [["administration/game/workspace/add/", []]]], ["admin:game_workspace_change", [["administration/game/workspace/%(object_id)s/change/", ["object_id"]]]], ["admin:game_workspace_changelist", [["administration/game/workspace/", []]]], ["admin:game_workspace_delete", [["administration/game/workspace/%(object_id)s/delete/", ["object_id"]]]], ["admin:game_workspace_history", [["administration/game/workspace/%(object_id)s/history/", ["object_id"]]]], ["admin:index", [["administration/", []]]], ["admin:jsi18n", [["administration/jsi18n/", []]]], ["admin:login", [["administration/login/", []]]], ["admin:logout", [["administration/logout/", []]]], ["admin:otp_static_staticdevice_add", [["administration/otp_static/staticdevice/add/", []]]], ["admin:otp_static_staticdevice_change", [["administration/otp_static/staticdevice/%(object_id)s/change/", ["object_id"]]]], ["admin:otp_static_staticdevice_changelist", [["administration/otp_static/staticdevice/", []]]], ["admin:otp_static_staticdevice_delete", [["administration/otp_static/staticdevice/%(object_id)s/delete/", ["object_id"]]]], ["admin:otp_static_staticdevice_history", [["administration/otp_static/staticdevice/%(object_id)s/history/", ["object_id"]]]], ["admin:otp_totp_totpdevice_add", [["administration/otp_totp/totpdevice/add/", []]]], ["admin:otp_totp_totpdevice_change", [["administration/otp_totp/totpdevice/%(object_id)s/change/", ["object_id"]]]], ["admin:otp_totp_totpdevice_changelist", [["administration/otp_totp/totpdevice/", []]]], ["admin:otp_totp_totpdevice_config", [["administration/otp_totp/totpdevice/%(pk)s/config/", ["pk"]]]], ["admin:otp_totp_totpdevice_delete", [["administration/otp_totp/totpdevice/%(object_id)s/delete/", ["object_id"]]]], ["admin:otp_totp_totpdevice_history", [["administration/otp_totp/totpdevice/%(object_id)s/history/", ["object_id"]]]], ["admin:otp_totp_totpdevice_qrcode", [["administration/otp_totp/totpdevice/%(pk)s/qrcode/", ["pk"]]]], ["admin:password_change", [["administration/password_change/", []]]], ["admin:password_change_done", [["administration/password_change/done/", []]]], ["admin:view_on_site", [["administration/r/%(content_type_id)s/%(object_id)s/", ["content_type_id", "object_id"]]]], ["administration_password_change", [["administration/password_change/", []]]], ["administration_password_change_done", [["administration/password_change_done/", []]]], ["anonymise-unverified-accounts", [["cron/user/unverified/delete/", []]]], ["anonymise_orphan_schools", [["schools/anonymise/%(start_id)s/", ["start_id"]]]], ["approve_level", [["rapidrouter/level_moderation/approve/%(levelID)s/", ["levelID"]]]], ["block-detail", [["rapidrouter/api/blocks/%(pk)s/", ["pk"]]]], ["block-list", [["rapidrouter/api/blocks/", []]]], ["celebrate", [["celebrate/", []]]], ["character-detail", [["rapidrouter/api/characters/%(pk)s/", ["pk"]]]], ["character-list", [["rapidrouter/api/characters/", []]]], ["codingClub", [["codingClub/", []]]], ["consent_form", [["consent_form/", []]]], ["contribute", [["contribute", []]]], ["dashboard", [["teach/dashboard/", []]]], ["decor-detail", [["rapidrouter/api/decors/%(pk)s/", ["pk"]]]], ["decor-list", [["rapidrouter/api/decors/", []]]], ["delete_account", [["delete/account/", []]]], ["delete_level", [["rapidrouter/level_moderation/delete/%(levelID)s/", ["levelID"]]]], ["delete_level_for_editor", [["rapidrouter/level_editor/delete/%(levelId)s/", ["levelId"]]]], ["delete_teacher_invite", [["teach/dashboard/delete_teacher_invite/%(token)s", ["token"]]]], ["delete_workspace", [["rapidrouter/workspace/delete/%(workspaceID)s/", ["workspaceID"]]]], ["email_verification", [["verify_email/", []]]], ["episode-detail", [["rapidrouter/api/episodes/%(pk)s/", ["pk"]]]], ["episode-list", [["rapidrouter/api/episodes/", []]]], ["final-inactivity-reminder", [["cron/user/inactive/send-final-reminder/", []]]], ["first-inactivity-reminder", [["cron/user/inactive/send-first-reminder/", []]]], ["first-verify-email-reminder", [["cron/user/unverified/send-first-reminder/", []]]], ["generate_random_map_for_editor", [["rapidrouter/level_editor/random/", []]]], ["get_sharing_information_for_editor", [["rapidrouter/level_editor/get_sharing_information/%(levelID)s/", ["levelID"]]]], ["getinvolved", [["getinvolved", []]]], ["home", [["", []]]], ["home-learning", [["home-learning", []]]], ["inactive_users", [["users/inactive/", []]]], ["independent_edit_account", [["play/account/independent/", []]]], ["independent_student_details", [["play/details/independent", []]]], ["independent_student_login", [["login/independent/", []]]], ["invite_toggle_admin", [["teach/dashboard/toggle_admin_invite/%(invite_id)s/", ["invite_id"]]]], ["invited_teacher", [["invited_teacher/%(token)s/", ["token"]]]], ["js-reverse", [["rapidrouter/reverse.js", []]]], ["last-connected-since", [["api/lastconnectedsince/%(year)s/%(month)s/%(day)s/", ["year", "month", "day"]]]], ["level-detail", [["rapidrouter/api/levels/%(pk)s/", ["pk"]]]], ["level-for-episode", [["rapidrouter/api/episodes/%(pk)s/levels/", ["pk"]]]], ["level-list", [["rapidrouter/api/levels/", []]]], ["level_editor", [["rapidrouter/level_editor/", []]]], ["level_editor_chosen_level", [["rapidrouter/level_editor/%(levelId)s/", ["levelId"]]]], ["level_moderation", [["rapidrouter/level_moderation/", []]]], ["levelblock-detail", [["rapidrouter/api/levelblocks/%(pk)s/", ["pk"]]]], ["levelblock-for-level", [["rapidrouter/api/levels/%(pk)s/blocks/", ["pk"]]]], ["leveldecor-detail", [["rapidrouter/api/leveldecors/%(pk)s/", ["pk"]]]], ["leveldecor-for-level", [["rapidrouter/api/levels/%(pk)s/decors/", ["pk"]]]], ["levels", [["rapidrouter/", []]]], ["load_level_for_editor", [["rapidrouter/level_editor/get/%(levelID)s/", ["levelID"]]]], ["load_list_of_workspaces", [["rapidrouter/workspace/load_list/", []]]], ["load_workspace", [["rapidrouter/workspace/load/%(workspaceID)s/", ["workspaceID"]]]], ["load_workspace_solution", [["rapidrouter/workspace/solution/%(level_name)s/", ["level_name"]]]], ["locked_out", [["locked_out/", []]]], ["logout_view", [["logout/", []]]], ["maintenance", [["maintenance/", []]]], ["map-for-level", [["rapidrouter/api/levels/%(pk)s/map/", ["pk"]]]], ["map-list", [["rapidrouter/api/maps/", []]]], ["mode-for-level", [["rapidrouter/api/levels/%(pk)s/mode/", ["pk"]]]], ["number_users_per_country", [["api/userspercountry/%(country)s/", ["country"]]]], ["old_login_form", [["login_form", []]]], ["onboarding-class", [["teach/onboarding-class/%(access_code)s", ["access_code"]]]], ["onboarding-classes", [["teach/onboarding-classes", []]]], ["onboarding-organisation", [["teach/onboarding-organisation/", []]]], ["organisation_kick", [["teach/dashboard/kick/%(pk)s/", ["pk"]]]], ["organisation_leave", [["teach/dashboard/school/leave/", []]]], ["organisation_toggle_admin", [["teach/dashboard/toggle_admin/%(pk)s/", ["pk"]]]], ["owned_levels", [["rapidrouter/level_editor/levels/owned/", []]]], ["password_reset_check_and_confirm", [["user/password/reset/%(uidb64)s-%(token)s/", ["uidb64", "token"]]]], ["password_reset_complete", [["teacher/password/reset/complete/", []]]], ["play", [["play/", []]]], ["play_anonymous_level", [["rapidrouter/level_editor/play_anonymous/%(levelId)s/", ["levelId"]]]], ["play_custom_level", [["rapidrouter/custom/%(levelId)s/", ["levelId"]]]], ["play_custom_level_from_editor", [["rapidrouter/level_editor/play_custom/%(levelId)s/", ["levelId"]]]], ["play_default_level", [["rapidrouter/%(level_name)s/", ["level_name"]], ["%(level_name)s/", ["level_name"]]]], ["play_python_default_level", [["pythonden/%(level_name)s/", ["level_name"]]]], ["privacy_notice", [["privacy-notice/", []]]], ["privacy_policy", [["privacy-policy/", []]]], ["process_newsletter_form", [["news_signup/", []]]], ["python_levels", [["pythonden/", []]]], ["python_scoreboard", [["pythonden/scoreboard/", []]]], ["random_level_for_episode", [["rapidrouter/levels/random/%(_0)s/", ["_0"]]]], ["rapid-router/javascript-catalog", [["rapidrouter/js-i18n/", []]]], ["register", [["register_form", []]]], ["registered-users", [["api/registered/%(year)s/%(month)s/%(day)s/", ["year", "month", "day"]]]], ["remove_fake_accounts", [["removeFakeAccounts/", []]]], ["resend_invite_teacher", [["teach/dashboard/resend_invite/%(token)s/", ["token"]]]], ["reset_password_email_sent", [["user/password/reset/done/", []]]], ["reset_screentime_warning", [["user/reset_screentime_warning/", []]]], ["reset_session_time", [["user/reset_session_time/", []]]], ["rest_framework:login", [["rapidrouter/api-auth/login/", []]]], ["rest_framework:logout", [["rapidrouter/api-auth/logout/", []]]], ["save_level_for_editor", [["rapidrouter/level_editor/save/%(levelId)s/", ["levelId"]], ["rapidrouter/level_editor/save/", []]]], ["save_workspace", [["rapidrouter/workspace/save/%(workspaceID)s/", ["workspaceID"]], ["rapidrouter/workspace/save/", []]]], ["school_student_edit_account", [["play/account/school_student/", []]]], ["scoreboard", [["rapidrouter/scoreboard/", []]]], ["second-inactivity-reminder", [["cron/user/inactive/send-second-reminder/", []]]], ["second-verify-email-reminder", [["cron/user/unverified/send-second-reminder/", []]]], ["set_language", [["i18n/setlang/", []]]], ["share_level_for_editor", [["rapidrouter/level_editor/share/%(levelID)s/", ["levelID"]]]], ["shared_levels", [["rapidrouter/level_editor/levels/shared/", []]]], ["start_episode", [["rapidrouter/episode/%(episodeId)s/", ["episodeId"]]]], ["start_python_episode", [["pythonden/episode/%(episodeId)s/", ["episodeId"]]]], ["student_details", [["play/details/", []]]], ["student_direct_login", [["u/%(user_id)s/%(login_id)s/", ["user_id", "login_id"]]]], ["student_edit_account", [["play/account/", []]]], ["student_join_organisation", [["play/join/", []]]], ["student_login", [["login/student/%(access_code)s/", ["access_code"]], ["login/student/%(access_code)s/%(login_type)s/", ["access_code", "login_type"]]]], ["student_login_access_code", [["login/student/", []]]], ["student_password_reset", [["user/password/reset/student/", []]]], ["submit_attempt", [["rapidrouter/submit/", []]]], ["teach", [["teach/", []]]], ["teacher_accept_student_request", [["teach/dashboard/student/accept/%(pk)s/", ["pk"]]]], ["teacher_class_password_reset", [["teach/class/%(access_code)s/password_reset/", ["access_code"]]]], ["teacher_delete_class", [["teach/class/delete/%(access_code)s", ["access_code"]]]], ["teacher_delete_students", [["teach/class/%(access_code)s/students/delete/", ["access_code"]]]], ["teacher_disable_2FA", [["teach/dashboard/disable_2FA/%(pk)s/", ["pk"]]]], ["teacher_dismiss_students", [["teach/class/%(access_code)s/students/dismiss/", ["access_code"]]]], ["teacher_download_csv", [["teach/onboarding-class/%(access_code)s/download_csv/", ["access_code"]]]], ["teacher_edit_class", [["teach/class/edit/%(access_code)s", ["access_code"]]]], ["teacher_edit_student", [["teach/class/student/edit/%(pk)s/", ["pk"]]]], ["teacher_login", [["login/teacher/", []]]], ["teacher_move_students", [["teach/class/%(access_code)s/students/move/", ["access_code"]]]], ["teacher_move_students_to_class", [["teach/class/%(access_code)s/students/move/disambiguate/", ["access_code"]]]], ["teacher_password_reset", [["user/password/reset/teacher/", []]]], ["teacher_print_reminder_cards", [["teach/onboarding-class/%(access_code)s/print_reminder_cards/", ["access_code"]]]], ["teacher_reject_student_request", [["teach/dashboard/student/reject/%(pk)s/", ["pk"]]]], ["terms", [["terms", []]]], ["theme-detail", [["rapidrouter/api/themes/%(pk)s/", ["pk"]]]], ["theme-list", [["rapidrouter/api/themes/", []]]], ["two_factor:backup_tokens", [["account/two_factor/backup/tokens/", []]]], ["two_factor:disable", [["account/two_factor/disable/", []]]], ["two_factor:profile", [["account/two_factor/", []]]], ["two_factor:qr", [["account/two_factor/qrcode/", []]]], ["two_factor:setup", [["account/two_factor/setup/", []]]], ["two_factor:setup_complete", [["account/two_factor/setup/complete/", []]]], ["verify_email", [["verify_email/%(token)s/", ["token"]]]], ["view_class", [["teach/class/%(access_code)s", ["access_code"]]]]], "prefix": "/"};
|
|
3
|
+
var resolverFactory;
|
|
4
|
+
/******/ (() => { // webpackBootstrap
|
|
5
|
+
/******/ "use strict";
|
|
6
|
+
/******/ // The require scope
|
|
7
|
+
/******/ var __webpack_require__ = {};
|
|
8
|
+
/******/
|
|
9
|
+
/************************************************************************/
|
|
10
|
+
/******/ /* webpack/runtime/define property getters */
|
|
11
|
+
/******/ (() => {
|
|
12
|
+
/******/ // define getter functions for harmony exports
|
|
13
|
+
/******/ __webpack_require__.d = (exports, definition) => {
|
|
14
|
+
/******/ for(var key in definition) {
|
|
15
|
+
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
|
|
16
|
+
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
|
|
17
|
+
/******/ }
|
|
18
|
+
/******/ }
|
|
19
|
+
/******/ };
|
|
20
|
+
/******/ })();
|
|
21
|
+
/******/
|
|
22
|
+
/******/ /* webpack/runtime/hasOwnProperty shorthand */
|
|
23
|
+
/******/ (() => {
|
|
24
|
+
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
|
|
25
|
+
/******/ })();
|
|
26
|
+
/******/
|
|
27
|
+
/******/ /* webpack/runtime/make namespace object */
|
|
28
|
+
/******/ (() => {
|
|
29
|
+
/******/ // define __esModule on exports
|
|
30
|
+
/******/ __webpack_require__.r = (exports) => {
|
|
31
|
+
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
|
|
32
|
+
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
33
|
+
/******/ }
|
|
34
|
+
/******/ Object.defineProperty(exports, '__esModule', { value: true });
|
|
35
|
+
/******/ };
|
|
36
|
+
/******/ })();
|
|
37
|
+
/******/
|
|
38
|
+
/************************************************************************/
|
|
39
|
+
var __webpack_exports__ = {};
|
|
40
|
+
__webpack_require__.r(__webpack_exports__);
|
|
41
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
42
|
+
/* harmony export */ "UrlResolver": () => (/* binding */ UrlResolver),
|
|
43
|
+
/* harmony export */ "factory": () => (/* binding */ factory)
|
|
44
|
+
/* harmony export */ });
|
|
45
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
46
|
+
|
|
47
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
48
|
+
|
|
49
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
50
|
+
|
|
51
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|
52
|
+
|
|
53
|
+
function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
54
|
+
|
|
55
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
56
|
+
|
|
57
|
+
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
|
|
58
|
+
|
|
59
|
+
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
60
|
+
|
|
61
|
+
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
|
|
62
|
+
|
|
63
|
+
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
|
|
64
|
+
|
|
65
|
+
var UrlResolver = /*#__PURE__*/function () {
|
|
66
|
+
function UrlResolver(prefix, patterns) {
|
|
67
|
+
_classCallCheck(this, UrlResolver);
|
|
68
|
+
|
|
69
|
+
this.prefix = prefix;
|
|
70
|
+
this.patterns = patterns;
|
|
71
|
+
this.reverse = this.reverse.bind(this);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
_createClass(UrlResolver, [{
|
|
75
|
+
key: "reverse",
|
|
76
|
+
value: function reverse() {
|
|
77
|
+
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
78
|
+
args[_key] = arguments[_key];
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
var validateArgs, buildKwargs;
|
|
82
|
+
|
|
83
|
+
if (args.length === 1 && _typeof(args[0]) === 'object') {
|
|
84
|
+
// kwargs mode
|
|
85
|
+
var providedKeys = Object.keys(args[0]);
|
|
86
|
+
|
|
87
|
+
validateArgs = function validateArgs(_ref) {
|
|
88
|
+
var _ref2 = _slicedToArray(_ref, 2),
|
|
89
|
+
_urlTemplate = _ref2[0],
|
|
90
|
+
urlParams = _ref2[1];
|
|
91
|
+
|
|
92
|
+
// check every needed param was provided (without extra elements)
|
|
93
|
+
return urlParams.length === providedKeys.length && urlParams.every(function (p) {
|
|
94
|
+
return providedKeys.includes(p);
|
|
95
|
+
});
|
|
96
|
+
}; // return first element
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
buildKwargs = function buildKwargs() {
|
|
100
|
+
return args[0];
|
|
101
|
+
};
|
|
102
|
+
} else {
|
|
103
|
+
// args mode
|
|
104
|
+
// check every required param
|
|
105
|
+
validateArgs = function validateArgs(_ref3) {
|
|
106
|
+
var _ref4 = _slicedToArray(_ref3, 2),
|
|
107
|
+
_urlTemplate = _ref4[0],
|
|
108
|
+
urlParams = _ref4[1];
|
|
109
|
+
|
|
110
|
+
return urlParams.length === args.length;
|
|
111
|
+
}; // build keyword-arguments from arguments
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
buildKwargs = function buildKwargs(keys) {
|
|
115
|
+
return Object.fromEntries(keys.map(function (key, i) {
|
|
116
|
+
return [key, args[i]];
|
|
117
|
+
}));
|
|
118
|
+
};
|
|
119
|
+
} // search between patterns if one matches provided args
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
var urlPattern = this.patterns.find(validateArgs);
|
|
123
|
+
|
|
124
|
+
if (!urlPattern) {
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
var _urlPattern = _slicedToArray(urlPattern, 2),
|
|
129
|
+
urlTemplate = _urlPattern[0],
|
|
130
|
+
urlKwargNames = _urlPattern[1];
|
|
131
|
+
|
|
132
|
+
var urlKwargs = buildKwargs(urlKwargNames);
|
|
133
|
+
var url = Object.entries(urlKwargs).reduce(function (partialUrl, _ref5) {
|
|
134
|
+
var _ref6 = _slicedToArray(_ref5, 2),
|
|
135
|
+
pName = _ref6[0],
|
|
136
|
+
pValue = _ref6[1];
|
|
137
|
+
|
|
138
|
+
if (pValue == null) pValue = ''; // replace variable with param
|
|
139
|
+
|
|
140
|
+
return partialUrl.replace("%(".concat(pName, ")s"), pValue);
|
|
141
|
+
}, urlTemplate);
|
|
142
|
+
return "".concat(this.prefix).concat(url);
|
|
143
|
+
}
|
|
144
|
+
}]);
|
|
145
|
+
|
|
146
|
+
return UrlResolver;
|
|
147
|
+
}();
|
|
148
|
+
function factory(config) {
|
|
149
|
+
var urlPatterns = config.urls,
|
|
150
|
+
urlPrefix = config.prefix;
|
|
151
|
+
return urlPatterns.reduce(function (resolver, _ref7) {
|
|
152
|
+
var _ref8 = _slicedToArray(_ref7, 2),
|
|
153
|
+
name = _ref8[0],
|
|
154
|
+
pattern = _ref8[1];
|
|
155
|
+
|
|
156
|
+
var urlResolver = new UrlResolver(urlPrefix, pattern);
|
|
157
|
+
resolver[name] = urlResolver.reverse; // turn snake-case into camel-case
|
|
158
|
+
|
|
159
|
+
resolver[name.replace(/[-_]+(.)/g, function (_m, p1) {
|
|
160
|
+
return p1.toUpperCase();
|
|
161
|
+
})] = urlResolver.reverse; // turn snake-case into dash-case
|
|
162
|
+
|
|
163
|
+
resolver[name.replace(/-/g, '_')] = urlResolver.reverse;
|
|
164
|
+
return resolver;
|
|
165
|
+
}, {});
|
|
166
|
+
}
|
|
167
|
+
resolverFactory = __webpack_exports__;
|
|
168
|
+
/******/ })()
|
|
169
|
+
;
|
|
170
|
+
return data ? resolverFactory.factory(data) : resolverFactory.factory;
|
|
171
|
+
})();
|
|
Binary file
|