From 9c6476615d47ff373aa53a1288ed09fd2d86f8fe Mon Sep 17 00:00:00 2001 From: cacaodev Date: Fri, 12 Nov 2010 13:47:36 +0100 Subject: [PATCH 01/17] Allow parsing of functions with multiple arguments like multiply:by:(5,2) or FUNCTION('method:arg:', arg1, arg2) Added a missing CPDate.j import in CPExpression_function that was causing an 'unknown variable CPDate' error in deploy builds. Added documentation for +expressionForSubquery:... Added licence headers with credits. --- .../CPPredicate/CPComparisonPredicate.j | 23 +++++++++ Foundation/CPPredicate/CPCompoundPredicate.j | 23 +++++++++ Foundation/CPPredicate/CPExpression.j | 50 +++++++++++++------ .../CPPredicate/CPExpression_aggregate.j | 20 ++++++++ .../CPPredicate/CPExpression_constant.j | 23 +++++++++ .../CPPredicate/CPExpression_function.j | 23 ++++++++- Foundation/CPPredicate/CPExpression_keypath.j | 23 +++++++++ Foundation/CPPredicate/CPExpression_self.j | 20 ++++++++ Foundation/CPPredicate/CPExpression_set.j | 20 ++++++++ .../CPPredicate/CPExpression_subquery.j | 20 ++++++++ .../CPPredicate/CPExpression_variable.j | 23 +++++++++ Foundation/CPPredicate/CPPredicate.j | 45 +++++++++++++++-- Tests/Foundation/CPPredicateTest.j | 14 +++--- 13 files changed, 300 insertions(+), 27 deletions(-) diff --git a/Foundation/CPPredicate/CPComparisonPredicate.j b/Foundation/CPPredicate/CPComparisonPredicate.j index 9af047dc2..ac70d419e 100644 --- a/Foundation/CPPredicate/CPComparisonPredicate.j +++ b/Foundation/CPPredicate/CPComparisonPredicate.j @@ -1,3 +1,26 @@ +/* + * CPComparisonPredicate.j + * + * Portions based on NSComparisonPredicate.m in Cocotron (http://www.cocotron.org/) + * Copyright (c) 2006-2007 Christopher J. W. Lloyd + * + * Created by cacaodev. + * Copyright 2010. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ @import "CPArray.j" @import "CPNull.j" diff --git a/Foundation/CPPredicate/CPCompoundPredicate.j b/Foundation/CPPredicate/CPCompoundPredicate.j index 5715152d5..c502a7c39 100644 --- a/Foundation/CPPredicate/CPCompoundPredicate.j +++ b/Foundation/CPPredicate/CPCompoundPredicate.j @@ -1,3 +1,26 @@ +/* + * CPCompoundPredicate.j + * + * Portions based on NSCompoundPredicate.m in Cocotron (http://www.cocotron.org/) + * Copyright (c) 2006-2007 Christopher J. W. Lloyd + * + * Created by cacaodev. + * Copyright 2010. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ @import "CPPredicate.j" diff --git a/Foundation/CPPredicate/CPExpression.j b/Foundation/CPPredicate/CPExpression.j index 40ac4c695..43ce49bb6 100644 --- a/Foundation/CPPredicate/CPExpression.j +++ b/Foundation/CPPredicate/CPExpression.j @@ -1,3 +1,23 @@ +/* + * CPExpression.j + * + * Created by cacaodev. + * Copyright 2010. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ @import "CPString.j" @import "CPArray.j" @@ -113,7 +133,6 @@ CPMinusSetExpressionType = 9; return [[CPExpression_keypath alloc] initWithKeyPath:keyPath]; } -//Creating a Collection Expression /*! Returns a new aggregate expression for a given collection. @param collection A collection object (an instance of CPArray, CPSet, or CPDictionary) that contains further expressions. @@ -126,7 +145,7 @@ CPMinusSetExpressionType = 9; /*! Returns a new CPExpression object that represent the union of a given set and collection. - @param left An expression that evaluates to an CPSet object. + @param left An expression that evaluates to a CPSet object. @param right An expression that evaluates to a collection object (an instance of CPArray, CPSet, or CPDictionary). @return A new CPExpression object that represents the union of left and right. */ @@ -137,7 +156,7 @@ CPMinusSetExpressionType = 9; /*! Returns a new CPExpression object that represent the intersection of a given set and collection. - @param left An expression that evaluates to an CPSet object. + @param left An expression that evaluates to a CPSet object. @param right An expression that evaluates to a collection object (an instance of CPArray, CPSet, or CPDictionary). @return A new CPExpression object that represents the intersection of left and right. */ @@ -148,7 +167,7 @@ CPMinusSetExpressionType = 9; /*! Returns a new CPExpression object that represent the subtraction of a given collection from a given set. - @param left An expression that evaluates to an CPSet object. + @param left An expression that evaluates to a CPSet object. @param left An expression that evaluates to a collection object (an instance of CPArray, CPSet, or CPDictionary). @return A new CPExpression object that represents the subtraction of right from left. */ @@ -196,16 +215,8 @@ CPMinusSetExpressionType = 9; trunc: one CPExpression instance representing a number CPNumber uppercase: one CPExpression instance representing a string CPString lowercase: one CPExpression instance representing a string CPString - random none CPNumber (integer) random: one CPExpression instance representing a number CPNumber (integer) such that 0 <= rand < param - now none [CPDate now] - bitwiseAnd:with: two CPExpression instances representing numbers CPNumber (numbers will be treated as CPInteger) - bitwiseOr:with: two CPExpression instances representing numbers CPNumber (numbers will be treated as CPInteger) - bitwiseXor:with: two CPExpression instances representing numbers CPNumber (numbers will be treated as CPInteger) - leftshift:by: two CPExpression instances representing numbers CPNumber (numbers will be treated as CPInteger) - rightshift:by: two CPExpression instances representing numbers CPNumber (numbers will be treated as CPInteger) - onesComplement: one CPExpression instance representing a numbers CPNumber (numbers will be treated as CPInteger) - @endverbatim + now: none [CPDate now] This method raises an exception immediately if the selector is invalid; it raises an exception at runtime if the parameters are incorrect. */ @@ -217,16 +228,23 @@ CPMinusSetExpressionType = 9; /*! Returns an expression which will return the result of invoking on a given target a selector with a given name using given arguments. @param target A CPExpression object which will evaluate an object on which the selector identified by name may be invoked. - @param function_name The name of the method to be invoked. + @param selectorName The name of the method to be invoked. @param parameters An array containing CPExpression objects which can be evaluated to provide parameters for the method specified by name. @return An expression which will return the result of invoking the selector named name on the result of evaluating the target expression with the parameters specified by evaluating the elements of parameters. See the description of expressionForFunction:arguments: for examples of how to construct the parameter array. */ -+ (CPExpression)expressionForFunction:(CPExpression)target selectorName:(CPString)function_name arguments:(CPArray)parameters ++ (CPExpression)expressionForFunction:(CPExpression)target selectorName:(CPString)selectorName arguments:(CPArray)parameters { - return [[CPExpression_function alloc] initWithTarget:target selector:CPSelectorFromString(function_name) arguments:parameters]; + return [[CPExpression_function alloc] initWithTarget:target selector:CPSelectorFromString(selectorName) arguments:parameters]; } +/*! + Returns an expression that filters a collection by storing elements in the collection in a given variable and keeping the elements for which qualifier returns true. + @param expression A CPExpression that evaluates to a collection. + @param variable Used as a local variable, and will shadow any instances of variable in the bindings dictionary. The variable is removed or the old value replaced once evaluation completes. + @param predicate The predicate used to determine whether the element belongs in the result collection. + @return An expression that filters a collection by storing elements in the collection in the variable variable and keeping the elements for which qualifier returns true. +*/ + (CPExpression)expressionForSubquery:(CPExpression)expression usingIteratorVariable:(CPString)variable predicate:(CPPredicate)predicate { return [[CPExpression_subquery alloc] initWithExpression:expression usingIteratorVariable:variable predicate:predicate]; diff --git a/Foundation/CPPredicate/CPExpression_aggregate.j b/Foundation/CPPredicate/CPExpression_aggregate.j index 47be66fc3..ce91ef4ef 100644 --- a/Foundation/CPPredicate/CPExpression_aggregate.j +++ b/Foundation/CPPredicate/CPExpression_aggregate.j @@ -1,3 +1,23 @@ +/* + * CPExpression_aggregate.j + * + * Created by cacaodev. + * Copyright 2010. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ @import "CPExpression.j" @import "CPArray.j" diff --git a/Foundation/CPPredicate/CPExpression_constant.j b/Foundation/CPPredicate/CPExpression_constant.j index 01ca5084b..c9405cec5 100644 --- a/Foundation/CPPredicate/CPExpression_constant.j +++ b/Foundation/CPPredicate/CPExpression_constant.j @@ -1,3 +1,26 @@ +/* + * CPExpression_constant.j + * + * Portions based on NSExpression_constant.m in Cocotron (http://www.cocotron.org/) + * Copyright (c) 2006-2007 Christopher J. W. Lloyd + * + * Created by cacaodev. + * Copyright 2010. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ @import "CPExpression.j" @import "CPDictionary.j" diff --git a/Foundation/CPPredicate/CPExpression_function.j b/Foundation/CPPredicate/CPExpression_function.j index 72c8762dd..135f55113 100644 --- a/Foundation/CPPredicate/CPExpression_function.j +++ b/Foundation/CPPredicate/CPExpression_function.j @@ -1,8 +1,29 @@ +/* + * CPExpression_function.j + * + * Created by cacaodev. + * Copyright 2010. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ @import "CPExpression.j" @import "CPString.j" @import "CPArray.j" @import "CPDictionary.j" +@import "CPDate.j" @implementation CPExpression_function : CPExpression { @@ -247,7 +268,7 @@ var CPSelectorNameKey = @"CPSelectorName", return ABS(num); } -+ (CPDate)now ++ (CPDate)now:(id)_ { return [CPDate date]; } diff --git a/Foundation/CPPredicate/CPExpression_keypath.j b/Foundation/CPPredicate/CPExpression_keypath.j index 05d52e8cd..e4d459421 100644 --- a/Foundation/CPPredicate/CPExpression_keypath.j +++ b/Foundation/CPPredicate/CPExpression_keypath.j @@ -1,3 +1,26 @@ +/* + * CPExpression_keypath.j + * + * Portions based on NSExpression_keypath.m in Cocotron (http://www.cocotron.org/) + * Copyright (c) 2006-2007 Christopher J. W. Lloyd + * + * Created by cacaodev. + * Copyright 2010. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ @import "CPExpression.j" @import "CPExpression_function.j" diff --git a/Foundation/CPPredicate/CPExpression_self.j b/Foundation/CPPredicate/CPExpression_self.j index a313fe8ba..56e5efe85 100644 --- a/Foundation/CPPredicate/CPExpression_self.j +++ b/Foundation/CPPredicate/CPExpression_self.j @@ -1,3 +1,23 @@ +/* + * CPExpression_self.j + * + * Created by cacaodev. + * Copyright 2010. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ @import "CPExpression.j" @import "CPString.j" diff --git a/Foundation/CPPredicate/CPExpression_set.j b/Foundation/CPPredicate/CPExpression_set.j index 9be28e076..df2a95157 100644 --- a/Foundation/CPPredicate/CPExpression_set.j +++ b/Foundation/CPPredicate/CPExpression_set.j @@ -1,3 +1,23 @@ +/* + * CPExpression_set.j + * + * Created by cacaodev. + * Copyright 2010. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ @import "CPExpression.j" diff --git a/Foundation/CPPredicate/CPExpression_subquery.j b/Foundation/CPPredicate/CPExpression_subquery.j index 912f50d8e..7ab7f9bca 100644 --- a/Foundation/CPPredicate/CPExpression_subquery.j +++ b/Foundation/CPPredicate/CPExpression_subquery.j @@ -1,3 +1,23 @@ +/* + * CPExpression_subquery.j + * + * Created by cacaodev. + * Copyright 2010. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ @import "CPExpression.j" diff --git a/Foundation/CPPredicate/CPExpression_variable.j b/Foundation/CPPredicate/CPExpression_variable.j index 340c858b2..2455d3e69 100644 --- a/Foundation/CPPredicate/CPExpression_variable.j +++ b/Foundation/CPPredicate/CPExpression_variable.j @@ -1,3 +1,26 @@ +/* + * CPExpression_variable.j + * + * Portions based on NSExpression_variable.m in Cocotron (http://www.cocotron.org/) + * Copyright (c) 2006-2007 Christopher J. W. Lloyd + * + * Created by cacaodev. + * Copyright 2010. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ @import "CPExpression.j" @import "CPString.j" diff --git a/Foundation/CPPredicate/CPPredicate.j b/Foundation/CPPredicate/CPPredicate.j index d9df99faf..ba28c4e2a 100644 --- a/Foundation/CPPredicate/CPPredicate.j +++ b/Foundation/CPPredicate/CPPredicate.j @@ -1,6 +1,29 @@ +/* + * CPPredicate.j + * + * CPPredicate parsing based on NSPredicate.m in GNUStep Base Library (http://www.gnustep.org/) + * Copyright (c) 2005 Free Software Foundation. + * + * Created by cacaodev. + * Copyright 2010. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ -@import "CPValue.j" @import "CPArray.j" +@import "CPDictionary.j" @import "CPSet.j" @import "CPNull.j" @import "CPScanner.j" @@ -776,15 +799,28 @@ function(newValue)\ if (![self scanString:@"]" intoString:NULL]) CPRaiseParseError(self, @"expression"); } - else if ([self scanString:@":(" intoString:NULL]) + else if ([self scanString:@":" intoString:NULL]) { // function - this parser allows for (max)(a, b, c) to be properly // recognized and even (%K)(a, b, c) if %K evaluates to "max" - var args = []; if (![left keyPath]) CPRaiseParseError(self, @"expression"); + var selector = [left keyPath] + @":", + args = []; + + if (![self scanString:@"(" intoString:NULL]) + { + var str; + [self scanCharactersFromSet:[CPCharacterSet lowercaseLetterCharacterSet] intoString:REFERENCE(str)]; + + if (![self scanString:@":(" intoString:NULL]) + CPRaiseParseError(self, @"expression"); + + selector += str + @":"; + } + if (![self scanString:@")" intoString:NULL]) { [args addObject:[self parseExpression]]; @@ -794,7 +830,8 @@ function(newValue)\ if (![self scanString:@")" intoString:NULL]) CPRaiseParseError(self, @"expression"); } - left = [CPExpression expressionForFunction:([left keyPath] + ":") arguments:args]; + + left = [CPExpression expressionForFunction:selector arguments:args]; } else if ([self scanString:@"UNION" intoString:NULL]) { diff --git a/Tests/Foundation/CPPredicateTest.j b/Tests/Foundation/CPPredicateTest.j index 62863c887..3090e506b 100644 --- a/Tests/Foundation/CPPredicateTest.j +++ b/Tests/Foundation/CPPredicateTest.j @@ -272,7 +272,7 @@ [self assertTrue:[predicate evaluateWithObject:dict] message:[predicate description] + " should be true"]; // Test Symbolic token - predicate = [CPPredicate predicateWithFormat:@"Record1.Children[FIRST] = 'Kid1'"]; + predicate = [CPPredicate predicateWithFormat:@"Record1.Children[ FIRST ] = 'Kid1'"]; [self assertTrue:[predicate evaluateWithObject:dict] message:[predicate description] + " should be true"]; predicate = [CPPredicate predicateWithFormat:@"Record1.Children[1] = 'Kid2'"]; @@ -332,8 +332,8 @@ predicate = [CPPredicate predicateWithFormat: @"sum:(1,1) = 2"]; [self assertTrue:[predicate evaluateWithObject:nil] message:"Predicate " + predicate + " should evaluate to TRUE"]; -// predicate = [CPPredicate predicateWithFormat: @"multiply:by:(5,3) = 15"]; -// [self assertTrue:[predicate evaluateWithObject:nil] message:"Predicate " + predicate + " should evaluate to TRUE"]; + predicate = [CPPredicate predicateWithFormat: @"multiply:by:(5,3) = 15"]; + [self assertTrue:[predicate evaluateWithObject:nil] message:"Predicate " + predicate + " should evaluate to TRUE"]; // TEST custom functions predicate = [CPPredicate predicateWithFormat:@"FUNCTION('a/path', 'lastPathComponent') = 'path'"]; @@ -342,14 +342,16 @@ predicate = [CPPredicate predicateWithFormat:@"FUNCTION('a/path', 'substringFromIndex:', 2) = 'path'"]; [self assertTrue:[predicate evaluateWithObject:nil] message:"Predicate " + predicate + " should evaluate to TRUE"]; + predicate = [CPPredicate predicateWithFormat:@"FUNCTION('toto', 'stringByReplacingOccurrencesOfString:withString:', 'o', 'a') == 'tata'"]; + [self assertTrue:[predicate evaluateWithObject:nil] message:"Predicate " + predicate + " should be TRUE"]; + // TEST Subquery -- This means: search people who have 2 boys. predicate = [CPPredicate predicateWithFormat: @"SUBQUERY(Record1.Children, $x, $x BEGINSWITH 'Kid')[SIZE] = 2"]; [self assertTrue:[predicate evaluateWithObject:dict] message:"Predicate " + predicate + " should evaluate to TRUE"]; // Test Set expressions -// Parsing is ok but the evaluation of this predicate will return NO for 2 reasons: -// 1- CPSet -isEqual: is unimplemented. -// 2- lhs will evaluate to a CPSet and rhs to a CPArray (aggregate exp). Comparing sets against arrays will always fail in CPComparisonPredicate. This is also cocoa behavior but i guess it's for historical reasons (set expressions are 10.5+) and should be changed in capp in my opinion. +// Parsing is ok but the evaluation of this predicate will return NO because: +// - lhs will evaluate to a CPSet and rhs to a CPArray (aggregate exp). Comparing sets against arrays will always fail in CPComparisonPredicate. This is also cocoa behavior but i guess it's for historical reasons (set expressions are 10.5+) and should be changed in capp in my opinion. var object = [CPDictionary dictionaryWithObject:[CPSet setWithObjects:@"a"] forKey:"a"], result = [CPSet setWithObjects:@"a",@"b"]; From 72b8ed2fafac895a240d00ed6799f04c08291460 Mon Sep 17 00:00:00 2001 From: cacaodev Date: Sat, 15 Jan 2011 00:00:15 +0100 Subject: [PATCH 02/17] CPOutlineView: If nil, set outlineTableColumn when the first column is added. nib2cib: handle indentationPerLevel when the key is not in the xib. CPoutlineViewCibTest --- AppKit/CPOutlineView.j | 11 + .../CPOutlineViewCibTest/AppController.j | 79 + Tests/Manual/CPOutlineViewCibTest/Info.plist | 12 + Tests/Manual/CPOutlineViewCibTest/Jakefile | 94 + .../Resources/InitInfo.dict | 135 + .../Resources/MainMenu.cib | 1 + .../Resources/MainMenu.xib | 3339 +++++++++++++++++ .../Resources/spinner.gif | Bin 0 -> 1849 bytes .../CPOutlineViewCibTest/index-debug.html | 103 + Tests/Manual/CPOutlineViewCibTest/index.html | 77 + Tests/Manual/CPOutlineViewCibTest/main.j | 18 + .../Manual/CPOutlineViewTest/AppController.j | 4 +- Tools/nib2cib/NSOutlineView.j | 5 +- 13 files changed, 3875 insertions(+), 3 deletions(-) create mode 100644 Tests/Manual/CPOutlineViewCibTest/AppController.j create mode 100644 Tests/Manual/CPOutlineViewCibTest/Info.plist create mode 100644 Tests/Manual/CPOutlineViewCibTest/Jakefile create mode 100644 Tests/Manual/CPOutlineViewCibTest/Resources/InitInfo.dict create mode 100644 Tests/Manual/CPOutlineViewCibTest/Resources/MainMenu.cib create mode 100644 Tests/Manual/CPOutlineViewCibTest/Resources/MainMenu.xib create mode 100644 Tests/Manual/CPOutlineViewCibTest/Resources/spinner.gif create mode 100644 Tests/Manual/CPOutlineViewCibTest/index-debug.html create mode 100644 Tests/Manual/CPOutlineViewCibTest/index.html create mode 100644 Tests/Manual/CPOutlineViewCibTest/main.j diff --git a/AppKit/CPOutlineView.j b/AppKit/CPOutlineView.j index 67c7a6943..5f9d81b49 100644 --- a/AppKit/CPOutlineView.j +++ b/AppKit/CPOutlineView.j @@ -954,6 +954,17 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0, [self reloadItem:nil reloadChildren:YES]; } +/*! + @ignore + If the outlineTableColumn doesn't exist yet, we set it to the first column added. +*/ +- (void)addTableColumn:(CPTableColumn)aTableColumn +{ + if (_outlineTableColumn === nil) + _outlineTableColumn = aTableColumn; + + [super addTableColumn:aTableColumn]; +} /*! @ignore We overide this because we need a special behaviour for the outline column diff --git a/Tests/Manual/CPOutlineViewCibTest/AppController.j b/Tests/Manual/CPOutlineViewCibTest/AppController.j new file mode 100644 index 000000000..740f2491b --- /dev/null +++ b/Tests/Manual/CPOutlineViewCibTest/AppController.j @@ -0,0 +1,79 @@ +/* + * AppController.j + * CPOutlineViewCibTest + * + * Created by cacaodev on January 14, 2011. + * Copyright 2011, Your Company All rights reserved. + */ + +@import + +@implementation AppController : CPObject +{ + CPWindow theWindow; + CPOutlineView outlineView; + + CPDictionary rootItem; +} + +- (void)awakeFromCib +{ + var path = [[CPBundle mainBundle] pathForResource:@"InitInfo.dict"], + request = [CPURLRequest requestWithURL:path], + connection = [CPURLConnection connectionWithRequest:request delegate:self]; + + rootItem = nil; + [theWindow setFullBridge:YES]; +} + +- (void)connection:(CPURLConnection)connection didReceiveData:(CPString)dataString +{ + if (!dataString) + return; + + var data = [[CPData alloc] initWithRawString:dataString], + rootItem = [CPPropertyListSerialization propertyListFromData:data format:CPPropertyListXMLFormat_v1_0]; + + [outlineView reloadData]; +} + +// ========================== +// ! CPOutlineView Delegate +// ========================== + +- (int)outlineView:(CPOutlineView)theOutlineView numberOfChildrenOfItem:(id)theItem +{ + if (theItem == nil) + theItem = rootItem; + + if ([theItem isKindOfClass:[CPString class]]) + return 0; + + return [[theItem objectForKey:"Children"] count]; +} + +- (id)outlineView:(CPOutlineView)theOutlineView child:(int)theIndex ofItem:(id)theItem +{ + if (theItem == nil) + theItem = rootItem; + + return [[theItem objectForKey:"Children"] objectAtIndex:theIndex]; +} + +- (BOOL)outlineView:(CPOutlineView)theOutlineView isItemExpandable:(id)theItem +{ + if (theItem == nil) + theItem = rootItem; + + return ![theItem isKindOfClass:[CPString class]]; +} + +- (id)outlineView:(CPOutlineView)anOutlineView objectValueForTableColumn:(CPTableColumn)theColumn byItem:(id)theItem +{ + if ([theItem isKindOfClass:[CPString class]]) + return theItem; + + return [theItem objectForKey:"Name"]; +} + +@end diff --git a/Tests/Manual/CPOutlineViewCibTest/Info.plist b/Tests/Manual/CPOutlineViewCibTest/Info.plist new file mode 100644 index 000000000..9bb0bef23 --- /dev/null +++ b/Tests/Manual/CPOutlineViewCibTest/Info.plist @@ -0,0 +1,12 @@ + + + + + Main cib file base name + MainMenu.cib + CPBundleName + CPOutlineViewCibTest + CPPrincipalClass + CPApplication + + diff --git a/Tests/Manual/CPOutlineViewCibTest/Jakefile b/Tests/Manual/CPOutlineViewCibTest/Jakefile new file mode 100644 index 000000000..262b7c3dd --- /dev/null +++ b/Tests/Manual/CPOutlineViewCibTest/Jakefile @@ -0,0 +1,94 @@ +/* + * Jakefile + * CPOutlineViewCibTest + * + * Created by You on January 14, 2011. + * Copyright 2011, Your Company All rights reserved. + */ + +var ENV = require("system").env, + FILE = require("file"), + JAKE = require("jake"), + task = JAKE.task, + FileList = JAKE.FileList, + app = require("cappuccino/jake").app, + configuration = ENV["CONFIG"] || ENV["CONFIGURATION"] || ENV["c"] || "Debug", + OS = require("os"); + +app ("CPOutlineViewCibTest", function(task) +{ + task.setBuildIntermediatesPath(FILE.join("Build", "CPOutlineViewCibTest.build", configuration)); + task.setBuildPath(FILE.join("Build", configuration)); + + task.setProductName("CPOutlineViewCibTest"); + task.setIdentifier("com.yourcompany.CPOutlineViewCibTest"); + task.setVersion("1.0"); + task.setAuthor("Your Company"); + task.setEmail("feedback @nospam@ yourcompany.com"); + task.setSummary("CPOutlineViewCibTest"); + task.setSources((new FileList("**/*.j")).exclude(FILE.join("Build", "**"))); + task.setResources(new FileList("Resources/**")); + task.setIndexFilePath("index.html"); + task.setInfoPlistPath("Info.plist"); + task.setNib2CibFlags("-R Resources/"); + + if (configuration === "Debug") + task.setCompilerFlags("-DDEBUG -g"); + else + task.setCompilerFlags("-O"); +}); + +task ("default", ["CPOutlineViewCibTest"], function() +{ + printResults(configuration); +}); + +task ("build", ["default"]); + +task ("debug", function() +{ + ENV["CONFIGURATION"] = "Debug"; + JAKE.subjake(["."], "build", ENV); +}); + +task ("release", function() +{ + ENV["CONFIGURATION"] = "Release"; + JAKE.subjake(["."], "build", ENV); +}); + +task ("run", ["debug"], function() +{ + OS.system(["open", FILE.join("Build", "Debug", "CPOutlineViewCibTest", "index.html")]); +}); + +task ("run-release", ["release"], function() +{ + OS.system(["open", FILE.join("Build", "Release", "CPOutlineViewCibTest", "index.html")]); +}); + +task ("deploy", ["release"], function() +{ + FILE.mkdirs(FILE.join("Build", "Deployment", "CPOutlineViewCibTest")); + OS.system(["press", "-f", FILE.join("Build", "Release", "CPOutlineViewCibTest"), FILE.join("Build", "Deployment", "CPOutlineViewCibTest")]); + printResults("Deployment") +}); + +task ("desktop", ["release"], function() +{ + FILE.mkdirs(FILE.join("Build", "Desktop", "CPOutlineViewCibTest")); + require("cappuccino/nativehost").buildNativeHost(FILE.join("Build", "Release", "CPOutlineViewCibTest"), FILE.join("Build", "Desktop", "CPOutlineViewCibTest", "CPOutlineViewCibTest.app")); + printResults("Desktop") +}); + +task ("run-desktop", ["desktop"], function() +{ + OS.system([FILE.join("Build", "Desktop", "CPOutlineViewCibTest", "CPOutlineViewCibTest.app", "Contents", "MacOS", "NativeHost"), "-i"]); +}); + +function printResults(configuration) +{ + print("----------------------------"); + print(configuration+" app built at path: "+FILE.join("Build", configuration, "CPOutlineViewCibTest")); + print("----------------------------"); +} diff --git a/Tests/Manual/CPOutlineViewCibTest/Resources/InitInfo.dict b/Tests/Manual/CPOutlineViewCibTest/Resources/InitInfo.dict new file mode 100644 index 000000000..f62f92b96 --- /dev/null +++ b/Tests/Manual/CPOutlineViewCibTest/Resources/InitInfo.dict @@ -0,0 +1,135 @@ + + + + + Children + + + Children + + + Children + + + Children + + Monty + Smithers + Frink + Carl + Cletus + Bobo + Duff + + Name + Simpsons + + + Children + + Mountain Unicycling + Rock Climbing + Bouldering + Snowboarding + + Name + Sports + + + Children + + Eating Strawberries + Mangoes + Treehouses + Good Weather + Maui + Trogdor + + Name + Just Fun Stuff + + Foo with the Bar + Bar + BooFar + Foo Bar + + Name + Shows + + + Children + + + Children + + Big Sur + New York + Naples + Chez Panisse + Lucia + Switzerland + Ireland + + Name + Vacation + + + Children + + Green Bay + Milwaukee + Monroe + + Name + Other + + + Name + Travel + + + Children + + Kark + Valen + Kosh + Red Letter + Fluffy Ears + Hiro + + Name + Science Fiction + + + Name + Favorite Things Group + + + Children + + Mischief + Mayhem + Soap + + Name + Movies Group with a Long Title + + + Children + + ObjC + Cocoa + KVC + NSTooblar + + Name + Things That Rule + + Eagle + Boiler + Tarheel + + Name + OVRoot + + diff --git a/Tests/Manual/CPOutlineViewCibTest/Resources/MainMenu.cib b/Tests/Manual/CPOutlineViewCibTest/Resources/MainMenu.cib new file mode 100644 index 000000000..e25d45f05 --- /dev/null +++ b/Tests/Manual/CPOutlineViewCibTest/Resources/MainMenu.cib @@ -0,0 +1 @@ +280NPLIST;1.0;D;K;4;$topD;K;18;CPCibObjectDataKeyD;K;6;CP$UIDd;1;2E;E;K;8;$objectsA;S;5;$nullD;K;10;$classnameS;16;_CPCibObjectDataK;8;$classesA;S;16;_CPCibObjectDataS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;1;1E;K;28;_CPCibObjectDataNamesKeysKeyD;K;6;CP$UIDd;1;4E;K;30;_CPCibObjectDataNamesValuesKeyD;K;6;CP$UIDd;1;5E;K;30;_CPCibObjectDataClassesKeysKeyD;K;6;CP$UIDd;1;6E;K;32;_CPCibObjectDataClassesValuesKeyD;K;6;CP$UIDd;1;7E;K;30;_CPCibObjectDataConnectionsKeyD;K;6;CP$UIDd;1;8E;K;28;_CPCibObjectDataFrameworkKeyD;K;6;CP$UIDd;1;9E;K;26;_CPCibObjectDataNextOidKeyD;K;6;CP$UIDd;2;10E;K;30;_CPCibObjectDataObjectsKeysKeyD;K;6;CP$UIDd;2;11E;K;32;_CPCibObjectDataObjectsValuesKeyD;K;6;CP$UIDd;2;12E;K;26;_CPCibObjectDataOidKeysKeyD;K;6;CP$UIDd;2;13E;K;28;_CPCibObjectDataOidValuesKeyD;K;6;CP$UIDd;2;14E;K;28;_CPCibObjectDataFileOwnerKeyD;K;6;CP$UIDd;2;16E;K;33;_CPCibObjectDataVisibleWindowsKeyD;K;6;CP$UIDd;2;18E;E;D;K;10;$classnameS;7;CPArrayK;8;$classesA;S;7;CPArrayS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;20E;D;K;6;CP$UIDd;2;22E;D;K;6;CP$UIDd;2;23E;D;K;6;CP$UIDd;2;24E;D;K;6;CP$UIDd;2;25E;D;K;6;CP$UIDd;2;26E;D;K;6;CP$UIDd;2;27E;D;K;6;CP$UIDd;2;28E;D;K;6;CP$UIDd;2;29E;D;K;6;CP$UIDd;2;31E;D;K;6;CP$UIDd;2;32E;D;K;6;CP$UIDd;2;33E;D;K;6;CP$UIDd;2;34E;D;K;6;CP$UIDd;2;35E;D;K;6;CP$UIDd;2;36E;D;K;6;CP$UIDd;2;37E;D;K;6;CP$UIDd;2;38E;D;K;6;CP$UIDd;2;39E;D;K;6;CP$UIDd;2;40E;D;K;6;CP$UIDd;2;41E;D;K;6;CP$UIDd;2;42E;D;K;6;CP$UIDd;2;43E;D;K;6;CP$UIDd;2;44E;D;K;6;CP$UIDd;2;45E;D;K;6;CP$UIDd;2;46E;D;K;6;CP$UIDd;2;47E;D;K;6;CP$UIDd;2;48E;D;K;6;CP$UIDd;2;49E;D;K;6;CP$UIDd;2;50E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;51E;D;K;6;CP$UIDd;2;52E;D;K;6;CP$UIDd;2;53E;D;K;6;CP$UIDd;2;54E;D;K;6;CP$UIDd;2;55E;D;K;6;CP$UIDd;2;56E;D;K;6;CP$UIDd;2;57E;D;K;6;CP$UIDd;2;58E;D;K;6;CP$UIDd;2;59E;D;K;6;CP$UIDd;2;60E;D;K;6;CP$UIDd;2;61E;D;K;6;CP$UIDd;2;62E;D;K;6;CP$UIDd;2;63E;D;K;6;CP$UIDd;2;64E;D;K;6;CP$UIDd;2;65E;D;K;6;CP$UIDd;2;66E;D;K;6;CP$UIDd;2;67E;D;K;6;CP$UIDd;2;16E;D;K;6;CP$UIDd;2;68E;D;K;6;CP$UIDd;2;69E;D;K;6;CP$UIDd;2;70E;D;K;6;CP$UIDd;2;71E;D;K;6;CP$UIDd;2;72E;D;K;6;CP$UIDd;2;74E;D;K;6;CP$UIDd;2;75E;D;K;6;CP$UIDd;2;76E;D;K;6;CP$UIDd;2;77E;D;K;6;CP$UIDd;2;78E;D;K;6;CP$UIDd;2;79E;D;K;6;CP$UIDd;2;80E;D;K;6;CP$UIDd;2;81E;D;K;6;CP$UIDd;2;82E;D;K;6;CP$UIDd;2;83E;D;K;6;CP$UIDd;2;84E;D;K;6;CP$UIDd;2;85E;D;K;6;CP$UIDd;2;86E;D;K;6;CP$UIDd;2;87E;D;K;6;CP$UIDd;2;88E;D;K;6;CP$UIDd;2;90E;D;K;6;CP$UIDd;2;91E;D;K;6;CP$UIDd;2;93E;D;K;6;CP$UIDd;2;94E;D;K;6;CP$UIDd;2;95E;D;K;6;CP$UIDd;2;96E;D;K;6;CP$UIDd;2;97E;D;K;6;CP$UIDd;2;98E;D;K;6;CP$UIDd;2;99E;D;K;6;CP$UIDd;3;100E;D;K;6;CP$UIDd;3;101E;D;K;6;CP$UIDd;3;102E;D;K;6;CP$UIDd;3;103E;D;K;6;CP$UIDd;3;104E;D;K;6;CP$UIDd;3;105E;D;K;6;CP$UIDd;3;106E;D;K;6;CP$UIDd;3;107E;D;K;6;CP$UIDd;3;108E;D;K;6;CP$UIDd;3;109E;D;K;6;CP$UIDd;3;110E;D;K;6;CP$UIDd;3;111E;D;K;6;CP$UIDd;3;112E;D;K;6;CP$UIDd;3;113E;D;K;6;CP$UIDd;3;114E;D;K;6;CP$UIDd;3;115E;D;K;6;CP$UIDd;3;116E;D;K;6;CP$UIDd;3;118E;D;K;6;CP$UIDd;3;119E;D;K;6;CP$UIDd;3;120E;D;K;6;CP$UIDd;3;121E;D;K;6;CP$UIDd;3;123E;D;K;6;CP$UIDd;3;124E;D;K;6;CP$UIDd;3;125E;D;K;6;CP$UIDd;3;126E;D;K;6;CP$UIDd;3;127E;D;K;6;CP$UIDd;3;128E;D;K;6;CP$UIDd;3;129E;D;K;6;CP$UIDd;3;130E;D;K;6;CP$UIDd;3;131E;D;K;6;CP$UIDd;3;132E;D;K;6;CP$UIDd;3;133E;D;K;6;CP$UIDd;3;134E;D;K;6;CP$UIDd;3;135E;D;K;6;CP$UIDd;3;136E;D;K;6;CP$UIDd;3;138E;D;K;6;CP$UIDd;3;139E;D;K;6;CP$UIDd;3;140E;D;K;6;CP$UIDd;3;141E;D;K;6;CP$UIDd;3;142E;D;K;6;CP$UIDd;3;143E;D;K;6;CP$UIDd;3;144E;D;K;6;CP$UIDd;3;145E;D;K;6;CP$UIDd;3;146E;D;K;6;CP$UIDd;3;147E;D;K;6;CP$UIDd;3;148E;D;K;6;CP$UIDd;3;149E;D;K;6;CP$UIDd;3;150E;D;K;6;CP$UIDd;3;151E;D;K;6;CP$UIDd;3;152E;D;K;6;CP$UIDd;3;153E;D;K;6;CP$UIDd;3;154E;D;K;6;CP$UIDd;3;155E;D;K;6;CP$UIDd;3;156E;D;K;6;CP$UIDd;3;157E;D;K;6;CP$UIDd;3;158E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;159E;D;K;6;CP$UIDd;3;160E;D;K;6;CP$UIDd;3;161E;D;K;6;CP$UIDd;3;162E;D;K;6;CP$UIDd;3;163E;D;K;6;CP$UIDd;3;164E;D;K;6;CP$UIDd;3;165E;D;K;6;CP$UIDd;3;166E;D;K;6;CP$UIDd;3;167E;D;K;6;CP$UIDd;3;168E;D;K;6;CP$UIDd;3;169E;D;K;6;CP$UIDd;3;170E;D;K;6;CP$UIDd;3;171E;D;K;6;CP$UIDd;3;172E;D;K;6;CP$UIDd;3;173E;D;K;6;CP$UIDd;3;174E;D;K;6;CP$UIDd;3;175E;D;K;6;CP$UIDd;3;176E;D;K;6;CP$UIDd;3;177E;D;K;6;CP$UIDd;3;178E;D;K;6;CP$UIDd;3;179E;D;K;6;CP$UIDd;3;180E;D;K;6;CP$UIDd;3;181E;D;K;6;CP$UIDd;3;182E;D;K;6;CP$UIDd;3;183E;D;K;6;CP$UIDd;3;184E;D;K;6;CP$UIDd;3;185E;D;K;6;CP$UIDd;3;186E;D;K;6;CP$UIDd;3;187E;D;K;6;CP$UIDd;3;188E;D;K;6;CP$UIDd;3;189E;D;K;6;CP$UIDd;3;190E;D;K;6;CP$UIDd;3;191E;D;K;6;CP$UIDd;3;192E;D;K;6;CP$UIDd;3;193E;D;K;6;CP$UIDd;3;194E;D;K;6;CP$UIDd;3;195E;D;K;6;CP$UIDd;3;196E;D;K;6;CP$UIDd;3;197E;D;K;6;CP$UIDd;3;198E;D;K;6;CP$UIDd;3;199E;D;K;6;CP$UIDd;3;200E;D;K;6;CP$UIDd;3;201E;D;K;6;CP$UIDd;3;202E;D;K;6;CP$UIDd;3;203E;D;K;6;CP$UIDd;3;204E;D;K;6;CP$UIDd;3;205E;D;K;6;CP$UIDd;3;206E;D;K;6;CP$UIDd;3;207E;D;K;6;CP$UIDd;3;208E;D;K;6;CP$UIDd;3;209E;D;K;6;CP$UIDd;3;210E;D;K;6;CP$UIDd;3;211E;D;K;6;CP$UIDd;3;212E;D;K;6;CP$UIDd;3;213E;D;K;6;CP$UIDd;3;214E;D;K;6;CP$UIDd;3;215E;D;K;6;CP$UIDd;3;216E;D;K;6;CP$UIDd;3;217E;D;K;6;CP$UIDd;3;218E;D;K;6;CP$UIDd;3;219E;D;K;6;CP$UIDd;3;220E;D;K;6;CP$UIDd;3;221E;D;K;6;CP$UIDd;3;222E;D;K;6;CP$UIDd;3;223E;D;K;6;CP$UIDd;3;224E;D;K;6;CP$UIDd;3;225E;D;K;6;CP$UIDd;3;226E;D;K;6;CP$UIDd;3;227E;D;K;6;CP$UIDd;3;228E;D;K;6;CP$UIDd;3;229E;D;K;6;CP$UIDd;3;230E;D;K;6;CP$UIDd;3;231E;D;K;6;CP$UIDd;3;232E;D;K;6;CP$UIDd;3;233E;D;K;6;CP$UIDd;3;234E;D;K;6;CP$UIDd;3;235E;D;K;6;CP$UIDd;3;236E;D;K;6;CP$UIDd;3;237E;D;K;6;CP$UIDd;3;238E;D;K;6;CP$UIDd;3;239E;D;K;6;CP$UIDd;3;240E;D;K;6;CP$UIDd;3;241E;D;K;6;CP$UIDd;3;242E;D;K;6;CP$UIDd;3;243E;D;K;6;CP$UIDd;3;244E;D;K;6;CP$UIDd;3;245E;D;K;6;CP$UIDd;3;246E;D;K;6;CP$UIDd;3;247E;D;K;6;CP$UIDd;3;248E;D;K;6;CP$UIDd;3;249E;D;K;6;CP$UIDd;3;250E;D;K;6;CP$UIDd;3;251E;D;K;6;CP$UIDd;3;252E;D;K;6;CP$UIDd;3;253E;D;K;6;CP$UIDd;3;254E;D;K;6;CP$UIDd;3;255E;D;K;6;CP$UIDd;3;256E;D;K;6;CP$UIDd;3;257E;D;K;6;CP$UIDd;3;258E;D;K;6;CP$UIDd;3;259E;D;K;6;CP$UIDd;3;260E;D;K;6;CP$UIDd;3;261E;D;K;6;CP$UIDd;3;262E;D;K;6;CP$UIDd;3;263E;D;K;6;CP$UIDd;3;264E;D;K;6;CP$UIDd;3;265E;D;K;6;CP$UIDd;3;266E;D;K;6;CP$UIDd;3;267E;D;K;6;CP$UIDd;3;268E;D;K;6;CP$UIDd;3;269E;D;K;6;CP$UIDd;3;270E;D;K;6;CP$UIDd;3;271E;D;K;6;CP$UIDd;3;272E;D;K;6;CP$UIDd;3;273E;D;K;6;CP$UIDd;3;274E;D;K;6;CP$UIDd;3;275E;D;K;6;CP$UIDd;3;276E;D;K;6;CP$UIDd;3;277E;D;K;6;CP$UIDd;3;278E;D;K;6;CP$UIDd;3;279E;D;K;6;CP$UIDd;3;280E;D;K;6;CP$UIDd;3;281E;D;K;6;CP$UIDd;3;282E;D;K;6;CP$UIDd;3;283E;D;K;6;CP$UIDd;3;284E;D;K;6;CP$UIDd;3;285E;D;K;6;CP$UIDd;3;286E;D;K;6;CP$UIDd;3;287E;D;K;6;CP$UIDd;3;288E;D;K;6;CP$UIDd;3;289E;D;K;6;CP$UIDd;3;290E;D;K;6;CP$UIDd;3;291E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;293E;D;K;6;CP$UIDd;3;294E;D;K;6;CP$UIDd;3;295E;D;K;6;CP$UIDd;3;296E;D;K;6;CP$UIDd;3;297E;D;K;6;CP$UIDd;3;299E;D;K;6;CP$UIDd;3;300E;D;K;6;CP$UIDd;3;301E;D;K;6;CP$UIDd;3;302E;D;K;6;CP$UIDd;3;303E;D;K;6;CP$UIDd;3;304E;D;K;6;CP$UIDd;3;305E;D;K;6;CP$UIDd;3;306E;D;K;6;CP$UIDd;3;307E;D;K;6;CP$UIDd;3;308E;D;K;6;CP$UIDd;3;309E;D;K;6;CP$UIDd;3;310E;D;K;6;CP$UIDd;3;311E;D;K;6;CP$UIDd;3;312E;D;K;6;CP$UIDd;3;313E;D;K;6;CP$UIDd;3;314E;D;K;6;CP$UIDd;3;315E;D;K;6;CP$UIDd;3;316E;D;K;6;CP$UIDd;3;317E;D;K;6;CP$UIDd;3;318E;D;K;6;CP$UIDd;3;319E;D;K;6;CP$UIDd;3;320E;D;K;6;CP$UIDd;3;321E;D;K;6;CP$UIDd;3;322E;D;K;6;CP$UIDd;3;323E;D;K;6;CP$UIDd;3;324E;D;K;6;CP$UIDd;3;325E;D;K;6;CP$UIDd;3;326E;D;K;6;CP$UIDd;3;327E;D;K;6;CP$UIDd;3;328E;D;K;6;CP$UIDd;3;329E;D;K;6;CP$UIDd;3;330E;D;K;6;CP$UIDd;3;331E;D;K;6;CP$UIDd;3;332E;D;K;6;CP$UIDd;3;333E;D;K;6;CP$UIDd;3;334E;D;K;6;CP$UIDd;3;335E;D;K;6;CP$UIDd;3;336E;D;K;6;CP$UIDd;3;337E;D;K;6;CP$UIDd;3;338E;D;K;6;CP$UIDd;3;339E;D;K;6;CP$UIDd;3;340E;D;K;6;CP$UIDd;3;341E;D;K;6;CP$UIDd;3;342E;D;K;6;CP$UIDd;3;343E;D;K;6;CP$UIDd;3;344E;D;K;6;CP$UIDd;3;345E;D;K;6;CP$UIDd;3;346E;D;K;6;CP$UIDd;3;347E;D;K;6;CP$UIDd;3;348E;D;K;6;CP$UIDd;3;349E;D;K;6;CP$UIDd;3;350E;D;K;6;CP$UIDd;3;351E;D;K;6;CP$UIDd;3;352E;D;K;6;CP$UIDd;3;353E;D;K;6;CP$UIDd;3;354E;D;K;6;CP$UIDd;3;355E;D;K;6;CP$UIDd;3;356E;D;K;6;CP$UIDd;3;357E;D;K;6;CP$UIDd;3;358E;D;K;6;CP$UIDd;3;359E;E;E;S;16;IBCocoaFrameworkD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;20E;D;K;6;CP$UIDd;2;22E;D;K;6;CP$UIDd;2;23E;D;K;6;CP$UIDd;2;24E;D;K;6;CP$UIDd;2;25E;D;K;6;CP$UIDd;2;26E;D;K;6;CP$UIDd;2;27E;D;K;6;CP$UIDd;2;29E;D;K;6;CP$UIDd;2;36E;D;K;6;CP$UIDd;2;38E;D;K;6;CP$UIDd;2;32E;D;K;6;CP$UIDd;2;33E;D;K;6;CP$UIDd;2;34E;D;K;6;CP$UIDd;2;35E;D;K;6;CP$UIDd;2;37E;D;K;6;CP$UIDd;2;28E;D;K;6;CP$UIDd;2;31E;D;K;6;CP$UIDd;2;39E;D;K;6;CP$UIDd;2;40E;D;K;6;CP$UIDd;2;41E;D;K;6;CP$UIDd;2;42E;D;K;6;CP$UIDd;2;43E;D;K;6;CP$UIDd;2;44E;D;K;6;CP$UIDd;2;45E;D;K;6;CP$UIDd;2;46E;D;K;6;CP$UIDd;2;47E;D;K;6;CP$UIDd;2;48E;D;K;6;CP$UIDd;2;49E;D;K;6;CP$UIDd;2;50E;D;K;6;CP$UIDd;2;51E;D;K;6;CP$UIDd;2;52E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;53E;D;K;6;CP$UIDd;2;54E;D;K;6;CP$UIDd;2;55E;D;K;6;CP$UIDd;2;56E;D;K;6;CP$UIDd;2;57E;D;K;6;CP$UIDd;2;58E;D;K;6;CP$UIDd;2;59E;D;K;6;CP$UIDd;2;60E;D;K;6;CP$UIDd;2;61E;D;K;6;CP$UIDd;2;62E;D;K;6;CP$UIDd;2;63E;D;K;6;CP$UIDd;2;64E;D;K;6;CP$UIDd;2;65E;D;K;6;CP$UIDd;2;66E;D;K;6;CP$UIDd;2;67E;D;K;6;CP$UIDd;2;68E;D;K;6;CP$UIDd;2;69E;D;K;6;CP$UIDd;2;70E;D;K;6;CP$UIDd;2;71E;D;K;6;CP$UIDd;2;72E;D;K;6;CP$UIDd;2;74E;D;K;6;CP$UIDd;2;75E;D;K;6;CP$UIDd;2;76E;D;K;6;CP$UIDd;2;77E;D;K;6;CP$UIDd;2;78E;D;K;6;CP$UIDd;2;79E;D;K;6;CP$UIDd;2;80E;D;K;6;CP$UIDd;2;81E;D;K;6;CP$UIDd;2;82E;D;K;6;CP$UIDd;2;83E;D;K;6;CP$UIDd;2;84E;D;K;6;CP$UIDd;2;85E;D;K;6;CP$UIDd;2;86E;D;K;6;CP$UIDd;2;87E;D;K;6;CP$UIDd;2;88E;D;K;6;CP$UIDd;2;91E;D;K;6;CP$UIDd;2;90E;D;K;6;CP$UIDd;2;93E;D;K;6;CP$UIDd;2;94E;D;K;6;CP$UIDd;2;95E;D;K;6;CP$UIDd;2;96E;D;K;6;CP$UIDd;2;97E;D;K;6;CP$UIDd;2;98E;D;K;6;CP$UIDd;2;99E;D;K;6;CP$UIDd;3;100E;D;K;6;CP$UIDd;3;101E;D;K;6;CP$UIDd;3;102E;D;K;6;CP$UIDd;3;103E;D;K;6;CP$UIDd;3;104E;D;K;6;CP$UIDd;3;105E;D;K;6;CP$UIDd;3;106E;D;K;6;CP$UIDd;3;107E;D;K;6;CP$UIDd;3;108E;D;K;6;CP$UIDd;3;109E;D;K;6;CP$UIDd;3;110E;D;K;6;CP$UIDd;3;112E;D;K;6;CP$UIDd;3;111E;D;K;6;CP$UIDd;3;113E;D;K;6;CP$UIDd;3;114E;D;K;6;CP$UIDd;3;115E;D;K;6;CP$UIDd;3;116E;D;K;6;CP$UIDd;3;118E;D;K;6;CP$UIDd;3;119E;D;K;6;CP$UIDd;3;120E;D;K;6;CP$UIDd;3;121E;D;K;6;CP$UIDd;3;123E;D;K;6;CP$UIDd;3;124E;D;K;6;CP$UIDd;3;125E;D;K;6;CP$UIDd;3;126E;D;K;6;CP$UIDd;3;127E;D;K;6;CP$UIDd;3;128E;D;K;6;CP$UIDd;3;129E;D;K;6;CP$UIDd;3;130E;D;K;6;CP$UIDd;3;131E;D;K;6;CP$UIDd;3;132E;D;K;6;CP$UIDd;3;133E;D;K;6;CP$UIDd;3;134E;D;K;6;CP$UIDd;3;135E;D;K;6;CP$UIDd;3;136E;D;K;6;CP$UIDd;3;139E;D;K;6;CP$UIDd;3;140E;D;K;6;CP$UIDd;3;138E;D;K;6;CP$UIDd;3;141E;D;K;6;CP$UIDd;3;142E;D;K;6;CP$UIDd;3;143E;D;K;6;CP$UIDd;3;144E;D;K;6;CP$UIDd;3;145E;D;K;6;CP$UIDd;3;146E;D;K;6;CP$UIDd;3;147E;D;K;6;CP$UIDd;3;148E;D;K;6;CP$UIDd;3;149E;D;K;6;CP$UIDd;3;150E;D;K;6;CP$UIDd;3;151E;D;K;6;CP$UIDd;3;152E;D;K;6;CP$UIDd;3;153E;D;K;6;CP$UIDd;3;154E;D;K;6;CP$UIDd;3;155E;D;K;6;CP$UIDd;3;156E;D;K;6;CP$UIDd;3;157E;D;K;6;CP$UIDd;3;158E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;119E;D;K;6;CP$UIDd;2;41E;D;K;6;CP$UIDd;2;69E;D;K;6;CP$UIDd;2;99E;D;K;6;CP$UIDd;2;76E;D;K;6;CP$UIDd;3;139E;D;K;6;CP$UIDd;2;69E;D;K;6;CP$UIDd;3;119E;D;K;6;CP$UIDd;3;108E;D;K;6;CP$UIDd;2;45E;D;K;6;CP$UIDd;3;139E;D;K;6;CP$UIDd;3;108E;D;K;6;CP$UIDd;2;69E;D;K;6;CP$UIDd;3;139E;D;K;6;CP$UIDd;2;45E;D;K;6;CP$UIDd;3;119E;D;K;6;CP$UIDd;2;93E;D;K;6;CP$UIDd;2;16E;D;K;6;CP$UIDd;2;22E;D;K;6;CP$UIDd;3;139E;D;K;6;CP$UIDd;2;51E;D;K;6;CP$UIDd;3;142E;D;K;6;CP$UIDd;3;121E;D;K;6;CP$UIDd;2;32E;D;K;6;CP$UIDd;3;139E;D;K;6;CP$UIDd;3;149E;D;K;6;CP$UIDd;3;104E;D;K;6;CP$UIDd;2;43E;D;K;6;CP$UIDd;2;22E;D;K;6;CP$UIDd;2;88E;D;K;6;CP$UIDd;3;121E;D;K;6;CP$UIDd;3;123E;D;K;6;CP$UIDd;3;119E;D;K;6;CP$UIDd;3;121E;D;K;6;CP$UIDd;2;59E;D;K;6;CP$UIDd;3;139E;D;K;6;CP$UIDd;3;139E;D;K;6;CP$UIDd;3;139E;D;K;6;CP$UIDd;2;25E;D;K;6;CP$UIDd;2;35E;D;K;6;CP$UIDd;2;69E;D;K;6;CP$UIDd;3;108E;D;K;6;CP$UIDd;2;69E;D;K;6;CP$UIDd;3;119E;D;K;6;CP$UIDd;3;108E;D;K;6;CP$UIDd;3;108E;D;K;6;CP$UIDd;3;139E;D;K;6;CP$UIDd;3;139E;D;K;6;CP$UIDd;3;143E;D;K;6;CP$UIDd;3;108E;D;K;6;CP$UIDd;3;121E;D;K;6;CP$UIDd;3;139E;D;K;6;CP$UIDd;2;90E;D;K;6;CP$UIDd;3;121E;D;K;6;CP$UIDd;2;16E;D;K;6;CP$UIDd;3;130E;D;K;6;CP$UIDd;3;121E;D;K;6;CP$UIDd;2;76E;D;K;6;CP$UIDd;2;69E;D;K;6;CP$UIDd;2;69E;D;K;6;CP$UIDd;3;101E;D;K;6;CP$UIDd;2;69E;D;K;6;CP$UIDd;2;22E;D;K;6;CP$UIDd;3;101E;D;K;6;CP$UIDd;2;81E;D;K;6;CP$UIDd;2;60E;D;K;6;CP$UIDd;3;121E;D;K;6;CP$UIDd;3;108E;D;K;6;CP$UIDd;2;16E;D;K;6;CP$UIDd;2;74E;D;K;6;CP$UIDd;2;60E;D;K;6;CP$UIDd;2;69E;D;K;6;CP$UIDd;2;60E;D;K;6;CP$UIDd;2;59E;D;K;6;CP$UIDd;3;108E;D;K;6;CP$UIDd;3;108E;D;K;6;CP$UIDd;3;102E;D;K;6;CP$UIDd;2;78E;D;K;6;CP$UIDd;2;76E;D;K;6;CP$UIDd;2;51E;D;K;6;CP$UIDd;2;76E;D;K;6;CP$UIDd;2;51E;D;K;6;CP$UIDd;2;16E;D;K;6;CP$UIDd;3;149E;D;K;6;CP$UIDd;2;79E;D;K;6;CP$UIDd;3;149E;D;K;6;CP$UIDd;2;22E;D;K;6;CP$UIDd;3;119E;D;K;6;CP$UIDd;3;119E;D;K;6;CP$UIDd;3;100E;D;K;6;CP$UIDd;2;43E;D;K;6;CP$UIDd;2;77E;D;K;6;CP$UIDd;3;121E;D;K;6;CP$UIDd;2;93E;D;K;6;CP$UIDd;3;158E;D;K;6;CP$UIDd;3;121E;D;K;6;CP$UIDd;3;131E;D;K;6;CP$UIDd;3;138E;D;K;6;CP$UIDd;2;60E;D;K;6;CP$UIDd;2;69E;D;K;6;CP$UIDd;3;139E;D;K;6;CP$UIDd;2;43E;D;K;6;CP$UIDd;3;108E;D;K;6;CP$UIDd;3;139E;D;K;6;CP$UIDd;3;121E;D;K;6;CP$UIDd;2;76E;D;K;6;CP$UIDd;3;108E;D;K;6;CP$UIDd;3;121E;D;K;6;CP$UIDd;3;139E;D;K;6;CP$UIDd;3;121E;D;K;6;CP$UIDd;3;139E;D;K;6;CP$UIDd;3;153E;D;K;6;CP$UIDd;2;45E;D;K;6;CP$UIDd;2;93E;D;K;6;CP$UIDd;3;121E;D;K;6;CP$UIDd;2;76E;D;K;6;CP$UIDd;2;76E;D;K;6;CP$UIDd;2;69E;D;K;6;CP$UIDd;3;101E;D;K;6;CP$UIDd;2;93E;D;K;6;CP$UIDd;3;139E;D;K;6;CP$UIDd;2;86E;D;K;6;CP$UIDd;2;44E;D;K;6;CP$UIDd;3;101E;D;K;6;CP$UIDd;2;60E;D;K;6;CP$UIDd;3;101E;D;K;6;CP$UIDd;2;48E;D;K;6;CP$UIDd;2;77E;D;K;6;CP$UIDd;2;51E;D;K;6;CP$UIDd;3;119E;D;K;6;CP$UIDd;2;43E;D;K;6;CP$UIDd;2;48E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;E;E;D;K;10;$classnameS;18;_CPCibCustomObjectK;8;$classesA;S;18;_CPCibCustomObjectS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;15E;K;27;_CPCibCustomObjectClassNameD;K;6;CP$UIDd;3;360E;E;D;K;10;$classnameS;5;CPSetK;8;$classesA;S;5;CPSetS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;17E;K;15;CPSetObjectsKeyD;K;6;CP$UIDd;3;361E;E;D;K;10;$classnameS;10;CPMenuItemK;8;$classesA;S;10;CPMenuItemS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;362E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;119E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;363E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;10;$classnameS;6;CPMenuK;8;$classesA;S;6;CPMenuS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;21E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;365E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;366E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;367E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;69E;E;D;K;6;$classD;K;6;CP$UIDd;2;21E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;368E;K;13;CPMenuNameKeyD;K;6;CP$UIDd;3;369E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;370E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;371E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;372E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;20;CPMenuItemSubmenuKeyD;K;6;CP$UIDd;2;59E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;76E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;24;CPMenuItemIsSeparatorKeyD;K;6;CP$UIDd;3;373E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;374E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;22;CPMenuItemIsEnabledKeyD;K;6;CP$UIDd;3;375E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;139E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;376E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;69E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;377E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;378E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;24;CPMenuItemIsSeparatorKeyD;K;6;CP$UIDd;3;373E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;374E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;22;CPMenuItemIsEnabledKeyD;K;6;CP$UIDd;3;375E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;119E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;379E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;119E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;380E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;10;$classnameS;10;CPScrollerK;8;$classesA;S;10;CPScrollerS;9;CPControlS;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;30E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;93E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;381E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;382E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;383E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;93E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;384E;K;17;CPViewIsHiddenKeyD;K;6;CP$UIDd;3;385E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;386E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;387E;K;17;CPControlValueKeyD;K;6;CP$UIDd;3;381E;K;18;CPControlTargetKeyD;K;6;CP$UIDd;2;93E;K;18;CPControlActionKeyD;K;6;CP$UIDd;3;388E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;3;389E;K;21;CPScrollerControlSizeD;K;6;CP$UIDd;3;381E;K;24;CPScrollerKnobProportionD;K;6;CP$UIDd;3;390E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;391E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;372E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;20;CPMenuItemSubmenuKeyD;K;6;CP$UIDd;2;45E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;139E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;24;CPMenuItemIsSeparatorKeyD;K;6;CP$UIDd;3;373E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;374E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;22;CPMenuItemIsEnabledKeyD;K;6;CP$UIDd;3;375E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;108E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;392E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;69E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;393E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;394E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;372E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;20;CPMenuItemSubmenuKeyD;K;6;CP$UIDd;2;60E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;139E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;24;CPMenuItemIsSeparatorKeyD;K;6;CP$UIDd;3;373E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;374E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;22;CPMenuItemIsEnabledKeyD;K;6;CP$UIDd;3;375E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;108E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;395E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;45E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;396E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;45E;E;D;K;6;$classD;K;6;CP$UIDd;2;15E;K;27;_CPCibCustomObjectClassNameD;K;6;CP$UIDd;3;360E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;397E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;22E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;365E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;372E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;20;CPMenuItemSubmenuKeyD;K;6;CP$UIDd;2;22E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;139E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;398E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;51E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;21E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;399E;K;13;CPMenuNameKeyD;K;6;CP$UIDd;3;400E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;401E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;402E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;372E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;20;CPMenuItemSubmenuKeyD;K;6;CP$UIDd;3;149E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;121E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;21E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;391E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;403E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;404E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;139E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;405E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;406E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;3;407E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;149E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;408E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;21E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;409E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;410E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;24;CPMenuItemIsSeparatorKeyD;K;6;CP$UIDd;3;373E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;374E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;22;CPMenuItemIsEnabledKeyD;K;6;CP$UIDd;3;375E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;43E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;411E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;22E;E;D;K;6;$classD;K;6;CP$UIDd;2;21E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;412E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;413E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;24;CPMenuItemIsSeparatorKeyD;K;6;CP$UIDd;3;373E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;374E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;22;CPMenuItemIsEnabledKeyD;K;6;CP$UIDd;3;375E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;121E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;414E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;119E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;415E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;121E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;416E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;417E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;59E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;418E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;419E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;420E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;3;421E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;139E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;422E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;24;CPMenuItemIsSeparatorKeyD;K;6;CP$UIDd;3;373E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;374E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;22;CPMenuItemIsEnabledKeyD;K;6;CP$UIDd;3;375E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;139E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;423E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;139E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;424E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;21E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;371E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;425E;E;D;K;6;$classD;K;6;CP$UIDd;2;21E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;394E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;426E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;24;CPMenuItemIsSeparatorKeyD;K;6;CP$UIDd;3;373E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;374E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;22;CPMenuItemIsEnabledKeyD;K;6;CP$UIDd;3;375E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;69E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;427E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;108E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;428E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;419E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;429E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;69E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;430E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;431E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;119E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;416E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;432E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;433E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;108E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;24;CPMenuItemIsSeparatorKeyD;K;6;CP$UIDd;3;373E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;374E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;22;CPMenuItemIsEnabledKeyD;K;6;CP$UIDd;3;375E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;108E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;434E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;139E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;418E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;24;CPMenuItemIsSeparatorKeyD;K;6;CP$UIDd;3;373E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;374E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;22;CPMenuItemIsEnabledKeyD;K;6;CP$UIDd;3;375E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;139E;E;D;K;6;$classD;K;6;CP$UIDd;2;21E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;435E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;436E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;437E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;108E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;438E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;439E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;121E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;440E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;441E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;3;389E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;139E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;442E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;10;$classnameS;6;CPViewK;8;$classesA;S;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;73E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;381E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;443E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;443E;K;17;CPViewSubviewsKeyD;K;6;CP$UIDd;3;444E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;1;0E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;445E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;446E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;121E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;447E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;21E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;448E;K;13;CPMenuNameKeyD;K;6;CP$UIDd;3;449E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;450E;E;D;K;6;$classD;K;6;CP$UIDd;2;21E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;451E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;452E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;453E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;372E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;20;CPMenuItemSubmenuKeyD;K;6;CP$UIDd;3;101E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;121E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;454E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;372E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;20;CPMenuItemSubmenuKeyD;K;6;CP$UIDd;3;108E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;76E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;455E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;69E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;456E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;457E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;372E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;20;CPMenuItemSubmenuKeyD;K;6;CP$UIDd;2;86E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;69E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;458E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;3;407E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;101E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;408E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;459E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;69E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;460E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;378E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;395E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;22E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;461E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;3;462E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;101E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;463E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;21E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;457E;K;13;CPMenuNameKeyD;K;6;CP$UIDd;3;464E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;465E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;395E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;60E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;412E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;372E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;20;CPMenuItemSubmenuKeyD;K;6;CP$UIDd;2;51E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;121E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;10;$classnameS;20;_CPCibWindowTemplateK;8;$classesA;S;20;_CPCibWindowTemplateS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;89E;K;30;_CPCibWindowTemplateMaxSizeKeyD;K;6;CP$UIDd;3;466E;K;32;_CPCibWindowTemplateViewClassKeyD;K;6;CP$UIDd;1;0E;K;34;_CPCibWindowTemplateWindowClassKeyD;K;6;CP$UIDd;3;467E;K;33;_CPCibWindowTemplateWindowRectKeyD;K;6;CP$UIDd;3;468E;K;30;_CPCibWindowTempatStyleMaskKeyD;K;6;CP$UIDd;3;462E;K;34;_CPCibWindowTemplateWindowTitleKeyD;K;6;CP$UIDd;3;399E;K;33;_CPCibWindowTemplateWindowViewKeyD;K;6;CP$UIDd;2;74E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;469E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;108E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;428E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;10;$classnameS;12;CPScrollViewK;8;$classesA;S;12;CPScrollViewS;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;92E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;74E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;381E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;470E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;471E;K;17;CPViewSubviewsKeyD;K;6;CP$UIDd;3;472E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;74E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;473E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;474E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;445E;K;23;CPScrollViewContentViewD;K;6;CP$UIDd;3;476E;K;29;CPScrollViewHeaderClipViewKeyD;K;6;CP$UIDd;3;477E;K;21;CPScrollViewVScrollerD;K;6;CP$UIDd;3;146E;K;21;CPScrollViewHScrollerD;K;6;CP$UIDd;2;31E;K;23;CPScrollViewVLineScrollD;K;6;CP$UIDd;3;478E;K;23;CPScrollViewVPageScrollD;K;6;CP$UIDd;3;478E;K;23;CPScrollViewHLineScrollD;K;6;CP$UIDd;3;478E;K;23;CPScrollViewHPageScrollD;K;6;CP$UIDd;3;478E;K;24;CPScrollViewHasVScrollerD;K;6;CP$UIDd;3;373E;K;24;CPScrollViewHasHScrollerD;K;6;CP$UIDd;3;373E;K;29;CPScrollViewAutohidesScrollerD;K;6;CP$UIDd;3;373E;K;25;CPScrollViewCornerViewKeyD;K;6;CP$UIDd;3;480E;K;31;CPScrollViewBottomCornerViewKeyD;K;6;CP$UIDd;3;481E;K;25;CPScrollViewBorderTypeKeyD;K;6;CP$UIDd;3;407E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;482E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;60E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;24;CPMenuItemIsSeparatorKeyD;K;6;CP$UIDd;3;373E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;374E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;22;CPMenuItemIsEnabledKeyD;K;6;CP$UIDd;3;375E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;69E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;483E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;60E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;484E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;59E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;485E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;108E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;486E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;368E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;372E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;20;CPMenuItemSubmenuKeyD;K;6;CP$UIDd;2;24E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;108E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;21E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;487E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;488E;E;D;K;6;$classD;K;6;CP$UIDd;2;21E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;453E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;489E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;487E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;372E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;20;CPMenuItemSubmenuKeyD;K;6;CP$UIDd;3;100E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;76E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;490E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;51E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;491E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;409E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;372E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;20;CPMenuItemSubmenuKeyD;K;6;CP$UIDd;2;48E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;76E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;492E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;51E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;15E;K;27;_CPCibCustomObjectClassNameD;K;6;CP$UIDd;3;493E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;494E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;3;421E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;149E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;495E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;21E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;454E;K;13;CPMenuNameKeyD;K;6;CP$UIDd;3;496E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;497E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;498E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;3;499E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;149E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;500E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;378E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;501E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;22E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;502E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;119E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;503E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;432E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;504E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;119E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;505E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;506E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;100E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;507E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;508E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;43E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;509E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;77E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;510E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;121E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;511E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;10;$classnameS;17;CPTableHeaderViewK;8;$classesA;S;17;CPTableHeaderViewS;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;117E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;3;477E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;381E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;512E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;512E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;3;477E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;513E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;445E;K;29;CPTableHeaderViewTableViewKeyD;K;6;CP$UIDd;3;138E;K;33;CPTableHeaderViewDrawsColumnLinesD;K;6;CP$UIDd;3;373E;E;D;K;6;$classD;K;6;CP$UIDd;2;21E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;514E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;515E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;516E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;121E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;503E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;21E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;517E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;518E;E;D;K;10;$classnameS;13;CPTableColumnK;8;$classesA;S;13;CPTableColumnS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;122E;K;26;CPTableColumnIdentifierKeyD;K;6;CP$UIDd;1;0E;K;21;CPTableColumnWidthKeyD;K;6;CP$UIDd;3;519E;K;24;CPTableColumnMinWidthKeyD;K;6;CP$UIDd;3;520E;K;24;CPTableColumnMaxWidthKeyD;K;6;CP$UIDd;3;521E;K;26;CPTableColumnHeaderViewKeyD;K;6;CP$UIDd;3;523E;K;24;CPTableColumnDataViewKeyD;K;6;CP$UIDd;3;525E;K;28;CPTableColumnResizingMaskKeyD;K;6;CP$UIDd;3;499E;K;24;CPTableColumnIsHiddenKeyD;K;6;CP$UIDd;3;375E;K;26;CPTableColumnIsEditableKeyD;K;6;CP$UIDd;3;373E;K;28;CPSortDescriptorPrototypeKeyD;K;6;CP$UIDd;1;0E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;526E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;60E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;527E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;69E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;528E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;24;CPMenuItemIsSeparatorKeyD;K;6;CP$UIDd;3;373E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;374E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;22;CPMenuItemIsEnabledKeyD;K;6;CP$UIDd;3;375E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;139E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;529E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;43E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;530E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;108E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;531E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;139E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;503E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;419E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;451E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;372E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;20;CPMenuItemSubmenuKeyD;K;6;CP$UIDd;2;77E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;121E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;517E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;372E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;20;CPMenuItemSubmenuKeyD;K;6;CP$UIDd;3;121E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;76E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;24;CPMenuItemIsSeparatorKeyD;K;6;CP$UIDd;3;373E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;374E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;22;CPMenuItemIsEnabledKeyD;K;6;CP$UIDd;3;375E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;108E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;532E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;121E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;533E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;378E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;534E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;3;407E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;139E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;535E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;536E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;121E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;537E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;139E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;416E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;419E;E;D;K;10;$classnameS;13;CPOutlineViewK;8;$classesA;S;13;CPOutlineViewS;11;CPTableViewS;9;CPControlS;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;137E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;3;476E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;381E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;538E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;538E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;3;476E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;539E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;445E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;3;389E;K;24;CPTableViewDataSourceKeyD;K;6;CP$UIDd;1;0E;K;22;CPTableViewDelegateKeyD;K;6;CP$UIDd;1;0E;K;23;CPTableViewRowHeightKeyD;K;6;CP$UIDd;3;540E;K;30;CPTableViewIntercellSpacingKeyD;K;6;CP$UIDd;3;541E;K;37;CPTableViewSelectionHighlightStyleKeyD;K;6;CP$UIDd;3;381E;K;37;CPTableViewColumnAutoresizingStyleKeyD;K;6;CP$UIDd;3;389E;K;31;CPTableViewMultipleSelectionKeyD;K;6;CP$UIDd;3;375E;K;28;CPTableViewEmptySelectionKeyD;K;6;CP$UIDd;3;373E;K;30;CPTableViewColumnReorderingKeyD;K;6;CP$UIDd;3;373E;K;28;CPTableViewColumnResizingKeyD;K;6;CP$UIDd;3;373E;K;29;CPTableViewColumnSelectionKeyD;K;6;CP$UIDd;3;375E;K;26;CPTableViewTableColumnsKeyD;K;6;CP$UIDd;3;542E;K;23;CPTableViewGridColorKeyD;K;6;CP$UIDd;1;0E;K;27;CPTableViewGridStyleMaskKeyD;K;6;CP$UIDd;1;0E;K;39;CPTableViewUsesAlternatingBackgroundKeyD;K;6;CP$UIDd;3;375E;K;34;CPTableViewAlternatingRowColorsKeyD;K;6;CP$UIDd;1;0E;K;24;CPTableViewCornerViewKeyD;K;6;CP$UIDd;3;480E;K;24;CPTableViewHeaderViewKeyD;K;6;CP$UIDd;3;118E;K;26;CPTableViewAutosaveNameKeyD;K;6;CP$UIDd;1;0E;K;34;CPOutlineViewOutlineTableColumnKeyD;K;6;CP$UIDd;3;123E;K;35;CPOutlineViewIndentationPerLevelKeyD;K;6;CP$UIDd;3;520E;K;26;CPOutlineViewDataSourceKeyD;K;6;CP$UIDd;1;0E;K;24;CPOutlineViewDelegateKeyD;K;6;CP$UIDd;1;0E;E;D;K;6;$classD;K;6;CP$UIDd;2;21E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;543E;K;13;CPMenuNameKeyD;K;6;CP$UIDd;3;544E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;545E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;397E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;45E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;24;CPMenuItemIsSeparatorKeyD;K;6;CP$UIDd;3;373E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;374E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;22;CPMenuItemIsEnabledKeyD;K;6;CP$UIDd;3;375E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;121E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;399E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;372E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;20;CPMenuItemSubmenuKeyD;K;6;CP$UIDd;2;43E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;76E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;435E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;372E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;20;CPMenuItemSubmenuKeyD;K;6;CP$UIDd;2;69E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;76E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;546E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;69E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;547E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;548E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;3;421E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;101E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;495E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;30E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;93E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;381E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;549E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;550E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;93E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;384E;K;17;CPViewIsHiddenKeyD;K;6;CP$UIDd;3;385E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;386E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;551E;K;17;CPControlValueKeyD;K;6;CP$UIDd;3;381E;K;18;CPControlTargetKeyD;K;6;CP$UIDd;2;93E;K;18;CPControlActionKeyD;K;6;CP$UIDd;3;552E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;3;389E;K;21;CPScrollerControlSizeD;K;6;CP$UIDd;3;381E;K;24;CPScrollerKnobProportionD;K;6;CP$UIDd;3;553E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;554E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;3;499E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;139E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;555E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;556E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;86E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;21E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;402E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;557E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;558E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;3;499E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;101E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;500E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;378E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;559E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;60E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;560E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;101E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;561E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;543E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;372E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;20;CPMenuItemSubmenuKeyD;K;6;CP$UIDd;3;139E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;48E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;562E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;77E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;563E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;51E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;564E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;565E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;119E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;566E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;43E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;567E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;364E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;514E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;372E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;20;CPMenuItemSubmenuKeyD;K;6;CP$UIDd;3;119E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;48E;E;S;1;0S;1;1S;1;2S;1;3S;1;4S;1;5S;1;6S;2;15S;1;7S;2;16S;2;10S;2;11S;2;12S;2;13S;1;8S;2;14S;1;9S;2;17S;2;18S;2;19S;2;20S;2;21S;2;22S;2;23S;2;24S;2;25S;2;26S;2;27S;2;28S;2;31S;2;29S;2;30S;2;32S;2;33S;2;34S;2;35S;2;36S;2;37S;2;38S;2;39S;2;40S;2;41S;2;42S;2;43S;2;44S;2;45S;2;46S;12;File's OwnerS;2;47S;2;48S;2;49S;2;50S;2;51S;2;52S;2;53S;2;54S;2;55S;2;56S;2;57S;2;58S;2;59S;2;60S;2;61S;2;62S;2;63S;2;64S;2;65S;2;66S;2;68S;2;67S;2;69S;2;70S;2;71S;2;72S;2;73S;2;74S;2;75S;2;76S;2;77S;2;78S;2;79S;2;80S;2;81S;2;82S;2;83S;2;84S;2;85S;2;86S;2;88S;2;87S;2;89S;2;90S;2;91S;2;92S;2;93S;2;94S;2;95S;2;96S;2;97S;2;98S;2;99S;3;100S;3;101S;3;102S;3;103S;3;104S;3;105S;3;106S;3;107S;3;108S;3;109S;3;110S;3;113S;3;111S;3;112S;3;114S;3;115S;3;116S;3;117S;3;118S;3;119S;3;120S;3;121S;3;122S;3;123S;3;124S;3;125S;3;126S;3;127S;3;128S;3;129S;3;130S;3;131D;K;10;$classnameS;20;CPCibOutletConnectorK;8;$classesA;S;20;CPCibOutletConnectorS;14;CPCibConnectorS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;292E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;16E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;3;106E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;568E;E;D;K;6;$classD;K;6;CP$UIDd;3;292E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;106E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;3;138E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;569E;E;D;K;6;$classD;K;6;CP$UIDd;3;292E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;106E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;90E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;570E;E;D;K;6;$classD;K;6;CP$UIDd;3;292E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;138E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;3;106E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;571E;E;D;K;6;$classD;K;6;CP$UIDd;3;292E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;138E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;3;106E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;568E;E;D;K;10;$classnameS;21;CPCibControlConnectorK;8;$classesA;S;21;CPCibControlConnectorS;14;CPCibConnectorS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;114E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;572E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;157E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;573E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;65E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;16E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;574E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;144E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;575E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;125E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;576E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;63E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;577E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;27E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;578E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;34E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;579E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;83E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;580E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;80E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;581E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;113E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;582E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;23E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;583E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;148E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;584E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;91E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;585E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;70E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;39E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;586E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;62E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;587E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;128E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;588E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;154E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;589E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;115E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;590E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;54E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;591E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;75E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;592E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;116E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;593E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;103E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;594E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;135E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;595E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;120E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;596E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;155E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;597E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;71E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;598E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;145E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;599E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;152E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;600E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;133E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;601E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;42E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;602E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;127E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;603E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;55E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;604E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;97E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;605E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;105E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;606E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;107E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;607E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;47E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;608E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;109E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;609E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;112E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;610E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;29E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;611E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;53E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;612E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;20E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;613E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;156E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;614E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;64E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;615E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;111E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;616E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;46E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;617E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;58E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;618E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;136E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;619E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;129E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;620E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;87E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;621E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;96E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;622E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;124E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;623E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;94E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;624E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;151E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;625E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;37E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;626E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;140E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;627E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;38E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;628E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;84E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;629E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;40E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;630E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;110E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;631E;E;D;K;6;$classD;K;6;CP$UIDd;3;298E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;50E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;632E;E;S;13;CPApplicationD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;90E;E;E;S;11;Align RightS;1;}d;7;1048576S;4;KernD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;84E;D;K;6;CP$UIDd;2;40E;D;K;6;CP$UIDd;3;110E;D;K;6;CP$UIDd;2;50E;E;E;S;15;Revert to SavedS;8;ServicesS;15;_CPServicesMenuD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;E;E;S;4;ViewS;14;submenuAction:T;S;0;F;S;13;Page Setup...S;1;Pd;7;1179648S;6;CenterS;1;|d;1;0S;19;{{1, 1}, {438, 15}}S;19;{{0, 0}, {438, 15}}d;1;8d;11;-2147483648S;8;scrollerS;8;disabledS;29;_horizontalScrollerDidScroll:d;1;4f;18;0.8295454545454546S;8;LigatureS;6;Print…S;1;pS;8;BaselineS;11;Use DefaultS;7;Use AllS;8;Use NoneS;27;Check Spelling While TypingS;6;WindowS;14;_CPWindowsMenuD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;157E;D;K;6;CP$UIDd;3;127E;D;K;6;CP$UIDd;2;49E;D;K;6;CP$UIDd;3;114E;E;E;S;13;SubstitutionsD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;37E;D;K;6;CP$UIDd;3;140E;D;K;6;CP$UIDd;2;38E;E;E;S;9;UnderlineS;1;uS;12;Smart Quotesd;1;2S;1;gS;6;FormatD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;153E;D;K;6;CP$UIDd;3;158E;E;E;S;6;LoosenS;20;Spelling and GrammarD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;155E;D;K;6;CP$UIDd;3;103E;D;K;6;CP$UIDd;2;42E;D;K;6;CP$UIDd;3;105E;E;E;S;7;JustifyS;4;CopyS;1;cS;12;Show ToolbarS;1;td;7;1572864S;6;Italicd;1;1S;1;iS;11;Show ColorsS;1;CD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;55E;D;K;6;CP$UIDd;2;97E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;87E;D;K;6;CP$UIDd;2;96E;D;K;6;CP$UIDd;3;124E;D;K;6;CP$UIDd;2;94E;D;K;6;CP$UIDd;3;151E;E;E;S;11;Hide OthersS;1;hS;4;SaveS;1;sS;10;Copy Rulerd;7;1310720S;20;About NewApplicationS;10;Show FontsS;4;FileD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;80E;D;K;6;CP$UIDd;3;144E;D;K;6;CP$UIDd;2;81E;D;K;6;CP$UIDd;2;61E;D;K;6;CP$UIDd;3;125E;D;K;6;CP$UIDd;2;63E;D;K;6;CP$UIDd;2;83E;D;K;6;CP$UIDd;2;23E;D;K;6;CP$UIDd;2;95E;D;K;6;CP$UIDd;2;27E;D;K;6;CP$UIDd;2;34E;E;E;S;19;Quit NewApplicationS;1;qS;4;UndoS;1;zS;7;SmallerS;1;-S;20;{{0, 0}, {480, 360}}D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;93E;E;E;S;6;normalS;10;Select AllS;1;aS;9;AMainMenuS;11;_CPMainMenuD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;79E;D;K;6;CP$UIDd;3;143E;D;K;6;CP$UIDd;3;131E;D;K;6;CP$UIDd;3;104E;D;K;6;CP$UIDd;2;25E;D;K;6;CP$UIDd;3;142E;D;K;6;CP$UIDd;3;102E;E;E;S;6;SpeechD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;115E;D;K;6;CP$UIDd;3;154E;E;E;S;4;FindS;14;NewApplicationS;3;NewS;1;nS;11;Open RecentS;9;Find NextS;8;Save As…S;1;SS;22;Use Selection for Findd;1;7S;1;eS;22;_CPRecentDocumentsMenuD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;148E;E;E;S;32;{10000000000000, 10000000000000}S;8;CPWindowS;24;{{335, 128}, {480, 360}}S;19;Hide NewApplicationS;22;{{20, 20}, {440, 320}}S;20;{{0, 0}, {440, 320}}D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;476E;D;K;6;CP$UIDd;3;146E;D;K;6;CP$UIDd;2;31E;D;K;6;CP$UIDd;3;477E;D;K;6;CP$UIDd;3;480E;D;K;6;CP$UIDd;3;481E;E;E;d;2;36S;10;scrollviewD;K;10;$classnameS;10;CPClipViewK;8;$classesA;S;10;CPClipViewS;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;475E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;93E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;381E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;633E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;538E;K;17;CPViewSubviewsKeyD;K;6;CP$UIDd;3;634E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;93E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;384E;K;21;CPViewBackgroundColorD;K;6;CP$UIDd;3;636E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;1;0E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;445E;K;24;CPScrollViewDocumentViewD;K;6;CP$UIDd;3;138E;E;D;K;6;$classD;K;6;CP$UIDd;3;475E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;93E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;381E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;637E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;638E;K;17;CPViewSubviewsKeyD;K;6;CP$UIDd;3;639E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;93E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;384E;K;21;CPViewBackgroundColorD;K;6;CP$UIDd;3;636E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;1;0E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;445E;K;24;CPScrollViewDocumentViewD;K;6;CP$UIDd;3;118E;E;d;2;10D;K;10;$classnameS;13;_CPCornerViewK;8;$classesA;S;13;_CPCornerViewS;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;479E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;93E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;381E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;640E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;641E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;93E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;384E;K;17;CPViewIsHiddenKeyD;K;6;CP$UIDd;3;385E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;642E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;445E;E;D;K;6;$classD;K;6;CP$UIDd;2;73E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;93E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;643E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;643E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;93E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;1;0E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;445E;E;S;5;RaiseS;11;SuperscriptS;18;Customize Toolbar…S;12;Preferences…S;1;,S;4;HelpD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;113E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;145E;D;K;6;CP$UIDd;2;82E;D;K;6;CP$UIDd;3;150E;D;K;6;CP$UIDd;2;85E;D;K;6;CP$UIDd;3;152E;E;E;S;14;Check SpellingS;1;;S;27;Check Grammar With SpellingS;13;AppControllerS;16;Smart Copy/PasteS;1;fS;18;_CPApplicationMenuD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;65E;D;K;6;CP$UIDd;2;36E;D;K;6;CP$UIDd;2;98E;D;K;6;CP$UIDd;2;33E;D;K;6;CP$UIDd;2;99E;D;K;6;CP$UIDd;2;66E;D;K;6;CP$UIDd;2;91E;D;K;6;CP$UIDd;2;62E;D;K;6;CP$UIDd;3;128E;D;K;6;CP$UIDd;3;132E;D;K;6;CP$UIDd;2;70E;E;E;S;11;Smart Linksd;1;3S;1;GS;7;TightenS;11;Paste RulerS;1;vS;10;Align LeftS;1;{S;19;NewApplication HelpS;1;?S;18;Bring All to FrontS;14;Start SpeakingS;3;CutS;1;xS;19;{{0, 0}, {438, 23}}S;14;tableHeaderRowS;4;TextD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;112E;D;K;6;CP$UIDd;2;29E;D;K;6;CP$UIDd;2;53E;D;K;6;CP$UIDd;2;20E;D;K;6;CP$UIDd;2;28E;D;K;6;CP$UIDd;3;156E;D;K;6;CP$UIDd;2;64E;D;K;6;CP$UIDd;3;111E;E;E;S;5;PasteS;4;EditD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;71E;D;K;6;CP$UIDd;3;133E;D;K;6;CP$UIDd;2;52E;D;K;6;CP$UIDd;3;116E;D;K;6;CP$UIDd;2;54E;D;K;6;CP$UIDd;3;120E;D;K;6;CP$UIDd;3;135E;D;K;6;CP$UIDd;2;75E;D;K;6;CP$UIDd;3;141E;D;K;6;CP$UIDd;2;78E;D;K;6;CP$UIDd;2;88E;D;K;6;CP$UIDd;2;44E;D;K;6;CP$UIDd;3;130E;E;E;d;3;422d;2;16d;4;1000D;K;10;$classnameS;24;_CPTableColumnHeaderViewK;8;$classesA;S;24;_CPTableColumnHeaderViewS;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;522E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;643E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;643E;K;17;CPViewSubviewsKeyD;K;6;CP$UIDd;3;644E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;645E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;445E;K;16;$atext-alignmentD;K;6;CP$UIDd;3;381E;K;38;_CPTableColumnHeaderViewStringValueKeyD;K;6;CP$UIDd;3;374E;K;32;_CPTableColumnHeaderViewImageKeyD;K;6;CP$UIDd;1;0E;K;31;_CPTableColumnHeaderViewFontKeyD;K;6;CP$UIDd;3;647E;E;D;K;10;$classnameS;11;CPTextFieldK;8;$classesA;S;11;CPTextFieldS;9;CPControlS;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;524E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;643E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;643E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;648E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;649E;K;6;$afontD;K;6;CP$UIDd;3;651E;K;17;$aline-break-modeD;K;6;CP$UIDd;3;389E;K;20;$avertical-alignmentD;K;6;CP$UIDd;3;407E;K;11;$aalignmentD;K;6;CP$UIDd;3;381E;K;15;$acontent-insetD;K;6;CP$UIDd;3;653E;K;17;CPControlValueKeyD;K;6;CP$UIDd;3;374E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;3;654E;K;24;CPTextFieldIsEditableKeyD;K;6;CP$UIDd;1;0E;K;26;CPTextFieldIsSelectableKeyD;K;6;CP$UIDd;1;0E;K;29;CPTextFieldDrawsBackgroundKeyD;K;6;CP$UIDd;1;0E;K;29;CPTextFieldBackgroundColorKeyD;K;6;CP$UIDd;1;0E;K;27;CPTextFieldLineBreakModeKeyD;K;6;CP$UIDd;3;389E;K;23;CPTextFieldAlignmentKeyD;K;6;CP$UIDd;3;381E;K;31;CPTextFieldPlaceholderStringKeyD;K;6;CP$UIDd;3;374E;E;S;9;SubscriptS;5;CloseS;1;wS;4;ZoomS;8;Show AllS;11;Paste StyleS;4;RedoS;1;ZS;4;BoldS;1;bS;6;DeleteS;10;Copy StyleS;20;{{0, 0}, {438, 302}}S;9;tableviewd;2;23S;6;{3, 2}D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;123E;E;E;S;4;FontS;11;_CPFontMenuD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;67E;D;K;6;CP$UIDd;3;134E;D;K;6;CP$UIDd;2;56E;D;K;6;CP$UIDd;2;46E;D;K;6;CP$UIDd;3;126E;D;K;6;CP$UIDd;3;147E;D;K;6;CP$UIDd;2;72E;D;K;6;CP$UIDd;2;26E;D;K;6;CP$UIDd;2;41E;D;K;6;CP$UIDd;2;32E;D;K;6;CP$UIDd;2;35E;D;K;6;CP$UIDd;2;68E;D;K;6;CP$UIDd;2;58E;D;K;6;CP$UIDd;2;57E;D;K;6;CP$UIDd;3;136E;D;K;6;CP$UIDd;3;129E;E;E;S;5;Open…S;1;oS;5;Find…S;22;{{424, 16}, {15, 287}}S;19;{{0, 0}, {15, 287}}S;17;disabled+verticalS;27;_verticalScrollerDidScroll:f;18;0.9503311258278145S;6;BiggerS;1;+S;10;Clear MenuD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;107E;D;K;6;CP$UIDd;2;47E;D;K;6;CP$UIDd;3;109E;E;E;S;13;Find PreviousS;5;LowerS;17;Jump to SelectionS;1;jS;13;Stop SpeakingS;14;Show Spelling…S;1;:S;10;Show RulerS;8;MinimizeS;1;mS;8;delegateS;11;outlineViewS;9;theWindowS;10;dataSourceS;15;arrangeInFront:S;19;performMiniaturize:S;29;orderFrontStandardAboutPanel:S;13;openDocument:S;13;performClose:S;13;saveDocument:S;14;runPageLayout:S;6;print:S;15;saveDocumentAs:S;12;newDocument:S;9;showHelp:S;22;revertDocumentToSaved:S;21;clearRecentDocuments:S;5;hide:S;10;terminate:S;22;hideOtherApplications:S;22;unhideAllApplications:S;13;stopSpeaking:S;14;startSpeaking:S;5;copy:S;10;selectAll:S;4;cut:S;14;checkSpelling:S;7;delete:S;6;paste:S;15;showGuessPanel:S;5;undo:S;23;performFindPanelAction:S;29;centerSelectionInVisibleArea:S;5;redo:S;30;toggleContinuousSpellChecking:S;12;performZoom:S;19;toggleToolbarShown:S;31;runToolbarCustomizationPalette:S;22;toggleGrammarChecking:S;24;toggleSmartInsertDelete:S;33;toggleAutomaticQuoteSubstitution:S;29;toggleAutomaticLinkDetection:S;10;alignLeft:S;12;alignCenter:S;15;alignJustified:S;11;alignRight:S;12;toggleRuler:S;10;copyRuler:S;11;pasteRuler:S;10;underline:S;21;orderFrontColorPanel:S;9;copyFont:S;10;pasteFont:S;9;unscript:S;12;superscript:S;10;subscript:S;14;raiseBaseline:S;14;lowerBaseline:S;21;useStandardLigatures:S;17;turnOffLigatures:S;16;useAllLigatures:S;19;useStandardKerning:S;15;turnOffKerning:S;15;tightenKerning:S;14;loosenKerning:S;20;{{1, 1}, {438, 302}}D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;138E;E;E;D;K;10;$classnameS;7;CPColorK;8;$classesA;S;7;CPColorS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;635E;K;20;CPColorComponentsKeyD;K;6;CP$UIDd;3;655E;E;S;21;{{1, 303}, {438, 17}}S;19;{{0, 0}, {438, 17}}D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;118E;E;E;S;22;{{424, 297}, {16, 23}}S;18;{{0, 0}, {16, 23}}S;10;cornerviewS;16;{{0, 0}, {0, 0}}D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;657E;E;E;S;12;columnHeaderD;K;10;$classnameS;6;CPFontK;8;$classesA;S;6;CPFontS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;646E;K;13;CPFontNameKeyD;K;6;CP$UIDd;3;658E;K;13;CPFontSizeKeyD;K;6;CP$UIDd;3;659E;K;15;CPFontIsBoldKeyD;K;6;CP$UIDd;3;375E;E;S;9;textfieldS;11;placeholderD;K;10;$classnameS;17;_CPThemeAttributeK;8;$classesA;S;17;_CPThemeAttributeS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;650E;K;4;nameD;K;6;CP$UIDd;3;660E;K;6;valuesD;K;6;CP$UIDd;3;662E;E;D;K;10;$classnameS;21;_CPKeyedArchiverValueK;8;$classesA;S;21;_CPKeyedArchiverValueS;7;CPValueS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;652E;K;15;CPValueValueKeyD;K;6;CP$UIDd;3;663E;E;d;4;3072D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;421E;D;K;6;CP$UIDd;3;421E;D;K;6;CP$UIDd;3;421E;D;K;6;CP$UIDd;3;421E;E;E;D;K;10;$classnameS;19;_CPImageAndTextViewK;8;$classesA;S;19;_CPImageAndTextViewS;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;656E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;3;523E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;643E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;643E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;3;523E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;664E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;1;0E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;445E;E;S;17;Arial, sans-serifd;2;12S;4;fontD;K;10;$classnameS;12;CPDictionaryK;8;$classesA;S;12;CPDictionaryS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;661E;K;10;CP.objectsD;K;21;selectedTableDataViewD;K;6;CP$UIDd;3;665E;K;6;normalD;K;6;CP$UIDd;3;647E;E;E;S;39;{"top":0,"right":5,"bottom":0,"left":5}d;2;18D;K;6;$classD;K;6;CP$UIDd;3;646E;K;13;CPFontNameKeyD;K;6;CP$UIDd;3;658E;K;13;CPFontSizeKeyD;K;6;CP$UIDd;3;659E;K;15;CPFontIsBoldKeyD;K;6;CP$UIDd;3;373E;E;E;K;9;$archiverS;15;CPKeyedArchiverK;8;$versionS;6;100000E; \ No newline at end of file diff --git a/Tests/Manual/CPOutlineViewCibTest/Resources/MainMenu.xib b/Tests/Manual/CPOutlineViewCibTest/Resources/MainMenu.xib new file mode 100644 index 000000000..c33a1ada4 --- /dev/null +++ b/Tests/Manual/CPOutlineViewCibTest/Resources/MainMenu.xib @@ -0,0 +1,3339 @@ + + + + 1050 + 10J567 + 823 + 1038.35 + 462.00 + + com.apple.InterfaceBuilder.CocoaPlugin + 823 + + + YES + + + + YES + com.apple.InterfaceBuilder.CocoaPlugin + + + PluginDependencyRecalculationVersion + + + + YES + + NSApplication + + + FirstResponder + + + NSApplication + + + AMainMenu + + YES + + + NewApplication + + 1048576 + 2147483647 + + NSImage + NSMenuCheckmark + + + NSImage + NSMenuMixedState + + submenuAction: + + NewApplication + + YES + + + About NewApplication + + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Preferences… + , + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Services + + 1048576 + 2147483647 + + + submenuAction: + + Services + + YES + + _NSServicesMenu + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Hide NewApplication + h + 1048576 + 2147483647 + + + + + + Hide Others + h + 1572864 + 2147483647 + + + + + + Show All + + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Quit NewApplication + q + 1048576 + 2147483647 + + + + + _NSAppleMenu + + + + + File + + 1048576 + 2147483647 + + + submenuAction: + + File + + YES + + + New + n + 1048576 + 2147483647 + + + + + + Open… + o + 1048576 + 2147483647 + + + + + + Open Recent + + 1048576 + 2147483647 + + + submenuAction: + + Open Recent + + YES + + + Clear Menu + + 1048576 + 2147483647 + + + + + _NSRecentDocumentsMenu + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Close + w + 1048576 + 2147483647 + + + + + + Save + s + 1048576 + 2147483647 + + + + + + Save As… + S + 1179648 + 2147483647 + + + + + + Revert to Saved + + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Page Setup... + P + 1179648 + 2147483647 + + + + + + + Print… + p + 1048576 + 2147483647 + + + + + + + + + Edit + + 1048576 + 2147483647 + + + submenuAction: + + Edit + + YES + + + Undo + z + 1048576 + 2147483647 + + + + + + Redo + Z + 1179648 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Cut + x + 1048576 + 2147483647 + + + + + + Copy + c + 1048576 + 2147483647 + + + + + + Paste + v + 1048576 + 2147483647 + + + + + + Delete + + 1048576 + 2147483647 + + + + + + Select All + a + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Find + + 1048576 + 2147483647 + + + submenuAction: + + Find + + YES + + + Find… + f + 1048576 + 2147483647 + + + 1 + + + + Find Next + g + 1048576 + 2147483647 + + + 2 + + + + Find Previous + G + 1179648 + 2147483647 + + + 3 + + + + Use Selection for Find + e + 1048576 + 2147483647 + + + 7 + + + + Jump to Selection + j + 1048576 + 2147483647 + + + + + + + + + Spelling and Grammar + + 1048576 + 2147483647 + + + submenuAction: + + Spelling and Grammar + + YES + + + Show Spelling… + : + 1048576 + 2147483647 + + + + + + Check Spelling + ; + 1048576 + 2147483647 + + + + + + Check Spelling While Typing + + 1048576 + 2147483647 + + + + + + Check Grammar With Spelling + + 1048576 + 2147483647 + + + + + + + + + Substitutions + + 1048576 + 2147483647 + + + submenuAction: + + Substitutions + + YES + + + Smart Copy/Paste + f + 1048576 + 2147483647 + + + 1 + + + + Smart Quotes + g + 1048576 + 2147483647 + + + 2 + + + + Smart Links + G + 1179648 + 2147483647 + + + 3 + + + + + + + Speech + + 1048576 + 2147483647 + + + submenuAction: + + Speech + + YES + + + Start Speaking + + 1048576 + 2147483647 + + + + + + Stop Speaking + + 1048576 + 2147483647 + + + + + + + + + + + + Format + + 2147483647 + + + submenuAction: + + Format + + YES + + + Font + + 2147483647 + + + submenuAction: + + Font + + YES + + + Show Fonts + t + 1048576 + 2147483647 + + + + + + Bold + b + 1048576 + 2147483647 + + + 2 + + + + Italic + i + 1048576 + 2147483647 + + + 1 + + + + Underline + u + 1048576 + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Bigger + + + 1048576 + 2147483647 + + + 3 + + + + Smaller + - + 1048576 + 2147483647 + + + 4 + + + + YES + YES + + + 2147483647 + + + + + + Kern + + 2147483647 + + + submenuAction: + + Kern + + YES + + + Use Default + + 2147483647 + + + + + + Use None + + 2147483647 + + + + + + Tighten + + 2147483647 + + + + + + Loosen + + 2147483647 + + + + + + + + + Ligature + + 2147483647 + + + submenuAction: + + Ligature + + YES + + + Use Default + + 2147483647 + + + + + + Use None + + 2147483647 + + + + + + Use All + + 2147483647 + + + + + + + + + Baseline + + 2147483647 + + + submenuAction: + + Baseline + + YES + + + Use Default + + 2147483647 + + + + + + Superscript + + 2147483647 + + + + + + Subscript + + 2147483647 + + + + + + Raise + + 2147483647 + + + + + + Lower + + 2147483647 + + + + + + + + + YES + YES + + + 2147483647 + + + + + + Show Colors + C + 1048576 + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Copy Style + c + 1572864 + 2147483647 + + + + + + Paste Style + v + 1572864 + 2147483647 + + + + + _NSFontMenu + + + + + Text + + 2147483647 + + + submenuAction: + + Text + + YES + + + Align Left + { + 1048576 + 2147483647 + + + + + + Center + | + 1048576 + 2147483647 + + + + + + Justify + + 2147483647 + + + + + + Align Right + } + 1048576 + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Show Ruler + + 2147483647 + + + + + + Copy Ruler + c + 1310720 + 2147483647 + + + + + + Paste Ruler + v + 1310720 + 2147483647 + + + + + + + + + + + + View + + 1048576 + 2147483647 + + + submenuAction: + + View + + YES + + + Show Toolbar + t + 1572864 + 2147483647 + + + + + + Customize Toolbar… + + 1048576 + 2147483647 + + + + + + + + + Window + + 1048576 + 2147483647 + + + submenuAction: + + Window + + YES + + + Minimize + m + 1048576 + 2147483647 + + + + + + Zoom + + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Bring All to Front + + 1048576 + 2147483647 + + + + + _NSWindowsMenu + + + + + Help + + 1048576 + 2147483647 + + + submenuAction: + + Help + + YES + + + NewApplication Help + ? + 1048576 + 2147483647 + + + + + + + + _NSMainMenu + + + 7 + 2 + {{335, 390}, {480, 360}} + 1946157056 + Window + NSWindow + + {1.79769e+308, 1.79769e+308} + + + 256 + + YES + + + 268 + + YES + + + 2304 + + YES + + + 256 + {438, 302} + + YES + + + 256 + {438, 17} + + + + + + -2147483392 + {{424, 0}, {16, 17}} + + + + YES + + 422 + 16 + 1000 + + 75628096 + 2048 + + + LucidaGrande + 11 + 3100 + + + 3 + MC4zMzMzMzI5ODU2AA + + + 6 + System + headerTextColor + + 3 + MAA + + + + + 337772096 + 2048 + Text Cell + + LucidaGrande + 13 + 1044 + + + + 6 + System + controlBackgroundColor + + 3 + MC42NjY2NjY2NjY3AA + + + + 6 + System + controlTextColor + + + + 3 + YES + YES + + + + 3 + 2 + + 3 + MQA + + + 6 + System + gridColor + + 3 + MC41AA + + + 17 + -767557632 + + + 4 + 15 + 0 + YES + 0 + + + {{1, 17}, {438, 302}} + + + + + 4 + + + + -2147483392 + {{424, 17}, {15, 287}} + + + _doScroller: + 0.95033112582781454 + + + + -2147483392 + {{1, 304}, {438, 15}} + + 1 + + _doScroller: + 0.82954545454545459 + + + + 2304 + + YES + + + {{1, 0}, {438, 17}} + + + + + 4 + + + + {{20, 20}, {440, 320}} + + + 562 + + + + + + QSAAAEEgAABBmAAAQZgAAA + + + {480, 360} + + + {{0, 0}, {1440, 878}} + {1.79769e+308, 1.79769e+308} + + + AppController + + + + + YES + + + performMiniaturize: + + + + 37 + + + + arrangeInFront: + + + + 39 + + + + print: + + + + 86 + + + + runPageLayout: + + + + 87 + + + + clearRecentDocuments: + + + + 127 + + + + orderFrontStandardAboutPanel: + + + + 142 + + + + performClose: + + + + 193 + + + + toggleContinuousSpellChecking: + + + + 222 + + + + undo: + + + + 223 + + + + copy: + + + + 224 + + + + checkSpelling: + + + + 225 + + + + paste: + + + + 226 + + + + stopSpeaking: + + + + 227 + + + + cut: + + + + 228 + + + + showGuessPanel: + + + + 230 + + + + redo: + + + + 231 + + + + selectAll: + + + + 232 + + + + startSpeaking: + + + + 233 + + + + delete: + + + + 235 + + + + performZoom: + + + + 240 + + + + performFindPanelAction: + + + + 241 + + + + centerSelectionInVisibleArea: + + + + 245 + + + + toggleGrammarChecking: + + + + 347 + + + + toggleSmartInsertDelete: + + + + 355 + + + + toggleAutomaticQuoteSubstitution: + + + + 356 + + + + toggleAutomaticLinkDetection: + + + + 357 + + + + showHelp: + + + + 360 + + + + saveDocument: + + + + 362 + + + + saveDocumentAs: + + + + 363 + + + + revertDocumentToSaved: + + + + 364 + + + + runToolbarCustomizationPalette: + + + + 365 + + + + toggleToolbarShown: + + + + 366 + + + + hide: + + + + 367 + + + + hideOtherApplications: + + + + 368 + + + + unhideAllApplications: + + + + 370 + + + + newDocument: + + + + 373 + + + + openDocument: + + + + 374 + + + + raiseBaseline: + + + + 426 + + + + lowerBaseline: + + + + 427 + + + + copyFont: + + + + 428 + + + + subscript: + + + + 429 + + + + superscript: + + + + 430 + + + + tightenKerning: + + + + 431 + + + + underline: + + + + 432 + + + + orderFrontColorPanel: + + + + 433 + + + + useAllLigatures: + + + + 434 + + + + loosenKerning: + + + + 435 + + + + pasteFont: + + + + 436 + + + + unscript: + + + + 437 + + + + useStandardKerning: + + + + 438 + + + + useStandardLigatures: + + + + 439 + + + + turnOffLigatures: + + + + 440 + + + + turnOffKerning: + + + + 441 + + + + alignLeft: + + + + 442 + + + + alignJustified: + + + + 443 + + + + copyRuler: + + + + 444 + + + + alignCenter: + + + + 445 + + + + toggleRuler: + + + + 446 + + + + alignRight: + + + + 447 + + + + pasteRuler: + + + + 448 + + + + terminate: + + + + 449 + + + + delegate + + + + 451 + + + + theWindow + + + + 459 + + + + dataSource + + + + 469 + + + + delegate + + + + 470 + + + + outlineView + + + + 475 + + + + + YES + + 0 + + YES + + + + + + -2 + + + File's Owner + + + -1 + + + First Responder + + + -3 + + + Application + + + 29 + + + YES + + + + + + + + + + MainMenu + + + 19 + + + YES + + + + + + 56 + + + YES + + + + + + 103 + + + YES + + + + 1 + + + 217 + + + YES + + + + + + 83 + + + YES + + + + + + 81 + + + YES + + + + + + + + + + + + + + + + 75 + + + 3 + + + 80 + + + 8 + + + 78 + + + 6 + + + 72 + + + + + 82 + + + 9 + + + 124 + + + YES + + + + + + 77 + + + 5 + + + 73 + + + 1 + + + 79 + + + 7 + + + 112 + + + 10 + + + 74 + + + 2 + + + 125 + + + YES + + + + + + 126 + + + + + 205 + + + YES + + + + + + + + + + + + + + + + + + 202 + + + + + 198 + + + + + 207 + + + + + 214 + + + + + 199 + + + + + 203 + + + + + 197 + + + + + 206 + + + + + 215 + + + + + 218 + + + YES + + + + + + 216 + + + YES + + + + + + 200 + + + YES + + + + + + + + + 219 + + + + + 201 + + + + + 204 + + + + + 220 + + + YES + + + + + + + + + + 213 + + + + + 210 + + + + + 221 + + + + + 208 + + + + + 209 + + + + + 106 + + + YES + + + + 2 + + + 111 + + + + + 57 + + + YES + + + + + + + + + + + + + + + + 58 + + + + + 134 + + + + + 150 + + + + + 136 + + + 1111 + + + 144 + + + + + 129 + + + 121 + + + 143 + + + + + 236 + + + + + 131 + + + YES + + + + + + 149 + + + + + 145 + + + + + 130 + + + + + 24 + + + YES + + + + + + + + + 92 + + + + + 5 + + + + + 239 + + + + + 23 + + + + + 295 + + + YES + + + + + + 296 + + + YES + + + + + + + 297 + + + + + 298 + + + + + 211 + + + YES + + + + + + 212 + + + YES + + + + + + + 195 + + + + + 196 + + + + + 346 + + + + + 348 + + + YES + + + + + + 349 + + + YES + + + + + + + + 350 + + + + + 351 + + + + + 354 + + + + + 371 + + + YES + + + + + + 372 + + + YES + + + + + + 375 + + + YES + + + + + + 376 + + + YES + + + + + + + 377 + + + YES + + + + + + 378 + + + YES + + + + + + 379 + + + YES + + + + + + + + + + + + + 380 + + + + + 381 + + + + + 382 + + + + + 383 + + + + + 384 + + + + + 385 + + + + + 386 + + + + + 387 + + + + + 388 + + + YES + + + + + + + + + + + + + + + + + + + + + 389 + + + + + 390 + + + + + 391 + + + + + 392 + + + + + 393 + + + + + 394 + + + + + 395 + + + + + 396 + + + + + 397 + + + YES + + + + + + 398 + + + YES + + + + + + 399 + + + YES + + + + + + 400 + + + + + 401 + + + + + 402 + + + + + 403 + + + + + 404 + + + + + 405 + + + YES + + + + + + + + + + 406 + + + + + 407 + + + + + 408 + + + + + 409 + + + + + 410 + + + + + 411 + + + YES + + + + + + + + 412 + + + + + 413 + + + + + 414 + + + + + 415 + + + YES + + + + + + + + + 416 + + + + + 417 + + + + + 418 + + + + + 419 + + + + + 450 + + + + + 460 + + + YES + + + + + + + + + 461 + + + + + 462 + + + + + 463 + + + YES + + + + + + 464 + + + + + 465 + + + YES + + + + + + 468 + + + + + + + YES + + YES + -3.IBPluginDependency + 103.IBPluginDependency + 103.ImportedFromIB2 + 106.IBPluginDependency + 106.ImportedFromIB2 + 106.editorWindowContentRectSynchronizationRect + 111.IBPluginDependency + 111.ImportedFromIB2 + 112.IBPluginDependency + 112.ImportedFromIB2 + 124.IBPluginDependency + 124.ImportedFromIB2 + 125.IBPluginDependency + 125.ImportedFromIB2 + 125.editorWindowContentRectSynchronizationRect + 126.IBPluginDependency + 126.ImportedFromIB2 + 129.IBPluginDependency + 129.ImportedFromIB2 + 130.IBPluginDependency + 130.ImportedFromIB2 + 130.editorWindowContentRectSynchronizationRect + 131.IBPluginDependency + 131.ImportedFromIB2 + 134.IBPluginDependency + 134.ImportedFromIB2 + 136.IBPluginDependency + 136.ImportedFromIB2 + 143.IBPluginDependency + 143.ImportedFromIB2 + 144.IBPluginDependency + 144.ImportedFromIB2 + 145.IBPluginDependency + 145.ImportedFromIB2 + 149.IBPluginDependency + 149.ImportedFromIB2 + 150.IBPluginDependency + 150.ImportedFromIB2 + 19.IBPluginDependency + 19.ImportedFromIB2 + 195.IBPluginDependency + 195.ImportedFromIB2 + 196.IBPluginDependency + 196.ImportedFromIB2 + 197.IBPluginDependency + 197.ImportedFromIB2 + 198.IBPluginDependency + 198.ImportedFromIB2 + 199.IBPluginDependency + 199.ImportedFromIB2 + 200.IBPluginDependency + 200.ImportedFromIB2 + 200.editorWindowContentRectSynchronizationRect + 201.IBPluginDependency + 201.ImportedFromIB2 + 202.IBPluginDependency + 202.ImportedFromIB2 + 203.IBPluginDependency + 203.ImportedFromIB2 + 204.IBPluginDependency + 204.ImportedFromIB2 + 205.IBPluginDependency + 205.ImportedFromIB2 + 205.editorWindowContentRectSynchronizationRect + 206.IBPluginDependency + 206.ImportedFromIB2 + 207.IBPluginDependency + 207.ImportedFromIB2 + 208.IBPluginDependency + 208.ImportedFromIB2 + 209.IBPluginDependency + 209.ImportedFromIB2 + 210.IBPluginDependency + 210.ImportedFromIB2 + 211.IBPluginDependency + 211.ImportedFromIB2 + 212.IBPluginDependency + 212.ImportedFromIB2 + 212.editorWindowContentRectSynchronizationRect + 213.IBPluginDependency + 213.ImportedFromIB2 + 214.IBPluginDependency + 214.ImportedFromIB2 + 215.IBPluginDependency + 215.ImportedFromIB2 + 216.IBPluginDependency + 216.ImportedFromIB2 + 217.IBPluginDependency + 217.ImportedFromIB2 + 218.IBPluginDependency + 218.ImportedFromIB2 + 219.IBPluginDependency + 219.ImportedFromIB2 + 220.IBPluginDependency + 220.ImportedFromIB2 + 220.editorWindowContentRectSynchronizationRect + 221.IBPluginDependency + 221.ImportedFromIB2 + 23.IBPluginDependency + 23.ImportedFromIB2 + 236.IBPluginDependency + 236.ImportedFromIB2 + 239.IBPluginDependency + 239.ImportedFromIB2 + 24.IBPluginDependency + 24.ImportedFromIB2 + 24.editorWindowContentRectSynchronizationRect + 29.IBEditorWindowLastContentRect + 29.IBPluginDependency + 29.ImportedFromIB2 + 29.WindowOrigin + 29.editorWindowContentRectSynchronizationRect + 295.IBPluginDependency + 296.IBPluginDependency + 296.editorWindowContentRectSynchronizationRect + 297.IBPluginDependency + 298.IBPluginDependency + 346.IBPluginDependency + 346.ImportedFromIB2 + 348.IBPluginDependency + 348.ImportedFromIB2 + 349.IBPluginDependency + 349.ImportedFromIB2 + 349.editorWindowContentRectSynchronizationRect + 350.IBPluginDependency + 350.ImportedFromIB2 + 351.IBPluginDependency + 351.ImportedFromIB2 + 354.IBPluginDependency + 354.ImportedFromIB2 + 371.IBEditorWindowLastContentRect + 371.IBPluginDependency + 371.IBWindowTemplateEditedContentRect + 371.NSWindowTemplate.visibleAtLaunch + 371.editorWindowContentRectSynchronizationRect + 371.windowTemplate.maxSize + 372.IBPluginDependency + 375.IBPluginDependency + 376.IBEditorWindowLastContentRect + 376.IBPluginDependency + 377.IBPluginDependency + 378.IBPluginDependency + 379.IBPluginDependency + 380.IBPluginDependency + 381.IBPluginDependency + 382.IBPluginDependency + 383.IBPluginDependency + 384.IBPluginDependency + 385.IBPluginDependency + 386.IBPluginDependency + 387.IBPluginDependency + 388.IBEditorWindowLastContentRect + 388.IBPluginDependency + 389.IBPluginDependency + 390.IBPluginDependency + 391.IBPluginDependency + 392.IBPluginDependency + 393.IBPluginDependency + 394.IBPluginDependency + 395.IBPluginDependency + 396.IBPluginDependency + 397.IBPluginDependency + 398.IBPluginDependency + 399.IBPluginDependency + 400.IBPluginDependency + 401.IBPluginDependency + 402.IBPluginDependency + 403.IBPluginDependency + 404.IBPluginDependency + 405.IBPluginDependency + 406.IBPluginDependency + 407.IBPluginDependency + 408.IBPluginDependency + 409.IBPluginDependency + 410.IBPluginDependency + 411.IBPluginDependency + 412.IBPluginDependency + 413.IBPluginDependency + 414.IBPluginDependency + 415.IBPluginDependency + 416.IBPluginDependency + 417.IBPluginDependency + 418.IBPluginDependency + 419.IBPluginDependency + 460.IBPluginDependency + 461.IBPluginDependency + 462.IBPluginDependency + 463.IBPluginDependency + 464.IBPluginDependency + 465.IBPluginDependency + 468.IBPluginDependency + 5.IBPluginDependency + 5.ImportedFromIB2 + 56.IBPluginDependency + 56.ImportedFromIB2 + 57.IBEditorWindowLastContentRect + 57.IBPluginDependency + 57.ImportedFromIB2 + 57.editorWindowContentRectSynchronizationRect + 58.IBPluginDependency + 58.ImportedFromIB2 + 72.IBPluginDependency + 72.ImportedFromIB2 + 73.IBPluginDependency + 73.ImportedFromIB2 + 74.IBPluginDependency + 74.ImportedFromIB2 + 75.IBPluginDependency + 75.ImportedFromIB2 + 77.IBPluginDependency + 77.ImportedFromIB2 + 78.IBPluginDependency + 78.ImportedFromIB2 + 79.IBPluginDependency + 79.ImportedFromIB2 + 80.IBPluginDependency + 80.ImportedFromIB2 + 81.IBPluginDependency + 81.ImportedFromIB2 + 81.editorWindowContentRectSynchronizationRect + 82.IBPluginDependency + 82.ImportedFromIB2 + 83.IBPluginDependency + 83.ImportedFromIB2 + 92.IBPluginDependency + 92.ImportedFromIB2 + + + YES + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{596, 852}, {216, 23}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{522, 812}, {146, 23}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{436, 809}, {64, 6}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{608, 612}, {275, 83}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{187, 434}, {243, 243}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{608, 612}, {167, 43}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{608, 612}, {241, 103}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{525, 802}, {197, 73}} + {{143, 285}, {478, 20}} + com.apple.InterfaceBuilder.CocoaPlugin + + {74, 862} + {{6, 978}, {478, 20}} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + {{475, 832}, {234, 43}} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{608, 612}, {215, 63}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{542, 408}, {480, 360}} + com.apple.InterfaceBuilder.CocoaPlugin + {{542, 408}, {480, 360}} + + {{33, 99}, {480, 360}} + {3.40282e+38, 3.40282e+38} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + {{437, 242}, {86, 43}} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + {{523, 2}, {178, 283}} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{155, 102}, {245, 183}} + com.apple.InterfaceBuilder.CocoaPlugin + + {{23, 794}, {245, 183}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{145, 474}, {199, 203}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + + + + YES + + + YES + + + + + YES + + + YES + + + + 475 + + + + YES + + AppController + NSObject + + YES + + YES + outlineView + theWindow + + + YES + id + NSWindow + + + + YES + + YES + outlineView + theWindow + + + YES + + outlineView + id + + + theWindow + NSWindow + + + + + IBUserSource + + + + + + 0 + IBCocoaFramework + + com.apple.InterfaceBuilder.CocoaPlugin.macosx + + + + com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 + + + YES + ../adsfsdf.xcodeproj + 3 + + YES + + YES + NSMenuCheckmark + NSMenuMixedState + + + YES + {9, 8} + {7, 2} + + + + diff --git a/Tests/Manual/CPOutlineViewCibTest/Resources/spinner.gif b/Tests/Manual/CPOutlineViewCibTest/Resources/spinner.gif new file mode 100644 index 0000000000000000000000000000000000000000..06dbc2bc21dddcf0e09b566d5b211aee89570f52 GIT binary patch literal 1849 zcma*odr(tX9tZHtz31lM+(&Y`A`Ou`NeG&R#DrIfV%?hng21vs6v>ooRQQFbk7E_K!V( z{?5!fpZWgIZ%*d6t%i*j24bL}AZUJm9)h6R*;%L4IWse3G#VWaN1#$zSSXcBhlYlH zJ|D}n{r&w2f+Qp)SS*&n?*G4}{}!h?td_mjU6Kad-rW*QwWYCUk7d^e+sjpZAn6kT z5rM;`{~_}-wm+L@%+E;JphLm}C3WzQAQD0wBoY|rOTQX{(@pp-WAA8Iw0HKl|15j) zhGh(SFWu#5zUCw^T!}C~eC}~?{xG-r7ugQC>taC+|L^xr&a%{#cgUOZXIM&v?)k^2 z1i5%0!U00wq)r4vlAwXBA_m5J5WNeuBm-XJQ5pG4GD%vc|K){+TJ{AkHqN@SJKczX zU}QRd9n*_bf^h94)6Ctv{CUfz_;qs#RDuQ$DR%y1&5G-a6rhf*4Y zl+UOD1*GE{GQ7vv;c-tTIMkz0ovO>9j%b5hpa@a*CBJ#W!0@ndSwF|%hMkdFtXiU) z`BEp+yhkt8ZY>tg&uyH@%^%K4jDrbA;et&vnnzZ3z22@e6<27z2Vk13kb7OtISyxv z(XoO-LNQCZe3lfzc%*pNqU<9T+p~teThOEB+~e&U0mC|zS{Q)dJZ)!^1f7L(zg*L> z*vSW%?dR~@@0(}x6-V^A`~ImD;)NaBUnP8;RH=bS2@pk`wp>>8r&jGjmGPy%1BW}v zoPo}ca$~bze@efc3kapuEVW1!%teOZT3j2Tw5=hjiAf02d}7dL0oFC%@=RXp5Ow#% z@a>+AM|YWt$n&e`>sB-32gBcuTi>R>*|8@lp`y6thc7ydyqDsuUn~YzZf|{-R@-3y zL#wx{Ii}xxL_csiW*LBn0-A$>zp4WOmkf6=ilrjlW?-l9+bCd7|i?*b5NTmy<<6NZ0T8$SN@mwdC2f z6jqK=N@bS@!=YSj%>h0}*4p+%0HbTIrE$w7UMT6+AZZ&DAo*qZAAi(OtNbIfl#Dw^ zJWeiCp~zi#&t6x}m9)O^eR4HiLV3QA<<0>HZ8%$^lrSE94Wb}=+MM^!b>n#5&-JQR zkr-CEu9C;_F*7DqDisulV6Pmg$nFL0TPn%~*m^-`Z3^BgU(sNpnx%nW(!eV9A&FvI zHL3X3lw8Wji^6=8KbQDE-e%b?svdFxxdh$8r97@7$ojeI`6AL8Ob6QC$qh&>ZWVDX1F{0vJnT%%mE;GveKWR%C} zM&4d;Jf3s9|HAA)yVUPo`Aq;0do#)uHSXi5*QF*)x@MVVHr+cN)uMZ__F|&Ta#p8d z53TOKtce!PJUuie8UWol-S(`c2nH?UGqJP{!4RR4u$LCfn)q-hj0^f=h(VYy)T6eN zhRO!ja-aDBTcgeyP(8Ua4IdiOog^*CQa?R(cP#9AgL9`j>EX-6Yf1lzX(!~``M1XC zNmM<4<6d~wWZ$Xrk0K}UteTrq@LBBk#MsjkK;pbuVhe)NI7(7Pf(l?lxC7=1Z7Pzl zMbS;nV4NI5_N{1$P)&XC)huOGQ+h^zpYUZfb*1n6>!`#*b3y52LGmi+<4sY5jyD#- zw&$d}DTguLAfnRtjrM*JfqtHqUu6rQoU=g%1E9xk%;)TDm^2<8n-0IhTsQFaek)MY}>PK4;nBk=ow4pF>vzkO& gna%Org-kgQCf=+BeMi^RbuY;YE~rTjend;_cdi8t>i_@% literal 0 HcmV?d00001 diff --git a/Tests/Manual/CPOutlineViewCibTest/index-debug.html b/Tests/Manual/CPOutlineViewCibTest/index-debug.html new file mode 100644 index 000000000..fc4af497d --- /dev/null +++ b/Tests/Manual/CPOutlineViewCibTest/index-debug.html @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + CPOutlineViewCibTest + + + + + + + + + + + + + + +
+
+ + + +
+
+ + + diff --git a/Tests/Manual/CPOutlineViewCibTest/index.html b/Tests/Manual/CPOutlineViewCibTest/index.html new file mode 100644 index 000000000..547dcc523 --- /dev/null +++ b/Tests/Manual/CPOutlineViewCibTest/index.html @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + CPOutlineViewCibTest + + + + + + + + + + + + +
+
+ + + +
+
+ + + diff --git a/Tests/Manual/CPOutlineViewCibTest/main.j b/Tests/Manual/CPOutlineViewCibTest/main.j new file mode 100644 index 000000000..a90de971f --- /dev/null +++ b/Tests/Manual/CPOutlineViewCibTest/main.j @@ -0,0 +1,18 @@ +/* + * AppController.j + * CPOutlineViewCibTest + * + * Created by cacaodev on January 14, 2011. + * Copyright 2011, Your Company All rights reserved. + */ + +@import +@import + +@import "AppController.j" + + +function main(args, namedArgs) +{ + CPApplicationMain(args, namedArgs); +} diff --git a/Tests/Manual/CPOutlineViewTest/AppController.j b/Tests/Manual/CPOutlineViewTest/AppController.j index a155d58fe..be9aaa1b9 100644 --- a/Tests/Manual/CPOutlineViewTest/AppController.j +++ b/Tests/Manual/CPOutlineViewTest/AppController.j @@ -180,13 +180,13 @@ CustomOutlineViewDragType = @"CustomOutlineViewDragType"; var column = [[CPTableColumn alloc] initWithIdentifier:@"One"]; [_outlineView addTableColumn:column]; - [_outlineView setOutlineTableColumn:column]; + //[_outlineView setOutlineTableColumn:column]; setTimeout(function(){ [column setWidth:200]; },0); [_outlineView addTableColumn:[[CPTableColumn alloc] initWithIdentifier:@"Two"]]; -[_outlineView addTableColumn:[[CPTableColumn alloc] initWithIdentifier:@"Three"]]; + [_outlineView addTableColumn:[[CPTableColumn alloc] initWithIdentifier:@"Three"]]; [_outlineView registerForDraggedTypes:[CustomOutlineViewDragType]]; diff --git a/Tools/nib2cib/NSOutlineView.j b/Tools/nib2cib/NSOutlineView.j index ba9b6a6b1..e0ddae889 100644 --- a/Tools/nib2cib/NSOutlineView.j +++ b/Tools/nib2cib/NSOutlineView.j @@ -36,7 +36,10 @@ else _outlineTableColumn = [[self tableColumns] objectAtIndex:0]; - _indentationPerLevel = [aCoder decodeFloatForKey:@"NSOutlineViewIndentationPerLevelKey"]; + if ([aCoder containsValueForKey:"NSOutlineViewIndentationPerLevelKey"]) + _indentationPerLevel = [aCoder decodeFloatForKey:@"NSOutlineViewIndentationPerLevelKey"]; + else + _indentationPerLevel = 16; _outlineViewDataSource = [aCoder decodeObjectForKey:@"NSDataSource"]; _outlineViewDelegate = [aCoder decodeObjectForKey:@"NSDelegate"]; From 32107ab650f285954379eb757a79d34da1947ca0 Mon Sep 17 00:00:00 2001 From: Stephen Ierodiaconou Date: Thu, 2 Dec 2010 17:30:44 +0200 Subject: [PATCH 03/17] Improvements to CPDecimalNumberHandler including docs and archiving/unarchiving and associated test. --- Foundation/CPDecimalNumber.j | 194 ++++++++++++------ Tests/Foundation/CPDecimalNumberHandlerTest.j | 36 +++- 2 files changed, 167 insertions(+), 63 deletions(-) diff --git a/Foundation/CPDecimalNumber.j b/Foundation/CPDecimalNumber.j index 3c09dee7d..44345e668 100644 --- a/Foundation/CPDecimalNumber.j +++ b/Foundation/CPDecimalNumber.j @@ -19,24 +19,17 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -@import "CPObject.j" @import "CPDecimal.j" @import "CPException.j" +@import "CPNumber.j" +@import "CPObject.j" -/* The protocol is defined as : Make sure CPDecimalNumberHandler implements these methods -@protocol CPDecimalNumberBehaviors -- (CPRoundingMode)roundingMode; -- (short)scale; -- (CPDecimalNumber)exceptionDuringOperation:(SEL)operation error:(CPCalculationError)error leftOperand:(CPDecimalNumber)leftOperand rightOperand:(CPDecimalNumber)rightOperand; -@end -*/ - -/*! @class CPDecimalNumberHandler +/*! + @class CPDecimalNumberHandler @ingroup foundation @brief Decimal floating point number exception and rounding behavior. This class is mutable. */ -// protocols this implements @implementation CPDecimalNumberHandler : CPObject { CPRoundingMode _roundingMode; @@ -50,12 +43,21 @@ // initializers - (id)init { - if (self = [super init]) - { - } + self = [super init]; + return self; } +/*! + Initialise a CPDecimalNumberHandler object with the parameters specified. This class handles the behaviour of the decimal number calculation engine on certain exception. + @param roundingMode the technique used for rounding (see \e CPRoundingMode values) + @param scale The number of digits after the decimal point that a number which is rounded should have + @param exact if true, a change in precision (i.e. rounding) will cause a \e CPDecimalNumberExactnessException exception to be raised, else they are ignored + @param overflow if true, a calculation overflow will cause a \e CPDecimalNumberOverflowException exception to be raised, else the maximum possible valid number is returned + @param underflow if true, a calculation underflow will cause a \e CPDecimalNumberUnderflowException exception to be raised, else the minimum possible valid number is returned + @param divideByZero if true, a divide by zero will cause a \e CPDecimalNumberDivideByZeroException exception to be raised, else a NotANumber (NaN) CPDecimal is returned + @return the reference to the receiver CPDecimalNumberHandler +*/ - (id)initWithRoundingMode:(CPRoundingMode)roundingMode scale:(short)scale raiseOnExactness:(BOOL)exact raiseOnOverflow:(BOOL)overflow raiseOnUnderflow:(BOOL)underflow raiseOnDivideByZero:(BOOL)divideByZero { if (self = [self init]) @@ -72,70 +74,90 @@ } // class methods +/*! + Create a new CPDecimalNumberHandler object with the parameters specified. This class handles the behaviour of the decimal number calculation engine on certain exception. + @param roundingMode the technique used for rounding (see \e CPRoundingMode values) + @param scale The number of digits after the decimal point that a number which is rounded should have + @param exact if true, a change in precision (i.e. rounding) will cause a \e CPDecimalNumberExactnessException exception to be raised, else they are ignored + @param overflow if true, a calculation overflow will cause a \e CPDecimalNumberOverflowException exception to be raised, else the maximum possible valid number is returned + @param underflow if true, a calculation underflow will cause a \e CPDecimalNumberUnderflowException exception to be raised, else the minimum possible valid number is returned + @param divideByZero if true, a divide by zero will cause a \e CPDecimalNumberDivideByZeroException exception to be raised, else a NotANumber (NaN) CPDecimal is returned + @return the reference to the receiver CPDecimalNumberHandler +*/ + (id)decimalNumberHandlerWithRoundingMode:(CPRoundingMode)roundingMode scale:(short)scale raiseOnExactness:(BOOL)exact raiseOnOverflow:(BOOL)overflow raiseOnUnderflow:(BOOL)underflow raiseOnDivideByZero:(BOOL)divideByZero { return [[self alloc] initWithRoundingMode:roundingMode scale:scale raiseOnExactness:exact raiseOnOverflow:overflow raiseOnUnderflow:underflow raiseOnDivideByZero:divideByZero]; } +/*! + Return the default Cappuccino CPDecimalNumberHandler object instance. This is created when the framework is initialised. + @return the default CPDecimalNumberHandler object reference with Rounding = \e CPRoundPlain, Scale = 0 and Raise on [exactness, overflow, underflow, divide by zero] = [no, yes, yes, yes] +*/ + (id)defaultDecimalNumberHandler { return _cappdefaultDcmHandler; } -// CPCoding methods -- (void)encodeWithCoder:(CPCoder)aCoder -{ -} +@end -- (id)initWithCoder:(CPCoder)aDecoder -{ -} +// CPDecimalNumberBehaviors protocol +@implementation CPDecimalNumberHandler (CPDecimalNumberBehaviors) -// CPDecimalNumberBehaviors methods +/*! + Returns the current rounding mode. One of \e CPRoundingMode enum: CPRoundPlain, CPRoundDown, CPRoundUp, CPRoundBankers. + @return the current rounding mode +*/ - (CPRoundingMode)roundingMode { return _roundingMode; } +/*! + Returns the number of digits allowed after the decimal point. + @return the current number of digits +*/ - (short)scale { return _scale; } -// FIXME: LOCALE? +/*! + This method is invoked by the framework when an exception occurs on a decimal operation. Depending on the specified behaviour of the CPDecimalNumberHandler this will throw + exceptions accordingly with formatted error messages. + @param operation the selector of the method of the operation being performed when the exception occured + @param error the actual error type. From the \e CPCalculationError enum: CPCalculationNoError, CPCalculationLossOfPrecision, CPCalculationOverflow, CPCalculationUnderflow, CPCalculationDivideByZero + @param leftOperand the CPDecimalNumber left-hand side operand used in the calculation that caused the exception + @param rightOperand the CPDecimalNumber right-hand side operand used in the calculation that caused the exception + @return if appropriate a CPDecimalNumber is returned (either the maxumum, minimum or NaN values), or nil +*/ - (CPDecimalNumber)exceptionDuringOperation:(SEL)operation error:(CPCalculationError)error leftOperand:(CPDecimalNumber)leftOperand rightOperand:(CPDecimalNumber)rightOperand { - // default behavior of throwing exceptions a la gnustep + // TODO: default behavior of throwing exceptions a la gnustep, check if same on Cocoa + // FIXME: locale? switch (error) { - case CPCalculationNoError: - return nil; - case CPCalculationOverflow: - if (_raiseOnOverflow) - [CPException raise:CPDecimalNumberOverflowException reason:("A CPDecimalNumber overflow has occured. (Left operand= '" + [leftOperand descriptionWithLocale:nil] + "' Right operand= '" + [rightOperand descriptionWithLocale:nil] + "' Selector= '" + operation + "')") ]; - else - return [CPDecimalNumber maximumDecimalNumber]; // there was overflow return largest possible val - break; - case CPCalculationUnderflow: - if (_raiseOnUnderflow) - [CPException raise:CPDecimalNumberUnderflowException reason:("A CPDecimalNumber underflow has occured. (Left operand= '" + [leftOperand descriptionWithLocale:nil] + "' Right operand= '" + [rightOperand descriptionWithLocale:nil] + "' Selector= '" + operation + "')") ]; - else - return [CPDecimalNumber minimumDecimalNumber]; // there was underflow, return smallest possible value - break; - case CPCalculationLossOfPrecision: - if (_raiseOnExactness) - [CPException raise:CPDecimalNumberExactnessException reason:("A CPDecimalNumber has been rounded off during a calculation. (Left operand= '" + [leftOperand descriptionWithLocale:nil] + "' Right operand= '" + [rightOperand descriptionWithLocale:nil] + "' Selector= '" + operation + "')") ]; - else - return nil; // Ignore. - break; - case CPCalculationDivideByZero: - if (_raiseOnDivideByZero) - [CPException raise:CPDecimalNumberDivideByZeroException reason:("A CPDecimalNumber divide by zero has occured. (Left operand= '" + [leftOperand descriptionWithLocale:nil] + "' Right operand= '" + [rightOperand descriptionWithLocale:nil] + "' Selector= '" + operation + "')") ]; - else - return [CPDecimalNumber notANumber]; // Div by zero returns NaN - break; - default: - [CPException raise:CPInvalidArgumentException reason:("An unknown CPDecimalNumber error has occured. (Left operand= '" + [leftOperand descriptionWithLocale:nil] + "' Right operand= '" + [rightOperand descriptionWithLocale:nil] + "' Selector= '" + operation + "')") ]; + case CPCalculationNoError: return nil; + case CPCalculationOverflow: if (_raiseOnOverflow) + [CPException raise:CPDecimalNumberOverflowException reason:("A CPDecimalNumber overflow has occured. (Left operand= '" + [leftOperand descriptionWithLocale:nil] + "' Right operand= '" + [rightOperand descriptionWithLocale:nil] + "' Selector= '" + operation + "')") ]; + else + return [CPDecimalNumber maximumDecimalNumber]; // there was overflow return largest possible val + break; + case CPCalculationUnderflow: if (_raiseOnUnderflow) + [CPException raise:CPDecimalNumberUnderflowException reason:("A CPDecimalNumber underflow has occured. (Left operand= '" + [leftOperand descriptionWithLocale:nil] + "' Right operand= '" + [rightOperand descriptionWithLocale:nil] + "' Selector= '" + operation + "')") ]; + else + return [CPDecimalNumber minimumDecimalNumber]; // there was underflow, return smallest possible value + break; + case CPCalculationLossOfPrecision: if (_raiseOnExactness) + [CPException raise:CPDecimalNumberExactnessException reason:("A CPDecimalNumber has been rounded off during a calculation. (Left operand= '" + [leftOperand descriptionWithLocale:nil] + "' Right operand= '" + [rightOperand descriptionWithLocale:nil] + "' Selector= '" + operation + "')") ]; + else + return nil; // Ignore. + break; + case CPCalculationDivideByZero: if (_raiseOnDivideByZero) + [CPException raise:CPDecimalNumberDivideByZeroException reason:("A CPDecimalNumber divide by zero has occured. (Left operand= '" + [leftOperand descriptionWithLocale:nil] + "' Right operand= '" + [rightOperand descriptionWithLocale:nil] + "' Selector= '" + operation + "')") ]; + else + return [CPDecimalNumber notANumber]; // Div by zero returns NaN + break; + default: [CPException raise:CPInvalidArgumentException reason:("An unknown CPDecimalNumber error has occured. (Left operand= '" + [leftOperand descriptionWithLocale:nil] + "' Right operand= '" + [rightOperand descriptionWithLocale:nil] + "' Selector= '" + operation + "')") ]; } return nil; @@ -143,6 +165,51 @@ @end +// CPCoding category +var CPDecimalNumberHandlerRoundingModeKey = @"CPDecimalNumberHandlerRoundingModeKey", + CPDecimalNumberHandlerScaleKey = @"CPDecimalNumberHandlerScaleKey", + CPDecimalNumberHandlerRaiseOnExactKey = @"CPDecimalNumberHandlerRaiseOnExactKey", + CPDecimalNumberHandlerRaiseOnOverflowKey = @"CPDecimalNumberHandlerRaiseOnOverflowKey", + CPDecimalNumberHandlerRaiseOnUnderflowKey = @"CPDecimalNumberHandlerRaiseOnUnderflowKey", + CPDecimalNumberHandlerDivideByZeroKey = @"CPDecimalNumberHandlerDivideByZeroKey"; + +@implementation CPDecimalNumberHandler (CPCoding) + +/*! + Called by CPCoder's \e decodeObject: to initialise the object with an archived one. + @param aCoder a \c CPCoder instance +*/ +- (id)initWithCoder:(CPCoder)aCoder +{ + if (self) + { + [self initWithRoundingMode:[aCoder decodeIntForKey:CPDecimalNumberHandlerRoundingModeKey] + scale:[aCoder decodeIntForKey:CPDecimalNumberHandlerScaleKey] + raiseOnExactness:[aCoder decodeBoolForKey:CPDecimalNumberHandlerRaiseOnExactKey] + raiseOnOverflow:[aCoder decodeBoolForKey:CPDecimalNumberHandlerRaiseOnOverflowKey] + raiseOnUnderflow:[aCoder decodeBoolForKey:CPDecimalNumberHandlerRaiseOnUnderflowKey] + raiseOnDivideByZero:[aCoder decodeBoolForKey:CPDecimalNumberHandlerDivideByZeroKey]]; + } + + return self; +} + +/*! + Called by CPCoder's \e encodeObject: to archive the object instance. + @param aCoder a \c CPCoder instance +*/ +- (void)encodeWithCoder:(CPCoder)aCoder +{ + [aCoder encodeInt:[self roundingMode] forKey:CPDecimalNumberHandlerRoundingModeKey]; + [aCoder encodeInt:[self scale] forKey:CPDecimalNumberHandlerScaleKey]; + [aCoder encodeBool:_raiseOnExactness forKey:CPDecimalNumberHandlerRaiseOnExactKey]; + [aCoder encodeBool:_raiseOnOverflow forKey:CPDecimalNumberHandlerRaiseOnOverflowKey]; + [aCoder encodeBool:_raiseOnUnderflow forKey:CPDecimalNumberHandlerRaiseOnUnderflowKey]; + [aCoder encodeBool:_raiseOnDivideByZero forKey:CPDecimalNumberHandlerDivideByZeroKey]; +} + +@end + // create the default global behavior class _cappdefaultDcmHandler = [CPDecimalNumberHandler decimalNumberHandlerWithRoundingMode:CPRoundPlain scale:0 raiseOnExactness:NO raiseOnOverflow:YES raiseOnUnderflow:YES raiseOnDivideByZero:YES]; @@ -150,16 +217,15 @@ _cappdefaultDcmHandler = [CPDecimalNumberHandler decimalNumberHandlerWithRoundin // CPNumber is toll free bridged and anyway its methods will need to be // overrided here as CPDecimalNumber is not interchangable with CPNumbers. -/*! @class CPDecimalNumber +/*! + @class CPDecimalNumber @ingroup foundation @brief Decimal floating point number - This class represents a decimal floating point number and the relavent - mathematical operations to go with it. + This class represents a decimal floating point number and the relavent mathematical operations to go with it. + The default number handler can be accessed at [CPDecimalNumberHandler +defaultDecimalNumberHandler] This class is mutable. */ - - @implementation CPDecimalNumber : CPNumber { CPDecimal _data; @@ -173,8 +239,8 @@ _cappdefaultDcmHandler = [CPDecimalNumberHandler decimalNumberHandlerWithRoundin // initializers - (id)init { - if (self = [super init]) - {} + self = [super init]; + return self; } @@ -191,7 +257,15 @@ _cappdefaultDcmHandler = [CPDecimalNumberHandler decimalNumberHandlerWithRoundin return self; } -// NOTE: long long doesnt exist in JS, so this is actually a double +/*! + Initialise a CPDecimalNumber object with the given mantissa and exponent. + Note that since 'long long' doesn't exist in JS the mantissa is smaller + than possible in Cocoa. + @param mantissa the mantissa of the decimal number + @param exponent the exponent of the number + @param flag true if number is negative + @return the reference to the receiver CPDecimalNumber +*/ - (id)initWithMantissa:(unsigned long long)mantissa exponent:(short)exponent isNegative:(BOOL)flag { if (self = [self init]) diff --git a/Tests/Foundation/CPDecimalNumberHandlerTest.j b/Tests/Foundation/CPDecimalNumberHandlerTest.j index b1b59ff01..88a15a9e2 100644 --- a/Tests/Foundation/CPDecimalNumberHandlerTest.j +++ b/Tests/Foundation/CPDecimalNumberHandlerTest.j @@ -19,8 +19,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -@import @import +@import +@import +@import @implementation CPDecimalNumberHandlerTest : OJTestCase @@ -72,8 +74,8 @@ var h1 = [CPDecimalNumberHandler decimalNumberHandlerWithRoundingMode:CPRoundDown scale:0 raiseOnExactness:NO raiseOnOverflow:NO raiseOnUnderflow:NO raiseOnDivideByZero:NO]; [self assertTrue:h1 message:"T1 exceptionDuringOperation: no alloc"]; - var a = [CPDecimalNumber decimalNumberWithString:@"100"]; - var b = [CPDecimalNumber decimalNumberWithString:@"100"]; + var a = [CPDecimalNumber decimalNumberWithString:@"100"], + b = [CPDecimalNumber decimalNumberWithString:@"100"]; // no throw first try { @@ -146,4 +148,32 @@ } } +- (void)testEncoding +{ + var handler = [CPDecimalNumberHandler decimalNumberHandlerWithRoundingMode:CPRoundDown scale:3 raiseOnExactness:NO raiseOnOverflow:NO raiseOnUnderflow:YES raiseOnDivideByZero:NO], + encoded = [CPKeyedArchiver archivedDataWithRootObject:handler], + decoded = [CPKeyedUnarchiver unarchiveObjectWithData:encoded]; + + [self assert:[handler roundingMode] equals:[decoded roundingMode]]; + [self assert:[handler scale] equals:[decoded scale]]; + + try { + [decoded exceptionDuringOperation:nil error:CPCalculationDivideByZero leftOperand:CPDecimalMakeZero() rightOperand:CPDecimalMakeZero()]; + } + catch (e) + { + [self fail:"Should not have thrown a divide by zero exception"]; + } + + try { + [decoded exceptionDuringOperation:nil error:CPCalculationUnderflow leftOperand:CPDecimalMakeZero() rightOperand:CPDecimalMakeZero()]; + [self fail:"Should have thrown an underflow exception"]; + } + catch (e) + { + if ((e.isa) && [e name] == AssertionFailedError) + throw e; + } +} + @end From 5a0cfc1595cba3fa1da9026b35e2aa893495a9b7 Mon Sep 17 00:00:00 2001 From: Stephen Ierodiaconou Date: Thu, 2 Dec 2010 19:33:34 +0200 Subject: [PATCH 04/17] Make default number hanler file global only and Improvements and optimisations for CPDecimalNumber --- Foundation/CPDecimal.j | 21 ++++++ Foundation/CPDecimalNumber.j | 72 +++++++------------ Tests/Foundation/CPDecimalNumberHandlerTest.j | 2 +- Tests/Foundation/CPDecimalNumberTest.j | 2 +- 4 files changed, 49 insertions(+), 48 deletions(-) diff --git a/Foundation/CPDecimal.j b/Foundation/CPDecimal.j index 6ff74eb81..75a68047c 100644 --- a/Foundation/CPDecimal.j +++ b/Foundation/CPDecimal.j @@ -239,6 +239,27 @@ function CPDecimalMakeNaN() return d; } +// private methods +function _CPDecimalMakeMaximum() +{ + var s = @"", + i = 0; + for (; i < CPDecimalMaxDigits; i++) + s += "9"; + s += "e" + CPDecimalMaxExponent; + return CPDecimalMakeWithString(s); +} + +function _CPDecimalMakeMinimum() +{ + var s = @"-", + i = 0; + for (; i < CPDecimalMaxDigits; i++) + s += "9"; + s += "e" + CPDecimalMinExponent; + return CPDecimalMakeWithString(s); +} + /*! @ingroup foundation Checks to see if a CPDecimal is zero. Can handle uncompacted strings. diff --git a/Foundation/CPDecimalNumber.j b/Foundation/CPDecimalNumber.j index 44345e668..f43eb4ff5 100644 --- a/Foundation/CPDecimalNumber.j +++ b/Foundation/CPDecimalNumber.j @@ -95,7 +95,7 @@ */ + (id)defaultDecimalNumberHandler { - return _cappdefaultDcmHandler; + return CPDefaultDcmHandler; } @end @@ -166,12 +166,12 @@ @end // CPCoding category -var CPDecimalNumberHandlerRoundingModeKey = @"CPDecimalNumberHandlerRoundingModeKey", - CPDecimalNumberHandlerScaleKey = @"CPDecimalNumberHandlerScaleKey", - CPDecimalNumberHandlerRaiseOnExactKey = @"CPDecimalNumberHandlerRaiseOnExactKey", - CPDecimalNumberHandlerRaiseOnOverflowKey = @"CPDecimalNumberHandlerRaiseOnOverflowKey", - CPDecimalNumberHandlerRaiseOnUnderflowKey = @"CPDecimalNumberHandlerRaiseOnUnderflowKey", - CPDecimalNumberHandlerDivideByZeroKey = @"CPDecimalNumberHandlerDivideByZeroKey"; +var CPDecimalNumberHandlerRoundingModeKey = @"CPDecimalNumberHandlerRoundingModeKey", + CPDecimalNumberHandlerScaleKey = @"CPDecimalNumberHandlerScaleKey", + CPDecimalNumberHandlerRaiseOnExactKey = @"CPDecimalNumberHandlerRaiseOnExactKey", + CPDecimalNumberHandlerRaiseOnOverflowKey = @"CPDecimalNumberHandlerRaiseOnOverflowKey", + CPDecimalNumberHandlerRaiseOnUnderflowKey = @"CPDecimalNumberHandlerRaiseOnUnderflowKey", + CPDecimalNumberHandlerDivideByZeroKey = @"CPDecimalNumberHandlerDivideByZeroKey"; @implementation CPDecimalNumberHandler (CPCoding) @@ -211,11 +211,7 @@ var CPDecimalNumberHandlerRoundingModeKey = @"CPDecimalNumberHandlerRoundingMode @end // create the default global behavior class -_cappdefaultDcmHandler = [CPDecimalNumberHandler decimalNumberHandlerWithRoundingMode:CPRoundPlain scale:0 raiseOnExactness:NO raiseOnOverflow:YES raiseOnUnderflow:YES raiseOnDivideByZero:YES]; - -// After discussing with boucher about this it makes sense not to inherit, as -// CPNumber is toll free bridged and anyway its methods will need to be -// overrided here as CPDecimalNumber is not interchangable with CPNumbers. +var CPDefaultDcmHandler = [CPDecimalNumberHandler decimalNumberHandlerWithRoundingMode:CPRoundPlain scale:0 raiseOnExactness:NO raiseOnOverflow:YES raiseOnUnderflow:YES raiseOnDivideByZero:YES]; /*! @class CPDecimalNumber @@ -231,6 +227,7 @@ _cappdefaultDcmHandler = [CPDecimalNumberHandler decimalNumberHandlerWithRoundin CPDecimal _data; } +// overriding alloc means CPDecimalNumbers are not toll free bridged + (id)alloc { return class_createInstance(self); @@ -281,14 +278,7 @@ _cappdefaultDcmHandler = [CPDecimalNumberHandler decimalNumberHandlerWithRoundin - (id)initWithString:(CPString)numberValue { - if (self = [self init]) - { - _data = CPDecimalMakeWithString(numberValue, nil); - if (_data === nil) - [CPException raise:CPInvalidArgumentException reason:"A CPDecimalNumber has been passed an invalid string. '" + numberValue + "'"]; - } - - return self; + return [self initWithString:numberValue locale:nil]; } - (id)initWithString:(CPString)numberValue locale:(CPDictionary)locale @@ -326,27 +316,17 @@ _cappdefaultDcmHandler = [CPDecimalNumberHandler decimalNumberHandlerWithRoundin + (id)defaultBehavior { - return _cappdefaultDcmHandler; + return CPDefaultDcmHandler; } + (CPDecimalNumber)maximumDecimalNumber { - var s = @"", - i = 0; - for (;i < CPDecimalMaxDigits; i++) - s += "9"; - s += "e" + CPDecimalMaxExponent; - return [[self alloc] initWithString:s]; + return [[self alloc] initWithDecimal:_CPDecimalMakeMaximum()]; } + (CPDecimalNumber)minimumDecimalNumber { - var s = @"-", - i = 0; - for (;i < CPDecimalMaxDigits; i++) - s += "9"; - s += "e" + CPDecimalMinExponent; - return [[self alloc] initWithString:s]; + return [[self alloc] initWithDecimal:_CPDecimalMakeMinimum()]; } + (CPDecimalNumber)notANumber @@ -354,25 +334,25 @@ _cappdefaultDcmHandler = [CPDecimalNumberHandler decimalNumberHandlerWithRoundin return [[self alloc] initWithDecimal:CPDecimalMakeNaN()]; } ++ (CPDecimalNumber)zero +{ + return [[self alloc] initWithDecimal:CPDecimalMakeZero()]; +} + + (CPDecimalNumber)one { - return [[self alloc] initWithString:"1"]; + return [[self alloc] initWithDecimal:CPDecimalMakeOne()]; } + (void)setDefaultBehavior:(id )behavior { - _cappdefaultDcmHandler = behavior; -} - -+ (CPDecimalNumber)zero -{ - return [[self alloc] initWithString:"0"]; + CPDefaultDcmHandler = behavior; } // instance methods - (CPDecimalNumber)decimalNumberByAdding:(CPDecimalNumber)decimalNumber { - return [self decimalNumberByAdding:decimalNumber withBehavior:_cappdefaultDcmHandler]; + return [self decimalNumberByAdding:decimalNumber withBehavior:CPDefaultDcmHandler]; } - (CPDecimalNumber)decimalNumberByAdding:(CPDecimalNumber)decimalNumber withBehavior:(id )behavior @@ -394,7 +374,7 @@ _cappdefaultDcmHandler = [CPDecimalNumberHandler decimalNumberHandlerWithRoundin - (CPDecimalNumber)decimalNumberBySubtracting:(CPDecimalNumber)decimalNumber { - return [self decimalNumberBySubtracting:decimalNumber withBehavior:_cappdefaultDcmHandler]; + return [self decimalNumberBySubtracting:decimalNumber withBehavior:CPDefaultDcmHandler]; } - (CPDecimalNumber)decimalNumberBySubtracting:(CPDecimalNumber)decimalNumber withBehavior:(id )behavior @@ -414,7 +394,7 @@ _cappdefaultDcmHandler = [CPDecimalNumberHandler decimalNumberHandlerWithRoundin - (CPDecimalNumber)decimalNumberByDividingBy:(CPDecimalNumber)decimalNumber { - return [self decimalNumberByDividingBy:decimalNumber withBehavior:_cappdefaultDcmHandler]; + return [self decimalNumberByDividingBy:decimalNumber withBehavior:CPDefaultDcmHandler]; } - (CPDecimalNumber)decimalNumberByDividingBy:(CPDecimalNumber)decimalNumber withBehavior:(id )behavior @@ -434,7 +414,7 @@ _cappdefaultDcmHandler = [CPDecimalNumberHandler decimalNumberHandlerWithRoundin - (CPDecimalNumber)decimalNumberByMultiplyingBy:(CPDecimalNumber)decimalNumber { - return [self decimalNumberByMultiplyingBy:decimalNumber withBehavior:_cappdefaultDcmHandler]; + return [self decimalNumberByMultiplyingBy:decimalNumber withBehavior:CPDefaultDcmHandler]; } - (CPDecimalNumber)decimalNumberByMultiplyingBy:(CPDecimalNumber)decimalNumber withBehavior:(id )behavior @@ -454,7 +434,7 @@ _cappdefaultDcmHandler = [CPDecimalNumberHandler decimalNumberHandlerWithRoundin - (CPDecimalNumber)decimalNumberByMultiplyingByPowerOf10:(short)power { - return [self decimalNumberByMultiplyingByPowerOf10:power withBehavior:_cappdefaultDcmHandler]; + return [self decimalNumberByMultiplyingByPowerOf10:power withBehavior:CPDefaultDcmHandler]; } - (CPDecimalNumber)decimalNumberByMultiplyingByPowerOf10:(short)power withBehavior:(id )behavior @@ -474,7 +454,7 @@ _cappdefaultDcmHandler = [CPDecimalNumberHandler decimalNumberHandlerWithRoundin - (CPDecimalNumber)decimalNumberByRaisingToPower:(unsigned)power { - return [self decimalNumberByRaisingToPower:power withBehavior:_cappdefaultDcmHandler]; + return [self decimalNumberByRaisingToPower:power withBehavior:CPDefaultDcmHandler]; } - (CPDecimalNumber)decimalNumberByRaisingToPower:(unsigned)power withBehavior:(id )behavior diff --git a/Tests/Foundation/CPDecimalNumberHandlerTest.j b/Tests/Foundation/CPDecimalNumberHandlerTest.j index 88a15a9e2..d018cdd35 100644 --- a/Tests/Foundation/CPDecimalNumberHandlerTest.j +++ b/Tests/Foundation/CPDecimalNumberHandlerTest.j @@ -48,7 +48,7 @@ - (void)testdefaultDecimalNumberHandler { - [self assert:_cappdefaultDcmHandler equals:[CPDecimalNumberHandler defaultDecimalNumberHandler] message:"T1 defaultDecimalNumberHandler returned different handler than the current default"]; + [self assertTrue:[CPDecimalNumberHandler defaultDecimalNumberHandler] message:"T1 defaultDecimalNumberHandler returned nothing"]; } - (void)testroundingMode diff --git a/Tests/Foundation/CPDecimalNumberTest.j b/Tests/Foundation/CPDecimalNumberTest.j index 5ceff6211..b57de77b1 100644 --- a/Tests/Foundation/CPDecimalNumberTest.j +++ b/Tests/Foundation/CPDecimalNumberTest.j @@ -93,7 +93,7 @@ [self assert:NO equals:dcm._isNegative message:"decimalNumberWithMantissa:exponent:isNegative: - sign"]; // Def behavior - [self assert:[CPDecimalNumber defaultBehavior] equals:_cappdefaultDcmHandler message:"defaultBehavior: - returned different object"]; + [self assertTrue:[CPDecimalNumber defaultBehavior] message:"defaultBehavior: - returned nothing"]; [CPDecimalNumber setDefaultBehavior:_dcmnhWithExactness]; [self assertTrue:[CPDecimalNumber defaultBehavior]._raiseOnExactness message:"setDefaultBehavior: - new behavior not set"]; From 6a6256bdb49c9de63c77f814eb47e10134a83ad5 Mon Sep 17 00:00:00 2001 From: Stephen Ierodiaconou Date: Sat, 15 Jan 2011 14:15:31 +0200 Subject: [PATCH 05/17] CPCoding support for CPDecimalNumber and test --- Foundation/CPDecimalNumber.j | 44 ++++++++++++++++++++++++++ Tests/Foundation/CPDecimalNumberTest.j | 14 ++++++++ 2 files changed, 58 insertions(+) diff --git a/Foundation/CPDecimalNumber.j b/Foundation/CPDecimalNumber.j index f43eb4ff5..692c37742 100644 --- a/Foundation/CPDecimalNumber.j +++ b/Foundation/CPDecimalNumber.j @@ -754,3 +754,47 @@ var CPDefaultDcmHandler = [CPDecimalNumberHandler decimalNumberHandlerWithRoundi } @end + +// CPCoding category +var CPDecimalNumberDecimalExponent = @"CPDecimalNumberDecimalExponent", + CPDecimalNumberDecimalIsNegative = @"CPDecimalNumberDecimalIsNegative", + CPDecimalNumberDecimalIsCompact = @"CPDecimalNumberDecimalIsCompact", + CPDecimalNumberDecimalIsNaN = @"CPDecimalNumberDecimalIsNaN", + CPDecimalNumberDecimalMantissa = @"CPDecimalNumberDecimalMantissa"; + +@implementation CPDecimalNumber (CPCoding) + +/*! + Called by CPCoder's \e decodeObject: to initialise the object with an archived one. + @param aCoder a \c CPCoder instance +*/ +- (id)initWithCoder:(CPCoder)aCoder +{ + if (self) + { + var dcm = CPDecimalMakeZero(); + dcm._exponent = [aCoder decodeIntForKey:CPDecimalNumberDecimalExponent]; + dcm._isNegative = [aCoder decodeBoolForKey:CPDecimalNumberDecimalIsNegative]; + dcm._isCompact = [aCoder decodeBoolForKey:CPDecimalNumberDecimalIsCompact]; + dcm._isNaN = [aCoder decodeBoolForKey:CPDecimalNumberDecimalIsNaN]; + dcm._mantissa = [aCoder decodeObjectForKey:CPDecimalNumberDecimalMantissa]; + [self initWithDecimal:dcm]; + } + + return self; +} + +/*! + Called by CPCoder's \e encodeObject: to archive the object instance. + @param aCoder a \c CPCoder instance +*/ +- (void)encodeWithCoder:(CPCoder)aCoder +{ + [aCoder encodeInt:_data._exponent forKey:CPDecimalNumberDecimalExponent]; + [aCoder encodeBool:_data._isNegative forKey:CPDecimalNumberDecimalIsNegative]; + [aCoder encodeBool:_data._isCompact forKey:CPDecimalNumberDecimalIsCompact]; + [aCoder encodeBool:_data._isNaN forKey:CPDecimalNumberDecimalIsNaN]; + [aCoder encodeObject:_data._mantissa forKey:CPDecimalNumberDecimalMantissa]; +} + +@end diff --git a/Tests/Foundation/CPDecimalNumberTest.j b/Tests/Foundation/CPDecimalNumberTest.j index b57de77b1..844a1cecf 100644 --- a/Tests/Foundation/CPDecimalNumberTest.j +++ b/Tests/Foundation/CPDecimalNumberTest.j @@ -532,4 +532,18 @@ [self assert:"82346.2341144" equals:[dcmn descriptionWithLocale:nil] message:"descriptionWithLocale: - large number"]; } + +- (void)testEncoding +{ + var number = [CPDecimalNumber decimalNumberWithString:@"-1.233e24"], + encoded = [CPKeyedArchiver archivedDataWithRootObject:number], + decoded = [CPKeyedUnarchiver unarchiveObjectWithData:encoded]; + + [self assert:21 equals:decoded._data._exponent message:"exponent not unarchived correctly"]; + [self assert:[1,2,3,3] equals:decoded._data._mantissa message:"mantissa not unarchived correctly"]; + [self assert:YES equals:decoded._data._isNegative message:"sign not unarchived correctly"]; + [self assert:NO equals:decoded._data._isNaN message:"isNaN not unarchived correctly"]; + [self assert:YES equals:decoded._data._isCompact message:"isCompact not unarchived correctly"]; +} + @end From fc746db70f3be9b09bbac1a002d49fa124a21673 Mon Sep 17 00:00:00 2001 From: Stephen Ierodiaconou Date: Sat, 15 Jan 2011 16:12:06 +0200 Subject: [PATCH 06/17] Cocoa compatible constructors for CPDecimals --- Foundation/CPDecimal.j | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Foundation/CPDecimal.j b/Foundation/CPDecimal.j index 75a68047c..baaf5b355 100644 --- a/Foundation/CPDecimal.j +++ b/Foundation/CPDecimal.j @@ -102,7 +102,7 @@ CPDecimal format: function CPDecimalMakeWithString(string, locale) { if (!string) - return CPDecimalMakeZero(); + return CPDecimalMakeNaN(); // Regexp solution as found in JSON spec, with working regexp (I added groupings) // Test here: http://www.regexplanet.com/simple/index.html @@ -116,7 +116,7 @@ function CPDecimalMakeWithString(string, locale) // If yes simply add '?' after integer part group, ie ([+\-]?)((?:0|[1-9]\d*)?) var matches = string.match(/^([+\-]?)((?:0|[1-9]\d*))(?:\.(\d*))?(?:[eE]([+\-]?)(\d+))?$/); if (!matches) - return nil; + return CPDecimalMakeNaN(); var ds = matches[1], intpart = matches[2], @@ -143,7 +143,7 @@ function CPDecimalMakeWithString(string, locale) } if (exponent > CPDecimalMaxExponent || exponent < CPDecimalMinExponent) - return nil; + return CPDecimalMakeNaN(); // Representation internally starts at most significant digit var m = [CPArray array], @@ -190,7 +190,7 @@ function CPDecimalMakeWithParts(mantissa, exponent) [m addObject: 0]; if (exponent > CPDecimalMaxExponent || exponent < CPDecimalMinExponent) - return nil; + return CPDecimalMakeNaN(); // remaining digits are disposed of via truncation while ((mantissa > 0) && ([m count] < CPDecimalMaxDigits)) // count selector here could be optimised away @@ -256,7 +256,7 @@ function _CPDecimalMakeMinimum() i = 0; for (; i < CPDecimalMaxDigits; i++) s += "9"; - s += "e" + CPDecimalMinExponent; + s += "e" + CPDecimalMaxExponent; return CPDecimalMakeWithString(s); } From 27ad98e1600727cfd8669fed0b4d5bfeed81d63d Mon Sep 17 00:00:00 2001 From: Stephen Ierodiaconou Date: Sat, 15 Jan 2011 16:18:01 +0200 Subject: [PATCH 07/17] Initialiser fixes and docs Fix tests for new initialisers --- Foundation/CPDecimalNumber.j | 74 +++++++++++++++++++++--- Tests/Foundation/CPDecimalNumberTest.j | 79 +++++++------------------- Tests/Foundation/CPDecimalTest.j | 57 ++++++++++++------- 3 files changed, 123 insertions(+), 87 deletions(-) diff --git a/Foundation/CPDecimalNumber.j b/Foundation/CPDecimalNumber.j index 692c37742..8773fe5d1 100644 --- a/Foundation/CPDecimalNumber.j +++ b/Foundation/CPDecimalNumber.j @@ -234,11 +234,13 @@ var CPDefaultDcmHandler = [CPDecimalNumberHandler decimalNumberHandlerWithRoundi } // initializers +/*! + Initialise a CPDecimalNumber object with NaN + @return the reference to the receiver CPDecimalNumber +*/ - (id)init { - self = [super init]; - - return self; + return [self initWithDecimal:CPDecimalMakeNaN()]; } /*! @@ -248,7 +250,7 @@ var CPDefaultDcmHandler = [CPDecimalNumberHandler decimalNumberHandlerWithRoundi */ - (id)initWithDecimal:(CPDecimal)dcm { - if (self = [self init]) + if (self = [super init]) _data = CPDecimalCopy(dcm); return self; @@ -256,8 +258,11 @@ var CPDefaultDcmHandler = [CPDecimalNumberHandler decimalNumberHandlerWithRoundi /*! Initialise a CPDecimalNumber object with the given mantissa and exponent. - Note that since 'long long' doesn't exist in JS the mantissa is smaller - than possible in Cocoa. + Note: that since 'long long' doesn't exist in JS the mantissa is smaller + than possible in Cocoa and can thus not create the full number range + possible for a CPDecimal. Also note that at extreme cases where overflow + or truncation will occur to the parameters in Cocoa this method produces + different results to its Cocoa counterpart. @param mantissa the mantissa of the decimal number @param exponent the exponent of the number @param flag true if number is negative @@ -276,39 +281,82 @@ var CPDefaultDcmHandler = [CPDecimalNumberHandler decimalNumberHandlerWithRoundi return self; } +/*! + Initialise a CPDecimalNumber with a string. If the string is badly formed + or outside of the acceptable range of a CPDecimal then the number is + initialised to NaN. + @param numberValue the string to parse. + @return the reference to the receiver CPDecimalNumber +*/ - (id)initWithString:(CPString)numberValue { return [self initWithString:numberValue locale:nil]; } +/*! + Initialise a CPDecimalNumber with a string using the given locale. If the + string is badly formed or outside of the acceptable range of a CPDecimal + then the number is initialised to NaN. NOTE: Locales are currently + not supported. + @param numberValue the string to parse + @param locale the CPLocale object to use when parsing the number string + @return the reference to the receiver CPDecimalNumber +*/ - (id)initWithString:(CPString)numberValue locale:(CPDictionary)locale { if (self = [self init]) { - _data = CPDecimalMakeWithString(numberValue,locale); - if (!_data) - [CPException raise:CPInvalidArgumentException reason:"A CPDecimalNumber has been passed an invalid string. '" + numberValue + "'"]; + _data = CPDecimalMakeWithString(numberValue, locale); } return self; } // class methods +/*! + Return a new CPDecimalNumber object with the contents of a CPDecimal object + @param dcm the CPDecimal object to copy + @return the new CPDecimalNumber object +*/ + (CPDecimalNumber)decimalNumberWithDecimal:(CPDecimal)dcm { return [[self alloc] initWithDecimal:dcm]; } +/*! + Create a new CPDecimalNumber object with the given mantissa and exponent. + See \c -initWithMantissa:exponent:isNegative: for some extra notes. + @param mantissa the mantissa of the decimal number + @param exponent the exponent of the number + @param flag true if number is negative + @return the new CPDecimalNumber object +*/ + (CPDecimalNumber)decimalNumberWithMantissa:(unsigned long long)mantissa exponent:(short)exponent isNegative:(BOOL)flag { return [[self alloc] initWithMantissa:mantissa exponent:exponent isNegative:flag]; } +/*! + Create a new CPDecimalNumber with a string. If the string is badly formed + or outside of the acceptable range of a CPDecimal then the number is + initialised to NaN. + @param numberValue the string to parse. + @return the new CPDecimalNumber object +*/ + (CPDecimalNumber)decimalNumberWithString:(CPString)numberValue { return [[self alloc] initWithString:numberValue]; } +/*! + Create a new CPDecimalNumber with a string using the given locale. If the + string is badly formed or outside of the acceptable range of a CPDecimal + then the number is initialised to NaN. NOTE: Locales are currently + not supported. + @param numberValue the string to parse + @param locale the CPLocale object to use when parsing the number string + @return the new CPDecimalNumber object +*/ + (CPDecimalNumber)decimalNumberWithString:(CPString)numberValue locale:(CPDictionary)locale { return [[self alloc] initWithString:numberValue locale:locale]; @@ -319,11 +367,19 @@ var CPDefaultDcmHandler = [CPDecimalNumberHandler decimalNumberHandlerWithRoundi return CPDefaultDcmHandler; } +/*! + 340282366920938463463374607431768211455e127 + 99999999999999999999999999999999999999e127 +*/ + (CPDecimalNumber)maximumDecimalNumber { return [[self alloc] initWithDecimal:_CPDecimalMakeMaximum()]; } +/*! + -340282366920938463463374607431768211455e127 + -99999999999999999999999999999999999999e127 +*/ + (CPDecimalNumber)minimumDecimalNumber { return [[self alloc] initWithDecimal:_CPDecimalMakeMinimum()]; diff --git a/Tests/Foundation/CPDecimalNumberTest.j b/Tests/Foundation/CPDecimalNumberTest.j index 844a1cecf..83b768086 100644 --- a/Tests/Foundation/CPDecimalNumberTest.j +++ b/Tests/Foundation/CPDecimalNumberTest.j @@ -108,7 +108,7 @@ dcmn = [CPDecimalNumber minimumDecimalNumber]; dcm = [dcmn decimalValue]; - [self assert:CPDecimalMinExponent equals:dcm._exponent message:"minimumDecimalNumber: - exponent"]; + [self assert:CPDecimalMaxExponent equals:dcm._exponent message:"minimumDecimalNumber: - exponent"]; [self assert:[9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9] equals:dcm._mantissa message:"minimumDecimalNumber: - mantissa"]; [self assert:YES equals:dcm._isNegative message:"minimumDecimalNumber: - sign"]; @@ -139,63 +139,26 @@ dcm = [dcmn boolValue]; [self assert:true equals:dcm message:"boolValue: - should be true"]; - // exceptions - try { - dcmn = [[CPDecimalNumber alloc] initWithString:@"111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"]; - [self fail:"initWithString: TEX1: overflow from string"]; - } catch (e) - { - if ((e.isa) && [e name] == AssertionFailedError) - throw e; - } - try { - dcmn = [[CPDecimalNumber alloc] initWithString:@"foo"]; - [self fail:"initWithString: TEX2: invalid string"]; - } catch (e) - { - if ((e.isa) && [e name] == AssertionFailedError) - throw e; - } - try { - dcmn = [[CPDecimalNumber alloc] initWithString:@".123"]; - [self fail:"initWithString: TEX3: invalid string"]; - } catch (e) - { - if ((e.isa) && [e name] == AssertionFailedError) - throw e; - } - try { - dcmn = [[CPDecimalNumber alloc] initWithString:@"-.123"]; - [self fail:"initWithString: TEX4: invalid string"]; - } catch (e) - { - if ((e.isa) && [e name] == AssertionFailedError) - throw e; - } - try { - dcmn = [[CPDecimalNumber alloc] initWithString:@"0123"]; - [self fail:"initWithString: TEX5: invalid string"]; - } catch (e) - { - if ((e.isa) && [e name] == AssertionFailedError) - throw e; - } - try { - dcmn = [[CPDecimalNumber alloc] initWithString:@"1e200"]; - [self fail:"initWithString: TEX6: exponent overflow"]; - } catch (e) - { - if ((e.isa) && [e name] == AssertionFailedError) - throw e; - } - try{ - dcmn = [[CPDecimalNumber alloc] initWithString:@"12312e-23421"]; - [self fail:"initWithString: TEX7: exponent underflow"]; - } catch (e) - { - if ((e.isa) && [e name] == AssertionFailedError) - throw e; - } + dcmn = [[CPDecimalNumber alloc] initWithString:@"111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"]; + [self assertTrue:[dcm compare:[CPDecimalNumber notANumber]] message:"initWithString: overflow should return NaN"]; + + dcmn = [[CPDecimalNumber alloc] initWithString:@"foo"]; + [self assertTrue:[dcm compare:[CPDecimalNumber notANumber]] message:"initWithString: overflow should return NaN"]; + + dcmn = [[CPDecimalNumber alloc] initWithString:@".123"]; + [self assertTrue:[dcm compare:[CPDecimalNumber notANumber]] message:"initWithString: overflow should return NaN"]; + + dcmn = [[CPDecimalNumber alloc] initWithString:@"-.123"]; + [self assertTrue:[dcm compare:[CPDecimalNumber notANumber]] message:"initWithString: overflow should return NaN"]; + + dcmn = [[CPDecimalNumber alloc] initWithString:@"0123"]; + [self assertTrue:[dcm compare:[CPDecimalNumber notANumber]] message:"initWithString: overflow should return NaN"]; + + dcmn = [[CPDecimalNumber alloc] initWithString:@"1e200"]; + [self assertTrue:[dcm compare:[CPDecimalNumber notANumber]] message:"initWithString: overflow should return NaN"]; + + dcmn = [[CPDecimalNumber alloc] initWithString:@"12312e-23421"]; + [self assertTrue:[dcm compare:[CPDecimalNumber notANumber]] message:"initWithString: overflow should return NaN"]; } - (void)testAdd diff --git a/Tests/Foundation/CPDecimalTest.j b/Tests/Foundation/CPDecimalTest.j index 2678122e7..3ff6a1032 100644 --- a/Tests/Foundation/CPDecimalTest.j +++ b/Tests/Foundation/CPDecimalTest.j @@ -68,27 +68,42 @@ [self assert:NO equals:dcm._isNaN message:"CPDecimalMakeWithString() Tf4: NaN is incorrectly set"]; dcm = CPDecimalMakeWithString(@"000000000000000000"); - [self assertNull:dcm message:"CPDecimalMakeWithString() Tf5: Should be invalid"]; + [self assertTrue:dcm._isNaN message:"CPDecimalMakeWithString() Tf5: Should be invalid"]; - // too large return nil - [self assertNull:CPDecimalMakeWithString(@"111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111") message:"CPDecimalMakeWithString() To1: number overflow handling"]; - [self assertNull:CPDecimalMakeWithString(@"-1e1000") message:"CPDecimalMakeWithString() To2: exponent overflow not caught"]; - [self assertNull:CPDecimalMakeWithString(@"-1e-2342") message:"CPDecimalMakeWithString() To3: exponent underflow not caught"]; + // too large return NaN + dcm = CPDecimalMakeWithString(@"111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"); + [self assertTrue:dcm._isNaN message:"CPDecimalMakeWithString() To1: number overflow handling. Should return NaN"]; + dcm =CPDecimalMakeWithString(@"-1e1000"); + [self assertTrue:dcm._isNaN message:"CPDecimalMakeWithString() To2: exponent overflow not caught. Should return NaN"]; + dcm = CPDecimalMakeWithString(@"-1e-2342"); + [self assertTrue:dcm._isNaN message:"CPDecimalMakeWithString() To3: exponent underflow not caught. Should return NaN"]; // Tests for invalid strings - [self assertNull:CPDecimalMakeWithString(@"abc") message:"CPDecimalMakeWithString() Ti1: catch of invalid number string"]; - [self assertNull:CPDecimalMakeWithString(@"123a") message:"CPDecimalMakeWithString() Ti2: catch of invalid number string"]; - [self assertNull:CPDecimalMakeWithString(@"12.7e") message:"CPDecimalMakeWithString() Ti3: catch of invalid number string"]; - [self assertNull:CPDecimalMakeWithString(@"e") message:"CPDecimalMakeWithString() Ti4: catch of invalid number string"]; - [self assertNull:CPDecimalMakeWithString(@"12 ") message:"CPDecimalMakeWithString() Ti5: catch of invalid number string"]; - [self assertNull:CPDecimalMakeWithString(@"1 2 3") message:"CPDecimalMakeWithString() Ti6: catch of invalid number string"]; - [self assertNull:CPDecimalMakeWithString(@"e10") message:"CPDecimalMakeWithString() Ti7: catch of invalid number string"]; - [self assertNull:CPDecimalMakeWithString(@"123ee") message:"CPDecimalMakeWithString() Ti8: catch of invalid number string"]; - [self assertNull:CPDecimalMakeWithString(@"0001") message:"CPDecimalMakeWithString() Ti9: catch of invalid number string"]; - [self assertNull:CPDecimalMakeWithString(@"-0001") message:"CPDecimalMakeWithString() Ti10: catch of invalid number string"]; - [self assertNull:CPDecimalMakeWithString(@".123") message:"CPDecimalMakeWithString() Ti11: catch of invalid number string"]; - [self assertNull:CPDecimalMakeWithString(@"-.1") message:"CPDecimalMakeWithString() Ti12: catch of invalid number string"]; - + dcm = CPDecimalMakeWithString(@"abc"); + [self assertTrue:dcm._isNaN message:"CPDecimalMakeWithString() Ti1: catch of invalid number string. Should return NaN"]; + dcm = CPDecimalMakeWithString(@"123a"); + [self assertTrue:dcm._isNaN message:"CPDecimalMakeWithString() Ti2: catch of invalid number string. Should return NaN"]; + dcm = CPDecimalMakeWithString(@"12.7e"); + [self assertTrue:dcm._isNaN message:"CPDecimalMakeWithString() Ti3: catch of invalid number string. Should return NaN"]; + dcm = CPDecimalMakeWithString(@"e"); + [self assertTrue:dcm._isNaN message:"CPDecimalMakeWithString() Ti4: catch of invalid number string. Should return NaN"]; + dcm = CPDecimalMakeWithString(@"12 "); + [self assertTrue:dcm._isNaN message:"CPDecimalMakeWithString() Ti5: catch of invalid number string. Should return NaN"]; + dcm = CPDecimalMakeWithString(@"1 2 3"); + [self assertTrue:dcm._isNaN message:"CPDecimalMakeWithString() Ti6: catch of invalid number string. Should return NaN"]; + dcm = CPDecimalMakeWithString(@"e10"); + [self assertTrue:dcm._isNaN message:"CPDecimalMakeWithString() Ti7: catch of invalid number string. Should return NaN"]; + dcm = CPDecimalMakeWithString(@"123ee"); + [self assertTrue:dcm._isNaN message:"CPDecimalMakeWithString() Ti8: catch of invalid number string. Should return NaN"]; + dcm = CPDecimalMakeWithString(@"0001"); + [self assertTrue:dcm._isNaN message:"CPDecimalMakeWithString() Ti9: catch of invalid number string. Should return NaN"]; + dcm = CPDecimalMakeWithString(@"-0001"); + [self assertTrue:dcm._isNaN message:"CPDecimalMakeWithString() Ti10: catch of invalid number string. Should return NaN"]; + dcm = CPDecimalMakeWithString(@".123"); + [self assertTrue:dcm._isNaN message:"CPDecimalMakeWithString() Ti11: catch of invalid number string. Should return NaN"]; + dcm = CPDecimalMakeWithString(@"-.1"); + [self assertTrue:dcm._isNaN message:"CPDecimalMakeWithString() Ti12: catch of invalid number string. Should return NaN"]; + //test make with parts dcm = CPDecimalMakeWithParts(10127658,2); [self assert:2 equals:dcm._exponent message:"CPDecimalMakeWithParts() Tmp1: exponent"]; @@ -101,8 +116,10 @@ [self assert:YES equals:dcm._isNegative message:"CPDecimalMakeWithParts() Tmp2: sign"]; [self assert:NO equals:dcm._isNaN message:"CPDecimalMakeWithParts() Tmp2: NaN is incorrectly set"]; - [self assertNull:CPDecimalMakeWithParts(1,10000) message:"CPDecimalMakeWithParts() Tmp3: exponent overflow not caught"]; - [self assertNull:CPDecimalMakeWithParts(-1,-1000) message:"CPDecimalMakeWithParts() Tmp4: exponent underflow not caught"]; + dcm = CPDecimalMakeWithParts(1,10000); + [self assertTrue:dcm._isNaN message:"CPDecimalMakeWithParts() Tmp3: exponent overflow not caught. Should return NaN"]; + dcm = CPDecimalMakeWithParts(-1,-1000); + [self assertTrue:dcm._isNaN message:"CPDecimalMakeWithParts() Tmp4: exponent underflow not caught. Should return NaN"]; } - (void)testZeros From c02128a1fdcb9c1b523f118ceafe067ff6edcc94 Mon Sep 17 00:00:00 2001 From: Stephen Ierodiaconou Date: Sat, 15 Jan 2011 17:19:37 +0200 Subject: [PATCH 08/17] Instantiate default number handler lazily and fix CPDecimalNumberHandler initialisers and CPDecimalNumberHandler docs --- Foundation/CPDecimalNumber.j | 141 ++++++++++++++++++++++------------- 1 file changed, 89 insertions(+), 52 deletions(-) diff --git a/Foundation/CPDecimalNumber.j b/Foundation/CPDecimalNumber.j index 8773fe5d1..b51c1339f 100644 --- a/Foundation/CPDecimalNumber.j +++ b/Foundation/CPDecimalNumber.j @@ -23,6 +23,10 @@ @import "CPException.j" @import "CPNumber.j" @import "CPObject.j" +@import "CPString.j" + +// The default global behavior class, created lazily +var CPDefaultDcmHandler = nil; /*! @class CPDecimalNumberHandler @@ -41,26 +45,46 @@ } // initializers +/*! + Initialise a CPDecimalNumberHandler with 'Rounding' = \e CPRoundPlain, + 'Scale' = 0 and 'Raise On [exactness, overflow, underflow, divide by zero]' + = [no, yes, yes, yes]. + @return the receiver CPDecimalNumberHandler object reference +*/ - (id)init { - self = [super init]; - - return self; + return [self initWithRoundingMode:CPRoundPlain + scale:0 + raiseOnExactness:NO + raiseOnOverflow:YES + raiseOnUnderflow:YES + raiseOnDivideByZero:YES]; } /*! - Initialise a CPDecimalNumberHandler object with the parameters specified. This class handles the behaviour of the decimal number calculation engine on certain exception. - @param roundingMode the technique used for rounding (see \e CPRoundingMode values) - @param scale The number of digits after the decimal point that a number which is rounded should have - @param exact if true, a change in precision (i.e. rounding) will cause a \e CPDecimalNumberExactnessException exception to be raised, else they are ignored - @param overflow if true, a calculation overflow will cause a \e CPDecimalNumberOverflowException exception to be raised, else the maximum possible valid number is returned - @param underflow if true, a calculation underflow will cause a \e CPDecimalNumberUnderflowException exception to be raised, else the minimum possible valid number is returned - @param divideByZero if true, a divide by zero will cause a \e CPDecimalNumberDivideByZeroException exception to be raised, else a NotANumber (NaN) CPDecimal is returned + Initialise a CPDecimalNumberHandler object with the parameters specified. + This class handles the behaviour of the decimal number calculation engine + on certain exceptions. + @param roundingMode the technique used for rounding (see \e CPRoundingMode) + @param scale The number of digits after the decimal point that a number + which is rounded should have + @param exact If true, a change in precision (i.e. rounding) will cause a + \e CPDecimalNumberExactnessException exception to be + raised, else they are ignored + @param overflow If true, a calculation overflow will cause a \e + CPDecimalNumberOverflowException exception to be raised, + else the maximum possible valid number is returned + @param underflow If true, a calculation underflow will cause a \e + CPDecimalNumberUnderflowException exception to be raised, + else the minimum possible valid number is returned + @param divideByZero If true, a divide by zero will cause a \e + CPDecimalNumberDivideByZeroException exception to be + raised, else a NotANumber (NaN) CPDecimal is returned @return the reference to the receiver CPDecimalNumberHandler */ - (id)initWithRoundingMode:(CPRoundingMode)roundingMode scale:(short)scale raiseOnExactness:(BOOL)exact raiseOnOverflow:(BOOL)overflow raiseOnUnderflow:(BOOL)underflow raiseOnDivideByZero:(BOOL)divideByZero { - if (self = [self init]) + if (self = [super init]) { _roundingMode = roundingMode; _scale = scale; @@ -75,26 +99,30 @@ // class methods /*! - Create a new CPDecimalNumberHandler object with the parameters specified. This class handles the behaviour of the decimal number calculation engine on certain exception. - @param roundingMode the technique used for rounding (see \e CPRoundingMode values) - @param scale The number of digits after the decimal point that a number which is rounded should have - @param exact if true, a change in precision (i.e. rounding) will cause a \e CPDecimalNumberExactnessException exception to be raised, else they are ignored - @param overflow if true, a calculation overflow will cause a \e CPDecimalNumberOverflowException exception to be raised, else the maximum possible valid number is returned - @param underflow if true, a calculation underflow will cause a \e CPDecimalNumberUnderflowException exception to be raised, else the minimum possible valid number is returned - @param divideByZero if true, a divide by zero will cause a \e CPDecimalNumberDivideByZeroException exception to be raised, else a NotANumber (NaN) CPDecimal is returned - @return the reference to the receiver CPDecimalNumberHandler + Create a new CPDecimalNumberHandler object with the parameters specified. + This class handles the behaviour of the decimal number calculation engine + on certain exception. For more details see \c -initWithRoundingMode:scale:raiseOnExactness:raiseOnOverflow:raiseOnUnderflow:raiseOnDivideByZero: */ + (id)decimalNumberHandlerWithRoundingMode:(CPRoundingMode)roundingMode scale:(short)scale raiseOnExactness:(BOOL)exact raiseOnOverflow:(BOOL)overflow raiseOnUnderflow:(BOOL)underflow raiseOnDivideByZero:(BOOL)divideByZero { - return [[self alloc] initWithRoundingMode:roundingMode scale:scale raiseOnExactness:exact raiseOnOverflow:overflow raiseOnUnderflow:underflow raiseOnDivideByZero:divideByZero]; + return [[self alloc] initWithRoundingMode:roundingMode + scale:scale + raiseOnExactness:exact + raiseOnOverflow:overflow + raiseOnUnderflow:underflow + raiseOnDivideByZero:divideByZero]; } /*! - Return the default Cappuccino CPDecimalNumberHandler object instance. This is created when the framework is initialised. - @return the default CPDecimalNumberHandler object reference with Rounding = \e CPRoundPlain, Scale = 0 and Raise on [exactness, overflow, underflow, divide by zero] = [no, yes, yes, yes] + Return the default Cappuccino CPDecimalNumberHandler object instance. + @return the default CPDecimalNumberHandler object reference with + Rounding = \e CPRoundPlain, Scale = 0 and Raise on [exactness, + overflow, underflow, divide by zero] = [no, yes, yes, yes] */ + (id)defaultDecimalNumberHandler { + if (!CPDefaultDcmHandler) + CPDefaultDcmHandler = [[CPDecimalNumberHandler alloc] init]; return CPDefaultDcmHandler; } @@ -104,7 +132,8 @@ @implementation CPDecimalNumberHandler (CPDecimalNumberBehaviors) /*! - Returns the current rounding mode. One of \e CPRoundingMode enum: CPRoundPlain, CPRoundDown, CPRoundUp, CPRoundBankers. + Returns the current rounding mode. One of \e CPRoundingMode enum: + CPRoundPlain, CPRoundDown, CPRoundUp, CPRoundBankers. @return the current rounding mode */ - (CPRoundingMode)roundingMode @@ -122,18 +151,25 @@ } /*! - This method is invoked by the framework when an exception occurs on a decimal operation. Depending on the specified behaviour of the CPDecimalNumberHandler this will throw - exceptions accordingly with formatted error messages. - @param operation the selector of the method of the operation being performed when the exception occured - @param error the actual error type. From the \e CPCalculationError enum: CPCalculationNoError, CPCalculationLossOfPrecision, CPCalculationOverflow, CPCalculationUnderflow, CPCalculationDivideByZero - @param leftOperand the CPDecimalNumber left-hand side operand used in the calculation that caused the exception - @param rightOperand the CPDecimalNumber right-hand side operand used in the calculation that caused the exception - @return if appropriate a CPDecimalNumber is returned (either the maxumum, minimum or NaN values), or nil + This method is invoked by the framework when an exception occurs on a + decimal operation. Depending on the specified behaviour of the + CPDecimalNumberHandler this will throw exceptions accordingly with + formatted error messages. + @param operation the selector of the method of the operation being + performed when the exception occured + @param error the actual error type. From the \e + CPCalculationError enum: CPCalculationNoError, + CPCalculationLossOfPrecision, CPCalculationOverflow, + CPCalculationUnderflow, CPCalculationDivideByZero + @param leftOperand the CPDecimalNumber left-hand side operand used in the + calculation that caused the exception + @param rightOperand the CPDecimalNumber right-hand side operand used in the + calculation that caused the exception + @return if appropriate a CPDecimalNumber is returned (either the maxumum, + minimum or NaN values), or nil */ - (CPDecimalNumber)exceptionDuringOperation:(SEL)operation error:(CPCalculationError)error leftOperand:(CPDecimalNumber)leftOperand rightOperand:(CPDecimalNumber)rightOperand { - // TODO: default behavior of throwing exceptions a la gnustep, check if same on Cocoa - // FIXME: locale? switch (error) { case CPCalculationNoError: return nil; @@ -184,11 +220,11 @@ var CPDecimalNumberHandlerRoundingModeKey = @"CPDecimalNumberHandlerRoundi if (self) { [self initWithRoundingMode:[aCoder decodeIntForKey:CPDecimalNumberHandlerRoundingModeKey] - scale:[aCoder decodeIntForKey:CPDecimalNumberHandlerScaleKey] - raiseOnExactness:[aCoder decodeBoolForKey:CPDecimalNumberHandlerRaiseOnExactKey] - raiseOnOverflow:[aCoder decodeBoolForKey:CPDecimalNumberHandlerRaiseOnOverflowKey] - raiseOnUnderflow:[aCoder decodeBoolForKey:CPDecimalNumberHandlerRaiseOnUnderflowKey] - raiseOnDivideByZero:[aCoder decodeBoolForKey:CPDecimalNumberHandlerDivideByZeroKey]]; + scale:[aCoder decodeIntForKey:CPDecimalNumberHandlerScaleKey] + raiseOnExactness:[aCoder decodeBoolForKey:CPDecimalNumberHandlerRaiseOnExactKey] + raiseOnOverflow:[aCoder decodeBoolForKey:CPDecimalNumberHandlerRaiseOnOverflowKey] + raiseOnUnderflow:[aCoder decodeBoolForKey:CPDecimalNumberHandlerRaiseOnUnderflowKey] + raiseOnDivideByZero:[aCoder decodeBoolForKey:CPDecimalNumberHandlerDivideByZeroKey]]; } return self; @@ -210,9 +246,6 @@ var CPDecimalNumberHandlerRoundingModeKey = @"CPDecimalNumberHandlerRoundi @end -// create the default global behavior class -var CPDefaultDcmHandler = [CPDecimalNumberHandler decimalNumberHandlerWithRoundingMode:CPRoundPlain scale:0 raiseOnExactness:NO raiseOnOverflow:YES raiseOnUnderflow:YES raiseOnDivideByZero:YES]; - /*! @class CPDecimalNumber @ingroup foundation @@ -362,9 +395,18 @@ var CPDefaultDcmHandler = [CPDecimalNumberHandler decimalNumberHandlerWithRoundi return [[self alloc] initWithString:numberValue locale:locale]; } +/*! + Return the default \c CPDecimalNumberHandler object. + @return the new default CPDecimalNumberHandler object +*/ + (id)defaultBehavior { - return CPDefaultDcmHandler; + return [CPDecimalNumberHandler defaultDecimalNumberHandler]; +} + ++ (void)setDefaultBehavior:(id )behavior +{ + CPDefaultDcmHandler = behavior; } /*! @@ -400,15 +442,10 @@ var CPDefaultDcmHandler = [CPDecimalNumberHandler decimalNumberHandlerWithRoundi return [[self alloc] initWithDecimal:CPDecimalMakeOne()]; } -+ (void)setDefaultBehavior:(id )behavior -{ - CPDefaultDcmHandler = behavior; -} - // instance methods - (CPDecimalNumber)decimalNumberByAdding:(CPDecimalNumber)decimalNumber { - return [self decimalNumberByAdding:decimalNumber withBehavior:CPDefaultDcmHandler]; + return [self decimalNumberByAdding:decimalNumber withBehavior:[CPDecimalNumber defaultBehavior]]; } - (CPDecimalNumber)decimalNumberByAdding:(CPDecimalNumber)decimalNumber withBehavior:(id )behavior @@ -430,7 +467,7 @@ var CPDefaultDcmHandler = [CPDecimalNumberHandler decimalNumberHandlerWithRoundi - (CPDecimalNumber)decimalNumberBySubtracting:(CPDecimalNumber)decimalNumber { - return [self decimalNumberBySubtracting:decimalNumber withBehavior:CPDefaultDcmHandler]; + return [self decimalNumberBySubtracting:decimalNumber withBehavior:[CPDecimalNumber defaultBehavior]]; } - (CPDecimalNumber)decimalNumberBySubtracting:(CPDecimalNumber)decimalNumber withBehavior:(id )behavior @@ -450,7 +487,7 @@ var CPDefaultDcmHandler = [CPDecimalNumberHandler decimalNumberHandlerWithRoundi - (CPDecimalNumber)decimalNumberByDividingBy:(CPDecimalNumber)decimalNumber { - return [self decimalNumberByDividingBy:decimalNumber withBehavior:CPDefaultDcmHandler]; + return [self decimalNumberByDividingBy:decimalNumber withBehavior:[CPDecimalNumber defaultBehavior]]; } - (CPDecimalNumber)decimalNumberByDividingBy:(CPDecimalNumber)decimalNumber withBehavior:(id )behavior @@ -470,7 +507,7 @@ var CPDefaultDcmHandler = [CPDecimalNumberHandler decimalNumberHandlerWithRoundi - (CPDecimalNumber)decimalNumberByMultiplyingBy:(CPDecimalNumber)decimalNumber { - return [self decimalNumberByMultiplyingBy:decimalNumber withBehavior:CPDefaultDcmHandler]; + return [self decimalNumberByMultiplyingBy:decimalNumber withBehavior:[CPDecimalNumber defaultBehavior]]; } - (CPDecimalNumber)decimalNumberByMultiplyingBy:(CPDecimalNumber)decimalNumber withBehavior:(id )behavior @@ -490,7 +527,7 @@ var CPDefaultDcmHandler = [CPDecimalNumberHandler decimalNumberHandlerWithRoundi - (CPDecimalNumber)decimalNumberByMultiplyingByPowerOf10:(short)power { - return [self decimalNumberByMultiplyingByPowerOf10:power withBehavior:CPDefaultDcmHandler]; + return [self decimalNumberByMultiplyingByPowerOf10:power withBehavior:[CPDecimalNumber defaultBehavior]]; } - (CPDecimalNumber)decimalNumberByMultiplyingByPowerOf10:(short)power withBehavior:(id )behavior @@ -510,7 +547,7 @@ var CPDefaultDcmHandler = [CPDecimalNumberHandler decimalNumberHandlerWithRoundi - (CPDecimalNumber)decimalNumberByRaisingToPower:(unsigned)power { - return [self decimalNumberByRaisingToPower:power withBehavior:CPDefaultDcmHandler]; + return [self decimalNumberByRaisingToPower:power withBehavior:[CPDecimalNumber defaultBehavior]]; } - (CPDecimalNumber)decimalNumberByRaisingToPower:(unsigned)power withBehavior:(id )behavior From 2fe884584230c9675593d07f3cf54845459e2026 Mon Sep 17 00:00:00 2001 From: Stephen Ierodiaconou Date: Sat, 15 Jan 2011 18:35:02 +0200 Subject: [PATCH 09/17] CPDecimalString returns NaN for a NaN and Fix Compare of NaNs and Cocoa compatable handling of overflow/underflows when no exception --- Foundation/CPDecimal.j | 16 +++++++++++----- Foundation/CPDecimalNumber.j | 12 +++++------- Tests/Foundation/CPDecimalNumberTest.j | 14 +++++++------- 3 files changed, 23 insertions(+), 19 deletions(-) diff --git a/Foundation/CPDecimal.j b/Foundation/CPDecimal.j index baaf5b355..eb5f267cd 100644 --- a/Foundation/CPDecimal.j +++ b/Foundation/CPDecimal.j @@ -146,7 +146,7 @@ function CPDecimalMakeWithString(string, locale) return CPDecimalMakeNaN(); // Representation internally starts at most significant digit - var m = [CPArray array], + var m = [CPMutableArray array], i = 0; for (; i < (intpart?intpart.length:0); i++) { @@ -177,7 +177,7 @@ function CPDecimalMakeWithString(string, locale) */ function CPDecimalMakeWithParts(mantissa, exponent) { - var m = [CPArray array], + var m = [CPMutableArray array], isNegative = NO; if (mantissa < 0 ) @@ -310,7 +310,7 @@ function _CPDecimalSet(t,s) function _CPDecimalSetZero(result) { - result._mantissa = [CPArray arrayWithObject:0]; + result._mantissa = [CPMutableArray arrayWithObject:0]; result._exponent = 0; result._isNegative = NO; result._isCompact = YES; @@ -319,7 +319,7 @@ function _CPDecimalSetZero(result) function _CPDecimalSetOne(result) { - result._mantissa = [CPArray arrayWithObject:1]; + result._mantissa = [CPMutableArray arrayWithObject:1]; result._exponent = 0; result._isNegative = NO; result._isCompact = YES; @@ -362,6 +362,9 @@ function CPDecimalCopy(dcm) */ function CPDecimalCompare(leftOperand, rightOperand) { + if (leftOperand._isNaN && rightOperand._isNaN) + return CPOrderedSame; + if (leftOperand._isNegative != rightOperand._isNegative) { if (rightOperand._isNegative) @@ -756,7 +759,7 @@ function _SimpleDivide(result, leftOperand, rightOperand, roundingMode) _CPDecimalSetZero(result); - n1._mantissa = [CPArray array]; + n1._mantissa = [CPMutableArray array]; while ((k < [leftOperand._mantissa count]) || ([n1._mantissa count] && !(([n1._mantissa count] == 1) && (n1._mantissa[0] == 0)))) @@ -1432,6 +1435,9 @@ function CPDecimalString(dcm, locale) { // Cocoa seems to just add all the zeros... this maybe controlled by locale, // will check. + if (dcm._isNaN) + return @"NaN"; + var string = @"", i = 0; diff --git a/Foundation/CPDecimalNumber.j b/Foundation/CPDecimalNumber.j index b51c1339f..81bb6f4a0 100644 --- a/Foundation/CPDecimalNumber.j +++ b/Foundation/CPDecimalNumber.j @@ -172,21 +172,19 @@ var CPDefaultDcmHandler = nil; { switch (error) { - case CPCalculationNoError: return nil; + case CPCalculationNoError: break; case CPCalculationOverflow: if (_raiseOnOverflow) [CPException raise:CPDecimalNumberOverflowException reason:("A CPDecimalNumber overflow has occured. (Left operand= '" + [leftOperand descriptionWithLocale:nil] + "' Right operand= '" + [rightOperand descriptionWithLocale:nil] + "' Selector= '" + operation + "')") ]; else - return [CPDecimalNumber maximumDecimalNumber]; // there was overflow return largest possible val + return [CPDecimalNumber notANumber]; break; case CPCalculationUnderflow: if (_raiseOnUnderflow) [CPException raise:CPDecimalNumberUnderflowException reason:("A CPDecimalNumber underflow has occured. (Left operand= '" + [leftOperand descriptionWithLocale:nil] + "' Right operand= '" + [rightOperand descriptionWithLocale:nil] + "' Selector= '" + operation + "')") ]; else - return [CPDecimalNumber minimumDecimalNumber]; // there was underflow, return smallest possible value + return [CPDecimalNumber notANumber]; break; case CPCalculationLossOfPrecision: if (_raiseOnExactness) [CPException raise:CPDecimalNumberExactnessException reason:("A CPDecimalNumber has been rounded off during a calculation. (Left operand= '" + [leftOperand descriptionWithLocale:nil] + "' Right operand= '" + [rightOperand descriptionWithLocale:nil] + "' Selector= '" + operation + "')") ]; - else - return nil; // Ignore. break; case CPCalculationDivideByZero: if (_raiseOnDivideByZero) [CPException raise:CPDecimalNumberDivideByZeroException reason:("A CPDecimalNumber divide by zero has occured. (Left operand= '" + [leftOperand descriptionWithLocale:nil] + "' Right operand= '" + [rightOperand descriptionWithLocale:nil] + "' Selector= '" + operation + "')") ]; @@ -196,7 +194,7 @@ var CPDefaultDcmHandler = nil; default: [CPException raise:CPInvalidArgumentException reason:("An unknown CPDecimalNumber error has occured. (Left operand= '" + [leftOperand descriptionWithLocale:nil] + "' Right operand= '" + [rightOperand descriptionWithLocale:nil] + "' Selector= '" + operation + "')") ]; } - return nil; + return nil; } @end @@ -581,7 +579,7 @@ var CPDecimalNumberHandlerRoundingModeKey = @"CPDecimalNumberHandlerRoundi // Thus the type is checked to send the operand to the correct compare function. - (CPComparisonResult)compare:(CPNumber)decimalNumber { - if ([decimalNumber class] != CPDecimalNumber) + if (![decimalNumber isKindOfClass:[CPDecimalNumber class]]) decimalNumber = [CPDecimalNumber decimalNumberWithString:decimalNumber.toString()]; return CPDecimalCompare([self decimalValue], [decimalNumber decimalValue]); } diff --git a/Tests/Foundation/CPDecimalNumberTest.j b/Tests/Foundation/CPDecimalNumberTest.j index 83b768086..aa6fb452f 100644 --- a/Tests/Foundation/CPDecimalNumberTest.j +++ b/Tests/Foundation/CPDecimalNumberTest.j @@ -140,25 +140,25 @@ [self assert:true equals:dcm message:"boolValue: - should be true"]; dcmn = [[CPDecimalNumber alloc] initWithString:@"111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"]; - [self assertTrue:[dcm compare:[CPDecimalNumber notANumber]] message:"initWithString: overflow should return NaN"]; + [self assert:CPOrderedSame equals:[dcmn compare:[CPDecimalNumber notANumber]] message:"initWithString: 1 overflow should return NaN"]; dcmn = [[CPDecimalNumber alloc] initWithString:@"foo"]; - [self assertTrue:[dcm compare:[CPDecimalNumber notANumber]] message:"initWithString: overflow should return NaN"]; + [self assert:CPOrderedSame equals:[dcmn compare:[CPDecimalNumber notANumber]] message:"initWithString: 2 overflow should return NaN"]; dcmn = [[CPDecimalNumber alloc] initWithString:@".123"]; - [self assertTrue:[dcm compare:[CPDecimalNumber notANumber]] message:"initWithString: overflow should return NaN"]; + [self assert:CPOrderedSame equals:[dcmn compare:[CPDecimalNumber notANumber]] message:"initWithString: 3 overflow should return NaN"]; dcmn = [[CPDecimalNumber alloc] initWithString:@"-.123"]; - [self assertTrue:[dcm compare:[CPDecimalNumber notANumber]] message:"initWithString: overflow should return NaN"]; + [self assert:CPOrderedSame equals:[dcmn compare:[CPDecimalNumber notANumber]] message:"initWithString: 4 overflow should return NaN"]; dcmn = [[CPDecimalNumber alloc] initWithString:@"0123"]; - [self assertTrue:[dcm compare:[CPDecimalNumber notANumber]] message:"initWithString: overflow should return NaN"]; + [self assert:CPOrderedSame equals:[dcmn compare:[CPDecimalNumber notANumber]] message:"initWithString: 5 overflow should return NaN"]; dcmn = [[CPDecimalNumber alloc] initWithString:@"1e200"]; - [self assertTrue:[dcm compare:[CPDecimalNumber notANumber]] message:"initWithString: overflow should return NaN"]; + [self assert:CPOrderedSame equals:[dcmn compare:[CPDecimalNumber notANumber]] message:"initWithString: 6 overflow should return NaN"]; dcmn = [[CPDecimalNumber alloc] initWithString:@"12312e-23421"]; - [self assertTrue:[dcm compare:[CPDecimalNumber notANumber]] message:"initWithString: overflow should return NaN"]; + [self assert:CPOrderedSame equals:[dcmn compare:[CPDecimalNumber notANumber]] message:"initWithString: 7 overflow should return NaN"]; } - (void)testAdd From e0185a0eff3bd53fa2256af655c760895a2e2956 Mon Sep 17 00:00:00 2001 From: Stephen Ierodiaconou Date: Sat, 15 Jan 2011 21:37:53 +0200 Subject: [PATCH 10/17] Documentation for CPDecimalNumber --- Foundation/CPDecimalNumber.j | 443 +++++++++++++++++++++++++++++++---- 1 file changed, 401 insertions(+), 42 deletions(-) diff --git a/Foundation/CPDecimalNumber.j b/Foundation/CPDecimalNumber.j index 81bb6f4a0..761cf44f2 100644 --- a/Foundation/CPDecimalNumber.j +++ b/Foundation/CPDecimalNumber.j @@ -249,18 +249,62 @@ var CPDecimalNumberHandlerRoundingModeKey = @"CPDecimalNumberHandlerRoundi @ingroup foundation @brief Decimal floating point number - This class represents a decimal floating point number and the relavent mathematical operations to go with it. - The default number handler can be accessed at [CPDecimalNumberHandler +defaultDecimalNumberHandler] - This class is mutable. + This class represents a decimal floating point number and the relavent + mathematical operations to go with it. It guarantees accuracy up to 38 + digits in the mantissa/coefficient and can handle numbers in the range: + +/- 99999999999999999999999999999999999999 x 10^(127/-128) + Methods are available for: Addition, Subtraction, Multiplication, Division, + Powers and Rounding. + Exceptions can be thrown on: Overflow, Underflow, Loss of Precision + (rounding) and Divide by zero, the behaviour of which is controlled via the + CPDecimalNumberHandler class. + + Note: The aim here is to try to produce the exact same output as Cocoa. + However, this is effectively not possible but to get as close as possible + we must perform our calculations in a way such that we even get the same + rounding errors building up, say when computing large powers which require + many multiplications. The code here almost matches the results of Cocoa but + there are some small differences as outlined below: + + An example where a small rounding error difference creeps in: + For the calculation (0.875 ^ 101) the result becomes: + In Cocoa: 0.00000(13893554059925661274821814636807535200)1 + the 38 digits are bracketed, the extra 39th digit in Cocoa + is explained below. + In Cappuccino: 0.00000(13893554059925661274821814636807535204) + Difference: 4e-41 + + Since, in Cocoa, NSDecimalNumber uses a binary internal format for + the mantissa (coefficient) the maximum it can store before truly + losing precision is actually 2^128, which is a 39 digit number. After this + rounding and exponent changes occur. In our implementation each digit is + stored separately hence the mantissa maximum value is the maximum possible + 38 digit number. Obviously Apple can only say precision is guaranteed to + 38 digits cause at some point in the 39 digits numbers rounding starts. + Hence there will be inherent differences between Cocoa and Cappuccino + answers if rounding occurs (see above example). They both still provide + the same 38 digit guarantee however. + + So the actual range of NSDecimal is + +/- 340282366920938463463374607431768211455 x 10^(127/-128) + (Notice this is 39 digits) + Compared to in Cappuccino: + +/- 99999999999999999999999999999999999999 x 10^(127/-128) */ @implementation CPDecimalNumber : CPNumber { CPDecimal _data; } -// overriding alloc means CPDecimalNumbers are not toll free bridged +/*! + Create a new CPDecimalNumber object uninitialised. + Note: eventhough CPDecimalNumber inherits from CPNumber it is not toll free + bridged to a JS type as CPNumber is. + @return a new CPDecimalNumber instance +*/ + (id)alloc { + // overriding alloc means CPDecimalNumbers are not toll free bridged return class_createInstance(self); } @@ -355,7 +399,7 @@ var CPDecimalNumberHandlerRoundingModeKey = @"CPDecimalNumberHandlerRoundi } /*! - Create a new CPDecimalNumber object with the given mantissa and exponent. + Creates a new CPDecimalNumber object with the given mantissa and exponent. See \c -initWithMantissa:exponent:isNegative: for some extra notes. @param mantissa the mantissa of the decimal number @param exponent the exponent of the number @@ -368,7 +412,7 @@ var CPDecimalNumberHandlerRoundingModeKey = @"CPDecimalNumberHandlerRoundi } /*! - Create a new CPDecimalNumber with a string. If the string is badly formed + Creates a new CPDecimalNumber with a string. If the string is badly formed or outside of the acceptable range of a CPDecimal then the number is initialised to NaN. @param numberValue the string to parse. @@ -380,7 +424,7 @@ var CPDecimalNumberHandlerRoundingModeKey = @"CPDecimalNumberHandlerRoundi } /*! - Create a new CPDecimalNumber with a string using the given locale. If the + Creates a new CPDecimalNumber with a string using the given locale. If the string is badly formed or outside of the acceptable range of a CPDecimal then the number is initialised to NaN. NOTE: Locales are currently not supported. @@ -395,21 +439,28 @@ var CPDecimalNumberHandlerRoundingModeKey = @"CPDecimalNumberHandlerRoundi /*! Return the default \c CPDecimalNumberHandler object. - @return the new default CPDecimalNumberHandler object + @return the default CPDecimalNumberHandler object */ + (id)defaultBehavior { return [CPDecimalNumberHandler defaultDecimalNumberHandler]; } +/*! + Set the default \c CPDecimalNumberHandler object. This is a framework wide + setting. All subsequent decimal number operations will use this behaviour. + @param behavior the new default CPDecimalNumberHandler object +*/ + (void)setDefaultBehavior:(id )behavior { CPDefaultDcmHandler = behavior; } /*! - 340282366920938463463374607431768211455e127 - 99999999999999999999999999999999999999e127 + Returns a new CPDecimalNumer with the maximum permissable decimal number + value. Note: this is different to the number Cocoa returns. See + CPDecimalNumber class description for details. + @return a new CPDecimalNumber object */ + (CPDecimalNumber)maximumDecimalNumber { @@ -417,57 +468,100 @@ var CPDecimalNumberHandlerRoundingModeKey = @"CPDecimalNumberHandlerRoundi } /*! - -340282366920938463463374607431768211455e127 - -99999999999999999999999999999999999999e127 + Returns a new CPDecimalNumer with the minimum permissable decimal number + value. Note: this is different to the number Cocoa returns. See + CPDecimalNumber class description for details. + @return a new CPDecimalNumber object */ + (CPDecimalNumber)minimumDecimalNumber { return [[self alloc] initWithDecimal:_CPDecimalMakeMinimum()]; } +/*! + Returns a new CPDecimalNumer initialised to \e NaN. + @return a new CPDecimalNumber object +*/ + (CPDecimalNumber)notANumber { return [[self alloc] initWithDecimal:CPDecimalMakeNaN()]; } +/*! + Returns a new CPDecimalNumer initialised to zero (0.0). + @return a new CPDecimalNumber object +*/ + (CPDecimalNumber)zero { return [[self alloc] initWithDecimal:CPDecimalMakeZero()]; } +/*! + Returns a new CPDecimalNumer initialised to one (1.0). + @return a new CPDecimalNumber object +*/ + (CPDecimalNumber)one { return [[self alloc] initWithDecimal:CPDecimalMakeOne()]; } // instance methods +/*! + Returns a new CPDecimalNumber object with the result of the summation of + the receiver object and \c decimalNumber. If overflow occurs then the + consequence depends on the current default CPDecimalNumberHandler. + @param decimalNumber the decimal number to add to the receiver + @return a new CPDecimalNumber object +*/ - (CPDecimalNumber)decimalNumberByAdding:(CPDecimalNumber)decimalNumber { return [self decimalNumberByAdding:decimalNumber withBehavior:[CPDecimalNumber defaultBehavior]]; } +/*! + Returns a new CPDecimalNumber object with the result of the summation of + the receiver object and \c decimalNumber. If overflow occurs then the + consequence depends on the CPDecimalNumberHandler object \e behavior. + @param decimalNumber the decimal number to add to the receiver + @param behavior a CPDecimalNumberHandler object + @return a new CPDecimalNumber object +*/ - (CPDecimalNumber)decimalNumberByAdding:(CPDecimalNumber)decimalNumber withBehavior:(id )behavior { - // FIXME: Surely this can take CPNumber (any JS number) as an argument as CPNumber is CPDecimalNumbers super normally (not here tho) var result = CPDecimalMakeZero(), - res = 0, error = CPDecimalAdd(result, [self decimalValue], [decimalNumber decimalValue], [behavior roundingMode]); if (error > CPCalculationNoError) { - res = [behavior exceptionDuringOperation:_cmd error:error leftOperand:self rightOperand:decimalNumber]; - // Gnustep does this, not sure if it is correct behavior + var res = [behavior exceptionDuringOperation:_cmd error:error leftOperand:self rightOperand:decimalNumber]; if (res != nil) - return res; // say on overflow and no exception handling, returns max decimal val + return res; } return [CPDecimalNumber decimalNumberWithDecimal:result]; } +/*! + Returns a new CPDecimalNumber object with the result of the subtraction of + \c decimalNumber from the receiver object. If underflow or loss of precision + occurs then the consequence depends on the current default + CPDecimalNumberHandler. + @param decimalNumber the decimal number to subtract from the receiver + @return a new CPDecimalNumber object +*/ - (CPDecimalNumber)decimalNumberBySubtracting:(CPDecimalNumber)decimalNumber { return [self decimalNumberBySubtracting:decimalNumber withBehavior:[CPDecimalNumber defaultBehavior]]; } +/*! + Returns a new CPDecimalNumber object with the result of the subtraction of + \c decimalNumber from the receiver object. If underflow or loss of + precision occurs then the consequence depends on the CPDecimalNumberHandler + object \e behavior. + @param decimalNumber the decimal number to subtract from the receiver + @param behavior a CPDecimalNumberHandler object + @return a new CPDecimalNumber object +*/ - (CPDecimalNumber)decimalNumberBySubtracting:(CPDecimalNumber)decimalNumber withBehavior:(id )behavior { var result = CPDecimalMakeZero(), @@ -476,18 +570,34 @@ var CPDecimalNumberHandlerRoundingModeKey = @"CPDecimalNumberHandlerRoundi if (error > CPCalculationNoError) { var res = [behavior exceptionDuringOperation:_cmd error:error leftOperand:self rightOperand:decimalNumber]; - // Gnustep does this, not sure if it is correct behavior if (res != nil) - return res; // say on overflow and no exception handling, returns max decimal val + return res; } return [CPDecimalNumber decimalNumberWithDecimal:result]; } +/*! + Returns a new CPDecimalNumber object with the result of dividing the + receiver object by \c decimalNumber. If underflow, divide by zero or loss + of precision occurs then the consequence depends on the current default + CPDecimalNumberHandler object. + @param decimalNumber the decimal number to divide the the receiver by + @return a new CPDecimalNumber object +*/ - (CPDecimalNumber)decimalNumberByDividingBy:(CPDecimalNumber)decimalNumber { return [self decimalNumberByDividingBy:decimalNumber withBehavior:[CPDecimalNumber defaultBehavior]]; } +/*! + Returns a new CPDecimalNumber object with the result of dividing the + receiver object by \c decimalNumber. If underflow, divide by zero or loss + of precision occurs then the consequence depends on the + CPDecimalNumberHandler object \e behavior. + @param decimalNumber the decimal number to divide the the receiver by + @param behavior a CPDecimalNumberHandler object + @return a new CPDecimalNumber object +*/ - (CPDecimalNumber)decimalNumberByDividingBy:(CPDecimalNumber)decimalNumber withBehavior:(id )behavior { var result = CPDecimalMakeZero(), @@ -496,18 +606,34 @@ var CPDecimalNumberHandlerRoundingModeKey = @"CPDecimalNumberHandlerRoundi if (error > CPCalculationNoError) { var res = [behavior exceptionDuringOperation:_cmd error:error leftOperand:self rightOperand:decimalNumber]; - // Gnustep does this, not sure if it is correct behavior if (res != nil) - return res; // say on overflow and no exception handling, returns max decimal val + return res; } return [CPDecimalNumber decimalNumberWithDecimal:result]; } +/*! + Returns a new CPDecimalNumber object with the result of multiplying the + receiver object by \c decimalNumber. If overflow or loss of precision + occurs then the consequence depends on the current default + CPDecimalNumberHandler object. + @param decimalNumber the decimal number to multiply the the receiver by + @return a new CPDecimalNumber object +*/ - (CPDecimalNumber)decimalNumberByMultiplyingBy:(CPDecimalNumber)decimalNumber { return [self decimalNumberByMultiplyingBy:decimalNumber withBehavior:[CPDecimalNumber defaultBehavior]]; } +/*! + Returns a new CPDecimalNumber object with the result of multiplying the + receiver object by \c decimalNumber. If overflow or loss of precision + occurs then the consequence depends on the CPDecimalNumberHandler object + \e behavior. + @param decimalNumber the decimal number to multiply the the receiver by + @param behavior a CPDecimalNumberHandler object + @return a new CPDecimalNumber object +*/ - (CPDecimalNumber)decimalNumberByMultiplyingBy:(CPDecimalNumber)decimalNumber withBehavior:(id )behavior { var result = CPDecimalMakeZero(), @@ -516,18 +642,34 @@ var CPDecimalNumberHandlerRoundingModeKey = @"CPDecimalNumberHandlerRoundi if (error > CPCalculationNoError) { var res = [behavior exceptionDuringOperation:_cmd error:error leftOperand:self rightOperand:decimalNumber]; - // Gnustep does this, not sure if it is correct behavior if (res != nil) - return res; // say on overflow and no exception handling, returns max decimal val + return res; } return [CPDecimalNumber decimalNumberWithDecimal:result]; } +/*! + Returns a new CPDecimalNumber object with the result of multiplying the + receiver object by (10 ^ \c power). If overflow, underflow or loss of + precision occurs then the consequence depends on the current default + CPDecimalNumberHandler object. + @param power the power of 10 to multiply the receiver by + @return a new CPDecimalNumber object +*/ - (CPDecimalNumber)decimalNumberByMultiplyingByPowerOf10:(short)power { return [self decimalNumberByMultiplyingByPowerOf10:power withBehavior:[CPDecimalNumber defaultBehavior]]; } +/*! + Returns a new CPDecimalNumber object with the result of multiplying the + receiver object by (10 ^ \c power). If overflow, underflowor loss of + precision occurs then the consequence depends on the CPDecimalNumberHandler + object \e behavior. + @param power the power of 10 to multiply the receiver by + @param behavior a CPDecimalNumberHandler object + @return a new CPDecimalNumber object +*/ - (CPDecimalNumber)decimalNumberByMultiplyingByPowerOf10:(short)power withBehavior:(id )behavior { var result = CPDecimalMakeZero(), @@ -536,18 +678,34 @@ var CPDecimalNumberHandlerRoundingModeKey = @"CPDecimalNumberHandlerRoundi if (error > CPCalculationNoError) { var res = [behavior exceptionDuringOperation:_cmd error:error leftOperand:self rightOperand:[CPDecimalNumber decimalNumberWithString:power.toString()]]; - // Gnustep does this, not sure if it is correct behavior if (res != nil) - return res; // say on overflow and no exception handling, returns max decimal val + return res; } return [CPDecimalNumber decimalNumberWithDecimal:result]; } +/*! + Returns a new CPDecimalNumber object with the result of raising the + receiver object to the power \c power. If overflow, underflow or loss of + precision occurs then the consequence depends on the current default + CPDecimalNumberHandler object. + @param power the power to raise the receiver by + @return a new CPDecimalNumber object +*/ - (CPDecimalNumber)decimalNumberByRaisingToPower:(unsigned)power { return [self decimalNumberByRaisingToPower:power withBehavior:[CPDecimalNumber defaultBehavior]]; } +/*! + Returns a new CPDecimalNumber object with the result of raising the + receiver object to the power \c power. If overflow, underflow or loss of + precision occurs then the consequence depends on the CPDecimalNumberHandler + object \e behavior. + @param power the power to raise the receiver by + @param behavior a CPDecimalNumberHandler object + @return a new CPDecimalNumber object +*/ - (CPDecimalNumber)decimalNumberByRaisingToPower:(unsigned)power withBehavior:(id )behavior { if (power < 0) @@ -559,13 +717,19 @@ var CPDecimalNumberHandlerRoundingModeKey = @"CPDecimalNumberHandlerRoundi if (error > CPCalculationNoError) { var res = [behavior exceptionDuringOperation:_cmd error:error leftOperand:self rightOperand:[CPDecimalNumber decimalNumberWithString:power.toString()]]; - // Gnustep does this, not sure if it is correct behavior if (res != nil) - return res; // say on overflow and no exception handling, returns max decimal val + return res; } return [CPDecimalNumber decimalNumberWithDecimal:result]; } +/*! + Returns a new CPDecimalNumber object with the result of rounding the number + according to the rounding behavior specified by the CPDecimalNumberHandler + object \e behavior. + @param behavior a CPDecimalNumberHandler object + @return a new rounded CPDecimalNumber object +*/ - (CPDecimalNumber)decimalNumberByRoundingAccordingToBehavior:(id )behavior { var result = CPDecimalMakeZero(); @@ -575,21 +739,19 @@ var CPDecimalNumberHandlerRoundingModeKey = @"CPDecimalNumberHandlerRoundi return [CPDecimalNumber decimalNumberWithDecimal:result]; } -// This method takes a CPNumber. Thus the parameter may be a CPDecimalNumber or a CPNumber class. -// Thus the type is checked to send the operand to the correct compare function. -- (CPComparisonResult)compare:(CPNumber)decimalNumber -{ - if (![decimalNumber isKindOfClass:[CPDecimalNumber class]]) - decimalNumber = [CPDecimalNumber decimalNumberWithString:decimalNumber.toString()]; - return CPDecimalCompare([self decimalValue], [decimalNumber decimalValue]); -} - /*! - Unimplemented + Compare the reciever CPDecimalNumber to \c aNumber. This is a CPNumber or + subclass. Returns \e CPOrderedDescending, \e CPOrderedAscending or + \e CPOrderedSame. + @param aNumber an object of kind CPNumber to compare against. + @return result from \e CPComparisonResult enum. */ -- (CPString)hash +- (CPComparisonResult)compare:(CPNumber)aNumber { - [CPException raise:CPUnsupportedMethodException reason:"hash: NOT YET IMPLEMENTED"]; + // aNumber type is checked to convert if appropriate + if (![aNumber isKindOfClass:[CPDecimalNumber class]]) + aNumber = [CPDecimalNumber decimalNumberWithString:aNumber.toString()]; + return CPDecimalCompare([self decimalValue], [aNumber decimalValue]); } /*! @@ -601,17 +763,30 @@ var CPDecimalNumberHandlerRoundingModeKey = @"CPDecimalNumberHandlerRoundi return @"d"; } +/*! + Returns a string representation of the decimal number. + @return a CPString +*/ - (CPString)description { - // FIXME: I expect here locale should be some default locale return [self descriptionWithLocale:nil] } +/*! + Returns a string representation of the decimal number given the specified + locale. Note: locales are currently unsupported + @param locale the locale + @return a CPString +*/ - (CPString)descriptionWithLocale:(CPDictionary)locale { return CPDecimalString(_data, locale); } +/*! + Returns a string representation of the decimal number. + @return a CPString +*/ - (CPString)stringValue { return [self description]; @@ -628,148 +803,272 @@ var CPDecimalNumberHandlerRoundingModeKey = @"CPDecimalNumberHandlerRoundi } // Type Conversion Methods +/*! + Returns a JS float representation. Truncation may occur. + @return a JS float +*/ - (double)doubleValue { // FIXME: locale support / bounds check? return parseFloat([self stringValue]); } +/*! + Returns a JS bool representation. + @return a JS bool +*/ - (BOOL)boolValue { return (CPDecimalIsZero(_data))?NO:YES; } +/*! + Returns a JS int representation. Truncation may occur. + @return a JS int +*/ - (char)charValue { // FIXME: locale support / bounds check? return parseInt([self stringValue]); } +/*! + Returns a JS float representation. Truncation may occur. + @return a JS float +*/ - (float)floatValue { // FIXME: locale support / bounds check? return parseFloat([self stringValue]); } +/*! + Returns a JS int representation. Truncation may occur. + @return a JS int +*/ - (int)intValue { // FIXME: locale support / bounds check? return parseInt([self stringValue]); } +/*! + Returns a JS int representation. Truncation may occur. + @return a JS int +*/ - (long long)longLongValue { // FIXME: locale support / bounds check? - return parseFloat([self stringValue]); + return parseInt([self stringValue]); } +/*! + Returns a JS int representation. Truncation may occur. + @return a JS int +*/ - (long)longValue { // FIXME: locale support / bounds check? return parseInt([self stringValue]); } +/*! + Returns a JS int representation. Truncation may occur. + @return a JS int +*/ - (short)shortValue { // FIXME: locale support / bounds check? return parseInt([self stringValue]); } +/*! + Returns a JS int representation. Truncation may occur. + @return a JS int +*/ - (unsigned char)unsignedCharValue { // FIXME: locale support / bounds check? return parseInt([self stringValue]); } +/*! + Returns a JS int representation. Truncation may occur. + @return a JS int +*/ - (unsigned int)unsignedIntValue { // FIXME: locale support / bounds check? return parseInt([self stringValue]); } +/*! + Returns a JS int representation. Truncation may occur. + @return a JS int +*/ - (unsigned long)unsignedLongValue { // FIXME: locale support / bounds check? return parseInt([self stringValue]); } +/*! + Returns a JS int representation. Truncation may occur. + @return a JS int +*/ - (unsigned short)unsignedShortValue { // FIXME: locale support / bounds check? return parseInt([self stringValue]); } +// CPNumber inherited methods +/*! + Compare the reciever CPDecimalNumber to \c aNumber and return \e YES if + equal. + @param aNumber an object of kind CPNumber to compare against. + @return a boolean +*/ - (BOOL)isEqualToNumber:(CPNumber)aNumber { return (CPDecimalCompare(CPDecimalMakeWithString(aNumber.toString(),nil), _data) == CPOrderedSame)?YES:NO; } -// CPNumber inherited methods +/*! + Create a new CPDecimalNumber initialised with \e aBoolean. + @param aBoolean a JS boolean value + @return a new CPDecimalNumber object +*/ + (id)numberWithBool:(BOOL)aBoolean { return [[self alloc] initWithBool:aBoolean]; } +/*! + Create a new CPDecimalNumber initialised with \e aChar. + @param aChar a JS int value + @return a new CPDecimalNumber object +*/ + (id)numberWithChar:(char)aChar { return [[self alloc] initWithChar:aChar]; } +/*! + Create a new CPDecimalNumber initialised with \e aDouble. + @param aDouble a JS float value + @return a new CPDecimalNumber object +*/ + (id)numberWithDouble:(double)aDouble { return [[self alloc] initWithDouble:aDouble]; } +/*! + Create a new CPDecimalNumber initialised with \e aFloat. + @param aFloat a JS float value + @return a new CPDecimalNumber object +*/ + (id)numberWithFloat:(float)aFloat { return [[self alloc] initWithFloat:aFloat]; } +/*! + Create a new CPDecimalNumber initialised with \e anInt. + @param anInt a JS int value + @return a new CPDecimalNumber object +*/ + (id)numberWithInt:(int)anInt { return [[self alloc] initWithInt:anInt]; } +/*! + Create a new CPDecimalNumber initialised with \e aLong. + @param aLong a JS int value + @return a new CPDecimalNumber object +*/ + (id)numberWithLong:(long)aLong { return [[self alloc] initWithLong:aLong]; } +/*! + Create a new CPDecimalNumber initialised with \e aLongLong. + @param aLongLong a JS int value + @return a new CPDecimalNumber object +*/ + (id)numberWithLongLong:(long long)aLongLong { return [[self alloc] initWithLongLong:aLongLong]; } +/*! + Create a new CPDecimalNumber initialised with \e aShort. + @param aShort a JS int value + @return a new CPDecimalNumber object +*/ + (id)numberWithShort:(short)aShort { return [[self alloc] initWithShort:aShort]; } +/*! + Create a new CPDecimalNumber initialised with \e aChar. + @param aChar a JS int value + @return a new CPDecimalNumber object +*/ + (id)numberWithUnsignedChar:(unsigned char)aChar { return [[self alloc] initWithUnsignedChar:aChar]; } +/*! + Create a new CPDecimalNumber initialised with \e anUnsignedInt. + @param anUnsignedInt a JS int value + @return a new CPDecimalNumber object +*/ + (id)numberWithUnsignedInt:(unsigned)anUnsignedInt { return [[self alloc] initWithUnsignedInt:anUnsignedInt]; } +/*! + Create a new CPDecimalNumber initialised with \e aChar. + @param aChar a JS int value + @return a new CPDecimalNumber object +*/ + (id)numberWithUnsignedLong:(unsigned long)anUnsignedLong { return [[self alloc] initWithUnsignedLong:anUnsignedLong]; } +/*! + Create a new CPDecimalNumber initialised with \e anUnsignedLongLong. + @param anUnsignedLongLong a JS int value + @return a new CPDecimalNumber object +*/ + (id)numberWithUnsignedLongLong:(unsigned long)anUnsignedLongLong { return [[self alloc] initWithUnsignedLongLong:anUnsignedLongLong]; } +/*! + Create a new CPDecimalNumber initialised with \e anUnsignedShort. + @param anUnsignedShort a JS int value + @return a new CPDecimalNumber object +*/ + (id)numberWithUnsignedShort:(unsigned short)anUnsignedShort { return [[self alloc] initWithUnsignedShort:anUnsignedShort]; } +/*! + Initialise the receiver with a boolean \e value. + @param value a JS boolean value + @return a reference to the initialised object +*/ - (id)initWithBool:(BOOL)value { if (self = [self init]) @@ -777,61 +1076,121 @@ var CPDecimalNumberHandlerRoundingModeKey = @"CPDecimalNumberHandlerRoundi return self; } +/*! + Initialise the receiver with an int \e value. + @param value a JS int value + @return a reference to the initialised object +*/ - (id)initWithChar:(char)value { return [self _initWithJSNumber:value]; } +/*! + Initialise the receiver with a float \e value. + @param value a JS float value + @return a reference to the initialised object +*/ - (id)initWithDouble:(double)value { return [self _initWithJSNumber:value]; } +/*! + Initialise the receiver with a float \e value. + @param value a JS float value + @return a reference to the initialised object +*/ - (id)initWithFloat:(float)value { return [self _initWithJSNumber:value]; } +/*! + Initialise the receiver with an int \e value. + @param value a JS int value + @return a reference to the initialised object +*/ - (id)initWithInt:(int)value { return [self _initWithJSNumber:value]; } +/*! + Initialise the receiver with an int \e value. + @param value a JS int value + @return a reference to the initialised object +*/ - (id)initWithLong:(long)value { return [self _initWithJSNumber:value]; } +/*! + Initialise the receiver with an int \e value. + @param value a JS int value + @return a reference to the initialised object +*/ - (id)initWithLongLong:(long long)value { return [self _initWithJSNumber:value]; } +/*! + Initialise the receiver with an int \e value. + @param value a JS int value + @return a reference to the initialised object +*/ - (id)initWithShort:(short)value { return [self _initWithJSNumber:value]; } +/*! + Initialise the receiver with an int \e value. + @param value a JS int value + @return a reference to the initialised object +*/ - (id)initWithUnsignedChar:(unsigned char)value { return [self _initWithJSNumber:value]; } +/*! + Initialise the receiver with an int \e value. + @param value a JS int value + @return a reference to the initialised object +*/ - (id)initWithUnsignedInt:(unsigned)value { return [self _initWithJSNumber:value]; } +/*! + Initialise the receiver with an int \e value. + @param value a JS int value + @return a reference to the initialised object +*/ - (id)initWithUnsignedLong:(unsigned long)value { return [self _initWithJSNumber:value]; } +/*! + Initialise the receiver with an int \e value. + @param value a JS int value + @return a reference to the initialised object +*/ - (id)initWithUnsignedLongLong:(unsigned long long)value { return [self _initWithJSNumber:value]; } +/*! + Initialise the receiver with an int \e value. + @param value a JS int value + @return a reference to the initialised object +*/ - (id)initWithUnsignedShort:(unsigned short)value { return [self _initWithJSNumber:value]; From ddbba2253393e22bb5880be8efd83e470a5fbd3d Mon Sep 17 00:00:00 2001 From: Randall Luecke Date: Sat, 15 Jan 2011 18:10:28 -0500 Subject: [PATCH 11/17] Only set the outlineview column if it's the first column added. --- AppKit/CPOutlineView.j | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/AppKit/CPOutlineView.j b/AppKit/CPOutlineView.j index 5f9d81b49..93085e149 100644 --- a/AppKit/CPOutlineView.j +++ b/AppKit/CPOutlineView.j @@ -515,7 +515,7 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0, /*! Sets the table column you want to display the disclosure button in. - + If you do not want an outline column pass nil. @param aTableColumn - The CPTableColumn you want to use for hierarchical data. */ - (void)setOutlineTableColumn:(CPTableColumn)aTableColumn @@ -955,15 +955,16 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0, } /*! - @ignore - If the outlineTableColumn doesn't exist yet, we set it to the first column added. + Adds a new table column to the reciever. If this is the first column added it will automatically be set to the outline column. + Also see -setOutlineTableColumn: + NOTE: This behavior deviates from cocoa slightly. */ - (void)addTableColumn:(CPTableColumn)aTableColumn { - if (_outlineTableColumn === nil) - _outlineTableColumn = aTableColumn; - [super addTableColumn:aTableColumn]; + + if ([self numberOfColumns] === 1) + _outlineTableColumn = aTableColumn; } /*! @ignore From e656e0561b10b467105517763c495a6645ced4bd Mon Sep 17 00:00:00 2001 From: Randall Luecke Date: Sat, 15 Jan 2011 18:31:41 -0500 Subject: [PATCH 12/17] removeTableColumn: on the outlineview shouldn't allow removal of outlineTableColumn per cocoa. --- AppKit/CPOutlineView.j | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/AppKit/CPOutlineView.j b/AppKit/CPOutlineView.j index 93085e149..9f56ce8d0 100644 --- a/AppKit/CPOutlineView.j +++ b/AppKit/CPOutlineView.j @@ -958,6 +958,7 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0, Adds a new table column to the reciever. If this is the first column added it will automatically be set to the outline column. Also see -setOutlineTableColumn: NOTE: This behavior deviates from cocoa slightly. + @param CPTableColumn aTableColumn - The table column to add. */ - (void)addTableColumn:(CPTableColumn)aTableColumn { @@ -966,6 +967,16 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0, if ([self numberOfColumns] === 1) _outlineTableColumn = aTableColumn; } +/*! + @ignore +*/ +- (void)removeTableColumn:(CPTableColumn)aTableColumn +{ + if (aTableColumn === [self outlineTableColumn]) + CPLog("CPOutlineView cannot remove outlineTableColumn with removeTableColumn:. User setOutlineTableColumn: instead."); + else + [super removeTableColumn:aTableColumn]; +} /*! @ignore We overide this because we need a special behaviour for the outline column From c65bfd22a24f792e92c81b2e6a4b83dcf202a6cc Mon Sep 17 00:00:00 2001 From: Stephen Ierodiaconou Date: Sun, 16 Jan 2011 01:47:14 +0200 Subject: [PATCH 13/17] Use native javascript array for mantissa for big performance increase --- Foundation/CPDecimal.j | 122 +++++++++++++++++++++-------------------- 1 file changed, 62 insertions(+), 60 deletions(-) diff --git a/Foundation/CPDecimal.j b/Foundation/CPDecimal.j index eb5f267cd..58c53f218 100644 --- a/Foundation/CPDecimal.j +++ b/Foundation/CPDecimal.j @@ -146,20 +146,20 @@ function CPDecimalMakeWithString(string, locale) return CPDecimalMakeNaN(); // Representation internally starts at most significant digit - var m = [CPMutableArray array], + var m = [], i = 0; for (; i < (intpart?intpart.length:0); i++) { if (i >= CPDecimalMaxDigits) break; // truncate - [m addObject:parseInt(intpart.charAt(i))]; + Array.prototype.push.call(m, parseInt(intpart.charAt(i))); } var j = 0; for (; j < (decpart?decpart.length:0); j++) { if ((i + j) >= CPDecimalMaxDigits) break; // truncate - [m addObject:parseInt(decpart.charAt(j))]; + Array.prototype.push.call(m, parseInt(decpart.charAt(j))); } var dcm = {_exponent:exponent, _isNegative:isNegative, _isCompact:NO, _isNaN:NO, _mantissa:m}; @@ -177,7 +177,7 @@ function CPDecimalMakeWithString(string, locale) */ function CPDecimalMakeWithParts(mantissa, exponent) { - var m = [CPMutableArray array], + var m = [], isNegative = NO; if (mantissa < 0 ) @@ -187,15 +187,15 @@ function CPDecimalMakeWithParts(mantissa, exponent) } if (mantissa == 0) - [m addObject: 0]; + Array.prototype.push.call(m, 0); if (exponent > CPDecimalMaxExponent || exponent < CPDecimalMinExponent) return CPDecimalMakeNaN(); // remaining digits are disposed of via truncation - while ((mantissa > 0) && ([m count] < CPDecimalMaxDigits)) // count selector here could be optimised away + while ((mantissa > 0) && (m.length < CPDecimalMaxDigits)) // count selector here could be optimised away { - [m insertObject:parseInt(mantissa % 10) atIndex:0]; + Array.prototype.unshift.call(m, parseInt(mantissa % 10)); mantissa = FLOOR(mantissa / 10); } @@ -291,7 +291,7 @@ function CPDecimalIsOne(dcm) // exponent doesnt matter as long as mantissa = 0 if (!dcm._isNaN) { - if (dcm._mantissa && ([dcm._mantissa count] == 1) && (dcm._mantissa[0] == 1)) + if (dcm._mantissa && (dcm._mantissa.length == 1) && (dcm._mantissa[0] == 1)) return YES; } return NO; @@ -305,12 +305,12 @@ function _CPDecimalSet(t,s) t._isNegative = s._isNegative; t._isCompact = s._isCompact; t._isNaN = s._isNaN; - t._mantissa = [s._mantissa copy]; + t._mantissa = Array.prototype.slice.call(s._mantissa, 0); } function _CPDecimalSetZero(result) { - result._mantissa = [CPMutableArray arrayWithObject:0]; + result._mantissa = [0]; result._exponent = 0; result._isNegative = NO; result._isCompact = YES; @@ -319,7 +319,7 @@ function _CPDecimalSetZero(result) function _CPDecimalSetOne(result) { - result._mantissa = [CPMutableArray arrayWithObject:1]; + result._mantissa = [1]; result._exponent = 0; result._isNegative = NO; result._isCompact = YES; @@ -348,7 +348,7 @@ function CPDecimalCopy(dcm) _isNegative:dcm._isNegative, _isCompact:dcm._isCompact, _isNaN:dcm._isNaN, - _mantissa:[dcm._mantissa copy] + _mantissa:Array.prototype.slice.call(dcm._mantissa, 0) }; } @@ -373,8 +373,8 @@ function CPDecimalCompare(leftOperand, rightOperand) return CPOrderedAscending; } - var s1 = leftOperand._exponent + [leftOperand._mantissa count], - s2 = rightOperand._exponent + [rightOperand._mantissa count]; + var s1 = leftOperand._exponent + leftOperand._mantissa.length, + s2 = rightOperand._exponent + rightOperand._mantissa.length; // Sign is the same, quick check size (length + exp) if (s1 < s2) @@ -393,7 +393,7 @@ function CPDecimalCompare(leftOperand, rightOperand) } // Same size, so check mantissa - var l = MIN([leftOperand._mantissa count], [rightOperand._mantissa count]), + var l = MIN(leftOperand._mantissa.length, rightOperand._mantissa.length), i = 0; for (; i < l; i++) @@ -417,14 +417,14 @@ function CPDecimalCompare(leftOperand, rightOperand) } // Same digits, check length - if ([leftOperand._mantissa count] > [rightOperand._mantissa count]) + if (leftOperand._mantissa.length > rightOperand._mantissa.length) { if (rightOperand._isNegative) return CPOrderedAscending; else return CPOrderedDescending; } - if ([leftOperand._mantissa count] < [rightOperand._mantissa count]) + if (leftOperand._mantissa.length < rightOperand._mantissa.length) { if (rightOperand._isNegative) return CPOrderedDescending; @@ -444,8 +444,8 @@ function _SimpleAdd(result, leftOperand, rightOperand, roundingMode, longMode) _CPDecimalSet(result, leftOperand); - var j = [leftOperand._mantissa count] - [rightOperand._mantissa count], - l = [rightOperand._mantissa count], + var j = leftOperand._mantissa.length - rightOperand._mantissa.length, + l = rightOperand._mantissa.length, i = l - 1, carry = 0, error = CPCalculationNoError; @@ -467,7 +467,7 @@ function _SimpleAdd(result, leftOperand, rightOperand, roundingMode, longMode) if (carry) { - for (i = j-1; i >= 0; i--) + for (i = j - 1; i >= 0; i--) { if (result._mantissa[i] != 9) { @@ -480,13 +480,13 @@ function _SimpleAdd(result, leftOperand, rightOperand, roundingMode, longMode) if (carry) { - [result._mantissa insertObject:1 atIndex:0]; + Array.prototype.splice.call(result._mantissa, 0, 0, 1); // The number must be shifted to the right - if ((CPDecimalMaxDigits * factor) == [leftOperand._mantissa count]) + if ((CPDecimalMaxDigits * factor) == leftOperand._mantissa.length) { var scale = - result._exponent - 1; - CPDecimalRound(result, result,scale,roundingMode); + CPDecimalRound(result, result, scale, roundingMode); } if (CPDecimalMaxExponent < result._exponent) @@ -550,8 +550,8 @@ function CPDecimalAdd(result, leftOperand, rightOperand, roundingMode, longMode) // below is equiv of simple compare var comp = 0, - ll = [n1._mantissa count], - lr = [n2._mantissa count]; + ll = n1._mantissa.length, + lr = n2._mantissa.length; if (ll == lr) comp = CPOrderedSame; else if (ll > lr) @@ -605,8 +605,8 @@ function _SimpleSubtract(result, leftOperand, rightOperand, roundingMode) { var error = CPCalculationNoError, borrow = 0, - l = [rightOperand._mantissa count], - j = [leftOperand._mantissa count] - l, + l = rightOperand._mantissa.length, + j = leftOperand._mantissa.length - l, i = l - 1; _CPDecimalSet(result, leftOperand); @@ -628,7 +628,7 @@ function _SimpleSubtract(result, leftOperand, rightOperand, roundingMode) if (borrow) { - for (i = j-1; i >= 0; i--) + for (i = j - 1; i >= 0; i--) { if (result._mantissa[i] != 0) { @@ -759,10 +759,10 @@ function _SimpleDivide(result, leftOperand, rightOperand, roundingMode) _CPDecimalSetZero(result); - n1._mantissa = [CPMutableArray array]; + n1._mantissa = []; - while ((k < [leftOperand._mantissa count]) || ([n1._mantissa count] - && !(([n1._mantissa count] == 1) && (n1._mantissa[0] == 0)))) + while ((k < leftOperand._mantissa.length) || (n1._mantissa.length + && !((n1._mantissa.length == 1) && (n1._mantissa[0] == 0)))) { while (CPOrderedAscending == CPDecimalCompare(n1, rightOperand)) { @@ -771,19 +771,19 @@ function _SimpleDivide(result, leftOperand, rightOperand, roundingMode) if (n1._exponent) { // Put back zeros removed by compacting - [n1._mantissa addObject:0]; + Array.prototype.push.call(n1._mantissa, 0); n1._exponent--; n1._isCompact = NO; } else { - if (used < [leftOperand._mantissa count]) + if (used < leftOperand._mantissa.length) { // Fill up with own digits - if ([n1._mantissa count] || leftOperand._mantissa[used]) + if (n1._mantissa.length || leftOperand._mantissa[used]) { // only add 0 if there is already something - [n1._mantissa addObject:(leftOperand._mantissa[used])]; + Array.prototype.push.call(n1._mantissa, (leftOperand._mantissa[used])); n1._isCompact = NO; } used++; @@ -797,7 +797,7 @@ function _SimpleDivide(result, leftOperand, rightOperand, roundingMode) break; } // Borrow one digit - [n1._mantissa addObject:0]; + Array.prototype.push.call(n1._mantissa, 0); result._exponent--; } @@ -922,11 +922,11 @@ function _SimpleMultiply(result, leftOperand, rightOperand, roundingMode, powerM // Do every digit of the second number var i = 0; - for (; i < [rightOperand._mantissa count]; i++) + for (; i < rightOperand._mantissa.length; i++) { _CPDecimalSetZero(n); - n._exponent = [rightOperand._mantissa count] - i - 1; + n._exponent = rightOperand._mantissa.length - i - 1; carry = 0; d = rightOperand._mantissa[i]; @@ -934,7 +934,7 @@ function _SimpleMultiply(result, leftOperand, rightOperand, roundingMode, powerM continue; var j = 0; - for (j = [leftOperand._mantissa count]-1; j >= 0; j--) + for (j = leftOperand._mantissa.length - 1; j >= 0; j--) { e = leftOperand._mantissa[j] * d + carry; if (e >= 10) @@ -967,11 +967,11 @@ function _SimpleMultiply(result, leftOperand, rightOperand, roundingMode, powerM result._exponent += exp; // perform round to CPDecimalMaxDigits - if ([result._mantissa count] > CPDecimalMaxDigits && !powerMode) + if (result._mantissa.length > CPDecimalMaxDigits && !powerMode) { result._isCompact = NO; - var scale = CPDecimalMaxDigits - ([result._mantissa count] + result._exponent); - CPDecimalRound(result, result, scale ,roundingMode); // calls compact + var scale = CPDecimalMaxDigits - (result._mantissa.length + result._exponent); + CPDecimalRound(result, result, scale, roundingMode); // calls compact error = CPCalculationLossOfPrecision; } @@ -1027,8 +1027,8 @@ function CPDecimalMultiply(result, leftOperand, rightOperand, roundingMode, powe // below is equiv of simple compare var comp = 0, - ll = [n1._mantissa count], - lr = [n2._mantissa count]; + ll = n1._mantissa.length, + lr = n2._mantissa.length; if (ll == lr) comp = CPOrderedSame; else if (ll > lr) @@ -1183,8 +1183,8 @@ function CPDecimalNormalize(dcm1, dcm2, roundingMode, longMode) e2 = dcm2._exponent; // Add zeros - var l2 = [dcm2._mantissa count], - l1 = [dcm1._mantissa count], + var l2 = dcm2._mantissa.length, + l1 = dcm1._mantissa.length, l = 0; var e = 0; @@ -1202,16 +1202,16 @@ function CPDecimalNormalize(dcm1, dcm2, roundingMode, longMode) e = e1 - e2; if (e2 > e1) - l = MIN((CPDecimalMaxDigits*factor) - l2, e); //(e2 - e1)); + l = MIN((CPDecimalMaxDigits * factor) - l2, e); //(e2 - e1)); else - l = MIN((CPDecimalMaxDigits*factor) - l1, e); //(e1 - e2)); + l = MIN((CPDecimalMaxDigits * factor) - l1, e); //(e1 - e2)); for (var i = 0; i < l; i++) { if (e2 > e1) - [dcm2._mantissa addObject:0]; //dcm2._mantissa[i + l2] = 0; + Array.prototype.push.call(dcm2._mantissa, 0); //dcm2._mantissa[i + l2] = 0; else - [dcm1._mantissa addObject:0]; + Array.prototype.push.call(dcm1._mantissa, 0); } if (e2 > e1) { @@ -1246,7 +1246,7 @@ function CPDecimalNormalize(dcm1, dcm2, roundingMode, longMode) // Some zeros where cut of again by compacting if (e2 > e1) { - l1 = [dcm1._mantissa count]; + l1 = dcm1._mantissa.length; l = MIN((CPDecimalMaxDigits * factor) - l1, ABS(dcm1._exponent - dcm2._exponent)); for (var i = 0; i < l; i++) { @@ -1257,7 +1257,7 @@ function CPDecimalNormalize(dcm1, dcm2, roundingMode, longMode) } else { - l2 = [dcm2._mantissa count]; + l2 = dcm2._mantissa.length; l = MIN((CPDecimalMaxDigits * factor) - l2, ABS(dcm2._exponent - dcm1._exponent)); for (var i = 0; i < l; i++) { @@ -1301,7 +1301,7 @@ function CPDecimalRound(result, dcm, scale ,roundingMode) _CPDecimalSet(result,dcm); - var mc = [result._mantissa count], + var mc = result._mantissa.length, l = mc + scale + result._exponent; if (mc <= l) @@ -1350,7 +1350,7 @@ function CPDecimalRound(result, dcm, scale ,roundingMode) break; } // cut mantissa - result._mantissa = [result._mantissa subarrayWithRange:CPMakeRange(0, l)]; + result._mantissa = Array.prototype.slice.call(result._mantissa, 0, l); if (up) { @@ -1373,7 +1373,7 @@ function CPDecimalRound(result, dcm, scale ,roundingMode) // Overflow in rounding. // Add one zero add the end. There must be space as // we just cut off some digits. - [result._mantissa addObject:0]; + Array.prototype.push.call(result._mantissa, 0); } else result._exponent++; @@ -1392,7 +1392,7 @@ function CPDecimalRound(result, dcm, scale ,roundingMode) function CPDecimalCompact(dcm) { // if positive or zero exp leading zeros simply delete, trailing ones u need to increment exponent - if (!dcm || [dcm._mantissa count] == 0 || CPDecimalIsNotANumber(dcm) ) + if (!dcm || dcm._mantissa.length == 0 || CPDecimalIsNotANumber(dcm) ) return; @@ -1406,12 +1406,12 @@ function CPDecimalCompact(dcm) // if exp is zero does it make sense to have them? dont think so so delete them while (dcm._mantissa[0] === 0) { - [dcm._mantissa removeObjectAtIndex:0]; + Array.prototype.shift.call(dcm._mantissa); } // trailing zeros, strip them - while ([dcm._mantissa lastObject] === 0) + while (dcm._mantissa[dcm._mantissa.length - 1] === 0) { - [dcm._mantissa removeLastObject]; + Array.prototype.pop.call(dcm._mantissa); dcm._exponent++; if (dcm._exponent + 1 > CPDecimalMaxExponent) { @@ -1443,8 +1443,10 @@ function CPDecimalString(dcm, locale) if (dcm._isNegative) string += "-"; - var k = [dcm._mantissa count], + + var k = dcm._mantissa.length, l = ((dcm._exponent < 0) ? dcm._exponent : 0) + k; + if (l < 0) { // add leading zeros From 630cd121a65eac52b885db74245d77ce702f4449 Mon Sep 17 00:00:00 2001 From: Randall Luecke Date: Sat, 15 Jan 2011 20:40:24 -0500 Subject: [PATCH 14/17] Typo in docs --- Foundation/CPDecimalNumber.j | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Foundation/CPDecimalNumber.j b/Foundation/CPDecimalNumber.j index 761cf44f2..05b04e466 100644 --- a/Foundation/CPDecimalNumber.j +++ b/Foundation/CPDecimalNumber.j @@ -298,7 +298,7 @@ var CPDecimalNumberHandlerRoundingModeKey = @"CPDecimalNumberHandlerRoundi /*! Create a new CPDecimalNumber object uninitialised. - Note: eventhough CPDecimalNumber inherits from CPNumber it is not toll free + Note: even though CPDecimalNumber inherits from CPNumber it is not toll free bridged to a JS type as CPNumber is. @return a new CPDecimalNumber instance */ From c73e2e1a91dc7ae5787ee90d9d3e0c01d458452b Mon Sep 17 00:00:00 2001 From: Randall Luecke Date: Sat, 15 Jan 2011 21:45:37 -0500 Subject: [PATCH 15/17] Fix for nib2cib'd textfields jumping when editing --- Tools/nib2cib/NSTextField.j | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tools/nib2cib/NSTextField.j b/Tools/nib2cib/NSTextField.j index 1d9ca5561..d4dea04fa 100644 --- a/Tools/nib2cib/NSTextField.j +++ b/Tools/nib2cib/NSTextField.j @@ -68,8 +68,8 @@ { var frame = [self frame]; - [self setFrameOrigin:CGPointMake(frame.origin.x - 4.0, frame.origin.y - 4.0)]; - [self setFrameSize:CGSizeMake(frame.size.width + 8.0, frame.size.height + 8.0)]; + [self setFrameOrigin:CGPointMake(frame.origin.x - 3.0, frame.origin.y - 3.0)]; + [self setFrameSize:CGSizeMake(frame.size.width + 7.0, frame.size.height + 7.0)]; } CPLog.debug([self stringValue] + " => isBordered=" + [self isBordered] + ", isBezeled=" + [self isBezeled] + ", bezelStyle=" + [self bezelStyle] + "("+[cell stringValue]+", " + [cell placeholderString] + ")"); From bf4724d401a6769504b9cb089da67ad086409dc2 Mon Sep 17 00:00:00 2001 From: Randall Luecke Date: Sat, 15 Jan 2011 23:15:55 -0500 Subject: [PATCH 16/17] Fix for textfield jumping when textfield wasn't the right size or the vertical alignment was something other than center. --- AppKit/CPTextField.j | 34 +++++++++++++++++++++---- AppKit/Themes/Aristo/ThemeDescriptors.j | 1 + 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/AppKit/CPTextField.j b/AppKit/CPTextField.j index 91cae055a..ab9a6ed9d 100644 --- a/AppKit/CPTextField.j +++ b/AppKit/CPTextField.j @@ -486,11 +486,15 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); #if PLATFORM(DOM) var string = [self stringValue], - element = [self _inputElement]; + element = [self _inputElement], + font = [self currentValueForThemeAttribute:@"font"]; + + // generate the font metric + [font _getMetrics]; element.value = string; element.style.color = [[self currentValueForThemeAttribute:@"text-color"] cssString]; - element.style.font = [[self currentValueForThemeAttribute:@"font"] cssString]; + element.style.font = [font cssString]; element.style.zIndex = 1000; switch ([self alignment]) @@ -502,12 +506,32 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); default: element.style.textAlign = "left"; } - var contentRect = [self contentRectForBounds:[self bounds]]; + var contentRect = [self contentRectForBounds:[self bounds]], + verticalAlign = [self currentValueForThemeAttribute:"vertical-alignment"]; - element.style.top = _CGRectGetMinY(contentRect) + "px"; + switch(verticalAlign) + { + case CPTopVerticalTextAlignment: + var topPoint = (_CGRectGetMinY(contentRect) + 1) + "px"; // for the same reason we have a -1 for the left, we also have a + 1 here + break; + + case CPCenterVerticalTextAlignment: + var topPoint = (_CGRectGetMidY(contentRect) - (font._lineHeight / 2) + 1) + "px"; + break; + + case CPBottomVerticalTextAlignment: + var topPoint = (_CGRectGetMaxY(contentRect) - font._lineHeight) + "px"; + break; + + default: + var topPoint = (_CGRectGetMinY(contentRect) + 1) + "px"; + break; + } + + element.style.top = topPoint; element.style.left = (_CGRectGetMinX(contentRect) - 1) + "px"; // why -1? element.style.width = _CGRectGetWidth(contentRect) + "px"; - element.style.height = _CGRectGetHeight(contentRect) + "px"; + element.style.height = font._lineHeight + "px"; // private ivar for the line height of the DOM text at this particaulr size _DOMElement.appendChild(element); diff --git a/AppKit/Themes/Aristo/ThemeDescriptors.j b/AppKit/Themes/Aristo/ThemeDescriptors.j index 838d32a78..dddf67ef8 100755 --- a/AppKit/Themes/Aristo/ThemeDescriptors.j +++ b/AppKit/Themes/Aristo/ThemeDescriptors.j @@ -804,6 +804,7 @@ var themedButtonValues = nil, // Global for reuse by CPTokenField. themedTextFieldValues = [ + [@"vertical-alignment", CPTopVerticalTextAlignment, CPThemeStateBezeled], [@"bezel-color", bezelColor, CPThemeStateBezeled], [@"bezel-color", bezelFocusedColor, CPThemeStateBezeled | CPThemeStateEditing], [@"bezel-color", bezelDisabledColor, CPThemeStateBezeled | CPThemeStateDisabled], From 8720a952b0c7a762ad86f09f3af69542c8e30a66 Mon Sep 17 00:00:00 2001 From: Randall Luecke Date: Sun, 16 Jan 2011 00:23:14 -0500 Subject: [PATCH 17/17] Fix for scrollview flashing while uniformly resizing columns. Closes #1075 --- AppKit/CPTableView.j | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/AppKit/CPTableView.j b/AppKit/CPTableView.j index a0a456b6c..8de0541c5 100644 --- a/AppKit/CPTableView.j +++ b/AppKit/CPTableView.j @@ -1933,6 +1933,13 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; } } } + + // now that we've reached the end we know there are likely rounding errors + // so we should size the last resized to fit + var delta = superviewWidth - _CGRectGetMaxX([self rectOfColumn:[self numberOfColumns] - 1]), + newSize = [item width] + delta; + + [item _tryToResizeToWidth:newSize]; } /*!