├── .gitignore ├── .gitmodules ├── BFS ├── Dockerfile.build └── tictac.bin ├── CL ├── Cargo.toml ├── Dockerfile ├── Dockerfile.launcher ├── README.md ├── STEP1 ├── launcher.sh ├── launcher_funcs.sh └── src │ └── main.rs ├── CS ├── 2048 │ ├── .gitignore │ ├── .jshintrc │ ├── CONTRIBUTING.md │ ├── LICENSE.txt │ ├── README.md │ ├── Rakefile │ ├── favicon.ico │ ├── index.html │ ├── js │ │ ├── animframe_polyfill.js │ │ ├── application.js │ │ ├── bind_polyfill.js │ │ ├── classlist_polyfill.js │ │ ├── game_manager.js │ │ ├── grid.js │ │ ├── html_actuator.js │ │ ├── keyboard_input_manager.js │ │ ├── local_storage_manager.js │ │ └── tile.js │ ├── meta │ │ ├── apple-touch-icon.png │ │ ├── apple-touch-startup-image-640x1096.png │ │ └── apple-touch-startup-image-640x920.png │ └── style │ │ ├── fonts │ │ ├── ClearSans-Bold-webfont.eot │ │ ├── ClearSans-Bold-webfont.svg │ │ ├── ClearSans-Bold-webfont.woff │ │ ├── ClearSans-Light-webfont.eot │ │ ├── ClearSans-Light-webfont.svg │ │ ├── ClearSans-Light-webfont.woff │ │ ├── ClearSans-Regular-webfont.eot │ │ ├── ClearSans-Regular-webfont.svg │ │ ├── ClearSans-Regular-webfont.woff │ │ └── clear-sans.css │ │ ├── helpers.scss │ │ ├── main.css │ │ └── main.scss ├── Dockerfile └── README.md ├── DFD ├── Dockerfile.new └── requirements.new ├── DSM ├── Dockerfile ├── Dockerfile.build ├── README.md ├── main └── main.go ├── DYT ├── .idea │ ├── .name │ ├── compiler.xml │ ├── copyright │ │ └── profiles_settings.xml │ ├── encodings.xml │ ├── libraries │ │ └── Maven__junit_junit_3_8_1.xml │ ├── misc.xml │ ├── modules.xml │ └── workspace.xml ├── FizzBuzz.iml ├── STEP1 ├── STEP2 ├── STEP3 ├── alias.sh ├── pom.xml └── src │ ├── main │ └── java │ │ └── com │ │ └── github │ │ └── containerspatterns │ │ └── App.java │ └── test │ └── java │ └── com │ └── github │ └── containerspatterns │ └── AppTest.java ├── ECC └── Dockerfile ├── EFE ├── Dockerfile.exec └── Dockerfile.shell ├── HS ├── STEP1 └── print_host_info.sh ├── LICENSE ├── MS ├── 2048 │ ├── .gitignore │ ├── .jshintrc │ ├── CONTRIBUTING.md │ ├── LICENSE.txt │ ├── README.md │ ├── Rakefile │ ├── favicon.ico │ ├── index.html │ ├── js │ │ ├── animframe_polyfill.js │ │ ├── application.js │ │ ├── bind_polyfill.js │ │ ├── classlist_polyfill.js │ │ ├── game_manager.js │ │ ├── grid.js │ │ ├── html_actuator.js │ │ ├── keyboard_input_manager.js │ │ ├── local_storage_manager.js │ │ └── tile.js │ ├── meta │ │ ├── apple-touch-icon.png │ │ ├── apple-touch-startup-image-640x1096.png │ │ └── apple-touch-startup-image-640x920.png │ └── style │ │ ├── fonts │ │ ├── ClearSans-Bold-webfont.eot │ │ ├── ClearSans-Bold-webfont.svg │ │ ├── ClearSans-Bold-webfont.woff │ │ ├── ClearSans-Light-webfont.eot │ │ ├── ClearSans-Light-webfont.svg │ │ ├── ClearSans-Light-webfont.woff │ │ ├── ClearSans-Regular-webfont.eot │ │ ├── ClearSans-Regular-webfont.svg │ │ ├── ClearSans-Regular-webfont.woff │ │ └── clear-sans.css │ │ ├── helpers.scss │ │ ├── main.css │ │ └── main.scss ├── Dockerfile ├── README.md └── STEP1 ├── OBI ├── Dockerfile ├── FizzBuzz.iml ├── pom.xml └── src │ ├── main │ └── java │ │ └── com │ │ └── github │ │ └── containerspatterns │ │ └── App.java │ └── test │ └── java │ └── com │ └── github │ └── containerspatterns │ └── AppTest.java ├── README.md ├── S2I ├── Dockerfile ├── README.md ├── STEP1 ├── STEP2 ├── pom.xml └── src │ └── main │ └── java │ └── Source2Image.java ├── SC ├── README.md ├── STEP1 ├── STEP2 └── STEP3 ├── TODO.md ├── dockermeetupnantes-2016-11-29.md ├── favicon.ico ├── images ├── 5container5languages-recap.png ├── arnoldc-logo-small.jpeg ├── box.jpg ├── che-mini.png ├── che-mini.svg ├── che.png ├── che2.svg ├── cl.svg ├── clock.jpg ├── containerslanguages.png ├── cp-BFS.png ├── cp-CL-1.svg ├── cp-CL-2.svg ├── cp-CL-3.svg ├── cp-CL.png ├── cp-CL1.svg ├── cp-CL2.svg ├── cp-CL3.svg ├── cp-CL4.svg ├── cp-CL5.svg ├── cp-CL6.svg ├── cp-CS.png ├── cp-DFD.png ├── cp-DSM.png ├── cp-DYT.png ├── cp-DYT.svg ├── cp-ECC.png ├── cp-EFE.png ├── cp-HS.png ├── cp-MS.png ├── cp-MS.svg ├── cp-OBI.png ├── cp-PeriodicTable.png ├── cp-S2I.svg ├── cp-SC.svg ├── dexec.gif ├── docker-logo-orig.png ├── docker-mini.png ├── docker.png ├── dupond-dupont-1.png ├── dupond-dupont-2.png ├── dupond-dupont-3.png ├── dyt.svg ├── fivelangs.png ├── fizzbuzz.png ├── fizzbuzzterminals.png ├── frustration.gif ├── github.png ├── gof-mod.png ├── gof.jpg ├── gof.png ├── golang-logo-mini.png ├── golang-logo-small.png ├── golang-logo-with-name.jpeg ├── haikel-round.png ├── haskell-logo-mini.png ├── haskell-logo-small.png ├── haskell-logo-with-name.png ├── hp.png ├── hpe.png ├── hs.svg ├── javascript-logo-mini.png ├── javascript-logo-small.png ├── jshell-logo-small.png ├── languagestacks.png ├── languagestacks2.png ├── mario-round.png ├── mario_pixels.png ├── mike-round.png ├── ms.svg ├── osio-mini.png ├── osio-mini.svg ├── osio.jpg ├── periodictable-nolegend.svg ├── periodictable-partial.svg ├── periodictable.png ├── periodictable.svg ├── redhat.png ├── rust-logo-mini.png ├── rust-logo-small.png ├── rust-logo-with-name.png ├── rust.jpg ├── s2i.svg ├── say-works-on-my-machine.jpg ├── sc.svg ├── swift-logo-small.png ├── swift-logo.png ├── swift.png ├── twitter.png ├── whoami.svg └── zenika.png ├── index.html ├── rivieradev-2018-05-17.md ├── run.sh └── snowcampio-2018-01-26.md /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.jar 3 | target 4 | .classpath 5 | .settings 6 | .project 7 | .vscode 8 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "BFS/tictac"] 2 | path = BFS/tictac 3 | url = https://github.com/emilevauge/tictac 4 | [submodule "DFD/flask-todolist"] 5 | path = DFD/flask-todolist 6 | url = https://github.com/polyfunc/flask-todolist.git 7 | -------------------------------------------------------------------------------- /BFS/Dockerfile.build: -------------------------------------------------------------------------------- 1 | ## docker build -t tictac-build -f Dockerfile.build . 2 | ## docker run -v $(pwd):/code/ -w /code/ tictac-build 3 | 4 | FROM golang:1.6.3 5 | 6 | RUN go get github.com/parnurzeal/gorequest 7 | 8 | ENV CGO_ENABLED "0" 9 | ENV GOOS "linux" 10 | ENV GOARCH "amd64" 11 | 12 | ENTRYPOINT ["go"] 13 | CMD ["build","-a","--installsuffix","cgo","--ldflags=\"-s\"","-o","tictac"] 14 | -------------------------------------------------------------------------------- /BFS/tictac.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/BFS/tictac.bin -------------------------------------------------------------------------------- /CL/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "sample" 3 | version = "1.0.0" 4 | 5 | [dependencies] 6 | bson = "0.10.0" 7 | mongodb = "0.3.7" -------------------------------------------------------------------------------- /CL/Dockerfile: -------------------------------------------------------------------------------- 1 | # To build it 2 | # docker build -t containerspatterns/rust . 3 | # 4 | # To run it 5 | # docker run --rm -t --link mongodb containerspatterns/rust 6 | 7 | FROM rust:1.26 8 | 9 | RUN apt-get update && \ 10 | apt-get install -y build-essential cmake git libssl-dev git 11 | 12 | RUN wget http://dist.libuv.org/dist/v1.14.0/libuv-v1.14.0.tar.gz && \ 13 | tar xzf libuv-v1.14.0.tar.gz && \ 14 | cd libuv-v1.14.0 && \ 15 | sh autogen.sh && \ 16 | ./configure && \ 17 | make install 18 | 19 | RUN git clone https://github.com/datastax/cpp-driver.git && \ 20 | mkdir cpp-driver/build && \ 21 | cd cpp-driver/build && \ 22 | cmake .. && \ 23 | make && \ 24 | make install 25 | 26 | ADD / /code/ 27 | 28 | WORKDIR /code/ 29 | 30 | RUN cargo build 31 | 32 | CMD /code/target/debug/sample -------------------------------------------------------------------------------- /CL/Dockerfile.launcher: -------------------------------------------------------------------------------- 1 | # To build it 2 | # docker build -t containerspatterns/rust-launcher -f Dockerfile.launcher . 3 | # 4 | # To run it 5 | # docker run -v /var/run/docker.sock:/var/run/docker.sock --rm containerspatterns/rust-launcher start 6 | FROM alpine 7 | 8 | ADD /launcher.sh /app/launcher.sh 9 | ADD /launcher_funcs.sh /app/launcher_funcs.sh 10 | 11 | RUN apk add --no-cache \ 12 | ca-certificates \ 13 | curl \ 14 | openssl 15 | 16 | ENV DOCKER_CHANNEL stable 17 | ENV DOCKER_VERSION 18.03.1-ce 18 | 19 | RUN curl -fL -o docker.tgz "https://download.docker.com/linux/static/${DOCKER_CHANNEL}/x86_64/docker-${DOCKER_VERSION}.tgz" && \ 20 | tar --extract \ 21 | --file docker.tgz \ 22 | --strip-components 1 \ 23 | --directory /usr/local/bin/ 24 | 25 | ENTRYPOINT ["/app/launcher.sh"] 26 | CMD ["start"] -------------------------------------------------------------------------------- /CL/README.md: -------------------------------------------------------------------------------- 1 | # Rust and Containers launcher pattern 2 | 3 | In this repository we share an example of "Rust and Containers launcher pattern" for the workshop [5 containers patterns for 5 languages](https://l0rd.github.io/talks/containers-and-languages/index_en.html). 4 | 5 | ```bash 6 | # The following steps are commented out because 7 | # not necessary to run the example 8 | # git clone https://github.com/l0rd/containerspatterns/ 9 | # cd containerspatterns/CL 10 | 11 | # Build the rust app and package it withing a Docker image 12 | # docker build -t containerspatterns/rust-app . 13 | 14 | # Build the launcher image 15 | # docker build -t containerspatterns/rust-launcher -f Dockerfile.launcher . 16 | 17 | # Run the launcher 18 | docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \ 19 | containerspatterns/rust-launcher start 20 | ``` 21 | -------------------------------------------------------------------------------- /CL/STEP1: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | echo -n 'docker run -v $(pwd):/src/ \ 4 | -v /var/run/docker.sock:/var/run/docker.sock \ 5 | containerspatterns/rust-launcher' | pbcopy 6 | -------------------------------------------------------------------------------- /CL/launcher.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | launcher_dir="$(dirname "$0")" 3 | source "$launcher_dir/launcher_funcs.sh" 4 | 5 | MONGODB_CONTAINER_NAME="mongodb" 6 | 7 | # Run mongodb 8 | cid=$(docker run -d --name ${MONGODB_CONTAINER_NAME} mongo:3.2.10) 9 | 10 | # Wait until it has started 11 | wait_until_container_is_running ${cid} 12 | if ! container_is_running ${cid}; then 13 | echo "ERROR: Timeout waiting for mongodb container to start." 14 | exit 1 15 | else 16 | echo "Mongodb has started and is running in container ${cid}" 17 | fi 18 | 19 | # Smoke test mongodb to confirm it'working fine 20 | check_mongod_is_fine ${cid} 21 | 22 | # Run our application 23 | cid=$(docker run -d --link ${MONGODB_CONTAINER_NAME}:mongodb containerspatterns/rust-app) 24 | 25 | # Wait until it has started 26 | wait_until_container_is_running ${cid} 27 | if ! container_is_running ${cid}; then 28 | echo "ERROR: Timeout waiting for the rust container to start." 29 | exit 1 30 | else 31 | echo "Our rust app has started and is running in container ${cid}" 32 | fi 33 | -------------------------------------------------------------------------------- /CL/launcher_funcs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | container_is_running() { 4 | CONTAINER_ID=${1} 5 | if [ "$(docker ps -qa -f "status=running" -f "id=${CONTAINER_ID}" | wc -l)" -eq 0 ]; then 6 | return 1 7 | else 8 | return 0 9 | fi 10 | } 11 | 12 | wait_until_container_is_running() { 13 | CONTAINER_ID=${1} 14 | CONTAINER_START_TIMEOUT=10 15 | 16 | ELAPSED=0 17 | until container_is_running ${CONTAINER_ID} || [ ${ELAPSED} -eq "${CONTAINER_START_TIMEOUT}" ]; do 18 | sleep 1 19 | ELAPSED=$((ELAPSED+1)) 20 | done 21 | } 22 | 23 | check_mongod_is_fine() { 24 | CONTAINER_ID=${1} 25 | if [ "$(docker exec ${CONTAINER_ID} pidof mongod | wc -l)" -eq 0 ]; then 26 | return 1 27 | else 28 | return 0 29 | fi 30 | } 31 | -------------------------------------------------------------------------------- /CL/src/main.rs: -------------------------------------------------------------------------------- 1 | #[macro_use(bson, doc)] 2 | extern crate bson; 3 | extern crate mongodb; 4 | 5 | use bson::Bson; 6 | use mongodb::{Client, ThreadedClient}; 7 | use mongodb::db::ThreadedDatabase; 8 | use std::time::Duration; 9 | use std::thread; 10 | 11 | fn main() { 12 | let client = Client::connect("mongodb", 27017) 13 | .ok().expect("Failed to initialize standalone client."); 14 | 15 | let coll = client.db("test").collection("movies"); 16 | 17 | loop { 18 | 19 | let doc = doc! { "title" => "Jaws", 20 | "array" => [ 1, 2, 3 ] }; 21 | 22 | // Insert document into 'test.movies' collection 23 | coll.insert_one(doc.clone(), None) 24 | .ok().expect("Failed to insert document."); 25 | 26 | println!("Inserted movie in db"); 27 | 28 | // Find the document and receive a cursor 29 | let mut cursor = coll.find(Some(doc.clone()), None) 30 | .ok().expect("Failed to execute find."); 31 | 32 | let item = cursor.next(); 33 | 34 | // cursor.next() returns an Option> 35 | match item { 36 | Some(Ok(doc)) => match doc.get("title") { 37 | Some(&Bson::String(ref title)) => println!("Fetched movie {} from db", title), 38 | _ => panic!("Expected title to be a string!"), 39 | }, 40 | Some(Err(_)) => panic!("Failed to get next from server!"), 41 | None => panic!("Server returned no results!"), 42 | } 43 | 44 | thread::sleep(Duration::from_secs(2)) 45 | } 46 | } -------------------------------------------------------------------------------- /CS/2048/.gitignore: -------------------------------------------------------------------------------- 1 | .sass-cache/ 2 | -------------------------------------------------------------------------------- /CS/2048/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "esnext": true, 3 | "indent": 2, 4 | "maxlen": 80, 5 | "freeze": true, 6 | "camelcase": true, 7 | "unused": true, 8 | "eqnull": true, 9 | "proto": true, 10 | "supernew": true, 11 | "noyield": true, 12 | "evil": true, 13 | "node": true, 14 | "boss": true, 15 | "expr": true, 16 | "loopfunc": true, 17 | "white": true, 18 | "maxdepth": 4 19 | } 20 | -------------------------------------------------------------------------------- /CS/2048/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | Changes and improvements are more than welcome! Feel free to fork and open a pull request. 3 | 4 | Please follow the house rules to have a bigger chance of your contribution being merged. 5 | 6 | ## House rules 7 | 8 | ### How to make changes 9 | - To make changes, create a new branch based on `master` (do not create one from `gh-pages` unless strictly necessary) and make them there, then create a Pull Request to master. 10 | `gh-pages` is different from master in that it contains sharing features, analytics and other things that have no direct bearing with the game. `master` is the "pure" version of the game. 11 | - If you want to modify the CSS, please edit the SCSS files present in `style/`: `main.scss` and others. Don't edit the `main.css`, because it's supposed to be generated. 12 | In order to compile your SCSS modifications, you need to use the `sass` gem (install it by running `gem install sass` once Ruby is installed). 13 | To run SASS, simply use the following command: 14 | `sass --unix-newlines --watch style/main.scss` 15 | SASS will automatically recompile your css when changed. 16 | - `Rakefile` contains some tasks that help during development. Feel free to add useful tasks if needed. 17 | - Please use 2-space indentation when editing the JavaScript. A `.jshintrc` file is present, which will help your code to follow the guidelines if you install and run `jshint`. 18 | - Please test your modification thoroughly before submitting your Pull Request. 19 | 20 | ### Changes that might not be accepted 21 | We have to be conservative with the core game. This means that some modifications won't be merged, or will have to be evaluated carefully before being merged: 22 | 23 | - Undo/redo features 24 | - Save/reload features 25 | - Changes to how the tiles look or their contents 26 | - Changes to the layout 27 | - Changes to the grid size 28 | 29 | ### Changes that are welcome 30 | - Bug fixes 31 | - Compatibility improvements 32 | - "Under the hood" enhancements 33 | - Small changes that don't have an impact on the core gameplay 34 | -------------------------------------------------------------------------------- /CS/2048/LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Gabriele Cirulli 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 | -------------------------------------------------------------------------------- /CS/2048/README.md: -------------------------------------------------------------------------------- 1 | # 2048 2 | A small clone of [1024](https://play.google.com/store/apps/details?id=com.veewo.a1024), based on [Saming's 2048](http://saming.fr/p/2048/) (also a clone). 3 | 4 | Made just for fun. [Play it here!](http://gabrielecirulli.github.io/2048/) 5 | 6 | The official app can also be found on the [Play Store](https://play.google.com/store/apps/details?id=com.gabrielecirulli.app2048) and [App Store!](https://itunes.apple.com/us/app/2048-by-gabriele-cirulli/id868076805) 7 | 8 | ### Contributions 9 | 10 | [Anna Harren](https://github.com/iirelu/) and [sigod](https://github.com/sigod) are maintainers for this repository. 11 | 12 | Other notable contributors: 13 | 14 | - [TimPetricola](https://github.com/TimPetricola) added best score storage 15 | - [chrisprice](https://github.com/chrisprice) added custom code for swipe handling on mobile 16 | - [marcingajda](https://github.com/marcingajda) made swipes work on Windows Phone 17 | - [mgarciaisaia](https://github.com/mgarciaisaia) added support for Android 2.3 18 | 19 | Many thanks to [rayhaanj](https://github.com/rayhaanj), [Mechazawa](https://github.com/Mechazawa), [grant](https://github.com/grant), [remram44](https://github.com/remram44) and [ghoullier](https://github.com/ghoullier) for the many other good contributions. 20 | 21 | ### Screenshot 22 | 23 |

24 | Screenshot 25 |

26 | 27 | That screenshot is fake, by the way. I never reached 2048 :smile: 28 | 29 | ## Contributing 30 | Changes and improvements are more than welcome! Feel free to fork and open a pull request. Please make your changes in a specific branch and request to pull into `master`! If you can, please make sure the game fully works before sending the PR, as that will help speed up the process. 31 | 32 | You can find the same information in the [contributing guide.](https://github.com/gabrielecirulli/2048/blob/master/CONTRIBUTING.md) 33 | 34 | ## License 35 | 2048 is licensed under the [MIT license.](https://github.com/gabrielecirulli/2048/blob/master/LICENSE.txt) 36 | 37 | ## Donations 38 | I made this in my spare time, and it's hosted on GitHub (which means I don't have any hosting costs), but if you enjoyed the game and feel like buying me coffee, you can donate at my BTC address: `1Ec6onfsQmoP9kkL3zkpB6c5sA4PVcXU2i`. Thank you very much! 39 | -------------------------------------------------------------------------------- /CS/2048/Rakefile: -------------------------------------------------------------------------------- 1 | require "date" 2 | 3 | namespace :appcache do 4 | desc "update the date in the appcache file (in the gh-pages branch)" 5 | task :update do 6 | appcache = File.read("cache.appcache") 7 | updated = "# Updated: #{DateTime.now}" 8 | 9 | File.write("cache.appcache", appcache.sub(/^# Updated:.*$/, updated)) 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /CS/2048/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/CS/2048/favicon.ico -------------------------------------------------------------------------------- /CS/2048/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 2048 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 |
22 |

2048

23 |
24 |
0
25 |
0
26 |
27 |
28 | 29 |
30 |

Join the numbers and get to the 2048 tile!

31 | New Game 32 |
33 | 34 |
35 |
36 |

37 |
38 | Keep going 39 | Try again 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 | How to play: Use your arrow keys to move the tiles. When two tiles with the same number touch, they merge into one! 77 |

78 |
79 |

80 | Note: This site is the official version of 2048. You can play it on your phone via http://git.io/2048. All other apps or sites are derivatives or fakes, and should be used with caution. 81 |

82 |
83 |

84 | Created by Gabriele Cirulli. Based on 1024 by Veewo Studio and conceptually similar to Threes by Asher Vollmer. 85 |

86 |
87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /CS/2048/js/animframe_polyfill.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var lastTime = 0; 3 | var vendors = ['webkit', 'moz']; 4 | for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { 5 | window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame']; 6 | window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || 7 | window[vendors[x] + 'CancelRequestAnimationFrame']; 8 | } 9 | 10 | if (!window.requestAnimationFrame) { 11 | window.requestAnimationFrame = function (callback) { 12 | var currTime = new Date().getTime(); 13 | var timeToCall = Math.max(0, 16 - (currTime - lastTime)); 14 | var id = window.setTimeout(function () { 15 | callback(currTime + timeToCall); 16 | }, 17 | timeToCall); 18 | lastTime = currTime + timeToCall; 19 | return id; 20 | }; 21 | } 22 | 23 | if (!window.cancelAnimationFrame) { 24 | window.cancelAnimationFrame = function (id) { 25 | clearTimeout(id); 26 | }; 27 | } 28 | }()); 29 | -------------------------------------------------------------------------------- /CS/2048/js/application.js: -------------------------------------------------------------------------------- 1 | // Wait till the browser is ready to render the game (avoids glitches) 2 | window.requestAnimationFrame(function () { 3 | new GameManager(4, KeyboardInputManager, HTMLActuator, LocalStorageManager); 4 | }); 5 | -------------------------------------------------------------------------------- /CS/2048/js/bind_polyfill.js: -------------------------------------------------------------------------------- 1 | Function.prototype.bind = Function.prototype.bind || function (target) { 2 | var self = this; 3 | return function (args) { 4 | if (!(args instanceof Array)) { 5 | args = [args]; 6 | } 7 | self.apply(target, args); 8 | }; 9 | }; 10 | -------------------------------------------------------------------------------- /CS/2048/js/classlist_polyfill.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | if (typeof window.Element === "undefined" || 3 | "classList" in document.documentElement) { 4 | return; 5 | } 6 | 7 | var prototype = Array.prototype, 8 | push = prototype.push, 9 | splice = prototype.splice, 10 | join = prototype.join; 11 | 12 | function DOMTokenList(el) { 13 | this.el = el; 14 | // The className needs to be trimmed and split on whitespace 15 | // to retrieve a list of classes. 16 | var classes = el.className.replace(/^\s+|\s+$/g, '').split(/\s+/); 17 | for (var i = 0; i < classes.length; i++) { 18 | push.call(this, classes[i]); 19 | } 20 | } 21 | 22 | DOMTokenList.prototype = { 23 | add: function (token) { 24 | if (this.contains(token)) return; 25 | push.call(this, token); 26 | this.el.className = this.toString(); 27 | }, 28 | contains: function (token) { 29 | return this.el.className.indexOf(token) != -1; 30 | }, 31 | item: function (index) { 32 | return this[index] || null; 33 | }, 34 | remove: function (token) { 35 | if (!this.contains(token)) return; 36 | for (var i = 0; i < this.length; i++) { 37 | if (this[i] == token) break; 38 | } 39 | splice.call(this, i, 1); 40 | this.el.className = this.toString(); 41 | }, 42 | toString: function () { 43 | return join.call(this, ' '); 44 | }, 45 | toggle: function (token) { 46 | if (!this.contains(token)) { 47 | this.add(token); 48 | } else { 49 | this.remove(token); 50 | } 51 | 52 | return this.contains(token); 53 | } 54 | }; 55 | 56 | window.DOMTokenList = DOMTokenList; 57 | 58 | function defineElementGetter(obj, prop, getter) { 59 | if (Object.defineProperty) { 60 | Object.defineProperty(obj, prop, { 61 | get: getter 62 | }); 63 | } else { 64 | obj.__defineGetter__(prop, getter); 65 | } 66 | } 67 | 68 | defineElementGetter(HTMLElement.prototype, 'classList', function () { 69 | return new DOMTokenList(this); 70 | }); 71 | })(); 72 | -------------------------------------------------------------------------------- /CS/2048/js/game_manager.js: -------------------------------------------------------------------------------- 1 | function GameManager(size, InputManager, Actuator, StorageManager) { 2 | this.size = size; // Size of the grid 3 | this.inputManager = new InputManager; 4 | this.storageManager = new StorageManager; 5 | this.actuator = new Actuator; 6 | 7 | this.startTiles = 2; 8 | 9 | this.inputManager.on("move", this.move.bind(this)); 10 | this.inputManager.on("restart", this.restart.bind(this)); 11 | this.inputManager.on("keepPlaying", this.keepPlaying.bind(this)); 12 | 13 | this.setup(); 14 | } 15 | 16 | // Restart the game 17 | GameManager.prototype.restart = function () { 18 | this.storageManager.clearGameState(); 19 | this.actuator.continueGame(); // Clear the game won/lost message 20 | this.setup(); 21 | }; 22 | 23 | // Keep playing after winning (allows going over 2048) 24 | GameManager.prototype.keepPlaying = function () { 25 | this.keepPlaying = true; 26 | this.actuator.continueGame(); // Clear the game won/lost message 27 | }; 28 | 29 | // Return true if the game is lost, or has won and the user hasn't kept playing 30 | GameManager.prototype.isGameTerminated = function () { 31 | return this.over || (this.won && !this.keepPlaying); 32 | }; 33 | 34 | // Set up the game 35 | GameManager.prototype.setup = function () { 36 | var previousState = this.storageManager.getGameState(); 37 | 38 | // Reload the game from a previous game if present 39 | if (previousState) { 40 | this.grid = new Grid(previousState.grid.size, 41 | previousState.grid.cells); // Reload grid 42 | this.score = previousState.score; 43 | this.over = previousState.over; 44 | this.won = previousState.won; 45 | this.keepPlaying = previousState.keepPlaying; 46 | } else { 47 | this.grid = new Grid(this.size); 48 | this.score = 0; 49 | this.over = false; 50 | this.won = false; 51 | this.keepPlaying = false; 52 | 53 | // Add the initial tiles 54 | this.addStartTiles(); 55 | } 56 | 57 | // Update the actuator 58 | this.actuate(); 59 | }; 60 | 61 | // Set up the initial tiles to start the game with 62 | GameManager.prototype.addStartTiles = function () { 63 | for (var i = 0; i < this.startTiles; i++) { 64 | this.addRandomTile(); 65 | } 66 | }; 67 | 68 | // Adds a tile in a random position 69 | GameManager.prototype.addRandomTile = function () { 70 | if (this.grid.cellsAvailable()) { 71 | var value = Math.random() < 0.9 ? 2 : 4; 72 | var tile = new Tile(this.grid.randomAvailableCell(), value); 73 | 74 | this.grid.insertTile(tile); 75 | } 76 | }; 77 | 78 | // Sends the updated grid to the actuator 79 | GameManager.prototype.actuate = function () { 80 | if (this.storageManager.getBestScore() < this.score) { 81 | this.storageManager.setBestScore(this.score); 82 | } 83 | 84 | // Clear the state when the game is over (game over only, not win) 85 | if (this.over) { 86 | this.storageManager.clearGameState(); 87 | } else { 88 | this.storageManager.setGameState(this.serialize()); 89 | } 90 | 91 | this.actuator.actuate(this.grid, { 92 | score: this.score, 93 | over: this.over, 94 | won: this.won, 95 | bestScore: this.storageManager.getBestScore(), 96 | terminated: this.isGameTerminated() 97 | }); 98 | 99 | }; 100 | 101 | // Represent the current game as an object 102 | GameManager.prototype.serialize = function () { 103 | return { 104 | grid: this.grid.serialize(), 105 | score: this.score, 106 | over: this.over, 107 | won: this.won, 108 | keepPlaying: this.keepPlaying 109 | }; 110 | }; 111 | 112 | // Save all tile positions and remove merger info 113 | GameManager.prototype.prepareTiles = function () { 114 | this.grid.eachCell(function (x, y, tile) { 115 | if (tile) { 116 | tile.mergedFrom = null; 117 | tile.savePosition(); 118 | } 119 | }); 120 | }; 121 | 122 | // Move a tile and its representation 123 | GameManager.prototype.moveTile = function (tile, cell) { 124 | this.grid.cells[tile.x][tile.y] = null; 125 | this.grid.cells[cell.x][cell.y] = tile; 126 | tile.updatePosition(cell); 127 | }; 128 | 129 | // Move tiles on the grid in the specified direction 130 | GameManager.prototype.move = function (direction) { 131 | // 0: up, 1: right, 2: down, 3: left 132 | var self = this; 133 | 134 | if (this.isGameTerminated()) return; // Don't do anything if the game's over 135 | 136 | var cell, tile; 137 | 138 | var vector = this.getVector(direction); 139 | var traversals = this.buildTraversals(vector); 140 | var moved = false; 141 | 142 | // Save the current tile positions and remove merger information 143 | this.prepareTiles(); 144 | 145 | // Traverse the grid in the right direction and move tiles 146 | traversals.x.forEach(function (x) { 147 | traversals.y.forEach(function (y) { 148 | cell = { x: x, y: y }; 149 | tile = self.grid.cellContent(cell); 150 | 151 | if (tile) { 152 | var positions = self.findFarthestPosition(cell, vector); 153 | var next = self.grid.cellContent(positions.next); 154 | 155 | // Only one merger per row traversal? 156 | if (next && next.value === tile.value && !next.mergedFrom) { 157 | var merged = new Tile(positions.next, tile.value * 2); 158 | merged.mergedFrom = [tile, next]; 159 | 160 | self.grid.insertTile(merged); 161 | self.grid.removeTile(tile); 162 | 163 | // Converge the two tiles' positions 164 | tile.updatePosition(positions.next); 165 | 166 | // Update the score 167 | self.score += merged.value; 168 | 169 | // The mighty 2048 tile 170 | if (merged.value === 2048) self.won = true; 171 | } else { 172 | self.moveTile(tile, positions.farthest); 173 | } 174 | 175 | if (!self.positionsEqual(cell, tile)) { 176 | moved = true; // The tile moved from its original cell! 177 | } 178 | } 179 | }); 180 | }); 181 | 182 | if (moved) { 183 | this.addRandomTile(); 184 | 185 | if (!this.movesAvailable()) { 186 | this.over = true; // Game over! 187 | } 188 | 189 | this.actuate(); 190 | } 191 | }; 192 | 193 | // Get the vector representing the chosen direction 194 | GameManager.prototype.getVector = function (direction) { 195 | // Vectors representing tile movement 196 | var map = { 197 | 0: { x: 0, y: -1 }, // Up 198 | 1: { x: 1, y: 0 }, // Right 199 | 2: { x: 0, y: 1 }, // Down 200 | 3: { x: -1, y: 0 } // Left 201 | }; 202 | 203 | return map[direction]; 204 | }; 205 | 206 | // Build a list of positions to traverse in the right order 207 | GameManager.prototype.buildTraversals = function (vector) { 208 | var traversals = { x: [], y: [] }; 209 | 210 | for (var pos = 0; pos < this.size; pos++) { 211 | traversals.x.push(pos); 212 | traversals.y.push(pos); 213 | } 214 | 215 | // Always traverse from the farthest cell in the chosen direction 216 | if (vector.x === 1) traversals.x = traversals.x.reverse(); 217 | if (vector.y === 1) traversals.y = traversals.y.reverse(); 218 | 219 | return traversals; 220 | }; 221 | 222 | GameManager.prototype.findFarthestPosition = function (cell, vector) { 223 | var previous; 224 | 225 | // Progress towards the vector direction until an obstacle is found 226 | do { 227 | previous = cell; 228 | cell = { x: previous.x + vector.x, y: previous.y + vector.y }; 229 | } while (this.grid.withinBounds(cell) && 230 | this.grid.cellAvailable(cell)); 231 | 232 | return { 233 | farthest: previous, 234 | next: cell // Used to check if a merge is required 235 | }; 236 | }; 237 | 238 | GameManager.prototype.movesAvailable = function () { 239 | return this.grid.cellsAvailable() || this.tileMatchesAvailable(); 240 | }; 241 | 242 | // Check for available matches between tiles (more expensive check) 243 | GameManager.prototype.tileMatchesAvailable = function () { 244 | var self = this; 245 | 246 | var tile; 247 | 248 | for (var x = 0; x < this.size; x++) { 249 | for (var y = 0; y < this.size; y++) { 250 | tile = this.grid.cellContent({ x: x, y: y }); 251 | 252 | if (tile) { 253 | for (var direction = 0; direction < 4; direction++) { 254 | var vector = self.getVector(direction); 255 | var cell = { x: x + vector.x, y: y + vector.y }; 256 | 257 | var other = self.grid.cellContent(cell); 258 | 259 | if (other && other.value === tile.value) { 260 | return true; // These two tiles can be merged 261 | } 262 | } 263 | } 264 | } 265 | } 266 | 267 | return false; 268 | }; 269 | 270 | GameManager.prototype.positionsEqual = function (first, second) { 271 | return first.x === second.x && first.y === second.y; 272 | }; 273 | -------------------------------------------------------------------------------- /CS/2048/js/grid.js: -------------------------------------------------------------------------------- 1 | function Grid(size, previousState) { 2 | this.size = size; 3 | this.cells = previousState ? this.fromState(previousState) : this.empty(); 4 | } 5 | 6 | // Build a grid of the specified size 7 | Grid.prototype.empty = function () { 8 | var cells = []; 9 | 10 | for (var x = 0; x < this.size; x++) { 11 | var row = cells[x] = []; 12 | 13 | for (var y = 0; y < this.size; y++) { 14 | row.push(null); 15 | } 16 | } 17 | 18 | return cells; 19 | }; 20 | 21 | Grid.prototype.fromState = function (state) { 22 | var cells = []; 23 | 24 | for (var x = 0; x < this.size; x++) { 25 | var row = cells[x] = []; 26 | 27 | for (var y = 0; y < this.size; y++) { 28 | var tile = state[x][y]; 29 | row.push(tile ? new Tile(tile.position, tile.value) : null); 30 | } 31 | } 32 | 33 | return cells; 34 | }; 35 | 36 | // Find the first available random position 37 | Grid.prototype.randomAvailableCell = function () { 38 | var cells = this.availableCells(); 39 | 40 | if (cells.length) { 41 | return cells[Math.floor(Math.random() * cells.length)]; 42 | } 43 | }; 44 | 45 | Grid.prototype.availableCells = function () { 46 | var cells = []; 47 | 48 | this.eachCell(function (x, y, tile) { 49 | if (!tile) { 50 | cells.push({ x: x, y: y }); 51 | } 52 | }); 53 | 54 | return cells; 55 | }; 56 | 57 | // Call callback for every cell 58 | Grid.prototype.eachCell = function (callback) { 59 | for (var x = 0; x < this.size; x++) { 60 | for (var y = 0; y < this.size; y++) { 61 | callback(x, y, this.cells[x][y]); 62 | } 63 | } 64 | }; 65 | 66 | // Check if there are any cells available 67 | Grid.prototype.cellsAvailable = function () { 68 | return !!this.availableCells().length; 69 | }; 70 | 71 | // Check if the specified cell is taken 72 | Grid.prototype.cellAvailable = function (cell) { 73 | return !this.cellOccupied(cell); 74 | }; 75 | 76 | Grid.prototype.cellOccupied = function (cell) { 77 | return !!this.cellContent(cell); 78 | }; 79 | 80 | Grid.prototype.cellContent = function (cell) { 81 | if (this.withinBounds(cell)) { 82 | return this.cells[cell.x][cell.y]; 83 | } else { 84 | return null; 85 | } 86 | }; 87 | 88 | // Inserts a tile at its position 89 | Grid.prototype.insertTile = function (tile) { 90 | this.cells[tile.x][tile.y] = tile; 91 | }; 92 | 93 | Grid.prototype.removeTile = function (tile) { 94 | this.cells[tile.x][tile.y] = null; 95 | }; 96 | 97 | Grid.prototype.withinBounds = function (position) { 98 | return position.x >= 0 && position.x < this.size && 99 | position.y >= 0 && position.y < this.size; 100 | }; 101 | 102 | Grid.prototype.serialize = function () { 103 | var cellState = []; 104 | 105 | for (var x = 0; x < this.size; x++) { 106 | var row = cellState[x] = []; 107 | 108 | for (var y = 0; y < this.size; y++) { 109 | row.push(this.cells[x][y] ? this.cells[x][y].serialize() : null); 110 | } 111 | } 112 | 113 | return { 114 | size: this.size, 115 | cells: cellState 116 | }; 117 | }; 118 | -------------------------------------------------------------------------------- /CS/2048/js/html_actuator.js: -------------------------------------------------------------------------------- 1 | function HTMLActuator() { 2 | this.tileContainer = document.querySelector(".tile-container"); 3 | this.scoreContainer = document.querySelector(".score-container"); 4 | this.bestContainer = document.querySelector(".best-container"); 5 | this.messageContainer = document.querySelector(".game-message"); 6 | 7 | this.score = 0; 8 | } 9 | 10 | HTMLActuator.prototype.actuate = function (grid, metadata) { 11 | var self = this; 12 | 13 | window.requestAnimationFrame(function () { 14 | self.clearContainer(self.tileContainer); 15 | 16 | grid.cells.forEach(function (column) { 17 | column.forEach(function (cell) { 18 | if (cell) { 19 | self.addTile(cell); 20 | } 21 | }); 22 | }); 23 | 24 | self.updateScore(metadata.score); 25 | self.updateBestScore(metadata.bestScore); 26 | 27 | if (metadata.terminated) { 28 | if (metadata.over) { 29 | self.message(false); // You lose 30 | } else if (metadata.won) { 31 | self.message(true); // You win! 32 | } 33 | } 34 | 35 | }); 36 | }; 37 | 38 | // Continues the game (both restart and keep playing) 39 | HTMLActuator.prototype.continueGame = function () { 40 | this.clearMessage(); 41 | }; 42 | 43 | HTMLActuator.prototype.clearContainer = function (container) { 44 | while (container.firstChild) { 45 | container.removeChild(container.firstChild); 46 | } 47 | }; 48 | 49 | HTMLActuator.prototype.addTile = function (tile) { 50 | var self = this; 51 | 52 | var wrapper = document.createElement("div"); 53 | var inner = document.createElement("div"); 54 | var position = tile.previousPosition || { x: tile.x, y: tile.y }; 55 | var positionClass = this.positionClass(position); 56 | 57 | // We can't use classlist because it somehow glitches when replacing classes 58 | var classes = ["tile", "tile-" + tile.value, positionClass]; 59 | 60 | if (tile.value > 2048) classes.push("tile-super"); 61 | 62 | this.applyClasses(wrapper, classes); 63 | 64 | inner.classList.add("tile-inner"); 65 | inner.textContent = tile.value; 66 | 67 | if (tile.previousPosition) { 68 | // Make sure that the tile gets rendered in the previous position first 69 | window.requestAnimationFrame(function () { 70 | classes[2] = self.positionClass({ x: tile.x, y: tile.y }); 71 | self.applyClasses(wrapper, classes); // Update the position 72 | }); 73 | } else if (tile.mergedFrom) { 74 | classes.push("tile-merged"); 75 | this.applyClasses(wrapper, classes); 76 | 77 | // Render the tiles that merged 78 | tile.mergedFrom.forEach(function (merged) { 79 | self.addTile(merged); 80 | }); 81 | } else { 82 | classes.push("tile-new"); 83 | this.applyClasses(wrapper, classes); 84 | } 85 | 86 | // Add the inner part of the tile to the wrapper 87 | wrapper.appendChild(inner); 88 | 89 | // Put the tile on the board 90 | this.tileContainer.appendChild(wrapper); 91 | }; 92 | 93 | HTMLActuator.prototype.applyClasses = function (element, classes) { 94 | element.setAttribute("class", classes.join(" ")); 95 | }; 96 | 97 | HTMLActuator.prototype.normalizePosition = function (position) { 98 | return { x: position.x + 1, y: position.y + 1 }; 99 | }; 100 | 101 | HTMLActuator.prototype.positionClass = function (position) { 102 | position = this.normalizePosition(position); 103 | return "tile-position-" + position.x + "-" + position.y; 104 | }; 105 | 106 | HTMLActuator.prototype.updateScore = function (score) { 107 | this.clearContainer(this.scoreContainer); 108 | 109 | var difference = score - this.score; 110 | this.score = score; 111 | 112 | this.scoreContainer.textContent = this.score; 113 | 114 | if (difference > 0) { 115 | var addition = document.createElement("div"); 116 | addition.classList.add("score-addition"); 117 | addition.textContent = "+" + difference; 118 | 119 | this.scoreContainer.appendChild(addition); 120 | } 121 | }; 122 | 123 | HTMLActuator.prototype.updateBestScore = function (bestScore) { 124 | this.bestContainer.textContent = bestScore; 125 | }; 126 | 127 | HTMLActuator.prototype.message = function (won) { 128 | var type = won ? "game-won" : "game-over"; 129 | var message = won ? "You win!" : "Game over!"; 130 | 131 | this.messageContainer.classList.add(type); 132 | this.messageContainer.getElementsByTagName("p")[0].textContent = message; 133 | }; 134 | 135 | HTMLActuator.prototype.clearMessage = function () { 136 | // IE only takes one value to remove at a time. 137 | this.messageContainer.classList.remove("game-won"); 138 | this.messageContainer.classList.remove("game-over"); 139 | }; 140 | -------------------------------------------------------------------------------- /CS/2048/js/keyboard_input_manager.js: -------------------------------------------------------------------------------- 1 | function KeyboardInputManager() { 2 | this.events = {}; 3 | 4 | if (window.navigator.msPointerEnabled) { 5 | //Internet Explorer 10 style 6 | this.eventTouchstart = "MSPointerDown"; 7 | this.eventTouchmove = "MSPointerMove"; 8 | this.eventTouchend = "MSPointerUp"; 9 | } else { 10 | this.eventTouchstart = "touchstart"; 11 | this.eventTouchmove = "touchmove"; 12 | this.eventTouchend = "touchend"; 13 | } 14 | 15 | this.listen(); 16 | } 17 | 18 | KeyboardInputManager.prototype.on = function (event, callback) { 19 | if (!this.events[event]) { 20 | this.events[event] = []; 21 | } 22 | this.events[event].push(callback); 23 | }; 24 | 25 | KeyboardInputManager.prototype.emit = function (event, data) { 26 | var callbacks = this.events[event]; 27 | if (callbacks) { 28 | callbacks.forEach(function (callback) { 29 | callback(data); 30 | }); 31 | } 32 | }; 33 | 34 | KeyboardInputManager.prototype.listen = function () { 35 | var self = this; 36 | 37 | var map = { 38 | 38: 0, // Up 39 | 39: 1, // Right 40 | 40: 2, // Down 41 | 37: 3, // Left 42 | 75: 0, // Vim up 43 | 76: 1, // Vim right 44 | 74: 2, // Vim down 45 | 72: 3, // Vim left 46 | 87: 0, // W 47 | 68: 1, // D 48 | 83: 2, // S 49 | 65: 3 // A 50 | }; 51 | 52 | // Respond to direction keys 53 | document.addEventListener("keydown", function (event) { 54 | var modifiers = event.altKey || event.ctrlKey || event.metaKey || 55 | event.shiftKey; 56 | var mapped = map[event.which]; 57 | 58 | if (!modifiers) { 59 | if (mapped !== undefined) { 60 | event.preventDefault(); 61 | self.emit("move", mapped); 62 | } 63 | } 64 | 65 | // R key restarts the game 66 | if (!modifiers && event.which === 82) { 67 | self.restart.call(self, event); 68 | } 69 | }); 70 | 71 | // Respond to button presses 72 | this.bindButtonPress(".retry-button", this.restart); 73 | this.bindButtonPress(".restart-button", this.restart); 74 | this.bindButtonPress(".keep-playing-button", this.keepPlaying); 75 | 76 | // Respond to swipe events 77 | var touchStartClientX, touchStartClientY; 78 | var gameContainer = document.getElementsByClassName("game-container")[0]; 79 | 80 | gameContainer.addEventListener(this.eventTouchstart, function (event) { 81 | if ((!window.navigator.msPointerEnabled && event.touches.length > 1) || 82 | event.targetTouches.length > 1) { 83 | return; // Ignore if touching with more than 1 finger 84 | } 85 | 86 | if (window.navigator.msPointerEnabled) { 87 | touchStartClientX = event.pageX; 88 | touchStartClientY = event.pageY; 89 | } else { 90 | touchStartClientX = event.touches[0].clientX; 91 | touchStartClientY = event.touches[0].clientY; 92 | } 93 | 94 | event.preventDefault(); 95 | }); 96 | 97 | gameContainer.addEventListener(this.eventTouchmove, function (event) { 98 | event.preventDefault(); 99 | }); 100 | 101 | gameContainer.addEventListener(this.eventTouchend, function (event) { 102 | if ((!window.navigator.msPointerEnabled && event.touches.length > 0) || 103 | event.targetTouches.length > 0) { 104 | return; // Ignore if still touching with one or more fingers 105 | } 106 | 107 | var touchEndClientX, touchEndClientY; 108 | 109 | if (window.navigator.msPointerEnabled) { 110 | touchEndClientX = event.pageX; 111 | touchEndClientY = event.pageY; 112 | } else { 113 | touchEndClientX = event.changedTouches[0].clientX; 114 | touchEndClientY = event.changedTouches[0].clientY; 115 | } 116 | 117 | var dx = touchEndClientX - touchStartClientX; 118 | var absDx = Math.abs(dx); 119 | 120 | var dy = touchEndClientY - touchStartClientY; 121 | var absDy = Math.abs(dy); 122 | 123 | if (Math.max(absDx, absDy) > 10) { 124 | // (right : left) : (down : up) 125 | self.emit("move", absDx > absDy ? (dx > 0 ? 1 : 3) : (dy > 0 ? 2 : 0)); 126 | } 127 | }); 128 | }; 129 | 130 | KeyboardInputManager.prototype.restart = function (event) { 131 | event.preventDefault(); 132 | this.emit("restart"); 133 | }; 134 | 135 | KeyboardInputManager.prototype.keepPlaying = function (event) { 136 | event.preventDefault(); 137 | this.emit("keepPlaying"); 138 | }; 139 | 140 | KeyboardInputManager.prototype.bindButtonPress = function (selector, fn) { 141 | var button = document.querySelector(selector); 142 | button.addEventListener("click", fn.bind(this)); 143 | button.addEventListener(this.eventTouchend, fn.bind(this)); 144 | }; 145 | -------------------------------------------------------------------------------- /CS/2048/js/local_storage_manager.js: -------------------------------------------------------------------------------- 1 | window.fakeStorage = { 2 | _data: {}, 3 | 4 | setItem: function (id, val) { 5 | return this._data[id] = String(val); 6 | }, 7 | 8 | getItem: function (id) { 9 | return this._data.hasOwnProperty(id) ? this._data[id] : undefined; 10 | }, 11 | 12 | removeItem: function (id) { 13 | return delete this._data[id]; 14 | }, 15 | 16 | clear: function () { 17 | return this._data = {}; 18 | } 19 | }; 20 | 21 | function LocalStorageManager() { 22 | this.bestScoreKey = "bestScore"; 23 | this.gameStateKey = "gameState"; 24 | 25 | var supported = this.localStorageSupported(); 26 | this.storage = supported ? window.localStorage : window.fakeStorage; 27 | } 28 | 29 | LocalStorageManager.prototype.localStorageSupported = function () { 30 | var testKey = "test"; 31 | var storage = window.localStorage; 32 | 33 | try { 34 | storage.setItem(testKey, "1"); 35 | storage.removeItem(testKey); 36 | return true; 37 | } catch (error) { 38 | return false; 39 | } 40 | }; 41 | 42 | // Best score getters/setters 43 | LocalStorageManager.prototype.getBestScore = function () { 44 | return this.storage.getItem(this.bestScoreKey) || 0; 45 | }; 46 | 47 | LocalStorageManager.prototype.setBestScore = function (score) { 48 | this.storage.setItem(this.bestScoreKey, score); 49 | }; 50 | 51 | // Game state getters/setters and clearing 52 | LocalStorageManager.prototype.getGameState = function () { 53 | var stateJSON = this.storage.getItem(this.gameStateKey); 54 | return stateJSON ? JSON.parse(stateJSON) : null; 55 | }; 56 | 57 | LocalStorageManager.prototype.setGameState = function (gameState) { 58 | this.storage.setItem(this.gameStateKey, JSON.stringify(gameState)); 59 | }; 60 | 61 | LocalStorageManager.prototype.clearGameState = function () { 62 | this.storage.removeItem(this.gameStateKey); 63 | }; 64 | -------------------------------------------------------------------------------- /CS/2048/js/tile.js: -------------------------------------------------------------------------------- 1 | function Tile(position, value) { 2 | this.x = position.x; 3 | this.y = position.y; 4 | this.value = value || 2; 5 | 6 | this.previousPosition = null; 7 | this.mergedFrom = null; // Tracks tiles that merged together 8 | } 9 | 10 | Tile.prototype.savePosition = function () { 11 | this.previousPosition = { x: this.x, y: this.y }; 12 | }; 13 | 14 | Tile.prototype.updatePosition = function (position) { 15 | this.x = position.x; 16 | this.y = position.y; 17 | }; 18 | 19 | Tile.prototype.serialize = function () { 20 | return { 21 | position: { 22 | x: this.x, 23 | y: this.y 24 | }, 25 | value: this.value 26 | }; 27 | }; 28 | -------------------------------------------------------------------------------- /CS/2048/meta/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/CS/2048/meta/apple-touch-icon.png -------------------------------------------------------------------------------- /CS/2048/meta/apple-touch-startup-image-640x1096.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/CS/2048/meta/apple-touch-startup-image-640x1096.png -------------------------------------------------------------------------------- /CS/2048/meta/apple-touch-startup-image-640x920.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/CS/2048/meta/apple-touch-startup-image-640x920.png -------------------------------------------------------------------------------- /CS/2048/style/fonts/ClearSans-Bold-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/CS/2048/style/fonts/ClearSans-Bold-webfont.eot -------------------------------------------------------------------------------- /CS/2048/style/fonts/ClearSans-Bold-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/CS/2048/style/fonts/ClearSans-Bold-webfont.woff -------------------------------------------------------------------------------- /CS/2048/style/fonts/ClearSans-Light-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/CS/2048/style/fonts/ClearSans-Light-webfont.eot -------------------------------------------------------------------------------- /CS/2048/style/fonts/ClearSans-Light-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/CS/2048/style/fonts/ClearSans-Light-webfont.woff -------------------------------------------------------------------------------- /CS/2048/style/fonts/ClearSans-Regular-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/CS/2048/style/fonts/ClearSans-Regular-webfont.eot -------------------------------------------------------------------------------- /CS/2048/style/fonts/ClearSans-Regular-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/CS/2048/style/fonts/ClearSans-Regular-webfont.woff -------------------------------------------------------------------------------- /CS/2048/style/fonts/clear-sans.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: "Clear Sans"; 3 | src: url("ClearSans-Light-webfont.eot"); 4 | src: url("ClearSans-Light-webfont.eot?#iefix") format("embedded-opentype"), 5 | url("ClearSans-Light-webfont.svg#clear_sans_lightregular") format("svg"), 6 | url("ClearSans-Light-webfont.woff") format("woff"); 7 | font-weight: 200; 8 | font-style: normal; 9 | } 10 | 11 | @font-face { 12 | font-family: "Clear Sans"; 13 | src: url("ClearSans-Regular-webfont.eot"); 14 | src: url("ClearSans-Regular-webfont.eot?#iefix") format("embedded-opentype"), 15 | url("ClearSans-Regular-webfont.svg#clear_sansregular") format("svg"), 16 | url("ClearSans-Regular-webfont.woff") format("woff"); 17 | font-weight: normal; 18 | font-style: normal; 19 | } 20 | 21 | @font-face { 22 | font-family: "Clear Sans"; 23 | src: url("ClearSans-Bold-webfont.eot"); 24 | src: url("ClearSans-Bold-webfont.eot?#iefix") format("embedded-opentype"), 25 | url("ClearSans-Bold-webfont.svg#clear_sansbold") format("svg"), 26 | url("ClearSans-Bold-webfont.woff") format("woff"); 27 | font-weight: 700; 28 | font-style: normal; 29 | } 30 | 31 | -------------------------------------------------------------------------------- /CS/2048/style/helpers.scss: -------------------------------------------------------------------------------- 1 | // Exponent 2 | // From: https://github.com/Team-Sass/Sassy-math/blob/master/sass/math.scss#L36 3 | 4 | @function exponent($base, $exponent) { 5 | // reset value 6 | $value: $base; 7 | // positive intergers get multiplied 8 | @if $exponent > 1 { 9 | @for $i from 2 through $exponent { 10 | $value: $value * $base; } } 11 | // negitive intergers get divided. A number divided by itself is 1 12 | @if $exponent < 1 { 13 | @for $i from 0 through -$exponent { 14 | $value: $value / $base; } } 15 | // return the last value written 16 | @return $value; 17 | } 18 | 19 | @function pow($base, $exponent) { 20 | @return exponent($base, $exponent); 21 | } 22 | 23 | // Transition mixins 24 | @mixin transition($args...) { 25 | -webkit-transition: $args; 26 | -moz-transition: $args; 27 | transition: $args; 28 | } 29 | 30 | @mixin transition-property($args...) { 31 | -webkit-transition-property: $args; 32 | -moz-transition-property: $args; 33 | transition-property: $args; 34 | } 35 | 36 | @mixin animation($args...) { 37 | -webkit-animation: $args; 38 | -moz-animation: $args; 39 | animation: $args; 40 | } 41 | 42 | @mixin animation-fill-mode($args...) { 43 | -webkit-animation-fill-mode: $args; 44 | -moz-animation-fill-mode: $args; 45 | animation-fill-mode: $args; 46 | } 47 | 48 | @mixin transform($args...) { 49 | -webkit-transform: $args; 50 | -moz-transform: $args; 51 | -ms-transform: $args; 52 | transform: $args; 53 | } 54 | 55 | // Keyframe animations 56 | @mixin keyframes($animation-name) { 57 | @-webkit-keyframes $animation-name { 58 | @content; 59 | } 60 | @-moz-keyframes $animation-name { 61 | @content; 62 | } 63 | @keyframes $animation-name { 64 | @content; 65 | } 66 | } 67 | 68 | // Media queries 69 | @mixin smaller($width) { 70 | @media screen and (max-width: $width) { 71 | @content; 72 | } 73 | } 74 | 75 | // Clearfix 76 | @mixin clearfix { 77 | &:after { 78 | content: ""; 79 | display: block; 80 | clear: both; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /CS/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM httpd 2 | COPY /2048/ /usr/local/apache2/htdocs/ -------------------------------------------------------------------------------- /CS/README.md: -------------------------------------------------------------------------------- 1 | # Javascript and Copy Sources container pattern 2 | 3 | In this repository we share an example of "Javascript and Mount the Sources container pattern" for the workshop [5 containers patterns for 5 languages](https://l0rd.github.io/talks/containers-and-languages/index_en.html). 4 | 5 | ```bash 6 | # The following steps are commented out because 7 | # not necessary to run the example 8 | # git clone --recursive https://github.com/containerslanguages/js 9 | 10 | docker build -t 2048 . 11 | docker run -d -p 8080:80 2048 12 | ``` 13 | -------------------------------------------------------------------------------- /DFD/Dockerfile.new: -------------------------------------------------------------------------------- 1 | FROM alpine:3.4 2 | 3 | # from https://github.com/frol/docker-alpine-python3 4 | RUN apk add --no-cache python3 && \ 5 | python3 -m ensurepip && \ 6 | rm -r /usr/lib/python*/ensurepip && \ 7 | pip3 install --upgrade pip setuptools && \ 8 | rm -r /root/.cache 9 | 10 | # Copy the application's requirements.txt and run pip to install all 11 | # dependencies into the virtualenv. 12 | ADD requirements.txt /code/requirements.txt 13 | RUN pip install -r /code/requirements.txt 14 | 15 | ADD . /code 16 | WORKDIR /code 17 | 18 | CMD ["gunicorn", "todolist:app", "-w","2","-b",":8000"] -------------------------------------------------------------------------------- /DFD/requirements.new: -------------------------------------------------------------------------------- 1 | Flask==0.11.1 2 | Flask-Login==0.3.2 3 | Flask-SQLAlchemy==2.1 4 | Flask-WTF==0.12 5 | Flask-Migrate==2.0.0 6 | gunicorn==19.6.0 7 | -------------------------------------------------------------------------------- /DSM/Dockerfile: -------------------------------------------------------------------------------- 1 | # docker build -t containerspatterns/dsm . 2 | # docker run -t -v /var/run/docker.sock:/var/run/docker.sock containerspatterns/dsm 3 | FROM scratch 4 | COPY main / 5 | CMD ["/main"] 6 | 7 | -------------------------------------------------------------------------------- /DSM/Dockerfile.build: -------------------------------------------------------------------------------- 1 | # docker build -t containerslanguages/golang-build -f Dockerfile.build . 2 | # docker run -v $(pwd):/code/ -w /code/ containerslanguages/golang-build -o /code/main main.go 3 | FROM golang:1.6.3 4 | 5 | RUN go get github.com/fsouza/go-dockerclient \ 6 | github.com/docker/go-units 7 | 8 | ENV CGO_ENABLED "0" 9 | ENV GOOS "linux" 10 | ENV GOARCH "amd64" 11 | ENTRYPOINT ["go","build","-a","-installsuffix", "cgo"] -------------------------------------------------------------------------------- /DSM/README.md: -------------------------------------------------------------------------------- 1 | # Go and Mount the Docker Socket container pattern 2 | 3 | In this repository we share an example of "Go and Mount the Docker Socket container pattern" for the workshop [5 containers patterns for 5 languages](https://l0rd.github.io/talks/containers-and-languages/index_en.html). 4 | 5 | ```bash 6 | # The following steps are commented out because 7 | # not necessary to run the example 8 | # git clone https://github.com/containerslanguages/go 9 | 10 | # Build the main.go 11 | # docker build -t containerslanguages/golang-build -f Dockerfile.build . 12 | # docker run -v $(pwd):/code/ -w /code/ containerslanguages/golang-build -o /code/main main.go 13 | 14 | # Build the image from scratch 15 | # docker build -t containerslanguages/golang . 16 | 17 | docker run -t -v /var/run/docker.sock:/var/run/docker.sock \ 18 | containerslanguages/golang 19 | ``` 20 | -------------------------------------------------------------------------------- /DSM/main: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/DSM/main -------------------------------------------------------------------------------- /DSM/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "strings" 7 | "text/tabwriter" 8 | "time" 9 | "github.com/fsouza/go-dockerclient" 10 | "github.com/docker/go-units" 11 | ) 12 | 13 | func Short(s string, i int) string { 14 | s = strings.TrimPrefix(s, "sha256:") 15 | runes := []rune( s ) 16 | if len( runes ) > i { 17 | return string( runes[:i] ) 18 | } 19 | return s 20 | } 21 | 22 | func main() { 23 | endpoint := "unix:///var/run/docker.sock" 24 | client, _ := docker.NewClient(endpoint) 25 | w := new(tabwriter.Writer) 26 | w.Init(os.Stdout, 20, 1, 3, ' ', 0) 27 | 28 | ticker := time.NewTicker(time.Second) 29 | quit := make(chan bool) 30 | 31 | fmt.Printf("\033[s") 32 | go func() { 33 | for { 34 | select { 35 | case <- ticker.C: 36 | conts, _ := client.ListContainers(docker.ListContainersOptions{All: false}) 37 | fmt.Printf("\033[u") 38 | fmt.Printf("\033[J") 39 | titles := "CONTAINER ID\tIMAGE\tCOMMAND\tCREATED\tSTATUS\tNAMES\n" 40 | fmt.Fprintf(w, titles) 41 | for _, cont := range conts { 42 | ID := Short(cont.ID, 12) 43 | img := Short(cont.Image, 12) 44 | cmd := Short(cont.Command, 14) 45 | created := units.HumanDuration(time.Now().UTC().Sub(time.Unix(cont.Created, 0))) 46 | status := Short(cont.Status, 12) 47 | names := Short(cont.Names[0][1:], 12) 48 | fmt.Fprintf(w, "%s\t%s\t\"%s\"\t%s ago\t%s\t%s\n", ID, img, cmd, created, status, names) 49 | w.Flush() 50 | } 51 | 52 | } 53 | 54 | } 55 | }() 56 | <-quit 57 | } 58 | -------------------------------------------------------------------------------- /DYT/.idea/.name: -------------------------------------------------------------------------------- 1 | FizzBuzz -------------------------------------------------------------------------------- /DYT/.idea/compiler.xml: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /DYT/.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /DYT/.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /DYT/.idea/libraries/Maven__junit_junit_3_8_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /DYT/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 1.8 31 | 32 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /DYT/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /DYT/FizzBuzz.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /DYT/STEP1: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | echo -n 'alias mvn="docker run \ 4 | -v $(pwd):/usr/src \ 5 | -w /usr/src \ 6 | -v ~/.m2:/root/.m2 \ 7 | maven:3.3.3-jdk-8 \ 8 | mvn"' | pbcopy 9 | -------------------------------------------------------------------------------- /DYT/STEP2: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | echo -n 'alias java="docker run \ 4 | -v $(pwd):/usr/src \ 5 | -w /usr/src \ 6 | -v ~/.m2:/root/.m2 \ 7 | openjdk:11-jre-slim \ 8 | java"' | pbcopy 9 | -------------------------------------------------------------------------------- /DYT/STEP3: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | echo -n 'java -cp target/fizz-buzz-1.0-SNAPSHOT.jar \ 4 | com.github.containerspatterns.App' | pbcopy 5 | -------------------------------------------------------------------------------- /DYT/alias.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | alias mvndock="docker run \ 4 | -v $(pwd):/usr/src \ 5 | -v ~/.m2:/root/.m2 \ 6 | -w /usr/src \ 7 | maven:3.3.3-jdk-8 \ 8 | mvn" 9 | 10 | # mvndock -version 11 | # mvn version 12 | 13 | # mvndock clean install 14 | # java -cp target/fizz-buzz-1.0-SNAPSHOT.jar com.github.containerspatterns.App -------------------------------------------------------------------------------- /DYT/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | com.github.containerspatterns 6 | fizz-buzz 7 | 1.0-SNAPSHOT 8 | jar 9 | 10 | fizz-buzz 11 | http://maven.apache.org 12 | 13 | 14 | UTF-8 15 | 16 | 17 | 18 | 19 | junit 20 | junit 21 | 3.8.1 22 | test 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /DYT/src/main/java/com/github/containerspatterns/App.java: -------------------------------------------------------------------------------- 1 | package com.github.containerspatterns; 2 | 3 | /** 4 | * Hello world! 5 | * 6 | */ 7 | public class App 8 | { 9 | public static void main( String[] args ) 10 | { 11 | for (int i = 1; i <= 100; i++) { 12 | if (i % 3 == 0 && i % 5 == 0 ) { 13 | System.out.println("fizzbuzz"); 14 | } else if (i % 3 == 0 ) { 15 | System.out.println("fizz"); 16 | } else if (i % 5 == 0 ) { 17 | System.out.println("buzz"); 18 | } else { 19 | System.out.println(Integer.toString(i)); 20 | } 21 | 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /DYT/src/test/java/com/github/containerspatterns/AppTest.java: -------------------------------------------------------------------------------- 1 | package com.github.containerspatterns; 2 | 3 | import junit.framework.Test; 4 | import junit.framework.TestCase; 5 | import junit.framework.TestSuite; 6 | 7 | /** 8 | * Unit test for simple App. 9 | */ 10 | public class AppTest extends TestCase 11 | { 12 | /** 13 | * Create the test case 14 | * 15 | * @param testName name of the test case 16 | */ 17 | public AppTest( String testName ) 18 | { 19 | super( testName ); 20 | } 21 | 22 | /** 23 | * @return the suite of tests being tested 24 | */ 25 | public static Test suite() 26 | { 27 | return new TestSuite( AppTest.class ); 28 | } 29 | 30 | /** 31 | * Rigourous Test :-) 32 | */ 33 | public void testApp() 34 | { 35 | assertTrue( true ); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /ECC/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM hairyhenderson/figlet 2 | 3 | ENTRYPOINT ["figlet", "-c"] 4 | CMD ["-k", "nil"] 5 | -------------------------------------------------------------------------------- /EFE/Dockerfile.exec: -------------------------------------------------------------------------------- 1 | FROM httpd 2 | 3 | ENTRYPOINT ["httpd-foreground"] 4 | -------------------------------------------------------------------------------- /EFE/Dockerfile.shell: -------------------------------------------------------------------------------- 1 | FROM httpd 2 | 3 | ENTRYPOINT httpd-foreground 4 | -------------------------------------------------------------------------------- /HS/STEP1: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo -n 'docker run --net=host \ 4 | -v /:/hostfs/ \ 5 | --pid=host \ 6 | --uts=host \ 7 | --ipc=host \ 8 | -v $(pwd):/src/ \ 9 | alpine sh -c ". /src/print_host_info.sh"' | pbcopy 10 | -------------------------------------------------------------------------------- /HS/print_host_info.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | HOST_IP=$(ip a s eth0 | grep "inet " | cut -d " " -f 6 | cut -d "/" -f 1 ) 4 | echo "Host IP is ${HOST_IP}" 5 | 6 | HOST_HOSTNAME=$(hostname) 7 | echo "Host hostname is $HOST_HOSTNAME" 8 | 9 | echo "Host filesystem info:" 10 | df -k /hostfs/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Mario Loriedo 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /MS/2048/.gitignore: -------------------------------------------------------------------------------- 1 | .sass-cache/ 2 | -------------------------------------------------------------------------------- /MS/2048/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "esnext": true, 3 | "indent": 2, 4 | "maxlen": 80, 5 | "freeze": true, 6 | "camelcase": true, 7 | "unused": true, 8 | "eqnull": true, 9 | "proto": true, 10 | "supernew": true, 11 | "noyield": true, 12 | "evil": true, 13 | "node": true, 14 | "boss": true, 15 | "expr": true, 16 | "loopfunc": true, 17 | "white": true, 18 | "maxdepth": 4 19 | } 20 | -------------------------------------------------------------------------------- /MS/2048/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | Changes and improvements are more than welcome! Feel free to fork and open a pull request. 3 | 4 | Please follow the house rules to have a bigger chance of your contribution being merged. 5 | 6 | ## House rules 7 | 8 | ### How to make changes 9 | - To make changes, create a new branch based on `master` (do not create one from `gh-pages` unless strictly necessary) and make them there, then create a Pull Request to master. 10 | `gh-pages` is different from master in that it contains sharing features, analytics and other things that have no direct bearing with the game. `master` is the "pure" version of the game. 11 | - If you want to modify the CSS, please edit the SCSS files present in `style/`: `main.scss` and others. Don't edit the `main.css`, because it's supposed to be generated. 12 | In order to compile your SCSS modifications, you need to use the `sass` gem (install it by running `gem install sass` once Ruby is installed). 13 | To run SASS, simply use the following command: 14 | `sass --unix-newlines --watch style/main.scss` 15 | SASS will automatically recompile your css when changed. 16 | - `Rakefile` contains some tasks that help during development. Feel free to add useful tasks if needed. 17 | - Please use 2-space indentation when editing the JavaScript. A `.jshintrc` file is present, which will help your code to follow the guidelines if you install and run `jshint`. 18 | - Please test your modification thoroughly before submitting your Pull Request. 19 | 20 | ### Changes that might not be accepted 21 | We have to be conservative with the core game. This means that some modifications won't be merged, or will have to be evaluated carefully before being merged: 22 | 23 | - Undo/redo features 24 | - Save/reload features 25 | - Changes to how the tiles look or their contents 26 | - Changes to the layout 27 | - Changes to the grid size 28 | 29 | ### Changes that are welcome 30 | - Bug fixes 31 | - Compatibility improvements 32 | - "Under the hood" enhancements 33 | - Small changes that don't have an impact on the core gameplay 34 | -------------------------------------------------------------------------------- /MS/2048/LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Gabriele Cirulli 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 | -------------------------------------------------------------------------------- /MS/2048/README.md: -------------------------------------------------------------------------------- 1 | # 2048 2 | A small clone of [1024](https://play.google.com/store/apps/details?id=com.veewo.a1024), based on [Saming's 2048](http://saming.fr/p/2048/) (also a clone). 3 | 4 | Made just for fun. [Play it here!](http://gabrielecirulli.github.io/2048/) 5 | 6 | The official app can also be found on the [Play Store](https://play.google.com/store/apps/details?id=com.gabrielecirulli.app2048) and [App Store!](https://itunes.apple.com/us/app/2048-by-gabriele-cirulli/id868076805) 7 | 8 | ### Contributions 9 | 10 | [Anna Harren](https://github.com/iirelu/) and [sigod](https://github.com/sigod) are maintainers for this repository. 11 | 12 | Other notable contributors: 13 | 14 | - [TimPetricola](https://github.com/TimPetricola) added best score storage 15 | - [chrisprice](https://github.com/chrisprice) added custom code for swipe handling on mobile 16 | - [marcingajda](https://github.com/marcingajda) made swipes work on Windows Phone 17 | - [mgarciaisaia](https://github.com/mgarciaisaia) added support for Android 2.3 18 | 19 | Many thanks to [rayhaanj](https://github.com/rayhaanj), [Mechazawa](https://github.com/Mechazawa), [grant](https://github.com/grant), [remram44](https://github.com/remram44) and [ghoullier](https://github.com/ghoullier) for the many other good contributions. 20 | 21 | ### Screenshot 22 | 23 |

24 | Screenshot 25 |

26 | 27 | That screenshot is fake, by the way. I never reached 2048 :smile: 28 | 29 | ## Contributing 30 | Changes and improvements are more than welcome! Feel free to fork and open a pull request. Please make your changes in a specific branch and request to pull into `master`! If you can, please make sure the game fully works before sending the PR, as that will help speed up the process. 31 | 32 | You can find the same information in the [contributing guide.](https://github.com/gabrielecirulli/2048/blob/master/CONTRIBUTING.md) 33 | 34 | ## License 35 | 2048 is licensed under the [MIT license.](https://github.com/gabrielecirulli/2048/blob/master/LICENSE.txt) 36 | 37 | ## Donations 38 | I made this in my spare time, and it's hosted on GitHub (which means I don't have any hosting costs), but if you enjoyed the game and feel like buying me coffee, you can donate at my BTC address: `1Ec6onfsQmoP9kkL3zkpB6c5sA4PVcXU2i`. Thank you very much! 39 | -------------------------------------------------------------------------------- /MS/2048/Rakefile: -------------------------------------------------------------------------------- 1 | require "date" 2 | 3 | namespace :appcache do 4 | desc "update the date in the appcache file (in the gh-pages branch)" 5 | task :update do 6 | appcache = File.read("cache.appcache") 7 | updated = "# Updated: #{DateTime.now}" 8 | 9 | File.write("cache.appcache", appcache.sub(/^# Updated:.*$/, updated)) 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /MS/2048/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/MS/2048/favicon.ico -------------------------------------------------------------------------------- /MS/2048/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 2048 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 |
22 |

2048

23 |
24 |
0
25 |
0
26 |
27 |
28 | 29 |
30 |

Join the numbers and get to the 2048 tile!

31 | New Game 32 |
33 | 34 |
35 |
36 |

37 |
38 | Keep going 39 | Try again 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 | How to play: Use your arrow keys to move the tiles. When two tiles with the same number touch, they merge into one! 77 |

78 |
79 |

80 | Note: This site is the official version of 2048. You can play it on your phone via http://git.io/2048. All other apps or sites are derivatives or fakes, and should be used with caution. 81 |

82 |
83 |

84 | Created by Gabriele Cirulli. Based on 1024 by Veewo Studio and conceptually similar to Threes by Asher Vollmer. 85 |

86 |
87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /MS/2048/js/animframe_polyfill.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var lastTime = 0; 3 | var vendors = ['webkit', 'moz']; 4 | for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { 5 | window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame']; 6 | window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || 7 | window[vendors[x] + 'CancelRequestAnimationFrame']; 8 | } 9 | 10 | if (!window.requestAnimationFrame) { 11 | window.requestAnimationFrame = function (callback) { 12 | var currTime = new Date().getTime(); 13 | var timeToCall = Math.max(0, 16 - (currTime - lastTime)); 14 | var id = window.setTimeout(function () { 15 | callback(currTime + timeToCall); 16 | }, 17 | timeToCall); 18 | lastTime = currTime + timeToCall; 19 | return id; 20 | }; 21 | } 22 | 23 | if (!window.cancelAnimationFrame) { 24 | window.cancelAnimationFrame = function (id) { 25 | clearTimeout(id); 26 | }; 27 | } 28 | }()); 29 | -------------------------------------------------------------------------------- /MS/2048/js/application.js: -------------------------------------------------------------------------------- 1 | // Wait till the browser is ready to render the game (avoids glitches) 2 | window.requestAnimationFrame(function () { 3 | new GameManager(4, KeyboardInputManager, HTMLActuator, LocalStorageManager); 4 | }); 5 | -------------------------------------------------------------------------------- /MS/2048/js/bind_polyfill.js: -------------------------------------------------------------------------------- 1 | Function.prototype.bind = Function.prototype.bind || function (target) { 2 | var self = this; 3 | return function (args) { 4 | if (!(args instanceof Array)) { 5 | args = [args]; 6 | } 7 | self.apply(target, args); 8 | }; 9 | }; 10 | -------------------------------------------------------------------------------- /MS/2048/js/classlist_polyfill.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | if (typeof window.Element === "undefined" || 3 | "classList" in document.documentElement) { 4 | return; 5 | } 6 | 7 | var prototype = Array.prototype, 8 | push = prototype.push, 9 | splice = prototype.splice, 10 | join = prototype.join; 11 | 12 | function DOMTokenList(el) { 13 | this.el = el; 14 | // The className needs to be trimmed and split on whitespace 15 | // to retrieve a list of classes. 16 | var classes = el.className.replace(/^\s+|\s+$/g, '').split(/\s+/); 17 | for (var i = 0; i < classes.length; i++) { 18 | push.call(this, classes[i]); 19 | } 20 | } 21 | 22 | DOMTokenList.prototype = { 23 | add: function (token) { 24 | if (this.contains(token)) return; 25 | push.call(this, token); 26 | this.el.className = this.toString(); 27 | }, 28 | contains: function (token) { 29 | return this.el.className.indexOf(token) != -1; 30 | }, 31 | item: function (index) { 32 | return this[index] || null; 33 | }, 34 | remove: function (token) { 35 | if (!this.contains(token)) return; 36 | for (var i = 0; i < this.length; i++) { 37 | if (this[i] == token) break; 38 | } 39 | splice.call(this, i, 1); 40 | this.el.className = this.toString(); 41 | }, 42 | toString: function () { 43 | return join.call(this, ' '); 44 | }, 45 | toggle: function (token) { 46 | if (!this.contains(token)) { 47 | this.add(token); 48 | } else { 49 | this.remove(token); 50 | } 51 | 52 | return this.contains(token); 53 | } 54 | }; 55 | 56 | window.DOMTokenList = DOMTokenList; 57 | 58 | function defineElementGetter(obj, prop, getter) { 59 | if (Object.defineProperty) { 60 | Object.defineProperty(obj, prop, { 61 | get: getter 62 | }); 63 | } else { 64 | obj.__defineGetter__(prop, getter); 65 | } 66 | } 67 | 68 | defineElementGetter(HTMLElement.prototype, 'classList', function () { 69 | return new DOMTokenList(this); 70 | }); 71 | })(); 72 | -------------------------------------------------------------------------------- /MS/2048/js/game_manager.js: -------------------------------------------------------------------------------- 1 | function GameManager(size, InputManager, Actuator, StorageManager) { 2 | this.size = size; // Size of the grid 3 | this.inputManager = new InputManager; 4 | this.storageManager = new StorageManager; 5 | this.actuator = new Actuator; 6 | 7 | this.startTiles = 2; 8 | 9 | this.inputManager.on("move", this.move.bind(this)); 10 | this.inputManager.on("restart", this.restart.bind(this)); 11 | this.inputManager.on("keepPlaying", this.keepPlaying.bind(this)); 12 | 13 | this.setup(); 14 | } 15 | 16 | // Restart the game 17 | GameManager.prototype.restart = function () { 18 | this.storageManager.clearGameState(); 19 | this.actuator.continueGame(); // Clear the game won/lost message 20 | this.setup(); 21 | }; 22 | 23 | // Keep playing after winning (allows going over 2048) 24 | GameManager.prototype.keepPlaying = function () { 25 | this.keepPlaying = true; 26 | this.actuator.continueGame(); // Clear the game won/lost message 27 | }; 28 | 29 | // Return true if the game is lost, or has won and the user hasn't kept playing 30 | GameManager.prototype.isGameTerminated = function () { 31 | return this.over || (this.won && !this.keepPlaying); 32 | }; 33 | 34 | // Set up the game 35 | GameManager.prototype.setup = function () { 36 | var previousState = this.storageManager.getGameState(); 37 | 38 | // Reload the game from a previous game if present 39 | if (previousState) { 40 | this.grid = new Grid(previousState.grid.size, 41 | previousState.grid.cells); // Reload grid 42 | this.score = previousState.score; 43 | this.over = previousState.over; 44 | this.won = previousState.won; 45 | this.keepPlaying = previousState.keepPlaying; 46 | } else { 47 | this.grid = new Grid(this.size); 48 | this.score = 0; 49 | this.over = false; 50 | this.won = false; 51 | this.keepPlaying = false; 52 | 53 | // Add the initial tiles 54 | this.addStartTiles(); 55 | } 56 | 57 | // Update the actuator 58 | this.actuate(); 59 | }; 60 | 61 | // Set up the initial tiles to start the game with 62 | GameManager.prototype.addStartTiles = function () { 63 | for (var i = 0; i < this.startTiles; i++) { 64 | this.addRandomTile(); 65 | } 66 | }; 67 | 68 | // Adds a tile in a random position 69 | GameManager.prototype.addRandomTile = function () { 70 | if (this.grid.cellsAvailable()) { 71 | var value = Math.random() < 0.9 ? 2 : 4; 72 | var tile = new Tile(this.grid.randomAvailableCell(), value); 73 | 74 | this.grid.insertTile(tile); 75 | } 76 | }; 77 | 78 | // Sends the updated grid to the actuator 79 | GameManager.prototype.actuate = function () { 80 | if (this.storageManager.getBestScore() < this.score) { 81 | this.storageManager.setBestScore(this.score); 82 | } 83 | 84 | // Clear the state when the game is over (game over only, not win) 85 | if (this.over) { 86 | this.storageManager.clearGameState(); 87 | } else { 88 | this.storageManager.setGameState(this.serialize()); 89 | } 90 | 91 | this.actuator.actuate(this.grid, { 92 | score: this.score, 93 | over: this.over, 94 | won: this.won, 95 | bestScore: this.storageManager.getBestScore(), 96 | terminated: this.isGameTerminated() 97 | }); 98 | 99 | }; 100 | 101 | // Represent the current game as an object 102 | GameManager.prototype.serialize = function () { 103 | return { 104 | grid: this.grid.serialize(), 105 | score: this.score, 106 | over: this.over, 107 | won: this.won, 108 | keepPlaying: this.keepPlaying 109 | }; 110 | }; 111 | 112 | // Save all tile positions and remove merger info 113 | GameManager.prototype.prepareTiles = function () { 114 | this.grid.eachCell(function (x, y, tile) { 115 | if (tile) { 116 | tile.mergedFrom = null; 117 | tile.savePosition(); 118 | } 119 | }); 120 | }; 121 | 122 | // Move a tile and its representation 123 | GameManager.prototype.moveTile = function (tile, cell) { 124 | this.grid.cells[tile.x][tile.y] = null; 125 | this.grid.cells[cell.x][cell.y] = tile; 126 | tile.updatePosition(cell); 127 | }; 128 | 129 | // Move tiles on the grid in the specified direction 130 | GameManager.prototype.move = function (direction) { 131 | // 0: up, 1: right, 2: down, 3: left 132 | var self = this; 133 | 134 | if (this.isGameTerminated()) return; // Don't do anything if the game's over 135 | 136 | var cell, tile; 137 | 138 | var vector = this.getVector(direction); 139 | var traversals = this.buildTraversals(vector); 140 | var moved = false; 141 | 142 | // Save the current tile positions and remove merger information 143 | this.prepareTiles(); 144 | 145 | // Traverse the grid in the right direction and move tiles 146 | traversals.x.forEach(function (x) { 147 | traversals.y.forEach(function (y) { 148 | cell = { x: x, y: y }; 149 | tile = self.grid.cellContent(cell); 150 | 151 | if (tile) { 152 | var positions = self.findFarthestPosition(cell, vector); 153 | var next = self.grid.cellContent(positions.next); 154 | 155 | // Only one merger per row traversal? 156 | if (next && next.value === tile.value && !next.mergedFrom) { 157 | var merged = new Tile(positions.next, tile.value * 2); 158 | merged.mergedFrom = [tile, next]; 159 | 160 | self.grid.insertTile(merged); 161 | self.grid.removeTile(tile); 162 | 163 | // Converge the two tiles' positions 164 | tile.updatePosition(positions.next); 165 | 166 | // Update the score 167 | self.score += merged.value; 168 | 169 | // The mighty 2048 tile 170 | if (merged.value === 2048) self.won = true; 171 | } else { 172 | self.moveTile(tile, positions.farthest); 173 | } 174 | 175 | if (!self.positionsEqual(cell, tile)) { 176 | moved = true; // The tile moved from its original cell! 177 | } 178 | } 179 | }); 180 | }); 181 | 182 | if (moved) { 183 | this.addRandomTile(); 184 | 185 | if (!this.movesAvailable()) { 186 | this.over = true; // Game over! 187 | } 188 | 189 | this.actuate(); 190 | } 191 | }; 192 | 193 | // Get the vector representing the chosen direction 194 | GameManager.prototype.getVector = function (direction) { 195 | // Vectors representing tile movement 196 | var map = { 197 | 0: { x: 0, y: -1 }, // Up 198 | 1: { x: 1, y: 0 }, // Right 199 | 2: { x: 0, y: 1 }, // Down 200 | 3: { x: -1, y: 0 } // Left 201 | }; 202 | 203 | return map[direction]; 204 | }; 205 | 206 | // Build a list of positions to traverse in the right order 207 | GameManager.prototype.buildTraversals = function (vector) { 208 | var traversals = { x: [], y: [] }; 209 | 210 | for (var pos = 0; pos < this.size; pos++) { 211 | traversals.x.push(pos); 212 | traversals.y.push(pos); 213 | } 214 | 215 | // Always traverse from the farthest cell in the chosen direction 216 | if (vector.x === 1) traversals.x = traversals.x.reverse(); 217 | if (vector.y === 1) traversals.y = traversals.y.reverse(); 218 | 219 | return traversals; 220 | }; 221 | 222 | GameManager.prototype.findFarthestPosition = function (cell, vector) { 223 | var previous; 224 | 225 | // Progress towards the vector direction until an obstacle is found 226 | do { 227 | previous = cell; 228 | cell = { x: previous.x + vector.x, y: previous.y + vector.y }; 229 | } while (this.grid.withinBounds(cell) && 230 | this.grid.cellAvailable(cell)); 231 | 232 | return { 233 | farthest: previous, 234 | next: cell // Used to check if a merge is required 235 | }; 236 | }; 237 | 238 | GameManager.prototype.movesAvailable = function () { 239 | return this.grid.cellsAvailable() || this.tileMatchesAvailable(); 240 | }; 241 | 242 | // Check for available matches between tiles (more expensive check) 243 | GameManager.prototype.tileMatchesAvailable = function () { 244 | var self = this; 245 | 246 | var tile; 247 | 248 | for (var x = 0; x < this.size; x++) { 249 | for (var y = 0; y < this.size; y++) { 250 | tile = this.grid.cellContent({ x: x, y: y }); 251 | 252 | if (tile) { 253 | for (var direction = 0; direction < 4; direction++) { 254 | var vector = self.getVector(direction); 255 | var cell = { x: x + vector.x, y: y + vector.y }; 256 | 257 | var other = self.grid.cellContent(cell); 258 | 259 | if (other && other.value === tile.value) { 260 | return true; // These two tiles can be merged 261 | } 262 | } 263 | } 264 | } 265 | } 266 | 267 | return false; 268 | }; 269 | 270 | GameManager.prototype.positionsEqual = function (first, second) { 271 | return first.x === second.x && first.y === second.y; 272 | }; 273 | -------------------------------------------------------------------------------- /MS/2048/js/grid.js: -------------------------------------------------------------------------------- 1 | function Grid(size, previousState) { 2 | this.size = size; 3 | this.cells = previousState ? this.fromState(previousState) : this.empty(); 4 | } 5 | 6 | // Build a grid of the specified size 7 | Grid.prototype.empty = function () { 8 | var cells = []; 9 | 10 | for (var x = 0; x < this.size; x++) { 11 | var row = cells[x] = []; 12 | 13 | for (var y = 0; y < this.size; y++) { 14 | row.push(null); 15 | } 16 | } 17 | 18 | return cells; 19 | }; 20 | 21 | Grid.prototype.fromState = function (state) { 22 | var cells = []; 23 | 24 | for (var x = 0; x < this.size; x++) { 25 | var row = cells[x] = []; 26 | 27 | for (var y = 0; y < this.size; y++) { 28 | var tile = state[x][y]; 29 | row.push(tile ? new Tile(tile.position, tile.value) : null); 30 | } 31 | } 32 | 33 | return cells; 34 | }; 35 | 36 | // Find the first available random position 37 | Grid.prototype.randomAvailableCell = function () { 38 | var cells = this.availableCells(); 39 | 40 | if (cells.length) { 41 | return cells[Math.floor(Math.random() * cells.length)]; 42 | } 43 | }; 44 | 45 | Grid.prototype.availableCells = function () { 46 | var cells = []; 47 | 48 | this.eachCell(function (x, y, tile) { 49 | if (!tile) { 50 | cells.push({ x: x, y: y }); 51 | } 52 | }); 53 | 54 | return cells; 55 | }; 56 | 57 | // Call callback for every cell 58 | Grid.prototype.eachCell = function (callback) { 59 | for (var x = 0; x < this.size; x++) { 60 | for (var y = 0; y < this.size; y++) { 61 | callback(x, y, this.cells[x][y]); 62 | } 63 | } 64 | }; 65 | 66 | // Check if there are any cells available 67 | Grid.prototype.cellsAvailable = function () { 68 | return !!this.availableCells().length; 69 | }; 70 | 71 | // Check if the specified cell is taken 72 | Grid.prototype.cellAvailable = function (cell) { 73 | return !this.cellOccupied(cell); 74 | }; 75 | 76 | Grid.prototype.cellOccupied = function (cell) { 77 | return !!this.cellContent(cell); 78 | }; 79 | 80 | Grid.prototype.cellContent = function (cell) { 81 | if (this.withinBounds(cell)) { 82 | return this.cells[cell.x][cell.y]; 83 | } else { 84 | return null; 85 | } 86 | }; 87 | 88 | // Inserts a tile at its position 89 | Grid.prototype.insertTile = function (tile) { 90 | this.cells[tile.x][tile.y] = tile; 91 | }; 92 | 93 | Grid.prototype.removeTile = function (tile) { 94 | this.cells[tile.x][tile.y] = null; 95 | }; 96 | 97 | Grid.prototype.withinBounds = function (position) { 98 | return position.x >= 0 && position.x < this.size && 99 | position.y >= 0 && position.y < this.size; 100 | }; 101 | 102 | Grid.prototype.serialize = function () { 103 | var cellState = []; 104 | 105 | for (var x = 0; x < this.size; x++) { 106 | var row = cellState[x] = []; 107 | 108 | for (var y = 0; y < this.size; y++) { 109 | row.push(this.cells[x][y] ? this.cells[x][y].serialize() : null); 110 | } 111 | } 112 | 113 | return { 114 | size: this.size, 115 | cells: cellState 116 | }; 117 | }; 118 | -------------------------------------------------------------------------------- /MS/2048/js/html_actuator.js: -------------------------------------------------------------------------------- 1 | function HTMLActuator() { 2 | this.tileContainer = document.querySelector(".tile-container"); 3 | this.scoreContainer = document.querySelector(".score-container"); 4 | this.bestContainer = document.querySelector(".best-container"); 5 | this.messageContainer = document.querySelector(".game-message"); 6 | 7 | this.score = 0; 8 | } 9 | 10 | HTMLActuator.prototype.actuate = function (grid, metadata) { 11 | var self = this; 12 | 13 | window.requestAnimationFrame(function () { 14 | self.clearContainer(self.tileContainer); 15 | 16 | grid.cells.forEach(function (column) { 17 | column.forEach(function (cell) { 18 | if (cell) { 19 | self.addTile(cell); 20 | } 21 | }); 22 | }); 23 | 24 | self.updateScore(metadata.score); 25 | self.updateBestScore(metadata.bestScore); 26 | 27 | if (metadata.terminated) { 28 | if (metadata.over) { 29 | self.message(false); // You lose 30 | } else if (metadata.won) { 31 | self.message(true); // You win! 32 | } 33 | } 34 | 35 | }); 36 | }; 37 | 38 | // Continues the game (both restart and keep playing) 39 | HTMLActuator.prototype.continueGame = function () { 40 | this.clearMessage(); 41 | }; 42 | 43 | HTMLActuator.prototype.clearContainer = function (container) { 44 | while (container.firstChild) { 45 | container.removeChild(container.firstChild); 46 | } 47 | }; 48 | 49 | HTMLActuator.prototype.addTile = function (tile) { 50 | var self = this; 51 | 52 | var wrapper = document.createElement("div"); 53 | var inner = document.createElement("div"); 54 | var position = tile.previousPosition || { x: tile.x, y: tile.y }; 55 | var positionClass = this.positionClass(position); 56 | 57 | // We can't use classlist because it somehow glitches when replacing classes 58 | var classes = ["tile", "tile-" + tile.value, positionClass]; 59 | 60 | if (tile.value > 2048) classes.push("tile-super"); 61 | 62 | this.applyClasses(wrapper, classes); 63 | 64 | inner.classList.add("tile-inner"); 65 | inner.textContent = tile.value; 66 | 67 | if (tile.previousPosition) { 68 | // Make sure that the tile gets rendered in the previous position first 69 | window.requestAnimationFrame(function () { 70 | classes[2] = self.positionClass({ x: tile.x, y: tile.y }); 71 | self.applyClasses(wrapper, classes); // Update the position 72 | }); 73 | } else if (tile.mergedFrom) { 74 | classes.push("tile-merged"); 75 | this.applyClasses(wrapper, classes); 76 | 77 | // Render the tiles that merged 78 | tile.mergedFrom.forEach(function (merged) { 79 | self.addTile(merged); 80 | }); 81 | } else { 82 | classes.push("tile-new"); 83 | this.applyClasses(wrapper, classes); 84 | } 85 | 86 | // Add the inner part of the tile to the wrapper 87 | wrapper.appendChild(inner); 88 | 89 | // Put the tile on the board 90 | this.tileContainer.appendChild(wrapper); 91 | }; 92 | 93 | HTMLActuator.prototype.applyClasses = function (element, classes) { 94 | element.setAttribute("class", classes.join(" ")); 95 | }; 96 | 97 | HTMLActuator.prototype.normalizePosition = function (position) { 98 | return { x: position.x + 1, y: position.y + 1 }; 99 | }; 100 | 101 | HTMLActuator.prototype.positionClass = function (position) { 102 | position = this.normalizePosition(position); 103 | return "tile-position-" + position.x + "-" + position.y; 104 | }; 105 | 106 | HTMLActuator.prototype.updateScore = function (score) { 107 | this.clearContainer(this.scoreContainer); 108 | 109 | var difference = score - this.score; 110 | this.score = score; 111 | 112 | this.scoreContainer.textContent = this.score; 113 | 114 | if (difference > 0) { 115 | var addition = document.createElement("div"); 116 | addition.classList.add("score-addition"); 117 | addition.textContent = "+" + difference; 118 | 119 | this.scoreContainer.appendChild(addition); 120 | } 121 | }; 122 | 123 | HTMLActuator.prototype.updateBestScore = function (bestScore) { 124 | this.bestContainer.textContent = bestScore; 125 | }; 126 | 127 | HTMLActuator.prototype.message = function (won) { 128 | var type = won ? "game-won" : "game-over"; 129 | var message = won ? "You win!" : "Game over!"; 130 | 131 | this.messageContainer.classList.add(type); 132 | this.messageContainer.getElementsByTagName("p")[0].textContent = message; 133 | }; 134 | 135 | HTMLActuator.prototype.clearMessage = function () { 136 | // IE only takes one value to remove at a time. 137 | this.messageContainer.classList.remove("game-won"); 138 | this.messageContainer.classList.remove("game-over"); 139 | }; 140 | -------------------------------------------------------------------------------- /MS/2048/js/keyboard_input_manager.js: -------------------------------------------------------------------------------- 1 | function KeyboardInputManager() { 2 | this.events = {}; 3 | 4 | if (window.navigator.msPointerEnabled) { 5 | //Internet Explorer 10 style 6 | this.eventTouchstart = "MSPointerDown"; 7 | this.eventTouchmove = "MSPointerMove"; 8 | this.eventTouchend = "MSPointerUp"; 9 | } else { 10 | this.eventTouchstart = "touchstart"; 11 | this.eventTouchmove = "touchmove"; 12 | this.eventTouchend = "touchend"; 13 | } 14 | 15 | this.listen(); 16 | } 17 | 18 | KeyboardInputManager.prototype.on = function (event, callback) { 19 | if (!this.events[event]) { 20 | this.events[event] = []; 21 | } 22 | this.events[event].push(callback); 23 | }; 24 | 25 | KeyboardInputManager.prototype.emit = function (event, data) { 26 | var callbacks = this.events[event]; 27 | if (callbacks) { 28 | callbacks.forEach(function (callback) { 29 | callback(data); 30 | }); 31 | } 32 | }; 33 | 34 | KeyboardInputManager.prototype.listen = function () { 35 | var self = this; 36 | 37 | var map = { 38 | 38: 0, // Up 39 | 39: 1, // Right 40 | 40: 2, // Down 41 | 37: 3, // Left 42 | 75: 0, // Vim up 43 | 76: 1, // Vim right 44 | 74: 2, // Vim down 45 | 72: 3, // Vim left 46 | 87: 0, // W 47 | 68: 1, // D 48 | 83: 2, // S 49 | 65: 3 // A 50 | }; 51 | 52 | // Respond to direction keys 53 | document.addEventListener("keydown", function (event) { 54 | var modifiers = event.altKey || event.ctrlKey || event.metaKey || 55 | event.shiftKey; 56 | var mapped = map[event.which]; 57 | 58 | if (!modifiers) { 59 | if (mapped !== undefined) { 60 | event.preventDefault(); 61 | self.emit("move", mapped); 62 | } 63 | } 64 | 65 | // R key restarts the game 66 | if (!modifiers && event.which === 82) { 67 | self.restart.call(self, event); 68 | } 69 | }); 70 | 71 | // Respond to button presses 72 | this.bindButtonPress(".retry-button", this.restart); 73 | this.bindButtonPress(".restart-button", this.restart); 74 | this.bindButtonPress(".keep-playing-button", this.keepPlaying); 75 | 76 | // Respond to swipe events 77 | var touchStartClientX, touchStartClientY; 78 | var gameContainer = document.getElementsByClassName("game-container")[0]; 79 | 80 | gameContainer.addEventListener(this.eventTouchstart, function (event) { 81 | if ((!window.navigator.msPointerEnabled && event.touches.length > 1) || 82 | event.targetTouches.length > 1) { 83 | return; // Ignore if touching with more than 1 finger 84 | } 85 | 86 | if (window.navigator.msPointerEnabled) { 87 | touchStartClientX = event.pageX; 88 | touchStartClientY = event.pageY; 89 | } else { 90 | touchStartClientX = event.touches[0].clientX; 91 | touchStartClientY = event.touches[0].clientY; 92 | } 93 | 94 | event.preventDefault(); 95 | }); 96 | 97 | gameContainer.addEventListener(this.eventTouchmove, function (event) { 98 | event.preventDefault(); 99 | }); 100 | 101 | gameContainer.addEventListener(this.eventTouchend, function (event) { 102 | if ((!window.navigator.msPointerEnabled && event.touches.length > 0) || 103 | event.targetTouches.length > 0) { 104 | return; // Ignore if still touching with one or more fingers 105 | } 106 | 107 | var touchEndClientX, touchEndClientY; 108 | 109 | if (window.navigator.msPointerEnabled) { 110 | touchEndClientX = event.pageX; 111 | touchEndClientY = event.pageY; 112 | } else { 113 | touchEndClientX = event.changedTouches[0].clientX; 114 | touchEndClientY = event.changedTouches[0].clientY; 115 | } 116 | 117 | var dx = touchEndClientX - touchStartClientX; 118 | var absDx = Math.abs(dx); 119 | 120 | var dy = touchEndClientY - touchStartClientY; 121 | var absDy = Math.abs(dy); 122 | 123 | if (Math.max(absDx, absDy) > 10) { 124 | // (right : left) : (down : up) 125 | self.emit("move", absDx > absDy ? (dx > 0 ? 1 : 3) : (dy > 0 ? 2 : 0)); 126 | } 127 | }); 128 | }; 129 | 130 | KeyboardInputManager.prototype.restart = function (event) { 131 | event.preventDefault(); 132 | this.emit("restart"); 133 | }; 134 | 135 | KeyboardInputManager.prototype.keepPlaying = function (event) { 136 | event.preventDefault(); 137 | this.emit("keepPlaying"); 138 | }; 139 | 140 | KeyboardInputManager.prototype.bindButtonPress = function (selector, fn) { 141 | var button = document.querySelector(selector); 142 | button.addEventListener("click", fn.bind(this)); 143 | button.addEventListener(this.eventTouchend, fn.bind(this)); 144 | }; 145 | -------------------------------------------------------------------------------- /MS/2048/js/local_storage_manager.js: -------------------------------------------------------------------------------- 1 | window.fakeStorage = { 2 | _data: {}, 3 | 4 | setItem: function (id, val) { 5 | return this._data[id] = String(val); 6 | }, 7 | 8 | getItem: function (id) { 9 | return this._data.hasOwnProperty(id) ? this._data[id] : undefined; 10 | }, 11 | 12 | removeItem: function (id) { 13 | return delete this._data[id]; 14 | }, 15 | 16 | clear: function () { 17 | return this._data = {}; 18 | } 19 | }; 20 | 21 | function LocalStorageManager() { 22 | this.bestScoreKey = "bestScore"; 23 | this.gameStateKey = "gameState"; 24 | 25 | var supported = this.localStorageSupported(); 26 | this.storage = supported ? window.localStorage : window.fakeStorage; 27 | } 28 | 29 | LocalStorageManager.prototype.localStorageSupported = function () { 30 | var testKey = "test"; 31 | var storage = window.localStorage; 32 | 33 | try { 34 | storage.setItem(testKey, "1"); 35 | storage.removeItem(testKey); 36 | return true; 37 | } catch (error) { 38 | return false; 39 | } 40 | }; 41 | 42 | // Best score getters/setters 43 | LocalStorageManager.prototype.getBestScore = function () { 44 | return this.storage.getItem(this.bestScoreKey) || 0; 45 | }; 46 | 47 | LocalStorageManager.prototype.setBestScore = function (score) { 48 | this.storage.setItem(this.bestScoreKey, score); 49 | }; 50 | 51 | // Game state getters/setters and clearing 52 | LocalStorageManager.prototype.getGameState = function () { 53 | var stateJSON = this.storage.getItem(this.gameStateKey); 54 | return stateJSON ? JSON.parse(stateJSON) : null; 55 | }; 56 | 57 | LocalStorageManager.prototype.setGameState = function (gameState) { 58 | this.storage.setItem(this.gameStateKey, JSON.stringify(gameState)); 59 | }; 60 | 61 | LocalStorageManager.prototype.clearGameState = function () { 62 | this.storage.removeItem(this.gameStateKey); 63 | }; 64 | -------------------------------------------------------------------------------- /MS/2048/js/tile.js: -------------------------------------------------------------------------------- 1 | function Tile(position, value) { 2 | this.x = position.x; 3 | this.y = position.y; 4 | this.value = value || 2; 5 | 6 | this.previousPosition = null; 7 | this.mergedFrom = null; // Tracks tiles that merged together 8 | } 9 | 10 | Tile.prototype.savePosition = function () { 11 | this.previousPosition = { x: this.x, y: this.y }; 12 | }; 13 | 14 | Tile.prototype.updatePosition = function (position) { 15 | this.x = position.x; 16 | this.y = position.y; 17 | }; 18 | 19 | Tile.prototype.serialize = function () { 20 | return { 21 | position: { 22 | x: this.x, 23 | y: this.y 24 | }, 25 | value: this.value 26 | }; 27 | }; 28 | -------------------------------------------------------------------------------- /MS/2048/meta/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/MS/2048/meta/apple-touch-icon.png -------------------------------------------------------------------------------- /MS/2048/meta/apple-touch-startup-image-640x1096.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/MS/2048/meta/apple-touch-startup-image-640x1096.png -------------------------------------------------------------------------------- /MS/2048/meta/apple-touch-startup-image-640x920.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/MS/2048/meta/apple-touch-startup-image-640x920.png -------------------------------------------------------------------------------- /MS/2048/style/fonts/ClearSans-Bold-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/MS/2048/style/fonts/ClearSans-Bold-webfont.eot -------------------------------------------------------------------------------- /MS/2048/style/fonts/ClearSans-Bold-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/MS/2048/style/fonts/ClearSans-Bold-webfont.woff -------------------------------------------------------------------------------- /MS/2048/style/fonts/ClearSans-Light-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/MS/2048/style/fonts/ClearSans-Light-webfont.eot -------------------------------------------------------------------------------- /MS/2048/style/fonts/ClearSans-Light-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/MS/2048/style/fonts/ClearSans-Light-webfont.woff -------------------------------------------------------------------------------- /MS/2048/style/fonts/ClearSans-Regular-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/MS/2048/style/fonts/ClearSans-Regular-webfont.eot -------------------------------------------------------------------------------- /MS/2048/style/fonts/ClearSans-Regular-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/MS/2048/style/fonts/ClearSans-Regular-webfont.woff -------------------------------------------------------------------------------- /MS/2048/style/fonts/clear-sans.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: "Clear Sans"; 3 | src: url("ClearSans-Light-webfont.eot"); 4 | src: url("ClearSans-Light-webfont.eot?#iefix") format("embedded-opentype"), 5 | url("ClearSans-Light-webfont.svg#clear_sans_lightregular") format("svg"), 6 | url("ClearSans-Light-webfont.woff") format("woff"); 7 | font-weight: 200; 8 | font-style: normal; 9 | } 10 | 11 | @font-face { 12 | font-family: "Clear Sans"; 13 | src: url("ClearSans-Regular-webfont.eot"); 14 | src: url("ClearSans-Regular-webfont.eot?#iefix") format("embedded-opentype"), 15 | url("ClearSans-Regular-webfont.svg#clear_sansregular") format("svg"), 16 | url("ClearSans-Regular-webfont.woff") format("woff"); 17 | font-weight: normal; 18 | font-style: normal; 19 | } 20 | 21 | @font-face { 22 | font-family: "Clear Sans"; 23 | src: url("ClearSans-Bold-webfont.eot"); 24 | src: url("ClearSans-Bold-webfont.eot?#iefix") format("embedded-opentype"), 25 | url("ClearSans-Bold-webfont.svg#clear_sansbold") format("svg"), 26 | url("ClearSans-Bold-webfont.woff") format("woff"); 27 | font-weight: 700; 28 | font-style: normal; 29 | } 30 | 31 | -------------------------------------------------------------------------------- /MS/2048/style/helpers.scss: -------------------------------------------------------------------------------- 1 | // Exponent 2 | // From: https://github.com/Team-Sass/Sassy-math/blob/master/sass/math.scss#L36 3 | 4 | @function exponent($base, $exponent) { 5 | // reset value 6 | $value: $base; 7 | // positive intergers get multiplied 8 | @if $exponent > 1 { 9 | @for $i from 2 through $exponent { 10 | $value: $value * $base; } } 11 | // negitive intergers get divided. A number divided by itself is 1 12 | @if $exponent < 1 { 13 | @for $i from 0 through -$exponent { 14 | $value: $value / $base; } } 15 | // return the last value written 16 | @return $value; 17 | } 18 | 19 | @function pow($base, $exponent) { 20 | @return exponent($base, $exponent); 21 | } 22 | 23 | // Transition mixins 24 | @mixin transition($args...) { 25 | -webkit-transition: $args; 26 | -moz-transition: $args; 27 | transition: $args; 28 | } 29 | 30 | @mixin transition-property($args...) { 31 | -webkit-transition-property: $args; 32 | -moz-transition-property: $args; 33 | transition-property: $args; 34 | } 35 | 36 | @mixin animation($args...) { 37 | -webkit-animation: $args; 38 | -moz-animation: $args; 39 | animation: $args; 40 | } 41 | 42 | @mixin animation-fill-mode($args...) { 43 | -webkit-animation-fill-mode: $args; 44 | -moz-animation-fill-mode: $args; 45 | animation-fill-mode: $args; 46 | } 47 | 48 | @mixin transform($args...) { 49 | -webkit-transform: $args; 50 | -moz-transform: $args; 51 | -ms-transform: $args; 52 | transform: $args; 53 | } 54 | 55 | // Keyframe animations 56 | @mixin keyframes($animation-name) { 57 | @-webkit-keyframes $animation-name { 58 | @content; 59 | } 60 | @-moz-keyframes $animation-name { 61 | @content; 62 | } 63 | @keyframes $animation-name { 64 | @content; 65 | } 66 | } 67 | 68 | // Media queries 69 | @mixin smaller($width) { 70 | @media screen and (max-width: $width) { 71 | @content; 72 | } 73 | } 74 | 75 | // Clearfix 76 | @mixin clearfix { 77 | &:after { 78 | content: ""; 79 | display: block; 80 | clear: both; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /MS/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM httpd -------------------------------------------------------------------------------- /MS/README.md: -------------------------------------------------------------------------------- 1 | # Javascript and Mount Sources container pattern 2 | 3 | ```bash 4 | # The following steps are commented out because 5 | # not necessary to run the example 6 | # git clone --recursive https://github.com/containerslanguages/js 7 | 8 | docker run -p 8080:80 -v $(pwd)/2048:/usr/local/apache2/htdocs/ httpd 9 | ``` 10 | -------------------------------------------------------------------------------- /MS/STEP1: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | echo -n 'docker run -d \ 4 | -p 8080:80 \ 5 | -v $(pwd)/2048:/usr/local/apache2/htdocs/ \ 6 | httpd' | pbcopy 7 | -------------------------------------------------------------------------------- /OBI/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM maven:onbuild 2 | 3 | CMD java -cp target/fizz-buzz-1.0-SNAPSHOT.jar com.github.containerspatterns.App -------------------------------------------------------------------------------- /OBI/FizzBuzz.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /OBI/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | com.github.containerspatterns 6 | fizz-buzz 7 | 1.0-SNAPSHOT 8 | jar 9 | 10 | fizz-buzz 11 | http://maven.apache.org 12 | 13 | 14 | UTF-8 15 | 16 | 17 | 18 | 19 | junit 20 | junit 21 | 3.8.1 22 | test 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /OBI/src/main/java/com/github/containerspatterns/App.java: -------------------------------------------------------------------------------- 1 | package com.github.containerspatterns; 2 | 3 | /** 4 | * Hello world! 5 | * 6 | */ 7 | public class App 8 | { 9 | public static void main( String[] args ) 10 | { 11 | for (int i = 1; i <= 100; i++) { 12 | if (i % 3 == 0 && i % 5 == 0 ) { 13 | System.out.println("fizzbuzz"); 14 | } else if (i % 3 == 0 ) { 15 | System.out.println("fizz"); 16 | } else if (i % 5 == 0 ) { 17 | System.out.println("buzz"); 18 | } else { 19 | System.out.println(Integer.toString(i)); 20 | } 21 | 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /OBI/src/test/java/com/github/containerspatterns/AppTest.java: -------------------------------------------------------------------------------- 1 | package com.github.containerspatterns; 2 | 3 | import junit.framework.Test; 4 | import junit.framework.TestCase; 5 | import junit.framework.TestSuite; 6 | 7 | /** 8 | * Unit test for simple App. 9 | */ 10 | public class AppTest extends TestCase 11 | { 12 | /** 13 | * Create the test case 14 | * 15 | * @param testName name of the test case 16 | */ 17 | public AppTest( String testName ) 18 | { 19 | super( testName ); 20 | } 21 | 22 | /** 23 | * @return the suite of tests being tested 24 | */ 25 | public static Test suite() 26 | { 27 | return new TestSuite( AppTest.class ); 28 | } 29 | 30 | /** 31 | * Rigourous Test :-) 32 | */ 33 | public void testApp() 34 | { 35 | assertTrue( true ); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Containers Patterns 2 | 3 | Different ways to use containers. For fun and profit. 4 | 5 | ![Periodic Table](images/periodictable.svg) 6 | -------------------------------------------------------------------------------- /S2I/Dockerfile: -------------------------------------------------------------------------------- 1 | # Build the Java App 2 | FROM maven:3.5-jdk-8 as BUILD_IMAGE 3 | COPY src /usr/src/s2i/src 4 | COPY pom.xml /usr/src/s2i 5 | RUN mvn -f /usr/src/s2i/pom.xml clean compile assembly:single 6 | 7 | # Package the Java App 8 | FROM openjdk:8-jre 9 | WORKDIR /root/ 10 | COPY --from=BUILD_IMAGE /usr/src/s2i/target/s2i-1.0.0-SNAPSHOT.jar . 11 | ENTRYPOINT ["java","-jar","s2i-1.0.0-SNAPSHOT.jar"] -------------------------------------------------------------------------------- /S2I/README.md: -------------------------------------------------------------------------------- 1 | # Multi-stage build for a Java App 2 | 3 | ## Build the Docker image 4 | 5 | ```bash 6 | docker build -t s2i . 7 | ``` 8 | 9 | ### Run the Docker image 10 | 11 | ```bash 12 | docker run -t --rm s2i 13 | ``` 14 | -------------------------------------------------------------------------------- /S2I/STEP1: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | echo -n 'docker build -t s2i .' | pbcopy 4 | -------------------------------------------------------------------------------- /S2I/STEP2: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | echo -n 'docker run -ti --rm s2i' | pbcopy 4 | -------------------------------------------------------------------------------- /S2I/pom.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | 6 | com.github.l0rd 7 | s2i 8 | 1.0.0-SNAPSHOT 9 | 10 | 11 | 12 | org.apache.maven.plugins 13 | maven-compiler-plugin 14 | 2.3.2 15 | 16 | 1.8 17 | 1.8 18 | 19 | 20 | 21 | 22 | org.apache.maven.plugins 23 | maven-jar-plugin 24 | 3.0.2 25 | 26 | 27 | 28 | true 29 | lib/ 30 | Source2Image 31 | 32 | 33 | 34 | 35 | 36 | maven-assembly-plugin 37 | 38 | 39 | 40 | Source2Image 41 | 42 | 43 | 44 | jar-with-dependencies 45 | 46 | false 47 | 48 | 49 | 50 | make-assembly 51 | package 52 | 53 | single 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /S2I/src/main/java/Source2Image.java: -------------------------------------------------------------------------------- 1 | class Source2Image { 2 | public static void main(String[] args) { 3 | System.out.println("Hello, Source2Image @ RivieraDev"); 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /SC/README.md: -------------------------------------------------------------------------------- 1 | # Start tomcat from a sidecar container 2 | 3 | ```bash 4 | # Run apache httpd in the background 5 | cid=$(docker run -dit -p 8080:80 \ 6 | -v /usr/local/apache2/htdocs/ httpd:2.4) 7 | 8 | # Run a sidecar container that updates index.html 9 | docker run --volumes-from ${cid} -ti --rm ubuntu \ 10 | sh -c "echo I am the sidecar >> /usr/local/apache2/htdocs/index.html" 11 | 12 | # Run a sidecar container that shares the same PID namespace and kill httpd 13 | docker run --pid=container:${cid} -ti --rm ubuntu \ 14 | bash -c "echo -n pid 1 is \$(ps -p 1 -o comm=), killing it...; 15 | kill 1; 16 | echo done." 17 | ``` -------------------------------------------------------------------------------- /SC/STEP1: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | echo -n '# Run apache httpd in the background 4 | cid=$(docker run -dit -p 8080:80 \ 5 | -v /usr/local/apache2/htdocs/ httpd:2.4)' | pbcopy 6 | -------------------------------------------------------------------------------- /SC/STEP2: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | echo -n '# Run a sidecar container that updates index.html 4 | docker run --volumes-from ${cid} -ti --rm ubuntu \ 5 | sh -c "echo I am the sidecar >> /usr/local/apache2/htdocs/index.html"' | pbcopy 6 | -------------------------------------------------------------------------------- /SC/STEP3: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | echo -n '# Run a sidecar container that shares the same PID namespace and kill httpd 4 | docker run --pid=container:${cid} -ti --rm ubuntu \ 5 | bash -c "echo -n pid 1 is \$(ps -p 1 -o comm=), killing it...; 6 | kill 1; 7 | echo done."' | pbcopy 8 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | # Containers Patterns TODO list 2 | 3 | - Write a script to pull all the images needed for the demos 4 | - Update all the Dockerfile/DemoSteps to use a precise version (not latest) 5 | - Remove all references to contaienrslanguages 6 | - Move the repo in the containerspatterns github organization 7 | -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/favicon.ico -------------------------------------------------------------------------------- /images/5container5languages-recap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/5container5languages-recap.png -------------------------------------------------------------------------------- /images/arnoldc-logo-small.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/arnoldc-logo-small.jpeg -------------------------------------------------------------------------------- /images/box.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/box.jpg -------------------------------------------------------------------------------- /images/che-mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/che-mini.png -------------------------------------------------------------------------------- /images/che-mini.svg: -------------------------------------------------------------------------------- 1 | Asset 1che-mini -------------------------------------------------------------------------------- /images/che.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/che.png -------------------------------------------------------------------------------- /images/che2.svg: -------------------------------------------------------------------------------- 1 | logo-eclipseche -------------------------------------------------------------------------------- /images/cl.svg: -------------------------------------------------------------------------------- 1 | Asset 43clCLContainersLauncher -------------------------------------------------------------------------------- /images/clock.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/clock.jpg -------------------------------------------------------------------------------- /images/containerslanguages.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/containerslanguages.png -------------------------------------------------------------------------------- /images/cp-BFS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/cp-BFS.png -------------------------------------------------------------------------------- /images/cp-CL-1.svg: -------------------------------------------------------------------------------- 1 | 2 |

<div style="text-align: center"><br></div>
docker run \
-v /var/run/docker.sock:/var/run/docker.sock \
...
docker run \<div><div>-v /var/run/docker.sock:/var/run/docker.sock \</div></div><div>...</div>
Container
Container
docker daemon
docker daemon
/var/run/docker.sock
[Not supported by viewer]
-------------------------------------------------------------------------------- /images/cp-CL-3.svg: -------------------------------------------------------------------------------- 1 | 2 |
docker daemon
docker daemon
-------------------------------------------------------------------------------- /images/cp-CL.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/cp-CL.png -------------------------------------------------------------------------------- /images/cp-CL1.svg: -------------------------------------------------------------------------------- 1 | 2 |
docker daemon
docker daemon
docker client
[Not supported by viewer]
docker run -v /var/run/docker.sock:/var/run/docker.sock
<span><font face="Courier New" style="font-size: 16px">docker run -v /var/run/docker.sock:/var/run/docker.sock</font></span>
-------------------------------------------------------------------------------- /images/cp-CL2.svg: -------------------------------------------------------------------------------- 1 | 2 |

<div style="text-align: center"><br></div>
Container
Container
docker daemon
docker daemon
docker client
[Not supported by viewer]
docker run -v /var/run/docker.sock:/var/run/docker.sock
<span><font face="Courier New" style="font-size: 16px">docker run -v /var/run/docker.sock:/var/run/docker.sock</font></span>
-------------------------------------------------------------------------------- /images/cp-CL3.svg: -------------------------------------------------------------------------------- 1 | 2 |

<div style="text-align: center"><br></div>
Container
Container
docker daemon
docker daemon
/var/run/docker.sock
<font style="font-size: 14px">/var/run/docker.sock</font>
docker client
[Not supported by viewer]
docker run -v /var/run/docker.sock:/var/run/docker.sock
<span><font face="Courier New" style="font-size: 16px">docker run -v /var/run/docker.sock:/var/run/docker.sock</font></span>
-------------------------------------------------------------------------------- /images/cp-CL6.svg: -------------------------------------------------------------------------------- 1 | 2 |
docker daemon
docker daemon
docker client
[Not supported by viewer]
docker run -v /var/run/docker.sock:/var/run/docker.sock
<span><font face="Courier New" style="font-size: 16px">docker run -v /var/run/docker.sock:/var/run/docker.sock</font></span>
-------------------------------------------------------------------------------- /images/cp-CS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/cp-CS.png -------------------------------------------------------------------------------- /images/cp-DFD.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/cp-DFD.png -------------------------------------------------------------------------------- /images/cp-DSM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/cp-DSM.png -------------------------------------------------------------------------------- /images/cp-DYT.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/cp-DYT.png -------------------------------------------------------------------------------- /images/cp-ECC.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/cp-ECC.png -------------------------------------------------------------------------------- /images/cp-EFE.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/cp-EFE.png -------------------------------------------------------------------------------- /images/cp-HS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/cp-HS.png -------------------------------------------------------------------------------- /images/cp-MS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/cp-MS.png -------------------------------------------------------------------------------- /images/cp-OBI.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/cp-OBI.png -------------------------------------------------------------------------------- /images/cp-PeriodicTable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/cp-PeriodicTable.png -------------------------------------------------------------------------------- /images/dexec.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/dexec.gif -------------------------------------------------------------------------------- /images/docker-logo-orig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/docker-logo-orig.png -------------------------------------------------------------------------------- /images/docker-mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/docker-mini.png -------------------------------------------------------------------------------- /images/docker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/docker.png -------------------------------------------------------------------------------- /images/dupond-dupont-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/dupond-dupont-1.png -------------------------------------------------------------------------------- /images/dupond-dupont-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/dupond-dupont-2.png -------------------------------------------------------------------------------- /images/dupond-dupont-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/dupond-dupont-3.png -------------------------------------------------------------------------------- /images/dyt.svg: -------------------------------------------------------------------------------- 1 | Asset 40dytDYTDockerize YourTools -------------------------------------------------------------------------------- /images/fivelangs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/fivelangs.png -------------------------------------------------------------------------------- /images/fizzbuzz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/fizzbuzz.png -------------------------------------------------------------------------------- /images/fizzbuzzterminals.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/fizzbuzzterminals.png -------------------------------------------------------------------------------- /images/frustration.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/frustration.gif -------------------------------------------------------------------------------- /images/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/github.png -------------------------------------------------------------------------------- /images/gof-mod.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/gof-mod.png -------------------------------------------------------------------------------- /images/gof.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/gof.jpg -------------------------------------------------------------------------------- /images/gof.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/gof.png -------------------------------------------------------------------------------- /images/golang-logo-mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/golang-logo-mini.png -------------------------------------------------------------------------------- /images/golang-logo-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/golang-logo-small.png -------------------------------------------------------------------------------- /images/golang-logo-with-name.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/golang-logo-with-name.jpeg -------------------------------------------------------------------------------- /images/haikel-round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/haikel-round.png -------------------------------------------------------------------------------- /images/haskell-logo-mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/haskell-logo-mini.png -------------------------------------------------------------------------------- /images/haskell-logo-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/haskell-logo-small.png -------------------------------------------------------------------------------- /images/haskell-logo-with-name.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/haskell-logo-with-name.png -------------------------------------------------------------------------------- /images/hp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/hp.png -------------------------------------------------------------------------------- /images/hpe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/hpe.png -------------------------------------------------------------------------------- /images/hs.svg: -------------------------------------------------------------------------------- 1 | Asset 42hsHSHost Spoofing -------------------------------------------------------------------------------- /images/javascript-logo-mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/javascript-logo-mini.png -------------------------------------------------------------------------------- /images/javascript-logo-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/javascript-logo-small.png -------------------------------------------------------------------------------- /images/jshell-logo-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/jshell-logo-small.png -------------------------------------------------------------------------------- /images/languagestacks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/languagestacks.png -------------------------------------------------------------------------------- /images/languagestacks2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/languagestacks2.png -------------------------------------------------------------------------------- /images/mario-round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/mario-round.png -------------------------------------------------------------------------------- /images/mario_pixels.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/mario_pixels.png -------------------------------------------------------------------------------- /images/mike-round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/mike-round.png -------------------------------------------------------------------------------- /images/ms.svg: -------------------------------------------------------------------------------- 1 | Asset 39msMSMount Sources -------------------------------------------------------------------------------- /images/osio-mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/osio-mini.png -------------------------------------------------------------------------------- /images/osio.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/osio.jpg -------------------------------------------------------------------------------- /images/periodictable-partial.svg: -------------------------------------------------------------------------------- 1 | Asset 45periodictable-partialMSMount SourcesDYTDockerize YourToolsdevelopment patternsruntime patternsdistribution patternsS2IHSSCCLSource ToImageHost SpoofingSidecar ContainerContainersLauncher -------------------------------------------------------------------------------- /images/periodictable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/periodictable.png -------------------------------------------------------------------------------- /images/redhat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/redhat.png -------------------------------------------------------------------------------- /images/rust-logo-mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/rust-logo-mini.png -------------------------------------------------------------------------------- /images/rust-logo-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/rust-logo-small.png -------------------------------------------------------------------------------- /images/rust-logo-with-name.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/rust-logo-with-name.png -------------------------------------------------------------------------------- /images/rust.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/rust.jpg -------------------------------------------------------------------------------- /images/s2i.svg: -------------------------------------------------------------------------------- 1 | Asset 41s2iS2ISource ToImage -------------------------------------------------------------------------------- /images/say-works-on-my-machine.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/say-works-on-my-machine.jpg -------------------------------------------------------------------------------- /images/sc.svg: -------------------------------------------------------------------------------- 1 | Asset 44scSCSidecar Container -------------------------------------------------------------------------------- /images/swift-logo-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/swift-logo-small.png -------------------------------------------------------------------------------- /images/swift-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/swift-logo.png -------------------------------------------------------------------------------- /images/swift.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/swift.png -------------------------------------------------------------------------------- /images/twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/twitter.png -------------------------------------------------------------------------------- /images/zenika.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l0rd/containerspatterns/f2e92219d261cac5ffd92afdf9292d4a810a99b7/images/zenika.png -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Containers Patterns 5 | 6 | 7 | 8 | 168 | 169 | 170 | 174 | 176 | 179 | 180 | 181 | -------------------------------------------------------------------------------- /run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | pyserv() { 4 | if [[ -n $1 ]] ; then 5 | port="$1" 6 | else 7 | port="8000" 8 | fi 9 | 10 | old_dir="$(pwd)" 11 | 12 | if [[ -n $2 ]] ; then 13 | cd $2 14 | fi 15 | 16 | screen -dmS pyserv${port} python -m SimpleHTTPServer ${port} 17 | 18 | if ! [[ "$(pwd)" == $old_dir ]] ; then 19 | cd $old_dir 20 | fi 21 | } 22 | 23 | PORT=8002 24 | pyserv $PORT . 25 | open http://localhost:$PORT/ 26 | 27 | echo "To put SimpleHTTPServer back to the foreground: 28 | screen -r pyserv$PORT " 29 | # screen -ls 30 | --------------------------------------------------------------------------------