├── .gitignore ├── .gitmodules ├── Contributing.md ├── Credits ├── License ├── Plans ├── BitcloudPlan.md └── bitcloud.mm ├── README.md ├── bitcloud.c ├── Makefile ├── README.md ├── bc_sockets.h ├── bitcloud.h ├── main.c ├── nodepool.c ├── nodepool.sql ├── nodepool_sql.h ├── testing.md └── tests │ ├── Makefile │ ├── logs.c │ ├── main.c │ └── serialization.c ├── bitcloud.js ├── README.md ├── admin.js ├── bitcloud.js ├── nodepool.sql ├── repl.js ├── resetnodepool.sh └── test.js ├── crowdfunding └── img ├── bitcloud-fm.png └── structure.png /.gitignore: -------------------------------------------------------------------------------- 1 | *.a 2 | src/tests/nodepool 3 | src/tests/tests 4 | javi/* 5 | src/python/* 6 | *~ 7 | \#* 8 | *~ 9 | *.DS_Store 10 | .*.kate-swp 11 | *.o 12 | src/nodepool 13 | src/nodepool_sql.h 14 | src/bitcloud 15 | 16 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wetube/bitcloud/75036a2dde59012b14a26d98bfe221dba0e9e940/.gitmodules -------------------------------------------------------------------------------- /Contributing.md: -------------------------------------------------------------------------------- 1 | # GUIDELINES 2 | 3 | ### SECURITY 4 | 5 | The team is currently working on improving project security and code security to 6 | ensure Bitcloud sustainability as a wild open source application platform. 7 | 8 | If you would like access to the [collaborative Cloud 9 development environment](https://ide.c9.io/gnosticat1on/bitcloud) 9 | that has been established for the Bitcloud project, please request access. 10 | At first, you will only be given Read access to the workspace. No write access will 11 | be granted until after your contributions to the code have been accepted. 12 | 13 | Please recognize that the designers and contributors thus far may or may not seek 14 | to have themselves known, and that is okay. The group is very close, yet secretive 15 | to support security for all involved. 16 | 17 | ### FOCUS 18 | 19 | The focus is on the code, always. Development of documentation is secondary to 20 | development of working and accepted code. 21 | 22 | The source code is changing rapidly. The time it would take to update documentation 23 | after updating code would result in unnecessary resource drain, when resources 24 | already are scarce. 25 | 26 | Therefore, most documentation will exist within the living code. Other documentation 27 | exists, but not all of it may be published. See SECURITY, above. 28 | 29 | ### ORGANIZATION 30 | 31 | There aren't many of us. We will know it when we get there, but the core group 32 | of active developers on the team would probably have to number at least 8 before 33 | it warrants us spending time building and testing more complete project management 34 | tools. 35 | 36 | We have had issues with our information when we used free or third-party (e.g., Google) 37 | provided organization tools. As a result, we tend to trust very few tools available. 38 | 39 | [Riseup free email](http://www.riseup.net) is a trusted source for free email 40 | service. With minimal logs and sympathetic management, use your Riseup account 41 | for project communication. Donate to them, too. (I do, every month.) 42 | 43 | Email works great for communication, but sometimes you want something more conversational. 44 | That's where [IRC](http://webchat.freenode.net/?channels=bitcloud) comes in. No, 45 | someone from the core team won't always be there. In fact, we only have windows 46 | of time available for chat. We have jobs that actually pay us. These take most 47 | of our time away from things like IRC, for the most part. 48 | 49 | We welcome all respectful conversation, though. And I don't want to dissuade you 50 | from reaching out to us using IRC. We actually are on there more than we should be. 51 | 52 | The discussion boards pretty much fell apart as the Bitcoin fanatics who missed the 53 | boat tried to join the Bitcloud project thinking it would be their golden ticket to 54 | fortune. The boards are still up and we'd love to continue the conversation, but minimal 55 | input has been contributed to the forums for almost a year. 56 | 57 | We have Skype, but only very rarely are available for conversation. 58 | 59 | # CONTRIBUTING 60 | If you have any questions about the code or are interested in contributing, 61 | feel free to contact us on our [mailing list](http://bitcloudproject.org/w/Mailing_list) 62 | or on [IRC](http://webchat.freenode.net/?channels=bitcloud). 63 | 64 | ### FORK 65 | Fork bitcloud [on GitHub](https://github.com/wetube/bitcloud/fork) and clone 66 | your repository. 67 | 68 | ``` 69 | $ git clone https://github.com/your-username/bitcloud.git 70 | $ cd bitcloud 71 | $ git remote add upstream https://github.com/wetube/bitcloud 72 | ``` 73 | 74 | ### CODE 75 | 76 | Try to follow the same format of coding there is when editing code 77 | 78 | * Publicly available functions and types are prefixed with `bc_`, and macros with`BC_`. 79 | 80 | * Don't leave whitespace at the end of lines. 81 | 82 | * Try to keep lines at around 80 characters long. 83 | 84 | * All variables are assigned before use (to avoid bugs). 85 | 86 | * All header files should have `#define` guards to prevent multiple inclusion. The format should be `_H` (e.g. `bitcloud.h` has `BITCLOUD_H`). 87 | 88 | * Use `0` for integers, `NULL` for pointers, and `'\0'` for chars. 89 | 90 | 91 | ### COMMIT 92 | 93 | Make sure git knows your name and email address: 94 | 95 | ``` 96 | $ git config --global user.name "Random Developer" 97 | $ git config --global user.email "random.developer@example.org" 98 | ``` 99 | You might find Git GUIs such as [git-cola](http://git-cola.github.io/) useful 100 | at this part. 101 | 102 | Commit logs consist of a single-line summary and a description separated by a 103 | blank line, it's highly recommended to: 104 | 105 | * Have a concise summary, 50 characters max. 106 | * Wrap everything else at 72 columns 107 | 108 | Here's an example: 109 | 110 | ``` 111 | subsystem: explaining the commit in one line 112 | 113 | Body of commit message is a few lines of text, explaining things 114 | in more detail, possibly giving some background about the issue 115 | being fixed, etc etc. 116 | 117 | Do proper word-wrap and keep columns shorter than about 118 | 72 characters or so. That way `git log` will show things 119 | nicely even when it is indented. 120 | ``` 121 | 122 | ### REBASE 123 | 124 | Use `git rebase` when changes appear on upstream to make sure you're not editing 125 | outdated code. 126 | 127 | ``` 128 | $ git fetch upstream 129 | $ git rebase upstream/master 130 | ``` 131 | 132 | ### PUSH 133 | 134 | To push your local changes to your online repository. 135 | 136 | ``` 137 | $ git push origin master 138 | ``` 139 | 140 | Go to https://github.com/your-username/bitcloud/compare/wetube:master...master 141 | and click "Create Pull Request" and fill out the form 142 | 143 | To have your pull request accepted you have to agree with the following 144 | Developer's Certificate of Origin 1.1 by adding a "sign-off" line at the end of 145 | your pull request: 146 | ``` 147 | Signed-off-by: Random Developer 148 | ``` 149 | 150 | You have to use your real name. 151 | 152 | Developer's Certificate of Origin 1.1: 153 | 154 | ``` 155 | By making a contribution to this project, I certify that: 156 | 157 | (a) The contribution was created in whole or in part by me and I have 158 | the right to submit it under the open source license indicated in the file; or 159 | 160 | (b) The contribution is based upon previous work that, to the best of my 161 | knowledge, is covered under an appropriate open source license and I have the 162 | right under that license to submit that work with modifications, whether created 163 | in whole or in part by me, under the same open source license (unless I am 164 | permitted to submit under a different license), as indicated in the file; or 165 | 166 | (c) The contribution was provided directly to me by some other person who 167 | certified (a), (b) or (c) and I have not modified it; and 168 | 169 | (d) In the case of each of (a), (b), or (c), I understand and agree that 170 | this project and the contribution are public and that a record of the contribution 171 | (including all personal information I submit with it, including my sign-off) is 172 | maintained indefinitely and may be redistributed consistent with this project or 173 | the open source license indicated in the file. 174 | ``` 175 | 176 | Try to address all feedback/comments you receive, if you have to make changes 177 | apply them in a separate commit and push them using the command mentioned above. 178 | Post a comment in the pull request afterwards; GitHub does not send out 179 | notifications when you add commits. 180 | 181 | ### LICENSE HEADER 182 | 183 | 184 | All source files should have the following header: 185 | 186 | ``` 187 | /* This file is part of the Bitcloud project 188 | * Distributed under the MIT License, see the accompanying file License. */ 189 | 190 | ``` 191 | 192 | Do not add attributions (e.g. `Copyright (C) 2014 John Doe `) 193 | to the source code, `git` maintains a history of who changed what, you can submit 194 | a patch to the `Credits` file to add yourself. 195 | 196 | 197 | 198 | -------------------------------------------------------------------------------- /Credits: -------------------------------------------------------------------------------- 1 | This file is a partial list of people who have contributed to the 2 | Bitcloud project. If you have contributed a patch or made some other 3 | contribution to Bitcloud, you can submit a patch to this file to add yourself. 4 | 5 | The list is sorted by surname and formatted to allow easy grepping and 6 | beautification by scripts. The fields are: name (N), email (E), web-address 7 | (W), PGP key ID and fingerprint (P), description (D), snail-mail address 8 | (S), and (I) IRC handle. 9 | 10 | -------------------------------------------------------------------------------- /License: -------------------------------------------------------------------------------- 1 | MIT License (MIT) 2 | 3 | Copyright (c) 2014 Bitcloud Developers 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 13 | all 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 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /Plans/BitcloudPlan.md: -------------------------------------------------------------------------------- 1 | # Bitcloud: High Level Plan 2 | 3 | ## Versioning 4 | 5 | * 0.1 - Beginning of nodepool, end of general design 6 | 7 | * 0.2 - First Proof of Concept (PoC): rudimentary sync (including UBJSON communication) 8 | * 0.3 - Second PoC: Cryptography proof, possibly with first CA mining routine 9 | * 0.4 - Third PoC: Initial node storage and retrieval operations (including file slicing) 10 | 11 | * 0.5 - First Alpha version - initial synch, LAFS storage, CA/cryptography, and interface capability 12 | * 0.6 - Second Alpha version - first rudimentary DApp (e.g., "box" storage on a grid) ** Additional team may breakoff and begin WeTube development in parallel with Bitcloud Beta development activity. 13 | 14 | * 0.7 - First Beta version - integration of publisher and payment/agreements 15 | * 0.9 - Final Beta version 16 | 17 | * 1.0 - First Production version 18 | -------------------------------------------------------------------------------- /Plans/bitcloud.mm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Welcome to Bitcloud 2 | 3 | Bitcloud is a universal protocol aiming to provide a massive distributed 4 | database and filesystem, or "virtual 5 | hard disk", capable of storing data encrypted and signed across all connected 6 | nodes, protecting privacy and guaranteeing quality of service (QoS). 7 | 8 | # Introduction 9 | 10 | Bitcloud can be the base for decentralized applications that require data 11 | storage and bandwidth. There are many Bitcoin 2.0 projects in the works right 12 | now, but they all still rely on some type of blockchain. In Bitcloud, the 13 | blockchain is replaced by a distributed database, also known as the 14 | nodepool. Bitcloud creates a new decentralized system of trust where entire 15 | web applications can be hosted without a centralized server. 16 | 17 | Bitcloud is *coin agnostic*, meaning that it only intends to be the base for 18 | the storage needs of future Distributed Applications (DAs). Bitcloud can use the escrow capabilities of 19 | Bitcoin and/or the contracts of Ethereum. Bitcloud intends to substitute the 20 | way in which servers interconnect today and make it much easier, more secure and 21 | more private for users, publishers and DAs to share files. It will be *fundamental* 22 | for the upcoming DAs. 23 | 24 | Whether you're watching videos from YouTube or listening to music on 25 | Soundcloud, you're getting all of your content through one centralized 26 | source. That centralized source could decide to delete certain content or be 27 | forced to delete controversial content by a local government. The core 28 | principles behind the applications built on top of Bitcloud are 29 | decentralization, complete autonomy, open source, and the choice of anonymity. 30 | 31 | For further information and a technical overview, read 32 | [the White Paper](http://bitcloudproject.org/w/Main_Page). 33 | 34 | Why do we need Bitcloud? Read [this](http://bitcloudproject.org/w/Why_Do_We_Need_Bitcloud%3F) 35 | 36 | 37 | # Help Work With Us 38 | 39 | We want to make the process of creating Bitcloud *extremely* open, allowing 40 | anyone who wants to participate to share their opinion and help with the 41 | project. 42 | 43 | Look at our current team [here](http://bitcloudproject.org/w/Team). 44 | 45 | Watch us at github. 46 | 47 | And, most importantly, join us [here](http://bitcloudproject.org/w/Join_Us). 48 | 49 | # What are we doing now? 50 | 51 | We have mostly finished the design stage! We are fully entering the programming stage now. 52 | 53 | Heres the plan for Alpha Development: 54 | 55 | Design Documentation: 56 | -Nodepool.sql Specifications 57 | -Compnent Function Specification 58 | -Functional Requirements 59 | -Process Diagrams 60 | -Component Dependencies 61 | -Possible UML, Schema, and other Diagrams 62 | 63 | Develop Components: 64 | - 65 | 66 | Testing: 67 | -Test locally on many machines 68 | -Solve any errors 69 | -Build and test an Alpha Grid 70 | -Fix any errors 71 | 72 | Move on to Beta! 73 | 74 | # New node.js version for PoC 75 | 76 | We have decided to create the first PoC version using node.js. 77 | We hope that this decission will make many developers happy to contribute 78 | to the project. 79 | TODO 80 | -------------------------------------------------------------------------------- /bitcloud.c/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-Wall `pkg-config --cflags sqlite3` 2 | LDLIBS=`pkg-config --libs sqlite3` 3 | 4 | bitcloud: main.o bitcloud.a 5 | $(CC) -o $@ $^ $(LDLIBS) 6 | 7 | tests: bitcloud.a tests/main.c tests/logs.c 8 | cd tests && $(MAKE) 9 | 10 | bitcloud.a: nodepool.o 11 | rm -f $@ 12 | ar rcs $@ $^ 13 | 14 | main.o: main.c bitcloud.h 15 | $(CC) $(CFLAGS) -c $< 16 | 17 | nodepool.o: nodepool.c nodepool_sql.h bitcloud.h 18 | $(CC) $(CFLAGS) -c $< 19 | 20 | # careful, everytime nodepool.sql is modified the nodepool is deleted: 21 | nodepool_sql.h: nodepool.sql 22 | rm -f nodepool 23 | xxd -i $< > nodepool_sql.h 24 | 25 | clean: 26 | rm -f *.o *.a nodepool nodepool_sql.h bitcloud 27 | cd tests && $(MAKE) clean 28 | -------------------------------------------------------------------------------- /bitcloud.c/README.md: -------------------------------------------------------------------------------- 1 | Requirements 2 | ============ 3 | 4 | Current requirements: 5 | 6 | - GCC and GNU make. 7 | - sqlite3-dev 8 | - xxd 9 | - pkg-config 10 | - libuv-dev 11 | 12 | Tested on Debian 7, Does not compile on Mac OSX 10.9. 13 | 14 | Building the PoC 15 | ==================== 16 | 17 | To compile, just: 18 | 19 | `make` 20 | 21 | Test 22 | ----- 23 | 24 | `make tests` 25 | 26 | This will create a nodepool in the "tests" directory and run tests. 27 | 28 | Clean 29 | ----- 30 | 31 | `make clean` 32 | 33 | This will remove all compiled files, the nodepool, and tests. 34 | 35 | Nodepool 36 | ======== 37 | 38 | To generate the nodepool, run: 39 | 40 | `./bitcloud` 41 | 42 | Every time nodepool.sql is modified, the last nodepool is deleted, so 43 | make backup copies in case that the content in the actual nodepool is 44 | important to preserve. 45 | 46 | The generated nodepool can be open by sqlite3 or a client of it: 47 | 48 | `# sqlite3 nodepool` 49 | 50 | `.schema` 51 | 52 | `.help` 53 | 54 | To see the logs from the command line: 55 | 56 | `sqlite3 nodepool "select * from logs"` 57 | -------------------------------------------------------------------------------- /bitcloud.c/bc_sockets.h: -------------------------------------------------------------------------------- 1 | /* This contains all Bitcloud networking code, leveraging UV library. 2 | */ 3 | 4 | #include "libuv/include/uv.h" // make sure it is there 5 | #include "bitcloud.h" 6 | 7 | // socket structure 8 | 9 | typedef struct bc_socket { 10 | char *address; /* the sockaddr */ 11 | int port; 12 | bc_error status; 13 | // what else? 14 | } bc_socket; 15 | 16 | // function prototypes/declarations 17 | 18 | bc_socket bc_prepare_sockets (void); 19 | 20 | bc_error bc_open_sockets (bc_socket *cur_sock); // and initiate listening 21 | 22 | bc_error bc_close_sockets (bc_socket *cur_sock); 23 | 24 | bc_error bc_sockets_connect (bc_socket *cur_sock); // reach out to another node 25 | 26 | // not sure if these two will be needed 27 | 28 | bc_error bc_sockets_transmit (bc_socket *cur_sock); 29 | 30 | bc_error bc_sockets_receive (bc_socket *cur_sock); 31 | -------------------------------------------------------------------------------- /bitcloud.c/bitcloud.h: -------------------------------------------------------------------------------- 1 | /* About the comments: right now we are writing here the documentation and ideas as 2 | we prototype. When we write the real documentation, most of the comments here will 3 | be deleted and moved to the docs. */ 4 | 5 | #ifndef _BITCLOUD_H 6 | #define _BITCLOUD_H 7 | 8 | #include "libuv/include/uv.h" 9 | 10 | /* #include */ 11 | #include 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | 18 | 19 | /* Error codes: */ 20 | typedef enum bc_error { 21 | BC_OK=0, 22 | BC_DB_ERROR, 23 | BC_BAD_SQL, 24 | BC_BAD_DATA, 25 | BC_BAD_SIGNATURE, 26 | BC_NOT_FOUND, 27 | BC_SERVER_ERROR, 28 | BC_NO_CONNECTION, 29 | BC_DROP_CONNECTION, 30 | BC_BAD_DNS, 31 | BC_BAD_ROUTE, 32 | BC_UNEXPECTED_END, 33 | BC_CORRUPT_DATA, 34 | /* DApps errors: */ 35 | BC_DAPP_BAD_LIBRARY, 36 | BC_DAPP_NOT_INSTALLED, 37 | BC_DAPP_BAD_TABLE_RULES, 38 | BC_DAPP_ID_CONFLICT, 39 | BC_DAPP_BAD_REPO_SIG, 40 | /* attempt to write to a non serializable table: */ 41 | BC_TABLE_NOT_SERIALIZABLE, 42 | /* NON ERRORS: */ 43 | BC_ROW, /* a new row is ready to read */ 44 | BC_DONE, /* done steeping */ 45 | } bc_error; 46 | 47 | 48 | typedef uint8_t bc_key[256]; /*2048 bits*/ 49 | typedef uint8_t bc_signature[256]; 50 | typedef uint8_t bc_id[40]; /* 160bits for the node Id */ 51 | typedef sqlite3_stmt* bc_stmt; /* statement for the db operations */ 52 | 53 | /* log an error to the logs table and (optionally) prints a msg: */ 54 | void bc_log (bc_error error, const char *msg, ...); 55 | extern int BC_log_to_stdout; 56 | #define BC_MAX_LOG_SIZE 256 57 | 58 | 59 | 60 | /* 61 | Nodepool database structures and functions 62 | ========================================== 63 | */ 64 | 65 | bc_error bc_open_nodepool (const char* filename); 66 | 67 | extern sqlite3 *nodepool; 68 | 69 | /* functions to use SQL inside BC and Dapps: */ 70 | /* TODO: documentation */ 71 | bc_error bc_sql (bc_stmt *stmt, const char* sql); 72 | bc_error bc_step (bc_stmt stmt); 73 | bc_error bc_reset (bc_stmt stmt); 74 | bc_error bc_finalize (bc_stmt stmt); 75 | bc_error bc_binds (bc_stmt stmt, int position, const char *value); 76 | bc_error bc_bindi (bc_stmt stmt, int position, int value); 77 | int bc_geti (bc_stmt stmt, int column); 78 | char *bc_gets (bc_stmt stmt, int column); 79 | 80 | /* exit if there is an important SQL error */ 81 | extern int BC_exit_on_sql_error; 82 | 83 | 84 | /* 85 | UBJSON 86 | ====== 87 | 88 | We use ubjson specification http://ubjson.org/ for all serialization 89 | purposes, with some extensions like specified below: 90 | */ 91 | 92 | typedef char bc_msgType; 93 | 94 | /* standard ubjson: */ 95 | #define BC_MSG_NULL 'Z' 96 | #define BC_MSG_NO_OP 'N' 97 | #define BC_MSG_TRUE 'T' 98 | #define BC_MSG_FALSE 'F' 99 | #define BC_MSG_INT8 'i' 100 | #define BC_MSG_UINT8 'U' 101 | #define BC_MSG_INT16 'I' 102 | #define BC_MSG_INT32 'l' 103 | #define BC_MSG_INT64 'L' 104 | #define BC_MSG_FLOAT32 'd' 105 | #define BC_MSG_FLOAT64 'D' 106 | #define BC_MSG_CHAT 'C' 107 | #define BC_MSG_STRING 'S' /* needs size */ 108 | #define BC_MSG_ARRAY_START '[' /* needs size */ 109 | #define BC_MSG_ARRAY_END ']' /* consistance check */ 110 | #define BC_MSG_OBJECT_START '{' /* needs size */ 111 | #define BC_MSG_OBJECT_END '}' /* consistance check */ 112 | /* extensions to ubjson: */ 113 | #define BC_MSG_ID 'Y' /*20 bytes (160bits) ID*/ 114 | #define BC_MSG_SIGNATURE 'G' /* public signature */ 115 | #define BC_MSG_KEY 'K' /* public or private encryption key */ 116 | #define BC_MSG_DATE 'E' /*date in unix timestamp format*/ 117 | #define BC_MSG_BLOB 'B' /* needs size which is 8 bytes length instead of 4 */ 118 | #define BC_MSG_TABLE_NAME 'A' /* size of 1byte length and name */ 119 | #define BC_MSG_INSERT_ROW 'R' /* size and serialized data between {} */ 120 | #define BC_MSG_UPDATE_ROW 'W' /* size and serialized data between {} */ 121 | #define BC_MSG_DELETE_ROW 'X' /* size and key between {} */ 122 | 123 | /* All sizes are 4 bytes length, except for the blob which is 8 bytes, and the table 124 | name which is 1 byte */ 125 | 126 | 127 | /* 128 | examples of a serialized table: 129 | 130 | A5nodesR{0123...serialized data here...}X{0123...key data...} 131 | ^1size ^size of the data ^size of the key 132 | 133 | A is the marker, 5 the size of the name "nodes", R is the marker commanding to insert a row, { initiates the row, then it comes the count of elements, the elements themselves, and the } to check consistency. 134 | 135 | The serialized data in the example is also ubjson format, each column is a 136 | value, like: 137 | 138 | R{0012Y12345E1411655029S16this is a string} 139 | ^siz^ID ^date ^string 140 | 141 | So there is a size and 3 columns in the example, one of type ID, one of type date and 142 | the other of type string. 143 | 144 | It is important to take in consideration that numbers are really stored in 145 | binary format, not in ASCII, but here we show them in ASCII for clarity of understanding. 146 | 147 | */ 148 | 149 | 150 | /* 151 | CELLS 152 | ===== 153 | 154 | A row is composed by a series of cells, corresponding to the columns in a 155 | table. Each cell must have a type, typically in correspondence with the type 156 | of the column. 157 | 158 | */ 159 | 160 | typedef enum bc_cell_type { 161 | BC_TYPE_NULL=0, 162 | BC_TYPE_ID, 163 | BC_TYPE_KEY, 164 | BC_TYPE_SIGNATURE, 165 | BC_TYPE_INTEGER, 166 | BC_TYPE_REAL, 167 | BC_TYPE_STRING, 168 | BC_TYPE_BLOB 169 | } bc_cell_type; 170 | 171 | /* A cell in a table: */ 172 | typedef struct bc_cell { 173 | bc_cell_type type; 174 | union { 175 | bc_key key; 176 | bc_id id; 177 | bc_signature signature; 178 | int integer; 179 | char *string; 180 | double real; 181 | struct { 182 | size_t size; 183 | uint8_t *data; 184 | } blob; 185 | } value; 186 | } bc_cell; 187 | 188 | /* A row is a null terminated (the type is BC_TYPE_NULL) array of cells: */ 189 | typedef bc_cell *bc_row; 190 | 191 | 192 | /* 193 | SERIALIZATION 194 | ============= 195 | */ 196 | 197 | 198 | bc_error bc_deserialize_row (const char *table_name, 199 | uint8_t *origin, 200 | size_t size, 201 | bc_row *row); 202 | /* the row is initialized by the function, so it should not point to any 203 | allocated memory or a memory leak may happen. 204 | 205 | // example: 206 | ... obtain 'origin' and 'size' from the net ... 207 | bc_row row = NULL; 208 | if (!bc_deserialize_rows ("nodes", origin, size, &row)) { 209 | ... do things with the row ... 210 | free (row); 211 | } 212 | */ 213 | 214 | bc_error bc_serialize_row (const char *table_name, bc_row row, uint8_t **destination); 215 | /* // example: 216 | ... obtain the row from other means ... 217 | if (!bc_serialize_row ("nodes", row, &destination)) { 218 | .... do things with destination .... 219 | free (destination); 220 | } 221 | */ 222 | 223 | /* 224 | DATABASE WRITING 225 | ================ 226 | */ 227 | 228 | /* The three main functions of the nodepool section, most of the 229 | actions happen here, as each table has a different way to insert 230 | data. These functions dispatch the data received to the DApp functions 231 | using what is defined in the table_rules in nodepool.sql. 232 | 233 | Normally the dispatched functions will use bc_deserialize internally. 234 | */ 235 | 236 | bc_error bc_insert (char *table, bc_cell *row); 237 | bc_error bc_update (char *table, bc_cell *row); 238 | bc_error bc_delete (char *table, bc_cell *row); 239 | 240 | 241 | 242 | /* 243 | Dapps functions 244 | =============== 245 | */ 246 | 247 | /* Run all the Dapps that are specified in "Dapps" table with the "run" 248 | attribute set to true. Dynamic libraries for the Dapps must be in the 249 | "dapps" directory, except if they are compiled static. */ 250 | bc_error bc_run_all_dapps (void); 251 | 252 | /* load in memory and run or stop a specific Dapp defined in the DApps 253 | table: */ 254 | bc_error bc_run_dapp (int id); 255 | bc_error bc_stop_dapp (int id); 256 | 257 | bc_error bc_update_repositories (int id); 258 | 259 | /* this downloads the DApp from the repository referenced by its ID, which is 260 | a ZIP file that contains the shared libraries, the sql file and auxiliary 261 | files specific to the DApp: */ 262 | bc_error bc_download_app (int id); 263 | 264 | /* install a particual Dapp. The DApp will contain a sqlfile with an INSERT 265 | command for a new row in "DApps" table, plus all the tables needed for the 266 | Dapp with their respective "table_rules" row, plus all dynamic libraries 267 | needed all in a bundled zip file. */ 268 | bc_error bc_install_dapp (char *zipfile); 269 | 270 | /* stops the Dapp specified by the id and delete all the tables owned by the 271 | DApp */ 272 | bc_error bc_uninstall_dapp (int id); 273 | 274 | 275 | 276 | /* 277 | Sync structures and functions 278 | ============================= 279 | */ 280 | 281 | typedef struct bc_node { 282 | bc_id id; 283 | char *address; /* the sockaddr */ 284 | int port; 285 | struct bc_node *next; /* the neighboor */ 286 | } bc_node; 287 | 288 | typedef struct bc_connection { 289 | bc_node node; 290 | int bandwidth_quality; 291 | int ping; 292 | int storage_quality; 293 | int availability; 294 | int service_quality; 295 | char address[0]; /* null terminated */ 296 | } bc_connection; 297 | 298 | extern bc_connection *bc_Connections; 299 | extern int n_Connections; 300 | 301 | bc_error bc_find_proximity (bc_id * dest); 302 | 303 | /* 304 | Messagge system 305 | =============== 306 | */ 307 | 308 | 309 | typedef struct bc_msg { 310 | bc_key origin; 311 | int command; 312 | uint8_t *data; 313 | } bc_msg; 314 | 315 | bc_error bc_send (bc_msg); 316 | 317 | /* receives the msg */ 318 | bc_error bc_event_loop (); 319 | 320 | 321 | #endif /* _BITCLOUD_H */ 322 | -------------------------------------------------------------------------------- /bitcloud.c/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "bitcloud.h" 5 | #include "bc_sockets.h" 6 | 7 | int main (int argc, char **argv) 8 | { 9 | 10 | if (bc_open_nodepool("nodepool")) return 1; 11 | 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /bitcloud.c/nodepool.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "bitcloud.h" 5 | 6 | #include "nodepool_sql.h" 7 | 8 | sqlite3 *nodepool; 9 | 10 | /* 11 | Opens the nodepool db. 12 | If it doesn't exist, it creates all the necessary tables. 13 | */ 14 | 15 | bc_error bc_open_nodepool (const char* filename) 16 | { 17 | int rc; 18 | char *err; 19 | 20 | rc = sqlite3_open_v2(filename, &nodepool, SQLITE_OPEN_READWRITE, NULL); 21 | if (rc) { /* file doesn't exist yet or is readonly */ 22 | sqlite3_close (nodepool); 23 | rc = sqlite3_open(filename, &nodepool); 24 | if (rc) { 25 | sqlite3_close (nodepool); 26 | nodepool = NULL; 27 | bc_log(BC_DB_ERROR, 28 | "could not create the db: %s", 29 | sqlite3_errmsg(nodepool)); 30 | return (BC_DB_ERROR); 31 | } 32 | /* Create all the tables in the nodepool.sql file. nodepool_sql.h was 33 | generated by xxd utility in the Makefile to include the SQL source into 34 | the executable. */ 35 | nodepool_sql[nodepool_sql_len] = '\0'; /* because xxd doesn't nul-terminate 36 | the string. Look Makefile. */ 37 | rc = sqlite3_exec (nodepool, (const char*)nodepool_sql,NULL,NULL, &err); 38 | if (rc != SQLITE_OK) { 39 | sqlite3_free (err); 40 | sqlite3_close (nodepool); 41 | remove (filename); 42 | nodepool = NULL; 43 | bc_log (BC_DB_ERROR, "%s", err); 44 | return (BC_DB_ERROR); 45 | } 46 | bc_log (BC_OK, "Nodepool created"); 47 | } 48 | 49 | return BC_OK; 50 | } 51 | 52 | 53 | 54 | /* general authorization callback function for sqlite */ 55 | 56 | bc_error bc_auth (void *user_data, 57 | int event_code, 58 | const char *event_spec, 59 | const char *event_spec2, 60 | const char *db_name, 61 | const char *trigger) 62 | { 63 | switch (event_code) { 64 | default: 65 | return SQLITE_DENY; 66 | } 67 | return SQLITE_DENY; 68 | } 69 | 70 | int BC_log_to_stdout = 1; 71 | int BC_exit_on_sql_error = 1; 72 | 73 | void bc_log (bc_error error, const char *msg, ...) 74 | { 75 | va_list args; 76 | char buffer[BC_MAX_LOG_SIZE]; 77 | 78 | va_start(args, msg); 79 | vsnprintf (buffer, BC_MAX_LOG_SIZE, msg, args); 80 | va_end(args); 81 | 82 | if (BC_log_to_stdout) { 83 | if (error!=BC_OK) printf ("ERROR %d: ", error); 84 | printf ("%s\n", buffer); 85 | } 86 | 87 | /* log into the nodepool: */ 88 | if (nodepool) { 89 | /* static variables and prepared statements to make it faster:*/ 90 | static sqlite3_stmt *stmt; 91 | static char *sql = "INSERT INTO logs(error_code,log) VALUES(?,?)"; 92 | static const char *tail; 93 | static int rc = -1; 94 | 95 | if (rc==-1) { 96 | rc = sqlite3_prepare(nodepool, sql, strlen(sql), &stmt, &tail); 97 | 98 | if (rc!=SQLITE_OK) { 99 | fprintf (stderr, "FATAL: error in the database, cannot log.\n"); 100 | sqlite3_close (nodepool); 101 | exit(rc); 102 | } 103 | } 104 | 105 | sqlite3_bind_int(stmt, 1, error); 106 | sqlite3_bind_text(stmt, 2, buffer, -1, SQLITE_STATIC); 107 | 108 | sqlite3_step(stmt); 109 | 110 | int reset_err = sqlite3_reset(stmt); 111 | if (reset_err) { 112 | fprintf (stderr, 113 | "FATAL: database error (SQLite error %d).\n", 114 | reset_err); 115 | exit(BC_DB_ERROR); 116 | } 117 | 118 | if (BC_exit_on_sql_error && (error == BC_BAD_SQL)) { 119 | sqlite3_close (nodepool); 120 | exit (BC_BAD_SQL); 121 | } 122 | } 123 | } 124 | 125 | 126 | bc_error bc_sql (bc_stmt *stmt, const char* sql) 127 | { 128 | if (sqlite3_prepare(nodepool, sql, strlen(sql), stmt, NULL)) { 129 | bc_log (BC_BAD_SQL, 130 | "bad SQL statement: %s", 131 | (const char*) sqlite3_errmsg(nodepool)); 132 | return BC_BAD_SQL; 133 | } 134 | return BC_OK; 135 | } 136 | 137 | bc_error bc_step (bc_stmt stmt) 138 | { 139 | int rc = sqlite3_step (stmt); 140 | if (rc && (rc != SQLITE_ROW) && (rc != SQLITE_DONE)) { 141 | bc_reset (stmt); 142 | bc_log (BC_BAD_SQL, 143 | "can not perform SQL step: %s", 144 | (const char*) sqlite3_errmsg(nodepool)); 145 | return BC_BAD_SQL; 146 | } 147 | return (rc == SQLITE_ROW) ? BC_ROW : BC_OK; 148 | } 149 | 150 | bc_error bc_reset (bc_stmt stmt) 151 | { 152 | if (sqlite3_reset (stmt)) { 153 | bc_log (BC_BAD_SQL, 154 | "can not perform SQL statement reset: %s", 155 | (const char*) sqlite3_errmsg(nodepool)); 156 | return BC_BAD_SQL; 157 | } 158 | return BC_OK; 159 | } 160 | 161 | bc_error bc_finalize (bc_stmt stmt) 162 | { 163 | if (sqlite3_finalize (stmt)) { 164 | printf ("finalize\n"); 165 | bc_log (BC_BAD_SQL, 166 | "can not perform SQL statement finalize: %s", 167 | (const char*) sqlite3_errmsg(nodepool)); 168 | return BC_BAD_SQL; 169 | } 170 | 171 | return BC_OK; 172 | } 173 | 174 | bc_error bc_binds (bc_stmt stmt, int position, const char *value) 175 | { 176 | int rc = sqlite3_bind_text(stmt, position, value, -1, SQLITE_STATIC); 177 | if (rc) { 178 | bc_reset (stmt); 179 | bc_log (BC_BAD_SQL, 180 | "can not perform SQL string bind: %d: %s", rc, 181 | (const char*) sqlite3_errmsg(nodepool)); 182 | return BC_BAD_SQL; 183 | } 184 | return BC_OK; 185 | } 186 | 187 | bc_error bc_bindi (bc_stmt stmt, int position, int value) 188 | { 189 | if (sqlite3_bind_int(stmt, position, value)) { 190 | bc_reset (stmt); 191 | bc_log (BC_BAD_SQL, 192 | "can not perform SQL integer bind: %s", 193 | (const char*) sqlite3_errmsg(nodepool)); 194 | return BC_BAD_SQL; 195 | } 196 | return BC_OK; 197 | } 198 | 199 | int bc_geti (bc_stmt stmt, int column) 200 | { 201 | return sqlite3_column_int(stmt, column); 202 | } 203 | 204 | char *bc_gets (bc_stmt stmt, int column) 205 | { 206 | return (char*) sqlite3_column_text (stmt, column); 207 | } 208 | 209 | /* get the name of a serializable table or return NULL otherwise */ 210 | char * bc_get_table_name (int table_id) 211 | { 212 | static bc_stmt stmt = NULL; 213 | char *table_name; 214 | 215 | /* get the table name: */ 216 | if (!stmt) 217 | bc_sql (&stmt, "SELECT table_name FROM table_rules WHERE table_id=?"); 218 | 219 | bc_bindi (stmt, 1, table_id); 220 | 221 | if (bc_step (stmt) != BC_ROW) { /* table not found */ 222 | bc_finalize (stmt); 223 | stmt = NULL; 224 | return NULL; 225 | } 226 | 227 | table_name = strdup (bc_gets (stmt, 0)); 228 | bc_reset (stmt); 229 | return table_name; 230 | } 231 | 232 | /* return the number of columns in a serialiable table given its name, 0 if 233 | the table does not exist or is not serializable */ 234 | int bc_num_columns (const char *table_name) 235 | { 236 | return 0; 237 | } 238 | 239 | /* TODO: function is absolete, must be update to use bc_rows */ 240 | bc_error bc_deserialize_row (const char *table_name, uint8_t *data, size_t length, bc_row *row) 241 | { 242 | bc_stmt stmt; 243 | int pos; 244 | 245 | /* TODO: check table existance and permissions */ 246 | 247 | /* ubjson check this is an object */ 248 | if (*data != '{') { 249 | bc_log (BC_BAD_DATA, "trying to deserialize something that is not a ubjson object"); 250 | goto bad_data; 251 | } 252 | data++; 253 | 254 | /* check the number of columns in the table: */ 255 | int num_columns = bc_num_columns (table_name); 256 | 257 | /* generate the insert: */ 258 | 259 | /* bind values */ 260 | for (pos = 1; *data!='}'; pos++) { 261 | if (pos > num_columns) { 262 | bc_finalize (stmt); 263 | bc_log (BC_BAD_DATA, 264 | "there is more data to deserialize than actual columns in the table %s", 265 | table_name); 266 | goto bad_data; 267 | } 268 | /* TODO: keep track of pointers */ 269 | switch (*data) { 270 | 271 | case BC_MSG_INT32: 272 | bc_bindi (stmt, pos, *(int*)++data); 273 | data += 4; 274 | continue; 275 | 276 | case BC_MSG_STRING: { 277 | uint32_t size = *(uint32_t*)++data; 278 | if (length < size) { /* TODO: improve pointer checks */ 279 | bc_finalize (stmt); 280 | bc_log (BC_BAD_DATA, 281 | "incorrect string size when deserializing to table %s", table_name); 282 | goto bad_data; 283 | } 284 | /* TODO: bc_bindns to use length for strings */ 285 | data += sizeof (uint32_t); 286 | bc_binds (stmt, pos, (char*)data); 287 | data += size; 288 | continue; 289 | } 290 | 291 | case BC_MSG_FLOAT64: 292 | /*TODO*/ 293 | continue; 294 | 295 | case BC_MSG_BLOB: 296 | /*TODO*/ 297 | continue; 298 | 299 | default: 300 | /*TODO*/ 301 | break; 302 | } 303 | } 304 | 305 | /* execute the insersection: */ 306 | if (bc_step (stmt)) { 307 | /* get the error from sqlite (copy it because it may change after 308 | calling finalize): */ 309 | char *err = strdup ((char*) sqlite3_errmsg (nodepool)); 310 | bc_finalize (stmt); 311 | bc_log (BC_DB_ERROR, 312 | "error while deserializing in table %s: %s", 313 | table_name, 314 | err); 315 | free (err); 316 | return BC_DB_ERROR; 317 | /* TODO: ban system for nodes trying to cheat SQL checks */ 318 | } 319 | 320 | bc_finalize (stmt); 321 | return BC_OK; 322 | 323 | bad_data: 324 | return BC_BAD_DATA; 325 | 326 | } 327 | 328 | -------------------------------------------------------------------------------- /bitcloud.c/nodepool.sql: -------------------------------------------------------------------------------- 1 | -- For more verbose documentation, see Bitcloud.org wiki -- 2 | -- http://bitcloudproject.org/w/Nodepool.sql_Database_Design -- 3 | -- All below SQL should be generic SQL -- 4 | 5 | /* Nodepool.sql Database 6 | 7 | Rules: 8 | 9 | - Every record is owned by its creator, as enforced via synchronization 10 | verifying signature. 11 | 12 | - The only exception to the above is in the case of user files, which are 13 | owned by both the user and Publisher. 14 | 15 | - Every record may only be modified/deleted by its owner(s), but may be 16 | removed by anyone via "garbage collection" if its owner(s) have been 17 | banned. 18 | 19 | - SQLite supports DB functions/stored procedures written in C. Those 20 | functions, therefore, will only be referenced hereing documentation 21 | provided in the sync and interface code elsewhere. 22 | 23 | */ 24 | 25 | PRAGMA foreign_keys = ON; 26 | 27 | ---------------------------- 28 | -- Bitcloud Nodepool Team -- 29 | ---------------------------- 30 | 31 | -- general nodepool -- 32 | 33 | -- The contents of the general nodepool are synced globally across every nodes 34 | -- in the Bitcloud network. 35 | 36 | /* 37 | nodes table 38 | 39 | Contains: records of all nodes on the Bitcloud nework (up to 1.8e19) 40 | 41 | Rules: 42 | 43 | - Each node must sign its own entire row (except the signature field itself) 44 | using its own public key. 45 | 46 | - The node must provide a new signature of its row every 3 days 47 | maximum. Otherwise it is deleted from the nodepool and connections refused. 48 | 49 | - creation_date must be within the same synchronization period that the node 50 | is registered for node registration be valid. 51 | 52 | - Consistancy is checked by ensuring that nobody tries to register in other 53 | period that is not the actual: 54 | 55 | */ 56 | 57 | CREATE TABLE nodes ( 58 | public_key BLOB PRIMARY KEY NOT NULL, -- ID 59 | proximity BLOB NOT NULL, -- DHT (kademlia-like) map coordinates 60 | signature BLOB NOT NULL, -- self certificate of this row 61 | creation_date INTEGER NOT NULL, 62 | proof_of_creation BLOB, -- see CA generation in the protocol spec 63 | net_protocol INTEGER DEFAULT 1, -- 1 IP, 2 Tor 64 | address TEXT NOT NULL -- IP or onion address 65 | ); 66 | 67 | 68 | -- A grid is a collection of nodes associated that can sell 69 | -- space and bandwidth to a publisher 70 | CREATE TABLE grids ( 71 | id BLOB PRIMARY KEY NOT NULL, -- random number 72 | owner_id BLOB NOT NULL REFERENCES nodes(public_key), 73 | signature BLOB NOT NULL -- signature of the owner 74 | ); 75 | 76 | 77 | CREATE TABLE publishers ( 78 | public_key BLOB PRIMARY KEY NOT NULL, 79 | address TEXT, 80 | creation_date DATE DEFAULT CURRENT_TIMESTAMP NOT NULL, 81 | proof_of_creation BLOB, -- see CA generation in the protocol spec 82 | nickname TEXT, 83 | -- is information about the content of this publisher public?: 84 | public_metadata BOOLEAN DEFAULT FALSE, 85 | public_files BOOLEAN DEFAULT FALSE, 86 | -- trust all other publisher users by default? If not, only trust 87 | -- those in the publisher_trusts with positive trust. If yes, trust 88 | -- all except those with negative trust. 89 | trust_all_users BOOLEAN DEFAULT TRUE 90 | ); 91 | 92 | 93 | 94 | ------------------------------------- 95 | -- internal publishers/grid tables -- 96 | ------------------------------------- 97 | 98 | -- these tables are shared between associations (e.g., between publishers and 99 | -- grids, or grids and nodes, etc.) 100 | 101 | /* 102 | 103 | node_audit table: things in this table are only inserted after a node failed 104 | to provide a correct check. Every single row in this table is deleted after 105 | every check period, and the new content based on the last one, so it can 106 | ensure continuation of the measurements and save space at the same time. 107 | 108 | For example, if a node fails to be available for some periods, there is no 109 | need that the nodes doing the check have to insert new rows, they just reuse 110 | the rows from the previous perirods, and sign the row. The limit is 16 rows 111 | per node. 112 | 113 | Auditors are random. 114 | 115 | Nodes doing everything perfect are never present in this table except when 116 | issued by malicious nodes. The majority of the net must be malicious in order 117 | to have consecuences for those nodes. 118 | 119 | Bitcloud do not count reputation, but just measures possible incorrections of 120 | the nodes. DAs on top could implement a system of reputation based on this 121 | table and other tables they provide. 122 | 123 | */ 124 | 125 | 126 | CREATE TABLE publisher_trusts ( 127 | from_publisher BLOB NOT NULL REFERENCES publishers(public_key), 128 | to_publisher BLOB REFERENCES publishers(public_key), 129 | trust_users BOOLEAN NOT NULL, 130 | trust_powers BOOLEAN NOT NULL, -- like baning users or moderate files 131 | signature BLOB NOT NULL, -- from signature 132 | reason INTEGER NOT NULL, 133 | /* 134 | 1: Friend 135 | 2: Banned 136 | 3: Bad contracts 137 | 4: ... to be continued 138 | */ 139 | CHECK (reason>=1 and reason <=3) 140 | ); 141 | 142 | 143 | CREATE TABLE users ( 144 | public_key BLOB PRIMARY KEY NOT NULL, 145 | publisher BLOB NOT NULL REFERENCES publishers(public_key), 146 | publisher_signature BLOB, 147 | address TEXT, 148 | nick TEXT COLLATE NOCASE, 149 | fixed_address BOOLEAN DEFAULT TRUE, 150 | revocation_date DATE DEFAULT CURRENT_TIMESTAMP, 151 | storage_quota INTEGER DEFAULT 0, 152 | bandwidth_quota INTEGER DEFAULT 0, 153 | files_quota INTEGER DEFAULT 0, -- how many files can upload 154 | folder_quota INTEGER DEFAULT 0, -- how many folders allowed 155 | root_folder BLOB REFERENCES folders(id) 156 | ); 157 | 158 | -- User requests sent to the grids, for example, creating 159 | -- a folder or uploading/downloading a file 160 | CREATE TABLE user_requests ( 161 | id BLOB PRIMARY KEY NOT NULL, 162 | user BLOB NOT NULL REFERENCES users(public_key), 163 | signature BLOB NOT NULL, 164 | grid TEXT NOT NULL REFERENCES grids(public_key), 165 | action INTEGER NOT NULL, 166 | -- every type of action will have a different param values 167 | param1 BLOB, 168 | param2 BLOB, 169 | /* 170 | 1: Download file: param1=fileID, param2=offset 171 | 2: Stream file: param1=fileID, param2=offset 172 | 3: Upload file: param1=fileID, param2=folderID 173 | 4: Create folder: param1=folderID 174 | 5: Remove folder: param1=folderID 175 | 6: Rename folder: param1=folderID 176 | 7: Move file: param1=origin_foldeID, param2=final_folderID 177 | 8: Rename file: param1=fileID, param2=new_name 178 | 9: Delete file: param1=fileID 179 | 10: Update file owner: param1=fileID, param2=userID 180 | 11: Update file permissions: param1=fileID, param2=flags 181 | 11: Grant user file access: param1=fileID, param2=userID 182 | 12: Grant user folder acccess: param1=folderID, param2=userID 183 | 13: ... to be continued 184 | */ 185 | CHECK (action > 0 and action<=12) 186 | ); 187 | 188 | 189 | CREATE TABLE publisher_grid_contracts ( 190 | id BLOB PRIMARY KEY NOT NULL, 191 | publisher BLOB NOT NULL REFERENCES publishers(public_key), 192 | grid TEXT NOT NULL REFERENCES grids(public_key), 193 | -- Signatures of this contract: 194 | publisher_sig TEXT NOT NULL, 195 | grid_sig TEXT NOT NULL, 196 | -- Terms: 197 | min_bandwidth INTEGER NOT NULL, 198 | start_date DATE DEFAULT CURRENT_TIMESTAMP NOT NULL, 199 | end_date DATE DEFAULT CURRENT_TIMESTAMP NOT NULL, 200 | availability INTEGER NOT NULL, -- % of time online 201 | ping_average INTEGER DEFAULT 0, 202 | -- Coin terms 203 | coin TEXT /* example: BTC */ 204 | ); 205 | 206 | 207 | -- Table for owner requests of its grid nodes 208 | CREATE TABLE grid_owner_requests ( 209 | grid BLOB PRIMARY KEY REFERENCES grids(id), 210 | owner_sig BLOB NOT NULL, 211 | action INTEGER NOT NULL, 212 | param1 BLOB, 213 | param2 BLOB 214 | /* possible actions 215 | 1: Assign storage node: param1=nodeID, param2=gatewayID 216 | 2: Upgrade storage node to gateway: param1=nodeID 217 | 3: Set minimum bandwidth: param1=nodeID, param2=rate 218 | 4: Revoke node: param1=nodeID 219 | 5: ... to be continued 220 | */ 221 | ); 222 | 223 | -- Table used for publishers instructing orders to contracted grids: 224 | CREATE TABLE publisher_requests ( 225 | grid_sig BLOB NOT NULL, 226 | publisher_sig BLOB, 227 | action INTEGER NOT NULL, 228 | param1 BLOB, 229 | param2 BLOB, 230 | /* possible actions: 231 | 1: Accept user: param1=userID, param2=due-time 232 | 2: Revoke user: param1=userID 233 | 3: Remove file: param1=fileID 234 | 4: Remove folder: param1=folderID 235 | 5: Set user files quota: param1=userID, param2=quota 236 | 6: Set user storage quota: param1=userID, param2=quota 237 | 7: Set user folders quota: param1=userID, param2=quota 238 | 8: Set file permisions: param1=fileID, param2=flags 239 | 9: Update file owner: param1=fileID, param2=userID 240 | 10: Update folder owner: param1=fileID, param2=userID 241 | 11: Register nickname: param1=userID, param2=nickname 242 | 12: Delete nickname: param1=nickname 243 | 13: .... to be continued 244 | */ 245 | CHECK (action>=1 and action<=12) 246 | ); 247 | 248 | -- Gateways convert reconstruct data from the storage nodes and 249 | -- present it to the users/publishers. Multiple gateways per grid 250 | -- are possible. 251 | CREATE TABLE gateways ( 252 | node BLOB PRIMARY KEY REFERENCES nodes(public_key), 253 | grid TEXT NOT NULL REFERENCES grids(id), 254 | priority INTEGER, --larger means more priority, in case of the gateway 255 | --to have more than one grid associated. 256 | grid_sig TEXT, 257 | node_sig TEXT 258 | ); 259 | 260 | CREATE TABLE grid_node_contracts ( 261 | id BLOB PRIMARY KEY NOT NULL, 262 | grid TEXT REFERENCES grids(public_key), 263 | node BLOB NOT NULL REFERENCES nodes(public_key), 264 | grid_sig TEXT, 265 | node_sig TEXT, 266 | min_storage INTEGER NOT NULL, 267 | min_bandwidth INTEGER NOT NULL, 268 | start_date DATE DEFAULT CURRENT_TIMESTAMP NOT NULL, 269 | working_time INTEGER, -- only the grid can modify this 270 | -- Coin terms 271 | coin TEXT(4), -- ie: BTC 272 | bandwidth_block_size INTEGER DEFAULT 100000000, 273 | price_per_block INTEGER DEFAULT 0 274 | ); 275 | 276 | CREATE TABLE node_audits ( 277 | node BLOB REFERENCES nodes(public_key), 278 | auditor BLOB NOT NULL REFERENCES nodes(public_key), 279 | signature BLOB NOT NULL, -- auditors signature 280 | periods INTEGER DEFAULT 1, -- number of periods this audis is applicable for 281 | reason INTEGER NOT NULL, 282 | /* 283 | 1: Ping timeout. 284 | 2: Incorrect signature. 285 | 3: Incorrect audition. 286 | 4: Too slow connection. 287 | 5: Denial of service. 288 | 6: Corrupt data. 289 | 7: ... to be continued 290 | */ 291 | CHECK (reason>=1 and reason <=6) 292 | ); 293 | 294 | 295 | -------------------- 296 | -- files and folders 297 | -------------------- 298 | 299 | -- synced between publishers/grids/users but not globally. 300 | 301 | CREATE TABLE folders ( 302 | id BLOB NOT NULL PRIMARY KEY, 303 | parent BLOB REFERENCES folders(id), 304 | name TEXT, 305 | permission BLOB REFERENCES permissions(id) 306 | ); 307 | 308 | CREATE TABLE files ( 309 | hash TEXT NOT NULL PRIMARY KEY, 310 | name TEXT, 311 | mime_type TEXT, 312 | content BLOB, 313 | rate INTEGER DEFAULT 0, --bandwidth rate at what must be streamed 314 | folder BLOB NOT NULL REFERENCES folders(id), 315 | user_sig TEXT NOT NULL, 316 | permissions BLOB REFERENCES permissions(id) 317 | ); 318 | 319 | 320 | CREATE TABLE permissions ( 321 | id BLOB NOT NULL PRIMARY KEY, 322 | user BLOB REFERENCES users(public_key), 323 | publisher BLOB REFERENCES publishers(public_key), 324 | -- NULL user/publisher means permissions for everyone 325 | read BOOLEAN, 326 | read_quota INTEGER, 327 | write BOOLEAN, 328 | write_quota INTEGER, 329 | create_new BOOLEAN, 330 | remove BOOLEAN, 331 | set_perm BOOLEAN -- Meaning someone can have permissions to set permissions in UI term 332 | ); 333 | 334 | 335 | 336 | 337 | -------------------- 338 | -- private tables -- 339 | -------------------- 340 | 341 | -- Tables not synced. Mostly internal configuration and convenient tables. 342 | 343 | CREATE TABLE CAs ( 344 | public_key BLOB PRIMARY KEY NOT NULL, 345 | private_key BLOB NOT NULL, 346 | proof_of_generation BLOB, 347 | ssl_extra TEXT 348 | ); 349 | 350 | CREATE TABLE configs ( 351 | var BLOB PRIMARY KEY NOT NULL, 352 | val BLOB NOT NULL 353 | ); 354 | 355 | -- logs -- 356 | ---------- 357 | 358 | CREATE TABLE logs ( 359 | num INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, 360 | error_code INTEGER NOT NULL, 361 | log TEXT, 362 | ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP 363 | ); 364 | 365 | -- synch working tables -- 366 | ---------- 367 | CREATE TABLE syncing_pool ( 368 | node_id BLOB PRIMARY KEY NOT NULL REFERENCES nodes(public_key), 369 | num INTEGER, -- the number of the current synchronization round 370 | instance_num INTEGER -- different synchronization pool per instance, since data may have different consistency 371 | -- anything else to add about the synch process? random assignment info? 372 | ); 373 | 374 | /* 375 | 376 | CREATE TABLE instance_index ( 377 | node_key BLOB PRIMARY KEY NOT NULL REFERENCES nodes(public_key), 378 | instance_num INTEGER() -- size should be equivalent to number of different configurations/instances 379 | ); 380 | 381 | --- this may be built out later. this was an idea to not duplicate nodes table per instance 382 | 383 | */ 384 | 385 | 386 | /* 387 | 388 | Every table, including deriving DAs tables, need to meet certain rules. This 389 | table is just a configuration table never synced. It is created at the time 390 | of node creation and updated when the software is updated. 391 | 392 | When a Dapp is addded to the node, this table is updated with the information 393 | of the new tables. 394 | 395 | */ 396 | 397 | 398 | 399 | CREATE TABLE table_rules ( 400 | table_id INTEGER PRIMARY KEY NOT NULL, -- must be unique and assigned by the repository 401 | table_name TEXT NOT NULL, 402 | dapp INTEGER REFERENCES DApps(id), 403 | 404 | -- exposure of the table in the nodepool 405 | -- 0=private; 1=grid; 2=participants only; 3=full global (careful); 406 | exposure INTEGER DEFAULT 0, 407 | 408 | -- participants (OR checked) 409 | -- 1=node; 2=grid owner; 4=gateways; 8=publishers; 16=users 410 | paticipants INTEGER DEFAULT 0, 411 | 412 | -- how data is synced? 413 | -- 0=nosync, 1=proximity, 2=random, 3=manual, 4=owner 414 | sync_type INTEGER DEFAULT 0, 415 | nodes_to_sync INTEGER DEFAULT 16, 416 | proximity_nodes INTEGER DEFAULT 12, 417 | 418 | -- how offten to check consistency? (this is different than actually syncing) 419 | -- in seconds, 0=nocheck 420 | check_every INTEGER DEFAULT 600, 421 | 422 | 423 | 424 | -- check function: this is a C function that checks the consistency of the 425 | -- last block across the nodes affected (from exposure). 426 | check_function TEXT DEFAULT "bc_check", 427 | 428 | -- sync functions: this C functions take a table and a row from argument and try 429 | -- to modify the local DB if tests are passed: 430 | insert_function TEXT default "bc_insert", 431 | delete_function TEXT default "bc_delete", 432 | update_function TEXT default "bc_update", 433 | 434 | -- maximum general number of transactions per check period and participant: 435 | max_transactions INTEGER DEFAULT 1, 436 | -- if max number of transaction must be specified per participant to avoid excess 437 | -- of flood or DDOS attacks: 438 | check_flood_function TEXT DEFAULT "bc_check_flood" 439 | 440 | ); 441 | 442 | 443 | -- Table for registering DApps using repositories 444 | CREATE TABLE DApps ( 445 | id INTEGER NOT NULL PRIMARY KEY, -- the ID must be unique and assigned by the repository 446 | name TEXT NOT NULL UNIQUE, 447 | description TEXT, 448 | author TEXT, 449 | license TEXT, 450 | version FLOAT NOT NULL, -- example: 0.96 451 | 452 | is_static BOOLEAN DEFAULT 0, -- compiled static or dynamic. 453 | 454 | -- This is the name of the library (.so or .dll) file to download. This file 455 | -- will contain some or all the functions in the "table_rules". This file is 456 | -- located in the "dapp" directory. 457 | dapp_library TEXT, 458 | 459 | run BOOLEAN DEFAULT 0, -- is this DApp to be run when calling bc_run_all_apps()? 460 | is_downloaded BOOLEAN DEFAULT 0, -- the files are downloaded 461 | 462 | -- The respository and signature, without this the app is considered malicious 463 | repository INTEGER REFERENCES repositories(id), 464 | rep_sig BLOB 465 | ); 466 | 467 | 468 | -- DApps dependences. Multiple dependences per DApp are possible 469 | CREATE TABLE dependences ( 470 | dapp INTEGER REFERENCES DApps(id), 471 | dependency INTEGER REFERENCES DApps(id), -- the DApp in dependency 472 | min_version FLOAT DEFAULT 0, -- the required minimum version 473 | max_version FLOAT DEFAULT 999, 474 | PRIMARY KEY (dapp, dependency) 475 | ); 476 | 477 | 478 | CREATE TABLE repositories ( 479 | id INTEGER NOT NULL PRIMARY KEY, 480 | name TEXT NOT NULL, 481 | address TEXT NOT NULL, 482 | public_key BLOB NOT NULL, -- for signing DApps 483 | signature BLOB NOT NULL -- self signature of this row for security reasons 484 | ); 485 | 486 | 487 | /* 488 | Default values 489 | */ 490 | 491 | 492 | -- Fake first repository for testing purposes 493 | INSERT INTO repositories VALUES ( 494 | 1, --id 495 | "Bitcloud Foundation Main Repository", --name 496 | "127.0.0.1", --address 497 | "foo", --public key 498 | "bar" --signature 499 | ); 500 | 501 | -- The first DApp is Bitcloud itself, some values faked 502 | INSERT INTO DApps VALUES ( 503 | 1, --id 504 | "Bitcloud", --name 505 | "Bitcloud bare bones.", --description 506 | "Bitcloud Foundation", --author 507 | "MIT", --license 508 | 0.01, --version 509 | 1, --is static 510 | NULL, --library 511 | 1, --run 512 | 1, --is downloaded 513 | 1, --bitcloud foundation repository 514 | "foo" --signature 515 | ); 516 | 517 | -- The default dependence only requires Bitcloud to run: 518 | INSERT INTO dependences VALUES ( 519 | 1, --Bitcloud dapp 520 | 1, --Bitcloud dapp depends on itself 521 | 0, --min version 522 | 999 --max version 523 | ); 524 | 525 | 526 | 527 | -- end 528 | -------------------------------------------------------------------------------- /bitcloud.c/nodepool_sql.h: -------------------------------------------------------------------------------- 1 | // This must be updated after every nodepool.sql change 2 | // Hex formated version of the schema... 3 | 4 | unsigned char nodepool_sql[] = { 5 | 0x2d, 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, 6 | 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x63, 0x75, 7 | 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x73, 8 | 0x65, 0x65, 0x20, 0x42, 0x69, 0x74, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 9 | 0x6f, 0x72, 0x67, 0x20, 0x77, 0x69, 0x6b, 0x69, 0x20, 0x2d, 0x2d, 0x0a, 10 | 0x2d, 0x2d, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x62, 0x69, 11 | 0x74, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 12 | 0x74, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x77, 0x2f, 0x4e, 0x6f, 0x64, 0x65, 13 | 0x70, 0x6f, 0x6f, 0x6c, 0x2e, 0x73, 0x71, 0x6c, 0x5f, 0x44, 0x61, 0x74, 14 | 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x44, 0x65, 0x73, 0x69, 0x67, 0x6e, 15 | 0x20, 0x2d, 0x2d, 0x0a, 0x2d, 0x2d, 0x20, 0x41, 0x6c, 0x6c, 0x20, 0x62, 16 | 0x65, 0x6c, 0x6f, 0x77, 0x20, 0x53, 0x51, 0x4c, 0x20, 0x73, 0x68, 0x6f, 17 | 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 18 | 0x69, 0x63, 0x20, 0x53, 0x51, 0x4c, 0x20, 0x2d, 0x2d, 0x0a, 0x0a, 0x2f, 19 | 0x2a, 0x20, 0x4e, 0x6f, 0x64, 0x65, 0x70, 0x6f, 0x6f, 0x6c, 0x2e, 0x73, 20 | 0x71, 0x6c, 0x20, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x0a, 21 | 0x0a, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x3a, 0x0a, 0x0a, 0x20, 0x2d, 0x20, 22 | 0x45, 0x76, 0x65, 0x72, 0x79, 0x20, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 23 | 0x20, 0x69, 0x73, 0x20, 0x6f, 0x77, 0x6e, 0x65, 0x64, 0x20, 0x62, 0x79, 24 | 0x20, 0x69, 0x74, 0x73, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 25 | 0x2c, 0x20, 0x61, 0x73, 0x20, 0x65, 0x6e, 0x66, 0x6f, 0x72, 0x63, 0x65, 26 | 0x64, 0x20, 0x76, 0x69, 0x61, 0x20, 0x73, 0x79, 0x6e, 0x63, 0x68, 0x72, 27 | 0x6f, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x20, 28 | 0x20, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x73, 29 | 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x2e, 0x0a, 0x0a, 0x20, 30 | 0x2d, 0x20, 0x54, 0x68, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x65, 31 | 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x20, 32 | 0x74, 0x68, 0x65, 0x20, 0x61, 0x62, 0x6f, 0x76, 0x65, 0x20, 0x69, 0x73, 33 | 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x61, 0x73, 0x65, 34 | 0x20, 0x6f, 0x66, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x66, 0x69, 0x6c, 35 | 0x65, 0x73, 0x2c, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x61, 0x72, 36 | 0x65, 0x0a, 0x20, 0x20, 0x20, 0x6f, 0x77, 0x6e, 0x65, 0x64, 0x20, 0x62, 37 | 0x79, 0x20, 0x62, 0x6f, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 38 | 0x73, 0x65, 0x72, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x50, 0x75, 0x62, 0x6c, 39 | 0x69, 0x73, 0x68, 0x65, 0x72, 0x2e, 0x0a, 0x0a, 0x20, 0x2d, 0x20, 0x45, 40 | 0x76, 0x65, 0x72, 0x79, 0x20, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x20, 41 | 0x6d, 0x61, 0x79, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x62, 0x65, 0x20, 42 | 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x2f, 0x64, 0x65, 0x6c, 43 | 0x65, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x69, 0x74, 0x73, 0x20, 44 | 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x28, 0x73, 0x29, 0x2c, 0x20, 0x62, 0x75, 45 | 0x74, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x62, 0x65, 0x0a, 0x20, 0x20, 0x20, 46 | 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x61, 47 | 0x6e, 0x79, 0x6f, 0x6e, 0x65, 0x20, 0x76, 0x69, 0x61, 0x20, 0x22, 0x67, 48 | 0x61, 0x72, 0x62, 0x61, 0x67, 0x65, 0x20, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 49 | 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x20, 0x69, 0x66, 0x20, 0x69, 0x74, 50 | 0x73, 0x20, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x28, 0x73, 0x29, 0x20, 0x68, 51 | 0x61, 0x76, 0x65, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 52 | 0x62, 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x20, 0x2d, 0x20, 53 | 0x53, 0x51, 0x4c, 0x69, 0x74, 0x65, 0x20, 0x73, 0x75, 0x70, 0x70, 0x6f, 54 | 0x72, 0x74, 0x73, 0x20, 0x44, 0x42, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 55 | 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x20, 56 | 0x70, 0x72, 0x6f, 0x63, 0x65, 0x64, 0x75, 0x72, 0x65, 0x73, 0x20, 0x77, 57 | 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x43, 0x2e, 58 | 0x20, 0x20, 0x54, 0x68, 0x6f, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x66, 59 | 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2c, 0x20, 0x74, 0x68, 60 | 0x65, 0x72, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x2c, 0x20, 0x77, 0x69, 0x6c, 61 | 0x6c, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x62, 0x65, 0x20, 0x72, 0x65, 62 | 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x64, 0x20, 0x68, 0x65, 0x72, 63 | 0x65, 0x69, 0x6e, 0x67, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 64 | 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x70, 0x72, 65 | 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 66 | 0x65, 0x20, 0x73, 0x79, 0x6e, 0x63, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x69, 67 | 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x20, 0x63, 0x6f, 0x64, 68 | 0x65, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x77, 0x68, 0x65, 0x72, 0x65, 0x2e, 69 | 0x0a, 0x0a, 0x20, 0x2a, 0x2f, 0x0a, 0x0a, 0x50, 0x52, 0x41, 0x47, 0x4d, 70 | 0x41, 0x20, 0x66, 0x6f, 0x72, 0x65, 0x69, 0x67, 0x6e, 0x5f, 0x6b, 0x65, 71 | 0x79, 0x73, 0x20, 0x3d, 0x20, 0x4f, 0x4e, 0x3b, 0x0a, 0x0a, 0x2d, 0x2d, 72 | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 73 | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 74 | 0x2d, 0x2d, 0x0a, 0x2d, 0x2d, 0x20, 0x42, 0x69, 0x74, 0x63, 0x6c, 0x6f, 75 | 0x75, 0x64, 0x20, 0x4e, 0x6f, 0x64, 0x65, 0x70, 0x6f, 0x6f, 0x6c, 0x20, 76 | 0x54, 0x65, 0x61, 0x6d, 0x20, 0x2d, 0x2d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 77 | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 78 | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 79 | 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 80 | 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x70, 0x6f, 0x6f, 0x6c, 0x20, 0x2d, 0x2d, 81 | 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x54, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6e, 82 | 0x74, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 83 | 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x20, 0x6e, 0x6f, 0x64, 84 | 0x65, 0x70, 0x6f, 0x6f, 0x6c, 0x20, 0x61, 0x72, 0x65, 0x20, 0x73, 0x79, 85 | 0x6e, 0x63, 0x65, 0x64, 0x20, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x6c, 86 | 0x79, 0x20, 0x61, 0x63, 0x72, 0x6f, 0x73, 0x73, 0x20, 0x65, 0x76, 0x65, 87 | 0x72, 0x79, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x0a, 0x2d, 0x2d, 0x20, 88 | 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x42, 0x69, 0x74, 0x63, 0x6c, 89 | 0x6f, 0x75, 0x64, 0x20, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 90 | 0x0a, 0x0a, 0x2f, 0x2a, 0x0a, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x20, 91 | 0x74, 0x61, 0x62, 0x6c, 0x65, 0x0a, 0x0a, 0x20, 0x43, 0x6f, 0x6e, 0x74, 92 | 0x61, 0x69, 0x6e, 0x73, 0x3a, 0x20, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 93 | 0x73, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6e, 0x6f, 0x64, 94 | 0x65, 0x73, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x42, 0x69, 95 | 0x74, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x20, 0x6e, 0x65, 0x77, 0x6f, 0x72, 96 | 0x6b, 0x20, 0x28, 0x75, 0x70, 0x20, 0x74, 0x6f, 0x20, 0x31, 0x2e, 0x38, 97 | 0x65, 0x31, 0x39, 0x29, 0x0a, 0x0a, 0x20, 0x52, 0x75, 0x6c, 0x65, 0x73, 98 | 0x3a, 0x0a, 0x0a, 0x20, 0x2d, 0x20, 0x45, 0x61, 0x63, 0x68, 0x20, 0x6e, 99 | 0x6f, 0x64, 0x65, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x73, 0x69, 0x67, 100 | 0x6e, 0x20, 0x69, 0x74, 0x73, 0x20, 0x6f, 0x77, 0x6e, 0x20, 0x65, 0x6e, 101 | 0x74, 0x69, 0x72, 0x65, 0x20, 0x72, 0x6f, 0x77, 0x20, 0x28, 0x65, 0x78, 102 | 0x63, 0x65, 0x70, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x69, 0x67, 103 | 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 104 | 0x20, 0x69, 0x74, 0x73, 0x65, 0x6c, 0x66, 0x29, 0x0a, 0x20, 0x75, 0x73, 105 | 0x69, 0x6e, 0x67, 0x20, 0x69, 0x74, 0x73, 0x20, 0x6f, 0x77, 0x6e, 0x20, 106 | 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x6b, 0x65, 0x79, 0x2e, 0x0a, 107 | 0x0a, 0x20, 0x2d, 0x20, 0x54, 0x68, 0x65, 0x20, 0x6e, 0x6f, 0x64, 0x65, 108 | 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 109 | 0x65, 0x20, 0x61, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x73, 0x69, 0x67, 0x6e, 110 | 0x61, 0x74, 0x75, 0x72, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x69, 0x74, 0x73, 111 | 0x20, 0x72, 0x6f, 0x77, 0x20, 0x65, 0x76, 0x65, 0x72, 0x79, 0x20, 0x33, 112 | 0x20, 0x64, 0x61, 0x79, 0x73, 0x0a, 0x20, 0x6d, 0x61, 0x78, 0x69, 0x6d, 113 | 0x75, 0x6d, 0x2e, 0x20, 0x4f, 0x74, 0x68, 0x65, 0x72, 0x77, 0x69, 0x73, 114 | 0x65, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x64, 0x65, 0x6c, 0x65, 115 | 0x74, 0x65, 0x64, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 116 | 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x70, 0x6f, 0x6f, 0x6c, 0x20, 0x61, 0x6e, 117 | 0x64, 0x20, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 118 | 0x73, 0x20, 0x72, 0x65, 0x66, 0x75, 0x73, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 119 | 0x20, 0x2d, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 120 | 0x64, 0x61, 0x74, 0x65, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 121 | 0x20, 0x77, 0x69, 0x74, 0x68, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 122 | 0x73, 0x61, 0x6d, 0x65, 0x20, 0x73, 0x79, 0x6e, 0x63, 0x68, 0x72, 0x6f, 123 | 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x65, 0x72, 124 | 0x69, 0x6f, 0x64, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 125 | 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x0a, 0x20, 0x69, 0x73, 0x20, 0x72, 0x65, 126 | 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 127 | 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x20, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 128 | 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x76, 0x61, 129 | 0x6c, 0x69, 0x64, 0x2e, 0x0a, 0x0a, 0x20, 0x2d, 0x20, 0x43, 0x6f, 0x6e, 130 | 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x79, 0x20, 0x69, 0x73, 0x20, 131 | 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x65, 132 | 0x6e, 0x73, 0x75, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x61, 0x74, 133 | 0x20, 0x6e, 0x6f, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x74, 0x72, 0x69, 0x65, 134 | 0x73, 0x20, 0x74, 0x6f, 0x20, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 135 | 0x72, 0x20, 0x69, 0x6e, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x0a, 0x20, 136 | 0x20, 0x20, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x20, 0x74, 0x68, 0x61, 137 | 0x74, 0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x74, 0x68, 0x65, 138 | 0x20, 0x61, 0x63, 0x74, 0x75, 0x61, 0x6c, 0x3a, 0x0a, 0x0a, 0x2a, 0x2f, 139 | 0x0a, 0x0a, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x20, 0x54, 0x41, 0x42, 140 | 0x4c, 0x45, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x20, 0x28, 0x0a, 0x20, 141 | 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x20, 0x42, 142 | 0x4c, 0x4f, 0x42, 0x20, 0x50, 0x52, 0x49, 0x4d, 0x41, 0x52, 0x59, 0x20, 143 | 0x4b, 0x45, 0x59, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x4e, 0x55, 0x4c, 0x4c, 144 | 0x2c, 0x20, 0x2d, 0x2d, 0x20, 0x49, 0x44, 0x0a, 0x20, 0x70, 0x72, 0x6f, 145 | 0x78, 0x69, 0x6d, 0x69, 0x74, 0x79, 0x20, 0x42, 0x4c, 0x4f, 0x42, 0x20, 146 | 0x4e, 0x4f, 0x54, 0x20, 0x4e, 0x55, 0x4c, 0x4c, 0x2c, 0x20, 0x2d, 0x2d, 147 | 0x20, 0x44, 0x48, 0x54, 0x20, 0x28, 0x6b, 0x61, 0x64, 0x65, 0x6d, 0x6c, 148 | 0x69, 0x61, 0x2d, 0x6c, 0x69, 0x6b, 0x65, 0x29, 0x20, 0x6d, 0x61, 0x70, 149 | 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 150 | 0x0a, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x20, 151 | 0x42, 0x4c, 0x4f, 0x42, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x4e, 0x55, 0x4c, 152 | 0x4c, 0x2c, 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x20, 153 | 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 154 | 0x6f, 0x66, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x72, 0x6f, 0x77, 0x0a, 155 | 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x61, 156 | 0x74, 0x65, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x20, 0x4e, 157 | 0x4f, 0x54, 0x20, 0x4e, 0x55, 0x4c, 0x4c, 0x2c, 0x0a, 0x20, 0x70, 0x72, 158 | 0x6f, 0x6f, 0x66, 0x5f, 0x6f, 0x66, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 159 | 0x69, 0x6f, 0x6e, 0x20, 0x42, 0x4c, 0x4f, 0x42, 0x2c, 0x20, 0x2d, 0x2d, 160 | 0x20, 0x73, 0x65, 0x65, 0x20, 0x43, 0x41, 0x20, 0x67, 0x65, 0x6e, 0x65, 161 | 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 162 | 0x65, 0x20, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x20, 0x73, 163 | 0x70, 0x65, 0x63, 0x0a, 0x20, 0x6e, 0x65, 0x74, 0x5f, 0x70, 0x72, 0x6f, 164 | 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 165 | 0x52, 0x20, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x20, 0x31, 0x2c, 166 | 0x20, 0x2d, 0x2d, 0x20, 0x31, 0x20, 0x49, 0x50, 0x2c, 0x20, 0x32, 0x20, 167 | 0x54, 0x6f, 0x72, 0x0a, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 168 | 0x20, 0x54, 0x45, 0x58, 0x54, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x4e, 0x55, 169 | 0x4c, 0x4c, 0x20, 0x2d, 0x2d, 0x20, 0x49, 0x50, 0x20, 0x6f, 0x72, 0x20, 170 | 0x6f, 0x6e, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 171 | 0x73, 0x0a, 0x29, 0x3b, 0x0a, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x41, 0x20, 172 | 0x67, 0x72, 0x69, 0x64, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x63, 0x6f, 173 | 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 174 | 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x20, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 175 | 0x61, 0x74, 0x65, 0x64, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x63, 0x61, 176 | 0x6e, 0x20, 0x73, 0x65, 0x6c, 0x6c, 0x0a, 0x2d, 0x2d, 0x20, 0x73, 0x70, 177 | 0x61, 0x63, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x62, 0x61, 0x6e, 0x64, 178 | 0x77, 0x69, 0x64, 0x74, 0x68, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x20, 0x70, 179 | 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x0a, 0x43, 0x52, 0x45, 180 | 0x41, 0x54, 0x45, 0x20, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x20, 0x67, 0x72, 181 | 0x69, 0x64, 0x73, 0x20, 0x28, 0x0a, 0x20, 0x69, 0x64, 0x20, 0x42, 0x4c, 182 | 0x4f, 0x42, 0x20, 0x50, 0x52, 0x49, 0x4d, 0x41, 0x52, 0x59, 0x20, 0x4b, 183 | 0x45, 0x59, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x4e, 0x55, 0x4c, 0x4c, 0x2c, 184 | 0x20, 0x2d, 0x2d, 0x20, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x20, 0x6e, 185 | 0x75, 0x6d, 0x62, 0x65, 0x72, 0x0a, 0x20, 0x6f, 0x77, 0x6e, 0x65, 0x72, 186 | 0x5f, 0x69, 0x64, 0x20, 0x42, 0x4c, 0x4f, 0x42, 0x20, 0x4e, 0x4f, 0x54, 187 | 0x20, 0x4e, 0x55, 0x4c, 0x4c, 0x20, 0x52, 0x45, 0x46, 0x45, 0x52, 0x45, 188 | 0x4e, 0x43, 0x45, 0x53, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x28, 0x70, 189 | 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x29, 0x2c, 0x0a, 190 | 0x20, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x20, 0x42, 191 | 0x4c, 0x4f, 0x42, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x4e, 0x55, 0x4c, 0x4c, 192 | 0x20, 0x2d, 0x2d, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 193 | 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x77, 0x6e, 194 | 0x65, 0x72, 0x0a, 0x29, 0x3b, 0x0a, 0x0a, 0x0a, 0x43, 0x52, 0x45, 0x41, 195 | 0x54, 0x45, 0x20, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x20, 0x70, 0x75, 0x62, 196 | 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x20, 0x28, 0x0a, 0x20, 0x70, 197 | 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x20, 0x42, 0x4c, 198 | 0x4f, 0x42, 0x20, 0x50, 0x52, 0x49, 0x4d, 0x41, 0x52, 0x59, 0x20, 0x4b, 199 | 0x45, 0x59, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x4e, 0x55, 0x4c, 0x4c, 0x2c, 200 | 0x0a, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x20, 0x54, 0x45, 201 | 0x58, 0x54, 0x2c, 0x0a, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 202 | 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x20, 0x44, 0x41, 0x54, 0x45, 0x20, 203 | 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x20, 0x43, 0x55, 0x52, 0x52, 204 | 0x45, 0x4e, 0x54, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x53, 0x54, 0x41, 0x4d, 205 | 0x50, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x4e, 0x55, 0x4c, 0x4c, 0x2c, 0x0a, 206 | 0x20, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x5f, 0x6f, 0x66, 0x5f, 0x63, 0x72, 207 | 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x42, 0x4c, 0x4f, 0x42, 0x2c, 208 | 0x20, 0x2d, 0x2d, 0x20, 0x73, 0x65, 0x65, 0x20, 0x43, 0x41, 0x20, 0x67, 209 | 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 210 | 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 211 | 0x6c, 0x20, 0x73, 0x70, 0x65, 0x63, 0x0a, 0x20, 0x6e, 0x69, 0x63, 0x6b, 212 | 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x54, 0x45, 0x58, 0x54, 0x2c, 0x0a, 0x20, 213 | 0x2d, 0x2d, 0x20, 0x69, 0x73, 0x20, 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 214 | 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x20, 215 | 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x20, 216 | 0x6f, 0x66, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x70, 0x75, 0x62, 0x6c, 217 | 0x69, 0x73, 0x68, 0x65, 0x72, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 218 | 0x3f, 0x3a, 0x0a, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6d, 219 | 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x20, 0x42, 0x4f, 0x4f, 0x4c, 220 | 0x45, 0x41, 0x4e, 0x20, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x20, 221 | 0x46, 0x41, 0x4c, 0x53, 0x45, 0x2c, 0x0a, 0x20, 0x70, 0x75, 0x62, 0x6c, 222 | 0x69, 0x63, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x20, 0x42, 0x4f, 0x4f, 223 | 0x4c, 0x45, 0x41, 0x4e, 0x20, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 224 | 0x20, 0x46, 0x41, 0x4c, 0x53, 0x45, 0x2c, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 225 | 0x74, 0x72, 0x75, 0x73, 0x74, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x74, 226 | 0x68, 0x65, 0x72, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 227 | 0x72, 0x20, 0x75, 0x73, 0x65, 0x72, 0x73, 0x20, 0x62, 0x79, 0x20, 0x64, 228 | 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x3f, 0x20, 0x49, 0x66, 0x20, 0x6e, 229 | 0x6f, 0x74, 0x2c, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x74, 0x72, 0x75, 230 | 0x73, 0x74, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x74, 0x68, 0x6f, 0x73, 0x65, 231 | 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x75, 0x62, 0x6c, 232 | 0x69, 0x73, 0x68, 0x65, 0x72, 0x5f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x73, 233 | 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 234 | 0x76, 0x65, 0x20, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x20, 0x49, 0x66, 235 | 0x20, 0x79, 0x65, 0x73, 0x2c, 0x20, 0x74, 0x72, 0x75, 0x73, 0x74, 0x0a, 236 | 0x20, 0x2d, 0x2d, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x65, 0x78, 0x63, 0x65, 237 | 0x70, 0x74, 0x20, 0x74, 0x68, 0x6f, 0x73, 0x65, 0x20, 0x77, 0x69, 0x74, 238 | 0x68, 0x20, 0x6e, 0x65, 0x67, 0x61, 0x74, 0x69, 0x76, 0x65, 0x20, 0x74, 239 | 0x72, 0x75, 0x73, 0x74, 0x2e, 0x0a, 0x20, 0x74, 0x72, 0x75, 0x73, 0x74, 240 | 0x5f, 0x61, 0x6c, 0x6c, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x20, 0x42, 241 | 0x4f, 0x4f, 0x4c, 0x45, 0x41, 0x4e, 0x20, 0x44, 0x45, 0x46, 0x41, 0x55, 242 | 0x4c, 0x54, 0x20, 0x54, 0x52, 0x55, 0x45, 0x0a, 0x29, 0x3b, 0x0a, 0x0a, 243 | 0x0a, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 244 | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 245 | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 246 | 0x2d, 0x2d, 0x2d, 0x0a, 0x2d, 0x2d, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 247 | 0x6e, 0x61, 0x6c, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 248 | 0x72, 0x73, 0x2f, 0x67, 0x72, 0x69, 0x64, 0x20, 0x74, 0x61, 0x62, 0x6c, 249 | 0x65, 0x73, 0x20, 0x2d, 0x2d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 250 | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 251 | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 252 | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 253 | 0x74, 0x68, 0x65, 0x73, 0x65, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 254 | 0x20, 0x61, 0x72, 0x65, 0x20, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x20, 255 | 0x62, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x20, 0x61, 0x73, 0x73, 0x6f, 256 | 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x28, 0x65, 0x2e, 257 | 0x67, 0x2e, 0x2c, 0x20, 0x62, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x20, 258 | 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x20, 0x61, 259 | 0x6e, 0x64, 0x0a, 0x2d, 0x2d, 0x20, 0x67, 0x72, 0x69, 0x64, 0x73, 0x2c, 260 | 0x20, 0x6f, 0x72, 0x20, 0x67, 0x72, 0x69, 0x64, 0x73, 0x20, 0x61, 0x6e, 261 | 0x64, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x2c, 0x20, 0x65, 0x74, 0x63, 262 | 0x2e, 0x29, 0x0a, 0x0a, 0x2f, 0x2a, 0x0a, 0x0a, 0x20, 0x6e, 0x6f, 0x64, 263 | 0x65, 0x5f, 0x61, 0x75, 0x64, 0x69, 0x74, 0x20, 0x74, 0x61, 0x62, 0x6c, 264 | 0x65, 0x3a, 0x20, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x20, 0x69, 0x6e, 265 | 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 266 | 0x61, 0x72, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x69, 0x6e, 0x73, 267 | 0x65, 0x72, 0x74, 0x65, 0x64, 0x20, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 268 | 0x61, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x20, 0x66, 0x61, 0x69, 0x6c, 0x65, 269 | 0x64, 0x0a, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 270 | 0x65, 0x20, 0x61, 0x20, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x20, 271 | 0x63, 0x68, 0x65, 0x63, 0x6b, 0x2e, 0x20, 0x45, 0x76, 0x65, 0x72, 0x79, 272 | 0x20, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x20, 0x72, 0x6f, 0x77, 0x20, 273 | 0x69, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x74, 0x61, 0x62, 0x6c, 274 | 0x65, 0x20, 0x69, 0x73, 0x20, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 275 | 0x20, 0x61, 0x66, 0x74, 0x65, 0x72, 0x0a, 0x20, 0x65, 0x76, 0x65, 0x72, 276 | 0x79, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x70, 0x65, 0x72, 0x69, 277 | 0x6f, 0x64, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 278 | 0x6e, 0x65, 0x77, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x20, 279 | 0x62, 0x61, 0x73, 0x65, 0x64, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 280 | 0x20, 0x6c, 0x61, 0x73, 0x74, 0x20, 0x6f, 0x6e, 0x65, 0x2c, 0x20, 0x73, 281 | 0x6f, 0x20, 0x69, 0x74, 0x20, 0x63, 0x61, 0x6e, 0x0a, 0x20, 0x65, 0x6e, 282 | 0x73, 0x75, 0x72, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 283 | 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 284 | 0x20, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 285 | 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x61, 0x76, 0x65, 0x20, 0x73, 286 | 0x70, 0x61, 0x63, 0x65, 0x20, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 287 | 0x73, 0x61, 0x6d, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x0a, 0x0a, 288 | 0x20, 0x46, 0x6f, 0x72, 0x20, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 289 | 0x2c, 0x20, 0x69, 0x66, 0x20, 0x61, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x20, 290 | 0x66, 0x61, 0x69, 0x6c, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x20, 291 | 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x66, 0x6f, 292 | 0x72, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x20, 0x70, 0x65, 0x72, 0x69, 0x6f, 293 | 0x64, 0x73, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 0x20, 0x69, 0x73, 294 | 0x20, 0x6e, 0x6f, 0x0a, 0x20, 0x6e, 0x65, 0x65, 0x64, 0x20, 0x74, 0x68, 295 | 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x73, 296 | 0x20, 0x64, 0x6f, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 297 | 0x68, 0x65, 0x63, 0x6b, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x74, 0x6f, 298 | 0x20, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x20, 0x6e, 0x65, 0x77, 0x20, 299 | 0x72, 0x6f, 0x77, 0x73, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x79, 0x20, 0x6a, 300 | 0x75, 0x73, 0x74, 0x20, 0x72, 0x65, 0x75, 0x73, 0x65, 0x0a, 0x20, 0x74, 301 | 0x68, 0x65, 0x20, 0x72, 0x6f, 0x77, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d, 302 | 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 303 | 0x73, 0x20, 0x70, 0x65, 0x72, 0x69, 0x72, 0x6f, 0x64, 0x73, 0x2c, 0x20, 304 | 0x61, 0x6e, 0x64, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x20, 0x74, 0x68, 0x65, 305 | 0x20, 0x72, 0x6f, 0x77, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, 0x6c, 0x69, 306 | 0x6d, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x31, 0x36, 0x20, 0x72, 0x6f, 307 | 0x77, 0x73, 0x0a, 0x20, 0x70, 0x65, 0x72, 0x20, 0x6e, 0x6f, 0x64, 0x65, 308 | 0x2e, 0x0a, 0x0a, 0x20, 0x41, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x73, 309 | 0x20, 0x61, 0x72, 0x65, 0x20, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x2e, 310 | 0x0a, 0x0a, 0x20, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x20, 0x64, 0x6f, 0x69, 311 | 0x6e, 0x67, 0x20, 0x65, 0x76, 0x65, 0x72, 0x79, 0x74, 0x68, 0x69, 0x6e, 312 | 0x67, 0x20, 0x70, 0x65, 0x72, 0x66, 0x65, 0x63, 0x74, 0x20, 0x61, 0x72, 313 | 0x65, 0x20, 0x6e, 0x65, 0x76, 0x65, 0x72, 0x20, 0x70, 0x72, 0x65, 0x73, 314 | 0x65, 0x6e, 0x74, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 315 | 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x65, 0x78, 0x63, 0x65, 0x70, 0x74, 316 | 0x20, 0x77, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x69, 0x73, 0x73, 0x75, 0x65, 317 | 0x64, 0x20, 0x62, 0x79, 0x20, 0x6d, 0x61, 0x6c, 0x69, 0x63, 0x69, 0x6f, 318 | 0x75, 0x73, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x2e, 0x20, 0x54, 0x68, 319 | 0x65, 0x20, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x6f, 320 | 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x65, 0x74, 0x20, 0x6d, 0x75, 321 | 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x6d, 0x61, 0x6c, 0x69, 0x63, 0x69, 322 | 0x6f, 0x75, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x6f, 0x72, 0x64, 0x65, 0x72, 323 | 0x0a, 0x20, 0x74, 0x6f, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x63, 0x6f, 324 | 0x6e, 0x73, 0x65, 0x63, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x20, 0x66, 325 | 0x6f, 0x72, 0x20, 0x74, 0x68, 0x6f, 0x73, 0x65, 0x20, 0x6e, 0x6f, 0x64, 326 | 0x65, 0x73, 0x2e, 0x0a, 0x0a, 0x20, 0x42, 0x69, 0x74, 0x63, 0x6c, 0x6f, 327 | 0x75, 0x64, 0x20, 0x64, 0x6f, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x63, 0x6f, 328 | 0x75, 0x6e, 0x74, 0x20, 0x72, 0x65, 0x70, 0x75, 0x74, 0x61, 0x74, 0x69, 329 | 0x6f, 0x6e, 0x2c, 0x20, 0x62, 0x75, 0x74, 0x20, 0x6a, 0x75, 0x73, 0x74, 330 | 0x20, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x73, 0x20, 0x70, 0x6f, 331 | 0x73, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x20, 0x69, 0x6e, 0x63, 0x6f, 0x72, 332 | 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x0a, 333 | 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x2e, 0x20, 334 | 0x44, 0x41, 0x73, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x70, 0x20, 0x63, 335 | 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 336 | 0x6e, 0x74, 0x20, 0x61, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20, 337 | 0x6f, 0x66, 0x20, 0x72, 0x65, 0x70, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 338 | 0x6e, 0x20, 0x62, 0x61, 0x73, 0x65, 0x64, 0x20, 0x6f, 0x6e, 0x20, 0x74, 339 | 0x68, 0x69, 0x73, 0x0a, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x61, 340 | 0x6e, 0x64, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x74, 0x61, 0x62, 341 | 0x6c, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x79, 0x20, 0x70, 0x72, 0x6f, 342 | 0x76, 0x69, 0x64, 0x65, 0x2e, 0x0a, 0x0a, 0x2a, 0x2f, 0x0a, 0x0a, 0x0a, 343 | 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x20, 0x54, 0x41, 0x42, 0x4c, 0x45, 344 | 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x5f, 0x74, 345 | 0x72, 0x75, 0x73, 0x74, 0x73, 0x20, 0x28, 0x0a, 0x20, 0x66, 0x72, 0x6f, 346 | 0x6d, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x20, 347 | 0x42, 0x4c, 0x4f, 0x42, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x4e, 0x55, 0x4c, 348 | 0x4c, 0x20, 0x52, 0x45, 0x46, 0x45, 0x52, 0x45, 0x4e, 0x43, 0x45, 0x53, 349 | 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x28, 350 | 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x29, 0x2c, 351 | 0x0a, 0x20, 0x74, 0x6f, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 352 | 0x65, 0x72, 0x20, 0x42, 0x4c, 0x4f, 0x42, 0x20, 0x52, 0x45, 0x46, 0x45, 353 | 0x52, 0x45, 0x4e, 0x43, 0x45, 0x53, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 354 | 0x73, 0x68, 0x65, 0x72, 0x73, 0x28, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 355 | 0x5f, 0x6b, 0x65, 0x79, 0x29, 0x2c, 0x0a, 0x20, 0x74, 0x72, 0x75, 0x73, 356 | 0x74, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x20, 0x42, 0x4f, 0x4f, 0x4c, 357 | 0x45, 0x41, 0x4e, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x4e, 0x55, 0x4c, 0x4c, 358 | 0x2c, 0x0a, 0x20, 0x74, 0x72, 0x75, 0x73, 0x74, 0x5f, 0x70, 0x6f, 0x77, 359 | 0x65, 0x72, 0x73, 0x20, 0x42, 0x4f, 0x4f, 0x4c, 0x45, 0x41, 0x4e, 0x20, 360 | 0x4e, 0x4f, 0x54, 0x20, 0x4e, 0x55, 0x4c, 0x4c, 0x2c, 0x20, 0x2d, 0x2d, 361 | 0x20, 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x62, 0x61, 0x6e, 0x69, 0x6e, 0x67, 362 | 0x20, 0x75, 0x73, 0x65, 0x72, 0x73, 0x20, 0x6f, 0x72, 0x20, 0x6d, 0x6f, 363 | 0x64, 0x65, 0x72, 0x61, 0x74, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x73, 364 | 0x0a, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x20, 365 | 0x42, 0x4c, 0x4f, 0x42, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x4e, 0x55, 0x4c, 366 | 0x4c, 0x2c, 0x20, 0x2d, 0x2d, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x73, 367 | 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x0a, 0x20, 0x72, 0x65, 368 | 0x61, 0x73, 0x6f, 0x6e, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 369 | 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x4e, 0x55, 0x4c, 0x4c, 0x2c, 0x0a, 0x20, 370 | 0x2f, 0x2a, 0x0a, 0x20, 0x31, 0x3a, 0x20, 0x46, 0x72, 0x69, 0x65, 0x6e, 371 | 0x64, 0x0a, 0x20, 0x32, 0x3a, 0x20, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x64, 372 | 0x0a, 0x20, 0x33, 0x3a, 0x20, 0x42, 0x61, 0x64, 0x20, 0x63, 0x6f, 0x6e, 373 | 0x74, 0x72, 0x61, 0x63, 0x74, 0x73, 0x0a, 0x20, 0x34, 0x3a, 0x20, 0x2e, 374 | 0x2e, 0x2e, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x20, 0x63, 0x6f, 0x6e, 375 | 0x74, 0x69, 0x6e, 0x75, 0x65, 0x64, 0x0a, 0x20, 0x2a, 0x2f, 0x0a, 0x20, 376 | 0x43, 0x48, 0x45, 0x43, 0x4b, 0x20, 0x28, 0x72, 0x65, 0x61, 0x73, 0x6f, 377 | 0x6e, 0x3e, 0x3d, 0x31, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x72, 0x65, 0x61, 378 | 0x73, 0x6f, 0x6e, 0x20, 0x3c, 0x3d, 0x33, 0x29, 0x0a, 0x29, 0x3b, 0x0a, 379 | 0x0a, 0x0a, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x20, 0x54, 0x41, 0x42, 380 | 0x4c, 0x45, 0x20, 0x75, 0x73, 0x65, 0x72, 0x73, 0x20, 0x28, 0x0a, 0x20, 381 | 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x20, 0x42, 382 | 0x4c, 0x4f, 0x42, 0x20, 0x50, 0x52, 0x49, 0x4d, 0x41, 0x52, 0x59, 0x20, 383 | 0x4b, 0x45, 0x59, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x4e, 0x55, 0x4c, 0x4c, 384 | 0x2c, 0x0a, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 385 | 0x20, 0x42, 0x4c, 0x4f, 0x42, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x4e, 0x55, 386 | 0x4c, 0x4c, 0x20, 0x52, 0x45, 0x46, 0x45, 0x52, 0x45, 0x4e, 0x43, 0x45, 387 | 0x53, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 388 | 0x28, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x29, 389 | 0x2c, 0x0a, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 390 | 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x20, 0x42, 391 | 0x4c, 0x4f, 0x42, 0x2c, 0x0a, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 392 | 0x73, 0x20, 0x54, 0x45, 0x58, 0x54, 0x2c, 0x0a, 0x20, 0x6e, 0x69, 0x63, 393 | 0x6b, 0x20, 0x54, 0x45, 0x58, 0x54, 0x20, 0x43, 0x4f, 0x4c, 0x4c, 0x41, 394 | 0x54, 0x45, 0x20, 0x4e, 0x4f, 0x43, 0x41, 0x53, 0x45, 0x2c, 0x0a, 0x20, 395 | 0x66, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 396 | 0x73, 0x20, 0x42, 0x4f, 0x4f, 0x4c, 0x45, 0x41, 0x4e, 0x20, 0x44, 0x45, 397 | 0x46, 0x41, 0x55, 0x4c, 0x54, 0x20, 0x54, 0x52, 0x55, 0x45, 0x2c, 0x0a, 398 | 0x20, 0x72, 0x65, 0x76, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 399 | 0x64, 0x61, 0x74, 0x65, 0x20, 0x44, 0x41, 0x54, 0x45, 0x20, 0x44, 0x45, 400 | 0x46, 0x41, 0x55, 0x4c, 0x54, 0x20, 0x43, 0x55, 0x52, 0x52, 0x45, 0x4e, 401 | 0x54, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x53, 0x54, 0x41, 0x4d, 0x50, 0x2c, 402 | 0x0a, 0x20, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5f, 0x71, 0x75, 403 | 0x6f, 0x74, 0x61, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x20, 404 | 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x20, 0x30, 0x2c, 0x0a, 0x20, 405 | 0x62, 0x61, 0x6e, 0x64, 0x77, 0x69, 0x64, 0x74, 0x68, 0x5f, 0x71, 0x75, 406 | 0x6f, 0x74, 0x61, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x20, 407 | 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x20, 0x30, 0x2c, 0x0a, 0x20, 408 | 0x66, 0x69, 0x6c, 0x65, 0x73, 0x5f, 0x71, 0x75, 0x6f, 0x74, 0x61, 0x20, 409 | 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x20, 0x44, 0x45, 0x46, 0x41, 410 | 0x55, 0x4c, 0x54, 0x20, 0x30, 0x2c, 0x20, 0x2d, 0x2d, 0x20, 0x68, 0x6f, 411 | 0x77, 0x20, 0x6d, 0x61, 0x6e, 0x79, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x73, 412 | 0x20, 0x63, 0x61, 0x6e, 0x20, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x0a, 413 | 0x20, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x5f, 0x71, 0x75, 0x6f, 0x74, 414 | 0x61, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x20, 0x44, 0x45, 415 | 0x46, 0x41, 0x55, 0x4c, 0x54, 0x20, 0x30, 0x2c, 0x20, 0x2d, 0x2d, 0x20, 416 | 0x68, 0x6f, 0x77, 0x20, 0x6d, 0x61, 0x6e, 0x79, 0x20, 0x66, 0x6f, 0x6c, 417 | 0x64, 0x65, 0x72, 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 418 | 0x0a, 0x20, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x66, 0x6f, 0x6c, 0x64, 0x65, 419 | 0x72, 0x20, 0x42, 0x4c, 0x4f, 0x42, 0x20, 0x52, 0x45, 0x46, 0x45, 0x52, 420 | 0x45, 0x4e, 0x43, 0x45, 0x53, 0x20, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 421 | 0x73, 0x28, 0x69, 0x64, 0x29, 0x0a, 0x29, 0x3b, 0x0a, 0x0a, 0x2d, 0x2d, 422 | 0x20, 0x55, 0x73, 0x65, 0x72, 0x20, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 423 | 0x74, 0x73, 0x20, 0x73, 0x65, 0x6e, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x74, 424 | 0x68, 0x65, 0x20, 0x67, 0x72, 0x69, 0x64, 0x73, 0x2c, 0x20, 0x66, 0x6f, 425 | 0x72, 0x20, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x63, 426 | 0x72, 0x65, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x0a, 0x2d, 0x2d, 0x20, 0x61, 427 | 0x20, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x20, 0x6f, 0x72, 0x20, 0x75, 428 | 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x2f, 0x64, 0x6f, 0x77, 429 | 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x66, 430 | 0x69, 0x6c, 0x65, 0x0a, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x20, 0x54, 431 | 0x41, 0x42, 0x4c, 0x45, 0x20, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x72, 0x65, 432 | 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x20, 0x28, 0x0a, 0x20, 0x69, 0x64, 433 | 0x20, 0x42, 0x4c, 0x4f, 0x42, 0x20, 0x50, 0x52, 0x49, 0x4d, 0x41, 0x52, 434 | 0x59, 0x20, 0x4b, 0x45, 0x59, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x4e, 0x55, 435 | 0x4c, 0x4c, 0x2c, 0x0a, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x42, 0x4c, 436 | 0x4f, 0x42, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x4e, 0x55, 0x4c, 0x4c, 0x20, 437 | 0x52, 0x45, 0x46, 0x45, 0x52, 0x45, 0x4e, 0x43, 0x45, 0x53, 0x20, 0x75, 438 | 0x73, 0x65, 0x72, 0x73, 0x28, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 439 | 0x6b, 0x65, 0x79, 0x29, 0x2c, 0x0a, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x61, 440 | 0x74, 0x75, 0x72, 0x65, 0x20, 0x42, 0x4c, 0x4f, 0x42, 0x20, 0x4e, 0x4f, 441 | 0x54, 0x20, 0x4e, 0x55, 0x4c, 0x4c, 0x2c, 0x0a, 0x20, 0x67, 0x72, 0x69, 442 | 0x64, 0x20, 0x54, 0x45, 0x58, 0x54, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x4e, 443 | 0x55, 0x4c, 0x4c, 0x20, 0x52, 0x45, 0x46, 0x45, 0x52, 0x45, 0x4e, 0x43, 444 | 0x45, 0x53, 0x20, 0x67, 0x72, 0x69, 0x64, 0x73, 0x28, 0x70, 0x75, 0x62, 445 | 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x29, 0x2c, 0x0a, 0x20, 0x61, 446 | 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 447 | 0x52, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x4e, 0x55, 0x4c, 0x4c, 0x2c, 0x0a, 448 | 0x20, 0x2d, 0x2d, 0x20, 0x65, 0x76, 0x65, 0x72, 0x79, 0x20, 0x74, 0x79, 449 | 0x70, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 450 | 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x61, 451 | 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x70, 452 | 0x61, 0x72, 0x61, 0x6d, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x0a, 453 | 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x31, 0x20, 0x42, 0x4c, 0x4f, 0x42, 454 | 0x2c, 0x0a, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x32, 0x20, 0x42, 0x4c, 455 | 0x4f, 0x42, 0x2c, 0x0a, 0x20, 0x2f, 0x2a, 0x0a, 0x20, 0x31, 0x3a, 0x20, 456 | 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x20, 0x66, 0x69, 0x6c, 457 | 0x65, 0x3a, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x31, 0x3d, 0x66, 0x69, 458 | 0x6c, 0x65, 0x49, 0x44, 0x2c, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x32, 459 | 0x3d, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x0a, 0x20, 0x32, 0x3a, 0x20, 460 | 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x3a, 461 | 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x31, 0x3d, 0x66, 0x69, 0x6c, 0x65, 462 | 0x49, 0x44, 0x2c, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x32, 0x3d, 0x6f, 463 | 0x66, 0x66, 0x73, 0x65, 0x74, 0x0a, 0x20, 0x33, 0x3a, 0x20, 0x55, 0x70, 464 | 0x6c, 0x6f, 0x61, 0x64, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x3a, 0x20, 0x70, 465 | 0x61, 0x72, 0x61, 0x6d, 0x31, 0x3d, 0x66, 0x69, 0x6c, 0x65, 0x49, 0x44, 466 | 0x2c, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x32, 0x3d, 0x66, 0x6f, 0x6c, 467 | 0x64, 0x65, 0x72, 0x49, 0x44, 0x0a, 0x20, 0x34, 0x3a, 0x20, 0x43, 0x72, 468 | 0x65, 0x61, 0x74, 0x65, 0x20, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x3a, 469 | 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x31, 0x3d, 0x66, 0x6f, 0x6c, 0x64, 470 | 0x65, 0x72, 0x49, 0x44, 0x0a, 0x20, 0x35, 0x3a, 0x20, 0x52, 0x65, 0x6d, 471 | 0x6f, 0x76, 0x65, 0x20, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x3a, 0x20, 472 | 0x70, 0x61, 0x72, 0x61, 0x6d, 0x31, 0x3d, 0x66, 0x6f, 0x6c, 0x64, 0x65, 473 | 0x72, 0x49, 0x44, 0x0a, 0x20, 0x36, 0x3a, 0x20, 0x52, 0x65, 0x6e, 0x61, 474 | 0x6d, 0x65, 0x20, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x3a, 0x20, 0x70, 475 | 0x61, 0x72, 0x61, 0x6d, 0x31, 0x3d, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 476 | 0x49, 0x44, 0x0a, 0x20, 0x37, 0x3a, 0x20, 0x4d, 0x6f, 0x76, 0x65, 0x20, 477 | 0x66, 0x69, 0x6c, 0x65, 0x3a, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x31, 478 | 0x3d, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x5f, 0x66, 0x6f, 0x6c, 0x64, 479 | 0x65, 0x49, 0x44, 0x2c, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x32, 0x3d, 480 | 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x5f, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 481 | 0x49, 0x44, 0x0a, 0x20, 0x38, 0x3a, 0x20, 0x52, 0x65, 0x6e, 0x61, 0x6d, 482 | 0x65, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x3a, 0x20, 0x70, 0x61, 0x72, 0x61, 483 | 0x6d, 0x31, 0x3d, 0x66, 0x69, 0x6c, 0x65, 0x49, 0x44, 0x2c, 0x20, 0x70, 484 | 0x61, 0x72, 0x61, 0x6d, 0x32, 0x3d, 0x6e, 0x65, 0x77, 0x5f, 0x6e, 0x61, 485 | 0x6d, 0x65, 0x0a, 0x20, 0x39, 0x3a, 0x20, 0x44, 0x65, 0x6c, 0x65, 0x74, 486 | 0x65, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x3a, 0x20, 0x70, 0x61, 0x72, 0x61, 487 | 0x6d, 0x31, 0x3d, 0x66, 0x69, 0x6c, 0x65, 0x49, 0x44, 0x0a, 0x20, 0x31, 488 | 0x30, 0x3a, 0x20, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x66, 0x69, 489 | 0x6c, 0x65, 0x20, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x3a, 0x20, 0x70, 0x61, 490 | 0x72, 0x61, 0x6d, 0x31, 0x3d, 0x66, 0x69, 0x6c, 0x65, 0x49, 0x44, 0x2c, 491 | 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x32, 0x3d, 0x75, 0x73, 0x65, 0x72, 492 | 0x49, 0x44, 0x0a, 0x20, 0x31, 0x31, 0x3a, 0x20, 0x55, 0x70, 0x64, 0x61, 493 | 0x74, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x70, 0x65, 0x72, 0x6d, 494 | 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x20, 0x70, 0x61, 0x72, 495 | 0x61, 0x6d, 0x31, 0x3d, 0x66, 0x69, 0x6c, 0x65, 0x49, 0x44, 0x2c, 0x20, 496 | 0x70, 0x61, 0x72, 0x61, 0x6d, 0x32, 0x3d, 0x66, 0x6c, 0x61, 0x67, 0x73, 497 | 0x0a, 0x20, 0x31, 0x31, 0x3a, 0x20, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x20, 498 | 0x75, 0x73, 0x65, 0x72, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x61, 0x63, 499 | 0x63, 0x65, 0x73, 0x73, 0x3a, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x31, 500 | 0x3d, 0x66, 0x69, 0x6c, 0x65, 0x49, 0x44, 0x2c, 0x20, 0x70, 0x61, 0x72, 501 | 0x61, 0x6d, 0x32, 0x3d, 0x75, 0x73, 0x65, 0x72, 0x49, 0x44, 0x0a, 0x20, 502 | 0x31, 0x32, 0x3a, 0x20, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x20, 0x75, 0x73, 503 | 0x65, 0x72, 0x20, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x20, 0x61, 0x63, 504 | 0x63, 0x63, 0x65, 0x73, 0x73, 0x3a, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 505 | 0x31, 0x3d, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x49, 0x44, 0x2c, 0x20, 506 | 0x70, 0x61, 0x72, 0x61, 0x6d, 0x32, 0x3d, 0x75, 0x73, 0x65, 0x72, 0x49, 507 | 0x44, 0x0a, 0x20, 0x31, 0x33, 0x3a, 0x20, 0x2e, 0x2e, 0x2e, 0x20, 0x74, 508 | 0x6f, 0x20, 0x62, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 509 | 0x65, 0x64, 0x0a, 0x20, 0x2a, 0x2f, 0x0a, 0x20, 0x43, 0x48, 0x45, 0x43, 510 | 0x4b, 0x20, 0x28, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3e, 0x20, 511 | 0x30, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 512 | 0x3c, 0x3d, 0x31, 0x32, 0x29, 0x0a, 0x29, 0x3b, 0x0a, 0x0a, 0x0a, 0x43, 513 | 0x52, 0x45, 0x41, 0x54, 0x45, 0x20, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x20, 514 | 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x5f, 0x67, 0x72, 515 | 0x69, 0x64, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x73, 516 | 0x20, 0x28, 0x0a, 0x20, 0x69, 0x64, 0x20, 0x42, 0x4c, 0x4f, 0x42, 0x20, 517 | 0x50, 0x52, 0x49, 0x4d, 0x41, 0x52, 0x59, 0x20, 0x4b, 0x45, 0x59, 0x20, 518 | 0x4e, 0x4f, 0x54, 0x20, 0x4e, 0x55, 0x4c, 0x4c, 0x2c, 0x0a, 0x20, 0x70, 519 | 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x20, 0x42, 0x4c, 0x4f, 520 | 0x42, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x4e, 0x55, 0x4c, 0x4c, 0x20, 0x52, 521 | 0x45, 0x46, 0x45, 0x52, 0x45, 0x4e, 0x43, 0x45, 0x53, 0x20, 0x70, 0x75, 522 | 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x28, 0x70, 0x75, 0x62, 523 | 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x29, 0x2c, 0x0a, 0x20, 0x67, 524 | 0x72, 0x69, 0x64, 0x20, 0x54, 0x45, 0x58, 0x54, 0x20, 0x4e, 0x4f, 0x54, 525 | 0x20, 0x4e, 0x55, 0x4c, 0x4c, 0x20, 0x52, 0x45, 0x46, 0x45, 0x52, 0x45, 526 | 0x4e, 0x43, 0x45, 0x53, 0x20, 0x67, 0x72, 0x69, 0x64, 0x73, 0x28, 0x70, 527 | 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x29, 0x2c, 0x0a, 528 | 0x20, 0x2d, 0x2d, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 529 | 0x65, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x63, 530 | 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x3a, 0x0a, 0x20, 0x70, 0x75, 531 | 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x67, 0x20, 532 | 0x54, 0x45, 0x58, 0x54, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x4e, 0x55, 0x4c, 533 | 0x4c, 0x2c, 0x0a, 0x20, 0x67, 0x72, 0x69, 0x64, 0x5f, 0x73, 0x69, 0x67, 534 | 0x20, 0x54, 0x45, 0x58, 0x54, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x4e, 0x55, 535 | 0x4c, 0x4c, 0x2c, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x54, 0x65, 0x72, 0x6d, 536 | 0x73, 0x3a, 0x0a, 0x20, 0x6d, 0x69, 0x6e, 0x5f, 0x62, 0x61, 0x6e, 0x64, 537 | 0x77, 0x69, 0x64, 0x74, 0x68, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 538 | 0x52, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x4e, 0x55, 0x4c, 0x4c, 0x2c, 0x0a, 539 | 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x20, 540 | 0x44, 0x41, 0x54, 0x45, 0x20, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 541 | 0x20, 0x43, 0x55, 0x52, 0x52, 0x45, 0x4e, 0x54, 0x5f, 0x54, 0x49, 0x4d, 542 | 0x45, 0x53, 0x54, 0x41, 0x4d, 0x50, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x4e, 543 | 0x55, 0x4c, 0x4c, 0x2c, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x5f, 0x64, 0x61, 544 | 0x74, 0x65, 0x20, 0x44, 0x41, 0x54, 0x45, 0x20, 0x44, 0x45, 0x46, 0x41, 545 | 0x55, 0x4c, 0x54, 0x20, 0x43, 0x55, 0x52, 0x52, 0x45, 0x4e, 0x54, 0x5f, 546 | 0x54, 0x49, 0x4d, 0x45, 0x53, 0x54, 0x41, 0x4d, 0x50, 0x20, 0x4e, 0x4f, 547 | 0x54, 0x20, 0x4e, 0x55, 0x4c, 0x4c, 0x2c, 0x0a, 0x20, 0x61, 0x76, 0x61, 548 | 0x69, 0x6c, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x20, 0x49, 0x4e, 549 | 0x54, 0x45, 0x47, 0x45, 0x52, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x4e, 0x55, 550 | 0x4c, 0x4c, 0x2c, 0x20, 0x2d, 0x2d, 0x20, 0x25, 0x20, 0x6f, 0x66, 0x20, 551 | 0x74, 0x69, 0x6d, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x0a, 552 | 0x20, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x76, 0x65, 0x72, 0x61, 0x67, 553 | 0x65, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x20, 0x44, 0x45, 554 | 0x46, 0x41, 0x55, 0x4c, 0x54, 0x20, 0x30, 0x2c, 0x0a, 0x20, 0x2d, 0x2d, 555 | 0x20, 0x43, 0x6f, 0x69, 0x6e, 0x20, 0x74, 0x65, 0x72, 0x6d, 0x73, 0x0a, 556 | 0x20, 0x63, 0x6f, 0x69, 0x6e, 0x20, 0x54, 0x45, 0x58, 0x54, 0x20, 0x2f, 557 | 0x2a, 0x20, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x3a, 0x20, 0x42, 558 | 0x54, 0x43, 0x20, 0x2a, 0x2f, 0x0a, 0x29, 0x3b, 0x0a, 0x0a, 0x0a, 0x2d, 559 | 0x2d, 0x20, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 560 | 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x20, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 561 | 0x74, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x69, 0x74, 0x73, 0x20, 0x67, 0x72, 562 | 0x69, 0x64, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x0a, 0x43, 0x52, 0x45, 563 | 0x41, 0x54, 0x45, 0x20, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x20, 0x67, 0x72, 564 | 0x69, 0x64, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x71, 565 | 0x75, 0x65, 0x73, 0x74, 0x73, 0x20, 0x28, 0x0a, 0x20, 0x67, 0x72, 0x69, 566 | 0x64, 0x20, 0x42, 0x4c, 0x4f, 0x42, 0x20, 0x50, 0x52, 0x49, 0x4d, 0x41, 567 | 0x52, 0x59, 0x20, 0x4b, 0x45, 0x59, 0x20, 0x52, 0x45, 0x46, 0x45, 0x52, 568 | 0x45, 0x4e, 0x43, 0x45, 0x53, 0x20, 0x67, 0x72, 0x69, 0x64, 0x73, 0x28, 569 | 0x69, 0x64, 0x29, 0x2c, 0x0a, 0x20, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 570 | 0x73, 0x69, 0x67, 0x20, 0x42, 0x4c, 0x4f, 0x42, 0x20, 0x4e, 0x4f, 0x54, 571 | 0x20, 0x4e, 0x55, 0x4c, 0x4c, 0x2c, 0x0a, 0x20, 0x61, 0x63, 0x74, 0x69, 572 | 0x6f, 0x6e, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x20, 0x4e, 573 | 0x4f, 0x54, 0x20, 0x4e, 0x55, 0x4c, 0x4c, 0x2c, 0x0a, 0x20, 0x70, 0x61, 574 | 0x72, 0x61, 0x6d, 0x31, 0x20, 0x42, 0x4c, 0x4f, 0x42, 0x2c, 0x0a, 0x20, 575 | 0x70, 0x61, 0x72, 0x61, 0x6d, 0x32, 0x20, 0x42, 0x4c, 0x4f, 0x42, 0x0a, 576 | 0x20, 0x2f, 0x2a, 0x20, 0x70, 0x6f, 0x73, 0x73, 0x69, 0x62, 0x6c, 0x65, 577 | 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x0a, 0x20, 0x31, 0x3a, 578 | 0x20, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x20, 0x73, 0x74, 0x6f, 0x72, 579 | 0x61, 0x67, 0x65, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x3a, 0x20, 0x70, 0x61, 580 | 0x72, 0x61, 0x6d, 0x31, 0x3d, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x44, 0x2c, 581 | 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x32, 0x3d, 0x67, 0x61, 0x74, 0x65, 582 | 0x77, 0x61, 0x79, 0x49, 0x44, 0x0a, 0x20, 0x32, 0x3a, 0x20, 0x55, 0x70, 583 | 0x67, 0x72, 0x61, 0x64, 0x65, 0x20, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 584 | 0x65, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x67, 0x61, 585 | 0x74, 0x65, 0x77, 0x61, 0x79, 0x3a, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 586 | 0x31, 0x3d, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x44, 0x0a, 0x20, 0x33, 0x3a, 587 | 0x20, 0x53, 0x65, 0x74, 0x20, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 588 | 0x20, 0x62, 0x61, 0x6e, 0x64, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 589 | 0x70, 0x61, 0x72, 0x61, 0x6d, 0x31, 0x3d, 0x6e, 0x6f, 0x64, 0x65, 0x49, 590 | 0x44, 0x2c, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x32, 0x3d, 0x72, 0x61, 591 | 0x74, 0x65, 0x0a, 0x20, 0x34, 0x3a, 0x20, 0x52, 0x65, 0x76, 0x6f, 0x6b, 592 | 0x65, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x3a, 0x20, 0x70, 0x61, 0x72, 0x61, 593 | 0x6d, 0x31, 0x3d, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x44, 0x0a, 0x20, 0x35, 594 | 0x3a, 0x20, 0x2e, 0x2e, 0x2e, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x20, 595 | 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x64, 0x0a, 0x20, 0x2a, 596 | 0x2f, 0x0a, 0x29, 0x3b, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x54, 0x61, 0x62, 597 | 0x6c, 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 598 | 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x20, 0x69, 599 | 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x6f, 600 | 0x72, 0x64, 0x65, 0x72, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x63, 0x6f, 0x6e, 601 | 0x74, 0x72, 0x61, 0x63, 0x74, 0x65, 0x64, 0x20, 0x67, 0x72, 0x69, 0x64, 602 | 0x73, 0x3a, 0x0a, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x20, 0x54, 0x41, 603 | 0x42, 0x4c, 0x45, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 604 | 0x72, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x20, 0x28, 605 | 0x0a, 0x20, 0x67, 0x72, 0x69, 0x64, 0x5f, 0x73, 0x69, 0x67, 0x20, 0x42, 606 | 0x4c, 0x4f, 0x42, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x4e, 0x55, 0x4c, 0x4c, 607 | 0x2c, 0x0a, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 608 | 0x5f, 0x73, 0x69, 0x67, 0x20, 0x42, 0x4c, 0x4f, 0x42, 0x2c, 0x0a, 0x20, 609 | 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 610 | 0x45, 0x52, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x4e, 0x55, 0x4c, 0x4c, 0x2c, 611 | 0x0a, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x31, 0x20, 0x42, 0x4c, 0x4f, 612 | 0x42, 0x2c, 0x0a, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x32, 0x20, 0x42, 613 | 0x4c, 0x4f, 0x42, 0x2c, 0x0a, 0x20, 0x2f, 0x2a, 0x20, 0x70, 0x6f, 0x73, 614 | 0x73, 0x69, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 615 | 0x73, 0x3a, 0x0a, 0x20, 0x31, 0x3a, 0x20, 0x41, 0x63, 0x63, 0x65, 0x70, 616 | 0x74, 0x20, 0x75, 0x73, 0x65, 0x72, 0x3a, 0x20, 0x70, 0x61, 0x72, 0x61, 617 | 0x6d, 0x31, 0x3d, 0x75, 0x73, 0x65, 0x72, 0x49, 0x44, 0x2c, 0x20, 0x70, 618 | 0x61, 0x72, 0x61, 0x6d, 0x32, 0x3d, 0x64, 0x75, 0x65, 0x2d, 0x74, 0x69, 619 | 0x6d, 0x65, 0x0a, 0x20, 0x32, 0x3a, 0x20, 0x52, 0x65, 0x76, 0x6f, 0x6b, 620 | 0x65, 0x20, 0x75, 0x73, 0x65, 0x72, 0x3a, 0x20, 0x70, 0x61, 0x72, 0x61, 621 | 0x6d, 0x31, 0x3d, 0x75, 0x73, 0x65, 0x72, 0x49, 0x44, 0x0a, 0x20, 0x33, 622 | 0x3a, 0x20, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x20, 0x66, 0x69, 0x6c, 623 | 0x65, 0x3a, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x31, 0x3d, 0x66, 0x69, 624 | 0x6c, 0x65, 0x49, 0x44, 0x0a, 0x20, 0x34, 0x3a, 0x20, 0x52, 0x65, 0x6d, 625 | 0x6f, 0x76, 0x65, 0x20, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x3a, 0x20, 626 | 0x70, 0x61, 0x72, 0x61, 0x6d, 0x31, 0x3d, 0x66, 0x6f, 0x6c, 0x64, 0x65, 627 | 0x72, 0x49, 0x44, 0x0a, 0x20, 0x35, 0x3a, 0x20, 0x53, 0x65, 0x74, 0x20, 628 | 0x75, 0x73, 0x65, 0x72, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x20, 0x71, 629 | 0x75, 0x6f, 0x74, 0x61, 0x3a, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x31, 630 | 0x3d, 0x75, 0x73, 0x65, 0x72, 0x49, 0x44, 0x2c, 0x20, 0x70, 0x61, 0x72, 631 | 0x61, 0x6d, 0x32, 0x3d, 0x71, 0x75, 0x6f, 0x74, 0x61, 0x0a, 0x20, 0x36, 632 | 0x3a, 0x20, 0x53, 0x65, 0x74, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x73, 633 | 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x20, 0x71, 0x75, 0x6f, 0x74, 0x61, 634 | 0x3a, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x31, 0x3d, 0x75, 0x73, 0x65, 635 | 0x72, 0x49, 0x44, 0x2c, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x32, 0x3d, 636 | 0x71, 0x75, 0x6f, 0x74, 0x61, 0x0a, 0x20, 0x37, 0x3a, 0x20, 0x53, 0x65, 637 | 0x74, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x66, 0x6f, 0x6c, 0x64, 0x65, 638 | 0x72, 0x73, 0x20, 0x71, 0x75, 0x6f, 0x74, 0x61, 0x3a, 0x20, 0x70, 0x61, 639 | 0x72, 0x61, 0x6d, 0x31, 0x3d, 0x75, 0x73, 0x65, 0x72, 0x49, 0x44, 0x2c, 640 | 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x32, 0x3d, 0x71, 0x75, 0x6f, 0x74, 641 | 0x61, 0x0a, 0x20, 0x38, 0x3a, 0x20, 0x53, 0x65, 0x74, 0x20, 0x66, 0x69, 642 | 0x6c, 0x65, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x69, 0x6f, 0x6e, 643 | 0x73, 0x3a, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x31, 0x3d, 0x66, 0x69, 644 | 0x6c, 0x65, 0x49, 0x44, 0x2c, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x32, 645 | 0x3d, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x0a, 0x20, 0x39, 0x3a, 0x20, 0x55, 646 | 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x6f, 647 | 0x77, 0x6e, 0x65, 0x72, 0x3a, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x31, 648 | 0x3d, 0x66, 0x69, 0x6c, 0x65, 0x49, 0x44, 0x2c, 0x20, 0x70, 0x61, 0x72, 649 | 0x61, 0x6d, 0x32, 0x3d, 0x75, 0x73, 0x65, 0x72, 0x49, 0x44, 0x0a, 0x20, 650 | 0x31, 0x30, 0x3a, 0x20, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x66, 651 | 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x20, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x3a, 652 | 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x31, 0x3d, 0x66, 0x69, 0x6c, 0x65, 653 | 0x49, 0x44, 0x2c, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x32, 0x3d, 0x75, 654 | 0x73, 0x65, 0x72, 0x49, 0x44, 0x0a, 0x20, 0x31, 0x31, 0x3a, 0x20, 0x52, 655 | 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x20, 0x6e, 0x69, 0x63, 0x6b, 656 | 0x6e, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x31, 657 | 0x3d, 0x75, 0x73, 0x65, 0x72, 0x49, 0x44, 0x2c, 0x20, 0x70, 0x61, 0x72, 658 | 0x61, 0x6d, 0x32, 0x3d, 0x6e, 0x69, 0x63, 0x6b, 0x6e, 0x61, 0x6d, 0x65, 659 | 0x0a, 0x20, 0x31, 0x32, 0x3a, 0x20, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 660 | 0x20, 0x6e, 0x69, 0x63, 0x6b, 0x6e, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x70, 661 | 0x61, 0x72, 0x61, 0x6d, 0x31, 0x3d, 0x6e, 0x69, 0x63, 0x6b, 0x6e, 0x61, 662 | 0x6d, 0x65, 0x0a, 0x20, 0x31, 0x33, 0x3a, 0x20, 0x2e, 0x2e, 0x2e, 0x2e, 663 | 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x69, 664 | 0x6e, 0x75, 0x65, 0x64, 0x0a, 0x20, 0x2a, 0x2f, 0x0a, 0x20, 0x43, 0x48, 665 | 0x45, 0x43, 0x4b, 0x20, 0x28, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 666 | 0x3d, 0x31, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, 667 | 0x6e, 0x3c, 0x3d, 0x31, 0x32, 0x29, 0x0a, 0x29, 0x3b, 0x0a, 0x0a, 0x2d, 668 | 0x2d, 0x20, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x20, 0x63, 669 | 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x20, 0x72, 0x65, 0x63, 0x6f, 0x6e, 670 | 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 671 | 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x74, 0x6f, 672 | 0x72, 0x61, 0x67, 0x65, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x20, 0x61, 673 | 0x6e, 0x64, 0x0a, 0x2d, 0x2d, 0x20, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 674 | 0x74, 0x20, 0x69, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 675 | 0x75, 0x73, 0x65, 0x72, 0x73, 0x2f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 676 | 0x68, 0x65, 0x72, 0x73, 0x2e, 0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 677 | 0x6c, 0x65, 0x20, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x20, 678 | 0x70, 0x65, 0x72, 0x20, 0x67, 0x72, 0x69, 0x64, 0x0a, 0x2d, 0x2d, 0x20, 679 | 0x61, 0x72, 0x65, 0x20, 0x70, 0x6f, 0x73, 0x73, 0x69, 0x62, 0x6c, 0x65, 680 | 0x2e, 0x0a, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x20, 0x54, 0x41, 0x42, 681 | 0x4c, 0x45, 0x20, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x20, 682 | 0x28, 0x0a, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x20, 0x42, 0x4c, 0x4f, 0x42, 683 | 0x20, 0x50, 0x52, 0x49, 0x4d, 0x41, 0x52, 0x59, 0x20, 0x4b, 0x45, 0x59, 684 | 0x20, 0x52, 0x45, 0x46, 0x45, 0x52, 0x45, 0x4e, 0x43, 0x45, 0x53, 0x20, 685 | 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x28, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 686 | 0x5f, 0x6b, 0x65, 0x79, 0x29, 0x2c, 0x0a, 0x20, 0x67, 0x72, 0x69, 0x64, 687 | 0x20, 0x54, 0x45, 0x58, 0x54, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x4e, 0x55, 688 | 0x4c, 0x4c, 0x20, 0x52, 0x45, 0x46, 0x45, 0x52, 0x45, 0x4e, 0x43, 0x45, 689 | 0x53, 0x20, 0x67, 0x72, 0x69, 0x64, 0x73, 0x28, 0x69, 0x64, 0x29, 0x2c, 690 | 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x49, 691 | 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x20, 0x2d, 0x2d, 0x6c, 0x61, 692 | 0x72, 0x67, 0x65, 0x72, 0x20, 0x6d, 0x65, 0x61, 0x6e, 0x73, 0x20, 0x6d, 693 | 0x6f, 0x72, 0x65, 0x20, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 694 | 0x2c, 0x20, 0x69, 0x6e, 0x20, 0x63, 0x61, 0x73, 0x65, 0x20, 0x6f, 0x66, 695 | 0x20, 0x74, 0x68, 0x65, 0x20, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 696 | 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 697 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x2d, 0x74, 0x6f, 698 | 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x74, 699 | 0x68, 0x61, 0x6e, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x67, 0x72, 0x69, 0x64, 700 | 0x20, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x65, 0x64, 0x2e, 701 | 0x0a, 0x20, 0x67, 0x72, 0x69, 0x64, 0x5f, 0x73, 0x69, 0x67, 0x20, 0x54, 702 | 0x45, 0x58, 0x54, 0x2c, 0x0a, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x73, 703 | 0x69, 0x67, 0x20, 0x54, 0x45, 0x58, 0x54, 0x0a, 0x29, 0x3b, 0x0a, 0x0a, 704 | 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x20, 0x54, 0x41, 0x42, 0x4c, 0x45, 705 | 0x20, 0x67, 0x72, 0x69, 0x64, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x63, 706 | 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x73, 0x20, 0x28, 0x0a, 0x20, 707 | 0x69, 0x64, 0x20, 0x42, 0x4c, 0x4f, 0x42, 0x20, 0x50, 0x52, 0x49, 0x4d, 708 | 0x41, 0x52, 0x59, 0x20, 0x4b, 0x45, 0x59, 0x20, 0x4e, 0x4f, 0x54, 0x20, 709 | 0x4e, 0x55, 0x4c, 0x4c, 0x2c, 0x0a, 0x20, 0x67, 0x72, 0x69, 0x64, 0x20, 710 | 0x54, 0x45, 0x58, 0x54, 0x20, 0x52, 0x45, 0x46, 0x45, 0x52, 0x45, 0x4e, 711 | 0x43, 0x45, 0x53, 0x20, 0x67, 0x72, 0x69, 0x64, 0x73, 0x28, 0x70, 0x75, 712 | 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x29, 0x2c, 0x0a, 0x20, 713 | 0x6e, 0x6f, 0x64, 0x65, 0x20, 0x42, 0x4c, 0x4f, 0x42, 0x20, 0x4e, 0x4f, 714 | 0x54, 0x20, 0x4e, 0x55, 0x4c, 0x4c, 0x20, 0x52, 0x45, 0x46, 0x45, 0x52, 715 | 0x45, 0x4e, 0x43, 0x45, 0x53, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x28, 716 | 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x29, 0x2c, 717 | 0x0a, 0x20, 0x67, 0x72, 0x69, 0x64, 0x5f, 0x73, 0x69, 0x67, 0x20, 0x54, 718 | 0x45, 0x58, 0x54, 0x2c, 0x0a, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x73, 719 | 0x69, 0x67, 0x20, 0x54, 0x45, 0x58, 0x54, 0x2c, 0x0a, 0x20, 0x6d, 0x69, 720 | 0x6e, 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x20, 0x49, 0x4e, 721 | 0x54, 0x45, 0x47, 0x45, 0x52, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x4e, 0x55, 722 | 0x4c, 0x4c, 0x2c, 0x0a, 0x20, 0x6d, 0x69, 0x6e, 0x5f, 0x62, 0x61, 0x6e, 723 | 0x64, 0x77, 0x69, 0x64, 0x74, 0x68, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 724 | 0x45, 0x52, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x4e, 0x55, 0x4c, 0x4c, 0x2c, 725 | 0x0a, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x65, 726 | 0x20, 0x44, 0x41, 0x54, 0x45, 0x20, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 727 | 0x54, 0x20, 0x43, 0x55, 0x52, 0x52, 0x45, 0x4e, 0x54, 0x5f, 0x54, 0x49, 728 | 0x4d, 0x45, 0x53, 0x54, 0x41, 0x4d, 0x50, 0x20, 0x4e, 0x4f, 0x54, 0x20, 729 | 0x4e, 0x55, 0x4c, 0x4c, 0x2c, 0x0a, 0x20, 0x77, 0x6f, 0x72, 0x6b, 0x69, 730 | 0x6e, 0x67, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x49, 0x4e, 0x54, 0x45, 731 | 0x47, 0x45, 0x52, 0x2c, 0x20, 0x2d, 0x2d, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 732 | 0x20, 0x74, 0x68, 0x65, 0x20, 0x67, 0x72, 0x69, 0x64, 0x20, 0x63, 0x61, 733 | 0x6e, 0x20, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x20, 0x74, 0x68, 0x69, 734 | 0x73, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x43, 0x6f, 0x69, 0x6e, 0x20, 0x74, 735 | 0x65, 0x72, 0x6d, 0x73, 0x0a, 0x20, 0x63, 0x6f, 0x69, 0x6e, 0x20, 0x54, 736 | 0x45, 0x58, 0x54, 0x28, 0x34, 0x29, 0x2c, 0x20, 0x2d, 0x2d, 0x20, 0x69, 737 | 0x65, 0x3a, 0x20, 0x42, 0x54, 0x43, 0x0a, 0x20, 0x62, 0x61, 0x6e, 0x64, 738 | 0x77, 0x69, 0x64, 0x74, 0x68, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 739 | 0x73, 0x69, 0x7a, 0x65, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 740 | 0x20, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x20, 0x31, 0x30, 0x30, 741 | 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x2c, 0x0a, 0x20, 0x70, 0x72, 0x69, 742 | 0x63, 0x65, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 743 | 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x20, 0x44, 0x45, 0x46, 744 | 0x41, 0x55, 0x4c, 0x54, 0x20, 0x30, 0x0a, 0x29, 0x3b, 0x0a, 0x0a, 0x43, 745 | 0x52, 0x45, 0x41, 0x54, 0x45, 0x20, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x20, 746 | 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x61, 0x75, 0x64, 0x69, 0x74, 0x73, 0x20, 747 | 0x28, 0x0a, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x20, 0x42, 0x4c, 0x4f, 0x42, 748 | 0x20, 0x52, 0x45, 0x46, 0x45, 0x52, 0x45, 0x4e, 0x43, 0x45, 0x53, 0x20, 749 | 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x28, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 750 | 0x5f, 0x6b, 0x65, 0x79, 0x29, 0x2c, 0x0a, 0x20, 0x61, 0x75, 0x64, 0x69, 751 | 0x74, 0x6f, 0x72, 0x20, 0x42, 0x4c, 0x4f, 0x42, 0x20, 0x4e, 0x4f, 0x54, 752 | 0x20, 0x4e, 0x55, 0x4c, 0x4c, 0x20, 0x52, 0x45, 0x46, 0x45, 0x52, 0x45, 753 | 0x4e, 0x43, 0x45, 0x53, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x28, 0x70, 754 | 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x29, 0x2c, 0x0a, 755 | 0x20, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x20, 0x42, 756 | 0x4c, 0x4f, 0x42, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x4e, 0x55, 0x4c, 0x4c, 757 | 0x2c, 0x20, 0x2d, 0x2d, 0x20, 0x61, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 758 | 0x73, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x0a, 759 | 0x20, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x73, 0x20, 0x49, 0x4e, 0x54, 760 | 0x45, 0x47, 0x45, 0x52, 0x20, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 761 | 0x20, 0x31, 0x2c, 0x20, 0x2d, 0x2d, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 762 | 0x72, 0x20, 0x6f, 0x66, 0x20, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x73, 763 | 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x61, 0x75, 0x64, 0x69, 0x73, 0x20, 764 | 0x69, 0x73, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x62, 0x6c, 765 | 0x65, 0x20, 0x66, 0x6f, 0x72, 0x0a, 0x20, 0x72, 0x65, 0x61, 0x73, 0x6f, 766 | 0x6e, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x20, 0x4e, 0x4f, 767 | 0x54, 0x20, 0x4e, 0x55, 0x4c, 0x4c, 0x2c, 0x0a, 0x20, 0x2f, 0x2a, 0x0a, 768 | 0x20, 0x31, 0x3a, 0x20, 0x50, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x69, 0x6d, 769 | 0x65, 0x6f, 0x75, 0x74, 0x2e, 0x0a, 0x20, 0x32, 0x3a, 0x20, 0x49, 0x6e, 770 | 0x63, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x20, 0x73, 0x69, 0x67, 0x6e, 771 | 0x61, 0x74, 0x75, 0x72, 0x65, 0x2e, 0x0a, 0x20, 0x33, 0x3a, 0x20, 0x49, 772 | 0x6e, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x20, 0x61, 0x75, 0x64, 773 | 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x0a, 0x20, 0x34, 0x3a, 0x20, 0x54, 774 | 0x6f, 0x6f, 0x20, 0x73, 0x6c, 0x6f, 0x77, 0x20, 0x63, 0x6f, 0x6e, 0x6e, 775 | 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x0a, 0x20, 0x35, 0x3a, 0x20, 776 | 0x44, 0x65, 0x6e, 0x69, 0x61, 0x6c, 0x20, 0x6f, 0x66, 0x20, 0x73, 0x65, 777 | 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x0a, 0x20, 0x36, 0x3a, 0x20, 0x43, 778 | 0x6f, 0x72, 0x72, 0x75, 0x70, 0x74, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2e, 779 | 0x0a, 0x20, 0x37, 0x3a, 0x20, 0x2e, 0x2e, 0x2e, 0x20, 0x74, 0x6f, 0x20, 780 | 0x62, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x64, 781 | 0x0a, 0x20, 0x2a, 0x2f, 0x0a, 0x20, 0x43, 0x48, 0x45, 0x43, 0x4b, 0x20, 782 | 0x28, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x3e, 0x3d, 0x31, 0x20, 0x61, 783 | 0x6e, 0x64, 0x20, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x20, 0x3c, 0x3d, 784 | 0x36, 0x29, 0x0a, 0x29, 0x3b, 0x0a, 0x0a, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 785 | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 786 | 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x2d, 0x2d, 0x20, 0x66, 0x69, 0x6c, 0x65, 787 | 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 788 | 0x73, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 789 | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 790 | 0x2d, 0x2d, 0x20, 0x73, 0x79, 0x6e, 0x63, 0x65, 0x64, 0x20, 0x62, 0x65, 791 | 0x74, 0x77, 0x65, 0x65, 0x6e, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 792 | 0x68, 0x65, 0x72, 0x73, 0x2f, 0x67, 0x72, 0x69, 0x64, 0x73, 0x2f, 0x75, 793 | 0x73, 0x65, 0x72, 0x73, 0x20, 0x62, 0x75, 0x74, 0x20, 0x6e, 0x6f, 0x74, 794 | 0x20, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x6c, 0x79, 0x2e, 0x0a, 0x0a, 795 | 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x20, 0x54, 0x41, 0x42, 0x4c, 0x45, 796 | 0x20, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x73, 0x20, 0x28, 0x0a, 0x20, 797 | 0x69, 0x64, 0x20, 0x42, 0x4c, 0x4f, 0x42, 0x20, 0x4e, 0x4f, 0x54, 0x20, 798 | 0x4e, 0x55, 0x4c, 0x4c, 0x20, 0x50, 0x52, 0x49, 0x4d, 0x41, 0x52, 0x59, 799 | 0x20, 0x4b, 0x45, 0x59, 0x2c, 0x0a, 0x20, 0x70, 0x61, 0x72, 0x65, 0x6e, 800 | 0x74, 0x20, 0x42, 0x4c, 0x4f, 0x42, 0x20, 0x52, 0x45, 0x46, 0x45, 0x52, 801 | 0x45, 0x4e, 0x43, 0x45, 0x53, 0x20, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 802 | 0x73, 0x28, 0x69, 0x64, 0x29, 0x2c, 0x0a, 0x20, 0x6e, 0x61, 0x6d, 0x65, 803 | 0x20, 0x54, 0x45, 0x58, 0x54, 0x2c, 0x0a, 0x20, 0x70, 0x65, 0x72, 0x6d, 804 | 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x42, 0x4c, 0x4f, 0x42, 0x20, 805 | 0x52, 0x45, 0x46, 0x45, 0x52, 0x45, 0x4e, 0x43, 0x45, 0x53, 0x20, 0x70, 806 | 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x28, 0x69, 807 | 0x64, 0x29, 0x0a, 0x29, 0x3b, 0x0a, 0x0a, 0x43, 0x52, 0x45, 0x41, 0x54, 808 | 0x45, 0x20, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x20, 0x66, 0x69, 0x6c, 0x65, 809 | 0x73, 0x20, 0x28, 0x0a, 0x20, 0x68, 0x61, 0x73, 0x68, 0x20, 0x54, 0x45, 810 | 0x58, 0x54, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x4e, 0x55, 0x4c, 0x4c, 0x20, 811 | 0x50, 0x52, 0x49, 0x4d, 0x41, 0x52, 0x59, 0x20, 0x4b, 0x45, 0x59, 0x2c, 812 | 0x0a, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x54, 0x45, 0x58, 0x54, 0x2c, 813 | 0x0a, 0x20, 0x6d, 0x69, 0x6d, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x20, 814 | 0x54, 0x45, 0x58, 0x54, 0x2c, 0x0a, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 815 | 0x6e, 0x74, 0x20, 0x42, 0x4c, 0x4f, 0x42, 0x2c, 0x0a, 0x20, 0x72, 0x61, 816 | 0x74, 0x65, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x20, 0x44, 817 | 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x20, 0x30, 0x2c, 0x20, 0x2d, 0x2d, 818 | 0x62, 0x61, 0x6e, 0x64, 0x77, 0x69, 0x64, 0x74, 0x68, 0x20, 0x72, 0x61, 819 | 0x74, 0x65, 0x20, 0x61, 0x74, 0x20, 0x77, 0x68, 0x61, 0x74, 0x20, 0x6d, 820 | 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x73, 0x74, 0x72, 0x65, 0x61, 821 | 0x6d, 0x65, 0x64, 0x0a, 0x20, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x20, 822 | 0x42, 0x4c, 0x4f, 0x42, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x4e, 0x55, 0x4c, 823 | 0x4c, 0x20, 0x52, 0x45, 0x46, 0x45, 0x52, 0x45, 0x4e, 0x43, 0x45, 0x53, 824 | 0x20, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x73, 0x28, 0x69, 0x64, 0x29, 825 | 0x2c, 0x0a, 0x20, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x67, 0x20, 826 | 0x54, 0x45, 0x58, 0x54, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x4e, 0x55, 0x4c, 827 | 0x4c, 0x2c, 0x0a, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 828 | 0x6f, 0x6e, 0x73, 0x20, 0x42, 0x4c, 0x4f, 0x42, 0x20, 0x52, 0x45, 0x46, 829 | 0x45, 0x52, 0x45, 0x4e, 0x43, 0x45, 0x53, 0x20, 0x70, 0x65, 0x72, 0x6d, 830 | 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x28, 0x69, 0x64, 0x29, 0x0a, 831 | 0x29, 0x3b, 0x0a, 0x0a, 0x0a, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x20, 832 | 0x54, 0x41, 0x42, 0x4c, 0x45, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 833 | 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x28, 0x0a, 0x20, 0x69, 0x64, 0x20, 834 | 0x42, 0x4c, 0x4f, 0x42, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x4e, 0x55, 0x4c, 835 | 0x4c, 0x20, 0x50, 0x52, 0x49, 0x4d, 0x41, 0x52, 0x59, 0x20, 0x4b, 0x45, 836 | 0x59, 0x2c, 0x0a, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x42, 0x4c, 0x4f, 837 | 0x42, 0x20, 0x52, 0x45, 0x46, 0x45, 0x52, 0x45, 0x4e, 0x43, 0x45, 0x53, 838 | 0x20, 0x75, 0x73, 0x65, 0x72, 0x73, 0x28, 0x70, 0x75, 0x62, 0x6c, 0x69, 839 | 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x29, 0x2c, 0x0a, 0x20, 0x70, 0x75, 0x62, 840 | 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x20, 0x42, 0x4c, 0x4f, 0x42, 0x20, 841 | 0x52, 0x45, 0x46, 0x45, 0x52, 0x45, 0x4e, 0x43, 0x45, 0x53, 0x20, 0x70, 842 | 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x28, 0x70, 0x75, 843 | 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x29, 0x2c, 0x0a, 0x20, 844 | 0x2d, 0x2d, 0x20, 0x4e, 0x55, 0x4c, 0x4c, 0x20, 0x75, 0x73, 0x65, 0x72, 845 | 0x2f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x20, 0x6d, 846 | 0x65, 0x61, 0x6e, 0x73, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 847 | 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x65, 0x76, 0x65, 848 | 0x72, 0x79, 0x6f, 0x6e, 0x65, 0x0a, 0x20, 0x72, 0x65, 0x61, 0x64, 0x20, 849 | 0x42, 0x4f, 0x4f, 0x4c, 0x45, 0x41, 0x4e, 0x2c, 0x0a, 0x20, 0x72, 0x65, 850 | 0x61, 0x64, 0x5f, 0x71, 0x75, 0x6f, 0x74, 0x61, 0x20, 0x49, 0x4e, 0x54, 851 | 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, 852 | 0x20, 0x42, 0x4f, 0x4f, 0x4c, 0x45, 0x41, 0x4e, 0x2c, 0x0a, 0x20, 0x77, 853 | 0x72, 0x69, 0x74, 0x65, 0x5f, 0x71, 0x75, 0x6f, 0x74, 0x61, 0x20, 0x49, 854 | 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x2c, 0x0a, 0x20, 0x63, 0x72, 0x65, 855 | 0x61, 0x74, 0x65, 0x5f, 0x6e, 0x65, 0x77, 0x20, 0x42, 0x4f, 0x4f, 0x4c, 856 | 0x45, 0x41, 0x4e, 0x2c, 0x0a, 0x20, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 857 | 0x20, 0x42, 0x4f, 0x4f, 0x4c, 0x45, 0x41, 0x4e, 0x2c, 0x0a, 0x20, 0x73, 858 | 0x65, 0x74, 0x5f, 0x70, 0x65, 0x72, 0x6d, 0x20, 0x42, 0x4f, 0x4f, 0x4c, 859 | 0x45, 0x41, 0x4e, 0x20, 0x2d, 0x2d, 0x20, 0x4d, 0x65, 0x61, 0x6e, 0x69, 860 | 0x6e, 0x67, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x6f, 0x6e, 0x65, 0x20, 0x63, 861 | 0x61, 0x6e, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x70, 0x65, 0x72, 0x6d, 862 | 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x73, 863 | 0x65, 0x74, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 864 | 0x6e, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x55, 0x49, 0x20, 0x74, 0x65, 0x72, 865 | 0x6d, 0x0a, 0x29, 0x3b, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x2d, 0x2d, 0x2d, 866 | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 867 | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x2d, 0x2d, 0x20, 0x70, 0x72, 0x69, 868 | 0x76, 0x61, 0x74, 0x65, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x20, 869 | 0x2d, 0x2d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 870 | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 871 | 0x0a, 0x2d, 0x2d, 0x20, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x20, 0x6e, 872 | 0x6f, 0x74, 0x20, 0x73, 0x79, 0x6e, 0x63, 0x65, 0x64, 0x2e, 0x20, 0x4d, 873 | 0x6f, 0x73, 0x74, 0x6c, 0x79, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 874 | 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 875 | 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x6f, 0x6e, 876 | 0x76, 0x65, 0x6e, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x74, 0x61, 0x62, 0x6c, 877 | 0x65, 0x73, 0x2e, 0x0a, 0x0a, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x20, 878 | 0x54, 0x41, 0x42, 0x4c, 0x45, 0x20, 0x43, 0x41, 0x73, 0x20, 0x28, 0x0a, 879 | 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x20, 880 | 0x42, 0x4c, 0x4f, 0x42, 0x20, 0x50, 0x52, 0x49, 0x4d, 0x41, 0x52, 0x59, 881 | 0x20, 0x4b, 0x45, 0x59, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x4e, 0x55, 0x4c, 882 | 0x4c, 0x2c, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 883 | 0x6b, 0x65, 0x79, 0x20, 0x42, 0x4c, 0x4f, 0x42, 0x20, 0x4e, 0x4f, 0x54, 884 | 0x20, 0x4e, 0x55, 0x4c, 0x4c, 0x2c, 0x0a, 0x20, 0x70, 0x72, 0x6f, 0x6f, 885 | 0x66, 0x5f, 0x6f, 0x66, 0x5f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 886 | 0x69, 0x6f, 0x6e, 0x20, 0x42, 0x4c, 0x4f, 0x42, 0x2c, 0x0a, 0x20, 0x73, 887 | 0x73, 0x6c, 0x5f, 0x65, 0x78, 0x74, 0x72, 0x61, 0x20, 0x54, 0x45, 0x58, 888 | 0x54, 0x0a, 0x29, 0x3b, 0x0a, 0x0a, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 889 | 0x20, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x20, 0x63, 0x6f, 0x6e, 0x66, 0x69, 890 | 0x67, 0x73, 0x20, 0x28, 0x0a, 0x20, 0x76, 0x61, 0x72, 0x20, 0x42, 0x4c, 891 | 0x4f, 0x42, 0x20, 0x50, 0x52, 0x49, 0x4d, 0x41, 0x52, 0x59, 0x20, 0x4b, 892 | 0x45, 0x59, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x4e, 0x55, 0x4c, 0x4c, 0x2c, 893 | 0x0a, 0x20, 0x76, 0x61, 0x6c, 0x20, 0x42, 0x4c, 0x4f, 0x42, 0x20, 0x4e, 894 | 0x4f, 0x54, 0x20, 0x4e, 0x55, 0x4c, 0x4c, 0x0a, 0x29, 0x3b, 0x0a, 0x0a, 895 | 0x2d, 0x2d, 0x20, 0x6c, 0x6f, 0x67, 0x73, 0x20, 0x2d, 0x2d, 0x0a, 0x2d, 896 | 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x43, 897 | 0x52, 0x45, 0x41, 0x54, 0x45, 0x20, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x20, 898 | 0x6c, 0x6f, 0x67, 0x73, 0x20, 0x28, 0x0a, 0x20, 0x6e, 0x75, 0x6d, 0x20, 899 | 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x20, 0x50, 0x52, 0x49, 900 | 0x4d, 0x41, 0x52, 0x59, 0x20, 0x4b, 0x45, 0x59, 0x20, 0x41, 0x55, 0x54, 901 | 0x4f, 0x49, 0x4e, 0x43, 0x52, 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x4e, 902 | 0x4f, 0x54, 0x20, 0x4e, 0x55, 0x4c, 0x4c, 0x2c, 0x0a, 0x20, 0x65, 0x72, 903 | 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x49, 0x4e, 0x54, 904 | 0x45, 0x47, 0x45, 0x52, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x4e, 0x55, 0x4c, 905 | 0x4c, 0x2c, 0x0a, 0x20, 0x6c, 0x6f, 0x67, 0x20, 0x54, 0x45, 0x58, 0x54, 906 | 0x2c, 0x0a, 0x20, 0x74, 0x73, 0x20, 0x54, 0x49, 0x4d, 0x45, 0x53, 0x54, 907 | 0x41, 0x4d, 0x50, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x4e, 0x55, 0x4c, 0x4c, 908 | 0x20, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x20, 0x43, 0x55, 0x52, 909 | 0x52, 0x45, 0x4e, 0x54, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x53, 0x54, 0x41, 910 | 0x4d, 0x50, 0x0a, 0x29, 0x3b, 0x0a, 0x0a, 0x0a, 0x2f, 0x2a, 0x0a, 0x0a, 911 | 0x20, 0x45, 0x76, 0x65, 0x72, 0x79, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 912 | 0x2c, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x69, 0x6e, 0x67, 0x20, 913 | 0x64, 0x65, 0x72, 0x69, 0x76, 0x69, 0x6e, 0x67, 0x20, 0x44, 0x41, 0x73, 914 | 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x2c, 0x20, 0x6e, 0x65, 0x65, 915 | 0x64, 0x20, 0x74, 0x6f, 0x20, 0x6d, 0x65, 0x65, 0x74, 0x20, 0x63, 0x65, 916 | 0x72, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x2e, 917 | 0x20, 0x54, 0x68, 0x69, 0x73, 0x0a, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 918 | 0x20, 0x69, 0x73, 0x20, 0x6a, 0x75, 0x73, 0x74, 0x20, 0x61, 0x20, 0x63, 919 | 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 920 | 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x6e, 0x65, 0x76, 0x65, 0x72, 921 | 0x20, 0x73, 0x79, 0x6e, 0x63, 0x65, 0x64, 0x2e, 0x20, 0x49, 0x74, 0x20, 922 | 0x69, 0x73, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x61, 923 | 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x0a, 0x20, 924 | 0x6f, 0x66, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x20, 0x63, 0x72, 0x65, 0x61, 925 | 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x75, 0x70, 0x64, 926 | 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x74, 0x68, 927 | 0x65, 0x20, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x69, 928 | 0x73, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 929 | 0x20, 0x57, 0x68, 0x65, 0x6e, 0x20, 0x61, 0x20, 0x44, 0x61, 0x70, 0x70, 930 | 0x20, 0x69, 0x73, 0x20, 0x61, 0x64, 0x64, 0x64, 0x65, 0x64, 0x20, 0x74, 931 | 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x2c, 0x20, 932 | 0x74, 0x68, 0x69, 0x73, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x69, 933 | 0x73, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 934 | 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x66, 0x6f, 0x72, 935 | 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x6f, 0x66, 0x20, 0x74, 936 | 0x68, 0x65, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 937 | 0x73, 0x2e, 0x0a, 0x0a, 0x2a, 0x2f, 0x0a, 0x0a, 0x43, 0x52, 0x45, 0x41, 938 | 0x54, 0x45, 0x20, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x20, 0x74, 0x61, 0x62, 939 | 0x6c, 0x65, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x20, 0x28, 0x0a, 0x20, 940 | 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x20, 0x49, 0x4e, 0x54, 941 | 0x45, 0x47, 0x45, 0x52, 0x20, 0x50, 0x52, 0x49, 0x4d, 0x41, 0x52, 0x59, 942 | 0x20, 0x4b, 0x45, 0x59, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x4e, 0x55, 0x4c, 943 | 0x4c, 0x2c, 0x20, 0x2d, 0x2d, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 944 | 0x65, 0x20, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x20, 0x61, 0x6e, 0x64, 945 | 0x20, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x20, 0x62, 0x79, 946 | 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 947 | 0x6f, 0x72, 0x79, 0x0a, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 948 | 0x61, 0x6d, 0x65, 0x20, 0x54, 0x45, 0x58, 0x54, 0x20, 0x4e, 0x4f, 0x54, 949 | 0x20, 0x4e, 0x55, 0x4c, 0x4c, 0x2c, 0x0a, 0x20, 0x64, 0x61, 0x70, 0x70, 950 | 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x20, 0x52, 0x45, 0x46, 951 | 0x45, 0x52, 0x45, 0x4e, 0x43, 0x45, 0x53, 0x20, 0x44, 0x41, 0x70, 0x70, 952 | 0x73, 0x28, 0x69, 0x64, 0x29, 0x2c, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 953 | 0x65, 0x78, 0x70, 0x6f, 0x73, 0x75, 0x72, 0x65, 0x20, 0x6f, 0x66, 0x20, 954 | 0x74, 0x68, 0x65, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x69, 0x6e, 955 | 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x70, 0x6f, 0x6f, 956 | 0x6c, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x30, 0x3d, 0x70, 0x72, 0x69, 0x76, 957 | 0x61, 0x74, 0x65, 0x3b, 0x20, 0x20, 0x31, 0x3d, 0x67, 0x72, 0x69, 0x64, 958 | 0x3b, 0x20, 0x20, 0x32, 0x3d, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 959 | 0x70, 0x61, 0x6e, 0x74, 0x73, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x3b, 0x20, 960 | 0x33, 0x3d, 0x66, 0x75, 0x6c, 0x6c, 0x20, 0x67, 0x6c, 0x6f, 0x62, 0x61, 961 | 0x6c, 0x20, 0x28, 0x63, 0x61, 0x72, 0x65, 0x66, 0x75, 0x6c, 0x29, 0x3b, 962 | 0x0a, 0x20, 0x65, 0x78, 0x70, 0x6f, 0x73, 0x75, 0x72, 0x65, 0x20, 0x49, 963 | 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x20, 0x44, 0x45, 0x46, 0x41, 0x55, 964 | 0x4c, 0x54, 0x20, 0x30, 0x2c, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x70, 965 | 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x20, 966 | 0x28, 0x4f, 0x52, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, 0x29, 967 | 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x31, 0x3d, 0x6e, 0x6f, 0x64, 0x65, 0x3b, 968 | 0x20, 0x32, 0x3d, 0x67, 0x72, 0x69, 0x64, 0x20, 0x6f, 0x77, 0x6e, 0x65, 969 | 0x72, 0x3b, 0x20, 0x34, 0x3d, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 970 | 0x73, 0x3b, 0x20, 0x38, 0x3d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 971 | 0x65, 0x72, 0x73, 0x3b, 0x20, 0x31, 0x36, 0x3d, 0x75, 0x73, 0x65, 0x72, 972 | 0x73, 0x0a, 0x20, 0x70, 0x61, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 973 | 0x74, 0x73, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x20, 0x44, 974 | 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x20, 0x30, 0x2c, 0x0a, 0x0a, 0x20, 975 | 0x2d, 0x2d, 0x20, 0x68, 0x6f, 0x77, 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 976 | 0x69, 0x73, 0x20, 0x73, 0x79, 0x6e, 0x63, 0x65, 0x64, 0x3f, 0x0a, 0x20, 977 | 0x2d, 0x2d, 0x20, 0x30, 0x3d, 0x6e, 0x6f, 0x73, 0x79, 0x6e, 0x63, 0x2c, 978 | 0x20, 0x31, 0x3d, 0x70, 0x72, 0x6f, 0x78, 0x69, 0x6d, 0x69, 0x74, 0x79, 979 | 0x2c, 0x20, 0x32, 0x3d, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x2c, 0x20, 980 | 0x33, 0x3d, 0x6d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x2c, 0x20, 0x34, 0x3d, 981 | 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x0a, 0x20, 0x73, 0x79, 0x6e, 0x63, 0x5f, 982 | 0x74, 0x79, 0x70, 0x65, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 983 | 0x20, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x20, 0x30, 0x2c, 0x0a, 984 | 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x5f, 0x74, 0x6f, 0x5f, 0x73, 0x79, 985 | 0x6e, 0x63, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x20, 0x44, 986 | 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x20, 0x31, 0x36, 0x2c, 0x0a, 0x20, 987 | 0x70, 0x72, 0x6f, 0x78, 0x69, 0x6d, 0x69, 0x74, 0x79, 0x5f, 0x6e, 0x6f, 988 | 0x64, 0x65, 0x73, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x20, 989 | 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x20, 0x31, 0x32, 0x2c, 0x0a, 990 | 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x68, 0x6f, 0x77, 0x20, 0x6f, 0x66, 0x66, 991 | 0x74, 0x65, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 992 | 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x63, 0x79, 993 | 0x3f, 0x20, 0x28, 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x64, 994 | 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x74, 0x68, 0x61, 995 | 0x6e, 0x20, 0x61, 0x63, 0x74, 0x75, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x73, 996 | 0x79, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x29, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 997 | 0x69, 0x6e, 0x20, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x2c, 0x20, 998 | 0x30, 0x3d, 0x6e, 0x6f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x0a, 0x20, 0x63, 999 | 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x65, 0x76, 0x65, 0x72, 0x79, 0x20, 0x49, 1000 | 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x20, 0x44, 0x45, 0x46, 0x41, 0x55, 1001 | 0x4c, 0x54, 0x20, 0x36, 0x30, 0x30, 0x2c, 0x0a, 0x0a, 0x0a, 0x0a, 0x20, 1002 | 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x66, 0x75, 0x6e, 1003 | 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 1004 | 0x69, 0x73, 0x20, 0x61, 0x20, 0x43, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 1005 | 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x63, 0x68, 0x65, 1006 | 0x63, 0x6b, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x73, 1007 | 0x69, 0x73, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, 1008 | 0x68, 0x65, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x6c, 0x61, 0x73, 0x74, 0x20, 1009 | 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x61, 0x63, 0x72, 0x6f, 0x73, 0x73, 1010 | 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x20, 0x61, 1011 | 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x28, 0x66, 0x72, 0x6f, 1012 | 0x6d, 0x20, 0x65, 0x78, 0x70, 0x6f, 0x73, 0x75, 0x72, 0x65, 0x29, 0x2e, 1013 | 0x0a, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x66, 0x75, 0x6e, 0x63, 1014 | 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x54, 0x45, 0x58, 0x54, 0x20, 0x44, 0x45, 1015 | 0x46, 0x41, 0x55, 0x4c, 0x54, 0x20, 0x22, 0x62, 0x63, 0x5f, 0x63, 0x68, 1016 | 0x65, 0x63, 0x6b, 0x22, 0x2c, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x73, 1017 | 0x79, 0x6e, 0x63, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 1018 | 0x73, 0x3a, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x43, 0x20, 0x66, 0x75, 1019 | 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x74, 0x61, 0x6b, 0x65, 1020 | 0x20, 0x61, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x6e, 0x64, 1021 | 0x20, 0x61, 0x20, 0x72, 0x6f, 0x77, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 1022 | 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x61, 0x6e, 0x64, 1023 | 0x20, 0x74, 0x72, 0x79, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x74, 0x6f, 0x20, 1024 | 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 1025 | 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x44, 0x42, 0x20, 0x69, 0x66, 0x20, 0x74, 1026 | 0x65, 0x73, 0x74, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x70, 0x61, 0x73, 1027 | 0x73, 0x65, 0x64, 0x3a, 0x0a, 0x20, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 1028 | 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x54, 0x45, 1029 | 0x58, 0x54, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x22, 1030 | 0x62, 0x63, 0x5f, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x22, 0x2c, 0x0a, 1031 | 0x20, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x66, 0x75, 0x6e, 0x63, 1032 | 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x54, 0x45, 0x58, 0x54, 0x20, 0x64, 0x65, 1033 | 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x22, 0x62, 0x63, 0x5f, 0x64, 0x65, 1034 | 0x6c, 0x65, 0x74, 0x65, 0x22, 0x2c, 0x0a, 0x20, 0x75, 0x70, 0x64, 0x61, 1035 | 0x74, 0x65, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 1036 | 0x54, 0x45, 0x58, 0x54, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 1037 | 0x20, 0x22, 0x62, 0x63, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x22, 1038 | 0x2c, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x6d, 0x61, 0x78, 0x69, 0x6d, 1039 | 0x75, 0x6d, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x20, 0x6e, 1040 | 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x72, 0x61, 1041 | 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x70, 0x65, 1042 | 0x72, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x70, 0x65, 0x72, 0x69, 1043 | 0x6f, 0x64, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 1044 | 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x3a, 0x0a, 0x20, 0x6d, 0x61, 0x78, 1045 | 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 1046 | 0x73, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x20, 0x44, 0x45, 1047 | 0x46, 0x41, 0x55, 0x4c, 0x54, 0x20, 0x31, 0x2c, 0x0a, 0x20, 0x2d, 0x2d, 1048 | 0x20, 0x69, 0x66, 0x20, 0x6d, 0x61, 0x78, 0x20, 0x6e, 0x75, 0x6d, 0x62, 1049 | 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 1050 | 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 1051 | 0x65, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 1052 | 0x70, 0x65, 0x72, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 1053 | 0x61, 0x6e, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x76, 0x6f, 0x69, 0x64, 1054 | 0x20, 0x65, 0x78, 0x63, 0x65, 0x73, 0x73, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 1055 | 0x6f, 0x66, 0x20, 0x66, 0x6c, 0x6f, 0x6f, 0x64, 0x20, 0x6f, 0x72, 0x20, 1056 | 0x44, 0x44, 0x4f, 0x53, 0x20, 0x61, 0x74, 0x74, 0x61, 0x63, 0x6b, 0x73, 1057 | 0x3a, 0x0a, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x66, 0x6c, 0x6f, 1058 | 0x6f, 0x64, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 1059 | 0x54, 0x45, 0x58, 0x54, 0x20, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 1060 | 0x20, 0x22, 0x62, 0x63, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x66, 1061 | 0x6c, 0x6f, 0x6f, 0x64, 0x22, 0x0a, 0x0a, 0x29, 0x3b, 0x0a, 0x0a, 0x0a, 1062 | 0x2d, 0x2d, 0x20, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x66, 0x6f, 0x72, 1063 | 0x20, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x69, 0x6e, 0x67, 1064 | 0x20, 0x44, 0x41, 0x70, 0x70, 0x73, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 1065 | 0x20, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x65, 1066 | 0x73, 0x0a, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x20, 0x54, 0x41, 0x42, 1067 | 0x4c, 0x45, 0x20, 0x44, 0x41, 0x70, 0x70, 0x73, 0x20, 0x28, 0x0a, 0x20, 1068 | 0x69, 0x64, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x20, 0x4e, 1069 | 0x4f, 0x54, 0x20, 0x4e, 0x55, 0x4c, 0x4c, 0x20, 0x50, 0x52, 0x49, 0x4d, 1070 | 0x41, 0x52, 0x59, 0x20, 0x4b, 0x45, 0x59, 0x2c, 0x20, 0x2d, 0x2d, 0x20, 1071 | 0x74, 0x68, 0x65, 0x20, 0x49, 0x44, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 1072 | 0x62, 0x65, 0x20, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x20, 0x61, 0x6e, 1073 | 0x64, 0x20, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x20, 0x62, 1074 | 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 1075 | 0x74, 0x6f, 0x72, 0x79, 0x0a, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x54, 1076 | 0x45, 0x58, 0x54, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x4e, 0x55, 0x4c, 0x4c, 1077 | 0x20, 0x55, 0x4e, 0x49, 0x51, 0x55, 0x45, 0x2c, 0x0a, 0x20, 0x64, 0x65, 1078 | 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x54, 0x45, 1079 | 0x58, 0x54, 0x2c, 0x0a, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x20, 1080 | 0x54, 0x45, 0x58, 0x54, 0x2c, 0x0a, 0x20, 0x6c, 0x69, 0x63, 0x65, 0x6e, 1081 | 0x73, 0x65, 0x20, 0x54, 0x45, 0x58, 0x54, 0x2c, 0x0a, 0x20, 0x76, 0x65, 1082 | 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x46, 0x4c, 0x4f, 0x41, 0x54, 0x20, 1083 | 0x4e, 0x4f, 0x54, 0x20, 0x4e, 0x55, 0x4c, 0x4c, 0x2c, 0x20, 0x2d, 0x2d, 1084 | 0x20, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x3a, 0x20, 0x30, 0x2e, 1085 | 0x39, 0x36, 0x0a, 0x0a, 0x20, 0x69, 0x73, 0x5f, 0x73, 0x74, 0x61, 0x74, 1086 | 0x69, 0x63, 0x20, 0x42, 0x4f, 0x4f, 0x4c, 0x45, 0x41, 0x4e, 0x20, 0x44, 1087 | 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x20, 0x30, 0x2c, 0x20, 0x2d, 0x2d, 1088 | 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x64, 0x20, 0x73, 0x74, 1089 | 0x61, 0x74, 0x69, 0x63, 0x20, 0x6f, 0x72, 0x20, 0x64, 0x79, 0x6e, 0x61, 1090 | 0x6d, 0x69, 0x63, 0x2e, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x54, 0x68, 1091 | 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x61, 1092 | 0x6d, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x69, 1093 | 0x62, 0x72, 0x61, 0x72, 0x79, 0x20, 0x28, 0x2e, 0x73, 0x6f, 0x20, 0x6f, 1094 | 0x72, 0x20, 0x2e, 0x64, 0x6c, 0x6c, 0x29, 0x20, 0x66, 0x69, 0x6c, 0x65, 1095 | 0x20, 0x74, 0x6f, 0x20, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 1096 | 0x2e, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x0a, 1097 | 0x20, 0x2d, 0x2d, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x63, 0x6f, 0x6e, 1098 | 0x74, 0x61, 0x69, 0x6e, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x20, 0x6f, 0x72, 1099 | 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x6e, 1100 | 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 1101 | 0x65, 0x20, 0x22, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x72, 0x75, 0x6c, 1102 | 0x65, 0x73, 0x22, 0x2e, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x66, 0x69, 1103 | 0x6c, 0x65, 0x20, 0x69, 0x73, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x6c, 0x6f, 1104 | 0x63, 0x61, 0x74, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 1105 | 0x20, 0x22, 0x64, 0x61, 0x70, 0x70, 0x22, 0x20, 0x64, 0x69, 0x72, 0x65, 1106 | 0x63, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x0a, 0x20, 0x64, 0x61, 0x70, 0x70, 1107 | 0x5f, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x20, 0x54, 0x45, 0x58, 1108 | 0x54, 0x2c, 0x0a, 0x0a, 0x20, 0x72, 0x75, 0x6e, 0x20, 0x42, 0x4f, 0x4f, 1109 | 0x4c, 0x45, 0x41, 0x4e, 0x20, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 1110 | 0x20, 0x30, 0x2c, 0x20, 0x2d, 0x2d, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 1111 | 0x69, 0x73, 0x20, 0x44, 0x41, 0x70, 0x70, 0x20, 0x74, 0x6f, 0x20, 0x62, 1112 | 0x65, 0x20, 0x72, 0x75, 0x6e, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x63, 1113 | 0x61, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x62, 0x63, 0x5f, 0x72, 0x75, 1114 | 0x6e, 0x5f, 0x61, 0x6c, 0x6c, 0x5f, 0x61, 0x70, 0x70, 0x73, 0x28, 0x29, 1115 | 0x3f, 0x0a, 0x20, 0x69, 0x73, 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 1116 | 0x61, 0x64, 0x65, 0x64, 0x20, 0x42, 0x4f, 0x4f, 0x4c, 0x45, 0x41, 0x4e, 1117 | 0x20, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x20, 0x30, 0x2c, 0x20, 1118 | 0x2d, 0x2d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x73, 1119 | 0x20, 0x61, 0x72, 0x65, 0x20, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 1120 | 0x64, 0x65, 0x64, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x54, 0x68, 0x65, 1121 | 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 1122 | 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 1123 | 0x72, 0x65, 0x2c, 0x20, 0x77, 0x69, 0x74, 0x68, 0x6f, 0x75, 0x74, 0x20, 1124 | 0x74, 0x68, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x70, 0x70, 1125 | 0x20, 0x69, 0x73, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, 1126 | 0x65, 0x64, 0x20, 0x6d, 0x61, 0x6c, 0x69, 0x63, 0x69, 0x6f, 0x75, 0x73, 1127 | 0x0a, 0x20, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 1128 | 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x20, 0x52, 0x45, 0x46, 1129 | 0x45, 0x52, 0x45, 0x4e, 0x43, 0x45, 0x53, 0x20, 0x72, 0x65, 0x70, 0x6f, 1130 | 0x73, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x28, 0x69, 0x64, 0x29, 1131 | 0x2c, 0x0a, 0x20, 0x72, 0x65, 0x70, 0x5f, 0x73, 0x69, 0x67, 0x20, 0x42, 1132 | 0x4c, 0x4f, 0x42, 0x0a, 0x29, 0x3b, 0x0a, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 1133 | 0x44, 0x41, 0x70, 0x70, 0x73, 0x20, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 1134 | 0x65, 0x6e, 0x63, 0x65, 0x73, 0x2e, 0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, 1135 | 0x70, 0x6c, 0x65, 0x20, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 1136 | 0x63, 0x65, 0x73, 0x20, 0x70, 0x65, 0x72, 0x20, 0x44, 0x41, 0x70, 0x70, 1137 | 0x20, 0x61, 0x72, 0x65, 0x20, 0x70, 0x6f, 0x73, 0x73, 0x69, 0x62, 0x6c, 1138 | 0x65, 0x0a, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x20, 0x54, 0x41, 0x42, 1139 | 0x4c, 0x45, 0x20, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 1140 | 0x65, 0x73, 0x20, 0x28, 0x0a, 0x20, 0x64, 0x61, 0x70, 0x70, 0x20, 0x49, 1141 | 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x20, 0x52, 0x45, 0x46, 0x45, 0x52, 1142 | 0x45, 0x4e, 0x43, 0x45, 0x53, 0x20, 0x44, 0x41, 0x70, 0x70, 0x73, 0x28, 1143 | 0x69, 0x64, 0x29, 0x2c, 0x0a, 0x20, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 1144 | 0x65, 0x6e, 0x63, 0x79, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 1145 | 0x20, 0x52, 0x45, 0x46, 0x45, 0x52, 0x45, 0x4e, 0x43, 0x45, 0x53, 0x20, 1146 | 0x44, 0x41, 0x70, 0x70, 0x73, 0x28, 0x69, 0x64, 0x29, 0x2c, 0x20, 0x2d, 1147 | 0x2d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x44, 0x41, 0x70, 0x70, 0x20, 0x69, 1148 | 0x6e, 0x20, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x79, 1149 | 0x0a, 0x20, 0x6d, 0x69, 0x6e, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 1150 | 0x6e, 0x20, 0x46, 0x4c, 0x4f, 0x41, 0x54, 0x20, 0x44, 0x45, 0x46, 0x41, 1151 | 0x55, 0x4c, 0x54, 0x20, 0x30, 0x2c, 0x20, 0x2d, 0x2d, 0x20, 0x74, 0x68, 1152 | 0x65, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x20, 0x6d, 1153 | 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 1154 | 0x6f, 0x6e, 0x0a, 0x20, 0x6d, 0x61, 0x78, 0x5f, 0x76, 0x65, 0x72, 0x73, 1155 | 0x69, 0x6f, 0x6e, 0x20, 0x46, 0x4c, 0x4f, 0x41, 0x54, 0x20, 0x44, 0x45, 1156 | 0x46, 0x41, 0x55, 0x4c, 0x54, 0x20, 0x39, 0x39, 0x39, 0x2c, 0x0a, 0x20, 1157 | 0x50, 0x52, 0x49, 0x4d, 0x41, 0x52, 0x59, 0x20, 0x4b, 0x45, 0x59, 0x20, 1158 | 0x28, 0x64, 0x61, 0x70, 0x70, 0x2c, 0x20, 0x64, 0x65, 0x70, 0x65, 0x6e, 1159 | 0x64, 0x65, 0x6e, 0x63, 0x79, 0x29, 0x0a, 0x29, 0x3b, 0x0a, 0x0a, 0x0a, 1160 | 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x20, 0x54, 0x41, 0x42, 0x4c, 0x45, 1161 | 0x20, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x65, 1162 | 0x73, 0x20, 0x28, 0x0a, 0x20, 0x69, 0x64, 0x20, 0x49, 0x4e, 0x54, 0x45, 1163 | 0x47, 0x45, 0x52, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x4e, 0x55, 0x4c, 0x4c, 1164 | 0x20, 0x50, 0x52, 0x49, 0x4d, 0x41, 0x52, 0x59, 0x20, 0x4b, 0x45, 0x59, 1165 | 0x2c, 0x0a, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x54, 0x45, 0x58, 0x54, 1166 | 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x4e, 0x55, 0x4c, 0x4c, 0x2c, 0x0a, 0x20, 1167 | 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x20, 0x54, 0x45, 0x58, 0x54, 1168 | 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x4e, 0x55, 0x4c, 0x4c, 0x2c, 0x0a, 0x20, 1169 | 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x20, 0x42, 1170 | 0x4c, 0x4f, 0x42, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x4e, 0x55, 0x4c, 0x4c, 1171 | 0x2c, 0x20, 0x2d, 0x2d, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x73, 0x69, 0x67, 1172 | 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x44, 0x41, 0x70, 0x70, 0x73, 0x0a, 0x20, 1173 | 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x20, 0x42, 0x4c, 1174 | 0x4f, 0x42, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x4e, 0x55, 0x4c, 0x4c, 0x20, 1175 | 0x2d, 0x2d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x20, 0x73, 0x69, 0x67, 0x6e, 1176 | 0x61, 0x74, 0x75, 0x72, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x69, 1177 | 0x73, 0x20, 0x72, 0x6f, 0x77, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x73, 0x65, 1178 | 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x72, 0x65, 0x61, 0x73, 0x6f, 1179 | 0x6e, 0x73, 0x0a, 0x29, 0x3b, 0x0a, 0x0a, 0x0a, 0x2f, 0x2a, 0x0a, 0x20, 1180 | 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, 1181 | 0x65, 0x73, 0x0a, 0x2a, 0x2f, 0x0a, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x46, 1182 | 0x61, 0x6b, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x72, 0x65, 1183 | 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x20, 0x66, 0x6f, 0x72, 1184 | 0x20, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x70, 0x75, 0x72, 1185 | 0x70, 0x6f, 0x73, 0x65, 0x73, 0x0a, 0x49, 0x4e, 0x53, 0x45, 0x52, 0x54, 1186 | 0x20, 0x49, 0x4e, 0x54, 0x4f, 0x20, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 1187 | 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x20, 0x56, 0x41, 0x4c, 0x55, 0x45, 1188 | 0x53, 0x20, 0x28, 0x0a, 0x20, 0x31, 0x2c, 0x20, 0x2d, 0x2d, 0x69, 0x64, 1189 | 0x0a, 0x20, 0x22, 0x42, 0x69, 0x74, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x20, 1190 | 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4d, 1191 | 0x61, 0x69, 0x6e, 0x20, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 1192 | 0x72, 0x79, 0x22, 0x2c, 0x20, 0x2d, 0x2d, 0x6e, 0x61, 0x6d, 0x65, 0x0a, 1193 | 0x20, 0x22, 0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x22, 1194 | 0x2c, 0x20, 0x2d, 0x2d, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x0a, 1195 | 0x20, 0x22, 0x66, 0x6f, 0x6f, 0x22, 0x2c, 0x20, 0x2d, 0x2d, 0x70, 0x75, 1196 | 0x62, 0x6c, 0x69, 0x63, 0x20, 0x6b, 0x65, 0x79, 0x0a, 0x20, 0x22, 0x62, 1197 | 0x61, 0x72, 0x22, 0x20, 0x2d, 0x2d, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 1198 | 0x75, 0x72, 0x65, 0x0a, 0x29, 0x3b, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x54, 1199 | 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x44, 0x41, 0x70, 1200 | 0x70, 0x20, 0x69, 0x73, 0x20, 0x42, 0x69, 0x74, 0x63, 0x6c, 0x6f, 0x75, 1201 | 0x64, 0x20, 0x69, 0x74, 0x73, 0x65, 0x6c, 0x66, 0x2c, 0x20, 0x73, 0x6f, 1202 | 0x6d, 0x65, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x20, 0x66, 0x61, 1203 | 0x6b, 0x65, 0x64, 0x0a, 0x49, 0x4e, 0x53, 0x45, 0x52, 0x54, 0x20, 0x49, 1204 | 0x4e, 0x54, 0x4f, 0x20, 0x44, 0x41, 0x70, 0x70, 0x73, 0x20, 0x56, 0x41, 1205 | 0x4c, 0x55, 0x45, 0x53, 0x20, 0x28, 0x0a, 0x20, 0x31, 0x2c, 0x20, 0x2d, 1206 | 0x2d, 0x69, 0x64, 0x0a, 0x20, 0x22, 0x42, 0x69, 0x74, 0x63, 0x6c, 0x6f, 1207 | 0x75, 0x64, 0x22, 0x2c, 0x20, 0x2d, 0x2d, 0x6e, 0x61, 0x6d, 0x65, 0x0a, 1208 | 0x20, 0x22, 0x42, 0x69, 0x74, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x20, 0x62, 1209 | 0x61, 0x72, 0x65, 0x20, 0x62, 0x6f, 0x6e, 0x65, 0x73, 0x2e, 0x22, 0x2c, 1210 | 0x20, 0x2d, 0x2d, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 1211 | 0x6f, 0x6e, 0x0a, 0x20, 0x22, 0x42, 0x69, 0x74, 0x63, 0x6c, 0x6f, 0x75, 1212 | 0x64, 0x20, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 1213 | 0x22, 0x2c, 0x20, 0x2d, 0x2d, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x0a, 1214 | 0x20, 0x22, 0x4d, 0x49, 0x54, 0x22, 0x2c, 0x20, 0x2d, 0x2d, 0x6c, 0x69, 1215 | 0x63, 0x65, 0x6e, 0x73, 0x65, 0x0a, 0x20, 0x30, 0x2e, 0x30, 0x31, 0x2c, 1216 | 0x20, 0x2d, 0x2d, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x0a, 0x20, 1217 | 0x31, 0x2c, 0x20, 0x2d, 0x2d, 0x69, 0x73, 0x20, 0x73, 0x74, 0x61, 0x74, 1218 | 0x69, 0x63, 0x0a, 0x20, 0x4e, 0x55, 0x4c, 0x4c, 0x2c, 0x20, 0x2d, 0x2d, 1219 | 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x0a, 0x20, 0x31, 0x2c, 0x20, 1220 | 0x2d, 0x2d, 0x72, 0x75, 0x6e, 0x0a, 0x20, 0x31, 0x2c, 0x20, 0x2d, 0x2d, 1221 | 0x69, 0x73, 0x20, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x65, 1222 | 0x64, 0x0a, 0x20, 0x31, 0x2c, 0x20, 0x2d, 0x2d, 0x62, 0x69, 0x74, 0x63, 1223 | 0x6c, 0x6f, 0x75, 0x64, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x74, 1224 | 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 1225 | 0x72, 0x79, 0x0a, 0x20, 0x22, 0x66, 0x6f, 0x6f, 0x22, 0x20, 0x2d, 0x2d, 1226 | 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x0a, 0x29, 0x3b, 1227 | 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x54, 0x68, 0x65, 0x20, 0x64, 0x65, 0x66, 1228 | 0x61, 0x75, 0x6c, 0x74, 0x20, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 1229 | 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x72, 0x65, 0x71, 1230 | 0x75, 0x69, 0x72, 0x65, 0x73, 0x20, 0x42, 0x69, 0x74, 0x63, 0x6c, 0x6f, 1231 | 0x75, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x72, 0x75, 0x6e, 0x3a, 0x0a, 0x49, 1232 | 0x4e, 0x53, 0x45, 0x52, 0x54, 0x20, 0x49, 0x4e, 0x54, 0x4f, 0x20, 0x64, 1233 | 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x20, 0x56, 1234 | 0x41, 0x4c, 0x55, 0x45, 0x53, 0x20, 0x28, 0x0a, 0x20, 0x31, 0x2c, 0x20, 1235 | 0x2d, 0x2d, 0x42, 0x69, 0x74, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x20, 0x64, 1236 | 0x61, 0x70, 0x70, 0x0a, 0x20, 0x31, 0x2c, 0x20, 0x2d, 0x2d, 0x42, 0x69, 1237 | 0x74, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x20, 0x64, 0x61, 0x70, 0x70, 0x20, 1238 | 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x73, 0x20, 0x6f, 0x6e, 0x20, 0x69, 1239 | 0x74, 0x73, 0x65, 0x6c, 0x66, 0x0a, 0x20, 0x30, 0x2c, 0x20, 0x2d, 0x2d, 1240 | 0x6d, 0x69, 0x6e, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x0a, 1241 | 0x20, 0x39, 0x39, 0x39, 0x20, 0x2d, 0x2d, 0x6d, 0x61, 0x78, 0x20, 0x76, 1242 | 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x0a, 0x29, 0x3b, 0x0a, 0x0a, 0x0a, 1243 | 0x0a, 0x2d, 0x2d, 0x20, 0x65, 0x6e, 0x64, 0x0a 1244 | }; 1245 | unsigned int nodepool_sql_len = 14864; 1246 | -------------------------------------------------------------------------------- /bitcloud.c/testing.md: -------------------------------------------------------------------------------- 1 | #### Validation of blank nodepool database 2 | 3 | After a new iteration of the code appears to compile and run, project best practice dictates that the ``nodepool`` 4 | DB next be tested to ensure it was actually generated properly. 5 | 6 | * After test instance has executed and appears to have generated a blank ``nodepool`` DB, open SQLite command prompt 7 | with ``# sqlite3 nodepool.db`` (or replace the nodepool.db with whatever filename the nodepool was given). 8 | * You should see a ``sqlite>`` command prompt. Type ``.tables`` at the prompt and press enter. 9 | * You should see a list of tables that matches the ``nodepool.sql`` schema. 10 | * You may also type ``.schema`` to have a complete schema printed. This should match ``nodepool.sql`` 11 | * Type ``.exit`` and press enter to exit the SQLite command-line interface. 12 | 13 | **You may use the SQLite command-line interface, in combination with the API, to output and query the nodepool 14 | database as part of the project's test-driven development lifecycle.** 15 | 16 | -------------------------------------------------------------------------------- /bitcloud.c/tests/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | LDLIBS=../bitcloud.a `pkg-config --libs sqlite3` 3 | INCLUDES=-I.. 4 | CFLAGS=-Wall -ansi `pkg-config --cflags sqlite3` -D_GNU_SOURCE 5 | 6 | run_tests_and_clean: clean run_tests 7 | 8 | run_tests: tests 9 | @echo -- STARTING TESTS -- 10 | ./tests 11 | @echo -- ALL TESTS PASSED -- 12 | 13 | logs: 14 | sqlite3 nodepool "select * from logs" 15 | 16 | tests: main.c logs.c ../bitcloud.a 17 | $(CC) -o $@ $< $(INCLUDES) $(LDLIBS) $(CFLAGS) 18 | 19 | clean: 20 | rm -f tests nodepool 21 | -------------------------------------------------------------------------------- /bitcloud.c/tests/logs.c: -------------------------------------------------------------------------------- 1 | 2 | void logs (void) 3 | { 4 | printf ("log_to_stdout=%d\n", BC_log_to_stdout); 5 | } 6 | -------------------------------------------------------------------------------- /bitcloud.c/tests/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "logs.c" 8 | #include "serialization.c" 9 | 10 | int main (int argc, char **argv) 11 | { 12 | 13 | assert (bc_open_nodepool("nodepool") == BC_OK); 14 | bc_log (BC_OK, "Starting tests..."); 15 | logs (); 16 | serialization (); 17 | bc_log (BC_OK, "Tests finished."); 18 | 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /bitcloud.c/tests/serialization.c: -------------------------------------------------------------------------------- 1 | 2 | void serialization (void) 3 | { 4 | bc_stmt stmt = NULL; 5 | char 6 | *var1 = "textvar", 7 | *value1 ="textvalue", 8 | *var2 = "intvar"; 9 | int value2 = 444; 10 | 11 | bc_sql (&stmt, "INSERT INTO configs VALUES (?,?)"); 12 | bc_binds (stmt, 1, var1); 13 | bc_binds (stmt, 2, value1); 14 | bc_step (stmt); 15 | bc_finalize (stmt); 16 | bc_sql (&stmt,"SELECT val FROM configs WHERE var=?"); 17 | bc_binds (stmt, 1, var1); 18 | bc_step (stmt); 19 | assert(!strcmp (bc_gets (stmt, 0), value1)); 20 | bc_finalize (stmt); 21 | 22 | /* test insertion and retrival of an integer: */ 23 | 24 | bc_sql (&stmt, "INSERT INTO configs VALUES (?,?)"); 25 | bc_binds (stmt, 1, var2); 26 | bc_bindi (stmt, 2, value2); 27 | bc_step (stmt); 28 | bc_finalize (stmt); 29 | bc_sql (&stmt,"SELECT val FROM configs WHERE var=?"); 30 | bc_binds (stmt, 1, var2); 31 | bc_step (stmt); 32 | assert(bc_geti (stmt, 0) == value2); 33 | bc_finalize (stmt); 34 | 35 | } 36 | -------------------------------------------------------------------------------- /bitcloud.js/README.md: -------------------------------------------------------------------------------- 1 | Instructions to construct 2 | 3 | $ npm install ubjson sqlite3 crypto node-rsa 4 | 5 | To run: 6 | 7 | $ node bitcloud.js -------------------------------------------------------------------------------- /bitcloud.js/admin.js: -------------------------------------------------------------------------------- 1 | // Admininstration Control Panel 2 | 3 | function run (node, port, ip) { 4 | 5 | } -------------------------------------------------------------------------------- /bitcloud.js/bitcloud.js: -------------------------------------------------------------------------------- 1 | // Copyright Bitcloud Foundation (2014) 2 | 3 | 4 | // Include objects required for BC functionality <-- BC dependencies 5 | //var ub = require ("ubjson"); // JSON for now 6 | var sqlite3 = require ("sqlite3"); 7 | var net = require('net'); 8 | var fs = require("fs"); 9 | var crypto = require("crypto"); 10 | var rsa = require("node-rsa"); 11 | 12 | var LOGERROR = 0; 13 | var LOGWARNING = 1; 14 | var LOGINFO = 2; 15 | 16 | // List of local Bitcloud node instances 17 | var nodes = []; 18 | 19 | 20 | // Returns a complete Node object 21 | function create_node (filename, init_admin) { 22 | var db = new sqlite3.Database(filename, sqlite3.OPEN_READWRITE); 23 | var block = new sqlite3.Database(":memory:"); 24 | var last_block = new sqlite3.Database(":memory:"); 25 | var key = null; 26 | var sig = null; 27 | return { 28 | block : block, // current block being synced in real time 29 | last_block : last_block, // last block to be hashed, signed and checked 30 | id : null, // the node id (extracted from the nodepool) 31 | grids : [], // grids in which to participate 32 | filename : filename, 33 | 34 | init_admin : init_admin || false, 35 | // run_admin : require("./admin.js").run, // not needed right now 36 | 37 | running : false, 38 | run : function (port, ip) { 39 | var node = this; 40 | // TODO: obtain id and key 41 | this.server = net.createServer(function(sockect) { 42 | sockect.write (node.filename); 43 | sockect.pipe (sockect); 44 | }); 45 | port = port || 19999; 46 | ip = ip || '127.0.0.1'; 47 | this.server.listen(port, ip); 48 | this.log(null, LOGINFO, filename + " is running on " + ip + ":" + port); 49 | 50 | nodes.push(this); 51 | this.running = true; 52 | return true; 53 | }, 54 | stop : function () { 55 | this.server.close(); 56 | this.running = false; 57 | return true; 58 | }, 59 | close : function () { 60 | this.stop(); 61 | this.db.close(); 62 | }, 63 | 64 | log_console : true, 65 | log_db : true, 66 | log_admin : true, // log to admin interface if connected 67 | log : function (table, log_type, text) { 68 | if (this.log_console) 69 | console.log((table ? table + ': ' : '') + text); 70 | }, 71 | //------------------------------------- 72 | // ----- COMMUNICATION 73 | // - For networking and JSON messaging 74 | // - First declaration of communication elements 75 | // ----------------- 76 | connections : [], // current connections for this period 77 | server : null, 78 | connected : false, 79 | // ----------------- 80 | // - communication functions 81 | // ----------------- 82 | open_listen : function () { 83 | /* Opens a listening port to receive external connections */ 84 | 85 | }, 86 | 87 | receive_connect : function () { 88 | /* Handle and process an incoming connection. Either the incoming 89 | connection is a synch request, an external request (like Publisher, 90 | user, or even another grid/node), audit or other administration 91 | request, or someone trying to attack the node. Any other cnnection 92 | types? Returns connection object. */ 93 | }, 94 | 95 | connect_node : function(node_id, connect_type) { 96 | /* Connect to another node or external entity. connect_type likely 97 | will be a multi-element object. May be used by sync functions 98 | below. Returns connection object. */ 99 | 100 | }, 101 | 102 | connect_ip : function(ip, connect_type) { 103 | /* Connect to another node or external entity. connect_type likely 104 | will be a multi-element object. May be used by sync functions 105 | below. Returns connection object. */ 106 | 107 | }, 108 | 109 | 110 | close_connect : function(connection) { 111 | /* Close a connection. Returns success/error code. 112 | Possibly also with an "all" input option to close out all. 113 | Include connection garbage collection in this function. */ 114 | 115 | }, 116 | 117 | msg_pack : function(type, data) { 118 | /* Packing data/instructions into something transmittable. Returns 119 | packed message. */ 120 | }, 121 | 122 | msg_transmit : function(message, connection) { 123 | /* Send a message to a particule connection. Returns success code. */ 124 | }, 125 | 126 | msg_receive : function(message) { 127 | /* Process an incoming message for unpacking. - validate compatible 128 | packing protocol (e.g., UBJSON, JSON, etc.) was used - validate 129 | that the message has no errors (e.g., checksum) */ 130 | }, 131 | 132 | msg_unpack : function(message) { 133 | /* Unpack the message. Returns list containing command type and any 134 | attached data. Commands may be queries, synch RPCs, transmission 135 | of data slice, or other. */ 136 | }, 137 | 138 | //------------------------------------- 139 | // ----- SYNCHING 140 | // - For all synchronization elements and functions 141 | // ----------------- 142 | // - First declaration of synchronization elements 143 | // ----------------- 144 | sync_period : 10, // global tables sync period 145 | 146 | // ----------------- 147 | // - synchronization functions 148 | // ----------------- 149 | sync_with : function (other) { 150 | /* Sync with another node, given its id. 151 | As the whitepaper specify, be careful with whom you sync, it should 152 | be in the list of allowed (see 'get_sync_list'), or there is risk of 153 | being banned.*/ 154 | }, 155 | get_sync_list : function () { 156 | // Get the list of nodes to sync with in this period 157 | }, 158 | 159 | sync : function () { 160 | /* General sync, this normally calls sync_with at each period for every 161 | needed node */ 162 | }, 163 | 164 | // ----- COMMANDS 165 | command_parse : function(command_list) { 166 | /* uses output of msg_unpack to process command. May call qry_command 167 | function below, if applicable to a DB query. */ 168 | }, 169 | 170 | 171 | qry_command : function (table, command) { 172 | /* Process a DB command and run the checks. 173 | This is very often related to command parameters in the *_requests 174 | tables. 175 | 176 | table : table name 177 | command : DB command as directly read from the sync function */ 178 | 179 | }, 180 | 181 | //------------------------------------- 182 | // ----- CA 183 | create_id : function (country, region, city, center, array) { 184 | // temp comment: why country, region, city, etc.? is this really needed? Especially in the PoC? 185 | // also, what is "center" and "array"? 186 | 187 | /* Creates a random proximity ID. 188 | TODO */ 189 | this.id = crypto.randomBytes(20); // provisional solution 190 | return this.id; 191 | }, 192 | mine_CA : function (problem) { 193 | /* Given a problem based on a deterministic global table, mine a CA 194 | problem : string that must be salted with previous hash then hashed using CA 195 | */ 196 | key = new rsa.NodeRSA({b: 2048}); 197 | sig = key.sign(problem, 'base64'); 198 | }, 199 | store_CA : function(CA_key, CA_sig){ 200 | /* Save the mined CA in applicable private table */ 201 | }, 202 | register : function () { 203 | /* Register this node in the Bitcloud 204 | TODO */ 205 | if (!key) throw ("Cannot register without a CA"); 206 | }, 207 | quick_start : function (grid) { 208 | /* Do all the hard staff automatically: 209 | - mine a CA 210 | - create an ID 211 | - register 212 | - connect to the grid */ 213 | }, 214 | //------------------------------------- 215 | // ----- DB operations code 216 | // ----------------- 217 | // - DB elements 218 | // ----------------- 219 | db : db, // nodepool db 220 | // TODO: define the node object type, for working with various nodes at a time 221 | 222 | // ----------------- 223 | // - DB functions 224 | // ----------------- 225 | 226 | // ----- remote db management 227 | insert : function (id, table, values) { 228 | /* Insert a record in the tables, given: 229 | id : id of the soliciting node 230 | table : table to insert (after verification) 231 | value : array consituting the elements of the record 232 | Note: the signature of the operation is included in the record as stated 233 | in nodepool.sql*/ 234 | db.serialize(function() { 235 | var stmt = db.prepare("INSERT INTO " + table + " VALUES (?,?)"); 236 | stmt.run(values); 237 | stmt.finalize(); 238 | }); 239 | 240 | }, 241 | delete : function (id, table, key, signature) { 242 | /* Delete a record in the tables, given: 243 | id : id of the soliciting 244 | table : table to insert (after verification) 245 | key : key to identify the record 246 | signature: the node certificate of this operation*/ 247 | }, 248 | update : function (id, table, key, values) { 249 | /* Insert a record in the tables, given: 250 | id : id of the soliciting node 251 | table : table to insert (after verification) 252 | value : array consituting the elements of the record 253 | Note: the signature of the operation is included in the record as stated 254 | in nodepool.sql*/ 255 | 256 | }, 257 | 258 | // ----- local db management 259 | sql : function (statement, values) { 260 | // A wrapper for sqlite3.Database.run() with some extra checks 261 | 262 | }, 263 | 264 | get_node : function (node_id) { 265 | // returns a node object for the node "node_id" 266 | }, 267 | 268 | push_node : function (node_obj) { 269 | /* takes a node object and serializes it into a record and adds the 270 | record to nodes table */ 271 | }, 272 | 273 | update_node : function (node_obj) { 274 | /* updates the record for node_obj.node_id with all the current values 275 | contained in node_obj */ 276 | } 277 | }} 278 | 279 | 280 | function create_grid (name, owner) { 281 | return { // todo 282 | id : null 283 | }} 284 | 285 | function create_publisher (name){ 286 | return { // todo 287 | id : null 288 | }} 289 | 290 | 291 | // EXPORTS 292 | exports.create_node = create_node; 293 | exports.create_grid = create_grid; 294 | exports.create_publisher = create_publisher; 295 | 296 | exports.LOGERROR = LOGERROR; 297 | exports.LOGWARNING = LOGWARNING; 298 | exports.LOGINFO = LOGINFO; 299 | 300 | // TODO: command line options 301 | 302 | -------------------------------------------------------------------------------- /bitcloud.js/nodepool.sql: -------------------------------------------------------------------------------- 1 | -- For more verbose documentation, see Bitcloud.org wiki -- 2 | -- http://bitcloudproject.org/w/Nodepool.sql_Database_Design -- 3 | -- All below SQL should be generic SQL -- 4 | 5 | /* Nodepool.sql Database 6 | 7 | Rules: 8 | 9 | - Every record is owned by its creator, as enforced via synchronization 10 | verifying signature. 11 | 12 | - The only exception to the above is in the case of user files, which are 13 | owned by both the user and Publisher. 14 | 15 | - Every record may only be modified/deleted by its owner(s), but may be 16 | removed by anyone via "garbage collection" if its owner(s) have been 17 | banned. 18 | 19 | - SQLite supports DB functions/stored procedures written in C. Those 20 | functions, therefore, will only be referenced hereing documentation 21 | provided in the sync and interface code elsewhere. 22 | 23 | */ 24 | 25 | PRAGMA foreign_keys = ON; 26 | 27 | ---------------------------- 28 | -- Bitcloud Nodepool Team -- 29 | ---------------------------- 30 | 31 | -- general nodepool -- 32 | 33 | -- The contents of the general nodepool are synced globally across every nodes 34 | -- in the Bitcloud network. 35 | 36 | /* 37 | nodes table 38 | 39 | Contains: records of all nodes on the Bitcloud nework (up to 1.8e19) 40 | 41 | Rules: 42 | 43 | - Each node must sign its own entire row (except the signature field itself) 44 | using its own public key. 45 | 46 | - The node must provide a new signature of its row every 3 days 47 | maximum. Otherwise it is deleted from the nodepool and connections refused. 48 | 49 | - creation_date must be within the same synchronization period that the node 50 | is registered for node registration be valid. 51 | 52 | - Consistancy is checked by ensuring that nobody tries to register in other 53 | period that is not the actual: 54 | 55 | */ 56 | 57 | CREATE TABLE nodes ( 58 | public_key BLOB PRIMARY KEY NOT NULL, -- ID 59 | proximity BLOB NOT NULL, -- DHT (kademlia-like) map coordinates 60 | signature BLOB NOT NULL, -- self certificate of this row 61 | creation_date INTEGER NOT NULL, 62 | proof_of_creation BLOB, -- see CA generation in the protocol spec 63 | net_protocol INTEGER DEFAULT 1, -- 1 IP, 2 Tor 64 | address TEXT NOT NULL -- IP or onion address 65 | ); 66 | 67 | 68 | -- A grid is a collection of nodes associated that can sell 69 | -- space and bandwidth to a publisher 70 | CREATE TABLE grids ( 71 | id BLOB PRIMARY KEY NOT NULL, -- random number 72 | owner_id BLOB NOT NULL REFERENCES nodes(public_key), 73 | signature BLOB NOT NULL -- signature of the owner 74 | ); 75 | 76 | 77 | CREATE TABLE publishers ( 78 | public_key BLOB PRIMARY KEY NOT NULL, 79 | address TEXT, 80 | creation_date DATE DEFAULT CURRENT_TIMESTAMP NOT NULL, 81 | proof_of_creation BLOB, -- see CA generation in the protocol spec 82 | nickname TEXT, 83 | -- is information about the content of this publisher public?: 84 | public_metadata BOOLEAN DEFAULT FALSE, 85 | public_files BOOLEAN DEFAULT FALSE, 86 | -- trust all other publisher users by default? If not, only trust 87 | -- those in the publisher_trusts with positive trust. If yes, trust 88 | -- all except those with negative trust. 89 | trust_all_users BOOLEAN DEFAULT TRUE 90 | ); 91 | 92 | 93 | 94 | ------------------------------------- 95 | -- internal publishers/grid tables -- 96 | ------------------------------------- 97 | 98 | -- these tables are shared between associations (e.g., between publishers and 99 | -- grids, or grids and nodes, etc.) 100 | 101 | /* 102 | 103 | node_audit table: things in this table are only inserted after a node failed 104 | to provide a correct check. Every single row in this table is deleted after 105 | every check period, and the new content based on the last one, so it can 106 | ensure continuation of the measurements and save space at the same time. 107 | 108 | For example, if a node fails to be available for some periods, there is no 109 | need that the nodes doing the check have to insert new rows, they just reuse 110 | the rows from the previous perirods, and sign the row. The limit is 16 rows 111 | per node. 112 | 113 | Auditors are random. 114 | 115 | Nodes doing everything perfect are never present in this table except when 116 | issued by malicious nodes. The majority of the net must be malicious in order 117 | to have consecuences for those nodes. 118 | 119 | Bitcloud do not count reputation, but just measures possible incorrections of 120 | the nodes. DAs on top could implement a system of reputation based on this 121 | table and other tables they provide. 122 | 123 | */ 124 | 125 | 126 | CREATE TABLE publisher_trusts ( 127 | from_publisher BLOB NOT NULL REFERENCES publishers(public_key), 128 | to_publisher BLOB REFERENCES publishers(public_key), 129 | trust_users BOOLEAN NOT NULL, 130 | trust_powers BOOLEAN NOT NULL, -- like baning users or moderate files 131 | signature BLOB NOT NULL, -- from signature 132 | reason INTEGER NOT NULL, 133 | /* 134 | 1: Friend 135 | 2: Banned 136 | 3: Bad contracts 137 | 4: ... to be continued 138 | */ 139 | CHECK (reason>=1 and reason <=3) 140 | ); 141 | 142 | 143 | CREATE TABLE users ( 144 | public_key BLOB PRIMARY KEY NOT NULL, 145 | publisher BLOB NOT NULL REFERENCES publishers(public_key), 146 | publisher_signature BLOB, 147 | address TEXT, 148 | nick TEXT COLLATE NOCASE, 149 | fixed_address BOOLEAN DEFAULT TRUE, 150 | revocation_date DATE DEFAULT CURRENT_TIMESTAMP, 151 | storage_quota INTEGER DEFAULT 0, 152 | bandwidth_quota INTEGER DEFAULT 0, 153 | files_quota INTEGER DEFAULT 0, -- how many files can upload 154 | folder_quota INTEGER DEFAULT 0, -- how many folders allowed 155 | root_folder BLOB REFERENCES folders(id) 156 | ); 157 | 158 | -- User requests sent to the grids, for example, creating 159 | -- a folder or uploading/downloading a file 160 | CREATE TABLE user_requests ( 161 | id BLOB PRIMARY KEY NOT NULL, 162 | user BLOB NOT NULL REFERENCES users(public_key), 163 | signature BLOB NOT NULL, 164 | grid TEXT NOT NULL REFERENCES grids(public_key), 165 | action INTEGER NOT NULL, 166 | -- every type of action will have a different param values 167 | param1 BLOB, 168 | param2 BLOB, 169 | /* 170 | 1: Download file: param1=fileID, param2=offset 171 | 2: Stream file: param1=fileID, param2=offset 172 | 3: Upload file: param1=fileID, param2=folderID 173 | 4: Create folder: param1=folderID 174 | 5: Remove folder: param1=folderID 175 | 6: Rename folder: param1=folderID 176 | 7: Move file: param1=origin_foldeID, param2=final_folderID 177 | 8: Rename file: param1=fileID, param2=new_name 178 | 9: Delete file: param1=fileID 179 | 10: Update file owner: param1=fileID, param2=userID 180 | 11: Update file permissions: param1=fileID, param2=flags 181 | 11: Grant user file access: param1=fileID, param2=userID 182 | 12: Grant user folder acccess: param1=folderID, param2=userID 183 | 13: ... to be continued 184 | */ 185 | CHECK (action > 0 and action<=12) 186 | ); 187 | 188 | 189 | CREATE TABLE publisher_grid_contracts ( 190 | id BLOB PRIMARY KEY NOT NULL, 191 | publisher BLOB NOT NULL REFERENCES publishers(public_key), 192 | grid TEXT NOT NULL REFERENCES grids(public_key), 193 | -- Signatures of this contract: 194 | publisher_sig TEXT NOT NULL, 195 | grid_sig TEXT NOT NULL, 196 | -- Terms: 197 | min_bandwidth INTEGER NOT NULL, 198 | start_date DATE DEFAULT CURRENT_TIMESTAMP NOT NULL, 199 | end_date DATE DEFAULT CURRENT_TIMESTAMP NOT NULL, 200 | availability INTEGER NOT NULL, -- % of time online 201 | ping_average INTEGER DEFAULT 0, 202 | -- Coin terms 203 | coin TEXT /* example: BTC */ 204 | ); 205 | 206 | 207 | -- Table for owner requests of its grid nodes 208 | CREATE TABLE grid_owner_requests ( 209 | grid BLOB PRIMARY KEY REFERENCES grids(id), 210 | owner_sig BLOB NOT NULL, 211 | action INTEGER NOT NULL, 212 | param1 BLOB, 213 | param2 BLOB 214 | /* possible actions 215 | 1: Assign storage node: param1=nodeID, param2=gatewayID 216 | 2: Upgrade storage node to gateway: param1=nodeID 217 | 3: Set minimum bandwidth: param1=nodeID, param2=rate 218 | 4: Revoke node: param1=nodeID 219 | 5: ... to be continued 220 | */ 221 | ); 222 | 223 | -- Table used for publishers instructing orders to contracted grids: 224 | CREATE TABLE publisher_requests ( 225 | grid_sig BLOB NOT NULL, 226 | publisher_sig BLOB, 227 | action INTEGER NOT NULL, 228 | param1 BLOB, 229 | param2 BLOB, 230 | /* possible actions: 231 | 1: Accept user: param1=userID, param2=due-time 232 | 2: Revoke user: param1=userID 233 | 3: Remove file: param1=fileID 234 | 4: Remove folder: param1=folderID 235 | 5: Set user files quota: param1=userID, param2=quota 236 | 6: Set user storage quota: param1=userID, param2=quota 237 | 7: Set user folders quota: param1=userID, param2=quota 238 | 8: Set file permisions: param1=fileID, param2=flags 239 | 9: Update file owner: param1=fileID, param2=userID 240 | 10: Update folder owner: param1=fileID, param2=userID 241 | 11: Register nickname: param1=userID, param2=nickname 242 | 12: Delete nickname: param1=nickname 243 | 13: .... to be continued 244 | */ 245 | CHECK (action>=1 and action<=12) 246 | ); 247 | 248 | -- Gateways convert reconstruct data from the storage nodes and 249 | -- present it to the users/publishers. Multiple gateways per grid 250 | -- are possible. 251 | CREATE TABLE gateways ( 252 | node BLOB PRIMARY KEY REFERENCES nodes(public_key), 253 | grid TEXT NOT NULL REFERENCES grids(id), 254 | priority INTEGER, --larger means more priority, in case of the gateway 255 | --to have more than one grid associated. 256 | grid_sig TEXT, 257 | node_sig TEXT 258 | ); 259 | 260 | CREATE TABLE grid_node_contracts ( 261 | id BLOB PRIMARY KEY NOT NULL, 262 | grid TEXT REFERENCES grids(public_key), 263 | node BLOB NOT NULL REFERENCES nodes(public_key), 264 | grid_sig TEXT, 265 | node_sig TEXT, 266 | min_storage INTEGER NOT NULL, 267 | min_bandwidth INTEGER NOT NULL, 268 | start_date DATE DEFAULT CURRENT_TIMESTAMP NOT NULL, 269 | working_time INTEGER, -- only the grid can modify this 270 | -- Coin terms 271 | coin TEXT(4), -- ie: BTC 272 | bandwidth_block_size INTEGER DEFAULT 100000000, 273 | price_per_block INTEGER DEFAULT 0 274 | ); 275 | 276 | CREATE TABLE node_audits ( 277 | node BLOB REFERENCES nodes(public_key), 278 | auditor BLOB NOT NULL REFERENCES nodes(public_key), 279 | signature BLOB NOT NULL, -- auditors signature 280 | periods INTEGER DEFAULT 1, -- number of periods this audis is applicable for 281 | reason INTEGER NOT NULL, 282 | /* 283 | 1: Ping timeout. 284 | 2: Incorrect signature. 285 | 3: Incorrect audition. 286 | 4: Too slow connection. 287 | 5: Denial of service. 288 | 6: Corrupt data. 289 | 7: ... to be continued 290 | */ 291 | CHECK (reason>=1 and reason <=6) 292 | ); 293 | 294 | 295 | -------------------- 296 | -- files and folders 297 | -------------------- 298 | 299 | -- synced between publishers/grids/users but not globally. 300 | 301 | CREATE TABLE folders ( 302 | id BLOB NOT NULL PRIMARY KEY, 303 | parent BLOB REFERENCES folders(id), 304 | name TEXT, 305 | permission BLOB REFERENCES permissions(id) 306 | ); 307 | 308 | CREATE TABLE files ( 309 | hash TEXT NOT NULL PRIMARY KEY, 310 | name TEXT, 311 | mime_type TEXT, 312 | content BLOB, 313 | rate INTEGER DEFAULT 0, --bandwidth rate at what must be streamed 314 | folder BLOB NOT NULL REFERENCES folders(id), 315 | user_sig TEXT NOT NULL, 316 | permissions BLOB REFERENCES permissions(id) 317 | ); 318 | 319 | 320 | CREATE TABLE permissions ( 321 | id BLOB NOT NULL PRIMARY KEY, 322 | user BLOB REFERENCES users(public_key), 323 | publisher BLOB REFERENCES publishers(public_key), 324 | -- NULL user/publisher means permissions for everyone 325 | read BOOLEAN, 326 | read_quota INTEGER, 327 | write BOOLEAN, 328 | write_quota INTEGER, 329 | create_new BOOLEAN, 330 | remove BOOLEAN, 331 | set_perm BOOLEAN -- Meaning someone can have permissions to set permissions in UI term 332 | ); 333 | 334 | 335 | 336 | 337 | -------------------- 338 | -- private tables -- 339 | -------------------- 340 | 341 | -- Tables not synced. Mostly internal configuration and convenient tables. 342 | 343 | CREATE TABLE CAs ( 344 | public_key BLOB PRIMARY KEY NOT NULL, 345 | private_key BLOB NOT NULL, 346 | proof_of_generation BLOB, 347 | ssl_extra TEXT 348 | ); 349 | 350 | CREATE TABLE configs ( 351 | var BLOB PRIMARY KEY NOT NULL, 352 | val BLOB NOT NULL 353 | ); 354 | 355 | -- logs -- 356 | ---------- 357 | 358 | CREATE TABLE logs ( 359 | num INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, 360 | error_code INTEGER NOT NULL, 361 | log TEXT, 362 | ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP 363 | ); 364 | 365 | -- synch working tables -- 366 | ---------- 367 | CREATE TABLE syncing_pool ( 368 | node_id BLOB PRIMARY KEY NOT NULL REFERENCES nodes(public_key), 369 | num INTEGER, -- the number of the current synchronization round 370 | instance_num INTEGER -- different synchronization pool per instance, since data may have different consistency 371 | -- anything else to add about the synch process? random assignment info? 372 | ); 373 | 374 | /* 375 | 376 | CREATE TABLE instance_index ( 377 | node_key BLOB PRIMARY KEY NOT NULL REFERENCES nodes(public_key), 378 | instance_num INTEGER() -- size should be equivalent to number of different configurations/instances 379 | ); 380 | 381 | --- this may be built out later. this was an idea to not duplicate nodes table per instance 382 | 383 | */ 384 | 385 | 386 | /* 387 | 388 | Every table, including deriving DAs tables, need to meet certain rules. This 389 | table is just a configuration table never synced. It is created at the time 390 | of node creation and updated when the software is updated. 391 | 392 | When a Dapp is addded to the node, this table is updated with the information 393 | of the new tables. 394 | 395 | */ 396 | 397 | 398 | 399 | CREATE TABLE table_rules ( 400 | table_id INTEGER PRIMARY KEY NOT NULL, -- must be unique and assigned by the repository 401 | table_name TEXT NOT NULL, 402 | dapp INTEGER REFERENCES DApps(id), 403 | 404 | -- exposure of the table in the nodepool 405 | -- 0=private; 1=grid; 2=participants only; 3=full global (careful); 406 | exposure INTEGER DEFAULT 0, 407 | 408 | -- participants (OR checked) 409 | -- 1=node; 2=grid owner; 4=gateways; 8=publishers; 16=users 410 | paticipants INTEGER DEFAULT 0, 411 | 412 | -- how data is synced? 413 | -- 0=nosync, 1=proximity, 2=random, 3=manual, 4=owner 414 | sync_type INTEGER DEFAULT 0, 415 | nodes_to_sync INTEGER DEFAULT 16, 416 | proximity_nodes INTEGER DEFAULT 12, 417 | 418 | -- how offten to check consistency? (this is different than actually syncing) 419 | -- in seconds, 0=nocheck 420 | check_every INTEGER DEFAULT 600, 421 | 422 | 423 | 424 | -- check function: this is a C function that checks the consistency of the 425 | -- last block across the nodes affected (from exposure). 426 | check_function TEXT DEFAULT "bc_check", 427 | 428 | -- sync functions: this C functions take a table and a row from argument and try 429 | -- to modify the local DB if tests are passed: 430 | insert_function TEXT default "bc_insert", 431 | delete_function TEXT default "bc_delete", 432 | update_function TEXT default "bc_update", 433 | 434 | -- maximum general number of transactions per check period and participant: 435 | max_transactions INTEGER DEFAULT 1, 436 | -- if max number of transaction must be specified per participant to avoid excess 437 | -- of flood or DDOS attacks: 438 | check_flood_function TEXT DEFAULT "bc_check_flood" 439 | 440 | ); 441 | 442 | 443 | -- Table for registering DApps using repositories 444 | CREATE TABLE DApps ( 445 | id INTEGER NOT NULL PRIMARY KEY, -- the ID must be unique and assigned by the repository 446 | name TEXT NOT NULL UNIQUE, 447 | description TEXT, 448 | author TEXT, 449 | license TEXT, 450 | version FLOAT NOT NULL, -- example: 0.96 451 | 452 | is_static BOOLEAN DEFAULT 0, -- compiled static or dynamic. 453 | 454 | -- This is the name of the library (.so or .dll) file to download. This file 455 | -- will contain some or all the functions in the "table_rules". This file is 456 | -- located in the "dapp" directory. 457 | dapp_library TEXT, 458 | 459 | run BOOLEAN DEFAULT 0, -- is this DApp to be run when calling bc_run_all_apps()? 460 | is_downloaded BOOLEAN DEFAULT 0, -- the files are downloaded 461 | 462 | -- The respository and signature, without this the app is considered malicious 463 | repository INTEGER REFERENCES repositories(id), 464 | rep_sig BLOB 465 | ); 466 | 467 | 468 | -- DApps dependences. Multiple dependences per DApp are possible 469 | CREATE TABLE dependences ( 470 | dapp INTEGER REFERENCES DApps(id), 471 | dependency INTEGER REFERENCES DApps(id), -- the DApp in dependency 472 | min_version FLOAT DEFAULT 0, -- the required minimum version 473 | max_version FLOAT DEFAULT 999, 474 | PRIMARY KEY (dapp, dependency) 475 | ); 476 | 477 | 478 | CREATE TABLE repositories ( 479 | id INTEGER NOT NULL PRIMARY KEY, 480 | name TEXT NOT NULL, 481 | address TEXT NOT NULL, 482 | public_key BLOB NOT NULL, -- for signing DApps 483 | signature BLOB NOT NULL -- self signature of this row for security reasons 484 | ); 485 | 486 | 487 | /* 488 | Default values 489 | */ 490 | 491 | 492 | -- Fake first repository for testing purposes 493 | INSERT INTO repositories VALUES ( 494 | 1, --id 495 | "Bitcloud Foundation Main Repository", --name 496 | "127.0.0.1", --address 497 | "foo", --public key 498 | "bar" --signature 499 | ); 500 | 501 | -- The first DApp is Bitcloud itself, some values faked 502 | INSERT INTO DApps VALUES ( 503 | 1, --id 504 | "Bitcloud", --name 505 | "Bitcloud bare bones.", --description 506 | "Bitcloud Foundation", --author 507 | "MIT", --license 508 | 0.01, --version 509 | 1, --is static 510 | NULL, --library 511 | 1, --run 512 | 1, --is downloaded 513 | 1, --bitcloud foundation repository 514 | "foo" --signature 515 | ); 516 | 517 | -- The default dependence only requires Bitcloud to run: 518 | INSERT INTO dependences VALUES ( 519 | 1, --Bitcloud dapp 520 | 1, --Bitcloud dapp depends on itself 521 | 0, --min version 522 | 999 --max version 523 | ); 524 | 525 | 526 | 527 | -- end 528 | -------------------------------------------------------------------------------- /bitcloud.js/repl.js: -------------------------------------------------------------------------------- 1 | 2 | var bitcloud = require("./bitcloud.js"); 3 | var repl = require("repl"); 4 | 5 | console.log("INFO: 'main_node' object contains the running node"); 6 | 7 | var readline = require('readline') 8 | , rl, 9 | colors = require('colors') // npm install colors #already installed 10 | ,help = [ 'help ' + 'display help message.'.grey 11 | , '.error ' + 'display an example error'.grey 12 | , 'connect ' + 'connect to nodes .'.grey 13 | , '.q[uit] ' + 'exit console.'.grey 14 | ].join('\n') 15 | ; 16 | 17 | // Auto Complete Function 18 | function completer(line) {//add all commands to be autocompleted on tab 19 | var completions = 'help .error exit quit connect .q'.split(' ') 20 | var hits = completions.filter(function(c) { 21 | if (c.indexOf(line) === 0) { 22 | // console.log('bang! ' + c); 23 | return c; 24 | } 25 | }); 26 | return [hits && hits.length ? hits : completions, line]; 27 | }; 28 | 29 | 30 | 31 | rl = readline.createInterface(process.stdin, process.stdout, completer); 32 | 33 | rl.setPrompt("Bitcloud>"); 34 | 35 | rl.on('line', function(cmd) { 36 | var args = cmd.split(' -');//getting argumments 37 | //console.info(args);//use for debugging args 38 | cmd = args[0].trim(); 39 | args.shift();//removeing cmd frmo args 40 | switch(cmd) { 41 | case 'quit': 42 | rl.question('Are you sure? (y/n) ', function(answer) { 43 | if (answer === 'y') { 44 | rl.close(); 45 | } else { 46 | rl.prompt(); 47 | } 48 | }); 49 | break; 50 | case 'connect'://we can add after the connect all or connect IP_address 51 | var connect_setup = [],display="",error=0; 52 | args.map(function(a){ 53 | var vals = a.split(' '); 54 | connect_setup.push(vals); 55 | switch(vals[0]) { 56 | case 'ip': 57 | display+='Connecting to nodes using ip='+vals[1]; 58 | break; 59 | case 'limit': 60 | display+=' Limiting nodes number ='+vals[1]+' nodes'; 61 | break; 62 | case 'type': 63 | display+=' and connect type of '+vals[1]; 64 | break; 65 | default://unkown argument 66 | error=1;//set error to true and do not proceed the connection untill correct args given 67 | display='Unkown argument '+vals[0]+' \n Valid arguments are:\n'; 68 | display+='-ip : for connect with specifi ip address \n'; 69 | display+='-type : using connect type : either multi or single \n'; 70 | display+='-limit : limit number of connecting nodes : Integer '; 71 | } 72 | }); 73 | /* Connect code here or call to function */ 74 | console.info(display+'\n '); 75 | if(!error)//there is no error 76 | connect_setup;//use this array to setup the connection with all arguments you want 77 | //else 78 | //log errors 79 | break; 80 | case 'help': 81 | var text='Bitcloud Help!\n Use the following commands for : ';//there is no problem using ' for a full string 82 | text += "\n help : Displays this help menu \n connect : Connects all nodes \n quit : Exits the bitcloud shell"; 83 | console.log(text); 84 | break; 85 | default: 86 | console.log('Command not found :', cmd.trim() ); 87 | console.log('Type "quit" to exit or help to display help menu '); 88 | break; 89 | } 90 | 91 | rl.prompt();0; 92 | return false; 93 | }); 94 | 95 | rl.on('close', function() { 96 | console.log('All Nodes Connections closed...\n Bye'); 97 | process.exit(); 98 | }); 99 | 100 | rl.prompt(); 101 | 102 | -------------------------------------------------------------------------------- /bitcloud.js/resetnodepool.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | 4 | if [ $# -eq 0 ]; then 5 | echo "This utility resets or creates the nodepool." 6 | echo "Name of the nodepool required as first parameter." 7 | exit 1 8 | fi 9 | 10 | rm -f $1 11 | cat nodepool.sql | sqlite3 $1 12 | echo $1 reset 13 | -------------------------------------------------------------------------------- /bitcloud.js/test.js: -------------------------------------------------------------------------------- 1 | // THIS SHOULD GO TO test.js 2 | console.log("Bitcloud.js 0.1 PoC"); 3 | 4 | var bitcloud = require('./bitcloud'); 5 | var repl = require("repl"); 6 | 7 | var nodes = []; 8 | 9 | var main_node = bitcloud.create_node ("nodepool.db"); 10 | main_node.run(); 11 | 12 | // nodes.push(main_node); // not sure if this works. trying to use nodes[] 13 | 14 | //main_node.close(); // only after receiving an exit command from local_repl 15 | 16 | /* repl.start({ 17 | prompt: "bitcloud> ", 18 | input: process.stdin, 19 | output: process.stdout 20 | }); 21 | */ 22 | 23 | console.log("INFO: 'main_node' object contains the running node"); 24 | var local_repl = repl.start({ prompt : "bitcloud> ", }); 25 | 26 | local_repl.context.main_node = main_node; -------------------------------------------------------------------------------- /crowdfunding: -------------------------------------------------------------------------------- 1 | 1. 1st campaign 2 | a. Goal of $50,000 dollars? 3 | b. Prerequisites 4 | 1. Proof of concept 5 | 2. Pristine white paper 6 | 3. Videos 7 | 4. Endorsements from various authority figures in each target group 8 | a. Open Bitcoin Privacy Project (code review, etc.) 9 | 5. Marketing materials (flyers, buttons, stickers, brochures, etc.) 10 | 6. Design documentation: 11 | - clear problem statement 12 | - architecture (system design document) 13 | - state diagrams (to specify protocol processes) 14 | c. What we do with the money 15 | 1. Fund alpha release with X features. 16 | d. Who to target? 17 | 1. Bitcoin community 18 | a. No altcoin 19 | b. Adds value to bitcoin 20 | 2. Open source/tech communities 21 | 3. Libertarians and other privacy advocates (also young people) 22 | a. The Snowden generation 23 | b. People who would support Bitcloud for political reasons 24 | e. Possible criticisms 25 | 1. Storj or maidsafe 26 | a. Explain why appcoins don't work 27 | b. Point to most respected people in bitcoin not liking appcoins 28 | f. Platform for raising funds 29 | 1. Lighthouse 30 | 2. Alternative Bitcoin address for those who don't wish to use Lighthouse? 31 | g. Perks for donors 32 | 1. Are they needed? 33 | 2. 2nd campaign 34 | a. Goal of X dollars. 35 | b. Prerequisites 36 | c. What we do with the money 37 | 1. How far does this take development? 38 | d. Who to target? 39 | 1. Data centers 40 | 2. App developers 41 | e. Platform for raising funds 42 | 1. Indiegogo/FundAnything/Kickstarter 43 | g. Perks for donors 44 | 1. Can consult with Bitcloud developers. 45 | 46 | 3. 3rd campaign 47 | a. Goal of X dollars. 48 | b. Prerequisites 49 | c. What we do with the money 50 | 1. How far does this take development? 51 | d. Who to target? 52 | e. Platform for raising funds 53 | 1. Indiegogo/FundAnything/Kickstarter 54 | 2. Lighthouse/Bitcoin 55 | g. Perks for donors 56 | 1. Rasberry Pi storage node. 57 | 58 | ---GENERAL NOTES--- 59 | 1. Learn from Unsystem's Dark Wallet campaign. 60 | -------------------------------------------------------------------------------- /img/bitcloud-fm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wetube/bitcloud/75036a2dde59012b14a26d98bfe221dba0e9e940/img/bitcloud-fm.png -------------------------------------------------------------------------------- /img/structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wetube/bitcloud/75036a2dde59012b14a26d98bfe221dba0e9e940/img/structure.png --------------------------------------------------------------------------------