@kiva/kv-components 8.17.1 → 8.18.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.
package/dist/index.js CHANGED
@@ -1,261 +1,266 @@
1
1
  import { default as r } from "./vue/KvAccordionItem.js";
2
2
  import { default as a } from "./vue/KvActivityRow.js";
3
3
  import { default as l } from "./vue/KvBorrowerImage.js";
4
- import { default as s } from "./vue/KvButton.js";
4
+ import { default as p } from "./vue/KvButton.js";
5
5
  import { default as d } from "./vue/KvCardFrame.js";
6
6
  import { default as x } from "./vue/KvCarousel.js";
7
7
  import { default as K } from "./vue/KvCartModal.js";
8
8
  import { default as A } from "./vue/KvCartPill.js";
9
9
  import { default as C } from "./vue/KvCheckbox.js";
10
10
  import { default as c } from "./vue/KvCheckoutReceipt.js";
11
- import { default as N } from "./vue/KvChip.js";
11
+ import { default as L } from "./vue/KvChip.js";
12
12
  import { default as E } from "./vue/KvClassicLoanCard.js";
13
13
  import { default as M } from "./vue/KvCompactLoanCard.js";
14
- import { default as I } from "./vue/KvCommentsAdd.js";
15
- import { default as P } from "./vue/KvCommentsContainer.js";
14
+ import { default as O } from "./vue/KvCommentsAdd.js";
15
+ import { default as g } from "./vue/KvCommentsContainer.js";
16
16
  import { default as G } from "./vue/KvCommentsHeartButton.js";
17
- import { default as F } from "./vue/KvCommentsList.js";
18
- import { default as B } from "./vue/KvCommentsListItem.js";
19
- import { default as y } from "./vue/KvCommentsReplyButton.js";
20
- import { default as k } from "./vue/KvContentfulImg.js";
17
+ import { default as D } from "./vue/KvCommentsList.js";
18
+ import { default as V } from "./vue/KvCommentsListItem.js";
19
+ import { default as U } from "./vue/KvCommentsReplyButton.js";
20
+ import { default as b } from "./vue/KvContentfulImg.js";
21
21
  import { default as w } from "./vue/KvCountdownTimer.js";
22
22
  import { default as H } from "./vue/KvDatePicker.js";
23
- import { default as z } from "./vue/KvExpandable.js";
24
- import { default as Z } from "./vue/KvExpandableQuestion.js";
25
- import { default as J } from "./vue/KvFlag.js";
26
- import { default as Y } from "./vue/KvGrid.js";
23
+ import { default as j } from "./vue/KvExpandable.js";
24
+ import { default as Y } from "./vue/KvExpandableQuestion.js";
25
+ import { default as q } from "./vue/KvFlag.js";
26
+ import { default as X } from "./vue/KvGrid.js";
27
27
  import { default as ee } from "./vue/KvIconButton.js";
28
- import { default as re } from "./vue/KvImpactDashboardHeader.js";
29
- import { default as ae } from "./vue/KvImpactVerticalSelector.js";
30
- import { default as le } from "./vue/KvInlineActivityCard.js";
31
- import { default as se } from "./vue/KvInlineActivityFeed.js";
32
- import { default as de } from "./vue/KvIntroductionLoanCard.js";
33
- import { default as xe } from "./vue/KvLendAmountButton.js";
34
- import { default as Ke } from "./vue/KvLendCta.js";
35
- import { default as Ae } from "./vue/KvLightbox.js";
36
- import { default as Ce } from "./vue/KvLineGraph.js";
37
- import { default as ce } from "./vue/KvLoanActivities.js";
38
- import { default as Ne } from "./vue/KvLoanBookmark.js";
39
- import { default as Ee } from "./vue/KvLoanCallouts.js";
40
- import { KV_LOAN_INFO_CARD_FRAGMENT as Me, default as Oe } from "./vue/KvLoanInfoCard.js";
41
- import { default as Se } from "./vue/KvLoanProgressGroup.js";
42
- import { default as ge } from "./vue/KvLoanTag.js";
28
+ import { default as re } from "./vue/KvImageUpload.js";
29
+ import { default as ae } from "./vue/KvImpactDashboardHeader.js";
30
+ import { default as le } from "./vue/KvImpactVerticalSelector.js";
31
+ import { default as pe } from "./vue/KvInlineActivityCard.js";
32
+ import { default as de } from "./vue/KvInlineActivityFeed.js";
33
+ import { default as xe } from "./vue/KvIntroductionLoanCard.js";
34
+ import { default as Ke } from "./vue/KvLendAmountButton.js";
35
+ import { default as Ae } from "./vue/KvLendCta.js";
36
+ import { default as Ce } from "./vue/KvLightbox.js";
37
+ import { default as ce } from "./vue/KvLineGraph.js";
38
+ import { default as Le } from "./vue/KvLoanActivities.js";
39
+ import { default as Ee } from "./vue/KvLoanBookmark.js";
40
+ import { default as Me } from "./vue/KvLoanCallouts.js";
41
+ import { KV_LOAN_INFO_CARD_FRAGMENT as Oe, default as Se } from "./vue/KvLoanInfoCard.js";
42
+ import { default as Pe } from "./vue/KvLoanProgressGroup.js";
43
+ import { default as Fe } from "./vue/KvLoanTag.js";
43
44
  import { default as he } from "./vue/KvLoanTeamPick.js";
44
- import { default as Ve } from "./vue/KvLoanUse.js";
45
- import { default as De } from "./vue/KvLoadingPlaceholder.js";
46
- import { default as be } from "./vue/KvLoadingSpinner.js";
47
- import { default as Ue } from "./vue/KvMap.js";
48
- import { default as We } from "./vue/KvMaterialIcon.js";
49
- import { default as je } from "./vue/KvSimpleMap.js";
50
- import { default as Qe } from "./vue/KvPageContainer.js";
51
- import { default as qe } from "./vue/KvPagination.js";
52
- import { default as Xe } from "./vue/KvPieChart.js";
53
- import { default as $e } from "./vue/KvPieChartV2.js";
54
- import { default as oo } from "./vue/KvPill.js";
55
- import { default as to } from "./vue/KvPopper.js";
56
- import { default as fo } from "./vue/KvProgressBar.js";
57
- import { default as mo } from "./vue/KvProgressCircle.js";
58
- import { default as po } from "./vue/KvPulsingDot.js";
59
- import { default as xo } from "./vue/KvRadio.js";
60
- import { default as Ko } from "./vue/KvSelect.js";
61
- import { default as Ao } from "./vue/KvSideSheet.js";
62
- import { default as Co } from "./vue/KvSwitch.js";
63
- import { default as co } from "./vue/KvTab.js";
64
- import { default as No } from "./vue/KvTabPanel.js";
65
- import { default as Eo } from "./vue/KvTabs.js";
66
- import { default as Mo } from "./vue/KvTextInput.js";
67
- import { default as Io } from "./vue/KvTextLink.js";
68
- import { default as Po } from "./vue/KvThemeProvider.js";
69
- import { default as Go } from "./vue/KvToast.js";
70
- import { default as Fo } from "./vue/KvTooltip.js";
71
- import { default as Bo } from "./vue/KvTreeMapChart.js";
72
- import { default as yo } from "./vue/KvUserAvatar.js";
73
- import { default as ko } from "./vue/KvUtilityMenu.js";
74
- import { default as wo } from "./vue/KvVerticalCarousel.js";
75
- import { default as Ho } from "./vue/KvVotingCard.js";
76
- import { default as zo } from "./vue/KvVotingCardV2.js";
77
- import { default as Zo } from "./vue/KvWideLoanCard.js";
78
- import { default as Jo } from "./vue/KvAtbModal.js";
79
- import { default as Yo } from "./vue/KvSecondaryNav.js";
80
- import { default as er } from "./vue/KvWwwHeader.js";
81
- import { default as rr } from "./vue/KvWwwHeaderBasic/KvWwwHeaderBasic.js";
82
- import { default as ar, Mash as fr } from "./utils/Alea.js";
83
- import { groupBy as mr, sortBy as sr } from "./utils/arrayUtils.js";
84
- import { useAttrs as dr } from "./utils/attrs.js";
85
- import { carouselUtil as xr } from "./utils/carousels.js";
86
- import { abc as Kr, indexIn as vr, startsWith as Ar } from "./utils/comparators.js";
87
- import { debounce as Cr } from "./utils/debounce.js";
88
- import { useEventListener as cr } from "./utils/event.js";
89
- import { collapse as Nr, expand as Tr } from "./utils/expander.js";
90
- import { getKivaImageUrl as Rr, isLegacyPlaceholderAvatar as Mr, randomizedUserAvatarClass as Or } from "./utils/imageUtils.js";
91
- import { LOAN_CALLOUTS_FRAGMENT as Sr, LOAN_GEOCODE_FRAGMENT as Pr, LOAN_PROGRESS_FRAGMENT as gr, loanCardComputedProperties as Gr, loanCardMethods as hr } from "./utils/loanCard.js";
92
- import { BALANCE_CAMPAIGN as Vr, BASE_CAMPAIGN as Br, ERL_COOKIE_NAME as Dr, NO_BALANCE_CAMPAIGN as yr, TOP_UP_CAMPAIGN as br, getDropdownPriceArray as kr, getLendCtaSelectedOption as Ur, isBetween25And50 as wr, isLessThan25 as Wr, truncateStringByWords as Hr } from "./utils/loanUtils.js";
93
- import { animationCoordinator as zr, computeMapCenter as Qr, computeMapZoom as Zr, generateMapMarkers as qr, getCoordinatesBetween as Jr, getCountryColor as Xr, getLoansIntervals as Yr } from "./utils/mapUtils.js";
94
- import { lockPrintSingleEl as et, unlockPrintSingleEl as ot } from "./utils/printing.js";
95
- import { lockScroll as tt, lockScrollSmallOnly as at, unlockScroll as ft, unlockScrollSmallOnly as lt } from "./utils/scrollLock.js";
96
- import { buildTailwindClassName as st, headerNumberCase as pt, kebabCase as dt, removeObjectProperty as ut } from "./utils/themeUtils.js";
97
- import { throttle as nt } from "./utils/throttle.js";
98
- import { isTargetElement as vt, offBodyTouchstart as At, onBodyTouchstart as it } from "./utils/touchEvents.js";
99
- import { getTreemap as _t } from "./utils/treemap.js";
100
- import { KvBlueskyIcon as Lt } from "./assets/icons/bluesky.js";
101
- import { KV_CLASSIC_LOAN_CARD_FRAGMENT as Tt, KV_CLASSIC_LOAN_CARD_USER_FRAGMET as Et } from "./vue/KvClassicLoanCard2.js";
102
- import { KV_COMPACT_LOAN_CARD_FRAGMENT as Mt, KV_COMPACT_LOAN_CARD_USER_FRAGMENT as Ot } from "./vue/KvCompactLoanCard2.js";
103
- import { KV_INTRODUCTION_LOAN_CARD_FRAGMENT as St, KV_INTRODUCTION_LOAN_CARD_USER_FRAGMENT as Pt } from "./vue/KvIntroductionLoanCard2.js";
104
- import { KV_LEND_CTA_FRAGMENT as Gt, KV_LEND_CTA_USER_FRAGMENT as ht } from "./vue/KvLendCta2.js";
105
- import { KV_LOAN_ACTIVITIES_FRAGMENT as Vt } from "./vue/KvLoanActivities2.js";
106
- import { KV_LOAN_BOOKMARK_FRAGMENT as Dt } from "./vue/KvLoanBookmark2.js";
107
- import { KV_LOAN_TAG_FRAGMENT as bt } from "./vue/KvLoanTag2.js";
108
- import { KV_LOAN_USE_FRAGMENT as Ut } from "./vue/KvLoanUse2.js";
109
- import { KV_WIDE_LOAN_CARD_FRAGMENT as Wt, KV_WIDE_LOAN_CARD_USER_FRAGMENT as Ht } from "./vue/KvWideLoanCard2.js";
45
+ import { default as Be } from "./vue/KvLoanUse.js";
46
+ import { default as ye } from "./vue/KvLoadingPlaceholder.js";
47
+ import { default as ke } from "./vue/KvLoadingSpinner.js";
48
+ import { default as We } from "./vue/KvMap.js";
49
+ import { default as ze } from "./vue/KvMaterialIcon.js";
50
+ import { default as Qe } from "./vue/KvSimpleMap.js";
51
+ import { default as Ze } from "./vue/KvPageContainer.js";
52
+ import { default as Je } from "./vue/KvPagination.js";
53
+ import { default as $e } from "./vue/KvPieChart.js";
54
+ import { default as oo } from "./vue/KvPieChartV2.js";
55
+ import { default as to } from "./vue/KvPill.js";
56
+ import { default as fo } from "./vue/KvPopper.js";
57
+ import { default as mo } from "./vue/KvProgressBar.js";
58
+ import { default as so } from "./vue/KvProgressCircle.js";
59
+ import { default as xo } from "./vue/KvPulsingDot.js";
60
+ import { default as Ko } from "./vue/KvRadio.js";
61
+ import { default as Ao } from "./vue/KvSelect.js";
62
+ import { default as Co } from "./vue/KvSideSheet.js";
63
+ import { default as co } from "./vue/KvSwitch.js";
64
+ import { default as Lo } from "./vue/KvTab.js";
65
+ import { default as Eo } from "./vue/KvTabPanel.js";
66
+ import { default as Mo } from "./vue/KvTabs.js";
67
+ import { default as Oo } from "./vue/KvTextInput.js";
68
+ import { default as go } from "./vue/KvTextLink.js";
69
+ import { default as Go } from "./vue/KvThemeProvider.js";
70
+ import { default as Do } from "./vue/KvToast.js";
71
+ import { default as Vo } from "./vue/KvTooltip.js";
72
+ import { default as Uo } from "./vue/KvTreeMapChart.js";
73
+ import { default as bo } from "./vue/KvUserAvatar.js";
74
+ import { default as wo } from "./vue/KvUtilityMenu.js";
75
+ import { default as Ho } from "./vue/KvVerticalCarousel.js";
76
+ import { default as jo } from "./vue/KvVotingCard.js";
77
+ import { default as Yo } from "./vue/KvVotingCardV2.js";
78
+ import { default as qo } from "./vue/KvWideLoanCard.js";
79
+ import { default as Xo } from "./vue/KvAtbModal.js";
80
+ import { default as er } from "./vue/KvSecondaryNav.js";
81
+ import { default as rr } from "./vue/KvWwwHeader.js";
82
+ import { default as ar } from "./vue/KvWwwHeaderBasic/KvWwwHeaderBasic.js";
83
+ import { default as lr, Mash as mr } from "./utils/Alea.js";
84
+ import { groupBy as sr, sortBy as dr } from "./utils/arrayUtils.js";
85
+ import { useAttrs as xr } from "./utils/attrs.js";
86
+ import { carouselUtil as Kr } from "./utils/carousels.js";
87
+ import { abc as Ar, indexIn as ir, startsWith as Cr } from "./utils/comparators.js";
88
+ import { debounce as cr } from "./utils/debounce.js";
89
+ import { useEventListener as Lr } from "./utils/event.js";
90
+ import { collapse as Er, expand as Rr } from "./utils/expander.js";
91
+ import { DEFAULT_ACCEPTED_IMAGE_TYPES as Ir, cropResizeImageToDataUrl as Or, getKivaImageUrl as Sr, isLegacyPlaceholderAvatar as gr, randomizedUserAvatarClass as Pr, validateImageFile as Gr } from "./utils/imageUtils.js";
92
+ import { LOAN_CALLOUTS_FRAGMENT as Dr, LOAN_GEOCODE_FRAGMENT as hr, LOAN_PROGRESS_FRAGMENT as Vr, loanCardComputedProperties as Br, loanCardMethods as Ur } from "./utils/loanCard.js";
93
+ import { BALANCE_CAMPAIGN as br, BASE_CAMPAIGN as kr, ERL_COOKIE_NAME as wr, NO_BALANCE_CAMPAIGN as Wr, TOP_UP_CAMPAIGN as Hr, getDropdownPriceArray as zr, getLendCtaSelectedOption as jr, isBetween25And50 as Qr, isLessThan25 as Yr, truncateStringByWords as Zr } from "./utils/loanUtils.js";
94
+ import { animationCoordinator as Jr, computeMapCenter as Xr, computeMapZoom as $r, generateMapMarkers as et, getCoordinatesBetween as ot, getCountryColor as rt, getLoansIntervals as tt } from "./utils/mapUtils.js";
95
+ import { lockPrintSingleEl as ft, unlockPrintSingleEl as lt } from "./utils/printing.js";
96
+ import { lockScroll as pt, lockScrollSmallOnly as st, unlockScroll as dt, unlockScrollSmallOnly as ut } from "./utils/scrollLock.js";
97
+ import { buildTailwindClassName as nt, headerNumberCase as Kt, kebabCase as vt, removeObjectProperty as At } from "./utils/themeUtils.js";
98
+ import { throttle as Ct } from "./utils/throttle.js";
99
+ import { isTargetElement as ct, offBodyTouchstart as Tt, onBodyTouchstart as Lt } from "./utils/touchEvents.js";
100
+ import { getTreemap as Et } from "./utils/treemap.js";
101
+ import { KvBlueskyIcon as Mt } from "./assets/icons/bluesky.js";
102
+ import { KV_CLASSIC_LOAN_CARD_FRAGMENT as Ot, KV_CLASSIC_LOAN_CARD_USER_FRAGMET as St } from "./vue/KvClassicLoanCard2.js";
103
+ import { KV_COMPACT_LOAN_CARD_FRAGMENT as Pt, KV_COMPACT_LOAN_CARD_USER_FRAGMENT as Gt } from "./vue/KvCompactLoanCard2.js";
104
+ import { KV_INTRODUCTION_LOAN_CARD_FRAGMENT as Dt, KV_INTRODUCTION_LOAN_CARD_USER_FRAGMENT as ht } from "./vue/KvIntroductionLoanCard2.js";
105
+ import { KV_LEND_CTA_FRAGMENT as Bt, KV_LEND_CTA_USER_FRAGMENT as Ut } from "./vue/KvLendCta2.js";
106
+ import { KV_LOAN_ACTIVITIES_FRAGMENT as bt } from "./vue/KvLoanActivities2.js";
107
+ import { KV_LOAN_BOOKMARK_FRAGMENT as wt } from "./vue/KvLoanBookmark2.js";
108
+ import { KV_LOAN_TAG_FRAGMENT as Ht } from "./vue/KvLoanTag2.js";
109
+ import { KV_LOAN_USE_FRAGMENT as jt } from "./vue/KvLoanUse2.js";
110
+ import { KV_WIDE_LOAN_CARD_FRAGMENT as Yt, KV_WIDE_LOAN_CARD_USER_FRAGMENT as Zt } from "./vue/KvWideLoanCard2.js";
110
111
  export {
111
- ar as Alea,
112
- Vr as BALANCE_CAMPAIGN,
113
- Br as BASE_CAMPAIGN,
114
- Dr as ERL_COOKIE_NAME,
115
- Tt as KV_CLASSIC_LOAN_CARD_FRAGMENT,
116
- Et as KV_CLASSIC_LOAN_CARD_USER_FRAGMET,
117
- Mt as KV_COMPACT_LOAN_CARD_FRAGMENT,
118
- Ot as KV_COMPACT_LOAN_CARD_USER_FRAGMENT,
119
- St as KV_INTRODUCTION_LOAN_CARD_FRAGMENT,
120
- Pt as KV_INTRODUCTION_LOAN_CARD_USER_FRAGMENT,
121
- Gt as KV_LEND_CTA_FRAGMENT,
122
- ht as KV_LEND_CTA_USER_FRAGMENT,
123
- Vt as KV_LOAN_ACTIVITIES_FRAGMENT,
124
- Dt as KV_LOAN_BOOKMARK_FRAGMENT,
125
- Me as KV_LOAN_INFO_CARD_FRAGMENT,
126
- bt as KV_LOAN_TAG_FRAGMENT,
127
- Ut as KV_LOAN_USE_FRAGMENT,
128
- Wt as KV_WIDE_LOAN_CARD_FRAGMENT,
129
- Ht as KV_WIDE_LOAN_CARD_USER_FRAGMENT,
112
+ lr as Alea,
113
+ br as BALANCE_CAMPAIGN,
114
+ kr as BASE_CAMPAIGN,
115
+ Ir as DEFAULT_ACCEPTED_IMAGE_TYPES,
116
+ wr as ERL_COOKIE_NAME,
117
+ Ot as KV_CLASSIC_LOAN_CARD_FRAGMENT,
118
+ St as KV_CLASSIC_LOAN_CARD_USER_FRAGMET,
119
+ Pt as KV_COMPACT_LOAN_CARD_FRAGMENT,
120
+ Gt as KV_COMPACT_LOAN_CARD_USER_FRAGMENT,
121
+ Dt as KV_INTRODUCTION_LOAN_CARD_FRAGMENT,
122
+ ht as KV_INTRODUCTION_LOAN_CARD_USER_FRAGMENT,
123
+ Bt as KV_LEND_CTA_FRAGMENT,
124
+ Ut as KV_LEND_CTA_USER_FRAGMENT,
125
+ bt as KV_LOAN_ACTIVITIES_FRAGMENT,
126
+ wt as KV_LOAN_BOOKMARK_FRAGMENT,
127
+ Oe as KV_LOAN_INFO_CARD_FRAGMENT,
128
+ Ht as KV_LOAN_TAG_FRAGMENT,
129
+ jt as KV_LOAN_USE_FRAGMENT,
130
+ Yt as KV_WIDE_LOAN_CARD_FRAGMENT,
131
+ Zt as KV_WIDE_LOAN_CARD_USER_FRAGMENT,
130
132
  r as KvAccordionItem,
131
133
  a as KvActivityRow,
132
- Jo as KvAtbModal,
133
- Lt as KvBlueskyIcon,
134
+ Xo as KvAtbModal,
135
+ Mt as KvBlueskyIcon,
134
136
  l as KvBorrowerImage,
135
- s as KvButton,
137
+ p as KvButton,
136
138
  d as KvCardFrame,
137
139
  x as KvCarousel,
138
140
  K as KvCartModal,
139
141
  A as KvCartPill,
140
142
  C as KvCheckbox,
141
143
  c as KvCheckoutReceipt,
142
- N as KvChip,
144
+ L as KvChip,
143
145
  E as KvClassicLoanCard,
144
- I as KvCommentsAdd,
145
- P as KvCommentsContainer,
146
+ O as KvCommentsAdd,
147
+ g as KvCommentsContainer,
146
148
  G as KvCommentsHeartButton,
147
- F as KvCommentsList,
148
- B as KvCommentsListItem,
149
- y as KvCommentsReplyButton,
149
+ D as KvCommentsList,
150
+ V as KvCommentsListItem,
151
+ U as KvCommentsReplyButton,
150
152
  M as KvCompactLoanCard,
151
- k as KvContentfulImg,
153
+ b as KvContentfulImg,
152
154
  w as KvCountdownTimer,
153
155
  H as KvDatePicker,
154
- z as KvExpandable,
155
- Z as KvExpandableQuestion,
156
- J as KvFlag,
157
- Y as KvGrid,
156
+ j as KvExpandable,
157
+ Y as KvExpandableQuestion,
158
+ q as KvFlag,
159
+ X as KvGrid,
158
160
  ee as KvIconButton,
159
- re as KvImpactDashboardHeader,
160
- ae as KvImpactVerticalSelector,
161
- le as KvInlineActivityCard,
162
- se as KvInlineActivityFeed,
163
- de as KvIntroductionLoanCard,
164
- xe as KvLendAmountButton,
165
- Ke as KvLendCta,
166
- Ae as KvLightbox,
167
- Ce as KvLineGraph,
168
- De as KvLoadingPlaceholder,
169
- be as KvLoadingSpinner,
170
- ce as KvLoanActivities,
171
- Ne as KvLoanBookmark,
172
- Ee as KvLoanCallouts,
173
- Oe as KvLoanInfoCard,
174
- Se as KvLoanProgressGroup,
175
- ge as KvLoanTag,
161
+ re as KvImageUpload,
162
+ ae as KvImpactDashboardHeader,
163
+ le as KvImpactVerticalSelector,
164
+ pe as KvInlineActivityCard,
165
+ de as KvInlineActivityFeed,
166
+ xe as KvIntroductionLoanCard,
167
+ Ke as KvLendAmountButton,
168
+ Ae as KvLendCta,
169
+ Ce as KvLightbox,
170
+ ce as KvLineGraph,
171
+ ye as KvLoadingPlaceholder,
172
+ ke as KvLoadingSpinner,
173
+ Le as KvLoanActivities,
174
+ Ee as KvLoanBookmark,
175
+ Me as KvLoanCallouts,
176
+ Se as KvLoanInfoCard,
177
+ Pe as KvLoanProgressGroup,
178
+ Fe as KvLoanTag,
176
179
  he as KvLoanTeamPick,
177
- Ve as KvLoanUse,
178
- Ue as KvMap,
179
- We as KvMaterialIcon,
180
- Qe as KvPageContainer,
181
- qe as KvPagination,
182
- Xe as KvPieChart,
183
- $e as KvPieChartV2,
184
- oo as KvPill,
185
- to as KvPopper,
186
- fo as KvProgressBar,
187
- mo as KvProgressCircle,
188
- po as KvPulsingDot,
189
- xo as KvRadio,
190
- Yo as KvSecondaryNav,
191
- Ko as KvSelect,
192
- Ao as KvSideSheet,
193
- je as KvSimpleMap,
194
- Co as KvSwitch,
195
- co as KvTab,
196
- No as KvTabPanel,
197
- Eo as KvTabs,
198
- Mo as KvTextInput,
199
- Io as KvTextLink,
200
- Po as KvThemeProvider,
201
- Go as KvToast,
202
- Fo as KvTooltip,
203
- Bo as KvTreeMapChart,
204
- yo as KvUserAvatar,
205
- ko as KvUtilityMenu,
206
- wo as KvVerticalCarousel,
207
- Ho as KvVotingCard,
208
- zo as KvVotingCardV2,
209
- Zo as KvWideLoanCard,
210
- er as KvWwwHeader,
211
- rr as KvWwwHeaderBasic,
212
- Sr as LOAN_CALLOUTS_FRAGMENT,
213
- Pr as LOAN_GEOCODE_FRAGMENT,
214
- gr as LOAN_PROGRESS_FRAGMENT,
215
- fr as Mash,
216
- yr as NO_BALANCE_CAMPAIGN,
217
- br as TOP_UP_CAMPAIGN,
218
- Kr as abc,
219
- zr as animationCoordinator,
220
- st as buildTailwindClassName,
221
- xr as carouselUtil,
222
- Nr as collapse,
223
- Qr as computeMapCenter,
224
- Zr as computeMapZoom,
225
- Cr as debounce,
226
- Tr as expand,
227
- qr as generateMapMarkers,
228
- Jr as getCoordinatesBetween,
229
- Xr as getCountryColor,
230
- kr as getDropdownPriceArray,
231
- Rr as getKivaImageUrl,
232
- Ur as getLendCtaSelectedOption,
233
- Yr as getLoansIntervals,
234
- _t as getTreemap,
235
- mr as groupBy,
236
- pt as headerNumberCase,
237
- vr as indexIn,
238
- wr as isBetween25And50,
239
- Mr as isLegacyPlaceholderAvatar,
240
- Wr as isLessThan25,
241
- vt as isTargetElement,
242
- dt as kebabCase,
243
- Gr as loanCardComputedProperties,
244
- hr as loanCardMethods,
245
- et as lockPrintSingleEl,
246
- tt as lockScroll,
247
- at as lockScrollSmallOnly,
248
- At as offBodyTouchstart,
249
- it as onBodyTouchstart,
250
- Or as randomizedUserAvatarClass,
251
- ut as removeObjectProperty,
252
- sr as sortBy,
253
- Ar as startsWith,
254
- nt as throttle,
255
- Hr as truncateStringByWords,
256
- ot as unlockPrintSingleEl,
257
- ft as unlockScroll,
258
- lt as unlockScrollSmallOnly,
259
- dr as useAttrs,
260
- cr as useEventListener
180
+ Be as KvLoanUse,
181
+ We as KvMap,
182
+ ze as KvMaterialIcon,
183
+ Ze as KvPageContainer,
184
+ Je as KvPagination,
185
+ $e as KvPieChart,
186
+ oo as KvPieChartV2,
187
+ to as KvPill,
188
+ fo as KvPopper,
189
+ mo as KvProgressBar,
190
+ so as KvProgressCircle,
191
+ xo as KvPulsingDot,
192
+ Ko as KvRadio,
193
+ er as KvSecondaryNav,
194
+ Ao as KvSelect,
195
+ Co as KvSideSheet,
196
+ Qe as KvSimpleMap,
197
+ co as KvSwitch,
198
+ Lo as KvTab,
199
+ Eo as KvTabPanel,
200
+ Mo as KvTabs,
201
+ Oo as KvTextInput,
202
+ go as KvTextLink,
203
+ Go as KvThemeProvider,
204
+ Do as KvToast,
205
+ Vo as KvTooltip,
206
+ Uo as KvTreeMapChart,
207
+ bo as KvUserAvatar,
208
+ wo as KvUtilityMenu,
209
+ Ho as KvVerticalCarousel,
210
+ jo as KvVotingCard,
211
+ Yo as KvVotingCardV2,
212
+ qo as KvWideLoanCard,
213
+ rr as KvWwwHeader,
214
+ ar as KvWwwHeaderBasic,
215
+ Dr as LOAN_CALLOUTS_FRAGMENT,
216
+ hr as LOAN_GEOCODE_FRAGMENT,
217
+ Vr as LOAN_PROGRESS_FRAGMENT,
218
+ mr as Mash,
219
+ Wr as NO_BALANCE_CAMPAIGN,
220
+ Hr as TOP_UP_CAMPAIGN,
221
+ Ar as abc,
222
+ Jr as animationCoordinator,
223
+ nt as buildTailwindClassName,
224
+ Kr as carouselUtil,
225
+ Er as collapse,
226
+ Xr as computeMapCenter,
227
+ $r as computeMapZoom,
228
+ Or as cropResizeImageToDataUrl,
229
+ cr as debounce,
230
+ Rr as expand,
231
+ et as generateMapMarkers,
232
+ ot as getCoordinatesBetween,
233
+ rt as getCountryColor,
234
+ zr as getDropdownPriceArray,
235
+ Sr as getKivaImageUrl,
236
+ jr as getLendCtaSelectedOption,
237
+ tt as getLoansIntervals,
238
+ Et as getTreemap,
239
+ sr as groupBy,
240
+ Kt as headerNumberCase,
241
+ ir as indexIn,
242
+ Qr as isBetween25And50,
243
+ gr as isLegacyPlaceholderAvatar,
244
+ Yr as isLessThan25,
245
+ ct as isTargetElement,
246
+ vt as kebabCase,
247
+ Br as loanCardComputedProperties,
248
+ Ur as loanCardMethods,
249
+ ft as lockPrintSingleEl,
250
+ pt as lockScroll,
251
+ st as lockScrollSmallOnly,
252
+ Tt as offBodyTouchstart,
253
+ Lt as onBodyTouchstart,
254
+ Pr as randomizedUserAvatarClass,
255
+ At as removeObjectProperty,
256
+ dr as sortBy,
257
+ Cr as startsWith,
258
+ Ct as throttle,
259
+ Zr as truncateStringByWords,
260
+ lt as unlockPrintSingleEl,
261
+ dt as unlockScroll,
262
+ ut as unlockScrollSmallOnly,
263
+ xr as useAttrs,
264
+ Lr as useEventListener,
265
+ Gr as validateImageFile
261
266
  };
@@ -9,3 +9,22 @@ export declare function getKivaImageUrl({ base, width, height, square, faceZoom,
9
9
  hash: string;
10
10
  format?: string;
11
11
  }): string;
12
+ export declare const DEFAULT_ACCEPTED_IMAGE_TYPES: string[];
13
+ export interface ImageFileValidationOptions {
14
+ maxSizeMb?: number;
15
+ acceptedFileTypes?: string[];
16
+ }
17
+ export interface ImageFileValidationError {
18
+ type: 'size' | 'format';
19
+ message: string;
20
+ }
21
+ export interface ImageFileValidationResult {
22
+ valid: boolean;
23
+ error?: ImageFileValidationError;
24
+ }
25
+ export declare function validateImageFile(file: File, { maxSizeMb, acceptedFileTypes, }?: ImageFileValidationOptions): ImageFileValidationResult;
26
+ export interface CropResizeOptions {
27
+ aspectRatio?: number;
28
+ maxDimension?: number;
29
+ }
30
+ export declare function cropResizeImageToDataUrl(file: File, { aspectRatio, maxDimension }?: CropResizeOptions): Promise<string>;
@@ -1,12 +1,12 @@
1
- import s from "./Alea.js";
2
- function $(o) {
3
- if (!o)
1
+ import b from "./Alea.js";
2
+ function p(a) {
3
+ if (!a)
4
4
  return !1;
5
- let t = o.toString();
5
+ let t = a.toString();
6
6
  return t.includes(".") && ([t] = t.split(".")), ["726677", "315726", "4d844ac2c0b77a8a522741b908ea5c32"].includes(t);
7
7
  }
8
- function w(o = "") {
9
- const t = s(o), r = [
8
+ function $(a = "") {
9
+ const t = b(a), e = [
10
10
  { color: "tw-text-action", bg: "tw-bg-brand-100" },
11
11
  { color: "tw-text-black", bg: "tw-bg-brand-100" },
12
12
  { color: "tw-text-white", bg: "tw-bg-action" },
@@ -14,27 +14,74 @@ function w(o = "") {
14
14
  { color: "tw-text-primary-inverse", bg: "tw-bg-action" },
15
15
  { color: "tw-text-white", bg: "tw-bg-black" },
16
16
  { color: "tw-text-action", bg: "tw-bg-black" }
17
- ], e = r[Math.floor(t() * r.length)];
18
- return `${e.color} ${e.bg}`;
17
+ ], n = e[Math.floor(t() * e.length)];
18
+ return `${n.color} ${n.bg}`;
19
19
  }
20
- function d({
21
- base: o = "/img/",
20
+ function h({
21
+ base: a = "/img/",
22
22
  width: t,
23
- height: r,
24
- square: e,
25
- faceZoom: l,
26
- hash: n,
27
- format: b = "jpg"
23
+ height: e,
24
+ square: n,
25
+ faceZoom: o,
26
+ hash: l,
27
+ format: r = "jpg"
28
28
  }) {
29
- if (!n || !t && !r && !e && !l)
29
+ if (!l || !t && !e && !n && !o)
30
30
  return "";
31
- let c = "", a = "";
32
- t && r && t === r ? e = t : (c = t ? `w${Math.ceil(t)}` : "", a = r ? `h${Math.ceil(r)}` : "");
33
- const i = e ? `s${Math.ceil(e)}` : "", g = l && (t || r || e) ? `fz${Math.ceil(l)}` : "";
34
- return `${o}${c}${a}${i}${g}/${n}.${b}`;
31
+ let c = "", s = "";
32
+ t && e && t === e ? n = t : (c = t ? `w${Math.ceil(t)}` : "", s = e ? `h${Math.ceil(e)}` : "");
33
+ const d = n ? `s${Math.ceil(n)}` : "", g = o && (t || e || n) ? `fz${Math.ceil(o)}` : "";
34
+ return `${a}${c}${s}${d}${g}/${l}.${r}`;
35
+ }
36
+ const m = ["image/png", "image/jpeg", "image/jpg", "image/gif"];
37
+ function v(a, {
38
+ maxSizeMb: t = 1,
39
+ acceptedFileTypes: e = m
40
+ } = {}) {
41
+ return a.size > t * 1024 * 1024 ? {
42
+ valid: !1,
43
+ error: { type: "size", message: `File size must be less than ${t}MB` }
44
+ } : e.includes(a.type) ? { valid: !0 } : {
45
+ valid: !1,
46
+ error: { type: "format", message: "File format not supported" }
47
+ };
48
+ }
49
+ function x(a, { aspectRatio: t = 1, maxDimension: e = 1e3 } = {}) {
50
+ return new Promise((n, o) => {
51
+ const l = new FileReader();
52
+ l.onerror = () => o(new Error("Failed to read file")), l.onload = () => {
53
+ const r = new Image();
54
+ r.onerror = () => o(new Error("Failed to read file")), r.onload = () => {
55
+ const c = r.naturalWidth / r.naturalHeight;
56
+ let s = 0, d = 0, g = r.naturalWidth, u = r.naturalHeight;
57
+ c > t ? (g = r.naturalHeight * t, s = (r.naturalWidth - g) / 2) : c < t && (u = r.naturalWidth / t, d = (r.naturalHeight - u) / 2);
58
+ const i = document.createElement("canvas");
59
+ i.width = e * 2, i.height = i.width / t;
60
+ const f = i.getContext("2d");
61
+ if (!f) {
62
+ o(new Error("Failed to process image"));
63
+ return;
64
+ }
65
+ f.drawImage(
66
+ r,
67
+ s,
68
+ d,
69
+ g,
70
+ u,
71
+ 0,
72
+ 0,
73
+ i.width,
74
+ i.height
75
+ ), n(i.toDataURL(a.type));
76
+ }, r.src = l.result;
77
+ }, l.readAsDataURL(a);
78
+ });
35
79
  }
36
80
  export {
37
- d as getKivaImageUrl,
38
- $ as isLegacyPlaceholderAvatar,
39
- w as randomizedUserAvatarClass
81
+ m as DEFAULT_ACCEPTED_IMAGE_TYPES,
82
+ x as cropResizeImageToDataUrl,
83
+ h as getKivaImageUrl,
84
+ p as isLegacyPlaceholderAvatar,
85
+ $ as randomizedUserAvatarClass,
86
+ v as validateImageFile
40
87
  };
@@ -0,0 +1 @@
1
+ .image-upload-icon[data-v-ea802cf6]{background-color:#ffffffbf;border-radius:9px;display:flex;align-items:center;justify-content:center;border-radius:.5rem}.image-upload-icon--circle[data-v-ea802cf6]{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1));--tw-shadow: 0 1px 4px 0 rgb(0 0 0 / .08);--tw-shadow-colored: 0 1px 4px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}
@@ -0,0 +1,72 @@
1
+ import p from "./KvImageUpload2.js";
2
+ import { resolveComponent as f, openBlock as i, createElementBlock as n, createElementVNode as a, normalizeClass as l, normalizeStyle as g, renderSlot as b, createVNode as c, withModifiers as w, createCommentVNode as m } from "vue";
3
+ import "./KvImageUpload.css";
4
+ import u from "../_virtual/_plugin-vue_export-helper.js";
5
+ const v = { class: "tw-flex tw-flex-col" }, h = ["src", "alt"], C = ["accept", "aria-label"];
6
+ function k(d, t, s, e, I, _) {
7
+ const r = f("kv-material-icon");
8
+ return i(), n("div", v, [
9
+ a("div", {
10
+ class: l(["kv-image-upload tw-relative", e.shapeClass]),
11
+ style: g(e.containerStyle)
12
+ }, [
13
+ e.previewImage ? (i(), n("img", {
14
+ key: 0,
15
+ src: e.previewImage,
16
+ alt: s.imageAlt,
17
+ class: l(["tw-w-full tw-h-full tw-object-cover", e.shapeClass])
18
+ }, null, 10, h)) : b(d.$slots, "fallback-image", { key: 1 }, () => [
19
+ a("div", {
20
+ class: l(["kv-image-upload__placeholder tw-w-full tw-h-full tw-bg-eco-green-1 tw-p-0.5", e.shapeClass])
21
+ }, [
22
+ a("div", {
23
+ class: l(["tw-flex tw-flex-col tw-items-center tw-justify-center tw-gap-0.5 tw-w-full tw-h-full tw-border-2 tw-border-dashed tw-border-black", e.shapeClass])
24
+ }, [
25
+ c(r, {
26
+ icon: e.mdiCameraPlusOutline,
27
+ class: "tw-w-3.5"
28
+ }, null, 8, ["icon"]),
29
+ t[3] || (t[3] = a("span", { class: "tw-text-label" }, " Add a photo ", -1))
30
+ ], 2)
31
+ ], 2)
32
+ ], !0),
33
+ a("input", {
34
+ ref: "fileInput",
35
+ type: "file",
36
+ accept: e.acceptAttr,
37
+ "aria-label": e.inputLabel,
38
+ class: "tw-absolute tw-inset-0 tw-w-full tw-h-full tw-opacity-0 tw-cursor-pointer",
39
+ onChange: t[0] || (t[0] = (...o) => e.handleFileChange && e.handleFileChange(...o))
40
+ }, null, 40, C),
41
+ e.previewImage || s.showEditIcon ? (i(), n("button", {
42
+ key: 2,
43
+ class: l(["image-upload-icon edit-icon tw-absolute tw-bottom-1 tw-right-1 tw-p-1 tw-z-10", { "image-upload-icon--circle": e.isCircle }]),
44
+ type: "button",
45
+ "aria-hidden": "true",
46
+ tabindex: "-1",
47
+ onClick: t[1] || (t[1] = w((...o) => e.openFileInput && e.openFileInput(...o), ["stop"]))
48
+ }, [
49
+ c(r, {
50
+ icon: e.mdiPencil,
51
+ class: "tw-w-2"
52
+ }, null, 8, ["icon"])
53
+ ], 2)) : m("", !0),
54
+ e.previewImage ? (i(), n("button", {
55
+ key: 3,
56
+ class: l(["image-upload-icon remove-icon tw-absolute tw-top-1 tw-right-1 tw-p-1 tw-z-10", { "image-upload-icon--circle": e.isCircle }]),
57
+ type: "button",
58
+ "aria-label": "Remove Image",
59
+ onClick: t[2] || (t[2] = w((...o) => e.removeImage && e.removeImage(...o), ["stop"]))
60
+ }, [
61
+ c(r, {
62
+ icon: e.mdiClose,
63
+ class: "tw-w-2"
64
+ }, null, 8, ["icon"])
65
+ ], 2)) : m("", !0)
66
+ ], 6)
67
+ ]);
68
+ }
69
+ const A = /* @__PURE__ */ u(p, [["render", k], ["__scopeId", "data-v-ea802cf6"]]);
70
+ export {
71
+ A as default
72
+ };
@@ -0,0 +1,150 @@
1
+ import { toRefs as S, ref as u, watch as x, computed as l } from "vue";
2
+ import { mdiPencil as F, mdiClose as w, mdiCameraPlusOutline as I } from "@mdi/js";
3
+ import C from "./KvMaterialIcon.js";
4
+ import { DEFAULT_ACCEPTED_IMAGE_TYPES as b, validateImageFile as R, cropResizeImageToDataUrl as T } from "../utils/imageUtils.js";
5
+ const U = {
6
+ components: {
7
+ KvMaterialIcon: C
8
+ },
9
+ props: {
10
+ /**
11
+ * URL of an initial image to preview.
12
+ */
13
+ imageUrl: {
14
+ type: String,
15
+ default: ""
16
+ },
17
+ /**
18
+ * Target crop aspect ratio (width / height). `1` = square, `4 / 3` ≈ 1.333.
19
+ */
20
+ aspectRatio: {
21
+ type: Number,
22
+ default: 1
23
+ },
24
+ /**
25
+ * Preview shape. `square (default), circle`
26
+ */
27
+ shape: {
28
+ type: String,
29
+ default: "square",
30
+ validator(e) {
31
+ return ["square", "circle"].includes(e);
32
+ }
33
+ },
34
+ /**
35
+ * Maximum allowed file size, in megabytes.
36
+ */
37
+ maxSizeMb: {
38
+ type: Number,
39
+ default: 1
40
+ },
41
+ /**
42
+ * Output resolution used when generating the preview.
43
+ */
44
+ maxDimension: {
45
+ type: Number,
46
+ default: 1e3
47
+ },
48
+ /**
49
+ * Maximum rendered preview size, in pixels (height; width follows aspectRatio).
50
+ * Note: the parent element must supply a width; this component sets only
51
+ * max-width/max-height + aspect-ratio and will not stretch to fill a sizeless container.
52
+ */
53
+ previewSize: {
54
+ type: Number,
55
+ default: 200
56
+ },
57
+ /**
58
+ * Accepted MIME types for both the file input and validation.
59
+ */
60
+ acceptedFileTypes: {
61
+ type: Array,
62
+ default: () => [...b]
63
+ },
64
+ /**
65
+ * Whether to show the edit (pencil) affordance in the blank state, before an image is
66
+ * selected. Off by default. Once an image is present the edit icon always shows
67
+ * (bottom-right, below the remove icon), regardless of this prop.
68
+ */
69
+ showEditIcon: {
70
+ type: Boolean,
71
+ default: !1
72
+ },
73
+ /**
74
+ * Alt text for the preview image.
75
+ */
76
+ imageAlt: {
77
+ type: String,
78
+ default: "Image preview"
79
+ }
80
+ },
81
+ emits: [
82
+ /**
83
+ * Emitted with `{ file }` when a valid file is selected or dropped.
84
+ */
85
+ "file-uploaded",
86
+ /**
87
+ * Emitted when the current image is removed.
88
+ */
89
+ "file-removed",
90
+ /**
91
+ * Emitted with `{ type, message }` when validation or processing fails.
92
+ */
93
+ "file-error"
94
+ ],
95
+ setup(e, { emit: r }) {
96
+ const { imageUrl: c } = S(e), a = u(c.value || ""), s = u(null);
97
+ x(c, (t) => {
98
+ a.value = t || "";
99
+ });
100
+ const m = l(() => e.shape === "circle"), d = l(() => m.value ? "tw-rounded-full" : "tw-rounded"), p = l(() => e.acceptedFileTypes.join(",")), f = l(() => a.value ? "Change image" : "Upload image"), g = l(() => ({
101
+ aspectRatio: String(e.aspectRatio),
102
+ maxHeight: `${e.previewSize}px`,
103
+ maxWidth: `${e.previewSize * e.aspectRatio}px`
104
+ })), v = () => {
105
+ var t;
106
+ (t = s.value) == null || t.click();
107
+ }, y = () => {
108
+ a.value = "", r("file-removed");
109
+ }, h = async (t) => {
110
+ const { valid: o, error: i } = R(t, {
111
+ maxSizeMb: e.maxSizeMb,
112
+ acceptedFileTypes: e.acceptedFileTypes
113
+ });
114
+ if (!o && i) {
115
+ r("file-error", i);
116
+ return;
117
+ }
118
+ try {
119
+ a.value = await T(t, {
120
+ aspectRatio: e.aspectRatio,
121
+ maxDimension: e.maxDimension
122
+ }), r("file-uploaded", { file: t });
123
+ } catch {
124
+ r("file-error", { type: "other", message: "Failed to read file" });
125
+ }
126
+ };
127
+ return {
128
+ mdiPencil: F,
129
+ mdiClose: w,
130
+ mdiCameraPlusOutline: I,
131
+ fileInput: s,
132
+ previewImage: a,
133
+ isCircle: m,
134
+ shapeClass: d,
135
+ acceptAttr: p,
136
+ inputLabel: f,
137
+ containerStyle: g,
138
+ openFileInput: v,
139
+ removeImage: y,
140
+ handleFileChange: (t) => {
141
+ var n;
142
+ const o = t.target, i = (n = o.files) == null ? void 0 : n[0];
143
+ i && (h(i), o.value = "");
144
+ }
145
+ };
146
+ }
147
+ };
148
+ export {
149
+ U as default
150
+ };
@@ -115,8 +115,8 @@ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropT
115
115
  }>> & Readonly<{}>, {
116
116
  values: KvPieChartV2Item[];
117
117
  loading: boolean;
118
- initialDelay: number;
119
118
  strokeWidth: number;
119
+ initialDelay: number;
120
120
  unit: PieChartUnit;
121
121
  shownSegments: number;
122
122
  segmentGap: number;
@@ -27,6 +27,7 @@ export { default as KvExpandableQuestion } from './KvExpandableQuestion.vue';
27
27
  export { default as KvFlag } from './KvFlag.vue';
28
28
  export { default as KvGrid } from './KvGrid.vue';
29
29
  export { default as KvIconButton } from './KvIconButton.vue';
30
+ export { default as KvImageUpload } from './KvImageUpload.vue';
30
31
  export { default as KvImpactDashboardHeader } from './KvImpactDashboardHeader.vue';
31
32
  export { default as KvImpactVerticalSelector } from './KvImpactVerticalSelector.vue';
32
33
  export { default as KvInlineActivityCard } from './KvInlineActivityCard.vue';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kiva/kv-components",
3
- "version": "8.17.1",
3
+ "version": "8.18.0",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -128,5 +128,5 @@
128
128
  "dependencies": {
129
129
  "fuse.js": "^7.1.0"
130
130
  },
131
- "gitHead": "b717eef77a82336fd6df9908773911555f431a71"
131
+ "gitHead": "34c0c8109e5d079a5d08fedda139c2ecee8fdc8e"
132
132
  }