DIRECTORY Camelot, IO USING [int, PutFR, PutFR1], Mach, Rope USING [Cat, Fetch, Length, ROPE]; CamelotImpl: CEDAR PROGRAM IMPORTS IO, Mach, Rope EXPORTS Camelot ~ BEGIN OPEN Camelot, Mach; DSInitialize: PUBLIC PROC [dsPort: portT, raiseSignal: BOOL] RETURNS [serverID: serverIdT, tsPort, mPort, sPort: portT, sharedMemAddr: vmAddressT, seqDescList: ListOfSegmentDesc _ NIL, seqPortList: ListOfPorts, kernCode: Mach.kernReturnT _ -1] ~ TRUSTED { innerDSInitialize: PROC [idsPort: portT, iserverID: POINTER TO serverIdT, itsPort, imPort, isPort: POINTER TO portT, isharedMemAddr: POINTER TO vmAddressT, iseqDescList: POINTER TO segmentDescListT, isegDescListCnt: POINTER TO INT, iseqPortList: POINTER TO portArrayT, isegPortListCnt: POINTER TO INT] RETURNS [kernReturnT]~ TRUSTED MACHINE CODE { ".DS_Initialize" }; ZsegDescList, DsegDescList: segmentDescListT _ NIL; ZsegDescListCnt: INT _ -1; ZsegPortList, DsegPortList: portArrayT _ NIL; ZsegPortListCnt: INT _ -1; initCode: INT _ SendErrorsStart; initCode _ innerDSInitialize[dsPort, @serverID, @tsPort, @mPort, @sPort, @sharedMemAddr, @ZsegDescList, @ZsegDescListCnt, @ZsegPortList, @ZsegPortListCnt]; IF raiseSignal AND initCode # KernSuccess THEN SIGNAL MachCall[initCode, Rope.Cat["DS_Initialize failed; code = ", IO.PutFR1["%g", IO.int[initCode]]]]; IF ZsegDescListCnt # ZsegPortListCnt AND raiseSignal THEN SIGNAL MachCall[-1, IO.PutFR["DS_Initialize failed; different number of segments and ports = %g segments and %g ports", IO.int[ZsegDescListCnt], IO.int[ZsegPortListCnt]]]; IF ZsegDescListCnt > 0 THEN TRUSTED { newItem: PROC RETURNS [lsd: ListOfSegmentDesc] ~ TRUSTED { lsd _ LIST[[ZsegDescList.serverId, ZsegDescList.segmentId, ZsegDescList.logicalDisk, ZsegDescList.unused, ZsegDescList.highSize, ZsegDescList.lowSize]]; ZsegDescList _ ZsegDescList + UNITS[segmentDescT]; }; DsegDescList _ ZsegDescList; seqDescList _ newItem[]; IF ZsegDescListCnt > 1 THEN { lastItem: ListOfSegmentDesc _ seqDescList; FOR item: INT IN [1..ZsegDescListCnt) DO lastItem.rest _ newItem[]; lastItem _ lastItem.rest; ENDLOOP; }; [] _ vmDeallocate[targetTask: taskSelf[], address: LOOPHOLE[DsegDescList], size: BYTES[segmentDescT]*ZsegDescListCnt, raiseSignal: TRUE]; }; IF ZsegPortListCnt > 0 THEN TRUSTED { newPort: PROC RETURNS [lp: ListOfPorts] ~ TRUSTED { lp _ LIST[[ZsegPortList.portNumber]]; ZsegPortList _ ZsegPortList + UNITS[portT]; }; DsegPortList _ ZsegPortList; seqPortList _ newPort[]; IF ZsegPortListCnt > 1 THEN { lastPort: ListOfPorts _ seqPortList; FOR item: INT IN [1..ZsegPortListCnt) DO lastPort.rest _ newPort[]; lastPort _ lastPort.rest; ENDLOOP; }; [] _ vmDeallocate[targetTask: taskSelf[], address: LOOPHOLE[DsegPortList], size: BYTES[portT]*ZsegPortListCnt, raiseSignal: TRUE]; }; }; DSPinObject: PUBLIC PROC [dsPort: portT, tid: tidT, optr: optrT, size: uInt, raiseSignal: BOOL] RETURNS [kernCode: Mach.kernReturnT _ -1] ~ { innerDSPinObject: PROC [idsPort: portT, itid: tidT, ioptr: optrT, isize: uInt] RETURNS [kernReturnT] ~ TRUSTED MACHINE CODE { ".DS_PinObject" }; pinCode: INT _ -1; pinCode _ innerDSPinObject[dsPort, tid, optr, size]; IF raiseSignal AND pinCode # KernSuccess THEN SIGNAL MachCall[pinCode, Rope.Cat["DS_PinObject failed; code = ", IO.PutFR1["%g", IO.int[pinCode]]]]; RETURN[pinCode]; }; DSLogNewValue: PUBLIC PROC [dsPort: portT, tid: tidT, optr: optrT, newValue: pointerT, newValueCnt: INT, raiseSignal: BOOL] RETURNS [kernCode: Mach.kernReturnT _ -1] ~ { innerDSLogNewValue: PROC [idsPort: portT, itid: tidT, ioptr: optrT, inewValue: pointerT, inewValueCnt: INT] RETURNS [kernReturnT] ~ TRUSTED MACHINE CODE { ".DS_LogNewValue" }; logCode: INT _ -1; logCode _ innerDSLogNewValue[dsPort, tid, optr, newValue, newValueCnt]; IF raiseSignal AND logCode # KernSuccess THEN SIGNAL MachCall[logCode, Rope.Cat["DS_LogNewValue failed; code = ", IO.PutFR1["%g", IO.int[logCode]]]]; RETURN[logCode]; }; DSLogOldValueNewValue: PUBLIC PROC [dsPort: portT, tid: tidT, optr: optrT, oldValue: pointerT, oldValueCnt: INT, newValue: pointerT, newValueCnt: INT, raiseSignal: BOOL] RETURNS [kernCode: Mach.kernReturnT _ -1] ~ { innerDSLogOldValueNewValue: PROC [idsPort: portT, itid: tidT, ioptr: optrT, ioldValue: pointerT, ioldValueCnt: INT, inewValue: pointerT, inewValueCnt: INT] RETURNS [kernReturnT] ~ TRUSTED MACHINE CODE { ".DS_LogOldValueNewValue" }; logCode: INT _ -1; logCode _ innerDSLogOldValueNewValue[dsPort, tid, optr, oldValue, oldValueCnt, newValue, newValueCnt]; IF raiseSignal AND logCode # KernSuccess THEN SIGNAL MachCall[logCode, Rope.Cat["DS_LogOldValueNewValue failed; code = ", IO.PutFR1["%g", IO.int[logCode]]]]; RETURN[logCode]; }; DSPrepare: PUBLIC PROC [dsPort: portT, topBTid: btidT, prepareData: pointerT, prepareDataCnt: INT, raiseSignal: BOOL] RETURNS [kernCode: Mach.kernReturnT _ -1] ~ { innerDSPrepare: PROC [idsPort: portT, itopBTid: btidT, iprepareData: pointerT, iprepareDataCnt: INT] RETURNS [kernReturnT] ~ TRUSTED MACHINE CODE { ".DS_Prepare" }; prepareCode: INT _ -1; prepareCode _ innerDSPrepare[dsPort, topBTid, prepareData, prepareDataCnt]; IF prepareCode # KernSuccess THEN SIGNAL MachCall[prepareCode, Rope.Cat["DS_Prepare failed; code = ", IO.PutFR1["%g", IO.int[prepareCode]]]]; RETURN[prepareCode]; }; DSQInit: PUBLIC PROC [sharedMemAddr: Mach.vmAddressT] ~ { innerDSQInit: PROC [XsharedMemAddr: Mach.vmAddressT] ~ TRUSTED MACHINE CODE { ".Dsq_Init" }; innerDSQInit[sharedMemAddr]; }; DSQPreflush: PUBLIC PROC [dsPort: Mach.portT, optr: optrT, sizeInBytes: uInt] ~ { ERROR; -- preflush should only be used in SunOS emulation for now }; camelotStringTFromRope: PROC [name: Rope.ROPE] RETURNS [camelotString: REF camelotStringT] ~ { oNSize: INT _ 0; camelotString _ NEW[camelotStringT]; oNSize _ Rope.Length[name]; IF oNSize >= Camelot.CAMELOTSTRINGLENGTH THEN ERROR; FOR index: INT IN [0..oNSize) DO camelotString[index] _ Rope.Fetch[name, index]; ENDLOOP; camelotString[oNSize] _ 0C; }; TAAddApplication: PUBLIC PROC [tPort: portT, atPort: portT, authName: Rope.ROPE, raiseSignal: BOOL] RETURNS [applicationID: applicationIdT, taPort: portT, kernCode: Mach.kernReturnT _ -1] ~ TRUSTED { innerTAAddApplication: PROC [itPort: portT, iatPort: portT, iauthName: POINTER TO camelotStringT, iapplicationID: POINTER TO applicationIdT, itaPort: POINTER TO portT] RETURNS [kernReturnT] ~ TRUSTED MACHINE CODE { ".TA_AddApplication" }; camString: REF camelotStringT; camString _ camelotStringTFromRope[authName]; kernCode _ innerTAAddApplication[tPort, atPort, LOOPHOLE[camString], @applicationID, @taPort]; IF raiseSignal AND kernCode # KernSuccess THEN SIGNAL MachCall[kernCode, Rope.Cat["TA_AddApplication failed; code = ", IO.PutFR1["%g", IO.int[kernCode]]]]; }; TABegin: PUBLIC PROC [taPort: portT, parentTid: tidT, transType: transactionTypeT, raiseSignal: BOOL] RETURNS [newTid: tidT, kernCode: Mach.kernReturnT _ -1] ~ TRUSTED { innerTABegin: PROC [taPortInner: portT, parentTidInner: tidT, transTypeInner: transactionTypeT, newTidInner: POINTER TO tidT] RETURNS [kernReturnT] ~ TRUSTED MACHINE CODE { ".TA_Begin" }; kernCode _ innerTABegin[taPort, parentTid, transType, @newTid]; IF raiseSignal AND kernCode # KernSuccess THEN SIGNAL MachCall[kernCode, Rope.Cat["TA_Begin failed; code = ", IO.PutFR1["%g", IO.int[kernCode]]]]; }; TAEnd: PUBLIC PROC [taPort: portT, tid: tidT, protocolType: protocolTypeT, raiseSignal: BOOL] RETURNS [timestamp: timestampT, status: INT, kernCode: Mach.kernReturnT _ -1] ~ TRUSTED { innerTAEnd: PROC [taPortInner: portT, tidInner: tidT, protocolTypeInner: protocolTypeT, timestampInner: POINTER TO timestampT, statusInner: POINTER TO INT] RETURNS [kernReturnT] ~ TRUSTED MACHINE CODE { ".TA_End" }; kernCode _ innerTAEnd[taPort, tid, protocolType, @timestamp, @status]; IF raiseSignal AND kernCode # KernSuccess THEN SIGNAL MachCall[kernCode, Rope.Cat["TA_End failed; code = ", IO.PutFR1["%g", IO.int[kernCode]]]]; }; TAKill: PUBLIC PROC [taPort: portT, tid: tidT, status: INT, raiseSignal: BOOL] RETURNS [kernCode: Mach.kernReturnT _ -1] ~ TRUSTED { innerTAKill: PROC [taPortInner: portT, tidInner: tidT, statusInner: INT] RETURNS [kernReturnT] ~ TRUSTED MACHINE CODE { ".TA_Kill" }; kernCode _ innerTAKill[taPort, tid, status]; IF raiseSignal AND kernCode # KernSuccess THEN SIGNAL MachCall[kernCode, Rope.Cat["TA_Kill failed; code = ", IO.PutFR1["%g", IO.int[kernCode]]]]; }; TSJoin: PUBLIC PROC [tsPort: portT, tid: tidT, raiseSignal: BOOL] RETURNS [kernCode: Mach.kernReturnT _ -1] ~ { innerTSJoin: PROC [tsPortInner: portT, tidInner: tidT] RETURNS [kernReturnT] ~ TRUSTED MACHINE CODE { ".TS_Join" }; kernCode _ innerTSJoin[tsPort, tid]; IF raiseSignal AND kernCode # KernSuccess THEN SIGNAL MachCall[kernCode, Rope.Cat["TA_Join failed; code = ", IO.PutFR1["%g", IO.int[kernCode]]]]; }; TDAddDataServer: PUBLIC PROC [tdPort: portT, serverID: serverIdT, sendPort: portT, raiseSignal: BOOL] RETURNS [rcvPort: portT, kernCode: Mach.kernReturnT _ -1] ~ TRUSTED { innerTDAddDataServer: PROC [itdPort: portT, iserverID: serverIdT, isendPort: portT, ircvPort: POINTER TO portT] RETURNS [kernReturnT]~ TRUSTED MACHINE CODE { ".TD_AddDataServer" }; kernCode _ innerTDAddDataServer[tdPort, serverID, sendPort, @rcvPort]; IF raiseSignal AND kernCode # KernSuccess THEN SIGNAL MachCall[kernCode, Rope.Cat["TD_AddDataServer failed; code = ", IO.PutFR1["%g", IO.int[kernCode]]]]; }; objectNameTFromRope: PROC [name: Rope.ROPE] RETURNS [objectNameString: REF objectNameT] ~ { oNSize: INT _ 0; objectNameString _ NEW[objectNameT]; oNSize _ Rope.Length[name]; IF oNSize >= ObjectNameLength THEN ERROR; FOR index: INT IN [0..oNSize) DO objectNameString[index] _ Rope.Fetch[name, index]; ENDLOOP; objectNameString[oNSize] _ 0C; }; CSSignIn: PUBLIC PROC [nameServerPort: Mach.portT, name: Rope.ROPE, port: Mach.portT, raiseSignal: BOOL] RETURNS [kernCode: Mach.kernReturnT] ~ { innerCSSignIn: PROC [inameServerPort: Mach.portT, iname: POINTER TO objectNameT, iport: Mach.portT] RETURNS [kernReturnT] ~ TRUSTED MACHINE CODE { ".CS_SignIn" }; objectNameString: REF objectNameT; objectNameString _ objectNameTFromRope[name]; kernCode _ innerCSSignIn[nameServerPort, LOOPHOLE[objectNameString], port]; IF raiseSignal AND kernCode # KernSuccess THEN SIGNAL MachCall[kernCode, Rope.Cat["CS_SignIn failed; code = ", IO.PutFR1["%g", IO.int[kernCode]]]]; }; CSSignOut: PUBLIC PROC [nameServerPort: Mach.portT, name: Rope.ROPE, port: Mach.portT, raiseSignal: BOOL] RETURNS [kernCode: Mach.kernReturnT] ~ { innerCSSignOut: PROC [inameServerPort: Mach.portT, iname: POINTER TO objectNameT, iport: Mach.portT] RETURNS [kernReturnT] ~ TRUSTED MACHINE CODE { ".CS_SignOut" }; objectNameString: REF objectNameT; objectNameString _ objectNameTFromRope[name]; kernCode _ innerCSSignOut[nameServerPort, LOOPHOLE[objectNameString], port]; IF raiseSignal AND kernCode # KernSuccess THEN SIGNAL MachCall[kernCode, Rope.Cat["CS_SignOut failed; code = ", IO.PutFR1["%g", IO.int[kernCode]]]]; }; innerLookup: PROC [nameServerPort: Mach.portT, name: Rope.ROPE, site: Rope.ROPE, numberWanted: INT, maxSeconds: INT, raiseSignal: BOOL, cs: BOOL] RETURNS [portList: Mach.ListOfPorts, kernCode: Mach.kernReturnT] ~ { innerCSLookup: PROC [inameServerPort: Mach.portT, iname: POINTER TO objectNameT, isite: POINTER TO objectNameT, inumberWanted: INT, imaxSeconds: INT, iportList: POINTER TO portArrayT, iportListCnt: POINTER TO INT] RETURNS [kernReturnT] ~ TRUSTED MACHINE CODE { ".CS_Lookup" }; innerCALookup: PROC [inameServerPort: Mach.portT, iname: POINTER TO objectNameT, isite: POINTER TO objectNameT, inumberWanted: INT, imaxSeconds: INT, iportList: POINTER TO portArrayT, iportListCnt: POINTER TO INT] RETURNS [kernReturnT] ~ TRUSTED MACHINE CODE { ".CA_Lookup" }; objectNameString: REF objectNameT; siteString: REF objectNameT; ZportList, DportList: portArrayT _ NIL; ZportListCnt: INT _ -1; objectNameString _ objectNameTFromRope[name]; siteString _ objectNameTFromRope[site]; IF cs THEN TRUSTED { kernCode _ innerCSLookup[nameServerPort, LOOPHOLE[objectNameString], LOOPHOLE[siteString], numberWanted, maxSeconds, @ZportList, @ZportListCnt]; IF raiseSignal AND kernCode # KernSuccess THEN SIGNAL MachCall[kernCode, Rope.Cat["CS_Lookup failed; code = ", IO.PutFR1["%g", IO.int[kernCode]]]]; } ELSE TRUSTED { kernCode _ innerCALookup[nameServerPort, LOOPHOLE[objectNameString], LOOPHOLE[siteString], numberWanted, maxSeconds, @ZportList, @ZportListCnt]; IF raiseSignal AND kernCode # KernSuccess THEN SIGNAL MachCall[kernCode, Rope.Cat["CA_Lookup failed; code = ", IO.PutFR1["%g", IO.int[kernCode]]]]; }; IF ZportListCnt > 0 THEN TRUSTED { newPort: PROC RETURNS [lp: ListOfPorts] ~ TRUSTED { lp _ LIST[[ZportList.portNumber]]; ZportList _ ZportList + UNITS[portT]; }; DportList _ ZportList; portList _ newPort[]; IF ZportListCnt > 1 THEN { lastPort: ListOfPorts _ portList; FOR item: INT IN [1..ZportListCnt) DO lastPort.rest _ newPort[]; lastPort _ lastPort.rest; ENDLOOP; }; [] _ vmDeallocate[targetTask: taskSelf[], address: LOOPHOLE[DportList], size: BYTES[portT]*ZportListCnt, raiseSignal: TRUE]; }; }; CSLookup: PUBLIC PROC [nameServerPort: Mach.portT, name: Rope.ROPE, site: Rope.ROPE, numberWanted: INT, maxSeconds: INT, raiseSignal: BOOL] RETURNS [portList: Mach.ListOfPorts, kernCode: Mach.kernReturnT] ~ { [portList, kernCode] _ innerLookup[nameServerPort, name, site, numberWanted, maxSeconds, raiseSignal, TRUE]; }; CALookup: PUBLIC PROC [nameServerPort: Mach.portT, name: Rope.ROPE, site: Rope.ROPE, numberWanted: INT, maxSeconds: INT, raiseSignal: BOOL] RETURNS [portList: Mach.ListOfPorts, kernCode: Mach.kernReturnT] ~ { [portList, kernCode] _ innerLookup[nameServerPort, name, site, numberWanted, maxSeconds, raiseSignal, FALSE]; }; END. tCamelotImpl.mesa Copyright Ó 1988 by Xerox Corporation. All rights reserved. Bob Hagmann May 4, 1989 8:58:50 am PDT Handle calls to Camelot from Cedar. Parameters to Camelot from C have IN, OUT, and INOUT parameters, at least when used with MIG. They are processed to (sometimes) change the real calling sequence to the C code. To find out what the real calling sequence for XX_someRoutine is, look in XX.h somewhere in the ~camelot directory subtree (e.g., ~camelot/camelot/alpha/include/camlib/ts.h). I (rbh) think that the following is the algorithm to change parameters: IN - no change (pass by copy) OUT and INOUT - normally make it indirect, that is pass by address. However, for lists (I don't know how it guesses that something is a list) the argument is divided into two new arguments. The first one is passed by address and is of type of "pointer to the type of the argument". This is just the indirect passing of the argument. It has the same name as the argument. But then a pointer to an "unsigned int" (read CARD) is passed! This will get the number of items in the list. Its name is the argument's name with "Cnt" appended. To see this in action, open ~camelot/alpha/src/lib/camlib/ds.h ( the same contents seem to be in ~camelot/alpha/include/camlib/ds.h) and look at the DS_Initialize call (you'll have to modify this name after the alpha release). Compare with ~camelot/alpha/src/lib/camlib/ds.defs -- which matches the documentation. Exported recoverable storage management procedures Initialize the data server. Pin an object in preparation for modification. Send a new value of an object to the log. Send a new value of an object to the log. Send a new value of an object to the log. Send a new value of an object to the log. Preflush some dirty memory. Exported transaction management procedures Initialize an application to the transaction manager. Start a new transaction. Try to commit a transaction. Try to abort a transaction. Join a server to a transaction. Join a server to a transaction. Initialize the data server to the transaction manager. Name server Sign in as a data server. Sign out as a data server. Lookup for servers. Lookup for servers. Lookup for applications. Exported lock procedures (if we are going to use CamLib) Lock: PUBLIC PROC [tid: tidT, lockName: LockName, lockMode: lockModeT] ~ { Obtain the lock for this transaction. innerLOCK: PROC [lockNameInner: LockName, lockModeInner: lockModeT] ~ TRUSTED MACHINE CODE { "LOCK" }; MakeThisThreadPartOfTransaction[tid]; innerLOCK[lockName, lockMode]; }; TryLock: PUBLIC PROC [tid: tidT, lockName: LockName, lockMode: lockModeT] ~ { Obtain the lock for this transaction if immediately available. innerTryLock: PROC [lockNameInner: LockName, lockModeInner: lockModeT] ~ TRUSTED MACHINE CODE { "TRY_LOCK" }; MakeThisThreadPartOfTransaction[tid]; innerTryLock[lockName, lockMode]; }; Unlock: PUBLIC PROC [tid: tidT, lockName: LockName] ~ { Release lock for this transaction. innerUnlock: PROC [lockNameInner: LockName] ~ TRUSTED MACHINE CODE { "UNLOCK" }; MakeThisThreadPartOfTransaction[tid]; innerUnlock[lockName]; }; DemoteLock: PUBLIC PROC [tid: tidT, lockName: LockName] ~ { Demote write lock to a read lock for this transaction. innerDemoteLock: PROC [lockNameInner: LockName] ~ TRUSTED MACHINE CODE { "UNLOCK" }; MakeThisThreadPartOfTransaction[tid]; innerDemoteLock[lockName]; }; Initialization Ê/˜code•Mark outsideHeaderšœ™Kšœ<™žœžœ˜—Kš œ5žœžœžœbžœžœ˜åšžœžœžœ˜%šœ žœžœžœ˜:KšœžœŽ˜˜Kšœžœ˜2K˜—Kšœ˜Kšœ˜šžœžœ˜Kšœ*˜*šžœžœžœž˜(Kšœ˜Kšœ˜Kšžœ˜—K˜—Kšœ3žœžœ+žœ˜‰K˜—šžœžœžœ˜%šœ žœžœžœ˜3Kšœžœ˜%Kšœžœ˜+K˜—Kšœ˜Kšœ˜šžœžœ˜Kšœ$˜$šžœžœžœž˜(Kšœ˜Kšœ˜Kšžœ˜—K˜—Kšœ3žœžœ$žœ˜‚K˜—K˜K™—š   œžœžœBžœžœ&˜Kšœ.™.š œžœ9žœžœžœžœ˜}Kšœ˜K˜—Kšœ˜Kšœ4˜4Kš žœ žœžœžœ<žœžœ˜“Kšžœ ˜K˜K™—š   œžœžœJžœžœžœ&˜©Kšœ)™)š œžœOžœžœžœžœžœ˜šKšœ˜K˜—Kšœ˜KšœG˜GKš žœ žœžœžœ>žœžœ˜•Kšžœ ˜K˜K™—š  œžœžœ‚žœžœ&˜×Kšœ)™)š œžœ|žœžœžœžœ˜ÊKšœ˜K˜—Kšœ˜Kšœf˜fKš žœ žœžœžœFžœžœ˜Kšžœ ˜K˜K™—š   œžœžœHžœžœžœ&˜£Kšœ)™)š œžœLžœžœžœžœžœ˜“Kšœ˜K˜—Kšœ˜KšœK˜KKš žœžœžœ>žœžœ˜Kšžœ˜K˜K˜—š œžœžœ%˜9Kšœ)™)š œžœ%žœžœžœ˜MKšœ˜K˜—Kšœ˜K˜K™—š  œž œ9˜QKšœ™KšžœÏc:˜BK˜K™K™K™——šœ*™*š Ïbœžœ žœžœžœ˜^Kšœžœ˜Kšœžœ˜$Kšœ˜Kšžœžœžœžœ˜4šžœžœžœ ž˜ Kšœ/˜/Kšžœ˜—Kšœ˜K˜K™—š  œž œ.žœžœžœSžœ˜ÇKšœ5™5šœžœWžœžœžœžœžœžœžœžœ˜ÖKšœ˜K˜—Kšœ žœ˜Kšœ-˜-Kšœ^˜^Kš žœ žœžœžœBžœžœ˜›K˜K™—š  œžœžœLžœžœ3žœ˜©Kšœ™šœžœ[žœžœžœžœžœžœ˜¬Kšœ˜K˜—Kšœ?˜?Kš žœ žœžœžœ9žœžœ˜’K˜K™—š œžœžœFžœžœ!žœ%žœ˜·Kšœ™šœ žœXžœžœžœžœžœžœžœžœžœ˜ÊKšœ˜K˜—KšœF˜FKš žœ žœžœžœ7žœžœ˜K˜K™—š  œž œ$žœžœžœ%žœ˜„Kšœ™š œ žœ3žœžœžœžœžœ˜wKšœ˜K˜—Kšœ,˜,Kš žœ žœžœžœ8žœžœ˜‘K˜K™—š  œžœžœ)žœžœ&˜oK™š œ žœ&žœžœžœžœ˜eKšœ˜K˜—Kšœ$˜$Kš žœ žœžœžœ8žœžœ˜‘K˜K™—š  œž œDžœžœ5žœ˜«K™Kšœ6™6šœžœDžœžœžœžœžœžœ˜Kšœ˜K˜—KšœF˜FKš žœ žœžœžœAžœžœ˜šK˜——™ š ¢œžœ žœžœžœ˜[Kšœžœ˜Kšœžœ˜$Kšœ˜Kšžœžœžœ˜)šžœžœžœ ž˜ Kšœ2˜2Kšžœ˜—Kšœ˜K˜K™—K™š  œž œ)žœžœ žœžœ!˜‘Kšœ™š œžœQžœžœžœžœ˜’Kšœ˜K˜—Kšœžœ ˜"Kšœ-˜-Kšœ)žœ˜KKš žœ žœžœžœ:žœžœ˜“K˜K™—š   œž œ)žœ!žœžœ!˜’Kšœ™š œžœQžœžœžœžœ˜“Kšœ˜K˜—Kšœžœ ˜"Kšœ-˜-Kšœ*žœ˜LKš žœ žœžœžœ;žœžœ˜”K˜K™—š¢ œžœ)žœ žœžœžœžœžœžœ=˜ÖKšœ™š!œžœ&žœžœžœžœžœžœ žœžœžœžœžœžœžœžœžœ˜„Kšœ˜K˜—š!œžœ&žœžœžœžœžœžœ žœžœžœžœžœžœžœžœžœ˜„Kšœ˜K˜—Kšœžœ ˜"Kšœ žœ ˜Kšœ#žœ˜'Kšœžœ˜Kšœ-˜-Kšœ'˜'šžœžœžœ˜Kšœ)žœžœC˜Kš žœ žœžœžœ:žœžœ˜“Kšœ˜—šœžœžœ˜Kšœ)žœžœC˜Kš žœ žœžœžœ:žœžœ˜“Kšœ˜—šžœžœžœ˜"šœ žœžœžœ˜3Kšœžœ˜"Kšœžœ˜%K˜—Kšœ˜Kšœ˜šžœžœ˜Kšœ!˜!šžœžœžœž˜%Kšœ˜Kšœ˜Kšžœ˜—K˜—Kšœ3žœžœ#žœ˜|K˜—K˜K™—š œž œ)žœ žœžœžœžœžœ=˜ÐKšœ™Kšœfžœ˜lK˜K™—š œž œ)žœ žœžœžœžœžœ=˜ÐKšœ™Kšœfžœ˜mK˜—K™—šœ8™8š œžœžœ9™JKšœ%™%š œ žœ7žœžœžœ™\K™K™—Kšœ%™%Kšœ™K™K™K™—š œžœžœ9™MKšœ>™>š œžœ7žœžœžœ™_K™ K™—Kšœ%™%Kšœ!™!K™K™K™—š œžœžœ$™7Kšœ"™"š œ žœžœžœžœ™DK™K™—Kšœ%™%Kšœ™K™K™K™—š  œžœžœ$™;Kšœ6™6š œžœžœžœžœ™HK™K™—Kšœ%™%Kšœ™K™K™K™——™K˜—K˜Kšžœ˜—…—5ÖRy