persagy-vant 0.0.52 → 0.0.54

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 (57) hide show
  1. package/es/icon/index.css +1 -1
  2. package/es/icon/latest-iconfont.css +1 -1
  3. package/es/icon/latest-iconfont.less +2 -14
  4. package/es/icon/svg-icon-masks.css +1 -0
  5. package/es/icon/svg-icon-masks.less +18 -0
  6. package/es/index.d.ts +1 -1
  7. package/es/index.mjs +1 -1
  8. package/es/locale/lang/en-US.d.ts +9 -0
  9. package/es/locale/lang/en-US.mjs +9 -0
  10. package/es/locale/lang/zh-CN.d.ts +9 -0
  11. package/es/locale/lang/zh-CN.mjs +9 -0
  12. package/es/locale/lang/zh-TW.d.ts +9 -0
  13. package/es/locale/lang/zh-TW.mjs +9 -0
  14. package/es/qr-scanner/QrScanner.d.ts +18 -1
  15. package/es/qr-scanner/QrScanner.mjs +141 -18
  16. package/es/qr-scanner/decoder.d.ts +3 -3
  17. package/es/qr-scanner/decoder.mjs +99 -27
  18. package/es/qr-scanner/function-call.d.ts +13 -1
  19. package/es/qr-scanner/function-call.mjs +5 -0
  20. package/es/qr-scanner/index.d.ts +1 -1
  21. package/es/qr-scanner/startup.d.ts +3 -0
  22. package/es/qr-scanner/startup.mjs +33 -0
  23. package/es/qr-scanner/types.d.ts +16 -1
  24. package/lib/{decoder-8f5b00db.js → decoder-03a4b162.js} +112 -34
  25. package/lib/{decoder-a36ba9ae.mjs → decoder-9637718d.mjs} +112 -34
  26. package/lib/icon/index.css +1 -1
  27. package/lib/icon/latest-iconfont.css +1 -1
  28. package/lib/icon/latest-iconfont.less +2 -14
  29. package/lib/icon/svg-icon-masks.css +1 -0
  30. package/lib/icon/svg-icon-masks.less +18 -0
  31. package/lib/index-d68a26ab.mjs +22968 -0
  32. package/lib/index-ea574b22.js +22967 -0
  33. package/lib/index.css +1 -1
  34. package/lib/index.d.ts +1 -1
  35. package/lib/index.js +1 -1
  36. package/lib/locale/lang/en-US.d.ts +9 -0
  37. package/lib/locale/lang/en-US.js +9 -0
  38. package/lib/locale/lang/zh-CN.d.ts +9 -0
  39. package/lib/locale/lang/zh-CN.js +9 -0
  40. package/lib/locale/lang/zh-TW.d.ts +9 -0
  41. package/lib/locale/lang/zh-TW.js +9 -0
  42. package/lib/qr-scanner/QrScanner.d.ts +18 -1
  43. package/lib/qr-scanner/QrScanner.js +141 -18
  44. package/lib/qr-scanner/decoder.d.ts +3 -3
  45. package/lib/qr-scanner/decoder.js +94 -26
  46. package/lib/qr-scanner/function-call.d.ts +13 -1
  47. package/lib/qr-scanner/function-call.js +5 -0
  48. package/lib/qr-scanner/index.d.ts +1 -1
  49. package/lib/qr-scanner/startup.d.ts +3 -0
  50. package/lib/qr-scanner/startup.js +52 -0
  51. package/lib/qr-scanner/types.d.ts +16 -1
  52. package/lib/vant.cjs.js +131 -22802
  53. package/lib/vant.es.js +131 -22802
  54. package/lib/vant.js +372 -137
  55. package/lib/vant.min.js +1 -1
  56. package/lib/web-types.json +1 -1
  57. package/package.json +6 -4
package/lib/vant.js CHANGED
@@ -662,6 +662,15 @@
662
662
  takePhoto: "拍照",
663
663
  recordVideo: "拍视频",
664
664
  chooseFromAlbum: "从相册选择"
665
+ },
666
+ vanQrScanner: {
667
+ startupCamera: "正在请求相机权限并打开摄像头...",
668
+ startupPreview: "正在启动相机画面...",
669
+ startupDecoder: "正在准备扫码识别...",
670
+ timeoutCamera: "摄像头启动超时,请检查系统和浏览器相机授权,也可以从相册识别",
671
+ timeoutPreview: "相机画面启动超时,请重试或从相册识别",
672
+ timeoutDecoder: "扫码识别准备超时,请检查网络或扫码资源部署后重试",
673
+ previewFailed: "相机画面启动失败,请重试或从相册识别"
665
674
  }
666
675
  };
667
676
  const lang = vue.ref("zh-CN");
@@ -3432,7 +3441,7 @@
3432
3441
  }, [renderOptions()])]);
3433
3442
  }
3434
3443
  });
3435
- const [name$1L, bem$1H, t$l] = createNamespace("picker");
3444
+ const [name$1L, bem$1H, t$m] = createNamespace("picker");
3436
3445
  const pickerSharedProps = {
3437
3446
  title: String,
3438
3447
  loading: Boolean,
@@ -3638,7 +3647,7 @@
3638
3647
  }
3639
3648
  };
3640
3649
  const renderCancel = () => {
3641
- const text = props2.cancelButtonText || t$l("cancel");
3650
+ const text = props2.cancelButtonText || t$m("cancel");
3642
3651
  return vue.createVNode("button", {
3643
3652
  "type": "button",
3644
3653
  "class": [bem$1H("cancel"), HAPTICS_FEEDBACK],
@@ -3646,7 +3655,7 @@
3646
3655
  }, [slots.cancel ? slots.cancel() : text]);
3647
3656
  };
3648
3657
  const renderConfirm = () => {
3649
- const text = props2.confirmButtonText || t$l("confirm");
3658
+ const text = props2.confirmButtonText || t$m("confirm");
3650
3659
  return vue.createVNode("button", {
3651
3660
  "type": "button",
3652
3661
  "class": [bem$1H("confirm"), HAPTICS_FEEDBACK],
@@ -6144,7 +6153,7 @@
6144
6153
  });
6145
6154
  const Switch = withInstall(stdin_default$1J);
6146
6155
  const [name$1z, bem$1v] = createNamespace("address-edit-detail");
6147
- const t$k = createNamespace("address-edit")[2];
6156
+ const t$l = createNamespace("address-edit")[2];
6148
6157
  var stdin_default$1I = vue.defineComponent({
6149
6158
  name: name$1z,
6150
6159
  props: {
@@ -6207,11 +6216,11 @@
6207
6216
  "rows": props2.rows,
6208
6217
  "type": "textarea",
6209
6218
  "rules": props2.rules,
6210
- "label": t$k("addressDetail"),
6219
+ "label": t$l("addressDetail"),
6211
6220
  "border": !showSearchResult(),
6212
6221
  "maxlength": props2.maxlength,
6213
6222
  "modelValue": props2.value,
6214
- "placeholder": t$k("addressDetail"),
6223
+ "placeholder": t$l("addressDetail"),
6215
6224
  "onBlur": onBlur,
6216
6225
  "onFocus": onFocus,
6217
6226
  "onUpdate:modelValue": onInput
@@ -6220,7 +6229,7 @@
6220
6229
  };
6221
6230
  }
6222
6231
  });
6223
- const [name$1y, bem$1u, t$j] = createNamespace("address-edit");
6232
+ const [name$1y, bem$1u, t$k] = createNamespace("address-edit");
6224
6233
  const DEFAULT_DATA = {
6225
6234
  name: "",
6226
6235
  tel: "",
@@ -6334,16 +6343,16 @@
6334
6343
  }
6335
6344
  });
6336
6345
  return {
6337
- name: [makeRule("name", t$j("nameEmpty"))],
6338
- tel: [makeRule("tel", t$j("telInvalid")), {
6346
+ name: [makeRule("name", t$k("nameEmpty"))],
6347
+ tel: [makeRule("tel", t$k("telInvalid")), {
6339
6348
  validator: telValidator,
6340
- message: t$j("telInvalid")
6349
+ message: t$k("telInvalid")
6341
6350
  }],
6342
- areaCode: [makeRule("areaCode", t$j("areaEmpty"))],
6343
- addressDetail: [makeRule("addressDetail", t$j("addressEmpty"))],
6344
- postalCode: [makeRule("addressDetail", t$j("postalEmpty")), {
6351
+ areaCode: [makeRule("areaCode", t$k("areaEmpty"))],
6352
+ addressDetail: [makeRule("addressDetail", t$k("addressEmpty"))],
6353
+ postalCode: [makeRule("addressDetail", t$k("postalEmpty")), {
6345
6354
  validator: postalValidator,
6346
- message: t$j("postalEmpty")
6355
+ message: t$k("postalEmpty")
6347
6356
  }]
6348
6357
  };
6349
6358
  });
@@ -6355,7 +6364,7 @@
6355
6364
  const onAreaConfirm = (values) => {
6356
6365
  values = values.filter(Boolean);
6357
6366
  if (values.some((value) => !value.code)) {
6358
- Toast(t$j("areaEmpty"));
6367
+ Toast(t$k("areaEmpty"));
6359
6368
  } else {
6360
6369
  showAreaPopup.value = false;
6361
6370
  assignAreaValues();
@@ -6393,7 +6402,7 @@
6393
6402
  };
6394
6403
  return vue.withDirectives(vue.createVNode(Cell, {
6395
6404
  "center": true,
6396
- "title": t$j("defaultAddress"),
6405
+ "title": t$k("defaultAddress"),
6397
6406
  "class": bem$1u("default")
6398
6407
  }, slots2), [[vue.vShow, !hideBottomFields.value]]);
6399
6408
  }
@@ -6427,27 +6436,27 @@
6427
6436
  "modelValue": data.name,
6428
6437
  "onUpdate:modelValue": ($event) => data.name = $event,
6429
6438
  "clearable": true,
6430
- "label": t$j("name"),
6439
+ "label": t$k("name"),
6431
6440
  "rules": rules.value.name,
6432
- "placeholder": t$j("name"),
6441
+ "placeholder": t$k("name"),
6433
6442
  "onFocus": () => onFocus("name")
6434
6443
  }, null), vue.createVNode(Field, {
6435
6444
  "modelValue": data.tel,
6436
6445
  "onUpdate:modelValue": ($event) => data.tel = $event,
6437
6446
  "clearable": true,
6438
6447
  "type": "tel",
6439
- "label": t$j("tel"),
6448
+ "label": t$k("tel"),
6440
6449
  "rules": rules.value.tel,
6441
6450
  "maxlength": props2.telMaxlength,
6442
- "placeholder": t$j("tel"),
6451
+ "placeholder": t$k("tel"),
6443
6452
  "onFocus": () => onFocus("tel")
6444
6453
  }, null), vue.withDirectives(vue.createVNode(Field, {
6445
6454
  "readonly": true,
6446
- "label": t$j("area"),
6455
+ "label": t$k("area"),
6447
6456
  "is-link": !disableArea,
6448
6457
  "modelValue": areaText.value,
6449
6458
  "rules": rules.value.areaCode,
6450
- "placeholder": props2.areaPlaceholder || t$j("area"),
6459
+ "placeholder": props2.areaPlaceholder || t$k("area"),
6451
6460
  "onFocus": () => onFocus("areaCode"),
6452
6461
  "onClick": () => {
6453
6462
  emit("click-area");
@@ -6471,9 +6480,9 @@
6471
6480
  "onUpdate:modelValue": ($event) => data.postalCode = $event,
6472
6481
  "type": "tel",
6473
6482
  "rules": rules.value.postalCode,
6474
- "label": t$j("postal"),
6483
+ "label": t$k("postal"),
6475
6484
  "maxlength": "6",
6476
- "placeholder": t$j("postal"),
6485
+ "placeholder": t$k("postal"),
6477
6486
  "onFocus": () => onFocus("postalCode")
6478
6487
  }, null), [[vue.vShow, !hideBottomFields.value]]), (_a = slots.default) == null ? void 0 : _a.call(slots)]), renderSetDefaultCell(), vue.withDirectives(vue.createVNode("div", {
6479
6488
  "class": bem$1u("buttons")
@@ -6481,7 +6490,7 @@
6481
6490
  "block": true,
6482
6491
  "round": true,
6483
6492
  "type": "primary",
6484
- "text": props2.saveButtonText || t$j("save"),
6493
+ "text": props2.saveButtonText || t$k("save"),
6485
6494
  "class": bem$1u("button"),
6486
6495
  "loading": props2.isSaving,
6487
6496
  "nativeType": "submit"
@@ -6490,7 +6499,7 @@
6490
6499
  "round": true,
6491
6500
  "class": bem$1u("button"),
6492
6501
  "loading": props2.isDeleting,
6493
- "text": props2.deleteButtonText || t$j("delete"),
6502
+ "text": props2.deleteButtonText || t$k("delete"),
6494
6503
  "onClick": onDelete
6495
6504
  }, null)]), [[vue.vShow, !hideBottomFields.value]]), vue.createVNode(Popup, {
6496
6505
  "show": showAreaPopup.value,
@@ -6605,7 +6614,7 @@
6605
6614
  };
6606
6615
  }
6607
6616
  });
6608
- const [name$1w, bem$1s, t$i] = createNamespace("address-list");
6617
+ const [name$1w, bem$1s, t$j] = createNamespace("address-list");
6609
6618
  const addressListProps = {
6610
6619
  list: makeArrayProp(),
6611
6620
  modelValue: numericProp,
@@ -6657,7 +6666,7 @@
6657
6666
  "round": true,
6658
6667
  "block": true,
6659
6668
  "type": "primary",
6660
- "text": props2.addButtonText || t$i("add"),
6669
+ "text": props2.addButtonText || t$j("add"),
6661
6670
  "class": bem$1s("add"),
6662
6671
  "onClick": () => emit("add")
6663
6672
  }, null)]);
@@ -7091,8 +7100,8 @@
7091
7100
  }
7092
7101
  });
7093
7102
  const BottomActionBar = withInstall(stdin_default$1z);
7094
- const [name$1p, bem$1l, t$h] = createNamespace("calendar");
7095
- const formatMonthTitle = (date) => t$h("monthTitle", date.getFullYear(), date.getMonth() + 1);
7103
+ const [name$1p, bem$1l, t$i] = createNamespace("calendar");
7104
+ const formatMonthTitle = (date) => t$i("monthTitle", date.getFullYear(), date.getMonth() + 1);
7096
7105
  function compareMonth(date1, date2) {
7097
7106
  const year1 = date1.getFullYear();
7098
7107
  const year2 = date2.getFullYear();
@@ -7435,10 +7444,10 @@
7435
7444
  const getBottomInfo = (dayType) => {
7436
7445
  if (props2.type === "range") {
7437
7446
  if (dayType === "start" || dayType === "end") {
7438
- return t$h(dayType);
7447
+ return t$i(dayType);
7439
7448
  }
7440
7449
  if (dayType === "start-end") {
7441
- return `${t$h("start")}/${t$h("end")}`;
7450
+ return `${t$i("start")}/${t$i("end")}`;
7442
7451
  }
7443
7452
  }
7444
7453
  };
@@ -7535,7 +7544,7 @@
7535
7544
  }) {
7536
7545
  const renderTitle = () => {
7537
7546
  if (props2.showTitle) {
7538
- const text = props2.title || t$h("title");
7547
+ const text = props2.title || t$i("title");
7539
7548
  const title = slots.title ? slots.title() : text;
7540
7549
  return vue.createVNode("div", {
7541
7550
  "class": bem$1l("header-title")
@@ -7556,7 +7565,7 @@
7556
7565
  const {
7557
7566
  firstDayOfWeek
7558
7567
  } = props2;
7559
- const weekdays = t$h("weekdays");
7568
+ const weekdays = t$i("weekdays");
7560
7569
  const renderWeekDays2 = [...weekdays.slice(firstDayOfWeek, 7), ...weekdays.slice(0, firstDayOfWeek)];
7561
7570
  return vue.createVNode("div", {
7562
7571
  "class": bem$1l("weekdays")
@@ -7777,7 +7786,7 @@
7777
7786
  } = props2;
7778
7787
  if (maxRange && calcDateNum(date) > maxRange) {
7779
7788
  if (showRangePrompt) {
7780
- Toast(rangePrompt || t$h("rangePrompt", maxRange));
7789
+ Toast(rangePrompt || t$i("rangePrompt", maxRange));
7781
7790
  }
7782
7791
  emit("over-range");
7783
7792
  return false;
@@ -7863,7 +7872,7 @@
7863
7872
  const [unselectedDate] = dates.splice(selectedIndex, 1);
7864
7873
  emit("unselect", cloneDate(unselectedDate));
7865
7874
  } else if (props2.maxRange && dates.length >= props2.maxRange) {
7866
- Toast(props2.rangePrompt || t$h("rangePrompt", props2.maxRange));
7875
+ Toast(props2.rangePrompt || t$i("rangePrompt", props2.maxRange));
7867
7876
  } else {
7868
7877
  select([...dates, date]);
7869
7878
  }
@@ -7904,7 +7913,7 @@
7904
7913
  }, {
7905
7914
  default: () => [slot ? slot({
7906
7915
  disabled
7907
- }) : text || t$h("confirm")]
7916
+ }) : text || t$i("confirm")]
7908
7917
  });
7909
7918
  }
7910
7919
  };
@@ -8915,7 +8924,7 @@
8915
8924
  return a;
8916
8925
  };
8917
8926
  var __spreadProps = (a, b2) => __defProps(a, __getOwnPropDescs(b2));
8918
- const [name$1f, bem$1e, t$g] = createNamespace("tabs");
8927
+ const [name$1f, bem$1e, t$h] = createNamespace("tabs");
8919
8928
  const tabsProps = {
8920
8929
  type: makeStringProp("line"),
8921
8930
  color: String,
@@ -9221,7 +9230,7 @@
9221
9230
  "name": "ellipsis"
9222
9231
  }, null)])]), (_c = slots["nav-bottom"]) == null ? void 0 : _c.call(slots), props2.more && vue.createVNode(ActionSheet, {
9223
9232
  "show": props2.showMore,
9224
- "title": props2.moreTitle || t$g("moreTitle"),
9233
+ "title": props2.moreTitle || t$h("moreTitle"),
9225
9234
  "actions": moreActions.value,
9226
9235
  "class": bem$1e("more-panel"),
9227
9236
  "closeOnClickAction": true,
@@ -9497,7 +9506,7 @@
9497
9506
  });
9498
9507
  const Tab = withInstall(stdin_default$1m);
9499
9508
  const Tabs = withInstall(stdin_default$1o);
9500
- const [name$1c, bem$1b, t$f] = createNamespace("cascader");
9509
+ const [name$1c, bem$1b, t$g] = createNamespace("cascader");
9501
9510
  const cascaderProps = {
9502
9511
  title: String,
9503
9512
  options: makeArrayProp(),
@@ -9664,7 +9673,7 @@
9664
9673
  options,
9665
9674
  selected
9666
9675
  } = tab;
9667
- const placeholder = props2.placeholder || t$f("select");
9676
+ const placeholder = props2.placeholder || t$g("select");
9668
9677
  const title = selected ? selected[textKey] : placeholder;
9669
9678
  return vue.createVNode(Tab, {
9670
9679
  "title": title,
@@ -9806,7 +9815,7 @@
9806
9815
  }
9807
9816
  });
9808
9817
  const Empty = withInstall(stdin_default$1j);
9809
- const [name$19, bem$18, t$e] = createNamespace("list");
9818
+ const [name$19, bem$18, t$f] = createNamespace("list");
9810
9819
  const listProps = {
9811
9820
  error: Boolean,
9812
9821
  offset: makeNumericProp(300),
@@ -9893,7 +9902,7 @@
9893
9902
  }, [slots.loading ? slots.loading() : vue.createVNode(Loading, {
9894
9903
  "class": bem$18("loading-icon")
9895
9904
  }, {
9896
- default: () => [props2.loadingText || t$e("loading")]
9905
+ default: () => [props2.loadingText || t$f("loading")]
9897
9906
  })]);
9898
9907
  }
9899
9908
  };
@@ -9937,7 +9946,7 @@
9937
9946
  }
9938
9947
  });
9939
9948
  const List = withInstall(stdin_default$1i);
9940
- const [name$18, bem$17, t$d] = createNamespace("search");
9949
+ const [name$18, bem$17, t$e] = createNamespace("search");
9941
9950
  const searchProps = extend$1({}, fieldSharedProps, {
9942
9951
  label: String,
9943
9952
  shape: makeStringProp("round"),
@@ -9984,7 +9993,7 @@
9984
9993
  };
9985
9994
  const renderAction = () => {
9986
9995
  if (props2.showAction) {
9987
- const text = props2.actionText || t$d("cancel");
9996
+ const text = props2.actionText || t$e("cancel");
9988
9997
  return vue.createVNode("div", {
9989
9998
  "class": bem$17("action"),
9990
9999
  "role": "button",
@@ -10776,7 +10785,7 @@
10776
10785
  });
10777
10786
  const CollapseItem = withInstall(stdin_default$1b);
10778
10787
  const ConfigProvider = withInstall(stdin_default$26);
10779
- const [name$11, bem$10, t$c] = createNamespace("contact-card");
10788
+ const [name$11, bem$10, t$d] = createNamespace("contact-card");
10780
10789
  const contactCardProps = {
10781
10790
  tel: String,
10782
10791
  name: String,
@@ -10798,9 +10807,9 @@
10798
10807
  };
10799
10808
  const renderContent = () => {
10800
10809
  if (props2.type === "add") {
10801
- return props2.addText || t$c("addContact");
10810
+ return props2.addText || t$d("addContact");
10802
10811
  }
10803
- return [vue.createVNode("div", null, [`${t$c("name")}:${props2.name}`]), vue.createVNode("div", null, [`${t$c("tel")}:${props2.tel}`])];
10812
+ return [vue.createVNode("div", null, [`${t$d("name")}:${props2.name}`]), vue.createVNode("div", null, [`${t$d("tel")}:${props2.tel}`])];
10804
10813
  };
10805
10814
  return () => vue.createVNode(Cell, {
10806
10815
  "center": true,
@@ -10816,7 +10825,7 @@
10816
10825
  }
10817
10826
  });
10818
10827
  const ContactCard = withInstall(stdin_default$1a);
10819
- const [name$10, bem$$, t$b] = createNamespace("contact-edit");
10828
+ const [name$10, bem$$, t$c] = createNamespace("contact-edit");
10820
10829
  const DEFAULT_CONTACT = {
10821
10830
  tel: "",
10822
10831
  name: ""
@@ -10856,14 +10865,14 @@
10856
10865
  "block": true,
10857
10866
  "round": true,
10858
10867
  "type": "primary",
10859
- "text": t$b("save"),
10868
+ "text": t$c("save"),
10860
10869
  "class": bem$$("button"),
10861
10870
  "loading": props2.isSaving,
10862
10871
  "nativeType": "submit"
10863
10872
  }, null), props2.isEdit && vue.createVNode(Button, {
10864
10873
  "block": true,
10865
10874
  "round": true,
10866
- "text": t$b("delete"),
10875
+ "text": t$c("delete"),
10867
10876
  "class": bem$$("button"),
10868
10877
  "loading": props2.isDeleting,
10869
10878
  "onClick": onDelete
@@ -10896,30 +10905,30 @@
10896
10905
  "modelValue": contact.name,
10897
10906
  "onUpdate:modelValue": ($event) => contact.name = $event,
10898
10907
  "clearable": true,
10899
- "label": t$b("name"),
10908
+ "label": t$c("name"),
10900
10909
  "rules": [{
10901
10910
  required: true,
10902
- message: t$b("nameEmpty")
10911
+ message: t$c("nameEmpty")
10903
10912
  }],
10904
10913
  "maxlength": "30",
10905
- "placeholder": t$b("name")
10914
+ "placeholder": t$c("name")
10906
10915
  }, null), vue.createVNode(Field, {
10907
10916
  "modelValue": contact.tel,
10908
10917
  "onUpdate:modelValue": ($event) => contact.tel = $event,
10909
10918
  "clearable": true,
10910
10919
  "type": "tel",
10911
- "label": t$b("tel"),
10920
+ "label": t$c("tel"),
10912
10921
  "rules": [{
10913
10922
  validator: props2.telValidator,
10914
- message: t$b("telInvalid")
10923
+ message: t$c("telInvalid")
10915
10924
  }],
10916
- "placeholder": t$b("tel")
10925
+ "placeholder": t$c("tel")
10917
10926
  }, null)]), renderSetDefault(), renderButtons()]
10918
10927
  });
10919
10928
  }
10920
10929
  });
10921
10930
  const ContactEdit = withInstall(stdin_default$19);
10922
- const [name$$, bem$_, t$a] = createNamespace("contact-list");
10931
+ const [name$$, bem$_, t$b] = createNamespace("contact-list");
10923
10932
  const contactListProps = {
10924
10933
  list: Array,
10925
10934
  addText: String,
@@ -10991,7 +11000,7 @@
10991
11000
  "block": true,
10992
11001
  "type": "primary",
10993
11002
  "class": bem$_("add"),
10994
- "text": props2.addText || t$a("addContact"),
11003
+ "text": props2.addText || t$b("addContact"),
10995
11004
  "onClick": () => emit("add")
10996
11005
  }, null)])]);
10997
11006
  }
@@ -11152,7 +11161,7 @@
11152
11161
  }
11153
11162
  const formatDiscount = (discount) => (discount / 10).toFixed(discount % 10 === 0 ? 0 : 1);
11154
11163
  const formatAmount = (amount) => (amount / 100).toFixed(amount % 100 === 0 ? 0 : amount % 10 === 0 ? 1 : 2);
11155
- const [name$Y, bem$X, t$9] = createNamespace("coupon");
11164
+ const [name$Y, bem$X, t$a] = createNamespace("coupon");
11156
11165
  var stdin_default$15 = vue.defineComponent({
11157
11166
  name: name$Y,
11158
11167
  props: {
@@ -11182,13 +11191,13 @@
11182
11191
  return [vue.createVNode("span", null, [currency]), ` ${denominations}`];
11183
11192
  }
11184
11193
  if (coupon.discount) {
11185
- return t$9("discount", formatDiscount(coupon.discount));
11194
+ return t$a("discount", formatDiscount(coupon.discount));
11186
11195
  }
11187
11196
  return "";
11188
11197
  });
11189
11198
  const conditionMessage = vue.computed(() => {
11190
11199
  const condition = formatAmount(props2.coupon.originCondition || 0);
11191
- return condition === "0" ? t$9("unlimited") : t$9("condition", condition);
11200
+ return condition === "0" ? t$a("unlimited") : t$a("condition", condition);
11192
11201
  });
11193
11202
  return () => {
11194
11203
  const {
@@ -11225,7 +11234,7 @@
11225
11234
  }
11226
11235
  });
11227
11236
  const Coupon = withInstall(stdin_default$15);
11228
- const [name$X, bem$W, t$8] = createNamespace("coupon-cell");
11237
+ const [name$X, bem$W, t$9] = createNamespace("coupon-cell");
11229
11238
  const couponCellProps = {
11230
11239
  title: String,
11231
11240
  border: truthProp,
@@ -11251,7 +11260,7 @@
11251
11260
  }
11252
11261
  return `-${currency} ${(value / 100).toFixed(2)}`;
11253
11262
  }
11254
- return coupons.length === 0 ? t$8("noCoupon") : t$8("count", coupons.length);
11263
+ return coupons.length === 0 ? t$9("noCoupon") : t$9("count", coupons.length);
11255
11264
  }
11256
11265
  var stdin_default$14 = vue.defineComponent({
11257
11266
  name: name$X,
@@ -11262,7 +11271,7 @@
11262
11271
  return vue.createVNode(Cell, {
11263
11272
  "class": bem$W(),
11264
11273
  "value": formatValue(props2),
11265
- "title": props2.title || t$8("title"),
11274
+ "title": props2.title || t$9("title"),
11266
11275
  "border": props2.border,
11267
11276
  "isLink": props2.editable,
11268
11277
  "valueClass": bem$W("value", {
@@ -11273,7 +11282,7 @@
11273
11282
  }
11274
11283
  });
11275
11284
  const CouponCell = withInstall(stdin_default$14);
11276
- const [name$W, bem$V, t$7] = createNamespace("coupon-list");
11285
+ const [name$W, bem$V, t$8] = createNamespace("coupon-list");
11277
11286
  const couponListProps = {
11278
11287
  code: makeStringProp(""),
11279
11288
  coupons: makeArrayProp(),
@@ -11332,7 +11341,7 @@
11332
11341
  }, {
11333
11342
  default: () => [vue.createVNode("p", {
11334
11343
  "class": bem$V("empty-tip")
11335
- }, [t$7("noCoupon")])]
11344
+ }, [t$8("noCoupon")])]
11336
11345
  });
11337
11346
  const renderExchangeBar = () => {
11338
11347
  if (props2.showExchangeBar) {
@@ -11345,13 +11354,13 @@
11345
11354
  "clearable": true,
11346
11355
  "border": false,
11347
11356
  "class": bem$V("field"),
11348
- "placeholder": props2.inputPlaceholder || t$7("placeholder"),
11357
+ "placeholder": props2.inputPlaceholder || t$8("placeholder"),
11349
11358
  "maxlength": "20"
11350
11359
  }, null), vue.createVNode(Button, {
11351
11360
  "plain": true,
11352
11361
  "type": "primary",
11353
11362
  "class": bem$V("exchange"),
11354
- "text": props2.exchangeButtonText || t$7("exchange"),
11363
+ "text": props2.exchangeButtonText || t$8("exchange"),
11355
11364
  "loading": props2.exchangeButtonLoading,
11356
11365
  "disabled": buttonDisabled.value,
11357
11366
  "onClick": onExchange
@@ -11363,7 +11372,7 @@
11363
11372
  coupons
11364
11373
  } = props2;
11365
11374
  const count = props2.showCount ? ` (${coupons.length})` : "";
11366
- const title = (props2.enabledTitle || t$7("enable")) + count;
11375
+ const title = (props2.enabledTitle || t$8("enable")) + count;
11367
11376
  return vue.createVNode(Tab, {
11368
11377
  "title": title
11369
11378
  }, {
@@ -11392,7 +11401,7 @@
11392
11401
  disabledCoupons
11393
11402
  } = props2;
11394
11403
  const count = props2.showCount ? ` (${disabledCoupons.length})` : "";
11395
- const title = (props2.disabledTitle || t$7("disabled")) + count;
11404
+ const title = (props2.disabledTitle || t$8("disabled")) + count;
11396
11405
  return vue.createVNode(Tab, {
11397
11406
  "title": title
11398
11407
  }, {
@@ -11440,7 +11449,7 @@
11440
11449
  "block": true,
11441
11450
  "type": "primary",
11442
11451
  "class": bem$V("close"),
11443
- "text": props2.closeButtonText || t$7("close"),
11452
+ "text": props2.closeButtonText || t$8("close"),
11444
11453
  "onClick": () => emit("change", -1)
11445
11454
  }, null), [[vue.vShow, props2.showCloseButton]])])]);
11446
11455
  }
@@ -12001,7 +12010,7 @@
12001
12010
  }
12002
12011
  });
12003
12012
  const DatetimePicker = withInstall(stdin_default$$);
12004
- const [name$R, bem$S, t$6] = createNamespace("dialog");
12013
+ const [name$R, bem$S, t$7] = createNamespace("dialog");
12005
12014
  const dialogProps = extend$1({}, popupSharedProps, {
12006
12015
  title: String,
12007
12016
  theme: String,
@@ -12165,7 +12174,7 @@
12165
12174
  })]
12166
12175
  }, [props2.showCancelButton && vue.createVNode(Button, {
12167
12176
  "size": "large",
12168
- "text": props2.cancelButtonText || t$6("cancel"),
12177
+ "text": props2.cancelButtonText || t$7("cancel"),
12169
12178
  "class": bem$S("cancel"),
12170
12179
  "style": {
12171
12180
  color: props2.cancelButtonColor
@@ -12175,7 +12184,7 @@
12175
12184
  "onClick": onCancel
12176
12185
  }, null), props2.showConfirmButton && vue.createVNode(Button, {
12177
12186
  "size": "large",
12178
- "text": props2.confirmButtonText || t$6("confirm"),
12187
+ "text": props2.confirmButtonText || t$7("confirm"),
12179
12188
  "class": [bem$S("confirm"), {
12180
12189
  [BORDER_LEFT]: props2.showCancelButton && !props2.showThirdButton
12181
12190
  }],
@@ -12201,7 +12210,7 @@
12201
12210
  }, {
12202
12211
  default: () => [props2.showCancelButton && vue.createVNode(ActionBarButton, {
12203
12212
  "type": "warning",
12204
- "text": props2.cancelButtonText || t$6("cancel"),
12213
+ "text": props2.cancelButtonText || t$7("cancel"),
12205
12214
  "class": bem$S("cancel"),
12206
12215
  "color": props2.cancelButtonColor,
12207
12216
  "loading": loading.cancel,
@@ -12209,7 +12218,7 @@
12209
12218
  "onClick": onCancel
12210
12219
  }, null), props2.showConfirmButton && vue.createVNode(ActionBarButton, {
12211
12220
  "type": "primary",
12212
- "text": props2.confirmButtonText || t$6("confirm"),
12221
+ "text": props2.confirmButtonText || t$7("confirm"),
12213
12222
  "class": bem$S("confirm"),
12214
12223
  "color": props2.confirmButtonColor,
12215
12224
  "loading": loading.confirm,
@@ -18077,7 +18086,7 @@
18077
18086
  }
18078
18087
  });
18079
18088
  const ObjectSelect = withInstall(stdin_default$u);
18080
- const [name$o, bem$o, t$5] = createNamespace("pagination");
18089
+ const [name$o, bem$o, t$6] = createNamespace("pagination");
18081
18090
  const makePage = (number, text, active) => ({
18082
18091
  number,
18083
18092
  text,
@@ -18176,7 +18185,7 @@
18176
18185
  "type": "button",
18177
18186
  "disabled": disabled,
18178
18187
  "onClick": () => updateModelValue(modelValue - 1, true)
18179
- }, [slot ? slot() : props2.prevText || t$5("prev")])]);
18188
+ }, [slot ? slot() : props2.prevText || t$6("prev")])]);
18180
18189
  };
18181
18190
  const renderNextButton = () => {
18182
18191
  const {
@@ -18195,7 +18204,7 @@
18195
18204
  "type": "button",
18196
18205
  "disabled": disabled,
18197
18206
  "onClick": () => updateModelValue(modelValue + 1, true)
18198
- }, [slot ? slot() : props2.nextText || t$5("next")])]);
18207
+ }, [slot ? slot() : props2.nextText || t$6("next")])]);
18199
18208
  };
18200
18209
  const renderPages = () => pages.value.map((page) => vue.createVNode("li", {
18201
18210
  "class": [bem$o("item", {
@@ -18365,7 +18374,7 @@
18365
18374
  }
18366
18375
  });
18367
18376
  const Progress = withInstall(stdin_default$r);
18368
- const [name$l, bem$l, t$4] = createNamespace("pull-refresh");
18377
+ const [name$l, bem$l, t$5] = createNamespace("pull-refresh");
18369
18378
  const DEFAULT_HEAD_HEIGHT = 50;
18370
18379
  const TEXT_STATUS = ["pulling", "loosing", "success"];
18371
18380
  const pullRefreshProps = {
@@ -18441,7 +18450,7 @@
18441
18450
  if (status === "normal") {
18442
18451
  return "";
18443
18452
  }
18444
- return props2[`${status}Text`] || t$4(status);
18453
+ return props2[`${status}Text`] || t$5(status);
18445
18454
  };
18446
18455
  const renderStatus = () => {
18447
18456
  const {
@@ -18550,6 +18559,34 @@
18550
18559
  }
18551
18560
  });
18552
18561
  const PullRefresh = withInstall(stdin_default$q);
18562
+ const DEFAULT_STARTUP_TIMEOUT = 15e3;
18563
+ function abortError() {
18564
+ const error = new Error("Scanner startup cancelled");
18565
+ error.name = "AbortError";
18566
+ return error;
18567
+ }
18568
+ function waitForAbort(task, signal) {
18569
+ return new Promise((resolve, reject) => {
18570
+ const onAbort = () => {
18571
+ signal == null ? void 0 : signal.removeEventListener("abort", onAbort);
18572
+ reject(abortError());
18573
+ };
18574
+ if (signal == null ? void 0 : signal.aborted)
18575
+ onAbort();
18576
+ else
18577
+ signal == null ? void 0 : signal.addEventListener("abort", onAbort, { once: true });
18578
+ task.then(
18579
+ (value) => {
18580
+ signal == null ? void 0 : signal.removeEventListener("abort", onAbort);
18581
+ resolve(value);
18582
+ },
18583
+ (error) => {
18584
+ signal == null ? void 0 : signal.removeEventListener("abort", onAbort);
18585
+ reject(error);
18586
+ }
18587
+ );
18588
+ });
18589
+ }
18553
18590
  var __async$3 = (__this, __arguments, generator) => {
18554
18591
  return new Promise((resolve, reject) => {
18555
18592
  var fulfilled = (value) => {
@@ -18570,12 +18607,14 @@
18570
18607
  step((generator = generator.apply(__this, __arguments)).next());
18571
18608
  });
18572
18609
  };
18573
- const [name$k, bem$k] = createNamespace("qr-scanner");
18610
+ const [name$k, bem$k, t$4] = createNamespace("qr-scanner");
18574
18611
  const qrScannerProps = {
18575
18612
  show: Boolean,
18576
18613
  title: makeStringProp("扫描设备二维码"),
18577
18614
  tip: makeStringProp("将设备二维码置于取景框内,即可自动识别"),
18578
18615
  processingText: makeStringProp("正在处理扫码结果..."),
18616
+ startupTimeout: makeNumericProp(DEFAULT_STARTUP_TIMEOUT),
18617
+ startupTexts: Object,
18579
18618
  formats: extend$1(makeArrayProp(), {
18580
18619
  default: () => ["QRCode"]
18581
18620
  }),
@@ -18601,7 +18640,7 @@
18601
18640
  var stdin_default$p = vue.defineComponent({
18602
18641
  name: name$k,
18603
18642
  props: qrScannerProps,
18604
- emits: ["update:show", "scan", "error", "cancel", "close", "closed", "ready"],
18643
+ emits: ["update:show", "scan", "error", "cancel", "close", "closed", "ready", "stageChange"],
18605
18644
  setup(props2, {
18606
18645
  emit
18607
18646
  }) {
@@ -18610,6 +18649,7 @@
18610
18649
  const frame = vue.ref();
18611
18650
  const fileInput = vue.ref();
18612
18651
  const phase = vue.ref("idle");
18652
+ const startupStage = vue.ref("camera");
18613
18653
  const message = vue.ref("");
18614
18654
  const hasTorch = vue.ref(false);
18615
18655
  const torchOn = vue.ref(false);
@@ -18620,13 +18660,25 @@
18620
18660
  let stream;
18621
18661
  let canvas;
18622
18662
  let timer2;
18663
+ let startupTimer;
18664
+ let startupStartedAt = 0;
18665
+ let startupDeadline = 0;
18623
18666
  let generation = 0;
18624
18667
  let abortController;
18625
18668
  let resumeWhenVisible = false;
18669
+ let pickingAlbum = false;
18626
18670
  const recentResults = /* @__PURE__ */ new Map();
18627
18671
  const isCurrent = (id) => id === generation && props2.show && !props2.paused;
18672
+ const startupText = (key) => t$4(key) || stdin_default$2a.vanQrScanner[key];
18673
+ const clearStartupTimer = () => {
18674
+ if (startupTimer !== void 0)
18675
+ clearTimeout(startupTimer);
18676
+ startupTimer = void 0;
18677
+ startupDeadline = 0;
18678
+ };
18628
18679
  const release = () => {
18629
18680
  generation += 1;
18681
+ clearStartupTimer();
18630
18682
  if (timer2)
18631
18683
  clearTimeout(timer2);
18632
18684
  timer2 = void 0;
@@ -18645,6 +18697,7 @@
18645
18697
  phase.value = "paused";
18646
18698
  };
18647
18699
  const close = (cancelled = false) => {
18700
+ pickingAlbum = false;
18648
18701
  release();
18649
18702
  phase.value = "idle";
18650
18703
  if (cancelled)
@@ -18652,14 +18705,46 @@
18652
18705
  emit("update:show", false);
18653
18706
  };
18654
18707
  const reportError = (code, text, cause) => {
18708
+ const startupInfo = phase.value === "starting" && abortController && !props2.nativeScan ? {
18709
+ stage: startupStage.value,
18710
+ elapsedMs: Math.max(0, Date.now() - startupStartedAt)
18711
+ } : {};
18655
18712
  release();
18656
18713
  phase.value = "error";
18657
18714
  message.value = text;
18658
- emit("error", {
18715
+ emit("error", extend$1({
18659
18716
  code,
18660
18717
  message: text,
18661
18718
  cause
18719
+ }, startupInfo));
18720
+ };
18721
+ const reportStartupTimeout = () => {
18722
+ const timeoutMessages = {
18723
+ camera: startupText("timeoutCamera"),
18724
+ preview: startupText("timeoutPreview"),
18725
+ decoder: startupText("timeoutDecoder"),
18726
+ ready: ""
18727
+ };
18728
+ reportError("STARTUP_TIMEOUT", timeoutMessages[startupStage.value]);
18729
+ };
18730
+ const canContinueStartup = (id) => {
18731
+ if (!isCurrent(id))
18732
+ return false;
18733
+ if (startupDeadline && Date.now() >= startupDeadline) {
18734
+ reportStartupTimeout();
18735
+ return false;
18736
+ }
18737
+ return true;
18738
+ };
18739
+ const setStartupStage = (stage, id) => {
18740
+ if (!canContinueStartup(id))
18741
+ return false;
18742
+ startupStage.value = stage;
18743
+ emit("stageChange", {
18744
+ stage,
18745
+ elapsedMs: Math.max(0, Date.now() - startupStartedAt)
18662
18746
  });
18747
+ return isCurrent(id);
18663
18748
  };
18664
18749
  const cameraError = (error) => {
18665
18750
  const errorName = error == null ? void 0 : error.name;
@@ -18747,7 +18832,7 @@
18747
18832
  height: target.height / scale
18748
18833
  });
18749
18834
  if (image) {
18750
- const result = yield decoder2.decode(image, props2.formats, props2.wasmUrl);
18835
+ const result = yield decoder2.decode(image, props2.formats, props2.wasmUrl, abortController == null ? void 0 : abortController.signal);
18751
18836
  if (!isCurrent(id))
18752
18837
  return;
18753
18838
  if (result)
@@ -18773,6 +18858,7 @@
18773
18858
  return;
18774
18859
  }
18775
18860
  const id = generation;
18861
+ pickingAlbum = false;
18776
18862
  phase.value = "starting";
18777
18863
  message.value = "";
18778
18864
  if (props2.nativeScan) {
@@ -18808,8 +18894,25 @@
18808
18894
  reportError("CAMERA_UNSUPPORTED", "当前环境不支持实时扫码,请从相册识别或在系统浏览器打开");
18809
18895
  return;
18810
18896
  }
18897
+ abortController = new AbortController();
18898
+ const {
18899
+ signal
18900
+ } = abortController;
18901
+ startupStartedAt = Date.now();
18902
+ const configuredTimeout = Number(props2.startupTimeout);
18903
+ const timeout = Number.isFinite(configuredTimeout) ? Math.max(0, configuredTimeout) : DEFAULT_STARTUP_TIMEOUT;
18904
+ if (timeout > 0) {
18905
+ startupDeadline = startupStartedAt + timeout;
18906
+ startupTimer = setTimeout(() => {
18907
+ if (!isCurrent(id) || phase.value !== "starting")
18908
+ return;
18909
+ reportStartupTimeout();
18910
+ }, timeout);
18911
+ }
18912
+ if (!setStartupStage("camera", id))
18913
+ return;
18811
18914
  try {
18812
- const acquiredStream = yield navigator.mediaDevices.getUserMedia({
18915
+ const acquiredStream = yield waitForAbort(navigator.mediaDevices.getUserMedia({
18813
18916
  audio: false,
18814
18917
  video: extend$1(deviceId ? {
18815
18918
  deviceId: {
@@ -18827,28 +18930,44 @@
18827
18930
  ideal: 720
18828
18931
  }
18829
18932
  })
18830
- });
18933
+ }).then((acquired) => {
18934
+ if (!isCurrent(id))
18935
+ acquired.getTracks().forEach((track2) => track2.stop());
18936
+ return acquired;
18937
+ }), signal);
18831
18938
  if (!isCurrent(id)) {
18832
18939
  acquiredStream.getTracks().forEach((track2) => track2.stop());
18833
18940
  return;
18834
18941
  }
18835
18942
  stream = acquiredStream;
18943
+ } catch (error) {
18944
+ if (isCurrent(id))
18945
+ cameraError(error);
18946
+ return;
18947
+ }
18948
+ if (!setStartupStage("preview", id))
18949
+ return;
18950
+ try {
18836
18951
  yield vue.nextTick();
18837
- if (!isCurrent(id))
18952
+ if (!canContinueStartup(id))
18838
18953
  return;
18839
18954
  if (!video.value)
18840
18955
  throw new Error("扫码预览尚未就绪");
18841
18956
  video.value.srcObject = stream;
18842
- yield video.value.play();
18957
+ yield waitForAbort(video.value.play(), signal);
18843
18958
  } catch (error) {
18844
18959
  if (isCurrent(id))
18845
- cameraError(error);
18960
+ reportError("PREVIEW_FAILED", startupText("previewFailed"), error);
18846
18961
  return;
18847
18962
  }
18963
+ if (!setStartupStage("decoder", id))
18964
+ return;
18848
18965
  let decoder$1;
18849
18966
  try {
18850
- decoder$1 = yield Promise.resolve().then(() => decoder);
18851
- yield decoder$1.prepareDecoder(props2.wasmUrl);
18967
+ decoder$1 = yield waitForAbort(Promise.resolve().then(() => decoder), signal);
18968
+ if (!canContinueStartup(id))
18969
+ return;
18970
+ yield waitForAbort(decoder$1.prepareDecoder(props2.wasmUrl, signal), signal);
18852
18971
  } catch (error) {
18853
18972
  if (isCurrent(id))
18854
18973
  reportError("DECODER_LOAD_FAILED", "扫码资源加载失败,请检查网络或资源部署后重试", error);
@@ -18856,6 +18975,8 @@
18856
18975
  }
18857
18976
  if (!isCurrent(id))
18858
18977
  return;
18978
+ if (!canContinueStartup(id))
18979
+ return;
18859
18980
  const track = stream == null ? void 0 : stream.getVideoTracks()[0];
18860
18981
  try {
18861
18982
  const capability = (_b = track == null ? void 0 : track.getCapabilities) == null ? void 0 : _b.call(track).torch;
@@ -18877,6 +18998,9 @@
18877
18998
  }).catch(() => {
18878
18999
  });
18879
19000
  phase.value = "scanning";
19001
+ clearStartupTimer();
19002
+ if (!setStartupStage("ready", id))
19003
+ return;
18880
19004
  emit("ready", {
18881
19005
  torch: hasTorch.value
18882
19006
  });
@@ -18886,25 +19010,32 @@
18886
19010
  const scanImage = (file) => __async$3(this, null, function* () {
18887
19011
  if (!props2.show || props2.paused)
18888
19012
  return;
19013
+ pickingAlbum = false;
19014
+ release();
19015
+ phase.value = "processing";
19016
+ message.value = "";
18889
19017
  if (file.size > Number(props2.maxImageSize)) {
18890
19018
  reportError("IMAGE_TOO_LARGE", "图片过大,请选择较小的图片");
18891
19019
  return;
18892
19020
  }
18893
- release();
18894
19021
  const id = generation;
18895
- phase.value = "processing";
18896
- message.value = "";
19022
+ abortController = new AbortController();
19023
+ const {
19024
+ signal
19025
+ } = abortController;
18897
19026
  let imageCanvas;
18898
19027
  try {
18899
- const decoder$1 = yield Promise.resolve().then(() => decoder);
18900
- const image = yield decoder$1.loadImage(file);
19028
+ const decoder$1 = yield waitForAbort(Promise.resolve().then(() => decoder), signal);
19029
+ if (!isCurrent(id))
19030
+ return;
19031
+ const image = yield waitForAbort(decoder$1.loadImage(file, signal), signal);
18901
19032
  if (!isCurrent(id))
18902
19033
  return;
18903
19034
  imageCanvas = document.createElement("canvas");
18904
19035
  const data = decoder$1.captureImage(image, imageCanvas, 1920);
18905
19036
  if (!data)
18906
19037
  throw new Error("无法读取图片");
18907
- const result = yield decoder$1.decode(data, props2.formats, props2.wasmUrl);
19038
+ const result = yield waitForAbort(decoder$1.decode(data, props2.formats, props2.wasmUrl, signal), signal);
18908
19039
  if (!isCurrent(id))
18909
19040
  return;
18910
19041
  if (!result) {
@@ -18973,6 +19104,15 @@
18973
19104
  start2();
18974
19105
  }
18975
19106
  };
19107
+ const onAlbumCancel = () => {
19108
+ if (pickingAlbum && phase.value === "paused")
19109
+ start2();
19110
+ pickingAlbum = false;
19111
+ };
19112
+ vue.watch(fileInput, (input, previous) => {
19113
+ previous == null ? void 0 : previous.removeEventListener("cancel", onAlbumCancel);
19114
+ input == null ? void 0 : input.addEventListener("cancel", onAlbumCancel);
19115
+ });
18976
19116
  vue.watch(() => props2.show, (show) => __async$3(this, null, function* () {
18977
19117
  release();
18978
19118
  recentResults.clear();
@@ -18999,9 +19139,15 @@
18999
19139
  if (props2.show)
19000
19140
  start2();
19001
19141
  });
19142
+ vue.watch(() => props2.wasmUrl, () => {
19143
+ if (props2.show && !props2.nativeScan && (phase.value === "starting" || phase.value === "scanning"))
19144
+ start2();
19145
+ });
19002
19146
  vue.onMounted(() => document.addEventListener("visibilitychange", onVisibilityChange));
19003
19147
  vue.onBeforeUnmount(() => {
19148
+ var _a;
19004
19149
  release();
19150
+ (_a = fileInput.value) == null ? void 0 : _a.removeEventListener("cancel", onAlbumCancel);
19005
19151
  if (canvas) {
19006
19152
  canvas.width = 0;
19007
19153
  canvas.height = 0;
@@ -19086,7 +19232,15 @@
19086
19232
  "color": "white",
19087
19233
  "vertical": true
19088
19234
  }, {
19089
- default: () => [phase.value === "starting" ? props2.nativeScan ? "正在打开扫码..." : "正在启动摄像头..." : props2.processingText]
19235
+ default: () => {
19236
+ var _a, _b, _c, _d, _e, _f;
19237
+ return [phase.value === "starting" ? props2.nativeScan ? "正在打开扫码..." : {
19238
+ camera: (_b = (_a = props2.startupTexts) == null ? void 0 : _a.camera) != null ? _b : startupText("startupCamera"),
19239
+ preview: (_d = (_c = props2.startupTexts) == null ? void 0 : _c.preview) != null ? _d : startupText("startupPreview"),
19240
+ decoder: (_f = (_e = props2.startupTexts) == null ? void 0 : _e.decoder) != null ? _f : startupText("startupDecoder"),
19241
+ ready: ""
19242
+ }[startupStage.value] : props2.processingText];
19243
+ }
19090
19244
  }), needsRetry && vue.createVNode(vue.Fragment, null, [vue.createVNode("p", {
19091
19245
  "class": bem$k("message")
19092
19246
  }, [message.value || "扫描已暂停"]), vue.createVNode(Button, {
@@ -19119,6 +19273,7 @@
19119
19273
  var _a;
19120
19274
  stop();
19121
19275
  resumeWhenVisible = false;
19276
+ pickingAlbum = true;
19122
19277
  (_a = fileInput.value) == null ? void 0 : _a.click();
19123
19278
  }
19124
19279
  }, [vue.createVNode(Icon, {
@@ -19148,6 +19303,9 @@
19148
19303
  input.value = "";
19149
19304
  if (file)
19150
19305
  scanImage(file);
19306
+ else if (pickingAlbum && phase.value === "paused")
19307
+ start2();
19308
+ pickingAlbum = false;
19151
19309
  }
19152
19310
  }, null)]
19153
19311
  });
@@ -19159,6 +19317,8 @@
19159
19317
  title: "扫描设备二维码",
19160
19318
  tip: "将设备二维码置于取景框内,即可自动识别",
19161
19319
  processingText: "正在处理扫码结果...",
19320
+ startupTimeout: DEFAULT_STARTUP_TIMEOUT,
19321
+ startupTexts: void 0,
19162
19322
  formats: ["QRCode"],
19163
19323
  facingMode: "environment",
19164
19324
  showAlbum: true,
@@ -19177,6 +19337,8 @@
19177
19337
  closeOnPopstate: true,
19178
19338
  onScan: void 0,
19179
19339
  onError: void 0,
19340
+ onStageChange: void 0,
19341
+ onReady: void 0,
19180
19342
  onCancel: void 0,
19181
19343
  onClose: void 0
19182
19344
  };
@@ -22192,7 +22354,7 @@
22192
22354
  t2.removeEventListener(i, s, n);
22193
22355
  }), this.eventListeners = []);
22194
22356
  }
22195
- function ready$1() {
22357
+ function ready() {
22196
22358
  return new Promise((e2) => this.ready ? setTimeout(e2, 0) : on$1.call(this, this.elements.container, "ready", e2)).then(() => {
22197
22359
  });
22198
22360
  }
@@ -23072,7 +23234,7 @@
23072
23234
  }, togglePoster(e2) {
23073
23235
  toggleClass(this.elements.container, this.config.classNames.posterEnabled, e2);
23074
23236
  }, setPoster(e2, t2 = true) {
23075
- return t2 && this.poster ? Promise.reject(new Error("Poster already set")) : (this.media.setAttribute("data-poster", e2), this.elements.poster.removeAttribute("hidden"), ready$1.call(this).then(() => loadImage$1(e2)).catch((t3) => {
23237
+ return t2 && this.poster ? Promise.reject(new Error("Poster already set")) : (this.media.setAttribute("data-poster", e2), this.elements.poster.removeAttribute("hidden"), ready.call(this).then(() => loadImage$1(e2)).catch((t3) => {
23076
23238
  throw e2 === this.poster && ui.togglePoster.call(this, false), t3;
23077
23239
  }).then(() => {
23078
23240
  if (e2 !== this.poster)
@@ -26134,7 +26296,7 @@
26134
26296
  });
26135
26297
  }
26136
26298
  };
26137
- const version = "0.0.52";
26299
+ const version = "0.0.54";
26138
26300
  function install(app) {
26139
26301
  const components = [
26140
26302
  ActionBar,
@@ -26811,6 +26973,9 @@
26811
26973
  }
26812
26974
  (c == null ? n(a, s) : c) || K.set(e2, [s]);
26813
26975
  }
26976
+ function Y(e2) {
26977
+ K.delete(e2);
26978
+ }
26814
26979
  async function X(e2, t2) {
26815
26980
  let n = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : I, r = {
26816
26981
  ...I,
@@ -26907,12 +27072,12 @@
26907
27072
  var e3;
26908
27073
  if (!(y2 != null && (e3 = y2.buffer) != null && e3.resizable)) {
26909
27074
  var t3 = te();
26910
- y2 = new Int8Array(t3), Ht = new Int16Array(t3), i.HEAPU8 = I2 = new Uint8Array(t3), Y = new Uint16Array(t3), Ut = new Int32Array(t3), E2 = new Uint32Array(t3), Lt = new Float32Array(t3), Rt = new Float64Array(t3);
27075
+ y2 = new Int8Array(t3), Ht = new Int16Array(t3), i.HEAPU8 = I2 = new Uint8Array(t3), Y2 = new Uint16Array(t3), Ut = new Int32Array(t3), E2 = new Uint32Array(t3), Lt = new Float32Array(t3), Rt = new Float64Array(t3);
26911
27076
  }
26912
27077
  }
26913
27078
  function re() {
26914
27079
  var e3 = i.preRun;
26915
- e3 && (typeof e3 == "function" && (e3 = [e3]), ge.push(...e3)), b2(ge);
27080
+ e3 && (typeof e3 == "function" && (e3 = [e3]), ge2.push(...e3)), b2(ge2);
26916
27081
  }
26917
27082
  function ie() {
26918
27083
  Rr.ra();
@@ -26986,7 +27151,7 @@
26986
27151
  var y2, b2 = (e3) => {
26987
27152
  for (; e3.length > 0; )
26988
27153
  e3.shift()(i);
26989
- }, x2 = [], ge = [], _e = true, S = (e3) => Yn(e3), C2 = () => Zn(), ve = [], w2 = (e3) => {
27154
+ }, x2 = [], ge2 = [], _e = true, S = (e3) => Yn(e3), C2 = () => Zn(), ve = [], w2 = (e3) => {
26990
27155
  var t3 = ve[e3];
26991
27156
  return t3 || (ve[e3] = t3 = rr.get(e3)), t3;
26992
27157
  }, ye = (e3, t3) => w2(e3)(t3), T = [], be = 0, E2;
@@ -27627,12 +27792,12 @@
27627
27792
  var r3 = [n3[0], null].concat(n3.slice(1));
27628
27793
  return _t(e3, Ot(e3, r3, null, i2, a2, o2), t3 - 1), [];
27629
27794
  });
27630
- }, Ht, Y, Ut, Wt = (e3, t3, n2) => {
27795
+ }, Ht, Y2, Ut, Wt = (e3, t3, n2) => {
27631
27796
  switch (t3) {
27632
27797
  case 1:
27633
27798
  return n2 ? (e4) => y2[e4] : (e4) => I2[e4];
27634
27799
  case 2:
27635
- return n2 ? (e4) => Ht[e4 >> 1] : (e4) => Y[e4 >> 1];
27800
+ return n2 ? (e4) => Ht[e4 >> 1] : (e4) => Y2[e4 >> 1];
27636
27801
  case 4:
27637
27802
  return n2 ? (e4) => Ut[e4 >> 2] : (e4) => E2[e4 >> 2];
27638
27803
  default:
@@ -27789,11 +27954,11 @@
27789
27954
  }
27790
27955
  });
27791
27956
  }, on2 = globalThis.TextDecoder ? new TextDecoder("utf-16le") : void 0, sn = (e3, t3, n2) => {
27792
- var r2 = e3 >> 1, i2 = tn(Y, r2, t3 / 2, n2);
27957
+ var r2 = e3 >> 1, i2 = tn(Y2, r2, t3 / 2, n2);
27793
27958
  if (i2 - r2 > 16 && on2)
27794
- return on2.decode(Y.subarray(r2, i2));
27959
+ return on2.decode(Y2.subarray(r2, i2));
27795
27960
  for (var a2 = "", o2 = r2; o2 < i2; ++o2) {
27796
- var s2 = Y[o2];
27961
+ var s2 = Y2[o2];
27797
27962
  a2 += String.fromCharCode(s2);
27798
27963
  }
27799
27964
  return a2;
@@ -28375,6 +28540,9 @@
28375
28540
  function x(e2) {
28376
28541
  return J(b, e2);
28377
28542
  }
28543
+ function ge() {
28544
+ return Y(b);
28545
+ }
28378
28546
  async function C(e2, t2) {
28379
28547
  return X(b, e2, t2);
28380
28548
  }
@@ -28398,47 +28566,114 @@
28398
28566
  step((generator = generator.apply(__this, __arguments)).next());
28399
28567
  });
28400
28568
  };
28401
- let ready;
28402
- let activeWasmUrl;
28403
- function prepareDecoder(wasmUrl) {
28404
- return __async(this, null, function* () {
28569
+ let preparation;
28570
+ function invalidate(entry) {
28571
+ if (preparation === entry) {
28572
+ preparation = void 0;
28573
+ ge();
28574
+ }
28575
+ }
28576
+ function createPreparation(wasmUrl) {
28577
+ const controller = new AbortController();
28578
+ const entry = {
28579
+ wasmUrl,
28580
+ pending: true,
28581
+ controller,
28582
+ consumers: /* @__PURE__ */ new Set(),
28583
+ promise: void 0
28584
+ };
28585
+ const initialize = () => __async(this, null, function* () {
28405
28586
  const url = wasmUrl || (yield Promise.resolve().then(() => zxing_reader$1)).default;
28406
- if (!ready || url !== activeWasmUrl) {
28407
- activeWasmUrl = url;
28408
- ready = Promise.resolve(
28409
- x({
28410
- overrides: { locateFile: () => url },
28411
- fireImmediately: true
28412
- })
28413
- ).catch((error) => {
28414
- ready = void 0;
28415
- throw error;
28416
- });
28587
+ if (controller.signal.aborted || preparation !== entry)
28588
+ throw abortError();
28589
+ yield x({
28590
+ overrides: { locateFile: () => url },
28591
+ fireImmediately: true
28592
+ });
28593
+ });
28594
+ entry.promise = waitForAbort(
28595
+ Promise.resolve().then(initialize),
28596
+ controller.signal
28597
+ ).then(
28598
+ () => {
28599
+ entry.pending = false;
28600
+ },
28601
+ (error) => {
28602
+ entry.pending = false;
28603
+ invalidate(entry);
28604
+ throw error;
28605
+ }
28606
+ );
28607
+ return entry;
28608
+ }
28609
+ function prepareDecoder(wasmUrl, signal) {
28610
+ return __async(this, null, function* () {
28611
+ if (signal == null ? void 0 : signal.aborted)
28612
+ throw abortError();
28613
+ if (!preparation || preparation.wasmUrl !== wasmUrl) {
28614
+ preparation = createPreparation(wasmUrl);
28615
+ }
28616
+ const entry = preparation;
28617
+ const consumer = Symbol("decoder-consumer");
28618
+ entry.consumers.add(consumer);
28619
+ const releaseConsumer = () => {
28620
+ entry.consumers.delete(consumer);
28621
+ if (entry.pending && !entry.consumers.size) {
28622
+ invalidate(entry);
28623
+ entry.controller.abort();
28624
+ }
28625
+ };
28626
+ signal == null ? void 0 : signal.addEventListener("abort", releaseConsumer, { once: true });
28627
+ try {
28628
+ yield waitForAbort(entry.promise, signal);
28629
+ } finally {
28630
+ signal == null ? void 0 : signal.removeEventListener("abort", releaseConsumer);
28631
+ releaseConsumer();
28417
28632
  }
28418
- yield ready;
28419
28633
  });
28420
28634
  }
28421
- function decode(image, formats, wasmUrl) {
28635
+ function decode(image, formats, wasmUrl, signal) {
28422
28636
  return __async(this, null, function* () {
28423
- yield prepareDecoder(wasmUrl);
28424
- const results = yield C(image, {
28425
- formats: formats.length ? formats : ["QRCode"],
28426
- tryHarder: true,
28427
- maxNumberOfSymbols: 1
28428
- });
28637
+ yield prepareDecoder(wasmUrl, signal);
28638
+ if (signal == null ? void 0 : signal.aborted)
28639
+ throw abortError();
28640
+ const results = yield waitForAbort(
28641
+ C(image, {
28642
+ formats: formats.length ? formats : ["QRCode"],
28643
+ tryHarder: true,
28644
+ maxNumberOfSymbols: 1
28645
+ }),
28646
+ signal
28647
+ );
28429
28648
  return results.find((result) => result.isValid && result.text.length > 0);
28430
28649
  });
28431
28650
  }
28432
- function loadImage(file) {
28651
+ function loadImage(file, signal) {
28433
28652
  return new Promise((resolve, reject) => {
28653
+ if (signal == null ? void 0 : signal.aborted) {
28654
+ reject(abortError());
28655
+ return;
28656
+ }
28434
28657
  const url = URL.createObjectURL(file);
28435
28658
  const image = new Image();
28436
- image.onload = () => {
28659
+ const cleanup = () => {
28437
28660
  URL.revokeObjectURL(url);
28661
+ signal == null ? void 0 : signal.removeEventListener("abort", onAbort);
28662
+ image.onload = null;
28663
+ image.onerror = null;
28664
+ };
28665
+ const onAbort = () => {
28666
+ cleanup();
28667
+ image.src = "";
28668
+ reject(abortError());
28669
+ };
28670
+ signal == null ? void 0 : signal.addEventListener("abort", onAbort, { once: true });
28671
+ image.onload = () => {
28672
+ cleanup();
28438
28673
  resolve(image);
28439
28674
  };
28440
28675
  image.onerror = () => {
28441
- URL.revokeObjectURL(url);
28676
+ cleanup();
28442
28677
  reject(new Error("无法读取图片,请选择 JPG、PNG 等浏览器支持的图片"));
28443
28678
  };
28444
28679
  image.src = url;