DIRECTORY BcdDefs USING [ Base, Link, CTIndex, CTNull, EVNull, FPIndex, FPRecord, GFTIndex, MTIndex, VarLimit, VersionID], BcdOps USING [ BcdBase, CTHandle, FPHandle, MTHandle, NameString, ProcessConfigs, ProcessFramePacks, ProcessModules], Inline USING [BITAND], LongString USING [AppendString], MB USING [ Abort, AllocateFrames, BHandle, BIndex, EnumerateFramePacks, EnumerateGlobalFrames, Error, Handle, ModuleInfo, MT, Zero], MBLoaderOps USING [ Bind, EnterModule, FileNotFound, FindFiles, FindCode, GetModule, GetNextGFI, GetVirtualLinks, InputLoadState, LinkFragLength, ProcessUnboundImports, SetGFTEntry, UpdateLoadState, VirtualLinks, WriteLoadState, WriteLinks], MBOut USING [Char, CR, Decimal, Line, Number, NumberFormat, Octal, SP, Text], MBStorage USING [Pages, FreePages, FreeWords, Words], MBTTY USING [Handle, PutCR, PutLine, PutString], MBVM USING [AllocFile, Base, CopyWrite, FileSeg, HyperSpace, Read, Write], PilotLoadStateFormat USING [ConfigIndex, ModuleInfo], PrincOps USING [ AV, ControlLink, ControlModule, FrameCodeBase, GFTIndex, GlobalFrame, GlobalFrameHandle, NullControl, NullLink, UnboundLink], RuntimeInternal USING [MakeFsi], Segments USING [ BaseFromSegment, DeleteSegment, FHandle, FileFromSegment, HardUp, MoveSegment, NewFile, NewSegment, PagesFromSegment, Read, SegmentAddress, SHandle, SwapIn, Unlock]; MBLoaderCore: PROGRAM IMPORTS BcdOps, Inline, MB, MBLoaderOps, MBOut, MBStorage, MBTTY, MBVM, RuntimeInternal, Segments, String: LongString EXPORTS MB, MBLoaderOps = BEGIN OPEN MB; data: MB.Handle _ NIL; InitLoaderCore: PUBLIC PROC [h: MB.Handle] = {data _ h}; FinishLoaderCore: PUBLIC PROC = { FOR i: MB.BIndex IN [0..data.inputBCDs.nBcds) DO loadee: MB.BHandle = data.inputBCDs.bcds[i]; ReleaseModuleTable[loadee]; IF loadee.bcdSegment ~= NIL THEN { Segments.Unlock[loadee.bcdSegment]; Segments.DeleteSegment[loadee.bcdSegment]; }; ENDLOOP; data _ NIL; }; Load: PUBLIC PROC = { tty: MBTTY.Handle = data.ttyHandle; data.nModules _ 0; FOR i: MB.BIndex IN [0..data.inputBCDs.nBcds) DO loadee: MB.BHandle = data.inputBCDs.bcds[i]; name: STRING _ [40]; missingCodeFile: BOOL _ FALSE; config: PilotLoadStateFormat.ConfigIndex; String.AppendString[name, loadee.name]; MBTTY.PutString[tty, "Loading "]; MBTTY.PutString[tty, name]; MBTTY.PutString[tty, "..."L]; IF (loadee.bcdSegment _ LoadBcd[Segments.NewFile[name]]) = NIL THEN { MBTTY.PutCR[tty]; MBTTY.PutString[tty, "!Invalid file "L]; MBTTY.PutString[tty, name]; ERROR MB.Abort }; MBOut.Text["Global Frames for Modules in "L]; MBOut.Text[name]; MBOut.Char[':]; MBOut.CR[]; loadee.bcd _ Segments.SegmentAddress[loadee.bcdSegment]; IF ~data.germ THEN { loadee.bcdSeg _ MBVM.AllocFile[ file: Segments.FileFromSegment[loadee.bcdSegment], fileBase: Segments.BaseFromSegment[loadee.bcdSegment], base: MBVM.HyperSpace, pages: Segments.PagesFromSegment[loadee.bcdSegment]]; loadee.bcdSeg.segment _ loadee.bcdSegment; loadee.bcdSeg.bIndex _ i; }; MBLoaderOps.FindFiles[loadee ! MBLoaderOps.FileNotFound => { MBTTY.PutCR[tty]; MBTTY.PutString[tty, "!Can't find file "L]; MBTTY.PutString[tty, name]; missingCodeFile _ TRUE; RESUME } ]; IF missingCodeFile THEN {MBTTY.PutCR[tty]; MB.Error["Missing code files"L]}; config _ LoadModules[loadee]; MBTTY.PutString[tty, "looking up code..."L]; MBLoaderOps.FindCode[loadee]; MBTTY.PutString[tty, "binding modules..."L]; [] _ AssignControlModules[loadee]; IF config = FIRST[PilotLoadStateFormat.ConfigIndex] THEN JustRelocateLinks[loadee] ELSE MBLoaderOps.Bind[loadee, config]; MBOut.CR[]; MBTTY.PutLine[tty, "done"L]; ENDLOOP; MBLoaderOps.WriteLoadState[]; data.nGFIs _ MBLoaderOps.GetNextGFI[reserve: 0]; MBOut.CR[]; MBOut.Text["Total of "L]; MBOut.Decimal[data.nModules]; MBOut.Text[" modules, "L]; MBOut.Decimal[data.nGFIs]; MBOut.Line[" GFIs"L]; MBLoaderOps.ProcessUnboundImports[]; MBTTY.PutLine[tty, "Finished loading."L]; }; LoadBcd: PROC [bcdfile: Segments.FHandle] RETURNS [bcdseg: Segments.SHandle] = { b: BcdOps.BcdBase; pages: CARDINAL; bcdseg _ Segments.NewSegment[file: bcdfile, base: 1, pages: 1, access: Segments.Read]; Segments.SwapIn[seg: bcdseg, info: Segments.HardUp]; b _ Segments.SegmentAddress[bcdseg]; IF b.versionIdent # BcdDefs.VersionID OR b.definitions --OR ~b.spare1-- THEN { Segments.Unlock[bcdseg]; Segments.DeleteSegment[bcdseg]; RETURN[NIL] }; IF (pages _ b.nPages) > 1 THEN { Segments.Unlock[bcdseg]; Segments.MoveSegment[bcdseg, 1, pages]; Segments.SwapIn[seg: bcdseg, info: Segments.HardUp]; }; }; SetupModuleTable: PROC [loadee: MB.BHandle] RETURNS [ngfi: CARDINAL _ 0] = { words: CARDINAL = loadee.bcd.firstdummy * SIZE[MB.ModuleInfo]; SetEntriesForOneModule: PROC [ mth: BcdOps.MTHandle, mti: BcdDefs.MTIndex] RETURNS [stop: BOOL] = { ngfi _ ngfi + mth.ngfi; FOR i: CARDINAL IN [mth.gfi..mth.gfi+mth.ngfi) DO loadee.mt[i] _ MB.ModuleInfo[mth: mth, frame: NIL, code: NIL]; ENDLOOP; RETURN[FALSE] }; loadee.mt _ DESCRIPTOR[MBStorage.Words[words], loadee.bcd.firstdummy]; MB.Zero[BASE[loadee.mt], words]; loadee.mt[0] _ MB.ModuleInfo[mth: NIL, frame: NIL, code: NIL]; [] _ BcdOps.ProcessModules[loadee.bcd, SetEntriesForOneModule]; loadee.mt _ DESCRIPTOR[BASE[loadee.mt], ngfi+1]; }; ReleaseModuleTable: PUBLIC PROC [loadee: MB.BHandle] = { IF BASE[loadee.mt] # NIL THEN { MBStorage.FreeWords[BASE[loadee.mt]]; loadee.mt _ DESCRIPTOR[NIL,0]; }; }; LoadModules: PROC [loadee: MB.BHandle] RETURNS [config: PilotLoadStateFormat.ConfigIndex] = BEGIN bcd: BcdOps.BcdBase = loadee.bcd; mt: MT; ngfi: CARDINAL; gfiOffset: CARDINAL; framePtr: POINTER; frameSpace: CARDINAL _ 0; useFrameHeap: BOOL = (bcd.nModules = 1); inFrameHeap: BOOL; framesResident: BOOL _ FALSE; ProcessOneFramePack: PROC [fph: BcdOps.FPHandle, fpi: BcdDefs.FPIndex] RETURNS [BOOL] = { mtb: BcdDefs.Base = LOOPHOLE[bcd + bcd.mtOffset]; frameSpace _ 0; framesResident _ FALSE; FOR i: CARDINAL IN [0..fph.length) DO GetFrameSize[@mtb[fph.modules[i]]]; ENDLOOP; [framePtr, inFrameHeap] _ MB.AllocateFrames[ size: NextMultipleOfFour[frameSpace], single: useFrameHeap, resident: framesResident OR ResidentFramePack[fph] -- specified in bootmesa file--]; FOR i: CARDINAL IN [0..fph.length) DO FrameInit[@mtb[fph.modules[i]]]; ENDLOOP; RETURN[FALSE] }; GetFrameSize: PROC [mth: BcdOps.MTHandle] = { IF ~(mth.linkLoc = code AND mth.code.linkspace) THEN -- frame links frameSpace _ frameSpace + MBLoaderOps.LinkFragLength[loadee, mth]; frameSpace _ NextMultipleOfFour[frameSpace] + mth.framesize; framesResident _ framesResident OR mth.residentFrame; }; FrameInit: PROC [mth: BcdOps.MTHandle] = { frame: PrincOps.GlobalFrameHandle; gf: PrincOps.GlobalFrame; gfi: PrincOps.GFTIndex = gfiOffset + mth.gfi; -- module's biased gfi framelinks: BOOL = ~(mth.linkLoc = code AND mth.code.linkspace); nLinks: CARDINAL = MBLoaderOps.LinkFragLength[loadee, mth]; data.nModules _ data.nModules + 1; IF framelinks THEN framePtr _ (framePtr + nLinks); frame _ NextMultipleOfFour[framePtr]; framePtr _ (frame + mth.framesize); FOR i: CARDINAL IN [0..mth.ngfi) DO mt[mth.gfi + i].frame _ frame; ENDLOOP; MBLoaderOps.SetGFTEntry[frame: frame, gfi: gfi, ngfi: mth.ngfi]; FOR i: CARDINAL IN [0..mth.ngfi) DO MBLoaderOps.EnterModule[ rgfi: (gfi + i), module: PilotLoadStateFormat.ModuleInfo[ config: config, gfi: (mth.gfi + i), -- local gfi resolved: (nLinks = 0)] ]; ENDLOOP; gf _ PrincOps.GlobalFrame[ gfi: gfi, copied: FALSE, alloced: inFrameHeap, shared: FALSE, started: FALSE, trapxfers: FALSE, codelinks: ~framelinks, global: , code: PrincOps.FrameCodeBase[ offset[offset: mth.code.offset, highHalf: NIL]] ]; gf.code.out _ TRUE; MBVM.CopyWrite[from: @gf, to: frame, nwords: SIZE[PrincOps.GlobalFrame]]; MBVM.Write[@frame.global[0], PrincOps.NullControl]; -- no control module PrintLoadmapEntry[bcd: bcd, mth: mth, frame: frame, gfiOffset: gfiOffset]; }; OtherFrameSizes: PROC [mth: BcdOps.MTHandle, mti: BcdDefs.MTIndex] RETURNS [BOOL] = { IF mt[mth.gfi].frame = NIL THEN GetFrameSize[mth]; RETURN[FALSE] }; OtherFrameInit: PROC [mth: BcdOps.MTHandle, mti: BcdDefs.MTIndex] RETURNS [BOOL] = { IF mt[mth.gfi].frame = NIL THEN FrameInit[mth]; RETURN[FALSE] }; ngfi _ SetupModuleTable[loadee]; mt _ loadee.mt; config _ MBLoaderOps.InputLoadState[]; loadee.gfiOffset _ gfiOffset _ MBLoaderOps.GetNextGFI[reserve: ngfi] - 1; [] _ BcdOps.ProcessFramePacks[bcd, ProcessOneFramePack]; frameSpace _ 0; framesResident _ FALSE; [] _ BcdOps.ProcessModules[bcd, OtherFrameSizes]; IF frameSpace # 0 THEN { -- there are frames not in frame packs [framePtr, inFrameHeap] _ MB.AllocateFrames[ size: NextMultipleOfFour[frameSpace], single: useFrameHeap, resident: framesResident OR AnyResidentGlobalFrames[loadee]]; [] _ BcdOps.ProcessModules[bcd, OtherFrameInit]}; END; ResidentFramePack: PROC [f: BcdOps.FPHandle] RETURNS [resident: BOOL] = { CheckOne: PROC [bh: MB.BHandle, fph: BcdOps.FPHandle] RETURNS [BOOL] = { RETURN[resident _ (f = fph)]}; MB.EnumerateFramePacks[resident, CheckOne]; }; AnyResidentGlobalFrames: PROC [loadee: MB.BHandle] RETURNS [resident: BOOL] = { CheckOne: PROC [bh: MB.BHandle, mth: BcdOps.MTHandle] RETURNS [BOOL] = { RETURN[resident _ (bh = loadee)]}; MB.EnumerateGlobalFrames[resident, CheckOne]; }; NextMultipleOfFour: PROC [x: UNSPECIFIED] RETURNS [UNSPECIFIED] = INLINE { RETURN[x + Inline.BITAND[-LOOPHOLE[x, INTEGER], 3B]]}; PrintLoadmapEntry: PROC [ bcd: BcdOps.BcdBase, mth: BcdOps.MTHandle, frame: POINTER, gfiOffset: CARDINAL] = { ssb: BcdOps.NameString _ LOOPHOLE[bcd + bcd.ssOffset]; MBOut.Text[" New: g = "L]; MBOut.Number[frame, MBOut.NumberFormat[8,FALSE,TRUE,6]]; MBOut.SP[]; FOR i: CARDINAL IN [mth.name .. mth.name+ssb.size[mth.name]) DO MBOut.Char[ssb.string.text[i]]; ENDLOOP; MBOut.Text[" ["L]; MBOut.Octal[PrincOps.ControlLink[ procedure[gfi: (gfiOffset + mth.gfi), ep: 0, tag: FALSE]]]; MBOut.Char[']]; MBOut.CR[]; }; CMMapItem: TYPE = RECORD [ cti: BcdDefs.CTIndex, cm: PrincOps.ControlModule, depth: CARDINAL ]; AssignControlModules: PROC [loadee: MB.BHandle] RETURNS [cm: PrincOps.ControlModule] = { bcd: BcdOps.BcdBase = loadee.bcd; mt: MB.MT = loadee.mt; ctb: BcdDefs.Base _ LOOPHOLE[bcd + bcd.ctOffset]; mtb: BcdDefs.Base _ LOOPHOLE[bcd + bcd.mtOffset]; cmMap: LONG POINTER TO ARRAY [0..0) --subconfig#-- OF CMMapItem; lastConfig, maxDepth: CARDINAL _ 0; cti: BcdDefs.CTIndex; EnterControlInfoForConfig: PROC [ cth: BcdOps.CTHandle, cti: BcdDefs.CTIndex] RETURNS [stop: BOOL] = { cm: PrincOps.ControlModule; depth: CARDINAL _ 0; -- depth of config in Bcd's config structure IF cth.nControls = 0 THEN cm _ PrincOps.NullControl ELSE { cm.list _ Alloc[RuntimeInternal.MakeFsi[words: (cth.nControls + 1) + 1] ! AllocFault => MB.Error["Larger frame heap needed (for control list)"L] ]; MBVM.Write[@cm.list.nModules, (cth.nControls + 1)]; FOR i: CARDINAL IN [0..cth.nControls) DO WITH cItem: cth.controls[i] SELECT FROM module => MBVM.Write[@cm.list.frames[i+1], mt[mtb[cItem.mti].gfi].frame]; config => MB.Error["Configurations in control lists aren't supported yet."L]; ENDCASE; ENDLOOP; cm.multiple _ TRUE; FOR c: BcdDefs.CTIndex _ ctb[cti].config, ctb[c].config UNTIL c = BcdDefs.CTNull DO depth _ depth + 1; ENDLOOP; }; maxDepth _ MAX[maxDepth, depth]; cmMap[lastConfig] _ CMMapItem[cti: cti, cm: cm, depth: depth]; lastConfig _ lastConfig + 1; RETURN[FALSE] }; IF bcd.nModules = 1 THEN { frame: PrincOps.GlobalFrameHandle _ mt[1].frame; MBVM.Write[@frame.global[0], PrincOps.NullControl]; RETURN }; cmMap _ MBStorage.Words[bcd.nConfigs * SIZE[CMMapItem]]; lastConfig _ 0; [] _ BcdOps.ProcessConfigs[bcd, EnterControlInfoForConfig]; FOR depth: CARDINAL DECREASING IN [0..maxDepth] DO FOR index: CARDINAL IN [0..lastConfig) DO list, listHead, oldCm: PrincOps.ControlModule; SetModulesControl: PROC [ mth: BcdOps.MTHandle, mti: BcdDefs.MTIndex] RETURNS [stop: BOOL] = { frame: PrincOps.GlobalFrameHandle _ mt[mth.gfi].frame; IF mth.config # cti THEN RETURN[FALSE]; IF MBVM.Read[@frame.global[0]] = PrincOps.NullControl THEN MBVM.Write[@frame.global[0], GetLink[cm]]; RETURN[FALSE] }; IF cmMap[index].depth # depth OR (cm _ cmMap[index].cm) = PrincOps.NullControl THEN LOOP; list _ cm; list.multiple _ FALSE; cti _ cmMap[index].cti; listHead _ SetLink[cm: cm, frame: MBVM.Read[@list.list.frames[1]]]; MBVM.Write[@list.list.frames[1], listHead]; -- restore old value FOR i: CARDINAL IN [2..ctb[cti].nControls+1) DO oldCm _ SetLink[cm: GetLink[listHead], frame: MBVM.Read[@list.list.frames[i]]]; MBVM.Write[@list.list.frames[i], oldCm]; ENDLOOP; [] _ BcdOps.ProcessModules[bcd, SetModulesControl]; ENDLOOP; ENDLOOP; FOR index: CARDINAL IN [0..lastConfig) DO parent: CARDINAL; list: PrincOps.ControlModule _ cmMap[index].cm; IF list = PrincOps.NullControl THEN LOOP; list.multiple _ FALSE; IF (cti _ ctb[cmMap[index].cti].config) = BcdDefs.CTNull THEN cm _ PrincOps.NullControl ELSE { FOR parent IN [0..lastConfig) DO IF cmMap[parent].cti = cti THEN EXIT ENDLOOP; cm _ GetLink[cmMap[parent].cm]; }; MBVM.Write[@list.list.frames[0], cm]; ENDLOOP; FOR i: CARDINAL IN [0..lastConfig) DO IF ctb[cmMap[i].cti].config = BcdDefs.CTNull THEN { cm _ GetLink[cmMap[i].cm]; EXIT}; ENDLOOP; MBStorage.FreeWords[cmMap]; }; AllocFault: PUBLIC ERROR = CODE; Alloc: PUBLIC PROC [fsi: CARDINAL] RETURNS [p: POINTER] = { DO p _ MBVM.Read[PrincOps.AV + fsi]; SELECT LOOPHOLE[p, CARDINAL] MOD 4 FROM 0 => EXIT; -- a free frame 1, 3 => ERROR AllocFault; 2 => fsi _ LOOPHOLE[p, CARDINAL]/4; -- use an fsi for larger frames ENDCASE; ENDLOOP; MBVM.Write[PrincOps.AV + fsi, MBVM.Read[p]]; RETURN[p] }; GetLink: PROC [ cm: PrincOps.ControlModule] RETURNS [--frame--PrincOps.ControlModule] = { list: PrincOps.ControlModule; DO -- search up backward pointers for the actual frame to start IF ~cm.multiple THEN RETURN[cm]; list _ cm; list.multiple _ FALSE; cm _ MBVM.Read[@list.list.frames[1]]; ENDLOOP; }; SetLink: PROC [cm: PrincOps.ControlModule, frame: PrincOps.GlobalFrameHandle] RETURNS [PrincOps.ControlModule] = { old: PrincOps.ControlModule = MBVM.Read[@frame.global[0]]; MBVM.Write[@frame.global[0], cm]; RETURN[IF old # PrincOps.NullControl THEN old ELSE [frame[frame]]] }; JustRelocateLinks: PROC [loadee: MB.BHandle] = { bcd: BcdOps.BcdBase = loadee.bcd; mt: MB.MT = loadee.mt; realLinks: LONG POINTER TO ARRAY [0..0) OF PrincOps.ControlLink = MBStorage.Pages[1]; RelocateLinksForModule: PROC [mth: BcdOps.MTHandle, mti: BcdDefs.MTIndex] RETURNS [BOOL] = { gfi: BcdDefs.GFTIndex = mth.gfi; frame: PrincOps.GlobalFrameHandle _ mt[gfi].frame; resolved: BOOL _ TRUE; virtualLinks: MBLoaderOps.VirtualLinks _ MBLoaderOps.GetVirtualLinks[loadee, mth]; IF LENGTH[virtualLinks] # 0 THEN { -- relocate external links FOR i: CARDINAL IN [0..LENGTH[virtualLinks]) DO link: BcdDefs.Link _ virtualLinks[i]; SELECT link.vtag FROM proc1, proc0 => IF link.gfi >= bcd.firstdummy THEN {resolved _ FALSE; realLinks[i] _ PrincOps.UnboundLink} ELSE realLinks[i] _ ConvertLink[link]; var => IF link.gfi >= bcd.firstdummy THEN {resolved _ FALSE; realLinks[i] _ PrincOps.NullLink} ELSE realLinks[i] _ ConvertVariableLink[link]; ENDCASE => {resolved _ FALSE; realLinks[i] _ PrincOps.NullLink}; ENDLOOP; MBLoaderOps.WriteLinks[loadee: loadee, mth: mth, links: realLinks]; }; FOR i: CARDINAL IN [gfi..gfi+mth.ngfi) DO info: PilotLoadStateFormat.ModuleInfo _ MBLoaderOps.GetModule[i]; info.resolved _ resolved; MBLoaderOps.EnterModule[i, info]; ENDLOOP; RETURN[FALSE] }; ConvertVariableLink: PROC [link: BcdDefs.Link] RETURNS [PrincOps.ControlLink] = { mth: BcdOps.MTHandle; frame: PrincOps.GlobalFrameHandle; gfi: BcdDefs.GFTIndex = link.gfi; evb: BcdDefs.Base = LOOPHOLE[bcd + bcd.evOffset]; vp: CARDINAL; [mth: mth, frame: frame] _ mt[gfi]; IF gfi >= bcd.firstdummy THEN RETURN[PrincOps.NullLink]; vp _ BcdDefs.VarLimit*(gfi - mth.gfi) + link.var; IF vp = 0 THEN RETURN[LOOPHOLE[frame]]; IF mth.variables = BcdDefs.EVNull THEN RETURN[PrincOps.NullLink] ELSE RETURN[LOOPHOLE[frame + evb[mth.variables].offsets[vp]]] }; MBLoaderOps.UpdateLoadState[FIRST[PilotLoadStateFormat.ConfigIndex], loadee]; [] _ BcdOps.ProcessModules[bcd, RelocateLinksForModule]; MBStorage.FreePages[realLinks]; }; ConvertLink: PROC [bl: BcdDefs.Link] RETURNS [PrincOps.ControlLink] = INLINE { RETURN[LOOPHOLE[bl]]}; END. "MBLoaderCore.mesa Last modified by Sandman on 6-Aug-81 15:41:04 Last modified by Lewis on 23-Sep-81 15:59:10 Last modified by Levin on April 13, 1983 4:36 pm There is some non-intuitive handling of the firstdummy field in the bcd header. If the bcd consists of a single module, it was probably generated by the Compiler. The Compiler sets the firstdummy field to an arbitrary value which is higher than the number of gfis needed to load the module. The ngfi field of the module table entry is the correct one to use. For a multi-module bcd (created by the Binder), bcd.firstdummy-1 is the number of gfis needed. The code below is intended to be the only place that this ugliness is known. The following is a hint, which is guaranteed big enough. (See comment above) allocate global frame record global frame handle in module table (mt) enter into GFT, and loadstate if not making germ initialize global frame gfi 0 in each input BCD is not used. Thus, gfiOffset is set one less than the first gfi actually allocated to us, since all subsequent indexing uses the 0-origin gfi's in the input BCD. control module information for each (sub)config in bcd list.frames[0] is bkwds pointer to cm for enclosing config (st. first) create subconfig# -> (subconfig & control module info) map list.frames[1]'s global[0] has ControlModule (possibly list) for config for each module, set global[0] to the actual cm frame for config for each config, set backwards pointer to cm frame for the enclosing config set "cm" to the actual cm frame for the outermost config Êá˜Jšœ™Jšœ2™2Jšœ,™,Jšœ0™0J˜šÏk ˜ šœœ˜J˜`—šœœ˜J˜f—Jšœœœ˜Jšœ œ˜ šœœ˜ Jšœoœ˜y—šœ œ˜J˜Ý—Jšœœœ.œ˜MJšœ œ&˜5Jšœœ%˜0Jšœœ@˜JJšœœ˜5šœ œ˜Jšœ{˜}—Jšœœ ˜ šœ œ˜J˜¥J˜——šœ˜šœ˜Jšœœ!œœ/˜m—Jšœœ˜J˜—Jš˜J˜Jšœœ˜J˜Jšœœ œ˜J˜JšÏnœœœœ˜8J˜šžœœœ˜!šœœœ˜0Jšœœ"˜,J˜šœœœ˜"J˜#J˜*J˜—Jšœ˜—Jšœ˜ Jšœ˜J˜J˜—šžœœœ˜Jšœœ˜#J˜šœœœ˜0Jšœœ"˜,Jšœœ˜Jšœœœ˜J˜)J˜'Jšœ˜!Jšœ˜Jšœ˜šœ9œœ˜EJšœ ˜Jšœ#˜(Jšœ˜Jšœœ˜Jšœ˜—J˜-J˜Jšœœ˜J˜8šœ œ˜šœœ ˜J˜2Jšœ=œ ˜MJ˜5—J˜*J˜J˜—˜˜Jšœ ˜Jšœ(œ˜HJšœœ˜Jš˜Jšœ˜—Jšœ˜—Jšœœœ œ˜LJ˜Jšœ'˜,J˜Jšœ'˜,J˜"Jšœ œ#œ˜RJšœ"˜&Jšœœ˜ Jšœ˜Jšœ˜—J˜J˜0Jšœœ˜%J˜8J˜0J˜$Jšœ$˜)Jšœ˜J˜—šžœœœ˜PJ˜Jšœœ˜J˜VJ˜4J˜$šœ$œÏcœœ˜NJ˜J˜Jšœœ˜ Jšœ˜—šœœ˜ J˜J˜'J˜4J˜—˜J˜——š žœœ œ œœ ˜LJšœ—™—Jšœœœœ ˜>šžœœ˜Jšœ,œœ˜DJ˜šœœœ˜1Jšœœœœ˜>Jšœ˜—Jšœœ˜ Jšœ˜—JšœM™MJšœ œ0˜FJšœœ˜ Jš œœœ œœ˜>J˜?Jšœ œœ˜0Jšœ˜J˜—šžœœœ œ ˜8šœœœœ˜Jšœœ˜'Jšœ œœ˜Jšœ˜—šœ˜J˜——šž œœ œ œ-˜[Jš˜J˜!Jšœœ˜Jšœœ˜Jšœ œ˜Jšœ œ˜Jšœ œ˜Jšœœ˜(Jšœ œ˜Jšœœœ˜šžœœ-˜FJšœœ˜Jšœœ˜1J˜Jšœœ˜šœœœ˜%J˜#Jšœ˜—šœœ˜,J˜&J˜JšœœŸœ˜T—šœœœ˜%J˜ Jšœ˜—Jšœœ˜ Jšœ˜—šž œœ˜-šœœœŸ˜DJ˜B—J˜Jšœœ˜6J˜Jšœ)œœ˜8Jšœœ˜ šœœœ+˜?J˜Jšœ˜—J˜˜!Jšœ2œ˜;—J˜Jšœœ˜ Jšœ˜J˜J˜—Jšœ6™6šœ œœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜J˜—šžœœ œ œ!˜XJ˜!Jšœœœ ˜Jšœœ˜1Jšœœ˜1Jš œœœœœŸœœ ˜@Jšœœ˜#J˜šžœœ˜!Jšœ,œœ˜DJ˜JšœœŸ,˜BJšœœ˜3šœ˜JšœF™F˜GJšœœ6˜HJšœ˜—Jšœ/˜3šœœœ˜(šœœ˜'Jšœ œ;˜IJšœ œA˜MJšœ˜—Jšœ˜—Jšœœ˜Jšœ5˜8šœ˜J˜Jš˜—Jšœ˜—Jšœ œ˜ J˜>J˜Jšœœ˜ Jšœ˜—šœœ˜J˜0Jšœ/˜3Jš˜Jšœ˜—Jšœ:™:Jšœ'œ ˜8J˜J˜;š œœ œœ˜2šœœœ˜)J˜.šžœœ˜Jšœ,œœ˜DJ˜6Jšœœœœ˜'šœœ/˜:Jšœ&˜*—Jšœœ˜ Jšœ˜—šœœ/˜SJšœ˜—J˜ Jšœœ˜J˜JšœG™GJšœ"œ˜CJšœ)Ÿ˜Ašœœœ˜/Jšœ.œ˜OJšœ$˜(Jšœ˜—Jšœ@™@J˜3Jšœ˜—Jšœ˜—JšœK™Kšœœœ˜)Jšœœ˜J˜/Jšœœœ˜)Jšœœ˜šœ7œ˜>J˜—šœ˜Jšœœœœœœœ˜NJ˜J˜—Jšœ!˜%Jšœ˜—Jšœ8™8šœœœ˜%šœ+œ˜4Jšœœ˜"—Jšœ˜—J˜Jšœ˜J˜—Jšœ œœœ˜ J˜š žœœœœœœ˜;š˜Jšœœœ˜!š œœœœ˜'JšœœŸ˜Jšœœ ˜Jšœ œœŸ˜DJšœ˜—Jšœ˜—Jšœœœ ˜,Jšœ˜ Jšœ˜J˜—šžœœ˜JšœœŸ œ˜IJ˜šœŸ<˜@Jšœœœ˜ J˜ Jšœœ˜Jšœœ˜%Jš˜—šœ˜J˜——šžœœA˜NJšœ˜$Jšœœ˜:Jšœ˜!Jšœœœœ˜BJšœ˜J˜—šžœœ œ ˜0J˜!Jšœœœ ˜Jš œ œœœœœ+˜Ušžœœ-˜IJšœœ˜J˜ J˜2Jšœ œœ˜J˜RšœœœŸ˜>š œœœœ˜/J˜%šœ ˜˜šœ˜"Jšœ œ'˜8—Jšœ"˜&—˜šœ˜"Jšœ œ$˜5—Jšœ*˜.—Jšœœ%˜A—Jšœ˜—J˜CJ˜—šœœœ˜)J˜AJ˜J˜!Jšœ˜—Jšœœ˜ Jšœ˜—šžœœœ˜QJ˜J˜"J˜!Jšœœ˜1Jšœœ˜ J˜#Jšœœœ˜8J˜1Jšœœœœ ˜'Jšœ œœ˜@Jšœœœ)˜=Jšœ˜—Jšœœ,˜MJ˜8J˜Jšœ˜J˜—šž œœœœ˜NJšœœ˜J˜—Jšœ˜J˜—…—?W