PDA

View Full Version : [SOLVED:] VBA code to speed up and automate multiple account, multiple site stock movements



cfo20code
12-04-2020, 11:21 AM
MVPs

I need help with vba code to speed up and automate multiple account, multiple site stock movements. The current file has formula and due to the large size of the data set(this is growing every single day!), running the report this way is now crushing excel(file attached).
Input Tab : Column A - stock codes, Main Header Row(OS, GRNS, WMS, LGRNS, CS, TRANSFERS) are Stock Movement Categories.
TRANSFERS represent inter site movements eg. WML>CW(WML to CW) and CW>WML(CW to WML).
Sub Header Row(WML,MCO,DW,CW,IH,WH,YEA,OTH,SPW) are Stock Storage sites. This is the raw data tab.



Output Tab: (Desired Result):
Column A: Currently builds the Key ID for Site & Stock Code(Concat Account(column B) & Code(Column C).
Sumifs formulae are then used to sum up stocks by storage sites(from Input Tab) under Headers(OS, GRNS, WMS, LRGNs, CS),
Ifs formulae are used to sum up all intersite transfers).

Please note that all sites share the same 10 000 different stock items(Column A in Input tab and Column C in Output tab). Had to truncate the file size(currently about 30MB). (May be adding a single tab with one set of stock items in Column A and the site movements counts tabulated from there-have hidden the tab incase this will help simplify the solution)

Although this works, as it is run daily, it is too much real estate, is very slow, crushing Excel due to the ever growing size of the data set. I have tried recording a macro on this and it crashes due to formulae(I suspect). Would also be grateful if the vba solution can accept dynamic update of stock randomly across the sites in the OUTPUT sheet(column B -sites are ordered in groups currently). Thank you in advance.

cfo

p45cal
12-04-2020, 07:55 PM
I've been able to get similar results to you and get them updating almost instantly (partly due to it being a small subset of your data).
One reason for differences in values in the picture below is that some of your formulae refer to the empty cells below the table on the INPUT sheet.
What version of Excel are you using?
How do you get this data into Excel? Does it come from external files? If so it would very probably be easier (and lighter on Excel) to grab this data directly from those files.
It would help if you could perhaps share a workbook on a file-sharing site which would allow bigger files, then share a link to it (privately if you want).
It would be even better if you could share the source files of this data (if they exist, that is).
27546

Paul_Hossler
12-05-2020, 09:10 AM
Another approach is to take the INPUT and process it to a pivot table-friendly format

27548

Not sure of some of your business rules, and I think some of your test data as formulas were incorrect




Option Explicit

Dim rowOut As Long
Dim wsIn As Worksheet, wsTemp As Worksheet

Sub PrepareForPivotTable()

Application.ScreenUpdating = False

On Error Resume Next
Application.DisplayAlerts = False
Worksheets("Temp").Delete
Application.DisplayAlerts = True
On Error GoTo 0

Worksheets.Add.Name = "Temp"
Set wsTemp = Worksheets("Temp")

Set wsIn = Worksheets("INPUT")

rowOut = 1

With wsTemp
.Cells(rowOut, 1).Value = "Code" ' e.g. RB515
.Cells(rowOut, 2).Value = "Category" ' e.g. OS
.Cells(rowOut, 3).Value = "Account" ' e.g. WML
.Cells(rowOut, 4).Value = "Qty" ' e.g. 180
End With

rowOut = rowOut + 1

Call pvtList("OS", wsIn.Range("B:J"))
Call pvtList("GRN", wsIn.Range("K:S"))
Call pvtList("WMS", wsIn.Range("T:AB"))
Call pvtList("LGRN ", wsIn.Range("AC:AK"))
Call pvtList("CS", wsIn.Range("AL:AT"))
Call pvtList("TRANSFERS", wsIn.Range("AU:BN"))

wsTemp.Cells(1, 1).CurrentRegion.Name = "Data"


Application.ScreenUpdating = True
End Sub




Private Sub pvtList(Cat As String, R As Range)
Dim r1 As Range
Dim iRow As Long, iCol As Long
Dim rowCell As Long, colCell As Long
Dim v As Variant

Set r1 = Intersect(R, wsIn.UsedRange)

With r1
For iRow = 3 To .Rows.Count
For iCol = 1 To .Columns.Count
If .Cells(iRow, iCol).Value > 0 Then
rowCell = .Cells(iRow, iCol).Row
colCell = .Cells(iRow, iCol).Column

wsTemp.Cells(rowOut, 1).Value = wsIn.Cells(rowCell, 1).Value ' code
If Cat = "TRANSFERS" Then
v = Split(wsIn.Cells(2, colCell).Value, ">")
wsTemp.Cells(rowOut, 2).Value = "TRANS" ' category
wsTemp.Cells(rowOut, 3).Value = v(1) ' account
Else
wsTemp.Cells(rowOut, 2).Value = Cat ' category
wsTemp.Cells(rowOut, 3).Value = wsIn.Cells(2, colCell).Value ' account
End If

wsTemp.Cells(rowOut, 4).Value = wsIn.Cells(rowCell, colCell).Value ' qty

rowOut = rowOut + 1
End If

Next iCol
Next iRow
End With
End Sub

cfo20code
12-05-2020, 10:06 AM
Thanks P45cal - the source data is a csv download from a bespoke software for stock management. Using Excel 2016. I had to truncate the file(hence empty data bit in some cells). Let me try and set up a link to save the whole file and will get back to you. Much appreciated.
Cfo

cfo20code
12-05-2020, 10:09 AM
Hi MPVP Paul - thanks a lot for this. Let me try this out. Also, MVP P45cal has an idea to use the source data so will post a large file of this and share link. I will feedback on the script you sent. Thanks once again.
Cfo

cfo20code
12-05-2020, 10:38 AM
Hi here is the link with the full file.

https://drive.google.com/file/d/1KHx4d-sxmg8k4FGjOJG873eKNbOeIP2e/view?usp=sharing

Thanks

cfo

Paul_Hossler
12-05-2020, 02:21 PM
As example --

The attachment includes only the pivot tables (copy/paste values) based on the temp sheet generated by the macro (runs in 3-4 seconds)
Normally INPUT and Temp would be in the the workbook

If you want to try it out, put the macro in your real workbook, run it, and then make pivot table(s)


27551


Some data issues

1. Some Codes are blank
2. I think I did the transfer calculations correctly
3. Data goes wahoonie-shaped if I sort INPUT since the OUTPUT formulas don't update and now point to the wrong row.
4. Don't know about KiDm field - the two sub-fields are there already


If you do have a formatting requirement for management, a second macro can take the PT and make a pretty report

cfo20code
12-05-2020, 02:22 PM
Hi Paul - data is random test data(stock in KGs that could be between 1 and up to 100k). Sorry for not specifying.
Thanks

cfo20code
12-05-2020, 02:26 PM
Hi Paul - thanks. Have you seen the latest file I sent through the link?
https://drive.google.com/file/d/1KHx...ew?usp=sharing (https://drive.google.com/file/d/1KHx4d-sxmg8k4FGjOJG873eKNbOeIP2e/view?usp=sharing)
This is a third of the full data set. I would replicate the code soluton for full coverage once done. I will play with what you just sent and feedback. Thanks once again.

Paul_Hossler
12-05-2020, 02:33 PM
OK

If there's any confusion, I'll PM you a link to my Google Drive with the more complete file

cfo20code
12-05-2020, 02:38 PM
Hi Paul - have replaced the sample input data with the real dataset - script been running for the last 5 mins, and still running. 100% memory usage. Timing it(hopefull wont crash). Thanks

Paul_Hossler
12-05-2020, 02:43 PM
Hmmmm - seems long

PM me link to your GD with the full dataset (if you can) and I'll look for bottle necks in my macro

cfo20code
12-05-2020, 02:58 PM
hi Paul - the full dataset crashed Excel. It does work on a small data set. Thanks

Paul_Hossler
12-05-2020, 03:00 PM
What version of Excel? 32 bit or 64 bit?

PM me link to your GD with the full dataset (if you want) and I'll look for bottle necks in my macro

cfo20code
12-05-2020, 03:18 PM
Hi Paul - I have deleted the Output file(Formulae caused the crashing) and replicated your runtime. Can you please add code for Intersite Transfers be part of the Temp file so they can be pivoted by site? eg for CW - it will show WML>CW, DW>CW, SPW>CW, WH>CW example. Alternatively, a separate pivot?
Thanks.

Paul_Hossler
12-05-2020, 04:02 PM
I tried to make the PT look like your Output. What changes did you want?

Input

27554


Your original Output

27555


My pivot table

27556

cfo20code
12-05-2020, 04:03 PM
Hi Paul - have attached the Intersite by Site Transfer pivot idea. And yes, my team would benefit from a Management Report as per your brilliant idea. Will transform the execution of our Working Capital and Sustainability Strategy significantly.

Thanks once again.

Paul_Hossler
12-05-2020, 06:44 PM
27557

How about this format? Little different, but putting the To and the From in separate fields is better (I think)

Can be done the other way

This PT is built off the same INPUT sheet as the non-transfers (OK?? or do you have a separate sheet for transfers??))



http://www.vbaexpress.com/forum/image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAUgAAAHqCAYAAABmwNfWAAAgAElEQVR4Ae29348t x3Ue2v9Hnu6fQHBAIPOSt/sY3BvEliOPY9NOJo4TXf MozAymNF1HOI BPOqHBMmmGHo0Ee0acojmgQBiuaYIECQICkQEM4TX/ZrEjmyZFFiX6x9zrdnTZ3V3au7qvpbPacOsE/17qru9a1vrfq6uvd0Vbfb7fr2aRy0HGg50HLg4RzoGikPk9I4aZy0HGg5IDmwikB /PHHbZT6YKR m7mI5hsLD8uuV9RZ Fh2c3hZRSA//PDDJpAPBPI2cxHNNxYell2vELDwsezm8LKKQL7//vtNIB8I5G3mIppvLDwsu14hYOFj2c3hZRWBfO 995pAPhDI28xFNN9YeFh2vULAwseym8NLFYH85JNPbgjiX//1X9/47gV8G9vdZi6i cbCw7Lr7S8sfCy7ObwUF0gRx29961s3BPGv/uqvbnz3Ar6N7W4zF9F8Y Fh2fX2FxY lt0cXooKJMQxFci33nqLLpDdyUXfdV2/uzihYqnNxZX8acLR2d5X8Vc J L37qK63yV8O7va9V13dMB/diTYrxZhn4PH4m1pvsyxO9R5h/BcnR0t4kLbWYIP/Qc5tYSbJXY1bmynObIEC86lSwtfMYHU4pgK5JtvvpkdVO3I3O2L3a4/6k76o5OT/uJEOhzvb7xqc4GOhY6E72v4nevbyYXEqet3V2eHGB2dXfXwZW7c5uABT9qW4JHOp/d5MMyxO3Q 4KlxQV CTwRyLg pb0vspudATDQv0r9POhn45A0CLHxFBDIVx1QgX3/99UPCpw6v8V1IlZHI2dVVf9LJFTiPyBzMtblAx9LJLCKTMxLz pvjmyR5J0lecIQ/B4/Fm/gtuTN3BD7H7hC3wFOSD9hagq EQC6xC8xS1sgRfX4LX7ZAWuKYCuS3v/1tqkAiuEg6LR6aoDW2a3OR ph r ljjm9y21T64jUHzxBPSzrlHLtD8QCeGgK5BB/60BBez/4ldvV5l1ys9PFT2xa LIEcEsdUINPvU0BL1kvHO5JR44PbtrVGU0M 1OYCHUs/K0pvW4ew5e7P8a1G8s/BA97Si cSgZxjd4hz4NFxnDuSHTr3EnwikLlYltjVPqQ5In0ZmEpwY FbLJBj4pgaeuWVV2gjyFQQU8HUAVhjuzYX6Fi6o0tirSGSOb6lyV8iFnPwWLwJhiUCOcfukJ/AU2MEuQRfiRHkEruan6EcGdqvj/VsW/gWCeSUOKYC fLLL1MEEkmGq4wutYB4yCvVpjYX8Fn7t6STL/E3x7caGOfgsXgTDpZ0vjl2h3gGnhoCuQRfCYFcYlfzM5QjS2Kkz4ttC99sgfSIYyqQf/Inf0IRSCHOGjnJqLLEkBzEzilrc4GOpQVyiIc5uD1tc32TuKTxkn3aFw8OtJmDx INf04y1/4cu8CalsBTQyCX4CshkEvsprxIPshAR/NSSiAtfLME0iuOqUD 8R//MUUgJajWn7cMXYnSYNT4XpsLdCw9Wk4TqoZfcs4SvqEDAH/Or 9z8Fi8pWLt5W2O3aFzWniEk7libZ1/Cb4SArnEroUfFy7kSE1e3AI5RxxTgXzhhRcoAmmRy953m7mI5hsLD8uuN7dZ Fh2c3hxC6TXiNXu eefbwL54I/TbzMX0Xxj4WHZtfqetY Fj2XX4sDaZ FbRSD/6I/ qAnkA4G8zVxE842Fh2XX6vTWPhY ll2LA2ufhW8VgfzDP/zDJpAPBPI2cxHNNxYell2r01v7WPhYdi0OrH0Wvu7TTz/t5fniRx991H/wwQe9TGop87a967/TvvvNO//fbbvbzELe8pvvHGG/1rr73WX15e9q movfzckP43fvXu3f mll/oXX3yxl cMMlR97rnn meffba/c dO/41vfKN9GgctB1oObC4HVhlBikB 77Pvt88jwEEf6N93v/tdChqWXa zLHwsuzm8NIF8BETLc3H6b3df7XM/YifSP1aHZNn1cs/Cx7Kbw0sTyCaQ 5G9iOMXfb/4I8c3gbzfFbcoBF4RyWm3RV6aQDaBvBbIL77ov1j4aQJ5LR1bFIJr9PW2tshLE8gmkAeB/OlPv iXfppAXgvLFoXgGn29rS3y0gSyCeRBIH/yk5/26ef//YNneny /vv/qf8PX//9/vf w9f7f/97T/dffepr/e/826/uj2kCeS0sWxSCa/T1trbIyyyBxHuyc98Hxa/Ydz77ft91Tx7mcNPvUn6p6/rvfXZ331k9PyrcpjZPfUd4eeLAy1OPCxcf9o89/WGPbfiLtt977skbXFltcYynFIH7/POfmh8RxqdFGJ/ ev/vv/Z0/9V/97X d373q/1v/va/ObRvAnktLFsUgmv09ba2yItLIDG5w8XZ0X5BqKUCqTuqdPTHuif6733nmRsdXbd5FLa/9Jzw0N3gQcTu9aef6C2OpL1cWO58WUT0 k nui/f3R j983ZFoH78ec/Gfykwvj//MZv3mjbBPJaWLYoBNfo621tkReXQOKvzjHDSE2BfF1GmY8/cxhN3eaRJUbU6WgQwgYuRCyxT4TwS19 ov SXFwejLjlPI91T94QWbT3liJwP/rx56Of3/itf9N/5dd/s/ 1f/2Vh9o1gbwWli0KwTX6eltb5CWUQEIQ9OhIRlO3VSRlhKiFzhIz8R98QAjvfEcuIE/2EFYZVeZyJAL3w7/7fPTzL//VV/rTX/21/pf/2elD7ZpAXgvLFoXgGn29rS3yEkogLcGAKNzGW3GPsOk2ws9Tj8vI8cNe31JrEbVE1rNPBO5vf/jj0c8v/8pp/4u/9Cv9z//CLz7UrgnktbBsUQiu0dfb2iIvoQRSiwE6NUaVGC1h/20oLX9Tv/RtuBZCOVZ wHldxPLxZw6jyfR473cRuB/87Y/3H/lRRj5f 72z/rd/56v9r/7av97v//mTX x/7p/8fP8zP/tzh7Y4pgnktbBsUQiu0dfb2iIvoQTyURtBavEbEzKMFqXEhQIj66eee2byNn3s3KgTgfubH/zd4fNv/93X q/8 m/1v/zP/sVh3z/ mZ/r/ 9/9DP9P/y//tFhH45pAnktLFsUgmv09ba2yEsogcRoEc/cpPPKqCn9Uxd06ttQin9Dv2LDPxktPvZ4d0MIwdVjjz9xeEaJ9ktKEbjv/ BHNz4n//TJG9/Tev29CeS1sGxRCK7R19vaIi8ugcSf ei/W5yzDgT DlJ3XBktWn/mg1EVbN1mcQQfIpLwV8rUZ3CS7sdxGFXifEtKEbj/9b9/tPjTBPJaWLYoBNfo621tkReXQOLPfJaWlkAu6cTtmOu/eyzNhQjc//ybHy7 NIG8FpYtCsE1 npbW SlCaT6Y vSorOl84nA/Y/v/3DxpwnktbBsUQiu0dfb2iIvTSCbQO7/CF0ELvcjF4RI/1gdkmXXyz0LH8tuDi9NIJtAHt7SKTHi9SbjGu1YHZJl18spCx/Lbg4vq61J85// 72 fW4/B9IJ2qdxcFtyYLURpFfFb3u76FfRHP6j cbCw7LrjR0LH8tuDi9NIL3sFWoXPUly3IzmGwsPy643dix8LLs5vDSB9LJXqF30JMlxM5pvLDws u97YsfCx7Obw0gTSy16hdtGTJMfNaL6x8LDsemPHwseym8NLE0gve4XaRU SHDej cbCw7LrjR0LH8tuDi9NIL3sFWoXPUly3IzmGwsPy643dix8LLs5vLgFEuvR4J3h3cVJ7331UF41 bP/uMxA9SXLiFM03Fh6WXW/sWPhYdnN4cQnk2dWuPzs66ne7q70oiliedF2/2124RLIJ5HWIoifJNdL5W9F8Y Fh2fVGjIWPZTeHF5dApiNFEcyj7qjfXZ01gfSy/6Bd9CSZ6c6N5tF8Y Fh2b0RjJEvLHwsuyNU3Kiy8C0SyJOLXRtB3qDW/8UKgv/o2C2j cbCw7LrzQ4WPpbdHF5mC SSlQ3bLfZ1iKInyTXS VvRfGPhYdn1RoyFj2U3h5fZAtmdXPRnR/L88f7zyPT22/reBPI6RNGT5Brp/K1ovrHwsOx6I8bCx7Kbw8ssgVwijiKYTSCvQxQ9Sa6Rzt K5hsLD8uuN2IsfCy7Oby4BBK31XNHjhhNNoG8DlH0JLlGOn8rmm8sPCy73oix8LHs5vDiEkj5UQ Z//6jLixO51d5NfppAXocoepJcI52/Fc03Fh6WXW/EWPhYdnN4cQmkRwTH2jSBvA5R9CS5Rjp/K5pvLDwsu96IsfCx7Obw0gTSy16hdtGTJMfNaL6x8LDsemPHwseym8NLE0gve4XaRU SHDej cbCw7LrjR0LH8tuDi9NIL3sFWoXPUly3IzmGwsPy643dix8LLs5vHR37tzp26dx0HKg5UDLgYdz YLURZIkV89o5vl90BcLG56PLp3dUVbLdJkeQY78 l6qTX7FbZ4zdGXPXxJbjW4xjx1jHp6Twec/VBHLgbyKbQMbvOCJwX/T94k8TyPgxbgI5LuWWgLdb7M 2ldg6yUtu7wXyiy/6LxZ mkBuK4/GpaJOrSVAdSwtO6uFrwlkE8j9rbEI3E9/ sXiTxPIJpBTsmQJ0NQxa9Zb JpAPhDIO599v6J/svdV3/vc/uPnLP00TgfvKTny7 NIFsAjklZpYATR2zZr2Fzy2Qek2aOcstyA891jPILz0ngtTd Lz 9BOrCNPrIoaPP3NDDFOBtNqUvKWVc8FGysP3nntyFR60PyJwn3/ 08WfJpBNIKfEzBKgqWPWrLfwuQTyYidr0sgiXffngJRpz7wTVVgC djTH 6FUQsi9t35sozg6iYbhGlstOhpk4tzDRtejCJwP/78J4s/TSDr5qw3jt52awoPbFkChLoIpYXPJZDpn/vIaHLO1Gd6BJmO1BBQ7H9MbnG/80z/1HdkhPlED8GEmKBejktHoRBcnOvO00/sR4oYocnIDOfBPimferzrX//sw8Oo8s6Dbd2me/zJ/kuPd722Dzty/Pc3C2sAOLJdTw/ynxQd36wyawaTw4xvK7 /Ldw2jdGqGKwP3ox5/f Hz9Pz7T4/P02e/3T33t6f63f/er/Vd /TdvtJPjmkA2gZwSOUuApo5Zs97CN1sgZTTZdSf91Zmscjg91Vk6goSoQfggkFKiE0sHPnT2ByNK iAkEQeqfelxuyT88iB6ERouInAvfUY9z4bvYTvel36UNRrkQYviC79oXz7ZlA8fBfxFCCNqQH5o Tuaik3 UcgjE9HrakFIH74d99/tDn6a//xxvCePqrv/ZQGzmuCWQTyCkxswRo6pg16y18boHUc0LOub1OBRIikyuQunPLtogrhAFCoEd2ut4SpnRf l1spOfV50zxeL7DBkaDUsIHCKT2wRJk8CkCmB6D8 sLwRBmEbi//eGPzc9v/c7v9v/8X/zL/hd/6VfMejmuCWQTyCkxswRo6pg16y18boHUo8Ul62JDMNDJU4FEZ8aICZ0d7VAPAZHzSWe3xCUVMrT FsTiXFo50X/od CEwr3/nmf0tuRYwtPGWQzbk NR/2afFEDbAZwmB/MHf/rgf vzcP/n5wTo5pglkE8gpMbMEaOqYNestfIsEcsm62OjQ6PipsEDUIFpoNySQEAvcfkK45PklzqVt6HpLm NJ96XfghyA99rj8Av/E/tYVdXPLIRtyntR/2Qfb pZe84Bj4Ld1fs2DxisC9zc/ LvFnyaQTSCnxMwSoKlj1qy38LkEUgTx4uT6mWPOCFI6pXRSGfnpjp7ug8hBMCEOGAWKMGAbbdPv EArYRL313SsmaKdvh7XQzNnGueCjPhZihwuE1MFP JUej2OG6uUcYwL5/R/8qF/6aQLZBHJKzCwBmjpmzXoLn0sgsWgXbmePuq7fXZ0t pEGIoCRD86JUosFRFHqpNM/9vTDzxkPx335yYcEE0JhCQPEBOfWv2LjD8XTNvilGtj1 eHXnDIVOH0sbGuBlHrsP/it/rAddcBlnX9MIP/X//5Rv/TTBLIJ5JSYWQI0dcya9RY l0Dq549LtvWf WgRSLchPHqkl7aJ8B3CrUfAEXDlYBCB 59/88PFnyaQTSCnxMwSoKlj1qy38IUSSOngIj7RBRKPA/D8M0eYohwrAvc/vv/DxZ8mkE0gp8TMEqCpY9ast/CFE8gogjGEA7ex lHAUNst7ReBy/1syd9HHeuawgNblgChLkJp4WsCWfm1xke9Izb/Y44sGYJkCRADx5BNC1/36aef9p988kn/0Ucf9R988EH//vvv99917/7rvv9u 8807/9ttv92 99Vb/5ptv9m 88Ub/2muv9ZeXl/2rr77av/LKK/3LL7/c3717t3/ppZf6F198sX/hhRf6559/vn/uuef6Z599dr/ejfcZZOtMMTtTi8vti4uIQftMc9BGkG0EOfsd8iaY2xfMoVFUzf3WCK2mvbnntvA1gZwhkLnP6N oPGdsXlttycZgrHiXaWwJU4rylzmHhawI5UyDbui1N5G6DSJYSlTnnsQRozvG121r4mkDOFciFa 7bIWi9tBNnENYq41hYb6/yWAFntWPssfE0gZwpkW7eliVwUkcvBwRAhS4AYOIZsWvg2L5B4nW6NPy6XEWBbt6UJZI4wRTl2S CRq7rcEqKa9uee28M0WSFluQd4DXjphLhIEr vhnWK8P4x6b7m2QJZctwWTT4ADlPoVRry1o/eBu/SP1bFft/XyWKMd/qg 9WvIb7yZVMPnpecEVp2fyLmUf4vDXLvgDtzAhuYWOCysaJ Wc8WjRHtLgEqct9Q5LHyzBFImzT056vruaPmM4hIovHOtJ2KQfUs6NpJ1rRFkyXVbrIROuYHopV xZHQfHpp0p7RxrfEcHhrBInL70 DP7FSPhNzo2Yig CfYaPi89J7DCD EOeIF/jM9cu5LX3eNP7CdrwWQpYk9ijTrgsLAOYSslKnPOYwnQnONrt7XwuQUSM/pcXZz03dHZ4hEkgoigWgFEG4hAKn5IOqmXdWJkvRjdBgk8dLxl07NPbrFLrtsCP3XnExwYdYhYp G1S33BRwf4xXj0 lmqDGGlhx7nhk8YKcRd/UA9e4BviucTnpedMjxMfgEfjh29pmR6PY6d8wXFi47Gnn7mR36h76suS 9ercx72O9ZIqi021vktAbLasfZZ NwCKXNAylILB6GssCaNJBeCjORDQkEAUY/Og46IerTH8XJOERz9PU1i73cRyJLrtqS AIcWC/gD/w7HPFjMCzxgxGYJEs67Zgk8IgTACPvwQcekts9LeQRW7QPOpfHDt7RE27nxg12x8dR3ZP7U68mZ kfOvP/dkE8iCarpYIGXC3JNOJsy9yBZIdIShjnwIvlojG8fIyCGtTxMQHVOfH8fk3nqKQJZctwWdQHc 6WDAi5ES/Ne3n gc6Hg4JtfHtIPnfEcsMFqCn/AbAoPv8EVs1vB5yTmBDT7oEvinOMqxKzZe/ zujeU9cMHHfuAAVvA8hqugrrhPZQmQAVGlr4JkeQGDHuLmRd7F22QKIjawHTgUQyQRykDsfIvrQ FUi01YmM7VzxEIEcWrNF9s9dt2UooVMfITTCmdShQ6Cd CWdRguM5pS9DfwSB4kh/EZcpEyx45iSPi85J7Bq0UHOIQ5T/ObYhQ2JtXD01HPPHJZDTnFYWIewraA3D5mwBOihRsQdFr5JgcQyrzqZse1dG1tPVoFkQeDTAELg tEBqIUjrkSToYGl9ev6c7yKQJddtGUroVOzQDs9b0VkPXMqzqO7Jh25lc3wtfSziIoJ38EfNhp7 aO7R58Iy5hM9LzoljYF9wIueGcriEL7ALG4i1vpikOHCMxppiwXeGDlkCxMAxZNPCNymQ6QziGF Hm/JmPCIAEWo8ipQPp0QWCnCYBEgX16HgQSCQJEgsJUaIUgVy6ZoscJ8drHMAKX6QOFwPNjewHZ8Ib Lh44Hhcs7Nc2WNvih8YD/DLaBe6pGOGYkj7PPSew6hilOenheKldcASbwgWwYB/aWFiHsA2JRM39lgDVtDf33BY ikBK0CAE6NwIutRBBFGHBECwIYpIFr1WjbRBouB4KdNz4FxzShG4pWu2yHFDAqlxyrYWFuDTPut HBeh4uECgPbtE59W ATfiMxWTGj7PPSew6vyEb1P4dQyW2tU20GeQHykOYNWcD XFXPEo0d4SoBLnLXUOC99sgUxHlJ7v hZbJ83WtkXg2rot7U2areWthbeUqMw5jyVAc46v3dbC1wRy5rvYbd2WJpCW4GxtX22xsc5vCZDV jrXPwtcEcqZAyigy57O1jtTw3s4LAkOELAFi4BiyaeFrAjlDIJtY3E6xeBTjOiQSNfdbAlTT3tx zW/hWW5PmP//3e337NA5aDsTIARGD9pnmYLUR5Fw1v63travUbfE1mm8sPCy73jxi4WPZzeGlCaSXvULtoidJjp vRfGPhYdn1xo6Fj2U3h5cmkF72CrWLniQ5bkbzjYWHZdcbOxY lt0cXppAetkr1C56kuS4Gc03Fh6WXW/sWPhYdnN4aQLpZa9Qu hJkuNmNN9YeFh2vbFj4WPZzeGlCaSXvULtoidJjpvRfGPhYdn1xo6Fj2U3hxeXQGKCCv2Op0ye6 3nNUNrIq4aMf6eX/X5SDI1btk 7ru/7yz2k4/N7 zb3zo8fgog6OeZYjrl3fmiDuvQ47IfN/vL0cIxsRE SG2BnfmH51p1emjGshSfNqzQHatmdGY7B5ix8LLuDRCQVFr5ZAok5Ib3CiHYsgUz833 VznR52u3lsetO 8vz4747Pu/TJBehOz8WIb134zQiq0PHnd/r /NjEdr7x8g5tBjLiawg3DCw4S8M30SsTo 7vjs fSiGNfBI/I 708PFUmJ 3B0fvm8hxjV48aQty64H21DcHimBtJJZpCwVyLQTWARbx6XtLHvRkyT1Yc73tX07xODy9KEYCu4 aeCSmpyKID 5ArFypYXdOHKbasvCx7E7xgXoL3yyBxG3jUdf1u6uz8LfYcBwlRo/4LuWhk6lbbAhbd3x8uEWXUaf Zx2n62V7P7pRt/OyzwpCetxWv6/tm4zQJS5DsaiFR/JI7gzu9ZerCXPJnKjFyxRGlt0pXKi38LkEErfKKGUBrxMRyd2FSyQj3GLj1jh9Jmh1LhE2/cxRBLOTUYN6nmgdB6KlHKq3gqCP2/L2mr7pkRyDazz3tB7DrMnDknxh4WPZ9XJk4VskkFiGwftMMoJADj1TtDpXOvKz2lj7dCCkA22x8 2gf5m5bCTb3HJ724B4XLHxPnyPXwJNeaCWv9MVU8New6 HF24aFj2U3h5dFAimrHB7JKofO22y2QKZJrQmzOhdusfGrtdXG2ofzDomj1EdPEviwpFzLN8QTj 3x0qS9KNfCkF1orD2rYXRKPoWNY Fh2h3hI91v4XAJ5dHJxQwy7k4veu2CX3JazBVKSOv01GeRYCZ7uS2 55di0jd6nOynsoLSCgLqtlyzfrFgIlzXwpHcX1uOXGnZL5gYLH8uulzsLn0sgTy52hx8r5Go9Rx zZAonRRnr7hf169CHbaIfERz1u58aOk86D9rrUP/BYQfAGMHo7lm9rCqTEAM8fEWPkDOLD4gH2p0oWPpbdKT5Qb FzCSR nFlaskeQICBCaQUhAq4SGKL5xsLDsuuNIQsfy24OL00gvewVahc9SXLcjOYbCw/Lrjd2LHwsuzm8NIH0sleoXfQkyXEzmm8sPCy73tix8LHs5vDSBNLLXqF20ZMkx81ovrHwsOx6Y8 fCx7Kbw8tqa9IIOe3TOGg50HJgSznQRpDey0uhdpIct/VfNN9YeFh2vXnFwseym8NLE0gve4XaRU SHDej cbCw7LrjR0LH8tuDi9NIL3sFWoXPUly3IzmGwsPy643dix8LLs5vDSB9LJXqF30JMlxM5pvLDws u97YsfCx7Obw0gTSy16hdtGTJMfNaL6x8LDsemPHwseym8NLE0gve4XaRU SHDej cbCw7LrjR0LH8tuDi zBFLmgcT7p3MmzWW9ajj0bjQmrpBJLOCPlHjfGoSiPn3XVupRJ8dhuiu8E6zPqd/DluOiJwl8X1KyfMO70WmcauFJ82otu0tiYh1TixfLlt7HsqsxjG1b NwCKeI4d5IKvLvNEkiLDOlMIloyGcXQ jGYkGLuejUQyFRoNQ4rCLp y9sM3/az67Q1aWalDSNOApBl10uOhc8lkDJB7lF3cmPKM4ifp4wikOk8j5o4qw6Cp0cIIp560SZ9DrRvA qlZqbcNvu 1NWlmkWwJwawTLGzMsuuFa FzCSQmyO2Ojg63pFtY9jUlBqPHdL98349EkvVjDh3QuV4N2uMWG7fe2p4VBF2/5e21fZPHHG1NmvkZs3acgJBlF/anSgufSyBlPkj9zFEEs5MZxS9ONr8mjZAGYdMjxaH9IqRa DBvpDVqlA6M550IjhUE1G29XNM34R2rCw7FryYePPe0JkeuabdEjrDwsex6ObPwuQVSL9J1tdv1 3dFZf3V2tBmBFLGyklnIk2S36qyOl440rTYICJ5lavG0goD2Wy/X8g2cg1d8Ty9wNfCkMZW80hdMiWENuyVzg4WPZdfLnYXPJZC4xcYaNFsTyDSpNWFD4ihtrI6XPq u02uD8aVvZbwUB7bderuUb4olHGbrUF7oaeNILrRX/GnZL5gYLH8uulzsLn0sgU0FMb7mnfqhh/0hj3eoisXWHSolEGz0ySffpW 5j XLv/HAaS3ytIBwO2PgGy7c0JqCxBp70DsJ6xFLDLnwqUbLwsex6ObPwuQRSBBDPHXG19j5/lGOZAonRhhY5IUwSHb7oUh764xi9X7ZxDnQK1ONWLz2nJb5WELwBjN6O5duaAikxwPNHxB95gfi weID9qZKFj2V3ig/UW/jcAjk1ShyrZwoknI9SWkGIgi0XRzTfWHhYdr3xY Fj2c3hpQmkl71C7aInSY6b0Xxj4WHZ9caOhbQSF5YAACAASURBVI9lN4eXJpBe9gq1i54kOW5G8 42Fh2XXGzsWPpbdHF6aQHrZK9QuepLkuBnNNxYell1v7Fj4WHZzeOn 8i//sn/ttdf6b3/72/vP5eVlL5 / Iu/2H9a1v9a ur 8 d//ue9fF555ZX958/ 7M96 fzpn/5p//LLL 8/3/zmN3v53L17d//5P377/ zlI S0T Og5UDLgS3lQPfxxx/3NT8QSK K3/Z2khy39V8031h4WHa9ecXCx7Kbw0sTSC97hdpFT5IcN6P5xsLDsuuNHQsfy24OL00gvewVahc9S XLcjOYbCw/Lrjd2LHwsuzm8NIH0sleoXfQkyXEzmm8sPCy73tix8LHs5vDSBNLLXqF20ZMkx81ovrHwsOx6Y8 fCx7Kbw0sTSC97hdpFT5IcN6P5xsLDsuuNHQsfy24OLy6B/KVvftz/vV/4 w99fukX/n7/8cf/dfRXcOav2Om70Xh3FnM0yiQW2Ccl3qkGoahP37WVetTJcXq6q9Rmemz0JIHvS0qWb3g3ei2utx5 jVpxYdr25bOFzCaT1Z0B/7w/ a3/nD0Qgx/9MiCmQFjHSmWqtSSOTXOjlGNp0Z1YEyu4TsTpta9LMItUSglknWNiYZdcL18K3SCCffuvj/h/8ws/2H7/1/21KIC3BAnlWnTVLTCqCOF5KOQdmuZbvVlsrCPocW95e27dDfNqaNLPSZu04ARzLLuxPlRa RQLpHT3K6DLSCBKjR4uo/Ugkc00aOa/YkFv4e/1l3x2fH6ZIg00rCKjberm2b/KYo61JMz9r1o4TELLswv5UaeGbLZB3Ppbnkb/Rf/zN35gcPUYSSMzxmD5nFNIOIxG1ONfQfhFS/cxRRo1dd3zj SWeibX5IKdScnm9Hq0Pxc9K OUWbx655RjX5OUmSze/sezeRDH8zcI3WyD/wX95vX/6t TZ4 ubEkgZbViCJXRJslt1VsdLR5q6TSrCYlOLqdiygjAcsm3VrOUbOMfFDt/X JHmNsR4rTil2cuym IY m7hmyWQc0ePUUaQaVJrgobEUdpYHS99VqnbpCKs62DTCgLqtl6u5Rviqf8CAdv6QlcDz22IcQ1e PLnLsuvBJm0sfLMEUkaPnj/t0b9sR3gGKUmNP 0BWRAv3aFQhxJt9Mgk3advudPRpXX7bQUB9rZesnxLYwIea C5DTGuwQs4HytZdscw6ToLn1sgMXr89n/5WdetNUSSLZAYbWiRE1Ik0THq0GXOmjRyXjybwjlTu1YQdJC2vM3ybU2BvA0xZsWJZdfbpyx8bo GE4M0t2QLpJWetdlYQ1rJd204031h4WHa98WXhY9nN4aUJpJe9Qu2iJ0mOm9F8Y Fh2fXGjoWPZTeHlyaQXvYKtYueJDluRvONhYdl1xs7Fj6W3RxemkB62SvULnqS5LgZzTcWHpZdb xY Fh2c3hpa9K0tXLaWkEtB1oODORAW9XQe3kp1C76VTTHzWi sfCw7Hpjx8LHspvDSxNIL3uF2kVPkhw3o/nGwsOy640dCx/Lbg4vTSC97BVqFz1JctyM5hsLD8uuN3YsfCy7Obw0gfSyV6hd9CTJcTOabyw8LLve2LHwsezm8N IE0steoXbRkyTHzWi sfCw7Hpjx8LHspvDSxNIL3uF2kVPkhw3o/nGwsOy640dCx/Lbg4vboE8udjdeHf56uyo3 12rs83vvENL8ai7Ybet8bEFTKJBd6ZlhLTZwEE6tP3qfV50 nMdJ2cMz02epLA9yUlyze8/74W11uPMStOLLveXLbwuQTyYrfrj7qTfnd1thfEsyv5fnT4PiWULIG0iJHOlLMmjXQOLYryHYIr E2O0NWks1uvt2/Pf1qSZRbAlBLNOsLAxy64XroXPJZAiiCciiLuLvUCmgrkVgUznctTEWXXWLDHpfIBaFOUcbU0az Wrd7UN82po0s4i2hGDWCRY2Ztn1wrXwuQRSBLA7uehPuq6/2l303dFZv4Vb7JQYjB7T/fJdjwRRf iAaimGtB2mU8Ptudhoa9KAwbqlXKzamjTzObaEYP5Z5h/BsutFauFzCyREUp6rnR11/W535Xr KMdFuMVOhUyTZgmh1A/txzMv4UJut7vjtiaN8GUlmOa55LYerQ/FqSYe5IA14XJNuyU4ZOFj2fVyZuFzCaTcUnfyDPLiZC KR2dX/VHXbeoZZHprrEmTZLcSfajj6WO18OptaSM29fNK2WcFQZ9vy9tr Ya4YNSO72v8SHMbYrxWnNJcZtlNcQx9t/C5BFIEUY8ar0QwZ9xms0eQaVJrgobEUdoMdTx9vL7lTkXYOt4Kgj7flrfX8g3xlBF8 tEXuhp4bkOMa/DiyVuWXQ82aWPhcwmk/ImPPH/EjzTyo00nP9o8GFFG/5FGkhq/NIMsiJfuUKhDiTbpyAT16Kio12IpbeQ2MF0S1goCzrf1kuXbUJxq4LkNMa7Biyd3WXY92KSNhc8 lkPr5I67YW/mRJhUxkCWJDl90ObUmDUQPx0AccV48mxqqt4KAY7desnxbUyAlRluPMStOLLvefmXhcwvk1Chxr J59i 0laI12VhDWsLuGjWi sfCw7HpjzMLHspvDSxNIL3uF2kVPkhw3o/nGwsOy640dCx/Lbg4vTSC97BVqFz1JctyM5hsLD8uuN3YsfCy7Obw0gfSyV6hd9CTJcTOabyw8LLve2LHwsezm8N J9 umn/SeffNJ/9NFH/QcffNC///77/Xvvvde/67/TvvvNO//fbb/VtvvdW/ eab/RtvvNG/9tpr/eXlZf/qq6/2r7zySv/yyy/3d /e7V966aX xRdf7F944YXeef75977rn 2Wef7e/cubP/Q3Ehp30aBy0HWg5sKQfaCNJ7eSnUTpLjtv6L5hsLD8uuN69Y Fh2c3hpAullr1C76EmS42Y031h4WHa9sWPhY9nN4aUJpJe9Qu2iJ0mOm9F8Y Fh2fXGjoWPZTeHlyaQXvYKtYueJDluRvONhYdl1xs7Fj6W3RxemkB62SvULnqS5LgZzTcWHpZdb xY Fh2c3hpAullr1C76EmS42Y031h4WHa9sWPhY9nN4cUtkHpNmjlTnckriKxXDYfet8bEFTKJBd6Z lhLTZwmhY3Xp 9j6OH1s p621EVPEm8yWe1YvuHd6JTvWnjSvFrLrsX5kn21eJnCwrI7hQv1Fj6XQIo4alFMZ/cZew bKZBwXJfSmabWpBEBPJdJcPcTnt0XS4hqOvmFdBbM Yi6y/Pjvjs f2jBLsFhBUHj2/I2wzfh/7StSTMrbRhx2kLuW7y4BDKdD/JRWZMGWSeCedwd9/2984eWZsBMMnoUiX3pyGILSQKfl5RWgi05j/eYA89tTRovZft2a8cJ4Fh2YX qtPC5BDIdMaYzjG9lBInRo0XUfiQit9m9jANv/tN1nglTDx1XrWWDM1pBQN3Wy7V9k1i0NWnmZ83acQJCll3YnyotfC6BFAGURbvwvE5ut7uj7UyY K8Tg9leP9EDYmKCldalAyjlEePVoMT0GdqS0gqDrt7y9pm8yqscKkkN818SD557WhMs17ZbIDxY ll0vZxY t0DqUeIWR5CWsIE4SXYr0aU rUvPY3VOax9sWUFA3dbLtXwDv7jY4bu SAmXNfCkF1rJBzyDRvxq2MW5S5QsfCy7Xs4sfIsEMr3l1uJpbbN xQYxaVJjv5SpAE7V6dttaYvOic6q96UdVuqsIGibW95eyzfEE3c0utQXuhp4PBfIGnZL5gULH8u ulzsL32yBxOhxK0suCDmS1PgVGmRB2HSH8tShc0IQU8GUc DcTSDBaN1yiG8r4XORpPHGn3whH T8Nezm4tbHs/Cx7Grfx7YtfC6BxCJduFLPEUcZUTJHkBC0VKwk0eGPLuWh/1idEIxOIcfp2yvY0ueTbW3bCsJY0LZUx/JtTYGUeOD5I Ks4yv1LB68ucLCx7Kbw4tLIK3b5jn7mALpJWetdtGTJIeHaL6x8LDsemPHwseym8NLE0gve4XaR U SHDej cbCw7LrjR0LH8tuDi9NIL3sFWoXPUly3IzmGwsPy643dix8LLs5vDSB9LJXqF30JMlxM5pvLDws u97YsfCx7Obw0takaWvl7H9UkORtn8ZBy4GbOdBGkN7LS6F20a iOW5G842Fh2XXGzsWPpbdHF6aQHrZK9QuepLkuBnNNxYell1v7Fj4WHZzeGkC6WWvULvoSZLjZj TfWHhYdr2xY Fj2c3hpQmkl71C7aInSY6b0Xxj4WHZ9caOhY9lN4eXJpBe9gq1i54kOW5G842Fh2XXGzsWPpbdH F6aQHrZK9QuepLkuBnNNxYell1v7Fj4WHZzeJkUSJlNXN45Td /Tt/P3l2c9EOvH7JeNRx6pxoTV8gkFnifVko94cBYnX4Xe w42NEBip4kGuvcbZZveDd6rXei07xay 7ceAy1Z8WJZXeIh3S/hW9QIDFrz8XZUd8dnd0QSNRBNNM1a1KhZAlkSoB8l85Uc02a8 PTw1o2sKVxWEHQ9VveZvgmYtXWpJmXNYw4CUKWXS87Fr5BgYTIXcls4olApvNBos3QKDKKQMrID 2vLpKR56/YdUi3NgJlk9OgT507nDtxCkgD7ktJKsCXn8R4D7u 1NWm8lO3brR0ngGPZhf2p0sK3SCDTRbwgkBhRQlxRRhFIa0QH0lLhw34pdV0qeodOmqw/g6nPtnb7pf2eu20l2NxzzGkvsWhr0sxh7H7bteMEhCy7sD9VWviKCKQIoaxZE1kgIVjWSG9I5IT QtC4VSGkjwgshFDHFc03pvOk/Kwhpm61 X9M3GfG3NWmWZcqacdIIWXY1hrFtC18RgdzCCNISNpAlAmfNLC71aV16nlRAcU4ppW36Q40VBH3 MlrfX8g2c42KH77hIgcMaeNILrcRYT5ostmvYhU8lShY ll0vZxa RQK5tWeQaVJrwlIBnKrTt9vSFp0TnVUfbz3XtIKgj9ny9lq IZ4YqetSX hq4PFcIGvYLZkXLHwsu17uLHyLBBK/YuNHmVQw8ewRJfsZpDWSg7DpDgUix rQOSGIWjBFEC9Pj3GaNoI8MFF3A/FaYwSp4y1eScy77vjGn4hZHa0uA/POzsLHsutlx8I3KJAQQX11lm08Z9R/BynrZO uzsL9HaQQA0FLO49 Vqh9zFmTBh0V50tvvQSPFQRvAKO3Y/kG3tMY18Ijdx2IsZRr2S0V/1q8TOFj2Z3ChXoL36BAYvRXomSPIEFAhNIKQgRcJTBE842Fh2XXG0MWPpbdHF6aQHrZK9QuepLk uBnNNxYell1v7Fj4WHZzeGkC6WWvULvoSZLjZjTfWHhYdr2xY Fj2c3hpQmkl71C7aInSY6b0Xxj4WHZ9caOhY9lN4eXtiZNW4ulrUXTcqDlwEAOtBGk9/JSqF30q2iOm9F8Y Fh2fXGjoWPZTeHlyaQXvYKtYueJDluRvONhYdl1xs7Fj6W3RxemkB62SvULnqS5LgZzTcWHpZdb xY Fh2c3hpAullr1C76EmS42Y031h4WHa9sWPhY9nN4aUJpJe9Qu2iJ0mOm9F8Y Fh2fXGjoWPZTeHlyaQXvYKtYueJDluRvONhYdl1xs7Fj6W3RxeJgVyaE0aeQVxrE6/osh61XDofWtMQSaTWOh3ajEBhRA6VocJCnAsjsM7wdgvZTonZPQk8SaT1Y7lG96NXuud6DSv1rJ rcb5kHytOLLtejix8gwKJySrG1qSx6rQwYpslkBYx0plEtETkzo9l5h2RtZtzN47VpZNfSGfBpB QQSAimZd8KgtVui/sYvgn/bU2aednCiJMgZNn1smPhGxRIiNvYZLhjdTheyigCKcJXc02aJpDf9eZikXbgu61JM49OSwjmnWF Za5ZdL1oL3yMlkBg9WoTtRyJqMS7dRteNTZiKDotbbIws9bmsIOj6LW v7ZvEQu4GwPtat7qSR/KY5l5/2XfH5226M2fSrp0fTliHZha R0YgcWts3f4OdTBhLq1LBVLaSIdJO6fsl7Z43okoWEFA3dbLNX2Tu4G2Js2yjFkzThohy67GMLZ t4XtkBNISNpAlAmfNLC71aV16nlRAcU4pLVG2gqCP2fL2Wr6Bc1zs8D29SNXAk8ZU8iG9U6hht2 ResPCx7Hq5s/A9EgKZJrUmLBXAqTp9uy1t0TnRWfXx1jNPKwj6mC1vr Ub4olHGbrUF7oaeDwXyBp2S YFCx/Lrpc7C98jIZCS1OmtLoRNdygQOVaHzglB1IJ5LF/uneM0D40 pcIKwuGAjW wfEO81hhB6nhLuOQi2Nak8SUuKz986Oy OSiQ DMffXWWbVmTZqxO/3qNbeav2BC0tPNIoqe yfecNWnSc1riGz1JvMlktWP5tqZAit9y16FzJ80tFg9WTKx9LHwsuxYH1j4L36BAQtxKlEyBtIh g7rOCwMRT0nY031h4WHa9sWThY9nN4aUJpJe9Qu2iJ0mOm9F8Y Fh2fXGjoWPZTeHlyaQXvYKtYueJDluRvONhYdl1xs7Fj6W3RxemkB62SvULnqS5LgZzTcWHpZdb xY Fh2c3hpa9IMrEUhwWyfxkHLgUc7B9oI0nt5KdQu lU0x81ovrHwsOx6Y8fCx7Kbw0sTSC97hdpFT5IcN6P5xsLDsuuNHQsfy24OL00gvewVahc9SXLc jOYbCw/Lrjd2LHwsuzm8NIH0sleoXfQkyXEzmm8sPCy73tix8LHs5vDSBNLLXqF20ZMkx81ovrHwsOx6Y8 fCx7Kbw0sTSC97hdpFT5IcN6P5xsLDsuuNHQsfy24OL5MCObTuDPbjndTdxUk/9Foi61XD9N1oYMXEFTKJBfZJiQkohNCxOkxQgGP1cemxW5sKy5tMVjtWB8C70Wu9E53m1Vp2Lc6 X7GPFiWXXy5GFb1AgMSGFte7M2dWuPzs66ne7q70oiliedF2/212YIskSSIsY6Uy11qQRe l0WCkGKwhpm61 Z/gmYtXWpJmXMYw4CUKWXS87Fr5BgcRo0LPujAjmUXfU767OQgukNT8jyPPW7TukWpoBM8nIKFJmD jruTm9MeYbzo7SCgLqtl2v7Bu7bmjTzMmftOAEdyy7sT5UWviICeXKx28QIEqNHi6hU HQbXZeOEA d9Px4PzegLArWHR8fbt1ltKr/WUHQ9VveXts3iUVbk2Z xqwdJyBk2YX9qdLCly2QnhFmhFtszAuZPi8U0rTIpSSmdalASnsRXnkOJUKqnzniWaW2aQUhtbn V72v6Jty2NWmWZcqacdIIWXY1hrFtC1 2QHYnF/3ZkTx/vP88ErfmuowgkJawgSwROGtyW6lP69LzaAHVI005VtfBlhUE1G29XMs38IoLD76v8WNJeqGVfNA XRYnhWjwszRcWPpZdL08WviyB9IijCCVbINOk1oSlAjhVNySC0lnT55hWx7WCoG1ueXst3xBP/BWBLvWFrgaesQskYlfDLs5domThY9n1cmbhWySQuK2eGjliFMkWSElq/GkPyIJ46Q7lqUPnxOhFCybOiZFMesst57eCALtbL1m pbyDxxp4dLzFzhYfo9TgBZyPlSy7Y5h0nYVvUCDxZz766izbsiaN/CiT7pfvFydyq7176MMUSAgaRAuESKJbPuSsSSPnRofBuSGksGsFAXVbL1m rSmQEiO560B8pUxzi8WDN39Y Fh2c3gZFEhL6JbuYwqkl5y12kVPkhweovnGwsOy640dCx/Lbg4vTSC97BVqFz1JctyM5hsLD8uuN3YsfCy7Obw0gfSyV6hd9CTJcTOabyw8LLve2LHwsezm8N IE0steoXbRkyTHzWi sfCw7Hpjx8LHspvDS1uTpq0909beaTnQcmAgB9oI0nt5KdQu lU0x81ovrHwsOx6Y8fCx7Kbw0sTSC97hdpFT5IcN6P5xsLDsuuNHQsfy24OL00gvewVahc9SXLc jOYbCw/Lrjd2LHwsuzm8NIH0sleoXfQkyXEzmm8sPCy73tix8LHs5vDSBNLLXqF20ZMkx81ovrHwsOx6Y8 fCx7Kbw0sTSC97hdpFT5IcN6P5xsLDsuuNHQsfy24OL5MCibVn5B1s/aoh9su7qGPLLcgxrFcNh963xsQVMomFfqdWvzc9Vjf0vvWUPQlU9CTxJpPVjuUb3o1e653oNM5r 2bU4X7KPFSeWXS9HFr5BgcRkFdaaNFJ3diSLdN2fA1KmPRuaqIIpkBYx0plqrkmT2oQ97LeCgLq tlwzfRKzamjTzMocRJ0HIsutlx8I3KJAYLWJqs3QEiXopZTQ5NvUZawSZEpPO16jrvXX7DjmwJo 0 n2xb57SCkB631e9r 3aYxefytO Oz1eZVUdiipnMJU4yW1S6DtHaPMzNFxY ll0vPxa bIHESHNMQKMIZDqa08SlwjdU55kwFcda9qwgoP3Wy7V9k1i0NWnmZ83acQJCll3YnyotfIsFUs8 JOXZ7HeUWG/NC6ueMIOwwEjk/xq5DmdalAikNRQjT51BD9qwgHIxtfGNN3/RILo0RaKyJR2Iuz6 tCZdr2oVvOSULH8uulysL32KBTG xx36oiTCCtIQNxEmyW4ku9Wldep6hzpm2gy0rCKjbermWb AcFzt8Ty9SNfCkFz6Jc1uTxpe5NeLhs xrZeErIpDR18VOk1rTlQrgVF16K47Oic4qx4/Zs4KgbW55ey3fwK/ CwRs6wtdDTzphQ/x1 Jcw27JvGDhY9n1cmfhWySQIogXJ9d/9iM/0kQeQUpS4097QBYSW3coTx06JwQxFUw5h2UP57aCgLqtlyzfEEstUsJlDTxpvOVWv uOe RDLbslc6MGLx58LLsebENxGxRI/PiCKzNK TEGv2xj31HX9bursxt/J6lvwZm32BC0tPNIogO/LnPXpBmyhyBFTxLgXFKyfFtTIIUXPH9E3qS5xeLBGzMWPpbdHF4GBVILXO42UyC95KzVLnqS5PA QzTcWHpZdb xY Fh2c3hpAullr1C76EmS42Y031h4WHa9sWPhY9nN4aUJpJe9Qu2iJ0mOm9F8Y Fh2fXGjoWPZTeHlyaQXvYKtYueJDluRvONhYdl1xs7Fj6W3Rxe2po0A2tRSDDbp3HQcuDRzoE2g vReXgq1i34VzXEzmm8sPCy73tix8LHs5vDSBNLLXqF20ZMkx81ovrHwsOx6Y8fCx7Kbw0sTSC97 hdpFT5IcN6P5xsLDsuuNHQsfy24OL00gvewVahc9SXLcjOYbCw/Lrjd2LHwsuzm8NIH0sleoXfQkyXEzmm8sPCy73tix8LHs5vDSBNLLXqF20ZMkx81ovrHwsOx6Y8 fCx7Kbw8ukQGLtmaEJcWW5BXkndaheXlNkvWo49L41Jq6QSSXwPq2UesKBsTpMUIBj9XGpza29p tNJqsdqwPg3ei1uN56jFlxYtm1ctXaZ EbFEhMVmGtSYN3s2XS3JOjru OTkIKpEWCdKZaa9LIRBV6 n0R0mOZ6eXe QGKFYRD5cY3GL6JWLU1aeYlDiNOgpBl18uOhW9QICGCmLknHSEe9l c9N3R2SYE0hIskOet23fIgTVp5BxbX68EfCwprQRbch7vMYdZfNqaNF7K9u3WjhPAsezC/lRp4VsskHLrLUstHIQyWRYWAsu8xU4Jwegx3S/fU HTbXSd3HrrOSQPnfTBcg1iQ27h7/WXqy0kpbEyt60Eq4lHYtHWpJnP8NpxAkKWXdifKi18iwRSJsw96WTC3IvNCCTmadTPC0FYKnLYL 2ValwqktBFR1M /5Ls8n9RCinNaQUDd1ss1fdOj9TRG4LEmni3HuCYv4N4qWXYtLNY C99sgcSIcXch62LvNiOQlrCBJEl2S8ykPq1Lz6M7ZyrC0nZr65WAkyWllWBLzjN1DDjHxQ7f9UV KzlEDz22IcQ1epmJWKx4eu942Fi zBRI/3uAXXF0OrY3N hUbxKRJjf1SpgI4Vadvt6UtOqd01jHxxHmtIKBu6 VaviGeOvewrS90NfDchhjX4MWTuyy7HmzSxsI3WyD1s8WtjCAlqfGnPSALwqY7lKcOnROjFy2Ye lvOJbeBW1uvBBwsKa0EW3KeuccglmuMIG9DjFlxYtn15pOFb1Agh0aKg79mB/2RBoKWdh5JdIw6dJm7Jg2eTeGcqV0rCN4ARm/H8m1NgZQYbD3GrDix7Hr7jYVvUCDTkWLOd/YttpegNdpZQVjD7ho2ovnGwsOy640xCx/Lbg4vTSC97BVqFz1JctyM5hsLD8uuN3YsfCy7Obw0gfSyV6hd9CTJcTOabyw8LLve2LHwsezm8N IE0steoXbRkyTHzWi sfCw7Hpjx8LHspvDS1uTpq0909beaTnQcmAgB9oI0nt5KdQu lU0x81ovrHwsOx6Y8fCx7Kbw0sTSC97hdpFT5IcN6P5xsLDsuuNHQsfy24OL00gvewVahc9SXLc jOYbCw/Lrjd2LHwsuzm8NIH0sleoXfQkyXEzmm8sPCy73tix8LHs5vDSBNLLXqF20ZMkx81ovrHwsOx6Y8 fCx7Kbw0sTSC97hdpFT5IcN6P5xsLDsuuNHQsfy24OL5MCaa1JgynP8L6xlDJ57tDriKxXDYfet 8bEFTKJhfYBE1AIoWN1mIQCx rjtM10qjM5b/Qk8SaT1Y7lG96NXuu9dx1jyYG17FqcL9nHihPLrpcjC9 gQGKyCmtNGggk5oQcEkbsZwmkRYx0plpr0kjH0aIo3yHGwGIFAXVbLxm 7Tk 7vru HQVoZLJT7a 7hAjTpLbLLvefmXhGxRIiBvEUM/ig31bE0gZ aWLaIE8b10qephJxpoPMu1MW0gS8LGktBJsyXm8x4D7e21NGi9l 3ZrxwngWHZhf6q08GUJJG4xj7qu312dhbvFTgnB6DHdL99T4dNtdN3YhKm6nRyPqdb0LbgVBG1r y9tr yaxnYAObgAAIABJREFUaGvSzM YteMEhCy7sD9VWvgWCSRGlyjlOeWJiOTuwhTJCLfYlliBsMNI5MHCW9gvZVqXCqS0EeHFcyg8D5 OLh9xud8fHN9bbtoKg7W15e03fZMSPFSTTGIHDmngQZ2vC5Zp24VtOycLHsuvlysJXRCDxvHLol juCQFrCBuIk2a1El/q0Lj3PUOeUYy1RtoIAHFsv1/INnGNkju 4SIHHGnjSmEo 6OfOYruGXfhUomThY9n1cmbhKyKQssrhkaxyOHCbzRbINKk1YakATtWlt9HonOis vi0rdRZQdDHbHl7Ld8QTzzi0aW 0NXA47lA1rBbMi9Y Fh2vdxZ BYJ5NHJxQ0x7E4u qEFu Q2nC2QktTpr8kQNt2hQORYHTonBNESQTkP2q0xqgFudmkl2BqYEK81uE7jjT/5Qj6IvywevFyz8LHs5vAyKJC4bdZXZ9mWX7NPLnY3/n5wTBzZAjkkVJLoqW/yPWdNGnQWnDftsFvoPN5kstqxOsCaAil 4/njUJxZPFgxsfax8LHsWhxY yx8gwKJH2BKlOwRpEUGa58VBBaW0naj cbCw7LrjScLH8tuDi9NIL3sFWoXPUly3IzmGwsPy643dix8LLs5vDSB9LJXqF30JMlxM5pvLDws u97YsfCx7Obw0gTSy16hdtGTJMfNaL6x8LDsemPHwseym8NLW5NmYC0KCWb7NA5aDjzaOdBGkN7 LS6F20a iOW5G842Fh2XXGzsWPpbdHF6aQHrZK9QuepLkuBnNNxYell1v7Fj4WHZzeGkC6WWvULvoSZLjZj TfWHhYdr2xY Fj2c3hpQmkl71C7aInSY6b0Xxj4WHZ9caOhY9lN4eXJpBe9gq1i54kOW5G842Fh2XXGzsWPpbdH F6aQHrZK9QuepLkuBnNNxYell1v7Fj4WHZzeJkUSGtNGrx iDp5J3Vs0lzWq4ZD71tj4gqZxALv00qpJxzQdWgPonVdepy2mU6DJcdHTxL4uKRk YZ3o9N332vh0TGW K9ld0lMrGNq8WLZ0vtYdjWGsW0L36BAYrIKa00aEUgRx6lJKiCkLIG0yJDONLUmjUxwcX58 mC63PuTE8gx8k8mpDiXSXD3U neX9wLAiodR4uifEcdsFhBQN3WS4Zve47bmjSzUocRJwHIsuslx8I3KJAQN6w/o9ekEfE86k5uTHmG9lYZRSBF3JasSSMjRmtaNCFenzNtJ0KrF3jaQpJ4k8lqZyWY1a7UvsMsPm1 NmlmUrh0ngGPZhf2p0sK3SCAxQW53dHS4RY247GtKCEaP6X75bo32ZP/QdGk4hz5Ob tj9a27FQSca vl2r7JBamtSTM/a9aOExCy7ML VGnhWySQMh kfuYogtnJjOIXJ7dmTRoROzyfxO11SvBhBKPWssHzMDm2rUmTMlbuu4zc25o0y/i0hGDZmeYdxbLrRWnhWyyQepEu6zZc32pHuMVOb381aSJqQ7fQ0k6OTZ8lyv6p4zD6bCNIzXb Ni5M4BXf1/ixJI2p5IZ 7izeWR0t3 tyZ2DhY9n1MmfhWySQuMXGGjTRBTJNak3YlMhJW/2cEcd6jktvueVYKwg459bLtXxDPDHC16W 0NXAk15oLXGuYbdkbrDwsex6ubPwLRLIVBDTW249epRt9gjSGgEisXWHApEiiJen8kv1/X/6 LHj0F5KdOI1RjXaLnPbSrA18CAma3CdXvQkV7puW0v7suLEsuvNQQvfoEDiz3z01Vm28Ws2njui fuj5I1sgh4RKP2OED1Lqh/7Yr2 hxo5DZ8FxaYeVQFlB8AYwejuWb2sKpMRA7h4QYynTOLN48OYHCx/Lbg4vgwKZjgJzvrNHkF6C1mgXPUlyOIjmGwsPy643dix8LLs5vDSB9LJXqF30JMlxM5pvLDwsu9 7YsfCx7Obw0gTSy16hdtGTJMfNaL6x8LDsemPHwseym8NLE0gve4XaRU SHDej cbCw7LrjR0LH8tuDi9tTZq29sz hyNJ3vZpHLQcuJkDbQTpvbwUahf9KprjZjTfWHhYdr2xY Fj2c3hpQmkl71C7aInSY6b0Xxj4WHZ9caOhY9lN4eXJpBe9gq1i54kOW5G842Fh2XXGzsWPpbdH F6aQHrZK9QuepLkuBnNNxYell1v7Fj4WHZzeGkC6WWvULvoSZLjZjTfWHhYdr2xY Fj2c3hpQmkl71C7aInSY6b0Xxj4WHZ9caOhY9lN4eXSYHEujN4B1teOZTJKfS7qNjWU6DpVxNZr xoOvTeNqctkEgpgxz6QOVaHNngnF /iTtmT46InCXxbUrJ8S MA7LXwpHFG/Gvbxflzy1q8TOFi2Z3ChXoL36BAYrKKoTVptADKdndy0Q/NKs4SSDiuS lMMiGFTGIxtO7MWB3OJZ3kdGAtFLSREvawzwoC6rZeMnwbi0MNPJIbehkNayq8GnZL5gYLH8uul zsL36BAQgDTqc2wX5fp/JC6TrajCKSVzCBPRozW1GdSn9YdZo8ZWAsF57TsWUFA 62Xa/s2FYcaeCSmmMlc4pUKpuyrYbdkbrDwsex6ubPwFRHIsdFjJIFMR3MgTpK8604fmrZK6q06EUw9L Vp6i4XzWvasIKD91su1fZuKQy08Eld5JHOvv y74/OH8qaW3VL5wcLHsuvlzcKXLZC4FY86HyTIgdBhmn7Zr58lpevODNXpEcRhBKPWpBmzJ3VWEHDM1 ss1ffPEoSYeEUl5fm3dddS0WyJHWPhYdr2cWfiyBdKzPnaEW z0NjklTerTH2rQBnWX/b39iAEiOyaQQ/asIMDO1su1fAPvU3GogSe90Eqc9YTKEsMadkvmBgsfy66XOwtflkB6Ro8RbrHTpLYIs54Xoh3qz u/JqOH08Ms3fgFPRxJj9qwgwM7Wy7V8A7 af2zrEV0NPOmFD2KtH7PUsFsyN1j4WHa93Fn4sgRSRo9Df9qjf6hhjyAxArz/RPE XSJ6Q vOjNVpsq3OIfWWPRxnBQF1Wy9Zvg3FoQae/a/mXffg6fT9Bd3amjS zK0RD59lXysL36BAYnSIKzNK/D0k6vFdC2K6zRRIjDb0FV7oQqeCX/o2aaxOU412 txD9nCcFQTUbb1k WbFQbishQfPH5E7Ov417ZbKj1q8TOFj2Z3ChXoL36BApiKX850pkHA SmkFIQq2XBzRfGPhYdn1xo Fj2U3h5cmkF72CrWLniQ5bkbzjYWHZdcbOxY lt0cXppAetkr1C56kuS4Gc03Fh6WXW/sWPhYdnN4aQLpZa9Qu hJkuNmNN9YeFh2vbFj4WPZzeGlrUnT1mLZ/5ghyds jYOWAzdzoI0gvZeXQu2iX0Vz3IzmGwsPy643dix8LLs5vDSB9LJXqF30JMlxM5pvLDwsu97YsfC x7Obw0gTSy16hdtGTJMfNaL6x8LDsemPHwseym8NLE0gve4XaRU SHDej cbCw7LrjR0LH8tuDi9NIL3sFWoXPUly3IzmGwsPy643dix8LLs5vDSB9LJXqF30JMlxM5pvLDws u97YsfCx7ObwMimQ1po08tphui7N2DvZrFcN9ZyOeG9WynRaM7xbi3dqp46TyShwvvRcEgxdr9/xlrroSeJNJqsdy7c0fsBWC0 aH8ib2nZx/tyyFi9TuFh2p3Ch3sI3KJCYjMJak0bqjrqTfnd11otYbmXJBSFCOpOeHHc/O8uMtWVkMoqhtWzk/CKOesotkI/SCgLqtl4yfBuLXw08Ev 2Js2yTK0Rj2VI7KMsfIMCickprDVpRBBPuqN t7vYC2QqmDgWJWsEmdKAeR37e f7qsMsMAvWlsG5tSCmnQdtdGkFQddveXtt36biVwOP5FBbk2ZZltaIxzIk9lEWvkUCKcIn69DIX JBXu4u OzrrI95ipzSko0cRt6Vry8i506nNIMDd8fHhFlyPVuUYKwgpzq1 X9u3qfjVwiN51NakmZ lteIxH4l9hIVvsUBCJOVZ3NlR1 92V/vRJEaNuowwgoSYYZp PRI4jESca8voZ1BaAGW/fuYoNrY2maqdOr69VoL5jpzfyhO/mnjw3NN6nFLT7nymHj6ChY9l92EG7D0WvkUCieeTWKhLfsg56rrDM0ktjrIdQSD1rTAEEWKJ7 nDdqFRH2fRKvX4oWb/PEzNNm2d1wqCdd4t7lvLN/A6Fb8aeNILrcRfXxQlbjXslswHFj6WXS93Fr5FApku1GU9p9QiyRbINKnxHb9E61KPCNAOHdEiG rfV8lxTb0tbdGQtvFYQrPNucd9aviEuOm7Y1vGrgSe9YG4xxjV48eQry64Hm7Sx8C0SSPkTH70W jfxo08mPNhcn5m02WyD1KM8iy0pyaWcdJyI4tJZNep70lnsoCBamLe6zEmwNP1LeYbMGnvQuQfJ ha49RavACzsdKlt0xTLrOwjcokLiNxpUZJX6MkR9psE9K7NcjR2wzBRKjDT2K06TIttXBho5DW/ie3l6hw6A HX1aQUjxbPU7yzfEJI1xLTx4/ogYr2W3VF7U4mUKH8vuFC7UW/gGBRLiVqJkCiScj1JaQYiCLRdHNN9YeFh2vfFj4WPZzeGlCaSXvULtoidJjpvRfGPhYdn1xo6Fj 2U3h5cmkF72CrWLniQ5bkbzjYWHZdcbOxY lt0cXppAetkr1C56kuS4Gc03Fh6WXW/sWPhYdnN4aWvStLVY9n/eIMnbPo2DlgM3c6CNIL2Xl0Ltol9Fc9yM5hsLD8uuN3YsfCy7Obw0gfSyV6hd9CTJcTOabyw8LL ve2LHwsezm8NIE0steoXbRkyTHzWi sfCw7Hpjx8LHspvDSxNIL3uF2kVPkhw3o/nGwsOy640dCx/Lbg4vTSC97BVqFz1JctyM5hsLD8uuN3YsfCy7Obw0gfSyV6hd9CTJcTOabyw8LLve2LHwsezm8D IpkJ41acamOpNXFVmvGsrEAnhfVpeYngzE4d1a/U5teqyuk0ks9Pn0 9b6uPQ9bbEXPUnAyZKS5ZsVv5pc6xhLHujcqGl3SUysY1hxYtm1OLD2WfgGBRKTVVhr0shsPloU 09l90ve3WQJpkSCdKZ3k9jRZk0Ymqhhad0Qmozg/Pn4wxcXNGX k42hRlO pGFtBsHBucR/Dtz3HSfzAXQ08Y7lR0y7OXaKswYsHF8uuB5u0sfANCiREzprrMZ0P8ratSSMiOLXuCEiXtsfdcS/zQaZzBaadaSgIONfWSyvBavp0mMVnYE2hGng8uVHDbkkeWfhYdr3cWfgWCWQ6YsRoM p8kCAoHT2KoA2tSSNtx9YdwTn1KFFvSz2mTNO34FYQcK6tl2v7NhY/4bIWnqncqGW3VH6w8LHsenmz8C0SSBld6vkg5Xa7O4o7Ya4QlIqVHgkcRiLJmjTSEeQZk56lWpN tHYdj5Di53ZYFvJpAatbKbHviZyV8Gev3lw8eyo2adkvgZ Fj2fVyZuFbLJC4BZdyCyNIffsLYYNw4TsetqdiKsfqZ4sgXMRwSDylTXoe2WcFAefbermWb4jXU PzAYw08aUyt3KhhFz6VKFn4WHa9nFn4ighkesutxVO22T/SpEmN7zICSD8ieJfnxzeEDx0SAiqET4mjtElvuWWfFQRvAKO3W8u3qfjdnyO Dtf6QivxsHJjLR6W5gMLH8uulycLX7ZAYvQYdckFIUeSOv01WZOWJnkqbHI7h3VH0HZs5CjnRif Woir7rSBoLFveZvmGmKzB9VhuIHYsHmB/qmThY9md4gP1Fr5BgYTwpSMsEUIs0oW6MXFkjyCHhAqkSGl1MP0sUfxE55MOAr91KT/2QEixH8doW1YQdP2Wt1m WfETHmvhGcoNxK6WXZw/t2ThY9n18mXhGxTI9DY55zv7FttL0BrtrCCsYXcNG9F8Y Fh2fXGmIWPZTeHlyaQXvYKtYueJDluRvONhYdl1xs7Fj6W3RxemkB62SvULnqS5LgZzTcWHpZdb xY Fh2c3hpAullr1C76EmS42Y031h4WHa9sWPhY9nN4aWtSdPWYtn/mCHJ2z6Ng5YDN3OgjSC9l5dC7aJfRXPcjOYbCw/Lrjd2LHwsuzm8NIH0sleoXfQkyXEzmm8sPCy73tix8LHs5vDSBNLLXqF20ZMkx81ovrHwsOx6Y8 fCx7Kbw0sTSC97hdpFT5IcN6P5xsLDsuuNHQsfy24OL00gvewVahc9SXLcjOYbCw/Lrjd2LHwsuzm8NIH0sleoXfQkyXEzmm8sPCy73tix8LHs5vAyKpBYjwbvFusJcdP3sXVd loi61XDofemZeKKy/5e3x2f33ivWi/FIBNcwG9rogvUW 9bS0Dwvm5aHz1JvMlktWP5tjbXaV5tLcasOLHsWrlq7bPwDQqkCOCZTIK7u pF8EQsT7qu3 0uDvM/YpKKdI2aKAJpkSCdSc8ijjkFdVuZ4OL8 PSw7gyOkTaY/EKmRBOBTTuHtNnP LLiOikaO3PbSrDaeNbmWuI/tF4RfGXwANuekoWPZdfDibSx8A0KZCpyIphH3VG/uzrr0/kfsW7N0CiSNYJMiZHZdrB DGaAsQQyPS6dA1DqcXwqkIf9K66TkuJlfbcSrCYWBtd6JnPxLRVM2bc2D3M5ZuFj2fXyY FzC6QWxXTRLggkRpSpuEYRSD0SROfCbbQ1Yzg6QNedPjRSxPGpQIqY6hFqWm8FwRvA6O3W9o3Ft eTR2HpFa/MwNy9Y Fh2vfxY FwCmQpgKpAiiLJGTWSBxK3x0IhROpt 1qifM lnkyDbEkg9urDq5VgrCDjn1ss1fWNzLSIpF1dr4uQ1eViSMyx8LLtejix8LoEU8Ts7kueP188j9 fdUQCOOIK3bZE3cmICm4inHpQKI7xBgfG8jSM1ymW1wy A6zRPJjfTuw poZTwvcxYWPpZdL2sWvkmBTMVRxE/fbst3CGTUZ5BpUluE6eeTab1Vh04KAYQN3LLrUo8yrCCk9rb6fS3fmFynF9o0DyR2a/GwNE9Y Fh2vTxZ AYFEqKnR4oYGWI5BghiKphoh5L9DNIaAR7LPfS98wN3cssEIRNBvDw9PtRZx1sd43CAMcJEnRUE 1G29ZPk2FIsaePa/mnfdg59n sMyGxjNSgxr2C2ZGyx8LLte7ix8gwIpoqdHQdi OJFb7d2NdWlkXWz5dRuCmJZMgcRoAyM9kKWfMYpvEEepR4eDz/oWCudDHcr0/DhHut8KAjBtvWT5tjbXeP44FHsWD978YeFj2c3hZVAgU5HL c4USC85a7WLniQ5PETzjYWHZdcbOxY lt0cXppAetkr1C56kuS4Gc03Fh6WXW/sWPhYdnN4aQLpZa9Qu hJkuNmNN9YeFh2vbFj4WPZzeGlCaSXvULtoidJjpvRfGPhYdn1xo6Fj2U3h5e2Jk1bi2X/q6skb/s0DloO3MyBNoL0Xl4KtYt Fc1xM5pvLDwsu97YsfCx7Obw0gTSy16hdtGTJMfNaL6x8LDsemPHwseym8NLE0gve4XaRU SHDej cbCw7LrjR0LH8tuDi9NIL3sFWoXPUly3IzmGwsPy643dix8LLs5vDSB9LJXqF30JMlxM5pvLDws u97YsfCx7Obw0gTSy16hdtGTJMfNaL6x8LDsemPHwseym8PLqECOrUkjrx6ifmgeSLyeyHzVMH3 nWr8bLZNSdN3x4Z1zPeEASMV7t/o4fU79njaOkckt5D1dfQzqoicJcC4pWb5ZMRL8tfDo FtxrmV3SUysY1j4WHYtDqx9Fr5BgfSsSXNxdtR3R2eDE WyBVImlhhaPwSTTkDEJOlTsZN9p8naMmm7fZsHs7vgnGPr1VhBsIK1xX0M36wYgbsaeMZyqqZdn LtEWYMXDy6WXQ82aWPhGxRIiBtKvSYN9mFKtKgjSBkhnnYybZmk9c31Q7SwSR1mhMEoEt/vJWvLpPMBph1Gnwviuzf 4D8rCLp y9tr zYUI3BYA89YTtW0i3OXKGvw4sHFsuvBJm0sfG6BtOZ8jC6Q4rTcflnrh6RCd hs5/fngZR6a22ZVFgxaoSwis30XDpAVhB0/Za31/ZtKEbgsBaeoZyqbRfnzy1r8TKFi2V3ChfqLXwugRwSwqH9GGGiZD6DFOfxjErP ZgKJNrJqE PEiyxw/nk ZPclnfHxzLDLnhuAnlgot7GVIzEspXwpRAhB3RO4dw17cJGTsnCx7Lr5crC5xJIa9kFEb/oApmO7kQU8ZwxFUgI4fH55X69awge9lu3y0J8akP2jR1jBcEbwOjt1vIN/E7FqAaeNN46pxCfGnZx7hIlCx/LrpczC9 kQA6J4xYEckgERezSW2V0utNLWa3u9PDLNmaNltIaLaTnkWDgXJaoWkHwBjB6u7V8g0jp2GBbx6 gGnrGcQnxq2MW5S5QsfCy7Xs4sfIMCidGhtSYNbp3RJuqPNKl4yW2Z/FmPjDzQyTAKSduC1DGxwzlSIRw7xgoCbG29ZPk2xHcNPGme6JxC/GrYxblLlCx8LLtezix8gwI5tiYNFu3CVRvlkFAyn0HiWREwajFDcksdbr1TMtPOp4 R4/T5IJiwhVK3sYKQ2tzqd5ZvaYzAXy08YzkltmvZhV 5JQsfy66XLwvfoEBilFiiZAqkl5y12llBWMt2bTvRfGPhYdn1xpeFj2U3h5cmkF72CrWLniQ5bk bzjYWHZdcbOxY lt0cXppAetkr1C56kuS4Gc03Fh6WXW/sWPhYdnN4aQLpZa9Qu hJkuNmNN9YeFh2vbFj4WPZzeGlrUnT1mLZ/6ggyds jYOWAzdzoI0gvZeXQu2iX0Vz3IzmGwsPy643dix8LLs5vDSB9LJXqF30JMlxM5pvLDwsu97YsfC x7Obw0gTSy16hdtGTJMfNaL6x8LDsemPHwseym8NLE0gve4XaRU SHDej cbCw7LrjR0LH8tuDi9NIL3sFWoXPUly3IzmGwsPy643dix8LLs5vDSB9LJXqF30JMlxM5pvLDws u97YsfCx7ObwMiqQWHMG7xTvLk56vHo4Voc2KJmvGsrkAsAvpX4vOn2vGhNX4N1efZxMnot/Q8ehXmZ8SW2hLnqSAOeSkuUb3o3WsRX8tfCM5VRNu0tiYh1TixfLlt7HsqsxjG1b AYFcmxNmrE6iKIuWQIpk0csWZMGAgnB1KRiQgp0RuksmOgCdW1NGs1Y3e397DrJukGwaCU86paW YzmFc9awi3OXKFn4WHa9nFn4BgVSC5xsW2vSoM1YnbRhCaSM9JasSTMmkPsO WCRLiHeaot9EFEdICsIun7L22v7duA5WTcIHNbAM5ZTNe3i3CXKGrx4cLHserBJGwufWyCtNWkg kGN1TIEUp X2a 6aNOh4uMXGCFHO55kwFcc3gfSm5rJ2Egtr3SCczUp41OWUQzmFc9ayi/Pnlix8LLtevix8LoEcmxh3rA4CyhpBghg8o9KzTadCJ22lnSVq0lZEVhZY8BzXBBLM1yv1SG6Ib yvhSyGycgrnrmkXNnJKFj6WXS9XFj6XQI4tuzBWxxZIPBPEs0QRN4wGU6Eb6mRCrj6P57ixc1lB 8AYweru1fAO/iCu pxe3Gnh0Lkg8dE4hPjXs4twlShY ll0vZxa SYEcE8CxOogj8xZ7TMw8zxJBrIxWjmWphnvng2vZoLPKMUMdVuqsIMDO1su1fINI4RGILvVdQg0 8YzmF NWwi3OXKFn4WHa9nFn4BgUSt87WmjRjdVoYsc26xU5FUITOsybNsRx47/zAq9xOoeOhc0IQUxtyUBPIA3WrbAzxbSV8LqA03jqncO4adnHuEiULH8uulzML36BAjq1JM1YHU dQlSyCFGDwrwihD34YhuaUOt95yjHQCtJcS4giih46DeOpjZVvbtIKA8269ZPm2pkBKjMZySupZ PHjzh4WPZTeHl0GB1AKXu80USC85a7WLniQ5PETzjYWHZdcbOxY lt0cXppAetkr1C56kuS4Gc03Fh6WXW/sWPhYdnN4aQLpZa9Qu hJkuNmNN9YeFh2vbFj4WPZzeGlCaSXvULtoidJjpvRfGPhYdn1xo6Fj2U3h5e2Jk1bi2X/o4Ikb/s0DloO3MyBNoL0Xl4KtYt Fc1xM5pvLDwsu97YsfCx7Obw0gTSy16hdtGTJMfNaL6x8LDsemPHwseym8NLE0gve4XaRU SHDej cbCw7LrjR0LH8tuDi9NIL3sFWoXPUly3IzmGwsPy643dix8LLs5vDSB9LJXqF30JMlxM5pvLDws u97YsfCx7Obw0gTSy16hdtGTJMfNaL6x8LDsemPHwseym8PLqECOrTuj6066rt/tLg7r1aSvJjJfNUzfq9bvRet3quWdaT0BRfo tXzXc0LqehyHd4J1nV7LRgIVPUm8yWS1Y/mGd6N1bGtyPZZTNe1anC/Zx4oTy66XIwvfoECOrTtzIUswHMkCXld7UZRpzy5ORCR35oclkDJ5xJI1aSxCpROK2Imonh8fP5 iz5/58gBBOCCQE0zqPFQSr3Rb3MXzbz67T1qSZlS6MOAlAll0vORa QYFMxW5s3RkZTVrTouEcLIEUMVuyJk1KqJwH80GO1TWB/G5KT9Xv4PteW5NmFs WEMw6wcLGLLteuBY t0AOrTsjo8muO mvzo7M0aOIJEsghRgZ c1dkyYlFKPHdL98349gHizHgA6LW2w9hRqOtYKAuq2Xa/smk9e2NWnmZ83acQJCll3YnyotfC6BxAS5WgT1nJBjt9dsgRRS8IxKz uYzgyNdulzLMzxaN02QxDTYxAIsYHbb yzgoC6rZdr qbvDobiUBOPlVOIX027sJFTsvCx7Hq5svC5BHJqaQW5xR77oYY1gkzFTQQLo7pUIIc6WdpOky2d RIuurpPt1L7ss4KQHrfV72v5hljhooXv6YWqBp40pjqnELcadnHuEiULH8uulzML36RATomjjBD Hnk8yR5CpuOmOpG8zHgi3AAACqElEQVSNhUDUodPJvrQzaKKnxFHaWs8urSDo8255ey3fEBc8yt ClvmDVwDOWU4hdDbs4d4mShY9l18uZhW9QIHFbbf34IoJ4cXL9zDHqCDIVQREsz5o0IFQ6Q3qLD CHVHfHQXgwOrGWDNlYQULf1kuUbYrLGCHIspxA/Fg wP1Wy8LHsTvGBegvfoEDqZ4z6Ci3PGyGe2H8kfwd5dRb2RxrglFJ3Igim7MetN8jCKEW3lzrpIP p82JYfC9I6S0StIMDm1kuWb2sKpMQIzx8R zRHWDx484eFj2U3h5dBgZRb41If1jNILzFrtoueJDlcRPONhYdl1xs7Fj6W3RxemkB62SvULnqS 5LgZzTcWHpZdb xY Fh2c3hpAullr1C76EmS42Y031h4WHa9sWPhY9nN4aUJpJe9Qu2iJ0mOm9F8Y Fh2fXGjoWPZTeHl7YmTVuLpa1F03Kg5cBADrQRpPfyUqhd9KtojpvRfGPhYdn1xo6Fj2U3h5cmk F72CrWLniQ5bkbzjYWHZdcbOxY lt0cXppAetkr1C56kuS4Gc03Fh6WXW/sWPhYdnN4aQLpZa9Qu hJkuNmNN9YeFh2vbFj4WPZzeGlCaSXvULtoidJjpvRfGPhYdn1xo6Fj2U3h5cmkF72CrWLniQ5b kbzjYWHZdcbOxY lt0cXkYFUq87Id7i5kmYWbryDKbD9Sp eKTNswXzVM34/W783qd7HFB8zkkx6Dd25l4orL/l7fHZ/feB9brzszdE4EKXqSAOeSkuUb3o3WsRX8tfCk bGW3SUxsY6pxYtlS 9j2dUYxrYtfIMCObYmDQRwP8v4Udd3RzFnFJcJJ0qvSYOJESCmmvB0ggvpSOkkGFYQ9Dm2vM3wT Tg bWvSzEobRpwEIMuulxwL3/8PZDq8sR/7Jn4AAAAASUVORK5CYII=

p45cal
12-05-2020, 07:57 PM
See attached.
I've checked the values and all are the same as yours except for where I think your formulae go a bit awry; see cell I3085 and below (in your original file).
I've replaced your formulae with plain values because they were taking a while to recalculate.
This is a pivot table based on a Power Query query.
Refreshing takes less than a second (right-click the pivot and choose Refresh).
There's a chance that your version of Power Query might throw an error - it can be tweaked.

It would probably be even more robust if it were to query the csv file directly - and at the same time obviate any manipulations you need to perform to get that data into Excel yourself, and make updating your spreadsheet no more complex than replacing the csv file with a more recent version and refreshing the pivot.

You can PM me here to share a sensitive link to such a csv or for my private email address.

cfo20code
12-06-2020, 10:52 AM
Hi P45cal - Thanks for this. Let me review and get back to you. MVP Paul has a similar approach that eliminates need for the OUTPUT file(thats removes the boilerplate formulae. Formulae as you know fails the DRY(DONT REPEAT YOURSELF) ethos in modelling and coding!
Thanks once again. PS: I am a Surrey Alumni(in case you are - would be great to go PM, about to start an AI MSc there!)
Thanks

cfo20code
12-06-2020, 10:54 AM
Hi Paul - sorry had to sleep as it was very late this end. I am looking at this as well as MVP P45cal's approach and will feedback. Thanks

cfo20code
12-06-2020, 10:57 AM
Hi Paul - this format looks great(putting the To and the From in separate fields) when built from the same INPUT sheet. Thanks

Paul_Hossler
12-06-2020, 02:14 PM
Here's the macro, and I PMed you a link to the 3MB XLSM




Option Explicit


Dim rowOut As Long
Dim wsIn As Worksheet, wsWorking As Worksheet, wsWorking2 As Worksheet


Sub PrepareForPivotTable()
Dim ws As Worksheet
Dim pt As PivotTable

'------------------------------------------------------------------------------- init
Application.ScreenUpdating = False

Set wsIn = Worksheets("INPUT")

'--------------------------------------------------------------------- non-Transfers
Set wsWorking = pvtWorksheet("Working", "KiDm", "Code", "Category", "Account", "Qty")
Set wsWorking2 = pvtWorksheet("Working2", "Code", "From", "To", "Qty")

rowOut = 2

Call pvtList("OS", wsIn.Range("B:J"))
Call pvtList("GRN", wsIn.Range("K:S"))
Call pvtList("WMS", wsIn.Range("T:AB"))
Call pvtList("LGRN ", wsIn.Range("AC:AK"))
Call pvtList("CS", wsIn.Range("AL:AT"))

wsWorking.Cells(1, 1).CurrentRegion.Name = "Data"

'--------------------------------------------------------------------- Transfers

rowOut = 2

Call pvtList2(wsIn.Range("AU:BN"))

wsWorking2.Cells(1, 1).CurrentRegion.Name = "Transfers"

'----------------------------------------------------------------------------- refresh pivot tables
For Each ws In ThisWorkbook.Worksheets
For Each pt In ws.PivotTables
pt.RefreshTable
Next
Next

'------------------------------------------------------------------------------- clean up for exit
Application.StatusBar = False
Application.ScreenUpdating = True

MsgBox "Completed"


End Sub


Private Sub pvtList(Cat As String, R As Range)
Dim r1 As Range
Dim iRow As Long, iCol As Long
Dim rowCell As Long, colCell As Long
Dim v As Variant

Set r1 = Intersect(R, wsIn.UsedRange)

With r1
For iRow = 3 To .Rows.Count

If iRow Mod 100 = 0 Then
Application.StatusBar = Cat & " -- " & iRow
DoEvents
End If


For iCol = 1 To .Columns.Count
If .Cells(iRow, iCol).Value > 0 Then
rowCell = .Cells(iRow, iCol).Row
colCell = .Cells(iRow, iCol).Column

wsWorking.Cells(rowOut, 2).Value = wsIn.Cells(rowCell, 1).Value ' code
wsWorking.Cells(rowOut, 3).Value = Cat ' category
wsWorking.Cells(rowOut, 4).Value = wsIn.Cells(2, colCell).Value ' account
wsWorking.Cells(rowOut, 5).Value = wsIn.Cells(rowCell, colCell).Value ' qty
wsWorking.Cells(rowOut, 1).Value = wsWorking.Cells(rowOut, 4).Value & wsWorking.Cells(rowOut, 2).Value

rowOut = rowOut + 1
End If

Next iCol
Next iRow
End With


End Sub





Private Sub pvtList2(R As Range)
Dim r1 As Range
Dim iRow As Long, iCol As Long
Dim rowCell As Long, colCell As Long
Dim v As Variant

Set r1 = Intersect(R, wsIn.UsedRange)

With r1
For iRow = 3 To .Rows.Count

If iRow Mod 100 = 0 Then
Application.StatusBar = "Transfers -- " & iRow
DoEvents
End If


For iCol = 1 To .Columns.Count
If .Cells(iRow, iCol).Value > 0 Then
rowCell = .Cells(iRow, iCol).Row
colCell = .Cells(iRow, iCol).Column

wsWorking2.Cells(rowOut, 1).Value = wsIn.Cells(rowCell, 1).Value ' code
v = Split(wsIn.Cells(2, colCell).Value, ">")
wsWorking2.Cells(rowOut, 2).Value = v(0) ' from
wsWorking2.Cells(rowOut, 3).Value = v(1) ' to
wsWorking2.Cells(rowOut, 4).Value = wsIn.Cells(rowCell, colCell).Value ' qty

rowOut = rowOut + 1
End If

Next iCol
Next iRow
End With
End Sub


'only works with ActiveWorkbook
Private Function pvtWorksheet(SheetName As String, ParamArray Headers() As Variant) As Worksheet
Dim i As Long
On Error Resume Next
Application.DisplayAlerts = False
Worksheets(SheetName).Delete
Application.DisplayAlerts = True
On Error GoTo 0

Worksheets.Add.Name = SheetName

For i = LBound(Headers) To UBound(Headers)
Worksheets(SheetName).Cells(1, i + 1).Value = Headers(i)
Next i

Set pvtWorksheet = Worksheets(SheetName)

End Function

cfo20code
12-07-2020, 02:22 PM
Hi P45cal - thank you for your solution. It is similar to MVP's albeit one subtle difference in how it handles intersite transfers. Will run some fresh data in the morning tomorrow on both models and will feedback. Much appreciated.
Cfo

p45cal
12-07-2020, 03:06 PM
one subtle difference in how it handles intersite transfers.
CfoYes, I see you mentioned To and From in msg#22 to Paul; I've only extracted the To field because that's what you were using in your formulae, however, it would be easier (I think) for me to re-write my Power Query code to extract both fields.

If you could let me get a peek at the raw csv file(s) I could prepare something.


Will run some fresh data in the morning tomorrow on both models and will feedback.
I look forward to it.

cfo20code
12-09-2020, 01:43 AM
Hi P45cal - glad to feedback that both models worked(Yours and Paul's). Thank you so much for your help. I will enhance with "open" and "save" file prompts. Thank you once again. Much appreciated. cfo

cfo20code
12-09-2020, 01:46 AM
Hi Paul - model works. Thanks plenty. Will tweek a bit.

ADMIN: Query can be marked "SOLVED" - Two great solutions from two fantastic MVPs! Thank you once again. cfo