Spam detection software, running on the system "europa.mgmt.inetu.net", has
identified this incoming email as possible spam. The original message has been attached to this so you can view it (if it isn't spam) or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: Ricardo Moran uploaded a new version of Skeleton to project Etoys Inbox: http://source.squeak.org/etoysinbox/Skeleton-Richo.1.mcz ==================== Summary ==================== Name: Skeleton-Richo.1 Author: Richo Time: 14 October 2011, 7:52:01 pm UUID: 1e40d535-a560-e247-ba6b-7e2cda5b8ba3 Ancestors: [...] Content analysis details: (7.4 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 3.5 BAYES_99 BODY: Bayesian spam probability is 99 to 100% [score: 1.0000] 0.0 MISSING_MID Missing Message-Id: header 1.2 INVALID_DATE Invalid Date: header (not RFC 2822) 1.0 DATE_IN_PAST_12_24 Date: is 12 to 24 hours before Received: date 1.7 TVD_FUZZY_SYMBOL BODY: TVD_FUZZY_SYMBOL 1.0 FUZZY_AMBIEN BODY: Attempt to obfuscate words in spam 0.8 SARE_OBFU_PART_INA BODY: obfusciation of word containing ina 3.8 TVD_STOCK1 BODY: TVD_STOCK1 0.1 RDNS_NONE Delivered to trusted network by a host with no rDNS -5.7 AWL AWL: From: address is in the auto white-list Ricardo Moran uploaded a new version of Skeleton to project Etoys Inbox: http://source.squeak.org/etoysinbox/Skeleton-Richo.1.mcz ==================== Summary ==================== Name: Skeleton-Richo.1 Author: Richo Time: 14 October 2011, 7:52:01 pm UUID: 1e40d535-a560-e247-ba6b-7e2cda5b8ba3 Ancestors: Integrating Skeleton-Base-0.4.1 with a few modifications from me: * Added SkSheetMorph>>#width: and #height: so that changing the Spreadsheet's extent from the viewer works. * Added "spreadsheet" viewer category, with a few slots and commands to iterate over the contents of the spreadsheet. * Added "data i/o" viewer category, which allows you to import/export data from/to csv files. It requires the CSV package, which I'll upload in a separate commit. ==================== Snapshot ==================== SystemOrganization addCategory: #'Skeleton-Base'! SystemOrganization addCategory: #'Skeleton-Base-Sheet'! Parser subclass: #SkParser instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Skeleton-Base'! ----- Method: SkParser class>>pointToA1Name: (in category 'support') ----- pointToA1Name: aPoint "(self new pointToA1Name: 1@1) = 'A1' (self new pointToA1Name: 10@10) = 'J10' (self new pointToA1Name: 100@100) = 'CV100'" | base i dest remain xPos | base _ 26. dest _ aPoint x. i _ 1. xPos _ (String streamContents: [:aStream | [dest > 0] whileTrue: [remain _ dest \\ (i * base). dest _ dest - remain. aStream nextPut: (Character value: 64 + (remain / i)). i _ i * base]]) reverse. ^ xPos , aPoint y printString! ----- Method: SkParser>>A1Node:interval: (in category 'error correction') ----- A1Node: proposedVariable interval: spot | receiver argument | receiver _ encoder encodeVariable: 'holder' sourceRange: spot ifUnknown: [encoder undeclared: proposedVariable]. argument _ encoder encodeLiteral: (self cellPositionOf: proposedVariable). ^ MessageNode new receiver: receiver selector: #at: arguments: (Array with: argument) precedence: 3 from: encoder! ----- Method: SkParser>>cellPositionOf: (in category 'error correction') ----- cellPositionOf: aString "(self new cellPositionOf: 'A1') = (1@1)" "(self new cellPositionOf: 'B2') = (2@2)" "(self new cellPositionOf: 'CV100') = (100@100)" | col | col _ aString stemAndNumericSuffix first inject: 0 into: [:subTotal :next | subTotal _ subTotal * 26. subTotal _ subTotal + next asciiValue - $A asciiValue + 1]. ^ col @ aString stemAndNumericSuffix second asNumber! ----- Method: SkParser>>correctVariable:interval: (in category 'error correction') ----- correctVariable: proposedVariable interval: spot | receiver argument | (self isA1Name: proposedVariable) ifTrue: [^ self A1Node: proposedVariable interval: spot]. receiver _ encoder encodeVariable: 'holder' sourceRange: spot ifUnknown: [encoder undeclared: proposedVariable]. argument _ encoder encodeLiteral: proposedVariable. ^ MessageNode new receiver: receiver selector: #findName: arguments: (Array with: argument) precedence: 3 from: encoder"^ encoder global: #Moge -> 1 name: #Hoge"! ----- Method: SkParser>>isA1Name: (in category 'testing') ----- isA1Name: aString " (self new isA1Name: 'A1') = true. (self new isA1Name: 'XYZ123') = true. (self new isA1Name: '123') = false. (self new isA1Name: 'ABC') = false. (self new isA1Name: 'Abc') = false. (self new isA1Name: 'abc') = false. (self new isA1Name: 'Hello12') = false. " | begin end number | begin _ aString indexOfAnyOf: ($A to: $Z) asCharacterSet startingAt: 0. begin isZero ifTrue: [^ false]. end _ aString indexOfAnyOf: ($A to: $Z) asCharacterSet complement startingAt: begin. end isZero ifTrue: [^ false]. number _ (aString allButFirst: end - 1). ^ (number anySatisfy: [:c | c isDigit not]) not! ----- Method: HaloMorph>>endInteraction (in category '*skeleton-base-sheet') ----- endInteraction "Clean up after a user interaction with the a halo control" | m | target endHaloInteraction. self isMagicHalo: false. "no longer" self magicAlpha: 1.0. (target isInWorld not or: [owner isNil]) ifTrue: [^self]. [target isFlexMorph and: [target hasNoScaleOrRotation]] whileTrue: [m := target firstSubmorph. target removeFlexShell. target := m]. self isInWorld ifTrue: ["make sure handles show in front, even if flex shell added" self comeToFront. self addHandles]. (self valueOfProperty: #commandInProgress) doIfNotNil: [:cmd | self rememberCommand: cmd. self removeProperty: #commandInProgress]! ----- Method: PhraseTileMorph>>arrowTargets (in category '*skeleton-base-arrow') ----- arrowTargets ^ Array with: 'player' -> self actualObject! ----- Method: PasteUpMorph>>createOrResizeTrailsForm (in category '*skeleton-base-pentrail') ----- createOrResizeTrailsForm "If necessary, create a new turtleTrailsForm or resize the existing one to fill my bounds. On return, turtleTrailsForm exists and is the correct size." | newForm | turtleTrailsForm ifNil: ["create new TrailsForm if needed" turtleTrailsForm _ Form extent: self extent depth: 32. turtleTrailsForm fillColor: self color. turtlePen _ nil]. turtleTrailsForm extent = self extent ifFalse: ["resize TrailsForm if my size has changed" newForm _ Form extent: self extent depth: 32. newForm fillColor: self color. newForm copy: self bounds from: turtleTrailsForm to: 0@0 rule: Form paint. turtleTrailsForm _ newForm. turtlePen _ nil]. "Recreate Pen for this form" turtlePen ifNil: [turtlePen _ Pen newOnForm: turtleTrailsForm. turtlePen combinationRule: Form blend].! ----- Method: PasteUpMorph>>runStepMethods (in category '*skeleton-base-sheet') ----- runStepMethods "dirty hack" worldState runStepMethodsIn: self. (self valueOfProperty: #SkStepList) ifNotNilDo: [:m | m do: [:s | s safetyResolve]]! ContextVariablesInspector subclass: #SkCellInspector instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Skeleton-Base'! ----- Method: SkCellInspector class>>holder:key: (in category 'initialize-release') ----- holder: holder key: key ^ self new holder: holder key: key! ----- Method: SkCellInspector>>contents (in category 'accessing') ----- contents ^ self holder textAt: self key! ----- Method: SkCellInspector>>contents: (in category 'accessing') ----- contents: textOrString ^ self holder textAt: self key put: textOrString! ----- Method: SkCellInspector>>holder (in category 'accessing') ----- holder ^ object ifNotNil: [object tempAt: 1]! ----- Method: SkCellInspector>>holder:key: (in category 'accessing') ----- holder: holder key: key | cell context | self holder ifNotNil: [self holder removeDependent: self]. holder addDependent: self. cell _ holder cellAt: key. context _ MethodContext sender: holder receiver: cell method: SkNullCell >> #resolveContextOn:at: arguments: {holder. key}. self inspect: context! ----- Method: SkCellInspector>>key (in category 'accessing') ----- key ^ object tempAt: 2! ----- Method: SkCellInspector>>update: (in category 'update') ----- update: aSymbol self changed: #contents! PackageInfo subclass: #SkeletonBaseInfo instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Skeleton-Base'! !SkeletonBaseInfo commentStamp: 'tak 4/10/2004 22:24' prior: 0! This is a spreadsheet package in Skeleton. To open a spreadsheet, try SkSheet open. -- workspace -- * package building SkeletonBaseInfo fileOutSar. SkeletonConnectorsInfo fileOutSar. * make change set to current project * self makeChangeSetForThisPackage * benchmark MessageTally spyOn: [1000 timesRepeat: [World runStepMethods]] * It's useful for debug set/unset when old project is hung. SkGridMorph>>isDebug * sound initialize * self createSoundLibFromWav: 'sound\cas.wav' name: 'cassete' self createSoundLibFromWav: 'sound\cork.wav' name: 'cork' self createSoundLibFromWav: 'sound\arrow.wav' name: 'arrow' self createSoundLibFromWav: 'sound\mochi.wav' name: 'mochi' self createSoundLibFromWav: 'sound\unstick.wav' name: 'unstick' self createSoundLibFromWav: 'sound\rice.wav' name: 'rice' * Initialize Compiler evaluate: self new postscriptText * stepping list (World valueOfProperty: #SkSheet) ifNotNilDo: [:set | set asArray] * for DEMO TTCFont newTextStyleFromTTFile: 'C:\WINDOWS\Fonts\verdana.ttf'. TTCFont newTextStyleFromTTFile: 'C:\WINDOWS\Fonts\pala.ttf' * debug for Babel Language subclass: #Romaji instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Babel-Kernel'. Romaji compile: 'name ^ #Romaji'! ----- Method: SkeletonBaseInfo class>>addClass:toChangeset: (in category 'fileIn/Out') ----- addClass: aClass toChangeset: aChangeSet aChangeSet addClass: aClass. aChangeSet commentClass: aClass. aClass selectors do: [:aSymbol | aChangeSet adoptSelector: aSymbol forClass: aClass]. aClass class selectors do: [:aSymbol | aChangeSet adoptSelector: aSymbol forClass: aClass class]. ^ aChangeSet! ----- Method: SkeletonBaseInfo class>>addPseudoMethodForBabel (in category 'class initialization') ----- addPseudoMethodForBabel "This method supports both 3.6 and 3.7" "self addPseudoMethodForBabel" | addMethodBlock | addMethodBlock _ [:class | class compileInobtrusively: 'translated ^ self' classified: 'forward compatibility']. ['Can you translate?' translated] on: MessageNotUnderstood do: [:ex | addMethodBlock value: (Smalltalk at: #AbstractString ifAbsent: [^ addMethodBlock value: String])]! ----- Method: SkeletonBaseInfo class>>arrow (in category 'sound library') ----- arrow SampledSound addLibrarySoundNamed: 'arrow' samples: (self mimeStringToBuffer: '/WD9a/0g/N78nvx0/Kv9Rv39/qz/gACQAYsCGAIjAfIB9AJeAxgD2AREBGsElgTABOoFHAU9 BU4FPwTpBIMEOwP+A+gEGQRSBDQDrQMcAr4CWwHeAXIBKwEjAUgBRwEFAKQASwAF/6P/C/50 /g792P3D/bL9hP0i/G77efqF+dL5hvmf+fH6Wfrl+6D8P/xr/GL8q/1b/hj+oP8a/9sA3QGy AfMBnwEdAMcAoQCxARABsgKUA6AEfgTjBL8EPgPcA+EEBgQFA90DfAK9AcMBMgGYAqwDkAPe A9MDpQM8AqgCXQKuA2YEDQRnBIgEjARwBCUDtAMdAlQBYwBv/6X/Gf6Z/gb9sf3V/gD9pvzD ++b7oPvS++373fva++H75fwL/HD83v0P/S79nP5R/xf/xgA1AG4AjgBe/6/+8f62/v3/RP78 /hn9JfyP/Dz8H/wv/Bb70/vj/HD9Iv1m/Nr7yPq7+cf4sveN9rP2LfXZ9ib3XfkM+sv8dv4D /5QBFgKFBEoGjwkYC1oMewyjDO0NwA70EF4RhxI4EmkR5hDhD8YOhw0UC8QK3QnxCGAGkAU8 BDEC4gDt/lb70voH+PT4SPd29kb1D/Pj8qDxSu+67fvsOepP6I7nnud559vos+mi6mTrge2s 8KbzvPb9+pj+EgE6BC0GvgkbC80O4hITFQEXTxkKGlsbKBtCGn8ZCBd8FnoWCBWVFJYS4RCC DbUK6Ag+BZMCsP9W+5r3/PSH8NXtJuom58rl6OUe5bPm0+fQ6L/p/+vl7j3wV/H483r1WvgD +4b/8gUmCfMNEA6HDuIOUQ08DK8NJQ2ADMkMCgzYD10SLRO2FAoUFhP2E6ATHhIVEHgOQQsK BwECZPzG9ibvYOmn5d/jvuJV4TjgdOBf4UXjCOWv6UvthfIP9tf8BgGFBkEJkQvXDMUMHQq7 CRUHSwX/BhUIHAriDGIMaQvCCs0KEQnzCikJhAZ7AU78S/nf+yb+zwGaATz+O/rh+O74Vvf8 98b5Ov0XAgIGHAhECLUJZwxOEOwUghUTE3kR4BFZEQgPGQtYB+IGlQbaBhUCjP1s+SP2m/Ry 8P3s3eqJ60rteO5D7RjroOtp7Hns6utC6RbpIuxY8UD1Zvgo+xz/zwZjDVkTVxisHWsgXyD/ IBwe3R4fHhsd3BvxGEkT8Q95CtQFff8e+PP08POv9AD0D/L/8O3uAeql5/TnCed753vmkOaD 6OftAfDD8/T4eP57A5QGeAivDAAQBxOnFsoZRRn7F9UTKA3PCMQDVf1E92PzB/D/8IvwufD0 78rsn+k556/n7ee/5gDkn+XA6RztTfHQ9vL81wNDCZYPdhVsG3EgtiUtKLYqdSo+KNgnFCUH IlgfBBrwFgEQdgotA0z8vfc/8zvwXO2f6sbodOb35X3i1N883Fvbjdzc34XjV+gx7Tbx4PZW +2MBwQhtDhAStRY2GDgZQxnpGgoYtxUWD4YJLwL9/QH3MvMA8hLzsfVE9OfzJ/I586r20vkZ +Hv1OfEM7j7uafFf9gr7UgDIBqYMqBJ8GCMc7yCfJAgnVyoVK9EsFSsKKR8mXCL0H10bfhbn EZMLgwSM/TT2VfDR7frtru0+6mLlPN942z3ZvNoQ2mjaD9n924re2+Lt5yzr5fE49xP9pASL CvwQzxZAG1sgHCRHJxcn3SbTJOYi4yEdHz8clhkSFUYSIBCbEA8OJwn2BMT/ifoG8/rtoOdY 4b3dYNpP2LnZQNt73Zveut+04QfiJOL25G7nx+za8an1f/oiAC4FsQivCRoJFgriDfsPfw0E BqD+svg/9Yj2+ftcAYEIng9xFHYW2ReAGIMaohyGHL4a8Rd8EuMNnwftAeT7tfVU7nbnlOGw 3VXat9m02cLar9yM30fi7OeH7PDzF/nyAVII8BCDF4Uc/CBMIhwjPiNZIc0e6RuYGBQTyw6j CNACQPtT9F/tGOYS4I3crNoG2E3XQddW2Qzb2t8y4wHm/er/7t/xyvPc9vD8BAHIBtYLihE4 GCEfDCUFKaosFyviKgsn1SYfJT4kpCN6IRcdaxmUFr8UhBFDDDMHQQVSBcsE0gB1+l70re/h 6+npd+kC6VXonOY84ubf7N8I4Rjk5Ojt7XbyrvcF+TD6BvtX/b4AVQJjBDcG6gvZEncXnBjo FxMUNRG/EBQPFw4pC8cG0//s+HzxMenw4xfduNpE2KrY59nx2sLcB95y4cnlvunA7azyBva+ +7ABQwetDuIWOxyzIoUoUC1PMCowfC9FLcIr/im2Jw0j3CBIHK0YyhRaD0wJoAOd/Rj14e6/ 6BbhotvH1yfUPNN91KbW2dmX3L7gOeQC6EDtIPKe+Lr/fAa5DlYWEh0oIo8lmibZJ6soWyhI JwMkeiE4HboZvRVFEGUKrwSQ/sb5CvNU7lTqZOcu45ffAdq42GjYitpm3DTcpNyW3a7gaORR 6JvsS+7o8T31A/rcAXQHkw1+E70aMCBKJXIpVyvlLT8t5y33LN8qrCf5JMwhPR3fGsoXbhNK DogKMwc3BMoBB/tU9Rnv9ewe6F7ji94C2WbXAtbA11HXWNZ61W/VWta+2RzcBt9H4kjlJejQ 7V/yFPZ9+rn/YgTeCsgQnRZKG/chhyYiKSUq+CxPLa4vMzACL0MtIyoKJl4iyh+PHE8YrRRh D3MKVwUG/vL4HPFD6y7mIeGa3OPYMdSn01XUFdWg1xfYhNoE27Td2+B942jmf+nu7eryNfac +34A4QZSC6oQ9haEHJciiydfKnUrgSszKuIrECttK1Ap5Cc+JFYhmh62G2EXkRMxDgYILAIx /NL4nfUH8Onskuks5rLk8+Rb5HnkFOK04NLe7tzt2wDaU9tv3WnfauFe44zmVOl47CPuW/Fq 9j378gEPBTIIaQpxC4AMRw1rDxkQVQ+4DQYJtgiLCzcP3BLYEqcQwA+cELUUAxgrGs0aJRbc E44SxRUmGQobvxs+F4cSbw4QC8gLfQuAClUHrAPG/4z8BPlN9xn03/GU7IvmVODa3hPeK+Bx 5KPpmOzb7KrpyOdy6IvtAfKq9uz35/YM9Cf1Q/o/ASEG/wqdDNwPchNJF6Ma1RwhHE0cdRze HMkbUhiJFPEQrAw7CHMFHQF4/UX4O/IL62rlzOIE3//f4+HT5Drkd+Gq3b7bvd0P4IXknOkr 7kbzY/gB+7j+Cf8pAIcDUwb8CYkJagc8BTkE2AYvCQYM3xD3FK4XLBd7FZMSaA9dDg0PORG2 E48TshG/DdoJdgaxBj4HCwgRCSEJ3gm4CPgITAe1BqUEyQLnAosEBgXIBgEEFwC//Rn6Bvfa 9iX0fvM98oryFvHs8kzzF/Oc8tLwb+3C7ODu6PLG9dr2H/Oi8FTuZO5L7rvuwO8X8L/y+PQG 8z7xjfCd8bL1DPnD/lICJAW1CIsJdgjLCG0KOg5rExEWBxayFasToBDiDoMOdhEdFMMXhBgn FncTGA7ECq8IXAg0CSsJXAflBeQEIAGR/VX4XvTd84zyp/DQ7pXsvOuQ6qTpIud05zzpme4W 8vr3E/p1/N79Xfuy+N72cPWc9r748Ppp+oP6LPnx+X/4Y/aw9cD2//oE/Un/4AHbA8IFcwY4 BesFFARTBAsEgQXfB8EJKglhCJAHlAbVBZ4DiAGaAUgCwgTVBsoI5ArgDCQMpgxNC1EKsgsC C/sM9g1JDI0KcwdFBCwBjP7R/C/6efoC+mz6v/o/+Qn3m/aI9hr2P/cr+NL6FPnM+CH2XPWO 9X71i/YC95D55PuZ+5P5+Pfg9r73e/lf+xz8Rvy+/Dn7Fvpq+xP9Fv/nAuAFAwVWBDMDAgKS AmYBoACRAI0B1AMXA0MCkwIpAqsDXwNLArQCsAPeBgcIfwqCC7YMhg1HDYkNDQxGC7QL9g1z D10QCg6PC8oJsgk5CUsITgYFA8UC0wL/Aw4B9v/L/ZT8FPs6+oL5YfgP9zv2y/ZK9av1PvXZ 96/5g/pp+pn6bvoH+ZP5gPoS+uv71fzi/ab92P1q/BT6RvkL+ND5L/lO+LT3o/ZD9Q/1L/bA +JX6E/ui/Xr/PgDtAp4DkAO6BLIHQgpaDK8OAw9VEasU3hfrGZYZmxlQGaQaEhoYGcYZTxjY GFkXtxayFRgTHBD3DsMMvwqnB8sEDgAr/Sv7RPms98r1gvL/8Pfvwu737k7tk+yT65vrD+sx 7BntdO8o8Wzz+/Yx94r33fe2+AL5N/sO/Mf91/4i/dP9dv2S/ib+6f+A/7H/k/8s/nj9zP2F /cz+X/6F/iP99P52/6EBAwHzAn8DSASBBfcHUAg1CMAJWwplC/YNeg5zDzQQKhFUEmoS2xJY EU8QWg+lDsgNLQrxCNEHFQVtA4gBVv8M/Rn7q/qJ+Y34rvfK9033ufhV+BP3EfYB9Un1AfUK 9Tr1bvW49lT3FveI96L3kfds96X4v/qG/Av8vfzV/K/8hPyO/KH8U/vU++39Df6d/7kAOwBv ALEBXwJIAtoC9gMNA8kFWgbtB6wHqAdyB2kHUgbdBkgFzAVbBQkEwQQyAygBzwDHAFX/6v8E /bP8hPwv/Kb9Evzq/Fb7wPsh+iT5AvgI9xf2U/XY9V/01vRh9Bv0MfSN9Of1KfVS9XP1xvaU 9/b5Zvpc+x/8Gf0w/if+zf8b/zX/R/98/6//mv+I//EA4gIlA1QEPwUZBcAF5QWQBScFaAab B+AIfQizCNsJAAjsCGwH3Ae9CCAIuAjqCEoHRAaQBkQGEQXvBfoF5wV6BNMD0wI1ADn+VPzZ +/b7a/ql+Tv3OvUh813yBvE68O/wqvAk75vvT+9G74fwNvFB8mHzc/RC9Jr00fWM9yv5l/xM /skA7QLJBJwGqAjPCtEMfQ3HDv0QTxE3ESEQNA8QDhMNHgvmCjgICAWSAx8Axv53/B/5xfeR 9ab0HPLU8YbwNe7+7cHsn+vt69fsle488IHy+/U49yP5K/uI/j4BaQSsB2wJoQuCDTMO1BBY EagSxxOfFAYT7hNMEg8QOQ4nDHELVQpzCSMHIwTlAvEBOf9J/N76Rff99f/z6PHH8C7vmO/1 8LjxbPI183/1Wfc3+Jv5r/rF+738hv11/nb+9P8U/7kBHgK2A+EEVgRgBJUFMgXhBiEGBAYF BfsFgQTMBB4DnANAApQBcgAc/p79WPzD/J38tv0m/av+Jf62/3QAggGwAq8DggQFBDQEWgQ0 AzEBeP++/nH9X/xY+436+PqV+qD61frZ+vD7UvvY/Dj8Gvts+lL5FfhL+EL4yPmZ+mj7GvvN /HT9AP2Y/j/+yv8W/zr/bv+d/4H/MP8H/yv/b/+4ABMAUwBqAMwB2wN5BRsGEwZYBoUHEwgX CTYJ7gpQCsILWwvBC4UKsAm7CQYImQf9BsQFbgTJBPoFjQXMBWsFAgUVBWgFcQTpBDYD8AQI BAQDqQMtAuACpgI/AcIBUwDTAB7/NP5R/bL9b/22/pz/0AEKAhwCzgMsA4UD4wQSBCIEXwTe BWQF0AYHBa4EjALtAUD/yf7F/iX9bPxN+vf53fmK+hf66Ptf+0f60fpx+nD6hvpB+aj5QPlY +b76LPp1+pv6//vL/MP94v8sAE0BGQGpAhICZwKxAwMDfwQNBIEE2AT5BKoD6AL+AlYCGAH7 AbIBOQDTAN8BYwHzAiUB7wHAAfkCZAKeAocCSQJHAqoDTAQcBOYFaAXbBmsGzAbJBoMGcwbx B5AHuwdgBqAFnQRpAwgBkAAO/qf9yP1u/Rb8ZPs8+fj5U/mN+mr7sPzp/Y39pf2Y/b3+Ov8K AA0BDAHEAisCjwMNA2EDlwPpBD8EqwVUBdgF4AV3BLAD2QNBAskCJAEF/2/90Pxz+136evmO +G/3EPVn88HydPFs8H3vmu7n7rXu++9l79/wivF88pzzsfSG9Sj2Efe3+dH76f3t/9EBkAN5 BckIRQpYC70Mww2jDksOuw8eD7QQaxDtEWMR/RJHEfURFQ+nDeUMMgq7CYMIbwdaBjoFJQRD A08Bzv/l/gL8Q/rU+dX5Gfh599P3Mfbq9yL3tviF+UX5vPoG+mn7Evvm/Kv9cv5y/6AAvQFy AXMA3wAv/7L/b/9D/xL+9P80/+cAqgEUASoBOQGKAisCxAMGA0cD2QRbBFYD4wNjAx4DAAKZ AZwANv7f/hr+Av4g/g/92f2x/bn98P4d/jH+eP8mABoBCAGvAdcBXwB9/5//C/7x/07/if8C /dL8fPti+oT5nPjL+Kv5bvp7+xn7LPsi+1r73/x2/Mr86f0B/PD8yPzb/UX9+v7D/1X/sQAL AIUBEAFvAagCBwKMAw4DQQLnAmcCTgKYAu4C3gJUAcQBZQEXAMAAPP+p/zH+vf6M/t7/Sf+W ABIAuQEhAQ4A1QDvAUABkAH0AjQCCwGVAOgAGv+D/1r/cv+R/9kAXADCAOoBCwFKAcYCYQKp ApYCeQJvAosCkwIMASIAT/9p/kD9HPwg+0L6ifnp+Ur4qfgD93P3Pfdi95j3u/fs+GL5O/pZ +2L7/Pwy/J39vv9BAE0AiABrALUBgwI/AocCiQKJArEC8wLzAocB3AEuANMA8AE1AVABSgF2 Ag0CwgMeAvMCXgHiAfECXwLxA3QDkgOIA9gEcAUBBUQFKAUOBQcE2QSYBDwDkwLVAkcB3QFG AEj/Ef3n/P78dPvg+rT5APcp9an04fSq9KH0svUM9bj2cPb/92v3yPiM+hP7zf0k/iH+8P/h AR0CUwM2A7MD5wQrBJ0FFQVwBaIF0QYABfYF0wWyBX4FSwTqBD0DswNFAnABOwAL/z/+5/6g /jX9rvzo/AH7Yfsu+zn7JfrT+oj6a/qN+uj7Nftm+7D8Ffx5/LD8p/yV/KH8z/0t/ar+Lv6s /wH/UP//ARcCLALMAuACuwLAAxADiAP0BGUE4wVJBaQGBwZpBsMG9AbuBrkGKwVdBMMETwO0 AtoBsQBT/tb9Mfun+nn5nPj6+D/3RvaW9ln2M/Ya9h32Ofa+98X41PmC+fn6v/wL/Z//MgCc AeIDNASzBkoHyAkJCgAKmwrhCvYK2Ap5CfUJWAiXB6kGiwVUBAwClADi/y/9v/x++xf5g/gc 9yn2n/Y+9ev1pvVe9U31xPaa96n4+/pL+278iv2s/tL/6ADkAfcDDgPsBJwFLQXGBocHIwd0 B68H8AhVCLIImgg6B9UHQAaPBegFKwRaA5QC/gKbAgkBHQAA/r39rv05/P/8gfvY+1f7Gvrk +of6N/o9+sj73/0r/i3+u/79/1QABgD3AecCuANdA88EJwSPBPcFSAWYBdAFzQWjBWME+ARe A54C3wJLAdUBawD/AH7/5v85/o/+F/3D/XP9Mfz1/Nn9NP3i/nH+x/7+/1H//ADLAT0BIwDF AJQAtQEZAasCLAJzAqUC2wL7AtUCcgItAhoB9QHAAYoBPwD4AK8ASf/m/6D/df9I/vD+jv5F /eL9dP1A/UP9cP23/er9+v3x/eH91v3P/eb+If5g/qL+9f9M/6P/3P/V/7X/vAAJAHkA4QFc AfECbQLFAvcC9wLgAswC5gMyAz8C0gIuAZEBBABA/yT+M/2y/Tj8o/wi+938B/yF/OH8+P0f /Zf+Of7B/xP/KP8n/0n/k//d/+j/rP+K/7QAAABoAM8BDAFNAaEB7QJNAr8DFQNNA3kDtwRC BRoF/ga7BzEHOgbRBjwFqAT3BCYDUQJoAW8AmP/4/3T+/f6f/kX9w/0T/EL7dPrh+pr6iPqj +t77OvvC/Ev8nvzL/QL9d/42/wn/wwBcAMAA6wEHAT0BjQHRAdgBowFjATYBIQEPAO0A8gFM AcoCKAI6AeABSgC5AB7/av7F/lD+HP4f/i3+Af2M/RX8yfyJ/Ev8G/v1+9z7uvt5+0j7cvwW /QT98/6v/yH/hgBHAS0BuQHwAh4CdQL9A3wDyQPvA/MD1gOlA3EDNwLTAmACFwHNAWEA/gDA ANABHQFAARYAygCNAF3/3v8I/l799/2g/YH9sv36/j3+pf9hAE0BHQGkAdcB9AI0AoAC5ANZ A5UDgQMyAsACagJZAnwCmgJvAhYBxwFwAQ4AqAA5/97/r/+f/23+1P4k/b/9df0Y/JP74/tr +0/7WPtw+2X7W/u+/F386v1i/ar+A/7G/8YAywGRAd8B/QIbAjwCcgJ2AjICEQI3AokC3QLr AsQClwJmAkECFAHPAaIBdAEJAGL/jf7G/kD91/1u/QP8mvw2+7n7KfrW+u/7Yvv2/Hb86/1P /Zn+E/7j/9QAtwGNAmoDKQNuA0QDNAOuBHkE5QTgBOsFBwT9BL8EKAN1Ay4DWQOkA7cDQgJP AR8AFP9//0n/Qv83/vX+v/6t/kD9efzV/IT8d/x4/Ij84/04/Tb9Pf1w/a/+Hf6Z/sX+kP4W /aL9jv3E/f7+MP54/u7/kwBqAV0CHwJ4Ao0CugMtA8gEagTmBNwEWgPhA5gDXAMiAs8CcQJG Aj0CDwG1AWwBUwE8AP0ApgBqAGwAggCCAJIAvADGAJoASv/n/3n/CP64/on+Rf4H/fv99v3Y /aj9cv1t/ab90f2h/QX8Wvwg/F78u/zo/ML8fvx7/Lr86PzM/ID8QPxD/Jz9Ff1q/ZD9pv3m /nH+6v8J/xn/dwBDAWACdgNCA8EEHASOBQYFVwWkBgUGWgaEBmUGBQXBBfoGxAeoCAIHtAcK BlgFvwUPBBwDBAIAAU4AygAQ/zD+ev4F/bv9VPyt/Av7ffrs+nP5/vmN+Wf5f/m5+lP7bvy/ /cD+A/23/Xv9rP4y/rP+8/7r/sv+8v+EACwAlQDMAPwBDQDIAEH/4AALALQBQwExAKkAPQA/ AJgA9QEIAKT/4v88/vz/C/86/zn+7/60/q7+tf63/on+M/4x/rP/cgA7ARgCHwM3BBUEpgUV BXkFzwXxBbsFQgS1BDUD0ANyAvoCYAGxAPEAIf8+/kH9JvwF+vn6MPnj+fX6D/oa+hz6FPoO +ib6o/u2/Ob9j/2t/ZX9pP4h/v7/+QDPAS0BFwEBATABgAGkAYQBaAGCAZEBXgEaAR8BhQHE AVgAnwAb/8b/pP+u/3P+4f6C/qD++v8x/yL+8v7Z/ub+5f66/rz/Jv+w//j/xP81/tL+6/89 /3n/mf/GAB0AiQDgAQABAwFIAdQCPwJgAlMCNAISAdoBfgEYALkAcwAy/6P+y/38/U/83fy1 /Jj8Xvws/DH8c/y+/Nb8s/xv/D78WPy//Vf96f4x/kv+ev63/vf/ZQAaANIBGADlALwA+AFs Ab8B4wIQAl4CowLLAwUDaQO4A7cDcwMQAqcCbwKJArQCoQJkAjkCJgIVAgAByQFiAPoAvwCy AKwAlACNALkA+wEmARoA3gCyAMAA5gECAPgAl//3/3L/If7b/pj+av5j/o3+xP62/lv9/f28 /Yv9ZP1J/UL9Vf11/Xj9Qfz0/Mz8v/zJ/QD9Uv2j/e3+Mf6E/vX/af/B/+H/zf/WAC8AtgE2 AYgBvAIMAngC7AN1A+wEFQQBA/4EQwShBLgEfQQfA84DlANRAukCPAE+AFL/zP9t/un+J/0x /GL8B/wA/BH8Cfvd+7f7xvwV/F38T/wu/GP8+P29/nT+/P+EAEMBKwHnAjsChAMJA4MD2QQO A/MDnwNOAvwCuwKYAnsCcAJ7AlsB5wFoASAA3gB6AAn/eP7G/gr9K/w4+1X6l/pA+kL6OPo0 +lf6ivrK+xb7nPyM/YX+Sf8W//EA0AGlAkQC5QOVA+sD6APLA5EDVwMtAwcC8QLfAs8C6gMn AzkC8gJ8AhABlwDuACL/X/7T/ov+gv6r/rr+ev4b/dX9y/38/j7+nP8Z/3T/ov/YAD4A2AFN AWgBcgGfAesCKwIjAhwCeAMIA3sDpgOGA1gDIgLeAp8CJAFbAJ4AAv+L/0X+5P5Y/fD9vP2I /Pz8FPtj+0r7mPwV/KP9Jf2p/lf/Mv/8AIsA6AEMAREBHQELANoAvwC6AMwBEgFeAXUBbwGK AbYBoQFOAP4AqQBD//D/0P/qAAn/6f+r/4T/e/+h/9T/v/9b/tT+Uf4J/jj+3/+a//wAC//8 /9r/n/9G/uf+tv6Y/lr+Mf58/00AYAFeAhcCeQJkAfwBqgGkAdQCEQInAfIBcQDbAHoAWQBP AFMAagCIAKMAtADDANMAwABU/27+R/1f/Qz9Tv3p/mP+YP4O/dH92P34/c39RPzZ/OD9Lv2c /hz+g/7W/zD/ff/AACUAjgDKAOAA/AFEAa8CGwKIAuIDHQNWA2UDIQLbArkClgJkAiYB2wGA ARYAzQDLAPABFAEhAQgAzgCGAFwAXwBYAC3/9v+2/1f+2v59/mD+Nv30/dX9nf0a/Jb8TvxR /H78lvyw/Qf9lv40/q//Gf+gAB8AjwEPAWYBlQIEAroDXwOtA5sDZQM9AykDJgMbAxMDLgNB AykDAQLNAocCSQH8AYgBLgEfASEA6wBz/8P/Ef6t/q7+4v8C/un+tv6R/mz+M/3t/cT93v4p /lj+KP3G/aj94v4W/i3+Vf6U/uH/Jv8j/tP+iP53/qv/Fv9g/zH+yv6q/t3/Kf9o/5X/1gBS AOgBWgGZAc4CJgKQAswCrwJfAioCNQJxAqoCqAJ0AksCUQJlAhkBVwCsAGIAOwAI/5n+p/1h /G38Kfwi+9L7ivur++X8A/w3/IL8tfzP/Pr9RP2M/cP97v4r/rf/b//mACgAewD0AYkCDgJd AoYCkgKeAsoC6QLmAucC2AKKAgEBZgD/APMBIAE6AQwAtgB9AGcASwAY/8T/Uf76/tf+s/6Q /qj+3P79/xP/I/9A/47/3v/4//YAFgB9AOwBDQEVAWYB8AJvArgCzQLBAp8CfwJjAgEBYgEK ARcBNgFKATUAp//g/5D/vv/g/8D/cP8L/tb+5v7w/sv+fv4U/cj91P4E/hH+CP4B/ff99f4I /kH+jv67/tf/Cv8z/0n/VP8+/y7/dAAGAIMAnAByAEgAJAANAB0ANAAsABUACAAHAAUAEAAu AD0AQABAABv/9f/7ABMAQgCIANwBSwGiAdwCRwKlApICFgEsAB7/cv8U/tf+6v9J/9kAZwCg AIcARwAA//sAcgFdAowDcwN9ApcBMf/K/rT+Jv4n/nL+1v88/3H/cf9F/tj+U/3X/Uj87/0i /ZL93f3z/c/9iv1D/QH8+f1//mT++/7k/nT+R/6D/rf+vf71/2X/0ABZAQEBawGBAVgBDADx ASgBcQGSAYcBagFEAPIAaP+l/qj9yP1y/Zz98/4s/jT+Wv7M/zP/Nf7a/nn+k/9VAEEA3QFC AcMChwObBN8F6wZqBmkGJgXRBXsFOQUMBNcEkgRUBA8DowMWAm8BwgE8ANcAY//w/7f/vf/E /57/ZP9Y/5D/3QAYADkAMf/9/6z/Pv7G/m3+QP5N/o3+vv7I/rX+gv5d/lr+Uf5P/k/+Of4s /iH9/P3a/d/+M/7N/0n/pP/+//b/ev8C/uH/Fv9B/x3+6P7I/rH+pv6L/nL+kP68/sD+rP6X /ob+ZP5J/lj+Y/5f/oj+4f9C/3H/NP7V/rf+vf6r/p7+3P9O/57/1QAVAEgAiQDNAOMA7QEC AP4A5QCyAGsAKP/v//YASgCtAR8BhQGRAWUBLgDZAH8AKP/I/2r/Jf8s/4P/4wAYACMALwBz AN0BQQGDAZsBvwIDAk4CowLNAqYCcQJCAh8COQJaAkUCDAGzATwAmP/K/z3/IP9Z//cAoADQ AJoAQwAQACMAMgAgAA8ABQAOABj//f/k/+sAFwBwAMkA9wDkAH8AF//r/9H/wf+v/4f/fP97 /0z/RP+O/8r/1v/sADIAfwCBADT/7P/R/6v/Yv8s/xf/CP8S/zT/P/8e/tP+gv6D/s//B/8R /wj++P78/yj/Wv9k/1D/P/88/1L/gv+g/6b/xv/+ACwAXQCfAMwAywC7AK8AqwDHAOoA8wD/ ARAA9wC/AIEARgAtADsAWwB/AI8AigCFAHkAXQA4ABYAFwAzAD0AOAAi/9//jf9O/zD/Sv9u /1n/JP8Q/zL/Z/90/3b/vgAtAF8AJf+i/zD+8/7R/s3+6/8K/zn/pgBJAO4BiwIkAooCmgJu AjACFwI7AloCYwKEApUCZAIUAckBrwHXAf8B9AG2AUIApf/r/zf+sP41/aL9Kv0T/W/99/5T /on+qP6I/jT9y/1d/RX8+v0J/VX9w/4j/nT+vv78/yP/OP9X/4D/rv/mABwAVACLAJ8AgQAy /9n/0QAVAF0AlQCiAIcAeQBoAD0AEP/a/6f/hf9Y/yz/Jf82/0T/MP8X/y//V/9n/2D/JP7R /rP+uv7T/wr/Sv+Q/8//2/+5/5T/fv+E/6T/0AADADUAVwBfAFYAUgBYAFMAOAAXABgAMwAx ABUAJwBpAJUArQDqASsBNwEuAS8BMQEyARIA0wDDAO0BIwFOAVoBUQE8APsAxwD+AXQB1gH/ AecBqwFPANcAlACoANwBDwEhAQgA9gDiAKAASP/h/27/Mf9B/1T/Of8R/vP+vP50/lv+jf7x /1H/hf+m/8z/yv+K/zf/CP8N/x//Ov97/7n/0v/a/9H/yv/nAAIAFAA6AEcAMQAiABIACP/2 /5n/Ef7F/qr+YP3I/Un9P/14/bv+CP4//lj+Zf5M/i7+S/6L/sL+8v8n/2z/zAA5AJQAuwC3 ALkA3wEFAPMAvACUAHoAdQCUALQAvgC5AL8A+wFQAXYBaQFMAUMBSgEiAPIA+wDfAHEAEP/l /+P//P/9/+H/3P/yAAIAHQBfAIwAYwAvAD4AiQDzAS4BGgEZAU0BgAGlAbgByAHkAeQBygG0 AaUBqgGkAW8BLgDmAIkAPwAH/+n/8//W/2b+7v6n/qH+wf7i/v7/HP8+/1D/Lv8C/uv+u/6O /pr+xf78/zL/Zf++ADEAgwCaAIcAdgBoAE0APgA8AEEAaQCFAHQAVAAS/8X/sv+n/33/W/9A /yX++v6k/kj99/2g/Wz9a/11/XL9bv2R/c/94/3a/cr9nf17/Xn9df17/ZL9nf2z/eL+Df4k /h7+Df4g/mv+4v9d/7H/3P/8AAj/6P/WABcAfQDPAQYBIQFBAXUBmQGuAcABugHBAfACCwHo AZEBKwDeAKwAkgCoANEA5ADeAN0A/AEQAOQApABiAAH/sP+s/94AGwBUAIsAzwEmAYMBugGk AVwBAgCgAFIAKgAVABcALAAY/7//c/9o/27/Z/9o/27/g/+w/8L/tP/B/+P//AAQACwAWQCP ALQA3AENASIBIwFVAbkB/QIEAgQCEQIiAjYCKgIBAfsCGAIdAeEBSwCZACv/4/+O/1n/YP+I /8T/+//9/9X/tf+R/0v/D/8A/xP/Wv/PACgAZQC6ARMBSgFnAWcBLwDBAF8AUQCSANkBAQEe ATcBKQDrALEAkABO/9j/bf84/y//Qf9P/z//KP8V/tj+ff5H/in+Ff41/oD+4f9g/8L/5QAA ABUADgApAHMAoQCeAJAAmgC9AN0A1ACeAH8AogDEAKUAUP/u/6r/iv9h/xj+zv7U/y3/X/82 /v/+0P6x/rn+1/8e/4j/tf+k/6f/v//uADYAawCiAPkBMgEkAQQA/AEHASgBcQHSAiICMgIF Ad4BvgFwASAA+wDUAJUAVwBDAHgApQCKAGoAbAB9AIcAcgBqAHQAOf/j/8P/xv/sADkAjwD5 AUgBUwFPATgBBADsAOwA8gEOAPYAfP/6/8T/y//E/43/Yv9p/3v/Yf8i/vf+3/7C/qH+eP5r /pT+tv7A/sf+m/5w/pv+wf60/rL+rP6P/mr+N/4H/er97/40/oL+uv8W/3T/jv+J/5T/qf+V /0v/Ov+A/80AKQB0AGYATQBVAEsAVABoADv/5f+M/y7+7/7e/vj/Mf9i/37/if+Y/9EAAv/4 //oAHQAqADcARgAyAAb/z/+O/17/YP+a/+AAAQAIABwAWQCwAOgA7QDUAJUAMf/b/7z/v/+V /xf+k/5X/kD+Ef3q/gH+OP5o/pb+uv7d/wL/E/81/47/5wAZAB8ADgASABQACwAtAE8AUQB/ AMUA1wDCAKsAwADxAOAAjwBJACAAMgCDAMoA6gD+ARgBGgDGADb/yP+R/3H/Tf8o/yD/Nv9S /2X/ZP9q/5L/qv+e/5n/nP+e/6r/qP+L/4P/rv/sADcAoAD5AQoA+QD3AQEA/wDiAMgA5gE0 AX4BqwGoAWcA8QBtACkASwCGAIIAXgBPADwAFf/t/9X/zv/F/67/mf95/z7/Ef8I/xz/P/9I /y7/EP7v/uj/LP+d//8ANQBOAHoAoQCJAEYABP/R/63/iv+L/8sABAAZACcAFP/f/7H/h/9d /zH+7P61/rT+vv7F/uL+8v7U/qX+hP57/pP+v/72/z//fv+Q/5j/zwAsAG0AiQDHATMBdgFb AR8BCwEUAQsA8QDhAOwBDgE4AX0B4wIeAfkBrQF4AWsBggGXAXoBJQDMALoA5AEEARUBRgGP AbYBogF3AUQA+QCsAHkAZQB+ALYA6AEWATIBEQDBAI0AiwB7AEEAFgAUADcAewCzALcAkABt AHUAoADTAQABDwEWAToBSgE+AT4BQQFDATIA2wBi////rf95/03/Ef7w/vb/E/8x/x3/B/81 /3j/s//Z/8z/xf/j/+j/vv90/yb+8/69/pv+zP8y/6AAAAAjAA7/3/+W/2j/kf/X/+T/w/+6 /8r/1//xAAwAAP/D/2L/H/8S/vr+6P8g/2T/dv+C/6L/uP+n/3T/TP8+/z7/Vf9+/5X/kP+S /7X/3f/9ABAACP/9AAb//P/f/9H/5QA0AI4AjgBQAB3/+//3////+wAqAIsAtwCjAI8AiQBm AB7/7//c/5X/K/76/w7/Q/9l/2L/fP/I//r/+v/a/5X/Mv7k/u//M/9Z/4H/4wAS/8//kf+h /7b/nP+a/9QABQAcAEUAcAB6AGsAQQAOAAQAJQA8ADEAMABTAGgAVAA2ABoAA//7AAUAJwBi AKUA4QELARkBFgEBANAAkwCUAPsBWgFjAWMBcgFTASsBMgFDARsAuwB1AHMAkAC9AP0BHQDm AHcASwCBAKIAggBmAGAAeQCqAMEAvAChAGEAHP/j/7f/o/+J/2j/Tf8X/vz/Nv90/5b/t/+3 /6f/nf+A/4f/5wBLAE7/+/+b/03/I/9K/4n/ev8o/tr+z/8J/yr/Hv8e/xj/C/8G/t7+v/7N /rT+fv6J/sL+3v7T/tH+8P8J/xH/If8m/wj+3P7N/vj/Lf84/0z/j//F/9H/3f/6ABUAKgBD AFMAWQBsAHoAcQBhAFsAZgB6AHsAaQBdAF0AcgCLAH0AXAB1ANABJAFEAT4BHgDyANwA6QED APoAygC8ANkA0QCOAEYALgBgAKYAyQDxASgBOgErARMA+ADfAMcAuwDPAPIBAADsALQAegBc AFYAYgBrAE4AEv/h/83/xP+p/4v/h/90/yf+1f7D/tj+zf6j/o/+qf7g/xz/O/9A/0r/Sv8o /w//Hv85/0z/Zf+D/5j/uP/i//gABwAwAE4ANv/+/9L/vP+6/+UANgBE/93/Zf87/1z/kf+e /4r/if+t/9f/0f+c/3D/TP8Y/vn/AP8F/u/+vf6e/s7/Lf97/5b/jP+M/5H/kf+v/90AAQAl ACoAA//l/9r/zv++/6n/pv++/+EAHAB4ANYBDQD5AN0BDAE7ATcBRgFQARcAygCOAFwAQAAy ABX/6P/D/7P/pv+b/6P/r/+t/7n/5QAZADEAFP/W/53/ev97/6P/z//b/8//s/+O/5n/7ABB AFsAWgBeAEoABv/A/6L/mP+g/7v/xv/SAA8AUwBqAGoAbwBvAE4AFf/0/+f/yP+i/4f/ef9/ /3v/bP95/43/ff9Z/0P/Sf9Y/1b/Yv+F/5b/nv+q/63/1QAfAEgAUQBQADkALwBEAEwANwAq AFYAxQFFAacB2wHTAaUBggGDAaIByAHlAfQB6wHXAdkB4AGyAUEAwgB3AGoAigC/AN4A0wCk AFcAEwAIADwAjQC2AJwAhgCSAJAAagA4ACQAOwBFADAAMQBJADz/+f/C/94AIgA5AC4AIgAL /+T/wv+q/3z/U/+E/+H/8//C/5r/q//i/+T/qf99/2j/Y/+B/7D/yv+2/6j/6wAyABn/1v+m /5T/h/9T/yX/DP7H/pv+yP7m/tv+4P72/yD/Pf89/1r/j/+7//QAFgAE//gAGwBsALUAtACS AIwAoACuAJoAfQCBAJAAjwCLAJkAsgCiAHUAeQCaAJcAdAAr/9n/wf/L/9L/1//D/7b/2//9 /+T/ov92/4L/k/+V/5//sv/bABoAMwAoAA//1P+h/6X/uf++/7v/v//R/9n/yf+b/1T/HP79 /v7/Tv/DAAUAGwAL/9j/tP+z/7z/xf/YAAwAPgA7AC4AMQAwAEoAggCeAJMAXf/+/6b/gf+c /+sAPABhADr/4v+z/7//3gAJADQASABOAEEAJwAYAAj/6P/B/6j/vP/h//cAEAAI/6z/M/7l /tL+9/8q/0X/Uv9c/3D/qf/zABT////d/9wACABTAKUA0QC8AJMAgQB9AJAAsACaAEL/8P/K /7j/u//oACgATABNAFAAWgBPAD8APgBTAJgA8QEfASkBCQCrAEYAGgAmAFMAZwBBABb/7f+Y /y/++v8Q/zn/NP8c/yn/Rv9F/yj/Cv7//wP/Ef8f/yL/Pf9t/2v/U/9t/4//lf+b/6f/t//V AAUARABxAIAAjACbAK4AxAC2AIMATgAtAD4AdAClAMoAzACfAGkAKv/f/7T/lP9w/4H/uv/h /+T/3f/m/9j/kv9i/33/pP+6/9v/+f/0/9j/vv+5/+EAIQA0AB4AKQBPAFgAWQByAHcAUwAi /+3/w//S//wABQAEAAX/8v/j/9L/qP+V/6b/sv+k/3z/aP9u/0//Mf9T/4f/xwAkAHAAoQCj AFsAEf/w/+EAAgBQAIEAegBeAFsAcgCGAIsAfwBUABj/2f+k/5D/q//c//H/0/+i/27/RP89 /0X/SP9H/y7/Fv8t/1D/VP9D/0X/if/qAAX/5f/c//QABwAOABMADgAA//j/+P/v/9T/v//a ABYANgBJAGMAVwAk//v/4//T/9H/7gApAFEATwBKAFUAZwB2AGsASAA5AEwAZQBsAF8ASgBG AGAAewCAAIEAlADBAPAA+QDmAN4A4wD1AP4A7wDgAMwApACaALYAwAC8AMIAqgBbACUAUgCd AKMAfQBpAFsAOgAJ/+z/8//5/+P/zf+8/6P/pP/WACIAXQBgACr/8v/X/9T/+QBAAHEAagA9 ABoAIwAuABf/9f/Q/7X/0gAPADAAPgBPAFgAUwBJAEQAPAAsACIAC//Y/63/p/+5/73/p/+D /1z/Rv9P/2r/nv/d/9z/pf+P/6b/zAAGAEQAVgAc/83/wP//AFQAjACZAJYAdwBIAFMAhQCf ALkA2wDmANEAlQBVAEIAQAA3ABn/6P/vACMAIwAKABgAOABeAIgAiQBI//n/5QAIAEIAfQCT AJsAswCtAJEAgABH//n/6wAPADsAZAB4AHMAXgBTAE0ARgBvALUAuACUAIUAhgCPAGwACv/V /+YABAApAEYARAAvABQABv/3/8//vf/dAAwAMAAp/+3/r/+Y/7P/6AASABn/6f+h/5j/3AAx AF8ATQAoAB4AKQA+AEAAJgAhADEAI//q/6j/lv+r/6f/kv9s/yP+7/7e/tr/Ef9o/5f/tv+9 /3//GP7W/u7/P/9z/43/rv+5/6T/i/+J/6T/tv+7/87/2P+w/2n/Rf9d/2L/LP8M/yT/WP+j /9//9//+/+D/nf9Y/yn/Mv9s/5T/qf/H/9D/uv+q/84AIwBTADH/9v/b/9b/tP9s/1L/f/+k /6T/nf+b/6P/p/+N/1//Q/9O/2r/bf9Y/zT/Bf7l/tD+vv7e/zL/ev+e/63/v//4ADcARgAv ABD/7f/U/8P/wP/rADIAawCnAO8BBwDVAIkAVwBVAHMAjQCZAJsAjABlACT/4//H/7j/kf9q /1P/Uf9t/5D/qv+q/2X/EP8G/yb/R/9n/23/df+g/8f/6QASACsATQCcAPUBIAEKAMwAjwB6 AJYAnQB4AHgAlgCHAGQARQAd//D/vP+Z/70AHQBiAEH/+//3AAb/8//j/77/gP9//8cAFAAv AAH/xv+1/7n/yf/uAA8AEf/s/6v/c/9m/3z/nP/IAAgAOQBJAE0ASgBFAEwAXABtAHwAgAB7 AGgAQwAd////8AAAAC8AagCCAFAAGAAsAFoATgAR/+D/2//R/5X/ZP9m/27/b/95/3//g/+P /7H/8gAnADIAQgByAJkAnQCTAIUAZgBGADgAMQBDAGIAUAAtAEAAZQBoAFMAWQCXAMwAvQCL AGMAZQB9AHgAfACfAKUAmwC3ANQA1QDKALgAqQCmAKkAnQCCAHoAlwDBAM4AsACkAMMAxACG AEoANwAvAAn/3f/S/9v/+QAqADsALwAnABIACQAuAEkARABEAFEAagCJAJ4AuwDGAJ0AcwBs AHEAlQDNANsA1QDhAM0AmACFAKIAuACzALUAxQCzAHoAUwBeAIIAiwBhAB7/8v/u//f/6f+z /2b/OP9B/1b/cv+f/8T/7gAT//f/zf/d//j/6/+0/2z/SP9c/4j/nv+L/4j/rf+//7f/v//T /9n/y/+6/7b/tf+3/7v/sf+g/57/n/+c/67/zv/L/5z/bv9f/3X/hf9q/1n/cP9z/1H/M/8+ /2//j/+T/7L/1v/V/9D/2v/v//v/3P+y/8YAHgBwAHMALP/g/7n/pv+D/2b/f/+w/73/rf+i /4X/Nf7a/q3+m/57/k7+L/5A/nj+qP69/rn+uP7U/u//Df9Y/6H/w//sABYAJQAeABAAFAAt ADIADf/Z/7v/tf+8/9X/0/+Z/2D/X/+I/6r/rf+w/8H/0f/m/+T/r/94/3v/zQBIAI8AkwCX AJsAgABYADD//f/Q/8v/6P/8AAYAIgBMAGgAewCkANEAvQB5AD4AFAALADMAZwCiAOMA4QCT AFcAUgBhAHIAeQBxAGUAXgBiAHYAmACxAKQAjgCYAJEAWwAf//0AEwBWAGwASwAsABYAIQBX AJwA5AEDAOwA3QDbANUA1gDQANcA9wDpAKkAfwCEAJsAkwB0AG8AcABH//n/rv99/1D/OP9m /7T/4P/M/47/lf/wABX/7f+//53/i/+H/5//7QAzAEQAQgAxAA3/3f+w/8EAAAAS//H/2//l /+v/yv+c/3P/S/9G/2//twAfAGYAXAA3ABL/3f+2/6z/o/+f/7D/z//p//4ADgAJ/+T/pf9/ /6P/8gAiAC0AF//H/3P/YP9w/3H/WP8+/1b/iv+R/4n/q//P/8P/of+l/7v/nf94/4H/nf/J AAMALwBfAIEAiwCpALgAmgCAAFQADP/wABgAdADYANL///66/kn/fwFGAccAof7+/h7+fP/b AUMBjwDH/+j/h/9//2X/Tv+vADwAgwC2ALgAYAAqAEgAggCjAHMAHf/s/9b/6QAvAHgAlgBv AEQAaQCXAIAARwAlADQANv/a/1j/B/7b/sv+3/8H/yT/Kf86/4L/5wAwACv/1v+H/3P/c/90 /4//u//i/+3/zf+o/6j/nP9y/3b/sf/Y/+wAEQAjAAL/uP9g/1H/o//a/7r/pf/KAAgAQQBg AGYAWAA+ADsAQgA3ACsAOQB0AMIA3wDlAPUA7wDrAP0A9QDdAMgAugDVAPYA3ACQADX/9//r //kAIABaAHkAggCHAIAAdwB2AHcAbABVAGoAqwCtAGUAQwBnAJcAugDGAKYAaQAw//7/2//b AA4AcADDALwAawAR/9H/y//6ABsAEgAEABkAXwCRAEb/yv/CACYAkQDGAKEAZQBdAFsAMv/n /6P/qf/O/9b/5P/6ABQAUgCEAJcAsQCzAIUALv/R/8n/+wAEAAEACgAC//j/9AALAE8AhACN AIIAawA8//j/x//E/7z/oP+e/8gAAAAbACQAJ//x/5L/Vv8+/0H/Y/+kAAUAM//o/4X/Y/9z /4v/jv+oAAQAVgBoAF8AVQA9AA7/6f/wAAD/+wAGAEIAiwCeAIoAgwBoACwAFgAyAFYAfQCP AGYAAP+Y/4f/0gAfAB3/zv91/y7++v8S/3b/vv/fABMAKP/u/5v/fP+vAAYAQABYAE4AIQAN ACoAQQAr/+n/xQAKAGAAWgAtACgAPgBAABb//QAkAEkAOQAY//L/z//UAAoAKf/a/zT+vf7A /vz/Fv73/tT+5f8X/zX/B/53/ef92v46/n3+fP6c/v3/LP8F/v7/LP83/yr/K/8X/tn+l/6P /sz+/f7p/rD+h/6Q/sD+8f8b/x3+8v7l/wf/H/8l/yv/Kf8P/uj+1P8B/5oAeAEYASwA1wBw AFkAoQD1ARAA4gCmAKsA1QDMAJsAoADjAQIA8gD8APsAxgCbAJUAmACUAIEAewCVAMcBDAEz ASAA+gDSAMIA5QEPAToBfQGbAW0BEACzAI0ApQD2AXABvAHAAZsBQgDsAPYBMAEwAO0AmgBI /+r/n/+X/9AABP/q/6X/mP+3/7b/cf7t/mj+Iv4d/mL+x/7W/oX+I/3g/ej+M/5m/kr+Af3S /er+P/6I/m79+P2M/Wr9o/4k/o3+v/74/0X/rAAeACr/r/8j/tf+4P9M/9sAE//b/5r/o//i ADsAowDtAPkAwABwAHAAtQDTALkAhQBAACEAYADtAXwBwwHiAfoBxwFgATsBZAGeAboBrgGm AZkBQgDNAIQAagCDALsA6gEXAT4BUwF1AcECMgKzAwkDCgKzAgoBQwCpAF4AgwEpAeoCKgHE ASsAzACzAMoA5gCn/9v/Af66/tv+yP5z/kD+af60/pz+F/25/dX+Nv5v/iX9efzv/M39E/1+ /af9m/2m/bT9nP19/ar+R/8D/4f/0v/m/7T/RP6+/m/+hP7n/1//mf+I/54AIACuAMwAmwCP AK8ApgBiABkAAAAsAHkAqACUAGgAaABnACD/y/+4ABYAyQFQAW8BcgGlAiUCpAKqAlQB8gGW AW8BmwHlAgMBvQFeAVUBmAIXArMC/QLJAjsBpgGIAaoBhQFAAQsAxwCUAIMAjQCyAM8AsABF /73/Yf8W/rz+n/7e/0b/nf/F/9H/vv97/zr+3v5D/d39zP3G/df96v26/Uv8q/w7/G/87/1C /Yz90/3X/Zb9Tv04/VP9uP6P/4cAMgCGAJYAdwBGABgAEwBCAHgAkACDAHQAmQDoASMBGgD2 AQ8BOAERAPYBVwHRAe4ByQG1AeoCXALEAvIC9QMEAzIDbAOvA9EDoQNWAz4DRgMmAsMCWgJF AoQCyQLaArQCegJLAkQCPgHXAS0AzgDAAK0AjgBvAEsAMAAiABsAGAAfAC4ADP+w/5b/7QA2 AAz/iP8J/sX+h/4h/bb9dP19/cf+AP3x/a79Wf0a/O78pvwm+5z7afu3/FD85f0x/Rn88P0Q /XH95P4W/aD8mvvk/FX9mf6l/xL/D/6+/mD+RP5Y/kj99v3j/n7/NP9c/0n/cv+v/5z/Uf9v ABkAuQEVAVMBdAGCAZsB1AIzApkC6AMAArICPAI9AuMDzQRoBGgEDQO9A7ED6wQtBD4EIQPX A0sCnAI6AmQCkwI/AbYBkAH9AsEDZANlAoQBUQDXARABJwEiAXEB4QHxAWAAev/X/6n/8ABe ACT/F/4S/aP9bPzb+/r7R/rn+tb7Kvuh+/D8KvxM/Cz7uvsE+kz52fng+oL7hPxn/Lr8TfuK +zr7ePvM++/8Bfxt/Tv+Ff6i/rr+jP6R/tz/Ev8a/yz/Sf8m/rj+jP8K/8kAHQAJADoBBQHb AikCEAHjAb8BvAIMArUDWwOxA/AEUAS1BOYEoQP1A5wEAAR2BDEDcgMYA2oD7QRUBLgFDAUP BNcEtwTFBOYE9gSpA9gC/AKiApwCXAHgAYgBMgClAEcAQf/+/1//DP81/zf+nP3C/Rj8Vfto +0f8UP05/OX7+fup+9D7afqT+lv62PsL+mL5YPjC+Jr4yfly+mv7Kftn+037N/tO+1z7L/q8 +i/6CfqI+2v8hP2Z/jf+OP3//iv+zv9zAC0BLgHXAd8CBwKzAysC2QI6AhYCXgKIAoECsQNN BBUExQU9BU4FFwT1BM4EfgRCBBkDuwMnAuYDpgTyBX4FEwSaBKUFCQU/BTcFQgUxBOUE5wVO BYEFSgUSBSwFSATyBDsDgAMSAusCoQH8AT0AngAk/7n/Tf7H/fX9Gvze/SD9Qf0s/PP8ePvf +4L7Uvra+kv6fvsy+zX6aPmw+XL5bvlh+Wb5w/p9+1/8IPyl/S79sf2+/Uj8wvyb/N/9Tf3j /rj/fgAOAJ8BCQD3AJEATABrAK8AzADyAT8BfAG1AgYCIAHwAfECZgL1Ay8DEQL4A1wERwUV BRkEUANRAuYDVgP3A+8DMwJ1AmAC+QPHBBkDfgKFAjIClwL8AxcDPQOoA/IDrALyAf4A2//X /z//BP8F/1L/5gBF/+v/Av4t/eT+Cv3p/U783/zu/Sb9CvxX+5P7dfvh/GP8lfw/+9X7yPwW /Lr9Q/0H/Dr7iftZ+6/8OPz6/iX/Jv9e/yz/QP/BAE8ArADuAO8AkAAo//oAEwBvAMYA4ADH AHn/7P88/tP/Df99/4H/X//YAQYCIAJqAiwCEAJAApwC5gLnAsECjgJAAdYBMQBc/+kAWwFg AhUCEQHhAi8C3QMaAm0BggFPAdoCfgK4AoYCQQHvAXYBMgE/ATAA0gAg/z3+nP5n/lv+Rf4M /bb9av1f/Z79yf2t/dP+fP8C/vj+tv53/fr9Vf0o/X/9pf1W/SH9l/5r/ob9ePws+7r8Uf1O /hH+i/7N/rr+cP4h/cL9WP1F/d3+sf7N/iX9qv3t/qv/Vv+P/0z+u/4//lL+8/+hABIATABV AEoAjwFSAhYCTwH2AWUBHwFOAZYBzwImAqkDSQPVA/sDtgNLAxADKQN7A/QEWAQzA8QDsAPB A1gCewHVAf8C5QQFBKsELAMAAo0DIQO+A5oC5wKSAu8DTAM+AxgDEgL4AoEB0QFLAM4ASAAt AHYATf9I/in96v5Z/mj91/2O/i7/E/89/rP+Mv4N/fX9kP0R/O39N/3C/hb9oPy3/DX8P/xn /DD7iPtA+9j8gfxm+/r8MPzj/Qv8ivwa+9P7e/tt/AD81f1S/Xj9uv4I/fX9yv47/zn/6//R /2n/X/+U/4j/NP7o/sj+4f9hAFkBaAHPAVkA4QECAT8BKgERAU8BwwINAjUCdAJ/AjgCKgKH AvkDOAMvAzQDngRSBRoFpQWuBbIGKAaWBk8FPgQEA30DogOsA3gDcgOWA4AC+gJOAhwCcQKh AmUCAwGRAQsAmgBaAFkAmgD2AT8BQwDpAIAAegDNAPgAsgBiAGYAdQAj/zj96f0V/U7+Av5W /hz9tf2A/Wv9O/zo/Kr8v/0U/Uv9JvyO+6P65vrY+5D8lf0v/Tn9GP0V/TP9R/07/TH9Lf0M /ND8gvw6/Cb8YfzH/PL82Pz9/Xf96P4r/jn+O/5//vf/Qf8U/q7+uv9G/9MAKAAs//3//AAv AIEBFAGzAfwBwgEwALMAXAARAA8AWgCgAMUA1AD2AUoBvgI7Ao4CowLBAvIDDQMUAtwCewJe AnMCeAJ9ApsC6AMmAuwCZQHzAbcByAICAhwCGgIfAjcCEwFQADv/jf+L/+P////U/+sAYADJ AQABEQDuALIAswDvAO4AjQA4ADIAbgCwAJkAAv8l/qX/Dv/fABv/rP8q/u/+0P6K/k7+Qv4h /gz+VP7D/wD++v7e/wn/df+s/5H/cP+E/8X/9v/J/yz+mv6p/zX/ov+p/13+/P7Z/xz/if+s /3H/Nv8F/rX+gv6b/sj+xP5//iv+Gf5H/nD+iP7B/0P/6AA+AB3/4v/e/+r/v/+A/5T/6f/z /5f/T/9b/3H/Vv9D/37/4AARAAf/8P/R/6//vAAAAB7/zf9P/xr/OP9e/2T/Uv9A/2j/4gBP AE3/7v+R/5j/+AAxAAn/xf+m/7f/2P/4ACgASAAyAB0ANwB4ALIAev/p/8cAYQEsAYUBRQDV AJoAsAEMAVYBVQFkAbwCBwIHAdEBkQFzAakCPgKtAoACEAHOAa8BeAEYANoA5wDvAO0BGgE0 AQUAwACYAKwAvABd/9b/u//g/9D/tv/pAEMAggCmALAAnABvAC3/7v+6/4T/dv+V/53/gv9Q /wb+4P8A/xf+7P6u/rP/F/+3AEYAiwC9AQ0BIQC0AAb/cf85/1H/bf+F/7H/7gAzAEoAMQAQ /6//Fv63/oj+ev7B/xT/Ff7k/sf+2P7o/tf+4/8m/4s=') samplingRate: 44100! ----- Method: SkeletonBaseInfo class>>cassete (in category 'sound library') ----- cassete SampledSound addLibrarySoundNamed: 'cassete' samples: (self mimeStringToBuffer: 'AQD/AP4A/wD+AAAAAAD+AP8AAAD/AP0AAAAAAP8AAAABAAIA/AD/AP0A/wAAAAEA/QADAAAA AAD+AP8AAQACAP8A/wD+AP8AAgD9AAQA/AD/AP8AAAACAP0AAAD6AAgACgD4APkA9gAGABIA CQDpAPwA/gANAAoAAgDpAAEABwD2AOwAAQD/AAsA/gAFAAoAAQD5ABIABAAaAPcA1wDeAAEA BwARABwA9AD3APIA8QD3ABkA/AATAPMA+wAAAPEAEgD+AAoABgD9AP4A9wD0AAYA+wAEAAgA 9QD8AAYAAAD3APsADQABAAoA+AD8AAEA9AD2APgA+AAGAAwADQAKAAMA9wD4APsACQAPAAUA +gD5APQA9gDzAAAABgAGAA4ABwD7APoA9wD3AAIACgARAAcA+gD3APkA+gAAAAkA/wACAPgA 9AD5AP4A/gADAAAACQACAAEA/gAAAP0AAAD9AAAAAAAFAPwA/QD7AAEA/gACAAMAAwD7AP0A +wD/AAIAAwAFAAYA/gD8APgA/QABAAEA/wD/AP8A/wD9AAAAAAADAAAA/wD/APsA+wAEAPkA BAD9AAIA/AAFAPwA/wD8AAIA+gABAAUA/gACAP8ABQD7AP4AAQACAPwAAAABAP8A/gABAP4A AAD+AP0AAAAAAAIA/gD/AAIA/gD/AAAA/wD/AP4AAAD/AAMAAgD+AAAA/AD+APwAAwAAAP4A AAABAP8A/gACAAEAAQD/AA4A9AAGAPsA6QAIAAMA9AASABgA5AD/AAIA9gAKAPsAFwAHAMwA 5gAlABcAPQAGAMkAygDoABYALwD/ANcAyAACACkAOgAXAOEABgDHAPkA+AA0ABoAEgDMAOAA 5AAOAB0AJgAMANwAzwDwADYAFgAUAPEA/QDaAPwA/gAnAP8A9wDlAO4AIQAdACQADgDgAMYA 8gAVAC0AOAD/ANsAzQDqAPMACwALAPoA+ADrAAEAFAAqABUA8QDgAPEAFQAFABIABQDyAOkA 6wAJABYACgD0APIA9QAFAAcAFAAPAOgA5QDsAAwAFgARAOwA+QD5ABMADQAKAOkA7QAAAAMA FAAEAAQA8QD7APkAGwAQAA8A9wDxAOQA6gD8AAoAEgAMAP0A/wAQAAUA6QDtAPoA+gD3ABAA JAAYAAIA4gDeAOUA/QAUAAsABAD6APsA9wAKABMAEQD4APcA8AAKAAQAAgD5APgA+AD3AP4A /AD6APYA+wADAA8ABwAKAA4ABQD6AOsA7gD7AAkA+gAEAPcA+AD+AAkACwAEAP4A/wD7AP0A BwAOAAsABwADAP4A/QD3APQA9QD4APUAAwALAA0A/AD2APgA/AAFAAsABwADAAMAAgAAAP8A AwACAP0A8AD0APkAAwAFAAEA/QD9APcA/gAEAAgA/QD5APwAAAAHAAQAAgAEAPMA9gD6APkA BAAEAPUACQAIAP8A9wD/APsABAAAAAoACAD8APUA8AADAA0ADQAGAP8A9wD4APwACAAGAAMA /QD9APkA/gD3APwAAQACAAAAAwAHAAkAAwD8APsA/wAFAAcABgAAAP0A+QD0APsA/gADAAIA /gD7APwA/QADAAAAAgD/AP4A/wD7AP4A/AD9AP0AAQABAAEAAAD+AAAAAwAEAAMABAADAAIA /wD/AP4A/QD+AP0A/QD+APsA+wD8AAEAAgACAAIAAgAAAP8A/gD/AAEAAQAAAP0A/gAAAP8A /wAAAP8A/wD/AP8AAwABAP8A/gD/AP8AAgAFAAQAAAD/AP4A/QD+AP8AAgAEAAIA/wD/AP4A /gD/AAIABAABAP8AAgD9AP4A/AAAAAEAAgD/AP4A/gD9AP8A/wD+AP0A/gABAAEA/wD/AP8A AAAAAAAAAQAAAP4A/gD9AP0A/wD/AAIAAQAAAP8AAAAAAAEAAQADAAAAAAD+AP8A/gAAAP8A AQAAAP4A/QAAAP8AAAABAAEAAQACAAEAAAD+AP8A/wAAAAEAAQD9AP0A/AD8AP0AAQACAAAA AAD+AP8A/wAAAP8AAgACAAAA/gD+APwA+wD8AAMACQALAAQA+gD0APYA+AD9AAMACAAIAAIA /QD5APwA/gABAAIABAADAP8A+wD5APoAAAAFAAYAAwAAAPwA+QD+AAAA/wABAAMAAgACAP0A /AACAAMAAgAEAP0A/gD+AP8A/wABAP4AAQAAAP4A/AD9AP8AAAD/AAIAAgABAP4A/gD8AP0A AAD/AP8AAAD+AP0A/wD+AP4A/QD+AP4A/gD/AAAA/wAAAAEAAgAEAAIAAQAAAP4A/QABAAMA AQABAAAA/gD+AP8A/wAAAP8A/QAAAP8AAQACAAEAAQABAAIAAAD/AP4A/wD/AAAA/wD+APwA /wD+APwA/AD+AP0A/gACAAUABQADAAAA/wD/AP8AAQABAAAAAAAAAP8AAAD9AP0A/gD/AAAA /wAAAAAAAAD/AAAAAAABAAMAAwD/AP0A+QD9AAAAAAABAAEAAQD/AP4A/gD+AP8AAAAAAAAA AQABAAEAAAD/AAAA/wD/AP8A/wAAAP8A/gAAAAAA/wABAAEAAQAAAAAA/gAAAAIAAQABAAEA AAAAAAAAAAAAAAAAAAAAAP4A/gD/AAAAAQABAAEAAQAAAP8A/gD+AP4A/gD/AAAA/wAAAP4A /gD/AP8A/wD/AAAAAAABAP8AAAAAAAAA/wD+AP4AAAAAAP8AAAD+AP4A/gD/AAAAAgABAP8A /QD9AP0AAAABAAIAAQABAP4A/QD8AP0A/wABAAEAAgAAAP4A/wD/AAAAAQABAAEAAQAAAP8A /gD+AP8AAAABAAAAAQD/AP0A/QD+AAAAAgABAAEAAgAAAP8A/wD/AP8A/wD/AAAA/wD+AP4A /wD/AAAAAAAAAAAAAAD/AAAA/wD/AP8AAQAAAAAA/wD+AP0A/gD/AAEAAQAAAAAA/gD+AP8A AAABAAIAAAD/AP8A/QD+AAAAAAAAAAAA/wD+AP4A/QAAAAAAAQAAAAAA/gD/AP4A/gD/AAEA AAABAP8A/gD+AP4A/wABAAEAAQAAAP8A/wD/AAAA/wABAAEAAQD/AP8A/QD/AAAAAAABAAAA /wD/AAAA/gD/AAAAAAABAAAA/wD+AP8A/gAAAP8A/wD/AP8A/gAAAP8A/wAAAAEAAQABAAAA /wD/AP8A/gAAAAEAAQAAAP8A/gD/AAAAAAAAAAAA/wAAAP4A/QD8AP8AAQACAAEAAAD/AP0A /gD+AP8AAQAAAAAAAAD9AP8A/gAAAAAAAAD/AP4A/QD9AAAAAgACAAIAAAD+AP8A/gD/AP8A /wAAAAEAAQAAAP8A/gD+AAAAAQAAAP8A/wD+AP4A/wD/AAAAAQABAP8A/QD8APsA/gABAAMA AQACAAAAAAD/AAAA/gAAAP8AAAAAAAEAAAAAAP4A/wD+AAAA/gABAP4AAAD+AAEAAAACAP8A AAAAAP8A/wAAAAAAAQAAAP8A/gD/AP4AAAAAAAEAAAABAP4AAAD+AAAAAAABAAAA/wAAAAAA /wAAAP8AAAD/AAAAAAAAAP4AAAD+AAEA/wABAAEAAQAAAAEA/gD/AP0A/gD+AP4A/gAAAAAA AAABAAEAAAAAAP8A/wAAAP8A/gD/AP4AAQAAAAAAAAD/AP4A/wD/AP8AAAAAAP8AAAD/AAAA AAABAAIAAQACAAIA/AD9APwA+gAAAAMABgABAPwA/QD+AAQAAgADAAIA/gD8AP0A/AABAP4A AgD/AAIA/wD+APsAAAABAAQA/wABAP0A/gD9AAAA/QACAAAAAQAAAAEA/gABAP8AAAAAAP8A /wD+AP8A/wD/AAAAAAABAAEAAwABAP8A/gD9AP8AAAACAP8A/gD/AP4AAAAAAAEA/wAAAP4A AwD/AAEA/QD/AP0AAgD/AAIA/wABAP4A/wD9AP8A/wAAAAEAAwABAP0A/gD+AAIA/wABAP8A AAD9AP4A+wAAAP8AAgAAAP8A/QD/AP8AAAABAAIAAQD/AP0A/wD+AAAAAgABAAAA/wAAAAAA /wD/AAIA/wD+AP0A/gD/AAAA/wADAAEAAAD+AAAA/wABAP8A/wD9AP8A/wD/AAAAAQD/AP4A /QD+AAEAAAD/AP8A/gD/AP8A/wABAAEA/QD+AP4AAAD/AAEA/wABAP0A/gD/AP0AAgAAAAMA /QD/AP4A/wD+AAIAAwAIAP4AAAD5AP4A/AACAAAAAgD7AP8A/gD/AAAABQABAP8AAAD/AAAA AQACAAIAAAD9AAAAAQABAAEAAAD+AP4AAAD+AAQA/wABAPwA/gACAAEAAQABAP0A/AD7AAEA AAAAAAAAAAAAAP8A/QD+AAAAAQADAP0A/wD/AAMAAQAAAP8A/gD8AAEAAgABAP4AAgD+AP4A /QABAAAA/wD+AP4A/gD/AAAAAAAAAP8AAwD9AAAA/gABAAAAAQABAAEA/wABAAQAAgABAPsA /QABAP8A/gD/AP4A/wABAAAAAAD7AAQA+gAEAP8A/wACAAIA/AABAAAAAwD8AP0A+QAFAP0A AAD5AAcA+gAKAPkA+wD5AAwAAwAGAAIA+wALAPYAAAD1AAQA+QAKAPsACAD6AAEA+wAEAPwA AAAAAAAA/AABAP4A/wACAAIABAD6AP8A/gABAP8A/QADAP0A/QD+AAEA/AD+AAEAAwD8AAAA /wADAP8AAQD6AAEAAwD8APgA/gD6AAcA/AACAPsA/wAAAAEA/QD9AAAAAwAEAAEAAQD7AAEA AQD+AAAA+wACAP4A/QAAAAAAAgAEAP8AAAD/AAMAAgACAAcA/gADAP0A/AD/AP0AAwABAP0A +gD7AP0A/wD9APwA/QABAAEA+wAKAAMADAAAAAMA9QD5APcADAAGAP0A/QDoAOoA/gALABAA IwD6APEA8wD3AOkACwAAAAwACgD0APkA9gABAAIABwADAA8A+AAIAPoAAwD+AAgA/gDxAAYA AAACAAgA/wD6APoABwAFAP4ABAABAAAA+wD2AP8A/gD6AAEAAAABAPkA9AD+AP8AAQAFAAYA /wAAAAQA+QAEAPoA/QAAAAcACgAAAPwA+gADAAEAAgD7APYAAgAIAAQA/gD4APkABgAEAAMA AQD/AAQABAD+APYA9AD6AAAACwALAAsAEQD2AOgA+gD8ABgAGQD+APAA+QDVAPsA4gAQACkA LQAWAAkAxwDSAOEABQAiACYAFQD8APMA5ADsAP8AFwAQAPkA5AD+ABcACQDxAPkABAANAPwA 7gD7AP0ABwAHAAAA/AAEABoAGQD+AOcA1wDuABMAEwABAAUA/gAUAPUA7gDiAPQA/QAEABIA FQAZABYAEwD2AOUA5gDpAOgA/wAFAAkAIAAXAP4A6gDjAPAAIAAMAAYA3gDZAPwAFAAmAB8A AQDtAPoA7gDtAAYAEAALAAoABwAFABAABAD0AOQA6wDxAAUAFgANAAsA8gDzAPcAAwD9AAkA DQAEAP0A8wD4AAoABQAQAAUA8wDhAOgAFgARAPEA/ADVABYA/QAhABIAKAD1AM0ACgAdAD8A MgDmALgA0wAiADoA5QDlAOsA6gD3AC0AGAAbACQA9wDQAL4A3ADpAB4APQAKAMMAyQDtABkA 6wAmACsAzwDqAOMAEwADADsAKQD1AAwAygALABMA+QAkAOYAwQDxACQAJgAFABcA8QDlACEA +AA5APsA+AD5APoA+wA0AC0AHADAAMAA2gDtABYAEwACAPAA6AD6AAUAGQAhAPMAyQDxADMA IwAtAAMAxQDFAMQA7QAyADgALAD6AMIAzQDyACQARwA+AAgA3gDlAN4AEQAEAPgAEgANAOIA 8QD1APgA7wDwAPoAGwAqAB0AFAD6APEA9wD2AAcAJgAEAOwA6wD7AO0A8gAAAPQA9gD7AA4A FgAWAP0ABwANABkAAwD3AAIA/wDxAOYA4AD/AAcAAgD4AO8A/gD4AAAAEgATAP4ABAABAPgA 8gD3AP0A8wDwAOEA9QD8AAgAIgAYAAIA7QDoAPUAEQAMAPsA9QD0AP8AAQD4AAgADgAIAP0A AQAHAA4AEAAAAAwAFgANAAkA/wD3APYA/QD+AAMACwD9AO0A7wD3AA4ADwAHAPsA7QD3AAMA DwAWAAsA+ADyAPcA9QD/AAMA/QD3APsA+QD+AAgABQAAAAIABgAEAAgABQABAAEA+wD3APgA /AACAPYA9gDyAPUABAAQAAUAAwAAAPwA7gD3AAIABwD2AO8A/AAQAAQA8wD9APkABQABAA0A CwD+APUA9AD/AAYABAACAAQABQAFAAcAEAAOAA8ABwAFAAcAAQD4APwAAAD8APoAAgACAAAA +gD6APoA+AD5APgA9gADAAQA/AD+AP0A+wD0APYA+wD+AAAA+AD6APsAAQAEAAwABwD9APwA /gD/AAMABAABAAQABAD/APkA/AD+AAIA+gD+AAcABQADAAEAAQACAAkABwADAPwA+QD4APsA /QABAP4AAAADAAYAAQD/AP8AAQAFAAgABAACAAEABAD9APoA+gD9APwAAAD/AAAA/gACAAQA AAACAAEA/QD6APwA+wD6APwA/gD9AAAA/wABAPsA9wD5AP0ABgD/AP8A+QDwAPUA/AAHAAYA AQABAPsA+gD9AAUACAAGAAIA/QAAAAQAAwACAAAA/wAAAAEABgABAAQAAAAFAAMABQAIAAYA /wD8AP4AAAD+AP4A/AD7APsA/QD/AP4A/QD7APcA+wABAAIAAAACAP0A+wD6AP0AAgAIAAYA BQD8APkA+wD+AAAAAgD+AP4A/QD+AAAABAAJAAkACQAGAAEA/wACAAMAAwD/AP0A9wD5APsA /wD+AP4A/QD+AAAAAQABAAEAAAABAP8A/QD9AP0A+wD7APsA/QD8APwA/AD7AP8A/wACAAMA BAADAAMABAAFAAUABAAEAAIA/AD6APoA/gD+AP4A/AD9APsA+QD8AP8AAgACAAEABAADAAEA AAD/AAAAAAD9APwA/QD9APwA/gD/AAIAAwACAAMAAwADAAQABQADAAEAAQAAAAAA/gD8APsA +gD7AP4AAAAAAP8A/gD+AAEAAQD/AAEAAQD/AAEAAQAAAAAA/wD+AP4A/wD/AP8A/wABAAEA AAD/AAAAAQACAAAA/wD/AP4AAAADAAAA/wADAAIA') samplingRate: 11025! ----- Method: SkeletonBaseInfo class>>cork (in category 'sound library') ----- cork SampledSound addLibrarySoundNamed: 'cork' samples: (self mimeStringToBuffer: 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAA/wD+AP0A/QD7APoA+QD3APgA9wD4APcA+AD4AP0A+gD7AP0A/AD9AP0A+wD9APsA /AAAAAAAAwAEAAcAAgAIAAoACQANACcAHgAjACAAIQAnACgAGQAzAC4AHgAnACQAGwAbABMA AwD1AMEArACrAK8AvgDnAA8AJQAtABsA9wDUALUAuwDBAM0A9wAmACcAKQARAN0A0gDNANAA /AAKAA0AFADuAOAA7QDyACAAOgA0ADEACQDaANUA0wDuAB0AJwAqABAA4gDUANYA6gAQACAA JAANAOkA2wDdAO4ADwAgACEADQDxAOMA5QD6ABIAHwAeAAwA9wDuAPEAAwAWAB4AGgAKAPsA 9QD9AAkAFAAVAA0AAAD1APMA+gADAAkABwD9APMA8QD1AAAACQAMAAYA/ADxAOsA8QD6AAMA BgAEAP0A9gD4AP0ABAALAAcAAgD9APcA+wADAAwAEgASAAwABgADAAEAAwAEAAAA+wD1APMA 9gAAAAcADAAJAP4A8wDoAOYA7QD0AP4ABQADAAMAAgABAAUABgAGAAYAAgAAAP4A/AD9AP8A /wAAAAAAAgAGAAgACQAGAAAA+wD3APcA/QACAAYACAADAP4A+AD0APQA9wD7AAAAAAD/AP4A /QD9AAAAAQABAAEA/wD7APoA9wD3APsA/QABAAQAAgAAAAAA/AD9AAAAAgAHAAkABwAGAAMA AAAAAP8A/gD9APsA+QD4APgA+wAAAAMABQAFAAIAAQAAAAAAAAD/AP0A/AD7APwA/wACAAQA BQACAP4A+QD3APgA/QABAAUABQADAAAA/wD/AAAABAAJAAoACQAHAAMAAAD+AP0A/QD9APsA +gD6APoA+gD8AP0AAAAAAAAAAQAAAP0A/AD6AP0AAAAFAAkACwAJAAUA/wD6APgA+AD8AAAA AgADAAIAAAABAAIAAwAGAAUAAwAAAPsA+AD3APkA/AAAAAMABgAHAAYABQACAAAA/QD7APoA +wD8AP4AAAAAAAEAAwAEAAYACAAGAAQAAAD9APoA+gD7AAAAAgADAAQAAgAAAAAAAAAAAAEA AAAAAP4A+wD7AP0A/gABAAIAAQAAAP0A+wD7APsA/AD9AP0A/QD9AP4AAAADAAYACAAHAAUA AwABAAAAAAAAAP4A/QD9AP0A/gAAAAMABQAGAAMAAgAAAP0A/QD+AP8AAAD9AP0A/QD9AAAA AgAEAAUABAAAAP8A/AD6APsA/QD+AAAAAgADAAUABgAGAAYAAwAAAP8A/AD6APoA+gD8AP8A AQADAAUABQAEAAIAAAD9APwA/AD9AP0A/gD+AP8A/wAAAAAAAQABAAAAAAD+AP4A/QD/AAAA AAAAAAAAAAAAAAAAAAACAAMAAgAAAP8A/QD9AP0A/wAAAAAAAAAAAAAAAAACAAMAAwABAAAA /gD9AP0A/QD/AP8A/wD/AP8AAAABAAMAAwADAAAA/gD8APsA/QD+AAAAAQACAAIAAgACAAMA AwACAAAA/QD6APkA+gD9AAAAAwAEAAMAAQD/AP0A/QD9AP8AAAD/AP4A/gD+AAAAAQACAAMA AgAAAAAA/gD+AP8AAAAAAAAAAAAAAAAAAAAAAAEAAgABAAAA/wD9AP0A/QD+AP8AAAAAAAAA AQABAAAAAAAAAAAAAAAAAP4A/QD9AP0A/QD/AAAAAwADAAQAAwABAAAA/wD+AP4A/gD+AP4A /gD/AP8AAAAAAAAAAQABAAAAAAD/AP4A/gD/AP8AAAAAAAAAAQACAAMAAwABAAAA/QD9APwA /QD/AAAAAAAAAAAAAAAAAAAAAgACAAIAAAD+AP0A+wD8AP4AAAABAAIAAgABAAEAAAAAAAAA AAAAAP8A/gD+AP8AAAABAAIAAgABAAEAAAAAAAAAAAD/AP0A/AD8AP0A/gAAAAAAAgACAAEA AQAAAAAAAAD/AP0A/QD8APwA/gAAAAEAAgACAAAAAAD/AP8A/wAAAAAAAAD/AP4A/gAAAAAA AgADAAMAAQAAAP0A/QD9AP0A/wAAAAAAAAAAAAAAAAAAAAEAAQABAAAAAAD/AP4A/QD+AP8A AAAAAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAD/AP8A/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA /wD/AP8A/wD/AAAAAAAAAAEAAQAAAAAAAAD+AP0A/QD9AP4A/wAAAAAAAQACAAIAAQAAAAAA /wD+AP0A/gD/AAAAAAAAAAAAAAAAAAEAAQAAAAAAAAD+AP0A/QD+AAAAAQACAAMAAgABAAAA AAAAAAAA/wD/AP4A/gD+AP8AAAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAA/wD/AP4A/gAAAAAA AAABAAAAAAAAAAAAAAAAAP8A/wD+AP4A/wAAAAAAAQABAAEAAAAAAAAA/wAAAAAAAAAAAP8A /wAAAAAAAAABAAIAAQAAAAAAAAD/AP8A/wAAAAAAAAAAAAAAAAAAAAEAAQABAAAAAAAAAP8A /gD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8A/wD/AP8AAAAAAAEAAQABAAAAAAAAAAAA AAAAAAAA/wD/AP8A/wAAAAAAAQABAAAAAAD/AP8A/wD/AAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAA/wD/AP8A/wD/AP8AAAAAAAAAAAABAAEAAAAAAAAAAAAAAAAAAAD/AP8A/wAAAAAA AAAAAAAAAAAAAAAAAAD/AP8A/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AP8A /wD/AAAAAAAAAAAAAAAAAAAA/wD/AP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AP8A /wD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8A/gD/AP8AAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAA/wD/AP8AAAAAAAAAAQABAAEAAAAAAAAA/wD/AP8AAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAP8A/wD/AP8AAAAAAAAAAAAAAAAAAAAAAAAAAAD/AP8AAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wD/AP4A/wD/AAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AP8A /wAAAAAAAAABAAEAAAAAAAAA/wD/AP8A/wD/AAAAAAAAAAAAAAABAAEAAAAAAAAA/wD/AP8A /wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wD/AA==') samplingRate: 11025! ----- Method: SkeletonBaseInfo class>>createSoundLibFromWav:name: (in category 'sound') ----- createSoundLibFromWav: fileName name: aString "self createSoundLibFromWav: 'sound\cas.wav' name: 'cassete'" self createSoundMethod: (SampledSound fromWaveFileNamed: fileName) name: aString. self perform: aString asSymbol. (SampledSound soundNamed: aString) play! ----- Method: SkeletonBaseInfo class>>createSoundMethod:name: (in category 'sound') ----- createSoundMethod: aSampleSound name: aString " see self>>createSoundLibFromWav:name: " | method | method _ aString , ' SampledSound addLibrarySoundNamed: ' , aString printString , ' samples: (self mimeStringToBuffer: ' , (Base64MimeConverter mimeEncode: (ReadStream on: aSampleSound samples asByteArray)) contents printString , ') samplingRate: ', aSampleSound originalSamplingRate asString. self class compile: method classified: 'sound library'! ----- Method: SkeletonBaseInfo class>>initialize (in category 'class initialization') ----- initialize self installMenu. self installWorld. self installSound. self addPseudoMethodForBabel ! ----- Method: SkeletonBaseInfo class>>installMenu (in category 'class initialization') ----- installMenu TheWorldMenu registerOpenCommand: {'Skeleton Spreadsheet'. {SkSheet. #open}}. ! ----- Method: SkeletonBaseInfo class>>installSound (in category 'class initialization') ----- installSound | sounds | sounds _ self class organization listAtCategoryNamed: #'sound library'. sounds do: [:each | self perform: each]! ----- Method: SkeletonBaseInfo class>>installWorld (in category 'class initialization') ----- installWorld Preferences enable: #batchPenTrails! ----- Method: SkeletonBaseInfo class>>makeChangeSetForThisPackage (in category 'fileIn/Out') ----- makeChangeSetForThisPackage "This is for building .pr file" "self makeChangeSetForThisPackage" | aChangeSet package | aChangeSet _ ChangeSet current. package _ self default. package classes do: [:aClass | self addClass: aClass toChangeset: aChangeSet]. package extensionMethods do: [:method | aChangeSet adoptSelector: method methodSymbol forClass: method actualClass]. aChangeSet postscriptString: self default postscriptText. ^ aChangeSet! ----- Method: SkeletonBaseInfo class>>mimeStringToBuffer: (in category 'sound') ----- mimeStringToBuffer: aString ^ SoundBuffer fromByteArray: (Base64MimeConverter mimeDecodeToBytes: (ReadStream on: aString)) contents! ----- Method: SkeletonBaseInfo class>>mochi (in category 'sound library') ----- mochi SampledSound addLibrarySoundNamed: 'mochi' samples: (self mimeStringToBuffer: '8gDsAOIA3gDvAC4AUQBDAA8AAAAxACsAHQAtABIA4wDEAMEA6gDbAPYAOQAqAAwAEADzALkA xAAGAOgAzgABADAAMwAgADEAGQAEAAQAxgDgAPQA7QDUAN4A+gDtAPQABwD9ANoAxQDNANoA 4gAEAC8AOgBDAEEANgATAAIA6ADRAMcAxQDRANcA3ADpAAYAEQAtAEMAPwAtABwALQBDAD8A NgAwACcAHAATAAIA7wDoAM8AygDBAMkAxgDGANUA3wDqAPEA9gD7AAAAAAABAAgACgADAAIA AwACAAEA9wD1AAEABQAEAA4AEwAVABEAEQAQABcAIAAeABQAEgAgABcADgAVABIADwAIAA4A EQATABIACgAJAAoABAAAAPYA9wD7APkA+QABAAAA9gD7AAAA9AD0APcA7gDtAPYA8QDxAPcA +wD2AO8A8wD4APkA/AAAAAEAAAACAAAA/gD1APMA+AD4APcA+AD5APYA+wD8APoA/AD4APIA 7ADzAPYA+gD7AP4ABAAHAAoACAAEAAIAAAD4APkA9wDvAPAA+AD8APoAAAAAAAMABQAFAAQA /wAAAAAABAAEAAkACwAGAAoADgANAAgACQAGAAIA/wD9APkA+wAAAAEAAAADAAgACAAKAAsA CQAOAA8ADQAQABIADgAIAAcADAAQAAwACAAEAAUAAgACAAUAAgAEAAgACQAFAAcACQAGAAcA BwAHAAQABQAGAAYABQAAAPwA/AAAAAAAAAAAAP4AAAAAAP0AAAACAPsA9QD6APwA+gD6APoA +QD4APgA+gD8APoA+AD5APoA+wD8APoA/AD/AP8A/QD9APwA+QD2APUA9wD1APUA+gD7APoA +wD7APsA/gAAAAAAAQABAAAAAAAAAAQABQAAAAMAAAD9AP4A+wD7AP0A/QD9AP0A/QD+AP0A +AD4APcA9QD3APcA9wD8APwA+wD9AP8A+wD5APoA+AD5APsA+AD7AP0A/gAAAAIAAwAAAAAA /gD8APwA/AD9AP4AAQABAAAAAgAFAAUAAgACAAEA/wD+AP4AAAABAAIAAAAAAAEA/wAAAAEA AAAAAP4A/QABAAIAAAACAAIAAQABAAAAAAAAAAAAAAADAAMABAADAAIABQAFAAIAAQADAAEA AgADAAIABAAEAAQABAAEAAMAAwAFAAQABgAGAAUABgAHAAcABQAEAAQAAwACAAAAAQABAAEA AQADAAMABQADAAEAAAAAAP8A/gAAAAEAAgADAAYABwAEAAQAAwABAAEAAgAAAAEAAgABAAEA AQAAAAAAAAACAAMAAAD/AAAAAgACAAEAAQACAAEAAAACAAEAAAD/AAAA/gD+AAAAAAAAAAEA AAAAAAAAAAD+AP0A/QD9AP4A/gD/AAAA/wD/AP0A/QD9AP0A/QD9AP4A/gD+AP4AAAAAAAAA AAABAAAA/AD7APsA+wD8APwA/gAAAAAAAgAEAAMABAAFAAUABAAEAAIAAAAAAAEA/gD+AAAA AAD/AAAAAAD+AP0A/QD/AP8A/AD9AP8AAAAAAAMABAAEAAUABAAFAAUABAAEAAMAAwADAAMA BAAHAAcABAAEAAIAAwAFAAQABQAHAAcAAwADAAQAAwADAAUAAwACAAMAAQABAAQAAgAAAAAA AAAAAAAA/wD+AP4A/QD+AP8A/wD+AP4A/gAAAP8A/gD/AP4A/wD/AP8A/gD7APoA+AD5APoA +gD8AP0A/AD+AP8A/gD+APwA/AD9AP0A/AD9AP4A/QD/AAAAAAAAAAAAAgAAAAAA/wD/AAAA AAAAAP8A/wAAAAEAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAQADAAIA AAD+AP8AAAAAAAAAAgACAAEAAgABAAAAAAABAAAAAAAAAP8A/wABAAAAAQABAAAAAAACAAMA AQADAAQAAwABAAEAAQAAAAEAAwACAAIAAgAAAAAA/wD+AP4AAAAAAAAA/wD/AP8A/wD/AAAA AAAAAAAA/wD+AAAAAQAAAP4A/wD/AP4A/gAAAAAAAAAAAAIAAQAAAAEAAQAAAAEA/wD+AAAA /wD/AAAAAAACAAAAAQACAAEAAQAAAAAAAAAAAAAAAAACAAIAAQADAAMAAwACAAIAAQAAAAAA AAD/AAAAAAD/AP8AAAAAAP4A/gD9AP0A/QD9AP4A/wD/AP8A/wAAAAAA/wD+AP4A/gD9AP0A /gD9AP8AAAAAAAAAAAD/AP4A/gD+APwA/QD9AP4A/QD+AAAAAAAAAAAA/wD+AP4A/gD9AP4A /QD+AAAAAAAAAAAAAAACAAAAAAAAAAAA/gD+AP4A/wD/AAAAAAAAAAAAAAD/AP8AAAD+AP0A /QD/AAAAAAD/AAAAAgAAAAAAAAD/AP4A/gD9AP0A/QD9AP4AAAABAAAA/wAAAP8A/gD+AP4A /gD+AP8AAAD/AAAAAQAAAAAAAQAAAP4A/wD/AP4A/gD+AP4A/wAAAAAAAAD/AAAA/wD+AP8A AAAAAAEAAQACAAIAAwACAAIAAgADAAEAAAABAAIAAwAEAAQABQAFAAMAAgABAAEAAQAAAAEA AgADAAIAAgABAAAAAAAAAAAAAAABAAEAAgADAAMAAgACAAMAAQABAAIAAgABAAAAAAAAAAAA AAAAAAEAAQABAAEAAQADAAMAAgADAAMAAgADAAQABAAEAAMAAgACAAIAAgACAAEAAgABAAAA AQABAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAgABAAEAAAD+AP4AAAD/AP4A/wD/AP8A /wAAAP8AAAAAAP4A/wD/AP8AAAAAAP8A/gD/AAAA/wD/AP8A/wD/AP4A/gD+AP8AAAAAAAAA AAAAAP8AAAABAAAAAAAAAAAAAAAAAAAAAAAAAAEAAQAAAAAAAAAAAAAAAQACAAEAAAAAAAEA AAABAAEAAAAAAAAAAAAAAAEAAAAAAAEAAAAAAAAAAQABAAEAAAAAAAAAAQABAAEAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AP8AAAAAAP8A/gD/AAAA /wD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAP8A/wD/AP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AP8A/gAAAAAA AAAAAAAA/wD/AP8A/wAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAAAAAD/AAAAAAAAAP8A /wD+AP8A/wAAAAAAAAD/AP8AAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAEAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAEAAgACAAEAAQABAAEAAgACAAIAAgABAAEA AgADAAIAAQABAAMAAgACAAIAAgAAAAAAAQABAAEAAQAAAAAAAAABAAAAAAAAAAAA/wD/AAAA AAAAAAAAAAAAAP8AAAAAAAAAAAABAAAAAAABAAAAAAAAAAEAAQAAAAAAAAAAAAAAAAAAAAAA AAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAAAA/wD/AP8A/wAAAAAA/wD/AP8A/wD+AP4A /wD+AP4A/gD+AP4A/wD/AP8AAAD/AP8A/wD/AP8A/gD+AP4A/wD/AP8AAAD/AAAAAAAAAP8A /wD/AP8A/wD/AP8A/wAAAAAAAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEA AQAAAAAAAAAAAAAAAAAAAAAA/wD/AP8A/wD/AAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AP8A /wD/AP8A/wD/AAAA/wD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAAAA /wD/AAAAAAAAAAAAAAAAAAAAAAAAAP8A/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAA/wD/AP8A/wD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAEAAQABAAEAAQAAAAAAAAAAAAAAAAABAAEAAgACAAEAAQABAAEAAAAAAAAAAAAAAAAA AQABAAEAAQAAAAEAAQABAAAAAAAAAAAAAAAAAAEAAQABAAEAAgABAAAAAAAAAAAAAAAAAAEA AQABAAEAAQAAAAEAAQAAAA==') samplingRate: 11025! ----- Method: SkeletonBaseInfo class>>point (in category 'parts bin') ----- point "self point openInHand" ^ EllipseMorph new extent: 24 @ 24; color: (Color r: 0.0 g: 0.8 b: 0.7); borderColor: (TranslucentColor r: 0.0 g: 0.8 b: 0.7 alpha: 0.4) yourself! ----- Method: SkeletonBaseInfo class>>renameAllProtocol:to: (in category 'utility') ----- renameAllProtocol: before to: after " Change all method category. self renameAllProtocol: #'*skeleton-2003' to: #'obsolete-sk2003'. self renameAllProtocol: #'*skeleton-2003-var' to: #'obsolete-sk2003-var' self renameAllProtocol: #'*skeleton-velocity' to: #'obsolete-velocity' self renameAllProtocol: #'*skeleton-morph-sumim' to: #'*skeleton-connectors-sumim' " ProtoObject withAllSubclassesDo: [:class | (class organization listAtCategoryNamed: before) isEmpty not ifTrue: [class organization renameCategory: before toBe: after]. (class class organization listAtCategoryNamed: before) isEmpty not ifTrue: [class organization renameCategory: before toBe: after]]! ----- Method: SkeletonBaseInfo class>>rice (in category 'sound library') ----- rice SampledSound addLibrarySoundNamed: 'rice' samples: (self mimeStringToBuffer: 'CgAGAPQADAAAAAgA/gAIAPoABAAEAO4AAAAAAPoA9AAGAAIA+gAIAPIACgD6AAoA+gACAA4A AAD+AP4ABADmAPQADAD2AP4AAAD2AAgAAAD0AA4A/gACAAgACAAAAAgAAgD2APgA/gDwAPoA BgDyAAYA6AAWAPgAAgD8AAIAAgAOAPYABgAGAPoACgD6AAIA8gACAPYAAAAAAP4A+AD8AP4A AgD8APwABAAOAPwACgAMAAIA/AACAPQAAgAAAAYA9gD8APwABAD6APgA8gAAAPgACAAAAAYA AAAGAAQA/gAGAPoAAAAAAP4A+AAAAPgA+gAEAP4A/AD2APoABAAEAAgA9gAOAP4A/gAGAP4A DAD+APAACAAAAPYAAgD0AP4A+gD6AAQA/AD6AAwA9AAAAP4ACgD6AAoA/gAIAP4AAgAGAAAA +gD+APQA7gAAAPYA/gAAAPgA+gD6APwAAgAKAAIACAD6AAQAEgD6AAgA/gD2APgA+gD+APwA 9gD6AAQA/AD4AAQA/AAOAAAA+gAKABAA+gAEAAQA9AAGAAIA5gAIAP4A7gD6AAYABADuAPwA DgD6AAAABgAGAPgACgAIAAoA+AACAAgA9gDyAAIA9gAEAPAA+gD8AAIABAAAAAIAAgD+AAYA /gAIAAYA9gAIAAIAAAAGAPgA+gD+APoABADuAPQABgD4AAgA9gD+AAoAAgD8AAwAAgAKAAIA AAAEAPoABgAEAPYA8gAEAPQA+AD2AAAABAAAAP4ABAD8AAwA/gAEAAoA/AAAAAwA/AD4AAAA /AD8AP4A9gAAAPwA/gD6APgACAD+AAYAAgAIAPwACAACAP4ABgD+AAIA/gD6APoA9AD8APoA /gD8APwABAD8AAQAAgD+AAQA/gAGAAIAAgAAAAAA/gD2AAQAAAACAPYA9gD8APoAAAAAAPwA /AAGAPwACAAAAAQA/gAAAAgAAAD6AAIA/AD+APoA8gD8AAIAAAD6AP4A+gACAP4ABgD8AAYA BAAAAAQABgD+APwA/gAEAAIA/AD2AP4A/AAAAPgAAgD4APwA/gD+AP4ACAAAAAQABAAAAAYA AAD8AAYA9AAIAPwA+gD6AP4A/AD4APwA+AAGAPwABgAAAAAAAAAEAAAACAD+APoAAgD+AAAA +gD8APwA+AD6AAAA/gD+AAAAAAAEAAIAAAAEAPgABAD8AAAABAACAPYABAD+AAAA/gD4AP4A /AD+AAAA/gD+AAIA/AAEAAQA+gD8AAIA/gD8AAAABgACAAIA+AAAAP4A+gD+AAAA+gD+APoA /AAAAAAAAAAAAP4ABgD+AAYA+gACAAIAAgD+AP4AAgD8APQAAAD8AP4A/gD8AP4A/gAAAAIA BAAAAAIABAACAP4AAgAAAP4A+gD8AP4A/gAGAPQA/gACAPwABgD6AAYAAAAAAAIA/gACAAQA BAD6AP4A/gD6APwAAgD6APwA/AAAAAQA/gAAAPwAAAAAAAYA/AAAAA==') samplingRate: 11025! ----- Method: SkeletonBaseInfo class>>unstick (in category 'sound library') ----- unstick SampledSound addLibrarySoundNamed: 'unstick' samples: (self mimeStringToBuffer: 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAADAAAAAAD+AP0A+gACAAQAAAAAAAAA AAAAAP8AAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA /wAAAAAAAAABAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAQD/AAAAAQAAAP8AAQACAP4AAQATAAAA/wAKAPQA 9gD8APUABQD/APQACQAEAAQAAAAFAAQAAAAAAPsA/QD3AP0A/gAGAAUABAAGAAIA/gD/AAEA AAD/AAAAAQABAAQAAwAAAAAA/gD9AP4A/wD/AP4AAAABAAAAAAABAAAA/wABAP4AAAAFAAQA +gAHAAEAAAABAAAA/QD8AAAA/AABAAEAAAACAAAAAAABAAAAAAAAAAEAAAAAAAIAAgAAAAAA AAD+APwAAAAAAAAAAAAAAAAA/AD9AAAAAgADAAAABAAAAAAAAQABAAAAAAAAAAAAAAD/AAAA /QD3ABUACQDmAP8A7gD6APwAEAAAAA4ABAD/AP8AAAD8AAAA/QAAAP0AAgAEAAMAAQABAP4A /AD+AP0AAQACAP8AAAAEAAAAAAACAAEA/wD+AAAAAAAAAAAA/wAAAP8A/AD/AAAAAAABAAEA /wD9AAIAAQAEAAMAAAABAAUAAAAAAP0AAwD6APwA/gABAAAAAQD/AAAAAgD+AAAAAAD+AAAA AAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQACAP4AAAD+AAIAAAAAAAIAAAABAAAAAAABAAAA AQAAAAAAAAD/AP8AAQAAAAAAAAAAAAAAAAAAAP8AAAAAAAAA/gABAAAAAAABAAAAAAABAAEA AAAAAAAAAAD/AAAAAAAAAP8AAAAAAP8A/wAAAAIAAAAAAAAAAQAAAAAAAAD9AAAA/gAAAAAA AwACAAAAAAD/AP8AAQAAAAAA/wAAAAAA/gAAAAAAAQAAAAAAAAD/AAEAAAD6AAMAAAACAP8A AgD8APIA9wALABMABAD/APoA9gD/AAMACAAGAAUAAgD+APoA9wD7AP4AAgAAAAMABgAEAAEA /AD9AP8A/wABAAQAAQAAAP4A/gD+AP8A/wD6AAUABQAQABAAAADsANcA8QD0ABoADwAIAAYA AwD9AAIAAwD6APsAAQABAAQACwAEAP0A/gD8AP8AAwADAAAAAgD+AAAA/wD/AP8AAgACAAAA AAD8AP0AAAD+AAAAAAAAAPwABQADAAAABQD/AP8A/AD9AP0AAAACAAQAAwAAAP8A/QD+AAAA /gAAAAEAAAADAAAABAD+AAAA+wD/AAAAAAAFAAQAAQD+AP4A/QABAAIAAQAAAP8A/wAAAP8A AQABAAEAAQACAAAAAAAAAP4A/QD/AP4AAAACAAIAAAABAAAAAAD/AP8A/wD+AAAA/gAAAAIA AAACAAQAAAD/APsA/QD8AAMAAQADAAAAAQD+AP8AAAD+AAAAAAAAAAIAAQAAAAAABQAHAAAA DQAAAOwA8wDvAAkA/AAOAAkAAQD8AAIAAAD+AAQACgD0AAwA/ADyAAoA4QD+AAcA+wAAAAoA AwD9AAYADAD9AAwAAwAHAPkACQD2APgABgDzAPwABQD6AAUAAgD7AAIAAAD/AP4ABAAGAAEA /wD+APwAAwABAAAAAAABAP8AAAD8AP0A/wD/AAAAAAACAAAABAABAAAAAAAKAPgAAgAAAAAA 9wAHAP4A9wACAAQA+AAIAAwADAAJAOsA9ADeAAAAJwADAAUADADtAOAADQD1AP8AEgD1APQA CwAaAP8ABwABAOkABAAAAP4AAgAAAAAACQAJAAAAAQAGAPkA/QD/APYA+gAAAAEABAALAAIA AQD/APkA/gAJAPUAAAADAPwA/AACAAAAAQAGAAUA/AD9APcA9gADAAoAAgADAP8A/QAHAP0A /QD/AP4AAAAJAAMAAQABAPwA/gAAAPoABgD1AAEAAwAHAAAAAAABAPwAAQAEAP8A/AD+AAMA AgAAAPsA/wD7AAEAAgD/AAAA/wAAAAIABAABAAEA/QD+AAIA/gACAP8AAAD+AAAAAQABAPsA AAACAAEAAQAAAP0A+gAAAP4AAwD/AP0A/gD4APgAJAAFAAkA/AABAOAAAgDwAAIACgAGAA0A FAAMAPoABwDTAOoAAQDxABoADgD+AAoA/gAFAP0A+gD9APcA/AAEAAMABgAIAP0ABgABAPsA /gD9APsAAgACAP4A/gAMAAUAAAAFAPoA8QD8APkAAAAKAAUABwD/AAAA/AD8AAIA9wACAAcA AAAFAPoA/QACAP4A+gADAPwA+wACABQA/AALAPYA+gDsABAABgAGAAEABAD+APsABgDyAO0A AAD5AAcAEQAHAAIABAAAAP8AAAD9APcA/QAEAAYACQAHAPoA+wD0APUAAAD+AAsACgAHAAYA AQAEAAAAAQD8APwA/gAAAAEABAAAAAIAAgAAAP4AAAD/AP0A/AAAAAEABgABAP8A/wAAAAAA AAD8AP8A/QD5AAAAAwAAAAMAAAD+APwA/AAAAP4AAQAAAP8A/QDwAAkA/gAHAAoA/QAAAPsA AAD/AAQAAAAAAAAAAAABAAIABwAAAAAA/QD8AP8AAAACAAIAAAAAAP0AAgAAAAQAAAAAAP0A /gAAAAIACAAAAAEA+AD5AAUA/gAHAAEABwAAAAAAAAD+AP0AAQABAAAAAQAAAAAAAAD9AAAA AAD/AAMABgAHAAEA9gAAAOYABAD6AAAABAAIAAEAAAAAAP0AAAD/AAAA/gD/AAIA/wD/AAEA AgD+AAQAAQABAAEA/wD8AAAA/QAAAAMAAQAAAP8A/AD8AAEA/gD/AAAAAAAAAAEAAQACAP8A AwAAAAAAAAAAAAAAAQAAAP4A/gD/AAAAAAAEAAMAAAAAAAAAAQABAAIAAAD/AAAA/AD/AP8A /AAAAAEAAAABAAMA/gAAAAAAAAABAAAAAQAAAAIAAgADAAEAAQABAAIAAQAAAAAA/AD8APoA /QAAAAIAAgABAAIAAwACAP4A/gD3APUA+gAEAAkACgABAP8A9gAAAAAAAQD/AAEAAAACAP4A AQD+AAEA/wAAAAEAAQAAAAEA/wAAAAAAAAAAAP4A+wAHAAQA7AAIAPkA+wAGAAoA9gAKAPsA AgD6AAIAAQADAAQAAQACAAEAAQD/AAAA/gD/AP0AAAAAAAAAAQAAAPwAAQD/AAEABAAAAP4A AwD3AAAAAAADAAUABQABAAAA+gD9APsA+gAAAAEAAAD9AAIAAAAFAP0ABAAAAAQAAAADAAEA AQAAAAAAAQACAAMAAQADAAAAAgD/AAEA/QD8AP4A/gD9AP4AAwACAP4AAAD9AP4A/QAAAP8A AwAFAAEABAACAPwAAAAAAAAAAwABAP4AAAD/AP8A/AD9AAQA/QAGAAQABgD7APwA+QD6AP0A /QADAAMABgADAAAA/gD8AAMA/QDuABYA+wAbAPoABQDzAPgAAAD6AAcAAgAEAP0ABwAAAAAA AAADAP4A/gD8AAIA/AACAP0ACgAAAAcAAAABAPsAAwD/AP8AAAADAAMAAAAEAP8A/gD+AAEA AAABAAEAAAD7APwAAAD+AAEAAAD/AP8AAQAAAAEAAAAAAP4AAQD/AAAAAQAEAP8A9wABAP4A 9QAAAP8AFADzAAAABgD2ABIAAAAAAAEA+QD+AAQAAAAHAP4AAgAAAAMABQACAP4AAAD7AP4A /gABAAAAAQD/AAAAAAABAAEA/QD+AAEAAAAEAAIAAAAAAP0A/AD8AAIABgAEAP4A/gD6APwA BgAAAAgA/AABAPoAAAD+AAMA/gAAAP8A/wAAAP8AAgAAAAAA/wD/AAAAAAABAAAA/wACAAAA AAAAAP8AAgADAP0A/gAJAAEABQD6AAAAAgD+AAgA/QD7APgADAD4AA8A+AAGAPYAAAAAAAIA AQACAP8ABQAAAAAA/wAAAAAA/wABAP8AAgD+AAAA+gAAAAUABQADAAAA+gD/AAEAAwD9AAIA /gAFAP4A/QD/AP0AAgD+AAEA+wAQAAAA9wDmAOgA+gD4ABcAGAALAAcAAgD9APUACQACAAsA DADoAOEA9QDvAAQAHAAYABAACgD/APcA9wAEAAkAAwAKAPoA+gAFAAAAAAD5APcA+wACAAYA AQD/AP4A+AD7AAAAAQAAAAAA/gD/AP8A/gABAAIA/gD+AAAA/QD9AAIABQAAAAAA/wAAAPwA /AADAAEAAAAAAAAA/wAAAAQAAAADAAAAAQAAAAMABQAAAAEA/AAAAP0ADAD/AAUA+gADAOwA AQDoAA0AAAAeAPYACgD5APUAAwABAAIAAAAEAO4ADQARAAUAEAAGABsA6wAAAPsACAD7APgA 6gAFAAEAEAAGAP8A9AD7APkA+QD5AAEABAD/AP8AAAD+APoABAD+AP8A+wD6AAAAAwD+APkA /gADAAAAAQD/APwA/gD/AAAA/wADAAUA/wAAAAIAAAABAAMAAQAAAAAAAAAAAP8AAgAAAAIA AwAAAAEAAQD/AAEAAQABAAQAAgACAP8AAQACAAIA/AD/AP4AAgADAAIAAQAAAP4AAAAAAAAA AgAAAAMA/QD9AP8ABAACAP8A/wAAAP0AAQABAAAA/wAAAP4AAAAAAP4AAAAAAP8A/gD+AAAA AAD/AAAAAAD+AAIAAAAAAAAA/gAAAAAAAQD8AAAAAQAEAP8A/gD9AAIAAQAAAAEAAwAAAAEA AAAEAP8AAAAAAAAA/wAAAP8AAAD+AP8AAAABAP8AAAD/AAAA/wAAAAAAAAAAAAAAAAAAAP8A AAABAAEAAQABAAAAAAAAAAAAAAAAAAAA/wD/AAEAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAA/wAAAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAP8AAAAAAAEAAAAAAAAAAAAAAAAA AAAAAP8A/wAAAP0AAQAAAAEA/wAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAA/wAAAAAA AAAAAAAAAAAAAAAAAQD/AAAA/wAAAAAA/wD/AP8AAAAAAAAAAQAAAP8AAAAAAAAAAAABAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wD/AP8AAAABAAEAAgAAAP8AAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAIAPkABQD8AAMA/gABAAAA/wD/AAMAAAAAAAEA AAAAAAAAAAD/AAAAAAD/AP8AAAD6AAAADgD8ABEA8wAJAPQA/QD/AAIAAQACAAIAAAABAAAA /wAAAAEAAAACAAAAAAAAAAAAAQD/AAIAAAAAAP8A/gD9AAIA/AAGAAAAAQAAAAAA/gD/AP4A /wAAAAYA/AAMAPkAAwD6AP8ABgACAAAAAAD4AAEA/QACAAAA/wAGAPsAAgD8AAEAAAAAAAAA AAD7AAEACAD6ABAA8wAHAPgA/wACAAIABAABAAAAAAAAAAEA/gAAAPwAAAACAAAAAgD/AAAA /wD/AAAA/wABAAEAAAD/AP0A/QD/AAAAAgABAAAAAAAAAAAAAAAAAAAAAQAAAAMAAAAAAP8A AAD+AAAAAAAAAAEAAgAAAP4AAgABAP8AAwD9AAQA/QADAAAA/wD/AAAAAAAAAAEAAAAAAAEA /wAAAAAAAAAAAAAAAAAAAAAAAQAAAAAA/wD/AAEA/wAAAAAAAAD/AP8AAAAAAPwA/QAWAPcA 9gABAAMA+gD9AAsAAAD4AAkABgD3AAEABAD4AP4AAAAAAP8AAQAEAAAAAAACAAMABQD+AAAA AAD/AAAAAgAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAA/wAAAAAAAAD/AAEAAAAAAP8A AAD/AP8AAAACAP4A/gABAAAA/gD/AAEAAAD/AAAAAgD9AP0AAQAAAAEA/gD/AP8AAQAAAAAA AAD/AAAAAAAAAP4AAAACAAEAAQAAAAAAAAAAAAAAAAAAAP8AAwACAAAAAQD8AAMA/gADAAAA AQD/AP8A/wAAAAQA/wABAAMA/QAJAPgABAD+AP8AAAABAAAAAAD9AAEA/QAAAAAAAwAAAP8A /QAAAP8AAAABAAEAAgD6AP0ABAD3AAUA/gD/AAAAAAACAAAABAABAAIAAQAAAAEAAAACAAAA AAADAAEAAAD7AP4A/gD/AAEAAQD/APwAAAADAAEAAwD+AP0AAAD/AAEABQADAP8A/AABAAIA AAAAAAAABAACAAAA+wD7AAsACQAGAPoABwD/APcA/AD3AP8A/wAFAAEAAAD9AAAA/QAAAP4A AAAAAAAA/wAAAAIABAADAAoAAAAHAP8ABAD/AAIAAQADAPwA/gD9APoAAgD+AP4A/gABAAAA AAAAAP4AAQAHABAAGQDoAOEA1AAGAAQAIwATAPkA7wDtAP4ABwAZAP4A+wAFAPoACAD/AAQA AAD3AP0A+QABAAYA/AAEAPsABQAAAAIA+wACAAAAAAAAAAAAAgAAAAAABAAHAPkA+wD6AP8A BgALAAEAAQD5APwAAAACAAsAAwAAAPUA+wACAAMABAADAP4AAgD8AAIA/gD7AAIADADxAA8A 8QADAAIA/AD5ANoA9gATAA0ANAAeAPYAwwDOAAEALQA8ACQA2gDDAOcAHQAzACoACwDuAOsA /wAKAA4ABAD7AO8AAgABAAIA+gAAAAgA+gAFAPAAAADtAAYAAgAJAPEA/gD7AAEA6wD8AAEA BAAEAPAA7QD+AAcAAgANAOoABgD1AAAAEAAbAPEA9AD6ANAA+AADAAQAFwAdAAQADwAPAPkA CgD4APoA6wD6APsAAQAAAAQA7AADAPEA/QAXAN4AAwAHAP0AHwAHAA0A7wAAABcACQANAAsA BAD0AP0A9QD+AAUACQAAAAgAAwADAPkA/QD5AAUA/QAHAAQA+AD1AAAA+wAVABcA1ADsAAQA /gAgAOkADAAJAAsAzwDsAOMAIQBGACYA6QDmAM4A8QArAAYAHgDkACkAEgA5ABQA6QDGAN8A 5QAcAA4A8wDdAOcA8AAQAB4AHgAKAO0ACQD4AAYA+wDyAPkAHwASAPYA9wD6AO4ACQAFAAMA +AD1AA0AIgAYAOUADADWAOMA6gD7APwA6QDvAPcABgACABoADQAOAPMA+QD6APUA+gACAAMA 8wAHAA8ACQAIAAoA8ADyAPcACgATABsAEQAQAAwABAD4AAsABAANAAIABwD4AP0ABQD/AAsA BAAEAPoABAAFAAEAEgD7AAQABwALAAgAAAAKAPUA7gD0APUA+gAUAPsA/wAEAAoAAAD5APQA 9QD/APoABQACAPkACAAAAAMA8wDwAPcA7wD/AAsACwD4ABEA8QDxABcAIAAQAPgA5wDlAO4A +AAHAA4ACQDyAPwA8ADwAPcA+wD3AAAA/gD/AAAACgABAP8ABgAKAAIA+QD/APoA6QAmAA4A 9QDxAAYA2QDkAO0AAAA3ACIAHAD+AP0A3QDrAAIAHAAUAPMA6QDxAAMACgD3APUA+AAGAAIA CgDuAAoA+QAFAOIAIgAHABoAAQACAO8AAQDwAP4AEQALAAsA6gAAAP0ACQAFAAAABQD9AAEA 9wAKABUA/wD6APgA/gAAAAsA8QD7AAAAEQD9AAAA/wD3AAQAAwD9AA8A8QAMAAAA+QAIAP4A CADyAAgA+gAUAAMA+wDsAPUA/gAAAAIACADzAAQA/AD1ABMAAQALAAYADQD/AAoA+wD9AAkA 9QD9APsABQD5AAEA/wD/APoADADoAPEA/QAQAAQABwD2ABUAAAAHAAsACgACAPUAAwABAP4A BAACAPwAFQDrAPAADgD6AAYACwDvAOUACQADAP8A9QD7AAIA8AD8AAQABgAHAAEA/wD4AAAA /AD8AAIA+wAIAAAADQD8AAAABwAGAO4ABQAGAP8A9QAgAPMACwAFAAkAFQDvAP4A/wADAAYA CgDlAOUA/gAAAAwAEAAbABIAAgACAAkA7wABAO8A9gD3AAAA4wD3ABUA8wAdAAQADgAAAAEA FgD3APMA/wD9AP4A/gAIABkA9QDqAPsA5AD2ABQA6AADAPgABgAMAAUADwALAOsA9QD3APUA CQAKAAwABAAAAPsA/gAHAP8A/QANAP8A/QABAAoAAAAIAP0ACgADAPgAAwAAAAAA9wADAAcA AQAEAPcAAgD8AAAA+gD7AAgA/QDzAAAA8wAFAAcAJgD4AOEA8QDgAOsADwAPAOsACwD7AB8A AgARAA8A1wDvAOoA5AANACEAFQAGAPoACQAAAA0AFgARAPcA/gD8AAoAAAD9AAEAAQDzAAYA /QAAAPsA/QDwAPUA7gD2AAkABAABAAAA/QD8AAAAAAAYAAsAAAAAAP0A/gAHAPsA/wD8ABEA /wAAAOoA7gD1ABgA+QAFAAsA7QD9APUA2ADmAPMABwATABoADAAHABQADgAOAAYACwAFAAcA +AAAAAcAIAAcAPYA+ADjAN0ABgATABIADAD3AOIA+gAEAPgA/gASAAsAFAARAPQA6QAAAAIA CAAEAAsAAAD8APUA/wD1APYA8wD3AAcA/QAIAAkA9QD7AP0ABAD8AAYAAwD4APUAAwAGAAUA CQAGAPwA/gD+APkA/QAAAP8A/AAIAAMA9AD6AAQA9AAEAAgAGQANAAoA2gAMAOgA9gAZABEA 4AASAP8AAgAaAAgAAAAEAPkA9wDtAO4A8AD/APsAAAACAAgAEQAJAP0AAAAHAPIA/AAEAPcA AAD5AAIA/wD2APQABgADAP0AAgAHAPkAAQAHAAUAAwAFAP4A/AAEAPwA/wABAAYACgAYAPYA CQADAPQA+wD7AAgA/gAAAPMA+wABAPgADgAKAAkABADuAPkA+QD1AAMAAgAIAAUABQADABYA CAD5AAYA+wD9AAAA/wAFAPoA/gAAAP0AAAD5APwABAAVAAIA8AD7AO4A+QD+APMA9wAEAAgA EgAIAAIADAAAAAoA9AD8AP4A+gD5AAoA9gD/AAQAAQABAPsAAgADABgA/AAAAP4ADQD5AAAA +gDxAPoA/wADAAAA+gAAAPUABwD7AAAAFAD2AAkA/wANAOcA/wAAAAAABADxAAwA9QADAP0A BgAFAPIABQD0AAAA/wD4ABgA8QABAAEA/wAMAAEAAQD3ABIAAgAFAA4ACAD6AAMAAQAMAAYA +gAEAAAABgAEAP0ADQD4ABEA8gD/APwA+AAEAP0ABAABAAAAAAD6AP4A+QD3APkAAAADAPgA 7wD5AAEAAgD8AP0A9wD6AAQACgD9AP4AAAAEAP0A/wAGAPoAAgACAPwAAgD9AP0A+wAFAAQA AwADAAIAAQAEAAMA/wD+AAIAAQAGAP4A+gD9AAQAFwD9AAMAEQD4AAEADwAJAAgA/wD+AA4A CwD3APIA8AD9AAQAAAD6APgA+QDxAPMAEwAhAPoABQDqAPcA7QANAAwADAD3AAIA8wADAPcA BQD7AAIA/gADAAEA/QD5APsA+wD/AAgAAAAHAPoAAQD+AAgAAgABAP0A+wD7APwAAAAHAAAA BQD9AAEA+QD3AO4A9gD6AAAA/wACAPoA+QA=') samplingRate: 22050! ----- Method: SkeletonBaseInfo class>>version (in category 'constant') ----- version ^ '0.4.1'! ----- Method: SkeletonBaseInfo>>packageName (in category 'naming') ----- packageName ^ 'Skeleton-Base'! ----- Method: SkeletonBaseInfo>>readmeText (in category 'introspection') ----- readmeText ^ 'Skeleton ', self class version, ' Skeleton is a easy scripting system with spreadsheet-like user interface. It handles an etoy''s slot as a spread sheet''s cell. So user can describe declarative rules among morphs as spread sheet''s "=A1 +A2" style. It is similar with Visio''s "shape sheet", but Skeleton-sheet has more dynamic and real-time behavior. Takashi Yamamiya <[hidden email]> http://languagegame.org:8080/ggame/11 SkSheet example 2004-04-10 Fix some dirty code (Remove references of Transcript, Fix a word in world menu). Support Babel. '! PackageInfo subclass: #SkeletonInfo instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Skeleton-Base'! !SkeletonInfo commentStamp: 'tak 3/30/2004 21:40' prior: 0! I am a full Skeleton package information.! ----- Method: SkeletonInfo>>packageName (in category 'naming') ----- packageName ^ 'Skeleton'! ----- Method: Color>>asCellText (in category '*skeleton-base') ----- asCellText ^ '=', self asString! ----- Method: Object>>asCellText (in category '*skeleton-base') ----- asCellText ^ self asString! ----- Method: Object>>isSkObject (in category '*skeleton-base') ----- isSkObject ^ false! ----- Method: Object>>rule:do: (in category '*skeleton-base') ----- rule: sub do: aBlock ^ SkRule new observer: self subjects: sub rule: aBlock! Object subclass: #SkCellScreenConverter instanceVariableNames: 'border grid xCache yCache offset cellTopLeft' classVariableNames: '' poolDictionaries: '' category: 'Skeleton-Base'! !SkCellScreenConverter commentStamp: 'tak 12/27/2003 16:55' prior: 0! Main comment stating the purpose of this class and relevant relationship to other classes. Possible useful expressions for doIt or printIt. Structure: border Number model grid SkGridMorph xCache Array yCache Array offset Number topLeft of the cache screenOfset Point ! ----- Method: SkCellScreenConverter class>>grid:border: (in category 'instance creation') ----- grid: anSkGridMorph border: aNumber ^ self new grid: anSkGridMorph border: aNumber ! ----- Method: SkCellScreenConverter>>cellAreaToScreen:topLeft: (in category 'accessing') ----- cellAreaToScreen: aRectangle topLeft: topLeft ^ (self cellToScreenRect: aRectangle topLeft topLeft: topLeft) topLeft - border corner: (self cellToScreenRect: aRectangle bottomRight - 1 topLeft: topLeft) bottomRight + border! ----- Method: SkCellScreenConverter>>cellToScreenRect:topLeft: (in category 'accessing') ----- cellToScreenRect: aPoint topLeft: topLeft | xRange yRange | (self extent containsPoint: aPoint) ifFalse: [self createCacheFor: (self extent merge: (aPoint extent: 1 @ 1))]. xRange _ xCache at: aPoint x - (cellTopLeft x + offset x) + 1. yRange _ yCache at: aPoint y - (cellTopLeft y + offset y) + 1. ^ (xRange first @ yRange first corner: xRange last @ yRange last) translateBy: topLeft! ----- Method: SkCellScreenConverter>>createCacheFor: (in category 'private') ----- createCacheFor: aRectangle "xCache = #{{left. right}. {left. right}. ...}" | first last screenOffset | offset _ aRectangle topLeft - cellTopLeft. screenOffset _ self createOffset: offset. xCache _ Array new: aRectangle width. first _ screenOffset x + border. aRectangle left to: aRectangle right - 1 do: [:i | last _ first + (grid cellExtentAt: (grid globalToLocal: i @ 0)) x. xCache at: i - aRectangle left + 1 put: {first. last}. first _ last + border]. yCache _ Array new: aRectangle height. first _ screenOffset y + border. aRectangle top to: aRectangle bottom - 1 do: [:i | last _ first + (grid cellExtentAt: (grid globalToLocal: 0 @ i)) y. yCache at: i - aRectangle top + 1 put: {first. last}. first _ last + border]! ----- Method: SkCellScreenConverter>>createOffset: (in category 'private') ----- createOffset: aPoint | x y | x _ ((aPoint x min: 0) to: (aPoint x max: 0) - 1) inject: 0 into: [:sub :next | sub + (grid cellExtentAt: next @ 0) x + border]. x _ aPoint x negative ifTrue: [0 - x] ifFalse: [x]. y _ ((aPoint y min: 0) to: (aPoint y max: 0) - 1) inject: 0 into: [:sub :next | sub + (grid cellExtentAt: 0 @ next) y + border]. y _ aPoint y negative ifTrue: [0 - y] ifFalse: [y]. ^ x @ y! ----- Method: SkCellScreenConverter>>extent (in category 'accessing') ----- extent ^ cellTopLeft + offset extent: xCache size @ yCache size! ----- Method: SkCellScreenConverter>>grid:border: (in category 'initialization') ----- grid: aSkGridMorph border: aNumber border _ aNumber. grid _ aSkGridMorph. cellTopLeft _ aSkGridMorph visibleArea topLeft. self createCacheFor: (cellTopLeft extent: 1 @ 1)! ----- Method: SkCellScreenConverter>>screenToCell:topLeft: (in category 'accessing') ----- screenToCell: aPoint topLeft: topLeft "Convert screen position to cell position" | x y right left bottom top | aPoint x < topLeft x ifTrue: [x _ self extent left - 1. left _ topLeft x. [(left _ left - (grid cellExtentAt: x @ 0) x + border) > aPoint x] whileTrue: [x _ x - 1]] ifFalse: [x _ self extent left. right _ topLeft x. [(right _ right + (grid cellExtentAt: x @ 0) x + border) < aPoint x] whileTrue: [x _ x + 1]]. aPoint y < topLeft y ifTrue: [y _ self extent top - 1. top _ topLeft y. [(top _ top - (grid cellExtentAt: 0 @ y) y + border) > aPoint y] whileTrue: [y _ y - 1]] ifFalse: [y _ self extent top. bottom _ topLeft y. [(bottom _ bottom + (grid cellExtentAt: 0 @ y) y + border) < aPoint y] whileTrue: [y _ y + 1]]. ^ x @ y! Object subclass: #SkColorSet instanceVariableNames: 'basic base label selected borderStyle selectedBorderStyle plug' classVariableNames: '' poolDictionaries: '' category: 'Skeleton-Base'! SkColorSet class instanceVariableNames: 'map default'! !SkColorSet commentStamp: 'tak 12/20/2003 21:43' prior: 0! This is a cache of color property. ! SkColorSet class instanceVariableNames: 'map default'! ----- Method: SkColorSet class>>at: (in category 'accessing') ----- at: anObject ^ map at: anObject ifAbsent: [self projectAt: anObject ifAbsent: [default]]! ----- Method: SkColorSet class>>baseFor: (in category 'query') ----- baseFor: anObject ^ (self at: anObject) base! ----- Method: SkColorSet class>>basicFor: (in category 'query') ----- basicFor: anObject ^ (self at: anObject) basic! ----- Method: SkColorSet class>>borderStyleFor: (in category 'query') ----- borderStyleFor: anObject ^ (self at: anObject) borderStyle! ----- Method: SkColorSet class>>for:color: (in category 'accessing') ----- for: anObject color: color "Resist color for the morph" | property | property _ self new. property basic: color. map ifNil: [map _ WeakKeyDictionary new]. map at: anObject put: property! ----- Method: SkColorSet class>>initialize (in category 'accessing') ----- initialize "It's read by system" "self initialize" map ifNil: [self reset]! ----- Method: SkColorSet class>>labelFor: (in category 'query') ----- labelFor: anObject ^ (self at: anObject) label! ----- Method: SkColorSet class>>map (in category 'accessing') ----- map "This is temporary implementation, see SkProxy comment" ^ map! ----- Method: SkColorSet class>>plugFor: (in category 'query') ----- plugFor: anObject ^ (self at: anObject) plug! ----- Method: SkColorSet class>>projectAt:ifAbsent: (in category 'accessing') ----- projectAt: anObject ifAbsent: aBlock | set colors | set _ SkProject current colorSet. set ifNil: [^ aBlock value]. colors _ set at: anObject ifAbsent: [^ aBlock value]. SkColorSet for: anObject color: colors basic. ^ colors! ----- Method: SkColorSet class>>reset (in category 'accessing') ----- reset "self reset" map := WeakKeyDictionary new. default := self new basic: Color blue! ----- Method: SkColorSet class>>selectedBorderStyleFor: (in category 'query') ----- selectedBorderStyleFor: anObject ^ (self at: anObject) selectedBorderStyle! ----- Method: SkColorSet class>>selectedFor: (in category 'query') ----- selectedFor: anObject ^ (self at: anObject) selected! ----- Method: SkColorSet>>base (in category 'accessing') ----- base "Answer the value of base" ^ base! ----- Method: SkColorSet>>basic (in category 'accessing') ----- basic ^basic! ----- Method: SkColorSet>>basic: (in category 'accessing') ----- basic: aColor | border | basic _ aColor. label _ aColor luminance > 0.9 ifTrue: [aColor alpha: aColor alpha] ifFalse: [Color h: aColor hue s: aColor saturation * 0.5 v: aColor brightness alpha: aColor alpha * 0.7]. base _ aColor luminance > 0.9 ifTrue: [Color h: aColor hue s: 0.1 v: aColor brightness - 0.05 alpha: aColor alpha] ifFalse: [Color h: aColor hue s: 0.08 v: (aColor brightness * 2 max: 0.8) alpha: aColor alpha]. border _ aColor luminance > 0.9 ifTrue: [Color h: aColor hue s: aColor saturation * 0.5 v: aColor brightness - 0.2] ifFalse: [Color h: aColor hue s: aColor saturation * 0.5 v: aColor brightness]. borderStyle _ BorderStyle color: border width: 1. selected _ aColor luminance > 0.95 ifTrue: [aColor] ifFalse: [Color h: base hue s: base saturation v: base brightness - 0.1]. selectedBorderStyle _ BorderStyle color: border lighter width: 1. plug _ base darker! ----- Method: SkColorSet>>borderStyle (in category 'accessing') ----- borderStyle "Answer the value of borderStyle" ^ borderStyle! ----- Method: SkColorSet>>label (in category 'accessing') ----- label "Answer the value of label" ^ label! ----- Method: SkColorSet>>plug (in category 'accessing') ----- plug ^ plug! ----- Method: SkColorSet>>selected (in category 'accessing') ----- selected "Answer the value of selected" ^ selected! ----- Method: SkColorSet>>selectedBorderStyle (in category 'accessing') ----- selectedBorderStyle "Answer the value of border" ^ selectedBorderStyle! Object subclass: #SkNullCell instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Skeleton-Base'! !SkNullCell commentStamp: 'tak 12/7/2003 19:53' prior: 0! The cell object is used when a cell is not modified yet. ! SkNullCell subclass: #SkDictionaryCell instanceVariableNames: 'dictionary key isKey' classVariableNames: '' poolDictionaries: '' category: 'Skeleton-Base'! !SkDictionaryCell commentStamp: 'tak 12/30/2003 00:23' prior: 0! I am a proxy of dictionary.! ----- Method: SkDictionaryCell class>>new (in category 'instance creation') ----- new self shouldNotImplement ! ----- Method: SkDictionaryCell class>>newFor:key: (in category 'instance creation') ----- newFor: aSkDictionary key: aString ^ super new dictionary: aSkDictionary key: aString! ----- Method: SkDictionaryCell>>contents (in category 'accessing') ----- contents (dictionary includesPosition: key) ifTrue: [key x = 1 ifTrue: [^ (dictionary rowAt: key y) key]. key x = 2 ifTrue: [^ (dictionary rowAt: key y) value]. ^ '']. ^ dictionary nameAt: key ifAbsent: ['']! ----- Method: SkDictionaryCell>>contents: (in category 'accessing') ----- contents: anObject dictionary isLocked ifTrue: [^ self]. key ifNil: [dictionary at: anObject asString put: ''] ifNotNil: [self isKey ifTrue: [dictionary removeAt: key. dictionary at: anObject asString put: ''] ifFalse: [dictionary at: key put: anObject]]! ----- Method: SkDictionaryCell>>dictionary:key: (in category 'initialization') ----- dictionary: aSkDictionary key: aString dictionary _ aSkDictionary. key _ aString! ----- Method: SkDictionaryCell>>editContents: (in category 'accessing') ----- editContents: anObject ^ self contents: anObject! ----- Method: SkDictionaryCell>>isKey (in category 'accessing') ----- isKey ^ isKey ifNil: [false]! ----- Method: SkDictionaryCell>>isKey: (in category 'accessing') ----- isKey: aBoolean isKey _ aBoolean! ----- Method: SkNullCell class>>evaluatorClass (in category 'accessing') ----- evaluatorClass ^ SkCompiler! ----- Method: SkNullCell>>contents (in category 'accessing') ----- contents ^ ''! ----- Method: SkNullCell>>contents: (in category 'accessing') ----- contents: anObject ^ ''! ----- Method: SkNullCell>>editContents: (in category 'accessing') ----- editContents: aText! ----- Method: SkNullCell>>formula (in category 'accessing') ----- formula ^ nil! ----- Method: SkNullCell>>hasCard (in category 'accessing') ----- hasCard ^ self contents isSkObject! ----- Method: SkNullCell>>hasFormula (in category 'accessing') ----- hasFormula ^ self formula notNil! ----- Method: SkNullCell>>hasUpdated (in category 'testing') ----- hasUpdated ^ false! ----- Method: SkNullCell>>label (in category 'accessing') ----- label ^ nil! ----- Method: SkNullCell>>morph (in category 'accessing') ----- morph ^ nil! ----- Method: SkNullCell>>player (in category 'accessing') ----- player ^ nil! ----- Method: SkNullCell>>printOn: (in category 'printing') ----- printOn: aStream super printOn: aStream. aStream nextPutAll: '('. aStream print: self identityHash; nextPutAll: ')'! ----- Method: SkNullCell>>privateContents (in category 'accessing') ----- privateContents ^ self contents! ----- Method: SkNullCell>>referenceAt: (in category 'updating') ----- referenceAt: aPoint ^ #()! ----- Method: SkNullCell>>remember (in category 'accessing') ----- remember ! ----- Method: SkNullCell>>resolveContextOn:at: (in category 'updating') ----- resolveContextOn: holder at: pos! ----- Method: SkNullCell>>resolveFormulaOn:at: (in category 'updating') ----- resolveFormulaOn: sheet at: aPoint ! ----- Method: SkNullCell>>resolveOn:at: (in category 'updating') ----- resolveOn: sheet at: aPoint ! ----- Method: SkNullCell>>value (in category 'accessing') ----- value ^ ''! SkNullCell subclass: #SkProxyCell instanceVariableNames: 'holderCell argCell' classVariableNames: '' poolDictionaries: '' category: 'Skeleton-Base'! !SkProxyCell commentStamp: 'tak 12/30/2003 14:07' prior: 0! I represent the top of cells at card model.! ----- Method: SkProxyCell>>contents (in category 'accessing') ----- contents ^ holderCell contents! ----- Method: SkProxyCell>>contents: (in category 'accessing') ----- contents: anObject ^ holderCell contents: anObject ! ----- Method: SkProxyCell>>editContents: (in category 'accessing') ----- editContents: anObject ((anObject isString or: [anObject isText]) and: [anObject first = $=]) ifTrue: [^ argCell editContents: anObject] ifFalse: [^ holderCell editContents: anObject]! ----- Method: SkProxyCell>>formula (in category 'accessing') ----- formula ^ argCell formula! ----- Method: SkProxyCell>>hasUpdated (in category 'testing') ----- hasUpdated ^ holderCell hasUpdated! ----- Method: SkProxyCell>>holderCell (in category 'accessing') ----- holderCell ^ holderCell! ----- Method: SkProxyCell>>holderCell:argCell: (in category 'initialization') ----- holderCell: hCell argCell: aCell holderCell _ hCell. argCell _ aCell.! ----- Method: SkProxyCell>>privateContents (in category 'accessing') ----- privateContents ^ holderCell contents! ----- Method: SkProxyCell>>resolveFormulaOn:at: (in category 'updating') ----- resolveFormulaOn: sheet at: aPoint "I execute rule's formula. And chlid's card is build in this message as soon. So recursive call is not supported (Need more lasy solution). " argCell resolveFormulaOn: sheet rule at: aPoint ! SkNullCell subclass: #SkValueCell instanceVariableNames: 'formula block model getter setter oldValue' classVariableNames: '' poolDictionaries: '' category: 'Skeleton-Base'! ----- Method: SkValueCell class>>new (in category 'instance creation') ----- new ^ super new initialize! ----- Method: SkValueCell>>block (in category 'accessing') ----- block ^ block! ----- Method: SkValueCell>>contents (in category 'accessing') ----- contents ^ (model perform: getter) ifNil: ['']! ----- Method: SkValueCell>>contents: (in category 'accessing') ----- contents: anObject model perform: setter with: anObject! ----- Method: SkValueCell>>editContents: (in category 'accessing') ----- editContents: anObject | string | (self formula: anObject) ifTrue: [^ self]. anObject isNumber ifTrue: [^ self contents: anObject]. string _ anObject isString ifTrue: [anObject] ifFalse: [(anObject isText and: [anObject unembellished]) ifTrue: [anObject asString]]. string ifNotNil: [^ self contents: ((self isLikeNumber: string) ifTrue: [string asNumber] ifFalse: [string])]. self contents: anObject! ----- Method: SkValueCell>>formula (in category 'accessing') ----- formula ^ formula! ----- Method: SkValueCell>>formula: (in category 'accessing') ----- formula: anObject "Set formula if appropriate object. Answer true if fomula" formula _ block _ nil. (anObject isString or: [anObject isText]) ifFalse: [^ false]. anObject first = $= ifFalse: [^ false]. formula _ anObject asString. block _ (Compiler new parserClass: SkParser) evaluate: '[:holder :pos | ' , formula allButFirst , ']' in: nil to: nil notifying: nil ifFail: [Error signal]. ^ true! ----- Method: SkValueCell>>hasUpdated (in category 'testing') ----- hasUpdated ^ self hasCard or: [(self contents = oldValue) not]! ----- Method: SkValueCell>>initialize (in category 'initialization') ----- initialize model _ ValueHolder new. setter _ #contents:. getter _ #contents! ----- Method: SkValueCell>>isLikeNumber: (in category 'support') ----- isLikeNumber: aString " self new isLikeNumber: '0' self new isLikeNumber: '-3.141592' self new isLikeNumber: 'word' self new isLikeNumber: '10a' " ^ aString = ([aString asNumber] on: Error do: [0]) asString! ----- Method: SkValueCell>>isNull (in category 'testing') ----- isNull ^ block isNil and: [self contents = '']! ----- Method: SkValueCell>>label (in category 'accessing') ----- label ^ (self contents isKindOf: Player) ifTrue: [self contents externalName] ifFalse: [(model isKindOf: Player) ifTrue: [self slotName]]! ----- Method: SkValueCell>>modelAddDependent: (in category 'updating') ----- modelAddDependent: anObject model addDependent: anObject! ----- Method: SkValueCell>>modelRemoveDependent: (in category 'updating') ----- modelRemoveDependent: anObject model removeDependent: anObject! ----- Method: SkValueCell>>on:getter:setter: (in category 'accessing') ----- on: anObject getter: getSelector setter: setSelector model _ anObject. getter _ getSelector. setter _ setSelector! ----- Method: SkValueCell>>player (in category 'accessing') ----- player (self contents isKindOf: Player) ifTrue: [^ self contents]. (model isKindOf: Player) ifTrue: [^ model]. ^ super morph! ----- Method: SkValueCell>>printOn: (in category 'printing') ----- printOn: aStream aStream nextPutAll: '[' , self contents printString , ' | ' , formula printString , ']'. aStream nextPutAll: '('. aStream print: self identityHash; nextPutAll: ')'! ----- Method: SkValueCell>>referenceAt: (in category 'updating') ----- referenceAt: aPoint | finder | ^ self hasCard ifTrue: [(self hasCard and: [self contents isInstance]) ifTrue: [(self contents referenceAt: aPoint) asSet] ifFalse: [#()]] ifFalse: [finder _ SkRefFinder new. self resolveOn: finder at: aPoint. finder keys]! ----- Method: SkValueCell>>remember (in category 'accessing') ----- remember oldValue _ self contents! ----- Method: SkValueCell>>resolveCardOn:at: (in category 'updating') ----- resolveCardOn: sheet at: aPoint | ruleCase privateCase | ruleCase _ self contents. privateCase _ (sheet assuredCellAt: aPoint) privateContents. ruleCase = sheet ifTrue: [^ self]. (privateCase isSkObject and: [ruleCase rule = privateCase rule]) ifFalse: [privateCase _ block value: sheet value: aPoint. sheet at: aPoint put: privateCase. privateCase holder: sheet at: aPoint. self changed: #cardList]. privateCase resolveOn: sheet! ----- Method: SkValueCell>>resolveFormulaOn:at: (in category 'updating') ----- resolveFormulaOn: sheet at: aPoint block ifNil: [^ self]. sheet at: aPoint put: ([block value: sheet value: aPoint] ifError: [:err :rcvr | false ifTrue: [Transcript show: err printString; cr; show: rcvr printString; cr]. 0])! ----- Method: SkValueCell>>resolveOn:at: (in category 'updating') ----- resolveOn: sheet at: aPoint "Execute card if I have already had card Execute formula if I doesn't have card" self hasFormula ifTrue: [self hasCard ifTrue: [self resolveCardOn: sheet at: aPoint] ifFalse: [self resolveFormulaOn: sheet at: aPoint]]! ----- Method: SkValueCell>>slotName (in category 'accessing') ----- slotName "See Player>>tearOffFancyWatcherFor:" | info watcherWording anInterface | info _ model slotInfoForGetter: getter. info ifNil: [anInterface _ Vocabulary eToyVocabulary methodInterfaceAt: getter ifAbsent: []. watcherWording _ anInterface elementWording] ifNotNil: [watcherWording _ Utilities inherentSelectorForGetter: getter]. ^ model tileReferringToSelf bePossessive labelMorph contents , ' ' , watcherWording! ----- Method: SkValueCell>>sourceCode (in category 'accessing') ----- sourceCode | code | code := block sourceCode. ^ code copyFrom: (code indexOf: $[) + 1 to: (code lastIndexOf: $]) - 1! ----- Method: SkValueCell>>veryDeepInner: (in category 'coping') ----- veryDeepInner: deepCopier "block is not copied" model _ model veryDeepCopyWith: deepCopier. getter _ getter veryDeepCopyWith: deepCopier. setter _ setter veryDeepCopyWith: deepCopier. oldValue _ oldValue veryDeepCopyWith: deepCopier. ! Object subclass: #SkObject instanceVariableNames: '' classVariableNames: 'NullCell Root' poolDictionaries: '' category: 'Skeleton-Base'! !SkObject commentStamp: 'tak 1/11/2004 13:57' prior: 0! I am a base class of Skeleton object.! SkObject subclass: #SkLibrary instanceVariableNames: 'args direction' classVariableNames: '' poolDictionaries: '' category: 'Skeleton-Base'! SkLibrary subclass: #SkAverage instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Skeleton-Base-Sheet'! ----- Method: SkAverage class>>defaultColor (in category 'instance creation') ----- defaultColor ^ (TranslucentColor r: 0.484 g: 0.806 b: 0.0 alpha: 0.667)! ----- Method: SkAverage>>resolve (in category 'updating') ----- resolve | elements | args size < 2 ifTrue: [^self]. elements _ args allButFirst collect: [:each | each contents]. args first contents: (elements sum) / elements size! SkLibrary subclass: #SkCopy instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Skeleton-Base-Sheet'! ----- Method: SkCopy>>resolve (in category 'updating') ----- resolve | first | args isEmpty ifTrue: [^ self]. first _ args first contents. args allButFirst do: [:each | each contents: first copy]! SkLibrary subclass: #SkCount instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Skeleton-Base-Sheet'! ----- Method: SkCount class>>defaultColor (in category 'instance creation') ----- defaultColor ^(TranslucentColor r: 0.226 g: 0.258 b: 1.0 alpha: 0.812)! ----- Method: SkCount>>resolve (in category 'updating') ----- resolve args withIndexDo: [ :each :index | each contents: index]. ! SkLibrary subclass: #SkDistance instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Skeleton-Base-Sheet'! ----- Method: SkDistance class>>defaultColor (in category 'instance creation') ----- defaultColor ^ (TranslucentColor r: 0.806 g: 0.0 b: 0.065 alpha: 0.745)! ----- Method: SkDistance>>initialize (in category 'initialization') ----- initialize super initialize. args _ {SkValueCell new. SkValueCell new. SkValueCell new}! ----- Method: SkDistance>>resolve (in category 'updating') ----- resolve | m1 m2 distance | args size < 3 ifTrue: [^ self]. m1 _ (args first contents isKindOf: Player) ifTrue: [args first contents costume] ifFalse: [^ self]. m2 _ (args second contents isKindOf: Player) ifTrue: [args second contents costume] ifFalse: [^ self]. distance _ args third contents isNumber ifTrue: [args third contents] ifFalse: [^ self]. self setDistanceFrom: m1 to: m2 distance: distance! ----- Method: SkDistance>>setDistanceFrom:to:distance: (in category 'updating') ----- setDistanceFrom: m1 to: m2 distance: distance | goal | goal _ m1 position direction2: m2 position distance: distance. m2 position: goal. ! ----- Method: SkDistance>>size: (in category 'accessing') ----- size: aNumber ! ----- Method: SkDistance>>wantsUpdate (in category 'updating') ----- wantsUpdate ^ true! ----- Method: SkLibrary class>>collectDependents (in category 'planning') ----- collectDependents ^ #()! ----- Method: SkLibrary class>>defaultColor (in category 'instance creation') ----- defaultColor ^ TranslucentColor r: 0.0 g: 0.71 b: 0.806 alpha: 0.745! ----- Method: SkLibrary class>>direction: (in category 'instance creation') ----- direction: aSymbol ^self new direction: aSymbol! ----- Method: SkLibrary class>>direction:size: (in category 'instance creation') ----- direction: direction size: aNumber | instance | instance _ self new. instance direction: direction. instance size: aNumber. ^ instance! ----- Method: SkLibrary class>>wantsUpdate (in category 'testing') ----- wantsUpdate ^ false! ----- Method: SkLibrary>>argPositions (in category 'arg accessing') ----- argPositions ^ (1 to: args size) collect: [:index | index @ 1]! ----- Method: SkLibrary>>args (in category 'accessing') ----- args ^ args! ----- Method: SkLibrary>>attachProject (in category 'structure') ----- attachProject ! ----- Method: SkLibrary>>cardList: (in category 'cell accessing') ----- cardList: aRectangle ^ #()! ----- Method: SkLibrary>>cellAt:ifAbsent: (in category 'cell accessing') ----- cellAt: key ifAbsent: aBlock key class = Point ifTrue: [key y = 1 ifTrue: [key x <= args size ifTrue: [^ args at: key x ifAbsent: aBlock]]]. ^ aBlock value! ----- Method: SkLibrary>>direction (in category 'accessing') ----- direction ^ direction! ----- Method: SkLibrary>>direction: (in category 'accessing') ----- direction: aSymbol direction _ aSymbol! ----- Method: SkLibrary>>holder:at: (in category 'holder and card') ----- holder: aSkSheet at: aPoint | holderCell | self initializeArgs. (self referenceAt: aPoint) withIndexDo: [:pos :index | holderCell _ aSkSheet assuredCellAt: pos. holderCell modelAddDependent: self. args at: index put: holderCell]. self update: #contents.! ----- Method: SkLibrary>>initialize (in category 'initialization') ----- initialize super initialize. self initializeArgs. direction _ #right. ! ----- Method: SkLibrary>>initializeArgs (in category 'initialization') ----- initializeArgs args ifNil: [args _ #()] ifNotNil: [args do: [:each | each class = SkValueCell ifTrue: [each modelRemoveDependent: self]]]! ----- Method: SkLibrary>>initializeArgs: (in category 'initialization') ----- initializeArgs: aNumber self initializeArgs. args _ Array new: aNumber. args withIndexDo: [:each :index | | cell | cell _ SkValueCell new. cell modelAddDependent: self. args at: index put: cell]! ----- Method: SkLibrary>>parent (in category 'structure') ----- parent ^ self rule parent! ----- Method: SkLibrary>>referenceAt: (in category 'arg accessing') ----- referenceAt: aPoint "Answer the dependents object's point" ^ self argPositions collect: [:each | self pointForHolder: aPoint at: each]! ----- Method: SkLibrary>>releaseHolder (in category 'holder and card') ----- releaseHolder self initializeArgs: 3. super releaseHolder! ----- Method: SkLibrary>>resolve (in category 'updating') ----- resolve! ----- Method: SkLibrary>>resolveOn: (in category 'updating') ----- resolveOn: sheet [self resolve] ifError: [:err :rcvr | false ifTrue: [Transcript show: err printString; cr; show: rcvr printString; cr]. 0]! ----- Method: SkLibrary>>rule (in category 'structure') ----- rule ^ self class! ----- Method: SkLibrary>>size (in category 'accessing') ----- size ^ args size! ----- Method: SkLibrary>>size: (in category 'accessing') ----- size: aNumber args _ Array new: aNumber. args _ args collect: [:each | SkValueCell new]! ----- Method: SkLibrary>>wantsSteps (in category 'updating') ----- wantsSteps ^ true! SkLibrary subclass: #SkName instanceVariableNames: 'holder' classVariableNames: '' poolDictionaries: '' category: 'Skeleton-Base-Sheet'! ----- Method: SkName class>>defaultColor (in category 'instance creation') ----- defaultColor ^ (TranslucentColor r: 0.581 g: 0.581 b: 0.581 alpha: 0.682)! ----- Method: SkName>>cell (in category 'accessing') ----- cell ^ args second! ----- Method: SkName>>holder:at: (in category 'arg accessing') ----- holder: aSkSheet at: aPoint super holder: aSkSheet at: aPoint. holder _ aSkSheet. holder updateKeys! ----- Method: SkName>>initialize (in category 'initialization') ----- initialize super initialize. args _ {SkValueCell new. SkValueCell new}! ----- Method: SkName>>key (in category 'accessing') ----- key ^ args first contents! ----- Method: SkName>>releaseHolder (in category 'holder and card') ----- releaseHolder holder removeAt: self key. holder updateKeys. super releaseHolder! ----- Method: SkName>>resolve (in category 'updating') ----- resolve args first hasUpdated ifTrue: [holder updateKeys]! ----- Method: SkName>>size: (in category 'accessing') ----- size: aNumber ! SkLibrary subclass: #SkSum instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Skeleton-Base-Sheet'! ----- Method: SkSum class>>defaultColor (in category 'instance creation') ----- defaultColor ^ (TranslucentColor r: 0.484 g: 0.806 b: 0.0 alpha: 0.667)! ----- Method: SkSum>>resolve (in category 'updating') ----- resolve args first contents: (args allButFirst collect: [:each | each contents]) sum! SkObject subclass: #SkNamed instanceVariableNames: 'parent' classVariableNames: '' poolDictionaries: '' category: 'Skeleton-Base'! !SkNamed commentStamp: 'tak 1/11/2004 13:58' prior: 0! I am a abstract class of Skeleton object that has a name. parent SkObject! SkNamed subclass: #SkMap instanceVariableNames: 'map' classVariableNames: '' poolDictionaries: '' category: 'Skeleton-Base'! SkMap subclass: #SkCollection instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Skeleton-Base'! !SkCollection commentStamp: 'tak 1/22/2004 08:41' prior: 0! SkCollection open! ----- Method: SkCollection>>add: (in category 'accessing') ----- add: anObject map add: anObject. self changed: #cardList.! ----- Method: SkCollection>>cardPositions (in category 'accessing') ----- cardPositions ^ (1 to: map size) collect: [:each | 1 @ (each + 1)]! ----- Method: SkCollection>>cellAt:ifAbsent: (in category 'cell accessing') ----- cellAt: key ifAbsent: aBlock | contents | (self isApplicableKey: key) ifTrue: [contents _ map at: (key - 1) y ifAbsent: aBlock. ^ SkValueCell new contents: contents] ifFalse: [^ aBlock value]! ----- Method: SkCollection>>do: (in category 'enumrating') ----- do: aBlock map do: aBlock! ----- Method: SkCollection>>includes: (in category 'testing') ----- includes: anObject ^ map includes: anObject! ----- Method: SkCollection>>initialize (in category 'initialization') ----- initialize super initialize. map _ OrderedCollection new. ! ----- Method: SkCollection>>isApplicableKey: (in category 'testing') ----- isApplicableKey: anObject anObject class == Point ifFalse: [^ false]. anObject x = 1 ifFalse: [^ false]. (anObject y < 2 or: [anObject y > (map size + 1)]) ifTrue: [^ false]. ^ true! ----- Method: SkCollection>>isInstance (in category 'testing') ----- isInstance "maybe bad" ^ false! ----- Method: SkCollection>>isStepList (in category 'testing') ----- isStepList ^ self ruleName = 'StepList'! ----- Method: SkCollection>>isStepping (in category 'updating') ----- isStepping (self isStepList and: [map isEmpty not]) ifTrue: [^ true]. ^ super isStepping! ----- Method: SkCollection>>remove: (in category 'accessing') ----- remove: value map removeAllSuchThat: [:each | each = value]. self changed: #cardList. ^ value! ----- Method: SkCollection>>removeAt: (in category 'cell accessing') ----- removeAt: key (self isApplicableKey: key) ifFalse: [^ NullCell]. map removeAt: key y - 1. self changed: #cardList. ^ NullCell! ----- Method: SkCollection>>stopStepping (in category 'updating') ----- stopStepping map _ OrderedCollection new. self changed: #cardList. ! SkMap subclass: #SkDictionary instanceVariableNames: 'comment orderedCache args' classVariableNames: '' poolDictionaries: '' category: 'Skeleton-Base'! !SkDictionary commentStamp: 'tak 12/22/2003 16:11' prior: 0! This is a dictionary like rule.! ----- Method: SkDictionary>>argPositions (in category 'arg accessing') ----- argPositions ^ (1 to: self args size) collect: [:index | index @ 1]! ----- Method: SkDictionary>>args (in category 'accessing') ----- args ^ args ifNil: [self initializeArgs]! ----- Method: SkDictionary>>assuredCellAt: (in category 'cell accessing') ----- assuredCellAt: key (self includesArgs: key) ifTrue: [^ args at: key x]. (self includesPosition: key) ifTrue: [key x = 1 ifTrue: [^ (SkDictionaryCell newFor: self key: (self rowAt: key y) key) isKey: true] ifFalse: [^ SkDictionaryCell newFor: self key: (self rowAt: key y) key]]. ^ key class == Point ifTrue: [SkDictionaryCell newFor: self key: nil] ifFalse: [SkDictionaryCell newFor: self key: key]! ----- Method: SkDictionary>>at:put: (in category 'accessing') ----- at: key put: anObject self flag: #TODO. map at: key put: anObject. self updateCache. ^ anObject! ----- Method: SkDictionary>>cardPositions (in category 'accessing') ----- cardPositions ^ (1 to: orderedCache size + 1) collect: [:each | 2 @ each] thenSelect: [:key | (self at: key) isSkObject]! ----- Method: SkDictionary>>cellAt:ifAbsent: (in category 'cell accessing') ----- cellAt: key ifAbsent: aBlock "Evaluate aBlock when not found and key is not point" (self includesArgs: key) ifTrue: [^ self args at: key x]. (self includesPosition: key) ifTrue: [^ SkDictionaryCell newFor: self key: key]. (map includesKey: key) ifTrue: [^ SkDictionaryCell newFor: self key: key] ifFalse: [^ aBlock value]! ----- Method: SkDictionary>>defaultArea (in category 'accessing') ----- defaultArea ^ 0 @ 0 extent: 3 @ (self namesSize + 1)! ----- Method: SkDictionary>>holder:at: (in category 'arg accessing') ----- holder: aSkSheet at: aPoint | holderCell | (self referenceAt: aPoint) withIndexDo: [:pos :index | holderCell _ aSkSheet assuredCellAt: pos. args at: index put: holderCell]! ----- Method: SkDictionary>>includesArgs: (in category 'testing') ----- includesArgs: aPoint ^ {1 @ 1. 2 @ 1} includes: aPoint! ----- Method: SkDictionary>>includesPosition: (in category 'testing') ----- includesPosition: aPoint aPoint class == Point ifFalse: [^ false]. aPoint y < 2 ifTrue: [^ false]. aPoint y > (map size + 1) ifTrue: [^ false]. (#(1 2 ) includes: aPoint x) ifFalse: [^ false]. ^ true! ----- Method: SkDictionary>>initialize (in category 'initialization') ----- initialize super initialize. map _ Dictionary new. comment _ '' asText. self updateCache. self initializeArgs! ----- Method: SkDictionary>>initializeArgs (in category 'initialization') ----- initializeArgs ^ args _ {SkValueCell new. SkValueCell new}! ----- Method: SkDictionary>>isLocked (in category 'testing') ----- isLocked ^ map includesKey: 'locked'! ----- Method: SkDictionary>>keyAtValue:ifAbsent: (in category 'structure') ----- keyAtValue: anObject ifAbsent: aBlock ^ map keyAtValue: anObject ifAbsent: aBlock! ----- Method: SkDictionary>>locked: (in category 'accessing') ----- locked: boolean. map at: 'locked' put: boolean! ----- Method: SkDictionary>>nameAt:ifAbsent: (in category 'accessing') ----- nameAt: key ifAbsent: aBlock ^ map at: key ifAbsent: aBlock! ----- Method: SkDictionary>>namesSize (in category 'accessing') ----- namesSize ^ map size! ----- Method: SkDictionary>>referenceAt: (in category 'arg accessing') ----- referenceAt: aPoint "Answer the dependents object's point" ^ self argPositions collect: [:each | self pointForHolder: aPoint at: each]! ----- Method: SkDictionary>>removeAt: (in category 'structure') ----- removeAt: key | cell name | name _ key class == Point ifTrue: [(self rowAt: key y) key] ifFalse: [key]. self isLocked ifTrue: [^ self cellAt: name]. cell _ super removeAt: name. self updateCache. self update: #cardList. ^ cell! ----- Method: SkDictionary>>removeForce: (in category 'structure') ----- removeForce: key map removeKey: key ifAbsent: []! ----- Method: SkDictionary>>resolveOn: (in category 'updating') ----- resolveOn: holder | value | (value _ map at: args first contents ifAbsent: [args second contents: ''. ^ self]) = args second contents ifFalse: [args second contents: value. holder changed: #cardList. self changed: #cardList]! ----- Method: SkDictionary>>rowAt: (in category 'accessing') ----- rowAt: aNumber ^ (1 < aNumber and: [aNumber <= (orderedCache size + 1)]) ifTrue: [orderedCache at: aNumber - 1]! ----- Method: SkDictionary>>size (in category 'accessing') ----- size ^ 2! ----- Method: SkDictionary>>updateCache (in category 'accessing') ----- updateCache orderedCache _ SortedCollection sortBlock: [:x :y | x key name <= y key name]. map associationsDo: [:assoc | orderedCache add: assoc]! ----- Method: SkDictionary>>wantsSteps (in category 'updating') ----- wantsSteps ^ true! SkDictionary subclass: #SkProject instanceVariableNames: 'colorSet' classVariableNames: '' poolDictionaries: '' category: 'Skeleton-Base'! !SkProject commentStamp: 'tak 1/25/2004 00:00' prior: 0! I hold all spreadsheets in a project. I find my parent from class variable but instance variable. This is because to aviod copy all trees when I am saved into project file. colorSet -- SkColorSet ... This is temporary implementation. It is bounded to save as project.! ----- Method: SkProject class>>current (in category 'accessing') ----- current ^ self for: Project current! ----- Method: SkProject class>>for: (in category 'accessing') ----- for: aProject "SkProject for: (Project named: 'Unnamed1')" | parent dict | parent _ self root at: 'Projects'. dict _ parent at: aProject ifAbsent: [(SkProject newFor: aProject) parent: parent; name: aProject]. ^ dict! ----- Method: SkProject class>>forceRemoveAt: (in category 'accessing') ----- forceRemoveAt: aProject "remove for debug" "self forceRemoveAt: Project current" (SkDictionary allInstances select: [:each | each includesKey: aProject]) do: [:each | each removeForce: aProject]! ----- Method: SkProject class>>newFor: (in category 'accessing') ----- newFor: aProject "find this instance for the project. little tricky" "self findProject: Project current" | map | map _ SkDictionary allInstances detect: [:each | each includesKey: aProject] ifNone: [^ self new]. ^ map at: aProject! ----- Method: SkProject>>colorSet (in category 'accessing') ----- colorSet ^colorSet! ----- Method: SkProject>>initialize (in category 'initialization') ----- initialize super initialize. colorSet _ SkColorSet map! ----- Method: SkProject>>parent (in category 'structure') ----- parent ^ self class root findName: 'Projects'! ----- Method: SkProject>>parent: (in category 'structure') ----- parent: aSkObject "do nothing" ^ self! ----- Method: SkProject>>stepList (in category 'accessing') ----- stepList ^ self at: 'StepList' ifAbsent: [| list | list _ SkCollection new. self at: 'StepList' put: list. list parent: self. World setProperty: #SkStepList toValue: list. list]! ----- Method: SkMap>>removeAt: (in category 'structure') ----- removeAt: key | cell | cell _ self cellAt: key. map removeKey: key ifAbsent: []. ^ cell! SkMap subclass: #SkSheet instanceVariableNames: 'plan dependMap' classVariableNames: '' poolDictionaries: '' category: 'Skeleton-Base'! !SkSheet commentStamp: 'tak 4/2/2004 21:27' prior: 0! I am a simple spreadsheets model. Preferences enable: #batchPenTrails SkSheet example Structure: dictionary Dictionary -- reference of cells ! ----- Method: SkSheet class>>example (in category 'examples') ----- example "self example" | sheet p1 p2 | ActiveWorld setProperty: #originAtCenter toValue: true. sheet _ SkSheet new. p1 _ (SkeletonBaseInfo point color: Color blue) openInWorld assuredPlayer. p2 _ (SkeletonBaseInfo point color: Color red) openInWorld assuredPlayer. sheet modelAt: 1 @ 1 for: p1 getter: #getX setter: #setX:. sheet modelAt: 2 @ 1 for: p1 getter: #getY setter: #setY:. sheet modelAt: 1 @ 2 for: p2 getter: #getX setter: #setX:. sheet modelAt: 2 @ 2 for: p2 getter: #getY setter: #setY:. sheet textAt: 1 @ 1 put: '=( 4 * A2 ) degreeSin * 200'. sheet textAt: 2 @ 1 put: '=( 7 * A2 ) degreeSin * 200'. p1 setPenDown: true. p1 setPenColor: (TranslucentColor r: 1.0 g: 0.0 b: 0.0 alpha: 0.1). p1 setPenSize: 3. p2 setX: 0; setY: 0. sheet grid openInWorld! ----- Method: SkSheet>>assuredCellAt: (in category 'cell accessing') ----- assuredCellAt: key ^ self cellAt: key ifAbsent: [map at: key put: SkValueCell new]! ----- Method: SkSheet>>cardList: (in category 'accessing') ----- cardList: aRectangle ^ self cardPositions collect: [:key | key -> (self at: key)]! ----- Method: SkSheet>>cardPositions (in category 'planning') ----- cardPositions ^ map keys select: [:each | each class = Point and: [(map at: each) hasCard]]! ----- Method: SkSheet>>cellAt:ifAbsent: (in category 'cell accessing') ----- cellAt: key ifAbsent: aBlock ^ map at: key ifAbsent: aBlock! ----- Method: SkSheet>>cleaning (in category 'updating') ----- cleaning (map keys select: [:key | (map at: key) isNull and: [(dependMap keys includes: key) not]]) do: [:key | map removeKey: key]! ----- Method: SkSheet>>collectCardDependents: (in category 'planning') ----- collectCardDependents: depArray "Answer #((observer subject subject ..) .." "This is ugly code because using Array. We should use Dictionary by building plan" | dict | dict _ Dictionary new. depArray do: [:each | dict at: each first put: each allButFirst asSet]. (self cardPositions select: [:each | (map at: each) contents isInstance]) do: [:each | ((map at: each) contents collectDependentsForCard: each) ifNotNilDo: [:depends | depends keysAndValuesDo: [:key :value | (dict at: key ifAbsentPut: Set new) addAll: value]]]. ^ self dictToArray: dict! ----- Method: SkSheet>>collectDependents (in category 'planning') ----- collectDependents "Answer #((observer subject subject ..) (observer subject subject ..) (observer subject subject ..))" | node myDepends | myDepends _ self collectTargets collect: [:point | node _ ((self cellAt: point) referenceAt: point) asSortedCollection: self sortBlock. node _ node asOrderedCollection addFirst: point; yourself. node asArray]. ^ self collectCardDependents: myDepends! ----- Method: SkSheet>>collectOrder (in category 'planning') ----- collectOrder | trees | trees _ self collectTrees. ^ trees inject: OrderedCollection new into: [:order :next | order addAll: (self collectOrder: next); yourself]! ----- Method: SkSheet>>collectOrder: (in category 'planning') ----- collectOrder: tree tree isCollection ifFalse: [^ Array with: tree]. ^ Array streamContents: [:aStream | tree allButFirst do: [:node | aStream nextPutAll: (self collectOrder: node)]. aStream nextPut: tree first]! ----- Method: SkSheet>>collectTargets (in category 'planning') ----- collectTargets "Answer points that has formula or card" ^ ((map keys select: [:key | key class = Point and: [(map at: key) hasFormula]]) asSortedCollection: self sortBlock) asArray! ----- Method: SkSheet>>collectTrees (in category 'planning') ----- collectTrees "Adopt parted node (collectDependents) into a big tree" "The order is important" | pool newNodes isFound | "pool is a map of observer -> subjects" pool _ self collectDependents. newNodes _ OrderedCollection new. pool do: [:node | isFound _ false. (pool copyWithout: node) do: [:mother | (self hasRecursion: mother first in: node) ifFalse: [2 to: mother size do: [:index | (isFound not and: [(mother at: index) = node first]) ifTrue: [mother at: index put: node. isFound _ true]]]]. isFound ifFalse: [newNodes add: node]]. ^ newNodes asArray! ----- Method: SkSheet>>dependMap (in category 'planning') ----- dependMap "directory of (subject -> a set of observers)" | dep values | dep _ Dictionary new. "Make simple dictionary reverse of dependents #(observers subject ..)" self collectDependents do: [:each | each allButFirst do: [:point | values _ dep at: point ifAbsentPut: Set new. values add: each first]]. dep keys do: [:key | self dependMap: key addKey: (dep at: key) dict: dep]. ^ dep! ----- Method: SkSheet>>dependMap:addKey:dict: (in category 'planning') ----- dependMap: target addKey: addKey dict: dict | founds more | founds _ Set with: target. founds addAll: (dict at: target). more _ Set new. addKey do: [:key | more addAll: ((dict at: key ifAbsent: [#()]) select: [:value | (founds includes: value) not])]. more isEmpty ifTrue: [^ self]. (dict at: target) addAll: more. self dependMap: target addKey: more dict: dict! ----- Method: SkSheet>>dictToArray: (in category 'planning') ----- dictToArray: aDictionary " (self new dictToArray: (Dictionary new at: 1@2 put: (Set new addAll: {2@2. 3@2}); at: 1@1 put: (Set new addAll: {3@1. 2@1}); yourself)) = {{1@1. 2@1. 3@1}.{1@2. 2@2. 3@2}} " | set line | ^ ((aDictionary keys asSortedCollection: self sortBlock) collect: [:key | line _ OrderedCollection new. line add: key. set _ aDictionary at: key. line addAll: (set asSortedCollection: self sortBlock). line asArray]) asArray! ----- Method: SkSheet>>grid (in category 'initialization') ----- grid self startStepping. ^ super grid! ----- Method: SkSheet>>hasRecursion:in: (in category 'planning') ----- hasRecursion: aPoint in: node "(self new hasRecursion: 1@1 in: {2@2. {1@1. 2@2}}) = true" "(self new hasRecursion: 1@1 in: {3@3. {2@2. 1@1}}) = false" ^ node first = aPoint or: [node allButFirst anySatisfy: [:each | each isCollection and: [self hasRecursion: aPoint in: each]]]! ----- Method: SkSheet>>initialize (in category 'initialization') ----- initialize super initialize. map _ Dictionary new. plan _ #()! ----- Method: SkSheet>>installFormulaAt: (in category 'holder and card') ----- installFormulaAt: aPoint | cell card | (cell _ self cellAt: aPoint) hasCard ifTrue: [card _ cell contents. card isInstance ifTrue: [card holder: self at: aPoint]. self changed: #cardList.]. self updatePlan. self changed! ----- Method: SkSheet>>isInstance (in category 'testing') ----- isInstance ^ false! ----- Method: SkSheet>>keyAtValue:ifAbsent: (in category 'structure') ----- keyAtValue: value ifAbsent: aBlock "Answer only named key" map associationsDo: [:association | (value == association value contents and: [association key class ~= Point]) ifTrue: [^ association key]]. ^ aBlock value! ----- Method: SkSheet>>modelAt:for:getter:setter: (in category 'accessing') ----- modelAt: aPoint for: anObject getter: getter setter: setter self textAt: aPoint put: (anObject perform: getter). (self cellAt: aPoint) on: anObject getter: getter setter: setter. ! ----- Method: SkSheet>>nameAt:putCell: (in category 'cell accessing') ----- nameAt: aString putCell: cell map at: aString put: cell.! ----- Method: SkSheet>>plan (in category 'accessing') ----- plan ^ plan! ----- Method: SkSheet>>rememberUpdatesOn: (in category 'updating') ----- rememberUpdatesOn: holder dependMap keys do: [:key | (holder cellAt: key) remember]! ----- Method: SkSheet>>resolveOn: (in category 'updating') ----- resolveOn: holder "Aplly all constrains to cells in holder" | updates | dependMap ifNil: [^ self]. updates _ Set new addAll: (self updatedCellsOn: holder); addAll: (self updatedCellsInCardOn: holder); yourself. plan do: [:pair | (updates includes: pair key) ifTrue: [pair value resolveOn: holder at: pair key]]. self rememberUpdatesOn: holder. " updates isEmpty not ifTrue: [Transcript show: updates asString; cr] "! ----- Method: SkSheet>>sortBlock (in category 'planning') ----- sortBlock ^ [:a :b | a y < b y or: [a y == b y and: [a x <= b x]]]! ----- Method: SkSheet>>updateKeys (in category 'accessing') ----- updateKeys | propertyKeys newMap | propertyKeys _ self findName: 'PropertyKeys'. newMap _ Dictionary new. map associationsDo: [:assoc | (assoc key class == Point or: [propertyKeys includes: assoc key]) ifTrue: [newMap at: assoc key put: assoc value]]. (map values select: [:cell | cell contents class == SkName] thenCollect: [:cell | cell contents]) do: [:each | newMap at: each key put: each cell]. map _ newMap.! ----- Method: SkSheet>>updatePlan (in category 'planning') ----- updatePlan "Order of plan is reserved, but not redundant" | keys remain | keys := self collectOrder. remain := keys asSet. plan := (keys select: [:key | (remain includes: key) and: [(self cellAt: key) hasFormula and: [remain remove: key. true]]] thenCollect: [:key | key -> (map at: key)]) asArray. dependMap := self dependMap! ----- Method: SkSheet>>updatedCellsInCardOn: (in category 'updating') ----- updatedCellsInCardOn: holder "Ask card to want to update?" ^ self cardPositions select: [:each | (map at: each) contents wantsUpdate]! ----- Method: SkSheet>>updatedCellsOn: (in category 'updating') ----- updatedCellsOn: holder "detect where I have to do" | updates | updates := Set new. dependMap keys do: [:key | (holder cellAt: key) hasUpdated ifTrue: [updates addAll: (dependMap at: key)]]. ^updates! ----- Method: SkSheet>>wantsSteps (in category 'updating') ----- wantsSteps ^ true! SkMap subclass: #SkSimple instanceVariableNames: 'rules' classVariableNames: '' poolDictionaries: '' category: 'Skeleton-Base'! !SkSimple commentStamp: 'tak 3/11/2004 19:12' prior: 0! I am a simple spreadsheet object.! ----- Method: SkSimple>>addRule: (in category 'accessing') ----- addRule: aSkRule rules add: aSkRule. ^ aSkRule.! ----- Method: SkSimple>>at:ifAbsent: (in category 'accessing') ----- at: key ifAbsent: aBlock ^ (map at: key ifAbsent: aBlock) value! ----- Method: SkSimple>>at:put: (in category 'accessing') ----- at: key put: anObject map at: key put: anObject. ^ anObject! ----- Method: SkSimple>>initialize (in category 'initialization') ----- initialize super initialize. map _ Dictionary new. rules _ OrderedCollection new. ! ----- Method: SkSimple>>resolveOn: (in category 'updating') ----- resolveOn: holder rules do: [:each | each resolveOn: holder]! ----- Method: SkSimple>>textAt: (in category 'accessing') ----- textAt: aPoint ^ (self at: aPoint) asString! ----- Method: SkSimple>>textAt:put: (in category 'accessing') ----- textAt: aPoint put: aText aText = '' ifTrue: [self removeAt: aPoint. ^ '']. map at: aPoint put: aText asString. self changed. ^ aText! ----- Method: SkNamed>>parent (in category 'structure') ----- parent ^ parent! ----- Method: SkNamed>>parent: (in category 'structure') ----- parent: aSkObject parent _ aSkObject! ----- Method: SkNamed>>siblingWith: (in category 'copying') ----- siblingWith: deepCopier ^ self new! ----- Method: SkNamed>>veryDeepCopyWith: (in category 'copying') ----- veryDeepCopyWith: deepCopier | new | new _ super veryDeepCopyWith: deepCopier. new parent: SkProject current uniqueName: self ruleName. ^ new! ----- Method: SkNamed>>veryDeepInner: (in category 'copying') ----- veryDeepInner: deepCopier "parent is not copied" super veryDeepInner: deepCopier. ! ----- Method: SkObject class>>codeString (in category 'accessing') ----- codeString ^ self ruleName! ----- Method: SkObject class>>color: (in category 'accessing') ----- color: aColor SkColorSet for: self color: aColor! ----- Method: SkObject class>>contents: (in category 'instance creation') ----- contents: aBlock | holder | holder _ self new. aBlock value: holder. ^ holder! ----- Method: SkObject class>>defaultColor (in category 'instance creation') ----- defaultColor ^ Color blue! ----- Method: SkObject class>>defaultName (in category 'instance creation') ----- defaultName ^ self name allButFirst: 2! ----- Method: SkObject class>>direction (in category 'accessing') ----- direction ^ #right! ----- Method: SkObject class>>direction: (in category 'instance creation') ----- direction: aSymbol ^self new direction: aSymbol! ----- Method: SkObject class>>grid (in category 'instance creation') ----- grid | case grid | grid _ SkSheetMorph new model: (case _ self new). grid area: case defaultArea. ^ grid! ----- Method: SkObject class>>initialize (in category 'class initialization') ----- initialize "self initialize" super initialize. SkColorSet initialize. NullCell _ SkNullCell new. Root _ self initializeRoot. self initializeLibrary. ! ----- Method: SkObject class>>initializeLibrary (in category 'class initialization') ----- initializeLibrary "self initializeLibrary" | library | library _ (self root at: 'Library' put: SkDictionary new) parent: self root. library locked: true. library color: (Color r: 0.258 g: 0.645 b: 0.0). SkLibrary allSubclasses asArray , {SkSheet. SkDictionary} do: [:each | each parent: library; name: each defaultName. each color: each defaultColor]. self initializePropertyKeys! ----- Method: SkObject class>>initializePropertyKeys (in category 'class initialization') ----- initializePropertyKeys | library | library _ self root at: 'Library'. library at: 'PropertyKeys' put: {'CellExtent'} asSet! ----- Method: SkObject class>>initializeRoot (in category 'class initialization') ----- initializeRoot | root library projects | root _ SkDictionary new. library _ SkDictionary new. library color: (Color r: 0.258 g: 0.645 b: 0.0). projects _ SkDictionary new. root at: 'Root' put: root. root parent: root. root at: 'Library' put: library. library parent: root. root at: 'Projects' put: projects. projects parent: root. projects locked: true. root locked: true. ^ root! ----- Method: SkObject class>>invokeCardMenu: (in category 'menu') ----- invokeCardMenu: evt! ----- Method: SkObject class>>isInstance (in category 'testing') ----- isInstance ^ false! ----- Method: SkObject class>>isSkObject (in category 'testing') ----- isSkObject ^true! ----- Method: SkObject class>>name: (in category 'structure') ----- name: aString self parent uniqueNameAt: aString put: self rule! ----- Method: SkObject class>>name:contents: (in category 'instance creation') ----- name: aString contents: aBlock | holder | holder _ self new name: aString. aBlock value: holder. ^ holder! ----- Method: SkObject class>>new (in category 'instance creation') ----- new ^ super new initialize! ----- Method: SkObject class>>open (in category 'instance creation') ----- open "self open" ^ self new grid openInHand! ----- Method: SkObject class>>parent (in category 'structure') ----- parent ^ self root at: 'Library'! ----- Method: SkObject class>>parent: (in category 'structure') ----- parent: anObject "parent can't set"! ----- Method: SkObject class>>releaseHolder (in category 'holder and card') ----- releaseHolder! ----- Method: SkObject class>>root (in category 'accessing') ----- root ^ Root! ----- Method: SkObject class>>rule (in category 'accessing') ----- rule ^ self! ----- Method: SkObject class>>ruleName (in category 'accessing') ----- ruleName "Answer name or nil" ^ self parent ifNotNil: [self parent keyAtValue: self rule]! ----- Method: SkObject class>>siblingWith: (in category 'copying') ----- siblingWith: deepCopier ! ----- Method: SkObject class>>size (in category 'accessing') ----- size ^ 0! ----- Method: SkObject class>>size: (in category 'accessing') ----- size: aNumber ^ aNumber! ----- Method: SkObject class>>stopStepping (in category 'updating') ----- stopStepping World ifNotNil: [(World valueOfProperty: #SkSheet) ifNotNilDo: [:set | set remove: self ifAbsent: []]]! ----- Method: SkObject>>++ (in category 'arithmetic') ----- ++ anObject ^ SkParametric new func: #+ arg1: self arg2: anObject ! ----- Method: SkObject>>adopt: (in category 'structure') ----- adopt: aSkObject (self findName: aSkObject ruleName) = aSkObject rule ifTrue: [^ self]. self uniqueNameAt: aSkObject ruleName put: aSkObject! ----- Method: SkObject>>args (in category 'accessing') ----- args ^ #()! ----- Method: SkObject>>assuredCellAt: (in category 'cell accessing') ----- assuredCellAt: key ^ self cellAt: key! ----- Method: SkObject>>at: (in category 'accessing') ----- at: key "Anwer '' NOT nil when unfound" ^ self at: key ifAbsent: [^ '']! ----- Method: SkObject>>at:ifAbsent: (in category 'accessing') ----- at: key ifAbsent: aBlock "answer a value of the point" ^ (self cellAt: key ifAbsent: [^ aBlock value]) contents! ----- Method: SkObject>>at:put: (in category 'accessing') ----- at: aPosition put: anObject | cell | cell _ self assuredCellAt: aPosition. cell contents: anObject. ^ anObject! ----- Method: SkObject>>attachProject (in category 'structure') ----- attachProject self parent: SkProject current uniqueName: self ruleName ! ----- Method: SkObject>>beAlone (in category 'structure') ----- beAlone self parent ifNotNil: [self parent removeAt: self ruleName]! ----- Method: SkObject>>cardList: (in category 'accessing') ----- cardList: aRectangle ^ self cardPositions collect: [:key | key -> (self at: key)]! ----- Method: SkObject>>cardPositions (in category 'accessing') ----- cardPositions ^ #()! ----- Method: SkObject>>caseAt:put: (in category 'holder and card') ----- caseAt: key put: case "Drop the case into me" self at: key put: case.! ----- Method: SkObject>>cellAt: (in category 'cell accessing') ----- cellAt: key ^ self cellAt: key ifAbsent: [NullCell]! ----- Method: SkObject>>cellAt:ifAbsent: (in category 'cell accessing') ----- cellAt: key ifAbsent: aBlock ^ aBlock value! ----- Method: SkObject>>codeString (in category 'accessing') ----- codeString ^ self ruleName , ' direction: ' , self direction printString , ' size: ' , (self size ifNil: [0]) printString! ----- Method: SkObject>>collectDependents (in category 'planning') ----- collectDependents ^ #()! ----- Method: SkObject>>collectDependentsForCard: (in category 'updating') ----- collectDependentsForCard: aPoint ^nil! ----- Method: SkObject>>collectUpdates: (in category 'updating') ----- collectUpdates: aPoint "Answer updated position" ^ #()! ----- Method: SkObject>>collectUpdatesForCard: (in category 'updating') ----- collectUpdatesForCard: aPoint ^#()! ----- Method: SkObject>>color (in category 'accessing') ----- color ^ SkColorSet basicFor: self rule! ----- Method: SkObject>>color: (in category 'accessing') ----- color: aColor SkColorSet for: self color: aColor! ----- Method: SkObject>>defaultArea (in category 'initialization') ----- defaultArea ^ 0 @ 0 extent: 3 @ 3! ----- Method: SkObject>>defaultColor (in category 'accessing') ----- defaultColor ^ Color blue.! ----- Method: SkObject>>defaultName (in category 'constants') ----- defaultName ^ 'Sheet'! ----- Method: SkObject>>dependMap (in category 'accessing') ----- dependMap ^ #()! ----- Method: SkObject>>direction (in category 'accessing') ----- direction ^ #right! ----- Method: SkObject>>direction: (in category 'accessing') ----- direction: aSymbol ! ----- Method: SkObject>>direction:size: (in category 'instance creation') ----- direction: direction size: aNumber | card | card := self rule new. card direction: direction. card size: aNumber. ^card! ----- Method: SkObject>>findLibrary:ifAbsent: (in category 'name accessing') ----- findLibrary: aString ifAbsent: aBlock ^ (self class root findName: 'Library') at: aString ifAbsent: aBlock! ----- Method: SkObject>>findName: (in category 'name accessing') ----- findName: aString ^ self findName: aString ifAbsent: [nil]! ----- Method: SkObject>>findName:ifAbsent: (in category 'name accessing') ----- findName: aString ifAbsent: aBlock "Search parent if not found" aString = 'parent' ifTrue: [^ self parent]. ^ self at: aString ifAbsent: [(self = self parent or: [self parent isNil]) ifTrue: [self findLibrary: aString ifAbsent: aBlock] ifFalse: [self parent findName: aString ifAbsent: aBlock]]! ----- Method: SkObject>>grid (in category 'initialization') ----- grid | grid | grid _ SkSheetMorph new model: self. grid area: self defaultArea. ^ grid! ----- Method: SkObject>>includesKey: (in category 'structure') ----- includesKey: key self at: key ifAbsent: [^ false]. ^ true! ----- Method: SkObject>>initialize (in category 'initialization') ----- initialize "initialize code is here"! ----- Method: SkObject>>inspectAt: (in category 'accessing') ----- inspectAt: key | inspector | inspector _ SkCellInspector holder: self key: key. inspector openLabel: (SkParser pointToA1Name: key)! ----- Method: SkObject>>install:to: (in category 'initialization') ----- install: aSkCard to: aSkObject "It can remove when SkDefine doesn't use SkProxy"! ----- Method: SkObject>>installFormulaAt: (in category 'holder and card') ----- installFormulaAt: aPoint ! ----- Method: SkObject>>invokeCardMenu: (in category 'menu') ----- invokeCardMenu: evt! ----- Method: SkObject>>isInstance (in category 'testing') ----- isInstance ^ true! ----- Method: SkObject>>isSkObject (in category 'testing') ----- isSkObject ^ true! ----- Method: SkObject>>isStepping (in category 'updating') ----- isStepping ^ SkProject current stepList includes: self! ----- Method: SkObject>>keyAtValue: (in category 'structure') ----- keyAtValue: anObject ^ self keyAtValue: anObject ifAbsent: []! ----- Method: SkObject>>keyAtValue:ifAbsent: (in category 'structure') ----- keyAtValue: anObject ifAbsent: aBlock ^ self subclassResponsibility! ----- Method: SkObject>>name: (in category 'structure') ----- name: aString self parent ifNil: [self parent: SkProject current]. self parent uniqueNameAt: aString put: self rule! ----- Method: SkObject>>new (in category 'instance creation') ----- new "Build instance object" ^ self isInstance ifTrue: [self] ifFalse: [SkProxy newFrom: self]! ----- Method: SkObject>>parent (in category 'structure') ----- parent ^ nil! ----- Method: SkObject>>parent: (in category 'structure') ----- parent: aSkRule self subclassResponsibility! ----- Method: SkObject>>parent:uniqueName: (in category 'structure') ----- parent: aSkObject uniqueName: aString self parent: aSkObject; name: aString! ----- Method: SkObject>>pointForHolder:at: (in category 'support') ----- pointForHolder: holderPoint at: aPoint "Translating cordinate local to holder holderPoint is a point that I am put" | rotateDirection standardized | rotateDirection _ self direction == #right ifFalse: [self direction == #down ifTrue: [#right] ifFalse: [self direction == #left ifTrue: [#pi] ifFalse: [self direction == #up ifTrue: [#left]]]]. standardized _ aPoint + (0 @ -1). rotateDirection ifNotNil: [standardized _ standardized rotateBy: rotateDirection centerAt: 0 @ 0]. ^ standardized + holderPoint! ----- Method: SkObject>>printOn: (in category 'accessing') ----- printOn: aStream | aName | super printOn: aStream. (aName _ self ruleName printString) notNil ifTrue: [aStream nextPutAll: '<' , aName , '>']. aStream nextPutAll: '('. aStream print: self identityHash; nextPutAll: ')'! ----- Method: SkObject>>referenceAt: (in category 'updating') ----- referenceAt: aPoint "Answer the dependents object's point(with cordinate of holder)." ^ #()! ----- Method: SkObject>>releaseHolder (in category 'holder and card') ----- releaseHolder! ----- Method: SkObject>>removeAt: (in category 'cell accessing') ----- removeAt: aPosition "Remove value and formula, Then answer the cell" ^NullCell! ----- Method: SkObject>>resolve (in category 'updating') ----- resolve "Rule should not be specified if instantiation is done" self rule resolveOn: self! ----- Method: SkObject>>resolveOn: (in category 'updating') ----- resolveOn: holder ! ----- Method: SkObject>>rule (in category 'accessing') ----- rule ^ self! ----- Method: SkObject>>ruleName (in category 'structure') ----- ruleName "Answer name or nil" ^ self parent ifNil: [self rule class ruleName] ifNotNil: [self parent keyAtValue: self rule]! ----- Method: SkObject>>safetyResolve (in category 'updating') ----- safetyResolve [self resolve] ifError: [:err :rcvr | self stopStepping. self error: err]! ----- Method: SkObject>>saftyResolve (in category 'updating') ----- saftyResolve self safetyResolve! ----- Method: SkObject>>siblingWith: (in category 'copying') ----- siblingWith: deepCopier ^ self veryDeepCopyWith: deepCopier! ----- Method: SkObject>>size (in category 'accessing') ----- size ^ 0! ----- Method: SkObject>>size: (in category 'accessing') ----- size: aNumber ! ----- Method: SkObject>>startStepping (in category 'updating') ----- startStepping | stepList | self wantsSteps ifFalse: [^ self]. self attachProject. stepList _ SkProject current stepList. (stepList includes: self) ifFalse: [stepList add: self]! ----- Method: SkObject>>stopStepping (in category 'updating') ----- stopStepping SkProject current stepList remove: self! ----- Method: SkObject>>textAt: (in category 'accessing') ----- textAt: aPoint "I am send when a user want to edit the value by text editor" | cell contents | aPoint = (0 @ 0) ifTrue: [^ self ruleName asString]. cell _ self cellAt: aPoint. ^ cell formula ifNil: [contents _ (self cellAt: aPoint) contents. contents isText ifTrue: [contents] ifFalse: [contents asCellText asText]] ifNotNil: [cell formula]! ----- Method: SkObject>>textAt:put: (in category 'accessing') ----- textAt: aPoint put: aText | cell | aText = '' ifTrue: [cell _ self removeAt: aPoint. cell hasCard ifTrue: [cell contents releaseHolder. self updatePlan. self changed: #cardList]. ^ '']. aPoint = (0 @ 0) ifTrue: [^ self name: aText asString]. cell _ self assuredCellAt: aPoint. cell editContents: aText. cell resolveFormulaOn: self at: aPoint. self installFormulaAt: aPoint. self changed. ^ aText! ----- Method: SkObject>>uniqueNameAt:put: (in category 'structure') ----- uniqueNameAt: aString put: aSkObject "put object with unique name" | rule oldKey newName | rule _ self rule. oldKey _ rule keyAtValue: aSkObject ifAbsent: []. "object has the name already" (aString notNil and: [aString = oldKey]) ifTrue: [^ aSkObject]. "rename" oldKey ifNotNil: [rule removeAt: oldKey]. newName _ self uniqueNameLike: (aString ifNil: [self defaultName]) satisfy: [:s | (rule includesKey: s) not]. rule at: newName put: aSkObject. "aSkObject parent: rule." ^ aSkObject! ----- Method: SkObject>>uniqueNameLike:satisfy: (in category 'support') ----- uniqueNameLike: aString satisfy: aBlock " self new uniqueNameLike: 'test' satisfy: [:s | (#('test' 'test1' 'test2') includes: s) not] self new uniqueNameLike: 'test1' satisfy: [:s | (#('test' 'test1' 'test2') includes: s) not] " | try | (aBlock value: aString) ifTrue: [^ aString] ifFalse: [1 to: 999999 do: [:i | try _ aString splitInteger first , i printString. (aBlock value: try) ifTrue: [^ try]]]! ----- Method: SkObject>>up (in category 'accessing') ----- up ^ self parent ifNil: [SkProject current]! ----- Method: SkObject>>updateKeys (in category 'accessing') ----- updateKeys ! ----- Method: SkObject>>updatePlan (in category 'updating') ----- updatePlan! ----- Method: SkObject>>wantsUpdate (in category 'updating') ----- wantsUpdate ^ false! SkObject subclass: #SkParametric instanceVariableNames: 'func arg1 arg2' classVariableNames: '' poolDictionaries: '' category: 'Skeleton-Base-Sheet'! ----- Method: SkParametric>>cellAt:ifAbsent: (in category 'accessing') ----- cellAt: aPoint ifAbsent: aBlock | holder | holder _ ValueHolder new. holder contents: ((arg1 isSkObject ifTrue: [arg1 at: aPoint] ifFalse: [arg1]) perform: func with: (arg2 isSkObject ifTrue: [arg2 at: aPoint] ifFalse: [arg2])). ^ holder! ----- Method: SkParametric>>func:arg1:arg2: (in category 'initialization') ----- func: aSymbol arg1: obj1 arg2: obj2 func _ aSymbol. arg1 _ obj1. arg2 _ obj2. ! SkObject subclass: #SkProxy instanceVariableNames: 'rule map size direction' classVariableNames: '' poolDictionaries: '' category: 'Skeleton-Base'! ----- Method: SkProxy class>>newForTest (in category 'instance creation') ----- newForTest "It is just used for test" ^ self newFrom: SkSheet new! ----- Method: SkProxy class>>newFrom: (in category 'instance creation') ----- newFrom: aSkObject ^ super new rule: aSkObject rule! ----- Method: SkProxy>>argPositions (in category 'accessing') ----- argPositions ^ (1 to: size) collect: [:index | index @ 1]! ----- Method: SkProxy>>assuredCellAt: (in category 'cell accessing') ----- assuredCellAt: key key class == Point ifFalse: [^ rule assuredCellAt: key]. ^ map at: key ifAbsent: [map at: key put: (SkProxyCell new holderCell: SkValueCell new argCell: (rule assuredCellAt: key))]! ----- Method: SkProxy>>cardChanged (in category 'updating') ----- cardChanged self changed: #cardList.! ----- Method: SkProxy>>cardList: (in category 'accessing') ----- cardList: aRectangle ^ self cardPositions select: [:key | (self at: key) isSkObject] thenCollect: [:key | key -> (self at: key)]! ----- Method: SkProxy>>cardPositions (in category 'accessing') ----- cardPositions ^ (map keys select: [:each | each class = Point and: [(map at: each) hasCard]]) addAll: rule cardPositions; yourself! ----- Method: SkProxy>>cellAt:ifAbsent: (in category 'cell accessing') ----- cellAt: key ifAbsent: aBlock ^ map at: key ifAbsent: [rule cellAt: key ifAbsent: aBlock]! ----- Method: SkProxy>>collectDependentsForCard: (in category 'updating') ----- collectDependentsForCard: aPoint | points dict | self flag: #TODO. "It has a BAD assumption" points _ self referenceAt: aPoint. dict _ Dictionary new. ^ points size > 1 ifTrue: [dict at: points first put: {aPoint} asSet; yourself]! ----- Method: SkProxy>>direction (in category 'accessing') ----- direction ^ direction! ----- Method: SkProxy>>direction: (in category 'accessing') ----- direction: aSymbol direction _ aSymbol! ----- Method: SkProxy>>holder:at: (in category 'updating') ----- holder: aSkSheet at: aPoint | holderCell | (aSkSheet cellAt: aPoint) hasCard ifFalse: [^ aSkSheet]. (self referenceAt: aPoint) withIndexDo: [:pos :index | holderCell _ aSkSheet assuredCellAt: pos. map at: index @ 1 put: (SkProxyCell new holderCell: holderCell argCell: (rule assuredCellAt: index @ 1))]! ----- Method: SkProxy>>initialize (in category 'initialization') ----- initialize super initialize. direction _ #right. map _ Dictionary new. size _ 0! ----- Method: SkProxy>>installFormulaAt: (in category 'holder and card') ----- installFormulaAt: aPoint rule installFormulaAt: aPoint. "Cell is not needed where card is" (rule cellAt: aPoint) hasCard ifTrue: [ self removeAt: aPoint].! ----- Method: SkProxy>>parent (in category 'structure') ----- parent ^ rule ifNotNil: [rule parent]! ----- Method: SkProxy>>parent: (in category 'structure') ----- parent: aSkRule rule parent: aSkRule! ----- Method: SkProxy>>referenceAt: (in category 'updating') ----- referenceAt: aPoint "Answer the dependents object's point" ^ self argPositions collect: [:each | self pointForHolder: aPoint at: each]! ----- Method: SkProxy>>removeAt: (in category 'cell accessing') ----- removeAt: key | cell | cell _ self cellAt: key. map removeKey: key ifAbsent: []. ^ cell! ----- Method: SkProxy>>resolveOn: (in category 'updating') ----- resolveOn: holder rule resolveOn: self! ----- Method: SkProxy>>rule (in category 'accessing') ----- rule ^ rule! ----- Method: SkProxy>>rule: (in category 'accessing') ----- rule: SkObject rule ifNotNil: [rule removeDependent: self]. SkObject ifNotNil: [SkObject addDependent: self]. rule _ SkObject ! ----- Method: SkProxy>>siblingWith: (in category 'copying') ----- siblingWith: deepCopier | new | new _ self clone. new siblingWithInner: deepCopier. ^ new! ----- Method: SkProxy>>siblingWithInner: (in category 'copying') ----- siblingWithInner: deepCopier map _ map veryDeepCopyWith: deepCopier. size _ size veryDeepCopyWith: deepCopier. direction _ direction veryDeepCopyWith: deepCopier. ^ self! ----- Method: SkProxy>>size (in category 'accessing') ----- size ^ size! ----- Method: SkProxy>>size: (in category 'accessing') ----- size: aNumber size _ aNumber! ----- Method: SkProxy>>up (in category 'accessing') ----- up ^ rule! ----- Method: SkProxy>>update: (in category 'updating') ----- update: anObject anObject == #cardList ifTrue: [self updateCardList]. self changed: anObject! ----- Method: SkProxy>>updateCardList (in category 'updating') ----- updateCardList "Delete dispensable cards" | ruleCards | ruleCards _ rule cardPositions. (self cardPositions select: [:key | (ruleCards includes: key) not]) do: [:key | self removeAt: key]! ----- Method: SkProxy>>updateKeys (in category 'accessing') ----- updateKeys rule updateKeys! ----- Method: SkProxy>>wantsSteps (in category 'updating') ----- wantsSteps ^ true! SkObject subclass: #SkRefFinder instanceVariableNames: 'keys' classVariableNames: '' poolDictionaries: '' category: 'Skeleton-Base'! ----- Method: SkRefFinder>>at: (in category 'accessing') ----- at: key keys add: key. ^ ''! ----- Method: SkRefFinder>>at:put: (in category 'accessing') ----- at: aPosition put: anObject ^ anObject! ----- Method: SkRefFinder>>initialize (in category 'initialization') ----- initialize super initialize. keys _ Set new.! ----- Method: SkRefFinder>>keys (in category 'accessing') ----- keys ^ keys! Object subclass: #SkRule instanceVariableNames: 'observer subjects rule' classVariableNames: '' poolDictionaries: '' category: 'Skeleton-Base'! ----- Method: SkRule class>>observer:subjects:rule: (in category 'instance creation') ----- observer: obs subjects: sub rule: aBlock ^ self new observer: obs subjects: sub rule: aBlock! ----- Method: SkRule>>observer:subjects:rule: (in category 'initialization') ----- observer: obs subjects: sub rule: aBlock observer _ obs. subjects _ sub. rule _ aBlock! ----- Method: SkRule>>printOn: (in category 'printing') ----- printOn: aStream observer printOn: aStream. aStream nextPutAll: ' rule: {'. subjects do: [:each | each printOn: aStream. aStream nextPut: $.]. aStream nextPutAll: '} do: '. rule printOn: aStream.! ----- Method: SkRule>>resolveOn: (in category 'evaluating') ----- resolveOn: holder holder at: observer put: (rule valueWithArguments: (subjects collect: [:each | holder at: each]))! ----- Method: Player>>asCellText (in category '*skeleton-base') ----- asCellText ^ '=References at: #', self uniqueNameForReference! ----- Method: Player>>clearColumn (in category '*skeleton-spreadsheet') ----- clearColumn 0 to: self getTotalRows - 1 do: [:i | self sheet removeAt: self getColumnIndex @ i ]! ----- Method: Player>>clearRow (in category '*skeleton-spreadsheet') ----- clearRow 0 to: self getTotalColumns - 1 do: [:i | self sheet removeAt: i @ self getRowIndex ]! ----- Method: Player>>clearTable (in category '*skeleton-spreadsheet') ----- clearTable 0 to: self getTotalColumns - 1 do: [:i | 0 to: self getTotalRows - 1 do: [:j | self sheet removeAt: i @ j ] ]! ----- Method: Player>>csvFileName (in category '*skeleton-base') ----- csvFileName ^self sheetMorph valueOfProperty: #csvFileName ifAbsent: ['fileName.csv'].! ----- Method: Player>>csvFileName: (in category '*skeleton-base') ----- csvFileName: aString self sheetMorph setProperty: #csvFileName toValue: aString! ----- Method: Player>>csvSeparator (in category '*skeleton-base') ----- csvSeparator ^ self sheetMorph valueOfProperty: #csvSeparator ifAbsent: [$,].! ----- Method: Player>>csvSeparator: (in category '*skeleton-base') ----- csvSeparator: aCharacter self sheetMorph setProperty: #csvSeparator toValue: aCharacter! ----- Method: Player>>exportDataToFile (in category '*skeleton-data i/o') ----- exportDataToFile [self saveCSVFile: self csvFileName separator: self csvSeparator] on: Error do: [:err| ^ self inform: err description]! ----- Method: Player>>getColumnIndex (in category '*skeleton-spreadsheet') ----- getColumnIndex ^ self sheetMorph selection ifNil: [0] ifNotNil: [:rect | rect origin x]! ----- Method: Player>>getCsvFileName (in category '*skeleton-data i/o') ----- getCsvFileName ^ self csvFileName! ----- Method: Player>>getCsvSeparator (in category '*skeleton-data i/o') ----- getCsvSeparator ^ self csvSeparator asString! ----- Method: Player>>getCurrentCharacters (in category '*skeleton-spreadsheet') ----- getCurrentCharacters ^ (self sheet cellAt: self getColumnIndex @ self getRowIndex) contents! ----- Method: Player>>getCurrentNumericValue (in category '*skeleton-spreadsheet') ----- getCurrentNumericValue | str | ^ [(str := self getCurrentCharacters) asNumber] ifError: [:err :rcvr | str asInteger ifNil: [0]]! ----- Method: Player>>getRowIndex (in category '*skeleton-spreadsheet') ----- getRowIndex ^ self sheetMorph selection ifNil: [0] ifNotNil: [:rect | rect origin y]! ----- Method: Player>>getTotalColumns (in category '*skeleton-spreadsheet') ----- getTotalColumns ^ self sheetMorph visibleArea corner x! ----- Method: Player>>getTotalRows (in category '*skeleton-spreadsheet') ----- getTotalRows ^ self sheetMorph visibleArea corner y! ----- Method: Player>>getWriteMode (in category '*skeleton-data i/o') ----- getWriteMode ^ self writeMode! ----- Method: Player>>importDataFromFile (in category '*skeleton-data i/o') ----- importDataFromFile [[self openCSVFile: self csvFileName separator: self csvSeparator] on: FileDoesNotExistException do: [:err | self inform: 'The file doesn''t exist.' translated]] on: Error do: [:err | self inform: 'An error occurred. Please check if the file''s format is CSV.' translated].! ----- Method: Player>>openCSVFile:separator: (in category '*skeleton-data i/o') ----- openCSVFile: filePath separator: separator FileStream readOnlyFileNamed: filePath do: [:file || values rows columns | values := (CSVParser on: file) useDelimiter: separator; rows. rows := values size. columns := values first size. self setTotalRows: rows + 1; setTotalColumns: columns + 1. 1 to: rows do: [:r| 1 to: columns do: [:c | ((values at: r) at: c ifAbsent: nil) ifNotNil: [:aString | (self sheet assuredCellAt: c @ r) contents: aString]]]].! ----- Method: Player>>rows (in category '*skeleton-base') ----- rows ^ (1 to: self getTotalRows - 1) collect: [:r | (1 to: self getTotalColumns - 1) collect: [:c | (self sheet cellAt: c @ r) contents]]! ----- Method: Player>>saveCSVFile:separator: (in category '*skeleton-data i/o') ----- saveCSVFile: filePath separator: separator FileStream perform: (self writeMode = #overwrite ifTrue: [#forceNewFileNamed:do:] ifFalse: [#fileNamed:do:]) with: filePath with: [:file | file setToEnd. self rows do: [:row | row do: [:cell | file nextPut: $"; nextPutAll: (cell copyReplaceAll: '"' with: '""'); nextPut: $"] separatedBy: [file nextPut: separator]. file cr]]! ----- Method: Player>>setColumnIndex: (in category '*skeleton-spreadsheet') ----- setColumnIndex: aNumber self sheetMorph selectSelection: (aNumber \\ self getTotalColumns) @ self getRowIndex! ----- Method: Player>>setCsvFileName: (in category '*skeleton-data i/o') ----- setCsvFileName: aString self csvFileName: aString! ----- Method: Player>>setCsvSeparator: (in category '*skeleton-data i/o') ----- setCsvSeparator: aString ^ self csvSeparator: (aString at: 1 ifAbsent: $,)! ----- Method: Player>>setCurrentCharacters: (in category '*skeleton-spreadsheet') ----- setCurrentCharacters: aString (self sheet assuredCellAt: self getColumnIndex @ self getRowIndex) contents: aString! ----- Method: Player>>setCurrentNumericValue: (in category '*skeleton-spreadsheet') ----- setCurrentNumericValue: aNumber self setCurrentCharacters: aNumber asString! ----- Method: Player>>setRowIndex: (in category '*skeleton-spreadsheet') ----- setRowIndex: aNumber self sheetMorph selectSelection: self getColumnIndex @ (aNumber \\ self getTotalRows)! ----- Method: Player>>setTotalColumns: (in category '*skeleton-spreadsheet') ----- setTotalColumns: aNumber ^ self sheetMorph area: (0@0 corner: aNumber @ self getTotalRows)! ----- Method: Player>>setTotalRows: (in category '*skeleton-spreadsheet') ----- setTotalRows: aNumber ^ self sheetMorph area: (0@0 corner: self getTotalColumns @ aNumber)! ----- Method: Player>>setWriteMode: (in category '*skeleton-data i/o') ----- setWriteMode: aSymbol (#(overwrite append) includes: aSymbol) ifTrue: [self writeMode: aSymbol]! ----- Method: Player>>sheet (in category '*skeleton-base') ----- sheet ^ self sheetMorph model! ----- Method: Player>>sheetMorph (in category '*skeleton-base') ----- sheetMorph ^ self costume renderedMorph! ----- Method: Player>>writeMode (in category '*skeleton-base') ----- writeMode ^self sheetMorph valueOfProperty: #writeMode ifAbsent: [#overwrite].! ----- Method: Player>>writeMode: (in category '*skeleton-base') ----- writeMode: aSymbol self sheetMorph setProperty: #writeMode toValue: aSymbol! ----- Method: SequenceableCollection>>split:do: (in category '*skeleton-base-sheet') ----- split: delimitor do: aBlock | start end | start _ 1. [start <= self size] whileTrue: [end _ self indexOf: delimitor startingAt: start ifAbsent: [self size + 1]. end _ end - 1. aBlock value: (self copyFrom: start to: end). start _ end + 2] " See SkSheetTest>>testSplitDo 'first second forth' delimited: Character tab do: [:aField | Transcript cr; show: aField] 'first second forth ' delimited: Character tab do: [:aField | Transcript cr; show: aField] "! ----- Method: Morph>>addHalo: (in category '*skeleton-base-arrow') ----- addHalo: evt | halo prospectiveHaloClass | prospectiveHaloClass _ Smalltalk at: self haloClass ifAbsent: [HaloMorph]. halo _ prospectiveHaloClass new bounds: self worldBoundsForHalo. halo popUpFor: self event: evt. self showPointArrow. ^halo! ----- Method: Morph>>arrowTargets (in category '*skeleton-base-arrow') ----- arrowTargets | player friends | player _ self player ifNil: [^ #()]. friends _ OrderedCollection new. player class allInstVarNames withIndexDo: [:name :index | ((#(#dependents #costume #costume ) includes: name) not and: [(player instVarAt: index) isKindOf: Player]) ifTrue: [friends add: name -> (player instVarAt: index)]]. ^ friends! ----- Method: Morph>>endHaloInteraction (in category '*skeleton-base-sheet') ----- endHaloInteraction! ----- Method: Morph>>showPointArrow (in category '*skeleton-base-arrow') ----- showPointArrow "ActiveWorld submorphsDo: [:m | m showPointArrow]" self arrowTargets do: [:each | self showPointArrowFrom: each value costume to: self label: each key]! ----- Method: Morph>>showPointArrowFrom:to:label: (in category '*skeleton-base-arrow') ----- showPointArrowFrom: morph1 to: morph2 label: aString "Morph new showPointArrowFrom: (Morph new position: 0@0) to: (Morph new position: 200@200) label: 'test'" | p1 p2 arrow label connector | p1 := morph1 center. p2 := morph2 center. arrow := PolygonMorph arrowPrototype. arrow borderColor: (TranslucentColor r: 1.0 g: 0.3 b: 0.0 alpha: 0.6). arrow setVertices: (Array with: p1 with: p2). arrow dashedBorder: {30. 30. Color transparent. 0. -10}; startStepping. (Smalltalk at: #NCConnectorMorph ifAbsent: []) ifNotNil: [connector := NCConnectorMorph fromMorph: morph1 toMorph: morph2. connector line: arrow. connector lock. label := NCLabelMorph new string: aString. label input: morph1. label color: Color red. label openInWorld. arrow := connector]. [arrow openInWorld. (Delay forMilliseconds: 500) wait. arrow delete. label ifNotNilDo: [:obj | obj delete]] fork! Morph subclass: #SkGridMorph instanceVariableNames: 'area converter' classVariableNames: '' poolDictionaries: '' category: 'Skeleton-Base'! ----- Method: SkGridMorph class>>standardCellExtent (in category 'constant') ----- standardCellExtent ^ 80 @ 20! ----- Method: SkGridMorph class>>titleStyle (in category 'constant') ----- titleStyle #(#NewYork #Accujen ) do: [:fontName | (TextStyle named: fontName) ifNotNilDo: [:style | ^ style fontOfPointSize: 24]]. Error signal: 'Font not found'! ----- Method: SkGridMorph>>area (in category 'accessing') ----- area ^ area ! ----- Method: SkGridMorph>>area: (in category 'accessing') ----- area: aRectangle area = aRectangle ifTrue: [^ self]. area _ aRectangle. self areaChanged. self changed! ----- Method: SkGridMorph>>areaChanged (in category 'layout') ----- areaChanged | newBounds | self visibleArea ifNil: [^ self hide] ifNotNil: [converter _ SkCellScreenConverter grid: self border: 1. self show. newBounds _ self cellAreaToScreen: self visibleArea. self position: newBounds topLeft. self extent: newBounds extent]! ----- Method: SkGridMorph>>borderStyle (in category 'visual properties') ----- borderStyle ^ self model ifNil: [super borderStyle] ifNotNil: [SkColorSet borderStyleFor: self model rule]! ----- Method: SkGridMorph>>cellAreaToScreen: (in category 'layout') ----- cellAreaToScreen: aRectangle ^ converter cellAreaToScreen: aRectangle topLeft: self topLeft + self expandSize! ----- Method: SkGridMorph>>cellExtentAt: (in category 'layout') ----- cellExtentAt: aPoint ^self class standardCellExtent! ----- Method: SkGridMorph>>cellOrigin (in category 'accessing') ----- cellOrigin ^ area origin ! ----- Method: SkGridMorph>>cellToScreenRect: (in category 'layout') ----- cellToScreenRect: aPoint ^ converter cellToScreenRect: aPoint topLeft: self topLeft + self expandSize! ----- Method: SkGridMorph>>drawBorder: (in category 'drawing') ----- drawBorder: aCanvas | y offset x borderColor borderWidth | offset _ self borderWidth // 2. borderColor _ self borderColor. borderWidth _ self borderWidth. self visibleArea top to: self visibleArea bottom - 2 do: [:row | y _ (self cellToScreenRect: self visibleArea right @ row) bottom + offset. aCanvas fillRectangle: (self left + borderWidth @ y corner: self right - borderWidth @ y + 1) color: borderColor]. self visibleArea left to: self visibleArea right - 2 do: [:col | x _ (self cellToScreenRect: col @ self visibleArea top) right + offset. aCanvas fillRectangle: (x @ (self top + borderWidth) corner: x + 1 @ (self bottom - borderWidth)) color: borderColor]! ----- Method: SkGridMorph>>drawCell:at: (in category 'drawing') ----- drawCell: aCanvas at: aPoint ! ----- Method: SkGridMorph>>drawContents: (in category 'drawing') ----- drawContents: aCanvas | block | block _ [self model ifNil: [^ self]. self visibleArea top to: self visibleArea bottom - 1 do: [:row | self visibleArea left to: self visibleArea right - 1 do: [:col | self drawCell: aCanvas at: col @ row]]]. self isDebug ifTrue: [[block value] ifError: [:err :rcvr | rcvr]] ifFalse: [block value]! ----- Method: SkGridMorph>>drawContents:on:at: (in category 'drawing') ----- drawContents: anObject on: aCanvas at: aPoint "To debug, try self drawCell: World canvas at: 2@6 " | aRectangle string morph | (anObject isSkObject) ifTrue: [^ self]. (anObject isKindOf: Player) ifTrue: [^ self drawPlayer: anObject on: aCanvas at: aPoint]. anObject = '' ifTrue: [^ self]. aRectangle _ self localCellToScreenRect: aPoint. string _ anObject isString ifTrue: [anObject] ifFalse: [anObject isNumber ifTrue: [anObject asString]]. string ifNil: [morph _ anObject isText ifTrue: [TextMorph new contents: anObject] ifFalse: [(anObject isKindOf: Player) ifTrue: [anObject costume] ifFalse: [anObject asMorph]]. aCanvas translateTo: aRectangle topLeft - morph bounds origin clippingTo: (aRectangle topLeft corner: self bottomRight) during: [:c | morph drawOn: c]] ifNotNil: [aCanvas drawString: string in: (aRectangle expandBy: -2) font: TextStyle defaultFont color: Color black]! ----- Method: SkGridMorph>>drawDependMap: (in category 'drawing') ----- drawDependMap: aCanvas | subjectColor dependArray observer subjects observerColor | subjectColor _ SkColorSet selectedFor: self model rule. observerColor _ subjectColor adjustBrightness: -0.06. dependArray _ self model rule collectDependents. "draw subjects" aCanvas clipBy: self bounds during: [:canvas | (dependArray inject: Set new into: [:set :next | set addAll: next allButFirst; yourself]) do: [:each | canvas fillOval: ((self localCellToScreenRect: each) center - (7 @ 7) extent: 14 @ 14) fillStyle: subjectColor]. "draw objerver and line" dependArray do: [:each | observer _ each first. subjects _ each allButFirst. canvas fillOval: ((self localCellToScreenRect: observer) center - (4 @ 4) extent: 8 @ 8) fillStyle: observerColor. subjects do: [:end | canvas line: (self localCellToScreenRect: observer) center to: (self localCellToScreenRect: end) center width: 1 color: observerColor]]]! ----- Method: SkGridMorph>>drawGrabAreaOn: (in category 'drawing') ----- drawGrabAreaOn: aCanvas | rect borderColor | borderColor _ self borderColor. rect _ self grabArea. rect left to: rect right by: 2 do: [:x | aCanvas frameRectangle: (x @ rect top corner: x + 1 @ rect bottom) color: borderColor]! ----- Method: SkGridMorph>>drawLabel:string:at: (in category 'drawing') ----- drawLabel: aCanvas string: aString at: aPoint | aRectangle | aRectangle _ self localCellToScreenRect: aPoint. aCanvas clipBy: self bounds during: [:canvas | canvas fillRectangle: aRectangle color: (SkColorSet labelFor: (self model ifNotNil: [self model rule])). canvas drawString: aString asString in: ((aRectangle expandBy: -2) withLeft: aRectangle left + 6) font: ScriptingSystem fontForTiles color: Color black]! ----- Method: SkGridMorph>>drawPlayer:on:at: (in category 'drawing') ----- drawPlayer: aPlayer on: aCanvas at: aPoint "To debug, try self drawCell: World canvas at: 2@6 " | aRectangle morph form scaleX scaleY scale | morph _ aPlayer costume. aRectangle _ self localCellToScreenRect: aPoint. form _ morph imageForm. scaleY _ aRectangle height / form height. scaleX _ aRectangle width / form width. scale _ (scaleX min: scaleY) min: 1. form _ form magnify: form boundingBox by: scale @ scale smoothing: 2. aCanvas translucentImage: form at: (aRectangle topLeft + (aRectangle extent - form extent / 2)) asIntegerPoint! ----- Method: SkGridMorph>>expandSize (in category 'accessing') ----- expandSize ^ 0! ----- Method: SkGridMorph>>externalName (in category 'accessing') ----- externalName ^ self model ifNotNilDo: [:m | "name can be nil" m ruleName asString]! ----- Method: SkGridMorph>>fillStyle: (in category 'visual properties') ----- fillStyle: aFillStyle super fillStyle: aFillStyle. self model ifNotNil: [SkColorSet for: self model rule color: aFillStyle asColor]. self changed! ----- Method: SkGridMorph>>globalToLocal: (in category 'layout') ----- globalToLocal: aPoint ^ aPoint! ----- Method: SkGridMorph>>grabArea (in category 'accessing') ----- grabArea ^ (self topLeft corner: self right @ (self top + 16)) insetBy: 3! ----- Method: SkGridMorph>>isDebug (in category 'debug') ----- isDebug ^ true! ----- Method: SkGridMorph>>labelAt: (in category 'drawing') ----- labelAt: aPoint aPoint x = aPoint y ifTrue: [^ '']. aPoint x = 0 ifTrue: [^ aPoint y asString]. ^ ($A asInteger + aPoint x - 1) asCharacter asString! ----- Method: SkGridMorph>>localCellToScreenRect: (in category 'layout') ----- localCellToScreenRect: aPoint ^ self cellToScreenRect: aPoint! ----- Method: SkGridMorph>>model (in category 'accessing') ----- model ^ self subclassResponsibility! ----- Method: SkGridMorph>>screenToCell: (in category 'layout') ----- screenToCell: aPoint ^ converter screenToCell: aPoint topLeft: self topLeft + self expandSize! ----- Method: SkGridMorph>>setExtentFromHalo: (in category 'layout') ----- setExtentFromHalo: newExtent "Answer new cell size" | newSize | newSize _ (self screenToCell: self topLeft + newExtent) - self area origin. newSize _ newSize max: 1 @ 1. self area extent ~~ newSize ifTrue: [self area: (self area origin extent: newSize)]. ^ newSize! ----- Method: SkGridMorph>>visibleArea (in category 'accessing') ----- visibleArea ^ self area! SkGridMorph subclass: #SkGridPartsMorph instanceVariableNames: 'holder' classVariableNames: '' poolDictionaries: '' category: 'Skeleton-Base'! SkGridPartsMorph subclass: #SkCardMorph instanceVariableNames: 'model origin size' classVariableNames: '' poolDictionaries: '' category: 'Skeleton-Base'! !SkCardMorph commentStamp: 'tak 12/26/2003 19:45' prior: 0! I am a Card bar of a rule. area always NIL model SkRule (maybe SkCard) origin Point a position of label size SmallInteger -- It is used when model has no size (it is ugly implementation...) The morphs area is determined based on area's origin, size, and model's direction.! ----- Method: SkCardMorph class>>model: (in category 'instance creation') ----- model: aSkObject ^ super new model: aSkObject! ----- Method: SkCardMorph class>>new (in category 'instance creation') ----- new self error: 'SkCardMorph must only be created with model: aSkObject'! ----- Method: SkCardMorph class>>newFrom: (in category 'instance creation') ----- newFrom: aSkSheetMorph | cardMorph | cardMorph _ self model: aSkSheetMorph model. cardMorph area: (0 @ 1 extent: aSkSheetMorph area width @ 1). cardMorph position: aSkSheetMorph position. ^ cardMorph! ----- Method: SkCardMorph>>addFlexShellIfNecessary (in category 'rotate scale and flex') ----- addFlexShellIfNecessary "When scaling or rotating from a halo, I can do this without a flex shell" ^ self ! ----- Method: SkCardMorph>>area (in category 'accessing') ----- area ^ model direction = #right ifTrue: [origin extent: self size + 1 @ 1] ifFalse: [model direction = #down ifTrue: [origin extent: 1 @ (self size + 1)] ifFalse: [model direction = #left ifTrue: [origin - (self size @ 0) corner: origin + 1] ifFalse: [origin - (0 @ self size) corner: origin + 1]]]! ----- Method: SkCardMorph>>area: (in category 'accessing') ----- area: aRectangle "area corner is determined by size and direction" self cellOrigin: ((#(#right #down ) includes: model direction) ifTrue: [aRectangle origin] ifFalse: [model direction = #left ifTrue: [aRectangle origin + (self size @ 0)] ifFalse: [aRectangle origin + (0 @ self size)]]). self isHorizonal ifTrue: [self size: aRectangle width - 1] ifFalse: [self size: aRectangle height - 1]. self changed! ----- Method: SkCardMorph>>cellOrigin (in category 'accessing') ----- cellOrigin "The cell point which has label" ^ origin! ----- Method: SkCardMorph>>cellOrigin: (in category 'accessing') ----- cellOrigin: aPoint "The cell point which has label" origin _ aPoint. self areaChanged.! ----- Method: SkCardMorph>>direction (in category 'accessing') ----- direction ^ model direction! ----- Method: SkCardMorph>>direction: (in category 'accessing') ----- direction: aSymbol self keepCellOriginDo: [model direction: aSymbol]! ----- Method: SkCardMorph>>doubleClick: (in category 'event handling') ----- doubleClick: evt | sheet | (holder notNil and: [owner = holder]) ifTrue: [^ holder goto: model]. self owner = World ifTrue: [self delete]. sheet _ SkSheetMorph allInstances detect: [:each | each world = World and: [each model = model]] ifNone: [model grid]. sheet position: self position; openInWorld! ----- Method: SkCardMorph>>drawCell:at: (in category 'drawing') ----- drawCell: aCanvas at: aPoint | modelPoint | modelPoint _ self globalToLocal: aPoint. modelPoint = (0 @ 1) ifTrue: [^ self drawLabel: aCanvas string: model ruleName at: modelPoint]. self drawContents: (model at: modelPoint) on: aCanvas at: modelPoint. ! ----- Method: SkCardMorph>>drawOn: (in category 'drawing') ----- drawOn: aCanvas super drawOn: aCanvas. self drawGrabAreaOn: aCanvas. self drawContents: aCanvas. self drawBorder: aCanvas! ----- Method: SkCardMorph>>endHaloInteraction (in category 'event handling') ----- endHaloInteraction self isOnHolder ifFalse: [^ self]. holder model textAt: self cellOrigin put: '=' , model codeString. self halo ifNotNilDo: [:halo | halo setTarget: (holder cardMorphAt: self cellOrigin ifAbsent: []). self delete]! ----- Method: SkCardMorph>>expandSize (in category 'accessing') ----- expandSize ^ -2! ----- Method: SkCardMorph>>fillStyle (in category 'visual properties') ----- fillStyle ^ SkColorSet baseFor: model rule! ----- Method: SkCardMorph>>globalToLocal: (in category 'layout') ----- globalToLocal: aPoint "Transformation a position of cell" | normalized | normalized _ aPoint - self cellOrigin. model direction = #left ifTrue: [^ normalized * -1 + (0 @ 1)]. model direction = #down ifTrue: [^ normalized transposed + (0 @ 1)]. model direction = #up ifTrue: [^ normalized transposed * -1 + (0 @ 1)]. ^ normalized + (0 @ 1)! ----- Method: SkCardMorph>>grabArea (in category 'accessing') ----- grabArea | width inset base | width _ 16. inset _ 3. base _ self cellToScreenRect: self cellOrigin. ^ model direction = #right ifTrue: [(base topLeft corner: base left + width @ base bottom) insetBy: inset] ifFalse: [model direction = #down ifTrue: [(base topLeft corner: base right @ (base top + width)) insetBy: inset] ifFalse: [model direction = #left ifTrue: [(base right - width @ base top corner: base bottomRight) insetBy: inset] ifFalse: [(base left @ (base bottom - width) corner: base bottomRight) insetBy: inset]]]! ----- Method: SkCardMorph>>handlesMouseDown: (in category 'event handling') ----- handlesMouseDown: evt ^ (self screenToCell: evt position) = self cellOrigin! ----- Method: SkCardMorph>>holderArea (in category 'accessing') ----- holderArea ^ 1@1 corner: holder area bottomRight! ----- Method: SkCardMorph>>initialize (in category 'initialization') ----- initialize super initialize. origin _ 0 @ 0. self borderStyle: (RaisedBorder color: Color black width: 1). self fillStyle: (SolidFillStyle color: (Color r: 1.0 g: 0.935 b: 0.839)). self cornerStyle: #rounded! ----- Method: SkCardMorph>>isHorizonal (in category 'testing') ----- isHorizonal ^ #(#right #left ) includes: model direction! ----- Method: SkCardMorph>>isMorphicModel (in category 'classification') ----- isMorphicModel ^true! ----- Method: SkCardMorph>>keepCellOriginDo: (in category 'accessing') ----- keepCellOriginDo: aBlock | oldOriginByScreen delta | oldOriginByScreen _ (self cellToScreenRect: self cellOrigin) topLeft. aBlock value. self areaChanged. delta _ oldOriginByScreen - (self cellToScreenRect: self cellOrigin) topLeft. self topLeft: self topLeft + delta. self areaChanged! ----- Method: SkCardMorph>>localCellToScreenRect: (in category 'layout') ----- localCellToScreenRect: aPoint ^ self cellToScreenRect: (self localToGlobal: aPoint)! ----- Method: SkCardMorph>>localToGlobal: (in category 'layout') ----- localToGlobal: aPoint | normalized | normalized _ aPoint + (0 @ -1). model direction = #left ifTrue: [^ normalized * -1 + self cellOrigin]. model direction = #down ifTrue: [^ normalized transposed + self cellOrigin]. model direction = #up ifTrue: [^ normalized transposed * -1 + self cellOrigin]. ^ normalized + self cellOrigin! ----- Method: SkCardMorph>>model (in category 'accessing') ----- model ^ model! ----- Method: SkCardMorph>>model: (in category 'accessing') ----- model: aSkRule model _ aSkRule. self areaChanged! ----- Method: SkCardMorph>>mouseDown: (in category 'event handling') ----- mouseDown: evt "For easy doublecilck to selection" evt hand waitForClicksOrDrag: self event: evt. evt yellowButtonPressed ifTrue: [^ model invokeCardMenu: evt] ifFalse: [(self grabArea containsPoint: evt position) ifTrue: [evt hand grabMorph: self]]! ----- Method: SkCardMorph>>referencePosition (in category 'rotate scale and flex') ----- referencePosition ^ (self cellToScreenRect: self cellOrigin) center! ----- Method: SkCardMorph>>replaceToSheet: (in category 'layout') ----- replaceToSheet: newCellExtent "Create new spreadsheet for the model. And I will be deleted" | sheetMorph | (newCellExtent y > 1 and: [newCellExtent x > 1]) ifTrue: [sheetMorph _ SkSheetMorph new model: model. sheetMorph area: (0 @ 0 extent: newCellExtent). sheetMorph position: self position. self owner addMorph: sheetMorph. self halo ifNotNilDo: [:helo | helo setTarget: sheetMorph]. ^ self delete]! ----- Method: SkCardMorph>>rotationDegrees: (in category 'rotate scale and flex') ----- rotationDegrees: degrees | d newDirection | d _ degrees \\ 360. newDirection _ #right. (d < 45 or: [315 <= d]) ifTrue: [newDirection _ #right] ifFalse: [d < 135 ifTrue: [newDirection _ #down] ifFalse: [d < 225 ifTrue: [newDirection _ #left] ifFalse: [d < 315 ifTrue: [newDirection _ #up]]]]. self forwardDirection: degrees. self direction ~~ newDirection ifTrue: ["Transcript show: ActiveHand target printString." self direction: newDirection. self halo ifNil: [self isOnHolder ifTrue: [holder model textAt: self cellOrigin put: '=' , model codeString]]]. self changed! ----- Method: SkCardMorph>>setExtentFromHalo: (in category 'layout') ----- setExtentFromHalo: newExtent | newCellExtent nSize | newCellExtent _ (self screenToCell: ActiveHand position - 10) - origin. (newCellExtent y > 1 and: [newCellExtent x > 1]) ifTrue: [^ self replaceToSheet: newCellExtent]. nSize _ (newCellExtent x abs max: newCellExtent y abs) max: 0. newCellExtent y > (0 - newCellExtent x) ifTrue: [newCellExtent y < newCellExtent x ifTrue: [self direction: #right] ifFalse: [self direction: #down]] ifFalse: [newCellExtent y < newCellExtent x ifTrue: [self direction: #up] ifFalse: [self direction: #left]]. self size: nSize! ----- Method: SkCardMorph>>size (in category 'accessing') ----- size ^ model size ifNil: [size ifNil: [size _ 0]]! ----- Method: SkCardMorph>>size: (in category 'accessing') ----- size: aNumber (aNumber > 0 and: [model isInstance not]) ifTrue: [self model: model new]. self keepCellOriginDo: [model size ifNil: ["Maybe it doesn't need" nil. size _ aNumber] ifNotNil: [model size: aNumber]]! ----- Method: SkCardMorph>>veryDeepInner: (in category 'accessing') ----- veryDeepInner: deepCopier "rule is not copied" model _ model siblingWith: deepCopier. origin _ origin veryDeepCopyWith: deepCopier. size _ size veryDeepCopyWith: deepCopier. super veryDeepInner: deepCopier! ----- Method: SkGridPartsMorph>>cellAreaToScreen: (in category 'layout') ----- cellAreaToScreen: aRectangle ^ (self isOnHolder ifTrue: [holder cellAreaToScreen: aRectangle] ifFalse: [super cellAreaToScreen: aRectangle]) expandBy: self expandSize! ----- Method: SkGridPartsMorph>>cellToScreenRect: (in category 'layout') ----- cellToScreenRect: aRectangle ^ self isOnHolder ifTrue: [holder cellToScreenRect: aRectangle] ifFalse: [super cellToScreenRect: aRectangle]! ----- Method: SkGridPartsMorph>>holder (in category 'accessing') ----- holder "it's only for test" ^ holder.! ----- Method: SkGridPartsMorph>>holder: (in category 'accessing') ----- holder: anObject holder _ anObject! ----- Method: SkGridPartsMorph>>holderArea (in category 'accessing') ----- holderArea ^ holder area! ----- Method: SkGridPartsMorph>>isOnHolder (in category 'testing') ----- isOnHolder ^ holder notNil and: [owner = holder]! ----- Method: SkGridPartsMorph>>veryDeepInner: (in category 'copying') ----- veryDeepInner: deepCopier "holder is not copied" ! ----- Method: SkGridPartsMorph>>visibleArea (in category 'accessing') ----- visibleArea "Answer nil if no intersect" | visibleArea | self area ifNil: [^ nil]. ^ self isOnHolder ifTrue: [visibleArea _ self area intersect: self holderArea. visibleArea hasPositiveExtent ifTrue: [visibleArea]] ifFalse: [self area]! SkGridPartsMorph subclass: #SkGridSelectionMorph instanceVariableNames: 'editor' classVariableNames: '' poolDictionaries: '' category: 'Skeleton-Base'! ----- Method: SkGridSelectionMorph>>area: (in category 'accessing') ----- area: aRectangle editor ifNil: [super area: aRectangle] ifNotNil: [(editor text isEmpty not and: [editor text first = $= and: [editor hasUnacceptedEdits]]) ifTrue: [editor correctSelectionWithString: (SkParser pointToA1Name: aRectangle origin)] ifFalse: [editor accept. editor _ nil. super area: aRectangle]]! ----- Method: SkGridSelectionMorph>>borderStyle (in category 'visual properties') ----- borderStyle ^ SkColorSet selectedBorderStyleFor: (holder ifNotNil: [holder model rule])! ----- Method: SkGridSelectionMorph>>deleteEditor (in category 'accessing') ----- deleteEditor editor delete. editor _ nil! ----- Method: SkGridSelectionMorph>>doubleClick: (in category 'event handling') ----- doubleClick: evt (self bounds containsPoint: ActiveHand position) ifTrue: [self installEditor]! ----- Method: SkGridSelectionMorph>>drawOn: (in category 'drawing') ----- drawOn: aCanvas | clip | clip _ aCanvas copyClipRect: self bounds. super drawOn: aCanvas. editor ifNil: [holder drawBorder: clip. holder drawContents: clip]! ----- Method: SkGridSelectionMorph>>editor (in category 'accessing') ----- editor ^ editor! ----- Method: SkGridSelectionMorph>>expandSize (in category 'accessing') ----- expandSize ^ 2! ----- Method: SkGridSelectionMorph>>externalName (in category 'accessing') ----- externalName ^ SkParser pointToA1Name: area topLeft! ----- Method: SkGridSelectionMorph>>fillStyle (in category 'visual properties') ----- fillStyle ^ SkColorSet selectedFor: (holder ifNotNil: [holder model rule])! ----- Method: SkGridSelectionMorph>>handlesKeyboard: (in category 'event handling') ----- handlesKeyboard: evt ^ true! ----- Method: SkGridSelectionMorph>>handlesMouseDown: (in category 'event handling') ----- handlesMouseDown: evt ^ true! ----- Method: SkGridSelectionMorph>>initialize (in category 'initialization') ----- initialize super initialize. area _ 1 @ 1 extent: 4 @ 4. self borderStyle: (RaisedBorder color: Color black width: 1). self fillStyle: (SolidFillStyle color: (Color r: 1.0 g: 0.935 b: 0.839)). " self cornerStyle: #rounded"! ----- Method: SkGridSelectionMorph>>installEditor (in category 'event handling') ----- installEditor self area ifNil: [^self]. editor ifNil: [editor _ PluggableTextMorph on: holder text: #editContents accept: #editContents:]. editor setProperty: #alwaysAccept toValue: true. editor acceptOnCR: true. editor hideScrollBarIndefinitely. editor borderWidth: 0. editor bounds: (holder cellToScreenRect: self area origin). editor selectAll. self addMorphFront: editor. ActiveHand newKeyboardFocus: editor. editor on: #mouseLeave send: holder to: #acceptCell! ----- Method: SkGridSelectionMorph>>invokeMenu: (in category 'menu') ----- invokeMenu: evt | menu | menu _ MenuMorph new defaultTarget: holder. (holder model cellAt: self area topLeft) label ifNotNilDo: [:label | menu addTitle: label]. menu add: (holder showFormula ifTrue: ['<on>'] ifFalse: ['<off>']) , 'formula' translated target: holder selector: #toggleFormula. (holder model cellAt: self area topLeft) player ifNotNilDo: [:player | menu add: 'reveal this object' target: player selector: #revealPlayerIn: argument: ActiveWorld. player costume showPointArrowFrom: player costume to: self label: ' ']. menu addList: {{'library' translated. #openLibrary}. #-. {'copy (c)' translated. #copySelection}. {'cut (x)' translated. #cut}. {'paste (v)' translated. #paste}. {'spawn (o)' translated. #spawn}}. menu popUpEvent: evt in: self world! ----- Method: SkGridSelectionMorph>>keyStroke: (in category 'event handling') ----- keyStroke: evt evt keyValue = $c asciiValue ifTrue: [^ holder copySelection]. evt keyValue = $o asciiValue ifTrue: [^ holder spawn]. evt keyValue = $v asciiValue ifTrue: [^ holder paste]. evt keyValue = $x asciiValue ifTrue: [^ holder cut]. self installEditor. editor ifNotNil: [editor keyStroke: evt].! ----- Method: SkGridSelectionMorph>>model (in category 'accessing') ----- model ^ holder ifNotNil: [holder model]! ----- Method: SkGridSelectionMorph>>mouseDown: (in category 'event handling') ----- mouseDown: evt evt yellowButtonPressed ifTrue: [^ self invokeMenu: evt]. owner ifNotNil: [owner mouseDown: evt]! ----- Method: SkGridSelectionMorph>>mouseMove: (in category 'event handling') ----- mouseMove: evt | newArea | newArea _ self area encompass: (holder screenToCell: evt position) + 1. area _ newArea. self areaChanged! ----- Method: SkGridSelectionMorph>>screenToCell: (in category 'layout') ----- screenToCell: aPoint ^ holder ifNil: [super screenToCell: aPoint] ifNotNil: [holder screenToCell: aPoint]! ----- Method: SkGridSelectionMorph>>setExtentFromHalo: (in category 'layout') ----- setExtentFromHalo: newExtent self isOnHolder ifTrue: [holder setCellExtentFromHalo: newExtent]! SkGridMorph subclass: #SkSheetMorph instanceVariableNames: 'history model selectionMorph dropZone showFormula' classVariableNames: '' poolDictionaries: '' category: 'Skeleton-Base'! !SkSheetMorph commentStamp: 'tak 12/11/2003 19:10' prior: 0! I am a presentation compornent for showing as 2-D grid. The contents what I show is depended on a model. I never access to a cell directly except through model because a cell doesn't know where he locates. Basically, Position information is only in model. cellArea Rectangle -- the area of cells for drawing. Actual size of table is cellArea extent. model SkSheet -- ! ----- Method: SkSheetMorph class>>additionsToViewerCategories (in category 'viewer categories') ----- additionsToViewerCategories ^ #( (#spreadsheet ( #(command clearTable 'Deletes the contents of all cells') #(command clearRow 'Deletes the contents of the current row cells' ) #(command clearColumn 'Deletes the contents of the current columns cells' ) #(slot totalRows 'Lets you change the amount of rows in the spreadsheet' Number readWrite Player getTotalRows Player setTotalRows: ) #(slot totalColumns 'Lets you change the amount of columns in the spreadsheet' Number readWrite Player getTotalColumns Player setTotalColumns: ) #(slot rowIndex 'Sets the current row' Number readWrite Player getRowIndex Player setRowIndex: ) #(slot columnIndex 'Sets the current column' Number readWrite Player getColumnIndex Player setColumnIndex: ) #(slot currentCharacters 'Lets you read and modify the characters of the current cell' String readWrite Player getCurrentCharacters Player setCurrentCharacters: ) #(slot currentNumericValue 'Lets you read and modify the numeric value of the current cell' Number readWrite Player getCurrentNumericValue Player setCurrentNumericValue: ) )) (#'data i/o' ( #(slot writeMode 'Lets you choose a write mode (overwrite or append)' WriteMode readWrite Player getWriteMode Player setWriteMode: ) #(slot csvSeparator 'Lets you choose a character to act as a separator between cells' String readWrite Player getCsvSeparator Player setCsvSeparator: ) #(slot csvFileName 'Sets the name of the file to import/export data' String readWrite Player getCsvFileName Player setCsvFileName: ) #(command importDataFromFile 'Reads the data from the file and loads it in the spreadsheet') #(command exportDataToFile 'Writes the data from the spreadsheet into the file') )) )! ----- Method: SkSheetMorph class>>descriptionForPartsBin (in category 'parts bin') ----- descriptionForPartsBin ^ self partName: 'Spread Sheet' categories: #('Skeleton') documentation: 'A spread sheet'! ----- Method: SkSheetMorph class>>formPreviousPage (in category 'constants') ----- formPreviousPage ^((ColorForm extent: 5@9 depth: 1 fromArray: #( 4026531840 3758096384 3489660928 2952790016 1879048192 2952790016 3489660928 3758096384 4026531840) offset: 0@0) colorsFromArray: #(#(0.0 0.0 0.0) #( ) )) " form storeString "! ----- Method: SkSheetMorph class>>formUpPage (in category 'constants') ----- formUpPage ^((ColorForm extent: 9@5 depth: 2 fromArray: #( 2859106304 2845474816 2795929600 2326298624 1431650304) offset: 0@0) colorsFromArray: #(#(0.004 0.004 0.008) #(0.0 0.0 0.004) #( ) #(0.0 0.0 0.0) )) " form storeString "! ----- Method: SkSheetMorph class>>initialize (in category 'class initialization') ----- initialize " self initialize. " Vocabulary addStandardVocabulary: (SymbolListType new vocabularyName: #WriteMode; symbols: #(#overwrite #append)).! ----- Method: SkSheetMorph class>>model: (in category 'instance creation') ----- model: aSkObject ^ super new model: aSkObject! ----- Method: SkSheetMorph>>acceptDroppingMorph:event: (in category 'drag and drop') ----- acceptDroppingMorph: aMorph event: evt | cellPos successed | cellPos _ self screenToCell: aMorph topLeft. (cellPos x < 1 or: [cellPos y < 1]) ifTrue: [self beep: 'arrow'. ^ aMorph rejectDropMorphEvent: evt]. successed _ false. successed _ (aMorph isKindOf: SkGridPartsMorph) ifTrue: [self acceptRuleMorph: aMorph event: evt] ifFalse: [aMorph class = PhraseTileMorph ifTrue: [self acceptPhraseTileMorph: aMorph event: evt] ifFalse: [aMorph class = TileMorph ifTrue: [self acceptTileMorph: aMorph event: evt]]]. successed ifTrue: [self beep: 'cassete'] ifFalse: [self beep: 'arrow'. aMorph rejectDropMorphEvent: evt]! ----- Method: SkSheetMorph>>acceptPhraseTileMorph:event: (in category 'drag and drop') ----- acceptPhraseTileMorph: aMorph event: evt | setter getter | getter _ aMorph operatorTile operatorOrExpression. setter _ ('set' , (getter allButFirst: 3) , ':') asSymbol. self model modelAt: (self screenToCell: aMorph topLeft) for: aMorph actualObject getter: getter setter: setter. ^ true! ----- Method: SkSheetMorph>>acceptRuleMorph:event: (in category 'drag and drop') ----- acceptRuleMorph: aMorph event: evt | cellPos card | model parent adopt: aMorph model rule. cellPos _ (self screenToCell: aMorph topLeft) + (aMorph cellOrigin - aMorph area topLeft). self model textAt: cellPos put: '=' , aMorph model codeString. card _ self cardMorphAt: cellPos ifAbsent: [^ false]. card model rule = aMorph model rule ifFalse: ["maybe successed" ^ false]. aMorph halo ifNotNilDo: [:halo | halo setTarget: card]. ^ true! ----- Method: SkSheetMorph>>acceptTileMorph:event: (in category 'drag and drop') ----- acceptTileMorph: aMorph event: evt | object | object _ aMorph actualObject. self model at: (self screenToCell: aMorph topLeft) put: object. ^ true! ----- Method: SkSheetMorph>>areaChanged (in category 'layout') ----- areaChanged super areaChanged. self submorphsDo: [:m | (m isKindOf: SkGridMorph) ifTrue: [m areaChanged]]! ----- Method: SkSheetMorph>>cardMorphAt:ifAbsent: (in category 'accessing') ----- cardMorphAt: aPoint ifAbsent: aBlock ^ self submorphs detect: [:m | m class = SkCardMorph and: [m cellOrigin = aPoint]] ifNone: aBlock! ----- Method: SkSheetMorph>>cellExtentAt: (in category 'layout') ----- cellExtentAt: aPoint | cellExtent x y | ^ (model notNil and: [(cellExtent _ model findName: self cellExtentName) class == SkSheet ]) ifTrue: [x _ (cellExtent at: aPoint x @ 1 ifAbsent: [SkGridMorph standardCellExtent]) x. y _ (cellExtent at: 1 @ aPoint y ifAbsent: [SkGridMorph standardCellExtent]) y. x @ y] ifFalse: [SkGridMorph standardCellExtent]! ----- Method: SkSheetMorph>>cellExtentName (in category 'layout') ----- cellExtentName ^ 'CellExtent'! ----- Method: SkSheetMorph>>copySelection (in category 'action') ----- copySelection | text | text _ Text streamContents: [:aStream | self selection top to: self selection bottom - 1 do: [:y | (self selection left to: self selection right - 1) do: [:x | aStream nextPutAll: (model textAt: x @ y)] separatedBy: [aStream nextPut: Character tab]. aStream nextPut: Character cr]]. Clipboard clipboardText: text! ----- Method: SkSheetMorph>>cut (in category 'action') ----- cut self copySelection. self selection top to: self selection bottom - 1 do: [:y | self selection left to: self selection right - 1 do: [:x | model textAt: x @ y put: '']]! ----- Method: SkSheetMorph>>drawCell:at: (in category 'drawing') ----- drawCell: aCanvas at: aPoint (aPoint x isZero or: [aPoint y isZero]) ifTrue: [^ self drawLabel: aCanvas string: (self labelAt: aPoint) at: aPoint]. self flag: #TODO. self drawContents: ((showFormula notNil and: [showFormula]) ifTrue: [model textAt: aPoint] ifFalse: [ showFormula _ false.model at: aPoint.]) on: aCanvas at: aPoint! ----- Method: SkSheetMorph>>drawName: (in category 'drawing') ----- drawName: aCanvas | name | name := model ruleName asString. model isInstance ifTrue: [name := name , '*']. aCanvas clipBy: self bounds during: [:canvas | canvas drawString: name at: self topLeft + (28 @ 6) font: self class titleStyle color: Color gray]! ----- Method: SkSheetMorph>>drawOn: (in category 'drawing') ----- drawOn: aCanvas super drawOn: aCanvas. self drawGrabAreaOn: aCanvas. dropZone ifNotNil: [aCanvas fillRectangle: (self cellAreaToScreen: (dropZone intersect: area)) fillStyle: (SkColorSet labelFor: model) borderStyle: self borderStyle]. self drawDependMap: aCanvas. self drawName: aCanvas. self drawBorder: aCanvas. self drawContents: aCanvas! ----- Method: SkSheetMorph>>editContents (in category 'accessing') ----- editContents self selection ifNil: [^'']. ^ model ifNil: [''] ifNotNil: [model textAt: self selection origin]! ----- Method: SkSheetMorph>>editContents: (in category 'accessing') ----- editContents: aText "Accept text" self selection ifNil: [^self]. model ifNotNil: [model textAt: self selection origin put: aText]. selectionMorph deleteEditor! ----- Method: SkSheetMorph>>fillStyle (in category 'visual properties') ----- fillStyle ^ SkColorSet baseFor: model rule! ----- Method: SkSheetMorph>>goto: (in category 'navigation') ----- goto: aSkObject | grid | self beep: 'rice'. grid _ aSkObject grid. self replace: grid. grid history: self. ^ grid! ----- Method: SkSheetMorph>>handlesKeyboard: (in category 'event handling') ----- handlesKeyboard: evt ^ true! ----- Method: SkSheetMorph>>handlesMouseDown: (in category 'event handling') ----- handlesMouseDown: evt ^ (self grabArea containsPoint: evt position) not! ----- Method: SkSheetMorph>>handlesMouseOver: (in category 'event handling') ----- handlesMouseOver: evt ^ true ! ----- Method: SkSheetMorph>>handlesMouseOverDragging: (in category 'event handling') ----- handlesMouseOverDragging: evt ^ true ! ----- Method: SkSheetMorph>>height: (in category 'accessing') ----- height: aNumber ^ self setExtentFromHalo: self width @ aNumber! ----- Method: SkSheetMorph>>history: (in category 'navigation') ----- history: aSkSheetMorph history ifNil: [history _ aSkSheetMorph]! ----- Method: SkSheetMorph>>initialize (in category 'initialization') ----- initialize super initialize. self showPageControls. selectionMorph _ SkGridSelectionMorph new holder: self. self area: (1 @ 1 extent: 4 @ 4). self borderStyle: (RaisedBorder color: Color black width: 1). self fillStyle: (SolidFillStyle color: (Color r: 1.0 g: 0.935 b: 0.839)). self cornerStyle: #rounded. self selection: nil. showFormula _ false! ----- Method: SkSheetMorph>>initializeToStandAlone (in category 'parts bin') ----- initializeToStandAlone super initializeToStandAlone. self model: SkSheet new attachProject. self area: (0 @ 0 extent: 3 @ 3)! ----- Method: SkSheetMorph>>isModelStepping (in category 'stepping and presenter') ----- isModelStepping ^ model isStepping! ----- Method: SkSheetMorph>>isMorphicModel (in category 'classification') ----- isMorphicModel ^true! ----- Method: SkSheetMorph>>keyStroke: (in category 'event handling') ----- keyStroke: evt selectionMorph keyStroke: evt! ----- Method: SkSheetMorph>>model (in category 'accessing') ----- model ^ model! ----- Method: SkSheetMorph>>model: (in category 'accessing') ----- model: anObject model ifNotNil: [model removeDependent: self]. anObject ifNotNil: [anObject addDependent: self]. model _ anObject. self update: #all. ! ----- Method: SkSheetMorph>>mouseDown: (in category 'event handling') ----- mouseDown: event self selectSelection: (self screenToCell: event position). event yellowButtonPressed ifTrue: [^ selectionMorph invokeMenu: event]. "For easy doublecilck to selection" event hand waitForClicksOrDrag: selectionMorph event: event. event hand mouseFocus: selectionMorph! ----- Method: SkSheetMorph>>mouseEnter: (in category 'event handling') ----- mouseEnter: evt | hand tile | hand _ evt hand. hand submorphs size = 1 ifFalse: [^ self]. tile _ hand firstSubmorph renderedMorph. (self wantsDroppedMorph: tile event: evt) ifFalse: [^ self]. self startStepping: #trackDropZones at: Time millisecondClockValue arguments: nil stepTime: 20! ----- Method: SkSheetMorph>>mouseEnterDragging: (in category 'event handling') ----- mouseEnterDragging: evt "Test button state elsewhere if at all" ^ self mouseEnter: evt! ----- Method: SkSheetMorph>>mouseLeave: (in category 'event handling') ----- mouseLeave: evt dropZone _ nil. self stopSteppingSelector: #trackDropZones! ----- Method: SkSheetMorph>>mouseLeaveDragging: (in category 'event handling') ----- mouseLeaveDragging: evt ^ self mouseLeave: evt! ----- Method: SkSheetMorph>>mouseUpTick:onItem: (in category 'event handling') ----- mouseUpTick: evt onItem: aMorph aMorph isTicking ifTrue: [model stopStepping. aMorph isTicking: false] ifFalse: [model startStepping. aMorph isTicking: true]! ----- Method: SkSheetMorph>>openLibrary (in category 'action') ----- openLibrary (SkObject root at: 'Library') grid openInHand! ----- Method: SkSheetMorph>>paste (in category 'action') ----- paste | pos selection isJustACell | selection _ self selection. isJustACell _ selection extent = (1 @ 1). pos _ selection origin. Clipboard clipboardText split: Character cr do: [:line | line split: Character tab do: [:field | (isJustACell or: [selection containsPoint: pos]) ifTrue: [model textAt: pos put: field]. pos _ pos + (1 @ 0)]. pos _ selection left @ (pos y + 1)]! ----- Method: SkSheetMorph>>previousPage (in category 'navigation') ----- previousPage self beep: 'rice'. ^ history ifNotNil: [self replace: history]! ----- Method: SkSheetMorph>>privateRemoveMorph: (in category 'private') ----- privateRemoveMorph: aMorph aMorph class = SkCardMorph ifTrue: [self beep: 'cork'. self model textAt: aMorph cellOrigin put: '']. super privateRemoveMorph: aMorph! ----- Method: SkSheetMorph>>replace: (in category 'navigation') ----- replace: aSkSheetMorph aSkSheetMorph area: self area. aSkSheetMorph position: self position. self delete. aSkSheetMorph openInWorld. ^ aSkSheetMorph! ----- Method: SkSheetMorph>>selectSelection: (in category 'action') ----- selectSelection: aPoint "Select at event position" aPoint ifNil: [^ self]. self selection: (aPoint extent: 1 @ 1). self changed! ----- Method: SkSheetMorph>>selection (in category 'accessing') ----- selection ^ selectionMorph area! ----- Method: SkSheetMorph>>selection: (in category 'accessing') ----- selection: aRectangle submorphs first == selectionMorph ifFalse: [self addMorphFront: selectionMorph]. selectionMorph area: aRectangle! ----- Method: SkSheetMorph>>selectionMorph (in category 'accessing') ----- selectionMorph ^ selectionMorph! ----- Method: SkSheetMorph>>setCellExtentFromHalo: (in category 'layout') ----- setCellExtentFromHalo: newExtent | eachExtent cellExtent | model ifNil: [^ self]. cellExtent _ model at: self cellExtentName ifAbsent: [model at: self cellExtentName put: (SkSheet new parent: model)]. eachExtent _ newExtent // self selection extent max: 10 @ 10. self selection left to: self selection right - 1 do: [:x | cellExtent at: x @ 1 put: eachExtent]. self selection top to: self selection bottom - 1 do: [:y | cellExtent at: 1 @ y put: eachExtent]. self areaChanged. self changed! ----- Method: SkSheetMorph>>setExtentFromHalo: (in category 'layout') ----- setExtentFromHalo: newExtent | card cardMorph direction size | super setExtentFromHalo: newExtent. direction := nil. area height = 1 ifTrue: [direction := #right. size := area width - 1] ifFalse: [area width = 1 ifTrue: [direction := #down. size := area height - 1]]. direction ifNotNil: [card := model new. card direction: direction. card size: size. cardMorph := SkCardMorph model: card. cardMorph position: self position. self owner addMorph: cardMorph. self halo ifNotNilDo: [:helo | helo setTarget: cardMorph]. self delete]! ----- Method: SkSheetMorph>>showFormula (in category 'accessing') ----- showFormula ^ showFormula! ----- Method: SkSheetMorph>>showPageControls (in category 'initialization') ----- showPageControls | panel prev up | panel _ Morph new extent: 80@20; color: Color transparent. panel on: #mouseDown send: #yourself to: self. panel addMorph: self tickMorph. prev _ (PolygonMorph new setVertices: {0 @ 7. 7 @ 0. 7 @ 14}) borderWidth: 1; borderColor: Color darkGray; color: Color transparent. prev on: #mouseDown send: #previousPage to: self. prev position: 24 @ 3. prev setBalloonText: 'View the previous sheet.' translated. panel addMorph: prev. up _ prev copy heading: 90. up on: #mouseDown send: #upPage to: self. up position: 36 @ 4. up setBalloonText: 'View the definision or the parent rule.' translated. panel addMorph: up. self addMorph: panel! ----- Method: SkSheetMorph>>spawn (in category 'action') ----- spawn model inspectAt: self selection topLeft! ----- Method: SkSheetMorph>>spawn: (in category 'action') ----- spawn: anObject self spawn! ----- Method: SkSheetMorph>>startStepping (in category 'stepping and presenter') ----- startStepping model ifNotNil: [model startStepping]. super startStepping. ! ----- Method: SkSheetMorph>>step (in category 'stepping and presenter') ----- step self changed! ----- Method: SkSheetMorph>>tickMorph (in category 'initialization') ----- tickMorph | tick | tick _ SkPluggableTickMorph new. tick position: self position + 1. tick on: self isTickingSel: #isModelStepping. tick on: #mouseUp send: #mouseUpTick:onItem: to: self. tick stepTime: 500. tick startStepping. tick setBalloonText: 'Press to toggle ticking state.' translated. ^ tick! ----- Method: SkSheetMorph>>toggleFormula (in category 'accessing') ----- toggleFormula showFormula _ showFormula not! ----- Method: SkSheetMorph>>trackDropZones (in category 'event handling') ----- trackDropZones | hand target | hand _ self primaryHand. ((self hasOwner: hand) not and: [hand submorphCount > 0]) ifTrue: [target _ hand submorphs first. dropZone _ (self screenToCell: target topLeft) extent: ((target respondsTo: #area) ifTrue: [target area extent] ifFalse: [1 @ 1]). (dropZone topLeft x < 1 or: [dropZone topLeft y < 1]) ifTrue: [dropZone _ nil]. self changed] ifFalse: [dropZone _ nil. self stopSteppingSelector: #trackDropZones]! ----- Method: SkSheetMorph>>tryToRenameTo: (in category 'accessing') ----- tryToRenameTo: aName ^ model ifNotNilDo: [:m | m name: aName]! ----- Method: SkSheetMorph>>upPage (in category 'navigation') ----- upPage self beep: 'rice'. ^ self goto: model up! ----- Method: SkSheetMorph>>update: (in category 'updating') ----- update: anObject anObject = #cardList ifTrue: [self updateCardList]. anObject = #all ifTrue: [self updateCardList]. self changed! ----- Method: SkSheetMorph>>updateCardList (in category 'updating') ----- updateCardList | cardList morph | cardList _ model cardList: self visibleArea. self removeAllMorphsIn: (self submorphs select: [:m | m class == SkCardMorph]). cardList do: [:cardInfo | morph _ SkCardMorph model: cardInfo value. morph holder: self. self addMorph: morph. morph cellOrigin: cardInfo key]. selectionMorph hide! ----- Method: SkSheetMorph>>veryDeepInner: (in category 'copying') ----- veryDeepInner: deepCopier "history is not copied" model _ model veryDeepCopyWith: deepCopier. selectionMorph _ (selectionMorph veryDeepCopyWith: deepCopier) holder: self. dropZone _ dropZone veryDeepCopyWith: deepCopier. showFormula _ showFormula veryDeepCopyWith: deepCopier. super veryDeepInner: deepCopier! ----- Method: SkSheetMorph>>wantsDroppedMorph:event: (in category 'drag and drop') ----- wantsDroppedMorph: aMorph event: anEvent ^ aMorph class = PhraseTileMorph or: [aMorph class = TileMorph or: [aMorph isKindOf: SkGridPartsMorph]]! ----- Method: SkSheetMorph>>width: (in category 'accessing') ----- width: aNumber ^ self setExtentFromHalo: aNumber @ self height! ----- Method: ScriptEditorMorph>>arrowTargets (in category '*skeleton-base-arrow') ----- arrowTargets ^ Array with: 'player' -> playerScripted! Compiler subclass: #SkCompiler instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Skeleton-Base'! ----- Method: SkCompiler class>>parserClass (in category 'accessing') ----- parserClass ^ SkParser! TickIndicatorMorph subclass: #SkPluggableTickMorph instanceVariableNames: 'model isTickingSel' classVariableNames: '' poolDictionaries: '' category: 'Skeleton-Base'! ----- Method: SkPluggableTickMorph>>isTicking (in category 'accessing') ----- isTicking ^model perform: isTickingSel. ! ----- Method: SkPluggableTickMorph>>on:isTickingSel: (in category 'accessing') ----- on: anObject isTickingSel: tickSel model _ anObject. isTickingSel _ tickSel. ! ----- Method: SkPluggableTickMorph>>runningColor (in category 'accessing') ----- runningColor ^ Color r: 0.767 g: 0.767 b: 1.0! ----- Method: SkPluggableTickMorph>>stepAt: (in category 'stepping and presenter') ----- stepAt: nowTick | delta | self isTicking ifTrue: [(lastTick isNil or: [nowTick < lastTick]) ifTrue: [lastTick _ nowTick]. delta _ nowTick - lastTick // stepTime. delta > 0 ifTrue: [self color: self runningColor. index _ index + delta. lastTick _ nowTick. self changed]] ifFalse: [self color: self stoppedColor]! ----- Method: SkPluggableTickMorph>>stoppedColor (in category 'accessing') ----- stoppedColor ^ Color r: 1.0 g: 0.774 b: 0.774! TestCase subclass: #SkBaseTest instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Skeleton-Base'! ----- Method: SkBaseTest>>testAsSkeletonText (in category 'text test') ----- testAsSkeletonText | morph | self assert: 1 asCellText = '1'. self assert: Color white asCellText = '=Color white'. morph _ Morph new name: 'AsSkeletonText'. self assert: morph assuredPlayer asCellText = '=References at: #AsSkeletonText'. References removeKey: #AsSkeletonText. ! TestCase subclass: #SkSheetTest instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Skeleton-Base-Sheet'! ----- Method: SkSheetTest>>testA1Name (in category 'sheet test') ----- testA1Name | s | s _ SkSheet new. s textAt: 100@100 put: 'test'. s textAt: 1@1 put: '=CV100'. s resolve. self assert: (s at: 1@1) = 'test'. ! ----- Method: SkSheetTest>>testAddCardIntoProxy (in category 'rule and case') ----- testAddCardIntoProxy | proxy base | base _ SkSheet new. proxy _ SkProxy newForTest. proxy parent: base uniqueName: 'Case'. proxy textAt: 2@2 put: '=Case direction: #right size: 1'. self assert: (proxy at: 2@2) rule = proxy rule. ! ----- Method: SkSheetTest>>testAdopt (in category 'card tests') ----- testAdopt | s1 c1 s2 c2 | (SkProject current) removeAt: 'Sheet'; removeAt: 'Card'. s1 := SkSheet new attachProject name: 'Sheet'. c1 := SkProxy newForTest attachProject name: 'Card'. s1 adopt: c1. self assert: (s1 findName: 'Card') = c1 rule. s2 := SkSheet new. c2 := SkProxy newForTest parent: s2 uniqueName: 'Card'. s2 adopt: c1. self assert: c2 parent = s2. self assert: (s2 findName: 'Card1') = c1. self assert: c2 ruleName = 'Card'! ----- Method: SkSheetTest>>testAtPut (in category 'sheet test') ----- testAtPut | s | s _ SkSheet new. s textAt: 1@1 put: 1. self assert: (s cellAt: 1@1) contents == 1. s textAt: 1@1 put: '1'. self assert: (s cellAt: 1@1) contents == 1. s textAt: 2@1 put: 'test'. self assert: (s cellAt: 2@1) contents = 'test'. s textAt: 3@1 put: 'test' asText. self assert: (s cellAt: 3@1) contents = 'test'. self assert: (s cellAt: 3@1) contents class = String. s textAt: 1@2 put: '=A1*2'. s resolve. self assert: (s cellAt: 1@2) contents == 2. ! ----- Method: SkSheetTest>>testBehavior (in category 'text test') ----- testBehavior | s | s _ SkSimple contents: [ :h | h addRule: (1@1 rule: {2@1. 3@1} do: [ :a :b | a + b]). h at: 2@1 put: 2. h at: 3@1 put: 3. h resolve. ]. " s grid openInWorld." ! ----- Method: SkSheetTest>>testBidirectional (in category 'planning test') ----- testBidirectional | s | s _ SkSheet new. s textAt: 1 @ 1 put: '=B1'. s textAt: 2 @ 1 put: '=A1'. s at: 1 @ 1 put: 'first'. s resolve. self assert: (s at: 2 @ 1) = 'first'. s at: 2 @ 1 put: 'second'. s resolve. self assert: (s at: 1 @ 1) = 'second'. ! ----- Method: SkSheetTest>>testCardBidirectional (in category 'planning test') ----- testCardBidirectional | s c | s := SkSheet new. c := SkProxy newForTest parent: s uniqueName: 'Inc'. c textAt: 1 @ 1 put: '=B1+1'. s textAt: 1 @ 1 put: '=Inc direction: #right size: 2'. s textAt: 1 @ 2 put: '=Inc direction: #right size: 2'. s textAt: 3 @ 2 put: '=B1'. s at: 3 @ 1 put: 10. s resolve. self assert: (s at: 2 @ 2) = 12. s at: 3 @ 1 put: 100. s resolve. self assert: (s at: 2 @ 2) = 102. s textAt: 3 @ 1 put: '=B2'. s textAt: 3 @ 2 put: '10'. self assert: (s dependMap at: 3 @ 2) = { 1 @ 1. 2 @ 1. 3 @ 1. 1 @ 2. 2 @ 2} asSet. s resolve. self assert: (s at: 2 @ 1) = 12. s at: 3 @ 2 put: 100. s resolve. self assert: (s at: 2 @ 1) = 102! ----- Method: SkSheetTest>>testCardCode (in category 'card tests') ----- testCardCode | c | SkProject current removeAt: 'Test'. c := SkProxy newForTest attachProject. c size: 3. c direction: #left. c name: 'Test'. self assert: c codeString = 'Test direction: #left size: 3'! ----- Method: SkSheetTest>>testCardHasContents (in category 'card tests') ----- testCardHasContents self flag: #abeyance. [ | proxy sheet | proxy _ SkProxy newForTest size: 1. sheet _ SkSheet new. proxy at: 1@1 put: 'test'. sheet caseAt: 1@1 put: proxy. self assert: (sheet at: 2@1) = 'test'. ]! ----- Method: SkSheetTest>>testCardInCardMorphCopy (in category 'copy test') ----- testCardInCardMorphCopy | old new card sample | SkProject current removeAt: 'Test'. card := SkProxy newForTest attachProject name: 'Test'. card size: 3. old := SkCardMorph model: card. sample := 'test'. card at: 1 @ 1 put: sample. new := old veryDeepCopy. self assert: old model ~~ new model. self assert: old model parent == new model parent. [ self flag: #TODO. "I don't know sure if the proxy should copy old contents". self assert: (new model at: 1 @ 1) = 'test'. ]. self assert: ((new model at: 1 @ 1) == sample) not. self assert: new model ruleName notNil! ----- Method: SkSheetTest>>testCardInSheetMorphCopy (in category 'copy test') ----- testCardInSheetMorphCopy | old new card sample | SkProject current removeAt: 'Test'. card := SkProxy newForTest attachProject name: 'Test'. card size: 3. old := SkSheetMorph model: card. sample := 'test'. card at: 1 @ 1 put: sample. new := old veryDeepCopy. self assert: old model ~~ new model. self assert: old model parent == new model parent. self assert: (new model at: 1 @ 1) = 'test'. self assert: ((new model at: 1 @ 1) == sample) not. self assert: new model ruleName notNil! ----- Method: SkSheetTest>>testCardInThenEdit (in category 'rule and case') ----- testCardInThenEdit | sheet card | SkProject current removeAt: 'Sheet'; removeAt: 'Card'. sheet _ SkSheet new name: 'Sheet'. card _ SkSheet new name: 'Card'. sheet textAt: 1@1 put: '=Card direction: #right size: 2'. " sheet explore. (sheet at: 1@1) explore." card textAt: 2@1 put: '=A1'. sheet textAt: 2@1 put: 'test'. sheet resolve. self assert: (sheet at: 3@1) = 'test'. ! ----- Method: SkSheetTest>>testCardMorph (in category 'card tests') ----- testCardMorph "It has not assert, just drawing test for avoid error." | s m f | SkProject current removeAt: 'Test'. s _ SkSheet new attachProject name: 'Test'. m _ SkCardMorph model: s. s at: 1 @ 1 put: 1. s at: 2 @ 1 put: 2. s at: 3 @ 1 put: 3. m area: (2 @ 2 extent: 3 @ 1). m areaChanged. f _ FormCanvas extent: m extent. m drawOn: f! ----- Method: SkSheetTest>>testCardPut (in category 'card tests') ----- testCardPut | sheet card1 card2 | SkProject current removeAt: 'Sheet'. sheet := SkSheet new attachProject name: 'Sheet'. card1 := SkProxy newFrom: sheet. card1 size: 1. card1 textAt: 1 @ 1 put: 'test1'. card1 textAt: 2 @ 1 put: 'test2'. self assert: (card1 at: 1 @ 1) = 'test1'. card2 := SkProxy newFrom: sheet. self assert: (card2 at: 1 @ 1) = ''. self assert: (card2 at: 2 @ 1) = ''. card1 textAt: 1 @ 1 put: '=100'. self assert: (card2 textAt: 1 @ 1) = '=100'! ----- Method: SkSheetTest>>testCardResolve (in category 'card tests') ----- testCardResolve | sheet card | (SkProject current) removeAt: 'Sheet'; removeAt: 'Card'. sheet := SkSheet new attachProject name: 'Sheet'. card := SkProxy newForTest attachProject name: 'Card'. card textAt: 1 @ 1 put: '=B1+C1'. sheet textAt: 1 @ 1 put: '=Card direction: #right size: 3'. sheet textAt: 3 @ 1 put: '1'. sheet textAt: 4 @ 1 put: '2'. sheet resolve. self assert: (sheet at: 2 @ 1) = 3. self assert: ((sheet at: 1 @ 1) at: 2 @ 1) = 1. sheet textAt: 1 @ 5 put: '=Card direction: #up size: 3'. sheet textAt: 1 @ 2 put: '1'. sheet textAt: 1 @ 3 put: '2'. sheet resolve. self assert: (sheet at: 1 @ 4) = 3 ! ----- Method: SkSheetTest>>testCaseInCase (in category 'rule and case') ----- testCaseInCase | s1 s2 s3 | SkProject current removeAt: 'Sheet1'; removeAt: 'Sheet2'. s1 _ SkSheet new attachProject name: 'Sheet1'. s2 _ SkSheet new attachProject name: 'Sheet2'. s1 textAt: 1@1 put: '=B1'. s2 textAt: 1@2 put: '=Sheet1 direction: #right size: 2'. s3 _ s2 new. s3 textAt: 3@2 put: '2'. s3 resolve. s2 textAt: 1@2 put: ''. self assert: (s2 at: 1@2) = ''. self assert: (s3 at: 1@2) = ''. ! ----- Method: SkSheetTest>>testCaseInCaseDelete (in category 'rule and case') ----- testCaseInCaseDelete | s1 s2 s3 | SkProject current removeAt: 'Sheet1'; removeAt: 'Sheet2'. s1 _ SkSheet new attachProject name: 'Sheet1'. s2 _ SkSheet new attachProject name: 'Sheet2'. s1 textAt: 1@1 put: '=B1'. s2 textAt: 1@2 put: '=Sheet1 direction: #right size: 2'. s2 textAt: 3@2 put: '1'. s3 _ s2 new. s3 textAt: 3@2 put: '2'. s2 resolve. s3 resolve. self assert: (s2 at: 2@2) = 1. self assert: (s3 at: 2@2) = 2. ! ----- Method: SkSheetTest>>testCellOrigin (in category 'card tests') ----- testCellOrigin | c | c := SkCardMorph model: SkProxy newForTest. c size: 2; direction: #right. c cellOrigin: 5 @ 5. self assert: c area origin = (5 @ 5). c size: 2; direction: #left. c cellOrigin: 5 @ 5. self assert: c area origin = (3 @ 5). c size: 2; direction: #up. c cellOrigin: 5 @ 5. self assert: c area origin = (5 @ 3). c size: 2; direction: #down. c cellOrigin: 5 @ 5. self assert: c area origin = (5 @ 5)! ----- Method: SkSheetTest>>testCellToScreenRect (in category 'gui tests') ----- testCellToScreenRect | grid | grid _ SkSheetMorph model: SkSheet new. self assert: (grid cellExtentAt: 1 @ 1) = (80 @ 20). grid area: (0 @ 0 extent: 2 @ 2). grid position: 20 @ 10. self assert: (grid cellToScreenRect: 0 @ 0) = (21 @ 11 corner: 101 @ 31). self assert: (grid cellToScreenRect: 1 @ 1) = (102 @ 32 corner: 182 @ 52)! ----- Method: SkSheetTest>>testCellToScreenRect2 (in category 'gui tests') ----- testCellToScreenRect2 | conv grid | grid _ SkSheetMorph new. grid area: (0 @ 0 extent: 2 @ 2). conv _ SkCellScreenConverter grid: grid border: 1. self assert: (conv cellToScreenRect: 0 @ 0 topLeft: 20@10) = (21 @ 11 corner: 101 @ 31). self assert: (conv cellToScreenRect: 1 @ 1 topLeft: 20@10) = (102 @ 32 corner: 182 @ 52). self assert: (conv cellToScreenRect: 100 @ 100 topLeft: 20@10) = (((20@10) + 1 + (((80@20) + 1) * 100)) extent: 80@20). self assert: (conv cellToScreenRect: -1 @ -1 topLeft: 20@10) = (((20@10) + 1 + (((80@20) + 1) * -1)) extent: 80@20). self assert: (conv cellToScreenRect: 10 @ -1 topLeft: 20@10) = ((20@10) + 1 + (((800@-20) + (10@-1))) extent: 80@20) ! ----- Method: SkSheetTest>>testCopyFromFlap (in category 'copy test') ----- testCopyFromFlap | base sheet new | SkProject current removeAt: 'Original'. base _ SkSheet new. sheet _ SkSheetMorph model: (SkSheet new parent: base uniqueName: 'Original'). new _ sheet veryDeepCopy. self assert: new model parent = SkProject current. self assert: new model ruleName = 'Original'. ! ----- Method: SkSheetTest>>testCopyInCardMorph (in category 'copy test') ----- testCopyInCardMorph | old new | old _ SkCardMorph model: SkSheet new. new _ old veryDeepCopy. self assert: old model ~= new model. self assert: old model rule == new model rule. old _ SkCardMorph model: SkProxy newForTest. new _ old veryDeepCopy. self assert: old model ~= new model. self assert: old model rule == new model rule. ! ----- Method: SkSheetTest>>testCopyInSheetMorph (in category 'copy test') ----- testCopyInSheetMorph | old new | old _ SkSheetMorph model: SkSheet new. new _ old veryDeepCopy. self assert: old model ~= new model. old _ SkSheetMorph new model: SkProxy newForTest. new _ old veryDeepCopy. self assert: old model rule ~= new model rule. ! ----- Method: SkSheetTest>>testCopyPaste (in category 'sheet test') ----- testCopyPaste | s grid | s _ SkSheet new. s textAt:1@1 put: 1. s textAt:2@1 put: 'string'. s textAt:1@2 put: 'text' asText. s textAt:2@2 put: '=A1'. s textAt:1@3 put: 'remain'. grid _ SkSheetMorph new model: s. grid selection: (1@1 extent: 2@2). grid copySelection. self assert: Clipboard clipboardText = '1 string text =A1 ' asText. grid selection: (2@2 extent: 1@1). grid paste. grid selection: (1@1 extent: 3@3). grid copySelection. self assert: Clipboard clipboardText = '1 string text 1 string remain text =A1 ' asText. Clipboard clipboardText: 'x x x x x x x x x x x x x x x x ' asText. grid selection: (1@1 extent: 2@2). grid paste. grid selection: (1@1 extent: 4@4). grid copySelection. self assert: Clipboard clipboardText = 'x x x x string remain text =A1 ' asText. ! ----- Method: SkSheetTest>>testCopySkSheet (in category 'copy test') ----- testCopySkSheet | sheet new | SkProject current removeAt: 'Test'. sheet _ SkSheetMorph model: (SkProxy newForTest attachProject name: 'Test'). sheet history: (SkSheetMorph new model: SkProject current). new _ sheet duplicate. new! ----- Method: SkSheetTest>>testCopyWithCard (in category 'copy test') ----- testCopyWithCard | old new | old _ SkSheetMorph model: SkSheet new. old model textAt: 1@1 put: '=Sum direction: #right size: 3'. old model at: 3@1 put: 1. old model at: 4@1 put: 2. new _ old veryDeepCopy. self assert: ((old model at: 1@1) at: 2@1) = ((new model at: 1@1) at: 2@1). self assert: new submorphs first model = (new model at: 1@1). ! ----- Method: SkSheetTest>>testCreateOffset (in category 'gui tests') ----- testCreateOffset | conv | conv _ SkCellScreenConverter grid: SkSheetMorph new border: 1. self assert: (conv createOffset: 0@0) = (0@0). self assert: (conv createOffset: 1@1) = (81@21). self assert: (conv createOffset: -1@-1) = (-81@-21)! ----- Method: SkSheetTest>>testCutAndPasteWithGUI (in category 'copy test') ----- testCutAndPasteWithGUI | sheet morph | SkProject current removeAt: 'Sheet'. sheet := SkSheet new attachProject name: 'Sheet'. morph := SkSheetMorph model: sheet. sheet textAt: 1 @ 1 put: '=Sum'. self assert: (morph submorphs select: [:m | m class = SkCardMorph]) size = 1. morph selection: (1 @ 1 extent: 1 @ 1). morph cut. self assert: (morph submorphs select: [:m | m class = SkCardMorph]) isEmpty! ----- Method: SkSheetTest>>testDeepCopy (in category 'copy test') ----- testDeepCopy |old new sheet sample | SkProject current removeAt: 'Test'. sheet _ SkSheet new attachProject name: 'Test'. old _ SkSheetMorph model: sheet. sample _ 'test'. sheet at: 1@1 put: sample. new _ old veryDeepCopy. self assert: old model ~~ new model. self assert: old model parent == new model parent. self assert: ((new model at: 1@1) = 'test'). self assert: (((new model at: 1@1) == sample) not). self assert: new model ruleName notNil! ----- Method: SkSheetTest>>testDependents (in category 'planning test') ----- testDependents | sheet1 dep | sheet1 _ SkSheet new. sheet1 textAt: 1 @ 1 put: '0'. sheet1 textAt: 2 @ 1 put: '=A1 + 1'. sheet1 textAt: 3 @ 1 put: '=B1 + 1'. sheet1 textAt: 1 @ 2 put: '=B2 + C2'. sheet1 textAt: 2 @ 2 put: '=C2 + 1'. sheet1 textAt: 3 @ 2 put: '=A1 + 1'. dep _ sheet1 dependMap. self assert: ((dep at: 1@1) includes: 2@1). self assert: ((dep at: 1@1) includes: 3@1). self assert: ((dep at: 1@1) includes: 1@2). self assert: ((dep at: 1@1) includes: 2@2). self assert: ((dep at: 1@1) includes: 3@2). self assert: ((dep at: 2@1) includes: 3@1). self assert: ((dep at: 3@1 ifAbsent: [nil]) isNil). self assert: ((dep at: 1@2 ifAbsent: [nil]) isNil). self assert: ((dep at: 2@2) includes: 1@2). self assert: ((dep at: 3@2) includes: 1@2). self assert: ((dep at: 3@2) includes: 2@2). ! ----- Method: SkSheetTest>>testDictionary (in category 'structure test') ----- testDictionary | d | d _ SkDictionary new. d at: 'orenge' put: 'mikan'. d at: 'apple' put: 'ringo'. d at: 'banana' put: 'banana'. self assert: (d at: 1 @ 2) = 'apple'. self assert: (d at: 2 @ 4) = 'mikan'! ----- Method: SkSheetTest>>testDictionaryCard (in category 'structure test') ----- testDictionaryCard | d | d := SkProxy newFrom: SkDictionary new. d at: 'orenge' put: 'mikan'. d at: 'apple' put: 'ringo'. d at: 'banana' put: 'banana'. self assert: (d at: 1 @ 2) = 'apple'. self assert: (d at: 2 @ 4) = 'mikan' ! ----- Method: SkSheetTest>>testDictionaryCell (in category 'dictionary test') ----- testDictionaryCell |cell dict | dict _ SkDictionary new. cell _ SkDictionaryCell newFor: dict key: 'hello'. cell contents: 'world'. self assert: (dict at: 'hello') = 'world'! ----- Method: SkSheetTest>>testDictionaryNewName (in category 'dictionary test') ----- testDictionaryNewName | dict | dict _ SkDictionary new name: 'test'. self assert: (dict at: 'test') = ''. ! ----- Method: SkSheetTest>>testDirection (in category 'card tests') ----- testDirection | c | c := SkCardMorph model: SkProxy newForTest. c direction: #right. c area: (4 @ 5 extent: 4 @ 1). self assert: c size = 3. c direction: #down. self assert: c area = (4 @ 5 corner: 5 @ 9). c direction: #left. self assert: c area = (1 @ 5 corner: 5 @ 6). c direction: #up. self assert: c area = (4 @ 2 corner: 5 @ 6). c size: 2. self assert: c area = (4 @ 3 corner: 5 @ 6). c direction: #right. self assert: c area = (4 @ 5 corner: 7 @ 6) ! ----- Method: SkSheetTest>>testFindName (in category 'structure test') ----- testFindName | s c | s := SkSheet new attachProject. self assert: (s findName: 'Projects') = s parent parent. self assert: (s findName: 'Root') = s parent parent parent. c := SkProxy newFrom: s. self assert: (c findName: 'Projects') = s parent parent ! ----- Method: SkSheetTest>>testFormula (in category 'cell test') ----- testFormula | cell | cell _ SkValueCell new. cell formula: '=A1+B2'. self assert: cell block sourceCode = 'DoIt ^ [:t1 :t2 | (t1 at: 1@1) + (t1 at: 2@2)]' ! ----- Method: SkSheetTest>>testFunction (in category 'cell test') ----- testFunction | s | s _ SkSheet new. s textAt: 1@1 put: 1. s textAt: 2@1 put: '=A1 sin'. s resolve. self assert: ((s cellAt: 2@1) contents closeTo: 0.8414). s textAt: 1@1 put: '1' asText. s resolve. self assert: ((s cellAt: 2@1) contents closeTo: 0.8414). ! ----- Method: SkSheetTest>>testGlobalToLocal (in category 'card tests') ----- testGlobalToLocal | m | m := SkCardMorph model: SkProxy newForTest. m area: (2 @ 3 corner: 6 @ 4). m direction: #right. self assert: (m globalToLocal: 3 @ 3) = (1 @ 1). self assert: (m globalToLocal: 5 @ 3) = (3 @ 1). m direction: #left. self assert: (m globalToLocal: 1 @ 3) = (1 @ 1). self assert: (m globalToLocal: -1 @ 3) = (3 @ 1). m direction: #down. m area: (2 @ 3 corner: 3 @ 7). self assert: (m globalToLocal: 2 @ 4) = (1 @ 1). self assert: (m globalToLocal: 2 @ 6) = (3 @ 1). m direction: #up. self assert: (m globalToLocal: 2 @ 2) = (1 @ 1). self assert: (m globalToLocal: 2 @ 0) = (3 @ 1) ! ----- Method: SkSheetTest>>testGoto (in category 'navigation test') ----- testGoto | sheet goal result | SkProject current removeAt: 'Test'. sheet _ SkSheetMorph model: (SkSheet new attachProject name: 'Test'). result _ sheet goto: (goal _ SkSheet new). self assert: goal = result model. result delete. result _ sheet goto: (goal _ SkSheet). self assert: goal = result model class. result delete. ! ----- Method: SkSheetTest>>testIncludesPosition (in category 'dictionary test') ----- testIncludesPosition | dict | dict _ SkDictionary new. dict at: 'hello' put: 'world'. self assert: (dict includesPosition: 'hello') not. self assert: (dict includesPosition: 1@1) not. self assert: (dict includesPosition: 1@2) . self assert: (dict includesPosition: 2@2) . self assert: (dict includesPosition: 1@3) not. self assert: (dict includesPosition: 3@2) not. ! ----- Method: SkSheetTest>>testLibraryName (in category 'card tests') ----- testLibraryName | sheet | SkProject current removeAt: 'Sheet'. SkProject current removeAt: 'sum'. sheet _ SkSheet new attachProject name: 'Sheet'. sheet textAt: 1 @ 1 put: '=Sum direction: #right size: 3'. sheet textAt: 3 @ 1 put: '1'. sheet textAt: 4 @ 1 put: '2'. sheet resolve. self assert: (sheet at: 2 @ 1) = 3. self assert: (SkProject current at: 'Sum') = ''. self assert: (sheet findName: 'Sum') parent = (sheet findName: 'Library') ! ----- Method: SkSheetTest>>testName (in category 'structure test') ----- testName | sheet card | SkProject current removeAt: 'Test'. sheet := SkSheet new attachProject name: 'Test'. card := SkProxy newFrom: sheet. self assert: card ruleName = 'Test'. sheet beAlone. card := SkProxy newFrom: SkSheet new. card attachProject name: 'Test'. self assert: card ruleName = 'Test'. card beAlone ! ----- Method: SkSheetTest>>testNameOnCard (in category 'structure test') ----- testNameOnCard | card sheet | card := SkProxy newForTest. self assert: (card findName: 'cellExtent') isNil. self assert: (card at: 'cellExtent') = ''. sheet := card at: 'cellExtent' put: (SkSheet new parent: sheet). self assert: (card at: 'cellExtent') == sheet ! ----- Method: SkSheetTest>>testNil (in category 'other tests') ----- testNil | sheet | sheet _ SkSheet new. self assert: (sheet at: 1@1) = ''. self assert: (sheet at: 1@1 ifAbsent: ['ABSENT']) = 'ABSENT'.! ----- Method: SkSheetTest>>testNullCell (in category 'sheet test') ----- testNullCell | s | s _ SkSheet new. self assert: (s cellAt: 1 @ 1) value = ''. s textAt: 2 @ 1 put: 'test'. s textAt: 2 @ 1 put: ''. self assert: (s cellAt: 2 @ 1) class = SkNullCell. self assert: (s cellAt: 2 @ 1) value = ''! ----- Method: SkSheetTest>>testPlan (in category 'planning test') ----- testPlan | sheet1 | sheet1 _ SkSheet new. sheet1 textAt: 1@1 put: '0'. sheet1 textAt: 2@1 put: '=A1 + 1'. sheet1 textAt: 3@1 put: '=B1 + 1'. sheet1 textAt: 1@2 put: '=B2 + C2'. sheet1 textAt: 2@2 put: '=C2 + 1'. sheet1 textAt: 3@2 put: '=A1 + 1'. self assert: (sheet1 collectTargets = {2@1. 3@1. 1@2. 2@2. 3@2}). self assert: sheet1 collectDependents = {{2@1. 1@1}. {3@1. 2@1}. {1@2. 2@2. 3@2}. {2@2. 3@2}. {3@2. 1@1}}. self assert: (sheet1 collectTrees = { {3@1. {2@1. 1@1}}. {1@2. {2@2. 3@2}. {3@2. 1@1}}}). self assert: sheet1 collectOrder asArray = {1@1. 2@1. 3@1. 3@2. 2@2. 1@1. 3@2. 1@2.}. sheet1 resolve. self assert: (sheet1 at: 1@2) = 3. self assert: (sheet1 plan collect: [:each | each key]) = {2@1. 3@1. 3@2. 2@2. 1@2}. ! ----- Method: SkSheetTest>>testPlanWithCard (in category 'planning test') ----- testPlanWithCard | sheet card | sheet := SkSheet new. card := SkProxy newForTest parent: sheet uniqueName: 'Card'. card textAt: 1 @ 1 put: '=B1'. sheet textAt: 1 @ 1 put: '=Card direction: #right size: 2'. self assert: sheet cardPositions asArray = { 1 @ 1}. [self assert: sheet collectTargets = { 1 @ 1}. self assert: sheet collectDependents = { { 1 @ 1. 2 @ 1. 3 @ 1}. { 2 @ 1. 3 @ 1}}] ! ----- Method: SkSheetTest>>testPointForHolder (in category 'card tests') ----- testPointForHolder | proxy | proxy _ SkProxy newForTest. proxy direction: #right. self assert: (proxy pointForHolder: 10 @ 10 at: 1 @ 1) = (11 @ 10). proxy direction: #down. self assert: (proxy pointForHolder: 10 @ 10 at: 1 @ 1) = (10 @ 11). proxy direction: #left. self assert: (proxy pointForHolder: 10 @ 10 at: 1 @ 1) = (9 @ 10). proxy direction: #up. self assert: (proxy pointForHolder: 10 @ 10 at: 1 @ 1) = (10 @ 9) ! ----- Method: SkSheetTest>>testPrePrecess (in category 'cell test') ----- testPrePrecess "ABSOLUTE" [ | cell | cell _ SkValueCell new. self assert: (cell preProcess: '=A1+1') = '(holder at: 1@1)+1'. self assert: (cell preProcess: '=A1+B2') = '(holder at: 1@1)+(holder at: 2@2)' ]! ----- Method: SkSheetTest>>testProxyRererenceAt (in category 'card tests') ----- testProxyRererenceAt | proxy | proxy _ SkProxy newForTest. proxy size: 3. proxy direction: #down. self assert: (proxy referenceAt: 10@10) = {10@11. 10@12. 10@13}. ! ----- Method: SkSheetTest>>testReference (in category 'planning test') ----- testReference | sheet1 sheet2 cell | sheet1 _ SkSheet new. sheet1 textAt: 1@1 put: '=B1 + C1'. sheet1 textAt: 2@1 put: '=C1'. cell _ sheet1 cellAt: 1@1. self assert: (cell referenceAt: 1@1) = {2@1. 3@1} asSet. sheet2 _ SkSheet new. sheet1 parent: sheet2 uniqueName: 'Sheet1'. sheet2 textAt: 1@1 put: '=Sheet1 direction: #right size: 3'. cell _ sheet2 cellAt: 1@1. self assert: (cell referenceAt: 1@1) = {2@1. 3@1. 4@1} asSet. ! ----- Method: SkSheetTest>>testRotationCard (in category 'gui tests') ----- testRotationCard | sheet card oldCard | SkProject current removeAt: 'Card'. sheet := SkSheetMorph model: SkSheet new attachProject. sheet area: (0 @ 0 extent: 5 @ 5). sheet model textAt: 1 @ 2 put: 'test'. SkProxy newForTest attachProject name: 'Card'. sheet model textAt: 2 @ 2 put: '=Card direction: #right size: 1'. oldCard := card := sheet submorphs detect: [:m | m class = SkCardMorph]. card rotationDegrees: 90. self assert: (sheet model textAt: 2 @ 2) = '=Card direction: #down size: 1'. card endHaloInteraction. self assert: oldCard owner isNil. card := sheet submorphs detect: [:m | m class = SkCardMorph]. card rotationDegrees: 180. self assert: (sheet model textAt: 2 @ 2) = '=Card direction: #left size: 1'. card := sheet submorphs detect: [:m | m class = SkCardMorph]. card rotationDegrees: 270. self assert: (sheet model textAt: 2 @ 2) = '=Card direction: #up size: 1'! ----- Method: SkSheetTest>>testRuleAsCell (in category 'sheet test') ----- testRuleAsCell | s1 s2 | SkProject current removeAt: 'Test1'. s1 _ SkSheet new attachProject name: 'Test1'. s1 textAt: 1 @ 1 put: '=B1'. s1 textAt: 2 @ 1 put: '=A1'. s1 at: 1 @ 1 put: 'test'. s1 resolve. self assert: (s1 at: 2 @ 1) = 'test'. s2 _ SkSheet new attachProject. s2 textAt: 1 @ 1 put: '=Test1 direction: #right size: 2'. s2 textAt: 1 @ 2 put: '=Test1 direction: #right size: 2'. s2 textAt: 2 @ 1 put: 'source1'. s2 textAt: 2 @ 2 put: 'source2'. s2 resolve. self assert: (s2 at: 3 @ 1) = 'source1'. self assert: (s2 at: 3 @ 2) = 'source2'! ----- Method: SkSheetTest>>testScreenToCell (in category 'gui tests') ----- testScreenToCell | grid | grid _ SkSheetMorph model: SkSheet new. grid area: (0 @ 0 extent: 2 @ 2). grid position: 20 @ 10. self assert: (grid screenToCell: 101 @ 31) = (0 @ 0). self assert: (grid screenToCell: 102 @ 32) = (1 @ 1)! ----- Method: SkSheetTest>>testScreenToCell2 (in category 'gui tests') ----- testScreenToCell2 | conv grid | grid _ SkSheetMorph new. grid area: (0 @ 0 extent: 2 @ 2). conv _ SkCellScreenConverter grid: grid border: 1. self assert: (conv screenToCell: 101 @ 31 topLeft: 20@10) = (0 @ 0). self assert: (conv screenToCell: 102 @ 32 topLeft: 20@10) = (1 @ 1). self assert: (conv screenToCell: 19 @9 topLeft: 20@10) = (-1 @ -1)! ----- Method: SkSheetTest>>testSheetInCardMorphCopy (in category 'copy test') ----- testSheetInCardMorphCopy |old new card sample | "SkSheet should be copied in SkCardMorph" SkProject current removeAt: 'Test'. card _ SkSheet new attachProject name: 'Test'. card size: 3. old _ SkCardMorph model: card. sample _ 'test'. card at: 1@1 put: sample. new _ old veryDeepCopy. self assert: old model ~= new model. self assert: old model parent == new model parent. self assert: ((new model at: 1@1) = 'test'). self assert: new model ruleName notNil! ----- Method: SkSheetTest>>testSheetPlus (in category 'parameter test') ----- testSheetPlus "NOT YET" | base s1 s2 | SkProject current removeAt: 'Base'; removeAt: 'St1'; removeAt: 'St2'. base _ SkSheet new attachProject name: 'Base'. s1 _ SkSheet new attachProject name: 'St1'. s2 _ SkSheet new attachProject name: 'St1'. base textAt: 1@1 put: '=B1+C1'. base textAt: 2@1 put: '=number'. base textAt: 3@1 put: '=number'. s1. s2.! ----- Method: SkSheetTest>>testSimple (in category 'text test') ----- testSimple | s | s _ SkSimple contents: [ :h | h at: 1@1 put: [ (h at: 2@1) + (h at: 3@1)]. h at: 2@1 put: 2. h at: 3@1 put: 3]. " s grid openInWorld." ! ----- Method: SkSheetTest>>testSkGridPartHolder (in category 'copy test') ----- testSkGridPartHolder |card new| card _ SkCardMorph model: (SkProxy newForTest). new _ card veryDeepCopy. self assert: new holder = card holder! ----- Method: SkSheetTest>>testSkProxy (in category 'copy test') ----- testSkProxy |card new| SkProject current removeAt: 'Sheet'; removeAt: 'Sheet1'. card _ SkCardMorph model: (SkProxy newForTest name: 'Sheet'). card model textAt: 1@1 put: '=B1'. new _ card veryDeepCopy. self assert: new model rule = card model rule. self assert: (SkProject current at: 'Sheet1' ifAbsent: [nil]) = nil.! ----- Method: SkSheetTest>>testSlotName (in category 'cell test') ----- testSlotName | cell morph | cell _ SkValueCell new. morph _ EllipseMorph new. cell on: morph assuredPlayer getter: #getX setter: #setX:. Project current naturalLanguage in: [:currentLanguage | [Project current setNaturalLanguageTo: #English. self assert: cell slotName = 'Ellipse''s x'] ensure: [Project current setNaturalLanguageTo: currentLanguage]]! ----- Method: SkSheetTest>>testSplitDo (in category 'cell test') ----- testSplitDo self assert: (Array streamContents: [:s | 'hi,hello,thanks' split: $, do: [:each | s nextPut: each]]) contents = #('hi' 'hello' 'thanks' ). self assert: (Array streamContents: [:s | 'hi,hello,thanks,' split: $, do: [:each | s nextPut: each]]) contents = #('hi' 'hello' 'thanks' ). self assert: (Array streamContents: [:s | 'hi,hello,thanks,,' split: $, do: [:each | s nextPut: each]]) contents = #('hi' 'hello' 'thanks' '')! ----- Method: SkSheetTest>>testStructureOnDictionary (in category 'structure test') ----- testStructureOnDictionary | s1 s2 s3 s4 | SkProject current removeAt: 'Sheet'. s1 := SkDictionary new. s2 := SkNamed new. s3 := SkDictionary new. s4 := SkNamed new. s2 parent: s1; name: 'TestName'. self assert: s2 ruleName = 'TestName'. s3 parent: s1; name: 'TestName'. self assert: s3 ruleName = 'TestName1'. s3 beAlone. self assert: s4 ruleName isNil. s4 attachProject. self assert: s4 ruleName = 'Sheet'. ! ----- Method: SkSheetTest>>testStructureOnSheet (in category 'structure test') ----- testStructureOnSheet | s1 s2 s3 s4 | s1 := SkSheet new. s2 := SkNamed new. s3 := SkSheet new. s4 := SkNamed new. s2 parent: s1; name: 'TestName'. self assert: s2 ruleName = 'TestName'. s4 parent: s3 uniqueName: nil. self assert: s4 ruleName = 'Sheet'. s4 parent: s1; name: 'TestName'. self assert: s4 ruleName = 'TestName1'. s4 beAlone. self assert: s4 ruleName isNil! ----- Method: SkSheetTest>>testText (in category 'text test') ----- testText | sheet | sheet _ SkSheet contents: [:holder | holder at: 1 @ 1 put: [(holder at: 2 @ 1) + (holder at: 3 @ 1)]. holder at: 2 @ 1 put: 1. holder at: 3 @ 1 put: 1]. " sheet grid openInWorld."! ----- Method: SkSheetTest>>testlocalToGlobal (in category 'card tests') ----- testlocalToGlobal | m | m := SkCardMorph model: SkProxy newForTest. m area: (2 @ 3 corner: 6 @ 4). m direction: #right. self assert: (m localToGlobal: 1 @ 1) = (3 @ 3). self assert: (m localToGlobal: 3 @ 1) = (5 @ 3). m direction: #left. self assert: (m localToGlobal: 1 @ 1) = (1 @ 3). self assert: (m localToGlobal: 3 @ 1) = (-1 @ 3). m direction: #down. " m area: (2@3 corner: 3@7)." self assert: (m localToGlobal: 1 @ 1) = (2 @ 4). self assert: (m localToGlobal: 3 @ 1) = (2 @ 6). m direction: #up. self assert: (m localToGlobal: 1 @ 1) = (2 @ 2). self assert: (m localToGlobal: 3 @ 1) = (2 @ 0)! ----- Method: Pen>>squareNib: (in category '*skeleton-base-pentrail') ----- squareNib: widthInteger "Makes this pen draw with a square nib of the given width." self sourceForm: (Form extent: widthInteger @ widthInteger) fillBlack. combinationRule ifNil: [self combinationRule: Form over "a bit faster than paint mode"]! ----- Method: Point>>direction2:distance: (in category '*skeleton-base-sheet') ----- direction2: freePoint distance: distance "Ask Point by extention of self - freePoint with distance. (100@100 direction: 400@100 distance: 100) = (200@100)" "IT SHOULD BE REMOVED!!!!!! use #direction:distance:" self flag: #TODO. ^ self = freePoint ifTrue: [self] ifFalse: [self + (freePoint - self * distance / (freePoint - self) r)]! _______________________________________________ etoys-dev mailing list [hidden email] http://lists.squeakland.org/mailman/listinfo/etoys-dev |
On 14.10.2011, at 22:52, [hidden email] wrote: Spam detection software, running on the system "europa.mgmt.inetu.net", has Err, sometimes spam detectors are stupid ;) Something is suspicious though. E.g., I think we can remove this: ----- Method: SkeletonBaseInfo class>>addPseudoMethodForBabel (in category 'class initialization') ----- And do we really want to add all those sounds? They will make the sound drop-down longer. ----- Method: SkeletonBaseInfo class>>arrow (in category 'sound library') ----- ... ----- Method: SkeletonBaseInfo class>>cassete (in category 'sound library') ----- ... ----- Method: SkeletonBaseInfo class>>cork (in category 'sound library') ----- ... ----- Method: SkeletonBaseInfo class>>mochi (in category 'sound library') ----- ... ----- Method: SkeletonBaseInfo class>>rice (in category 'sound library') ----- ... ----- Method: SkeletonBaseInfo class>>unstick (in category 'sound library') -----... How about this? PackageInfo subclass: #SkeletonInfo And there are some method flagged TODO. ----- Method: Point>>direction2:distance: (in category '*skeleton-base-sheet') ----- This here uses fork without synchronizing with the Morphic UI process:
It should be at least something like arrow openInWorld. [ (Delay forMilliseconds: 500) wait. WorldState addDeferredUIMessage: [ arrow delete. label ifNotNilDo: [:obj | obj delete]]. ] fork Or even better schedule an alarm instead of forking, e.g. arrow openInWorld. arrow addAlarm: #delete after: 500. label ifNotNil: [label addAlarm: #delete after: 500. - Bert - _______________________________________________ etoys-dev mailing list [hidden email] http://lists.squeakland.org/mailman/listinfo/etoys-dev |
Free forum by Nabble | Edit this page |