DIRECTORY AMModel USING [ParentSection, Section, SectionClass, SectionName, SectionSource, Source, SourceObj], AMModelLocation USING [CodeLocation, EntryLocations], AMViewerOps USING [ReportProc, SectionFromSelection, ViewerFromSection], BackStop USING [Call], BasicTime USING [GetClockPulses, Pulses, PulsesToMicroseconds], Commander USING [CommandProc, Register], FastBreak USING [ClearFastBreak, FastBreakId, SetFastBreak], IO USING [PutFR], Menus USING [AppendMenuEntry, CreateEntry, CreateMenu, Menu, MenuProc], MessageWindow USING [Append], NumberLabels USING [CreateNumber, NumberLabel, NumberLabelUpdate], PrincOps USING [BytePC, FrameCodeBase], Process USING [Detach, Milliseconds, MsecToTicks, SetTimeout], Rope USING [Cat, ROPE], ViewerOps USING [ChangeColumn, ComputeColumn, PaintViewer, SetMenu, SetOpenHeight], VTables USING [Create, ExchangeRows, GetTableEntry, Install, NullBorder, SetRowsAndColumns, SetTableEntry, VTable]; Celtics: CEDAR MONITOR IMPORTS AMModel, AMModelLocation, AMViewerOps, BackStop, BasicTime, Commander, FastBreak, IO, Menus, MessageWindow, NumberLabels, Process, Rope, ViewerOps, VTables = BEGIN BytePC: TYPE = PrincOps.BytePC; CARD: TYPE = LONG CARDINAL; CodeLocation: TYPE = AMModelLocation.CodeLocation; CodeLocationList: TYPE = LIST OF CodeLocation; FrameCodeBase: TYPE = PrincOps.FrameCodeBase; ROPE: TYPE = Rope.ROPE; Section: TYPE = AMModel.Section; Source: TYPE = AMModel.Source; SourceObj: TYPE = AMModel.SourceObj; BaseData: TYPE = REF BaseDataRep; BaseDataRep: TYPE = RECORD [ vtab: VTables.VTable _ NIL, head: EachData _ NIL, changeCond: CONDITION, timeCond: CONDITION, locked: BOOL _ FALSE, rows: NAT _ 0, cols: NAT _ limitCol]; EachData: TYPE = REF EachDataRep; EachDataRep: TYPE = RECORD [ next: EachData _ NIL, isTotal: BOOL _ FALSE, lastCount: INT _ 0, -- last count displayed id: FastBreak.FastBreakId _ NIL]; setCol: NAT = 0; clearCol: NAT = 1; countCol: NAT = 2; codeCol: NAT = 3; pcCol: NAT = 4; posCol: NAT = 5; nameCol: NAT = 6; limitCol: NAT = 7; UpdateDisplayProcess: PROC = TRUSTED { vtab: VTables.VTable _ VTables.Create[rows: 1, columns: limitCol, name: "Celtics", x: 0, y: 2]; data: BaseData _ NEW[BaseDataRep]; pulses: BasicTime.Pulses _ BasicTime.GetClockPulses[]; menu: Menus.Menu _ Menus.CreateMenu[]; inner: PROC [data: BaseData] = TRUSTED { newPulses: BasicTime.Pulses _ BasicTime.GetClockPulses[]; inverseSecs: REAL; deltaMicros: CARD _ BasicTime.PulsesToMicroseconds[newPulses] - BasicTime.PulsesToMicroseconds[pulses]; each: EachData _ data.head; lag: EachData _ NIL; index: NAT _ 1; changed: BOOL _ FALSE; newRows: NAT _ data.rows; subTotal, grandTotal: INT _ 0; IF deltaMicros < 100 THEN RETURN; inverseSecs _ 1E6 / deltaMicros; pulses _ newPulses; WHILE NOT vtab.destroyed AND each # NIL DO id: FastBreak.FastBreakId _ each.id; next: EachData _ each.next; SELECT TRUE FROM each.isTotal => { nl: NumberLabels.NumberLabel _ VTables.GetTableEntry[vtab, index, countCol]; current: INT _ subTotal; last: INT _ each.lastCount; index _ index + 1; lag _ each; IF nl # NIL AND current # last THEN { each.lastCount _ current; NumberLabels.NumberLabelUpdate[nl, each.lastCount]; }; subTotal _ 0; }; id = NIL => { changed _ TRUE; FOR i: NAT IN [index+1..data.rows) DO VTables.ExchangeRows[vtab, i, i-1]; ENDLOOP; IF lag = NIL THEN data.head _ next ELSE lag.next _ next; }; ENDCASE => { nl: NumberLabels.NumberLabel _ VTables.GetTableEntry[vtab, index, countCol]; current: INT _ id^; last: INT _ each.lastCount; index _ index + 1; lag _ each; subTotal _ subTotal + current; grandTotal _ grandTotal + current; IF nl # NIL AND current # last THEN { each.lastCount _ current; NumberLabels.NumberLabelUpdate[nl, each.lastCount]; }; }; each _ next; ENDLOOP; IF NOT vtab.parent.iconic THEN NumberLabels.NumberLabelUpdate[VTables.GetTableEntry[vtab, 0, countCol], grandTotal]; IF changed THEN InstallNewRows[data, index]; }; data.vtab _ vtab; Menus.AppendMenuEntry[menu, Menus.CreateEntry[ name: "Set", proc: SetFastBreak, clientData: data]]; Menus.AppendMenuEntry[menu, Menus.CreateEntry[ name: "Clear *", proc: ClearAll, clientData: data]]; Menus.AppendMenuEntry[menu, Menus.CreateEntry[ name: "Reset *", proc: ResetAllCounts, clientData: data]]; Menus.AppendMenuEntry[menu, Menus.CreateEntry[ name: "AddSubTotal", proc: AddSubTotal, clientData: data]]; VTables.SetTableEntry[ table: vtab, row: 0, column: countCol, flavor: $Viewer, clientData: NumberLabels.CreateNumber[info: [parent: vtab], chars: 9, paint: FALSE], useMaxSize: TRUE]; ViewerOps.ChangeColumn[vtab.parent, left]; ViewerOps.SetMenu[vtab.parent, menu, FALSE]; InstallNewRows[data, 1]; SetPause[data]; UNTIL WaitForChange[data] DO ENABLE ABORTED => EXIT; DoUnderLock[data, inner]; ENDLOOP; DoUnderLock[data, innerClearAll]; InstallNewRows[data, 0]; }; AddSubTotal: Menus.MenuProc = TRUSTED { DoUnderLock[clientData, innerAddSubTotal]; }; innerAddSubTotal: PROC [data: BaseData] = { vtab: VTables.VTable = data.vtab; eachData: EachData _ NEW[EachDataRep]; row: NAT = data.rows; eachData.isTotal _ TRUE; IF data.head = NIL THEN data.head _ eachData ELSE FOR each: EachData _ data.head, each.next DO IF each.next = NIL THEN {each.next _ eachData; EXIT}; ENDLOOP; InstallNewRows[data, row + 1]; VTables.SetTableEntry[ table: vtab, row: row, column: clearCol, name: "clear", proc: ClearBreak, clientData: eachData, useMaxSize: TRUE]; VTables.SetTableEntry[ table: vtab, row: row, column: countCol, flavor: $Viewer, clientData: NumberLabels.CreateNumber[info: [parent: vtab], chars: 9, paint: FALSE], useMaxSize: TRUE]; VTables.SetTableEntry[ table: vtab, row: row, column: nameCol, flavor: $Text, name: "subTotal", proc: NIL, clientData: eachData, useMaxSize: TRUE]; VTables.Install[vtab]; }; ClarkKent: AMViewerOps.ReportProc = { MessageWindow.Append[msg, TRUE]; }; SetFastBreak: Menus.MenuProc = { DoUnderLock[clientData, innerSetFastBreak]; }; innerSetFastBreak: PROC [data: BaseData] = { stage: ROPE _ "Can't do it, "; inner: PROC = TRUSTED { section: Section _ NIL; source: Source _ NIL; locationList: CodeLocationList _ NIL; vtab: VTables.VTable = data.vtab; row: NAT _ data.rows; pos: INT; parent: Section; parentName: ROPE; section _ AMViewerOps.SectionFromSelection[].section; parent _ section; IF AMModel.SectionClass[section] = statement THEN parent _ AMModel.ParentSection[section]; parentName _ AMModel.SectionName[parent]; IF AMModel.SectionClass[parent] = proc THEN { DO parent _ AMModel.ParentSection[parent]; IF AMModel.SectionClass[parent] # proc THEN EXIT; ENDLOOP; parentName _ Rope.Cat[AMModel.SectionName[parent], ".", parentName]; }; source _ AMModel.SectionSource[section]; WITH source SELECT FROM entire: REF SourceObj[entire] => pos _ -1; field: REF SourceObj[field] => { pos _ field.firstCharIndex; [] _ AMViewerOps.ViewerFromSection[section, ClarkKent]; }; ENDCASE; locationList _ AMModelLocation.EntryLocations[section].list; IF locationList = NIL THEN { MessageWindow.Append["No such locations found!", TRUE]; RETURN; }; FOR locList: CodeLocationList _ locationList, locList.rest UNTIL locList = NIL DO loc: CodeLocation = locList.first; code: FrameCodeBase _ loc.codeBase; pc: BytePC = loc.pc; eachData: EachData; code.out _ FALSE; -- Because nobody expects the Spanish Inquisition! eachData _ NEW[EachDataRep _ [id: FastBreak.SetFastBreak[code.longbase, pc]]]; IF data.head = NIL THEN data.head _ eachData ELSE FOR each: EachData _ data.head, each.next DO IF each.next = NIL THEN {each.next _ eachData; EXIT}; ENDLOOP; MessageWindow.Append["Counting break set in ", TRUE]; MessageWindow.Append[parentName]; InstallNewRows[data, row + 1]; VTables.SetTableEntry[ table: vtab, row: row, column: setCol, name: "reset", proc: ResetCount, clientData: eachData, useMaxSize: TRUE]; VTables.SetTableEntry[ table: vtab, row: row, column: clearCol, name: "clear", proc: ClearBreak, clientData: eachData, useMaxSize: TRUE]; VTables.SetTableEntry[ table: vtab, row: row, column: countCol, flavor: $Viewer, clientData: NumberLabels.CreateNumber[info: [parent: vtab], chars: 9, paint: FALSE], useMaxSize: TRUE]; VTables.SetTableEntry[ table: vtab, row: row, column: codeCol, flavor: $Text, name: IO.PutFR["%bB", [cardinal[LOOPHOLE[code]]]], useMaxSize: TRUE]; VTables.SetTableEntry[ table: vtab, row: row, column: pcCol, flavor: $Text, name: IO.PutFR["%bB", [cardinal[pc]]], useMaxSize: TRUE]; VTables.SetTableEntry[ table: vtab, row: row, column: posCol, flavor: $Text, name: IO.PutFR["%d", [integer[pos]]], useMaxSize: TRUE]; VTables.SetTableEntry[ table: vtab, row: row, column: nameCol, flavor: $Text, name: parentName, useMaxSize: TRUE]; row _ row + 1; ENDLOOP; VTables.Install[vtab]; }; msg: ROPE _ BackStop.Call[inner]; IF msg # NIL THEN { MessageWindow.Append[stage, TRUE]; MessageWindow.Append[msg]; MessageWindow.Append["."]; }; }; ClearAll: Menus.MenuProc = { DoUnderLock[clientData, innerClearAll]; }; innerClearAll: PROC [data: BaseData] = { vtab: VTables.VTable = data.vtab; FOR each: EachData _ data.head, each.next WHILE each # NIL DO IF each.id # NIL THEN TRUSTED { [] _ FastBreak.ClearFastBreak[each.id]; each.id _ NIL; }; each.isTotal _ FALSE; ENDLOOP; }; ClearBreak: Menus.MenuProc = { WITH clientData SELECT FROM each: EachData => TRUSTED { id: FastBreak.FastBreakId = each.id; IF id # NIL THEN {each.id _ NIL; [] _ FastBreak.ClearFastBreak[id]}; each.isTotal _ FALSE; }; ENDCASE; }; ResetCount: Menus.MenuProc = TRUSTED { WITH clientData SELECT FROM each: EachData => { id: FastBreak.FastBreakId = each.id; IF id # NIL THEN id^ _ 0; }; ENDCASE; }; ResetAllCounts: Menus.MenuProc = { DoUnderLock[clientData, innerResetAllCounts]; }; innerResetAllCounts: PROC [data: BaseData] = TRUSTED { vtab: VTables.VTable = data.vtab; FOR each: EachData _ data.head, each.next WHILE each # NIL DO IF each.id # NIL THEN each.id^ _ 0; ENDLOOP; }; fudge: NAT _ 20; InstallNewRows: PROC [data: BaseData, rows: NAT] = TRUSTED { IF data # NIL THEN { vtab: VTables.VTable _ data.vtab; IF vtab # NIL AND NOT vtab.destroyed AND rows # data.rows THEN { parent: VTables.VTable _ vtab.parent; smaller: BOOL _ rows < data.rows; IF rows = 0 THEN data.cols _ 0; VTables.SetRowsAndColumns[vtab, data.rows _ rows, data.cols]; SELECT rows FROM 0 => {}; 1 => { VTables.SetTableEntry[ table: vtab, column: codeCol, name: NIL, border: VTables.NullBorder]; VTables.SetTableEntry[ table: vtab, column: pcCol, name: NIL, border: VTables.NullBorder]; VTables.SetTableEntry[ table: vtab, column: posCol, name: NIL, border: VTables.NullBorder]; VTables.SetTableEntry[ table: vtab, column: nameCol, name: NIL, border: VTables.NullBorder]; }; 2 => { VTables.SetTableEntry[ table: vtab, column: codeCol, name: "code", border: VTables.NullBorder]; VTables.SetTableEntry[ table: vtab, column: pcCol, name: "pc", border: VTables.NullBorder]; VTables.SetTableEntry[ table: vtab, column: posCol, name: "pos", border: VTables.NullBorder]; VTables.SetTableEntry[ table: vtab, column: nameCol, name: "name", border: VTables.NullBorder]; }; ENDCASE; VTables.Install[vtab, FALSE]; ViewerOps.SetOpenHeight[parent, vtab.wh + fudge]; IF NOT parent.iconic THEN { ViewerOps.ComputeColumn[parent.column]; IF smaller THEN ViewerOps.PaintViewer[parent, all, TRUE, NIL]; }; }}; }; WaitForChange: ENTRY PROC [data: BaseData] RETURNS [quit: BOOL] = TRUSTED { ENABLE UNWIND => NULL; vtab: VTables.VTable = data.vtab; WAIT data.timeCond; RETURN [vtab.destroyed]; }; SetPause: PROC [data: BaseData, pause: Process.Milliseconds _ 1000] = TRUSTED { ENABLE UNWIND => NULL; Process.SetTimeout[@data.timeCond, Process.MsecToTicks[pause]]; }; AcquireLock: ENTRY PROC [data: BaseData] = TRUSTED { ENABLE UNWIND => NULL; WHILE data.locked DO WAIT data.changeCond; ENDLOOP; data.locked _ TRUE; }; ReleaseLock: ENTRY PROC [data: BaseData] = TRUSTED { ENABLE UNWIND => NULL; data.locked _ FALSE; BROADCAST data.changeCond; }; DoUnderLock: PROC [ref: REF, inner: PROC [data: BaseData]] = TRUSTED { WITH ref SELECT FROM data: BaseData => { ENABLE UNWIND => ReleaseLock[data]; AcquireLock[data]; inner[data]; ReleaseLock[data]; }; ENDCASE; }; StartCeltics: Commander.CommandProc = TRUSTED { Process.Detach[FORK UpdateDisplayProcess[]]; }; Commander.Register["Celtics", StartCeltics, "is a tool to take counts of fast breaks."]; END. ,Celtics.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Russ Atkinson (RRA) June 24, 1985 8:48:34 pm PDT T Y P E S update the count Update event count remove the row from the table update the count Update event count PROC [parent: REF ANY, clientData: REF ANY _ NIL, mouseButton: MouseButton _ red, shift, control: BOOL _ FALSE] [msg: ROPE, severity: Severity] PROC [parent: REF ANY, clientData: REF ANY _ NIL, mouseButton: MouseButton _ red, shift, control: BOOL _ FALSE] try to find the module name as well PROC [parent: REF ANY, clientData: REF ANY _ NIL, mouseButton: MouseButton _ red, shift, control: BOOL _ FALSE] PROC [parent: REF ANY, clientData: REF ANY _ NIL, mouseButton: MouseButton _ red, shift, control: BOOL _ FALSE] PROC [parent: REF ANY, clientData: REF ANY _ NIL, mouseButton: MouseButton _ red, shift, control: BOOL _ FALSE] PROC [parent: REF ANY, clientData: REF ANY _ NIL, mouseButton: MouseButton _ red, shift, control: BOOL _ FALSE] WaitForChange waits until there is a change to some value, then gets the lock for us. Κp˜codešœ ™ Kšœ Οmœ1™Kšœžœžœ˜Kšœ žœD˜SKšœžœf˜sK˜—šœ žœž˜Kšžœœ˜£Kšœž˜K˜—šœ ™ K˜Kšœžœ˜Kšžœžœžœžœ˜Kšœžœ ˜2Kšœžœžœžœ˜.Kšœžœ˜-Kšžœžœžœ˜Kšœ žœ˜ Kšœžœ˜Kšœ žœ˜$K˜Kšœ žœžœ ˜!šœ žœžœ˜Kšœžœ˜Kšœžœ˜Kšœ ž œ˜Kšœ ž œ˜Kšœž œ˜Kšœžœ˜Kšœžœ ˜K˜—Kšœ žœžœ ˜!šœ žœžœ˜Kšœžœ˜Kšœ žœžœ˜Kšœ žœΟc˜+Kšœžœ˜!K˜—Kšœžœ˜Kšœ žœ˜Kšœ žœ˜Kšœ žœ˜Kšœžœ˜Kšœžœ˜Kšœ žœ˜Kšœ žœ˜K˜—šΟnœžœžœ˜&Kšœ_˜_Kšœžœ˜"Kšœ6˜6Kšœ&˜&šœžœžœ˜(Kšœ9˜9Kšœ žœ˜šœ žœ˜KšœS˜S—Kšœ˜Kšœžœ˜Kšœžœ˜Kšœ žœžœ˜Kšœ žœ ˜Kšœžœ˜Kšžœžœžœ˜!Kšœ ˜ Kšœ˜š žœžœžœžœž˜*Kšœ$˜$Kšœ˜šžœžœž˜šœ˜Kšœ™KšœL˜LKšœ žœ ˜Kšœžœ˜K˜K˜ šžœžœžœžœ˜%Kšœ™Kšœ˜Kšœ3˜3K˜—Kšœ ˜ K˜—šœžœ˜ Kšœ™Kšœ žœ˜šžœžœžœž˜%Kšœ#˜#Kšžœ˜—Kšžœžœžœžœ˜8K˜—šžœ˜ Kšœ™KšœL˜LKšœ žœ˜Kšœžœ˜K˜K˜ Kšœ˜Kšœ"˜"šžœžœžœžœ˜%Kšœ™Kšœ˜Kšœ3˜3K˜—K˜——Kšœ ˜ Kšžœ˜—šžœžœž˜KšœU˜U—Kšžœ žœ˜,Kšœ˜—Kšœ˜šœ.˜.Kšœ4˜4—šœ.˜.Kšœ4˜4—šœ.˜.Kšœ:˜:—šœ.˜.Kšœ;˜;—šœ˜Kšœ7˜7KšœMžœ˜TKšœ žœ˜—Kšœ*˜*Kšœ%žœ˜,Kšœ˜K˜šžœž˜Kšžœžœžœ˜Kšœ˜Kšžœ˜—Kšœ!˜!Kšœ˜K˜K˜—šœžœ˜'š žœ žœžœžœžœžœ™1Kšœ0žœžœ™=—Kšœ*˜*K˜K˜—šœžœ˜+Kšœ!˜!Kšœžœ˜&Kšœžœ ˜Kšœžœ˜šžœ ž˜Kšžœ˜šž˜šžœ'ž˜,Kšžœ žœžœžœ˜5Kšžœ˜———Kšœ˜šœ˜Kšœ(˜(Kšœ6˜6Kšœ žœ˜—šœ˜Kšœ9˜9KšœMžœ˜TKšœ žœ˜—šœ˜Kšœ6˜6Kšœžœ˜2Kšœ žœ˜—Kšœ˜K˜K˜—šœ%˜%Kšœ™Kšœžœ˜ Kšœ˜K˜—šœ ˜ š žœ žœžœžœžœžœ™1Kšœ0žœžœ™=—Kšœ+˜+K˜K˜—šœžœ˜,Kšœžœ˜šœžœžœ˜Kšœžœ˜Kšœžœ˜Kšœ!žœ˜%Kšœ!˜!Kšœžœ ˜Kšœžœ˜ Kšœ˜Kšœ žœ˜Kšœ5˜5Kšœ˜šžœ+ž˜1Kšœ(˜(—Kšœ)˜)šžœ%žœ˜-Kšœ#™#šž˜Kšœ'˜'Kšžœ%žœžœ˜1Kšžœ˜—KšœD˜DKšœ˜—Kšœ(˜(šžœžœž˜Kšœžœ˜*šœžœ˜ Kšœ˜Kšœ7˜7K˜—Kšžœ˜—Kšœ<˜<šžœžœžœ˜Kšœ1žœ˜7Kšžœ˜Kšœ˜—šžœ8žœ žœž˜QKšœ"˜"Kšœ#˜#Kšœ˜Kšœ˜Kšœ žœŸ2˜EKšœ žœ@˜Nšžœ ž˜Kšžœ˜šž˜šžœ'ž˜,Kšžœ žœžœžœ˜5Kšžœ˜———Kšœ/žœ˜5Kšœ!˜!Kšœ˜šœ˜Kšœ&˜&Kšœ6˜6Kšœ žœ˜—šœ˜Kšœ(˜(Kšœ6˜6Kšœ žœ˜—šœ˜Kšœ9˜9KšœMžœ˜TKšœ žœ˜—šœ˜Kšœ6˜6Kšœžœžœ ˜2Kšœ žœ˜—šœ˜Kšœ4˜4Kšœžœ˜&Kšœ žœ˜—šœ˜Kšœ5˜5Kšœžœ˜%Kšœ žœ˜—šœ˜Kšœ6˜6Kšœ˜Kšœ žœ˜—Kšœ˜Kšžœ˜—Kšœ˜K˜—Kšœžœ˜!šžœžœžœ˜Kšœžœ˜"Kšœ˜Kšœ˜K˜—K˜—K˜šœ˜š žœ žœžœžœžœžœ™1Kšœ0žœžœ™=—Kšœ'˜'K˜K˜—šœžœ˜(Kšœ!˜!šžœ'žœžœž˜=šžœ žœžœžœ˜Kšœ'˜'Kšœ žœ˜K˜—Kšœžœ˜Kšžœ˜—K˜K˜—šœ˜š žœ žœžœžœžœžœ™1Kšœ0žœžœ™=—šžœ žœž˜šœžœ˜Kšœ$˜$Kšžœžœžœ žœ%˜DKšœžœ˜K˜—Kšžœ˜—K˜K˜—šœžœ˜&š žœ žœžœžœžœžœ™1Kšœ0žœžœ™=—šžœ žœž˜šœ˜Kšœ$˜$Kšžœžœžœ ˜K˜—Kšžœ˜—K˜K˜—šœ"˜"š žœ žœžœžœžœžœ™1Kšœ0žœžœ™=—Kšœ-˜-K˜K˜—šœžœžœ˜6Kšœ!˜!šžœ'žœžœž˜=Kšžœ žœžœ˜#Kšžœ˜—K˜K˜—Kšœžœ˜š œžœžœžœ˜<šžœžœžœ˜Kšœ!˜!š žœžœžœžœžœžœ˜@Kšœ%˜%Kšœ žœ˜!Kšžœ žœ˜Kšœ=˜=šžœž˜K˜˜šœ˜Kšœ$žœ˜E—šœ˜Kšœ"žœ˜C—šœ˜Kšœ#žœ˜D—šœ˜Kšœ$žœ˜E—K˜—šœ˜šœ˜KšœH˜H—šœ˜KšœD˜D—šœ˜KšœF˜F—šœ˜KšœH˜H—K˜—Kšžœ˜—Kšœžœ˜Kšœ1˜1šžœžœžœ˜Kšœ'˜'Kšžœ žœ$žœžœ˜>K˜—K˜——K˜K˜—š   œžœžœžœžœžœ˜KKšœU™UKšžœžœžœ˜Kšœ!˜!Kšžœ˜Kšžœ˜K˜K˜—š œžœ8žœ˜OKšžœžœžœ˜Kšœ?˜?K˜K˜—š  œžœžœžœ˜4Kšžœžœžœ˜Kšžœ žœžœžœ˜3Kšœžœ˜K˜K˜—š  œžœžœžœ˜4Kšžœžœžœ˜Kšœžœ˜Kšž œ˜K˜K˜—š   œžœžœ žœžœ˜Fšžœžœž˜šœ˜Kšžœžœ˜#Kšœ˜Kšœ ˜ Kšœ˜K˜—Kšžœ˜—K˜—K˜šœ&žœ˜/Kšœžœ˜,Kšœ˜—K˜šœX˜XK˜—Kšžœ˜—…—/ΤDp