├── test ├── config.json ├── package.json └── test.js ├── README.md ├── package.json ├── LICENSE ├── worknotes.md ├── gptnotes.md ├── commoncode.js ├── davegpt.js └── source.opml /test/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "chatGptApiKey": "your apikey goes here", 3 | "messageText": "Please give me a list of the five most interesting baseball stadiums in the united states.", 4 | "messageText0": "Please give me a list of five places to get a great massage in the united states." 5 | } 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # davegpt 2 | 3 | Simple interface to Open API from Node and (eventually) browser JavaScript. 4 | 5 | ### Hello world 6 | 7 | The test app here is a simple Hello World app for using this package from Node.js. 8 | 9 | -------------------------------------------------------------------------------- /test/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "testdavegpt", 3 | "description": "Simple test app for davegpt", 4 | "author": "Dave Winer ", 5 | "version": "0.4.1", 6 | "license": "MIT", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/scripting/davegpt.git" 10 | }, 11 | "dependencies" : { 12 | "daveutils": "*", 13 | "davegpt": "*" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "davegpt", 3 | "description": "Node and browser-based JavaScript code that communicates with OpenAI.", 4 | "author": "Dave Winer ", 5 | "version": "0.4.1", 6 | "license": "MIT", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/scripting/davegpt.git" 10 | }, 11 | "files": [ 12 | "davegpt.js" 13 | ], 14 | "main": "davegpt.js", 15 | "dependencies" : { 16 | "request": "*", 17 | "daveutils": "*" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | const fs = require ("fs"); 2 | const daveutils = require ("daveutils"); 3 | const davegpt = require ("davegpt"); 4 | 5 | var myChatGpt; 6 | 7 | fs.readFile ("config.json", function (err, jsontext) { 8 | if (err) { 9 | console.log (err.message); 10 | } 11 | else { 12 | const config = JSON.parse (jsontext); 13 | const options = { 14 | apiKey: config.chatGptApiKey 15 | }; 16 | myChatGpt = new davegpt.chatWithChatGpt (options); 17 | myChatGpt.sendMessage (config.messageText, function (err, responseText) { 18 | if (err) { 19 | console.log (err.message); 20 | } 21 | else { 22 | console.log (responseText); 23 | } 24 | }); 25 | } 26 | }); 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Dave Winer 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /worknotes.md: -------------------------------------------------------------------------------- 1 | #### 8/12/25; 11:50:13 AM by DW 2 | 3 | Rewrote according to advice from Paul Boutin and instructions from ChatGPT. 4 | 5 | * But it didn't work so I reverted the changes. I have code that depends on this, e.g. bingeworthyServer. 6 | 7 | * If you want to try again, look for code with today's date, it should be obvious what the change was. 8 | 9 | #### 12/18/24; 10:02:46 AM by DW 10 | 11 | I have the package working for Node. 12 | 13 | When we want it to work for the browser too, the starting point will be to include commoncode.js in the header portion of their html file, and then start debugging from there. 14 | 15 | Since the code was derived from code that worked in the browser, the problems should probably just be the difference between code that's in utils.js, but we won't know until we're doing the work, of course. ;-) 16 | 17 | #### 12/17/24; 5:41:10 PM by DW 18 | 19 | Turning it into a node package, and will also provide a browser-based client that uses the same code to communicate. 20 | 21 | #### 12/17/24; 11:52:09 AM by DW 22 | 23 | Added a new option to chatWithChatGpt, the caller can now provide a callback that makes an HTTP request. That way code running on Node can use request and code running on the desktop can use jQuery. Since I developed this on the desktop, the default is jQuery, so you can leave xxx undefined if you're running on the desktop. 24 | 25 | #### 12/16/24; 9:32:59 AM by DW 26 | 27 | I have the outliner set up. When I click the Go button it sends the text of the line I was editing to ChatGPT, and inserts the response as a subhead. 28 | 29 | It's really sending back lines of text, delimited by \n\n between lines. I have to parse this and generate a list of subs. 30 | 31 | But ChatGPT is too slow now to get any work done. Will try this at night when things are running faster? 32 | 33 | But it looks promising. 34 | 35 | -------------------------------------------------------------------------------- /gptnotes.md: -------------------------------------------------------------------------------- 1 | #### 12/18/24; 11:11:43 AM by DW 2 | 3 | This Node.js project interfaces with OpenAI's GPT API, offering both Node.js and browser-based communication options. Key features and observations about the setup include: 4 | 5 | 6 | 7 | 1. **Node.js and Browser Support**: 8 | 9 | - The project uses `davegpt.js` to communicate with OpenAI APIs. 10 | 11 | - Separate implementations (`nodeHttpRequest` and `browserHttpRequest`) handle requests in Node.js and browser environments respectively, depending on the runtime environment. 12 | 13 | 14 | 15 | 2. **Custom Configuration**: 16 | 17 | - A `config.json` file is used for API keys and sample message texts. It stores critical data like the `chatGptApiKey` and sample prompts for testing. 18 | 19 | 20 | 21 | 3. **Dependencies**: 22 | 23 | - Relies on the `request` package for HTTP requests in Node.js, and includes `daveutils` for utility operations. 24 | 25 | 26 | 27 | 4. **Project Scope**: 28 | 29 | - The package aims to work in Node.js initially, with plans for browser integration. Debugging browser-specific code will involve integrating a `commoncode.js` file. 30 | 31 | 32 | 33 | 5. **Chat API Interface**: 34 | 35 | - The `chatWithChatGpt` class provides an interface for sending messages to OpenAI's GPT models. 36 | 37 | - Uses an initialization step to set system prompts and store message history. 38 | 39 | - Supports custom callbacks to make HTTP requests, simplifying integration across environments. 40 | 41 | 42 | 43 | 6. **Simplified Example**: 44 | 45 | - A test application (`test.js`) demonstrates basic usage by sending a message and logging the response. 46 | 47 | 48 | 49 | 7. **Design Philosophy**: 50 | 51 | - Modular and reusable, supporting future extensions and testing. 52 | 53 | 54 | 55 | If you'd like, I can help with debugging, browser compatibility, or adding new features! 56 | 57 | -------------------------------------------------------------------------------- /commoncode.js: -------------------------------------------------------------------------------- 1 | function httpRequest (url, method, timeout, headers, data, callback) { 2 | var myHttpRequest; 3 | function isNodeEnvironment () { 4 | if ((typeof process !== "undefined") && (typeof process.versions !== "undefined") && (typeof process.versions.node !== "undefined")) { 5 | return (true); //running in Node 6 | } 7 | else { 8 | return (false); //running in the browser 9 | } 10 | } 11 | function nodeHttpRequest (url, method, timeout, headers, data, callback) { 12 | timeout = (timeout === undefined) ? 30000 : timeout; 13 | headers = (headers === undefined) ? new Object () : headers; 14 | 15 | const theRequest = { 16 | url, 17 | method, 18 | timeout, 19 | headers, 20 | body: (method.toLowerCase () == "post") ? data : undefined, 21 | json: true 22 | }; 23 | 24 | request (theRequest, function (err, response, body) { 25 | if (err) { 26 | callback (err); 27 | } 28 | else { 29 | if (response.statusCode >= 200 && response.statusCode <= 299) { 30 | if (body.error === undefined) { 31 | callback (undefined, body); //body is already parsed as JSON due to json: true in theRequest 32 | } 33 | else { 34 | callback (body.error); 35 | } 36 | } 37 | else { 38 | var theError; 39 | try { 40 | theError = body.error; //a strange quirk of OpenAI 41 | } 42 | catch (err) { 43 | const message = "Couldn't make the HTTP request because there was an error == " + response.statusCode + "."; 44 | theError = {message}; 45 | } 46 | callback (theError); 47 | } 48 | } 49 | }); 50 | } 51 | function browserHttpRequest (url, method, timeout, headers, data, callback) { 52 | timeout = (timeout === undefined) ? 30000 : timeout; 53 | var jxhr = $.ajax ({ 54 | url, 55 | method, 56 | headers, 57 | timeout, 58 | data: (method.toLowerCase () == "post") ? JSON.stringify (data) : undefined 59 | }) 60 | .success (function (data, status) { 61 | callback (undefined, data); 62 | }) 63 | .error (function (status) { 64 | var message; 65 | try { //9/18/21 by DW 66 | message = JSON.parse (status.responseText).message; 67 | } 68 | catch (err) { 69 | message = status.responseText; 70 | } 71 | if ((message === undefined) || (message.length == 0)) { //7/22/22 by DW & 8/31/22 by DW 72 | message = "There was an error communicating with the server."; 73 | } 74 | var err = { 75 | code: status.status, 76 | message 77 | }; 78 | callback (err); 79 | }); 80 | } 81 | if (isNodeEnvironment ()) { 82 | myHttpRequest = nodeHttpRequest; 83 | } 84 | else { 85 | myHttpRequest = browserHttpRequest; 86 | } 87 | return (myHttpRequest (url, method, timeout, headers, data, callback)); 88 | } 89 | function chatWithChatGpt (userOptions) { 90 | const options = { 91 | userPrompt: "Greetings!", 92 | apiUrl: "https://api.openai.com/v1/chat/completions", 93 | apiKey: undefined, 94 | systemRole: "You are a helpful assistant.", 95 | httpRequestCallback: httpRequest //12/17/24 by DW 96 | }; 97 | utils.mergeOptions (userOptions, options); 98 | 99 | var messages, conversation; 100 | 101 | function init () { 102 | messages = [ 103 | {role: "system", content: options.systemRole} 104 | ]; 105 | conversation = [ 106 | ]; 107 | } 108 | 109 | function sendMessage (theMessage, callback) { 110 | const newMessage = {role: "user", content: theMessage}; 111 | messages.push (newMessage); 112 | conversation.push (newMessage); 113 | 114 | const timeout = undefined; //accept the default 115 | const headers = { 116 | "Content-Type": "application/json", 117 | "Authorization": `Bearer ${options.apiKey}` 118 | }; 119 | const bodyStruct = { 120 | model: "gpt-4", 121 | messages: messages 122 | }; 123 | 124 | console.log ("sendMessage: messages == " + utils.jsonStringify (messages)); 125 | options.httpRequestCallback (options.apiUrl, "POST", timeout, headers, bodyStruct, function (err, dataFromChatGpt) { 126 | if (err) { 127 | console.log (err.message); 128 | if (callback !== undefined) { 129 | callback (err); 130 | } 131 | } 132 | else { 133 | const responseMessage = dataFromChatGpt.choices [0].message; 134 | console.log ("sendMessage: responseMessage.content == " + utils.jsonStringify (responseMessage.content)); 135 | conversation.push (responseMessage.content); 136 | if (callback !== undefined) { 137 | callback (err, utils.jsonStringify (responseMessage.content)); 138 | } 139 | } 140 | }); 141 | } 142 | function getConversation () { 143 | return (conversation); 144 | } 145 | 146 | init (); 147 | this.sendMessage = sendMessage; 148 | this.getConversation = getConversation; 149 | this.init = init; 150 | } 151 | -------------------------------------------------------------------------------- /davegpt.js: -------------------------------------------------------------------------------- 1 | const myVersion = "0.4.1", myProductName = "davegpt"; 2 | 3 | exports.chatWithChatGpt = chatWithChatGpt; 4 | 5 | const utils = require ("daveutils"); 6 | const request = require ("request"); 7 | 8 | 9 | //below, i've included the code from commoncode.js here -- 12/18/24 by DW 10 | 11 | function httpRequest (url, method, timeout, headers, data, callback) { 12 | var myHttpRequest; 13 | function isNodeEnvironment () { 14 | if ((typeof process !== "undefined") && (typeof process.versions !== "undefined") && (typeof process.versions.node !== "undefined")) { 15 | return (true); //running in Node 16 | } 17 | else { 18 | return (false); //running in the browser 19 | } 20 | } 21 | function nodeHttpRequest (url, method, timeout, headers, data, callback) { 22 | timeout = (timeout === undefined) ? 30000 : timeout; 23 | headers = (headers === undefined) ? new Object () : headers; 24 | 25 | const theRequest = { 26 | url, 27 | method, 28 | timeout, 29 | headers, 30 | body: (method.toLowerCase () == "post") ? data : undefined, 31 | json: true 32 | }; 33 | 34 | request (theRequest, function (err, response, body) { 35 | if (err) { 36 | callback (err); 37 | } 38 | else { 39 | if (response.statusCode >= 200 && response.statusCode <= 299) { 40 | if (body.error === undefined) { 41 | callback (undefined, body); //body is already parsed as JSON due to json: true in theRequest 42 | } 43 | else { 44 | callback (body.error); 45 | } 46 | } 47 | else { 48 | var theError; 49 | try { 50 | theError = body.error; //a strange quirk of OpenAI 51 | } 52 | catch (err) { 53 | const message = "Couldn't make the HTTP request because there was an error == " + response.statusCode + "."; 54 | theError = {message}; 55 | } 56 | callback (theError); 57 | } 58 | } 59 | }); 60 | } 61 | function browserHttpRequest (url, method, timeout, headers, data, callback) { 62 | timeout = (timeout === undefined) ? 30000 : timeout; 63 | var jxhr = $.ajax ({ 64 | url, 65 | method, 66 | headers, 67 | timeout, 68 | data: (method.toLowerCase () == "post") ? JSON.stringify (data) : undefined 69 | }) 70 | .success (function (data, status) { 71 | callback (undefined, data); 72 | }) 73 | .error (function (status) { 74 | var message; 75 | try { //9/18/21 by DW 76 | message = JSON.parse (status.responseText).message; 77 | } 78 | catch (err) { 79 | message = status.responseText; 80 | } 81 | if ((message === undefined) || (message.length == 0)) { //7/22/22 by DW & 8/31/22 by DW 82 | message = "There was an error communicating with the server."; 83 | } 84 | var err = { 85 | code: status.status, 86 | message 87 | }; 88 | callback (err); 89 | }); 90 | } 91 | if (isNodeEnvironment ()) { 92 | myHttpRequest = nodeHttpRequest; 93 | } 94 | else { 95 | myHttpRequest = browserHttpRequest; 96 | } 97 | return (myHttpRequest (url, method, timeout, headers, data, callback)); 98 | } 99 | function chatWithChatGpt (userOptions) { 100 | const options = { 101 | userPrompt: "Greetings!", 102 | apiUrl: "https://api.openai.com/v1/chat/completions", 103 | apiKey: undefined, 104 | systemRole: "You are a helpful assistant.", 105 | httpRequestCallback: httpRequest //12/17/24 by DW 106 | }; 107 | utils.mergeOptions (userOptions, options); 108 | 109 | var messages, conversation; 110 | 111 | function init () { 112 | messages = [ 113 | {role: "system", content: options.systemRole} 114 | ]; 115 | conversation = [ 116 | ]; 117 | } 118 | 119 | function sendMessage (theMessage, callback) { 120 | const newMessage = {role: "user", content: theMessage}; 121 | messages.push (newMessage); 122 | conversation.push (newMessage); 123 | 124 | const timeout = undefined; //accept the default 125 | const headers = { 126 | "Content-Type": "application/json", 127 | "Authorization": `Bearer ${options.apiKey}` 128 | }; 129 | const bodyStruct = { 130 | model: "gpt-4", 131 | messages: messages 132 | }; 133 | 134 | console.log ("sendMessage: messages == " + utils.jsonStringify (messages)); 135 | options.httpRequestCallback (options.apiUrl, "POST", timeout, headers, bodyStruct, function (err, dataFromChatGpt) { 136 | if (err) { 137 | console.log (err.message); 138 | if (callback !== undefined) { 139 | callback (err); 140 | } 141 | } 142 | else { 143 | const responseMessage = dataFromChatGpt.choices [0].message; 144 | console.log ("sendMessage: responseMessage.content == " + utils.jsonStringify (responseMessage.content)); 145 | conversation.push (responseMessage.content); 146 | if (callback !== undefined) { 147 | callback (err, utils.jsonStringify (responseMessage.content)); 148 | } 149 | } 150 | }); 151 | } 152 | function getConversation () { 153 | return (conversation); 154 | } 155 | 156 | init (); 157 | this.sendMessage = sendMessage; 158 | this.getConversation = getConversation; 159 | this.init = init; 160 | } 161 | 162 | -------------------------------------------------------------------------------- /source.opml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14 | 15 | 16 | 17 | nodeEditor: davegpt 18 | Tue, 17 Dec 2024 21:40:16 GMT 19 | Tue, 12 Aug 2025 16:03:28 GMT 20 | Dave Winer 21 | http://davewiner.com/ 22 | 1, 2, 3, 4, 13, 15, 16, 30, 41, 43, 62, 81 23 | 1 24 | 110 25 | 692 26 | 1127 27 | 2025 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 690 | 691 | 692 | 693 | 694 | 695 | 696 | 697 | 698 | 699 | 700 | 701 | 702 | 703 | 704 | 705 | 706 | 707 | 708 | 709 | 710 | 711 | 712 | 713 | 714 | 715 | 716 | 717 | 718 | 719 | 720 | 721 | 722 | 723 | 724 | 725 | 726 | 727 | 728 | 729 | 730 | 731 | 732 | 733 | 734 | 735 | 736 | 737 | 738 | 739 | 740 | 741 | 742 | 743 | 744 | 745 | 746 | 747 | 748 | 749 | 750 | 751 | 752 | 753 | 754 | 755 | 756 | 757 | 758 | 759 | 760 | 761 | 762 | 763 | 764 | 765 | 766 | 767 | 768 | 769 | 770 | 771 | 772 | 773 | 774 | 775 | 776 | 777 | 778 | 779 | 780 | 781 | 782 | 783 | 784 | 785 | 786 | 787 | 788 | 789 | 790 | 791 | 792 | 793 | 794 | 795 | 796 | 797 | 798 | 799 | 800 | 801 | 802 | 803 | 804 | 805 | 806 | 807 | 808 | 809 | 810 | 811 | 812 | 813 | 814 | 815 | 816 | 817 | 818 | 819 | 820 | 821 | 822 | 823 | 824 | 825 | 826 | 827 | 828 | 829 | 830 | 831 | 832 | 833 | 834 | 835 | 836 | 837 | 838 | 839 | 840 | 841 | 842 | 843 | 844 | 845 | 846 | 847 | 848 | 849 | 850 | 851 | 852 | 853 | 854 | 855 | 856 | 857 | 858 | 859 | 860 | 861 | 862 | 863 | 864 | 865 | 866 | 867 | 868 | 869 | 870 | 871 | 872 | 873 | 874 | 875 | 876 | 877 | 878 | 879 | 880 | 881 | 882 | 883 | 884 | 885 | 886 | 887 | 888 | 889 | 890 | 891 | 892 | 893 | 894 | 895 | 896 | 897 | 898 | 899 | 900 | 901 | 902 | 903 | 904 | 905 | 906 | 907 | 908 | 909 | 910 | 911 | 912 | 913 | 914 | 915 | 916 | 917 | 918 | 919 | 920 | 921 | 922 | 923 | 924 | 925 | 926 | 927 | 928 | 929 | 930 | 931 | 932 | 933 | 934 | 935 | 936 | 937 | 938 | 939 | 940 | 941 | 942 | 943 | 944 | 945 | 946 | 947 | 948 | 949 | 950 | 951 | 952 | 953 | 954 | 955 | 956 | 957 | 958 | 959 | 960 | 961 | 962 | 963 | 964 | 965 | 966 | 967 | 968 | 969 | 970 | 971 | 972 | 973 | 974 | 975 | 976 | 977 | 978 | 979 | 980 | 981 | 982 | 983 | 984 | 985 | 986 | 987 | 988 | 989 | 990 | 991 | 992 | 993 | 994 | 995 | 996 | 997 | 998 | 999 | 1000 | 1001 | 1002 | 1003 | 1004 | 1005 | 1006 | 1007 | 1008 | 1009 | 1010 | 1011 | 1012 | 1013 | 1014 | 1015 | 1016 | 1017 | 1018 | 1019 | 1020 | 1021 | 1022 | 1023 | 1024 | 1025 | 1026 | 1027 | 1028 | 1029 | 1030 | 1031 | 1032 | 1033 | 1034 | 1035 | 1036 | 1037 | 1038 | 1039 | 1040 | 1041 | 1042 | 1043 | 1044 | 1045 | 1046 | 1047 | 1048 | 1049 | 1050 | 1051 | 1052 | 1053 | 1054 | 1055 | 1056 | 1057 | 1058 | 1059 | 1060 | 1061 | 1062 | 1063 | 1064 | 1065 | 1066 | 1067 | 1068 | 1069 | 1070 | 1071 | 1072 | 1073 | 1074 | 1075 | 1076 | 1077 | 1078 | 1079 | 1080 | 1081 | 1082 | 1083 | 1084 | 1085 | 1086 | 1087 | 1088 | 1089 | 1090 | 1091 | 1092 | 1093 | 1094 | 1095 | 1096 | 1097 | 1098 | 1099 | 1100 | 1101 | 1102 | 1103 | 1104 | 1105 | 1106 | 1107 | 1108 | 1109 | 1110 | 1111 | 1112 | 1113 | 1114 | 1115 | 1116 | 1117 | 1118 | 1119 | 1120 | 1121 | 1122 | 1123 | 1124 | 1125 | 1126 | 1127 | 1128 | 1129 | 1130 | 1131 | 1132 | 1133 | 1134 | 1135 | 1136 | 1137 | 1138 | 1139 | 1140 | 1141 | 1142 | 1143 | 1144 | 1145 | 1146 | 1147 | 1148 | 1149 | 1150 | 1151 | 1152 | --------------------------------------------------------------------------------