DIRECTORY Ascii USING [BS, CR, FF, SP, TAB], BasicTime USING [Now], FS USING[ Delete, Error, nullOpenFile, Open, OpenFile, StreamOpen ], IO USING [Close, CreateStreamProcs, CreateStream, PutChar, PutF, PutRope, STREAM, Value], Loader USING [BCDBuildTime], LupineMakeRpcModules USING [ MakeRpcControlModule, MakeRpcClientModule, MakeRpcClientBinderModule, MakeRpcServerModule ], LupineManager USING [], LupineManagerPrivate USING [ Abort, Error, ErrorCode, ErrorHandlerProc, ErrorType, ExplanationProc, IsNull, Language, ModuleTypes, Nest, Options, ParamPassingMethod, SHORT, String, StringNIL], LupineMarshal USING [ParameterProtocolVersions], LupineSymbolTable USING [ CloseInterface, GetInterfaceInfo, GMT, InterfaceInfo, OpenError, OpenInterface, VersionStampString, VersionStamp ], Rope USING [Cat, Find, Length, ROPE]; LupineManagerImpl: MONITOR IMPORTS BasicTime, FS, IO, Loader, LupineMakeRpcModules, LupineManagerPrivate, Marshal: LupineMarshal, ST: LupineSymbolTable, Rope EXPORTS LupineManager, LupineManagerPrivate = BEGIN OPEN LupineManagerPrivate; TranslateRemoteInterface: PUBLIC ENTRY PROCEDURE [ interfaceBcdFilename: String, interfaceBcdCapability: FS.OpenFile _ FS.nullOpenFile, errorHandler: ErrorHandlerProc, options: Options, desiredLineLength: LONG INTEGER ] = BEGIN ENABLE BEGIN UNWIND => NULL; AbortTranslation => GOTO AbortTranslation; ST.OpenError => -- This can come from ST.Open or MakeRpcXXX. Abort[ code: (SELECT why FROM badFileFormat => BadBcdFileFormat, badFileName => NoSuchFile, badFileVersion => BadBcdFileVersion, notInterfaceModule => NotInterfaceModule, ENDCASE => ERROR), problemText: fileOrModuleName]; END; -- ENABLE. EstablishErrorHandler[errorHandler]; SetCodeLineLength[desiredLineLength]; GetInterface[interfaceBcdFilename, interfaceBcdCapability]; BEGIN ENABLE UNWIND => { ST.CloseInterface; ClearErrorHandler }; interfaceName: String; contents: ST.InterfaceInfo; [contents: contents, moduleName: interfaceName] _ ST.GetInterfaceInfo[]; MakeModuleNames[interfaceName, options.targetLanguage]; BEGIN ENABLE UNWIND => FreeModuleNames[]; IF contents.variables THEN Error[InterfaceVariables, interfaceBcdFilename]; IF contents.transfers[Port] OR contents.transfers[Process] OR contents.transfers[Program] OR contents.transfers[Other] THEN Error[UnsupportedTransfers, interfaceBcdFilename]; BEGIN OPEN LupineMakeRpcModules; MakeRpcControlModule[options ! AbortTranslation => CONTINUE]; MakeRpcClientModule[options ! AbortTranslation => CONTINUE]; MakeRpcClientBinderModule[options ! AbortTranslation => CONTINUE]; MakeRpcServerModule[options ! AbortTranslation => CONTINUE]; END; END; -- ENABLE UNWIND => FreeModuleNames. FreeModuleNames[]; END; -- ENABLE UNWIND => ST.CloseInterface. ST.CloseInterface; ClearErrorHandler; EXITS AbortTranslation => NULL; -- The GOTO's UNWIND will cleanup. END; -- TranslateRemoteInterface. GetInterface: PROCEDURE [ interfaceFilename: String, interfaceCapability: FS.OpenFile ] = BEGIN IF interfaceCapability = FS.nullOpenFile THEN interfaceCapability _ FS.Open[AppendBcd[interfaceFilename] ! FS.Error => GOTO noFile ]; ST.OpenInterface[interfaceFilename, interfaceCapability]; EXITS noFile => Abort[code: NoSuchFile, problemText: interfaceFilename]; END; AppendBcd: PROCEDURE [s: String] RETURNS[new: String] = INLINE BEGIN IF Rope.Find[s, "."] >= 0 THEN new _ s ELSE new _ s.Cat[".bcd"] END; clientErrorHandler: ErrorHandlerProc _ NIL; EstablishErrorHandler: PROCEDURE [handler: ErrorHandlerProc] = INLINE {clientErrorHandler _ handler}; ClearErrorHandler: PROCEDURE = INLINE {clientErrorHandler _ NIL}; AbortTranslation: PRIVATE ERROR = CODE; ReportError: PUBLIC PROCEDURE [ type: ErrorType, code: ErrorCode, problemText: String ] = BEGIN Report: ExplanationProc = BEGIN clientSaysAbort: BOOLEAN = clientErrorHandler[ type: type, code: code, codeExplanation: explanation, outputFileName: GetCodeFileName[], outputFileCharPosition: GetCodeStreamIndex[], problemCausingText: problemText ].abortTranslation; IF type=abort OR clientSaysAbort THEN ERROR AbortTranslation; END; -- Explainer. GiveExplanation[code: code, explainer: Report]; END; GiveExplanation: PUBLIC PROCEDURE [ code: ErrorCode, explainer: ExplanationProc ] = BEGIN Explanation: PACKED ARRAY ErrorCode OF --explanation:-- String = [ AnonymousIdentifier: "Unnamed item (probably record component) encountered; cannot marshal this anonymous item.", BadBcdFileFormat: "Module or file has invalid BCD or symbols format.", BadBcdFileVersion: "So-called BCD file has an incorrect version stamp.", ComputedVariant: "Address-containing computed or overlaid variant record encountered; cannot marshal these records.", ComputedSequence: "Computed sequence encountered; cannot marshal these sequences.", EmbeddedRESULT: "VAR or RESULT parameter has embedded addresses; cannot marshal these parameters.", EmptyArray: "Empty (hint for dynamic?) array encountered; use explicit descriptors and sequences instead.", HandleREF: "REF-containing type being passed as a handle; this is extremely dangerous for the collector.", ImproperPassingMethod: "Parameter uses call by VAR, VALUE, RESULT, or HANDLE improperly.", ImproperReadonlyRESULT: "Readonly parameter cannot be called by VAR or RESULT.", ImproperRESULTResult: "Result parameter called by VAR or RESULT; only arguments can be called by VAR and RESULT.", InterfaceVariables: "Interface contains variables; interface variables are not supported.", InvalidHandle: "Ref or pointer to unspecified, completely opaque, or ANY encountered; it must be passed as a HANDLE.", MdsAllocation: "Argument or result requires allocating short POINTER storage (in the MDS).", NoSuchFile: "Could not find required file or module.", NotInterfaceModule: "Specified file is not a DEFINITIONS module; PROGRAM module translation is not supported.", ProbablePointerRecursion: "Probable list, tree, or graph detected; can only marshal explicit LIST OF types.", TransferParameter: "Cannot YET marshal transfer (e.g., procedure) parameter.", SequenceInsideVariant: "An arm of a variant record contains a sequence; this marshaling is not implemented.", ShortInterMdsPointers: "Parameter of interMDS call contains short pointers; use long pointers instead.", UnimplementedMarshaling: "Marshaling this type is either impossible or unimplemented.", Unknown: "", UnsupportedTransfers: "Interface contains PROCESSES, PROGRAMS, or PORTS; only procedures, signals, and errors are supported." ]; explainer[Explanation[code]]; END; moduleNames: ARRAY ModuleTypes OF String _ ALL[StringNIL]; ModuleName: PUBLIC PROC [module: ModuleTypes] RETURNS [--name:-- String] = BEGIN RETURN[moduleNames[module]] END; MakeModuleNames: PROCEDURE [interfaceName: String, language: Language] = BEGIN RpcInterfaceName: PACKED ARRAY Language OF String = [ Cedar: "RPC", Mesa: "MesaRPC" ]; RpcLupineInterfaceName: PACKED ARRAY Language OF String = [ Cedar: "RPCLupine", Mesa: "MesaRPCLupine" ]; MakeName: PROC [root: String, suffix: String_StringNIL] RETURNS[rootSuffix: String] = BEGIN RETURN[root.Cat[suffix]] END; -- MakeName. moduleNames[interface] _ MakeName[interfaceName]; moduleNames[openedInterface] _ MakeName[StringNIL]; moduleNames[control] _ MakeName[interfaceName, "RpcControl"]; moduleNames[client] _ MakeName[interfaceName, "RpcClientImpl"]; moduleNames[clientBinder] _ MakeName[interfaceName, "RpcBinderImpl"]; moduleNames[server] _ MakeName[interfaceName, "RpcServerImpl"]; moduleNames[rpcPublic] _ MakeName[RpcInterfaceName[language]]; moduleNames[rpcPrivate] _ MakeName[RpcLupineInterfaceName[language]]; moduleNames[lupineRuntime] _ MakeName["LupineRuntime"]; END; FreeModuleNames: PROCEDURE [] = BEGIN FOR module: ModuleTypes IN ModuleTypes DO moduleNames[module] _ NIL; ENDLOOP; END; codeFilename: String _ NIL; codeStream: IO.STREAM _ NIL; codeStreamIndex: LONG INTEGER _ 0; OpenCodeFile: PUBLIC PROCEDURE [codeModuleName: String] = BEGIN codeStream _ FS.StreamOpen[ fileName: ModuleDotMesa[codeModuleName], accessOptions: $create ]; codeStreamIndex _ 0; InitializeCodeLinePut; END; CodeStreamPut: PROCEDURE [char: CHARACTER] = INLINE BEGIN codeStream.PutChar[char]; codeStreamIndex _ codeStreamIndex + 1; END; CodeStreamPutRope: PROCEDURE [rope: String] = INLINE BEGIN codeStream.PutRope[rope]; codeStreamIndex _ codeStreamIndex + rope.Length[]; END; GetCodeFileName: PROC RETURNS [String] = INLINE {RETURN[ IF IsNull[codeFilename] THEN StringNIL ELSE codeFilename ]}; GetCodeStreamIndex: PROC RETURNS [LONG INTEGER] = INLINE {RETURN[codeStreamIndex]}; StampCodeFile: PUBLIC PROCEDURE [codeModuleName:String] = BEGIN moduleName, fileName: String; now: ST.GMT _ BasicTime.Now[]; lupineTime: ST.GMT _ Loader.BCDBuildTime[]; moduleVersion: ST.VersionStamp; moduleTime, sourceTime: ST.GMT; [moduleName: moduleName, fileName: fileName, moduleVersion: moduleVersion, moduleCreateTime: moduleTime, sourceCreateTime: sourceTime] _ ST.GetInterfaceInfo[]; codeStream.PutF["-- Stub file %g was translated on %g by Lupine of %g", [rope[codeFilename]], [time[now]], [time[lupineTime]] ]; codeStream.PutF["\n-- Source interface %g came from file %g, which was created on %g with version stamp %g from source of %g.\n", [rope[moduleName]], [rope[fileName]], [time[moduleTime]], [rope[ST.VersionStampString[stamp: moduleVersion]]], [time[sourceTime]] ]; END; StampTranslationOptions: PUBLIC PROCEDURE [options: Options] = BEGIN LanguageString: ARRAY Language OF String = [Cedar: "Cedar", Mesa: "Mesa"]; ParamPassingString: ARRAY ParamPassingMethod OF String = [ Var: "VAR", Value: "VALUE", Result: "RESULT", Handle: "HANDLE", InterMds: "InterMds" ]; BoolString: ARRAY BOOLEAN OF String = [TRUE: "TRUE", FALSE: "FALSE"]; oldest, newest: LONG INTEGER; [oldestSupported: oldest, newestSupported: newest] _ Marshal.ParameterProtocolVersions[]; codeStream.PutF[" -- The parameters for this translation are: -- Target language = %g -- Default parameter passing = %g -- Deallocate server heap arguments = %g -- Inline RpcServerImpl dispatcher stubs = %g -- Declare signals = %g", [rope[LanguageString[options.targetLanguage]]], [rope[ParamPassingString[options.defaultParamPassing]]], [rope[BoolString[options.freeServerArguments]]], [rope[BoolString[options.inlineServerDispatcherStubs]]], [rope[BoolString[options.declareSignals]]] ]; codeStream.PutF[" -- Warn about short POINTER (\"MDS\") allocations = %g -- Maximum number of dynamic heap NEWs = %g, MDS NEWs = %g -- Acceptable parameter protocols = VersionRange[%g..%g].\n", [rope[BoolString[options.warnMDSAllocs]]], [integer[options.maxHeapAllocations]], [integer[options.maxMdsAllocations]], [integer[oldest]], [integer[newest]] ]; END; -- StampTranslationOptions. CloseCodeFile: PUBLIC PROCEDURE = BEGIN FinalizeCodeLinePut[]; codeStream.Close[]; codeStreamIndex _ 0; codeFilename _ NIL; END; DeleteExistingCodeFiles: PROCEDURE = BEGIN DeleteOne: PROC [module: String] = BEGIN FS.Delete [ name: ModuleDotMesa[module] ! FS.Error => CONTINUE ]; END; DeleteOne[ModuleName[control]]; DeleteOne[ModuleName[client]]; DeleteOne[ModuleName[server]]; END; ModuleDotMesa: PROCEDURE [moduleName: String] RETURNS [String] = INLINE BEGIN RETURN[moduleName.Cat[".mesa"]] END; SpacesPerNest: INTEGER = 2; SpacesPerTab: INTEGER = 4; ExtraSpacesOnWrap: INTEGER = 2*SpacesPerNest; ApproxMaxIdentifierLength: INTEGER = 12; stillLeadingSpaces, doingComment: BOOLEAN; lineLength, spaces, lastHyphen, lineWrapThreshhold: INTEGER; formattedStream: PUBLIC IO.STREAM _ IO.CreateStream[ streamProcs: IO.CreateStreamProcs[variety: output, class: $Lupine, putChar: CodeLinePut], streamData: NIL]; SetCodeLineLength: PROCEDURE [desiredLineLength: LONG INTEGER] = INLINE BEGIN lineWrapThreshhold _ MAX[ 28, SHORT[desiredLineLength]-ApproxMaxIdentifierLength-ExtraSpacesOnWrap ]; END; InitializeCodeLinePut, StartNewCodeLine: PROCEDURE = INLINE BEGIN stillLeadingSpaces _ TRUE; lineLength _ spaces _ 0; lastHyphen _ -1; doingComment _ FALSE; END; FinalizeCodeLinePut: PROCEDURE = INLINE {}; CodeLinePut: SAFE PROCEDURE[self: IO.STREAM, char: CHAR] = TRUSTED BEGIN WrapLine: PROC = BEGIN IF stillLeadingSpaces THEN lineLength _ spaces _ lineWrapThreshhold ELSE BEGIN lineLength _ spaces; IF spaces >= lineWrapThreshhold THEN stillLeadingSpaces _ TRUE; CodeStreamPut[Ascii.CR]; CodeStreamPutRope[IndentInline[(spaces+ExtraSpacesOnWrap)/SpacesPerNest]]; IF doingComment THEN { CodeStreamPutRope["-- "]; lineLength _ lineLength + 3; lastHyphen _ -1 }; END; END; -- WrapLine. ExtendToNextTabStop: PROC [length: INTEGER] RETURNS [--lengthAtStop:-- INTEGER] = INLINE {RETURN[SpacesPerTab*(length/SpacesPerTab+1)]}; SELECT char FROM Ascii.SP => IF lineLength < lineWrapThreshhold THEN { lineLength _ lineLength + 1; IF stillLeadingSpaces THEN spaces _ spaces + 1; CodeStreamPut[Ascii.SP] } ELSE WrapLine; Ascii.TAB => IF lineLength < lineWrapThreshhold THEN { lineLength _ ExtendToNextTabStop[lineLength]; IF stillLeadingSpaces THEN spaces _ ExtendToNextTabStop[spaces]; CodeStreamPut[Ascii.TAB] } ELSE WrapLine; Ascii.CR, Ascii.FF => { StartNewCodeLine[]; CodeStreamPut[char] }; Ascii.BS => WrapLine; -- Special; BS not printed. ENDCASE => { stillLeadingSpaces _ FALSE; lineLength _ lineLength + 1; IF char = '- THEN { IF lastHyphen = lineLength-1 THEN doingComment _ ~doingComment ELSE lastHyphen _ lineLength }; CodeStreamPut[char] }; END; -- CodeLinePut. WF1: PUBLIC PROC[format: Rope.ROPE, v1: IO.Value] = BEGIN formattedStream.PutF[format, v1]; END; WFS, WriteFormattedStrings: PUBLIC PROCEDURE [ s01, s02, s03: String_StringNIL ] = BEGIN IF s01 # StringNIL THEN formattedStream.PutRope[s01]; IF s02 # StringNIL THEN formattedStream.PutRope[s02]; IF s03 # StringNIL THEN formattedStream.PutRope[s03]; END; WFSL, WriteFormattedStringsLong: PUBLIC PROCEDURE [ s01, s02, s03, s04, s05, s06, s07, s08, s09, s10, s11, s12, s13, s14, s15, s16, s17, s18: String_StringNIL] = BEGIN IF s01 # StringNIL THEN formattedStream.PutRope[s01]; IF s02 # StringNIL THEN formattedStream.PutRope[s02]; IF s03 # StringNIL THEN formattedStream.PutRope[s03]; IF s04 # StringNIL THEN formattedStream.PutRope[s04]; IF s05 # StringNIL THEN formattedStream.PutRope[s05]; IF s06 # StringNIL THEN formattedStream.PutRope[s06]; IF s07 # StringNIL THEN formattedStream.PutRope[s07]; IF s08 # StringNIL THEN formattedStream.PutRope[s08]; IF s09 # StringNIL THEN formattedStream.PutRope[s09]; IF s10 # StringNIL THEN formattedStream.PutRope[s10]; IF s11 # StringNIL THEN formattedStream.PutRope[s11]; IF s12 # StringNIL THEN formattedStream.PutRope[s12]; IF s13 # StringNIL THEN formattedStream.PutRope[s13]; IF s14 # StringNIL THEN formattedStream.PutRope[s14]; IF s15 # StringNIL THEN formattedStream.PutRope[s15]; IF s16 # StringNIL THEN formattedStream.PutRope[s16]; IF s17 # StringNIL THEN formattedStream.PutRope[s17]; IF s18 # StringNIL THEN formattedStream.PutRope[s18]; END; WFL, WriteFormattedLine: PUBLIC PROCEDURE [ nest: Nest, s01, s02, s03: String_StringNIL ] = BEGIN formattedStream.PutRope[IndentInline[nest]]; WFS[s01, s02, s03]; formattedStream.PutChar[Ascii.CR]; END; WFL1, WriteFormattedLine1: PUBLIC PROCEDURE [nest: Nest, s01: String] = BEGIN formattedStream.PutRope[IndentInline[nest]]; formattedStream.PutRope[s01]; formattedStream.PutChar[Ascii.CR]; END; WFLL, WriteFormattedLineLong: PUBLIC PROCEDURE [ nest: Nest, s01, s02, s03, s04, s05, s06: String_StringNIL ] = BEGIN formattedStream.PutRope[IndentInline[nest]]; WFSL[s01, s02, s03, s04, s05, s06]; formattedStream.PutChar[Ascii.CR]; END; Indent: PUBLIC PROCEDURE [nest: Nest] RETURNS [--tabsAndSpaces:-- String] = BEGIN RETURN[ IndentInline[nest] ]; END; IndentInline: PROCEDURE [nest: Nest] RETURNS [--tabsAndSpaces:-- String] = INLINE BEGIN RETURN[ NestTable[MIN[nest,LAST[NestTableIndex]]] ]; END; NestTableIndex: TYPE = Nest[0..30]; NestTable: PACKED ARRAY NestTableIndex OF String = [ --00-- "", --01-- " ", --02-- " ", --03-- " ", --04-- " ", --05-- " ", --06-- " ", --07-- " ", --08-- " ", --09-- " ", --10-- " ", --11-- " ", --12-- " ", --13-- " ", --14-- " ", --15-- " ", --16-- " ", --17-- " ", --18-- " ", --19-- " ", --20-- " ", --21-- " ", --22-- " ", --23-- " ", --24-- " ", --25-- " ", --26-- " ", --27-- " ", --28-- " ", --29-- " ", --30-- " " ]; END. -- LupineManagerImpl. .File [Ivy]Lupine>LupineManagerImpl.mesa. Last edited by BZM on 12-May-82 19:22:17. Last edited by Andrew Birrell on October 25, 1983 10:37 am Top-level translator routine. Can raise ST.OpenError. DeleteExistingCodeFiles; Client-level error handling routines. Raised by ReportError and caught by TranslateRemoteInterface. Routines that construct the string names of important modules. Global OPEN 'interfaceName'. if openedInterface=NIL; named otherwise. OPEN RpcPublic: RPC (or MesaRPC). OPEN RpcPrivate: RPCLupine (or MesaRPCLupine). OPEN Lupine: LupineRuntime. Output file routines (via IO) for the Mesa code that Lupine generates. It is VERY important to call CloseCodeFile on any relevant UNWINDs. Simple formatting routines for indenting and wrapping code lines. This routine WILL wrap comments and string constants. Lupine generates no troublesome strings (i.e., strings that are too long or contain one or more hyphens). Comments should be wrapped OK. The BS character is specially interpreted to mean start a new line and indent for a continuation (as in a multiline record declaration). If the current line is indented all the way to the RIGHT margin (lineWrapThreshhold), any further attempts to indent are ignored. These constants must have SpacesPerNest spaces per nest. No module initialization. Êå˜Jšœ0™0Jšœ)™)Jšœ:™:J˜J˜šÏk ˜ Jš œœœœœœœ˜"Jšœ œ˜Jšœœ<˜DJšœœBœ ˜YJšœœ˜šœœ˜J˜*J˜1—Jšœœ˜šœœ˜J˜ J˜'J˜J˜ J˜/Jšœ˜—Jšœœ˜0šœœ˜Jšœ"œ˜5Jšœ=˜=—Jšœœœ˜%J˜J˜—šœ˜š˜Jšœœ ˜J˜+Jšœœ˜.Jšœ˜—Jšœ&˜-Jšœœ˜ J˜—J˜Jšœ™˜šÏnœœœ œ˜2J˜J˜6J˜J˜Jšœœœ˜#šœœ˜Jšœœ˜Jšœœ˜*šœÏc,˜=˜šœœ˜J˜"J˜˜$J˜)—Jšœœ˜—J˜——JšœŸ ˜—J˜$J˜%˜;Jšœ™—šœœœ˜Jšœ˜J˜J˜Jšœ œ˜Jšœ2œ˜HJ˜7šœœœ˜)Jšœ™Jšœœ1˜Kšœœ˜:šœœ˜;Jšœ3˜7——šœœ˜ Jšœ3œ˜=Jšœ2œ˜Jšœ ˜&J˜—Jšžœ œœœ˜AJ˜Jšœœœœ˜'Jšœ=™=J˜šž œœ œ˜J˜9Jš˜˜Jš˜šœœ˜.J˜J˜J˜"J˜-J˜3—Jšœ œœœ˜=JšœŸ ˜—J˜/Jšœ˜J˜—šžœœ œ˜#J˜/Jš˜š œ œœ œŸœ ˜B˜J˜\—˜J˜4—˜J˜5—˜J˜d—˜J˜A—˜J˜S—˜ J˜_—˜ J˜_—˜J˜C—˜J˜8—˜J˜\—˜J˜G—˜J˜g—˜J˜M—˜ J˜*—˜J˜[—˜J˜S—˜J˜;—˜J˜V—˜J˜Q—˜J˜>—˜J˜$—˜J˜j——J˜Jšœ˜J˜——J˜Jšœ>™>˜Jšœ œ œ œ ˜:J˜š ž œœœœŸ œ ˜JJšœœœ˜&J˜—šžœ œ/˜IJš˜šœœœ œ ˜5J˜ —šœœœ œ ˜;J˜,—šžœœ)˜7Jšœ˜Jš˜Jšœ˜JšœŸ ˜—J˜1šœ3˜3JšœE™E—J˜=J˜?J˜EJ˜?˜>Jšœ!™!—šœE˜EJšœ.™.—šœ7˜7Jšœ™—Jšœ˜J˜—šžœ œ˜ Jš˜šœœ ˜)Jšœœ˜Jšœ˜—Jšœ˜J˜——J˜JšœF™F˜Jšœœ˜Jšœ œœœ˜Jšœœœ˜"J˜šž œœ œ˜9Jš˜˜J˜(J˜—J˜J˜Jšœ˜J˜—šž œ œ œ˜,Jšœ˜ J˜J˜&Jšœ˜J˜—šžœ œ˜-Jšœ˜ Jšœ˜Jšœ2˜2Jšœ˜J˜—šžœœœ ˜(šœœ˜Jšœœ œ˜Jš˜Jšœœ œ)˜Jšœœœ ˜:J˜-J˜)—Jš œ œœœ œ œ ˜EJšœœœ˜J˜Yšœò˜òJ˜/J˜8J˜0J˜8Jšœ*˜*J˜—šœÇ˜ÇJšœ*˜*Jšœ&˜&Jšœ%˜%Jšœ˜J˜J˜—JšœŸ˜!—J˜šž œœ œ˜!JšœC™CJš˜J˜J˜J˜Jšœœ˜Jšœ˜J˜—šžœ œ˜$Jš˜šž œœ˜"Jš˜˜ J˜—Jšœœ˜Jšœ˜—J˜J˜J˜Jšœ˜J˜—šž œ œ˜-Jšœ ˜Jšœ˜ Jšœ˜Jšœ˜J˜——J˜JšœA™A˜Jšœœ˜Jšœœ˜Jšœœ˜-Jšœœ˜(J˜Jšœ"œ˜*Jšœ4œ˜JšŸœ:˜@JšŸœ<˜BJšŸœ>˜DJšŸœ@˜FJšŸœD˜JJ˜J˜Jšœ™J˜JšœŸ˜J˜——…—CŒZŸ