@mdn/fred 2.0.2 → 2.1.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 (186) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/components/about-tabs/element.css +3 -2
  3. package/components/scrim-inline/element.css +0 -7
  4. package/components/scrim-inline/global.css +10 -0
  5. package/components/social-image/README.md +16 -0
  6. package/components/social-image/sandbox.js +23 -0
  7. package/components/social-image/server.css +28 -0
  8. package/components/social-image/server.js +13 -0
  9. package/l10n/fluent.js +8 -7
  10. package/out/service-worker.js +1 -1
  11. package/out/service-worker.js.map +1 -1
  12. package/out/static/client/5183.ed3575d7370b617c.js +64 -0
  13. package/out/static/client/5183.ed3575d7370b617c.js.map +1 -0
  14. package/out/static/client/7047.7084b7bcf9a47b7b.js +9 -0
  15. package/out/static/client/7047.7084b7bcf9a47b7b.js.map +1 -0
  16. package/out/static/client/{8292.88217634072b2959.js → 8292.5a4929a466c7b3ca.js} +2 -2
  17. package/out/static/client/{8292.88217634072b2959.js.map → 8292.5a4929a466c7b3ca.js.map} +1 -1
  18. package/out/static/client/{index.a7f592ef6e4f2a0e.js → index.0e1f202766cdb426.js} +3 -3
  19. package/out/static/client/{index.a7f592ef6e4f2a0e.js.map → index.0e1f202766cdb426.js.map} +1 -1
  20. package/out/static/client/{runtime.14f0bbf7912ff6c2.js → runtime.076e84c93222dfd0.js} +2 -2
  21. package/out/static/client/{runtime.14f0bbf7912ff6c2.js.map → runtime.076e84c93222dfd0.js.map} +1 -1
  22. package/out/static/client/stats.json +319 -283
  23. package/out/static/client/styles-a11y-menu.bf24a870a8a4969f.js +1 -0
  24. package/out/static/client/styles-advertising.9f2b7bddc08575fc.js +1 -0
  25. package/out/static/client/styles-article-footer.aa9f8d240980b0f4.js +1 -0
  26. package/out/static/client/styles-banner.e738836bac789a8b.js +1 -0
  27. package/out/static/client/styles-baseline-indicator.c062716f3d033dd8.js +1 -0
  28. package/out/static/client/styles-blog-index.818261c8123bc042.js +1 -0
  29. package/out/static/client/styles-blog-post.96ce1680245bbc86.js +1 -0
  30. package/out/static/client/styles-breadcrumbs-bar.ed7d1440bdccf98f.js +1 -0
  31. package/out/static/client/styles-breadcrumbs.7599a269dc584d75.js +1 -0
  32. package/out/static/client/styles-button.de6a7b9b7548d84b.js +1 -0
  33. package/out/static/client/styles-content-section.a8bd7fde04898354.js +1 -0
  34. package/out/static/client/styles-contributor-spotlight.adad2e813e1667fe.js +1 -0
  35. package/out/static/client/styles-curriculum-about.eefa128bb415258c.js +1 -0
  36. package/out/static/client/styles-curriculum-default.a2692218d2b1a1f9.js +1 -0
  37. package/out/static/client/styles-curriculum-landing.2d51b8fce8f12b8d.js +1 -0
  38. package/out/static/client/styles-curriculum-module.f4ae8920ee1c92ff.js +1 -0
  39. package/out/static/client/styles-curriculum-overview.2d7c17b0f0b9bd92.js +1 -0
  40. package/out/static/client/styles-featured-articles.c54e8f6b90567441.js +1 -0
  41. package/out/static/client/styles-footer.cff8d2b7669e06a9.js +1 -0
  42. package/out/static/client/styles-generic-about.b31b672a5d394108.js +1 -0
  43. package/out/static/client/styles-generic-community.f7e5df670c7aeaf3.js +1 -0
  44. package/out/static/client/styles-generic-content.1a9e4b87d8a12a85.js +1 -0
  45. package/out/static/client/styles-generic-layout.76e37948146a2f39.js +1 -0
  46. package/out/static/client/styles-generic-sidebar.c07d266d1382c357.js +1 -0
  47. package/out/static/client/styles-generic-toc.342bb77a42e3cc84.js +1 -0
  48. package/out/static/client/{styles-global.e813b635d036a38b.css → styles-global.63980d9c69df1f6a.css} +2 -2
  49. package/out/static/client/{styles-global.e813b635d036a38b.css.map → styles-global.63980d9c69df1f6a.css.map} +1 -1
  50. package/out/static/client/styles-global.c2e6118d3b833b4a.js +1 -0
  51. package/out/static/client/styles-heading-anchor.79390408a0c88875.js +1 -0
  52. package/out/static/client/styles-homepage-body.20c015a218d0bc96.js +1 -0
  53. package/out/static/client/styles-homepage-contributor-spotlight.21f37f11b3bd4bda.js +1 -0
  54. package/out/static/client/styles-homepage-footer.24e66b627b59d99f.js +1 -0
  55. package/out/static/client/styles-homepage-header.1a75fa94f8bab5a0.js +1 -0
  56. package/out/static/client/styles-homepage-hero.f1bf55f1be2d516d.js +1 -0
  57. package/out/static/client/styles-homepage.cd5bf6213bc06b4e.js +1 -0
  58. package/out/static/client/styles-latest-news.0f32a584ef1ed171.js +1 -0
  59. package/out/static/client/styles-left-sidebar.d7d52289da7ba969.js +1 -0
  60. package/out/static/client/styles-logo.1ff82941fc133017.js +1 -0
  61. package/out/static/client/styles-mandala.2a99de27a8c19d02.js +1 -0
  62. package/out/static/client/styles-menu.13c3394ada0512ef.js +1 -0
  63. package/out/static/client/styles-navigation.f857f577084aa7ef.js +1 -0
  64. package/out/static/client/styles-not-found.0bdc6a72643ebe34.js +1 -0
  65. package/out/static/client/styles-observatory-landing.e709efc8103ee08c.js +1 -0
  66. package/out/static/client/styles-observatory-results.e098740504c0c0f0.js +1 -0
  67. package/out/static/client/styles-page-layout.2ab75fc5b95edf1b.js +1 -0
  68. package/out/static/client/styles-pagination.667a2af3eaebe782.js +1 -0
  69. package/out/static/client/styles-playground.c1339745dabdf1f6.js +1 -0
  70. package/out/static/client/styles-recent-contributions.706333df420f227c.js +1 -0
  71. package/out/static/client/styles-reference-layout.6eaaea648e7e4dce.js +1 -0
  72. package/out/static/client/styles-reference-toc.dcb67aadb5032e3f.js +1 -0
  73. package/out/static/client/styles-sandbox.c14203f7b76d9e70.js +1 -0
  74. package/out/static/client/styles-site-search.ba674569591c3348.js +1 -0
  75. package/out/static/client/styles-social-image.47d082e57762bfb4.css +2 -0
  76. package/out/static/client/styles-social-image.47d082e57762bfb4.css.map +1 -0
  77. package/out/static/client/styles-social-image.f457942a12584899.js +1 -0
  78. package/out/static/client/styles-translation-banner.c0bf41a60bc2fe87.js +1 -0
  79. package/out/static/client/styles-writer-toolbar.e7438b6d8e7c99f4.js +1 -0
  80. package/out/static/client/{styles.519e2a3b2b0392d7.js → styles.cbf2ca4b84823096.js} +2 -2
  81. package/out/static/client/{styles.519e2a3b2b0392d7.js.map → styles.cbf2ca4b84823096.js.map} +1 -1
  82. package/out/static/legacy/{145.f57152daa80bc354.js → 145.e71ec0c1d16bfeb6.js} +2 -2
  83. package/out/static/legacy/{145.f57152daa80bc354.js.map → 145.e71ec0c1d16bfeb6.js.map} +1 -1
  84. package/out/static/legacy/{2439.db04dec0f2bfe008.js → 2439.152ddc8eff5390cc.js} +2 -2
  85. package/out/static/legacy/{2439.db04dec0f2bfe008.js.map → 2439.152ddc8eff5390cc.js.map} +1 -1
  86. package/out/static/legacy/{2569.2ed6f988d52f6cb2.js → 2569.41b52dfae9ff5dbd.js} +2 -2
  87. package/out/static/legacy/{2569.2ed6f988d52f6cb2.js.map → 2569.41b52dfae9ff5dbd.js.map} +1 -1
  88. package/out/static/legacy/{3097.5ee3eace96d8c3ea.js → 3097.89f8c27a39d2d759.js} +2 -2
  89. package/out/static/legacy/{3097.5ee3eace96d8c3ea.js.map → 3097.89f8c27a39d2d759.js.map} +1 -1
  90. package/out/static/legacy/{4624.5f395686fe61b4a3.js → 4624.831090754998070f.js} +2 -2
  91. package/out/static/legacy/{4624.5f395686fe61b4a3.js.map → 4624.831090754998070f.js.map} +1 -1
  92. package/out/static/legacy/{4944.dff54c3109113729.js → 4944.d5de2520acb6bc03.js} +2 -2
  93. package/out/static/legacy/{4944.dff54c3109113729.js.map → 4944.d5de2520acb6bc03.js.map} +1 -1
  94. package/out/static/legacy/{4968.12b8af0a52d054ac.js → 4968.c5c0429688b49438.js} +2 -2
  95. package/out/static/legacy/{4968.12b8af0a52d054ac.js.map → 4968.c5c0429688b49438.js.map} +1 -1
  96. package/out/static/legacy/{652.702c9f7893508b7f.js → 652.984bbafca5a127d6.js} +2 -2
  97. package/out/static/legacy/{652.702c9f7893508b7f.js.map → 652.984bbafca5a127d6.js.map} +1 -1
  98. package/out/static/legacy/{6542.8f8dc41c1b7b4f3d.js → 6542.9ae1d636a2097c7a.js} +2 -2
  99. package/out/static/legacy/{6542.8f8dc41c1b7b4f3d.js.map → 6542.9ae1d636a2097c7a.js.map} +1 -1
  100. package/out/static/legacy/{6786.d37ed4aa6d7a5c1a.js → 6786.c180a40232e02d98.js} +3 -3
  101. package/out/static/legacy/{6786.d37ed4aa6d7a5c1a.js.map → 6786.c180a40232e02d98.js.map} +1 -1
  102. package/out/static/legacy/{8292.88217634072b2959.js → 8292.5a4929a466c7b3ca.js} +2 -2
  103. package/out/static/legacy/{8292.88217634072b2959.js.map → 8292.5a4929a466c7b3ca.js.map} +1 -1
  104. package/out/static/legacy/{8315.525575601119f224.js → 8315.732f4f8af2f04044.js} +2 -2
  105. package/out/static/legacy/{8315.525575601119f224.js.map → 8315.732f4f8af2f04044.js.map} +1 -1
  106. package/out/static/legacy/{8769.d63b4369d16f3391.js → 8769.c0eb10a75d355ed3.js} +2 -2
  107. package/out/static/legacy/{8769.d63b4369d16f3391.js.map → 8769.c0eb10a75d355ed3.js.map} +1 -1
  108. package/out/static/legacy/{9380.d18451f1d350375d.js → 9380.2e09c0a94dc10112.js} +2 -2
  109. package/out/static/legacy/{9380.d18451f1d350375d.js.map → 9380.2e09c0a94dc10112.js.map} +1 -1
  110. package/out/static/legacy/asset-manifest.json +20 -20
  111. package/out/static/legacy/{index.0b85877f879160b2.js → index.5e65b9f52e86ad40.js} +5 -5
  112. package/out/static/legacy/{index.0b85877f879160b2.js.LICENSE.txt → index.5e65b9f52e86ad40.js.LICENSE.txt} +1 -1
  113. package/out/static/legacy/{index.0b85877f879160b2.js.map → index.5e65b9f52e86ad40.js.map} +1 -1
  114. package/out/static/legacy/{index.645247acbde1c666.html → index.6838304b64f32836.html} +1 -1
  115. package/out/static/legacy/stats.json +14 -14
  116. package/out/static/legacy/{yari.46e28128e98126d7.js → yari.c8f274d3a31b194e.js} +6 -6
  117. package/out/static/legacy/{yari.46e28128e98126d7.js.LICENSE.txt → yari.c8f274d3a31b194e.js.LICENSE.txt} +1 -1
  118. package/out/static/legacy/{yari.46e28128e98126d7.js.map → yari.c8f274d3a31b194e.js.map} +1 -1
  119. package/out/static/ssr/8292.js +1 -1
  120. package/out/static/ssr/8292.js.map +1 -1
  121. package/out/static/ssr/index.js +149 -142
  122. package/out/static/ssr/index.js.map +1 -1
  123. package/out/static/ssr/stats.json +4 -4
  124. package/out/twitter-card-summary.46ac2375.png +0 -0
  125. package/package.json +16 -15
  126. package/public/twitter-card-summary.46ac2375.png +0 -0
  127. package/server.js +12 -1
  128. package/out/static/client/5183.e4104aeffa888fd3.js +0 -64
  129. package/out/static/client/5183.e4104aeffa888fd3.js.map +0 -1
  130. package/out/static/client/7047.5a3c9165bf33e8ef.js +0 -9
  131. package/out/static/client/7047.5a3c9165bf33e8ef.js.map +0 -1
  132. package/out/static/client/styles-a11y-menu.49f604eb400e3a1b.js +0 -1
  133. package/out/static/client/styles-advertising.206d401ac1918107.js +0 -1
  134. package/out/static/client/styles-article-footer.bf7a12a8f26de9d8.js +0 -1
  135. package/out/static/client/styles-banner.045fd9429c0b4559.js +0 -1
  136. package/out/static/client/styles-baseline-indicator.1a9a989c5eed2bd0.js +0 -1
  137. package/out/static/client/styles-blog-index.07075fbe70ea701a.js +0 -1
  138. package/out/static/client/styles-blog-post.f096d7b72acc54c7.js +0 -1
  139. package/out/static/client/styles-breadcrumbs-bar.b6d2903779905507.js +0 -1
  140. package/out/static/client/styles-breadcrumbs.7b6a3fca16762395.js +0 -1
  141. package/out/static/client/styles-button.68557b262acc04d5.js +0 -1
  142. package/out/static/client/styles-content-section.8b58198fcbb512cd.js +0 -1
  143. package/out/static/client/styles-contributor-spotlight.65897b7d1c3de5e6.js +0 -1
  144. package/out/static/client/styles-curriculum-about.013603624423e8b7.js +0 -1
  145. package/out/static/client/styles-curriculum-default.8d3cc74e416d99c0.js +0 -1
  146. package/out/static/client/styles-curriculum-landing.95ce2c9c6203fda2.js +0 -1
  147. package/out/static/client/styles-curriculum-module.6bd730e94b6ab4b0.js +0 -1
  148. package/out/static/client/styles-curriculum-overview.31fd536067fb14e7.js +0 -1
  149. package/out/static/client/styles-featured-articles.122a3779cde55236.js +0 -1
  150. package/out/static/client/styles-footer.fedc4476f04ebc15.js +0 -1
  151. package/out/static/client/styles-generic-about.7e63ff8a4b7851ef.js +0 -1
  152. package/out/static/client/styles-generic-community.dae09a544431e63d.js +0 -1
  153. package/out/static/client/styles-generic-content.16d08aa39ea401b9.js +0 -1
  154. package/out/static/client/styles-generic-layout.3e4f2f4951ea186b.js +0 -1
  155. package/out/static/client/styles-generic-sidebar.b2e094fc3c0756ab.js +0 -1
  156. package/out/static/client/styles-generic-toc.cd70dab26a1241d4.js +0 -1
  157. package/out/static/client/styles-global.339e7f9a94da6256.js +0 -1
  158. package/out/static/client/styles-heading-anchor.0deb48e0e151aba3.js +0 -1
  159. package/out/static/client/styles-homepage-body.cb1b213bec93efdd.js +0 -1
  160. package/out/static/client/styles-homepage-contributor-spotlight.1a2acbf06be6d425.js +0 -1
  161. package/out/static/client/styles-homepage-footer.3435c9576666f4a5.js +0 -1
  162. package/out/static/client/styles-homepage-header.6a6b4ebaf675e721.js +0 -1
  163. package/out/static/client/styles-homepage-hero.de64115a608af810.js +0 -1
  164. package/out/static/client/styles-homepage.09583f85e229d2de.js +0 -1
  165. package/out/static/client/styles-latest-news.d7d8beb1f187d6f5.js +0 -1
  166. package/out/static/client/styles-left-sidebar.62e4bdb34c86bc43.js +0 -1
  167. package/out/static/client/styles-logo.15608a14aefd9e51.js +0 -1
  168. package/out/static/client/styles-mandala.18c6e16ec318e10a.js +0 -1
  169. package/out/static/client/styles-menu.8011e6627accb1f3.js +0 -1
  170. package/out/static/client/styles-navigation.507be0a6a4278751.js +0 -1
  171. package/out/static/client/styles-not-found.5abe16a37f65b63a.js +0 -1
  172. package/out/static/client/styles-observatory-landing.2bda92fc6d68c4fc.js +0 -1
  173. package/out/static/client/styles-observatory-results.090bb92b82d036eb.js +0 -1
  174. package/out/static/client/styles-page-layout.ca4cbe58578a57eb.js +0 -1
  175. package/out/static/client/styles-pagination.cacd3f49e3de0552.js +0 -1
  176. package/out/static/client/styles-playground.1c172c9a3a8d9b79.js +0 -1
  177. package/out/static/client/styles-recent-contributions.45d4f26778c7ba5b.js +0 -1
  178. package/out/static/client/styles-reference-layout.d26c1e2e7b6dcf90.js +0 -1
  179. package/out/static/client/styles-reference-toc.bb1b05755fbc1108.js +0 -1
  180. package/out/static/client/styles-sandbox.a14cc003eeaa8914.js +0 -1
  181. package/out/static/client/styles-site-search.76d1310c8fe1b8fb.js +0 -1
  182. package/out/static/client/styles-translation-banner.c9804ae977f28550.js +0 -1
  183. package/out/static/client/styles-writer-toolbar.e88f55bfa22d6f0e.js +0 -1
  184. /package/out/static/client/{5183.e4104aeffa888fd3.js.LICENSE.txt → 5183.ed3575d7370b617c.js.LICENSE.txt} +0 -0
  185. /package/out/static/client/{index.a7f592ef6e4f2a0e.js.LICENSE.txt → index.0e1f202766cdb426.js.LICENSE.txt} +0 -0
  186. /package/out/static/legacy/{6786.d37ed4aa6d7a5c1a.js.LICENSE.txt → 6786.c180a40232e02d98.js.LICENSE.txt} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"145.f57152daa80bc354.js","sources":["webpack://@mdn/fred/./node_modules/@mdn/yari/client/src/translations/differences/index.tsx","webpack://@mdn/fred/./node_modules/@mdn/yari/client/src/translations/missing/index.tsx","webpack://@mdn/fred/./node_modules/@mdn/yari/client/src/translations/dashboard/index.tsx","webpack://@mdn/fred/./node_modules/@mdn/yari/client/src/translations/index.tsx","webpack://@mdn/fred/./node_modules/@mdn/yari/client/src/ui/molecules/paginator/index.tsx"],"sourcesContent":["import React from \"react\";\nimport {\n createSearchParams,\n Link,\n useSearchParams,\n useNavigate,\n} from \"react-router-dom\";\nimport useSWR from \"swr\";\nimport dayjs from \"dayjs\";\nimport relativeTime from \"dayjs/plugin/relativeTime\";\n\nimport \"./index.scss\";\n\nimport { MainContentContainer } from \"../../ui/atoms/page-content\";\nimport { Paginator } from \"../../ui/molecules/paginator\";\nimport { useLocale } from \"../../hooks\";\n\ndayjs.extend(relativeTime);\n\ninterface DocumentPopularity {\n value: number;\n ranking: number;\n parentValue: number;\n parentRanking: number;\n}\n\ntype CountByType = { [key: string]: number };\n\ninterface DocumentDifferences {\n countByType: CountByType;\n total: number;\n}\n\ninterface DocumentEdits {\n modified: string;\n parentModified: string;\n commitURL: string;\n parentCommitURL: string;\n sourceCommitsBehindCount?: number;\n sourceCommitURL?: string;\n}\n\ninterface Document {\n mdn_url: string;\n edits: DocumentEdits;\n title: string;\n popularity: DocumentPopularity;\n differences: DocumentDifferences;\n}\n\ninterface Counts {\n found: number;\n total: number;\n pages: number;\n noParents: number;\n cacheMisses: number;\n}\n\ninterface Times {\n took: number;\n}\n\ninterface FlawLevel {\n name: string;\n level: string;\n ignored: boolean;\n}\n\ninterface Data {\n counts: Counts;\n documents: Document[];\n times: Times;\n flawLevels: FlawLevel[];\n}\n\ninterface LocaleStorageData {\n lastLoadTime?: number;\n defaultSort?: string;\n defaultSortReverse?: string;\n}\n\ninterface StorageData {\n [locale: string]: LocaleStorageData;\n}\n\nconst LOCALSTORAGE_KEY = \"translations-dashboard-differences\";\n\nfunction saveStorage(locale: string, data: LocaleStorageData) {\n try {\n const stored = JSON.parse(\n localStorage.getItem(LOCALSTORAGE_KEY) || \"{}\"\n ) as StorageData;\n stored[locale] = Object.assign({}, stored[locale] || {}, data);\n localStorage.setItem(LOCALSTORAGE_KEY, JSON.stringify(stored));\n } catch (err) {\n console.warn(\"Unable to save to localStorage\", err);\n }\n}\n\nfunction getStorage(locale: string): LocaleStorageData | null {\n try {\n const stored = JSON.parse(localStorage.getItem(LOCALSTORAGE_KEY) || \"{}\");\n if (stored) {\n return stored[locale] as LocaleStorageData;\n }\n } catch (err) {\n console.warn(\"Unable to retrieve from localStorage\", err);\n }\n return null;\n}\n\nexport function TranslationDifferences() {\n const locale = useLocale();\n const [searchParams] = useSearchParams();\n const navigate = useNavigate();\n\n const [lastData, setLastData] = React.useState<Data | null>(null);\n\n React.useEffect(() => {\n if (locale.toLowerCase() === \"en-us\") {\n navigate(`/${locale}/_translations`);\n }\n }, [locale, navigate]);\n\n React.useEffect(() => {\n let title = \"All translations\";\n if (locale.toLowerCase() !== \"en-us\") {\n title += ` for ${locale}`;\n }\n if (lastData) {\n title = `(${lastData.counts.found.toLocaleString()} found) ${title}`;\n }\n document.title = title;\n }, [lastData, locale]);\n\n const { data, error, isValidating } = useSWR<Data, Error>(\n locale.toLowerCase() !== \"en-us\"\n ? `/_translations/differences/?locale=${locale}`\n : null,\n async (url) => {\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`${response.status} (${await response.text()})`);\n }\n if (\n !(response.headers.get(\"content-type\") || \"\").includes(\n \"application/json\"\n )\n ) {\n throw new Error(\n `Response is not JSON (${response.headers.get(\"content-type\")})`\n );\n }\n return response.json();\n },\n {\n revalidateOnFocus: false,\n }\n );\n\n // Use this to be able to figure out how long the XHR takes when there's no cache\n const startTime = React.useRef<Date>();\n React.useEffect(() => {\n if (locale) {\n if (!data) {\n startTime.current = new Date();\n } else {\n if (\n data.counts.cacheMisses > 0 &&\n data.counts.cacheMisses === data.counts.total &&\n startTime.current\n ) {\n const lastLoadTime =\n new Date().getTime() - startTime.current.getTime();\n saveStorage(locale, { lastLoadTime });\n }\n }\n }\n }, [locale, data]);\n\n React.useEffect(() => {\n if (data) {\n setLastData(data);\n }\n }, [data]);\n\n const lastStorageData = getStorage(locale);\n const defaultSort = lastStorageData?.defaultSort || \"modified\";\n const defaultSortReverse = lastStorageData?.defaultSortReverse || \"false\";\n const sort = searchParams.get(\"sort\") || defaultSort;\n const sortReverse = JSON.parse(\n searchParams.get(\"sortReverse\") || defaultSortReverse\n );\n\n React.useEffect(() => {\n saveStorage(\n locale,\n Object.assign({}, lastStorageData, {\n defaultSort: sort,\n defaultSortReverse: sortReverse,\n })\n );\n }, [locale, sort, sortReverse, lastStorageData]);\n\n if (locale.toLowerCase() === \"en-us\") {\n return null;\n }\n\n return (\n <Container>\n {lastData && !error && isValidating && (\n <p style={{ float: \"right\" }}>Reloading...</p>\n )}\n {!data && !error && !lastData && (\n <Loading\n estimate={\n (lastStorageData && lastStorageData.lastLoadTime) || 30 * 1000\n }\n />\n )}\n {lastData && (\n <p style={{ textAlign: \"right\" }}>\n Go to{\" \"}\n <Link to={`/${locale}/_translations/missing`}>\n Missing translations for <b>{locale}</b>\n </Link>\n </p>\n )}\n {error && <ShowSearchError error={error} />}\n {lastData && (\n <div className=\"filter-documents\">\n <FilterControls />\n <DocumentsTable\n locale={locale}\n counts={lastData.counts}\n documents={lastData.documents}\n sort={sort}\n sortReverse={sortReverse}\n />\n </div>\n )}\n {data && <BuildTimes times={data.times} />}\n </Container>\n );\n}\n\nfunction Container({ children }: { children: React.ReactNode }) {\n return (\n <MainContentContainer className=\"all-translations\" standalone={true}>\n {children}\n </MainContentContainer>\n );\n}\n\nfunction ShowSearchError({ error }) {\n return (\n <div className=\"error-message search-error\">\n <h3>Search error</h3>\n <pre>{error.toString()}</pre>\n </div>\n );\n}\n\nfunction BuildTimes({ times }: { times: Times }) {\n function format(ms: number) {\n if (ms > 1000) {\n const s = ms / 1000;\n return `${s.toFixed(1)} seconds`;\n } else {\n return `${Math.trunc(ms)} milliseconds`;\n }\n }\n return (\n <div className=\"search-times\">\n <p>Time to find all documents {format(times.took)}</p>\n </div>\n );\n}\n\nfunction Loading({ estimate }: { estimate: number }) {\n const startLoadingTime = new Date();\n const [estimateEndTime] = React.useState(\n new Date(startLoadingTime.getTime() + estimate)\n );\n\n const [, setIncrements] = React.useState(0);\n React.useEffect(() => {\n const interval = setInterval(() => {\n setIncrements((state) => state + 1);\n }, 1000);\n return () => clearInterval(interval);\n }, []);\n\n const distance = estimateEndTime.getTime() - startLoadingTime.getTime();\n const elapsed = new Date().getTime() - startLoadingTime.getTime();\n const percent = (100 * elapsed) / distance;\n return (\n <div className=\"loading\">\n <progress id=\"progress\" max=\"100\" value={percent} style={{ margin: 20 }}>\n {percent}%\n </progress>\n <br />\n <small>\n Estimated time to finish: {((distance - elapsed) / 1000).toFixed(0)}s{\" \"}\n {elapsed > distance ? (\n <span aria-label=\"weird\" role=\"img\">\n 🙃\n </span>\n ) : null}\n </small>\n </div>\n );\n}\n\nfunction FilterControls() {\n const [searchParams, setSearchParams] = useSearchParams();\n const [title, setTitle] = React.useState(searchParams.get(\"title\") || \"\");\n const [url, setURL] = React.useState(searchParams.get(\"url\") || \"\");\n const [differences, setDifferences] = React.useState(\n searchParams.get(\"differences\") || \"\"\n );\n\n function refreshFilters(reset = false) {\n const filterParams = createSearchParams(searchParams);\n for (const [key, value] of [\n [\"url\", url],\n [\"title\", title],\n [\"differences\", differences],\n ]) {\n if (!reset && value) {\n filterParams.set(key, value);\n } else {\n filterParams.delete(key);\n }\n }\n filterParams.delete(\"page\");\n setSearchParams(filterParams);\n }\n\n function resetFilters() {\n setURL(\"\");\n setTitle(\"\");\n setDifferences(\"\");\n refreshFilters(true);\n }\n\n return (\n <div className=\"filters\">\n <h3>Filters</h3>\n <form\n onSubmit={(event) => {\n event.preventDefault();\n refreshFilters();\n }}\n >\n <div>\n <h4>Document</h4>\n <input\n type=\"search\"\n placeholder=\"Filter by document URI\"\n value={url}\n onChange={(event) => {\n setURL(event.target.value);\n }}\n onBlur={() => refreshFilters()}\n />\n <input\n type=\"search\"\n placeholder=\"Filter by document title\"\n value={title}\n onChange={(event) => {\n setTitle(event.target.value);\n }}\n onBlur={() => refreshFilters()}\n />\n </div>\n <div>\n <h4>Differences</h4>\n <input\n type=\"text\"\n placeholder=\"E.g. >0 or >=5\"\n value={differences}\n onChange={(event) => {\n setDifferences(event.target.value);\n }}\n onBlur={() => refreshFilters()}\n />\n </div>\n\n <div>\n <h4>&nbsp;</h4>\n <button type=\"submit\">Filter now</button>{\" \"}\n {(url || title) && (\n <button type=\"button\" onClick={resetFilters}>\n Reset filters\n </button>\n )}\n </div>\n </form>\n </div>\n );\n}\ntype NumericOperation = {\n operation: \"eq\" | \"gt\" | \"gte\" | \"lt\" | \"lte\";\n value: number;\n};\n\nfunction getNumericOperation(expression: string): NumericOperation | null {\n function parseIntOrThrow(v: string) {\n if (!v) {\n throw new Error(\"Can't be empty\");\n }\n\n const parsed = parseInt(v, 10);\n if (isNaN(parsed)) {\n throw new Error(`'${v}' not a valid number`);\n }\n return parsed;\n }\n try {\n if (expression.startsWith(\">=\")) {\n return {\n operation: \"gte\",\n value: parseIntOrThrow(expression.replace(\">=\", \"\")),\n };\n } else if (expression.startsWith(\">\")) {\n return {\n operation: \"gt\",\n value: parseIntOrThrow(expression.replace(\">\", \"\")),\n };\n } else if (expression.startsWith(\"<=\")) {\n return {\n operation: \"lte\",\n value: parseIntOrThrow(expression.replace(\"<=\", \"\")),\n };\n } else if (expression.startsWith(\"<\")) {\n return {\n operation: \"lt\",\n value: parseIntOrThrow(expression.replace(\"<\", \"\")),\n };\n } else if (expression.startsWith(\"==\") || expression.startsWith(\"=\")) {\n return {\n operation: \"eq\",\n value: parseIntOrThrow(expression.replace(/=/g, \"\")),\n };\n } else if (expression) {\n return {\n operation: \"eq\",\n value: parseIntOrThrow(expression),\n };\n } else {\n return null;\n }\n } catch (error) {\n console.warn(error);\n return null;\n }\n}\n\nfunction matchNumericOperation(value: number, op: NumericOperation): boolean {\n if (op.operation === \"eq\") {\n if (value !== op.value) {\n return false;\n }\n } else if (op.operation === \"gt\") {\n if (!(value > op.value)) {\n return false;\n }\n } else if (op.operation === \"gte\") {\n if (!(value >= op.value)) {\n return false;\n }\n } else if (op.operation === \"lt\") {\n if (!(value < op.value)) {\n return false;\n }\n } else if (op.operation === \"lte\") {\n if (!(value <= op.value)) {\n return false;\n }\n } else {\n throw new Error(`Not implemented operation '${op.operation}'`);\n }\n return true;\n}\n\nfunction DocumentsTable({\n locale,\n counts,\n documents,\n sort,\n sortReverse,\n}: {\n locale: string;\n counts: Counts;\n documents: Document[];\n sort: string;\n sortReverse: boolean;\n}) {\n const [searchParams, setSearchParams] = useSearchParams();\n\n const page = parseInt(searchParams.get(\"page\") || \"1\", 10);\n const pageSize = parseInt(searchParams.get(\"pageSize\") || \"20\", 10);\n const filterTitle = searchParams.get(\"title\") || \"\";\n const filterURL = searchParams.get(\"url\") || \"\";\n const filterDifferences = searchParams.get(\"differences\") || \"\";\n const filterDifferencesOperation = getNumericOperation(filterDifferences);\n\n function TableHead({ id, title }: { id: string; title: string }) {\n return (\n <th\n onClick={() => {\n if (sort === id) {\n setSearchParams(\n createSearchParams({\n sort: id,\n sortReverse: JSON.stringify(!sortReverse),\n })\n );\n } else {\n setSearchParams(createSearchParams({ sort: id }));\n }\n }}\n className=\"sortable\"\n >\n {title} {sort === id ? (sortReverse ? \"↓\" : \"↑\") : null}\n </th>\n );\n }\n\n const filteredDocuments = documents\n .filter((document) => {\n if (\n filterTitle &&\n !document.title.toLowerCase().includes(filterTitle.toLowerCase())\n ) {\n return false;\n }\n\n if (\n filterURL &&\n !document.mdn_url.toLowerCase().includes(filterURL.toLowerCase())\n ) {\n return false;\n }\n\n if (\n filterDifferencesOperation &&\n !matchNumericOperation(\n document.differences.total,\n filterDifferencesOperation\n )\n ) {\n return false;\n }\n\n return true;\n })\n .sort((A, B) => {\n let reverse = sortReverse ? -1 : 1;\n if (sort === \"modified\") {\n const a = new Date(A.edits.modified);\n const b = new Date(B.edits.modified);\n return reverse * (b.getTime() - a.getTime());\n } else if (sort === \"popularity\") {\n const a = A.popularity.value;\n const b = B.popularity.value;\n return reverse * (b - a);\n } else if (sort === \"differences\") {\n const a = A.differences.total;\n const b = B.differences.total;\n return reverse * (b - a);\n } else if (sort === \"title\") {\n const a = A.title;\n const b = B.title;\n return reverse * a.localeCompare(b);\n } else if (sort === \"mdn_url\") {\n const a = A.mdn_url;\n const b = B.mdn_url;\n return reverse * a.localeCompare(b);\n } else if (sort === \"sourceCommit\") {\n const a = A.edits.sourceCommitsBehindCount ?? -1;\n const b = B.edits.sourceCommitsBehindCount ?? -1;\n return reverse * (b - a);\n } else {\n throw new Error(`Unrecognized sort '${sort}'`);\n }\n });\n const pageCount = Math.ceil(counts.found / pageSize);\n\n return (\n <div className=\"documents\">\n <h3>\n Documents with differences found (\n {filteredDocuments.length.toLocaleString()}){\" \"}\n {pageCount > 1 && (\n <span className=\"page\">\n page {page}/{pageCount}\n </span>\n )}\n </h3>\n <h4 className=\"subheader\">\n {counts.total.toLocaleString()} total documents found ({locale})\n </h4>\n\n {filterDifferences && !filterDifferencesOperation && (\n <div className=\"error-message\">\n <h3>Invalid differences filter</h3>\n <p>\n The <i>differences</i> filter can't be parsed.\n <br />\n <code>{filterDifferences}</code>\n </p>\n </div>\n )}\n\n <table>\n <thead>\n <tr>\n <TableHead id=\"title\" title=\"Document\" />\n <TableHead id=\"popularity\" title=\"Popularity\" />\n <TableHead id=\"modified\" title=\"Last modified\" />\n <TableHead id=\"differences\" title=\"Differences\" />\n <TableHead id=\"sourceCommit\" title=\"Source Commit\" />\n </tr>\n </thead>\n <tbody>\n {filteredDocuments\n .slice((page - 1) * pageSize, page * pageSize)\n .map((doc: Document) => {\n return (\n <tr key={doc.mdn_url}>\n <td>\n <span className=\"document-title-preview\">\n {filterTitle ? (\n <HighlightedText\n text={doc.title}\n highlight={filterTitle}\n />\n ) : (\n doc.title\n )}\n </span>\n <br />\n <Link\n to={`${doc.mdn_url}#_flaws`}\n title={doc.title}\n target=\"_blank\"\n >\n <BriefURL uri={doc.mdn_url} filterURL={filterURL} />\n </Link>\n </td>\n <td\n title={\n doc.popularity.ranking\n ? `Meaning there are ${\n doc.popularity.ranking - 1\n } more popular pages than this`\n : \"Meaning it has no ranking. Most likely a very rare (or new) document\"\n }\n >\n {!doc.popularity.ranking\n ? \"n/a\"\n : `${getGetOrdinal(doc.popularity.ranking)}`}{\" \"}\n <small title=\"For the parent document\">\n (\n {!doc.popularity.parentRanking\n ? \"n/a\"\n : `${getGetOrdinal(doc.popularity.parentRanking)}`}\n )\n </small>\n </td>\n <td>\n <LastModified edits={doc.edits} />\n </td>\n <td>{doc.differences.total.toLocaleString()}</td>\n <td>\n <L10nSourceCommitModified\n sourceCommitsBehindCount={\n doc.edits.sourceCommitsBehindCount\n }\n sourceCommitURL={doc.edits.sourceCommitURL}\n />\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n\n <Paginator last={pageCount} />\n </div>\n );\n}\n\nfunction L10nSourceCommitModified({\n sourceCommitsBehindCount,\n sourceCommitURL,\n}: Pick<DocumentEdits, \"sourceCommitsBehindCount\" | \"sourceCommitURL\">) {\n if (\n !sourceCommitURL ||\n (!sourceCommitsBehindCount && sourceCommitsBehindCount !== 0)\n ) {\n return <>Metadata does not exist.</>;\n }\n\n const getImportanceColor = () => {\n if (sourceCommitsBehindCount === 0) return \"🟢\";\n return sourceCommitsBehindCount < 10 ? \"🟠\" : \"🔴\";\n };\n\n return (\n <a\n href={sourceCommitURL}\n >{`${getImportanceColor()} ${sourceCommitsBehindCount} commits behind`}</a>\n );\n}\n\nfunction LastModified({ edits }: { edits: DocumentEdits }) {\n const modified = dayjs(edits.modified);\n const parentModified = dayjs(edits.parentModified);\n return (\n <span\n className={`last_modified ${\n parentModified < modified ? \"ahead\" : \"behind\"\n }`}\n >\n <a href={edits.commitURL} target=\"_blank\" rel=\"noreferrer\">\n <time dateTime={modified.toISOString()} title={modified.toISOString()}>\n {modified.fromNow()}\n </time>\n </a>\n <br />\n <a href={edits.parentCommitURL} target=\"_blank\" rel=\"noreferrer\">\n <small>\n <time\n dateTime={parentModified.toISOString()}\n title={parentModified.toISOString()}\n >\n en-US {parentModified.fromNow()}\n </time>\n </small>\n </a>\n </span>\n );\n}\n\nfunction HighlightedText({\n text,\n highlight,\n}: {\n text: string;\n highlight: string;\n}) {\n // Split on highlight term and include term into parts, ignore case\n const parts = text.split(new RegExp(`(${highlight})`, \"gi\"));\n return (\n <span>\n {\" \"}\n {parts.map((part, i) => (\n <span\n key={i}\n style={\n part.toLowerCase() === highlight.toLowerCase()\n ? { fontWeight: \"bold\" }\n : {}\n }\n >\n {part}\n </span>\n ))}{\" \"}\n </span>\n );\n}\n\nfunction BriefURL({ uri, filterURL }: { uri: string; filterURL: string }) {\n const [left, right] = uri.split(/\\/docs\\//, 2);\n return (\n <>\n <span className=\"url-prefix\">{left}/docs/</span>\n <span className=\"url-slug\">\n {filterURL ? (\n <HighlightedText text={right} highlight={filterURL} />\n ) : (\n right\n )}\n </span>\n </>\n );\n}\n\n// https://gist.github.com/jlbruno/1535691/db35b4f3af3dcbb42babc01541410f291a8e8fac\nfunction getGetOrdinal(n: number) {\n const s = [\"th\", \"st\", \"nd\", \"rd\"];\n const v = n % 100;\n return n.toLocaleString() + (s[(v - 20) % 10] || s[v] || s[0]);\n}\n","import React from \"react\";\nimport {\n createSearchParams,\n Link,\n useSearchParams,\n useNavigate,\n} from \"react-router-dom\";\nimport useSWR from \"swr\";\nimport dayjs from \"dayjs\";\nimport relativeTime from \"dayjs/plugin/relativeTime\";\n\nimport { MainContentContainer } from \"../../ui/atoms/page-content\";\nimport { Paginator } from \"../../ui/molecules/paginator\";\nimport { useLocale } from \"../../hooks\";\n\ndayjs.extend(relativeTime);\n\ninterface DocumentPopularity {\n value: number;\n ranking: number;\n parentValue: number;\n parentRanking: number;\n}\n\ntype CountByType = { [key: string]: number };\n\ninterface DocumentDifferences {\n countByType: CountByType;\n total: number;\n}\n\ninterface DocumentEdits {\n modified: string;\n parentModified: string;\n commitURL: string;\n parentCommitURL: string;\n}\n\ninterface Document {\n mdn_url: string;\n edits: DocumentEdits;\n title: string;\n popularity: DocumentPopularity;\n differences: DocumentDifferences;\n}\n\ninterface Counts {\n missing: number;\n translated: number;\n total: number;\n cacheMisses: number;\n}\n\ninterface Times {\n took: number;\n}\n\ninterface FlawLevel {\n name: string;\n level: string;\n ignored: boolean;\n}\n\ninterface Data {\n counts: Counts;\n missingDocuments: Document[];\n times: Times;\n flawLevels: FlawLevel[];\n}\n\ninterface LocaleStorageData {\n lastLoadTime?: number;\n defaultSort?: string;\n defaultSortReverse?: string;\n}\n\ninterface StorageData {\n [locale: string]: LocaleStorageData;\n}\n\nconst LOCALSTORAGE_KEY = \"translations-dashboard-missing\";\n\nfunction saveStorage(locale: string, data: LocaleStorageData) {\n try {\n const stored = JSON.parse(\n localStorage.getItem(LOCALSTORAGE_KEY) || \"{}\"\n ) as StorageData;\n stored[locale] = Object.assign({}, stored[locale] || {}, data);\n localStorage.setItem(LOCALSTORAGE_KEY, JSON.stringify(stored));\n } catch (err) {\n console.warn(\"Unable to save to localStorage\", err);\n }\n}\n\nfunction getStorage(locale: string): LocaleStorageData | null {\n try {\n const stored = JSON.parse(localStorage.getItem(LOCALSTORAGE_KEY) || \"{}\");\n if (stored) {\n return stored[locale] as LocaleStorageData;\n }\n } catch (err) {\n console.warn(\"Unable to retrieve from localStorage\", err);\n }\n return null;\n}\n\nexport function MissingTranslations() {\n const locale = useLocale();\n const [searchParams] = useSearchParams();\n const navigate = useNavigate();\n\n const [lastData, setLastData] = React.useState<Data | null>(null);\n\n React.useEffect(() => {\n if (locale.toLowerCase() === \"en-us\") {\n navigate(`/${locale}/_translations`);\n }\n }, [locale, navigate]);\n\n React.useEffect(() => {\n let title = \"Missing translations\";\n if (locale.toLowerCase() !== \"en-us\") {\n title += ` for ${locale}`;\n }\n if (lastData) {\n title = `(${lastData.counts.missing.toLocaleString()} found) ${title}`;\n }\n document.title = title;\n }, [lastData, locale]);\n\n const { data, error, isValidating } = useSWR<Data, Error>(\n locale.toLowerCase() !== \"en-us\"\n ? `/_translations/missing/?locale=${locale}`\n : null,\n async (url) => {\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`${response.status} (${await response.text()})`);\n }\n if (\n !(response.headers.get(\"content-type\") || \"\").includes(\n \"application/json\"\n )\n ) {\n throw new Error(\n `Response is not JSON (${response.headers.get(\"content-type\")})`\n );\n }\n return response.json();\n },\n {\n revalidateOnFocus: false,\n }\n );\n\n // Use this to be able to figure out how long the XHR takes when there's no cache\n const startTime = React.useRef<Date>();\n React.useEffect(() => {\n if (locale) {\n if (!data) {\n startTime.current = new Date();\n } else {\n if (\n data.counts.cacheMisses > 0 &&\n data.counts.cacheMisses === data.counts.total &&\n startTime.current\n ) {\n const lastLoadTime =\n new Date().getTime() - startTime.current.getTime();\n saveStorage(locale, { lastLoadTime });\n }\n }\n }\n }, [locale, data]);\n\n React.useEffect(() => {\n if (data) {\n setLastData(data);\n }\n }, [data]);\n\n const lastStorageData = getStorage(locale);\n const defaultSort = lastStorageData?.defaultSort || \"popularity\";\n const defaultSortReverse = lastStorageData?.defaultSortReverse || \"false\";\n const sort = searchParams.get(\"sort\") || defaultSort;\n const sortReverse = JSON.parse(\n searchParams.get(\"sortReverse\") || defaultSortReverse\n );\n\n React.useEffect(() => {\n saveStorage(\n locale,\n Object.assign({}, lastStorageData, {\n defaultSort: sort,\n defaultSortReverse: sortReverse,\n })\n );\n }, [locale, sort, sortReverse, lastStorageData]);\n\n if (locale.toLowerCase() === \"en-us\") {\n return null;\n }\n\n return (\n <Container>\n {lastData && !error && isValidating && (\n <p style={{ float: \"right\" }}>Reloading...</p>\n )}\n {!data && !error && !lastData && (\n <Loading\n estimate={\n (lastStorageData && lastStorageData.lastLoadTime) || 30 * 1000\n }\n />\n )}\n {lastData && (\n <p style={{ textAlign: \"right\" }}>\n Go to{\" \"}\n <Link to={`/${locale}/_translations/differences`}>\n Translation differences for <b>{locale}</b>\n </Link>\n </p>\n )}\n {error && <ShowSearchError error={error} />}\n {lastData && (\n <div className=\"filter-documents\">\n <FilterControls />\n <DocumentsTable\n counts={lastData.counts}\n documents={lastData.missingDocuments}\n sort={sort}\n sortReverse={sortReverse}\n />\n </div>\n )}\n {data && <BuildTimes times={data.times} />}\n </Container>\n );\n}\n\nfunction Container({ children }: { children: React.ReactNode }) {\n return (\n <MainContentContainer className=\"missing-translations\" standalone={true}>\n {children}\n </MainContentContainer>\n );\n}\n\nfunction ShowSearchError({ error }) {\n return (\n <div className=\"error-message search-error\">\n <h3>Search error</h3>\n <pre>{error.toString()}</pre>\n </div>\n );\n}\n\nfunction BuildTimes({ times }: { times: Times }) {\n function format(ms: number) {\n if (ms > 1000) {\n const s = ms / 1000;\n return `${s.toFixed(1)} seconds`;\n } else {\n return `${Math.trunc(ms)} milliseconds`;\n }\n }\n return (\n <div className=\"search-times\">\n <p>Time to find all documents {format(times.took)}</p>\n </div>\n );\n}\n\nfunction Loading({ estimate }: { estimate: number }) {\n const startLoadingTime = new Date();\n const [estimateEndTime] = React.useState(\n new Date(startLoadingTime.getTime() + estimate)\n );\n\n const [, setIncrements] = React.useState(0);\n React.useEffect(() => {\n const interval = setInterval(() => {\n setIncrements((state) => state + 1);\n }, 1000);\n return () => clearInterval(interval);\n }, []);\n\n const distance = estimateEndTime.getTime() - startLoadingTime.getTime();\n const elapsed = new Date().getTime() - startLoadingTime.getTime();\n const percent = (100 * elapsed) / distance;\n return (\n <div className=\"loading\">\n <progress id=\"progress\" max=\"100\" value={percent} style={{ margin: 20 }}>\n {percent}%\n </progress>\n <br />\n <small>\n Estimated time to finish: {((distance - elapsed) / 1000).toFixed(0)}s{\" \"}\n {elapsed > distance ? (\n <span aria-label=\"weird\" role=\"img\">\n 🙃\n </span>\n ) : null}\n </small>\n </div>\n );\n}\n\nfunction FilterControls() {\n const [searchParams, setSearchParams] = useSearchParams();\n const [title, setTitle] = React.useState(searchParams.get(\"title\") || \"\");\n const [url, setURL] = React.useState(searchParams.get(\"url\") || \"\");\n\n function refreshFilters(reset = false) {\n const filterParams = createSearchParams(searchParams);\n for (const [key, value] of [\n [\"url\", url],\n [\"title\", title],\n ]) {\n if (!reset && value) {\n filterParams.set(key, value);\n } else {\n filterParams.delete(key);\n }\n }\n filterParams.delete(\"page\");\n setSearchParams(filterParams);\n }\n\n function resetFilters() {\n setURL(\"\");\n setTitle(\"\");\n refreshFilters(true);\n }\n\n return (\n <div className=\"filters\">\n <h3>Filters</h3>\n <form\n onSubmit={(event) => {\n event.preventDefault();\n refreshFilters();\n }}\n >\n <div>\n <h4>Document</h4>\n <input\n type=\"search\"\n placeholder=\"Filter by document URI\"\n value={url}\n onChange={(event) => {\n setURL(event.target.value);\n }}\n onBlur={() => refreshFilters()}\n />\n <input\n type=\"search\"\n placeholder=\"Filter by document title\"\n value={title}\n onChange={(event) => {\n setTitle(event.target.value);\n }}\n onBlur={() => refreshFilters()}\n />\n </div>\n\n <div>\n <h4>&nbsp;</h4>\n <button type=\"submit\">Filter now</button>{\" \"}\n {(url || title) && (\n <button type=\"button\" onClick={resetFilters}>\n Reset filters\n </button>\n )}\n </div>\n </form>\n </div>\n );\n}\ntype NumericOperation = {\n operation: \"eq\" | \"gt\" | \"gte\" | \"lt\" | \"lte\";\n value: number;\n};\n\nfunction getNumericOperation(expression: string): NumericOperation | null {\n function parseIntOrThrow(v: string) {\n if (!v) {\n throw new Error(\"Can't be empty\");\n }\n\n const parsed = parseInt(v, 10);\n if (isNaN(parsed)) {\n throw new Error(`'${v}' not a valid number`);\n }\n return parsed;\n }\n try {\n if (expression.startsWith(\">=\")) {\n return {\n operation: \"gte\",\n value: parseIntOrThrow(expression.replace(\">=\", \"\")),\n };\n } else if (expression.startsWith(\">\")) {\n return {\n operation: \"gt\",\n value: parseIntOrThrow(expression.replace(\">\", \"\")),\n };\n } else if (expression.startsWith(\"<=\")) {\n return {\n operation: \"lte\",\n value: parseIntOrThrow(expression.replace(\"<=\", \"\")),\n };\n } else if (expression.startsWith(\"<\")) {\n return {\n operation: \"lt\",\n value: parseIntOrThrow(expression.replace(\"<\", \"\")),\n };\n } else if (expression.startsWith(\"==\") || expression.startsWith(\"=\")) {\n return {\n operation: \"eq\",\n value: parseIntOrThrow(expression.replace(/=/g, \"\")),\n };\n } else if (expression) {\n return {\n operation: \"eq\",\n value: parseIntOrThrow(expression),\n };\n } else {\n return null;\n }\n } catch (error) {\n console.warn(error);\n return null;\n }\n}\n\nfunction matchNumericOperation(value: number, op: NumericOperation): boolean {\n if (op.operation === \"eq\") {\n if (value !== op.value) {\n return false;\n }\n } else if (op.operation === \"gt\") {\n if (!(value > op.value)) {\n return false;\n }\n } else if (op.operation === \"gte\") {\n if (!(value >= op.value)) {\n return false;\n }\n } else if (op.operation === \"lt\") {\n if (!(value < op.value)) {\n return false;\n }\n } else if (op.operation === \"lte\") {\n if (!(value <= op.value)) {\n return false;\n }\n } else {\n throw new Error(`Not implemented operation '${op.operation}'`);\n }\n return true;\n}\n\nfunction DocumentsTable({\n counts,\n documents,\n sort,\n sortReverse,\n}: {\n counts: Counts;\n documents: Document[];\n sort: string;\n sortReverse: boolean;\n}) {\n const [searchParams, setSearchParams] = useSearchParams();\n\n const page = parseInt(searchParams.get(\"page\") || \"1\", 10);\n const pageSize = parseInt(searchParams.get(\"pageSize\") || \"20\", 10);\n const filterTitle = searchParams.get(\"title\") || \"\";\n const filterURL = searchParams.get(\"url\") || \"\";\n const filterDifferences = searchParams.get(\"differences\") || \"\";\n const filterDifferencesOperation = getNumericOperation(filterDifferences);\n\n function TableHead({ id, title }: { id: string; title: string }) {\n return (\n <th\n onClick={() => {\n if (sort === id) {\n setSearchParams(\n createSearchParams({\n sort: id,\n sortReverse: JSON.stringify(!sortReverse),\n })\n );\n } else {\n setSearchParams(createSearchParams({ sort: id }));\n }\n }}\n className=\"sortable\"\n >\n {title} {sort === id ? (sortReverse ? \"↓\" : \"↑\") : null}\n </th>\n );\n }\n\n const filteredDocuments = documents\n .filter((document) => {\n if (\n filterTitle &&\n !document.title.toLowerCase().includes(filterTitle.toLowerCase())\n ) {\n return false;\n }\n\n if (\n filterURL &&\n !document.mdn_url.toLowerCase().includes(filterURL.toLowerCase())\n ) {\n return false;\n }\n\n if (\n filterDifferencesOperation &&\n !matchNumericOperation(\n document.differences.total,\n filterDifferencesOperation\n )\n ) {\n return false;\n }\n\n return true;\n })\n .sort((A, B) => {\n let reverse = sortReverse ? -1 : 1;\n if (sort === \"modified\") {\n const a = new Date(A.edits.modified);\n const b = new Date(B.edits.modified);\n return reverse * (b.getTime() - a.getTime());\n } else if (sort === \"popularity\") {\n const a = A.popularity.value;\n const b = B.popularity.value;\n return reverse * (b - a);\n } else if (sort === \"differences\") {\n const a = A.differences.total;\n const b = B.differences.total;\n return reverse * (b - a);\n } else if (sort === \"title\") {\n const a = A.title;\n const b = B.title;\n return reverse * a.localeCompare(b);\n } else if (sort === \"mdn_url\") {\n const a = A.mdn_url;\n const b = B.mdn_url;\n return reverse * a.localeCompare(b);\n } else {\n throw new Error(`Unrecognized sort '${sort}'`);\n }\n });\n const pageCount = Math.ceil(counts.total / pageSize);\n\n return (\n <div className=\"documents\">\n <h3>\n {counts.missing.toLocaleString()} missing translations (of{\" \"}\n {counts.total.toLocaleString()} possible)\n </h3>\n\n <table>\n <thead>\n <tr>\n <TableHead id=\"title\" title=\"Document\" />\n <TableHead id=\"popularity\" title=\"Popularity\" />\n <TableHead id=\"modified\" title=\"Last modified\" />\n </tr>\n </thead>\n <tbody>\n {filteredDocuments\n .slice((page - 1) * pageSize, page * pageSize)\n .map((doc: Document) => {\n return (\n <tr key={doc.mdn_url}>\n <td>\n <span className=\"document-title-preview\">\n {filterTitle ? (\n <HighlightedText\n text={doc.title}\n highlight={filterTitle}\n />\n ) : (\n doc.title\n )}\n </span>\n <br />\n <Link\n to={`${doc.mdn_url}#_flaws`}\n title={doc.title}\n target=\"_blank\"\n >\n <BriefURL uri={doc.mdn_url} filterURL={filterURL} />\n </Link>\n </td>\n <td\n title={\n doc.popularity.ranking\n ? `Meaning there are ${\n doc.popularity.ranking - 1\n } more popular pages than this`\n : \"Meaning it has no ranking. Most likely a very rare (or new) document\"\n }\n >\n {!doc.popularity.ranking\n ? \"n/a\"\n : `${getGetOrdinal(doc.popularity.ranking)}`}{\" \"}\n </td>\n <td>\n <LastModified edits={doc.edits} />\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n\n <Paginator last={pageCount} />\n </div>\n );\n}\n\nfunction LastModified({ edits }: { edits: DocumentEdits }) {\n const modified = dayjs(edits.modified);\n return (\n <span className=\"last_modified\">\n <a href={edits.commitURL} target=\"_blank\" rel=\"noreferrer\">\n <time dateTime={modified.toISOString()} title={modified.toISOString()}>\n {modified.fromNow()}\n </time>\n </a>\n </span>\n );\n}\n\nfunction HighlightedText({\n text,\n highlight,\n}: {\n text: string;\n highlight: string;\n}) {\n // Split on highlight term and include term into parts, ignore case\n const parts = text.split(new RegExp(`(${highlight})`, \"gi\"));\n return (\n <span>\n {\" \"}\n {parts.map((part, i) => (\n <span\n key={i}\n style={\n part.toLowerCase() === highlight.toLowerCase()\n ? { fontWeight: \"bold\" }\n : {}\n }\n >\n {part}\n </span>\n ))}{\" \"}\n </span>\n );\n}\n\nfunction BriefURL({ uri, filterURL }: { uri: string; filterURL: string }) {\n const [left, right] = uri.split(/\\/docs\\//, 2);\n return (\n <>\n <span className=\"url-prefix\">{left}/docs/</span>\n <span className=\"url-slug\">\n {filterURL ? (\n <HighlightedText text={right} highlight={filterURL} />\n ) : (\n right\n )}\n </span>\n </>\n );\n}\n\n// https://gist.github.com/jlbruno/1535691/db35b4f3af3dcbb42babc01541410f291a8e8fac\nfunction getGetOrdinal(n: number) {\n const s = [\"th\", \"st\", \"nd\", \"rd\"];\n const v = n % 100;\n return n.toLocaleString() + (s[(v - 20) % 10] || s[v] || s[0]);\n}\n","import React from \"react\";\nimport {\n createSearchParams,\n Link,\n useSearchParams,\n useNavigate,\n} from \"react-router-dom\";\nimport useSWR from \"swr\";\n\nimport { MainContentContainer } from \"../../ui/atoms/page-content\";\nimport { Icon } from \"../../ui/atoms/icon\";\nimport { useLocale } from \"../../hooks\";\n\ninterface Data {\n l10nKPIs: L10nKPIs;\n sections: Section[];\n detailDocuments: DetailDocument[];\n}\n\ninterface Section {\n l10nKPIs: L10nKPIs;\n name: string;\n}\n\ninterface L10nKPIs {\n missing: number;\n outOfDate: number;\n upToDate: number;\n total: number;\n}\n\ninterface DetailDocument {\n url: string;\n info: InfoDocument;\n}\n\ninterface InfoDocument {\n popularity: DocumentPopularity;\n localePopularity: DocumentPopularity;\n defaultLocaleInfo: LocaleInfo;\n localeInfo?: LocaleInfo;\n dateDiff?: number;\n}\n\ninterface DocumentPopularity {\n value: number;\n ranking: number;\n parentValue: number;\n parentRanking: number;\n}\n\ninterface LocaleInfo {\n modified: string;\n commitURL: string;\n}\n\ninterface LocaleStorageData {\n defaultSort?: string;\n defaultSortReverse?: string;\n}\n\ninterface StorageData {\n [locale: string]: LocaleStorageData;\n}\n\nconst LOCALSTORAGE_KEY = \"translations-dashboard-sections\";\n\nfunction saveStorage(locale: string, data: LocaleStorageData) {\n try {\n const stored = JSON.parse(\n localStorage.getItem(LOCALSTORAGE_KEY) || \"{}\"\n ) as StorageData;\n stored[locale] = Object.assign({}, stored[locale] || {}, data);\n localStorage.setItem(LOCALSTORAGE_KEY, JSON.stringify(stored));\n } catch (err) {\n console.warn(\"Unable to save to localStorage\", err);\n }\n}\n\nfunction getStorage(locale: string): LocaleStorageData | null {\n try {\n const stored = JSON.parse(localStorage.getItem(LOCALSTORAGE_KEY) || \"{}\");\n if (stored) {\n return stored[locale] as LocaleStorageData;\n }\n } catch (err) {\n console.warn(\"Unable to retrieve from localStorage\", err);\n }\n return null;\n}\n\nexport function TranslationDashboard() {\n const locale = useLocale();\n const [searchParams] = useSearchParams();\n const navigate = useNavigate();\n\n const [lastData, setLastData] = React.useState<Data | null>(null);\n\n const currentSection = searchParams.get(\"section\") || \"\";\n React.useEffect(() => {\n if (locale.toLowerCase() === \"en-us\") {\n navigate(`/${locale}/_translations`);\n }\n }, [locale, navigate]);\n\n React.useEffect(() => {\n let title = \"Translation dashboard \";\n if (locale.toLowerCase() !== \"en-us\") {\n title += ` for ${locale}`;\n }\n if (currentSection !== \"\") {\n title += ` - section ${currentSection}`;\n }\n document.title = title;\n }, [lastData, locale, currentSection]);\n\n let { data, error, isValidating } = useSWR<Data, Error>(\n locale.toLowerCase() !== \"en-us\"\n ? `/_translations/dashboard/?locale=${locale}&section=${currentSection}`\n : null,\n async (url) => {\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`${response.status} (${await response.text()})`);\n }\n if (\n !(response.headers.get(\"content-type\") || \"\").includes(\n \"application/json\"\n )\n ) {\n throw new Error(\n `Response is not JSON (${response.headers.get(\"content-type\")})`\n );\n }\n return response.json();\n },\n {\n revalidateOnFocus: false,\n }\n );\n\n React.useEffect(() => {\n if (data) {\n setLastData(data);\n }\n }, [data]);\n\n const lastStorageData = getStorage(locale);\n const defaultSort = lastStorageData?.defaultSort || \"url\";\n const defaultSortReverse = lastStorageData?.defaultSortReverse || \"false\";\n const sort = searchParams.get(\"sort\") || defaultSort;\n const sortReverse = JSON.parse(\n searchParams.get(\"sortReverse\") || defaultSortReverse\n );\n\n React.useEffect(() => {\n saveStorage(\n locale,\n Object.assign({}, lastStorageData, {\n defaultSort: sort,\n defaultSortReverse: sortReverse,\n })\n );\n }, [locale, sort, sortReverse, lastStorageData]);\n\n if (locale.toLowerCase() === \"en-us\") {\n return null;\n }\n\n let parentSection = \"/\";\n if (currentSection.split(\"/\").length > 2) {\n const arrPathSection = currentSection.split(\"/\");\n arrPathSection.pop();\n parentSection = arrPathSection.join(\"/\");\n }\n\n return (\n <Container>\n {lastData && !error && isValidating && (\n <p style={{ float: \"right\" }}>Reloading...</p>\n )}\n {!data && !error && !lastData && <Loading />}\n {lastData && (\n <p style={{ textAlign: \"right\" }}>\n Go to{\" \"}\n <Link to={`/${locale}/_translations/differences`}>\n Translation differences for <b>{locale}</b>\n </Link>\n {\" / \"}\n <Link to={`/${locale}/_translations/missing`}>\n Missing translations for <b>{locale}</b>\n </Link>\n </p>\n )}\n {error && <ShowError error={error} />}\n {lastData && (\n <div>\n <SectionHeader\n l10nKPIs={lastData.l10nKPIs}\n section={currentSection}\n parentSection={parentSection}\n />\n <SubsectionTable\n sections={lastData.sections}\n currentSection={currentSection}\n />\n <DocumentsTable\n documents={lastData.detailDocuments}\n sort={sort}\n sortReverse={sortReverse}\n locale={locale}\n />\n </div>\n )}\n </Container>\n );\n /*\n );\n }\n */\n}\n\nfunction Container({ children }: { children: React.ReactNode }) {\n return (\n <div className=\"dashboard-section-translations\">\n <MainContentContainer standalone={true}>{children}</MainContentContainer>\n </div>\n );\n}\n\nfunction ShowError({ error }) {\n return (\n <div className=\"error-message\">\n <h3>Error</h3>\n <pre>{error.toString()}</pre>\n </div>\n );\n}\n\nfunction Loading() {\n return (\n <div>\n <label htmlFor=\"progress\">Loading</label>\n <progress id=\"progress\" max=\"100\" style={{ margin: 20 }}></progress>\n </div>\n );\n}\n\nfunction SectionHeader({\n l10nKPIs,\n section,\n parentSection,\n}: {\n l10nKPIs: L10nKPIs;\n section: string;\n parentSection: string;\n}) {\n const completenessExact =\n (100 * (l10nKPIs.total - l10nKPIs.missing)) / l10nKPIs.total;\n const completenessStr = completenessExact.toFixed(1) + \"%\";\n const freshnessExact = (100 * l10nKPIs.upToDate) / l10nKPIs.total;\n const freshnessStr = freshnessExact.toFixed(1) + \"%\";\n return (\n <div className=\"documents\">\n <h2>Localization dashboard for: {section || \"/\"}</h2>\n <p>\n Parent section:{\" \"}\n <a href={`dashboard?section=${parentSection}`}>{parentSection}</a>\n </p>\n <h3>Summary</h3>\n <dl>\n <dt>Total number of pages</dt>\n <dd>{l10nKPIs.total}</dd>\n <dt>Number of untranslated pages</dt>\n <dd>{l10nKPIs.missing}</dd>\n <dt>Number of outdated pages (older than English in Git) </dt>\n <dd>{l10nKPIs.outOfDate}</dd>\n <dt>Number of up-to-date pages</dt>\n <dd>{l10nKPIs.upToDate}</dd>\n <dt>\n <label htmlFor=\"completeness\">Localization completeness</label>\n </dt>\n <dd>\n <progress id=\"completeness\" max=\"100\" value={completenessExact}>\n {completenessStr}\n </progress>{\" \"}\n {completenessStr}\n </dd>\n <dt>\n <label htmlFor=\"freshness\">Localization freshness</label>\n </dt>\n <dd>\n <progress id=\"freshness\" max=\"100\" value={freshnessExact}>\n {freshnessStr}\n </progress>{\" \"}\n {freshnessStr}\n </dd>\n </dl>\n </div>\n );\n}\n\nfunction SubsectionTable({\n sections,\n currentSection,\n}: {\n sections: Section[];\n currentSection: string;\n}) {\n if (sections.length > 0) {\n return (\n <section id=\"subsection-table\">\n <h3>Subsections</h3>\n <table>\n <thead>\n <tr>\n <th>Section</th>\n <th>Total / Untranslated / Out of date</th>\n <th>Completeness</th>\n <th>Freshness</th>\n </tr>\n </thead>\n <tbody>\n {sections\n .sort(\n (sectionA, sectionB) =>\n sectionB.l10nKPIs.total - sectionA.l10nKPIs.total\n )\n .map((section) => {\n const completenessExact =\n (100 * (section.l10nKPIs.total - section.l10nKPIs.missing)) /\n section.l10nKPIs.total;\n const completenessStr = completenessExact.toFixed(1) + \"%\";\n const freshnessExact =\n (100 * section.l10nKPIs.upToDate) / section.l10nKPIs.total;\n const freshnessStr = freshnessExact.toFixed(1) + \"%\";\n const sectionHref =\n \"dashboard?section=%2F\" + encodeURIComponent(section.name);\n return (\n <tr key={section.name}>\n <td>\n <a href={sectionHref}>\n {section.name\n .replace(currentSection.slice(1), \"\")\n .replace(\"/\", \"\")}\n </a>\n </td>\n <td>\n {section.l10nKPIs.total} / {section.l10nKPIs.missing} /{\" \"}\n {section.l10nKPIs.outOfDate}\n </td>\n <td>\n <progress max=\"100\" value={completenessExact}>\n {completenessStr}\n </progress>{\" \"}\n {completenessStr}\n </td>\n <td>\n <progress max=\"100\" value={freshnessExact}>\n {freshnessStr}\n </progress>{\" \"}\n {freshnessStr}\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </section>\n );\n } else {\n return null;\n }\n}\n\nfunction DocumentsTable({\n documents,\n sort,\n sortReverse,\n locale,\n}: {\n documents: DetailDocument[];\n sort: string;\n sortReverse: boolean;\n locale: string;\n}) {\n const [searchParams, setSearchParams] = useSearchParams();\n const currentSection = searchParams.get(\"section\") || \"\";\n documents.map((documentDetail) => {\n if (documentDetail.info.localeInfo) {\n const dateLocale = new Date(documentDetail.info.localeInfo.modified);\n const dateDefaultLocale = new Date(\n documentDetail.info.defaultLocaleInfo.modified\n );\n const dateDiff = dateLocale.getTime() - dateDefaultLocale.getTime();\n documentDetail.info.dateDiff = dateDiff;\n } else {\n documentDetail.info.dateDiff = Number.POSITIVE_INFINITY;\n }\n return documentDetail;\n });\n\n function TableHead({\n id,\n title,\n sortable,\n }: {\n id: string;\n title: string;\n sortable?: boolean;\n }) {\n function getClassName() {\n const className = [\"sortable\"];\n\n if (sort === id) {\n className.push(\"active\");\n }\n\n if (sortReverse) {\n className.push(\"reverse\");\n }\n\n return className.join(\" \");\n }\n\n function onClick() {\n if (sort === id) {\n setSearchParams(\n createSearchParams({\n sort: id,\n sortReverse: JSON.stringify(!sortReverse),\n section: currentSection,\n })\n );\n } else {\n setSearchParams(\n createSearchParams({ sort: id, section: currentSection })\n );\n }\n }\n\n return sortable ? (\n <th className={getClassName()} onClick={onClick}>\n {title} <Icon name=\"small-arrow\" />\n </th>\n ) : (\n <th>{title}</th>\n );\n }\n\n return (\n <section id=\"documents-table\">\n <h3>List of direct subpages</h3>\n\n <table>\n <thead>\n <tr>\n <TableHead id=\"url\" title=\"Slug\" sortable />\n <TableHead id=\"enMDNURL\" title=\"English doc on MDN\" />\n <TableHead\n id=\"enCommitGHURL\"\n title=\"English doc commit on GitHub\"\n />\n <TableHead id=\"localURL\" title=\"Local localized doc\" />\n <TableHead id=\"localMDNURL\" title=\"Localized doc on MDN\" />\n <TableHead\n id=\"localCommitGHURL\"\n title=\"Localized doc commit on GitHub\"\n />\n <TableHead\n id=\"popularityEn\"\n title=\"Popularity rank (en-US)\"\n sortable\n />\n <TableHead\n id=\"popularityLocale\"\n title={`Popularity rank (${locale})`}\n sortable\n />\n <TableHead id=\"dateDiff\" title=\"Date delta\" sortable />\n </tr>\n </thead>\n\n <tbody>\n {documents\n .sort((A, B) => {\n let reverse = sortReverse ? -1 : 1;\n if (sort === \"dateDiff\") {\n const a = A.info.dateDiff || Number.POSITIVE_INFINITY;\n const b = B.info.dateDiff || Number.POSITIVE_INFINITY;\n return reverse * (b - a);\n } else if (sort === \"popularityLocale\") {\n const a =\n A.info.localePopularity?.ranking || Number.POSITIVE_INFINITY;\n const b =\n B.info.localePopularity?.ranking || Number.POSITIVE_INFINITY;\n return reverse * (a - b);\n } else if (sort === \"popularityEn\") {\n const a = A.info.popularity.ranking || Number.POSITIVE_INFINITY;\n const b = B.info.popularity.ranking || Number.POSITIVE_INFINITY;\n return reverse * (a - b);\n } else if (sort === \"url\") {\n const a = A.url;\n const b = B.url;\n return reverse * a.localeCompare(b);\n } else {\n throw new Error(`Unrecognized sort '${sort}'`);\n }\n })\n .map((documentDetail) => {\n const url = \"https://developer.mozilla.org\" + documentDetail.url;\n const englishCommitHash =\n documentDetail.info.defaultLocaleInfo.commitURL\n .split(\"commit/\")[1]\n .substring(0, 7);\n const localeCommitHash = documentDetail.info.localeInfo?.commitURL\n .split(\"commit/\")[1]\n .substring(0, 7);\n let status = \"Untranslated\";\n if (documentDetail.info.localeInfo) {\n let dateDiff =\n documentDetail.info.dateDiff ?? Number.POSITIVE_INFINITY;\n status = \"Out of date\";\n\n if (dateDiff > 0) {\n status = \"Fresher than English\";\n } else if (dateDiff > -2678400000) {\n const nbDays = Math.round(-dateDiff / (3600 * 24 * 1000));\n status = nbDays + \" day\" + (nbDays > 1 ? \"s\" : \"\");\n } else {\n const nbMonths = Math.round(\n -dateDiff / (3600 * 24 * 1000 * 30)\n );\n status = nbMonths + \" month\" + (nbMonths > 1 ? \"s\" : \"\");\n }\n }\n return (\n <tr key={documentDetail.url}>\n <td>\n <a href={documentDetail.url}>{documentDetail.url}</a>\n </td>\n <td>\n <a href={url}>English current MDN page</a>\n </td>\n <td>\n <a href={documentDetail.info.defaultLocaleInfo.commitURL}>\n GitHub link for <code>{englishCommitHash}</code>\n </a>\n </td>\n <td>\n {documentDetail.info.localeInfo && (\n <a\n href={documentDetail.url.replace(\n \"/en-US/\",\n \"/\" + locale + \"/\"\n )}\n >\n Local {locale} page\n </a>\n )}\n </td>\n <td>\n {documentDetail.info.localeInfo && (\n <a href={url.replace(\"/en-US/\", \"/\" + locale + \"/\")}>\n Locale current MDN page\n </a>\n )}\n </td>\n <td>\n {documentDetail.info.localeInfo && (\n <a href={documentDetail.info.localeInfo.commitURL}>\n GitHub link for <code>{localeCommitHash}</code>\n </a>\n )}\n </td>\n <td>{documentDetail.info.popularity.ranking}</td>\n <td>\n {documentDetail.info.localePopularity &&\n documentDetail.info.localePopularity.ranking}\n </td>\n <td>{status}</td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </section>\n );\n}\n","import React from \"react\";\nimport { Link, Routes, Route } from \"react-router-dom\";\nimport useSWR from \"swr\";\n\nimport \"./index.scss\";\n\nimport { Loading } from \"../ui/atoms/loading\";\nimport { MainContentContainer } from \"../ui/atoms/page-content\";\n\nimport { TranslationDifferences } from \"./differences\";\nimport { MissingTranslations } from \"./missing\";\nimport { TranslationDashboard } from \"./dashboard\";\nimport { useLocale } from \"../hooks\";\n\ninterface Locale {\n locale: string;\n language: {\n English: string;\n native: string;\n };\n isActive: boolean;\n count: number;\n}\n\ninterface LocalesData {\n locales: Locale[];\n}\n\nexport default function Translations() {\n return (\n <Container>\n <Routes>\n <Route path=\"/\" element={<PickLocale />} />\n <Route path=\"differences\" element={<TranslationDifferences />} />\n <Route path=\"missing\" element={<MissingTranslations />} />\n <Route path=\"dashboard\" element={<TranslationDashboard />} />\n </Routes>\n </Container>\n );\n}\n\nfunction PickLocale() {\n const locale = useLocale();\n React.useEffect(() => {\n let title = \"All translations\";\n if (locale.toLowerCase() !== \"en-us\") {\n title += ` for ${locale}`;\n }\n document.title = title;\n }, [locale]);\n\n const { data: dataLocales, error: errorLocales } = useSWR<LocalesData, Error>(\n locale.toLowerCase() === \"en-us\" ? \"/_translations/\" : null,\n async (url) => {\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`${response.status} (${await response.text()})`);\n }\n return response.json();\n }\n );\n\n if (locale.toLowerCase() === \"en-us\") {\n return (\n <>\n {!dataLocales && !errorLocales && <Loading />}\n {errorLocales && (\n <div className=\"error-message\">\n <h3>Server error</h3>\n <pre>{errorLocales.toString()}</pre>\n </div>\n )}\n {dataLocales && <ShowLocales locales={dataLocales.locales} />}\n </>\n );\n }\n\n return (\n <div className=\"translation-choices\">\n <Link to={`/${locale}/_translations/differences`} className=\"button\">\n Translation differences\n </Link>{\" \"}\n <Link to={`/${locale}/_translations/missing`} className=\"button\">\n Missing translations\n </Link>{\" \"}\n <Link to={`/${locale}/_translations/dashboard`} className=\"button\">\n Dashboard\n </Link>\n </div>\n );\n}\n\nfunction Container({ children }: { children: React.ReactNode }) {\n return (\n <MainContentContainer className=\"all-translations\" standalone={true}>\n {children}\n </MainContentContainer>\n );\n}\n\nfunction ShowLocales({ locales }: { locales: Locale[] }) {\n return (\n <div>\n <h2>Select locale</h2>\n <table>\n <tbody>\n {locales.map((locale) => {\n return (\n <tr key={locale.locale}>\n <td>\n <b>\n {locale.language.English} ({locale.locale})\n </b>{\" \"}\n {!locale.isActive && <small>not active</small>}\n </td>\n <td>{locale.count.toLocaleString()} documents</td>\n <td>\n <Link to={`/${locale.locale}/_translations/differences`}>\n Translation differences\n </Link>{\" \"}\n </td>\n <td>\n <Link to={`/${locale.locale}/_translations/missing`}>\n Missing translations\n </Link>{\" \"}\n </td>\n <td>\n <Link to={`/${locale.locale}/_translations/dashboard`}>\n Dashboard\n </Link>{\" \"}\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n );\n}\n","import { Link, useSearchParams } from \"react-router-dom\";\nimport { range } from \"../../../utils\";\n\nconst PARAM = \"page\";\n\nfunction PageLink({\n page,\n children,\n onClick,\n disabled,\n}: {\n page: number;\n children?: React.ReactNode;\n onClick?: (page: number) => unknown;\n disabled?: boolean;\n}) {\n const [searchParams, setSearchParams] = useSearchParams();\n\n return (\n <Link\n to={{}}\n className={disabled ? \"disabled\" : \"\"}\n onClick={(event) => {\n event.preventDefault();\n if (disabled) {\n return;\n }\n\n onClick && onClick(page);\n setSearchParams({\n ...Object.fromEntries(searchParams.entries()),\n [PARAM]: page.toString(),\n });\n\n window.setTimeout(() => document.documentElement.scrollTo());\n }}\n >\n {children || page}\n </Link>\n );\n}\n\nexport function Paginator({\n first = 1,\n last,\n endPadding = 2,\n middlePadding = 2,\n onChange,\n}: {\n first?: number;\n last: number;\n endPadding?: number;\n middlePadding?: number;\n onChange?: (page: number, oldPage: number) => unknown;\n}) {\n const [searchParams] = useSearchParams();\n const current = parseInt(searchParams.get(PARAM) || \"\", 10) || first;\n const middleFirst = Math.max(current - middlePadding, first);\n const middleLast = Math.min(middleFirst + middlePadding * 2 + 1, last + 1);\n const left = range(first, Math.min(endPadding, middleFirst));\n const middle = range(middleFirst, middleLast);\n const right = range(Math.max(last + 1 - endPadding, middleLast), last + 1);\n\n const onClick = (page: number) => {\n onChange && onChange(page, current);\n };\n\n if (first === last) {\n // There are no pages, so return nothing\n return <></>;\n }\n\n return (\n <div className=\"pagination\">\n <PageLink\n page={current - 1}\n onClick={onClick}\n disabled={current === first}\n >\n ← Previous\n </PageLink>\n {left.map((page) => (\n <PageLink key={page} page={page} onClick={onClick} />\n ))}\n {Boolean(left.length) && left[left.length - 1] + 1 !== middle[0] && \"…\"}\n {middle.map((page) =>\n current === page ? (\n <span className=\"current-page\" key={page}>\n {page}\n </span>\n ) : (\n <PageLink key={page} page={page} onClick={onClick} />\n )\n )}\n {Boolean(right.length) &&\n middle[middle.length - 1] + 1 !== right[0] &&\n \"…\"}\n {right.map((page) => (\n <PageLink key={page} page={page} onClick={onClick} />\n ))}\n <PageLink\n page={current + 1}\n onClick={onClick}\n disabled={current === last}\n >\n Next →\n </PageLink>\n </div>\n );\n}\n"],"names":["dayjs","relativeTime","LOCALSTORAGE_KEY","saveStorage","locale","data","stored","JSON","localStorage","Object","err","console","TranslationDifferences","useLocale","searchParams","_useSearchParams","navigate","useNavigate","_React_useState","lastData","setLastData","React","title","document","_useSWR","url","response","fetch","Error","n","error","isValidating","startTime","lastLoadTime","Date","lastStorageData","getStorage","defaultSort","defaultSortReverse","sort","sortReverse","Container","Loading","Link","ShowSearchError","FilterControls","DocumentsTable","BuildTimes","param","children","MainContentContainer","ms","times","s","Math","estimate","startLoadingTime","estimateEndTime","setIncrements","_React_useState1","interval","setInterval","state","clearInterval","distance","elapsed","percent","setSearchParams","setTitle","setURL","_React_useState2","differences","setDifferences","refreshFilters","reset","filterParams","createSearchParams","_iter","key","value","event","counts","documents","page","parseInt","pageSize","filterTitle","filterURL","filterDifferences","filterDifferencesOperation","getNumericOperation","expression","parseIntOrThrow","v","parsed","isNaN","TableHead","id","filteredDocuments","document1","matchNumericOperation","op","A","B","reverse","a","b","a1","b1","a2","b2","a3","b3","a4","b4","_A_edits_sourceCommitsBehindCount","_B_edits_sourceCommitsBehindCount","a5","b5","pageCount","doc","HighlightedText","BriefURL","getGetOrdinal","LastModified","L10nSourceCommitModified","Paginator","sourceCommitsBehindCount","sourceCommitURL","edits","modified","parentModified","text","highlight","parts","RegExp","part","i","uri","_uri_split","left","right","MissingTranslations","TranslationDashboard","currentSection","parentSection","arrPathSection","ShowError","SectionHeader","SubsectionTable","l10nKPIs","section","completenessExact","completenessStr","freshnessExact","freshnessStr","sections","sectionA","sectionB","sectionHref","encodeURIComponent","className","sortable","Icon","documentDetail","dateLocale","dateDefaultLocale","dateDiff","Number","_A_info_localePopularity","_B_info_localePopularity","englishCommitHash","localeCommitHash","_documentDetail_info_localeInfo","status","_documentDetail_info_dateDiff","nbDays","nbMonths","Translations","Routes","Route","PickLocale","dataLocales","errorLocales","ShowLocales","locales","PARAM","PageLink","onClick","disabled","window","first","last","endPadding","middlePadding","onChange","current","middleFirst","middleLast","range","middle","Boolean"],"mappings":"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"}
1
+ {"version":3,"file":"145.e71ec0c1d16bfeb6.js","sources":["webpack://@mdn/fred/./node_modules/@mdn/yari/client/src/translations/differences/index.tsx","webpack://@mdn/fred/./node_modules/@mdn/yari/client/src/translations/missing/index.tsx","webpack://@mdn/fred/./node_modules/@mdn/yari/client/src/translations/dashboard/index.tsx","webpack://@mdn/fred/./node_modules/@mdn/yari/client/src/translations/index.tsx","webpack://@mdn/fred/./node_modules/@mdn/yari/client/src/ui/molecules/paginator/index.tsx"],"sourcesContent":["import React from \"react\";\nimport {\n createSearchParams,\n Link,\n useSearchParams,\n useNavigate,\n} from \"react-router-dom\";\nimport useSWR from \"swr\";\nimport dayjs from \"dayjs\";\nimport relativeTime from \"dayjs/plugin/relativeTime\";\n\nimport \"./index.scss\";\n\nimport { MainContentContainer } from \"../../ui/atoms/page-content\";\nimport { Paginator } from \"../../ui/molecules/paginator\";\nimport { useLocale } from \"../../hooks\";\n\ndayjs.extend(relativeTime);\n\ninterface DocumentPopularity {\n value: number;\n ranking: number;\n parentValue: number;\n parentRanking: number;\n}\n\ntype CountByType = { [key: string]: number };\n\ninterface DocumentDifferences {\n countByType: CountByType;\n total: number;\n}\n\ninterface DocumentEdits {\n modified: string;\n parentModified: string;\n commitURL: string;\n parentCommitURL: string;\n sourceCommitsBehindCount?: number;\n sourceCommitURL?: string;\n}\n\ninterface Document {\n mdn_url: string;\n edits: DocumentEdits;\n title: string;\n popularity: DocumentPopularity;\n differences: DocumentDifferences;\n}\n\ninterface Counts {\n found: number;\n total: number;\n pages: number;\n noParents: number;\n cacheMisses: number;\n}\n\ninterface Times {\n took: number;\n}\n\ninterface FlawLevel {\n name: string;\n level: string;\n ignored: boolean;\n}\n\ninterface Data {\n counts: Counts;\n documents: Document[];\n times: Times;\n flawLevels: FlawLevel[];\n}\n\ninterface LocaleStorageData {\n lastLoadTime?: number;\n defaultSort?: string;\n defaultSortReverse?: string;\n}\n\ninterface StorageData {\n [locale: string]: LocaleStorageData;\n}\n\nconst LOCALSTORAGE_KEY = \"translations-dashboard-differences\";\n\nfunction saveStorage(locale: string, data: LocaleStorageData) {\n try {\n const stored = JSON.parse(\n localStorage.getItem(LOCALSTORAGE_KEY) || \"{}\"\n ) as StorageData;\n stored[locale] = Object.assign({}, stored[locale] || {}, data);\n localStorage.setItem(LOCALSTORAGE_KEY, JSON.stringify(stored));\n } catch (err) {\n console.warn(\"Unable to save to localStorage\", err);\n }\n}\n\nfunction getStorage(locale: string): LocaleStorageData | null {\n try {\n const stored = JSON.parse(localStorage.getItem(LOCALSTORAGE_KEY) || \"{}\");\n if (stored) {\n return stored[locale] as LocaleStorageData;\n }\n } catch (err) {\n console.warn(\"Unable to retrieve from localStorage\", err);\n }\n return null;\n}\n\nexport function TranslationDifferences() {\n const locale = useLocale();\n const [searchParams] = useSearchParams();\n const navigate = useNavigate();\n\n const [lastData, setLastData] = React.useState<Data | null>(null);\n\n React.useEffect(() => {\n if (locale.toLowerCase() === \"en-us\") {\n navigate(`/${locale}/_translations`);\n }\n }, [locale, navigate]);\n\n React.useEffect(() => {\n let title = \"All translations\";\n if (locale.toLowerCase() !== \"en-us\") {\n title += ` for ${locale}`;\n }\n if (lastData) {\n title = `(${lastData.counts.found.toLocaleString()} found) ${title}`;\n }\n document.title = title;\n }, [lastData, locale]);\n\n const { data, error, isValidating } = useSWR<Data, Error>(\n locale.toLowerCase() !== \"en-us\"\n ? `/_translations/differences/?locale=${locale}`\n : null,\n async (url) => {\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`${response.status} (${await response.text()})`);\n }\n if (\n !(response.headers.get(\"content-type\") || \"\").includes(\n \"application/json\"\n )\n ) {\n throw new Error(\n `Response is not JSON (${response.headers.get(\"content-type\")})`\n );\n }\n return response.json();\n },\n {\n revalidateOnFocus: false,\n }\n );\n\n // Use this to be able to figure out how long the XHR takes when there's no cache\n const startTime = React.useRef<Date>();\n React.useEffect(() => {\n if (locale) {\n if (!data) {\n startTime.current = new Date();\n } else {\n if (\n data.counts.cacheMisses > 0 &&\n data.counts.cacheMisses === data.counts.total &&\n startTime.current\n ) {\n const lastLoadTime =\n new Date().getTime() - startTime.current.getTime();\n saveStorage(locale, { lastLoadTime });\n }\n }\n }\n }, [locale, data]);\n\n React.useEffect(() => {\n if (data) {\n setLastData(data);\n }\n }, [data]);\n\n const lastStorageData = getStorage(locale);\n const defaultSort = lastStorageData?.defaultSort || \"modified\";\n const defaultSortReverse = lastStorageData?.defaultSortReverse || \"false\";\n const sort = searchParams.get(\"sort\") || defaultSort;\n const sortReverse = JSON.parse(\n searchParams.get(\"sortReverse\") || defaultSortReverse\n );\n\n React.useEffect(() => {\n saveStorage(\n locale,\n Object.assign({}, lastStorageData, {\n defaultSort: sort,\n defaultSortReverse: sortReverse,\n })\n );\n }, [locale, sort, sortReverse, lastStorageData]);\n\n if (locale.toLowerCase() === \"en-us\") {\n return null;\n }\n\n return (\n <Container>\n {lastData && !error && isValidating && (\n <p style={{ float: \"right\" }}>Reloading...</p>\n )}\n {!data && !error && !lastData && (\n <Loading\n estimate={\n (lastStorageData && lastStorageData.lastLoadTime) || 30 * 1000\n }\n />\n )}\n {lastData && (\n <p style={{ textAlign: \"right\" }}>\n Go to{\" \"}\n <Link to={`/${locale}/_translations/missing`}>\n Missing translations for <b>{locale}</b>\n </Link>\n </p>\n )}\n {error && <ShowSearchError error={error} />}\n {lastData && (\n <div className=\"filter-documents\">\n <FilterControls />\n <DocumentsTable\n locale={locale}\n counts={lastData.counts}\n documents={lastData.documents}\n sort={sort}\n sortReverse={sortReverse}\n />\n </div>\n )}\n {data && <BuildTimes times={data.times} />}\n </Container>\n );\n}\n\nfunction Container({ children }: { children: React.ReactNode }) {\n return (\n <MainContentContainer className=\"all-translations\" standalone={true}>\n {children}\n </MainContentContainer>\n );\n}\n\nfunction ShowSearchError({ error }) {\n return (\n <div className=\"error-message search-error\">\n <h3>Search error</h3>\n <pre>{error.toString()}</pre>\n </div>\n );\n}\n\nfunction BuildTimes({ times }: { times: Times }) {\n function format(ms: number) {\n if (ms > 1000) {\n const s = ms / 1000;\n return `${s.toFixed(1)} seconds`;\n } else {\n return `${Math.trunc(ms)} milliseconds`;\n }\n }\n return (\n <div className=\"search-times\">\n <p>Time to find all documents {format(times.took)}</p>\n </div>\n );\n}\n\nfunction Loading({ estimate }: { estimate: number }) {\n const startLoadingTime = new Date();\n const [estimateEndTime] = React.useState(\n new Date(startLoadingTime.getTime() + estimate)\n );\n\n const [, setIncrements] = React.useState(0);\n React.useEffect(() => {\n const interval = setInterval(() => {\n setIncrements((state) => state + 1);\n }, 1000);\n return () => clearInterval(interval);\n }, []);\n\n const distance = estimateEndTime.getTime() - startLoadingTime.getTime();\n const elapsed = new Date().getTime() - startLoadingTime.getTime();\n const percent = (100 * elapsed) / distance;\n return (\n <div className=\"loading\">\n <progress id=\"progress\" max=\"100\" value={percent} style={{ margin: 20 }}>\n {percent}%\n </progress>\n <br />\n <small>\n Estimated time to finish: {((distance - elapsed) / 1000).toFixed(0)}s{\" \"}\n {elapsed > distance ? (\n <span aria-label=\"weird\" role=\"img\">\n 🙃\n </span>\n ) : null}\n </small>\n </div>\n );\n}\n\nfunction FilterControls() {\n const [searchParams, setSearchParams] = useSearchParams();\n const [title, setTitle] = React.useState(searchParams.get(\"title\") || \"\");\n const [url, setURL] = React.useState(searchParams.get(\"url\") || \"\");\n const [differences, setDifferences] = React.useState(\n searchParams.get(\"differences\") || \"\"\n );\n\n function refreshFilters(reset = false) {\n const filterParams = createSearchParams(searchParams);\n for (const [key, value] of [\n [\"url\", url],\n [\"title\", title],\n [\"differences\", differences],\n ]) {\n if (!reset && value) {\n filterParams.set(key, value);\n } else {\n filterParams.delete(key);\n }\n }\n filterParams.delete(\"page\");\n setSearchParams(filterParams);\n }\n\n function resetFilters() {\n setURL(\"\");\n setTitle(\"\");\n setDifferences(\"\");\n refreshFilters(true);\n }\n\n return (\n <div className=\"filters\">\n <h3>Filters</h3>\n <form\n onSubmit={(event) => {\n event.preventDefault();\n refreshFilters();\n }}\n >\n <div>\n <h4>Document</h4>\n <input\n type=\"search\"\n placeholder=\"Filter by document URI\"\n value={url}\n onChange={(event) => {\n setURL(event.target.value);\n }}\n onBlur={() => refreshFilters()}\n />\n <input\n type=\"search\"\n placeholder=\"Filter by document title\"\n value={title}\n onChange={(event) => {\n setTitle(event.target.value);\n }}\n onBlur={() => refreshFilters()}\n />\n </div>\n <div>\n <h4>Differences</h4>\n <input\n type=\"text\"\n placeholder=\"E.g. >0 or >=5\"\n value={differences}\n onChange={(event) => {\n setDifferences(event.target.value);\n }}\n onBlur={() => refreshFilters()}\n />\n </div>\n\n <div>\n <h4>&nbsp;</h4>\n <button type=\"submit\">Filter now</button>{\" \"}\n {(url || title) && (\n <button type=\"button\" onClick={resetFilters}>\n Reset filters\n </button>\n )}\n </div>\n </form>\n </div>\n );\n}\ntype NumericOperation = {\n operation: \"eq\" | \"gt\" | \"gte\" | \"lt\" | \"lte\";\n value: number;\n};\n\nfunction getNumericOperation(expression: string): NumericOperation | null {\n function parseIntOrThrow(v: string) {\n if (!v) {\n throw new Error(\"Can't be empty\");\n }\n\n const parsed = parseInt(v, 10);\n if (isNaN(parsed)) {\n throw new Error(`'${v}' not a valid number`);\n }\n return parsed;\n }\n try {\n if (expression.startsWith(\">=\")) {\n return {\n operation: \"gte\",\n value: parseIntOrThrow(expression.replace(\">=\", \"\")),\n };\n } else if (expression.startsWith(\">\")) {\n return {\n operation: \"gt\",\n value: parseIntOrThrow(expression.replace(\">\", \"\")),\n };\n } else if (expression.startsWith(\"<=\")) {\n return {\n operation: \"lte\",\n value: parseIntOrThrow(expression.replace(\"<=\", \"\")),\n };\n } else if (expression.startsWith(\"<\")) {\n return {\n operation: \"lt\",\n value: parseIntOrThrow(expression.replace(\"<\", \"\")),\n };\n } else if (expression.startsWith(\"==\") || expression.startsWith(\"=\")) {\n return {\n operation: \"eq\",\n value: parseIntOrThrow(expression.replace(/=/g, \"\")),\n };\n } else if (expression) {\n return {\n operation: \"eq\",\n value: parseIntOrThrow(expression),\n };\n } else {\n return null;\n }\n } catch (error) {\n console.warn(error);\n return null;\n }\n}\n\nfunction matchNumericOperation(value: number, op: NumericOperation): boolean {\n if (op.operation === \"eq\") {\n if (value !== op.value) {\n return false;\n }\n } else if (op.operation === \"gt\") {\n if (!(value > op.value)) {\n return false;\n }\n } else if (op.operation === \"gte\") {\n if (!(value >= op.value)) {\n return false;\n }\n } else if (op.operation === \"lt\") {\n if (!(value < op.value)) {\n return false;\n }\n } else if (op.operation === \"lte\") {\n if (!(value <= op.value)) {\n return false;\n }\n } else {\n throw new Error(`Not implemented operation '${op.operation}'`);\n }\n return true;\n}\n\nfunction DocumentsTable({\n locale,\n counts,\n documents,\n sort,\n sortReverse,\n}: {\n locale: string;\n counts: Counts;\n documents: Document[];\n sort: string;\n sortReverse: boolean;\n}) {\n const [searchParams, setSearchParams] = useSearchParams();\n\n const page = parseInt(searchParams.get(\"page\") || \"1\", 10);\n const pageSize = parseInt(searchParams.get(\"pageSize\") || \"20\", 10);\n const filterTitle = searchParams.get(\"title\") || \"\";\n const filterURL = searchParams.get(\"url\") || \"\";\n const filterDifferences = searchParams.get(\"differences\") || \"\";\n const filterDifferencesOperation = getNumericOperation(filterDifferences);\n\n function TableHead({ id, title }: { id: string; title: string }) {\n return (\n <th\n onClick={() => {\n if (sort === id) {\n setSearchParams(\n createSearchParams({\n sort: id,\n sortReverse: JSON.stringify(!sortReverse),\n })\n );\n } else {\n setSearchParams(createSearchParams({ sort: id }));\n }\n }}\n className=\"sortable\"\n >\n {title} {sort === id ? (sortReverse ? \"↓\" : \"↑\") : null}\n </th>\n );\n }\n\n const filteredDocuments = documents\n .filter((document) => {\n if (\n filterTitle &&\n !document.title.toLowerCase().includes(filterTitle.toLowerCase())\n ) {\n return false;\n }\n\n if (\n filterURL &&\n !document.mdn_url.toLowerCase().includes(filterURL.toLowerCase())\n ) {\n return false;\n }\n\n if (\n filterDifferencesOperation &&\n !matchNumericOperation(\n document.differences.total,\n filterDifferencesOperation\n )\n ) {\n return false;\n }\n\n return true;\n })\n .sort((A, B) => {\n let reverse = sortReverse ? -1 : 1;\n if (sort === \"modified\") {\n const a = new Date(A.edits.modified);\n const b = new Date(B.edits.modified);\n return reverse * (b.getTime() - a.getTime());\n } else if (sort === \"popularity\") {\n const a = A.popularity.value;\n const b = B.popularity.value;\n return reverse * (b - a);\n } else if (sort === \"differences\") {\n const a = A.differences.total;\n const b = B.differences.total;\n return reverse * (b - a);\n } else if (sort === \"title\") {\n const a = A.title;\n const b = B.title;\n return reverse * a.localeCompare(b);\n } else if (sort === \"mdn_url\") {\n const a = A.mdn_url;\n const b = B.mdn_url;\n return reverse * a.localeCompare(b);\n } else if (sort === \"sourceCommit\") {\n const a = A.edits.sourceCommitsBehindCount ?? -1;\n const b = B.edits.sourceCommitsBehindCount ?? -1;\n return reverse * (b - a);\n } else {\n throw new Error(`Unrecognized sort '${sort}'`);\n }\n });\n const pageCount = Math.ceil(counts.found / pageSize);\n\n return (\n <div className=\"documents\">\n <h3>\n Documents with differences found (\n {filteredDocuments.length.toLocaleString()}){\" \"}\n {pageCount > 1 && (\n <span className=\"page\">\n page {page}/{pageCount}\n </span>\n )}\n </h3>\n <h4 className=\"subheader\">\n {counts.total.toLocaleString()} total documents found ({locale})\n </h4>\n\n {filterDifferences && !filterDifferencesOperation && (\n <div className=\"error-message\">\n <h3>Invalid differences filter</h3>\n <p>\n The <i>differences</i> filter can't be parsed.\n <br />\n <code>{filterDifferences}</code>\n </p>\n </div>\n )}\n\n <table>\n <thead>\n <tr>\n <TableHead id=\"title\" title=\"Document\" />\n <TableHead id=\"popularity\" title=\"Popularity\" />\n <TableHead id=\"modified\" title=\"Last modified\" />\n <TableHead id=\"differences\" title=\"Differences\" />\n <TableHead id=\"sourceCommit\" title=\"Source Commit\" />\n </tr>\n </thead>\n <tbody>\n {filteredDocuments\n .slice((page - 1) * pageSize, page * pageSize)\n .map((doc: Document) => {\n return (\n <tr key={doc.mdn_url}>\n <td>\n <span className=\"document-title-preview\">\n {filterTitle ? (\n <HighlightedText\n text={doc.title}\n highlight={filterTitle}\n />\n ) : (\n doc.title\n )}\n </span>\n <br />\n <Link\n to={`${doc.mdn_url}#_flaws`}\n title={doc.title}\n target=\"_blank\"\n >\n <BriefURL uri={doc.mdn_url} filterURL={filterURL} />\n </Link>\n </td>\n <td\n title={\n doc.popularity.ranking\n ? `Meaning there are ${\n doc.popularity.ranking - 1\n } more popular pages than this`\n : \"Meaning it has no ranking. Most likely a very rare (or new) document\"\n }\n >\n {!doc.popularity.ranking\n ? \"n/a\"\n : `${getGetOrdinal(doc.popularity.ranking)}`}{\" \"}\n <small title=\"For the parent document\">\n (\n {!doc.popularity.parentRanking\n ? \"n/a\"\n : `${getGetOrdinal(doc.popularity.parentRanking)}`}\n )\n </small>\n </td>\n <td>\n <LastModified edits={doc.edits} />\n </td>\n <td>{doc.differences.total.toLocaleString()}</td>\n <td>\n <L10nSourceCommitModified\n sourceCommitsBehindCount={\n doc.edits.sourceCommitsBehindCount\n }\n sourceCommitURL={doc.edits.sourceCommitURL}\n />\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n\n <Paginator last={pageCount} />\n </div>\n );\n}\n\nfunction L10nSourceCommitModified({\n sourceCommitsBehindCount,\n sourceCommitURL,\n}: Pick<DocumentEdits, \"sourceCommitsBehindCount\" | \"sourceCommitURL\">) {\n if (\n !sourceCommitURL ||\n (!sourceCommitsBehindCount && sourceCommitsBehindCount !== 0)\n ) {\n return <>Metadata does not exist.</>;\n }\n\n const getImportanceColor = () => {\n if (sourceCommitsBehindCount === 0) return \"🟢\";\n return sourceCommitsBehindCount < 10 ? \"🟠\" : \"🔴\";\n };\n\n return (\n <a\n href={sourceCommitURL}\n >{`${getImportanceColor()} ${sourceCommitsBehindCount} commits behind`}</a>\n );\n}\n\nfunction LastModified({ edits }: { edits: DocumentEdits }) {\n const modified = dayjs(edits.modified);\n const parentModified = dayjs(edits.parentModified);\n return (\n <span\n className={`last_modified ${\n parentModified < modified ? \"ahead\" : \"behind\"\n }`}\n >\n <a href={edits.commitURL} target=\"_blank\" rel=\"noreferrer\">\n <time dateTime={modified.toISOString()} title={modified.toISOString()}>\n {modified.fromNow()}\n </time>\n </a>\n <br />\n <a href={edits.parentCommitURL} target=\"_blank\" rel=\"noreferrer\">\n <small>\n <time\n dateTime={parentModified.toISOString()}\n title={parentModified.toISOString()}\n >\n en-US {parentModified.fromNow()}\n </time>\n </small>\n </a>\n </span>\n );\n}\n\nfunction HighlightedText({\n text,\n highlight,\n}: {\n text: string;\n highlight: string;\n}) {\n // Split on highlight term and include term into parts, ignore case\n const parts = text.split(new RegExp(`(${highlight})`, \"gi\"));\n return (\n <span>\n {\" \"}\n {parts.map((part, i) => (\n <span\n key={i}\n style={\n part.toLowerCase() === highlight.toLowerCase()\n ? { fontWeight: \"bold\" }\n : {}\n }\n >\n {part}\n </span>\n ))}{\" \"}\n </span>\n );\n}\n\nfunction BriefURL({ uri, filterURL }: { uri: string; filterURL: string }) {\n const [left, right] = uri.split(/\\/docs\\//, 2);\n return (\n <>\n <span className=\"url-prefix\">{left}/docs/</span>\n <span className=\"url-slug\">\n {filterURL ? (\n <HighlightedText text={right} highlight={filterURL} />\n ) : (\n right\n )}\n </span>\n </>\n );\n}\n\n// https://gist.github.com/jlbruno/1535691/db35b4f3af3dcbb42babc01541410f291a8e8fac\nfunction getGetOrdinal(n: number) {\n const s = [\"th\", \"st\", \"nd\", \"rd\"];\n const v = n % 100;\n return n.toLocaleString() + (s[(v - 20) % 10] || s[v] || s[0]);\n}\n","import React from \"react\";\nimport {\n createSearchParams,\n Link,\n useSearchParams,\n useNavigate,\n} from \"react-router-dom\";\nimport useSWR from \"swr\";\nimport dayjs from \"dayjs\";\nimport relativeTime from \"dayjs/plugin/relativeTime\";\n\nimport { MainContentContainer } from \"../../ui/atoms/page-content\";\nimport { Paginator } from \"../../ui/molecules/paginator\";\nimport { useLocale } from \"../../hooks\";\n\ndayjs.extend(relativeTime);\n\ninterface DocumentPopularity {\n value: number;\n ranking: number;\n parentValue: number;\n parentRanking: number;\n}\n\ntype CountByType = { [key: string]: number };\n\ninterface DocumentDifferences {\n countByType: CountByType;\n total: number;\n}\n\ninterface DocumentEdits {\n modified: string;\n parentModified: string;\n commitURL: string;\n parentCommitURL: string;\n}\n\ninterface Document {\n mdn_url: string;\n edits: DocumentEdits;\n title: string;\n popularity: DocumentPopularity;\n differences: DocumentDifferences;\n}\n\ninterface Counts {\n missing: number;\n translated: number;\n total: number;\n cacheMisses: number;\n}\n\ninterface Times {\n took: number;\n}\n\ninterface FlawLevel {\n name: string;\n level: string;\n ignored: boolean;\n}\n\ninterface Data {\n counts: Counts;\n missingDocuments: Document[];\n times: Times;\n flawLevels: FlawLevel[];\n}\n\ninterface LocaleStorageData {\n lastLoadTime?: number;\n defaultSort?: string;\n defaultSortReverse?: string;\n}\n\ninterface StorageData {\n [locale: string]: LocaleStorageData;\n}\n\nconst LOCALSTORAGE_KEY = \"translations-dashboard-missing\";\n\nfunction saveStorage(locale: string, data: LocaleStorageData) {\n try {\n const stored = JSON.parse(\n localStorage.getItem(LOCALSTORAGE_KEY) || \"{}\"\n ) as StorageData;\n stored[locale] = Object.assign({}, stored[locale] || {}, data);\n localStorage.setItem(LOCALSTORAGE_KEY, JSON.stringify(stored));\n } catch (err) {\n console.warn(\"Unable to save to localStorage\", err);\n }\n}\n\nfunction getStorage(locale: string): LocaleStorageData | null {\n try {\n const stored = JSON.parse(localStorage.getItem(LOCALSTORAGE_KEY) || \"{}\");\n if (stored) {\n return stored[locale] as LocaleStorageData;\n }\n } catch (err) {\n console.warn(\"Unable to retrieve from localStorage\", err);\n }\n return null;\n}\n\nexport function MissingTranslations() {\n const locale = useLocale();\n const [searchParams] = useSearchParams();\n const navigate = useNavigate();\n\n const [lastData, setLastData] = React.useState<Data | null>(null);\n\n React.useEffect(() => {\n if (locale.toLowerCase() === \"en-us\") {\n navigate(`/${locale}/_translations`);\n }\n }, [locale, navigate]);\n\n React.useEffect(() => {\n let title = \"Missing translations\";\n if (locale.toLowerCase() !== \"en-us\") {\n title += ` for ${locale}`;\n }\n if (lastData) {\n title = `(${lastData.counts.missing.toLocaleString()} found) ${title}`;\n }\n document.title = title;\n }, [lastData, locale]);\n\n const { data, error, isValidating } = useSWR<Data, Error>(\n locale.toLowerCase() !== \"en-us\"\n ? `/_translations/missing/?locale=${locale}`\n : null,\n async (url) => {\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`${response.status} (${await response.text()})`);\n }\n if (\n !(response.headers.get(\"content-type\") || \"\").includes(\n \"application/json\"\n )\n ) {\n throw new Error(\n `Response is not JSON (${response.headers.get(\"content-type\")})`\n );\n }\n return response.json();\n },\n {\n revalidateOnFocus: false,\n }\n );\n\n // Use this to be able to figure out how long the XHR takes when there's no cache\n const startTime = React.useRef<Date>();\n React.useEffect(() => {\n if (locale) {\n if (!data) {\n startTime.current = new Date();\n } else {\n if (\n data.counts.cacheMisses > 0 &&\n data.counts.cacheMisses === data.counts.total &&\n startTime.current\n ) {\n const lastLoadTime =\n new Date().getTime() - startTime.current.getTime();\n saveStorage(locale, { lastLoadTime });\n }\n }\n }\n }, [locale, data]);\n\n React.useEffect(() => {\n if (data) {\n setLastData(data);\n }\n }, [data]);\n\n const lastStorageData = getStorage(locale);\n const defaultSort = lastStorageData?.defaultSort || \"popularity\";\n const defaultSortReverse = lastStorageData?.defaultSortReverse || \"false\";\n const sort = searchParams.get(\"sort\") || defaultSort;\n const sortReverse = JSON.parse(\n searchParams.get(\"sortReverse\") || defaultSortReverse\n );\n\n React.useEffect(() => {\n saveStorage(\n locale,\n Object.assign({}, lastStorageData, {\n defaultSort: sort,\n defaultSortReverse: sortReverse,\n })\n );\n }, [locale, sort, sortReverse, lastStorageData]);\n\n if (locale.toLowerCase() === \"en-us\") {\n return null;\n }\n\n return (\n <Container>\n {lastData && !error && isValidating && (\n <p style={{ float: \"right\" }}>Reloading...</p>\n )}\n {!data && !error && !lastData && (\n <Loading\n estimate={\n (lastStorageData && lastStorageData.lastLoadTime) || 30 * 1000\n }\n />\n )}\n {lastData && (\n <p style={{ textAlign: \"right\" }}>\n Go to{\" \"}\n <Link to={`/${locale}/_translations/differences`}>\n Translation differences for <b>{locale}</b>\n </Link>\n </p>\n )}\n {error && <ShowSearchError error={error} />}\n {lastData && (\n <div className=\"filter-documents\">\n <FilterControls />\n <DocumentsTable\n counts={lastData.counts}\n documents={lastData.missingDocuments}\n sort={sort}\n sortReverse={sortReverse}\n />\n </div>\n )}\n {data && <BuildTimes times={data.times} />}\n </Container>\n );\n}\n\nfunction Container({ children }: { children: React.ReactNode }) {\n return (\n <MainContentContainer className=\"missing-translations\" standalone={true}>\n {children}\n </MainContentContainer>\n );\n}\n\nfunction ShowSearchError({ error }) {\n return (\n <div className=\"error-message search-error\">\n <h3>Search error</h3>\n <pre>{error.toString()}</pre>\n </div>\n );\n}\n\nfunction BuildTimes({ times }: { times: Times }) {\n function format(ms: number) {\n if (ms > 1000) {\n const s = ms / 1000;\n return `${s.toFixed(1)} seconds`;\n } else {\n return `${Math.trunc(ms)} milliseconds`;\n }\n }\n return (\n <div className=\"search-times\">\n <p>Time to find all documents {format(times.took)}</p>\n </div>\n );\n}\n\nfunction Loading({ estimate }: { estimate: number }) {\n const startLoadingTime = new Date();\n const [estimateEndTime] = React.useState(\n new Date(startLoadingTime.getTime() + estimate)\n );\n\n const [, setIncrements] = React.useState(0);\n React.useEffect(() => {\n const interval = setInterval(() => {\n setIncrements((state) => state + 1);\n }, 1000);\n return () => clearInterval(interval);\n }, []);\n\n const distance = estimateEndTime.getTime() - startLoadingTime.getTime();\n const elapsed = new Date().getTime() - startLoadingTime.getTime();\n const percent = (100 * elapsed) / distance;\n return (\n <div className=\"loading\">\n <progress id=\"progress\" max=\"100\" value={percent} style={{ margin: 20 }}>\n {percent}%\n </progress>\n <br />\n <small>\n Estimated time to finish: {((distance - elapsed) / 1000).toFixed(0)}s{\" \"}\n {elapsed > distance ? (\n <span aria-label=\"weird\" role=\"img\">\n 🙃\n </span>\n ) : null}\n </small>\n </div>\n );\n}\n\nfunction FilterControls() {\n const [searchParams, setSearchParams] = useSearchParams();\n const [title, setTitle] = React.useState(searchParams.get(\"title\") || \"\");\n const [url, setURL] = React.useState(searchParams.get(\"url\") || \"\");\n\n function refreshFilters(reset = false) {\n const filterParams = createSearchParams(searchParams);\n for (const [key, value] of [\n [\"url\", url],\n [\"title\", title],\n ]) {\n if (!reset && value) {\n filterParams.set(key, value);\n } else {\n filterParams.delete(key);\n }\n }\n filterParams.delete(\"page\");\n setSearchParams(filterParams);\n }\n\n function resetFilters() {\n setURL(\"\");\n setTitle(\"\");\n refreshFilters(true);\n }\n\n return (\n <div className=\"filters\">\n <h3>Filters</h3>\n <form\n onSubmit={(event) => {\n event.preventDefault();\n refreshFilters();\n }}\n >\n <div>\n <h4>Document</h4>\n <input\n type=\"search\"\n placeholder=\"Filter by document URI\"\n value={url}\n onChange={(event) => {\n setURL(event.target.value);\n }}\n onBlur={() => refreshFilters()}\n />\n <input\n type=\"search\"\n placeholder=\"Filter by document title\"\n value={title}\n onChange={(event) => {\n setTitle(event.target.value);\n }}\n onBlur={() => refreshFilters()}\n />\n </div>\n\n <div>\n <h4>&nbsp;</h4>\n <button type=\"submit\">Filter now</button>{\" \"}\n {(url || title) && (\n <button type=\"button\" onClick={resetFilters}>\n Reset filters\n </button>\n )}\n </div>\n </form>\n </div>\n );\n}\ntype NumericOperation = {\n operation: \"eq\" | \"gt\" | \"gte\" | \"lt\" | \"lte\";\n value: number;\n};\n\nfunction getNumericOperation(expression: string): NumericOperation | null {\n function parseIntOrThrow(v: string) {\n if (!v) {\n throw new Error(\"Can't be empty\");\n }\n\n const parsed = parseInt(v, 10);\n if (isNaN(parsed)) {\n throw new Error(`'${v}' not a valid number`);\n }\n return parsed;\n }\n try {\n if (expression.startsWith(\">=\")) {\n return {\n operation: \"gte\",\n value: parseIntOrThrow(expression.replace(\">=\", \"\")),\n };\n } else if (expression.startsWith(\">\")) {\n return {\n operation: \"gt\",\n value: parseIntOrThrow(expression.replace(\">\", \"\")),\n };\n } else if (expression.startsWith(\"<=\")) {\n return {\n operation: \"lte\",\n value: parseIntOrThrow(expression.replace(\"<=\", \"\")),\n };\n } else if (expression.startsWith(\"<\")) {\n return {\n operation: \"lt\",\n value: parseIntOrThrow(expression.replace(\"<\", \"\")),\n };\n } else if (expression.startsWith(\"==\") || expression.startsWith(\"=\")) {\n return {\n operation: \"eq\",\n value: parseIntOrThrow(expression.replace(/=/g, \"\")),\n };\n } else if (expression) {\n return {\n operation: \"eq\",\n value: parseIntOrThrow(expression),\n };\n } else {\n return null;\n }\n } catch (error) {\n console.warn(error);\n return null;\n }\n}\n\nfunction matchNumericOperation(value: number, op: NumericOperation): boolean {\n if (op.operation === \"eq\") {\n if (value !== op.value) {\n return false;\n }\n } else if (op.operation === \"gt\") {\n if (!(value > op.value)) {\n return false;\n }\n } else if (op.operation === \"gte\") {\n if (!(value >= op.value)) {\n return false;\n }\n } else if (op.operation === \"lt\") {\n if (!(value < op.value)) {\n return false;\n }\n } else if (op.operation === \"lte\") {\n if (!(value <= op.value)) {\n return false;\n }\n } else {\n throw new Error(`Not implemented operation '${op.operation}'`);\n }\n return true;\n}\n\nfunction DocumentsTable({\n counts,\n documents,\n sort,\n sortReverse,\n}: {\n counts: Counts;\n documents: Document[];\n sort: string;\n sortReverse: boolean;\n}) {\n const [searchParams, setSearchParams] = useSearchParams();\n\n const page = parseInt(searchParams.get(\"page\") || \"1\", 10);\n const pageSize = parseInt(searchParams.get(\"pageSize\") || \"20\", 10);\n const filterTitle = searchParams.get(\"title\") || \"\";\n const filterURL = searchParams.get(\"url\") || \"\";\n const filterDifferences = searchParams.get(\"differences\") || \"\";\n const filterDifferencesOperation = getNumericOperation(filterDifferences);\n\n function TableHead({ id, title }: { id: string; title: string }) {\n return (\n <th\n onClick={() => {\n if (sort === id) {\n setSearchParams(\n createSearchParams({\n sort: id,\n sortReverse: JSON.stringify(!sortReverse),\n })\n );\n } else {\n setSearchParams(createSearchParams({ sort: id }));\n }\n }}\n className=\"sortable\"\n >\n {title} {sort === id ? (sortReverse ? \"↓\" : \"↑\") : null}\n </th>\n );\n }\n\n const filteredDocuments = documents\n .filter((document) => {\n if (\n filterTitle &&\n !document.title.toLowerCase().includes(filterTitle.toLowerCase())\n ) {\n return false;\n }\n\n if (\n filterURL &&\n !document.mdn_url.toLowerCase().includes(filterURL.toLowerCase())\n ) {\n return false;\n }\n\n if (\n filterDifferencesOperation &&\n !matchNumericOperation(\n document.differences.total,\n filterDifferencesOperation\n )\n ) {\n return false;\n }\n\n return true;\n })\n .sort((A, B) => {\n let reverse = sortReverse ? -1 : 1;\n if (sort === \"modified\") {\n const a = new Date(A.edits.modified);\n const b = new Date(B.edits.modified);\n return reverse * (b.getTime() - a.getTime());\n } else if (sort === \"popularity\") {\n const a = A.popularity.value;\n const b = B.popularity.value;\n return reverse * (b - a);\n } else if (sort === \"differences\") {\n const a = A.differences.total;\n const b = B.differences.total;\n return reverse * (b - a);\n } else if (sort === \"title\") {\n const a = A.title;\n const b = B.title;\n return reverse * a.localeCompare(b);\n } else if (sort === \"mdn_url\") {\n const a = A.mdn_url;\n const b = B.mdn_url;\n return reverse * a.localeCompare(b);\n } else {\n throw new Error(`Unrecognized sort '${sort}'`);\n }\n });\n const pageCount = Math.ceil(counts.total / pageSize);\n\n return (\n <div className=\"documents\">\n <h3>\n {counts.missing.toLocaleString()} missing translations (of{\" \"}\n {counts.total.toLocaleString()} possible)\n </h3>\n\n <table>\n <thead>\n <tr>\n <TableHead id=\"title\" title=\"Document\" />\n <TableHead id=\"popularity\" title=\"Popularity\" />\n <TableHead id=\"modified\" title=\"Last modified\" />\n </tr>\n </thead>\n <tbody>\n {filteredDocuments\n .slice((page - 1) * pageSize, page * pageSize)\n .map((doc: Document) => {\n return (\n <tr key={doc.mdn_url}>\n <td>\n <span className=\"document-title-preview\">\n {filterTitle ? (\n <HighlightedText\n text={doc.title}\n highlight={filterTitle}\n />\n ) : (\n doc.title\n )}\n </span>\n <br />\n <Link\n to={`${doc.mdn_url}#_flaws`}\n title={doc.title}\n target=\"_blank\"\n >\n <BriefURL uri={doc.mdn_url} filterURL={filterURL} />\n </Link>\n </td>\n <td\n title={\n doc.popularity.ranking\n ? `Meaning there are ${\n doc.popularity.ranking - 1\n } more popular pages than this`\n : \"Meaning it has no ranking. Most likely a very rare (or new) document\"\n }\n >\n {!doc.popularity.ranking\n ? \"n/a\"\n : `${getGetOrdinal(doc.popularity.ranking)}`}{\" \"}\n </td>\n <td>\n <LastModified edits={doc.edits} />\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n\n <Paginator last={pageCount} />\n </div>\n );\n}\n\nfunction LastModified({ edits }: { edits: DocumentEdits }) {\n const modified = dayjs(edits.modified);\n return (\n <span className=\"last_modified\">\n <a href={edits.commitURL} target=\"_blank\" rel=\"noreferrer\">\n <time dateTime={modified.toISOString()} title={modified.toISOString()}>\n {modified.fromNow()}\n </time>\n </a>\n </span>\n );\n}\n\nfunction HighlightedText({\n text,\n highlight,\n}: {\n text: string;\n highlight: string;\n}) {\n // Split on highlight term and include term into parts, ignore case\n const parts = text.split(new RegExp(`(${highlight})`, \"gi\"));\n return (\n <span>\n {\" \"}\n {parts.map((part, i) => (\n <span\n key={i}\n style={\n part.toLowerCase() === highlight.toLowerCase()\n ? { fontWeight: \"bold\" }\n : {}\n }\n >\n {part}\n </span>\n ))}{\" \"}\n </span>\n );\n}\n\nfunction BriefURL({ uri, filterURL }: { uri: string; filterURL: string }) {\n const [left, right] = uri.split(/\\/docs\\//, 2);\n return (\n <>\n <span className=\"url-prefix\">{left}/docs/</span>\n <span className=\"url-slug\">\n {filterURL ? (\n <HighlightedText text={right} highlight={filterURL} />\n ) : (\n right\n )}\n </span>\n </>\n );\n}\n\n// https://gist.github.com/jlbruno/1535691/db35b4f3af3dcbb42babc01541410f291a8e8fac\nfunction getGetOrdinal(n: number) {\n const s = [\"th\", \"st\", \"nd\", \"rd\"];\n const v = n % 100;\n return n.toLocaleString() + (s[(v - 20) % 10] || s[v] || s[0]);\n}\n","import React from \"react\";\nimport {\n createSearchParams,\n Link,\n useSearchParams,\n useNavigate,\n} from \"react-router-dom\";\nimport useSWR from \"swr\";\n\nimport { MainContentContainer } from \"../../ui/atoms/page-content\";\nimport { Icon } from \"../../ui/atoms/icon\";\nimport { useLocale } from \"../../hooks\";\n\ninterface Data {\n l10nKPIs: L10nKPIs;\n sections: Section[];\n detailDocuments: DetailDocument[];\n}\n\ninterface Section {\n l10nKPIs: L10nKPIs;\n name: string;\n}\n\ninterface L10nKPIs {\n missing: number;\n outOfDate: number;\n upToDate: number;\n total: number;\n}\n\ninterface DetailDocument {\n url: string;\n info: InfoDocument;\n}\n\ninterface InfoDocument {\n popularity: DocumentPopularity;\n localePopularity: DocumentPopularity;\n defaultLocaleInfo: LocaleInfo;\n localeInfo?: LocaleInfo;\n dateDiff?: number;\n}\n\ninterface DocumentPopularity {\n value: number;\n ranking: number;\n parentValue: number;\n parentRanking: number;\n}\n\ninterface LocaleInfo {\n modified: string;\n commitURL: string;\n}\n\ninterface LocaleStorageData {\n defaultSort?: string;\n defaultSortReverse?: string;\n}\n\ninterface StorageData {\n [locale: string]: LocaleStorageData;\n}\n\nconst LOCALSTORAGE_KEY = \"translations-dashboard-sections\";\n\nfunction saveStorage(locale: string, data: LocaleStorageData) {\n try {\n const stored = JSON.parse(\n localStorage.getItem(LOCALSTORAGE_KEY) || \"{}\"\n ) as StorageData;\n stored[locale] = Object.assign({}, stored[locale] || {}, data);\n localStorage.setItem(LOCALSTORAGE_KEY, JSON.stringify(stored));\n } catch (err) {\n console.warn(\"Unable to save to localStorage\", err);\n }\n}\n\nfunction getStorage(locale: string): LocaleStorageData | null {\n try {\n const stored = JSON.parse(localStorage.getItem(LOCALSTORAGE_KEY) || \"{}\");\n if (stored) {\n return stored[locale] as LocaleStorageData;\n }\n } catch (err) {\n console.warn(\"Unable to retrieve from localStorage\", err);\n }\n return null;\n}\n\nexport function TranslationDashboard() {\n const locale = useLocale();\n const [searchParams] = useSearchParams();\n const navigate = useNavigate();\n\n const [lastData, setLastData] = React.useState<Data | null>(null);\n\n const currentSection = searchParams.get(\"section\") || \"\";\n React.useEffect(() => {\n if (locale.toLowerCase() === \"en-us\") {\n navigate(`/${locale}/_translations`);\n }\n }, [locale, navigate]);\n\n React.useEffect(() => {\n let title = \"Translation dashboard \";\n if (locale.toLowerCase() !== \"en-us\") {\n title += ` for ${locale}`;\n }\n if (currentSection !== \"\") {\n title += ` - section ${currentSection}`;\n }\n document.title = title;\n }, [lastData, locale, currentSection]);\n\n let { data, error, isValidating } = useSWR<Data, Error>(\n locale.toLowerCase() !== \"en-us\"\n ? `/_translations/dashboard/?locale=${locale}&section=${currentSection}`\n : null,\n async (url) => {\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`${response.status} (${await response.text()})`);\n }\n if (\n !(response.headers.get(\"content-type\") || \"\").includes(\n \"application/json\"\n )\n ) {\n throw new Error(\n `Response is not JSON (${response.headers.get(\"content-type\")})`\n );\n }\n return response.json();\n },\n {\n revalidateOnFocus: false,\n }\n );\n\n React.useEffect(() => {\n if (data) {\n setLastData(data);\n }\n }, [data]);\n\n const lastStorageData = getStorage(locale);\n const defaultSort = lastStorageData?.defaultSort || \"url\";\n const defaultSortReverse = lastStorageData?.defaultSortReverse || \"false\";\n const sort = searchParams.get(\"sort\") || defaultSort;\n const sortReverse = JSON.parse(\n searchParams.get(\"sortReverse\") || defaultSortReverse\n );\n\n React.useEffect(() => {\n saveStorage(\n locale,\n Object.assign({}, lastStorageData, {\n defaultSort: sort,\n defaultSortReverse: sortReverse,\n })\n );\n }, [locale, sort, sortReverse, lastStorageData]);\n\n if (locale.toLowerCase() === \"en-us\") {\n return null;\n }\n\n let parentSection = \"/\";\n if (currentSection.split(\"/\").length > 2) {\n const arrPathSection = currentSection.split(\"/\");\n arrPathSection.pop();\n parentSection = arrPathSection.join(\"/\");\n }\n\n return (\n <Container>\n {lastData && !error && isValidating && (\n <p style={{ float: \"right\" }}>Reloading...</p>\n )}\n {!data && !error && !lastData && <Loading />}\n {lastData && (\n <p style={{ textAlign: \"right\" }}>\n Go to{\" \"}\n <Link to={`/${locale}/_translations/differences`}>\n Translation differences for <b>{locale}</b>\n </Link>\n {\" / \"}\n <Link to={`/${locale}/_translations/missing`}>\n Missing translations for <b>{locale}</b>\n </Link>\n </p>\n )}\n {error && <ShowError error={error} />}\n {lastData && (\n <div>\n <SectionHeader\n l10nKPIs={lastData.l10nKPIs}\n section={currentSection}\n parentSection={parentSection}\n />\n <SubsectionTable\n sections={lastData.sections}\n currentSection={currentSection}\n />\n <DocumentsTable\n documents={lastData.detailDocuments}\n sort={sort}\n sortReverse={sortReverse}\n locale={locale}\n />\n </div>\n )}\n </Container>\n );\n /*\n );\n }\n */\n}\n\nfunction Container({ children }: { children: React.ReactNode }) {\n return (\n <div className=\"dashboard-section-translations\">\n <MainContentContainer standalone={true}>{children}</MainContentContainer>\n </div>\n );\n}\n\nfunction ShowError({ error }) {\n return (\n <div className=\"error-message\">\n <h3>Error</h3>\n <pre>{error.toString()}</pre>\n </div>\n );\n}\n\nfunction Loading() {\n return (\n <div>\n <label htmlFor=\"progress\">Loading</label>\n <progress id=\"progress\" max=\"100\" style={{ margin: 20 }}></progress>\n </div>\n );\n}\n\nfunction SectionHeader({\n l10nKPIs,\n section,\n parentSection,\n}: {\n l10nKPIs: L10nKPIs;\n section: string;\n parentSection: string;\n}) {\n const completenessExact =\n (100 * (l10nKPIs.total - l10nKPIs.missing)) / l10nKPIs.total;\n const completenessStr = completenessExact.toFixed(1) + \"%\";\n const freshnessExact = (100 * l10nKPIs.upToDate) / l10nKPIs.total;\n const freshnessStr = freshnessExact.toFixed(1) + \"%\";\n return (\n <div className=\"documents\">\n <h2>Localization dashboard for: {section || \"/\"}</h2>\n <p>\n Parent section:{\" \"}\n <a href={`dashboard?section=${parentSection}`}>{parentSection}</a>\n </p>\n <h3>Summary</h3>\n <dl>\n <dt>Total number of pages</dt>\n <dd>{l10nKPIs.total}</dd>\n <dt>Number of untranslated pages</dt>\n <dd>{l10nKPIs.missing}</dd>\n <dt>Number of outdated pages (older than English in Git) </dt>\n <dd>{l10nKPIs.outOfDate}</dd>\n <dt>Number of up-to-date pages</dt>\n <dd>{l10nKPIs.upToDate}</dd>\n <dt>\n <label htmlFor=\"completeness\">Localization completeness</label>\n </dt>\n <dd>\n <progress id=\"completeness\" max=\"100\" value={completenessExact}>\n {completenessStr}\n </progress>{\" \"}\n {completenessStr}\n </dd>\n <dt>\n <label htmlFor=\"freshness\">Localization freshness</label>\n </dt>\n <dd>\n <progress id=\"freshness\" max=\"100\" value={freshnessExact}>\n {freshnessStr}\n </progress>{\" \"}\n {freshnessStr}\n </dd>\n </dl>\n </div>\n );\n}\n\nfunction SubsectionTable({\n sections,\n currentSection,\n}: {\n sections: Section[];\n currentSection: string;\n}) {\n if (sections.length > 0) {\n return (\n <section id=\"subsection-table\">\n <h3>Subsections</h3>\n <table>\n <thead>\n <tr>\n <th>Section</th>\n <th>Total / Untranslated / Out of date</th>\n <th>Completeness</th>\n <th>Freshness</th>\n </tr>\n </thead>\n <tbody>\n {sections\n .sort(\n (sectionA, sectionB) =>\n sectionB.l10nKPIs.total - sectionA.l10nKPIs.total\n )\n .map((section) => {\n const completenessExact =\n (100 * (section.l10nKPIs.total - section.l10nKPIs.missing)) /\n section.l10nKPIs.total;\n const completenessStr = completenessExact.toFixed(1) + \"%\";\n const freshnessExact =\n (100 * section.l10nKPIs.upToDate) / section.l10nKPIs.total;\n const freshnessStr = freshnessExact.toFixed(1) + \"%\";\n const sectionHref =\n \"dashboard?section=%2F\" + encodeURIComponent(section.name);\n return (\n <tr key={section.name}>\n <td>\n <a href={sectionHref}>\n {section.name\n .replace(currentSection.slice(1), \"\")\n .replace(\"/\", \"\")}\n </a>\n </td>\n <td>\n {section.l10nKPIs.total} / {section.l10nKPIs.missing} /{\" \"}\n {section.l10nKPIs.outOfDate}\n </td>\n <td>\n <progress max=\"100\" value={completenessExact}>\n {completenessStr}\n </progress>{\" \"}\n {completenessStr}\n </td>\n <td>\n <progress max=\"100\" value={freshnessExact}>\n {freshnessStr}\n </progress>{\" \"}\n {freshnessStr}\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </section>\n );\n } else {\n return null;\n }\n}\n\nfunction DocumentsTable({\n documents,\n sort,\n sortReverse,\n locale,\n}: {\n documents: DetailDocument[];\n sort: string;\n sortReverse: boolean;\n locale: string;\n}) {\n const [searchParams, setSearchParams] = useSearchParams();\n const currentSection = searchParams.get(\"section\") || \"\";\n documents.map((documentDetail) => {\n if (documentDetail.info.localeInfo) {\n const dateLocale = new Date(documentDetail.info.localeInfo.modified);\n const dateDefaultLocale = new Date(\n documentDetail.info.defaultLocaleInfo.modified\n );\n const dateDiff = dateLocale.getTime() - dateDefaultLocale.getTime();\n documentDetail.info.dateDiff = dateDiff;\n } else {\n documentDetail.info.dateDiff = Number.POSITIVE_INFINITY;\n }\n return documentDetail;\n });\n\n function TableHead({\n id,\n title,\n sortable,\n }: {\n id: string;\n title: string;\n sortable?: boolean;\n }) {\n function getClassName() {\n const className = [\"sortable\"];\n\n if (sort === id) {\n className.push(\"active\");\n }\n\n if (sortReverse) {\n className.push(\"reverse\");\n }\n\n return className.join(\" \");\n }\n\n function onClick() {\n if (sort === id) {\n setSearchParams(\n createSearchParams({\n sort: id,\n sortReverse: JSON.stringify(!sortReverse),\n section: currentSection,\n })\n );\n } else {\n setSearchParams(\n createSearchParams({ sort: id, section: currentSection })\n );\n }\n }\n\n return sortable ? (\n <th className={getClassName()} onClick={onClick}>\n {title} <Icon name=\"small-arrow\" />\n </th>\n ) : (\n <th>{title}</th>\n );\n }\n\n return (\n <section id=\"documents-table\">\n <h3>List of direct subpages</h3>\n\n <table>\n <thead>\n <tr>\n <TableHead id=\"url\" title=\"Slug\" sortable />\n <TableHead id=\"enMDNURL\" title=\"English doc on MDN\" />\n <TableHead\n id=\"enCommitGHURL\"\n title=\"English doc commit on GitHub\"\n />\n <TableHead id=\"localURL\" title=\"Local localized doc\" />\n <TableHead id=\"localMDNURL\" title=\"Localized doc on MDN\" />\n <TableHead\n id=\"localCommitGHURL\"\n title=\"Localized doc commit on GitHub\"\n />\n <TableHead\n id=\"popularityEn\"\n title=\"Popularity rank (en-US)\"\n sortable\n />\n <TableHead\n id=\"popularityLocale\"\n title={`Popularity rank (${locale})`}\n sortable\n />\n <TableHead id=\"dateDiff\" title=\"Date delta\" sortable />\n </tr>\n </thead>\n\n <tbody>\n {documents\n .sort((A, B) => {\n let reverse = sortReverse ? -1 : 1;\n if (sort === \"dateDiff\") {\n const a = A.info.dateDiff || Number.POSITIVE_INFINITY;\n const b = B.info.dateDiff || Number.POSITIVE_INFINITY;\n return reverse * (b - a);\n } else if (sort === \"popularityLocale\") {\n const a =\n A.info.localePopularity?.ranking || Number.POSITIVE_INFINITY;\n const b =\n B.info.localePopularity?.ranking || Number.POSITIVE_INFINITY;\n return reverse * (a - b);\n } else if (sort === \"popularityEn\") {\n const a = A.info.popularity.ranking || Number.POSITIVE_INFINITY;\n const b = B.info.popularity.ranking || Number.POSITIVE_INFINITY;\n return reverse * (a - b);\n } else if (sort === \"url\") {\n const a = A.url;\n const b = B.url;\n return reverse * a.localeCompare(b);\n } else {\n throw new Error(`Unrecognized sort '${sort}'`);\n }\n })\n .map((documentDetail) => {\n const url = \"https://developer.mozilla.org\" + documentDetail.url;\n const englishCommitHash =\n documentDetail.info.defaultLocaleInfo.commitURL\n .split(\"commit/\")[1]\n .substring(0, 7);\n const localeCommitHash = documentDetail.info.localeInfo?.commitURL\n .split(\"commit/\")[1]\n .substring(0, 7);\n let status = \"Untranslated\";\n if (documentDetail.info.localeInfo) {\n let dateDiff =\n documentDetail.info.dateDiff ?? Number.POSITIVE_INFINITY;\n status = \"Out of date\";\n\n if (dateDiff > 0) {\n status = \"Fresher than English\";\n } else if (dateDiff > -2678400000) {\n const nbDays = Math.round(-dateDiff / (3600 * 24 * 1000));\n status = nbDays + \" day\" + (nbDays > 1 ? \"s\" : \"\");\n } else {\n const nbMonths = Math.round(\n -dateDiff / (3600 * 24 * 1000 * 30)\n );\n status = nbMonths + \" month\" + (nbMonths > 1 ? \"s\" : \"\");\n }\n }\n return (\n <tr key={documentDetail.url}>\n <td>\n <a href={documentDetail.url}>{documentDetail.url}</a>\n </td>\n <td>\n <a href={url}>English current MDN page</a>\n </td>\n <td>\n <a href={documentDetail.info.defaultLocaleInfo.commitURL}>\n GitHub link for <code>{englishCommitHash}</code>\n </a>\n </td>\n <td>\n {documentDetail.info.localeInfo && (\n <a\n href={documentDetail.url.replace(\n \"/en-US/\",\n \"/\" + locale + \"/\"\n )}\n >\n Local {locale} page\n </a>\n )}\n </td>\n <td>\n {documentDetail.info.localeInfo && (\n <a href={url.replace(\"/en-US/\", \"/\" + locale + \"/\")}>\n Locale current MDN page\n </a>\n )}\n </td>\n <td>\n {documentDetail.info.localeInfo && (\n <a href={documentDetail.info.localeInfo.commitURL}>\n GitHub link for <code>{localeCommitHash}</code>\n </a>\n )}\n </td>\n <td>{documentDetail.info.popularity.ranking}</td>\n <td>\n {documentDetail.info.localePopularity &&\n documentDetail.info.localePopularity.ranking}\n </td>\n <td>{status}</td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </section>\n );\n}\n","import React from \"react\";\nimport { Link, Routes, Route } from \"react-router-dom\";\nimport useSWR from \"swr\";\n\nimport \"./index.scss\";\n\nimport { Loading } from \"../ui/atoms/loading\";\nimport { MainContentContainer } from \"../ui/atoms/page-content\";\n\nimport { TranslationDifferences } from \"./differences\";\nimport { MissingTranslations } from \"./missing\";\nimport { TranslationDashboard } from \"./dashboard\";\nimport { useLocale } from \"../hooks\";\n\ninterface Locale {\n locale: string;\n language: {\n English: string;\n native: string;\n };\n isActive: boolean;\n count: number;\n}\n\ninterface LocalesData {\n locales: Locale[];\n}\n\nexport default function Translations() {\n return (\n <Container>\n <Routes>\n <Route path=\"/\" element={<PickLocale />} />\n <Route path=\"differences\" element={<TranslationDifferences />} />\n <Route path=\"missing\" element={<MissingTranslations />} />\n <Route path=\"dashboard\" element={<TranslationDashboard />} />\n </Routes>\n </Container>\n );\n}\n\nfunction PickLocale() {\n const locale = useLocale();\n React.useEffect(() => {\n let title = \"All translations\";\n if (locale.toLowerCase() !== \"en-us\") {\n title += ` for ${locale}`;\n }\n document.title = title;\n }, [locale]);\n\n const { data: dataLocales, error: errorLocales } = useSWR<LocalesData, Error>(\n locale.toLowerCase() === \"en-us\" ? \"/_translations/\" : null,\n async (url) => {\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`${response.status} (${await response.text()})`);\n }\n return response.json();\n }\n );\n\n if (locale.toLowerCase() === \"en-us\") {\n return (\n <>\n {!dataLocales && !errorLocales && <Loading />}\n {errorLocales && (\n <div className=\"error-message\">\n <h3>Server error</h3>\n <pre>{errorLocales.toString()}</pre>\n </div>\n )}\n {dataLocales && <ShowLocales locales={dataLocales.locales} />}\n </>\n );\n }\n\n return (\n <div className=\"translation-choices\">\n <Link to={`/${locale}/_translations/differences`} className=\"button\">\n Translation differences\n </Link>{\" \"}\n <Link to={`/${locale}/_translations/missing`} className=\"button\">\n Missing translations\n </Link>{\" \"}\n <Link to={`/${locale}/_translations/dashboard`} className=\"button\">\n Dashboard\n </Link>\n </div>\n );\n}\n\nfunction Container({ children }: { children: React.ReactNode }) {\n return (\n <MainContentContainer className=\"all-translations\" standalone={true}>\n {children}\n </MainContentContainer>\n );\n}\n\nfunction ShowLocales({ locales }: { locales: Locale[] }) {\n return (\n <div>\n <h2>Select locale</h2>\n <table>\n <tbody>\n {locales.map((locale) => {\n return (\n <tr key={locale.locale}>\n <td>\n <b>\n {locale.language.English} ({locale.locale})\n </b>{\" \"}\n {!locale.isActive && <small>not active</small>}\n </td>\n <td>{locale.count.toLocaleString()} documents</td>\n <td>\n <Link to={`/${locale.locale}/_translations/differences`}>\n Translation differences\n </Link>{\" \"}\n </td>\n <td>\n <Link to={`/${locale.locale}/_translations/missing`}>\n Missing translations\n </Link>{\" \"}\n </td>\n <td>\n <Link to={`/${locale.locale}/_translations/dashboard`}>\n Dashboard\n </Link>{\" \"}\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n );\n}\n","import { Link, useSearchParams } from \"react-router-dom\";\nimport { range } from \"../../../utils\";\n\nconst PARAM = \"page\";\n\nfunction PageLink({\n page,\n children,\n onClick,\n disabled,\n}: {\n page: number;\n children?: React.ReactNode;\n onClick?: (page: number) => unknown;\n disabled?: boolean;\n}) {\n const [searchParams, setSearchParams] = useSearchParams();\n\n return (\n <Link\n to={{}}\n className={disabled ? \"disabled\" : \"\"}\n onClick={(event) => {\n event.preventDefault();\n if (disabled) {\n return;\n }\n\n onClick && onClick(page);\n setSearchParams({\n ...Object.fromEntries(searchParams.entries()),\n [PARAM]: page.toString(),\n });\n\n window.setTimeout(() => document.documentElement.scrollTo());\n }}\n >\n {children || page}\n </Link>\n );\n}\n\nexport function Paginator({\n first = 1,\n last,\n endPadding = 2,\n middlePadding = 2,\n onChange,\n}: {\n first?: number;\n last: number;\n endPadding?: number;\n middlePadding?: number;\n onChange?: (page: number, oldPage: number) => unknown;\n}) {\n const [searchParams] = useSearchParams();\n const current = parseInt(searchParams.get(PARAM) || \"\", 10) || first;\n const middleFirst = Math.max(current - middlePadding, first);\n const middleLast = Math.min(middleFirst + middlePadding * 2 + 1, last + 1);\n const left = range(first, Math.min(endPadding, middleFirst));\n const middle = range(middleFirst, middleLast);\n const right = range(Math.max(last + 1 - endPadding, middleLast), last + 1);\n\n const onClick = (page: number) => {\n onChange && onChange(page, current);\n };\n\n if (first === last) {\n // There are no pages, so return nothing\n return <></>;\n }\n\n return (\n <div className=\"pagination\">\n <PageLink\n page={current - 1}\n onClick={onClick}\n disabled={current === first}\n >\n ← Previous\n </PageLink>\n {left.map((page) => (\n <PageLink key={page} page={page} onClick={onClick} />\n ))}\n {Boolean(left.length) && left[left.length - 1] + 1 !== middle[0] && \"…\"}\n {middle.map((page) =>\n current === page ? (\n <span className=\"current-page\" key={page}>\n {page}\n </span>\n ) : (\n <PageLink key={page} page={page} onClick={onClick} />\n )\n )}\n {Boolean(right.length) &&\n middle[middle.length - 1] + 1 !== right[0] &&\n \"…\"}\n {right.map((page) => (\n <PageLink key={page} page={page} onClick={onClick} />\n ))}\n <PageLink\n page={current + 1}\n onClick={onClick}\n disabled={current === last}\n >\n Next →\n </PageLink>\n </div>\n );\n}\n"],"names":["dayjs","relativeTime","LOCALSTORAGE_KEY","saveStorage","locale","data","stored","JSON","localStorage","Object","err","console","TranslationDifferences","useLocale","searchParams","_useSearchParams","navigate","useNavigate","_React_useState","lastData","setLastData","React","title","document","_useSWR","url","response","fetch","Error","n","error","isValidating","startTime","lastLoadTime","Date","lastStorageData","getStorage","defaultSort","defaultSortReverse","sort","sortReverse","Container","Loading","Link","ShowSearchError","FilterControls","DocumentsTable","BuildTimes","param","children","MainContentContainer","ms","times","s","Math","estimate","startLoadingTime","estimateEndTime","setIncrements","_React_useState1","interval","setInterval","state","clearInterval","distance","elapsed","percent","setSearchParams","setTitle","setURL","_React_useState2","differences","setDifferences","refreshFilters","reset","filterParams","createSearchParams","_iter","key","value","event","counts","documents","page","parseInt","pageSize","filterTitle","filterURL","filterDifferences","filterDifferencesOperation","getNumericOperation","expression","parseIntOrThrow","v","parsed","isNaN","TableHead","id","filteredDocuments","document1","matchNumericOperation","op","A","B","reverse","a","b","a1","b1","a2","b2","a3","b3","a4","b4","_A_edits_sourceCommitsBehindCount","_B_edits_sourceCommitsBehindCount","a5","b5","pageCount","doc","HighlightedText","BriefURL","getGetOrdinal","LastModified","L10nSourceCommitModified","Paginator","sourceCommitsBehindCount","sourceCommitURL","edits","modified","parentModified","text","highlight","parts","RegExp","part","i","uri","_uri_split","left","right","MissingTranslations","TranslationDashboard","currentSection","parentSection","arrPathSection","ShowError","SectionHeader","SubsectionTable","l10nKPIs","section","completenessExact","completenessStr","freshnessExact","freshnessStr","sections","sectionA","sectionB","sectionHref","encodeURIComponent","className","sortable","Icon","documentDetail","dateLocale","dateDefaultLocale","dateDiff","Number","_A_info_localePopularity","_B_info_localePopularity","englishCommitHash","localeCommitHash","_documentDetail_info_localeInfo","status","_documentDetail_info_dateDiff","nbDays","nbMonths","Translations","Routes","Route","PickLocale","dataLocales","errorLocales","ShowLocales","locales","PARAM","PageLink","onClick","disabled","window","first","last","endPadding","middlePadding","onChange","current","middleFirst","middleLast","range","middle","Boolean"],"mappings":"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"}