DIRECTORY Alloc: TYPE USING [Create, Chunkify, Destroy, Failure, Reset, TableInfo], Ascii: TYPE USING [Lower], BasicTime: TYPE USING [GMT, Now, Period, ToNSTime], BcdBindDefs: TYPE USING [RelocHandle], BcdComData: TYPE USING [ aborted, bcdName, binderVersion, codeName, commandArgs, copyCode, copySymbols, currentName, debug, errors, errorStream, logStream, nConfigs, nErrors, nExports, nImports, nModules, nPages, nWarnings, objectStamp, op, outputFile, outputFti, rootName, sourceName, sourceStream, sourceVersion, symbolName, table, textIndex, warnings], BcdControlDefs: TYPE USING [ BindRoot, BuildSemanticEntries, LoadRoot, WriteBcd, PrintBcd, PrintRelocations, PrintSemanticEntries, PrintTree], BcdDefs: TYPE USING [ BinderNTables, httype, MTNull, NullName, sstype, treetype, VersionStamp], BcdErrorDefs: TYPE USING [Finalize, GetModule, GetSti, Initialize], BcdFileDefs: TYPE USING [BuildFileTable, EraseFileTable], BcdLiterals: TYPE USING [Initialize, Finalize, SealLiterals], BcdParseData: TYPE, BcdUtilDefs: TYPE USING [EnterFile, Init, Reset], Commander: TYPE USING [Handle, Register], CommandUtil: TYPE USING [Echo, Failed, GetNthPair, ListLength, PairList, Parse, SetExtension], DebuggerSwap: TYPE USING [CallDebugger], FileViewerOps: TYPE USING [WaitUntilSaved, ShowLog], FS: TYPE USING [ Close, Create, Delete, Error, nullOpenFile, Open, OpenFile, StreamFromOpenFile, FileInfo], HashOps: TYPE USING [Finalize, Initialize], IO: TYPE USING [ char, Close, CR, CreateStream, CreateStreamProcs, int, Put, PutChar, PutRope, rope, SetLength, STREAM, StreamProcs, time, RIS], Loader: TYPE USING [BCDBuildTime], OSMiscOps: TYPE USING [MergeStamps, TimeToStamp], P1: TYPE USING [InstallParseTable, Parse], PrincOpsUtils: TYPE USING [Codebase], ProcessExtras: TYPE USING [CheckForAbort], Rope: TYPE USING [Equal, Fetch, Find, Flatten, Length, ROPE, Substr, Cat], Symbols: TYPE USING [stNull], Tree: TYPE USING [Link], TreeOps: TYPE USING [PopTree, Finalize, Initialize], UserProfile: TYPE USING [Token, Boolean]; BcdControl: PROGRAM IMPORTS Alloc, Ascii, BasicTime, BcdControlDefs, BcdErrorDefs, BcdFileDefs, BcdLiterals, BcdParseData, BcdUtilDefs, Commander, CommandUtil, DebuggerSwap, FileViewerOps, FS, HashOps, IO, Loader, OSMiscOps, P1, PrincOpsUtils, ProcessExtras, Rope, TreeOps, UserProfile, data: BcdComData = { EquivalentRope: PROC [s1, s2: Rope.ROPE] RETURNS [BOOL] ~ { RETURN [Rope.Equal[s1, s2, FALSE]]}; log: IO.STREAM _ NIL; logFile: FS.OpenFile _ FS.nullOpenFile; SetLogStream: PROC ~ { IF logFile = FS.nullOpenFile THEN logFile _ FS.Create["Binder.Log"]; log _ FS.StreamFromOpenFile[logFile, $write]; log.SetLength[0]; }; LogRope: PROC [s: Rope.ROPE] ~ {IO.PutRope[log, s]}; LogChar: PROC [c: CHAR] ~ {IO.PutChar[log, c]}; LogNumber: PROC [n: INTEGER] ~ {IO.Put[log, IO.int[n]]}; renamedOutput: BOOL _ FALSE; RepeatCommand: PROC [s: IO.STREAM] ~ { OPEN IO; PutRope[s, "\nBinding "]; PutRope[s, data.sourceName]; IF renamedOutput THEN {PutRope[s, ", BCD to "]; PutRope[s, data.bcdName]}; IF data.copyCode THEN { PutRope[s, ", code to "]; PutRope[s, IF data.codeName = NIL THEN "BCD" ELSE data.codeName]}; IF data.copySymbols THEN { PutRope[s, ", symbols to "]; PutRope[s, IF data.symbolName = NIL THEN "BCD" ELSE data.symbolName]}; PutChar[s, '\n]}; errorName: Rope.ROPE _ NIL; errorFile: FS.OpenFile _ FS.nullOpenFile; errorStream: IO.STREAM _ NIL; errorStreamProcs: REF IO.StreamProcs _ NIL; SetErrorName: PROC ~ { IF errorName = NIL THEN { errorName _ CommandUtil.SetExtension[data.rootName, "errlog"]}}; DummyErrorStream: PROC [ putProc: SAFE PROC[self: IO.STREAM, char: CHAR]] RETURNS [IO.STREAM] ~ { IF errorStreamProcs = NIL THEN errorStreamProcs _ IO.CreateStreamProcs[ variety: $output, class: $DummyErrorStream, putChar: putProc ]; RETURN[IO.CreateStream[errorStreamProcs, NIL]]}; OpenErrorStream: PROC ~ { IF errorName = NIL THEN SetErrorName[]; IF errorFile = FS.nullOpenFile THEN errorFile _ FS.Create[errorName]; errorStream _ FS.StreamFromOpenFile[errorFile, $write]; IO.SetLength[errorStream, 0]; WriteHerald[errorStream, errorName]; RepeatCommand[errorStream]}; CloseErrorStream: PROC ~ INLINE {IF data.errorStream # NIL THEN ErrorDestroy[]}; ErrorPut: SAFE PROC[self: IO.STREAM, char: CHAR] ~ TRUSTED { IF errorStream = NIL THEN OpenErrorStream[]; errorStream.PutChar[char]}; ErrorDestroy: PROC ~ { IF errorFile # FS.nullOpenFile AND errorStream # NIL THEN { IO.Close[errorStream]; errorStream _ NIL}}; WriteHerald: PROC [stream: IO.STREAM, id: Rope.ROPE] ~ { stream.Put[IO.rope["Cedar 5.0 Binder of "], IO.time[Loader.BCDBuildTime[]]]; IF id.Length[] # 0 THEN stream.Put[IO.rope[id], IO.rope[" -- "]]; stream.Put[IO.time[], IO.char['\n]]}; Logger: PROC [proc: PROC [log: IO.STREAM]] = { proc[data.errorStream]}; sourceFile, bcdFile: FS.OpenFile _ FS.nullOpenFile; GetRoot: PROC [s: Rope.ROPE] RETURNS[Rope.ROPE] ~ { dotIndex: INT _ Rope.Find[s, "."]; IF dotIndex > -1 THEN s _ Rope.Substr[s, 0, dotIndex]; RETURN[s]}; StandardDefaults: PACKED ARRAY CHAR ['a..'z] OF BOOL ~ [ FALSE, -- A Copy all (code and symbols) FALSE, -- B Unused TRUE , -- C Copy code FALSE, -- D Call debugger error FALSE, -- E Unused FALSE, -- F Unused TRUE , -- G TRUE => errlog goes to binder.log, FALSE => use root.errlog FALSE, -- H Unused FALSE, -- I Unused FALSE, -- J Unused FALSE, -- K Unused FALSE, -- L Unused FALSE, -- M Unused FALSE, -- N Unused FALSE, -- O Unused FALSE, -- P Pause after config with errors FALSE, -- Q Unused FALSE, -- R Unused FALSE, -- S Copy symbols FALSE, -- T Unused FALSE, -- U Unused FALSE, -- V Unused FALSE, -- W Pause after config with warnings FALSE, -- X Copy compressed symbols (not implemented) FALSE, -- Y Unused FALSE -- Z Unused ]; Bind: SAFE PROC [cmd: Commander.Handle] RETURNS [result: REF _ NIL, msg: Rope.ROPE _ NIL] ~ TRUSTED { results: CommandUtil.PairList; switches: Rope.ROPE; key, value: Rope.ROPE; anyErrors, anyWarnings: BOOL _ FALSE; localPause: BOOL; cmdStream: IO.STREAM; defaultSwitches: PACKED ARRAY CHAR ['a..'z] OF BOOL _ StandardDefaults; defaultDebugPass: CARDINAL _ CARDINAL.LAST; localSwitches: PACKED ARRAY CHAR ['a..'z] OF BOOL; debugPass: CARDINAL; cmd.commandLine _ Rope.Cat[UserProfile.Token["Binder.Switches"], " ", cmd.commandLine]; cmdStream _ IO.RIS[cmd.commandLine]; data.sourceName _ data.bcdName _ data.codeName _ data.symbolName _ NIL; SetLogStream[]; WriteHerald[log, NIL]; data.op _ $bind; data.table _ NIL; DO { Initialize: PROC ~ { weights: ARRAY [0..BcdDefs.BinderNTables) OF Alloc.TableInfo _ [ -- empirical (SDD) [4], [2], [10], [4], [5], [4], [4], [4], [2], [1], [4], [4], [4], [2], [4], [2], [4], [5], [1], [1]]; RepeatCommand[log]; data.errors _ data.warnings _ FALSE; data.nErrors _ data.nWarnings _ 0; data.textIndex _ 0; data.currentName _ BcdDefs.NullName; IF data.table = NIL THEN { data.table _ Alloc.Create[weights~DESCRIPTOR[weights]]; (data.table).Chunkify[BcdDefs.treetype]} ELSE (data.table).Reset[]; HashOps.Initialize[data.table, BcdDefs.httype, BcdDefs.sstype]; TreeOps.Initialize[data.table]; BcdUtilDefs.Init[data.table]; BcdLiterals.Initialize[data.table]; BcdErrorDefs.Initialize[]; errorStream _ NIL}; Finalize: PROC ~ { TreeOps.Finalize[]; HashOps.Finalize[]; BcdErrorDefs.Finalize[]; BcdLiterals.Finalize[]; BcdUtilDefs.Reset[]; (data.table).Reset[]; anyErrors _ data.errors OR anyErrors; anyWarnings _ data.warnings OR anyWarnings; IF data.aborted THEN LogRope["Binding aborted\n"] ELSE IF data.errors THEN LogRope["Errors detected; BCD not written\n"] ELSE { IF data.nConfigs > 1 THEN { LogNumber[data.nConfigs]; LogRope[" configs, "]}; LogNumber[data.nModules]; LogRope[" modules, "]; LogNumber[data.nImports]; LogRope[" imports, "]; LogNumber[data.nExports]; LogRope[" exports, "]; LogNumber[data.nPages]; LogRope[" pages, "]; LogNumber[BasicTime.Period[from: startTime, to: BasicTime.Now[]]]; LogRope[" seconds\n"]}; IF errorStream # NIL THEN { LogRope["See "]; LogRope[data.rootName]; LogRope[".errlog\n"]}; IF log # data.errorStream THEN CloseErrorStream[]; IF errorName = NIL THEN { SetErrorName[]; }; IO.Close[data.sourceStream]; sourceFile _ FSClose[sourceFile]; bcdFile _ FSClose[bcdFile]; IF data.nErrors # 0 OR data.aborted THEN FS.Delete[data.bcdName ! FS.Error => TRUSTED {CONTINUE}]; data.outputFile _ FS.nullOpenFile; IF data.errors THEN cmd.out.Put[IO.rope["no errors"]] ELSE cmd.out.Put[IO.int[data.nErrors], IO.rope[" errors"]]; IF data.nWarnings # 0 THEN cmd.out.Put[IO.rope[", "], IO.int[data.nWarnings], IO.rope[" warnings"]]; cmd.out.Put[IO.char['\n]]; }; Debug: PROC [printRel, printBcd: BOOL] ~ { BcdControlDefs.PrintTree[root]; BcdControlDefs.PrintSemanticEntries[]; IF printRel THEN BcdControlDefs.PrintRelocations[relocationHead]; IF printBcd THEN BcdControlDefs.PrintBcd[]}; parsed: BOOL; root: Tree.Link; first: BOOL _ TRUE; relocationHead: BcdBindDefs.RelocHandle; startTime: BasicTime.GMT; localSwitches _ defaultSwitches; localPause _ FALSE; debugPass _ defaultDebugPass; renamedOutput _ FALSE; data.aborted _ FALSE; [data.sourceName, data.commandArgs, results, switches] _ CommandUtil.Parse[s: cmdStream ! CommandUtil.Failed => {GOTO badSyntax}]; IF data.sourceName = NIL AND switches = NIL THEN EXIT; -- done binding LogRope["\nCommand: "]; CommandUtil.Echo[ d~log, operator~data.sourceName, argList~data.commandArgs, resultList~results, switches~switches]; IF data.sourceName = NIL THEN GOTO globalSwitches; FOR n: CARDINAL IN [0..CommandUtil.ListLength[results]) DO [key, value] _ CommandUtil.GetNthPair[list~results, n~n]; SELECT TRUE FROM (key = NIL), EquivalentRope[key, "bcd"] => { data.bcdName _ value; renamedOutput _ TRUE}; EquivalentRope[key, "code"] => { data.codeName _ value; localSwitches['c] _ TRUE}; EquivalentRope[key, "symbols"] => { data.symbolName _ value; localSwitches['s] _ TRUE}; ENDCASE => GO TO badSemantics; ENDLOOP; data.rootName _ GetRoot[ (IF data.bcdName # NIL THEN data.bcdName ELSE data.sourceName)]; IF switches # NIL THEN { sense: BOOL _ TRUE; length: INT _ switches.Length[]; FOR i: INT IN [0..length) DO c: CHAR ~ switches.Fetch[i]; SELECT c FROM '-, '~ => sense _ ~sense; IN ['a..'z] => {localSwitches[c] _ sense; sense _ TRUE}; IN ['A..'Z] => {localSwitches[Ascii.Lower[c]] _ sense; sense _ TRUE}; '! => {DebuggerSwap.CallDebugger[NIL]; sense _ TRUE}; IN ['1..'4] => {debugPass _ c-'0; sense _ TRUE}; ENDCASE; ENDLOOP; }; data.sourceName _ CommandUtil.SetExtension[data.sourceName, "config"]; FileViewerOps.WaitUntilSaved[data.sourceName, cmd.out ! ABORTED => {data.aborted _ TRUE; EXIT}]; IF data.bcdName = NIL THEN data.bcdName _ data.rootName; data.bcdName _ CommandUtil.SetExtension[data.bcdName, "bcd"]; data.copyCode _ (localSwitches['c] OR localSwitches['a]); data.copySymbols _ (localSwitches['s] OR localSwitches['x] OR localSwitches['a]); IF localSwitches['x] THEN LogRope["\nSymbol compression not available in this version"]; IF data.copyCode AND data.codeName # NIL THEN { data.codeName _ CommandUtil.SetExtension[data.codeName, "code"]; IF EquivalentRope[data.codeName, data.bcdName] THEN data.codeName _ NIL; }; IF data.copySymbols AND ~(localSwitches['a] AND data.symbolName = NIL) THEN { data.symbolName _ CommandUtil.SetExtension[data.symbolName, "symbols"]; IF EquivalentRope[data.symbolName, data.bcdName] THEN data.symbolName _ NIL; }; cmd.out.Put[IO.rope["Binding: "], IO.rope[data.rootName]]; FOR c: CHAR IN ['a..'z] DO IF localSwitches[c] # StandardDefaults[c] THEN { IF first THEN {first _ FALSE; cmd.out.PutChar['/]}; IF StandardDefaults[c] THEN cmd.out.PutChar['-]; cmd.out.PutChar[c]}; ENDLOOP; cmd.out.PutChar[IO.CR]; startTime _ BasicTime.Now[]; sourceFile _ FS.nullOpenFile; errorFile _ data.outputFile _ FS.nullOpenFile; data.sourceStream _ NIL; sourceFile _ FS.Open[data.sourceName ! FS.Error => TRUSTED {CONTINUE}]; IF sourceFile # NIL THEN { data.sourceStream _ FS.StreamFromOpenFile[sourceFile]; data.sourceVersion _ BcdDefs.VersionStamp[ net~0, host~0, time~BasicTime.ToNSTime[FS.FileInfo[data.sourceName].created]]; }; IF data.sourceStream = NIL THEN GOTO noSource; data.outputFile _ bcdFile _ FS.Create[data.bcdName ! FS.Error => TRUSTED {CONTINUE}]; data.logStream _ log; data.errorStream _ IF localSwitches['g] THEN log ELSE DummyErrorStream[putProc~ErrorPut]; localPause _ localSwitches['p]; data.debug _ localSwitches['d]; localSwitches['g] _ localSwitches['p] _ localSwitches['d] _ FALSE; data.objectStamp _ OSMiscOps.TimeToStamp[data.sourceVersion]; data.objectStamp _ OSMiscOps.MergeStamps[ data.objectStamp, OSMiscOps.TimeToStamp[[0, 0, LOOPHOLE[localSwitches]]]]; data.objectStamp _ OSMiscOps.MergeStamps[ data.objectStamp, OSMiscOps.TimeToStamp[data.binderVersion]]; Initialize[]; BEGIN ENABLE { BcdErrorDefs.GetModule => RESUME [BcdDefs.MTNull, 0]; BcdErrorDefs.GetSti => RESUME [Symbols.stNull]; Alloc.Failure => { data.errors _ TRUE; IF ~data.debug THEN { LogRope["Storage Overflow\n"]; GOTO Overflow}}; UNWIND => Finalize[]; }; ProcessExtras.CheckForAbort[! ABORTED => GOTO Abort]; cmd.out.PutRope[". " ! ABORTED => GOTO Abort]; -- pass 1 [complete~parsed, nErrors~data.nErrors] _ P1.Parse[data.sourceStream, Logger]; IF ~parsed THEN GO TO Failed; IF data.nErrors > 0 THEN data.errors _ TRUE; root _ TreeOps.PopTree[]; BcdControlDefs.BuildSemanticEntries[root]; data.outputFti _ BcdUtilDefs.EnterFile[LOOPHOLE[Rope.Flatten[data.bcdName]]]; BcdFileDefs.BuildFileTable[data.table]; IF debugPass <= 1 THEN Debug[printRel~FALSE, printBcd~FALSE]; ProcessExtras.CheckForAbort[! ABORTED => GOTO AbortAndEraseFileTable]; cmd.out.PutRope[". " ! ABORTED => GOTO AbortAndEraseFileTable]; -- pass 2 relocationHead _ BcdControlDefs.LoadRoot[root]; BcdLiterals.SealLiterals[]; IF debugPass <= 2 THEN Debug[printRel~TRUE, printBcd~TRUE]; ProcessExtras.CheckForAbort[! ABORTED => GOTO AbortAndEraseFileTable]; cmd.out.PutRope[". " ! ABORTED => GOTO AbortAndEraseFileTable]; -- pass 3 BcdControlDefs.BindRoot[relocationHead]; IF debugPass <= 3 THEN Debug[printRel~FALSE, printBcd~TRUE]; IF ~data.errors THEN { ProcessExtras.CheckForAbort[! ABORTED => GOTO AbortAndEraseFileTable]; cmd.out.PutRope[". " ! ABORTED => GOTO AbortAndEraseFileTable]; -- pass 4 BcdControlDefs.WriteBcd[root]}; BcdFileDefs.EraseFileTable[]; EXITS Overflow => NULL; Failed => data.errors _ TRUE; Abort => data.aborted _ TRUE; AbortAndEraseFileTable => {BcdFileDefs.EraseFileTable[]; data.aborted _ TRUE}; END; Finalize[]; EXITS noSource => { LogRope["\nCan't open "]; LogRope[data.sourceName]; LogChar['\n]; data.errors _ TRUE}; globalSwitches => { sense: BOOL _ TRUE; length: INT _ switches.Length[]; FOR i: INT IN [0..length) DO c: CHAR ~ switches.Fetch[i]; SELECT c FROM '-, '~ => sense _ ~sense; '! => DebuggerSwap.CallDebugger[NIL]; IN ['a..'z] => {defaultSwitches[c] _ sense; sense _ TRUE}; IN ['A..'Z] => {defaultSwitches[Ascii.Lower[c]] _ sense; sense _ TRUE}; IN ['1..'5] => {defaultDebugPass _ c-'0; sense _ TRUE}; ENDCASE => EXIT; ENDLOOP}; badSemantics => { data.errors _ TRUE; LogRope["\n -- Illegal command"]}; }; data.sourceName _ data.bcdName _ data.codeName _ data.symbolName _ NIL; errorName _ NIL; IF data.aborted THEN EXIT; -- stop binding IF (data.errors OR (data.warnings AND localSwitches['w])) AND localPause THEN EXIT; REPEAT badSyntax => {anyErrors _ data.errors _ TRUE; LogRope["-- Illegal syntax"]}; ENDLOOP; IF data.table # NIL THEN {Alloc.Destroy[data.table]; data.table _ NIL}; IO.Close[log]; logFile _ FS.nullOpenFile; cmd.out.PutRope["End of binding\n"]; IF data.aborted OR anyErrors OR anyWarnings THEN result _ $Failure ELSE result _ $Success; FileViewerOps.ShowLog[fileName: "Binder.log", destroyIt: result # $Failure, createIconic: UserProfile.Boolean["Compiler.IconicLogs", FALSE], blinkIfIconic: UserProfile.Boolean["Compiler.IconicLogs", FALSE]]; }; FSClose: PROC [fh: FS.OpenFile] RETURNS [FS.OpenFile] = { IF fh # FS.nullOpenFile THEN FS.Close[fh ! FS.Error => IF error.code = $invalidOpenFile THEN CONTINUE]; RETURN [FS.nullOpenFile]; }; Init: PROC ~ { START data; data.binderVersion _ [net~0Ch, host~0Bh, time~000F0003h]; -- Cedar release P1.InstallParseTable[PrincOpsUtils.Codebase[LOOPHOLE[BcdParseData]]]; Commander.Register["Binder", Bind, "Bind a list of configurations."]}; Init[]; }. BBcdControl.mesa Satterthwaite on May 10, 1983 10:24 am Maxwell, August 29, 1983 2:52 pm Russ Atkinson, October 7, 1983 11:34 am Paul Rovner, December 4, 1983 12:06 pm command gathering and logging error logging IF fbh = NIL AND feedback.create # NIL THEN fbh _ feedback.create[system~"Binder"L, herald~herald]; file bookkeeping switches Command interface main loop OSMiscOps.DeleteFile[errorName]; IF feedback.finishItem # NIL THEN ... encode switches, binder version (see BcdLoad processing also) global Binder initialization data.binderVersion _ OSMiscOps.ImageId[]; Ê£˜šœ™Jšœ'™'J™ J™'J™&—J˜šÏk ˜ Jšœœœ8˜IJšœœœ ˜Jšœ œœœ˜3Jšœ œœ˜&šœ œœ˜J˜Ê—šœœœ˜J˜q—šœ œœ˜J˜I—Jšœœœ+˜CJšœ œœ"˜9Jšœ œœ&˜=Jšœœ˜Jšœ œœ˜1Jšœ œœ˜)Jšœ œœG˜^Jšœœœ˜(Jšœœœ˜4šœœœ˜JšœZ˜Z—Jšœ œœ˜+šœœœ˜Jšœ œPœœ˜—Jšœœœ˜"Jšœ œœ˜1Jšœœœ˜*Jšœœœ ˜%Jšœœœ˜*Jšœœœ'œ˜KJšœ œœ ˜Jšœœœ˜Jšœ œœ!˜4Jšœ œœ˜)J˜—šœ ˜š˜Jšœ¡œ œR˜‚Jšœ˜—J˜J˜š Ïnœœœœœ˜;Jšœœ˜$J˜J˜—Jšœ™˜Jšœœœœ˜Jšœ œ œ˜'J˜šž œœ˜Jšœ œœ œ˜DJšœ-˜-Jšœ˜Jšœ˜J˜—Jšžœœ œœ˜4Jšžœœœœ˜/Jš ž œœœœ œ ˜8J˜Jšœœœ˜J˜šž œœœœ˜&Jšœœ˜J˜6Jšœœ5˜Jšœœ˜J˜Jš œ œœœœ˜B—šœœ˜J˜Jš œ œœœœ˜F—J˜J˜J˜——Jšœ ™ ˜Jšœœœ˜Jšœ œ œ˜)Jšœ œœœ˜Jšœœœœ˜+J˜J˜šž œœ˜šœ œœ˜J˜@J˜——šžœœ˜Jšœ œœœœœœœœ˜Hšœœœ˜šœœ˜(Jšœ˜Jšœ˜Jšœ˜Jšœ˜——Jšœœ œ˜0J˜—šžœœ˜Jšœ œœ˜'Jšœ œœ œ˜EJšœ7˜7Jšœ˜J˜BJ˜—Jš žœœœœœœ˜PJ˜šžœœœœœœœ˜J˜Jšœœ˜Jšœœ˜Jšœœœ˜%Jšœ œ˜Jšœ œœ˜J˜Jš œœœœ œœ˜GJšœœœœ˜+Jš œœœœ œœ˜2Jšœ œ˜J˜JšœW˜WJšœ œœ˜$JšœCœ˜GJ˜Jšœ˜Jšœœ˜J˜J˜Jšœ œ˜J˜Jšœ ™ ˜Jšœ˜˜šž œœ˜šœ œœŸ˜SJ˜2J˜2—J˜Jšœœ˜$J˜"J˜J˜$šœœœ˜Jšœ" œ ˜7J˜(—Jšœ˜J˜?J˜J˜J˜#J˜Jšœœ˜J˜—šžœœ˜J˜(J˜J˜-J˜Jšœœ)œ ˜RJšœœ˜1Jšœœ œ.˜Fšœ˜šœœ˜Jšœ1˜1—Jšœ0˜0Jšœ0˜0Jšœ0˜0Jšœ,˜,JšœZ˜Z—šœœœ˜Jšœ?˜?—Jšœœ˜2šœ œœ˜Jšœ˜Jšœ ™ Jšœ˜—Jšœ˜Jšœ!˜!Jšœ˜šœœ˜(Jšœœ œœ˜9—Jšœœ˜"Jšœœœ™%šœ ˜Jšœ œ˜&Jšœ œœ˜;—šœ˜Jšœ œ œœ˜N—Jšœ œ ˜˜J˜——šžœœœ˜*J˜J˜&Jšœ œ1˜AJšœ œ˜,J˜—Jšœœ˜ J˜Jšœœœ˜J˜(Jšœœ˜J˜J˜ Jšœ œ ˜2Jšœœ˜Jšœœ˜J˜˜8šœ˜Jšœœ ˜*——Jš œœœ œœœŸ˜GJšœ˜˜J˜;J˜'—Jšœœœœ˜2šœœœ&˜:J˜9šœœ˜šœœ#˜-Jšœ&œ˜,—šœ!˜!Jšœ+œ˜1—šœ%˜%Jšœ-œ˜3—Jšœœœ˜—Jšœ˜—˜Jš œœœœœ˜@—šœ œœ˜Jšœœœ˜Jšœœ˜ šœœœ ˜Jšœœ˜šœ˜ J˜Jšœ0œ˜8Jšœ=œ˜EJšœ!œ œ˜5Jšœ(œ˜0Jšœ˜—Jš˜—Jšœ˜J˜—JšœF˜Fšœ5˜5Jšœœœœ˜*—Jšœœœ˜8Jšœ=˜=Jšœ#œ˜9Jšœ&œœ˜Qšœ˜Jšœ>˜>—šœœœœ˜/Jšœ@˜@Jšœ-œ˜HJšœ˜—š œœœœœ˜MJšœG˜GJšœ/œ˜LJšœ˜—J˜Jšœ œœ˜:šœœœ ˜šœ(œ˜0Jšœœ œ˜3Jšœœ˜0Jšœ˜—Jšœ˜—šœœœ˜J˜—J˜J˜Jšœ œ˜Jšœœ˜.Jšœœ˜Jš œ œœ œœ˜Gšœœœ˜Jšœ6˜6˜*Jšœ'œ%˜N—Jšœ˜—Jšœœœœ ˜.Jš œœœ œœ˜UJ˜J˜˜Jšœœœ$˜F—J˜J˜Jšœ<œ˜BJ˜˜=Jšœ=™=˜)Jšœ/œ˜J—˜)J˜=J˜——˜ J˜—š˜šœ˜Jšœœ˜5Jšœœ˜/˜Jšœœ˜šœ œ˜Jšœœ ˜/——Jšœ˜Jšœ˜J˜—Jšœ œœ˜5Jšœ œœ Ÿ ˜8J˜NJšœ œœœ˜Jšœœœ˜,J˜J˜*J˜Jšœ'œ˜M˜'Jšœœœ œ˜=J˜—Jšœ œœ˜FJšœ œœŸ ˜IJ˜/˜Jšœœœ œ˜;J˜—Jšœœœ˜FJšœœœŸ ˜I˜(Jšœœœ œ˜