From: owner-sc-users-digest@lists.io.com (sc-users-digest) To: sc-users-digest@lists.io.com Subject: sc-users-digest V1 #23 Reply-To: sc-users Sender: owner-sc-users-digest@lists.io.com Errors-To: owner-sc-users-digest@lists.io.com Precedence: bulk sc-users-digest Thursday, January 7 1999 Volume 01 : Number 023 ---------------------------------------------------------------------- Date: Tue, 29 Dec 1998 09:26:17 -0600 From: James McCartney <---@---.---> Subject: Re: AW: Synth class question At 8:51 AM -0600 12/29/98, Junger Joerg wrote: >Hi James, > >thank you for the info so far. I must admit, that I still have some >questions.... Do I get it right, when I asume that in the program I write, >it makes no sense to call the new constructor for the Synth class several >times with different synthesizer functions, as I am only allowed to send the >play message to one of this synth objects Right. --- james mccartney james@audiosynth.com http://www.audiosynth.com If you have a PowerMac check out SuperCollider2, a real time synth program: ------------------------------ Date: Tue, 29 Dec 1998 22:57:54 -0600 From: James McCartney <---@---.---> Subject: FWD Re: SC2 with Newer G3 cards? >To: sc-users@lists.io.com >From: "B. Pennycook" <---@---.---> >Subject: Re: SC2 with Newer G3 cards? > >>Sorry, i forgot. I'm also interested in SC compatibility of other >>accelerator cards for PPC 8100, like Sonnet, for instance. >>Anyone? >>TIA >>Maurizio Giri >> >>_____________________________________________ >>o Maurizio Giri o >>o ConTempo o >>o Italian Contemporary (and Early) Music o >>o http://www.axnet.it/contempo o >>o-------------------------------------------o >>o ConTempo e-mail: contempo@wmail.axnet.it o >>o Personal e-mail: m.giri@agora.stm.it o >>o o >>o Snail: Via Ostilia, 55 - 00184 Roma Italy o >>o Tel +39.6.70451885 o >>_____________________________________________ > >I have a SONNET G3 300/150 in a ppc7500. works great and >lots of cycles. > >B. Pennycook > ------------------------------ Date: Wed, 30 Dec 1998 02:10:16 -0500 From: Kevin Parks <---@---.---> Subject: FAQ & list archives Where is the faq? Has it been abandoned? I don't see it on the www site. Where are the list archives? Are they gone too? When does the d in SC 2.0dx get removed? Anyone have a fix on when/if the pope book will be updated? Manual? Toots? SC 2.0 is getting more powerful and more exciting with each new build, but has been really hard to track all the changes. cheers, kevin kevin@raven.dartmouth.edu ------------------------------ Date: Thu, 31 Dec 1998 00:00:24 +0100 From: joel ryan <---@---.---> Subject: kj James, A few SC2 wishesmostly dealing with issues of control and performance >< Variable font size in the GUI [especially numericals] The SC GUI remains a bit illegible on stage due to the small size of the font.This got worse recently with the highres G3 LCD screens. I just did a gig with Evan Parker and felt like the hunchback of notre dame trying to see my screen. I would be endlessly thankful if it were possible to somehow increase at least numerical string display to a size useful in performance. Just a few choices would be enough. >< file name string access I would like to automatically link by name sample files with preset files (parameter settings). I could do this all by hand but the best would be if when I loaded samples via the say the getAudioFromUser dialog I could get the name string of selected file so I could generate a varient for a preset file of sample associated data. >< Mouse control support We are making a bowable controller at STEIM which uses the mouse port as an appropriate highres channel for real time music software. The idea however requires the ability to scroll outside the limits of the mac/mouse graph port. This is not unlike numericals in MAX and other GUIs which use continuous mouse scrolling to enter values. Would you be able to give us access in SC2 to the tool box call which resets the cursor value so as to get this endless scrolling mode? Thanks Joel Ryan _____________________________________________ Joel Ryan Institute of Sonology :: Ballett Frankfurt STEIM [Stichting for Electro-Instrumental Music] Achtergracht 19, 1017 Amsterdam +31 (020) 624-3886 +31 (020) 626-4262 fax http://www.xs4all.nl/~steim http://www.frankfurt-ballett.de/joel.html _______________________ ------------------------------ Date: Sun, 3 Jan 1999 11:23:50 -0600 From: James McCartney <---@---.---> Subject: Re: kj At 5:00 PM -0600 12/30/98, joel ryan wrote: >>< Mouse control support >We are making a bowable controller at STEIM which uses the mouse >port as an appropriate highres channel for real time music software. >The idea however requires the ability to scroll outside the limits of the >mac/mouse graph port. This is not unlike numericals in MAX and other GUIs which >use continuous mouse scrolling to enter values. Would you be able to give us >access in SC2 to the tool box call which resets the cursor value so as to get >this endless scrolling mode? SC code runs at the audio interrupt level not at the user interface level. So there is no feasible way to write a mouse tracking loop in SC code. I would suggest writing your own control app and using Open Sound Control to control SC. Open Sound Control will be supported in SC soon. --- james mccartney james@audiosynth.com http://www.audiosynth.com If you have a PowerMac check out SuperCollider2, a real time synth program: ------------------------------ Date: Sun, 3 Jan 1999 12:42:55 -0500 (EST) From: David Crandall <---@---.---> Subject: Re: kj On Sun, 3 Jan 1999, James McCartney wrote: > I would suggest writing your own control app and using Open Sound Control > to control SC. Open Sound Control will be supported in SC soon. Is there a good source for more inroductory information on Open Sound Control? thanks dc ------------------------------ Date: Sun, 3 Jan 1999 13:03:31 -0600 From: James McCartney <---@---.---> Subject: Re: kj At 11:42 AM -0600 1/3/99, David Crandall wrote: >On Sun, 3 Jan 1999, James McCartney wrote: > >> I would suggest writing your own control app and using Open Sound Control >> to control SC. Open Sound Control will be supported in SC soon. > >Is there a good source for more inroductory information on Open Sound >Control? http://cnmat.cnmat.berkeley.edu/OpenSoundControl/ --- james mccartney james@audiosynth.com http://www.audiosynth.com If you have a PowerMac check out SuperCollider2, a real time synth program: ------------------------------ Date: Sun, 3 Jan 1999 16:45:11 -0500 From: johndu@world.std.com (John Duesenberry) Subject: Filter control & modulation I'm looking for ways to control the Fc and/or Q of SuperCollider's various filters, using envelope functions somewhat less simplistic than Line or Xline. Ideally I would like to use the breakpoint envelope functions for this purpose, as in Env/EnvGen. Or... the Ugen ref sheet mentions " Osc1 .. single shot function generator," but as far as I can see this is not implemented. I tried to coerce EnvGen into doing what I wanted by using a "DC" constant as the "mul" input of EnvGen, then using the output of EnvGen as a filter control, but it basically did nothing. Any suggestions? Another thing I have been playing with that seems to work reasonably well is the use of audio-rate signals to modulate a filter's Fc or Q. This seems to work with at least some of the filters, such as LPF, producing interesting sidebands that sound somewhat like AM but also like phase modulation, plus artifacts that sound like aliasing.( Not surprisingly.) I'm curious to know if others have experimented with audio-rate filter modulation, and whether James McCartney has any comments on whether this "technique" is really supported? It seems to use surprisingly little CPU resources. ------------------------------ Date: Mon, 04 Jan 1999 09:28:59 +0100 From: "Iannis Zannos" <---@---.---> Subject: Re: kj Hi Joel, as a suggestion have a look at the GetFileDialog class. Appended below is some code which may be partly useful for your purposes - if only as example of how to use GetFileDialog and related stuff. Note: To use the code below it is necessary to patch the method scatList in class String as follows: scatList { arg list; var string; string = this.copy; list.do({ arg item, i; // string = string primCat: " " ++ item; // (patch the bug: primCat no longer exists) string = string.prCat( " " ++ item); }); ^string } Best regards, Iannis > >>< file name string access >I would like to automatically link by name sample files with preset files >(parameter settings). >I could do this all by hand but the best would be if when I loaded samples >via the say the getAudioFromUser dialog I could get the name string of >selected file >so I could generate a varient for a preset file of sample associated data. Iannis Zannos SIM Tiergartenstr. 1, D-10785 Berlin, Germany Fax: +49 30 25481172 ================================================================ Score { var <>name = 'score', <>orchestra, <>score; // var <>window; *new { arg orchestra, score, name = 'score'; ^super.new.orchestra_(orchestra).score_(score).name_(name); } *fromfile { arg thepath; ^this.new.readfile(thepath) } readfile { arg thepath; var file, line, end; if ( thepath.isNil, // If path is nil, then get path from user { ^GetFileDialog.new( { arg ok, path; if ( ok, { this.readfile(path) }, { this })})}); file = File.new(thepath, "r"); // OPEN FILE if ( file.isNil, // Check if file found { ^GetStringDialog.new("oops...","Score cannot open file " ++ thepath.asCompileString ++ ". Try again with another path ...") } ); line = file.getLine; // READ AND CHECK SCORE FILE HEADER if ( this.notequalstring(line, "ORCHESTRA".prCat(10.asAscii.asString.copyRange(1, 1))), { ^GetStringDialog.new("oops...","This is not a valid score file. " ++ "Score files should begin with the line "++ "ORCHESTRA".asCompileString)}); end = false.asRef; orchestra = this.readcompileblock(file, "SCORE", end); // READ ORCHESTRA if ( end.value, // Check if end of file { ^GetStringDialog.new("oops...","Score missing. " ++ "The score should begin with the line "++ "SCORE".asCompileString)}); score = this.readscore(file); // READ SCORE; } readorchestra { arg file; var line, scoreheader, filesize; orchestra = List.new(32); scoreheader = "SCORE".prCat(10.asAscii.asString.copyRange(1, 1)); line = file.getLine; filesize = file.length; 'READING ORCHESTRA...'.postln; while ( { (file.pos < filesize) }, { line = file.getLine; if ( this.equalstring(line, scoreheader), { ^true }); orchestra.add(thisProcess.interpreter.compile(line).value); }); ^false; } readcompileblock { arg file, nextmarker = "DATA", end; var line, marker, filesize, result; filesize = file.length; end = end ? nil.asRef; if ( file.pos >= filesize, { end.value_(true); ^GetStringDialog.new("End of file!","Cannot read this data block") }); result = List.new(32); marker = nextmarker.copy.prCat(10.asAscii.asString.copyRange(1, 1)); while ( { (file.pos < filesize) }, { line = file.getLine; if ( this.equalstring(line, marker), { end.value_(false); ^result }, { result.add(thisProcess.interpreter.compile(line).value) }); }); end.value_(true); ^result; } equalstring { arg string1, string2; if ( string1.size == string2.size, { ^string1.every({arg char, i; char.ascii == (string2@i).ascii }) }, { ^false }) } notequalstring { arg string1, string2; if ( string1.size == string2.size, { ^string1.every({arg char, i; char.ascii == (string2@i).ascii }).not }, { ^true }) } save { var f; PutFileDialog.new("Save score which file?", name.asString ++ ".os", { arg ok, thepath; if(ok, { f = File.new(thepath, "w"); if ( f.isNil, { ^GetStringDialog.new("SORRY!","Cannot overwrite file " ++ thepath.asCompileString ++ ". It is probably still open due to a previous write fail. " ++ "Try quitting SC to close this file") }); this.writecompileblock(orchestra, f, "ORCHESTRA"); this.writecompileblock(score, f, "SCORE"); this.writelines( ["END", "", "--------- comments: ---------", "Name: " ++ name.asString, "Saved in file:", thepath], f); f.close; }); }); } writecompileblock { arg data, file, header = "DATA"; var newline; newline = 10.asAscii; file.write(header); file.putChar(10.asAscii); data.do({ arg d; file.write(d.asCompileString); file.putChar(newline); }) } writelines { arg data, file; var newline; newline = 10.asAscii; data.do( { arg d; file.write(d); file.putChar(newline) }); } writeline { arg item, file; file.write(item); file.putChar(10.asAscii); } play { arg numChannels = 1, nextTime = 1.0, maxRepeats = 1; OrcScore.ar(orchestra, score, numChannels, nextTime, maxRepeats); } } /* (Score.new( [ { arg spawn, i, synth, deltaTime, instrumentNum, note, amp = 0.1; EnvGen.ar(e, FSinOsc.ar(note.midicps, amp)); }, { arg spawn, i, synth, deltaTime, instrumentNum, note, amp = 0.1; EnvGen.ar(e, LFPulse.ar(note.midicps, 0.1, amp)); }, { arg spawn, i, synth, deltaTime, instrumentNum, amp = 0.2; EnvGen.ar(e, BrownNoise.ar(amp)); } ], #[ // deltaTime, instrumentNum, ... [0.1, 1, 60, 0.5], [0.1, 1, 62], [0.1, 1, 64], [0.1, 1, 65], [0.0, 0, 67], [0.0, 0, 71], [0.0, 0, 74], [0.4, 0, 79], [0.0, 0, 69], [0.0, 0, 72], [0.0, 0, 76], [0.4, 0, 81], [0.2, 2, 0.5], [0.2, 2], [0.4, 2], [0.4, 2], [0.4, 2], [0.4, 2, 0.5], [0.4, 2], [0.2, 2], [0.2, 2], [0.8, 2] ]).save ) */ - ---------- >From: joel ryan <---@---.---> >To: sc-users@lists.io.com >Subject: kj >Date: Thu, 31 Dec 1998 12:00 AM > > > >_____________________________________________ >Joel Ryan >Institute of Sonology :: Ballett Frankfurt >STEIM [Stichting for Electro-Instrumental Music] >Achtergracht 19, 1017 Amsterdam >+31 (020) 624-3886 >+31 (020) 626-4262 fax >http://www.xs4all.nl/~steim >http://www.frankfurt-ballett.de/joel.html >_______________________ > > > ------------------------------ Date: Mon, 4 Jan 1999 08:27:42 -0600 From: James McCartney <---@---.---> Subject: Re: Filter control & modulation At 3:45 PM -0600 1/3/99, John Duesenberry wrote: >I'm looking for ways to control the Fc and/or Q of SuperCollider's various >filters, using envelope functions somewhat less simplistic than Line or >Xline. Ideally I would like to use the breakpoint envelope functions >for this purpose, as in Env/EnvGen. Or... the Ugen ref sheet mentions " >Osc1 .. single shot function generator," but as far as I can see this is >not implemented. I tried to coerce EnvGen into doing what I wanted by using >a >"DC" constant as the "mul" input of EnvGen, then using the output of >EnvGen as a filter control, but it basically did nothing. > >Any suggestions? There is a level offset input to EnvGen which can be used to DC bias an envelope. You could also use the 'add' input, though that is less efficient. The 'mul' input scales the envelope which also the level scale input does in a more efficient manner. Post your code. > >Another thing I have been playing with that seems to work reasonably well is >the use of audio-rate signals to modulate a filter's Fc or Q. This seems to >work with at least some of the filters, such as LPF, producing interesting >sidebands that sound somewhat like AM but also like phase modulation, plus >artifacts that sound like aliasing.( Not surprisingly.) I'm curious to know if >others have experimented with audio-rate filter modulation, and whether >James McCartney has any comments on whether this "technique" is really >supported? All filters only respond to filter parameter changes at control rate. --- james mccartney james@audiosynth.com http://www.audiosynth.com If you have a PowerMac check out SuperCollider2, a real time synth program: ------------------------------ Date: Mon, 4 Jan 1999 11:58:58 -0500 From: johndu@world.std.com (John Duesenberry) Subject: Re: Filter control & modulation (1) I guess my question wasn't clear - I don't want to DC-bias an envelope. What I want to do is use an envelope-like k-rate function to control the cutoff frequency of a filter. Line and Xline work fine for this, but they are too simple. The following actually works: ( { //envelope control of filter cutoff freq. //this works!! var foo,e, dc,bar; dc = 5000; e = Env.new([0.1,1,0.3,0.8,0.001],[2,3,1,4],'linear'); //cutoff freq. "breakpoints:" 500 Hz, 5 kHz, 1.5 kHz, 4 kHz, 5Hz //obtained by "envleoping the DC" bar = EnvGen.ar(e, dc, 0, 1, 0, 1); foo = LPF.ar(WhiteNoise.ar(1), bar,1,0); foo }.scope; But I was looking for a more direct way to do it, such as Osc1 (not available yet?). The above doesn't work with Env.linen, as far as I can see. (2) So what exactly happens if an a-rate signal is used as a cutoff freq. control? No error message is issued, and it sure *sounds* like the filter freq. is being modulated. (It sounds a lot like modulating the filter on my old Arp 2600 - actually a good feature!) Does the signal get sub-sampled down to the k-rate, or what? >All filters only respond to filter parameter changes at control rate. ------------------------------ Date: Mon, 4 Jan 1999 11:47:40 -0600 From: James McCartney <---@---.---> Subject: Re: Filter control & modulation At 10:58 AM -0600 1/4/99, John Duesenberry wrote: >Does the signal get sub-sampled down to the k-rate, or what? Yes. --- james mccartney james@audiosynth.com http://www.audiosynth.com If you have a PowerMac check out SuperCollider2, a real time synth program: ------------------------------ Date: Mon, 04 Jan 1999 16:13:29 -0700 From: "David Cottle" <---@---.---> Subject: Computer keyboard control Hi, I've looked through the external control help and can't find a feature I would like to use: being able to use the keyboard to control parameters similar to MouseX and MouseY. For example, assigning the values 0 through 9 to an incremental control rate. Is there a way to do this? ------------------------------ Date: Mon, 4 Jan 1999 23:33:20 -0600 From: James McCartney <---@---.---> Subject: Re: Computer keyboard control At 5:13 PM -0600 1/4/99, David Cottle wrote: >Hi, > >I've looked through the external control help and can't find a feature I >would like to use: being able to use the keyboard to control parameters >similar to MouseX and MouseY. For example, assigning the values 0 through 9 >to an incremental control rate. Is there a way to do this? The problem is when would this be active? Normally the keys are taken by the text editor or a focused view. Views have a keyDown method that is called when a key is pressed and that view is the focused view. Sliders have some built in key responses: '0' - '9' set the slider's value to 0.0 to 9.0 if that value is in range. arrow keys change value up or down by one percent of the total range. 'x' moves the slider to maximum. 'n' moves the slider to minimum. 'c' moves the slider to the center. 'r' sets the slider to a random value --- james mccartney james@audiosynth.com http://www.audiosynth.com If you have a PowerMac check out SuperCollider2, a real time synth program: ------------------------------ Date: Tue, 5 Jan 1999 07:22:31 -0600 From: finer@easynet.co.uk Subject: record playthrough Hello, just wondering why i hear the recorded sound being recorded (click record) : ( // record and play - basic var signal; signal = Signal.newClear(Synth.sampleRate * 2.0); SoundManager.with({ SoundPalette.fromspecs([ ['addContinuousSound', //record "record", { RecordBuf.ar(signal, AudioIn.ar(1), 1, MouseY.kr(0,1), 0, 1, 1); }], ['addContinuousSound', // play "play", {Pan2.ar( PlayBuf.ar(signal,Synth.sampleRate,MouseX.kr(-2,2),0,0,signal.size-2), 0)} ] ]);// end of sound palette Scope.window("Input", Synth.sampleRate * 0.1, Rect.new(498, 59, 794, 249),AudioIn.ar(1)) }) // end of sound manager ) Thanks, Jem ------------------------------ Date: Tue, 05 Jan 1999 16:38:37 +0100 From: "Iannis Zannos" <---@---.---> Subject: Re: record playthrough >just wondering why i hear the recorded sound being recorded (click record) : Have you had any experiences with recording in SC previously? I have not tried anything in this field yet so I cant tell you whether this is due to SC, to GUIUtils or to SC-Mac Sound-Manager. Apparently some Mac models resp. MacOS versions always route the audio in signal to the loudspeakers. This has been discussed in the SC list around last October. Perhaps you should post this to SC list. Cheers, Iannis Zannos SIM Tiergartenstr. 1, D-10785 Berlin, Germany Fax: +49 30 25481172 - ---------- >From: finer@easynet.co.uk >To: sc-users@lists.io.com >Subject: record playthrough >Date: Tue, 5 Jan 1999 2:22 PM > >Hello, > >just wondering why i hear the recorded sound being recorded (click record) : > > >( >// record and play - basic >var signal; >signal = Signal.newClear(Synth.sampleRate * 2.0); > >SoundManager.with({ > SoundPalette.fromspecs([ > > ['addContinuousSound', //record > "record", > { > RecordBuf.ar(signal, > AudioIn.ar(1), > 1, MouseY.kr(0,1), > 0, > 1, > 1); }], > > ['addContinuousSound', // play > "play", > {Pan2.ar( > >PlayBuf.ar(signal,Synth.sampleRate,MouseX.kr(-2,2),0,0,signal.size-2), > 0)} > ] > > ]);// end of sound palette > >Scope.window("Input", Synth.sampleRate * 0.1, Rect.new(498, 59, 794, >249),AudioIn.ar(1)) > }) // end of sound manager > >) > > > >Thanks, > >Jem > > > ------------------------------ Date: Tue, 5 Jan 1999 17:18:51 +0000 From: finer@easynet.co.uk Subject: Re: record playthrough >>just wondering why i hear the recorded sound being recorded (click record) : > >Have you had any experiences with recording in SC previously? >I have not tried anything in this field yet so I cant tell you >whether this is due to SC, to GUIUtils or to SC-Mac Sound-Manager. >Apparently some Mac models resp. MacOS versions always route the >audio in signal to the loudspeakers. This has been discussed >in the SC list around last October. Perhaps you should post >this to SC list. > An earlier patch (not using GUIUtils) that performed the same function - record and playback - does not do this playthrough thing so I'm pretty sure it's not the computer. Same thing happens on the G3. Jem Jem Finer finer@easynet.co.uk Longplayer : http://easyweb.easynet.co.uk/artangel/finer.html Autodestruct/Marseille en Juin : http://www.chez.com/immedias ------------------------------ Date: Wed, 6 Jan 1999 01:21:33 -0400 From: kbabb@escape.com (Kenneth N Babb) Subject: Csound Magazine Winter 1999 The following was posted on the Emusic list and may be of interest to some members of the SC list. >Greetings, > >The premier issue of Csound Magazine is now complete and available at >the following web site: > >http://www.werewolf.net/~hljmm/Ezine/ > >In this issue: > >"A Beginners Look at Csound" by Hans Mikelson > >"Implementing Cellular Automatas in Csound, with some musical >applications" >by Josep M Comajuncosas > >"Hyperbolic Tangent Distortion" by Hans Mikelson > >"DirectCsound Information" by Gabriel Maldonado > >"DirectCsound FAQ" by Gabriel Maldonado > >"A Practical Guide To Compiling Csound" by Hans Mikelson > >"Perception of Tone Sequences and Pitch Paradoxes: A Digital Synthesis >Laboratory" by Luca Pavan > >Enjoy, >Hans Mikelson ------------------------------ Date: Thu, 07 Jan 1999 15:43:02 +0100 From: "Iannis Zannos" <---@---.---> Subject: keyDown action response in ButtonViews? In order to enable various actions by keyboard commands, I changed the keyDown method in class View as follows: keyDown { arg asciiChar, keyCode, modifiers; [asciiChar, keyCode, modifiers].postln; // for debugging ... if ( model.isKindOf(SoundApp), { model.keyDown(asciiChar, keyCode, modifiers, this) }); // ... etc. } While items like CheckBoxView respond correctly to keyboard events, ButtonView instances do nothing. I tried defining this method in ButtonView, and it had no effect. Is it possible to make keyDown accessible to ButtonViews? It is really handy there! Best wishes to the SC clan, Iannis Zannos SIM Tiergartenstr. 1, D-10785 Berlin, Germany Fax: +49 30 25481172 ------------------------------ Date: Thu, 07 Jan 1999 16:13:58 +0100 From: "Iannis Zannos" <---@---.---> Subject: User Data file class for loading / saving orchestras et al. > THIS MESSAGE IS IN MIME FORMAT. Since your mail reader does not understand this format, some or all of this message may not be legible. - --MS_Mac_OE_2998570438_1159575_MIME_Part Content-type: text/plain; charset="US-ASCII" Content-transfer-encoding: 7bit Maybe the following class can be a solution for saving and loading largish orchestra files or other data - like several people have asked in this list. The code is appended here as asci together with extensive description and attached also as mac - bin encoded attachment. Best, Iannis Zannos SIM Tiergartenstr. 1, D-10785 Berlin, Germany Fax: +49 30 25481172 ===================================================================== /* UDFile (User Data File) What it does UDFile is a subclass of File that lets you read and write (multiple, nested) arrays containing elements of different data types. For writing it converts each line of data into a compile string, which can be compiled upon reading to reload the saved data in the system. There are limitations and workarounds, explained below. A header mechanism is foreseen to enable the saving and loading of multiple data chunks, like an orchestra and a score array, in the same file. This can be ignored when one is writing or reading only a single data chunk. Data format A. Single chunk of data The data for saving are given in an array, called "data chunk". Each element of the array is written as a compile-string on a new line. Thus the array #[[1, 2, 3], ["a", ["b", 0.1]], ['symbol', 1], 'MySymbolicLabel'] Would be saved as: [1, 2, 3] ["a", ["b", 0.1]] ['symbol', 1] 'MySymbolicLabel' B. Multiple chunks of data Optionally, the data for saving can be given in an array of 2 element arrays: [[name1, chunk1], [name2, chunk2] ...] I.e.: The first element of each array is the name of the chunk (symbol or string). The second element of each array is the data of the chunk, in the format described above under A. Single chunk of data. Usage Loading data UDFile.load( optional args: headers, file-path, verbose = true ) headers = array of strings or symbols that separate each successive chunk of data in a multi-chunk file (see B. Multiple chunks of data); If omitted, UDFile attempts to read the file as a single array of data. file-path: a valid path for the file to read. If nil, a file dialog is provided for choosing the file. verbose: (default: true). If true, messages are printed marking the loading of each chunk and the end of the loading. Saving data UDFile.save1(args: data, optional: path); Saves an array of data as a single chunk under the given path. If path is nil, provides a dialog for entering the file name. UDFile.save(args: data, optional: path); Saves an array of data chunks given in the format described above: B. Multiple chunks of data, under the given path. If path is nil, provides a dialog for entering the file name. What can be saved Numbers, Strings, Symbols, and nested arrays containing any combination of these can be saved. There are limits both to the length of a line that SC can read and to the size of an array that it can compile. Thus care should be taken to keep the size of each element (line) in the data array rather small (I have not figured out any limits. Instances of ParameterWindow, OrcScore and other useful classes will usually require lines of less than 100 elements each to save / recreate musical parameter configurations). Functions, classes, or instances of other classes than the ones named above cannot be saved. However, one may save instances of any class as specifications of how to recreate these instances from the class, by defining an appropriate "asCompileString" method. For example, SoundModel defines its compile string as: asCompileString { ^lib.name.asString ++ ".new.getsoundmodel('" ++ name.asString ++ "')"} Thus a SoundModel instance can be recreated, as long as a SoundLib class with the corresponding class name and the corresponding sound model name method exists in the system. Examples ( UDFile.save1([// deltaTime, instrumentNum, ... [0.1, 1, 60, 0.5], [0.1, 1, 62], [0.1, 1, 64], [0.1, 1, 65], [0.0, 0, 67], [0.0, 0, 71], [0.0, 0, 74], [0.4, 0, 79], [0.0, 0, 69], [0.0, 0, 72], [0.0, 0, 76], [0.4, 0, 81], [0.2, 2, 0.5], [0.2, 2], [0.4, 2], [0.4, 2], [0.4, 2], [0.4, 2, 0.5], [0.4, 2], [0.2, 2], [0.2, 2], [0.8, 2] ]) ) // ========================================================== ( a = UDFile.load; a.postln; a.first.postln; a.last.postln; ) // ========================================================== // Note 6.1.1999: SoundLib for saving the orchestra is not provided here yet.... ( UDFile.save( [ 'ORCHESTRA', { arg spawn, i, synth, deltaTime, instrumentNum, note, amp = 0.1; EnvGen.ar(e, FSinOsc.ar(note.midicps, amp)); }, { arg spawn, i, synth, deltaTime, instrumentNum, note, amp = 0.1; EnvGen.ar(e, LFPulse.ar(note.midicps, 0.1, amp)); }, { arg spawn, i, synth, deltaTime, instrumentNum, amp = 0.2; EnvGen.ar(e, BrownNoise.ar(amp)); } ], #['SCORE', [// deltaTime, instrumentNum, ... [0.1, 1, 60, 0.5], [0.1, 1, 62], [0.1, 1, 64], [0.1, 1, 65], [0.0, 0, 67], [0.0, 0, 71], [0.0, 0, 74], [0.4, 0, 79], [0.0, 0, 69], [0.0, 0, 72], [0.0, 0, 76], [0.4, 0, 81], [0.2, 2, 0.5], [0.2, 2], [0.4, 2], [0.4, 2], [0.4, 2], [0.4, 2, 0.5], [0.4, 2], [0.2, 2], [0.2, 2], [0.8, 2] ]]) ) */ UDFile : File { var <>data, <>headers, path; // 1. LOADING *load { arg headers, path, verbose = true; var file; if ( path.isNil, { path = GetFileDialog.new.path; }); // If path is nil, then get path from user file = this.new(path, "r"); if ( file.isNil, // Exit if bad path or user has canceled. { ^GetStringDialog.new("oops...","Cannot open file " ++ path.asCompileString ++ ". Try again with another path ...") } ); ^file.load(headers, path, verbose); // Read and return data } load { arg inheaders, inpath, verbose = true; path = inpath; size = this.length; data = List.new; if ( inheaders.isKindOf(String), { inheaders = [inheaders] }); inheaders = inheaders ? []; headers = inheaders; if ( headers.size < 1, { if ( verbose, { 'Reading file as single chunk of data'.postln; }); data = this.readall(verbose) }, { data = this.readchunks(headers, verbose) }); this.close; if ( verbose, { ("Finished loading file: " ++ path.asCompileString).postln; }); ^data; } readall { var line, chunk; if ( this.pos >= size, { ^nil }); // Return nil if already at end of file; chunk = List.new(32); while ( { this.pos < size }, { line = this.getLine; chunk.add(thisProcess.interpreter.compile(line).value); }); ^chunk; } readchunks { arg headers, verbose = true; var numchunks; if ( verbose, { ("Looking for first header:" ++ headers.first.asCompileString).postln; }); this.skiplinesto(headers.first.asString); numchunks = headers.size - 1; data = headers.collect({ arg h, i; ("Reading data: " ++ h.asCompileString).postln; if ( i < numchunks, { [h, this.readuptonextheader((headers@(i + 1)).asString, verbose)] }, { [h, this.readall] }); }); ^data; } skiplinesto { arg astring; var line; astring = astring.copy.prCat(10.asAscii.asString.copyRange(1, 1)); if ( this.pos >= size, { ^false }); // Return false if already at end of file; while ( { (this.pos < size) }, { line = this.getLine; // ['comparing', line, 'with', astring, 'makes', this.equalstring(line, astring)].postln; if ( this.equalstring(line, astring), { ^true } // return that next header has been reached. ); }); ^false; // return that next header has NOT been reached. } readuptonextheader { arg header; var line, chunk; chunk = List.new(32); if ( this.pos >= size, { ^nil }); // return nil if already at end of file; // append line-feed char to header header = header.copy.prCat(10.asAscii.asString.copyRange(1, 1)); while ( { (this.pos < size) }, { line = this.getLine; // ['comparing', line, 'with', header, 'makes', this.equalstring(line, header)].postln; if ( this.equalstring(line, header), { ^chunk }); chunk.add(thisProcess.interpreter.compile(line).value); }); ^chunk; } equalstring { arg string1, string2; if ( string1.size == string2.size, { ^string1.every({arg char, i; char.ascii == (string2@i).ascii }) }, { ^false }) } notequalstring { arg string1, string2; if ( string1.size == string2.size, { ^string1.every({arg char, i; char.ascii == (string2@i).ascii }).not }, { ^true }) } // 2. SAVING *save {arg data, inpath, verbose = true; this.save_(data, inpath, verbose, multichunk: true); } *save1 {arg data, inpath, verbose = true; this.save_(data, inpath, verbose, multichunk: false); } *save_ { arg data, inpath, verbose = true, multichunk; if ( inpath.isNil, { PutFileDialog.new( "Save data to which file?", "score.os", { arg ok, p; if (ok, { this.new(p, "w").save_(data, p, verbose, multichunk); })}) }, { this.new(inpath, "w").save_(data, inpath, verbose, multichunk); } ); } save_ { arg data, inpath, verbose = true, multichunk = true; if ( multichunk, { this.save(data, inpath, verbose) }, { this.save1(data, inpath, verbose) }); } save { arg indata, ininpath, verbose = true; if ( verbose, { indata.do({ arg d; ("Writing: " ++ (d@0).asCompileString).postln; this.writechunk(d@1, d@0) }); ("Saved data to file: "++ ininpath.asCompileString).postln; }, { indata.do({ arg d; d.writechunk(d@1, d@0) }); }); this.close; } save1 { arg indata, ininpath, verbose = true; if ( verbose, { ("Writing " ++ indata.size.asString ++ " lines of data").postln; this.writechunk(indata); ("Saved data to file: "++ ininpath.asCompileString).postln }, {this.writechunk(indata) }); this.close; } writechunk { arg chunk, header; var newline; newline = 10.asAscii; if ( header.notNil, { this.write(header.asString); this.putChar(10.asAscii); }); chunk.do({ arg d; this.write(d.asCompileString); this.putChar(newline); }) } // ======================================================== // Utils for customizing UDFile to provide extra information. // e.g. info at the beginning of the saved file. writelines { arg chunk, file; var newline; newline = 10.asAscii; chunk.do( { arg d; this.write(d); this.putChar(newline) }); } writeline { arg item, file; this.write(item); this.putChar(10.asAscii); } } /* // Getting path file from user will not work if from within another function // in this version. The save has to be performed from within the GetStringDialog action. Why? *save_ { arg data, path, verbose = true, multichunk; var file; if ( path.isNil, { path = PutFileDialog.new("Save data to which file?", "score.os").path }); // path.postln; file = this.new(path, "w"); if ( file.isNil, { ^GetStringDialog.new( "SORRY!","Cannot open file " ++ path.asCompileString ++ ". It may already be open due to previous write fail. " ++ "If so, quit SC to close this file") }); if ( multichunk, { file.save(data, path, verbose) }, { file.save1(data, path, verbose) }); } */ - --MS_Mac_OE_2998570438_1159575_MIME_Part Content-type: application/mac-binhex40; name="UDFile.sc" (This file must be converted with BinHex 4.0) :#99%4QPXC5jcB`"849K88d0UE3#3"#UQ!!!)j$F6,bS0$99%4QPXC5!S9A0PFL" %BA4K)%CTE'8T$C!$9fKKG#"TG#"NEf9c$3e94%CTE'8JDA-JB5"cG@*ME'&cFb" [CL"'D@aP)(4SBA3JE'9dFb"jEh8JFQ9KC#"KEQ3JGh*TG'8J$5KYG@adDA"XC5` JEQ9cG'9N+5"KFR*KHA-JBfpZG'&TEQPZCb"PE'9YC@jdFb"[CL"ND@CQCA*PER3 JC'&dB5"dHA"PFbiJ$8C[FL"hFQPdD@jR)'Pd)'0[ERCPFR4c)'9KBfJJE'PZC5" [CL"NBA4K)'PZG'mJB5"MEfe`D@aP)(0dFQPZCb`0GfKTBfJJBf&Z)'*P)'0[EA" TE'9N)(9`EfiJFQ9KC'PZCb"dEb"bC@a[B@3JG'KP)(0KGQ9N)!eNBA4K)'PZ)(4 SC5"cHA0dC@dZ)#"8D'9bC5"KFQ8JE'PYDA4KG'P[ER-JB@jN)(G[FQYKFQpeEQ4 c,!ePH("XB@PZC@3JBQ9XEhFZ)!d035"SC@&NCA)JE@9MD'&ZDA0Y)'Pc)'C[FQ9 cC@9Z)(4[)'9ZB@*XC5"dD'8JFf&fD@jR)'&ZC#"XEf&ND@jR)'pQ)'eeE(4TF'a P$@4KG'%JBfKeEQYc,#"XD@YP)'&Z)'pbBfKPFh4bB5"KEQ3JB5"cBfpbC5"KFR* KH5`JD@iJG'KP)(0KE@8JCQPXC5iJ$94SDA-JBf&Z)'*P)'PREQpbC@3JGfKPEL" [EQ8JDA-JGh*TG'PZCb"[FL"bC@&ND@jR)'pZE(NJB5"cD@jRE'8JC'&dB5"MD(9 ZDbiJ$C!$4'&dB5"QEh*YBA30$8%Z)&0TEQGXC5"MD(9ZDb"[CL"NBA4K$3e8D'8 JC'&dB5"QEh)JFf&fD@jR)'&bC5"RDACPEL"TEL"KEL"KFR*KH5`JBf&XE'9N)#* NBA4K)'0SG@jV)Li04@&MD#"PE'9YC@jd)'pQ)(4SC5"KFR*KH5"TFb"hFQPdG'9 Z)'&c)'%JBfpYF'PXC5ecG(*TEQFJEfiJB5"ZCAFJE'PZC5iJ$94SGA-JG'KP)'& bFQ&j)#0E@c%X)$)X)$0G,#"E)Q%L,#"E)Q)L,#!`,M&GA5`J@bGcH@eLEf`R,#! aA5`J*dej8hPYBQpXD@0-B@*PE#GG$9G[G@aN)'*P)(0KGQ9N)'&c1L!0@c%X)$) X)$0G$9XLB5)X)&XLBL)X)$!Z-9eG$9XRFhPYBQpX*b`J-9dJ$5G0H90jE@*[E'P M6'&LC@`R$3e#,L"0G@adDA"XC5"MD(9ZDh-JEfBJC'&dB3d06h"dD@pZB@aXH5` JG'KP)'4KG'%JCQpb)(0KGQPZCb"MB@iJBQ8JCfPfC@iJD@iJB@iJBA*bBANJEfB J-L"PE'9YC@jd)'&bFQ&jFcSJ$9YEEQ&YC6%X)'0SG@jV-9dX)&YZB@eP-L`JBfK eEQXbA5!ZN!0G$8NZC5ik)#!09'KP)'CTFR0d)'9XC@ePER3JEfBJC@&MD#"KFR* KH5"TFb"dD'8JEQ&YC5"[CL"dD'8JBfKeEQXJ+(0jE@*[E#"[FL"cG(*TEQFT,Je 8D'8JFf9MEfjN)'9XC@ePER3JEfBJC@&MD#"KFR*KH5"TFb"dD'8JC'&dB5"[CL" dD'8JBfKeEQXX)'PZ)(4SC5"QEh*YBA30C'9cBh*TBQ9N)'&LEhCP)(9ZC'9b)%% Z)&0TEQGXC5"MD(9ZDb"[CL"NBA4K,Jf3!e9cB@GP$3e-Ef&ND@jR)'4KG'%0$99 %4QPXC5jXEf&N+#"[F(4TEfjKE#"KFQGc1L"SC@&NCA*c,#"QD@aP,A"KG'JX)(C PFQ*[Ff8J25"dFR9P)#N0D'9KC'9bFb!p)'&bFQ&j)'pQ)(0dFQPZCh-JEh)JFhP YBQpXFb"dD'&d)(0PF'&bBA4P)'9KBfJJFh9MBf9cFfPfC5!0#@0SG@jV)'pQ)'4 KG'%JD@iJB5"YG@adD5eMD(9ZDb"QD@aP)#KcC@8J3LiJ6A9XG'P`E'8JBfKeEQY c)'pQ)'4KG'%T1`d*5@BJEfeTG(4PC#`J984'D@aP)'&dG'9YF(4c)(4[)(*PB@3 JG'KP)'CTE'8JBA-JB5"cD@jRE'8JBA*bBANJEfBJC'&dB5iJ$@CTE'8YF'&dD$S JB5"fB@aTC#"`BA4S)'C[FL"dD'8JCQPXC5"dEb"bC@&N,L"*CL"ZD@`X)'%JCQP XC5"ND@&XEfFJDA-JF(*[GQPNC@30#@C[FL"MD'p[FfPZCb"dD'8JCQPXC5iJ$AC PFQ*[Ff8k)#KNC@CKG@ad1L"dFR9P+5iJ5@BJG(*eC5`JE@9cFf&RCA-JBA*P)(" bD@jdC@3JE@&bDfPZCb"dD'8J$@a[B@4TEQFJEfBJC@&MD#"MD(9ZDb"KEQ3JG'K P)'9ZC#"[CL"dD'8JE'pKC'PZCbiJ$3e6BACTEQFJC'&dB3d0984'D@aP,R0KGQ8 a+'&bCh-k)'4KG'%X)'p`G'P[EQ&X1L"`BA4S+6XJ$3e6BACPFb"KEL"KFR*KH5" [CL"NBA4K)'&c)'%JFfPZCfaP)'0SG@jV)(9ZC'9b)(4SC5"RDACPEJe`BA4S,L" *CL"`BA4S)'Pc)'jTE#`JF(*[GQPNCA-JB5"ND@&XEfFJCQpb)'9ZG'9bD@jR)(4 SC5"QD@aP)'jKE@8Z)!d0984'D@aP,R0KGQ8SBA*RFcSJC'&dB5`JEh"dD@pZB@` k)("KG'JT1b!0$90KGQ9c)'&Z)'&bFQ&j)'pQ)'4KG'%JBfKeEQYc)'GTGQ9Z)'P Z)(4SC5"QEh*YBA3J$@4PFf0bD@*PC#"KBQpfC6SJ3LiJ6A9XG'P`E'8JBfKeEQY c)'pQ)'4KG'%X)(9ZC'9b)(4SC5"RDACPEJe`BA4S,L"*CL"`BA4S)'Pc)'jTE#` JF(*[GQPNCA-JB5"ND@&XEfFJCQpb)'9ZG'9bD@jR)(4SC5"QD@aP)'jKE@8Z)!f 3!eGSBA3JBf&Z)'*P)(0KGQ9N)!d06R9YBQ9bFb`J8h4bD@jRFb`J8hPYBQpXFb` JB@jN)'jPFh4PC#"KFR*KHA-JBfpZG'&TEQPZCb"KERNJBfpYBQPZBA4TEfiJEfB J$A4SCA0P)'0KEL"LC5"cBACPC#iJ9'KPFQ8JBA*P)'aTE@PdFb"LEh4S)(4[)(4 SC5"XC@jRG'JJEfBJB5"XD@jP)(4SBA3J8d-JBf&Z)(*PB@30B@jN)(4[)(4SC5" cDATP)'pQ)'&Z)'&bFQ&j)(4SBA3JDA3JBf&Z)'0[EA"TE'8Z)&4SGA-JBf&bC5" cD'peE'3JBQ8JG'&VC@iJG'mJ$@YPCA!JG'KP)(0THQ8JEfBJC@&MD#"PE'9YC@j d)#KXD@jP+5"TEL"dD'8JC'&dB5"KFR*KH5"bBA4SCA)JFfeKE'`J+%NJD'&fC5! 0EQpd)'CTCh9bC@3JEh9d)'&ZH5"XD@eTG(-Z)%PZFh4KEQ0PFb"[CL"3BA*KE@9 dCA*AD@jNEhFX)%pbBe0MEh*P)'&ZC#"[G'KPFL!0GA0PCR9X)'0XBA0cCA-JGfP XE#"eFh9KE'aj)(*PFA9TFQ8JE'PZCA-JEfBJE'9cFb"dD'&Z)$%`-#"PE'9YC@j dFb"PB@0S)!edEb"cBACP)#mJFQ9MFQ9KG'8JEA9cD@0KE#"`BA*KE@9dCA)JBfp ZCQPRGA*KG'P[ER-T,Jd04R9ZBh4TEfjc,#"ME'&cFf9c,#"[FL"TER0dB@jMCA- JEfBJEh4SCA)JBfaKFh0PFb"dD'&Z)(4SC5"[EQ9c)'jKE@9N)'&LEhCP)!eMB@j ZEh3JBQ8JFf&fC@3Z)%K[Gf9fCA)X)'pZC5"YBANJFf&fC5"TER0dB@jMCA-JEfB JB@jj)'0XBA0c)'&c)(0`C@0TCQPMBA4TEfjc$@pQ)'K[Gb"dEb"bC@0bC@&dC5" dD'9cC5"TER0dB@jMCA-JCR*[E5"dD'8JBfaKFh-X)'*j)'4PCQPZD@jR)'&Z)'& `F(*[F(*TBA4P$5*KFd0[EA"TE'96G(*TEQFL)'ePG'K[C#iJ4Qpb)'9iB@e`E'8 X)&0[G@jN6@pNC@`JC'9QD@jPFb"TG(-JBfpYF'PXC5"cG(*TEQFJBA-k)!d*BA0 $Efe`D@aP8h4bD@jR)(XJAQaTBLjZB@eP,Q&c8h4bD@jR)#XV)#)ZEQ9h,QGPG(0 [G@jNE@pNC@`S*b)J+bXJEQ&YC5jKFe0dFQPZCb!V+b!L*bNLI3e8D(9c)'%J8fp eEQ40Ef4PE#"TER0dB@jMC5"MB@iJBQ8JFQ9MFQ9KG'9N,#"KFb"XEfjR)'&c)'% J8fpeEQ4-D@)JBfaKFh-JGfPdD#!0G'KP)'0[FR*PFh"[EQ4TEQFJBfaKFh-JEQ& YC5"KEQ3JG'KP)'0[FR*PFh"[EQ4TEQFJFfpeEQ3JE@pNC@`JEQ&YC5"YCA4SEf3 J$@9iDA0dFb"TEL"dD'8JFhPcG'9Y,L!0N!0&H'&YF'aPFb!0$5J0984'D@aP,R0 KGQ8a+&X[,b"NC@adB94TE@8X)'PZFh4bG@ePER41G@dX)#k3!`d*N!0E-#ia,#! a,#!f-#`J-#ieA5`0#C!$@c!Z-5`J-5`J0M*G,!d*N!0E-#ia,#!a,#!f0&dX$3Q 3!eX`,M%X)$%X)$BeA5`0#C!$@c!Z-#`J-#`J0MGG,!d*N!0E-#i`,#!`,#!h-9d X$3Q3!eX`,M!X)$!X)$FdA5`0#C!$@c!Z0#`J-#`J0cPG,!d*N!0E-#i`,#!`,#! f19dX$3Q3!eX`,M!X)$!X)$FbA5`0#C!$@c!Z-#`J-#`J0cCG,!d*N!0E-#id,#! `,#!i-9dX$3Q3!eX`,M)X)$)X)$!Z09dX$3Q3!eX`,M)X)$*G,!d*N!0E-#id,#! bA5`0#C!$@c!Z0#`J-PdX$3Q3!eX`,M3X)$*G,!d*N!0E-#id,#!b,#!`,M9G,!d *N!0E-#id,#!bA5`0#C!$@c!Z-L`J-PdX$3Q3!eX`,M)X)$*G,!d*N!0E-#ii,#! bA3d*A5N0+3d[,b!pN$S0$5J0B5!p)&9%4QPXC5jXEf&N1`eK,R"[Fh4XEMXJ$@% ZCQPbFh3ZF'pcG'aZ1`eK,QaKFh3ZF'pcG'aZ1b!0+3d0,bmJ2C!k$3d[,b"1Eh4 P)$BZ-5ia1C!$1L"6Eh9ZC%aTBL"QEh)JFf&fD@jR)(4SC5"[FQ0SCA0dFQ%JDA- JEQpd)("bEhCTC'9N)'KPFQ8JH@9d,T!%$5J0984'D@aP,R0KGQ8S#3d*@b!R6e* $5%969&*"*b`J$3N*Hb"KFQFJFh"KGfiX)'NX)(0jER4S,#"NC@adB94TE@8X)'P ZFh4bG@ePER41G@dX)'j[G'8X)'&YF#!p)$!Z-6X0#C!$4@jf4f9Z,Q&b+'8X)%C 6D@j2Ff-ZBA)SEQpdC5jYD@4TBh"c,#"KEA!T+6X0#3Pp,!d*#AXJBA*R)(0`BAG Z,#"T,#"cH@jdD#`JC'9XG'&8D@eP,#"TER0dFR9YC@jd6R9Y,#"ZEh4P,#"KEA! J25!`,M%l$3Q3!d9ZGNGPELjKFLKP,#"-4P"eE(0P,Q&b+'j[G'8ZE@PND@0`Fb` J-#ia,#"KEA!T+6X0#3Pp,!d*#AXJBA*R)(0`BAGZ,#"T,#"cH@jdD#`JC'9XG'& 8D@eP,#"TER0dFR9YC@jd6R9Y,#"KEA!J25!`,M)l$3Q3!d9ZGNGPELjKFLKP,#" #FQphENj[DA0P,Q&b+'&YF#NT1`d*#Ad0#9dX$3d*)eXR8d028N8R,#!0#3PE,bm JC'9XG'&8D@eP,#"TER0dFR9YC@jd6R9Y,#!ZN!-0#C!$@c!Z-5`J-5`J0M!X)$! Z09dX$3Q3!eX`,M%X)$%X)$BbA5`0#C!$@c!Z-5`J-5`J0M4G,!d*N!0E-#ia,#! a,#!f09dX$3Q3!eX`,M!X)$!X)$BhA5`0#C!$@c!Z-#`J-#`J0c&G,!d*N!0E-#i `,#!`,#!h0&dX$3Q3!eX`,M3X)$!X)$FjA5`0#C!$@c!Z-#`J-#`J0MPG,!d*N!0 E-#i`,#!`,#!h-PdX$3Q3!eX`,M!X)$!X)$FfA5`0#C!$@c!Z0#`J-#`J1$&G,!d *N!0E-#ib,#!b,#!`,M9G,!d*N!0E-#ib,#!bA5`0#C!$@c!Z0#`J-PdX$3Q3!eX `,M3X)$*G,!d*N!0E-#id,#!bA5`0#C!$@c!Z0#`J-L`J-#ieA5`0#C!$@c!Z0#` J-PdX$3Q3!eX`,M)X)$*G,!d*N!0E-#ib,#!bA5`0#C!$@c!Z1#`J-Pd0#9eG+3d T$3dU,`d0984'D@aP)$SJ4QPXC5"l)!d*GQ&b)$`qC'&dB5`J2$jSC@&NCA*c,#! mFfPkC5`J2$j`BA4S1b!0N!-[,b!a,L"-6d&%58j()*"E$3N0#5TXEf&N)(XJBA* R)'KPB@4PFR-X)("KG'JX)(CPFQ*[Ff8J25"dFR9P1b!0#3PfBA)JCQPXC6XJ$3N *D@BJ+#"`BA4S,QPc6QPX,#!JHb"`BA4S)$dJ4f9d4QPXC84TB@a[CbjZCAFZF'& dD$XJI5Nl#3N[,b"*CL"`BA4S)'Pc)'jTE#`JG'KPEL"RCA3JF'&dD#"QFQpY)(9 cCA)0#3PQD@aP)$dJG'KTFbjZCAFSF'&dD#`J)R)L+6X0#3PTCL!S)'CTE'8ZDA0 1D@`X#C!*,bmJ4AKTG#"TCL"LB@3JF'&dD#"[FL"eFf9b)'KKFb"MB@jMC@aPC#i 0#3Pl)#"H4f9d8h4bD@jR4'PKE'pR,QjPGbJLEfp`Fbk3!b)X)N0KEQj[G#"[F'9 Z)'CTE'8J)L!V+b"`BA4S,Q&c3fpYF'PXC90dFQPZCb!V+`d*N!-L,L"8FRNJB@G KD@iJGfPdD#"KEQpdD'9b)("KG'JJ,T!$)LNJI5!T1`N*$3N*AQCTE'8ZE'pKC#K SC@&NCA*c,#"`BA4S,#"fCA*LEh0P+6XJ#C!&,bmJ8Q9KC#"KEQ3JFQ9dGA*Z)'4 KG'%0#3Pp$3PXEf&N)(XJBA*R)'PZD'9KC'9bFb`JD@j`BA4S,#"fCA*LEh0P)$d JG(*eC6X0#3P`BA4S)$dJD@j`BA4S1`d*#A0THQ8J25"dD'Pc,QaPEQGdD$X0#3P NBA4K)$dJ6'PcG#jZCAFl)!d*#@PQ)#JJD@jSC@&NCA*c,QPc5fPZC%pQ+&0dFQP ZCbNX)(XJD@jSC@&NCA*c)$dJ@fPZD'9KC'9bFedJI5Nl$3N*D@jSC@&NCA*c)$d JD@jSC@&NCA*c)$mJ@edl)!d*#@KPB@4PFR-J25"TEQKPB@4PFR-l)!d*#@PQ)#J *D'9KC'9bFbjcDATP)$`J-5`J$3Q3!hXJ#@PQ)#JJGQ9bBQpcC5`JHb!R8Q9KC'P ZCb"QD@aP)'&c)(0TEQGXC5"MD(9ZDb"[CL"NBA4K*bj`Eh0dE'il)(dT1`d*N!4 NBA4K)$dJG'KTFbjbC@&NB@aX+(CPFQ*[Ff8T)(dX)!d*N!0l)'4KG'%J25"dD'P c,R*PB@4MD(9ZDh-SD'9KC'9bFb`JGQ9bBQpcC5NJI5Nl$3N*G'KTFbjME'pcC6X 0#3PTCL!S)(CPFQ*[Ff8X)(XJ+#*'D@jTFfKPC#"XEf&ND@jR)'CTE'8k)#)J+bX JF'&dD#jKFd0[EA"TE'96G(*TEQFT,R"[Fh4XEMXJI5Nl$3N*AQ4KG'%l)!d*I3d *FQ9KC'&XE#"l$5!*#ACKFL"XD@jP,#"MD(9ZDcX0#3PTCL!S)(4SDA-ZF'pc)$i p)(0THQ8X)(XJAQjTE#"p+6X*#5m[)&*PG(9bEL"ZD@`JD@BJB@abC@&NH5"KG#" PEQ3JEfBJCQPXC6X0#3PMD(9ZDb!p)%aTFh3ZEQ9h+$-b+6X0)!N*GfKTE'8J+!d *N!0l)(4SDA-ZF'pc)$`JFfPkC5"p,!d*N!0l)!PXD@jP)$dJG'KTFbjRCA4-D@j P1`d*N!4MD(9ZDbjKC'3SG'KTFe"bEf0PFh-ZD@jdCA*`FQ9dCA)ZBfpYF'PXC5K XD@jP+5jfB@aeC5Nl$3Q3!hdT1`d*#9jMD(9ZDcXJ$3Pp$3PbC@&NBfKeEQYc)(X JBA*R)'KPB@4PFR-X)(CPFQ*[Ff8J25"dFR9P1b!0#3PfBA)JER9YBfKeEQYc1`d *#@PQ)#JJGQ9bBQpcC5`JHb!S)Na[EfYTEQFJCQpb)'CTFR0d)'KPB@4PFMSL)#X V)'KPB@4PFR-ZCQPbFh3ZBA0$Efe`D@aP8h4bD@jR+5j`Eh0dE'il)(dT1b!0#3P dD'Pc,R0VDA"XD@jPFh4[+'KPB@4PFR-ZCQPbFh3ZBA06G(*TEQFT1`d*#@jeE@0 SG@jVFb!p)'KPB@4PFR-ZFfPkC5!Y)$%l)!d*#@4KG'%J25"SC@&NCA*c,Q0[E'a PBh3SHb"KFQFJD#`JD6X0#C!$+#*5C@&ND@jR)'4KG'%k)#)J+bXJD#jKFd0[EA" TE'96G(*TEQFT,R"[Fh4XEMXJ$3Q3!fPQ)#JJD5!m)'jeE@0SG@jVFb`J$3Q3!hX J@fJX)(4SDA-ZFQ9KC(9`G'pZCAKdD'9KC'9b+#KSC@&NCA*c3#KT)#XJ-5NT,Q& c8h4bD@jR,#"fCA*LEh0P+9dJI5`0#C!$Hb"ED#`JG'KTFbjbC@&NB@aXA5"p+6X 0#3Pp+6X*$3N*AQ4KG'%l)!d*I3d*FfYTF'aTEQ9cG'mJHb"KFQFJBA0dFQPZCcX 0#3PfBA)JE'PZC6XJ$3N*BA0dFQPZCb!p)'&cG(*TEQFZBfp`H5j`FN0KG#Ja-#j KFd&cBfPT,Q&c8h4bD@jR,Q0[F(P5B@jRC5Ja,#!a+5Nl$3N*D@BJ+#"dD'Pc,R" [Fb!q25"cDATP,#"l)&jQB@acC5"p+6X*#5m[)&*PG(9bEL"QB@acC5"TCL"KE(* PB@4j)'&d)'9ZC#"[CL"QD@aP1`dJ#3PhD'PXC5!S)!d*#AXJ+(4SDA-ZF'pc)$` JFfPkC5NJI5`0#3Pl)!PXD@jP)$dJG'KTFbjRCA4-D@jP1`d[,`Q3!eXRBfpYF'& bD@jR*b`JE'PZC5`J*hGTG'JR,#"KFh4bD@jR,#!RE@&VCA-R,#!JG'KTFbjPFA9 KE(0dFQPZCbKXD@jP,#"KFh4bD@jR+9dZF'pcG'aZ1b!0#C!$D@BJ+#"dD'Pc,Q9 aG@&XFh4bD@jR+'aTEQ8X)'&cG(*TEQFT,#!0#C!$Hb"HG(*eC5"p#C!%,bmJ)(* PG(9bEL"dD'&d)'jPH(3JD'9KC'9b)'KKFb"LC@9Z)(*PB@0SC@3Z$3Q3!bNl)!d *#AdT1`d*#9jQB@acC6XJ#C!&,bmJ)(*PG(9bEL"dD'&d)'jPH(3JD'9KC'9b)'K KFb"16e3JBQ9PEL"bC@&MD'9N,Jd*I3dJ#A*PB@4eF(4[EQ9iG'KPB@4PFL"l)'& bCb"SC@&NCA)l$5!*#ACKFL"XD@jP,#"MD(9ZDcXJ$3N*BfKeEQXJ25"-DA0d,Qj PGbJc-LNl$3N*D@BJ+#"dD'Pc,R"[Fb!q25"cDATP,#"l)&jZD@`JI5Nl#5m[)(* PG(9bEL"ZD@`JD@BJB@abC@&NH5"KG#"PEQ3JEfBJCQPXC6XJ$3Q3"bm[)'&`F'9 ZC#"XD@jP,@CPC@3JBfKKFL"dEb"SC@&NCA)0#3PSC@&NCA)J25"SC@&NCA)ZBfp `H5j`FN0KG#Ja-#jKFd&cBfPT,Q&c8h4bD@jR,Q0[F(P5B@jRC5Ja,#!a+5Nl$5! *#AGSD@aP)#JJ$3N*Hb!SG'KTFbj`Eh-J2#"cDATP+5"p,!d*#AXJ#@aTEQ8J25" dD'Pc,QGPG%aTEQ8l$5m[#C!$@bGMEfe`BA*TEQFR,#"XD@jP,#!RGfPdD#FX)'K PB@4PFL`J*feKDf9c*b`J)(4SDA-ZCA&eB@acG(*TEQFSE'PZC5`JD'9KC'9b+9d ZF'pcG'aZ1b!0#C!$D@BJ+#"dD'Pc,Q9aG@&XFh4bD@jR+'aTEQ8X)'KPB@4PFLN X)(XJAQ0SG@jV)(dT1`d*N!0MD(9ZDbjKC'3SG'KTFe"bEf0PFh-ZD@jdCA*`FQ9 dCA)ZBfpYF'PXC5KXD@jP+5jfB@aeC5Nl$3N*I5Nl$3N*AQ0SG@jV1`dJ#Ad0#@9 aG@&XFh4bD@jR)(XJBA*R)(0dFQPZCc%X)(0dFQPZCc)l$3N*D@BJ+#"cG(*TEQF a,R0THQ8J26dJFh4bD@jR-LjcDATP,!d*#AXJAR0dFQPZCc%ZCACPFRNSHf&bCb" MD'&b,#"T1b"MD'&b,Q&cBfPT)$dp)#KcG(*TEQFb3'NT,Q&cBfPT)(dT)(dX$3N *Hb"HCQ&XFf8JI5N0#Ad0#@j[G'9aG@&XFh4bD@jR)(XJBA*R)(0dFQPZCc%X)(0 dFQPZCc)l$3N*D@BJ+#"cG(*TEQFa,R0THQ8J26dJFh4bD@jR-LjcDATP,!d*#AX JAR0dFQPZCc%ZCACPFRNSHf&bCb"MD'&b,#"T1b"MD'&b,Q&cBfPT)$dp)#KcG(* TEQFb3'NT,Q&cBfPT)(dT,Qj[G#"p,!d*#AXJAR4bG@8JI5N0#Ad0$5m[)$)Z)&0 "9NP14b#3@`d0#5TcBACP)(YKFQFJC'&dB5`JD@j`BA4S,#"fCA*LEh0P)$dJG(* eC6X0#3PdD'Pc,R0KGQ9I+'4KG'%X)'PZF'&dD#`JGQ9bBQpcC5`JEA9XG'PMD(9 ZDcSJG(*eC5Nl)!d*I3d*+R0KGQ8a)(YKFQFJC'&dB5`JD@j`BA4S,#"fCA*LEh0 P)$dJG(*eC6X0#3PdD'Pc,R0KGQ9I+'4KG'%X)'PZF'&dD#`JGQ9bBQpcC5`JEA9 XG'PMD(9ZDcSJCQ&XFf8T1b!0#Ad0#5TcBACPAb"l)'&bCb"NBA4K,#"TER"KG'J X)(CPFQ*[Ff8J25"dFR9P,#"YG@adD@0SG@jV1b!0#3PTCL!S)'PZF'&dD#jTFdj TE#`J$3Q3!hXJ8(9d4QPXC84TB@a[CbjZCAFS$3Q3"#*6BACP)'4KG'%JG'mJGfK TBfJJCQPXC6mL,#!0#C!%)R0MEh*P,Qpc)L`J$3Q3"(XJBA*R)'pV,#"`1b"TCL! SEfXX)(XJG'KTFbjZCAFSF#`J)RFL+5jcBACPAbKNBA4K,#"`,#"fCA*LEh0P,#" YG@adD@0SG@jV+6XJI5Pp+3d*N!0p,!d*N!0l)(4SDA-ZEQ9h+'PZF'&dD#`J)RF L+5jcBACPAbKNBA4K,#"TER"KG'JX)(CPFQ*[Ff8X)'eeE(4TBfKeEQXT1b!JI3d *#5Nl$3Pp#3d0#A0KGQ9I)(XJBA*R)'4KG'%X)'PZF'&dD#`JGQ9bBQpcC5!p)(4 bG@8X)'eeE(4TBfKeEQXJ25"dFR9P1`d*#@PQ)#JJEA9XG'PMD(9ZDb`J$3N*Hb" dD'Pc,R0KGQ8SC'&dB5`JD@j`BA4S,#"fCA*LEh0P+5"p,!d*#AXJG'KTFbjcBAC P-5KNBA4K,#"TER"KG'JX)(CPFQ*[Ff8T)(dT1`d*I3d*#3d0#A0KGQ8JHb"KFQF JD@jNBA4K,#"TEQPZF'&dD#`JGQ9bBQpcC5!p)(4bG@8l$3N*D@BJ+#"fCA*LEh0 P,#!0#3Pl)'PZC'&dB5jNEbKl)'&bCb"N1b!0#C!$+#*AFQPdD@jR1L!L)#XV)#K N3$!T,Q&c3fpYF'PXC90dFQPZCbNZF'pcG'aZ1b!0#C!%G'KTFbjhFQPdC@0SG@j V+'4!-5`JC%!`+5"p+6X0#3NJ#5JL8f&fC@3JC'&dB5"dEb"QD@aP1L!L+bXJD@j TER"KG'JZBA0$Efe`D@aP8h4bD@jR+5j`Eh0dE'il)(dX)!d*#AXJD@jNBA4K,Q4 [+(XJBA*R)'3l)'3ZGh*TG'9MD(9ZDbKN3$%X)'4!-#NJI5Nl)!d*#AdT1b!0#3P dD'Pc,Q0XEh0P1b!0#Ad0#A0KGQ8a)(XJBA*R)'PZC'&dB5`JD@jTER"KG'JX)(C PFQ*[Ff8J25"dFR9P1`d*#@PQ)#JJGQ9bBQpcC5`J$3N*Hb!*+#*AFQPdD@jR)#) J+bXJD@jNBA4K,R0THQ8ZBA06G(*TEQFJ+bXJ)L"XD@jPFb"[CL"NBA4K)LNZF'p cG'aZ1b!0#C!$G'KTFbjhFQPdC@0SG@jV+'PZC'&dB5Nl$3N*)!NS)P0KGQ9N)'4 KG'%JG'mJCQPXC6SJ)LXV)'PZD@j`BA4S,Q&c3fpYF'PXC90dFQPZCbNZF'pcG'a Z)(dX)!d*#AYdD'Pc,RGbDA4PBfKeEQXSD@jNBA4K+5"p+6XJ$3N*G'KTFbjME'p cC6XJ$3Pp$3PhFQPdC@0SG@jV)(XJBA*R)'0SG@jV,#"SC@&NCA)l$3N*GQ&b)'j PGfaTEQ8l)!d*#@jPGfaTEQ8J25!a-#jKFd&cBfPT1b!0#3PTCL!S)'KPB@4PFLj ZEh41D@`X$3N*Hb!*G'KTFbjhFQPdC5KSC@&NCA)ZBA06G(*TEQFT1`d*N!0dD'P c,R"eG%0SBA)S-6!ZBA0"Ff0TD5Nl)(dT1b!0#3PMD(9ZDbjNEbKl)'&bCb"N1b! 0#C!$G'KTFbjhFQPdC5KN,Q&c3fpYF'PXC90dFQPZCbNl$3Q3!h4SDA-ZF(9d3fK KFLKZCAGXD@jP+6X0#3Pp+3dJ#Ad0$5![,b!pN$J0$5!*,bmJ9A4TE(-JCQpb)'0 eFh4[E@PkD@jR)&9%4QPXC5"dEb"`FQpfD@4P)'9iG(*K)'PZCQpbE@&dD@pZ,Jd J#5m[)'8ZCbiJD@jQEb"KG#"dD'8JBQ9RD@jZD@jR)'pQ)(4SC5"cBACPC#"QD@a P,L!0#AGbDA4PE'PZCA-JHb"KFQFJBfKeEQXX)'CTE'8l$3N*GQ&b)'jPGfaTEQ8 l)!d*#@jPGfaTEQ8J25!a-#jKFd&cBfPT1b!0#3PMD(9ZDbjNEbJJHb"KFQFJC$X JG'KTFbjhFQPdC5KN+6XJG'KTFbj`GA4$D'&b+'jPGfaTEQ8T)(dT1`d*I3d*Gh* TG'9XD@jP)(XJBA*R)'PdC@dX)'CTE'8l)!d*#A4SDA-ZGh*TG'8SDA4PE5Nl)!d *#A4SDA-ZF(9d3fKKFLJa-#jKFd&cBfPT+6X0#Ad0$AdJ$C!$,bS0,bmJ4f9dG'P ZCb"`BA4S)'CTE'8JCR*[E5"eFf9b)(GTE'`JEQpd)(G[FQXJD@BJCR*[E5"hDA4 SD@iJB@j[G'KPFL"QG@jMG'P[EJd[,b"TEL"dD'Pc)(CPFR0TEfiZ)&4SC5"cBAC P)'KKFb"dEb"LC5"`CA*QEh*YC@3JCR*[E5"hDA4SD@iJG'KP)%GPG&0dFQPZCd4 TB@a[Cb"KBh4TEfiZ)&GSH6m0#5TcBACPAb"l)'&bCb"NBA4K,#"`BA4S,#"fCA* LEh0P)$dJG(*eC5`JEA9XG'PMD(9ZDcXJ$3N*GQ&b)'CTE'8l)!d*#@PQ)#JJF'& dD#jTFdjTE#`JHb"`BA4S)$dJ$3Q3!e"eG%CTE'9%D@&XEfFZEQ9h+#*6BACP)'4 KG'%JG'mJGfKTBfJJCQPXC6mL,#!LFf0[FQ8ZEh-L+5j`BA4S)(dT1`d*#5m[)(" KG'JZF'pcG'aZ1b!0#3PQD@aP)$dJG'KTFbjZCAFSF'&dD#`J)RFL+6X0#3PTCL! S)'CTE'8ZDA01D@`X)!d*#AXJ#9j(CA46G(*TEQG%D@&XEfFZEQ9h+!d*N!3L8dp 58PNK)L`L3f&ZEQpd)'p`C@iJCQPXC5!L)#XV)("KG'JZBA0$Efe`D@aP8h4bD@j R)#XV$3Q3"#)Z)%Pd)'eKH5"KE(*PB@4j)'*P)'p`C@iJC(9P)(4[)("bCACTEh9 c)(GbDA4P)'CKD@`Z)#)J+bX0#C!%)NPQ)(0[,#"aG@Pd)&0$)(4[)'0XEh0P)(4 SDA-JCQPXC5)T)(dT1`d*#@PQ)#JJEA9XG'PMD(9ZDb`J$3N*Hb"QD@aP,R0KGQ8 SC'&dB5`JF'&dD#`JGQ9bBQpcC5NJI5`0#3Pl)'CTE'8ZFf&fC6%SC'&dB5`JF'& dD#`JGQ9bBQpcC5NJI5Nl$3Pp#3dU,b!0)cX!!!%!N!-)RJ!!"ji!N!0'B@*L3'9 cBf&`C5jMEfdJ+%YPEQjPG'JJ6L"#B@*L+3!,,6%b16Bc16F`-MKdC@ec99*548j 8)#KN-MNTDA4eFJ"X9%9B9&0$DQd!N"LbZSdF!!!UTJ!!#14bCbjNC5!S3@aLFQ9 MD(3J8f0SEQ9TC'9b+3!L5@&ZEQPc)&TKEQj[Fb)J2'PKEQP!FfPY,R0`DbeLCA* XD@iZC'8q!&*P1L!R3@JR)&C[Gf9X)%CTE(4PFL"*ER0dFL!Y)&*PGQPcC@3J,5" AEh*V)%PZ)&"bEfGbCA0c)#dJN!0K!!!(PJ"K!*!&$J!+!"8!N!--!*!*!`!5!!i !&3%!!")!N!NE!!i!#J!9!*!$$!#3#4i!$`!,!"8"!!!1!*!*+J!1!!S!&3#3!`` !N!J#@!!2!!X!&3%!!!i!N!J#B`!1!!S!&3#3!``!N!J#C3!1!!S!&3%!!!`!N!J #I!!1!!S!&3#3!``!N!J$E!!,!!N$k!#3!`N!N!J$U3!1!!S!&3#3!``!N!J$UJ! 1!!S!&3%!!!`!N!J$a!!1!!S!&3#3!``!N!J%&3!,!!N$k!#3!`N!N!J%1`!1!!S !&3#3!``!N!J&#`!2!!X!&3%!!!i!N!J&%!!1!!S!&3#3!``!N!J&%J!1!!S!&3% !!!`!N!J&(J!1!!S!&3#3!``!N!J('3!1!!S!&3%!!!`!N!J(*!!1!!S!&3#3!`` !N!J(*J!,!!N$k!#3!`N!N!J(6`!1!!S!&3#3!``!N!J(d3!,!!N$k!#3!`N!N!J (q3!1!!S!&3#3!``!N!J)X`!2!!X!&3%!!!i!N!J)a!!1!!S!&3#3!``!N!J-$`! 1!!S!&3%!!!`!N!J-(J!1!!S!&3#3!``!N!J0(!!2!!X!&3%!!!i!N!J0*!!1!!S !&3#3!``!N!J0+!!,!!N$k!#3!`N!N!J21!!1!!S!&3#3!``!N!J21J!,!!N$k!# 3!`N!N!J2H3!1!!S!&3#3!``!N!J2kJ!,!!N$k!#3!`N!N!J46!!1!!S!&3#3!`` !N!J4A!!,!!N$k!#3!`N!N!J5iJ!1!!S!&3#3!``!N!J5jJ!1!!S!&3%!!!`!N!J 5p!!1!!S!&3#3!``!N!J5q3!1!!S!&3%!!!`!N!J5r!!1!!S!&3#3!``!N!J6)J! 1!!S!&38!!!`!N!J6LJ!1!!S!&3#3!``!N!J6M`!1!!S!&3%!!!`!N!J6N`!1!!S !&3#3!``!N!J8"!!1!!S!&3%!!!`!N!J8+`!1!!S!&3#3!``!N!J8A!!1!!S!&3% !!!`!N!J8A3!1!!S!&3#3!``!N!J8D!!1!!S!&3%!!!`!N!J8MJ!1!!S!&3#3!`` !N!J92`!1!!S!&3%!!!`!N!J98`!1!!S!&3#3!``!N!J9@3!1!!S!&3%!!!`!N!J 9A3!1!!S!&3#3!``!N!JABJ!1!!S!&3%!!!`!N!JAD3!1!!S!&3#3!``!N!JAU!! 1!!S!&3%!!!`!N!JAc3!1!!S!&3#3!``!N!JBGJ!1!!S!&3%!!!`!N!JBJ!!1!!S !&3#3!``!N!JD5!!1!!S!&3%!!!`!N!JD8`!1!!S!&3#3!``!N!JFA`!1!!S!&3% !!!`!N!JFF3!1!!S!&3#3!``!N!JFe!!1!!S!&3%!!!`!N!JFqJ!1!!S!&3#3!`` !N!JHL!!1!!S!&3%!!!`!N!JHN`!1!!S!&3#3!``!N!JI+J!1!!S!&3%!!!`!N!J I1!!1!!S!&3#3!``!N!JIdJ!1!!S!&38!!!`!N!JJ13!1!!S!&3#3!``!N!JJ23! 1!!S!&3%!!!`!N!JJ33!1!!S!&3#3!``!N!JJSJ!1!!S!&3%!!!`!N!JJT`!1!!S !&3#3!``!N!JK#!!1!!S!&3%!!!`!N!JK$J!1!!S!&3#3!``!N!JL6`!1!!S!&3% !!!`!N!JL9!!1!!S!&3#3!``!N!JLqJ!1!!S!&3%!!!`!N!JLrJ!1!!S!&3#3!`` !N!JN0J!1!!S!&3%!!!`!N!JN1`!1!!S!&3#3!``!N!JP6J!1!!S!&3%!!!`!N!J P@!!1!!S!&3#3!``!N!JQ63!1!!S!&3%!!!`!N!JQL!!1!!S!&3#3!``!N!JQr`! 1!!S!&3%!!!`!N!JR#3!1!!S!&3#3!``!N!JRL!!1!!S!&3%!!!`!N!JRN3!1!!S !&3#3!``!N!JSMJ!1!!S!&3%!!!`!N!JSP!!1!!S!&3#3!``!N!`"!*!$#*i!!!H H!*!$4JCdZPJT)J#3!a`!4J!"Fh4jE!#3!a*66e93!*!$(J#!rrm!N!Q!rrm!!!H D!*!%-+88: - --MS_Mac_OE_2998570438_1159575_MIME_Part-- ------------------------------ End of sc-users-digest V1 #23 *****************************