@cavulsqa/create 2.9.3 → 2.10.1

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 (199) hide show
  1. package/README.md +12 -1
  2. package/bin/create.mjs +18 -25
  3. package/lib/templates.mjs +56 -0
  4. package/package.json +13 -5
  5. package/templates/f7-app/auto-imports.d.ts +9 -0
  6. package/templates/f7-app/package.json +6 -3
  7. package/templates/f7-app/src/env.d.ts +1 -0
  8. package/templates/f7-app/src/main.ts +3 -0
  9. package/templates/f7-app/src/plugins/bootstrapError.ts +2 -0
  10. package/templates/f7-app/src/plugins/recorder.plugin.ts +155 -0
  11. package/templates/f7-app/src/shared/recorder/capacitorSink.ts +124 -0
  12. package/templates/f7-app/vite.config.ts +1 -0
  13. package/templates/m3e-app/.claude/rules/data-fetching.md +68 -0
  14. package/templates/m3e-app/.claude/rules/database.md +106 -0
  15. package/templates/m3e-app/.claude/rules/m3e-ui.md +48 -0
  16. package/templates/m3e-app/.claude/rules/modules.md +43 -0
  17. package/templates/m3e-app/.claude/rules/native.md +60 -0
  18. package/templates/m3e-app/.claude/skills/m3-expressive/SKILL.md +68 -0
  19. package/templates/m3e-app/.claude/skills/m3-expressive/color.md +44 -0
  20. package/templates/m3e-app/.claude/skills/m3-expressive/components.md +325 -0
  21. package/templates/m3e-app/.claude/skills/m3-expressive/layout.md +42 -0
  22. package/templates/m3e-app/.claude/skills/m3-expressive/motion.md +51 -0
  23. package/templates/m3e-app/.claude/skills/m3-expressive/shapes-type.md +48 -0
  24. package/templates/m3e-app/.claude/skills/m3-expressive/sources.md +53 -0
  25. package/templates/m3e-app/.claude/skills/module-architecture/SKILL.md +65 -0
  26. package/templates/m3e-app/.claude/skills/module-architecture/file-templates.md +178 -0
  27. package/templates/m3e-app/.claude/skills/reactive-data/SKILL.md +90 -0
  28. package/templates/m3e-app/.claude/skills/reactive-data/testing.md +55 -0
  29. package/templates/m3e-app/.env.example +32 -0
  30. package/templates/m3e-app/CLAUDE.md +93 -0
  31. package/templates/m3e-app/auto-imports.d.ts +851 -0
  32. package/templates/m3e-app/capacitor.config.ts +44 -0
  33. package/templates/m3e-app/components.d.ts +252 -0
  34. package/templates/m3e-app/index.html +16 -0
  35. package/templates/m3e-app/package.json +108 -0
  36. package/templates/m3e-app/src/App.vue +129 -0
  37. package/templates/m3e-app/src/app/pragmas.config.ts +35 -0
  38. package/templates/m3e-app/src/app/scroll.config.ts +20 -0
  39. package/templates/m3e-app/src/app/storage.config.ts +65 -0
  40. package/templates/m3e-app/src/app/tabs.ts +33 -0
  41. package/templates/m3e-app/src/app/theme.config.ts +51 -0
  42. package/templates/m3e-app/src/assets/css/app.css +18 -0
  43. package/templates/m3e-app/src/assets/css/base.css +53 -0
  44. package/templates/m3e-app/src/assets/css/layout/container-transform.css +113 -0
  45. package/templates/m3e-app/src/assets/css/layout/shell.css +69 -0
  46. package/templates/m3e-app/src/assets/css/layout/transitions.css +121 -0
  47. package/templates/m3e-app/src/assets/css/m3e.css +6 -0
  48. package/templates/m3e-app/src/assets/css/theme/framework7.css +18 -0
  49. package/templates/m3e-app/src/assets/css/theme/tailwind.css +365 -0
  50. package/templates/m3e-app/src/domains/benchmark/benchmark.dataset.ts +209 -0
  51. package/templates/m3e-app/src/domains/benchmark/benchmark.suite.ts +662 -0
  52. package/templates/m3e-app/src/domains/sales/sales.repository.ts +458 -0
  53. package/templates/m3e-app/src/env.d.ts +40 -0
  54. package/templates/m3e-app/src/locales/ar.json +1260 -0
  55. package/templates/m3e-app/src/locales/en.json +1260 -0
  56. package/templates/m3e-app/src/locales/fr.json +1260 -0
  57. package/templates/m3e-app/src/main.ts +41 -0
  58. package/templates/m3e-app/src/modules/demo/components/DemoBenchmark.vue +119 -0
  59. package/templates/m3e-app/src/modules/demo/components/DemoBusLog.vue +63 -0
  60. package/templates/m3e-app/src/modules/demo/components/DemoCreateOrderSheet.vue +203 -0
  61. package/templates/m3e-app/src/modules/demo/components/DemoMetricsSheet.vue +75 -0
  62. package/templates/m3e-app/src/modules/demo/components/DemoOrderList.vue +75 -0
  63. package/templates/m3e-app/src/modules/demo/components/DemoPipelineBenchmark.vue +65 -0
  64. package/templates/m3e-app/src/modules/demo/components/DemoStatCards.vue +71 -0
  65. package/templates/m3e-app/src/modules/demo/composables/useBenchmark.ts +139 -0
  66. package/templates/m3e-app/src/modules/demo/composables/useOrderStatus.ts +64 -0
  67. package/templates/m3e-app/src/modules/demo/composables/useReactiveDemo.ts +171 -0
  68. package/templates/m3e-app/src/modules/demo/router/routes/demo.routes.ts +22 -0
  69. package/templates/m3e-app/src/modules/demo/views/DemoView.vue +210 -0
  70. package/templates/m3e-app/src/modules/demo/views/OrderDetailView.vue +136 -0
  71. package/templates/m3e-app/src/modules/demo/views/OrderSearchView.vue +74 -0
  72. package/templates/m3e-app/src/modules/gallery/components/GalleryBlock.vue +16 -0
  73. package/templates/m3e-app/src/modules/gallery/components/GalleryCarouselTile.vue +71 -0
  74. package/templates/m3e-app/src/modules/gallery/components/GalleryCustomerForm.vue +76 -0
  75. package/templates/m3e-app/src/modules/gallery/components/GalleryProofOfDelivery.vue +69 -0
  76. package/templates/m3e-app/src/modules/gallery/components/agenda/AgendaDay.vue +106 -0
  77. package/templates/m3e-app/src/modules/gallery/components/agenda/AgendaMonth.vue +40 -0
  78. package/templates/m3e-app/src/modules/gallery/components/agenda/AgendaVisitList.vue +45 -0
  79. package/templates/m3e-app/src/modules/gallery/components/chat/ChatAttachSheet.vue +106 -0
  80. package/templates/m3e-app/src/modules/gallery/components/chat/ChatContactPicker.vue +85 -0
  81. package/templates/m3e-app/src/modules/gallery/components/chat/ChatInviteComposer.vue +131 -0
  82. package/templates/m3e-app/src/modules/gallery/components/chat/ChatPollComposer.vue +148 -0
  83. package/templates/m3e-app/src/modules/gallery/components/chat/ChatRecentPhotos.vue +62 -0
  84. package/templates/m3e-app/src/modules/gallery/components/inputs/InputsAccount.vue +79 -0
  85. package/templates/m3e-app/src/modules/gallery/components/inputs/InputsTags.vue +53 -0
  86. package/templates/m3e-app/src/modules/gallery/components/inputs/InputsVerification.vue +73 -0
  87. package/templates/m3e-app/src/modules/gallery/components/inputs/PasswordStrength.vue +37 -0
  88. package/templates/m3e-app/src/modules/gallery/components/sections/GalleryButtons.vue +128 -0
  89. package/templates/m3e-app/src/modules/gallery/components/sections/GalleryCarousels.vue +236 -0
  90. package/templates/m3e-app/src/modules/gallery/components/sections/GalleryCharts.vue +84 -0
  91. package/templates/m3e-app/src/modules/gallery/components/sections/GalleryFabs.vue +70 -0
  92. package/templates/m3e-app/src/modules/gallery/components/sections/GalleryInputs.vue +219 -0
  93. package/templates/m3e-app/src/modules/gallery/components/sections/GalleryNavigation.vue +141 -0
  94. package/templates/m3e-app/src/modules/gallery/components/sections/GalleryOverlays.vue +368 -0
  95. package/templates/m3e-app/src/modules/gallery/components/sections/GalleryPickers.vue +175 -0
  96. package/templates/m3e-app/src/modules/gallery/components/sections/GalleryProgress.vue +118 -0
  97. package/templates/m3e-app/src/modules/gallery/components/sections/GalleryScale.vue +103 -0
  98. package/templates/m3e-app/src/modules/gallery/components/sections/GallerySelection.vue +219 -0
  99. package/templates/m3e-app/src/modules/gallery/components/sections/GalleryShapes.vue +48 -0
  100. package/templates/m3e-app/src/modules/gallery/components/sections/GallerySurfaces.vue +213 -0
  101. package/templates/m3e-app/src/modules/gallery/components/sections/GalleryTables.vue +185 -0
  102. package/templates/m3e-app/src/modules/gallery/components/surfaces/SurfacesContainerTransform.vue +46 -0
  103. package/templates/m3e-app/src/modules/gallery/composables/chatTeam.ts +18 -0
  104. package/templates/m3e-app/src/modules/gallery/composables/composeKind.ts +2 -0
  105. package/templates/m3e-app/src/modules/gallery/composables/currentPosition.ts +35 -0
  106. package/templates/m3e-app/src/modules/gallery/composables/demoOrders.ts +29 -0
  107. package/templates/m3e-app/src/modules/gallery/composables/featuredStories.ts +73 -0
  108. package/templates/m3e-app/src/modules/gallery/composables/fieldFormats.ts +36 -0
  109. package/templates/m3e-app/src/modules/gallery/composables/openExternal.ts +11 -0
  110. package/templates/m3e-app/src/modules/gallery/composables/routePlan.ts +90 -0
  111. package/templates/m3e-app/src/modules/gallery/composables/useAgenda.ts +61 -0
  112. package/templates/m3e-app/src/modules/gallery/composables/useChatCustomers.ts +31 -0
  113. package/templates/m3e-app/src/modules/gallery/composables/useChatDemo.ts +299 -0
  114. package/templates/m3e-app/src/modules/gallery/composables/useGallerySections.ts +230 -0
  115. package/templates/m3e-app/src/modules/gallery/composables/useLocalAttachments.ts +71 -0
  116. package/templates/m3e-app/src/modules/gallery/composables/useLocationShare.ts +38 -0
  117. package/templates/m3e-app/src/modules/gallery/composables/usePhotoScenes.ts +82 -0
  118. package/templates/m3e-app/src/modules/gallery/composables/useTreeDemo.ts +67 -0
  119. package/templates/m3e-app/src/modules/gallery/composables/wilayas.ts +67 -0
  120. package/templates/m3e-app/src/modules/gallery/router/routes/gallery.routes.ts +52 -0
  121. package/templates/m3e-app/src/modules/gallery/views/GalleryAgendaView.vue +117 -0
  122. package/templates/m3e-app/src/modules/gallery/views/GalleryChatView.vue +292 -0
  123. package/templates/m3e-app/src/modules/gallery/views/GalleryContactsView.vue +77 -0
  124. package/templates/m3e-app/src/modules/gallery/views/GalleryFeaturedView.vue +60 -0
  125. package/templates/m3e-app/src/modules/gallery/views/GalleryLoginView.vue +135 -0
  126. package/templates/m3e-app/src/modules/gallery/views/GalleryOnboardingView.vue +116 -0
  127. package/templates/m3e-app/src/modules/gallery/views/GallerySectionView.vue +27 -0
  128. package/templates/m3e-app/src/modules/gallery/views/GalleryTabsView.vue +135 -0
  129. package/templates/m3e-app/src/modules/gallery/views/GalleryView.vue +50 -0
  130. package/templates/m3e-app/src/modules/home/components/HomeHero.vue +57 -0
  131. package/templates/m3e-app/src/modules/home/composables/useHomeFeatures.ts +128 -0
  132. package/templates/m3e-app/src/modules/home/composables/useOpenFeature.ts +22 -0
  133. package/templates/m3e-app/src/modules/home/router/routes/home.routes.ts +21 -0
  134. package/templates/m3e-app/src/modules/home/views/FeatureDetailView.vue +66 -0
  135. package/templates/m3e-app/src/modules/home/views/HomeView.vue +47 -0
  136. package/templates/m3e-app/src/modules/settings/components/RolePalette.vue +38 -0
  137. package/templates/m3e-app/src/modules/settings/components/SeedSwatches.vue +41 -0
  138. package/templates/m3e-app/src/modules/settings/components/SettingsChoice.vue +43 -0
  139. package/templates/m3e-app/src/modules/settings/components/StudioPreview.vue +52 -0
  140. package/templates/m3e-app/src/modules/settings/router/routes/settings.routes.ts +17 -0
  141. package/templates/m3e-app/src/modules/settings/types.ts +7 -0
  142. package/templates/m3e-app/src/modules/settings/views/ColorStudioView.vue +166 -0
  143. package/templates/m3e-app/src/modules/settings/views/SettingsView.vue +157 -0
  144. package/templates/m3e-app/src/plugins/bootstrapError.ts +62 -0
  145. package/templates/m3e-app/src/plugins/capacitor/index.ts +14 -0
  146. package/templates/m3e-app/src/plugins/capacitor/useAndroidBackButton.ts +36 -0
  147. package/templates/m3e-app/src/plugins/capacitor/useKeyboard.ts +48 -0
  148. package/templates/m3e-app/src/plugins/capacitor/useSplashScreen.ts +43 -0
  149. package/templates/m3e-app/src/plugins/capacitor/useStatusBar.ts +16 -0
  150. package/templates/m3e-app/src/plugins/framework7.plugin.ts +36 -0
  151. package/templates/m3e-app/src/plugins/i18n.plugin.ts +87 -0
  152. package/templates/m3e-app/src/plugins/m3e.plugin.ts +22 -0
  153. package/templates/m3e-app/src/plugins/seed.plugin.ts +7 -0
  154. package/templates/m3e-app/src/plugins/sqlite.plugin.ts +32 -0
  155. package/templates/m3e-app/src/router/global/global.routes.ts +12 -0
  156. package/templates/m3e-app/src/router/index.ts +20 -0
  157. package/templates/m3e-app/src/shared/components/error/404.vue +13 -0
  158. package/templates/m3e-app/src/shared/components/layout/EmptyState.vue +30 -0
  159. package/templates/m3e-app/src/shared/components/layout/SectionHeader.vue +10 -0
  160. package/templates/m3e-app/src/shared/components/page/AppPage.vue +104 -0
  161. package/templates/m3e-app/src/shared/composables/navigation/useActiveTab.ts +39 -0
  162. package/templates/m3e-app/src/shared/composables/navigation/useContainerTransform.ts +117 -0
  163. package/templates/m3e-app/src/shared/composables/navigation/useNavigationGuard.ts +48 -0
  164. package/templates/m3e-app/src/shared/composables/navigation/useNavigationVisibility.ts +64 -0
  165. package/templates/m3e-app/src/shared/composables/navigation/useViewRouter.ts +25 -0
  166. package/templates/m3e-app/src/shared/composables/navigation/useWindowClass.ts +22 -0
  167. package/templates/m3e-app/src/shared/composables/theme/useThemeSettings.ts +155 -0
  168. package/templates/m3e-app/src/shared/database/candidates/capacitorSqlite.ts +36 -0
  169. package/templates/m3e-app/src/shared/database/candidates/index.ts +4 -0
  170. package/templates/m3e-app/src/shared/database/candidates/opfsSahPool.ts +25 -0
  171. package/templates/m3e-app/src/shared/database/candidates/types.ts +56 -0
  172. package/templates/m3e-app/src/shared/database/candidates/waSqlite.ts +56 -0
  173. package/templates/m3e-app/src/shared/database/database.ts +219 -0
  174. package/templates/m3e-app/src/shared/database/index.ts +3 -0
  175. package/templates/m3e-app/src/shared/database/migrations.ts +223 -0
  176. package/templates/m3e-app/src/shared/database/opfs.worker.ts +5 -0
  177. package/templates/m3e-app/src/shared/database/queries.ts +26 -0
  178. package/templates/m3e-app/src/shared/database/schema.ts +153 -0
  179. package/templates/m3e-app/src/shared/database/storage.ts +64 -0
  180. package/templates/m3e-app/src/shared/database/wa.worker.ts +5 -0
  181. package/templates/m3e-app/src/shared/utils/lazyRoute.ts +41 -0
  182. package/templates/m3e-app/src/shared/utils/resolvers/resolvers.ts +42 -0
  183. package/templates/m3e-app/src/shared/utils/textDirection.ts +22 -0
  184. package/templates/m3e-app/src/shared/utils/theme/themeSettings.ts +59 -0
  185. package/templates/m3e-app/src/shared/utils/tone.ts +8 -0
  186. package/templates/m3e-app/tests/benchmark.suite.test.ts +104 -0
  187. package/templates/m3e-app/tests/containerTransform.test.ts +58 -0
  188. package/templates/m3e-app/tests/fieldFormats.test.ts +25 -0
  189. package/templates/m3e-app/tests/lazyRoute.test.ts +30 -0
  190. package/templates/m3e-app/tests/locales.test.ts +73 -0
  191. package/templates/m3e-app/tests/migrations.test.ts +74 -0
  192. package/templates/m3e-app/tests/navigationGuard.test.ts +82 -0
  193. package/templates/m3e-app/tests/openDatabase.test.ts +54 -0
  194. package/templates/m3e-app/tests/sales.repository.test.ts +329 -0
  195. package/templates/m3e-app/tests/storage.test.ts +117 -0
  196. package/templates/m3e-app/tests/textDirection.test.ts +11 -0
  197. package/templates/m3e-app/tooling/linkedPackages.ts +112 -0
  198. package/templates/m3e-app/tsconfig.json +21 -0
  199. package/templates/m3e-app/vite.config.ts +144 -0
@@ -0,0 +1,1260 @@
1
+ {
2
+ "tabs": {
3
+ "home": "Overview",
4
+ "demo": "Orders",
5
+ "gallery": "Gallery",
6
+ "settings": "Settings"
7
+ },
8
+ "shell": {
9
+ "navigation": "Main navigation",
10
+ "back": "Back",
11
+ "expand": "Expand navigation",
12
+ "collapse": "Collapse navigation",
13
+ "dismiss": "Dismiss",
14
+ "routeFailed": "This page could not open",
15
+ "reload": "Reload",
16
+ "notification": "Notification",
17
+ "notificationsMore": "{count} more | {count} more",
18
+ "notificationsLess": "Show less",
19
+ "notificationsClear": "Clear all"
20
+ },
21
+ "home": {
22
+ "title": "Overview",
23
+ "overline": "Material 3 Expressive",
24
+ "headline": "Your app, in motion",
25
+ "intro": "{app} is an offline-first starter: Vue, Capacitor and a local SQLite database, dressed in shape, spring and colour.",
26
+ "morph": "Morph the shape",
27
+ "actions": "Where to go next",
28
+ "explore": "Explore components",
29
+ "personalise": "Make it yours",
30
+ "studio": "Colour studio",
31
+ "included": "What's inside"
32
+ },
33
+ "detail": {
34
+ "thisScreen": "This screen",
35
+ "transition": "Page transition",
36
+ "transitionNote": "Framework7 opened this page with {name}; back plays it in reverse. Every feature on Home has its own.",
37
+ "appBar": "Medium flexible app bar",
38
+ "appBarNote": "Scroll: the big title leaves and the bar takes it, turning surface-container as content passes beneath.",
39
+ "nesting": "Nested in its tab",
40
+ "nestingNote": "This push lives in the Overview tab's own history: other tabs keep their screen, and back unwinds only this one.",
41
+ "next": "Next feature"
42
+ },
43
+ "features": {
44
+ "expressive": {
45
+ "title": "Material 3 Expressive",
46
+ "subtitle": "Shapes, springs, wavy progress",
47
+ "text": "Forty components from the m3e-vue package, built from Google's own Compose numbers: the 35 shapes, the spring motion scheme, the loading indicator and the wavy indicators."
48
+ },
49
+ "color": {
50
+ "title": "Dynamic colour",
51
+ "subtitle": "One seed, the 2025 colour spec",
52
+ "text": "Every role in light and dark is generated from one seed. The colour studio changes it live: variant, contrast, custom colours."
53
+ },
54
+ "shell": {
55
+ "title": "Adaptive shell",
56
+ "subtitle": "Bar on phones, rail from 600dp",
57
+ "text": "Destinations are data. Compact windows get the 64dp navigation bar; medium and larger get the navigation rail, each tab keeping its own history."
58
+ },
59
+ "sqlite": {
60
+ "title": "SQLite",
61
+ "subtitle": "Kysely, offline-first",
62
+ "text": "SQLite compiled to WebAssembly, in a worker, against a real file in OPFS - no native plugin."
63
+ },
64
+ "reactive": {
65
+ "title": "Reactive queries",
66
+ "subtitle": "No manual invalidation",
67
+ "text": "A write announces its tables and every query watching one refetches, debounced."
68
+ },
69
+ "back": {
70
+ "title": "Android back",
71
+ "subtitle": "Closes the top layer first",
72
+ "text": "Back closes the topmost sheet, dialog or menu, then walks the tab's history, then returns to the start destination."
73
+ },
74
+ "keyboard": {
75
+ "title": "Keyboard",
76
+ "subtitle": "Fields stay in view",
77
+ "text": "The focused field scrolls back into view on every phase of the keyboard animation, and the navigation bar steps aside."
78
+ },
79
+ "metrics": {
80
+ "title": "Query metrics",
81
+ "subtitle": "Durations, refetches, cache",
82
+ "text": "Every query is measured. Open the metrics sheet from the Orders screen to see what refetched and why."
83
+ }
84
+ },
85
+ "demo": {
86
+ "title": "Orders",
87
+ "clear": "Reset data",
88
+ "refetching": "Refreshing",
89
+ "empty": "Seed some sample data, or create an order from the button.",
90
+ "pipelining": "Read pipelining",
91
+ "measure": "Measure",
92
+ "measuring": "Measuring…",
93
+ "parallel": "Together",
94
+ "sequential": "One by one",
95
+ "ratio": "Faster by",
96
+ "pipeliningNative": "{count} reads issued together, then the same {count} awaited one at a time. The engine runs in a worker that executes statements one at a time, so issuing them together overlaps the message round trips and nothing else.",
97
+ "pipeliningWeb": "{count} reads issued together, then the same {count} awaited one at a time. In a desktop browser the round trip is nearly free - see the note under the result.",
98
+ "ratioNative": "Above 1x means the message round trips are overlapping. The worker is serial, so this can never show queries themselves running in parallel.",
99
+ "ratioWeb": "Expected on {platform}: the worker is serial and a desktop round trip is nearly free, so there is little to overlap. Measure on a device, where the round trip costs something.",
100
+ "data": "Data",
101
+ "diagnostics": "Diagnostics",
102
+ "searchPlaceholder": "Search orders or customers",
103
+ "orders": "Orders",
104
+ "lines": "{count} line | {count} lines",
105
+ "seed": "Seed sample data",
106
+ "tiles": {
107
+ "draft": "Draft",
108
+ "confirmed": "Confirmed",
109
+ "delivered": "Delivered",
110
+ "committed": "Committed",
111
+ "ofOrders": "of {count} order | of {count} orders",
112
+ "ofTotal": "of {total} total"
113
+ },
114
+ "bus": "Change bus",
115
+ "busHint": "Every event a write published. The queries are subscribed to the same stream.",
116
+ "busEmpty": "No events yet.",
117
+ "newOrder": "New order",
118
+ "reference": "Reference",
119
+ "customer": "Customer",
120
+ "products": "Products",
121
+ "total": "Total",
122
+ "save": "Save order",
123
+ "cancel": "Cancel",
124
+ "confirm": "Confirm",
125
+ "deliver": "Mark delivered",
126
+ "delete": "Delete",
127
+ "noMatches": "Nothing matches that search.",
128
+ "order": "Order",
129
+ "orderGone": "That order no longer exists.",
130
+ "lineItems": "Line items",
131
+ "searchTitle": "Search orders",
132
+ "statusDraft": "Draft",
133
+ "statusConfirmed": "Confirmed",
134
+ "statusDelivered": "Delivered",
135
+ "deleteConfirm": "Delete this order and its lines?",
136
+ "allOrders": "Recent orders",
137
+ "matches": "{count} match | {count} matches",
138
+ "engineSwitch": "One engine everywhere - no bridge to pipeline",
139
+ "measuredOn": "Measured on {engine}",
140
+ "emptyTitle": "No orders yet",
141
+ "actions": "Order actions",
142
+ "actionsFor": "Actions for {reference}",
143
+ "chooseCustomer": "Choose a customer",
144
+ "less": "One less {product}",
145
+ "more": "One more {product}",
146
+ "loadFailed": "The order form could not load.",
147
+ "saveFailed": "The order was not saved. Try again.",
148
+ "actionFailed": "That did not work. Nothing was changed.",
149
+ "saved": "{reference} saved",
150
+ "deleted": "{reference} deleted",
151
+ "clearTitle": "Reset the demo data?",
152
+ "clearText": "Every order is deleted. Customers and products are put back.",
153
+ "noMatchesTitle": "Nothing found",
154
+ "status": "Order status"
155
+ },
156
+ "metrics": {
157
+ "totalQueries": "Queries run",
158
+ "avgQueryTime": "Average duration",
159
+ "cacheHitRate": "Cache hit rate",
160
+ "activeListeners": "Active listeners",
161
+ "title": "Query metrics",
162
+ "refetchesTitle": "Refetches per table",
163
+ "noRefetches": "No refetches yet.",
164
+ "slowest": "Slowest queries",
165
+ "noQueries": "No queries recorded yet.",
166
+ "calls": "{count} call | {count} calls",
167
+ "reset": "Reset metrics"
168
+ },
169
+ "bench": {
170
+ "title": "Benchmark",
171
+ "intro": "Every operation a screen in this app performs, run against the benchmark's own two tables so it never touches your data. Switch engines in Settings and run it again - the second run is compared against the first.",
172
+ "run": "Run benchmark",
173
+ "running": "Running",
174
+ "against": "vs {engine}",
175
+ "cases": "Cases",
176
+ "rows": "Rows seeded",
177
+ "wall": "Wall clock",
178
+ "worst": "worst",
179
+ "faster": "{times}x faster here",
180
+ "slower": "{times}x slower here",
181
+ "copy": "Copy JSON",
182
+ "clear": "Clear results",
183
+ "copied": "Copied",
184
+ "copyFailed": "Could not reach the clipboard.",
185
+ "group": {
186
+ "read": "Reads",
187
+ "join": "Joins",
188
+ "write": "Writes",
189
+ "transaction": "Transactions",
190
+ "schema": "Schema",
191
+ "concurrency": "Concurrency",
192
+ "sync": "Sync strategies"
193
+ },
194
+ "pragmas": "PRAGMA {profile}",
195
+ "seeded": "Dataset built in {ms} ms - later runs reuse it"
196
+ },
197
+ "gallery": {
198
+ "title": "Gallery",
199
+ "intro": "Every Material 3 Expressive component in this kit, live, with the spec point each one shows.",
200
+ "loading": "Loading",
201
+ "sections": {
202
+ "buttons": {
203
+ "title": "Buttons",
204
+ "subtitle": "Five sizes, shape morph, toggles, groups"
205
+ },
206
+ "fabs": {
207
+ "title": "Floating action buttons",
208
+ "subtitle": "FAB, extended FAB, FAB menu"
209
+ },
210
+ "progress": {
211
+ "title": "Progress and loading",
212
+ "subtitle": "Wavy indicators, the shape loader"
213
+ },
214
+ "shapes": {
215
+ "title": "Shapes",
216
+ "subtitle": "The 35-shape library and morphing"
217
+ },
218
+ "navigation": {
219
+ "title": "Navigation",
220
+ "subtitle": "Tabs, navigation bar, toolbars"
221
+ },
222
+ "overlays": {
223
+ "title": "Sheets and dialogs",
224
+ "subtitle": "Bottom sheet, action sheet, menu, snackbar"
225
+ },
226
+ "selection": {
227
+ "title": "Selection",
228
+ "subtitle": "Switches, checkboxes, sliders, chips"
229
+ },
230
+ "inputs": {
231
+ "title": "Text input",
232
+ "subtitle": "Fields and the search bar"
233
+ },
234
+ "carousels": {
235
+ "title": "Carousels",
236
+ "subtitle": "Multi-browse, hero, uncontained, photo browser"
237
+ },
238
+ "surfaces": {
239
+ "title": "Cards and lists",
240
+ "subtitle": "Surfaces and expressive lists"
241
+ },
242
+ "pickers": {
243
+ "title": "Date and time",
244
+ "subtitle": "Dates, times, wheels - dialog or sheet"
245
+ },
246
+ "scale": {
247
+ "title": "Lists at scale",
248
+ "subtitle": "5,000 rows, pull to refresh"
249
+ },
250
+ "tabs": {
251
+ "title": "Swipeable tabs",
252
+ "subtitle": "Pages under the app bar, swiped between"
253
+ },
254
+ "contacts": {
255
+ "title": "Grouped list and index",
256
+ "subtitle": "Sticky group titles, an A–Z rail"
257
+ },
258
+ "tables": {
259
+ "title": "Data table",
260
+ "subtitle": "Sort, select, sticky header and column"
261
+ },
262
+ "charts": {
263
+ "title": "Charts",
264
+ "subtitle": "Line, area, bar and donut"
265
+ },
266
+ "chat": {
267
+ "title": "Messages",
268
+ "subtitle": "Bubbles, history and a composer"
269
+ },
270
+ "onboarding": {
271
+ "title": "Onboarding",
272
+ "subtitle": "A pager with page dots"
273
+ },
274
+ "login": {
275
+ "title": "Sign-in screen",
276
+ "subtitle": "Validation and a remembered email"
277
+ },
278
+ "agenda": {
279
+ "title": "Agenda",
280
+ "subtitle": "Day, week and month views of a rep's route"
281
+ }
282
+ },
283
+ "buttons": {
284
+ "variants": "Variants",
285
+ "variantsNote": "Filled for the main action, tonal and outlined below it, text for the least.",
286
+ "sizes": "Sizes",
287
+ "sizesNote": "XS to XL, round or square. Press one: the corners tighten on the effects spring, without bounce.",
288
+ "toggle": "Toggle buttons",
289
+ "toggleNote": "Selected round buttons turn square; selected square ones turn round.",
290
+ "save": "Save",
291
+ "star": "Star",
292
+ "icon": "Icon buttons",
293
+ "iconNote": "Standard, filled, tonal, outlined; narrow, default and wide.",
294
+ "favorite": "Favourite",
295
+ "share": "Share",
296
+ "edit": "Edit",
297
+ "more": "More",
298
+ "group": "Standard button group",
299
+ "groupNote": "Press and hold one: it widens by 15% and its neighbours give way.",
300
+ "bold": "Bold",
301
+ "italic": "Italic",
302
+ "underline": "Underline",
303
+ "connected": "Connected button group",
304
+ "connectedNote": "Replaces segmented buttons: 2dp apart, the selected one rounds off completely.",
305
+ "periods": {
306
+ "day": "Day",
307
+ "week": "Week",
308
+ "month": "Month"
309
+ },
310
+ "split": "Split button",
311
+ "splitNote": "A main action with related ones; the trailing half rounds off while its menu is open.",
312
+ "send": "Send",
313
+ "moreOptions": "More send options",
314
+ "schedule": "Schedule send",
315
+ "saveDraft": "Save as draft",
316
+ "sent": "Done"
317
+ },
318
+ "fabs": {
319
+ "sizes": "Sizes",
320
+ "sizesNote": "Small, baseline, medium (new in Expressive) and large.",
321
+ "colors": "Colours",
322
+ "colorsNote": "Container colours by default; the solid roles for more emphasis.",
323
+ "extended": "Extended FAB",
324
+ "extendedNote": "Tap it: the label collapses away and comes back on the spatial spring.",
325
+ "compose": "Compose",
326
+ "menu": "FAB menu",
327
+ "menuNote": "Up to six actions spring out from the FAB's corner, staggered; it turns into a close button.",
328
+ "create": "Create",
329
+ "order": "Order",
330
+ "customer": "Customer",
331
+ "note": "Note",
332
+ "picked": "Picked"
333
+ },
334
+ "progress": {
335
+ "drive": "Progress",
336
+ "driveNote": "Drag to drive every determinate indicator below. The wave flattens under 10% and above 95%.",
337
+ "loading": "Loading indicator",
338
+ "loadingNote": "Seven shapes morphing in a loop, for waits under a few seconds. It replaces the spinner.",
339
+ "determinate": "Determinate",
340
+ "indeterminate": "Indeterminate",
341
+ "flat": "Flat",
342
+ "thick": "Thick",
343
+ "gauge": "Gauge",
344
+ "linear": "Linear",
345
+ "linearNote": "Wavy, indeterminate, flat and thick. A gap and a stop dot mark where the track ends.",
346
+ "circular": "Circular",
347
+ "circularNote": "48dp wavy or 40dp flat, and the half-ring gauge.",
348
+ "skeleton": "Skeleton loading",
349
+ "skeletonNote": "Framework7's placeholders in Material colours: the layout of what is coming, with one highlight sweeping the whole group.",
350
+ "reload": "Reload",
351
+ "wave": "Wave",
352
+ "pulse": "Pulse",
353
+ "loadingCustomers": "Loading customers",
354
+ "customer": "Customer {n}",
355
+ "customerNote": "{count} open orders"
356
+ },
357
+ "shapes": {
358
+ "morph": "Morph",
359
+ "morphNote": "Pick any shape below: this one morphs into it on the default spatial spring.",
360
+ "library": "The library",
361
+ "libraryNote": "All 35, built from the same vertices and rounding as Android's MaterialShapes."
362
+ },
363
+ "navigation": {
364
+ "primaryTabs": "Primary tabs",
365
+ "primaryTabsNote": "A 3dp indicator as wide as the content, springing between tabs.",
366
+ "flights": "Flights",
367
+ "trips": "Trips",
368
+ "explore": "Explore",
369
+ "secondaryTabs": "Secondary tabs",
370
+ "secondaryTabsNote": "Scrollable, with a full-width 2dp indicator.",
371
+ "months": {
372
+ "jan": "January",
373
+ "feb": "February",
374
+ "mar": "March",
375
+ "apr": "April",
376
+ "may": "May",
377
+ "jun": "June",
378
+ "jul": "July",
379
+ "aug": "August"
380
+ },
381
+ "bar": "Navigation bar",
382
+ "barNote": "The flexible 64dp bar: the indicator springs open, the icon fills, badges count or dot.",
383
+ "inbox": "Inbox",
384
+ "starred": "Starred",
385
+ "saved": "Saved",
386
+ "toolbar": "Floating toolbar",
387
+ "toolbarNote": "Replaces the bottom app bar; standard or vibrant, with a paired FAB.",
388
+ "vibrant": "Vibrant colours",
389
+ "breadcrumbs": "Breadcrumbs",
390
+ "breadcrumbsNote": "Where you are in a hierarchy; each level goes back up. Past four levels the middle folds into a menu.",
391
+ "moreLevels": "Show hidden levels",
392
+ "deeper": "Go deeper",
393
+ "top": "Back to the top",
394
+ "levels": {
395
+ "catalogue": "Catalogue",
396
+ "beverages": "Beverages",
397
+ "juices": "Juices",
398
+ "brand": "Ramy",
399
+ "orange": "Orange 1L",
400
+ "pack": "Pack of 6"
401
+ }
402
+ },
403
+ "overlays": {
404
+ "sheet": "Bottom sheets",
405
+ "sheetNote": "Drag the handle, or content scrolled to its top: a fling or half the height dismisses.",
406
+ "openSheet": "Open a sheet",
407
+ "standard": "Standard sheet",
408
+ "standardNote": "Beside the content, not over it: peek, half and full. Drag anywhere on it until it is open, then the list scrolls; pull down from the list's top to bring it back.",
409
+ "showStandard": "Show the sheet",
410
+ "hideStandard": "Hide the sheet",
411
+ "nearby": "Nearby deliveries",
412
+ "stop": "Stop {n}",
413
+ "stopNote": "{minutes} min away",
414
+ "expandSheet": "Expand sheet",
415
+ "collapseSheet": "Collapse sheet",
416
+ "openActions": "Action sheet",
417
+ "sheetTitle": "Twelve rows",
418
+ "sheetText": "Scroll to the end, then pull down from the top to dismiss.",
419
+ "row": "Row {n}",
420
+ "done": "Done",
421
+ "actionsTitle": "Photo",
422
+ "actionsText": "Taken this morning",
423
+ "copy": "Copy",
424
+ "delete": "Delete",
425
+ "deleteNote": "Removed from every device",
426
+ "chose": "Chose {choice}",
427
+ "dialog": "Dialogs",
428
+ "dialogNote": "For decisions that must not be missed. A hero icon centres the headline.",
429
+ "openDialog": "Delete something",
430
+ "dialogTitle": "Delete this photo?",
431
+ "dialogText": "It is removed from every device signed in to this account.",
432
+ "cancel": "Cancel",
433
+ "deleted": "Deleted",
434
+ "kept": "Kept",
435
+ "menu": "Menus",
436
+ "menuNote": "Expressive menus in segments; the selected item takes the tertiary container, and Group by cascades into a submenu.",
437
+ "groupBy": "Group by",
438
+ "groups": {
439
+ "none": "None",
440
+ "customer": "Customer",
441
+ "status": "Status"
442
+ },
443
+ "sort": "Sort by",
444
+ "sortBy": "Sort: {order}",
445
+ "orders": {
446
+ "recent": "Most recent",
447
+ "name": "Name",
448
+ "amount": "Amount"
449
+ },
450
+ "reset": "Reset sorting",
451
+ "snackbar": "Snackbar",
452
+ "snackbarNote": "Brief feedback with one action; it waits while touched.",
453
+ "archive": "Archive",
454
+ "archived": "Conversation archived",
455
+ "undo": "Undo",
456
+ "restored": "Restored",
457
+ "side": "Side sheets and the modal rail",
458
+ "sideNote": "Filters slide in from the end edge; navigation from the start edge, closing itself once you choose.",
459
+ "openSide": "Filters",
460
+ "openRail": "Navigation",
461
+ "filters": "Filters",
462
+ "tooltips": "Tooltips",
463
+ "tooltipsNote": "Long-press the icon for its label; tap the text button for a rich tooltip.",
464
+ "richTitle": "Seed colour",
465
+ "richText": "Every colour in the app is generated from this one, in light and dark.",
466
+ "whatsThis": "What's this?",
467
+ "gotIt": "Got it",
468
+ "notification": "In-app notification",
469
+ "notificationNote": "Framework7's notification: drops in from the top, opens on tap, flies away when swiped sideways or up, and pauses while touched. Several stack, newest in front - tap the pill to spread them out.",
470
+ "notifyOrder": "New order",
471
+ "notifySync": "Sync done",
472
+ "ordersSource": "Orders",
473
+ "syncSource": "Sync",
474
+ "now": "now",
475
+ "orderTitle": "New order from Oran Market",
476
+ "orderText": "SO-1024 · 12 lines · 48,300 DA, to deliver tomorrow morning.",
477
+ "orderOpened": "Opened SO-1024",
478
+ "syncTitle": "Everything is up to date",
479
+ "fullscreen": "Full-screen dialog",
480
+ "fullscreenNote": "Framework7's popup for a task that needs the whole screen. Save waits for a name; closing with changes asks before discarding them. From 600dp it becomes a basic dialog.",
481
+ "newCustomer": "New customer",
482
+ "save": "Save",
483
+ "customerName": "Customer name",
484
+ "phone": "Phone",
485
+ "note": "Delivery note",
486
+ "discardTitle": "Discard this customer?",
487
+ "discardText": "What you typed will be lost.",
488
+ "discard": "Discard",
489
+ "keepEditing": "Keep editing",
490
+ "customerSaved": "Saved {name}",
491
+ "popover": "Popover",
492
+ "popoverNote": "Anchored to what opened it, grows out of it, closes on a tap outside, Escape or back.",
493
+ "cases": "{n} cases",
494
+ "quantity": "Quantity",
495
+ "quantityNote": "Pallet price from 24 cases.",
496
+ "draftRestored": "Your unsaved draft was restored.",
497
+ "notifyBurst": "Three at once",
498
+ "burstTitle": "New order from {shop}",
499
+ "burstText": "Synced from the field just now."
500
+ },
501
+ "selection": {
502
+ "stepper": "Stepper",
503
+ "stepperNote": "Framework7's stepper: hold a button to repeat - across a wide range it speeds up. Tap the value to type it; the arrow keys step.",
504
+ "guests": "Guests",
505
+ "weight": "Weight",
506
+ "units": "Units",
507
+ "kilos": "{value} kg",
508
+ "decrease": "Decrease",
509
+ "increase": "Increase",
510
+ "switches": "Switches",
511
+ "switchesNote": "The handle grows when on and travels on the fast spatial spring.",
512
+ "wifi": "Wi-Fi",
513
+ "bluetooth": "Bluetooth",
514
+ "airplane": "Airplane mode",
515
+ "locked": "Locked by policy",
516
+ "checks": "Checkboxes and radios",
517
+ "checksNote": "The check draws in; the radio dot springs.",
518
+ "terms": "Accept the terms",
519
+ "partial": "Some selected",
520
+ "required": "Required",
521
+ "cups": {
522
+ "small": "Small",
523
+ "medium": "Medium",
524
+ "large": "Large"
525
+ },
526
+ "sliders": "Sliders",
527
+ "slidersNote": "A slim handle splits the track; sizes XS to XL, with ticks and an inset icon.",
528
+ "volume": "Volume",
529
+ "steps": "Steps",
530
+ "brightness": "Brightness",
531
+ "chips": "Chips",
532
+ "chipsNote": "Filter chips toggle with a check; input chips can be removed.",
533
+ "filters": {
534
+ "open": "Open now",
535
+ "nearby": "Nearby",
536
+ "rated": "Top rated"
537
+ },
538
+ "addEvent": "Add to calendar",
539
+ "remove": "Remove",
540
+ "range": "Range slider",
541
+ "rangeNote": "Two handles; a press moves the nearer one. The price pair keeps 1,000 apart; the hours snap to ticks.",
542
+ "priceFrom": "Minimum price",
543
+ "priceTo": "Maximum price",
544
+ "opensAt": "Opens at",
545
+ "closesAt": "Closes at",
546
+ "smart": "Smart select",
547
+ "smartNote": "Framework7's smart select: a row naming the choice opens a sheet of options - several with check marks and Done, one with radio marks that closes on its own. Long lists get a search field.",
548
+ "deliveryDays": "Delivery days",
549
+ "none": "None",
550
+ "done": "Done",
551
+ "searchWilaya": "Search wilayas",
552
+ "days": {
553
+ "sat": "Saturday",
554
+ "sun": "Sunday",
555
+ "mon": "Monday",
556
+ "tue": "Tuesday",
557
+ "wed": "Wednesday",
558
+ "thu": "Thursday",
559
+ "fri": "Friday"
560
+ }
561
+ },
562
+ "inputs": {
563
+ "search": "Search bar",
564
+ "searchNote": "A 56dp pill on surface-container-high.",
565
+ "searchPlaceholder": "Search messages",
566
+ "clear": "Clear",
567
+ "voice": "Voice search",
568
+ "filled": "Filled fields",
569
+ "filledNote": "The label floats up; errors replace the supporting text.",
570
+ "name": "Full name",
571
+ "nameHint": "As it appears on the invoice",
572
+ "amount": "Amount",
573
+ "amountInvalid": "Enter a number with up to two decimals",
574
+ "outlined": "Outlined fields",
575
+ "outlinedNote": "For dense forms; the label cuts into the outline.",
576
+ "email": "Email",
577
+ "note": "Delivery note",
578
+ "searchView": "Search view",
579
+ "searchViewNote": "The bar opens into a full-screen view on one spring: recent searches first, then matches as you type. Back closes it.",
580
+ "searchCustomers": "Search customers",
581
+ "noMatches": "No customer matches",
582
+ "dropdown": "Exposed dropdown",
583
+ "dropdownNote": "A select, and Framework7's autocomplete: type to filter the 58 wilayas - accents and case do not matter - while focus stays in the field.",
584
+ "status": "Status",
585
+ "statuses": {
586
+ "draft": "Draft",
587
+ "confirmed": "Confirmed",
588
+ "delivered": "Delivered",
589
+ "cancelled": "Cancelled"
590
+ },
591
+ "wilaya": "Wilaya",
592
+ "wilayaHint": "Try \"bej\" or \"setif\"",
593
+ "results": "No results | {count} result | {count} results",
594
+ "richText": "Rich text",
595
+ "richTextNote": "Bold, lists and links for a visit report. What is stored is sanitised HTML: pasted scripts and styles never get in.",
596
+ "report": "Visit report",
597
+ "reportPlaceholder": "What happened on this visit",
598
+ "linkAddress": "Link address",
599
+ "apply": "Apply",
600
+ "removeLink": "Remove link",
601
+ "invalidLink": "Use a web, email or phone address",
602
+ "stored": "{n} characters of HTML stored",
603
+ "commands": {
604
+ "bold": "Bold",
605
+ "italic": "Italic",
606
+ "underline": "Underline",
607
+ "strikeThrough": "Strikethrough",
608
+ "bulleted": "Bulleted list",
609
+ "numbered": "Numbered list",
610
+ "link": "Link",
611
+ "clear": "Clear formatting"
612
+ },
613
+ "signature": "Signature",
614
+ "signatureNote": "Proof of delivery: ink that thickens when slow, kept as a draft, exported as a PNG. A typed name stands beside it for anyone who cannot sign on screen.",
615
+ "signatureLabel": "Customer signature",
616
+ "signHere": "Sign here",
617
+ "undo": "Undo",
618
+ "clearSignature": "Clear",
619
+ "receivedBy": "Received by",
620
+ "receivedByNote": "The name of the person who signed",
621
+ "confirmDelivery": "Confirm delivery",
622
+ "exported": "The exported signature",
623
+ "delivered": "Delivery confirmed by {name}",
624
+ "account": "Account details",
625
+ "accountNote": "Show the password, see how strong it is, and a phone number grouped as it is typed - whatever prefix you start with.",
626
+ "password": "Password",
627
+ "showPassword": "Show password",
628
+ "hidePassword": "Hide password",
629
+ "strength": {
630
+ "weak": "Weak",
631
+ "fair": "Fair",
632
+ "good": "Good",
633
+ "strong": "Strong"
634
+ },
635
+ "phone": "Mobile number",
636
+ "phoneHint": "Starts with 5, 6 or 7",
637
+ "phoneInvalid": "Not a mobile number",
638
+ "phoneShort": "Nine digits after +213",
639
+ "verification": "Verification code",
640
+ "verificationNote": "One real input under the cells: the SMS code from the keyboard, a pasted message or Arabic digits all fill it. The demo code is {code}.",
641
+ "codeLabel": "Verification code",
642
+ "codeSent": "Sent to +213 5 55 •• •• 56",
643
+ "codeWrong": "That code doesn't match",
644
+ "codeVerified": "Number verified",
645
+ "codeAgain": "Try again",
646
+ "resend": "Resend code",
647
+ "resendIn": "Resend in {s}s",
648
+ "codeResent": "A new code is on its way",
649
+ "tags": "Customer tags",
650
+ "tagsNote": "Type and press Enter or a comma, or paste a list. Backspace marks a tag before removing it; a duplicate flashes the one already there.",
651
+ "tagsLabel": "Tags",
652
+ "tagsPlaceholder": "Add a tag",
653
+ "tagsHint": "2 to 24 characters",
654
+ "removeTag": "Remove {tag}",
655
+ "suggested": "Suggested tags",
656
+ "suggestedTags": {
657
+ "nightDelivery": "Night delivery",
658
+ "pharmacy": "Pharmacy",
659
+ "cashOnly": "Cash only",
660
+ "keyAccount": "Key account"
661
+ }
662
+ },
663
+ "carousels": {
664
+ "multiBrowse": "Multi-browse",
665
+ "multiBrowseNote": "Large items with smaller ones peeking: each compresses toward the edge and its picture slides under the mask. A fling carries as far as it goes and snaps to an item.",
666
+ "hero": "Hero",
667
+ "heroNote": "One featured item between two small ones, centred once you leave the first. A fling moves one item.",
668
+ "featured": "Featured: {place}",
669
+ "uncontained": "Uncontained",
670
+ "uncontainedNote": "Fixed-width items that coast freely; only the one leaving the edge compresses.",
671
+ "slide": "{n} of {count}",
672
+ "places": {
673
+ "mountains": "Mountains",
674
+ "forest": "Forest",
675
+ "coast": "Coast",
676
+ "city": "City",
677
+ "harbour": "Harbour",
678
+ "trail": "Trail",
679
+ "park": "Park",
680
+ "cafe": "Café"
681
+ },
682
+ "photos": "Photo browser",
683
+ "photosNote": "Framework7's photo browser: swipe between photos, pinch or double-tap to zoom, pan when zoomed, swipe up or down to close. A tap hides the bar.",
684
+ "counter": "{position} of {count}",
685
+ "scenes": {
686
+ "mountains": "Mountains at dawn",
687
+ "coast": "The coast, portrait",
688
+ "dunes": "Dunes, panorama",
689
+ "city": "City skyline",
690
+ "forest": "Pine forest",
691
+ "harbour": "Harbour at dusk"
692
+ },
693
+ "lazy": "Lazy images",
694
+ "lazyNote": "Space reserved before loading, a placeholder colour, a fade once decoded, and a failure that keeps its description.",
695
+ "missing": "A photo that failed to load"
696
+ },
697
+ "surfaces": {
698
+ "cards": "Cards",
699
+ "cardsNote": "Elevated, filled and outlined; a whole card can be one target.",
700
+ "containerTransform": "Container transform",
701
+ "containerTransformNote": "A card that is the way into its page: tap one and it grows into it, colour and corners included; back shrinks the page into the same card.",
702
+ "cardText": "Tap to open",
703
+ "tapped": "Opened the {variant} card",
704
+ "segmented": "Segmented list",
705
+ "items": {
706
+ "inbox": {
707
+ "title": "Inbox",
708
+ "text": "12 unread"
709
+ },
710
+ "drafts": {
711
+ "title": "Drafts",
712
+ "text": "3 saved"
713
+ },
714
+ "archive": {
715
+ "title": "Archive",
716
+ "text": "Everything you put away"
717
+ }
718
+ },
719
+ "standard": "Standard list",
720
+ "wifi": "Wi-Fi",
721
+ "wifiText": "Connected to Office",
722
+ "storage": "Storage used",
723
+ "accordion": "Expandable items",
724
+ "accordionNote": "Framework7's accordion list: one item open at a time, stepping out of the run as its own card.",
725
+ "faq": {
726
+ "offline": {
727
+ "q": "Does it work offline?",
728
+ "a": "Yes. Every screen reads the database on the device, so a lost connection changes nothing you can see."
729
+ },
730
+ "sync": {
731
+ "q": "When does my data sync?",
732
+ "a": "This template has no server. Add one and it syncs into the local database; screens keep reading only the local copy."
733
+ },
734
+ "storage": {
735
+ "q": "Where is the database kept?",
736
+ "a": "In the app's private storage, through SQLite compiled to WebAssembly - the same engine in the browser and on the phone."
737
+ },
738
+ "export": {
739
+ "q": "Can I export my orders?",
740
+ "a": "Not yet in the template - a repository function over the orders table is all it takes."
741
+ }
742
+ },
743
+ "sortable": "Sortable list",
744
+ "sortableNote": "Framework7's sortable list: drag a handle, or long-press a stop and drag it. The others step aside and the page scrolls near its edges.",
745
+ "reorder": "Reorder",
746
+ "moved": "{label}, position {position} of {count}",
747
+ "stopOrder": "Stop {n}",
748
+ "stops": {
749
+ "warehouse": "Central warehouse",
750
+ "market": "Oran Market",
751
+ "pharmacy": "El Hayat pharmacy",
752
+ "school": "Ibn Khaldoun school",
753
+ "bakery": "Sidi El Houari bakery"
754
+ },
755
+ "timeline": "Timeline",
756
+ "tracking": "Tracking SO-1024",
757
+ "states": {
758
+ "done": "done",
759
+ "current": "in progress",
760
+ "upcoming": "to come"
761
+ },
762
+ "steps": {
763
+ "placed": {
764
+ "title": "Order placed",
765
+ "text": "Oran Market, 12 lines"
766
+ },
767
+ "confirmed": {
768
+ "title": "Confirmed",
769
+ "text": "Stock reserved at the central warehouse"
770
+ },
771
+ "picked": {
772
+ "title": "Picked and packed",
773
+ "text": "3 crates, 1 pallet"
774
+ },
775
+ "transit": {
776
+ "title": "Out for delivery",
777
+ "text": "Driver Karim, about 40 minutes away"
778
+ },
779
+ "delivered": {
780
+ "title": "Delivered",
781
+ "text": "Signature on delivery"
782
+ }
783
+ },
784
+ "infinite": "Infinite scroll",
785
+ "infiniteNote": "Framework7's infinite scroll: the next page loads as the end comes near. The third page fails once on purpose - retry it.",
786
+ "page": "Page {n}",
787
+ "loadingMore": "Loading more orders",
788
+ "loadFailed": "Could not load more orders",
789
+ "retry": "Retry",
790
+ "allLoaded": "That is every order"
791
+ },
792
+ "pickers": {
793
+ "modal": "Modal date picker",
794
+ "modalNote": "Calendar or typed input in your locale's order; nothing is kept until OK.",
795
+ "pick": "Pick a date",
796
+ "selectDate": "Select date",
797
+ "ok": "OK",
798
+ "typeDate": "Type a date",
799
+ "useCalendar": "Use the calendar",
800
+ "invalid": "Not a valid date",
801
+ "docked": "Docked calendar",
802
+ "dockedNote": "From today on, Sundays closed. Arrow keys, Page Up and Page Down move through it.",
803
+ "range": "Date range",
804
+ "rangeNote": "Tap a start, then an end; the days between take the band.",
805
+ "sheet": "Date picker in a sheet",
806
+ "sheetNote": "Framework7's way: from the bottom, within thumb reach. Switch between the calendar and the wheel.",
807
+ "useWheel": "Use the wheel",
808
+ "time": "Time picker",
809
+ "timeNote": "Dial or keyboard; the clock follows your language's 12 or 24 hours.",
810
+ "timeSheet": "Time picker in a sheet",
811
+ "timeSheetNote": "Dial or wheel, in quarter hours.",
812
+ "pickTime": "Pick a time",
813
+ "selectTime": "Select time",
814
+ "useDial": "Use the clock",
815
+ "useKeyboard": "Use the keyboard",
816
+ "hour": "Hour",
817
+ "minute": "Minute",
818
+ "period": "AM or PM",
819
+ "day": "Day",
820
+ "month": "Month",
821
+ "year": "Year",
822
+ "dateWheel": "Date wheel",
823
+ "dateWheelNote": "Inline, in your language's order. Spin to a shorter month and the day follows.",
824
+ "wheel": "Wheel picker",
825
+ "wheelNote": "Any values on drums - here a quantity and its unit.",
826
+ "quantity": "Quantity",
827
+ "unit": "Unit",
828
+ "units": {
829
+ "box": "boxes",
830
+ "pack": "packs",
831
+ "pallet": "pallets"
832
+ },
833
+ "selectedDate": "Selected date"
834
+ },
835
+ "scale": {
836
+ "refreshing": "Refreshing",
837
+ "virtual": "Virtual list",
838
+ "virtualNote": "{count} rows, only the visible ones in the DOM. Pull down from the top to refresh.",
839
+ "rendered": "{count} row rendered | {count} rows rendered",
840
+ "refreshed": "Refreshed {count}×",
841
+ "customer": "Customer",
842
+ "orders": "{count} order | {count} orders",
843
+ "updated": "Customers updated"
844
+ },
845
+ "tabs": {
846
+ "title": "Swipeable tabs",
847
+ "orders": "Orders",
848
+ "invoices": "Invoices",
849
+ "payments": "Payments",
850
+ "returns": "Returns",
851
+ "ordersNote": "Swipe between tabs anywhere on the page; swipe a row left to archive it - the row wins over the pager.",
852
+ "order": "SO-{n}",
853
+ "orderLines": "No lines | {count} line | {count} lines",
854
+ "archive": "Archive",
855
+ "invoice": "INV-{n}",
856
+ "amount": "{value} DA",
857
+ "paymentsNote": "A carousel inside a tab keeps its own sideways drag.",
858
+ "methods": {
859
+ "cash": "Cash",
860
+ "cheque": "Cheque",
861
+ "transfer": "Transfer",
862
+ "credit": "Credit"
863
+ },
864
+ "noReturns": "No returns",
865
+ "noReturnsText": "Returned goods show up here.",
866
+ "quickActions": "Quick actions",
867
+ "actions": {
868
+ "order": "New order",
869
+ "scan": "Scan a barcode",
870
+ "call": "Call the customer",
871
+ "map": "Open the route map",
872
+ "close": "Close"
873
+ }
874
+ },
875
+ "contacts": {
876
+ "title": "Customers A–Z",
877
+ "jump": "Jump to letter"
878
+ },
879
+ "tree": {
880
+ "title": "Treeview",
881
+ "note": "Framework7's treeview: the chevron opens a branch, a row selects. Dairy loads its products the first time it opens. Arrow keys walk the tree.",
882
+ "categories": "Product categories",
883
+ "permissions": "Permissions",
884
+ "products": "{count} products",
885
+ "loadsLater": "Loads when opened",
886
+ "nodes": {
887
+ "drinks": "Drinks",
888
+ "water": "Water",
889
+ "juice": "Juice",
890
+ "orange": "Orange juice",
891
+ "apple": "Apple juice",
892
+ "soda": "Soda",
893
+ "dairy": "Dairy",
894
+ "milk": "Milk",
895
+ "yoghurt": "Yoghurt",
896
+ "cheese": "Cheese",
897
+ "grocery": "Grocery",
898
+ "pasta": "Pasta",
899
+ "oil": "Oil",
900
+ "sales": "Sales",
901
+ "stock": "Stock",
902
+ "read": "View",
903
+ "create": "Create",
904
+ "cancel": "Cancel",
905
+ "adjust": "Adjust"
906
+ }
907
+ },
908
+ "tables": {
909
+ "orders": "Orders",
910
+ "ordersNote": "Tap a header for its menu: sort, group with a total per group, pin, hide. The layout is kept for next time.",
911
+ "dense": "Dense",
912
+ "selected": "None selected | {count} selected | {count} selected",
913
+ "selectAll": "Select every order",
914
+ "selectRow": "Select {ref}",
915
+ "opened": "Opened {ref}",
916
+ "total": "Total",
917
+ "ref": "Order",
918
+ "customer": "Customer",
919
+ "date": "Date",
920
+ "status": "Status",
921
+ "totalColumn": "Total",
922
+ "menu": {
923
+ "sortAscending": "Sort ascending",
924
+ "sortDescending": "Sort descending",
925
+ "clearSort": "Clear sort",
926
+ "groupBy": "Group by this column",
927
+ "ungroup": "Ungroup",
928
+ "pin": "Pin to start",
929
+ "unpin": "Unpin",
930
+ "hide": "Hide column",
931
+ "columns": "Columns"
932
+ },
933
+ "groupCount": "{count} order | {count} orders",
934
+ "selectGroup": "Select every {label} order",
935
+ "rowCount": "{count} rows"
936
+ },
937
+ "charts": {
938
+ "line": "Monthly sales",
939
+ "lineNote": "A line chart filled as an area: this year against last. Touch and slide along it to read both values; the gap is the months to come.",
940
+ "bar": "Sales by rep",
941
+ "barNote": "Grouped bars, or stacked. Touch a rep to read the numbers.",
942
+ "stacked": "Stacked",
943
+ "donut": "Sales by channel",
944
+ "donutNote": "Touch a segment or its legend entry to bring it to the centre.",
945
+ "total": "Total",
946
+ "thisYear": "2026",
947
+ "lastYear": "2025",
948
+ "august": "August",
949
+ "september": "September",
950
+ "channels": {
951
+ "shops": "Shops",
952
+ "wholesale": "Wholesale",
953
+ "online": "Online",
954
+ "export": "Export"
955
+ }
956
+ },
957
+ "featured": {
958
+ "glance": "At a glance",
959
+ "note": "This page grew out of the card you tapped. Go back, by the bar or the system gesture, and it shrinks into the card again.",
960
+ "range": {
961
+ "title": "Summer range",
962
+ "text": "Four new flavours across the 1L line",
963
+ "body": "The summer range reaches the shelves in June. Every route carries the four new flavours from the first week, and stores that stock the whole line get a display stand.",
964
+ "facts": {
965
+ "products": "Products",
966
+ "flavours": "New flavours",
967
+ "wilayas": "Wilayas"
968
+ }
969
+ },
970
+ "stores": {
971
+ "title": "New stores",
972
+ "text": "Seven openings on this week's routes",
973
+ "body": "Seven stores opened along existing routes. Each gets a first visit within the week, with the catalogue and an opening order.",
974
+ "facts": {
975
+ "opened": "Opened",
976
+ "visits": "Visits planned",
977
+ "orders": "First orders"
978
+ }
979
+ },
980
+ "route": {
981
+ "title": "Coast route",
982
+ "text": "Fourteen stops from Oran to Mostaganem",
983
+ "body": "The coast route leaves the Oran depot at seven and follows the shore east. Stops are ordered so the heaviest deliveries come first.",
984
+ "facts": {
985
+ "stops": "Stops",
986
+ "distance": "Kilometres",
987
+ "hours": "Hours on the road"
988
+ }
989
+ }
990
+ },
991
+ "chat": {
992
+ "title": "Route team",
993
+ "subtitle": "Amina, Karim and you",
994
+ "you": "You",
995
+ "compose": "Message",
996
+ "send": "Send",
997
+ "attach": "Attach",
998
+ "thumbsUp": "Add a thumbs up",
999
+ "photos": "Shared photos",
1000
+ "retry": "Tap to retry",
1001
+ "latest": "Jump to the latest message",
1002
+ "loadingOlder": "Loading earlier messages",
1003
+ "loadFailed": "Could not load earlier messages",
1004
+ "start": "This is the start of the conversation",
1005
+ "typing": "{name} is typing",
1006
+ "unread": "{count} new message | {count} new messages",
1007
+ "copy": "Copy text",
1008
+ "delete": "Delete for me",
1009
+ "copied": "Copied",
1010
+ "copyFailed": "Could not copy",
1011
+ "status": {
1012
+ "sending": "Sending",
1013
+ "sent": "Sent",
1014
+ "delivered": "Delivered",
1015
+ "read": "Read",
1016
+ "failed": "Not sent"
1017
+ },
1018
+ "lines": {
1019
+ "s1": "Reminder: the new prices apply from Sunday.",
1020
+ "s2": "Noted, I'll tell the shops on my route.",
1021
+ "s3": "How did Bab Ezzouar go?",
1022
+ "s4": "18 visits, 14 orders.",
1023
+ "s5": "Two shops were closed, I'll go back Thursday.",
1024
+ "s6": "Sunrise on the coast road, first visit at 7.",
1025
+ "s7": "Beautiful. Can you push the 1L range on that route next week?",
1026
+ "s8": "Yes, I'll add it to Tuesday's orders.",
1027
+ "s9": "Sending the updated price list now",
1028
+ "o1": "Stock count is due Friday.",
1029
+ "o2": "On it.",
1030
+ "o3": "I can cover the north route tomorrow.",
1031
+ "o4": "Thanks both, good week so far.",
1032
+ "o5": "See you at the depot at 8.",
1033
+ "r1": "👍",
1034
+ "r2": "Got it, thanks.",
1035
+ "r3": "Good work today 💪",
1036
+ "r4": "I'll pass by the depot later."
1037
+ },
1038
+ "attachTitle": "Send",
1039
+ "recent": "Recent photos",
1040
+ "sendPhoto": "Send {name}",
1041
+ "attachOptions": {
1042
+ "gallery": "Gallery",
1043
+ "camera": "Camera",
1044
+ "file": "File",
1045
+ "location": "Location",
1046
+ "contact": "Contact",
1047
+ "poll": "Poll",
1048
+ "event": "Event"
1049
+ },
1050
+ "attachFailed": "Couldn't read {name}",
1051
+ "react": "React",
1052
+ "messageActions": "Message actions",
1053
+ "reactionCount": "{emoji} from {count} person | {emoji} from {count} people",
1054
+ "reactionsTitle": "Reactions",
1055
+ "allReactions": "All",
1056
+ "removeReaction": "Tap to remove",
1057
+ "othersReacted": "{count} other | {count} others",
1058
+ "location": {
1059
+ "here": "Current location",
1060
+ "depot": "Oran depot",
1061
+ "sendDepot": "Send depot",
1062
+ "denied": "Location access is off",
1063
+ "unavailable": "Couldn't find your location",
1064
+ "timeout": "Finding your location took too long",
1065
+ "unsupported": "This device can't share its location"
1066
+ },
1067
+ "contact": {
1068
+ "title": "Share a contact",
1069
+ "search": "Search customers",
1070
+ "empty": "No customers yet",
1071
+ "failed": "Couldn't load customers"
1072
+ },
1073
+ "poll": {
1074
+ "title": "New poll",
1075
+ "question": "Question",
1076
+ "option": "Option {number}",
1077
+ "remove": "Remove option {number}",
1078
+ "add": "Add option",
1079
+ "repeated": "Already an option",
1080
+ "multiple": "Allow several answers",
1081
+ "multipleHint": "Everyone can pick more than one"
1082
+ },
1083
+ "invite": {
1084
+ "title": "New event",
1085
+ "name": "Event name",
1086
+ "date": "Date",
1087
+ "time": "Time",
1088
+ "place": "Place (optional)"
1089
+ },
1090
+ "cards": {
1091
+ "openLocation": "Open in maps",
1092
+ "openContact": "Show their orders",
1093
+ "pollSingle": "Choose one",
1094
+ "pollMultiple": "Choose any",
1095
+ "votes": "{count} vote | {count} votes",
1096
+ "going": "Going",
1097
+ "maybe": "Maybe",
1098
+ "no": "Can't go"
1099
+ }
1100
+ },
1101
+ "onboarding": {
1102
+ "title": "Welcome tour",
1103
+ "skip": "Skip",
1104
+ "next": "Next",
1105
+ "start": "Get started",
1106
+ "page": "Page {n}",
1107
+ "pages": {
1108
+ "route": {
1109
+ "title": "Your route, in order",
1110
+ "text": "Every visit of the day in the order you drive it, with what each shop ordered last time."
1111
+ },
1112
+ "orders": {
1113
+ "title": "Orders in seconds",
1114
+ "text": "Scan, adjust quantities, and the totals and promotions follow as you type."
1115
+ },
1116
+ "offline": {
1117
+ "title": "No signal, no problem",
1118
+ "text": "Everything is kept on the phone and goes out as soon as there is a connection."
1119
+ }
1120
+ }
1121
+ },
1122
+ "login": {
1123
+ "title": "Sign in",
1124
+ "heading": "Welcome back",
1125
+ "subtitle": "Sign in to see today's route.",
1126
+ "email": "Email",
1127
+ "password": "Password",
1128
+ "show": "Show password",
1129
+ "hide": "Hide password",
1130
+ "forgot": "Forgot password?",
1131
+ "forgotSent": "A reset link would be sent to your email",
1132
+ "signIn": "Sign in",
1133
+ "signingIn": "Signing in…",
1134
+ "emailInvalid": "Enter a valid email address",
1135
+ "passwordMissing": "Enter your password",
1136
+ "rejected": "Wrong email or password",
1137
+ "welcome": "Signed in as {email}",
1138
+ "restored": "Restored from your last visit",
1139
+ "hint": "Demo: any email, with the password demo."
1140
+ },
1141
+ "agenda": {
1142
+ "title": "Route agenda",
1143
+ "today": "Go to today",
1144
+ "days": "Days of the week",
1145
+ "visits": "{count} visit | {count} visits",
1146
+ "weekend": "No visits",
1147
+ "weekendText": "The weekend: the route starts again on Sunday.",
1148
+ "states": {
1149
+ "done": "Done",
1150
+ "next": "Next",
1151
+ "planned": "Planned"
1152
+ },
1153
+ "view": "Agenda view",
1154
+ "views": {
1155
+ "day": "Day",
1156
+ "week": "Week",
1157
+ "month": "Month"
1158
+ },
1159
+ "previousMonth": "Previous month",
1160
+ "nextMonth": "Next month",
1161
+ "chooseYear": "Choose year"
1162
+ }
1163
+ },
1164
+ "settings": {
1165
+ "about": "About",
1166
+ "appName": "Name",
1167
+ "version": "Version",
1168
+ "platform": "Platform",
1169
+ "storage": "Storage",
1170
+ "engine": "Database engine",
1171
+ "webview": "WebView",
1172
+ "notDurable": "Storage is not persisted",
1173
+ "title": "Settings",
1174
+ "appearance": "Appearance",
1175
+ "colors": "Colour studio",
1176
+ "darkMode": "Theme",
1177
+ "modeSystem": "System",
1178
+ "modeLight": "Light",
1179
+ "modeDark": "Dark",
1180
+ "motion": "Motion",
1181
+ "motionNote": "Reduced keeps fades and morphs, and drops travel and bounce.",
1182
+ "motionSystem": "System",
1183
+ "motionReduced": "Reduced",
1184
+ "motionFull": "Full",
1185
+ "general": "General",
1186
+ "language": "Language",
1187
+ "languages": {
1188
+ "en": "English",
1189
+ "fr": "Français",
1190
+ "ar-DZ": "العربية"
1191
+ },
1192
+ "unknown": "Unknown"
1193
+ },
1194
+ "studio": {
1195
+ "title": "Colour studio",
1196
+ "reset": "Reset colours",
1197
+ "resetDone": "Colours reset",
1198
+ "undo": "Undo",
1199
+ "seed": "Seed colour",
1200
+ "custom": "Custom seed",
1201
+ "customHint": "Any hex colour, like #6750a4",
1202
+ "customInvalid": "Use #rgb or #rrggbb",
1203
+ "pick": "Pick a colour",
1204
+ "variant": "Scheme variant",
1205
+ "spec2025": "Generated with the 2025 Expressive colour rules.",
1206
+ "spec2021": "This variant uses the 2021 colour rules - Material applies the 2025 rules to Tonal spot, Expressive, Vibrant and Neutral only.",
1207
+ "contrast": "Contrast",
1208
+ "contrastNote": "Higher contrast separates text from its surface for low vision and bright light.",
1209
+ "contrastStandard": "Standard",
1210
+ "contrastMedium": "Medium",
1211
+ "contrastHigh": "High",
1212
+ "roles": "Generated roles",
1213
+ "preview": "Preview",
1214
+ "previewTitle": "Afternoon delivery",
1215
+ "previewText": "12 stops, 8 done",
1216
+ "previewSwitch": "Notifications",
1217
+ "previewProgress": "Route progress",
1218
+ "previewChip": "Priority",
1219
+ "previewAssist": "Optimise",
1220
+ "previewPrimary": "Start",
1221
+ "previewTonal": "Details",
1222
+ "previewLoading": "Loading",
1223
+ "previewFab": "Add stop",
1224
+ "variants": {
1225
+ "tonalSpot": "Tonal spot",
1226
+ "expressive": "Expressive",
1227
+ "vibrant": "Vibrant",
1228
+ "brand": "Match brand",
1229
+ "neutral": "Neutral",
1230
+ "monochrome": "Monochrome",
1231
+ "fidelity": "Fidelity",
1232
+ "content": "Content",
1233
+ "rainbow": "Rainbow",
1234
+ "fruitSalad": "Fruit salad"
1235
+ },
1236
+ "presets": {
1237
+ "brand": "Brand",
1238
+ "red": "Red",
1239
+ "amber": "Amber",
1240
+ "green": "Green",
1241
+ "teal": "Teal",
1242
+ "blue": "Blue",
1243
+ "indigo": "Indigo",
1244
+ "violet": "Violet",
1245
+ "pink": "Pink",
1246
+ "slate": "Slate"
1247
+ },
1248
+ "hue": "Hue",
1249
+ "chroma": "Chroma",
1250
+ "tone": "Tone",
1251
+ "hex": "Hex",
1252
+ "pickNote": "Picked in HCT, the space Material builds schemes in: hue stays put while tone and chroma move.",
1253
+ "cancel": "Cancel",
1254
+ "apply": "Use this colour"
1255
+ },
1256
+ "errors": {
1257
+ "notFoundTitle": "Not found",
1258
+ "notFound": "That screen does not exist."
1259
+ }
1260
+ }