DIRECTORY Ascii USING[Upper], Basics, BasicTime, ConvertUnsafe, DBCommon, DBStorage, DBStats, DBDefs, DB, DBModel, DBModelPrivate, DBModelSchema, Rope; DBModelPrivateImpl: CEDAR PROGRAM IMPORTS Ascii, Basics, BasicTime, ConvertUnsafe, Rope, DBStorage, DB, DBDefs, DBModel, DBModelPrivate, DBModelSchema EXPORTS DBModelPrivate = BEGIN OPEN DB, DBCommon, DBDefs, DBModel, DBModelPrivate; desperate: PUBLIC BOOL_ FALSE; MaxDataTypeID: LONG CARDINAL = 25; IsDomainType: PUBLIC PROC [vt: DataType] RETURNS [BOOL] = BEGIN SELECT vt FROM IntType, RopeType, BoolType, TimeType, RecordType => RETURN[FALSE]; ENDCASE => RETURN[TRUE] END; ConvertToUpper: PUBLIC PROC[s: ROPE] RETURNS [ROPE] = BEGIN pos: INT_ -1; upperProc: SAFE PROC RETURNS [CHAR] = CHECKED {RETURN[Ascii.Upper[s.Fetch[pos_ pos+1]]]}; RETURN[Rope.FromProc[s.Length[], upperProc]] END; NCode: PUBLIC PROC[v: Value] RETURNS[ROPE] = TRUSTED BEGIN WITH v: v SELECT FROM null => RETURN[NIL]; -- pass NILs right through for now rope => BEGIN CheckForNulls[v.value]; RETURN[ConvertToUpper[v.value]] END; integer => BEGIN i: LONG CARDINAL_ LOOPHOLE[v.value, LONG CARDINAL]+20000000000B; s: STRING_ [4]; s.length_ 4; s[0]_ HighByte[Basics.HighHalf[i]]; s[1]_ LowByte[Basics.HighHalf[i]]; s[2]_ HighByte[Basics.LowHalf[i]]; s[3]_ LowByte[Basics.LowHalf[i]]; RETURN[ConvertUnsafe.ToRope[s]] END; time => -- same as above but don't turn off top bit BEGIN i: LONG CARDINAL_ BasicTime.ToPupTime[v.value]; s: STRING_ [4]; s.length_ 4; s[0]_ HighByte[Basics.HighHalf[i]]; s[1]_ LowByte[Basics.HighHalf[i]]; s[2]_ HighByte[Basics.LowHalf[i]]; s[3]_ LowByte[Basics.LowHalf[i]]; RETURN[ConvertUnsafe.ToRope[s]] END; entity => { -- we index entity-valued attributes by the entity name IF NullEntity[v.value] THEN RETURN[NIL];-- pass NILs right through for now RETURN[ConvertToUpper[GetCachedEntityInfo[SegmentOf[v.value], v.value].name]] }; boolean => IF v.value THEN RETURN["TRUE"] ELSE RETURN["FALSE"]; ENDCASE => ERROR Error[NotImplemented]; -- for now END; CheckForNulls: PROC[s: ROPE] = INLINE BEGIN i: LONG CARDINAL _ 0; last: LONG CARDINAL _ Rope.Size[s]; WHILE (i _ i+1) < last DO IF Rope.Fetch[s,i]=0C OR Rope.Fetch[s,i]=377C THEN ERROR DB.Error[IllegalString] ENDLOOP; END; NCodeForTuple: PROC[t: Relship, i: Index] RETURNS [ROPE] = BEGIN s: ROPE_ ""; FOR ifs: LIST OF IndexFactor_ VL2TL[QGetPList[i, ifIndexOf]], ifs.rest UNTIL ifs=NIL DO if: IndexFactor_ ifs.first; s_ Rope.Cat[s, NCode[QGetF[t, DBModelSchema.TupleToAttribute[V2E[QGetP[if, ifAttributeIs]]]]], "\000"]; ENDLOOP; RETURN[s]; END; MakeNullValueOfType: PUBLIC PROC [vt: DataType] RETURNS[Value] = BEGIN SELECT vt FROM RopeType => {gdfc: ROPE_ ""; RETURN[S2V[gdfc]]}; IntType => RETURN[I2V[0]]; TimeType => RETURN[T2V[BasicTime.nullGMT]]; BoolType => RETURN[B2V[FALSE]]; ENDCASE => RETURN[[null[]]]; END; GetDomainIndex: PUBLIC PROC[s: SegmentHandle] RETURNS [DBStorage.IndexHandle] = {RETURN[DBStorage.RootIndicesFromSegment[s.segment][DBCommon.domainIndex]]}; GetRelationIndex: PUBLIC PROC[s: SegmentHandle] RETURNS [DBStorage.IndexHandle] = {RETURN[DBStorage.RootIndicesFromSegment[s.segment][DBCommon.relationIndex]]}; CreateEntityIndexEntries: PUBLIC PROC [e: Entity] = BEGIN name: ROPE; d: Domain; nameIndex: Index; surrRelns: LIST OF Relation; dt: TupleHandle; [name, d] _ GetCachedEntityInfo[SegmentOf[e], e]; dt _ DBModelSchema.GetDomainTuple[d]; nameIndex _ PV2E[SafeGetP[dt, dIndexProp]]; DBStorage.InsertIntoIndex[nameIndex, NCode[S2V[name]], e]; FOR surrRelns_ GetIndexedSurrogates[dt], surrRelns.rest UNTIL surrRelns=NIL DO r: Relation_ surrRelns.first; fakeSurrogateRelship: SurrogateRelshipHandle_ SurrogateCreateRelship[r]; fakeSurrogateRelship.entity_ e; CreateAllIndexEntries[fakeSurrogateRelship]; ENDLOOP; END; DestroyEntityIndexEntries: PUBLIC PROC [e: Entity] = BEGIN name: ROPE; d: Domain; nameIndex: Index; [name, d] _ GetCachedEntityInfo[SegmentOf[e], e]; nameIndex _ PV2E[SafeGetP[DBModelSchema.GetDomainTuple[d], dIndexProp]]; IF nameIndex#NIL THEN DBStorage.DeleteFromIndex[nameIndex, NCode[S2V[name]], e]; END; CreateIndexEntries: PUBLIC PROC [t: Relship, indexList: LIST OF Index] = BEGIN th: TupleHandle_ GetTupleHandle[t]; FOR is: LIST OF Index _ indexList, is.rest UNTIL is=NIL DO DBStorage.InsertIntoIndex[is.first, NCodeForTuple[t, is.first], th]; ENDLOOP; END; CreateAllIndexEntries: PUBLIC PROC [t: Relship] = BEGIN i: Index; th: TupleHandle_ GetTupleHandle[t]; al: LIST OF Attribute _ QRelationOf[t].attributes; FOR il: LIST OF Index_ GetRelationIndices[al], il.rest UNTIL il=NIL DO i_ il.first; DBStorage.InsertIntoIndex[i, NCodeForTuple[t, i], th]; ENDLOOP; END; DestroyIndexEntries: PUBLIC PROC [t: Relship, indexList: LIST OF Index] = BEGIN th: TupleHandle_ GetTupleHandle[t]; FOR is: LIST OF Index _ indexList, is.rest UNTIL is=NIL DO DBStorage.DeleteFromIndex[is.first, NCodeForTuple[t, is.first], th]; ENDLOOP; END; DestroyAllIndexEntries: PUBLIC PROC [t: Relship, r: Relation] = BEGIN i: Index; th: TupleHandle_ GetTupleHandle[t]; FOR il: LIST OF Index_ GetRelationIndices[r.attributes], il.rest UNTIL il=NIL DO i_ il.first; DBStorage.DeleteFromIndex[i, NCodeForTuple[t, i], th]; ENDLOOP; END; DestroyLinksTo: PUBLIC PROC[e: Entity] = BEGIN al: LIST OF Attribute; rs: RelshipSet; rsi: CARDINAL; r: Relship; ev: Value _ E2V[e]; al_ QGetAllRefAttributes[e]; IF al # NIL AND DBModelSchema.InvalidAttribute[al.first] THEN ERROR Error[InvalidSchema]; [rs, rsi] _ GetNewRelshipSet[]; FOR alT: LIST OF Attribute_ al, alT.rest UNTIL alT=NIL DO rs_ QRelationSubset[alT.first.relation, LIST[[alT.first, ev]], First, rs]; WHILE (r_ QNextRelship[rs])#NIL DO QDestroyRelship[r] ENDLOOP; QReleaseRelshipSet[rs]; ENDLOOP; ReturnRelshipSet[rsi]; END; GetRelationIndices: PROC [attributes: LIST OF Attribute] RETURNS [LIST OF Index] = BEGIN il: LIST OF Index_ NIL; FOR al: LIST OF Attribute_ attributes, al.rest UNTIL al=NIL DO ifl: LIST OF IndexFactor_ VL2TL[QGetPList[DBModelSchema.GetAttributeTuple[al.first], ifAttributeOf]]; FOR iflT: LIST OF IndexFactor_ ifl, ifl.rest UNTIL iflT=NIL DO IF iflT.first#NIL THEN il_ AppendIfNew[V2E[QGetP[iflT.first, ifIndexIs]], il]; ENDLOOP; ENDLOOP; RETURN[il] END; GetIndexedSurrogates: PROC [t: TupleHandle] RETURNS [indexedSurrogates: LIST OF Relation] = TRUSTED BEGIN surrogates: LIST OF Relation_ GetSurrogates[t]; indexedSurrogates_ NIL; FOR surrogatesT: LIST OF Relation_ surrogates, surrogatesT.rest UNTIL surrogatesT=NIL DO surrAttrs: LIST OF Attribute _ surrogatesT.first.attributes; FOR surrAttrs_ surrAttrs, surrAttrs.rest UNTIL surrAttrs=NIL DO v: PrivateValue = SafeGetP[DBModelSchema.GetAttributeTuple[surrAttrs.first], ifAttributeOf]; WITH v: v SELECT FROM public => WITH v.val SELECT FROM null => NULL; ENDCASE => GOTO ThisRelation; ENDCASE => GOTO ThisRelation; ENDLOOP; REPEAT ThisRelation=> indexedSurrogates_ CONS[surrogatesT.first, indexedSurrogates]; ENDLOOP; END; GetSurrogates: PROC [t: TupleHandle] RETURNS [LIST OF Relation] = BEGIN rl: LIST OF Relation_ NIL; FOR al: LIST OF Attribute_ VL2AL[QGetPList[t, aDomainOf]], al.rest UNTIL al=NIL DO IF DBModelSchema.InvalidAttribute[al.first] THEN ERROR Error[InvalidSchema]; rl_ AppendIfNewR[al.first.relation, rl]; ENDLOOP; RETURN[rl] END; AppendIfNew: PROC [e: Entity, il: LIST OF Index] RETURNS [LIST OF Index] = BEGIN ilT: LIST OF Index; FOR ilT_ il, ilT.rest UNTIL ilT=NIL DO IF EntityEq[ilT.first, e] THEN RETURN[il] ENDLOOP; RETURN[CONS[e, il]]; END; AppendIfNewR: PROC [r: Relation, rl: LIST OF Relation] RETURNS [LIST OF Relation] = BEGIN rlT: LIST OF Relation; FOR rlT_ rl, rlT.rest UNTIL rlT=NIL DO IF QRelationEq[rlT.first, r] THEN RETURN[rl] ENDLOOP; RETURN[CONS[r, rl]]; END; EmptyDomain: PUBLIC PROC [d: Domain] RETURNS [b: BOOLEAN] = BEGIN es: EntitySet; esi: CARDINAL; [es, esi] _ GetNewEntitySet[]; es _ QDomainSubset[d: d, es: es]; b_ NullEntity[QNextEntity[es]]; QReleaseEntitySet[es]; ReturnEntitySet[esi]; END; EmptyRelation: PUBLIC PROC [r: Relation] RETURNS [b: BOOLEAN] = BEGIN rs: RelshipSet; rsi: CARDINAL; [rs, rsi] _ GetNewRelshipSet[]; rs _ QRelationSubset[r: r, rs: rs]; b_ NullRelship[QNextRelship[rs]]; QReleaseRelshipSet[rs]; ReturnRelshipSet[rsi]; END; NumberOfAttributes: PUBLIC PROC [r: Relation] RETURNS [n: CARDINAL] = BEGIN count: INT_ 0; IF DBModelSchema.InvalidRelation[r] THEN ERROR Error[InvalidSchema]; FOR al: LIST OF Attribute _ r.attributes, al.rest UNTIL al=NIL DO count_ count+1 ENDLOOP; RETURN[count] END; GetFirstAttribute: PUBLIC PROC [ of: Relation, notCounting: Attribute_ NIL] RETURNS [a: Attribute] = BEGIN ENABLE Error => TRUSTED {IF code=NILArgument THEN {a_ NIL; CONTINUE}}; IF QAttributeEq[notCounting, of.attributes.first] THEN RETURN[of.attributes.rest.first] ELSE RETURN[of.attributes.first]; END; GetTypeAndLink: PUBLIC PROC [a: TupleHandle] RETURNS [type: DataType, link: LinkType] = BEGIN vtTid: INT; pos: LONG CARDINAL; vtTid_ PV2I[SafeGetP[a, aTypeCodeProp]]; IF vtTid<=0 THEN RETURN[EntityToDataType[PV2E[SafeGetP[a, aTypeEntityProp]]], LOOPHOLE[Basics.LowHalf[-vtTid]]] ELSE IF (pos_ vtTid)<=MaxDataTypeID THEN RETURN[EntityToDataType[DBModelPrivate.systemTupleVec[pos]], Linked] ELSE ERROR InternalError; END; SetTypeAndLink: PUBLIC PROC [a: TupleHandle, type: DataType, link: LinkType] = BEGIN segment: SegmentHandle _ IF IsSystem[a] THEN NIL ELSE SegmentOf[a]; typeEntity: Entity _ DataTypeToEntity[type, segment]; SELECT type FROM RopeType, IntType, TimeType, BoolType, AnyDomainType, RecordType => []_ SafeSetP[a, aTypeCodeProp, I2PV[typeEntity.tid]]; ENDCASE => { []_ SafeSetP [a, aTypeCodeProp, I2PV[- LOOPHOLE[link, INTEGER]]]; []_ SafeSetP[a, aTypeEntityProp, E2PV[typeEntity]]; IF link=Unlinked OR link=Remote THEN -- set aUnlinked so can find refs by group scan []_ SafeSetP[a, aUnlinkedIs, E2PV[typeEntity]] }; END; SegmentOf: PUBLIC PROC[t: TupleHandle] RETURNS [SegmentHandle] = { CheckNullified[t]; IF IsSystem[t] THEN RETURN[NIL]; RETURN[SegmentToHandle[DBStorage.SegmentFromTuple[t]]] }; CheckNullified: PROC [p: TupleHandle] = INLINE { IF p=NIL THEN ERROR DB.Error[NILArgument] ELSE IF p.tid=NoTID THEN ERROR DB.Error[NullifiedArgument] }; GetTupleHandle: PROC [t: Relship] RETURNS [TupleHandle] = TRUSTED BEGIN WITH t SELECT FROM t1: TupleHandle => RETURN[t1]; t2: SurrogateRelshipHandle => RETURN[t2.entity]; ENDCASE => ERROR InternalError; END; MakeFD: PUBLIC PROC [vt: DataType, length: INT_ 0, link: BOOL_ TRUE, a: TupleHandle_ NIL] RETURNS [DBStorage.FieldDescriptor] = BEGIN len: CARDINAL_ Basics.LowHalf[length]; -- sigh SELECT vt FROM BoolType => RETURN[[OneWord[]]]; IntType => RETURN[[TwoWord[]]]; TimeType => RETURN[[TwoWord[]]]; RopeType => RETURN[[VarByte[lengthHint: len]]]; RecordType => RETURN[[NWord[length: len]]]; ENDCASE => { -- some entity reffing field IF a=NIL THEN ERROR; IF link THEN RETURN[[Group[groupID: a]]] ELSE RETURN[[VarByte[lengthHint: len]]]; }; END; VL2AL: PROC[vl: LIST OF Value] RETURNS [LIST OF Attribute] = { IF vl = NIL THEN RETURN[NIL] ELSE RETURN[CONS[DBModelSchema.TupleToAttribute[V2E[vl.first]], VL2AL[vl.rest]]] }; LowByte: PROC [n: CARDINAL] RETURNS [CHAR] = TRUSTED INLINE {RETURN[LOOPHOLE[LOOPHOLE[n, Basics.BytePair].low]]}; HighByte: PROC [n: CARDINAL] RETURNS [CHAR] = TRUSTED INLINE {RETURN[LOOPHOLE[LOOPHOLE[n, Basics.BytePair].high]]}; END. ŠFile: DBModelPrivateImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Contents: Implementation of miscellaneous internal procedures for Model level Last edited by: Rick Cattell on September 15, 1983 4:40 pm Willie-Sue, April 25, 1985 2:52:14 pm PST Donahue, September 30, 1985 9:34:53 am PDT Widom, September 13, 1985 4:27:39 pm PDT Checking procedures String manipulation Encodes value v as an index key. All routines constructing index keys or doing key comparisons should call this routine. Encodes the attributes of t required as factors of index i as ropes, concatenates the ropes in the order required by the index, and returns the result (for use in using DBStorage indices, which require a single rope key). A null byte is placed between the encoded attribute ropes to preserve the lexicographic priorities of the attributes. Note this means null chars may not appear in attributes of type string if proper orderings are to result. Index-related procedures Returns the domain index for the segment Returns the relation index for the segment Finds the name index for e's Domain and insert e into it. Also creates index entries for any surrogate relations that are actually stored in e. Find the name index for e's Domain and remove e from it. Does NOT destroy any surrogate relation index entries; that can be done by DestroyLinksTo. Non-NIL unless we are destroying this entity in the process of destroying domain Find all existing indexes for t's tupleset and insert t into them. Find all relevant indexes for t and delete t from them. To do this, find the attributes of t's relation, find index factors involving those attributes, find indices for those index factors, and destroy index entries for them. The relationship t may be an ordinary or surrogate relationship; GetTupleHandle below returns the entity handle in the latter case, the relationship handle in the former case, so the right thing happens. Destroys any references to e by following backlinks (groups) to the tuples whose fields point to t, and destroying those tuples. Also destroys tuples that do NOT reference e via a group (i.e., with aUnlinkedIs TRUE); we get these because QGetAllRefAttributes returns unlinked attributes as well. Note: DBModelGlobalImpl.DestroyDictionaryEntity depends upon this procedure working for dictionary entities as well as ordinary client entities. Returns the list of surrogate relations that have been targetted to domain d. First we find the attributes that have been targetted to domain d using a group scan on aDomainOf, then we find their relations, eliminating duplicates. Add entity e to list el if it is not already in the list. Add relation r to list rl if it is not already in the list. Handy list and set procedures Returns the first attribute of relation "of" except for "notCounting". Miscellaneous procs The use of aTypeIs is unusual. If aTypeCodeProp > 0, the type is the system entity whose tid is the aTypeCodeProp. Else the type is the domain referenced by aTypeEntityProp, and aTypeCodeProp= - LOOPHOLE[LinkType, INTEGER], distinguishable since <= 0. Must check explicitly for system attribute because SafeGetP won't handle aTypeEntityProp and aTypeCodeProp on system entities (it would be too inefficient to NEW INTs and BOOLs). See comment above about encoding of aTypeCodeProp and aTypeEntityProp. Also note: if attribute is not linked, must set aUnlinked to domain so can find later. Attribute defined on client-defined domain. Store domain in the aTypeEntity field. Returns the target entity's tuple handle if t is surrogate, else just returns t. Takes information about an attribute, returns a field descriptor for values of the given attribute. Κ$˜šœ™Jšœ Οmœ1™<—JšœM™Mšœ™Jšœ*™*Jšœ)™)Icode™*K™(J˜—šΟk ˜ Jšœžœ˜J˜J˜ J˜J˜ J˜ J˜J˜Jšžœ˜J˜J˜J˜J˜J˜—šœžœž˜!šžœ/˜6Jšœ žœ0˜=—Jšžœ˜J˜—Jšžœžœžœ-˜:˜Jšœ žœžœžœ˜J˜Jšœžœžœ˜"Ihead1šœ™š Οn œžœžœžœžœ˜9Jšž˜šžœž˜Jšœ5žœžœ˜CJšžœžœžœ˜—Jšžœ˜——šœ™š Ÿœžœžœžœžœžœ˜5Jšžœžœ˜š œ žœžœžœžœžœ˜.Jšœžœ$˜+—Jšžœ&˜,Jšžœ˜—J˜š Ÿœžœžœ žœžœžœ˜5JšœA™AJšœ7™7Jšž˜šžœžœž˜JšœžœžœΟc"˜7šœ˜Jšžœžœžœ˜B—šœ ˜ Jš žœžœžœžœ žœžœ˜FJšœžœ˜J˜#J˜"J˜EJšžœ˜Jšžœ˜—šœ +˜3Jšžœžœžœ˜5Jšœžœ˜J˜GJ˜EJšžœ˜Jšžœ˜—šœ  7˜CJš žœžœžœžœ "˜JJšžœJ˜P—šœ ˜ Jš žœ žœžœ žœžœ ˜4—Jšžœžœ  ˜2—Jšžœ˜J˜—šŸ œžœžœ˜Jšžœž˜ Jšœžœžœ˜Jšœžœžœ˜#šžœž˜Jš žœžœžœžœžœžœ˜Y—Jšžœ˜J˜—šŸ œžœžœžœ˜:JšœQ™QJšœP™PJšœQ™QJšœO™OJšœW™WJšœ"™"Jšž˜Jšœžœ˜ š žœžœžœ7žœžœž˜WJ˜J˜gJšžœ˜—Jšžœ˜ Jšžœ˜J˜—šŸœžœžœžœ ˜@Jšž˜šžœž˜Jšœžœžœ ˜0Jšœ žœ ˜Jšœ žœ˜+Jšœ žœžœ˜Jšžœžœ ˜—Jšžœ˜——šœ™šŸœžœžœžœ˜PJšœ(™(JšœžœE˜LJ˜—šŸœžœžœžœ˜RJšœ*™*JšœžœG˜NJ˜—šŸœžœžœ˜3Jšœ9™9JšœU™UJšž˜Jšœžœ ˜J˜Jšœ žœžœ ˜J˜Jšœ1˜1J˜%J˜+J˜:šžœ5žœ žœž˜NJšœ˜J˜HJ˜J˜,Jšžœ˜—Jšžœ˜—J˜šŸœžœžœ˜4JšœK™KJšœI™IJšž˜Jšœžœ ˜J˜J˜1J˜Hšžœ žœž˜JšœP™PJ˜:—Jšžœ˜J˜—š Ÿœžœžœžœžœ ˜HJšž˜Jšœ#˜#š žœžœžœžœžœž˜:J˜DJšžœ˜—Jšžœ˜J˜—šŸœžœžœ˜1JšœB™BJšž˜Jšœ ˜ Jšœ#˜#Jšœžœžœ'˜2š žœžœžœ(žœžœž˜FJšœ ˜ J˜6Jšžœ˜—Jšžœ˜J˜—š Ÿœžœžœžœžœ ˜IJšž˜Jšœ#˜#š žœžœžœžœžœž˜:J˜DJšžœ˜—Jšžœ˜J˜—šŸœžœžœ˜?Jšœ[™[Jšœb™bJšœW™WJšœT™TJšœC™CJšžœ.˜3š žœžœžœ2žœžœž˜PJ˜ J˜6Jšžœ˜—Jšžœ˜J˜—šŸœžœžœ ˜)JšœP™PJšœQ™QJšœK™KJšœ9™9JšœK™KJšœD™DJšž˜Jšœžœžœ ˜Jšœžœ˜J˜ Jšœ˜J˜Jš žœžœžœ*žœžœ˜YJ˜š žœžœžœžœžœž˜9Jšœ(žœ˜Jšžœžœž˜"Jšœžœ˜—J˜Jšžœ˜J˜—Jšžœ˜J˜—šŸœžœžœžœ žœžœžœ ˜RJšžœžœžœžœ˜š žœžœžœ žœžœž˜>JšœžœžœY˜eš žœžœžœžœžœž˜>Jšžœ žœžœ8˜NJšžœ˜—Jšžœ˜—Jšžœ˜ Jšžœ˜J˜—šŸœžœ˜+Jšžœžœžœ ˜/Jšžœž˜ Jšœ žœžœ˜/Jšœžœ˜š žœžœžœ(žœ žœž˜XJšœ žœžœ*˜<šžœ&žœ žœž˜?Jšœ\˜\šžœžœž˜šœ ˜ šžœžœž˜Jšœžœ˜ Jšžœžœ˜——Jšžœžœ˜—Jšžœ˜—šž˜Jšœ"žœ'˜M—Jšžœ˜—Jšžœ˜J˜—š Ÿ œžœžœžœžœ ˜AJšœM™MJšœW™WJšœ@™@Jšžœžœžœ žœ˜ š žœžœžœ4žœžœž˜RJšžœ*žœžœ˜LJ˜(Jšžœ˜Jšžœ˜ Jšžœ˜J˜——šŸ œžœžœžœžœžœžœ ˜JJšœ9™9Jšžœžœžœ˜šžœžœžœž˜&Jšžœžœžœžœ˜2—Jšžœžœ ˜Jšžœ˜J˜—šŸ œžœžœžœ žœžœžœ ˜SJšœ;™;Jšžœžœžœ ˜šžœžœžœž˜&Jšžœžœžœžœ˜5—Jšžœžœ ˜Jšžœ˜——šœ™š Ÿ œžœžœ žœžœ˜;Jšž˜Jšœžœ˜J˜Jšœ!˜!J˜J˜J˜Jšžœ˜J˜—š Ÿ œžœžœžœžœ˜?Jšž˜Jšœžœ˜J˜J˜#J˜!J˜J˜Jšžœ˜—J˜š Ÿœžœžœžœžœ˜EJšžœžœ˜Jšžœ"žœžœ˜Dš žœžœžœ#žœžœž˜AJšœžœ˜—Jšžœ˜ Jšžœ˜J˜—šŸœžœžœ˜ Jšœ&žœžœ˜CJšœF™FJšžœžœ žœžœžœžœžœ˜Lšžœ0žœžœ˜WJšžœžœ˜!—Jšžœ˜——šœ™šŸœžœžœžœ#˜WJšœY™YJšœU™UJšœM™MJšœX™XJšœY™YJšž˜Jšœžœžœžœ˜J˜(šžœ ž˜Jšžœ7žœ˜^—šžœžœž˜(Jšžœ>˜D—Jšžœžœ˜Jšžœ˜J˜—šŸœžœžœ3˜NJšœF™FJšœV™VJšž˜Jš œžœ žœžœžœ˜CJšœ5˜5šžœž˜šœC˜CJšœ5˜5—šžœ˜ JšœS™SJšœ'žœžœ˜AJšœ3˜3šžœžœ žœ /˜TJšœ1˜1———Jšžœ˜J˜—šŸ œžœžœžœ˜BJ˜Jšžœ žœžœžœ˜ Jšžœ3˜9J˜—šŸœžœžœ˜0Jš žœžœžœžœžœ˜)Jš žœžœ žœžœžœ˜=—J˜šŸœžœžœ˜9JšœP™PJšžœž˜ šžœžœž˜Jšœžœ˜Jšœžœ ˜0Jšžœžœ˜—Jšžœ˜J˜—šŸœžœžœžœ žœžœžœ˜YJšžœ˜%JšœX™XJšœ ™ Jšž˜Jšœžœ ˜.šžœž˜Jšœ žœ˜!Jšœ žœ˜Jšœ žœ˜ Jšœ žœ˜/Jšœžœ˜+šžœ ˜)Jšžœžœžœžœ˜Jšžœžœžœ˜(Jšžœžœ˜(J˜——Jšžœ˜—J˜šŸœžœžœžœžœžœžœ˜>š žœžœžœžœžœ˜JšžœžœžœC˜SJ˜——š Ÿœžœžœžœžœžœž˜;Jšœžœžœžœ˜5——˜š Ÿœžœžœžœžœžœž˜