Load/Save Table(envelope) shapes
-
@ustk Thanks mate, will take a look! No doubt I will be messaging you again soon! :face_with_tears_of_joy:
-
What's wrong with copy/paste?
-
@d-healey Thanks David, this is great for working within Hise, but I want the User to be able to do the same within the plugin... and even across plugins if possible!
-
-
@d-healey Do you think it would be possible to create a mini preset browser for it like this https://forum.hise.audio/topic/3273/custom-mini-preset-browser-example-using-filesystem-api
-
@ustk Can't see how to 'save' a file from that link.. do you know how? Do I need to wrap it in a callback function from a button?
-
Did you load the snippet from that post into HISE? There's everything in there that you'd need to make what you're describing. You just need to export the table as base64 and save that string to a file. When you load the file, you restore the table from the base64 string like @ustk said.
-
@Lunacy-Audio I took a look at it the other day, thanks for posting it up :)
I'm a bit at a loss trying to work these base64 API's but will take another look at that snippet and see if any clues are inside!
-
The table's are definitely confusing! Took me a while to get a hang of them.
This is where you'll need to start:
// retrieve table processor from backend synth var tableProcessor = Synth.getTableProcessor("Velocity Modulator1"); // export backend table as base 64 - this is what you save in the preset file var tableData = tableProcessor.exportAsBase64(0); // restore backend table from base 64 tableProcessor.restoreFromBase64(0, tableData);
-
@Lunacy-Audio Aaaaaahhh... ok that makes more sense! Brilliant, thanks mate :)
-
Also note: You never actually need to do anything with the visible table in the UI. It should just be linked to the backend table and you do all of the processing on the backend table.
-
@Lunacy-Audio How do you mean? The UI table is just a dummy? In this case my visible table in the UI is a global LFO. So I need to create a new table to replace this one, and link it to the Global LFO?
-
I just mean in the code you only do work on the backend table. The user uses the front end table as usual, but it's linked to the backend table. You just need to set the
processorId
on the front end table component. -
@Lunacy-Audio Oh right haha, all good :) Thank you
-
@Lunacy-Audio Ok I'm officially lost :smiling_face_with_open_mouth_closed_eyes:
I can't find a way to save the Base64 string as a preset / file of any sort.
I did manage to restore a default Table shape using a simple button callback and the restoreFromBase64 API.
-
It's just a few lines. This is all in that snippet I posted. You just need to save the base64 string instead of the other two knobs I save in the example.
var tableProcessor = Synth.getTableProcessor("Velocity Modulator1"); var tableData = tableProcessor.exportAsBase64(0); var userPresetFolder = FileSystem.getFolder(FileSystem.UserPresets); var presetFile = userPresetFolder.getChildFile("MyCoolTableData.preset"); presetFile.writeObject(tableData);
-
@Lunacy-Audio Thanks mate. So I've given this a go but so far its kinda half way there. I can get the Table shape into a preset file, and load it back in, but there's a few issues - firstly; all my Presets' table shapes change to whatever I just saved, and then saving/loading a new file doesn't change the shape. I've tried to merge it with your mini preset menu snippet in case you can see where I'm going wrong!
Thanks in advance for any help with this :)
HiseSnippet 4770.3oc4a07ibajcmsjngl1VN9qDDDj.PnSsVoL6Lijk8XiMd3GU2MmljEM+X5oGGm08zMaMbmdZ1aSNi7rFBw.4Ptr.AKPNkSAH.IXABB1+DBPRtjSKvdHWxg8Og8b7AkWUjrppY+gZIXGrKx.Hgtp5Uu526i58dUQR2YIChRSSlIUaqfqmFIU6Mj8udR1Y5m0OdhjogTsaK6NKJMJSR65o8SSiFJUq1MaQFs1V2Rh92u4Sz5Ot+jAQ7tjjNJIdPjU7EwY7dcOnS73wM6OLJH9BApezAlCRlnmLN4R.I2TdGoo8Gbd+mD4zmP1Mjkp8ZngwYIy7y5mEkJU6VZICu1+rjmNIm9ihSiOcbDowtR9.ix6tYx3gDDS9sj9YwiG5VJwoRR0jc4x+Myk+2S1NdXLqetd3snCnvmgn9n1MVG71UDd6rT3s6xfWMA3cqb381x9ClEOMiOBAautr4jrnYi5Cl.QXkSqzMF8Vx5I.ESx19h9mG0bFzfMiFOdmcdfx6uyN26iuS86T+6+8UHzNKYbpRVhxoQJo8uJZnR7DkoTGg6TGrUoYJW0elh+33AmC+2vnYJ+.kx03IQY5IWLMYBznwcEn4tjkfOasn9WlEO5xwZWlkkLYkbnBcU3RVePyxzG.SnNvDVDL2HMtqUS7tKaxF8y5CyadFsczWNMYVlZpV+znG+nFb0iQzn3IQoJ8GOVYPopp+jgJCfdNEbbSUFA.IWaob5rjmlFM6N0m.9xofecjR9FJs7AT9p6TWA9iio7gshglqRivIgJOj4y6Z6TBsTboWfnFIS3iWLV4Dqt7D21bhotmqwvVgPFTpNvxATUpdQvB7ByIe0.hQBGJrtVAHXiuwKOdZVLz8FfhBJYfYYbKHNabzFvKJcKgS4iRhSFjPn9E3xvI7tqSRwmuVHgOeNEL97UqbwmKnXW1RoSRbLdsKWNIysj4cs5kMe7kZSmlL8xwPXZ9FhFyS.rE2sflzxcwWEG8TR3.kSuVYTT1fyhm7DZ.fQwf4it0lDgL6rHkPXScgi5v3YQCfzBWmy33Iig.GJitbx.hiwRQRY3.xeiSfHJEHvgtD+fB6caHbyXXiEEJbKaJHIrYOe.gF2MNK5hz69.Q9s8OJIdRi69mCgTKl3yDUDUw6RBhzXPoo5AfEc7kQKQ.nKL.cFoDSbIdt21oSGGmkChOdoh9BR83j9CKhb.Z+FTF8YzU+yKsjj+3NGGQFKsQN6JI4Ye75k0UDeZ8Rb7HkFE8NOlSqvsFaLLpFgZ8.XgnOzUtbp4z+RrxrsuarXKz6x7gYFSdjnb2grnujG1ddeXlNjIaT6NmoOP4IUs02qJqlOS.kpFi5ONMZMDN3r9SdRzvFUIYMgPD1DsI524hSsoV10H.qA7qGNKp.EW6YQYWNaRUa6bk18QhECRLo4H7dOnxbpVL2GUsLv0LWV0ZvrdQUqwsFaPjsEBULDVj409BBGS8SnZagQDsDUkp4mTkQEmXEACLlPFDRM6WTJaOfW1ZYX65Oqn3TXhWAPIkIa4EiRBYRSYAkoBaiH+rH3JIAFPCvdZ1KZ9rzqSgXpKVxZwFwR8xR7glOD2RbgH6b8ormXmKHTnSd1yz4SIUeqpK2hI+T9p5askXDGRZGAlC0sOjzLswBP8AJ286sc9jfbjYyHgIqvrxTve1mSFgnUaP0VrSFkdOn+sDyuN8xzynDscVhe1LPs2XWZjIfN3eE5DgY.b9Y0WTTqjwiOgEEYBAuDRsPj46qb2knAlCiD17Y674zLvpo3S+QP4MjZNVJnWS35hsWKG5KfRZIgjSGWgOhHlhUNa19oyfxBJ.3v7MJKEjbtg9RHNd5B51B4+UCTaGmRGdkpnEpJftlKtXDBK3xyDRg3j.B4jF2qNLq5OqtR0gFMZoiUDqaLg0KYXxkyLacSrwjKu3znYkYoJITp1sl+ZPjW80fHdKMCxq7WfvjIlShgJXhlrpKGQp33BR.AEnB9UF8RRdyhKIIOnrT7PoZ2QVHLsDE1EW+zA0+u9UehzpXQd3YJKda4JAsmiM4+wXysxYycJXC8lHnb41xzeu6hSl3kJU6eTd281Y64+6J7.qtZ6e0ns+wefNs8wSN4j8st15Zw1W0t+EONu8Yo6u69G+o65Tz9QVmr29G+Ad6UPeqqOu88e3YyF794s24omZdegw63Dez8A1cYw7g+az8IPY+3SFqeEVRJzjj9gbIUEFBv3LMZVVLwtWyH5p3AQ4WY0VxFQommkLUp1MXGrSpV840Pt8mDMlpg98jm69Qj9RlR5ec1AWKpwdZ7vryDG8rn3mbF+9FO3u7fSeR4sJt0q87m+bZ2jJMWrWxoH38lld4Smu28HcC87WQ5tlrfjr07RhU+SKjj+fBIQo7pdnGhWPfj1WPfT9pClWfNHop.IYevz9yfEUX0qptHRG41JmeokFAVI+3exbW5pzhlik32+NxUOIjnDXJZRN9f7U+NzonTPcbpcxEvhzeFPZsaLuPJ06.RdByhiVRt0xWnHVUq7mMmjr0Jkj2PlWdrfL7ECVgLPtNkBpW.zKhgWZwPDzudNnemBPGM7nhKbn.37SZrJk+W7EUbe96iqBxe8rWdPRObszM98eWviOYre1kiFsWc0.rsoORoglpu+8paDp2oWYCWOjuenGaPOU6lVp1kMa5EZF3bDpkRCKjpw8pu2N6tS4fpdcXrIzQucYiVdpGAKfefp18p6aY5zB4UNlM1.44PQSNCcaqFDXVNrenlRWrllEpdayVsCvt9kD1D20pjoXGjhMFPcPnCC56+gJdHjNqcaUKb4uIS.2TQUoioiQYmAsCsc4PqK11v7jxVGhHRW9x0EPUQ2mn5RmR9.GF5A8Zpy0dGg5oXP++V4MJPePaSpVOukucnOSc421rY.aHcOUM+xgzvF8TzTaU1F.uYKlP0U0qY4u0UcwbUgFtqOAk4rT0V0S0Ifufp9eZnZ.wfkSvgpdJj+wrev5v0KsrvcEVREPz8XVESm.NkTgD4v6vvy7HAF4AlPdSO0dsB8b3lKOari4ILg.zD.2774zaXBhAmdaaj2g.M7IfPB1SK0dmvEplXOCEjuN1iwAMyVDgnTT7vsB46CPmbByWvmvYt+c2BsagGMxKnMuIYSQGSXML7Bsg1nivVTcfKYMzPFJNXAUudXfBLcE81HDeSgA1oCy5Q.bAwsUMcz7PprAAeCaUGlaEXYrLCXroope.2M.croEaHuPGG9PdXPKhax8lrvgFJ6KvWMUFSsvsTLYXxmDMQ0NzlsL.fYh2GpnAjZgE7FMngMJ4E53xeC1BcD34U1l3OPPCagbw5re2FiYHvS8DLi6fuay.A0MxwjGpAbMC7T45GhyStaDGPgcPvFjt1bfnBgGwVj1TdRFT8P19ZL07YQBVwB40CT619kXf3gp1Rkwf.jpUwOcQApPbB6xQ.+HaSXSfdQG1lAlsn.l1rEX.CBX9n4KZnawnMCcHQXxAoKhDfIeVPfHyfxQf8XcPkM7.8AKbB3cYirPXFNor+PjpCaK3QD7YYYxnAxqDn1AwHnMBB5UNHjawvO.LosJ5v.bcsYFGKHXghOOzpNxR0fw4Vp1PzuVkhteaUWToJsIVOr729gNP.TGFc.+HQ2fbCzfOJ6UGTmHEvpUGHPQC4XPIpopEDKh9yhHO5DSKDcCQhvu.ifTbV9DQwCRd4QRa4iHwl88q2NDfYA+n+NmDRBLEUHcCI9Ir10IqcuhbTPnRmVzEIGlVMwjDPtjg8Qfs.651iAxlF0G1exd0YI0eHrEknpYgcNAaqQ7zadLDepsoqkpea9NGgL5tlGax7fvgAtgr3gFltDOPyPNwVpAlN71FlNXeLaQ0.aDqRh.hugCTqgP79PdHk1HvX1F2hmvxxDhI6HrZ9cTcXAyM.na0imChD7Wj2swf8fMSBPERD0CTt8Tc3KV6PdhCVHhxER2zVj01p9bTn10QH2mlEMutIOoUnefEScR1p5SpynMxxhmCTHwbWZx8xRB73IV08BOlIMl7bZcxSEiZwjEGX2bKQ7ZfC03X.xPhPMUY7EaYopwsQnlbCFNrU6dba4IXLH5EtPljZv7DyFxq5w0hldJuQ.pC7CVnOX6dGNk5dXR.7hFsM8bKaX.opULHd9k7gfFE6PCC9z8yMa4MrAIgUUIT1kPYX9VXwpxHxLROPf4f1kVeZA9gL8jxdKa2FLP87vjjkFk84.5BViNdXl75gbCn4Q4blMFjKTOzBwwLT3.o3MVUjZbPBgjgc.ALIpkCj6topNiyNbv3Z5RhBAAOYXFYXpwQQGRcWLV2D73BTYEKCQNp6h4U8.6TXVcOg5PghifXrJvVIl6cOLDaszesqWQEDB6tEJwFhhBQ66wKwHHzSCxNh4UX4.E+yB8n4aRpmSbKbWVzBMDXM3a+cUcDppTCYwKFCBZ41i2.JvSIPrVMfQH1dwfPMdtJWXIfburyd.QLg183gAZAkKvgGODZKHqcWNgDEFuFTqPed8G5psE17SiRwDBKP8g7XSChlq1huKlvDroA+XZ3.LWW0kGG0iFAhWkrVHoJPCt0FBwpysZvol3EPXX5I5JzpEhMOnxLgiRAoGoaxKszjD2pcEhQ0RwVsi3AA3iBVKSjPlJ+tHDq1MPKf5w4qiguhAlGxUuMjJMeSAKLotoPzNLrsWLVXGGnRVLOklqETdJsDohfmXEc.nB9v46IE1M.IV73KGl3Fv07GB614oO8fj0fVpmP5TvolyOWhhANWFyXYHdjMpCluP9OG7QHaA3PbJDb6CfHFhoKaM2oc8P1yMYnXWmdcENnsFF2RvOAbnImetG+n+PwxfmzgglblFz0rnx1hRggytPNqSW01bSDBx.vO+NKBXArfsmVB0GpxO9kaaKLOmWGL3nPOBRQk3HKCHUaHGu7Jx0fcb5v4d36W7cTMsTNzjelMCrtfegFbv9.SalxvFjCMUdRZ5g0sTbMCDx1aQNUT4QuvV40kWf8dAs4dEzioTsFDav3ItjfsyVMP3H5lN7XufwvVUXoYNrGh0TzA8I2LAkHykKrWKfu57fvX3r47C7bjpvoTYxhupkPXOaScwy.fEuRDM9HvAE3we3Ql0wNvgi4hE3NviwAITzD1rFzU.D5XaaU9cw3hg5qgCSvR1fHGarE+btVjjz7Zp34qKOStSGVUHnlH1tD.1kGcU5xzH5cxUq1MDuo4gCG97hmG.6h0diUce2uq7BuyFq7BVeuJ2wmzB2w2Aga1UDyAa4soKJ.k8M+kh+S+o+c6rjKEur6qJe5N0tYsasI2O9aKW48aSPt+Zs4tq+JxsxWrvEv9nEk6koYyub22T7xc+DongwzmnNA5qwlwQ96HW8kXYU2pOzXdn+qOcAnu+lAcQCzO6m829KVho3ryR9lEsaPG+ajdW7Y.7fhK69M32t6Ck1rGKvskye+fDE7SDEbqJB9W+oupBdNFukLrXUu+5JOagMC54OGf7W8lUZ291F92VtXAe4EgEiYTWt7czVD+RRurOdr48S9O9O+lk8Pu9m9m+ue5pBPr7PIys8u9F9PY4BxA9BFhoSqFy6unpf70tKZHDzPh39i9n+8vkHhdd+7uYQw47y+GVHL9q+R77gELMABRzu3pWrD0YikHU0+kkIQGd3e8RhDzq2OeTobRhhwPrRAjk1j31uECIK9DMejff9a9IuROQSAAMGm+wBqWB8UbSwbR4Sl6E8fMu8K7IwuxcPqEZERlbsuWMI1SjTt1+Cwks78TvDVlWSl7YGHIs32xwaIamLj7dDN+mYB4aqoX.H7wbeOGjuYiIowYWK9s27cx2dxlB22V1MNavYKGu2XI3EBN7cMdK9RdtiLZznnAYbvdK4lG+c+msiHTtcNT9ijaMN4z9i4JPvKBPUT9muyeRwvJrwUXDr6Z9tq9ka52c0zM96tp1M2XMxKw2Y0s9s5uypM0W+cWvLk9s5tyWBEp3WF1alCYYRbFJNKh37BgVyYQ+3KilLXtcmDmDStO1A+MGzEh2NJY1EEuMOET9GdfUzS.cfHCChf.k9WOYfXm9WjjjQ9bIl2068NvJIYJZBID7PQ5cOqeJ4EWiVcDGW5WllkbQIV9cl2SJ+rnozWTpZel7iez17wIz+P72NsWHj5M2Lmrk3XciMdu.3iovbqHaI9s7LU4Hl4y+6.Hds4Vu4++L2pWBTu5jmX2OaVLT2lrykW3CIuFDAHYBb5HxKcJbFJxTos2gzlnY7ilLj134veECtKocshA2sbv+OYMtn+fYI+vxudTvvcaZOfbOg9IOukrMosB68DUVdms2Q5BH03Obv.h59OEzOKeN68JLmG9JLmG8JLm2+UXNO9UXNevqvb9v0NGRUIpWB4fx2JBc3hxirWikEq1Mk9eAG54Re
-
@DanH You forgot to put
data
in front oftableData
in line 78. Remember thatdata
is the object you're loading from the preset, so you need to refer to that when restoring the values.Should read:
tableProcessor.restoreFromBase64(0, data.tableData);
-
@Lunacy-Audio Amazing thank you!! Is it possible to save these presets to a different folder and as a different type of file than .preset? For example save a .lfo into a folder called 'LFO'? When I change the path and extensions I get errors....
-
@DanH Yup, you should just need to change a few lines.
Note: This might not work unless the subfolder "LFO" already exists, so you'll need to set that up with the installer.Line 85
return FileSystem.getFolder(FileSystem.UserPresets).getChildFile("LFO");
Change all instances of
.preset
to.lfo
.This works fine here:
HiseSnippet 2740.3oc4Z07aabbEeVIsFhLVt1NFEEEs.KzIpZUFRaY6JajZZIaYqX8Aiorh+ntwK2cn3FsbGlcVJYFCgZfdnWBPQ.5odp.EnEAnnH+ITf1domJPOzK8P9SH28A027wt6rePpUBwEInDvFZm4Mu42u26Mu4MytM8IVXJk3izJs0v9Xj1o0aMzKn6xcMc7Pqdaj1z5M8wTb.Zog8MoTrMRSax6x5UqzTH9uu5lKY5Z5YgiaBg1l3XgWyomSPbqMabeGW2ULswa4zSQ5EZrpEwaYhKY.fjI0qg5aZsq4N3MLYhMgNR6T2w1If32JvL.SQZSsDwdXqtj88DxusC0osKl8PcTKPQhlWg3ZyPLqUzxccbsaFxXJBoo2Ll+SJ3+EzW2w1Ip8X6vY4cXDOBU6g1DiCd0UgWshCOME3Mk.dmSukkuS+f3dXX6szW0K.62wDbApvRHKZB5Y0Wl.R3ETsm4t3U7gGhFQkqVq17FWoVs4twLkmo767NFLY8ItTi.hQarA0bOrsgimQedfvLkAeEMvXOSeiVtNV6B+mM123cMBmicvAKS50m3AOTYVEYlkMEwidIr4f.mNCbWZPP.wajZHkbozRfIXYirGfR3AvLUrUhdpL6ZqrY87F7sMCLgwkTQUwunOwO3VzkLo3qtPkXyyswcb7vTCSWWCqPSkomsgEzRaHvkZzA.hvZYz1mrOE6OSYOHVlBw0XCwBpkDcX7xYJa.+hwjn60bfGGkEIVDNeXiOtopTlrbbsrDQUHdw8K6KbfomdVXqPXd34XbroDLBJo6He.kVpiBVPTnP7QCnHQhgRTSi.DQ8W3oey9ANPyE.ERIi.SdZaKm.WbAzEWtbzjnWVdxsHLoOhPlXAmcbLcycGKj1b2DF3M2czF2M2Uwvl2TsLaiC2wNcBQRLkhlF8zJ5OWeZeR+AtPZ53EDURJ.rDuoTFZ3p38bv6yRGXzdnQGbfUWGuc3I.53.tO9RaVFxftXiGBKpkAp1N9XKXaggBE634BINL5LvyhEXjKRBSGv94RfLJRDrAeJdWo+9dP5FWXgEGJwdVJvjnQmLgPkYcBv8nyNup9p9QDGuJy9yfTpxAdfpgHMdyIIREqPW07fG0c.NGBvmX.5Qhxbwg3Ytpz9tNABPbibodFV6RLskYN.qeEthdJe1eVnmj8KN3XaVezJB0EJxA2X7bcD4mFOic5XTQ1ZRLSSosJEFFoyPMd.jI6CelCGpP9iwLGs7svzVo07hgiblwYhDgCA3WDm1NYLbjMLhab+drRm2Xmz954Rqpj6DvkpRGSWJdLBZ00zaGrckzhLlTHJKhJh8MQdph5YGCAFC3GObxZ.Umaebv.euz91Dk1cc0hAYtTABma9TiIcwbWOcYfiYrQUqAi5npVK1aTfLaYRUXCSRRquB4hL+LoppzipmHMqRNnT8pNvTDCblvNHrZ16Exs4M35HxZDl6t7AxJTgQuGfGZDAEUjxxax22BpUEVKw9SYFV1tXfLvbv2BiuoFcHERrlstU4pwPiSNARIyykSbDa4aKt5YNaofJMFuEJcNd8.riFwWyypge1j6UUtTZHjcWQiWVtTI0TQr8iTlPnfdt9oUx.+4Ml8GU0sCA14Lvmk7LklB2X9oOi0CyLWga9hNuDcNn8Rp651e.sKWnpAjVA9fenRcd9JPN3eRijxH.MeP4r7L09fwCHKeYBbLnrR95KZLaZ5m.fLc7zZOiuo7sna19ifJdXkgjKhGSFb4Jt7wcFHlLpHG3xAZrNptuOTlfDc1h0L4hvXUcmW.40oYrpRxeBPTUGJuuQZbxTh.eByNSLAkZ4.k8S1f.LzqxbkgQU9fxFo6pSmb6Sl3yko5b5lcSM9iafU7FzqM1ObKqPAQZSk7NQzG8chndkMVhiAnHHwaUOGnbFr2ntoDj7rCHP.Ipf+JfeiImQdiIhLzHGaj1L5J4rQbXKuKpFk+2+qahFkJD4p4p3b5oxfmPMheQpYJgZlQpF90Rv0xz57+td1AyBQQZ+A85WpV0j+1aSq09fkVbuNU+3qsL+4G48jmr3ZCWan5y6cOydWU7bW5h0W7Que8MjOuvZO4RK9nq8fKIk+tC28dW7xc8sth34Z62d0Kpz+82vY6KBpafb7v+04hLnrnySbWduMQnGtJaaH1MVIcDfyoO1Ovg420tMdOGKr39qJoeaLc2.Rej1DQmxCoUNoEpooG1kag9N5ItrDzKhLR+E+FCUsX66XGzUs2tXmc5Fe4iM9EMZuS3ULV5TGd3g7lYkclsU1QJhakRGrexVuDqYnkeIqYMcElTJISVyrsjIeWISLBu2G9I5UHDZQEBY7xFIITCRZBgVuQeSeXRUl8zlKF6XWcYxoF0A7Rsb9jD2.KJq6Hm39yqm9XQpLXUUWxiZHl8Y3CwPJsCccROXRL8AQ0lHIIQOtAaGhUkmyjcElGIESaU9oIXRoQxjSqGWqrBGdt0H3.6tUjRmAzYwvwlFpf9sDf97RPis2Vd6CRfGeriQY7e9ySE976bRCxuz+3CxATLeVAGm5ZIaa6CCWePY.bYBwsUvfNctbBdc5QsJ+s0ybr0QFVcgTLCkgYMdXwVXDSfvbHpjJrsjoB9zO82VKmTAgMuW3dZZSpMUQxJbN8TWwmBue0RIxvkh2FOOSX2BY4cdVVQH8YTCouIBC6UaJg9X7YwH+75oOG+nxkAOjD5eY6LPewhAcUGzm8Y+luHGWQ2tjWm0uAM7WYslMy27xk3iLpczICmVWbEIpD+IpDesTD+Uu+Ik3BLNkNLYoW0lJiZwftH6m31GFoe6qa3OstbBO9THaNix5gulJU7iPG2hBRFm72+GuNus5+i+o+y9iJAQ9oRRr7ubAKEMlHMZo3H52OcNuedZh7plYcDJVHUbe8q+2dXNT7AO3yecV5r6t+9CkEyld6oBUUrhqYKEF8E6czL59ElQ25V+47Xz68d+pbxD73G+4cB4IKKVDhMjPFUj71mMBIYqiaAEh9UexIpNNEhJv4OPY9H7a4yXUuv5QNpx4l9HO+wHWAMVnkpDirqtHM5GdJsUgo6T5r2.KBk80ZeV80I1rqTM4abm8YFH6.Rij3Uayd80dTmfgpeFBuQdM7EEtmSuoSfU27w6D4fWHIwaZ7J+nFlQ+Nc5fsBhA6T5q7n27eACpPYZAT99520kz1zM1.BQS.pvhujgenrain9MhDn9X9DT9mE8SPoeg+DTzlrvVjiwmbxTei9SNonw5ucF2D83u5bxhg3i3Ci4LBXpyxsvwlLKyQBmU7we7.rmUhUjr.iUiiqZ7qa7APt1ND+dx6uPJ42qwZ3c.dqpvsvPRxVC8rTarUOBIf81hSFtcgFqQH8uiGK8qsp7M6ZRYWUGuxnXbs7.Z.oWHV9VyMC0J.2me0PZOU+pKTMtel7WdyuddFcLBrpO9.qIJb7ODiYDEVwVF7M7cmDHNJl+aAHdr6mN4+ete5CHPspd6rtYfuCTyl9FC50B1vxBCHwCNYD6Z1gyOwFJ+4ZrmYVlVXOa9CGB+jcVm8rlry5gc9+j4nmokO4CC+34.G2z7V.d6w+hOKouN6YinaFWWuV0Zndv1genkEyb+iA6S9i4Rmfwb4SvXV3DLlqbBFyUOAi4Zmfw7SF6XXUhbqAvdPhkhPCMuiHytVztXZSh9u.HM5g6A