ccdeck 3.40.1 → 3.41.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 (282) hide show
  1. package/README.md +10 -3
  2. package/THIRD_PARTY_NOTICES.md +29 -0
  3. package/dist/web/assets/{BrowserWatchModal-C07nz8O3.js → BrowserWatchModal-s7_Wr7WT.js} +1 -1
  4. package/dist/web/assets/RadioPanel-UcoMDWAH.js +1 -0
  5. package/dist/web/assets/TrafficRadar-9Qlon_77.js +1 -0
  6. package/dist/web/assets/{UsageHistoryModal-DNMj-rt1.js → UsageHistoryModal-CGh4GESl.js} +1 -1
  7. package/dist/web/assets/ad-B18i8NGa.svg +150 -0
  8. package/dist/web/assets/ae-CZRtWSox.svg +6 -0
  9. package/dist/web/assets/af-C77Rf6cE.svg +81 -0
  10. package/dist/web/assets/ag-C8MykuG2.svg +14 -0
  11. package/dist/web/assets/ai-Dmedkf4v.svg +29 -0
  12. package/dist/web/assets/al-10QRkakw.svg +5 -0
  13. package/dist/web/assets/am-DMt4_dd4.svg +5 -0
  14. package/dist/web/assets/ao-tXuRa6vm.svg +13 -0
  15. package/dist/web/assets/aq-CF5jO-0h.svg +5 -0
  16. package/dist/web/assets/ar-Be8Ju1cG.svg +32 -0
  17. package/dist/web/assets/as-Dekqy8Of.svg +72 -0
  18. package/dist/web/assets/at-DGA_6m5E.svg +4 -0
  19. package/dist/web/assets/au-DAHDIuPI.svg +8 -0
  20. package/dist/web/assets/aw-W0PWLK5p.svg +186 -0
  21. package/dist/web/assets/ax-DvLIy84U.svg +18 -0
  22. package/dist/web/assets/az-Bk-bYNxy.svg +8 -0
  23. package/dist/web/assets/ba-WdDiSMvP.svg +12 -0
  24. package/dist/web/assets/bb-DJxbaxmT.svg +6 -0
  25. package/dist/web/assets/bd-BF9t1-60.svg +4 -0
  26. package/dist/web/assets/be-CLLkK3PN.svg +7 -0
  27. package/dist/web/assets/bf-YclsoDuF.svg +7 -0
  28. package/dist/web/assets/bg-GUQenraa.svg +5 -0
  29. package/dist/web/assets/bh-BQqEGq6F.svg +4 -0
  30. package/dist/web/assets/bi-CRmKY6RQ.svg +15 -0
  31. package/dist/web/assets/bj-14PhO9bM.svg +14 -0
  32. package/dist/web/assets/bl-4CI2YcwX.svg +5 -0
  33. package/dist/web/assets/bm-BeYgB2z9.svg +97 -0
  34. package/dist/web/assets/bn-B6T3O78g.svg +36 -0
  35. package/dist/web/assets/bo-CcUiMqkJ.svg +673 -0
  36. package/dist/web/assets/bq-BYpdxEeT.svg +5 -0
  37. package/dist/web/assets/br-Cu5YU29T.svg +45 -0
  38. package/dist/web/assets/bs-7Gd_oriM.svg +13 -0
  39. package/dist/web/assets/bt-BTo4qm10.svg +89 -0
  40. package/dist/web/assets/bv-wM9JLv4R.svg +13 -0
  41. package/dist/web/assets/bw-n5ZaAnGL.svg +7 -0
  42. package/dist/web/assets/by-C621sBpd.svg +18 -0
  43. package/dist/web/assets/bz-BCKHR4_q.svg +145 -0
  44. package/dist/web/assets/ca-PYUrLVUV.svg +4 -0
  45. package/dist/web/assets/cc-BNT6Xjzk.svg +19 -0
  46. package/dist/web/assets/cd-BGclsrP6.svg +5 -0
  47. package/dist/web/assets/cf-DRetLmp-.svg +15 -0
  48. package/dist/web/assets/cg-CwIyG6SE.svg +12 -0
  49. package/dist/web/assets/ch-sfriZoF1.svg +9 -0
  50. package/dist/web/assets/ci-C8Q8IYTn.svg +7 -0
  51. package/dist/web/assets/ck-DfXMUOTo.svg +9 -0
  52. package/dist/web/assets/cl-BgYYb4qP.svg +13 -0
  53. package/dist/web/assets/cm-D4yjdmKT.svg +15 -0
  54. package/dist/web/assets/cn-DifnnI3t.svg +11 -0
  55. package/dist/web/assets/co-DV591zMm.svg +7 -0
  56. package/dist/web/assets/cp-K_ay05Q_.svg +7 -0
  57. package/dist/web/assets/cr-BlYVN-_Q.svg +7 -0
  58. package/dist/web/assets/cu-L6XVZNgo.svg +13 -0
  59. package/dist/web/assets/cv-CPsfcOfk.svg +13 -0
  60. package/dist/web/assets/cw-BbrnximR.svg +14 -0
  61. package/dist/web/assets/cx-DpYD6n6U.svg +15 -0
  62. package/dist/web/assets/cy-bZuP8hmf.svg +6 -0
  63. package/dist/web/assets/cz-WWBC5Aeb.svg +5 -0
  64. package/dist/web/assets/de-B-2o-4Z9.svg +5 -0
  65. package/dist/web/assets/dg-CJPJrjiZ.svg +130 -0
  66. package/dist/web/assets/dj-hp_BwbmO.svg +13 -0
  67. package/dist/web/assets/dk-DmS9BCZB.svg +5 -0
  68. package/dist/web/assets/dm-Cbhezfe1.svg +152 -0
  69. package/dist/web/assets/do-B86d445t.svg +121 -0
  70. package/dist/web/assets/dz-Dytc1TFu.svg +5 -0
  71. package/dist/web/assets/ec-CaVOFQ3t.svg +138 -0
  72. package/dist/web/assets/ee-DufrxGIR.svg +5 -0
  73. package/dist/web/assets/eg-YC70hswZ.svg +38 -0
  74. package/dist/web/assets/eh-0awM4TVj.svg +16 -0
  75. package/dist/web/assets/er-X83uml6t.svg +8 -0
  76. package/dist/web/assets/es-d5m8M5h8.svg +544 -0
  77. package/dist/web/assets/et-DwdlzOIx.svg +14 -0
  78. package/dist/web/assets/eu-Brdgz8ab.svg +28 -0
  79. package/dist/web/assets/fi-DWUIkfjL.svg +5 -0
  80. package/dist/web/assets/fj-DEAVMg38.svg +120 -0
  81. package/dist/web/assets/fk-nuUF_Ak3.svg +90 -0
  82. package/dist/web/assets/fm-B4Z83GL0.svg +11 -0
  83. package/dist/web/assets/fo-DFjwyWur.svg +12 -0
  84. package/dist/web/assets/fr-DVvUyOqI.svg +5 -0
  85. package/dist/web/assets/ga-BklUhLH_.svg +7 -0
  86. package/dist/web/assets/gb-DTXiLQoe.svg +7 -0
  87. package/dist/web/assets/gd-CO-whzUe.svg +27 -0
  88. package/dist/web/assets/ge-B2RiL-Ih.svg +6 -0
  89. package/dist/web/assets/gf-DWl5zcw0.svg +5 -0
  90. package/dist/web/assets/gg-jdOQS2nU.svg +9 -0
  91. package/dist/web/assets/gh-r3LP_X7q.svg +6 -0
  92. package/dist/web/assets/gi-BJKE9SzW.svg +32 -0
  93. package/dist/web/assets/gl-CHaBnMib.svg +4 -0
  94. package/dist/web/assets/gm-Bu99atwn.svg +14 -0
  95. package/dist/web/assets/gn-1dJNy9oQ.svg +7 -0
  96. package/dist/web/assets/gp-DNyt_wTA.svg +5 -0
  97. package/dist/web/assets/gq-Cag8QTk2.svg +23 -0
  98. package/dist/web/assets/gr-C5PU0p9p.svg +16 -0
  99. package/dist/web/assets/gs-DiiNa0F5.svg +133 -0
  100. package/dist/web/assets/gt-CJo5DI-7.svg +204 -0
  101. package/dist/web/assets/gu-Di1JYREk.svg +19 -0
  102. package/dist/web/assets/gw-D249VY33.svg +13 -0
  103. package/dist/web/assets/gy-CcVYUM2E.svg +9 -0
  104. package/dist/web/assets/hk-CUNIaSX0.svg +8 -0
  105. package/dist/web/assets/hm-Dh6t_Tj3.svg +8 -0
  106. package/dist/web/assets/hn-CRjyS_bm.svg +18 -0
  107. package/dist/web/assets/hr-fzLfaANM.svg +58 -0
  108. package/dist/web/assets/ht-DIMg4gti.svg +116 -0
  109. package/dist/web/assets/hu-7Q5wwIIi.svg +7 -0
  110. package/dist/web/assets/ic-CSo4d8tH.svg +7 -0
  111. package/dist/web/assets/id-DiSP6Fmm.svg +4 -0
  112. package/dist/web/assets/ie-ChAXClx3.svg +7 -0
  113. package/dist/web/assets/il-_56OEGLa.svg +14 -0
  114. package/dist/web/assets/im--VPIqfkF.svg +36 -0
  115. package/dist/web/assets/in-Cdwu6Bq7.svg +25 -0
  116. package/dist/web/assets/index-B9pQ4U7M.js +305 -0
  117. package/dist/web/assets/index-BhNayHbp.css +1 -0
  118. package/dist/web/assets/io-13HOfeJD.svg +130 -0
  119. package/dist/web/assets/iq-Dp8HDzo2.svg +10 -0
  120. package/dist/web/assets/ir-cCIgaNf6.svg +219 -0
  121. package/dist/web/assets/is-CZjefTNV.svg +12 -0
  122. package/dist/web/assets/it-Br7q0Zh6.svg +7 -0
  123. package/dist/web/assets/je-DyWbhIiC.svg +62 -0
  124. package/dist/web/assets/jm-CItSr3iX.svg +8 -0
  125. package/dist/web/assets/jo-BAF1FGbm.svg +16 -0
  126. package/dist/web/assets/jp-BIMmfxpO.svg +11 -0
  127. package/dist/web/assets/ke-C8foqndp.svg +23 -0
  128. package/dist/web/assets/kg-B0FsxZiL.svg +4 -0
  129. package/dist/web/assets/kh-BeWfuE30.svg +61 -0
  130. package/dist/web/assets/ki-p_fAQGbS.svg +36 -0
  131. package/dist/web/assets/km-B5tqtGG7.svg +16 -0
  132. package/dist/web/assets/kn-DVPxDkNY.svg +14 -0
  133. package/dist/web/assets/kp-CrDKzoxe.svg +15 -0
  134. package/dist/web/assets/kr-BCXH1Hao.svg +24 -0
  135. package/dist/web/assets/kw-fSBzmd30.svg +13 -0
  136. package/dist/web/assets/ky-Dpsu1myA.svg +103 -0
  137. package/dist/web/assets/kz-CwKXYZ8s.svg +36 -0
  138. package/dist/web/assets/la-CuJflhIW.svg +12 -0
  139. package/dist/web/assets/lb-BSjpYEoo.svg +15 -0
  140. package/dist/web/assets/lc-CNvab8Ae.svg +8 -0
  141. package/dist/web/assets/li-CHdhvNcr.svg +43 -0
  142. package/dist/web/assets/lk-DUkgV9Tq.svg +22 -0
  143. package/dist/web/assets/lr-B84vu3Ds.svg +14 -0
  144. package/dist/web/assets/ls-5Xk3Mxq5.svg +8 -0
  145. package/dist/web/assets/lt-DoukV-Sm.svg +7 -0
  146. package/dist/web/assets/lu-DOI02Msy.svg +5 -0
  147. package/dist/web/assets/lv-C-KfY8Yc.svg +6 -0
  148. package/dist/web/assets/ly-BWpTK3ux.svg +13 -0
  149. package/dist/web/assets/ma-BTRNTRUj.svg +4 -0
  150. package/dist/web/assets/mc-PK078JHl.svg +6 -0
  151. package/dist/web/assets/md-DRlxvNwm.svg +70 -0
  152. package/dist/web/assets/me-Cv4Gwqah.svg +116 -0
  153. package/dist/web/assets/mf-BaAGWwAq.svg +5 -0
  154. package/dist/web/assets/mg-C168LHXW.svg +7 -0
  155. package/dist/web/assets/mh-gxuIp6Wk.svg +7 -0
  156. package/dist/web/assets/mk-D9SIMr-a.svg +5 -0
  157. package/dist/web/assets/ml-DVf6ujpi.svg +7 -0
  158. package/dist/web/assets/mm-lwT09MQ0.svg +12 -0
  159. package/dist/web/assets/mn-CgXyw0O9.svg +14 -0
  160. package/dist/web/assets/mo-BAtCjuYA.svg +9 -0
  161. package/dist/web/assets/mp-CrOApEqW.svg +86 -0
  162. package/dist/web/assets/mq-BFnJ22KI.svg +5 -0
  163. package/dist/web/assets/mr-D6G1wpeZ.svg +6 -0
  164. package/dist/web/assets/ms-DxciGbUu.svg +29 -0
  165. package/dist/web/assets/mt-YqzKx9xl.svg +58 -0
  166. package/dist/web/assets/mu-mcq7cUFl.svg +8 -0
  167. package/dist/web/assets/mv-BynAllfM.svg +6 -0
  168. package/dist/web/assets/mw-C15nc1xZ.svg +10 -0
  169. package/dist/web/assets/mx-Cc8Ccfe8.svg +382 -0
  170. package/dist/web/assets/my-Co4JeeyE.svg +26 -0
  171. package/dist/web/assets/mz-Drlr_USV.svg +21 -0
  172. package/dist/web/assets/na-D79ffb4Z.svg +16 -0
  173. package/dist/web/assets/nc-5j7wEmDR.svg +13 -0
  174. package/dist/web/assets/ne-B1jPOYkl.svg +6 -0
  175. package/dist/web/assets/nf-Dl00mlk2.svg +9 -0
  176. package/dist/web/assets/ng-su4NM9If.svg +6 -0
  177. package/dist/web/assets/ni-CcFCSQxm.svg +129 -0
  178. package/dist/web/assets/nl-BnOa6UiA.svg +5 -0
  179. package/dist/web/assets/no-qf2JPO73.svg +7 -0
  180. package/dist/web/assets/np-CIuq5GKd.svg +13 -0
  181. package/dist/web/assets/nr-DERIdzkN.svg +12 -0
  182. package/dist/web/assets/nu-BfgWvGcd.svg +10 -0
  183. package/dist/web/assets/nz-5vODdBjz.svg +36 -0
  184. package/dist/web/assets/om-DcqxRdQL.svg +115 -0
  185. package/dist/web/assets/pa-BLNN9G2-.svg +14 -0
  186. package/dist/web/assets/pc-BJpYiA9b.svg +33 -0
  187. package/dist/web/assets/pe-BLqhuu1C.svg +4 -0
  188. package/dist/web/assets/pf-C8ahG68q.svg +19 -0
  189. package/dist/web/assets/pg-BAYpbp9Z.svg +9 -0
  190. package/dist/web/assets/ph-BEzTn62K.svg +6 -0
  191. package/dist/web/assets/pk-CWMEc3ad.svg +15 -0
  192. package/dist/web/assets/pl-o38JROoc.svg +6 -0
  193. package/dist/web/assets/pm-CHiP5UmZ.svg +5 -0
  194. package/dist/web/assets/pn-DgxdtieE.svg +53 -0
  195. package/dist/web/assets/pr-B4tMV0xm.svg +13 -0
  196. package/dist/web/assets/ps-DO8YKYeS.svg +6 -0
  197. package/dist/web/assets/pt-DZ2ADgIR.svg +57 -0
  198. package/dist/web/assets/pw-CQP52WMX.svg +11 -0
  199. package/dist/web/assets/py-mNzh0mZC.svg +157 -0
  200. package/dist/web/assets/qa-Dkmpc78M.svg +4 -0
  201. package/dist/web/assets/re-Bk4ipYK1.svg +5 -0
  202. package/dist/web/assets/ro-CoSeqKY1.svg +7 -0
  203. package/dist/web/assets/rs-BfwKwXtn.svg +292 -0
  204. package/dist/web/assets/ru-D-4tNwXt.svg +5 -0
  205. package/dist/web/assets/rw-D7nbSYKI.svg +13 -0
  206. package/dist/web/assets/sa-Dh79zbT9.svg +25 -0
  207. package/dist/web/assets/sb-BDTYjcbk.svg +13 -0
  208. package/dist/web/assets/sc-CRNsSLg9.svg +7 -0
  209. package/dist/web/assets/sd-ClziNjGr.svg +13 -0
  210. package/dist/web/assets/se-8C923vhy.svg +4 -0
  211. package/dist/web/assets/sg-DGYIMG0G.svg +13 -0
  212. package/dist/web/assets/sh-DNImvbrE.svg +7 -0
  213. package/dist/web/assets/si-BMKT-Tec.svg +18 -0
  214. package/dist/web/assets/sj-BFFEGknm.svg +7 -0
  215. package/dist/web/assets/sk-K9BNIYAO.svg +9 -0
  216. package/dist/web/assets/sl-DxLJY5vJ.svg +7 -0
  217. package/dist/web/assets/sm-DGBIRFB_.svg +75 -0
  218. package/dist/web/assets/sn-S8ipNF1U.svg +8 -0
  219. package/dist/web/assets/so-DlzA2Fco.svg +11 -0
  220. package/dist/web/assets/sr-Co7OKBh3.svg +6 -0
  221. package/dist/web/assets/ss-CxVEpdPD.svg +8 -0
  222. package/dist/web/assets/st-C1Nd1c3V.svg +16 -0
  223. package/dist/web/assets/sv-CJIHhYwF.svg +593 -0
  224. package/dist/web/assets/sx-nDhIaDNb.svg +56 -0
  225. package/dist/web/assets/sy-DwSud114.svg +6 -0
  226. package/dist/web/assets/sz-qxMwa2gs.svg +34 -0
  227. package/dist/web/assets/tc-dtelpZmc.svg +50 -0
  228. package/dist/web/assets/td-BsuVhZpT.svg +7 -0
  229. package/dist/web/assets/tf-Co33RhQH.svg +15 -0
  230. package/dist/web/assets/tg-CP1-sc35.svg +14 -0
  231. package/dist/web/assets/th-tzq84hgd.svg +7 -0
  232. package/dist/web/assets/tj-b-aWfOTb.svg +22 -0
  233. package/dist/web/assets/tk-CDucsEss.svg +5 -0
  234. package/dist/web/assets/tl-wpo93AGk.svg +13 -0
  235. package/dist/web/assets/tm-C_WSgUcv.svg +204 -0
  236. package/dist/web/assets/tn-BcKCZULf.svg +4 -0
  237. package/dist/web/assets/to-D8uVsoxb.svg +10 -0
  238. package/dist/web/assets/tr-Cd6FO9Bg.svg +8 -0
  239. package/dist/web/assets/tt-CTnr7aY5.svg +5 -0
  240. package/dist/web/assets/tv-DDqkVT-n.svg +9 -0
  241. package/dist/web/assets/tw-d-Mf-0VT.svg +34 -0
  242. package/dist/web/assets/tz-BjLtHeil.svg +13 -0
  243. package/dist/web/assets/ua-Bq0XgQqK.svg +6 -0
  244. package/dist/web/assets/ug-ByL2ejGl.svg +30 -0
  245. package/dist/web/assets/um-Bhke9Eic.svg +9 -0
  246. package/dist/web/assets/un-Bqg4Cbbh.svg +16 -0
  247. package/dist/web/assets/us-C73uVeEr.svg +9 -0
  248. package/dist/web/assets/uy-DD6peej-.svg +28 -0
  249. package/dist/web/assets/uz-C2f-Cubn.svg +30 -0
  250. package/dist/web/assets/va-B9-hqIE-.svg +190 -0
  251. package/dist/web/assets/vc-COpmFovN.svg +8 -0
  252. package/dist/web/assets/ve-BSqnIB9l.svg +26 -0
  253. package/dist/web/assets/vg-C7xY6pic.svg +59 -0
  254. package/dist/web/assets/vi-BC_zcciE.svg +28 -0
  255. package/dist/web/assets/vn-BEAEijd0.svg +11 -0
  256. package/dist/web/assets/vu-D6k0NQlg.svg +21 -0
  257. package/dist/web/assets/wf-DrxpOO_G.svg +5 -0
  258. package/dist/web/assets/ws-vzJNwdVm.svg +7 -0
  259. package/dist/web/assets/xk-Bj15g7cp.svg +5 -0
  260. package/dist/web/assets/xx-zm_JmrXl.svg +4 -0
  261. package/dist/web/assets/ye-BwST9gXC.svg +7 -0
  262. package/dist/web/assets/yt-DIfEG0ex.svg +5 -0
  263. package/dist/web/assets/za-Jz40JTrv.svg +17 -0
  264. package/dist/web/assets/zm-BmsW91ne.svg +27 -0
  265. package/dist/web/assets/zw-U0m7oJ5e.svg +21 -0
  266. package/dist/web/index.html +2 -2
  267. package/package.json +1 -1
  268. package/release-notes.json +27 -1
  269. package/src/server/ccusage-session.mjs +17 -0
  270. package/src/server/codex-quota.mjs +7 -1
  271. package/src/server/index.mjs +4 -1
  272. package/src/server/quota-history.mjs +149 -0
  273. package/src/server/quota.mjs +7 -2
  274. package/src/server/request-gates.mjs +1 -0
  275. package/src/server/traffic-radar-config.mjs +35 -3
  276. package/src/server/traffic-radar-routes.mjs +13 -0
  277. package/src/server/traffic-radar.mjs +12 -1
  278. package/src/server/usage-routes.mjs +12 -0
  279. package/dist/web/assets/RadioPanel-N-duyYFJ.js +0 -1
  280. package/dist/web/assets/TrafficRadar-rynjtyN0.js +0 -1
  281. package/dist/web/assets/index-BJpK26-r.js +0 -306
  282. package/dist/web/assets/index-B_uYtqRM.css +0 -1
@@ -0,0 +1,28 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="flag-icons-vi" viewBox="0 0 640 480">
2
+ <path fill="#fff" d="M0 0h640v480H0z"/>
3
+ <path fill="#369443" stroke="#010002" stroke-miterlimit="10" stroke-width="1.5" d="M204.3 315s-.5-3.6 6.2-6.1c6.6-2.6 7.2-12.2 5.8-18.6 0 0-3.4 6-7.7 8.1 0 0-6.8 3.6-7.2 10.4 0 0 0 2.5-.5 4.5-.3 1-3.4-8.6 2.4-15.8 6-7.3 7.6-13.3 2.9-25 0 0-.5 7-5.1 11.1-4.7 4-5.3 4.4-5.2 14 0 0 0 3.4-1.7 4.5 0 0-3.6-5.3-4.6-8.8s-1.4-5 2.8-9c0 0 13.2-8.7 3.7-27.4 0 0-.3 6.4-5 10.2-4.5 3.9-4.2 6.4-4.4 13-.2 6.7-.6 6.2-1.1 7.2 0 0-8.5-15.6-2-23.8s10.2-10 3-25.4c0 0 .3 8-5.5 11.8-5.7 4-4.4 13-4.4 13s.4 3.5-.8 6c0 0-8.1-15.9-.4-24.4 6.6-7.3 7-12.4 3.5-22.6 0 0-.4 4.7-4 7.3-3.7 2.6-6.6 5.1-5.9 15 0 0 .3 7-.6 9 0 0-3.4-6.4-4.4-10.5-1-4.2-1.3-6.6 1.2-10.7s12.5-16 .6-33c0 0-.3 5.5-3.4 10.5-3 5-1.6 10.9-1 15.4s-1.5 8.9-1.5 8.9-5.2-9.5-4-20.4q1.6-16.6-13.5-26.4s-7.3 17 2.7 25.7c0 0 8.5 8.4 10.7 18.6 0 0-6.5-.6-12.3-12s-18-9.6-18.8-9.7c0 0 2 17.6 20.6 22.6 0 0 12 2 14.2 10.8 0 0 2 6 2.8 9.2 0 0-3.8-1.5-7.3-6.7-3.5-5-3-5.7-14.8-6.9 0 0-4.7-.5-7.2-3.9 0 0 5 18.6 17.7 18.5 0 0 11.6-1.3 18 14l-2.9-2c-1.7-1.1-6-3.3-14.5-2.3s-10.9-.4-13-1c0 0 8.6 15.7 20.7 11s18 12.4 18.2 12.7c0 0-1.7-1.2-3.8-3.3-2.2-2.1-6.6-4.7-15-2 0 0-6.1 2.3-12.3.4 0 0 6 11.5 19.8 9.5a15 15 0 0 1 17.3 10.2s-1.8-1-3-2c-1.3-1-6-3.7-16-.8s-13.6-.4-13.6-.4 5.5 10 16.2 11.3c0 0 6-.1 8.4-1s9.2-2.5 13.8 4.2c0 0-1.3.2-3.2-.7 0 0-7-2.5-12.5 2 0 0-4.8 4.9-11.6 4 0 0 8.8 8.5 22.8 1.3 0 0 4.7-3.4 8.2-.8 3.5 2.7 11.5-2.6 11.5-2.6z"/>
4
+ <g fill="#f4c53d" stroke="#010002" stroke-miterlimit="10" stroke-width="1.5">
5
+ <path d="M282.2 103.7s-1.6-14.5 10-16a38 38 0 0 1 18 1.2l5.5 10.6-2 7.2-7.4 3.4s1.3-11-8.8-11.2c-2.6 0-4 1-8.1.3s-6.3 3.8-7.2 4.5z"/>
6
+ <path d="M363.8 139.6c-1.8 2.2-8.7 3-8.7 3s7.1 5.5 10.2 13.3c3 7.7-82.4 0-82.4 0s3.8-2.6 6.3-7.6c0 0-3.8 1.4-7.6-2.4 0 0 2.8 1 6.5-4.6 0 0 5.5-7 9.4-9 0 0-1.8 1.2-6.1-1.2 0 0 7.4-1 10-13.5 0 0 .5-2.8 3.3-7 2.8-4 2.2.9 7.4-5.4 0 0 2.4-4.4.3-7-2-2.8-4.3-1.8-8.6-4.4-4.4-2.6-6.3-4-4.8-8s5.3-3.4 5.9-3.4.8-3.5 5.5-5.9 17.4-1.3 19.2-.3c2 1 9.5 3.3 14 14.5s-1.2 15.4 10.8 32.4c0 0-4.8 1-7.9 0 0 0 6.3 11.2 17.3 16.5z"/>
7
+ <path fill="none" d="M311 92.2c-10-.5-6.1-9.8-6.1-9.8"/>
8
+ <path d="M328 93.5s-1.7-.8-3.2-2.8c-2-2.7-6.7-4-9.1-1.4 0 0-2.5 2.8-4.8 3 0 0 2.6.7 4.3 2.3s3.5 2.8 6.1 2.4 3-1.7 4.2-2.5 2.5-1 2.5-1z"/>
9
+ </g>
10
+ <path fill="#369443" stroke="#010002" stroke-miterlimit="10" stroke-width="1.5" d="M202.8 336.5s-.2-6.4 7.8-6.8l23.5 32.7s-.9 2.1-11.5 1.9c0 0-1.2 0-1.8 1.2-.9 2-18-29-18-29z"/>
11
+ <g id="vi-a" fill="#f4c53d" stroke="#010002" stroke-width="10" transform="translate(3.6 26.2)scale(.15055)">
12
+ <path d="M1495 1807.9s-49.9 85.6-110.2 87c0 0-103.7-12.6-133 14.5-20.5 18.9-41.4 34.5-50 82.8-8.4 48.3 16.5 58.7 22.4 60.8 0 0 4.6 34.5 38.7 25.5 0 0 2 36 62.2 18.7s85.3-11.8 97-71.8c11.9-60.1 22.8-59.1 33.5-66.3 14.4-9.7 41.5-18.8 61.6-30.4 18-10.4 87.2-45.6 110.8-48.3 23.6-2.8 18.4-82.2 18.4-82.2h-61l-29.5-43.5zm192-429.4s-61 49.7-112.2 0c0 0-20.6 24.8-62 17.6-41.2-7.3-48.1-29-52-41.4 0 0-35.8 20.8-66 4.3-30-16.4-30-41.3-30-41.3s-52.5 10.4-79.4-25.2c-26.9-35.5-10.5-70.7 4-74.9 0 0-56.7 14.9-72.2-33.8a56 56 0 0 1 16.4-62.8s-119.4-.6-168.4-38c0 0-40.7-25.6-16.4-52.5 0 0-107.5-17.2-134.4-60 0 0-11.8-11.8-7.9-32.5 0 0 .7-11.7 12.5-12.4 0 0-122.6-19-158-59.4 0 0-17-18.6-8.5-43.5 0 0 1.8-6.5 4.7-11 0 0-111.6-23.5-166.6-73.2 0 0-31.8-28.3-15.4-66.3 0 0-186.5-51-143.3-133.2 0 0-87.2-28.3-59.6-107 0 0-72.1-36.6-40.7-94.6 30.1-55.5 122.6 9.7 232 40 0 0 296.4 93.2 442.3 118l414.6 617.3 241.9 93.2z"/>
13
+ <path d="M1689.9 923.9s-38.9-29.2-108.2 5.1c0 0-23.3 16.1-41.7-1.5a37.3 37.3 0 0 1 4.3-57.5c51.7-38.3 70.8-153.2-7.8-200.9 0 0-114-67.6-532.3-174 0 0-35-9.8-53.8-5.1a52 52 0 0 0-37.6 37.8S894 581.1 957 611.6c0 0 28.4 13 57.7 21.4 0 0-32.2-7-46 24.8-13 30.4 6 61.5 65 81.5 0 0 16 6.2 38.7 11.7 0 0-50.5 14.5-26.2 55.3 0 0 21.6 42.8 98 50.4 0 0-57 6.2-16.8 60.4 0 0 17.7 29.7 73.4 40.7 0 0-42.2 1.4-21 39.3 21.4 38 71.5 59.4 120.9 62.9 0 0 26.7 1.4 45.4-2.8 0 0-47 23.5-19.4 62.8 0 0 20.3 28 71.1 26.6 0 0-13.1 44 24.1 60.6 29 13 53.1-7.8 53.1-7.8s-9.8 47.1 32.5 63.7c0 0 21.1 10.9 52.6 0 0 0 24 53.9 109.6 16 85.6-37.7 20.2-355.1 20.2-355.1zm5 489.4s-12.5 67.4-112 152.2c0 0-76.8 67.7-74.9 145.7 2 79.5-13.7 88.4-43.9 115.3 0 0 62.3 4.9 92.4-36.6 0 0-1.3 69-10.5 75.3 0 0 19.6 1.2 47.9-29.7 0 0 17-18 32.8-24.9 0 0-18.4 47.7-4 91.9 0 0 4.6-17.3 28.9-24.9 0 0 44-9 61-72.5 0 0 11.1-42 80-79.4 0 0 78-29.4 76-67.8-2-38.5-173.6-244.6-173.6-244.6z"/>
14
+ <path stroke-miterlimit="10" d="M2056.5 2282.2s-17.9 78.8-80 72.5c0 0-43.9-4.2-40.6-77.4 0 0-64.9 34.6-75.4-51 0 0-59 13.7-58.3-66.3 0 0-55 9.6-48.5-61.5 0 0-59.7 16-59.7-51 0 0-139.6-23.2 151.4-288.6l259.6 154.6z"/>
15
+ <path d="M2085.4 1928.3s-43.3 38.4-74.1-19c0 0-42-2-48.5-33.8 0 0-34.1-3.4-40.7-35.9 0 0-46.5-4.8-45.2-44.1 0 0-84.6-6.6 0-102.4s228.1 159 228.1 159zm48.2-23.8c42 0 89.5 262 77.2 419.9-4.5 57.3-35.2 104.1-77.2 104.1s-72.6-46.8-77-104.1c-12.4-157.9 35.1-419.9 77-419.9"/>
16
+ <ellipse cx="2133.6" cy="1902.5" rx="58" ry="86"/>
17
+ <path fill="none" stroke-miterlimit="10" d="M1935.9 2277.3s6.6-138.7 126.8-337.6m-202.2 286.6s-18.7-80.1 150.8-317c0 0-19.7-56.5 40.6-92.8M1802.2 2160s-5.3-86.7 160.6-284.5c0 0-14.7-51 45.4-91.8m-254.5 314.8s6.2-87.6 168.4-258.9c0 0-8-52.4 50-84.9m-278 292.8s11.7-100.1 182.8-252c0 0-5.9-39.4 51.1-79.4"/>
18
+ <path fill="none" d="M372.3 432s134.3 77.8 552.9 155.6M431.9 539S795.6 657.6 965 672.2m-389.9 0s213.4 67 463.3 109.3m-281.2 30.3s241 57.9 356.2 67.5M919 925.6s203.9 42.5 255.5 47.6m-125.7 57.3s148.8 22.6 208 21.4m-23.2 69s60.2-2.8 89.1-7.6m-33.4 104.3s51.2-13.8 81.3-33.1m-5.9 133.2s39.4-15.2 58.4-56.6m37.7 93.6s30.4-27.3 32.4-57.7m81.6 81.5s-11.4-9.9-3.6-52.7m-11.1-62.8s-6-12.2-4-31.6m-211-581.3s68.8 27.6 91.7 65.6 7.9 74.9 0 96c-3.9 10.7-52.4 104.2 4.6 171.9M1346 1057s.4-.3 24.6-8m-169.8-91.4s41 8.2 81.3 8.6m-138-109.8s48.2 4.9 93.5 4.2m-165.2-109.8s69.5 13.8 106.8 14.5M1014.7 633s85.7 24.4 149.4 33.1m141.6 50.4s-61.6 57.3 12.5 110.5c0 0-30.8 48.3 30.8 98.7m-16.4 23.8s-9.2 92.2 103.6 92.2c0 0-21.7 82.1 87.2 79.4 0 0 12.4 65.6 91 52.4M1441.3 1895s-17.9 4-56.6 0m-108.8 48.3s-54.4-8.3-51.8 109.8m84.6-82.9s-49.2-6.2-46 108.4m520.7-384.5s-23.6 4.8-40 23.5-47.8 15.1-47.8 15.1 17-13.8 23-48.3c5.8-34.5 24.9-44.9 24.9-44.9m-56.3-32.6s-23.6 4.8-40 23.4c-16.4 18.7-47.9 15.2-47.9 15.2s17-13.8 23-48.3 24.9-44.9 24.9-44.9m23.7 188.5s-20.6 4.3-34.9 20.5c-14.3 16.3-41.8 13.3-41.8 13.3s15-12 20-42.2c5.2-30.1 21.8-39.2 21.8-39.2"/>
19
+ </g>
20
+ <use xlink:href="#vi-a" width="100%" height="100%" stroke="#010002" stroke-width="10" transform="matrix(-1 0 0 1 647.2 0)"/>
21
+ <path fill="#0081c6" stroke="#010002" stroke-miterlimit="10" stroke-width="1.5" d="m466 256-14.3 61.7-5.9-4.2 14-59.2-9.8.2 23.1-42.3 1.5 48.7zm37 13-43 50.8-4.6-5.2 42.8-50.2-8.7-4.6 39.2-26-20.3 43.8z"/>
22
+ <path fill="#0081c6" stroke="#010002" stroke-miterlimit="10" stroke-width="1.5" d="m492.6 242-38.5 74-5.9-3.5 38.7-73.8-9.4-2.4 32.7-34.6-10.5 47.5zm-48 96.6-2.9 11.7 8 8-11.2 47-10-13.3-14.6 6.8 11.1-47 10.4-3 2.6-11.7s3.2-1.2 6.6 1.5z"/>
23
+ <path fill="#0081c6" stroke="#010002" stroke-miterlimit="10" stroke-width="1.5" d="m447.3 330.8-5.7 10.6 5.7 9.7-22.4 42.5-6.3-15.6-15.9 2.6 22.4-42.4h10.7l5.5-10.6s4 0 6 3.2z"/>
24
+ <path fill="#0081c6" stroke="#010002" stroke-miterlimit="10" stroke-width="1.5" d="m448.2 333.9-15 19.2 3.4 10.8-30.9 36-2.8-16.6-16-1.2 30.8-36 10.4 2.5 16-20.4s4.4 2.2 4.1 5.7zm-382.7-45c3.6-1.5 6.2-2.9 6.2-6.7q0-1.5-1.5-6.1L46 202a59 59 0 0 0-3-7.9c-1.1-2-3.2-2.9-6.1-4h30.7c-3.3 1.5-6.4 2.7-6.3 6.3q0 2 1.1 5.7l18.6 58 18.5-58a20 20 0 0 0 1.1-5.7c0-3.7-3.2-5-6.3-6.4h29.8c-2.7 1.1-5 2-6 4.1a63 63 0 0 0-3.1 8L90.8 276a38 38 0 0 0-1.5 6.1s-1.1 4.7 6.2 6.7zm515.3-7.6v-83.7q0-2.1-.8-3.3c-.8-1.2-2.5-3-5.5-4.2h27.7a12 12 0 0 0-5.5 4.2q-.7 1.2-.7 3.3v83.7q0 2.2.7 3.4c.5.8 2.5 2.8 5.5 4.2h-27.7c3-1.4 5-3.4 5.5-4.2q.8-1.2.8-3.4z"/>
25
+ <path fill="#fff" stroke="#010002" stroke-width="1.5" d="M324.8 309.8S399 276.9 399.1 201H250.5c.2 76 74.3 108.8 74.3 108.8z"/>
26
+ <path fill="#a60032" stroke="#010002" stroke-width="1.5" d="M262 201v48.5s5.6 11.3 11.4 18.3V201zm22.8 0v80s7.2 7 11.4 10.4V201zm22.9 0v98.9s8.1 5.2 11.4 7v-106h-11.4zm80 0v48.5s-5.7 11.3-11.5 18.3V201zm-22.9 0v80s-7.1 7-11.4 10.4V201zm-22.8 0v98.9s-8.2 5.2-11.5 7v-106H342z"/>
27
+ <path fill="#162667" stroke="#010002" stroke-miterlimit="10" stroke-width="1.5" d="M399.1 145.8s-36.4 19-74.3-1.6c-37.9 20.6-74.3 1.6-74.3 1.6V201h148.6z"/>
28
+ </svg>
@@ -0,0 +1,11 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" id="flag-icons-vn" viewBox="0 0 640 480">
2
+ <defs>
3
+ <clipPath id="vn-a">
4
+ <path fill-opacity=".7" d="M-85.3 0h682.6v512H-85.3z"/>
5
+ </clipPath>
6
+ </defs>
7
+ <g fill-rule="evenodd" clip-path="url(#vn-a)" transform="translate(80)scale(.9375)">
8
+ <path fill="#da251d" d="M-128 0h768v512h-768z"/>
9
+ <path fill="#ff0" d="M349.6 381 260 314.3l-89 67.3L204 272l-89-67.7 110.1-1 34.2-109.4L294 203l110.1.1-88.5 68.4 33.9 109.6z"/>
10
+ </g>
11
+ </svg>
@@ -0,0 +1,21 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="flag-icons-vu" viewBox="0 0 640 480">
2
+ <defs>
3
+ <clipPath id="vu-a">
4
+ <path d="M0 0v475l420-195h480v-85H420Z"/>
5
+ </clipPath>
6
+ </defs>
7
+ <path fill="#009543" d="M0 0h640v480H0z"/>
8
+ <path fill="#d21034" d="M0 0h640v240H0z"/>
9
+ <g clip-path="url(#vu-a)" transform="scale(.71111 1.01053)">
10
+ <path stroke="#fdce12" stroke-width="110" d="m0 0 420 195h480v85H420L0 475"/>
11
+ <path fill="none" stroke="#000" stroke-width="60" d="m0 0 420 195h480m0 85H420L0 475"/>
12
+ </g>
13
+ <g fill="#fdce12" transform="translate(-22)scale(1.01053)">
14
+ <path d="M106.9 283v27c23.5 0 69.7-18 69.7-76.1s-49.3-68.9-64-68.9-60.3 10.6-60.3 58c0 47.6 44.7 52 53.5 52s41.8-8 38-43.6a35.5 35.5 0 0 1-35.4 31.5c-24 0-39-17.8-39-35.4s14.6-41.2 39.9-41.2 43.8 22.5 43.8 45.1-17.8 51.5-46.2 51.5z"/>
15
+ <g id="vu-b">
16
+ <path stroke="#fdce12" stroke-width=".8" d="m86.2 247.7 1.4 1s11.2-25.5 41.1-43.6c-3.8 2-23.8 12-42.5 42.6z"/>
17
+ <path d="M89.1 243.3s-3.4-7-.4-10.2 1.7 8.3 1.7 8.3l1.3-1.9s-2-8.6.2-10.4 1.2 8.3 1.2 8.3l1.4-1.8s-1.5-8.4.7-10 .9 8 .9 8l1.6-2s-1.2-8 1.5-9.9.3 7.6.3 7.6l1.8-2s-.8-7.3 1.5-9c2.3-1.6.4 7 .4 7l1.6-1.8s-.5-6.8 1.7-8.4.2 6.5.2 6.5l1.7-1.6s-.4-6.9 2.4-8.2-.5 6.4-.5 6.4l2-1.6s.5-8 2.9-8.7c2.4-.8-1 7-1 7l1.7-1.4s.9-6.8 3.5-7.6c2.7-.9-1.6 6.2-1.6 6.2l1.7-1.3s1.9-6.8 4.4-7.6c2.4-.7-2.6 6.5-2.6 6.5l1.7-1.2s2.7-6.2 5-6.6c2.1-.4-2.6 5.1-2.6 5.1l2.1-1.2s3.5-6.4 4.8-4.5-5 4.9-5 4.9l-2 1.2s7.5-3.6 8.4-1.8-10.3 3-10.3 3l-1.8 1.2s7.5-2 6.6-.1-8.4 1.5-8.4 1.5l-1.7 1.2s7.5-1.8 6.5 0c-1 1.6-8.3 1.5-8.3 1.5l-1.8 1.5s7.3-2 6.2.3-9.4 2.1-9.4 2.1l-2 2s7.7-2.7 7-.6c-.6 2-9.4 3-9.4 3l-2 2s8.3-2.7 5.8-.2c-2.4 2.6-8.5 3.2-8.5 3.2l-2.3 3s8.2-5 7-2.2-9.2 4.7-9.2 4.7l-1.6 2s7.4-4.3 6.6-2c-.7 2.5-8.6 5-8.6 5l-1.3 1.8s8.7-5.2 8-2.5c-.8 2.6-9.1 4.5-9.1 4.5l-1 1.7s8-4.7 8-2.4c.2 2.2-9.4 4.4-9.4 4.4z"/>
18
+ </g>
19
+ <use xlink:href="#vu-b" width="100%" height="100%" transform="matrix(-1 0 0 1 220 0)"/>
20
+ </g>
21
+ </svg>
@@ -0,0 +1,5 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" id="flag-icons-wf" viewBox="0 0 640 480">
2
+ <path fill="#fff" d="M0 0h640v480H0z"/>
3
+ <path fill="#000091" d="M0 0h213.3v480H0z"/>
4
+ <path fill="#e1000f" d="M426.7 0H640v480H426.7z"/>
5
+ </svg>
@@ -0,0 +1,7 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" id="flag-icons-ws" viewBox="0 0 640 480">
2
+ <g fill-rule="evenodd" stroke-width="1pt">
3
+ <path fill="#ce1126" d="M0 0h640v480H0z"/>
4
+ <path fill="#002b7f" d="M0 0h320v240H0z"/>
5
+ <path fill="#fff" d="m180 229.3-20.7-14-19.9 14.1 6.5-24.9-19-15.2 24.5-1.5 8.1-23.6 8.8 24 24 .7-19 16.3zm-3.6-165.6L159.8 53l-16 10.4 4.4-20-14.6-12.7 19.4-1.6 7.2-18.6 7.4 18.7 19.1 1.7L172 44.3zm-73 59.5-16-11-16.7 11 5.2-19.4L60.8 91 80 90l7-19 6.8 18.9 19.6 1.1-15 12.5zM250 110l-15.4-10-15 10 4.4-18.3-14-11.8 18.3-1.5 6.3-17.2 7 17.4 17.7 1-13.7 12.3zm-43.1 43.4-10.3-6.4-10.3 6.6 2.7-12.3-9.2-8.3 12-1 4.6-11.6 4.9 11.6 11.9 1-9.1 8.3z"/>
6
+ </g>
7
+ </svg>
@@ -0,0 +1,5 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" id="flag-icons-xk" viewBox="0 0 640 480">
2
+ <path fill="#244AA5" d="M0 0h640v480H0z"/>
3
+ <path fill="#D0A650" d="M253 224.8s1.2-.8 1.6-.9l2-.6s1-.5 1.5-.5 1.6.6 2 1.1 2 1.4 2 1.4 1.2.4 1.5 0q.4-.6 1.3-.7.7-.2.6-.9c-.1-.7.2-.9.6-1.4.5-.5 1.3-.8 1.3-.8s1.2-.5 1.3-1.2 1.3-1.2 2-1.3c.7 0 0-.4 1.8-.2 1.7.2 2-.4 2-.9.1-.5 0-1 1.1-1q1.6.4 1.6-.4c0-.6 1-1-.7-1.4-1.8-.5-1.6-.1-1.8-1 0-.7 0-.6-1.1-.7s-.6-.7-.7-1.3q-.2-.9-.6-1.3c-.3-.4-.9-.4-.9-1s-.1-1-.7-1q-1 .1-1-.5 0-1 .8-1 1-.2 1-1.2c-.2-.6-.2-1.9-.2-1.9l.9-1s2.6-2.1 2.8-2.5 1.1-.7 1.5.1.6 1 1 1.4c.3.4 1.3.1 1.5-.3s.3-1.9.9-2.7q1-.9 1.1-1.8.2-1.3 1.2-1.2c.6 0 1-.9 1-1.4q0-.8 1.2-1.2c.8-.1 1.3-.6 1.6.2s.6.7 1.1 1q1 .6 1.8.3c.5-.4.7-1 1.3-.7q.9.5 1.2-.7l.3-1.9s.1-.5 1.1-.5.3-.6.8-1 .6-.8 1.3-.6 1.8-.3 1.3-1-1.8-1.6-1.1-2.4 1-2 .3-2.2c-.7-.1-1.8.1-1.9-.6-.1-.8-.4-1.4.5-1.5s2.2-.1 2.7-.5 1.8-.7 1.8-1.8.4-1.3.6-2 .1-2-.5-2.6-1.4-1.6-1.5-2q-.3-.7-1.6-1.3c-.8-.2-1.6-.4-1.6-1s.6.1.6-1.6-1.1-2-1.1-2l-1.7-1s-3-.8-3.8-.8-1.8-.8-.9-1.4 1.2-1.5.9-2.2c-.4-.7-.6-1.3-1.9-1.6q-2-.3-1-1.4c.5-.7.7-1.3 1.4-.7.6.5 1.8.7 2.7.3s1.3-.8 1.8-.3 1 .8 1.7.2 2-.8 2.6-.5c.5.4 2 .3 2.4 0s1.4-1 1.4-1.3.6-1.2 1.1-1.5 1.3-1.4 1.9-1.4.8-.7.8-1c0-.5.5-1.4.6-1.7s1.2-.8 2 0c.9.5 2 .8 2 .8s1 .2 1.7 0a2 2 0 0 1 2.1 0c.9.6 2 .6 2 .6l.3-1.3c0-.4.2-1.2-.3-1.5s-1-.7-.1-1.4 1-.5 1.9-.5l2.2.1c.7 0 1.8.7 1.8 1.3q.1.8 1 1.4c.6.3 1.3.6 1 1.2q-.3 1 .6.8 1 0 .9.9-.1.7 1 1 1 .4 1 1.2c0 .8-.2.9 0 1.4l1 1.4s1.3 1.5-.4.7c-1.6-.7-2-1-2.5-1l-1 .5-1.3.2c-.6 0-1.2 1.2-.2 1.4q1.3.2 1.2 1.2c-.1 1-.3.5-.8 1s-.8.2-1.6.2-1 .7-1 1.3.3.6.6 1q.6 1 1.6.2c.5-.5 1-.9 1.3.1s.9 1 1.5 1q.9.1 1.6-.4 1-.5 1.3.9.4 1 1.3 1.3t1 1q.3 1 1.1.5 1.1-.7 1.9-.1l.9 1.2v1.1l2.3.8.2 1q0 .6 1 .4h1.6s.8-.3.8-1q0-.9 1-.8c.5 0 1.8.5 2.1-.2s1.4-.8 2.2-.5l3 1.2s-.3 0 .4 1.1 2 1.1 2 1.1 0 1 .3 1.4 1.3.6 1.8.2q1-.8 2.1-1c1.1-.2 1.2 0 1.2-.4s-.7-.7-.7-1.4.7-.6.8-1.3c.1-.6.8 0 1.3.4s1 .8 1 1.2c0 .5 1 2 1.5 2.2s2.1.3 2.6-.2 1.6-.8 1.5.5-.4 1.4.4 1.8 1 2 .3 2.4-1 .5-1 1.2-.2 1.6.4 2q1 .7 1 1.2c0 .5.6 2.4.6 2.4s.4 1.9.2 2.3c0 .5-.3 1.2.7 1.1q1.4-.3 1.3.7c-.1 1 .4 1.2-.2 1.5s-1 1.4-.4 1.6q.9.3 1.2 1c.1.4 1 1.2 1.6.7s.7-.6 1.2-.7.8-.4.3-1q-.7-.8-.1-1.4c.5-.3.7-1.3.7-1.3s.7-1 1.5 0 1 .6 1.5.6.8.5.8 1 1.2.5 1.2 1.3l.2 3s0 1.1.7 1.5q1 .6.2 1-.3 1-.2 2c.1 1 .2.5-.3 1q-1 .7-.5 1.6c.3.6.2 1 1.1 1.8 1 .7.9 1 .9 1.6 0 .5.9 1.3.9 1.8s.7 1.2 1.3 1.3 1.2 1 1.2 1.6l.1 1.9s0 .3.6.3 1.2.8 1.4 0c.2-1 1-1 1.4-1.3s1.4-.6 1.9-.3 1 .3 1.5.3l2.6.1s.6 0 1 .8c.3.8 1.3 1.8.8 2.2s-.6 1.3 0 1.3 1.5 0 1.5.5q-.2 1 .7.7.8-.5 1.1 0t1.3.7q.8.4 1.2-.3c.3-.4 1.7-.8 1.7-.8s1.8-.5 2.5-.3l1.7.7s.4 1 .2 1.7-.5.5-.2 1.5-.3 1-.7 1q-.9-.5-1 .7c0 .8-.4 1-.4 1.8s0 .6-.5 1q-.8.6.1 1c.7 0 .5.8.5 1.2l-.1 1.4s0 .5-.7.5-1.5 0-1.6.5-1 1.3-.3 1.9q1 .7.1 1c-.4.3-.8 1.3.2 1.6q1.2.5.2 1.1c-.6.4-1.7.8-1.7 1.4s-.3.6-1 .7q-1.2.3-.2 2c.8 1.1 1 1 1.6 1s.6-1 .6-1l2.5.2q1 0 1.9-.3c.5-.4 1.7-.9 1.7 0s.3 1 .8 1.3c.6.5.7.1 1.2.8.5.6.6 0 1-.7.3-.7 1-1.4 1.6-.6.5.9.5.6 1.2.6s1 .4 1 .9.6.5 1.5.4.9.5 1.2 1 .5.4 1 .4q.7.1 1.2-.4c.4-.4.8-1 1.3-.3s1.4.5 1.6-.2c.3-.8 1.3-1.4 1.9-.6.6.9 1 .9 1.6 1q1-.2 1.7.6c.4.6 1.5 1.4.7 2s-1.7 1.5-1 1.8a3 3 0 0 1 1.6 1c.5.4 2 .7 2.7.8.7 0 1.2.2 2-.5s1.7-.6 1.6.3.3 1.8.3 1.8.6 1.4.6 1.9-.1.6 1 1.3c1 .6.8 1 1.7.4q1.1-.8 1-1.5v-1.7s1.2-.2 1.6-.5c.5-.4 2.3-1.3 2.8-.9s1 .3 1.5.1l1.9-.2c.4 0 1.2.1 2.2-.6.9-.8.9-.6 1.5 0q.7.8.2 1.6c-.4.4 0 1.3.8 1.3s1 .5 1 1l.3 1.7c0 .4 0 .7 1.4 1 1.2.3 1 1 1.2 1.6q.6.9-.4 1c-1 .1-1 .3-1 .8-.2.5-1.2.7-1.2.7l-1-.2s-.8 0-1.1.4-1 1.3-.6 2q.7 1.1 0 1.6c-.4.3-.7 1.9-1.1 1.6-.5-.4-1 0-1.5.3s-.4 1.7.5 2.2q1.4 1.1 1.2 1.3l1 1.6s-.3.3-.5.9c-.3.5-1 1.6-.3 1.8s.4 1.4-.3 1.4-1.5-.4-1.6.5-.5.6-1.2.5-2.4-.5-2.9.3-.6 1.2-1.4 1.1-.5 1.3-.2 1.8l1 1.3s.7.5.7 1.6q-.1 1.4-1 .2c-.4-.7-1.3-.6-1.4.2s-.3 2.2-1 2.2q-1.2 0-1.6.6c-.3.4-.9 1.2-.9 1.6s-.1.9-.7 1-.7 1.2-.7 1.2-1.4.3-1.5.8.1 1.4-1 1.5a3 3 0 0 0-2.2 1.4q-.7.7 0 1.5c.7.8.8 2.2 1.4 2.5q.9.3.9 1.3c-.1.9-.8 1.5.1 1.5q1.6-.1 1.2 1c-.4.7-.4.8-1 1.1-.8.4-1.1.4-1.1 1.2s.2.9-.4 1.2-.6.7-.6 1.4-.2.4-.9 1.1q-1.2 1-2.2.6c-1-.4-.7-.2-.8-.9s-1.1-.6-1.7-.5-1.4.7-1.4.7-1 .7-.6 1.2.2 1.4-.6 1.3-2.6.8-3.2-.1-2.2-1.6-2.5-.3c-.2 1.2.7 1.1.6 2.4s-.3 1.3-.8 1.7q-.5.6-.6 1.3c0 .5-.2 1.7.6 2.1s1.2 1.6 1.2 2.3q-.2 1.1.8 1.3 1.5.2 1.6-.9c.1-.7 1.7-1.2 1.9.3q-.2 2.1.7 2.9c.5.6 1 1.5 1.5 1.8s1.2 3 1.2 3c-1.1.3-1.4 1.8-2.1 2-.4.2-.9 0-1.3.3q-.1.6-.6.8c-.9.4-.7-.9-1.8-.4-.9.4-1 1.5-2.3 1-.7-.2-1.1-3-1.3-3.6l-1.1-1.8c-.8-1.2-2.3 0-2.8-.4-.8-.5-.5-1.4-1.7-1.5-2.4-.2-.7 1.5-1.7 1.8-2 .7-2-1.8-3.4-.6-.5.4 1 .7.6 1.4-.3.6-1.7 1.6-1.7 2.3.2 1 1.2 1.3 1.5 2 1 2.3-.5 3.8-2.7 2-1.2-.9-1.5-2.7-3.3-2.5l-1 .5c-.5 0-.8-.4-1.3-.3-.7.3 0 .8-.2 1.2 0 0-1 .7-1 1-.6.6-.4 1.2-1.2 1.8-.6.5-1.1.2-1.8 1-.7.7-.8 1.9-1.7 2.6-.5.4-.8-1.1-1.4-.1l-.2.4q-.3.4 0 .7c1.2 2.4-1.4 3.2-2.2 4.9-.3.7.6 1.3.3 1.9l-1.5 1.7c0 .2-.2.8-.4 1s-1 0-1 .4.8.7 1 .9-.2.7 0 .8c1.2 1.3.5.9 1.1 2 .1.2.5-.1.7.3s-.4.4-.2.8c0 .2 1 1.4 1 1.4 0 .4-1.8 1.2-2.2 1.2-1.1 0 1-2.2-.8-2.2-.8 0-.9 1.7-1 2h-1c-1.2 0-2 1.4-2.4 1.5s-1-.2-1.5 0c-.4 0-1 .5-1.4.5q-.4 0-.7-.4c-.5-.3-1.5-.4-2-.6-.4 0-1 .4-1.2.3-.3-.2.3-1-.6-1.4l-.7-1.7q.6-1.5.5-3.1c-.2-1.1-2-2-2.4-3-.3-.6-.6-2.4-1.3-2.8a6 6 0 0 1-1.8-2.2c0-.2.3-.6 0-1q-.6-.4-1-1c-.1-.4 0-1.8-.5-2.1s-4-.8-5-.9q-.6 0-1-.3l-.6-.7-1 .2h-1c-1.1.7-1.4 1.7-2.5 2.6-1.1.8-2.3.8-3.4 1.7-.7.6-1.2 2.1-1.9 2.8-.3.3-.7 0-.8.1l-2 1.8q0 .3-.2.5l-1.3.4h-1.2c-.5.2-.5.8-2.5 1.2l-.5.3-.6.5h-.9c-.5 0-.8.5-1.2.5-1 .2-2.8-.5-3.6-.1-.5.1-1.8 1.7-2.3 1.8q-.4.1-1-.1l-.6 2.2-2.4 2.1-.8 1q-.5.5-1 .5l-1.6-.4c-.8-.2-3.3-.3-4-.1-.9.1-.6 2.4-2.6 2.6l-3.3.4c-.1 0-.8-.4-1.5-.3-.3.1-1.1 1-1.1 1.2v.5l.2.4c-.4.5-1.4 1.3-1.7 2l-.4.4c-.2.2-1.6.7-1.7.9-.3.8 1 1.6.8 1.9-.3 1-1.7 2-2.2 3-.1.4.5 1.7.5 2.1q-.5 2.1-.5 4.1l.2 1.7.7.5 1.8 3.6c.3 2.2-3 1.4-1 3.6q.2.6.8 1l2.8 2.3c0 .4-2 .7-2.3 1-1 1-1.7 2.6-2.6 3.6-.6.5-1-.1-1.8 1.3-.2.5 0 1.6-.3 2-.5.4-.8-.2-1.3 0-.2 0-.3.7-.5.8-.5.5-5.2 3-5.6 2.7-.2-.1-.5-.9-.5-1.1q-.1-.6-.6-1c-1.2-1-3-1.3-4.2 0l-.7 1-2 1.6-.5.5c-.5 0-1.6-1.3-2-1.7-.4-.6-2-2-2.1-2.7 0-2.4-1.9-4.9-2.6-7.2h1.1c1.3-.9 1-3 3.3-2.2.3-.4.3-.8.8-1l.7-.5c.8-1.2 1.7-5.8.9-7-.7-1-1.5-1-2-2.7q-.1-.7 0-1.6l-1-3.1-.7-.7-.2-3.1c-.7-2.2-3.4-3.5-3.5-3.8l-1-1.7-.6-1.6c-.1-.3-.6-.6-.6-.9 0-.6 1.6-1.7 1.5-2.7 0-.3-1-1.3-.8-1.8s1.2-1.8 1.2-2.5c0-.8-1.6-2.6-1.8-3.4-.1-.5.6-.8.4-1.1s-1.8-1.9-2-2.3c-.3-.3.5-.7 0-1.3-.6-.5-.1-.4-.3-.8l-1-1.5c-.2-.5-1.6-5.5-1.5-5.8q-.5-.4-.9-1l-.4-1.2s-1.6-.5-1.9-1c-.2-.3-.3-1.6-.7-2.2l-.7-.4-.3-.7c-.5-.6-1.4 0-2-2.4q-1.4-.8-2.4-1.8l-.4-.4q-1-.2-2-.7c-.3 0-1.8 0-2-.2l-.4-.8c-.8-.1-2.2 0-2.9-.6-.5-.5-.6-2.8-1.6-2.5h-.4c-.7-1-2.9-1-3.8-1.6-.2-.1-1 0-1-.2l.1-1.3-1.1-1.4c-.9-.2-.6-.3-1-.6-1.5 0-1.7.2-2.6 1q-.4.3-1 .4c-.5.3-.6 1.2-1.3.8l-.6-.5c-.4-.4-.6-.2-.8-.8-1.2-.7-4.5 1.5-5.2 0-.6-.3-1 0-1.5-.4-.2-.2.7-3-1.7-4l1.6-1.1q.2-.6 0-1c0-.5.3-1.4.2-1.7l-.5-1-.2-1.2-.8-.4q-1-.6-1.7-1.4l-.4-.5c-.4-.3-1.8-.8-1.8-1.4l.4-.5q0-.5.3-.8c.6-1 2.1-.5 1.9-2.2-.1-.8-.7-1.4-.8-2.2l-.5-.7c-1.5-.1-1.3-1.6-1.8-2-1.5-1-2.7-.4-1-2.4.2-.7-1.5-1.8-1.8-2.1-.6-.6-.3-1.9-.6-2.5 0-.3-1.1-.9-1.4-1.3l-.5-1v-.1q.4-.6 0-1c-.1-.3-.6-.2-.7-.4q-2-1.6-4.9-2.5c-.5-.2-.3-.6-.8-.8l-3-1.2c-.2 0-.4-1.1-.6-1.5l-.9-1c0-1-.6-1-1.4-1.6v-.6l.6-2.1c.1-.4.6-.8.5-1.2l-.4-2.3c-.8-2-1.7-1.8-1.2-4.5q-.2-.8.3-1.4l.2-.3 1.2-.9c.4-.6.7-1.9 1.2-2.3l1.8-1.2c.2-.2.4-.9.3-1.2l-1.2-.2-1.1-.4-.3-.5-.2-.2q-.8-.1-1.4-.5l-1.7-.5c-1-.5-2-2-2.9-2.2-1.2-.3-2 .1-3.2.2-.7 0-.7-.4-1.3-.6-.8-.3-.2.4-2-.2-.3-.2 0-.8 0-1h-1c-1.4-.4-.9-1.8-1.3-2.7-.1-.2-.8-.2-1-.2l-.2-.2.2-.1c.2-.4-.7-1.4-.7-1.6.1-.3 2-.6 2.2-.6q0-.4-.2-.7.1-.8.5-1.7v-.2c-.6-.3-.7-.7-1.2-1q.1-.4.4-.7c.9-2.5 2.3-.5 3.5-2.8l.6-1.1h.2q.4.1.8 0l.8-.3h.5c2.2-.4 1.7-1.2 3-2.1.4-.3 1.4-.4 1.8-.6q.7.6 2.1 1.4c.7.2 3 .7 3.4 1 .5.2.6.8 1 1 1.3.8.5-.4 1.8-.2s2.3 1.4 3.5 1.9l1-.1c.3-.1 2.3-.5 2.5-.4l.8.3c.3.1.5-.5.8-.5.8.2.8.5 2 .4 0 0 .6-3.3 1.2-3.4.3-.1 1.2.7 1.4.8.4.1 0-.7 0-.7-.2-.3-.8-2.3-.7-2.5l.8.1q1-.2 2-.9l1-1.5c.1-.2-.2-.8 0-1l.9-.6c.4-.4.4-1 1-1.3 2-.2 2.7-1.8 4.6-2h.6l.4.6c0 .1 1.3.9 1.5.8q.3-.1.5-.4c.3.1 1.4-.5 1.5-.9l-.1-.6 1.6-1.2h1.4q.2.4.5.6h1.2c.2 0 .3-.5.7-.5"/>
4
+ <path fill="#FFF" d="M351.9 73.4 368 123l-42.2-30.7H378L335.8 123zm62.8 11.1 16 49.6-42.1-30.7h52.1l-42.2 30.7zm59.9 21.8 16 49.6-42.1-30.7h52.1L458.4 156l16.2-49.6zM288.1 73.4 272 123l42.2-30.7H262l42.2 30.7zm-62.8 11.1-16 49.6 42.1-30.7h-52.1l42.2 30.7zm-59.6 21.8 16.2 49.6-42.2-30.7h52.1l-42.2 30.7z"/>
5
+ </svg>
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" id="flag-icons-xx" viewBox="0 0 640 480">
2
+ <path fill="#fff" fill-rule="evenodd" stroke="#adb5bd" stroke-width="1.1" d="M.5.5h638.9v478.9H.5z"/>
3
+ <path fill="none" stroke="#adb5bd" stroke-width="1.1" d="m.5.5 639 479m0-479-639 479"/>
4
+ </svg>
@@ -0,0 +1,7 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" id="flag-icons-ye" viewBox="0 0 640 480">
2
+ <g fill-rule="evenodd" stroke-width="1pt">
3
+ <path fill="#fff" d="M0 0h640v472.8H0z"/>
4
+ <path fill="#f10600" d="M0 0h640v157.4H0z"/>
5
+ <path fill="#000001" d="M0 322.6h640V480H0z"/>
6
+ </g>
7
+ </svg>
@@ -0,0 +1,5 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" id="flag-icons-yt" viewBox="0 0 640 480">
2
+ <path fill="#fff" d="M0 0h640v480H0z"/>
3
+ <path fill="#000091" d="M0 0h213.3v480H0z"/>
4
+ <path fill="#e1000f" d="M426.7 0H640v480H426.7z"/>
5
+ </svg>
@@ -0,0 +1,17 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" id="flag-icons-za" viewBox="0 0 640 480">
2
+ <defs>
3
+ <clipPath id="za-a">
4
+ <path fill-opacity=".7" d="M-71.9 0h682.7v512H-71.9z"/>
5
+ </clipPath>
6
+ </defs>
7
+ <g clip-path="url(#za-a)" transform="translate(67.4)scale(.93748)">
8
+ <g fill-rule="evenodd" stroke-width="1pt">
9
+ <path fill="#000001" d="M-71.9 407.8V104.4L154 256.1z"/>
10
+ <path fill="#000c8a" d="m82.2 512.1 253.6-170.6H696V512H82.2z"/>
11
+ <path fill="#e1392d" d="M66 0h630v170.8H335.7S69.3-1.7 66 0"/>
12
+ <path fill="#ffb915" d="M-71.9 64v40.4L154 256-72 407.8v40.3l284.5-192z"/>
13
+ <path fill="#007847" d="M-71.9 64V0h95l301.2 204h371.8v104.2H324.3L23 512h-94.9v-63.9l284.4-192L-71.8 64z"/>
14
+ <path fill="#fff" d="M23 0h59.2l253.6 170.7H696V204H324.3zm0 512.1h59.2l253.6-170.6H696v-33.2H324.3L23 512z"/>
15
+ </g>
16
+ </g>
17
+ </svg>
@@ -0,0 +1,27 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" id="flag-icons-zm" viewBox="0 0 640 480">
2
+ <defs>
3
+ <clipPath id="zm-a">
4
+ <path fill-opacity=".7" d="M-170.7 0H512v512h-682.7z"/>
5
+ </clipPath>
6
+ </defs>
7
+ <g fill-rule="evenodd" clip-path="url(#zm-a)" transform="translate(160)scale(.9375)">
8
+ <path fill="#198a00" d="M-256 0h768v512h-768z"/>
9
+ <path fill="#ef7d00" d="M421.9 184H512v328h-90.1z"/>
10
+ <path fill="#000001" d="M331.9 183.8h90v328h-90z"/>
11
+ <path fill="#de2010" d="M240 184h91.9v328h-92z"/>
12
+ <g fill="#ef7d00" stroke="#000">
13
+ <path stroke-linejoin="round" d="M451.6 65.6s34-14.5 37.2-17.5c1.5 1.8-13.6 20-42.9 26.7 26.6-6.2 49.3-26 54-25.4 1.3.3 1 19.3-60 35.8 42.2-11 66.7-31.4 66.4-29.2.3.5-4.2 16-41.1 28.1 10.3-2.4 38.3-19.4 38-16.1.9 1.3-27 37.2-77.6 25.5 40.4 10.5 66.5-14.8 70.2-14.3.8.1-7.4 22-58.2 23.4 24.3-2.5 17.3-.1 17.3-.1s-14.3 11.2-31.7 3.6c13.6 3.7 15.1 3.9 15.4 5-.9 1.6-12 3.8-22.9-2 8.7 3.6 16.5 4.2 16.6 5.5-.1.4-5.6 3.6-10.6 1.3s-50.3-30.1-50.3-30.1l77.4-21.3 2.8 1zm-91 75.6c-6.8 0-7 6-7 6s-.5.5-.2 3.4l1.7-2.6c.8.1 3.9 1 8.8-2.8-4.5 4.7-1.8 6.4-1.8 6.4s-1 3.7 2.4 4.4c-1-1.5-.4-2.8-.4-2.8s4.8-.5 4.5-6.3c.1 5.3 3 6.6 3 6.6s0 2.9 3.1 3.2c-1.6-1.5-1.3-3.8-1.3-3.8s4-3 .7-8c2-1.2 3.7-4.5 3.7-4.5s-2.8-1.2-4.1-2.2c-.6-1.3 0-8.5 0-8.5l-1.8-9.3-4.8 14.5c.2-2 .3 6.3-6.5 6.3z"/>
14
+ <path stroke-linejoin="round" d="M394.2 120.3c.2.1 5.1 5.6 9.9 5.3 1.8-1.5-3.7-4.7-3.7-5.5 2 1.8 10.1 8.8 15.4 6.3 2-3-3.8-2.5-10.2-10.6 4.5 3 15.7 9.5 21 7 2.1-2.4-11.7-9.9-16.4-15.7l-12-6.1-16.2 13.3 12.3 6z"/>
15
+ <path stroke-linecap="round" stroke-linejoin="round" d="M375.9 74.8s5.5-3.2 27.6-1.6c2.4.3 15-4.3 19.1-5.7 6.4-1.2 27-5.6 32.4-9.8 4-.5-1 7.1-6 9-5.2 2.3-24.1 8.9-30.9 8 8.1.1 3.6 6.7-9.8 3.6 6.4 3.6 4 4.2 4 4.2s-11.3.6-14.3-2c7.6 2.9 4.4 4 4.4 4s-7.7.7-11.3-1c5.5 1.7 2.7 2.7 2.7 2.7s-4.5.8-8.2-.6c-3.8-1.3-9.4-10.7-9.7-10.7z"/>
16
+ <path stroke-linejoin="round" d="m384.7 123.4.8 14.6-.8 1.2c-.3.4-10.3-1.6-9 6 0 3.2 0 4 2.2 5.7-.5-2-.4-3.5-.4-3.5s2.9 1.7 5.6-3c-1.9 4.6-.6 6.3-.1 6.4.4.8-.8 4.5 3 4.4-1.5-1.4-.8-3.4-.8-3.4s4-.6 2.6-7.7c1.4-1.4 2 0 2 0s.4 4.2 3.9 3.3c1.5.9-.3 3.2-.3 3.2s2.5 0 3.3-2c.7-2.2 1.6-6-2.5-7.6-.5-1.5 1.6-1.6 1.6-1.6s2.6.9 3.4 2.2.5-3.4-2.8-4c-4 0-4.2-.9-4.2-1l-1-13.7z"/>
17
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.1" d="M398.6 135.8c0-.7-6.8-9.9-5-11 1.7.3 4.5 4.5 6.9 3.1-.7-1.6-2.8-.7-5.1-4.9-2.4-4.8-2.7-11.9-11-19.6 5.4 8.2 17.4 13 18 10.6s-10.7-11.4-10.1-13.6c2.2 4.4 13.4 14.4 21.6 13.6.6-2-6.7-5.8-8.6-9.4-5.3-3.6-19.4-15.7-19.6-18.5a33 33 0 0 0-9.9-10.6l-.8-1.7c-3.2-7.5 1-10 3.5-10.3 2-.3 2.6 0 4-.7l-5.1-2c2.3 1.7 8 .2 6.8 5 2.5-1 7.9-7.4-6.1-8.8-4.6-5.2-23.3-8.2-28 14.6.4.3.6.6 1.8 1.4-6-2.8-21.9-5-27.6-6-15.6-4.4-31.7-15.2-33.2-13.9-2 1 9.4 11.6 8.8 11.8a263 263 0 0 0-27.5-13.6c-6-2.2-11.9-7.4-12.5-6.4-2.2 4.5 9.5 15.9 11.7 17.2s19.3 9.3 19 9.4c-25.8-11.7-30-13.9-31.4-15.2-2.3-.5-7.8-8-9.3-7.5-.9.8.8 12.6 13.1 18 2 1.4 26.4 10.1 26.2 10.8 0 .2-28-11.5-29-12-5.4-2-12-9.4-13.2-8.6s3 8.8 8.4 11.3c2.9 1.2 13.8 6.6 23.6 10 .6.3-17.7-6.9-26.5-10.5-4-2.2-5.8-5-6.4-4.4-1 .6 1.4 12.4 29.7 19 .7.4 10-2.1 9.5-1.8a113 113 0 0 1-15.8 2.8c-.3.8 1.8 5 16.4 4.2 1.8-.1 12-3.7 11.1-3a174 174 0 0 1-14.8 4.9c-.9 0-5.6.6-5.8 1-.2.8 3.5 3.8 11.3 4.2 7 .4 20.2-4.2 20-3.9-.4.3-12.8 4.6-13.1 4.8-.5.3-5 .5-5.2.9-.4.9 6.6 7.4 27.1.4-2 2.8-12 4.7-12 5.2s2.2 2.5 5.7 3.3c1.7.4 4.1.3 6.3 0 4-.8 8-2.3 13.3-7.2.6 1.5-13.1 8.5-12.5 9.1 3 2.8 12.9-.3 13.5-.7.7-.3 19-10.7 19-12 .3 1.6-23.7 14.7-23.4 15.2 1.5 2.4 9.7-.1 10-.4l10.8-5.8c.3-.1-11.8 7-10.8 8.2-.5 4.7 19-3.2 20.5-4.2.7-.5-9.4 4.4-9.4 6.7 3.3 5.5 13.7 3.8 15.3 2.6.8-.6-1 4-.4 3.6a16 16 0 0 0 3-4.3c-.2 1.6-1.4 4-2 6.8s-.9 5.9-1.8 9.2c-.2 1.4 6.4-2.9 5.4-13.2.6 5.4-2 15.4-1.3 16 1.3 1 5.2-5 5.6-9.1 1.1 2 3.5 6.3 5.6 7.3-.2-3.1 0-3-1-6q.8-6.3.8-16.1c5.6 10.7 7.9 15.3 6.3 23.5 1.7.7 4.3-5.8 4.1-9a13 13 0 0 0 11.5 10.2"/>
18
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.1" d="M305.4 67.7s-3.9 2.9-8.6 2.7c1.2 4.8 11 1.1 11 1.1s-4.7 5.3-8.1 6.1c2 1.7 10.6 1.1 12 .3s4-4.2 4-4.2-8.8 10.2-10 10.1c-.3 1.2 9.1.8 11-1s7-4.4 7-4.4-13 9-13.5 9c4.8 1.2 14.5-1.6 20.7-5.4-9.2 6.1-10 7.2-14.7 9.3 4.2.9 6.3 3.7 20.3-2.4 8-3.8 12.6-10.8 12.6-10.8a82 82 0 0 1-21.6 18c-.5 1 9.4 5.2 21.9-7.9"/>
19
+ <path stroke-linecap="round" stroke-width="1.1" d="M373.4 96s.9 4 4.3 7 3.6 6 3.6 6m-9.5-39s1.1 3.7 4.6 6c3.6 2.2 9 9.4 9.3 10.7.4 1.5 2.5 12.6 2.3 13.8m-37.8-25c.2 1.5-5 8.3 2.2 16.4-6.6 8-6.6 9-6.6 9s3.7 2 10.2-3.6c10.8 13.2 7.2 19.2 7.2 19.2"/>
20
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.1" d="M362.3 107.2s-1-1.4.8-6.7c1.6 2 3.4 2.3 4.1 3 .8.9 9 2 9.4 7.5"/>
21
+ <path stroke-width="1.1" d="M371.9 57.5c0-.4-1.7-4-7.8.4 3.3.2 6.5 2.1 7.8-.4z"/>
22
+ <path stroke-linejoin="round" stroke-width="1.1" d="M430.1 73.5c.3.2 18.2 4 24.2 2.1-7.6 10.2-22.9 3.3-22.9 3.3 7.5 2.2 7.8 2 10.2 4.2.8 2-13.8 1-18.5-1.7 13.3 4.2 13.6 4 14 5.5.6 2.3-21.8-.6-23.7-3.5 6 4.6 9.2 5.5 12.5 7.6-4 1.8-11.5 3.6-25.2-6.1 18 16.4 34.3 15.4 36.9 18.3-6.3 9.3-30.7-5.5-41.9-13s24.5 18.1 27.8 17.7c-1.6 2.5-13.4.3-14.2-1"/>
23
+ <path stroke-linecap="round" stroke-width="1.1" d="M434.7 90.7c-2 .3-8.3.3-9.2.1"/>
24
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.1" d="M300.1 65s13.6 7.2 19.4 6.7a10 10 0 0 1-3.8 2c1.4.6 5.4 2.7 11.4 1.4l-3.3 3s5.2 2 11-1l-2.8 3.7 4.1.3"/>
25
+ </g>
26
+ </g>
27
+ </svg>
@@ -0,0 +1,21 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="flag-icons-zw" viewBox="0 0 640 480">
2
+ <defs>
3
+ <clipPath id="zw-a">
4
+ <rect width="546" height="420.1" x="1.9" y=".1" fill="#00f" fill-rule="evenodd" ry="0"/>
5
+ </clipPath>
6
+ </defs>
7
+ <g clip-path="url(#zw-a)" transform="matrix(1.1722 0 0 1.1426 -2.3 -.1)">
8
+ <path fill="#006400" d="M0 0h840v420H0z"/>
9
+ <path fill="#ffd200" d="M0 60h840v300H0z"/>
10
+ <path fill="#d40000" d="M0 120h840v180H0z"/>
11
+ <path fill="#000001" d="M0 180h840v60H0z"/>
12
+ <path stroke="#000" stroke-width="20" d="M0 0v420l280-210z"/>
13
+ <path fill="#fff" d="M0 0v420l280-210z"/>
14
+ <path fill="#d40000" d="M106.5 104.4 162 275.1 16.8 169.6h179.5L51 275.1z"/>
15
+ <path fill="#fc0" d="m82.8 253.7 9.8-1.8 18.1-.7 6.7.6 15 2.5 1.1-1.5V242l1.8-9.3 3-9.4 3.3-7.5 4.2-7.8 6.8 1.7h1.8l.2-1.3-14.4-12.3-15-11.5-21.7-16.2-2-.5-2.3-17-1.7-5.1-2.3-2-4.3-1.4-4.8.2-2.2 1.2-4.6 1-2.4.4-1.6 1.9-.2 2.4 6.7.2 1.7.7-.2.7-3.8.5-1.8.6 2.1 1.6 2.2.8 2.8 1 .6 2 .2 25.8-1.5 4-.5 7.5 2.2 9-5.6 6.4L77 216l-.6 3.5-1.7 3.5-.2 2.2 1.1 2.4 4.3 14.2 2.2 11.7z"/>
16
+ <path d="M88 142c-1.8 0-2.6.2-4.3 1.1a11 11 0 0 1-4.6 1.4c-2.5 0-4.5 1.8-4.5 4.1v1.5l3.6-.1c10.6.3 1 1.3.2 1.4-2.6.5.6 2.6 3.7 3.7 3.3 1 3.1.4 3.1 15 0 11.9 0 13.6-1 16.3-1.3 4-1.3 10 0 14 .6 1.6 1 3 1 3.3s-1.6 2.1-3.5 4.3c-3.5 4-5.6 8.1-5.6 11a6 6 0 0 1-1 2.6c-1.3 1.7-1.3 4.6-.1 5.7 1.3 1.2 6.6 21.8 6.7 25.7 0 1.4.2 1.4 8.3-.2 6.6-1.3 22.1-1.6 30-.6 3.6.5 7.8 1.3 9.3 1.6 4.8 1.3 4.6 1.5 4.6-4.3a74 74 0 0 1 5.1-26.7 95 95 0 0 1 6.9-14s1.8.2 4 .8c4.1 1 5.3.9 5.3-1 0-1-4.3-4.6-25.4-21a432 432 0 0 0-26.3-19.9q-1 0-1.3-.7l-1.5-9.5c-.7-4.9-1.7-9.7-2.1-10.7q-2-4.4-8.6-4.8zm.1 1h2c6.6.4 7.8 2.2 9.6 14l1.2 9.4q.1 1.1-3.2 3.3a47 47 0 0 0-10 9.5l-1.3 1.8-.3-4.2V165c.3-8.7 0-9.5-2.8-10.5-2.3-.8-5.3-1.6-4.5-2.1 1-.6 2-.2 4.4-.9 1-.2.9-.1.7-.9-.2-1.3-1.6-2-5.3-1.8-3 .2-3.3.1-3.1-.7q.7-2.4 4.5-2.9a13 13 0 0 0 4.4-1.3 7 7 0 0 1 3.7-1zm14.9 25.8h.4c1.7.3 50.8 38.7 50.8 39.8q0 .7-1 .7c-.4 0-12.9-3.5-27.7-7.8-23.6-7-27-8-28-9.3a5 5 0 0 1-.1-6.2 5 5 0 0 0 1-2c0-1.2-2.5 1.8-3 3.5-.5 2 .5 5.4 2 6.5.6.5 5.1 2 10 3.5 8.4 2.4 9 2.7 9.4 4.1 1 3.3-2.5 7.2-7.5 8.3a15 15 0 0 0-5.2 2.4 68 68 0 0 1-17.2 10.4c-.4.3-.9 1.9-1.2 3.4-.6 3.3-.8 3.8-1.8 3.8q-.8.1-.2-1.4c.7-2 .6-4.4-.1-4.4q-.7 0-.7 1.8c0 1-.3 2.2-.7 2.5-.5.6-.6.2-.4-2.3.2-1.7.1-3-.1-3-.5 0-1.4 2.5-1.7 4.7q-.2 2-.6-.3c-.3-1.2-.2-2 .7-3.5a9 9 0 0 0 1-3.5c0-1.3 1-2.6 5.7-7.3 3-3.1 6.7-7 8-8.7 2.3-2.8 2.4-3 2.3-5.9 0-1.6-.2-3.1-.4-3.3-.6-.6-1.4 2.6-1 4.3.2 1.6 0 2.1-3.3 6a113 113 0 0 1-7.5 7.8c-3.9 3.6-5.3 5.6-5.3 7.4 0 .6-.4 2-1 3.3s-.8 2.6-.6 2.9q.2.5-.3 0-.7-.6-.1-3a7 7 0 0 0 .2-2.6c-.5-1-1.2.2-1.5 2.7-.2 1.4-.5 2.5-.8 2.3-.7-.4-.5-3 .4-4.4.5-.7 1-2.3 1.3-3.6.7-3.7 2.3-6.7 5.8-10.7l3.2-3.8-1-3.3a25 25 0 0 1-.2-13.7q1.9-5.6 8-11.7c4-3.9 7.9-6.3 10-6.4m15 32.2a.9.6 0 0 1 1 .6.9.6 0 0 1-1.7 0 .9.6 0 0 1 .7-.6m2.5.3a.9.6 0 0 1 1 .6.9.6 0 0 1-1.7 0 .9.6 0 0 1 .7-.6m2.6.5a.9.6 0 0 1 1 .6.9.6 0 0 1-1.7 0 .9.6 0 0 1 .7-.6m2.4.5a.9.6 0 0 1 1 .6.9.6 0 0 1-1.7 0 .9.6 0 0 1 .7-.6m-6.3.6a.9.6 0 0 1 1 .6.9.6 0 0 1-1.7 0 .9.6 0 0 1 .7-.6m2.4.4a.9.6 0 0 1 1 .6.9.6 0 0 1-1.7 0 .9.6 0 0 1 .7-.6m5.2.2a.9.6 0 0 1 1 .6.9.6 0 0 1-1.7 0 .9.6 0 0 1 .7-.6m-2.7 0a.9.6 0 0 1 1 .6.9.6 0 0 1-1.7 0 .9.6 0 0 1 .7-.6m5 .6c.1 0 3.7.8 8 2l7.9 2.3-1.5 2.7-2.4 4.4c-1 2-1.2 2-6 .9-5.2-1.2-13.4-2.3-21.8-3l-8-.7 3-1.1 5.3-2.4c2-1.1 2.8-1.3 5.9-1q6.8.4 8.7-2.4l1-1.7zm-8.8.6a.9.6 0 0 1 1 .6.9.6 0 0 1-1.7 0 .9.6 0 0 1 .7-.6m5.6 0a.9.6 0 0 1 1 .6.9.6 0 0 1-1.6 0 .9.6 0 0 1 .7-.6zm-8 0a.9.6 0 0 1 1 .6.9.6 0 0 1-1.7 0 .9.6 0 0 1 .7-.5zm5.3.2a.9.6 0 0 1 1 .5.9.6 0 0 1-1.7 0 .9.6 0 0 1 .7-.5m-6.6 1.1a.9.6 0 0 1 1 .6.9.6 0 0 1-1.7 0 .9.6 0 0 1 .7-.6m2.5 0a.9.6 0 0 1 1 .7.9.6 0 0 1-1.7 0 .9.6 0 0 1 .7-.6zm2.6.2a.9.6 0 0 1 1 .5.9.6 0 0 1-1.7 0 .9.6 0 0 1 .7-.5m2.8 0a.9.6 0 0 1 1 .6.9.6 0 0 1-1.7 0 .9.6 0 0 1 .7-.6m-20.3 8.1a191 191 0 0 1 35.1 4.2c.1.1-.6 2.5-1.7 5.4l-2 6q0 .7-2.5.3c-8.3-1.3-32.3-1.2-41.5.2-5.3.8-6 .7-5.6-.4l1-3.5.6-2.7L93 221a63 63 0 0 0 10.2-6.5h.9zm-27 14.2q.5 0 1.6.8c1 .6 2.2 1.1 2.7 1.1 2.6 0 4 3.7 6.2 16l.8 4.4c.2 1 0 1.2-2.3 1.7-2.8.6-3.5.7-3.5.3 0-1-2.8-13.7-4-18.2l-1.6-6h.1zm28.6 2h2.9l-1 1c-1.7 2-2.5 2.1-3.7.8l-1-1.5c0-.2 1.3-.4 2.8-.4zm6.1 0h5.4l-1.2 1.2c-1.4 1.6-1.5 1.6-3 0l-1.2-1.3zm8.2 0h1.3c.7 0 2 0 2.8.2l1.5.3-1.4 1.3q-1.3 1.2-1.6 1.2l-1.4-1.6zm8.5.3 1.2.3c.7.2 2.2.3 3.3.4h2l-1.5 1.3-1.8 1.3c-.1 0-1-.8-1.7-1.7zm-30.2.1h.2q.1.5-1 1.7l-1 1.4-1.5-1.2-1.5-1.3 2.4-.3zm2.3.2 1.6 1.4 1.6 1.5-3 .2-3 .1 1.4-1.5zm18 0q.4 0 .8.3l1.3 1.7q.8 1.1-1 1l-2.5-.5-1.2-.3 1.3-1.3q.8-1 1.4-1zm-8.3 0q.7-.1 1.6 1.3c.7 1.1.7 1.1-2 1.1h-2.7l1.4-1.3q1-1 1.7-1zm17 .2 1.2 1.2q2.1 2 .6 2l-2.8-.3-2.2-.2 1.6-1.3zm-35.2.7q.5 0 1.6 1.2l1.2 1.3-2.5.4-3.5.5q-1.1.3 1-1.6 1.7-1.7 2.2-1.8m-3.7 0h.4c.8.2.8.4-.6 1.8l-1.5 1.5-.5-1.3c-.4-1-.3-1.3.6-1.7zm46 1.8q.3 0 0 .6c-.2.8-1.1 1-1.1.2q0-.3.7-.7zm-21.4 1.6c7.7 0 15.5.2 17.4.4 3.1.4 3.4.5 3.4 1.7 0 1.4-.4 1.5-4.6.8-1.2-.3-6.3-.7-11.2-1.1a150 150 0 0 0-28.5 1c-1.9.2-2.4 0-2.4-.6 0-1.3 10.2-2.2 25.9-2.2m-10.3 2.9h5.4l-1.2 1.3c-1.5 1.6-1.6 1.6-3 0zm7 0 1.4 1.4 1.4 1.6-2.9.1h-2.9l1.5-1.6zm2.1 0h5.4l-1.2 1.3c-1.4 1.6-1.5 1.6-3 0zm-12.8 0q.3 0-.7 1.5-1.2 1.5-1.5 1.6-.5-.1-1.5-1.3l-1.2-1.3H96a9 9 0 0 0 2.7-.4zm2 .5 1.3 1.2 1.5 1.3-2.6.2-2.9.2 1.4-1.5zm17.4 0 1.4 1.6c1.6 1.7 1.5 1.8-2.1 1.1l-1.7-.3 1.2-1.2zm2 0h2.4q3.8-.1 1.4 1.8c-1.2 1-1.2 1-2.6-.5zm-30.6.5c1.2 0 1.1.1-.4 1.6-1.1 1.1-1.2 1.1-1.6.3q-.3-1.6 2-1.9m38.8.2 2 .2 2.3.4-1.3 1.2-1.2 1.2-1.1-1.4-1-1.6zm-36 .5q.4 0 1.1.7c1 1 1 1 .2 1.4l-2.4.4H90l1.3-1.4q1-1 1.3-1.1zm34.1.3q.5-.1 1.2 1l.9 1.2h-2.1q-2 0-2-.6.3-.7 1.3-1.3zm6.4 1.3q.3 0 .2.5c0 1-.9 1.7-1.3 1q-.1-.5.5-1.1zm-25.9 1.2c8.7 0 18.3.6 24 1.6l1.6.3v4.4c0 3.3-.2 4.4-.7 4.4l-5-1a126 126 0 0 0-35-1l-2.3.3-.6-3.7-.4-3.8s2.3-.5 5-.8c3.3-.5 8.2-.7 13.4-.7"/>
17
+ <path id="zw-b" d="M124.8 217.8c-3 0-5.1 2.1-5.1 5.2 0 4.8 5.4 7.2 8.6 3.8s1-9-3.5-9m0 1.2a4 4 0 0 1 4 4c0 3-3.3 5-6 3.7-2.7-1.5-2.5-6.1.4-7.3z"/>
18
+ <use xlink:href="#zw-b" width="100%" height="100%" x="-20.1" y="-.6"/>
19
+ <path d="M88 145.3a1.7 1.8 0 0 0-1.6 1.7 1.7 1.8 0 1 0 3.5 0 1.7 1.8 0 0 0-1.9-1.7m.1.6a1.2 1.2 0 0 1 1.2 1.1 1.2 1.1 0 1 1-2.4 0 1.2 1.2 0 0 1 1.2-1.1"/>
20
+ </g>
21
+ </svg>
@@ -66,8 +66,8 @@
66
66
  document.documentElement.setAttribute("data-color-scheme", lightThemes.indexOf(theme) >= 0 ? "light" : "dark");
67
67
  })();
68
68
  </script>
69
- <script type="module" crossorigin src="/assets/index-BJpK26-r.js"></script>
70
- <link rel="stylesheet" crossorigin href="/assets/index-B_uYtqRM.css">
69
+ <script type="module" crossorigin src="/assets/index-B9pQ4U7M.js"></script>
70
+ <link rel="stylesheet" crossorigin href="/assets/index-BhNayHbp.css">
71
71
  </head>
72
72
  <body>
73
73
  <div id="root"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccdeck",
3
- "version": "3.40.1",
3
+ "version": "3.41.0",
4
4
  "description": "Local dashboard for Claude Code and Codex CLI sessions: which Claude Code session needs input, every tool call and Claude Code subagent live, token cost and quota, several Claude accounts. Run npx ccdeck.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -75,7 +75,33 @@
75
75
  "3.38.2",
76
76
  "3.38.6",
77
77
  "3.39.4",
78
- "3.40.1"
78
+ "3.40.1", "3.40.2"
79
+ ],
80
+ "3.41.0": [
81
+ {
82
+ "title": "📅 Plan account resets",
83
+ "body": "See the next seven days of resets, account capacity and which readings need refreshing."
84
+ },
85
+ {
86
+ "title": "📊 Follow quota history",
87
+ "body": "Inspect recorded Claude and Codex quota readings to see how remaining capacity changes over time."
88
+ },
89
+ {
90
+ "title": "♻️ See cached input reuse",
91
+ "body": "Session usage details now show the percentage of measured input reused from cache."
92
+ },
93
+ {
94
+ "title": "📻 A more polished Radio Explorer",
95
+ "body": "Find radio stations with compact search and filters, explore workspace streams separately, and save favorites from either source. Playback and keyboard navigation are more reliable."
96
+ },
97
+ {
98
+ "title": "🌍 Radio flags on Windows",
99
+ "body": "Country flags now display correctly in the radio station list on Windows."
100
+ },
101
+ {
102
+ "title": "🔧 Clearer Telemetry Radar controls",
103
+ "body": "Change individual telemetry flags and use a simpler Monitor view."
104
+ }
79
105
  ],
80
106
  "3.40.0": [
81
107
  {
@@ -9,6 +9,22 @@ const counters = value => ({
9
9
  const tokenTotal = row => row.inputTokens + row.outputTokens + row.cacheReadTokens + row.cacheCreationTokens;
10
10
  const date = value => typeof value === "string" && Number.isFinite(Date.parse(value)) ? value : null;
11
11
 
12
+ // Both ccusage providers normalize inputTokens to NON-cached input. Codex's
13
+ // raw input_tokens (which includes cache) must never be fed to this formula.
14
+ // ccusage/ccusage rust/adapters/codex/src/report.rs: non_cached_input_tokens.
15
+ export function sessionCacheReuse(rows, agent) {
16
+ let input = 0, cached = 0, measured = 0;
17
+ for (const row of rows) {
18
+ const values = [row?.inputTokens, row?.cacheReadTokens, row?.cacheCreationTokens];
19
+ if (!values.every(n => typeof n === "number" && Number.isFinite(n) && n >= 0)) continue;
20
+ input += values[0] + values[1] + values[2];
21
+ cached += values[1];
22
+ measured++;
23
+ }
24
+ return { pct: input > 0 ? cached / input * 100 : null, inputTokens: input, cachedTokens: cached,
25
+ measured, total: rows.length, unit: agent === "codex" ? "model groups" : "usage records" };
26
+ }
27
+
12
28
  export function validSessionLookup(agent, id, speed = "auto") {
13
29
  if (agent !== "claude" && agent !== "codex") return false;
14
30
  if (!["auto", "standard", "fast", "flex"].includes(speed) || (agent !== "codex" && speed !== "auto")) return false;
@@ -54,6 +70,7 @@ export function sessionDetail(raw, agent, sessionId, speed = "auto") {
54
70
  return {
55
71
  sessionId, agent, speed, totalCost: raw.totalCost, totalTokens: raw.totalTokens,
56
72
  ...usage, firstActivity, lastActivity, entries,
73
+ cacheReuse: sessionCacheReuse(agent === "claude" ? raw.entries : Object.values(raw.models), agent),
57
74
  models: [...models.values()].map(row => ({ ...row, totalTokens: tokenTotal(row) }))
58
75
  .sort((a, b) => b.totalTokens - a.totalTokens || a.model.localeCompare(b.model)),
59
76
  };
@@ -1,3 +1,4 @@
1
+ import { noteQuotaHistory, forgetQuotaHistoryAccount } from "./quota-history.mjs";
1
2
  // Fetches Codex/ChatGPT quota from the same endpoint the Codex CLI uses.
2
3
  // Auth (including token refresh) lives in codex-auth.mjs.
3
4
  //
@@ -366,7 +367,12 @@ async function doFetchCodexQuota() {
366
367
  const finish = (r) => {
367
368
  _cache = r;
368
369
  _cacheAt = Date.now();
369
- if (r.ok && !r.stale) _lastGood = r;
370
+ if (r.ok && !r.stale) {
371
+ noteQuotaHistory("codex", _accountOfQuota.get(r), r);
372
+ _lastGood = r;
373
+ } else if (["no_token", "api_key_mode", "refresh_rejected"].includes(r.reason)) {
374
+ forgetQuotaHistoryAccount("codex");
375
+ }
370
376
  return r;
371
377
  };
372
378
  const fail = (reason) => finish({ ok: false, reason, fetchedAt: started });
@@ -164,7 +164,8 @@ import { handleBrowserWatch, handleBrowserWatchDismiss, handleBrowserWatchSettin
164
164
  // The music routes, every one behind AGENTS_DECK_NO_MUSIC — see music-routes.mjs.
165
165
  import { handleBestOfNostalgia, handleCafeMusicBgm, handleClaudeFm, handleFmStation, handleGoodLifeRadio, handleLiveRadioMix, handleLofiGirl, handleRadioStations, handleRadioClick, handleMusicConfig } from "./music-routes.mjs";
166
166
  // The usage panel's quota and history reads — see usage-routes.mjs.
167
- import { handleCcusage, handleCcusageSession, handleCodexQuota, handleCodexUsage, handleProviderStatus, handleQuota } from "./usage-routes.mjs";
167
+ import { startQuotaHistory } from "./quota-history.mjs";
168
+ import { handleCcusage, handleCcusageSession, handleCodexQuota, handleCodexUsage, handleProviderStatus, handleQuota, handleQuotaHistory } from "./usage-routes.mjs";
168
169
  // The port fallback, one listen attempt, and the words for a failed one — see
169
170
  // listen.mjs. The loop that uses them is startServer's.
170
171
  import { listenFailure, portRetryable, randomPort, tryListen } from "./listen.mjs";
@@ -190,6 +191,7 @@ export function requestUrl(rawUrl) {
190
191
  }
191
192
 
192
193
  export async function startServer({ port = 4317, host = "127.0.0.1", persist = null, portRange = [4318, 4400], workspace = "", codex = true, claude = true, onRestart = null, onStop = null, cswapQuiet = null } = {}) {
194
+ startQuotaHistory();
193
195
  armLifecycle({ onRestart, onStop, persist, onSelfUpdate: () => reporter.noteSelfUpdate() });
194
196
  // Which tree and which CLIs, normalised once — see setDeckScope.
195
197
  setDeckScope({ workspace, claude, codex });
@@ -316,6 +318,7 @@ export async function startServer({ port = 4317, host = "127.0.0.1", persist = n
316
318
  if (req.method === "POST" && url.pathname === "/api/restart") return guard(handleRestart(req, res), res);
317
319
  if (req.method === "POST" && url.pathname === "/api/presence") return guard(handlePresence(req, res), res);
318
320
  if (req.method === "POST" && url.pathname === "/api/shutdown") return guard(handleStop(req, res), res);
321
+ if (req.method === "GET" && url.pathname === "/api/quota/history") return guard(handleQuotaHistory(req, res), res);
319
322
  if (req.method === "GET" && url.pathname === "/api/quota") return guard(handleQuota(req, res), res);
320
323
  if (req.method === "GET" && url.pathname === "/api/codex-usage") return guard(handleCodexUsage(req, res), res);
321
324
  // Machine state, not session state: sampled on the server's own timer and
@@ -0,0 +1,149 @@
1
+ // Observed quota, never inferred from tokens or cost. Recording adds no polls.
2
+ import { createHash } from "node:crypto";
3
+ import { readFile, stat, mkdir } from "node:fs/promises";
4
+ import { dirname, join } from "node:path";
5
+ import { deckDataDir } from "./deck-home.mjs";
6
+ import { writeFileAtomic } from "./atomic-write.mjs";
7
+
8
+ export const HISTORY_LIMITS = Object.freeze({ series: 32, points: 2048, totalPoints: 16384, days: 35, bytes: 2 * 1024 * 1024 });
9
+ const finite = n => typeof n === "number" && Number.isFinite(n);
10
+ const providers = new Set(["claude", "codex"]);
11
+ const hash = (provider, identity) => createHash("sha256").update(`${provider}\0${identity}`).digest("hex");
12
+
13
+ export function historyAccount(provider, account) {
14
+ if (provider === "claude" && typeof account?.email === "string" && account.email.trim()
15
+ && typeof account?.organizationUuid === "string" && account.organizationUuid) {
16
+ return hash(provider, `${account.email.trim().toLowerCase()}\0${account.organizationUuid}`);
17
+ }
18
+ if (provider === "codex" && (typeof account?.accountId === "string" && account.accountId
19
+ || typeof account?.email === "string" && account.email.trim())) {
20
+ return hash(provider, `${typeof account.accountId === "string" ? account.accountId : ""}\0${typeof account.email === "string" ? account.email.trim().toLowerCase() : ""}`);
21
+ }
22
+ return null;
23
+ }
24
+
25
+ export function historyWindows(provider, r) {
26
+ if (!r?.ok || r.stale) return [];
27
+ if (provider === "codex") return [...(r.windows ?? []), ...(r.extraWindows ?? [])];
28
+ const out = [
29
+ { id: "five_hour", label: "5-hour window", pct: r.session5hPct, resetAt: r.session5hResetAt, windowSec: r.session5hWindowSec },
30
+ { id: "seven_day", label: "7-day window", pct: r.week7dPct, resetAt: r.week7dResetAt, windowSec: r.week7dWindowSec },
31
+ ];
32
+ // Store fallback can copy the weekly reading into the nominal session lane.
33
+ return out.filter((w, i) => i !== 0 || w.resetAt !== out[1].resetAt || w.pct !== out[1].pct);
34
+ }
35
+
36
+ function prune(series, now) {
37
+ const floor = now - HISTORY_LIMITS.days * 86400_000;
38
+ let rows = series.filter(s => s.points.length && s.points.at(-1).t >= floor)
39
+ .map(s => ({ ...s, points: s.points.filter(p => p.t >= floor).slice(-HISTORY_LIMITS.points) }))
40
+ .filter(s => s.points.length).sort((a, b) => b.points.at(-1).t - a.points.at(-1).t)
41
+ .slice(0, HISTORY_LIMITS.series);
42
+ let total = rows.reduce((n, s) => n + s.points.length, 0);
43
+ while (total > HISTORY_LIMITS.totalPoints) total -= rows.pop().points.length;
44
+ return rows;
45
+ }
46
+
47
+ export function normalizeHistory(raw, now) {
48
+ if (raw?.v !== 1 || !Array.isArray(raw.series)) return [];
49
+ const out = [];
50
+ for (const s of raw.series.slice(0, HISTORY_LIMITS.series)) {
51
+ if (!providers.has(s?.provider) || !/^[a-f0-9]{64}$/.test(s.account ?? "")
52
+ || typeof s.id !== "string" || s.id.length > 100 || typeof s.label !== "string"
53
+ || !finite(s.resetAt) || !finite(s.windowSec) || s.windowSec < 60 || s.windowSec > 40 * 86400
54
+ || !Array.isArray(s.points)) continue;
55
+ const points = s.points.slice(-HISTORY_LIMITS.points).filter(p => finite(p?.t) && finite(p?.pct)
56
+ && p.pct >= 0 && p.pct <= 100 && p.t <= now + 60_000
57
+ && p.t >= (s.resetAt - s.windowSec) * 1000 - 120_000 && p.t < s.resetAt * 1000)
58
+ .map(p => ({ t: p.t, pct: p.pct })).sort((a, b) => a.t - b.t)
59
+ .filter((p, i, all) => !i || p.t !== all[i - 1].t);
60
+ out.push({ provider: s.provider, account: s.account, id: s.id, label: s.label.slice(0, 100),
61
+ resetAt: s.resetAt, windowSec: s.windowSec, points });
62
+ }
63
+ return prune(out, now);
64
+ }
65
+
66
+ export function createQuotaHistory({ load = async () => null, save = async () => {}, now = Date.now } = {}) {
67
+ let series = [], loading = null, storageOk = true;
68
+ const active = new Map();
69
+ let queue = Promise.resolve();
70
+ const ready = () => loading ??= (async () => {
71
+ try { series = normalizeHistory(await load(), now()); }
72
+ catch { storageOk = false; }
73
+ })();
74
+ return {
75
+ activate(provider, account) {
76
+ if (!providers.has(provider)) return null;
77
+ const key = historyAccount(provider, account);
78
+ active.set(provider, key);
79
+ return key;
80
+ },
81
+ record(provider, account, reading) {
82
+ queue = queue.then(async () => {
83
+ await ready();
84
+ if (!providers.has(provider) || !/^[a-f0-9]{64}$/.test(account ?? "") || !reading?.ok || reading.stale
85
+ || !finite(reading.fetchedAt) || reading.fetchedAt > now() + 60_000) return;
86
+ let changed = false;
87
+ for (const w of historyWindows(provider, reading)) {
88
+ if (typeof w.id !== "string" || !finite(w.pct) || w.pct < 0 || w.pct > 100
89
+ || !finite(w.resetAt) || !finite(w.windowSec) || w.windowSec < 60 || w.windowSec > 40 * 86400
90
+ || reading.fetchedAt >= w.resetAt * 1000
91
+ || reading.fetchedAt < (w.resetAt - w.windowSec) * 1000 - 120_000) continue;
92
+ let s = series.find(s => s.provider === provider && s.account === account && s.id === w.id
93
+ && s.windowSec === w.windowSec && Math.abs(s.resetAt - w.resetAt) <= 120);
94
+ if (!s) {
95
+ s = { provider, account, id: w.id.slice(0, 100), label: String(w.label ?? w.id).slice(0, 100),
96
+ resetAt: w.resetAt, windowSec: w.windowSec, points: [] };
97
+ series.push(s);
98
+ }
99
+ if (s.points.length && reading.fetchedAt <= s.points.at(-1).t) continue;
100
+ // Small source jitter must not place a captured point beyond the
101
+ // persisted window's end, where the next load would discard it.
102
+ s.resetAt = Math.max(s.resetAt, w.resetAt);
103
+ s.points.push({ t: reading.fetchedAt, pct: w.pct });
104
+ changed = true;
105
+ }
106
+ series = prune(series, now());
107
+ if (changed) {
108
+ try { await save({ v: 1, series }); storageOk = true; }
109
+ catch { storageOk = false; } // history cannot fail a quota request
110
+ }
111
+ }).catch(() => { storageOk = false; });
112
+ return queue;
113
+ },
114
+ async report(provider, account) {
115
+ await queue;
116
+ await ready();
117
+ // A delayed request for an account that was switched away from cannot
118
+ // display its history beside the new account's current quota.
119
+ if (!account || active.get(provider) !== account) return { ok: true, account: null, series: [], storageOk };
120
+ series = prune(series, now());
121
+ return { ok: true, account, storageOk, series: series.filter(s => s.provider === provider && s.account === account)
122
+ .map(({ account: _account, provider: _provider, ...s }) => ({ ...s, points: s.points.map(p => ({ ...p })) })) };
123
+ },
124
+ };
125
+ }
126
+
127
+ let history = null;
128
+ export function startQuotaHistory() {
129
+ if (history) return;
130
+ const file = join(deckDataDir(), "quota-history.json");
131
+ history = createQuotaHistory({
132
+ load: async () => {
133
+ try {
134
+ if ((await stat(file)).size > HISTORY_LIMITS.bytes) throw new Error("History exceeds capacity");
135
+ return JSON.parse((await readFile(file, "utf8")).replace(/^\uFEFF/, ""));
136
+ } catch (e) { if (e?.code === "ENOENT") return null; throw e; }
137
+ },
138
+ save: async raw => { await mkdir(dirname(file), { recursive: true }); await writeFileAtomic(file, JSON.stringify(raw)); },
139
+ });
140
+ }
141
+ export function noteQuotaHistory(provider, account, reading) {
142
+ if (!history) return;
143
+ const key = history.activate(provider, account);
144
+ if (key) { reading.historyAccount = key; void history.record(provider, key, reading); }
145
+ }
146
+ export function forgetQuotaHistoryAccount(provider) { history?.activate(provider, null); }
147
+ export async function quotaHistoryReport(provider, account) {
148
+ return history ? history.report(provider, account) : { ok: true, account: null, series: [], storageOk: true };
149
+ }
@@ -52,6 +52,7 @@
52
52
  // shape in quota-shape.mjs; the token, source 2's request and the cooldown are
53
53
  // quota-oauth.mjs's; running source 3 is quota-cli.mjs's; and the store path's
54
54
  // reset inventory is quota-store-resets.mjs's.
55
+ import { noteQuotaHistory, forgetQuotaHistoryAccount } from "./quota-history.mjs";
55
56
  import { activeAccountUsage, requestCollection } from "./claude-accounts.mjs";
56
57
  import { quotaFromStore, readingLapsed, WIN_5H_SEC, WIN_7D_SEC } from "./quota-shape.mjs";
57
58
  import {
@@ -254,7 +255,10 @@ function publish(gen, result, at, { good = false, who = null } = {}) {
254
255
  if (gen !== _generation) return result;
255
256
  _cache = result;
256
257
  _cacheAt = at;
257
- if (good) { _lastGood = result; _lastGoodFor = who; }
258
+ if (good) {
259
+ noteQuotaHistory("claude", who?.account, result);
260
+ _lastGood = result; _lastGoodFor = who;
261
+ }
258
262
  return result;
259
263
  }
260
264
 
@@ -421,7 +425,7 @@ async function _doFetch(now, force = false, gen = _generation) {
421
425
  // the question is new, and it can be asked at most once per reading held.
422
426
  const who = await readFor(store);
423
427
  const switched = _lastGood != null && switchedSince(_lastGoodFor, who);
424
- if (switched) { _lastGood = null; _lastGoodFor = null; }
428
+ if (switched) { _lastGood = null; _lastGoodFor = null; forgetQuotaHistoryAccount("claude"); }
425
429
 
426
430
  if (store && now - store.fetchedAt <= STORE_TRUSTED_MS) {
427
431
  // Keep the store moving even when the accounts panel is closed. Without
@@ -563,6 +567,7 @@ async function _doFetch(now, force = false, gen = _generation) {
563
567
  * left.
564
568
  */
565
569
  export function invalidateQuotaCache() {
570
+ forgetQuotaHistoryAccount("claude");
566
571
  _cache = null;
567
572
  _cacheAt = 0;
568
573
  _lastGood = null;
@@ -447,6 +447,7 @@ export const GUARDED_READS = new Set([
447
447
  // this answer (codex-quota.mjs), which is the account identity the roster
448
448
  // route above is guarded for.
449
449
  "/api/codex-quota",
450
+ "/api/quota/history",
450
451
  // And the rest of the usage panel, by the rule /api/account-projects is here
451
452
  // under: the active account's quota windows, Claude's spend by day and by
452
453
  // session, Codex's token spend, and the auto-switch settings with the last
@@ -2,8 +2,10 @@ import { open } from "node:fs/promises";
2
2
  import { homedir } from "node:os";
3
3
  import { posix, win32 } from "node:path";
4
4
  import { claudeConfigDir } from "./claude-dir.mjs";
5
+ import { mkdir } from "node:fs/promises";
6
+ import { readSettingsForWrite, stripBom, writeFileAtomic } from "./atomic-write.mjs";
5
7
 
6
- const BOOLEAN_KEYS = [
8
+ export const BOOLEAN_KEYS = [
7
9
  "CLAUDE_CODE_ENABLE_TELEMETRY", "CLAUDE_CODE_ENHANCED_TELEMETRY_BETA",
8
10
  "ENABLE_ENHANCED_TELEMETRY_BETA", "OTEL_LOG_USER_PROMPTS",
9
11
  "OTEL_LOG_ASSISTANT_RESPONSES", "OTEL_LOG_TOOL_DETAILS",
@@ -64,7 +66,7 @@ async function readBoundedJson(path) {
64
66
  const buffer = Buffer.alloc(262_145);
65
67
  const { bytesRead } = await file.read(buffer, 0, buffer.length, 0);
66
68
  if (bytesRead > 262_144) throw new Error("oversize");
67
- return JSON.parse(buffer.subarray(0, bytesRead).toString("utf8"));
69
+ return JSON.parse(stripBom(buffer.subarray(0, bytesRead).toString("utf8")));
68
70
  } finally { await file.close(); }
69
71
  }
70
72
 
@@ -86,5 +88,35 @@ export async function readRadarConfig({ home = homedir(), env = process.env, pla
86
88
  return { name, status: error?.code === "ENOENT" ? "absent" : "unavailable", variables: [] };
87
89
  }
88
90
  }));
89
- return { sources: sources.map(({ name, status }) => ({ name, status })), variables: sources.flatMap(s => s.variables) };
91
+ const variables = sources.flatMap(s => s.variables);
92
+ const blockedKeys = new Set(variables.filter(v => v.source !== "User settings").map(v => v.key));
93
+ const uncertain = sources.some(s => s.status === "unavailable");
94
+ return { sources: sources.map(({ name, status }) => ({ name, status })), variables: variables.map(v => ({
95
+ ...v,
96
+ ...(BOOLEAN_KEYS.includes(v.key) ? { editable: !uncertain && !blockedKeys.has(v.key),
97
+ ...((uncertain || blockedKeys.has(v.key)) ? { blockedReason: uncertain ? "Settings could not be verified. Try again after they can be read." : "Controlled by organization or managed settings. Ask your administrator to change this flag." } : {}) } : {}),
98
+ })) };
99
+ }
100
+
101
+ // Serialize read/modify/write requests so toggling different flags preserves both.
102
+ let settingsWrite = Promise.resolve();
103
+ export function updateRadarFlag(key, enabled, options = {}) {
104
+ const write = settingsWrite.catch(() => {}).then(async () => {
105
+ if (!BOOLEAN_KEYS.includes(key) || typeof enabled !== "boolean") throw new Error("Choose a supported telemetry flag and an On or Off value.");
106
+ const config = await readRadarConfig(options);
107
+ if (config.sources.some(s => s.status === "unavailable")) throw new Error("Settings could not be verified. No changes were saved.");
108
+ if (config.variables.some(v => v.key === key && v.source !== "User settings")) throw new Error("This flag is controlled by organization or managed settings. Ask your administrator to change it.");
109
+ const { home = homedir(), env = process.env, platform = process.platform } = options;
110
+ const pathJoin = platform === "win32" ? win32.join : posix.join;
111
+ const dir = claudeConfigDir(env, home, platform);
112
+ const path = pathJoin(dir, "settings.json");
113
+ const { settings } = await readSettingsForWrite(path);
114
+ if (settings.env !== undefined && (!settings.env || typeof settings.env !== "object" || Array.isArray(settings.env))) throw new Error("User settings contain an invalid env object. No changes were saved.");
115
+ settings.env = { ...settings.env, [key]: enabled ? "1" : "0" };
116
+ await mkdir(dir, { recursive: true });
117
+ await writeFileAtomic(path, JSON.stringify(settings, null, 2) + "\n");
118
+ return { ok: true, config: await readRadarConfig(options) };
119
+ });
120
+ settingsWrite = write;
121
+ return write;
90
122
  }