Commit f533b816d84901f08ac049812e886fffe59e7b88
1 parent
f46545cd
add generation of editor view
Showing
8 changed files
with
221 additions
and
35 deletions
Show diff stats
calexium_lib @ 64fc7e3c2d3
hayamiki.aproj
| ... | ... | @@ -494,6 +494,7 @@ |
| 494 | 494 | <Compile Include="src\generation\menu.anubis" /> |
| 495 | 495 | <Compile Include="src\generation\model.anubis" /> |
| 496 | 496 | <Compile Include="src\generation\types.anubis" /> |
| 497 | + <Compile Include="src\generation\vt_edit.anubis" /> | |
| 497 | 498 | <Compile Include="src\main.anubis" /> |
| 498 | 499 | <Compile Include="src\model.3.0.0.anubis" /> |
| 499 | 500 | <Compile Include="src\utils\utils.anubis" /> | ... | ... |
hayamiki_lib @ 291e3895c2e
src/generation/files.anubis
| ... | ... | @@ -21,6 +21,7 @@ read generation/create_table.anubis |
| 21 | 21 | read generation/menu.anubis |
| 22 | 22 | read generation/fn_delete.anubis |
| 23 | 23 | read generation/choices_selector.anubis |
| 24 | +read generation/vt_edit.anubis | |
| 24 | 25 | read check.anubis |
| 25 | 26 | |
| 26 | 27 | define Maybe(One) |
| ... | ... | @@ -60,7 +61,7 @@ define Maybe(One) |
| 60 | 61 | if generate_selector(strm, table) is { failure then failure, success(_) then |
| 61 | 62 | if generate_choices_selector(strm, table) is { failure then failure, success(_) then |
| 62 | 63 | if generate_VT_all_view(strm, table) is { failure then failure, success(_) then |
| 63 | - if generate_VT_edit(strm, table) is { failure then failure, success(_) then | |
| 64 | + if generate_VT_all_edit(strm, table) is { failure then failure, success(_) then | |
| 64 | 65 | success(unique)}}}}}}}}}}}}}} |
| 65 | 66 | }. |
| 66 | 67 | ... | ... |
src/generation/types.anubis
| 1 | +/* | |
| 2 | + * Created by PyramIDE. | |
| 3 | + * User: フランスのトトロ aka (David RENÉ) | |
| 4 | + * Date: 28/08/2016 | |
| 5 | + * Time: 01:16 | |
| 6 | + * © Calexium | |
| 7 | + */ | |
| 8 | + | |
| 9 | +read hayamiki_lib/types/hayamiki.anubis | |
| 10 | +read tools/basis.anubis | |
| 11 | +read tools/streams.anubis | |
| 12 | +read system/string.anubis | |
| 13 | +read fields.anubis | |
| 14 | +read columns.anubis | |
| 15 | +read html.anubis | |
| 16 | + . | |
| 17 | + | |
| 18 | +public define Maybe(One) | |
| 19 | +/* Generate | |
| 20 | + | |
| 21 | +*/ | |
| 22 | + generate_VT_edit | |
| 23 | + ( | |
| 24 | + Stream stream, //stream file where to write | |
| 25 | + HK_Table table, // | |
| 26 | + HK_Edit_View edit_view //edit view to generate | |
| 27 | + )= | |
| 28 | + since table is hk_table(table_name, short_name, model, display), | |
| 29 | + since model is hk_model( columns, _), | |
| 30 | + //since display is db_display(list_view, list_edit), | |
| 31 | + | |
| 32 | + with type_name = to_upper(table_name, 1), //make the first character to upper case and be an Anubis Type. | |
| 33 | + with view_name = if edit_view is | |
| 34 | + { | |
| 35 | + edit_view_all then "default", | |
| 36 | + edit_view(view_name, _) then view_name | |
| 37 | + }, | |
| 38 | + with current_edit_view = if edit_view is | |
| 39 | + { | |
| 40 | + edit_view_all then to_List_String(columns, false), | |
| 41 | + edit_view(_, cols) then cols | |
| 42 | + }, | |
| 43 | + //generate the type of the table that contain all components | |
| 44 | + if write_string(stream, | |
| 45 | + "\n\n"+ | |
| 46 | + //SQL query | |
| 47 | + "define VT_edit\n"+ | |
| 48 | + " _get_editable_"+table_name+"_"+view_name+"\n"+ | |
| 49 | + " (\n"+ | |
| 50 | + " "+type_name+" "+table_name+",\n"+ | |
| 51 | + " SQLite3DataBase db\n"+ | |
| 52 | + " )=\n"+ | |
| 53 | + " with edit_entries = (List(VT_edit_entry))\n"+ | |
| 54 | + " [\n"+ | |
| 55 | + edit_entries(columns, table_name, " ", [])+"\n"+ | |
| 56 | + " ],\n"+ | |
| 57 | + " vt_edit(\""+table_name+"\", edit_entries).\n\n" | |
| 58 | + ) is //end of the function | |
| 59 | + { | |
| 60 | + failure then println("can't write generate_VT_view "+type_name); failure, | |
| 61 | + success(_) then success(unique) | |
| 62 | + }. | |
| 63 | + | |
| 64 | +public define Maybe(One) | |
| 65 | +/* Generate | |
| 66 | + | |
| 67 | +*/ | |
| 68 | + _generate_VT_edit | |
| 69 | + ( | |
| 70 | + Stream stream, //stream file where to write | |
| 71 | + HK_Table table, // | |
| 72 | + List(HK_Edit_View) edit_view, //edit view to generate | |
| 73 | + Bool has_default //set to true if a default view was encountered. | |
| 74 | + )= | |
| 75 | + if edit_view is | |
| 76 | + { | |
| 77 | + [] then | |
| 78 | + //if default view was not generated, we force to generate it | |
| 79 | + if has_default = false then | |
| 80 | + generate_VT_edit(stream, table, edit_view_all) | |
| 81 | + else | |
| 82 | + success(unique), | |
| 83 | + [view . t] then | |
| 84 | + if generate_VT_edit(stream, table, view) is | |
| 85 | + { | |
| 86 | + failure then failure, | |
| 87 | + success(_) then | |
| 88 | + with new_has_default = if has_default = true then //already true, no need to go further | |
| 89 | + true | |
| 90 | + else | |
| 91 | + if view is | |
| 92 | + { | |
| 93 | + edit_view_all then true, //list_view_all is default view | |
| 94 | + edit_view(view_name, _) then | |
| 95 | + //if not we search for view named 'default' | |
| 96 | + if view_name = "default" then true else false | |
| 97 | + }, | |
| 98 | + _generate_VT_edit(stream, table, t, new_has_default) | |
| 99 | + } | |
| 100 | + }. | |
| 101 | + | |
| 102 | +public define String | |
| 103 | +/* Generate | |
| 104 | + | |
| 105 | +*/ | |
| 106 | + _generate_get_editable_if_else | |
| 107 | + ( | |
| 108 | + String table_name, // | |
| 109 | + List(HK_Edit_View) edit_view, //edit view to generate | |
| 110 | + String so_far | |
| 111 | + )= | |
| 112 | + if edit_view is | |
| 113 | + { | |
| 114 | + [] then | |
| 115 | + so_far + | |
| 116 | + "\n"+ | |
| 117 | + " _get_editable_"+table_name+"_default("+table_name+", db)\n", | |
| 118 | + [view . t] then | |
| 119 | + with view_name = if view is | |
| 120 | + { | |
| 121 | + edit_view_all then "default", | |
| 122 | + edit_view(view_name, _) then view_name | |
| 123 | + }, | |
| 124 | + _generate_get_editable_if_else( table_name, t, | |
| 125 | + so_far + | |
| 126 | + " if editor_view = \""+view_name+"\" then\n"+ | |
| 127 | + " _get_editable_"+table_name+"_"+view_name+"("+table_name+", db)\n"+ | |
| 128 | + " else" | |
| 129 | + ) | |
| 130 | + }. | |
| 131 | + | |
| 132 | +public define Maybe(One) | |
| 133 | +/* Generate the function which get the right editor according to editor name | |
| 134 | + | |
| 135 | +*/ | |
| 136 | + generate_get_viewable | |
| 137 | + ( | |
| 138 | + Stream stream, //stream file where to write | |
| 139 | + HK_Table table, // | |
| 140 | + List(HK_Edit_View) edit_view //list view to generate | |
| 141 | + )= | |
| 142 | + since table is hk_table(table_name, short_name, model, display), | |
| 143 | + if write_string(stream, | |
| 144 | + "public define VT_edit\n"+ | |
| 145 | + " get_editable_"+table_name+"\n"+ | |
| 146 | + " (\n"+ | |
| 147 | + " SQLite3DataBase db,\n"+ | |
| 148 | + " VT_action action,\n"+ | |
| 149 | + " String editor_view\n"+ | |
| 150 | + " )=\n"+ | |
| 151 | + " with "+table_name+" = if action is\n"+ | |
| 152 | + " {\n"+ | |
| 153 | + " new_entry then get_default_"+table_name+"\n"+ | |
| 154 | + " edit_entry(idx) then\n"+ | |
| 155 | + " if get_"+table_name+"(db, idx) is\n"+ | |
| 156 | + " {\n"+ | |
| 157 | + " failure then get_default_"+table_name+",\n"+ | |
| 158 | + " success(data) then data\n"+ | |
| 159 | + " }\n"+ | |
| 160 | + " },\n"+ | |
| 161 | + _generate_get_editable_if_else(table_name, edit_view, "")+ | |
| 162 | + ".\n" | |
| 163 | + ) is //end of the function | |
| 164 | + { | |
| 165 | + failure then println("can't write generate_get_editable "+table_name); failure, | |
| 166 | + success(_) then success(unique) | |
| 167 | + }. | |
| 168 | + | |
| 169 | +public define Maybe(One) | |
| 170 | + generate_VT_all_edit | |
| 171 | + ( | |
| 172 | + Stream stream, | |
| 173 | + HK_Table table | |
| 174 | + )= | |
| 175 | + since table is hk_table(name, short_name, model, display), | |
| 176 | + since model is hk_model( columns, _), | |
| 177 | + since display is hk_display(_, list_edit), | |
| 178 | + | |
| 179 | + with type_name = to_upper(name, 1), //make the first character to upper case to able to be a Anubis Type. | |
| 180 | + if _generate_VT_edit(stream, table, list_edit, false) is //edit view to generate | |
| 181 | + { | |
| 182 | + failure then failure, | |
| 183 | + success(_) then generate_get_viewable(stream, table, list_edit) | |
| 184 | + }. | |
| 185 | + | ... | ... |
src/main.anubis
| ... | ... | @@ -20,7 +20,7 @@ read hayamiki_lib/hk_generator.anubis |
| 20 | 20 | read model.3.0.0.anubis |
| 21 | 21 | read system/muscle.anubis |
| 22 | 22 | |
| 23 | - global define One | |
| 23 | +global define One | |
| 24 | 24 | hayamiki |
| 25 | 25 | ( |
| 26 | 26 | List(String) args |
| ... | ... | @@ -28,7 +28,7 @@ read system/muscle.anubis |
| 28 | 28 | if load_hk_generator is |
| 29 | 29 | { |
| 30 | 30 | failure then println("Hayamiki generator can't be load"), |
| 31 | - success(hk_gen) then forget(hk_gen.generate_model_files(domain_manager_description, "")) | |
| 31 | + success(hk_gen) then forget(hk_gen.generate_model_files(the_database_description, "")) | |
| 32 | 32 | }. |
| 33 | 33 | |
| 34 | 34 | global define One | ... | ... |
src/model.3.0.0.anubis
| ... | ... | @@ -16,7 +16,7 @@ public define HK_Table settings_table = |
| 16 | 16 | //list_view |
| 17 | 17 | [ list_view_all], |
| 18 | 18 | //list edit |
| 19 | - ["var_name", "var_value"] | |
| 19 | + [edit_view_all] | |
| 20 | 20 | ) |
| 21 | 21 | ). |
| 22 | 22 | |
| ... | ... | @@ -41,7 +41,7 @@ public define HK_Table django_admin_log_table = |
| 41 | 41 | //list_view |
| 42 | 42 | [ list_view_all], |
| 43 | 43 | //list edit |
| 44 | - ["action_time", "user_id", "content_type_id", "object_id", "object_repr", "action_flag", "change_message"] | |
| 44 | + [ edit_view_all] | |
| 45 | 45 | ) |
| 46 | 46 | ). |
| 47 | 47 | |
| ... | ... | @@ -59,7 +59,7 @@ public define HK_Table production_macaddress_table = |
| 59 | 59 | //list_view |
| 60 | 60 | [ list_view_all], |
| 61 | 61 | //list edit |
| 62 | - ["mac", "index", "mailfountain_id"] | |
| 62 | + [edit_view_all] | |
| 63 | 63 | ) |
| 64 | 64 | ). |
| 65 | 65 | |
| ... | ... | @@ -76,7 +76,7 @@ public define HK_Table production_mass_storage_type_table = |
| 76 | 76 | //list_view |
| 77 | 77 | [ list_view_all], |
| 78 | 78 | //list edit |
| 79 | - ["type"] | |
| 79 | + [edit_view_all] | |
| 80 | 80 | ) |
| 81 | 81 | ). |
| 82 | 82 | |
| ... | ... | @@ -103,7 +103,7 @@ public define HK_Table production_mass_storage_table = |
| 103 | 103 | list_view("current",["model_id", "serial", "status", "date_created"]) |
| 104 | 104 | ], |
| 105 | 105 | //list_edit |
| 106 | - ["purchase_id", "model_id", "serial", "status", "comments"] | |
| 106 | + [ edit_view("default", ["purchase_id", "model_id", "serial", "status", "comments"])] | |
| 107 | 107 | ) |
| 108 | 108 | ). |
| 109 | 109 | |
| ... | ... | @@ -142,7 +142,7 @@ public define HK_Table production_mass_storage_model_table = |
| 142 | 142 | list_view("default", ["manufacturer", "type_id", "capacity", "tr_min", "last_modified", "date_created"]) |
| 143 | 143 | ], |
| 144 | 144 | //list_edit |
| 145 | - [] | |
| 145 | + [edit_view_all] | |
| 146 | 146 | ) |
| 147 | 147 | ). |
| 148 | 148 | |
| ... | ... | @@ -167,7 +167,7 @@ public define HK_Table production_memory_table = |
| 167 | 167 | list_view("default", ["serial", "status", "last_modified", "date_created"]) |
| 168 | 168 | ], |
| 169 | 169 | //list_edit |
| 170 | - ["purchase_id", "model_id", "serial", "status", "last_modified", "date_created", "comments"] | |
| 170 | + [edit_view_all] | |
| 171 | 171 | ) |
| 172 | 172 | ). |
| 173 | 173 | |
| ... | ... | @@ -186,7 +186,7 @@ public define HK_Table production_memory_model_table = |
| 186 | 186 | //list_view |
| 187 | 187 | [ list_view_all], |
| 188 | 188 | //list_edit |
| 189 | - ["type_id", "manufacturer", "capacity"] | |
| 189 | + [edit_view_all] | |
| 190 | 190 | ) |
| 191 | 191 | ). |
| 192 | 192 | |
| ... | ... | @@ -203,7 +203,7 @@ public define HK_Table production_memory_type_table = |
| 203 | 203 | //list_view |
| 204 | 204 | [ list_view_all], |
| 205 | 205 | //list edit |
| 206 | - ["type"] | |
| 206 | + [edit_view_all] | |
| 207 | 207 | ) |
| 208 | 208 | ). |
| 209 | 209 | |
| ... | ... | @@ -229,7 +229,7 @@ public define HK_Table production_motherboard_table = |
| 229 | 229 | list_view("default", ["serial", "week_fab", "status", "last_modified", "date_created"]) |
| 230 | 230 | ], |
| 231 | 231 | //list_edit |
| 232 | - ["purchase_id", "model_id", "serial", "week_fab", "status", "last_modified", "date_created", "comments"] | |
| 232 | + [edit_view_all] | |
| 233 | 233 | ) |
| 234 | 234 | ). |
| 235 | 235 | |
| ... | ... | @@ -255,7 +255,7 @@ public define HK_Table production_motherboard_model_table = |
| 255 | 255 | list_view("default", ["name", "manufacturer", "cpu_model", "cpu_freq"]) |
| 256 | 256 | ], |
| 257 | 257 | //list_edit |
| 258 | - ["name", "manufacturer", "has_nand", "nand_capacity", "memory", "cpu_freq", "cpu_model", "endian"] | |
| 258 | + [edit_view_all] | |
| 259 | 259 | ) |
| 260 | 260 | ). |
| 261 | 261 | |
| ... | ... | @@ -280,7 +280,7 @@ public define HK_Table production_power_supply_table = |
| 280 | 280 | list_view("default", ["serial", "status", "date_created", "last_modified"]) |
| 281 | 281 | ], |
| 282 | 282 | //list_edit |
| 283 | - ["purchase_id", "model_id", "serial", "status", "date_created", "last_modified", "comments"] | |
| 283 | + [edit_view_all] | |
| 284 | 284 | ) |
| 285 | 285 | ). |
| 286 | 286 | |
| ... | ... | @@ -301,7 +301,7 @@ public define HK_Table production_power_supply_model_table = |
| 301 | 301 | list_view("default", ["name", "manufacturer"]) |
| 302 | 302 | ], |
| 303 | 303 | //list_edit |
| 304 | - ["name", "manufacturer", "power"] | |
| 304 | + [edit_view_all] | |
| 305 | 305 | ) |
| 306 | 306 | ). |
| 307 | 307 | |
| ... | ... | @@ -331,8 +331,7 @@ public define HK_Table production_product_reference_table = |
| 331 | 331 | list_view("default", ["type_ref_id", "product_ref", "product_name", "description"]) |
| 332 | 332 | ], |
| 333 | 333 | //list_edit |
| 334 | - [ "type_ref_id", "product_ref", "product_name", "description", "need_memory", "need_power_supply", "need_additional_storage", "min_additional_storage", "max_additional_storage", | |
| 335 | - "date_created", "last_modified", "comments"] | |
| 334 | + [ edit_view_all] | |
| 336 | 335 | ) |
| 337 | 336 | ). |
| 338 | 337 | |
| ... | ... | @@ -368,8 +367,8 @@ public define HK_Table production_products_table = |
| 368 | 367 | list_view("default", ["production_id", "date", "serial", "motherboard_id", "app_id", "status"]) |
| 369 | 368 | ], |
| 370 | 369 | //list_edit |
| 371 | - [ "production_id", "produced", "date", "serial", "security_code", "motherboard_id", "storage_id", "memory_id", "power_supply_id", "wifi", "mac", | |
| 372 | - "app_id", "os_version", "published", "publish_date", "status", "date_created", "last_modified", "comments"] | |
| 370 | + [ edit_view("default", [ "production_id", "produced", "date", "serial", "security_code", "motherboard_id", "storage_id", "memory_id", "power_supply_id", "wifi", "mac", | |
| 371 | + "app_id", "os_version", "published", "publish_date", "status", "date_created", "last_modified", "comments"])] | |
| 373 | 372 | ) |
| 374 | 373 | ). |
| 375 | 374 | |
| ... | ... | @@ -402,8 +401,8 @@ public define HK_Table production_production_table = |
| 402 | 401 | list_view("default", ["date", "type_ref_id", "sticker_tpl_id", "product_ref_id", "site_id", "product_count", "produced_count"]) |
| 403 | 402 | ], |
| 404 | 403 | //list_edit |
| 405 | - [ "date", "assembler_id", "type_ref_id", "product_ref_id", "site_id", "serial_prefix_id", "sticker_tpl_id", "starting_index", "product_count", "produced_count", "completed", | |
| 406 | - "active", "date_created", "last_modified", "comments"] | |
| 404 | + [ edit_view("default", [ "date", "assembler_id", "type_ref_id", "product_ref_id", "site_id", "serial_prefix_id", "sticker_tpl_id", "starting_index", "product_count", "produced_count", "completed", | |
| 405 | + "active", "date_created", "last_modified", "comments"])] | |
| 407 | 406 | ) |
| 408 | 407 | ). |
| 409 | 408 | |
| ... | ... | @@ -428,7 +427,7 @@ public define HK_Table production_production_site_table = |
| 428 | 427 | list_view("default", ["ref", "name", "city", "country"]) |
| 429 | 428 | ], |
| 430 | 429 | //list_edit |
| 431 | - [ "ref", "name", "city", "country", "next_serial", "date_created", "last_modified", "comments"] | |
| 430 | + [edit_view_all] | |
| 432 | 431 | ) |
| 433 | 432 | ). |
| 434 | 433 | |
| ... | ... | @@ -453,7 +452,7 @@ public define HK_Table production_purchase_table = |
| 453 | 452 | list_view("default", ["date", "supplier_id", "description"]) |
| 454 | 453 | ], |
| 455 | 454 | //list_edit |
| 456 | - ["date", "buyer_id", "supplier_id", "order_ref", "description", "comments"] | |
| 455 | + [edit_view_all] | |
| 457 | 456 | ) |
| 458 | 457 | ). |
| 459 | 458 | |
| ... | ... | @@ -471,7 +470,7 @@ public define HK_Table production_serial_prefix_table = |
| 471 | 470 | //list_view |
| 472 | 471 | [list_view_all], |
| 473 | 472 | //list_edit |
| 474 | - ["prefix", "next_start"] | |
| 473 | + [edit_view_all] | |
| 475 | 474 | ) |
| 476 | 475 | ). |
| 477 | 476 | |
| ... | ... | @@ -494,7 +493,7 @@ public define HK_Table production_type_number_table = |
| 494 | 493 | list_view("default", ["type_ref", "description"]) |
| 495 | 494 | ], |
| 496 | 495 | //list_edit |
| 497 | - ["type_ref", "description", "comments"] | |
| 496 | + [ edit_view("default", ["type_ref", "description", "comments"])] | |
| 498 | 497 | ) |
| 499 | 498 | ). |
| 500 | 499 | |
| ... | ... | @@ -529,8 +528,8 @@ public define HK_Table production_supplier_table = |
| 529 | 528 | list_view("default", ["company", "phone", "mobile", "email"]) |
| 530 | 529 | ], |
| 531 | 530 | //list_edit |
| 532 | - ["company", "supplier_id", "address1", "address2", "zipcode", "city", "country", "email", "url", "phone", "fax", "mobile", | |
| 533 | - "siret", "tva_number", "date_created", "last_modified", "comments"] | |
| 531 | + [ edit_view("default", ["company", "supplier_id", "address1", "address2", "zipcode", "city", "country", "email", "url", "phone", "fax", "mobile", | |
| 532 | + "siret", "tva_number", "date_created", "last_modified", "comments"])] | |
| 534 | 533 | ) |
| 535 | 534 | ). |
| 536 | 535 | |
| ... | ... | @@ -554,7 +553,7 @@ public define HK_Table department_table = |
| 554 | 553 | list_view("default", ["name"]) |
| 555 | 554 | ], |
| 556 | 555 | //list_edit |
| 557 | - ["name", "description", "comments"] | |
| 556 | + [ edit_view("default", ["name", "description", "comments"])] | |
| 558 | 557 | ) |
| 559 | 558 | ). |
| 560 | 559 | |
| ... | ... | @@ -577,7 +576,7 @@ public define HK_Table role_table = |
| 577 | 576 | list_view("default", ["role_name"]) |
| 578 | 577 | ], |
| 579 | 578 | //list_edit |
| 580 | - ["role_name", "description", "comments"] | |
| 579 | + [ edit_view("default", ["role_name", "description", "comments"])] | |
| 581 | 580 | ) |
| 582 | 581 | ). |
| 583 | 582 | |
| ... | ... | @@ -607,7 +606,7 @@ public define HK_Table staff_table = |
| 607 | 606 | |
| 608 | 607 | ], |
| 609 | 608 | //list_edit |
| 610 | - ["contact_id", "department_id", "role_id", "email", "incoming_date", "outgoing_date", "still_present", "date_created", "date_modified", "comments"] | |
| 609 | + [ edit_view("default", ["contact_id", "department_id", "role_id", "email", "incoming_date", "outgoing_date", "still_present", "date_created", "date_modified", "comments"])] | |
| 611 | 610 | ) |
| 612 | 611 | ). |
| 613 | 612 | |
| ... | ... | @@ -644,7 +643,7 @@ public define HK_Table address_book_contact_table = |
| 644 | 643 | list_view("details", ["first_name", "last_name", "company", "url", "role", "phone", "mobile", "email", "address1", "address2", "zipcode", "city", "country"]) |
| 645 | 644 | ], |
| 646 | 645 | //list_edit |
| 647 | - ["first_name", "last_name", "company", "role", "address1", "address2", "zipcode", "city", "country", "email", "url", "phone", "fax", "mobile", "comments"] | |
| 646 | + [ edit_view("default", ["first_name", "last_name", "company", "role", "address1", "address2", "zipcode", "city", "country", "email", "url", "phone", "fax", "mobile", "comments"])] | |
| 648 | 647 | ) |
| 649 | 648 | ). |
| 650 | 649 | ... | ... |