'From Squeak3.1alpha of 6 February 2001 [latest update: #3563] on 12 February 2001 at 10:02:08 pm'! "Change Set: MacVM3.0.5UpdatesJMM Date: 12 February 2001 Author: johnmci@smalltalkconsulting.com Macintosh VM source code changes for 3.0.5VM"! !InterpreterSupportCode class methodsFor: 'source file exporting' stamp: 'JMM 2/12/2001 16:28'! compareWithFilesInFolder: folderName "InterpreterSupportCode compareWithFilesInFolder: 'Tosh:Desktop Folder:Squeak VM Project'" | dir | dir _ FileDirectory on: folderName. (dir readOnlyFileNamed: 'projectArchive.sit') binary contentsOfEntireFile = InterpreterSupportCode macArchiveBinaryFile asByteArray ifFalse: [self inform: 'File projectArchive.sit differs from the version stored in this image.']. (dir readOnlyFileNamed: 'readme') contentsOfEntireFile = InterpreterSupportCode readmeFile ifFalse: [self inform: 'File readme differs from the version stored in this image.']. (dir readOnlyFileNamed: 'sq.h') contentsOfEntireFile = InterpreterSupportCode squeakHeaderFile ifFalse: [self inform: 'File sq.h differs from the version stored in this image.']. (dir readOnlyFileNamed: 'sqConfig.h') contentsOfEntireFile = InterpreterSupportCode squeakConfigFile ifFalse: [self inform: 'File sqConfig.h differs from the version stored in this image.']. (dir readOnlyFileNamed: 'platform.exports') contentsOfEntireFile = InterpreterSupportCode squeakPlatformExportsFile ifFalse: [self inform: 'File platform.exports differs from the version stored in this image.']. (dir readOnlyFileNamed: 'sqPlatformSpecific.h') contentsOfEntireFile = InterpreterSupportCode squeakPlatSpecFile ifFalse: [self inform: 'File sqPlatformSpecific.h differs from the version stored in this image.']. (dir readOnlyFileNamed: 'sqFilePrims.c') contentsOfEntireFile = InterpreterSupportCode squeakFilePrimsFile ifFalse: [self inform: 'File sqFilePrims.c differs from the version stored in this image.']. (dir readOnlyFileNamed: 'sqMacAsyncFilePrims.c') contentsOfEntireFile = InterpreterSupportCode macAsyncFilePrimsFile ifFalse: [self inform: 'File sqMacAsyncFilePrims.c differs from the version stored in this image.']. (dir readOnlyFileNamed: 'sqMacNSPlugin.c') contentsOfEntireFile = InterpreterSupportCode macBrowserPluginFile ifFalse: [self inform: 'File sqMacNSPlugin.c differs from the version stored in this image.']. (dir readOnlyFileNamed: 'sqMacDirectory.c') contentsOfEntireFile = InterpreterSupportCode macDirectoryFile ifFalse: [self inform: 'File sqMacDirectory.c differs from the version stored in this image.']. (dir readOnlyFileNamed: 'sqMacDragDrop.c') contentsOfEntireFile = InterpreterSupportCode macDragDropFile ifFalse: [self inform: 'File sqMacDragDrop.c differs from the version stored in this image.']. (dir readOnlyFileNamed: 'sqMacJoystickAndTablet.c') contentsOfEntireFile = InterpreterSupportCode macJoystickAndTabletFile ifFalse: [self inform: 'File sqMacJoystickAndTablet.c differs from the version stored in this image.']. (dir readOnlyFileNamed: 'sqMacMinimal.c') contentsOfEntireFile = InterpreterSupportCode macMinimal ifFalse: [self inform: 'File sqMacMinimal.c differs from the version stored in this image.']. (dir readOnlyFileNamed: 'sqMacNetwork.c') contentsOfEntireFile = InterpreterSupportCode macNetworkFile ifFalse: [self inform: 'File sqMacNetwork.c differs from the version stored in this image.']. (dir readOnlyFileNamed: 'sqMacSerialAndMIDIPort.c') contentsOfEntireFile = InterpreterSupportCode macSerialAndMIDIPortFile ifFalse: [self inform: 'File sqMacSerialAndMIDIPort.c differs from the version stored in this image.']. (dir readOnlyFileNamed: 'sqMacSecurity.c') contentsOfEntireFile = InterpreterSupportCode macSecurityFile ifFalse: [self inform: 'File sqMacSecurity.c differs from the version stored in this image.']. (dir readOnlyFileNamed: 'sqMacSound.c') contentsOfEntireFile = InterpreterSupportCode macSoundFile ifFalse: [self inform: 'File sqMacSound.c differs from the version stored in this image.']. (dir readOnlyFileNamed: 'sqMacWindow.c') contentsOfEntireFile = InterpreterSupportCode macWindowFile ifFalse: [self inform: 'File sqMacWindow.c differs from the version stored in this image.']. (dir readOnlyFileNamed: 'sqNamedPrims.c') contentsOfEntireFile = InterpreterSupportCode squeakNamedPrimsFile ifFalse: [self inform: 'File sqNamedPrims.c differs from the version stored in this image.']. (dir readOnlyFileNamed: 'sqVirtualMachine.h') contentsOfEntireFile = InterpreterSupportCode squeakVirtualMachineHeaderFile ifFalse: [self inform: 'File sqVirtualMachine.h differs from the version stored in this image.']. (dir readOnlyFileNamed: 'sqVirtualMachine.c') contentsOfEntireFile = InterpreterSupportCode squeakVirtualMachineFile ifFalse: [self inform: 'File sqVirtualMachine.c differs from the version stored in this image.']. (dir readOnlyFileNamed: 'MacTCP.h') contentsOfEntireFile = InterpreterSupportCode macTCPFile ifFalse: [self inform: 'File MacTCP.h differs from the version stored in this image.']. (dir readOnlyFileNamed: 'AddressXlation.h') contentsOfEntireFile = InterpreterSupportCode macAddressXlationFile ifFalse: [self inform: 'File AddressXlation.h differs from the version stored in this image.']. (dir readOnlyFileNamed: 'dnr.c') contentsOfEntireFile = InterpreterSupportCode macDNRFile ifFalse: [self inform: 'File dnr.c differs from the version stored in this image.']. ! ! !InterpreterSupportCode class methodsFor: 'source file exporting' stamp: 'JMM 2/12/2001 16:27'! writeMacSourceFiles "Store into this image's folder the C sources files required to support the interpreter on the Macintosh. It also generates the code for the sound synthesis primitives. However, because generating code for the interpreter itself takes several minutes, that is not done automatically by this method. To generate the interpreter code, use the method 'translate:doInlining:' in Interpreter class." "InterpreterSupportCode writeMacSourceFiles" self writeSupportFiles. FFIPlugin writeSupportFiles. self storeString: self macAsyncFilePrimsFile onFileNamed: 'sqMacAsyncFilePrims.c'. self storeString: self macBrowserPluginFile onFileNamed: 'sqMacNSPlugin.c'. self storeString: self macDirectoryFile onFileNamed: 'sqMacDirectory.c'. self storeString: self macJoystickAndTabletFile onFileNamed: 'sqMacJoystickAndTablet.c'. self storeString: self macMinimal onFileNamed: 'sqMacMinimal.c'. self storeString: self macNetworkFile onFileNamed: 'sqMacNetwork.c'. self storeString: self macDragDropFile onFileNamed: 'sqMacDragDrop.c'. self storeString: self macSecurityFile onFileNamed: 'sqMacSecurity.c'. self storeString: self macSerialAndMIDIPortFile onFileNamed: 'sqMacSerialAndMIDIPort.c'. self storeString: self macSoundFile onFileNamed: 'sqMacSound.c'. self storeString: self macWindowFile onFileNamed: 'sqMacWindow.c'. self storeString: self macTCPFile onFileNamed: 'MacTCP.h'. self storeString: self macAddressXlationFile onFileNamed: 'AddressXlation.h'. self storeString: self macDNRFile onFileNamed: 'dnr.c'. self storeStuffitArchive: self macArchiveBinaryFile onFileNamed: 'projectArchive.sit'. ! ! !InterpreterSupportCode class methodsFor: 'source files' stamp: 'JMM 2/12/2001 16:20'! macArchiveBinaryFile "Answer the binary contents of a StuffIt archive file containing the CodeWarrier project files for the virtual machine. You will need to use a StuffIt unpacking utility such as StuffIt Expander to unpack the file. The result will be a folder containing the project files." "To create the text for this method evaulate: | in out | in _ (FileStream oldFileNamed: 'projectArchive.sit') binary. out _ WriteStream on: (String new: 100000). out nextPutAll: '#('. [in atEnd] whileFalse: [out nextPutAll: in next printString; space]. out skip: -1. out nextPutAll: ')'. in close. Clipboard clipboardText: out contents asText and then do paste into this method." ^ #(83 116 117 102 102 73 116 32 40 99 41 49 57 57 55 45 49 57 57 56 32 65 108 97 100 100 105 110 32 83 121 115 116 101 109 115 44 32 73 110 99 46 44 32 104 116 116 112 58 47 47 119 119 119 46 97 108 97 100 100 105 110 115 121 115 46 99 111 109 47 83 116 117 102 102 73 116 47 13 10 26 0 5 16 0 0 109 185 0 0 0 114 0 10 0 0 0 114 22 162 0 43 0 5 1 96 1 255 0 0 0 0 0 0 165 165 165 165 1 0 0 62 0 16 181 144 51 21 182 158 25 127 0 0 0 0 0 0 11 3 0 0 0 0 0 14 47 50 0 0 37 20 0 0 9 183 0 0 0 0 15 0 109 121 77 97 99 72 101 97 100 101 114 115 46 99 0 1 249 212 84 69 88 84 67 87 73 69 1 0 1 128 1 1 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 1 154 0 0 0 106 0 0 0 0 15 0 66 193 212 138 116 88 41 37 231 118 79 249 86 183 220 130 201 119 237 194 11 107 95 101 129 233 78 237 233 41 2 10 134 65 190 14 57 147 88 117 246 30 129 230 100 86 124 160 181 213 228 113 176 242 110 15 116 236 78 49 113 111 82 137 215 100 243 164 56 26 150 173 165 69 200 187 255 179 112 28 55 170 135 33 198 200 235 206 99 142 62 109 255 116 149 57 0 236 41 186 92 188 174 38 174 192 66 193 212 132 70 70 86 227 229 250 240 216 108 46 2 127 7 118 93 193 98 100 220 19 200 129 89 135 89 82 22 238 49 159 133 108 171 14 212 223 34 215 77 208 114 160 164 237 185 214 129 65 199 201 45 211 163 103 203 58 2 85 140 45 151 178 152 115 9 199 215 95 96 151 105 218 21 183 124 139 66 246 165 122 233 239 249 49 33 230 241 98 152 155 66 5 97 56 210 80 40 74 50 161 38 49 191 246 13 248 37 22 30 82 47 247 193 20 8 253 47 112 160 72 112 53 215 204 3 97 248 96 8 243 221 18 149 108 14 129 125 171 25 125 64 92 146 29 121 208 175 185 114 183 252 116 88 47 20 203 91 54 195 197 212 254 215 49 246 175 214 179 20 62 218 106 240 184 65 250 38 189 140 67 51 74 95 30 3 237 219 189 131 26 139 234 59 182 38 237 228 223 81 228 70 109 151 93 182 102 227 203 12 157 152 107 15 98 148 171 41 204 102 172 62 195 233 155 129 52 241 31 197 124 118 99 45 58 83 248 22 215 210 251 42 253 224 32 223 130 124 29 99 117 213 224 39 13 123 115 248 26 221 26 239 139 238 20 111 20 56 127 75 111 87 227 74 59 31 173 85 118 51 26 21 56 145 199 107 6 134 163 54 13 38 143 9 8 177 101 138 176 126 236 42 83 222 165 174 137 128 18 108 62 172 104 206 82 31 153 2 182 57 73 14 84 208 156 251 177 59 232 160 12 252 203 218 179 103 69 40 108 127 129 76 239 43 241 84 12 202 12 118 247 134 247 28 5 26 17 8 152 197 86 37 168 231 169 178 114 72 86 108 222 32 244 59 133 232 143 193 13 133 147 126 127 149 24 121 2 38 68 52 152 209 111 150 184 27 137 253 238 123 197 0 118 134 239 237 36 138 92 9 194 243 159 213 60 212 20 229 59 28 20 233 18 161 31 106 165 1 110 83 216 106 180 249 207 9 174 17 94 185 168 244 3 4 168 140 63 65 99 190 250 119 64 70 17 171 160 166 169 104 159 33 175 236 14 164 90 174 65 175 124 152 30 15 87 146 118 109 236 131 130 220 219 214 112 125 170 137 231 54 250 21 145 43 231 188 66 60 145 144 78 191 182 237 122 40 55 70 174 38 200 113 225 103 84 13 29 121 130 211 114 223 222 52 197 13 242 137 125 59 249 152 208 14 117 204 232 95 173 10 254 158 64 113 32 71 211 118 10 37 152 22 6 193 1 255 147 16 255 96 95 2 197 244 163 41 80 165 64 231 82 177 26 111 196 195 16 244 124 241 119 42 72 98 152 240 138 13 187 140 50 8 203 25 228 139 176 231 43 188 185 2 244 190 171 127 194 95 139 23 204 75 146 60 62 27 80 38 93 38 145 109 19 117 6 190 225 110 85 211 48 214 67 194 48 118 230 103 121 110 231 193 135 164 195 102 232 253 49 148 47 128 195 236 125 10 219 186 74 154 99 167 196 60 86 195 220 106 181 140 85 69 75 218 24 134 11 31 42 184 151 115 226 63 107 52 127 87 90 27 209 125 49 244 52 72 106 47 168 194 221 133 102 80 172 93 30 180 148 98 219 250 1 131 80 231 16 175 251 155 120 51 58 133 74 44 194 98 69 220 203 116 191 232 6 60 149 104 160 232 101 60 176 56 85 193 184 154 196 187 176 181 220 6 241 108 26 22 183 125 180 240 179 101 192 98 125 237 3 89 114 235 91 209 164 113 1 58 129 69 227 29 19 29 199 223 52 106 86 210 28 98 88 130 229 148 120 16 129 14 17 4 222 44 49 251 34 155 53 1 122 248 192 61 173 28 105 15 199 20 82 30 53 37 81 146 117 100 246 78 108 152 234 93 106 164 44 100 57 126 9 134 155 27 184 21 148 185 94 106 50 113 228 79 94 34 151 21 160 54 33 4 249 230 134 176 70 241 249 85 152 252 212 193 251 181 238 242 57 219 252 62 154 74 65 219 88 115 39 77 236 5 188 230 126 109 127 233 91 10 224 186 224 60 237 252 238 150 54 161 201 94 8 244 145 47 44 217 137 239 234 201 42 8 178 49 89 199 176 56 165 31 101 19 109 234 101 137 162 10 229 183 144 68 242 150 52 133 117 88 173 140 84 230 109 53 133 118 31 127 28 54 7 230 85 169 251 254 192 6 169 172 189 140 22 174 91 19 91 125 223 162 84 237 230 213 183 153 250 131 177 111 6 84 183 247 13 76 39 186 31 198 85 4 65 32 19 1 99 145 201 225 227 243 17 214 185 26 33 101 205 44 160 34 195 147 137 18 207 88 193 239 159 19 49 180 186 110 34 91 81 126 47 101 10 118 12 117 42 111 147 156 94 195 157 204 248 229 229 155 103 232 66 107 220 242 138 252 243 151 217 136 131 173 212 193 219 166 253 173 88 80 220 63 46 109 88 232 90 249 96 67 199 255 136 27 154 43 84 216 241 187 178 227 175 65 114 73 13 15 98 255 39 134 162 119 232 163 16 23 93 129 62 166 157 15 154 27 26 22 115 8 168 226 84 233 64 121 6 75 60 59 127 229 225 29 214 193 226 73 79 102 74 60 56 130 137 229 133 2 50 59 52 230 115 36 203 162 101 18 167 216 183 101 153 45 171 24 125 246 212 22 150 51 149 179 153 191 89 161 218 135 97 19 194 50 34 223 113 101 103 136 83 76 55 48 36 80 56 226 27 48 120 156 42 19 32 20 17 57 39 33 219 123 249 192 127 10 182 75 171 92 189 220 14 220 60 159 227 228 14 241 235 112 90 20 251 157 160 3 36 236 95 173 58 230 127 69 243 123 75 97 113 205 83 246 125 11 125 96 36 176 106 177 61 42 181 20 175 94 167 143 126 251 254 160 166 65 77 62 9 249 97 143 85 228 244 116 212 36 139 27 39 2 205 126 120 142 16 221 171 238 9 71 136 127 183 207 62 15 86 53 15 2 102 101 179 61 141 49 213 40 141 163 67 190 184 255 243 129 31 131 167 254 204 179 48 58 103 182 95 167 251 52 47 18 107 18 137 227 164 93 85 188 234 111 109 2 84 181 250 201 87 56 179 139 122 116 9 72 150 26 201 3 16 131 116 158 40 94 162 107 116 254 167 70 163 135 76 238 186 199 185 34 229 206 216 82 176 11 88 86 57 139 30 2 208 123 57 141 221 171 211 186 142 118 126 139 154 109 57 79 1 35 167 40 44 39 213 242 211 220 168 159 200 169 179 212 88 68 78 200 147 37 40 78 169 30 98 229 242 15 101 5 179 4 239 182 164 66 15 21 205 242 169 118 60 166 24 139 110 88 102 100 95 76 164 156 185 94 78 122 188 84 74 244 3 153 155 54 89 214 52 181 186 49 248 74 61 63 130 1 251 48 92 241 131 25 214 90 146 245 111 208 0 200 130 56 240 165 169 148 206 222 128 170 66 144 165 235 199 35 41 172 79 16 73 84 79 60 126 86 20 84 57 189 173 108 83 108 81 41 110 196 34 198 64 130 167 53 95 252 127 145 160 17 25 107 30 200 4 122 235 171 27 245 83 163 114 251 243 83 92 90 202 225 71 136 233 48 236 166 227 153 9 44 86 152 46 157 33 106 211 38 217 131 189 158 77 118 186 137 83 106 231 38 183 90 52 35 137 96 149 252 106 81 140 59 206 123 111 194 70 128 243 110 236 189 248 13 44 218 175 155 189 61 117 24 11 169 190 120 244 49 97 84 33 238 113 123 121 234 200 117 143 213 164 67 118 136 81 156 181 97 170 195 15 90 84 197 162 128 180 123 146 157 140 166 23 62 191 219 207 52 11 47 102 15 132 239 222 55 33 195 105 219 7 235 139 152 116 60 25 96 195 178 61 14 158 181 173 197 130 3 51 243 102 76 103 143 10 245 92 220 236 141 223 116 227 66 7 57 153 114 238 10 230 232 176 12 175 132 255 205 252 18 152 205 169 191 124 59 188 115 70 80 37 198 61 238 169 19 8 73 36 110 103 133 105 74 11 15 219 222 225 80 37 208 46 80 225 212 115 148 86 235 203 83 7 141 117 136 142 4 23 62 124 10 94 45 49 81 53 68 172 40 141 44 61 248 53 189 171 93 232 151 125 187 242 44 48 78 122 14 155 71 149 26 249 110 4 137 252 232 107 95 133 111 248 39 32 216 250 139 71 199 65 188 109 185 222 173 38 154 41 26 203 164 65 78 224 92 171 208 90 72 55 177 173 76 81 231 243 216 204 118 128 229 102 224 120 76 223 0 232 167 190 139 96 143 251 23 60 117 73 185 52 25 41 30 92 16 109 65 55 254 254 173 95 201 191 193 56 212 8 23 212 173 150 167 92 25 22 96 99 170 165 164 40 36 195 183 62 219 4 67 46 22 63 222 5 189 85 231 135 117 193 81 183 28 185 150 204 45 138 16 29 249 195 34 17 152 49 55 161 150 67 67 238 114 100 72 91 0 22 231 161 15 143 49 222 113 6 12 169 143 119 228 135 153 170 60 177 165 119 120 180 81 178 118 192 182 42 171 188 123 62 224 76 89 178 221 232 21 1 32 55 48 174 83 32 204 196 152 115 160 94 162 76 36 234 130 46 208 158 156 130 16 2 200 63 214 12 68 238 216 11 69 230 210 144 197 49 0 137 72 242 7 201 79 14 15 92 223 226 57 137 113 156 96 94 22 62 239 156 25 246 159 72 150 236 47 148 93 81 82 160 65 193 218 226 5 173 68 149 131 185 38 21 54 28 45 163 133 100 249 71 53 193 81 236 219 46 36 117 122 241 67 70 160 158 137 200 28 140 228 117 216 92 197 139 107 45 76 132 225 120 25 241 135 183 155 93 124 61 178 162 153 124 169 222 88 143 122 87 102 247 47 37 141 255 232 110 183 43 235 205 24 115 77 112 204 130 226 183 244 107 237 88 133 215 112 156 91 244 40 149 126 211 18 61 248 243 242 234 1 67 155 205 165 46 241 183 45 57 192 220 209 108 240 103 75 84 225 56 241 98 50 22 74 38 110 229 178 174 113 149 105 219 99 204 9 187 142 57 11 80 19 222 31 78 163 164 81 225 238 93 139 39 45 77 116 191 122 147 93 63 47 1 43 54 59 33 120 183 197 115 221 125 55 140 107 197 207 252 168 189 93 204 160 15 6 92 87 21 69 13 171 60 68 240 229 169 136 185 10 16 114 157 62 4 62 98 10 25 57 208 210 238 206 221 244 23 46 24 203 6 182 53 192 196 161 244 15 113 51 114 84 111 207 79 49 240 83 61 153 132 114 177 48 194 95 237 67 44 187 237 135 159 159 33 223 31 214 108 74 197 120 50 91 204 64 45 244 193 54 170 53 199 41 10 70 220 145 68 218 10 32 158 205 48 186 18 120 100 158 47 3 157 62 91 7 54 31 217 83 233 226 95 125 28 51 6 123 194 39 147 63 52 100 201 220 96 226 242 131 85 96 214 22 71 194 69 5 99 37 88 48 22 245 153 70 245 85 38 116 133 224 61 191 197 143 169 70 94 167 89 162 114 248 119 73 40 186 97 52 83 229 239 50 37 67 25 0 165 165 165 165 1 0 0 64 0 16 181 144 51 13 182 158 25 127 0 0 0 114 0 0 13 78 0 0 0 0 0 16 118 69 0 0 3 20 0 0 1 114 0 0 0 0 15 0 109 121 77 97 99 72 101 97 100 101 114 115 46 112 99 104 0 1 88 136 84 69 88 84 67 87 73 69 1 0 0 192 2 1 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 1 154 0 0 0 103 0 0 0 0 15 0 66 193 212 165 47 158 101 143 90 111 232 62 137 252 56 69 246 56 222 197 11 110 186 70 46 68 245 227 157 58 176 118 108 255 85 62 40 178 85 18 69 169 203 40 18 219 49 207 252 15 57 78 136 238 192 137 69 135 101 84 46 156 13 5 175 9 5 162 245 172 207 165 169 206 88 73 211 171 164 174 112 63 71 184 31 221 37 166 79 5 131 15 114 244 238 207 216 239 17 227 177 67 160 66 193 212 154 175 240 32 110 231 176 220 75 122 67 45 140 218 152 26 188 19 16 70 46 100 12 102 162 171 207 147 232 46 129 230 224 142 44 70 162 102 82 16 65 169 232 58 197 1 226 230 247 241 20 175 215 67 32 203 217 208 134 187 150 162 63 110 169 185 56 142 225 246 180 33 114 124 5 37 84 212 128 30 164 229 208 216 224 187 2 126 209 51 142 7 56 139 220 232 168 56 210 119 197 236 95 113 121 147 62 5 16 6 102 148 120 76 237 88 4 46 152 207 227 190 58 105 25 63 228 30 242 145 30 205 193 119 28 65 161 6 85 113 254 35 25 218 241 155 57 46 34 101 87 219 177 175 90 37 23 192 16 110 135 14 201 90 113 155 204 60 215 16 232 111 135 218 123 36 119 224 93 163 67 233 232 62 127 241 177 118 93 131 253 225 94 147 211 226 106 223 56 140 40 243 210 212 240 205 25 69 158 223 23 7 45 121 161 103 21 93 76 191 131 11 37 220 95 159 108 53 71 237 228 38 192 96 36 234 168 14 101 68 218 187 125 239 67 136 208 224 145 202 41 73 44 92 125 93 164 127 252 148 199 42 76 2 0 50 102 61 155 95 144 49 242 226 212 139 39 169 250 165 133 244 188 11 198 113 244 133 255 208 95 234 165 90 112 27 52 250 90 78 166 0 202 127 35 59 223 131 14 154 81 218 181 53 29 254 103 48 33 191 225 6 186 233 121 161 97 169 147 218 120 247 111 39 193 212 57 27 102 129 167 141 48 58 146 236 83 180 135 36 193 196 77 181 97 218 24 94 119 88 225 88 61 107 38 42 0 165 165 165 165 1 0 0 70 0 16 181 144 51 13 182 158 25 125 0 0 11 3 0 0 15 252 0 0 0 0 0 22 20 235 0 0 3 180 0 0 1 205 0 0 0 0 15 0 109 121 77 97 99 72 101 97 100 101 114 115 67 97 114 98 111 110 46 112 99 104 0 1 219 219 84 69 88 84 67 87 73 69 1 0 0 16 0 16 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 1 154 0 0 0 105 0 0 0 0 15 0 66 193 212 165 47 158 104 163 81 45 121 217 33 168 151 12 136 51 216 133 159 78 214 216 43 6 93 88 173 49 224 16 210 176 244 190 46 112 249 208 12 31 155 208 114 175 160 237 166 80 129 149 37 165 111 12 49 64 250 168 169 159 82 99 244 238 46 66 203 196 69 63 252 89 175 97 38 187 103 169 162 122 93 198 238 248 174 171 90 231 91 24 116 109 194 102 235 220 101 188 198 239 167 48 0 66 193 212 247 142 41 244 252 170 32 131 125 120 226 219 34 155 40 95 65 156 245 152 111 218 35 102 116 216 131 145 17 84 107 97 158 240 249 195 150 60 120 140 104 228 134 193 204 31 57 215 166 99 44 206 176 32 16 144 208 6 248 187 61 109 226 227 51 211 25 218 191 40 12 114 22 28 230 0 112 11 172 202 32 219 160 175 46 72 139 187 24 169 29 138 113 109 138 194 65 131 26 203 70 229 19 88 5 218 129 23 174 244 179 27 110 213 99 88 249 52 149 107 131 128 11 191 219 77 60 140 147 221 41 5 154 71 244 111 11 122 216 102 224 199 124 224 181 243 197 90 177 66 36 17 3 41 236 155 135 117 157 197 125 86 112 49 216 189 27 139 184 235 236 11 77 248 224 96 79 164 194 90 103 41 162 119 82 173 71 116 83 120 63 237 133 59 95 243 179 182 38 66 89 112 120 57 175 247 2 86 164 221 215 242 66 72 241 206 94 82 185 213 183 84 158 243 111 184 131 123 154 113 69 129 63 216 193 18 183 237 229 86 226 139 223 239 210 173 153 53 67 49 7 198 215 211 213 85 237 110 87 144 203 47 169 210 32 17 124 119 167 84 218 32 64 80 64 213 139 46 73 67 237 85 242 129 68 80 18 116 121 38 21 132 110 38 88 152 155 85 234 152 132 14 186 223 127 213 177 161 118 126 164 93 140 86 9 39 140 158 128 15 121 128 22 82 198 32 125 160 105 176 229 213 67 60 105 93 166 53 20 133 196 110 63 239 200 252 182 252 210 104 194 171 61 38 193 140 109 223 92 105 43 228 169 222 61 252 104 255 66 238 34 62 131 239 211 193 88 118 48 247 65 45 181 8 92 165 55 106 219 2 60 38 114 62 64 145 43 151 179 227 59 232 214 164 43 226 209 187 193 230 212 51 34 107 155 72 0 26 242 4 241 9 64 80 182 179 217 254 181 123 67 245 13 80 221 209 230 9 60 229 105 10 138 253 27 231 68 155 196 137 233 97 229 82 175 213 222 96 165 165 165 165 1 0 0 61 0 0 172 94 103 33 181 100 42 6 0 0 13 78 0 0 28 169 0 0 0 0 0 13 171 241 0 0 7 218 0 0 2 139 0 0 0 0 15 0 77 121 80 108 117 103 105 110 46 112 114 111 106 0 1 46 58 77 77 80 82 67 87 73 69 1 0 3 64 1 1 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 43 27 0 0 9 179 0 0 0 0 15 0 66 193 212 194 19 180 140 109 220 205 78 57 63 90 66 84 57 156 71 10 240 179 194 234 180 76 49 136 61 86 193 33 87 165 51 39 174 141 114 32 57 229 43 22 87 128 72 84 38 117 129 4 182 215 234 186 97 240 130 6 7 168 37 149 122 3 125 3 195 87 185 151 254 22 251 249 238 210 167 130 219 121 155 186 134 229 95 75 152 58 93 250 123 38 106 43 222 218 75 149 20 150 219 56 44 81 228 23 54 251 165 214 237 251 0 192 205 43 113 64 228 181 201 133 51 84 209 66 37 59 176 144 234 4 186 142 81 128 228 2 55 216 158 134 41 177 194 7 95 252 212 255 73 83 237 231 200 33 245 234 99 190 79 33 76 97 115 253 35 55 46 42 13 118 116 73 161 215 249 23 162 74 26 161 34 208 52 177 148 31 2 225 128 147 212 218 175 235 77 215 179 45 41 42 83 138 73 222 20 4 247 49 227 152 237 224 96 210 249 218 162 93 24 168 187 8 67 87 106 36 240 23 14 253 32 32 233 250 182 103 110 104 23 208 218 230 121 74 225 57 124 53 128 60 111 91 170 168 211 245 68 13 214 181 216 230 12 119 31 218 154 171 103 239 30 230 22 188 226 29 238 162 224 59 253 70 31 56 103 224 36 245 159 238 139 104 201 201 132 39 227 128 0 62 234 60 136 63 255 195 11 172 202 17 37 216 84 146 63 219 54 56 151 166 38 241 106 221 197 103 27 237 182 165 6 183 114 101 218 141 240 64 148 45 222 37 21 103 254 127 46 56 173 37 215 210 155 156 143 214 184 249 118 238 209 196 193 63 132 149 152 85 92 181 13 27 221 176 225 145 152 79 7 62 97 181 120 39 91 165 74 115 184 46 199 3 192 153 218 145 229 140 225 48 115 235 24 105 61 157 168 6 39 4 200 157 182 175 112 130 106 48 11 175 17 0 192 51 97 61 92 231 192 128 4 202 158 82 84 178 6 244 58 194 143 198 197 84 245 194 178 69 38 193 153 99 228 73 197 137 51 95 234 74 220 141 111 161 135 191 121 33 201 254 51 7 28 164 179 195 57 17 73 210 193 161 123 149 11 73 41 75 25 196 86 100 212 137 148 255 191 61 249 212 167 243 124 178 252 243 230 210 105 103 137 88 244 8 170 166 127 33 239 33 76 177 46 165 94 119 60 57 69 82 53 93 97 113 18 211 180 59 221 195 107 202 4 125 117 172 218 169 252 32 46 1 54 41 228 135 201 89 109 105 202 112 20 196 166 41 173 208 173 27 148 202 143 245 25 142 72 111 18 240 135 44 9 113 199 4 252 36 142 207 253 43 184 119 116 86 138 249 177 138 141 63 33 191 93 190 139 209 129 212 216 83 151 194 200 24 252 41 196 242 80 71 41 30 226 43 28 209 35 219 218 177 65 128 188 55 183 237 64 231 242 161 168 189 135 114 61 217 9 64 19 4 196 99 134 88 34 235 184 97 44 234 25 195 176 83 127 209 207 190 234 196 243 14 19 177 134 74 190 120 202 207 65 100 1 59 62 46 48 80 135 3 9 73 242 18 57 109 183 245 222 178 216 183 84 76 56 208 27 8 158 248 66 214 155 165 188 137 94 194 111 156 211 2 200 53 127 166 203 170 79 164 98 8 33 169 242 184 152 189 171 140 226 112 193 38 34 179 149 178 39 37 88 11 56 158 240 172 153 69 71 107 203 187 140 154 176 235 8 151 194 172 241 194 59 173 162 204 166 181 114 97 224 92 71 116 144 235 121 221 159 124 218 189 170 239 83 135 28 243 178 223 131 227 17 146 169 220 93 31 64 246 60 114 194 162 48 94 192 255 37 210 128 223 90 148 255 167 134 204 96 230 126 180 73 114 139 161 17 171 76 130 56 199 160 130 180 229 165 79 185 10 128 134 241 79 80 147 118 89 165 116 61 94 67 177 61 154 226 10 230 26 219 235 251 35 12 194 40 38 35 252 251 191 11 198 3 254 127 229 204 232 61 105 255 53 135 108 128 24 78 193 229 23 109 141 167 141 113 72 6 184 7 83 149 143 141 161 13 193 130 105 121 159 72 83 255 218 246 207 168 2 188 251 220 106 202 121 24 137 85 236 151 184 191 38 29 12 123 142 42 244 196 40 124 66 26 203 78 220 166 73 142 150 63 166 17 119 99 243 166 176 210 220 215 118 253 59 143 35 122 222 50 58 29 51 211 19 174 220 236 227 198 71 227 70 156 97 25 76 78 210 252 109 98 200 134 0 148 114 221 154 66 23 196 248 37 253 225 184 18 33 116 236 252 67 236 135 114 205 157 120 160 155 132 133 60 83 40 206 205 65 122 27 3 244 137 119 158 91 42 59 189 57 230 202 3 71 214 181 17 91 237 71 219 25 87 69 187 54 79 222 40 229 9 229 71 160 174 72 187 107 25 142 156 159 128 201 103 230 130 228 230 37 21 220 76 245 164 173 70 236 120 248 32 0 235 8 226 156 150 195 159 49 115 251 27 199 242 115 185 77 140 190 205 244 7 223 191 94 162 200 1 170 101 82 196 36 62 145 104 149 184 123 177 153 15 220 14 50 253 40 5 192 198 227 129 195 234 3 23 1 199 104 182 67 51 17 31 177 252 147 96 76 24 221 202 12 236 136 115 123 75 165 115 55 2 242 194 9 252 13 250 160 95 132 217 253 162 222 168 205 117 26 224 163 41 136 164 32 42 40 60 7 24 87 230 249 31 58 236 150 135 184 249 22 205 31 97 180 112 137 182 250 89 4 221 38 113 74 247 168 206 215 112 54 174 17 124 134 22 229 141 40 117 220 60 36 142 159 28 196 12 79 250 234 136 200 220 192 151 253 59 63 143 176 44 197 118 7 251 9 88 225 69 165 197 229 146 92 13 230 142 60 188 7 204 81 241 42 116 68 128 100 171 169 163 137 188 9 17 212 4 231 195 226 170 216 196 24 94 172 65 211 52 75 97 206 167 143 24 61 168 230 229 31 239 42 70 74 67 179 96 52 199 96 80 117 42 122 92 36 146 138 21 213 65 96 75 175 232 31 107 43 33 91 231 154 123 5 24 28 139 122 138 127 91 147 185 79 21 150 196 39 242 145 196 148 195 22 235 187 30 46 175 109 249 30 33 44 231 138 19 255 207 171 119 184 201 171 190 52 6 187 143 13 176 206 38 141 52 54 14 234 19 13 72 228 115 134 239 231 78 161 68 240 39 189 238 92 137 134 220 92 228 98 165 0 223 127 16 233 228 150 150 183 157 213 170 18 108 187 193 244 40 94 214 27 214 103 133 11 23 106 140 153 150 249 216 192 173 245 226 15 71 223 152 10 15 241 34 209 142 177 116 19 237 153 115 235 149 33 51 8 136 185 42 26 124 13 143 64 6 191 151 249 2 34 136 141 198 23 227 78 45 51 175 180 143 131 177 93 122 47 116 190 243 99 42 32 159 106 87 251 223 159 179 37 63 143 200 173 119 171 27 79 79 149 2 209 224 156 255 224 213 5 208 114 14 166 128 135 141 222 107 146 148 60 212 87 95 249 62 108 29 151 193 171 48 111 202 218 27 135 180 253 254 184 223 129 63 91 60 123 221 98 165 199 70 36 4 155 209 197 95 213 90 27 172 67 75 182 52 134 225 138 50 128 100 245 153 1 73 95 228 92 254 186 19 225 208 85 38 151 24 215 131 149 191 230 74 57 107 248 227 229 111 209 108 16 211 152 104 163 251 128 215 147 85 150 15 43 134 83 159 42 239 54 28 40 73 52 207 84 129 239 98 214 179 21 102 137 178 110 247 152 202 120 33 245 91 121 128 234 177 58 4 101 109 183 205 222 157 164 79 7 109 210 19 253 233 66 110 212 180 156 55 124 37 83 157 36 52 71 108 27 185 118 84 11 222 1 186 180 176 54 75 2 134 10 200 41 247 243 115 198 166 236 142 190 189 239 126 125 106 88 219 213 89 86 112 164 28 237 40 73 163 214 41 167 51 226 144 185 109 128 31 24 46 11 81 151 124 82 134 29 127 35 25 190 38 212 98 223 126 203 32 60 74 103 251 72 156 19 78 206 72 239 13 5 249 184 234 54 28 128 245 0 249 90 69 3 123 98 160 210 186 41 73 17 3 28 112 129 216 217 199 108 97 59 3 225 73 152 69 217 146 229 62 27 45 119 23 226 20 9 145 94 46 115 121 134 233 179 133 155 94 199 108 100 28 131 175 206 140 90 173 14 18 76 19 202 83 159 22 214 223 144 183 119 149 129 120 70 181 99 68 133 35 149 192 17 182 40 216 129 186 185 222 109 72 135 219 119 115 196 249 44 150 83 58 212 26 210 154 53 109 49 36 39 146 188 84 202 107 117 165 30 161 103 160 138 30 154 85 67 10 214 221 117 225 102 176 143 120 211 187 176 196 245 60 28 179 165 154 167 22 55 97 242 45 252 235 170 218 20 43 72 243 201 54 123 101 20 33 48 168 180 233 60 232 203 7 66 56 124 146 214 112 254 140 37 96 243 38 179 116 69 25 227 129 70 166 160 195 95 119 149 251 212 214 138 62 183 247 149 85 11 116 61 189 17 187 149 100 21 248 121 103 245 72 14 36 248 191 128 103 91 132 118 39 131 121 52 247 206 93 47 82 113 11 31 148 91 121 169 110 211 31 34 248 177 165 90 108 123 99 171 35 104 32 238 176 63 65 30 99 58 169 225 58 211 237 4 229 142 123 59 108 223 136 197 220 218 91 179 0 121 93 76 67 65 204 151 161 33 65 74 212 79 82 70 71 34 30 120 110 193 0 36 170 193 44 45 143 228 131 205 150 244 160 150 106 22 65 152 121 20 125 25 104 52 133 104 165 184 88 121 83 121 93 99 250 114 15 118 56 143 178 96 88 189 162 5 211 244 73 153 40 207 205 71 138 167 60 186 201 213 118 68 181 199 75 78 195 34 132 17 127 183 98 72 65 22 255 140 196 232 205 157 2 110 42 175 37 4 30 101 25 242 48 107 25 105 159 30 213 210 157 118 121 51 157 187 180 131 3 44 5 185 15 215 79 162 2 26 65 168 188 175 126 122 46 117 97 63 225 223 18 22 211 203 44 218 82 158 29 119 110 57 91 14 143 66 109 2 240 56 94 247 35 47 101 146 49 98 29 193 204 226 150 16 203 189 11 251 203 208 29 186 250 218 53 107 74 41 140 45 140 4 31 27 113 69 36 188 128 46 81 132 34 77 101 50 169 28 156 133 164 129 253 215 241 194 174 172 194 42 220 190 205 227 223 125 42 185 109 222 61 100 144 193 147 66 193 232 72 220 164 225 179 24 189 206 106 11 94 84 43 63 244 25 229 114 152 79 232 252 147 54 43 138 6 104 248 81 78 162 136 226 36 206 113 106 248 66 115 193 28 216 164 130 112 222 54 251 213 143 169 214 127 195 37 79 48 191 31 239 222 47 54 197 188 194 74 4 90 50 70 38 100 59 49 223 218 178 37 231 49 12 152 217 227 91 99 20 154 159 152 122 106 149 86 103 187 70 156 1 251 186 172 207 166 67 51 147 24 159 0 66 193 212 209 173 202 54 121 186 247 106 241 139 248 136 144 151 199 247 80 188 144 101 75 21 223 57 158 220 219 236 232 23 100 202 212 173 34 206 147 90 245 218 205 94 143 37 178 123 245 10 207 222 177 255 205 243 59 2 92 205 14 246 210 227 42 114 60 115 43 247 225 110 54 179 180 171 8 226 94 227 206 84 12 108 245 165 220 186 62 202 190 198 31 48 221 104 253 145 8 22 239 235 157 224 89 115 154 66 225 233 26 132 65 101 103 113 198 133 195 218 235 163 15 66 48 130 138 254 104 191 21 132 73 188 3 18 49 233 212 33 173 203 85 255 167 237 129 60 173 232 204 54 14 112 18 11 20 121 253 133 205 30 128 169 42 1 114 138 184 35 247 111 197 232 255 8 125 197 39 27 123 188 217 183 113 101 115 55 200 76 41 136 182 194 36 115 226 46 180 223 15 180 184 199 127 207 175 183 18 108 253 224 68 225 189 230 145 197 113 58 99 64 169 236 231 55 89 138 194 172 139 126 15 235 114 7 190 146 185 206 38 26 160 116 201 4 85 157 75 151 138 219 4 150 5 192 67 120 123 231 151 29 125 34 237 37 125 175 14 219 63 40 148 37 198 227 142 220 5 165 190 80 20 226 226 188 106 110 189 68 213 83 144 111 161 33 212 140 77 52 244 117 247 254 247 134 221 112 95 223 125 162 95 247 113 127 148 138 20 251 103 234 125 73 19 94 81 44 249 114 11 173 196 15 63 229 13 115 251 195 11 98 206 183 202 33 193 89 219 11 110 155 116 53 252 253 48 32 153 170 120 19 185 239 38 248 134 53 99 79 234 178 251 112 68 87 151 119 91 159 228 132 234 207 90 233 251 86 23 140 87 198 204 228 239 33 97 205 23 105 57 191 169 94 234 175 182 54 157 209 165 39 1 23 153 99 4 83 250 118 150 110 225 141 205 108 23 85 157 117 151 134 213 237 178 162 80 51 220 165 2 220 8 167 35 52 225 141 195 156 254 21 76 95 231 237 249 231 199 223 249 56 16 105 49 246 179 86 86 199 222 103 162 50 165 41 77 133 132 4 246 90 221 161 237 175 20 1 224 5 208 134 151 85 245 81 241 166 113 128 176 170 18 208 148 167 107 165 84 201 247 77 110 178 243 212 76 28 185 151 25 3 254 91 135 233 7 181 194 191 189 100 178 100 20 92 126 239 85 113 127 203 20 251 252 161 1 63 35 197 97 30 51 62 136 236 104 162 216 84 86 49 130 181 92 215 169 183 20 181 106 88 75 233 118 139 43 234 2 58 27 15 194 152 140 103 217 39 100 170 4 96 201 205 75 153 189 203 211 117 177 25 176 204 93 16 68 7 53 84 183 210 189 91 68 187 188 136 34 168 145 152 249 26 42 26 225 31 239 15 249 137 120 247 29 172 107 103 137 180 207 217 121 27 149 32 90 137 141 176 165 165 165 165 1 0 0 64 0 0 172 94 103 33 181 100 23 240 0 0 15 252 0 0 40 248 0 0 0 0 0 16 180 253 0 0 7 90 0 0 2 148 0 0 0 0 15 0 77 121 80 108 117 103 105 110 54 56 75 46 112 114 111 106 0 1 162 139 77 77 80 82 67 87 73 69 1 0 3 128 0 129 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 37 135 0 0 9 73 0 0 0 0 15 0 66 193 212 169 9 210 149 55 104 18 166 123 198 254 115 231 189 56 26 63 233 107 89 215 26 41 64 39 168 254 239 247 106 245 213 179 37 162 85 150 47 25 75 142 73 147 42 103 39 18 89 87 185 158 183 144 191 121 197 58 247 237 47 168 4 250 221 80 196 140 250 2 153 82 24 7 101 152 165 56 154 236 133 124 32 161 65 134 202 240 234 38 74 220 207 29 183 187 78 143 128 78 228 25 224 83 50 226 241 200 15 193 111 178 15 246 78 206 228 147 246 197 203 10 10 242 105 41 4 66 205 9 1 225 252 22 138 140 209 6 181 240 179 154 27 24 6 94 118 33 215 71 251 65 6 46 194 156 224 245 152 248 245 163 117 106 184 81 55 44 43 63 12 15 131 173 177 63 58 108 90 116 237 57 130 18 45 207 39 168 184 124 14 234 151 77 158 24 238 174 149 45 154 30 127 131 200 231 47 199 96 208 217 78 147 104 4 219 175 174 33 142 236 210 130 219 100 211 116 254 15 231 119 8 95 0 178 98 122 210 142 229 104 67 70 12 175 141 92 58 110 110 125 213 36 115 84 117 144 245 75 148 181 55 130 172 219 99 192 169 188 102 174 245 3 98 201 249 187 198 155 60 173 205 234 41 227 58 211 109 39 124 98 234 206 156 15 73 86 25 233 109 125 254 184 178 214 178 133 136 246 117 48 173 55 248 26 8 190 78 97 200 67 23 26 223 148 9 135 229 250 93 43 221 207 238 48 11 146 126 167 202 57 129 122 208 16 68 11 171 85 193 55 197 75 206 6 101 225 159 104 37 53 24 149 113 98 108 118 35 180 159 124 25 241 188 82 51 147 186 228 19 144 214 103 241 33 199 95 1 89 148 121 49 217 177 30 75 206 83 68 131 49 235 210 72 87 124 132 117 54 28 248 36 131 82 144 238 147 41 18 75 146 21 97 35 176 24 27 156 45 171 65 232 213 217 183 86 97 199 127 122 105 229 192 146 21 171 163 104 83 164 85 85 159 97 16 133 250 117 123 35 109 109 221 183 95 120 25 237 167 23 213 43 6 178 186 44 154 201 162 86 26 136 87 11 90 163 230 224 102 104 162 19 246 228 233 218 91 12 199 141 183 74 205 224 12 153 150 177 85 0 41 202 28 63 57 160 34 129 152 15 10 240 140 213 45 91 151 230 63 252 32 81 62 58 251 113 147 52 74 212 214 30 114 32 135 185 204 7 224 181 26 172 91 169 81 65 140 201 52 185 195 170 193 233 103 214 112 109 65 219 94 83 253 182 167 152 47 211 90 104 203 34 241 216 55 162 73 128 24 254 18 243 43 51 199 224 93 181 216 4 195 100 21 1 142 111 89 99 181 120 228 69 89 150 166 67 160 133 83 74 25 120 228 202 151 213 197 238 169 7 25 75 215 132 139 13 128 148 42 185 174 244 128 76 188 161 166 164 16 51 147 115 251 235 205 105 232 86 142 76 237 244 167 29 43 177 248 156 194 246 97 15 7 255 213 141 41 156 105 175 207 13 3 192 68 119 2 85 97 230 126 53 40 79 97 45 221 168 205 66 34 36 28 180 173 22 22 180 51 194 56 193 255 243 75 101 57 141 155 154 6 150 42 8 180 204 128 177 95 60 122 220 131 125 225 225 49 227 224 60 187 72 148 80 225 109 173 250 161 103 80 190 248 119 106 225 182 172 156 189 14 39 39 172 51 134 119 87 74 119 174 13 184 80 179 206 211 203 197 4 98 108 88 244 9 167 90 0 179 111 74 175 93 37 151 71 255 226 242 57 3 70 223 10 238 143 109 72 108 218 5 38 140 97 70 133 196 185 229 124 137 190 203 76 81 53 60 4 82 244 201 125 216 66 13 237 218 214 208 120 143 242 251 23 135 220 72 32 82 237 68 189 70 62 224 254 70 62 224 229 134 119 188 130 31 152 255 212 226 149 189 221 60 223 148 73 202 157 18 249 54 56 126 101 207 255 58 91 68 133 67 118 98 230 235 242 45 38 75 183 17 235 204 212 204 222 45 249 140 101 163 86 59 125 195 111 43 228 127 205 120 199 85 241 203 115 36 38 114 138 200 134 12 65 52 23 170 58 186 89 15 23 144 208 141 125 252 131 154 213 103 133 164 20 24 181 20 212 220 255 114 55 158 205 47 147 146 107 120 61 236 170 84 104 212 61 32 201 252 208 92 120 214 182 30 6 28 5 1 22 67 109 244 114 222 27 168 58 178 108 199 187 12 57 225 72 255 253 245 130 250 31 222 250 246 10 101 46 52 182 55 251 253 245 81 49 245 105 93 45 82 221 74 249 125 1 22 82 12 24 109 64 86 153 199 117 92 85 16 118 131 199 159 35 198 115 25 194 53 204 76 60 91 61 99 94 137 235 45 223 47 205 83 53 161 9 165 132 157 86 145 51 163 200 190 148 205 153 118 167 140 3 86 133 127 81 179 26 56 173 105 221 157 174 25 29 252 191 134 231 205 247 66 63 40 168 20 174 40 253 99 88 50 93 57 46 77 42 38 230 44 152 237 96 246 158 174 127 80 223 21 171 208 218 64 83 60 6 39 178 161 246 16 149 28 35 238 182 210 44 48 166 87 16 17 60 128 20 135 242 84 199 79 197 192 216 159 45 88 172 97 28 155 254 95 247 229 19 84 119 64 208 127 23 119 239 50 27 133 55 86 37 222 63 40 63 237 92 219 43 139 185 171 144 78 174 41 45 134 33 179 81 222 241 244 47 230 107 206 53 93 206 223 25 220 198 187 145 188 22 208 189 21 158 201 29 156 207 162 236 106 151 65 58 250 220 39 200 228 244 143 101 56 32 72 194 32 92 161 170 95 226 91 247 74 68 91 243 111 13 53 30 159 155 43 194 142 72 76 100 240 231 155 202 2 170 87 103 101 137 13 158 138 204 152 21 128 163 227 158 239 113 74 203 205 138 28 253 172 176 47 237 128 246 167 129 252 181 12 189 44 9 25 249 55 100 198 20 247 11 221 58 43 244 154 235 66 177 195 182 215 227 81 34 233 12 208 171 215 60 228 237 247 68 237 254 101 72 11 189 214 132 0 237 192 83 247 146 44 29 115 128 161 61 99 89 134 224 142 199 58 193 76 75 167 233 190 242 240 211 62 140 149 132 19 231 30 187 11 119 216 16 130 123 220 109 76 105 8 8 51 177 93 127 176 168 236 224 185 239 147 241 252 89 235 117 89 232 240 134 105 5 97 209 251 211 122 163 130 146 101 27 0 163 26 227 99 143 189 100 252 184 92 204 15 249 41 66 137 162 186 236 108 107 110 37 6 27 122 43 43 183 9 177 188 52 107 174 190 52 142 8 234 72 246 140 207 86 16 62 58 111 246 174 164 206 167 225 25 226 156 194 36 44 43 216 74 52 246 175 115 93 50 77 141 193 52 62 121 123 202 32 231 159 172 154 127 94 71 139 59 99 60 95 93 5 219 230 131 152 119 71 166 108 172 186 159 236 122 151 241 89 190 225 248 70 6 59 222 41 63 1 165 51 242 86 140 13 190 182 4 62 76 202 29 142 235 136 247 213 221 89 87 129 198 64 125 243 139 125 99 248 77 77 161 154 149 206 132 228 19 219 21 20 117 100 106 17 25 129 82 47 223 238 149 91 209 180 62 152 199 225 74 120 88 182 193 105 50 55 18 249 249 177 21 79 110 42 239 129 88 200 29 133 34 98 15 45 175 191 221 140 248 216 149 245 89 166 178 80 182 78 190 69 50 222 205 239 161 190 224 7 58 209 212 252 3 217 253 195 183 64 52 49 155 161 91 219 253 14 98 134 170 152 67 190 151 34 0 244 30 29 40 140 166 74 48 227 156 179 126 37 235 250 104 255 27 136 65 183 130 244 43 240 35 123 226 134 15 235 124 3 209 133 214 35 208 2 203 15 238 71 79 163 249 77 38 232 160 127 174 99 90 151 104 248 47 21 102 40 10 75 7 38 213 12 191 187 208 175 51 104 120 67 247 117 94 241 128 200 6 166 210 115 55 169 169 217 14 21 75 98 182 140 181 241 103 66 242 210 58 92 215 100 223 168 223 224 23 185 68 213 123 36 81 24 49 168 209 69 245 79 245 26 172 28 132 233 201 18 122 188 2 206 212 185 33 163 205 123 122 253 31 107 244 225 171 154 126 238 192 76 97 3 130 6 136 89 106 53 55 117 226 25 20 196 35 147 112 210 205 162 106 50 158 32 159 46 222 213 182 51 197 240 80 51 244 161 110 150 205 10 210 29 211 191 134 8 62 165 173 11 212 161 149 21 59 192 148 10 206 136 162 153 70 254 239 231 184 38 59 63 15 77 159 36 158 37 220 110 219 185 101 189 130 102 113 59 89 8 251 111 16 111 199 206 9 183 37 71 67 15 254 146 122 128 22 246 172 83 255 83 89 0 246 254 92 199 238 49 177 50 56 60 7 47 70 50 98 209 93 12 210 64 75 186 162 82 59 16 42 28 252 150 217 13 179 131 109 44 168 155 109 124 107 172 34 39 56 93 136 156 226 51 195 139 240 86 22 205 163 244 246 122 13 115 134 172 202 203 8 83 178 251 160 6 219 89 67 181 18 209 214 63 231 59 24 227 158 23 7 240 58 71 177 7 113 158 183 64 244 85 7 107 227 60 68 82 254 89 181 121 244 154 127 239 164 100 253 201 24 40 247 95 2 117 74 39 105 8 93 65 60 200 39 164 174 113 104 28 234 29 2 248 240 139 89 240 62 145 199 95 144 239 95 112 133 161 248 7 69 77 160 179 10 214 118 130 47 36 196 113 185 107 12 184 128 166 184 156 240 64 39 22 137 148 42 166 209 186 106 148 29 222 181 182 12 140 98 107 232 202 192 126 214 67 12 90 3 7 248 95 36 76 59 188 66 63 98 47 55 72 103 196 189 55 155 89 36 43 7 171 26 228 14 129 26 180 143 57 83 243 131 55 10 86 141 23 182 84 53 42 118 71 72 221 140 17 103 43 14 243 168 38 236 161 104 222 196 131 99 100 2 95 182 238 89 158 129 168 152 135 33 197 190 201 123 56 211 17 219 71 63 164 17 28 210 229 135 70 215 21 37 111 40 118 238 71 231 185 92 225 238 138 15 196 191 125 76 175 41 229 73 155 45 56 91 234 166 249 104 4 179 127 38 179 30 101 157 148 54 199 109 249 21 239 65 56 118 173 182 77 172 225 67 185 168 180 146 85 179 50 125 131 216 129 42 197 47 124 221 171 199 98 155 4 245 181 64 165 225 148 159 88 65 126 225 27 188 72 65 126 66 80 88 14 250 23 35 36 212 224 92 173 32 66 193 212 120 244 150 156 45 75 143 253 186 160 103 148 110 138 210 209 163 125 11 126 208 172 225 255 129 97 133 7 117 173 34 14 198 74 241 119 114 179 69 78 241 172 212 89 124 91 120 8 205 235 82 98 142 194 32 245 179 201 44 162 110 214 68 254 158 4 147 19 254 191 118 156 232 12 254 184 209 40 217 121 173 182 158 0 168 203 19 227 183 248 42 166 119 134 20 184 72 174 2 197 58 133 29 213 233 74 101 1 85 71 25 150 55 32 225 207 234 168 1 132 48 188 104 84 53 145 212 222 88 12 164 128 218 29 207 78 77 249 16 88 28 232 164 142 192 159 5 8 135 38 217 75 132 1 169 131 180 254 194 85 160 186 146 180 24 82 91 133 163 169 12 134 152 70 138 133 74 186 173 245 88 137 116 233 235 3 118 28 107 126 133 54 54 53 235 170 9 149 65 194 190 72 136 43 247 87 106 245 14 28 216 174 131 61 75 2 32 48 18 90 42 185 42 139 107 94 143 236 239 204 214 131 5 194 198 84 239 253 129 60 182 156 134 15 194 224 152 87 64 148 238 6 49 222 188 124 178 199 34 127 212 174 139 147 19 174 19 177 25 35 173 239 20 162 133 142 35 21 226 49 117 215 117 82 150 137 206 32 224 106 132 88 229 130 225 121 252 199 118 93 193 14 161 171 76 13 36 30 78 89 226 51 243 117 178 220 71 194 253 155 147 117 169 112 214 170 151 80 176 47 113 137 200 71 128 223 66 205 149 141 14 174 254 215 224 212 209 129 71 42 114 80 117 179 6 107 207 86 126 92 5 186 201 125 182 1 242 50 66 210 232 200 192 245 137 242 31 142 235 147 161 97 3 161 124 80 122 86 211 86 19 222 78 188 48 94 226 5 28 139 115 71 189 71 214 76 63 3 208 118 242 103 42 218 166 31 193 172 90 1 221 207 45 41 132 69 109 253 53 20 18 46 39 129 112 108 97 15 218 100 16 0 87 235 39 246 68 156 112 218 135 240 49 235 29 171 113 255 41 197 77 237 159 181 64 19 122 215 56 164 218 187 2 68 137 251 240 202 132 181 223 81 212 100 47 233 101 78 16 141 85 48 151 108 6 121 86 47 13 210 187 225 178 157 228 22 177 139 131 77 189 136 67 214 106 21 35 156 24 206 241 20 160 172 42 105 163 82 42 95 198 28 128 214 182 183 18 226 9 84 238 73 67 7 6 79 149 143 81 6 165 26 204 217 230 127 245 25 64 156 2 31 40 230 31 152 83 16 27 19 48 88 183 13 234 44 214 230 142 115 130 245 184 253 244 91 188 169 175 129 42 172 27 94 36 204 250 103 164 187 225 237 171 117 127 191 201 200 10 17 53 9 251 134 12 155 134 192 93 150 96 13 18 25 200 160 243 9 207 137 253 198 235 76 86 159 204 94 141 69 7 244 119 142 65 54 80 199 204 199 217 168 184 53 128 33 0 165 165 165 165 1 0 0 59 0 16 181 174 127 194 181 175 1 132 0 0 28 169 0 0 43 74 0 0 0 0 0 11 142 68 0 0 2 170 0 0 1 124 0 0 0 0 15 0 83 113 117 101 97 107 65 112 112 46 114 0 1 36 38 84 69 88 84 67 87 73 69 1 0 3 192 0 1 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 1 154 0 0 0 105 0 0 0 0 15 0 66 193 212 165 47 158 101 198 187 5 232 62 137 252 56 69 246 56 206 7 115 110 186 70 46 70 112 68 98 27 12 96 93 177 126 138 205 129 15 225 200 70 141 184 144 238 51 187 21 2 100 253 33 237 17 99 201 74 232 168 36 57 93 93 223 103 146 181 14 19 20 203 255 77 196 6 172 46 213 244 253 180 118 156 135 21 216 169 140 101 119 170 86 133 3 176 82 146 129 56 164 43 198 114 16 66 193 212 157 170 210 35 52 27 93 136 197 106 52 54 31 166 122 205 231 32 32 112 160 40 138 126 3 77 99 4 251 242 199 125 87 169 103 99 226 123 60 70 128 113 18 28 85 6 189 121 109 31 26 249 161 83 169 157 62 74 239 8 51 45 186 94 58 49 252 46 209 169 153 202 106 248 205 178 15 4 139 59 160 209 168 125 168 73 48 103 120 110 199 109 171 159 179 239 33 94 118 136 247 133 234 179 177 46 218 151 77 116 44 159 93 94 44 99 70 93 125 137 53 84 131 32 59 239 13 28 34 65 92 91 104 119 79 119 174 134 219 228 67 30 37 182 200 207 220 0 237 187 20 146 233 200 152 182 39 167 14 242 53 180 240 195 154 154 94 91 182 52 134 249 136 119 67 194 147 228 97 60 211 48 22 65 190 202 99 103 114 208 10 131 161 3 87 31 64 250 4 254 133 169 217 77 183 225 106 142 240 240 180 146 248 39 192 170 88 102 69 95 13 89 148 174 206 78 162 131 133 161 167 150 32 158 248 178 173 101 227 217 102 143 206 171 62 75 41 237 239 9 58 126 14 226 107 122 250 208 40 209 10 252 105 101 26 155 10 18 126 136 104 210 186 8 64 134 82 245 212 110 151 241 61 69 16 181 128 165 251 123 137 63 121 161 161 183 56 176 164 4 136 161 23 48 88 225 129 48 129 37 151 67 233 215 152 90 89 82 27 227 240 224 102 238 138 80 14 201 181 17 19 136 193 127 207 108 171 212 101 238 237 175 10 248 251 8 248 107 203 87 203 119 235 140 103 161 208 168 170 55 199 88 185 214 52 170 233 214 179 94 170 196 230 181 174 40 0 165 165 165 165 1 0 0 62 0 0 181 174 119 219 182 173 176 230 0 0 40 248 0 0 56 227 0 0 0 0 0 14 90 72 0 0 0 0 0 0 0 0 0 0 0 0 0 0 83 113 117 101 97 107 65 112 112 46 114 115 114 99 0 1 110 211 114 115 114 99 82 83 69 68 1 0 255 255 255 255 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 40 111 0 0 13 41 0 0 0 0 15 0 66 193 213 19 32 207 221 161 198 69 165 49 49 163 44 68 182 220 208 98 3 104 90 104 50 121 149 179 221 229 227 218 24 177 155 55 76 59 170 223 31 186 42 107 230 227 232 78 210 112 78 144 78 101 153 20 100 21 113 34 86 121 4 82 215 232 227 236 158 8 177 190 230 223 83 84 237 148 7 170 219 251 49 107 209 121 95 19 142 221 245 229 208 93 102 171 66 93 51 91 15 192 115 41 146 47 38 44 128 149 206 19 73 214 243 63 134 185 162 63 190 209 118 46 232 38 160 233 103 92 179 67 170 147 238 96 5 178 108 31 198 142 27 71 0 252 18 157 84 217 115 240 55 138 8 134 100 181 201 91 154 43 221 56 198 203 54 203 223 246 78 211 75 62 202 147 101 108 145 98 255 87 81 19 116 84 105 20 53 35 186 106 250 114 137 91 30 167 101 76 166 46 241 174 167 210 92 15 66 47 106 89 111 95 216 169 157 97 204 203 175 67 131 100 228 115 101 202 102 201 85 197 128 102 224 152 248 208 22 182 13 65 185 43 236 146 8 103 164 68 199 167 90 161 44 115 100 75 148 212 133 205 185 240 91 254 62 54 53 239 150 84 98 211 70 114 120 183 103 103 115 93 178 126 224 111 251 255 187 2 190 193 166 28 139 27 108 150 55 252 38 95 40 204 61 97 2 5 127 120 0 243 229 135 147 150 124 152 226 200 238 110 10 181 117 118 31 112 88 72 144 14 237 207 92 110 48 130 189 1 231 108 15 115 142 33 243 63 70 202 105 190 33 106 49 249 174 151 46 242 184 92 27 85 108 8 61 186 25 204 238 168 23 220 122 57 26 0 94 219 160 117 212 36 110 61 85 13 72 110 98 228 52 153 35 204 126 98 140 89 197 33 115 94 246 29 46 207 110 59 178 37 214 135 84 26 226 172 61 164 37 249 132 232 36 135 159 231 16 215 37 60 234 247 241 168 243 58 72 46 41 220 66 76 33 145 234 176 69 142 127 25 0 95 144 67 47 251 134 209 37 54 146 89 34 177 76 177 86 69 39 60 252 204 11 215 43 181 181 62 7 207 200 27 52 88 45 191 95 136 245 143 36 198 200 96 212 14 34 44 75 92 179 19 205 21 61 183 249 19 14 90 152 106 128 109 207 18 193 125 216 221 102 13 243 3 207 160 48 121 221 140 131 189 1 167 100 183 37 16 148 140 51 150 130 119 146 90 59 119 2 56 252 58 58 98 132 210 172 193 250 110 130 138 137 30 148 194 169 174 215 165 40 214 232 9 99 113 176 246 152 29 216 37 136 174 72 22 25 32 70 176 136 185 148 59 152 164 218 63 103 164 113 113 196 204 74 198 179 199 228 6 0 114 86 130 58 205 68 187 219 142 213 80 170 199 245 139 50 148 199 98 205 8 97 101 52 62 74 229 238 194 230 110 113 96 157 29 204 242 231 195 253 8 5 235 178 77 239 179 21 108 203 6 194 88 118 245 33 204 30 20 82 30 32 55 147 64 253 61 81 114 208 183 177 48 254 58 177 183 123 204 111 181 141 184 209 186 179 252 157 93 141 160 18 67 11 232 124 221 48 166 117 213 18 90 154 139 77 48 247 153 128 76 164 54 63 183 28 6 56 230 28 53 43 11 186 53 127 239 253 146 139 15 49 104 164 75 167 114 206 42 92 242 191 197 189 12 26 237 123 125 2 253 32 66 21 77 82 157 188 198 133 31 137 152 205 155 31 114 9 21 165 217 37 236 104 60 146 152 234 138 79 210 179 211 151 106 72 226 73 67 64 228 198 114 114 84 176 53 72 173 185 2 211 169 3 115 200 32 3 123 86 25 16 169 20 62 221 52 102 24 40 64 141 101 250 121 195 75 52 16 152 106 112 79 90 114 59 17 28 98 106 134 67 70 136 222 131 242 137 208 231 99 120 104 242 246 64 25 254 24 205 51 247 57 90 154 34 167 8 114 32 158 82 228 140 160 233 22 142 139 80 11 101 80 227 174 113 44 94 75 214 131 153 27 175 183 181 253 38 34 40 245 29 62 108 66 41 212 152 86 19 19 20 202 150 208 29 4 96 75 98 102 135 162 68 88 71 49 79 157 209 161 24 143 37 127 118 52 145 239 197 75 212 102 223 121 41 229 116 244 33 182 113 183 17 64 172 29 152 149 170 116 196 107 13 38 62 209 25 127 166 48 203 162 218 215 176 183 240 17 240 68 188 58 14 75 52 164 12 29 22 172 196 55 49 50 136 184 202 249 93 93 62 24 247 91 114 46 129 80 29 243 249 237 168 117 231 124 113 76 69 174 237 128 35 97 12 128 208 115 100 254 26 138 159 152 224 43 116 104 219 61 202 83 25 210 255 105 97 156 233 202 8 202 248 184 32 5 69 149 237 178 18 246 246 73 124 34 25 28 148 236 140 12 232 62 145 79 208 141 233 154 198 41 67 61 90 103 133 96 151 62 175 6 239 206 135 93 115 213 94 61 54 229 106 177 229 7 96 214 221 210 61 152 194 165 83 50 184 40 114 196 125 38 13 164 195 104 113 22 80 73 143 37 199 164 130 172 133 217 21 44 180 159 107 8 103 46 139 210 146 97 254 27 70 148 79 84 17 117 19 243 201 136 245 199 200 192 51 255 109 56 166 154 164 247 236 43 48 136 139 0 254 126 146 13 84 128 44 45 25 184 226 169 250 92 50 160 127 93 238 32 214 193 198 204 174 4 218 231 32 147 151 157 27 207 24 125 242 113 208 159 200 119 123 218 166 231 20 255 61 129 246 104 147 204 212 111 79 85 163 182 249 19 208 77 2 114 235 94 110 70 142 158 75 203 114 119 248 103 107 19 110 40 20 8 24 93 54 182 152 35 152 248 105 96 165 68 30 124 195 179 122 47 108 23 65 39 171 89 232 73 60 201 214 80 54 100 38 79 146 243 109 145 81 26 243 227 235 65 95 135 162 63 141 58 105 245 185 184 239 226 116 205 239 174 38 47 189 69 83 190 10 16 2 17 54 22 191 16 103 3 158 14 137 245 70 136 183 14 206 185 63 233 96 179 113 162 133 51 233 170 53 61 88 138 22 79 138 162 120 45 66 64 22 130 164 82 243 43 51 135 153 159 127 236 139 68 55 180 187 166 48 173 196 216 135 24 243 248 164 157 215 52 148 182 255 75 234 201 90 77 39 227 114 119 28 112 89 103 23 241 59 103 125 131 121 26 198 122 89 43 59 21 153 189 83 96 14 93 126 36 17 249 201 21 163 150 23 114 116 90 250 233 233 49 76 153 73 185 134 125 119 129 133 150 184 228 87 204 105 9 171 251 236 85 52 117 204 251 101 16 53 147 26 238 14 194 104 141 152 67 145 37 255 146 198 6 165 51 208 199 143 157 9 34 191 219 103 97 137 121 4 40 8 134 14 13 130 149 89 220 91 47 51 14 210 62 33 153 208 118 18 135 134 120 214 198 141 10 45 27 207 97 94 238 246 179 177 113 70 242 189 92 204 194 184 157 247 120 25 173 143 67 181 75 25 68 237 149 189 240 197 221 226 215 122 16 244 141 138 59 177 10 10 124 15 108 116 23 55 171 152 248 17 205 41 1 56 131 194 90 151 0 60 99 226 103 224 73 189 30 14 229 125 31 186 195 194 19 184 66 81 108 163 177 148 80 251 249 64 193 52 221 192 58 150 174 98 248 83 18 184 78 23 56 218 243 192 57 119 244 2 147 198 164 123 43 1 193 197 241 170 217 41 199 215 204 37 120 83 111 250 109 111 2 183 73 140 71 163 178 60 9 113 189 165 205 67 146 234 239 17 250 219 151 139 173 117 241 47 46 142 71 160 242 4 220 237 224 224 59 31 89 213 232 18 77 88 249 110 242 12 240 106 215 143 136 58 144 83 55 154 143 170 96 29 7 244 62 208 209 228 52 134 152 32 140 194 146 136 192 74 198 141 145 116 221 40 217 146 33 125 199 117 118 184 117 170 137 197 199 53 72 244 88 74 46 24 237 114 19 128 24 243 117 65 20 226 81 155 229 142 201 254 1 12 233 55 74 239 139 107 38 56 143 37 84 3 245 78 106 146 121 225 218 151 93 255 151 61 130 87 217 103 20 197 8 164 67 3 73 118 206 25 217 224 39 135 77 150 127 90 115 96 217 155 87 176 91 124 16 180 204 83 12 90 62 219 60 168 115 122 206 215 100 94 78 107 48 195 144 192 178 44 80 209 79 0 116 206 163 42 248 103 212 213 169 65 182 233 220 223 161 149 99 225 83 71 208 190 233 84 120 59 69 178 151 17 62 38 228 236 205 86 48 214 202 235 99 205 121 178 240 254 49 136 193 115 7 189 14 211 188 132 3 27 60 114 9 254 204 215 34 183 108 41 247 102 43 129 50 221 20 50 124 119 127 59 6 97 65 223 155 51 117 243 9 40 120 74 225 234 95 44 149 183 69 159 101 89 106 41 67 245 119 0 201 17 166 33 129 113 40 18 178 8 117 97 43 204 1 57 177 241 23 66 112 238 143 198 92 93 185 95 35 47 51 209 246 148 68 191 158 182 68 145 16 17 2 125 235 188 169 146 154 246 79 194 66 2 172 27 54 165 224 175 171 250 237 62 112 83 82 87 49 184 220 221 46 126 23 229 97 52 12 45 81 248 178 95 153 81 111 219 45 225 129 76 175 171 204 93 166 101 223 239 68 182 94 158 15 94 12 130 13 5 78 84 191 86 78 75 26 91 167 213 69 170 157 229 210 149 207 23 218 36 83 141 136 189 85 125 142 63 99 156 42 129 115 38 192 176 34 39 234 126 94 239 245 51 193 207 158 193 66 198 182 235 65 114 53 59 46 236 167 39 146 122 94 150 78 217 189 62 201 104 38 189 244 205 100 136 162 153 79 53 248 23 54 116 136 135 172 42 118 171 200 179 240 227 88 147 115 136 190 39 169 155 53 255 156 167 49 75 87 63 92 112 210 235 138 246 204 251 57 49 209 240 185 152 95 24 214 221 160 255 131 230 79 191 79 160 199 110 14 111 241 125 169 226 7 67 10 84 222 77 241 221 110 70 43 247 255 130 122 120 124 197 31 23 91 17 86 59 145 6 100 157 14 155 161 237 26 115 251 200 169 167 200 150 193 91 36 80 100 75 166 144 82 119 66 39 112 231 23 48 43 56 175 81 52 145 107 185 183 88 231 8 227 54 90 237 198 213 16 150 206 67 235 144 175 14 212 249 224 173 137 122 212 172 231 52 8 111 80 253 78 84 255 222 96 205 52 160 221 159 45 162 64 157 86 42 223 16 34 139 245 169 30 23 172 191 71 71 254 179 58 22 66 215 10 211 37 128 39 210 174 230 144 16 11 37 119 52 115 185 177 159 249 129 224 68 81 114 197 196 206 226 7 32 77 205 22 99 163 91 112 116 108 133 85 174 235 63 220 239 185 56 25 84 42 147 246 110 233 252 252 85 219 137 27 69 126 176 213 69 186 236 197 186 49 118 195 43 36 172 52 1 114 229 111 130 108 67 156 210 169 35 52 215 63 28 75 245 107 230 170 1 221 223 45 158 43 32 79 207 78 95 44 251 179 56 175 78 44 18 41 201 88 33 35 99 103 23 198 110 5 16 31 199 254 214 79 96 103 182 246 137 162 243 230 50 179 88 238 71 79 86 173 114 181 20 245 203 13 182 251 245 116 98 194 194 254 159 126 202 72 58 101 201 170 157 50 206 156 239 217 159 207 55 50 144 248 14 226 177 70 15 223 29 214 233 173 134 248 127 91 39 85 87 51 164 198 191 87 51 93 244 241 48 187 124 231 52 75 21 218 8 200 5 149 128 5 54 129 208 72 0 208 105 232 101 57 19 170 207 145 167 63 8 222 92 217 219 59 129 44 94 83 26 217 172 191 126 180 26 30 95 3 192 68 125 18 55 100 187 8 175 44 164 226 144 147 191 123 129 57 240 149 220 94 149 29 163 17 150 37 16 187 197 180 103 80 51 197 234 197 193 249 172 195 109 74 234 244 8 240 247 84 103 152 97 203 89 42 129 29 50 218 146 109 144 22 128 189 128 166 129 83 29 232 195 231 160 65 25 122 213 171 137 205 246 3 128 216 235 8 222 12 133 158 177 159 190 211 46 216 70 178 43 129 225 179 155 124 116 29 255 152 23 194 230 104 145 116 97 108 243 62 203 13 48 136 194 237 186 178 99 199 159 113 103 228 91 147 124 241 51 19 234 50 111 235 42 146 209 212 84 2 183 99 51 107 158 177 135 136 24 174 94 178 91 20 208 30 135 78 119 247 226 68 220 244 87 96 55 38 87 230 44 215 13 214 235 19 14 162 129 14 69 148 193 220 121 118 102 163 18 197 164 114 179 152 84 220 87 141 199 182 156 218 118 238 66 11 22 245 27 32 211 201 45 50 116 150 165 243 39 115 197 7 109 130 126 75 57 148 184 85 14 106 168 56 166 23 17 218 5 145 55 92 57 127 176 192 137 34 32 40 1 204 107 133 175 95 145 32 132 112 196 116 25 56 110 130 147 47 108 0 180 70 17 89 61 43 8 28 197 144 18 40 223 50 248 73 88 94 116 29 105 174 82 92 238 187 216 132 121 201 233 113 20 40 106 3 29 120 78 102 164 122 43 104 35 46 105 98 236 224 71 96 68 22 114 143 79 39 56 251 236 79 175 79 142 3 94 240 223 117 134 232 191 38 183 136 197 91 60 20 214 131 147 90 210 140 51 216 11 203 198 221 53 251 235 102 115 226 31 15 159 142 212 11 241 110 217 107 90 217 226 135 175 17 92 163 71 184 178 2 112 255 157 115 60 215 18 132 136 181 119 56 153 109 62 41 189 66 145 96 183 188 94 149 169 56 64 117 52 142 18 113 212 185 41 178 110 183 31 196 109 177 53 196 228 58 161 130 130 102 157 109 45 225 191 53 182 218 240 124 189 11 17 117 195 34 211 211 174 123 80 142 182 115 13 161 21 25 162 254 27 6 35 87 140 107 12 218 10 253 176 127 254 195 134 39 121 248 223 186 32 7 139 160 60 106 242 174 240 227 139 119 254 87 204 28 232 6 160 233 26 237 216 83 218 108 170 162 2 208 175 49 65 172 219 98 212 244 146 236 45 217 58 45 201 186 220 59 94 237 103 100 30 240 253 122 224 159 137 26 123 224 82 160 255 177 94 215 96 55 85 13 56 206 199 59 20 93 73 144 38 185 64 104 1 112 237 147 156 213 206 235 125 220 228 214 3 37 132 0 14 40 26 47 50 78 133 109 246 58 86 119 96 11 181 217 22 78 232 35 22 221 75 167 139 85 210 152 1 161 197 212 244 81 26 101 92 206 250 162 73 181 59 181 117 174 250 87 197 90 48 215 134 141 180 134 93 236 137 72 21 113 108 157 206 69 213 252 9 218 62 92 93 88 221 154 9 172 219 88 47 59 188 38 85 144 129 247 110 239 220 148 208 4 235 30 148 181 130 37 75 81 4 111 137 198 113 251 45 50 34 206 238 173 142 222 96 153 130 144 73 71 158 134 199 144 0 165 165 165 165 1 0 0 68 0 0 181 174 119 219 181 183 37 82 0 0 43 74 0 0 57 143 0 0 0 0 0 20 182 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 83 113 117 101 97 107 67 97 114 98 111 110 65 112 112 46 114 115 114 99 0 1 224 122 114 115 114 99 82 83 69 68 1 0 255 255 255 255 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 1 56 0 0 0 54 0 0 0 0 15 0 66 193 212 120 70 64 63 99 16 59 255 97 202 132 145 70 204 255 242 147 131 117 178 216 188 111 47 148 73 157 252 231 185 213 153 225 248 22 106 46 220 74 229 99 130 75 44 98 229 175 219 67 79 64 165 165 165 165 1 0 0 68 0 0 180 207 51 128 182 173 176 245 0 0 56 227 0 0 59 145 0 0 0 0 0 20 130 54 0 0 0 0 0 0 0 0 0 0 0 0 0 0 83 113 117 101 97 107 73 110 66 114 111 119 115 101 114 46 114 115 114 99 0 1 62 107 114 115 114 99 82 83 69 68 1 0 4 0 0 129 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 1 255 0 0 1 140 0 0 0 0 15 0 66 193 212 190 116 19 225 40 139 5 15 124 31 121 65 93 191 82 76 171 251 157 66 200 64 87 145 197 77 232 218 8 241 108 103 240 196 61 210 179 140 69 232 233 177 174 46 80 119 27 238 33 51 89 171 126 13 159 132 209 13 194 163 156 2 170 37 126 170 107 61 193 112 17 158 254 189 0 201 149 74 164 219 180 202 21 163 218 62 72 166 33 184 145 88 101 208 108 141 134 74 181 47 78 33 207 230 160 228 242 198 73 48 108 241 5 190 178 204 200 174 125 149 147 54 3 24 78 133 142 149 43 233 31 38 232 49 155 10 172 82 101 56 101 216 47 13 47 240 86 216 215 6 154 32 249 238 14 0 223 208 191 239 86 146 44 66 173 189 39 216 56 120 26 89 209 81 179 146 216 3 64 44 246 78 118 148 10 225 147 86 40 91 147 86 108 222 149 206 177 235 163 21 138 209 120 246 131 203 157 128 252 78 37 205 32 178 18 184 243 215 38 90 212 83 211 30 127 151 202 202 221 49 91 61 33 97 235 1 243 163 199 157 46 120 89 133 172 54 27 248 124 251 167 28 100 77 61 229 94 124 62 44 143 72 56 193 117 30 159 9 82 114 236 34 120 226 180 194 119 48 7 194 95 14 67 155 7 246 173 0 105 157 37 201 232 211 190 205 63 23 252 46 132 246 105 237 248 144 246 153 163 198 200 38 90 241 197 38 231 229 163 169 117 91 40 214 30 185 111 123 91 153 153 131 219 43 12 101 113 91 152 143 221 3 116 103 52 247 98 209 203 95 49 28 103 14 140 87 214 32 168 47 53 68 157 234 38 3 131 153 42 202 113 55 109 48 138 38 137 238 254 43 36 171 30 165 110 234 220 33 200 10 93 18 208 165 165 165 165 1 0 0 62 0 16 182 173 188 122 182 173 188 122 0 0 57 143 0 0 0 0 0 0 0 0 0 14 119 160 0 12 213 19 0 0 49 198 0 0 0 0 15 0 83 113 117 101 97 107 80 114 111 53 46 120 109 108 0 0 99 190 84 69 88 84 67 87 73 69 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 66 193 212 254 252 27 63 143 188 103 118 108 165 221 169 237 116 200 1 124 16 229 32 96 32 163 69 255 112 3 193 121 185 58 62 97 46 156 40 55 99 245 205 237 59 135 141 131 54 74 167 223 253 245 141 88 83 10 202 233 203 120 112 181 102 55 17 248 251 173 132 156 120 20 16 103 44 248 173 58 110 91 202 183 224 30 248 120 15 47 41 213 81 86 201 40 36 149 68 12 86 85 27 35 210 16 56 66 190 221 0 235 153 158 15 253 123 22 138 185 195 25 4 23 41 88 53 242 136 251 116 35 67 220 201 155 132 216 128 175 144 87 35 163 35 234 232 248 37 59 119 191 62 206 13 245 92 94 231 134 143 160 229 151 215 224 127 65 124 31 100 215 89 59 28 48 101 76 167 195 210 227 223 12 31 194 224 61 123 150 183 51 189 253 139 105 223 38 46 26 168 195 51 137 250 230 127 80 64 65 109 210 67 210 32 217 185 237 21 90 100 162 21 54 176 225 226 130 191 163 13 220 97 147 99 66 16 203 54 46 169 198 16 24 14 78 126 232 44 55 0 146 104 233 77 175 0 117 146 102 37 88 91 36 181 232 241 238 140 168 248 173 146 89 64 133 109 160 96 31 128 47 157 112 130 5 195 166 165 67 252 175 73 247 129 170 236 123 39 114 71 130 52 155 80 227 81 98 104 245 193 0 195 184 232 133 103 202 47 69 244 65 255 4 15 164 87 243 98 98 173 40 92 176 207 128 105 154 168 12 46 205 104 172 67 21 99 0 239 171 93 23 196 98 198 75 97 176 50 122 164 64 245 194 137 127 21 253 107 86 212 187 255 110 200 6 203 54 29 103 71 32 62 149 21 13 225 1 95 157 166 156 85 83 113 175 28 156 141 92 42 240 55 190 64 239 189 99 184 91 229 92 26 184 29 230 155 232 204 113 47 10 75 5 74 74 119 28 12 209 234 85 207 171 127 173 85 244 159 111 93 194 70 77 251 10 17 243 94 50 246 25 236 22 46 52 90 126 244 120 227 28 72 100 37 173 1 228 238 84 170 255 29 17 137 246 78 29 53 184 85 42 22 165 103 112 174 16 111 29 211 175 54 106 156 151 29 185 54 247 236 0 54 209 61 32 16 3 164 126 49 108 196 61 159 149 25 31 119 129 244 119 9 229 205 198 197 159 251 190 157 42 138 213 159 9 255 101 87 76 7 135 55 76 46 134 143 208 127 82 241 114 103 135 54 195 147 98 248 15 23 178 104 137 93 212 97 162 101 239 50 209 219 112 199 54 210 255 25 168 27 200 143 249 126 125 58 191 203 239 110 103 18 157 24 214 252 158 91 172 199 6 54 179 121 199 88 166 156 176 197 190 139 24 163 216 203 3 39 98 14 229 27 29 193 189 243 196 204 147 10 131 133 8 228 67 119 231 165 203 152 169 181 224 194 43 35 228 70 3 74 148 169 16 148 219 213 167 72 175 191 157 94 56 153 143 55 236 0 111 204 47 215 207 144 58 249 180 201 148 192 153 30 162 69 178 94 25 90 241 85 59 37 173 10 209 39 220 23 191 154 80 77 35 156 109 103 100 255 183 166 175 2 4 196 209 163 205 79 165 241 228 131 128 246 107 175 140 232 34 134 204 230 74 155 216 34 105 97 34 108 243 235 73 153 168 110 243 142 1 156 251 217 88 16 176 227 104 141 242 222 44 121 130 175 126 71 193 172 133 82 26 31 161 248 38 218 187 203 219 90 240 142 119 18 225 236 51 86 11 92 155 217 168 109 45 53 52 200 109 165 33 68 64 114 233 238 200 90 236 32 75 122 93 76 81 72 14 165 220 204 159 101 70 3 84 127 249 65 93 86 236 25 157 246 179 49 11 147 44 46 200 124 158 10 98 122 249 73 202 223 202 48 71 110 225 49 182 138 182 32 68 95 39 117 141 2 99 244 252 111 9 226 248 73 224 70 144 147 241 227 23 99 185 70 106 194 243 254 175 5 137 188 205 32 9 69 156 34 75 157 65 107 201 106 255 244 23 202 38 124 172 6 190 200 157 119 172 29 194 196 96 58 26 180 131 116 130 178 169 56 84 106 1 24 64 142 41 26 208 221 69 233 75 100 86 66 244 235 136 53 5 125 51 252 132 27 110 74 211 173 149 111 200 16 173 240 22 208 10 83 160 60 104 225 167 54 110 241 22 208 240 42 228 114 79 254 92 20 54 113 158 193 147 14 250 95 32 75 88 80 137 214 198 8 24 171 250 231 26 125 198 8 63 226 166 0 66 199 36 136 42 209 138 159 116 247 243 219 132 125 76 245 231 16 92 28 135 182 186 120 94 10 49 169 92 27 107 86 187 113 248 169 172 69 100 147 121 7 227 218 89 130 69 135 49 195 32 7 225 248 191 95 252 0 70 163 189 254 201 209 158 150 157 167 10 232 99 109 190 222 179 211 32 167 155 255 81 21 86 226 55 68 241 18 152 142 62 202 179 146 211 75 0 201 95 62 231 212 42 10 39 11 243 161 208 142 26 77 172 1 249 102 225 75 28 229 46 41 73 182 27 144 162 118 26 76 176 65 153 48 83 88 212 211 132 143 32 255 68 207 4 133 34 153 235 84 130 229 230 155 211 210 52 135 31 8 69 144 180 160 18 175 49 161 71 151 96 169 230 152 179 115 220 152 253 215 64 176 136 220 84 248 157 119 197 14 54 13 227 202 101 123 117 13 135 81 48 194 250 164 55 184 161 194 132 100 28 159 114 132 156 245 132 94 240 231 175 105 39 66 143 48 90 8 210 101 70 114 55 178 225 142 120 194 182 222 75 104 0 103 84 163 231 184 53 11 92 205 120 218 223 158 199 130 238 172 197 128 185 24 248 22 85 251 63 19 16 209 246 13 168 231 42 254 103 160 42 242 12 194 17 146 14 148 202 4 250 203 237 181 236 43 35 53 113 89 34 131 81 203 161 177 248 12 166 216 197 86 16 56 246 181 69 106 88 73 254 119 107 89 180 4 5 37 106 198 129 50 46 87 226 247 196 56 189 71 255 63 171 147 15 96 105 214 187 89 76 149 164 184 89 106 92 252 58 59 3 193 196 155 17 125 140 113 135 12 220 16 26 212 58 204 157 126 113 82 43 12 62 122 239 172 61 98 179 225 56 84 80 191 64 200 239 111 31 198 44 131 24 148 252 33 228 152 208 136 58 74 245 166 114 155 100 209 183 153 8 39 62 221 244 217 34 64 88 222 172 209 87 91 188 233 56 19 64 167 189 42 186 101 88 186 179 84 34 8 157 142 146 92 185 117 207 48 243 181 154 210 99 149 11 200 39 41 125 162 221 223 197 18 20 134 254 171 48 125 229 29 104 244 207 208 242 175 19 59 79 129 90 164 251 213 230 13 88 33 25 27 140 8 28 249 38 160 124 252 31 125 195 89 55 93 183 171 199 245 228 200 37 180 191 140 171 89 122 242 214 126 216 78 183 53 241 106 60 129 207 141 192 231 252 20 171 102 245 130 2 116 156 112 162 137 101 21 201 158 161 137 233 119 139 9 111 203 46 222 211 239 242 103 9 82 248 65 15 152 125 55 132 19 212 54 228 151 35 186 188 35 113 182 222 250 139 93 39 235 21 17 14 76 29 243 64 93 134 110 34 178 17 224 165 148 144 133 155 23 28 81 52 216 202 219 17 78 230 91 86 180 156 51 155 12 103 169 214 153 14 175 126 139 66 202 132 126 98 25 111 174 214 20 4 186 180 156 67 9 150 162 11 179 241 230 2 113 40 22 225 84 68 222 199 47 168 112 250 215 20 4 92 24 24 235 245 88 28 174 106 251 129 128 133 204 83 11 56 73 189 171 243 131 20 68 191 187 24 142 244 239 163 248 88 42 250 74 226 173 251 94 1 212 83 232 242 126 239 64 210 147 43 189 83 107 64 198 58 51 1 132 194 100 193 0 157 176 32 214 165 51 185 30 141 41 53 53 112 152 178 169 58 59 183 209 254 77 94 26 21 15 216 239 46 215 91 158 14 149 155 186 19 102 117 59 144 203 151 218 185 30 165 249 92 178 229 140 31 155 117 139 69 61 239 85 106 78 14 190 125 130 253 49 4 73 11 166 56 116 147 160 243 130 152 132 88 73 173 228 190 15 186 215 11 178 198 45 168 87 193 72 73 82 88 206 76 126 111 25 182 19 84 167 88 69 17 198 63 117 162 26 245 219 243 21 50 111 122 190 218 193 138 59 192 163 92 164 218 4 19 76 130 195 4 246 10 3 188 118 67 143 33 115 6 47 65 1 21 81 48 39 230 48 78 52 232 136 146 224 44 247 70 12 216 29 198 17 54 140 186 127 196 78 226 142 150 82 121 167 151 84 104 148 234 135 24 223 160 75 214 191 157 134 80 85 168 154 238 96 186 247 121 152 63 53 10 243 147 249 250 186 38 220 46 212 179 52 226 116 52 194 250 98 101 215 9 84 162 54 117 221 21 103 219 195 142 113 109 184 114 212 216 132 88 127 25 86 198 171 15 68 33 146 137 107 175 147 190 225 89 116 9 127 53 62 132 154 154 146 67 142 235 24 160 170 131 140 149 157 191 108 121 34 226 84 118 163 101 168 133 26 41 75 154 122 158 250 182 195 226 112 204 13 8 16 116 77 151 108 194 248 17 230 15 181 133 80 197 194 193 222 82 151 242 11 67 52 172 21 150 253 209 157 62 211 239 87 159 39 234 206 49 122 81 108 204 25 196 199 155 173 126 200 6 217 168 112 237 76 188 137 17 246 34 72 177 44 1 229 241 159 0 179 34 172 95 154 124 219 49 78 69 73 168 56 22 103 211 8 204 241 103 65 76 161 148 62 81 184 53 162 153 225 230 215 242 231 12 61 254 202 73 57 252 34 116 47 3 233 154 112 253 166 95 52 156 237 196 160 76 186 227 66 153 242 112 236 51 147 48 13 61 221 50 53 72 197 136 81 189 182 232 94 202 170 92 13 50 127 229 237 231 23 69 204 186 199 83 192 3 199 207 237 212 4 115 180 120 25 215 172 84 107 61 71 247 100 210 9 185 62 204 88 70 248 169 11 189 229 71 253 121 252 193 144 219 92 127 26 76 166 91 20 10 80 228 252 19 0 53 135 93 72 210 182 206 170 158 125 226 216 172 94 37 63 58 233 18 218 131 98 98 194 143 83 125 62 183 8 75 129 180 155 96 166 49 229 225 10 117 245 79 183 248 172 227 208 41 138 116 54 78 18 59 135 192 141 49 123 132 33 154 189 251 209 134 32 97 170 58 47 96 55 1 151 1 142 206 51 255 98 202 125 112 15 218 249 174 170 242 3 44 73 24 3 224 132 95 237 127 204 0 249 13 115 251 46 131 247 14 113 238 237 145 210 195 164 168 82 179 214 244 81 71 106 118 249 165 63 176 143 158 68 241 44 174 145 16 252 131 223 64 141 135 151 179 65 65 113 33 229 97 154 228 128 226 49 244 129 132 106 84 8 116 70 169 56 212 91 172 162 45 221 7 14 72 122 203 83 84 210 62 70 109 151 2 184 107 27 74 144 203 115 70 158 120 20 229 174 132 143 95 59 148 79 40 47 119 172 151 111 203 238 10 179 136 102 161 100 253 79 173 65 236 183 116 26 71 50 21 206 134 245 162 98 161 155 33 238 87 199 252 228 47 145 139 0 116 139 203 237 121 87 73 153 56 223 44 155 94 135 153 207 162 253 98 160 120 47 32 128 190 91 40 206 139 48 106 57 20 187 226 177 128 95 34 31 86 90 0 170 224 103 138 200 232 7 164 133 230 164 208 131 53 6 149 68 115 184 138 171 245 114 193 70 20 97 6 120 186 133 104 166 195 129 252 10 203 99 174 117 88 175 121 39 250 217 185 157 149 136 154 225 43 110 131 21 20 159 45 85 200 92 9 128 18 209 76 67 111 120 204 53 47 26 246 219 99 191 162 116 232 63 246 71 137 162 46 241 68 69 144 249 112 127 191 236 43 67 111 76 238 249 172 132 237 225 209 36 191 244 212 69 247 0 95 116 76 107 212 193 191 187 215 79 25 95 134 168 175 29 129 236 42 239 140 195 239 62 102 5 65 141 184 136 152 101 153 143 59 188 113 135 13 5 254 239 241 14 135 62 148 104 104 172 174 85 61 52 163 232 227 219 107 97 86 230 189 184 145 105 95 57 102 150 51 17 61 168 26 212 197 113 17 237 234 211 135 160 53 105 165 20 148 242 21 63 18 170 248 128 77 62 56 206 28 5 197 1 206 207 208 240 66 254 27 128 69 244 169 202 190 181 251 161 83 246 40 128 176 172 82 116 23 1 239 71 184 194 101 160 231 244 97 25 3 19 163 112 40 223 238 159 201 142 173 204 58 236 4 204 146 242 164 36 179 78 230 207 155 12 164 172 78 23 172 31 162 181 7 175 8 252 39 27 99 174 193 122 22 0 196 128 50 190 213 86 48 195 37 85 47 213 196 119 80 117 127 43 25 253 245 96 107 67 192 171 63 187 247 14 111 67 65 77 56 9 205 246 22 76 56 16 191 192 80 4 227 144 116 62 85 133 53 197 181 122 47 128 198 185 133 101 76 120 128 149 202 101 32 102 111 125 118 36 14 90 173 218 191 249 68 95 82 191 120 68 164 29 147 80 52 173 38 12 178 87 252 68 246 182 52 22 253 132 11 113 99 55 132 235 100 255 12 103 40 42 72 194 37 3 220 30 197 240 69 236 251 249 234 100 192 9 210 163 157 149 171 252 247 52 235 209 251 153 142 37 179 60 172 142 84 95 70 120 117 203 19 150 194 8 137 247 128 138 14 82 185 124 48 61 238 170 34 168 107 195 41 76 216 108 248 206 148 45 127 2 227 50 71 82 87 185 165 250 151 208 246 55 154 48 85 14 202 250 110 2 23 177 171 1 174 168 212 52 25 25 148 149 248 119 153 55 51 172 85 195 98 73 147 182 241 55 96 71 140 69 80 179 26 102 10 155 206 41 184 87 250 122 16 242 88 91 120 164 173 195 68 221 191 94 170 146 246 107 167 195 91 154 150 224 251 12 116 119 164 116 213 90 127 208 28 67 24 186 179 155 43 196 253 223 234 158 41 139 201 152 246 172 34 61 203 192 42 198 145 199 79 255 147 89 104 71 106 178 216 39 150 152 34 138 252 161 155 88 171 22 134 215 225 94 97 112 197 202 168 185 89 48 118 169 194 28 227 159 239 106 61 63 37 166 182 12 215 36 3 136 138 9 128 210 134 62 241 57 31 31 241 64 46 162 245 215 214 103 170 124 158 60 198 139 76 235 45 1 81 250 47 98 168 17 11 214 151 127 92 177 97 37 73 253 106 133 59 196 29 129 206 130 136 199 177 80 156 236 121 56 166 85 45 239 203 196 247 122 4 95 131 42 181 202 20 178 170 88 239 232 229 166 171 43 203 35 110 230 213 1 242 43 81 191 240 116 158 253 86 234 218 15 163 133 189 239 41 205 6 179 240 91 95 144 77 229 217 255 41 166 231 189 239 175 81 78 163 81 181 0 56 180 120 199 137 104 105 134 167 36 139 135 19 29 8 235 251 128 55 3 217 39 231 75 127 58 176 155 55 73 145 126 5 183 15 21 214 228 1 40 184 0 99 140 203 135 172 233 162 226 145 80 62 216 169 107 168 112 241 171 52 138 200 210 168 194 253 184 199 92 105 132 238 9 101 109 185 76 58 248 146 98 2 62 154 151 158 177 197 107 223 170 29 68 191 255 215 9 98 23 194 155 11 244 35 89 224 140 240 165 156 132 238 60 209 222 248 34 64 247 142 143 181 192 248 224 49 126 108 185 144 228 167 224 75 91 176 66 143 129 136 177 113 117 188 247 160 180 169 80 140 77 26 81 38 108 81 209 102 186 103 184 106 36 231 126 113 5 18 22 53 46 139 150 235 130 49 173 10 139 41 18 130 167 31 145 80 230 190 158 23 62 240 24 81 164 173 140 232 35 134 15 124 32 69 148 205 161 168 68 75 67 97 181 142 9 80 97 100 218 104 231 54 234 231 85 18 162 119 125 111 90 152 152 161 82 249 237 44 253 113 76 156 22 27 87 56 82 101 30 88 154 252 178 210 67 164 15 133 190 189 17 245 78 70 8 43 248 202 2 108 96 152 142 111 44 10 71 14 55 9 243 24 68 193 60 56 241 189 99 113 73 6 133 243 99 218 142 150 136 162 44 149 113 87 160 177 197 183 243 221 38 140 28 213 178 193 87 11 218 49 25 167 25 101 108 202 83 125 197 142 115 43 72 234 125 193 117 202 113 105 147 157 137 101 16 54 191 147 37 21 196 3 62 190 217 21 162 159 111 154 184 26 177 35 231 250 31 57 75 31 198 222 162 89 86 252 252 111 210 45 175 177 153 21 79 191 49 88 122 139 4 8 47 200 239 44 42 48 95 59 15 222 175 106 165 85 7 3 154 146 31 57 139 216 189 218 155 9 65 22 81 114 41 91 88 0 189 217 239 69 132 25 208 165 72 82 222 195 147 46 191 228 191 103 251 197 35 52 177 75 34 69 14 46 130 102 187 116 77 92 154 101 240 60 56 186 31 141 208 199 227 188 245 140 70 54 139 152 148 27 240 69 158 58 254 138 235 200 134 169 218 104 132 135 160 195 182 199 157 10 252 218 89 69 83 34 132 30 131 1 94 80 113 151 97 159 62 241 143 26 217 136 58 21 59 221 133 20 222 199 71 190 237 82 187 235 77 40 198 173 47 122 53 118 233 3 234 29 93 85 148 26 25 149 100 222 104 169 177 4 240 215 131 130 225 150 167 108 13 57 164 111 245 159 7 86 240 155 96 192 69 97 112 190 240 53 48 20 197 44 225 217 182 43 165 175 76 182 63 147 78 0 199 140 202 34 255 98 79 52 248 58 84 225 24 86 226 7 2 128 212 118 237 186 50 129 156 177 78 4 26 156 254 255 2 220 38 187 118 171 62 196 77 36 100 168 9 96 15 179 164 42 163 60 234 107 175 14 138 7 39 230 202 192 56 87 227 149 142 66 223 64 98 78 146 197 18 130 59 0 43 135 25 71 91 248 10 88 252 88 124 239 121 241 6 11 220 20 41 46 255 144 205 162 234 114 93 132 170 253 129 91 27 21 248 143 174 47 63 181 139 80 236 168 168 247 1 139 231 92 22 82 181 145 181 116 228 69 49 55 76 216 30 56 220 66 15 120 62 230 239 72 231 164 8 20 127 116 56 115 21 87 237 251 53 39 63 226 200 67 39 61 64 86 93 135 9 196 110 126 91 165 191 105 38 52 126 6 250 249 107 164 253 42 2 177 95 137 55 210 253 73 70 135 35 72 231 50 17 87 127 144 184 189 57 180 205 23 76 160 133 51 230 42 141 1 41 126 16 189 137 250 176 137 221 9 185 13 215 177 120 134 20 66 30 132 112 222 77 243 175 119 97 75 224 243 62 49 186 199 29 77 133 112 44 248 220 41 205 81 124 75 7 124 90 57 182 92 61 99 171 50 203 226 27 88 167 168 23 113 230 151 152 62 254 51 86 210 144 155 35 103 240 69 62 31 95 104 181 7 66 84 137 1 178 71 46 24 247 244 39 254 212 190 37 111 65 62 53 16 165 117 17 5 62 100 243 97 128 109 51 232 147 117 71 211 5 43 241 158 52 208 75 118 198 22 231 42 7 213 93 99 51 195 203 88 146 8 98 134 223 123 246 132 176 152 83 237 17 67 207 92 207 165 230 39 248 69 115 210 247 228 108 110 42 86 226 22 26 252 45 32 184 67 55 189 59 146 141 60 253 26 228 190 58 210 252 152 70 251 153 148 88 251 150 129 242 240 194 129 39 244 220 37 56 33 28 213 80 103 157 134 170 226 87 204 107 186 155 96 48 200 144 27 126 26 150 230 15 244 129 145 27 253 105 60 44 167 168 104 113 202 224 63 228 228 83 5 56 3 54 157 242 22 75 92 227 183 39 216 57 92 134 233 17 158 186 224 49 90 245 220 136 0 149 245 136 255 223 6 181 157 111 113 21 247 247 106 226 66 97 250 192 14 194 83 148 92 175 183 103 46 191 154 25 113 63 52 72 221 232 94 153 230 94 0 184 172 108 146 167 13 47 169 228 96 113 130 91 100 85 25 168 116 60 122 221 100 125 18 178 166 218 244 168 80 24 187 252 66 8 194 158 150 234 90 206 107 85 163 187 121 25 253 114 127 162 176 139 214 203 211 231 165 171 64 241 51 17 228 141 12 233 196 108 78 188 68 26 246 81 113 113 117 238 39 155 147 140 95 27 202 60 69 10 140 245 80 232 186 216 51 110 90 155 186 226 91 183 113 26 75 77 58 178 23 233 238 168 166 167 25 246 249 136 147 143 20 254 101 25 162 12 60 8 133 136 139 5 30 221 54 231 29 160 107 44 55 52 86 29 201 20 216 165 85 88 42 41 23 40 130 129 249 218 110 129 13 2 18 66 160 81 71 170 103 90 31 220 109 65 166 228 153 244 13 62 83 148 90 192 155 252 156 177 206 220 234 154 88 134 60 100 227 211 248 2 168 75 82 90 181 116 5 59 126 28 74 25 245 221 17 181 183 62 88 141 213 19 201 43 191 89 65 234 66 82 38 138 32 236 3 124 1 186 3 0 156 207 98 221 215 25 252 198 143 51 83 140 193 181 25 143 234 144 248 73 218 125 8 126 236 178 178 63 167 254 231 34 57 248 232 253 179 132 154 251 63 234 198 1 69 184 128 147 244 103 7 126 168 65 70 69 81 178 142 225 124 198 214 77 96 141 204 159 10 124 45 101 66 86 253 73 174 176 145 9 77 169 231 235 235 203 186 219 194 223 91 156 181 207 15 19 31 201 58 59 54 48 171 232 224 18 100 135 140 51 113 229 137 97 18 27 35 7 240 174 190 73 91 10 120 168 249 163 39 103 157 25 192 23 65 171 137 33 27 176 63 107 112 96 101 118 87 107 217 221 246 196 99 103 146 197 51 27 45 38 35 129 76 160 59 45 73 216 105 167 164 46 84 104 227 77 134 189 195 225 184 125 248 159 137 137 56 211 98 172 64 174 56 111 237 157 217 38 175 207 24 190 244 200 26 14 117 192 20 177 151 226 237 138 188 87 201 10 71 26 200 123 175 222 166 178 71 157 166 42 250 11 115 17 160 25 161 231 8 156 171 171 156 135 16 71 137 149 190 131 211 70 45 170 144 128 181 15 63 151 166 204 136 251 62 9 146 89 92 106 159 219 166 59 60 22 157 83 90 84 177 189 215 186 80 98 124 31 66 219 249 179 89 40 55 151 120 89 164 56 123 245 94 66 104 222 122 212 159 219 111 56 80 246 70 49 219 24 3 125 219 170 181 229 188 191 1 220 10 238 18 168 248 213 172 192 105 2 245 45 142 158 211 59 1 46 32 68 36 195 191 164 199 56 28 120 32 92 180 184 62 120 219 216 23 8 230 150 188 33 74 203 135 17 0 199 3 112 59 176 23 241 192 172 204 96 118 118 39 98 168 81 119 35 220 184 73 216 212 248 45 102 10 29 41 72 13 46 195 236 127 189 24 185 71 190 119 50 129 180 41 98 135 79 35 77 39 162 26 66 231 137 221 234 205 68 171 83 82 145 191 86 209 229 149 13 225 48 30 182 45 154 154 75 221 36 196 49 100 68 13 202 58 161 218 255 0 252 222 149 40 172 5 48 101 242 86 26 231 217 37 16 6 114 95 199 63 181 16 219 232 108 133 48 140 216 190 62 61 244 186 134 157 123 144 65 18 140 145 71 204 82 92 205 248 40 253 49 41 124 42 96 148 218 7 118 242 209 164 169 14 174 133 128 79 63 104 59 38 25 141 92 133 154 87 220 51 123 199 66 95 168 157 42 114 13 83 164 43 254 8 94 36 198 171 193 248 147 76 130 48 193 10 207 225 109 216 108 116 69 182 73 46 70 51 131 155 179 9 213 167 163 241 29 69 99 30 117 21 243 154 128 167 32 173 150 176 11 56 52 43 117 127 130 251 166 53 7 55 229 161 242 239 7 199 166 173 236 51 223 126 15 96 102 218 81 139 145 188 138 217 34 245 28 222 187 146 222 212 158 186 229 218 175 37 154 221 217 30 152 230 111 43 161 73 175 162 95 153 177 48 245 236 215 188 214 143 152 106 146 191 255 245 16 3 110 66 91 213 113 98 238 55 171 132 9 99 134 135 82 78 7 222 59 249 123 193 52 1 47 64 183 137 37 29 126 234 222 49 118 57 55 75 133 167 4 215 116 205 98 88 121 85 231 14 12 16 235 5 92 123 148 84 213 128 23 137 48 135 50 139 208 71 64 8 213 208 198 171 220 248 81 107 84 141 232 156 191 133 224 222 21 98 11 152 164 125 68 147 115 148 252 222 203 209 208 250 223 27 45 159 144 240 163 80 252 67 208 4 139 3 188 124 142 200 166 2 179 117 245 120 232 120 75 99 114 78 105 36 26 239 233 244 141 131 148 206 204 231 96 152 215 149 124 76 233 176 82 230 6 167 76 41 38 244 206 46 195 247 59 45 104 9 121 142 6 255 64 241 126 168 202 178 215 167 205 73 76 220 238 255 249 64 245 246 221 233 24 77 168 138 77 95 99 165 27 120 233 98 182 91 203 82 38 234 68 204 76 146 163 203 197 210 243 241 121 66 196 136 120 43 145 123 205 115 153 159 233 52 131 123 217 250 17 164 241 178 86 209 226 126 225 72 26 36 132 218 225 95 136 30 201 166 100 66 252 147 97 181 229 18 162 126 224 213 95 62 139 229 227 103 206 10 66 74 215 63 31 70 167 22 116 177 127 45 184 132 107 147 190 97 131 117 201 155 103 18 23 164 158 9 180 214 162 212 63 68 194 124 33 48 250 42 138 79 83 108 241 251 163 23 252 110 20 110 127 88 45 255 240 121 249 238 19 207 51 130 122 52 153 141 85 204 79 27 41 124 233 121 118 48 63 248 136 39 90 232 140 202 50 59 103 24 233 134 114 236 94 120 175 90 22 154 157 211 231 227 76 54 189 0 216 1 127 118 250 19 110 153 151 47 15 45 85 107 95 3 189 142 156 18 195 15 184 198 95 94 88 199 80 39 121 119 174 75 252 137 115 43 236 56 10 32 242 39 1 254 111 215 189 84 222 240 141 96 170 243 116 158 32 101 150 67 32 144 217 169 246 157 145 218 15 3 245 101 220 114 53 126 160 113 23 31 55 8 49 185 152 122 229 100 17 67 180 174 213 95 127 1 102 10 10 47 131 196 122 232 31 37 73 236 26 136 186 133 164 14 181 168 162 26 51 106 101 170 205 176 146 96 75 183 254 59 89 61 231 239 239 201 141 36 20 90 207 111 115 148 218 160 218 217 69 102 212 226 49 194 247 184 17 147 250 46 248 31 10 83 153 109 254 189 25 221 171 191 246 117 157 229 234 26 215 75 254 2 173 75 177 26 51 142 24 79 81 29 192 247 53 100 200 194 188 130 72 105 159 47 192 86 122 27 52 50 67 248 212 169 92 24 111 254 53 187 18 156 97 148 203 103 169 208 166 157 25 45 106 135 248 4 248 99 140 192 131 28 189 105 221 21 43 203 61 109 130 236 51 238 161 159 40 179 131 69 91 212 55 132 202 0 62 36 252 99 249 161 199 43 102 26 1 205 141 171 66 165 59 167 4 191 235 18 47 134 184 11 78 130 99 134 164 5 47 47 59 107 45 191 95 217 45 51 168 6 18 117 62 34 141 142 84 202 175 134 132 73 8 252 74 238 163 86 239 195 144 208 153 121 251 221 62 173 40 165 17 140 221 175 32 25 213 132 2 67 68 187 86 163 152 145 69 48 123 80 159 28 204 79 240 250 53 26 253 47 41 60 14 148 252 235 15 6 224 11 14 212 248 149 245 92 114 210 151 55 222 214 51 145 222 197 22 78 24 171 102 229 249 242 146 73 175 153 171 27 68 221 55 198 10 174 252 234 85 116 101 8 165 220 55 57 99 109 232 150 145 208 60 167 141 97 243 140 191 246 22 226 150 180 177 1 37 68 27 253 6 61 148 105 64 18 72 91 230 95 139 82 15 59 171 198 183 94 9 114 154 217 177 254 142 184 48 170 180 249 85 229 64 146 18 65 180 4 16 211 201 113 71 40 170 200 191 58 218 8 9 191 221 80 16 65 252 226 81 144 214 53 120 86 173 35 123 192 76 197 162 147 40 92 118 79 238 76 185 106 142 55 229 116 240 50 204 125 89 93 46 140 41 237 252 145 151 54 194 85 133 53 17 33 39 241 59 34 100 202 13 1 137 170 236 133 222 31 67 183 197 113 239 178 111 152 120 249 130 239 234 246 34 244 222 123 143 206 175 91 250 28 75 116 231 1 89 203 89 1 151 183 127 217 119 117 93 232 82 39 129 27 2 187 37 151 74 203 93 221 100 148 42 195 95 137 86 96 27 194 35 125 5 71 72 73 106 85 180 229 33 199 49 199 30 120 159 221 40 69 158 34 186 148 110 31 1 57 195 103 5 12 118 247 96 246 246 194 246 80 48 220 189 63 117 54 171 19 129 241 18 4 205 238 111 93 95 95 38 239 88 208 127 147 205 82 246 246 137 129 125 87 209 107 103 231 30 193 198 121 207 62 222 106 60 211 143 203 58 20 249 9 162 110 39 77 76 7 58 207 224 214 150 231 91 68 92 133 104 162 137 59 8 73 63 67 64 236 57 134 193 0 44 163 59 73 197 206 175 92 168 18 198 200 83 190 196 22 20 22 210 32 88 47 111 152 31 36 62 115 20 236 103 252 211 215 37 87 8 118 214 53 196 43 153 95 6 191 162 158 160 157 167 51 182 26 123 89 202 198 3 190 92 182 213 244 230 39 150 217 41 176 199 163 149 220 45 52 42 33 189 52 53 218 30 83 253 244 210 122 208 171 227 150 45 243 145 241 228 82 69 143 102 204 136 105 124 204 18 224 232 88 53 233 248 82 211 141 168 207 174 34 85 47 184 80 19 166 5 132 83 49 26 219 173 68 157 197 53 142 39 114 251 96 53 53 230 119 202 239 106 244 111 153 208 4 159 171 96 119 101 225 246 39 113 176 215 211 24 197 65 111 197 119 126 147 191 84 34 131 175 241 225 229 53 166 117 37 239 88 176 227 207 106 122 239 217 173 79 35 46 219 33 37 250 120 111 43 233 23 131 96 126 169 46 43 54 5 78 52 221 216 80 251 87 24 255 182 157 227 102 204 192 169 99 33 115 108 48 207 221 195 13 211 149 62 47 184 232 168 38 109 174 9 8 85 77 183 155 176 222 222 164 26 74 200 229 242 80 67 244 120 214 174 96 253 83 38 49 16 228 217 51 145 11 160 204 55 214 0 134 221 64 176 204 172 165 99 168 63 35 41 227 58 26 47 222 225 94 196 224 123 212 210 155 86 84 104 98 86 240 37 128 89 125 134 191 53 228 126 143 156 242 169 194 89 173 142 208 162 139 94 125 228 78 214 43 235 235 24 122 213 143 126 66 143 88 69 56 208 13 176 180 236 13 206 163 94 6 19 228 23 71 214 189 16 144 163 19 137 5 77 23 81 54 229 75 45 244 10 189 43 28 144 84 78 132 64 137 235 224 161 153 246 165 146 78 135 166 179 228 199 75 135 144 192 26 97 20 61 106 203 28 153 97 106 163 213 48 251 45 151 0 122 49 140 157 23 237 189 241 187 148 58 150 144 161 131 231 197 36 51 214 227 111 138 225 112 129 90 114 61 88 144 31 20 179 72 116 90 230 237 221 28 90 162 123 109 238 33 198 152 112 26 78 203 113 94 21 10 133 38 189 221 142 160 242 179 194 141 121 73 145 201 184 112 104 138 147 200 199 50 143 37 26 221 167 235 133 112 129 28 177 250 231 232 250 21 133 148 103 67 85 142 57 60 115 64 234 232 16 143 226 94 10 123 27 167 15 175 80 213 87 130 135 16 135 80 133 98 212 3 121 208 132 71 142 3 134 27 130 5 179 77 201 78 254 192 228 33 61 172 49 56 111 69 184 186 166 64 65 121 46 87 214 66 211 159 141 128 82 4 201 23 225 26 214 119 46 220 210 175 225 54 195 244 39 82 119 150 115 20 44 63 218 25 218 215 240 19 39 64 182 208 182 229 49 81 195 232 246 37 234 240 103 249 243 225 37 143 138 128 215 215 184 0 112 18 157 64 44 42 44 242 7 32 162 91 80 245 14 118 233 12 146 118 54 6 234 187 191 57 1 254 42 63 128 42 35 128 120 25 201 199 117 166 44 47 216 58 121 244 100 195 200 254 223 233 98 218 21 218 31 56 162 90 158 228 72 97 27 161 42 55 119 217 75 90 244 130 219 184 96 105 37 125 99 212 38 206 255 92 151 118 61 146 144 142 252 13 172 248 202 113 165 119 80 112 184 133 160 97 12 62 181 4 108 231 46 21 127 198 14 219 90 184 195 209 32 198 215 6 196 236 179 131 92 194 20 62 251 65 164 148 17 104 8 194 234 122 116 10 182 192 9 13 57 161 124 162 121 10 2 69 239 171 62 207 10 214 114 120 190 238 20 51 75 106 177 225 225 67 132 155 88 222 17 205 196 6 173 56 28 143 73 10 212 135 244 149 166 20 124 12 79 214 100 142 230 15 238 86 34 5 37 153 134 18 155 210 236 60 187 185 250 48 134 177 166 233 154 235 20 208 75 65 151 118 195 107 21 253 12 215 171 177 219 210 63 207 49 43 228 48 109 254 202 174 188 81 226 179 15 223 141 109 230 91 53 61 140 23 221 57 252 149 91 3 142 157 196 224 253 110 20 136 166 49 111 66 133 168 172 212 157 137 6 188 161 81 66 48 133 108 96 84 221 141 209 68 54 117 87 30 130 215 132 126 78 46 203 81 106 20 58 21 130 100 126 41 150 190 226 146 10 76 219 178 224 113 32 235 41 169 28 184 144 159 85 3 49 160 244 83 166 170 14 86 173 145 232 124 125 50 170 72 39 156 238 220 106 94 14 125 247 235 234 59 40 75 15 68 165 212 200 95 37 0 50 150 224 72 223 172 231 37 162 235 48 207 40 248 145 243 111 56 162 35 37 13 66 108 166 124 180 137 36 185 81 96 156 218 195 75 23 235 221 158 179 253 106 62 225 215 107 98 89 251 16 63 172 8 54 93 253 112 37 236 193 9 238 137 106 174 242 42 25 60 127 39 95 79 167 196 147 145 253 150 4 69 31 13 155 49 136 35 154 131 60 34 76 91 21 35 214 24 212 93 180 212 16 31 163 37 52 205 9 162 214 141 174 157 27 10 224 88 205 19 81 232 67 8 152 86 81 214 148 35 90 13 74 149 110 27 161 72 111 237 208 36 143 113 222 246 49 228 175 209 216 0 170 19 111 224 24 140 91 206 228 178 217 102 162 18 240 13 41 35 161 13 113 244 214 214 39 22 247 115 185 153 6 24 102 27 131 217 236 153 146 142 27 31 26 182 100 201 40 71 144 53 125 191 242 247 156 65 249 178 218 114 161 19 96 108 2 63 118 180 69 114 251 161 195 176 183 23 101 88 167 81 239 110 241 2 29 191 83 157 227 152 16 115 191 111 61 59 197 249 185 198 95 116 88 93 224 112 217 121 129 219 175 226 40 26 230 210 191 48 73 140 88 235 120 165 122 233 37 141 15 31 227 28 95 192 179 35 252 221 248 129 88 45 143 227 250 162 238 88 165 165 132 39 251 47 172 51 15 30 212 36 105 127 255 131 139 199 51 145 239 255 23 231 36 251 68 174 203 35 223 206 255 255 151 16 51 26 204 196 196 36 123 88 158 105 61 25 32 9 165 187 223 88 239 73 0 49 15 14 133 141 185 235 169 101 174 51 253 131 172 245 211 2 49 113 38 83 200 5 27 167 81 232 253 168 170 247 44 120 137 58 187 161 187 64 145 95 92 150 83 32 1 52 202 184 228 49 210 117 13 188 198 79 133 13 238 17 70 130 113 231 170 78 202 110 44 72 209 62 214 229 72 166 228 4 138 127 196 69 175 255 208 125 98 150 53 109 165 80 159 42 27 32 192 47 34 37 181 218 200 124 154 21 36 189 17 189 145 118 48 71 124 15 8 34 72 102 49 168 90 171 99 226 243 82 32 161 11 163 197 181 252 92 191 40 16 109 193 172 20 252 245 246 32 15 11 111 178 60 159 63 3 28 102 137 198 184 235 146 147 155 101 128 172 49 28 244 218 247 128 208 71 185 115 140 6 238 24 12 95 183 84 127 164 218 120 253 163 201 56 118 34 43 114 8 234 12 120 59 240 117 214 126 135 181 53 160 215 182 79 198 251 0 205 166 6 79 65 143 195 42 10 117 102 93 100 51 208 126 93 131 221 88 167 226 171 28 194 216 124 98 20 183 80 222 39 104 109 80 47 23 233 202 25 169 162 126 118 147 68 38 245 64 44 11 7 228 58 52 5 139 22 239 78 29 68 130 21 127 18 250 152 144 157 100 7 134 95 237 41 64 160 197 163 237 41 41 108 122 130 91 243 45 131 116 19 196 51 143 93 175 89 216 12 48 223 111 191 228 11 9 208 192 163 28 180 242 67 245 224 75 236 89 74 144 71 199 133 50 1 186 157 137 204 151 51 248 9 8 182 189 82 160 180 109 97 181 201 104 230 84 138 188 134 189 159 15 25 255 29 221 205 173 183 184 114 68 69 111 121 235 175 193 209 182 163 230 214 150 159 83 88 137 5 117 166 112 160 15 158 177 199 146 116 220 67 64 225 114 91 154 125 188 79 143 206 219 198 31 201 0 177 76 211 214 229 97 104 13 138 31 91 84 4 94 75 250 233 252 79 5 79 63 171 6 190 175 73 100 253 189 241 210 176 41 179 6 67 197 17 128 158 80 26 187 243 17 145 142 47 252 81 73 28 191 149 184 37 244 97 104 10 193 252 82 183 143 224 153 48 166 234 254 109 184 115 19 253 135 87 229 189 68 253 104 176 208 150 88 251 113 31 36 1 15 185 180 72 194 89 148 151 200 193 183 218 140 21 165 205 92 202 204 231 147 105 113 130 111 205 29 249 112 145 197 45 199 3 154 193 240 76 239 84 138 94 30 227 30 62 45 99 109 102 215 236 69 133 126 60 34 169 232 193 123 180 94 151 10 70 252 182 3 249 37 75 87 203 8 165 237 63 83 56 52 12 220 103 6 121 90 17 70 139 78 7 179 164 98 25 96 126 172 123 80 3 208 94 65 120 189 76 1 136 197 242 76 182 226 251 217 93 161 51 76 204 151 157 157 84 29 176 118 60 96 58 52 69 28 128 221 139 82 234 6 188 152 46 125 109 27 48 142 145 203 77 222 91 205 189 238 125 76 137 95 179 17 33 17 114 234 62 231 147 109 138 230 42 225 172 37 18 197 182 232 11 93 236 73 150 170 20 218 65 87 51 2 214 234 123 70 64 70 122 118 204 94 0 192 39 84 243 193 254 160 19 162 89 173 47 113 92 181 30 42 41 232 144 194 13 96 182 144 203 112 168 65 83 83 55 207 210 236 83 244 69 25 93 134 236 84 86 197 79 103 141 144 76 219 68 73 195 213 191 44 3 239 149 170 159 70 32 13 126 34 7 142 243 17 47 69 194 17 87 187 113 207 159 2 70 95 116 165 215 198 153 55 100 84 152 76 100 148 209 213 63 72 195 198 174 128 156 70 221 196 241 82 234 101 105 216 81 53 218 124 71 16 114 185 93 54 138 200 108 216 224 230 165 173 115 229 93 148 167 50 16 45 5 73 94 215 129 225 134 27 209 95 110 84 48 200 148 60 97 126 20 187 39 150 191 155 51 208 224 88 57 196 72 100 101 239 26 37 180 158 103 165 184 54 104 91 149 220 205 24 167 142 3 244 83 99 182 235 1 223 173 64 241 232 104 211 83 104 41 94 80 107 88 41 85 210 33 24 89 214 178 226 145 38 1 104 225 54 62 105 229 10 83 179 85 124 92 211 36 150 47 214 65 171 242 109 190 158 3 79 173 135 51 115 110 129 70 14 7 237 82 17 215 32 148 105 137 113 253 115 186 198 29 228 107 95 236 24 193 193 67 177 163 49 19 66 4 226 72 236 163 230 57 200 167 181 52 20 234 215 107 32 84 205 169 31 158 7 1 114 38 209 70 243 192 71 215 111 183 60 82 70 166 12 224 186 109 147 214 33 104 120 236 129 114 99 72 165 28 161 127 87 27 214 118 75 165 209 7 110 255 30 165 163 215 222 72 88 167 216 119 39 230 154 128 119 179 252 34 98 103 7 31 238 29 9 124 29 139 63 122 26 228 141 91 145 117 13 242 164 66 196 74 105 110 15 132 210 252 135 148 37 183 199 46 1 124 15 5 23 47 163 93 99 79 4 47 133 214 63 96 44 106 247 166 185 14 110 188 35 35 69 150 40 189 42 74 123 219 247 22 113 195 117 218 70 31 53 183 31 206 193 127 26 140 248 231 221 58 101 54 163 214 125 243 88 206 51 187 82 98 58 190 126 229 189 46 166 137 86 182 122 170 232 47 159 129 212 25 245 215 207 151 185 49 182 235 200 97 63 72 126 57 67 235 70 53 193 12 82 211 49 229 55 121 183 188 167 101 198 49 230 217 80 214 187 70 99 254 223 211 154 44 208 67 255 9 56 74 254 46 194 90 132 227 247 199 223 206 36 219 223 60 157 191 27 224 249 55 131 45 115 122 185 231 74 29 39 214 21 186 104 113 31 116 220 9 237 104 100 216 13 73 247 128 69 105 214 247 4 20 31 133 108 168 178 95 74 165 204 124 208 245 250 78 60 11 20 61 163 20 25 203 197 158 242 208 171 213 37 161 27 90 27 48 54 80 43 7 195 241 201 24 202 121 222 142 188 251 196 30 12 174 134 100 247 246 28 85 13 104 10 67 144 247 243 157 255 149 179 177 207 214 88 104 199 52 61 47 57 9 232 142 8 230 100 13 102 213 116 141 29 93 44 71 170 208 244 43 186 93 225 212 27 74 193 104 97 141 168 156 151 243 127 255 244 33 18 157 244 164 108 226 48 82 76 138 0 55 201 252 252 38 196 180 42 218 112 39 180 167 94 231 11 191 155 163 121 91 183 255 18 88 72 217 248 172 77 160 21 34 87 106 205 80 227 196 45 76 254 66 175 25 10 207 97 253 243 214 2 98 53 99 156 167 51 6 226 255 215 171 178 23 118 110 229 54 22 117 126 254 205 77 51 215 82 137 227 101 45 72 191 17 53 175 240 213 229 78 73 188 45 245 22 240 98 202 193 217 237 23 158 13 33 213 16 53 142 109 20 178 151 34 28 50 95 87 43 64 82 181 189 91 30 84 8 111 93 14 15 198 15 50 30 205 7 2 65 249 92 145 141 196 216 58 4 70 115 28 74 126 185 62 48 174 97 206 12 80 233 155 148 124 29 14 197 104 127 14 128 129 113 35 211 67 41 108 158 150 98 133 230 82 33 42 74 252 0 110 146 81 131 2 13 222 13 130 247 75 90 228 35 59 225 150 114 175 251 48 164 220 69 112 175 148 175 170 149 250 109 106 8 118 50 159 134 115 63 4 214 94 148 152 46 139 191 232 26 71 67 23 95 136 223 17 69 214 69 207 19 86 88 114 204 241 66 104 145 214 119 78 203 180 2 75 170 177 120 160 63 11 250 234 74 251 62 163 122 107 211 142 170 173 121 194 161 180 163 171 26 186 151 0 128 155 108 228 48 195 113 85 196 141 102 233 236 42 76 133 234 59 101 125 133 41 13 198 195 0 242 200 2 53 172 124 231 101 57 215 221 119 37 252 103 66 114 39 182 90 65 168 104 77 86 113 235 75 79 68 177 147 201 18 183 220 6 144 243 119 224 19 39 160 247 248 63 43 120 30 128 107 162 13 82 248 164 228 133 211 253 221 43 98 120 59 28 150 36 18 157 110 200 71 114 23 18 232 64 66 112 133 166 2 107 148 54 23 110 117 180 109 225 101 115 95 171 248 142 158 20 78 118 153 3 84 74 173 40 45 47 91 86 26 219 236 101 250 72 143 58 23 49 98 145 101 154 120 94 138 11 254 54 115 164 5 133 64 178 99 120 231 86 254 31 54 74 160 6 244 73 129 108 101 162 239 180 186 229 26 47 43 137 198 244 84 110 251 168 131 72 24 208 23 246 131 178 66 160 199 106 222 167 210 192 120 48 118 208 222 200 113 167 100 56 173 233 4 179 67 25 144 32 245 226 197 69 174 29 156 100 9 223 10 78 84 90 254 68 239 113 53 139 24 146 226 84 124 101 65 49 16 80 59 166 247 233 159 209 185 121 150 148 201 67 124 224 250 215 237 107 54 41 232 209 79 237 221 58 39 161 65 103 88 12 86 201 76 209 180 111 62 239 35 222 171 92 45 61 77 177 185 65 208 45 228 66 49 6 236 54 226 32 162 92 211 146 108 88 244 54 24 143 232 212 33 108 134 95 221 242 30 199 244 80 123 191 244 198 21 233 208 211 197 14 85 179 245 90 173 23 21 182 216 243 23 107 205 61 238 185 153 212 60 113 87 228 215 105 70 143 248 93 216 2 58 134 207 88 232 156 247 147 249 138 23 84 208 41 69 92 2 6 93 161 85 134 247 248 215 161 60 169 42 249 145 29 241 125 123 174 242 77 105 33 156 26 74 113 221 72 56 172 177 224 239 80 30 252 153 53 194 111 22 156 251 76 88 26 162 102 34 193 219 168 103 109 220 243 98 23 19 104 156 98 210 228 30 15 180 249 201 229 123 79 100 167 145 54 246 144 2 32 89 28 106 136 171 47 231 14 237 66 49 62 241 213 227 108 51 28 149 83 92 73 195 14 145 244 150 242 175 219 63 72 132 96 218 10 234 102 202 86 95 79 127 218 186 243 117 6 83 72 112 190 133 27 40 105 230 90 156 219 190 68 60 156 110 74 175 251 145 172 215 8 86 72 179 46 15 116 129 58 31 21 159 107 212 187 22 193 154 20 255 26 104 129 12 35 14 217 161 130 122 91 159 190 104 214 64 30 42 216 234 43 140 39 40 62 26 69 146 90 222 28 46 104 175 97 37 13 155 68 62 246 216 214 148 141 36 233 30 58 11 2 162 229 161 32 125 168 236 220 35 156 104 45 125 93 195 195 62 115 123 143 42 58 55 165 69 201 125 41 190 186 165 15 49 38 207 207 218 63 224 204 39 189 98 98 49 251 243 128 252 12 166 225 129 169 64 217 110 32 139 208 176 185 173 90 199 1 252 102 13 72 31 9 105 37 149 82 135 218 250 242 41 221 9 139 1 124 63 50 97 151 31 171 116 160 120 5 245 160 253 135 216 51 68 138 244 50 120 51 233 229 6 105 191 108 28 30 114 126 31 123 9 207 201 182 5 28 7 126 235 255 155 160 183 115 58 223 121 26 70 227 203 195 18 27 10 26 65 17 169 250 2 91 158 209 220 55 229 135 65 103 203 62 184 46 10 145 163 187 217 229 156 233 105 244 223 172 205 126 240 198 45 17 18 7 217 185 232 164 203 36 234 67 134 232 140 195 63 179 217 177 72 92 29 138 207 134 78 237 11 103 98 98 171 133 133 70 47 72 51 126 215 129 202 162 226 80 175 39 251 157 186 50 255 150 201 116 248 55 220 111 14 103 84 127 169 3 105 214 11 156 222 106 233 22 229 172 39 16 231 52 147 42 122 93 168 241 72 192 224 251 108 250 189 193 252 166 248 208 15 60 38 33 108 81 174 141 216 70 59 191 177 92 180 196 168 137 91 19 157 246 4 65 151 162 38 97 176 36 156 107 147 10 181 23 197 91 152 206 98 127 209 231 57 169 44 107 199 66 232 201 150 14 175 69 189 21 44 66 80 169 160 170 23 202 122 218 64 26 235 146 172 26 199 31 120 54 163 83 22 163 104 248 132 167 45 115 36 7 25 160 181 72 153 54 100 0 96 99 119 230 168 145 76 100 139 118 222 178 166 70 210 150 237 181 144 72 92 215 57 50 116 102 249 21 3 252 127 217 179 230 230 21 155 41 40 121 121 47 241 99 54 252 200 59 245 237 23 203 212 215 43 159 118 41 12 26 30 73 149 106 186 197 20 213 112 180 239 88 97 226 170 37 4 77 55 207 117 152 152 211 225 64 242 243 13 97 154 118 173 87 181 19 231 204 243 105 199 158 205 220 151 197 126 127 92 212 179 216 196 107 187 239 123 24 126 156 54 144 127 206 97 6 249 212 116 125 128 191 53 114 215 85 44 229 230 34 130 212 184 77 222 165 1 12 142 240 80 127 23 80 38 188 84 78 67 191 20 161 48 60 207 38 209 251 68 96 101 160 67 43 145 220 164 128 243 10 3 190 212 53 92 204 97 50 78 226 201 47 87 49 69 22 224 166 128 177 214 143 122 200 66 115 27 190 164 200 66 1 217 112 135 44 224 127 152 4 146 198 180 250 200 250 150 173 93 98 167 192 81 48 17 97 100 189 175 238 184 205 182 181 141 9 107 68 181 179 93 114 176 196 4 176 136 147 105 82 235 236 185 253 219 100 201 219 99 160 38 129 219 80 197 76 105 86 43 178 183 213 242 118 159 32 111 137 85 12 81 89 73 195 116 92 104 237 202 124 7 171 150 37 191 218 186 109 93 212 52 116 20 206 69 245 61 53 128 255 116 89 236 152 125 149 207 217 127 189 167 248 246 188 82 110 212 27 66 74 123 102 139 130 9 69 49 197 37 46 50 213 101 153 55 203 197 161 214 154 169 184 29 156 141 168 102 46 10 179 135 70 103 217 89 184 136 234 60 185 176 96 41 42 80 180 86 170 86 64 85 166 224 91 115 14 72 101 102 80 27 206 68 137 44 120 41 232 69 33 166 93 130 137 14 154 202 144 209 17 113 182 161 116 250 114 122 139 58 26 48 189 150 188 69 83 189 27 101 86 16 55 93 238 97 36 148 202 200 16 203 61 197 45 64 115 210 140 198 104 21 118 12 209 164 68 122 197 138 14 81 133 179 146 128 47 236 252 70 6 71 59 109 169 30 230 254 57 252 168 113 225 0 142 93 134 192 187 221 80 216 154 36 237 107 62 209 192 149 78 230 226 127 18 152 63 46 39 82 231 123 77 43 94 239 117 232 136 105 155 148 82 181 61 151 242 164 26 166 89 144 120 87 79 166 130 8 106 255 74 207 109 7 16 126 40 214 66 78 212 30 215 30 28 46 154 190 81 115 198 186 155 48 24 101 71 2 156 32 62 199 152 121 170 49 254 183 162 205 96 28 218 38 26 242 201 50 36 250 176 108 193 59 130 40 169 20 110 245 151 229 76 199 178 49 76 118 164 50 95 62 121 253 226 15 242 86 250 19 210 50 12 202 194 63 236 22 136 123 49 192 66 235 9 159 72 80 214 79 33 80 116 137 235 243 118 205 70 208 51 166 113 49 189 155 94 28 220 194 87 222 190 92 36 133 123 124 83 7 48 183 135 247 57 167 203 224 248 4 49 243 159 117 216 39 66 29 234 16 102 54 253 64 253 147 204 250 99 171 191 150 62 147 109 41 34 144 79 12 54 9 166 47 69 63 173 50 183 49 131 184 211 232 189 192 55 49 40 115 160 150 218 132 203 224 94 248 2 185 136 192 50 119 139 180 165 73 105 123 192 31 196 71 94 209 76 217 27 187 130 215 8 96 42 149 56 99 154 247 24 213 24 191 245 206 40 66 42 15 2 192 139 226 14 37 239 40 184 215 56 204 215 70 88 201 163 190 21 109 108 137 4 179 47 253 38 197 130 61 153 215 20 122 149 48 132 176 140 140 164 21 39 18 6 170 246 102 182 53 80 157 204 53 147 6 107 221 216 87 206 168 255 228 33 253 127 59 211 83 9 86 13 128 96 14 155 100 52 171 99 204 7 97 204 194 196 160 216 183 255 213 122 206 235 150 35 64 155 103 158 114 150 83 116 159 195 82 52 189 89 252 199 93 248 4 205 207 247 70 179 45 154 54 192 38 140 44 197 1 165 166 243 205 197 246 190 55 231 87 171 205 182 163 181 143 205 146 28 178 20 86 175 18 134 124 125 186 47 67 34 165 162 62 47 151 127 176 77 62 105 62 44 8 40 199 131 223 128 78 245 166 174 223 40 22 87 33 224 47 16 119 56 175 154 83 169 241 210 47 234 79 32 129 25 47 199 12 98 210 229 228 224 35 123 61 180 152 222 193 12 18 234 246 178 60 218 255 78 236 12 7 208 57 73 229 2 71 215 47 51 87 120 37 119 176 189 139 85 243 85 211 239 225 31 175 111 77 231 85 222 77 230 131 135 212 86 86 157 65 24 43 210 159 120 191 62 223 49 146 189 128 248 85 25 76 197 94 114 146 129 113 138 116 248 121 45 119 194 51 24 196 74 52 7 250 63 192 212 195 222 184 42 238 124 84 167 59 22 192 125 105 223 127 55 167 47 69 196 115 183 109 178 171 198 254 173 232 130 192 229 120 211 63 49 139 67 66 38 130 218 244 82 124 93 213 209 192 34 247 110 102 245 218 120 18 106 121 128 141 198 155 72 219 24 242 180 68 144 250 45 166 13 116 68 102 135 160 41 212 239 111 141 86 161 99 123 223 195 16 207 155 124 28 142 212 88 0 245 83 95 69 178 217 184 18 173 129 165 204 53 157 225 28 25 69 213 157 20 134 80 211 140 217 86 91 182 191 171 152 24 66 241 20 252 14 57 150 95 118 106 151 114 121 247 73 43 229 178 48 137 77 7 196 215 251 223 67 120 148 35 171 173 80 131 52 199 26 22 55 4 227 12 158 162 98 23 213 212 213 126 231 61 51 159 10 150 42 89 126 129 8 84 81 29 185 191 51 75 64 145 164 252 22 85 162 61 15 140 210 14 11 11 162 68 82 150 33 211 230 218 106 125 25 199 229 238 92 200 160 157 207 202 158 197 95 138 23 50 197 248 115 177 19 81 81 214 241 40 108 134 114 221 158 115 124 253 168 157 229 94 253 14 103 181 153 214 146 15 184 188 88 175 25 227 212 233 138 103 12 117 187 44 67 147 34 162 158 172 0 111 77 145 207 217 246 0 29 198 4 69 242 64 19 104 147 21 73 13 156 105 129 144 213 9 219 74 116 11 141 201 115 232 126 186 253 71 91 58 151 119 109 181 127 147 75 239 65 181 2 63 227 10 16 7 92 148 240 129 89 43 123 254 75 47 210 229 47 61 129 188 199 103 112 211 40 15 213 120 155 1 174 249 3 135 235 213 160 176 208 106 245 195 80 62 224 186 154 129 84 15 144 220 51 191 170 235 55 141 111 128 178 182 252 136 139 150 96 153 126 100 51 243 241 255 237 166 84 238 59 114 253 141 198 236 68 115 243 219 7 56 31 123 11 144 101 81 232 41 179 68 237 174 230 129 119 137 181 16 193 53 93 102 211 213 200 38 15 50 118 211 165 243 112 119 121 178 217 48 19 154 49 58 129 130 30 95 219 151 160 216 26 221 4 122 121 220 13 33 33 39 111 44 108 197 127 51 109 226 209 187 53 57 189 88 138 0 35 167 162 71 44 190 150 135 119 58 28 199 141 7 6 116 95 128 123 158 13 197 69 52 37 201 51 245 194 213 101 41 98 245 48 19 11 41 81 124 184 78 236 148 189 184 123 119 113 57 80 127 173 2 20 142 90 111 57 215 44 199 164 201 70 77 189 13 224 207 198 126 144 200 188 88 127 180 91 231 211 137 66 183 1 27 71 54 92 217 153 67 167 214 125 230 170 197 143 78 37 50 86 150 68 49 118 235 55 243 44 47 72 252 190 179 183 176 187 218 73 85 142 77 126 237 72 68 86 226 20 153 185 12 141 58 74 96 13 243 9 206 60 31 61 211 183 107 198 37 75 217 174 124 114 6 24 146 103 218 91 64 85 47 241 52 141 182 102 78 103 163 235 232 185 30 35 173 116 122 48 192 218 228 138 135 142 247 76 200 180 160 24 25 39 19 87 57 92 71 185 75 232 21 117 134 94 245 157 103 218 160 205 35 58 55 6 83 223 136 119 229 118 96 233 104 231 92 213 109 84 31 167 213 245 22 24 53 253 39 133 55 2 214 47 251 215 253 144 101 92 24 40 61 148 219 10 197 46 176 221 131 30 144 20 128 233 157 206 155 80 182 160 65 215 238 45 188 78 151 98 107 211 42 88 249 137 248 158 210 148 138 141 5 131 182 38 58 84 15 129 140 202 107 251 23 105 123 37 248 13 155 161 76 52 67 56 36 125 94 21 24 67 84 208 161 141 167 79 231 85 12 237 145 117 182 188 11 198 179 214 110 165 72 210 251 54 154 24 12 44 255 148 247 161 201 165 49 140 249 33 94 223 108 173 195 91 195 36 243 161 174 84 145 84 250 114 57 203 242 98 130 243 25 70 61 71 213 86 9 165 92 231 135 12 142 66 227 122 0 54 154 136 229 122 148 177 117 131 113 17 242 56 9 158 70 112 76 229 186 159 77 181 129 17 243 171 3 197 106 208 252 7 139 234 0)! ! !InterpreterSupportCode class methodsFor: 'source files' stamp: 'JMM 2/12/2001 21:59'! macAsyncFilePrimsFile ^ '/* Adjustments for pluginized VM * * Note: The Mac support files have not yet been fully converted to * pluginization. For the time being, it is assumed that they are linked * with the VM. When conversion is complete, they will no longer import * "sq.h" and they will access all VM functions and variables through * the interpreterProxy mechanism. */ #include "sq.h" #include "AsynchFilePlugin.h" #include #if !!TARGET_API_MAC_CARBON #define DisposeIOCompletionUPP(userUPP) DisposeRoutineDescriptor(userUPP) #endif /* initialize/shutdown */ int asyncFileInit() { return true; } int asyncFileShutdown() {} /* End of adjustments for pluginized VM */ /* Experimental support for asynchronous file reading and writing. When a read or write operation is initiated, control is returned to Squeak immediately. A semaphore is signaled when the operation completes, at which time the client can find out how many bytes were actually read or written and copy the results of the read operation from the file buffer into a Squeak buffer. Only one operation may be in progress on a given file at a given time, but operations on different files may be done in parallel. The semaphore is signalled once for each transfer operation that is successfully started, even if that operation later fails. Write operations always write their entire buffer if they succeed, but read operations may transfer less than their buffer size if they are started less than a buffer''s size from the end of the file. The state of a file is kept in the following structure, which is stored directly in a Squeak ByteArray object: typedef struct { int sessionID; AsyncFileState *state; } AsyncFile; The session ID is used to detect stale files--files that were open when the image was saved. The state pointer of such files is meaningless. Async file handles use the same session ID as ordinary file handles. Note: These primitives are experimental!! They need not be implemented on every platform, and they may be withdrawn or replaced in a future release. */ #include #include #include /* Async file handle (defined in header file): */ typedef struct { ParamBlockRec pb; /* must be first */ long refNum; int writable; int semaIndex; int status; int bytesTransferred; int bufferSize; char *bufferPtr; } AsyncFileState; /*** Status Values ***/ #define IDLE 0 #define LAST_OP_FAILED 1 #define BUSY 2 /*** Imported Variables ***/ extern int successFlag; extern int thisSession; /*** Local Vaiables ***/ IOCompletionUPP asyncFileCompletionProc = nil; /*** Exported Functions ***/ int asyncFileClose(AsyncFile *f); int asyncFileOpen(AsyncFile *f, int fileNamePtr, int fileNameSize, int writeFlag, int semaIndex); int asyncFileRecordSize(); int asyncFileReadResult(AsyncFile *f, int bufferPtr, int bufferSize); int asyncFileReadStart(AsyncFile *f, int fPosition, int count); int asyncFileWriteResult(AsyncFile *f); int asyncFileWriteStart(AsyncFile *f, int fPosition, int bufferPtr, int bufferSize); /*** Local Functions ***/ int asyncFileAllocateBuffer(AsyncFileState *state, int byteCount); pascal void asyncFileCompletionRoutine(AsyncFileState *state); int asyncFileInitPB(AsyncFileState *state, int fPosition); int asyncFileValid(AsyncFile *f); int asyncFileAllocateBuffer(AsyncFileState *state, int byteCount) { /* Allocate a new buffer of the given size if necessary. If the current buffer is already allocated and of the desired size, do nothing. */ if ((state->bufferPtr !!= nil) && (state->bufferSize == byteCount)) { return; /* buffer is already allocated and of the desired size */ } /* free old buffer, if any */ if (state->bufferPtr !!= nil) { DisposePtr(state->bufferPtr); state->bufferSize = 0; state->bufferPtr = nil; } /* allocate new buffer */ state->bufferPtr = NewPtr(byteCount); if (state->bufferPtr == nil) { state->bufferSize = 0; return success(false); /* could not allocate a buffer of size count */ } state->bufferSize = byteCount; } pascal void asyncFileCompletionRoutine(AsyncFileState *state) { /* Called when an I/O request completes. Decides what to do based on the given state. Note that the first part of the state record is the I/O parameter block. */ OSErr err; err = state->pb.ioParam.ioResult; if ((err !!= noErr) && (err !!= eofErr)) { /* Note: eofErr indicates that fewer than the count bytes were transfered when reading because the end-of-file was encountered first; it isn''t a real error. */ state->status = LAST_OP_FAILED; state->bytesTransferred = 0; signalSemaphoreWithIndex(state->semaIndex); return; } state->bytesTransferred = state->pb.ioParam.ioActCount; state->status = IDLE; signalSemaphoreWithIndex(state->semaIndex); } int asyncFileInitPB(AsyncFileState *state, int fPosition) { memset(&state->pb, 0, sizeof(ParamBlockRec)); state->pb.ioParam.ioCompletion = asyncFileCompletionProc; state->pb.ioParam.ioRefNum = state->refNum; state->pb.ioParam.ioBuffer = state->bufferPtr; state->pb.ioParam.ioReqCount = state->bufferSize; state->pb.ioParam.ioPosMode = fsFromStart; state->pb.ioParam.ioPosOffset = (fPosition < 0) ? 0 : fPosition; state->status = BUSY; state->bytesTransferred = 0; } int asyncFileValid(AsyncFile *f) { return ( (f !!= NULL) && (f->sessionID == thisSession) && (f->state !!= NULL) && (((AsyncFileState *) f->state)->refNum !!= 0)); } /*** Exported Functions ***/ int asyncFileClose(AsyncFile *f) { /* Close the given asynchronous file. */ AsyncFileState *state; short int volRefNum; OSErr err; if (!!asyncFileValid(f)) return; /* already closed */ state = f->state; err = GetVRefNum(state->refNum, &volRefNum); success(err == noErr); err = FSClose(state->refNum); success(err == noErr); if (successFlag) err = FlushVol(NULL, volRefNum); success(err == noErr); if (asyncFileCompletionProc !!= nil) DisposeIOCompletionUPP(asyncFileCompletionProc); asyncFileCompletionProc = nil; if (state->bufferPtr !!= nil) DisposePtr(state->bufferPtr); DisposePtr((void *) f->state); f->state = nil; f->sessionID = 0; } int asyncFileOpen(AsyncFile *f, int fileNamePtr, int fileNameSize, int writeFlag, int semaIndex) { /* Opens the given file using the supplied AsyncFile structure to record its state. Fails with no side effects if f is already open. Files are always opened in binary mode. */ int i; Str255 cFileName; short int fileRefNum; AsyncFileState *state; OSErr err; /* don''t open an already open file */ if (asyncFileValid(f)) return success(false); /* build complete routine descriptor, if necessary */ if (asyncFileCompletionProc == nil) { #if TARGET_API_MAC_CARBON asyncFileCompletionProc = NewIOCompletionUPP((pascal void (*) (union ParamBlockRec *) )asyncFileCompletionRoutine); #else asyncFileCompletionProc = NewIOCompletionProc((pascal void (*) (union ParamBlockRec *) )asyncFileCompletionRoutine); #endif } /* copy the file name into a null-terminated C string */ if (fileNameSize > 255) return success(false); sqFilenameFromString(cFileName, fileNamePtr, fileNameSize); CopyCStringToPascal((const char *)cFileName,cFileName); f->sessionID = 0; if (writeFlag) { /* first try to open an existing file read/write: */ err = HOpenDF(0,0,cFileName, fsRdWrPerm, &fileRefNum); if (err !!= noErr) { /* file does not exist; must create it. */ err = HCreate(0, 0, cFileName,''R*ch'',''TEXT''); if (err !!= noErr) return success(false); err = HOpenDF(0,0,cFileName,fsRdWrPerm, &fileRefNum); if (err !!= noErr) return success(false); } } else { /* open the file read-only */ err = HOpenDF(0,0,cFileName, fsRdPerm, &fileRefNum); if (err !!= noErr) return success(false); } f->state = (AsyncFileState *) NewPtr(sizeof(AsyncFileState)); /* allocate state record */ if (f->state == nil) { FSClose(fileRefNum); return success(false); } f->sessionID = thisSession; state = (AsyncFileState *) f->state; state->refNum = fileRefNum; state->writable = writeFlag; state->semaIndex = semaIndex; state->status = IDLE; state->bytesTransferred = 0; state->bufferSize = 0; state->bufferPtr = nil; } int asyncFileReadResult(AsyncFile *f, int bufferPtr, int bufferSize) { /* Copy up to bufferSize bytes from the buffer of the last read operation into the given Squeak buffer, and return the number of bytes copied. Negative values indicate: -1 -- busy; the last operation has not finished yet -2 -- error; the last operation failed Note that a read operation may read fewer bytes than requested if, for example, there are fewer than the requested number of bytes between the starting file position of the read operation and the end-of-file. */ AsyncFileState *state; int bytesRead; if (!!asyncFileValid(f)) return success(false); state = f->state; if (state->status == BUSY) return -1; if (state->status == LAST_OP_FAILED) return -2; /* copy the file buffer into the squeak buffer */ bytesRead = (bufferSize < state->bytesTransferred) ? bufferSize : state->bytesTransferred; memcpy((char *) bufferPtr, state->bufferPtr, bytesRead); return bytesRead; } int asyncFileReadStart(AsyncFile *f, int fPosition, int count) { /* Start an asynchronous operation to read count bytes from the given file starting at the given file position. The file''s semaphore will be signalled when the operation is complete. The client may then use asyncFileReadResult() to find out if the operation succeeded and to get the data that was read. */ AsyncFileState *state; OSErr err; if (!!asyncFileValid(f)) return success(false); state = f->state; if (state->status == BUSY) return success(false); /* operation in progress */ /* allocate a new buffer if necessary */ asyncFileAllocateBuffer(state, count); if (state->bufferPtr == nil) return success(false); /* could not allocate buffer */ asyncFileInitPB(state, fPosition); err = PBReadAsync(&state->pb); if (err !!= noErr) { state->status = IDLE; return success(false); } } int asyncFileRecordSize() { return sizeof(AsyncFile); } int asyncFileWriteResult(AsyncFile *f) { /* Return the number of bytes copied by the last write operation. Negative values indicate: -1 -- busy; the last operation has not finished yet -2 -- error; the last operation failed */ AsyncFileState *state; if (!!asyncFileValid(f)) return success(false); state = f->state; if (state->status == BUSY) return -1; if (state->status == LAST_OP_FAILED) return -2; return state->bytesTransferred; } int asyncFileWriteStart(AsyncFile *f, int fPosition, int bufferPtr, int bufferSize) { /* Start an asynchronous operation to write bufferSize bytes to the given file starting at the given file position. The file''s semaphore will be signalled when the operation is complete. The client may then use asyncFileWriteResult() to find out if the operation succeeded and how many bytes were actually written. */ AsyncFileState *state; OSErr err; if (!!asyncFileValid(f)) return success(false); state = f->state; if (state->status == BUSY) return success(false); /* operation in progress */ if (!!state->writable) return success(false); /* allocate a new buffer if necessary */ asyncFileAllocateBuffer(state, bufferSize); if (state->bufferPtr == nil) return success(false); /* could not allocate buffer */ /* copy the squeak buffer into the file buffer */ memcpy(state->bufferPtr, (char *) bufferPtr, bufferSize); asyncFileInitPB(state, fPosition); err = PBWriteAsync(&state->pb); if (err !!= noErr) { state->status = IDLE; return success(false); } } '! ! !InterpreterSupportCode class methodsFor: 'source files' stamp: 'JMM 2/12/2001 22:00'! macBrowserPluginFile ^ '/********** Notes on Browser Plugin VM ************ How it Works: The browser plugin VM allows Squeak to be run as a plug-in under version 4.0 and later of either Netscape Navigator or Internet Explorer. To use it, you must translate a version of interp.c with the browser plugin hooks. Note for fullscreen support NPP_HandleEvent does not return control, it consumes events from waitnextevent. When fullscreen mode is turn off then control is returned to the browser. Relationship of this file to sqMacWindow.c: One can think of this file as specializing and extending sqMacWindow.c for running within a browser. Certain methods in sqMacWindow.c are replaced by functions defined here. The originals are removed from sqMacWindow.c by defining the PLUGIN flag in that file when compiling. Here is a list of the functions overridden: ioExit() ioScreenSize() ioSetFullScreen() sqAllocateMemory() In addition, ioProcessEvents() becomes a noop and main() is completely omitted when sqMacWindow.c is compiled for use in the browser plugin VM. Thing busted 2000 July 26th squeak quit restart has issues with change file open June/July 2000 johnmci@smalltalkconsulting.com Reviewed code readded comments, added FullScreen Support fixed issues with Carbon, general code cleaning. Sept 27th 2000 johnmci@smalltalkconsulting.com added logic to have more flexibility in memory size. Fix issue with volume ID, don''t use 0 Fix issue were IE lies about the frame size as it figures out the frame size in real time durning rendering Added check for file: in URL logic to disallow Fixed problem in NPP_URLNotify, must call notify complete logic Ensure NP_memFree is called for plugin arguments Add logic for URLPosting Feb 8th 2001 johnmci@smalltalkconsulting.com Rewrote to use Apple multithreaded library and ported Squeak VM 3.0 **********/ #include "sq.h" #include "FilePlugin.h" #include "npapi.h" #include #include #include #include #include #include #include #include #include #include #include #if TARGET_API_MAC_CARBON #define EnableMenuItemCarbon(m1,v1) EnableMenuItem(m1,v1); #define DisableMenuItemCarbon(m1,v1) DisableMenuItem(m1,v1); #else #define EnableMenuItemCarbon(m1,v1) EnableItem(m1,v1); #define DisableMenuItemCarbon(m1,v1) DisableItem(m1,v1); inline Rect *GetPortBounds(CGrafPtr w,Rect *r) { *r = w->portRect; return &w->portRect;} inline Rect *GetRegionBounds(RgnHandle region, Rect * bounds) { *bounds = (*region)->rgnBBox; return &(*region)->rgnBBox;} inline RgnHandle GetPortClipRegion(CGrafPtr port,RgnHandle clipRgn) {MacCopyRgn (port->clipRgn,clipRgn); return clipRgn;} inline BitMap *GetQDGlobalsScreenBits(BitMap *bm){*bm = qd.screenBits; return &qd.screenBits; } inline BitMap * GetPortBitMapForCopyBits (CGrafPtr w) { return &((GrafPtr)w)->portBits;} inline pascal long InvalWindowRect(WindowRef window, const Rect * bounds) {InvalRect (bounds);} #endif /********** Compilation Options: * * ENABLE_URL_FETCH * Define this to compile primitives to fetch URL''s via the browser. * * Warning: Fetching file URL''s through the URL fetch mechanism allows * potentially untrusted code to read files outside of the Squeak * file system "sandbox", a serious breach of privacy. * There are few uses for use for the browser URL fetch * mechanism, since you can always fetch URL''s from remote servers * using Squeak''s own HTTPSocket. * **********/ #define ENABLE_URL_FETCH #define IMAGE_NAME "SqueakPlugin.image" #define VMPATH_SIZE 300 /*** Exported Primitives ***/ #ifdef ENABLE_URL_FETCH #pragma export on int primitivePluginBrowserReady(void); int primitivePluginDestroyRequest(void); int primitivePluginRequestFileHandle(void); int primitivePluginRequestState(void); int primitivePluginRequestURL(void); int primitivePluginRequestURLStream(void); int primitivePluginPostURL(void); #pragma export off #endif /* Constants */ #define MAX_STRING_LENGTH 255 #define MAX_ARG_STRING_LENGTH 100 #define STATUS_BAD_HANDLE -1 #define STATUS_IDLE 0 #define STATUS_IN_PROGRESS 1 #define STATUS_FAILED 2 #define STATUS_SUCCEEDED 3 #define STARTINGsqueakHeapMBytes 20*1024*1024 /*** Imported Variables ***/ extern int interruptKeycode; extern unsigned char *memory; extern WindowPtr stWindow; extern int fullScreenFlag; extern int successFlag; extern char documentName[]; /* full path to document file */ extern char imageName[]; /* full path to image file */ extern char shortImageName[]; /* just the image file name */ extern char vmPath[]; /* full path to interpreter''s directory */ extern struct VirtualMachine *interpreterProxy; extern int thisSession; /* from sqFilePrims.c: */ /*** Local Variables ***/ int exitRequested = false; Rect gSavePortPortRect; RgnHandle gSavePortClipRgn; CGrafPtr gOldPort = nil; int needsUpdate = false; NPWindow* netscapeWindow = nil; Str255 notificationMsg = ""; NMRec notifyRec; int pluginArgCount = 0; char *pluginArgName[MAX_ARG_STRING_LENGTH]; char *pluginArgValue[MAX_ARG_STRING_LENGTH]; Boolean ignoreFirstEvent=false; int squeakHeapMBytes = STARTINGsqueakHeapMBytes; /* default heap size, override via the "memory" EMBED tag */ char squeakPluginImageName[] = IMAGE_NAME; NPP thisInstance = nil; WindowPtr gAFullscreenWindow = nil; char rememberMemoryString[128]=""; extern Boolean gAllowAccessToFilePlease; #define URL_REQUEST_COUNT 100 typedef struct { int id; /* used to associate a request with its outcome */ int status; int semaIndex; char fileName[MAX_STRING_LENGTH + 1]; char *buffer; } URLRequestRecord; URLRequestRecord urlRequests[URL_REQUEST_COUNT]; int nextRequestID = 1; /*** Functions Imported from sqMacWindow ***/ int recordKeystroke(EventRecord *theEvent); int recordModifierButtons(EventRecord *theEvent); int recordMouseDown(EventRecord *theEvent); void ioSetFullScreenRestore(); int PrefixPathWith(char *pathName, int pathNameSize, int pathNameMax, char *prefix); int PathToWorkingDir(char *pathName, int pathNameMax, short volumeNumber,long directoryID); extern int dropInit(void); /*** From VM ***/ int checkImageVersionFromstartingAt(sqImageFile f, int imageOffset); int getLongFromFileswap(sqImageFile f, int swapFlag); extern int inputSemaphoreIndex; int recordMouseEvent(EventRecord *theEvent, int theButtonState); int MouseModifierState(EventRecord *theEvent); typedef int (*eventMessageHook)(EventRecord* event); extern eventMessageHook postMessageHook; int recordKeyboardEvent(EventRecord *theEvent, int keyType); extern Boolean gThreadManager; OSErr createNewThread(); extern PixMapHandle stPixMap; extern ThreadID gSqueakThread; GDHandle getDominateDevice( WindowPtr theWindow,Rect *windRect); int ioInitSecurity(void); /*** Local Functions ***/ int CaseInsensitiveMatch(char *s1, char *s2); void EndDraw(void); void ExitCleanup(void); int FindIdleURLRequest(void); int InitFilePaths(void); void InitURLRequestTable(void); int IsPrefixedBy(char *s, char *prefix); void OpenFileReadOnly(SQFile *f, char *fileName); void ReadSqueakImage(void); void StartDraw(void); int StringToInteger(char *s); void URLRequestCompleted(int notifyData, const char* fileName); int URLRequestCreate(char *url, char *target, int semaIndex); void URLRequestDestroy(int requestHandle); void URLRequestFailed(int notifyData, int reason); char * URLRequestFileName(int requestHandle); int URLRequestStatus(int requestHandle); int parseMemorySize(int baseSize, char *src); int AbortIfFileURL(char *url); int URLPostCreate(char *url, char *buffer, char * window,int semaIndex); /*** Initialize/Shutdown ***/ /*+++++++++++++++++++++++++++++++++++++++++++++++++ * NPP_Initialize: * Provides global initialization for a plug-in, and returns an error value. * * This function is called once when a plug-in is loaded, before the first instance * is created. Allocate any memory or resources shared by all * instances of your plug-in at this time. After the last instance has been deleted, * NPP_Shutdown will be called, where you can release any memory or * resources allocated by NPP_Initialize. +++++++++++++++++++++++++++++++++++++++++++++++++*/ NPError NPP_Initialize(void) { exitRequested = false; needsUpdate = false; netscapeWindow = nil; pluginArgCount = 0; thisInstance = nil; InitURLRequestTable(); return NPERR_NO_ERROR; } /*+++++++++++++++++++++++++++++++++++++++++++++++++ * NPP_GetJavaClass: * New in Netscape Navigator 3.0. * * NPP_GetJavaClass is called during initialization to ask your plugin * what its associated Java class is. If you don''t have one, just return * NULL. +++++++++++++++++++++++++++++++++++++++++++++++++*/ jref NPP_GetJavaClass(void) { return (jref) NULL; } /*+++++++++++++++++++++++++++++++++++++++++++++++++ * NPP_Shutdown: * Provides global deinitialization for a plug-in. * * This function is called once after the last instance of your plug-in is destroyed. * Use this function to release any memory or resources shared across all * instances of your plug-in. +++++++++++++++++++++++++++++++++++++++++++++++++*/ void NPP_Shutdown(void) { ExitCleanup(); } /*** Instance Create/Destroy ***/ /*+++++++++++++++++++++++++++++++++++++++++++++++++ * NPP_New: * Creates a new instance of a plug-in and returns an error value. * * NPP_New creates a new instance of your plug-in with MIME type specified * by pluginType. The parameter mode is NP_EMBED if the instance was created * by an EMBED tag, or NP_FULL if the instance was created by a separate file. * You can allocate any instance-specific private data in instance->pdata at this * time. The NPP pointer is valid until the instance is destroyed. +++++++++++++++++++++++++++++++++++++++++++++++++*/ NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, char* argn[], char* argv[], NPSavedData* saved) { int i; long threadGestaltInfo; OSErr err; /* only one Squeak instance can be active at a time */ if (thisInstance !!= nil) return NPERR_GENERIC_ERROR; for (i = 0; i < MAX_ARG_STRING_LENGTH; i++) { pluginArgName[i] = pluginArgValue[i] = ""; } /* record plugin arguments */ pluginArgCount = argc; for (i = 0; (i < argc) && (i < MAX_ARG_STRING_LENGTH); i++) { pluginArgName[i] = (char *) NPN_MemAlloc(strlen(argn[i]) + 1); strcpy(pluginArgName[i], argn[i]); pluginArgValue[i] = (char *) NPN_MemAlloc(strlen(argv[i]) + 1); strcpy(pluginArgValue[i], argv[i]); if (CaseInsensitiveMatch(pluginArgName[i], "memory")) { strcpy(rememberMemoryString,pluginArgValue[i]); } } memory = nil; ReadSqueakImage(); if (!!memory) return NPERR_GENERIC_ERROR; thisInstance = instance; if ((Gestalt( gestaltThreadMgrAttr, &threadGestaltInfo) == noErr) && threadGestaltInfo & (1<pdata. If the instance being deleted is the last instance created * by your plug-in, NPP_Shutdown will subsequently be called, where you can * delete any data allocated in NPP_Initialize to be shared by all your plug-in''s * instances. Note that you should not perform any graphics operations in * NPP_Destroy as the instance''s window is no longer guaranteed to be valid. +++++++++++++++++++++++++++++++++++++++++++++++++*/ NPError NPP_Destroy(NPP instance, NPSavedData** save) { long i; ExitCleanup(); if (pluginArgCount !!= 0) { for(i=0;iwindow are NULL, the plug-in must not perform any additional * graphics operations on the window and should free any resources associated * with the window. +++++++++++++++++++++++++++++++++++++++++++++++++*/ NPError NPP_SetWindow(NPP instance, NPWindow* window) { NP_Port* port; if (window == NULL) return NPERR_NO_ERROR; if (window->window == NULL) return NPERR_NO_ERROR; netscapeWindow = window; port = (NP_Port *) netscapeWindow->window; stWindow = (WindowPtr) port->port; needsUpdate = true; dropInit(); return NPERR_NO_ERROR; } /*** Streaming ***/ /*+++++++++++++++++++++++++++++++++++++++++++++++++ * NPP_NewStream: * Notifies an instance of a new data stream and returns an error value. * * NPP_NewStream notifies the instance denoted by instance of the creation of * a new stream specifed by stream. The NPStream* pointer is valid until the * stream is destroyed. The MIME type of the stream is provided by the * parameter type. +++++++++++++++++++++++++++++++++++++++++++++++++*/ NPError NPP_NewStream( NPP instance, NPMIMEType type, NPStream *stream, NPBool seekable, uint16 *stype) { /* Call to load the initial URL and to handle explicit URL fetch requests. */ *stype = NP_ASFILEONLY; /* ask Netscape to cache file and call NPP_StreamAsFile */ return NPERR_NO_ERROR; } /*+++++++++++++++++++++++++++++++++++++++++++++++++ * NPP_DestroyStream: * Indicates the closure and deletion of a stream, and returns an error value. * * The NPP_DestroyStream function is called when the stream identified by * stream for the plug-in instance denoted by instance will be destroyed. You * should delete any private data allocated in stream->pdata at this time. +++++++++++++++++++++++++++++++++++++++++++++++++*/ NPError NPP_DestroyStream(NPP instance, NPStream *stream, NPError reason) { return NPERR_NO_ERROR; } /*+++++++++++++++++++++++++++++++++++++++++++++++++ * NPP_StreamAsFile: * Provides a local file name for the data from a stream. * * NPP_StreamAsFile provides the instance with a full path to a local file, * identified by fname, for the stream specified by stream. NPP_StreamAsFile is * called as a result of the plug-in requesting mode NP_ASFILEONLY or * NP_ASFILE in a previous call to NPP_NewStream. If an error occurs while * retrieving the data or writing the file, fname may be NULL. +++++++++++++++++++++++++++++++++++++++++++++++++*/ void NPP_StreamAsFile(NPP instance, NPStream *stream, const char* fname) { if (fname !!= null) URLRequestCompleted((int) stream->notifyData, fname); else URLRequestFailed((int) stream->notifyData, 1); } /*+++++++++++++++++++++++++++++++++++++++++++++++++ * NPP_WriteReady: * Returns the maximum number of bytes that an instance is prepared to accept * from the stream. * * NPP_WriteReady determines the maximum number of bytes that the * instance will consume from the stream in a subsequent call NPP_Write. This * function allows Netscape to only send as much data to the instance as the * instance is capable of handling at a time, allowing more efficient use of * resources within both Netscape and the plug-in. +++++++++++++++++++++++++++++++++++++++++++++++++*/ int32 NPP_WriteReady(NPP instance, NPStream *stream) { /* not used, because we use ASFILEONLY mode */ return 100000; } /*+++++++++++++++++++++++++++++++++++++++++++++++++ * NPP_Write: * Delivers data from a stream and returns the number of bytes written. * * NPP_Write is called after a call to NPP_NewStream in which the plug-in * requested a normal-mode stream, in which the data in the stream is delivered * progressively over a series of calls to NPP_WriteReady and NPP_Write. The * function delivers a buffer buf of len bytes of data from the stream identified * by stream to the instance. The parameter offset is the logical position of * buf from the beginning of the data in the stream. * * The function returns the number of bytes written (consumed by the instance). * A negative return value causes an error on the stream, which will * subsequently be destroyed via a call to NPP_DestroyStream. * * Note that a plug-in must consume at least as many bytes as it indicated in the * preceeding NPP_WriteReady call. All data consumed must be either processed * immediately or copied to memory allocated by the plug-in: the buf parameter * is not persistent. +++++++++++++++++++++++++++++++++++++++++++++++++*/ int32 NPP_Write(NPP instance, NPStream *stream, int32 offset, int32 len, void *buffer) { /* not used, because we use ASFILEONLY mode */ return len; } /*+++++++++++++++++++++++++++++++++++++++++++++++++ * NPP_URLNotify: * Notifies the instance of the completion of a URL request. * * NPP_URLNotify is called when Netscape completes a NPN_GetURLNotify or * NPN_PostURLNotify request, to inform the plug-in that the request, * identified by url, has completed for the reason specified by reason. The most * common reason code is NPRES_DONE, indicating simply that the request * completed normally. Other possible reason codes are NPRES_USER_BREAK, * indicating that the request was halted due to a user action (for example, * clicking the "Stop" button), and NPRES_NETWORK_ERR, indicating that the * request could not be completed (for example, because the URL could not be * found). The complete list of reason codes is found in npapi.h. * * The parameter notifyData is the same plug-in-private value passed as an * argument to the corresponding NPN_GetURLNotify or NPN_PostURLNotify * call, and can be used by your plug-in to uniquely identify the request. +++++++++++++++++++++++++++++++++++++++++++++++++*/ void NPP_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData) { if (reason !!= NPRES_DONE) URLRequestFailed((int) notifyData, reason); else URLRequestCompleted((int) notifyData, null); } /*** Printing ***/ void NPP_Print(NPP instance, NPPrint* printInfo) { /* printing is not supported */ } /*** Event Handling ***/ /*+++++++++++++++++++++++++++++++++++++++++++++++++ * NPP_HandleEvent: * Mac-only, but stub must be present for Windows * Delivers a platform-specific event to the instance. * * On the Macintosh, event is a pointer to a standard Macintosh EventRecord. * All standard event types are passed to the instance as appropriate. In general, * return TRUE if you handle the event and FALSE if you ignore the event. * Note special logic for full screen support +++++++++++++++++++++++++++++++++++++++++++++++++*/ int16 NPP_HandleEvent(NPP instance, void *rawEvent) { EventRecord *eventPtr = (EventRecord*) rawEvent; EventRecord theEvent; int ok; Boolean windowActive=true; static EventRecord oldEvent; GrafPtr rememberFrontWindow=null; Boolean rememberWindowOnce=true; if (rememberWindowOnce) { //Remember who the front window is rememberWindowOnce = false; rememberFrontWindow = FrontWindow(); } YieldToAnyThread(); //Give some time up, needed for Netscape do { if (rememberFrontWindow == FrontWindow()) windowActive = true; else windowActive = false; if (exitRequested) { exitRequested = false; ExitCleanup(); return false; } if ((thisInstance == nil) || (eventPtr == NULL)) { /* no instance or no event; do nothing */ return false; } switch (eventPtr->what) { case mouseDown: if (!!windowActive) break; if(inputSemaphoreIndex) { StartDraw(); recordMouseEvent(eventPtr,MouseModifierState(eventPtr)); EndDraw(); break; } recordMouseDown(eventPtr); break; case mouseUp: if (!!windowActive) break; if(inputSemaphoreIndex) { StartDraw(); recordMouseEvent(eventPtr,MouseModifierState(eventPtr)); EndDraw(); break; } recordModifierButtons(eventPtr); break; case keyDown: case autoKey: if(inputSemaphoreIndex) { recordKeyboardEvent(eventPtr,EventKeyDown); break; } recordModifierButtons(eventPtr); recordKeystroke(eventPtr); break; case keyUp: if(inputSemaphoreIndex) { recordKeyboardEvent(eventPtr,EventKeyUp); } break; case updateEvt: needsUpdate = true; break; case activateEvt: if (theEvent.modifiers & activeFlag) windowActive = true; else windowActive = false; break; case nullEvent: if(inputSemaphoreIndex && windowActive && !!((oldEvent.what == eventPtr->what) && (oldEvent.message == eventPtr->message) && ((oldEvent.where.v == eventPtr->where.v) && (eventPtr->where.h == eventPtr->where.h)) && (oldEvent.modifiers == eventPtr->modifiers))) { oldEvent = *eventPtr; StartDraw(); recordMouseEvent(eventPtr,MouseModifierState(eventPtr)); EndDraw(); } else oldEvent = *eventPtr; break; } if (needsUpdate && (netscapeWindow !!= nil) && (memory)) { if (fullScreenFlag) { BeginUpdate((WindowPtr) eventPtr->message); } fullDisplayUpdate(); /* ask VM to call ioShowDisplay */ if (fullScreenFlag) { EndUpdate((WindowPtr) eventPtr->message); } needsUpdate = false; } if (ignoreFirstEvent && fullScreenFlag) { ignoreFirstEvent = false; return true; } if (fullScreenFlag) { ok = WaitNextEvent(everyEvent, &theEvent,0,null); eventPtr = &theEvent; YieldToAnyThread(); } } while (fullScreenFlag); return true; } /*** Drawing ***/ void EndDraw(void) { SetOrigin(gSavePortPortRect.left, gSavePortPortRect.top); SetClip(gSavePortClipRgn); SetPort((GrafPtr) gOldPort); } void StartDraw(void) { NP_Port* port; Rect clipRect; port = (NP_Port *) netscapeWindow->window; /* save old graphics port and switch to ours */ GetPort((GrafPtr *) &gOldPort); SetPort((GrafPtr) port->port); stWindow = (WindowPtr) port->port; /* save old drawing environment */ GetPortBounds(port->port,&gSavePortPortRect); GetClip(gSavePortClipRgn); /* setup our drawing environment */ SetOrigin(port->portx, port->porty); clipRect.top = netscapeWindow->clipRect.top + port->porty; clipRect.left = netscapeWindow->clipRect.left + port->portx; clipRect.bottom = netscapeWindow->clipRect.bottom + port->porty; clipRect.right = netscapeWindow->clipRect.right + port->portx; if (clipRect.top == 0 && clipRect.left ==0 && clipRect.bottom==0 && clipRect.right==0) { // Not sure what to do IE is lying... this gets the full screen, not a table cell GetPortBounds(GetWindowPort(stWindow),&clipRect); } ClipRect(&clipRect); BackColor(whiteColor); /* needed to avoid funny colors */ } int ioShowDisplay( int dispBitsIndex, int width, int height, int depth, int affectedL, int affectedR, int affectedT, int affectedB) { Rect dstRect = { 0, 0, 0, 0 }; Rect srcRect = { 0, 0, 0, 0 }; RgnHandle maskRect = nil; Boolean restorePort=false; if (stWindow == nil) { return; } restorePort = true; StartDraw(); /*if (((NP_Port *) netscapeWindow->window)->port !!= (struct CGrafPort *) stWindow) { StartDraw(); restorePort = true; }*/ dstRect.left = 0; dstRect.top = 0; dstRect.right = width; dstRect.bottom = height; srcRect.left = 0; srcRect.top = 0; srcRect.right = width; srcRect.bottom = height; (*stPixMap)->baseAddr = (void *) dispBitsIndex; /* Note: top three bits of rowBytes indicate this is a PixMap, not a BitMap */ (*stPixMap)->rowBytes = (((((width * depth) + 31) / 32) * 4) & 0x1FFF) | 0x8000; (*stPixMap)->bounds = srcRect; (*stPixMap)->pixelSize = depth; if (depth<=8) { /*Duane Maxwell fix cmpSize Sept 18,2000 */ (*stPixMap)->cmpSize = depth; (*stPixMap)->cmpCount = 1; } else if (depth==16) { (*stPixMap)->cmpSize = 5; (*stPixMap)->cmpCount = 3; } else if (depth==32) { (*stPixMap)->cmpSize = 8; (*stPixMap)->cmpCount = 3; } /* create a mask region so that only the affected rectangle is copied */ maskRect = NewRgn(); SetRectRgn(maskRect, affectedL, affectedT, affectedR, affectedB); SetPortWindowPort(stWindow); CopyBits((BitMap *) *stPixMap, GetPortBitMapForCopyBits(GetWindowPort(stWindow)), &srcRect, &dstRect, srcCopy, maskRect); #if TARGET_API_MAC_CARBON QDFlushPortBuffer (GetWindowPort(stWindow), maskRect); #endif DisposeRgn(maskRect); if (restorePort) EndDraw(); } /*** Image File Reading ***/ void ReadSqueakImage(void) { sqImageFile f; char msg[500]; int swapBytes; int dataSize; int headerStart; int headerSize; int heapSize; plugInInit(squeakPluginImageName); InitFilePaths(); /* read the image file and allocate memory for Squeak heap */ f = sqImageFileOpen(imageName, "rb"); if (f == NULL) { strcpy(msg, "Could not open Squeak image file \""); strcat(msg, imageName); strcat(msg, "\""); plugInNotifyUser(msg); return; } ioInitSecurity(); //Cheat and peek ahead to get the image size so we can calculate the memory required swapBytes = checkImageVersionFromstartingAt(f, 0); headerStart = (sqImageFilePosition(f)) - 4; headerSize = getLongFromFileswap(f, swapBytes); dataSize = getLongFromFileswap(f, swapBytes); //Close then reopen to reset file position sqImageFileClose(f); f = sqImageFileOpen(imageName, "rb"); squeakHeapMBytes = parseMemorySize(dataSize, rememberMemoryString); if (squeakHeapMBytes == 0) squeakHeapMBytes = STARTINGsqueakHeapMBytes; readImageFromFileHeapSizeStartingAt(f, squeakHeapMBytes, 0); sqImageFileClose(f); interruptKeycode = 515; /* ctrl-C, since Netscape blocks cmd-. */ fullScreenFlag=false; //Note image can be saved with true } /*** URL Requests ***/ int URLRequestCreate(char *url, char *target, int semaIndex) { /* Start a URL request and return its index. Return -1 if there were no idle request handles. */ int handle, notifyData; long junk; handle = FindIdleURLRequest(); if (handle < 0) return handle; urlRequests[handle].id = nextRequestID++; urlRequests[handle].status = STATUS_IN_PROGRESS; urlRequests[handle].semaIndex = semaIndex; urlRequests[handle].buffer = null; /* temporarily return the grafPort to Netscape so it can display feedback: */ EndDraw(); notifyData = (urlRequests[handle].id << 8) + handle; NPN_GetURLNotify(thisInstance, url, target, (void *) notifyData); Delay(120, (unsigned long *) &junk); /* workaround for a bug in Mac Netscape 4.7-- back-to-back requests to a server sometimes fail when the server was heavily loaded Question is this value too long!!*/ StartDraw(); return handle; } int URLPostCreate(char *url, char *buffer, char * window,int semaIndex) { /* Start a URL request and return its index. Return -1 if there were no idle request handles. */ int handle, notifyData; long junk; NPError error; handle = FindIdleURLRequest(); if (handle < 0) return handle; urlRequests[handle].id = nextRequestID++; urlRequests[handle].status = STATUS_IN_PROGRESS; urlRequests[handle].semaIndex = semaIndex; urlRequests[handle].buffer = buffer; /* temporarily return the grafPort to Netscape so it can display feedback: */ EndDraw(); notifyData = (urlRequests[handle].id << 8) + handle; error = NPN_PostURLNotify(thisInstance, url, window, strlen(buffer)+1, buffer, false, (void *) notifyData); if (error !!= NPERR_NO_ERROR) { StartDraw(); return -1; } Delay(120, (unsigned long *) &junk); /* workaround for a bug in Mac Netscape 4.7-- back-to-back requests to a server sometimes fail when the server was heavily loaded Question is this value too long!!*/ StartDraw(); if (window[0] == 0x00) { //Bug? unsure, but if window is null, then no notification give so trigger semaphore URLRequestCompleted(notifyData,null); } return handle; } void URLRequestDestroy(int requestHandle) { /* Clear the url request with the given handle. */ if ((requestHandle < 0) || (requestHandle >= URL_REQUEST_COUNT)) { return; } urlRequests[requestHandle].id = 0; urlRequests[requestHandle].status = STATUS_IDLE; urlRequests[requestHandle].semaIndex = 0; urlRequests[requestHandle].fileName[0] = 0; urlRequests[requestHandle].buffer = null; } char * URLRequestFileName(int requestHandle) { /* Return the filename associated with the url request with the given handle. Return null if the request status is not STATUS_SUCCEEDED. */ if ((requestHandle < 0) || (requestHandle >= URL_REQUEST_COUNT) || (urlRequests[requestHandle].status !!= STATUS_SUCCEEDED)) { return null; } return urlRequests[requestHandle].fileName; } int URLRequestStatus(int requestHandle) { /* Return the status of the url request with the given handle. */ if ((requestHandle < 0) || (requestHandle >= URL_REQUEST_COUNT) || (urlRequests[requestHandle].status < STATUS_IN_PROGRESS)) { return STATUS_BAD_HANDLE; } return urlRequests[requestHandle].status; } int FindIdleURLRequest(void) { /* Return the index of an idle request or -1 if there are none. */ int i; for (i = 0; i < URL_REQUEST_COUNT; i++) { if (urlRequests[i].status == STATUS_IDLE) { return i; } } return -1; } void URLRequestCompleted(int notifyData, const char* fileName) { /* Record that the given request has completed, caching the result in the given file name. */ int handle = notifyData & 0xFF; if ((handle < 0) || (handle >= URL_REQUEST_COUNT)) { return; } if (urlRequests[handle].id == (notifyData >> 8)) { if (fileName !!= null) strncpy(urlRequests[handle].fileName, fileName, MAX_STRING_LENGTH); if (urlRequests[handle].buffer !!= null) { NPN_MemFree(urlRequests[handle].buffer); urlRequests[handle].buffer = null; } urlRequests[handle].status = STATUS_SUCCEEDED; signalSemaphoreWithIndex(urlRequests[handle].semaIndex); } } void URLRequestFailed(int notifyData, int reason) { /* Record that the given URL request failed. */ int handle = notifyData & 0xFF; if ((handle < 0) || (handle >= URL_REQUEST_COUNT)) { return; } if (urlRequests[handle].id == (notifyData >> 8)) { if (urlRequests[handle].buffer !!= null) { NPN_MemFree(urlRequests[handle].buffer); urlRequests[handle].buffer = null; } /* Note: For local files, we''re informed that there was a network error (but only after NPP_StreamAsFile has reported success). We could allow local files to be read through the URL request mechanism but NOT failing here if the status has already been set to success. But we don''t want to allow the URL mechanism to be used as a loophole to read files outside the sandbox, so we let this fail. */ if (urlRequests[handle].status !!= STATUS_SUCCEEDED) { urlRequests[handle].status = STATUS_FAILED; signalSemaphoreWithIndex(urlRequests[handle].semaIndex); } } } void InitURLRequestTable(void) { /* Initialize the table of URL requests. */ int i; for (i = 0; i < URL_REQUEST_COUNT; i++) { URLRequestDestroy(i); } nextRequestID = 1; } /*** Squeak I/O Support and Memory Allocation ***/ int ioExit(void) { /* Request that we stop running plugin. */ ioSetFullScreenRestore(); exitRequested = true; } int ioScreenSize(void) { int w = 0, h = 0; Rect bounds; if (netscapeWindow !!= nil) { w = netscapeWindow->clipRect.right - netscapeWindow->clipRect.left; h = netscapeWindow->clipRect.bottom - netscapeWindow->clipRect.top; } if (w == 0 && h == 0) { GetPortBounds(GetWindowPort(stWindow),&bounds); w = bounds.right - bounds.left; h = bounds.bottom - bounds.top; } return (w << 16) | (h & 0xFFFF); /* w is high 16 bits; h is low 16 bits */ } /* Full Screen logic */ Ptr gRestorableStateForScreen = nil; NP_Port gFullScreenNPPort; NPWindow *oldNetscapeWindow,gFullScreenNPWindow; WindowPtr oldStWindow; int ioSetFullScreen(int fullScreen) { short desiredWidth,desiredHeight; Rect windRect; if (fullScreen) { if (fullScreenFlag) return; desiredWidth = 0; desiredHeight = 0; oldNetscapeWindow = netscapeWindow; oldStWindow = stWindow; BeginFullScreen (&gRestorableStateForScreen,getDominateDevice(stWindow,&windRect), &desiredWidth, &desiredHeight, &gAFullscreenWindow, nil, fullScreenAllowEvents); fullScreenFlag = true; stWindow = gAFullscreenWindow; gFullScreenNPPort.port = (CGrafPort *) gAFullscreenWindow; gFullScreenNPPort.portx = 0; gFullScreenNPPort.porty = 0; gFullScreenNPWindow.window = &gFullScreenNPPort; gFullScreenNPWindow.x = 0; gFullScreenNPWindow.y = 0; gFullScreenNPWindow.width = desiredWidth; gFullScreenNPWindow.height = desiredHeight; gFullScreenNPWindow.clipRect.top = 0; gFullScreenNPWindow.clipRect.left = 0; gFullScreenNPWindow.clipRect.bottom = desiredHeight; gFullScreenNPWindow.clipRect.right = desiredWidth; netscapeWindow = &gFullScreenNPWindow; ignoreFirstEvent = true; } else { if (!!fullScreenFlag) return; fullScreenFlag = false; ioSetFullScreenRestore(); } } void ioSetFullScreenRestore() { if (gRestorableStateForScreen !!= nil) { EndFullScreen(gRestorableStateForScreen,nil); if (gAFullscreenWindow == nil) return; gRestorableStateForScreen = nil; netscapeWindow = oldNetscapeWindow; stWindow = oldStWindow; } } void * sqAllocateMemory(int minHeapSize, int desiredHeapSize) { /* Allocate the Squeak object heap memory from the system heap. */ #if TARGET_API_MAC_CARBON return NewPtr(desiredHeapSize); #else return NewPtrSys(desiredHeapSize); #endif } /*** File and Access Paths ***/ int InitFilePaths(void) { short vRefNum; char imageInPreferenceFolder[256]; long dirID; OSErr err; FSSpec fileSpec; /* clear all path and file names */ imageName[0] = shortImageName[0] = documentName[0] = vmPath[0] = 0; strcpy(shortImageName, squeakPluginImageName); /* get the path to the sytem folder preference area*/ err = FindFolder(kOnSystemDisk, kPreferencesFolderType, kDontCreateFolder, &vRefNum, &dirID); if (err !!= noErr) { strcpy(imageName,"Problems finding the System Preference folder"); return err; } // Look for folder, if not found abort */ strcpy(imageInPreferenceFolder,":Squeak:Internet:"); strcat(imageInPreferenceFolder,shortImageName); CopyCStringToPascal(imageInPreferenceFolder,(unsigned char *) imageInPreferenceFolder); err = FSMakeFSSpec(vRefNum, dirID,(unsigned char *) imageInPreferenceFolder , &fileSpec); if (err !!= noErr) { strcpy(imageName,"Problems finding the Internet folder in the Squeak Preference folder or the SqueakPlugin.image"); return err; } /* set the vmPath */ PathToWorkingDir(vmPath,VMPATH_SIZE, fileSpec.vRefNum,fileSpec.parID); strcpy(imageName, vmPath); strcat(imageName, shortImageName); } int IsPrefixedBy(char *s, char *prefix) { /* Return true if the given string begins with or equals the given prefix. */ int i; for (i = 0; prefix[i] !!= 0; i++) { if (s[i] !!= prefix[i]) return false; } return true; } /*** Optional URL Fetch Primitives ***/ #ifdef ENABLE_URL_FETCH int primitivePluginBrowserReady(void) { /* Args: none. Always return true on Macintosh. */ interpreterProxy->pop(1); interpreterProxy->pushBool(1); } int primitivePluginDestroyRequest(void) { /* Args: handle. Destroy the given request. */ int handle; handle = interpreterProxy->stackIntegerValue(0); if (interpreterProxy->failed()) { return null; } URLRequestDestroy(handle); interpreterProxy->pop(1); } int primitivePluginRequestFileHandle(void) { /* Args: handle. Return a file handle for the completed request. Fail if the request handle is not valid or hasn''t successfully completed. */ int handle, fileObj; char *fileName; SQFile *filePtr; handle = interpreterProxy->stackIntegerValue(0); if (interpreterProxy->failed()) { return null; } fileName = URLRequestFileName(handle); if (fileName == null) { interpreterProxy->success(false); return null; } fileObj = interpreterProxy->instantiateClassindexableSize( interpreterProxy->classByteArray(), sizeof(SQFile)); filePtr = (SQFile *) (fileObj + 4); /* Note: OpenFileReadOnly() allows any file on the disk to be read via a file URL. However, we are using it for now because we are not sure where the Netscape cache folder will be--it''s folder might even be user-name dependent. sqFileOpen() will only allow opening files within the sandbox, which would be better. Here''s the sandbox-safe alternative: sqFileOpen(filePtr, (int) fileName, strlen(fileName), false); */ OpenFileReadOnly(filePtr, fileName); if (interpreterProxy->failed()) { return null; } interpreterProxy->pop(2); interpreterProxy->push(fileObj); } int primitivePluginRequestState(void) { /* Args: handle. Return true if the request succeeded, false if it failed, and nil if it is still in progress. Fail if the request handle is not valid. */ int handle; int status; int resultObj; handle = interpreterProxy->stackIntegerValue(0); if (interpreterProxy->failed()) { return null; } status = URLRequestStatus(handle); if (status == STATUS_BAD_HANDLE) { interpreterProxy->success(false); return null; } /* default return object: (nil means "in progress") */ resultObj = interpreterProxy->nilObject(); if (status == STATUS_FAILED) { resultObj = interpreterProxy->falseObject(); } if (status == STATUS_SUCCEEDED) { resultObj = interpreterProxy->trueObject(); } interpreterProxy->pop(2); interpreterProxy->push(resultObj); } int primitivePluginRequestURL(void) { /* Args: url, target, semaphoreIndex. Start a URL request to fetch the given URL to the given target. (See the Netscape Plugin programmer''s manual for possible targets.) Return a handle that can be used to identify this request. Fail if there are already too many outstanding requests. */ char *urlPtr; char *targetPtr; int semaIndex; int urlObj, urlSize; int targetObj, targetSize; char url[MAX_STRING_LENGTH + 1]; char target[MAX_STRING_LENGTH + 1]; int i; int handle; semaIndex = interpreterProxy->stackIntegerValue(0); targetObj = interpreterProxy->stackObjectValue(1); urlObj = interpreterProxy->stackObjectValue(2); interpreterProxy->success(interpreterProxy->isBytes(targetObj)); interpreterProxy->success(interpreterProxy->isBytes(urlObj)); if (interpreterProxy->failed()) { return null; } urlSize = interpreterProxy->stSizeOf(urlObj); urlPtr = interpreterProxy->firstIndexableField(urlObj); targetSize = interpreterProxy->stSizeOf(targetObj); targetPtr = interpreterProxy->firstIndexableField(targetObj); /* copy url into a C string */ if (urlSize > MAX_STRING_LENGTH) urlSize = MAX_STRING_LENGTH; for (i = 0; i < urlSize; i++) { url[i] = urlPtr[i]; } url[urlSize] = 0; interpreterProxy->success(AbortIfFileURL(url)); if (interpreterProxy->failed()) { return null; } /* copy target into a C string */ if (targetSize > MAX_STRING_LENGTH) targetSize = MAX_STRING_LENGTH; for (i = 0; i < targetSize; i++) { target[i] = targetPtr[i]; } target[targetSize] = 0; handle = URLRequestCreate(url, target, semaIndex); interpreterProxy->success(handle >= 0); if (interpreterProxy->failed()) { return null; } interpreterProxy->pop(4); interpreterProxy->pushInteger(handle); } int primitivePluginPostURL(void) { /* Args: url, target, semaphoreIndex. Start a URL request to post the given URL to the given target. (See the Netscape Plugin programmer''s manual for possible targets.) Return a handle that can be used to identify this request. Fail if there are already too many outstanding requests. */ char *urlPtr; char *targetPtr; char *bufferPtr,*buffer; int semaIndex; int urlObj, urlSize; int targetObj, targetSize; int bufferObj, bufferSize; char url[MAX_STRING_LENGTH + 1]; char target[MAX_STRING_LENGTH + 1]; int i; int handle; semaIndex = interpreterProxy->stackIntegerValue(0); bufferObj = interpreterProxy->stackObjectValue(1); targetObj = interpreterProxy->stackObjectValue(2); urlObj = interpreterProxy->stackObjectValue(3); interpreterProxy->success(interpreterProxy->isBytes(targetObj)); interpreterProxy->success(interpreterProxy->isBytes(urlObj)); interpreterProxy->success(interpreterProxy->isBytes(bufferObj)); if (interpreterProxy->failed()) { return null; } urlSize = interpreterProxy->stSizeOf(urlObj); urlPtr = interpreterProxy->firstIndexableField(urlObj); targetSize = interpreterProxy->stSizeOf(targetObj); targetPtr = interpreterProxy->firstIndexableField(targetObj); bufferSize = interpreterProxy->stSizeOf(bufferObj); bufferPtr = interpreterProxy->firstIndexableField(bufferObj); /* copy url into a C string */ if (urlSize > MAX_STRING_LENGTH) urlSize = MAX_STRING_LENGTH; for (i = 0; i < urlSize; i++) { url[i] = urlPtr[i]; } url[urlSize] = 0; interpreterProxy->success(AbortIfFileURL(url)); if (interpreterProxy->failed()) { return null; } /* copy target into a C string */ if (targetSize > MAX_STRING_LENGTH) targetSize = MAX_STRING_LENGTH; for (i = 0; i < targetSize; i++) { target[i] = targetPtr[i]; } target[targetSize] = 0; /* copy over the post buffer which might be large*/ buffer = (char *) NPN_MemAlloc(bufferSize+1); for (i = 0; i < bufferSize; i++) { buffer[i] = bufferPtr[i]; } buffer[bufferSize] = 0; handle = URLPostCreate(url, buffer,target,semaIndex) ; interpreterProxy->success(handle >= 0); if (interpreterProxy->failed()) { return null; } interpreterProxy->pop(5); interpreterProxy->pushInteger(handle); } int primitivePluginRequestURLStream(void) { /* Args: url, semaphoreIndex. Start a URL request to fetch the given URL. Return a handle that can be used to identify this request. Fail if there are already too many outstanding requests. */ int urlObj, urlSize, semaIndex; char *urlPtr; char url[MAX_STRING_LENGTH + 1]; int handle, i; semaIndex = interpreterProxy->stackIntegerValue(0); urlObj = interpreterProxy->stackObjectValue(1); interpreterProxy->success(interpreterProxy->isBytes(urlObj)); if (interpreterProxy->failed()) { return null; } urlSize = interpreterProxy->stSizeOf(urlObj); urlPtr = interpreterProxy->firstIndexableField(urlObj); /* copy url into a C string */ if (urlSize > MAX_STRING_LENGTH) urlSize = MAX_STRING_LENGTH; for (i = 0; i < urlSize; i++) { url[i] = urlPtr[i]; } url[urlSize] = 0; interpreterProxy->success(AbortIfFileURL(url)); if (interpreterProxy->failed()) { return null; } handle = URLRequestCreate(url, null, semaIndex); interpreterProxy->success(handle >= 0); if (interpreterProxy->failed()) { return null; } interpreterProxy->pop(3); interpreterProxy->pushInteger(handle); } void OpenFileReadOnly(SQFile *f, char *fileName) { /* Opens the given file for reading using the supplied sqFile structure. This is a simplified version of sqFileOpen() that avoids the "sandbox" access check, since the browser''s cache folder is outside the Squeak sandbox. That is why we only allow reading of this file. Sets the primitive failure flag if not successful. */ f->file = fopen(fileName, "rb"); f->writable = false; if (f->file == NULL) { f->sessionID = 0; f->fileSize = 0; interpreterProxy->success(false); return; } else { f->sessionID = thisSession; /* compute and cache file size */ fseek(f->file, 0, SEEK_END); f->fileSize = ftell(f->file); fseek(f->file, 0, SEEK_SET); } f->lastOp = 0; } #endif /*** Other ***/ int CaseInsensitiveMatch(char *s1, char *s2) { /* Return true if the two strings are the same, not considering case. */ int len, i, c1, c2; len = strlen(s1); if (strlen(s2) !!= len) return false; for (i = 0; i < len; i++) { c1 = s1[i]; c2 = s2[i]; if ((c1 >= ''a'') && (c1 <= ''z'')) { c1 = c1 - (''a'' - ''A''); } if ((c2 >= ''a'') && (c2 <= ''z'')) { c2 = c2 - (''a'' - ''A''); } if (c1 !!= c2) return false; } return true; } int StringToInteger(char *s) { /* Answer the integer resulting from converting the given string, assumed to be decimal integer. */ int sign, n, i, ch; sign = 1; n = 0; i = 0; while ((ch = s[i++]) !!= 0) { if ((ch == ''-'') && (i == 1)) { sign = -1; } else { if ((ch >= ''0'') && (ch <= ''9'')) { n = (10 * n) + (ch - ''0''); } else { return sign * n; } } } return sign * n; } void ExitCleanup(void) { /* Clean up and stop running plugin. */ if (thisInstance == nil) return; thisInstance = nil; exitRequested = true; while(gSqueakThread !!= kNoThreadID && YieldToThread(gSqueakThread) == noErr){}; plugInShutdown(); ioSetFullScreenRestore(); NPP_Initialize(); /* reset local variables */ } /*** Interpreter Hooks ***/ int plugInNotifyUser(char *msg) { /* Notify the user that there was a problem starting Squeak. */ CopyCStringToPascal(msg,notificationMsg); /* copy message, since notification is asynchronous */ notifyRec.qType = nmType; notifyRec.nmMark = false; /* no mark in applications menu */ notifyRec.nmIcon = nil; /* no menu bar icon */ notifyRec.nmSound = (Handle) -1; /* -1 means system beep */ notifyRec.nmStr = notificationMsg; notifyRec.nmResp = (NMUPP) -1; /* -1 means remove notification when user confirms */ /* add to notification queue */ NMInstall(¬ifyRec); } void plugInSetStartTime(void) { } int plugInTimeToReturn(void) { if (exitRequested) return true; return false; } int parseMemorySize(int baseSize, char *src) { char buf[50], *tmp; int imageSize = 0, requestedSize; while(*src) { switch(*src) { case '' '': /* white spaces; ignore */ case ''"'': src++; break; case ''*'': /* multiple of image size */ tmp = buf; src++; while(*src && isdigit(*src)) *(tmp++) = *(src++); /* integer part */ if(*src == ''.'') { /* fraction part */ *(tmp++) = *(src++); while(*src && isdigit(*src)) *(tmp++) = *(src++); } *(tmp++) = 0; imageSize += (int) (baseSize * atof(buf)); break; case ''+'': /* additional space in bytes */ tmp = buf; src++; while(*src && isdigit(*src)) *(tmp++) = *(src++); *(tmp++) = 0; if (imageSize == 0) imageSize = baseSize; requestedSize = atoi(buf); imageSize += (requestedSize <= 1000) ? requestedSize*1024*1024 : requestedSize; break; default: /* absolute size */ tmp = buf; *(tmp++) = *(src++); while(*src && isdigit(*src)) *(tmp++) = *(src++); *(tmp++) = 0; requestedSize = atoi(buf); imageSize = (requestedSize <= 1000) ? requestedSize*1024*1024 : requestedSize; } } return imageSize; } int AbortIfFileURL(char *url) { char lookFor[6]; int i=0,placement=0; lookFor[5] = 0x00; while (true) { if (*url == 0x00) break; if (*url == '' '') { url++; } else { lookFor[placement++] = *url++; if (placement == 5) break; } } return !!CaseInsensitiveMatch(lookFor,"file:"); }'! ! !InterpreterSupportCode class methodsFor: 'source files' stamp: 'JMM 2/12/2001 22:00'! macDirectoryFile ^ '/* Adjustments for pluginized VM * * Note: The Mac support files have not yet been fully converted to * pluginization. For the time being, it is assumed that they are linked * with the VM. When conversion is complete, they will no longer import * "sq.h" and they will access all VM functions and variables through * the interpreterProxy mechanism. Feb 2nd 2001, JMM rewrote, using more current file manager logic. */ #include "sq.h" #include "FilePlugin.h" /* End of adjustments for pluginized VM */ #include #include #ifndef __MPW__ #include #else #include #include #endif #include /*** The interface to the directory primitive is path based. That is, the client supplies a Squeak string describing the path to the directory on every call. To avoid traversing this path on every call, a cache is maintained of the last path seen, along with the Mac volume and folder reference numbers corresponding to that path. ***/ /*** Constants ***/ #define ENTRY_FOUND 0 #define NO_MORE_ENTRIES 1 #define BAD_PATH 2 #define DELIMITOR '':'' #define MAX_PATH 2000 /*** Variables ***/ char lastPath[MAX_PATH + 1]; int lastPathValid = false; FSSpec lastSpec; /*** Functions ***/ int convertToSqueakTime(int macTime); int equalsLastPath(char *pathString, int pathStringLength); int lookupPath(char *pathString, int pathStringLength, FSSpec *spec,Boolean noDrillDown); int recordPath(char *pathString, int pathStringLength, FSSpec *spec); void makePascalStringFromSqName(char *pathString, int pathStringLength,unsigned char *name); OSErr makeFSSpec(char *pathString, int pathStringLength,FSSpec *spec); OSErr getSpecAndFInfo(char *filename, int filenameSize,FSSpec *spec,FInfo *finderInfo); int fetchFileInfo(CInfoPBRec *pb,int dirIndex,FSSpec *spec,unsigned char *name, Boolean doAlias, Boolean *isFolder); int doItTheHardWay(unsigned char *pathString,FSSpec *spec,CInfoPBRec *pb,Boolean noDrillDown); pascal OSErr FSMakeFSSpecCompat(short vRefNum, long dirID, ConstStr255Param fileName, FSSpec *spec); OSErr FSpLocationFromFullPath(short fullPathLength, const void *fullPath, FSSpec *spec); pascal OSErr GetFullPath(short vRefNum, long dirID, ConstStr255Param name, short *fullPathLength, Handle *fullPath); pascal OSErr FSpGetFullPath(const FSSpec *spec, short *fullPathLength, Handle *fullPath); OSErr squeakFindImage(const FSSpecPtr defaultLocationfssPtr,FSSpecPtr documentfsSpec); pascal void findImageEventProc(NavEventCallbackMessage callBackSelector, NavCBRecPtr callBackParms, NavCallBackUserData callBackUD); pascal Boolean findImageFilterProc(AEDesc* theItem, void* info, NavCallBackUserData callBackUD, NavFilterModes filterMode); pascal short DialogHook(short item, DialogPtr theDialog, void *userData); OSErr __path2fss(const char * pathName, FSSpecPtr spec) { return lookupPath((char *) pathName, strlen(pathName),spec,true); } int convertToSqueakTime(int macTime) { /* Squeak epoch is Jan 1, 1901, 3 non-leap years earlier than Mac one */ return macTime + (3 * 365 * 24 * 60 * 60); } void makePascalStringFromSqName(char *pathString, int pathStringLength,unsigned char *name) { /* copy file name into a Pascal string */ name[0] = pathStringLength; strncpy((char *)name+1,pathString,pathStringLength); } OSErr makeFSSpec(char *pathString, int pathStringLength,FSSpec *spec) { char name[256]; if (pathStringLength > 255 ) return -1; strncpy((char *) name,pathString,pathStringLength); name[pathStringLength] = 0x00; return __path2fss((char *) name, spec); } int dir_Create(char *pathString, int pathStringLength) { /* Create a new directory with the given path. By default, this directory is created in the current directory. Use a full path name such as "MyDisk:Working:New Folder" to create folders elsewhere. */ //JMM tests create file in Vm directory, other place, other volume FSSpec spec; OSErr err; long createdDirID; if ((err = makeFSSpec(pathString, pathStringLength,&spec)) == -1) return false; return FSpDirCreate(&spec,smSystemScript,&createdDirID) == noErr; } int dir_Delete(char *pathString, int pathStringLength) { /* Delete the existing directory with the given path. */ FSSpec spec; OSErr err; if ((err = makeFSSpec(pathString, pathStringLength,&spec)) == -1) return false; return FSpDelete(&spec) == noErr; } int dir_Delimitor(void) { return DELIMITOR; } int dir_Lookup(char *pathString, int pathStringLength, int index, /* outputs: */ char *name, int *nameLength, int *creationDate, int *modificationDate, int *isDirectory, int *sizeIfFile) { /* Lookup the index-th entry of the directory with the given path, starting at the root of the file system. Set the name, name length, creation date, creation time, directory flag, and file size (if the entry is a file). Return: 0 if a entry is found at the given index 1 if the directory has fewer than index entries 2 if the given path has bad syntax or does not reach a directory */ int okay; HVolumeParam volumeParams; CInfoPBRec dirParams; FSSpec spec; Boolean isFolder; OSErr err; /* default return values */ *name = 0; *nameLength = 0; *creationDate = 0; *modificationDate = 0; *isDirectory = false; *sizeIfFile = 0; if ((pathStringLength == 0)) { /* get volume info */ volumeParams.ioNamePtr = (unsigned char *) name; volumeParams.ioVRefNum = 0; volumeParams.ioVolIndex = index; okay = PBHGetVInfoSync((HParmBlkPtr) &volumeParams) == noErr; if (okay) { CopyPascalStringToC((ConstStr255Param) name,name); *nameLength = strlen(name); *creationDate = convertToSqueakTime(volumeParams.ioVCrDate); *modificationDate = convertToSqueakTime(volumeParams.ioVLsMod); *isDirectory = true; *sizeIfFile = 0; return ENTRY_FOUND; } else { return NO_MORE_ENTRIES; } } else { /* get file or directory info */ if (!!equalsLastPath(pathString, pathStringLength)) { /* lookup and cache the refNum for this path */ err = lookupPath(pathString, pathStringLength, &spec,false); if (err == noErr) recordPath(pathString, pathStringLength, &spec); else return BAD_PATH; } spec = lastSpec; okay = fetchFileInfo(&dirParams,index,&spec,(unsigned char *) name,true,&isFolder); if (okay) { CopyPascalStringToC((ConstStr255Param) name,name); *nameLength = strlen(name); *creationDate = convertToSqueakTime(dirParams.hFileInfo.ioFlCrDat); *modificationDate = convertToSqueakTime(dirParams.hFileInfo.ioFlMdDat); if (((dirParams.hFileInfo.ioFlAttrib & kioFlAttribDirMask) !!= 0) || isFolder) { *isDirectory = true; *sizeIfFile = 0; } else { *isDirectory = false; *sizeIfFile = dirParams.hFileInfo.ioFlLgLen; } return ENTRY_FOUND; } else return NO_MORE_ENTRIES; } } OSErr getSpecAndFInfo(char *filename, int filenameSize,FSSpec *spec,FInfo *finderInfo) { OSErr err; if ((err = makeFSSpec(filename, filenameSize,spec)) !!= noErr) return err; if ((err= FSpGetFInfo(spec,finderInfo)) !!= noErr) return err; return noErr; } dir_SetMacFileTypeAndCreator(char *filename, int filenameSize, char *fType, char *fCreator) { /* Set the Macintosh type and creator of the given file. */ /* Note: On other platforms, this is just a noop. */ FSSpec spec; FInfo finderInfo; if (getSpecAndFInfo(filename,filenameSize,&spec,&finderInfo) !!= noErr) return false; finderInfo.fdType = *((int *) fType); finderInfo.fdCreator = *((int *) fCreator); return FSpSetFInfo(&spec,&finderInfo) == noErr; } dir_GetMacFileTypeAndCreator(char *filename, int filenameSize, char *fType, char *fCreator) { /* Get the Macintosh type and creator of the given file. */ /* Note: On other platforms, this is just a noop. */ FSSpec spec; FInfo finderInfo; if (getSpecAndFInfo(filename,filenameSize,&spec,&finderInfo) !!= noErr) return false; *((int *) fType) = finderInfo.fdType; *((int *) fCreator) = finderInfo.fdCreator; return true; } int equalsLastPath(char *pathString, int pathStringLength) { /* Return true if the lastPath cache is valid and the given Squeak string equals it. */ int i, ch; if (!!lastPathValid || (pathStringLength > MAX_PATH)) { return false; } for (i = 0; i < pathStringLength; i++) { ch = lastPath[i]; if ((ch == 0) || (ch !!= pathString[i])) return false; } return lastPath[i] == 0; } /* JMM 2001/02/02 rewrote */ int lookupPath(char *pathString, int pathStringLength, FSSpec *spec,Boolean noDrillDown) { /* Resolve the given path and return the resulting folder or volume reference number in *refNumPtr. Return error if the path is bad. */ CInfoPBRec pb; Str255 tempName; OSErr err,err2; Boolean isFolder,isAlias; /* First locate by farily normal methods, with perhaps an alias lookup */ err = FSpLocationFromFullPath(pathStringLength, pathString, spec); err2 = ResolveAliasFile(spec,true,&isFolder,&isAlias); if (err == noErr && !!isAlias) return noErr; /* Than failed, we might have an alias change, or other issue so first setup for directory or file then do it the hard way */ strncpy((char *)tempName,pathString,pathStringLength); if (noDrillDown) { tempName[pathStringLength] = 0x00; } else { tempName[pathStringLength] = '':''; tempName[pathStringLength+1] = 0x00; } err = doItTheHardWay(tempName,spec,&pb,noDrillDown); return err; } /* This method is used to lookup paths, chunk by chunk. It builds specs for each chuck and fetchs the file information, Note the special case when noDrilldown */ int doItTheHardWay(unsigned char *pathString,FSSpec *spec,CInfoPBRec *pb,Boolean noDrillDown) { char *token; Str63 lookup; Boolean ignore,firstTime=true; OSErr err; token = strtok((char*) pathString,":"); if (token == 0) return -1; while (token) { if (firstTime) { strncpy((char*) lookup+1,(char*) token,63); lookup[0] = strlen(token)+1; lookup[lookup[0]] = '':''; firstTime = false; } else { strncpy((char*) lookup+2,(char*) token,63); lookup[0] = strlen(token)+1; lookup[1] = '':''; } if ((err = FSMakeFSSpecCompat(spec->vRefNum,spec->parID, lookup, spec)) !!= noErr) return err; fetchFileInfo(pb,0,spec,spec->name,true,&ignore); token = strtok(NULL,":"); } if (noDrillDown) spec->parID = pb->dirInfo.ioDrParID; return noErr; } /*Get the file ID that unique IDs this file or directory, also resolve any alias if required */ int fetchFileInfo(CInfoPBRec *pb,int dirIndex,FSSpec *spec,unsigned char *name,Boolean doAlias,Boolean *isFolder) { int i; for(i=0;ihFileInfo.ioNamePtr = name; pb->hFileInfo.ioFVersNum = 0; pb->hFileInfo.ioFDirIndex = dirIndex; pb->hFileInfo.ioVRefNum = spec->vRefNum; pb->hFileInfo.ioDirID = spec->parID; if (PBGetCatInfoSync(pb) == noErr) { if ((pb->hFileInfo.ioFlFndrInfo.fdFlags & kIsAlias) && doAlias) { FSSpec spec2; Boolean isAlias; OSErr err; err = FSMakeFSSpecCompat(spec->vRefNum, spec->parID, name,&spec2); err = ResolveAliasFile(&spec2,false,isFolder,&isAlias); if (err == noErr) { if (dirIndex == 0) { fetchFileInfo(pb,dirIndex,&spec2,spec2.name,false,isFolder); *spec = spec2; } return true; } } spec->parID = pb->hFileInfo.ioDirID; return true; } return false; } int recordPath(char *pathString, int pathStringLength, FSSpec *spec) { /* Copy the given Squeak string into the lastPath cache. */ if (pathStringLength > MAX_PATH) { lastPath[0] = 0; /* set to empty string */ lastPathValid = false; lastSpec = *spec; return; } strncpy(lastPath,pathString,pathStringLength); lastPath[pathStringLength] = 0; /* string terminator */ lastPathValid = true; lastSpec = *spec; } pascal OSErr GetFullPath(short vRefNum, long dirID, ConstStr255Param name, short *fullPathLength, Handle *fullPath) { OSErr result; FSSpec spec; *fullPathLength = 0; *fullPath = NULL; result = FSMakeFSSpecCompat(vRefNum, dirID, name, &spec); if ( (result == noErr) || (result == fnfErr) ) { result = FSpGetFullPath(&spec, fullPathLength, fullPath); } return ( result ); } pascal OSErr FSpGetFullPath(const FSSpec *spec, short *fullPathLength, Handle *fullPath) { OSErr result; OSErr realResult; FSSpec tempSpec; CInfoPBRec pb; *fullPathLength = 0; *fullPath = NULL; /* Default to noErr */ realResult = result = noErr; #if 0 //The following code doesn''t seem to work in OS X, the BlockMoveData crashes the // machine, the the FSMakeFSSpecCompat works, so go figure... KG 4/1/01 /* work around Nav Services "bug" (it returns invalid FSSpecs with empty names) */ if ( spec->name[0] == 0 ) { result = FSMakeFSSpecCompat(spec->vRefNum, spec->parID, spec->name, &tempSpec); } else { /* Make a copy of the input FSSpec that can be modified */ BlockMoveData(spec, &tempSpec, sizeof(FSSpec)); } #endif 0 result = FSMakeFSSpecCompat(spec->vRefNum, spec->parID, spec->name, &tempSpec); if ( result == noErr ) { if ( tempSpec.parID == fsRtParID ) { /* The object is a volume */ /* Add a colon to make it a full pathname */ ++tempSpec.name[0]; tempSpec.name[tempSpec.name[0]] = '':''; /* We''re done */ result = PtrToHand(&tempSpec.name[1], fullPath, tempSpec.name[0]); *fullPathLength = tempSpec.name[0]; } else { /* The object isn''t a volume */ /* Is the object a file or a directory? */ pb.dirInfo.ioNamePtr = tempSpec.name; pb.dirInfo.ioVRefNum = tempSpec.vRefNum; pb.dirInfo.ioDrDirID = tempSpec.parID; pb.dirInfo.ioFDirIndex = 0; result = PBGetCatInfoSync(&pb); // Allow file/directory name at end of path to not exist. realResult = result; if ( (result == noErr) || (result == fnfErr) ) { /* if the object is a directory, append a colon so full pathname ends with colon */ if ( (result == noErr) && (pb.hFileInfo.ioFlAttrib & kioFlAttribDirMask) !!= 0 ) { ++tempSpec.name[0]; tempSpec.name[tempSpec.name[0]] = '':''; } /* Put the object name in first */ result = PtrToHand(&tempSpec.name[1], fullPath, tempSpec.name[0]); *fullPathLength = tempSpec.name[0]; if ( result == noErr ) { /* Get the ancestor directory names */ pb.dirInfo.ioNamePtr = tempSpec.name; pb.dirInfo.ioVRefNum = tempSpec.vRefNum; pb.dirInfo.ioDrParID = tempSpec.parID; do /* loop until we have an error or find the root directory */ { pb.dirInfo.ioFDirIndex = -1; pb.dirInfo.ioDrDirID = pb.dirInfo.ioDrParID; result = PBGetCatInfoSync(&pb); if ( result == noErr ) { /* Append colon to directory name */ ++tempSpec.name[0]; tempSpec.name[tempSpec.name[0]] = '':''; /* Add directory name to beginning of fullPath */ (void) Munger(*fullPath, 0, NULL, 0, &tempSpec.name[1], tempSpec.name[0]); *fullPathLength += tempSpec.name[0]; result = MemError(); } } while ( (result == noErr) && (pb.dirInfo.ioDrDirID !!= fsRtDirID) ); } } } } if ( result == noErr ) { /* Return the length */ /// *fullPathLength = GetHandleSize(*fullPath); result = realResult; // return realResult in case it was fnfErr } else { /* Dispose of the handle and return NULL and zero length */ if ( *fullPath !!= NULL ) { DisposeHandle(*fullPath); } *fullPath = NULL; *fullPathLength = 0; } return ( result ); } pascal OSErr FSMakeFSSpecCompat(short vRefNum, long dirID, ConstStr255Param fileName, FSSpec *spec) { OSErr result; /* Let the file system create the FSSpec if it can since it does the job */ /* much more efficiently than I can. */ result = FSMakeFSSpec(vRefNum, dirID, fileName, spec); /* Fix a bug in Macintosh PC Exchange''s MakeFSSpec code where 0 is */ /* returned in the parID field when making an FSSpec to the volume''s */ /* root directory by passing a full pathname in MakeFSSpec''s */ /* fileName parameter. Fixed in Mac OS 8.1 */ if ( (result == noErr) && (spec->parID == 0) ) spec->parID = fsRtParID; return ( result ); } OSErr FSpLocationFromFullPath(short fullPathLength, const void *fullPath, FSSpec *spec) { AliasHandle alias; OSErr result; Boolean wasChanged; Str32 nullString; /* Create a minimal alias from the full pathname */ nullString[0] = 0; /* null string to indicate no zone or server name */ result = NewAliasMinimalFromFullPath(fullPathLength, fullPath, nullString, nullString, &alias); if ( result == noErr ) { /* Let the Alias Manager resolve the alias. */ result = ResolveAlias(NULL, alias, spec, &wasChanged); /* work around Alias Mgr sloppy volume matching bug */ if ( spec->vRefNum == 0 ) { /* invalidate wrong FSSpec */ spec->parID = 0; spec->name[0] = 0; result = nsvErr; } DisposeHandle((Handle)alias); /* Free up memory used */ } return ( result ); } typedef struct { StandardFileReply *theSFR; FSSpec *itemSpec; } HookRecord, *HookRecordPtr; OSErr squeakFindImage(const FSSpecPtr defaultLocationfssPtr,FSSpecPtr documentFSSpec) { NavDialogOptions dialogOptions; AEDesc defaultLocation; NavEventUPP eventProc = NewNavEventUPP(findImageEventProc); NavObjectFilterUPP filterProc = NewNavObjectFilterUPP(findImageFilterProc); OSErr anErr = noErr; #if !!TARGET_API_MAC_CARBON if ((Ptr) NavGetDefaultDialogOptions==(Ptr)kUnresolvedCFragSymbolAddress ) { //System pre 8.5 or system 7.x // point my hook data record at the reply record and at // the file spec for the system file StandardFileReply mySFR; HookRecord hookRec; DlgHookYDUPP myDlgHookUPP; SFTypeList mySFTypeList; Point dialogPt; hookRec.itemSpec = defaultLocationfssPtr; hookRec.theSFR = &mySFR; SetPt(&dialogPt, -1, -1); // Set up the universal proc pointer to your hook routine with this // macro defined in StandardFile.h. **NOTE** This is different // from the macro used for System 6 dialog hooks, and you should get // a compiler error if you try to use the wrong UPP with the wrong call. myDlgHookUPP = NewDlgHookYDProc(DialogHook); // call Std File CustomGetFile(nil, -1, mySFTypeList, &mySFR, 0, dialogPt, myDlgHookUPP, nil, nil, nil, &hookRec); // Dispose of the routine descriptor, since they do allocate memory.. DisposeRoutineDescriptor(myDlgHookUPP); *documentFSSpec = mySFR.sfFile; return noErr; } #endif // Specify default options for dialog box anErr = NavGetDefaultDialogOptions(&dialogOptions); if (anErr == noErr) { // Adjust the options to fit our needs // Set default location option dialogOptions.dialogOptionFlags |= kNavSelectDefaultLocation; dialogOptions.dialogOptionFlags |= kNavNoTypePopup; // Clear preview option dialogOptions.dialogOptionFlags ^= kNavAllowPreviews; // make descriptor for default location anErr = AECreateDesc(typeFSS, defaultLocationfssPtr, sizeof(*defaultLocationfssPtr), &defaultLocation ); if (anErr == noErr) { // Get ''open'' resource. A nil handle being returned is OK, // this simply means no automatic file filtering. NavTypeListHandle typeList = (NavTypeListHandle)GetResource( ''open'', 128); NavReplyRecord reply; // Call NavGetFile() with specified options and // declare our app-defined functions and type list anErr = NavGetFile (&defaultLocation, &reply, &dialogOptions, eventProc, nil, filterProc, typeList, nil); if (anErr == noErr && reply.validRecord) { // Deal with multiple file selection long count; anErr = AECountItems(&(reply.selection), &count); // Set up index for file list if (anErr == noErr) { long index; for (index = 1; index <= 1; index++) { AEKeyword theKeyword; DescType actualType; Size actualSize; // Get a pointer to selected file anErr = AEGetNthPtr(&(reply.selection), index, typeFSS, &theKeyword, &actualType,documentFSSpec, sizeof(FSSpec), &actualSize); } } // Dispose of NavReplyRecord, resources, descriptors anErr = NavDisposeReply(&reply); } if (typeList !!= NULL) { ReleaseResource( (Handle)typeList); } (void) AEDisposeDesc(&defaultLocation); } } DisposeNavEventUPP(eventProc); DisposeNavObjectFilterUPP(filterProc); return anErr; } pascal void findImageEventProc(NavEventCallbackMessage callBackSelector, NavCBRecPtr callBackParms, NavCallBackUserData callBackUD) { // WindowPtr window = // (WindowPtr)callBackParms->eventData.event->message; switch (callBackSelector) { case kNavCBEvent: switch (((callBackParms->eventData) .eventDataParms).event->what) { case updateEvt: // MyHandleUpdateEvent(window, // (EventRecord*)callBackParms->eventData.event); break; } break; } } pascal Boolean findImageFilterProc(AEDesc* theItem, void* info, NavCallBackUserData callBackUD, NavFilterModes filterMode) { OSErr theErr = noErr; Boolean display = true; NavFileOrFolderInfo* theInfo = (NavFileOrFolderInfo*)info; if (theItem->descriptorType == typeFSS) if (!!theInfo->isFolder) if (theInfo->fileAndFolder.fileInfo.finderInfo.fdType !!= ''STim'') display = false; return display; } #if !!TARGET_API_MAC_CARBON // this dialog hook for System 7 std file selects // the file specified by the hookRecord supplied as userData pascal short DialogHook(short item, DialogPtr theDialog, void *userData) { HookRecordPtr hookRecPtr; hookRecPtr = (HookRecordPtr) userData; // hookRecPtr->itemSpec points to the FSSpec of the item to be selected // hookRecPtr->theSFR points to the standard file reply record // make sure we''re dealing with the proper dialog if (GetWRefCon(theDialog) == sfMainDialogRefCon) { // just when opening the dialog... if (item == sfHookFirstCall) { // make the reply record hold the spec of the specified item hookRecPtr->theSFR->sfFile = *hookRecPtr->itemSpec; // ThereÕs a gotcha in Standard File when using sfHookChangeSelection. // Even though New Inside Macintosh: Files has a sample that doesn''t set // the sfScript field, it should be set, or the last object in the // selected directory will always be selected. hookRecPtr->theSFR->sfScript = smSystemScript; // tell std file to change the selection to that item item = sfHookChangeSelection; } } return item; } #endif '! ! !InterpreterSupportCode class methodsFor: 'source files' stamp: 'JMM 2/12/2001 16:23'! macDragDropFile ^ '/* Jan 24th 2001 Drag and drop support for Squeak John M McIntosh of Corporate Smalltalk Consulting Ltd johnmci@smalltalkconsulting.com http://www.smalltalkconsulting.com In Jan of 2001 under contract to Disney Dragging is only for objects into Squeak, not from Squeak outwards. V1.0 Jan 24th 2001, JMM Some of this code comes from Author: John Montbriand Some techniques borrowed from Pete Gontier''s original FinderDragPro. Copyright: Copyright: © 1999 by Apple Computer, Inc. all rights reserved. Disclaimer: You may incorporate this sample code into your applications without restriction, though the sample code has been provided "AS IS" and the responsibility for its operation is 100% yours. However, what you are not permitted to do is to redistribute the source as "DSC Sample Code" after having made changes. If you''re going to re-distribute the source, we require that you make it clear in the source that the code was descended from Apple Sample Code, but that you''ve made changes. Change History (most recent first): 9/9/99 by John Montbriand */ /* need get filetype/creator need DropPlugin_shutdownModule & dropShutdown */ #include "sq.h" #include #include #include #include #include "sqVirtualMachine.h" #include "FilePlugin.h" #include "DropPlugin.h" #if TARGET_API_MAC_CARBON #else inline Rect *GetPortBounds(CGrafPtr w,Rect *r) { *r = w->portRect; return &w->portRect;} #endif /* promise flavor types */ enum { kPromisedFlavor = ''fssP'', /* default promise */ kPromisedFlavorFindFile = ''rWm1'' /* Find File promise -- special case */ }; Boolean gHasDragManager = false; /* true if the Drag Manager is installed */ Boolean gCanTranslucentDrag = false; /* true if translucent dragging is available */ DragReceiveHandlerUPP gMainReceiveHandler = NULL; /* receive handler for the main dialog */ DragTrackingHandlerUPP gMainTrackingHandler = NULL; /* tracking handler for the main dialog */ WindowPtr gWindowPtr; extern Boolean gAllowAccessToFilePlease; UInt16 gNumDropFiles=0; HFSFlavor *dropFiles; #define DOCUMENT_NAME_SIZE 300 char tempName[DOCUMENT_NAME_SIZE + 1]; /* these routines are used both in the receive handler and inside of the tracking handler. The following variables are shared between MyDragTrackingHandler and MyDragReceiveHandler. */ Boolean gApprovedDrag = false; /* set to true if the drag is approved */ Boolean gInIconBox = false; /* set true if the drag is inside our drop box */ extern struct VirtualMachine *interpreterProxy; extern WindowPtr getSTWindow(void); pascal OSErr MyDragTrackingHandler(DragTrackingMessage message, WindowPtr theWindow, void *refCon, DragReference theDragRef); pascal OSErr MyDragReceiveHandler(WindowPtr theWindow, void *refcon, DragReference theDragRef); extern int (*instantiateClassindexableSize)(int classPointer, int size); extern int classByteArray(void); extern int fileRecordSize(void); extern int sqFileOpen(SQFile *f, int sqFileNameIndex, int sqFileNameSize, int writeFlag); extern SQFile * fileValueOf(int objectPointer); extern int recordDragDropEvent(EventRecord *theEvent, int theButtonState, int numberOfItems, int dragType); extern int MouseModifierState(EventRecord *theEvent); extern void StoreFullPathForLocalNameInto(char *shortName, char *fullName, int length, short VolumeNumber,long directoryID); // Startup logic int dropInit(void) { long response; long fn; Boolean installedReceiver=false, installedTracker=false; OSErr err; /* check for the drag manager & translucent feature??? */ if (gMainReceiveHandler !!= NULL) return 1; if (Gestalt(gestaltDragMgrAttr, &response) !!= noErr) return 0; gHasDragManager = (((1 << gestaltDragMgrPresent)) !!= 0); gCanTranslucentDrag = (((1 << gestaltDragMgrHasImageSupport)) !!= 0); if (!!(gHasDragManager && gCanTranslucentDrag)) return 0; if ((Ptr)InstallTrackingHandler==(Ptr)kUnresolvedCFragSymbolAddress) return 0; gWindowPtr = getSTWindow(); gMainTrackingHandler = NewDragTrackingHandlerUPP(MyDragTrackingHandler); if (gMainTrackingHandler == NULL) return 0; gMainReceiveHandler = NewDragReceiveHandlerUPP(MyDragReceiveHandler); if (gMainReceiveHandler == NULL) return 0; /* install the drag handlers, don''t forget to dispose of them later */ err = InstallTrackingHandler(gMainTrackingHandler, gWindowPtr, NULL); if (err !!= noErr) { err = memFullErr; goto bail; } installedTracker = true; err = InstallReceiveHandler(gMainReceiveHandler, gWindowPtr, NULL); if (err !!= noErr) { err = memFullErr; goto bail; } installedReceiver = true; return 1; bail: if (installedReceiver) RemoveReceiveHandler(gMainReceiveHandler, gWindowPtr); if (installedTracker) RemoveTrackingHandler(gMainTrackingHandler, gWindowPtr); gMainTrackingHandler = NULL; gMainReceiveHandler = NULL; return 0; } // Shutdown logic int dropShutdown() { if (gMainReceiveHandler !!= NULL) RemoveReceiveHandler(gMainReceiveHandler, gWindowPtr); if (gMainTrackingHandler !!= NULL) RemoveTrackingHandler(gMainTrackingHandler, gWindowPtr); if (gNumDropFiles !!= 0 ) { DisposePtr((char *) dropFiles); gNumDropFiles = 0; } gMainTrackingHandler = NULL; gMainReceiveHandler = NULL; } //Primitive to get file name char *dropRequestFileName(int dropIndex) { char shortName[256]; if(dropIndex < 1 || dropIndex > gNumDropFiles) return NULL; CopyPascalStringToC(dropFiles[dropIndex-1].fileSpec.name,shortName); StoreFullPathForLocalNameInto(shortName, tempName, DOCUMENT_NAME_SIZE, dropFiles[dropIndex-1].fileSpec.vRefNum, dropFiles[dropIndex-1].fileSpec.parID); return tempName; } //Primitive to get file stream handle. int dropRequestFileHandle(int dropIndex) { int fileHandle; int size,classPointer; char *dropName = dropRequestFileName(dropIndex); if(!!dropName) return interpreterProxy->nilObject(); size = fileRecordSize(); classPointer = interpreterProxy->classByteArray(); fileHandle = interpreterProxy->instantiateClassindexableSize(classPointer, size); gAllowAccessToFilePlease = true; sqFileOpen(fileValueOf(fileHandle),(int)dropName, strlen(dropName), 0); gAllowAccessToFilePlease = false; return fileHandle; } /* RECEIVING DRAGS ------------------------------------------------ */ /* ApproveDragReference is called by the drag tracking handler to determine if the contents of the drag can be handled by our receive handler. Note that if a flavor can''t be found, it''s not really an error; it only means the flavor wasn''t there and we should not accept the drag. Therefore, we translate ''badDragFlavorErr'' into a ''false'' value for ''*approved''. */ static pascal OSErr ApproveDragReference(DragReference theDragRef, Boolean *approved) { OSErr err; DragAttributes dragAttrs; FlavorFlags flavorFlags; ItemReference theItem; /* we cannot drag to our own window */ if ((err = GetDragAttributes(theDragRef, &dragAttrs)) !!= noErr) goto bail; if ((dragAttrs & kDragInsideSenderWindow) !!= 0) { err = userCanceledErr; goto bail; } /* gather information about the drag & a reference to item one. */ if ((err = GetDragItemReferenceNumber(theDragRef, 1, &theItem)) !!= noErr) goto bail; /* check for flavorTypeHFS */ err = GetFlavorFlags(theDragRef, theItem, flavorTypeHFS, &flavorFlags); if (err == noErr) { *approved = true; return noErr; } else if (err !!= badDragFlavorErr) goto bail; /* check for flavorTypePromiseHFS */ err = GetFlavorFlags(theDragRef, theItem, flavorTypePromiseHFS, &flavorFlags); if (err == noErr) { *approved = true; return noErr; } else if (err !!= badDragFlavorErr) goto bail; /* none of our flavors were found */ *approved = false; return noErr; bail: /* an error occured, clean up. set result to false. */ *approved = false; return err; } /* MyDragTrackingHandler is called for tracking the mouse while a drag is passing over our window. if the drag is approved, then the drop box will be hilitied appropriately as the mouse passes over it. */ static pascal OSErr MyDragTrackingHandler(DragTrackingMessage message, WindowPtr theWindow, void *refCon, DragReference theDragRef) { /* we''re drawing into the image well if we hilite... */ Rect bounds; EventRecord theEvent; switch (message) { case kDragTrackingEnterWindow: { Point mouse; gApprovedDrag = false; if (theWindow == gWindowPtr) { if (ApproveDragReference(theDragRef, &gApprovedDrag) !!= noErr) break; if ( !! gApprovedDrag ) break; SetPortWindowPort(theWindow); GetMouse(&mouse); GetPortBounds(GetWindowPort(gWindowPtr),&bounds); if (PtInRect(mouse, &bounds)) { // if we''re in the box, hilite... gInIconBox = true; /* queue up an event */ WaitNextEvent(0, &theEvent,0,null); recordDragDropEvent(&theEvent, MouseModifierState(&theEvent),gNumDropFiles,DragEnter); } } } break; case kDragTrackingInWindow: if (gApprovedDrag) { WaitNextEvent(0, &theEvent,0,null); recordDragDropEvent(&theEvent, MouseModifierState(&theEvent),gNumDropFiles,DragMove); } break; case kDragTrackingLeaveWindow: if (gApprovedDrag && gInIconBox) { /* queue up an event */ WaitNextEvent(0, &theEvent,0,null); recordDragDropEvent(&theEvent, MouseModifierState(&theEvent),gNumDropFiles,DragLeave); } gApprovedDrag = gInIconBox = false; break; } return noErr; // there''s no point in confusing Drag Manager or its caller } /* MyDragReceiveHandler is the receive handler for the main window. It is called when a file or folder (or a promised file or folder) is dropped into the drop box in the main window. Here, if the drag reference has been approved in the track drag call, we handle three different cases: 1. standard hfs flavors, 2. promised flavors provided by find file, mmmm This may be a pre sherlock issue 3. promised flavors provided by other applications. */ static pascal OSErr MyDragReceiveHandler(WindowPtr theWindow, void *refcon, DragReference theDragRef) { ItemReference theItem; PromiseHFSFlavor targetPromise; Size theSize; OSErr err; EventRecord theEvent; long i,countActualItems; FInfo finderInfo; HFSFlavor targetHFSFlavor; /* validate the drag. Recall the receive handler will only be called after the tracking handler has received a kDragTrackingInWindow event. As a result, the gApprovedDrag and gInIconBox will be defined when we arrive here. Hence, there is no need to spend extra time validating the drag at this point. */ if ( !! (gApprovedDrag && gInIconBox) ) return userCanceledErr; if (gNumDropFiles !!=0 ) DisposePtr((char *) dropFiles); if ((err = CountDragItems(theDragRef, &gNumDropFiles)) !!= noErr) return paramErr; dropFiles = (HFSFlavor *) NewPtr(sizeof(HFSFlavor)*gNumDropFiles); if (dropFiles == null) return userCanceledErr; WaitNextEvent(0, &theEvent,0,null); countActualItems = 0; for(i=1;i<=gNumDropFiles;i++) { /* get the first item reference */ if ((err = GetDragItemReferenceNumber(theDragRef, i, &theItem)) !!= noErr) continue; /* try to get a HFSFlavor*/ theSize = sizeof(HFSFlavor); err = GetFlavorData(theDragRef, theItem, flavorTypeHFS, &targetHFSFlavor, &theSize, 0); if (err == noErr) { if (dropFiles[countActualItems].fileCreator == ''MACS'' && ( dropFiles[countActualItems].fileType == ''fold'' || dropFiles[countActualItems].fileType == ''disk'')) continue; dropFiles[countActualItems] = targetHFSFlavor; countActualItems++; continue; } else if (err !!= badDragFlavorErr) continue; /* try to get a promised HFSFlavor*/ theSize = sizeof(PromiseHFSFlavor); err = GetFlavorData(theDragRef, theItem, flavorTypePromiseHFS, &targetPromise, &theSize, 0); if (err !!= noErr) continue; /* check for a drop from find file */ if (targetPromise.promisedFlavor == kPromisedFlavorFindFile) { /* from find file, no need to set the file location... */ theSize = sizeof(FSSpec); err = GetFlavorData(theDragRef, theItem, targetPromise.promisedFlavor, &dropFiles[countActualItems].fileSpec, &theSize, 0); if (err !!= noErr) continue; HGetFInfo(dropFiles[countActualItems].fileSpec.vRefNum,dropFiles[countActualItems].fileSpec.parID,dropFiles[countActualItems].fileSpec.name, &finderInfo); /* queue up an event */ dropFiles[countActualItems].fileType = finderInfo.fdType; dropFiles[countActualItems].fileCreator = finderInfo.fdCreator; dropFiles[countActualItems].fdFlags = finderInfo.fdFlags; countActualItems++; } else { err = badDragFlavorErr; return err; } } gNumDropFiles = countActualItems; if (gNumDropFiles == 0) { DisposePtr((char *) dropFiles); return noErr; } /* queue up an event */ recordDragDropEvent(&theEvent, MouseModifierState(&theEvent),gNumDropFiles,DragDrop); return noErr; } '! ! !InterpreterSupportCode class methodsFor: 'source files' stamp: 'JMM 2/12/2001 16:26'! macSecurityFile ^ '#include "sq.h" #define fromSqueak(string,length) string char * GetAttributeString(int id); void fixPath(char *path); int PathToWorkingDir(char *pathName, int pathNameMax, short volumeNumber,long directoryID); static char secureUserDirectory[256]; static char untrustedUserDirectory[256]; /***************************************************************************/ /***************************************************************************/ /***************************************************************************/ /***************************************************************************/ /* file security */ static int allowFileAccess = 1; /* full access to files */ static int isAccessiblePathName(char *pathName) { int i; /* Check if the path/file name is subdirectory of the image path */ for(i=0; i0;i--) if(path[i-1]=='':'') { path[i-1]=0x00; return; } } '! ! !InterpreterSupportCode class methodsFor: 'source files' stamp: 'JMM 2/12/2001 22:01'! macWindowFile ^ '#include "sq.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef __MPW__ #include #endif #include #include #ifndef __MPW__ #include #endif #include #include #include #include #include /*** Compilation Options: * * define PLUGIN to compile code for Netscape or IE Plug-in * define MAKE_PROFILE to compile code for profiling * ***/ //#define PLUGIN //#define MAKE_PROFILE //#define IHAVENOHEAD //Aug 7th 2000,JMM Added logic for interrupt driven dispatching //Sept 1st 2000, JMM fix problem with modifier information being passed back incorrectly. //Sept 1st 2000, JMM use floating point for time versus 64bit math (faster!!) //Sept 1st 2000, JMM watch mouse movement foreground only, ignore when squeak in background. //Sept 18th 2000, JMM fix to cmpSize //Sept 19th 2000, JMM Sept 1st fix to keyboard modifier info broke cmd shift //Sept 27 2000, JMM fix to documentPath //Nov 13 2000, JMM logic to read/write image from VM. //Nov 22 2000, JMM Bob Arning found a bug with the duplicate mouse event logic (we were altering the event then recording the altered value) //Nov 30 2000, JMM Use Open Transport clock versus upTime, solves some issues for jitter and it''s faster //Dec 5th 2000, JMM poll 60 times a second... do event polling via checkForInterrupts and drive semaphore //Dec 6th 2000, JMM added logic to interface with power manger (1997 was there but dropped..., back again for ibooks) //Jan 14th 2001, KG Did some carbon porting. //Feb 2nd 2001, JMM V3.0 added zoom window support, full path support //Feb 2nd 2001, JMM V3.04 do an open window dialog at startup time if no image file #if TARGET_API_MAC_CARBON #define EnableMenuItemCarbon(m1,v1) EnableMenuItem(m1,v1); #define DisableMenuItemCarbon(m1,v1) DisableMenuItem(m1,v1); #else #ifndef NewAEEventHandlerUPP #define NewAEEventHandlerUPP NewAEEventHandlerProc #endif #define EnableMenuItemCarbon(m1,v1) EnableItem(m1,v1); #define DisableMenuItemCarbon(m1,v1) DisableItem(m1,v1); inline Rect *GetPortBounds(CGrafPtr w,Rect *r) { *r = w->portRect; return &w->portRect;} inline Rect *GetRegionBounds(RgnHandle region, Rect * bounds) { *bounds = (*region)->rgnBBox; return &(*region)->rgnBBox;} inline BitMap *GetQDGlobalsScreenBits(BitMap *bm){*bm = qd.screenBits; return &qd.screenBits; } inline BitMap * GetPortBitMapForCopyBits (CGrafPtr w) { return &((GrafPtr)w)->portBits;} inline pascal long InvalWindowRect(WindowRef window, const Rect * bounds) {InvalRect (bounds);} #endif /*** Enumerations ***/ enum { appleID = 1, fileID, editID }; enum { quitItem = 1 }; /* The following prototype is missing from the CW11 header files: */ pascal void ExitToShell(void); /*** Variables -- Imported from Browser Plugin Module ***/ #ifdef PLUGIN extern int pluginArgCount; extern char *pluginArgName[100]; extern char *pluginArgValue[100]; #endif /*** Variables -- Imported from Virtual Machine ***/ extern int fullScreenFlag; extern int interruptCheckCounter; extern int interruptKeycode; extern int interruptPending; /* set to true by recordKeystroke if interrupt key is pressed */ extern unsigned char *memory; extern int savedWindowSize; /* set from header when image file is loaded */ /*** Variables -- image and path names ***/ #define IMAGE_NAME_SIZE 300 char imageName[IMAGE_NAME_SIZE + 1]; /* full path to image file */ #define SHORTIMAGE_NAME_SIZE 100 char shortImageName[SHORTIMAGE_NAME_SIZE + 1]; /* just the image file name */ #define DOCUMENT_NAME_SIZE 300 char documentName[DOCUMENT_NAME_SIZE + 1]; /* full path to document file */ #define VMPATH_SIZE 300 char vmPath[VMPATH_SIZE + 1]; /* full path to interpreter''s directory */ /*** Variables -- Mac Related ***/ MenuHandle appleMenu = nil; MenuHandle editMenu = nil; int menuBarHeight = 20; RgnHandle menuBarRegion = nil; /* if non-nil, then menu bar has been hidden */ MenuHandle fileMenu = nil; CTabHandle stColorTable = nil; PixMapHandle stPixMap = nil; WindowPtr stWindow = nil; OTTimeStamp timeStart; Boolean gTapPowerManager=false; Boolean gDisablePowerManager=false; const long gDisableIdleTickCount=60*10; long gDisableIdleTickLimit=0; Boolean gThreadManager=false; ThreadID gSqueakThread = kNoThreadID; ThreadEntryUPP gSqueakThreadUPP; Boolean gAllowAccessToFilePlease=false; #ifdef __MPW__ QDGlobals qd; #endif /*** Variables -- Event Recording ***/ #define MAX_EVENT_BUFFER 1024 int inputSemaphoreIndex = 0;/* if non-zero the event semaphore index */ sqInputEvent eventBuffer[MAX_EVENT_BUFFER]; int eventBufferGet = 0; int eventBufferPut = 0; /* declaration of the event message hook */ typedef int (*eventMessageHook)(EventRecord* event); eventMessageHook messageHook = NULL; eventMessageHook postMessageHook = NULL; #define KEYBUF_SIZE 64 int keyBuf[KEYBUF_SIZE]; /* circular buffer */ int keyBufGet = 0; /* index of next item of keyBuf to read */ int keyBufPut = 0; /* index of next item of keyBuf to write */ int keyBufOverflows = 0; /* number of characters dropped */ int buttonState = 0; /* mouse button and modifier state when mouse button went down or 0 if not pressed */ int cachedButtonState = 0; /* buffered mouse button and modifier state for last mouse click even if button has since gone up; this cache is kept until the next time ioGetButtonState() is called to avoid missing short clicks */ Point savedMousePosition; /* mouse position when window is inactive */ int windowActive = true; /* true if the Squeak window is the active window */ /* This table maps the 5 Macintosh modifier key bits to 4 Squeak modifier bits. (The Mac shift and caps lock keys are both mapped to the single Squeak shift bit). Mac bits: