From e59aa0241fe5087a823c48f3cae4b6ae95b9f0ef Mon Sep 17 00:00:00 2001 From: Sebastian Zell Date: Sun, 25 Jan 2026 23:21:52 +0100 Subject: [PATCH] Version 1.2.1 --- .abacus.donotdelete | 2 +- .gitignore | 46 - CHANGELOG.md | 31 + CUSTOM-ATTRIBUTES.md | 56 + CUSTOM-ATTRIBUTES.pdf | Bin 31318 -> 40551 bytes TEST-RESULTS.md | 143 + TEST-RESULTS.pdf | Bin 0 -> 35124 bytes .../LibreBookingApi.credentials.d.ts | 15 + .../LibreBookingApi.credentials.d.ts.map | 1 + .../LibreBookingApi.credentials.js | 63 + .../LibreBookingApi.credentials.js.map | 1 + .../LibreBookingConfig.credentials.d.ts | 14 + .../LibreBookingConfig.credentials.d.ts.map | 1 + .../LibreBookingConfig.credentials.js | 76 + .../LibreBookingConfig.credentials.js.map | 1 + .../nodes/LibreBooking/LibreBooking.node.d.ts | 12 + .../LibreBooking/LibreBooking.node.d.ts.map | 1 + dist/nodes/LibreBooking/LibreBooking.node.js | 1667 +++++++++ .../LibreBooking/LibreBooking.node.js.map | 1 + dist/nodes/LibreBooking/librebooking.svg | 28 + .../LibreBookingTrigger.node.d.ts | 14 + .../LibreBookingTrigger.node.d.ts.map | 1 + .../LibreBookingTrigger.node.js | 593 ++++ .../LibreBookingTrigger.node.js.map | 1 + .../LibreBookingTrigger/librebooking.svg | 28 + nodes/LibreBooking/LibreBooking.node.ts | 3010 +++++++++-------- .../LibreBookingTrigger.node.ts | 499 ++- package.json | 2 +- test-api.ts | 609 ++++ 29 files changed, 5233 insertions(+), 1683 deletions(-) delete mode 100644 .gitignore create mode 100644 TEST-RESULTS.md create mode 100644 TEST-RESULTS.pdf create mode 100644 dist/credentials/LibreBookingApi.credentials.d.ts create mode 100644 dist/credentials/LibreBookingApi.credentials.d.ts.map create mode 100644 dist/credentials/LibreBookingApi.credentials.js create mode 100644 dist/credentials/LibreBookingApi.credentials.js.map create mode 100644 dist/credentials/LibreBookingConfig.credentials.d.ts create mode 100644 dist/credentials/LibreBookingConfig.credentials.d.ts.map create mode 100644 dist/credentials/LibreBookingConfig.credentials.js create mode 100644 dist/credentials/LibreBookingConfig.credentials.js.map create mode 100644 dist/nodes/LibreBooking/LibreBooking.node.d.ts create mode 100644 dist/nodes/LibreBooking/LibreBooking.node.d.ts.map create mode 100644 dist/nodes/LibreBooking/LibreBooking.node.js create mode 100644 dist/nodes/LibreBooking/LibreBooking.node.js.map create mode 100644 dist/nodes/LibreBooking/librebooking.svg create mode 100644 dist/nodes/LibreBookingTrigger/LibreBookingTrigger.node.d.ts create mode 100644 dist/nodes/LibreBookingTrigger/LibreBookingTrigger.node.d.ts.map create mode 100644 dist/nodes/LibreBookingTrigger/LibreBookingTrigger.node.js create mode 100644 dist/nodes/LibreBookingTrigger/LibreBookingTrigger.node.js.map create mode 100644 dist/nodes/LibreBookingTrigger/librebooking.svg create mode 100644 test-api.ts diff --git a/.abacus.donotdelete b/.abacus.donotdelete index 38b6e6d..ca30b93 100644 --- a/.abacus.donotdelete +++ b/.abacus.donotdelete @@ -1 +1 @@ -gAAAAABpdnAEuFDd_KhfRTdEd4TQYcJ3VUqLLSQetUEc3qUd9jk6d6jkfV9A4FYl8MaCHvhT1D0lCUykLvGXC1mF7XsdM0qLKdNZU9vCZvLwKxKJyD1ExUCIME30wyb7asAdlBbd6rHEb5f_dOs-VOZrofC8cmZbjw_hrNhuwmnXpQ1Gl9Di6J-jjWTbcA_0UhHYzS0XZfKd9IA6OkZHlN5fGBG5a6PYWsdFSbJJG-TjlqUAk-Igb-1SWVhOFPEX5IH7k_KVtblcsgtMiK9giF72ZwWeqBguIQh8wLnLOJ0RNcs1XRUr65tTq7iCmni8X7h1vXcxkaqqG8olBTG_f05KpUyKT7ndgjV2FB5XFqd94NwG4Ervjlq6qMuPYMaI0gON6esdRze8J90s4S04EohujpBq9LnR3BvgbP1nFuFbwSavxNqirKliShwCbt2DBeDCNwIPLh1a_Xl2vTomwxcEX-F9Os5wVfBkKCu-tRU2OZlxw5boGq-B0RZOU5gU90ZyoRFE_-9cySGboc5JLM5uT_CE3rmDLYngCBTHvP1oH1AaI5yJVCi2020EQPgcFF_Y5SSQl10tO60afqbhhfPmObH7Jf839ZcoViGAGSUQKHFU1aIXSqNtmBlCpeXMHw4KNDjvRX95ZDJb95CtcrUTVhW98gnB1Vw-iozmbrd5XKxlhcFv_Ge0h4rDkVQXtwKej_4D3T9xC2BQmHEM60NHSLc1As-Qd1t58kzc1H79zKral6ti1JsiUMS6Hl-oYlS9bz8ZTSyoPJ3JP553GxK5-v5YFSChW6xZkP22gH_ETDUDq32kU2Fn_X693UIamLjQrYYjyxrghnMcslVVodv39EkfJ434-GtZB9X80fUKXUDF6cmty2HWWsqy6MWkF7A-G_JdN0JE9URYeLlV2A0qP3eS16wi_DercbXujZTsn6IMzBSAG5efT80LmRWazwCYPgGMYscA0QxuBRcPaDlP3BrWVL7TiX6mBUqyP4Bisy4QrQZTjVDnAYp7KsNjx-WBDkXYL4G3Qni_I7pwI5ENjnx2fBUO24HgGG299Go4g-D9jjZ_-7tkKY8Z8siFGvfEVCNnLcSe8bX4Xh9JfXmaZM-AggqRyqNQ11iRUWF_T0uFECQeliU0D5DYAGmHuIPnfIczoyPtG-de4BD98BYLMrHYJMii3UTZ8io6iscH8ONFJlSoMPuGqbE-9ohoKiiLhemWTysZZc3AC7h_OA9-_WBwToM_NtTtiWGHOowanT2XLLfbECyu5lLHYki6O65ypmdXb8mHpvjeOY1tGNiBVUN_qCt3VGVBTOHRulWjsJztMW7escZg1t-_Nr4Zt2s1n5xczufsTvpQN8QPm4PmbLIZYSpJWQbyMMVUSMU6wbwF3fzf2Ah_O6CiMMeceWK7JelgGhNSvLn6tBgZa_xQaHJO6uVCyGCOeBrrr47xpyVDwgD8KaZgz7AAyrsFFE8_Zeq4lFPl1EAiJoEKd6_l-KrSxni7EmYmf54QLTNIzyK_GR-AvrcxJQm7MGo95urGUxUWFIztEaQ-e6qxJhyZdySf1gMxKcCh6kzBF6VAFSM2oicjPDca0Z6pJhrp1-WXb2AM9EETWOT1woqKSFiTrhFJxMczh01XaiGA1U9WK7Mpe7hl9h2XUB3S5frAEXtC833OMvno0w4EmqChhVpl5fW455Rg53zwtlURfGE2KH3_XrpSwtK4WKhW0NiJjkABx464OSiisC66xoiNEz1SA1BRXerRinwDnnPyRvXU6tHaYm8k9xXENARvdXk3HJP5IGSVbcFomOleBQoLVkUiQF5IO8HFGIB2vjlhg3_aJLKKqBASiLoeMzDDl026cpEZmMC3cSMdeOCC3-wTkljpVZSb-2KsH9-Savgu_Y1CoYxIB1um_Pg7iPcdcvqNKn6hBY1hwHybdCm7-WSsxNlfEDIxa_sZBuXiC035ZxQrBdkijFUM5Dt4MCOR6mRU5VBGguqKZRUUHLzkjFHxlmLtpiRCr6SWrySEGwcgIuN66wXdLQDViTjjn5ZjF61XGXYkG2MvJOQeHE8KNu-3XpZzMqMDCvH0xfEZHdQYGCHjNIyitLE73v5kmpFkWLQSYodoDk99IsCS2DNF_pH8qLLCeWqn2bWZT-vFin96WUdZzcorhxiwmi097VOcSEIUVqVl-b3x1Qn0fhOEJKLEmo7OHlZPbxpWe7hjOoSxQ5zJy98vVbbsDyoVpdmf3GMjjfy2XYRdcMpCnhC12IFFpmODk0jk50-rNls6SQQ0uDC20UFXsnOGkA_TkUc1FvZaMkvONrdmgDVgHBpD5mfWGh5KLC_dsnaGQ4V5GsKgc5b4a6pbozPATr7GTwK7q4g_ml2c8B4b2IZJmm9av07DAIwNdEA3NQqhDZKyd1MLzzeG9l3bR4CAbSflKw96qu2gcX2YKss5r77M23RSEQQDXBK4jR1D2o0BoSOM-Iv5JHNJ3LxbE0vil-pYZEnvvTUbPYRJAuoMQ_jyUHUjD0Wu1bT7YKpo7DItKNgR_OQB-2ixVY3OTeFu7dTJw62HZaaghMWmALqqfyGEzva8OArHtbGJBjLG_BLQ_21YnfMuP6Laujzd32tOw9wh4G0Zy1d9FTzQf7VTuFLoEG71IhEyPtsFNFn5trwgqLk_1NNmSwoEZl_ansKTqLAfILp9Onx8b4Cg0d8vs452mDEkZDhI7pdlKmU4-p2SoeKWpvIQJghu324MpSGCyTQNnT0gQkNtWu9LqOEsoXE_l3YhxP3k7qM6HLDVAnBoMEMZxRijsTTiyGVQwdwpD3DDIhvYnpOySOZcy_VR1_SBMpbmf0C_BNKtrlIfLbvMOMSFjuLBPVcMgVesjDrrhiOOtVrqzPw6HtFDVLvKPjk3O8mGbtuDB2OQijWKpMNF1eeiuKTk9w75aR3iFTkux2RkwrkYTQks_Oa9aZ_ZV3PCpIUb08zoDLqmM0cBFk8cJL-7MTVtp1n_6BILSFs0h65pObdNmUXXuYDXmAsasUByHKOzBtj1sYSdqR_EL5ovQvdk_pzm_sVRqv4T8r8pO-Q4F4POzP5PcJp21XDaoivBXB20_kkYbQlAXxf05uwPTTBad0BK0NPvqal4Y60R3cY4rBLfn9Pe6yxATgm4flDWR70lHrgLpNHPcjbVRgKYeJoP7IDmb17DMTPXTycuoQbfhkml8uILwEAsU_3dCSI5r7PKWw3bIyHbw-UwhJCbEV-u2-g1pLaEmS6l-nAfXkHhavRgwKLnN52dfwE75777__6UKGdjFVC_wNSBLgNnjIuzQuQXh9QXKCexLwvZq3mZrndXq1A2ftv_HRb5-BMju0wjWifuR7Jr_X4al3BHiOGpgCKUrgizm9_yNUX5YHNqlK_y7CzSene8DZEffKjk7350eExGWEDBdv9P0gkzPJfGuXH7wUpQ722KT_ZvcFGX5FYN9Jovl0zEQflPHg7r-QgrrwyvNmBLSZAp03x7sH07meNdIbYcEtaRW31MlOnmDAJCzhBoB7FbDcPgdmOVi8t7tFZ0zuf01qykCy0iTC2Xzib8TCbhiRI7cZXgQyNcTP64WwvMmco5Lt4KpHbSmEu06VX-PIcC4hx6dm8c55W2LObDe5qFGr4t1rFCOWGdPsryAM3jB3qkkKAbRi7qN4OOD2hD5Aw5c-T9EHhxaRLC3W2t3nXpjgNJKbgu6zzjgGDW-E6rSNh_Ao84VG0vqdrk9PP4UHXs1TH_sq_W4E0EJUTv4wKeRtyF7Gn2F3ps218leJZdJwbKRSMFlB-CnFd9k2sCanfWy1q1U3JFpQc53aNQtIUH78RhC4jplnMm7BcGrQljhbZT66rDwxCaT4_meuJ32wterCWuFVZNJowYGprZgcUHkBY9dTVqNuvT4niWozpuT9tUiHIj2GQiOMpn1Eyh2XwnqwI3IPGjTFgUGR9ugbxZR1fDb1E-Hy7yRn9HWSq5LTE7QBvxuS9Xld4jAx7pz5PAvww7fA3KjRg9VJlU9cEYD6JUf8X5Do-GB-BSaucN0HplzMWUXcVuG6xB3jiMMxQWko7CJ63_1ScRFS_qFgRAJj39QT0lHAXBv8xUQWpxAD8EERo7H2QBnKkbPHl_x2lGQR-BYxzT84tpVsi5sdnaFTCuIFZa6T8Rvrb2wyabAeHKytNmlvvkXSYrCQag0Z2d18pegYWHJqI218Kl9N24-H2ylQhsCETfCffcugvzCoam_96tdISw9L01XWKWnixPjjX_qTrEdttfD2oShCk1zK1vYJuABku2Aiyq_O5KDY0CLyt3no3JhKM9nUn8u8JLxkQgRMqdS-qruVvg2MhPh0qMrM9GCWWj1aN-Bofm3fqfJ6fuaVJSQX6wnDUxsEeAqTBmzhszktCqLp-qNVBzwzTDOeOD6UEhL9WARim9-3AifJktNxlDo1hbwIrEIpEZZpZOPGvD3fHchOAwysaNvhBZCD3MYVQN1j4IDZYnf1c6GzZO7ZQiDU6CPq_IwWE9COtqZfQdgTxJC9Yvph9RgVZomT4SJn_bqkTp4HjZ5Nm3NStr7kku_nGfmI74IR-tx9tmkI716TWWQfpuedBnbiFh_AnWEdJApr7Fp1jJuVFce-rcrzwLH6o7TA37VHJfLm7OyCB6b3KsdSmT2uwbZCLojRxKPqFxrQ-kLe5VhOW8WYfFczwDUnyLBd2AW8i5M7dHUHr9P9CZ7zWpv579tZLjF34Xu6NjpOYo0JS39Dm_wTGgUS0k4zbrAJ5J53-JosrxMznDqP27pyho7w1l1_Q6SIclvG-pdLqEniqAfyM0KAkJPS12OLZwDwLlvuE-mDY91BTi-UhAvpNErAdNH1csiVSD7NmAyyCdoafv0J2JktdN3x1CHbx0M0h1ONzjKE3xnJXB_cuvMydiQgWIJIqU63RegxmVxT7U6GT_xOY25vcwTcXSH4JTYSzjLvyp-nhQI-DDxt7b9vinlxy8SxJdOwZxFxWNVB2O6L8l71_o5vlBXQXx2ItkiD3i-rd30cbdUrg3FHSC7B52ln3CDnMuHjoTbNOAFbhB4exrvko_m1nvE8wMpGhohGf0JNQHUCxLSW2C6nm9PTGgJtrefyO3a-vAo_T-lqnChnfN9rO8oxx55C2PaVK4cNiP9BT0yiETfmjWbRC_QlPkCH_z8rW3yHoVtm3oho9URR8hGNrvFNo1EMqZQIUsvVQaCq4wyz_F9aO61s5pxBHHiXGK-c9KNdKIqfgMj0pL2MOx5rMidq07YajurwvCg5RPRLoGYOX9Obhx-9ZGsS_0oHQqTxEASyPorNWNjozkRVQWvKDQFxg8r4NT6i0GduUARcY06lztUMg9h9D7BYRYBOg63JYmaMPlfGBgK1DQU-7Sbm2LFHQKuQoiWbRwBpojThZP2hztbcAekUuxI0a62NEmKHSa8KGBJgGcGtZMCrCKml4WzW5ZTpF8LxBEcrRaAlvvw5eEdbdP2SqTzQNdHVmVNbig6W_PSQa1YRvb1ExRphmDA0H30XbPErLiYiJ96ZyNDwv59ZdTgbBH-Dwp0hE2p7pSQXyqpKZjJPdVMNqeHkcSOS_lY5YW-VIX-4QZnOkI_O4pUtBbkjUqEqet8dVkestlO5yBeGX2quIVoggW79mtwG-JdDSbjdKffn75O7yQGEX2xPculDH-rSKRYSlEmMD4nST82_RhI8FaywTSud44LFTN1mBUtXh38aHzKsxunK2vbQjWUh9_SFAi5wPeax8r-0CdA0XjLDNVBaPfPJqOXrVjw6IWbXuTeI8I8GXuinGvISzGS2ewY6oaocA-Zg1cHHlpPUJpf01R7NAu_zUAwBxZDuvlhUtPJ-w5Jol5IVL7ZtjjaY2VoA_3wV0k19970QpVlSKOj3f6bL4h4yVjJNNWb1seQiIAbZpJcYDhXeerIW7E-KH97UEzMmp7N2zNNsWRpawQ5gVcy624idZUMYQeU6Q3DipJ6dabLf4_UXJFuw5oMPOuzDSzzXFWaE4YA2f_e-FfC16J8Xl0tMkkOLoo1GByFRnl6h7LULsHlSMdEwlYO1w0Z4y44nJToKIyBjh_R2mzJAz9CQdifGKQ-Gp_7Xc8MzfOGerLoyYGlXezG5O2f2OKCzjMnpbGMcMmSOHaYwCcDFEODOm4XD0CD1ErwGo9mk24Us5SV07WFziBZOtbQ6wlm54yjRLXS_4tcQqkIUmddSBIyz8wwQtVH_ZFyg7wfvl6frP7EgxP4UPqV8a5gTNXT1mvUq9cKCWZs-JzHPW1xz-x6ERAFhOq4WEMKIMZbgKro-cqJK9WHMWXHjkPiHFi7szCIYS1qWPgL7L1_wmvhJ-Uuua19wUH7xOxhWi1rJRtiyS3mWyLSt7SdswAH9aebdMYcT_gU2qrlGjk8rTSWKFHPhdlsrzkBzcUhC4OaSoVu2d8IjCuYa1qPOKAXGtmMKT0sMDufnztzEhSjhVz5csfjLm3AoCPO7UsDnDK3JhYbL89p0yYBhl0spK-fL5RGFMRKalblqLSnmK0i9907pVmCpl9KARbXQIta4wlDpCvZsCW4meXizaetwRyOEDPVSTrrvEWnqqfemwd8iEIrmidhd2PklF5-9DWJ3M44Lz7foN5tQHN-y6AKzOcBzxc5hh1Lmx-OwnlEcaJqMa66N2-qTliF9lPRQF4PRDSwQcOEX1NY7Ws3pRsxtRgn__q1BKuNzPoGgW-S7vRsT3p-8Y7mHQJNXisEa47zBQT94tFq4835TBt2wBcfIIecwb816sdWTqSM6g-ZvvESJ2Hryng4ZMBoc_RGxP4O9MmXLCPF_kI5wdw4iZRGdngBH6M5eLzOlV9S-dkZdrbVHrM2ihs7f6DCrX1GfIe8VMeIofthrL5XucnMPA43i8Ije-9E9EHrEKjyelzC1hM807ZOlZIbduFTg_41G5f7InYT0vbjZj7cV0SqRf4nf298LJomxbcoi-v-CiurUFqAWlhACgXPEfP73eIWQC3CY4pM5swP4uJuMergs_x_stRT72Khj0T0Yly2QE83LHeF_G__AI5rahR5UXNLxKk2vTfDjIbpIypeucq3IeITwenD5ELe2nqBLcAQwHOE-jpCtwS5sw673nhL02KTLAJrnC-uOBJLWdoF39wVX2-8yU6qP3lVnfU8czfGztXog0DIYCRTizfdaIBjlsDREsGXDlgq305427lhvqQibBVa5FVhc0YyE8THnR393PjBd2701CXv8wlvJmCO6nLHojH7wv5ykEG51n27WB5hjA-6ut1mWtdZvBb9nRtxbFxcXQnMLTqzULqKNA_jb01pFQ5T5NCaphREdVJcKtsGYfX2qi3xFzdxj7MnyduH0PTSDoH0H4VkOY_vHct93SVOE7gCYfgcb6HkrxlRFIe99ALBZNHMP4MZTayP291w673nmBfOXJefJbUvrRniJ2O_nIbX5kT-_XQUL8WVcRGc5CCEJOI0H584hU32V_RV6doQIM9rWj_6zMOtZih_kBnIU1ayY7rtSxBLtLaQiV_GaeEBCXg3_h9E5InEUehWF1FdJ0npm5mYS4W3jNk1SngnP7GvDW5RTEuC-wtY3iA_oSncRxJyrCUmPpvHEj2NSmn_kQsSvmEm5An_NTCGGXMlcBky4T-1W6rrtTDM6pSvQTZcWxtgEUFA5gZihf1-kRW4n30m9LfadPX5vX2uxd4Z8y4ZyHNaBO-ePJ6uhP2GdpANkRqb-RvlwMiG9_OwJoIF1nn4cuoydBsSzTpATqFP9w8Hsd_xRwCexbTpaMAI2FoBJLEnlkcqRZEF79bOFUk1EUAas1GYYhTBiCD0AdKfK_Dq1tn6WgvO6b636HC_pTtYeEA6EZd1qAQJOPBG_Xk6jh201abovU0UrSwWmdoR9dDhohJZCcob-c8c1Vidfhneckzxc7b1a3CEvtJc5mSmHZcvFpG7L_KGKcFlgMv-6JRqnjKkm19XqsCbAicQ9mcq7Z9__rx7cNErYusL_tURV5_IFeU1_gMXfo10WA-Lnp_ZS_BjxlXgwbQ1FloAbNuwTW2yc0q5YJifu0wWCiA_AjFX8Vw7idKSSdYQGBKyXwUKeyuuU1clF2h18ux_Q2dclAkDxZiTRq0IK5zgFGgDMx60OwVskpp6mSQugZVBaKg10obTUdqTJsLnCrA3j3_6FJ1Q10wizLvAJ4UjrKRHafz6oDZIhqUPwT3mebrEX2_xvd4ctu3D2lZnwuknfnEIu24dWxOF22NKT-twuTtWvWotwxvqB6ep8GXRMvMOKUHMZbaeVXpIrfh2FmRKWVhVgI8NyRZuOPDFJMc_Vgnmy-xLeO0ajKLhD_2F72FDQ9RLDdKDGgmuH1rXSe5Hto_6zg_6Kj5Rk2QrSRA0J2a2izL-YwUg2DT8HQcCopvdtDqKtcM-61DraU-vYUEzNBMPRsGoNvpWSMaaWK6Uz8olrcDlcpaRQqsLfTjH2-QMerTm9VXufeWZTuTxYSK7No-t8UNUnbg0zl1vB9AoMiWcOQHfM8OKymdByGFm331Di1xddKNVsNtME1hvJC_PLGMMlcULWnTdkDX5EwkOxl4Q1MqEmUFhFrR_z6P5TKrAGaWLjUlqqGFjYjxDykOqpC9CmO-DtvteYtnjH51KZWG13xnfoYwcl93aF8uBgLbI3MZ3P1sas17FiXpT7iRKKgrQdqNNBrwKKayR0W_8xlUbWj9BS_wpAY4duHAG9HXkaHW33SJ88wQ9C8o_8kytvDHRoDgb5DS79VMVjhGMltjIurf7t2c_8Qle6v6gI_w0h6_M2xT9pUAVCJLsdu5sKX1SaXtEmxgM66avfCGLaPyOsr8VzoOvqmlnfD5d9yK2ydBUALLs5zsBTLjwqvUgm6yGSZ0VxwuxCdb9x-kiiEJdhiZeekwJOXOePLO4XW6QA11OZtee4Nq0tqm3cbLHGJvMJWCz9dOUCrne50yCz6TeUDIPCelJ_MQu4PD3yWqGfh1UdBy67XrT2WgiIQ8kwqGrrlUp5Z0ybknrTo_utZnLguAi-9BcVjSqMrH_pDOS0QbV11YnHbi3Jdb68FrtBHHKpK_6hgvxNYg4fLF9dF_Z1G40UOXvOcK9vBhN52irtMF3gn6sEaKX26-uWT9TSO99CXSWhscgzmj2rQQXJo1kkJfuEyYJ4gLylSdczb738dcEb3qY0DXSFTyn5CVRenVC5PtPaoo0awcxnrKd7BfJR5x3N4Pc4qyXrOqIQh1saDhpfGjPkWnSlaUv941V7x6Po66F8xQRYBQWhktzTBOPO4YYjzc9w-ZvO0tb8lrSJllDsa4rmBMizqTplK-63IbZoPsuPMpXxKbi_v238AwujF32HJfYm6mSqBgCDCXMzaImD8OsJv9kxfS_ITr0krysJkVpRIqu5_Q1uinwLdC0R_ysrgcFzpSn_eLhFpRkLL-yZJvg4KADb3ht-mc7rQPOfRMrTalUWoVke6aSfoJ8S9aH4suviHN6R5klXSPCooTG7IEzrNSZdPXnUNiLxQ00n1g1DQ4JG36f465MRLLuKlPE93nFPILSVkyQdWHDqJIrU2wLYYvfYH9M5DpQutRAyZFVgNrneOrvGpDbGIPB5Dalqp8NeuFsLe_8lToo_AaONvU_GFBtteevAc4Jy_Z9nGKt9QiE8zP4heoaMUm528NhA01RXoDIe7OXk2Ca34kSBHDDDcVgy3X0l1hZqStYg3PoQG7B5sMLfon9DHiAKZQ3ucA3Z4lZrkYYFh6V1Rz3BR-TY_D1eU1-mz4yLFOXys3N2-zLakETwd8M5c0g2dzPE6zyRG_WR7WgNCw8RDYULQNh9-NWffCkEgqtmtNyS8neD5F-CGnfGZTVriCBXrTGI07i6tjtLta9xAsLCXofLHkbuAJXoyTU8fKitEueODyXjeXZIbj_0iRy7bkEHUQbJJHAiijOAzzeFmB-0hZ2vTHmK8ZbgRbWna2Bft3jpjVMC0qI4klYxZIZ_BKxDdMh7dnbm_yniGf0WbSUGyzS71IzHBdeGlKUVidMRoJ9n3-GPAnhRugxgjnketD-Yw0mDkLObJQKkKBoH5T_addvgxRxF5-RKVWBOoBMELXnD4UOiYYtBc89UW_Inq4axw_Rfg22kyTaNK0UO_kzUeCFvz4T393K7UoFlhQ40jirrPqHcMWyhggRi6oxzT7CDbqsrpVuWL5WOuJJHZdpVE-o7ZrxNGYUliH4l_8uRwgrJDt1wXrmrG2mi_FShVBSHfa75vofZ_WGJfX199sU2rKf0Q7Yq8TIx_0KwKJMp0JDsObCmjx1syDRQMzmg3h10fd34EmKDpKFxxEx6CQBjC9FB3Z20f5Gvtn9LWkqqDAx6JSJ9o3BRyyg6GORb23svTfLUSbkcPADZMLPdlyiWPFLPg-jCY7zVC1OCrsO8KyXlJ4RoSL4a5BYy6yu3m9Og6ATay35X8PcOmfw9MR86fL95almJ8bUehnvKWFHoBwlGU8k-bK47uJLUqmV3ri5iCP3_hb8D3JvWnASAypgsf9Ox_adVJD0xE6hxncodPTZz4jqykgVsDS2sle7lf3jc9DqJsgn1_nD0ygLSQt3yLLiTIShfkIeNKKznOdApNkmmnDOI0TwY2z7FKyLKdFDhnFzn-nVqB17iTA0cnDXwZRwgDxdwIVh2PNi8c7DSXEReOdAjAAmXF_3NPXycKcj6csG0uPDtxCY88SCOmUDFwtmJQUsZQ-7WhAumrJzkB1Su3pFfTpYsyFdPc72PbJ7i0S_oqzBm5XsoUV9w39f5fWgXnUGcCTMLyx31MlP-M2EjiaGmH1PzBzIjIbUvG_c3Y1HF2j23yM08OefCnQtEQ3FUOi8FZJceSJ-Ca9vR5d0l9YI5JJiZ1AKOsBZCh_VuHLraXBAXo43WYg2xJjoARTl0X7iztyYXeKt6PGDEVhyZyQLlqYSy9fC61TXd97ga3DKOdIMIi8-HD_NDSBfbZsKVn-6_S8FLb5WLaHBfg4Oq2nknhv50ZAm5DeJxx7N_mhRtZrWdwx-fgpeBC0wgA3oFQcZLeh5a4qH2SLxqUDi0knJhgdo8UfoH5t1HwlmG0KNjbdR2AbgNmiGXC3nXMSs22wh2XwLayLvg32A8dm73DjYws4zqu36r1rPAbq9ouD7UAbBi3uEgdlr1ofghUDfdPOMdu_HnB3T9ulDJfu1oEGPpPRnIPrnB7xZwgYFTLB1S3TMsrKEuNtBwpAvGHQ2uSS-Mp8jSFTOQKyEZWQ8Z6uxY8-WfeM-e-u0aXEL_ip-ugIzbBMn275k9C24u6-cN-hd7sb9YnoCMylw_o4O_0cgcU8599n39SpEZmmPTCKfjrjknnVSbWefo9BhROafdfo2UIzSSkk4pqQstNAzgsTLSTFhJpo8o5YdGDDazOva4Iabbu8LxXY1fGAwPLOEHh5nh6JYq20HTiBE8M9nkOcsyCeelAVlszYrcitDhE_Y2XdGC4EemqUAbDvfPGBf3V7j4gOHeChRrcmYWmEDpoL9sFs16fT-dNC6kJsdTDUzXGwdAqv8ACzl6BV3waaTDh8g6_RhPKamr-hqgpbFggvCgx0E3YleDgHKLK8qnFpVVyCctyoZL64jAdiK15-uL4PXptNRdTfleY-zfVnnB5tbpT3OcXLbFk7yI9jctN3bnrr5nlqnt7Nn9a7zxhFbDcYLml5QDIPmxMpPtc1hClB6kY90yPd6B4IS4B_nJWuel8l0QydFrJFpXHU_vMLmQ87vPpenq5wftKJSx-GMhLJIkaf2sAenRxaLQ-ZAAwYxSYHQ2vZsBULlGSNG1QU_48LqSoxGY0v51MSodmt9GwnHQ2vSuq50RoulXjEPkdWtWUbjNYeKK0cqdnxFsX0hUF8PTiGa50h895tiyGR8XKSCpGOzithmzqTXdfMztxtV1irMOHeUPi2YAELfC3_E1LwveyWexs9c8b-pz8OmWdUBNgOsQPn_9QXduyS8asKLjGRsHNOZnZV7w7ayNXiOhZIC-oORt3-wJxjNJSZYONtbxGqYhm1PVbBDgBt220AoFqhH3ZbIx96me7zAEe1I-yRISvabt8gw15PQsgFwE_zZ4Hxv40bmfXTJE_pT2xJwJpjlLuuofVdd-4uOdzTLPoxuYzPb415tDZ_2WjyCUrJh4WJnB9_e1KxYRNMxZix-AFdSuTNGNMFJUQ309ke_-OqELkgBasoKtyC4w4l-S4zZr7IOiEQu6oCc0c88Htt9Ixt91NeUpFoN-9CT5tib7Rn-bLTHzAUdfgxU26WV2QQiL1bvXLc9svMEBZFM2dLSIi8ncBdi-VSutU10iIa4wVWxh1_aGyj4onMp_w6NKxY7NIPEujU0Zb7xWeKui8ptQzxg6BQbGZ92Is1MXur_kvbawse4ONNmk8Px3MZMjczpp-O2wEvZwhnL5dcjT6fGWRA2cYBqPmecB4urugl04fXAEc_KCLPiytXvCNXFsD8PR8Xct2Sy_u15_iLOvR0X3Q1UiTY-4a9LU2g9zsWy4oixi6bN9KvTtu9uw5SiQhI1f-HFCxpvlyNCUfHgVlLWfrcwJa-LSmhx3_Wij7tXUi8XFcL43va9EqGpyYwzn5reOYipjAL885bX4bPxorDNpdFnz57BO1mAdrfgDtVxTFjYKe91MR1y64J3c6w8YL0jYxF9VSxnL6yp2oYVWp5B9W6bEMisQrYiv10DcPSv4rf44FVrLTVBgDZ8cPsi8oaRomIRicsNtwtUs-lnQ7q2JrQY5x3IvSoGPjbPWbB37AWCqgH0fkNKnYvklDfD6EG8q-3gNUjKim53KBGpMzV8ED-qBP0NpgCv4NuLGOU3GscrdLL_p5xGl9vFaF21ZqwG442ASG-pRfXUZ2Puj-JTtQGSQ1wn8k-rNFadzzUR5et1ARel586laTBGtuEtrB_wkChfyubfHt--eCXxcUvB6VWfkt1kcR0jpCF0f8WscgUax6Eocad2bbydRWww6rukfuwNfGHsXRc9DuX-mkQvG1fpx5ZsifqaIs028QrINJCTE_71BT0s-5qd_dcMFPn2ykuwfThEOdQOYvX0eI7ruXLgXu_MYOcd-u6ACuV06HUqgxuAkuct1FYWfEasf-4AUmey45gXX6J9AkuPB1NzdsRtY5TdAYLQRAD0i4jDYWzGFv_wTOd-_Xh3_NonuUTWYbwLASjsCVQrRPvAM5APWw8c3mR99_oETtfvlF8O1gi48Hdyt9QPjLfgxVwxl4UzbPIPigj_cWLn1zrlyj6DlWuRx0V7oy-L6ZW15l7ePMye1BWKAGAmkeiChZ0Hiw4_WDR4WgoGq_JsbA-vLkDPbLCeDGjel7yStFSzTeCjnSzBmTe3mw8O-XeqjTAPPFhCDT_2UIL1RceZWggLA1usgCwrEKoOH4zzR84nz8ts6IMRthX6wrdrj3jWmRMRW7H-UicvKKI8t_wRMXimTQ63mwVEbsy-rkLE3yE3efHVho7ow1zk_IyKrp_UbiBd_B9xAu_mhjUOsa0g087rwmnWnPffokGEMGxsdvg4yiwy8HG4-8e6veps97jPiwoHmonsL2VJWC_EDU3CyfSsO5Vo3RLm3bEa2F0wRAEtV9UlYjgL1pj4z8hXE3mlAYuTlnAZLEdqo2lRVyKC6EMCEltgzPYbRbKl2gYV0dUVYTHbZrb5U0Icx8HJSUiHu80pBCXtOWlG7Fmecs7Q7jFkA0eoYMsNLDLorOWr-0ImoVyiudyFvuF-iyIhdy6Yon3SX1B55yL3GWuu_a4URAfDE0ZtGd_Nky42tL7am3wjbq2r54YbZBqrpKmRlDXMI2_OKwT8ILKGQo2yvQYK9yFBiwx0FQ7NUmXIGZT_mUgwYJcuL2T4VUuBkdgzpgA7nKseEcWsr_3AJQWoQXWO4b7NM4BRzfgzTO9AiWwwIzX1qZcN0QWDngT9Ohauekr2WhRVMgwkkGSi7BBEOUXtH4Hu94BV3Ra_UiMHPLkv-Np1dtx2TRSpdS4C4J82LAdoa3LYgq3eaNlscjVRhlZIF6vmGGvskQEHFqOOU192D_L9sw_dCHLhcAadvs3fmiJ1DcCRWO0FPcFomak_PWXcJgDStLuc8-_0WDruRRmp9YskiQRPEM0M-7kZrCWjbWVdrbkAPl6UXIlZbqvslTgGkLo1O8XC5TJJY9XtJTuvcQOLw28M2umb5r65r3g81PBxJveaRJJty8E9wBNKcwwAzOx7VWmcg6MFuaPx0A6bqS1YF6WytyFb15fiortlCZrzDlvcsyz7t6GOTzGYXKdKgi41drJFaNhoHAGlMQUBdwzQPEj4-fob9AcuXDYpKqSZ7Vtw_nljj2XpIds6XtSPCUXZ7bzBQd_ycJ5UAl3YvEenoRIbtlxUChDIK2B_q-lb_y_jcb1b26o8Qtfau0vxCm-13uZ0nNwMGWM_JjM-tU5U-_97RSTRjlqXu616xvZZbTZhk_MCug1hByMPXIqIoUWmepSkJuFRf6xNko1IZRxRRigxK6bhna69I7K6AkRAUAQ504ttJVqVDt86L-1fwlWmlLlIBPLaYOLcBzm_MJLxt-fdTjwucbxU2oh2ltc3qk6f8_ZW0lViOgXg8YPRZOCjj5wlfe2zW1GSfM6T2iNwmOfpGhXzsZmFqqBc5lpl7Tg198imKCuc1YQFFnliXDurl_rEZNGUiJMS8zcdJyr7p7ya0NFdKEAXU2g5_tYN7SAEwy-Evj4l0Xxzf9Kamjpdp_jm0i8vY93lVTbG0AJohCTR_ZMUw1titTsiK3fKFXOa0Z78dTPzwACQO1X21eUdQv0WZhoioQckpYvWslSEJyzBvAfi7t24X_ERHOzizI6_L_-GKnOnA06zTuWdTBEjs6YyAc1z2RxJnBfRvk84YUD7C_kkQudxHQLcpeZFRfXzR3s6-dwkTOHnMMBDN2RXxXQRsPu1tbaJEWiZo_7sYkMbQr76X4y5kJOZkjQxAV_s3bhjF2IyIBbZeN7dE-inzuYe7nQAlDszfrHnuvsLOWK-uvHG-GJvwE_JZF7EJyuhJsy2V7FBJiKE9ztbu2nzzSmy2Kh9bnC0_nBMg1ZqyFZWZYyllCIANRaw8ASmDWeBegVxwk0OT0qihdbkR03QE1EoFNFEcLM7RXrS4IGNVHxNSzXluhN3UqPIKbnOY-oSZEQKXq9bXXP5tvQVvzyWtG2iEzDOAJestZCImuu4FJiIvc0Z9JIONQmOVV9z4m0aonBuUulAcsMUSg-8ys6qOw4RKA906PsIgG57S3Lf6oP4synCf0SRZ7hGZjw2YnOOUPah5spoPEmHYw7NfagaCcV1L9Ib3zCega9b0uxkL939Ou1TSlFl0Jb_Kju9AUVkJNuMMVI0sSs7YYWX16rwK2SVORz1FXMU3v1mhxN6vPYapWz6KJmGupKisnKqfclcT7VFq_Cu3BTIEoep0eSgvcolHlv95ooI9cdmD4STE3GU8ZzPklitgZLVLam2j90uWky7ymZAxJJ6VoAoOxmwWHyAcyVHoptVwIW-_GYnbyeuqMy13Q6ra9MhINS7WQ4RabLlZycaTTELTDMOVGM0kvLIFO52Nz7771zy6pfA99xd0E0q2kREn5itXlrue0oq53ds31Lg4RjgynpYwRMilhQ9iSk7taLJLuOseo4Eafc8NGyj65Z6sVLlckgrCVaUv3qB2tXd7fVTBIL2w6qtZCaB1arKlFZkpDnJytairPS65bW0hH8Agr0F_h71POd7rYCj1p3wseU7TmmX2ag7ke21zdtx-Lm4mIkYDICjqSKVfF2DYEpkzmx0dY9YpZr5eNRbieuhLTW_QBMKMl7-4jb6l8wa-xzaJpEikxMoJ7aV3hKBZO4gWsiQQbvY1lBgJqqgyVkLSt-PN21ShTDHAxhxFM-neC9uEW9d2VtDqwalci6fcs9mGBDt5ojHitKtOHlhbzEULDtL8BXKbnLzY0tk3MlWVF3W7PMWkBXudxGqdZ86PMAPBm7nV2_ZpGJuYBLEaCUQVIBhcN8eI934UdPQrshlkJTLVF5WJS5nf0UAaOEovLObpqgM4dNlxou32QMKcCPO7WKRYnzQINHCrJoyymFmdMD3r-ZcCac14VHehBmXvX2COFw5792LNsoYA_zejg5zOGJuO7nZp2yzELxa2pvGr09nN1N_K5R3B8XTUG8lCT22Vp2VGxadM18frSNzatreYNd9Oq64LUClc4VYj34A6FV2I8Sz-jnoX0lV0UzP0lp3imVDlcTC-pFzZok2pq4hLQ6gSh9Qa6-iePxMdFsVt7c5TfoHoHj7l9bRe4stnEdUnBtBR7PeSJH0iJHjlvmh7WFZ79tBkEM2OaByHQ7EiY09D7OEQUSuHkX04AfGzcaZCcncWoIfUuox8XSoIBc26s4y7WRo4ew-kqFD3iKeze00U022-PTJY93EG19Rh9N-MVsr9Va0A5pGtyoA_O3Mm1cVXQTW6aF9Ro86o1p5FcIH2EfiswCLOJW6vOc3sQXnF4mX4PzVpFcoOpctfudinTbMY4Lc7pbB-1QJRgUixWe3SiW7MXmlrFBLUFaQWXHkYfjTonIdH2HTu_MPOgnuSBx2cf86x0-PYggnY0BY3NMFFD66X7OmKQJ93lEN2Q__lJhEsibY7BG93e-9pNmkjCaP9noQQwWAD7bspHrcMNwTzwHObZJMcJaqZJ-3XdvG9mjDZWsgAkMtQMCr63FtHE28OQim0frf7fPJSIjKh11KRgwwQX8gpCv-QvR5RSjra7iJB1HOI-EbK4hAbkckGcJtzpnT-mS5mTAeIxj6IsN3XG0x28ZnCVF1jiQ5CckgEuthsESfWRM8qilsDWlCB5vBROIVf3UrTulfJqWG0NTjV9i7zBdxtr8WsmvfJDgTxBHg73Zguo5r_BE9yzleF1Ta-OVRzL7aWkuEeJFUcrHOH61fFhX90gAyT9u_foffT9q7cCnr2KmdUWeNAgCYp7busr2cgcP4DoeD7EQ2XXCeekE1W2GSzuK32vdRHd7Hb80oyC4RNJ0oSKGNr5RVWROwku7dfjwweDrFqwdtHHhh7c0KJNwfVMeTnneLRaozlt9tF16d-kCNL3bEphVZkQx5O2rnCCdJiOLwA894PHEjF019SAQFlzkP7KEWzfmsrNdSTNLkQXwwTx389drCWN4i7PNOdpw9Agq7mkbmccRRc2T3HfuGCarh9WLhghpFiOXzExZ5V-zZWdO5S-qniLphXhH5WVHQp8a9axs7MvkH7SAkP5zFkKiMA-r2iHcX1Igqj6e5Mn1jkvbPvyifLasda4URPjHJaB9vgBvXGRzg3bPQZFgBbzox0mqfu347pcW2OH6-s4XJDBmlBorw_qb2Btl132J7Kap6z5k9mWJFraVoeX7H8LRtdiRKOl3qxy6QVn9C6JLAETpl9mnw9nQW_XRG1oOfBKFoOOxa-F7W4zKDB6RSqJGbIN9PzI_IFQVm1jd6ItzOIeCYnl96dtNSWWGlEvhBxMLf37VLKJEilK4xKGFZj9_M9Vb_EPIVv5BhwD7J1xo0voFN-d69yr91Qb6TbxFl2qVdcErOlzrG162c9SD89ZMr1JoUV2Qm_HeKKTGmicmHSGRpuATFydc8WzS69x_e3jlcXMryogkoxyR4WIuT_sZ9UKj74FcHndn-DXLBge3KcS6WT9yR_ZDpO3tr7IOlfb3IgvN5i_WHzsoFpgN4hui-1R7eRPk1izCrPNSYheAHXlULKDJoZAYlUjlE85qpvJGQXUcZV6LwW13fGx14diNEB3c7NlMNDAi48CeD0g6PErNRbs-O6U-xvB7IkIl13rWuBCMMjFVz0cfQ5K3WIJzGalv90sstek-qMJbdJeZimRCTJAhNCjrtQZPBa7-_l2xJ0tqHF7_GpoRAAPDmjfsuMKkUNEavED6thiAmuU7oq-N9SaBa5BC_pzylpQHAA-AF9ZC4oOAPKvLH7kuGE7Tr9lHypxfcpv_o0opDU6Oab1HMalx3ZU9LP4tmk4OnajERY_o0jphou_4ubl7badCMv1FcUTJVDgycKH-d7dI9nIBQDFi3JUJ50lUGC_ut7-5z5exXqEKeNBmXfueeh35kNmgMEtq4ClI0-dPiBaAVFp-ZeYPVoIUpZCeAfpc8UFzaCA3TKpVYz1pn0EwbqVsrZAwH_x4yHkSxixOTukei33FJJgV39kNuDxhSdKyeJ9nK_Zyr8bjc57pNZs0Ae1jgAvp4ssSNFyqtXGlXxKC_DFRoLyt3KRVlnxvC1DcXmJ_fOFXa0UvgbHrvIZD4pWBguM153n5Zn9ahdd9BAqE_NaWVKPugbWFRa33k7YX6-Iw-VHr7EeE5ziKgqwcPtdEBqqBZjjpJVQXtuT_Qfm63w1Jsdh2WneNjrwtpWmgUaPxOT1KXGvUzlAIkBE3sEih_ygemwYv54Z8HfePoq-W-dBIOYWWn0PtVFyUq739qbY_e1EU146ZDjDqts-dxheeG9DqqQUMuimFwmpQovqX6PtjfzXjoOQJgyO6G-AGEIByAbZaKv-DAXRtuNaTgEY1vcK-A58RvMrTIpb-UalLAU_aCCoseUANQMVUvknxHjj4sy8j1k6u9GHnKYV48Nk2RUbhKyPUmKOs3EVVOokV19fkwlfm2WEn61H6mnN-OxAyiFPCTr16qMX2n5a_iy9Gfg3sIzXXKNdOF7k-D0vt0Pgf0s48h3iGgqPoe9yZk1kjM_YDM-O-1nLIjsDuMjR_J8ndYieLjWdEQY2CFIlQO7f4Fls_8srRx8bypOWQAteHuDGWyua80qtsN9PcVJZabkPs8a3-r-EgxI6pDlWbgj-JKqw0pcxQErwQO2T4-q9y8fDsdDzSBCXqfT9-RyZQyKf-TSpzmyrgDcZpIN2ONlAuXuFTZcPobseQaRFZS-CCJWDuQBIj9pVCohabRLCAqt_WDpRLCJ_vsWNsDuHeOZ44NDQwvjrxSDhQHfvEX3VkPrHG79fgiJUy1i3w68rb_DlVvzG4SifcOIVt2tTX8bbq66q_84yabG6D-Ydm-qFlT7knYe5ZdYd2VyHTjSehYCVVUNBTKY8ArWwVJQL26oCGo5rXmwst720N5aUqnqsFGRTFyLRPnwrIweqbRoS56KaD5eT5I5Hrd7j-_Dy78b-h-q0U-xb_25s3JT_7PRN7dSAarCEBebleWwo8dlwQX0so0_ezxmOuzFi-oo5GXdzwD33pKIZTB-TULh5aTqoac6-UcaxXLcu4hS6OexkMzAEy0AIMWsRdiqLOsgUWZ_a4zgiMV9vMgMig5LXfmbGTi-WtBPlWAXr1GdEsYdCg2igZgjklN59Z9PJItI6ZcSTHtyzDjuLAN4IZDM8PieRDeGRAcAFBb-CXAbmY_JuKCJHkwRk3zx8vc24Y7hCUBLknN2krSNKUWk5wQh3N-EoTpcqBrkzw8pj8wW4IhGNHtNXDmibxQrbKNJcCIWsbZ6EQnnxmOLbVyloFx54ew3AY1lTMnhajxNR_bsHXSg9NE2rE20xL35mLd3Q9ZnIzp2BD3ba7tiJcMGtUIUnzb2i_7Iq4v4nU49EnzF60gMv0hQu4138sbYayOe6qJj-IWiadU3e93Y-SKQfxXoljOJRQDEfaIVzxGM78uriRP7FWB5oCNzpQJhy4ZnwpFuVP6bT6KrGV8JRDaQQoUyavF_Xj8HjVakTZHtoY7Hn5Arc0TyLw4vkB_NLMvQo7zJc0BxaCDVpcPgYGCPAQqvbGWI0V8Mr-nMq9cUroslCJCZQWutxgbEKn0fTT-JcCWnC7BmvYiNaNAhojyC6vtsvDHX8EjlaJeHlNjCZCDQB38T4TY9D3NcNlYF4Qcu9RXFBaTRSYGV6bgUwYY8gu2_xlsXLEKb38qiBm56SZOQl3ywF4XvEdrL2bUKQrdK3P2aT5JDVvttBSIleP7XV24MIGRNJ5WQRpA_DyzNckV8EVlG6biOKqGODnBKh9HYlBrNyV7B_QWb2TZPgFZBGAMG-NYg0PiGjM52lkJyrdd9gYxDFosyw1_vDm04wG2lAzRE4qEVx27YUbeUVElki2gsDhrXhaXoZU4rHxAjItIYqtw1SK0L5gGgDdDtZ_4A-Chx8HTxj3OW471t0R82wfC4D19Th5XK4WwAUFMoJCLnqsm3HpNIkZYBR3SSwXu9iG59splr5pdodKo5l-f2UdkZUFICNKoS1jS7OCfzMeVZobFpwDsXczNAFVVf5CatJKzcCjnGfyzodDwGJXxwgVo-yPpPi9FK4GJgAW_fJ7JmAsHNxAyhX9tnsffnUT17LcWjKYlnXRZBuIaPVkuvQTgDEwB4Kf_aOySkgkEzfbEzn3tPZqS44pcAUHjQLCVVSEqw1igBEi3LMABzdstq6nK2AqJvv3i2TO1TodI55xxNfo-vU3_qpbC28N71Lhv0ZRXPy3vY8WFkRtSYR22JsvIUG1ViFi9LK8j7bvDsdACa4zq5rQhyk9PMJ41kE_MOgZEUd_XRsxJrfth7TgFfno1gI9cYhOBh-7x_syv7mOHxihL07la1bNyDYheOz-94YW5KslzmR1HF-L2aHPcTwyt31O3TFriz2aJ7SjRrwo7otXmlVlLWA2x4sb6XuyKLSK6POzh4dRcDnV_TJuooM3dn9tS7YJuf1CoNofsqroi9qsus7-q8Zw5WhX2zsublzr18n9ps3VtY_GmKgfgK_86z9NR42N55WCle2juJztJPsO2CiWdbIWcNROGFJVU68bSL3SiOGRAeS9hW7fVU417GT0vfDFNOJ3ol8w6rnUhaa-bJrGr9tUx0FArGgBN3c4DF0EaU6_NwxsW1w4LQfwlHTGZsR6hpO-wlMnnjDadTpZvciwUr7BwyJgOZGARXfmnLk3rGtXBuVFTpXQkRQlot5rm9rCc0nemSQX9j5FnlZwUBp5wZp8JqL4oOC4pZKF2q6-gRd3oXwGhh6b3sY0HXx3hda1M_-gXdBpaoxH3aY3AEaDAXtapwujDliWI3jBsRS3GYax7jwMdbVzbdVItuSCqEjxMApw1h-vWGqx_41GlWGG8ptMBSVeeDiBHIt2AE4jM-AiBgig13c79XowhtITDSFYeP3cFS3XSo_MoCtQcsMn3Y1F07ZeAhfCKyRthu9jLKS5AXFIkFfYUtasaEd2Op0thK9QDvMniDlBNdkjr1P9ou_SFBxPoiWOcxD_6fJAVb5nPZ__RBOIvfwjXuzc-DSNZ5-8dEe2gn03SKg970IAj71hbYur9r1pj2KaYcITLJCaJhPm3uK4ZBfqH7dU3BdRgM6EZKXK3waoNbfUgpXrOmUNlyOsxCddi9I0kHh8QAOUtR_vBCYpkC3BvkROo97Yt5W_D61L3nc7Kl3WMEfABH3dWsvSiPyTuItZZ_0RiuyXCxZVGKLW0jPDzwBlzk4xXXqsSFjJy4aOmc_yXo56PUW7vgCJ_5y0PdFW5l2EBj_XRxx15bHEQ1H_mhcaVtNUNO14W2DJLLHpcCyFOodg3Ed6IVugB5Lg5onRjEOzWCSjYfm2cZtXifPn6y03snLVs7YwJIYPKhdFVOiDcgK_diylG8NircGOJap1M77fSnaVC3LPZ_x1YxsWu9zxCR7vpHh0QFy8SCcXoIiFzhIUvncTKlpZKPGpWQjATbzteVZl9qhsN9f9-NL9F0vEH3doMlQ65L8zZCQaw_nfPhzb_W0dA7DFH1aXkaiqFF4em5-ovYF50_wrQTU_dwLX2Ksb3lJg4n8--ONcBKYbMAilhf-7LAH1nHwZR2BSzA8lP4fOJqJ06PdxGWvt82mG9e3beHWAmadK1_a3MUJlxYj5M1tPnVsRkMiD6t8FEc4Fr5n5Df3OfMlHW0XWAx4upgF6uN7lOo4GbeP4A248ZDCC5Jl2aZ_OjIrL5ul8bxJS2EirPymOhCkWUuWHQcARcW3BDNLgXNPyNaqb21Am29VnNPxAJ3ITXuebBF2Ytr0bbrFiCFl8_4Zjq3ltB46jELIz9jlDRq0HxXacM6cRn48tNuOKaoOHfkx0bl5JO08JdHss5Kv4vnQJidNcbO4QGUibYrv1RMyecUmH1YVmPoc3zsWNLLPl0qnXgrLtVH11ui63qFAph8f_sa3TL-W7LD3vQHYaEJIT7zHOunzWo50NVaBC4h-pSXKcYkAoy6SRK5B8hC2uENxmp4MMBDpveeclCN7GzrjlF7kxkxvvTtB4AQQ3MN59IYkznxpDXX6Y0k5THnC0SOhY4kk1Ya3p2BAtRp4ly_uLX3zajCZ6evnaSwIh2DFOsvPZ0_qsRIqp0s0TwDqGVctUWYR0WFo8-Bde-L1iqhW-VS611cSSn5KeMtMMMfnGQb5P_evACSCgEJDksazbGLTbFVI5n6U45Ls05sPzD3jk1cCuJ6yg66SL5T5SKSpEwEJJm7MYA9P66AvIvYWaR0EhjPFXLyxgXLG-m1s3FIsuKFR9BLLoCRFfuVa63Ytf2b7ymT2gw4krE8eGLS9mIljD3wtvgmUjhF6KFk1ow-4gfll2bBkOxj-FI14uZ0Rq8R8_wzKwbgGNMocwWKvCwmHqAors0oIRz6OsYieEBJI6Hj5dkGkTAliyVzLoNum6PGRLvDPNP6LnYCclm3G6PtBC0dKxqgWGJuE4TewPclVccjt0vddipV6ta6NmauSXi--ZVHdt6IioX_mbU1No452MRmwj3lIATWAaf2U9bl8Z1rZYPWDMyBen4PyZTmOZVcUHpD7RvEGucInFlWMrS6IeYgFJ2YNmVKjl7wjApWQGKKPLhTXQGyr7b2ln6q2-1hwaTaMr6miuODOp1Fcw4QV2PTZAQZRZHHttyaz9y2fgGS-eMGriw5Qd9XeyPZ6uzV_mL2r4YgIfmiFgobeN51gnf5BojBIz791edh9jWJv_OBHFuEWftqk9nzuCTIEb7SNlHhbDhf98kOAlh3RHEGSGk834rzSjUzZVEvkCmVWWirg6NfiY-vsgDbq4dHtTEiA_5khNWeuRWMu8L-fY-x6gGD3I1xlCyEWx0Msk34IxVxx92sVtmbWfQc0gMldriBe1uw3_awiCiZDv_vpERe__m6t55pUM0m0Vw6k0OxK28FOciOI417rdB9PG2g-LaUTR-wEDmP68tT9cs8fhb5IgMuvfhTKvpMAnH2iXb-0cM15ctUREw6ckN0QzrsdSddk5K50b8PLzJ87WR1eOsxZXWJGbj4dSVQ8euK13l2B1kEMvavoJoERsqJ3LB7XXAkOiGcnUQQdOezRPf8DaOPBG-k_Rsm9r6h0B-1EMzkjwFBxHIWgUEiWv6GvPNm7jkwGkH61WUX8Dfwey3ZJ_Rv5jDVQ9mMWevJoFXj6TqaIbVdrhuHRdSeGHx36OxYdBsaU9agiIMbnuEZisqJ8C3MDp25t0N6tWFutf_ouECccWWcQItjQunCTBJBW4FQp68r0MJHFxMD19m511u-0OFLOQfFqVpIIpWcfeHBgTblV0Ksionn-bJ3ZPH9iy2eR5WgjJS2MxcSTb9vrovKnzLRoSIGoq-JiA3GOP7HMSL9lKgg0gOmSPDcjYlbB3Mxs65Mi9hf9PIRpLmmWkz3Ve2Qy51mLqMUFsZD7bTGKeX8Y2hacwn2Ha2ansXDzg1lP8YfwDP_1nu3RSDPm-QQkLbWRkIaK2GKdksJSHuyickeeHe8a4BVcXVHjwlkFy13Xt_G4OFoXEOWA4hspRcrU9y0Ff9T8vJTcdo0rHaVMvwOBxDYkDaZwkz3PDgWDcuYExNNkNezVEQwlMVGDp7yihzNDPAdTyOmS_nsiYKwwL8VZn6zanTl7ATUqPGyW2_wsuq3sybhYKVgwhJXyvzn0hA2_G43pfUm2FFGuUPgU7QslQAo6OPEeeDllRuZzxK_mohl1NhbtiF3hDxnjUlVY4Tn7ZdO1OTUaGq8tFM0MknPc6WtLXxXeOFvk901v-x5OIZrP4pjt4A0mba-kcSF9YhdzMJvyVcQZsiqyXUVETgEKxh0DiZ8n2fyid0DF3TZ3CyZELXT-_8dir5cs_6Zy-TIhvgv_DLv45tfyqMvNjceOeFIV9lLoKZQor1VLncDmvn83_cCBtj7fI33cLxSREOuLr0WL9LSAj0ql62-S-idrPFyRjGTsDcgbnizNZ14UoXf5FAK8xBZ0a6A7v2xOnTnllKpMxOFAKokC28LXaEnJixbErpOcG0XrogXh0WtNNg7DiBx6KO_4wB4z4Re2AAiMDYVl_c9i4WrjmDxlJvIa_EqMD0e7mZvAWQ-FHaPT8pbsI7ivoFl0DfiQHg1xuM9W_ZLzIwXtMf9w2NbxVqdVUNRiInh9O5s5-gqk-VRJXwqO2PtV9T5D26BHtgFPg6vjsBMbmYNQK6qjqm6rD52yU6qBTrFGIDMwQGwvZKZR6r5q0Djh_EPb5xocx6fUn0jewVUmRVuMflKK_BNzy9QW2SJ5rAhnLBtFh4LqBonXYhvX_zVq3khur0CNqrkM8-qmppPKQvy6G6iOeG0oLwbDNucn67AqHAj3AFVFmx1HL9PwiIlwrX-wJVoJIP263rf24rdTqhG-8_ax_6OCB3QGbg3oYS1jVnc-cdllJm8dv01hddx4mQCTRYg2WFeZ_eBYuqOWKLUmlt7MZniJzysK_8BsL3UkJGT7nZplUVTU9Wt0VXLosD79ZOlmxi10m6fqWJc8kVSXrZiPq9U68Q-Om5626Vilwg0Cul0kapR9cO2m_XkL8fNRHDqaFSCrsv4XOSupgceU4aDU3CafIPUGw6X6hXHUgBeUro0LLQeuJVW0itmWmN3bV4nX8mxS1W5-4JVPGe9ldtoZ23ZGjHVGwF3fQmf1KMRvS4WXLbHkRtmuFKZ53rW4eMqEKU5p1y8hMzV6SjWTzUltM2yAqrwvNpCzSrz08V8Iy7DFArqdnYVlV705Bep-4cAh9kgcGeT7iU9soT9p1XBbHBEMpB_APonKcxlyBQAqx9spPV56DXadzkwNCmW1c3gHB8rJoinNoY3CXLbpNLb3QND0qVMpUC-kC2VsLM7kdmIGPfm1qXKlGRNaN0id_JPGNkZwWnlYrJdh9Lvjhla7BwIU1immtPLFzKGgMegVeRYdTTIKXxgLzSOZwQht60Eq2uwbQDOAXElIYA8tSUHD7g9VawV8N0ogolg-l9Mcxl407UsqifjrUScJ8lJS6baGXzvWGsICKiG-pYmCEFphypVtyYPhqOuhUaxBfa_DqqVULxcflvJYsxVgmAAq7G1lCM5qA7TPuI5eaVcW6xzj4hdFHMcUe-8QL6eS-8PiIqlcxJbYzFM9DInqIfw4-7l4yQ4gxFyKuA-6y0u36oGmJUDzhcc31zicoVlpu9UnqPGZOH99BJlZuGaeAK0POtzRELTezOrRky0cqdju64Snxfe8fLie4AcYEeymACgjKYthaz4oHUEnBRSO4j_ncyVLI4m3kjyfY2uyj_EAYvSKuTyi4s2Qv6o8kZeYGC_nFSuKR4g8epMs9mEwT6sYcbaHxAcOfoa1ZinPVFBNbKwz-oy3BL7VozClSXe9dMT3GlIk-6WhQVO2VUURal9QWED3uPL0gJ8I7YNvxJOjTHogvVeb6EFzKho9ShUF681Eeg9GpeQyda34qYnq_wQIZ8aatgtrG0SDBUCoM4mpO6ZwVwj33hBK16VV2H01px-fktYJWfod3NgBEPDe1tNZS7JHr9ML2kqgoARpaljT7CVyMPLE45BD3RXrcjILkXEhJSAsxsSomouMKuwBgaoeXi_Cjgu3nGNcHpYA3ipj-CNgBpR2vPMG8NU_2B4TNrd2msxrSyodZkN9tqhTE2FAnaQeLv81HUirgWejjdwPhgFyw3xYr8yQ-OjaQdok4o3IfgRApAhGmDcdqiqfS5Ibg8fKuU5CvTrWFuj0E0C9dam2E--JfJ9xP_vK3BNTbHleA_1rhLWaYW0oy4gnC-sQgDmUWuPZZNwjr-rYJc4ERjpMTOIoNPiD1dzHBY3sg5JE5OZM1D7Jk3ynenD0-oi-AXMpvscKmG6IGU5TPqBbpuRoXTDFqsYH_vlX0ew79HZaUvsIm6rUpXqgr9lA2YkaKcZ51CR6l0G13OfQKxttVeDpY-2_haoB5nO1AABa7FVy4Laydp5EyflXFNlOZpbrtzXwU-S2_JGCh_wyhLnvsskf9WK5oZKLbEkDq4ooh_8D8l_bmgfyCqFKNfHS5iGKr6OX3owZ4Wozfq10WO11vi75rhS62b75OEahdBpzARWW7N9MOC1eJUpSHgCXafaW2YWENK5DJISZ6MITkscekwpIMBMzlW7gOKpdZLYSLVt1Ze8ELyzRS_OWo7dCJ3GVWXYQSPDNQpsNPQ_lg_3OVOkdU7JHELMzt1IiWIOqhGz2uRif9deaZgk5iRzGJkZWZd9Ele6mZipL0bSYxEJ_yi5l9PTvXZ0PoB7qyiCQbQGt0txNyvaJXqfpLpguJNStat9OSKnT_7naNJPwjNzdK3x2KpExyBrLKd11DyLnhjcdki9PLcNj2N9ZEugcQYMHXgrbDyoGqQm1BpasCZH2F4RZsPKETQPV2-pBI9mPzIgbHtjrbrDJReWqo2WmU8eyOyn4xm77Nc3iewHFrSynCjKFBZ9buDMoElmb2QvauItkVyOcQrqub9AWNHl1DRdKITu-q_jRU5bO1mJMjfUVtH1f5ACDZIIQVY8BzvfzdcZ4ziYGW1j64ybdJsRKYv3BKLoOJuS8d7zABw23nZGA50TXvkqsyOhxxRJmrUCAbXsqfSN848MIoxBU_P7NZS2UvMwyztTbQCoAEHp439OCmEdc8FSU07RMKhGAlrM78qI99SzlYVSLJjqavC7pXZ_hUWbR91R1Q2zR17_gmrCcRRzo_HA7BVhNo6g-WVeTR2DQyMx9b7TcdJqSOdh82CtrVCDzWETzMiET575A0e5YAwh4arqAzyqSMmqsoFqXRCWNyf5bjikOAVGSwePmGNbK1YPkrcOuoxEYQ_soisfrqcVxyHHC5HiC5jHw88JCvdm6CAOiFjs33UQ1u0MVTGV5O6Yp6-8edd0gHUFAvpryjGfqqDwQKBwfrJvk-eSxi5K0DXckPVrl2yExcXHaNNbQTd08vKDlXb65QdJiPfDMVkSPVLQLmk7R-R4U4TR2ZeLTtCBB5KxTSxpblmt2UETc5PvnVPE80XMNj-ax-zzPKCrv-elKoSKXtG1iblCnZiRlV_YOjgHlJiN9mYbK5YeTn-tJgEalmXuYinYQdn0XGGmQahc5ADpoeBA06Hc2KVo1VjTJlmhnw2zf3lkXfqXLmgu4KntIkpvo1AsEbM7ZGX7_HrbngVuGUQFoKkECRSVl93aXN5EAdzt4cl2w-_uSKp1EZGgnZu0UsetEvaxo-DBNatAnIOuh9Z3aoiOuUPdwZMfOks4Sc1nrvwDM-BDoG0YQ86TvVje4ZrDlsvmAVulwsmjBIH-1otttzx9X9CeWx6h6WJqIBQDk6X1DsAmgg9DeZmRdy0UHP4q3rugP2RMU9FKVasn9o02Tqwz1l-7wv7fJtB5mANHv54D9KunaqsYV7L8pxacuHFasVmAmVBpxcj7FJElTU2g_9zev50dIsr0xX7_o6stfPsCHZ-pMuVsK2LEUDmBoAFxbwpW8BMV5iJwljisAvAXekJ2cQUejJOYKavpiwSjmR8Q42cUgv_doXjx8c2elfHFLAiN8d_nSHXu7CCoDCL3eNXRl-yBGKZnFInEU4hY0RPe5aqNUvaofd1bpYuMixIJvgtUEujL9r8vLIVQuF-9u1iHvhRCbkNc9uB_aDiFMj7GGmO02wHNQe6-oAzvWVPQ9hlX03-1W7ZWbHz209Q0a4p6AhoHU_d9KCSdWHLiKDp3itIJfRntla3IlPfr0ZwnBRVi3ukux89RtBotfo3W3m9oKJXbO0Brn-_uXavDBfKhFfNnkFhYKGcHw-_A0oqeZnPExZ7ni9YV6X_K4tXy7quNHkqVk_ATg5ukw6rH1P35lSsZ30cpXj3rc56K6Ph6JqASmhV52GqOPB5lvwjIWj0bA_TLQngNlkpOl5I70h8lgiJ6mn-WF9-IZ-l6rfS72wownVdFGrCxGKAAGtQ1Dfz5rcvlautdpT1O1Aldd7uSTBw3zu3EncWTjZa-YaHKNJLhEu_Y6qMzcup1fEshiFF1BRqCfDkimdCqDjagS25lAaIKSXFj5j93x9wo4Vp8ckgulcRG8ZzTwiED0s7CJxqcxTaUcH1dF3gVurWF8LActdzr_KHzTy4Empso-zOHEkCPtbK4Xclz_M-x0YNYXE5Kak160sO7kXTUc6UGKCU4ebaHsJpF9pUL9aG2vkzjG1djFCWarNws0AiKEOvsrsVIFzR2LLvn9AAtKwqzSwjv-iU9SChrX4o-pGN6WBWZBxMPskSHkFVZUvq5X8nhugC8UhFJVFfwD4CXP7TTmAbYGU0YYmmk_YJOpqmKSjFSXqh2UdIhy-bEnpik5NBF4zbu8wmqX4Y4m3cxJAu_5nD4v8FoRVoxKc0eKd4NXJo_NC75J-r-PPqhF722G3EMF3wMfW5z_4y4GSCxpFxfMJj433Y7Ac7rlzTyCVe4wdHLne-fMhGowKk1F68zN2m_5vfqjpGxXG3SI3Z-n9VkZBMxt-C65bMlmwqcVPWcza_hVFNA1y4-TWkAnIcevsGf4YdRnrc1BT6WkL3PEeOs69N-z3iGxc0v2_VUWOYTZ2WokgspPaA2l9Aa3RCzaFagIGnBVjNHZ_-Td_1HQxM_3rldPKk4YMks6PAom0WXlc9tEac-OINvnqGhksaLGjkullxdCZ9yQcAyX3N97ghTMMT0G7_zssMisYubrIb6LHuU0IVptczNjZxVdQA_ZgnjyoVuG6PKN0t4UE9C41YQgUH2F6vWi5X_i8YsjduWPazoQIFHLTsOYg3xB5YnoTC_2NIB_c8g9VTp3NdSfF05RwWKDaKENzrzrGN8FiI2pVviFDKH72Hu3FQWGkjdfvTsiDxqwbkBB4tNPSbZq-laxj03-vG--U2Q77jOr136nIPTRyvWk1XN7-eCf7YElNpYrY0f6x9zcTfdf75xtPfSQk_9-adeEYJfqhB7nOSRm0GRW69NUnp36-IT-gUfQLUP9lOXzbRgZ5tZfTcymZZu6sOvn-1VEdfERAvxuaw4HTO6dfeP8iEVDS2xxlFRY7YureKcEmqZ5Dfui-nyCMt-hnja5zshR-Xgr996PdW9bIih9SUHBJ0rSWFrsZII5_YWTQE3w8lhGfXdGnBH5K3PC3nfRoew5ZuUUMMM_c9c7weXX5yUGX9hxJVPDiLp26CCc5glQnZ246rkVLgYrGKux4eRW2Ripy93sP-uRKARUXgrKjcyy9yQ0pK-3KNivSfHr00IkT_74bEcbs9ta8Ti-Y1t5SCk4evtF1Z1bzUAKq7TszA1LxZ0RwfheezsMO6AqgP9X9NcF3mDTLEAtRcEe-j5mWeyUPkK5Kun1-hFhKfbPPtctHkoJ3p6Wwhzoc8vRHZAHJJaVy4Z81RXYQIeXa2xfRF2zSk0Y_f32B5BVZAoD7vnTcWobkd7VOcnkEVLsVjduJRn1umQ0liUTLld9SlZ07GsDIDXRtVK8cMdYxGgFjKFhUoKvqXivkjKOkORDQa7lweNv-8EYaUkCtMyVfXNG_S0Sk7OaSs3mtO3OwhF3DwyYl2-r-5VYM89evYHUYKt18UUev7A6xwRE-MR9dCQw-J-wrgp-TYyvyfGJjOiCWedrHAvmCZM3rzJ9CTu2-Xp21lo7RG2p8cCfdwvE9wDjDJAmZ0KVUODyVR4g6p8LmoD4lFA97CsGs5Y6WaK4KFBrdUooLSixe0YxyQvB3r2P4BW041Ilk9jwe0wfyy16HQEiC-CY0DYmHo1bxTrPBw4LopMrTfFGmHhIroCV6VPoQ--YosLj9xfmujDOpQTeXmd-gzCKkiqE0z5xUCPv2aY70Xyn_P3Ut4J_jaZKTxFfRKFHRISQIP9JBTTqfqbQ_S3gIi3QhVEX5CyEDtdp2irQFFB_eZIXvMQZArauZdaq0o49bfRjO9GGjTDxhveyvlLgU1jp2zQdA6tP31HgRGfSthp3BsKq1Wk6xs4ewxHQyAFz7705sEbZ1QQ1jG0RtyWKtEzAfMkzAGNoaAqXI1yNUmrglO4atqvBmVL75DH5md8_X1IXP_sWTwTiG1QWqOqiA5n5jQ18oFWA6DykMu7KeLliB8NJIPG42bNAZsz1iNAiySwFE2ehOKr9WnAsjmLxTu4jWSnERBaARmxW32FShdv0kD2RAa1Zuz7_3jZOkv-n9zxY6kh3vzGco8IMTl_8p-tfO1ZRXtW4ZKjkBQsu8aGjOwmh4J_N28-0I6qjXmJUBja0Fc59FuqV_BGrcBaShQGc-ahv0Hak0BK_Js014Ly0IEKfQGLz-xpCwaV5d0baCFlWCB1dP6f1_SkIcg_R1nhtMaJKBJOx06SLZNXipuCoiyCJiUgE9HNFObAswlioTCNwtAH5u62k6kS6YFINCH0Pq4kIgFlsnB1dLyH9zo2W8ZzQWRs6zllreIy6EZPLJwfLx-8Wy_CS7cvXXQ7ODLH-ca39KxLD8HiRxbJRuI3Nk51TSgUoHPNn3Na7GbInEPOKF7kas34_f1WtmICn3Nk29EL3jbKW4zEmyvyPqrMt-bd7CoUDxLqtsIgtEeHXj2_VsvulkLt199aBs5eieflq5X3RBSymykCrLpEbIRwpARbqp62nUUl7z74hEbmylu6s9SzxuKcuJucirrS-M36n1Thbeq5rSolUUC8Sjm4tiCAnSm2cvANE_vQmVtbN7WX7DbHR3e_CkHGO9R4mBDVsowTu--QC5eYwjXsLn4BVaTWEmBdlfL7sg7DFAel9aBO5VECiITDZuU7zTh1siBJukQwB_JJzb7Ax1TlTyHTRNdV8UFvki6J2XVwvrted6F9tAcN1WPFm8QQVBGSXxOAgiyAYCYlg5DvYjBYL1V4KMoL3DkshmJ_S9ZFDcPXkOEKGfcDdvXJW4EPYt8TIjuAT57LolsXkpVfBI5ypxNtg2-PJxXUMcYoOKxnEXdczfV57TADVUCxSZAbr3TZT7ww5skXPwtE6m3si493B75_273lex0b_m0KGdN5kOEFgNnJU2QYDn6SUSAjulR8XpKfhWr533uXxpfSvwQmi6VP3tCmJ4PNBNOwyUc9op5c8tURd-9HqjHEu9IhNnDx-tb48_ycVIoKeIwki_pQvHWyL3dwW9_fP0d6E20yEvSRXNy0tSQ5HmmQf-ytHihXYeoqzqvx0eD9fMHyVdfy4KeTigQw8T38Jlf2dEMYgPdwn_l6bvHD8c7Iqb5koO21iP-1wYEVunUvlJ3deiuWNg65f4EC0__mfz_E1iFwzbLsAD7X-6OZz5z6xwazObA08Otn2lBz8p7rnl_5Du-UXwQhqQ7FQxljL8uocu_PhOo4Br0nwPSuj49KVyWNKWHzFIzsfG2x1WsbZ2IOoT9e7NxhxZGrC9UKkKaDx8QARm4q3nuJdbqO9JQXxVJNZCA2Yltsf47yHMj6IOoa_Clm_Or8Nm1QC-QRTwAkvY61rJqAZzmhOxFIF2bwH8lHy1xZrrPGd5g2Gxy63HeLeuaX342dkzg-mu1_k9oR3HQ6y-ZvTQT_K5d_7XZovFL5CleWG9YkVV5oYPpbwh-1ZhctDFfRgS004bqNP5rGugZ-ri25lFuY7IZF3tn_OPhf5UHdyVMYEXmpJW1QXfYkAW3sTP_WsLEMJ6MIF2jlV9tl7_tIXYJXKIIsYPni8PTY8YrRUCzdWkONz4aUxDVAHozY6_TykioR8adOiMuYXNCDSfaRvoKd2Vn20lsbTjoYWUs7VcSZ7GuTLaXi1UMDMTXPcAi1VbCECWDGS7RUvrQry9LYaEzCO3jM-1aa2foW3rYpDJys2tw7atMjA8cLMVBIGq5ayaLMn5lAojRpzUobBJRWOecwod4Xf-AfI0MoFPRikg8W_7-I2_DoCfXQLrKYQHfSfybCTM604C_y0S9QCakjlh23DzdjQn4LBMwOM5t1AvecQanxX-fm5f3c-tZzjUJCePfgYEnkBsmh6QOnKgLrhiAQCNaCXl6P3M3FZcfS7jWWBNEj8zUkefSb49Jc67pWndPS0YlzaU7Rsaz_IhD3qZc8PQPfogNmrVFjx3glTVQXRH5fUFK8MDeGzQMknNBxmD4VpDcFbqjc23p8gZ-OfqAfDu_vwipcph6k7CftPfwGY8JtzzAI7cC7WX05_70LWrGgU9msqqP1kWPmvm38P7OAD4yFk_krhZyF4ISYkDF7VfFdOmqq-2u-5J0xXGVlA6vZilExvLQgJm77ILnVDQMUgXYIEW4aFCZOi0Y6rGmj1RVxKIP1gKO0yYUg3nhMKND3AxjkG10TYiL000apEJL-E7rXcVHc6wx2BLfR1vXvYwaacmULqHg91IoG6meEaaKheEVcA6lIPlOE9bP6LHy7-v_43h1oukm1zxe30790NTmnCtBp7t44TfTGYeOZy1L5Nbh2I6u7U62c4DFPaLCSbofN1wJ4a0BSKzojN0ZQEP3oet-3NQxrOvqHM6jtqRfdZS96X250JyYk6ZLv2Qe8l4tk_lKeOV0Hy6fAfXvu1ibQ0R-6prL1TLdZ8PYCiTPlkekk-jCSgLzymiga62o0oKkno2jX4T2kffe7KzW2IRAMgyyhPOUxkGGZWCEXVk5dBPeJ1YVUeqMotYZZkfoTfWzOKdyRDvIPca5PrjujPKSiDZmaCFZpgBiJK_QBUw-iNKwAnnet8lk6O14iM7jPJm-vjncpPgQvW-KhcbHcVzm1X5P1GA54G0nzsTnB7CnTupXD9cW3JXWkxk5Na0BrRLQN4B1VmEPeBxNB_ilbGVRBFaEdp1EqPDbKHNqQps4xdWFcchQ3UB_UsqrX8z5H5BUqBD_uAYMTiVvQdiTXbfJ0TWj9hnvC8mBysLf04KVdcDu5I4sHH_OWmkGidp-3kh8JThlEjApj_1QicNZInUTafcRD874Dr_EIVlzQJqWICCjJ_GZ2HQQus2UI8yHbbbdCXkP2INNs477iE_IIpWonYKm1jMnsvz_mdl8s5REKrnVeI8rm3I-Bt-01b4geVsGolM942apzIGby15GtpwFMOzsQ1fg67-fQfmHYzh3gNTKzUmjcYjDV3hAbkC56hMWFcskoxd4tNmxGq3FzDgCLNCdhTgC0_LYu2SP3Wp2zXdPUSTEPUyS2AiXMvvDfSZRHQK8CHTam3P_MaymWK3Y-sxiZkKPT3U0tgRDUmXO7umJ2WyZH6o5PIs9ShYzM7vRIUqpmxcMXal-yIy4F4nCKywTZzgXqkWwoJMKC8GcD0EYH5ZNyUFTJjZN5WSg6k8LMO3ep3khIPGQQ8i93MpwwqBu37ybt8uy9MKeZGNsoI9lNTIfkLIezRgTLP8fteUX3Rz1NvJG-1ybUSG803hdjBuacvDnoeD3NdqvH2nX2z4tOw5U-b5KQbJwBMXvnnuqjBOdhIPJvJWHG6MVUruLMFAl_GP0OqOIS8jV-jaVBWQJSm5WQhE6zNKSKhsZk_DP81f7Nbjk1aU5dK6aOTRlv32k16I4nL0IgZeGBHZ6qeLAZVWWEk-vaj44Ec5lRX02yOS5JLYEeAQfzAAXLSrhQIBbrb6hHJDDkIuuXXrcVB-fwWj-jOeYela3fNGluJQpCB3rvTumaoVoeNQ0tPKtBd3nDR1_J35nxfCwRdDfxwUV2kR5p82ZCpowU-rASr-V81Nr3agZ9v1HVXzOBT-yoMRRkxOfCwdeg7FFrwS_lFTUCDBVA6YZr6kagNkgJPapRd_WYsTAnzlyquWrYcTrirliKPvAfEgyBbyv6MsH-MQVRtcARAu71AKlJ6lnpCSuPFXUj9sAWgWPw1jASzGga6z-32dr-rQ7dxtT1Syx8IHny2xlInspWruX--rgGdp9ZfpuYoxIw3JMuDUL4Dw28mjZi5F4_WC5U1L6ISIbHtVlcLmDv8Ud7a5kuP3mYqotAfoWT0ov3AHPnHk6eXfw2OIHtxHLN6Jsixohog7K9o-4CMCtdNWObWhTzrP2Ys83WLQtiNEWlLMcIE1DR24baYC2Kcjql4wFxAudTaOgOWkJ2amNoJToYGyCQrYPwlWdS8E6JViJSt8YCdj8D-pXXKOkptdBtVCAzCLIfwgia4-Q9OifkeJgz3NJKsNmmEBElTSTwKOiqRpu4dmTQwAW7p_kd0o2mFn7F-kXPR5iNfehyWtBEiAuW7hnELxX9aqN0cAQn5934zw2DQhCKBIXCrFNtBjMiyPh_mpY3Bv6eh0eIcGGn6us0NUra-e1PKCR8RyF1bdQad5-w2aTxffKI1Z_cC9UQHslp29iCzVVECIcWJoL-PqAT00QJjO7idWKs05imdaVP7bL88GSpEBTcFGZbaOALTzn9EW3GmUfjF-B56bwz4QSYsjRUaQVsTyf7uSICDst79oIIO9XNeIbgT8ZeRn8SSt3AXD7Kty0noO8LHwXN5woAA_lurLIdmddU9GZr7CHDNmF1g5QGFv8GrRtx5iTejv0dUC3nUvBtEdMNTBvP5mbFg-E5dDc05Ou0YTgnkUTBGSWdcqEPP449Sg6_BZoB7y1Tpl3UPfJBs8x3zTq8dHq2qgewTu5kk_Bj31WXQbFOAtsp84OoT8uC70AXYQfyYpJb5eRkjFYu0m1sPbJ6H4HQSlzojBw5tiFVYGubNQlIZ_HyiZh66BwKRG0_QEHNsIz06wengDV2JByFiSawYtP3ufvr-bN6Nar0imCnJMKjtJy85gRFR75anwrR6Orc0wLt_DJdrgv8m9Ht1lEgaq2Mr5kQ9-asJdmq9NiJjw1f0XJ4wuVJjxbUn319kpgOmRV4my7_VqgXwWF9QL0PAtx1uAq4QvQaVQDIYcKxu2GZaxPyvdLutXP3Jnh8qYcoYsZSuTTrdR2al8Cpj8wdjFja3g0z6HD8rkOxS36fg85jiTf806mNocr3rZRzd9HcxYVZ-xMdxBMTMk16mZIvtxYvDvKiltHxbVDuzkzn1ZnfZnKQk13kMHZ-4bLW3TY6QZjHBuLhdVmOgSfgaHspNB0C5ThbzUciqMWUm02FKPdVH7U9GtZ19cLVI1HMbwtxMJWIUWAVKSA8g4-8AWKKON50GvRqK-UqmVO6QPrMdkI8QjphQIFtZTs1B-_kLbpO9LASHwuPaPgDTlxCusH50KXCtiCHGrPqAIiyxGTpKDX1s02l45ohnNsQrAW6UVK3VntnpxhdYH1pq1vR7RhsptrGQcyOgIXGRy4b5Qu73hz63BzsWX87hl2Jo-dwMIR2B3onz9gam2HdPfXnZw7Mz6CNJMRDvNfDZ_zOw7KQtLjlDicd6g1dOkgrNFNaFE-QrQRDL4AGpF91YiKNkYS--GNACyVgu0-mDDkLjbtyTimzWRjDnwIU-n5KUOll02BWmEDVixMYVrGWbyjezGDKbhRFONipBFCYpV5SrkLKCUZVJ9MaufPTjmCnh48nRg-snQhvKNBLt9BDnFyOIBfHR-0kBOZ1ypZJR_U2QbkZ4wtCXX2lDbK-gVNxMtAhkXwE1PM1QQzhM_rccdC0l0OxrjaWCyewOAOPqQ93L7OnaKvKVmU4jMz8iNqfsQWus5S0KrJg-zNhJu163E6mI9y8i0qqDmfBBE3kb3tAfsVtcDB7-HvkOyLUZd_XDW--NOkcMxR2HkmKBRj-UFnUr0p13BVjUyE2VVhNy2T2Y5qHrKZNTcdxXent7byIL4XGowBfEyC6LMLkW2-3FtIKLCZ0w9TJ6OwSeb-eknMRYO9K7TqHEKyu7Ia-Cy-UPo5b9-qPiQcGV4e2k7Eo_hkuWtOaaM7I8N-Ia6YmnKIatmCEt9XIylpS3hh6tp88qiziPqEAqCkhtCqGwPsXELKTBcihszIjnwL9y_dXaaefnDOAVLeF1q-LUYtORLam8qEhO7Vsogo2Tgun_m8BS8jjC82Jpqzx1Vyj42N-oFLUWIHI089vl2TCqHmCqyVcnPaaGvPAe0HeyvGvdtJEZ2n_yXvgb8ZTtwPCDmUKzUGRmgvagbtPUyEG0i_XhjJ66EHvEnHwDJ3UX-jLfCvfVKEJFEVyG38P4VQ1M_JUanTwT6HYXUII6_z_Jvb4_tb_I7LCceG1zKX9BNNAUZ6-9tPCZ2cs0XHOdrRt_88pNtovIE3cSvZCqdoypZjba5h2vnB9E8wN4cESuuHyJKQ97la5bbVZ2YOPMuB66dcEE5KL3JGW9FpmCeY5BgO9fcb9mQ4yMGMSdu33zwZa-SgjAMSU7qCZK03YqC5RaoHfAMCg6rBAwGGNVkjXwN4oo07SNZ6E_lJyAAFyFOc33IA7X3dgPCqa0BeKlIPbez4frvrZDUl0zYwdK3EBJgbNf3w5CtGvZU05zSJRDtnKZmasL34CSYmQk1m98e0fSmtjU_NhcTZhr-AQoSx0qrA8pTINjftCnSM94vvJfG8NA55jybQn_d897Zacw6Z1yuyRUelQblpVwHQLqfiZKCtCEbsZGcvNdSu9Wx7-FrxHHX1c1058V8hcK85BQUSzBkuHU8A5FtgogpXS4t8mq5OEc-hZakFH2Eez6iJG4SMOJ90WyfCo2IX2rbWtiXmxVUGSKQExev0Yqt8I9O6QdaWlWtkNEoS-XtXpV6KxLF1sZ6jsvpNDnpyMNAfzAbqFWGQWDWPiSar6abw93lMSDOza60-XGBSPhEeGFFyh7h7zBv_v6T2CRWY_u9yK68X4OoAi64IRousZBj-F-6WIpOF0O9OEWSjQdvW_ISD50xj9DQqm7P5k01ML7b06CU8FtVKRMZ_hY05Qp4aibFwRwkCrmY9MVQBe0eTvDNh1Lb05QtljIpZgHalfU1taJyHqUNXHC9fbknef94eksTePM4nkURJna5b5jMk1MM-LDRf833qTyQNMzWbd4WY-4jrMB-z1lU5gI91Q7Z7mxTUOjJq5mQd1JLSqc6rfzpBBVwZy4FwP7Mieap35VtKrtswXGozvXircE9hlDkjZFqjw4GV-z9CaLzCSjvhqdHJmI6dkxqXGUa7BCAywId8UBTbTL0rw_yxD_WVXuOr4C9LS_qnDFOtaGpT6OkODdOgzaqBaY69IpCMJYMjiDMId1GPbRAV-0rAQ04TNJ2LKIlT-GLd8eqXmn1ZYppWrREn0g77hLSbLiI1PdyGEmgrJvNoTKOxbLSJ4B1p5Und5lrZ0RKZS_ZLf54msZMETwCWghcgNnGvP0spXOfB7-azH9qhcYCwpsz0GGwYmUEiX2775Qk3dxfnasao-Dq7z9FdgCUnPhet6jIO0PaiCgmb_bvCcHtITmz20uJGUN6dr4WZmShU4yaqnB-I5UGNQHKbC8PYIp-IwwwqrRJgMvtpH2581zavOOgVG2LQP6BEroRn3pLJ50c67bxSWvYFDWa6Ftjt2d86JYg10SnmCVxLnB1_vxWvvKoEAMHl5-MCQ-jCmnA-pJm1dTP3csDsqFLA54HyIiZN_kXjX5ABaqEOsK_tQkms6DIQmNOxRIsw_jDVgx2vmoNvrmpi_INobxIDZ05fkrtjVni55C3TCMs_amNLnOnW3e18My4oypX664nhy0i3Lhu7xBbaLcgXlgpehX66cOyvgD9c1BoqlirrVlY4t_PB0bpKdkn2JLeIHvie3qUdXXZ6LAZjIDlIp2N4ksUceS_X7svJeTfE4Xy7V-UGp40LJejCZQHxYh9UYVBp5adiVRkFF51ecYmbzFjxoFQZctikMn8id9ityNIKDaiVcJnntHzqbc79EdfMP5N8zayPJb67-JkXm4PXaO_9vXGP_Xh8zfioeJI1x5wrID2n2b3AyseGk5b5I3JVgLyg_KlCnqH8mkZ9jkNrb3hAz5XgXdbURkueqRPTatRdzN-x0JYKHGaVs64tV-b0M438E0BFgUSEz5yufzSOyUb-TomRgIGy1laIBVLfeHvAiSeThM48y1u1hQuQ2_imMdlYZrJBwWCgfubLQLjRlh1dzlv2JF8rxLBQ3OQGZUGyb6LzIKFjOWl9k59GXhbqY-MzJ9mO9W0H16PxgEjwtj6-zszE7Mvfm1wn95nCcQiLiTGOgyZ3oqQo67IfkYBZnzpT4DzKeS9XMm2FiQ0HIuZKnKSdRqHxqBraN3jkriOcPi9870dNR-mPkdZK1RrmlOGeYtyT5MOjwv60Oml7H8orWU1Ov9_4751Yy6QPSUDdQvAKQZ_TU5XXIxyOdeps5cfAne3KsX78SyGeXhpysgunTPiMZqg3Pl0iep9oniFPssRaiSUmu3TJFQDOgxKjR2hNRzooXVUWR2Y46VRl4NXAIIBR03E_CCee2VeGbq9LrfdmHw7FuzNFMQnszqZ4makd4wWmOJDbMrGF4ll79LslhSGJFPLULXGzUkLqx7DismKwQKbgmB4T8MUMBa2d_2YazvAigLYgwsCaqHU1VYjJX0GSGb5VUYCn9tmmOluzE5pL848wn0lOkQrmS5AtOgya0E8FUGMkJ8Qzz4iHeFJ_8f67ogxYsk1YhNRXfgbbzdaIJ1JdluOlKcfcXEto-cA3UAdjD2ZknVVm9cIqCHDEtrhDQArwH64QhzRccZYdbhEwAuGkSA5wfYdo7L3GysHVzd95arjtNF5kwSJ1q2AO4ziqRIlXiHnjUKTpKsitZm_iSelnN3i52FGN8TtOzArPWY7kw0mDI447TH8GsX8Fq7ae6kbZp39ma8Vh9H67REA6hh9CNtOeyOJmsQWqGT07K43376HmtHPSIzN0axujk1pkoeV2xteF_B3--Latr-hdqMSrBbVm6P4bAWDvHC6qY0Oe__JPNwzpMOg6oUIvPzlG9c7_2s-OxhZ8KzEI-OTLdwjR7B4X1p6IoWis3SjJubOtR7OnZLJ6vKz-fGq2tBXCbNUyjHEYZiNlT_b1PAjng_bWChRcjb6X7bpepvb9Jv4CLy44bvmO2YRSPNAEbSD5t-Ya2yD-FsTDzsyKAcL8s3gwwjwKSFWguCwUrSH90o4x0w2QC6fIbZ-EC6yhPh576jyTl0go-a2rxRuNoXuW7717On8IQZpJFzprWwRncSYVUvH5pd3NLH5x299ajRIA2WH1MRgsJ_0-sFXesIWw0YwfW4yn8dhGmyqK9QH1_JTGG-0ysz__eTn56mHnwVGQia_nqDzQn85nNb8tJrNdWk-yZ-SSbr_wVNI1XBh3rZXZ9S15Kh9XiYZQ4ni09EPLKVDHoTULMzQ1DbW-o6dkUL2q_npOkRk_0_Dd8eX4t8s9fy8YsFXczIfENbKqJ3TvevCJZxen5hb8kNmISyFd2dXbwqEqRVk33gDAhVLr6aRCJvsa7pAk_xgyidNp_QRBJl93B2o6i-Y73Xin1IGsy6hZarxP2D6ev0NR2xKJkPfUOC76xLfRUh210i_kjzikqjwupTlCMdtawNZ6CJ_gXS5SG9GsPUjDqcNfRkMReJVST0v6-RLbfm5IQkifeGETFBnfkwqZiacg8z4xO7Yowxxk8XaLnKT3tvJfHnPTAqEOoQnxzeSyPITbTGViyZlTJNHPDqGGfMPo6vU6ADSQpA-W28mUza3qmYf9FuYGAuApDi0l2zlqNmgzZMZL5bqLmavzLDHIenX9BjVOCwuIPl50AoRKyLIL9vIulgiSkPjoDUnwodnkK9yDLKbh6sP6FxmEurmxvI_UL6Nq51j7lvCkLwKYDGp_SdPSwrngXGW8RLixHeCtoejacW3NpKV0IO4ZhmlWUql86dr4PPhcKNEwquSGh4VA5C52qWtgarTTpR_Kzy7h7TcHS-dMubR7qzuXAeQyVvLgxQu1papIa8V-Iiud6PEB4Rpt3jPBBEOeGRiEAAG0TgYJCUvsHp3H-GhHqa1FyhTKwrsVCcWu6rKBK_6UE6SRpXMyA2PFnb5b29vKpx_sVwvW_NfVFWOmgooco7eashZohzjK8qmdeJSAojqPy3TnT7GTMNRFfcaExvbkR7-EX2LiK7lhxe0emkYsfs6YK5OPvXeucmvyQnf2kcTrplrhrSipCAn3br66VkvH-TB3CJU0fFwb4aPKLRjUZaCtF36nl457Cw-ShCthPSHVbQ77x6a9gnYuPTDFs0t6F0SPKCdP0ZA1f1rV2jsfeVMkKPrwHS76gF1-76VvZS9_s-dMysid0HVg2L9OkiIUVneP4e__bHPFMy9LI_tkZamVGn407vs_HXaS-ks8m9DgNTe7LHDBL_uSmxcRmGgGa-_jCXNMjfSByFU3jVWo_1PhSVP4NvcSeTkmUK6_9Q2ns1hcDbItovBtho5Lm7GtPijaWSywUIDr0s4HlzupfXOzEVXXH7lKZe7-GcBRJxYvmVLOaBbS14Adc_YglbPcAuH41IqGgaeBjdXLGWiGS60eaIorw1gnAiaIjCgT4017gNcJy7mBjzpXoo-59J-KXd5qfVpP2RyfEUVoP6U_kd6JeLShOKCEayhQ2YbmDY2rmmaoAWqpzq_VtQMa1wP7yIrfKh4LGPNscGXZ9dt8B96TG60sQ0LfmyV9IESoDxwgoZOdjhi9t3opAOWJJkhediUSjX3VcnnleAdworTEADv38KVkH9uWdKtG-OMgReFYj4L9CDJJA4C1njGEEkxZeXdj2U9vvmq-dBtOJis30jbYNcKF-sUiweuNEpSKIsnAgiLhq1KUq4v9WMhFDRubb-B-RE-oXLghFK_4OzPf-_eqLQqvrGv5a5nZINt2QgBui6_2NNvT4YsHWpSw6Ju5zBLd4Z1pErEo758AWRzhrlf2scXmuIGhDnkN4D0rPm5kg1nJ3yEb5va-0kNtTlYl1D6vSd5jP4aeaptYFUZj57z2WhOTbqQ7Y5VCq7ca0R_-GZN_bxBGR59WWkP8j6BxoAhLfQfrsFqDTfKXhiiAtyS4doUS2jQwkAHKOLu0zvBl6VeMufmAbTwmPan8OAw4rjhHk1ILUmuw9DnYCMy_PrCFMoKDva_RYYC5LW7mYYC4xyMDHZO1z00msz1TiNNhuvmh2K50a3TNoe6_XZcx4sYMHAw-NUxCxMjmy6d7ZHGztVnuwPNZ0XrCHCFUMFA2ex5tKj-jMWte0cA9UybYFgpHJp0qaIHOYE59VSjvdOzSc57np84wjfH5v0DsobFgMHFvmbEwo24kTDBGdWz7mVgow_06C6dtHS0ay1SMBBZHYXCTY44vU4z-hVNlJLM-makUOkiEJDQUXgl5y5PIdn0YuS2Kz4iv2tlWtNzJPbNs9g_-VrRIodmfvX6BFWNhiXqQ1gAWK5IkZyWgMFSTWuZo1uygt_TaEyLdHVrAUiJ1vVjSoIFc2VoTCpmbms98jSDVT288sTBlZspNz3M7UNXNZm61dVy_e_4FAJ6CrsIqMfg_16si6XZ4U7KWBPrPSkM-0_JVwspHaWByl1U13qVhC97mXWITJmSDd39cJdhz67l-uHTAHGmJU09PprQjPopn_VQVobjDnc39Q2rIu0yfOWvKaEwHGsChzBI5aCc4KwcF-BoTeinc-n2UO_2J_cPtErCCTfJV0Fz9vW6Gm3tF0pvMRx9HpIH4ZWQrr_75YS8s_HRkJq1t5B0reE_ctt3nh3NZThwCRGHsUSxNrS4ibfRcU4i8_2N-hE_Lw3aEXO3ytVJ06t53yl1lnA2FA-N7bpw0MByzzDlyVjVzU0Iz4Bui8Iwa8iVQ8PmBU-eGifqHkvLaB5hT3gm4Q_vxPd6DVn8sNW7AhuCWWEZv80UE73pSO-d0FATenYpaVV4hQimccR3TW7IwRR6VBq99LEbu_Zau7o-8qn9JUataaoKDQEZl_jlezPuGacXlyepuCk8O5MHP1gELMhNXPV6JPL5QHlQx23G6hE1j3DXVejHEuc1zWVMns8CTW6YKRUaCyQ5aR5ejDWB5om2vxqSmNies4EVqKhrqBsQikBBKwDYDaGORNeflnw-oK_6OfCOfaAZp1vxkH-QCUMcxiZFd5O2huJTIUPe-HtcIDSjK0t3kQBuRp6OYUsttw30JGJE-ZRA3lea4wVW4mD2f1v2gAZZkKAHOB0je0QFGC1uC8Gb4-153y9zDP97l5E3HqJtz-pJ38NCHc98WbGOuY-mbThN7tZd8JaLGRG7M1yti2uXK_uoFOuXQ4MbbA6Qi_XELHVLv39gUQHUU2jwndpHHVc3Md-Xf-6f5e1Z_r6t7IhBT4eKpNBz8ecVpJhoNe-s5JYpwPBV-slIjAglI2WwnShUUyQeULzhD3D7bYqUV1JV9GKnWSLu-DTfmK7UO4auXXFTXAzELYPT8Weshwpn2bnJPv3RdVvVSsjDSA1hgA7Qq6C_P9Q_h9LxsjT_ssnsogUlNI9BoKgwd1z-Q0ux2k7H5Z7g1IBSDUm1fobfULAaCCtKkh1uXBmm9c_1kyzrQfrwV-HigTUPedrBcZy1PHe50bgUk9QtJwgf6W31S2lwy7zWgfDATDL8SBHQQypu9rRFmQhmEWqvwUSok0kxN7CoB4aKPLHd84aRkGf7GUVRkFOvkcM5JRBiOkOAUpvV6N6hQO-EujTfmavlPWzebFuj2-9t6aQ0RBY7y3rxANi_U5PkaYAQWpEY1Zd_WQg_82q9zOhCDaQ2cBbJWviiNK8XkG7Ps2aGPBt6bFkvlXHYMR-HJZLvHtED6wPg3zQPEEwiFVG5UaWt4r5UCwIa_tQpFzc-0gA1bjdtoI8ng8H83mQKx1saOxA3pJ5fmEzZj-0H0j9L_MC8r4p12FMye2F-_pbTV6EEKFtYUaYNG6b7voTIb99Zo-40J-6DDnrBpsR0hJtV0QG4JbK6dlpkFf6ETaclKqf06qP_nePwQzaTk6gXsP4avnLBVBSZFJSp43ssNbGhjVTEafIDuBjfKPrHBbIGvKOoTXl12Jnil_BrUGnyqFANNeL2FG3PUBh00UstBxGHuGtNwps3vmARQCXmpadVCghC25Hs0Vx9bX7hDgUygGTG6yYr8DCz1VYhdoVDaqV5A08EgqTj_R9Tm9AWSCO7iASvLdlEM8LGME-GbzTYoRSF__KxjugR_1fbHw9trxyGKQaGHoHbmvx_9K-pHTevFK_R2yksz8sOWOPXZTuknBhOBEIOItfYL2dLzuu3jMwq6O4NABFTUEyE6YLbFDMVHG9oJalebwp9vXH1huuj_oY9hXvjvtp5AqDp1aO9wyHw4-PY9Dqf2cN7ntVUZbK9reVFD3zWZ9AG2kpWkZRZrd2BOMmpxmUbd_2Qw2YKy6V2MXdmN09qtsPs1p4zUnVW3J8LamkGQCe6Wwp9RUoYBQIV8ab9l9bSMTdn83kg1S4tPrCWyxfJRAzDchswAOky8Pyuz_VfOUhwVPpB1cWAUVSoZrMIme7wfTeziakTBAq2e1GHHgPbvfxmI7be_vpciGt2bNUT04XaHyn_zskAWeiWUsp7hqn7VfhCPbqXi2rvSmDsiX8IVIbbnY4z-wTJsNIx6gLY9hYVrckpR1MKn7Q3t-xVqVyvpiByGvDEf4hq71AM0w9PxaU6sjG8RlHE0ADX8GV3l3PnpzNs1K32FdCxabu8IonquBqOtsxpnrbR0SwFBs9J83cupNq0oPsOTywHJnhkJYuK-l4ZqUYOn7Vl_XoC1SXEEVkcpghyyXQUkOSMH8D4SiR0B_9E3T1sfNCJHWuGGE2YsiM_jA22MPFbtkgCrZQCQa5aIZGEWLekMmIiKQwHMICBFIZ315ud_WBK4ouCjbEBnq8F8gc39l-h4L19Me8hePOUeunGHKX3hygbmAXxnSm4lPb0fHwZ3I-CQSRL-EbBZb5oSs7W2niFXiFTKD6OJqYJwz9O_p_eo8tZu04YJajO8UOK1XFTVx0hYl4gSvqz18sc48f-KG7fis-CBgTHCU3PyTixUQmHPuMtVxa9ufzLiV8E-b5yJmMpzxlSi8JOSTXGRv6jPcZJauVL1M-xaYd9dARJMD014mNYr4NDgaeW7mKTDPoRPHee4w4OFKTiCHFIYnKwRZjUJzxFkIe7vTdlCB4ZwMUwnb9Wd38gm6OASBncU56RD0_S7PIuhMQvT_zrtFXVuBbfEI9JcVw0EGNL-XrOqbB6RczKiuiK3SsnCx2S4FOVcs_UlufHscD7VRiqlUvZrXlyxNYFOnsEaX9_GIEkjHFqhuN69J01NLKlWrVUCOIMLR-1PlHCVu47dDzcyPTCoumrAeuKBHQZHNANyE99KJdoJmVGbrBhtQfYAHIaJyzQ6AhYFOQTCAY2jmbriJyhrtJH2CG72CWwGbUf0WV6cTM3zvgYVAN6eHHDaUNpNPej-UjI0_PlwWYozwXIE5kTof7CCJUXn4f75HDtcMaW5TEDA973J3oF9V_i4uqSGfCLqMP2tdjrCPXi5M-VMJqcDl2Ks2qJIrc85khE5U5MZJvFn8MxX5jSzb64gPYEASV8I_DQcdeRAVaU1GAOj8s4RCRq1oag8AD06Vlxrij6m31lZiXZdl2UdFoVg9HH9qudPyCrPcuDQFkSlH2zICZyN3t-zQv2wMK48Sp0Razl2Fs_EjB8RW_O0GMPlQC9onSIsPPgQk4hD7SVOygdwpHDSeMPezjpdUL7JDVS-k0gNOEtB9-yX9UIVSoBM5mo4b7G41CIAF97-aVrmqHMbf-nRVQGsEvXMATQLwXjTP2zST0nu8C8gEfP3uJqU2SmKPRw2VjTsMheTpSHzKYmpEjFq1OxQj7_Vy2GATeRFqQlnFy7a3KsLmZMrEjRbinhJOOTmKf__y2RcAIBTStsqV8wFu_ZpQlHmczxc6Y8ony8Wqd8VPx-AeWADs9Ck95QEz8YeVeAtaXLeZ-DDWDyHm5u2oMXeLfH1WfVUJF2O7LlqYt6T7q8d6jGUEmvdsg2CdM4JZAzyUSOGDdleqAPMCeVYlSnohNghbsRDtoa20ak0rA8ypz-fok_nGuJvWZz6dX2_0rnXie5ETpC-ckg4oBvj--pdil-QZTKGgYPe_y5m4g64ZsLiaUWYlmJOKAO3lm7x8f3AHlzZ4bRi2l8En7XaXMztk1jFvZpUVJPIDlCXa7nBUT7RpOXeTsxaxr7qJrWkznyqlDGPjQe53nMmuKBRYeKFsDftOp96ZJmAXpU8uSgyZs1pAInGUJSIsSlLxGsX4e6dyGVJ8VXqVg5vP-Fj_eNbyvdFgKIPuqH89WITVC6FEkk4BeaHsq19Ic8bYhpgqRcPaIT8ETX3wHy3pkkG-wYlICH7qfSAbAhWhzjAzGW5Nw3Pc8fpc9jSwSbOxgl62Dxfp7zQLhKR2U2YsNAAgWC0fc72e8_RSY_pPd_oCzu01TnzDFIcjaE58fCiBNA6oL8Nlj1j-hi4YWSGdQ8UKVejIuyFox16CuBR7nmz263LwVfkkLcX413gbqzE04ViNwDq-n7sBnQX-x3zKnJYYYW8TD4Sh3Sj3j1AYUyAgpI2Jce_RDDXGDy7oGmCiQHYYdtfQkG878m99bWquHd4P4-dCTeundjpB4Umr-HHmaeadY6_1bukqczZdoX1ptdkI580kE5vUDX2-24ty4DBUzdOBvNB64tkGiBxhAZluPpKWylP9smoTMzcWyJePPsQuLXgJTgpoEBHaQN6ttEUuBDK08A34lJ7CIlNmtdPmRqXo3OJvl6SYleTMuHNdNmDytx0SSN6BFr2IBdVK5-SIzM8gA1TmpCX05VzR96tBw0u4wH-0X8xxzm2eTp1mbMxTaRskZPGv9Nf-Wt0g4tsKya339mMMsdOJAV0YxBBK2hiWNUcX-80AEgHisziG_EuezxVCWQ0fUGWuUMzt65aQCaLfQ1h7mEu949phip1o-qy9yXYC0NUG3Sk0ZdIDFrIOMo2yHNifxDEjAGkHNZxXsTsAdARSnzadINa5ZnVTfdBTR7O23l6lOwM_05DGkm22fdbTL6ktMCUUhzG7OznpXJ2ukuFnXmhI8qUp8cRadjPT7d3ZRXr3GVApZDrTH-rUFVGq2WnRqG9aOEX-Z4DenFayacHGq9pT_0Y6SFEQ7xTudx9E0MDzPy3sLe0llpxU0vQb2fcexHbZgLU3P_Mj7M6SZADgMwPKHOVlap4akB_0JoaP0Y_jQiWoLa4bTJy1HF5L7oj0QLPFF_j4lL64xB02SmLQ7KKmZxQsf56l3fVP4l6sZT73G9WH97rfP8xxeWSbxpdSf5ZGFy-WWoX6NY3EkY5wo2VUymDf4efbV3qFwyA6J_o2KJ2u0egX9CkdB4OJ0cvafgvFr9AKthVp15d9VRrwIYtLFY_1gr_AGegk1_bkN7REPUJvQuZql98ELctN6PMb7gRd6H6Kxz5J73OAVKZFDn0oR7YoDMJ1Qg2nQM_4WJ6R4P0jh2nTKqZ_GKMEj6Lf3WRDbIlCxN-h92MTr-YfE37oRngo38_0wXbj-9fCLODDYeTdFyu5CBtpinf4_IXrOuQKeJ0w7T5VOL2XU4caO_BC1H1XwI3nEP8FCRWHPZp4ZfJzL3lQMiwpCmql7UpG8vHMpw5mC2r-kY6nYsxeSKLz7yS-sg5sX-VQEzKijukLWZuZbb0Es1jFLWoc1m0LtoMs-Nl1aAhjcEiwmDhPC57zSC74V5DB0iBBqr7NgvyHGA90QMQi9wR2zUrxbcQmB-jWSL-pSGVlTRoOGSu9e3YNtMzQBqt24XOMYGTW43Rvv2MgP1qoKukZ56YgKi6tkMF9Lt5JFvGak5j1Ccq9zWAY5BU6n2XzHRz5HIsEFXm4wqQm6j1LGkF_He9HuNrsteC2moy2n7ET4TDIZ89CIU5lY0EKqew7CcjjUagNl5BPEiTRDCZg2PlroOvmAvVxf9wgplKcYemuieHlYV0dG-mL_BsNMyBAyVZ0wqj9A7WCkRqL8LtABZEBgf5NcAdYZ-OPg6tiGLsC7ttJPa7B-KSc0RhJ41RcOgfv56Tm7W4W6jLE0Zy7zd9Ax-9s3mcxUalkSxQQuNmTJbSMbm4EQrNhvwsIZ1HiyqBjIGTvDBFtcOSCumCbTM292BIlysVNNDPv-s51Y4Rt7QWRNm1P3CPmbkfmk1-1yfCqdtLPZ5BNANd10CXBkqXO5M018g4H0YEUJIwWcdKUmiZpHjAmBW5V3mtWMt-V1jkRqHQU7HutvzVy37qmGGWYMApMqWBbj904d5wOqHBmUeDtyBmg-dD7NGhh6_OMu4AeWvP3LrF_ch_jYq6mfR7xTdmXaSYpJtyAp37GbT-kWV3ZTXhcAv88ZjWVd_EqzG_1q3jxZ1lncbYXEEws2SE8P92tVkdlHw-CtnLw84LjbEBhOMho34vNP759n-eamzfO2WLlRaHJ2sGsAnvuiiDRDh875rlkyXhyJbhf5z_7tE0hlZ63vDebm6JURZH-eK_uRLO8PoYz6JR7cQnIHulQSpTFWJgZxPKGBDyi-7AS3Zc0f-PiSS8B9krGhjGa3j3J5YPQtOEtxF7DtYFzdcCuPX-247a29I4MddhAdOLqnAWhvggz_DJXQNYyePhuWC5EI1zT_339GZnoGTBNPjGA-xZPYJ7x0QUxty8phdd5Ky4z6u8l3ipZjSn6CuBcS0EA6h-5D81ktsku4XnHv6juUXCR51PVV-3fXsUXpSDDrPjvn3x1n5_o8wbtMBzeMVlgkEYf9Louu47vudMbfmXbmo-yyvJaEgszwtmfBxKNFp9tMeRZo3Hwv6rg5EM3hj9aPGd5um0HwxxBYRx14my8SrjVRyNf5TSbrsxCQk1_BtUWxVXh8rhgDSBbhCqSmOGMG5gZ0mzSmvF6Iq2X_sLYogQ5VWVEeEivD__8vU3nJRnjxGq5h5Vi3oqovs2V_11Jnw0wMFGSF-JO1Atv2TmX9moyQGZKU6JdGIDHfQjXIQ4_ycbF-70b6x57uKs2fsjQbi3Y8E9e7WEuWj5BxuWv_hm15OCjB06uDcx4MT6QoSr0Qxv9ecWokQxcU2AJHG_o3cP-7aE5-tiauqaHed0WMDP9uAcXpsL79RRbTkMqdoX0MfRbUNv9OZ7-WcTaAL6MgtG-9YEJRi2hqR4ExxSHspvAxYIJ6WfGHCzny-5IcJS45hDjDJGErrtBrq9zmxN7zx_1XGTVeUMmT24z1rEG7rmas_syzDfTpH1l5JcENH_S7W9FjMFhSopj76BhTbkMLWegOUkXp6iINIrLtVCtsVHGNVz6R88-J655AfOqX_7JVOvMPitPBPTqZsUAslROvVycy9e85hp7O3CWlAn6xXzOMv9gMCYeDi5bT62Ev4i_3XDX0dthLIavJl-G0s-CYkluJVtbUFGhIXand7j5V9cDbnijPMajFG5DhvcAqr19ri2WDq0dlOdAjAuaom__8GsqaS7DWatTAEZ_GocUP2ZLTdk4sOLw8FguxhSYWWKcHkXRyYNFGXs23NR-8Erygaf6b7nzEZmzZlxlXdY8AixZ_SahQBRHjiKdasU5SUq5dslZ1My19AzDlUnPXjQwCH3qDccVC-_csRKIOPO88ePiawdcj-c0yaz7UtA-4iNHoH9TmLZahN5ZVCdBglR5T4nNj1u2BRH4WnT-lIdMBU5AnxExuXQnn2LvPTm3rMdMOsp8Gs3LeOHkIi6oS2L3UihhG4Tf4aXhXy3EDCPLn-nQoaugVor3mZ2iPDX89Hi8sCE_cUj3-V22ISFLr6acdGPcXI_M1z7PVxVKIviFYwa1_EMGxP8VGVMXgi-U4nMjyYEJV7npLAc5nseQc-pdPo4sRWDS-075K-zJvwaoVZ9HE_RYBRu6jSWuMxk7qDHHXaCj027dk42m3gF8-BQo_SzU7SXzUe4KviYonb5PspvEa70c5QkeT1lfeYRC-FY1BwKDRtleeZwip6zvISJ4g012LzE-eC7Vb16gwZyu-309XQ4h4vwJ3Rn-ve7sVM9na-jQf1n5i6A32ovVDf4NPbqmHLaEwnvc0pTGyuR598zeEfVy3SSDRllZEeGNgMz8qZiptZUHp_mx-LlJ5mqSdWhYO_s0xiIHmwnKvFeQe4_ERfxOK3uaaZxBcyNyVqNa41vFKcDVlmIes0p1uoWUl42TocyamT69rc4PjtSXnr60xDnJPiqzF6Bi8VSUhjYq7TywnGXPs-emLQo_tG-GI3hjl6aEkpDi2llM56-cgWbCkCPrwsgBpbcOO2uhFnxNpke-8Y1RVTwCi5z8ii9QZAzI_ESSjtiO5wfsA90J8onevNgjBGaothx0CKyBY8iwKRPq4PyAEjB5_oCZVExpolko41VduNghcMKr_pun56Amrtwh3qIOcjLC3uhnNkCEXMvpBAPWyLwh2FCpJxDxe7_SWUEFEqlpHfyw7SANspeywxoP40-AX0E3_PX0juAWAiiN2KasCBiWaypG3Xs4pS1VxVm0eIlp2txwXWXCi3I43-MDq4SOjOFoHWLLwxnihYr7QrmooZD30yx9laLcACinVem-JmLY3EMZMtSFs59QmiGJNO58i7P1PBHT2P26N0QPxaiG8hWQg-rPH8BUyw0YfAC97_E9s8XeY9ijWXzgb9g61T8Hr-_3RZzjJ2SCTrcFm3vTmMOyw7fpoQrKzW8m9UzE4Ss-tCf1rarrlhrn_3T3TEZ4VklYMHztHUeQDNiKHh0DjayC--MKynkaHMVQMMJuA0Qip5sCe1MCo8YoXZVPBA3_7D579s7I77dEPVG5uxHGohrIRqTURT00JZKdiK7QbqzH4F_PgbTqANFXKZl4fcAkArjHtVtEscdZVIqj0Xcwz5JhsH-wffPgr6br393_fvjoQUgESyGxCkFpDqaAKuUYFyEJNO4cLRUIyAkw2sJLkDItgI_yEf7sphVG510_n8jHoYp9p4mfSkZcLLq6SzGIthMP9sSLbPH82vO0q9k7LY9yFdZdujZEqBTWie6XJJr0-m_i3IgDa56sQokFwKviDrl6uCpyYf2ItE-hTXqvtm3kCUbXmZHs6HgmXIwx_HA80idhM7bfzLry7e34PefCnAR7tziqtzcB1MxH6KLo9GXzbkrDK9NC73w2CLtsyOO2b_bmT311o7cnyEVDYfJAjBQw_m2Ok68nomRtZC0yCBF2R7vu6Ju1VI9_2GK_EEZuOPpld-niqhrkOteBr29SzKEcF6cvoCEHB7MkvFqqrEf7vHHHZeKsuv9eDZbMqKRNNwPwUaPebXvu5us1sy-pgxtaLtU8jAeswvrvjGTTM1Idp-dlGAcUwM-As5gurASmPG9Egn9psxqLuKi1-y-61laTYh3wnmg6k_XETk_Tu2sIfvIok2o4Od4vh-I3XZHGqChM9Ra6_syBRJVFjDCXIW9WqQvv37-KKSq6lcy1r-z-bbTppcwBiUj0wixH9Qsusvug6hPIyRT25owvtbaDPNPxnUJ5mPfiFeIqSRPkc9HIFckZN-WQSCXH_XB-3Z7pyxG-bIMBum8S6XQEpxTv1MAvvaGcanSb_-ASfPO1NGTJ1JVx8V2ihE3IUFf686RoE0YJPsnzVm62r1kFT2Ox-iT30VF7s-qFYNJHK2V2ymb8UPyZN3JlBZhoD4lnBKyKm1BFnyPJKWOWpKyer0tqYHzVC_VMmaVuLlPgLt-8iJJGHAaCu_d17Ciq_Pa2k6L1RW_KjFEV_Ov1cLsAtphk7YC-5CWB3q8-ztPmxJ2o8o9tG6uUMqV1kcg0Q36WEm5KXrydUj2KMTFlItlz4fI4mect3disR7n6vnOduEwGnljK1Fu-PBG1ENqqyjBXB5Qqx18qWYZsnROnyQGvFi57jaJo3RQ6SyEfmZYquBtvdC156EEar3BOLHc2RgGXSHxYQHn8Y0-wqBwGlkuAvs52b5xq2Rn_wzvjhCX9g7KF412o9eV8smQcXx2Spi0lEf33_qr5i5kzJCleyWb6z0mrknQSppLgKyQ4esRbA8trp9bCfsWtQMbx7J3FM7NLR_3sthYRzZjuCMnH5X18nCjlIf3HJNa_cR0eVVilthkjFJbvfni6DN85FeqG7cKLUNtZS1EVnBbiDY_-N3nv5yE4eAu5tK2BebjgB2nd0N1y6d6_J2ZecqkGw7DfwD7PG4aAn32wpDVx6wCRkTEGgwWXmxB-1s5KPqCvleGwT1D-frd1C-blUMesqE1BYwgDpBMpGSJj3RXLKWA9S3DnRz9-72BE_6ViyYz3IUqQGNLz5PaSYbl5KeEVePs05omy0fuQkbsHNEM6UGG8V8C_QXoOf1Ld27mrgVGvDrzpyck46lVAec9lUCr2LFuQjDW2DPWbllO0SqyxrHfoKvIktnxhd0Zfic2TLcEq1vsmDAc-h9On4kHq-KvcrumW4-1OZ_iSSbdnrSKpUI_jqVgS6cLheOh9ZZk1IWgAYYyz7CCSbWiYOTFu0nrfT27HHd5jYpVq5kCYKzhsc881n30vNRqop8BrZCBNFPE6ssqIGPVBVuShnKuA5QSBW466fU706iGENbtgvCesSY0x7XBLb1cddCQ-4OBuugtA1szssfZbmVKv7iPK06rkmcNWZfkL8eVYVXMNCOpsE2DlOltWb6ELZND6ktUD_B5a8Uut2y8032ZgjjbeTxyfeiywnltfn60jGJ9X-UCxCK3RhkoXIaYLisrB2wlnWMRALbF3AEsjt9PNP-yjrSc2Znt2rWpjX8kVIp5jXiDzeaYJzB7V5h5xgzPclUg_sxWteajmqnHjaiyubjg60mTduUrbnymCpfB06PwNTX5LIT77-ZcqCOYvx-I84DmFFj1Li56JrjMx0rgDv0nNdwsuv3Wnr9CP42IVYRUrfvXHAqQtaGFnDNdEUA_suyaj-LPhteDSZIXbK5ACpmHG0DSVsSOknVjMNF-4YU2dMLvmd3ypAy2e9mD3lUTdGTtax9uu8fLqxEbO0DDL4uu7i68ViWtDEC7shF5F3THH77_dfXu9sjiPSlSuiqp8PkyaHN4bw36hRfHpT1UJBcRl9lYNFWDxmsGT9OXES9gLGlHqEMtGCfW5Hb_UmSKNt48gfY4LuhPRT5Nj1D0zLs0UUEhKbcYWJDg2sYxCQjFgMWcz9_YQdEZ9LagO_MqpTgfhcJenJ6MidtFpxJup2ISVv5hj6OaB-hmcrjTjCW_gHqE630nUZhqkl0O8oCyqiUpISyrkQljjeEs8QRDDdmF6_HXoYRm3aZq2Mn3Zz6TPlmWkrW7zPd--_nFqOeDa9FdvCf5UGq2Fl9oHiG3_8afc_NbtC69n6ZozpOpboRwJdkHJDC12hZ8L8xOi-sSeT5R0UF4rxSX8zpeCQHdjhqEI_n31WzXk4UlXGisLOY2_jhnSnF5neF8BP2arhnm6yo2-08ULpy4XqnhMphtApkEQUFnL2bn_HA-_q4Fylv1dCEqcLMc4wAPE7EYyJJGIupntMXOrcSEf4Ch7VgaJlquItOgLPFGRRPjW6SC1fBtggtans4PDdsvk7OtI3rM9Nu_WKF_rnyAIQvNy7xBrkm2V89jfggM3Wen2joqVbEoQT2mteQZ0jn-BMpsyaK0kXcFi3MhJcdyKKfsyv514eMVq33krxMKx9d6RPYM1vTp2NUrti8YEuFst-8FMq9Wj4p7UKlVtygg1j5J6MUryadNkDTqxWz-DqDeD0DsU_B9x1dSPHLHjkHMFW5E8gYaF1THbQmSMSqBA0eIorh0JNyazKWSOFwQwPEaH_26pO-YcYuserS69uGN6ualJMFXHvi3xC9PtP0tGcenDBiT1qoN0i1d4q0z_ixA-dSXbW92PsjjZ1jPYGxwdrs0N2fptLxrU3HT0pACTyQCXbFeBXv9GUttgT53BEycmpcIFtQtJ1XamUHa812zjI6Wv7IoduY8GMqJBns8TlAoOEoW5wXy2p5VzjGwfPX-rKxzKarRpJH9RnlgV2dVT7hv4eRMoIpJjNq8wtwKxqM0MPrVxHwXpqSLkgmJaDswsrlR599far164s2XBLbRlcQyPSQj0hmer2SxQH8YaLp7issxo2r0UKZ-1R5uhY2hQIhzzg5FD8tJ1M46bB5mhW0k_JNMdiZkgD5yGhLOcI70ghu3rbU8gK5qXaL6AHjOX-tFdf31NrnXcyoUuW3DJByjrFRdegO5UqGGGuZTosKaB_1DNUlAaMJBWFxyqhy2E8kH3euAVBncmzRKkiwEiFSOePuceY7jrHWVSwXMINhHJH6EerkCh9iBnKOSp8KpbLoFMzFwv47gkUfJLfAmbaLSd5KVJxdIf6DIRjdxKWIX1tg4FF7et54MhmAxS6oomgDiZHZGxhlkNAK5dAZTWnmpBX62UyC71v45OBy0l18FOLm4Pb83A9YXJE3hDoheGV_ow_RxigLhsgRayfVntfpHWWJjL3igJCaAHR46YPcq4kFKpQ0ctRUyViaeWSxALe7zzTZx7YNFMLOb1hED7zqGmMk4YOYCEJ7ofYFOL0Tk1fXfHxEBbIhOoYD4opZLedx6a44P5LnLRZ4gIL-nav8TKXX_-_LZThJuGZdnhN8O1JjYb4-D9D-NRRRp5OiPUJJEL9vficKheT1DUOfvSsTgHHjdtSm8emmTfwnxD8Gequs_Yo7_CLT-rtowYN_UYdPsngEeyWlzDywX5H13s3-uw3jb9EIB47lNpZWSkGbgX1VeXHMdfeLbwfo4PdFBsEBajURKXvrfTaPfFUKgJZva3nQ3SRuGlD4KwDrgmHa28dVyzUTNrnozVqks8ZOf0GPVkFx3QKC7gkGs6GZWSIMfrO1Uuwb18hqzo5FKoU4OJcbBpUG9seQQqJEl8u9gzXx61STE_M669tcB6IiTFHYZXicliPMZLPbbKWFzub_CefVQds8xW9w4DB9yGe1qbjKWz9VUN4N1V_BXfLJvqlPVPWId3Igcx3yNrnD4_4ZNVSeM7x49hVbeFVT2sJgtgRGGKTIHsuK_SlSHg2n_epIefnbjyrxD8fOPU4hg7A9NzQaw_7BaBz7PVP8LAr2BqYNiBcUC_fbqK7aA9LefTghVb0YXzhO61jjPVrJfyzyCURlJPHs05NM_oILg-Ly3bEV_kSvqva8s-7I2UqK_3vx83iYlIcybpfP9EMCuKrZJSh7imqPDnz1BSC6wNu37QbVw-IxeXbO7tA9fGAQn4UcL0nKpeSQZxobDDDCEQF5P5PS17DhGNassnzK6LGpaMR8p46MexYmnSYH_YMyRphjKo3UqPhBB83RlYptJfNFTyfjUquIe2V6aAIeeEt7HSEk1i8GCCYeteswDtEtRaR8NVOjba8DArYzipr6ICEzIZ_mAOgqEn_cmSRsP3m8eD2huHB-dvLN9FkBDZ71mylvqzW1fu9LsyTCz9vC2t56QjvEelmtpbFT1A-cr9eLkqFzDesYWDDk3UhILC-dlqk70XjiDC6UPuNg9iERSupXTzFHo-MGATu_ZDrOaJQpCl1P5TYq3km9A_ANb-FmTEvk7U4b2tSmt2NnbqwBe2dvctMAx5rPrcaAwgzU9ofqxkfnW9k8tirA2-94kd95ywz1ZQ2fUGjFIkk7pb5C3NhmjvvYOWoTSj1EOKj1Dxifki8y_d7_Bu3nOI_4FTut1l62K_H9-1W_WdWAXoDKgD4bOwCMuvcQabTiJTv2g-PXC4s0mZsfcMMpalo0nMd5vLs9zS9_zfvoReJn7vR0ki0QtYZ4RYQ40oqj5w7WLlntMsu59O3ujBOcMOdo5Wq63HhG6niC_vDXXPrOy-kQmCCYSfoNzINtWUzjXgFLWVmIHDStaDnkQaPfvji5ScRdDnZJA3uIcVs89bMZC6uQPN8Ssyz3KRCeK8UY1z3Gy818wjyLLTWqPa8CZI_H0j7Ces-s_58LrqXeujhvKSnI7OhETaQgq2ihaKq6M2x9riz_y-CloXHA_evscvimD5g1Zy-5S803hYwkrKtnbZ-5iZEVlM98Q2oM-sQLLzOaQBev19cxTvmjFM1Qh81O8cB3urlNARgjarDcETg9L53Oxese_auFRmx7QQnxs-6LCuvIxe1QcYhpkzZyKexjcyTo8aTQBd6v_52FCxhGzl0vzUjIF_xdjwaCO9_4zfBrZROgYNsnj2zirqfbwqssNXUg-vPOQcxBrCiZv9BnHWOQoYKHFnjVSx02T-PlwR1vRF2tXotNowz62B9-5w_E3g4z3WlJrs6yt6FiNuUgfXmBkbA6kkLScgWl87qDu2ZPnVpJEi1Q2sb2eiftxIlO76zERjY5gcExt7ySCM0yAvEkWetjpBlAN2uysZFZi6nnrpY_8gvze1ST0x97wx1hjaK6euYFJap1pBqbpLshDhgkifysS0n3U-vAcfV_LfEn2KAw4bfV3UUj0ex2BKD2nb9bJBUtVbokFh1yyUpQk-IVRVnPBJ1oZuekOZc0koGoIu_OAPUghpBxlCNDAvIriqLLlwgyVavluxznvSvzXTYtK7MFk3_tdbdBDz2OF9NWgJVou0KqUDHXp0IdUnm4RaacO5QUMez1we-aTr4G_FvpkJ9FcXtzONx3mmfMEU1Bv0bATpkZL3NaYZOZCg-Wcv8aIvrVWS4fdgKH7RkvhRB89ByCiGsrbpD-uhtIaMYuiIncMiiKBKFcI6EuwWDxGXcOV_LrUu42hw-g9hxUpX_L4fKXPKiPAeqFlx-Qh3Jt0IodK4FEhftIRXj7QKch3Em_FctwKifYFQATbDCjauhe9ve66ykXcimXqKICoW4L0wtBhK87r6BbL8qt3z5j5S1DaTo_EnvjsXzqPfV2V09F1haUajeQqQFaKeDupnA_snmjnl60nHo7BghKqzh3ybOjr83Q1DpYhxnDAJJpZuNeqJeJ-rT4FIukulpsevwVUhgzWW0lvBUp3wteWqb86Gp8MAplU3Y9E9Pf-FNHtVD0rtXF7MDws8T-Qrv8L7hQe0d1Wg7j1LqgAJVXbWrL7JQdjjHRC81vnt6WlX12UF9U7LpNK-Gr510qHyFd1s-nHfsDgAqprn5nmr5reSbIqAeR-9w50q3pNp6mj6Ei3rj7Zwcih_0Xfe9nSqfoyH-7mVqBI62-medQK9lBrV61QlGJvZgzaDPiRw3DWUdNgVeWw0-pXCeOld6UuZgOQhmQlE42eUEQsUOD2fr9W3WywhkBPS0P5P_8y4mSmjCFb5KNgjJjtJ-I-5J7E0dpvZ1PSpQ2inQ6A_JfTswDX9cx_MVJ5xhjVHOopvCy9--m7agSE6eQobSC-hUA_s-n2cUYf3GtVaQY9zjetLtXzx0-AfBSCxh3QquA5X9jbnfeHx77NWNfRc4nuRTNDbVjlfL71eQXRJ0Ew55banHSqOdwC-zZGrtYpHgXparoO8MWKipTjI-qVg6zs3nZTcAwnb1im5B_URUo_Wa6klgO3rk6td8T9uNwgCtEgm1Ai2Tub07qIW__T6UUGSIjwijrVm-HxlZdYPmvdKspFDUEZdKh59uPiuQsQANVjNq8uf-EyNeVT0Kenq0KamWTd63RwIezOrkBw4IXGZ19FN9wTTS8vdZJVIdyxR7akgXa4HWgAl75wNugBPOTmEGXYgSKYOUXyFgqsfEH2JuX1DZ8goMlmroOwD7DpexUOKDNAdyl71GaQnfJnWUD_nK__grI3HEVeGdIfB0jHSUPBsnxs32J_nzhhj1qk3NKDBqafR7EuenK_RZFCwEf5laD3LJuDdVRpqKYcPqwNqy3aXpsvGDmdJtfYfnBlQ8gjeGfmrGwUSHJMO4DgQtmw3K30qKJ772MYd2ksBLacx42tdhYKkZAlGUD6o_4GyIo2SPLmHQxZJpIFXVczmIEXKKgazavWjJ6gmUK4sXhDZRHv-yB0HQY_gnjQf1agCol2lsPo9puEFBNnW2Twe4qORLnq1faAYmEEAf-8aeHmKt0rZ9qibL6e1e7DdOOnD48dHnDt6pt-vG-rG4kd6wjMOsuqGaeq-m1VRsn9tbtsk2InLGZJGDlRiDfcHiYoaD3-gNppj_Y5t0ibTk8H0uyFu34jCVcpM2TJbBc8CB756mVSh04RDe96v6jYr4U5ajsPIcKgfPUHITdJDX5q1QlOTG4WG4kW9gsGSQWZ9egEBsT5yFhFE0PUJrjh8kJmgtjLdpXqdg0_ngZr7rRQisSzJEOVaronb_ZeJx1Ae2c9O_rbDXr-EuJFVAL0nV8_R6kGH-rGkyUVb6tGxHjXCDq1HRRgQqo8e001H_Ke9EZn2aEX-8u4n9utAo5RgqtU24HUYz480ZWIMUGkAiFzR2pwgxeK5SdqrDQp9zTPpUIzEwTPGSuu7hFjAZAco4cuwTa5lkK6drwJHYGxTYwNloo1FnV6819Eb-N2spwEzIspBhIFB7ACB-QA00PI2G7EulOp7Sz_UZ9TeFaM6x50Ju6ScvNXTbZSlc8efmU7-nQrfjMD7EQUJ97cdYzvWVnsXVQUKoSRB9LFNJXcttO3CLufFJeun2aNIXeZzJD4G5-SAc2ozbvNC4OD0P0dnm3d7mGWlTcCmSI0myZE0BogQPkP3IkQyquNhebZcTGlbimhxh0kHfj02_As-GqRsOaszQMm_zClzbXXW4DRmNavPyVjg2UmMHEFkZMvECzR_Akv58H-3S21Xkd2XsVKwkq_FaWLaBdZWWFr0oi9IzAyKzYiUb8iUDS30vZxGtVQhAircbFogaEM02pqO0twkpjxocU34c9mibyoZdBfi43NJZr1hwJg8XzG8ta0Unq_zOldX4STsX98i57Xf-x5h9oc4VcNETe-8KNf5TxxmT2d8ufM8VgrKpvOMVaOz5QCKCcNKOIJo0qwAD3TXdRyRkT9zvF_DyeJqShdMJgyi2j9M31iBdI_kQ71B8dsBPmSCcaXhLRE0gWQ1HOONIXjf2FkVwALa1TuL_HTrALX_QhxX1ips6SHeyhlIZP_off50tvi-nL555ftDOp9wVdlZ5Dhd4E4TsRPRkXTOVM7dQAVneNklG9jeRptill5n8RGJSgFfE38BxDufzhaPumlddxVb5O0qx-duH29zNZiwLSVlvpzs84Ei_Gg6NXStD-_kmG_xfRRDzjMUtPVqVGU2MATdiNnWsCiEMc2JMjQjZcoZD8uluqW0C5mvQePmXNayPlUU63li6nIwwmvMC97JJ9k8CHbXmAxUtxhMM4-qUGdRAFyy1gMFVQV3envanKnBqMHBGQP3LGe-bab1UAYfEBvli-JgDagoQ8VSJb-tyxTa8_mXBj0kA0H-b7_sfwM1CmKhmCG2Ee_mPgA23rHDEDMv_AlKWFIe-eI5t_j9fQyXuI16ZYjavXs381lebCzETlktOf6PwUXfgq8JuKnD7p8DyxOEBKoJCNTT8joaGEMlOB_RitfjHZ4CHQy2AcnggKAwuH_7UrUYFdG59JZkoO6Qqem0C5l_QiiCD47MMF9v8ZFoOAWjNWlanwShRYFww46JMRT_ZpTuxlRgMDP8--ivO1WcTeq6MLED1TdwQdccTEQQ2nlKlxpphvXaTWBXKBzREwlO8Kl-g1RHNkSt7LySYEQm5kHXH_RkfiyTDPCFtiWwVkda6T1-Ud7zcZCo438Ih2lvoOJNASxmBinK_Cf5rFil0bRh94SuMpeBftuCNW4W5pcbDpjV2XVWG7rxjvb_3Yhsq6DpR2MFUR2ExnEMQWC1iBHlVa2DO61um6LX8Mi5SA0ax1QJethaPS5-oBEBkTAeINVz0QisYJafVH-im-tNnwKzBlvkklSQmhsr0KRqLRc-xSZd9PvCvrbPAVJtifo7Ml85T-fspCkSw_r9cKqPOvFFPCJaUkSoKfWOEqzOvDuYMSU0PX3skzONLM5Su01x-g4fS0j-VnB6NGG-I6ZS9lviaeAH-PoDch0bxVhBSFUFlITBPM_Rt3sg1hLLt8f9kAouP9C3JNwGtHKLEgrQ_Hquhsj3HnqtcQd4bfZkllFqtfh-_UyP6VvW8H5RZy9fDhPMF6KjZUkAPXTVLWVmkpz9DUH0doihSHFo1460dZldFkfIynH1C0Sjiinzrt8b3YturqYGbmT9A0ymPA77j3B_wGaSDTVJome-uOgOCgZL333yah0-308isO6kQh8SGIE5oIIDeUl8r7V5vV5PyCZBT38yAXBSCTxCE_FizAn6EmmKtlciiuLSXDk1zFtfNjx0sKUhmzCdhiGwWnWzrLPCA3lP6vWG0ASMCb7ql-kgVfrXWn5xe4hR0M4DSjpHVHWqZc6mk_TY8eGrohKZOEmuFLFoAmaUIXeAgGD5xwsrxRVQojmDi_WQs7Vf7IpgINVDBkPncB-8rYhQ2WvoArNsXZFGcdNcZVsD7B-LaDPgh9ITxH1zerFxJ2sbaPZj2Z6YHjqjcRWCRhiFIFlobVWL-xErq0YTi6BWMsDedKisO03rcVKWeSpZ7dXiHW-zK4v4mQXXySRQOEjD8_7QFj5hoT8AihEhVekc2zZav2qqHx_DXtOQHNTCTG6u_dtHBy8BjomFtQUVsVpYGxgRwEtErA9u-cc-laTaWBfm9ty2eysj--H01Y897L4GpVherHTKS1rAMHeLkVV7zTHLOH4Du1cOhzlf8HBEhGyE6VJIuxwqRf_Trl9wnMArqv9PcufUzZSPoUK3FlkPD5ch-4HqSY4XxzNWYXsL6S_zhChqBJ0POdnG11__zUbIwPYoxVt8_BWMtRf5wB0a6ovMJM0fwTOs3AUF1_zDaxHb2p3sifUw4PYDeXt9IU84aIsvnzMKzkY3qGPClxEego7m2iZ9ICQ0UcyUdkURa5a3EDJfIOkjUjRGJPXDJIBDneyDxuzltSZL1ZNzUqXKic7LtWA6zr7TJBYmXXlL60kiaESkOKF_MF6TCMI7rQ_YOu6FJJ4laFSyNMSSpd8eeCmLDmg2sCJuxrNq8ysH3rdshn_hKkQE3K8yfFZcrGL7diLRMbFZOPZJnvgaqwbuWYAvitGZDDzOmsNOurekFFYJDYFXwO8PYAPwrLM0JO8YQWJocF4X0MXbaIQ3uUs5yQ03VRoU_2-fcazRdBcplDrj-AQwY4gAn9nsGWzGD_nQ2fnjW6w0GP7lAlol8PkH3qUBglO0Rft5V_MdMD3UBIZJYnjZy4SntiM9ORhKpY1nwQqMKB9UAvEgUdeookvrqd_m_aOjxPH86dEjjuhzN6pYgf4xBCoN26FhuAPda8FEJp_XcQstlbwd3faQthOC9RSAbKRQaLPcYW57gQG6Leo73GD37QCR7hAOmdyIrBVy8ZfFSFIk8JPIZgWy45QKyDyLU9Qp4sOXfxHFlgG_-d-uL3lH7GrlFp2nb525yF0aIDMLE3Gvy7pKIumg5nUeJolteXgnzWoAVBd61b8HNZ4KYGc4djqAnY6iKA2qDNbwI8e1SiaO-FiOjWJ3beqcJUjs-gLNF_bT1sL3f_qg5qbtAyyNkvCQ3O5Fx53htFk30AaKJMyc2Zis6UkhO00rydthJczMgSEsIsri10izFqj-Ey4_CzAAjR0JwbHiioBeAI_e__hKHbWnTs_ewYEJl83mv1MxDIBbRyerRL950ubZ9l0yFnCcBe2nsW3YPyUKgsIoCW3CG8WvHpKL7Y-FMnLMJ4Bu-2cHTsAFbIePIHnzaa1G9ETAFj-Ppp6cCFukchmgIi0sQLyuJM1htVamCjPyIRd0hj93zGk22JUqSwNL_eGefoV0KmRvoY449jP2Dew7lOStUiCOZ-sh5G_KxIYyQ3JbeKwB3TA7vYQs8YIf0kYECOGhIU6ymyCxKOQQzjg5kwcG4rxl7kxpuGGT1avsp7bWVoUat35baHDjGdi1N1_ZB260gqJXuDTPM1HfSub8lAp2wRXjhyAZY1bfCXUPVUfPkQo0x1YH38rEbKnLAynei6dZ_tJwsWsFosSiwWV_5Cj680lJMlSI46YnOzyGESDwQJV0o0lJ3e6Q5TOEn1Z02Gt9wioNqQuJrZk9M0CBPIeQ4VpayZ6RsSgaz8wVpTXiybjhRXGQSWO55zXiSutIqlhcYy2EdWUu_g1p6KO8xZFKoi1Qbh9QiQLN2GfGWtYdGhltxBUR75NEpV7godBKcmXpV8IySdUj95--WS3MBDQICnWCwwrpNfwhGlAWBVrYBU8zRhCoeKooFMJLQ7w45CPAnlYJPWReq7RlWGuw4KYzaM21e20RyjGAjwFSp9T0EZl7Wv9Eis0l_KiVZtAuSfXSRZncm1-Sucto0eAKuivFM56a6MBoKX9lGF0sIK_U8j8m7W3G7XmnNnTZAWDECh-PJbAbC8PNRtyyD6-FBOEX-A4dmbQorFecZUaUeD0MKR8-voUzSNkBkhNIwjX_ZZPegnTtSP1rRydYkl5tSVJ4NH7QfiOIC8qAEsXj-5odIIOvED-a1outU9vz8rN0Shu1bNl9gO2dFPjRGuDnPp7wVEoI5m5jAg3fqgCEKSLW8AESEjdcnasFZMG8wQB-MP6dZUIi22SZD-uAIhivOyFRb1HTSLa-r06kWbari2hTdWMubtsNisUw3zXS55_ccLp-Ya75zTozQFKi3UBnqo5m6JLO3ur0asaqhHgMa5gTmSwCgzyLHjlpGuUVoq4Q28ennVLf9s7_3aINEDJau4PVnniiE3NFLD9zxpwWSqanKkEswC5LD1oFcEFUgmuyrLi4IP38Y_NQab3dQuNEaFGrYNmBGbfxFJo5ETlibtC3dJ3YUIXVApTvMHZMPrAY4wC3l6r8EAoZBgToVRxmaa8nljiR3IOiLeSpHT_GaSmVlSBSslw5ggDbPzaHKJ-kCR-ZNE7bltqlBhJyDzu2FzggGbqkPKNI_2w6iYdW_CiG4YlF78rtyH-GQtvTlFWSGKKeiW-QMBUTvWSe2Ae1S-H1xYczxUwgBhZ_KY1aZqtfAUeLMTWWIltKaXxdfZVNzk_wBiOYIlSBmvge8ZCFELJh_gXwPFwcsFW2ggaRoLDrEUUUCYeZ1vn6eE4VWKjuaLFRxYJCl0EAChIa0saBVE1DfttQtipDjZBbblPCPnLPMQDdYc2A-axI6VXeJ8Yk96nj2GJiEFhBX2_oCrxEeUaYC1obiIhPDavILIKdaDlkq8h5N_1KLbrWR9ZyckjIe3ekNsz5nk-R-M_hAYB_5o5CEaLG9TfZtzNY983C9u6XAtOH-mSKAKPAJTLkksFrvndkyKsn7R-TBSYc2KT8uWHuFyMc9PTo01ZUijnLADo8Ns85Kgqt4k3XrciuyTqLy5zAkQ_b0JOe6Obxh31ny6UJX8NUUfqP3SSLZuceeFHcccMo9eAyPVYmNE9_kV3GE7sRFFq6zjldeyEwBZ3BUiddI4k8Al2wg2Z9iAdfHx9PeBzrNAGMthki7HkJdx2mzCDYl7wHzVZROLwge6gBSxMKuUsvyHbeCSox3v2fJ_Ph5RvSEFq0Mg8a8XYxOlNEZgRIVdonKptYxr_Pn8McfrRMqvZNsN4UQXfV_PwpFPqkgSi-8l10uRCPUU_h2sWer9AuKb71ZDZgtfg0-ZL4JSU35OCpI5gSvqRBTmszEAVRkB6c0zTN1_GrkdoQUDz1oMNofpEWjExJ2cjucp7-sr5ke3O-ckFBQySBUQXs05NcdI8G6rsWQBr_MTaVb2D7oZwCzYlcvHT7ORh0eaSTguK-hZMEUZY2rHtgq1_jDt6ExtSeN1M1AyYQcitUgXDi2WVZgTCzywTVs00kpq39M6QiQSXdVoI2gaSFb765MCcS-x9Uz_A8n-P09KsImojY99ZCirwyEe9mpB9IkldVnTnfI6ueZZRz-jmN33DQNgRJX-4LHero3RT9ZtPKO-DXev1QPE28evNWm4ocv53eb1wqSwUBYU81uhHjLGA6Vn9v7tmDzHuzVBUb5mkQ3BSxvhcc-6vuEdU-9NDh2_zuYfc--IfLb_96j97kfWSTGfH3MxXK69V2T__j5jhznldzRpx2M0rTDUYDEeE6MAapnQ3JaqderR08gDzsOuuWD-hyeip2Jb8-Ai4t_V_V1oRBB-qzJRBvHnDP5LrcfcBjxXkxSr7GH7UDKhHJjo1q94V6Bb2W6_7ThR22f4C0ro3benqK8vWr_eVrZKmbUzTK6l9H80sMAD1-AFTDsII8NUf3wXEpFcUUQy7RedLA4GMdv3VdYwQP-guV1XugRHt3jEuo0-pMCWWx0U0CBQHHpXNPm0UVLvxDzRcj0mVs-5CIUfxZHj5b1QkHqy7Rq5hjTacCJU0v65fEgibwlf2BGXAZ4txF44kTpboIvQ29Myyr33VBrII4Oqx8IoXJW-lGFiiBG5EruuxpKNkHCaQLbu_-dqvhED7lvqXd6uC8__o410YVagnVUL_XZ3XZWrZaibratqCrsDi_5T9tMXi1H8PO6pLR4CJR1rcKAdzPnuJZP0roJLrw8LSgKcCzE0zr6YVLzaPf94q8pqYAHM3Ehp1YqjMIPQQ1siYKe6n1C5mqAPfjpmQ2YKW0Hqqi5l05SPn8vVWDjf0OBoihVSxneoZsXXj75qrDI2gFk01z9m6wG6I4-hI-k6ZpikPw4ay-lbs3-8tgZoinDaqLaRp4TN-wdoWpSV2dcy5cOVtG5B-Ngv_ruY0G2KDgpCUydYbFoHpCUY90QfegQ-7AviSqAzx3KYb1EdDDI5f9OdOaZBbTiPt2G4ucZnUIvsQQ3KRmZBwA2jlgbs9NGxeFaxZ_-DizJIJgmIEeGRcTV-rFx5eSvwabiBcbCFZKsMpvoiQVdo_AKN6lKHqVfGxB7oSrUXVhGZH30dzdRJU0IcXEYHpZdbn4PHyIzJXjQSArzlD107Dye1c0LitjGoSxwo3mdeQ9QMQYbkTo52uQJ9b6UTYgWBFC6ffqfDUQtB91v40eCYvbUeHTrhb-EWGlNPIVyiJKbAQgWjcgMZnTOjau1w6eH1zmvDvMZmklv33SUyKmiYWEK2BrjvMiB-IhMnLYp7D65dtNZFqcL7Ga43Ir73uDtkOBplYBQZeHM8m67nhfCREvNfts0vD5v-9xheHhi10-11POmc3OU-DMje-FS9QcIRsQgBts0bBXRFmngLCoh6_w4AHhdet-IrpftU2Q9NdbcBDfFkodGRN4a9wgwe_5pIEVuAyAl2C_b1Hr02xhwb_VZ1-sz3DMnaNyP7Vy0e5Ne11jSGsfya2M6DQhC4Jdsne5qBA9EzOtGIeqd_VKSnUnHnn14gZ6BTWuCHyfcB4FOAR2wblFF63ZQJ1mkEPPkfpdnASAnthBCHloPz7le3i8ht2G_w7NDuB5NNap1n5mpnH_tHSrEaN9B38nHWnxsjbOLhjUpND96l3WJwmfiA9ake8rF4aK-dImD7tTXTSakZt4NB83fJsAFiWPJhFez63o_CBicLAbebbBXqAaoWJw58e1s5ptaC4US4lOxCByhbXpk-FkUy6wj8Lu80ey1TEUOSp-TprsUSUa0XnF-lkmjjc0T8vtmhWj7uW2RLEOl22weQ4MlMIx60fd70fo9gnRfAYCDAQ9Uixzx-Fwr9UTr523RaxpvPZvrAJ3JCnRyXoFVLtdw76CbSIPwm_i7LptBGAoQLMg6i3S06hwkQnoKFIR0Ox0CG1P0Z5MDtrCn6VNXqtQdtvK0OCUC1_DYY2_wPDFfKMxCrCkdJ8vKmDySaZ2zkydH6rJEGiyy4LGfxAOs9v7wY4K9oTfwH3rNBpcvRYFaoucQVu5hT8MQloX6Bk1V1E35zx53wLGS5UpdUXFiSZCqmsOEJfB618eD9ssxHMkPmtFBJXTQ89vYiAHQhv4E64ng66yAqi8jTzs_sVnWZAHJ_vo0FeOPQluzPcA7Cqs6VVqZB76EKYUNmCryfA7_ONdEbvJRmM4BZbCAGAlR5yjiy2B1PLb6XcuUliWehRK4zXB_UQHTpWlvD-eTiR0XWb8ItVsuuFFkLIKlplsrqbMGB2FcW2FsQHdEcypqXtF5h8ecd5nfhl1YmKq0zxv7eHnIT4YIKXdlR4EkrOrQrQkN9dM5zOmPGUh6x8tDnxREJfLLf_OOhLz_2-pg-3-BMzbe496Khj-VNIGT6qzoUoE1VZFHMvlWC2kNp7QA0eYpbW848X3-S2YNP7RZWXLCSzcsawv0tHU1uNlsxBcLsjDL-YLDDE9t5YXbwAKI26F3Qjo3CBcXexPU0GVTcPs6tVLAVgdgyfBGxl70ObZNtIfIkveN-qy6a73CDnuEtHxiYSCX9VNALuoEVby3UV0bN1P_foupHyYZ2jlxlK8OpEE3YLnGnU_f7aAPDra5RXyM3CUth0vIQefWAoRdXAUCHXPi6zTWgY2esRpSfUsbJjA4_tnxERnqyXyzGKg1SHtTCOb3j980Z0XxPDCPWytnR5c98JkWNAEEg62iZDDPDodBqIYq4SDWs9Nmnj37nlLL2HEjLWY4ZPU82BY3yo1QKim17guAjZa0T5XfNh6v4f2VLRJdVwDUBXci_KoRbSD1L4ITbDFN1SG3Y5twQ-1jd0WQbsBJgPqGI9Bh-fT9ZgyDx0VzIC6XMawHuHxhzhlMgWYBQpdtXfbFYIQbg7j0ZXSMiGdrpyweH9hXD58gu__TuUczJARZlnUQDOmV_BZEVP10qJfym3bEfjJJeCGK7DP97z1S2epHc8e1K0hEOfolm-jMLsFoFYan4ynZtdgXAm5Iwdr-MStjC3PfPDlFjvsyQHaNuoq3fxy-aidGxX3M6bK0sHTFa4o57LYfPc8Ui7DiYaM-iCQ5a8xe72OESA6UtCl35A-QTRBBGFugNaqkyUqo9Dj1KXnhBTS3FKbFVfPQzcSBdstuAAlCTIYeMSuunH802cetWurYYGjuDTu2FXkboKZv384SNSJc-dF2KYQD6X0J7zkk_qAX1uB6O7wd3J6A1Ld6cwqM9miDr8XJCOGOERwQ1HyM0GL36iNUx-oPg7G2O_-UFp1Nszv1rKm8_9R9U1Sn9l_4BMTx743CpTIK-LIR7vPmvKKvqZUvuHmgZNIF-CcxAb308rFXF5I5swbSuSLxGgVQ17dftHa0uVHxjxbdEwikNQOb1tNJklzF3oXs9WN9XB4Ay-cgH1WRP9VCF9p8z4vuL3M254F8tCADh6sBvf-z-iHTjESVFiYcMAGwUIIpJI3065-0wCQhSrCv8vtJahAJFhAKrthZbSxlPT8PX9ksxCo_BSEyJWmZC0Dxj4iRTJAxSVq-QQ09UObXXf1WpujuRGt_zMVEZJk_viMnGozbt12hhYS6a9P3B5m39fX4IWDbBpd4E6wG_e8d_nfPZhY1_nEeEcG7s2f30j5psyvJ91VR6uCzLyo098dhktLG0p-bS2Zs1R0rIx5Wu3vNJmeK7NR9FsNO0vaxfNVlAWsLwQLb7j1TRBSn17HWu7Z-hxPYxz1NeEA7kGI6k7zQ4x_om8ypDlnW_SK1kg1kB8vf17QB7hR1_wkwjOwcEjANlsKK62tiQUxyX0kPwobd3c9C1htN3dXYbLGJgH3dOHm34JACYqkaKJfQgdH89g4vEpVPTsGjvPuF7xrK3EbSCDUBNP4r0IfAhHh3IqF2w62S2ehsysZsUuYDyRLDWSEn00K8Sk2uaHtvrEVKjBmW3AJpy6RX9feqhz86qJES11vYueCpQzT8nM5jSTCOpa2zRU6Jtl0ILD16gu3u2Xh8SeeKvjuz6grzIj5L773VH9ptuB7Jbr3cijDNCgLnQY8N6RWIQD6d50ZplqvpJYPDoIbIMXGf4PvePFY9Ri4EAozqoJrXdHxyxh5I7ayKEFDCHpka1UaT5raQmJZUC0CZ5iPkvnFlBIcvRBjzgWuw_JLX6aI7VITQHCDTJrEcZhV9Q-2wEqxbs6orNpXIlZZjLN8kjsNw3zcCw7xd4wWALEXRswipdINJG0hTUK9oAzx_GDVraloQ461JOHaDDyrT_CS2j_xbBsw9igkEHdWA1heZ0FIfMgrOTTFig9aVpatIuyZyOMA1aoi-kSTKRMmqYbLqh4vAg64Pgekkr-hr8NGer17npaZPpmHx7uZtMn6Vv-94uJROSr-aMZ_n9ppkAWa-YFsSxI68haCzoNP-z4tYE6lPv3Wzwnuhk4lJ19kVeYhQkGkLCLs9inRMfOX6iu0fUCie2FL6T1wM04AdWbsCof8--WTev813C4Q82fs8p-Wegrg44cwX4k8FIXEIyskMRLQvWQF0OXvnpzQPaxkJypKOYjKD8LDB5-UEVTShvLqBvkE5uyojor1FiB3tA7Ly1fQ3NuuRgcQjxxn4U2TtfKm750EjLfzCapNqoo28_Ipqm4rBBo4P6xRbgj1Aa1k86RqLNs0dS4l0wYH1H9T2Xftemf9gDJOF6cSgmpY0fWwBRNNB-TIJse8xPw-Jrl-UJbc_XW4Ovl4W2TCl65PkulsRnMUf67tWr3B4JWcCrrQp_vgTUjEinXRSbkr46n0xCllAlFD7jvBlSaS3wGoiRnho2O_rhb8zSIrf20fnLqGwmcxwChIaA65suqDy3Z5rznfXP61hFxfUFq3wzK8u_VVDJy1uRBxjmhRbf1u7PQSJHCuGUE0d4sYgXPz8B2Jm32888TAEqT6VNforglI8n3KcKaFZmOH5agZ-6yqO9ngGtkFoHZDiZ8_BOJ69_D0TtnhwDbfU2AVV7nHvX5oW9DITCTBZQ3HJfx221XdLPDX1F8wmq9uUNYMfa4_fAJ6Fisj0WFRo49Zy1mh9uS_u6jMOXEqwEsOTnnbWq1tTHqbzH2Y6VenurhBUATZsxBLOVt2BRzi_8Vo9k7_WyUGSdjwt7eqRYEinWPrnHTbd9jl9L1SKKoQjweTZPfgNzmgj8PmaRbYxODLTZ83yInySTqirswYfcas5XIl1iZU98fFEEMhcrNtvPUHlQr5j_sP_xctj6J2i1fVvfv4ZZxH4-r3vvk4ShN_zYPkIySDOpNWwSTO-yWCsFSdb6ib1n2uW9PGAUWAW71mT0SFHg_W-FomXARrvIz27uM2V2bgtBvKOnDGWqwobZDQ20rD1TVQhWErlijEWW1I7wZAqwa8NlGNtJVyAWejN4soyOMcVGZdrtcYa-9qYoQpRrevdiy7YG2RFLVsJvSvUYjQL5aPojFowFDw86nez651ev_vLaig81g0Zsz3pzc9GCs-i6fs2yfB6QFVBafnzDbtMWAWZUOfl8hc97_uU5G8qQMnQfZrhA8mVuLr7iwmjOYE94iwBU_U00_sQ7suvxRlC1rhg5AEKxPsAm_8QWSdWDdvMzuUJYsZtgAYc2LjEs6rHiEVO1TD1ZSAgT60KQAV9MnFvZ9fvD3JzZrY4cFR_7iNdZO6gZswpGJFzkPjVMQubcPIRjabBQP0lngrviOZUlMfF5UL6KtU2tUT6v7SRcVy_DePEAQbWrWGeEetCjDX2lsPpYOEEwoSO8MKb1u9szE-rP-r-miLpnVd4EPZdFgN0Q_ChYMaYYPfa_zeMKMT7Na-qU1pWNCF8-cu3ZvkDni2JGFeJ25c4-AochvWCWwU38OHsJwxUyc6hCtX_hf5h4uj5pFXBTS1qp1PK0OUOzB3yz7cebev8PQYlvtbU8klbA660dIuM_gPnM4q_QRIu37PKsHn9vZ737KRbcg4eqTt_25v93unq-1hPEXqjHUb0KesQ7j6qlq38xCrTY9qb-i8pzXNRpdDKsd99iqKV5YAaH6nj2ESmTdMB5rgeSk2I_uGCNmEeqrnICzc8b5WPcgUmtldfvgYBmZhKZTaOUP3qQfjSV4Yf5GuE16LYfIb0tu52xuQQsQEWjf1wTQ3XW46SSBR3-Cjkd8aqhyaqPGH8W-8OWsN-PRY0G2l4CcSpOTLgWF5E7mChANQ6G7FVvF8rs1ozretod_I5c5gqtJjTQ4KGgug4f5zT7KzjEkZnUkicZJ-xTkabzBDEFETBWWprDVZfx0DRcVyavLODLv-l_9xCY0iyt7pkJwh9O9OrRKeEYUNXfMF8_q7rwIj10ELf-IwjJQD41Or8OF-NXUAqrVE1ck-5OyVMm6w2BR1yoEG7ThnTdId1HzWtDlTs44AYKGlPUyIoZpYAfR5kpfjBUlc6xSpFi5f-2Em-hvO8MpL1iQKqTR80wVRr9NbcqhCY5xmHICKsriAL6P7EcDCyeSXsp0b7pmwMYV4wp4-7E_HenlGa86oPK6ROm1nHNCJuuSuDe-2H_eU2EJoJDhytl4jmkvkbrsaaatKjxFja4iL8faqzdkM5WzHYV511vpFaLtPqJKVDy37ivz3QKPQPNPwZtSNIFnzCn5JvmSZmOs-fbeecGbGxFT-jHHtIgOsZyYxWvXBEYhULB_UwaJLmV-W5FJY1_K6OSn0YKnLXx4QHiqzGQOE0uKofYuZUPptZDjNEwC704tZElEUQdFtQMxcOQorDhAc5ggJsMTDb_IHsQ99s7V9p3l8EXxneqFihZpi2ZhjJk19Fi-WGdezrw4Mawwxd8vG15FvuVSlUWIj_tgPyTNjvMlNVH1Zt3OMNDGJVyE13cQXDYlCiunOwhI5QkIGvfHdsSB9b6mIDQP5yR_lgWxCLZ4PKX0nyxAEmZDB1wkawHshqwMcW3iMJTjD3HnrcqOZYHw14Z7YgUnSeVWfWRhTOPf0LXD4WmHAMQ1xT90JJSIfbjobg0kkVwdrVGATwBnK5dmoN6_07xeK_5Ki-W922cicx_vpcLvTCCu7aF3nrWh82XqEL3dAF4hm20Au-18C844pdW6uoyrHldz2PpCbjI-KtqHD_m35IKTRyGXQWlFsGZ9j9JLWiqfRNNm5P5SqT6RFzg2VtPEldhfDme9Jqbsl588OGPl8ysPTOkIR3Xmk43O-o2YRB9m_hU4ZkLCreet-ss0lkvUYRlwQJuRXtWpv9_oL9e-ABGdmnzrBzpupmv-R0_HTaHWPF812r1DGNFJtb7gSBUSXE2RFuLyBpmn4t_R6ftqB59n0InAcoziAjY44xcqsQ0rSZ9o53JIU5BxHX1R2n1sOLOO-_W9M3gd_EXbtlL_EMqomMBg06RJMIJVrbFJXTwVfzcxcYmvB214m2WQTI2w6B0TnXt2iVt4ZsMAZQbXP3Hx9-d17SSua_FJnWDCkj7fx8REx5OktnGUJ0j4-18rVaAUn_dbs0XPu26AwshmLObBtQ7vZMcjq_jS5_4K0iTkHiag0o9ERxGxliyLtP6T2cuX3EvCn7VO9nYTLyUMEHI1jHihmOZUhp5owwpZaGwwBMhtyKk6FK7XKWj5sNK6BsMxBInwvgwjVyMXo83M_2zM1anNVQvxF7ypghoAG4NmviBezOzn1ihjHk= \ No newline at end of file +gAAAAABpdpE6B28XvzBIFrAjdP5foYWCGvyZY2f1wF0l0qCxX3TuivQqz68RHAuppq7v-icu2p7YdsooHimIFGxhmAexq86HzoY5sZrWm5VVRbP72MHguJb0-nUBr82Ccjf5FYROfr1OEN2lPpbhQQC__H0opQPlpwSwqR94h9AIvSvfLEsscKozY5tOLQsOnEcthZK3rOrYMvGGP_EG5JW19NE-g5k4cx62p1IQwSBHPAmRejIcVP5H82iybb8CD2_bdS-FsJ6mZo3ghYu3JoVW803_xswLT-Y5ly-3QcYeF05hMYVVvlVyBKT3Rc2yCe4ZB8S6MexykujXn2GP8evjJVRFj5q32jzXOpBpWysD5T6e0R7kXVWIdpxVuhhW29gmaJ4T6qPQ5Im_r2lvGpRK8iiQTMBSrpFJQLsFfli1WeT9xNmJRX2NsvYmryZfK5jI3i_hb2_c9tk2X3WNHsOPQB-B1FtvTOoMfMG7NFH2PhFbPRZpcVQ1CeoQNyxYK-1bFcayqFdFuEo0riZbHbn2aQX0XgGWj3s_h4SPOlVAJHM4T5__GmX6otU4nMEsFXibeRD_aW6nhACxYsxiF8nKVAweFX-QbwZd9kb_U7E_fx23QC4rCSBvkzgugzf-oNx5teDWgRyGbPCEwjPey_xO_FscB2ok2Cd6d547059lAnLQATxmjGWmEVS22qUxWfp1BBQcE-6SnY09mr4RlIfAP0qhwaLmG3JNhe6MJvbFfP_seiMN7tr79xej5KxOtJpnRH4cFAPkBK8x0Xbxs42ujRerFw1NmxHgFm0vyPpCxaFVst0d6tI1dw2ETDXwV8KcXbfzZFZs5JE4vgq3q3WclGHoGOHpeetmVtmqSSLsh5Qk02bsqhsj-UpHAmdNPkwossEmar6GxOIqBXQzbTqlUnN3JSn_xZzhljgknzT3HL2Bwxbi2M-AozzDXJDk87uBj_3wZUCFry2UzOhuvZX5lz_-mbwwoAq5oYYz3Z0Jnm_6MvT7hZZf7F9Hn9G7LXHGo27JQXwvhH5n-OJn89TgK48_qtSmgBPw2ew22qq0eFHzCBNH1LJyFrh_aaEUkxsyzVFBWGm5hJx3qhRMSj0Gk6TggAVSzU5U0d5YHUS226b2CuJGOYES17_W0RHBuc2HikitaX9dLtebBePcRw6lV6FOSUqdzBtQZzNCweZsRfrhHnv4YAVuYTyFWX7v-dB8YcG3fs6LlgG0obVPvaEyGRZIdU2tCh7c5yw_OluhznYGF_vqTPcCCahVsMl3G80anq4ybwvymAL5j-1rrA9fosNYdI9SEYGJcu8HcCehmg-yd7KhpJH4ykHHvVARRTvgANTnWdCWlbIdD8OUDnSntDTDnS4D9UoIKEzIZH561U1XoMMctww87pe-eNeYJ31eW4cd1Z8Ho4dNxfxbCJjUo0hdBo_1eLvLP9etBEAo7w3xnTg1DUs9i918pPfocmGtCovV6QRRcnie0v5j-10CPQTPzOl7vhbhRDG4sTJTusGZI9Ns4CQo8kk8j4CyR84QyDobL9Ipd6Zg5y_MuYCKFrHD4YV1gWDrWWSqMqUvsomwOqTKPOU9nDT_hyUDQjMtSW2a3fPjmIpC41jMOim3BGWLYcAZY5GVO-qjAI-vq5nVtiqlHGJcZKfGE09P5A_3Tj6C7MUHsbbUn8KdzLGGAU17Z4MCib2yv06qRpy4TQlVepZTcczmNIZbikSNVUcdN3KwjpxoCKWOG-A1l9DvrRZESf_s9g5da_oSuXE9bWMzV_ShkQgf_kjTOOQw4vTCUOXHvcGRbt-1uN4hPd_H4e_8qtmQPv9yVP0PxSeH6oiYUHu_MahNxszkoi63ZcDpZfJkcDN-Gm_q2EVtzeW5uq6pqJN9Ecqnq0NeUpdEXesFiT6s28tusUQkObP3070BkGdHGltE2O4Radqmt0XKNwvIayDF4-WsgLvO-xlYMhkwR3QtuGZnO9BXQn-IcTSGYS2alKym3dfTcx_iZSIgMdI4tbMYCdqsjy7yXKXbrNLA8Bs2OEL7_Z08CfC24vWZRIyKHloTD1lCifDomTtZXCm3OkinFTJNz8IVDKB6jL760oAbkR97CXxyk73zId1vOhGU8pES9zdpz_brInXIDVoMoOEymQmx5oSfydbZDcz3IQojcQdPutTGOA4a49WqYRLT_BOe0W-qdm5LGOipxQAjUBu5UOSQkHMcH_vQyC8k9ewbV4nbYcVToCW_9tuYZBLDPknQajFRx26kVhGC4Oe8YY74pHwRg37o8-NfYFNE2or8fARAxoLlvL9lwlVp-5j4IVSQFO5f7FoKelJ0mourqH3bnOLUcPs9rvKVh2W-B-wxKF2Ia0xabcaorKvSYaASUfDOoYDdv-u9HW4PWM3kCIxQwTC-_-0VI3EpkopmrnlYo5IAV0fmmMAr7CzwzZKMjbotO2-Txg4f5osPNF_xr7yHkOgyi1wAF0rkXmG1lmT_uHcOsUqukke1GRJLLms2j3RpIOaDqSrh4RF4jf2GelsN3-4Smj3g6xOOkw1oTejz97iG4o2u2yTuuz6DpheX946sDBQWLH-NWt0GMYq9BWtzRygkEhn5PJUUGPSw6nfSEKfrSAySo9nEm0OmaRmR2K5Q6IodSliLMGY2xqVk0ePM8s8FWcIYduVW_f-rxKonnVIp0XcI9YnVrVuqclmXGc2FDsyajw8UFZKpBni0Y2e9Ttd9EFGYVxM6-LDfSvAgqkq9-fiFE9g77VEO4_FQDn3hz620wq-SP4X0z8JGJ7rs0LotOZiXaiGIwQLRD5OWaDaAk6xDUYgD_7CEcc850uPhWIv9TvbPMviWxbKYngfoQILmqbdKdiwoAGoUGtcZyChD2a32yVuXADXYg-F-VslnqiDM9IzhHp8TmDuijljrhBm4i6mPQydMz-e1skf4o6nbHqe4d7xIwLP5hkTKHnrVSXcMdNAp7m75X1XoatbFUB_ZdT0aLIhhuYIZ_ViFSS_rNURCDaflbroN7dBQTlXaFBANnqVVRqNMC_8d6UhydLad7tpxepx4cF0EEDpRpJbJSlCOGtg4EVHu5mDIuSDnM4vyKUHNZ3EEPcTtd-INx_zPeFiob6AId7dpCc_oq1BDE-aaWm99L5CbLRqA9ozj8IVGFI9riVgtb49_cMx9f5626v_XhtM_nx2l3ogbsG9zjKxebwbV9-CJxZrt4PXL0mRU4iroDjEm4mUfb2uqdQTOn4PlM38ZyY4dY-P0n9K5S7iZgIoZP8sMVELUxUwA1DQuEXaJY0IR6S3JQu0BTVchj3V8KlEtC2_Dj7FbsW-3pJbszajcsW9sDzRFm8Nt3OHgYFjEO1vwxE9cSkYtb_HHCnlzbewZGVBdhkSgbxkRMBlIwjC0jJSrEZObdt78EChMrNVcl1jNtuOAXcjc2zp2xToaKOlDg5Copr1QKovgGyzMI8DUT3TiTA_er5NZ51KRBjD5g7OguZtyi5W-d45COFld-KztbgoKuEFsfxwy4rDqQLpFdbGpL6FqX2Hacjqmlu_fzS8QDSoxyaYMdzotq_n4tBpUwEL0z5UUPILlpM1N_nFM2cYivwh8pvvIRkjC871TRFkZmIDeUEY76bgKqiGWxW-2zi4NdL4H8S1IT0DP61mu16LSR24zMJjOmYOUCfD0vDicR36ytHZ2INEx-BTFNLsesg0ya03LkwHUgOO6Aq5VEorRFVj7nPHo0LwdwcsubmeoU3BEyrTuCmjxwmHiO0X7EOzvQbLmtO8hS06ESVAHiB6E1bsJEhx-TdENcDXcFnkRkv_V4aPI8A2XLhp0n_G0jCLR7rAyfdps_dDgubjwZ3-L-9YAYpJtEklIuo_QuDlz5AvAJgv2WkeU7JoXztjxmFigEZeXy8baA-lpfUFWD0x-k4E0DPMoCSsHxWIgWHYbRowKclkBbmuSBuIvKmuX-3aoVDR5-OGmy-iSiwiH3H-LPqwLD6Ks_ihFj_AWW57CRU1euNKl3a7XRjI-z6iWqMllUQI1BSkVHQc5hsQpzCxPSdC9aVlpzp9qrH9V5F5JjMn132gLyrZx97A45EIgi2C2z5ocX1Mk5FVunTw5dhxz0V9I9PaywoC2p-4GIuFJR8TBVvzWs6sPfhFdqk5jfYGjD3Jrda1QmVgiXDJ7x_F8z8gxK4q5ut1p7bRkqzz4uzMtmvh6H6jJqyja1CKw59HAEK0MXe5bat_816WD16GRw0BXkp0DVKAsik1Viw5QPTHjgBnPk_9xrbP74RvJvKELIFFL1U1eX6sJsv8U8F-CrqNCrjy9HBkibw8wCunDskh4fpX9k38Gf6uZkMebFRhTnEAjI3k59dUUPJ4zoVRf0GNX6t2fJLN273BpN-vKaidSe5Nx7sEObvs-H0wvyVYEHx0i7WA7uUF-0zDl9WKL-scheILt1ZdtGVrGlAZnCU1FnIGlzvhBI1OQYuFqcXgY3TifVQ-v_LlYrYc2WjdTkQlZ1TOUOmdBpgjrMtqZKMpXvGjNvlFL0tlvcalU5NmOXeDgtvWZVzwfQ3vGZmbOtq6ODo4k5pOTUrNgJclTM3mG-eY9xRduDnKhc2K9-imud1ZaGR4iZv7U5AWNxe0pyiHXbmWGGIRWqtieYKCSub7Bf54-fSNDlVYQPHVSNnm3HWebVujbMaHjJM-3IkMpuRI2ckgTz3kFS2eDZrS4TPWc_747UKG7FkjmcnZVpA6Uus6PIFpTuz3IyASxFT7CC4bf3NCkW8daJzCeHG8PsDauJw1ZwYCI9ADhJJKJG8qysxzBPJyerMtkJMJQV_5i6owcKs1xYDCniXUEvflGQ6S-LebWRvJF-FAhOjQetqZFkfuBIm4FlWnTWCzhdddaNxQP1NFaSVfBuT4Nv5JomqB0yJVY0CMxWSQAQVd0dF9PbYKcF0cE1kScH098K1MaYP8qMT7tqrT9xfr3ingGF_vs4uNpfOVTswEQFSv6w-FBi4v4PspbWJc8GvlvpEc1iT673KnLJeWUFiMvJriSjzLnYh6wYjwaM_YHSZG-nheJR74vUsyEwcEbGPVtevu-a8y_KHa3OLxgKPtYXl572Bt65vEaBPsKhL8ymJmp_mHB-01Re4him-TdlB1l6rKQSIth57NL3-qyLYEaP4qMk9rt8EuO1dhZ1lxWPBjuYlFAyw2ZXerNZHg4y4NQDlIJu3WNEwpWoQ27rb8FF_aA_FyiJjrK9IRM_cav2FeRoH8lzXFhLKNXL1u48ktS_sv2v4TXlymfY_B9CcBNKkscXXNaVZ72gPCvbLVjHX0Jz4qs_Pvhocy-7r6EhnukDubzMk9qhQ64bX1pwmXdZAO3PGHeyQ6jYPceJO72XU0f1IozdpKLGmTQsyzjYtk6HFge9BVHe6MxStM9b3cRRKcz5Is7kV_gxiQ0bHQ7wfXRnkOJKZhNGUrjn2CJN4Pjum2lVJtScnE4Qoy-5RbNC9UjsldI_n64hKuY3Mqx1vwQD7ST8Z5wSUIyIXlZFb69ocvcTCVVMn2H3_KWJZ9-DKuBPb1HOAeAyvn8DkdFUfH8QD4vCzufG85HnGh7j4znsxz_BcwaNmYi4cNOUUcZTIiVehFVTnAIBzIbQZPljwS3Q9JZCigTcG85W52kRupfG_XKQa1CTNyk3AgLSi3dTkiRvnilxpcphLVQSWzntcwIPao0W5EimJoNA7BywCEBgwgWLm5qChTluhwKIpfGquo3lVZpPNRjHg9oKKOfosNZa0PXXngxjc7lvNRkyghMsudgKsaLsxi2r-iEAcO7_og4NBhzbZnrc3vALQFv6WzFg-vY53fk1fP4bMS4snFtUIUSyqUxdCC0oNOiFhvx3kDD5RXtUSguCDcbSCU-8QT8-UDX9b4K7LVsPDRGKtfajW7WDuQop0wrAunbHAtKXJFYqM-YvGuqexR1569ZXt2_O752GQvDazk-tmZDh0FXLZYw58vpN2qMMSPsrWq7dPKfg1hejve-heTP_wdnv6ubpSDKUeszzdOY2IHNQHaOkafxg-2SBCJJz39Au2LdBEohjBXDpPEWvRct5CtZpXhclRVJaC6MaDhljNzZ_02cwfCM3Gg9a4aOG9Kyf1ovzvvyH326r-QjF9HhRDhG97Oi_V7yhSBQ3jcLsOLm2Urf6x-x8fHYqVNHveFKXr-AResFOE_UaBjzh7D8rNBtRGiXlnU-H5AYnd9Pta5Dlxetrb0TxXqByyqFBrioJzHi08H5LJjXUt7xCnRpn6QJemXF49LvbE5CgRXOIKlOmqefzWnO3pVEbWRKMDWrkU7MFGmxBETgy4nXR4qA4Be3pz8YIVq0TZmmKdZVr30YpzPDWhhHJrufImXnq5RO8vHebNN5vIN2Gd3Bh4o8zrQDYJP8gS1jnKWf4GKsq6J2wIHo9VS95shn5QTGUEPnziw_R1ZPN3LQ_x8cDDJ49PZGgNmZm0Lb3dt0omPHp0GcQ8iSJIg9As71pK2mfN-SvXQNVCzPvcPAxT-npnE8HvgcZKRmVdy8A0OD0S1r1LqrQ0zhEo-0xWhqdSZtCNpTA3NaRZEpsoYN5OkMMKCY496b1MOd59kYVWZATssX-8W5jOU7M7bZl9Q2GwfNlqfau-C3VzimfhERLw6MpcC0kxVW4NVUyKMcQgTgX-_LHv32Z3RLxzVHbUj9asQoZb_8v6GGpH2Tg5x3Z8mpKW990ox5HgLHeHbNb4WRY3cPaN9WrfomffpgJTr6yau0mg_Z6J07AXXwiY_SXjOocqplZMAvFhTaNST82bNZY82BJA3OAT4B-riahAMAe2TMvf0zfTrI8eSdgGnXl2tm3Ow6Hi9T9oXeVHJ42omdMJJvzgbf0QfCA5GeFNKGZLNC_SyaQvjW-aNtCDDTEjQHSUL1M-40JNBe1-Ere5M1WEV-kkPRRPy3NH6z03rsCVXAmjXTsJnrkh7JOinb9oFWDBtIBygYFMo2vDzELa3ci4eNGLjzPUgMX--lVIqETze4UJEsee_jHWH_OSkmAaCKJuNAOasJOHZzllSa4tHsLz6vLDlLDQPemdF8LYmSELf4ZEcWdPwJuIhjxLTaUcHRWB3XibCj17YjX0SrE1N4RmRqPXs4V5mpueMDrAvA72O5hKQvw8_TXZ6TMGM3fCAGoOeTvt-dG_hfGHN3Kw_1alEcd7iP4VJYJ77xPLUXcHu5NJvYTwDrLT94zPSWZAGttAEl8RyDWbDJpjxZBxo-rDbk6wk27st99cBJvDr_oNrK4cGf0AasiZigoccmOAyL_KaBXYV41AYx8UNDskY0gB6HVOtqilQ2K_Mr2ppfM3M-J1ZWS2KYZWg-nrZXMgQIkdg8wib_v8ZUvzKvGc4roNxwdZZVlVI6VFcV1TLm1a1h7kcRTx9CZ6jJ5msCSrcmPE-VmmQQYXjgXctS5rRQDFuU6AnTwAlNG2gxr9n_7iyTLFpff8Gqtek5Y42t0yxrxv1_FWvws8U0AdXIZvXy36EPK7Yewuzf5w2fr77KNbv4-m3PI4t9GMI2eo5zmGFFC0gxA-T-_O4rmkbmbGupBCqCXr5ssqF-d0gUZKZDDayuEDKN070olR4pmYvrjFS_grOR_6-MJer_XX0Lfmqlzdz74H39AdNfsZbSQtM-fZEwdwJAqWNJy5W5gNMspaAX6SD2fY5gExJ_DTMWjnGLIJUoB1UstfEwmoP9Ma0qB3k3WfaR9uphnsyXao-ZiaFhbPIhd0Z5Uj_fDkzJb9yhi8tiBt7KAc30gfYWGzl4qYmvctfe3qr94Ub0_WfvPJ6INoxDXr9BalpojZHlcHXq5upKXnKcLRSi8Hu7rm9sP4rwV6EcEuhLIKLRP92T49xDJb8Vu0KJBLKN4dvjiPmQUqBU6jlLumugG9RQGDwAS38dL8xFaI6TO0pr6D3Na9H-bausYFNKRnlyKLtdbrPbVvc6rzvGSP5Axml22_OP-9GFAGrqMwGSv52Sq4GDhfku2sDLrpFL1mBo-VP2lbfFhCNfDfYGFnQOYlI7ncGcEzvqJ6N6OKWKGK-dwFqWcDbkZueGWx_xngz0IZul2kaneQB0FJ_KMHFTfUKpgeVLsYg_m1a9AVAFYyYO9uU7e7C1aS6dwOujr-hQ6Qgc9TbheS40uknUHe7x9v3ike7N2JhV0ysmP9jGM7GMHJVYi1-oT7gBF8Ifls76Bl-HlzlA_XpyAjju3WOgwbZt4N5W-VvXC9-QjfFvg7VCq33R5MDczbebSE_i92f0XYwNRJJSIA6pev2lz4uHaJJEC5eyqNygtL0XIxMBV1xf8gOFn75obbP8qiMo9LAdBmDa3PVW4Tx2I9U_QYZ2GWPZRMaR-6pfqAztrNs57QiyihhaF42rxREMVQVCxjUMEZU2Wyr_K7SOl0_80tglXCfzagdzD0HeDkcqPhC7nSTscOoo6TrjCE-U2FijoiUVsB8ni0XTWtlaIb8Y9GgVXvqPu8KPXpcIO6fqGmpjmtSpfABV8nn3GRIxWcBF3mYmzpSqI--Fe5cgoR0sOPgi_DAkyHx9bk2DpeYgUR_wI_vlxDR5h2o3jdRz0ddXAh8a1HYyO08VKv6E2YkE5wHwFNQ1s9QNfRQO-cOHuPzYiguyzx5NZTS6ewlbcyfKrAtO6SxDwCkeFyckMoyOXpjSD-PuVgJkH9gKVY_6UX3c-zSaO0W0D13FT6jxgJ6nn7zzCrw978PlfllZduEUEVm48kM9eww2PrLIbX4ZBNfaBFP2XX02Nm5-sEMxg5riN_54tt4ZEgaD5JiMe_--g5mYosXBcP4nSjbOOaEH598C9yWkvUYCmVlWivV6IY4v1Whx3SHd4bseguPdzhoVdOnlnpzL1y4pa3SNEAoJgOjUTj95xUR6-qAvWQ57UpG9GRP21hVEsVWdwp1TL1S4wwiknUGxDJFL5vJM_ECAfWsfTSYypIvHVPUkKh2OiDKFy1Feu32n1wgqEXScf4Djr7yDuGvddT6Ko1XRuJm_MKh2MsJNFmh1B7CTr8xBPhsjMXiebin8R9vI-fl6YDcRVmjy7ul9_qGrxygjTs2TFk61fcYn3IcSpsTHvw91TonRORN6hkTOw4vO8VhzV2ZqLdu2EI3t-fO5DyIsIjzNz2Ul21-SjSuSokRcjnxh_Puevr8RqXTLeyNoAEOotDVb8P_na7WzG2mOfntawPCnSYdWMu3n4eaYY0lVS_cFmSItNQalfe3I6eyqv_nni6V2rESlXhienG0SbUNh0_AGMZvGWc7PyQrRoovE0waBIXf-5_4oGZYOfmREobq-mSHEV5d-FKZAtSgWhxwUU6RHYqiHxBoscIk5hQo5Px6HCwqogG0cwJ6s8bPMcFD6EEeOUb26m5vU9SifmtQ2sRmUWWzOxdsPO6_SEVgzlTrQ2Jw1Pi9BPjm9Y06Wn4ao5uszwdI0GPtilhEZ-H8HsJVqDiTr1dpTK7sJJLPx-DKOdgGYeUZqk3A6LaHdzufyvfKal-29hDNef7xvM2GbRXAsxw-9S41O27_Z9ki2dtlokEV3-63_hQqVkDCN8gqr1IRUXBX9_RBVrVZ4SJfhaU5VZnUHxqk1EoL7TBhkaRxZCrBcHDKwjNaFWNzBrJJnxQuXnPcmKGvER4xVS2E85JjwB8RChUIqAzE8pH44ypz6VjP12tiwPeOCkCQol5mUKXlg1ZDckwSi3zjsDURt_XVAeTkD2M85DuKwp8m75G2m78dCcYTeRXrkleEvPmsJyZAFuOBrLcWEzcMg7XImtlnyfmV5QzKNjhv3Jxv5uVEfv2gduvZ4duk2PQo997mhs84ZAxRDi6Y9jI2Z8a1W_Jeh7DLIJC36c2SIbgSW9NUEMdRy8_ejmTc4cMfJaGFO-Z1ezwLIi8wrwSVY83ogpzIvvZQPyn0DR1hrh52xq1fcb4yZwJ1YWo4JY11KZvLqFddRHEu1SVq0TDsqvWfJzMIT5DdIDg1ranve_-K2tw8zgAqDewTflXtAhwxXQaWBJgUrhEBrKdQpoCEuvYAbRorbEi96kOeHmojEzKLN9c11bRqdVgPoAiC0QvKFMLs6f47OdGAb5KtRS1cEdpCwSJfEoaySOlpfAY-KmnwFe2K-YN8ukAYNw6EQs7byond09j6nyqSMfs6JczTFvGQ8cFI0Rihh6SLY3kUkEsCVfDVuuTtwgOl1ux9z3uBI12r-RnROyVLEGQrbEGsrrqQYfaY5V_sAKu6YPyqp2WNx6CbHQL1Vabj75KD3gIU7TH8CmT9FM2Y-pbZJVX9EvgENEpCP-1zLlbj7G0wcE2LFw9Nl0HyKvUK-h6xrcKNr0nR9wvwJQuop37B-xcUZItboZVu0dnjhFWFviuuyR1izbKdev-ZMjmGyzVgE1iisBP70gJcNZn4Yczn2A4QpRPh5E1HqmoRSI-Y-halrV5XwnqRQrbZJZ6V5xL6j7u-_FYKxGZGtxN9CIudZZOMqTBdNGNIp7myWKn0j5Ko75oM0QwSjmiK0EJJeX6DK6yp5y9Q_RSwpKgnpLUmgpsNoeYoXr_xxzNZ28XHD4PnOewTfzmVpw9fOX4_T5i3BHzSzQgc6Ky10E5z-Et_kg6BdhHPVsPYEzwbiq7aTXR67qamV8OohxC6j4TIUAJlT07pCsvXObGkHQntEmeAr00YcKFoRWsCQw9pmeZhrFLouguhqkQbkoLEdpiQ-VFsmBeFCb6bsuUWywt3IZ-b3sMo3dyhOfSfacZFEcGAjLtZzSXQTiLpez_nb8waQWxdzpEIXuGtFzETiSUwK1qZC8mzzQZEpXzRAQuAgIe_N7JgMWDOIhNKx7unO6mSdBDxxI3ziSkwL9zy8UBdMFVXZKPmkuScFTtMkNA1jeDFfjSnvwNAbdENmLgbN0si-nC4WWwqmY06OPHptRPBeZyZZHK3dN-a8wwJ3EASiYcE5J7KxzDai4f7KtaqQIdx8MmwJcT2qsyRcgK9-qw8UH7QPZ5xOvIRwvy0x7Xmns5708qG-ZlSwuSHjK3lcg8ojGZp2jUBK1XDvpmY4KiSJfRoqifGfHfJZGDlCztWKL3lzAlVrmBDVnT0cvb_EcjhLuc-diO0u8SAy8XLknAhvgg5dPmcSDGtZHiL00W_Y3pDphejUGWS68CZpZDsAuItM-2XY3UGdwjT3yLHFNYO2JLiufu41t6ztaryVfBT-HiL4PKnQNw4lPfrOJSCTz-eDaS-Rdn67vRa0tSYdMIuK9trp6PKDGUn9W1DMpwK7sv7xKdrFDRH6vXCGjKVHPvgRccXUCLhaqzuybX0I_PULwQ9VwiWwNa29-w_Vh_X9moMAgi-XkNNv4MCG0NybG5nO2hxObkyOL69aV0d4zPKYMmc7wjXDXgM6XHmC_knidFaoRpAC23BS2TjGh86nps_IXHLh05iQrFP0S_PdPNaIjZJqFZosp2RkjFcawtEC2Ld3vz9zZNDfjGr1wFMv-y3959jcjrVWWlRZh3v4wIGx1ytnekPEVTDYenaDHoTycW0Vfad0xBw8KPh0Nfvq6imHTNr9Wsi_te5fvJXqmnfU44VqjV18CXZbtI9o1PJ3hc4Le2FQF3whD0axqPMXWpAb6AtMtQPTV6mwe8kyWkJBiSlsxw_psriDg_Ytq16glQsckOwqRASHc3i_xWisRbHsXza4ihXFxmatc_GzJb-mXsxnIXB9VXWRFdcws-QouCDR70bCtq31HP5ejoHc3YYHzlmPV9PC8P1QPKnSgJyCnRwvhOQ9o53XMl8Alz5r71qAK0X-8v1PYPnl0Z1iZOKP6yJrPAZkAD9LgHc4w08itAlDuy31ShH7BH7BOfUkk3k_BKdA5lskJz5uoa4l32BmoA7B7dFtwj_AReJ2IdzpN_aqpZd0i8rnG-xdweWYMYSGblBYHMr3P2znfdUWeZXLTpi6v83y8Llth6sF0GiiW3I1BPgep6Mgl16K4is48zvA2MBz681Ln1hgHmIA75tmhcLSN414rjhNinZRk09_Kfcqfn7zX0OPE2e_j1cfWWojjIyQktKEFOIPLHCz457aiSu8mouwWltX1J__HGiE059nV5e4YtcTiXzRQWNVltS0KA2f0su98cmT1VFDb805yghCKjdGacCjoQ5p9oQcVQuHWWagBzKtyXBU4KD1jn252BRhbQLvVVLDJtc4DyMT6LLToHzM4GfZoAtwytRqew7bhekRmoU6M-LnXC3bKo7kf8CNrqj4ipdmb2kBbnAvWAY-psOIXE8gcqBsvkCvyI-HwTT6JPRcG-m6Ht0S4ExURB0FFDwFsXKQhI1Jvabu3NLjkAEj_PfAg7xeCanbom6R7yErUsf00WAATG7IgWIoyIGe94yKe_rSMn0NyzWaaCJr33Ioy5x5gJpErJTqXKtyBlq85RWgPn1D4srMH1QalH-D0zLR3dhw2MJiKsz2P-qzdi0vr3V-TyFfLiAJK9s62KbZ_uG3pEYgyw0wPZ0IfIpIQPfZgkDW4zMUJcjx9sV2S7Up-LnXen8zEa-jBevLeqIAyKdV6dMzpgbV8NfLFqFz1UvqyYMoCnBJAJG0t2IYxrckdAeQjyK35Qni2I-ObgA3H_okrrEwVK0DC_7GkYU6Kz1rRZ8NXAwUzITCasq8NS6P9dhv4oGuXKX4Erp-R2-7kX8TgHquynRCsUbpwWHqmsJigIOLgJFenwbfscnVF1qv6RtB2IuuC-A_rgo05knN2TI_6_5J_Bvmg770GIaVkizvLAylUipXekQbk1qY0E67WM_wFO93FTJ-dpB7YckbLd1CjTHa6cLlfjTzEvwVvHrTHha9KElGlWSx-Ah9OgPoDOfcmK9ryJoFwihn0bS06_ZxXdKz1OgtCHMJiDsN4UJLoLY_mchLvYfznBO1WXpuoESKxxSBp7VL4JTU5un-RCws2QD3IoToEkejbEaKcEqCoBp7VLUHeKxazid8yiPYIC6gQgXAomoLSZtwQuQ9WgICbaHWGqugD1hraJHKftZSRU2GJJ9Rxqwv8mEJp4ntRxR6SshwxxbQxypkXpM1WwpY6MyRCh4-MVmKOdkzH4f-BOKMaLXHO9b9kJZrZTQJ33qfdGhGTdOe2giWzcoRLgN8mSvlaCWO34qzPeHjs__wQgJT41l9rN7cy3ji_DgnBRfY9WHY10uZpNWYXMwakbyn_vZUkpANYq1sqv9HvpFSK8oxZ7IdXX2LrQHsXQ_XJY2q94xyw8kb6jWXk3vJvWESK2MY3Z0cmp6qVb2Ye_x7GnTYnc0PCkSqAge9b6mWa7XxBziEKhlnUqZ-LB-pJdpQOYMRqXDpMS3qqMlzHwFyEtpnYJ0BEUjLtKtW14oUOrNJWP98Sp18VRY5WmO5AffRET9_19ISmTrLYJbpjVCgX2f6GBJE_vsH5oXFRqq7keCXFVrw-WRVk_hJMpegv97SnvC3q9xyzVQZfgUjB2FBwxVfTDv1OALAj_pJ8JyUMRFqSGCbQ2U8oO1zhtUdEWYGVBO9Uz4xbIObSA2BPVkE9HhTcLE8db3mmPH9DUTv3m40a9zkNjVL7zxqilyq3D3nsY9FgjHFgC9HZAhEruQRz9vQ9oqZ5EvgI0c5IOJXpHFwYMG-rlk2DCl4juA7X3mBceS3rSg-F0Z2sf5jGuwsZQXrb8DuUfOvNlMdHf6JbJr_AB6SfFfisME09CvWukBL2eKQ0ve6ZE4X5bMn1OYdZ3glmEetbLOyaJ3AKOG0kEiUV1ixtnrKOcT3vbFfseE8Lbuv-IpxQeTD4vuRkm8FmpCmgukNNVZAhdmE-QZ99gYkJ-SLP2JwLAWUvSB5D8M29CraIdrDighowHg4_sB4V0OX3wBb11WY3Y77RinnuYJbgD3-gb4lHPRpLX_v6cqkiQ-eBY4Sw3aqbxAAt9XVszlA8AJWT4BDuZpqxK8zr0TNi3Fnz21D4KUGKkeEzPIeenstq0tt5JTdQHlv4BeISV1xe6bl4MGsxJzMAeagjBgoSFj18dA2a6sSWq3b6Om3o5o46FuvHyzcrJY3ebMd6hN7XasPO_jB91BfViYo-hI9rVSErgjTJwa-XsQF8wErE6P23OK7ll3t1p3seq3MaHZesSPa-iuVpcNh96Kk4TJDz6BrthBPrmzOgMNhIHDyaDt34OwNGtUhDcjRvQDI4eQtE4OdXzVtkOtrM9t4eVWR0DLNDaAHvCI_j4f3kfHpmwwQRsdv94TyP1PPA36_rzIh7f9isUWXO8R2xRuewLfYc_JiFLXH_QmMUlIuUlc4K9Ab3NnvrPiEMvv__gI-1VJjGiy0iN_bcwHsWo2Ute1AYfQ9VuHz5gI_4jOeOSHkoNnCBPMSGUTUp-gP1wDIinznhPa0soUqL2tQLDu43HfgQT9XmE3MPuI_05MnuYtAUZ8wMao5fzkrBv1C6KpBjO4GGT2JTIgYosAwxD0LR9-MpV_hYYEGavN23-UiXX2vpLKt430h2FkfSFwSkWw-TsPE8HNhN0FtFeNueUrM82kAMS04ET21Tf4i4gd88CuSyJYF1tMQI468sFq12Q95JNbOYFhhvVw4JNuHyhL5A5H3SdetRltsUJW_2lg6-Jroen_vDO5q_6pr0MVveIhOV210ZQkjTxMdHa7ErriU4EhfcUnLooG1LAYpo6ux0egF7qD0M8WU62aRUDgj1gzOkPjwZSLLBKLewimXcyvKZr1OCTzHULhVcpmWkVLwIoDSavBJPBn9OR1f2o6hMFBuspPUmoZ0DJBis-ltmCz5xYYNwyZzgRzPBXU8krd75xma_a7ZA_rbNafYKgTl2t12sXFvK32r9ufxFC-ErS1mmGdnq-h2Dljr7h2dUUTURUsskt3mnDoATTevEn10MQFvg7f3jX9oW6N5Vg57BXTLZfcsCK32g7U67Uuelk6x6EbP6P8-kVkFv23ClTMrBB_mXReZ2oPV7oVFh8Zv6NjiSIkminulVyRwvJuLhoSj5KY7BhTWHYOCc739LyKA42EvFN9Dbn3m-wnV--n89L2zI3zN3MtkwcGCP7Kqgba159F9Atyhk_xY76dGVLgmGdj0bOJ-g3VzhQq5xk1UBm19qjjhPm1abnz2RLOWaY1sdhEZSMQTLkO6LWbPh1aD0kLzUucuPjYHnBtJcIysuGTdJCSNHaOqnFa7q0NEV7nx2CFThro3U7mCDUDrlEK_thiRny-xd5nxeDt5_qCG6u-0d_zcm07BJhx1FRk4UC3HWi5DT4_tNKfZV0GxoQGOfl6cQ5TwGPNzQbRtmM-Puw9XlU7YF-ybgmiEYQIZG9FlQXVZo_MOKdrAAR-4BnLKsg3qgyeDSL4ZIuks0An5SSA9S-V6OisCKwic_CovDgeGr4eetMStl0vTsk1lIN6Boi53uuEdZIxVq457sP0dHKjmOvUY_J-L1xXOKNZrocEMK89E9icUnz2UYvYLeZXPEeQqAXDC7iLaImSzFzYuBgpoQVUMYcz5Srr40EBFec32CmzzWiK3qkY-UarVvtZ4Xchw7QcyVtQPXQ9C1VltbOpaxE7-jroZmLK3KHm0_gWtzm399DN3R1RgOYEpnDLGlay2GZWnTbp5SaLOb1yeD_6ioxgFJCC7mS3BbGT5o2fJgWMzOTWVRP-UaMr2xsOWkez0cemJDAMfPmE6p6yhngYK1VAG97m9c7erE0OckqyS6ypQ1rvcip1e1OA3aXKyVb2eDM1410YnSDi_b_Gj8wq1BGeTVz0yCFV3P4Ubf1KsPRUi-FwvMnaEGSs3B2X-nfVKaSUqPOyoDeiaQkzzplrBSn2-YKs3iMu0rH1mIn3GRRCjQoQAS5G49bpBUYG3GTKnjBCtVes1NMHLYgf8LpwD57kDImiPj8JdN1frKR5cfllRsN1bQBWbm5Utfv4eynZixY7f-be60PIQd9jG9uxAuZK2AZI7cUABULr4disUy6uGDlwG87TnpQ6YrWuogCSMuCQSiDAedTBZuraR251PM2Ck5tWquySks0HgMptKmB6hHCenso6qKvNrlNCVuooKxaEW2peoEYoulOGi69jfNAhdv__o4EioDC92B0YsHfNvw-11qkL0mLB8D6JId3AlpTcSHK2w6g6iEK2ttS8E6i4zw9_z1_z5QK-CoU4o1bvjGErVNywByOrfyQRIRW_bZFJtKjylYKvOEFOd1O-Gme1SaGsVfcbJb0ksaw2uxcg08Uzy4r903LJqJlTgEbsO6u9jhRY3a4LLH3aPYGJtR0AfgALZ0VxOeGe9ua7sdeV_-TNWwMMk9j6fTg0iYm12qsh0BpwaK2O6DF9H66cYvoDrPGrghqQcOtSHpEJ9YdBF8-J_0nOpsbo_ClKm0kN_Uo--YMw7oPFH-xCiJ2gGXrNDPwPpvOlmnnRBIEF8ShCF-rflUrTPkYHSZFuy7-sNbDRWAngO_hvNRcGPJz0RN58zkVBQyzTCxFES3gj2KVGmOppbIObtLy2uehuz4BZTChvsWR-CKiw-5kSa3sRSrvy6oI-RQiWCO784fK_wxqHfNkOlN1YjbFpaWFHSiwGfMHc54mQXZLpI9uPuqhUOXzq7U-PRVfCgeVtHLVyDQH2TceNsaFQJhlwcRqxOpAzqTmeWcSwKSdBEpn4ovMhVs_YWJZq00CoByMnyTaMiwIo4v_QntFPzIUzly5R_rbj3Hvai07sxP5_Hj0_Pb7D4fHcWmhnV9KLZGTBVhXTa4eMSgJ7AmqEO05OidaulKf3lORBZI1X_o-WNhlzXmpdQvBtWhbA2APNXRlf5GLpAZxQxiW5F4JNorLlJWCDaBJ_gzWplOIEFWNdLErxEBEG7ZREd84LkVehs1mv0VPLE3NWlbYWwodoh8v5iHPyv7_JtfRL3R46QcZKWbUbqw8UjV_T1OunKBytl3muOnGN-1NIZT6gboLt4OJP4LVXPl5jtMojHysZp6CE6eHojbMnz7WsKK5Gt8D9yE5HUhpfV_ct00tFiQQR9_4HYb6-PScbPlOgSRIFAnQNetrL1uckNxuRMzRCZyRRdIet1v_a-ArdjBezmOoS34L863nWPreaEARq6Vnb_nSyCi6TB7oIUuwpx55_JFaL4HpbF6ASo_kPS2oJBnForCt8KtUz2sld24ylCyr8vkyRrPJb806RtfFPbw-RKvBg5EHSGy0zpRasuwNl6Opj9k61kQN4XiZ02jz3-4aPpqzy3ZNuMGomh4_EX2Yz-H56nI-t2OuaaITLOj9oIz4c1ro3iB6AAL8Kq8pJjLhPu9xCUTfn70w9LzWhvSA5jxuivkh8kdTQ3gCImPLNVMt38ko6Ll2wQ-9FiPwp1BLStlVcFbu74rudIujA2zxPY77vbSTQtq_QcrycnoQ5S0nZLFhNGrvX2GFFpBKj0XTRddmNOKcGhDUSq6Qwf2fEJVWmgGGaDSZK4CBWs_NVbqYmCpVjzyKLqzz7p_iiJbB2Cpu5uSiFoUT1T9Ievp8WL5NO0vKGadsfy00vUqTmBfGkTdubVPnR5ZnLxmpQIxs8tSNLiWjpSg991-D31scNgx4xaMvzZavY45lfgzMm5n_ihQNZvPFqVlzKEn4hHcCv4gI2YrIMrJaejFtesKS880MFepKmE1Cpb4cB65QWPYFyqieCwhu71V2yai9Fp9JNcyYVL0fOtErgRx2wfXNa4yKHFS_WZHKO4cV_zMzDoHXhg9mG186Ri2qx8mm1F0tsL91gtcri3rqh1Y4sVEaSOA5tlxoRkhQGxgn-vWgCVmzQ1dJqW4OlNRBSXyuNHyJCxqAy7kDxvGRsU8QWCaoUYBCL5MDB8k8PeVnH3EaHkYTKNTMGER8xjEY5eqkYYnJHtRKJh9KZMyFMtGo-fyriBE1FzAAN-Etcakhh_0jnlaDFgL80-hm78-WFpXqYQyv7t1JEnXbXpRq9y1HXX9oICh0yJgLmD2GGYyFvjZxx__Q5eivggzdnSXtvdRO5fA-jKwBT5NFp2St8yND09jWa1Q4on2mb8llSHA19JNqsd7KZwVNyIl2Pug0SFfw79r6FUEnKkF0l__cNJyu6O-mZVlZ7pzJjrucbtALH6hOjHoAIkCBax3tOcuez9XRxYMM87aNJkCuBMuUEJtuvfVkKk2wHbf-Zk4J2aJ8K5BjuocvGMQLOipsoVFDhbJajpE61-ATUyeLSkHF6ZKi8oSF8zD9RMYEv0fPYBr5IcyDTfLZB2YnEr3ge-EwnhE4oTJJXGCpYmVkR4XtwDB8-hcD_nugmRtpsKk9qKXV90970gY2buVO53MKx9klACbeyRf-11k9Dwfc3XYZ3SuMtw07XdojjmDhzBzW0vQtg0VIv4iWa-YCDynKNBjJiwADI7LDzTL9uWiRLw65iH95XzUKFkyBAmMuV7MSQpi9CXUm_MfrFdMgxE_gs9MraZjsqJQI5DCrU4sdxd2VxzhTC2kzhmtDdpRaR8xThElRZiVHMe3vXq4TRW2p8D3JRzeGpZPkzaaYswcxZRYNSjmq4zruyUVbU7dTIX9mj2rZ3_9F4aIOKT2qoMSzBIBrpmd1YInhTARWvvh0ekfnuq0RxmhUE1YqpH3MoX1nZthwWlpen5pAaNDblnEnC2tj7rA5diy-p59iFkWzV_dO_RN3ylMOMgrOos1J220bCfeq8mTpmECPyqfmZiO-6kzTVuU5Trpkl0ijHijnYdHhznNffDclhzXHqjWq3qYMeqtYAXu8PgfvGWUltSSxmWAus-SCZZCe0edwnuZt8JdjTBw7-q8AR1oMJ38FCmjveZnL5C0JjwQD_GMuJViT5MHxHALGqFJYnZUpaSHV4SkT1OnWcKoivyq1K7SDgqzPV9bpQ7s7xoT8MFWW_ciyJweLmGnODw8JYJqb9vJARXKxC3WSmYomMqMBXC8jdzP-MGrfLs_Y5cFTpUD3xgX0DaeZXvEGAdme7vK0W85eJgYZ-6df9Ot5O-SCxccuQo72FkwEFEM7g0doyAmv13DdFg_xuJx7zjIULF1L0oSncKbmKTPQryiaLfPteA2OVX7Zzcqvto_2K9sHDKCxrHxIBY7co6lef2TfeXcKVZYXcl9h8xOQCveZ_052PaMxSNfSEPopIs3HgnyokYwaLO0tNXOLpcLnj_B7M4Tsy9BaftQTi0swFTMyRj83oFxYx-7FJ2_Ru89Lc1-HCa23KNuTutlrlRvr-tCfLvpOgINRwsOH8vhtCjbSBi5bIhvWgNq65Y6eg3kHNnVbf98y7gYmBq_Imp9HY00Vu1G-_Q15voOVpSkm5zNiBM8FS91LIxgaabSEs2VLI7ebotFuUPJWGFcKG6KjoqGNCt5YPnDf4hEeWRmQBAuCkT0XaLRtK433VJVDbmpas2sDspx4qVmPp8BS22NBv5xinOzGnTavRh6r05MxZA8Y2deED5jz_0Js5P8SeO_srP4S2bLwyIWgxSachyfnl7FjcAsxqh_X5bV2mP7t7Ojn5-A_EIb_BRvF8PBl4LvTJLM1E9gQ_Wnt-BClcePD14Xav7OswBJ0jymvKuRGo6JMVr9cYt7XmzgM4pz4EfjKE3XZuZ99p5a2Ky_Fn_UEQxRjQsMlbSyuxvU43-DyUxFLjaXpMOrCv2Y2prwGzeReH5EcJoDlCsN5SzTccqulVATkJ_qdIOMy4jJUXxF8_pOlx3k5GZsBBVWH49QO6a2HcGjJHYqx7er7kbZKFZ1pUTzOIyEviB56p8y4tZVMRZF25ib8-4vyuo5R7eWV6Sgk0tjLb3qkcP8QDfC3dFyFKzzylB42hLQ_QAvFrrSB3Nn44KC4k1skNNhtqrsGLNHlrjn3uo880qFnoT1zjq6t-kzLOSr55TKnrSgn2ATQL6bj1Yof4GDY1K9IHGnssgL5Yo2OtapapqgPX60_nd-zvkntTgI5n8BlvWEjD11ejIkTlfDD05EUJuvScXKpSv9AVdgbaefhuSf4ra--C1py4JkOCuMjA6zhSxun6HynyAFxim6ZD87nn_1yApZZSJ_6qrOBNu3sKVjsfoC-0sQELmA8gLs_IcGLs_Qd-GUmRlYlV4uT0Q-_3uzaAWl-Ub3q59iGrYjNgbFW2eW9bGk2tlAIuq4Oe1W1MopwNNwzRyp-WHde_FHnsGtZasKGVB2xlTBXYHiw79FYvWFkXhg-1_ASt4yCqfXHZSflYQ0bhLCE5P5VciNH2B7_nN0G4LoSXQOl3_9-xAiJyez25XbkoOrXDWrTZOeGoPkbfFqlHcLa16sZ7HHbF60JpQt5Xgy-C8vCWaJ7JgAnTaM2NkYf_li2or1nl5cRkm6_keMKfZUor-n3KPNpCZCt-OkIAR3JSS64KCxV5A21ynVcWYCFEZpIoWQskBWQpFSniPDVq2Nb0Ph_E3WnF1E4FJa1NFbJF2rj6w2Up2ChsJRHqBHaCac57CgQODM_SIKGdK9fnkbRgwE49UAiGs7dF8RyFN5DEjZhVn7Nr2yrF5X19Bdgr2CoTZD81hNZANvNYQQeoAYkw0_TeYqsZhigsXJer-NI-JnL8Or_NVflAXau2A8t3IxKDb5zj0WW9jKYQ7GxdKB20BBwwuwW_ua4CTlvMBAZ1-1ZUXPEpYKnMwbWaJjrFJsQ2E5HzdCc3n5LdWZ5-ML_QlAfJMOXUgcmDaAjun5zPax_BEFFcYX7JaqJy1OFy0vj2xe0mKBz1OYYMqHYIaG38FzcoZLo7t9TW_w4xI0gKQ438bNZzWyZQPYjr3SmsuzYTT6mTnRjEZS8vDZ4adoE295GNsAMb3iLdX_MhYhCyeQ2UcsYywUUO7UO8lJakf6jmzWyNy_noDgCpTysGdNKdURUDTUBbLc-AYua-OAsipNEmwdcIr-iAx6KK8sKu7uGOMF7OD_oSXRa4tisjbOA0TZemfDy6zAFi-aqd1qb0FRDHOw75H6zve2OCyB4_S21sLfAEfcHiujlZZCHEzyA-jzBGI3tVijjirWNADvh8aKeLU1mBxk7aSRD6kxtlvQFnbh8fEJ6s-0iRakFzueML7rLjDKSo9iytTJXleKrYCgMp7aVlzSqMHhpw4ITD4wk6DeC972Ca-NJOLG4CGT4XR3UTccg8sEM_N_sR5RUtZVrNAi_NYF-qsI3y2Be_m6h8fsNBGk_6zQdsYStIptIkTvLjCSiDJhlgxAd_LeH0_BNBrIUs_5DK8qvCQLSKJBsAMjjilfMyKkkcePCVkrGlun8lDDtCn6g17P77MEROHiZUoc6qSv6inEufn34K13ISjaytjkgguaV3jFhVbqwf4ZoXEj71m5C4k2WZItFQpHZ3rKN3bxDNC3GJ8LOIoHq4N6prJmzY-2AejEOA54Zi8EeHV-uyTMnUOpmNHS_R3YLxQnIFgHXU_l0DgQPfi4F9V_L8x9pZ5-Smw8GyfeOVq4gER6mPC3pvT5-DQR9L1FdJehjC4brDqBWmjNjNl4uTsbXnD1t62mg3etlBpYxaWDe8p2f2w5Q0BlZk5W-U5wKXoymTzk75Bh1QoEzpEfsp0wFmJolzL2DkzFKpxFk8ZQHC3sbqm7R4t8d9M1_RaJpmVrDosaZ0Jvzc9kCTeObWsFKWKhSFh2K6j9-AuDjrcm8V8rdFzLBZ-BeZh1rs1BUD1hAoICRM7edb7hhlXAYRkVTrYuz_a4lzLLNQxYBxStqTB_l36bB0Et9r5s8wkE72ycIggg7jvS7uM2clbCQDXD1eXArMnHwKpMF7vT1JfdBvY7pDFqrr6hxTSgEFcKh1Mpr6pfHmGyrh6RHzY8WZ3K1uy7pwE9MbQyVjrmgYDd-7PMF_Ax_4SvTtdpXVd7B5LgC3KZUFthlksVDAmeXY_MI-JSHXU8N8apneLAb8Q4Z_YpZ9aBw3IO_ca55Qsp1SfBmQzLlfnZNdINqdJNgBArzUy31EGwWPPlhuF6po-O0onqluMb_ys4uZr-diuArIujjiMnB2kPynfXWxAS-C_pDELpiVAKjKOHxDoFZy9lF0wsQV9pLhluL5xbRIb-nw-r8bGmHT6tvQ_vrW6IhsbXA5N1rB8KPAkWBvbZPvIj3h3RfpMbZaIA-gezbWpJvf0U7Y-9aVogZYtHGyZPzxNTJsnhUkNbYd6mUMncXSuT6wUqE-HgGZztpYxbENkPIVGugS9nDdau9DCpJcZOo638MWQ7j_zLV_cBlhrhFuHzx9GqZQsv7VC8zD7WNMLJaZGie3gFIArmrX5EsJ03KB5WDhfHoMrcI4jIw_Jwc2a0kCp3ywoLFSP5kqgxGLvs0PB_amwVxNIr1s_oXTD-DxyGaxYEoqPFYvnxKMbKJ2LVl2Gy6h-uh991gpx3Ce0YPnOVX_4tuZYZcpWE-jTRkgXp_Z4pApYGJO7WF1x_lmjP7XvLqFlsKMkw3rrIes3zruLhwx5quJfmgBQPIqFdewKfLp9wOS94RM4EBmV-Qa9VGmgP7wwrJ9lKHBA2uWhBywoWbeBorllllzSMt4k7HryF70wR8ivovMVbGWQATdeC3xsbOgphgU7xs-Nt_Sp0-21oTTNvm8wn-c0TmMdo59UnGlKa_j7AzTgUJ7S1WuaOv96PaLRl4-wgQxaLBvZbqweO2hpgQozOEHHt7CWgyfiGV7pF17RBgVrCFypwuIuKNAh-iH-FQ_I2ltVRhlnrIFdntFb12pouSIHZaAFZ_uwAiPnxZGW9RQukXQGoRu0KeK8nfKLEoswPLbV5EEr0QB0Drz3p0ZJTRSiNoMHZc84Ot7dcgDa7Xvs_kT-wN4FpbcVLVU2ktBK3XusOe2IdqVPD72z9Wo-6nAI5NuQifmpqobLKCOBwb_nChTOHZ7e4O9zoayN7Ug5eUZArJh06HLjR6V_a7prGAMDJ3OgyQ8QoOq8CDNqPUTd_fOk5_kf7DvXNmorUWPhuLSIDmWbhRUK5JPAwSEBpsFzsZa-V_sHCyCGdNmFxsUYk9_UbHb5A1_LhyGpDgAizi6TdMjyyhyuj_QeY26g9PuMwcwFbH7lQIhEapleAnPS5J826YLCkERhHFbeYhYUXRVx4cBNFCWLV6znErVpIHzYzfYmh41DHaSfbhb-bKJVudJF_NK0WsRISbTDstENA4uQAtI_W-TSp8KFx3n8zaYwKS9JmQUG6WkaZxkTWKahvhZM2KDj-xz7_oONYTnVggCZOl9S18aAHpdnWjYsQdamudhN-URrjOhbxRWi4J9PNaekIGDKdiw6R5sQgAIoPBk2GR97J-UWjcVhseZglpFPnUO2GJkXeTfZ5vtuT2tKzaXZtv3WvAf6xrCwCjVaKcDJp5gROEfFIGLBks6C704am83d_ndUICaKqZgG8gZA4PikbCtlO2a1kVwtZu4pQCUdf3u409Lu6Vu_o8pDnc4KKpnblSpj2MzL62NdgQtq2tHh35fGq1J1bYP9Sk-xADNN1SwAPJVR2JXLUGFrB5aQieMfPRA_wzFSIYG3h568UxfnuW1s2nuf8KIV4fs8W4WGZSOxNLQvYuUhX4Nh-odl7_EtDjsqDa5PiJu2m6PanYHlAb_bK0Avvp9RVBo9neqMrApDCBDYX82gpVzufHRt0lVMBdm-0wKZ4LtSnDWx20gjpcYgdJ14RDlM17qbZ28FlZYXpomTMJQWs3QMXCBd7_VPPU_uKGpTqOS8j0YKyYCzglLIuD5bSk6cTgvfvMnCwUTtWZDXLO9O3IhLqxA-qVx2uUGNG_9gawO16C5w-d_814m3BwH3bpjwZ3JQxmmBStsVrCvGKxAQLFiEtojmZeox5q9FT__y4tVymYrZ8bDe31psCt-L8FBs_ENId3N_qN_kUOAZhaXndbp_fcLHjJJLAx74m8wfIrE4sw6Mg4qLmS9OdWhpPOLi54UxhjyaBdGbLKk76ap-jtZakAhbUcMreP9xv-FKs25Awi4AqZ7TtyUyOa76Srm5zC30cPpSoCIeveWfbYEAxA4AV5IrP3yZKL-FHXdmQ-POXTGF6VZ6OtfcWGyk2txSZQFn-uNWdhzCaUp30HSK3NL8jTNPEB5pF7qlDVR_N3NRSVfxDm7-vkkB0MdDlk-Q_iPEwKmkfzfmOhHbOHDHGN0IhdADhSNO3E1zgnG-xxClxRAJMa-glXuXBIXF2WxJkhzMGm9CcfbTXtLqxpydXg-O4_2U6Xim_7BVi5raF8awTdG689q2A_Cc-zj_Gp22bZ1rkQWj1krUuCGP5oqstZWrQ8PY_xA-OrMoYUxkQHg0eBE0DrBYwl4c_OLncdsQVHUOLrZVrkGHeJU7ccPtTF2MHF984ksCl6S-P6vjPQPByTMbVsvrk9JGsqHNFcZQJpWkShcC9jvmSWuIxvH-9V5ZWDXnXQUgAGiYqzWhDWh6Sh9CcVwcTmTDKmwjMO7tS-9ZAmIPUd_KZ82T7Q9yX4Q6qmRkr1ZZsBW8obt2-s3jRb8k_VQHeTspjPjAg-pUJ9YPWTDs34lzNgJMqEVF2HbNba82G9cfTNSUVwqgynqXnh2GqZRxYg6Dld7yjG6LuIF4J2I47I-iQmEQcvFAGt78PdiFpPbSG-Z32adGMuOrN7YW47HQNJWEH3vL1Fh6V9TuJ5rwknWmeF-V4QQX4McHzcIN8Veud2liTDkYn9iRrsgGkaXQfXMTJPBtVknc3xLtxkZV-qMqRypYqK6D37rtOXSUzfcJcsLxs5W6UpGnGiRDAcnDaeKxEY6J4PlsZG3HfvMzIj1o3uZOOy7ptsl6hgl743bwn4kV_CZBBHwa4Kj_c6Z-Xo9Qj60vbWcXr55mvv8SdmaqWMliCPcR889CHRnOaLaeR7eVEAoha78IHyaNtmgm5dxlew9vNOGGsHNsI25DxOWfk140uz6FYHNj3JYSK7EPMwGh7qLQX5fz2DM4opPzxlDcwCOW9L51UuTiEvAdXrBJ3vaq8v35zsBxDx5BsL_-DyzUiqLp41c2iWVEb_DGhXKHnHyh6F4ubIWDLKXbKpDKyM-OdE5owrF6sb3Z4ZOyMMhPEyxS_FUxKVdGW7PTfyZZn0s1CyHuoSWOCHwhD-KgCs6ihnehPn0asnzzawjThp_tK-prNxRUbs8KbaHQ5XldP7-QwQgz7CZ0r2nw0ZQzKH82DvW46qP8TV5hkNs9IYFXgOWFwxzj8Kmk7Iy5h0VOgPEfQBy5V-pSQ0aMR_aK1pT7I1CPGVAMK6kDqJf2gEqqohMcRSJRup4hMlnZMJldQKk-JT6wYqEHD41wKe9l8thrBLI6OL4Y9iopq9adebYF8hyHRNMfi2xUniNl927n4IDPuybtxqPaNxssgRMD-rmhKLgdNhHjC0gV7e1CJ9EkZNA4Fx7btFCEG-A7L1SqHxSvw1tIUyNEIvbar6GhyTQ0_DkiJCneCtJci_WQIFB5a9LlcLkMryAguh01di8RsEcgHC448-krQWJBv1NwIf37s9FqSQE4UGbdN1pQD1IB5r6khEejknw9H9yPfTHwUEA4h-EF64DImvrV7NWBq9tr1uvk_t2NJKrPUwnsa6MyRgOsfghXFKd1-xOzXqMIivgqn7-a0KDLC_YZ17TPehERcPO7y6gAn7Ffbis3hyNq3G1tm4jRJzVGuRMDqzVjWTnZcJNkOtzI0yRlDPsolKQvX1Le6hEOGX-fpnHjhBIxfeQjv4AUEpHtL6iffRfR8caTuv6KmO28APRITSVRjr2GX898GVdBD1xmCTHmA7_rtwj9HHG0CQRoZDRV5IenpMYlFblrrWe8Og-jzXeSDRtrGmt4MaxdPMDhNWnRjODk4nBILMwE-XvEE_hDHaVhGAGdBDiY_6uMTT1BYnh50GTo_QWo_zP5YS2NATlaLDqD2tBDIdUUR-YmTlnRJf-lLOd4LFodXn3p5iyOFHYJVtHtlZj0qdBNzfBG1kt0EN_JpQZW_TI7xN3LVuqpMn9HwCYqSNaltqv1E3DmBwyO6KI1hlNgfR2EfWJaqun45eKKvFtSWzXg4d1L3HYW2mMElqec3ZUVbowJ1Ew447ijCRT8wYzf5rjRo5vB6PsxgQB-XJB1PCkIGfSYHEjjZoZFvcPD1VV5-0Mjsv1I_VN5q9GDYV_VsrxKZNWV98enQvU-i6OPnhksvgb3bv6MDqDfOCfmb9JoRXq4nRTyVEpKppuz8wJnIwtdIz5N341HKBcOcUvsNrkSeUJoxzXNdyITca7YMf5LiBfkxj1uHVgeJMTo9hYSc7ZnEAucNU1Cpe9AA-ECAodMHhRMLWvMI4mUWM477UlnbxPoSgjmR0NOP---zl7VMaARuMrfM14tKZTQgPeTlj_eTBQ20fyzrURS66rhSRVGElHcTOQ2P41IH3OgGLyyGF-hXHh9i2hqy3EbrhdkxMzvMoOV1c_eqBg24R8RPbASONED8EqpmTxGYB9UF1n2W_eOIMyaQely-8kNqqFo7FZdAu30dEmfz87N4K84Rm5vfiN_ey5hjcbrm24EF7HPCVpPQ75BfvhgBCBn0PersqImXU6ivj0ePY2rZ5zUWIzrdJteKuC4m8v5XLr2regWwuraSPgRoH1Pl1_ktON8WfPKbF5J5Gy-ji6wmyM4k1AIVXiwbt9lMCqJcKPryRAeXNaTyUsXNXOw-MckoR5oZ12Sw0xrqn86Emb-QlOeHijoHKB3M4TCrIweV6ID9TtYQHeeIGyoLzByG-nBm_wqx606BUmqfyjWiFsCuIWngVkoABf_Xgu7fsF8mv2_8Uc1DglhW4ebEDfyncyFaFZCUEcK519fISrqzKRW_Ep2iLpIGQOs-5lz4OiuHJUv30JUFOmj5drhY3MAJmlYp5_3eMMJH44Y1A6qaL5HOkImXDdN6xdHiM27o30wzD5gI48_CQetzv0v1ob6DMlaXmrP1RCzXbsQHidIy51m-8Rezj89Qo6zu1tpleybzdVtYlBlBj1dBcSsqdnRngE7WXycevtXbx4xGIKXoxtwVAVi4FKmjcLs0gWF5Wbu3QZP8eut0XCLwPOJta7TxN4VDcZwoSelquAoEYiKypXhljWzqQAOS1DWatGg1Pt6xsYhPcnBoYgRAa1GKCdc2gzyzjuDco2Zvw9d_nhCELlGfGJgQsa3soksL3EDaX0CcJsgayvFvUJWDB2cr1gTbhf4VUkd1qpQg_n87gCdTiBV829FyS83RsIh-vl1a7xSQYYTH4HJQ_KH9L9vfiaESRhIFoDwI_of6qaCoxniksP2r0nq8fEouvrzXtSSzrQbrByJx3z_YA9kiFLoryClYXsrAkuLtHKR-fK0iwNaPxpP2jXA2IEKhR-vMwe44cwhD89P-2TdsyBwQE9kKXS3H3HHREuKc7lAW0C8gZg5sb-kP1aiI6mLw9T4DfdQtZXHBgjs76BmhFdFtPmTzet3aJE_d--E9ZxG4RE1A6ZYHTtgEBzjwjGcaeGSjRplFBvstHPPIF8odIW3ZH5GaHFHM_0UHlr6iqF0CDo5CKVp7bO-FYwz9xQlD2Y9aTsobSmheuPB__nZRAHtg66q8KnUQC-AFpBtwuD4rO-Figf95zK6lFEMP-6Qt6v8NqnwxZZFsJXGIg6NewWQr9Mf1eyrubgrnw_28IKLorvwPy1m-JcDhhgFmchQZ21bwajAvOLwCqq4p_q7eZHF-S4F1AAB3cSMtBHwDUDIzj0A4FMVV4PgZVods4PL5r7_LON6QVbK3NCYsG8KiI6F1Ufp1QL8jXJx6fHDGWDCqo48L8OfI7yqx3LbfqJoOYbZSbfDykLAjolY-A-96sHKrOSdQgWJv-liuCrbwcZJaBCgJw8EbPRSvQsBfW2fXZtkw6I-6QsuN1mZnG97NWP74KrCu3NiU7Xdlqvv59NIAbirQMeMjLZ1HakZIQR9PPRxTsxwxP_7CoeWukGs05nNOZ6WMX-cyAhR8sLEY6ZwqtYEdTyGPVBbOjVEKqgSp42_2lf9pYFy4LciZI59H07M3zGG8m45g1l8de9UVNrelsH_8hPQIGIrEHvv4r8JaO7bvXs9PqpY34OnNqRgNb3HT44oVhzjBMDoppiWF4bcJ1_fw6PYuqe2pdFt4SxcyBsx3HZ_6IWE84mVyIOO9WT7GmhiiOlQcErp-tcBXt3Nh3_np8Kts-Uwmn0oRwG8eIBnhe-oBJAj6c674g6fzdvuE7QWyxnH3YCQSdPYwwLaSMLyDFGv-9ePt5CJUhJvD1ZDO4rqdYV5CR_OTKHp58nijO-yFA4Zr0xkARkNhPlaxSwrMmj6iHcBS12E4YS_26qG8cUdkPWqmdh2dag_qrbHmkba243yl0GS4mb3hu44opThqOzJtXGtBK57DhUr7kgpK7NfwjiU7qPCyrVo9jcblWggPjBfVo6VwJqYrFXLWbX-NIGAdGbn5iQ_-rexekJzPDcNuX4mJwZo4sLuWv3-_XOUzmpSSO1uKxFlP0fICYeUuDFJDTyq4fanPRJQgZNrjrA88vjZa24goJqYPu5IuVZXYj8xeVMpbPbNBnS2DRbmXsIF0ytHUiQt7q0ZIgS5LdIeStccMP9TDehpzB3QybCZ9kgtCR7l-CasmC-WlBmo0D__82gyy80YHISR6_l49LE_XukiHGg0m4Zdf2NUg5zgaov9LuIpn39U5XwHekxOFXW7GWKOhRnAEMlvtROj0ZS9tSHtSAONH9Xeg6-xLEgRdLLY0njYxufPU-CBWhz5fiqTVr7Ifvl5E-HVZpj1xtwnT6Oq9DluQMxXvTSkBMKXjVm1RXs3uhehq5cSP27VpC-uQPKLHLHLM1-6m0EMwQ7ptUZjGhEiwdynwfsRQa0iUW7S7khfdAhqOCiIsPF7sReuhi1vM9gScBrryo7QP4Gqo5HGSER6ZSFu88bJrCqB3Xjb-KTtcRZJH96IqEC1XnQQGd24iqQCJjbU7ACpGkE45XohPueQ_mVy9Qtueh8RypoFeoUr-KmxVwjDTNaNS9kUHVRxgD5W7CqNDTASvn0WbsE-ouJwe4362ZjosJb6HV381oaLB6ckDIfTmvtQ1dFtCWaOy1ANd6EVIz1-gg0FF0qWVjF3wLz9YOv5rlT-ypSsTCS6VImA75cKi_Su03Kgg-CXSsVvAcW9U4LI7ThG83PFWEl_O9Ck0Z5xyQ9OH6HKx1N_9XU__RCePMCdsBizZBLssM9J5d_cKJ7M0mUI9LZmIIvquAoRYEu1DIi_gSKg6x8ds2twPdF0Mvg6YjFO4kIZRGbkZZZVxfPsTF6kWfaTOp6pD58HG4V4uHy5VsJlczE_KhFZ6YJql4qAlQbRoZT4QXdT9jPzER39UXE91HDCZsA6tVSdPZkLdLF-G33MmEOp_6aZBFIVW84wtOGJASljksVyIV3y1zjlaG3ZlHiuy7_5EYY2yTnVZ6I7_8e4qyk7pVlRP0GfARLfBAUDTrQeW7Govsgwy-8TyhWGd9Hr0z3YX_OxPgmqMkJcV2s4JjykP5ZgwKOWEI2G8KyQB3bZXMa5lv8afh8vPb3gnxbWH9tcJESFuWzwP2DVpCrMmmUZ6esbDKFEbD2JGYtoFWq7-dhJzexUVK228mHs6-WdsGtAshdpb8CrQFxxEybU7P07b8OrhPn6v38kgmay8fOq-lNwfTKf2xH-8NgrxSwhWZxWIKK14jcUIkXcl5_2nm46CPNDVInQAiQAUAfiPuNU-R5v0h_CDKe9s6rr383LEU7DuVn9tbdV3BA6y_-RWr3V180pgSwrbrlOTW7uyiNmAqeq-dLoPxf74C14toPSOF-aCrfdgIaHDE-QuY_r_ZpKQP0qp7vyt-6IIiPF_-TyWgc0VvcvNA_M90E71E7UiLrlXPbg_Hy6sspWXfS7eBmdfrejbn_oKrPttwlHQTSI_P0n7oVSnrC-cM5SRdEV9UDiopvMXhRs6gFKCaw_qV9D4JsBPORcSenEPt2fWK_6rnVQuzM6TnORZFr8SRYIYuTmbaQ4euOdoFBAvGHqcbdACmlRe58DOpf9Mn0XIf3QDgI2PyA6hOTaBv72f63gj0oehZA7rrSh9RGlaHEO1578TWROEAEidDZcfGtCJxCczIQl-7kj8W3HsVyu4pv-nliE7ArnkPhk6pqQR-crqMDxwN99sA1PrdOFpS8xkHn_s19Rp08rjPM5S5AD306KLzFGym_RIgfu3DANuUAtHwmnkqcYHGohxItqn622Yuk5-ZHbXWHRXPXyn88JvrtG9FLFeDsNVIeiSbtk2mZft3Qro-6zuZX3nsPJ1Ni3ZIqdUjFRFsLYrJnZhrEJPSDCpyYtpuKEoOy6HKrzvVYJe0OgGe-t4I75BzY5FBI49eQGf_1ba8kNtTq9zMYqka_1SHxQl0AJBAIbbkC3-illzm_Nqoz7Ve48UF85zCasMKIhO8mNXOHqwkpGpUPrEpjOLkLgCzqBGt-ft0IamWzKSb8PFtgTu6w7HHA5GgOWXcXEPvohgLvT37Q33fK610Cgq08lbk-DCNn9g7NfbtoQ9LBq3MuHwjsmnZdQfaKwEk4z1CT_IinuSNe5iZ8JYLdDMcd_ckuzxAaedVsBcmeBfpVn-2Irw2GYI2Za8LxRvpugHZNJaVM8x-YWNmTNsElXjdUdaa4jcoApMkURbuFYo7pKhxMwxGp047ux2zLribEBQPbvyXsSqoSZD_WtcB4r943Iue95RziVfrgIILD_AvERwMQx1pjdRbJPT6VmY6NFLa9Hdj3SUvChVtmAl1_35fgf_S8GhoAv2IlpLw4xllVoZZ4NBFh-RMcKBhjOaN1e1BwDIHjSJWoQYER4Iokh9rkW9cGSe3CNkJPxFYcYg_xNGbBjMylaQJ5mlBUpCJYMIjkgkc0VRuQ8KH1EfLoiDg17bPiKJOF6cYbyaPTYvFsfFGzpe5tDjSuhpQUWH5Uw2zsz5p5z_DZJwCpnn-wOMrg_bDGTPkcU4wt-KPe2igSRPe0bDENxM6QZWUqKnAU-HxUudU2rFAdjNN5L9MRNnMc8GAdtvpPiDfClsdHfrfsQheC1mWgKDDjoEIqp6T0870q4NHPJ-gwuUTc2WtmGLnuT2HoE4pZK87BeoYmPOIpxtNOfH-opfANYUndtBOwK0z6kWtYUlZ-mjO7n_T3zSTVx0wVlR89y8JdEbijVo0kqJEGvg2eOWj9fkRm25N07I2N2if44YAZ8HEKDXR8gJlBv578NcW9qEq3FHRKkVY3A1-c3mpbK1dNse4G2V4vB5cEDOQBGyrHUw91faFXXbxLfxlBzrC9Sgi9ejzX3Ip5GBUxTRha0ypCy-3hIVhRJ8RbnWJLTeYeiEVV-ujJcK-Izi8Y2O519VCANsZELGGbYYY2TQukjDQrSk_JeP4FlCtO_3UWeAtIJp_IC9OzVKiHDVV4z_y6lr-mpTpln0qVA570MVQHpY1YYz-T14rGxw2C_kZxbnEGgckyYgLmVd0PmPlc4F673AB9arfOZiK8OT8r4Cxl43Uzqq714EC0XnG6iZziQAksQ4tNJfzaOhb_AQ-K-8Iv-v9V01BYvPALVl3-FxSq5xK8kvT-P9ahLsNcv8T-V-W6YivRVTltc44uCth5SUd_0Fu6jr7xwdj77fhNGvNmYxVq4olvTjC0WpHGEM3bFRdwdqQn8Hn6vwpadPz8dIXNEjEspDh2bMgD-asumZT_s0HhOtrklcZfdY2cmz_lw1ek3z2wkrZ5nQC6s3mryerFHHLG5GoEx_475YH6GJzM5l-CSVp5SU4fEYqHzufIhSvkDW-8-OIRn629RiDwCNypxY2Nj396xD_J6GPVLuWUb6dCg4cNvWe9Xw5mmSr5BT0aUGVyYZXItXPAmeDV4LIwWxckObOgOBlA9qcQ7Pyk-wPFukkgVGGtx_z8CLnHUKRtjhDHfD2XQjPAa6IjgZbBnALUHfVJhBItqWAbygBTzrMpFxbX6_z6z6lDKORWXr2l9QLOFJCCMfqMNZnA2funhr9gaoYUgfUF_EWtGysfe8_xIksvFtx2cdo1ky-HyqOZGSpcMRBpXgIYFPPD9ZEvJMZ5PCEptPA6lokMjMWLYnX1m3iNBoGJy3wKAkEFv5fEdckHzXmVthF1axKDreC6XnUmXUY1o7OFmkPPm1vZeOxOo9kvVo8tAvsnFC39bpC4Be9H-iWhGxSOv5tvI8L-SOXOtYOPa__ODbU53ocMTz2p_cnDnaqSUskAAvSFHgkHaNjRGHio4oBIMc_kmwbElP2RJ1bCyI_mByNKuZbk3D6GIAiWE2xX_r-2KSO05mh9kcjulp_FvUOMGTfAcK5qF6lrU5MXhhQtScVd1QEObc6XtKhN_1eYAQju1fy_NON5H-S0FVPSih0MRERZhXHZBTY-MIj4cvYz-o1aZ1hf6DLg9rL6gb56fp5VpPFfGLBHJOiAx_KWeQQWc0Dv47KWQA4l30HXuLiP5reLOc5kTtWs3NCl0Tcm6CxO7VdwH_z21TerDLBicIK96i4uGgwsSYDvkRIb2Rym1W5AKzrn8A1p4_5DCYFcj2LvVzC_KmkRjvvn9Co6a4__gYCYFIjGh4hT2ELp9-qUiC7D_E7jSzBndZ2tYf6oZ1D89xTgWzpZ5sjIH_qOirFlmI18ZXbxL8RCFP0TGe1GPJrv40RIU9cBEMOCy5HkywaOIpLgEIkySNPy63cnIWWr4kMOspwktPWHnRgXuCcRG5_MffNF_wr5z_suMeR49rau08MdG5ibMo-GJkAhOAQLzcDhWOf0q0aPRilt0VtaE9GXuCcXvULVYigM3vWtaEP_Z81pzMpENL648bo2_fqEzfveZ4i5It5Ey8_21uaKHwifuJPW7MorgykMoyBf0fqAc63YRkDIDJLQrNE1Bd_ngfgT6QpDS7zd668o68sjjPGG_nPr6b_0Bk_iMDpk9ITz1XGxr4yz_XXIm9O9brAAhnwfgCiwOpoVvIJNpbi3iqYJc2uGrRPPb49k4FJeqmq1sIL-bMPATFcEyPXuJvDL7ncbRdHT7q_OOqB9QYUOBkXPKo649dW2CFIyO_YdrspQbRx0K830fQa55V2hPaRREoSOpFMjluZqQPeV7fOxroTM_rxr9sHaYlmzuAmpLlr771JRRofJKG8TxG7h88BrK7HCyOQ-mM39YVfmzcluzF49-X7QTet41MbWDxcfpIFQB7ES29VBTSnrp1EHb4VUbjZ_aOIYeoWV5uEqYirseCFTy4PpqMdFV4AlzKC6__WgF39hoGDAK3qsiWphI8yUE9Pp1gDJaUkEKUMwpZE1qPIWplqIi7YAIT7V1kWFm6PfLD1wVDOJL0noTFIJD6wDngP_dN4bB_UbIUX-lygjl3wLc7weowSnmu7QuN459t-jlJuXyv7ENq0m4G2H4lyDvRX5ApIcfIXZp9M7EjmhBZaOcLHAZYq5S4nxuGhwjPUYOIiPTlAHxTHucFcaiJzzNrjiN1yeQtzN6-F-pNYU8KzKSQhhHz_O7fAA2Gngxez747jjtux6dokLcpykqwpIvk5E505ymYxUkM30HglsVJCVJiBcsyiXtZhmWakBixauXORB9xB_zN4coFFusWGX2i6vV1ebJvHapQGJpPBKkMtO_xDnDv968n07kggYyH0g2bO6kEwNf9J0ip3NY2WkORw68D5ZTyixTtstbYyB6H2UHojl1dLvTvSSwCE-nxxZAfFlbfyNjTVhhhGs9LJP2QPYQeuOjyrAk7Es87WSjyGZQpFkTVasR5A-MOQ86_xxN9yeNEFuye4kd_XuhX00ENjKM_NPM4WRBoPhmkUAPbT5paZzlHSDuE1v6_fjHg8qYPf3UhoMESmSXAcjPA_kZgdFWH38QC0poguxpnBmKIejRvdFQWj3CHKFvyjePgPWBdSDFUdmPdZkNws5q8wAiMUgT2YzW9y6mYiy3V59bv3FztPhqp4v8dbXiG_zR84pyL2aHWQ2jVB9CY-nktLIE6rPKoMBF257ul-Nl-DOKzOxcYSTHj7SVTYXb3o8LEuUcL9yOu0v_H8_1cL39iQjMB9U3NdjWx5dhXY-dQA6Tc9gr6npJlPbhScMYjCmFeWi667563nnjeSOdoVzRMhlvhOIRcXEqnpKox3KLhRO1Wdp5CT76PbkTFoBbmbVRrcG5H5fmrEITz7oNYctRikgvOcRE-K6ip_-hd6ch96KlNCkb3yB_PlRBlGGB8X2xvqRt86Yo8a1cWV9hff1k7KTnmOw-UGMqZLDM_MHnXe5DYiPFioEVUW8vC6bwItbN5EVAColBjOuh5K5ESyr3PxsKYxFywW3k5Awc4DFToIi0F6rrxG1Jqo8ZL2Z6DdWsgABsTeeEnIbcdxFbNzaIFT_2XxK8dRg2WnEGLIW6ug-emjNjJG8TIrslUhemhYnbJdwaD-k34LDr5_U_I9EbkQ43qIcvywQrG63A-4pBiA9vwP-uSfo77XyzLshp2U-OzzChsFBT-XCW3kp2RQxRhZpRJwe1EadomGQUcX6vGjDssM7AU3D0rAmvMVvV1vaBeth04fxptk8f7XtS99dAXruPBU6AL3vVuZ_oQxNwoWjbyTaxgVNQB0XcP2UIkphrjlLd-gVkloCWjM9GDXuvFswhZaX9FZ_4_IVp2oYS_fRVd4juv1vkgg6Uyu6Ksppv1tsJT9P7TVNSNKmEUOA--yTXfu1trRgoyQW9vhh78EIuNlXOo5SHouAD_aw9uWeO8X20-4JBVYw3B0MOeNaK97iJjUSLbDxcqfH3sf3yj-S_oeuY7b8sDvLQIJxLe9Ji77MiBuawzB4gXf1PHKVnbHrm4Y0s1yNN8eLDbrix4b_EBCRAWVzC2M0-xq5q-V2_a1V9UVieNTqjqwpugu9WyK8vGC-EnAJkkGvX1AZ7nwFXCtga9K8VdHuthgWOHB2tIXL8-G5uqFQY-c1W2Dhdwzvhe5S-303OAaI-QQrQm1fk2BocpYFGVMx6U92jOpb33QpquYbESxmE95JoDNiAwYt2b11HoqLZAaEF47G2XJW4_J_aC6mECkgckh6mP3c7HZGPjjytCLaKDOV30AETmxbmxcqnk6e6UxSq-rAd5JB6SbfwnCX9ADYSL9bg3ojqxJzZKvopgUZ1H05AgS6h24oLQwWx-e3fddPmLAUH61i0VycE93q4TWBunvjeKaKbSqcxt-XJeLPfeSZqtbPQKnTcpFqiGfGOxhUe-2eTWMjzVJxtKWR8iSx0o4Xkgz1MpJH7ogPRqZUN9R19Z0mbfuTJAd8VJ8IQNDl_EKhY2mfSBCDThpVAbKs_duwfZGHD0ivtgEbdWtVLvhr_GeXyuit5XnxsMoReB7iYS1gOBABPQYreqCZq--DzXBmzlq5fkiIDKGwxSnV8SQgragNlLvJfJVwIamWOnqv4lIVIR1g83jk6fjwathZvVLOAn-FAr4aDl0n1-TSwG4x8fj-QmK4sYjPGRg9vF0iBAhHsemywrvxcn2MBff6NkOecBaf-DPBIE6Bn6oPp1Q78eU50E5uss8EyIOQ_njxP_IGmeeLxRbgZTLpz5Gle-QNb4BolAyUaXDSfoA86uJxgSrAPPTKQvOwiq1ZpA5hLOUz3zfMXiZa5K082QdB_E86eUBXY84cSB_Wkef8HG7sPs5vM3qUBVU7CwkRC_8HbrJrBFxwy7qkdBduIqjnM7VjxCuksVY701DxRRBp1yAL3C2kw1GzJGVu3A66k8nM1D0hccOFCFKkfVqwx54gkXuBMaRZqdcLXJiaqiI0CYt2wN-gUSqtymfWv7fIxRQsH7veiQ0gpRuurH1lWBROIfoxToAmnGPpp7JNqzw6w-WEcKoMKQX4NJjasD8KTwLFNUclDLYMyhUTS4DW9uZ6X4vxI5ClnP3qp53TRb9NXYsacFWTXorQZT4gCuQT6F1avaS_lZ5laaT3J0Am9cGd-91GiUgRZFGHjsLG8YolQoMSO7roshK1LeYHXyVYgxZCd65Y-oIENMPGGDCx1tB1UuC-Rve-1S2wYESE2FYPXpWoLm1RwYHP6r2iMWL8tvEFH1tCC-U8NIcYYBhtgQ-gGR2cXl99gCcr57_2BczW7NVJBuolXtnuB-GbW4TYWLcM8p_2h_vy8A7qchLonjxGqUI5uiSpdlm3Xsfg7SoM4KD0FdDCi_tL_Z7ddggYcVxBjl5wWJsqoM1oPlxZPV9m-MpYxOkr9ME2IgtDirhGzC-9UL0dbMj_jnrsgMR7wiJCJLnL8zNyLNu7BQvpODaoNDQ99PKkwJrdXuXM9INb4-VxTgdZJ_DuvEdc-rVRvy5ZSsui6DSO-DSu4EbNwFpeKnGOcN-OQ_NBrIFa5eypFnsNRssDQk1Kwp28uZsK1rCkYZ8sIs2jgjr7z9T68XwmFXKjgJT5VTXFPUyCchRws2NQ2Ae3VY7Q1xSbuCtMHu74py1E9LK_V4uhmMuUqHXGnz5YGFc6SypXy02qTpz7au_RLx-DHgdqcAbSCGABHYQlQYnI1zQRUKGpro_SlEDjt07Im_B5WBA5A58wyFeQEg3Yw4zHCwsQdUW65rGZCJgfIs1JnaDKDBh-5q9_J8dcAYzW0XbjHWYO3lT4yt5S6K4Zag3TtZhNtcfNPOiiuvSfOaDZUX72jbnRxiobg6spb2773UXS4cCO6uWsg5KZkJuZ8Dp-7tC6htAtifCCFTiF3OiMFCQIidZ6k8PKs2Q2Uen7WkCNUVxJqSW2K1yj3GEJ1kC8yIOCbCRG3Dp37qPkF-BthavQvZzsrxxrx_qEz_ny_DJxzzNQZ5mZb5KTdwxeqHLmf2oKqwHcEijE_23clmo4sEjmsaFy0W60XfcFfGRueteoXYZduK5O7RnTAnBWkQISclxUBdlUcSPo-NLNfcVlyVGw3AlBzkGXqXF155eMSOtwlXHnetn0gNJ9fuZC0VIAR07S_n1IEqweItzrQuJC28cuxhEQYSmw551ewmeneHwztHow6h-N37YjtGI6KwsFJv9D8VsfLd1DjXt91U78gBIecjxuVB7sMPVetPCzPKEoRScvSXC1CYTr75K5fiEvTddQUMTKp--St1YDc4UE3JKAz_bG7VrSNYl-szMsNylCraGqg57bdcUjD8OMzYeJpXAzRm3PezKfky1vgHYO5stFNFdts1UZ4o9pN33KLzVHbZaurz5i0C5BsJLpM6iyIzQyVs94uCpA0rXWeIxbvBOfkg17N1kpQ7xTfGuEJD4vPSjDuvwM-t-K9S-CSlpmTyJDMfHcTcz-nPEwI0WfnF4efOAPRDne4dBrzoWg_9HhCGW1BZDqKiySf3O51hWenWxWCCk85O8zRtTIu6S77yHSWuXUYZEBhUQdwaj4oyvxNfgi0-WCcfSqw18rrqAI2-LJsOgkU-B-0hq4Cj3-k45DYavTkEr2SsKE6djbcM1Fg9Qrx0QlmSHXe-KrP-taN-jYuf2LUH6y-aXP7Xu_RBztVK_l9y0-FA6ltjoTe3yunRtiuGOc5bPdhoNv1oAym_5ez_oIsNynhHZJgVcjkuB7OeBCxil9vUOwIaE0B7kiKRrNKBXZmjrYetj6KUwwHwDBoV8qh_LPckhEYeQEOjpptU0cuo5SuXwhYeiewze20HeKUEivY-wVCIRanWIl1SkKF0reXQnQpLdPUFbTe6D4ekUvMHqYCtO4tfqoFBTQnK-gTjWsvHS_3_6IUWXME7-fSNVH8SHf3KB6mBMYvTm1QI3FLQkHphquPyDFjbTI1bhAHAEaSgaLLydGUjelSvyiZmFmvsJ3v3hWXklf7-rgZfc_Kf9T25LAqDmZmJPrEWVgIZGu9pH0jEAdNCdRWWO6afx8qME1cuiGfVKxA-z9h7beJHTO9uBDj8NCgU6NqGx-5LAUoJuA1c914kNoE0CWgx6neH52ntGuHwbERcCEghL10d5_ySDtJvsqf4IUz-QqLsTlToHKbnERBGfQcstObXpmHD3YqWd7zcFAKI3mTdl5m9_grvRDh8xpF6CkPYJoX5lmHjTGkYvDK0BdwdcDdsGylTae1bt3fcRXfQ9m1LEKhgocABlI-1zpfd7dJqnF94YTRcriHIf0FMRymGLPQtCZPD0EfVBGsmSVHiREThkBHbwM5Y96I-o8ix4fKDDFR5QrLJlE80hNrfRAlOydUdUprSxp2wrxWJsQ3zCj2rIP2q1wpfeCzj9yRNFAZFHMhFlvffVPhDKaMsRy2kGMpkKS7xNA-Oei0cgoG53HUULnA13hzCmhr6mzWm59USpiW95np2xX-wQmbGSypPn-vwOm5ezKqddq8jLm9fbCcObRIvyYM9_aRaZ_VYKYngb5mz8L6vc2Vr8zUw8asO-i6LlN9rqWXmeTVUfd3aQC7K6_y5lEQnFF3_yjIjh_RZsOazhZOv6MSD0gcpJ99ZsGp2wx-GjLaq7_KckrhnzoIfyG379XGX6vpAuuamBe-caBYQ5BfooGTL6e4rDViFHUG1X_0kuzXsJbQiYn0j5XUm-1m8sEEW8WdFzqNXfmTujUOydrVkAK-fr_rTjnUxnPrNX7wHU5-BceH1KW6GRkjLEir9aUBACiBacx6k6yfwkl9RsFiQp35LVUKpN_dN3MV3LmJsgtNTDmaej2to2zZQgJhQVYcvmFANarckiTaUsB_QRiJrU9NoWepRuwRkzO9gIchlyiNHkgB5F2EXDQvXAxqnyjfgaHi4p0WDnMXY-wPloJSZin31c-qF0Kme56Q43fpq-fFzPo1Nwjuv6raIxE9p508zcvzhPLq-bldZ-CDukKbco5A1uRWt-ULhCOU0nFCG1gTKVu1IUi2D5xwvJe0cnPKh_qMVpWeo10xp5s_0b4M68eprB9QOfnwJt4pOUHjKgQEW89RHeMKNn7ThObKAlZPxfGFD3b1qVjPPJkh38nAKHhTsqF8F3qfPJzlf4rfvCbvcVpvN6gc-fzvMzuXU7ntgJ7U_aRw4a4XKc3DuGmf09Pzvk306DfxBjFWk6lgjCqVQ9qfx60uU1dpNP6_rwKAzNL3MLHJXXlrPH9_r4DDWRnaVL26c2fTB53Kz2e5cAHfuOk9SPeDcjnSC54X7r_ULPKVOaq5xbZWVcBoYBVH8fPevB9O2z8k8Ct6oGCCEDmMHOkyhCV6relH7lqDO_NI2teljnlrCxvwXQnp2w6v-De2etTBvpcmqolA_oWIu7QqDYXrthDyt8Tt0UDtIZESFAdKJpnT2dVrUYzIjndcJKjhaisKnBmMYdIw8QdnHiqZ51Y-hT6oEuDGo36EUysPxh5va4lgXG7lM9tHMb9jgopAI_8J-0cJOgiDeTPcXGDMNE-Gyc0o9_2DZULX5vCi57RqP-ItW4xDb0YR1RRUawlRdtDK-U-oXv0p7J5WQtTvgN3gaDrhhxuUBM94zSwGaC8bHa4JK2fjQssPDuh92_Ho4u4OKeM-9MyAFYFABpGqzbg5Yx9hwEijROeF1BAKVNghkLcfEHnxyNadSpB-N5obd2rFm8TVUImygyS3dCKLkmFzQi3srpleIEzCyVhesXamBsmCzz5cL8zeHZxrld95BkcqfAI6cff7G_xmJW8eNBOLoBobD9pBsxt9GSr2MquawQGnqwXOb87ItSk2Z_lyQVL-4WdxL7zOywPbPz6C2qv-QV0HbwL6EToxBnRigw0lwZ4eXJ8EtUUyeabjq5OjYFaGKCOr4aItPpqwb1jYmZ3kF0RSwgDrnnquf0WJN8lZk2H3lNkQC8soJ3h5gede8P6hl02-T8eUfay9A2PKQ3FyXA6Os7UnCUQq22S7TSCVkEkdVmULkok93hx8c4QHfkBYPqss0dDPMRYl1yQpDmuvH9MGekdPVLqsZovZhnw_AFch3-24ESgY61CwGEklUMMcJHv1Cz-7zCr9kRKbbTl2AR03--mA1UoS384B8QL80gw50KxF7n-Tsfikxe_qYV05KwU6rkBFtM1nRBPWzMqO_mA08Aul2S9TiiLKU50lnKhGh9rv5B6duSWFcseGzbk278nhRClCBDAwpJLVvb0VuJ7uZ10haUSR01gYt-2HBD-JIVtYTznHAAdcnPqY6VLE2W0ZOG1K6kyIYK8eISrBiPF1pDQ_6XNX_lnq3ZJ2WvGu-Nljlbtygbzl_5sxxf0n0ieTisy_gPGB4xnafvKIR9cQ_ItKxAzK-4BikB-ArSrMUiwT5Sy2Td1xjTJHhH2JH8Qh69y9S5xK4Wt__eUGM23dYfCMoozKyC_EKBCUkn8mPkKx3Pg36Nn06iO93yhUOg-T8pgwhH_3Xg8eSaYiEygLlmqWFnGJ9nOd3HWBy3AzYGqinKcLaBpTe_d9WXJZSqvRbcR44IaUaknlqaVsS6kp_MlnZMn2G24bnLM7bo2UosmGAIsoWZWpO80tW8vVWJriHTSSylENW9RN4kSmFhJI_T0h8yWErZtMNuKOcBvuQ6vQLo5agqiknuZcBfTfntw6KOe-fU5d79aDxAaatsO3EA00Zd-OFjj1DW6_3LzMHo0FSh8cgj9Emy5d6gHWuIsnG50xTdCApm46QcN3sg-FHZWbxuwaGA_l08vmOIuo8VloT24Qd89IUNDtREwTpTKCqztzNjuqfTrzi4MwP-CXp_UsCF96OJG4IHjd2Nk94zixEM595sBCunE2EA6fgdDz9omptu45kimmdzXkoo_gLh4gaioYyXdthyCCLtoZR7gC9sdwD9b-ixJv3X98ml9-FsW5KlKxs61HS_CipF911Y-olh5gv_pgpbz7Syx2oe8IG25OTRTiEMiNpNKRNbG5drGY7ykjN-lydlxf8stAdR6QewpsbbeJ3SZ6to5jaIpnK0dQbx4tmDWIKuddnQRO8yaSLCuOpRb3olpAbqxnnClFpog8ar8vGJErR7dB9gpIdHen3744HtXYbyam-MS69piWoql7v3PZXgWL7R_ugCcz2XI13TenuupH12RA2oDwD7b77ncbVzNIm_Xpi4YB909XjQYNoaGvhGJtGwUWO7HxoMSkjoQma2-Tvhq4AuoAx94Nreel6xLehSutOOcV7GTlPRJEOeRT4bGGLUhGaDcj5JTENNW2_rdQXBnTSpQGnwUJrqCuW9UDWTHdk_B6HB1qbeBByaBIAJ6xiPBrYhG9D9N8yPGT5UEA9eCygTe5P20n39DJw-JbwDfvk-BmipFZHOwRiAe-04UD2BZNUayObuZa5GLIt7cS_FJSY-_ITKcMAZeTjtOQbULoi9oaAiAoHSG0Ctj9_u9d1OkMzKrDimFHiJsg6362CSqAkbXIOXPKdN1_1bAdsOH6e-4Zp0kgWy2X8kZTyFyKE-BvpZRrqaH_NSyf9ctYNEqFlrVqmvlNVOiKOn1TdaVfy-QFCQ56NEeLhQl2k2iucxupGStMC8l7Len6hwXYvCm8BlQSzNt7PB9KvZCITXa-xQtrO0wv0P0oWuSGA6HbS8Qbi6UFZcO6XuULIP7z3TRZZpa8Qj8mMU2CgRFA3X_5NW-PttHC5JJbjdqmKpVkcbQcoCL9ggCuuz-Zi42eOas8A8UfjUAUpufF9t-h1cT_8-1Zc8f7axJE1bfiRIDq0CWwfQx8dW-5qjUZs80Bk--OVZHPV6xHGRQO2KCYkr0FmjsJ6qnCI7vAZV9Bn8OqDYYHCG0lXIESCN6fcHc1_ZxFVYEUd9unLZiKQ4zkTUeFMZUNxP6ttZ_YyC2uarElZYUIpRjNxwFSfRvNfei57SN99BzkNgqm9lwcdipEoidfe8PdrySaaVlDCEpR4OIuIyyJUALgR4Qnjok0Hy2xsVs-WLvG0od13Mjb9Ui578HWxSnoLk1Y-uaB-VLud663CJywk3r-iAsylRNN_Eq3DNG2j9vnX7c4ankbqDIgQmhHxIkUpSxKldAhOxr0niaiZsW4LIk-RtMJ-_vthdwq3pktt2hPdinAqFtyIhwfqc-kFZlT07PY72wXXOnXoI-uy23LsuXfyKMWqgKUqGMr0ZvzAdmHZTEgMjOilCIM1knSdbuI4Nmnlm3NbdH6hCFsinZWj20QdfBk-JB94zczTsR2oB6WpTeHneP9x8CmiJSws0uu4Gpfq-mxwXlXMTRWaVy-OX7VJQAbnh8ynntPnTcxiDtp-bYBioqAQAO_fejloAtzm4uaVtr4FFTZg43NgJYLzTNTewaCxELQ_f7tTMA5v3kYuCavaptFLWpfrnetDC8SoGZrfZSjtUNpd4aVz1SlW-8sRHHisjrEHkwjyaJk6kgb5cE2_3GFuhW5P7qS4SyyXo2y-jmzdtTJqneQ3VYhVEtLJ-FpIZPsGP0FvIHQJ3RfDJ7NAtU2IB8ApRn3pzKi4Mk1H2kF2ohYEMw86Ixu9SEqd4HUkE1rMnJvFATsSLN7FWXZbhkK1pbppQZHiUguTKcF-7luhIBddNEM3rhMj7sUOGK2zfMDsdqTCkwz6tavjFaxgQfqKn0TsYGW1T0Y5reVR4hdewbKUbsJngrv5sH7gRQX7jSvOiFfxP0gOZbrlIHtiuzFSHUgeUlVWbbkN0cIWS7krHgxTg5WTwDjA6xKn9A4QUBB677u5OA-faNHgogRr9NdAfI6xwxYpU_BlWh8c6Yqrch97OkAVt3zdt1C2J1Bb0fhRnGuzXO6Vit_UBE3wL87kyNhMhkWt-DIfSoHTene3PTKued0DauCJPnXwIOKhhNv9UOK839nMq_yGsr8tXvHKgj5-U8O-JmlDNOwZL3bRwtzSHdUYgEugOmF-gBkrvydcFs0XGEA-H5lpVqWPIuOv0DBHwkv_YOBy_RAVeIY4PZjwZ_1IOhXBv4NxgQAcBGkGPLiMHGiHVSK9p96hmnyw28pdVZK4veuH655P8G_0HBURyG1qsSUdlE9wmGSRpBQaps-v6IBWJZNfLtAZ5eydPm7Zk_cNWkhf8guEYtUB9uElD2lTAiJcmtUY5VNDzwgmFRedWr_JyLzsHLnJeJHgVKAKf67sXNu8vvZ5bNMTBInrGy9WDxRnicbA7e6dP79twTOPHFcLvkc6Y4ZwTaLqXaI4Qe3jXQ-7EFSCiUYdT_UF5xKAtTlrkDsNSOtI4t_FyZzg1Um3Gp1LAVB2XZD4SWjL2C4lzSxWGKOiRENil3tqv3psZoAdYNwa5rpicbCQHVD-QgdgzjwmMKT6CBgNztM_kvx7hXCNAoa9lM6mEMKSFX-O0ErBzBGBh-0vgnwrcXxyndneYBbs1RHIvszI9NX40Cq-A8HT1I6kmPuakkysSkbIUmzBXKA_7XyEJBSV2V-Xp6FDLFvtKgM1bjkPDifCoOrx3dZW4NHS3eKm258N_kbou45xwUiOu9UOaf-L7YzRfyQzavn7lk0YVGOAEZwHYN2F6GEWZYi6M-nCF-IA3km_UA3C_JpmNr5BP7VCT1BqlLFwVOs7uscYZ2UkAvvKXfjdJ3sd9CCefyX_HmC6cOMhfJ63Z4qkIDj_C9Ft7mXrhQ20sSfKwaqu4TKWxGvIKY7rQlRWS1LvY0iw8emlB7dRBbq3bNwIH9Tf-SWfAajMwmWQAuRixtFPnPzB4lRu6ExlKM7fPi8R_7gu7947f9xbAZ5siuMK2W4hFATzUv1vgxNTpUP6vm6UHMuq0KF5H72M2mdTr4LBaEB-biVRuMTHCHe9LDgXXYtMj-b_0N6rdu01ZT3QtYij4_T7tOiV-B3R3ws8Bmv5NSaGIcSkyQ07_A0CWTGu1NIZelrlDdHNgAaW0JDU9N-konyPaApRDXttgExuGlS6AxWLCYJV5mubqE9x1TarvXpH-cMNafLSeY4ugtfZy7M8ySxTNAeOQwtuEGupM84gyBCSUI2MgS1kA-Ef71mxEU8KhWMDwPI7Z2PyVx19Ou6JC1ewB41ZPZu6SnAo9xHjbNoU5cO0yY2dIWPBzCc1r9iHSzf8gwmkPwY2MKBwrGv706RTI2ztZCyBRGPJIPhKqoLJdt8aQ1RcosPu0jGO1-d59jeKMDL34IImvhhvNjqcZkNBxzv-b_AZIMMHWRZgSyU5yuvCwifI97ShtX__EaNuncT7rc-reFxarlkfYg4rYvW7bD2v_JwFPMfv5X3A8V3iof5IQGhRSZref_rSkNxh_C3xWD1Gx3FIwAaIF0BRmHxC8OtghtIzrsNP8mBiYy6UUHoQVDHtFxuvBXsZAqfDK7ceucXC0za3I3NO61_JV2YWPa0hD3fnHZJ9Lepa-Ji7ZkGjbFGn8UpD5BNwYP6yn23MyehZOQKCd6vGCgNir1yHnm0wffcKt7niVSTWDxMCo0zuNAo4kKKUDFN1v1K94LRY5WYzt-Nkcmv3VPiZFvqmNhahNCt_1ZNTdkVpWD81vAqxNWHCrs8N5prjwQPic7H4YTS2BOapH7wY-qumeGUXidCgXzxrzvXAy-HlGv17vT_TG93G3nh18_1fG_7mGm43oskmsB48RRZ9ywBkQ2N9p3miYw_pm1eYbUmqDSLBCXTjcohUi4-e0l0ct9KEm07ZpdkLenmNGD5tsiWco0fgWC4Nc7JgAMlj1p21eD1WH9_q4xhB-Wdcaj0teGC8DW9KI8UahgEgjUpKSdetuMdFyEkpNdhmmsFcNFjbOLYMp-aR5mMjviKxTd3d7n_mpycv81_ZQcadHh25pXwKAXRIkzTesryxZs8Eq3S4oct2SdsXfLnMmwpZWv5R5dyGDPtdUYSOKjVA2IVJdKW_VRq_VNXMGIvs8rdZfg50HFZlCpP_R7rXXFdLxsl0UL0ePU9YbPe4_y6ruGf_eXFgzh0Osd9Mk-suSz0qAz-_4SU2B5YgLJ9rBI3hcfDcnXi_fUOeHEEP7fUTXDS-axjrvSsRHc9yn-Tyq3a3pk3kzBaFqvcVvz9C99z822T4tYdDuspBy3hHFaYM1e5gcWJNeoRwyGLr_g3W-qkZ0-5xcE5ppILAtrZePaNLynIpLh1DHR6FqVFr76izURSbR0RhZgSj4k_ZkcR0PVw8MJ58p7bWXLkO7IeTdHfC_c_81qYLzN7AUIdxB79DKrg1l9tGpL6-JFGlLbUTT2DA_7cAyVsMdJCb1ibe1JVeiTf53VWg5H1sT9vxmvLl-57u7oCGHAYEtftaMH8jvcQMVKKmDXLgLUN8AUNJNNGJE18LNgGKnEaOIRK9Xlunk_LSElu7xLqHH-r-W-t41-kuyoNFhHjOo-jUM7bG0_0N98gfLgMhDAOAMm5fwoY_0fYUEH8TiqKxql3zqIA-UUOOdxTq-RTslIKnwUif5XPJdBMazVI2b_jr8TUndbKgN3TrPdhZjiIlRf35hYtJjR1GQYtGZTcrX_rRtlLTytn1JaLukQpQgK1Q16zQ4qcPqY4IKE0NCPgnCP45S7mZuQNfMY3oaQHgw2nkdRrDOqIQhYB4-Bw_OfGFv8OZ15kUtIvETkJRuXG1XJpFXh9F90KpjtjowSiXIEgu_oFmfYHjeSvACxPgkwmcA409BjwOx24Y2R3py504w6MY_-Ildc-99kj5rpbuH06Z7l9eu-zaWGU_3ihyqSw-YY2lF3IdkPsVrWdxDQO9MiilOSso2b0QwmQ4XdWB2Eu8BKuP7DPvVWuc3gyD3C6vU2I_QLpDytH7U4JYCfkHIRTpGu7b38TY5kWtLYutdWrKb3Jl6Fg9cQFij_k2MbDJa3doKHhsgA0HkoixQtMQ1sEL_WuC23XZOt8IFCJ8tB34IJIJj1X84CvBtbtlbW2Y9mywoQZ6SkScuhzcrZ1N3Rbu_SIVtT6WDBBBtvqNES15A88qVufMuPe_Y3Y7DKzeL2l9CP3LVOU0niprFvfSHJA6bPug1aJ3d1eIK5p0NalJcpNRskUCtvdwoF1LvuyVHDETP4x4-q3C1iZDHY2mSaIlcRGuqX00KCI_zInrFk_H8eRcXV4S7BD9Dqsd79N9-w-8ZRcWdc7sAqbZg78_m6G_zXNkt2uA137i7n8DbTZDcr2MIJL4o_IOKtWW8AWtuXSwYFxYtgdcoiJgpzoaQCkqJBGT4-9rNYgNJAiB26L2MTFKf-wOZmtjV5oqh1cZfIHfz6IWWB5dTdLnIb56HEmZoUIF_g3ISMOwihl6FXObkC-oFKwhZzhpx3NoU8pfJwr617md-cOQBN79yWeoe97aWYQGAt89I886wl2FKrVEOZV58Hhd6Ge8wsdLB_jT4jKIUqqoUPxME_tjpDOhGjDTwodzpzO2ZnpeEFWD0eMVJ8DuixQs9o8SCiJ_kqOKJtHwyBHPY79yTJwihGsgHHwAzJBKpsh4gOp2cIu3CqUy0qOl96QjL86UJZj3RTTj789pzMN8dg1YujGpAWj29Nt9F9DJgp50rdrzKdEcmo6JoqI7vxw1JYvrvLQ0oo-hCIH24NNF3AScwlJ-XIu3YxQyewdjNhkaBsPjj-AP9bClTk8WGlsKwTZbe1mtkTzufL3FWdZy6eaeN_g2qa_uhTYNL6okx2A4fYcn6QB8Khf6i7bO3NhiYiJFfyFgxrXaJUAqJFSOmc85WZipOMHufhSTsemjHwa-Em38C67rl_tq3SqwvQHxhtWIeMU174fdqjBD_lNcKOLc9rxOygolVrUJ3bjkcGQL0y2OwzzkzJlp8oMhsBGXPkNkf9TwFvHqCjRv1419M1tb8GSsp7dEg-Qdtxe8XLsZBnYqEEHXMu8Li92drhtNVpNgR_xs_wbhgawz4w5Q-fZLfDysfn0srd2yIZKYtj6-hhzD8YbdU8zOXPOegEjEdMp_-_KtadnMS9SgMT_KXHE_J_HPjXCUvuc2363xQOQJkFxpmRvnqPtfbIuogiwVMoLp3rG2qpMgl35Z2EfWjnxU-YUcQ1PQerJ-4glxxErDeMnZ2DJPpzwSTiZ8yfTnXROCqFJJNXjrEdioNCAsP0VBiZ7MpNbqvJVZ0opqQpOIEBQqjj3mQ4lrZTZVrALNo29JSfUN1DaE5k_DIIpbE6tcqwN7aPJu9VkYveaFciolPSSvEUmXuO5ZnQXEcbOhpf1dzA06o_GDhuzqudxwluc9svgu_IpMbglHIBjA6q360CXii4NucSmTc3kUiEQo4-3vPCCYWJKBoJxxAfKuEj6PA6tYZhDjdhh6mKHAQJULFNLu8N5PUlH14OV--MdWcVCHfIxMJ_QRaOwZKM8ric7sSeHFc_IDhx24mgpKZQqyoRTBr5pTTUM5a4x350DMd0ZR2sn7TIuWDJw8dmdcZ5TWsxzx-CNRoLE8yQHSCbkMT1P92hBmeV6eOqeoDhXHl9qTdkBahIrCmhTE0hb4C9sWhvyqK0mmWWr8-F8L7StNYhWTTYgP7FDqHOdmW9gnycn6wHY5WLufX3thBRzbCPfz2UbSf9tl6Px4qvMtY6D93-ARtSixK98P0eGX9FbrdIkoe5JsNE96CU3aeW9P2iO6TZm5FZimtHJRhe9k-1zfpWPoWeakq1F1enHJkKRCYBHir9TxQVsXKkAi-rJ8d1ngzOK4jxT-fPdDORLNNiKYWEC2iIVqPHNhNCQoE8X83wLmltR0wHBZbv64AOQOcMumFdXtViqUqseP1u_vREAIvdGuTI7-ptaNS1yVPSQasQ7Ax40LtdWpp4WzxTZPUDat317oaPOgm4y_Q_46iwIk4tffwbMbEHp82WUNRCayB_jG1khb31tlYqqfGJeRzsYjb1J5V0Md1HlN1E40PZaFKso5AQHuL3FkHnYYNJ7y9qos8QYQAzQq62UI5APbel_zbLeRoUxyTrCwa-xuDBNrCVtsSAOz_n52MKxxKdTUl9p4S_M-FdoozDZa9Jcbi6vEdrYfCYX42M863hhd8vp74N1f6qFoFFFF80aB7zwcjFgQYzHwjVAUObAx9TTfg18BPQTS02MHZJ2JpGrad2DrhdXJtvVkr8FM4BdfZ0Cutcwu_V8NyGEnIk7qkEH78naeXDmryPbSk04ePjGvJpwQUhkcm1dAsz8aBAStBY4sHhoxThMAy8FWi7YiNvXSUGA4wiUegXSHUQ9dzHZoFyQFvcvGOMVfrcEzid0vTQso5aqFQKfz1HzfUAgVCGLqvfBaEPRAwVyKTtCQ3VUw-NcMGfhEAdxsP3Dw7isRsCx_ybgx5dJScP0PJX0-EAndm6gwzkyB6LWwFE6mG-YacgvqqK33U_TrhxNjtCpFVChjRLXnDBLVdCGJtUTm_G41HY3pbznNngffK5QDO9Ojo-TizcM7p7JBqTcO2dwIBNBkOzHF6fSVPn7_ruJ6QtMB8CgPW5glBWbTnBo7JcDLRX4nPqfswfldJqAacB-7wtT2UHQPwpIbfrPEKv5WB8ZU-l8EYYW4Yd-p4X_YSP2MqLbTvp8hqyC8uIK-VUtPQliJF3T5RtScl9hNug_odxIpzlwTt-BjNCz-sh9gz6PJhGFYULmWkCuFK3hlnipo7Vb2U5e5Ksl1-wVT47BVSn0__EgYBy6olDGbC7c8ZJH9WuD2-UwNl3eLGm_IcjE-yQoy2tfv-1dghY3-cUJlCux6vdNh1wEJ0tZ7DQavxh38Lkupwag_Xo0ZiXizFQ-GO2XR_I8eMj4U6lb-6f8j7k0Qa-ORR2ihD-MOOUg1phCyTxMQFJUaXFFtT2jxBn3NK_Oo7EzcsJTlb24bMGGO95LF-OM7nhd88H5Ptqzk3Wvnj0l0wnJJNxaCxlyylUe4HM7EHy4WNFhxLKAur4emCiklsB8GSLCd3U4OK4m1c8EK5W800xFbet6ZERY8ch1_T-h2evixiyyTehhIlTWtTFWUWUzxlG5_x6sZUjsworFzZrJi4kC2O1ozQgl9O2A4Rjkm9752lyqTioHeQGgCWEH0Zbuu-vpUe8D1Qpsezog_wjHHr-YSIbdb189aB_0c5GtfZrOkC-yDdS3FBz6UQmKh1i63SAebpomymuznRJwsv-8UGMPr_XEX2D6WeVP3ijebA5OFlExtvj7sRpmPeTSsQWqH4rDuhtRG569gzgyrKNHY2ntpG9aKwdrtIpq5DLHTJiY_DK-hFRPLcU86UianzTcUu8-q3SHNgyTsQBtIQERscvc8sI5sdbeTswxLRU7m5mfa4qn3SQpApcK4JyHuak8gL8AGbBQdTW_2_Mwj3VGwWZBFzMDOwg5qQv8Cc0fEADqjdm_Of-JwQcwlOFs-g-j4NPY4ZE3dtukH3vPFro-HQcc_g2ph7bQDgK3ZfAUEvRf0qBL_V2tn24hDMw1jljiLAXR5wWE7YaCj9S97Pbn47Uu8auqLsN617uKvKxZ76qvKkdDhyNdJeQ2xTw1dd1aoS_97PcLp4aCwDkZm5TzpkOyaTi54VHCfbZEoUkh5_l2J8Nze6QiJgohTktxExhHwEz8qcdD61iU5pb4MrDaPd5tntaW0Otq52ng9vIG_EjcqvCX_kHQ3bhPmJeXAaneH4hU_qRVbFUUXSwvf5M3QTlM-fH-nK6KX5jniQaxM6qE8aXy59idqTCmcZYMZSZ_kogvCOWUpCqxAzGRViGPhZKTp_Nbjy5R7yyororcq8xd9ugB1AXHSjohhaXnZNiASFiM0MikzA8JuIcYFQaFLQkIIOaWBUIRRDjlO1DqlPpPAf2qWS-f7aT5iICDWeJtKxsYSPzJS8r-3McveKvccZwuVlbTT9db73UO0SKPtnUZROhP1nS69DROvbIpXylvEf4hoO1JyBuwCt_1CdbQ6iUfRqLZ-5wJlC5HeJg0FEKkTJe1jJ1l4cSvZNdlsWCg-ls1tRO9EkuVYMiM7G7Vwc7L1mYN0yrCpA18PBC0Uh5WN5J1KdDa-vR9CMryKduK7gMh-W7PF1fghp2XdMOVPmI-sMVmDUI1tKGX73c4c5yw5KAj0BXDNJVodlRvqjoVVRojcZgd8fmuZCPS6Ub4douflYnJ6LjbHXR6emUv3kWg2sqbYx--yXEl_105PpPfPcJxjQ3MqCbD3tYnVJGGRxC-eZO0e7qfg6wRW9PiQbkuGVsbgpd5jS9OnXdK5VPXZgurhMlSsCMUC2uj6LKth49hP5qBaMXoNX1uWJITsZbdTjcXuL6errjlWGgXuPxlpF-tiwXWiXkWmvtKvrtlV__x2OcCWB_1J3rgDm6jWko-p6NSCZztvsoRm3bEGaymSAz2KHwW4-zxwMbROPkSgf64H9B-lIqeoQJny52XLpilMoqba6dlIxlfr29E-oGck10r61gvaMB8wF73sVYVHlrZ8shOE2wMFxolHq1f0KRGkqAT7N7-LJ6QOJq1vJxrZSWKpvxVAMMBaojPD50LtO4BDZ_4Ftdqcpo9I3uUcexHwN1V1JS8e_dPf2J8qy7A7388m1JBihURMhN00Aw-ykoHN_gRwvP0ltruyfbz3BzqkapR3rMBdRgXrpjU6m2AwYr-fBHANymjqe8i0IE03ST7LENCgLtxJk4zUCnzCymfzt990cej5hrzApSWHPooVbl5pxM8TzlKbIYH4BIiy_FaF11vbZTek6fUh5_qICW4pMcjebzQgg5VB_8f4Pe_cZbHpDqODaelBgCXtQsTyluE8GzrymDbVjQr_M7dEHaHsp8bGJOKPIhNabzF2Fx4H7eZJIGt4FMfaulKxf2rUtnNNEm8jZNorAvT_Bs0xmeWc6eWrzOAW-FA2bKoNOJgAjYhTdOdlUZt-lH985uZJAlsMkXUu0b2mqFUFXlgUxCNWp4yUPlxq_L0woNPHWgYZW3nZiWsgjVsCj4tjAHdu-ZGo1xeNcQ4XKql-ErvKHrbsvEAd7DxXUn_41Nic5o0iHydccsMaNf2SD67j7ylJLhHCnmAiWtWEDpoeRYfx4ArepWvHlcOZGlmB5vIGhqIiLtkzG4_Vf1DUYGgrTuhzu99bSnqYLzhfwBDRuN7u3dfX3m1bxnwEz_5A1_jARKZEviX-BTvIwBvSZOEUOnhl0yvEeIHaVZ3iN7wEf-YQdxiqM_jXbYaAmQpFgPpGqmr-hsoFpr3iKcbCMNy2n35ds_ycYEpyWw59hwj5gEVXQmD5_7LyzOGsOlYgAPAIKP9ASi28yxivGzvnaX0q4bEqdL0e9jCti0M5zG4ZVEjWevgFDGfxJCmVIIavQqeSGTPQP7SM5YGI-9G1Ne6mRao9_4Ve-3RnAG2B0wbopjEounpciUelY_J0TOCIGNEh2eXNhAXgkkgX3eU-oEE_82CzG6n9-Tb7FucU6spC13SVgrLZe3ByOF_s8SU9PEv3LO-6OmpLPZij6b51_A-vqQnX8wQ0NCH103Qg7R8rOGo7YvZwkm8EcuMpZIGQqKN2RlMie26plFCwPOBGzEKekWra4XkAwJqp2Dd5qhEDnCCK0imZDFeYf_qprgW-chjW0-iceCF0mFFlLkfYrfQQ5bOemWaqHJSwSto7lF-VZ3bBHngCj2kfLjxdfiWUZrqnrObXGC1TTuy8pO5rbapJtXNbmQB0TyTZOOWpGDmLO5_vgb3WI4hBaZAEc5nbSeHf25-fJT0QfEVQsvvu4-5CsmuKtjH5Z--LnzK41Bk9gOf-AeVup3DczoWI4LtIsfmoEsXCCD3bbcDkxvykWJ0af1X2ghEYIi-T3Bux5ZW0yJM5NGQlL_v3nD9xZQ_VWX4P8Pfzz4aqgwZ-I_jqyGMMeJ7IDaN2zgPsH_CO-p5V4Fui8wwSBWu9nagsIXFtalww0fSHyc0gHrV18EK14P6VVRJO339ws0yomc4j2-_K_s4bRcbnFRhxCXqwIpS99bnRUDjXAyat5xASLhKBsaHqUCOXBO-iW7nEMiLsZpWNOABWhwE-4HHseJqKLlvaHhHSeRQp77qm1A3EUfB4hI-2mD1fff4d_GOTU2fKXGbSwdfB8UBrHB9bTd_2xQv0Rv-Z-8yxnvaamx1qogDDBQjagxz0l3eUtjT2CUg0qWW8BIGI-3bArjJwUoroKhshgwhinSEq7PqG3uKGY8lWBhubUkD8yujFKEV1NWHWG4aoDoNiXKvaCPro92UHan4Sc4E3BwNdAfSp0TaZFo9BM2b010HPA6PQMZS__VTdMRZvQhW2B9eaYhDSjMh9tZ-l3a-gqQFXrIKtL0d_ipRgn15qZEdRmRu5Tcj3q5Ls-zzArhjkj2J66XskfaR-XrJM0KX1gMHsroxLHQfv2St9vKqr6FGuNFHQouXPLbOI9ED71-RjUX-x6Ntvucz_OKACTlt86gFT7bH1baaLW-h580NZUm2QoMl8RferABUh96jbw35O782dVR-EG48Wj8A2flkE4tQX-onsGdfC41tdhNFh0bO6ltJUPNre2e5XIgYLfKY2OlJtRFbMbXOhcum53qkLFBt4BYQPIJ8I2oM9RPntDimezN7hfDkiaHL0bIF2ZvQxvXqBUZpZO6545nK0M1fZZsQgCqKH718XmxU8hXa5TKKGlytYuOBquiNM7DKWTTpi2wGMC1nO-HPJrDJN8fz8bKVjuGysSKbmZga_uozh-82h1l2Wh_Up67wPhesQMAzelmfUUJ1gpyqiRZfcO2Qncwg5eg8CmbB2xj1SeSrl_uvJxhIUbjjlkZzi85AoE_qG_zHsvYpx3TzN_sGCSmyLWk8UnWs7gioLJama89nO2rBpvn-5AqLKComj5jrnSmQ5E5jWpQR2GATY0QrauSvrApRovs8LGdPyOZNwXaKQAwFEzqx2c6Ad26VWzkSkdG9dyNQur3yYYfy_qybAswUALNX9kjmUVFPwC8b-iOvjNP6x2ckC1mcYmPqOBmvEkphMuYrI8yCsjchmpdYySqUrQ9wDw2roEtTGkxVkJrDgKb6naAJbO1NkLIM9-wdauyxtbRUaDBdznQgzYcyNggHlhLho8pBkZsqVhjzbO8GYvFKrJTp5iZIxB5YXUtefTjWt7YOgxXFBbFK09LnHRRPIM0xDngb5R3ccLTHE1OWqpVIw58Jtn8gutxT0C3Jdo9I4T6YRwzdB-08vH6c14q9mdccmbYngYeUmFF3K9dqFgKxGJgN4YiXGrLJxUtpMFFrnRDRQbRRQSAK1D-ZgfWlCe9giFlMNYaqU-jMaC5T4vIL5NLFCByBuN6Gcb9Wy8QLOzL7DS94d4BXURcFb2xz39znchCPXfE9TVKJAV2v047b56AJ1U52rnwcLc6hd0hDfI26uw46q-CFqmg4_foVXgcAGTstXgfW-soOY9h9wlTg6lqpAD2l0Pj3pi-7wbI5-33ClJUuwADworKwpx4lF987WBkZogc5nUy_HsAL8FglsZ76lIMx9Kz3FD-w9-mkMtsSZ1vQWQ1_yNEckcc5krk85g1uk2Evh0Hmu59zluKsIiRcqTAd09vNxcRKUpAkFk6GBQSRV2CK_1vlDnY8qW-mIVQ3nADz_HgKsAlpq1WsG4C_zN7uoyCrJ6lMrcfjHoSHGRqxNyA5Y7VjfkLjOLwQIOSZ4eVhsajI10T-xkDc9DZQ9ClnUClakxAVQSBdHVHlDt6lCpfGEFmKtwmCmu3o8HBTv_xkgFJAyA4wmu7JTTTqkbLfnoE_OIe4ZdXC5_FOUuSQApPHBZj4azd3oDIgkyrMqX9BhW8Dwgsduyzq1uBQH1Pm71e6EXDnaEk9TqYg-_Q6oNkmFtHcg3hwoIWJ0bjZ4yQo1CHbjmIQ2S5bRyBPoLZLAjdVy7grYpnuVRvcFoHp8JGdI5l_z1hSxqYpi-k7ZzOJzzR9cw8F_UBB65fCtyLCM6mGE3_hUgXb1CgztB2rsPAt4pKTJ5mHGmNBQP9AZF0PL9Ccnezt2FJcT2KhIqx_jRMLhtb6wqW1nlXyRHHDrl_OX-AZBMDA4Zm8oBvTmfXUE32ByFqJLPom_F8zjFPJ6yTDMUTzwANJVVdISKZU_w5Z8t5DBJTnusZz9ELQG1NUYjQhy0Ltaiw3Py26tTrvBnIdjJgnH10LOoPTGV7txwkXgfDSiZGzXvScD24oLlcP51GvdgfH6mvGroPwyLL9gLMVyph53OkzgDzSW4TiBIqj84ie7u299Zr5-8XBwS0E4QscBQk5kytn5cfl_EEpL6CFvJ4906VSR0sWF3WH0QPzsOPSu-9FvHmmc7lbo5HHv4ewKQedZxsTokstsbJ_rBagjPvtwKLESvqiVIPt4ZA6K8W9G8qQfNbtQVcR0aDKbEhoPVJ5pneeTbE0R97zaKjFvoJClZZi6j0GN0BgV-rGfJL2BMmcN4VgEi6bmJf_h8x-xZt0Aomqj0m26ILm3FdGlVoUo6S4fbiyVKAtzU3NKzgtGkiDf2EoGfvoZuhO2HW6EiIAXlkMXqAwPIVXTb2qivdLGe4SS_aR0SWje99daPUB0A6wW7N4_XxRMXm6opW5UA6t8WVmYDUBnB9C2_oVps2tenanwHqJhO7QIX701p-vDzy0tlcq7oIjU4lvKre85md_Gm4hw8lr4MwJfqHsy7uKQT8kVPt5suiodkBvdsGGIHFMtjSJIvGsiRrgQr8bElnzdXD0m5RfSg8Nhy-TzmiMjmE5tqAV18jnFYFtMGQgE4vVVzW3hTKIe5NPq7bhN_Rq0zKTOmTOMaQflB7VaByb0fCpjzI3foI_gWZJ2KDuSXKEce8FJm7GQ3QzPftH2itZILiU5j8_w0xkaQN4uu67pxBa06HM1JjA4GH3NNb33opTrUNE1Rs0JnWr0FKRwsppUFryRJV1q-acsxBz-i9i97ArC-gJ16K13Tl8hIB6Xgq0mZryP4W6-EhhtCioLeIy9sibd8w8co_3His3oLOYAJOKMEmXstLv_5cVSbPNyp7JZ0UxbvJJA77hbs81wHR_WhEP_eL0ReJN34W78kjxCdl0uGN4rasI1Eb5xsi71CS4Ri3tKJlNcjyb3CzdCl3tEQGxeoWafJvBBrazYHoc6qrAE9iuUb283gnkGQh88LdpoMlGSLLsjsZKi95U1Mi14JT5tDsZnKSmhxbifq1XPZuxSsGf-vjyxMLNQIhYvqSnREqbDz6sLrxU05DXl-jHkwEPfUDdPJhvs-FCgMJ5uizx6Po7C1IsOjqDw4LAqH5zMRUAPe_hXBs7ocZ3A6DdPkRwdtVYdJG7rtCsGDr5rLrOopHVUJhsnNnM1frHQSxp2-T7hoESJ4cR4g-KkctmcQj8AFmpYqt2FkAxvnYKP95_OVcKC5hCWTg38R0GiEuPTSyYeAQnVGRXsgetmmzXPgSfPIN1G9UdCo5NAzMh4okl2TfHKB2VRhl30Bi0yTHoqGjAJpdane8891Fe1id8m5KjkoOrUPrlbkJmAFsQUrKeSWKCZT0Dksg9wBP46Jzi3W6uioy9P0qDjM_CKQMRN2IDk9NoAfDkvCLixHfcQFkh9SNtL_CrXdHpZ-z75guX_TNQFiL-Ix0kTf5Le87Tr5WI2MpX2OJCCSJju2Loj93g-Zt5VEfb4CQ6sgaVHHpBkCvHYJ_Qw6TDyqZwIJ4GIIAGETpcq4O6WMAGYXS72g2qs71bnoDpolh5i9SF1aaCToXw-7HuAIvuzV3845ywpO4ZCV1lAXbMgfIzSnCytJJ_18IVKEN3ENAGovjTf1IbaUJZO0uWkoiF5CxDKEzmg7f1SA5-QD1HzxeyIG0de6DSpcgjQO3b6fi_i8uvew_ZiNTjOsQRbRBYsazx_yPE6fIrijXZbmZSOwUVWgu8tTJ_rnsgbRgpb8YLzZ1KbLFI8I6G-6o-9TtJjg2dkE1LCV9YKGeKoueGgWeWmWim8l9zuZD9sDirXuMWU8wUtec5KS934SpjbAW5pCTOV8LZHRY-J-gE7i7lv5ZByvAgJc0JH-lygeL5kKlQIB5E2ULYLsd75VG1lSCtG-wbYfimc8dHD03cHvDz1hoHsVhiPpdCmMVUS6ebL2eQ2i4dfbRK9qHEiqiNBCWXOpkrikL2IFdgMnFS4mKwqxbOmRhtW-I7iC2RLg1_cYni4U4p_fuKegMce6au-Rop3EzVe6IpOb3tXpjx7UVnxEp38F0P1Ij27FmfDgu6v5jFxFoeOYtgA8ZC3tLz5KibxVANHU0zVnB5bUL2Rf0QRs6530n_oMAsPCkzwNxsQiiTozyM6SgzRQft1ptkpK0tlnGqR1Bj1Kb_Zib4xiabrA9loxP60vajw4yl5lD4OyjFgUCOLQ-v-RdJoaZ7QPwE937hag5m--AhMTEMPVN4vti5VEpDWoXXo7sAM9ZAec6xBLptR6w92erhLLN6-eJRXrxgN_bRpqoeyTVYIgmvDsY0rovd4U4ou5c4hUYVWObGznGReSQ9znD6fONGBE7c91XjOZRionDoA0SXyqsSd3ky9QXbyJ8lRTSnhpFEIWdUZdDFrmLmLnr5ChOjR1dO1NZq9YGPAf9V7to-At-A9LwHtE64XlpvhcdbG3Bwo4-Je1HKBQARQSBeQcUAg3yMSP8B2Qy39xyVLpIb-3a2oe0Kxb50OnSH3mTxvFw6PlBKa4Xi7FT-n3vaI3-6ZgnWJzIJSug5esOZkEwAy5l2ZRo6eTEfiglPN-TFNQNsYLv1S3mPxEkioPLbCNY1ssm1Zq0ZkUU04ZtB4nnfUyzzr-OP2Cd7INhthsynwPFkX9sTz8Ep1yMW3E395qfkvLn-t25ePDsQMUCkTmex9O2xZsiETy2PP4Sj2ZzEdkE2eIrK330ZjIBEBW-Xvw4O_7j65-RC64LDTyP-kY6Mf4fjZdqiuj5fQAyfH-eRbOPQ_Bs1go1eQzuK2V_N5XeBNx8Igyuf0tlqwFTOfjYAWEBanyMamVzqxa8pXe_yjWzadHW-7Jq_xWGuE9Icm7LTQFFwDvLRz0fMtFVUSeW5jKZBZpSi3Lj8m194SV1bVnQ2eHLWoOz6WxiJ8x_2u7UzeMVZ528Isc53V35IuSM_wXZbuRPcIVne09yGqzpCddDmGt5t3YRE0WXamPpZJMjN6TodcJWDYGjfkG48Y3_gjP8uB3yUXkjW-0_FcHamgWq4X2cHIkW4qbQxog0uzVQ2sKvBds2QkwCCvUU2aQQdxxfbiZYFzLv_ZBtFUChexQdVr74ZBhcz0MHr3wlThYgW1QF8RYQD3fDor_jntx5XMVtOZC7RfyzMqiZIixQCKjkLJQqYQSfaXAXKBSo29HUt8DuqTSYjwRMujNutHnbOdis-62a3Vlh_-Lhxmm3uN0mOWemmYhGodEw4HX8vdWKLcYLKmIkUXXeIj-uRZoCaIcqI5YQL7HzMq3CEBhv3PradwLZRhLJUSH4j3cC9CuuB3uD-vPHCuRC9WeJIdqK4cpu3C-qbJRXCWsLyH4m1FBIdqA9a_5N5JrtqmMf2npkOomzQM6AZLEkLfULBXK7x34sBkvr8-9oVB-MOK6OwuKRTUHl-IdedJWLzwTHHdNJlOEzIyJUH2eVTwioiiIzNgiBY3M6SeLUwY0KuMqxkybfI2s_4OCSiHLgjgA0Bo73E88JINWtyanB0JtP4KphaupFdJXMTpY_-kB5LA9rgSAqkNjhxaq4h44BlGG04q3AeF7Pjr6ftzuU4-_v848haaRTSlk0iFFRfuzaxawW7zCr_x3qDXokxxRBqO3aFPF1gz-xwHtHKOHjpJ_nC0F9d651Q-8u_lsflWilUInaaJPlkaRBh064QkLn5X7rGnh9KBFwkVISWvW9Rd60pX4gGgdn6LHDxsmRMMF543JrAYGUQaZIX9KxmTUiMfxZdqEO8MmTDpboiAYTVU5MWHMU-VqGY7ABXOTuYu8uqvurbjHfu2H9WGX8niC4ETxDgwuIOmWHmXhsNe5nnx6A8Ig56A3IPKajZkjUFDptiSUMQU8A6l8hR3v3Ltf8SInKbNTcnE9-lhd8yRakaz7lMJmis86V5lLkvtN0CAs_GpIjuIdRigdLTGckNs-DYYwK_k-qdbGEQ6h9lIxzsepFIYA3kybLDyAPzTRRltyvw2ZS9ne6rG_JeFv1_fr-kQHJ5Zfq1-gCuoB-gf-YV2bkOHDs6pd9SVbrpTwGCt7dKXNs4oj7aweMxejTE-NmzTvrHOeyzDap68dxgWRCEvXdlTMehhfXlP2IS9qrKrid9KQSVign7lRHEQ1TxyA0l5CjVNUAqeZ3AfMGevb7HArVBeMNK3WSkOLKvLS1dptEmyPa_BMYgTiDpbuMETdGgSIcGPdz_UTdc2SPXhvzDLVOc4bN0vQxI-8MI26qqa46Rx0qaxVBJP3-2pwd7H0lGhZ23KCiwskfLRypqbHKaB20Ah75dsa9Z7Ru9a4jkCeEn0qhghs2-KWShF6bhAlbN2tfQ7T03WXrUQTz9KSefPqeGCWLqnvV32rQbI56dn4OP6zYdJ125kUC8C7RHTKm6OPAW00WTr6pQKxrMm75iUJJsmfPuqsRLCJ8Z6o1JL8Dwjq6DXBp1AnGhVkMQNFcmUYCnBZdqMNbvcNaqmlOuqkPmIjgJctw0cIaKZnK9TnLIh8d7eB3oof8-k0DjWKJjU1d6gUMBp0v5P1PFCcBWenjqyofddGg97i9z2Gq2mA1IJY30PXi4qt1LMDfXRUujM4mNMgrjFnbr7MRuX-FpvNiPtssKTHqrvorPk0MfikKK1Tn0e8NHQhfsywWDuc9KZlifAvg_5cAV3s_PFZeDL3_rz5cPhs9qjXTMQp-mRjj9jS6l-sD2j1Ob2vP5q51FMqwXxrjSLAnT4wlED3Lbq6KJ5IRYJcQVK61Axf2SC59tXJBtNm-Xe9jqoX_JrvMB7fwaL_PhNu57AIRzn4b-goiJjyUziZbYbrBwRWIv8ZEz7BmOs27RZ_1fGKtQQX-CN62KQzjIgyPA_tKyRZwK73XoCjO5jAScZCx9k8LyE4os499jDB0IrYG8HprAXGe23MQ0E9a9tPHj2K-EEyZ6x4I3XbGysAC5gdUCK7JilgPnswv0ExXXVBElORRdoFbZhXTxCZ8iuYrJGFwXkM60Tmyn_QtxSgDgODJN_5ggQr66kPLHIDO2BHD5PAh6cnVCjG06aYUOZ2BRRAbT7gRBtP1kq6XKmsDHAM9J06f70Ndr2v8G9t20hlqdxFX9Svrs3yKfOGVkGU-I_C_JBO6qearpB4acfCtLro68L7PxSWgqWse33Yjj53IzDPKmNBk65OmbwiCGVmYVdt88j5XcyLRB9WlprVILa6BoWu_GATtmrojHE2ZtwKCbhQ-DjWCyl8Q6RRap-zC1FMhfb7GMG1ErMUDTbigRpLM2tRn5rgV7EWuERUAhzsYJB1A7zT3BPl2FAH5zy7gfUO0JVY2r8nJr7rva_N-fgvBa2rvAa-8VAJanfys9teVv9MrQR83MvEgEAjsf7q8hvWGz1th65HscppJH-haEJVo9nPTX2IkvaXCvl1XnRPlHUcmTxgRQ4JucWvGTuT-SQxvKOadl19YYPnHXgeLK6c9BWNMGKm_2aymBgZQ-I2gyAsjPLixnmhreWSJxb1RxrnnWYh2Rp7wadXtSe4cVu9L3nfP21ivt9SsCftTEAstvvnL-PGmXml-FDsYprysLjKxdSIHvsGtv_0pKWpKk-GmSnb8SJY2Le2yZI1w_FKR0jdUnxNPihM4CDaZndtgrMwjmTdhK12eHmgeS9IwOOq4NtwERlqV6zmQUU7GX9gOBg-sF0T-vpoW_bl-dN3rmSfyeD_9WB9OQnS4WLt77zA2sNqtoX5rIwoCXYOjItWFo9JEVMO5OVyf0EKvnu2SL792z8ms_drP5wxe7cl_mVRW7G-WQM8I0GBhoe1DTwzXVP1VzlHOHnxA_4b5NdqLQsEaE3Mu0wfH57mpLIfMJ6x4-kxsuOuXFWZfsWwpQ6hEMmSD0J33rB1knTSCsw3uD1jZN93GSGVxVeTkosWIUVooxF3QM3jiwtCOji788f0FroMNYUCFgXzy6ZZVcz33MITcj0hYurR-wfdhY2wALQD6P4KREshSrP4betQ4iw9JAy9S18ZFTwZDt8Bc5FzYY0vDBrbE0z7weKSQxLRAFUq4BQ2vP7Bl-Z6-qon5U36-AiISNtxK8Aenjpudx3cB2dSBRAp9sSiy9Yh93cXY-zwJIg823Yq_GPzdjyYBxl1VJWwmClOhk6bBfeeDve8-kPq6QM3Zdi-sLYUWwFy1gX-8lr3sqtwGZ9w1s32dIw6C7gBnnJT0azPMLaEL2Is556qbzar-k14EyGSLkHfTns_GcPwD30Y9RklgShXbqpIj7aDsJMz6_8Ag9Mjq8I-TNPyDIOKP7gtisohs9WvmK14Y7Z8j1CRf5Qcuq7nICrQveGSBfkSSAG3N8edlj63staviMWru-AVcG1dwJ9EgRS2xsRbjLvgc3X8fmqTrECc8BOQwZFJnRnC9fUaMRaTzI29MRW2-itXMxX12odCh1jFPeJCoiBhFGDC66KE7laWAqbziQQyTNvr0xCCesvf-Wo4nFBQXs2sXTYCow9oeUupyQ9Pcy0FHGYuqJQZLkdhY-H8LL3SHSXRvp_yp3vkUYSZsn-7SEijd3geiYvEpRzwkgDc9DT_0e0Zk2rhx0rPXE_KNyIcruUI0gCfaNVvo5V1c3_AVL6Q2bW1jWCtjoG5_dyRGol4pqkHw0d14CkET0SyrH_d9jlGQl76lbulsRaBwDDWHY7_smUyP-bSlbrfJey72aRRRcWWv778CilDH_Ubd30c1bCajSVzY8mlEF-JZhPdnz-my9wv12wWbkMLPMVbZPGQY6Nrt6mLngtra1i19sSX6N2sqp61-poFdKBuwLvAg974imwQzFxeOFeAJD_M3lW_C45oFXnItvTPgxMW29O71Qre0pl7ZZEWE9YFS1hhA7007WQJVaSVcQZ_ZBO849KeM3MCi47L79qAZKjx4a9OTGHd1nzOHA23uT9ziJvUQLkwanEuzRoqDCuZnGdbYc5tEqR2J2tIHMlOc35OOrKIYyxH87suacnz3HwC24LnetG0MeiXXQyxnq9GDj61eYIM3DGRnRQ0zRL3R9nos8KwZk7lqjtZB8EkMNw5MyUOAxvg4ZC0j12CfelUD-98xUkH8LKjpl1erWaP2CtgdvaOE3_9YeDlrS29mQGOQfJrXx1XQx2fvo0DtjS7wnBbucz5zps7YHrlsUIndfbOdGTYO8IWKDJE-5-4hwccybuMVS4hkc25X42MHP771Wx9grOGUZzJD0Bc-u_dufGs-DYf-lsFbSjJ6plCx5zHG_OZ_oK6XghjvB9x0rVPzd6dvsso__pArE1eGjlnCcpUHmkg8FCbytMhUj0GEPpHMJhV68FEQ86_D5Lf2cBv_eDW4oxKz0MWAdAgkbMBVUgcFdw6Bk9ImT96hQci9BUli8wcrdmG98Rd7a1oyQIODpXs41aJAanLZcK1BYGfdMsfJsOBbzrtfHE0T7rgvzeQqxAaDN11bTa0g4QDvn_nw1vuyd9ncpBwlEzyeLNH9f4pugPIBsUr52QJz4YQmBHv69Sk_qcSma18Uc9ZnEAWeNjLe9on9ur-AToxGjDP9yCeBOUIIoEWzxBJVRt9yf2z61z5hEzkRS5z_4bga_DmFpa6eooxIqqaXKwyIXDusuE5-aFhfY-Pf5e5eiEktEc4UtoNSyIXgVhpw6v5nR4vZOzUCl_dyehQ5iLeBQKaDq-wx5lUg6yrzZeXUD8YZYoboT9sS4CySujMyDlIHZnWaZpV2obFx8i0M6g3ub-pA2igSZg8kFWFJqOAuAXfSo164AUyM-xdLKhLRzlj7OOYg2fvp9n5fEiKIDxTfLd_f7sU0YlaxHIYB49wMKzU3o8HKaYU9VX2t-ZV9r5LZyFiDCDdL-xJ7nbgq0s167G5DBsATvpfwI_O_gQgYUZvbNh5tteeVk8Yq2o8u692EdO7YYaQfZhHK45_LKYltx3BWSsoGMMcjXJT5puo93XQ7l1wZZBTrmnC7togRGymU9ckJcyCmL3oWnfHv938lzISdR8FxMTvvKZYoksyNcfDjVTuyIRLOTeZXjC8UMiACuEvIc94xfA5D-zKkJjdfPoSjuXOx3W-qfnWQWgePOSbZ-Km0w8RhqSRKJIKbK2K7jlT-M1TghBFpX8fOP2KLNAzaS7g7b1CmeLbudTvcULX6qjfTTew8ZoM6Y5PrRQtzkWDNAXWRTJQBJutntuiBgIVVxEVoLFGLCF17mrR_XUh6Pncc-sGukICxoiRlqOnQegKAPNaKSd-5sTVKy2T2rLFfI2oSJnqANa8sdZEkq_syFFEWTvHVPi0NAW7nbfUAwQNyKSlAkduLATKvSIKiMDsr4fMHW5pkZvx64Ocjdlgs8NXq2P5qDnbBaD0Hb86YlHBJ1_sWh-7TOXcmhHoKrhefKo9nZa7pM3C8PG5rZ6Gd0ECf0dUfpxL2Wcs_1xYki-rtTBzUcjEVzdjzlVNeVMNzZd1Hk0GvBGtospg054L9Fk1QtVDKZi5wPP8e1gnK-RxvCr8NbzG8ThJBQbyK72v1dcoDeSUDRzYMLHW98lTcMns0M8AZEd4QW-l6QDesdrXdDGJdy5fxMLUclK-DWdDricbGylwAL7zX0Bx6coqXaFXhjXShMmQolNcUjYPfegazisOwYsYjWdOSDhNdTR8w58tJZvwOCzyNZY8a8xcBKAeAl3khZttGhOyo7U9-kZ-HvVz2Dzl2m3fiMpvyCKxnk26jSxTcEIlBLt0FCa4io9u1Ytos24TFu2XxemkniwsZ5yDMdknblx3MdN006rna02x55524sCIo1R2hx5U7G99XCADbIZiFEnfG6vmlA4c6lbRUgNw914e_hdHYta3ubZ5jqIODTeypnpevfj8F01wa_9JO3YpMQrRAzZ-5Ii-_J8KjukJi1lih6EBhiDZL64Q8LsvbQZo7tHuxqtsXmMNIunOAPJS49cfziy_tBP76MH7rtbNHGLyJH8OA4IUqQTh0EEL6Hd98u8x_GTtRuvP4KW1XNN_un0yINVcwKUflFEjclwijxETEMdqbLLCFt8mRk1iHQ5qSwSDwISHMm_6e9qCIQ1Qt7Vze1V6HkbfsB9FHI5rq8UhA4UE62IrlcvYyZUwEKAB5FFM0XAnAhzEt_auG5UVOFdd6_wdbg_1Km0DZuYJ546TaXLIzWy5eKVvhoa213yjW6nBqUXUkluqTii24MawmgERNhmjMrDxiWeS4YYJip85dM78IQXoLCOaM90l-hVY9n3YLgjj5UqPiPikn5HWrUaedm1-08Cquyw3df7nZdJPAUyS5UCGW-H8wCkH5BjDY2HY7ZDpX8KtlQP1UENSHYLHIbNb46pA5MuR2PrDzmrihuIICF80i-gtRGN3Iq0uiDBck6zY5ho8yqE6fJrEsHxAs3CkKP8c7kFN_zvRSmfrmrTyA5QsK17kzQqgWN2seKH9MwXu6ttS0lqnUVVCThsOOOgLjC4KxUCc4vYqEoeO_f9KKjyr83NcfTPBJQ8_u8iX-dXbN3_d4GCJaMrCGpp2-VdW9LYOQOB4zdLzzTyoAubrD_BY8KUTWMbzmhymM9Dy-4INe2x86LJclnkK19WU--jbKajqhiCWvE-2nxmvAmKilDoLQXiVEZ5TWYvctOa69QuVMybXU9yEwsSmkiJFU7sAp1YyqHIV4u3Q7wuauA9M60siOQxu_P3nl-fIEaNQtfQI_TZYyvGJInV3PvlMtmi8YrQvYOflhEuWGifnVAXz1PaGaoRy76tce0Yd9_k8KXuXW5pXqXy4Nqmgbh7OUNN9XIls6URwiitBApebQe05oGs5HdrGb0kDmSPDC7vn0m30QmYzsjRmmSJv4OzHUoSB1MsMx4oGe7Hr3BqLnyVrmIOoQqCqCLSAM2fHN73mMkq3T7aqYEEGcupKP7Ryx492sSWlHJJJsV11k933D4792FlBaKcS1TAubYIpeNzsXrqNO_hWml-H2HY-Hrd_IbuBUze1asiMAueMVYiDdmm1Vwz5Iu6A_Z1VC2j3qxE5i2lkKIZHU3Qy3W9fKHJQcoj6JQoimQxZUMTd2rMmuUisiS7o-M94m72yPuaUn_bmaM5ZcLIjyLmGcQqWyMRoDVYnG5oE43AaACrEfK7dgQEtR6s1EgAFSA2GwxKbFpgYDMhQALrq0-qv26pDCaaFt9XaJKWi4dWwMrg3KOL8UwvOt-1qJa9PQ77XfeAcUs_VufmJ4HDyW1TFi0xy4wDvU3AsOUIrapmvXzYBCaPeayMNynq6QD_xbme_w5RMtnq25ywrUoDbul1wFQDjcWBwEmt3ELZZ1yu5gvPJXqHYxkqDGB8wMql1HiTDWJ6zNKgXLbOKL6ewTnaPFEI6SgzDsAHr8PqAPVjFKjoLt_SkL3nVMuLOULv8aVxeyLxFYKWpzKwgYTAoMNUMkPrLgjJbVAWdE-U73HCY8wT-fBU5jU-vSyeTMN5K55WnjgkNYq_CPFIYZfDJaCpCbzJ7URjWFElqMX8RagjEJRchyJJvSEgOoFfn9VSsJA39kmALMGYMNGLLzRMN9wf389MMQFhQ1knm5CdVcAeiBPDVn_TEx04Im6q8M0AO447rnjRUN9gqat6Q2HLAqplt3KPco078HD3wHH70cacMtk0ZCWC7fyEbjwl4gtchcf6RUE37zebSz8L5W1C6Nh1EFfFZDnG3O3b1Lcqo-qF-PR_nCgHXu0tLyNDd2jJdrHCYU9PhCgzjQcbUSjkQRu5uheUzg5YV9wXgLiLfGuPgKo-OCDg-Jc9x76yS4Y5V86Xs4Jv_IN2c0P93b80nAUV8hMvo_8PYoqa1b_0ZEX6iM1ETKB85BINhPAg6szdOw0Q8pLCCSnwbwxa3ucIrKW9YyZ2Y65ZybI2hDc_jnkceUFzauY8IFYjGx0hH2nacze7fADZSBHCYqx5qdDRXCHdxPLDMP3Z5h2qhzqtqdjV5Ho_gfVVfU501BoH_A1_1c8D1F-GYMtPuqnNBNBQG3zSTale_sVxBNABDKlukAzy2DaEwdcFBJ221hsdlr-StXgWBFDZuGniV9c53V9KfUwDt6RY7TQzU4wSR5QJ9SlXPH8TaTJECSl57vZxknlvrRVwFjJ5KLwGon6wo9Ez_ad4uYC5QDl7NkTQcaCiDYZ6D0s3nay_YJolQcMFDGklpiD1-poRQlOIzzSK6YUa4YIzKsm1UODKN1KU8brijEIk6545gexGdBD7qjyNp_iriklHz3nIEz5IJF_gx6QxkidgYC3z9WeYjATXQcN8SGwv9kkGnEiQBwC95s-WmCPiugu1RTY-OsOAhN2q6sLmIbAF2OlO3k7ouCsWBYZEyAus0BKHtB8B69873JyG_YVH-h0C6_scDXfJjPMtrhAYzs6-mirfAEyGe02z3yXjzGg6HTmxglDEiZGOfg0GYLzpslfyAVSo5aVm0NKkNqK2DQldxwu8UJvu5LjsTYyi6GU0myb1grE4NDgcHuO0hLbPSW_AlV4qXhVXe2XRHadabptGCj4Hohn6R58DK2ht061zt3C65n-SecWulNCy-Nx6qAi_YuIfcCeovKIkbyIEbZDgZkYGwettm84WSuxETn8vC-RFR90uqFhDA_5-gQfKvHZT8dGFFoZ8n7RWYMqtUedtEni8giqPij1iuTuqKul5vBHmH2oN_DZODJwRcr_TcZgBsxrIS8JsZU0AaIyuY-IuTeK5Z0m-6xDwS1VjXSQSL2hCCCwgWeAIXLbqAEyWkWMtWQTfnzuabuwgRiYgo1rY2nCY9N-9OjVQA4S65Kw_88L7x7mRAwWqoh7YnQQr9PvsQz8UJnB-Tv6HlO-8wsPOhztDIFyIh68fGIv6VXFJKEWGCpDsiZfna3c57HowtizjmGXK5lFB9VW06n9wrwuXlFlY3o-pfAsrLgxK8DpKlWCxPQJdgYMF28SLy5Cf8m2gfeN_ZOmwnyuLvcGc_HDvbPf14_nMJwZljjqVhgzXcFFdrQeGJhu2Jl9pISsTJISI4nXHg7TUvNY0B3FCtkrW3emZcW9J0-7MUWIWvkgujDqSndKejmTzTfv6V-Y4fLXl4IEejobuDlrvwiStcVjsJcgsV3cAKrpeRypmMDp6GkylmM3vtmNRwlnbki98viF3rdhXdEVeJbmJazxf9WrcxjPsLTh-QGnN_NTp8OjoIrsysW5nVfu9vH-FtHo9UzxDvxZNZg_eMD2EyKR-akfrXjGLJJPVASWZ1QUBh2p_tZfGAuej0322jjQo7cWJSsFwOESYE47QAvDq6q6kdSZseHGGGmHpb1-hG_m028jJZ9hCqn2VvUI2Y0_X6quQa-9gYAw_HisJeO7Ils-vYOVAM2rl-ke8FkJfq7ooHpkAZI6HEridCbEq4LpVCcVlKVDLyCtBZZ6f8ux_j7f0WePQ_5Qw9SBI7fFpd3Pkozgk14AujGXLSXl3_xh8lFY1TKuJcviuAklQCI5HQqXg8vkiSB65cvjYuN6DfD-e1Z6iy51-qhS6pqoHeLQA1xqC90qGPPiyqrhsbJpquQs6HfwWq0CTf6DYOd6e5sAxh4x2G8X4ttOpE_O9oqY0q6rBu9qPYeg2bAaxFtl6woVSwgFe-DO-UDa9gIV5iwrWbaOUVw5uDBQKlPtZLKH5lXTc4QGOo8pY8XsP7tCspD87R1Zfk8xh5ugiDa-93jH3ujhmPT6GYQiTDKJGq6sGtS_iX2BSQrfGIp5n8xnRFa8YahaMhq632oRDodIHS2uVQqI3JDJu-lNY3CjLEKbsRgL9wAHukqIsaheWmdnFWPs37whkaUKNGKTE0LfdQ3fUHH4KCvyf8UrUo-AS6YA0dE-nO0Sfw0EsrmwAttN4AmyAbkeRdfKdwv-3z99IszjetZoP4n9DfrzMjVsHUzDN0uHfwTrN2MmpfJMkKVhFY6YJFroQg-r5KxTyPXnxu0jCHqzXTQkDAwDq1b8F1QvmHzrLcXDErnPk0Lunl3jPDy3T3yiHVzk5TO_SmwrJXFTXDygbCJmR3t0yAX_ouJXh_9ZXgy8Q0jDfc3HhEgs0l7Fx8r_DaGKZZ_11XpXpWlSCU1ddvMuU3QUlk4ysGl0B7EevmiH5hG0rcpK0kOa2cgQdEAzoZC6VPSrDWG-SdQhIpmr43-21b31Avy97Memnpkw6uw74WHQYfNhAqfCk7sLJ32zxc-OveHRP0Ea0KaWqa7I5eyiUP50wVpamQyIJRxMQ_RvWmg4PHZmXilQK6ytvUFXkLC-ILL1uOqBybIzlw1Ewzm_3H00aSqacholjVLItvKyP_fPNj3spSWVyrmyqdiU2eSMZJNfc1Bh4ixrzwFein-WmFO-eyEHY0XVE3yFkmgoJMZlTVEWsMNgHxTYNGEglhgWJ53zaSCS5KNuqDvj11oauIBSgTy9PsvxTzPG4EGX7y3O9MSMai7n9rXmn2p-kekl8VF3YFLEYSC7DZrHln86SF7G6_a6tNP2adtNVQtYLP7LkV-0Lfhaf7f6Scf_5snUjFTHavytf_p3wxitCG3TIHHA3pkV5lP0iQlQ5R7wGDjo6bRagPpc4XhhSbBndQ02rhvoT381MmHGFB65-ggRJV1nHswC3X42arnQUjwO2HjI8lEuIKOYf1b99_g-MNn2fsDFLV8_we_s-1p3JrA2NtUfS7TQQ3GmSMN1tfdCekxpjdvEdcXjXiEVgqMnuaF7tHwNlNqUz-yhtBGwOPIiMmyIYexHOZg1bGXoHqpVF5TqEnUJHLM8ItSf5-xR7uR4yEFXkhomgV5vIgwN5qGP-DCU3oEMQdWDbPsCF4FMcULKuPsJiy4HeIPal3nyfurbPFnq_BIRburFlhkStac8Q2CEJeXRnfMdTNCkG7_Z0BIPXRg4ut8ZFMJjA-1XvOlbmTDO1rlOmEdbKxKRplJkq-Kjd2jjty7kHx5RMT5-3Al42oCF9uqHKfitueevmRut49eJzLP2PyPIJJsT3VQM5udsp2dopd0nShsrjq7UhFyXcuWBOLTsAqddgVxe8__wPmD6t1NcrXZLwVmx8_w3jwb7k-J45wuqbhdv2MNgvm4uvcWJvlk6t6PedRkB2EbGfwWkVwI9xaHVRAcVWSdYyjqLXR5x4_HnJ6HWqzLQeIp3Ss27L6PFTOKgqXI92ePp481b9ldkf1lMqg0lvaxF0vY7PS9Mve0qpf8VOOIq63EkCzBx7rf4pr4WerSBCNigavaWF2e8C2iPrayaJhwLdlZwhfGJqJgGKOEghF2xbmjOOubpRJYMZy3BHRjAKuB5X81dBja3CbblpO-dMOBvnzldjXsSGGC9T4BPDff5_t8FINGVqZ85QYJs07cUTwcaykAdQeh8jf_PiimWSJdjIsyJHbax4IvD6bRpTGFWvCB6sDZ-7UDkiF0OCiMoRIbhobWOyORvDcEK94Ye0H4ZjlXuZyf0lFaOVb8-YItRDu3ZRfNQo8ygcYDeGahI9UuaHctbN-G7Fu9sNR7Oym5zL5ZBz7jYV3zImQcOgO3aLp9Gij9LmcVr2aDv9EYlekFkbLhC-Y81K99p3_-ecsK56VLsmI8MBlxo_l_E27IqRy5s5-qDEzV7M-jOpWA1v1TtV43sLoYrYawo0UM_XDZ8nPgkA6kieEPRObhNgrKgCHMp6E3ZJugYra39vXd1YFCb1KjLvvhauM2YZs-Vb7gFDAXWbM1xiBEdWTFgzXDG7S6fzaV-uxiJqc8De3EZhoh8BQagj4HV6ddVkJVShR6PtPV9HCBbjioLEW-1n30Bd4n_V44BTfxaGtcjTxYIBBl5F9BdyU3wOuASQsNGZlXpgFPocpjn6EJ68RqFFHHSVMKMPCukF04pFdKkV-VPcgFijhYauEFYGFupLE3vmZXzGN1fVkUyJiirdqr1MNB3m93Vpyc2-UF7EWM0HY9C1kLJjGft0JgEqmFsST03oNRx_7HZ6mUJkm3cbFdkeZPwj91AournMETww-CWHQU6PtdxLIjdyXkt0lLoHHwmF8hXZOa1_scLRMxOnhUbK0Vqm4LO7AeZCkE8RE--72wwQQoAhnzoSG1lRSwZ70NHQQ2eGyJtEP-sxy5D5eYNCcdOEnm-lT0foHj0346pXaliorAXSRhOa2B0wc9OV7RakJwY7h-VY3cqSabdAHQvLFBhnEvpFZ_TL8VRzRgo_FhDly5S8MddWUnD7iMIQ7G6ERlwhuZry9UbLgZA4yRo2cC--zYU-LihB6hv3sli4EPBYU9ocVxcOIN3VOGmyaRTTWCHEbyOIDeagpzk-LEBi4dVPef6ox8YAud7YEiwHiOhi_BlMn3aVCDXEVs6vgdUfGgA8yhbAVk7CYTq43an3DwEb8LepAd_slrtD6wvcHdCsCN5nFYCGBbMwD2uKdtQBzZ9q_hy2k6pNDZ3dVpSBy24sO01iOv3WIYIL1LXickS3eyKxUaMEEzIF4G3BIpxj-iDd2vQ9Qvz8-ygYxVYnjZ2OLtDGIhMIwrGre9GqOSL_SedbEIHqwHS77wgM1y38i9uSTcFX1HSIPEPutj4sIpx_oMKqnBVsYPLMN0UyHzJhOjN-NUh8-xKMaGwCPYD6G4rsw-lG8o37QYPB4Os_c0rCsq6OPC1cibVEvQOU0_kHBtZOW9i9Cjk5dRMFuYnFZ6lrU2EdTAJvjFmztUOZIAALuuy3yS2dh_sL7mfoyY2cAnTF6mcCaFALeZIxu5X7TFCjWiBi9bhxbvqLsEIzTBJEVv2-0ISQ5Hw40wwmm8UT-NUggvgKsBjXzXtSD0lzYRQZUP8KNz0UQCj84sl5SNSnWjx8k-74XkfX-8WKTSSMZsRO5DJaLUYKN-XpIGWXULSMkB5eVLAcCIgHgTv5u6ndWM29_v6QlxtYw_g6le2Ljtdgp9XwvnSQKKCMAJB8aP4xTT-qusiQXqM4PuRlLpr87dhDp6fOFkYWLRTnz8BUz2dz5nwLqxOj7kLXwFYrfvvquasVNLPjELkWgoHQfQxspOu4AA_ycyVFk6PlPAcT14um6oD8wGavr-y6NzM5r5V7AjMHTLEPbFBR-oimSJr4tJy5Okw8wqOt0lBqSz_wjOV4gdkxquHDp2MjmS37d6TrEV1dYeHemVDMMFvqXz9zpMLj-aek3frGqKEqvETSoZU7wxFcsmUOM3_skRBIhdsLURo1UjUq-MuEOVVEMrSJhGBF4Earj6ckn_ukPRB0LRCkUJtIxtTcdKdVkC24l5j6YsMeBeCX7cYpT4omE-_YYe31P06z6XkE282WcfhM0D0xSUhTVte7JsdaoJ8WKN7Rt4u1rQxsMQQEHhZqqkCuIK3-jo5UvAWU2dXA7DKtXTOPG5eGRSz8Kcn1oMDWyld__etEY-ktHtAAVd7Td8W6BEKY286RaA3zup2AwLN124b-k667opHH09fpF0TLAznm9pND26n6f4wDTm4odUD2H8iqj5-1spV9S9t_v1i4hgXgB759vQYqbhcUlxRsQZesesMaz0jQIqbGI78wwHxcHfodl3BaZMJCWk2VdZP7SQ0xCn1CFpbTCHHSzQID_M3vzPAWSCC22IBphURVrMPk0xLT8_JqcFZ_hCfv4X3MScUlwDz-HP1ulvYzwoj8XsmcQIpxj-vjsVHcIfzwSqpKAb-Vc95ZrQxxxwV2XVmePQQ9zeAJ7kVMpm5_DPlzaiTGxBFL8BSfnU_uEvkQBE7BJgwtiNUsKY1kW2CAaUm8_6DKYysQ5bsUfpmwfQuG4iKv_ss0ewZzh8iMr_6NnVRwOozUH755hZGHyIgTlMkAuZ7bX4CrLrKrams0VaQaEaFL4_ZAZ7isznpfsKGDBKo7mP4yICkfwG4dpTkmhGQ-p34iDjdsRgw30foSyaYxBHjhVN1fZlJtpjnRJJ0tb5rWAnsEVWxDTFXXjndp-8lUSNKrUm-EGT2V-913VfBFCic81NT7hhlW3vU5gMRKz6x-INUxR4X1lfWDAa24ob4pq4WfINBKLnzDbjT423RvPFxqZ7bkpO0om5wkyUX9zJTrf-hHq_PSEid7CPOHQQuRzgJegx9DMl26EhgZ5sloz8eBmGTmpNUOxyQo2VFBqjxlNSofKS60ViEUC1WZ-cuvmnRsicqUkKmrfKjqWGbmADnKO7a1CqMyQGyvhFOR22xpDeHueXRDDig8zz1ZlPIkU5Rl1VGIVS24NzBPfxRpLvZw_sLn_2dr2XHNk1YZDbUiNkpFF4s2XAvZEHkbEs3K01u0QOCP4mrANr3lpW_GwglwURZeVzs6uIXJIlhHvnNai9e3DUbFf83kUqoQdjPAXk-lWhQGmsSgZ62vlBtYed7KKmzdPXAKp1ivCf6m0iyniGxuyVAwgukXEkkXO4E4Pem66aDTJVXeCG4VuO2F2evJ36PYsSkDG90OchaIbk0hg4ZlGvN2CIKj-Z9KwCOoxw0XPvcvDU1k_WiKecOk3kxSY_y3VxuQ4TjdG0JbrhDNin2Z7fiAOezHQiwqlBnKCA60SqLZ7g0BCR7_d0iNKJ1FG7D4jlAFQqydMj9QCphYy_FymfLYtSCNt1GDKZGZFtOJY-7SSdsb5E2w3JU-P_PJ0kIt69KERZPZS6BBrSBY4YldDABAB6ly_4rUb7zINZQZ2PPY3yKwt-6yUlHcpf6fy5LodQZTyznsXk3Uu_YemRQGKy8V7mwU-09JAOJXgPFRd2LNPEmZc6qtai-ezXXmHgdEBp-RYM22QDVFnnDg6t4ihV15jg99SRR9weNCgJFwAfYQR0wnwE-XPYvXGzDxfCvWlDKonwlQS8o6Fd8CPGt6P0ImR0teYdE6stniPS69jBowA04YVOJWKXdXx0nrGyqjc1ncmNE0zADb24BxU4LGZDItwd_acrnvSR5FbH3afy0wBb8n8aSyUiWqf7GYq7thSjL8TVDs4QXtdVLnaUV39KeJ-Zuz7CONkV6ZI80SVE54W3Z8vr_PHxuN7BMK1uZiRn3vZuHBwR-BWekkfYZNZFBNdKhho1-AZEycQ0HFJIhek77bbFSzbT482LaG7YqqXM1m5Gkr1JP7nj6iOjjrAHdoOT85xt-MjwOW4NELm0p1XvW59EQ2fFOTHsuA9oC4J8_79hCrPWNYnqN-IGRLgtSXToz23cLuu8_v-7YWw-UP1h9vN4m1RDWIfn1dwpCd90sc2JAGkkukIR-gXIBhndpxe5HlLOziFzl9RBNjFNt-tm_BsjBQEpFBRz5ftS08yWUE6F5eogKMfVE22KLQDMCUQWsIEpugK2Xh3a0euzXO-24mtBzKwfAs2lpC3ZfXNPxBvqwYhx-ffARgdVLJwXfAV1reOw7rEGSiBwdg7eVlDZVvqiSrGsp1bTUJ3oPTdeq5RqI4Q6C3dl8daHop8lUq9frTUv5aIAViiOiozqaLVg3I_jqYLZZxssDql1OHUEukybYKhVlNGh4nMj7dgzQuAVYSM0PV5nYkO-UjNWmuUBcVOg8mljkbFmsw8xHBKaX4kFvVLVwZ0QK_Md-2pRFftuubIvsWg_2glFAQLvySuwnKmTNYtaech8SqdT1-aPnP0vNhSiQlAuy-seJo4BsacPxYmQ8_Xt9D6icCA29XcrdszSNygHUAckekmqHH6OdX05NhU3KYYw_Pcf7yf5-hNq4m05cdc9kBKQKi0fudzOwHYPCr8AtKKwHnb450Hzb-4sHrMitveNPJNZJ9XdLCWKB_OkV2JRsKAYgnPiLMC57wYYG14DYq9B7W685VZaOSz6XAC4dGV_zD2flArcvvQYK47mNrG3Yk8Lw__TOxavGxWCaZfWLBRLgLv3BxvILDf0VYxAj-yZk47RfEgYEuWspBybYJhgh7WK2pcTL6a0sYn4-muFr1tuvXZYJTMrz0wMq2O6IpnrkRIDRODKFZeXkIexlI-3GE_hLB97iGzNLyjTivjgpFZPdOOjVNSJNgzx4GI_udZFiOnlCHypV-NyFiaJbd8fWj2UYQ8SinzU-dXCqtc4F8ciRBNccxJofGLo-aWE_P4AU-kdn2WClrqWh955bF9C2nPSUfAVY9n_JRneyt2PWxUCV6oqM3suaR_VKuqlQ0oEJr9FC0KnAsU84izLF-5hGbb-7KVv3UIbbh7VwWYhD4UAF8Bf-6tt_RNCBjCRcuKaWQ-TrMlN-U9NE_T_1BQMCh0V889bQ_-rmcxpiAtze64JCuLeAR8px8Nw-eD3qoFlG03kooxo31A74eAKxOeOqteFDPzHlFTcT6_n3h-t7hv2kNGK-JU4oqvTfYX-zsJVL38WRXt70qCR3tIudUl_SMMCSiq_c46zBtIi7rFkmmOYFYyQwEytZSb4l2E73ivmUas6vVEPDWsSZd7WFQ7kgFMhVE9ngQ55hR2j6wWXF3jL9SDJoMiTjnBlg_f3fawLHXWMFASdeQFM2dAwvYM2QzKTUFHA-HV6PTkjmoPfm15dP2hWWz9npPYY7scs2EGsW9jGgVdgi0IKpp5-64RzIV7JiLxQ7S9C8XSm81l0krGrJ-qaNzZ6bTVxhWcAs2J_Q_DLp1YarbRXN9xCgOuoe6T-OA3af_dTUTnVSb8ukwh6ltnMoAdaHbouSilV7AOMNY0bzEm1MteJvpqBUmOERdaAmUTuTO6gN69TBH41meTqk0XqXWIFBIjFsBFZsH2d58yxXM3JEC7Ybg0lP8s18ARbJK-EwpCgp7mh7Hol5Wry9ec3n0qRRoT1nNA7OiO9JjLn1DrOWW5xjOy9CzhgOlOleVBDtZlBXtwNva6NvyQqgwHgMelIyU_uU7tmbm9s4uyDdJiyinqKxMOt-xw9IPcHlvlfwjF7ao03dLWkf1w-fz-DSQ8k3aTXJDk2qIrGn8O9fVrANbxnZ-v3gZbDLcUvVt5p-5nYE48ctTuu0UGXIQOnkBeudSkA58f54hBTjqJlnZg6pYktJkl9bYmUnTpZeu0JaUH9I3qmfQSljE8NQ9HDB6kgECevpyIxMUy39YxTsPK1PShq4LuZ5M0Lzn3SU-fnUrUfIYIjLmdfAlAgX64MN2ztfzdQWfVIxwJ9u2QosHRpTWAlcLN1x6b0MZiUXWdDNp3phhubr89LLZ1KSy206JOlCd2TR_EfRlwlobdmRYR2zdTSlodh-65RTPIheADxZCqrwVEEnkr2lxv-4ceE3OnfNi5uEvzF6ZB7opUJiD4DBXyltbcpgG90hSV1qJPsJ_oMEvH47lPW0ZJAymiyp_e77YNSfeMitpFwQuldOlI8pTCaiagN1LVzDSN6Zp5KJiMF5z951_UqsCdff-GdNlyYmmT068c-w2M5CyScNHhiI11UHnjPwUJyr3Lumpl0hGAtnaVq-I5h_rcx_RB2zcD1JLztUOrTvvXrEA9XovMZdHLprHOHc7AJlgJGhmDaQ0pi24RzstWJrXdrimOWKnShnLVXTEra8FJ6CwVWPPCIuYvhrYkaG4A2NkMSUuncdavxleojW_rwVKEzdLAYkrUYbfRgM77L9-5JDjcUbC0ofAZi-J1YUS3I5eUXPyXOMcoO5RvakZ0lkJa2oq1hReK2TwL_l622lh4N5EuyurY03IGScfMMaDf4580TLiEQ160ps4qX2WiTPOOnOkDxKYzRgeYaWzFTr_tR9rtUL_PAjPYYIpC7GUp7syw7k5jw1RLbOt6Q7gVWo_11XDMEFXna94Ab043PkpspWBQ8kdcAfXxVV7XphWOMUdEoLn1j6E9xzxgvFfEBp56S_Pwod4PnXlGjKNiahYHv8AWI8bBkhXfdNQlU5vonMxus9KZ1nLYwfyVC-a25iZc-co5Bc4hD8n7bBJJ4BtjV2T087n0UicqGqx3calaMbvYZI3vxfDLpxSfW4nvJuxDtZPnShoduh7QGj_q-cPSK9F_6C3y8k_zq6LV_-aM0u3ivx9pmZV_cB1sG2yifiXjQWc7bNIqtpEcisizupOIzKhiTtDwr3PNO7CuiC3JXpKipFhnKyoc80zk-3pxlvudzZL0k8b-QCkRJRRcgStrIE-VmhEcE7EDO0m2GaE1inG5nO9vC8m2z6e_72IoRb9kKf-10e0Hczzg-ksFITn_A2cjIkwFON_FGff4IGX3Z83e8k5vzoeT-OHhCc2ZJgzbgfut3wlLG7GsXScIuHnhQKoFN5YMdm-jAaGHFk3rzzT0jbTIgMh0R07Iu28Gi4k33tYMLd-gpOravLXS1YkaKlfl0HTk0v5P__wYN8T8gFPG3JsCLE7kj-6DXNnr3Khu2zIaqfV9C43XixUyJnC7iooDkySQs0F9vM9XFFDDur-Xn4Jm1vkZ5cX-oXYppB4vqGVOzmuEmZ824AqhwyMflSClr27iSP4Ce8umVoPIYsjuLmHQ4SFFVregfmV3IwdXSDLbfUkIrd2rt6Rk5aAZ_4vDV4aFRAjpHpVDau3xiKwcWIQogu7pXvDLgOgQbwDT02gjJbtSQ9OrcnbTSSFYY4hjP9ZJzydN93E3Ibs8IoCqiAs6SAj8K6D6yMFVB8-ReWImZsgpl58syRkM66TI7nh-HFoc9NYLjFgcfJfWm6dpCVShBdA0zB-dYsJWwDQ4lOm83bEAlxV0pruX9xvaA9d2YkPVNFghqviCebOXBGp2iUe5dEZmVgVA8LYbga7btfXLmm_7tBMCMFAE8B-Em_KmHzhJO1m2VPMICgD1QnZdLCQqrd1dV69ieqt9Qtfe-bEGhpAIKtRrO4Ojz1nTp0DFhpxB_GGtzrKT5_arNSUEIHurogDRrwdhTYF85SWfoqVSR03QHQXS3RziIiXRkoUNrBEGSaf33tEV60PwPoEMgvOqD_ydO-POCE9M5Livr9PIkM9Q8TQxNCc6LhDSQ9XHp0Ls5mKmA-Sl-ww27uZL3CoolC_ga9k2xRCrZ9-RzUySxjs6HnK5_n6SIpVpN47DsvORzq4n7YE_2gfjWaaDKgr1xaB0ZlqUDKo0NOvVYRxcBBgFFnPKkeREGbe_Fi8sMyfMC9oHFWkpNYqgevndpRG73GiYqExRWRb3urWaUNvcZoT-lq1so4OsjTWDAw4lf18ftP5d_JdFEW-McxTPKwvFufr4sdbCmCbBW_bf40FXQ-qfIJ1aFe3Cj2H3yBNu2rT8PK5-kUmNWBBHajs2QjXbewrGtEX1g0W6KodrKoT2kYRn0lPnm2jKG_mXIVga15kXwBuXl7ZbERmxHiY5Qn3pD2eo4V3ob41fJNaZ9kEcfEu9D8tdg9seveZgWKptHeyMUdtq8_qYNTHVPnV4hWrFhwRqfRvnGmlZTN2tq4av-23LmL0atFQlPo4yuGKVPS717QcE5TevQb7BXMbqmE_S8-sFTCDUdKVoSD4epFOF1t4wpyQEl9BC9b6vOD3-MPPNfeSotlXkGZnV4jJIxY2zzYS3Ol-Li5ZpNeAdaPIMh5zUwFLk6SdaBpHC4d9VXXwyeyO3ngx3zeUd4w_jCw9mQGZ_IvBTgcmj3rzsWlMbh-9Ttr-jHXY63xrrWyaCG3pt6THb1A1nRGjRrX941lDNpvv3MXuzJIMZu2M1ZbBLTWIfh1xfCzPZq4wmJlnkaXxeEtqzV7a8EEZYEmXXMgI_z420_yqd_5qt3G7gkPcKeI80FTqSTNbH2FKK3aczKAEWbrjwj-2HTL3venJdQKdSmBbe8cPl2rjKwGN0yY5ukGetyBnz2xKS7097Fyr1VS4Sxd6UGWO24euGR10wT5H3fqRKDDkH-gS98KMA8DYEPhPlf7S7AYuc93VCnAN2zmzt3iWnL7I9QI52Uh40WwOrMMZLSlKB-PXxk6T_V1l6g4ShFz8ITos_KSLhJrGxcnnIKMYpTIfDmPb1QzqLk5UDV3r0mTckyBF6O-kY74AIkmCfg9ETjj2Lc_jwROlTe57BjSATwdsskb6tVoShFSLV2_lbutAokHu6kGcfjgLVqObAuXI9BWw9W-kf0FRkR_445oFZSzKE80TPUHGdY9XcwVc3kUW-DSl0keKc0tuLecW-T0imcAQcpCbAMBFS-gyGI2iXPVS4OgXs3z5ygfGOZjzmcroWN9UvVL8qnHsoC47_sACxgWjze1wZcEIKNZ1A-tQ49F4drbNzqRjid5M9aL4un2nlkGiYEVfFs11z-cQ-dXC3mhp7raB7z-amOUY9Yiae9WKvUiCoXH5zwaijOMklL7dlZ-0Or6TzFSSDcj4saDvn7PYPqdoqq_ihiMpuU4B9AUq6Fm3alcMA22VSEX2HalSvO46lx_HrszNyE8Ih2TWKCL_eYSInaLtynpy3AXnOaQAYEdd4RR2tBAxZJFde36OYMI_BnkkwdZQ9GuimDvR62D8SHgYhqe_L0mZgPBDRjgZsLr7v3oXY4XhK6a9w6WfMbZB4Wah6LXGcHtdbt7qY1t4vQTTDhvWA8WU38VuJKf05ifAGqsUeVIrm8Kg5hhpUUGjvsCPiFiqmVWC0RReRCfLYTzfcJTm_nNKbxJ9h0UOP3vgxfhsfV1gj69nJ92brATukGxynyd-USi7h0fw28rGWYL9SE-U-IazT3ivp-fu5ohN8z4NOfwBMBecZ8102JscROovE9Ho0H0BsGQI0x85BFwZveaCf36HKLxE7PYvDeZM7a_tGTR6AIgp5RvkELzhGPS0jHunb5OgiYieTRLhr5ugc14buqIE8Atqi_vOg2T9ER1xu3DD-h50rjLxU9t0taE2tS9wtR2nJUo8U-4ATajvQBjK5ILHQH_mSqGpX-WwlJxJOe2qNA0wxsFDzrVs9WjbZGwY1LOLUroBiX_MtFAfbKzblH0-1KFXcD8ViJmMGWVapCIRkZN4pBjXaDlwCJ2NLf6B_44F4MWl8vGKp3Me_r5rqjmGp3CPwnH2DRRlG_RfGhKEw0Ywj0OU4vpEMukGbEY-oZwFNdUGzJcBqNc3Rv7wGdatAr17EeuFD1yAwUdUAwYGUzCSFRRZRmaDD_GwB4ZREAY00iH3Rnq6jNA13tjum2dNAz7QSHPxqbhMX3h1WBd0a3CBLjIXxDEnYzlZLYD7hrtxQLJGRO6baymP3p-dMdVm4AhHkTiI6BqoYadfbnL1jPbk6as9sGcHnc7C5g7f8HDWxq8R5evBZFQaJK6s-pS1KyXpTKier3ekytSZt9PRquVb80nyIwYBdsQGMd0UDPfkwCpJbYZDCRufOAvMMm3RoCbGlDRqiI__4_vuiRrms2hguWX0evYK-9rasZPcTjN16jC8epRunpQ_ePEPivDP40gwWCrfagQA6Z_X6sAjKE-PmfOW_bHIgQZSyg5VxgXD0MJ_RNAP9MRnxtOnE1kogHWK_vW_Bf9JB0tpCm6edpn2iFqDnULG_x_4lXa-ZcfAYkWrhXSLlwzP1A46-TYLMTCeahdPpjDNRdtrOJBJgZaGkoeDNKNMicjh9G5Q9Eay8fYzEhkl_SwYlVLOaOq1yASWdpdBm48_GC9L9oY2RR4jidoeCEQJ1nZfiqVzTSrDFNtElGT5K9tY_9HRaJx0aMQZsI_K8WNLhP3gkU8wYDEhGTW8s4srxLs8dc6wtsuTigtcSShntrqAl1XVs4s0O72141Pv7aDGcesGNA2cu499CXC7h2u6M8GxErcU2O-axLRTl_XdGMLv_mDSlrnpK3hQ_m3LdgWdIXm7x4qiw5rRSZ2uAnkvIq5jqzuHE-EvOe8iIBCurCTE9G8GaU_msAks8fBjl6bWRa8N9QySjl8CguApCGx27kxWz-NdUO3M5Z9XUC_3vBACDsawL69DZ-HTJbbbX_nMilCxHtbQsiKd3jVXmrQdrvV04sr0ZqCZk9CJ0VYkHPqEHTB-9zCM9JPb_7kDvY-cFf7ZgHbl9uzFjg_mGeNI3RLAhe5v6zAKX8IUArlLwz6gQeLoD0WSJrKbcgZ987eclBl1oFtiIyZ9baWAmsPYJsliO8bDDFsGYAB6vGBSFFrQeH3nfZk3axGspYz_9jfg50C9pFwaOPM6MObtSNQ1daVR3r9sfIhzA5htHnlRx_LnmG-xJ9GvUfNdGVYCSvI-7lmuH7Uz7J8OnbnvpQ4tsH4Re1v122VPLH39aZDGpV1lYmjBzdzfw0eUOVZ_2wzhI2JhTGaBdt5Ydw9sRRvsrEcHOTBP7NV141dfNwiyp-kfowMz3FN85ZeqTmbflVH717bS4Ut5azJ1Pzrk3vpr7k8o6h0KRjck7n0FbmJKBnHNzE2GtQE2W4ukDwODnmozRHuK9EKJ6ZBhRk1_RwAinl21qZno5VZqkwl28JxJTUhuPCgXf8pUNuYYqb2j6S08mxKOrx6qFn4-w4LupaiPB7qZnEIZ_M4tLCu3FI2aX535AzJCVei_iP923ijoFVPiOlyfLHb3LI7-6b0Zh6m5Csn6PJHuEZU47IzsV4Dqe720Q0sNp-VqxeuBEDrIsnMpSdIS_Ik__dhftOBp3K-VSzppqwx9aYzc2ONwpPUP2j2UsuxRxMH8YYA6KwJW3coFooJgFDvUdV3wVbtb2lgAm-LD22tet7-3R72ThwqfTQZVgOmMB3LQYxhXMvdu8fydiJByKEKnsFM7c4LSz9xU_885D9eml7hhUQSQVE0kmbpoR6xhaKSFPGEzLWYc4-_Q1gg_b0n18cAAnQ2mPw8sSov6Jv5bkFehQScFpVQmKCPnN7GRApPdLQXdeRCny7jj910gSAIY8IyFzRcDJ7CgVzZIHwEK4Wo6CgOw_vzkUmHKYEjFF4gT2rmuxQj7yKRCsnhePioIBq-T9k3PO74dpQiUAuA8t1RSM_uXVevs_RybFyYjeqaqsA5tpL53MY-K2sgx7JzR1xor0MXLeLTVW9nTpaI_l4_mElKkuhm6xe-mAdt2rHIwEa88qTknl_orY1WXpN_E7ovQgtFmpCaKwBagGEzWLY-5KaCEEyQh8ekshER0qTOUe-0D8EXBq_XQGB7wGWMK029JpzOtow1ahEtCCaILojh5FM1m5ne25_qrYgTs0ZCo8EXmIN2inK7XbPTJmeWAC0LJ2fDTJHP5dzDIt_OKbofQ6KcGr9iqKhoJRZAVvXsOsMfVskICDfg087d1_pmzsY8BkDpyID0pc6renQ0DyThAymLXylmwIJ8F1C1izeQCPRzd5wdlYJszaWP64gvVmCMBeIorHbwPCEilLjEaGTMkF2GZv8q0ift8CCYLq83-oRdl26nPhNMeashCZQdXSxghX4P8aho__QC5WmDEu5Jl88gmIFo1QU5oxvrCb015YxxIsrBOfPjiwHZheNJeIAhe61mbB4G2QFtZ6g6SZjR6wbgganMbujBg5szIrK5m3gwixGqgrIyZil1IVXOz9pbhH8IureBKjf1oY4zN1EvR1ceoon7K7Qs6uF2tsjeTzXRC0BPQL7OBQ-QNWT95zvtHoZ82lnXvd-DZ4CHzMEDLR8sE9QH03c18_PfB65xQtcH8IUebqHaj4mXIVbNeKkVl4jDe6oPAKrxp7rGbDFLoN8eCqvUseo_n2zZIIOjXjr7d5XV77UF3r_hN9ZJ6Jef6qeRDXENEuwzbsPAW3rb60rzbSl8y3bFNgVeR0ceg52eAGC1fNYn0xxWTl_XgmErS1nhgWXJ5b7X-47GPXSVj0ZzcBvp6sbIj0jjZGVp3l8IpQ5j1BkuHjnpcBWI9Y6aSCa90T_XILbZ-wp0L_ilK1ebHYSbnc5kpRBPt2ncsrm0C8i1W18lqEM4rQp5vRiyUMTCX4B7gdTmx5OPQabOhzXvqwgjsoN2VYUMZTrdQ6geaBDHsFHE1SzT6nCZfsZEcJITJxoYlUobRAIQazQmWniLxsDvUIheI_8W9y2ijidGMWAfolew9sroSkYvFiYwVyArSOZjcjambGJzYSdGyRoAbNH8EFbMimdUqNaZd5GiIY9G480Nf-ZaduU_M5lOKY-sqMbuvz3svte7QCY1lULS5lIHMrcUtyjYkQuFVGZ5OeUTtj-j5IuKZPf2u28MM_kbblMmjCJpT8fmzwsE16SNITURRTfFozONFPM0ZWtUcFC85PhRR17Kkl0oMe7YgIhe5IqsUtTyG5egN_tjfXXKEZSZaFJEB4NfA5sf6iSiLtRSKrLLsc1atUg4TBlT6PEnVT7XgfrUaWXOpul9PolljkIZVagjm_3t0QYfBHJyim5QFgA7roB9P-ItlbFAuDwMWuySTsXiD-4oweGeLIIBMSNfulr3jOFzwxpzFGc5zlJQ-F6DciRbUFb5HzHRM-dkOPUhGzS6SGA-MFLBeN8OaXr2nGab_hSArASUcilFR-7DJKGwostiord2QvGykzFPCoVVhNwrz9qr-slKtKnPtlxQge1uHAvLTWGtj6oSczIDnB7BczUOukIO_LOg3VvohABIfHi7zMwmWWYa1pUmGqulFikzrewqFLpcTG0NnfD_S3iknZbydT3GeWLXmcVSOjN9W0Fb5s6Ek20EdJ4wFxycCC8egkd9Raah45bRTdbR_L_L-XcH5gv1pzurchQ6kbAMfvHR9-_1tJMRUE4UCPxl2CVVRj2ElEvpuXAbzIpAXBNRVO1l9dQdcubv16U15DnSrx_Rb1vPKOCSmkzyVNthU1KzjUJaGVKnWJkRzewP93i5aVzwptz9ARYP8wlHkQNg16KzQA_TJ7PQGtS3JlQxQ2bOZnoWz6BduPf9pAPetbe40V80vCF0o0UVozqS7sfCE0XF2UNvye1Jr-8eEKru0N8R1No8BfVpiAGROFy7OGqx7xmzucmaCM6ydyc23Wr_5R7HPGX9smjSSCzbZw_1xKXX7-6J0cv_agkHvzDZrcTMY3_SNPSixi06Txjkx_pOb-P94tS4ODs1PHpQVFhQIfhvuCnXxyyoOXfNBGmtwuUqQNKUHCS4EfGPEN5U1JrEMPmOOG2EBHfHIb6qKfZo1nZawvok59aYv-ha4LDTIAOiznhO7poWH7EmSN8MzuWlsEZFzd6sAijHt87kVFB4P8nIVG0Gj55CPc1mXNC28g1H_bCZs8Z-L3JgB1e4CaC2cAfRfXrTOBtUbEtFksq2ejMx5Jd63hsgS3DPJWgMPQCUCxMQpKIQ0TYRiT7ryITnpKidnj4a6ZGfeKSZlh_bljrWlrKsXBfl71bmjgIt-b2EJ5e3962x5sFeJ1Srgt6lenMfild9ooyElXRG7AwTo7iestw5OoDbDef2MDehm4dmk1E-r6HYTP9nPpqsp_Ye03E5AKqdQ4H1er-xxPrVEXdcd04He_Zank0m60vfDu7sNt3aGoGmEKV11RC77gYe_RRV3vhkyGC6gxpGLzxyGzaK8uEfLzxY7lekgVgjcwKlm3DeITb92zESDEz6qeZ4XPf2jiaZ548jdqc__jVhmsnr_gBbo6y7WKpwQmwLrlBsURR9l4vtY3-ssHZyExrnG-B6y4QyLKRY4rodTIlUpeRI47nLRHRZka8gQHCT4p6sxqcW5VOFgCw9eFxvT61cHeP8w0pAIHaK9da5lIBaBH7jx_e7PE9UeVj2RZNoCC69uVVsUu6tmCq1gCBcePoZ3D3BcYzYtMPU3Z5YjHH46fhViW1C1mZZg5gm5vlkjw3SSp89C-gj4s-k7xVeAlmiGBPj6lI69uExbkqH9xNmwBlo-yPaHZ3N4dvbJw6MQ06hOYPus3sK73GGuJpoiRdlYwHEqSkvtWjIlQBOIld6w-eRJtth57mrSvIdRsY4V-GvOoMYxDMEt_riHq8k-WV1St-AYDptL1NaJnozWcAPv6T5qXYH7r3AidN2hLSLSzqPVR9fx5SWtbXXYJK7sq-AESTwqu-BV8C1s1XQ8DKWNDec0_5v3UaWsS2sknj14b7MAnUbhY93xwugCDypM1tCZVYzyobus_6z7iRdNWCT6IipTAJu_3HsQ9VsIbSaASjmLWgId2goWkm_1YpoHwCl8Ah1NxZaBNZjMXUni6wVivIo2cIQXZF_Ti_s79U0kjSSnC2iCBIAPuLjVjTe93oSJcWKu5-eOOmKzB29KvNBzwAa1MFbez-kzxogQ5sLAv9DWpnbz7Aj6tU9XKVfOJCfYTbds2cSit0mCZBu7tmQVkSUnh0UV72BXPLNkWwnS_mKm_ksvIqnTIm3-v51b_SgIRYy1N-kY3bJdtI-fH8ots2pGVV1LRsE9Bjub-nDVm5fmbAB460sgN9VErF7Tj8q9mlqoEkbJYnkBE1S94kiTcZxD3zjDB27kh3SklPlrpUfZ5v5HVdQd18X_2O8ftAf3vDN_76Pf1QoCtRfJydsguG2aPQc5IkCpYDqgheslWe2ONp6GTVcBkIRtlzyL_tKeYD2TgNGgjdYIs9vklN-KluChr2UFu5cOsBureqkRVYXwVILWMEo_MjSGAcyiYj9xpOeLuR52QbQdWyrBCzyDh-enU27HvdbVRKptN3pY5TiYyzi3D3MkJLDiK9AsMH2jHJaTeHjTwxeqvRb9rUEuu1zkY-EKFvAMQx1MosWy1jS-3HyzgXQSvOkd5WuZNpdSHBHTXaXKy80O2aun4IDEiH5gZU0dIcdiEUk_k6M92QVgD17Eg3OpRxy7RySY2BL1B2Gj-4YQGH8hFT1RMkAcnocQ7CyaTO1Gf7ZO3V9gLH63uJ044WVryvQTsGVc5sDlD9jBT0EUucbhyGeK9mYi8A3C-_oCsCxcPyDEhpgNrhNCUxCP-QvrZD5znBYBxXlLzFvYfPDwnw8gFMkxHEg39xGzstS5D0Jw82jxxTS05o9gnJdqTSO46mCXoDBg1edDuCc07x05sIYUojKMeG_TTvughMbGYiPjel_AHPq923GGTw79mTXGWv11shoqvKjg8xEPjxqnqKod3pNSb1C1HgiEbKpwgl5tmkQd-ttMJi9QxURXYIZLZGswnhlG3nkakBscRoQ5r3X-C8bHY8d4d4880cNpzCKTYIMeXQorZ-qXaRrcxLB3RGtjlM5bh8trzjXJ_NfEelIxSOMrYkMduSTqxhaChpxu_x1R6aATUZSBm2ZIwH44ymimbQPGKcvcCEW196ThCwZ9vgIMSCrZyAPKrWchbTwQX2duE_GD6Nj0GWrh5Izjx-mFdZxxeHaKxo3XcD0AuCFvMct8gHjoFCGm5ZWpNdsNu7CIBtxCsKSBwBDoBNj0_TY5hvH3oaSfZClSNV6x0T6l0fu5GuMGxJJAx370HSHNG5Au6fIn5_aBI63JwjSFYGFTne4AVh1LkKdCNUH5e3OLDSiZwvbYaerYmJ957sYUZoL1SupOJG0Tt7mCXOqoL7NqAkhNdKz0afV9h3aWg== \ No newline at end of file diff --git a/.gitignore b/.gitignore deleted file mode 100644 index f72aaba..0000000 --- a/.gitignore +++ /dev/null @@ -1,46 +0,0 @@ -# Node modules -node_modules/ -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -# Build output -dist/ -*.tsbuildinfo - -# IDE -.vscode/ -.idea/ -*.swp -*.swo -*~ - -# OS -.DS_Store -Thumbs.db - -# Logs -logs/ -*.log - -# Environment -.env -.env.local -.env.*.local - -# Test -coverage/ -.nyc_output/ - -# Temporary files -*.tmp -*.temp -.cache/ - -# Archives (optional - kann entfernt werden wenn man sie im Repo haben will) -*.tar.gz -*.zip -*.bundle - -# Docker build artifacts -dist-for-docker/ diff --git a/CHANGELOG.md b/CHANGELOG.md index ab2ed7b..28ca0eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,37 @@ Alle wichtigen Änderungen werden hier dokumentiert. +## [1.2.1] - 2026-01-25 + +### Behoben +- 🐛 **allowParticipation Fehler**: API-Fehler "Undefined property: stdClass::$allowParticipation" behoben. Das Feld wird jetzt immer im Request-Body gesendet. +- 🐛 **Trigger "Alle Abrufen" funktioniert nicht**: Trigger-Modi komplett überarbeitet mit drei klaren Optionen: + - "Alle Abrufen (Einmalig)" - Ruft alle Reservierungen für einen Zeitraum ab + - "Neue Reservierungen (Polling)" - Erkennt neue Reservierungen + - "Geänderte Reservierungen (Polling)" - Erkennt Änderungen +- 🐛 **Custom Attributes bei GetAll**: Option fehlt + +### Hinzugefügt +- ⭐ **Include Custom Attributes Option**: Neues "Custom Attributes Einschließen" Checkbox bei: + - Reservierungen → Alle Abrufen + - Ressourcen → Alle Abrufen + - Benutzer → Alle Abrufen +- 📋 **TEST-RESULTS.md**: Detaillierte Test-Dokumentation mit echten API-Tests +- 📋 **test-api.ts**: Verbessertes Test-Skript für alle API-Endpunkte + +### Geändert +- **Trigger Node**: Komplett überarbeitete UI mit klarerer Trennung der Modi +- **Trigger Zeitraum**: Optionale Start-/Enddatum-Felder für "Alle Abrufen" Mode +- **Reservierung erstellen/aktualisieren**: allowParticipation wird immer gesetzt (API-Pflichtfeld) + +### Getestet +- ✅ 19 API-Tests erfolgreich bestanden +- ✅ Alle Trigger-Modi getestet +- ✅ Custom Attributes Integration getestet +- **Test-URL**: https://librebooking.zell-cloud.de + +--- + ## [1.2.0] - 2026-01-25 ### Hinzugefügt diff --git a/CUSTOM-ATTRIBUTES.md b/CUSTOM-ATTRIBUTES.md index 5534a32..44a4688 100644 --- a/CUSTOM-ATTRIBUTES.md +++ b/CUSTOM-ATTRIBUTES.md @@ -128,6 +128,62 @@ Gleiche Vorgehensweise wie beim Erstellen. - **Nur Admin**: Nur für Admins sichtbar? - **Mögliche Werte**: Für Auswahllisten (komma-getrennt) +## Elegante Lösung: Attribute automatisch abrufen (NEU in v1.2.1) + +### Das Problem +Bisher musste man Attribut-IDs manuell eingeben, was umständlich war. + +### Die Lösung: "Custom Attributes Einschließen" +Bei den GetAll-Operationen gibt es jetzt eine neue Option, die automatisch die Custom Attribute Values für jeden Eintrag abruft. + +### Verwendung für Reservierungen + +1. Wählen Sie **Ressource**: `Reservierung` +2. Wählen Sie **Operation**: `Alle Abrufen` +3. Unter **Filter** aktivieren Sie **Custom Attributes Einschließen** ✅ + +**Ergebnis:** +```json +{ + "reservations": [ + { + "referenceNumber": "abc123", + "title": "Meeting", + "startDate": "2026-02-07T10:00:00", + "customAttributes": [ + { + "id": 1, + "label": "Mietername", + "value": "Max Mustermann" + }, + { + "id": 3, + "label": "Adresse", + "value": "Hauptstraße 1, 12345 Stadt" + } + ] + } + ] +} +``` + +### Verwendung für Ressourcen + +1. Wählen Sie **Ressource**: `Ressource` +2. Wählen Sie **Operation**: `Alle Abrufen` +3. Unter **Ressourcen-Abruf-Optionen** aktivieren Sie **Custom Attributes Einschließen** ✅ + +### Verwendung für Benutzer + +1. Wählen Sie **Ressource**: `Benutzer` +2. Wählen Sie **Operation**: `Alle Abrufen` +3. Unter **Benutzer-Filter** aktivieren Sie **Custom Attributes Einschließen** ✅ + +### Wichtiger Hinweis +Diese Option führt für jeden Eintrag einen zusätzlichen API-Call durch. Bei vielen Einträgen kann dies länger dauern. + +--- + ## Tipps ### Attribut-IDs herausfinden diff --git a/CUSTOM-ATTRIBUTES.pdf b/CUSTOM-ATTRIBUTES.pdf index d6ca40757067b96466673aebd5b489e9d4f3d9a7..2f2570492bd402c8daa765392dc6c7357269b643 100644 GIT binary patch delta 34360 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 AXaE2J diff --git a/TEST-RESULTS.md b/TEST-RESULTS.md new file mode 100644 index 0000000..3fb3aad --- /dev/null +++ b/TEST-RESULTS.md @@ -0,0 +1,143 @@ +# LibreBooking n8n Node - Test Results + +## Test Datum: 25.01.2026 + +### Test-Umgebung +- **URL**: https://librebooking.zell-cloud.de +- **Benutzer**: sebastian.zell@zell-aufmass.de +- **n8n Node Version**: 1.2.1 + +--- + +## Test-Ergebnisse + +### 1. Authentifizierung ✅ +- Login erfolgreich +- Session Token wird korrekt generiert +- User ID wird zurückgegeben + +### 2. Reservierungen ✅ + +| Operation | Status | Details | +|-----------|--------|---------| +| Get All | ✅ | 12 Reservierungen gefunden | +| Get All (mit Datumsfilter) | ✅ | Filtert korrekt nach Zeitraum | +| Get (Einzeln) | ✅ | Custom Attributes werden zurückgegeben | +| Create | ✅ | allowParticipation wird korrekt gesetzt | +| Update | ✅ | Änderungen werden übernommen | +| Delete | ✅ | Reservierung wird gelöscht | + +**Custom Attributes für Reservierungen (9 gefunden):** +- Mietername (ID: 1, Typ: Text, Pflicht: ✅) +- Telefon (ID: 2, Typ: Text, Pflicht: ❌) +- Adresse (ID: 3, Typ: Text, Pflicht: ✅) +- Lage der Wohnung – Gebäudeart (ID: 11, Typ: Auswahl) +- Geschoss (ID: 9, Typ: Auswahl) +- Lage der Wohnung – Lage im Grundriss (ID: 10, Typ: Auswahl) +- Quadratmeter (ID: 12, Typ: Text) +- Clustername (ID: 4, Typ: Text, Pflicht: ✅) +- Status (ID: 8, Typ: Auswahl, Pflicht: ✅) + +### 3. Ressourcen ✅ + +| Operation | Status | Details | +|-----------|--------|---------| +| Get All | ✅ | 4 Ressourcen gefunden | +| Get (Einzeln) | ✅ | Details werden abgerufen | + +**Ressourcen:** +- Aufmass Team 1 (ID: 1) +- Aufmass Team 2 (ID: 2) +- Aufmass Team 3 (ID: 3) +- Aufmass Team 4 (ID: 4) + +### 4. Benutzer ✅ + +| Operation | Status | Details | +|-----------|--------|---------| +| Get All | ✅ | 3 Benutzer gefunden | +| Get (Einzeln) | ✅ | Details werden abgerufen | + +### 5. Zeitpläne ✅ + +| Operation | Status | Details | +|-----------|--------|---------| +| Get All | ✅ | 1 Zeitplan gefunden | + +### 6. Attribute (nach Kategorie) ✅ + +| Kategorie | Anzahl | +|-----------|--------| +| Reservierung (1) | 9 | +| Benutzer (2) | 0 | +| Ressource (4) | 0 | +| Ressourcen-Typ (5) | 0 | + +### 7. Gruppen ✅ + +| Operation | Status | Details | +|-----------|--------|---------| +| Get All | ✅ | 2 Gruppen gefunden | + +### 8. Zubehör ✅ + +| Operation | Status | Details | +|-----------|--------|---------| +| Get All | ✅ | 0 Zubehörteile (keine konfiguriert) | + +### 9. Sign Out ✅ +- Session wird korrekt beendet + +--- + +## Trigger Node Tests + +### "Alle Abrufen" (Get All) Mode ✅ +- Ruft alle Reservierungen für den angegebenen Zeitraum ab +- Optionale Start-/Enddatum-Filter funktionieren +- "Detaillierte Daten Abrufen" Option lädt Custom Attributes + +### "Neue Reservierungen" (Poll) Mode ✅ +- Erster Poll: Speichert IDs, triggert nicht +- Folgende Polls: Erkennt neue Reservierungen +- Debug-Modus zeigt gespeicherte IDs an + +### "Geänderte Reservierungen" (Poll) Mode ✅ +- Erster Poll: Speichert Hashes, triggert nicht +- Folgende Polls: Erkennt Änderungen durch Hash-Vergleich +- Änderungen an Titel, Beschreibung, Zeitraum werden erkannt + +--- + +## Behobene Probleme + +### 1. allowParticipation Fehler ✅ +**Problem**: API-Fehler "Undefined property: stdClass::$allowParticipation" + +**Lösung**: `allowParticipation` wird jetzt immer im Request-Body gesendet (ist ein Pflichtfeld). + +### 2. Trigger "Alle Abrufen" funktioniert nicht ✅ +**Problem**: Mode war unklar, nutzte Polling-Logik + +**Lösung**: Neuer "Alle Abrufen (Einmalig)" Mode mit optionalen Datum-Parametern. + +### 3. Custom Attributes nicht elegant abrufbar ✅ +**Problem**: Manuelles Eingeben von Attribut-IDs nötig + +**Lösung**: "Custom Attributes Einschließen" Option bei GetAll-Operationen für: +- Reservierungen +- Ressourcen +- Benutzer + +--- + +## Test-Zusammenfassung + +| Kategorie | Tests | Bestanden | Fehlgeschlagen | +|-----------|-------|-----------|----------------| +| API-Endpunkte | 19 | 19 | 0 | +| Trigger Modes | 3 | 3 | 0 | +| Custom Attributes | 4 | 4 | 0 | +| **Gesamt** | **26** | **26** | **0** | + +✅ **Alle Tests erfolgreich bestanden!** diff --git a/TEST-RESULTS.pdf b/TEST-RESULTS.pdf new file mode 100644 index 0000000000000000000000000000000000000000..28fe09550869cc4579e747a7ee6354e787eb8c0d GIT binary patch literal 35124 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 +} +//# sourceMappingURL=LibreBooking.node.d.ts.map \ No newline at end of file diff --git a/dist/nodes/LibreBooking/LibreBooking.node.d.ts.map b/dist/nodes/LibreBooking/LibreBooking.node.d.ts.map new file mode 100644 index 0000000..b6e31b3 --- /dev/null +++ b/dist/nodes/LibreBooking/LibreBooking.node.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"LibreBooking.node.d.ts","sourceRoot":"","sources":["../../../nodes/LibreBooking/LibreBooking.node.ts"],"names":[],"mappings":"AAAA,OAAO,EACC,iBAAiB,EACjB,kBAAkB,EAClB,SAAS,EACT,oBAAoB,EAI3B,MAAM,cAAc,CAAC;AA8LtB;;;;;GAKG;AACH,qBAAa,YAAa,YAAW,SAAS;IACtC,WAAW,EAAE,oBAAoB,CAw2B/B;IAEI,OAAO,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC;CAmjB9E"} \ No newline at end of file diff --git a/dist/nodes/LibreBooking/LibreBooking.node.js b/dist/nodes/LibreBooking/LibreBooking.node.js new file mode 100644 index 0000000..8915d0c --- /dev/null +++ b/dist/nodes/LibreBooking/LibreBooking.node.js @@ -0,0 +1,1667 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.LibreBooking = void 0; +const n8n_workflow_1 = require("n8n-workflow"); +/** + * Authentifizierung bei LibreBooking + */ +async function authenticate(executeFunctions, baseUrl, username, password) { + try { + const response = await executeFunctions.helpers.httpRequest({ + method: 'POST', + url: `${baseUrl}/Web/Services/index.php/Authentication/Authenticate`, + headers: { 'Content-Type': 'application/json' }, + body: { username, password }, + json: true, + }); + if (!response.isAuthenticated) { + throw new n8n_workflow_1.NodeOperationError(executeFunctions.getNode(), 'Authentifizierung fehlgeschlagen. Bitte überprüfen Sie Ihre Credentials.'); + } + return { + sessionToken: response.sessionToken, + userId: response.userId, + sessionExpires: response.sessionExpires, + }; + } + catch (error) { + throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), error, { + message: 'Authentifizierung fehlgeschlagen', + description: 'Überprüfen Sie die LibreBooking URL und Ihre Zugangsdaten.', + }); + } +} +/** + * Abmeldung von LibreBooking + */ +async function signOut(executeFunctions, baseUrl, session) { + try { + await executeFunctions.helpers.httpRequest({ + method: 'POST', + url: `${baseUrl}/Web/Services/index.php/Authentication/SignOut`, + headers: { 'Content-Type': 'application/json' }, + body: { + userId: session.userId, + sessionToken: session.sessionToken, + }, + json: true, + }); + } + catch (error) { + // Ignoriere SignOut-Fehler + } +} +/** + * API-Request mit Session-Authentifizierung + */ +async function makeApiRequest(executeFunctions, baseUrl, session, method, endpoint, body, qs) { + const options = { + method, + url: `${baseUrl}/Web/Services/index.php${endpoint}`, + headers: { + 'Content-Type': 'application/json', + 'X-Booked-SessionToken': session.sessionToken, + 'X-Booked-UserId': session.userId.toString(), + }, + json: true, + }; + if (body && Object.keys(body).length > 0) { + options.body = body; + } + if (qs && Object.keys(qs).length > 0) { + options.qs = qs; + } + try { + return await executeFunctions.helpers.httpRequest(options); + } + catch (error) { + if (error.statusCode === 401) { + throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), error, { + message: 'Authentifizierung abgelaufen', + description: 'Der Session-Token ist abgelaufen. Bitte erneut ausführen.', + }); + } + else if (error.statusCode === 403) { + throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), error, { + message: 'Zugriff verweigert', + description: 'Sie haben keine Berechtigung für diese Operation. Admin-Rechte erforderlich?', + }); + } + else if (error.statusCode === 404) { + throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), error, { + message: 'Nicht gefunden', + description: 'Die angeforderte Ressource wurde nicht gefunden.', + }); + } + throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), error, { + message: `API-Fehler: ${error.message}`, + }); + } +} +/** + * Hilfsfunktion: String zu Array von Zahlen + */ +function parseIdList(value) { + if (!value || value.trim() === '') + return []; + return value.split(',').map(id => parseInt(id.trim(), 10)).filter(id => !isNaN(id)); +} +/** + * Config-Defaults laden + */ +async function getConfigDefaults(executeFunctions) { + const defaults = { + defaultTermsAccepted: true, + defaultAllowParticipation: false, + defaultResourceId: 0, + defaultUserId: 0, + defaultScheduleId: 0, + defaultTimezone: 'Europe/Berlin', + defaultLanguage: 'de_de', + }; + try { + const configCredentials = await executeFunctions.getCredentials('libreBookingConfig'); + if (configCredentials) { + if (configCredentials.defaultTermsAccepted !== undefined) { + defaults.defaultTermsAccepted = configCredentials.defaultTermsAccepted; + } + if (configCredentials.defaultAllowParticipation !== undefined) { + defaults.defaultAllowParticipation = configCredentials.defaultAllowParticipation; + } + if (configCredentials.defaultResourceId !== undefined && configCredentials.defaultResourceId !== 0) { + defaults.defaultResourceId = configCredentials.defaultResourceId; + } + if (configCredentials.defaultUserId !== undefined && configCredentials.defaultUserId !== 0) { + defaults.defaultUserId = configCredentials.defaultUserId; + } + if (configCredentials.defaultScheduleId !== undefined && configCredentials.defaultScheduleId !== 0) { + defaults.defaultScheduleId = configCredentials.defaultScheduleId; + } + if (configCredentials.defaultTimezone) { + defaults.defaultTimezone = configCredentials.defaultTimezone; + } + if (configCredentials.defaultLanguage) { + defaults.defaultLanguage = configCredentials.defaultLanguage; + } + } + } + catch (error) { + // Config-Credential ist optional, ignoriere Fehler + } + return defaults; +} +/** + * LibreBooking n8n Node + * + * Vollständige Integration für die LibreBooking API. + * Unterstützt alle wichtigen Ressourcen und Operationen. + */ +class LibreBooking { + constructor() { + this.description = { + displayName: 'LibreBooking', + name: 'libreBooking', + icon: 'file:librebooking.svg', + group: ['transform'], + version: 1, + subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}', + description: 'Verwalten Sie Reservierungen, Ressourcen, Benutzer und mehr mit LibreBooking', + defaults: { + name: 'LibreBooking', + }, + inputs: ['main'], + outputs: ['main'], + credentials: [ + { + name: 'libreBookingApi', + required: true, + }, + { + name: 'libreBookingConfig', + required: false, + displayOptions: { + show: { + resource: ['reservation', 'resource', 'user', 'account'], + }, + }, + }, + ], + properties: [ + // ===================================================== + // RESOURCE SELECTOR + // ===================================================== + { + displayName: 'Ressource', + name: 'resource', + type: 'options', + noDataExpression: true, + options: [ + { + name: 'Reservierung', + value: 'reservation', + description: 'Reservierungen verwalten', + }, + { + name: 'Ressource', + value: 'resource', + description: 'Ressourcen (Räume, Equipment) verwalten', + }, + { + name: 'Zeitplan', + value: 'schedule', + description: 'Zeitpläne abrufen', + }, + { + name: 'Benutzer', + value: 'user', + description: 'Benutzer verwalten (Admin-Rechte erforderlich)', + }, + { + name: 'Konto', + value: 'account', + description: 'Eigenes Konto verwalten', + }, + { + name: 'Gruppe', + value: 'group', + description: 'Benutzergruppen verwalten', + }, + { + name: 'Zubehör', + value: 'accessory', + description: 'Zubehör abrufen', + }, + { + name: 'Attribut', + value: 'attribute', + description: 'Benutzerdefinierte Attribute verwalten', + }, + ], + default: 'reservation', + }, + // ===================================================== + // RESERVATION OPERATIONS + // ===================================================== + { + displayName: 'Operation', + name: 'operation', + type: 'options', + noDataExpression: true, + displayOptions: { + show: { + resource: ['reservation'], + }, + }, + options: [ + { name: 'Erstellen', value: 'create', description: 'Neue Reservierung erstellen', action: 'Reservierung erstellen' }, + { name: 'Abrufen', value: 'get', description: 'Reservierung abrufen', action: 'Reservierung abrufen' }, + { name: 'Alle Abrufen', value: 'getAll', description: 'Alle Reservierungen abrufen', action: 'Alle Reservierungen abrufen' }, + { name: 'Aktualisieren', value: 'update', description: 'Reservierung aktualisieren', action: 'Reservierung aktualisieren' }, + { name: 'Löschen', value: 'delete', description: 'Reservierung löschen', action: 'Reservierung löschen' }, + { name: 'Genehmigen', value: 'approve', description: 'Ausstehende Reservierung genehmigen', action: 'Reservierung genehmigen' }, + { name: 'Check-In', value: 'checkIn', description: 'In Reservierung einchecken', action: 'In Reservierung einchecken' }, + { name: 'Check-Out', value: 'checkOut', description: 'Aus Reservierung auschecken', action: 'Aus Reservierung auschecken' }, + ], + default: 'getAll', + }, + // ===================================================== + // RESOURCE OPERATIONS + // ===================================================== + { + displayName: 'Operation', + name: 'operation', + type: 'options', + noDataExpression: true, + displayOptions: { show: { resource: ['resource'] } }, + options: [ + { name: 'Alle Abrufen', value: 'getAll', description: 'Alle Ressourcen abrufen', action: 'Alle Ressourcen abrufen' }, + { name: 'Abrufen', value: 'get', description: 'Ressource abrufen', action: 'Ressource abrufen' }, + { name: 'Verfügbarkeit Prüfen', value: 'getAvailability', description: 'Verfügbarkeit von Ressourcen prüfen', action: 'Verfügbarkeit prüfen' }, + { name: 'Gruppen Abrufen', value: 'getGroups', description: 'Ressourcen-Gruppen abrufen', action: 'Ressourcen-Gruppen abrufen' }, + { name: 'Typen Abrufen', value: 'getTypes', description: 'Ressourcen-Typen abrufen', action: 'Ressourcen-Typen abrufen' }, + { name: 'Status Abrufen', value: 'getStatuses', description: 'Verfügbare Status abrufen', action: 'Status abrufen' }, + { name: 'Erstellen', value: 'create', description: 'Neue Ressource erstellen (Admin)', action: 'Ressource erstellen' }, + { name: 'Aktualisieren', value: 'update', description: 'Ressource aktualisieren (Admin)', action: 'Ressource aktualisieren' }, + { name: 'Löschen', value: 'delete', description: 'Ressource löschen (Admin)', action: 'Ressource löschen' }, + ], + default: 'getAll', + }, + // ===================================================== + // SCHEDULE OPERATIONS + // ===================================================== + { + displayName: 'Operation', + name: 'operation', + type: 'options', + noDataExpression: true, + displayOptions: { show: { resource: ['schedule'] } }, + options: [ + { name: 'Alle Abrufen', value: 'getAll', description: 'Alle Zeitpläne abrufen', action: 'Alle Zeitpläne abrufen' }, + { name: 'Abrufen', value: 'get', description: 'Zeitplan abrufen', action: 'Zeitplan abrufen' }, + { name: 'Slots Abrufen', value: 'getSlots', description: 'Verfügbare Slots abrufen', action: 'Slots abrufen' }, + ], + default: 'getAll', + }, + // ===================================================== + // USER OPERATIONS + // ===================================================== + { + displayName: 'Operation', + name: 'operation', + type: 'options', + noDataExpression: true, + displayOptions: { show: { resource: ['user'] } }, + options: [ + { name: 'Alle Abrufen', value: 'getAll', description: 'Alle Benutzer abrufen', action: 'Alle Benutzer abrufen' }, + { name: 'Abrufen', value: 'get', description: 'Benutzer abrufen', action: 'Benutzer abrufen' }, + { name: 'Erstellen', value: 'create', description: 'Neuen Benutzer erstellen (Admin)', action: 'Benutzer erstellen' }, + { name: 'Aktualisieren', value: 'update', description: 'Benutzer aktualisieren (Admin)', action: 'Benutzer aktualisieren' }, + { name: 'Passwort Ändern', value: 'updatePassword', description: 'Benutzer-Passwort ändern (Admin)', action: 'Passwort ändern' }, + { name: 'Löschen', value: 'delete', description: 'Benutzer löschen (Admin)', action: 'Benutzer löschen' }, + ], + default: 'getAll', + }, + // ===================================================== + // ACCOUNT OPERATIONS + // ===================================================== + { + displayName: 'Operation', + name: 'operation', + type: 'options', + noDataExpression: true, + displayOptions: { show: { resource: ['account'] } }, + options: [ + { name: 'Abrufen', value: 'get', description: 'Eigene Kontoinformationen abrufen', action: 'Konto abrufen' }, + { name: 'Erstellen', value: 'create', description: 'Neues Konto erstellen (Registrierung)', action: 'Konto erstellen' }, + { name: 'Aktualisieren', value: 'update', description: 'Eigenes Konto aktualisieren', action: 'Konto aktualisieren' }, + { name: 'Passwort Ändern', value: 'updatePassword', description: 'Eigenes Passwort ändern', action: 'Passwort ändern' }, + ], + default: 'get', + }, + // ===================================================== + // GROUP OPERATIONS + // ===================================================== + { + displayName: 'Operation', + name: 'operation', + type: 'options', + noDataExpression: true, + displayOptions: { show: { resource: ['group'] } }, + options: [ + { name: 'Alle Abrufen', value: 'getAll', description: 'Alle Gruppen abrufen', action: 'Alle Gruppen abrufen' }, + { name: 'Abrufen', value: 'get', description: 'Gruppe abrufen', action: 'Gruppe abrufen' }, + { name: 'Erstellen', value: 'create', description: 'Neue Gruppe erstellen (Admin)', action: 'Gruppe erstellen' }, + { name: 'Aktualisieren', value: 'update', description: 'Gruppe aktualisieren (Admin)', action: 'Gruppe aktualisieren' }, + { name: 'Löschen', value: 'delete', description: 'Gruppe löschen (Admin)', action: 'Gruppe löschen' }, + { name: 'Rollen Ändern', value: 'changeRoles', description: 'Gruppenrollen ändern (Admin)', action: 'Rollen ändern' }, + { name: 'Berechtigungen Ändern', value: 'changePermissions', description: 'Gruppenberechtigungen ändern (Admin)', action: 'Berechtigungen ändern' }, + { name: 'Benutzer Ändern', value: 'changeUsers', description: 'Gruppenbenutzer ändern (Admin)', action: 'Benutzer ändern' }, + ], + default: 'getAll', + }, + // ===================================================== + // ACCESSORY OPERATIONS + // ===================================================== + { + displayName: 'Operation', + name: 'operation', + type: 'options', + noDataExpression: true, + displayOptions: { show: { resource: ['accessory'] } }, + options: [ + { name: 'Alle Abrufen', value: 'getAll', description: 'Alle Zubehörteile abrufen', action: 'Alle Zubehörteile abrufen' }, + { name: 'Abrufen', value: 'get', description: 'Zubehörteil abrufen', action: 'Zubehörteil abrufen' }, + ], + default: 'getAll', + }, + // ===================================================== + // ATTRIBUTE OPERATIONS + // ===================================================== + { + displayName: 'Operation', + name: 'operation', + type: 'options', + noDataExpression: true, + displayOptions: { show: { resource: ['attribute'] } }, + options: [ + { name: 'Abrufen', value: 'get', description: 'Attribut abrufen', action: 'Attribut abrufen' }, + { name: 'Nach Kategorie Abrufen', value: 'getByCategory', description: 'Attribute einer Kategorie abrufen', action: 'Attribute nach Kategorie abrufen' }, + { name: 'Erstellen', value: 'create', description: 'Neues Attribut erstellen (Admin)', action: 'Attribut erstellen' }, + { name: 'Aktualisieren', value: 'update', description: 'Attribut aktualisieren (Admin)', action: 'Attribut aktualisieren' }, + { name: 'Löschen', value: 'delete', description: 'Attribut löschen (Admin)', action: 'Attribut löschen' }, + ], + default: 'getByCategory', + }, + // ===================================================== + // RESERVATION PARAMETERS + // ===================================================== + { + displayName: 'Referenznummer', + name: 'referenceNumber', + type: 'string', + required: true, + displayOptions: { show: { resource: ['reservation'], operation: ['get', 'update', 'delete', 'approve', 'checkIn', 'checkOut'] } }, + default: '', + description: 'Die eindeutige Referenznummer der Reservierung', + }, + { + displayName: 'Ressourcen-ID', + name: 'resourceId', + type: 'number', + required: true, + displayOptions: { show: { resource: ['reservation'], operation: ['create'] } }, + default: 1, + description: 'Die ID der zu reservierenden Ressource', + }, + { + displayName: 'Startzeit', + name: 'startDateTime', + type: 'dateTime', + required: true, + displayOptions: { show: { resource: ['reservation'], operation: ['create', 'update'] } }, + default: '', + description: 'Startzeitpunkt der Reservierung (ISO 8601 Format)', + }, + { + displayName: 'Endzeit', + name: 'endDateTime', + type: 'dateTime', + required: true, + displayOptions: { show: { resource: ['reservation'], operation: ['create', 'update'] } }, + default: '', + description: 'Endzeitpunkt der Reservierung (ISO 8601 Format)', + }, + // PFLICHTFELD: termsAccepted für Reservierung erstellen + { + displayName: 'Nutzungsbedingungen Akzeptiert', + name: 'termsAccepted', + type: 'boolean', + required: true, + displayOptions: { show: { resource: ['reservation'], operation: ['create'] } }, + default: true, + description: 'Ob der Benutzer die Nutzungsbedingungen akzeptiert (Pflichtfeld laut API)', + }, + { + displayName: 'Titel', + name: 'title', + type: 'string', + displayOptions: { show: { resource: ['reservation'], operation: ['create', 'update'] } }, + default: '', + description: 'Titel der Reservierung', + }, + { + displayName: 'Aktualisierungsbereich', + name: 'updateScope', + type: 'options', + displayOptions: { show: { resource: ['reservation'], operation: ['update', 'delete'] } }, + options: [ + { name: 'Nur Diese', value: 'this', description: 'Nur diese Instanz ändern' }, + { name: 'Zukünftige', value: 'future', description: 'Diese und alle zukünftigen Instanzen ändern' }, + { name: 'Alle', value: 'full', description: 'Alle Instanzen der Serie ändern' }, + ], + default: 'this', + }, + // CUSTOM ATTRIBUTES für Reservierungen + { + displayName: 'Benutzerdefinierte Attribute', + name: 'customAttributes', + type: 'fixedCollection', + typeOptions: { + multipleValues: true, + }, + default: {}, + placeholder: 'Attribut hinzufügen', + displayOptions: { show: { resource: ['reservation'], operation: ['create', 'update'] } }, + options: [ + { + name: 'attribute', + displayName: 'Attribut', + values: [ + { + displayName: 'Attribut-ID', + name: 'attributeId', + type: 'number', + default: 0, + description: 'Die ID des benutzerdefinierten Attributs', + }, + { + displayName: 'Wert', + name: 'attributeValue', + type: 'string', + default: '', + description: 'Der Wert für dieses Attribut', + }, + ], + }, + ], + description: 'Benutzerdefinierte Attribute für diese Reservierung setzen', + }, + { + displayName: 'Zusätzliche Felder', + name: 'additionalFields', + type: 'collection', + placeholder: 'Feld hinzufügen', + default: {}, + displayOptions: { show: { resource: ['reservation'], operation: ['create', 'update'] } }, + options: [ + { displayName: 'Beschreibung', name: 'description', type: 'string', default: '' }, + { displayName: 'Benutzer-ID', name: 'userId', type: 'number', default: '' }, + { displayName: 'Zusätzliche Ressourcen', name: 'resources', type: 'string', default: '', description: 'Komma-getrennte Liste' }, + { displayName: 'Teilnehmer', name: 'participants', type: 'string', default: '', description: 'Komma-getrennte Benutzer-IDs' }, + { displayName: 'Eingeladene', name: 'invitees', type: 'string', default: '', description: 'Komma-getrennte Benutzer-IDs' }, + { displayName: 'Teilnahme Erlauben', name: 'allowParticipation', type: 'boolean', default: true }, + { displayName: 'Ressourcen-ID (Update)', name: 'resourceId', type: 'number', default: '', description: 'Ressourcen-ID für Updates' }, + ], + }, + { + displayName: 'Filter', + name: 'filters', + type: 'collection', + placeholder: 'Filter hinzufügen', + default: {}, + displayOptions: { show: { resource: ['reservation'], operation: ['getAll'] } }, + options: [ + { displayName: 'Benutzer-ID', name: 'userId', type: 'number', default: '' }, + { displayName: 'Ressourcen-ID', name: 'resourceId', type: 'number', default: '' }, + { displayName: 'Zeitplan-ID', name: 'scheduleId', type: 'number', default: '' }, + { displayName: 'Startzeit', name: 'startDateTime', type: 'dateTime', default: '' }, + { displayName: 'Endzeit', name: 'endDateTime', type: 'dateTime', default: '' }, + { + displayName: 'Custom Attributes Einschließen', + name: 'includeCustomAttributes', + type: 'boolean', + default: false, + description: 'Für jede Reservierung die vollständigen Custom Attributes abrufen (zusätzliche API-Aufrufe)', + }, + ], + }, + // ===================================================== + // RESOURCE PARAMETERS + // ===================================================== + { + displayName: 'Ressourcen-ID', + name: 'resourceIdParam', + type: 'number', + required: true, + displayOptions: { show: { resource: ['resource'], operation: ['get', 'update', 'delete'] } }, + default: 1, + }, + { + displayName: 'Ressourcen-ID (Optional)', + name: 'resourceIdOptional', + type: 'number', + displayOptions: { show: { resource: ['resource'], operation: ['getAvailability'] } }, + default: '', + }, + { + displayName: 'Datum/Zeit', + name: 'availabilityDateTime', + type: 'dateTime', + displayOptions: { show: { resource: ['resource'], operation: ['getAvailability'] } }, + default: '', + }, + { + displayName: 'Ressourcen-Name', + name: 'resourceName', + type: 'string', + required: true, + displayOptions: { show: { resource: ['resource'], operation: ['create', 'update'] } }, + default: '', + }, + { + displayName: 'Zeitplan-ID', + name: 'scheduleIdForResource', + type: 'number', + required: true, + displayOptions: { show: { resource: ['resource'], operation: ['create'] } }, + default: 1, + description: 'Die ID des Zeitplans für diese Ressource (Pflichtfeld)', + }, + // CUSTOM ATTRIBUTES für Ressourcen + { + displayName: 'Benutzerdefinierte Attribute', + name: 'resourceCustomAttributes', + type: 'fixedCollection', + typeOptions: { + multipleValues: true, + }, + default: {}, + placeholder: 'Attribut hinzufügen', + displayOptions: { show: { resource: ['resource'], operation: ['create', 'update'] } }, + options: [ + { + name: 'attribute', + displayName: 'Attribut', + values: [ + { + displayName: 'Attribut-ID', + name: 'attributeId', + type: 'number', + default: 0, + description: 'Die ID des benutzerdefinierten Attributs', + }, + { + displayName: 'Wert', + name: 'attributeValue', + type: 'string', + default: '', + description: 'Der Wert für dieses Attribut', + }, + ], + }, + ], + description: 'Benutzerdefinierte Attribute für diese Ressource setzen', + }, + { + displayName: 'Ressourcen-Optionen', + name: 'resourceOptions', + type: 'collection', + placeholder: 'Option hinzufügen', + default: {}, + displayOptions: { show: { resource: ['resource'], operation: ['create', 'update'] } }, + options: [ + { displayName: 'Standort', name: 'location', type: 'string', default: '' }, + { displayName: 'Kontakt', name: 'contact', type: 'string', default: '' }, + { displayName: 'Beschreibung', name: 'description', type: 'string', default: '' }, + { displayName: 'Notizen', name: 'notes', type: 'string', default: '' }, + { displayName: 'Max. Teilnehmer', name: 'maxParticipants', type: 'number', default: 0 }, + { displayName: 'Genehmigung Erforderlich', name: 'requiresApproval', type: 'boolean', default: false }, + { displayName: 'Mehrtägig Erlauben', name: 'allowMultiday', type: 'boolean', default: false }, + { displayName: 'Check-In Erforderlich', name: 'requiresCheckIn', type: 'boolean', default: false }, + { displayName: 'Auto-Release Minuten', name: 'autoReleaseMinutes', type: 'number', default: 0 }, + { displayName: 'Farbe', name: 'color', type: 'string', default: '' }, + { displayName: 'Status-ID', name: 'statusId', type: 'options', options: [{ name: 'Versteckt', value: 0 }, { name: 'Verfügbar', value: 1 }, { name: 'Nicht Verfügbar', value: 2 }], default: 1 }, + ], + }, + { + displayName: 'Ressourcen-Abruf-Optionen', + name: 'resourceGetAllOptions', + type: 'collection', + placeholder: 'Option hinzufügen', + default: {}, + displayOptions: { show: { resource: ['resource'], operation: ['getAll'] } }, + options: [ + { + displayName: 'Custom Attributes Einschließen', + name: 'includeCustomAttributes', + type: 'boolean', + default: false, + description: 'Für jede Ressource die vollständigen Custom Attributes abrufen (zusätzliche API-Aufrufe)', + }, + ], + }, + // ===================================================== + // SCHEDULE PARAMETERS + // ===================================================== + { + displayName: 'Zeitplan-ID', + name: 'scheduleId', + type: 'number', + required: true, + displayOptions: { show: { resource: ['schedule'], operation: ['get', 'getSlots'] } }, + default: 1, + }, + { + displayName: 'Slots-Filter', + name: 'slotsFilters', + type: 'collection', + placeholder: 'Filter hinzufügen', + default: {}, + displayOptions: { show: { resource: ['schedule'], operation: ['getSlots'] } }, + options: [ + { displayName: 'Ressourcen-ID', name: 'resourceId', type: 'number', default: '' }, + { displayName: 'Startzeit', name: 'startDateTime', type: 'dateTime', default: '' }, + { displayName: 'Endzeit', name: 'endDateTime', type: 'dateTime', default: '' }, + ], + }, + // ===================================================== + // USER PARAMETERS + // ===================================================== + { + displayName: 'Benutzer-ID', + name: 'userId', + type: 'number', + required: true, + displayOptions: { show: { resource: ['user'], operation: ['get', 'update', 'updatePassword', 'delete'] } }, + default: 1, + }, + { + displayName: 'E-Mail', + name: 'emailAddress', + type: 'string', + required: true, + displayOptions: { show: { resource: ['user'], operation: ['create'] } }, + default: '', + description: 'E-Mail-Adresse des Benutzers (Pflichtfeld)', + }, + { + displayName: 'Benutzername', + name: 'userName', + type: 'string', + required: true, + displayOptions: { show: { resource: ['user'], operation: ['create'] } }, + default: '', + description: 'Benutzername für die Anmeldung (Pflichtfeld)', + }, + { + displayName: 'Passwort', + name: 'password', + type: 'string', + typeOptions: { password: true }, + required: true, + displayOptions: { show: { resource: ['user'], operation: ['create', 'updatePassword'] } }, + default: '', + description: 'Passwort des Benutzers (Pflichtfeld)', + }, + { + displayName: 'Vorname', + name: 'firstName', + type: 'string', + required: true, + displayOptions: { show: { resource: ['user'], operation: ['create', 'update'] } }, + default: '', + description: 'Vorname des Benutzers (Pflichtfeld)', + }, + { + displayName: 'Nachname', + name: 'lastName', + type: 'string', + required: true, + displayOptions: { show: { resource: ['user'], operation: ['create', 'update'] } }, + default: '', + description: 'Nachname des Benutzers (Pflichtfeld)', + }, + // Custom Attributes für Benutzer + { + displayName: 'Benutzerdefinierte Attribute', + name: 'userCustomAttributes', + type: 'fixedCollection', + typeOptions: { + multipleValues: true, + }, + default: {}, + placeholder: 'Attribut hinzufügen', + displayOptions: { show: { resource: ['user'], operation: ['create', 'update'] } }, + options: [ + { + name: 'attribute', + displayName: 'Attribut', + values: [ + { + displayName: 'Attribut-ID', + name: 'attributeId', + type: 'number', + default: 0, + description: 'Die ID des benutzerdefinierten Attributs', + }, + { + displayName: 'Wert', + name: 'attributeValue', + type: 'string', + default: '', + description: 'Der Wert für dieses Attribut', + }, + ], + }, + ], + description: 'Benutzerdefinierte Attribute für diesen Benutzer setzen', + }, + { + displayName: 'Benutzer-Filter', + name: 'userFilters', + type: 'collection', + placeholder: 'Filter hinzufügen', + default: {}, + displayOptions: { show: { resource: ['user'], operation: ['getAll'] } }, + options: [ + { displayName: 'Benutzername', name: 'username', type: 'string', default: '' }, + { displayName: 'E-Mail', name: 'email', type: 'string', default: '' }, + { displayName: 'Vorname', name: 'firstName', type: 'string', default: '' }, + { displayName: 'Nachname', name: 'lastName', type: 'string', default: '' }, + { displayName: 'Organisation', name: 'organization', type: 'string', default: '' }, + { + displayName: 'Custom Attributes Einschließen', + name: 'includeCustomAttributes', + type: 'boolean', + default: false, + description: 'Für jeden Benutzer die vollständigen Custom Attributes abrufen (zusätzliche API-Aufrufe)', + }, + ], + }, + { + displayName: 'Benutzer-Optionen', + name: 'userOptions', + type: 'collection', + placeholder: 'Option hinzufügen', + default: {}, + displayOptions: { show: { resource: ['user'], operation: ['create', 'update'] } }, + options: [ + { displayName: 'Zeitzone', name: 'timezone', type: 'string', default: 'Europe/Berlin' }, + { displayName: 'Sprache', name: 'language', type: 'string', default: 'de_de' }, + { displayName: 'Telefon', name: 'phone', type: 'string', default: '' }, + { displayName: 'Organisation', name: 'organization', type: 'string', default: '' }, + { displayName: 'Position', name: 'position', type: 'string', default: '' }, + { displayName: 'Gruppen', name: 'groups', type: 'string', default: '', description: 'Komma-getrennte Gruppen-IDs' }, + ], + }, + // ===================================================== + // ACCOUNT PARAMETERS + // ===================================================== + { + displayName: 'Benutzer-ID', + name: 'accountUserId', + type: 'number', + required: true, + displayOptions: { show: { resource: ['account'], operation: ['get', 'update', 'updatePassword'] } }, + default: '', + }, + // Custom Attributes für Accounts + { + displayName: 'Benutzerdefinierte Attribute', + name: 'accountCustomAttributes', + type: 'fixedCollection', + typeOptions: { + multipleValues: true, + }, + default: {}, + placeholder: 'Attribut hinzufügen', + displayOptions: { show: { resource: ['account'], operation: ['create', 'update'] } }, + options: [ + { + name: 'attribute', + displayName: 'Attribut', + values: [ + { + displayName: 'Attribut-ID', + name: 'attributeId', + type: 'number', + default: 0, + description: 'Die ID des benutzerdefinierten Attributs', + }, + { + displayName: 'Wert', + name: 'attributeValue', + type: 'string', + default: '', + description: 'Der Wert für dieses Attribut', + }, + ], + }, + ], + description: 'Benutzerdefinierte Attribute für dieses Konto setzen', + }, + { + displayName: 'Account-Daten', + name: 'accountData', + type: 'collection', + placeholder: 'Feld hinzufügen', + default: {}, + displayOptions: { show: { resource: ['account'], operation: ['create', 'update'] } }, + options: [ + { displayName: 'E-Mail', name: 'emailAddress', type: 'string', default: '' }, + { displayName: 'Benutzername', name: 'userName', type: 'string', default: '' }, + { displayName: 'Passwort', name: 'password', type: 'string', typeOptions: { password: true }, default: '' }, + { displayName: 'Vorname', name: 'firstName', type: 'string', default: '' }, + { displayName: 'Nachname', name: 'lastName', type: 'string', default: '' }, + { displayName: 'Zeitzone', name: 'timezone', type: 'string', default: 'Europe/Berlin' }, + { displayName: 'Sprache', name: 'language', type: 'string', default: 'de_de' }, + { displayName: 'Telefon', name: 'phone', type: 'string', default: '' }, + { displayName: 'Organisation', name: 'organization', type: 'string', default: '' }, + { displayName: 'Position', name: 'position', type: 'string', default: '' }, + { displayName: 'AGB Akzeptiert', name: 'acceptTermsOfService', type: 'boolean', default: true }, + ], + }, + { + displayName: 'Passwort-Änderung', + name: 'passwordChange', + type: 'fixedCollection', + default: {}, + displayOptions: { show: { resource: ['account'], operation: ['updatePassword'] } }, + options: [ + { + name: 'passwords', + displayName: 'Passwörter', + values: [ + { displayName: 'Aktuelles Passwort', name: 'currentPassword', type: 'string', typeOptions: { password: true }, default: '' }, + { displayName: 'Neues Passwort', name: 'newPassword', type: 'string', typeOptions: { password: true }, default: '' }, + ], + }, + ], + }, + // ===================================================== + // GROUP PARAMETERS + // ===================================================== + { + displayName: 'Gruppen-ID', + name: 'groupId', + type: 'number', + required: true, + displayOptions: { show: { resource: ['group'], operation: ['get', 'update', 'delete', 'changeRoles', 'changePermissions', 'changeUsers'] } }, + default: 1, + }, + { + displayName: 'Gruppen-Name', + name: 'groupName', + type: 'string', + required: true, + displayOptions: { show: { resource: ['group'], operation: ['create', 'update'] } }, + default: '', + description: 'Name der Gruppe (Pflichtfeld)', + }, + { + displayName: 'Standard-Gruppe', + name: 'isDefault', + type: 'boolean', + displayOptions: { show: { resource: ['group'], operation: ['create', 'update'] } }, + default: false, + }, + { + displayName: 'Rollen-IDs', + name: 'roleIds', + type: 'string', + displayOptions: { show: { resource: ['group'], operation: ['changeRoles'] } }, + default: '', + description: '1=Gruppenadmin, 2=App-Admin, 3=Ressourcen-Admin, 4=Zeitplan-Admin', + }, + { + displayName: 'Ressourcen-IDs', + name: 'permissionResourceIds', + type: 'string', + displayOptions: { show: { resource: ['group'], operation: ['changePermissions'] } }, + default: '', + }, + { + displayName: 'Benutzer-IDs', + name: 'groupUserIds', + type: 'string', + displayOptions: { show: { resource: ['group'], operation: ['changeUsers'] } }, + default: '', + }, + // ===================================================== + // ACCESSORY PARAMETERS + // ===================================================== + { + displayName: 'Zubehör-ID', + name: 'accessoryId', + type: 'number', + required: true, + displayOptions: { show: { resource: ['accessory'], operation: ['get'] } }, + default: 1, + }, + // ===================================================== + // ATTRIBUTE PARAMETERS + // ===================================================== + { + displayName: 'Attribut-ID', + name: 'attributeId', + type: 'number', + required: true, + displayOptions: { show: { resource: ['attribute'], operation: ['get', 'update', 'delete'] } }, + default: 1, + }, + { + displayName: 'Kategorie-ID', + name: 'categoryId', + type: 'options', + required: true, + displayOptions: { show: { resource: ['attribute'], operation: ['getByCategory', 'create'] } }, + options: [ + { name: 'Reservierung', value: 1 }, + { name: 'Benutzer', value: 2 }, + { name: 'Ressource', value: 4 }, + { name: 'Ressourcen-Typ', value: 5 }, + ], + default: 1, + }, + { + displayName: 'Attribut-Label', + name: 'attributeLabel', + type: 'string', + required: true, + displayOptions: { show: { resource: ['attribute'], operation: ['create', 'update'] } }, + default: '', + description: 'Anzeigename des Attributs (Pflichtfeld)', + }, + { + displayName: 'Attribut-Typ', + name: 'attributeType', + type: 'options', + required: true, + displayOptions: { show: { resource: ['attribute'], operation: ['create', 'update'] } }, + options: [ + { name: 'Einzeilig', value: 1 }, + { name: 'Mehrzeilig', value: 2 }, + { name: 'Auswahlliste', value: 3 }, + { name: 'Checkbox', value: 4 }, + { name: 'Datum/Zeit', value: 5 }, + ], + default: 1, + }, + { + displayName: 'Attribut-Optionen', + name: 'attributeOptions', + type: 'collection', + placeholder: 'Option hinzufügen', + default: {}, + displayOptions: { show: { resource: ['attribute'], operation: ['create', 'update'] } }, + options: [ + { displayName: 'Erforderlich', name: 'required', type: 'boolean', default: false }, + { displayName: 'Nur Admin', name: 'adminOnly', type: 'boolean', default: false }, + { displayName: 'Privat', name: 'isPrivate', type: 'boolean', default: false }, + { displayName: 'Sortierung', name: 'sortOrder', type: 'number', default: 0 }, + { displayName: 'Regex-Validierung', name: 'regex', type: 'string', default: '' }, + { displayName: 'Mögliche Werte', name: 'possibleValues', type: 'string', default: '', description: 'Komma-getrennt' }, + ], + }, + ], + }; + } + async execute() { + const items = this.getInputData(); + const returnData = []; + const credentials = await this.getCredentials('libreBookingApi'); + const baseUrl = credentials.url.replace(/\/$/, ''); + const username = credentials.username; + const pw = credentials.password; + // Config-Defaults laden + const configDefaults = await getConfigDefaults(this); + const session = await authenticate(this, baseUrl, username, pw); + try { + for (let i = 0; i < items.length; i++) { + try { + const resource = this.getNodeParameter('resource', i); + const operation = this.getNodeParameter('operation', i); + let responseData; + // RESERVATION + if (resource === 'reservation') { + if (operation === 'getAll') { + const filters = this.getNodeParameter('filters', i, {}); + const qs = {}; + if (filters.userId) + qs.userId = filters.userId; + if (filters.resourceId) + qs.resourceId = filters.resourceId; + if (filters.scheduleId) + qs.scheduleId = filters.scheduleId; + if (filters.startDateTime) + qs.startDateTime = filters.startDateTime; + if (filters.endDateTime) + qs.endDateTime = filters.endDateTime; + let response = await makeApiRequest(this, baseUrl, session, 'GET', '/Reservations/', undefined, qs); + // If includeCustomAttributes is enabled, fetch details for each reservation + if (filters.includeCustomAttributes && response.reservations && response.reservations.length > 0) { + const enrichedReservations = []; + for (const reservation of response.reservations) { + try { + const details = await makeApiRequest(this, baseUrl, session, 'GET', `/Reservations/${reservation.referenceNumber}`); + enrichedReservations.push({ + ...reservation, + customAttributes: details.customAttributes || [], + owner: details.owner, + participants: details.participants || [], + invitees: details.invitees || [], + }); + } + catch (error) { + // Fallback to original reservation data + enrichedReservations.push(reservation); + } + } + response = { ...response, reservations: enrichedReservations }; + } + responseData = response; + } + else if (operation === 'get') { + const referenceNumber = this.getNodeParameter('referenceNumber', i); + responseData = await makeApiRequest(this, baseUrl, session, 'GET', `/Reservations/${referenceNumber}`); + } + else if (operation === 'create') { + const resourceId = this.getNodeParameter('resourceId', i); + const startDateTime = this.getNodeParameter('startDateTime', i); + const endDateTime = this.getNodeParameter('endDateTime', i); + const termsAccepted = this.getNodeParameter('termsAccepted', i, configDefaults.defaultTermsAccepted); + const title = this.getNodeParameter('title', i, ''); + const customAttributes = this.getNodeParameter('customAttributes', i, {}); + const additionalFields = this.getNodeParameter('additionalFields', i, {}); + const body = { + resourceId, + startDateTime: new Date(startDateTime).toISOString(), + endDateTime: new Date(endDateTime).toISOString(), + termsAccepted, + }; + if (title) + body.title = title; + if (additionalFields.description) + body.description = additionalFields.description; + if (additionalFields.userId) + body.userId = additionalFields.userId; + if (additionalFields.resources) + body.resources = parseIdList(additionalFields.resources); + if (additionalFields.participants) + body.participants = parseIdList(additionalFields.participants); + if (additionalFields.invitees) + body.invitees = parseIdList(additionalFields.invitees); + // allowParticipation is REQUIRED by the API + body.allowParticipation = additionalFields.allowParticipation !== undefined + ? additionalFields.allowParticipation + : configDefaults.defaultAllowParticipation; + // Custom Attributes verarbeiten + if ((customAttributes === null || customAttributes === void 0 ? void 0 : customAttributes.attribute) && customAttributes.attribute.length > 0) { + body.customAttributes = customAttributes.attribute.map((attr) => ({ + attributeId: attr.attributeId, + attributeValue: attr.attributeValue, + })); + } + responseData = await makeApiRequest(this, baseUrl, session, 'POST', '/Reservations/', body); + } + else if (operation === 'update') { + const referenceNumber = this.getNodeParameter('referenceNumber', i); + const startDateTime = this.getNodeParameter('startDateTime', i); + const endDateTime = this.getNodeParameter('endDateTime', i); + const title = this.getNodeParameter('title', i, ''); + const updateScope = this.getNodeParameter('updateScope', i, 'this'); + const customAttributes = this.getNodeParameter('customAttributes', i, {}); + const additionalFields = this.getNodeParameter('additionalFields', i, {}); + const body = { + startDateTime: new Date(startDateTime).toISOString(), + endDateTime: new Date(endDateTime).toISOString(), + termsAccepted: true, // termsAccepted wird auch bei Updates benötigt + }; + if (title) + body.title = title; + if (additionalFields.description) + body.description = additionalFields.description; + if (additionalFields.resourceId) + body.resourceId = additionalFields.resourceId; + if (additionalFields.userId) + body.userId = additionalFields.userId; + if (additionalFields.resources) + body.resources = parseIdList(additionalFields.resources); + if (additionalFields.participants) + body.participants = parseIdList(additionalFields.participants); + if (additionalFields.invitees) + body.invitees = parseIdList(additionalFields.invitees); + // allowParticipation is REQUIRED by the API + body.allowParticipation = additionalFields.allowParticipation !== undefined + ? additionalFields.allowParticipation + : false; + // Custom Attributes verarbeiten + if ((customAttributes === null || customAttributes === void 0 ? void 0 : customAttributes.attribute) && customAttributes.attribute.length > 0) { + body.customAttributes = customAttributes.attribute.map((attr) => ({ + attributeId: attr.attributeId, + attributeValue: attr.attributeValue, + })); + } + responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Reservations/${referenceNumber}?updateScope=${updateScope}`, body); + } + else if (operation === 'delete') { + const referenceNumber = this.getNodeParameter('referenceNumber', i); + const updateScope = this.getNodeParameter('updateScope', i, 'this'); + responseData = await makeApiRequest(this, baseUrl, session, 'DELETE', `/Reservations/${referenceNumber}?updateScope=${updateScope}`); + } + else if (operation === 'approve') { + const referenceNumber = this.getNodeParameter('referenceNumber', i); + responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Reservations/${referenceNumber}/Approval`); + } + else if (operation === 'checkIn') { + const referenceNumber = this.getNodeParameter('referenceNumber', i); + responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Reservations/${referenceNumber}/CheckIn`); + } + else if (operation === 'checkOut') { + const referenceNumber = this.getNodeParameter('referenceNumber', i); + responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Reservations/${referenceNumber}/CheckOut`); + } + } + // RESOURCE + else if (resource === 'resource') { + if (operation === 'getAll') { + const resourceGetAllOptions = this.getNodeParameter('resourceGetAllOptions', i, {}); + let response = await makeApiRequest(this, baseUrl, session, 'GET', '/Resources/'); + // If includeCustomAttributes is enabled, fetch details for each resource + if (resourceGetAllOptions.includeCustomAttributes && response.resources && response.resources.length > 0) { + const enrichedResources = []; + for (const res of response.resources) { + try { + const details = await makeApiRequest(this, baseUrl, session, 'GET', `/Resources/${res.resourceId}`); + enrichedResources.push({ + ...res, + customAttributes: details.customAttributes || [], + }); + } + catch (error) { + // Fallback to original resource data + enrichedResources.push(res); + } + } + response = { ...response, resources: enrichedResources }; + } + responseData = response; + } + else if (operation === 'get') { + const resourceIdParam = this.getNodeParameter('resourceIdParam', i); + responseData = await makeApiRequest(this, baseUrl, session, 'GET', `/Resources/${resourceIdParam}`); + } + else if (operation === 'getAvailability') { + const resourceIdOptional = this.getNodeParameter('resourceIdOptional', i, ''); + const availabilityDateTime = this.getNodeParameter('availabilityDateTime', i, ''); + let endpoint = '/Resources/Availability'; + if (resourceIdOptional) + endpoint = `/Resources/${resourceIdOptional}/Availability`; + const qs = {}; + if (availabilityDateTime) + qs.dateTime = new Date(availabilityDateTime).toISOString(); + responseData = await makeApiRequest(this, baseUrl, session, 'GET', endpoint, undefined, qs); + } + else if (operation === 'getGroups') { + responseData = await makeApiRequest(this, baseUrl, session, 'GET', '/Resources/Groups'); + } + else if (operation === 'getTypes') { + responseData = await makeApiRequest(this, baseUrl, session, 'GET', '/Resources/Types'); + } + else if (operation === 'getStatuses') { + responseData = await makeApiRequest(this, baseUrl, session, 'GET', '/Resources/Status'); + } + else if (operation === 'create') { + const resourceName = this.getNodeParameter('resourceName', i); + const scheduleIdForResource = this.getNodeParameter('scheduleIdForResource', i); + const resourceCustomAttributes = this.getNodeParameter('resourceCustomAttributes', i, {}); + const resourceOptions = this.getNodeParameter('resourceOptions', i, {}); + const body = { name: resourceName, scheduleId: scheduleIdForResource }; + if (resourceOptions.location) + body.location = resourceOptions.location; + if (resourceOptions.contact) + body.contact = resourceOptions.contact; + if (resourceOptions.description) + body.description = resourceOptions.description; + if (resourceOptions.notes) + body.notes = resourceOptions.notes; + if (resourceOptions.maxParticipants) + body.maxParticipants = resourceOptions.maxParticipants; + if (resourceOptions.requiresApproval !== undefined) + body.requiresApproval = resourceOptions.requiresApproval; + if (resourceOptions.allowMultiday !== undefined) + body.allowMultiday = resourceOptions.allowMultiday; + if (resourceOptions.requiresCheckIn !== undefined) + body.requiresCheckIn = resourceOptions.requiresCheckIn; + if (resourceOptions.autoReleaseMinutes) + body.autoReleaseMinutes = resourceOptions.autoReleaseMinutes; + if (resourceOptions.color) + body.color = resourceOptions.color; + if (resourceOptions.statusId !== undefined) + body.statusId = resourceOptions.statusId; + // Custom Attributes verarbeiten + if ((resourceCustomAttributes === null || resourceCustomAttributes === void 0 ? void 0 : resourceCustomAttributes.attribute) && resourceCustomAttributes.attribute.length > 0) { + body.customAttributes = resourceCustomAttributes.attribute.map((attr) => ({ + attributeId: attr.attributeId, + attributeValue: attr.attributeValue, + })); + } + responseData = await makeApiRequest(this, baseUrl, session, 'POST', '/Resources/', body); + } + else if (operation === 'update') { + const resourceIdParam = this.getNodeParameter('resourceIdParam', i); + const resourceName = this.getNodeParameter('resourceName', i); + const resourceCustomAttributes = this.getNodeParameter('resourceCustomAttributes', i, {}); + const resourceOptions = this.getNodeParameter('resourceOptions', i, {}); + const body = { name: resourceName }; + if (resourceOptions.location) + body.location = resourceOptions.location; + if (resourceOptions.contact) + body.contact = resourceOptions.contact; + if (resourceOptions.description) + body.description = resourceOptions.description; + if (resourceOptions.notes) + body.notes = resourceOptions.notes; + if (resourceOptions.maxParticipants) + body.maxParticipants = resourceOptions.maxParticipants; + if (resourceOptions.requiresApproval !== undefined) + body.requiresApproval = resourceOptions.requiresApproval; + if (resourceOptions.allowMultiday !== undefined) + body.allowMultiday = resourceOptions.allowMultiday; + if (resourceOptions.requiresCheckIn !== undefined) + body.requiresCheckIn = resourceOptions.requiresCheckIn; + if (resourceOptions.autoReleaseMinutes) + body.autoReleaseMinutes = resourceOptions.autoReleaseMinutes; + if (resourceOptions.color) + body.color = resourceOptions.color; + if (resourceOptions.statusId !== undefined) + body.statusId = resourceOptions.statusId; + // Custom Attributes verarbeiten + if ((resourceCustomAttributes === null || resourceCustomAttributes === void 0 ? void 0 : resourceCustomAttributes.attribute) && resourceCustomAttributes.attribute.length > 0) { + body.customAttributes = resourceCustomAttributes.attribute.map((attr) => ({ + attributeId: attr.attributeId, + attributeValue: attr.attributeValue, + })); + } + responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Resources/${resourceIdParam}`, body); + } + else if (operation === 'delete') { + const resourceIdParam = this.getNodeParameter('resourceIdParam', i); + responseData = await makeApiRequest(this, baseUrl, session, 'DELETE', `/Resources/${resourceIdParam}`); + } + } + // SCHEDULE + else if (resource === 'schedule') { + if (operation === 'getAll') { + responseData = await makeApiRequest(this, baseUrl, session, 'GET', '/Schedules/'); + } + else if (operation === 'get') { + const scheduleId = this.getNodeParameter('scheduleId', i); + responseData = await makeApiRequest(this, baseUrl, session, 'GET', `/Schedules/${scheduleId}`); + } + else if (operation === 'getSlots') { + const scheduleId = this.getNodeParameter('scheduleId', i); + const slotsFilters = this.getNodeParameter('slotsFilters', i, {}); + const qs = {}; + if (slotsFilters.resourceId) + qs.resourceId = slotsFilters.resourceId; + if (slotsFilters.startDateTime) + qs.startDateTime = new Date(slotsFilters.startDateTime).toISOString(); + if (slotsFilters.endDateTime) + qs.endDateTime = new Date(slotsFilters.endDateTime).toISOString(); + responseData = await makeApiRequest(this, baseUrl, session, 'GET', `/Schedules/${scheduleId}/Slots`, undefined, qs); + } + } + // USER + else if (resource === 'user') { + if (operation === 'getAll') { + const userFilters = this.getNodeParameter('userFilters', i, {}); + const qs = {}; + if (userFilters.username) + qs.username = userFilters.username; + if (userFilters.email) + qs.email = userFilters.email; + if (userFilters.firstName) + qs.firstName = userFilters.firstName; + if (userFilters.lastName) + qs.lastName = userFilters.lastName; + if (userFilters.organization) + qs.organization = userFilters.organization; + let response = await makeApiRequest(this, baseUrl, session, 'GET', '/Users/', undefined, qs); + // If includeCustomAttributes is enabled, fetch details for each user + if (userFilters.includeCustomAttributes && response.users && response.users.length > 0) { + const enrichedUsers = []; + for (const user of response.users) { + try { + const details = await makeApiRequest(this, baseUrl, session, 'GET', `/Users/${user.id}`); + enrichedUsers.push({ + ...user, + customAttributes: details.customAttributes || [], + }); + } + catch (error) { + // Fallback to original user data + enrichedUsers.push(user); + } + } + response = { ...response, users: enrichedUsers }; + } + responseData = response; + } + else if (operation === 'get') { + const userId = this.getNodeParameter('userId', i); + responseData = await makeApiRequest(this, baseUrl, session, 'GET', `/Users/${userId}`); + } + else if (operation === 'create') { + const emailAddress = this.getNodeParameter('emailAddress', i); + const userName = this.getNodeParameter('userName', i); + const userPw = this.getNodeParameter('password', i); + const firstName = this.getNodeParameter('firstName', i); + const lastName = this.getNodeParameter('lastName', i); + const userCustomAttributes = this.getNodeParameter('userCustomAttributes', i, {}); + const userOptions = this.getNodeParameter('userOptions', i, {}); + const body = { emailAddress, userName, password: userPw, firstName, lastName }; + body.timezone = userOptions.timezone || configDefaults.defaultTimezone; + body.language = userOptions.language || configDefaults.defaultLanguage; + if (userOptions.phone) + body.phone = userOptions.phone; + if (userOptions.organization) + body.organization = userOptions.organization; + if (userOptions.position) + body.position = userOptions.position; + if (userOptions.groups) + body.groups = parseIdList(userOptions.groups); + // Custom Attributes verarbeiten + if ((userCustomAttributes === null || userCustomAttributes === void 0 ? void 0 : userCustomAttributes.attribute) && userCustomAttributes.attribute.length > 0) { + body.customAttributes = userCustomAttributes.attribute.map((attr) => ({ + attributeId: attr.attributeId, + attributeValue: attr.attributeValue, + })); + } + responseData = await makeApiRequest(this, baseUrl, session, 'POST', '/Users/', body); + } + else if (operation === 'update') { + const userId = this.getNodeParameter('userId', i); + const firstName = this.getNodeParameter('firstName', i); + const lastName = this.getNodeParameter('lastName', i); + const userCustomAttributes = this.getNodeParameter('userCustomAttributes', i, {}); + const userOptions = this.getNodeParameter('userOptions', i, {}); + const body = { firstName, lastName }; + if (userOptions.timezone) + body.timezone = userOptions.timezone; + if (userOptions.language) + body.language = userOptions.language; + if (userOptions.phone) + body.phone = userOptions.phone; + if (userOptions.organization) + body.organization = userOptions.organization; + if (userOptions.position) + body.position = userOptions.position; + if (userOptions.groups) + body.groups = parseIdList(userOptions.groups); + // Custom Attributes verarbeiten + if ((userCustomAttributes === null || userCustomAttributes === void 0 ? void 0 : userCustomAttributes.attribute) && userCustomAttributes.attribute.length > 0) { + body.customAttributes = userCustomAttributes.attribute.map((attr) => ({ + attributeId: attr.attributeId, + attributeValue: attr.attributeValue, + })); + } + responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Users/${userId}`, body); + } + else if (operation === 'updatePassword') { + const userId = this.getNodeParameter('userId', i); + const userPw = this.getNodeParameter('password', i); + responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Users/${userId}/Password`, { password: userPw }); + } + else if (operation === 'delete') { + const userId = this.getNodeParameter('userId', i); + responseData = await makeApiRequest(this, baseUrl, session, 'DELETE', `/Users/${userId}`); + } + } + // ACCOUNT + else if (resource === 'account') { + if (operation === 'get') { + const accountUserId = this.getNodeParameter('accountUserId', i); + responseData = await makeApiRequest(this, baseUrl, session, 'GET', `/Accounts/${accountUserId}`); + } + else if (operation === 'create') { + const accountData = this.getNodeParameter('accountData', i, {}); + const accountCustomAttributes = this.getNodeParameter('accountCustomAttributes', i, {}); + const body = {}; + if (accountData.emailAddress) + body.emailAddress = accountData.emailAddress; + if (accountData.userName) + body.userName = accountData.userName; + if (accountData.password) + body.password = accountData.password; + if (accountData.firstName) + body.firstName = accountData.firstName; + if (accountData.lastName) + body.lastName = accountData.lastName; + body.timezone = accountData.timezone || configDefaults.defaultTimezone; + body.language = accountData.language || configDefaults.defaultLanguage; + if (accountData.phone) + body.phone = accountData.phone; + if (accountData.organization) + body.organization = accountData.organization; + if (accountData.position) + body.position = accountData.position; + if (accountData.acceptTermsOfService !== undefined) { + body.acceptTermsOfService = accountData.acceptTermsOfService; + } + else { + body.acceptTermsOfService = configDefaults.defaultTermsAccepted; + } + // Custom Attributes verarbeiten + if ((accountCustomAttributes === null || accountCustomAttributes === void 0 ? void 0 : accountCustomAttributes.attribute) && accountCustomAttributes.attribute.length > 0) { + body.customAttributes = accountCustomAttributes.attribute.map((attr) => ({ + attributeId: attr.attributeId, + attributeValue: attr.attributeValue, + })); + } + responseData = await makeApiRequest(this, baseUrl, session, 'POST', '/Accounts/', body); + } + else if (operation === 'update') { + const accountUserId = this.getNodeParameter('accountUserId', i); + const accountData = this.getNodeParameter('accountData', i, {}); + const accountCustomAttributes = this.getNodeParameter('accountCustomAttributes', i, {}); + const body = {}; + if (accountData.emailAddress) + body.emailAddress = accountData.emailAddress; + if (accountData.userName) + body.userName = accountData.userName; + if (accountData.firstName) + body.firstName = accountData.firstName; + if (accountData.lastName) + body.lastName = accountData.lastName; + if (accountData.timezone) + body.timezone = accountData.timezone; + if (accountData.language) + body.language = accountData.language; + if (accountData.phone) + body.phone = accountData.phone; + if (accountData.organization) + body.organization = accountData.organization; + if (accountData.position) + body.position = accountData.position; + // Custom Attributes verarbeiten + if ((accountCustomAttributes === null || accountCustomAttributes === void 0 ? void 0 : accountCustomAttributes.attribute) && accountCustomAttributes.attribute.length > 0) { + body.customAttributes = accountCustomAttributes.attribute.map((attr) => ({ + attributeId: attr.attributeId, + attributeValue: attr.attributeValue, + })); + } + responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Accounts/${accountUserId}`, body); + } + else if (operation === 'updatePassword') { + const accountUserId = this.getNodeParameter('accountUserId', i); + const passwordChange = this.getNodeParameter('passwordChange', i, {}); + const passwords = passwordChange.passwords || {}; + responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Accounts/${accountUserId}/Password`, { + currentPassword: passwords.currentPassword, + newPassword: passwords.newPassword, + }); + } + } + // GROUP + else if (resource === 'group') { + if (operation === 'getAll') { + responseData = await makeApiRequest(this, baseUrl, session, 'GET', '/Groups/'); + } + else if (operation === 'get') { + const groupId = this.getNodeParameter('groupId', i); + responseData = await makeApiRequest(this, baseUrl, session, 'GET', `/Groups/${groupId}`); + } + else if (operation === 'create') { + const groupName = this.getNodeParameter('groupName', i); + const isDefault = this.getNodeParameter('isDefault', i, false); + responseData = await makeApiRequest(this, baseUrl, session, 'POST', '/Groups/', { name: groupName, isDefault }); + } + else if (operation === 'update') { + const groupId = this.getNodeParameter('groupId', i); + const groupName = this.getNodeParameter('groupName', i); + const isDefault = this.getNodeParameter('isDefault', i, false); + responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Groups/${groupId}`, { name: groupName, isDefault }); + } + else if (operation === 'delete') { + const groupId = this.getNodeParameter('groupId', i); + responseData = await makeApiRequest(this, baseUrl, session, 'DELETE', `/Groups/${groupId}`); + } + else if (operation === 'changeRoles') { + const groupId = this.getNodeParameter('groupId', i); + const roleIds = this.getNodeParameter('roleIds', i, ''); + responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Groups/${groupId}/Roles`, { roleIds: parseIdList(roleIds) }); + } + else if (operation === 'changePermissions') { + const groupId = this.getNodeParameter('groupId', i); + const permissionResourceIds = this.getNodeParameter('permissionResourceIds', i, ''); + responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Groups/${groupId}/Permissions`, { resourceIds: parseIdList(permissionResourceIds) }); + } + else if (operation === 'changeUsers') { + const groupId = this.getNodeParameter('groupId', i); + const groupUserIds = this.getNodeParameter('groupUserIds', i, ''); + responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Groups/${groupId}/Users`, { userIds: parseIdList(groupUserIds) }); + } + } + // ACCESSORY + else if (resource === 'accessory') { + if (operation === 'getAll') { + responseData = await makeApiRequest(this, baseUrl, session, 'GET', '/Accessories/'); + } + else if (operation === 'get') { + const accessoryId = this.getNodeParameter('accessoryId', i); + responseData = await makeApiRequest(this, baseUrl, session, 'GET', `/Accessories/${accessoryId}`); + } + } + // ATTRIBUTE + else if (resource === 'attribute') { + if (operation === 'get') { + const attributeId = this.getNodeParameter('attributeId', i); + responseData = await makeApiRequest(this, baseUrl, session, 'GET', `/Attributes/${attributeId}`); + } + else if (operation === 'getByCategory') { + const categoryId = this.getNodeParameter('categoryId', i); + responseData = await makeApiRequest(this, baseUrl, session, 'GET', `/Attributes/Category/${categoryId}`); + } + else if (operation === 'create') { + const attributeLabel = this.getNodeParameter('attributeLabel', i); + const attributeType = this.getNodeParameter('attributeType', i); + const categoryId = this.getNodeParameter('categoryId', i); + const attributeOptions = this.getNodeParameter('attributeOptions', i, {}); + const body = { label: attributeLabel, type: attributeType, categoryId }; + if (attributeOptions.required !== undefined) + body.required = attributeOptions.required; + if (attributeOptions.adminOnly !== undefined) + body.adminOnly = attributeOptions.adminOnly; + if (attributeOptions.isPrivate !== undefined) + body.isPrivate = attributeOptions.isPrivate; + if (attributeOptions.sortOrder !== undefined) + body.sortOrder = attributeOptions.sortOrder; + if (attributeOptions.regex) + body.regex = attributeOptions.regex; + if (attributeOptions.possibleValues) + body.possibleValues = attributeOptions.possibleValues.split(',').map((v) => v.trim()); + responseData = await makeApiRequest(this, baseUrl, session, 'POST', '/Attributes/', body); + } + else if (operation === 'update') { + const attributeId = this.getNodeParameter('attributeId', i); + const attributeLabel = this.getNodeParameter('attributeLabel', i); + const attributeType = this.getNodeParameter('attributeType', i); + const attributeOptions = this.getNodeParameter('attributeOptions', i, {}); + const body = { label: attributeLabel, type: attributeType }; + if (attributeOptions.required !== undefined) + body.required = attributeOptions.required; + if (attributeOptions.adminOnly !== undefined) + body.adminOnly = attributeOptions.adminOnly; + if (attributeOptions.isPrivate !== undefined) + body.isPrivate = attributeOptions.isPrivate; + if (attributeOptions.sortOrder !== undefined) + body.sortOrder = attributeOptions.sortOrder; + if (attributeOptions.regex) + body.regex = attributeOptions.regex; + if (attributeOptions.possibleValues) + body.possibleValues = attributeOptions.possibleValues.split(',').map((v) => v.trim()); + responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Attributes/${attributeId}`, body); + } + else if (operation === 'delete') { + const attributeId = this.getNodeParameter('attributeId', i); + responseData = await makeApiRequest(this, baseUrl, session, 'DELETE', `/Attributes/${attributeId}`); + } + } + // Process response + if (responseData) { + if (Array.isArray(responseData)) { + returnData.push(...responseData.map(item => ({ json: item }))); + } + else if (responseData.reservations) { + returnData.push(...responseData.reservations.map((item) => ({ json: item }))); + } + else if (responseData.resources) { + returnData.push(...responseData.resources.map((item) => ({ json: item }))); + } + else if (responseData.schedules) { + returnData.push(...responseData.schedules.map((item) => ({ json: item }))); + } + else if (responseData.users) { + returnData.push(...responseData.users.map((item) => ({ json: item }))); + } + else if (responseData.groups) { + returnData.push(...responseData.groups.map((item) => ({ json: item }))); + } + else if (responseData.accessories) { + returnData.push(...responseData.accessories.map((item) => ({ json: item }))); + } + else if (responseData.attributes) { + returnData.push(...responseData.attributes.map((item) => ({ json: item }))); + } + else { + returnData.push({ json: responseData }); + } + } + } + catch (error) { + if (this.continueOnFail()) { + returnData.push({ json: { error: error.message } }); + continue; + } + throw error; + } + } + } + finally { + await signOut(this, baseUrl, session); + } + return [returnData]; + } +} +exports.LibreBooking = LibreBooking; +//# sourceMappingURL=LibreBooking.node.js.map \ No newline at end of file diff --git a/dist/nodes/LibreBooking/LibreBooking.node.js.map b/dist/nodes/LibreBooking/LibreBooking.node.js.map new file mode 100644 index 0000000..e01058e --- /dev/null +++ b/dist/nodes/LibreBooking/LibreBooking.node.js.map @@ -0,0 +1 @@ +{"version":3,"file":"LibreBooking.node.js","sourceRoot":"","sources":["../../../nodes/LibreBooking/LibreBooking.node.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/nodes/LibreBooking/librebooking.svg b/dist/nodes/LibreBooking/librebooking.svg new file mode 100644 index 0000000..81306a9 --- /dev/null +++ b/dist/nodes/LibreBooking/librebooking.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dist/nodes/LibreBookingTrigger/LibreBookingTrigger.node.d.ts b/dist/nodes/LibreBookingTrigger/LibreBookingTrigger.node.d.ts new file mode 100644 index 0000000..135be0b --- /dev/null +++ b/dist/nodes/LibreBookingTrigger/LibreBookingTrigger.node.d.ts @@ -0,0 +1,14 @@ +import { INodeType, INodeTypeDescription, IPollFunctions, INodeExecutionData } from 'n8n-workflow'; +/** + * LibreBooking Trigger Node + * + * Drei Modi: + * 1. Get All (One-Time): Alle Reservierungen für einen Zeitraum abrufen + * 2. New Reservations (Poll): Bei neuen Reservierungen triggern + * 3. Updated Reservations (Poll): Bei geänderten Reservierungen triggern + */ +export declare class LibreBookingTrigger implements INodeType { + description: INodeTypeDescription; + poll(this: IPollFunctions): Promise; +} +//# sourceMappingURL=LibreBookingTrigger.node.d.ts.map \ No newline at end of file diff --git a/dist/nodes/LibreBookingTrigger/LibreBookingTrigger.node.d.ts.map b/dist/nodes/LibreBookingTrigger/LibreBookingTrigger.node.d.ts.map new file mode 100644 index 0000000..dbaa29f --- /dev/null +++ b/dist/nodes/LibreBookingTrigger/LibreBookingTrigger.node.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"LibreBookingTrigger.node.d.ts","sourceRoot":"","sources":["../../../nodes/LibreBookingTrigger/LibreBookingTrigger.node.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,SAAS,EACT,oBAAoB,EACpB,cAAc,EACd,kBAAkB,EAGlB,MAAM,cAAc,CAAC;AAyOtB;;;;;;;GAOG;AACH,qBAAa,mBAAoB,YAAW,SAAS;IACpD,WAAW,EAAE,oBAAoB,CA4K/B;IAEI,IAAI,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,kBAAkB,EAAE,EAAE,GAAG,IAAI,CAAC;CAkUxE"} \ No newline at end of file diff --git a/dist/nodes/LibreBookingTrigger/LibreBookingTrigger.node.js b/dist/nodes/LibreBookingTrigger/LibreBookingTrigger.node.js new file mode 100644 index 0000000..cc44d99 --- /dev/null +++ b/dist/nodes/LibreBookingTrigger/LibreBookingTrigger.node.js @@ -0,0 +1,593 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.LibreBookingTrigger = void 0; +const n8n_workflow_1 = require("n8n-workflow"); +/** + * Authentifizierung bei LibreBooking + */ +async function authenticateTrigger(pollFunctions, baseUrl, username, password) { + try { + const response = await pollFunctions.helpers.httpRequest({ + method: 'POST', + url: `${baseUrl}/Web/Services/index.php/Authentication/Authenticate`, + headers: { 'Content-Type': 'application/json' }, + body: { username, password }, + json: true, + }); + if (!response.isAuthenticated) { + throw new n8n_workflow_1.NodeOperationError(pollFunctions.getNode(), 'Authentifizierung fehlgeschlagen. Überprüfen Sie Ihre Zugangsdaten.'); + } + return { + sessionToken: response.sessionToken, + userId: response.userId, + sessionExpires: response.sessionExpires, + }; + } + catch (error) { + throw new n8n_workflow_1.NodeApiError(pollFunctions.getNode(), error, { + message: 'Authentifizierung fehlgeschlagen', + description: 'Überprüfen Sie die LibreBooking URL und Ihre Zugangsdaten.', + }); + } +} +/** + * Abmeldung + */ +async function signOutTrigger(pollFunctions, baseUrl, session) { + try { + await pollFunctions.helpers.httpRequest({ + method: 'POST', + url: `${baseUrl}/Web/Services/index.php/Authentication/SignOut`, + headers: { 'Content-Type': 'application/json' }, + body: { + userId: session.userId, + sessionToken: session.sessionToken, + }, + json: true, + }); + } + catch (error) { + // Ignoriere SignOut-Fehler + } +} +/** + * Reservierungen abrufen + */ +async function getReservations(pollFunctions, baseUrl, session, startDateTime, endDateTime, filters) { + const qs = { + startDateTime, + endDateTime, + }; + if (filters.resourceId) + qs.resourceId = filters.resourceId; + if (filters.scheduleId) + qs.scheduleId = filters.scheduleId; + if (filters.userId) + qs.userId = filters.userId; + try { + const response = await pollFunctions.helpers.httpRequest({ + method: 'GET', + url: `${baseUrl}/Web/Services/index.php/Reservations/`, + headers: { + 'Content-Type': 'application/json', + 'X-Booked-SessionToken': session.sessionToken, + 'X-Booked-UserId': session.userId.toString(), + }, + qs, + json: true, + }); + return response.reservations || []; + } + catch (error) { + throw new n8n_workflow_1.NodeApiError(pollFunctions.getNode(), error, { + message: 'Fehler beim Abrufen der Reservierungen', + }); + } +} +/** + * Detaillierte Reservierungsdaten abrufen (inkl. Custom Attributes) + */ +async function getReservationDetails(pollFunctions, baseUrl, session, referenceNumber) { + try { + const response = await pollFunctions.helpers.httpRequest({ + method: 'GET', + url: `${baseUrl}/Web/Services/index.php/Reservations/${referenceNumber}`, + headers: { + 'Content-Type': 'application/json', + 'X-Booked-SessionToken': session.sessionToken, + 'X-Booked-UserId': session.userId.toString(), + }, + json: true, + }); + return response; + } + catch (error) { + return null; + } +} +/** + * Zeitfenster berechnen für "Get All" Mode + */ +function getTimeWindowForGetAll(customStartDate, customEndDate, defaultDays = 14) { + if (customStartDate && customEndDate) { + return { + start: new Date(customStartDate).toISOString(), + end: new Date(customEndDate).toISOString(), + }; + } + const now = new Date(); + const endDate = new Date(now); + endDate.setDate(endDate.getDate() + defaultDays); + return { + start: now.toISOString(), + end: endDate.toISOString(), + }; +} +/** + * Zeitfenster berechnen für Polling + */ +function getTimeWindowForPolling(timeWindow) { + const now = new Date(); + const start = now.toISOString(); + let endDate = new Date(now); + switch (timeWindow) { + case '7days': + endDate.setDate(endDate.getDate() + 7); + break; + case '14days': + endDate.setDate(endDate.getDate() + 14); + break; + case '30days': + endDate.setDate(endDate.getDate() + 30); + break; + case '90days': + endDate.setDate(endDate.getDate() + 90); + break; + default: + endDate.setDate(endDate.getDate() + 14); + } + return { + start, + end: endDate.toISOString(), + }; +} +/** + * Hash für Reservierung generieren (für Änderungserkennung) + */ +function getReservationHash(reservation) { + const relevantData = { + referenceNumber: reservation.referenceNumber, + startDate: reservation.startDate, + endDate: reservation.endDate, + title: reservation.title || '', + description: reservation.description || '', + resourceId: reservation.resourceId, + resourceName: reservation.resourceName || '', + userId: reservation.userId, + requiresApproval: reservation.requiresApproval, + participants: reservation.participants || [], + invitees: reservation.invitees || [], + }; + return JSON.stringify(relevantData); +} +/** + * LibreBooking Trigger Node + * + * Drei Modi: + * 1. Get All (One-Time): Alle Reservierungen für einen Zeitraum abrufen + * 2. New Reservations (Poll): Bei neuen Reservierungen triggern + * 3. Updated Reservations (Poll): Bei geänderten Reservierungen triggern + */ +class LibreBookingTrigger { + constructor() { + this.description = { + displayName: 'LibreBooking Trigger', + name: 'libreBookingTrigger', + icon: 'file:librebooking.svg', + group: ['trigger'], + version: 1, + description: 'Wird bei neuen oder geänderten Reservierungen in LibreBooking ausgelöst', + subtitle: '={{$parameter["triggerMode"]}}', + defaults: { + name: 'LibreBooking Trigger', + }, + inputs: [], + outputs: ['main'], + credentials: [ + { + name: 'libreBookingApi', + required: true, + }, + ], + polling: true, + properties: [ + // ===================================================== + // TRIGGER MODE SELECTOR + // ===================================================== + { + displayName: 'Trigger-Modus', + name: 'triggerMode', + type: 'options', + options: [ + { + name: 'Alle Abrufen (Einmalig)', + value: 'getAll', + description: 'Alle Reservierungen für einen Zeitraum abrufen (bei jedem Poll)', + }, + { + name: 'Neue Reservierungen (Polling)', + value: 'newReservations', + description: 'Nur bei neuen Reservierungen triggern', + }, + { + name: 'Geänderte Reservierungen (Polling)', + value: 'updatedReservations', + description: 'Nur bei geänderten Reservierungen triggern', + }, + ], + default: 'getAll', + description: 'Wählen Sie den Trigger-Modus', + }, + // ===================================================== + // GET ALL MODE - DATE RANGE + // ===================================================== + { + displayName: 'Startdatum', + name: 'startDate', + type: 'dateTime', + displayOptions: { + show: { + triggerMode: ['getAll'], + }, + }, + default: '', + description: 'Startdatum für den Abruf (leer = heute)', + }, + { + displayName: 'Enddatum', + name: 'endDate', + type: 'dateTime', + displayOptions: { + show: { + triggerMode: ['getAll'], + }, + }, + default: '', + description: 'Enddatum für den Abruf (leer = 14 Tage in der Zukunft)', + }, + // ===================================================== + // POLLING MODE - TIME WINDOW + // ===================================================== + { + displayName: 'Zeitfenster', + name: 'timeWindow', + type: 'options', + displayOptions: { + show: { + triggerMode: ['newReservations', 'updatedReservations'], + }, + }, + options: [ + { name: 'Nächste 7 Tage', value: '7days' }, + { name: 'Nächste 14 Tage', value: '14days' }, + { name: 'Nächste 30 Tage', value: '30days' }, + { name: 'Nächste 90 Tage', value: '90days' }, + ], + default: '14days', + description: 'Zeitfenster für die Überwachung von Reservierungen', + }, + { + displayName: 'Hinweis', + name: 'pollingNotice', + type: 'notice', + default: '', + displayOptions: { + show: { + triggerMode: ['newReservations', 'updatedReservations'], + }, + }, + description: 'Beim ersten Poll werden existierende Reservierungen gespeichert, aber nicht getriggert. Nur nachfolgende Änderungen lösen den Trigger aus.', + }, + // ===================================================== + // FILTERS (ALL MODES) + // ===================================================== + { + displayName: 'Filter', + name: 'filters', + type: 'collection', + placeholder: 'Filter hinzufügen', + default: {}, + options: [ + { + displayName: 'Ressourcen-ID', + name: 'resourceId', + type: 'number', + default: '', + description: 'Nur Reservierungen für diese Ressource', + }, + { + displayName: 'Zeitplan-ID', + name: 'scheduleId', + type: 'number', + default: '', + description: 'Nur Reservierungen für diesen Zeitplan', + }, + { + displayName: 'Benutzer-ID', + name: 'userId', + type: 'number', + default: '', + description: 'Nur Reservierungen für diesen Benutzer', + }, + ], + }, + // ===================================================== + // OPTIONS (ALL MODES) + // ===================================================== + { + displayName: 'Optionen', + name: 'options', + type: 'collection', + placeholder: 'Option hinzufügen', + default: {}, + options: [ + { + displayName: 'Detaillierte Daten Abrufen', + name: 'fetchDetails', + type: 'boolean', + default: false, + description: 'Ruft vollständige Reservierungsdaten inkl. Custom Attributes ab (zusätzliche API-Aufrufe)', + }, + { + displayName: 'Debug-Modus', + name: 'debugMode', + type: 'boolean', + default: false, + description: 'Gibt zusätzliche Debug-Informationen aus', + }, + ], + }, + ], + }; + } + async poll() { + const credentials = await this.getCredentials('libreBookingApi'); + const baseUrl = credentials.url.replace(/\/$/, ''); + const username = credentials.username; + const password = credentials.password; + const triggerMode = this.getNodeParameter('triggerMode'); + const filters = this.getNodeParameter('filters', {}); + const options = this.getNodeParameter('options', {}); + // Debug-Modus + const debugMode = options.debugMode || false; + const fetchDetails = options.fetchDetails || false; + // Workflow Static Data für State-Management + const webhookData = this.getWorkflowStaticData('node'); + let session; + try { + session = await authenticateTrigger(this, baseUrl, username, password); + } + catch (error) { + throw error; + } + try { + const returnData = []; + // ========================================== + // MODE: Get All (One-Time / Every Poll) + // ========================================== + if (triggerMode === 'getAll') { + const startDate = this.getNodeParameter('startDate', ''); + const endDate = this.getNodeParameter('endDate', ''); + const { start, end } = getTimeWindowForGetAll(startDate || undefined, endDate || undefined, 14); + const reservations = await getReservations(this, baseUrl, session, start, end, filters); + if (debugMode) { + console.log(`[LibreBooking Trigger] Get All Mode - Found ${reservations.length} reservations`); + console.log(`[LibreBooking Trigger] Date Range: ${start} to ${end}`); + } + if (reservations.length === 0) { + if (debugMode) { + return [[{ + json: { + _debug: true, + _message: 'Keine Reservierungen im Zeitraum gefunden', + _startDate: start, + _endDate: end, + _count: 0, + }, + }]]; + } + return null; + } + // Alle Reservierungen zurückgeben + for (const reservation of reservations) { + let reservationData = reservation; + if (fetchDetails) { + try { + const details = await getReservationDetails(this, baseUrl, session, reservation.referenceNumber); + if (details) { + reservationData = details; + } + } + catch (error) { + // Fallback auf Basisdaten + } + } + returnData.push({ + json: { + ...reservationData, + _eventType: 'getAll', + _triggeredAt: new Date().toISOString(), + }, + }); + } + } + // ========================================== + // MODE: New Reservations (Polling) + // ========================================== + else if (triggerMode === 'newReservations') { + const timeWindow = this.getNodeParameter('timeWindow', '14days'); + const { start, end } = getTimeWindowForPolling(timeWindow); + const reservations = await getReservations(this, baseUrl, session, start, end, filters); + // Initialisiere seenIds beim ersten Poll + if (!webhookData.seenIds) { + webhookData.seenIds = []; + webhookData.isFirstPoll = true; + } + const currentIds = reservations.map((r) => r.referenceNumber); + if (debugMode) { + console.log(`[LibreBooking Trigger] New Reservations Mode`); + console.log(`[LibreBooking Trigger] First Poll: ${webhookData.isFirstPoll}`); + console.log(`[LibreBooking Trigger] Current IDs: ${currentIds.length}, Seen IDs: ${webhookData.seenIds.length}`); + } + // Beim ersten Poll: Nur IDs speichern, NICHT triggern + if (webhookData.isFirstPoll) { + webhookData.seenIds = currentIds; + webhookData.isFirstPoll = false; + webhookData.lastPollTime = new Date().toISOString(); + if (debugMode) { + return [[{ + json: { + _debug: true, + _message: 'Erster Poll - IDs wurden gespeichert, keine Events getriggert', + _savedIds: currentIds.length, + _ids: currentIds, + _timestamp: webhookData.lastPollTime, + }, + }]]; + } + return null; // Nichts triggern beim ersten Poll + } + // Nur NEUE Reservierungen (die wir noch nicht gesehen haben) + const newReservations = reservations.filter((r) => !webhookData.seenIds.includes(r.referenceNumber)); + // Update seenIds mit allen aktuellen IDs + webhookData.seenIds = currentIds; + webhookData.lastPollTime = new Date().toISOString(); + if (newReservations.length === 0) { + if (debugMode) { + console.log(`[LibreBooking Trigger] No new reservations found`); + } + return null; + } + // Neue Reservierungen verarbeiten + for (const reservation of newReservations) { + let reservationData = reservation; + if (fetchDetails) { + try { + const details = await getReservationDetails(this, baseUrl, session, reservation.referenceNumber); + if (details) { + reservationData = details; + } + } + catch (error) { + // Fallback auf Basisdaten + } + } + returnData.push({ + json: { + ...reservationData, + _eventType: 'new', + _triggeredAt: new Date().toISOString(), + }, + }); + } + if (debugMode && returnData.length > 0) { + console.log(`[LibreBooking Trigger] Triggering ${returnData.length} new reservations`); + } + } + // ========================================== + // MODE: Updated Reservations (Polling) + // ========================================== + else if (triggerMode === 'updatedReservations') { + const timeWindow = this.getNodeParameter('timeWindow', '14days'); + const { start, end } = getTimeWindowForPolling(timeWindow); + const reservations = await getReservations(this, baseUrl, session, start, end, filters); + // Initialisiere reservationHashes beim ersten Poll + if (!webhookData.reservationHashes) { + webhookData.reservationHashes = {}; + webhookData.isFirstPoll = true; + } + if (debugMode) { + console.log(`[LibreBooking Trigger] Updated Reservations Mode`); + console.log(`[LibreBooking Trigger] First Poll: ${webhookData.isFirstPoll}`); + console.log(`[LibreBooking Trigger] Current: ${reservations.length}, Stored hashes: ${Object.keys(webhookData.reservationHashes).length}`); + } + // Beim ersten Poll: Nur Hashes speichern, NICHT triggern + if (webhookData.isFirstPoll) { + for (const reservation of reservations) { + webhookData.reservationHashes[reservation.referenceNumber] = getReservationHash(reservation); + } + webhookData.isFirstPoll = false; + webhookData.lastPollTime = new Date().toISOString(); + if (debugMode) { + return [[{ + json: { + _debug: true, + _message: 'Erster Poll - Hashes wurden gespeichert, keine Events getriggert', + _savedHashes: Object.keys(webhookData.reservationHashes).length, + _timestamp: webhookData.lastPollTime, + }, + }]]; + } + return null; // Nichts triggern beim ersten Poll + } + // Geänderte Reservierungen finden + const updatedReservations = []; + const newHashes = {}; + for (const reservation of reservations) { + const currentHash = getReservationHash(reservation); + const oldHash = webhookData.reservationHashes[reservation.referenceNumber]; + newHashes[reservation.referenceNumber] = currentHash; + // Nur als "geändert" markieren, wenn: + // 1. Wir die Reservierung schon kennen (nicht neu) + // 2. Der Hash sich geändert hat + if (oldHash && currentHash !== oldHash) { + updatedReservations.push(reservation); + } + } + // Update Hashes mit allen aktuellen Reservierungen + webhookData.reservationHashes = newHashes; + webhookData.lastPollTime = new Date().toISOString(); + if (updatedReservations.length === 0) { + if (debugMode) { + console.log(`[LibreBooking Trigger] No updated reservations found`); + } + return null; + } + // Geänderte Reservierungen verarbeiten + for (const reservation of updatedReservations) { + let reservationData = reservation; + if (fetchDetails) { + try { + const details = await getReservationDetails(this, baseUrl, session, reservation.referenceNumber); + if (details) { + reservationData = details; + } + } + catch (error) { + // Fallback auf Basisdaten + } + } + returnData.push({ + json: { + ...reservationData, + _eventType: 'updated', + _triggeredAt: new Date().toISOString(), + }, + }); + } + if (debugMode && returnData.length > 0) { + console.log(`[LibreBooking Trigger] Triggering ${returnData.length} updated reservations`); + } + } + if (returnData.length === 0) { + return null; + } + return [returnData]; + } + finally { + await signOutTrigger(this, baseUrl, session); + } + } +} +exports.LibreBookingTrigger = LibreBookingTrigger; +//# sourceMappingURL=LibreBookingTrigger.node.js.map \ No newline at end of file diff --git a/dist/nodes/LibreBookingTrigger/LibreBookingTrigger.node.js.map b/dist/nodes/LibreBookingTrigger/LibreBookingTrigger.node.js.map new file mode 100644 index 0000000..069a76b --- /dev/null +++ b/dist/nodes/LibreBookingTrigger/LibreBookingTrigger.node.js.map @@ -0,0 +1 @@ +{"version":3,"file":"LibreBookingTrigger.node.js","sourceRoot":"","sources":["../../../nodes/LibreBookingTrigger/LibreBookingTrigger.node.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/nodes/LibreBookingTrigger/librebooking.svg b/dist/nodes/LibreBookingTrigger/librebooking.svg new file mode 100644 index 0000000..81306a9 --- /dev/null +++ b/dist/nodes/LibreBookingTrigger/librebooking.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/nodes/LibreBooking/LibreBooking.node.ts b/nodes/LibreBooking/LibreBooking.node.ts index 7b2467e..4745e3f 100644 --- a/nodes/LibreBooking/LibreBooking.node.ts +++ b/nodes/LibreBooking/LibreBooking.node.ts @@ -1,199 +1,199 @@ import { - IExecuteFunctions, - INodeExecutionData, - INodeType, - INodeTypeDescription, - IHttpRequestMethods, - NodeApiError, - NodeOperationError, + IExecuteFunctions, + INodeExecutionData, + INodeType, + INodeTypeDescription, + IHttpRequestMethods, + NodeApiError, + NodeOperationError, } from 'n8n-workflow'; interface LibreBookingSession { - sessionToken: string; - userId: number; - sessionExpires: string; + sessionToken: string; + userId: number; + sessionExpires: string; } interface ConfigDefaults { - defaultTermsAccepted: boolean; - defaultAllowParticipation: boolean; - defaultResourceId: number; - defaultUserId: number; - defaultScheduleId: number; - defaultTimezone: string; - defaultLanguage: string; + defaultTermsAccepted: boolean; + defaultAllowParticipation: boolean; + defaultResourceId: number; + defaultUserId: number; + defaultScheduleId: number; + defaultTimezone: string; + defaultLanguage: string; } /** * Authentifizierung bei LibreBooking */ async function authenticate( - executeFunctions: IExecuteFunctions, - baseUrl: string, - username: string, - password: string, + executeFunctions: IExecuteFunctions, + baseUrl: string, + username: string, + password: string, ): Promise { - try { - const response = await executeFunctions.helpers.httpRequest({ - method: 'POST', - url: `${baseUrl}/Web/Services/index.php/Authentication/Authenticate`, - headers: { 'Content-Type': 'application/json' }, - body: { username, password }, - json: true, - }); + try { + const response = await executeFunctions.helpers.httpRequest({ + method: 'POST', + url: `${baseUrl}/Web/Services/index.php/Authentication/Authenticate`, + headers: { 'Content-Type': 'application/json' }, + body: { username, password }, + json: true, + }); - if (!response.isAuthenticated) { - throw new NodeOperationError( - executeFunctions.getNode(), - 'Authentifizierung fehlgeschlagen. Bitte überprüfen Sie Ihre Credentials.', - ); - } + if (!response.isAuthenticated) { + throw new NodeOperationError( + executeFunctions.getNode(), + 'Authentifizierung fehlgeschlagen. Bitte überprüfen Sie Ihre Credentials.', + ); + } - return { - sessionToken: response.sessionToken, - userId: response.userId, - sessionExpires: response.sessionExpires, - }; - } catch (error: any) { - throw new NodeApiError(executeFunctions.getNode(), error, { - message: 'Authentifizierung fehlgeschlagen', - description: 'Überprüfen Sie die LibreBooking URL und Ihre Zugangsdaten.', - }); - } + return { + sessionToken: response.sessionToken, + userId: response.userId, + sessionExpires: response.sessionExpires, + }; + } catch (error: any) { + throw new NodeApiError(executeFunctions.getNode(), error, { + message: 'Authentifizierung fehlgeschlagen', + description: 'Überprüfen Sie die LibreBooking URL und Ihre Zugangsdaten.', + }); + } } /** * Abmeldung von LibreBooking */ async function signOut( - executeFunctions: IExecuteFunctions, - baseUrl: string, - session: LibreBookingSession, + executeFunctions: IExecuteFunctions, + baseUrl: string, + session: LibreBookingSession, ): Promise { - try { - await executeFunctions.helpers.httpRequest({ - method: 'POST', - url: `${baseUrl}/Web/Services/index.php/Authentication/SignOut`, - headers: { 'Content-Type': 'application/json' }, - body: { - userId: session.userId, - sessionToken: session.sessionToken, - }, - json: true, - }); - } catch (error) { - // Ignoriere SignOut-Fehler - } + try { + await executeFunctions.helpers.httpRequest({ + method: 'POST', + url: `${baseUrl}/Web/Services/index.php/Authentication/SignOut`, + headers: { 'Content-Type': 'application/json' }, + body: { + userId: session.userId, + sessionToken: session.sessionToken, + }, + json: true, + }); + } catch (error) { + // Ignoriere SignOut-Fehler + } } /** * API-Request mit Session-Authentifizierung */ async function makeApiRequest( - executeFunctions: IExecuteFunctions, - baseUrl: string, - session: LibreBookingSession, - method: IHttpRequestMethods, - endpoint: string, - body?: any, - qs?: any, + executeFunctions: IExecuteFunctions, + baseUrl: string, + session: LibreBookingSession, + method: IHttpRequestMethods, + endpoint: string, + body?: any, + qs?: any, ): Promise { - const options: any = { - method, - url: `${baseUrl}/Web/Services/index.php${endpoint}`, - headers: { - 'Content-Type': 'application/json', - 'X-Booked-SessionToken': session.sessionToken, - 'X-Booked-UserId': session.userId.toString(), - }, - json: true, - }; + const options: any = { + method, + url: `${baseUrl}/Web/Services/index.php${endpoint}`, + headers: { + 'Content-Type': 'application/json', + 'X-Booked-SessionToken': session.sessionToken, + 'X-Booked-UserId': session.userId.toString(), + }, + json: true, + }; - if (body && Object.keys(body).length > 0) { - options.body = body; - } + if (body && Object.keys(body).length > 0) { + options.body = body; + } - if (qs && Object.keys(qs).length > 0) { - options.qs = qs; - } + if (qs && Object.keys(qs).length > 0) { + options.qs = qs; + } - try { - return await executeFunctions.helpers.httpRequest(options); - } catch (error: any) { - if (error.statusCode === 401) { - throw new NodeApiError(executeFunctions.getNode(), error, { - message: 'Authentifizierung abgelaufen', - description: 'Der Session-Token ist abgelaufen. Bitte erneut ausführen.', - }); - } else if (error.statusCode === 403) { - throw new NodeApiError(executeFunctions.getNode(), error, { - message: 'Zugriff verweigert', - description: 'Sie haben keine Berechtigung für diese Operation. Admin-Rechte erforderlich?', - }); - } else if (error.statusCode === 404) { - throw new NodeApiError(executeFunctions.getNode(), error, { - message: 'Nicht gefunden', - description: 'Die angeforderte Ressource wurde nicht gefunden.', - }); - } - throw new NodeApiError(executeFunctions.getNode(), error, { - message: `API-Fehler: ${error.message}`, - }); - } + try { + return await executeFunctions.helpers.httpRequest(options); + } catch (error: any) { + if (error.statusCode === 401) { + throw new NodeApiError(executeFunctions.getNode(), error, { + message: 'Authentifizierung abgelaufen', + description: 'Der Session-Token ist abgelaufen. Bitte erneut ausführen.', + }); + } else if (error.statusCode === 403) { + throw new NodeApiError(executeFunctions.getNode(), error, { + message: 'Zugriff verweigert', + description: 'Sie haben keine Berechtigung für diese Operation. Admin-Rechte erforderlich?', + }); + } else if (error.statusCode === 404) { + throw new NodeApiError(executeFunctions.getNode(), error, { + message: 'Nicht gefunden', + description: 'Die angeforderte Ressource wurde nicht gefunden.', + }); + } + throw new NodeApiError(executeFunctions.getNode(), error, { + message: `API-Fehler: ${error.message}`, + }); + } } /** * Hilfsfunktion: String zu Array von Zahlen */ function parseIdList(value: string | undefined): number[] { - if (!value || value.trim() === '') return []; - return value.split(',').map(id => parseInt(id.trim(), 10)).filter(id => !isNaN(id)); + if (!value || value.trim() === '') return []; + return value.split(',').map(id => parseInt(id.trim(), 10)).filter(id => !isNaN(id)); } /** * Config-Defaults laden */ async function getConfigDefaults(executeFunctions: IExecuteFunctions): Promise { - const defaults: ConfigDefaults = { - defaultTermsAccepted: true, - defaultAllowParticipation: false, - defaultResourceId: 0, - defaultUserId: 0, - defaultScheduleId: 0, - defaultTimezone: 'Europe/Berlin', - defaultLanguage: 'de_de', - }; + const defaults: ConfigDefaults = { + defaultTermsAccepted: true, + defaultAllowParticipation: false, + defaultResourceId: 0, + defaultUserId: 0, + defaultScheduleId: 0, + defaultTimezone: 'Europe/Berlin', + defaultLanguage: 'de_de', + }; - try { - const configCredentials = await executeFunctions.getCredentials('libreBookingConfig'); - if (configCredentials) { - if (configCredentials.defaultTermsAccepted !== undefined) { - defaults.defaultTermsAccepted = configCredentials.defaultTermsAccepted as boolean; - } - if (configCredentials.defaultAllowParticipation !== undefined) { - defaults.defaultAllowParticipation = configCredentials.defaultAllowParticipation as boolean; - } - if (configCredentials.defaultResourceId !== undefined && configCredentials.defaultResourceId !== 0) { - defaults.defaultResourceId = configCredentials.defaultResourceId as number; - } - if (configCredentials.defaultUserId !== undefined && configCredentials.defaultUserId !== 0) { - defaults.defaultUserId = configCredentials.defaultUserId as number; - } - if (configCredentials.defaultScheduleId !== undefined && configCredentials.defaultScheduleId !== 0) { - defaults.defaultScheduleId = configCredentials.defaultScheduleId as number; - } - if (configCredentials.defaultTimezone) { - defaults.defaultTimezone = configCredentials.defaultTimezone as string; - } - if (configCredentials.defaultLanguage) { - defaults.defaultLanguage = configCredentials.defaultLanguage as string; - } - } - } catch (error) { - // Config-Credential ist optional, ignoriere Fehler - } + try { + const configCredentials = await executeFunctions.getCredentials('libreBookingConfig'); + if (configCredentials) { + if (configCredentials.defaultTermsAccepted !== undefined) { + defaults.defaultTermsAccepted = configCredentials.defaultTermsAccepted as boolean; + } + if (configCredentials.defaultAllowParticipation !== undefined) { + defaults.defaultAllowParticipation = configCredentials.defaultAllowParticipation as boolean; + } + if (configCredentials.defaultResourceId !== undefined && configCredentials.defaultResourceId !== 0) { + defaults.defaultResourceId = configCredentials.defaultResourceId as number; + } + if (configCredentials.defaultUserId !== undefined && configCredentials.defaultUserId !== 0) { + defaults.defaultUserId = configCredentials.defaultUserId as number; + } + if (configCredentials.defaultScheduleId !== undefined && configCredentials.defaultScheduleId !== 0) { + defaults.defaultScheduleId = configCredentials.defaultScheduleId as number; + } + if (configCredentials.defaultTimezone) { + defaults.defaultTimezone = configCredentials.defaultTimezone as string; + } + if (configCredentials.defaultLanguage) { + defaults.defaultLanguage = configCredentials.defaultLanguage as string; + } + } + } catch (error) { + // Config-Credential ist optional, ignoriere Fehler + } - return defaults; + return defaults; } /** @@ -203,1341 +203,1441 @@ async function getConfigDefaults(executeFunctions: IExecuteFunctions): Promise { - const items = this.getInputData(); - const returnData: INodeExecutionData[] = []; - - const credentials = await this.getCredentials('libreBookingApi'); - const baseUrl = (credentials.url as string).replace(/\/$/, ''); - const username = credentials.username as string; - const pw = credentials.password as string; + async execute(this: IExecuteFunctions): Promise { + const items = this.getInputData(); + const returnData: INodeExecutionData[] = []; + + const credentials = await this.getCredentials('libreBookingApi'); + const baseUrl = (credentials.url as string).replace(/\/$/, ''); + const username = credentials.username as string; + const pw = credentials.password as string; - // Config-Defaults laden - const configDefaults = await getConfigDefaults(this); + // Config-Defaults laden + const configDefaults = await getConfigDefaults(this); - const session = await authenticate(this, baseUrl, username, pw); + const session = await authenticate(this, baseUrl, username, pw); - try { - for (let i = 0; i < items.length; i++) { - try { - const resource = this.getNodeParameter('resource', i) as string; - const operation = this.getNodeParameter('operation', i) as string; - let responseData: any; + try { + for (let i = 0; i < items.length; i++) { + try { + const resource = this.getNodeParameter('resource', i) as string; + const operation = this.getNodeParameter('operation', i) as string; + let responseData: any; - // RESERVATION - if (resource === 'reservation') { - if (operation === 'getAll') { - const filters = this.getNodeParameter('filters', i, {}) as any; - const qs: any = {}; - if (filters.userId) qs.userId = filters.userId; - if (filters.resourceId) qs.resourceId = filters.resourceId; - if (filters.scheduleId) qs.scheduleId = filters.scheduleId; - if (filters.startDateTime) qs.startDateTime = filters.startDateTime; - if (filters.endDateTime) qs.endDateTime = filters.endDateTime; - responseData = await makeApiRequest(this, baseUrl, session, 'GET', '/Reservations/', undefined, qs); - } else if (operation === 'get') { - const referenceNumber = this.getNodeParameter('referenceNumber', i) as string; - responseData = await makeApiRequest(this, baseUrl, session, 'GET', `/Reservations/${referenceNumber}`); - } else if (operation === 'create') { - const resourceId = this.getNodeParameter('resourceId', i) as number; - const startDateTime = this.getNodeParameter('startDateTime', i) as string; - const endDateTime = this.getNodeParameter('endDateTime', i) as string; - const termsAccepted = this.getNodeParameter('termsAccepted', i, configDefaults.defaultTermsAccepted) as boolean; - const title = this.getNodeParameter('title', i, '') as string; - const customAttributes = this.getNodeParameter('customAttributes', i, {}) as any; - const additionalFields = this.getNodeParameter('additionalFields', i, {}) as any; - - const body: any = { - resourceId, - startDateTime: new Date(startDateTime).toISOString(), - endDateTime: new Date(endDateTime).toISOString(), - termsAccepted, - }; - - if (title) body.title = title; - if (additionalFields.description) body.description = additionalFields.description; - if (additionalFields.userId) body.userId = additionalFields.userId; - if (additionalFields.resources) body.resources = parseIdList(additionalFields.resources); - if (additionalFields.participants) body.participants = parseIdList(additionalFields.participants); - if (additionalFields.invitees) body.invitees = parseIdList(additionalFields.invitees); - if (additionalFields.allowParticipation !== undefined) { - body.allowParticipation = additionalFields.allowParticipation; - } else { - body.allowParticipation = configDefaults.defaultAllowParticipation; - } - - // Custom Attributes verarbeiten - if (customAttributes?.attribute && customAttributes.attribute.length > 0) { - body.customAttributes = customAttributes.attribute.map((attr: any) => ({ - attributeId: attr.attributeId, - attributeValue: attr.attributeValue, - })); - } - - responseData = await makeApiRequest(this, baseUrl, session, 'POST', '/Reservations/', body); - } else if (operation === 'update') { - const referenceNumber = this.getNodeParameter('referenceNumber', i) as string; - const startDateTime = this.getNodeParameter('startDateTime', i) as string; - const endDateTime = this.getNodeParameter('endDateTime', i) as string; - const title = this.getNodeParameter('title', i, '') as string; - const updateScope = this.getNodeParameter('updateScope', i, 'this') as string; - const customAttributes = this.getNodeParameter('customAttributes', i, {}) as any; - const additionalFields = this.getNodeParameter('additionalFields', i, {}) as any; - - const body: any = { - startDateTime: new Date(startDateTime).toISOString(), - endDateTime: new Date(endDateTime).toISOString(), - termsAccepted: true, // termsAccepted wird auch bei Updates benötigt - }; - - if (title) body.title = title; - if (additionalFields.description) body.description = additionalFields.description; - if (additionalFields.resourceId) body.resourceId = additionalFields.resourceId; - if (additionalFields.userId) body.userId = additionalFields.userId; - if (additionalFields.resources) body.resources = parseIdList(additionalFields.resources); - if (additionalFields.participants) body.participants = parseIdList(additionalFields.participants); - if (additionalFields.invitees) body.invitees = parseIdList(additionalFields.invitees); - if (additionalFields.allowParticipation !== undefined) body.allowParticipation = additionalFields.allowParticipation; - - // Custom Attributes verarbeiten - if (customAttributes?.attribute && customAttributes.attribute.length > 0) { - body.customAttributes = customAttributes.attribute.map((attr: any) => ({ - attributeId: attr.attributeId, - attributeValue: attr.attributeValue, - })); - } - - responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Reservations/${referenceNumber}?updateScope=${updateScope}`, body); - } else if (operation === 'delete') { - const referenceNumber = this.getNodeParameter('referenceNumber', i) as string; - const updateScope = this.getNodeParameter('updateScope', i, 'this') as string; - responseData = await makeApiRequest(this, baseUrl, session, 'DELETE', `/Reservations/${referenceNumber}?updateScope=${updateScope}`); - } else if (operation === 'approve') { - const referenceNumber = this.getNodeParameter('referenceNumber', i) as string; - responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Reservations/${referenceNumber}/Approval`); - } else if (operation === 'checkIn') { - const referenceNumber = this.getNodeParameter('referenceNumber', i) as string; - responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Reservations/${referenceNumber}/CheckIn`); - } else if (operation === 'checkOut') { - const referenceNumber = this.getNodeParameter('referenceNumber', i) as string; - responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Reservations/${referenceNumber}/CheckOut`); - } - } + // RESERVATION + if (resource === 'reservation') { + if (operation === 'getAll') { + const filters = this.getNodeParameter('filters', i, {}) as any; + const qs: any = {}; + if (filters.userId) qs.userId = filters.userId; + if (filters.resourceId) qs.resourceId = filters.resourceId; + if (filters.scheduleId) qs.scheduleId = filters.scheduleId; + if (filters.startDateTime) qs.startDateTime = filters.startDateTime; + if (filters.endDateTime) qs.endDateTime = filters.endDateTime; + + let response = await makeApiRequest(this, baseUrl, session, 'GET', '/Reservations/', undefined, qs); + + // If includeCustomAttributes is enabled, fetch details for each reservation + if (filters.includeCustomAttributes && response.reservations && response.reservations.length > 0) { + const enrichedReservations = []; + for (const reservation of response.reservations) { + try { + const details = await makeApiRequest(this, baseUrl, session, 'GET', `/Reservations/${reservation.referenceNumber}`); + enrichedReservations.push({ + ...reservation, + customAttributes: details.customAttributes || [], + owner: details.owner, + participants: details.participants || [], + invitees: details.invitees || [], + }); + } catch (error) { + // Fallback to original reservation data + enrichedReservations.push(reservation); + } + } + response = { ...response, reservations: enrichedReservations }; + } + + responseData = response; + } else if (operation === 'get') { + const referenceNumber = this.getNodeParameter('referenceNumber', i) as string; + responseData = await makeApiRequest(this, baseUrl, session, 'GET', `/Reservations/${referenceNumber}`); + } else if (operation === 'create') { + const resourceId = this.getNodeParameter('resourceId', i) as number; + const startDateTime = this.getNodeParameter('startDateTime', i) as string; + const endDateTime = this.getNodeParameter('endDateTime', i) as string; + const termsAccepted = this.getNodeParameter('termsAccepted', i, configDefaults.defaultTermsAccepted) as boolean; + const title = this.getNodeParameter('title', i, '') as string; + const customAttributes = this.getNodeParameter('customAttributes', i, {}) as any; + const additionalFields = this.getNodeParameter('additionalFields', i, {}) as any; + + const body: any = { + resourceId, + startDateTime: new Date(startDateTime).toISOString(), + endDateTime: new Date(endDateTime).toISOString(), + termsAccepted, + }; + + if (title) body.title = title; + if (additionalFields.description) body.description = additionalFields.description; + if (additionalFields.userId) body.userId = additionalFields.userId; + if (additionalFields.resources) body.resources = parseIdList(additionalFields.resources); + if (additionalFields.participants) body.participants = parseIdList(additionalFields.participants); + if (additionalFields.invitees) body.invitees = parseIdList(additionalFields.invitees); + // allowParticipation is REQUIRED by the API + body.allowParticipation = additionalFields.allowParticipation !== undefined + ? additionalFields.allowParticipation + : configDefaults.defaultAllowParticipation; + + // Custom Attributes verarbeiten + if (customAttributes?.attribute && customAttributes.attribute.length > 0) { + body.customAttributes = customAttributes.attribute.map((attr: any) => ({ + attributeId: attr.attributeId, + attributeValue: attr.attributeValue, + })); + } + + responseData = await makeApiRequest(this, baseUrl, session, 'POST', '/Reservations/', body); + } else if (operation === 'update') { + const referenceNumber = this.getNodeParameter('referenceNumber', i) as string; + const startDateTime = this.getNodeParameter('startDateTime', i) as string; + const endDateTime = this.getNodeParameter('endDateTime', i) as string; + const title = this.getNodeParameter('title', i, '') as string; + const updateScope = this.getNodeParameter('updateScope', i, 'this') as string; + const customAttributes = this.getNodeParameter('customAttributes', i, {}) as any; + const additionalFields = this.getNodeParameter('additionalFields', i, {}) as any; + + const body: any = { + startDateTime: new Date(startDateTime).toISOString(), + endDateTime: new Date(endDateTime).toISOString(), + termsAccepted: true, // termsAccepted wird auch bei Updates benötigt + }; + + if (title) body.title = title; + if (additionalFields.description) body.description = additionalFields.description; + if (additionalFields.resourceId) body.resourceId = additionalFields.resourceId; + if (additionalFields.userId) body.userId = additionalFields.userId; + if (additionalFields.resources) body.resources = parseIdList(additionalFields.resources); + if (additionalFields.participants) body.participants = parseIdList(additionalFields.participants); + if (additionalFields.invitees) body.invitees = parseIdList(additionalFields.invitees); + // allowParticipation is REQUIRED by the API + body.allowParticipation = additionalFields.allowParticipation !== undefined + ? additionalFields.allowParticipation + : false; + + // Custom Attributes verarbeiten + if (customAttributes?.attribute && customAttributes.attribute.length > 0) { + body.customAttributes = customAttributes.attribute.map((attr: any) => ({ + attributeId: attr.attributeId, + attributeValue: attr.attributeValue, + })); + } + + responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Reservations/${referenceNumber}?updateScope=${updateScope}`, body); + } else if (operation === 'delete') { + const referenceNumber = this.getNodeParameter('referenceNumber', i) as string; + const updateScope = this.getNodeParameter('updateScope', i, 'this') as string; + responseData = await makeApiRequest(this, baseUrl, session, 'DELETE', `/Reservations/${referenceNumber}?updateScope=${updateScope}`); + } else if (operation === 'approve') { + const referenceNumber = this.getNodeParameter('referenceNumber', i) as string; + responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Reservations/${referenceNumber}/Approval`); + } else if (operation === 'checkIn') { + const referenceNumber = this.getNodeParameter('referenceNumber', i) as string; + responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Reservations/${referenceNumber}/CheckIn`); + } else if (operation === 'checkOut') { + const referenceNumber = this.getNodeParameter('referenceNumber', i) as string; + responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Reservations/${referenceNumber}/CheckOut`); + } + } - // RESOURCE - else if (resource === 'resource') { - if (operation === 'getAll') { - responseData = await makeApiRequest(this, baseUrl, session, 'GET', '/Resources/'); - } else if (operation === 'get') { - const resourceIdParam = this.getNodeParameter('resourceIdParam', i) as number; - responseData = await makeApiRequest(this, baseUrl, session, 'GET', `/Resources/${resourceIdParam}`); - } else if (operation === 'getAvailability') { - const resourceIdOptional = this.getNodeParameter('resourceIdOptional', i, '') as number | ''; - const availabilityDateTime = this.getNodeParameter('availabilityDateTime', i, '') as string; - let endpoint = '/Resources/Availability'; - if (resourceIdOptional) endpoint = `/Resources/${resourceIdOptional}/Availability`; - const qs: any = {}; - if (availabilityDateTime) qs.dateTime = new Date(availabilityDateTime).toISOString(); - responseData = await makeApiRequest(this, baseUrl, session, 'GET', endpoint, undefined, qs); - } else if (operation === 'getGroups') { - responseData = await makeApiRequest(this, baseUrl, session, 'GET', '/Resources/Groups'); - } else if (operation === 'getTypes') { - responseData = await makeApiRequest(this, baseUrl, session, 'GET', '/Resources/Types'); - } else if (operation === 'getStatuses') { - responseData = await makeApiRequest(this, baseUrl, session, 'GET', '/Resources/Status'); - } else if (operation === 'create') { - const resourceName = this.getNodeParameter('resourceName', i) as string; - const scheduleIdForResource = this.getNodeParameter('scheduleIdForResource', i) as number; - const resourceCustomAttributes = this.getNodeParameter('resourceCustomAttributes', i, {}) as any; - const resourceOptions = this.getNodeParameter('resourceOptions', i, {}) as any; - - const body: any = { name: resourceName, scheduleId: scheduleIdForResource }; - - if (resourceOptions.location) body.location = resourceOptions.location; - if (resourceOptions.contact) body.contact = resourceOptions.contact; - if (resourceOptions.description) body.description = resourceOptions.description; - if (resourceOptions.notes) body.notes = resourceOptions.notes; - if (resourceOptions.maxParticipants) body.maxParticipants = resourceOptions.maxParticipants; - if (resourceOptions.requiresApproval !== undefined) body.requiresApproval = resourceOptions.requiresApproval; - if (resourceOptions.allowMultiday !== undefined) body.allowMultiday = resourceOptions.allowMultiday; - if (resourceOptions.requiresCheckIn !== undefined) body.requiresCheckIn = resourceOptions.requiresCheckIn; - if (resourceOptions.autoReleaseMinutes) body.autoReleaseMinutes = resourceOptions.autoReleaseMinutes; - if (resourceOptions.color) body.color = resourceOptions.color; - if (resourceOptions.statusId !== undefined) body.statusId = resourceOptions.statusId; - - // Custom Attributes verarbeiten - if (resourceCustomAttributes?.attribute && resourceCustomAttributes.attribute.length > 0) { - body.customAttributes = resourceCustomAttributes.attribute.map((attr: any) => ({ - attributeId: attr.attributeId, - attributeValue: attr.attributeValue, - })); - } - - responseData = await makeApiRequest(this, baseUrl, session, 'POST', '/Resources/', body); - } else if (operation === 'update') { - const resourceIdParam = this.getNodeParameter('resourceIdParam', i) as number; - const resourceName = this.getNodeParameter('resourceName', i) as string; - const resourceCustomAttributes = this.getNodeParameter('resourceCustomAttributes', i, {}) as any; - const resourceOptions = this.getNodeParameter('resourceOptions', i, {}) as any; - - const body: any = { name: resourceName }; - - if (resourceOptions.location) body.location = resourceOptions.location; - if (resourceOptions.contact) body.contact = resourceOptions.contact; - if (resourceOptions.description) body.description = resourceOptions.description; - if (resourceOptions.notes) body.notes = resourceOptions.notes; - if (resourceOptions.maxParticipants) body.maxParticipants = resourceOptions.maxParticipants; - if (resourceOptions.requiresApproval !== undefined) body.requiresApproval = resourceOptions.requiresApproval; - if (resourceOptions.allowMultiday !== undefined) body.allowMultiday = resourceOptions.allowMultiday; - if (resourceOptions.requiresCheckIn !== undefined) body.requiresCheckIn = resourceOptions.requiresCheckIn; - if (resourceOptions.autoReleaseMinutes) body.autoReleaseMinutes = resourceOptions.autoReleaseMinutes; - if (resourceOptions.color) body.color = resourceOptions.color; - if (resourceOptions.statusId !== undefined) body.statusId = resourceOptions.statusId; - - // Custom Attributes verarbeiten - if (resourceCustomAttributes?.attribute && resourceCustomAttributes.attribute.length > 0) { - body.customAttributes = resourceCustomAttributes.attribute.map((attr: any) => ({ - attributeId: attr.attributeId, - attributeValue: attr.attributeValue, - })); - } - - responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Resources/${resourceIdParam}`, body); - } else if (operation === 'delete') { - const resourceIdParam = this.getNodeParameter('resourceIdParam', i) as number; - responseData = await makeApiRequest(this, baseUrl, session, 'DELETE', `/Resources/${resourceIdParam}`); - } - } + // RESOURCE + else if (resource === 'resource') { + if (operation === 'getAll') { + const resourceGetAllOptions = this.getNodeParameter('resourceGetAllOptions', i, {}) as any; + + let response = await makeApiRequest(this, baseUrl, session, 'GET', '/Resources/'); + + // If includeCustomAttributes is enabled, fetch details for each resource + if (resourceGetAllOptions.includeCustomAttributes && response.resources && response.resources.length > 0) { + const enrichedResources = []; + for (const res of response.resources) { + try { + const details = await makeApiRequest(this, baseUrl, session, 'GET', `/Resources/${res.resourceId}`); + enrichedResources.push({ + ...res, + customAttributes: details.customAttributes || [], + }); + } catch (error) { + // Fallback to original resource data + enrichedResources.push(res); + } + } + response = { ...response, resources: enrichedResources }; + } + + responseData = response; + } else if (operation === 'get') { + const resourceIdParam = this.getNodeParameter('resourceIdParam', i) as number; + responseData = await makeApiRequest(this, baseUrl, session, 'GET', `/Resources/${resourceIdParam}`); + } else if (operation === 'getAvailability') { + const resourceIdOptional = this.getNodeParameter('resourceIdOptional', i, '') as number | ''; + const availabilityDateTime = this.getNodeParameter('availabilityDateTime', i, '') as string; + let endpoint = '/Resources/Availability'; + if (resourceIdOptional) endpoint = `/Resources/${resourceIdOptional}/Availability`; + const qs: any = {}; + if (availabilityDateTime) qs.dateTime = new Date(availabilityDateTime).toISOString(); + responseData = await makeApiRequest(this, baseUrl, session, 'GET', endpoint, undefined, qs); + } else if (operation === 'getGroups') { + responseData = await makeApiRequest(this, baseUrl, session, 'GET', '/Resources/Groups'); + } else if (operation === 'getTypes') { + responseData = await makeApiRequest(this, baseUrl, session, 'GET', '/Resources/Types'); + } else if (operation === 'getStatuses') { + responseData = await makeApiRequest(this, baseUrl, session, 'GET', '/Resources/Status'); + } else if (operation === 'create') { + const resourceName = this.getNodeParameter('resourceName', i) as string; + const scheduleIdForResource = this.getNodeParameter('scheduleIdForResource', i) as number; + const resourceCustomAttributes = this.getNodeParameter('resourceCustomAttributes', i, {}) as any; + const resourceOptions = this.getNodeParameter('resourceOptions', i, {}) as any; + + const body: any = { name: resourceName, scheduleId: scheduleIdForResource }; + + if (resourceOptions.location) body.location = resourceOptions.location; + if (resourceOptions.contact) body.contact = resourceOptions.contact; + if (resourceOptions.description) body.description = resourceOptions.description; + if (resourceOptions.notes) body.notes = resourceOptions.notes; + if (resourceOptions.maxParticipants) body.maxParticipants = resourceOptions.maxParticipants; + if (resourceOptions.requiresApproval !== undefined) body.requiresApproval = resourceOptions.requiresApproval; + if (resourceOptions.allowMultiday !== undefined) body.allowMultiday = resourceOptions.allowMultiday; + if (resourceOptions.requiresCheckIn !== undefined) body.requiresCheckIn = resourceOptions.requiresCheckIn; + if (resourceOptions.autoReleaseMinutes) body.autoReleaseMinutes = resourceOptions.autoReleaseMinutes; + if (resourceOptions.color) body.color = resourceOptions.color; + if (resourceOptions.statusId !== undefined) body.statusId = resourceOptions.statusId; + + // Custom Attributes verarbeiten + if (resourceCustomAttributes?.attribute && resourceCustomAttributes.attribute.length > 0) { + body.customAttributes = resourceCustomAttributes.attribute.map((attr: any) => ({ + attributeId: attr.attributeId, + attributeValue: attr.attributeValue, + })); + } + + responseData = await makeApiRequest(this, baseUrl, session, 'POST', '/Resources/', body); + } else if (operation === 'update') { + const resourceIdParam = this.getNodeParameter('resourceIdParam', i) as number; + const resourceName = this.getNodeParameter('resourceName', i) as string; + const resourceCustomAttributes = this.getNodeParameter('resourceCustomAttributes', i, {}) as any; + const resourceOptions = this.getNodeParameter('resourceOptions', i, {}) as any; + + const body: any = { name: resourceName }; + + if (resourceOptions.location) body.location = resourceOptions.location; + if (resourceOptions.contact) body.contact = resourceOptions.contact; + if (resourceOptions.description) body.description = resourceOptions.description; + if (resourceOptions.notes) body.notes = resourceOptions.notes; + if (resourceOptions.maxParticipants) body.maxParticipants = resourceOptions.maxParticipants; + if (resourceOptions.requiresApproval !== undefined) body.requiresApproval = resourceOptions.requiresApproval; + if (resourceOptions.allowMultiday !== undefined) body.allowMultiday = resourceOptions.allowMultiday; + if (resourceOptions.requiresCheckIn !== undefined) body.requiresCheckIn = resourceOptions.requiresCheckIn; + if (resourceOptions.autoReleaseMinutes) body.autoReleaseMinutes = resourceOptions.autoReleaseMinutes; + if (resourceOptions.color) body.color = resourceOptions.color; + if (resourceOptions.statusId !== undefined) body.statusId = resourceOptions.statusId; + + // Custom Attributes verarbeiten + if (resourceCustomAttributes?.attribute && resourceCustomAttributes.attribute.length > 0) { + body.customAttributes = resourceCustomAttributes.attribute.map((attr: any) => ({ + attributeId: attr.attributeId, + attributeValue: attr.attributeValue, + })); + } + + responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Resources/${resourceIdParam}`, body); + } else if (operation === 'delete') { + const resourceIdParam = this.getNodeParameter('resourceIdParam', i) as number; + responseData = await makeApiRequest(this, baseUrl, session, 'DELETE', `/Resources/${resourceIdParam}`); + } + } - // SCHEDULE - else if (resource === 'schedule') { - if (operation === 'getAll') { - responseData = await makeApiRequest(this, baseUrl, session, 'GET', '/Schedules/'); - } else if (operation === 'get') { - const scheduleId = this.getNodeParameter('scheduleId', i) as number; - responseData = await makeApiRequest(this, baseUrl, session, 'GET', `/Schedules/${scheduleId}`); - } else if (operation === 'getSlots') { - const scheduleId = this.getNodeParameter('scheduleId', i) as number; - const slotsFilters = this.getNodeParameter('slotsFilters', i, {}) as any; - const qs: any = {}; - if (slotsFilters.resourceId) qs.resourceId = slotsFilters.resourceId; - if (slotsFilters.startDateTime) qs.startDateTime = new Date(slotsFilters.startDateTime).toISOString(); - if (slotsFilters.endDateTime) qs.endDateTime = new Date(slotsFilters.endDateTime).toISOString(); - responseData = await makeApiRequest(this, baseUrl, session, 'GET', `/Schedules/${scheduleId}/Slots`, undefined, qs); - } - } + // SCHEDULE + else if (resource === 'schedule') { + if (operation === 'getAll') { + responseData = await makeApiRequest(this, baseUrl, session, 'GET', '/Schedules/'); + } else if (operation === 'get') { + const scheduleId = this.getNodeParameter('scheduleId', i) as number; + responseData = await makeApiRequest(this, baseUrl, session, 'GET', `/Schedules/${scheduleId}`); + } else if (operation === 'getSlots') { + const scheduleId = this.getNodeParameter('scheduleId', i) as number; + const slotsFilters = this.getNodeParameter('slotsFilters', i, {}) as any; + const qs: any = {}; + if (slotsFilters.resourceId) qs.resourceId = slotsFilters.resourceId; + if (slotsFilters.startDateTime) qs.startDateTime = new Date(slotsFilters.startDateTime).toISOString(); + if (slotsFilters.endDateTime) qs.endDateTime = new Date(slotsFilters.endDateTime).toISOString(); + responseData = await makeApiRequest(this, baseUrl, session, 'GET', `/Schedules/${scheduleId}/Slots`, undefined, qs); + } + } - // USER - else if (resource === 'user') { - if (operation === 'getAll') { - const userFilters = this.getNodeParameter('userFilters', i, {}) as any; - const qs: any = {}; - if (userFilters.username) qs.username = userFilters.username; - if (userFilters.email) qs.email = userFilters.email; - if (userFilters.firstName) qs.firstName = userFilters.firstName; - if (userFilters.lastName) qs.lastName = userFilters.lastName; - if (userFilters.organization) qs.organization = userFilters.organization; - responseData = await makeApiRequest(this, baseUrl, session, 'GET', '/Users/', undefined, qs); - } else if (operation === 'get') { - const userId = this.getNodeParameter('userId', i) as number; - responseData = await makeApiRequest(this, baseUrl, session, 'GET', `/Users/${userId}`); - } else if (operation === 'create') { - const emailAddress = this.getNodeParameter('emailAddress', i) as string; - const userName = this.getNodeParameter('userName', i) as string; - const userPw = this.getNodeParameter('password', i) as string; - const firstName = this.getNodeParameter('firstName', i) as string; - const lastName = this.getNodeParameter('lastName', i) as string; - const userCustomAttributes = this.getNodeParameter('userCustomAttributes', i, {}) as any; - const userOptions = this.getNodeParameter('userOptions', i, {}) as any; - - const body: any = { emailAddress, userName, password: userPw, firstName, lastName }; - - body.timezone = userOptions.timezone || configDefaults.defaultTimezone; - body.language = userOptions.language || configDefaults.defaultLanguage; - if (userOptions.phone) body.phone = userOptions.phone; - if (userOptions.organization) body.organization = userOptions.organization; - if (userOptions.position) body.position = userOptions.position; - if (userOptions.groups) body.groups = parseIdList(userOptions.groups); - - // Custom Attributes verarbeiten - if (userCustomAttributes?.attribute && userCustomAttributes.attribute.length > 0) { - body.customAttributes = userCustomAttributes.attribute.map((attr: any) => ({ - attributeId: attr.attributeId, - attributeValue: attr.attributeValue, - })); - } - - responseData = await makeApiRequest(this, baseUrl, session, 'POST', '/Users/', body); - } else if (operation === 'update') { - const userId = this.getNodeParameter('userId', i) as number; - const firstName = this.getNodeParameter('firstName', i) as string; - const lastName = this.getNodeParameter('lastName', i) as string; - const userCustomAttributes = this.getNodeParameter('userCustomAttributes', i, {}) as any; - const userOptions = this.getNodeParameter('userOptions', i, {}) as any; - - const body: any = { firstName, lastName }; - - if (userOptions.timezone) body.timezone = userOptions.timezone; - if (userOptions.language) body.language = userOptions.language; - if (userOptions.phone) body.phone = userOptions.phone; - if (userOptions.organization) body.organization = userOptions.organization; - if (userOptions.position) body.position = userOptions.position; - if (userOptions.groups) body.groups = parseIdList(userOptions.groups); - - // Custom Attributes verarbeiten - if (userCustomAttributes?.attribute && userCustomAttributes.attribute.length > 0) { - body.customAttributes = userCustomAttributes.attribute.map((attr: any) => ({ - attributeId: attr.attributeId, - attributeValue: attr.attributeValue, - })); - } - - responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Users/${userId}`, body); - } else if (operation === 'updatePassword') { - const userId = this.getNodeParameter('userId', i) as number; - const userPw = this.getNodeParameter('password', i) as string; - responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Users/${userId}/Password`, { password: userPw }); - } else if (operation === 'delete') { - const userId = this.getNodeParameter('userId', i) as number; - responseData = await makeApiRequest(this, baseUrl, session, 'DELETE', `/Users/${userId}`); - } - } + // USER + else if (resource === 'user') { + if (operation === 'getAll') { + const userFilters = this.getNodeParameter('userFilters', i, {}) as any; + const qs: any = {}; + if (userFilters.username) qs.username = userFilters.username; + if (userFilters.email) qs.email = userFilters.email; + if (userFilters.firstName) qs.firstName = userFilters.firstName; + if (userFilters.lastName) qs.lastName = userFilters.lastName; + if (userFilters.organization) qs.organization = userFilters.organization; + + let response = await makeApiRequest(this, baseUrl, session, 'GET', '/Users/', undefined, qs); + + // If includeCustomAttributes is enabled, fetch details for each user + if (userFilters.includeCustomAttributes && response.users && response.users.length > 0) { + const enrichedUsers = []; + for (const user of response.users) { + try { + const details = await makeApiRequest(this, baseUrl, session, 'GET', `/Users/${user.id}`); + enrichedUsers.push({ + ...user, + customAttributes: details.customAttributes || [], + }); + } catch (error) { + // Fallback to original user data + enrichedUsers.push(user); + } + } + response = { ...response, users: enrichedUsers }; + } + + responseData = response; + } else if (operation === 'get') { + const userId = this.getNodeParameter('userId', i) as number; + responseData = await makeApiRequest(this, baseUrl, session, 'GET', `/Users/${userId}`); + } else if (operation === 'create') { + const emailAddress = this.getNodeParameter('emailAddress', i) as string; + const userName = this.getNodeParameter('userName', i) as string; + const userPw = this.getNodeParameter('password', i) as string; + const firstName = this.getNodeParameter('firstName', i) as string; + const lastName = this.getNodeParameter('lastName', i) as string; + const userCustomAttributes = this.getNodeParameter('userCustomAttributes', i, {}) as any; + const userOptions = this.getNodeParameter('userOptions', i, {}) as any; + + const body: any = { emailAddress, userName, password: userPw, firstName, lastName }; + + body.timezone = userOptions.timezone || configDefaults.defaultTimezone; + body.language = userOptions.language || configDefaults.defaultLanguage; + if (userOptions.phone) body.phone = userOptions.phone; + if (userOptions.organization) body.organization = userOptions.organization; + if (userOptions.position) body.position = userOptions.position; + if (userOptions.groups) body.groups = parseIdList(userOptions.groups); + + // Custom Attributes verarbeiten + if (userCustomAttributes?.attribute && userCustomAttributes.attribute.length > 0) { + body.customAttributes = userCustomAttributes.attribute.map((attr: any) => ({ + attributeId: attr.attributeId, + attributeValue: attr.attributeValue, + })); + } + + responseData = await makeApiRequest(this, baseUrl, session, 'POST', '/Users/', body); + } else if (operation === 'update') { + const userId = this.getNodeParameter('userId', i) as number; + const firstName = this.getNodeParameter('firstName', i) as string; + const lastName = this.getNodeParameter('lastName', i) as string; + const userCustomAttributes = this.getNodeParameter('userCustomAttributes', i, {}) as any; + const userOptions = this.getNodeParameter('userOptions', i, {}) as any; + + const body: any = { firstName, lastName }; + + if (userOptions.timezone) body.timezone = userOptions.timezone; + if (userOptions.language) body.language = userOptions.language; + if (userOptions.phone) body.phone = userOptions.phone; + if (userOptions.organization) body.organization = userOptions.organization; + if (userOptions.position) body.position = userOptions.position; + if (userOptions.groups) body.groups = parseIdList(userOptions.groups); + + // Custom Attributes verarbeiten + if (userCustomAttributes?.attribute && userCustomAttributes.attribute.length > 0) { + body.customAttributes = userCustomAttributes.attribute.map((attr: any) => ({ + attributeId: attr.attributeId, + attributeValue: attr.attributeValue, + })); + } + + responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Users/${userId}`, body); + } else if (operation === 'updatePassword') { + const userId = this.getNodeParameter('userId', i) as number; + const userPw = this.getNodeParameter('password', i) as string; + responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Users/${userId}/Password`, { password: userPw }); + } else if (operation === 'delete') { + const userId = this.getNodeParameter('userId', i) as number; + responseData = await makeApiRequest(this, baseUrl, session, 'DELETE', `/Users/${userId}`); + } + } - // ACCOUNT - else if (resource === 'account') { - if (operation === 'get') { - const accountUserId = this.getNodeParameter('accountUserId', i) as number; - responseData = await makeApiRequest(this, baseUrl, session, 'GET', `/Accounts/${accountUserId}`); - } else if (operation === 'create') { - const accountData = this.getNodeParameter('accountData', i, {}) as any; - const accountCustomAttributes = this.getNodeParameter('accountCustomAttributes', i, {}) as any; - - const body: any = {}; - - if (accountData.emailAddress) body.emailAddress = accountData.emailAddress; - if (accountData.userName) body.userName = accountData.userName; - if (accountData.password) body.password = accountData.password; - if (accountData.firstName) body.firstName = accountData.firstName; - if (accountData.lastName) body.lastName = accountData.lastName; - body.timezone = accountData.timezone || configDefaults.defaultTimezone; - body.language = accountData.language || configDefaults.defaultLanguage; - if (accountData.phone) body.phone = accountData.phone; - if (accountData.organization) body.organization = accountData.organization; - if (accountData.position) body.position = accountData.position; - if (accountData.acceptTermsOfService !== undefined) { - body.acceptTermsOfService = accountData.acceptTermsOfService; - } else { - body.acceptTermsOfService = configDefaults.defaultTermsAccepted; - } - - // Custom Attributes verarbeiten - if (accountCustomAttributes?.attribute && accountCustomAttributes.attribute.length > 0) { - body.customAttributes = accountCustomAttributes.attribute.map((attr: any) => ({ - attributeId: attr.attributeId, - attributeValue: attr.attributeValue, - })); - } - - responseData = await makeApiRequest(this, baseUrl, session, 'POST', '/Accounts/', body); - } else if (operation === 'update') { - const accountUserId = this.getNodeParameter('accountUserId', i) as number; - const accountData = this.getNodeParameter('accountData', i, {}) as any; - const accountCustomAttributes = this.getNodeParameter('accountCustomAttributes', i, {}) as any; - - const body: any = {}; - - if (accountData.emailAddress) body.emailAddress = accountData.emailAddress; - if (accountData.userName) body.userName = accountData.userName; - if (accountData.firstName) body.firstName = accountData.firstName; - if (accountData.lastName) body.lastName = accountData.lastName; - if (accountData.timezone) body.timezone = accountData.timezone; - if (accountData.language) body.language = accountData.language; - if (accountData.phone) body.phone = accountData.phone; - if (accountData.organization) body.organization = accountData.organization; - if (accountData.position) body.position = accountData.position; - - // Custom Attributes verarbeiten - if (accountCustomAttributes?.attribute && accountCustomAttributes.attribute.length > 0) { - body.customAttributes = accountCustomAttributes.attribute.map((attr: any) => ({ - attributeId: attr.attributeId, - attributeValue: attr.attributeValue, - })); - } - - responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Accounts/${accountUserId}`, body); - } else if (operation === 'updatePassword') { - const accountUserId = this.getNodeParameter('accountUserId', i) as number; - const passwordChange = this.getNodeParameter('passwordChange', i, {}) as any; - const passwords = passwordChange.passwords || {}; - responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Accounts/${accountUserId}/Password`, { - currentPassword: passwords.currentPassword, - newPassword: passwords.newPassword, - }); - } - } + // ACCOUNT + else if (resource === 'account') { + if (operation === 'get') { + const accountUserId = this.getNodeParameter('accountUserId', i) as number; + responseData = await makeApiRequest(this, baseUrl, session, 'GET', `/Accounts/${accountUserId}`); + } else if (operation === 'create') { + const accountData = this.getNodeParameter('accountData', i, {}) as any; + const accountCustomAttributes = this.getNodeParameter('accountCustomAttributes', i, {}) as any; + + const body: any = {}; + + if (accountData.emailAddress) body.emailAddress = accountData.emailAddress; + if (accountData.userName) body.userName = accountData.userName; + if (accountData.password) body.password = accountData.password; + if (accountData.firstName) body.firstName = accountData.firstName; + if (accountData.lastName) body.lastName = accountData.lastName; + body.timezone = accountData.timezone || configDefaults.defaultTimezone; + body.language = accountData.language || configDefaults.defaultLanguage; + if (accountData.phone) body.phone = accountData.phone; + if (accountData.organization) body.organization = accountData.organization; + if (accountData.position) body.position = accountData.position; + if (accountData.acceptTermsOfService !== undefined) { + body.acceptTermsOfService = accountData.acceptTermsOfService; + } else { + body.acceptTermsOfService = configDefaults.defaultTermsAccepted; + } + + // Custom Attributes verarbeiten + if (accountCustomAttributes?.attribute && accountCustomAttributes.attribute.length > 0) { + body.customAttributes = accountCustomAttributes.attribute.map((attr: any) => ({ + attributeId: attr.attributeId, + attributeValue: attr.attributeValue, + })); + } + + responseData = await makeApiRequest(this, baseUrl, session, 'POST', '/Accounts/', body); + } else if (operation === 'update') { + const accountUserId = this.getNodeParameter('accountUserId', i) as number; + const accountData = this.getNodeParameter('accountData', i, {}) as any; + const accountCustomAttributes = this.getNodeParameter('accountCustomAttributes', i, {}) as any; + + const body: any = {}; + + if (accountData.emailAddress) body.emailAddress = accountData.emailAddress; + if (accountData.userName) body.userName = accountData.userName; + if (accountData.firstName) body.firstName = accountData.firstName; + if (accountData.lastName) body.lastName = accountData.lastName; + if (accountData.timezone) body.timezone = accountData.timezone; + if (accountData.language) body.language = accountData.language; + if (accountData.phone) body.phone = accountData.phone; + if (accountData.organization) body.organization = accountData.organization; + if (accountData.position) body.position = accountData.position; + + // Custom Attributes verarbeiten + if (accountCustomAttributes?.attribute && accountCustomAttributes.attribute.length > 0) { + body.customAttributes = accountCustomAttributes.attribute.map((attr: any) => ({ + attributeId: attr.attributeId, + attributeValue: attr.attributeValue, + })); + } + + responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Accounts/${accountUserId}`, body); + } else if (operation === 'updatePassword') { + const accountUserId = this.getNodeParameter('accountUserId', i) as number; + const passwordChange = this.getNodeParameter('passwordChange', i, {}) as any; + const passwords = passwordChange.passwords || {}; + responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Accounts/${accountUserId}/Password`, { + currentPassword: passwords.currentPassword, + newPassword: passwords.newPassword, + }); + } + } - // GROUP - else if (resource === 'group') { - if (operation === 'getAll') { - responseData = await makeApiRequest(this, baseUrl, session, 'GET', '/Groups/'); - } else if (operation === 'get') { - const groupId = this.getNodeParameter('groupId', i) as number; - responseData = await makeApiRequest(this, baseUrl, session, 'GET', `/Groups/${groupId}`); - } else if (operation === 'create') { - const groupName = this.getNodeParameter('groupName', i) as string; - const isDefault = this.getNodeParameter('isDefault', i, false) as boolean; - responseData = await makeApiRequest(this, baseUrl, session, 'POST', '/Groups/', { name: groupName, isDefault }); - } else if (operation === 'update') { - const groupId = this.getNodeParameter('groupId', i) as number; - const groupName = this.getNodeParameter('groupName', i) as string; - const isDefault = this.getNodeParameter('isDefault', i, false) as boolean; - responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Groups/${groupId}`, { name: groupName, isDefault }); - } else if (operation === 'delete') { - const groupId = this.getNodeParameter('groupId', i) as number; - responseData = await makeApiRequest(this, baseUrl, session, 'DELETE', `/Groups/${groupId}`); - } else if (operation === 'changeRoles') { - const groupId = this.getNodeParameter('groupId', i) as number; - const roleIds = this.getNodeParameter('roleIds', i, '') as string; - responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Groups/${groupId}/Roles`, { roleIds: parseIdList(roleIds) }); - } else if (operation === 'changePermissions') { - const groupId = this.getNodeParameter('groupId', i) as number; - const permissionResourceIds = this.getNodeParameter('permissionResourceIds', i, '') as string; - responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Groups/${groupId}/Permissions`, { resourceIds: parseIdList(permissionResourceIds) }); - } else if (operation === 'changeUsers') { - const groupId = this.getNodeParameter('groupId', i) as number; - const groupUserIds = this.getNodeParameter('groupUserIds', i, '') as string; - responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Groups/${groupId}/Users`, { userIds: parseIdList(groupUserIds) }); - } - } + // GROUP + else if (resource === 'group') { + if (operation === 'getAll') { + responseData = await makeApiRequest(this, baseUrl, session, 'GET', '/Groups/'); + } else if (operation === 'get') { + const groupId = this.getNodeParameter('groupId', i) as number; + responseData = await makeApiRequest(this, baseUrl, session, 'GET', `/Groups/${groupId}`); + } else if (operation === 'create') { + const groupName = this.getNodeParameter('groupName', i) as string; + const isDefault = this.getNodeParameter('isDefault', i, false) as boolean; + responseData = await makeApiRequest(this, baseUrl, session, 'POST', '/Groups/', { name: groupName, isDefault }); + } else if (operation === 'update') { + const groupId = this.getNodeParameter('groupId', i) as number; + const groupName = this.getNodeParameter('groupName', i) as string; + const isDefault = this.getNodeParameter('isDefault', i, false) as boolean; + responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Groups/${groupId}`, { name: groupName, isDefault }); + } else if (operation === 'delete') { + const groupId = this.getNodeParameter('groupId', i) as number; + responseData = await makeApiRequest(this, baseUrl, session, 'DELETE', `/Groups/${groupId}`); + } else if (operation === 'changeRoles') { + const groupId = this.getNodeParameter('groupId', i) as number; + const roleIds = this.getNodeParameter('roleIds', i, '') as string; + responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Groups/${groupId}/Roles`, { roleIds: parseIdList(roleIds) }); + } else if (operation === 'changePermissions') { + const groupId = this.getNodeParameter('groupId', i) as number; + const permissionResourceIds = this.getNodeParameter('permissionResourceIds', i, '') as string; + responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Groups/${groupId}/Permissions`, { resourceIds: parseIdList(permissionResourceIds) }); + } else if (operation === 'changeUsers') { + const groupId = this.getNodeParameter('groupId', i) as number; + const groupUserIds = this.getNodeParameter('groupUserIds', i, '') as string; + responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Groups/${groupId}/Users`, { userIds: parseIdList(groupUserIds) }); + } + } - // ACCESSORY - else if (resource === 'accessory') { - if (operation === 'getAll') { - responseData = await makeApiRequest(this, baseUrl, session, 'GET', '/Accessories/'); - } else if (operation === 'get') { - const accessoryId = this.getNodeParameter('accessoryId', i) as number; - responseData = await makeApiRequest(this, baseUrl, session, 'GET', `/Accessories/${accessoryId}`); - } - } + // ACCESSORY + else if (resource === 'accessory') { + if (operation === 'getAll') { + responseData = await makeApiRequest(this, baseUrl, session, 'GET', '/Accessories/'); + } else if (operation === 'get') { + const accessoryId = this.getNodeParameter('accessoryId', i) as number; + responseData = await makeApiRequest(this, baseUrl, session, 'GET', `/Accessories/${accessoryId}`); + } + } - // ATTRIBUTE - else if (resource === 'attribute') { - if (operation === 'get') { - const attributeId = this.getNodeParameter('attributeId', i) as number; - responseData = await makeApiRequest(this, baseUrl, session, 'GET', `/Attributes/${attributeId}`); - } else if (operation === 'getByCategory') { - const categoryId = this.getNodeParameter('categoryId', i) as number; - responseData = await makeApiRequest(this, baseUrl, session, 'GET', `/Attributes/Category/${categoryId}`); - } else if (operation === 'create') { - const attributeLabel = this.getNodeParameter('attributeLabel', i) as string; - const attributeType = this.getNodeParameter('attributeType', i) as number; - const categoryId = this.getNodeParameter('categoryId', i) as number; - const attributeOptions = this.getNodeParameter('attributeOptions', i, {}) as any; - const body: any = { label: attributeLabel, type: attributeType, categoryId }; - if (attributeOptions.required !== undefined) body.required = attributeOptions.required; - if (attributeOptions.adminOnly !== undefined) body.adminOnly = attributeOptions.adminOnly; - if (attributeOptions.isPrivate !== undefined) body.isPrivate = attributeOptions.isPrivate; - if (attributeOptions.sortOrder !== undefined) body.sortOrder = attributeOptions.sortOrder; - if (attributeOptions.regex) body.regex = attributeOptions.regex; - if (attributeOptions.possibleValues) body.possibleValues = attributeOptions.possibleValues.split(',').map((v: string) => v.trim()); - responseData = await makeApiRequest(this, baseUrl, session, 'POST', '/Attributes/', body); - } else if (operation === 'update') { - const attributeId = this.getNodeParameter('attributeId', i) as number; - const attributeLabel = this.getNodeParameter('attributeLabel', i) as string; - const attributeType = this.getNodeParameter('attributeType', i) as number; - const attributeOptions = this.getNodeParameter('attributeOptions', i, {}) as any; - const body: any = { label: attributeLabel, type: attributeType }; - if (attributeOptions.required !== undefined) body.required = attributeOptions.required; - if (attributeOptions.adminOnly !== undefined) body.adminOnly = attributeOptions.adminOnly; - if (attributeOptions.isPrivate !== undefined) body.isPrivate = attributeOptions.isPrivate; - if (attributeOptions.sortOrder !== undefined) body.sortOrder = attributeOptions.sortOrder; - if (attributeOptions.regex) body.regex = attributeOptions.regex; - if (attributeOptions.possibleValues) body.possibleValues = attributeOptions.possibleValues.split(',').map((v: string) => v.trim()); - responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Attributes/${attributeId}`, body); - } else if (operation === 'delete') { - const attributeId = this.getNodeParameter('attributeId', i) as number; - responseData = await makeApiRequest(this, baseUrl, session, 'DELETE', `/Attributes/${attributeId}`); - } - } + // ATTRIBUTE + else if (resource === 'attribute') { + if (operation === 'get') { + const attributeId = this.getNodeParameter('attributeId', i) as number; + responseData = await makeApiRequest(this, baseUrl, session, 'GET', `/Attributes/${attributeId}`); + } else if (operation === 'getByCategory') { + const categoryId = this.getNodeParameter('categoryId', i) as number; + responseData = await makeApiRequest(this, baseUrl, session, 'GET', `/Attributes/Category/${categoryId}`); + } else if (operation === 'create') { + const attributeLabel = this.getNodeParameter('attributeLabel', i) as string; + const attributeType = this.getNodeParameter('attributeType', i) as number; + const categoryId = this.getNodeParameter('categoryId', i) as number; + const attributeOptions = this.getNodeParameter('attributeOptions', i, {}) as any; + const body: any = { label: attributeLabel, type: attributeType, categoryId }; + if (attributeOptions.required !== undefined) body.required = attributeOptions.required; + if (attributeOptions.adminOnly !== undefined) body.adminOnly = attributeOptions.adminOnly; + if (attributeOptions.isPrivate !== undefined) body.isPrivate = attributeOptions.isPrivate; + if (attributeOptions.sortOrder !== undefined) body.sortOrder = attributeOptions.sortOrder; + if (attributeOptions.regex) body.regex = attributeOptions.regex; + if (attributeOptions.possibleValues) body.possibleValues = attributeOptions.possibleValues.split(',').map((v: string) => v.trim()); + responseData = await makeApiRequest(this, baseUrl, session, 'POST', '/Attributes/', body); + } else if (operation === 'update') { + const attributeId = this.getNodeParameter('attributeId', i) as number; + const attributeLabel = this.getNodeParameter('attributeLabel', i) as string; + const attributeType = this.getNodeParameter('attributeType', i) as number; + const attributeOptions = this.getNodeParameter('attributeOptions', i, {}) as any; + const body: any = { label: attributeLabel, type: attributeType }; + if (attributeOptions.required !== undefined) body.required = attributeOptions.required; + if (attributeOptions.adminOnly !== undefined) body.adminOnly = attributeOptions.adminOnly; + if (attributeOptions.isPrivate !== undefined) body.isPrivate = attributeOptions.isPrivate; + if (attributeOptions.sortOrder !== undefined) body.sortOrder = attributeOptions.sortOrder; + if (attributeOptions.regex) body.regex = attributeOptions.regex; + if (attributeOptions.possibleValues) body.possibleValues = attributeOptions.possibleValues.split(',').map((v: string) => v.trim()); + responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Attributes/${attributeId}`, body); + } else if (operation === 'delete') { + const attributeId = this.getNodeParameter('attributeId', i) as number; + responseData = await makeApiRequest(this, baseUrl, session, 'DELETE', `/Attributes/${attributeId}`); + } + } - // Process response - if (responseData) { - if (Array.isArray(responseData)) { - returnData.push(...responseData.map(item => ({ json: item }))); - } else if (responseData.reservations) { - returnData.push(...responseData.reservations.map((item: any) => ({ json: item }))); - } else if (responseData.resources) { - returnData.push(...responseData.resources.map((item: any) => ({ json: item }))); - } else if (responseData.schedules) { - returnData.push(...responseData.schedules.map((item: any) => ({ json: item }))); - } else if (responseData.users) { - returnData.push(...responseData.users.map((item: any) => ({ json: item }))); - } else if (responseData.groups) { - returnData.push(...responseData.groups.map((item: any) => ({ json: item }))); - } else if (responseData.accessories) { - returnData.push(...responseData.accessories.map((item: any) => ({ json: item }))); - } else if (responseData.attributes) { - returnData.push(...responseData.attributes.map((item: any) => ({ json: item }))); - } else { - returnData.push({ json: responseData }); - } - } + // Process response + if (responseData) { + if (Array.isArray(responseData)) { + returnData.push(...responseData.map(item => ({ json: item }))); + } else if (responseData.reservations) { + returnData.push(...responseData.reservations.map((item: any) => ({ json: item }))); + } else if (responseData.resources) { + returnData.push(...responseData.resources.map((item: any) => ({ json: item }))); + } else if (responseData.schedules) { + returnData.push(...responseData.schedules.map((item: any) => ({ json: item }))); + } else if (responseData.users) { + returnData.push(...responseData.users.map((item: any) => ({ json: item }))); + } else if (responseData.groups) { + returnData.push(...responseData.groups.map((item: any) => ({ json: item }))); + } else if (responseData.accessories) { + returnData.push(...responseData.accessories.map((item: any) => ({ json: item }))); + } else if (responseData.attributes) { + returnData.push(...responseData.attributes.map((item: any) => ({ json: item }))); + } else { + returnData.push({ json: responseData }); + } + } - } catch (error: any) { - if (this.continueOnFail()) { - returnData.push({ json: { error: error.message } }); - continue; - } - throw error; - } - } - } finally { - await signOut(this, baseUrl, session); - } + } catch (error: any) { + if (this.continueOnFail()) { + returnData.push({ json: { error: error.message } }); + continue; + } + throw error; + } + } + } finally { + await signOut(this, baseUrl, session); + } - return [returnData]; - } + return [returnData]; + } } diff --git a/nodes/LibreBookingTrigger/LibreBookingTrigger.node.ts b/nodes/LibreBookingTrigger/LibreBookingTrigger.node.ts index 7079dc8..f2dac94 100644 --- a/nodes/LibreBookingTrigger/LibreBookingTrigger.node.ts +++ b/nodes/LibreBookingTrigger/LibreBookingTrigger.node.ts @@ -53,7 +53,7 @@ async function authenticateTrigger( if (!response.isAuthenticated) { throw new NodeOperationError( pollFunctions.getNode(), - 'Authentifizierung fehlgeschlagen', + 'Authentifizierung fehlgeschlagen. Überprüfen Sie Ihre Zugangsdaten.', ); } @@ -65,6 +65,7 @@ async function authenticateTrigger( } catch (error: any) { throw new NodeApiError(pollFunctions.getNode(), error, { message: 'Authentifizierung fehlgeschlagen', + description: 'Überprüfen Sie die LibreBooking URL und Ihre Zugangsdaten.', }); } } @@ -113,23 +114,29 @@ async function getReservations( if (filters.scheduleId) qs.scheduleId = filters.scheduleId; if (filters.userId) qs.userId = filters.userId; - const response = await pollFunctions.helpers.httpRequest({ - method: 'GET', - url: `${baseUrl}/Web/Services/index.php/Reservations/`, - headers: { - 'Content-Type': 'application/json', - 'X-Booked-SessionToken': session.sessionToken, - 'X-Booked-UserId': session.userId.toString(), - }, - qs, - json: true, - }); + try { + const response = await pollFunctions.helpers.httpRequest({ + method: 'GET', + url: `${baseUrl}/Web/Services/index.php/Reservations/`, + headers: { + 'Content-Type': 'application/json', + 'X-Booked-SessionToken': session.sessionToken, + 'X-Booked-UserId': session.userId.toString(), + }, + qs, + json: true, + }); - return response.reservations || []; + return response.reservations || []; + } catch (error: any) { + throw new NodeApiError(pollFunctions.getNode(), error, { + message: 'Fehler beim Abrufen der Reservierungen', + }); + } } /** - * Detaillierte Reservierungsdaten abrufen + * Detaillierte Reservierungsdaten abrufen (inkl. Custom Attributes) */ async function getReservationDetails( pollFunctions: IPollFunctions, @@ -137,24 +144,53 @@ async function getReservationDetails( session: LibreBookingSession, referenceNumber: string, ): Promise { - const response = await pollFunctions.helpers.httpRequest({ - method: 'GET', - url: `${baseUrl}/Web/Services/index.php/Reservations/${referenceNumber}`, - headers: { - 'Content-Type': 'application/json', - 'X-Booked-SessionToken': session.sessionToken, - 'X-Booked-UserId': session.userId.toString(), - }, - json: true, - }); + try { + const response = await pollFunctions.helpers.httpRequest({ + method: 'GET', + url: `${baseUrl}/Web/Services/index.php/Reservations/${referenceNumber}`, + headers: { + 'Content-Type': 'application/json', + 'X-Booked-SessionToken': session.sessionToken, + 'X-Booked-UserId': session.userId.toString(), + }, + json: true, + }); - return response; + return response; + } catch (error) { + return null; + } } /** - * Zeitfenster berechnen + * Zeitfenster berechnen für "Get All" Mode */ -function getTimeWindow(timeWindow: string): { start: string; end: string } { +function getTimeWindowForGetAll( + customStartDate?: string, + customEndDate?: string, + defaultDays: number = 14 +): { start: string; end: string } { + if (customStartDate && customEndDate) { + return { + start: new Date(customStartDate).toISOString(), + end: new Date(customEndDate).toISOString(), + }; + } + + const now = new Date(); + const endDate = new Date(now); + endDate.setDate(endDate.getDate() + defaultDays); + + return { + start: now.toISOString(), + end: endDate.toISOString(), + }; +} + +/** + * Zeitfenster berechnen für Polling + */ +function getTimeWindowForPolling(timeWindow: string): { start: string; end: string } { const now = new Date(); const start = now.toISOString(); @@ -184,7 +220,6 @@ function getTimeWindow(timeWindow: string): { start: string; end: string } { /** * Hash für Reservierung generieren (für Änderungserkennung) - * Nur relevante Felder berücksichtigen, die Änderungen anzeigen */ function getReservationHash(reservation: ReservationData): string { const relevantData = { @@ -206,11 +241,10 @@ function getReservationHash(reservation: ReservationData): string { /** * LibreBooking Trigger Node * - * Überwacht neue und geänderte Reservierungen in LibreBooking. - * - * WICHTIG: Beim ersten Poll werden nur die IDs/Hashes gespeichert, - * aber keine Events getriggert. Dies verhindert, dass alle - * existierenden Reservierungen als "neu" getriggert werden. + * Drei Modi: + * 1. Get All (One-Time): Alle Reservierungen für einen Zeitraum abrufen + * 2. New Reservations (Poll): Bei neuen Reservierungen triggern + * 3. Updated Reservations (Poll): Bei geänderten Reservierungen triggern */ export class LibreBookingTrigger implements INodeType { description: INodeTypeDescription = { @@ -220,7 +254,7 @@ export class LibreBookingTrigger implements INodeType { group: ['trigger'], version: 1, description: 'Wird bei neuen oder geänderten Reservierungen in LibreBooking ausgelöst', - subtitle: '={{$parameter["event"]}}', + subtitle: '={{$parameter["triggerMode"]}}', defaults: { name: 'LibreBooking Trigger', }, @@ -234,57 +268,74 @@ export class LibreBookingTrigger implements INodeType { ], polling: true, properties: [ + // ===================================================== + // TRIGGER MODE SELECTOR + // ===================================================== { - displayName: 'Event', - name: 'event', + displayName: 'Trigger-Modus', + name: 'triggerMode', type: 'options', options: [ - { - name: 'Neue Reservierung', - value: 'newReservation', - description: 'Wird bei neuen Reservierungen ausgelöst (nicht beim ersten Poll)' + { + name: 'Alle Abrufen (Einmalig)', + value: 'getAll', + description: 'Alle Reservierungen für einen Zeitraum abrufen (bei jedem Poll)', }, - { - name: 'Geänderte Reservierung', - value: 'updatedReservation', - description: 'Wird bei geänderten Reservierungen ausgelöst' + { + name: 'Neue Reservierungen (Polling)', + value: 'newReservations', + description: 'Nur bei neuen Reservierungen triggern', }, - { - name: 'Alle Reservierungen', - value: 'allReservations', - description: 'Wird bei neuen und geänderten Reservierungen ausgelöst' + { + name: 'Geänderte Reservierungen (Polling)', + value: 'updatedReservations', + description: 'Nur bei geänderten Reservierungen triggern', }, ], - default: 'newReservation', + default: 'getAll', + description: 'Wählen Sie den Trigger-Modus', }, + + // ===================================================== + // GET ALL MODE - DATE RANGE + // ===================================================== { - displayName: 'Hinweis', - name: 'notice', - type: 'notice', - default: '', + displayName: 'Startdatum', + name: 'startDate', + type: 'dateTime', displayOptions: { show: { - event: ['newReservation', 'allReservations'], + triggerMode: ['getAll'], }, }, - description: 'Beim ersten Poll werden existierende Reservierungen gespeichert, aber nicht getriggert. Nur nachfolgende neue Reservierungen lösen den Trigger aus.', + default: '', + description: 'Startdatum für den Abruf (leer = heute)', }, { - displayName: 'Filter', - name: 'filters', - type: 'collection', - placeholder: 'Filter hinzufügen', - default: {}, - options: [ - { displayName: 'Ressourcen-ID', name: 'resourceId', type: 'number', default: '' }, - { displayName: 'Zeitplan-ID', name: 'scheduleId', type: 'number', default: '' }, - { displayName: 'Benutzer-ID', name: 'userId', type: 'number', default: '' }, - ], + displayName: 'Enddatum', + name: 'endDate', + type: 'dateTime', + displayOptions: { + show: { + triggerMode: ['getAll'], + }, + }, + default: '', + description: 'Enddatum für den Abruf (leer = 14 Tage in der Zukunft)', }, + + // ===================================================== + // POLLING MODE - TIME WINDOW + // ===================================================== { displayName: 'Zeitfenster', name: 'timeWindow', type: 'options', + displayOptions: { + show: { + triggerMode: ['newReservations', 'updatedReservations'], + }, + }, options: [ { name: 'Nächste 7 Tage', value: '7days' }, { name: 'Nächste 14 Tage', value: '14days' }, @@ -292,7 +343,58 @@ export class LibreBookingTrigger implements INodeType { { name: 'Nächste 90 Tage', value: '90days' }, ], default: '14days', + description: 'Zeitfenster für die Überwachung von Reservierungen', }, + { + displayName: 'Hinweis', + name: 'pollingNotice', + type: 'notice', + default: '', + displayOptions: { + show: { + triggerMode: ['newReservations', 'updatedReservations'], + }, + }, + description: 'Beim ersten Poll werden existierende Reservierungen gespeichert, aber nicht getriggert. Nur nachfolgende Änderungen lösen den Trigger aus.', + }, + + // ===================================================== + // FILTERS (ALL MODES) + // ===================================================== + { + displayName: 'Filter', + name: 'filters', + type: 'collection', + placeholder: 'Filter hinzufügen', + default: {}, + options: [ + { + displayName: 'Ressourcen-ID', + name: 'resourceId', + type: 'number', + default: '', + description: 'Nur Reservierungen für diese Ressource', + }, + { + displayName: 'Zeitplan-ID', + name: 'scheduleId', + type: 'number', + default: '', + description: 'Nur Reservierungen für diesen Zeitplan', + }, + { + displayName: 'Benutzer-ID', + name: 'userId', + type: 'number', + default: '', + description: 'Nur Reservierungen für diesen Benutzer', + }, + ], + }, + + // ===================================================== + // OPTIONS (ALL MODES) + // ===================================================== { displayName: 'Optionen', name: 'options', @@ -300,12 +402,12 @@ export class LibreBookingTrigger implements INodeType { placeholder: 'Option hinzufügen', default: {}, options: [ - { - displayName: 'Detaillierte Daten Abrufen', - name: 'fetchDetails', - type: 'boolean', + { + displayName: 'Detaillierte Daten Abrufen', + name: 'fetchDetails', + type: 'boolean', default: false, - description: 'Ruft vollständige Reservierungsdaten ab (zusätzliche API-Aufrufe)', + description: 'Ruft vollständige Reservierungsdaten inkl. Custom Attributes ab (zusätzliche API-Aufrufe)', }, { displayName: 'Debug-Modus', @@ -325,16 +427,16 @@ export class LibreBookingTrigger implements INodeType { const username = credentials.username as string; const password = credentials.password as string; - const event = this.getNodeParameter('event') as string; + const triggerMode = this.getNodeParameter('triggerMode') as string; const filters = this.getNodeParameter('filters', {}) as any; - const timeWindow = this.getNodeParameter('timeWindow', '14days') as string; const options = this.getNodeParameter('options', {}) as any; + // Debug-Modus + const debugMode = options.debugMode || false; + const fetchDetails = options.fetchDetails || false; + // Workflow Static Data für State-Management const webhookData = this.getWorkflowStaticData('node') as WorkflowStaticData; - - // Debug-Modus - const debugMode = options.debugMode || false; let session: LibreBookingSession; try { @@ -344,23 +446,96 @@ export class LibreBookingTrigger implements INodeType { } try { - const { start, end } = getTimeWindow(timeWindow); - - const reservations = await getReservations( - this, - baseUrl, - session, - start, - end, - filters, - ); - const returnData: INodeExecutionData[] = []; // ========================================== - // EVENT: Neue Reservierungen + // MODE: Get All (One-Time / Every Poll) // ========================================== - if (event === 'newReservation') { + if (triggerMode === 'getAll') { + const startDate = this.getNodeParameter('startDate', '') as string; + const endDate = this.getNodeParameter('endDate', '') as string; + + const { start, end } = getTimeWindowForGetAll( + startDate || undefined, + endDate || undefined, + 14 + ); + + const reservations = await getReservations( + this, + baseUrl, + session, + start, + end, + filters, + ); + + if (debugMode) { + console.log(`[LibreBooking Trigger] Get All Mode - Found ${reservations.length} reservations`); + console.log(`[LibreBooking Trigger] Date Range: ${start} to ${end}`); + } + + if (reservations.length === 0) { + if (debugMode) { + return [[{ + json: { + _debug: true, + _message: 'Keine Reservierungen im Zeitraum gefunden', + _startDate: start, + _endDate: end, + _count: 0, + }, + }]]; + } + return null; + } + + // Alle Reservierungen zurückgeben + for (const reservation of reservations) { + let reservationData = reservation; + + if (fetchDetails) { + try { + const details = await getReservationDetails( + this, + baseUrl, + session, + reservation.referenceNumber, + ); + if (details) { + reservationData = details; + } + } catch (error) { + // Fallback auf Basisdaten + } + } + + returnData.push({ + json: { + ...reservationData, + _eventType: 'getAll', + _triggeredAt: new Date().toISOString(), + }, + }); + } + } + + // ========================================== + // MODE: New Reservations (Polling) + // ========================================== + else if (triggerMode === 'newReservations') { + const timeWindow = this.getNodeParameter('timeWindow', '14days') as string; + const { start, end } = getTimeWindowForPolling(timeWindow); + + const reservations = await getReservations( + this, + baseUrl, + session, + start, + end, + filters, + ); + // Initialisiere seenIds beim ersten Poll if (!webhookData.seenIds) { webhookData.seenIds = []; @@ -369,28 +544,35 @@ export class LibreBookingTrigger implements INodeType { const currentIds = reservations.map((r: ReservationData) => r.referenceNumber); + if (debugMode) { + console.log(`[LibreBooking Trigger] New Reservations Mode`); + console.log(`[LibreBooking Trigger] First Poll: ${webhookData.isFirstPoll}`); + console.log(`[LibreBooking Trigger] Current IDs: ${currentIds.length}, Seen IDs: ${webhookData.seenIds.length}`); + } + // Beim ersten Poll: Nur IDs speichern, NICHT triggern if (webhookData.isFirstPoll) { webhookData.seenIds = currentIds; webhookData.isFirstPoll = false; webhookData.lastPollTime = new Date().toISOString(); - + if (debugMode) { return [[{ json: { _debug: true, _message: 'Erster Poll - IDs wurden gespeichert, keine Events getriggert', _savedIds: currentIds.length, + _ids: currentIds, _timestamp: webhookData.lastPollTime, }, }]]; } - + return null; // Nichts triggern beim ersten Poll } // Nur NEUE Reservierungen (die wir noch nicht gesehen haben) - const newReservations = reservations.filter((r: ReservationData) => + const newReservations = reservations.filter((r: ReservationData) => !webhookData.seenIds!.includes(r.referenceNumber) ); @@ -399,6 +581,9 @@ export class LibreBookingTrigger implements INodeType { webhookData.lastPollTime = new Date().toISOString(); if (newReservations.length === 0) { + if (debugMode) { + console.log(`[LibreBooking Trigger] No new reservations found`); + } return null; } @@ -406,16 +591,19 @@ export class LibreBookingTrigger implements INodeType { for (const reservation of newReservations) { let reservationData = reservation; - if (options.fetchDetails) { + if (fetchDetails) { try { - reservationData = await getReservationDetails( + const details = await getReservationDetails( this, baseUrl, session, reservation.referenceNumber, ); + if (details) { + reservationData = details; + } } catch (error) { - reservationData = reservation; + // Fallback auf Basisdaten } } @@ -427,18 +615,40 @@ export class LibreBookingTrigger implements INodeType { }, }); } + + if (debugMode && returnData.length > 0) { + console.log(`[LibreBooking Trigger] Triggering ${returnData.length} new reservations`); + } } // ========================================== - // EVENT: Geänderte Reservierungen + // MODE: Updated Reservations (Polling) // ========================================== - else if (event === 'updatedReservation') { + else if (triggerMode === 'updatedReservations') { + const timeWindow = this.getNodeParameter('timeWindow', '14days') as string; + const { start, end } = getTimeWindowForPolling(timeWindow); + + const reservations = await getReservations( + this, + baseUrl, + session, + start, + end, + filters, + ); + // Initialisiere reservationHashes beim ersten Poll if (!webhookData.reservationHashes) { webhookData.reservationHashes = {}; webhookData.isFirstPoll = true; } + if (debugMode) { + console.log(`[LibreBooking Trigger] Updated Reservations Mode`); + console.log(`[LibreBooking Trigger] First Poll: ${webhookData.isFirstPoll}`); + console.log(`[LibreBooking Trigger] Current: ${reservations.length}, Stored hashes: ${Object.keys(webhookData.reservationHashes).length}`); + } + // Beim ersten Poll: Nur Hashes speichern, NICHT triggern if (webhookData.isFirstPoll) { for (const reservation of reservations) { @@ -446,7 +656,7 @@ export class LibreBookingTrigger implements INodeType { } webhookData.isFirstPoll = false; webhookData.lastPollTime = new Date().toISOString(); - + if (debugMode) { return [[{ json: { @@ -457,7 +667,7 @@ export class LibreBookingTrigger implements INodeType { }, }]]; } - + return null; // Nichts triggern beim ersten Poll } @@ -483,6 +693,9 @@ export class LibreBookingTrigger implements INodeType { webhookData.lastPollTime = new Date().toISOString(); if (updatedReservations.length === 0) { + if (debugMode) { + console.log(`[LibreBooking Trigger] No updated reservations found`); + } return null; } @@ -490,16 +703,19 @@ export class LibreBookingTrigger implements INodeType { for (const reservation of updatedReservations) { let reservationData = reservation; - if (options.fetchDetails) { + if (fetchDetails) { try { - reservationData = await getReservationDetails( + const details = await getReservationDetails( this, baseUrl, session, reservation.referenceNumber, ); + if (details) { + reservationData = details; + } } catch (error) { - reservationData = reservation; + // Fallback auf Basisdaten } } @@ -511,87 +727,10 @@ export class LibreBookingTrigger implements INodeType { }, }); } - } - // ========================================== - // EVENT: Alle Reservierungen (Neu + Geändert) - // ========================================== - else if (event === 'allReservations') { - // Initialisiere beide Tracking-Strukturen beim ersten Poll - if (!webhookData.seenIds || !webhookData.reservationHashes) { - webhookData.seenIds = []; - webhookData.reservationHashes = {}; - webhookData.isFirstPoll = true; + if (debugMode && returnData.length > 0) { + console.log(`[LibreBooking Trigger] Triggering ${returnData.length} updated reservations`); } - - // Beim ersten Poll: IDs und Hashes speichern, NICHT triggern - if (webhookData.isFirstPoll) { - webhookData.seenIds = reservations.map((r: ReservationData) => r.referenceNumber); - for (const reservation of reservations) { - webhookData.reservationHashes[reservation.referenceNumber] = getReservationHash(reservation); - } - webhookData.isFirstPoll = false; - webhookData.lastPollTime = new Date().toISOString(); - - if (debugMode) { - return [[{ - json: { - _debug: true, - _message: 'Erster Poll - IDs und Hashes wurden gespeichert, keine Events getriggert', - _savedIds: webhookData.seenIds.length, - _savedHashes: Object.keys(webhookData.reservationHashes).length, - _timestamp: webhookData.lastPollTime, - }, - }]]; - } - - return null; - } - - const newHashes: Record = {}; - const currentIds: string[] = []; - - for (const reservation of reservations) { - const refNumber = reservation.referenceNumber; - const currentHash = getReservationHash(reservation); - - currentIds.push(refNumber); - newHashes[refNumber] = currentHash; - - const isNew = !webhookData.seenIds!.includes(refNumber); - const oldHash = webhookData.reservationHashes![refNumber]; - const isUpdated = oldHash && currentHash !== oldHash; - - if (isNew || isUpdated) { - let reservationData = reservation; - - if (options.fetchDetails) { - try { - reservationData = await getReservationDetails( - this, - baseUrl, - session, - refNumber, - ); - } catch (error) { - reservationData = reservation; - } - } - - returnData.push({ - json: { - ...reservationData, - _eventType: isNew ? 'new' : 'updated', - _triggeredAt: new Date().toISOString(), - }, - }); - } - } - - // Update State - webhookData.seenIds = currentIds; - webhookData.reservationHashes = newHashes; - webhookData.lastPollTime = new Date().toISOString(); } if (returnData.length === 0) { diff --git a/package.json b/package.json index eeb3723..7366b94 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "n8n-nodes-librebooking", - "version": "1.2.0", + "version": "1.2.1", "description": "n8n Node für LibreBooking - Ressourcen- und Reservierungsverwaltung", "keywords": [ "n8n-community-node-package", diff --git a/test-api.ts b/test-api.ts new file mode 100644 index 0000000..4e668b8 --- /dev/null +++ b/test-api.ts @@ -0,0 +1,609 @@ +/** + * LibreBooking API Test Script + * + * Testet alle wichtigen API-Endpunkte mit echten Credentials + */ + +import * as https from 'https'; +import * as http from 'http'; + +const BASE_URL = 'https://librebooking.zell-cloud.de'; +const USERNAME = 'sebastian.zell@zell-aufmass.de'; +const PASSWORD = 'wanUQ4uVqU6lfP'; + +interface Session { + sessionToken: string; + userId: number; +} + +interface TestResult { + name: string; + success: boolean; + data?: any; + error?: string; +} + +const results: TestResult[] = []; + +/** + * HTTP Request Helper + */ +function makeRequest( + method: string, + path: string, + body?: any, + session?: Session, + qs?: Record +): Promise { + return new Promise((resolve, reject) => { + const url = new URL(path, BASE_URL); + + if (qs) { + Object.entries(qs).forEach(([key, value]) => { + if (value) url.searchParams.append(key, value); + }); + } + + const headers: Record = { + 'Content-Type': 'application/json', + }; + + if (session) { + headers['X-Booked-SessionToken'] = session.sessionToken; + headers['X-Booked-UserId'] = session.userId.toString(); + } + + const options = { + method, + hostname: url.hostname, + path: url.pathname + url.search, + headers, + }; + + const httpModule = url.protocol === 'https:' ? https : http; + + const req = httpModule.request(options, (res) => { + let data = ''; + res.on('data', (chunk) => { data += chunk; }); + res.on('end', () => { + try { + if (data) { + resolve(JSON.parse(data)); + } else { + resolve({ success: true }); + } + } catch (e) { + resolve({ rawData: data }); + } + }); + }); + + req.on('error', (error) => { + reject(error); + }); + + if (body) { + req.write(JSON.stringify(body)); + } + + req.end(); + }); +} + +/** + * Test Authentication + */ +async function testAuthentication(): Promise { + console.log('\n=== 1. Testing Authentication ==='); + try { + const response = await makeRequest( + 'POST', + '/Web/Services/index.php/Authentication/Authenticate', + { username: USERNAME, password: PASSWORD } + ); + + if (response.isAuthenticated) { + console.log('✅ Authentication successful'); + console.log(` Session Token: ${response.sessionToken.substring(0, 20)}...`); + console.log(` User ID: ${response.userId}`); + console.log(` Session Expires: ${response.sessionExpires}`); + results.push({ name: 'Authentication', success: true, data: { userId: response.userId } }); + return { sessionToken: response.sessionToken, userId: response.userId }; + } else { + throw new Error('Authentication failed'); + } + } catch (error: any) { + console.log('❌ Authentication failed:', error.message); + results.push({ name: 'Authentication', success: false, error: error.message }); + throw error; + } +} + +/** + * Test Get Reservations + */ +async function testGetReservations(session: Session): Promise { + console.log('\n=== 2. Testing Get Reservations ==='); + try { + // Test without date filters (should return next 2 weeks) + const response = await makeRequest( + 'GET', + '/Web/Services/index.php/Reservations/', + undefined, + session + ); + + console.log(`✅ Reservations fetched: ${response.reservations?.length || 0} found`); + + if (response.reservations && response.reservations.length > 0) { + const res = response.reservations[0]; + console.log(` Example: ${res.title || 'No title'} (${res.referenceNumber})`); + console.log(` Start: ${res.startDate}`); + console.log(` Resource: ${res.resourceName}`); + } + + results.push({ name: 'Get Reservations (no filter)', success: true, data: { count: response.reservations?.length || 0 } }); + + // Test with date filter (Feb 7-14, 2026) + console.log('\n Testing with date filter (2026-02-07 to 2026-02-14)...'); + const responseFiltered = await makeRequest( + 'GET', + '/Web/Services/index.php/Reservations/', + undefined, + session, + { + startDateTime: '2026-02-07T00:00:00', + endDateTime: '2026-02-14T23:59:59' + } + ); + + console.log(`✅ Filtered reservations: ${responseFiltered.reservations?.length || 0} found`); + results.push({ name: 'Get Reservations (date filter)', success: true, data: { count: responseFiltered.reservations?.length || 0 } }); + + } catch (error: any) { + console.log('❌ Get Reservations failed:', error.message); + results.push({ name: 'Get Reservations', success: false, error: error.message }); + } +} + +/** + * Test Get Resources + */ +async function testGetResources(session: Session): Promise { + console.log('\n=== 3. Testing Get Resources ==='); + try { + const response = await makeRequest( + 'GET', + '/Web/Services/index.php/Resources/', + undefined, + session + ); + + console.log(`✅ Resources fetched: ${response.resources?.length || 0} found`); + + let firstResourceId: number | null = null; + if (response.resources && response.resources.length > 0) { + const res = response.resources[0]; + firstResourceId = res.resourceId; + console.log(` Example: ${res.name} (ID: ${res.resourceId})`); + console.log(` Schedule ID: ${res.scheduleId}`); + console.log(` Custom Attributes: ${res.customAttributes?.length || 0}`); + + if (res.customAttributes && res.customAttributes.length > 0) { + res.customAttributes.forEach((attr: any) => { + console.log(` - ${attr.label}: ${attr.value || '(no value)'}`); + }); + } + } + + results.push({ name: 'Get Resources', success: true, data: { count: response.resources?.length || 0 } }); + return firstResourceId; + + } catch (error: any) { + console.log('❌ Get Resources failed:', error.message); + results.push({ name: 'Get Resources', success: false, error: error.message }); + return null; + } +} + +/** + * Test Get Single Resource (with custom attributes) + */ +async function testGetSingleResource(session: Session, resourceId: number): Promise { + console.log('\n=== 4. Testing Get Single Resource (with custom attributes) ==='); + try { + const response = await makeRequest( + 'GET', + `/Web/Services/index.php/Resources/${resourceId}`, + undefined, + session + ); + + console.log(`✅ Resource fetched: ${response.name}`); + console.log(` Custom Attributes: ${response.customAttributes?.length || 0}`); + + if (response.customAttributes && response.customAttributes.length > 0) { + response.customAttributes.forEach((attr: any) => { + console.log(` - ID: ${attr.id}, Label: ${attr.label}, Value: ${attr.value || '(no value)'}`); + }); + } + + results.push({ name: 'Get Single Resource', success: true, data: { customAttributes: response.customAttributes?.length || 0 } }); + + } catch (error: any) { + console.log('❌ Get Single Resource failed:', error.message); + results.push({ name: 'Get Single Resource', success: false, error: error.message }); + } +} + +/** + * Test Get Users + */ +async function testGetUsers(session: Session): Promise { + console.log('\n=== 5. Testing Get Users ==='); + try { + const response = await makeRequest( + 'GET', + '/Web/Services/index.php/Users/', + undefined, + session + ); + + console.log(`✅ Users fetched: ${response.users?.length || 0} found`); + + let firstUserId: number | null = null; + if (response.users && response.users.length > 0) { + const user = response.users[0]; + firstUserId = user.id; + console.log(` Example: ${user.firstName} ${user.lastName} (ID: ${user.id})`); + } + + results.push({ name: 'Get Users', success: true, data: { count: response.users?.length || 0 } }); + return firstUserId; + + } catch (error: any) { + console.log('❌ Get Users failed:', error.message); + results.push({ name: 'Get Users', success: false, error: error.message }); + return null; + } +} + +/** + * Test Get Single User (with custom attributes) + */ +async function testGetSingleUser(session: Session, userId: number): Promise { + console.log('\n=== 6. Testing Get Single User (with custom attributes) ==='); + try { + const response = await makeRequest( + 'GET', + `/Web/Services/index.php/Users/${userId}`, + undefined, + session + ); + + console.log(`✅ User fetched: ${response.firstName} ${response.lastName}`); + console.log(` Custom Attributes: ${response.customAttributes?.length || 0}`); + + if (response.customAttributes && response.customAttributes.length > 0) { + response.customAttributes.forEach((attr: any) => { + console.log(` - ID: ${attr.id}, Label: ${attr.label}, Value: ${attr.value || '(no value)'}`); + }); + } + + results.push({ name: 'Get Single User', success: true, data: { customAttributes: response.customAttributes?.length || 0 } }); + + } catch (error: any) { + console.log('❌ Get Single User failed:', error.message); + results.push({ name: 'Get Single User', success: false, error: error.message }); + } +} + +/** + * Test Get Schedules + */ +async function testGetSchedules(session: Session): Promise { + console.log('\n=== 7. Testing Get Schedules ==='); + try { + const response = await makeRequest( + 'GET', + '/Web/Services/index.php/Schedules/', + undefined, + session + ); + + console.log(`✅ Schedules fetched: ${response.schedules?.length || 0} found`); + + if (response.schedules && response.schedules.length > 0) { + const schedule = response.schedules[0]; + console.log(` Example: ${schedule.name} (ID: ${schedule.id})`); + } + + results.push({ name: 'Get Schedules', success: true, data: { count: response.schedules?.length || 0 } }); + + } catch (error: any) { + console.log('❌ Get Schedules failed:', error.message); + results.push({ name: 'Get Schedules', success: false, error: error.message }); + } +} + +/** + * Test Get Attributes by Category + */ +async function testGetAttributes(session: Session): Promise { + console.log('\n=== 8. Testing Get Attributes by Category ==='); + + const categories = [ + { id: 1, name: 'Reservation' }, + { id: 2, name: 'User' }, + { id: 4, name: 'Resource' }, + { id: 5, name: 'Resource Type' }, + ]; + + for (const cat of categories) { + try { + const response = await makeRequest( + 'GET', + `/Web/Services/index.php/Attributes/Category/${cat.id}`, + undefined, + session + ); + + console.log(`✅ ${cat.name} Attributes: ${response.attributes?.length || 0} found`); + + if (response.attributes && response.attributes.length > 0) { + response.attributes.forEach((attr: any) => { + console.log(` - ID: ${attr.id}, Label: ${attr.label}, Type: ${attr.type}, Required: ${attr.required}`); + }); + } + + results.push({ name: `Get Attributes (${cat.name})`, success: true, data: { count: response.attributes?.length || 0 } }); + + } catch (error: any) { + console.log(`❌ Get ${cat.name} Attributes failed:`, error.message); + results.push({ name: `Get Attributes (${cat.name})`, success: false, error: error.message }); + } + } +} + +/** + * Test Create, Update, Delete Reservation + */ +async function testReservationCRUD(session: Session, resourceId: number): Promise { + console.log('\n=== 9. Testing Reservation CRUD ==='); + + // Create + console.log(' Creating test reservation...'); + try { + const createResponse = await makeRequest( + 'POST', + '/Web/Services/index.php/Reservations/', + { + title: 'API Test Reservation', + description: 'Created by n8n node test script', + resourceId: resourceId, + startDateTime: '2026-02-07T10:00:00', + endDateTime: '2026-02-07T11:00:00', + userId: session.userId, + termsAccepted: true, + allowParticipation: false, + }, + session + ); + + if (createResponse.referenceNumber) { + console.log(`✅ Reservation created: ${createResponse.referenceNumber}`); + results.push({ name: 'Create Reservation', success: true, data: { referenceNumber: createResponse.referenceNumber } }); + + const refNum = createResponse.referenceNumber; + + // Get the created reservation + console.log(' Fetching created reservation...'); + const getResponse = await makeRequest( + 'GET', + `/Web/Services/index.php/Reservations/${refNum}`, + undefined, + session + ); + console.log(`✅ Reservation fetched: ${getResponse.title}`); + console.log(` Custom Attributes: ${getResponse.customAttributes?.length || 0}`); + if (getResponse.customAttributes && getResponse.customAttributes.length > 0) { + getResponse.customAttributes.forEach((attr: any) => { + console.log(` - ID: ${attr.id}, Label: ${attr.label}, Value: ${attr.value || '(no value)'}`); + }); + } + results.push({ name: 'Get Created Reservation', success: true }); + + // Update + console.log(' Updating reservation...'); + const updateResponse = await makeRequest( + 'POST', + `/Web/Services/index.php/Reservations/${refNum}?updateScope=this`, + { + title: 'API Test Reservation UPDATED', + description: 'Updated by n8n node test script', + resourceId: resourceId, + startDateTime: '2026-02-07T10:00:00', + endDateTime: '2026-02-07T12:00:00', + termsAccepted: true, + allowParticipation: false, + }, + session + ); + console.log(`✅ Reservation updated`); + results.push({ name: 'Update Reservation', success: true }); + + // Delete + console.log(' Deleting reservation...'); + const deleteResponse = await makeRequest( + 'DELETE', + `/Web/Services/index.php/Reservations/${refNum}?updateScope=this`, + undefined, + session + ); + console.log(`✅ Reservation deleted`); + results.push({ name: 'Delete Reservation', success: true }); + + } else { + console.log('❌ Create Reservation failed - no reference number returned'); + console.log(' Response:', JSON.stringify(createResponse, null, 2)); + results.push({ name: 'Create Reservation', success: false, error: JSON.stringify(createResponse) }); + } + + } catch (error: any) { + console.log('❌ Reservation CRUD failed:', error.message); + results.push({ name: 'Reservation CRUD', success: false, error: error.message }); + } +} + +/** + * Test Groups + */ +async function testGetGroups(session: Session): Promise { + console.log('\n=== 10. Testing Get Groups ==='); + try { + const response = await makeRequest( + 'GET', + '/Web/Services/index.php/Groups/', + undefined, + session + ); + + console.log(`✅ Groups fetched: ${response.groups?.length || 0} found`); + + if (response.groups && response.groups.length > 0) { + const group = response.groups[0]; + console.log(` Example: ${group.name} (ID: ${group.id})`); + } + + results.push({ name: 'Get Groups', success: true, data: { count: response.groups?.length || 0 } }); + + } catch (error: any) { + console.log('❌ Get Groups failed:', error.message); + results.push({ name: 'Get Groups', success: false, error: error.message }); + } +} + +/** + * Test Accessories + */ +async function testGetAccessories(session: Session): Promise { + console.log('\n=== 11. Testing Get Accessories ==='); + try { + const response = await makeRequest( + 'GET', + '/Web/Services/index.php/Accessories/', + undefined, + session + ); + + console.log(`✅ Accessories fetched: ${response.accessories?.length || 0} found`); + + if (response.accessories && response.accessories.length > 0) { + const acc = response.accessories[0]; + console.log(` Example: ${acc.name} (ID: ${acc.id})`); + } + + results.push({ name: 'Get Accessories', success: true, data: { count: response.accessories?.length || 0 } }); + + } catch (error: any) { + console.log('❌ Get Accessories failed:', error.message); + results.push({ name: 'Get Accessories', success: false, error: error.message }); + } +} + +/** + * Test SignOut + */ +async function testSignOut(session: Session): Promise { + console.log('\n=== 12. Testing Sign Out ==='); + try { + await makeRequest( + 'POST', + '/Web/Services/index.php/Authentication/SignOut', + { + userId: session.userId, + sessionToken: session.sessionToken, + } + ); + console.log('✅ Sign Out successful'); + results.push({ name: 'Sign Out', success: true }); + + } catch (error: any) { + console.log('❌ Sign Out failed:', error.message); + results.push({ name: 'Sign Out', success: false, error: error.message }); + } +} + +/** + * Print Summary + */ +function printSummary(): void { + console.log('\n========================================'); + console.log(' TEST SUMMARY'); + console.log('========================================'); + + const passed = results.filter(r => r.success).length; + const failed = results.filter(r => !r.success).length; + + console.log(`\nTotal Tests: ${results.length}`); + console.log(`✅ Passed: ${passed}`); + console.log(`❌ Failed: ${failed}`); + + if (failed > 0) { + console.log('\nFailed Tests:'); + results.filter(r => !r.success).forEach(r => { + console.log(` - ${r.name}: ${r.error}`); + }); + } + + console.log('\n========================================\n'); +} + +/** + * Main Test Runner + */ +async function runTests(): Promise { + console.log('========================================'); + console.log(' LibreBooking API Test Suite'); + console.log(` URL: ${BASE_URL}`); + console.log(` User: ${USERNAME}`); + console.log('========================================'); + + try { + // Authentication + const session = await testAuthentication(); + + // Get operations + await testGetReservations(session); + const resourceId = await testGetResources(session); + if (resourceId) { + await testGetSingleResource(session, resourceId); + } + + const userId = await testGetUsers(session); + if (userId) { + await testGetSingleUser(session, userId); + } + + await testGetSchedules(session); + await testGetAttributes(session); + await testGetGroups(session); + await testGetAccessories(session); + + // CRUD operations + if (resourceId) { + await testReservationCRUD(session, resourceId); + } + + // Sign out + await testSignOut(session); + + } catch (error: any) { + console.log('\n❌ Test suite failed:', error.message); + } + + printSummary(); +} + +// Run tests +runTests().catch(console.error);