pgkiln 0.82.0 → 0.83.0

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.
Files changed (61) hide show
  1. package/db/migrations/153_component_events.sql +21 -0
  2. package/docs/apex-feature-parity.md +3 -3
  3. package/docs/guide/03-builder.md +8 -1
  4. package/docs/guide/04-pages-and-regions.md +2 -1
  5. package/docs/guide/07-dynamic-actions.md +27 -0
  6. package/docs/guide/11-from-apex.md +2 -1
  7. package/docs/guide/12-development.md +9 -1
  8. package/package.json +1 -1
  9. package/public/app.css +2 -0
  10. package/public/app.js +85 -4
  11. package/public/builder.css +25 -2
  12. package/public/data-modeler.js +8 -5
  13. package/public/sql-monitor.js +5 -2
  14. package/src/builder/ai-builder.ts +50 -46
  15. package/src/builder/api.ts +49 -49
  16. package/src/builder/autorest.ts +92 -87
  17. package/src/builder/changelog.ts +39 -37
  18. package/src/builder/components.ts +5 -4
  19. package/src/builder/data-modeler.ts +89 -84
  20. package/src/builder/data-security.ts +39 -37
  21. package/src/builder/dataload.ts +69 -65
  22. package/src/builder/datapump.ts +108 -97
  23. package/src/builder/ddl-tools.ts +38 -34
  24. package/src/builder/document-view.ts +11 -11
  25. package/src/builder/i18n/de.ts +1627 -0
  26. package/src/builder/i18n/en.ts +1627 -0
  27. package/src/builder/i18n/es.ts +1627 -0
  28. package/src/builder/i18n/fr.ts +1627 -0
  29. package/src/builder/i18n/it.ts +1627 -0
  30. package/src/builder/i18n/ja.ts +1627 -0
  31. package/src/builder/i18n/ko.ts +1627 -0
  32. package/src/builder/i18n/nl.ts +1627 -0
  33. package/src/builder/i18n/pt.ts +1627 -0
  34. package/src/builder/i18n/zh-cn.ts +1627 -0
  35. package/src/builder/i18n/zh-tw.ts +1627 -0
  36. package/src/builder/i18n.ts +18 -0
  37. package/src/builder/object-actions.ts +18 -16
  38. package/src/builder/object-browser.ts +2 -2
  39. package/src/builder/querybuilder.ts +42 -36
  40. package/src/builder/quicksql.ts +16 -18
  41. package/src/builder/region-settings.ts +201 -199
  42. package/src/builder/report-settings.ts +64 -60
  43. package/src/builder/rest-modules.ts +145 -143
  44. package/src/builder/sampledata.ts +59 -52
  45. package/src/builder/scheduling.ts +180 -159
  46. package/src/builder/scripts.ts +71 -65
  47. package/src/builder/sql-charts.ts +36 -30
  48. package/src/builder/sql-monitor.ts +95 -89
  49. package/src/builder/sql-utilities.ts +47 -40
  50. package/src/builder/top-sql.ts +21 -17
  51. package/src/builder/unload.ts +48 -44
  52. package/src/builder/worksheet.ts +3 -3
  53. package/src/cron-schedule.ts +47 -17
  54. package/src/metadata.ts +3 -1
  55. package/src/runtime/calendar.ts +3 -2
  56. package/src/runtime/context.ts +2 -0
  57. package/src/runtime/grid.ts +1 -0
  58. package/src/runtime/maps.ts +7 -4
  59. package/src/runtime/render.ts +6 -1
  60. package/src/runtime/routes.ts +4 -0
  61. package/src/runtime/tree.ts +4 -3
@@ -2426,4 +2426,1631 @@ export const en = {
2426
2426
  'gallery.item.autocomplete': 'Text Field with Autocomplete',
2427
2427
  'gallery.item.percent_graph': 'Percent Graph',
2428
2428
  'gallery.item.display_map': 'Display Map',
2429
+ // ------------------------------------------------------------ SQL Monitor, Top SQL (sprint 162, CD-8)
2430
+ 'sm.views': 'SQL Monitor views',
2431
+ 'sm.sessions': 'Sessions',
2432
+ 'sm.active': 'Active',
2433
+ 'sm.idle_tx': 'Idle in a transaction',
2434
+ 'sm.blocked': 'Blocked',
2435
+ 'sm.longest': 'Longest running (s)',
2436
+ 'sm.cancel': 'Cancel',
2437
+ 'sm.terminate': 'Terminate',
2438
+ 'sm.cancel_confirm': 'Cancel the statement session {pid} is running?',
2439
+ 'sm.terminate_confirm': 'Terminate session {pid}? Its open transaction is rolled back and the client is disconnected.',
2440
+ 'sm.cancel_label': 'Cancel the statement of session {pid}',
2441
+ 'sm.terminate_label': 'Terminate session {pid}',
2442
+ 'sm.sessions_intro': 'The client sessions of this database (pg_stat_activity), without idle ones, active ones first.',
2443
+ 'sm.sessions_intro_all': 'The client sessions of this database (pg_stat_activity), active ones first.',
2444
+ 'sm.hide_idle': 'Hide idle sessions',
2445
+ 'sm.show_idle': 'Show idle sessions',
2446
+ 'sm.query_text_note': 'A query\'s text is shown only for roles whose statistics the owner may read ({role}).',
2447
+ 'sm.col.user': 'User',
2448
+ 'sm.col.application': 'Application',
2449
+ 'sm.col.state': 'State',
2450
+ 'sm.col.wait': 'Wait',
2451
+ 'sm.col.running': 'Running (s)',
2452
+ 'sm.col.blocked_by': 'Blocked by',
2453
+ 'sm.col.query': 'Query',
2454
+ 'sm.col.actions': 'Actions',
2455
+ 'sm.statement_link': 'Statistics and plan of this statement',
2456
+ 'sm.no_other': 'No other sessions.',
2457
+ 'sm.no_busy': 'No busy sessions.',
2458
+ 'sm.waits': 'Wait events',
2459
+ 'sm.waits_intro': 'What the active sessions of the server wait for now ({cpu} when they don\'t wait).',
2460
+ 'sm.cpu_running': 'CPU: running',
2461
+ 'sm.col.type': 'Type',
2462
+ 'sm.col.event': 'Event',
2463
+ 'sm.no_other_active': 'No other active sessions.',
2464
+ 'sm.in_progress': 'In progress',
2465
+ 'sm.col.command': 'Command',
2466
+ 'sm.col.object': 'Object',
2467
+ 'sm.col.phase': 'Phase',
2468
+ 'sm.col.done': 'Done',
2469
+ 'sm.updated': 'Updated {time} UTC',
2470
+ 'sm.refresh': 'Refresh',
2471
+ 'sm.refresh_every': 'Refresh every',
2472
+ 'sm.seconds': '{n} seconds',
2473
+ 'sm.pause': 'Pause',
2474
+ 'sm.not_client': 'Session {pid} isn\'t a client session of this database (any more).',
2475
+ 'sm.cancelled': 'Asked session {pid} to cancel its statement.',
2476
+ 'sm.terminated': 'Terminated session {pid}.',
2477
+ 'sm.not_signalled': 'Session {pid} could not be signalled.',
2478
+ 'sm.col.role': 'Role',
2479
+ 'sm.col.calls': 'Calls',
2480
+ 'sm.col.total_ms': 'Total ms',
2481
+ 'sm.col.mean_ms': 'Mean ms',
2482
+ 'sm.col.rows': 'Rows',
2483
+ 'sm.col.hit': 'Blocks hit',
2484
+ 'sm.col.read': 'Blocks read',
2485
+ 'sm.col.statement': 'Statement',
2486
+ 'sm.sort_by': 'Sort by {column}',
2487
+ 'sm.contains': 'Statement contains',
2488
+ 'sm.no_match': 'No statements match.',
2489
+ 'sm.none_yet': 'No statements recorded yet.',
2490
+ 'sm.since': 'Statistics since {time}.',
2491
+ 'sm.at_most': 'At most 100 statements are shown; literals and binds show as {p1}, {p2}….',
2492
+ 'sm.reset_confirm': 'Clear the statement statistics of the whole server?',
2493
+ 'sm.reset': 'Reset statistics',
2494
+ 'sm.reset_done': 'Statement statistics reset.',
2495
+ 'sm.top_intro': 'The statements of this database from {ext}, every role. Click a statement for its plan.',
2496
+ 'sm.statement': 'Statement',
2497
+ 'sm.temp_blocks_written': 'Temp blocks written',
2498
+ 'sm.text': 'Text',
2499
+ 'sm.sql_text': 'SQL text',
2500
+ 'sm.open_worksheet': 'Open in worksheet',
2501
+ 'sm.back_top': 'Back to Top SQL',
2502
+ 'sm.by_role': 'By role',
2503
+ 'sm.nested': 'nested',
2504
+ 'sm.col.stddev_ms': 'Std dev ms',
2505
+ 'sm.col.min_ms': 'Min ms',
2506
+ 'sm.col.max_ms': 'Max ms',
2507
+ 'sm.col.hit_short': 'Hit',
2508
+ 'sm.col.read_short': 'Read',
2509
+ 'sm.col.temp_read': 'Temp read',
2510
+ 'sm.col.temp_written': 'Temp written',
2511
+ 'sm.explain_plan': 'Explain Plan',
2512
+ 'sm.explain_intro': 'EXPLAIN without running the statement. Unqualified names are looked up in the schema you choose first.',
2513
+ 'sm.explain_intro_params': 'EXPLAIN without running the statement: its parameters ($1, …) get a generic plan. Unqualified names are looked up in the schema you choose first.',
2514
+ 'sm.schema': 'Schema',
2515
+ 'sm.search_path': '(the search path)',
2516
+ 'sm.explain': 'Explain',
2517
+ 'sm.err.one': 'Only one SQL statement can be explained.',
2518
+ 'sm.err.kind': 'Only SELECT, INSERT, UPDATE, DELETE, MERGE and VALUES statements have a plan.',
2519
+ 'sm.err.generic': 'The statement has parameters ($1, …): PostgreSQL 16 or later can explain it with a generic plan. Open it in the worksheet and fill in values.',
2520
+ 'sm.err.params': 'The statement has too many parameters to explain.',
2521
+ 'topsql.not_installed': 'The {ext} extension isn\'t installed in this database. To turn it on: set {setting} (postgresql.conf, or {alter}), restart PostgreSQL, then as a superuser: {create}',
2522
+ 'topsql.not_loaded': 'The server doesn\'t load {ext} yet. Set {setting} (the development {compose} does) and restart PostgreSQL.',
2523
+ 'topsql.read_error': 'The statistics could not be read: {message}',
2524
+ 'topsql.sort_by': 'Sort by {total} {mean} {calls} {rows}',
2525
+ 'topsql.sort.total': 'total time',
2526
+ 'topsql.sort.mean': 'time per call',
2527
+ 'topsql.sort.calls': 'calls',
2528
+ 'topsql.sort.rows': 'rows',
2529
+ 'topsql.share': 'Share',
2530
+ 'topsql.reset_confirm': 'Clear the statistics of role {role}?',
2531
+ 'topsql.reset': 'Reset the statistics',
2532
+ 'topsql.none_yet': 'No statements recorded for {role} yet. Use the application, then come back.',
2533
+ 'topsql.no_role': 'This application runs as the owner role, so its statements can\'t be told apart. Give it a database role in Settings.',
2534
+ 'topsql.owner': '(owner)',
2535
+ 'topsql.intro': 'Statements run as the role {role} since the statistics were last reset, from {ext}. Literals and binds show as {p1}, {p2}…; applications that share a role share this list.',
2536
+ 'topsql.back_activity': 'Back to Activity',
2537
+ 'topsql.activity': 'Activity',
2538
+ 'topsql.no_db_role': 'The application has no database role.',
2539
+ 'topsql.reset_done': 'Statistics reset.',
2540
+ // ------------------------------------------------------------ SQL Monitor and Data Modeler in the browser (sprint 162)
2541
+ 'js.sm.resume': 'Resume',
2542
+ 'js.sm.pause': 'Pause',
2543
+ 'js.sm.stopped': 'Refresh stopped: the monitor could not be reached (signed out?). Reload the page.',
2544
+ 'js.dm.unsaved': 'Unsaved changes',
2545
+ 'js.dm.saving': 'Saving…',
2546
+ 'js.dm.saved': 'Saved',
2547
+ 'js.dm.not_saved': 'Not saved ({error}): try again',
2548
+ 'js.dm.no_png': 'The PNG could not be made: export SVG instead',
2549
+ // ------------------------------------------------------------ Quick SQL, SQL Scripts (sprint 162, CD-8)
2550
+ 'qs.syntax': 'Syntax',
2551
+ 'qs.syntax.tables': 'A table name on a line of its own, its columns indented below it. A table indented under another table is a child table: it gets `<parent>_id` referencing the parent.',
2552
+ 'qs.syntax.types': 'Column types from the name (`*_id` bigint, `*_at` timestamptz, `*_date`/`*_on` date, `is_*` boolean, `price`/`amount` numeric, otherwise text) or written after it: `vc200`, `num`, `num(10,2)`, `int`, `date`, `ts`, `tstz`, `clob`, `blob`, `json`, `bool`, `uuid`.',
2553
+ 'qs.syntax.directives': 'Column directives: `/nn`, `/pk`, `/unique`, `/idx`, `/fk table`, `/check a, b`, `/between 1 and 10`, `/default value`, `/lower`, `/upper`; `[a comment]`. Table directive: `/auditcols`.',
2554
+ 'qs.syntax.settings': 'Settings: `# pk: identity | seq | guid | none`, `# schema: name`, `# prefix: xx`, `# drop: true`, `# auditcols: true`, or `# settings = { pk: "guid", schema: "app" }`.',
2555
+ 'qs.syntax.views': '`view name table1 table2`: a view joining the tables by their foreign keys. `--` starts a comment.',
2556
+ 'qs.generate': 'Generate SQL',
2557
+ 'qs.line': 'Line {line}: {message}',
2558
+ 'qs.generated': 'Generated SQL',
2559
+ 'qs.save_or_run': 'Save or run',
2560
+ 'qs.script_name': 'Script name',
2561
+ 'qs.save_script': 'Save as script',
2562
+ 'qs.run': 'Run',
2563
+ 'qs.too_large': 'The Quick SQL is larger than 1 MB.',
2564
+ 'qs.script_too_large': 'The generated script is too large.',
2565
+ 'qs.saved': 'Saved as script “{name}”.',
2566
+ 'scr.error': 'Error',
2567
+ 'scr.skipped': 'Skipped',
2568
+ 'scr.not_run': 'Not run',
2569
+ 'scr.summary': '{n} statement(s): {ok} succeeded, {failed} failed.',
2570
+ 'scr.summary_rest': '{n} statement(s): {ok} succeeded, {failed} failed, {rest} not run or skipped.',
2571
+ 'scr.rolled_back_note': 'The transaction was rolled back: nothing was changed.',
2572
+ 'scr.no_statements': 'The script has no statements.',
2573
+ 'scr.line': 'line {line}',
2574
+ 'scr.done': 'done',
2575
+ 'scr.rows': '{n} row(s)',
2576
+ 'scr.first_rows': 'First {shown} of {n} row(s).',
2577
+ 'scr.when_fails': 'When a statement fails',
2578
+ 'scr.stop': 'Stop the script',
2579
+ 'scr.continue': 'Continue with the next statement',
2580
+ 'scr.one_tx': 'Run in one transaction (with “Stop”, a failure rolls back the whole script)',
2581
+ 'scr.col.started': 'Started',
2582
+ 'scr.col.script': 'Script',
2583
+ 'scr.col.by': 'By',
2584
+ 'scr.col.statements': 'Statements',
2585
+ 'scr.col.failed': 'Failed',
2586
+ 'scr.col.result': 'Result',
2587
+ 'scr.rolled_back': 'Rolled back',
2588
+ 'scr.errors': 'Errors',
2589
+ 'scr.no_runs': 'No runs yet.',
2590
+ 'scr.col.updated': 'Updated',
2591
+ 'scr.col.size': 'Size',
2592
+ 'scr.col.last_run': 'Last run',
2593
+ 'scr.col.open': 'Open',
2594
+ 'scr.by': 'by {user}',
2595
+ 'scr.never': 'never',
2596
+ 'scr.worksheet': 'Worksheet',
2597
+ 'scr.download': 'Download',
2598
+ 'scr.none_yet': 'No scripts yet. Create one, upload a .sql file, or generate one with Quick SQL.',
2599
+ 'scr.create': 'Create script',
2600
+ 'scr.scripts': 'Scripts',
2601
+ 'scr.upload_title': 'Upload a script',
2602
+ 'scr.file': '.sql file (UTF-8, up to {mb} MB)',
2603
+ 'scr.upload': 'Upload',
2604
+ 'scr.recent_runs': 'Recent runs',
2605
+ 'scr.name': 'Name',
2606
+ 'scr.description': 'Description',
2607
+ 'scr.content_help': 'Statements end with a semicolon (outside strings, comments and $$ bodies). psql commands (\\set, \\i …) are skipped.',
2608
+ 'scr.statements': '{n} statement(s).',
2609
+ 'scr.save': 'Save',
2610
+ 'scr.save_run': 'Save and run',
2611
+ 'scr.delete_confirm': 'Delete this script and its run history?',
2612
+ 'scr.delete': 'Delete',
2613
+ 'scr.new': 'New script',
2614
+ 'scr.script_title': 'Script: {name}',
2615
+ 'scr.runs': 'Runs',
2616
+ 'scr.err.name': 'Give the script a name (at most 200 characters).',
2617
+ 'scr.err.size': 'The script is larger than {mb} MB.',
2618
+ 'scr.err.exists': 'A script named “{name}” already exists.',
2619
+ 'scr.saved': 'Script “{name}” saved.',
2620
+ 'scr.deleted': 'Script “{name}” deleted.',
2621
+ 'scr.err.choose': 'Choose a .sql file.',
2622
+ 'scr.err.file_size': 'The file is larger than {mb} MB.',
2623
+ 'scr.err.utf8': 'The file is not UTF-8 text.',
2624
+ 'scr.err.text': 'The file is not a text file.',
2625
+ 'scr.uploaded': 'Script “{name}” uploaded.',
2626
+ 'scr.opt.stop': 'stop on error',
2627
+ 'scr.opt.continue': 'continue on error',
2628
+ 'scr.opt.one_tx': 'one transaction',
2629
+ 'scr.results_title': 'Script results',
2630
+ 'scr.results': 'Results',
2631
+ 'scr.results_of': 'Results: {name}',
2632
+ 'scr.run_by': 'Run by {user} at {time} in {ms} ms ({options}).',
2633
+ 'scr.edit': 'Edit the script',
2634
+ // ------------------------------------------------------------ Generate DDL, Schema Comparison, Change Log (sprint 162, CD-8)
2635
+ 'ddl.type.types': 'Types and domains',
2636
+ 'ddl.type.sequences': 'Sequences',
2637
+ 'ddl.type.tables': 'Tables (constraints, indexes)',
2638
+ 'ddl.type.views': 'Views and materialized views',
2639
+ 'ddl.type.functions': 'Functions and procedures',
2640
+ 'ddl.type.triggers': 'Triggers',
2641
+ 'ddl.type.policies': 'Row level security and policies',
2642
+ 'ddl.choose_schema': '- choose a schema -',
2643
+ 'ddl.of': 'DDL of {schema}',
2644
+ 'ddl.objects_review': '{n} object(s). Review the script before you run it (SQL Workshop → SQL Scripts).',
2645
+ 'ddl.download': 'Download {file}',
2646
+ 'ddl.intro': 'The DDL of a schema\'s objects, from the database catalog, in an order that runs: types, sequences, tables, functions, views, constraints, indexes, triggers, row level security, comments and grants (APEX: Generate DDL). Objects of extensions are left out.',
2647
+ 'ddl.objects': 'Objects',
2648
+ 'ddl.comments': 'Comments',
2649
+ 'ddl.grants': 'Grants',
2650
+ 'ddl.generate': 'Generate',
2651
+ 'cmp.only_source': 'Only in the source',
2652
+ 'cmp.only_target': 'Only in the target',
2653
+ 'cmp.different': 'Different',
2654
+ 'cmp.n_only_source': '{n} only in the source',
2655
+ 'cmp.n_only_target': '{n} only in the target',
2656
+ 'cmp.n_different': '{n} different',
2657
+ 'cmp.apply_confirm': 'Run the change script on {target} in one transaction?',
2658
+ 'cmp.apply': 'Apply and record',
2659
+ 'cmp.apply_note': 'Runs the script on {target} (commented-out drops stay out) and records it in the {log}.',
2660
+ 'cmp.change_log': 'change log',
2661
+ 'cmp.two_different': 'Choose two different schemas.',
2662
+ 'cmp.summary': 'Summary',
2663
+ 'cmp.differences': '{n} difference(s): {parts}; {same} object(s) the same.',
2664
+ 'cmp.same': 'The schemas are the same ({n} objects).',
2665
+ 'cmp.both': '{source} and {target}',
2666
+ 'cmp.script_title': 'Change script: make {target} like {source}',
2667
+ 'cmp.script_intro': 'Creates what only {source} has, changes what differs, and lists what only {target} has as commented-out drops; columns that change identity or generation, and types, domains and sequences that differ, are left for review. Nothing runs until you choose Apply and record.',
2668
+ 'cmp.change_script': 'Change script',
2669
+ 'cmp.intro': 'Compares the objects of two schemas of this database by their DDL (APEX: Schema Comparison), e.g. a development copy with the schema it came from, and writes a script that makes the target like the source. The order of a table\'s columns is not compared.',
2670
+ 'cmp.source': 'Source',
2671
+ 'cmp.target': 'Target (to make like the source)',
2672
+ 'cmp.compare': 'Compare',
2673
+ 'cmp.nothing': '{target} is already like {source}: nothing to apply.',
2674
+ 'cmp.failed': 'Nothing was changed: the change script ran in one transaction, which was rolled back. {error}',
2675
+ 'cmp.applied': '{target} is now like {source}: {n} statement(s), recorded in the change log.',
2676
+ 'cl.from.table': 'Table Properties',
2677
+ 'cl.schemas': 'Schemas',
2678
+ 'cl.col.change_set': 'Change set',
2679
+ 'cl.col.author': 'Author',
2680
+ 'cl.col.recorded': 'Recorded',
2681
+ 'cl.col.from': 'From',
2682
+ 'cl.col.latest_export': 'Latest app export',
2683
+ 'cl.col.migration_file': 'Migration file',
2684
+ 'cl.rename': 'Rename',
2685
+ 'cl.delete_confirm': 'Delete change set {n} from the log? The database is not changed, and its number is not given again.',
2686
+ 'cl.in_it': 'in it',
2687
+ 'cl.after_it': 'after it',
2688
+ 'cl.written': 'written {time}',
2689
+ 'cl.not_yet': 'not yet',
2690
+ 'cl.none_yet': 'No change sets yet. DDL you run in the SQL Worksheet, apply in Table Properties or apply from Schema Comparison is recorded here.',
2691
+ 'cl.compare_with': 'Compare with the latest export of',
2692
+ 'cl.show': 'Show',
2693
+ 'cl.export_note': '✓ in it: recorded before the application was last exported, so a deployment of that export expects the change. {after}: still to be shipped with the next export.',
2694
+ 'cl.no_exports': 'No application of this workspace was exported from the builder yet (Application › Export): the change sets can\'t be compared with an export.',
2695
+ 'cl.format': 'Format',
2696
+ 'cl.format.flyway': 'Flyway: V0001__name.sql files (a zip for several)',
2697
+ 'cl.format.liquibase': 'Liquibase: formatted SQL changelog',
2698
+ 'cl.format.sql': 'Plain SQL script',
2699
+ 'cl.change_sets': 'Change sets',
2700
+ 'cl.which.pending': 'Not yet written to a file ({n})',
2701
+ 'cl.which.all': 'All of {schema} ({n})',
2702
+ 'cl.which.after': 'After the latest export of {app} ({n})',
2703
+ 'cl.download': 'Download migration',
2704
+ 'cl.intro': 'The change log (Liquibase, Flyway): DDL run from the SQL Worksheet, Table Properties and Schema Comparison is kept as change sets per schema, with who ran it and when. Download them as a migration for another database: Flyway versioned files, a Liquibase formatted SQL changelog or a plain script. Only statements that succeeded are kept; data changes (INSERT, UPDATE, DELETE) are not.',
2705
+ 'cl.change_sets_of': 'Change sets of {schema}',
2706
+ 'cl.nothing_to_write': 'No change sets to write: every one is in an earlier file. Choose "All".',
2707
+ 'cl.bad_name': 'A name is lower case letters, digits and _ (at most 60), starting with a letter or digit.',
2708
+ 'cl.renamed': 'Change set {n} is now {file}.',
2709
+ 'cl.deleted': 'Change set {n} removed from the log; the database is unchanged.',
2710
+ // ------------------------------------------------------------ Charts, Unload Data (sprint 162, CD-8)
2711
+ 'ch.kind.bar': 'Bar',
2712
+ 'ch.kind.column': 'Column',
2713
+ 'ch.kind.stacked': 'Stacked bar',
2714
+ 'ch.kind.line': 'Line',
2715
+ 'ch.kind.area': 'Area',
2716
+ 'ch.kind.donut': 'Donut',
2717
+ 'ch.kind.pie': 'Pie',
2718
+ 'ch.kind.scatter': 'Scatter',
2719
+ 'ch.type': 'Type',
2720
+ 'ch.labels': 'Labels',
2721
+ 'ch.values': 'Values',
2722
+ 'ch.no_number': 'The query has no number column to draw.',
2723
+ 'ch.row_one': '1 row.',
2724
+ 'ch.rows': '{n} rows.',
2725
+ 'ch.rows_first': '{n} rows (the first {n}).',
2726
+ 'ch.intro': 'Queries drawn as charts. Make one from a query in the {worksheet} (its Chart tab, Ctrl+F11), then save it.',
2727
+ 'ch.all': 'All charts',
2728
+ 'ch.chart': 'Chart',
2729
+ 'ch.on_dashboard_col': 'On the dashboard',
2730
+ 'ch.changed': 'Changed',
2731
+ 'ch.yes': 'Yes',
2732
+ 'ch.no': 'No',
2733
+ 'ch.none_yet': 'No charts yet.',
2734
+ 'ch.on_dashboard': 'On the Charts dashboard',
2735
+ 'ch.query': 'The query',
2736
+ 'ch.open_worksheet': 'Open in the worksheet',
2737
+ 'ch.delete_confirm': 'Delete the chart {name}?',
2738
+ 'ch.deleted': 'Deleted the chart {name}.',
2739
+ 'ch.err.name': 'A chart needs a name (at most 120 characters).',
2740
+ 'ch.err.exists': 'A chart named “{name}” exists already.',
2741
+ 'ch.saved': 'Saved the chart {name}.',
2742
+ 'ch.err.select': 'Only a chart of one SELECT can be saved.',
2743
+ 'ch.err.name_new': 'Name the chart to save it (at most 120 characters).',
2744
+ 'ch.saved_new': 'Saved the chart {name}: it is on the Charts dashboard.',
2745
+ 'ul.fmt.xlsx': 'Excel (.xlsx)',
2746
+ 'ul.fmt.sql': 'SQL inserts',
2747
+ 'ul.separator': 'Separator',
2748
+ 'ul.sep.comma': 'Comma ,',
2749
+ 'ul.sep.semicolon': 'Semicolon ;',
2750
+ 'ul.sep.tab': 'Tab',
2751
+ 'ul.sep.pipe': 'Pipe |',
2752
+ 'ul.enclosed': 'Enclosed by',
2753
+ 'ul.enc.double': 'Double quote "',
2754
+ 'ul.enc.single': 'Single quote \'',
2755
+ 'ul.enclosed_help': 'Only values that contain the separator, the enclosure or a line break are enclosed.',
2756
+ 'ul.header': 'First row: column names',
2757
+ 'ul.bom': 'UTF-8 byte order mark (for Excel)',
2758
+ 'ul.root': 'Root element',
2759
+ 'ul.row': 'Row element',
2760
+ 'ul.row_help': 'One child element per column; empty (null) values are left out.',
2761
+ 'ul.from': 'Unload from',
2762
+ 'ul.table_or_view': 'Table or view',
2763
+ 'ul.intro': 'Download the rows of a table, a view or a query as CSV, JSON, Excel or XML (up to {n} rows).',
2764
+ 'ul.intro2': 'Runs as the builder\'s owner connection (an isolated workspace\'s developer login for its developers) in a read-only transaction. To load a file into a table, use {load}.',
2765
+ 'ul.unload_query': 'Unload a query',
2766
+ 'ul.one_select': 'One SELECT (or WITH … SELECT) statement.',
2767
+ 'ul.choose_table': '- choose a table or view -',
2768
+ 'ul.view': '(view)',
2769
+ 'ul.choose': 'Choose',
2770
+ 'ul.unload_table': 'Unload a table or view',
2771
+ 'ul.unload_of': 'Unload {name}',
2772
+ 'ul.columns': 'Columns',
2773
+ 'ul.where': 'Where',
2774
+ 'ul.eg': 'e.g. {x}',
2775
+ 'ul.where_help': 'Optional: a condition, without the word WHERE.',
2776
+ 'ul.order': 'Order by',
2777
+ 'ul.order_help': 'Optional: columns, without the words ORDER BY.',
2778
+ 'ul.err.table': 'Choose a table or view.',
2779
+ 'ul.err.column': 'Choose at least one column.',
2780
+ 'ul.err.failed': 'The query failed: {error}',
2781
+ // ------------------------------------------------------------ Sample Data (sprint 162, CD-8)
2782
+ 'sd.help': 'Generators and their options',
2783
+ 'sd.intro': 'Generate realistic rows for the tables of a schema: names, e-mail addresses, dates and numbers in a range, values from a list, foreign keys that pick existing parent rows. Preview them, insert them in one transaction (parents first) or download them as SQL or CSV. Runs as the builder\'s owner connection (an isolated workspace\'s developer login for its developers), like the {worksheet}.',
2784
+ 'sd.none_saved': 'No saved generators yet: generate rows below, then save the definition to run it again.',
2785
+ 'sd.table_one': '1 table',
2786
+ 'sd.tables_n': '{n} tables',
2787
+ 'sd.tables_of': 'Tables of {schema}',
2788
+ 'sd.about_rows': '~{n} rows',
2789
+ 'sd.propose': 'Propose generators',
2790
+ 'sd.own_schema': 'Choose a schema of your own: not meta, information_schema or pg_*.',
2791
+ 'sd.new': 'New generator',
2792
+ 'sd.saved_title': 'Saved generators',
2793
+ 'sd.generator': 'Generator',
2794
+ 'sd.col_generator': '{column}: generator',
2795
+ 'sd.col_options': '{column}: options',
2796
+ 'sd.options': 'options',
2797
+ 'sd.col_nulls': '{column}: % nulls',
2798
+ 'sd.pct_null': '% null',
2799
+ 'sd.missing': 'Not found any more, left out: {tables}.',
2800
+ 'sd.seed': 'Seed',
2801
+ 'sd.seed_help': 'The same seed gives the same rows (for the same tables and parent rows). Empty: a new seed each run; a preview fills it in, so Insert then adds the rows you saw.',
2802
+ 'sd.change_tables': 'change tables',
2803
+ 'sd.preview': 'Preview',
2804
+ 'sd.insert': 'Insert rows',
2805
+ 'sd.download_sql': 'Download SQL',
2806
+ 'sd.download_csv': 'Download CSV',
2807
+ 'sd.save_def': 'Save the definition',
2808
+ 'sd.save_new': 'Save as new generator',
2809
+ 'sd.delete_confirm': 'Delete this generator definition? Rows already inserted stay.',
2810
+ 'sd.delete': 'Delete generator',
2811
+ 'sd.inserted': 'Inserted',
2812
+ 'sd.inserted_counts': '{counts} inserted (seed {seed}).',
2813
+ 'sd.rolled_back': 'Rolled back: nothing was saved.',
2814
+ 'sd.seed_is': 'seed {seed}',
2815
+ 'sd.first_of': 'first {shown} of {n}',
2816
+ 'sd.no_rows': 'No rows.',
2817
+ 'sd.err.name': 'Give the generator a name to save it.',
2818
+ 'sd.err.length': 'The name is at most 100 characters, the description 1000.',
2819
+ 'sd.err.table': 'Choose at least one table.',
2820
+ 'sd.saved': 'Generator {name} saved.',
2821
+ 'sd.err.action': 'Unknown action.',
2822
+ 'sd.nothing_inserted': 'Nothing was inserted: the transaction was rolled back.',
2823
+ 'sd.deleted': 'Generator {name} deleted.',
2824
+ // ------------------------------------------------------------ Sample Data generators (run-time keys sd.gen.*, sd.opt.*)
2825
+ 'sd.gen.skip': 'Skip (default / identity)',
2826
+ 'sd.gen.first_name': 'First name',
2827
+ 'sd.gen.last_name': 'Last name',
2828
+ 'sd.gen.full_name': 'Full name',
2829
+ 'sd.gen.email': 'E-mail address',
2830
+ 'sd.gen.username': 'User name',
2831
+ 'sd.gen.phone': 'Phone number',
2832
+ 'sd.gen.company': 'Company name',
2833
+ 'sd.gen.job_title': 'Job title',
2834
+ 'sd.gen.address': 'Street address',
2835
+ 'sd.gen.postal_code': 'Postal code',
2836
+ 'sd.gen.city': 'City',
2837
+ 'sd.gen.country': 'Country',
2838
+ 'sd.gen.word': 'Word',
2839
+ 'sd.gen.words': 'Words (title)',
2840
+ 'sd.gen.sentence': 'Sentence',
2841
+ 'sd.gen.code': 'Code (pattern)',
2842
+ 'sd.gen.url': 'Web address',
2843
+ 'sd.gen.uuid': 'UUID',
2844
+ 'sd.gen.integer': 'Whole number (range)',
2845
+ 'sd.gen.decimal': 'Decimal number (range)',
2846
+ 'sd.gen.date': 'Date (range)',
2847
+ 'sd.gen.timestamp': 'Timestamp (range)',
2848
+ 'sd.gen.time': 'Time of day (range)',
2849
+ 'sd.gen.boolean': 'Boolean (% true)',
2850
+ 'sd.gen.list': 'Value from a list',
2851
+ 'sd.gen.sequence': 'Sequence (start, step)',
2852
+ 'sd.gen.foreign_key': 'Foreign key (existing parent row)',
2853
+ 'sd.gen.fixed': 'Fixed value',
2854
+ 'sd.opt.skip': 'not inserted: the column default, identity or null',
2855
+ 'sd.opt.first_name': 'no options',
2856
+ 'sd.opt.last_name': 'no options',
2857
+ 'sd.opt.full_name': 'no options',
2858
+ 'sd.opt.email': 'no options',
2859
+ 'sd.opt.username': 'no options',
2860
+ 'sd.opt.phone': 'no options',
2861
+ 'sd.opt.company': 'no options',
2862
+ 'sd.opt.job_title': 'no options',
2863
+ 'sd.opt.address': 'no options',
2864
+ 'sd.opt.postal_code': 'no options',
2865
+ 'sd.opt.city': 'no options',
2866
+ 'sd.opt.country': 'no options',
2867
+ 'sd.opt.word': 'no options',
2868
+ 'sd.opt.words': 'number of words, e.g. 1..3',
2869
+ 'sd.opt.sentence': 'number of words, e.g. 4..12',
2870
+ 'sd.opt.code': 'pattern: A letter, a lower-case letter, 9 digit, other characters as typed, e.g. AAA-9999',
2871
+ 'sd.opt.url': 'no options',
2872
+ 'sd.opt.uuid': 'no options',
2873
+ 'sd.opt.integer': 'min..max, e.g. 1..1000; or another column plus a range, e.g. quantity + 0..10',
2874
+ 'sd.opt.decimal': 'min..max; the decimals of the column or of the numbers, e.g. 0.00..999.99; or column + min..max',
2875
+ 'sd.opt.date': 'from..to, e.g. 2021-01-01..2026-12-31; or another column plus days, e.g. start_date + 0..14',
2876
+ 'sd.opt.timestamp': 'from..to (dates), e.g. 2021-01-01..2026-12-31; or column + min..max days, e.g. created_at + 0..2',
2877
+ 'sd.opt.time': 'from..to, e.g. 08:00..18:00',
2878
+ 'sd.opt.boolean': 'percentage true, e.g. 50',
2879
+ 'sd.opt.list': 'values separated by commas, e.g. NEW, OPEN, CLOSED',
2880
+ 'sd.opt.sequence': 'start or start, step, e.g. 1000, 10',
2881
+ 'sd.opt.foreign_key': 'a random existing parent row; parents generated in the same run are inserted first',
2882
+ 'sd.opt.fixed': 'the value',
2883
+ // ------------------------------------------------------------ Query Builder (sprint 162, CD-8)
2884
+ 'qb.tables': 'Tables and views',
2885
+ 'qb.tables_of': 'Tables and views of {schema}',
2886
+ 'qb.view': 'view',
2887
+ 'qb.no_tables': 'This schema has no tables or views.',
2888
+ 'qb.apply': 'Apply',
2889
+ 'qb.columns_help': 'None ticked: all columns. A function (count, sum, …) groups the rows by the other chosen columns. Drag a table by its handle (or focus the handle and use the arrow keys); drag the dot next to a column onto a column of another table to join them.',
2890
+ 'qb.distinct': 'Distinct rows',
2891
+ 'qb.move': 'Move {table} (arrow keys)',
2892
+ 'qb.drag_move': 'Drag to move',
2893
+ 'qb.function_for': 'Function for {column}',
2894
+ 'qb.join_label': 'Join {column} to a column of another table',
2895
+ 'qb.join_title': 'Drag onto a column of another table to join them',
2896
+ 'qb.joins': 'Joins',
2897
+ 'qb.joins_help': 'From the foreign keys between the chosen tables, or the columns you joined.',
2898
+ 'qb.cross_join': 'No foreign key connects {table} to the other tables: it is cross joined. Join two of their columns on the canvas, or under Joins.',
2899
+ 'qb.on': 'on',
2900
+ 'qb.and': 'and',
2901
+ 'qb.cross': 'cross join',
2902
+ 'qb.join_type': 'Join type for {table}',
2903
+ 'qb.inner': 'inner join',
2904
+ 'qb.left': 'left join (keep rows without a match)',
2905
+ 'qb.join_two': 'Join two columns',
2906
+ 'qb.join_a': 'Join: column',
2907
+ 'qb.join_b': 'Join: column of another table',
2908
+ 'qb.conditions': 'Conditions',
2909
+ 'qb.rows_match': 'Rows must match',
2910
+ 'qb.all': 'all conditions',
2911
+ 'qb.any': 'any condition',
2912
+ 'qb.cond_column': 'Condition {n}: column',
2913
+ 'qb.cond_operator': 'Condition {n}: operator',
2914
+ 'qb.cond_value': 'Condition {n}: value',
2915
+ 'qb.add_condition': 'Apply / add a condition',
2916
+ 'qb.sort_limit': 'Sort and limit',
2917
+ 'qb.sort_column': 'Sort {n}: column',
2918
+ 'qb.sort_dir': 'Sort {n}: direction',
2919
+ 'qb.asc': 'ascending',
2920
+ 'qb.desc': 'descending',
2921
+ 'qb.limit': 'At most (rows)',
2922
+ 'qb.run': 'Run in the SQL Worksheet',
2923
+ 'qb.fn.count': 'count',
2924
+ 'qb.fn.count_distinct': 'count distinct',
2925
+ 'qb.fn.sum': 'sum',
2926
+ 'qb.fn.avg': 'average',
2927
+ 'qb.fn.min': 'minimum',
2928
+ 'qb.fn.max': 'maximum',
2929
+ 'qb.op.eq': 'equals',
2930
+ 'qb.op.ne': 'not equal',
2931
+ 'qb.op.lt': 'less than',
2932
+ 'qb.op.le': 'at most',
2933
+ 'qb.op.gt': 'greater than',
2934
+ 'qb.op.ge': 'at least',
2935
+ 'qb.op.like': 'like (% _)',
2936
+ 'qb.op.ilike': 'like, any case',
2937
+ 'qb.op.in': 'in (a, b, c)',
2938
+ 'qb.op.is_null': 'is empty',
2939
+ 'qb.op.is_not_null': 'is not empty',
2940
+ // ------------------------------------------------------------ Object actions menu (sprint 162, CD-8)
2941
+ 'oa.actions_for': 'Actions for {name}',
2942
+ 'oa.open': 'Open',
2943
+ 'oa.edit': 'Edit…',
2944
+ 'oa.template': 'Use as template',
2945
+ 'oa.security': 'Security…',
2946
+ 'oa.load': 'Load data',
2947
+ 'oa.fulltext': 'Add full-text search…',
2948
+ 'oa.vector': 'Add vector column…',
2949
+ 'oa.document': 'Document view…',
2950
+ 'oa.index': 'Add index',
2951
+ 'oa.trigger': 'Add trigger',
2952
+ 'oa.policy': 'Add policy',
2953
+ 'oa.rest': 'REST › Enable / Disable',
2954
+ 'oa.ddl': 'Quick DDL to the worksheet',
2955
+ 'oa.ddl_file': 'Quick DDL as a file',
2956
+ 'oa.drop': 'Drop…',
2957
+ 'oa.flash.ddl': 'The DDL of {name}.',
2958
+ 'oa.flash.drop': 'Review the DROP statement and run it yourself: nothing has been dropped yet.',
2959
+ 'oa.flash.fill': 'Fill in the statement and run it: nothing has been changed yet.',
2960
+ // ------------------------------------------------------------ Data Modeler (sprint 162, CD-8)
2961
+ 'dm.diagrams': 'Diagrams',
2962
+ 'dm.delete_confirm': 'Delete the diagram {name}? The tables stay as they are.',
2963
+ 'dm.delete_confirm_short': 'Delete the diagram {name}?',
2964
+ 'dm.none_yet': 'No diagrams in this workspace yet.',
2965
+ 'dm.name_placeholder': 'core tables',
2966
+ 'dm.objects_placeholder': 'orders, customers or *',
2967
+ 'dm.objects_help': 'Names separated by commas or spaces; `*` for all, `ord*` for those starting with ord. You can add more later.',
2968
+ 'dm.create': 'Create diagram',
2969
+ 'dm.intro': 'Relational diagrams of a schema\'s tables and views: their columns, keys and the foreign keys between them. From a diagram: its DDL and a data dictionary.',
2970
+ 'dm.schema_gone': 'The schema {schema} doesn\'t exist any more, or this workspace can\'t use it.',
2971
+ 'dm.delete_diagram': 'Delete diagram',
2972
+ 'dm.diagram': 'Diagram',
2973
+ 'dm.undo': 'Undo',
2974
+ 'dm.redo': 'Redo',
2975
+ 'dm.zoom_out': 'Zoom out',
2976
+ 'dm.zoom_in': 'Zoom in',
2977
+ 'dm.fit': 'Fit',
2978
+ 'dm.auto': 'Auto layout',
2979
+ 'dm.minimap': 'Mini-map',
2980
+ 'dm.export_svg': 'Export SVG',
2981
+ 'dm.print': 'Print',
2982
+ 'dm.dictionary': 'Data dictionary',
2983
+ 'dm.add_objects': 'Add objects',
2984
+ 'dm.objects_in': 'Objects in this diagram',
2985
+ 'dm.kind': 'Kind',
2986
+ 'dm.references': 'References',
2987
+ 'dm.remove_label': 'Remove {name} from the diagram',
2988
+ 'dm.remove': 'Remove',
2989
+ 'dm.no_objects': 'No objects yet: add some below.',
2990
+ 'dm.search_label': 'Search the tables and views of {schema}',
2991
+ 'dm.search_placeholder': 'Part of a name, emp*, or * for all',
2992
+ 'dm.found': '{n} found',
2993
+ 'dm.found_first': '500 found (the first 500)',
2994
+ 'dm.add_to': 'Add to diagram',
2995
+ 'dm.nothing_matches': 'Nothing else matches {q}.',
2996
+ 'dm.settings': 'Rename or delete the diagram',
2997
+ 'dm.head': 'Schema {schema} · {n} objects · updated {time} by {user}',
2998
+ 'dm.missing': 'Not in {schema} any more: {names}. Saving the diagram leaves them out.',
2999
+ 'dm.canvas_label': 'Diagram {name}: drag a box to move it, or focus it and use the arrow keys',
3000
+ 'dm.legend': 'P primary key · F foreign key · U unique · {star} not null · a line runs from the referencing table (crow\'s foot: many) to the referenced one (bar: one); dashed when the foreign key may be empty.',
3001
+ 'dm.legend_opens_table': 'A box\'s name opens Table Properties.',
3002
+ 'dm.legend_opens_object': 'A box\'s name opens the object.',
3003
+ 'dm.add_title': 'Add objects to diagram',
3004
+ 'dm.con.p': 'Primary key',
3005
+ 'dm.con.u': 'Unique',
3006
+ 'dm.con.f': 'Foreign key',
3007
+ 'dm.con.c': 'Check',
3008
+ 'dm.dict_title': 'Data dictionary: {name}',
3009
+ 'dm.dict_head': 'Schema {schema} · {n} objects · generated {time} UTC',
3010
+ 'dm.columns_of': 'Columns of {name}',
3011
+ 'dm.col.column': 'Column',
3012
+ 'dm.col.null': 'Null',
3013
+ 'dm.col.default': 'Default',
3014
+ 'dm.col.key': 'Key',
3015
+ 'dm.col.comment': 'Comment',
3016
+ 'dm.constraints': 'Constraints',
3017
+ 'dm.constraints_of': 'Constraints of {name}',
3018
+ 'dm.definition': 'Definition',
3019
+ 'dm.referenced_by': 'Referenced by',
3020
+ 'dm.err.name': 'A diagram needs a name.',
3021
+ 'dm.created_n': 'Diagram {name} created with {n} objects.',
3022
+ 'dm.created_empty': 'Diagram {name} created: add objects to it.',
3023
+ 'dm.err.exists': 'There is already a diagram {name} in this workspace.',
3024
+ 'dm.removed': '{name} removed from the diagram (the table stays as it is).',
3025
+ 'dm.err.nothing': 'Nothing to add: pick tables or views of the schema that aren\'t in the diagram.',
3026
+ 'dm.added': 'Added {n} objects: {names}.',
3027
+ 'dm.laid_out': 'The boxes were laid out again.',
3028
+ 'dm.saved': 'Diagram saved.',
3029
+ 'dm.renamed': 'Diagram renamed to {name}.',
3030
+ 'dm.deleted': 'Diagram {name} deleted.',
3031
+ 'dm.ddl_intro': 'The CREATE statements of the diagram\'s {n} objects in schema {schema}: tables, their keys, indexes, triggers, row level security, policies, comments and grants, and views. Review before running.',
3032
+ 'dm.back': 'Back to the diagram',
3033
+ 'dm.open_worksheet': 'Open in the SQL Worksheet',
3034
+ 'dm.download_html': 'Download HTML',
3035
+ 'dm.print_pdf': 'Print or save as PDF',
3036
+ // ------------------------------------------------------------ Data Modeler (singular)
3037
+ 'dm.added_one': 'Added 1 object: {names}.',
3038
+ // ------------------------------------------------------------ Change Log (note)
3039
+ 'cl.after_it_title': 'After it',
3040
+ // ------------------------------------------------------------ SQL Workshop Utilities, Object Reports, About Database (sprint 162, CD-8)
3041
+ 'su.title': 'SQL Workshop utilities',
3042
+ 'su.failed': 'The report failed.',
3043
+ 'su.nothing': 'Nothing found.',
3044
+ 'su.over': 'Over the schemas {role} may use.',
3045
+ 'su.col.owner': 'Owner',
3046
+ 'su.tables': 'Tables',
3047
+ 'su.setting': 'Setting',
3048
+ 'su.value': 'Value',
3049
+ 'su.extension': 'Extension',
3050
+ 'su.version': 'Version',
3051
+ 'su.database': 'Database',
3052
+ 'su.running_since': 'Running since',
3053
+ 'su.runs_as': 'The SQL Workshop runs as {user} (signed in as {login}).',
3054
+ 'su.settings': 'Settings',
3055
+ 'su.extensions': 'Extensions',
3056
+ 'su.no_schemas': 'No schemas.',
3057
+ 'su.r.no_primary_key': 'Tables without a primary key',
3058
+ 'su.r.no_primary_key.about': 'Forms, interactive grids and REST write-back need a key to find a row again.',
3059
+ 'su.r.unindexed_foreign_keys': 'Foreign keys without an index',
3060
+ 'su.r.unindexed_foreign_keys.about': 'Deleting or updating a parent row scans the child table, and joins from the parent are slower. An index on the foreign key columns (in this order) avoids it.',
3061
+ 'su.r.rls_without_policies': 'Row-level security without policies',
3062
+ 'su.r.rls_without_policies.about': 'Row-level security is enabled but the table has no policy: every role except its owner (and roles that bypass RLS) sees no rows and can change none.',
3063
+ 'su.r.no_row_level_security': 'Tables without row-level security',
3064
+ 'su.r.no_row_level_security.about': 'Every role with a grant on these tables sees and changes all their rows. Fine for lookup tables; enable row-level security where rows belong to users or tenants.',
3065
+ 'su.r.public_grants': 'Privileges granted to PUBLIC',
3066
+ 'su.r.public_grants.about': 'Every database role, including ones made later, has these privileges.',
3067
+ 'su.r.unused_indexes': 'Unused indexes',
3068
+ 'su.r.unused_indexes.about': 'Indexes not used by a query since the statistics were last reset (not primary keys or unique ones). They slow down writes and take space; check on every server (replicas count their own) before dropping one.',
3069
+ 'su.r.largest_tables': 'Largest tables',
3070
+ 'su.r.largest_tables.about': 'The 100 largest tables with their indexes and TOAST data.',
3071
+ 'su.r.no_comments': 'Tables without a comment',
3072
+ 'su.r.no_comments.about': 'Comments (COMMENT ON) document a data model; the App Builder and its AI read them. SQL Workshop → AI → Describe tables drafts them.',
3073
+ 'su.col.rows': 'Rows (estimate)',
3074
+ 'su.col.constraint': 'Foreign key',
3075
+ 'su.col.columns': 'Columns',
3076
+ 'su.col.parent': 'References',
3077
+ 'su.col.suggestion': 'Index',
3078
+ 'su.col.forced': 'Forced for the owner',
3079
+ 'su.col.grants': 'Granted to',
3080
+ 'su.col.kind': 'Kind',
3081
+ 'su.col.privileges': 'Privileges',
3082
+ 'su.col.index': 'Index',
3083
+ 'su.col.size': 'Size',
3084
+ 'su.col.table_size': 'Table',
3085
+ 'su.col.index_size': 'Indexes',
3086
+ 'su.col.total': 'Total',
3087
+ 'su.col.commented': 'With a comment',
3088
+ // ------------------------------------------------------------ SQL Workshop AI (sprint 162, CD-8)
3089
+ 'swai.service': 'AI service: {name} ({provider}, {model}). Table and column names, types and descriptions, and what you type, are sent to it.',
3090
+ 'swai.no_service': 'The App Builder has no AI service yet: ask an administrator to choose one here.',
3091
+ 'swai.service_label': 'AI service of the App Builder (administrators)',
3092
+ 'swai.none': '- none: no AI in the App Builder -',
3093
+ 'swai.service_help': 'Table and column names, types and descriptions (never rows), and what developers type, are sent to it. Its calls are logged without an application.',
3094
+ 'swai.describe_link': 'Describe tables for AI',
3095
+ 'swai.describe_why': '(better answers: say what tables and columns mean)',
3096
+ 'swai.question_title': 'SQL from a question',
3097
+ 'swai.question_intro': 'The answer is shown, never run: check it, then run it in the SQL Worksheet if you want.',
3098
+ 'swai.question': 'Question',
3099
+ 'swai.question_placeholder': 'e.g. employees per department with their average salary',
3100
+ 'swai.thinking': 'Thinking…',
3101
+ 'swai.write_sql': 'Write the SQL',
3102
+ 'swai.explain_title': 'Explain a query or an error',
3103
+ 'swai.schema_optional': 'Schema (optional)',
3104
+ 'swai.none_short': '- none -',
3105
+ 'swai.error_optional': 'Error message (optional)',
3106
+ 'swai.back': 'SQL Workshop AI',
3107
+ 'swai.describe_intro': 'Say what tables and columns mean: the descriptions go with the table list when the App Builder asks a model for SQL or pages. Without one, the database comment is used.',
3108
+ 'swai.choose': '- choose -',
3109
+ 'swai.show_tables': 'Show tables',
3110
+ 'swai.described': 'described',
3111
+ 'swai.drafted': 'Drafted by AI from the names and types: check and change the descriptions, then save.',
3112
+ 'swai.the_kind': 'The {kind}',
3113
+ 'swai.key': 'key',
3114
+ 'swai.description_of': 'Description of {name}',
3115
+ 'swai.as_comments': 'Also save them as database comments (COMMENT ON)',
3116
+ 'swai.save_descriptions': 'Save the descriptions',
3117
+ 'swai.draft': 'Draft with AI',
3118
+ 'swai.describe_crumb': 'Describe tables',
3119
+ 'swai.proposed': 'Proposed SQL',
3120
+ 'swai.not_run': 'SQL (not run)',
3121
+ 'swai.explanation': 'Explanation',
3122
+ 'swai.err.question': 'Type a question.',
3123
+ 'swai.err.schema': 'Choose a schema.',
3124
+ 'swai.err.paste': 'Paste a query, an error message or both.',
3125
+ 'swai.err.no_such': 'There is no AI service {name}.',
3126
+ 'swai.uses': 'The App Builder uses AI service {name}.',
3127
+ 'swai.uses_none': 'The App Builder uses no AI service.',
3128
+ 'swai.saved': 'Descriptions of {name} saved.',
3129
+ 'swai.saved_comments': 'Descriptions of {name} saved, also as database comments.',
3130
+ 'swai.not_saved': 'Not saved: {error}',
3131
+ // ------------------------------------------------------------ Schema Export / Import (sprint 162, CD-8)
3132
+ 'dp.content.all': 'Definitions and data',
3133
+ 'dp.content.definitions': 'Definitions only',
3134
+ 'dp.content.data': 'Data only',
3135
+ 'dp.admins_only': 'Only administrators export and import schemas: an export holds every row of a schema, an import runs its SQL as pgkiln\'s owner role.',
3136
+ 'dp.status.uploaded': 'uploaded',
3137
+ 'dp.status.running': 'running',
3138
+ 'dp.status.succeeded': 'succeeded',
3139
+ 'dp.status.failed': 'failed',
3140
+ 'dp.status.cancelled': 'cancelled',
3141
+ 'dp.what.export': 'Export of {schema}',
3142
+ 'dp.plain_sql': '(plain SQL)',
3143
+ 'dp.what.upload': 'Upload {file}',
3144
+ 'dp.what.import': 'Import of {schema} into {target}',
3145
+ 'dp.tools': '{version} and pg_restore for a PostgreSQL {server} server. Files are kept {n} days in the dump directory.',
3146
+ 'dp.tools_one': '{version} and pg_restore for a PostgreSQL {server} server. Files are kept {n} day in the dump directory.',
3147
+ 'dp.need_tools': 'Export and import need pg_dump and pg_restore.',
3148
+ 'dp.found': 'Found: {list}.',
3149
+ 'dp.col.job': 'Job',
3150
+ 'dp.col.what': 'What',
3151
+ 'dp.col.seconds': 'Seconds',
3152
+ 'dp.intro': 'A schema to a file with pg_dump, and a file into a schema with pg_restore (Data Pump), as background jobs.',
3153
+ 'dp.export_schema': 'Export a schema',
3154
+ 'dp.import': 'Import',
3155
+ 'dp.jobs': 'Jobs',
3156
+ 'dp.removed': 'removed',
3157
+ 'dp.no_jobs': 'No exports or imports yet.',
3158
+ 'dp.export_of': 'Export {schema}',
3159
+ 'dp.fmt.custom': 'Custom (compressed; imports here with pg_restore)',
3160
+ 'dp.fmt.plain': 'Plain SQL (for psql; not imported here)',
3161
+ 'dp.content': 'Content',
3162
+ 'dp.tables': 'Tables, views and sequences',
3163
+ 'dp.mode.all': 'The whole schema',
3164
+ 'dp.mode.only': 'Only the checked ones',
3165
+ 'dp.mode.except': 'All but the checked ones',
3166
+ 'dp.no_tables': 'The schema has no tables, views or sequences.',
3167
+ 'dp.some_tables_note': 'Only some tables: the file has no CREATE SCHEMA, and functions, types and the other objects of the schema stay out.',
3168
+ 'dp.start_export': 'Start the export',
3169
+ 'dp.export': 'Export',
3170
+ 'dp.col.file': 'File',
3171
+ 'dp.col.made': 'Made',
3172
+ 'dp.upload_title': 'Upload a dump',
3173
+ 'dp.upload_label': 'A custom or tar archive of one schema (pg_dump -Fc or -Ft), up to {mb} MB',
3174
+ 'dp.upload_note': 'The next page shows what the archive holds before anything runs. A dump is code: its functions and triggers run as pgkiln\'s owner role, so import only dumps you trust.',
3175
+ 'dp.or_export': 'Or an export of this server',
3176
+ 'dp.import_dots': 'Import…',
3177
+ 'dp.no_exports': 'No exports in custom format are kept.',
3178
+ 'dp.no_create_schema': '(some tables: no CREATE SCHEMA)',
3179
+ 'dp.none': 'none',
3180
+ 'dp.data_of': '(data of {n})',
3181
+ 'dp.object_type': 'Object type',
3182
+ 'dp.entries': 'Entries',
3183
+ 'dp.import_into': 'Import into',
3184
+ 'dp.target_help': 'A new schema is created; into an existing one, the dump\'s objects are added (or replaced, below). A name other than {schema} renames the dump\'s schema in the same transaction.',
3185
+ 'dp.clean': 'Drop the dump\'s objects in the schema first',
3186
+ 'dp.one_tx_note': 'Everything runs in one transaction: an error rolls it all back. Objects are owned by pgkiln\'s owner role. Names inside PL/pgSQL bodies are text: after a rename they still say {schema}.',
3187
+ 'dp.start_import': 'Start the import',
3188
+ 'dp.holds': 'What {file} holds',
3189
+ 'dp.job': 'Job #{id}',
3190
+ 'dp.opt.format': '{format} format',
3191
+ 'dp.opt.only': 'only {list}',
3192
+ 'dp.opt.without': 'without {list}',
3193
+ 'dp.opt.cleaned': 'existing objects dropped first',
3194
+ 'dp.created': 'Created',
3195
+ 'dp.finished': 'Finished',
3196
+ 'dp.options': 'Options',
3197
+ 'dp.job_lower': 'job #{id}',
3198
+ 'dp.kept_until': 'kept until {time}',
3199
+ 'dp.delete_with_file': 'Delete with its file',
3200
+ 'dp.job_kind': 'Job #{id}: {kind}',
3201
+ 'dp.kind.export': 'export',
3202
+ 'dp.kind.import': 'import',
3203
+ 'dp.log': 'Log',
3204
+ 'dp.nothing_logged': 'Nothing logged.',
3205
+ 'dp.nothing_logged_yet': 'Nothing logged yet.',
3206
+ 'dp.err.check_tables': 'Check the tables to export.',
3207
+ 'dp.err.not_importable': 'This file can\'t be imported (any more).',
3208
+ 'dp.err.schema_name': 'The schema: letters, digits, _ and $, up to 63, not starting with a digit.',
3209
+ 'dp.err.choose_file': 'Choose a file.',
3210
+ 'dp.err.too_large': 'The file is larger than {mb} MB (PGKILN_DUMP_MAX_MB).',
3211
+ 'dp.err.empty': 'The file is empty.',
3212
+ 'dp.cancelling': 'Cancelling the job.',
3213
+ 'dp.not_running': 'The job doesn\'t run on this server (any more).',
3214
+ 'dp.deleted': 'Job #{id} deleted.',
3215
+ // ------------------------------------------------------------ Scheduling (sprint 162, CD-8)
3216
+ 'cr.job_n': 'Job {id}',
3217
+ 'cr.job_n_lower': 'job {id}',
3218
+ 'cr.admins_only': 'Only administrators schedule database jobs: pg_cron runs them on the server, as any role.',
3219
+ 'cr.next_runs': 'Next runs ({tz}):',
3220
+ 'cr.no_times': 'No scheduled times: it runs when the database server starts.',
3221
+ 'cr.inactive': 'inactive',
3222
+ 'cr.at_start': 'at server start',
3223
+ 'cr.unreadable': 'unreadable',
3224
+ 'cr.never_ran': 'never ran',
3225
+ 'cr.step1': 'Install the pg_cron package on the database server (for example {apt}, or your cloud provider\'s pg_cron option).',
3226
+ 'cr.step2': 'In {conf} (or {alter}): {preload} and {db}; optionally {tz} (GMT unless set). Restart PostgreSQL.',
3227
+ 'cr.step3': 'As a superuser, in this database: {create}',
3228
+ 'cr.why.not_available': 'pg_cron isn\'t installed on this database server.',
3229
+ 'cr.why.not_loaded': 'pg_cron is installed on the server but not loaded: it isn\'t in {preload}.',
3230
+ 'cr.why.other_database': 'pg_cron runs in the database {other} ({setting}), not in {db}. Set {set} and restart, or schedule from that database (jobs can still run here with {fn}).',
3231
+ 'cr.why.not_created': 'pg_cron is loaded, but the extension isn\'t created in this database yet.',
3232
+ 'cr.why.no_access': 'pg_cron is installed, but pgkiln\'s owner connection can\'t read its jobs: {message}. Grant it access (as a superuser: {grant}), or connect pgkiln as the role that owns the jobs.',
3233
+ 'cr.why.old': 'This pg_cron ({version}) is too old: pgkiln needs version 1.4 or later ({fn1}, {fn2}). {update}',
3234
+ 'cr.to_schedule': 'To schedule SQL with pg_cron:',
3235
+ 'cr.own_scheduler': 'pgkiln\'s own scheduler works without it: an application\'s {automations} run SQL on a schedule as the application, and background execution chains run as {jobs}. They are listed below.',
3236
+ 'cr.automations_path': 'Shared Components › Automations',
3237
+ 'cr.process_jobs_lower': 'process jobs',
3238
+ 'cr.col.automation': 'Automation',
3239
+ 'cr.col.schedule': 'Schedule',
3240
+ 'cr.col.next_run': 'Next run',
3241
+ 'cr.col.last_run': 'Last run',
3242
+ 'cr.col.started_by': 'Started by',
3243
+ 'cr.col.queued': 'Queued',
3244
+ 'cr.col.ended': 'Ended',
3245
+ 'cr.automations': 'Automations',
3246
+ 'cr.automations_intro': 'Scheduled by pgkiln itself, per application (Shared Components › Automations), in each automation\'s time zone.',
3247
+ 'cr.disabled': 'disabled',
3248
+ 'cr.soon': 'soon',
3249
+ 'cr.no_automations': 'No automations.',
3250
+ 'cr.process_jobs': 'Process jobs',
3251
+ 'cr.process_jobs_intro': 'The latest execution chains that pages started in the background.',
3252
+ 'cr.no_process_jobs': 'No process jobs.',
3253
+ 'cr.col.run_as': 'Run as',
3254
+ 'cr.create': 'Create job',
3255
+ 'cr.history': 'Run history',
3256
+ 'cr.jobs': 'Jobs',
3257
+ 'cr.failed_last': 'Failed on their last run',
3258
+ 'cr.pg_cron_jobs': 'pg_cron jobs',
3259
+ 'cr.list_intro': 'pg_cron {version} runs these jobs on the database server; times are in its time zone {tz} ({setting}).',
3260
+ 'cr.own_only': 'pgkiln\'s owner connection ({user}) sees only its own jobs: pg_cron shows each role its own.',
3261
+ 'cr.search': 'Search jobs',
3262
+ 'cr.failures': '{n} failures in the last 10 runs',
3263
+ 'cr.no_match': 'No jobs match.',
3264
+ 'cr.none_yet': 'No jobs yet. {create}.',
3265
+ 'cr.create_one': 'Create one',
3266
+ 'cr.own_work': 'pgkiln\'s own scheduled work (automations, process jobs)',
3267
+ 'cr.job': 'Job',
3268
+ 'cr.name_placeholder': 'nightly vacuum',
3269
+ 'cr.name_help': 'Unique per role it runs as.',
3270
+ 'cr.database_help': 'pg_cron connects to it to run the command.',
3271
+ 'cr.run_as_help': 'The role the command runs as. Only a superuser schedules jobs for another role.',
3272
+ 'cr.active_help': 'An inactive job keeps its schedule and doesn\'t run.',
3273
+ 'cr.command': 'Command',
3274
+ 'cr.command_help': 'SQL run outside a transaction block, as pg_cron runs it: `vacuum analyze` works; several statements each commit on their own.',
3275
+ 'cr.schedule_help': 'Five fields, `minute hour day-of-month month day-of-week`; `n seconds` (1 to 59); or `@hourly`, `@daily`, `@weekly`, `@monthly`, `@yearly`, `@reboot`.',
3276
+ 'cr.presets': 'Common schedules',
3277
+ 'cr.choose': 'Choose…',
3278
+ 'cr.use': 'Use',
3279
+ 'cr.builder': 'Schedule builder',
3280
+ 'cr.use_fields': 'Use these fields',
3281
+ 'cr.review': 'Review SQL',
3282
+ 'cr.review_intro': 'These statements run in one transaction on pgkiln\'s owner connection when you apply them: all of them, or none.',
3283
+ 'cr.nothing': 'Nothing to change.',
3284
+ 'cr.failed_box': '{nothing}: the statements ran in one transaction, which was rolled back.',
3285
+ 'cr.nothing_changed': 'Nothing was changed',
3286
+ 'cr.edit_title': 'Edit {name}',
3287
+ 'cr.edit': 'Edit',
3288
+ 'cr.create_crumb': 'Create',
3289
+ 'cr.err.clash': '{user} has a job named {name} already.',
3290
+ 'cr.change_title': 'Change {name}',
3291
+ 'cr.create_title': 'Create job {name}',
3292
+ 'cr.back_form': 'Back to the form',
3293
+ 'cr.review_crumb': 'Review',
3294
+ 'cr.err.changed_form': 'The statements changed since you reviewed them (the job or the form changed): review them again.',
3295
+ 'cr.changed': 'Changed the job {name}.',
3296
+ 'cr.created': 'Created the job {name}.',
3297
+ 'cr.col.run': 'Run',
3298
+ 'cr.col.duration': 'Duration',
3299
+ 'cr.col.message': 'Message',
3300
+ 'cr.no_runs': 'No runs.',
3301
+ 'cr.run_confirm': 'Run {name} now, as {user} in {db}?',
3302
+ 'cr.run_now': 'Run now',
3303
+ 'cr.disable': 'Disable',
3304
+ 'cr.enable': 'Enable',
3305
+ 'cr.unschedule_dots': 'Unschedule…',
3306
+ 'cr.job_id': 'Job id',
3307
+ 'cr.recent_runs': 'Recent runs',
3308
+ 'cr.all_runs': 'All runs of this job',
3309
+ 'cr.purge_its': 'Purge its history',
3310
+ 'cr.enable_failed': 'Enabling failed: {error}',
3311
+ 'cr.disable_failed': 'Disabling failed: {error}',
3312
+ 'cr.enabled': 'Enabled {name}: {sql}',
3313
+ 'cr.disabled_flash': 'Disabled {name}: {sql}',
3314
+ 'cr.err.changed': 'The statements changed since you reviewed them: review them again.',
3315
+ 'cr.unscheduled': 'Unscheduled {name}. Its run history stays until you purge it.',
3316
+ 'cr.unschedule_title': 'Unschedule {name}',
3317
+ 'cr.unschedule_note': 'pg_cron forgets the job; its runs stay in the history until purged.',
3318
+ 'cr.unschedule': 'Unschedule',
3319
+ 'cr.ran': '{what} in {secs}, as {user} in {db}: {message}',
3320
+ 'cr.ran_ok': 'Ran',
3321
+ 'cr.ran_failed': 'Failed',
3322
+ 'cr.run_now_note': 'Run now runs the command from pgkiln, not from pg_cron: it isn\'t in pg_cron\'s run history; pgkiln\'s activity log has it.',
3323
+ 'cr.purge_dots': 'Purge…',
3324
+ 'cr.runs': 'Runs',
3325
+ 'cr.history_intro': 'pg_cron\'s {table}, newest first (200 at most); times in {tz}. pg_cron keeps every run until it is purged.',
3326
+ 'cr.all_jobs': 'All jobs',
3327
+ 'cr.any_status': 'Any status',
3328
+ 'cr.search_messages_label': 'Search messages and commands',
3329
+ 'cr.search_messages': 'Search messages',
3330
+ 'cr.filter': 'Filter',
3331
+ 'cr.older_7': 'older than 7 days',
3332
+ 'cr.older_30': 'older than 30 days',
3333
+ 'cr.older_90': 'older than 90 days',
3334
+ 'cr.purge_all': 'all',
3335
+ 'cr.purged': 'Purged the run history.',
3336
+ 'cr.purge_title': 'Purge run history',
3337
+ 'cr.which_runs': 'Which runs',
3338
+ 'cr.runs_of': 'Runs of {name}',
3339
+ 'cr.would_delete_one': '1 run would be deleted.',
3340
+ 'cr.would_delete': '{n} runs would be deleted.',
3341
+ 'cr.purge': 'Purge',
3342
+ // ------------------------------------------------------------ Scheduling: fields, statuses, presets, schedules in words (cron.*)
3343
+ 'cr.f.minute': 'Minute',
3344
+ 'cr.f.minute_help': '0-59',
3345
+ 'cr.f.hour': 'Hour',
3346
+ 'cr.f.hour_help': '0-23',
3347
+ 'cr.f.day': 'Day of month',
3348
+ 'cr.f.day_help': '1-31, $ = last',
3349
+ 'cr.f.month': 'Month',
3350
+ 'cr.f.month_help': '1-12 or jan-dec',
3351
+ 'cr.f.weekday': 'Day of week',
3352
+ 'cr.f.weekday_help': '0-6 (0 = Sunday) or sun-sat',
3353
+ 'cr.status.starting': 'starting',
3354
+ 'cr.status.running': 'running',
3355
+ 'cr.status.sending': 'sending',
3356
+ 'cr.status.connecting': 'connecting',
3357
+ 'cr.status.succeeded': 'succeeded',
3358
+ 'cr.status.failed': 'failed',
3359
+ 'cr.preset.p1': 'Every minute',
3360
+ 'cr.preset.p2': 'Every 30 seconds',
3361
+ 'cr.preset.p3': 'Every 5 minutes',
3362
+ 'cr.preset.p4': 'Every 15 minutes',
3363
+ 'cr.preset.p5': 'Every hour',
3364
+ 'cr.preset.p6': 'Every day at 02:00',
3365
+ 'cr.preset.p7': 'Every day at midnight',
3366
+ 'cr.preset.p8': 'Weekdays at 07:00',
3367
+ 'cr.preset.p9': 'Every Sunday at 03:00',
3368
+ 'cr.preset.p10': 'First day of the month at 01:00',
3369
+ 'cr.preset.p11': 'Last day of the month at 23:00',
3370
+ 'cr.preset.p12': 'Every year on 1 January',
3371
+ 'cron.reboot': 'When the database server starts',
3372
+ 'cron.every_second': 'Every second',
3373
+ 'cron.every_seconds': 'Every {n} seconds',
3374
+ 'cron.every_minute': 'Every minute',
3375
+ 'cron.every_minutes': 'Every {n} minutes',
3376
+ 'cron.every_hour': 'Every hour',
3377
+ 'cron.minute_of_hour': 'At minute {m} of every hour',
3378
+ 'cron.minutes_of_hour': 'At minutes {list} of every hour',
3379
+ 'cron.at': 'At {times}',
3380
+ 'cron.at_minute': 'At minute {m}',
3381
+ 'cron.at_minutes': 'At minutes {list}',
3382
+ 'cron.of_every_hours': '{mins} of every {n} hours',
3383
+ 'cron.past_hours': '{mins} past hours {list}',
3384
+ 'cron.day_and_last': 'on day {list} and the last day of the month',
3385
+ 'cron.last_day': 'on the last day of the month',
3386
+ 'cron.day_of_month': 'on day {list} of the month',
3387
+ 'cron.weekdays': 'on weekdays',
3388
+ 'cron.on_days': 'on {list}',
3389
+ 'cron.a_days': 'a {list}',
3390
+ 'cron.either': '{dom} or {dow}',
3391
+ 'cron.if': '{dom} if it is {dow}',
3392
+ 'cron.every_day': 'every day',
3393
+ 'cron.in_months': 'in {list}',
3394
+ 'cron.range': '{from} to {to}',
3395
+ // ------------------------------------------------------------ Region and report settings (CD-8)
3396
+ 'rs.set_items': 'Set items',
3397
+ 'rs.text_when_there_are_no': 'Text when there are no rows',
3398
+ 'rs.fill_colour_lines_polygons': 'Fill colour (lines / polygons)',
3399
+ 'rs.line_colour': 'Line colour',
3400
+ 'rs.line_width': 'Line width',
3401
+ 'rs.opacity_0_1': 'Opacity (0–1)',
3402
+ 'rs.rows_per_page': 'Rows per page',
3403
+ 'rs.aggregates_in_the_footer': 'Aggregates in the footer',
3404
+ 'rs.frozen_columns': 'Frozen columns',
3405
+ 'rs.public_reports_by': 'Public reports by',
3406
+ 'rs.as_a_master_column_of': 'As a master: column of the selected row',
3407
+ 'rs.goes_into_item': '… goes into item',
3408
+ 'rs.as_a_detail_follows_item': 'As a detail: follows item',
3409
+ 'rs.and_new_rows_get_it': '… and new rows get it in column',
3410
+ 'rs.load': 'Load',
3411
+ 'rs.name_legend': 'Name (legend)',
3412
+ 'rs.show_places_as': 'Show places as',
3413
+ 'rs.query': 'Query',
3414
+ 'rs.each_place_links_to_page': 'Each place links to page',
3415
+ 'rs.report_region': 'Report region',
3416
+ 'rs.filter_by': 'Filter by',
3417
+ 'rs.suggestions_per_facet_0_10': 'Suggestions per facet (0–10)',
3418
+ 'rs.placeholder_of_the_search_field': 'Placeholder of the search field',
3419
+ 'rs.shown_first': 'Shown first',
3420
+ 'rs.week_and_day_views_from': 'Week and day views from hour',
3421
+ 'rs.until_hour': 'Until hour',
3422
+ 'rs.sql_that_moves_an_event': 'SQL that moves an event',
3423
+ 'rs.key_column': 'Key column',
3424
+ 'rs.who_may_drag': 'Who may drag',
3425
+ 'rs.show_as': 'Show as',
3426
+ 'rs.carousel_next_region_every_seconds': 'Carousel: next region every (seconds)',
3427
+ 'rs.chart_type': 'Chart type',
3428
+ 'rs.sql_that_moves_a_task': 'SQL that moves a task',
3429
+ 'rs.steps': 'Steps',
3430
+ 'rs.style': 'Style',
3431
+ 'rs.list': 'List',
3432
+ 'rs.template': 'Template',
3433
+ 'rs.layer_name_legend': 'Layer name (legend)',
3434
+ 'rs.height': 'Height',
3435
+ 'rs.zoom_for_a_single_place': 'Zoom for a single place (1–19)',
3436
+ 'rs.levels_open_at_first': 'Levels open at first',
3437
+ 'rs.show': 'Show',
3438
+ 'rs.behaviour': 'Behaviour',
3439
+ 'rs.totals_and_columns': 'Totals and columns',
3440
+ 'rs.views': 'Views',
3441
+ 'rs.row_actions': 'Row actions',
3442
+ 'rs.master_detail': 'Master-detail',
3443
+ 'rs.columns': 'Columns',
3444
+ 'rs.filter_a_report': 'Filter a report',
3445
+ 'rs.filters': 'Filters',
3446
+ 'rs.facets': 'Facets',
3447
+ 'rs.drag_and_drop': 'Drag and drop',
3448
+ 'rs.appearance': 'Appearance',
3449
+ 'rs.regions': 'Regions',
3450
+ 'rs.gauge': 'Gauge',
3451
+ 'rs.gantt_drag_and_drop': 'Gantt: drag and drop',
3452
+ 'rs.workflows': 'Workflows',
3453
+ 'rs.tasks': 'Tasks',
3454
+ 'rs.saving_needs_a_process_of': 'Saving needs a process of type "grid_dml" for this region; without one the grid is read-only.',
3455
+ 'rs.column_sum_avg_count_min': 'column=sum, avg, count, min or max; separate columns with ";". Computed over all rows of the search, not only the page. Users can add their own (Actions → Aggregate).',
3456
+ 'rs.stay_in_view_while_the': 'Stay in view while the grid scrolls sideways. Users can change it, move, resize and hide columns; "layout" in the JSON sets the default order and widths.',
3457
+ 'rs.views_users_may_switch_to': 'Views users may switch to besides the grid. The single row view edits one row at a time (also from the row actions menu); group by and chart are set up in Actions.',
3458
+ 'rs.a_master_grid_s_selected': 'A master grid\'s selected row puts its value into a page item; detail grids and reports use it in their query (:P1_ID) and are refreshed without reloading the page. Other region types follow with {"master": {"item": "P1_ID"}}.',
3459
+ 'rs.edit_as_picks_a_shared': '"Edit as" picks a shared list of values (Shared Components → Lists of values) for a select list.',
3460
+ 'rs.the_visible_area_and_vector': 'The visible area and vector tiles need `lat`/`lng` (or a PostGIS geometry) and load again as the map moves. Vector tiles draw dots, lines and areas, without clustering or a list.',
3461
+ 'rs.the_same_columns_as_the': 'The same columns as the map\'s own query. Empty the query to remove the layer.',
3462
+ 'rs.the_condition_runs_on_the': 'The condition runs on the server: with PostGIS installed on a geometry/geography column, else on latitude and longitude.',
3463
+ 'rs.users_switch_between_the_ticked': 'Users switch between the ticked views. Hours outside the range are added when an event needs them.',
3464
+ 'rs.runs_as_the_application_s': 'Runs as the application\'s database role (row level security applies) with `:EVENT_ID` (the key column\'s value), `:NEW_START` and `:NEW_END` (same duration as before). Empty: events can\'t be dragged.',
3465
+ 'rs.only_events_the_user_sees': 'Only events the user sees in this calendar can be moved; without a mouse, the edit link changes the dates.',
3466
+ 'rs.not_while_the_pointer_or': 'Not while the pointer or the focus is in the carousel, nor for users who prefer reduced motion. A carousel has no "Show all".',
3467
+ 'rs.a_chosen_region_gets_display': 'A chosen region gets `"display_selector": true` in its settings (a tab named after it), or the tab name: regions with the same tab name share one tab (e.g. smart filters and their report). Without JavaScript every region shows, with links to each.',
3468
+ 'rs.gauge_charts_only_a_warning': 'Gauge charts only. A warning threshold above the critical one means low values are bad (e.g. warning 50, critical 20).',
3469
+ 'rs.drill_down_column_takes_the': 'Drill-down: `#column#` takes the value from the point\'s row, `#series#` the name of its series. Columns only the link refers to are not drawn.',
3470
+ 'rs.gantt_charts_with_a_task': 'Gantt charts with a `task_id` column. Runs as the application\'s database role (row level security applies) with `:TASK_ID`, `:NEW_START` and `:NEW_END` (`YYYY-MM-DD`, or `YYYY-MM-DDTHH:MM` by the hour; a milestone gets the same start and end). Empty: tasks can\'t be dragged.',
3471
+ 'rs.only_tasks_the_user_sees': 'Only tasks the user sees in this chart can be moved; the chart is drawn again from its query afterwards.',
3472
+ 'rs.column': 'Column',
3473
+ 'rs.heading': 'Heading',
3474
+ 'rs.shown': 'Shown',
3475
+ 'rs.read_only': 'Read-only',
3476
+ 'rs.required': 'Required',
3477
+ 'rs.edit_as': 'Edit as',
3478
+ 'rs.facet': 'Facet',
3479
+ 'rs.label': 'Label',
3480
+ 'rs.type': 'Type',
3481
+ 'rs.values_shown': 'Values shown',
3482
+ 'rs.exclude': 'Exclude',
3483
+ 'rs.ranges': 'Ranges',
3484
+ 'rs.from_to': 'From/to',
3485
+ 'rs.chart': 'Chart',
3486
+ 'rs.order': 'Order',
3487
+ 'rs.region': 'Region',
3488
+ 'rs.in_a_tab': 'In a tab',
3489
+ 'rs.tab_name': 'Tab name',
3490
+ 'rs.no_columns_yet': 'No columns yet.',
3491
+ 'rs.the_report_has_no_columns': 'The report has no columns.',
3492
+ 'rs.there_are_no_other_regions': 'There are no other regions on this page.',
3493
+ 'rs.shows_a_list_from_shared': 'Shows a list from Shared Components → Lists. Entries the user may not open are left out.',
3494
+ 'rs.these_fields_write_the_region': 'These fields write the region\'s settings JSON above (other keys are kept).',
3495
+ 'rs.users_may_add_rows': 'Users may add rows',
3496
+ 'rs.users_may_change_rows': 'Users may change rows',
3497
+ 'rs.users_may_delete_rows': 'Users may delete rows',
3498
+ 'rs.actions_menu_columns_aggregates_saved': 'Actions menu (columns, aggregates, saved reports)',
3499
+ 'rs.users_may_save_grid_reports': 'Users may save grid reports',
3500
+ 'rs.row_actions_menu': 'Row actions menu',
3501
+ 'rs.duplicate': 'Duplicate',
3502
+ 'rs.delete': 'Delete',
3503
+ 'rs.read_the_search_as_a': 'Read the search as a phrase ("clerks with salary between 1000 and 3000") and offer it as filters',
3504
+ 'rs.a_search_field_searches_all': 'A search field (searches all columns of the report)',
3505
+ 'rs.show_all_choice_shows_every': '"Show all" choice (shows every region)',
3506
+ 'rs.remember_the_choice_during_the': 'Remember the choice during the session',
3507
+ 'rs.group_markers_that_are_close': 'Group markers that are close together (clustering)',
3508
+ 'rs.include_completed_and_terminated_workflows': 'Include completed and terminated workflows',
3509
+ 'rs.include_completed_and_cancelled_tasks': 'Include completed and cancelled tasks',
3510
+ 'rs.no_link': '- no link -',
3511
+ 'rs.text_field': '- text field -',
3512
+ 'rs.nobody': '- nobody -',
3513
+ 'rs.not_a_master': '- not a master -',
3514
+ 'rs.all_rows_with_the_page': 'All rows with the page',
3515
+ 'rs.rows_in_the_visible_area': 'Rows in the visible area',
3516
+ 'rs.vector_tiles_large_data_sets': 'Vector tiles (large data sets)',
3517
+ 'rs.markers': 'Markers',
3518
+ 'rs.heat_map': 'Heat map',
3519
+ 'rs.lines': 'Lines',
3520
+ 'rs.polygons': 'Polygons',
3521
+ 'rs.extruded_polygons_shaded_by_height': 'Extruded polygons (shaded by height)',
3522
+ 'rs.none': '- none -',
3523
+ 'rs.the_visible_area': 'The visible area',
3524
+ 'rs.distance_from_the_centre': 'Distance from the centre',
3525
+ 'rs.none_2': 'None',
3526
+ 'rs.bar': 'Bar',
3527
+ 'rs.pie': 'Pie',
3528
+ 'rs.choose': '- choose -',
3529
+ 'rs.everyone_who_sees_the_calendar': 'Everyone who sees the calendar',
3530
+ 'rs.signed_in_users': 'Signed-in users',
3531
+ 'rs.tabs': 'Tabs',
3532
+ 'rs.select_list': 'Select list',
3533
+ 'rs.carousel_one_at_a_time': 'Carousel (one at a time, Previous and Next)',
3534
+ 'rs.everyone_who_sees_the_chart': 'Everyone who sees the chart',
3535
+ 'rs.days_or_hours_when_a': 'Days, or hours when a task has a time',
3536
+ 'rs.days': 'Days',
3537
+ 'rs.hours': 'Hours',
3538
+ 'rs.cards': 'Cards',
3539
+ 'rs.kpi_tiles_metric': 'KPI tiles (metric)',
3540
+ 'rs.links_nested': 'Links (nested)',
3541
+ 'rs.badge_list': 'Badge list',
3542
+ 'rs.cards_menu': 'Cards (menu)',
3543
+ 'rs.wizard_progress_numbered_steps': 'Wizard progress (numbered steps)',
3544
+ 'rs.small': 'Small',
3545
+ 'rs.medium': 'Medium',
3546
+ 'rs.large': 'Large',
3547
+ 'rs.workflows_i_started': 'Workflows I started',
3548
+ 'rs.workflows_i_administer': 'Workflows I administer',
3549
+ 'rs.my_tasks_to_act_on': 'My tasks: to act on, claim, or assigned to me',
3550
+ 'rs.tasks_i_requested': 'Tasks I requested',
3551
+ 'rs.tasks_i_administer': 'Tasks I administer',
3552
+ 'rs.aria_list_of_values_of': 'List of values of {name}',
3553
+ 'rs.aria_heading_of': 'Heading of {name}',
3554
+ 'rs.aria_show': 'Show {name}',
3555
+ 'rs.aria_facet_on': 'Facet on {name}',
3556
+ 'rs.aria_label_of': 'Label of {name}',
3557
+ 'rs.aria_type_of_the_facet_on': 'Type of the facet on {name}',
3558
+ 'rs.aria_values_shown_for': 'Values shown for {name}',
3559
+ 'rs.aria_users_may_exclude_values_of': 'Users may exclude values of {name}',
3560
+ 'rs.aria_ranges_of': 'Ranges of {name}',
3561
+ 'rs.aria_users_may_type_a_range': 'Users may type a range for {name}',
3562
+ 'rs.aria_chart_of_the_facet_on': 'Chart of the facet on {name}',
3563
+ 'rs.aria_order_of': 'Order of {name}',
3564
+ 'rs.aria_show_in_the_display_selector': 'Show {name} in the display selector',
3565
+ 'rs.aria_tab_name_of': 'Tab name of {name}',
3566
+ 'rs.no_data_found': 'No data found',
3567
+ 'rs.search_or_filter': 'Search or filter…',
3568
+ 'rs.link': 'Link',
3569
+ 'rs.link_help': 'ITEM=#column#, comma separated; #column# is replaced by the row\'s value.',
3570
+ 'rs.links_to_page': '{what} links to page',
3571
+ 'rs.w.edit': 'Edit',
3572
+ 'rs.row_actions_edit': 'Row actions: edit',
3573
+ 'rs.w.event': 'Each event',
3574
+ 'rs.edit_link': 'Edit link',
3575
+ 'rs.w.slot': 'An empty day or hour slot',
3576
+ 'rs.create_on_click': 'Create on click',
3577
+ 'rs.create_help': 'ITEM=#start#, #end# or #date#: the slot clicked (YYYY-MM-DD, or YYYY-MM-DD HH:MI for an hour slot).',
3578
+ 'rs.w.point': 'Each data point',
3579
+ 'rs.w.card': 'Each card',
3580
+ 'rs.w.place': 'Each place',
3581
+ 'rs.w.node': 'Each node',
3582
+ 'rs.layer_n': 'Layer {n}: {name}',
3583
+ 'rs.add_layer': 'Add a layer',
3584
+ 'rs.group_markers': 'Group close markers',
3585
+ 'rs.off_at_first': 'Off at first',
3586
+ 'rs.map_report_help': 'Users can show only the rows in the map\'s visible area ("Show this area in the list"), or near its centre. The report needs lat and lng (or location) columns, or a PostGIS geometry/geography column.',
3587
+ 'rs.map_report_none': 'Add a report region to this page to filter it by the map area.',
3588
+ 'rs.report_smart_help': 'The report on this page that the smart filters filter. Save to list its columns.',
3589
+ 'rs.report_facets_help': 'The report on this page that the facets filter. Save to list its columns.',
3590
+ 'rs.report_first': 'Add a report region to this page first.',
3591
+ 'rs.untitled': '(untitled)',
3592
+ 'rs.gauge.min': 'Minimum',
3593
+ 'rs.gauge.max': 'Maximum',
3594
+ 'rs.gauge.warning': 'Warning from',
3595
+ 'rs.gauge.critical': 'Critical from',
3596
+ 'rs.t.settings': 'Settings',
3597
+ 'rs.t.grid': 'Grid settings',
3598
+ 'rs.t.chart': 'Chart settings',
3599
+ 'rs.t.cards': 'Cards settings',
3600
+ 'rs.t.calendar': 'Calendar settings',
3601
+ 'rs.t.facets': 'Faceted search settings',
3602
+ 'rs.t.smart': 'Smart filters settings',
3603
+ 'rs.t.selector': 'Display selector settings',
3604
+ 'rs.t.list': 'List settings',
3605
+ 'rs.t.map': 'Map settings',
3606
+ 'rs.t.tree': 'Tree settings',
3607
+ 'rs.t.workflows': 'Workflow console settings',
3608
+ 'rs.t.tasks': 'Task list settings',
3609
+ 'rs.saved': 'Settings saved.',
3610
+ 'rs.chart.bar': 'Bar (horizontal)',
3611
+ 'rs.chart.column': 'Column',
3612
+ 'rs.chart.stacked': 'Stacked column',
3613
+ 'rs.chart.line': 'Line',
3614
+ 'rs.chart.area': 'Area',
3615
+ 'rs.chart.combo': 'Column and line (first series as columns)',
3616
+ 'rs.chart.scatter': 'Scatter (first column is x)',
3617
+ 'rs.chart.donut': 'Donut',
3618
+ 'rs.chart.pie': 'Pie',
3619
+ 'rs.chart.bubble': 'Bubble (label, x, y and size columns)',
3620
+ 'rs.chart.gauge': 'Gauge (one dial per row)',
3621
+ 'rs.chart.funnel': 'Funnel (stages in the query order)',
3622
+ 'rs.chart.radar': 'Radar (one axis per row)',
3623
+ 'rs.chart.gantt': 'Gantt (task, start and end columns)',
3624
+ 'rs.chart.treemap': 'Treemap (label and value; node_id, parent_id for a hierarchy)',
3625
+ 'rs.chart.sunburst': 'Sunburst (label and value; node_id, parent_id for a hierarchy)',
3626
+ 'rs.chart.timeline': 'Timeline (label, start, end; a series column for lanes)',
3627
+ 'rs.chart.pyramid': 'Pyramid (one series; two series back to back)',
3628
+ 'rs.chart.polar': 'Polar area (one sector per row)',
3629
+ 'rs.chart.range': 'Range (low and high columns: floating columns)',
3630
+ 'rs.chart.boxplot': 'Box plot (one value per row, or min, Q1, median, Q3 and max)',
3631
+ 'rs.chart.stock': 'Stock (open, high, low and close columns: candlesticks)',
3632
+ 'rs.gridview.row': 'Single row view',
3633
+ 'rs.gridview.group': 'Group by',
3634
+ 'rs.gridview.chart': 'Chart',
3635
+ 'rs.facet.checkbox': 'Checkboxes',
3636
+ 'rs.facet.range': 'Ranges',
3637
+ 'rs.facet.star': 'Star rating',
3638
+ 'rs.view.month': 'Month',
3639
+ 'rs.view.week': 'Week',
3640
+ 'rs.view.day': 'Day',
3641
+ 'rs.view.list': 'List',
3642
+ 'rpt.rows_per_page': 'Rows per page',
3643
+ 'rpt.on_phones': 'On phones',
3644
+ 'rpt.text_when_there_are_no': 'Text when there are no rows',
3645
+ 'rpt.who_may_save_public_reports': 'Who may save public reports',
3646
+ 'rpt.pagination': 'Pagination',
3647
+ 'rpt.keyset_columns': 'Keyset columns',
3648
+ 'rpt.maximum_row_count': 'Maximum row count',
3649
+ 'rpt.cache': 'Cache',
3650
+ 'rpt.cache_for_seconds': 'Cache for (seconds)',
3651
+ 'rpt.columns_read_from_a_json': 'Columns read from a json or jsonb column',
3652
+ 'rpt.link_column': 'Link column',
3653
+ 'rpt.to_page': 'To page',
3654
+ 'rpt.set_items': 'Set items',
3655
+ 'rpt.value_column': 'Value column',
3656
+ 'rpt.into_item': 'Into item',
3657
+ 'rpt.report_layout': 'Report layout',
3658
+ 'rpt.behaviour': 'Behaviour',
3659
+ 'rpt.large_tables': 'Large tables',
3660
+ 'rpt.json_path_columns': 'JSON path columns',
3661
+ 'rpt.columns': 'Columns',
3662
+ 'rpt.link': 'Link',
3663
+ 'rpt.row_selection': 'Row selection',
3664
+ 'rpt.pdf': 'PDF',
3665
+ 'rpt.row_ranges_skip_counting_the': 'Row ranges skip counting the rows: use them for large tables.',
3666
+ 'rpt.with_row_ranges_columns_that': 'With row ranges: columns that make a row unique (comma separated, indexed). Next and Previous then continue after the last row instead of skipping rows (fast deep pages).',
3667
+ 'rpt.the_report_and_its_downloads': 'The report (and its downloads) reads at most this many rows.',
3668
+ 'rpt.a_submit_of_the_page': 'A submit of the page empties its cache.',
3669
+ 'rpt.format_masks_numbers_like_999g999g990d00': 'Format masks: numbers like 999G999G990D00, FML999G990D00 (currency), 990D0% or 0000 (G and D are the language\'s separators); dates like DD-MON-YYYY. Empty: the application\'s formats. Excel and CSV downloads keep the raw values.',
3670
+ 'rpt.item_column_comma_separated_column': 'ITEM=#column#, comma separated; #column# is replaced by the row\'s value.',
3671
+ 'rpt.a_checkbox_per_row_on': 'A checkbox per row; on submit the checked rows\' values reach the item, colon separated (e.g. 7839:7902). Usually a hidden item. Treat the values as user input in your process.',
3672
+ 'rpt.layouts_are_under_shared_components': 'Layouts are under Shared Components → Report layouts.',
3673
+ 'rpt.column': 'Column',
3674
+ 'rpt.heading': 'Heading',
3675
+ 'rpt.format_mask': 'Format mask',
3676
+ 'rpt.display': 'Display',
3677
+ 'rpt.shown': 'Shown',
3678
+ 'rpt.in_pdf': 'In PDF',
3679
+ 'rpt.pdf_width_mm': 'PDF width (mm)',
3680
+ 'rpt.these_fields_write_the_region': 'These fields write the region\'s settings JSON above (other keys are kept).',
3681
+ 'rpt.no_columns_yet': 'No columns yet.',
3682
+ 'rpt.search_box': 'Search box',
3683
+ 'rpt.actions_menu_filters_break_aggregates': 'Actions menu (filters, break, aggregates, downloads…)',
3684
+ 'rpt.sortable': 'Sortable',
3685
+ 'rpt.users_may_save_reports': 'Users may save reports',
3686
+ 'rpt.load_after_the_page_shows': 'Load after the page shows (lazy loading)',
3687
+ 'rpt.normal': 'Normal',
3688
+ 'rpt.cards_reflow': 'Cards (reflow)',
3689
+ 'rpt.scrolling_table': 'Scrolling table',
3690
+ 'rpt.nobody': '- nobody -',
3691
+ 'rpt.rows_x_y_of_z': 'Rows X–Y of Z (counts the total)',
3692
+ 'rpt.row_ranges_x_y_no': 'Row ranges X–Y (no total)',
3693
+ 'rpt.no_cache': '- no cache -',
3694
+ 'rpt.per_user': 'Per user',
3695
+ 'rpt.per_session': 'Per session',
3696
+ 'rpt.for_all_users_with_the': 'For all users (with the same roles)',
3697
+ 'rpt.no_link': '- no link -',
3698
+ 'rpt.choose': '- choose -',
3699
+ 'rpt.no_row_selection': '- no row selection -',
3700
+ 'rpt.aria_heading_of': 'Heading of {name}',
3701
+ 'rpt.aria_format_mask_of': 'Format mask of {name}',
3702
+ 'rpt.aria_display_of': 'Display of {name}',
3703
+ 'rpt.aria_show': 'Show {name}',
3704
+ 'rpt.aria_print': 'Print {name}',
3705
+ 'rpt.aria_pdf_width_of': 'PDF width of {name}',
3706
+ 'rpt.no_data_found': 'No data found',
3707
+ 'rpt.saved_without': 'Report settings saved, without these format masks: {masks}.',
3708
+ 'rpt.saved': 'Report settings saved.',
3709
+ // ------------------------------------------------------------ Region settings help (CD-8)
3710
+ 'rs.not_in_query': 'not in the query',
3711
+ 'rpt.report_settings': 'Report settings',
3712
+ 'rpt.save_report_settings': 'Save report settings',
3713
+ 'rs.no_position_alert': 'The report has no `lat`/`lng` or `location` columns, so the map area can\'t filter it.',
3714
+ 'rs.facets_help': 'Checkboxes list the most frequent values (Exclude lets users filter them out instead). Ranges and From/to need a number or date column: ranges are `from..to = label` separated by `;`, an open end left empty (`..1000`, `2020-01-01..`); a range includes its start, not its end. A star rating offers "4 stars and up" and so on (up to 5; `"max"` in the JSON changes it).',
3715
+ 'rs.facets_help_chart': 'Chart: a bar or pie chart of the counts under the facet (collapsed); a bar or slice filters on its value.',
3716
+ 'rs.calendar_help': 'The query returns `start_date`, `title` and optionally `end_date` (dates for all-day events, timestamps for events with a time).',
3717
+ 'rs.chart_help': 'The first column is the label; each following numeric column is a series (up to 8). A Gantt chart reads `label, start, end` (dates or timestamps; an empty end is a milestone) and optional columns named `progress` (0 to 100), `task_id` and `depends_on` (the ids a task waits for, e.g. `3,4`).',
3718
+ 'rs.map_help': 'Each row is a marker at `lat`, `lng` (or `location` as "lat,lng"), with `title` and `body` in its popup; a `geojson` column draws lines and areas (with PostGIS installed, a `geometry` or `geography` column in WGS 84 works too). A heat map weighs each place by a `weight` column.',
3719
+ 'rs.tree_help': 'The query returns `id`, `parent_id` and `label` (and optionally `icon`); rows whose parent isn\'t in the result are the roots.',
3720
+ 'rs.workflow_help': 'Workflows come from workflow definitions (Shared Components); application SQL starts them with `meta.start_workflow(…)`.',
3721
+ 'rs.task_help': 'Tasks come from task definitions (Shared Components); application SQL creates them with `meta.create_task(…)`.',
3722
+ // ------------------------------------------------------------ SQL Workshop › RESTful Services › Modules (CD-8)
3723
+ 'rm.type.collection': 'Collection query: rows, paged',
3724
+ 'rm.type.item': 'Single row: an object, 404 without a row',
3725
+ 'rm.type.sql': 'SQL: the first row of the last statement',
3726
+ 'rm.type.plpgsql': 'PL/pgSQL block: meta.rest_reply(body, status)',
3727
+ 'rm.type.media': 'Media resource: content_type and content',
3728
+ 'rm.modules': 'Modules',
3729
+ 'rm.module': 'Module',
3730
+ 'rm.autorest_tab': 'AutoREST (tables and views)',
3731
+ 'rm.run_only_suffix': 'Set it back to Run and build to change it.',
3732
+ 'rm.locked_suffix': 'Changes are refused until it is unlocked.',
3733
+ 'rm.or': 'or',
3734
+ 'rm.public': 'public',
3735
+ 'rm.token': 'token',
3736
+ 'rm.module_role': 'module role {roles}',
3737
+ 'rm.role': 'role {roles}',
3738
+ 'rm.tree_aria': 'Templates and handlers',
3739
+ 'rm.disabled_suffix': 'disabled',
3740
+ 'rm.base_path': 'Base path',
3741
+ 'rm.application': 'Application',
3742
+ 'rm.templates': 'Templates',
3743
+ 'rm.template': 'Template',
3744
+ 'rm.handlers': 'Handlers',
3745
+ 'rm.privilege': 'Privilege',
3746
+ 'rm.off': 'off',
3747
+ 'rm.any_token': 'any token',
3748
+ 'rm.none_yet': 'No REST modules yet. Create one below: a base path, then templates and handlers.',
3749
+ 'rm.app_help': 'Its database role runs the handlers; its tokens and roles decide who may call them.',
3750
+ 'rm.base_path_rule': 'lower case letters, digits, _ and - (at most 40)',
3751
+ 'rm.eg': 'e.g. {example}',
3752
+ 'rm.eg_sales_api': 'e.g. Sales API',
3753
+ 'rm.title': 'Title',
3754
+ 'rm.privilege_roles': 'Privilege: roles',
3755
+ 'rm.any_caller': 'any caller with a token',
3756
+ 'rm.roles_help_app': 'Comma separated: every handler needs one of these application roles.',
3757
+ 'rm.roles_help': 'Comma separated: every handler needs one of these roles.',
3758
+ 'rm.description': 'Description',
3759
+ 'rm.create_module': 'Create module',
3760
+ 'rm.create_a_module': 'Create a module',
3761
+ 'rm.list_title': 'RESTful Services: Modules',
3762
+ 'rm.enabled': 'Enabled',
3763
+ 'rm.status': 'Status',
3764
+ 'rm.disabled_404': 'Disabled (404)',
3765
+ 'rm.save': 'Save',
3766
+ 'rm.saved': 'Saved.',
3767
+ 'rm.no_templates': 'No templates yet.',
3768
+ 'rm.uri_template': 'URI template',
3769
+ 'rm.add_template': 'Add template',
3770
+ 'rm.checks': 'Checks',
3771
+ 'rm.delete_module': 'Delete module',
3772
+ 'rm.module_title': 'REST module {name}',
3773
+ 'rm.method': 'Method',
3774
+ 'rm.source_type': 'Source type',
3775
+ 'rm.access': 'Access',
3776
+ 'rm.no_handlers': 'No handlers yet: the URI answers 404.',
3777
+ 'rm.add_handler': 'Add handler',
3778
+ 'rm.url': 'URL:',
3779
+ 'rm.uri_rename_help': 'Renaming it moves its handlers too.',
3780
+ 'rm.delete_template': 'Delete template',
3781
+ 'rm.source': 'Source',
3782
+ 'rm.none_here': 'none here',
3783
+ 'rm.who': 'Who may call it',
3784
+ 'rm.auth_token': 'A bearer token of the application',
3785
+ 'rm.auth_public': 'Public: no token',
3786
+ 'rm.roles': 'Roles',
3787
+ 'rm.no_further_role': 'no further role',
3788
+ 'rm.roles_help_handler': 'Comma separated: the caller needs one of them too.',
3789
+ 'rm.page_size': 'Page size',
3790
+ 'rm.page_size_help': 'Collection queries: rows without ?limit=.',
3791
+ 'rm.status_ph': '201 for POST, else 200',
3792
+ 'rm.status_help': 'SQL and PL/pgSQL handlers.',
3793
+ 'rm.params': 'Parameters (documentation)',
3794
+ 'rm.create_handler': 'Create handler',
3795
+ 'rm.delete_handler': 'Delete handler',
3796
+ 'rm.new_handler_for': 'New handler for {uri}',
3797
+ 'rm.new_handler': 'New handler',
3798
+ 'rm.response': 'Response',
3799
+ 'rm.no_token': 'no token',
3800
+ 'rm.no_token_option': 'No token',
3801
+ 'rm.try_it': 'Try it',
3802
+ 'rm.as': 'As',
3803
+ 'rm.query_string': 'Query string',
3804
+ 'rm.json_body': 'JSON body',
3805
+ 'rm.send': 'Send {method}',
3806
+ 'rm.content': 'content',
3807
+ 'rm.characters': '({n} characters)',
3808
+ 'rm.bytes_of': '({n} bytes of {type})',
3809
+ 'rm.openapi_doc': 'The module\'s OpenAPI 3 document (without the SQL):',
3810
+ 'rm.openapi_help': 'Import it into Swagger UI, Postman or a client generator. Handlers\' documented parameters become its query parameters and request bodies.',
3811
+ 'rm.delete_module_confirm': 'Delete the module {name} with all its templates and handlers?',
3812
+ 'rm.delete_template_confirm': 'Delete the template {uri} and its {n} handler(s)?',
3813
+ 'rm.delete_handler_confirm': 'Delete the handler {method} {uri}?',
3814
+ 'rm.auth_token_role': 'A bearer token of the application with the module\'s role {roles}',
3815
+ 'rm.auth_public_help': '(runs as `nobody`)',
3816
+ 'rm.auth_public_403': '(runs as `nobody`; the module\'s roles still apply, so it answers 403)',
3817
+ 'rm.uri_help': 'Segments and `:parameters` (bound as `:ID`)',
3818
+ 'rm.chk.runs_as': 'Handlers run as `{role}` with `meta.app_user()` the caller',
3819
+ 'rm.chk.role_problem': 'The application\'s database role: {problem} Its handlers answer 403.',
3820
+ 'rm.chk.no_role': 'The application has no database role: handlers run as pgkiln\'s runtime role. Give it its own role (Application › Settings) so grants and row level security are its own.',
3821
+ 'rm.chk.disabled': 'Disabled: every handler answers 404',
3822
+ 'rm.chk.privilege': 'Privilege: callers need the role {roles}',
3823
+ 'rm.chk.no_privilege': 'No privilege roles: any valid token of the application (handlers may add roles)',
3824
+ 'rm.response_as': '{request} as {as}',
3825
+ 'rm.try_intro': 'Sends the request to the real endpoint: a PUT, POST or DELETE changes data. {as} an account issues a short-lived token for it, as App › REST API does; without one you see what a caller without a token gets.',
3826
+ 'rm.intro': 'RESTful Services modules: a module is a base path of an application, its templates are URIs with `:parameters`, and each template has handlers per method with their source: a collection query, a single row, SQL, a PL/pgSQL block or a media resource. Handlers run as the application\'s database role with the caller as `meta.app_user()`, so its grants and row level security apply; parameters are bound, never pasted into the SQL. Every module has an OpenAPI document. Modules belong to their application: they travel with its export (also in Shared Components › RESTful Services).',
3827
+ 'rm.source_help': 'Binds, upper case: path parameters ({params}), query parameters and JSON body fields; `:BODY` is the whole body; `:APP_USER` is the caller. Values are bound, never pasted into the SQL. PL/pgSQL: a block (`declare … begin … end`, or statements) that answers with `perform meta.rest_reply(jsonb_build_object(…), 201)`. Media: a query returning `content_type`, `content` and optionally `filename`.',
3828
+ 'rm.params_help': 'One per line: `name query|body [{types}] [required] [description]`. They go into the OpenAPI document and the Try it form; a required one missing answers 400.',
3829
+ 'rm.e.params_line': 'Parameters, line {n}: write "name query" or "name body", then optionally a type ({types}), "required" and a description.',
3830
+ 'rm.e.choose_app': 'Choose an application of this workspace.',
3831
+ 'rm.e.base_path': 'The base path starts with a lower case letter: letters, digits, _ and - (at most 40).',
3832
+ 'rm.e.title': 'The title is 1 to 200 characters.',
3833
+ 'rm.created': 'Module {name} created at {path}. Add a template next.',
3834
+ 'rm.e.exists': '{app} already has a module {name}.',
3835
+ 'rm.deleted': 'Module {name} deleted: its URLs answer 404.',
3836
+ 'rm.e.template_exists': 'The template {uri} is there already.',
3837
+ 'rm.e.template_gone': 'The template no longer exists.',
3838
+ 'rm.template_deleted': 'Template {uri} and its handlers deleted.',
3839
+ 'rm.e.handler_gone': 'The handler no longer exists.',
3840
+ 'rm.handler_deleted': 'Handler {method} {uri} deleted.',
3841
+ 'rm.e.choose_account': 'Choose an account with access to the application.',
3842
+ 'rm.e.bad_json': 'The body is not valid JSON.',
3843
+ 'rm.e.module_gone': 'The module no longer exists.',
3844
+ 'rm.e.auth': 'Choose who may call it: a token of the application, or public.',
3845
+ 'rm.e.role_length': 'Role names are at most 100 characters.',
3846
+ 'rm.e.page_size': 'The page size is 1 to 500.',
3847
+ 'rm.e.status': 'The status is 200 to 299.',
3848
+ // ------------------------------------------------------------ SQL Workshop › RESTful Services › AutoREST (CD-8)
3849
+ 'ar.kind.table': 'table',
3850
+ 'ar.kind.view': 'view',
3851
+ 'ar.kind.mview': 'materialized view',
3852
+ 'ar.kind.foreign': 'foreign table',
3853
+ 'ar.m.get': 'rows and one row',
3854
+ 'ar.m.post': 'insert a row',
3855
+ 'ar.m.put': 'change a row',
3856
+ 'ar.m.delete': 'delete a row',
3857
+ 'ar.methods': 'Methods',
3858
+ 'ar.auth_token_help': '(an account\'s token or an OAuth client, App › REST API)',
3859
+ 'ar.auth_public': 'Public: anyone, without a token',
3860
+ 'ar.auth_public_help': '(runs as `nobody`; grants and row level security still apply)',
3861
+ 'ar.object': 'Object',
3862
+ 'ar.none_yet': 'No tables or views are published yet. Enable one below, or with {menu} in an object\'s ⋯ menu.',
3863
+ 'ar.menu_enable': 'REST › Enable',
3864
+ 'ar.table_or_view': 'Table or view',
3865
+ 'ar.choose': '- choose -',
3866
+ 'ar.runs_as': 'runs as {role}',
3867
+ 'ar.app_help': 'Its database role runs the statements, its tokens and roles decide who may call it.',
3868
+ 'ar.url_name': 'URL name',
3869
+ 'ar.object_name_ph': 'the object\'s name',
3870
+ 'ar.url_name_rule': 'lower case letters, digits, _ and -',
3871
+ 'ar.any_caller': 'any caller',
3872
+ 'ar.roles_help': 'Comma separated: the caller needs one of these application roles.',
3873
+ 'ar.page_size_help': 'Rows per page without ?limit= (at most {max}).',
3874
+ 'ar.enable': 'Enable',
3875
+ 'ar.no_usable_app': 'No application of this workspace has a database role to run as.',
3876
+ 'ar.intro': 'RESTful Services: publish a table or view as REST endpoints (AutoREST). Rows come paged as JSON, with filters; a primary key gives single-row GET, PUT and DELETE. Requests run as the publishing application\'s database role with the caller as `meta.app_user()`, so its grants and row level security apply.',
3877
+ 'ar.intro_module': 'For tailored endpoints with your own SQL or PL/pgSQL, create a {module}.',
3878
+ 'ar.module_link': 'module',
3879
+ 'ar.published': 'Published objects',
3880
+ 'ar.enable_a': 'Enable a table or view',
3881
+ 'ar.gone': 'The object no longer exists: its endpoints answer 404.',
3882
+ 'ar.chk.runs_as': 'Runs as `{role}`: not the owner, no superuser, no row level security bypass',
3883
+ 'ar.chk.may': '`{role}` may {priv}',
3884
+ 'ar.chk.may_not': '`{role}` may not {priv}',
3885
+ 'ar.chk.rls_on_1': 'Row level security is on (1 policy)',
3886
+ 'ar.chk.rls_on': 'Row level security is on ({n} policies)',
3887
+ 'ar.chk.rls_off': 'Row level security is off: callers see every row the role may select',
3888
+ 'ar.chk.invoker': 'The view is security_invoker: the tables\' row level security applies to the caller',
3889
+ 'ar.chk.definer': 'The view runs with its owner\'s rights, so the row level security of the tables beneath does not apply:',
3890
+ 'ar.chk.key': 'Primary key {columns}: single rows at',
3891
+ 'ar.chk.no_key': 'No primary key: the collection only (GET and POST)',
3892
+ 'ar.chk.hidden_columns': 'Columns the role may not select are left out: {columns}',
3893
+ 'ar.ep.rows': 'Rows, paged: ?limit= (1–{max}, default {size}) &offset= ; ?<column>=<value> ; ?q=<text> ; ?order=<column>.desc',
3894
+ 'ar.ep.post': 'A JSON object of column values: the new row (201)',
3895
+ 'ar.ep.one': 'One row (404 when there is none)',
3896
+ 'ar.ep.put': 'Change the columns the JSON object names',
3897
+ 'ar.ep.delete': 'Delete the row (204)',
3898
+ 'ar.enabled_l': 'enabled',
3899
+ 'ar.disabled_alert': 'Disabled: the endpoints answer 404.',
3900
+ 'ar.endpoints': 'Endpoints',
3901
+ 'ar.does': 'Does',
3902
+ 'ar.openapi_note': '(the public objects; send a token for all of them)',
3903
+ 'ar.public_no_token': 'Public: no token needed.',
3904
+ 'ar.get_token': 'Get {token} from {link}: issue a token for an account, or use an OAuth client\'s access token.',
3905
+ 'ar.caller_needs': 'The caller needs the role {roles}.',
3906
+ 'ar.status_codes': 'Without a valid token the endpoints answer 401; without the role or a grant, 403.',
3907
+ 'ar.settings': 'Settings',
3908
+ 'ar.published_by': 'Published by {app} (runs as {role}) at {path}.',
3909
+ 'ar.remove': 'Disable REST (remove)',
3910
+ 'ar.remove_help': 'The endpoints answer 404 at once; the table itself is not changed.',
3911
+ 'ar.e.no_role': 'The application has no database role. AutoREST runs as the application\'s role: set one in its settings.',
3912
+ 'ar.e.role_problem': 'The application\'s database role: {problem}',
3913
+ 'ar.e.owner': '"{role}" owns {object} (or is a member of its owner): grants and row level security would not apply. Publish it through an application whose role does not own it.',
3914
+ 'ar.e.method': 'Choose at least one method.',
3915
+ 'ar.e.page_size': 'The page size is 1 to {max}.',
3916
+ 'ar.e.mview': 'A materialized view answers GET only.',
3917
+ 'ar.e.no_key': 'PUT and DELETE need a primary key; this object has none.',
3918
+ 'ar.e.choose_object': 'Choose a table or view of a schema the SQL Workshop may use.',
3919
+ 'ar.e.url_name': 'The URL name starts with a lower case letter: letters, digits, _ and - (at most 63).',
3920
+ 'ar.published_at': '{object} is published at {path}.',
3921
+ 'ar.e.alias_taken': '{app} already publishes something as {alias}: choose another URL name.',
3922
+ 'ar.e.already': '{app} already publishes {object}.',
3923
+ 'ar.unpublished': '{object} is no longer published.',
3924
+ // ------------------------------------------------------------ SQL Workshop › Load Data (CD-8)
3925
+ 'dl.row': 'Row',
3926
+ 'dl.error': 'Error',
3927
+ 'dl.first_errors': 'The first {n} errors are shown.',
3928
+ 'dl.failed': '{n} row(s) could not be loaded, so nothing was loaded. Fix the file, or tick “Skip rows with errors”.',
3929
+ 'dl.inserted': '{n} row(s) inserted',
3930
+ 'dl.updated': '{n} updated',
3931
+ 'dl.skipped': '{n} skipped',
3932
+ 'dl.from_file': 'Load data from a file',
3933
+ 'dl.intro': 'CSV or TSV (UTF-8 or Windows-1252; the delimiter is detected), Excel .xlsx (the first sheet), JSON (an array of objects, or JSON Lines) or XML (rows from a repeating element), up to {mb} MB. Next you choose a new or existing table. Loading runs as the builder\'s owner connection.',
3934
+ 'dl.intro_unload': 'To download a table or a query as a file, use {link}.',
3935
+ 'dl.file': 'File',
3936
+ 'dl.headers': 'First row contains column names',
3937
+ 'dl.row_tag': 'XML row element',
3938
+ 'dl.row_tag_ph': 'e.g. employee (empty: detected)',
3939
+ 'dl.row_tag_help': 'XML only. DTDs and entity declarations are not accepted.',
3940
+ 'dl.no_definition': '- none: choose the table next -',
3941
+ 'dl.definition_help': 'Shared Components of an application: table, column mapping and transformations.',
3942
+ 'dl.next': 'Next',
3943
+ 'dl.e.no_file': 'Choose a file.',
3944
+ 'dl.e.too_large': 'The file is larger than {mb} MB.',
3945
+ 'dl.info': '{rows} row(s), {columns} column(s)',
3946
+ 'dl.xml_rows': 'XML rows {path}',
3947
+ 'dl.delimiter': 'delimiter {d}',
3948
+ 'dl.tab': 'tab',
3949
+ 'dl.first_shown': '(first {n} shown)',
3950
+ 'dl.another_file': 'Choose another file',
3951
+ 'dl.def_into': 'Definition {def}: into {table}, mode {mode}',
3952
+ 'dl.def_skipping': 'skipping rows with errors',
3953
+ 'dl.def_by_name': 'File columns are matched to table columns by name.',
3954
+ 'dl.after_mapping': 'After the mapping and transformations:',
3955
+ 'dl.after_mapping_first': 'After the mapping and transformations (first {n} rows):',
3956
+ 'dl.load_into': 'Load into {table}',
3957
+ 'dl.preview': 'Preview',
3958
+ 'dl.load_with': 'Load with {name}',
3959
+ 'dl.skip_errors': 'Skip rows with errors (otherwise nothing is loaded when a row fails)',
3960
+ 'dl.table_name': 'Table name',
3961
+ 'dl.table_name_help': 'schema.table; the table gets an identity primary key `id`.',
3962
+ 'dl.file_column': 'File column',
3963
+ 'dl.column_name': 'Column name (empty = skip)',
3964
+ 'dl.type': 'Type',
3965
+ 'dl.aria_name': 'Column name for {column}',
3966
+ 'dl.aria_type': 'Type of {column}',
3967
+ 'dl.create_and_load': 'Create table and load',
3968
+ 'dl.table_column': 'Table column',
3969
+ 'dl.aria_map': 'Table column for {column}',
3970
+ 'dl.skip': '- skip -',
3971
+ 'dl.key': 'key',
3972
+ 'dl.mode': 'Mode',
3973
+ 'dl.mode_append': 'Append: insert all rows',
3974
+ 'dl.mode_merge': 'Merge: update rows with the same primary key, insert the others',
3975
+ 'dl.mode_replace': 'Replace: delete all rows first',
3976
+ 'dl.save_mapping': 'Save this mapping as a data load definition',
3977
+ 'dl.save_mapping_help': 'For the data_load process of an application, and to load files like this one again.',
3978
+ 'dl.name': 'Name',
3979
+ 'dl.save_definition': 'Save as definition',
3980
+ 'dl.table': 'Table',
3981
+ 'dl.choose_table': '- choose a table -',
3982
+ 'dl.map_columns': 'Map columns',
3983
+ 'dl.into_new': 'Load into a new table',
3984
+ 'dl.into_existing': 'Load into an existing table',
3985
+ 'dl.def_saved': 'Data load definition {name} saved.',
3986
+ 'dl.def_not_saved': 'The definition could not be saved: {reason}',
3987
+ 'dl.def_exists': 'the application already has a definition named {name}.',
3988
+ 'dl.e.def_gone': 'The data load definition no longer exists.',
3989
+ 'dl.e.no_columns': 'Give at least one column a name.',
3990
+ 'dl.view': 'View {table}',
3991
+ 'dl.load_another': 'Load another file',
3992
+ // ------------------------------------------------------------ SQL Workshop › Object Browser › Security and Document view (CD-8)
3993
+ 'ds.roles_and_columns': 'Database roles and columns',
3994
+ 'ds.db_role': 'Database role',
3995
+ 'ds.masked_in': 'Masked in {view}',
3996
+ 'ds.masked': 'masked',
3997
+ 'ds.runs': 'runs {apps}',
3998
+ 'ds.read': 'read',
3999
+ 'ds.update': 'update',
4000
+ 'ds.no_grants': 'No database role has privileges on this table, and no application of the workspace runs with a database role.',
4001
+ 'ds.excluded': 'Not in the matrix, because column privileges can\'t restrict them:',
4002
+ 'ds.masks_per_column': 'Masks per column',
4003
+ 'ds.column': 'Column',
4004
+ 'ds.mask': 'Mask',
4005
+ 'ds.role_sees': '{role} sees it',
4006
+ 'ds.others_see': 'Everyone else sees it',
4007
+ 'ds.aria_mask': 'Mask of {column}',
4008
+ 'ds.not_masked': 'Not masked',
4009
+ 'ds.mask.null': 'empty (null)',
4010
+ 'ds.mask.stars': '***',
4011
+ 'ds.mask.partial': '*** + last 4',
4012
+ 'ds.aria_role_sees': '{role} sees {column}',
4013
+ 'ds.aria_others_see': 'Everyone else sees {column}',
4014
+ 'ds.rows': 'Rows',
4015
+ 'ds.rls_is': 'Row level security is {state}',
4016
+ 'ds.rls_on_owner': 'on, also for the owner',
4017
+ 'ds.rls_on': 'on',
4018
+ 'ds.rls_off': 'off',
4019
+ 'ds.rls_off_detail': 'every role that may read the table reads every row',
4020
+ 'ds.rls_how': '{props} switches it on; {policy} writes one in the worksheet.',
4021
+ 'ds.table_properties': 'Table Properties',
4022
+ 'ds.add_policy': 'Add policy',
4023
+ 'ds.policy': 'Policy',
4024
+ 'ds.command': 'Command',
4025
+ 'ds.roles': 'Roles',
4026
+ 'ds.restrictive': 'restrictive',
4027
+ 'ds.no_policies': 'No policies.',
4028
+ 'ds.no_policies_rls': 'No policies: with row level security on, the roles below read no rows at all.',
4029
+ 'ds.columns': 'Columns',
4030
+ 'ds.columns_help': 'What each database role may read and update, per column. A column a role may not read is refused by PostgreSQL whoever sends the query: pages, REST handlers, AutoREST, AI tools, MCP or psql.',
4031
+ 'ds.values': 'Values',
4032
+ 'ds.values_help': 'Masked columns show their value only to the application roles you tick (`meta.has_role()` of the signed-in user); others see the mask. The masks live in a view next to the table that the roles above read instead of the table.',
4033
+ 'ds.masking_view': 'Masking view',
4034
+ 'ds.view_name': 'View name',
4035
+ 'ds.app_roles': 'Application roles',
4036
+ 'ds.app_roles_help': 'Comma-separated. Changed roles get their column in the table below after Preview SQL.',
4037
+ 'ds.no_changes': 'No changes: the table\'s security is as the form shows it.',
4038
+ 'ds.preview_sql': 'Preview SQL',
4039
+ 'ds.changed_1': 'Changed the security of {table}: 1 statement.',
4040
+ 'ds.changed': 'Changed the security of {table}: {n} statements.',
4041
+ 'ds.rolled_back': 'Nothing was changed: the statements ran in one transaction, which was rolled back.',
4042
+ 'ds.failed_statement': 'Failed statement',
4043
+ 'ds.title': 'Security of {table}',
4044
+ 'ds.security': 'Security',
4045
+ 'docv.no_key': '{table} has no primary key: a document view finds its rows by it.',
4046
+ 'docv.doc_is_key': 'The document column may not have the name of a key column ({name}).',
4047
+ 'docv.made': 'The document view {view} is made.',
4048
+ 'docv.children': 'Child tables in the document',
4049
+ 'docv.list': 'List in the document',
4050
+ 'docv.fk': 'Foreign key',
4051
+ 'docv.no_children': 'No other table references {table}: the document is the row alone.',
4052
+ 'docv.children_help': 'Each child row is an object in its list, without the foreign key columns. Writing a document updates the children it lists by their key, inserts the ones without a key, and deletes the ones it leaves out; a document without the list leaves the children alone.',
4053
+ 'docv.view': 'View',
4054
+ 'docv.doc_column': 'Document column',
4055
+ 'docv.intro': 'A document view shows each row of {table} with its child rows as one JSON document, like an Oracle JSON Relational Duality View. Reports, REST (AutoREST on the view) and MCP read whole documents; an update of the document column writes the row and its children back in one statement. The table\'s row level security and grants apply (the view is security_invoker and gets the table\'s grants).',
2429
4056
  } as const;