Is there any way to observe when a device is moved?
Hoping the answer is yes. Is there a way to be notified when a device is moved within the set? When a device is moved, I would like to use its ID obtain its new path and save it with M4L.api.SaveLivePath.maxpat
I think the answer is no, but your method wouldn’t work anyway.
Quote from the documentation:
"If the object is moved in Live, its id usually remains unchanged. There may be exceptions if the movement is implemented as a delete/create sequence, though. When an object is deleted and a new object is created at its place, it will get a new id."
As I understand it, moving a device may result in a completely new configuration, i.e. previous id (and parameter mappings) are no longer valid.
hmm, the snippet you quoted says the id "usually remains unchanged" so I think my method would "usually" work except in the case they mention about deleting/creating.
It’s really blowing my mind that if I want to use a M4L device that observes params of another device, I can’t modify my set without having to rewire the M4L device next time I open the set.
It seems like if Live assigned a unique GUID to all devices on creation and retained them across closing/opening, this problem would be solved but maybe I’m simplifying things too much.
It depends what you mean by "modifying my set"
If you cut and paste a device which has a key or MIDI mapping, you will lose the mapping. There’s no way that could ever work.
If you are talking about modifications like adding tracks and changing the location of your device, then have a look at the left outlet of live.path.
live.path has two outlets: follows path and follows ID. If you always compare those both you should be able to detect when the device is moved. Than you can grab the path via the getpath method.
I’m using M4L.api.DeviceParameterRemote.maxpat which makes use of M4L.api.SaveLivePath.maxpat which uses the left outlet of live.path and outputs that back into the live.object and back into the M4L.api.SaveLivePath.maxpat patch. Is that not enough?
(And to answer your question, by ‘modifying the set’ I just mean creating new tracks/devices or possibly dragging a device to a new location)
I understand that I can compare the path vs. the ID to tell if it’s been moved. The question is *when* do I compare this? If I don’t know when the user has moved the device, I don’t know when to do the comparison and store a new path.
Seems like this problem could be solved if I had a "DeviceMoved" event to bind to or a "SetBeingClosed" event to bind to.
M4L.api.SaveLivePath sets its path using the path message
Live.path’s left outlet only responds to a bang, getid or goto message. Check the ref.
I recommend that people who are becoming more advanced in the use and design of Live API patchers get their hands dirty and work at the object level rather than the abstraction level. It’s a little more learning pain, but worth it for the flexibility
Seconded. You can do a lot more with code that does precisely what you want instead of reusing code that is, by its very nature, designed to accommodate anyone using m4l for the first time out of the box. Most of the time I find the abstractions included with the toolkit to be too cumbersome to use in my own patches. They are good to study and get an idea of how the API works.
just a small chime in here, but it is worth pointing out that using pattr to save/restore paths in abstractions, ie, somewhere not in the top level m4l patcher, became broken in max 5.1.4. apparently it will be fixed for 5.1.5.
see dalinnen post here:
is adamribaudo currently suffering – partly – from this issue? (i am!).
other than that i third andrew / amounra – always build your own.
I feel like we’re getting hung up that I’m using M4L.api.SaveLivePath.
My original question, and the question that I posed to Ring, was "Can I observe when a device has been moved and take action as a result? How do I know *when* to bang live.path to get the device’s new location? "
Even conceptually, I still don’t understand how I can build a patch that is smart enough to re-save a device path after the target device has been moved and before the set is closed.
pid – good thinking, but that’s fixed in the latest beta so I’m all set there.
there are a variety of ways to keep track of devices, here is one:
----------begin_max5_patcher---------- 862.3oc2X1rbaBCEEdM9oPCqi8fD+2csSe.5htKSlLXPIVsXgGPNIsY56dER XaRZhPXgUociwHYCG8oit5d0yKbbWW8DtwE7Av0.GmmW33HZpsAmt6cb2l8T dYVi3m4RwOVs9atWI6hgehIZt.eGttr5wCcbWEk0P9ItsSn2Jutlo62RnkXl 3YAO0X0d1qacWFKeCgd+s03blTg9P9CBfRhauDhZ+DlrxCbS2egTHzBWeKS6 KDZ1VgPb+XMIqD7opxhCcKewrerCKeEttfaZ64WKVz9wUlQk7MYz6wlyD+AY RjfFAQpXBz+rgxU.WBkc3xThnZ9KCCHElCIzfPxOQ.oXkPBZBjlTzTRd.uhO Z1bQMPvPAajWBgpXSjQnYxwSUVwZ95qKZHGIVDONPXnJ3DbtvQLFlRvrqluH ETfefji+RUi47wSwJqDgiIV.nDk.BMXL4yAA62tFWOvPbWMtASYYLRE8EQED pNMUL458GZ2vXNnvSj4Md58Hium6anz9u0w5o5BVO4VqZvxkKy2WW+4ywc4M 5M7kLTF2NUYbaTxrXG+i.5q0Y4e+hBGjWO3D6qbSsfYAbjAlXikLiNnDJpWP ovTkjAMyBJ0Od5jGSpyxnSLID5ekXRMFESZ7lKOQR1Hudad7tPL5R3t9qUqQ 2PGFKtDjnbnGOCK1n4riNOZaBzOnmMINPEqh+uxkzMx0xk.mitDF3dLqstKP 4EspTYsExSyHRcpyylZR2S2wW4.jzgWe5sM3tcza.jtZN3eybtEoHqP4FWcG 1QpxyAJz3RVO4ytDdMQM97NZGbifYnyrNVn+vlMKmH8VbSS1oPRmRVr0hw1P ZtU5pr.d7EalmH2RO5cpUaVjIsMOZnHgmITcAFS6ICIdE7AI80mMsPjss+Rj 0TsuN+vir63eAmDZAtgQnGSf85iyj89MaHEEXZ+M02RJ1UwWu2Ig.uUgbKxw CD502fD1FTvgu+NS25NBf9ZLDRG2PvPIknghhrphfZnHjUUTvza7LTQHcl1P oyOM0dpX1zKoyTGDM+zDxtZpsvtg0jkiCnilhspj3IdBBGhR1UR5riBztdIM TTh0UDTCEAspQxenYs3YWh.giSQx7lfxCylmG9gaLToQZLcBsqmGpSRKPSxQ feyuV7a.9+tz2C -----------end_max5_patcher-----------
Other options include monitoring the currently selected track->currently selected device, or managing/querying arrays of IDs in JS.
Thanks so much!
I was actually looking to track the movement of another device, not the current device, but was able to edit your patch easily enough to do so. My implementation is below.
This is just me ranting a bit but to me it makes sense for Cycling to add Ben’s pattern into the provided M4L "DeviceParameterRemote" patch to fix the problem mentioned above. I understand the importance of learning how abstracted patches work, but every M4L developer shouldn’t have to implement their own "Select a device parameter and hold on to it across sets" sub-patch. That problem is common enough that it only needs to be solved once and then everyone can get the benefits. Then, as the community finds frequently used patterns, Cycling can incorporate those abstracted building blocks into their distribution. As evidence of this problem, look at the "utilities" section of maxforlive.com. I found multiple devices with the problem mentioned in this thread that Ben just provided a solution for.
What I’m proposing is instead of viewing the provided M4L patches as examples, view them as the defacto way of accomplishing those tasks that will work 95% of the time. And if they are to going be the defacto solutions, update them as problems are found.
Here’s my implementation that tracks a device other than "this_device":
----------begin_max5_patcher---------- 2921.3oc0cs0iahjE94djl+Ck7SYjZ6kpJtFsZklIQZUjxN6n4xSQqhvlpcy FLXAEcmdFs+225FX.C1EtMlJOD6.TXNmuyoN04FU+We+2c2h0YekTr.7Vvm. 2c2ewNychywOycUm3tE6B+5ljvBw.WjRdNa8+cw8pqQIekJNedVIk.1GRer9 Zok6hSSHTwMBqNabjX7rejkNVMGK6GnZvnpS+PVJMMbGQbK+XdbXB3mxRhpu M48PeYOQxEKVbO6ef+S00YzylGiS294bxFpbHn.7Jq6APOa9WNAhC7WYc3l3 Ozh3+T7SBsVYIN8+66+N92rut+UiU6yI6IoQiDsr8G.sfWNZoERY6y+RhWSD RsiTTDtkbLTskPGFkP8gRtyCJEf3eZ6I.I2ap5TR7SjUrqvII8wI6YRaB5M4 y6FTa5WIOjSJdD7dxSwaXV9zGsfyDZ4x+z2eB0pVKd5j7ZJ8ov7ZF4eY+wUg 6iW8ajDFoIgM8sX4ETOVlIuBRJMjFmk1fMgNBkAwmPKuUtVVtVAr4Qvl7ZX9 V0pTGN2.hgSR4qXLNiaekxDaogPHj+EJnIgR1slD0hdZx2sufB0kRlJQCStF mPdhjWzY72sXDzASlucSVRVtBjEiq9CqNiLIayWjTsU8Yi3STFwyKisd1gav R8XN7QmgFmNDtHdzgkIzO2UAu2A7P3FxQTd8UOw7w6VrMONJKkSMs+A3mu54 9IfXlmeKFPLfzv88cyzrrj0g4OEWDuNgzlwXyCCSi2ERIzXIcgrNbmw61mGm Ra+yQRCY+LOVrIOKIo8ul7RO02khDJ6OGGwV2j+y0.6Z4vWS8tV1IZegN1K1 jsaGSxUCjsLvtb4+n0E50DQWyDXut2SiY1VMuzwB0V2YOyYwtBInszDJBczp NCaL8tCFTU+26mFPi9HAvlNPyxIfrG.7C2jky4A.6lJAwoQjuBdLr.Py.OGF SAkoz3Dw.kCn.vLajPhX22t8Ljij7B34X5ifvjDfTc.vwshVDPRbJYSVoToy a7hM6ITrYY2Pr4Kr+36YVhsmIfhvmHBwPgXUFl.ng.SH.xJyAb+yXifNL3iG O3ilPvW5KqZpixfeqUjuMnea+caC9Ly7j7jrmu.qMvSfbvSibsWB4LtPbF3U oa6LWljNE5VEfZWkVs.Xjo.vtBaHtdFH.SAwf0W.zZcBnE8pgVt+G2yhHHLc q9nLVZr.sxwTP4lAvTYXdobUvkBSy8KSpiXfYT+CoTx1CwDIFXCOpsV4X6XE 3y8s0u5+3DffNdBmraiAZIZgAS5rFgqk5JRs7qhGy.8VZKCSDq41zuFvCY4M b1o3ZtTKbB8yAILQg7EwI46NSKzd8coG5LcXFzpInYntzG9ElRYHy0uBpvm9 7vMeAvhaDDxVVcSNgEEXyqyUcCeJLNgGT24UhcFs.wcx0gkFMj5v7Ud+1WGF O85vVFbXoRszNJo0JxCqbhFMR6L0JmPe6CJmsSc02nJm9SttoByLScy+NHIK 6KfPJ34GYeDWvh4tHNh.V+BHJqjaDcSR7luv3LvajI37G.LWDd2tn+16n4IK euXPKeGePf2TlpFyvZ0ti2Y8ITqVt1WK0ZOGiPDsOOilwc77Pl3+3JUxtWVT taWX9K8KS+ox3jHl4FQJTFZMwUfwOWwN3xkDBWqAefFxTTN6DG0LFkocYEtN swF3bJUJJqp8yRZLCP5WrHKfBncseFwpnG8q1JNJLOxIrM+S69CcZhjUtGJu FTlh.7wNsjucslDZSoJWAv.lqQyFZl1usILkGCUdV41GOrrdw8M8L8jtlJbi kmyYlgWl42TZF6Lfx0k7Iuq.+QAOsnLqxBhox1bHnReCHqVMOe1QwE6SBeoN Y1q.+6R59RULdwQUYDuNCqpv9dC6dWyFPJarrOY+3sq32uDly.EZ8y5GVcMi Izw5UXRYLZnxduvwBUUAtarwj0kTZV54z5rUpcLN3BrPfzMyGGkUC8xTETki UrakqLUNzb0gKIEpAbIzDfViGsbz1sh97aPoTEbDRzNQWRSM7G4hqNDIXwqA BYMDBAuQ5SV1yGJ1oEW5D4VBILeXfCMTkQbm6D2KAVk2sXmi55ESHw8qujD2 iclzD2Kzauer5utxDnACloH7DNKbAXIti0id6rnpF2fOO0peFrsT.esJeR6V PcPSwxvDvptpYHZbv9jQ.JTxNU2br3WYdjksi+rum+gvgNdzuJ2kBef6Jztr mH0C4mynDvGIoa4sWo5bLU+0uTezNZ5p8DRNOh4EmV4n0jEFjT2uVyRcKiit .2Pl6xVVs3rprkXCrrk+YBX2glwU+UVfSacK0bFmBesspJyhAVV30fXP73Ud OUFNvWskWTF3zpVhU12T8ekqYpMGQRBOUVMFRg1yDzmU8zlzaIGrQpOm.Rtf D1Y.nqxIIjzZAdtP2S5muGvGDvdtfiW6RCu8m6k6jt7T2rAAFn29UoT5eRn+ XRhLEnenSsul11BAglYwT07.kXBYhcSUCwjTF8yG0qqSby63YPVrT0FBiLaI EaB0uyCR41NeB5ZFymT0JBhdctg130RfmQ6gZseAcvGv.xuhrx7MU7PkC6fN jTDofFmVGI5mND1T2Q9XbTTm2LBgVRbz9LlyiWPrgimAf5x.7DpZhL.RWFfm aISjAb0kAPFpDfYTG.0RBfMSFHPaIfkQx.BxRKI.7hUgrkuBh1NtxBs0yQPj 58uDJ5wYzHKczkw15I2LSiuHsM9hMTFPaiu1FI8i0d0aybhOVeEnK1zqskX5 rCTl9DoiXsOBKqXLhE8ui5noks0VtEXlhMGs06bMWFPuk7MTFvc5m3LoLfs1 ZPdFK8qkBjYR9NZa3EZlNsquO6GOPCf7Cz1gWKik9QZQ+l4JXZGwz025YiT4 rup2EKpo6ZpVswp712JQwpuUjF+EROZopNcMO3fiK0O0p+y7teMc3EY+Vsy5 XKSSpqyrsgM08kW+76jNA2XPBKqdqpWD54cTe5AoMOFltcDa1PGdcsFn92W1 lIWe079THF1cf5cO8HlbK36PuunAlAmgMfuJjB1bGSy+1uioMtceO2IQ6RCz RV3MrefL9z4.sxBijs.h1aUgWcyUs6rw9e40kIqyqwNJ1sdacjYkP0vc+RVg 9vEZHy6V5hW8fGNp2OZ0VnyjBHk6V2XCj6r7K15b6KbXjjdgx0eNt4HuZ1q5 cOunW7r5c02eHRZv85so2xOX4xkaJyye+oU9r5S46VushVAjxbrGLG1+qwKQ En0Gqf25MMSaqlXkGd1rpQGFn50wBzDXQy1soEsocm6cjVzNzlNCYQS9J2HM CaD1ypTsLQ6YEZZOqWQg6Tn5EHz1vxMA4ffuAhGB4MqwCUgXREKa+Y.wJzvJ euaasSgBjrw4TJPS5do8UKf5YVARgXynBDEnRm0glXVi4cyQH0p8QFWQ3gty QvOko646LLRzhEd8mKHJuFJ.w0u13wi3ON.Cfitu9.tuu06pkFo1AK2h6jqQ FflqLVL1838asm8UpgRWJlE0vKHyNvYJyNHYBKT8Auy38sWNv1M9oB85V3iJ L73B90tAPFpZMsGzwU5XfpbzqjUaZi+G7hySac4faEwYqCw0kEtQDmWfVDW6 hUqAwgsDaym9xtiwt9fqChpCM2kyNOMyiyg28NR2QkL.N3ZQytZCzFqVf67L +ANMh6JIrm3yCGbUHZLRGhdzy4QNhVQCIywOF5UezUgp0RMnKqoARKaKN6.4 ePHP9GeDRlG9J9yw4JwQPrNrTvrnXq0hVyybNslxglERCoErgBLXhCOONh.0 ZcSHxfINzLoy4oEwMSyU0h37lEZi2krNmE2lGZaZVg9pQZPcHM3rHQwm0Fhm 4tfpyn8dQ5kEV1EJX4e+BDGcUHZWcj0v4ItZnV9Az0GqKf33mf80+GTAr4jO -----------end_max5_patcher-----------
Seconded. I’d love to be able to draw from a library of ready-made source libraries to complete my objectives, it would save a lot of time.
I’m looking for good solutions to the same question you originally asked, and haven’t come to a conclusion on how I’m going to solve the problem. The solution works for a device, but what about when trying to keep track of ALL devices. BLOAT. And the more m4l has to keep track of in the API, the slower it becomes. Up to now I’ve just rebuilt the id table in JS with each track addition, but this is painfully slow when using a lot of API objects.
Max has been around for a while, and I’ve been using it for a while. There are a lot of resources. M4l on the other hand, not the case. It will take time. As much as Max is a niche developer environment, m4l is even more so, and that is going to make it harder to pull more people into it.
Just consider me the (sarcastic) yes-man of this thread ;)
To round things out, here is my "M4L.api.DeviceParameterRemote.maxpat" implementation that re-saves the path of the param after its device has moved within the set. I feel like it’s a little bloated but it works and that’s good enough for me for now ;)
----------begin_max5_patcher---------- 2543.3oc0bsziiiaD9bu.6+ABeIW5wQ7kdDDDfMXur.SxtHONMyfAzVraqrx RFRzcO8tH42dHKRYK+naI6lRp6cv1xhRVr3Gqp9JVEk+8u+6tY1hxuIqmg9S nOgt4leW2xMPalVtoogalsV7sk4hZ3FmUHerbw+Y1stqojeSAsWUtUIQaDpU 6t1ckEp5reSZtNlLOno8hsqyJxkJ3AhaZU+UWtJq39uVIWprxTbHU+sPL3Ki B4l+RBlGf9RqGkteadVj18bgXMzyy9gpLQ9Ngxd6pm1Hs8wrY2p++8OwrT3K oGie.SlAM9e+9uybTe31dCSKKWuVVnNEm9o6PpURTkbcoRl+DZoVTqJyykon T4CYKknUhZzxUhh60MkWtTnxJKpQYEv2qVptEUKdPBmomLNDxyyJjKK2V.8E yaSD3.6T.NlAG3vgPxyOUDzioh1Pcx0C0WqFYvU.DIjDPILDNvSrfxUoQh9q k4oWkZo+gpMUxMxhzABrXfUbDqKvBe8f0YAJV70iTqk00h6kmBU2KUWNJQ5F kvwQfuN3u3vQDkB8u9Td1Cx45qXFj9FnHVWQca64afh7dPaJNJ1fKzvfoQah R7u1Tp7NYUd4idzyjEd3VkHNYrUkF.1NaDC9GhnXPQJrKHh9pX5xLgJYObdN O5PEePVp+wrf1txG6nCvCj6bOGa.CBGfYCnjiGV0qmGtF.xOEx4UGk6c7hxC 2uTnwV0h+dIPAGVES6GV4au63f2GlfVW6jDt0Q+TYBh4Cvxr+vG9K9CovIPb BLqecRmNqtvE+FMHNgx8o6GNFP.pcob3ff47w2+SzP4.xlLl+Wmv0xx7xJqX FLOIlQwra0eJFqI9iMeJfGjn+.9HboetsHDZKsrvjWgV1gPbaHjsqUSRjR+p 026WEJUU1Bc7P0NPrAEuYlFBUYEoxuYQC3+rWyMO3WCWWRv1HpziHkrxqAnQ I1XxbwaD3aKYZvacWYQssi8tmLJy+Vn0KE4Rssk1p5xfgvts0H1DLGmzk6Lu uL4gfy6OijOHqdBoxVaSObqnqPY0lbGiTkHAj13rTziRjHutTeo5s5Oh9bS5 H97LjKiEHQQZS5l0OAHpV8hzJ2c5xUZSzOW74het.kWJRQYPWUIqUkUxTS+o QcQdNHP6sp0Clr6KLii4mO40Q9i6xZsyCrbWLvBvjsMeoz6O56GDU65u+F6i yEaxl+O0n+G0Sj+hF6+D9KmNseta7xnx3LKuklJq4C7DBlG8RTYuDjyrlWbp M1ab3TrbEZz6gD1w37VdjmfD1MDIIekLeCZPVaWnCtr1z1U3M3v0h6upH+Zi xCPF+13Jcn+BNnAbirqHLn2KbdUVZprXPpNwPDQERnP2kUUqLTfq.1MMKXQl RKkY0xVjanEOooMKR03joBrhChKE38z7cOloo2.x0i3bMjm6ZysHCzdxycbg 5aST+qn6J0OUUMZsomzsoGLnGD4ak0vkzS2Z585rR6U0.3lsPet97LnI9Vuf PsqIowqdf2nPYCPUCVlms4ZBaj1ivFcKQKbzqnIa.rFVHzJ2VsoZq9140mn9 aYXsWDhKQvX+oLweenL4VEpaMHiuxD+UDejsKlc4y7tJtg2sxydt9y1xc7r8 QwZ0ogfQxJlfwSB90OdRN+3Q7sgplWfQNPyXnX7aVkcoXg43J5tHX7WeZke4 J7DLTvnwwoGSxbvAbKSRwCCGn83vQzJu5UA3vJGCBOdrWzTHcBb0XMrdUtZB Ym0Ui0ef96d8iJXLb9AUP2ATgi38aPguzIJ9YGvUhGcNA+Tv74yweYfT6MbR dSo2o.znzGL5J8gCEJoY57GJYYjaPIxniRQCQw7V.+K26zzTGoCtyB5wtZbx RSd5wmA+hm1cYvvViulniZpjLdrC5OLYz8w2TzsgxGeTvY8wePEDG6wrK.kg aLiO6XFVJuprI2P.E2sn6xKEPkep2EIl+yhfv0M5EUrRVIsIEagDAkuKU+o7 xGsUSxknLK+6PmpglY.2FWfD64jMDQFKrLMyLpxe5P.773GwiEOqM74bak3O 3iN.v2iRz15Sy55gJd5FLwdHzZlJiSBUlFQteN5mTHSMQAHunzrW9JjUBkoR nOg92+8e7mQ0J4l54Wxqby0C7zD2xnYMQy3IfmjLnk8ou6nldSbZgCWwxRHu SJ6CN98PYebXqcqg7lnpODOlm6MUkpRSOtux5ebtamK7g5sqWKpd5TT9esuD PUxMUxZ8irV6s33smzyjOX70DRNkuuDvD6lyDmb86+KsqLQd1xylh7jAFeq2 tnAhUYZI9T.9Gs.4urKJs+A3x3rvIgsGNMOfCLKoF6PJXWxt18qfErc+MvUP d+g72Uc+hdHtsqWLcrL.TkWh5+OrPiAkEHy9LowVProwVvPdJVtTtAtWvFwU oTg4EX0DRpIBvkhBfL174cIGDdCW2V3BWzbISRZtqrZsP0tdmYp+.Tgz+39p iNGAhaSwQApaS..hCCAvUT1iiDnF83pL83bs3WMBgBsortNSONg.o2XI+MUj caZVIBNy9Ezc45s5i2Ipg.HVoGVMaaJ31VXFuPvDhmPqKqLu0u0kaqLuiuaK tu5oKJHhqxkBnQaKvD2llT90swmdAmI7SRvt84CCpie6xAgzbgizfs3hiTvU cJsMxdIMUZ1FpvKCcq6xreVaeW6oj1MVVmktoLqP4jDzWddCqdKbT9aXgKLV 2szNEN9jHbP2h6ExguDgKDh7AdmO3Z1yXh4.bl+D6NmvCStTw1OS3A5tkzkv AFTjWT3NfWMHlP4.akNrWZj8SXbTH+HZqiFRL6KG.KwVValcE2GbFgFzTpKt 6L+AD3dAD39CDrn.dLDsOViCD9ss1wjuDPPCiAfv9F4FRIyImdZydpw9dvAm Ml5DIc5DvK5Di4ra7kMjt1YWuLjXr93VgNMtp6GdCBGcJrlB4AAD1YaxYUQh XyiRRRL82XaZA3BaJb2FEDDfImsoFGuwwyi03RByqdeS5EGYvzoL2YPQznoS 35F4lnvIi5cnOSPf3wugENHP7tcTDOcBW2HW3zrJg9YPLgHWm7hgSiqDSgA6 AxQlFjK7sr0J8srvQ58JalHgqajiNMBWuV4NahxiTuBYh8rgLgGTgKZXbByn PxY31erbhRrok7fyHtWSYZHjffHeE5NtWjdD1jf23d45FOQlQ8w+ywifQR15 UJEwASRt45k2G7zrlHbuDtoI4C39EA3zHa8JRgoIPgdQnPu3v+RBgehD3wva oTBM5zyn1cNPb79y7CMDYXLgZDTalWS3zcm4mT60qXcml3v6EhxllUWw5EE8 zPzzOB5IrvZcOodwdL4DHuqte1LhHQO6YIz824HNjHWJutaDQir+XMdtyv1e rhSh1e1HxpgmFuB3d4VvCoH0zf9v+GPNtV0L -----------end_max5_patcher-----------