DIRECTORY Atom, Basics, BasicTime, Commander, CommandTool, Convert, FileSets, FS, IO, Misp, Rope, TextReplace, ViewerClasses, ViewerTools; FileCmdsImpl: CEDAR PROGRAM IMPORTS Atom, Commander, CommandTool, Convert, FileSets, FS, IO, Misp, Rope, TextReplace ={OPEN FileSets; Command: TYPE = REF CommandRep; CommandRep: TYPE = RECORD [ cmdData: REF ANY, Start: PROC [instance: Instance] _ NIL, HandleSwitch: PROC [instance: Instance, switch: ROPE] RETURNS [handled: BOOL] _ NIL, HandleArg: PROC [instance: Instance] RETURNS [handled: BOOL] _ NIL, AfterParse: PROC [instance: Instance], PerFile: PROC [instance: Instance, fn: FileNote], Finish: PROC [instance: Instance] RETURNS [result: REF ANY, msg: ROPE] _ NIL, usage: ROPE ]; Instance: TYPE = REF InstanceRep; InstanceRep: TYPE = RECORD [ cmd: Commander.Handle, of: Command, cls: STREAM, argCount, misses, subFailures: INT _ 0, setAsAny: REF ANY _ NIL, set: FileSet _ NIL, ids: IdentificationScheme _ [], touchy: BOOL _ TRUE, createdNeeded: BOOL _ FALSE, data: REF ANY _ NIL]; fcEnv: Misp.Environment _ NIL; idsKey: ATOM _ $FileSetsIdentificationScheme; Generic: PROC [cmd: Commander.Handle] RETURNS [result: REF ANY _ NIL, msg: ROPE _ NIL] --Commander.CommandProc-- = { AddMsg: PROC [more: ROPE] = {IF msg = NIL THEN msg _ more ELSE msg _ msg.Cat["; ", more]}; command: Command _ NARROW[cmd.procData.clientData]; cls: STREAM _ IO.RIS[cmd.commandLine]; instance: Instance _ NEW [InstanceRep _ [cmd, command, cls]]; DoIt: PROC [fn: FileNote] --FileConsumer-- = { created: GMT _ GetCreated[fn]; IF instance.createdNeeded AND created = noGMT THEN { cmd.err.PutF["Couldn't get a create time for %g\n", IO.rope[fn.id.name]]; instance.subFailures _ instance.subFailures + 1; } ELSE { command.PerFile[instance, fn]; }; }; IF command.Start # NIL THEN command.Start[instance]; FOR i: INT _ cls.SkipWhitespace[], cls.SkipWhitespace[] WHILE NOT cls.EndOf[] DO IF cls.PeekChar = '- THEN { switch: ROPE _ cls.GetTokenRope[MyBreak].token; IF switch.Equal["-askFS", FALSE] THEN instance.ids.askFS _ TRUE ELSE IF switch.Equal["-withoutServer", FALSE] THEN instance.ids.server _ FALSE ELSE IF switch.Equal["-withServer", FALSE] THEN instance.ids.server _ TRUE ELSE IF switch.Equal["-withoutDirectory", FALSE] THEN instance.ids.directory _ FALSE ELSE IF switch.Equal["-withDirectory", FALSE] THEN instance.ids.directory _ TRUE ELSE IF switch.Equal["-withoutVersion", FALSE] THEN instance.ids.version _ FALSE ELSE IF switch.Equal["-withVersion", FALSE] THEN instance.ids.version _ TRUE ELSE IF switch.Equal["-withoutCreate", FALSE] THEN instance.ids.create _ FALSE ELSE IF switch.Equal["-withCreate", FALSE] THEN instance.ids.create _ TRUE ELSE IF switch.Equal["-touchy", FALSE] THEN instance.touchy _ TRUE ELSE IF switch.Equal["-tough", FALSE] THEN instance.touchy _ FALSE ELSE IF command.HandleSwitch = NIL OR NOT command.HandleSwitch[instance, switch] THEN GOTO CmdSyntaxErr; } ELSE { ENABLE IO.Error => IF ec = SyntaxError THEN { result _ $Failure; msg _ IO.PutFR["Syntax error while parsing %g'th argument", IO.int[instance.argCount + 1]]; GOTO GiveUp --because the turkey language won't let us simply RETURN from catch phrases }; SELECT TRUE FROM command.HandleArg = NIL => { SELECT instance.argCount FROM 0 => instance.setAsAny _ instance.cls.GetRefAny[]; ENDCASE => GOTO CmdSyntaxErr; }; command.HandleArg # NIL => { IF NOT command.HandleArg[instance] THEN GOTO CmdSyntaxErr; }; ENDCASE => ERROR; instance.argCount _ instance.argCount + 1; }; REPEAT CmdSyntaxErr => RETURN [$Failure, command.usage]; ENDLOOP; IF instance.setAsAny = NIL THEN RETURN [$Failure, command.usage]; {ENABLE { Miss => { cmd.err.PutF["Failed to identify %g", IO.rope[name]]; IF created # noGMT THEN cmd.err.PutF[" of %g", IO.time[created]]; cmd.err.PutRope["\n"]; instance.misses _ instance.misses + 1; RESUME; }; Warning => { cmd.err.PutRope[message]; cmd.err.PutRope["\n"]; RESUME; }; Error => { result _ $Failure; AddMsg[message]; GOTO GiveUp; }; }; ans: REF ANY; IF command.AfterParse # NIL THEN command.AfterParse[instance]; Misp.Bind[idsKey, NEW [IdentificationScheme _ instance.ids], fcEnv, TRUE]; ans _ Misp.Eval[instance.setAsAny, fcEnv, NIL]; WITH ans SELECT FROM fs: FileSet => instance.set _ fs; ENDCASE => RETURN [$Failure, IO.PutFR["Expression yielded %g, instead of a FileSet", IO.refAny[ans]]]; IF instance.misses = 0 OR NOT instance.touchy THEN EnumSet[instance.set, DoIt]; }; IF instance.subFailures > 0 OR (instance.touchy AND instance.misses > 0) THEN RETURN [$Failure, IO.PutFR["%g files missed and %g command(s) failed", IO.int[instance.misses], IO.int[instance.subFailures]]]; IF command.Finish # NIL THEN [result, msg] _ command.Finish[instance]; cmd.out.PutF["%g files total\n", IO.rope[instance.set.summary]]; EXITS GiveUp => RETURN; }; MyBreak: PROC [char: CHAR] RETURNS [cc: IO.CharClass] --IO.BreakProc-- = { cc _ IF char IN ['\000 .. ' ] THEN sepr ELSE other; }; CmdPerFile: TYPE = REF CmdPerFileRep; CmdPerFileRep: TYPE = RECORD [ pattern: ROPE _ NIL]; StartCmdPerFile: PROC [instance: Instance] = { cpf: CmdPerFile _ NEW [CmdPerFileRep _ []]; instance.data _ cpf}; HandleCmdPerFileArg: PROC [instance: Instance] RETURNS [handled: BOOL] = { cpf: CmdPerFile _ NARROW[instance.data]; SELECT instance.argCount FROM 0 => cpf.pattern _ instance.cls.GetRopeLiteral[]; 1 => instance.setAsAny _ instance.cls.GetRefAny[]; ENDCASE => RETURN [FALSE]; handled _ TRUE}; AfterCmdPerFileParse: PROC [instance: Instance] = { cpf: CmdPerFile _ NARROW[instance.data]; instance.createdNeeded _ cpf.pattern.Find[""] > 0; }; PerCmdPerFileFile: PROC [instance: Instance, fn: FileNote] = { cpf: CmdPerFile = NARROW[instance.data]; createdR: ROPE = IF instance.createdNeeded THEN Convert.RopeFromTime[GetCreated[fn]] ELSE "??"; commandLine: ROPE = DoReplacements[cpf.pattern, fn, createdR]; thisResult: REF ANY; thisResult _ CommandTool.DoCommand[commandLine: commandLine, parent: instance.cmd]; IF thisResult = $Failure THEN instance.subFailures _ instance.subFailures + 1; }; cmdPerFile: Command _ NEW [CommandRep _ [ cmdData: NIL, Start: StartCmdPerFile, HandleArg: HandleCmdPerFileArg, AfterParse: AfterCmdPerFileParse, PerFile: PerCmdPerFileFile, usage: "Usage: CmdPerFile {-withServer|-withoutServer|-withDirectory|-withoutDirectory|-withVersion|-withoutVersion|-withCreate|-withoutCreate|-askFS|-touchy|-tough}* || {\"command pattern\" fileSetExpression}"]]; CmdAllFiles: TYPE = REF CmdAllFilesRep; CmdAllFilesRep: TYPE = RECORD [ prefix, perFile, infix, postfix, commandLine: ROPE _ NIL, first: BOOL _ TRUE]; StartCmdAllFiles: PROC [instance: Instance] = { caf: CmdAllFiles _ NEW [CmdAllFilesRep _ []]; instance.data _ caf}; HandleCmdAllFilesArg: PROC [instance: Instance] RETURNS [handled: BOOL] = { caf: CmdAllFiles _ NARROW[instance.data]; SELECT instance.argCount FROM 0 => caf.prefix _ instance.cls.GetRopeLiteral[]; 1 => caf.perFile _ instance.cls.GetRopeLiteral[]; 2 => caf.infix _ instance.cls.GetRopeLiteral[]; 3 => caf.postfix _ instance.cls.GetRopeLiteral[]; 4 => instance.setAsAny _ instance.cls.GetRefAny[]; ENDCASE => RETURN [FALSE]; handled _ TRUE}; AfterCmdAllFilesParse: PROC [instance: Instance] = { caf: CmdAllFiles _ NARROW[instance.data]; instance.createdNeeded _ caf.perFile.Find[""] > 0; }; PerCmdAllFilesFile: PROC [instance: Instance, fn: FileNote] = { caf: CmdAllFiles = NARROW[instance.data]; createdR: ROPE = IF instance.createdNeeded THEN Convert.RopeFromTime[GetCreated[fn]] ELSE "??"; perThis: ROPE = DoReplacements[caf.perFile, fn, createdR]; caf.commandLine _ caf.commandLine.Cat[IF caf.first THEN caf.prefix ELSE caf.infix, perThis]; caf.first _ FALSE; }; DoReplacements: PROC [pattern: ROPE, fn: FileNote, createdR: ROPE] RETURNS [replaced: ROPE] = { full: ROPE; cp: FS.ComponentPositions; Map: PROC [data: REF ANY, in: ROPE] RETURNS [out: ROPE] = { out _ SELECT Atom.MakeAtom[in] FROM $fileName => fn.fsName, $server => GetField[cp.server], $dir => GetField[cp.dir], $directory => full.Substr[0, cp.base.start], $subDirs => GetSubdir[], $base => GetField[cp.base], $ext => IF cp.ext.start > cp.base.start+cp.base.length THEN Rope.Concat[".", GetField[cp.ext]] ELSE "", $short => GetFields[cp.base, cp.ext], $ver => IF cp.ver.start > cp.ext.start+cp.ext.length THEN Rope.Concat["!", GetField[cp.ver]] ELSE "", $created => createdR, $primaryVolume => fn.primaryVolume, $backupVolume => fn.backupVolume, ENDCASE => "??"; }; GetSubdir: PROC RETURNS [subDir: ROPE] = INLINE { subDir _ IF cp.subDirs.length # 0 THEN GetField[cp.subDirs].Concat[">"] ELSE ""; }; GetField: PROC [pos: FS.Position] RETURNS [rope: ROPE] = INLINE { rope _ full.Substr[pos.start, pos.length]; }; GetFields: PROC [pi, pf: FS.Position] RETURNS [rope: ROPE] = INLINE { rope _ full.Substr[pi.start, pf.start+pf.length-pi.start]; }; rm: TextReplace.RopeMap = NEW [TextReplace.RopeMapRep _ [NIL]]; [full, cp, ] _ FS.ExpandName[fn.fsName]; TRUSTED {rm.Map _ Map}; replaced _ rm.Nest[].Apply[pattern]; full _ full; }; FinishCmdAllFiles: PROC [instance: Instance] RETURNS [result: REF ANY, msg: ROPE] = { caf: CmdAllFiles _ NARROW[instance.data]; caf.commandLine _ caf.commandLine.Cat[caf.postfix]; result _ CommandTool.DoCommand[commandLine: caf.commandLine, parent: instance.cmd]; }; cmdAllFiles: Command _ NEW [CommandRep _ [ Start: StartCmdAllFiles, HandleArg: HandleCmdAllFilesArg, AfterParse: AfterCmdAllFilesParse, PerFile: PerCmdAllFilesFile, Finish: FinishCmdAllFiles, usage: "Usage: CmdAllFiles {-withServer|-withoutServer|-withDirectory|-withoutDirectory|-withVersion|-withoutVersion|-withCreate|-withoutCreate|-askFS|-touchy|-tough}* || {\"command prefix\" \"pattern per file\" \"separator\" \"command postfix\" fileSetExpression}"]]; ListFileSet: TYPE = REF ListFileSetRep; ListFileSetRep: TYPE = RECORD [ long: BOOL _ FALSE, byteSum: INT _ 0]; StartListFileSet: PROC [instance: Instance] = { lfs: ListFileSet _ NEW [ListFileSetRep _ []]; instance.data _ lfs}; HandleListFileSetSwitch: PROC [instance: Instance, switch: ROPE] RETURNS [handled: BOOL] = { lfs: ListFileSet _ NARROW[instance.data]; IF switch.Equal["-l", FALSE] THEN lfs.long _ TRUE ELSE IF switch.Equal["-s", FALSE] THEN lfs.long _ FALSE ELSE RETURN [FALSE]; handled _ TRUE}; AfterListFileSetParse: PROC [instance: Instance] = { lfs: ListFileSet _ NARROW[instance.data]; instance.createdNeeded _ lfs.long}; PerListFileSetFile: PROC [instance: Instance, fn: FileNote] = { lfs: ListFileSet _ NARROW[instance.data]; IF lfs.long THEN { bytes: INT _ -1; ok: BOOL _ TRUE; bytes _ FS.FileInfo[name: fn.fsName, wantedCreatedTime: GetCreated[fn] !FS.Error => {ok _ FALSE; CONTINUE}].bytes; instance.cmd.out.PutF["%8g ", IO.int[bytes]]; IF ok THEN lfs.byteSum _ lfs.byteSum + bytes; }; instance.cmd.out.PutRope[fn.id.name]; IF lfs.long THEN { instance.cmd.out.PutF["\t%g", IO.time[GetCreated[fn]]]; }; instance.cmd.out.PutRope["\n"]}; FinishListFileSet: PROC [instance: Instance] RETURNS [result: REF ANY, msg: ROPE] = { lfs: ListFileSet _ NARROW[instance.data]; result _ NIL; msg _ NIL; IF lfs.long THEN msg _ IO.PutFR["%g bytes total", IO.int[lfs.byteSum]]; }; listFileSet: Command _ NEW [CommandRep _ [ Start: StartListFileSet, HandleSwitch: HandleListFileSetSwitch, AfterParse: AfterListFileSetParse, PerFile: PerListFileSetFile, Finish: FinishListFileSet, usage: "Usage: ListFileSet {-withServer|-withoutServer|-withDirectory|-withoutDirectory|-withVersion|-withoutVersion|-withCreate|-withoutCreate|-askFS|-touchy|-tough|-l|-s}* || {fileSetExpression}"]]; AfterDeleteParse: PROC [instance: Instance] = { instance.createdNeeded _ instance.ids.askFS OR instance.ids.create}; PerDeleteFile: PROC [instance: Instance, fn: FileNote] = { ok: BOOL _ TRUE; useCreate: BOOL _ instance.ids.askFS OR instance.ids.create; create: GMT _ IF useCreate THEN GetCreated[fn] ELSE noGMT; name: ROPE _ fn.fsName; instance.cmd.out.PutRope[name]; IF useCreate THEN instance.cmd.out.PutF[" of %g", IO.time[create]]; instance.cmd.out.PutRope[" ... "]; FS.Delete[ name: name, wantedCreatedTime: create !FS.Error => { instance.cmd.out.PutF[" Error[%g, %g]\n", IO.atom[error.code], IO.rope[error.explanation]]; ok _ FALSE; instance.subFailures _ instance.subFailures + 1; CONTINUE; }]; IF ok THEN instance.cmd.out.PutRope[" ok\n"]; }; deleteFileSet: Command _ NEW [CommandRep _ [ AfterParse: AfterDeleteParse, PerFile: PerDeleteFile, usage: "Usage: DeleteFileSet {-withServer|-withoutServer|-withDirectory|-withoutDirectory|-withVersion|-withoutVersion|-withCreate|-withoutCreate|-askFS|-touchy|-tough}* || {fileSetExpression}"]]; AfterArchiveRequestParse: PROC [instance: Instance] = { instance.createdNeeded _ FALSE}; PerArchiveRequestFile: PROC [instance: Instance, fn: FileNote] = { instance.cmd.out.PutF["Archive: %g\n", IO.rope[fn.fsName]]}; archiveFileSet: Command _ NEW [CommandRep _ [ AfterParse: AfterArchiveRequestParse, PerFile: PerArchiveRequestFile, usage: "Usage: ArchiveFileSet {-withServer|-withoutServer|-withDirectory|-withoutDirectory|-withVersion|-withoutVersion|-withCreate|-withoutCreate|-askFS|-touchy|-tough}* || {fileSetExpression}"]]; AfterRetrieveRequestParse: PROC [instance: Instance] = { instance.createdNeeded _ TRUE}; PerRetrieveRequestFile: PROC [instance: Instance, fn: FileNote] = { instance.cmd.out.PutF["Retrieve: %g of %g from %g or %g\n", IO.rope[fn.fsName], IO.time[GetCreated[fn]], IO.rope[fn.primaryVolume], IO.rope[fn.backupVolume]]}; retrieveFileSet: Command _ NEW [CommandRep _ [ AfterParse: AfterRetrieveRequestParse, PerFile: PerRetrieveRequestFile, usage: "Usage: RetrieveFileSet {-withServer|-withoutServer|-withDirectory|-withoutDirectory|-withVersion|-withoutVersion|-withCreate|-withoutCreate|-askFS|-touchy|-tough}* || {fileSetExpression}"]]; Replace: PROC [start, match, replace: ROPE] RETURNS [finish: ROPE] = { ml: INT _ match.Length[]; rl: INT _ replace.Length[]; len: INT _ (finish _ start).Length[]; loc: INT _ finish.Index[0, match]; WHILE loc < len DO finish _ finish.Substr[len: loc].Cat[replace, finish.Substr[start: loc+ml]]; len _ finish.Length[]; loc _ finish.Index[loc + rl, match]; ENDLOOP; }; Register: PROC [key: ROPE, command: Command, doc: ROPE] = { Commander.Register[key: key, proc: Generic, doc: doc, clientData: command, interpreted: FALSE]; }; Start: PROC = { Register["CmdPerFile", cmdPerFile, "execute a command for every file in ..."]; Register["CmdAllFiles", cmdAllFiles, "execute a command that takes every file in ..."]; Register["ListFileSet", listFileSet, "list files in a set"]; Register["lfs", listFileSet, "list files in a set"]; Register["DeleteFileSet", deleteFileSet, "delete files in a set"]; Register["dfs", deleteFileSet, "delete files in a set"]; Register["ArchiveFileSet", archiveFileSet, "print request to archive files in a set"]; Register["afs", archiveFileSet, "print request to files in a set"]; Register["RetrieveFileSet", retrieveFileSet, "print request to retrieves files in a set from archive"]; Register["rfs", retrieveFileSet, "print request to retrieves files in a set from archive"]; fcEnv _ Misp.NewEnvironment[name: "FileSets", sizeGuess: 200]; Misp.DefinePrimitives[fcEnv]; }; Start[]; }. FileCmdsImpl.Mesa Copyright c 1984 by Xerox Corporation. All rights reserved. Last Edited by: Spreitzer, February 11, 1986 1:13:28 pm PST Mike Spreitzer June 19, 1986 8:33:20 pm PDT set instance.createdNeeded. now we're done with parse, eval & execute Κ-˜code™Kšœ Οmœ1™—Kšœžœ˜3Kšœžœžœžœ˜&Kšœžœ%˜=š œžœ‘œ˜.Kšœ žœ˜šžœžœžœ˜4Kšœ4žœ˜IKšœ0˜0K˜—šžœ˜Kšœ˜K˜—K˜—Kšžœžœžœ˜4š žœžœ.žœžœ ž˜Pšžœžœ˜Kšœžœ#˜/Kšžœžœžœž˜?Kš žœžœ žœžœž˜NKš žœžœžœžœž˜JKš žœžœ#žœžœž˜TKš žœžœ žœžœž˜PKš žœžœ!žœžœž˜PKš žœžœžœžœž˜LKš žœžœ žœžœž˜NKš žœžœžœžœž˜JKš žœžœžœžœž˜BKš žœžœžœžœž˜BKšžœžœžœžœžœ(žœžœ˜hK˜—šžœ˜šžœžœ žœžœ˜-K˜Kšœžœ4žœ˜[Kšžœ‘K˜WKšœ˜—šžœžœž˜šœžœ˜šžœž˜K˜2Kšžœžœ˜K˜——šœžœ˜Kšžœžœžœžœ˜:K˜—Kšžœžœ˜—Kšœ*˜*K˜—šž˜Kšœžœ˜1—Kšžœ˜—Kšžœžœžœžœ˜Ašœ)™)šœžœ˜ ˜ Kšœ&žœ ˜5Kšžœžœžœ˜AK˜K˜&Kšžœ˜K˜—˜ J˜K˜Kšžœ˜K˜—˜ K˜K˜Kšžœ˜ K˜—K˜—Kšœžœžœ˜ Kšžœžœžœ˜>Kšœžœ/žœ˜JKšœ*žœ˜/šžœžœž˜K˜!Kšžœžœ žœ6žœ˜f—Kšžœžœžœžœ˜OK˜—Kšžœžœžœžœžœ žœ3žœžœ˜ΝKšžœžœžœ*˜FKšœ!žœ˜@šž˜Kšœ žœ˜—K˜—K˜š  œžœžœžœžœ ‘œ˜JKš œžœžœžœžœ˜3K˜—K˜Kšœ žœžœ˜%šœžœžœ˜Kšœ žœžœ˜—K˜š œžœ˜.Kšœžœ˜+K˜—K˜š œžœžœ žœ˜JKšœžœ˜(šžœž˜Kšœ1˜1Kšœ2˜2Kšžœžœžœ˜—Kšœ žœ˜—K˜š œžœ˜3Kšœžœ˜(Kšœ;˜;K˜—K˜š œžœ'˜>Kšœžœ˜(Kš œ žœžœžœ&žœ˜_Kšœ žœ-˜>Kšœ žœžœ˜KšœS˜SKšžœžœ1˜NK˜—K˜šœžœ˜)Kšœ žœ˜ Kšœ˜Kšœ˜Kšœ!˜!Kšœ˜KšœΥ˜Υ—K˜Kšœ žœžœ˜'šœžœžœ˜Kšœ.žœžœ˜9Kšœžœžœ˜—K˜š œžœ˜/Kšœžœ˜-K˜—K˜š œžœžœ žœ˜KKšœžœ˜)šžœž˜Kšœ0˜0Kšœ1˜1Kšœ/˜/Kšœ1˜1Kšœ2˜2Kšžœžœžœ˜—Kšœ žœ˜—K˜š œžœ˜4Kšœžœ˜)Kšœ;˜;K˜—K˜š œžœ'˜?Kšœžœ˜)Kš œ žœžœžœ&žœ˜_Kšœ žœ-˜:Kšœ&žœ žœ žœ˜\Kšœ žœ˜K˜—K˜š  œžœ žœžœžœ žœ˜_Kšœžœ˜ Kšœžœ˜š œžœžœžœžœžœžœ˜;šœžœž˜#Kšœ˜K˜K˜Kšœ,˜,Kšœ˜K˜Kšœžœ-žœ$žœ˜gK˜%Kšœžœ+žœ$žœ˜eKšœ˜Kšœ#˜#Kšœ!˜!Kšžœ ˜—K˜—š   œžœžœ žœžœ˜1Kšœ žœžœ"žœ˜PKšœ˜—š  œžœžœ žœžœžœ˜AKšœ*˜*Kšœ˜—š   œžœ žœ žœžœžœ˜EK˜:Kšœ˜—Kšœžœžœ˜?Kšœžœ˜(Kšžœ˜K˜$K˜ K˜—K˜š  œžœžœ žœžœžœ˜UKšœžœ˜)K˜3KšœS˜SK˜—K˜šœžœ˜*Kšœ˜Kšœ ˜ Kšœ"˜"Kšœ˜Kšœ˜KšœŒ˜Œ—K˜Kšœ žœžœ˜'šœžœžœ˜Kšœžœžœ˜Kšœ žœ˜—K˜š œžœ˜/Kšœžœ˜-K˜—K˜š  œžœžœžœ žœ˜\Kšœžœ˜)Kšžœžœžœ ž˜1Kš žœžœžœžœ ž˜7Kšžœžœžœ˜Kšœ žœ˜—K˜š œžœ˜4Kšœžœ˜)Kšœ#˜#—K˜š œžœ'˜?Kšœžœ˜)šžœ žœ˜Kšœžœ˜Kšœžœžœ˜Kš œžœ>žœžœžœ ˜rKšœžœ ˜-Kšžœžœ#˜-K˜—Kšœ%˜%šžœ žœ˜Kšœžœ˜7K˜—K˜ —K˜š  œžœžœ žœžœžœ˜UKšœžœ˜)Kšœ žœ˜ Kšœžœ˜ Kšžœ žœžœžœ˜GK˜—K˜šœžœ˜*Kšœ˜Kšœ&˜&Kšœ"˜"Kšœ˜K˜KšœΘ˜Θ—K˜š œžœ˜/Kšœ,žœ˜D—K˜š  œžœ'˜:Kšœžœžœ˜Kšœ žœžœ˜˜>K˜K˜—K˜K˜K˜K˜——…—; LQ