From 4892ab7f79dbd7a0ee19afa83944be5f3f5b0507 Mon Sep 17 00:00:00 2001 From: Jack Jansen Date: Tue, 24 Sep 1996 15:35:50 +0000 Subject: The Window Independent Tracer (which will probably move elsewhere once it is truly window-independent:-) --- Mac/Tools/twit/TwitCore.py | 493 ++++++++++++++++++++++++++++++++++++++ Mac/Tools/twit/mac_widgets.py | 308 ++++++++++++++++++++++++ Mac/Tools/twit/mactwit_app.py | 130 ++++++++++ Mac/Tools/twit/mactwit_browser.py | 429 +++++++++++++++++++++++++++++++++ Mac/Tools/twit/mactwit_edit.py | 24 ++ Mac/Tools/twit/mactwit_mod.py | 92 +++++++ Mac/Tools/twit/mactwit_stack.py | 191 +++++++++++++++ Mac/Tools/twit/twit.py | 94 ++++++++ Mac/Tools/twit/twit.rsrc.hqx | 482 +++++++++++++++++++++++++++++++++++++ Mac/Tools/twit/twittest.py | 13 + 10 files changed, 2256 insertions(+) create mode 100644 Mac/Tools/twit/TwitCore.py create mode 100644 Mac/Tools/twit/mac_widgets.py create mode 100644 Mac/Tools/twit/mactwit_app.py create mode 100644 Mac/Tools/twit/mactwit_browser.py create mode 100644 Mac/Tools/twit/mactwit_edit.py create mode 100644 Mac/Tools/twit/mactwit_mod.py create mode 100644 Mac/Tools/twit/mactwit_stack.py create mode 100644 Mac/Tools/twit/twit.py create mode 100644 Mac/Tools/twit/twit.rsrc.hqx create mode 100644 Mac/Tools/twit/twittest.py diff --git a/Mac/Tools/twit/TwitCore.py b/Mac/Tools/twit/TwitCore.py new file mode 100644 index 0000000..51f6485 --- /dev/null +++ b/Mac/Tools/twit/TwitCore.py @@ -0,0 +1,493 @@ +# Window-interface-independent part of twit +import sys +import types +import bdb +import types + +SIMPLE_TYPES=( + types.NoneType, + types.IntType, + types.LongType, + types.FloatType, + types.ComplexType, + types.StringType +) + +def Initialize(): + pass + +class DebuggerStuff(bdb.Bdb): + + def __init__(self, parent): + bdb.Bdb.__init__(self) + self.parent = parent + self.exception_info = (None, None) + self.reason = 'Not running' + self.reset() + + def reset(self): + bdb.Bdb.reset(self) + self.forget() + + def forget(self): + self.lineno = None + self.stack = [] + self.curindex = 0 + self.curframe = None + + def setup(self, f, t): + self.forget() + self.stack, self.curindex = self.get_stack(f, t) + self.curframe = self.stack[self.curindex][0] + + def interaction(self, frame, traceback): + self.setup(frame, traceback) + self.parent.interact() + self.exception_info = (None, None) + + def user_call(self, frame, argument_list): + self.reason = 'Calling function' + self.interaction(frame, None) + + def user_line(self, frame): + self.reason = 'Stopped' + self.interaction(frame, None) + + def user_return(self, frame, return_value): + self.reason = 'Returning from function' + self.interaction(frame, None) + + def user_exception(self, frame, (exc_type, exc_value, exc_traceback)): + self.reason = 'Exception occurred' + self.exception_info = (exc_type, exc_value) + self.interaction(frame, exc_traceback) + + def getexception(self): + tp, value = self.exception_info + if tp <> None and type(tp) <> type(''): + tp = tp.__name__ + if value <> None and type(value) <> type(''): + value = `value` + return tp, value + + def getstacktrace(self): + names, locations = [], [] + for frame, lineno in self.stack: + name = frame.f_code.co_name + if not name: + name = "" + elif name == '?': + name = "" + else: + name = name + '()' + names.append(name) + + if lineno == -1: + lineno = getframelineno(frame) + + modname = getframemodname(frame) + if not modname: modname = "" + + locations.append("%s:%d" % (modname, lineno)) + return names, locations + + def getframe(self, number): + if number < 0 or number >= len(self.stack): + return None + return self.stack[number][0] + + def getframevars(self, number, show_complex=1, show_system=1): + frame = self.getframe(number) + if not frame: + return [], [] + return getvarsfromdict(frame.f_locals, show_complex, show_system) + + def getframevar(self, number, var): + frame = self.getframe(number) + return frame.f_locals[var] + + def getframefilepos(self, frameno): + if frameno == None or frameno < 0 or frameno >= len(self.stack): + return None, None, None + frame, line = self.stack[frameno] + if line == -1: + line = getframelineno(frame) + modname = getframemodname(frame) + filename = frame.f_code.co_filename + return filename, modname, line + + def getprogramstate(self): + return self.reason + +class Application: + """Base code for the application""" + + def mi_init(self, run_args, pm_args): + self.dbg = DebuggerStuff(self) + self.run_dialog = self.new_stack_browser(self) + self.run_dialog.open() + self.module_dialog = None + self.initial_cmd = None + if pm_args: + while pm_args.tb_next <> None: + pm_args = pm_args.tb_next + self.dbg.setup(pm_args.tb_frame, pm_args) + self.run_dialog.setsession_pm() + elif run_args: + self.run_dialog.setsession_run() + self.initial_cmd = run_args + else: + self.run_dialog.setsession_none() + + def breaks_changed(self, filename): + self.run_dialog.breaks_changed(filename) + if self.module_dialog: + self.module_dialog.breaks_changed(filename) + + def to_debugger(self): + apply(self.dbg.run, self.initial_cmd) + + def interact(self): + # Interact with user. First, display correct info + self.run_dialog.update_views() + if self.module_dialog: + self.module_dialog.update_views() + + # Next, go into mainloop + self.one_mainloop() + + # Finally (before we start the debuggee again) show state + self.run_dialog.show_it_running() + + def quit_bdb(self): + self.dbg.set_quit() + + def run(self): + cmd = AskString('Statement to execute:') + self.initial_cmd = (cmd, None, None) + self.run_dialog.setsession_run() + self.exit_mainloop() + + def cont(self): + self.dbg.set_continue() + self.exit_mainloop() + + def step(self, frame): + self.dbg.set_next(frame) + self.exit_mainloop() + + def step_in(self): + self.dbg.set_step() + self.exit_mainloop() + + def step_out(self, frame): + self.dbg.set_return(frame) + self.exit_mainloop() + + def quit(self): + self.do_quit() + + def browse(self, module): + if not self.module_dialog: + self.module_dialog = self.new_module_browser(self) + self.module_dialog.open(module) + else: + self.module_dialog.focus(module) + + def browse_var(self, var): + b = self.new_var_browser(self, var) + +class StackBrowser: + """Base code for stack browser""" + def mi_open(self): + """Setup initial data structures""" + self.create_items() + self.cur_stackitem = None + self.cur_source = None + self.cur_modname = None + self.cur_line = None + self.show_complex = 1 + self.show_system = 0 + self.setup() + + # create_items(self) should create self.modules, self.vars and self.source + + def setup(self): + SetWatch() + """Fill the various widgets with values""" + name, value = self.parent.dbg.getexception() + self.setexception(name, value) + self.setprogramstate(self.parent.dbg.getprogramstate()) + + names, locations = self.parent.dbg.getstacktrace() + self.stack.setcontent(names, locations) + self.cur_stackitem = len(names)-1 + self.stack.select(self.cur_stackitem) + self.setup_frame() + + def setup_frame(self): + """Setup frame-dependent widget data""" + SetWatch() + self.cont_varnames, self.cont_varvalues = \ + self.parent.dbg.getframevars(self.cur_stackitem, + self.show_complex, self.show_system) + self.vars.setcontent(self.cont_varnames, self.cont_varvalues) + self.set_var_buttons() + + msg = "" + if self.cur_stackitem == None: + self.cur_source = None + self.cur_modname = None + self.cur_line = None + msg = "No stackframe selected" + else: + self.cur_source, self.cur_modname, optnextline = \ + self.parent.dbg.getframefilepos(self.cur_stackitem) + if optnextline >= 0: + self.cur_line = optnextline + if self.cur_source == '': + self.cur_source = None + msg = "Executing from " + print 'SOURCE', self.cur_source + print 'LINE', self.cur_line + + self.setsource(msg) + self.source.setcurline(self.cur_line) + self.breaks_changed(self.cur_source) + + + SetCursor() + + # setsource(msg) should display cur_source+content, or msg if None + + def show_it_running(self): + self.setprogramstate("Running") + + def update_views(self): + self.setup() + + def click_stack(self, number, *dummy): + if number == self.cur_stackitem: return + self.cur_stackitem = number + self.stack.select(self.cur_stackitem) + self.setup_frame() + + def click_var(self, var, *dummy): + v = self.parent.dbg.getframevar(self.cur_stackitem, var) + self.parent.browse_var(v) + + def click_source(self, lineno, inborder): + if not inborder: + self.source.select(lineno) + self.cur_line = lineno + if lineno == None or not self.cur_source or not inborder: + return + if self.parent.dbg.get_break(self.cur_source, lineno): + self.parent.dbg.clear_break(self.cur_source, lineno) + else: + self.parent.dbg.set_break(self.cur_source, lineno) + self.parent.breaks_changed(self.cur_source) + + def breaks_changed(self, filename): + if filename == self.cur_source: + list = self.parent.dbg.get_file_breaks(filename) + self.source.setbreaks(list) + + def click_quit(self): + self.parent.quit() + + def click_run(self): + self.parent.run() + + def click_continue(self): + self.parent.cont() + + def click_step(self): + if self.cur_stackitem <> None: + frame = self.parent.dbg.getframe(self.cur_stackitem) + self.parent.step(frame) + else: + self.parent.step_in() + + def click_step_in(self): + self.parent.step_in() + + def click_step_out(self): + if self.cur_stackitem <> None: + frame = self.parent.dbg.getframe(self.cur_stackitem) + self.parent.step_out(frame) + else: + self.parent.step_in() + + def click_browse(self): + self.parent.browse(self.cur_modname) + + def click_edit(self): + lino = self.cur_line + if not lino: + lino = 1 + if self.cur_source: + self.parent.edit(self.cur_source, lino) + +class ModuleBrowser: + """Base code for a module-browser""" + + def mi_open(self, module): + """Setup initial data structures""" + self.create_items() + self.cur_module = module + self.cur_source = None + self.cur_line = None + self.cont_modules = [] + self.value_windows = [] + self.setup() + + # create_items(self) should create self.modules, self.vars and self.source + + def setup(self): + """Fill the various widgets with values""" + SetWatch() + modnames = getmodulenames() + if not self.cur_module in modnames: + self.cur_module = None + if modnames <> self.cont_modules: + self.modules.setcontent(modnames) + self.cont_modules = modnames + if self.cur_module: + self.modules.select(self.cont_modules.index(self.cur_module)) + else: + self.modules.select(None) + self.setup_module() + + def setup_module(self): + """Setup module-dependent widget data""" + SetWatch() + if not self.cur_module: + self.vars.setcontent([], []) + else: + self.cont_varnames, self.cont_varvalues = getmodulevars(self.cur_module) + self.vars.setcontent(self.cont_varnames, self.cont_varvalues) + + msg = "" + if not self.cur_module: + self.cur_source = None + msg = "No module selected" + else: + m = sys.modules[self.cur_module] + try: + self.cur_source = m.__file__ + except AttributeError: + self.cur_source = None + msg = "Not a python module" + self.cur_lineno = 0 + self.setsource(msg) + self.source.select(self.cur_line) + self.breaks_changed(self.cur_source) + + SetCursor() + + # setsource(msg) should display cur_source+content, or msg if None + + def update_views(self): + self.setup_module() + + def click_module(self, module, *dummy): + if not module or module == self.cur_module: return + self.focus(module) + + def focus(self, module): + self.cur_module = module + self.setup() + + def click_var(self, var, *dummy): + if not var: return + m = sys.modules[self.cur_module] + dict = m.__dict__ + self.parent.browse_var(dict[var]) + + def click_source(self, lineno, inborder): + if not inborder: + self.source.select(lineno) + self.cur_lineno = lineno + if lineno == None or not self.cur_source or not inborder: + return + if self.parent.dbg.get_break(self.cur_source, lineno): + self.parent.dbg.clear_break(self.cur_source, lineno) + else: + self.parent.dbg.set_break(self.cur_source, lineno) + self.parent.breaks_changed(self.cur_source) + + def breaks_changed(self, filename): + if filename == self.cur_source: + list = self.parent.dbg.get_file_breaks(filename) + self.source.setbreaks(list) + + def click_edit(self): + lino = self.cur_lineno + if not lino: + lino = 1 + if self.cur_source: + self.parent.edit(self.cur_source, lino) + + +def getmodulenames(): + """Return a list of all current modules, sorted""" + list = sys.modules.keys()[:] + list.sort() + return list + +def getmodulevars(name): + """For given module return lists with names and values""" + m = sys.modules[name] + try: + dict = m.__dict__ + except AttributeError: + dict = {} + return getvarsfromdict(dict) + +def getvarsfromdict(dict, show_complex=1, show_system=1): + allnames = dict.keys()[:] + allnames.sort() + names = [] + for n in allnames: + if not show_complex: + if not type(dict[n]) in SIMPLE_TYPES: + continue + if not show_system: + if n[:2] == '__' and n[-2:] == '__': + continue + names.append(n) + values = [] + for n in names: + v = pretty(dict[n]) + values.append(v) + return names, values + +def pretty(var): + t = type(var) + if t == types.FunctionType: return '' + if t == types.ClassType: return '' + return `var` + +def getframelineno(frame): + """Given a frame return the line number""" + return getcodelineno(frame.f_code) + +def getfunclineno(func): + """Given a function return the line number""" + return getcodelineno(func.func_code) + +def getcodelineno(cobj): + """Given a code object return the line number""" + code = cobj.co_code + lineno = -1 + if ord(code[0]) == 127: # SET_LINENO instruction + lineno = ord(code[1]) | (ord(code[2]) << 8) + return lineno + +def getframemodname(frame): + """Given a frame return the module name""" + globals = frame.f_globals + if globals.has_key('__name__'): + return globals['__name__'] + return None diff --git a/Mac/Tools/twit/mac_widgets.py b/Mac/Tools/twit/mac_widgets.py new file mode 100644 index 0000000..370a1f6 --- /dev/null +++ b/Mac/Tools/twit/mac_widgets.py @@ -0,0 +1,308 @@ +from FrameWork import * +import Win +import Qd +import Controls +import Ctl +import TE +import List +import os +import string +import macfs + +SCROLLBAR=16 +MARGIN=2 +ICONSIZE=16 +TEXTWIDTH=4096 # More-or-less random value + +PIC_CURRENT=512 +PIC_BREAK=513 +picture_cache={} + +class MT_TextWidget: + def __init__(self, wid, r): + self.wid = wid + self.rect = r + left, top, right, bottom = r + self.terect = left+MARGIN+ICONSIZE, top+MARGIN, \ + right-(MARGIN+SCROLLBAR), bottom-(MARGIN+SCROLLBAR) + dr = self.terect[0], self.terect[1], TEXTWIDTH, self.terect[3] + Qd.SetPort(wid) + Qd.TextFont(4) + Qd.TextSize(9) + self.ted = TE.TENew(dr, self.terect) + self.ted.TEAutoView(1) + self.activate(1) + + rect = right-SCROLLBAR, top, right, bottom-SCROLLBAR+1 + self.bary = Ctl.NewControl(self.wid, rect, "", 1, 0, 0, 0, 16, 0) + rect = left, bottom-SCROLLBAR, right-SCROLLBAR+1, bottom + self.barx = Ctl.NewControl(self.wid, rect, "", 1, 0, 0, 0, 16, 0) + + self.have_data = 0 + self.line_index = [] + + def close(self): + del self.barx + del self.bary + del self.ted + + def scrollbars(self): + pass + + def setcontent(self, file): + self.line_index = [] + if file == None: + data = '' + self.have_data = 0 + else: + try: + fp = open(file, 'rb') # NOTE the binary + data = fp.read() + self.have_data = 1 + except IOError, arg: + data = 'Cannot open file:\r'+`arg` + self.have_data = 0 + if len(data) > 32767: + self.have_data = 0 + data = 'File too big' + self.ted.TESetText(data) + if self.have_data: + cur = 0 + while 1: + self.line_index.append(cur) + try: + cur = string.index(data, '\r', cur+1) + except ValueError: + break + self.line_index.append(len(data)) + Win.InvalRect(self.rect) + self.ted.TESetSelect(0,0) + self.ted.TECalText() + self.ted.TESelView() + self.setscrollbars() + + def setscrollbars(self): + docleft, doctop, docright, docbot = self.ted.destRect + winleft, wintop, winright, winbot = self.ted.viewRect + docbot = self.ted.nLines*self.ted.lineHeight + doctop + self.setbar(self.barx, docleft, docright, winleft, winright) + self.setbar(self.bary, doctop, docbot, wintop, winbot) + + def setbar(self, bar, minmin, maxmax, curmin, curmax): + if maxmax-minmin > 32767 or (curmin <= minmin and curmax >= maxmax): + bar.SetControlMinimum(0) + bar.SetControlMaximum(0) + bar.SetControlValue(0) + return + bar.SetControlMinimum(minmin) + bar.SetControlMaximum(maxmax-(curmax-curmin)) + bar.SetControlValue(curmin) + + def update(self, rgn): + Qd.EraseRect(self.terect) + Qd.FrameRect(self.rect) + self.ted.TEUpdate(self.terect) + + def activate(self, onoff): + if onoff: + self.ted.TEActivate() + else: + self.ted.TEDeactivate() + + def select(self, line): + if line == None or line <= 0 or not self.have_data: + self.ted.TESetSelect(0,0) + else: + line = line - 1 + if line > len(self.line_index)-1: line = len(self.line_index)-1 + if line == 1: + self.ted.TESetSelect(0, self.line_index[1]) + else: + self.ted.TESetSelect(self.line_index[line]+1, self.line_index[line+1]) + self.setscrollbars() + + def click(self, where, modifiers): + # First check scrollbars + ctltype, control = Ctl.FindControl(where, self.wid) + if ctltype and control: + partcode = control.TrackControl(where) + if partcode: + self.controlhit(control, partcode) + return None, 0 + off = self.ted.TEGetOffset(where) + inborder = where[0] < self.terect[0] + return self.offsettoline(off), inborder + + def offsettoline(self, offset): + for i in range(len(self.line_index)): + if offset < self.line_index[i]: + return i # Not i-1: 1-based line numbers in files + return None + + def controlhit(self, control, partcode): + if partcode <> Controls.inThumb: + if control == self.barx: + if partcode == Controls.inUpButton: + delta = -10 + if partcode == Controls.inDownButton: + delta = 10 + if partcode == Controls.inPageUp: + delta = 10-(self.terect[2]-self.terect[0]) + if partcode == Controls.inPageDown: + delta = (self.terect[2]-self.terect[0])-10 + old = control.GetControlValue() + control.SetControlValue(old+delta) + if control == self.bary: + if partcode == Controls.inUpButton: + delta = -self.ted.lineHeight + if partcode == Controls.inDownButton: + delta = self.ted.lineHeight + if partcode == Controls.inPageUp: + delta = self.ted.lineHeight-(self.terect[3]-self.terect[1]) + if partcode == Controls.inPageDown: + delta = (self.terect[3]-self.terect[1])-self.ted.lineHeight + old = control.GetControlValue() + control.SetControlValue(old+delta) + newx = self.barx.GetControlValue() + newy = self.bary.GetControlValue() + oldx = self.ted.viewRect[0] + oldy = self.ted.viewRect[1] + self.ted.TEPinScroll(oldx-newx, oldy-newy) + self.setscrollbars() # XXXX Bibbert, maar hoe anders? + +class MT_IconTextWidget(MT_TextWidget): + def __init__(self, wid, r): + MT_TextWidget.__init__(self, wid, r) + self.breakpointlist = [] + self.curline = None + self.iconrect = (self.rect[0]+1, self.rect[1]+1, + self.terect[0]-1, self.terect[3]-1) + self.curlinerange = (self.terect[1]+self.ted.lineHeight, + self.terect[3]-2*self.ted.lineHeight) + + def setbreaks(self, list): + self.breakpointlist = list[:] + Qd.SetPort(self.wid) + Win.InvalRect(self.iconrect) + + def setcurline(self, line): + self.curline = line + Qd.SetPort(self.wid) + self.showline(line) + + def showline(self, line): + if line <= 0: line = 1 + if line >= len(self.line_index): line = len(self.line_index)-1 + if line < 0: return + off = self.line_index[line] + x, y = self.ted.TEGetPoint(off) + if self.curlinerange[0] <= y <= self.curlinerange[1]: + return # It is in view + middle = (self.curlinerange[0]+self.curlinerange[1])/2 + self.ted.TEPinScroll(0, middle-y) # Of andersom? + self.setscrollbars() + + def setscrollbars(self): + MT_TextWidget.setscrollbars(self) + Win.InvalRect(self.iconrect) + + def update(self, rgn): + MT_TextWidget.update(self, rgn) + self.drawallicons() + + def drawallicons(self): + Qd.EraseRect(self.iconrect) + Qd.MoveTo(self.iconrect[2], self.iconrect[1]) + Qd.LineTo(self.iconrect[2], self.iconrect[3]) + topoffset = self.ted.TEGetOffset((self.terect[0], self.terect[1])) + botoffset = self.ted.TEGetOffset((self.terect[0], self.terect[3])) + topline = self.offsettoline(topoffset) + botline = self.offsettoline(botoffset) + if topline == None: topline = 1 # ??? + if botline == None: botline = len(self.line_index) + for i in self.breakpointlist: + if topline <= i <= botline: + self.draw1icon(i, PIC_BREAK) + if self.curline <> None and topline <= self.curline <= botline: + self.draw1icon(self.curline, PIC_CURRENT) + + def draw1icon(self, line, which): + offset = self.line_index[line] + botx, boty = self.ted.TEGetPoint(offset) + rect = self.rect[0]+2, boty-self.ted.lineHeight, \ + self.rect[0]+ICONSIZE-2, boty + if not picture_cache.has_key(which): + print 'Get picture', which + picture_cache[which] = Qd.GetPicture(which) + self.drawicon(rect, picture_cache[which]) + + def drawicon(self, rect, which): + Qd.DrawPicture(which, rect) + +class MT_IndexList: + def __init__(self, wid, rect, width): + # wid is the window (dialog) where our list is going to be in + # rect is it's item rectangle (as in dialog item) + self.rect = rect + rect2 = rect[0]+1, rect[1]+1, rect[2]-16, rect[3]-1 + self.list = List.LNew(rect2, (0, 0, width, 0), (0,0), 0, wid, + 0, 1, 0, 1) + self.wid = wid + self.width = width + + def setcontent(self, *content): + self.list.LDelRow(0, 1) + self.list.LSetDrawingMode(0) + self.list.LAddRow(len(content[0]), 0) + for x in range(len(content)): + column = content[x] + for y in range(len(column)): + self.list.LSetCell(column[y], (x, y)) + self.list.LSetDrawingMode(1) + Win.InvalRect(self.rect) + + def deselectall(self): + while 1: + ok, pt = self.list.LGetSelect(1, (0,0)) + if not ok: return + self.list.LSetSelect(0, pt) + + def select(self, num): + self.deselectall() + if num < 0: + return + for i in range(self.width): + self.list.LSetSelect(1, (i, num)) + + def click(self, where, modifiers): + is_double = self.list.LClick(where, modifiers) + ok, (x, y) = self.list.LGetSelect(1, (0, 0)) + if ok: + return y, is_double + else: + return None, is_double + + # draw a frame around the list, List Manager doesn't do that + def drawframe(self): + Qd.SetPort(self.wid) + Qd.FrameRect(self.rect) + + def update(self, rgn): + self.drawframe() + self.list.LUpdate(rgn) + + def activate(self, onoff): + self.list.LActivate(onoff) + +class MT_AnyList(MT_IndexList): + + def click(self, where, modifiers): + is_double = self.list.LClick(where, modifiers) + ok, (x, y) = self.list.LGetSelect(1, (0, 0)) + if ok: + self.select(y) + field0 = self.list.LGetCell(1000,(0,y)) + else: + field0 = None + return field0, is_double + diff --git a/Mac/Tools/twit/mactwit_app.py b/Mac/Tools/twit/mactwit_app.py new file mode 100644 index 0000000..268f644 --- /dev/null +++ b/Mac/Tools/twit/mactwit_app.py @@ -0,0 +1,130 @@ +import FrameWork +import EasyDialogs +import Res +import sys +import Qd +import Evt +import Events +import Dlg +import Win + +# Resource-id (for checking existence) +ID_MODULES=512 + +ID_ABOUT=515 + +_arrow = Qd.qd.arrow +_watch = Qd.GetCursor(4).data + +# Made available to TwitCore: +AskString = EasyDialogs.AskString + +def SetCursor(): + Qd.SetCursor(_arrow) + +def SetWatch(): + Qd.SetCursor(_watch) + +# Exception for temporarily exiting the loop and program +ExitMainloop = 'ExitMainloop' +ExitFully = 'ExitFully' + +class Application(FrameWork.Application): + """The twit main class - mac-dependent part""" + + def __init__(self, run_args, pm_args): + # First init menus, etc. + FrameWork.Application.__init__(self) + self._quitting = 0 + self.real_quit = 0 + + # Next create our dialogs + self.mi_init(run_args, pm_args) + if self.real_quit: + return + + if not run_args: + # Go into mainloop once + self.one_mainloop() + if self.real_quit: + return + + if not pm_args: + # And give the debugger control. + self.to_debugger() + + def makeusermenus(self): + self.filemenu = m = FrameWork.Menu(self.menubar, "File") + self._quititem = FrameWork.MenuItem(m, "Quit", "Q", self.do_quit) + + def do_about(self, id, item, window, event): + import time + d = Dlg.GetNewDialog(ID_ABOUT, -1) + if not d: + return + w = d.GetDialogWindow() + port = w.GetWindowPort() + l, t, r, b = port.portRect + sl, st, sr, sb = Qd.qd.screenBits.bounds + x = ((sr-sl) - (r-l)) / 2 + y = ((sb-st-16) - (b-t)) / 5 + w.MoveWindow(x, y, 0) + w.ShowWindow() + d.DrawDialog() + + tp, h, rect = d.GetDialogItem(2) + x0, y0, x1, y1 = rect + ybot = y0 + 32 + + rgn = Qd.NewRgn() + Qd.SetPort(d) + ok, evt = self.getevent(Events.mDownMask|Events.keyDownMask, 1) + if ok: return + (what, message, when, where, modifiers) = event + delta_t = 128 + nexttime = when+delta_t + while ybot < y1: + # Do the animation, if it is time + if when > nexttime: + Qd.ScrollRect((x0, y0, x1, ybot), 0, 1, rgn) + y0 = y0 + 1 + ybot = ybot + 1 + # And update next time + delta_t = int(delta_t*0.6)-1 + if delta_t < 0: + delta_t = 0 + nexttime = when + delta_t + # Check for an event. + ok, evt = self.getevent(Events.mDownMask|Events.keyDownMask, 0) + if ok: return + (what, message, when, where, modifiers) = evt + while 1: + ok, evt = self.getevent(Events.mDownMask|Events.keyDownMask, -1) + if ok: return + + def do_quit(self, *args): + self._quit() # Signal FrameWork.Application to stop + self.real_quit = 1 + self.quit_bdb() # Tell debugger to quit. + + def exit_mainloop(self): + self._quit() # Signal FrameWork.Application to stop + self.real_quit = 0 + + def one_mainloop(self): + self.quitting = 0 + self.mainloop() + +def Initialize(): + try: + # if this doesn't raise an error, we are an applet containing the + # necessary resources or we have been initialized already + # so we don't have to bother opening the resource file + dummy = Res.GetResource('DLOG', ID_MODULES) + except Res.Error: + try: + Res.OpenResFile("Twit.rsrc") + except Res.Error, arg: + EasyDialogs.Message("Cannot open Twit.rsrc: "+arg[1]) + sys.exit(1) + diff --git a/Mac/Tools/twit/mactwit_browser.py b/Mac/Tools/twit/mactwit_browser.py new file mode 100644 index 0000000..26a35b1 --- /dev/null +++ b/Mac/Tools/twit/mactwit_browser.py @@ -0,0 +1,429 @@ +"""A simple Mac-only browse utility to peek at the inner data structures of Python.""" +# Minor modifications by Jack to facilitate incorporation in twit. + +# june 1996 +# Written by Just van Rossum , please send comments/improvements. +# Loosely based on Jack Jansens's PICTbrowse.py, but depends on his fabulous FrameWork.py +# XXX Some parts are *very* poorly solved. Will fix. Guido has to check if all the +# XXX "python-peeking" is done correctly. I kindof reverse-engineered it ;-) + +# disclaimer: although I happen to be the brother of Python's father, programming is +# not what I've been trained to do. So don't be surprised if you find anything that's not +# as nice as it could be... + +# XXX to do: +# Arrow key support +# Copy & Paste? +# MAIN_TEXT item should not contain (type); should be below or something. +# MAIN_TEXT item should check if a string is binary or not: convert to '/000' style +# or convert newlines. + +version = "1.0" + +import FrameWork +import EasyDialogs +import Dlg +import Res +import Qd +import List +import sys +from Types import * +from QuickDraw import * +import string +import time +import os + +# The initial object to start browsing with. Can be anything, but 'sys' makes kindof sense. +start_object = sys + +# Resource definitions +ID_MAIN = 516 +NUM_LISTS = 4 # the number of lists used. could be changed, but the dlg item numbers should be consistent +MAIN_TITLE = 3 # this is only the first text item, the other three ID's should be 5, 7 and 9 +MAIN_LIST = 4 # this is only the first list, the other three ID's should be 6, 8 and 10 +MAIN_TEXT = 11 +MAIN_LEFT = 1 +MAIN_RIGHT = 2 +MAIN_RESET = 12 +MAIN_CLOSE = 13 +MAIN_LINE = 14 + +def Initialize(): + # this bit ensures that this module will also work as an applet if the resources are + # in the resource fork of the applet + # stolen from Jack, so it should work(?!;-) + try: + # if this doesn't raise an error, we are an applet containing the necessary resources + # so we don't have to bother opening the resource file + dummy = Res.GetResource('DLOG', ID_MAIN) + except Res.Error: + savewd = os.getcwd() + ourparentdir = os.path.split(openresfile.func_code.co_filename)[0] + os.chdir(ourparentdir) + try: + Res.OpenResFile("mactwit_browse.rsrc") + except Res.Error, arg: + EasyDialogs.Message("Cannot open mactwit_browse.rsrc: "+arg[1]) + sys.exit(1) + os.chdir(savewd) + +def main(): + Initialize() + PythonBrowse() + +# this is all there is to it to make an application. +class PythonBrowse(FrameWork.Application): + def __init__(self): + FrameWork.Application.__init__(self) + VarBrowser(self).open(start_object) + self.mainloop() + + def do_about(self, id, item, window, event): + EasyDialogs.Message(self.__class__.__name__ + " version " + version + "\rby Just van Rossum") + + def quit(self, *args): + raise self + +class MyList: + def __init__(self, wid, rect, itemnum): + # wid is the window (dialog) where our list is going to be in + # rect is it's item rectangle (as in dialog item) + # itemnum is the itemnumber in the dialog + self.rect = rect + rect2 = rect[0]+1, rect[1]+1, rect[2]-16, rect[3]-1 # Scroll bar space, that's 15 + 1, Jack! + self.list = List.LNew(rect2, (0, 0, 1, 0), (0,0), 0, wid, + 0, 1, 0, 1) + self.wid = wid + self.active = 0 + self.itemnum = itemnum + + def setcontent(self, content, title = ""): + # first, gather some stuff + keylist = [] + valuelist = [] + thetype = type(content) + if thetype == DictType: + keylist = content.keys() + keylist.sort() + for key in keylist: + valuelist.append(content[key]) + elif thetype == ListType: + keylist = valuelist = content + elif thetype == TupleType: + + keylist = valuelist = [] + for i in content: + keylist.append(i) + else: + # XXX help me! is all this correct? is there more I should consider??? + # XXX is this a sensible way to do it in the first place???? + # XXX I'm not familiar enough with Python's guts to be sure. GUIDOOOOO!!! + if hasattr(content, "__dict__"): + keylist = keylist + content.__dict__.keys() + if hasattr(content, "__methods__"): + keylist = keylist + content.__methods__ + if hasattr(content, "__members__"): + keylist = keylist + content.__members__ + if hasattr(content, "__class__"): + keylist.append("__class__") + if hasattr(content, "__bases__"): + keylist.append("__bases__") + if hasattr(content, "__name__"): + title = content.__name__ + if "__name__" not in keylist: + keylist.append("__name__") + keylist.sort() + for key in keylist: + valuelist.append(getattr(content, key)) + if content <> None: + title = title + "\r" + cleantype(content) + # now make that list! + tp, h, rect = self.wid.GetDialogItem(self.itemnum - 1) + Dlg.SetDialogItemText(h, title[:255]) + self.list.LDelRow(0, 1) + self.list.LSetDrawingMode(0) + self.list.LAddRow(len(keylist), 0) + for i in range(len(keylist)): + self.list.LSetCell(str(keylist[i]), (0, i)) + self.list.LSetDrawingMode(1) + self.list.LUpdate(self.wid.GetWindowPort().visRgn) + self.content = content + self.keylist = keylist + self.valuelist = valuelist + self.title = title + + # draw a frame around the list, List Manager doesn't do that + def drawframe(self): + Qd.SetPort(self.wid) + Qd.FrameRect(self.rect) + rect2 = Qd.InsetRect(self.rect, -3, -3) + save = Qd.GetPenState() + Qd.PenSize(2, 2) + if self.active: + Qd.PenPat(Qd.qd.black) + else: + Qd.PenPat(Qd.qd.white) + # draw (or erase) an extra frame to indicate this is the acive list (or not) + Qd.FrameRect(rect2) + Qd.SetPenState(save) + + + +class VarBrowser(FrameWork.DialogWindow): + def open(self, start_object, title = ""): + FrameWork.DialogWindow.open(self, ID_MAIN) + if title <> "": + windowtitle = self.wid.GetWTitle() + self.wid.SetWTitle(windowtitle + " >> " + title) + else: + if hasattr(start_object, "__name__"): + windowtitle = self.wid.GetWTitle() + self.wid.SetWTitle(windowtitle + " >> " + str(getattr(start_object, "__name__")) ) + + self.SetPort() + Qd.TextFont(3) + Qd.TextSize(9) + self.lists = [] + self.listitems = [] + for i in range(NUM_LISTS): + self.listitems.append(MAIN_LIST + 2 * i) # dlg item numbers... have to be consistent + for i in self.listitems: + tp, h, rect = self.wid.GetDialogItem(i) + list = MyList(self.wid, rect, i) + self.lists.append(list) + self.leftover = [] + self.rightover = [] + self.setup(start_object, title) + + def close(self): + self.lists = [] + self.listitems = [] + self.do_postclose() + + def setup(self, start_object, title = ""): + # here we set the starting point for our expedition + self.start = start_object + self.lists[0].setcontent(start_object, title) + for list in self.lists[1:]: + list.setcontent(None) + + def do_listhit(self, event, item): + (what, message, when, where, modifiers) = event + Qd.SetPort(self.wid) + where = Qd.GlobalToLocal(where) + for list in self.lists: + list.active = 0 + list = self.lists[self.listitems.index(item)] + list.active = 1 + for l in self.lists: + l.drawframe() + + point = (0,0) + ok, point = list.list.LGetSelect(1, point) + if ok: + oldsel = point[1] + else: + oldsel = -1 + # This should be: list.list.LClick(where, modifiers) + # Since the selFlags field of the list is not accessible from Python I have to do it like this. + # The effect is that you can't select more items by using shift or command. + list.list.LClick(where, 0) + + index = self.listitems.index(item) + 1 + point = (0,0) + ok, point = list.list.LGetSelect(1, point) + if oldsel == point[1]: + return # selection didn't change, do nothing. + if not ok: + for i in range(index, len(self.listitems)): + self.lists[i].setcontent(None) + self.rightover = [] + return + + if point[1] >= len(list.keylist): + return # XXX is this still necessary? is ok really true? + key = str(list.keylist[point[1]]) + value = list.valuelist[point[1]] + + self.settextitem("") + thetype = type(value) + if thetype == ListType or \ + thetype == TupleType or \ + thetype == DictType or \ + hasattr(value, "__dict__") or \ + hasattr(value, "__methods__") or \ + hasattr(value, "__members__"): # XXX or, or... again: did I miss something? + if index >= len(self.listitems): + # we've reached the right side of our dialog. move everything to the left + # (by pushing the rightbutton...) + self.do_rightbutton(1) + index = index - 1 + newlist = self.lists[index] + newlist.setcontent(value, key) + else: + index = index - 1 + self.settextitem( str(value) + "\r" + cleantype(value)) + for i in range(index + 1, len(self.listitems)): + self.lists[i].setcontent(None) + self.rightover = [] + + # helper to set the big text item at the bottom of the dialog. + def settextitem(self, text): + tp, h, rect = self.wid.GetDialogItem(MAIN_TEXT) + Dlg.SetDialogItemText(h, text[:255]) + + def do_rawupdate(self, window, event): + Qd.SetPort(self.wid) + iType, iHandle, iRect = window.GetDialogItem(MAIN_LINE) + Qd.FrameRect(iRect) + for list in self.lists: + Qd.FrameRect(list.rect) + if list.active: + # see MyList.drawframe + rect2 = Qd.InsetRect(list.rect, -3, -3) + save = Qd.GetPenState() + Qd.PenSize(2, 2) + Qd.FrameRect(rect2) + Qd.SetPenState(save) + for list in self.lists: + list.list.LUpdate(self.wid.GetWindowPort().visRgn) + + def do_activate(self, activate, event): + for list in self.lists: + list.list.LActivate(activate) + + # scroll everything one 'unit' to the left + # XXX I don't like the way this works. Too many 'manual' assignments + def do_rightbutton(self, force = 0): + if not force and self.rightover == []: + return + self.scroll(-1) + point = (0, 0) + ok, point = self.lists[0].list.LGetSelect(1, point) + self.leftover.append(point, self.lists[0].content, self.lists[0].title, self.lists[0].active) + for i in range(len(self.lists)-1): + point = (0, 0) + ok, point = self.lists[i+1].list.LGetSelect(1, point) + self.lists[i].setcontent(self.lists[i+1].content, self.lists[i+1].title) + self.lists[i].list.LSetSelect(ok, point) + self.lists[i].list.LAutoScroll() + self.lists[i].active = self.lists[i+1].active + self.lists[i].drawframe() + if len(self.rightover) > 0: + point, content, title, active = self.rightover[-1] + self.lists[-1].setcontent(content, title) + self.lists[-1].list.LSetSelect(1, point) + self.lists[-1].list.LAutoScroll() + self.lists[-1].active = active + self.lists[-1].drawframe() + del self.rightover[-1] + else: + self.lists[-1].setcontent(None) + self.lists[-1].active = 0 + for list in self.lists: + list.drawframe() + + # scroll everything one 'unit' to the right + def do_leftbutton(self): + if self.leftover == []: + return + self.scroll(1) + if self.lists[-1].content <> None: + point = (0, 0) + ok, point = self.lists[-1].list.LGetSelect(1, point) + self.rightover.append(point, self.lists[-1].content, self.lists[-1].title, self.lists[-1].active ) + for i in range(len(self.lists)-1, 0, -1): + point = (0, 0) + ok, point = self.lists[i-1].list.LGetSelect(1, point) + self.lists[i].setcontent(self.lists[i-1].content, self.lists[i-1].title) + self.lists[i].list.LSetSelect(ok, point) + self.lists[i].list.LAutoScroll() + self.lists[i].active = self.lists[i-1].active + self.lists[i].drawframe() + if len(self.leftover) > 0: + point, content, title, active = self.leftover[-1] + self.lists[0].setcontent(content, title) + self.lists[0].list.LSetSelect(1, point) + self.lists[0].list.LAutoScroll() + self.lists[0].active = active + self.lists[0].drawframe() + del self.leftover[-1] + else: + self.lists[0].setcontent(None) + self.lists[0].active = 0 + + # create some visual feedback when 'scrolling' the lists to the left or to the right + def scroll(self, leftright): # leftright should be 1 or -1 + # first, build a region containing all list rectangles + myregion = Qd.NewRgn() + mylastregion = Qd.NewRgn() + for list in self.lists: + AddRect2Rgn(list.rect, myregion) + AddRect2Rgn(list.rect, mylastregion) + # set the pen, but save it's state first + self.SetPort() + save = Qd.GetPenState() + Qd.PenPat(Qd.qd.gray) + Qd.PenMode(srcXor) + # how far do we have to scroll? + distance = self.lists[1].rect[0] - self.lists[0].rect[0] + step = 30 + lasttime = time.clock() # for delay + # do it + for i in range(0, distance, step): + if i <> 0: + Qd.FrameRgn(mylastregion) # erase last region + Qd.OffsetRgn(mylastregion, step * leftright, 0) + # draw gray region + Qd.FrameRgn(myregion) + Qd.OffsetRgn(myregion, step * leftright, 0) + while time.clock() - lasttime < 0.05: + pass # delay + lasttime = time.clock() + # clean up after your dog + Qd.FrameRgn(mylastregion) + Qd.SetPenState(save) + + def reset(self): + for list in self.lists: + point = (0,0) + ok, point = list.list.LGetSelect(1, point) + if ok: + sel = list.keylist[point[1]] + list.setcontent(list.content, list.title) + if ok: + list.list.LSetSelect(1, (0, list.keylist.index(sel))) + list.list.LAutoScroll() + + def do_itemhit(self, item, event): + if item in self.listitems: + self.do_listhit(event, item) + elif item == MAIN_LEFT: + self.do_leftbutton() + elif item == MAIN_RIGHT: + self.do_rightbutton() + elif item == MAIN_CLOSE: + self.close() + elif item == MAIN_RESET: + self.reset() + +# helper function that returns a short string containing the type of an arbitrary object +# eg: cleantype("wat is dit nu weer?") -> '(string)' +def cleantype(obj): + # type() typically returns something like: + items = string.split(str(type(obj)), "'") + if len(items) == 3: + return '(' + items[1] + ')' + else: + # just in case, I don't know. + return str(type(obj)) + +# helper for VarBrowser.scroll +def AddRect2Rgn(theRect, theRgn): + rRgn = Qd.NewRgn() + Qd.RectRgn(rRgn, theRect) + Qd.UnionRgn(rRgn, theRgn, theRgn) + + +if __name__ == "__main__": + main() diff --git a/Mac/Tools/twit/mactwit_edit.py b/Mac/Tools/twit/mactwit_edit.py new file mode 100644 index 0000000..ace253d --- /dev/null +++ b/Mac/Tools/twit/mactwit_edit.py @@ -0,0 +1,24 @@ +"""Edit a file using the MetroWerks editor. Modify to suit your needs""" + +import MacOS +import aetools +import Metrowerks_Shell_Suite +import Required_Suite + +_talker = None + +class MWShell(aetools.TalkTo, + Metrowerks_Shell_Suite.Metrowerks_Shell_Suite, + Required_Suite.Required_Suite): + pass + +def edit(file, line): + global _talker + if _talker == None: + _talker = MWShell('CWIE', start=1) + try: + _talker.open(file) + _talker.Goto_Line(line) + except "(MacOS.Error, aetools.Error)": + pass + diff --git a/Mac/Tools/twit/mactwit_mod.py b/Mac/Tools/twit/mactwit_mod.py new file mode 100644 index 0000000..e3a42bb --- /dev/null +++ b/Mac/Tools/twit/mactwit_mod.py @@ -0,0 +1,92 @@ +# A stab at a python debugger +import Res +import Qd +import Dlg +import Win +import FrameWork +import EasyDialogs +import sys +from mac_widgets import MT_AnyList, MT_IconTextWidget + +# Our dialogs +ID_MODULES=512 +I_MODULES_TITLE=1 +I_MODULES=2 +I_VARS_TITLE=3 +I_VARS=4 +I_SOURCE_TITLE=5 +I_SOURCE=6 +I_RULER=7 +I_EDIT=8 + +class ModuleBrowser(FrameWork.DialogWindow): + """The module-browser dialog - mac-dependent part""" + def open(self, module): + FrameWork.DialogWindow.open(self, ID_MODULES) + self.SetPort() + Qd.TextFont(3) + Qd.TextSize(9) + self.mi_open(module) + + def create_items(self): + """Create the lists we need""" + tp, h, rect = self.wid.GetDialogItem(I_MODULES) + self.modules = MT_AnyList(self.wid, rect, 1) + tp, h, rect = self.wid.GetDialogItem(I_VARS) + self.vars = MT_AnyList(self.wid, rect, 2) + tp, h, rect = self.wid.GetDialogItem(I_SOURCE) + self.source = MT_IconTextWidget(self.wid, rect) + + def setsource(self, msg): + tp, h, rect = self.wid.GetDialogItem(I_SOURCE_TITLE) + if self.cur_source: + Dlg.SetDialogItemText(h, self.cur_source) + else: + Dlg.SetDialogItemText(h, msg) + self.source.setcontent(self.cur_source) + + def do_itemhit(self, item, event): + (what, message, when, where, modifiers) = event + Qd.SetPort(self.wid) + where = Qd.GlobalToLocal(where) + + if item == I_MODULES: + new_module, double = self.modules.click(where, 0) + self.click_module(new_module) + elif item == I_VARS: + new_var, double = self.vars.click(where, 0) + if double: + self.click_var(new_var) + elif item == I_SOURCE: + lineno, inborder = self.source.click(where, 0) + if lineno <> None and lineno >= 0: + self.click_source(lineno, inborder) + elif item == I_EDIT: + self.click_edit() + + def do_rawupdate(self, window, event): + Qd.SetPort(self.wid) + rgn = self.wid.GetWindowPort().visRgn + tp, h, rect = self.wid.GetDialogItem(I_RULER) + Qd.MoveTo(rect[0], rect[1]) + Qd.LineTo(rect[2], rect[1]) + self.modules.update(rgn) + self.vars.update(rgn) + self.source.update(rgn) + + def do_activate(self, activate, event): + self.modules.activate(activate) + self.vars.activate(activate) + self.source.activate(activate) + + def close(self): + self.parent.module_dialog = None + self.source.close() + del self.modules + del self.vars + del self.source + self.do_postclose() + +if __name__ == '__main__': + main() + diff --git a/Mac/Tools/twit/mactwit_stack.py b/Mac/Tools/twit/mactwit_stack.py new file mode 100644 index 0000000..fa0cba6 --- /dev/null +++ b/Mac/Tools/twit/mactwit_stack.py @@ -0,0 +1,191 @@ +# A stab at a python debugger +import Res +import Qd +import Dlg +import Win +import FrameWork +import EasyDialogs +import sys +from mac_widgets import MT_AnyList, MT_IndexList, MT_IconTextWidget + +# Our dialogs +ID_STACK=513 +I_STACK_TITLE=1 +I_STACK=2 +I_VARS_TITLE=3 +I_VARS=4 +I_SOURCE_TITLE=5 +I_SOURCE=6 +I_EXC_TITLE=7 +I_EXC=8 +I_EXCVALUE_TITLE=9 +I_EXCVALUE=10 +I_QUIT=11 +I_CONTINUE=12 +I_STEP=13 +I_BROWSE=14 +I_RULER1=15 +I_RULER2=16 +I_STATE_TITLE=17 +I_STATE=18 +I_STEP_IN=19 +I_STEP_OUT=20 +I_RUN=21 +I_SHOW_COMPLEX=22 +I_SHOW_SYSTEM=23 +I_EDIT=24 + +class StackBrowser(FrameWork.DialogWindow): + """The stack-browser dialog - mac-dependent part""" + def open(self): + FrameWork.DialogWindow.open(self, ID_STACK) + self.SetPort() + Qd.TextFont(3) + Qd.TextSize(9) + self.mi_open() + + def create_items(self): + """Create the lists we need""" + tp, h, rect = self.wid.GetDialogItem(I_STACK) + self.stack = MT_IndexList(self.wid, rect, 2) + tp, h, rect = self.wid.GetDialogItem(I_VARS) + self.vars = MT_AnyList(self.wid, rect, 2) + tp, h, rect = self.wid.GetDialogItem(I_SOURCE) + self.source = MT_IconTextWidget(self.wid, rect) + + def setsource(self, msg): + tp, h, rect = self.wid.GetDialogItem(I_SOURCE_TITLE) + if self.cur_source: + Dlg.SetDialogItemText(h, self.cur_source) + else: + Dlg.SetDialogItemText(h, msg) + self.source.setcontent(self.cur_source) + + def setexception(self, name, value): + print 'SETEXC', (name, value) + if name == None: + self.wid.HideDialogItem(I_EXC) + self.wid.HideDialogItem(I_EXC_TITLE) + value = None + else: + self.wid.ShowDialogItem(I_EXC) + self.wid.ShowDialogItem(I_EXC_TITLE) + tp, h, rect = self.wid.GetDialogItem(I_EXC) + Dlg.SetDialogItemText(h, name) + if value == None: + self.wid.HideDialogItem(I_EXCVALUE) + self.wid.HideDialogItem(I_EXCVALUE_TITLE) + else: + self.wid.ShowDialogItem(I_EXCVALUE) + self.wid.ShowDialogItem(I_EXCVALUE_TITLE) + tp, h, rect = self.wid.GetDialogItem(I_EXCVALUE) + Dlg.SetDialogItemText(h, value) + + def setprogramstate(self, msg): + tp, h, rect = self.wid.GetDialogItem(I_STATE) + Dlg.SetDialogItemText(h, msg) + + def setsession_none(self): + """Nothing running, no stack trace""" + self.wid.HideDialogItem(I_CONTINUE) + self.wid.HideDialogItem(I_STEP) + self.wid.HideDialogItem(I_STEP_IN) + self.wid.HideDialogItem(I_STEP_OUT) + self.wid.ShowDialogItem(I_RUN) + + def setsession_run(self): + """Running""" + self.wid.HideDialogItem(I_RUN) + self.wid.ShowDialogItem(I_CONTINUE) + self.wid.ShowDialogItem(I_STEP) + self.wid.ShowDialogItem(I_STEP_IN) + self.wid.ShowDialogItem(I_STEP_OUT) + + def setsession_pm(self): + """Post-mortem debugging""" + self.wid.HideDialogItem(I_CONTINUE) + self.wid.HideDialogItem(I_STEP) + self.wid.HideDialogItem(I_STEP_IN) + self.wid.HideDialogItem(I_STEP_OUT) + self.wid.HideDialogItem(I_RUN) + + def setsession_none(self): + """Nothing running, no stack trace""" + self.wid.HideDialogItem(I_CONTINUE) + self.wid.HideDialogItem(I_STEP) + self.wid.HideDialogItem(I_STEP_IN) + self.wid.HideDialogItem(I_STEP_OUT) + self.wid.ShowDialogItem(I_RUN) + + + def do_itemhit(self, item, event): + (what, message, when, where, modifiers) = event + Qd.SetPort(self.wid) + where = Qd.GlobalToLocal(where) + + print 'STACKHIT', item + + if item == I_STACK: + new_stackitem, double = self.stack.click(where, 0) + self.click_stack(new_stackitem) + elif item == I_VARS: + new_var, double = self.vars.click(where, 0) + if double: + self.click_var(new_var) + elif item == I_SOURCE: + lineno, inborder = self.source.click(where, 0) + if lineno <> None and lineno >= 0: + self.click_source(lineno, inborder) + elif item == I_QUIT: + self.click_quit() + elif item == I_CONTINUE: + self.click_continue() + elif item == I_STEP: + self.click_step() + elif item == I_STEP_IN: + self.click_step_in() + elif item == I_STEP_OUT: + self.click_step_out() + elif item == I_BROWSE: + self.click_browse() + elif item == I_RUN: + self.click_run() + elif item == I_SHOW_COMPLEX: + self.show_complex = not self.show_complex + self.setup_frame() + elif item == I_SHOW_SYSTEM: + self.show_system = not self.show_system + self.setup_frame() + elif item == I_EDIT: + self.click_edit() + + def set_var_buttons(self): + tp, h, rect = self.wid.GetDialogItem(I_SHOW_COMPLEX) + h.as_Control().SetControlValue(self.show_complex) + tp, h, rect = self.wid.GetDialogItem(I_SHOW_SYSTEM) + h.as_Control().SetControlValue(self.show_system) + + def do_rawupdate(self, window, event): + Qd.SetPort(self.wid) + rgn = self.wid.GetWindowPort().visRgn + tp, h, rect = self.wid.GetDialogItem(I_RULER1) + Qd.MoveTo(rect[0], rect[1]) + Qd.LineTo(rect[2], rect[1]) + tp, h, rect = self.wid.GetDialogItem(I_RULER2) + Qd.MoveTo(rect[0], rect[1]) + Qd.LineTo(rect[2], rect[1]) + self.stack.update(rgn) + self.vars.update(rgn) + self.source.update(rgn) + + def do_activate(self, activate, event): + self.stack.activate(activate) + self.vars.activate(activate) + self.source.activate(activate) + + def close(self): + self.source.close() + del self.stack + del self.vars + del self.source + self.do_postclose() diff --git a/Mac/Tools/twit/twit.py b/Mac/Tools/twit/twit.py new file mode 100644 index 0000000..6054939 --- /dev/null +++ b/Mac/Tools/twit/twit.py @@ -0,0 +1,94 @@ +"""twit - The Window-Independent Tracer. + +Interface: +twit.main() Enter debugger in inactive interactive state +twit.run(stmt, globals, locals) Enter debugger and start running stmt +twit.post_mortem(traceback) Enter debugger in post-mortem mode on traceback +twit.pm() Enter debugger in pm-mode on sys.last_traceback + +main program: nothing but a bit of glue to put it all together. + +Jack Jansen, CWI, August 1996.""" + +import os +if os.name == 'mac': + import MacOS + MacOS.splash(515) # Try to show the splash screen + import mactwit_mod; twit_mod = mactwit_mod + import mactwit_stack; twit_stack = mactwit_stack + import mactwit_app; twit_app = mactwit_app + import mactwit_browser; twit_browser = mactwit_browser + import mactwit_edit; twit_edit = mactwit_edit +else: + try: + import _tkinter + have_tk = 1 + except ImportError: + have_tk = 0 + if have_tk: + import tktwit_mod; twit_mod = tktwit_mod + import tktwit_stack; twit_stack = tktwit_stack + import tktwit_app; twit_app = tktwit_app + else: + print 'Please implementent twit_mod, twit_stack and twit_app and try again:-)' + sys.exit(1) + +import TwitCore +import sys + +class Twit(twit_app.Application, TwitCore.Application): + + def new_module_browser(self, *args): + return apply(TWIT_ModuleBrowser, args) + + def new_stack_browser(self, *args): + return apply(TWIT_StackBrowser, args) + + def new_var_browser(self, *args): + return apply(TWIT_VarBrowser, args) + + def edit(self, *args): + return apply(twit_edit.edit, args) + +class TWIT_ModuleBrowser(twit_mod.ModuleBrowser, TwitCore.ModuleBrowser): + pass + +class TWIT_StackBrowser(twit_stack.StackBrowser, TwitCore.StackBrowser): + pass + +def TWIT_VarBrowser(parent, var): + return twit_browser.VarBrowser(parent).open(var) + +def Initialize(): + # Gross... + TwitCore.AskString = twit_app.AskString + TwitCore.SetWatch = twit_app.SetWatch + TwitCore.SetCursor = twit_app.SetCursor + +def main(): + twit_app.Initialize() + TwitCore.Initialize() + Initialize() + if os.name == 'mac': + MacOS.splash() + Twit(None, None) + +def run(statement, globals=None, locals=None): + twit_app.Initialize() + TwitCore.Initialize() + Initialize() + Twit((statement, globals, locals), None) + +def post_mortem(t): + twit_app.Initialize() + TwitCore.Initialize() + Initialize() + Twit(None, t) + +def pm(): + post_mortem(sys.last_traceback) + +if __name__ == '__main__': + main() + + diff --git a/Mac/Tools/twit/twit.rsrc.hqx b/Mac/Tools/twit/twit.rsrc.hqx new file mode 100644 index 0000000..00fd0dc --- /dev/null +++ b/Mac/Tools/twit/twit.rsrc.hqx @@ -0,0 +1,482 @@ +(This file must be converted with BinHex 4.0) + +:#A4hDA3ZFR0bB`"bFh*M8P0&4!%!N!GHp1!K!*!%!3!!!&eR!!"FC`!!!Bd!!!$ +`DIrr)"H6)!!#JH$`Drrr)"H8*!#3"2"[rrmJ#A4hDA3ZFR0bB`)!!!"bFh*M8P0 +&4!%!!$!!DJ#3"R*cFQ058d9%!3!!-!"U!*!5VM8Gq!#3"Pld!2"frrmJ&ja%!*! +%m(Irrb!AR8J!N!6`H2rr)"HH6!#3"2"jrrmJ&jp3!*!%m(Vrrb!AS&3!N!6`Hrr +r)"HK@!#3"2"mrrpJ&k*F!*!%m(hrrb!ASf!!N!6`J2rr)"HNC!#3"32rrb!AT@J +!!R3S[i6rrb!A6b!!N!3U!%`!D!&i!KS!"!%!!3#3"3)!&94hDA3J,5"0Ef4eE'8 +JBR*[Gh0PFJ!!!#m!+J!3!F-"e!!%!3#3"`)"'P4hDA3J,5"6G'&MDb"dFQ&MC5" +LFQphFf9b!!!)qJMk!*!&#`!-!"%#r``!rrj9Y!")!!!!5!#3"`X!$!'"&P!!(J! +"!!S!N!8,!!`!QB!-!*!&#`!-!*!*5!!!!%J!N!8)!!%!#!#3"!'"($3!N!BNQr8 +'!2m!!2q3"J!"rj!%c-`!![q3"*QC!!2rN!4QCJ!%rj!%-c-!"Iq3"!!!!!Errmc +-rrm!"rrrc*!%!!Mrrmc-QCN!#Irrc-aQCJ!+rrr-c$-c!![rrmc-!!!!$2rrQCR +rr`!0rrqCQFc-!!lrrjQ3"!!2rrqCQ@CQ!"$rrjQC-c-!%IrrQCN!!!!5rrpQC[r +r!"2rrfCQc-`!&2rrCQDCQ3!9rrpQN!3!&[rrCQBc-`!ArrpQCJ!!!"Mrrc-crrm +!'Irr-c2-c!!Drrmc-jQC!"[rrc-cCQB!(2rr-j!%!"hrrc-c!!!!([rr!!$rr`! +Irrm!!-c-!#$rr`!!QCN!)Irr!!"QCJ!Lrrm!!$-c!#2rr`#3"56-c2q3"!!Pc-c +rrmc-!#E-c2rrQCN!*mc-rrpQCJ!Sc-crrc-c!#R-c2rr!!!!+Xb3"2rr!#[-N!B +!,-b3"*QC!#h-N!4QCJ!Zc*!%-c-!,mb3"!!!!$$-c*QCrrm!-Fc-QCR-c!!bc-b +CN!3!-mc-QCPQCJ!dc-bCQ6-c!$A-c*QC!!!!0Xc-CQErr`!hc-aQCXc-!$M-c'C +QQCN!1Fc-CT!%!$V-c'CQ-c-!1mc-CQB!!!!mc-`c-rrr!$h-c$-cc-`!2Xc--c1 +CQ3!rc-`c-fCQ!%$-c$13"!""c-`c-`!!!%,-c!!!rrm!3mc-!!$-c!"%c-`!!*Q +C!%A-c!!!CQB!4Xc-!!!c-`"(c-`!N!9)QCRrN!3!5CQCrrr-c!"+QCRrrjQC!%Z +CQIrrCQB!6*QCrrmc-`"0QCRrr`!!!%kCQFc-rrm!6jQCc*!%!&#CQFc-QCN!8CQ +Cc-aQCJ"5QCR-c$-c!&1CQFc-!!!!9*Q3"2rr!&@CN!6-c!"@QC!'!&HCN!4QCJ" +BQC!%-c-!@CQ3"!!!!&UCQ@CQrrm!@jQCCQE-c!"FQCPQCTQC!&fCQ@D3"!"HQCP +QCM-c!&qCQ@CQ!!!!B*QC-c2rr`"KQCNc-mc-!'+CQ6-cQCN!BjQC-c0QCJ"NQCN +cN!3!CCQC-c-!!!"QQCN!!2rr!'HCQ3!!c-`!D*QC!!#CQ3"TQCN!!'CQ!'UCQ3! +!-c-!DjQC!*!&E'CQrj!%!'eQC[rrc-`!EQCQrrqCQ3"[CQErrfCQ!("QC[rr-c- +!F@CQrrm!!!"bCQE-c2rr!(0QCXb3"!"dCQE-c*QC!(9QCXc-CQB!GQCQc-`c-`" +hCQE-c!!!!(KQCTQCrrm!H@CQQCR-c!"kCQDCN!3!HfCQQCPQCJ"mCQDCQ6-c!(e +QCTQC!!!!IQD3"2rr!(pQN!6-c!#!CT!%QCN!J@D3"J##CT!%-c-!JfD3"!!!!)4 +QCM-crrm!K@CQ-c2-c!#'CQBc-jQC!)GQCM-cCQB!L'CQ-j!%!)PQCM-c!!!!LQC +Q!!$rr`#,CQB!!-c-!)aQCJ!!QCN!M@CQ!!"QCJ#1CQB!!$-c!)pQCJ#3"C!!-c2 +rN!3!N6-crrr-c!#5-c2rrjQC!*-c-rrrCQB!P$-crrmc-`#9-c2rr`!!!*Bc-mc +-rrm!Pc-cc*!%!*Jc-mc-QCN!Q6-cc-aQCJ#D-c2-c$-c!*Xc-mc-!!!!R$-cQCR +rr`#G-c1CQFc-!*ic-jQ3"!#I-c1CQ@CQ!+!c-jQC-c-!S6-cQCN!!!#L-c0QC[r +r!+-c-fCQc-`!T$-cCQDCQ3#P-c0QN!3!TM-cCQBc-`#R-c0QCJ!!!+JcN!6rr`# +T-j!%c-`!UM13"*QC!+XcN!4QCJ#X-j!'!+dcN!3!!!#Z-c-!!2rr!+mc-`!!c-` +!X$-c!!#CQ3#a-c-!!'CQ!,)c-`!!-c-!Xc-c!*!&Y!!!rj!%!,8!!2rrc-`!YJ! +!rrqCQ3#h!!$rrfCQ!,J!!2rr-c-!Z3!!rrm!!!#k!!$-c2rr!,X!!-b3"!#m!!$ +-c*QC!,d!!-c-CQB![J!!c-`c-`#r!!$-c!!!!-!!!*QCrrm!`3!!QCR-c!$#!!# +CN!3!``!!QCPQCJ$%!!#CQ6-c!-8!!*QC!!!!aJ!!CQErr`$(!!"QCXc-!-J!!'C +QQCN!b3!!CT!%!-S!!'CQ-c-!b`!!CQB!!!$-!!!c-rrr!-d!!$-cc-`!cJ!!-c1 +CQ3$2!!!c-fCQ!0!!!$13"!$4!!!c-`!!!0)!N!6rr`$6!*!%c-`!e!#3"*QC!08 +!N!4QCJ$@!*!%-c-!eqlZ!*!&f0hG!*!&fEZl!*!&fUUU!*!&fiL)!*!&h(Gh!*! +&h999!*!&hN4%!*!&hb)L!*!&i"%4!*!&i3!!lZi!!!$L!!$Gh3!!!1-!!,Zl!!! +!j!!!UUS!!!$P!!#)L!!!!1B!!(Gh!!!!j`!!998!!!$S!!"%4!!!!1N!!#)L!!! +!kJ!!%4%!!!$V!*!%lZi!l!#3"0hG!1d!N!5lZ`$Z!*!%UUS!l`#3")L)!2!!N!4 +hG`$a!*!%998!mJ#3"%4%!2-!N!3L)J$d!*!%%4%!pHk3"J$fhC!'!2HlN!B!q+U +3"J$jL*!'!2ThN!B!qe@3"J$m4*!'!2dLN!B!rK'3"J$r!*!,#`!-!*!&#`!-!%! +!#J#3"3X!$!Ep!!$rqJ!(r3!"rrrl!!Mp!!,r92rm!!S!!2hr!J"8rrd!$!J!r`" +8!&3!92rq!!d,!2p8!&3!9!"8r`!!$!J!r`"8!&3!92rq!!S!!2hr!J"8rrd!#2d +!![p8rr`!"rd!!Irrq`!'r3!!rrS!!2m!!!MX#1`!N!8,!!`!%3,r$!$rrP@d!%J +!!!")!*!(#`!-!B%@8!!H!!%!#J#3"3X!$!#CJ!`!N!8,!!`!N!P)!!!!5!#3"3J +!!3!)!*!%!B%F3!#3"Lm'i#-!r`!!rj!'!!(rN!6-c!!#rj!%QCN!!rq3"'CQ!!6 +rN!3c-`!&rj!%!!!!"[rrc-crr`!(rrr-N!3!#2rrc-bCQ3!*rrr-c'CQ!!Vrrmc +--c-!#rrrc-`!!!!-rrqCQIrr!!hrrjQCc-`!$[rrQC!%!!rrrjQCCQB!%2rrQCN +c-`!4rrqCQ3!!!",rrfCQrrm!%rrrCQE-c!!8rrpQCTQC!"ArrfD3"!!@rrpQCM- +c!"IrrfCQ!!!!'2rr-c2rr`!Crrmc-mc-!"Vrrc-cQCN!'rrr-c0QCJ!FrrmcN!3 +!(Irr-c-!!!!Hrrm!!2rr!"rrr`!!c-`!)2rr!!#CQ3!Krrm!!'CQ!#,rr`!!-c- +!)rrr!*!&*-c-rj!%!#A-c2rrc-`!*Xc-rrqCQ3!Rc-crrfCQ!#M-c2rr-c-!+Fc +-rrm!!!!Uc*!%rrm!+mb3"J!Xc*!%QCN!,Fb3"'CQ!#l-N!3c-`![c*!%!!!!--c +-QCRrr`!ac-bCQFc-!$,-c*Q3"!!cc-bCQ@CQ!$6-c*QC-c-!0Fc-QCN!!!!fc-a +QC[rr!$I-c'CQc-`!1-c-CQDCQ3!jc-aQN!3!1Xc-CQBc-`!lc-aQCJ!!!$c-c$- +crrm!2Fc--c2-c!!qc-`c-jQC!$r-c$-cCQB!3-c--j!%!%(-c$-c!!!!3Xc-!!$ +rr`"$c-`!!-c-!%6-c!!!QCN!4Fc-!!"QCJ"'c-`!!$-c!%I-c!#3"8LCQIq3"!" +*QCRrrmc-!%UCQIrrQCN!5jQCrrpQCJ"-QCRrrc-c!%fCQIrr!!!!6TQCc-crr`" +2QCR-N!3!8*QCc-bCQ3"4QCR-c'CQ!&+CQFc--c-!8jQCc-`!!!"8QC!%rrm!9CQ +3"-c-!&DCN!B!9jQ3"'CQ!&LCN!3c-`"CQC!%!!!!@TQCCQErr`"EQCPQCXc-!&b +CQ@CQQCN!ACQCCT!%!&kCQ@CQ-c-!AjQCCQB!!!"JQCNc-rrr!''CQ6-cc-`!BTQ +C-c1CQ3"MQCNc-fCQ!'5CQ613"!"PQCNc-`!!!'DCQ3!!rrm!CjQC!!$-c!"SQCN +!!*QC!'QCQ3!!CQB!DTQC!!!c-`"VQCN!N!9XCQErN!3!E@CQrrr-c!"ZCQErrjQ +C!'pQC[rrCQB!F'CQrrmc-`"aCQErr`!!!(*QCXc-rrm!FfCQc*!%!(4QCXc-QCN +!G@CQc-aQCJ"fCQE-c$-c!(GQCXc-!!!!H'CQQCRrr`"jCQDCQFc-!(TQCTQ3"!" +lCQDCQ@CQ!(aQCTQC-c-!I@CQQCN!!!"qCT!%rrm!IfD3"-c-!)"QN!5CQ3#"CT! +'!)*QN!3c-`#$CT!%!!!!K'CQ-c2rr`#&CQBc-mc-!)CQCM-cQCN!KfCQ-c0QCJ# +)CQBcN!3!L@CQ-c-!!!#+CQB!!2rr!)YQCJ!!c-`!M'CQ!!#CQ3#0CQB!!'CQ!)j +QCJ!!-c-!MfCQ!*!&N!!c-rq3"!#4-c2rrmc-!*)c-rrrQCN!Nc-crrpQCJ#8-c2 +rrc-c!*8c-rrr!!!!PM-cc-crr`#A-c2-N!3!Q$-cc-bCQ3#C-c2-c'CQ!*Sc-mc +--c-!Qc-cc-`!!!#F-c1CQIrr!*dc-jQCc-`!RM-cQC!%!*mc-jQCCQB!S$-cQCN +c-`#K-c1CQ3!!!+)c-fCQrrm!Sc-cCQE-c!#N-c0QCTQC!+8c-fD3"!#Q-c0QCM- +c!+Fc-fCQ!!!!U$13"2rr!+NcN!6-c!#U-j!%QCN!Uc13"'CQ!+`cN!B!V613"!! +!!+ic-`!!rrm!Vc-c!!$-c!#`-c-!!*QC!,%c-`!!CQB!XM-c!!!c-`#c-c-!N!@ +d!!$rN!3!Y3!!rrr-c!#f!!$rrjQC!,F!!2rrCQB!Z!!!rrmc-`#j!!$rr`!!!,S +!!-c-rrm!Z`!!c*!%!,`!!-c-QCN![3!!c-aQCJ#q!!$-c$-c!,m!!-c-!!!!`!! +!QCRrr`$"!!#CQFc-!-)!!*Q3"!$$!!#CQ@CQ!-3!!*QC-c-!a3!!QCN!!!$'!!" +QC[rr!-F!!'CQc-`!b!!!CQDCQ3$*!!"QN!3!bJ!!CQBc-`$,!!"QCJ!!!-`!!$- +crrm!c3!!-c2-c!$1!!!c-jQC!-m!!$-cCQB!d!!!-j!%!0%!!$-c!!!!dJ#3"2r +r!0-!N!6-c!$8!*!%QCN!e3#3"'CQ!0B!N!3c-`$AlZi!N!ABhGd!N!ACZlX!N!A +DUUS!N!AEL)J!N!AFGhF!N!AG998!N!AH4%3!N!AI)L)!N!AJ%4%!N!AK!!$ZlJ! +!!1)!!0hG!!!!i`!!ZlX!!!$N!!#UUJ!!!18!!)L)!!!!jJ!!GhF!!!$R!!"993! +!!1J!!%4%!!!!k3!!)L)!!!$U!!!4%3!!!1X!N!6ZlJ$X!*!%hGd!l3#3",Zl!1i +!N!5UUJ$[!*!%L)J!m!#3"(Gh!2%!N!4993$b!*!%4%3!m`#3"#)L!23!N!34%3$ +elT!'!2EGN!B!plZ3"J$iUT!'!2Q)N!B!qRH3"J$l9C!'!2a%N!B!r5+3"J$q%C! +'!2m!N!X,!!`!N!8,!!`!3!!+!*!&#`!-"[i!r1$p!!S#!!$Jr#-!i2i!#3%!i2S +M!Z!!!!F!i2JM!H!!"`$Jq!!"i!!(!1$i!!(J!!F!i2J!!H!!"`$Jq#-"i!!*!3$ +JqL-#i!!!#J)!!1$m)`$JrJ!'rJ$mi2d!!2m!!!!`!*!("!!!lT!'!!%!N!F#!*! +(!`#3"`6rN!B!!!!9!#J!+!$`!EJ!!3#3#!)$!*!%)!!"!*!*b!'3!%!#!J)!N!8 +5!!S!Y3"3J!!!!%A%4F6rN!3!bJ'5!"%#r``!rj!'!!$rr`!!!C)!!!$+!*!((J! +"!!VrN!3!bJ'5!!F!N!8)!!S!)J'N!PS!!!#K!,B!"!!"!!%!S3#f!!3!!3!"!!% +!#J#3"FJ"N!!!QJ!!!2q$)J#3"FJ"N3!!!!-!N!9)!!!!5!!!!"!!%!!$!!8!N"( +)!C!!!*!&b!'3!!!!!!q"Glf"Glf"GlhaGld!Irm!$i&h[B&h[B&h[I&h[3"rr`! +2JAHpJAHpJAHpmAHp!(rr!!q"Glf"Glf"GlhaGld!Irm!$i&h[B&h[B&h[I&h[3" +rr`!2JAHpJAHpJAHpmAHp!(rr!!q"Glf"Glf"GlhaGld!Irm!$i&h[B&h[B&h[I& +h[3"rr`!2JAHpJAHpJAHpmAHp!(rr!!q"Glf"Glf"GlhaGld!Irm!$i&h[B&h[B& +h[I&h[3"rr`!2JAHpJAHpJAHpmAHp!(rr!!q"Glf"Glf"GlhaGld!Irm!$i&h[B& +h[B&h[I&h[3"rr`!2JAHpJAHpJAHpmAHp!(rr!!q"Glf"Glf"GlhaGld!Irm!$i& +h[B&h[B&h[I&h[3"rr`!2JAHpJAHpJAHpmAHp!(rr!!q"Glf"Glf"GlhaGld!Irm +!*0ph[3"-$2jh[3"-$2eh[IPrrrPh[3"-$)&h[B&h[Deh[3"rr`!NfhHp!%`-rAH +p!(rrqaJ6!(rrqAHp!%`-JAHpJAHpVAHp!(rr!#cLGld!6!clGld!6!cpGld(Irm +B%aJ6Iq"ri"J6'"0rri&h[B&h[D4h[3"rr`!ReRHp!(rrqaJ6!(rrcAHprJ!!aAH +prJ!!iAHprJ!!JAHp[AHp!(rr!&(LGld$6!ah[AHp6!cjGlhqIrm"'"-B%rjrrpe +h[I4m!2jh[Ii!!0Ph[Ijm!!&h[AHprA`!!AHpGlhqI!$lGlhq!!$KGlhq!!#"Glf +pGld!Irm!@Z*h[30-$(HpGle-$2jh[IPrr`%B%aJ6qArrrRHp!d`-Gleh[8`-kAH +pp(`!rRHprJ!!fAHprR`!!AHpGlhpI!!"Gleh[Ijm!0Kh[Ii!!+&h[Ii!!+"h[3" +rr`"HiRHp!d`-Gleh[8`-rRHp!(rrm4J6!(rrrRHp!%`-iAHprR`!qAHprJ!!rPl +hh(HprR`!!AHpGlhpI!!"Gleh[Ijm!2Kh[IjHpq4h[Ii!!2jHpk4h[Ii!!+"h[3" +rr`"QiRHp!d`-Gleh[8`-rRHp!(rrm4J6!(rrrRHp!%`-ihHp!9lhA[IqI!$jA[I +q!!$qA[IFGlhqI!!"A[GHprem!!&HpelhrR`!rPlhqhHprPlhj(HprJ!!rPlhT(H +prJ!!S(Hp!(rr!&rIGld%6!ah[AHpIrprrr%B%`GrrhrrGleh[8`-Gleh[8`-jRH +p!9lhA[IqI!$jA[Iq!!$qA[IFGlhiI!!"A[GHprjm!2jHppYh[Ii!!2jHpk4h[Ii +!!2jHpk0h[3"rr`$'iRHp"N`-Gleh[8`-Gleh[ArrlaJ6"RrrGleh[8`-Gleh[8` +-j(HprR`!rPlhr(HprJ!!!9lhA[Ip!!$iGlhm!!$XGlhiI!!$A[Gm!(`!GlhqA[I +l!!$iGlhq!!!"Gleh[Id!!2Kh[IN!!2jHpreh[I`!!2ah[Ii!!2jh[Ii!!2jh[Ii +!!1jh[IS!!2ah[Ii!!2Th[Ii!!2ah[IS!!2Ph[Ii!!2jHprGh[I`!!2ah[Ii!!!" +h[Ii!!!&h[AHprJ!!`hHp!(rr!*[LGld'6!ah[AHp6!ah[AHpIrr['"-$Irph[AH +p6!cKGlhqI!$qA[ImGlhh!!$lGlhi!!$ZGlheI!!!GlhqA[Il!!$iGlhh!!$lGlh +h!!$qA[F"Gleh[IJ!!2jh[Ii!!2jh[Ii!!2jh[Ii!!1ph[IJ!!2eh[Ii!!2Th[Ii +!!2eh[IJ!!2eh[I8!!2ah[IJ!!2jh[I3!!-4h[3"rr`$JiRHp"N`-Gleh[8`-Gle +rrhrrlaJ6!hrrIrph[8`-iAHprR`!rPlhr(Hpq`!!!(Hpr3!!rAHpr3!!rRHprJ! +!lRHppA`!!(HprPlhrRHprJ!!q(Hpq`!!!(Hpr3!!r(Hpr3!!rRHprJ!!rPlh!(H +pr3!!rRHpr3!!!AHpGlhq!!$qGlhp!!!"Gleh[Ii!!2"h[Id!!2eh[3%!N!6mGlh +q!!$mGlhq!!$pGlhp!!$pGld"!*!%rAHpp3!!rAHpr3!!rRHprJ!!rRHpr3!!!(H +pr3!!!(HprJ!!a(Hp!(rr!4ELGld!6!cpGld!IrrY'"-!IrrpGld!6!cNGlhqI!$ +qA[ImGlhm!!!#A[Gh[AHprJ!!!&lhrRHprJ!!rRHp!9lhA[Iq!!$[GlheI!!#Gle +HpelhrAHprJ!!rPlhqhHpr!!!!PlhGleh[Ii!!!"Hprjh[Ii!!2jh[3&HpelhrJ! +!rPlh!(HprJ!!rRHp!9lhA[Iq!!$qGlhq!!!!A[Im!!!%A[GHp`#3"(HprPlhmhH +prJ!!!AHpGlhkA[IqGlhq!!!"A[GHprjh[Ii!!!"h[IjHpri!!!&h[AHpqPlhr(H +prJ!!rPlhqRHprJ!!rRHp!9lhA[Iq!!!"Gleh[Id!!!"Hprd!!!"Hpri!!!&Hpel +haRHp!(rr!3ILGld!6!cpGld!IrrY'"-!IrrpGld!6!cNGlhqI!$qA[ImGlhp!!$ +pA[Iq!!!#A[GHphHprJ!!!AHpGlhpA[Iq!!!"A[GHpr&h[Iam!!"HprYm!2jHpre +h[Ii!!2jHprYh[Id!!2eHpri!!!0HpelhGleh[Ii!!!"h[IeHpri!!2jHpri!!!& +h[AHpr&lhrJ!!!9lhGlhq!!!!A[Im!!!!A[Iq!!!!GlhqA[IcGlhp!!$iA[IqGlh +q!!!!A[IqGlhq!!!!GlhqA[Ip!!$iA[IpGlhq!!$iA[Iq!!!"Gleh[IeHpri!!!& +HpelhrJ!!!9lhA[Iq!!!"A[GHpri!!2jHpmGh[3"rr`%4iRHp!%`-rRHp!ArrIrr +Y'"-"Irprrrjh[3"-$14h[Ijm!2jHprah[Ii!!2aHpri!!2jHpr8!!!&HpelhmAH +pr(`!!9lhA[ImI!$qA[IpGlhq!!$qA[IlGlhq!!$mA[Iq!!$qA[Iq!!!"Gleh[Ie +Hpri!!2jHpri!!!"h[IeHp`&h[AHprJ!!!9lhA[Iq!!!'A[F!N!4h[3#3"&lhrJ! +!!(HprPlhp`!!r(Hpr!!!!&lhrAHp!9lhA[IqGlhq!!!#A[GHphHprJ!!!(HprPl +h!AHpGlhm!!!!A[IpGld"A[GHpreh[Ii!!2KHpr8!!!&HpelhrJ!!!9lhA[Iq!!! +"A[GHpri!!2jHpmGh[3"rr`$XiRHp!%`-rRHp!(rrkaJ6!(rrrRHp!%`-j(HprR` +!rPlhr(HprJ!!r&lhrJ!!rPlhp3!!rPlhmRHpr(`!!9lhA[ImI!$qA[IpGlhq!!$ +qA[IlGlhq!!$mA[Iq!!$qA[Iq!!!!GlhqA[F"Gleh[Ii!!2jHpri!!!"h[IjHprj +h[Ii!!!&Hpelhq`!!!(Hpq`!!!hHpA[GHphHpp`!!qhHpqJ!!qAHprJ!!!9lhGlh +q!!!!GlhqA[IqGlhk!!$jGlhq!!$qA[IlGlhe!!!"A[GHpri!!!&HpelhrJ!!!9l +hA[Iq!!$qA[I(Gld!Irm!r1*h[3"-$2jh[3"rrqXB%`"rrrjh[3"-$14h[Ijm!2j +Hprah[Ii!!2eHp`"h[Ii!!2jHpri!!2jHprYh[IjHpr*h[Iam!!&Hpelhr(`!rPl +hrAHprJ!!rPlhqhHprJ!!r9lh!(HprJ!!rPlhrJ!!!(HprPlh!AHpGlhq!!$qA[I +q!!$qA[IpGlhq!!!"A[GHprX!!!"h[IX!!2jHpqph[3&Hpelhr!!!qRHprJ!!!&l +hrJ!!!AHpGlhqA[IpGld"A[GHpr`!!2Th[Ii!!2jHprYh[Ii!!2jHprYh[3&Hpel +hrJ!!!9lhA[Iq!!!"A[GHpri!!2jHpmGh[3"rr`$[iRHp"%`-Gleh[ArrIrrV'"- +%IrprrhHpGle-$14h[Ijm!2jHprah[Ii!!2jHp`&h[AHprJ!!rPlhrJ!!p9lhmRH +pr(`!!9lhA[ImI!$qA[IpGlhq!!$qA[IlGlhq!!$qA[F"Gleh[Ii!!2jHpri!!2j +Hp`&h[AHpr3!!rPlhrJ!!rPlhrAHprJ!!!9lhA[Im!!!"A[Gh[IX!!2jHpreh[IG +Hprah[IjHprd!!2Th[IX!!!"h[IjHprYh[IjHprd!!2Yh[Ii!!2jHprYh[Ii!!2C +Hpri!!!&HpelhrJ!!!9lhA[Iq!!$qA[I(Gld!Irm!qpph[3"rrqNB%`"rrq&h[Ij +m!2jHprah[Ii!!2jHp`&h[AHprJ!!rPlh!(HprJ!!pPlhmAHprA`!!9lhA[IpI!$ +pA[IpGlhq!!$qA[IlGlhq!!$qA[F"Gleh[Ii!!2jHpri!!2jHp`"h[I`!!2jHp`" +h[Ii!!!&HpelhrRHprJ!!!RHpA[GHpr`!!2jHpr`!!2jHpreh[IGHp`*h[3#3"2j +h[IjHpri!!!"HprYh[IX!!!"h[IjHp`0h[AHp!*!%rRHprPlhrJ!!!&lhr(HprJ! +!rPlhqRHprJ!!pelhrJ!!!9lhA[Iq!!!"A[GHpri!!2jHpmGh[3"rr`%'hhHp!(r +rk4J6!(rriAHprR`!rPlhr(HprJ!!rPlh!AHpGlhq!!$qA[F!Glhp!!!!A[IqGlh +q!!$ZGlhqI!$pA[IqI!$pA[IpGlhq!!$qA[IlGlhq!!$qA[F"Gleh[Ii!!2jHp`" +h[Ii!!!&Hpelhq`!!rPlh!(Hpr3!!!PlhGleh[Id!!!"h[IjHprd!!2jHprd!!2e +Hpr*h[Id!!2jh[Id!!!&HpelhqhHpr3!!!(HprPlhrRHpr3!!rRHpr3!!!9lhA[I +pGlhp!!!%A[GHphHp!*!%rAHpr3!!!&lhrRHprJ!!!AHpGlhq!!!"A[GHpri!!!& +HpelhrJ!!rPlhahHp!(rr!-[JGld"IrprrqNB%`&rrhrriRHprR`!rPlhr(HprJ! +!rPlh!AHpGlhq!!$qA[F"Gleh[IF!!1jh[Ijm!2eHprjm!2eHpreh[IX!!2Yh[Ii +!!2jHp`&h[AHprJ!!rPlh!(HppJ!!rPlh!AHpGlhi!!!"Gleh[IjHpri!!2eHprd +!!2eHpr*h[IF!!2eHprah[Id!!2eHprjh[IF!!2eHpreh[IN!!2ah[IF!!!&h[AH +prJ!!!9lhA[Iq!!!"A[GHpri!!2jHpmGh[3"rr`$Yi(Hp!(rrrKJ6!(rJrKJ6!Ar +JIq$q'"-!Iq$d'"-!IrrLGlhqI!$qA[ImGlhq!!$qA[F"Gleh[Ii!!2jHpreh[IX +!!1ah[Ijm!2eHprjm!2jHprah[IX!!2Yh[Ii!!2jHp`&h[AHprJ!!rPlh!AHpGlh +m!!!"Gleh[Ii!!2jHpreh[I`!!2jh[IjHp`"h[Ii!!2eHp`"h[Ii!!2eHpr"h[IS +!!!&h[AHprPlhr(HprJ!!r&lhr(HpqJ!!!AHpGlhqA[ImGlhl!!$jGlhl!!$pGlh +q!!!"A[GHpri!!!&HpelhrJ!!rPlhahHp!(rr!0[JGld(IrmB%aJ6Iq"ri"J6'"0 +ri2`B%`"ri23B%`"rrpph[IjHprPh[IjHprah[IjHpreh[IeHpreh[IjHpqjh[Ij +Hpreh[IjHprPh[IjHprKh[IjHprah[IjHpreh[IjHp`&h[AHpqelhrAHpr9lhrRH +pr9lhrAHpr9lhrRHpr9lhlRHpr9lhrRHpr9lhr(HprJ!!r9lhqRHpr9lhrRHpr9l +hqhHpr9lhrRHp!9lhA[IpGlhpA[IpGlhqA[F"Gleh[IjHp`&h[AHprPlh!AHpGlh +qA[I(Gld!Irm!`1&h[3&rrhrrrKJ6!RrJ'"0ri2`B%rjri!8B%aJ6Iq"ri"J6'"2 +qIq$q'"-"Irprrq"h[IjHprPh[IjHprah[IjHprah[IGHpqjh[IjHpreh[IjHprP +h[IYHprYh[IjHprah[IjHpreh[ICHprah[IKHprah[IjHpreh[IeHpqjh[IGHpra +h[Ii!!!"h[IeHprTh[IGHprPh[IPHprah[IGHp`&h[AHprPlh!AHpGlhqA[F"Gle +h[IjHpmGh[3"rr`$*iAHp!(rrr4J6!ArJ'"2qIq$p'"-,Iq!B%aJ6Iq!B%aJ6Iq! +B%hrJ'"-B%hrJrKJ6!(rri(HprPlhqAHprPlhr(HprPlhqRHpqelhl(HprPlhrAH +prPlhqAHpqelhqhHprPlhr(HprPlhr(Hpr&lh!AHpGlhqA[IkGlhmA[IkGlhqA[I +mGlhqA[IXGlhkA[ImGlhp!!!!GlhqA[IhGlhkA[IhGlhlA[IjGlhlA[IpGlhqA[F +"Gleh[IjHp`&h[AHprPlhahHp!(rr!%rKGld!Irrp'"-&Iq!B%hrJ'"-B%hrJrKJ +6#hrJ'"-B%hrJ'"-B%hrJ'"0ri"J6'"0ri2iB%`"rri&h[E9h[IS!!!&h[AHprPl +hKhHp!(rr!&2LGld"IrprrrdB%`9ri"J6Iq!B%aJ6Iq$q'"-,Iq!B%aJ6Iq!B%aJ +6Iq!B%hrJ'"-B%hrJrKJ6!ArrIrq"GlffGlhl!!!"Gleh[IjHpiCh[3"rr`"&iRH +p!(rrr"J6"(rJ'"-B%hrJIq$p'"-,Iq"ri"J6'"0ri(rJ'"-B%hrJ'"-B%hrJr4J +6!(rrJAHpVhHpr9lhKRHp!(rr!"[LGld!IrrM'"-!Irq"GlfcGlhkA[H&Gld!Irm +!'q*h[3"rrq-B%`"rri&h[E0h[IYHpi4h[3"rr`!5iRHpiArrJAHpJAHpX(Hp!(r +r!!q"Glf"Glf"GlhaGld!Irm!$i&h[B&h[B&h[I&h[3"rr`!2JAHpJAHpJAHpmAH +p!(rr!!q"Glf"Glf"GlhaGld!Irm!&B0h[Ii!!,Ph[Ii!!)&h[Eeh[3"rr`!HUAH +ppR`!jRHprJ!!ZAHprJ!!`RHpp(`!LAHp!(rr!#5TGlhfI!$QGlhq!!#jGlhq!!$ +GGlhq!!$TGlhdI!#*Gld!Irm!+U9h[Ijm!1*h[Ii!!2jHplah[Ii!!2jHpq"h[Ii +!!14h[Ijm!)4h[3"rr`!iTRHp!&lhrR`!qPlhkAHprJ!!rPlh[(HprJ!!rPlhi(H +prJ!!jRHp!9lhA[IqI!$jA[H-Gld!Irm!1kCh[3"Hprjm!2THpqPh[Ii!!2jHpla +h[Ii!!2jHpq"h[Ii!!2jHpqPh[3&HpelhrR`!q9lhM(Hp!(rr!+ZPGlhqI!$qA[I +mGlhq!!!"Gleh[Id!!2Kh[IN!!2jHpreh[I`!!2Th[Ii!!!&h[AHpr!!!qAHpr!! +!qRHprJ!!!AHpGlhp!!$iGlhj!!$qA[IpGlhm!!$kGlhq!!!"Gleh[Id!!2Ph[Ii +!!2jHpqGh[Ijm!2jHprYh[Ii!!!&h[AHpr!!!qRHpq3!!qAHpq`!!qAHpr!!!qAH +prJ!!!AHpGlhm!!$6Gld!Irm!I+9h[Ijm!2jHprah[IF!!2Yh[IF!!2jHp`&h[AH +pq!!!r(HppJ!!r(Hpq!!!r(Hpp`!!qhHpp`!!rPlh!AHpGlhi!!$mGlhh!!$pGlh +e!!$UGlhqI!$qA[IlGlhh!!$mGlhh!!$lGlhi!!$mGlhi!!$lGlhh!!$6Gld!Irm +!d+9h[Ijm!2jHprah[IX!!!"h[Id!!2ah[Id!!2jh[Ii!!2jHp`"h[Id!!2jh[Ii +!!2ah[IX!!!&h[AHprJ!!rAHpr3!!rRHprJ!!r(Hpq`!!!(Hpr3!!r(Hpr3!!rRH +prJ!!rPlh!(Hpr3!!rRHprJ!!r(Hpq`!!!(Hpr3!!rRHpp3!!kRHprR`!rPlhqhH +pq`!!!(HprJ!!r(Hpr3!!rRHprJ!!r(Hpr3!!rAHp!3#3"2eh[Id!!2jh[Ii!!2Y +h[IX!!!"h[Ii!!00h[3"rr`%LTAHprR`!rPlhr(Hpr!!!!PlhGleh[Ii!!!"Hprj +h[Ii!!2jh[3&HpelhrJ!!rPlh!(HprJ!!rRHp!9lhA[Iq!!$pGlhm!!!$A[Gh[AH +pA[Iq!!!#A[Gh[AHprJ!!rRHp!9lhA[Iq!!$pGlhm!!!#A[Gh[AHprJ!!!&lhrRH +prJ!!rRHp!9lhA[Iq!!$qA[F!Glhq!!$qGld"A[GHpri!!2eh[I`!!!*HphHpGlh +q!!!!A[ImGlhq!!$qA[IRGlhqI!$qA[IlGlhm!!!"A[Gh[Ii!!2jHp`"h[Ii!!2j +h[3&HpelhrJ!!rPlh!AHpGlhq!!$qGlhlA[F"Gleh[Ii!!2jh[3&HpelhrJ!!r(H +pr!!!!9lhGlhq!!$qA[I@Gld!Irm"'+9h[Ijm!2jHprah[Id!!2eHpri!!!0Hpel +hGleh[Ii!!!"h[IeHpri!!2jHpri!!!&h[AHpr9lhrJ!!!elhA[Gh[AHpr3!!r&l +hrJ!!!9lhA[Iq!!!"Gleh[IeHpri!!!0HpelhGleh[Id!!2eHpri!!!0HpelhGle +h[Ii!!!"h[IeHpri!!2jHpri!!!&h[AHpr9lhrJ!!!elhA[Gh[AHpr3!!r9lhrJ! +!!9lhA[IpGlhq!!$iA[IYGlhqI!$qA[IlGlhp!!$qA[Iq!!$qA[F!Glhq!!!!Glh +pA[Iq!!$qA[F!Glhq!!!"Gleh[IKHpri!!!&h[AHpr9lhrJ!!!9lhA[IqGlhp!!$ +qA[Iq!!$qA[I@Gld!Irm!jk9h[Ijm!2jHprah[Ii!!2aHpri!!2jHpri!!!&h[AH +pr9lhrJ!!rPlhp3!!!elhA[Gh[AHprJ!!qelhrJ!!!9lhA[Ie!!!$A[GHphHpGlh +q!!$mA[Iq!!$qA[Iq!!!"Gleh[IeHpri!!2jHpr8!!!0HpelhGleh[Ii!!2aHpri +!!2jHprjh[Ii!!2KHpqeh[Ijm!2jHprYh[Ii!!2YHp`"h[IjHpri!!!&h[AHpr9l +hrJ!!rPlh!(HprJ!!!(Hpr9lhrAHp!9lhA[Ie!!!"A[GHprjh[Ii!!2YHp`"h[Ij +HppCh[3"rr`$TTAHprR`!rPlhr(HprJ!!r&lhrJ!!rPlhrJ!!!(HprPlh!AHpGlh +q!!$qA[Ie!!$qA[F!Glhq!!$mA[F!Glhq!!!"A[GHpr8!!2jHp`"h[Ii!!2aHpri +!!2jHpri!!!"h[IjHp`&h[AHprJ!!rPlhp3!!rPlh!(HprJ!!r&lhrJ!!rPlhrRH +prJ!!rPlhjhHprR`!rPlhqhHprJ!!r&lh!AHpGlhqA[Iq!!!!GlhqA[F"Gleh[Ii +!!2jHp`"h[Ii!!!"h[IjHprTh[I8!!2jHp`&h[AHprJ!!r&lh!AHpGlhqA[I@Gld +!Irm""D9h[Ijm!2jHprah[Ii!!2eHp`"h[Ii!!2jHpri!!!"h[IjHp`&h[AHprJ! +!rPlhrJ!!rPlhqhHprPlh!(HprJ!!r9lh!AHpGlhq!!!"A[GHpri!!2jHprYh[Ij +Hp`"h[Ii!!2eHp`"h[Ii!!2jHpri!!!"h[IjHp`&h[AHprJ!!rPlhrJ!!rPlhqhH +prPlh!(HprJ!!r9lh!(HprJ!!rPlhrRHprJ!!rPlhjhHprR`!rPlhqhHprJ!!r9l +hrRHprPlhrJ!!!(HprPlh!AHpGlhq!!$qA[F!Glhq!!$qA[IjGlhq!!$qA[IlGlh +qA[F"Gleh[Ii!!2eHprjh[IjHppCh[3"rr`$MTAHprR`!rPlhr(HprJ!!rPlh!AH +pGlhq!!$qA[Iq!!$qA[F"Gleh[Id!!2jHpri!!29Hp`"h[Ii!!2jHp`&h[AHprJ! +!!RHpA[GHpri!!29Hp`"h[Ii!!2jHp`&h[AHprJ!!rPlhrJ!!rPlh!AHpGlhp!!$ +qA[Iq!!$eA[F!Glhq!!$qA[F"Gleh[Ii!!2jHprjh[Ii!!2jHpqGh[Ijm!2jHprY +h[Ii!!2jHprTh[Ii!!2jHp`&h[AHpr3!!rPlh!(HprJ!!rPlhqAHprJ!!p9lh!AH +pGlhq!!$qA[I2Gld!Irm!jU9h[Ijm!2jHprah[Ii!!2jHp`&h[AHprJ!!rPlhrJ! +!rPlh!(Hpr!!!rPlh!(HprJ!!pPlh!(HprJ!!rPlh!AHpGlhq!!!!GlhqA[Iq!!$ +fA[F!Glhq!!$qA[F"Gleh[Ii!!2jHpri!!2jHp`"h[I`!!2jHp`"h[Ii!!2CHp`" +h[Ii!!2jHp`&h[AHprJ!!rPlhrRHprJ!!rPlhjhHprR`!rPlhqhHprJ!!rPlhqRH +prJ!!rPlh!(Hpr!!!rPlh!AHpGlhq!!!"A[GHprKh[Ii!!2CHp`&h[AHprJ!!rPl +hchHp!(rr!3UPGlhqI!$qA[ImGlhq!!$qA[F"Gleh[Ii!!2jHp`"h[Ii!!!&Hpel +hq`!!rPlh!(Hpr3!!!&lhrRHprJ!!rAHprJ!!rPlhr3!!!AHpGlhqA[Ip!!!!A[I +qGlhq!!$pGlhq!!$qA[F"Gleh[Ii!!2jHp`"h[Ii!!!&Hpelhq`!!rPlh!(Hpr3! +!!&lhrRHprJ!!rAHprJ!!rPlh!AHpGlhq!!$qA[IqGlhp!!!%A[GHphHp!*!%kRH +prR`!rPlhqhHprJ!!rPlhqAHprJ!!!9lhA[Il!!$qA[F"Gleh[Id!!!"Hprjh[3% +!N!6pGlhp!!!!A[IqGlhq!!$mGlhq!!$qA[I2Gld!Irm!Y+Ph[ICm!2eh[Ii!!2j +Hp`&h[AHprJ!!rPlh!(HppJ!!rPlh!AHpGlhh!!$pGlhh!!!!GlhqA[F"Gleh[IF +!!2eh[Ii!!2jHp`&h[AHprJ!!rPlh!(HppJ!!rPlh!AHpGlhh!!$pGlhq!!$qA[F +"Gleh[Ii!!2jHpreh[IN!!1Th[Ijm!2jHprYh[Ii!!2jHprPh[IB!!2jHprjh[IJ +!!2ah[IF!!2ah[Ii!!2jHpmph[3"rr`$+UAHppR`!rAHprJ!!rPlh!AHpGlhq!!$ +qA[F"Gleh[I`!!!&h[AHprJ!!rPlhrAHpq`!!qhHpq3!!rRHprPlhrAHpq`!!qhH +prJ!!rPlh!AHpGlhq!!$qA[F"Gleh[I`!!!&h[AHprJ!!rPlhrAHpq`!!qhHprJ! +!rPlh!AHpGlhq!!$qA[ImGlhl!!$TGlhqI!$qA[IlGlhq!!$qA[IiGlhm!!!"Gle +h[Ii!!2jHprah[IX!!2Ph[IX!!2Th[Ii!!2jHpmph[3"rr`$(SRHprPlhqAHprPl +hr(HprPlhrAHprPlh!AHpGlhlA[IpGlhpA[IpGlhqA[F!Glhq!!$qA[IqGlhpA[I +mGlhpA[IpGlhqA[IpGlhqA[ImGlhqA[IpGlhqA[F"Gleh[IYHpreh[IeHpreh[Ij +Hpreh[IjHprah[IjHprYh[IeHprjh[3&HpelhkRHprPlhq(HprPlhpRHprPlh!AH +pGlhlA[ImGlhpA[IpGld"A[GHpreh[IeHpreh[IjHprah[IjHpmph[3"rr`#"TRH +ppPlhrAHprPlhr(HprPlhrAHppPlhr(Hppelh!(HprJ!!pelhqhHppelhrAHprPl +hr(HprPlhrAHppPlhr(HppelhrAHprPlhr(HprPlhqRHpq9lhkRHprPlhq(HprPl +hpRHppPlhqhHpq&lhr(Hppelhr(HprPlhchHp!(rr!*QQGlhfA[IpGlhqA[ImGlh +qA[ImGlhmA[F"Gleh[IjHprTh[IYHprjh[Ii!!2PHprGh[IYHprYh[IjHprah[Ij +Hprah[IaHp`&h[AHprPlhqRHpqelhqhHprPlhr(HprPlhqAHpqelhkAHprPlhq(H +prPlhpAHpr&lh!AHpGlhqA[IjGlhlA[IjGlhlA[IkGlhqA[I2Gld!Irm!&B&h[He +h[Ii!!2jHpi&h[BYh[3"rr`!9JAHplAHprJ!!rPlhJAHpLhHp!(rr!"+"GlhUGlh +qA[H"Glf,Gld!Irm!%S&h[HTh[IjHpi&h[BYh[3"rr`!5JAHpkRHprPlhJAHpLhH +p!(rr!!q"Glf"Glf"GlhaGld!Irm!$i&h[B&h[B&h[I&h[3"rr`!2JAHpJAHpJAH +pmAHp!(rr!!q"Glf"Glf"GlhaGld!Irm!$i&h[B&h[B&h[I&h[3"rr`!2JAHpJAH +pJAHpmAHp!(rr!!q"Glf"Glf"GlhaGld!Irm!$i&h[B&h[B&h[I&h[3"rr`!2JAH +pJAHpJAHpmAHp!(rr!!q"Glf"Glf"GlhaGld!Irm!$i&h[B&h[B&h[I&h[3"rr`! +2JAHpJAHpJAHpmAHp!(rr!!q"Glf"Glf"GlhaGld!Irm!$i&h[B&h[B&h[I&h[3" +rr`!2JAHpJAHpJAHpmAHp!(rr!#5+Gld"!*!%p(Hp!3#3",*h[IX!!,jh[3%!N!5 +6Gld!Irm!2+4h[3%!N!6TGld"!*!%p(Hp!3#3",0h[3%!N!6DGlhk!!$`Gld"!*! +%qRHp!3#3"*0h[3"rr`"%TAHpr3!!kRHp!3#3"24h[3%!N!5dGld"!*!%fAHp!3# +3"2eh[3%!N!6aGld"!*!%qRHp!3#3"*0h[3"rr`"%TAHpr3!!kRHp!3#3"24h[3% +!N!5dGld"!*!%fAHp!3#3"2ah[3%!N!6bGld"!*!%qRHp!3#3"*0h[3"rr`$(TAH +p!`!!Gleh[3!!lRHpq`!!r(Hpr3!!rAHp!`#3"(HpGlhq!!$mGld"!*!%rAHp!3# +3"2ah[IX!!2ah[IX!!2ah[Id!!2ah[3-!N!4h[AHpr3!!mRHp!3#3"2Kh[I`!!2a +h[3-!N!4h[AHpr3!!p(Hp!3#3"2ah[38!N!4h[AHp!*!%r(Hp!3#3"2eh[3%!N!6 +kGld$!*!%Gleh[Ii!!2Yh[I`!!2eh[3-!N!4h[AHprJ!!VRHp!(rr!5HQGld&!*! +%Gleh[3#3"2"h[3%!N!6qGld"!*!%rRHp!3#3"2jh[3%!N!6qGld(!*!%Gld!!(H +pGld!N!6pGld"!*!%rAHp!3#3"2eh[3%!N!6qGld"!*!%rAHp!3#3"2jh[3%!N!6 +qGld"!*!%rRHp!3#3"2eh[3F!N!4h[3!!Gleh[3#3"24h[IJ!!2jh[3%!N!6qGld +"!*!%rAHp"`#3"(Hp!!"h[AHp!*!%p(Hp!3#3"2ah[38!N!4h[AHp!*!%r(Hp!`# +3"(HpGlhj!!$qGld(!*!%Gld!!(HpGld!N!6pGld"!*!%rRHp!3#3"2jh[3F!N!4 +h[3!!Gleh[3#3"+ph[3"rr`%1TRHp"3#3"(HpGld!N!6aGld"!*!%rAHp!3#3"2j +h[3%!N!6pGld$!*!%Gleh[Ii!!2eh[3%!N!6qGld"!*!%rAHp!3#3"2jh[3%!N!6 +pGld"!*!%rRHp!3#3"2eh[3%!N!6qGld"!*!%rAHp!3#3"2jh[Ii!!2jh[3%!N!6 +bGld"!*!%qRHp!3#3"2ah[3%!N!6qGlhq!!$qGld"!*!%p(Hp!3#3"2eh[3%!N!6 +pGld"!*!%rAHp!3#3"2eh[3%!N!6kGlhq!!$qGld"!*!%rRHp!3#3"2ah[3-!N!4 +h[AHprJ!!rRHp!3#3"+ph[3"rr`%8TRHp"3#3"(HpGld!N!6bGld"!*!%r(Hp"3# +3"(HpGld!N!6mGld&!*!%Gleh[3#3"2ah[3%!N!6qGld"!*!%rAHp"3#3"(HpGld +!N!6mGld&!*!%Gleh[3#3"2ah[38!N!4h[AHp!*!%r(Hp!3#3"2jh[3%!N!6pGld +"!*!%mRHp!3#3"2Th[3%!N!6mGld"!*!%rRHp!3#3"2eh[3%!N!6dGld"!*!%rRH +prJ!!rAHp!3#3"2jh[3%!N!6mGld"!*!%qRHp!3#3"2eh[3%!N!6qGld"!*!%r(H +p"3#3"(HpGld!N!6pGld"!*!%VhHp!(rr!1HQGld!!!$pGld!!!$bGld"!*!%r(H +p!`#3"(HpGlhi!!!$Gleh[3#3"2ah[3%!N!6qGld"!*!%rAHp"3#3"(HpGld!N!6 +mGld&!*!%Gleh[3#3"2ah[3-!N!4h[AHpq!!!rRHp!3#3"1ah[3%!N!6kGld"!*! +%r(Hp!3#3"2jh[3%!N!6ZGlhl!!$kGld&!*!%Gleh[3#3"2ah[3%!N!6kGld"!*! +%rAHp!3#3"2jh[3%!N!6mGld&!*!%Gleh[3#3"2eh[3%!N!5[Gld!Irm!l+Gh[3% +!N!6pGld"!*!%mhHp!3#3"2ah[38!N!4h[AHp!*!%q(Hp!3#3"2ah[3%!N!6qGld +"!*!%rAHp"3#3"(HpGld!N!6mGld&!*!%Gleh[3#3"2ah[38!N!4h[AHp!*!%phH +p!3#3"1ah[3%!N!6kGld"!*!%r(Hp!3#3"2jh[3%!N!6ZGld"!*!%pRHp"!#3"(H +pGld!!2Yh[3%!N!6kGld"!*!%rAHp!3#3"2jh[3%!N!6mGld&!*!%Gleh[3#3"2e +h[3%!N!5[Gld!Irm!fUGh[IN!!20h[3%!N!6mGld&!*!%Gleh[3#3"2Kh[3%!N!6 +mGld"!*!%rRHp!3#3"2eh[38!N!4h[AHp!*!%r(Hp"3#3"(HpGld!N!6mGld&!*! +%Gleh[3#3"2Gh[3%!N!6XGld"!*!%qRHp!3#3"2ah[3%!N!6qGld"!*!%lRHp!3# +3"29h[Id!!2Yh[3%!N!6kGld"!*!%rAHp!3#3"2jh[3%!N!6mGld&!*!%Gleh[3# +3"2eh[3%!N!5[Gld!Irm!hUGh[3%!N!6pGld"!*!%mhHp!3#3"2eh[Ii!!2jh[3% +!N!6jGld"!*!%rAHp!3#3"2eh[3%!N!6qGlhq!!!$Gleh[3#3"2eh[Ii!!!0h[AH +p!*!%rAHprJ!!rRHp!3#3"2Kh[3%!N!6XGld"!*!%qRHp!3#3"2ah[3%!N!6qGld +"!*!%lRHp!3#3"29h[Id!!2Yh[3%!N!6kGld"!*!%rAHp!3#3"2jh[3%!N!6mGld +&!*!%Gleh[3#3"2eh[3%!N!5[Gld!Irm"!kKh[3%!N!6lGld"!*!%mhHp"`#3"(H +pGld!!(Hp!*!%rRHprJ!!rAHp"!!!Gleh[3#3"2jh[3%!N!6mGld(!*!%Gleh[3! +!Gld!N!6qGld(!*!%Gleh[3!!Gld!N!6qGld(!*!%Gleh[3!!Gld!N!6qGlhq!!$ +pGld!!!$qGld"!*!%l(Hp!3#3"2Ph[3%!N!6qGld"!*!%rAHp!3#3"1jh[3%!N!6 +dGld"!*!%qRHprJ!!!RHpGld!!2jh[3%!N!6pGld"!*!%rAHp!3#3"2jh[3%!N!6 +qGld"!*!%rAHp!3#3"+ph[3"rr`#qU(Hp!3#3"2Yh[3%!N!6bGlhq!!!$Gleh[3# +3"2ah[I`!!2jh[IX!!2Th[Ii!!!0h[AHp!*!%rAHprJ!!!hHpGld!N!6pGlhq!!! +$Gleh[3#3"2ah[I`!!2eh[3%!N!6XGld"!*!%q(Hpr!!!r(Hp!3#3"1jh[3%!N!6 +dGld"!*!%qAHpr3!!rAHp!3#3"2eh[3%!N!6mGlhm!!$pGld"!*!%rAHp!3#3"+p +h[3"rr`!KJAHphRHp!3#3"2Kh[3%!N!5MGld!!!#"Gld"Glerr`!MJAHphRHp!3# +3"2Kh[3%!N!5NGld"!*!%JAHp!AHpIrm!0B&h[H9h[3%!N!6pGld"!*!%rRHp!3# +3"2eh[3%!N!5NGld"!*!%JAHp!RHpGlerr`!HJAHpj(Hpq`!!r(Hpq`!!TRHpr3! +!JAHprRHp!(rr!!q"Glf"Glf"GlhaGld!Irm!$i&h[B&h[B&h[I&h[3"rr`!2JAH +pJAHpJAHpmAHp!(rr!!q"Glf"Glf"GlhaGld!Irm!$i&h[B&h[B&h[I&h[3"rr`! +2JAHpJAHpJAHpmAHp!(rr!!q"Glf"Glf"GlhaGld!Irm!$i&h[B&h[B&h[I&h[3" +rr`!2JAHpJAHpJAHpmAHp!(rr!!q"Glf"Glf"GlhaGld!Irm!BkGh[3-!N!4h[AH +prJ!!r(Hp!`#3"(HpGlhp!!$pGlhm!!$kGlhl!!$qGld$!*!%Gleh[Id!!2ah[IX +!!!Ph[3#3"(Hp!*!%Gleh[3#3"2eh[IX!!)&h[Cph[3"rr`#@ThHp"`#3"(Hp!!" +h[AHp!*!%rAHp"`#3"(Hp!!"h[AHp!*!%rRHp!3#3"2jh[3%!N!6mGld"!*!%rRH +p!3#3"2jh[3F!N!4h[3!!Gleh[3#3"2eh[3%!N!6qGld#!*!%Glhq!!!!Glhq!!! +%Gld!N!4h[AHprJ!!rRHp!3#3")&h[D"h[3"rr`#"ThHprJ!!rAHp!3#3"2jh[Ii +!!2jh[38!N!4h[AHp!*!%r(Hp!3#3"2jh[3%!N!6pGld"!*!%rRHprJ!!rRHp!3# +3"2jh[3%!N!6pGld3!*!%Gld!N!4h[AHp!*!%Gleh[3#3"(HpGld!N!5"GlfDGld +!Irm!KUGh[3%!N!6mGld"!*!%rRHp!3#3"2eh[38!N!4h[AHp!*!%r(Hp"3#3"(H +pGld!N!6mGld"!*!%rRHp!3#3"2eh[38!N!4h[AHp!*!%r(Hp$J#3"(Hp!*!%Gle +h[3#3"(HpGld!N!4h[AHprJ!!JAHpQhHp!(rr!(@RGld"!*!%r(Hp!3#3"2jh[3% +!N!6jGld"!*!%r(Hp"3#3"(HpGld!N!6mGld"!*!%rRHp!3#3"2Ph[3%!N!6mGld +-!*!%Gld!N!4h[AHp!*!%Gleh[3#3"2jh[I`!!)&h[Cjh[3"rr`"eThHp!3#3"2a +h[3%!N!6qGld"!*!%qAHp!3#3"2ah[38!N!4h[AHp!*!%r(Hp!3#3"2jh[3%!N!6 +jGld"!*!%r(Hp$!#3"(Hp!*!%Gleh[3#3"(HpGld!N!6lGlhp!!#"GlfJGld!Irm +!GDGh[3%!N!6mGld"!*!%rRHp!3#3"2Ph[3%!N!6mGld&!*!%Gleh[3#3"2ah[3% +!N!6qGld"!*!%qAHp!3#3"2ah[3`!N!4h[3#3"(HpGld!N!4h[AHp!*!%qAHprJ! +!JAHpSAHp!(rr!(5RGld"!*!%rAHp!3#3"2eh[3%!N!6jGld"!*!%r(Hp"3#3"(H +pGld!N!6pGlhq!!$qGld"!*!%qAHp!3#3"2eh[Ii!!!Th[3#3"(HpGld!N!4h[AH +p!*!%q(Hp!3#3")&h[D&h[3"rr`#$ThHp!3#3"2jh[3%!N!6mGld"!*!%q(Hp!3# +3"2jh[3%!N!6pGld(!*!%Gleh[3!!Gld!N!6qGld"!*!%q(Hp&3#3"(HpGld!!(H +p!*!%Gld!N!4h[AHp!*!%Gleh[3#3"(HpGld!!2ah[Ii!!)&h[D&h[3"rr`"IThH +pq`!!qhHp!3#3"2Gh[I`!!2Yh[Ii!!!0h[AHp!*!%rRHp!3#3"2Gh[Ii!!!jh[AH +p!*!%Gld!N!4h[AHp!*!%Gleh[3#3"2jh[IS!!)&h[D"h[3"rr`!FThHp!3#3"0Y +h[3%!N!5"Glf"GlheGld!Irm!(+Gh[3%!N!6EGld"!*!%JAHpJAHppAHp!(rr!#5 +RGld"!*!%iRHp!3#3"2eh[3%!N!5"Glf"GlhdGld!Irm!'UGh[3%!N!6KGlhl!!# +"Glf"GlhcGld!Irm!$i&h[B&h[B&h[I&h[3"rr`!2JAHpJAHpJAHpmAHp!(rr!!q +"Glf"Glf"GlhaGld!Irm!$i&h[B&h[B&h[I&h[3"rr`!2JAHpJAHpJAHpmAHp!(r +r!!q"Glf"Glf"GlhaGld!Irm!$i&h[B&h[B&h[I&h[3"rr`!2JAHpJAHpJAHpmAH +p!(rr!!q"Glf"Glf"GlhaGld!Irm!$i&h[B&h[B&h[I&h[3"rr`!2JAHpJAHpJAH +pmAHp!(rr!!q"Glf"Glf"GlhaGld!Irm!$i&h[B&h[B&h[I&h[3"rr`!2JAHpJAH +pJAHpmAHp!(rr!!q"Glf"Glf"GlhaGld!Irm!$i&h[B&h[B&h[I&h[3"rr`!2JAH +pJAHpJAHpmAHp!(rr!!q"Glf"Glf"GlhaGld!Irm!$i&h[B&h[B&h[I&h[3"rr`! +2JAHpJAHpJAHpmAHp!(rr!!q"Glf"Glf"GlhaGld!Irm!$i&h[B&h[B&h[I&h[3" +rr`!2JAHpJAHpJAHpmAHp!(rr!!q"Glf"Glf"GlhaGld!Irm!$i&h[B&h[B&h[I& +h[3"rr`!2JAHpJAHpJAHpmAHp!(rr!!q"Glf"Glf"GlhaGld!Irm!$i&h[B&h[B& +h[I&h[3"rr`!2JAHpJAHpJAHpmAHp!(rr!"cJGld"!*!%lhHp!3#3")&h[B&h[DK +h[3"rr`"8i(Hp"!#3"(Hp!*!%rAHpr"J6rRHp"!#3"(Hp!*!%[(Hp!3#3")Ch[3% +!N!6QGld"!*!%phHpr!!!j(Hp!3#3"14h[Id!!0Kh[3"rr`"Ui(Hp"!!!Gleh[3# +3"2eh[I`B%rjh[33!N!4h[AHp!!$EGlhm!!$RGld"!*!%khHpr!!!SAHp!3#3"1C +h[3%!N!6iGld"!*!%rAHp!!!!jAHp!3#3"1*h[3%!N!6BGld!Irm!@1Th[IX!!2e +h[Ii!!2ah[ISB%reh[Ii!!2eh[IX!!1*h[3%!N!6RGld"!*!%k(Hp!3#3")4h[3% +!N!6jGld!!!$kGld!!!$&Gld"!*!%f(Hp!(rr!%l[Glh`!!$lGlhk'"2mGlh`!!$ +RGld"!*!%jhHp!3#3"1Kh[3%!N!5%Gld"!*!%qAHp!!!!qRHp!3#3"-Ch[3%!N!6 +BGld!Irm!hr&h[Hi!!2Yh[ISB%rah[Hi!!1Ph[3%!N!6lGlhl!!$mGlhl!!$qGld +"!*!%rAHp!!!!lAHp!3#3"2Yh[IX!!!9h[AHp!*!%Gleh[Ii!!2ah[IX!!2Th[Id +!!2eh[3-!N!4h[AHprJ!!fhHpq`!!qRHpq`!!r(Hpq`!!rRHp!3#3"2eh[3-!!(H +pGld!!2jh[Id!!!*h[AHp!!$pGlhl!!!#Gld!N!6qGld"!*!%rRHp!J#3"(Hpr3! +!m(Hp!`#3"(HpGlhq!!$kGld"!*!%f(Hp!(rr!8VbGlhY!!$lGlhk'"2mGlhY!!$ +UGld"!*!%r(Hp!3#3"2jh[3%!N!6pGld"!*!%rAHp!!!!rRHp!3#3"2jh[3!!!1a +h[3%!N!6mGld"!*!%rRHp#`#3"(HpGld!N!4h[3!!Gleh[3#3"2jh[Ii!!2jh[3% +!N!6pGld"!*!%rRHp!3#3"2jh[3F!N!4h[3!!Gleh[3#3"0ph[3!!!2Yh[3%!N!6 +lGld"!*!%rRHp!3#3"2eh[3%!N!6pGld!!!$qGld"!*!%rRHp!!!!rRHp!!!!rRH +p"J!!Gleh[3!!Gleh[3!!rRHp!3#3"2eh[3-!!(Hp!*!%rRHp!3#3"2jh[3%!N!6 +qGld"!*!%m(Hp"`#3"(Hp!!"h[AHp!*!%qhHp!3#3"2Yh[3!!!0ph[3"rr`%RmhH +pl!!!r(Hpq"J6rAHpl!!!khHp!3#3"2eh[3%!N!6pGld"!*!%rRHp!3#3"2Kh[33 +!N!4h[AHp!!$VGld"!*!%rAHp!3#3"2eh[3-!N!4h[AHprJ!!rRHp!3#3"2jh[3% +!N!6hGld"!*!%rAHp!`#3"(HpGlhq!!$qGld"!*!%iAHp!3#3"2Th[3%!N!6mGld +"!*!%rAHp!3#3"2jh[3%!N!6iGld%!*!%Gleh[3!!rAHp!`!!Gleh[3!!rRHp"`! +!Gleh[3!!Gleh[3#3"2Th[3%!N!6qGlhq!!!$Gleh[3#3"2jh[3%!N!6`Glhq!!$ +qGld"!*!%qhHp!3#3"2Th[3%!N!6KGld!Irm"62&h[3%!N!6mGld$!!"h[3#3"2j +h[3)!!(Hp!!$kGlhi'"2lGld#!!"h[3!!rRHp!`#3"(Hp!!$mGld"!*!%kAHp!3# +3"2jh[3%!N!6mGld&!*!%Gleh[3#3"2Gh[3-!N!4h[3!!kRHp!3#3"2jh[3%!N!6 +mGld&!*!%Gleh[3#3"2eh[3%!N!6qGlhq!!$jGld"!*!%r(Hp"3#3"(HpGld!N!6 +pGld"!*!%j(HprJ!!q(Hp!3#3"2eh[3%!N!6mGld&!*!%Gleh[3#3"2Gh[3-!N!4 +h[3!!r(Hp!`!!Gleh[3!!rRHp"J!!Gleh[3!!Gld!N!6iGld#!*!%Glhp!!!#Gld +!N!6pGld"!*!%m(Hp!3#3"2eh[3%!N!6lGld"!*!%q(HprJ!!j(Hp!(rr!9AbGld +#!!"h[3!!r(Hp!`!!Gld!N!6qGld#!!"h[3!!qRHp#"J6'"0ri"J6Iq!B%hrJ'"- +B%rYh[3)!!(Hp!!$qGld$!*!%Gld!!2ah[3)!!(Hp!!$UGld"!*!%rRHp!3#3"2a +h[38!N!4h[AHp!*!%phHpr3!!kRHp!3#3"2jh[3%!N!6mGld&!*!%Gleh[3#3"2e +h[3%!N!6pGlhm!!$mGlhi!!!$Gleh[3#3"2eh[3%!N!6QGld"!*!%pAHp!3#3"2e +h[3%!N!6mGld&!*!%Gleh[3#3"2Gh[Id!!2ah[3d!!(HpGld!!(HpGld!N!4h[3# +3"(Hp!*!%q(Hp#3#3"(Hp!!"h[3#3"(Hp!*!%rAHp!3#3"2"h[3%!N!6pGld"!*! +%qhHp!3#3"29h[3%!N!6QGld!Irm"@2*h[3)!!(Hp!!$pGld(!*!%Gleh[3!!Gle +h[3!!rRHp!!!!r(HprKJ6"(rJ'"0ri"J6Iq$q'"2pGld!!!$qGld(!!"h[AHp!!" +h[AHp!*!%rAHp!J!!Gld!!1Th[3%!N!6qGld"!*!%r(Hp"3#3"(HpGld!N!6hGlh +p!!$UGld"!*!%rRHp!3#3"2ah[38!N!4h[AHp!*!%rAHp!3#3"2Th[Id!!2jh[3% +!N!6iGld"!*!%rAHp!3#3"1Kh[3%!N!6cGld"!*!%rAHp!3#3"2ah[38!N!4h[AH +p!*!%phHpr3!!r(Hp!!!!rRHp!J#3"(HprJ!!!hHpGld!N!6iGld*!*!%Gld!!(H +pGld!!(Hp!*!%rAHp!3#3"2"h[3%!N!6pGld"!*!%qhHp!3#3"20h[3%!N!6SGld +!Irm"8I*h[3-!!(Hp!*!%rRHp!!!!rRHp!`!!Gleh[3!!rRHp!3#3"2eh[IBB%rj +h[3%!N!6qGld$!!"h[AHp!!$qGld!!!$qGld$!*!%Gld!!1Th[3%!N!6qGld"!*! +%r(Hp"3#3"(HpGld!N!6hGld%!*!%Gld!N!6VGld"!*!%rRHp!3#3"2ah[38!N!4 +h[AHp!*!%rAHp!3#3"2Kh[Ii!!!0h[AHp!*!%q(Hp!3#3"2eh[3%!N!6QGld"!*! +%pAHp!3#3"2eh[3%!N!6mGld&!*!%Gleh[3#3"2Gh[33!N!4h[3#3"2ah[3!!!2G +h[3%!N!6iGld*!*!%Gld!!(HpGld!!(Hp!*!%rAHp!3#3"2"h[3%!N!6pGld"!*! +%qhHp!3#3"29h[3%!N!6QGld!Irm""GTh[IBB%p0h[3%!N!6qGld"!*!%rAHprJ! +!rRHp!3#3"2Kh[38!N!4h[AHp!*!%l(Hp!3#3"2jh[3%!N!6pGlhq!!!$Gleh[3# +3"2eh[3%!N!6hGld"!*!%rRHp!3#3"2Ph[3%!N!6pGld"!*!%qhHp!3#3"1ah[Ii +!!2Kh[3%!N!6pGld"!*!%rAHprJ!!rRHp!3#3"2Kh[38!N!4h[AHp!*!%rAHp!!! +!pRHp!3#3"2Ph[Id!!!&h[AHpr3!!rAHp!3#3"2Kh[Ii!!2ah[3%!N!6pGld"!*! +%qhHp!3#3"2Kh[Ii!!14h[3"rr`%UThHp!!!!rAHp!3#3"2ah[3F!N!4h[AHp!!" +h[3#3"2jh[Ii!!2Ph[3%!N!6qGld"!*!%mhHp!!!!rAHp!3#3"2ah[3X!N!4h[AH +p!!"h[3#3"(HpGld!N!6pGld"!*!%rRHp!!!!r(HprJ!!rRHprJ!!rAHp"!!!Gle +h[3#3"2eh[3%!N!6lGlhq!!$UGld"!*!%qRHp!3#3"2ah[3F!N!4h[AHp!!"h[3# +3"2jh[Ii!!2Ph[3%!N!6qGld"!*!%rAHp!3#3"2jh[3!!!2ah[Ii!!2Ph[3%!N!6 +pGld"!*!%r(Hp!3#3"2Kh[Ii!!2ah[3%!N!6pGld"!*!%qhHp!3#3"2Th[3%!N!6 +KGld!Irm!lkGh[IX!!2Th[Ii!!!0h[AHp!*!%r(Hpq`!!rRHp!3#3"2eh[3%!N!6 +dGlhl!!$kGlhq!!!(Gleh[3#3"(HpGld!N!6pGld"!*!%rAHpqJ!!qhHpr!!!rRH +p!3#3"2eh[3%!N!6lGlhq!!$SGld!!!$lGld"!*!%qhHprJ!!!hHpGld!N!6mGlh +l!!$qGld"!*!%rAHp!3#3"2eh[I`!!2Th[IX!!2jh[3%!N!6pGld"!*!%r(Hpr3! +!qRHprJ!!r(Hp!3#3"2eh[3%!N!6lGlhp!!$pGld!!!$IGld!Irm!()&h[DTh[3% +!N!6KGld"!*!%JAHpl(Hp!(rr!"b"GlfUGld"!*!%iAHp!3#3")&h[Hah[3"rr`! +DJAHpURHp!!!!iAHp!3#3")&h[HYh[3"rr`!BJAHpUhHp!!!!j(Hpr!!!JAHpkRH +p!(rr!!q"Glf"Glf"GlhaGld!Irm!$i&h[B&h[B&h[I&h[3"rr`!2JAHpJAHpJAH +pmAHp!(rr!!q"Glf"Glf"GlhaGld!Irm!$i&h[B&h[B&h[I&h[3"rr`!2JAHpJAH +pJAHpmAHp!(rr!!q"Glf"Glf"GlhaGld!Irm!$i&h[B&h[B&h[I&h[3"rr`!2JAH +pJAHpJAHpmAHp!(rr!!q"Glf"Glf"GlhaGld!Irm!$i&h[B&h[B&h[I&h[3"rr`! +2JAHpJAHpJAHpmAHp!(rr!!q"Glf"Glf"GlhaGld!Irm!$i&h[B&h[B&h[I&h[3" +rr`$r!!!!-!#3"`3!!2q3"J!"!*!(!J#3"`-!N!F%rj!'!!!!-!#3"`3!!2q3"J! +"!*!(!J#3"`-!N!F%rj!'!!!!eJ!0!*!%!BJ!#J'B!#S%!M`m!*!%!BJ#1!'B!PJ +%!Miq!*!&#!!+!#)!PSJ!N!BS!!S"0J#@!*!(#!#J!#)",)J!N!BS!+!"0J%X!*! +(#!%f!#)"`SJ!N!BS!6B"0J(#!*!(#!(-!#)#@)J!N!BS!F`"0J*B!*!'!83!$J& +i!P5)!*!&!BJ!h!'B!5`%"R9`C'&dC3#3"!')!6B"Q!''"!9ME'pcC3#3"3&!!!S +"I!*BJ!#3"#-!-!!-!G3#EJ!%!3!"!*!&!J318(PdD'pZ)%*bEhGcCA)!!!#1!!F +!N!8+!"3!'J$%L!K0Ef4eE'9c1J#3"4d!&!#%!-3!N!F+!0!!(!'RL""*G'9YFb" +TEL"YEf4eE'8k!*!&(3$3!)3"T`#3"j3!&!#L!@f)!*!'T!!!!5`"X`#3"i`!!3# +0!E5!!*!'MJ&[!+)"U33%4@4TG!!!!H!!&`#3"3)!&!!5!)b)"P0dB@0V1J#3"43 +!&!"L!03!N!F#!1!!%J&,L""-Ef0KE#"fBA*TB@*XCA-k!*!&&!$J!')"Y`#3"r8 +!%`%&!@D)!*!&!3Irr`'D!F8!N!H4!$d!S3#'L!T&H'0PF(4TEfik!*!&N3#-!+% +"Y)J!N!DJ!"3!X!#'L""&H'0PF(4TEfiJGQ&XG@8k!*!&S!#-!,!"Y)J!N!Dk!AX +!cJ'e"!44G@Pd!*!&ZJ!8!-d!9!3)3fpZG'PZG@8!N!@k!&S!cJ#8"!46G'9`!*! +&f3%i!1`"YJ316@pNG@aP)'*bEhGcCA)!N!9l!!%!I!((J!#3"Y6rrJ$9!FZ!!*! +'JJ"@!*)!KSJ'8h4KG'8k!*!&JJ#-!*)"1BJ!N!Dk!*X!cJ$9"!G6G'9`)%PZ!*! +'ZJ$F!-i"'J3)8h4PF#"2GA3!N!@k!2)!cJ&d"""5G@iJFh4KG'9YC@jd,LiZ!*! +&C3$J!(J"A380BfpYF'peEQ3JGQ&bF`#3"Q8"DJ"j!EJ&"epI)(CKFR-!N!E`!@X +""!'h"!4&C'Pd!!!"!!!!A@F!!&aR!!!"M3'r,63G`!!!!"`!jJ!$4%P86!!$!#* +%6%p(!!-!8P"*3e3!!J##C'0dBJ!#!+B#!*!&@I%"[b`-!J%!$`!!@S-"[b`8!J- +!A`!!%T`"[b`)!J3!M!!!@2!"[b`%!J!!+`#3#!)"!"d!!!!Z!EmUS!)$!%X!!"+ +$!*!%!J3!Q!!!@FS!N!3#!!!k!!!!B3#3"!)"!%!!!!PI!*!%!J)!D3!!%X!!N!3 +#!`"9!!!56`#3"!)!!'m!!&L)!*!%!J%!IJ!!@,`!N!316@pNG@aP)'*bEhGcCA) +08h4KBfXJBR*[Gh0PFJe6G'&MDb"LFQphFf9b$Ne[C(9XC5"LFQphFf9b"8&bFQp +h#Q*bC@&VF'pTER3*3@*[GA3JBQpi#8&LEh9d)'*[H!P"BQpeG#"LEhJ&3@*[GA3 +16@pNG@aP)'*bEhGcCA)08h4KBfXJBR*[Gh0PFJY@BA)JBR*[Gh0PFJj#FQphFf9 +b)(GTEQ4[GfIN: diff --git a/Mac/Tools/twit/twittest.py b/Mac/Tools/twit/twittest.py new file mode 100644 index 0000000..10d3693 --- /dev/null +++ b/Mac/Tools/twit/twittest.py @@ -0,0 +1,13 @@ +# Test program + +def foo(arg1, arg2): + bar(arg1+arg2) + bar(arg1-arg2) + foo(arg1+1, arg2-1) + +def bar(arg): + rv = 10/arg + print rv + +foo(0,10) + -- cgit v0.12