├── .gitattributes ├── images ├── clear-architecture-dependency-rule.png ├── clear-architecture-dependency-inversion.png ├── clear-architecture-domain-application-client-tiers.png ├── clear-architecture-dependency-rule.svg └── clear-architecture-dependency-inversion.svg ├── .gitignore ├── .editorconfig ├── LICENSE.txt └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto -------------------------------------------------------------------------------- /images/clear-architecture-dependency-rule.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jkphl/clear-architecture/HEAD/images/clear-architecture-dependency-rule.png -------------------------------------------------------------------------------- /images/clear-architecture-dependency-inversion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jkphl/clear-architecture/HEAD/images/clear-architecture-dependency-inversion.png -------------------------------------------------------------------------------- /images/clear-architecture-domain-application-client-tiers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jkphl/clear-architecture/HEAD/images/clear-architecture-domain-application-client-tiers.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea 2 | 3 | # Logs 4 | /logs 5 | /*.log 6 | /npm-debug.log* 7 | 8 | # Dependency directories 9 | /node_modules 10 | 11 | # Optional npm cache directory 12 | /.npm 13 | 14 | # Optional REPL history 15 | /.node_repl_history 16 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | end_of_line = lf 6 | indent_style = space 7 | indent_size = 4 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright © 2017 Joschi Kuphal 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # A Clear Architecture 2 | 3 | In my experience, development approaches like [Domain-Driven Design] and structural concepts as the [Hexagonal Architecture] or the [Onion Architecture] carry a lot of wisdom but don't necessarily provide practical guidance when it comes to starting off with a new project. After several unsatisfactory experiments, I felt a sort of relief when I first read about the [Clean Architecture], which nicely aggregates some high-level concepts while simplifying things at the same time. 4 | 5 | However, even the Clean Architecture doesn't provide a simple-to-follow recipe for layouting a project, naming classes, files and directories and deciding where to settle a particular functionality. So I trial-and-errored myself to the point where I had a rather concise, opinionated implementation of the Clean Architecture that prove useful in several projects — even and especially in combination with each other. Let me introduce you to the **Clear Architecture**. 6 | 7 | *Note: I won't go into too much detail about the various high-level concepts involved in the Clear Architecture but rather focus on their practical application. Follow the links to learn more about them.* 8 | 9 | 10 | ## Key objectives 11 | 12 | * Pragmatic, down-to-earth architecture with a fixed base layout and a concise set of rules and conventions 13 | * Reasonable balance of simplicity, usability, abstraction and high-level concepts 14 | * Independence of programming environment, frameworks and delivery mechanisms 15 | * Suitable for building libraries (to be used by other packages) 16 | 17 | 18 | ## Three-tier architecture 19 | 20 | In the Clear Architecture, source code is structured into 3 tiers that build on one another, most easily illustrated as concentric circles with the outermost one consisting of 3 complementary sectors. 21 | 22 | Clear Architecture tiers 23 | 24 | 25 | ### ① Domain tier 26 | 27 | * [**Domain** objects & services] 28 | * High-level business rules 29 | 30 | > In a banking application, the domain layer holds the definitions of the bank account, the account holder, the currency etc. as well as their relationships with each other. 31 | 32 | 33 | ### ② Application tier 34 | 35 | * **Application** specific business rules & services 36 | * [Use cases] orchestrating domain components 37 | * Translating between external requests from the [③ client tier](#-client-tier-3-sectors) and domain logic (back and forth) 38 | 39 | > The application layer executes different types of bank transactions, provides a currency exchange service and so on. 40 | 41 | 42 | ### ③ Client tier (3 sectors) 43 | 44 | * Low-level implementation details and mechanisms 45 | * Public **ports** for external agencies (APIs, CLI, MVC components, etc.) 46 | * **Infrastructural** details (persistence strategy, database platform, frameworks, 3rd party library bindings, etc.) 47 | * Unit, functional and integration **tests** 48 | 49 | > The client layer implements the database operations, provides a web interface for online banking and a [FinTS] interface to be used by external applications. 50 | 51 | #### Ports 52 | 53 | The *Ports* sector is the **public interface** of your application. It accept requests from external agencies (e.g. the Web, the command-line, an embedding system etc.), communicates them to the [infrastructure sector](#infrastructure) as well as the [② application layer](#-application-tier) and responds with the processed results. It represents your system to the outer world by taking the form of a web or native [GUI], a [CLI], a [REST API] or any other type of interface suitable for accessing your application. Components in this sector may include (but are not limited to): 54 | 55 | * [Facades] 56 | * [Interfaces] 57 | * [Factories] 58 | * [Exceptions] that might occur on the client layer 59 | * [Constant definitions] useful for accessing your application 60 | * Controller / Action components of [MVC] / [ADR] architectures 61 | 62 | *Note: If your application provides a web interface or similar API, don't directly use the `Ports` directory (or any of its subdirectories) as document root for web server scripts. Instead, create a top-level `public` directory and put your bootstrap script files there. Search for a similar solution when providing a CLI ([see below](#considerations-for-php-implementations) for PHP specific recommendations).* 63 | 64 | #### Infrastructure 65 | 66 | The *Infrastructure* sector is not strictly private, but it holds the implementation details that are not necessarily of public interest. While the *[Ports](#ports)* interface should be stable in the long run, it's acceptable for infrastructural components to change with the requirements. Ideally, they can be swapped against equivalent mechanisms without affecting the overall system functionality. External agencies should avoid accessing the infrastructure layer directly, but there might be exceptions for efficiency's sake. Typically in this sector: 67 | 68 | * Third-party [libraries] and [frameworks] (they're always considered to be part of the infrastructure even if stored elsewhere and / or autoloaded) 69 | * [Persistence] mechanisms (e.g. [database] platforms) 70 | * Model / View / Presenter / Domain / Responder components of [MVC] / [MVP] / [ADR] architectures 71 | * [Template engines] and templates 72 | * Configuration data 73 | 74 | #### Tests 75 | 76 | The *Tests* sector holds all resources required for [testing your application]. In general, tests are nothing more than highly specialized clients of your application and must be granted full access to your [③ client](#-client-tier-3-sectors) and [② application](#-application-tier) layers. Test resources may also be accessed by external agencies (e.g. by extension) and typically include: 77 | 78 | * Unit, integration, interface and / or acceptance test cases 79 | * Test fixtures 80 | 81 | 82 | ## Directory layout 83 | 84 | ### Base skeleton 85 | 86 | ``` 87 | `-- src 88 | `-- 89 | |-- Application 90 | |-- Domain 91 | |-- Infrastructure 92 | |-- Ports 93 | `-- Tests 94 | ``` 95 | 96 | * The top level directory `src` separates the actual source files from other package resources, e.g. documentation, dependency modules, web interface files etc. 97 | * `` must be replaced with a vendor-unique [UpperCamelCase] package name (e.g. `MyApp`). 98 | * The 3rd level is made up of five directories representing the main architectural [tiers and sectors](#three-tier-architecture) . 99 | 100 | 101 | ### Application specifics 102 | 103 | Inside the five main directories, your application may add additional structures as needed. However, to keep things consistent, I recommend sticking to these conventions: 104 | 105 | * Directory and file names are always to be written in **UpperCamelCase**. I prefer using singular expressions wherever possible (i.e. `Factory` instead of `Factories`). 106 | * If you have **multiple similar components**, that are mostly used by external agencies (e.g. on a lower architectural level or by an external package), **keep them at a common central location**. As an example, I typically use directories named `Facade`, `Contract`, `Service` or `Factory` for grouping classes with similar functionality. 107 | * **Keep closely related components together**. If you have, for instance, a class definition that implements an interface as described in [The Dependency Inversion Principle](#the-dependency-inversion-principle), put them into the same directory instead of spreading them across the file system. This rule commonly outweighs the previous one — it might be a matter of taste in some situations though. 108 | * If a lower architectural layer "mirrors" and extends the structure of a higher one, e.g. by providing concrete implementations of a high-level interface, try to use **common file and directory names accross levels**. This will help keeping the cross-boundary relationships in mind. 109 | 110 | 111 | ## Rules & Conventions 112 | 113 | Clear Architecture tiers 114 | 115 | 116 | ### The Dependency Rule 117 | 118 | In the Clear Architecture, source code dependencies may **only ever point to the same or an inward layer**. 119 | 120 | > Nothing in an inner circle can know anything at all about something in an outer circle. In particular, the name of something declared in an outer circle must not be mentioned by the code in an inner circle. That includes functions, classes, variables or any other named software entity. (*[Clean Architecture], Robert C. Martin*) 121 | 122 | In other words, it's perfectly fine to reference same or higher-level components e.g. by 123 | 124 | * constructing class instances ("[objects]"), 125 | * implementing [interfaces], using [traits] etc., 126 | * calling functions and methods or 127 | * using classes, interfaces etc. for [typing]. 128 | 129 | Adhering to the Dependency Rule makes your application testable and flexible in terms of implementation details (persistence strategy, database platform, provided client APIs etc.). 130 | 131 | 132 | ### The Dependency Inversion Principle 133 | 134 | In order to not violate the Dependency Rule, the [Dependency Inversion Principle] must be used whenever complex data needs to be passed across a boundary to an inward layer. Instead of expecting and directly referencing a low-level component (e.g. as a function parameter), the high-level layer provides and references an interface that must be implemented and inherited from by the caller. This way, the conventional dependency relationship is inverted and the high-level layer is decoupled from the low-level component. 135 | 136 | ![Dependency inversion by using an interface / abstract service class](https://cdn.rawgit.com/jkphl/clear-architecture/b1d9d3f2/images/clear-architecture-dependency-inversion.svg) 137 | 138 | 139 | ### Decoupling & Dependency Injection 140 | 141 | In general, avoid tight coupling between components and prefer abstractions / [interfaces] over concrete implementations, thus enabling [polymorphism] and making your application a lot better testable. You will always have to deal with object instantiation and globals at some point, but try to limit their occurrences to a minimum and manage them smartly. Some type of [Dependency Injection] mechanism might be of great help, but please consider the [possible drawbacks][Dependency Injection drawbacks] as well. DI configuration should be part of the [*Infrastructure* sector](#infrastructure) or of a general bootstrap process, stored somewhere outside the layer directories altogether. 142 | 143 | 144 | ### Naming conventions 145 | 146 | The following special components (and their files) must be named after their role: 147 | 148 | * Interfaces must use the **`Interface`** suffix (e.g. `MyCustomInterface`) 149 | * Traits must use the **`Trait`** suffix (e.g. `MyCustomTrait`) 150 | * Factories must use the **`Factory`** suffix (e.g. `MyCustomFactory`). Public factory method names must use the `create` prefix (e.g. `createFromParams`). 151 | 152 | 153 | ## Considerations for PHP implementations 154 | 155 | *Note: I mostly use the Clear Architecture for projects written in PHP but it should be easy to adapt its principles to other environments as well. Please let me know if you succeed (or fail) in doing so.* 156 | 157 | * Stick to commonly agreed coding style rules like [PSR-1] and [PSR-2]. Consider using code quality checkers like [Scrutinizer], [Code Climate] etc. Have a look at my [Clear Architecture Yeoman Generator] to speed up the installation and configuration of these tools. 158 | * Apply [PSR-4] autoloading standards with `` being the **base directory** corresponding to the **namespace prefix** (e.g. `Jkphl\MyApp`). Follow the next point to get autoloading for free. 159 | * Use [Composer] as the principal dependency manager for your projects. By default, Composer installs package dependencies into the top-level `vendor` directory. 160 | * When providing a CLI, check out Composer's [vendor binary features]. 161 | * Use **environment variables** for configuration purposes (respectively the [phpdotenv] library or one of its equivalents). 162 | 163 | 164 | ## Recommended readings 165 | 166 | * [S.O.L.I.D. Software Development, One Step at a Time][S.O.L.I.D. Software Development] by Derek Bailey 167 | * [Clean Architecture in PHP] by Kristopher Wilson 168 | * [Domain-Driven Design in PHP] by Carlos Buenosvinos et al. 169 | 170 | ## Legal 171 | 172 | Copyright © 2017 Joschi Kuphal / [@jkphl](https://twitter.com/jkphl). Licensed under the terms of the [MIT license](LICENSE.txt). Originally published at at https://jkphl.is/articles/clear-architecture-php 173 | 174 | [ADR]: http://pmjones.io/adr/ "Action-Domain-Responder by Paul M. Jones" 175 | [Clean Architecture in PHP]: https://leanpub.com/cleanphp "Clean Architecture in PHP by Kristopher Wilson" 176 | [Clean Architecture]: https://8thlight.com/blog/uncle-bob/2012/08/13/the-clean-architecture.html "The Clean Architecture by Robert C. Martin" 177 | [Clear Architecture Yeoman Generator]: https://github.com/jkphl/generator-cleanphp "Clear Architecture PHP Project Yeoman Generator by Joschi Kuphal" 178 | [CLI]: https://en.wikipedia.org/wiki/Command-line_interface "Command-line Interface on Wikipedia" 179 | [Code Climate]: https://codeclimate.com/ "Automated code review | Code Climate" 180 | [Composer]: https://getcomposer.org "Composer — Dependency Manager for PHP" 181 | [Constant definitions]: https://en.wikipedia.org/wiki/Constant_(computer_programming) "Constants on Wikipedia" 182 | [database]: https://en.wikipedia.org/wiki/Database "Database on Wikipedia" 183 | [Dependency Injection]: https://en.wikipedia.org/wiki/Dependency_injection "Dependency Injection on Wikipedia" 184 | [Dependency Injection drawbacks]: https://sites.google.com/site/unclebobconsultingllc/blogs-by-robert-martin/dependency-injection-inversion "Dependency Injection Inversion by Robert C. Martin" 185 | [Dependency Inversion Principle]: https://en.wikipedia.org/wiki/Dependency_inversion_principle "Dependency Inversion Principle on Wikipedia" 186 | [Domain-Driven Design in PHP]: https://leanpub.com/ddd-in-php "Domain-Driven Design in PHP by Carlos Buenosvinos et al." 187 | [Domain-Driven Design]: https://en.wikipedia.org/wiki/Domain-driven_design "Domain Driven Design on Wikipedia" 188 | [**Domain** objects & services]: https://en.wikipedia.org/wiki/Domain_model "Domain model on Wikipedia" 189 | [Exceptions]: https://en.wikipedia.org/wiki/Exception_handling "Exception handling on Wikipedia" 190 | [Facades]: https://en.wikipedia.org/wiki/Facade_pattern "Facade pattern on Wikipedia" 191 | [Factories]: https://en.wikipedia.org/wiki/Factory_(object-oriented_programming) "Factories on Wikipedia" 192 | [FinTS]: https://en.wikipedia.org/wiki/FinTS "FinTS on Wikipedia" 193 | [frameworks]: https://en.wikipedia.org/wiki/Software_framework "Software framework on Wikipedia" 194 | [GUI]: https://en.wikipedia.org/wiki/Graphical_user_interface "Graphical User Interface on Wikipedia" 195 | [Hexagonal Architecture]: http://alistair.cockburn.us/Hexagonal+architecture "The Hexagonal Architecture by Alistair Cockburn" 196 | [Interfaces]: https://en.wikipedia.org/wiki/Protocol_(object-oriented_programming) "Interfaces on Wikipedia" 197 | [libraries]: https://en.wikipedia.org/wiki/Library_(computing) "Library on Wikipedia" 198 | [MVC]: https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller "Model-View-Controller on Wikipedia" 199 | [MVP]: https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93presenter "Model-View-Presenter on Wikipedia" 200 | [objects]: https://en.wikipedia.org/wiki/Object-oriented_programming#Objects_and_classes "Object oriented programming on Wikipedia" 201 | [polymorphism]: https://en.wikipedia.org/wiki/Polymorphism_(computer_science) "Polymorphism on Wikipedia" 202 | [Onion Architecture]: http://jeffreypalermo.com/blog/the-onion-architecture-part-1/ "The Onion Architecture by Jeffrey Palermo" 203 | [Persistence]: https://en.wikipedia.org/wiki/Persistence_(computer_science) "Persistence on Wikipedia" 204 | [phpdotenv]: https://github.com/vlucas/phpdotenv "vlucas/phpdotenv by Vance Lucas on Github" 205 | [PSR-1]: http://www.php-fig.org/psr/psr-1/ "PSR-1: Basic Coding Standard - PHP-FIG" 206 | [PSR-2]: http://www.php-fig.org/psr/psr-2/ "PSR-2: Coding Style Guide - PHP-FIG" 207 | [PSR-4]: http://www.php-fig.org/psr/psr-4/ "PSR-4: Autoloader - PHP-FIG" 208 | [REST API]: https://en.wikipedia.org/wiki/Representational_state_transfer "Representational state transfer on Wikipedia" 209 | [S.O.L.I.D. Software Development]: http://www.codemag.com/article/1001061 "S.O.L.I.D. Software Development, One Step at a Time by Derek Bailey" 210 | [Scrutinizer]: https://scrutinizer-ci.com/ "Measure and Improve Code Quality continuously with Scrutinizer" 211 | [Template engines]: https://en.wikipedia.org/wiki/Template_processor "Template processor on Wikipedia" 212 | [testing your application]: https://en.wikipedia.org/wiki/Software_testing#Testing_levels "Testing levels on Wikipedia" 213 | [traits]: https://en.wikipedia.org/wiki/Trait_(computer_programming) "Traits on Wikipedia" 214 | [typing]: https://en.wikipedia.org/wiki/Type_system "Type system on Wikipedia" 215 | [UpperCamelCase]: https://en.wikipedia.org/wiki/Camel_case "Camel case on Wikipedia" 216 | [Use cases]: https://en.wikipedia.org/wiki/Use_case "Use case on Wikipedia" 217 | [vendor binary features]: https://getcomposer.org/doc/articles/vendor-binaries.md "Vendor binaries and the vendor/bin directory - Composer" 218 | -------------------------------------------------------------------------------- /images/clear-architecture-dependency-rule.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 358 | 359 | 360 | 362 | 363 | 364 | 366 | 368 | 369 | 370 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 397 | Ports 398 | 401 | Tests 402 | 405 | Infrastructure 406 | 409 | Database Persistence Framework 3rd Paarty Lib 410 | 411 | 413 | Controller Presenter CLI API REST 414 | 415 | 416 | 417 | 418 | 419 | 420 | 648 | 649 | 650 | 652 | 653 | 654 | 656 | Application 657 | 658 | 661 | 667 | 673 | 674 | 677 | 680 | 686 | 689 | 692 | 696 | 700 | 701 | 702 | 703 | 704 | 705 | 807 | 808 | 809 | 811 | 812 | 813 | 814 | 818 | 821 | 826 | 831 | 833 | 836 | 837 | 838 | 839 | 840 | 845 | 849 | 852 | 855 | 860 | 861 | 862 | 864 | 868 | 873 | 876 | 881 | 882 | 883 | 884 | 888 | 891 | 894 | 899 | 904 | 907 | 910 | 914 | 918 | 921 | 925 | 928 | 932 | 933 | 934 | 935 | 937 | 938 | 939 | 940 | 941 | 942 | 943 | 944 | 945 | 946 | 947 | 949 | 950 | 951 | 952 | 953 | 954 | 955 | 956 | 957 | 958 | 959 | 961 | 962 | 963 | 964 | 965 | 966 | 967 | 968 | 969 | 970 | 971 | 972 | 973 | 974 | 975 | 976 | 977 | 978 | 979 | 980 | 981 | 982 | 983 | 984 | 985 | 986 | 987 | 988 | 989 | -------------------------------------------------------------------------------- /images/clear-architecture-dependency-inversion.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 76 | 80 | 84 | 85 | 87 | 90 | 95 | 98 | 100 | 103 | 106 | 107 | 108 | 109 | 110 | 111 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 169 | 172 | 177 | 182 | 184 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 236 | 241 | 245 | 249 | 252 | 255 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 306 | 311 | 315 | 319 | 322 | 325 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 347 | 351 | 354 | 358 | 361 | 365 | 369 | 372 | 376 | 380 | 381 | 382 | 383 | 384 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 427 | 432 | 436 | 440 | 443 | 446 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 498 | 501 | 505 | 508 | 511 | 516 | 519 | 523 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | 574 | 579 | 583 | 587 | 590 | 593 | 599 | 600 | 601 | 602 | 603 | 608 | 612 | 615 | 619 | 622 | 626 | 630 | 633 | 637 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 658 | 662 | 663 | 667 | 673 | 677 | 681 | 685 | 689 | 690 | 691 | 692 | 693 | 694 | 695 | 696 | 697 | 698 | 699 | 700 | 701 | 702 | 704 | 710 | 713 | 716 | 720 | 721 | 724 | 727 | 730 | 733 | 735 | 739 | 742 | 745 | 747 | 750 | 753 | 758 | 759 | 763 | 767 | 771 | 775 | 778 | 782 | 786 | 789 | 792 | 796 | 799 | 803 | 804 | 809 | 812 | 814 | 817 | 820 | 824 | 827 | 829 | 833 | 834 | 835 | 836 | 838 | 844 | 847 | 850 | 854 | 857 | 860 | 864 | 868 | 872 | 876 | 879 | 883 | 887 | 890 | 893 | 897 | 899 | 902 | 904 | 908 | 911 | 915 | 917 | 920 | 923 | 927 | 931 | 934 | 938 | 940 | 943 | 949 | 954 | 957 | 959 | 962 | 965 | 969 | 972 | 975 | 980 | 983 | 987 | 988 | 993 | 997 | 1001 | 1004 | 1007 | 1012 | 1015 | 1018 | 1022 | 1026 | 1029 | 1031 | 1033 | 1036 | 1040 | 1043 | 1044 | 1049 | 1053 | 1057 | 1058 | 1059 | 1060 | --------------------------------------------------------------------------------