DIRECTORY Atom USING [GetPName], BasicTime USING [GMT], DB USING [Aborted, CopyEntity, Error, ErrorCode, Failure, CreateRelship, DeclareEntity, DomainSubset, EntityInfo, FirstRelship, GetF, GetSegmentInfo, LookupEntity, LookupProperty, NextEntity, NullDomain, ReleaseEntitySet, SetF, B2V, E2V, I2V, L2VS, S2V, T2V, V2B, V2I, V2S, V2T, Entity, EntitySet, Relship, ValueSequence], IO, RefTab USING [Ref], Rope, WalnutDB, WalnutDefs USING [Error, MsgSet, Segment, ServerInfo], WalnutKernelDefs USING [LogExpungePhase], WalnutRoot USING [CommitAndContinue, StatsReport], WalnutSchema; WalnutDBOpsImpl: CEDAR PROGRAM IMPORTS Atom, DB, IO, WalnutDB, WalnutDefs, WalnutRoot, WalnutSchema EXPORTS WalnutDB = BEGIN OPEN WalnutSchema; GMT: TYPE = BasicTime.GMT; ROPE: TYPE = Rope.ROPE; MsgSet: TYPE = WalnutDefs.MsgSet; Entity: TYPE = DB.Entity; EntitySet: TYPE = DB.EntitySet; Relship: TYPE = DB.Relship; ServerInfo: TYPE = WalnutDefs.ServerInfo; walnutSegment: PUBLIC ATOM _ $Walnut; activeMsgSet: PUBLIC MsgSet _ ["Active", -1]; deletedMsgSet: PUBLIC MsgSet _ ["Deleted", -1]; activeMessageSet: PUBLIC Entity; deletedMessageSet: PUBLIC Entity; unacceptedEntity: PUBLIC Entity; msgSetsTable: PUBLIC RefTab.Ref _ NIL; debugging: BOOL _ FALSE; DBErrorSeen: SIGNAL = CODE; DeclareDB: PUBLIC PROC[segment: WalnutDefs.Segment, schemaInvalid: BOOL] = { IF schemaInvalid OR DB.NullDomain[MsgSetDomain] THEN InitSchema[segment, schemaInvalid] ELSE { walnutSegment _ segment; msgSetsTable _ NIL; }; }; InitSchema: PUBLIC PROC[segment: WalnutDefs.Segment, schemaInvalid: BOOL _ TRUE] = { init: DB.ValueSequence; fullNeeded: BOOL; aaName: ATOM = WalnutDB.CanonicalName[activeMsgSet.name]; caName: ROPE = Atom.GetPName[aaName]; walnutSegment _ segment; msgSetsTable _ NIL; IF schemaInvalid THEN { WalnutSchema.SetSchemaVersion[walnutSegment]; WalnutRoot.CommitAndContinue[]; }; WalnutSchema.Initialize[segment]; fullNeeded _ (DB.LookupEntity[MsgSetDomain, caName] = NIL); BEGIN adName: ATOM = WalnutDB.CanonicalName[deletedMsgSet.name]; e: Entity _ DB.DeclareEntity[MsgSetDomain, caName]; activeMessageSet _ DB.CopyEntity[e]; e _ DB.DeclareEntity[MsgSetDomain, Atom.GetPName[adName]]; deletedMessageSet _ DB.CopyEntity[e]; END; unacceptedEntity _ DB.CopyEntity[DB.DeclareEntity[UnacceptedDomain, "TRUE"]]; IF fullNeeded THEN { init _ DB.L2VS[LIST [ DB.E2V[activeMessageSet], [integer[0]], [integer[1]], [rope[activeMsgSet.name]] ] ]; [] _ DB.CreateRelship[msBasicInfo, init]; init _ DB.L2VS[LIST [ DB.E2V[deletedMessageSet], [integer[0]], [integer[1]], [rope[deletedMsgSet.name]] ] ]; [] _ DB.CreateRelship[msBasicInfo, init]; }; }; IsReadOnly: PUBLIC PROC RETURNS[readonly: BOOL] = { readonly_ DB.GetSegmentInfo[walnutSegment].readOnly }; GetDBName: PUBLIC PROC RETURNS[fileName: ROPE] = { fileName_ DB.GetSegmentInfo[walnutSegment].filePath }; GetRootInfo: PUBLIC PROC RETURNS[rootFileStamp: GMT, rootFileKey, mailFor: ROPE] = { Gri: PROC = { rRootInfo: Relship = DB.FirstRelship[gRootInfo]; rootFileStamp _ DB.V2T[DB.GetF[rRootInfo, gRootFileStamp]]; rootFileKey _ DB.V2S[DB.GetF[rRootInfo, gRootFileKey]]; mailFor _ DB.V2S[DB.GetF[rRootInfo, gMailFor]]; }; CarefullyApply[Gri]; }; SetRootInfo: PUBLIC PROC[rootFileStamp: GMT, rootFileKey, mailFor: ROPE] = { Sri: PROC = { rRootInfo: Relship = DB.FirstRelship[gRootInfo]; DB.SetF[rRootInfo, gRootFileStamp, DB.T2V[rootFileStamp]]; DB.SetF[rRootInfo, gRootFileKey, DB.S2V[rootFileKey]]; DB.SetF[rRootInfo, gMailFor, DB.S2V[mailFor]]; }; CarefullyApply[Sri]; }; GetRootFileVersion: PUBLIC PROC RETURNS[rootFileStamp: GMT] = { Gri: PROC = { rRootInfo: Relship = DB.FirstRelship[gRootInfo]; rootFileStamp _ DB.V2T[DB.GetF[rRootInfo, gRootFileStamp]]; }; CarefullyApply[Gri]; }; SetRootFileVersion: PUBLIC PROC[rootFileStamp: GMT] = { Sri: PROC = { rRootInfo: Relship = DB.FirstRelship[gRootInfo]; DB.SetF[rRootInfo, gRootFileStamp, DB.T2V[rootFileStamp]]; }; CarefullyApply[Sri]; }; GetOpInProgressPos: PUBLIC PROC RETURNS[inProgressPos: INT] = { Goip: PROC = { rLogInfo: Relship = DB.FirstRelship[gLogInfo]; inProgressPos_ DB.V2I[DB.GetF[rLogInfo, gOpInProgressPos]] }; CarefullyApply[Goip]; }; SetOpInProgressPos: PUBLIC PROC[inProgressPos: INT] = { Siop: PROC = { rLogInfo: Relship = DB.FirstRelship[gLogInfo]; DB.SetF[rLogInfo, gOpInProgressPos, DB.I2V[inProgressPos]]; }; CarefullyApply[Siop]; }; GetParseLogInProgress: PUBLIC PROC RETURNS[inProgress: BOOL] = { Gplp: PROC = { rParseLogInfo: Relship = DB.FirstRelship[gParseLogInfo]; inProgress_ DB.V2B[DB.GetF[rParseLogInfo, gParseLogInProgress]] }; CarefullyApply[Gplp]; }; SetParseLogInProgress: PUBLIC PROC[inProgress: BOOL] = { Splp: PROC = { rParseLogInfo: Relship = DB.FirstRelship[gParseLogInfo]; DB.SetF[rParseLogInfo, gParseLogInProgress, DB.B2V[inProgress]]; }; CarefullyApply[Splp]; }; GetParseLogPos: PUBLIC PROC RETURNS[pos: INT] = { Gplp: PROC = { rParseLogInfo: Relship = DB.FirstRelship[gParseLogInfo]; pos _ DB.V2I[DB.GetF[rParseLogInfo, gParseLogPos]] }; CarefullyApply[Gplp]; }; SetParseLogPos: PUBLIC PROC[pos: INT] = { Splp: PROC = { rParseLogInfo: Relship = DB.FirstRelship[gParseLogInfo]; DB.SetF[rParseLogInfo, gParseLogPos, DB.I2V[pos]]; }; CarefullyApply[Splp]; }; CarefullyApply: PUBLIC PROC [proc: PROC[]] = { exp: ROPE; eCode: ATOM; BEGIN ENABLE BEGIN DB.Error => { IF debugging THEN SIGNAL DBErrorSeen; eCode _ $DBError; exp _ RopeForDBError[code]; GOTO Quit }; DB.Failure => { eCode _ $DBFailure; exp _ info; GOTO Quit}; DB.Aborted => { eCode _ $TransactionAbort; GOTO Quit }; END; proc[]; EXITS Quit => { WalnutRoot.StatsReport[IO.PutFR["\n ***DB error - code: %g, exp: %g ", IO.atom[eCode], IO.rope[exp]]]; ERROR WalnutDefs.Error[$db, eCode, exp]; }; END; }; GetMsgDisplayInfo: PUBLIC PROC[m: Entity] RETURNS[hasBeenRead: BOOL, tocEntry: ROPE, startOfSubject: INT] = { rel: Relship = DB.LookupProperty[mDisplayInfo, m]; hasBeenRead_ DB.V2B[DB.GetF[rel, mDIHasBeenRead]]; tocEntry_ DB.V2S[DB.GetF[rel, mDITOCEntry]]; startOfSubject_ DB.V2I[DB.GetF[rel, mDIStartOfSubject]]; }; ChangeCountInMsgSet: PUBLIC PROC[ms: Entity, inc: INT] = { rel: Relship = DB.LookupProperty[msBasicInfo, ms]; new: INT _ DB.V2I[DB.GetF[rel, msBICount]] + inc; IF new < 0 THEN new _ 0; -- empty didn't used to change the count! DB.SetF[rel, msBICount, DB.I2V[new]]; new _ DB.V2I[DB.GetF[rel, msBIVersion]] + 1; DB.SetF[rel, msBIVersion, DB.I2V[new]]; }; ChangeCountOfMsgs: PUBLIC PROC[delta: INT] = { rVersionInfo: Relship = DB.FirstRelship[gVersionInfo]; numNow: INT = DB.V2I[DB.GetF[rVersionInfo, gMsgCount]]; DB.SetF[rVersionInfo, gMsgCount, DB.I2V[numNow + delta]]; }; RopeForDBError: PROC[code: DB.ErrorCode] RETURNS[ROPE] = { SELECT code FROM AlreadyExists => RETURN["AlreadyExists"]; IllegalAttribute => RETURN["IllegalAttribute"]; IllegalDomain => RETURN["IllegalDomain"]; IllegalEntity => RETURN["IllegalEntity"]; IllegalProperty => RETURN["IllegalRelship"]; IllegalRelation => RETURN["IllegalRelation"]; IllegalString => RETURN["IllegalString"]; MismatchedExistingRelation => RETURN["MismatchedExistingRelation"]; MismatchedExistingSegment => RETURN["MismatchedExistingSegment"]; MultipleMatch => RETURN["MultipleMatch"]; NILArgument => RETURN["NILArgument"]; NullifiedArgument => RETURN["NullifiedArgument"]; NotFound => RETURN["NotFound"]; TransactionNotOpen => RETURN["TransactionNotOpen"]; TransactionAlreadyOpen => RETURN["TransactionAlreadyOpen"]; QuotaExceeded => RETURN["QuotaExceeded"]; Unknown => RETURN["Unknown"]; ENDCASE => RETURN["Other Error"]; }; GetExpungeInfo: PUBLIC PROC RETURNS[ firstDestroyedMsgPos, bytesInDestroyedMsgs: INT] = { Gei: PROC = { rLogInfo: Relship = DB.FirstRelship[gLogInfo]; firstDestroyedMsgPos _ DB.V2I[DB.GetF[rLogInfo, gFirstDestroyedMsgPos]]; bytesInDestroyedMsgs _ DB.V2I[DB.GetF[rLogInfo, gBytesInDestroyedMsgs]] }; WalnutDB.CarefullyApply[Gei]; }; SetExpungeInfo: PUBLIC PROC[firstDestroyedMsgPos, bytesInDestroyedMsgs: INT] = { Sei: PROC = { rLogInfo: Relship = DB.FirstRelship[gLogInfo]; DB.SetF[rLogInfo, gFirstDestroyedMsgPos, DB.I2V[firstDestroyedMsgPos]]; DB.SetF[rLogInfo, gBytesInDestroyedMsgs, DB.I2V[bytesInDestroyedMsgs]]; }; WalnutDB.CarefullyApply[Sei]; }; GetLogExpungePhase: PUBLIC PROC RETURNS[exp: WalnutKernelDefs.LogExpungePhase] = { Gep: PROC = { rExpungeInfo: Relship = DB.FirstRelship[gExpungeInfo]; ph: INT _ DB.V2I[DB.GetF[rExpungeInfo, gLogExpungePhase]]; SELECT ph FROM 0 => exp_ idle; 1 => exp_ initializingExpungeLog; 2 => exp_ writingExpungeLog; 3 => exp_ swappingLogs; ENDCASE => { SIGNAL WalnutDefs.Error[$db, $Bug, IO.PutFR[badExpVal, IO.int[ph]] ]; exp_ idle }; }; WalnutDB.CarefullyApply[Gep]; }; badExpVal: ROPE = "Bad expungePhase value (%g)"; SetLogExpungePhase: PUBLIC PROC[exp: WalnutKernelDefs.LogExpungePhase] = { Sep: PROC = { rExpungeInfo: Relship = DB.FirstRelship[gExpungeInfo]; val: INT; SELECT exp FROM idle => val _ 0; initializingExpungeLog => val _ 1; writingExpungeLog => val _ 2; swappingLogs => val _ 3; ENDCASE => { ph: INTEGER _ LOOPHOLE[exp]; SIGNAL WalnutDefs.Error[$db, $Bug,IO.PutFR[badExpVal, IO.int[val]] ]; val _ 0; }; DB.SetF[rExpungeInfo, gLogExpungePhase, DB.I2V[val]]; }; WalnutDB.CarefullyApply[Sep]; }; GetExpungeProgressInfo: PUBLIC PROC RETURNS[currentLogPos, expungeLogPos: INT] = { Gepi: PROC = { rExpungeInfo: Relship = DB.FirstRelship[gExpungeInfo]; currentLogPos _ DB.V2I[DB.GetF[rExpungeInfo, gCurrentLogPos]]; expungeLogPos _ DB.V2I[DB.GetF[rExpungeInfo, gExpungeLogPos]]; }; WalnutDB.CarefullyApply[Gepi]; }; SetExpungeProgressInfo: PUBLIC PROC[currentLogPos, expungeLogPos: INT] = { Sepi: PROC = { rExpungeInfo: Relship = DB.FirstRelship[gExpungeInfo]; DB.SetF[rExpungeInfo, gCurrentLogPos, DB.I2V[currentLogPos]]; DB.SetF[rExpungeInfo, gExpungeLogPos, DB.I2V[expungeLogPos]]; }; WalnutDB.CarefullyApply[Sepi]; }; GetExpungeFileID: PUBLIC PROC RETURNS[expungeFileID: INT] = { Gefi: PROC = { rExpungeInfo: Relship = DB.FirstRelship[gExpungeInfo]; expungeFileID _ DB.V2I[DB.GetF[rExpungeInfo, gExpungeFileID]] }; WalnutDB.CarefullyApply[Gefi]; }; SetExpungeFileID: PUBLIC PROC[expungeFileID: INT] = { Sefi: PROC = { rExpungeInfo: Relship = DB.FirstRelship[gExpungeInfo]; DB.SetF[rExpungeInfo, gExpungeFileID, DB.I2V[expungeFileID]] }; WalnutDB.CarefullyApply[Sefi]; }; GetTimeOfLastExpunge: PUBLIC PROC RETURNS[when: GMT] = { Gtle: PROC = { rExpungeInfo: Relship = DB.FirstRelship[gExpungeInfo]; when _ DB.V2T[DB.GetF[rExpungeInfo, gTimeOfLastExpunge]] }; WalnutDB.CarefullyApply[Gtle]; }; SetTimeOfLastExpunge: PUBLIC PROC[when: GMT] = { Stle: PROC = { rExpungeInfo: Relship = DB.FirstRelship[gExpungeInfo]; DB.SetF[rExpungeInfo, gTimeOfLastExpunge, DB.T2V[when]] }; WalnutDB.CarefullyApply[Stle]; }; GetTimeOfLastScavenge: PUBLIC PROC RETURNS[when: GMT] = { Gtls: PROC = { rLogInfo: Relship = DB.FirstRelship[gLogInfo]; when _ DB.V2T[DB.GetF[rLogInfo, gTimeOfLastScavenge]] }; WalnutDB.CarefullyApply[Gtls]; }; SetTimeOfLastScavenge: PUBLIC PROC[when: GMT] = { Stls: PROC = { rLogInfo: Relship = DB.FirstRelship[gLogInfo]; DB.SetF[rLogInfo, gTimeOfLastScavenge, DB.T2V[when]] }; WalnutDB.CarefullyApply[Stls]; }; SetAcceptNewMailPos: PUBLIC PROC[pos: INT] = { Sanmp: PROC = { rNewMailInfo: Relship = DB.FirstRelship[gNewMailInfo]; DB.SetF[rNewMailInfo, gAcceptNewMailLogPos, DB.I2V[pos]] }; WalnutDB.CarefullyApply[Sanmp]; }; GetAcceptNewMailPos: PUBLIC PROC RETURNS[pos: INT] = { Ganmp: PROC = { rNewMailInfo: Relship = DB.FirstRelship[gNewMailInfo]; pos _ DB.V2I[DB.GetF[rNewMailInfo, gAcceptNewMailLogPos]] }; WalnutDB.CarefullyApply[Ganmp]; }; SetAddingServerMsgs: PUBLIC PROC[addingServerMsgs: BOOL] = { Sasm: PROC = { rNewMailInfo: Relship = DB.FirstRelship[gNewMailInfo]; DB.SetF[rNewMailInfo, gAddingServerMsgs, DB.B2V[addingServerMsgs]] }; WalnutDB.CarefullyApply[Sasm]; }; GetAddingServerMsgs: PUBLIC PROC RETURNS[addingServerMsgs: BOOL] = { Sasm: PROC = { rNewMailInfo: Relship = DB.FirstRelship[gNewMailInfo]; addingServerMsgs_ DB.V2B[DB.GetF[rNewMailInfo, gAddingServerMsgs]] }; WalnutDB.CarefullyApply[Sasm]; }; EnumerateServers: PUBLIC PROC RETURNS[serverList: LIST OF ServerInfo] = { Gsi: PROC = { enum: EntitySet _ DB.DomainSubset[ServerDomain, NIL, NIL, First]; se: Entity; FOR se _ DB.NextEntity[enum], DB.NextEntity[enum] UNTIL se = NIL DO rel: Relship = DB.LookupProperty[sBasicInfo, se]; si: ServerInfo; si.server _ DB.EntityInfo[se].name; si.num _ DB.V2I[DB.GetF[rel, sBINum]]; serverList _ CONS[si, serverList]; ENDLOOP; DB.ReleaseEntitySet[enum]; }; WalnutDB.CarefullyApply[Gsi]; }; GetServerInfo: PUBLIC PROC[server: ROPE] RETURNS[num: INT] = { Gsr: PROC = { se: Entity = DB.LookupEntity[ServerDomain, server]; IF se # NIL THEN { rel: Relship = DB.LookupProperty[sBasicInfo, se]; num _ DB.V2I[DB.GetF[rel, sBINum]] } ELSE num _ 0; }; WalnutDB.CarefullyApply[Gsr]; }; SetNewMailInfo: PUBLIC PROC[logLen: INT, when: GMT, server: ROPE, num: INT] = { Snmi: PROC = { rNewMailInfo: Relship = DB.FirstRelship[gNewMailInfo]; IF server # NIL THEN { se: Entity _ DB.LookupEntity[ServerDomain, server]; IF se = NIL THEN { -- create this entity init: DB.ValueSequence = DB.L2VS[LIST[ DB.E2V[DB.DeclareEntity[ServerDomain, server]], DB.I2V[num] ] ]; [] _ DB.CreateRelship[sBasicInfo, init]; } ELSE { rel: Relship = DB.LookupProperty[sBasicInfo, se]; DB.SetF[rel, sBINum, DB.I2V[num]]; }; }; DB.SetF[rNewMailInfo, gNewMailLogLength, DB.I2V[logLen]]; DB.SetF[rNewMailInfo, gLastNewMailTimeStamp, DB.T2V[when]] }; WalnutDB.CarefullyApply[Snmi]; }; SetNewMailLogLength: PUBLIC PROC[logLen: INT] = { Gnml: PROC = { rNewMailInfo: Relship = DB.FirstRelship[gNewMailInfo]; DB.SetF[rNewMailInfo, gNewMailLogLength, DB.I2V[logLen]]; }; WalnutDB.CarefullyApply[Gnml]; }; GetNewMailLogLength: PUBLIC PROC RETURNS[logLen: INT] = { Gnml: PROC = { rNewMailInfo: Relship = DB.FirstRelship[gNewMailInfo]; logLen _ DB.V2I[DB.GetF[rNewMailInfo, gNewMailLogLength]] }; WalnutDB.CarefullyApply[Gnml]; }; GetLastNewMailTimeStamp: PUBLIC PROC RETURNS[when: GMT] = { Glnmts: PROC = { rNewMailInfo: Relship = DB.FirstRelship[gNewMailInfo]; when _ DB.V2T[DB.GetF[rNewMailInfo, gLastNewMailTimeStamp]] }; WalnutDB.CarefullyApply[Glnmts]; }; SetCopyMailLogPos: PUBLIC PROC[pos: INT] = { Scml: PROC = { rNewMailInfo: Relship = DB.FirstRelship[gNewMailInfo]; DB.SetF[rNewMailInfo, gCopyNewMailLogPos, DB.I2V[pos]] }; WalnutDB.CarefullyApply[Scml]; }; GetCopyMailLogPos: PUBLIC PROC RETURNS[pos: INT] = { Gcml: PROC = { rNewMailInfo: Relship = DB.FirstRelship[gNewMailInfo]; pos _ DB.V2I[DB.GetF[rNewMailInfo, gCopyNewMailLogPos]] }; WalnutDB.CarefullyApply[Gcml]; }; SetReadArchivePos: PUBLIC PROC[pos: INT] = { Srap: PROC = { rReadArchiveInfo: Relship = DB.FirstRelship[gReadArchiveInfo]; DB.SetF[rReadArchiveInfo, gReadArchiveLogPos, DB.I2V[pos]] }; WalnutDB.CarefullyApply[Srap]; }; GetReadArchivePos: PUBLIC PROC RETURNS[pos: INT] = { Grap: PROC = { rReadArchiveInfo: Relship = DB.FirstRelship[gReadArchiveInfo]; pos _ DB.V2I[DB.GetF[rReadArchiveInfo, gReadArchiveLogPos]] }; WalnutDB.CarefullyApply[Grap]; }; SetCopyReadArchivePos: PUBLIC PROC[pos: INT] = { Scra: PROC = { rReadArchiveInfo: Relship = DB.FirstRelship[gReadArchiveInfo]; DB.SetF[rReadArchiveInfo, gCopyReadArchiveLogPos, DB.I2V[pos]] }; WalnutDB.CarefullyApply[Scra]; }; GetCopyReadArchivePos: PUBLIC PROC RETURNS[pos: INT] = { Gcra: PROC = { rReadArchiveInfo: Relship = DB.FirstRelship[gReadArchiveInfo]; pos _ DB.V2I[DB.GetF[rReadArchiveInfo, gCopyReadArchiveLogPos]] }; WalnutDB.CarefullyApply[Gcra]; }; END. ΈWalnutDBOpsImpl.mesa Copyright c 1985, 1986 by Xerox Corporation. All rights reserved. Willie-Sue, September 9, 1986 4:25:26 pm PDT Donahue, May 22, 1986 1:17:05 pm PDT Contents: types and procedures dealing with the Walnut message database Initiated by Willie-Sue, September 24, 1984 Types Public Variables Database initialization Global Values Internal procedures Operations used during Expunge, NewMail and reading Archive files Κα˜šΟn™Jšœ Οmœ7™BJ™,Icode™$J™—JšœG™GJšœ+™+J˜šΟk ˜ JšœŸœ ˜Jšœ ŸœŸœ˜šŸœŸœ1˜9Jšœ[˜[JšœM˜MJšœ2˜2Jšœ+˜+—JšŸœ˜JšœŸœ˜Jšœ˜Jšœ ˜ Jšœ Ÿœ&˜6JšœŸœ˜)Jšœ Ÿœ"˜2Jšœ ˜ J˜—šœŸœŸ˜šŸ˜JšœŸœŸœ˜ Jšœ.˜.—J˜JšŸœ ˜J˜—JšŸœŸœ˜head1šΟb™JšŸœŸœ Ÿœ˜JšŸœŸœŸœ˜JšœŸœ˜!J˜JšœŸœŸœ˜Jšœ ŸœŸœ ˜Jšœ ŸœŸœ ˜Jšœ Ÿœ˜)—™JšœŸœŸœ ˜%JšœŸœ˜-JšœŸœ˜/J˜JšœŸœ˜ JšœŸœ˜!JšœŸœ˜ JšœŸœŸœ˜&J˜Jšœ ŸœŸœ˜Jš œŸœŸœ˜—š ™š œŸœŸœ-Ÿœ˜LšŸœŸœŸœŸ˜4Jšœ"˜"šŸœ˜Jšœ˜JšœŸœ˜J˜——J˜—J˜š  œŸœŸœ-ŸœŸœ˜UJšœŸœ˜Jšœ Ÿœ˜JšœŸœ-˜9JšœŸœ˜%J˜Jšœ˜JšœŸœ˜šŸœŸœ˜Jšœ-˜-J˜J˜—Jšœ!˜!JšœŸœ&Ÿœ˜;J˜šŸ˜JšœŸœ.˜:Jšœ Ÿœ%˜3JšœŸœ˜$JšœŸœ4˜:JšœŸœ˜%JšŸœ˜—JšœŸœ Ÿœ*˜MšŸœ Ÿœ˜šœŸœŸœ˜JšŸœ˜Jšœ ˜ Jšœ ˜ Jšœ˜Jšœ˜—JšœŸœ"˜)šœŸœŸœ˜JšŸœ˜Jšœ ˜ Jšœ ˜ Jšœ˜Jšœ˜—JšœŸœ"˜)J˜—Jšœ˜——™ š œŸ œŸœ Ÿœ˜1Jšœ Ÿœ*˜8—J˜š œŸ œŸœ Ÿœ˜0Jšœ Ÿœ*˜8—J˜š  œŸ œŸœŸœŸœ˜TšœŸœ˜ JšœŸœ˜0JšœŸœŸœ"˜;Jšœ ŸœŸœ ˜7Jšœ ŸœŸœ˜/Jšœ˜—Jšœ˜J˜—J˜š  œŸœŸœŸœŸœ˜LšœŸœ˜ JšœŸœ˜0JšŸœ!Ÿœ˜:JšŸœŸœ˜6JšŸœŸœ˜.Jšœ˜—Jšœ˜J˜—J˜šœŸ œŸœŸœ˜?šœŸœ˜ JšœŸœ˜0JšœŸœŸœ"˜;Jšœ˜—Jšœ˜J˜—J˜šœŸ œŸœ˜7šœŸœ˜ JšœŸœ˜0JšŸœ!Ÿœ˜:Jšœ˜—Jšœ˜J˜—J˜šœŸ œŸœŸœ˜?šœŸœ˜JšœŸœ˜.JšœŸœŸœ"˜:Jšœ˜—Jšœ˜J˜—J˜šœŸ œŸœ˜7šœŸœ˜JšœŸœ˜.JšŸœ"Ÿœ˜;Jšœ˜—Jšœ˜Jšœ˜—J˜šœŸ œŸœ Ÿœ˜@šœŸœ˜JšœŸœ˜8Jšœ ŸœŸœ*˜?Jšœ˜—Jšœ˜J˜—J˜šœŸ œ Ÿœ˜8šœŸœ˜JšœŸœ˜8JšŸœ*Ÿœ˜@Jšœ˜—Jšœ˜J˜—J˜šœŸ œŸœŸœ˜1šœŸœ˜JšœŸœ˜8JšœŸœŸœ#˜2Jšœ˜—Jšœ˜J˜—J˜šœŸ œŸœ˜)šœŸœ˜JšœŸœ˜8JšŸœ#Ÿœ ˜2Jšœ˜—Jšœ˜J˜—J˜šœŸ œŸœ˜.JšœŸœ˜ JšœŸœ˜ šŸœŸœŸ˜šŸœ ˜ JšŸœ ŸœŸœ ˜%Jšœ˜Jšœ˜JšŸœ˜ Jšœ˜—JšŸœ.Ÿœ˜;JšŸœ)Ÿœ˜7JšŸœ˜—J˜Jšœ˜šŸ˜šœ ˜ šœŸœ-˜FJšŸœŸœ ˜—JšŸœ#˜(J˜——JšŸœ˜Jšœ˜—J˜š œŸ œ ŸœŸœ ŸœŸœ˜mJšœŸœ!˜2Jšœ ŸœŸœ˜2Jšœ ŸœŸœ˜,JšœŸœŸœ˜8J˜—J˜šœŸ œŸœ˜:JšœŸœ!˜2J˜JšœŸœŸœŸœ˜1JšŸœ Ÿœ Οc)˜CJšŸœŸœ ˜%J˜JšœŸœŸœ˜,JšŸœŸœ ˜'J˜—J˜šœŸ œŸœ˜.JšœŸœ˜6JšœŸœŸœŸœ ˜7JšŸœŸœ˜9J˜——š ™š œŸœŸœ ŸœŸœ˜:šŸœ ˜JšœŸœ˜)JšœŸœ˜/JšœŸœ˜)JšœŸœ˜)JšœŸœ˜,JšœŸœ˜-JšœŸœ˜)JšœŸœ˜CJšœŸœ˜AJšœŸœ˜)JšœŸœ˜%JšœŸœ˜1Jšœ Ÿœ ˜JšœŸœ˜3JšœŸœ˜;JšœŸœ˜)Jšœ Ÿœ ˜JšŸœŸœ˜!—Jšœ˜——J˜™AšœŸ œŸœ.Ÿœ˜YšœŸœ˜ JšœŸœ˜.JšœŸœŸœ(˜HJšœŸœŸœ'˜GJšœ˜—Jšœ˜J˜—J˜šœŸ œ-Ÿœ˜PšœŸœ˜ JšœŸœ˜.JšŸœ'Ÿœ˜GJšŸœ'Ÿœ˜GJšœ˜—Jšœ˜J˜—J˜šœŸ œŸœ+˜RšœŸœ˜ JšœŸœ˜6JšœŸœŸœŸœ'˜:šŸœŸ˜Jšœ˜Jšœ!˜!Jšœ˜Jšœ˜šŸœ˜ JšŸœŸœŸœ ˜EJšœ ˜ Jšœ˜——Jšœ˜—Jšœ˜J˜—J˜Jšœ Ÿœ!˜0J˜šœŸ œ+˜JšœŸœ˜ JšœŸœ˜6JšœŸœ˜ šŸœŸ˜J˜Jšœ"˜"Jšœ˜Jšœ˜šŸœ˜ JšœŸœŸœ˜JšŸœŸœŸœ ˜EJšœ˜Jšœ˜——JšŸœ&Ÿœ ˜5J˜—Jšœ˜J˜—J˜š œŸœŸœŸœŸœ˜RšœŸœ˜JšœŸœ˜6JšœŸœŸœ%˜>JšœŸœŸœ%˜>J˜—Jšœ˜J˜—J˜šœŸœŸœŸœ˜JšœŸœ˜JšœŸœ˜6JšŸœ$Ÿœ˜=JšŸœ$Ÿœ˜=J˜—Jšœ˜J˜—J˜š œŸœŸœŸœŸœ˜=šœŸœ˜JšœŸœ˜6JšœŸœŸœ$˜=Jšœ˜—Jšœ˜J˜—J˜šœŸœŸœŸœ˜5šœŸœ˜JšœŸœ˜6JšŸœ$Ÿœ˜šœŸœ˜ Jšœ Ÿœ$˜3šŸœŸœŸœ˜JšœŸœ ˜1JšœŸœŸœ˜"J˜JšŸœ ˜ —J˜—Jšœ˜J˜—J˜šœŸœŸœ ŸœŸœ ŸœŸœ˜OšœŸœ˜JšœŸœ˜6šŸœ ŸœŸœ˜Jšœ Ÿœ$˜3šŸœŸœŸœ‘˜)šœŸœŸœŸœ˜&JšŸœŸœ&˜/JšŸœ ˜ J˜—JšœŸœ!˜)J˜šŸœ˜JšœŸœ ˜1JšŸœŸœ ˜"J˜——J˜—J˜JšŸœ'Ÿœ˜9JšŸœ+Ÿœ ˜:Jšœ˜—Jšœ˜J˜—J˜šœŸœŸœ Ÿœ˜1šœŸœ˜JšœŸœ˜6JšŸœ'Ÿœ˜9J˜—Jšœ˜J˜—J˜š œŸœŸœŸœ Ÿœ˜9šœŸœ˜JšœŸœ˜6Jšœ ŸœŸœ'˜9Jšœ˜—Jšœ˜J˜—J˜š œŸœŸœŸœŸœ˜;šœŸœ˜JšœŸœ˜6JšœŸœŸœ+˜;Jšœ˜—Jšœ ˜ J˜—J˜šœŸœŸœŸœ˜,šœŸœ˜JšœŸœ˜6JšŸœ(Ÿœ ˜6Jšœ˜—Jšœ˜J˜—J˜š œŸœŸœŸœŸœ˜4šœŸœ˜JšœŸœ˜6JšœŸœŸœ(˜7Jšœ˜—Jšœ˜J˜—J˜šœŸœŸœŸœ˜,šœŸœ˜JšœŸœ ˜>JšŸœ,Ÿœ ˜:Jšœ˜—Jšœ˜J˜—J˜š œŸœŸœŸœŸœ˜4šœŸœ˜JšœŸœ ˜>JšœŸœŸœ,˜;Jšœ˜—Jšœ˜Jšœ˜—J˜šœŸœŸœŸœ˜0šœŸœ˜JšœŸœ ˜>JšŸœ<˜>Jšœ˜—Jšœ˜J˜—J˜š œŸœŸœŸœŸœ˜8šœŸœ˜JšœŸœ ˜>JšœŸœŸœ0˜?Jšœ˜—Jšœ˜J˜——J˜JšŸœ˜J˜—…—