From 10c3898e58c8c0305844c8d4638b280866aeac9b Mon Sep 17 00:00:00 2001 From: Jukka Kurkela Date: Sun, 14 Mar 2021 14:45:49 +0200 Subject: [PATCH 1/2] Add option to turn off grouping of bar datasets --- docs/docs/charts/bar.mdx | 1 + src/controllers/controller.bar.js | 55 ++++--- .../controller.bar/not-grouped/on-time.js | 134 ++++++++++++++++++ .../controller.bar/not-grouped/on-time.png | Bin 0 -> 21723 bytes 4 files changed, 167 insertions(+), 23 deletions(-) create mode 100644 test/fixtures/controller.bar/not-grouped/on-time.js create mode 100644 test/fixtures/controller.bar/not-grouped/on-time.png diff --git a/docs/docs/charts/bar.mdx b/docs/docs/charts/bar.mdx index 555fe38e544..d3123a21fff 100644 --- a/docs/docs/charts/bar.mdx +++ b/docs/docs/charts/bar.mdx @@ -173,6 +173,7 @@ The bar chart accepts the following configuration from the associated dataset op | `categoryPercentage` | `number` | `0.8` | Percent (0-1) of the available width each category should be within the sample width. [more...](#barpercentage-vs-categorypercentage) | `barThickness` | `number`\|`string` | | Manually set width of each bar in pixels. If set to `'flex'`, it computes "optimal" sample widths that globally arrange bars side by side. If not set (default), bars are equally sized based on the smallest interval. [more...](#barthickness) | `base` | `number` | | Base value for the bar in data units along the value axis. If not set, defaults to the value axis base value. +| `grouped` | `boolean` | `true` | Should the bars be grouped on index axis. When `true`, all the datasets at same index value will be placed next to each other centering on that index value. When `false`, each bar is placed on its actual index-axis value. | `maxBarThickness` | `number` | | Set this to ensure that bars are not sized thicker than this. | `minBarLength` | `number` | | Set this to ensure that bars have a minimum length in pixels. diff --git a/src/controllers/controller.bar.js b/src/controllers/controller.bar.js index 54be96a96a5..0d4176f279a 100644 --- a/src/controllers/controller.bar.js +++ b/src/controllers/controller.bar.js @@ -255,9 +255,9 @@ export default class BarController extends DatasetController { updateElements(bars, start, count, mode) { const me = this; const reset = mode === 'reset'; - const vscale = me._cachedMeta.vScale; - const base = vscale.getBasePixel(); - const horizontal = vscale.isHorizontal(); + const vScale = me._cachedMeta.vScale; + const base = vScale.getBasePixel(); + const horizontal = vScale.isHorizontal(); const ruler = me._getRuler(); const firstOpts = me.resolveDataElementOptions(start, mode); const sharedOptions = me.getSharedOptions(firstOpts); @@ -266,14 +266,14 @@ export default class BarController extends DatasetController { me.updateSharedOptions(sharedOptions, mode, firstOpts); for (let i = start; i < start + count; i++) { - const vpixels = me._calculateBarValuePixels(i); + const vpixels = reset ? {base, head: base} : me._calculateBarValuePixels(i); const ipixels = me._calculateBarIndexPixels(i, ruler); const properties = { horizontal, - base: reset ? base : vpixels.base, - x: horizontal ? reset ? base : vpixels.head : ipixels.center, - y: horizontal ? ipixels.center : reset ? base : vpixels.head, + base: vpixels.base, + x: horizontal ? vpixels.head : ipixels.center, + y: horizontal ? ipixels.center : vpixels.head, height: horizontal ? ipixels.size : undefined, width: horizontal ? undefined : ipixels.size }; @@ -370,6 +370,7 @@ export default class BarController extends DatasetController { */ _getRuler() { const me = this; + const opts = me.options; const meta = me._cachedMeta; const iScale = meta.iScale; const pixels = []; @@ -379,11 +380,8 @@ export default class BarController extends DatasetController { pixels.push(iScale.getPixelForValue(me.getParsed(i)[iScale.axis], i)); } - // Note: a potential optimization would be to skip computing this - // only if the barThickness option is defined - // Since a scriptable option may return null or undefined that - // means the option would have to be of type number - const min = computeMinSampleSize(iScale); + const barThickness = opts.barThickness; + const min = barThickness || computeMinSampleSize(iScale); return { min, @@ -391,7 +389,10 @@ export default class BarController extends DatasetController { start: iScale._startPixel, end: iScale._endPixel, stackCount: me._getStackCount(), - scale: iScale + scale: iScale, + grouped: opts.grouped, + // bar thickness ratio used for non-grouped bars + ratio: barThickness ? 1 : opts.categoryPercentage * opts.barPercentage }; } @@ -459,17 +460,24 @@ export default class BarController extends DatasetController { */ _calculateBarIndexPixels(index, ruler) { const me = this; + const scale = ruler.scale; const options = me.options; - const stackCount = options.skipNull ? me._getStackCount(index) : ruler.stackCount; - const range = options.barThickness === 'flex' - ? computeFlexCategoryTraits(index, ruler, options, stackCount) - : computeFitCategoryTraits(index, ruler, options, stackCount); - - const stackIndex = me._getStackIndex(me.index, me._cachedMeta.stack); - const center = range.start + (range.chunk * stackIndex) + (range.chunk / 2); - const size = Math.min( - valueOrDefault(options.maxBarThickness, Infinity), - range.chunk * range.ratio); + const maxBarThickness = valueOrDefault(options.maxBarThickness, Infinity); + let center, size; + if (ruler.grouped) { + const stackCount = options.skipNull ? me._getStackCount(index) : ruler.stackCount; + const range = options.barThickness === 'flex' + ? computeFlexCategoryTraits(index, ruler, options, stackCount) + : computeFitCategoryTraits(index, ruler, options, stackCount); + + const stackIndex = me._getStackIndex(me.index, me._cachedMeta.stack); + center = range.start + (range.chunk * stackIndex) + (range.chunk / 2); + size = Math.min(maxBarThickness, range.chunk * range.ratio); + } else { + // For non-grouped bar charts, exact pixel values are used + center = scale.getPixelForValue(me.getParsed(index)[scale.axis], index); + size = Math.min(maxBarThickness, ruler.min * ruler.ratio); + } return { base: center - size / 2, @@ -512,6 +520,7 @@ BarController.defaults = { categoryPercentage: 0.8, barPercentage: 0.9, + grouped: true, animations: { numbers: { diff --git a/test/fixtures/controller.bar/not-grouped/on-time.js b/test/fixtures/controller.bar/not-grouped/on-time.js new file mode 100644 index 00000000000..1795e1677d1 --- /dev/null +++ b/test/fixtures/controller.bar/not-grouped/on-time.js @@ -0,0 +1,134 @@ +const data1 = [ + { + x: '2017-11-02T20:30:00.000Z', + y: 27 + }, + { + x: '2017-11-03T20:53:00.000Z', + y: 30 + }, + { + x: '2017-11-06T05:46:00.000Z', + y: 19 + }, + { + x: '2017-11-06T21:03:00.000Z', + y: 28 + }, + { + x: '2017-11-07T20:49:00.000Z', + y: 29 + }, + { + x: '2017-11-08T21:52:00.000Z', + y: 33 + } +]; + +const data2 = [ + { + x: '2017-11-03T13:07:00.000Z', + y: 45 + }, + { + x: '2017-11-04T04:50:00.000Z', + y: 40 + }, + { + x: '2017-11-06T12:48:00.000Z', + y: 38 + }, + { + x: '2017-11-07T12:28:00.000Z', + y: 42 + }, + { + x: '2017-11-08T12:45:00.000Z', + y: 51 + }, + { + x: '2017-11-09T05:23:00.000Z', + y: 57 + } +]; + +const data3 = [ + { + x: '2017-11-03T16:30:00.000Z', + y: 32 + }, + { + x: '2017-11-04T11:50:00.000Z', + y: 34 + }, + { + x: '2017-11-06T18:30:00.000Z', + y: 28 + }, + { + x: '2017-11-07T15:51:00.000Z', + y: 31 + }, + { + x: '2017-11-08T17:27:00.000Z', + y: 36 + }, + { + x: '2017-11-09T06:53:00.000Z', + y: 31 + } +]; + +module.exports = { + description: 'https://github.com/chartjs/Chart.js/issues/5139', + config: { + type: 'bar', + data: { + datasets: [ + { + data: data1, + backgroundColor: 'rgb(0,0,255)', + }, + { + data: data2, + backgroundColor: 'rgb(255,0,0)', + }, + { + data: data3, + backgroundColor: 'rgb(0,255,0)', + }, + ] + }, + options: { + barThickness: 10, + grouped: false, + scales: { + x: { + bounds: 'ticks', + type: 'time', + offset: false, + position: 'bottom', + display: true, + time: { + isoWeekday: true, + unit: 'day' + }, + grid: { + offset: false + } + }, + y: { + beginAtZero: true, + display: false + } + }, + } + }, + options: { + spriteText: true, + canvas: { + width: 1000, + height: 300 + } + } +}; diff --git a/test/fixtures/controller.bar/not-grouped/on-time.png b/test/fixtures/controller.bar/not-grouped/on-time.png new file mode 100644 index 0000000000000000000000000000000000000000..034edc0c402cec18ecfb64fb0267c4bc5ae8220e GIT binary patch literal 21723 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 literal 0 HcmV?d00001 From 927386bc867e838a2019c300d8b898c8c5eeac18 Mon Sep 17 00:00:00 2001 From: Jukka Kurkela Date: Sun, 14 Mar 2021 15:08:02 +0200 Subject: [PATCH 2/2] Disregard time offset --- .../controller.bar/not-grouped/on-time.js | 36 +++++++++--------- .../controller.bar/not-grouped/on-time.png | Bin 21723 -> 17240 bytes 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/test/fixtures/controller.bar/not-grouped/on-time.js b/test/fixtures/controller.bar/not-grouped/on-time.js index 1795e1677d1..6c2d44cbb08 100644 --- a/test/fixtures/controller.bar/not-grouped/on-time.js +++ b/test/fixtures/controller.bar/not-grouped/on-time.js @@ -1,80 +1,80 @@ const data1 = [ { - x: '2017-11-02T20:30:00.000Z', + x: '2017-11-02T20:30:00', y: 27 }, { - x: '2017-11-03T20:53:00.000Z', + x: '2017-11-03T20:53:00', y: 30 }, { - x: '2017-11-06T05:46:00.000Z', + x: '2017-11-06T05:46:00', y: 19 }, { - x: '2017-11-06T21:03:00.000Z', + x: '2017-11-06T21:03:00', y: 28 }, { - x: '2017-11-07T20:49:00.000Z', + x: '2017-11-07T20:49:00', y: 29 }, { - x: '2017-11-08T21:52:00.000Z', + x: '2017-11-08T21:52:00', y: 33 } ]; const data2 = [ { - x: '2017-11-03T13:07:00.000Z', + x: '2017-11-03T13:07:00', y: 45 }, { - x: '2017-11-04T04:50:00.000Z', + x: '2017-11-04T04:50:00', y: 40 }, { - x: '2017-11-06T12:48:00.000Z', + x: '2017-11-06T12:48:00', y: 38 }, { - x: '2017-11-07T12:28:00.000Z', + x: '2017-11-07T12:28:00', y: 42 }, { - x: '2017-11-08T12:45:00.000Z', + x: '2017-11-08T12:45:00', y: 51 }, { - x: '2017-11-09T05:23:00.000Z', + x: '2017-11-09T05:23:00', y: 57 } ]; const data3 = [ { - x: '2017-11-03T16:30:00.000Z', + x: '2017-11-03T16:30:00', y: 32 }, { - x: '2017-11-04T11:50:00.000Z', + x: '2017-11-04T11:50:00', y: 34 }, { - x: '2017-11-06T18:30:00.000Z', + x: '2017-11-06T18:30:00', y: 28 }, { - x: '2017-11-07T15:51:00.000Z', + x: '2017-11-07T15:51:00', y: 31 }, { - x: '2017-11-08T17:27:00.000Z', + x: '2017-11-08T17:27:00', y: 36 }, { - x: '2017-11-09T06:53:00.000Z', + x: '2017-11-09T06:53:00', y: 31 } ]; diff --git a/test/fixtures/controller.bar/not-grouped/on-time.png b/test/fixtures/controller.bar/not-grouped/on-time.png index 034edc0c402cec18ecfb64fb0267c4bc5ae8220e..92506bd3ae7b05f5d7f791ed195efbe3c361ccd3 100644 GIT binary patch literal 17240 zcmeHvd03Ozw!Q@_I3Nyftx!l&5qkt_6~uy&C{{!SR7460SS=z12+9x*hRCr>IVvbJ zD2R!IARSNx3s$Gq%JVgBHs61^+1ROehmLS|SlgcaxDeBqJJEIx zn=N;RInlJegtcZbW^Oq@bKdNkaTKFi%T<=8*JJ!8q$-? z9+ff*slIPtUS_v-#q895=jt~%_K7X<`;s2NbM^F%>1D)P{m*Z_efIygVM^>u-BL1g zP0F($hCPX&oI2z$5Tsduz3qS(x4q4*bmAOQu^)L!)&Gf| zT8tpQtQ;%&W#zeG;sIY~d#j~*;>`3*t#Iyhj`#ca?K_J6;QI$PQ{z~M;orNZ3wVsn z<>h_z&NlvGj5jYalG-lLdv{xdj_VT?l&NQ$|Guy{Yh21AepnK0*#EX&a@_Ch*Ky(5 zUF^0E#`p;j^*`HZhv7Vv^4mY|?rv@I*Z%oW5M)$n7Gp3k#z6ahm`r)d&>*bWAeg@o z z*_~{0qF3ys^;S6l4v{HcrO)n4jYwa9(GKbHWf^hNgI|U8@8@GgGmV*N{Fag-`_yc{ zP_xl}!@9-2rADkCjXxhm!|KYuUvS&Ov{32 zg|EN=Z@btoT%L*Eo-uOK+H%=#>l1Qf(OHa6+3@!$R6EAgHC!!{E(z_2Sqb3D^I_Kq$6?Z zd%#zzt7c>Ml*4(r9E4S{C`N$#qr6Thbqi>wgFvui1<*k_S?fI*{ll~!De}z}x&0rt z6qrkcV4*<>Pb@Ewa{xNx7{3q7dB7GIyEsnU5uLVOz*8>xqgo@R=A#{BkkKm$*^e-U zB9MM)ywGlGgrK?I1ewkNdw)-5X_!|1m$Btb_Tj#zEBRUjzJ&YTg}biK>xyqH%Ov z=_!n4)xTdh=6o4b5VS9QIBj9QgY{_np3`q6EH{XffJ#?zodx&Nf}e|w9=~zM|Cr4= zm>64nZ^AgbBaU0Lrc0Rar$N~2r>^LdTMYlp!@zC5?sfu@QhSHdiKL6mEG|j68XU;F$N2Nt83mvymLR6;kGHmBw0G68#!-+ z{ClPIKf`8hBS6lPrzo^DRhr(pO*z?B`EXVj4m99@Kme47LQ@6+!=tD%b>sh+S}1vg ziRhbqC5Grw#JB!4i5u35F_`_&wMRLhcWwTMhrHuJKg8r8J<5lee2B@s{|-Kh9ASWx zgtf%m*lnR$Lo@e}{7cdj?a=y7cZ<{|EdnFb?OBT-3GoZnI7aV!ak(8OcGGWl!{=(1 zlk<6}=f7jd+fiyZpZxBh=JOuKVl01p*Nwl6^wStKTMfG5yA_H!7Nc|O_lie@Flxxs zHhiZEV2!;XicI{__eoUbO$W z&jL(W;U9SC1MhtBILN0G{`1N8Zvd=`L%~wRhi+3 zC$hq@Df&_dsy}}?r-R+$jhdYMY~D&zsVZzo**WgL!c{)BM;?)fFSi9prerXx>c>6T zWj7D0$Q|E!E0~rBSO4b1)Rz=$>hBO#r_rM6nN0G@yTd2epbILJ{d(%gj)*gMp`*7y zWr$Qt22E%pNsExGLarYbJiUA0FOq0l^SDA-efeU>&cK{U9Zv@Ri4(rh_ylgDw<7Ja z_<7ykrkbFNpyd8^vHFwueKZ9=UG%@}BSriQqEY^t*Bt@efz4afcD#%rw{*xYgWA8A z+f7ww5O0$P2ivL^ImnaS#jp8CN!5}Faj@?&yr<`&liV(OTG!1y{Oa*B)Jq|M_&^JO zVyGuB>%LJb@t}1#ca)exWH0en5RNX(Es9D-pRtZoWjm!SMTW}mI@{K3$X}KYR4ioM z7U~OylZ-kBKV$mp0n)Z%`4)d64vUQ%e=`qyLA1^7RfT?^xcGBp4h=u#Bz`$yY~&;E zV2>)}g+s$^pN1A{ta0MJm4*CgZzq}>0rNSRm1`uZuu}fK;g)xFOt#I0AO8E*kPVz#pE!Uca7;o>4 z!NEb%a8Z4!N?Xd_6!q$yrFrCVyEuWwB}#}RhCAc3$Y+uz`Vobftqmotma>bOo6&E*3pUe~1N6%;rlSLZGE zIl3`1iOD~2H}68^4hmD+mu@wXb#biTZ~^bWLmEL))_)7GrF9eXboKO%9Hea6ofRL? z6}9BK*Q1AS7j=^M){!N)&~rSWWvH#KeJd}o>2S4vPO1;V0eNtetMdglO<9@+);ze= zJmc`=B~~N9s83{~6kBmjMd@aWrtv`8f%tEcwGbwIVp|#;mpVM-mj3v3;aB@8lA$(S zKy{SY_%SWfiRIqmu>4$@&ay3MS$F+vmcw*bSBiGQg_iKMVf^`8`sB+qZm{H6322|S z2cJJtSw`TecP_9KhC_m3Og_FVKR-V)Ybw~u$!XUM3<(*P>Wgk^Ya6;2YtRS_9Fr{I zu^l?gh+aeS)`IrIuwJxtQV3VlooiAf%EuA&#JC-$>d|U1QOX`v@lZke;G@O9&1cLQ zH*JZsVpO zft7k6?Kx%j>g?L$(4I|k7@cj6A5kmCX?IOrxeTJk!RMbNo2!s;eLFvjVMHqkHe*kg z4K`%jE5BW?X0zVG)y0}`?&p#HL)GbkhU@tBRU~%OSFTwnVw8=JX0>SL zpX_$vKqhSCILYHnmU^OjuY{?pgi)B$itzDTOGlWYKECVlu3s>?fB+BCNRyvioiqM|AcG*dQ#H>u#cz7n`yb6lW+)LHxr4z4270D(+x*GIJ?b;( zvTp9o6tyvxZcAAw6T=&_94;pLU7ojL1ml!uJ`IltbIg(ev92yQEunSa_Vb>vt#7{m z-I;JsMBBj4%=kvpK$8)&Mkjy=->VN@mcry$l2__{#*=VKq$Zyz{taY9*ZS8r+scPC zzjDp)RdpG$XcvpaGSo3OmRy!-)i zScPmN5Q}YsRW=v-yKo}e!Ehv!6sTrXvxZOOMiY8YEsi`&p?a2VgMdWx`_F5MULa44 z5;s4LTh!9tey>W6Sa;>y@dT^Em7Jrm&Pl1aTbHubcR5k;L#<9HXKKS1Ru)&ODN5RW zyuu%S>dtFFkl=>J=B*3qx(PXmef9Vp40$C`t6wfdZ1ju}Z> zBWofnvr0?XA;7YT>8^~zXGF^eJWGQ*=FJg}zN)qq4YoKg-WwXT4%dC#ck1P0fL82k z#^ipu!5MDIb2qEKyw)Ca1{RKI2h$)jA~73BBV84eRB}&dbme9W&N851oWGnX%0#s! zyZe;2^iK-#%shx;XXmZf);$1EVYH-Nddzmx`s*K`oEMY*+FSAao+W)H8+2#hqSNW( zvD9uw$BkKwR(!(X|1@in?TDk+*rm_c{J6D0cC*o~St6xE4t!JBc-y0>bP3Nf#iXIV z@IVBtcnD(DvWi-<)ZrGDN+z~?_`hb(UhP1b8m+bfm9j85uMi41`qIO5ozaSLB+Ye5 zlP7_BZlqy^oO0S}ZN2Po4m=K8%kuK{3`dZjbOFRzph=B+~D#yQrX z!B<~rVKFe6M{QkT|3#r21=oIO<9J_fleT3Sh9cYt^E|0z`+fh_sDjT-J&S8GWHgDf z<(%#fWcG5dilOW$DeV)(pBTnIX98ETnLl|FB-JC!5;p8wwdeLq4H@9ZRwYylgrY}g z(L2e~=l;z-!e!Ht5EfP&=-M8?7s8PC1<#b-a?1;^*2f=ua^6sPeJDj&w_72R3^e7K zS&3M76ThhI6yxq4mmcws?C`VdzY;b(Mk#7?F@sC@DGytxaUPk)TEleBj`z%=zxeB% z;{A{Q1`h>Vx`vA$PnY!?qjSAN%8XPCJtu&L2Vhq_l%G2sLjBl?LcVg)S+3Dt? zFE9!~)x|eSRQ*NR*)8#3w00&NRGViD@@BRNrUITD{&8J)BP)$uL#h@n#17v%yvwuf3|(o|3` zNK>g$Q~H-S96KVfUlTs{0wJ4_a(*^fDW;{Z3r>Tqx2(PLt!rX9FxXAJu$!-1h7AhZ zE$pt0fOmq%t@@`2ui0o%-#DT^ey5H>o zX?6MV8YCoE0QPX{>r||C?6t0CNZ0Vmc~)B&t=P^2xE6 zQ7kI@d*8_ii>IU1MpC#djMdsQ6Ra%&TX3n3jx%RA}^L4H|Rz6}c> zF03AWwu<_kxdA?F2MCL1ZPXl~4;3^~Hl7S`^TvOwrhw(OCXl8M=pXC7koL`i(<^}a zk+hognF;H!AJ6$LBlN*6U90e$Y3b=LKuVA(Ll?$csLF zx2D-}*dISy(-R-4rl>|M3z2YWqK@y-G&s7?kkwzCo`dWMGDmZwESx9^BR6H>yK^nD zt-R}JR(r}u6G(f(4s})>D{8&%ky%etjw7iHw0*A@gR%^{0-!dt0d3|p@q07~J0KIU z*~JEmcnwwxQBy>%McXH83ZU;Zk0G`)89@PvX}~k(-Uxr4TI|E>eR@$Z-d1+VJM{j? zfdK&xkI(5%6pqT2} zVZs2CpUs9W5^%o7gn;8!zhV5WQqEL)LHb4U`wbBl9+$6E#a)gkXBIJ6Pw2N72e?k> z(7wgM8+(`=RNbi^hXh?^&+cxQbcH1>9{`x`Oz}&z#tYUl)f>yv>J1=2=k%>h6{r=~ zK{qx7*l-N#LC%pH)9C~O`d_T3xUY$7-l(acMN+hp5OG}1oI0YdYreJUU~S`gJsK@X zbOXpc2Zr5=;31Vc845sJJk2^tnb65JS0GS9QXoBq z?f^_&cby$l?nG7$`&)$dZC3!fwjhH0aDhD!&>UvS%5l!1-}It|SV8VgOpVtgUYP}3 zaoZk6+zo~gmS*<-9n3QO_~wrn@1+0{=gsG#r+RcsKpv5ZAQAi_RzJJR1?>&u$AaIL z#Uzzd7ad*E9W4)bBHMb)`84thr!+7yrTJ>amRoLCQzKOtum$FS7+@a4Q<}-B+Zs(ArJ*gFA ze_LJFyHFctyZ4O_H{Nj6+mc|A57yKT5?R(QVdOxD_W3p(#V=-lA-K7M#U%`xLKLyR zPcC%&rFzefu?=iq$-i5(+Os6kO`e+FkM0?RNmxwq+3xu6V>yUti!~r@E$5e}gT!*T z>Z=ifA)OGG?2Z!VV++c*^k?9&5+(+}qi8OTaN@Q`cdsFN4_bejtMFf96@6zaxCB+< zPW4I5f(2jp<(e1yEI zyDsRG0fA?jdr|egv#&Ni0%Qpg<}+m=(#OCW_?;zms4>~X00SOUxWN2d44S0ewflaV z;ovEi4NK@iO7YRmRR&ZlXb)^_gdV-T=qt@|y1u zTh(BX$`9etf!?7q*i8%JbTXF@6*oD%)?c-m;AJKR!bRg$hAfaMt?>n-EfSqXO<{ax zjj87TbzcmqE7xMB35$e^jr%nS7zhI*M7YX{6p(eRiQ$f-`Me_k`aSS4HY5O24uSk< zFLGYL5uoLPlw-sJN8d*9KDnTY+l({96A?^IgV9EHFWnN?3YBJofKxv7aFI*W8)I_j zGt)-o-H+5~7IQfpSj>@AW=Nj!Ni%v8xL>u2Lg>a7iydmbu*`lCahqZFHaXz*cUPlG z6)CH|{}TL4LP0~?%F>xqJx*wqHUWSU_$$_#5Xq9Dj=N%#?=$X-+#X=F8w3&Wf~o|` z6qw93BJcV+Rzdj`@nDuQ&mJwiU_cb@%sBco4smKFel;l|vmn6QvHFqU%Y_?N393n* z30{L;>fR%9;Ei+AFu0(gW-3X6<%8|y+azhqKo?x)ZBXH3b%tuwEiDl#>b>aF3d~bL zCGxSLt~|M7)`-(k8`T{OsaCKVL~(~bu+^Thu%b6rf+Uz<&71s&E2KJ-G{?w(yvh4x zzL)b9FG`pX(Z|Mqgk5p9>^_=F5D({q2;s(A=gyrQWYegp=PtRP>Kk453a|B1t{tLo z9<;6_XKbZUT|l>x7(ik9%O;9S!Br8JQCSDgd@8<2oQyM+$NHdhNN-@A-)+enPiSJ2 zND3%C617AWkT6hT-%c_`@B*!1kH~H754er(3$%>qjK5rt_BSA9-R(AH0<(g0*}HRW{g-P-WEBS)vm# zMRsQ=0!MvNcF+f;qyvaCV2bkgYV(k;^$wm%u?mFUU>_5v3jo-eZTiad_Z~s(=NSoW zr#u{JTR&Vtw3yl%i@^c)KDn@r&D_3DM+C*sp#&Q-6dw-88Cl@doDx%P!I}(mnaqNF zFJ}`6UCE7LtzK==DxEDNtET#q7(grFmbTuyW(ItYADFBXj3U(4P5$7Cz`$R%@lw~E zXQCmSc6!heN^HIp)UgH;U3-ILS%?jRG&5AWjc%g&f@#<0l;h2gUrDQn?@2Lql{aC7 zJBuAACMNjkV`-W)m@Afa!wb3qR?y`siR61a1j;~?@)M#(nX(=o(oIB$A>)z}Hd<4ehFJfrq$WX+3N?EtY1QSExRft70Fah-bn^(rv4Nqu!0 zd5|bWy5Ao8QK|W;wvJ>`0o6ECM??AHneRn&9-QB+1Lzz^oWx^2T=N{W3JP)y-&fa6 z&1PkUR=5M7`8S{O(qvOpQ}DIr#fWPFXGG||U@t06AeyKY7ON1PLJD{Q%#gz5mJ95R z6!rCPEfFwMvXu19A1EHY6j|1sGsc}myN&hLCINVi0=g@XS%J-%6QcwkJ@n$27<$iX zJ#$bBZG#QpyL(5tA@ipoCje#2oP(rPH4e^QywY|81GGgFH zYF{A+gcpg)G@pXHZ<=m&fEmw-U;k38HpAMT#)(XyXFK^~%5mtkl9G}DAZX;_P>?Rx zCyE-R%&#GHkuY3`KE%+^%iuL^&;r^) z^{GVcU%p4tmcjWvaFU1CBfbON6q3$uz9bvc)~*C|LIk0x;Hc}V*dqz!2RPQ;?8HiFWm zXo>hM_+5Tx&GZjHT);>5SE7QzITxS9 zP!(>X4b!~(`0*A_w44vEnYN!7EJK=#{i=nuU5R_BKKXDg5CG3>CP7!Ej~z0OE?N;h z!Szf99sTVY&}xIC%EbG~QzPUVlcTRDU}k-IJY)HEnGC&-h^I!WJlL{YiK&L{S@NoW zZbX|m;u9m9ciIO`O^y;?C%ca&*a2RHH3)p__5PS{Xz(G7|KO)t$WtvDquR*Rq#W<% z4pgR+4l2(v=n@8dX^EihG4W&^FJp{n2yf!J46ETgRp!UWdZ) zjSi&pI#X}@?zX*Q=LUy{CR|h^m$bG1&Pw4X?Z$G_AhdGHT$mcav<03pb?P~DGb8eJi+xqm@IW#g=a%P?j*%s-m zAce~V`H`9wQ>^TjliTQa5-9i(v zo_Xu~IHsQDcN-Lbd=HL&?{FqkV0U$ODPyb|%)-KbN56`Le-xmJ{9k~>>B6DO!`8ML z1`Ct7%ASJPYHn};e)292hPj!W`xS{DG{6b~4OP~IXx z0>6ObkQ@XPDwsTs91ZBRU_&22emvz~XjCaTnk=<)-hM1I+E_<)$4ph==>xBm$9nT=cLsU9RN1sDiQnLz< zFPfpR+5(g;n3`fHR35BNi$}o+0=G7v2PbZ^Ze1Ul4O=9uo@e8$xClYIeW_^^I>$X z>QTjrGCMmvUUE1O!)@)4nm%DUGe)Wp4hRS!U9b%9%z`?;ABTM+?1QQeB7Pe>VV&jd z^IS%sGB^TSQ+eRf9;BCAtie){0`jGXoRDYSg zs)Ce<5%#j{-W;6OC%4n4Z^r={h;5OrMb6jaFDQQKX1Y=EW5I7u*n$;N4{5JYGMxN{ zLXm`m$3PDcPS5T?#P2f}q-ZSQg~Va-P8xKtr7Umwl30pXcpIFt?b=_nGF+_RZkpnc zT;))?twKO7{q;DH-!XkUNdK-lSU5fHV#m#LF>m^8le4TdvTgd!X6x(3a^%b~F3Vs+ zaJeILxRlf$lEY`WP)}(Zm7aY$FxWN={vXDBe&*+>P(wkQ_aFXn(-ir$!*|Y`3pVZh G>wf@`++q0u literal 21723 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