├── .gitignore ├── 404.html ├── CONTRIBUTING.md ├── Gemfile ├── Gemfile.lock ├── LICENSE ├── Makefile ├── README.md ├── _config.yml ├── _data ├── assets.yml ├── carbon.yml ├── categories.yml ├── codesponsor.yml ├── content.yml ├── disqus.yml └── google_analytics.yml ├── _includes ├── 2017 │ ├── announcements-list.html │ ├── article-schema.html │ ├── code-sponsor.html │ ├── comments-area.html │ ├── critical │ │ ├── critical.js │ │ ├── home.css │ │ └── sheet.css │ ├── foot.html │ ├── head.html │ ├── meta-vars.html │ ├── pages-list-item.html │ ├── related-posts-item.html │ ├── related-posts.html │ ├── search-footer.html │ ├── search-form.html │ └── top-nav.html ├── about-the-site.html ├── common │ └── moment_format.md ├── foot.html ├── head.html ├── meta.html ├── polyfills.html ├── site-header.html ├── social-list.html └── values │ ├── description.html │ └── title.html ├── _js ├── app.js ├── behaviors │ ├── dismiss.js │ ├── dismissable.js │ ├── disqus.js │ ├── h3-section-list.js │ ├── main-body.js │ ├── no-preview.js │ ├── search-form.js │ ├── search-input.js │ ├── searchable-header.js │ └── searchable-item.js ├── critical.js ├── helpers │ ├── __tests__ │ │ └── qs.test.js │ ├── data.js │ ├── dismiss.js │ ├── dom.js │ ├── inject_disqus.js │ ├── noop.js │ ├── permutate.js │ ├── preview.js │ ├── qs.js │ ├── search.js │ └── store.js ├── initializers │ └── onmount.js └── wrapify │ ├── __tests__ │ ├── __snapshots__ │ │ └── index.test.js.snap │ └── index.test.js │ └── index.js ├── _layouts ├── 2017 │ ├── home.html │ ├── not_found.html │ └── sheet.html ├── blank.html ├── default-ad.html ├── default.html ├── home.html └── redirect.html ├── _sass ├── 2017 │ ├── base │ │ ├── base.scss │ │ └── fade.scss │ ├── components │ │ ├── announcements-item.scss │ │ ├── announcements-list.scss │ │ ├── attribute-peg.scss │ │ ├── back-button.scss │ │ ├── body-area.scss │ │ ├── code-sponsor.scss │ │ ├── comments-area.scss │ │ ├── comments-details.scss │ │ ├── comments-section.scss │ │ ├── h2-section.scss │ │ ├── h3-section-list.scss │ │ ├── h3-section.scss │ │ ├── headline-ad.scss │ │ ├── hint-mark.scss │ │ ├── home-button.scss │ │ ├── intro-content.scss │ │ ├── main-heading.scss │ │ ├── missing-message.scss │ │ ├── notice-box.scss │ │ ├── page-actions.scss │ │ ├── pages-list.scss │ │ ├── pre-footer.scss │ │ ├── push-button.scss │ │ ├── related-post-item.scss │ │ ├── related-post-list.scss │ │ ├── related-posts-area.scss │ │ ├── related-posts-callout.scss │ │ ├── related-posts-group.scss │ │ ├── related-posts-section.scss │ │ ├── search-box.scss │ │ ├── search-footer.scss │ │ ├── side-ad.scss │ │ ├── site-header.scss │ │ ├── top-nav.scss │ │ └── top-sheet.scss │ ├── markdown │ │ ├── a-em.scss │ │ ├── code.scss │ │ ├── headings.scss │ │ ├── p.scss │ │ ├── table.scss │ │ └── ul.scss │ ├── placeholders │ │ └── push-button.scss │ ├── style.scss │ ├── utils │ │ ├── _font-size.scss │ │ ├── carbon-style.scss │ │ ├── gutter.scss │ │ ├── heading-style.scss │ │ ├── section-gutter.scss │ │ └── section-with-container.scss │ └── variables.scss ├── .gitignore └── vendor │ ├── ionicons-inline │ └── ionicons.scss │ ├── modularscale │ └── _modularscale.scss │ └── sanitize.css │ └── sanitize.scss ├── _support ├── cf-prime.sh ├── cf-purge.sh ├── critical.js ├── webpack.config.js └── webpack.critical.js ├── architecture.md ├── assets ├── 2017 │ └── style.scss ├── bigger-picture-1.1.5 │ ├── bigger-picture.css │ └── bigger-picture.min.js ├── favicon.png ├── packed │ ├── app.js │ ├── app.js.map │ ├── vendor.js │ └── vendor.js.map ├── print.css ├── script.js └── style.css ├── data └── search-index.json ├── img ├── envoy-arch.svg ├── istio-arch.svg ├── istio-components.svg ├── istioctl-x.svg ├── istioctl.svg ├── prometheus-arch.svg ├── proxyless.svg ├── transparent-traffic-hijacking.svg └── xds.svg ├── index.md ├── istioctl.md ├── observability.md ├── package.json ├── robots.txt ├── samples └── traffic-management │ ├── destinationrule.yaml │ ├── gateway.yaml │ ├── virtualservice.yaml │ └── workloadentry.yaml ├── setup.md ├── sitemap.xml ├── traffic-management.md ├── webpack.config.js └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | _site 3 | node_modules 4 | -------------------------------------------------------------------------------- /404.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: 2017/not_found 3 | type: error 4 | permalink: /404.html 5 | --- 6 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Developer notes 2 | 3 | ## Starting a local instance 4 | 5 | This starts Jekyll and Webpack. 6 | 7 | ```bash 8 | yarn install 9 | bundle install 10 | env PORT=4001 yarn run dev 11 | ``` 12 | 13 | ## CSS classes 14 | 15 | See the [Cheatsheet Style](https://jimmysong.io/cheatsheets/cheatsheet-styles) for a reference on styling. 16 | 17 | ## JavaScript 18 | 19 | When updating JavaScript, be sure webpack is running (`yarn run dev` takes care of this). 20 | 21 | This auto-updates `/assets/packed/` with sources in `_js/`. 22 | 23 | ## JavaScript tests 24 | 25 | There are also automated tests: 26 | 27 | ``` 28 | yarn run test --watch 29 | ``` 30 | 31 | ## Frontmatter 32 | 33 | Each sheet supports these metadata: 34 | 35 | ```yml 36 | --- 37 | title: React.js 38 | layout: 2017/sheet # 'default' | '2017/sheet' 39 | 40 | # Optional: 41 | category: React 42 | updated: 2017-08-30 # To show in the updated list 43 | ads: false # Add this to disable ads 44 | weight: -5 # lower number = higher in related posts list 45 | deprecated: true # Don't show in related posts 46 | deprecated_by: /enzyme # Point to latest version 47 | prism_languages: [vim] # Extra syntax highlighting 48 | intro: | 49 | This is some *Markdown* at the beginning of the article. 50 | tags: 51 | - WIP 52 | - Featured 53 | 54 | # Special pages: 55 | # (don't set these for cheatsheets) 56 | type: home # home | article | error 57 | og_type: website # opengraph type 58 | --- 59 | ``` 60 | 61 | ## Prism languages 62 | 63 | For supported prism languages: 64 | 65 | - 66 | 67 | ## Setting up redirects 68 | 69 | This example sets up a redirect from `es2015` to `es6`: 70 | 71 | ```yml 72 | # /es2015.md 73 | --- 74 | title: ES2015 75 | category: Hidden 76 | redirect_to: /es6 77 | --- 78 | ``` 79 | 80 | ## Localizations 81 | 82 | See `_data/content.yml` for chrome strings. 83 | 84 | ## Forking 85 | 86 | So you want to fork this repo? Sure, here's what you need to know to whitelabel this: 87 | 88 | - It's all GitHub pages, so the branch has to be `gh-pages`. 89 | - All other GitHub pages gotchas apply (CNAME, etc). 90 | - Edit everything in `_data/` - this holds all 'config' for the site: ad IDs, strings, etc. 91 | - Edit `_config.yml` as well, lots of things may not apply to you. 92 | 93 | ## SEO description 94 | 95 | There are multiple ways to set meta description. 96 | 97 | ### keywords (and intro) 98 | 99 | Set `keywords` (and optionally `intro`). This is the easiest and the preferred 100 | way for now. 101 | 102 | ``` 103 | React cheatsheet - jimmysong.io 104 | ------------------------------ 105 | https://jimmysong.io/cheatsheets/react ▼ 106 | React.Component · render() · componentDidMount() · props/state · React is a 107 | JavaScript library for building web... 108 | ``` 109 | 110 | ### description (and intro) 111 | 112 | Set `description` (and optionally `intro`) 113 | 114 | ```bash 115 | React cheatsheet - jimmysong.io 116 | ------------------------------ 117 | https://jimmysong.io/cheatsheets/react ▼ 118 | One-page reference to React and its API. React is a JavaScript library for 119 | building web user interfaces... 120 | ``` 121 | 122 | ### intro only 123 | 124 | If you left out `description` or `keywords`, a default description will be added. 125 | 126 | ## Critical path CSS 127 | 128 | The critical path CSS is stored in: 129 | 130 | - `_includes/2017/critical/home.html` 131 | - `_includes/2017/critical/sheet.html` 132 | 133 | You'll need to update these every now and then when you change something in the CSS. Use this to update these snippets: 134 | 135 | ```bash 136 | yarn run critical 137 | ``` 138 | 139 | You can temporarily disable critical path optimizations by loading it with `?nocrit=1`, eg, `https://jimmysong.io/cheatsheets/?nocrit=1`. 140 | 141 | ## Critical path JS 142 | 143 | There's JavaScript that's included inline in every page. It's entrypoint is: 144 | 145 | - `_js/critical.js` 146 | 147 | This is automatically compiled into the partial `_includes/2017/critical/critical.js`. Keep this bundle as small as possible. 148 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | gem 'github-pages', group: :jekyll_plugins 3 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | activesupport (4.2.8) 5 | i18n (~> 0.7) 6 | minitest (~> 5.1) 7 | thread_safe (~> 0.3, >= 0.3.4) 8 | tzinfo (~> 1.1) 9 | addressable (2.5.2) 10 | public_suffix (>= 2.0.2, < 4.0) 11 | coffee-script (2.4.1) 12 | coffee-script-source 13 | execjs 14 | coffee-script-source (1.12.2) 15 | colorator (1.1.0) 16 | ethon (0.10.1) 17 | ffi (>= 1.3.0) 18 | execjs (2.7.0) 19 | faraday (0.13.1) 20 | multipart-post (>= 1.2, < 3) 21 | ffi (1.9.18) 22 | forwardable-extended (2.6.0) 23 | gemoji (3.0.0) 24 | github-pages (156) 25 | activesupport (= 4.2.8) 26 | github-pages-health-check (= 1.3.5) 27 | jekyll (= 3.5.2) 28 | jekyll-avatar (= 0.4.2) 29 | jekyll-coffeescript (= 1.0.1) 30 | jekyll-default-layout (= 0.1.4) 31 | jekyll-feed (= 0.9.2) 32 | jekyll-gist (= 1.4.1) 33 | jekyll-github-metadata (= 2.8.0) 34 | jekyll-mentions (= 1.2.0) 35 | jekyll-optional-front-matter (= 0.2.0) 36 | jekyll-paginate (= 1.1.0) 37 | jekyll-readme-index (= 0.1.0) 38 | jekyll-redirect-from (= 0.12.1) 39 | jekyll-relative-links (= 0.4.1) 40 | jekyll-sass-converter (= 1.5.0) 41 | jekyll-seo-tag (= 2.3.0) 42 | jekyll-sitemap (= 1.0.0) 43 | jekyll-swiss (= 0.4.0) 44 | jekyll-theme-architect (= 0.1.0) 45 | jekyll-theme-cayman (= 0.1.0) 46 | jekyll-theme-dinky (= 0.1.0) 47 | jekyll-theme-hacker (= 0.1.0) 48 | jekyll-theme-leap-day (= 0.1.0) 49 | jekyll-theme-merlot (= 0.1.0) 50 | jekyll-theme-midnight (= 0.1.0) 51 | jekyll-theme-minimal (= 0.1.0) 52 | jekyll-theme-modernist (= 0.1.0) 53 | jekyll-theme-primer (= 0.5.0) 54 | jekyll-theme-slate (= 0.1.0) 55 | jekyll-theme-tactile (= 0.1.0) 56 | jekyll-theme-time-machine (= 0.1.0) 57 | jekyll-titles-from-headings (= 0.4.0) 58 | jemoji (= 0.8.0) 59 | kramdown (= 1.13.2) 60 | liquid (= 4.0.0) 61 | listen (= 3.0.6) 62 | mercenary (~> 0.3) 63 | minima (= 2.1.1) 64 | rouge (= 1.11.1) 65 | terminal-table (~> 1.4) 66 | github-pages-health-check (1.3.5) 67 | addressable (~> 2.3) 68 | net-dns (~> 0.8) 69 | octokit (~> 4.0) 70 | public_suffix (~> 2.0) 71 | typhoeus (~> 0.7) 72 | html-pipeline (2.7.0) 73 | activesupport (>= 2) 74 | nokogiri (>= 1.4) 75 | i18n (0.8.6) 76 | jekyll (3.5.2) 77 | addressable (~> 2.4) 78 | colorator (~> 1.0) 79 | jekyll-sass-converter (~> 1.0) 80 | jekyll-watch (~> 1.1) 81 | kramdown (~> 1.3) 82 | liquid (~> 4.0) 83 | mercenary (~> 0.3.3) 84 | pathutil (~> 0.9) 85 | rouge (~> 1.7) 86 | safe_yaml (~> 1.0) 87 | jekyll-avatar (0.4.2) 88 | jekyll (~> 3.0) 89 | jekyll-coffeescript (1.0.1) 90 | coffee-script (~> 2.2) 91 | jekyll-default-layout (0.1.4) 92 | jekyll (~> 3.0) 93 | jekyll-feed (0.9.2) 94 | jekyll (~> 3.3) 95 | jekyll-gist (1.4.1) 96 | octokit (~> 4.2) 97 | jekyll-github-metadata (2.8.0) 98 | jekyll (~> 3.1) 99 | octokit (~> 4.0, != 4.4.0) 100 | jekyll-mentions (1.2.0) 101 | activesupport (~> 4.0) 102 | html-pipeline (~> 2.3) 103 | jekyll (~> 3.0) 104 | jekyll-optional-front-matter (0.2.0) 105 | jekyll (~> 3.0) 106 | jekyll-paginate (1.1.0) 107 | jekyll-readme-index (0.1.0) 108 | jekyll (~> 3.0) 109 | jekyll-redirect-from (0.12.1) 110 | jekyll (~> 3.3) 111 | jekyll-relative-links (0.4.1) 112 | jekyll (~> 3.3) 113 | jekyll-sass-converter (1.5.0) 114 | sass (~> 3.4) 115 | jekyll-seo-tag (2.3.0) 116 | jekyll (~> 3.3) 117 | jekyll-sitemap (1.0.0) 118 | jekyll (~> 3.3) 119 | jekyll-swiss (0.4.0) 120 | jekyll-theme-architect (0.1.0) 121 | jekyll (~> 3.5) 122 | jekyll-seo-tag (~> 2.0) 123 | jekyll-theme-cayman (0.1.0) 124 | jekyll (~> 3.5) 125 | jekyll-seo-tag (~> 2.0) 126 | jekyll-theme-dinky (0.1.0) 127 | jekyll (~> 3.5) 128 | jekyll-seo-tag (~> 2.0) 129 | jekyll-theme-hacker (0.1.0) 130 | jekyll (~> 3.5) 131 | jekyll-seo-tag (~> 2.0) 132 | jekyll-theme-leap-day (0.1.0) 133 | jekyll (~> 3.5) 134 | jekyll-seo-tag (~> 2.0) 135 | jekyll-theme-merlot (0.1.0) 136 | jekyll (~> 3.5) 137 | jekyll-seo-tag (~> 2.0) 138 | jekyll-theme-midnight (0.1.0) 139 | jekyll (~> 3.5) 140 | jekyll-seo-tag (~> 2.0) 141 | jekyll-theme-minimal (0.1.0) 142 | jekyll (~> 3.5) 143 | jekyll-seo-tag (~> 2.0) 144 | jekyll-theme-modernist (0.1.0) 145 | jekyll (~> 3.5) 146 | jekyll-seo-tag (~> 2.0) 147 | jekyll-theme-primer (0.5.0) 148 | jekyll (~> 3.5) 149 | jekyll-seo-tag (~> 2.2) 150 | jekyll-theme-slate (0.1.0) 151 | jekyll (~> 3.5) 152 | jekyll-seo-tag (~> 2.0) 153 | jekyll-theme-tactile (0.1.0) 154 | jekyll (~> 3.5) 155 | jekyll-seo-tag (~> 2.0) 156 | jekyll-theme-time-machine (0.1.0) 157 | jekyll (~> 3.5) 158 | jekyll-seo-tag (~> 2.0) 159 | jekyll-titles-from-headings (0.4.0) 160 | jekyll (~> 3.3) 161 | jekyll-watch (1.5.0) 162 | listen (~> 3.0, < 3.1) 163 | jemoji (0.8.0) 164 | activesupport (~> 4.0) 165 | gemoji (~> 3.0) 166 | html-pipeline (~> 2.2) 167 | jekyll (>= 3.0) 168 | kramdown (1.13.2) 169 | liquid (4.0.0) 170 | listen (3.0.6) 171 | rb-fsevent (>= 0.9.3) 172 | rb-inotify (>= 0.9.7) 173 | mercenary (0.3.6) 174 | mini_portile2 (2.2.0) 175 | minima (2.1.1) 176 | jekyll (~> 3.3) 177 | minitest (5.10.3) 178 | multipart-post (2.0.0) 179 | net-dns (0.8.0) 180 | nokogiri (1.8.0) 181 | mini_portile2 (~> 2.2.0) 182 | octokit (4.7.0) 183 | sawyer (~> 0.8.0, >= 0.5.3) 184 | pathutil (0.14.0) 185 | forwardable-extended (~> 2.6) 186 | public_suffix (2.0.5) 187 | rb-fsevent (0.10.2) 188 | rb-inotify (0.9.10) 189 | ffi (>= 0.5.0, < 2) 190 | rouge (1.11.1) 191 | safe_yaml (1.0.4) 192 | sass (3.5.1) 193 | sass-listen (~> 4.0.0) 194 | sass-listen (4.0.0) 195 | rb-fsevent (~> 0.9, >= 0.9.4) 196 | rb-inotify (~> 0.9, >= 0.9.7) 197 | sawyer (0.8.1) 198 | addressable (>= 2.3.5, < 2.6) 199 | faraday (~> 0.8, < 1.0) 200 | terminal-table (1.8.0) 201 | unicode-display_width (~> 1.1, >= 1.1.1) 202 | thread_safe (0.3.6) 203 | typhoeus (0.8.0) 204 | ethon (>= 0.8.0) 205 | tzinfo (1.2.3) 206 | thread_safe (~> 0.1) 207 | unicode-display_width (1.3.0) 208 | 209 | PLATFORMS 210 | ruby 211 | 212 | DEPENDENCIES 213 | github-pages 214 | 215 | BUNDLED WITH 216 | 1.11.2 217 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | npmbin := ./node_modules/.bin 2 | PORT ?= 4001 3 | 4 | # Builds intermediate files. Needs a _site built first though 5 | update: _site critical 6 | 7 | # Builds _site 8 | site: 9 | bundle exec jekyll build 10 | 11 | # Builds critical path CSS/JS 12 | critical: _site 13 | node _support/critical.js 14 | 15 | # Starts development server 16 | dev: 17 | $(npmbin)/concurrently -k -p command -c "blue,green" \ 18 | "make dev-webpack" \ 19 | "make dev-jekyll" 20 | 21 | dev-webpack: 22 | $(npmbin)/webpack --watch --colors -p 23 | 24 | dev-jekyll: 25 | if [ -f _site ]; then \ 26 | bundle exec jekyll serve --safe --trace --drafts --watch --incremental --port $(PORT); \ 27 | else \ 28 | bundle exec jekyll serve --safe --trace --drafts --watch --port $(PORT); \ 29 | fi 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Istio cheatsheet 2 | 3 | Istio configuration cheatsheets, created by Tetrate with ❤️ 4 | 5 | See [CONTRIBUTING](CONTRIBUTING.md) for developer notes. 6 | 7 | Theme by [devhints](https://devhints.io). -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | # Jekyll configuration 2 | 3 | whitelist: 4 | - jekyll-redirect-from 5 | - jekyll-github-metadata 6 | 7 | plugins: 8 | - jekyll-redirect-from 9 | - jekyll-github-metadata 10 | 11 | exclude: 12 | - Makefile 13 | - README.md 14 | - CONTRIBUTING.md 15 | - Gemfile 16 | - Gemfile.lock 17 | - CNAME 18 | - vendor 19 | - package.json 20 | - .babelrc 21 | - yarn.lock 22 | - package-lock.json 23 | - webpack.config.js 24 | - node_modules 25 | 26 | # Markdown 27 | 28 | highlighter: false 29 | markdown: kramdown 30 | kramdown: 31 | input: GFM 32 | hard_wrap: false 33 | parse_block_html: true 34 | syntax_highlighter_opts: 35 | disable: true 36 | 37 | # Defaults 38 | 39 | defaults: 40 | - scope: 41 | path: "" 42 | type: pages 43 | values: 44 | layout: "default" 45 | og_type: article 46 | type: article 47 | category: "Others" 48 | excerpt_separator: "" 49 | prism_languages: [] 50 | 51 | # Site info 52 | 53 | url: https://istio-cheatsheet.tetrate.io 54 | title: Istio cheatsheet 55 | 56 | repository: tetratelabs/istio-cheatsheet 57 | -------------------------------------------------------------------------------- /_data/assets.yml: -------------------------------------------------------------------------------- 1 | # No trailing slash 2 | preview_host: 3 | -------------------------------------------------------------------------------- /_data/carbon.yml: -------------------------------------------------------------------------------- 1 | enabled: false 2 | src: 3 | -------------------------------------------------------------------------------- /_data/categories.yml: -------------------------------------------------------------------------------- 1 | enabled: true 2 | names: 3 | - CLI 4 | - Resources 5 | - Concepts 6 | - Others 7 | -------------------------------------------------------------------------------- /_data/codesponsor.yml: -------------------------------------------------------------------------------- 1 | enabled: false 2 | id: 3 | 4 | -------------------------------------------------------------------------------- /_data/content.yml: -------------------------------------------------------------------------------- 1 | home: 2 | title: "Istio cheatsheet" 3 | tagline: | 4 | Istio configuration cheatsheet, created by Tetrate with ❤️ 5 | 6 | top_nav: 7 | title: Istio cheatsheet - Tetrate Labs 8 | edit: Edit 9 | edit_on_github: Edit this page on GitHub 10 | 11 | sheet: 12 | suffix: cheatsheet 13 | 14 | social_list: 15 | default_description: "Istio cheatsheet" 16 | description: "The ultimate cheatsheet for Istio." 17 | facebook_share: Share on Facebook 18 | twitter_share: Share on Twitter 19 | 20 | related_posts_callout: 21 | description: Over SIZE curated cheatsheets, by developers for developers. 22 | link: All cheatsheets 23 | 24 | related_posts_group: 25 | top: Top cheatsheets 26 | other: Other cheatsheets 27 | category: Other CATEGORY cheatsheets 28 | 29 | search_form: 30 | default_placeholder: Search SIZE+ cheatsheets 31 | home_placeholder: Search... 32 | prefix: cheatsheets 33 | 34 | comments_area: 35 | suffix: for this cheatsheet. 36 | link: "Write yours!" 37 | 38 | not_found: 39 | title: Not found 40 | description: Sorry, we don't have a cheatsheet for this yet. Try searching! 41 | home: Back to home 42 | 43 | announcement: 44 | id: 2017-10-26-twitter 45 | title: | 46 | Get updated 47 | body: | 48 | Follow [@tetrateio](https://twitter.com/tetrateio) on Twitter for everything about service mesh! 49 | 50 | [![](https://img.shields.io/twitter/follow/tetrateio.svg?style=social&label=@tetrateio)](https://twitter.com/tetrateio) 51 | -------------------------------------------------------------------------------- /_data/disqus.yml: -------------------------------------------------------------------------------- 1 | enabled: false 2 | host: 3 | -------------------------------------------------------------------------------- /_data/google_analytics.yml: -------------------------------------------------------------------------------- 1 | enabled: false 2 | hostname: tetrate.io 3 | id: "" 4 | -------------------------------------------------------------------------------- /_includes/2017/announcements-list.html: -------------------------------------------------------------------------------- 1 | {% if site.data.content.announcement %} 2 |
3 |
4 |

{{ site.data.content.announcement.title }}

5 |
{{ site.data.content.announcement.body | markdownify }}
6 | 7 |
8 |
9 | {% endif %} 10 | 11 | -------------------------------------------------------------------------------- /_includes/2017/article-schema.html: -------------------------------------------------------------------------------- 1 | 14 | 35 | -------------------------------------------------------------------------------- /_includes/2017/code-sponsor.html: -------------------------------------------------------------------------------- 1 | 11 | -------------------------------------------------------------------------------- /_includes/2017/comments-area.html: -------------------------------------------------------------------------------- 1 | {% assign identifier = include.page.url | remove: '.html' | remove_first: '/' %} 2 | {% if site.data.disqus.enabled %} 3 |
4 |
5 |
6 | 7 | 8 | 0 Comments 9 | 10 | {{ site.data.content.comments_area.suffix }} 11 | {{ site.data.content.comments_area.link }} 12 | 13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | 21 |
22 | {% endif %} 23 | -------------------------------------------------------------------------------- /_includes/2017/foot.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | {% for lang in page.prism_languages %}{% endfor %} 7 | -------------------------------------------------------------------------------- /_includes/2017/head.html: -------------------------------------------------------------------------------- 1 | {% include meta.html %} 2 | {% include polyfills.html %} 3 | 4 | 5 | 6 | 7 | {% if include.critical == 'home' 8 | %}{% 9 | endif 10 | %}{% 11 | if include.critical == 'sheet' 12 | %}{% 13 | endif %} 14 | 15 | 16 | 17 | 18 | 19 | 23 | 27 | -------------------------------------------------------------------------------- /_includes/2017/meta-vars.html: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | 3 | This partial assigns these variables: 4 | 5 | meta_image: "https://assets.devhints.io/previews/react.jpg" 6 | meta_description: "A comprehensive cheatsheet for React." 7 | meta_title: "React cheatsheet" 8 | depth: "1" 9 | base: "./" 10 | timestamp: "293048189123" 11 | page_url: "https://devhints.io/react" 12 | 13 | It emits some blank lines because Jekyll, lol. 14 | 15 | {% endcomment %} 16 | 17 | {% assign depth = page.url | split: '/' | size | minus: 1 %} 18 | 19 | {% assign base = '' %} 20 | {% if depth <= 1 %}{% assign base = '.' %} 21 | {% elsif depth == 2 %}{% assign base = '..' %} 22 | {% elsif depth == 3 %}{% assign base = '../..' %} 23 | {% elsif depth == 4 %}{% assign base = '../../..' %}{% endif %} 24 | 25 | {% assign timestamp = site.time | date: "%Y%m%d%H%M%S" %} 26 | 27 | {% if site.data.assets.preview_host %}{% capture meta_image %}{% 28 | if page.url == '/' 29 | %}{{ site.data.assets.preview_host }}/index.jpg?t={{ timestamp }}{% 30 | else 31 | %}{{ site.data.assets.preview_host }}{{ include.page.url | remove: '.html' }}.jpg?t={{ timestamp }}{% 32 | endif 33 | %}{% endcapture %}{% endif %} 34 | 35 | {% capture meta_title %}{% include values/title.html page=include.page %}{% endcapture %} 36 | {% assign meta_title = meta_title | strip_newlines %} 37 | 38 | {% capture meta_description %}{% include values/description.html page=include.page %}{% endcapture %} 39 | {% assign meta_description = meta_description | strip_newlines %} 40 | 41 | {% capture page_url %}{{ site.url }}{{ page.url | remove: '.html' }}{% endcapture %} 42 | -------------------------------------------------------------------------------- /_includes/2017/pages-list-item.html: -------------------------------------------------------------------------------- 1 | {% assign slug = include.page.url | remove: '.html' | remove_first: '/' %} 2 | 5 | 6 | {{ slug }} 7 | 8 | {% if include.page.layout == '2017/sheet' %} 9 | 10 | {% endif %} 11 | 12 | {{ include.page.title }} {{ include.page.redirect_to }} 13 | 14 | 15 | -------------------------------------------------------------------------------- /_includes/2017/related-posts-item.html: -------------------------------------------------------------------------------- 1 |
  • 2 | 3 | {{ include.page.title }} 4 | 5 | cheatsheet 6 | 7 | {% if include.page.layout == '2017/sheet' %} 8 | 9 | {% endif %} 10 | 11 | 12 |
  • 13 | -------------------------------------------------------------------------------- /_includes/2017/related-posts.html: -------------------------------------------------------------------------------- 1 | {% assign category_pages = site.pages 2 | | where: "category", include.page.category 3 | | where_exp: "page", "page.url != include.page.url" 4 | | where_exp: "page", "page.deprecated != true" 5 | | where_exp: "page", "page.redirect_to == null" 6 | | sort: "weight", "last" 7 | %} 8 | {% assign top_pages = site.pages 9 | | where_exp: "page", "page.url != include.page.url" 10 | | where_exp: "page", "page.deprecated != true" 11 | | sort: "weight", "last" 12 | %} 13 | {% assign size = site.pages | size %} 14 | 63 | -------------------------------------------------------------------------------- /_includes/2017/search-footer.html: -------------------------------------------------------------------------------- 1 | 13 | -------------------------------------------------------------------------------- /_includes/2017/search-form.html: -------------------------------------------------------------------------------- 1 | 20 | -------------------------------------------------------------------------------- /_includes/2017/top-nav.html: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | Params: 3 | - noshare 4 | - noedit 5 | - noback 6 | {% endcomment %} 7 | 36 | -------------------------------------------------------------------------------- /_includes/about-the-site.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |

    4 | {{ site.title }} is a collection of Istio best practices. 5 | Suggestions and corrections? Send them in. 6 | 7 | Created with ❤️ from Tetrate 8 | Theme by devhint.io 9 |

    10 | 11 | {% if page.url != '/index.html' %} 12 |

    13 | 14 |

    15 | {% endif %} 16 | 17 |

    18 |

    19 |
    20 |
    21 | -------------------------------------------------------------------------------- /_includes/common/moment_format.md: -------------------------------------------------------------------------------- 1 | ## {{ include.title }} 2 | {: .-three-column} 3 | 4 | ### Examples 5 | 6 | #### Date 7 | 8 | | Example | Output | 9 | | --- | --- | 10 | | `YYYY-MM-DD` | `2014-01-01` | 11 | | `dddd, MMMM Do YYYY` | `Friday, May 16th 2014` | 12 | {: .-shortcuts} 13 | 14 | #### Time 15 | 16 | | Example | Output | 17 | | --- | --- | 18 | | `hh:mm a` | `12:30 pm` | 19 | {: .-shortcuts} 20 | 21 | Used by [Moment.js](http://momentjs.com/docs/#/displaying/) and [date-fns/format](https://date-fns.org/v1.28.5/docs/format). Similar to Java [SimpleDateFormat](https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html). 22 | 23 | ### Date 24 | 25 | | Symbol | Example | Area | 26 | | --- | --- | --- | 27 | | `d` | `0`..`6` | **Weekday** | 28 | | `dd` | `Su` | | 29 | | `ddd` | `Sun` | | 30 | | `dddd` | `Sunday` | | 31 | | --- | --- | --- | 32 | | `YY` | `13` | **Year** | 33 | | `YYYY` | `2013` | | 34 | | --- | --- | --- | 35 | | `M` | `1`..`12` _(Jan is 1)_ | **Month** | 36 | | `Mo` | `1st`..`31st` | | 37 | | `MM` | `01`..`12` _(Jan is 1)_ | | 38 | | `MMM` | `Jan` | | 39 | | `MMMM` | `January` | | 40 | | --- | --- | --- | 41 | | `Q` | `1`..`4` | **Quarter** | 42 | | `Qo` | `1st`..`4th` | | 43 | | --- | --- | --- | 44 | | `D` | `1`..`31` | **Day** | 45 | | `Do` | `1st`..`31st` | | 46 | | `DD` | `01`..`31` | | 47 | | --- | --- | --- | 48 | | `DDD` | `1`..`365` | **Day of year** | 49 | | `DDDo` | `1st`..`365th` | | 50 | | `DDDD` | `001`..`365` | | 51 | | --- | --- | --- | 52 | | `w` | `1`..`53` | **Week of year** | 53 | | `wo` | `1st`..`53rd` | | 54 | | `ww` | `01`..`53` | | 55 | {: .-shortcuts} 56 | 57 | ### Time 58 | 59 | | Symbol | Example | Area | 60 | | --- | --- | --- | 61 | | `H` | `0`..`23` | **24h hour** | 62 | | `HH` | `00`..`23` | | 63 | | --- | --- | --- | 64 | | `h` | `1`..`12` | **12h hour** | 65 | | `hh` | `01`..`12` | | 66 | | --- | --- | --- | 67 | | `m` | `0`..`59` | **Minutes** | 68 | | `mm` | `00`..`59` | | 69 | | --- | --- | --- | 70 | | `s` | `0`..`59` | **Seconds** | 71 | | `ss` | `00`..`59` | | 72 | | --- | --- | --- | 73 | | `a` | `am` | **AM/PM** | 74 | | `A` | `AM` | | 75 | | --- | --- | --- | 76 | | `Z` | `+07:00` | **Timezone offset** | 77 | | `ZZ` | `+0730` | | 78 | | --- | --- | --- | 79 | | `S` | `0`..`9` | Deciseconds | 80 | | `SS` | `00`..`99` | Centiseconds | 81 | | `SSS` | `000`..`999` | Milliseconds | 82 | | --- | --- | --- | 83 | | `X` | | Unix timestamp | 84 | | `x` | | Millisecond Unix timestamp | 85 | {: .-shortcuts} 86 | 87 | ### Presets 88 | 89 | | Example | Output | 90 | | --- | --- | 91 | | `LT` | `8:30 PM` | 92 | | `LTS` | `8:30:25 PM` | 93 | | --- | --- | 94 | | `LL` | `August 2 1985` | 95 | | `ll` | `Aug 2 1985` | 96 | | --- | --- | 97 | | `LLL` | `August 2 1985 08:30 PM` | 98 | | `lll` | `Aug 2 1985 08:30 PM` | 99 | | --- | --- | 100 | | `LLLL` | `Thursday, August 2 1985 08:30 PM` | 101 | | `llll` | `Thu, Aug 2 1985 08:30 PM` | 102 | {: .-shortcuts} 103 | -------------------------------------------------------------------------------- /_includes/foot.html: -------------------------------------------------------------------------------- 1 | {% include about-the-site.html %} 2 | 3 | 4 | {% comment %}{% endcomment %} 5 | {% for lang in page.hljs_languages %} 6 | 7 | {% endfor %} 8 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /_includes/head.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {% include meta.html %} 5 | {% include polyfills.html %} 6 | 7 | 8 | 9 | 10 | 11 | 12 |
    13 | -------------------------------------------------------------------------------- /_includes/meta.html: -------------------------------------------------------------------------------- 1 | {% include 2017/meta-vars.html page=page %} 2 | 3 | 4 | 5 | 6 | 7 | {% if meta_title %} 8 | {{ meta_title }} 9 | 10 | 11 | 12 | {% endif %} 13 | 14 | {% if meta_image %} 15 | 16 | 17 | 18 | 19 | {% endif %} 20 | 21 | {% if meta_description %} 22 | 23 | 24 | 25 | {% endif %} 26 | 27 | 28 | 29 | {% if page.url == '/' %} 30 | 31 | 32 | {% endif %} 33 | 34 | {% if page.author %} 35 | {% for author in site.authors | where: "name", page.author %} 36 | 37 | {% if author.ogp %} 38 | 39 | {% endif %} 40 | {% endfor %} 41 | {% endif %} 42 | 43 | {% if site.title %} 44 | 45 | {% endif %} 46 | 47 | {% if site.facebook.app_id %} 48 | 49 | {% endif %} 50 | 51 | {% if site.facebook.admin %} 52 | 53 | {% endif %} 54 | 55 | {% if page.date %} 56 | 57 | {% endif %} 58 | 59 | {% if page.category %} 60 | 61 | {% endif %} 62 | 63 | {% if page.tags %} 64 | {% for tag in page.tags %} 65 | 66 | {% endfor %} 67 | {% endif %} 68 | 69 | {% if site.data.google_analytics.enabled %} 70 | 71 | 78 | {% endif %} 79 | 80 | {% if depth %} 81 | 82 | {% endif %} 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /_includes/polyfills.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 10 | -------------------------------------------------------------------------------- /_includes/site-header.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | -------------------------------------------------------------------------------- /_includes/social-list.html: -------------------------------------------------------------------------------- 1 | {% if include.page.type == 'home' %} 2 | {% assign description = site.data.content.social_list.default_description %} 3 | {% else %} 4 | {% assign description = site.data.content.social_list.description | replace: "TITLE", include.page.title %} 5 | {% endif %} 6 | 13 | -------------------------------------------------------------------------------- /_includes/values/description.html: -------------------------------------------------------------------------------- 1 | {% 2 | if page.description and page.intro 3 | %}{{ page.description }} {{ page.intro | markdownify | strip_html }}{% 4 | elsif page.description 5 | %}{{ page.description }} · One-page guide to {{ page.title }}{% 6 | elsif page.keywords and page.intro 7 | %}{{ page.keywords | join: ' · ' }} · {{ page.intro | markdownify | strip_html }}{% 8 | elsif page.keywords 9 | %}{{ page.keywords | join: ' · ' }} · One-page guide to {{ page.title }}{% 10 | elsif page.intro 11 | %}One-page guide to {{ page.title }}: usage, examples, and more. {{ page.intro | markdownify | strip_html }}{% 12 | elsif page.type == 'article' 13 | %}The one-page guide to {{ page.title }}: usage, examples, links, snippets, and more.{% 14 | else 15 | %}The one-page guide to {{ page.title }}: usage, examples, links, snippets, and more.{% 16 | endif 17 | %} 18 | -------------------------------------------------------------------------------- /_includes/values/title.html: -------------------------------------------------------------------------------- 1 | {% 2 | if page.full_title 3 | %}{{ page.full_title }}{% 4 | elsif page.type == 'article' 5 | %}{{ page.title }} cheatsheet{% 6 | elsif page.title 7 | %}{{ page.title }}{% 8 | else 9 | %}{{ site.title }}{% 10 | endif 11 | %} 12 | -------------------------------------------------------------------------------- /_js/app.js: -------------------------------------------------------------------------------- 1 | // 3rd party libs 2 | window.Prism = require('prismjs') 3 | 4 | // All the others 5 | function requireAll (r) { r.keys().forEach(r) } 6 | requireAll(require.context('./initializers/', true, /\.js$/)) 7 | requireAll(require.context('./behaviors/', true, /\.js$/)) 8 | -------------------------------------------------------------------------------- /_js/behaviors/dismiss.js: -------------------------------------------------------------------------------- 1 | import closest from 'dom101/closest' 2 | import remove from 'dom101/remove' 3 | import on from 'dom101/on' 4 | import { getData } from '../helpers/data' 5 | import onmount from 'onmount' 6 | import * as Dismiss from '../helpers/dismiss' 7 | 8 | /** 9 | * Dismiss button 10 | */ 11 | 12 | onmount('[data-js-dismiss]', function () { 13 | const parent = closest(this, '[data-js-dismissable]') 14 | const dismissable = getData(parent, 'js-dismissable') 15 | const id = (dismissable && dismissable.id) || '' 16 | 17 | on(this, 'click', e => { 18 | Dismiss.setDismissed(id) 19 | e.preventDefault() 20 | if (parent) remove(parent) 21 | }) 22 | }) 23 | -------------------------------------------------------------------------------- /_js/behaviors/dismissable.js: -------------------------------------------------------------------------------- 1 | import onmount from 'onmount' 2 | import remove from 'dom101/remove' 3 | import removeClass from 'dom101/remove-class' 4 | 5 | import { getData } from '../helpers/data' 6 | import { isDismissed } from '../helpers/dismiss' 7 | import { isPreview } from '../helpers/preview' 8 | 9 | onmount('[data-js-dismissable]', function () { 10 | const id = getData(this, 'js-dismissable').id || '' 11 | 12 | if (isPreview() || isDismissed(id)) { 13 | remove(this) 14 | } else { 15 | removeClass(this, '-hide') 16 | } 17 | }) 18 | -------------------------------------------------------------------------------- /_js/behaviors/disqus.js: -------------------------------------------------------------------------------- 1 | import onmount from 'onmount' 2 | import injectDisqus from '../helpers/inject_disqus' 3 | 4 | /** 5 | * Delay disqus by some time. It's at the bottom of the page, there's no need 6 | * for it to load fast. This will give more time to load more critical assets. 7 | */ 8 | 9 | const DISQUS_DELAY = 100 10 | 11 | /** 12 | * Injects Disqus onto the page. 13 | */ 14 | 15 | onmount('[data-js-disqus]', function () { 16 | const data = JSON.parse(this.getAttribute('data-js-disqus')) 17 | const $parent = this.parentNode 18 | $parent.setAttribute('hidden', true) 19 | 20 | window.disqus_config = function () { 21 | this.page.url = data.url 22 | this.page.identifier = data.identifier 23 | } 24 | 25 | // Disqus takes a while to load, don't do it so eagerly. 26 | window.addEventListener('load', () => { 27 | setTimeout(() => { 28 | injectDisqus(data.host) 29 | $parent.removeAttribute('hidden') 30 | }, DISQUS_DELAY) 31 | }) 32 | }) 33 | -------------------------------------------------------------------------------- /_js/behaviors/h3-section-list.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-new */ 2 | 3 | import Isotope from 'isotope-layout/dist/isotope.pkgd.js' 4 | import onmount from 'onmount' 5 | import on from 'dom101/on' 6 | import qsa from 'dom101/query-selector-all' 7 | 8 | /* 9 | * Behavior: Isotope 10 | */ 11 | 12 | onmount('[data-js-h3-section-list]', function () { 13 | const iso = new Isotope(this, { 14 | itemSelector: '.h3-section', 15 | transitionDuration: 0 16 | }) 17 | 18 | const images = qsa('img', this) 19 | 20 | images.forEach(image => { 21 | on(image, 'load', () => { 22 | iso.layout() 23 | }) 24 | }) 25 | 26 | // Insurance against weirdness on pages like devhints.io/vim, where the 27 | // critical path CSS may look different from the final CSS (because of the 28 | // tables). 29 | on(window, 'load', () => { 30 | iso.layout() 31 | }) 32 | }) 33 | -------------------------------------------------------------------------------- /_js/behaviors/main-body.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tetratelabs/istio-cheatsheet/59993e57ae0a7a6dda292db7a86e62cdaec8d211/_js/behaviors/main-body.js -------------------------------------------------------------------------------- /_js/behaviors/no-preview.js: -------------------------------------------------------------------------------- 1 | import remove from 'dom101/remove' 2 | import onmount from 'onmount' 3 | import addClass from 'dom101/add-class' 4 | 5 | import { isPreview } from '../helpers/preview' 6 | 7 | /* 8 | * Behavior: Things to remove when preview mode is on 9 | */ 10 | 11 | onmount('[data-js-no-preview]', function (b) { 12 | if (isPreview()) { 13 | remove(this) 14 | addClass(document.documentElement, 'PreviewMode') 15 | } 16 | }) 17 | -------------------------------------------------------------------------------- /_js/behaviors/search-form.js: -------------------------------------------------------------------------------- 1 | import onmount from 'onmount' 2 | import on from 'dom101/on' 3 | 4 | /** 5 | * Submitting the search form 6 | */ 7 | 8 | onmount('[data-js-search-form]', function () { 9 | on(this, 'submit', e => { 10 | e.preventDefault() 11 | 12 | const link = document.querySelector('a[data-search-index]:visible') 13 | const href = link && link.getAttribute('href') 14 | 15 | if (href) window.location = href 16 | }) 17 | }) 18 | -------------------------------------------------------------------------------- /_js/behaviors/search-input.js: -------------------------------------------------------------------------------- 1 | import onmount from 'onmount' 2 | import * as Search from '../helpers/search' 3 | import qs from '../helpers/qs' 4 | import on from 'dom101/on' 5 | 6 | onmount('[data-js-search-input]', function () { 7 | on(this, 'input', () => { 8 | const val = this.value 9 | 10 | if (val === '') { 11 | Search.showAll() 12 | } else { 13 | Search.show(val) 14 | } 15 | }) 16 | 17 | const query = (qs(window.location.search) || {}).q 18 | if (query && query.length) { 19 | this.value = query 20 | setTimeout(() => { Search.show(query) }) 21 | } 22 | }) 23 | -------------------------------------------------------------------------------- /_js/behaviors/searchable-header.js: -------------------------------------------------------------------------------- 1 | import onmount from 'onmount' 2 | import { nextUntil } from '../helpers/dom' 3 | import matches from 'dom101/matches' 4 | 5 | // Ensure that search-index is set first 6 | import './searchable-item' 7 | 8 | /** 9 | * Propagate item search indices to headers 10 | */ 11 | 12 | onmount('[data-js-searchable-header]', function () { 13 | const els = nextUntil(this, '[data-js-searchable-header]') 14 | .filter(el => matches(el, '[data-search-index]')) 15 | 16 | const keywords = els 17 | .map(n => n.getAttribute('data-search-index')) 18 | .join(' ') 19 | .split(' ') 20 | 21 | this.setAttribute('data-search-index', keywords.join(' ')) 22 | }) 23 | -------------------------------------------------------------------------------- /_js/behaviors/searchable-item.js: -------------------------------------------------------------------------------- 1 | import onmount from 'onmount' 2 | import permutate from '../helpers/permutate' 3 | 4 | /** 5 | * Sets search indices (`data-search-index` attribute) 6 | */ 7 | 8 | onmount('[data-js-searchable-item]', function () { 9 | const data = JSON.parse(this.getAttribute('data-js-searchable-item') || '{}') 10 | const words = permutate(data) 11 | 12 | this.setAttribute('data-search-index', words.join(' ')) 13 | }) 14 | -------------------------------------------------------------------------------- /_js/critical.js: -------------------------------------------------------------------------------- 1 | /* 2 | * This is the "critical path" JavaScript that will be included INLINE on every 3 | * page. Keep this as small as possible! 4 | */ 5 | 6 | import wrapify from './wrapify' 7 | import addClass from 'dom101/add-class' 8 | import on from 'dom101/on' 9 | 10 | // Transform the main body markup to make it readable. 11 | const body = document.querySelector('[data-js-main-body]') 12 | 13 | if (body) { 14 | wrapify(body) 15 | addClass(body, '-wrapified') 16 | } 17 | 18 | // Be "done" when we're done, or after a certain timeout. 19 | on(window, 'load', done) 20 | setTimeout(done, 5000) 21 | 22 | let isDone 23 | function done () { 24 | if (isDone) return 25 | addClass(document.documentElement, 'LoadDone') 26 | isDone = true 27 | } 28 | -------------------------------------------------------------------------------- /_js/helpers/__tests__/qs.test.js: -------------------------------------------------------------------------------- 1 | /* eslint-env jest */ 2 | import qs from '../qs' 3 | 4 | describe('qs()', () => { 5 | test('basic', run({ 6 | input: '?preview=1', 7 | output: { preview: '1' } 8 | })) 9 | 10 | test('two fragments', run({ 11 | input: '?a=1&b=2', 12 | output: { a: '1', b: '2' } 13 | })) 14 | 15 | function run ({ input, output }) { 16 | return function () { 17 | const result = qs(input) 18 | expect(result).toEqual(output) 19 | } 20 | } 21 | }) 22 | -------------------------------------------------------------------------------- /_js/helpers/data.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Stores and retrieves data from an element. Works like jQuery.data(). 3 | */ 4 | 5 | export function data (el, key, val) { 6 | if (typeof val !== 'undefined') { 7 | return getData(el, key) 8 | } else { 9 | return setData(el, key, val) 10 | } 11 | } 12 | 13 | export function getData (el, key) { 14 | const str = el.getAttribute('data-' + key) 15 | return JSON.parse(str || '{}') 16 | } 17 | 18 | export function setData (el, key, val) { 19 | el.setAttribute('data-' + key, JSON.stringify(val)) 20 | } 21 | -------------------------------------------------------------------------------- /_js/helpers/dismiss.js: -------------------------------------------------------------------------------- 1 | import * as Store from './store' 2 | 3 | /** 4 | * Dismisses an announcement. 5 | * 6 | * @example 7 | * setDismissed('2017-09-02-happy-birthday') 8 | */ 9 | 10 | export function setDismissed (id) { 11 | Store.update('dismissed', function (data) { 12 | data[id] = true 13 | return data 14 | }) 15 | } 16 | 17 | /** 18 | * Checks if an announcement has been dismissed before. 19 | * 20 | * @example 21 | * setDismissed('2017-09-02-happy-birthday') 22 | * isDismissed('2017-09-02-happy-birthday') => true 23 | */ 24 | 25 | export function isDismissed (id) { 26 | const data = Store.fetch('dismissed') 27 | return data && data[id] 28 | } 29 | -------------------------------------------------------------------------------- /_js/helpers/dom.js: -------------------------------------------------------------------------------- 1 | import matches from 'dom101/matches' 2 | 3 | /* 4 | * Just like jQuery.append 5 | */ 6 | 7 | export function appendMany (el, children) { 8 | children.forEach(child => { el.appendChild(child) }) 9 | } 10 | 11 | /* 12 | * Just like jQuery.nextUntil 13 | */ 14 | 15 | export function nextUntil (el, selector) { 16 | const nextEl = el.nextSibling 17 | return nextUntilTick(nextEl, selector, []) 18 | } 19 | 20 | function nextUntilTick (el, selector, acc) { 21 | if (!el) return acc 22 | 23 | const isMatch = matches(el, selector) 24 | if (isMatch) return acc 25 | 26 | return nextUntilTick(el.nextSibling, selector, [ ...acc, el ]) 27 | } 28 | 29 | /* 30 | * Just like jQuery.before 31 | */ 32 | 33 | export function before (reference, newNode) { 34 | reference.parentNode.insertBefore(newNode, reference) 35 | } 36 | 37 | /* 38 | * Like jQuery.children('selector') 39 | */ 40 | 41 | export function findChildren (el, selector) { 42 | return [].slice.call(el.children) 43 | .filter(child => matches(child, selector)) 44 | } 45 | 46 | /** 47 | * Creates a div 48 | * @private 49 | * 50 | * @example 51 | * 52 | * createDiv({ class: 'foo' }) 53 | */ 54 | 55 | export function createDiv (props) { 56 | const d = document.createElement('div') 57 | Object.keys(props).forEach(key => { 58 | d.setAttribute(key, props[key]) 59 | }) 60 | return d 61 | } 62 | -------------------------------------------------------------------------------- /_js/helpers/inject_disqus.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Injects disqus's scripts into the page. 3 | * 4 | * @example 5 | * inject('devhints.disqus.com') 6 | */ 7 | 8 | export default function inject (host) { 9 | injectEmbed(host) 10 | injectCount(host) 11 | } 12 | 13 | export function injectEmbed (host) { 14 | const d = document 15 | const s = d.createElement('script') 16 | s.src = `https://${host}/embed.js` 17 | s.setAttribute('data-timestamp', +new Date()) 18 | ;(d.head || d.body).appendChild(s) 19 | } 20 | 21 | export function injectCount (host) { 22 | const d = document 23 | const s = d.createElement('script') 24 | s.src = `https://${host}/count.js` 25 | s.id = 'dsq-count-scr' 26 | s.async = true 27 | ;(d.head || d.body).appendChild(s) 28 | } 29 | -------------------------------------------------------------------------------- /_js/helpers/noop.js: -------------------------------------------------------------------------------- 1 | /* blank */ 2 | -------------------------------------------------------------------------------- /_js/helpers/permutate.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Permutates a searcheable item. 3 | * 4 | * permutate({ 5 | * slug: 'hello-world', 6 | * category: 'greetings' 7 | * }) 8 | */ 9 | 10 | export default function permutate (data) { 11 | let words = [] 12 | if (data.slug) { 13 | words = words.concat(permutateString(data.slug)) 14 | } 15 | if (data.category) { 16 | words = words.concat(permutateString(data.category)) 17 | } 18 | return words 19 | } 20 | 21 | /* 22 | * Permutates strings. 23 | * 24 | * @example 25 | * permutateString('hi joe') 26 | * => ['h', 'hi', 'j', 'jo', 'joe'] 27 | */ 28 | 29 | export function permutateString (str) { 30 | let words = [] 31 | let inputs = splitwords(str) 32 | 33 | inputs.forEach(word => { 34 | words = words.concat(permutateWord(word)) 35 | }) 36 | 37 | return words 38 | } 39 | 40 | /** 41 | * Permutates a word. 42 | * 43 | * @example 44 | * permutateWord('hello') 45 | * => ['h', 'he', 'hel', 'hell', 'hello'] 46 | */ 47 | 48 | export function permutateWord (str) { 49 | let words = [] 50 | const len = str.length 51 | for (var i = 1; i <= len; ++i) { 52 | words.push(str.substr(0, i)) 53 | } 54 | return words 55 | } 56 | 57 | /** 58 | * Helper for splitting to words. 59 | * 60 | * @example 61 | * splitWords('Hello, world!') 62 | * => ['hello', 'world'] 63 | */ 64 | 65 | export function splitwords (str) { 66 | const words = str.toLowerCase() 67 | .split(/[ \/\-_]/) 68 | .filter(k => k && k.length !== 0) 69 | 70 | return words 71 | } 72 | -------------------------------------------------------------------------------- /_js/helpers/preview.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Checks if we're in preview mode (?preview=1). 3 | */ 4 | 5 | export function isPreview () { 6 | return window.location.search.indexOf('preview=1') !== -1 7 | } 8 | -------------------------------------------------------------------------------- /_js/helpers/qs.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Helper: minimal qs implementation 3 | */ 4 | 5 | export default function qs (search) { 6 | search = search.substr(1) 7 | const parts = search.split('&').map(p => p.split('=')) 8 | return parts.reduce((result, part) => { 9 | result[part[0]] = qsdecode(part[1]) 10 | return result 11 | }, {}) 12 | } 13 | 14 | export function qsdecode (string) { 15 | if (!string) string = '' 16 | string = string.replace(/\+/g, ' ') 17 | return string 18 | } 19 | -------------------------------------------------------------------------------- /_js/helpers/search.js: -------------------------------------------------------------------------------- 1 | import { splitwords } from './permutate' 2 | import qsa from 'dom101/query-selector-all' 3 | 4 | /** 5 | * Show everything. 6 | * 7 | * @example 8 | * Search.showAll() 9 | */ 10 | 11 | export function showAll () { 12 | qsa('[data-search-index]').forEach(el => { 13 | el.removeAttribute('aria-hidden') 14 | }) 15 | } 16 | 17 | /** 18 | * Search for a given keyword. 19 | * 20 | * @example 21 | * Search.show('hello') 22 | */ 23 | 24 | export function show (val) { 25 | const keywords = splitwords(val) 26 | 27 | if (!keywords.length) return showAll() 28 | 29 | const selectors = keywords 30 | .map(k => `[data-search-index~=${JSON.stringify(k)}]`) 31 | .join('') 32 | 33 | qsa('[data-search-index]').forEach(el => { 34 | el.setAttribute('aria-hidden', true) 35 | }) 36 | 37 | qsa(selectors).forEach(el => { 38 | el.removeAttribute('aria-hidden') 39 | }) 40 | } 41 | -------------------------------------------------------------------------------- /_js/helpers/store.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Updates a local storage key. If it doesn't exist, it defaults to an empty 3 | * object. 4 | * 5 | * @example 6 | * update('dismissed', (data) => { 7 | * data.lol = true 8 | * return data 9 | * }) 10 | */ 11 | 12 | export function update (key, fn) { 13 | if (!window.localStorage) return 14 | let data = JSON.parse(window.localStorage[key] || '{}') 15 | data = fn(data) 16 | window.localStorage[key] = JSON.stringify(data) 17 | } 18 | 19 | /** 20 | * Fetches a local storage key. 21 | * 22 | * @example 23 | * const data = fetch('dismissed') 24 | */ 25 | 26 | export function fetch (key) { 27 | if (!window.localStorage) return 28 | return JSON.parse(window.localStorage[key] || '{}') 29 | } 30 | -------------------------------------------------------------------------------- /_js/initializers/onmount.js: -------------------------------------------------------------------------------- 1 | import ready from 'dom101/ready' 2 | import onmount from 'onmount' 3 | 4 | /** 5 | * Behavior: Wrapping 6 | */ 7 | 8 | ready(() => { 9 | setTimeout(() => { onmount() }) 10 | }) 11 | -------------------------------------------------------------------------------- /_js/wrapify/__tests__/__snapshots__/index.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`h2 + pre 1`] = ` 4 |
    5 | 6 | 7 |
    10 |

    11 | heading 12 |

    13 |
    17 | 18 | 19 |
    22 |
    25 |
     28 |             (code)
     29 |           
    30 | 31 | 32 |
    33 |
    34 |
    35 |
    36 |
    37 | `; 38 | 39 | exports[`h3 with class 1`] = ` 40 |
    41 | 42 | 43 |
    46 |
    50 |
    53 |

    56 | install 57 |

    58 |
    61 | 62 | 63 |

    64 | (install) 65 |

    66 | 67 | 68 |
    69 |
    70 |
    71 |
    72 |
    73 | `; 74 | 75 | exports[`multiple h2s 1`] = ` 76 |
    77 | 78 | 79 |
    82 |

    83 | multiple h2 84 |

    85 |
    89 |
    90 |
    93 |

    94 | 95 | 96 | 97 |

    98 |
    102 |
    105 |

    106 | install 107 |

    108 |
    111 | 112 | 113 |

    114 | (install) 115 |

    116 | 117 | 118 | 119 |
    120 |
    121 |
    124 |

    125 | usage 126 |

    127 |
    130 | 131 | 132 |

    133 | (usage) 134 |

    135 | 136 | 137 | 138 |
    139 |
    140 |
    141 |
    142 |
    145 |

    146 | getting started 147 |

    148 |
    152 |
    153 |
    156 |

    157 | 158 | 159 | 160 |

    161 |
    165 |
    168 |

    169 | first 170 |

    171 |
    174 | 175 | 176 |

    177 | (first) 178 |

    179 | 180 | 181 | 182 |
    183 |
    184 |
    187 |

    188 | second 189 |

    190 |
    193 | 194 | 195 |

    196 | (second) 197 |

    198 | 199 | 200 |
    201 |
    202 |
    203 |
    204 |
    205 | `; 206 | 207 | exports[`simple usage 1`] = ` 208 |
    209 | 210 | 211 |
    214 |

    215 | simple usage 216 |

    217 |
    221 |
    222 |
    225 |

    226 | 227 | 228 | 229 |

    230 |
    234 |
    237 |

    238 | install 239 |

    240 |
    243 | 244 | 245 |

    246 | (install) 247 |

    248 | 249 | 250 | 251 |
    252 |
    253 |
    256 |

    257 | usage 258 |

    259 |
    262 | 263 | 264 |

    265 | (usage) 266 |

    267 | 268 | 269 |
    270 |
    271 |
    272 |
    273 |
    274 | `; 275 | -------------------------------------------------------------------------------- /_js/wrapify/__tests__/index.test.js: -------------------------------------------------------------------------------- 1 | /* eslint-env jest */ 2 | import wrapify from '../index' 3 | import $ from 'jquery' 4 | 5 | it('simple usage', run(` 6 |
    7 |

    simple usage

    8 | 9 |

    install

    10 |

    (install)

    11 | 12 |

    usage

    13 |

    (usage)

    14 |
    15 | `, $div => { 16 | expect($div.find('.h2-section .h3-section-list .h3-section').length).toEqual(2) 17 | })) 18 | 19 | it('h3 with class', run(` 20 |
    21 |

    install

    22 |

    (install)

    23 |
    24 | `, $div => { 25 | expect($div.find('div.h3-section.-hello').length).toEqual(1) 26 | expect($div.find('div.h3-section-list.-hello').length).toEqual(1) 27 | })) 28 | 29 | it('multiple h2s', run(` 30 |
    31 |

    multiple h2

    32 | 33 |

    install

    34 |

    (install)

    35 | 36 |

    usage

    37 |

    (usage)

    38 | 39 |

    getting started

    40 | 41 |

    first

    42 |

    (first)

    43 | 44 |

    second

    45 |

    (second)

    46 |
    47 | `)) 48 | 49 | function run (input, fn) { 50 | return function () { 51 | const $div = $(input) 52 | wrapify($div[0]) 53 | expect($div[0]).toMatchSnapshot() 54 | if (fn) fn($div) 55 | } 56 | } 57 | 58 | it('h2 + pre', run(` 59 |
    60 |

    heading

    61 |
    (code)
    62 |
    63 | `)) 64 | -------------------------------------------------------------------------------- /_js/wrapify/index.js: -------------------------------------------------------------------------------- 1 | import matches from 'dom101/matches' 2 | import addClass from 'dom101/add-class' 3 | import { appendMany, nextUntil, before, findChildren, createDiv } from '../helpers/dom' 4 | 5 | /** 6 | * Wraps h2 sections into h2-section. 7 | * Wraps h3 sections into h3-section. 8 | * 9 | * @private 10 | */ 11 | 12 | export default function wrapify (root) { 13 | // These are your H2 sections. Returns a list of .h2-section nodes. 14 | const sections = wrapifyH2(root) 15 | 16 | // For each h2 section, wrap the H3's in them 17 | sections.forEach(section => { 18 | const bodies = findChildren(section, '[data-js-h3-section-list]') 19 | bodies.forEach(body => { wrapifyH3(body) }) 20 | }) 21 | } 22 | 23 | /** 24 | * Wraps h2 sections into h2-section. 25 | * Creates and HTML structure like so: 26 | * 27 | * .h2-section 28 | * h2. 29 | * (title) 30 | * .body.h3-section-list. 31 | * (body goes here) 32 | * 33 | * @private 34 | */ 35 | 36 | function wrapifyH2 (root) { 37 | return groupify(root, { 38 | tag: 'h2', 39 | wrapperFn: () => createDiv({ class: 'h2-section' }), 40 | bodyFn: () => createDiv({ 41 | class: 'body h3-section-list', 42 | 'data-js-h3-section-list': '' 43 | }) 44 | }) 45 | } 46 | 47 | /** 48 | * Wraps h3 sections into h3-section. 49 | * Creates and HTML structure like so: 50 | * 51 | * .h3-section 52 | * h3. 53 | * (title) 54 | * .body. 55 | * (body goes here) 56 | * 57 | * @private 58 | */ 59 | 60 | function wrapifyH3 (root) { 61 | return groupify(root, { 62 | tag: 'h3', 63 | wrapperFn: () => createDiv({ class: 'h3-section' }), 64 | bodyFn: () => createDiv({ class: 'body' }) 65 | }) 66 | } 67 | 68 | /** 69 | * Groups all headings (a `tag` selector) under wrappers like `.h2-section` 70 | * (build by `wrapperFn()`). 71 | * @private 72 | */ 73 | 74 | export function groupify (el, { tag, wrapperFn, bodyFn }) { 75 | const first = el.children[0] 76 | let result = [] 77 | 78 | // Handle the markup before the first h2 79 | if (first && !matches(first, tag)) { 80 | const sibs = nextUntil(first, tag) 81 | result.push(wrap(first, null, [ first, ...sibs ])) 82 | } 83 | 84 | // Find all h3's inside it 85 | const children = findChildren(el, tag) 86 | 87 | children.forEach(child => { 88 | const sibs = nextUntil(child, tag) 89 | result.push(wrap(child, child, sibs)) 90 | }) 91 | 92 | return result 93 | 94 | function wrap (pivot, first, sibs) { 95 | const wrap = wrapperFn() 96 | 97 | const pivotClass = pivot.className 98 | if (pivotClass) addClass(wrap, pivotClass) 99 | before(pivot, wrap) 100 | 101 | const body = bodyFn() 102 | if (pivotClass) addClass(body, pivotClass) 103 | appendMany(body, sibs) 104 | 105 | if (first) wrap.appendChild(first) 106 | wrap.appendChild(body) 107 | 108 | return wrap 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /_layouts/2017/home.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {% assign featured_pages = site.pages 5 | | where_exp: "page", "page.tags contains 'Featured'" 6 | %} 7 | {% assign recent_pages = site.pages 8 | | where_exp: "page", "page.updated" 9 | | sort: "updated", "first" 10 | %} 11 | {% include 2017/head.html critical='home' %} 12 | 13 | 14 | 15 | {% include 2017/top-nav.html page=page is_home=true noedit=true noback=true %} 16 | 17 | {% if site.data.carbon.enabled %} 18 | 21 | {% endif %} 22 | 23 |
    24 | 35 | 36 |
    37 | {% for page in featured_pages %} 38 | {% include 2017/pages-list-item.html page=page class='item top-sheet' %} 39 | {% endfor %} 40 | 41 |

    42 | Recently updated 43 |

    44 | 45 | {% for page in recent_pages reversed %} 46 | {% if forloop.index <= 18 %} 47 | {% include 2017/pages-list-item.html page=page class='article item' %} 48 | {% endif %} 49 | {% endfor %} 50 | 51 | 52 | {% for category in site.data.categories.names %} 53 |

    54 | {{ category }} 55 |

    56 | 57 | {% for page in site.pages %} 58 | {% if page.category == category %} 59 | {% if page.title %} 60 | {% include 2017/pages-list-item.html page=page class='article item' %} 61 | {% endif %} 62 | {% endif %} 63 | {% endfor %} 64 | {% endfor %} 65 | 66 |
    67 |

    See something missing?

    68 |

    69 | Request cheatsheet 70 |

    71 |
    72 |
    73 |
    74 | 75 | {% include 2017/announcements-list.html %} 76 | 77 | {% include 2017/foot.html %} 78 | 79 | 80 | -------------------------------------------------------------------------------- /_layouts/2017/not_found.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {% include 2017/head.html %} 5 | 6 | 7 | 8 | {% include 2017/top-nav.html page=page noshare=true %} 9 | 10 |
    11 | 21 |
    22 | 23 | {% include 2017/foot.html %} 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /_layouts/2017/sheet.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {% include 2017/head.html critical='sheet' %} 5 | {% include 2017/article-schema.html page=page %} 6 | 7 | 8 | 9 | {% include 2017/top-nav.html page=page %} 10 | 11 |
    12 | 15 | 16 | {% if page.tags contains 'WIP' %} 17 | 20 | {% endif %} 21 | 22 | {% if page.deprecated_by %} 23 | 27 | {% endif %} 28 | 29 | {% if page.intro %} 30 |
    31 | {{ page.intro | markdownify }} 32 |
    33 | {% endif %} 34 | 35 |
    36 | {{ content }} 37 |
    38 |
    39 | 40 | 41 | 42 | {% include 2017/comments-area.html page=page %} 43 | {% include 2017/search-footer.html %} 44 | {% include 2017/related-posts.html page=page %} 45 | {% include 2017/foot.html %} 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /_layouts/blank.html: -------------------------------------------------------------------------------- 1 | {{content}} 2 | -------------------------------------------------------------------------------- /_layouts/default-ad.html: -------------------------------------------------------------------------------- 1 | --- 2 | type: article 3 | --- 4 | {% include head.html %} 5 | {% include site-header.html %} 6 | 7 |
    8 |
    9 | {% include social-list.html page=page class="-collapse" %} 10 | 11 |
    12 |

    13 |

    {{ page.title }}

    14 |
    15 | 16 |
    17 | {{ content }} 18 |
    19 | 20 | {% include social-list.html page=page %} 21 |
    22 |
    23 | 24 | {% include foot.html %} 25 | -------------------------------------------------------------------------------- /_layouts/default.html: -------------------------------------------------------------------------------- 1 | --- 2 | type: article 3 | --- 4 | {% include head.html %} 5 | {% include site-header.html %} 6 | 7 | {% include 2017/article-schema.html page=page %} 8 | 9 |
    10 |
    11 |
    12 |

    13 |

    {{ page.title }}

    14 | {% include social-list.html page=page %} 15 |
    16 | 17 |
    18 | {{ content }} 19 |
    20 | 21 | {% include social-list.html page=page %} 22 |
    23 |
    24 | 25 | {% include foot.html %} 26 | -------------------------------------------------------------------------------- /_layouts/home.html: -------------------------------------------------------------------------------- 1 | --- 2 | html_class: home 3 | type: home 4 | --- 5 | {% include head.html %} 6 | {% include site-header.html %} 7 | 8 | {% for category in site.data.categories.names %} 9 |
    10 |

    {{ category }}

    11 |
    12 |
    13 | {% for page in site.pages %} 14 | {% if page.category == category %} 15 | 16 | {{ page.title }} 17 | {{ page.url | remove: '.html' | remove: '/' }} 18 | 19 | {% endif %} 20 | {% endfor %} 21 |
    22 | {% endfor %} 23 | 24 | {% if site.data.carbon.enabled %} 25 |
    26 | 27 |
    28 | {% endif %} 29 | 30 | {% include foot.html %} 31 | -------------------------------------------------------------------------------- /_layouts/redirect.html: -------------------------------------------------------------------------------- 1 | 2 | {% assign target = page.redirect.to | remove: '.html' | replace: 'cheatsheets/cheatsheets', 'cheatsheets' %} 3 | 4 | 5 | Redirecting… 6 | 7 | 8 |

    Redirecting...

    9 | Click here if you are not redirected. 10 | 11 | 12 | -------------------------------------------------------------------------------- /_sass/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tetratelabs/istio-cheatsheet/59993e57ae0a7a6dda292db7a86e62cdaec8d211/_sass/.gitignore -------------------------------------------------------------------------------- /_sass/2017/base/base.scss: -------------------------------------------------------------------------------- 1 | /* 2 | * Base 3 | */ 4 | 5 | html, body { 6 | background: $base-body; 7 | font-family: $body-font; 8 | font-size: 14px; 9 | line-height: 1.6; 10 | color: $base-text; 11 | overflow-x: hidden; 12 | } 13 | 14 | body { 15 | @include font-size(0); 16 | padding: 0; 17 | margin: 0; 18 | } 19 | 20 | /* 21 | * Code 22 | */ 23 | 24 | pre, code { 25 | font-family: $monospace-font; 26 | letter-spacing: -0.03em; 27 | } 28 | 29 | pre { 30 | font-size: $code-size; 31 | } 32 | 33 | /* 34 | * Antialias 35 | */ 36 | 37 | *:not(pre):not(code) { 38 | -webkit-font-smoothing: antialiased; 39 | -moz-osx-font-smoothing: grayscale; 40 | } 41 | 42 | /* 43 | * Links 44 | */ 45 | 46 | a { 47 | color: $base-b; 48 | } 49 | 50 | a:visited { 51 | color: $base-b7; 52 | } 53 | 54 | a:hover { 55 | color: $base-b3; 56 | } 57 | 58 | /* prism.js adds area-hidden which it probably shouldn't */ 59 | [aria-hidden]:not(.line-highlight) { 60 | display: none !important; 61 | } 62 | 63 | // No tooltips on mobile 64 | @media (max-width: 580px) { 65 | .hint--bottom { 66 | &::before, 67 | &::after { 68 | display: none; 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /_sass/2017/base/fade.scss: -------------------------------------------------------------------------------- 1 | $bounce: cubic-bezier(.75,-0.5,0,1.75); 2 | 3 | /* 4 | * "Preloader": 5 | * This makes the content semi-transparent before the page ad loads. 6 | */ 7 | 8 | .post-content { 9 | html.WithJs & { 10 | opacity: 0; 11 | } 12 | } 13 | 14 | /* 15 | * Pop it in as the page loads 16 | */ 17 | 18 | .code-sponsor { 19 | html.WithJs & { 20 | transform: scale(0.7); 21 | opacity: 0; 22 | } 23 | 24 | html.WithJs.LoadDone & { 25 | transform: scale(1); 26 | opacity: 1; 27 | transition: transform 500ms $bounce, opacity 500ms linear; 28 | } 29 | } 30 | 31 | /* 32 | * Defer "loading" until page's onload event fires. 33 | * (The page actually already loaded, we just pretend like it hasn't) 34 | */ 35 | 36 | .pages-list, 37 | .post-content.-wrapified, 38 | .intro-content { 39 | html.WithJs & { 40 | opacity: 0.4; 41 | } 42 | 43 | html.WithJs.LoadDone & { 44 | opacity: 1; 45 | transition: opacity 100ms linear 100ms; 46 | } 47 | } 48 | 49 | /* 50 | * Subtle animation to drive attention to the ad on laod 51 | */ 52 | 53 | // .code-sponsor { 54 | // html.WithJs & { 55 | // transform: translate3d(0, 16px, 0); 56 | // } 57 | 58 | // html.WithJs.LoadDone & { 59 | // transform: translate3d(0, 0, 0); 60 | // transition: transform 200ms ease-out; 61 | // } 62 | // } 63 | -------------------------------------------------------------------------------- /_sass/2017/components/announcements-item.scss: -------------------------------------------------------------------------------- 1 | .announcements-item { 2 | & { 3 | position: relative; 4 | padding: 16px; 5 | box-shadow: $shadow6; 6 | border-radius: 1px; 7 | background: white; 8 | padding-right: 48px; 9 | animation: announcements-item-flyin 500ms ease-out; 10 | transition: opacity 500ms linear, transform 500ms ease-out; 11 | } 12 | 13 | &.-hide { 14 | display: none; 15 | } 16 | 17 | & > .title { 18 | @include font-size(1); 19 | font-weight: normal; 20 | color: $base-a; 21 | margin: 0; 22 | padding: 0; 23 | } 24 | 25 | & > .body > p { 26 | margin: 0; 27 | padding: 0; 28 | 29 | & + p { 30 | margin-top: 1em; 31 | } 32 | } 33 | 34 | & > .close { 35 | position: absolute; 36 | right: 0; 37 | top: 0; 38 | width: 40px; 39 | height: 40px; 40 | line-height: 40px; 41 | text-align: center; 42 | border: 0; 43 | margin: 0; 44 | padding: 0; 45 | cursor: pointer; 46 | 47 | &:hover, 48 | &:focus { 49 | color: $base-a; 50 | } 51 | } 52 | 53 | & > .close::before { 54 | content: "\00D7"; 55 | font-size: 14px; 56 | } 57 | } 58 | 59 | @keyframes announcements-item-flyin { 60 | 0% { 61 | transform: translate3d(0, 32px, 0); 62 | opacity: 0; 63 | } 64 | 65 | 100% { 66 | transform: translate3d(0, 0, 0); 67 | opacity: 1; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /_sass/2017/components/announcements-list.scss: -------------------------------------------------------------------------------- 1 | .announcements-list { 2 | & { 3 | position: fixed; 4 | left: 0; 5 | bottom: 0; 6 | max-width: 420px; 7 | padding: 0; 8 | z-index: 10; 9 | } 10 | 11 | @media (min-width: 481px) { 12 | padding: 16px; 13 | } 14 | 15 | @media (min-width: 769px) { 16 | padding: 32px; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /_sass/2017/components/attribute-peg.scss: -------------------------------------------------------------------------------- 1 | .attribute-peg { 2 | & { 3 | display: inline-block; 4 | height: 12px; 5 | width: 20px; 6 | text-align: center; 7 | } 8 | 9 | & > span { 10 | display: inline-block; 11 | width: 8px; 12 | height: 8px; 13 | background: saturate(lighten(#5a8, 16%), 24%); 14 | border-radius: 50%; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /_sass/2017/components/back-button.scss: -------------------------------------------------------------------------------- 1 | /* 2 | * Home link 3 | */ 4 | 5 | .back-button { 6 | text-decoration: none; 7 | width: 48px; 8 | height: 48px; 9 | line-height: 48px - 2px; 10 | text-align: center; 11 | display: inline-block; 12 | border-radius: 50%; 13 | transition: all 100ms linear; 14 | 15 | // Smaller on mobile 16 | @media (max-width: 480px) { 17 | width: 32px; 18 | height: 32px; 19 | line-height: 32px - 2; 20 | } 21 | 22 | // Colors 23 | &, 24 | &:visited { 25 | color: $base-mute; 26 | } 27 | 28 | // Active 29 | &:hover, 30 | &:focus { 31 | color: white; 32 | background: $base-a; 33 | opacity: 1; 34 | } 35 | 36 | // Icon 37 | &::before { 38 | content: ''; 39 | @include ion-md-arrow-back(24px, $base-text); 40 | vertical-align: middle; 41 | } 42 | 43 | &:hover::before, 44 | &:focus::before { 45 | @include ion-md-arrow-back(24px, white); 46 | } 47 | 48 | // Icon: smaller on mobile 49 | @media (max-width: 480px) { 50 | &::before { 51 | font-size: 16px; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /_sass/2017/components/body-area.scss: -------------------------------------------------------------------------------- 1 | .body-area { 2 | max-width: $area-width; 3 | margin: 0 auto; 4 | @include gutter(padding); 5 | 6 | &.-slim { 7 | max-width: 740px; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /_sass/2017/components/code-sponsor.scss: -------------------------------------------------------------------------------- 1 | .code-sponsor { 2 | & { 3 | text-align: center; 4 | position: relative; 5 | height: 130px; 6 | overflow: hidden; 7 | } 8 | 9 | /* Prelude */ 10 | & > .prelude { 11 | position: relative; 12 | z-index: 5; 13 | display: block; 14 | @include font-size(-1); 15 | color: lighten($gray-text, 20%); 16 | text-align: center; 17 | font-weight: normal; 18 | user-select: none; 19 | } 20 | 21 | & > .prelude > a, 22 | & > .prelude > a:visited { 23 | text-decoration: none; 24 | color: lighten($gray-text, 20%); 25 | } 26 | 27 | & > .prelude > a:hover, 28 | & > .prelude > a:focus { 29 | color: $gray-text; 30 | } 31 | 32 | /* Compensate padding to put it next to prelude */ 33 | & > div { 34 | position: relative; 35 | z-index: 1; 36 | margin-top: -16px; 37 | } 38 | 39 | /* Extra line between prelude and ad? */ 40 | & > .prelude + div { 41 | margin-top: -8px; 42 | } 43 | 44 | & > div > iframe { 45 | display: inline-block; 46 | opacity: 0.9; 47 | transition: opacity 150ms linear; 48 | } 49 | 50 | & > div:hover > iframe { 51 | opacity: 1; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /_sass/2017/components/comments-area.scss: -------------------------------------------------------------------------------- 1 | /* 2 | * Disqus 3 | */ 4 | 5 | .comments-area { 6 | & { 7 | margin: 32px 0 16px 0; 8 | } 9 | 10 | // Container 11 | & > .container { 12 | @include gutter(padding-left); 13 | @include gutter(padding-right); 14 | max-width: $area-width; 15 | margin: 0 auto; 16 | } 17 | 18 | // Horizontal line 19 | & > .container::before { 20 | content: ''; 21 | display: block; 22 | background: linear-gradient(to right, $dark-line-color 50%, transparent); 23 | height: 1px; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /_sass/2017/components/comments-details.scss: -------------------------------------------------------------------------------- 1 | /* 2 | * Comments disclosure triangle 3 | */ 4 | 5 | .comments-details { 6 | & { 7 | margin-bottom: -16px; 8 | } 9 | 10 | &[open] { 11 | margin-bottom: 0; 12 | } 13 | 14 | & > summary { 15 | @include font-size(1); 16 | color: $base-a; 17 | padding: 24px 0; 18 | white-space: nowrap; 19 | cursor: pointer; 20 | } 21 | 22 | & > summary:hover, 23 | & > summary:focus { 24 | &, 25 | & > .suffix { 26 | color: $base-a7; 27 | } 28 | 29 | & > .fauxlink { 30 | border-bottom: solid 1px $base-a7; 31 | } 32 | } 33 | 34 | & > summary > .count { 35 | font-weight: bold; 36 | } 37 | 38 | & > summary > .count::before { 39 | @include ion-md-chatboxes(24px, $base-a); 40 | content: ''; 41 | vertical-align: middle; 42 | color: $base-a; 43 | margin: 0 8px; 44 | } 45 | 46 | & > summary > .suffix { 47 | color: $base-mute; 48 | } 49 | 50 | & > summary > .fauxlink { 51 | margin-left: 4px; 52 | border-bottom: solid 1px rgba($base-a, 0.25); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /_sass/2017/components/comments-section.scss: -------------------------------------------------------------------------------- 1 | /* 2 | * Disqus 3 | */ 4 | 5 | .comments-section { 6 | & { 7 | display: flex; 8 | } 9 | 10 | // Mobile: full width 11 | @media (max-width: 768px) { 12 | & > .comments { 13 | flex: 1 0 100%; 14 | width: 100%; 15 | } 16 | } 17 | 18 | // Desktop: partial width 19 | @media (min-width: 769px) { 20 | & > .comments { 21 | flex: 0 1 66%; 22 | min-width: 300px; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /_sass/2017/components/h2-section.scss: -------------------------------------------------------------------------------- 1 | /* 2 | * h2 section 3 | */ 4 | 5 | /* Hide the first h2 heading */ 6 | .h2-section { 7 | &:first-child:not(.-no-hide) > h2 { 8 | display: none; 9 | } 10 | 11 | @media (min-width: 481px) { 12 | & + & { 13 | margin-top: 48px; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /_sass/2017/components/h3-section-list.scss: -------------------------------------------------------------------------------- 1 | /* 2 | * H3 section list: 3 | * The body that is isotoped. 4 | */ 5 | 6 | .h3-section-list { 7 | & { 8 | @include section-gutter(margin-left, $multiplier: -1); 9 | @include section-gutter(margin-right, $multiplier: -1); 10 | margin-top: 0; 11 | margin-bottom: 0; 12 | } 13 | 14 | // Clearfix 15 | &::after { 16 | content: ''; 17 | display: table; 18 | clear: both; 19 | zoom: 1; 20 | } 21 | 22 | // Each section 23 | & > .h3-section { 24 | @include section-gutter(padding); 25 | float: left; 26 | width: 100%; 27 | } 28 | 29 | @media (min-width: 769px) { 30 | & > .h3-section { 31 | padding-top: 0; 32 | } 33 | } 34 | } 35 | 36 | /* 37 | * Two column (default) 38 | */ 39 | 40 | .h3-section-list, 41 | .h3-section-list.-two-column { 42 | @media (min-width: 769px) { 43 | & > .h3-section { 44 | width: 50%; 45 | } 46 | } 47 | } 48 | 49 | /* 50 | * One column 51 | */ 52 | 53 | .h3-section-list.-one-column { 54 | & > .h3-section { 55 | width: 100%; 56 | } 57 | 58 | & > .h3-section + .h3-section { 59 | margin-top: 16px; 60 | } 61 | } 62 | 63 | /* 64 | * Three column 65 | */ 66 | 67 | .h3-section-list.-three-column { 68 | @media (min-width: 769px) { 69 | & > .h3-section { 70 | width: 50%; 71 | } 72 | } 73 | 74 | @media (min-width: 961px) { 75 | & > .h3-section { 76 | width: 33.33%; 77 | } 78 | } 79 | } 80 | 81 | /* 82 | * Three column, left reference 83 | */ 84 | 85 | .h3-section-list.-left-reference { 86 | @media (min-width: 769px) { 87 | & > .h3-section { 88 | width: 50%; 89 | } 90 | } 91 | 92 | @media (min-width: 961px) { 93 | & > .h3-section { 94 | width: 66.67%; 95 | } 96 | 97 | & > .h3-section:first-child { 98 | width: 33.33%; 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /_sass/2017/components/h3-section.scss: -------------------------------------------------------------------------------- 1 | /* 2 | * H3 section 3 | */ 4 | 5 | .h3-section > .body { 6 | & > pre { 7 | margin: 0; 8 | padding: 16px; 9 | } 10 | 11 | @media (max-width: 768px) { 12 | overflow-x: auto; 13 | } 14 | 15 | & { 16 | background: white; 17 | box-shadow: $shadow3; 18 | } 19 | 20 | /* Collapse/flush */ 21 | @media (max-width: 480px) { 22 | margin: 0 -16px; 23 | box-shadow: $shadow2; 24 | } 25 | 26 | /* Border radius */ 27 | @media (min-width: 481px) { 28 | & { 29 | border-radius: 2px; 30 | } 31 | 32 | & > :first-child { 33 | border-top-left-radius: 3px; 34 | border-top-right-radius: 3px; 35 | } 36 | 37 | & > :last-child { 38 | border-bottom-left-radius: 3px; 39 | border-bottom-right-radius: 3px; 40 | } 41 | } 42 | } 43 | 44 | /* 45 | * Heading 46 | */ 47 | 48 | .h3-section > h3 { 49 | & { 50 | margin-top: 8px; 51 | margin-bottom: 16px; 52 | white-space: nowrap; 53 | overflow: hidden; 54 | } 55 | 56 | // Mobile: the padding below h3-section is enough 57 | @media (max-width: 768px) { 58 | margin-top: 0; 59 | } 60 | 61 | // Horizontal line 62 | &::after { 63 | margin-left: 24px; 64 | content: ''; 65 | display: inline-block; 66 | vertical-align: middle; 67 | width: 100%; 68 | height: 1px; 69 | background: linear-gradient(to right, rgba($base-a, 0.2), transparent 80%); 70 | } 71 | } 72 | 73 | /* 74 | * Children 75 | */ 76 | 77 | .h3-section > .body { 78 | /* Lists */ 79 | & > ul { 80 | margin: 0; 81 | padding: 0; 82 | list-style-type: none; 83 | } 84 | 85 | & > ul > li { 86 | padding: 8px; 87 | padding-left: 32px + 4px; 88 | position: relative; 89 | } 90 | 91 | & > ul > li > p { 92 | margin: 0; 93 | padding: 0; 94 | } 95 | 96 | & > ul > li::before { 97 | content: ''; 98 | position: absolute; 99 | display: inline-block; 100 | width: 4px; 101 | height: 4px; 102 | background: $gray-text; 103 | border-radius: 50%; 104 | left: 16px; 105 | top: 16px + 2px; 106 | } 107 | 108 | & > ul > li + li { 109 | border-top: solid 1px $line-color; 110 | } 111 | 112 | /* Paragraphs */ 113 | & > p { 114 | padding: 16px; 115 | margin: 0; 116 | } 117 | 118 | /* Headings in between bodies */ 119 | & > h4 { 120 | @include font-size(-1); 121 | margin: 0; 122 | padding: 4px 16px; 123 | font-weight: normal; 124 | background: $gray-bg; 125 | color: $gray-text; 126 | 127 | & + * { 128 | border-top: solid 1px $line-color; 129 | } 130 | } 131 | 132 | /* Description paragraphs */ 133 | & > pre ~ p, 134 | & > ul ~ p, 135 | & > iframe ~ p, 136 | & > table ~ p { 137 | background: $gray-bg; 138 | color: $gray-text; 139 | 140 | /* Links */ 141 | & a, 142 | & a:visited { 143 | color: $base-text; 144 | text-decoration: none; 145 | border-bottom: solid 1px $line-color; 146 | } 147 | 148 | & a:hover { 149 | color: $base-b; 150 | } 151 | } 152 | 153 | // Line divisions 154 | & > *:not(:first-child) { 155 | border-top: solid 1px $line-color; 156 | } 157 | 158 | // Collapse paragraphs together 159 | & > p + p, 160 | & > p + p:not(:first-child) { 161 | margin-top: -1.5em; 162 | border-top: 0; 163 | } 164 | } 165 | 166 | /* 167 | * Variant: Prime 168 | */ 169 | 170 | .h3-section.-prime > .body { 171 | @media (min-width: 481px) { 172 | border-radius: 2px; 173 | box-shadow: $shadow6; 174 | } 175 | } 176 | 177 | /* 178 | * Variant: Also see :\ 179 | */ 180 | 181 | ul.-also-see.-also-see.-also-see { 182 | display: flex; 183 | flex-wrap: wrap; 184 | background: $gray-bg; 185 | 186 | & > li { 187 | flex: 1 0 20%; 188 | padding: 24px; 189 | border-top: solid 1px $dark-line-color; 190 | 191 | & + li { 192 | border-left: solid 1px $dark-line-color; 193 | } 194 | } 195 | 196 | &, 197 | & > li { 198 | list-style-type: none; 199 | } 200 | 201 | & > li::before { 202 | display: none; 203 | } 204 | 205 | & > li > a { 206 | @include font-size(1); 207 | display: block; 208 | } 209 | 210 | & > li > em { 211 | @include font-size(-1); 212 | display: block; 213 | } 214 | } 215 | -------------------------------------------------------------------------------- /_sass/2017/components/headline-ad.scss: -------------------------------------------------------------------------------- 1 | /* 2 | * Carbon ads 3 | * 4 | * .headline-ad 5 | * #carbonads 6 | * span 7 | * span.carbon-wrap 8 | * a.carbon-img > img 9 | * a.carbon-text {description} 10 | * a.carbon-poweredby {powered by Carbon} 11 | */ 12 | 13 | .HeadlineAd { 14 | @include font-size(-1); 15 | @include carbon-style; 16 | 17 | & { 18 | display: inline-block; 19 | } 20 | 21 | &, 22 | & > div > span { 23 | min-width: 130px + 16px + 64px; 24 | max-width: 380px; 25 | height: 100px; 26 | } 27 | 28 | & > div > span { 29 | display: inline-block; 30 | text-align: right; 31 | } 32 | 33 | // Clearfix 34 | & > div > span::after { 35 | content: ''; 36 | display: table; 37 | clear: both; 38 | zoom: 1; 39 | } 40 | 41 | .carbon-img { 42 | float: right; 43 | margin-left: 16px; 44 | } 45 | 46 | .carbon-text:first-line { 47 | @include font-size(1); 48 | color: $base-head; 49 | font-weight: 300; 50 | margin-bottom: -0.02em; 51 | } 52 | 53 | @media (min-width: 481px) { 54 | .carbon-poweredby::before { 55 | display: block; 56 | content: ''; 57 | width: 32px; 58 | height: 1px; 59 | background: $dark-line-color; 60 | margin: 8px (130px + 16px) 8px auto; 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /_sass/2017/components/hint-mark.scss: -------------------------------------------------------------------------------- 1 | .hint-mark { 2 | & { 3 | cursor: help; 4 | } 5 | 6 | & > i::before { 7 | content: '?'; 8 | font-size: 11px; 9 | font-weight: bold; 10 | font-style: normal; 11 | } 12 | 13 | & > i { 14 | display: inline-block; 15 | width: 16px; 16 | height: 16px; 17 | line-height: 16px - 4px; 18 | text-align: center; 19 | border-radius: 50%; 20 | background: rgba($base-b3, 0.3); 21 | color: $base-mute; 22 | margin: 0 0.4em; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /_sass/2017/components/home-button.scss: -------------------------------------------------------------------------------- 1 | /* 2 | * Home button inside `search-footer` 3 | */ 4 | 5 | .home-button { 6 | & { 7 | display: inline-block; 8 | box-shadow: inset 0 0 0 1px $dark-line-color; 9 | border-radius: 50%; 10 | } 11 | 12 | &, 13 | &:visited { 14 | color: $base-mute; 15 | } 16 | 17 | &:hover, 18 | &:focus { 19 | background-color: $base-a; 20 | color: white; 21 | } 22 | 23 | & > i::before { 24 | content: ''; 25 | @include ion-ios-home-outline(24px, $base-mute); 26 | height: 48px; 27 | line-height: 48px; 28 | width: 48px; 29 | } 30 | 31 | &:hover > i::before { 32 | background-image: ion-ios-home-image(white); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /_sass/2017/components/intro-content.scss: -------------------------------------------------------------------------------- 1 | /* 2 | * A prelude/intro to the article 3 | */ 4 | 5 | .intro-content { 6 | // Horizontal line, but I don't like how it looks! 7 | // &::before { 8 | // content: ''; 9 | // display: block; 10 | // margin-bottom: 16px; 11 | // height: 1px; 12 | // background: linear-gradient(to right, $dark-line-color, transparent 50%); 13 | 14 | // @media (min-width: 769px) { 15 | // margin-bottom: 32px; 16 | // } 17 | // } 18 | } 19 | -------------------------------------------------------------------------------- /_sass/2017/components/main-heading.scss: -------------------------------------------------------------------------------- 1 | /* 2 | * The top-level heading 3 | */ 4 | 5 | .main-heading { 6 | @include heading-style; 7 | 8 | & { 9 | margin-top: 0; 10 | margin-bottom: 0; 11 | } 12 | 13 | & > h1 { 14 | @include font-size(8); 15 | line-height: 1.2; 16 | font-weight: 200; 17 | font-family: $body-font; 18 | margin: 0; 19 | } 20 | 21 | & > h1 > em { 22 | font-style: normal; 23 | color: lighten($gray-text, 20%); 24 | } 25 | } 26 | 27 | .main-heading.-center { 28 | & > h1 { 29 | text-align: center; 30 | } 31 | 32 | & > .adbox { 33 | margin-top: 16px; 34 | text-align: center; 35 | } 36 | 37 | & > .adbox > .ad { 38 | display: inline-block; 39 | } 40 | 41 | & > .adbox > .ad.-carbon { 42 | margin-top: 16px; 43 | } 44 | 45 | // Horizontal line 46 | // (no need for now) 47 | // & > .adbox > .ad.-codesponsor::before { 48 | // content: ''; 49 | // display: block; 50 | // margin: 8px auto 24px auto; 51 | // width: 64px; 52 | // height: 1px; 53 | // background: lighten($gray-text, 40%); 54 | // } 55 | } 56 | 57 | /** 58 | * Add some space in preview mode 59 | */ 60 | 61 | .PreviewMode .main-heading { 62 | margin-top: 16px; 63 | } 64 | -------------------------------------------------------------------------------- /_sass/2017/components/missing-message.scss: -------------------------------------------------------------------------------- 1 | .missing-message.missing-message { 2 | text-align: center; 3 | margin: 32px 0; 4 | display: flex; 5 | align-items: center; 6 | border-top: solid 1px $dark-line-color; 7 | padding-top: 16px; 8 | 9 | @media (min-width: 769px) { 10 | padding-top: 32px; 11 | } 12 | 13 | & > h3, 14 | & > p { 15 | margin: 0; 16 | padding: 0; 17 | } 18 | 19 | & > h3 { 20 | @include font-size(1); 21 | font-weight: normal; 22 | color: $base-text; 23 | flex: 1 0 auto; 24 | text-align: left; 25 | } 26 | 27 | & > h3::before { 28 | content: ''; 29 | @include ion-md-arrow-forward(24px, $base-a); 30 | margin-right: 16px; 31 | } 32 | 33 | & > p { 34 | color: $base-mute; 35 | flex: 0 0 auto; 36 | } 37 | 38 | @media (max-width: 480px) { 39 | flex-wrap: wrap; 40 | 41 | & > p { 42 | margin-top: 16px; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /_sass/2017/components/notice-box.scss: -------------------------------------------------------------------------------- 1 | .notice-box { 2 | & { 3 | margin-bottom: 24px; 4 | color: $base-mute; 5 | } 6 | 7 | @media (max-width: 480px) { 8 | margin-bottom: 16px; 9 | } 10 | 11 | &::before { 12 | content: ''; 13 | @include ion-md-information-circle(24px, $base-mute3); 14 | margin-right: 8px; 15 | } 16 | 17 | & > a { 18 | text-decoration: none; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /_sass/2017/components/page-actions.scss: -------------------------------------------------------------------------------- 1 | @mixin action-bar { 2 | & { 3 | height: 32px; 4 | } 5 | 6 | & > .link.link > a { 7 | display: inline-block; 8 | height: 32px; 9 | line-height: 32px; 10 | vertical-align: top; 11 | width: auto; 12 | } 13 | 14 | & > li { 15 | margin: 0; 16 | padding: 0; 17 | list-style-type: none; 18 | } 19 | 20 | & > li > a, 21 | & > li > a:visited { 22 | color: $base-mute; 23 | text-decoration: none; 24 | } 25 | 26 | & > li > a:hover, 27 | & > li > a:focus { 28 | color: $base-a; 29 | 30 | & > .text { 31 | color: $base-a; 32 | } 33 | } 34 | 35 | & > li > a > .text { 36 | @include font-size(-1); 37 | display: none; 38 | } 39 | 40 | & > li > a > .text.-visible { 41 | display: inline; 42 | } 43 | } 44 | 45 | .page-actions { 46 | & { 47 | @include action-bar; 48 | margin: 0; 49 | padding: 0; 50 | } 51 | 52 | & + & { 53 | margin-left: 8px; 54 | } 55 | 56 | & > .facebook > a::before, 57 | & > .twitter > a::before, 58 | & > .github > a::before { 59 | content: ''; 60 | vertical-align: middle; 61 | } 62 | 63 | & > .facebook > a::before { 64 | @include ion-logo-facebook(16px, #334455); 65 | } 66 | 67 | & > .twitter > a::before { 68 | @include ion-logo-twitter(16px, #334455); 69 | } 70 | 71 | & > .github > a::before { 72 | @include ion-logo-github(16px, #334455); 73 | } 74 | 75 | & > .github > a:hover::before { 76 | background-image: ion-logo-github-image(white); 77 | } 78 | 79 | & > .facebook > a::before, 80 | & > .twitter > a::before { 81 | width: 32px; 82 | height: 32px; 83 | } 84 | 85 | // Compensate alignment 86 | & > .github > a::before { 87 | position: relative; 88 | top: -2px; 89 | } 90 | 91 | & > .link.-button > a { 92 | box-shadow: inset 0 0 0 1px $dark-line-color; 93 | border-radius: 2px; 94 | padding: 0 16px; 95 | margin: 0 8px; 96 | transition: all 100ms linear; 97 | 98 | & > .text { 99 | margin-left: 4px; 100 | position: relative; 101 | top: -1px; 102 | } 103 | 104 | &:hover, 105 | &:focus { 106 | background: $base-a-gradient; 107 | box-shadow: $shadow2; 108 | 109 | &, 110 | & > .text { 111 | color: white; 112 | } 113 | } 114 | } 115 | 116 | // Space them out in mobile 117 | @media (max-width: 768px) { 118 | & > .link { 119 | margin-left: 16px; 120 | } 121 | } 122 | 123 | // Collapse 124 | & > .link:first-child > a { 125 | margin-left: 0; 126 | } 127 | 128 | & > .link:last-child > a { 129 | margin-right: 0; 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /_sass/2017/components/pages-list.scss: -------------------------------------------------------------------------------- 1 | // search-box.scss 2 | 3 | .pages-list { 4 | & { 5 | display: flex; 6 | flex-wrap: wrap; 7 | } 8 | 9 | > .item { 10 | flex: 0 0 100%; 11 | } 12 | 13 | > .item.article { 14 | flex: 0 0 50%; 15 | } 16 | 17 | @media (min-width: 581px) { 18 | > .item.top-sheet { 19 | flex: 0 0 25%; 20 | } 21 | } 22 | } 23 | 24 | // Article 25 | .pages-list > .article { 26 | text-decoration: none; 27 | display: block; 28 | white-space: nowrap; 29 | padding: 4px 0; 30 | 31 | &, 32 | &:visited { 33 | color: $base-mute3; 34 | } 35 | 36 | & > .info > .slug { 37 | color: $base-head; 38 | } 39 | 40 | &:visited > .info > .slug { 41 | color: $base-text; 42 | } 43 | 44 | & > .info > .title::before { 45 | content: ''; 46 | margin: 0 4px; 47 | } 48 | 49 | & > .info > .title { 50 | opacity: 0; 51 | } 52 | 53 | @media (max-width: 768px) { 54 | & > .info > .title { 55 | display: none; 56 | } 57 | } 58 | 59 | &:hover, 60 | &:focus { 61 | & { 62 | color: $base-mute; 63 | } 64 | 65 | & > .info > .title { 66 | opacity: 1; 67 | color: $base-a; 68 | } 69 | } 70 | } 71 | 72 | .pages-list > .category { 73 | @include font-size(1); 74 | border-bottom: solid 1px $dark-line-color; 75 | margin: 16px 0; 76 | padding: 0 0 16px 0; 77 | font-weight: normal; 78 | color: $base-a; 79 | } 80 | -------------------------------------------------------------------------------- /_sass/2017/components/pre-footer.scss: -------------------------------------------------------------------------------- 1 | /* 2 | content: ''; 3 | * Spacer before footer 4 | */ 5 | 6 | .pre-footer { 7 | & { 8 | padding: 32px; 9 | padding-top: 24px; 10 | padding-bottom: 48px; 11 | text-align: center; 12 | } 13 | 14 | & > .icon::before { 15 | content: ''; 16 | @include ion-ios-flash(32px, $base-mute); 17 | opacity: 0.25; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /_sass/2017/components/push-button.scss: -------------------------------------------------------------------------------- 1 | .push-button { 2 | @extend %push-button; 3 | } 4 | -------------------------------------------------------------------------------- /_sass/2017/components/related-post-item.scss: -------------------------------------------------------------------------------- 1 | .related-post-item { 2 | & { 3 | display: flex; 4 | text-align: left; 5 | line-height: 1.4; 6 | } 7 | 8 | // Layout 9 | & > a { 10 | flex: 1 1 100%; 11 | display: block; 12 | border-radius: 2px; 13 | box-shadow: $shadow2; 14 | padding: 16px; 15 | text-decoration: none; 16 | } 17 | 18 | // Color 19 | & > a, 20 | & > a:visited { 21 | background: white; 22 | color: $base-mute; 23 | 24 | & > strong { 25 | color: $base-a; 26 | } 27 | 28 | &:hover, 29 | &:focus { 30 | color: $base-a; 31 | } 32 | 33 | &:hover > strong, 34 | &:focus > strong { 35 | color: darken($base-a, 16%); 36 | } 37 | } 38 | 39 | &:first-of-type > a, 40 | &:first-of-type > a:visited { 41 | background: $base-a; 42 | color: rgba(white, 0.5); 43 | 44 | & > strong { 45 | color: white; 46 | } 47 | 48 | &:hover, 49 | &:focus { 50 | color: white; 51 | } 52 | 53 | &:hover > strong, 54 | &:focus > strong { 55 | color: white; 56 | } 57 | 58 | &:hover, 59 | &:focus { 60 | background: darken($base-a, 8%); 61 | } 62 | } 63 | 64 | // Two lines when bigger 65 | @media (min-width: 481px) { 66 | & > a > strong, 67 | & > a > span { 68 | display: block; 69 | } 70 | } 71 | 72 | & > a > strong { 73 | @include font-size(1); 74 | font-weight: normal; 75 | } 76 | 77 | & > a > span { 78 | @include font-size(-1); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /_sass/2017/components/related-post-list.scss: -------------------------------------------------------------------------------- 1 | .related-post-list { 2 | &, 3 | & > li { 4 | margin: 0; 5 | padding: 0; 6 | list-style-type: none; 7 | } 8 | 9 | & { 10 | display: flex; 11 | margin: -4px; 12 | flex-wrap: wrap; 13 | } 14 | 15 | @media (max-width: 768px) { 16 | flex-wrap: wrap; 17 | } 18 | 19 | & > .item { 20 | flex: 1 1 auto; 21 | margin: 4px; 22 | 23 | @media (min-width: 481px) { 24 | flex: 1 1 40%; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /_sass/2017/components/related-posts-area.scss: -------------------------------------------------------------------------------- 1 | /* 2 | * Related posts 3 | */ 4 | 5 | .related-posts-area { 6 | & { 7 | @include section-with-container; 8 | padding-top: 16px; 9 | padding-bottom: 16px; 10 | background: $gray-bg; 11 | } 12 | 13 | @media (min-width: 481px) { 14 | padding-top: 64px; 15 | padding-bottom: 64px; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /_sass/2017/components/related-posts-callout.scss: -------------------------------------------------------------------------------- 1 | /* 2 | * Callout 3 | */ 4 | 5 | .related-posts-callout { 6 | & { 7 | display: flex; 8 | text-decoration: none; 9 | background: $base-a-gradient; 10 | padding: 32px; 11 | align-items: center; 12 | justify-content: center; 13 | color: white; 14 | border-radius: 2px; 15 | box-shadow: $shadow2; 16 | text-shadow: 0 1px 1px rgba(black, 0.2); 17 | } 18 | 19 | &, 20 | &:visited { 21 | color: white; 22 | } 23 | 24 | &:hover, 25 | &:focus { 26 | background: darken($base-a, 8%); 27 | } 28 | 29 | & > .text { 30 | margin: auto; 31 | text-align: center; 32 | } 33 | 34 | & > .text > .icon { 35 | margin-bottom: 16px; 36 | display: block; 37 | } 38 | 39 | & > .text > .icon::before { 40 | content: ''; 41 | @include ion-ios-arrow-back(48px, adjust-color($base-a, $lightness: 16%, $hue: 20deg)); 42 | height: 64px; 43 | width: 64px; 44 | border: solid 2px adjust-color($base-a, $lightness: 16%, $hue: 20deg); 45 | border-radius: 50%; 46 | text-indent: -2px; 47 | text-shadow: none; 48 | } 49 | 50 | & > .text > .description { 51 | @include font-size(1); 52 | line-height: 1.4; 53 | font-weight: 300; 54 | display: block; 55 | margin-bottom: 16px; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /_sass/2017/components/related-posts-group.scss: -------------------------------------------------------------------------------- 1 | /* 2 | * Group 3 | */ 4 | 5 | .related-posts-group { 6 | & > h3 { 7 | @include font-size(1); 8 | color: $base-a; 9 | margin: 0; 10 | padding: 0; 11 | margin-bottom: 16px; 12 | padding-bottom: 16px; 13 | border-bottom: solid 1px $dark-line-color; 14 | line-height: 1.2; 15 | font-weight: 400; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /_sass/2017/components/related-posts-section.scss: -------------------------------------------------------------------------------- 1 | /* 2 | * Section 3 | * has callout and group 4 | */ 5 | 6 | .related-posts-section { 7 | & { 8 | display: flex; 9 | @include section-gutter(margin-left, $multiplier: -1); 10 | @include section-gutter(margin-right, $multiplier: -1); 11 | } 12 | 13 | & > .callout, 14 | & > .group { 15 | margin: 0; 16 | @include section-gutter(margin-left); 17 | @include section-gutter(margin-right); 18 | } 19 | 20 | & > .callout { 21 | flex: 1 1 33%; 22 | } 23 | 24 | & > .group { 25 | flex: 1 1 50%; 26 | } 27 | 28 | & > .callout { 29 | display: flex; 30 | 31 | & > * { 32 | flex: 1 0 100%; 33 | } 34 | } 35 | 36 | // Mobile 37 | @media (max-width: 480px) { 38 | & { 39 | flex-wrap: wrap; 40 | } 41 | 42 | & > .callout, 43 | & > .group { 44 | @include section-gutter(margin-top); 45 | @include section-gutter(margin-bottom); 46 | flex: 1 1 100%; 47 | } 48 | } 49 | 50 | // Tablet 51 | @media (min-width: 481px) { 52 | @media (max-width: 768px) { 53 | & { 54 | flex-wrap: wrap; 55 | } 56 | 57 | & > .callout, 58 | & > .group { 59 | @include section-gutter(margin-top); 60 | @include section-gutter(margin-bottom); 61 | flex: 1 1 100%; 62 | } 63 | 64 | & > .group { 65 | flex: 1 1 40%; 66 | } 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /_sass/2017/components/search-box.scss: -------------------------------------------------------------------------------- 1 | .search-box { 2 | background: $base-panel; 3 | box-shadow: $shadow3; 4 | display: flex; 5 | height: 64px; 6 | align-items: center; 7 | cursor: text; 8 | 9 | & > input { 10 | font-family: $body-font; 11 | @include font-size(2); 12 | padding: 16px; 13 | height: 64px; 14 | background: transparent; 15 | border: 0; 16 | flex: 1 1 auto; 17 | padding-left: 0; 18 | font-weight: bold; 19 | color: $base-head; 20 | min-width: 48px; 21 | 22 | &::placeholder { 23 | font-weight: normal; 24 | color: $base-mute; 25 | } 26 | } 27 | 28 | & > input:focus { 29 | outline: 0; 30 | } 31 | 32 | & > .prefix { 33 | @include font-size(0); 34 | display: block; 35 | color: rgba($base-mute, 0.5); 36 | font-weight: 400; 37 | user-select: none; 38 | line-height: 1.5em; 39 | padding: 2px 8px; 40 | border-radius: 3px; 41 | background: rgba($base-body, 0.5); 42 | margin: 0 0 0 16px; 43 | box-shadow: 0 1px 1px rgba($base-mute, 0.25); 44 | } 45 | 46 | & > .sep { 47 | color: rgba($base-mute, 0.5); 48 | @include font-size(2); 49 | margin: 0 8px; 50 | } 51 | 52 | // Hide prefix in mobiel 53 | @media (max-width: 768px) { 54 | & > .prefix, 55 | & > .sep { 56 | display: none; 57 | } 58 | 59 | & > input { 60 | padding-left: 16px; 61 | } 62 | } 63 | 64 | // Icon 65 | &::before { 66 | content: ''; 67 | @include ion-md-search(32px, $base-head); 68 | background-position: center center; 69 | flex: 0 0 64px; 70 | width: 64px; 71 | order: 2; 72 | } 73 | } 74 | 75 | /* 76 | * Small 77 | */ 78 | 79 | .search-box.-small { 80 | & { 81 | height: 48px; 82 | } 83 | 84 | & > input { 85 | padding: 8px; 86 | height: 48px; 87 | padding-left: 0; 88 | } 89 | 90 | & > .prefix, 91 | & > .sep, 92 | & > input { 93 | @include font-size(1); 94 | } 95 | 96 | &::before { 97 | flex: 0 0 48px; 98 | width: 48px; 99 | line-height: 48px; 100 | background-size: 24px 24px; 101 | background-position: center center; 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /_sass/2017/components/search-footer.scss: -------------------------------------------------------------------------------- 1 | /* 2 | * Search bar around the footer 3 | */ 4 | 5 | .search-footer { 6 | & { 7 | @include section-with-container; 8 | padding-top: 16px; 9 | padding-bottom: 16px; 10 | background: $gray-bg; 11 | border-top: solid 1px $dark-line-color; 12 | border-bottom: solid 1px $dark-line-color; 13 | } 14 | } 15 | 16 | .search-footer-section { 17 | & { 18 | display: flex; 19 | } 20 | 21 | & > .search { 22 | flex: 0 1 640px; 23 | } 24 | 25 | & > .links { 26 | @include gutter(padding-left); 27 | flex: 0 1 auto; 28 | margin-left: auto; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /_sass/2017/components/side-ad.scss: -------------------------------------------------------------------------------- 1 | .SideAd { 2 | @include font-size(-1); 3 | @include carbon-style; 4 | 5 | @media (min-width: 961px) { 6 | position: absolute; 7 | right: 32px; 8 | top: 80px; 9 | width: 130px; 10 | text-align: left; 11 | 12 | .carbon-img { 13 | margin-bottom: 16px; 14 | } 15 | } 16 | 17 | .carbon-text:first-line { 18 | color: $base-head; 19 | font-weight: bold; 20 | } 21 | 22 | .carbon-poweredby::before { 23 | display: block; 24 | content: ''; 25 | width: 32px; 26 | height: 1px; 27 | background: $dark-line-color; 28 | margin: 12px 0; 29 | } 30 | 31 | @media (max-width: 960px) { 32 | & { 33 | margin: 16px auto; 34 | max-width: 300px; 35 | } 36 | 37 | &::after { 38 | content: ''; 39 | display: table; 40 | clear: both; 41 | zoom: 1; 42 | } 43 | 44 | .carbon-img { 45 | float: left; 46 | margin-right: 16px; 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /_sass/2017/components/site-header.scss: -------------------------------------------------------------------------------- 1 | .site-header { 2 | margin: 32px 0; 3 | 4 | & > p { 5 | margin: 0; 6 | padding: 0; 7 | text-align: center; 8 | color: $base-mute; 9 | } 10 | 11 | & > p > a { 12 | text-decoration: none; 13 | } 14 | 15 | & > h1 { 16 | @include font-size(8); 17 | line-height: 1.2; 18 | margin: 0; 19 | padding: 0; 20 | color: $base-head; 21 | font-weight: 200; 22 | text-align: center; 23 | margin-bottom: 16px; 24 | } 25 | 26 | & > .search { 27 | margin-top: 32px; 28 | } 29 | 30 | & > .action { 31 | margin-top: 32px; 32 | } 33 | 34 | & > .adbox { 35 | margin-top: 32px; 36 | margin-bottom: -16px; 37 | } 38 | 39 | @media (max-width: 480px) { 40 | & > .adbox { 41 | margin-left: -16px; 42 | margin-right: -16px; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /_sass/2017/components/top-nav.scss: -------------------------------------------------------------------------------- 1 | .top-nav { 2 | &, 3 | & > .container { 4 | height: 64px; 5 | line-height: 64px; 6 | text-align: center; 7 | position: relative; 8 | } 9 | 10 | // Smaller on mobile 11 | @media (max-width: 480px) { 12 | & > .container { 13 | height: 32px; 14 | line-height: 32px; 15 | margin-top: 8px; 16 | } 17 | 18 | & { 19 | height: 32px + 8px + 8px; 20 | padding: 8px 0; 21 | border-bottom: solid 1px $dark-line-color; 22 | margin-bottom: 8px; 23 | } 24 | } 25 | 26 | & > .container { 27 | @include gutter(padding-left); 28 | @include gutter(padding-right); 29 | max-width: $area-width; 30 | margin: 0 auto; 31 | } 32 | } 33 | 34 | .top-nav > .container { 35 | & { 36 | display: flex; 37 | align-items: center; 38 | position: relative; 39 | } 40 | 41 | & > .left { 42 | flex: 0 0 auto; 43 | line-height: 32px; 44 | } 45 | 46 | & > .brand { 47 | flex: 1 1 auto; 48 | } 49 | 50 | & > .actions { 51 | flex: 0 0 auto; 52 | display: flex; 53 | } 54 | 55 | & > .brand { 56 | @include font-size(-1); 57 | display: inline-block; 58 | font-weight: bold; 59 | text-transform: uppercase; 60 | letter-spacing: 0.05em; 61 | text-decoration: none; 62 | 63 | &, 64 | &:visited { 65 | color: $base-text; 66 | } 67 | 68 | &:hover { 69 | color: $base-a; 70 | } 71 | } 72 | 73 | // Mobile 74 | @media (max-width: 480px) { 75 | & > .brand { 76 | display: none; 77 | } 78 | 79 | & > .actions { 80 | margin-left: auto; 81 | } 82 | } 83 | 84 | // Desktop: absolute the actions 85 | @media (min-width: 481px) { 86 | & > .actions { 87 | position: absolute; 88 | @include gutter(right); 89 | top: (64px - 32px) / 2; 90 | } 91 | 92 | & > .left { 93 | position: absolute; 94 | @include gutter(left); 95 | top: (64px - 32px) / 2; 96 | } 97 | } 98 | 99 | // Offset so it doesn't look misasligned 100 | @media (min-width: $area-width) { 101 | & > .left > .home { 102 | position: relative; 103 | left: -16px; 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /_sass/2017/components/top-sheet.scss: -------------------------------------------------------------------------------- 1 | .top-sheet.top-sheet { 2 | padding: 4px; 3 | text-decoration: none; 4 | 5 | & > .info { 6 | display: block; 7 | background: darken($base-a, 0%); 8 | color: white; 9 | text-align: left; 10 | padding: 16px; 11 | width: auto; 12 | border-radius: 3px; 13 | box-shadow: $shadow2; 14 | text-shadow: 0 1px 1px rgba($base-text, 0.3); 15 | white-space: nowrap; 16 | } 17 | 18 | &:hover > .info, 19 | &:focus > .info { 20 | box-shadow: $shadow3; 21 | } 22 | 23 | &:nth-of-type(3n + 1) { 24 | & > .info { 25 | background: linear-gradient( 26 | 15deg, 27 | $base-a, 28 | adjust-color($base-a, $lightness: 4%, $hue: 20deg)); 29 | } 30 | 31 | &:hover > .info, 32 | &:focus > .info { 33 | background: darken($base-a, 8%); 34 | } 35 | } 36 | 37 | &:nth-of-type(3n + 2) { 38 | & > .info { 39 | background: linear-gradient( 40 | 15deg, 41 | $base-mute, 42 | adjust-color($base-mute, $lightness: 4%, $hue: -10deg)); 43 | } 44 | 45 | &:hover > .info, 46 | &:focus > .info { 47 | background: darken($base-mute, 8%); 48 | } 49 | } 50 | 51 | &:nth-of-type(3n + 3) { 52 | & > .info { 53 | background: linear-gradient( 54 | 15deg, 55 | $base-c, 56 | adjust-color($base-c, $lightness: 2%, $hue: 6deg)); 57 | } 58 | 59 | &:hover > .info, 60 | &:focus > .info { 61 | background: darken($base-c, 8%); 62 | } 63 | } 64 | 65 | & > .info > .title { 66 | display: none; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /_sass/2017/markdown/a-em.scss: -------------------------------------------------------------------------------- 1 | /* 2 | * For links with sources, eg, 3 | * [Foo](foo.com) _(foo.com)_ 4 | */ 5 | 6 | .MarkdownBody.MarkdownBody { 7 | a + em { 8 | opacity: 0.5; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /_sass/2017/markdown/code.scss: -------------------------------------------------------------------------------- 1 | .MarkdownBody code { 2 | color: $gray-text; 3 | font-size: $code-size; 4 | } 5 | 6 | .MarkdownBody pre, 7 | .MarkdownBody code { 8 | font-family: $monospace-font; 9 | } 10 | 11 | // Reduce line height for box drawing characters 12 | .MarkdownBody pre.-box-chars { 13 | line-height: 1.32; 14 | } 15 | 16 | // For figlet.md 17 | .MarkdownBody pre.-figlet { 18 | line-height: 1; 19 | font-size: 11px; 20 | } 21 | 22 | /* 23 | * Undo prism theme crap 24 | */ 25 | 26 | .MarkdownBody { 27 | pre { 28 | box-shadow: none; 29 | border-left: 0; 30 | overflow: hidden; 31 | overflow-x: auto; 32 | background: white; 33 | font-size: $code-size; 34 | line-height: $code-line-height; 35 | } 36 | 37 | pre.-wrap { 38 | white-space: pre-wrap; 39 | } 40 | 41 | pre > code { 42 | color: $base-head; 43 | max-height: auto; 44 | padding: 0; 45 | background: transparent; 46 | overflow: visible; 47 | font-size: 1em; 48 | } 49 | 50 | // Line highlight 51 | .line-highlight { 52 | transform: translate3d(0, 2px, 0); 53 | background: linear-gradient( 54 | to right, 55 | rgba($base-c, 0.05) 25%, 56 | transparent); 57 | } 58 | 59 | // Line highlight ranges 60 | .line-highlight[data-end] { 61 | margin-top: 0; 62 | } 63 | 64 | .line-highlight::before, 65 | .line-highlight::after { 66 | display: none; 67 | } 68 | } 69 | 70 | .MarkdownBody pre.-setup, 71 | .MarkdownBody p.-setup, 72 | .MarkdownBody ul.-setup, 73 | .MarkdownBody p.-crosslink { 74 | background: $gray-bg; 75 | } 76 | 77 | /* 78 | * Syntax kighlight 79 | */ 80 | 81 | .token { 82 | $cA: $base-b; 83 | $cA-3: adjust-color($cA, $lightness: 8%, $hue: -10deg); 84 | $cA-7: adjust-color($cA, $lightness: -8%, $hue: 10deg); 85 | 86 | $cB: $base-c; 87 | $cB-3: adjust-color($cB, $lightness: 8%, $hue: -10deg); 88 | 89 | $cM: #aaa; // Mute 90 | 91 | &.tag, 92 | &.keyword { 93 | color: $cA; 94 | } 95 | 96 | &.tag { 97 | color: $cA-7; 98 | } 99 | 100 | &.value, 101 | &.string, 102 | &.number, 103 | &.attr-value, 104 | &.boolean, 105 | &.regex { 106 | color: $cB; 107 | } 108 | 109 | &.function, 110 | &.attr-name { 111 | color: $cA-3; 112 | } 113 | 114 | &.comment, 115 | &.punctuation, 116 | &.operator { 117 | color: $cM; 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /_sass/2017/markdown/headings.scss: -------------------------------------------------------------------------------- 1 | /* 2 | * MarkdownBody context 3 | */ 4 | 5 | .MarkdownBody h2 { 6 | @include heading-style; 7 | @include font-size(6); 8 | line-height: 1.2; 9 | font-weight: 200; 10 | font-family: $heading-font; 11 | margin-top: 0; 12 | } 13 | 14 | .MarkdownBody h3 { 15 | margin: 0; 16 | padding: 0; 17 | margin-bottom: 16px; 18 | font-family: $heading-font; 19 | @include font-size(2); 20 | font-weight: 400; 21 | color: $base-a; 22 | } 23 | 24 | .MarkdownBody { 25 | a, 26 | a:visited { 27 | color: $base-b; 28 | text-decoration: none; 29 | } 30 | 31 | a:hover { 32 | text-decoration: underline; 33 | } 34 | 35 | em { 36 | font-style: normal; 37 | color: $gray-text; 38 | } 39 | 40 | iframe { 41 | border: 0; 42 | margin: 0; 43 | width: 100%; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /_sass/2017/markdown/p.scss: -------------------------------------------------------------------------------- 1 | /* 2 | * Crosslink (eg, phoenix.md) 3 | */ 4 | 5 | .MarkdownBody.MarkdownBody { 6 | img { 7 | max-width: 100%; 8 | } 9 | } 10 | 11 | .MarkdownBody.MarkdownBody p.-crosslink { 12 | & > a { 13 | display: block; 14 | text-decoration: none; 15 | color: $base-a; 16 | border-bottom: 0; 17 | box-shadow: none; 18 | margin: -16px; 19 | padding: 16px; 20 | } 21 | 22 | & > a:visited { 23 | color: $base-a; 24 | } 25 | 26 | & > a::before { 27 | content: ''; 28 | @include ion-md-arrow-forward(16px, white); 29 | margin-right: 16px; 30 | width: 32px; 31 | height: 32px; 32 | line-height: 32px; 33 | border-radius: 50%; 34 | } 35 | 36 | & > a, 37 | & > a:visited { 38 | &::before { 39 | background-color: $base-a; 40 | color: white; 41 | } 42 | } 43 | 44 | & > a:hover, 45 | & > a:focus { 46 | & { 47 | color: $base-a7; 48 | } 49 | 50 | &::before { 51 | background-color: $base-a7; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /_sass/2017/markdown/table.scss: -------------------------------------------------------------------------------- 1 | @mixin table-align-left { 2 | & tr th, 3 | & tr td, 4 | & tr td:last-child { 5 | text-align: left; 6 | } 7 | } 8 | 9 | /* 10 | * Table 11 | */ 12 | 13 | .MarkdownBody table { 14 | & { 15 | width: 100%; 16 | } 17 | 18 | & tr + tr { 19 | border-top: solid 1px $line-color; 20 | } 21 | 22 | /* Horizontal lines */ 23 | & tbody + tbody { 24 | border-top: solid 1px $dark-line-color; 25 | } 26 | 27 | & td, 28 | & th { 29 | padding: 8px 16px; 30 | vertical-align: top; 31 | text-align: left; 32 | } 33 | 34 | & tr th:last-child, 35 | & tr td:last-child { 36 | text-align: right; 37 | } 38 | 39 | & td:first-child { 40 | white-space: nowrap; 41 | } 42 | 43 | & td > code { 44 | font-size: $code-size; 45 | } 46 | 47 | & td:first-child > code { 48 | color: #35a; 49 | } 50 | 51 | & a, 52 | & a:visited { 53 | color: #35a; 54 | text-decoration: none; 55 | } 56 | 57 | & td:first-child > code ~ em { 58 | @include font-size(-1); 59 | font-style: normal; 60 | color: $gray-text; 61 | } 62 | 63 | & thead { 64 | display: none; 65 | } 66 | 67 | & thead th { 68 | font-weight: normal; 69 | color: $base-a; 70 | } 71 | } 72 | 73 | .MarkdownBody table.-shortcuts { 74 | td:first-child > code { 75 | font-size: 1rem; 76 | padding: 5px 6px; 77 | padding-left: 8px; // compensation 78 | background: $gray-bg; 79 | border-radius: 3px; 80 | margin-right: 2px; 81 | letter-spacing: 0.1em; 82 | color: $base-text; 83 | } 84 | } 85 | 86 | .MarkdownBody table.-left-align { 87 | @include table-align-left; 88 | } 89 | 90 | .MarkdownBody table.-headers { 91 | & thead { 92 | display: table-header-group; 93 | border-bottom: solid 1px $dark-line-color; 94 | } 95 | } 96 | 97 | /* 98 | * Key-value pairs (like in css) 99 | */ 100 | 101 | .MarkdownBody table.-key-values { 102 | & tbody tr td + td code { 103 | display: block; 104 | } 105 | } 106 | 107 | .MarkdownBody table.-css-breakdown { 108 | @include table-align-left; 109 | 110 | & tr td { 111 | @include font-size(1); 112 | white-space: nowrap; 113 | } 114 | 115 | & tr td:not(:last-child) { 116 | padding-right: 4px; 117 | } 118 | 119 | & tr td:not(:first-child) { 120 | padding-left: 4px; 121 | } 122 | 123 | & tr:last-child { 124 | background: $gray-bg; 125 | } 126 | 127 | & tr:last-child td { 128 | @include font-size(-1); 129 | color: $base-mute; 130 | white-space: auto; 131 | } 132 | } 133 | 134 | .MarkdownBody table.-bold-first { 135 | & tr > td:first-child { 136 | font-weight: bold; 137 | } 138 | } 139 | 140 | .MarkdownBody table.-no-wrap { 141 | & td, 142 | & th { 143 | white-space: nowrap; 144 | } 145 | } 146 | 147 | .MarkdownBody table.-mute-em { 148 | & td, 149 | & th { 150 | & em { 151 | opacity: 0.5; 152 | } 153 | 154 | & em > code { 155 | margin-right: 0.5em; 156 | } 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /_sass/2017/markdown/ul.scss: -------------------------------------------------------------------------------- 1 | .MarkdownBody ul.-six-column { 2 | & { 3 | display: flex; 4 | flex-wrap: wrap; 5 | } 6 | 7 | & > li { 8 | flex: 0 0 (100% / 6); 9 | 10 | @media (max-width: 480px) { 11 | flex: 0 0 (100% / 2); 12 | } 13 | 14 | @media (max-width: 768px) { 15 | flex: 0 0 (100% / 4); 16 | } 17 | } 18 | } 19 | 20 | .MarkdownBody ul.-four-column { 21 | & { 22 | display: flex; 23 | flex-wrap: wrap; 24 | } 25 | 26 | & > li { 27 | flex: 0 0 (100% / 4); 28 | 29 | @media (max-width: 480px) { 30 | flex: 0 0 (100% / 2); 31 | } 32 | 33 | @media (max-width: 768px) { 34 | flex: 0 0 (100% / 3); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /_sass/2017/placeholders/push-button.scss: -------------------------------------------------------------------------------- 1 | %push-button { 2 | display: inline-block; 3 | text-decoration: none; 4 | padding: 8px 16px; 5 | border-radius: 3px; 6 | 7 | &, 8 | &:visited { 9 | background-color: $base-a; 10 | background: $base-a-gradient; 11 | color: white; 12 | } 13 | 14 | &:hover, 15 | &:focus { 16 | background: darken($base-a, 16%); 17 | box-shadow: none; 18 | color: white; 19 | } 20 | } 21 | 22 | %push-button.-dark { 23 | &, 24 | &:visited { 25 | background: darken($base-a, 16%); 26 | color: white; 27 | } 28 | 29 | &:hover, 30 | &:focus { 31 | background: darken($base-a, 24%); 32 | color: white; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /_sass/2017/style.scss: -------------------------------------------------------------------------------- 1 | @import '../vendor/sanitize.css/sanitize'; 2 | @import './variables'; 3 | @import '../vendor/modularscale/modularscale'; 4 | @import '../vendor/ionicons-inline/ionicons'; 5 | @import './utils/carbon-style'; 6 | @import './utils/font-size'; 7 | @import './utils/gutter'; 8 | @import './utils/heading-style'; 9 | @import './utils/section-gutter'; 10 | @import './utils/section-with-container'; 11 | @import './placeholders/push-button'; 12 | @import './base/base'; 13 | @import './base/fade'; 14 | @import './markdown/a-em'; 15 | @import './markdown/code'; 16 | @import './markdown/headings'; 17 | @import './markdown/p'; 18 | @import './markdown/table'; 19 | @import './markdown/ul'; 20 | @import './components/attribute-peg'; 21 | @import './components/announcements-item'; 22 | @import './components/announcements-list'; 23 | @import './components/back-button'; 24 | @import './components/body-area'; 25 | @import './components/code-sponsor'; 26 | @import './components/comments-area'; 27 | @import './components/comments-details'; 28 | @import './components/comments-section'; 29 | @import './components/h2-section'; 30 | @import './components/h3-section'; 31 | @import './components/h3-section-list'; 32 | @import './components/headline-ad'; 33 | @import './components/hint-mark'; 34 | @import './components/home-button'; 35 | @import './components/intro-content'; 36 | @import './components/main-heading'; 37 | @import './components/missing-message'; 38 | @import './components/notice-box'; 39 | @import './components/page-actions'; 40 | @import './components/pages-list'; 41 | @import './components/pre-footer'; 42 | @import './components/push-button'; 43 | @import './components/related-posts-area'; 44 | @import './components/related-posts-callout'; 45 | @import './components/related-posts-group'; 46 | @import './components/related-posts-section'; 47 | @import './components/related-post-list'; 48 | @import './components/related-post-item'; 49 | @import './components/search-box'; 50 | @import './components/search-footer'; 51 | @import './components/side-ad'; 52 | @import './components/site-header'; 53 | @import './components/top-nav'; 54 | @import './components/top-sheet'; 55 | 56 | -------------------------------------------------------------------------------- /_sass/2017/utils/_font-size.scss: -------------------------------------------------------------------------------- 1 | @mixin font-size ($n) { 2 | @include ms-respond(font-size, $n); 3 | } 4 | -------------------------------------------------------------------------------- /_sass/2017/utils/carbon-style.scss: -------------------------------------------------------------------------------- 1 | /* 2 | * Base carbon ads style 3 | */ 4 | 5 | @mixin carbon-style { 6 | .carbon-img, 7 | .carbon-text, 8 | .carbon-poweredby { 9 | text-decoration: none; 10 | display: block; 11 | } 12 | 13 | .carbon-img { 14 | width: 130px; 15 | height: 100px; 16 | box-shadow: $shadow3; 17 | } 18 | 19 | .carbon-img > img { 20 | border-radius: 3px; 21 | background: white; 22 | } 23 | 24 | .carbon-img:hover { 25 | transform: translate3d(0, -1px, 0); 26 | box-shadow: $shadow6; 27 | } 28 | 29 | .carbon-text, 30 | .carbon-text:visited { 31 | color: $gray-text; 32 | } 33 | 34 | .carbon-poweredby, 35 | .carbon-poweredby:visited { 36 | color: lighten($gray-text, 20%); 37 | } 38 | 39 | .carbon-text:hover, 40 | .carbon-poweredby:hover { 41 | color: $base-a; 42 | } 43 | } 44 | 45 | -------------------------------------------------------------------------------- /_sass/2017/utils/gutter.scss: -------------------------------------------------------------------------------- 1 | @mixin gutter ($property, $multiplier: 1) { 2 | #{$property}: $gut * $multiplier; 3 | 4 | @media (max-width: 480px) { 5 | #{$property}: $gut-small * $multiplier; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /_sass/2017/utils/heading-style.scss: -------------------------------------------------------------------------------- 1 | @mixin heading-style { 2 | margin: 0; 3 | padding: 0; 4 | margin-bottom: 16px + 8px; 5 | margin-top: 64px; 6 | position: relative; 7 | 8 | @media (max-width: 768px) { 9 | margin-bottom: 8px; 10 | margin-top: 32px; 11 | } 12 | 13 | @media (max-width: 480px) { 14 | margin-bottom: 8px; 15 | margin-top: 32px; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /_sass/2017/utils/section-gutter.scss: -------------------------------------------------------------------------------- 1 | @mixin section-gutter($property, $multiplier: 1) { 2 | #{$property}: 16px * $multiplier; 3 | 4 | @media (max-width: $area-width + 32px) { 5 | #{$property}: 8px * $multiplier; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /_sass/2017/utils/section-with-container.scss: -------------------------------------------------------------------------------- 1 | @mixin section-with-container { 2 | & > .container { 3 | @include gutter(padding-left); 4 | @include gutter(padding-right); 5 | max-width: $area-width; 6 | margin: 0 auto; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /_sass/2017/variables.scss: -------------------------------------------------------------------------------- 1 | /* 2 | * Metrics 3 | */ 4 | 5 | $gut-small: 16px; // max 480px width 6 | $gut: 16px; 7 | $column: 400px; 8 | $code-size: 0.96em; 9 | $code-line-height: 1.5; 10 | $area-width: $column * 3 + 32px; 11 | 12 | /* 13 | * Fonts 14 | */ 15 | 16 | $system-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; 17 | $system-mono: 'SFMono-Regular', Consolas, Menlo, 'Liberation Mono', 'Ubuntu Mono', Courier, monospace; 18 | $body-font: $system-sans; 19 | $heading-font: $system-sans; 20 | $monospace-font: cousine, $system-mono; 21 | 22 | /* 23 | * Base colors 24 | */ 25 | 26 | $base-body: #f1f3f5; 27 | $base-panel: white; 28 | $base-head: #111; 29 | $base-text: #345; 30 | $base-mute: #667788; // gray 31 | 32 | $base-a: adjust-color(#F05623, $lightness: -5%); // orange 33 | $base-b: adjust-color(#2b72a2, $lightness: -5%); // blue 34 | $base-c: adjust-color(#000717, $lightness: -5%); // black 35 | 36 | $base-a3: adjust-color($base-a, $lightness: 16%, $hue: -20deg); 37 | $base-a7: adjust-color($base-a, $lightness: -16%, $hue: 20deg); 38 | $base-b3: adjust-color($base-b, $lightness: 16%, $hue: -20deg); 39 | $base-b7: adjust-color($base-b, $lightness: -16%, $hue: 20deg); 40 | $base-mute7: adjust-color($base-mute, $lightness: -16%); 41 | $base-mute6: adjust-color($base-mute, $lightness: -8%); 42 | $base-mute4: adjust-color($base-mute, $lightness: 8%); 43 | $base-mute3: adjust-color($base-mute, $lightness: 16%); 44 | 45 | $body-bg: $base-body; 46 | $gray-bg: mix($base-body, $base-panel, 50%); 47 | $gray-text: $base-mute; 48 | 49 | $line-color: rgba($base-mute, 0.05); 50 | $dark-line-color: rgba($base-mute, 0.2); 51 | 52 | // 53 | // Variants 54 | // 55 | 56 | $base-a-gradient: linear-gradient( 57 | 5deg, 58 | $base-a, 59 | adjust-color($base-a, $lightness: 2%, $hue: 16deg)); 60 | 61 | // 62 | // Shadows 63 | // 64 | 65 | $shadow2: 66 | 0 1px 1px rgba($base-mute, 0.55); 67 | 68 | $shadow3: 69 | 0 6px 8px rgba($base-mute, 0.03), 70 | 0 1px 2px rgba($base-mute, 0.30); 71 | 72 | $shadow6: 73 | 0 6px 8px rgba($base-mute, 0.03), 74 | 0 1px 2px rgba($base-mute, 0.30), 75 | 0 8px 12px rgba($base-b3, 0.1); 76 | 77 | /* 78 | * Mod scale 79 | */ 80 | 81 | $modularscale: ( 82 | base: 14px, ratio: 1.2, 83 | 480px: (base: 13px, ratio: 1.15), 84 | 768px: (base: 14px, ratio: 1.16), 85 | 1280px: (base: 14px, ratio: 1.17) 86 | ); 87 | -------------------------------------------------------------------------------- /_sass/vendor/modularscale/_modularscale.scss: -------------------------------------------------------------------------------- 1 | // https://github.com/modularscale/modularscale-sass v3.0.3 2 | 3 | // Ratios 4 | $double-octave : 4 ; 5 | $pi : 3.14159265359 ; 6 | $major-twelfth : 3 ; 7 | $major-eleventh : 2.666666667 ; 8 | $major-tenth : 2.5 ; 9 | $octave : 2 ; 10 | $major-seventh : 1.875 ; 11 | $minor-seventh : 1.777777778 ; 12 | $major-sixth : 1.666666667 ; 13 | $phi : 1.618034 ; 14 | $golden : $phi ; 15 | $minor-sixth : 1.6 ; 16 | $fifth : 1.5 ; 17 | $augmented-fourth : 1.41421 ; 18 | $fourth : 1.333333333 ; 19 | $major-third : 1.25 ; 20 | $minor-third : 1.2 ; 21 | $major-second : 1.125 ; 22 | $minor-second : 1.066666667 ; 23 | 24 | // Base config 25 | $ms-base : 1em !default; 26 | $ms-ratio : $fifth !default; 27 | $modularscale : () !default;// Parse settings starting with defaults. 28 | // Settings should cascade down like you would expect in CSS. 29 | // More specific overrides previous settings. 30 | 31 | @function ms-settings($b: false, $r: false, $t: false, $m: $modularscale) { 32 | $base: $ms-base; 33 | $ratio: $ms-ratio; 34 | $thread: map-get($m, $t); 35 | 36 | // Override with user settings 37 | @if map-get($m, base) { 38 | $base: map-get($m, base); 39 | } 40 | @if map-get($m, ratio) { 41 | $ratio: map-get($m, ratio); 42 | } 43 | 44 | // Override with thread settings 45 | @if $thread { 46 | @if map-get($thread, base) { 47 | $base: map-get($thread, base); 48 | } 49 | @if map-get($thread, ratio) { 50 | $ratio: map-get($thread, ratio); 51 | } 52 | } 53 | 54 | // Override with inline settings 55 | @if $b { 56 | $base: $b; 57 | } 58 | @if $r { 59 | $ratio: $r; 60 | } 61 | 62 | @return $base $ratio; 63 | }// Sass does not have native pow() support so this needs to be added. 64 | // Compass and other libs implement this more extensively. 65 | // In order to keep this simple, use those when they are avalible. 66 | // Issue for pow() support in Sass: https://github.com/sass/sass/issues/684 67 | 68 | @function ms-pow($b,$e) { 69 | 70 | // Return 1 if exponent is 0 71 | @if $e == 0 { 72 | @return 1; 73 | } 74 | 75 | // If pow() exists (compass or mathsass) use that. 76 | @if function-exists('pow') { 77 | @return pow($b,$e); 78 | } 79 | 80 | // This does not support non-integer exponents, 81 | // Check and return an error if a non-integer exponent is passed. 82 | @if (floor($e) != $e) { 83 | @error ' 84 | ====================================================================== 85 | Non-integer values are not supported in modularscale by default. 86 | 87 | Try using mathsass in your project to add non-integer scale support. 88 | https://github.com/terkel/mathsass 89 | ====================================================================== 90 | ' 91 | } 92 | 93 | // Seed the return. 94 | $ms-return: $b; 95 | 96 | // Multiply or divide by the specified number of times. 97 | @if $e > 0 { 98 | @for $i from 1 to $e { 99 | $ms-return: $ms-return * $b; 100 | } 101 | } 102 | @if $e < 0 { 103 | @for $i from $e through 0 { 104 | $ms-return: $ms-return / $b; 105 | } 106 | } 107 | @return $ms-return; 108 | }// Stripping units is not a best practice 109 | // This function should not be used elsewhere 110 | // It is used here because calc() doesn't do unit logic 111 | // AND target ratios use units as a hack to get a number. 112 | @function ms-unitless($val) { 113 | @return ($val / ($val - $val + 1)); 114 | }// Basic list sorting 115 | // Would like to replace with http://sassmeister.com/gist/30e4863bd03ce0e1617c 116 | // Unfortunately libsass has a bug with passing arguments into the min() funciton. 117 | 118 | @function ms-sort($l) { 119 | 120 | // loop until the list is confirmed to be sorted 121 | $sorted: false; 122 | @while $sorted == false { 123 | 124 | // Start with the assumption that the lists are sorted. 125 | $sorted: true; 126 | 127 | // Loop through the list, checking each value with the one next to it. 128 | // Swap the values if they need to be swapped. 129 | // Not super fast but simple and modular scale doesn't lean hard on sorting. 130 | @for $i from 2 through length($l) { 131 | $n1: nth($l,$i - 1); 132 | $n2: nth($l,$i); 133 | 134 | // If the first value is greater than the 2nd, swap them. 135 | @if $n1 > $n2 { 136 | $l: set-nth($l, $i, $n1); 137 | $l: set-nth($l, $i - 1, $n2); 138 | 139 | // The list isn't sorted and needs to be looped through again. 140 | $sorted: false; 141 | } 142 | } 143 | } 144 | 145 | // Return the sorted list. 146 | @return $l; 147 | }// No reason to have decimal pixel values, 148 | // normalize them to whole numbers. 149 | 150 | @function ms-round-px($r) { 151 | @if unit($r) == 'px' { 152 | @return round($r); 153 | } 154 | @return $r; 155 | }// Convert number string to number 156 | @function ms-to-num($n) { 157 | $l: str-length($n); 158 | $r: 0; 159 | $m: str-index($n,'.'); 160 | @if $m == null { 161 | $m: $l + 1; 162 | } 163 | // Loop through digits and convert to numbers 164 | @for $i from 1 through $l { 165 | $v: str-slice($n,$i,$i); 166 | @if $v == '1' { $v: 1; } 167 | @elseif $v == '2' { $v: 2; } 168 | @elseif $v == '3' { $v: 3; } 169 | @elseif $v == '4' { $v: 4; } 170 | @elseif $v == '5' { $v: 5; } 171 | @elseif $v == '6' { $v: 6; } 172 | @elseif $v == '7' { $v: 7; } 173 | @elseif $v == '8' { $v: 8; } 174 | @elseif $v == '9' { $v: 9; } 175 | @elseif $v == '0' { $v: 0; } 176 | @else { $v: null; } 177 | @if $v != null { 178 | $m: $m - 1; 179 | $r: $r + ms-pow(10,$m - 1) * $v; 180 | } @else { 181 | $l: $l - 1; 182 | } 183 | } 184 | @return $r; 185 | } 186 | 187 | // Find a ratio based on a target value 188 | @function ms-target($t,$b) { 189 | // Convert to string 190 | $t: $t + ''; 191 | // Remove base units to calulate ratio 192 | $b: ms-unitless(nth($b,1)); 193 | // Find where 'at' is in the string 194 | $at: str-index($t,'at'); 195 | 196 | // Slice the value and target out 197 | // and convert strings to numbers 198 | $v: ms-to-num(str-slice($t,0,$at - 1)); 199 | $t: ms-to-num(str-slice($t,$at + 2)); 200 | 201 | // Solve the modular scale function for the ratio. 202 | @return ms-pow(($v/$b),(1/$t)); 203 | }@function ms-function($v: 0, $base: false, $ratio: false, $thread: false, $settings: $modularscale) { 204 | 205 | // Parse settings 206 | $ms-settings: ms-settings($base,$ratio,$thread,$settings); 207 | $base: nth($ms-settings, 1); 208 | $ratio: nth($ms-settings, 2); 209 | 210 | // Render target values from settings. 211 | @if unit($ratio) != '' { 212 | $ratio: ms-target($ratio,$base) 213 | } 214 | 215 | // Fast calc if not multi stranded 216 | @if(length($base) == 1) { 217 | @return ms-round-px(ms-pow($ratio, $v) * $base); 218 | } 219 | 220 | // Create new base array 221 | $ms-bases: nth($base,1); 222 | 223 | // Normalize base values 224 | @for $i from 2 through length($base) { 225 | // initial base value 226 | $ms-base: nth($base,$i); 227 | // If the base is bigger than the main base 228 | @if($ms-base > nth($base,1)) { 229 | // divide the value until it aligns with main base. 230 | @while($ms-base > nth($base,1)) { 231 | $ms-base: $ms-base / $ratio; 232 | } 233 | $ms-base: $ms-base * $ratio; 234 | } 235 | // If the base is smaller than the main base. 236 | @elseif ($ms-base < nth($base,1)) { 237 | // pump up the value until it aligns with main base. 238 | @while $ms-base < nth($base,1) { 239 | $ms-base: $ms-base * $ratio; 240 | } 241 | } 242 | // Push into new array 243 | $ms-bases: append($ms-bases,$ms-base); 244 | } 245 | 246 | // Sort array from smallest to largest. 247 | $ms-bases: ms-sort($ms-bases); 248 | 249 | // Find step to use in calculation 250 | $vtep: floor($v / length($ms-bases)); 251 | // Find base to use in calculation 252 | $ms-base: round(($v / length($ms-bases) - $vtep) * length($ms-bases)) + 1; 253 | 254 | @return ms-round-px(ms-pow($ratio, $vtep) * nth($ms-bases,$ms-base)); 255 | }// Generate calc() function 256 | // based on Mike Riethmuller's Precise control over responsive typography 257 | // http://madebymike.com.au/writing/precise-control-responsive-typography/ 258 | @function ms-fluid($val1: 1em, $val2: 1em, $break1: 0, $break2: 0) { 259 | $diff: ms-unitless($val2) - ms-unitless($val1); 260 | 261 | // v1 + (v2 - v1) * ( (100vw - b1) / b2 - b1 ) 262 | @return calc( #{$val1} + #{ms-unitless($val2) - ms-unitless($val1)} * ( ( 100vw - #{$break1}) / #{ms-unitless($break2) - ms-unitless($break1)} ) ); 263 | } 264 | 265 | // Main responsive mixin 266 | @mixin ms-respond($prop, $val, $map: $modularscale) { 267 | $base: $ms-base; 268 | $ratio: $ms-ratio; 269 | 270 | $first-write: true; 271 | $last-break: null; 272 | 273 | // loop through all settings with a breakpoint type value 274 | @each $v, $s in $map { 275 | @if type-of($v) == number { 276 | @if unit($v) != '' { 277 | 278 | // Write out the first value without a media query. 279 | @if $first-write { 280 | #{$prop}: ms-function($val, $thread: $v, $settings: $map); 281 | 282 | // Not the first write anymore, reset to false to move on. 283 | $first-write: false; 284 | $last-break: $v; 285 | } 286 | 287 | // Write intermediate breakpoints. 288 | @else { 289 | @media (min-width: $last-break) and (max-width: $v) { 290 | $val1: ms-function($val, $thread: $last-break, $settings: $map); 291 | $val2: ms-function($val, $thread: $v, $settings: $map); 292 | #{$prop}: ms-fluid($val1,$val2,$last-break,$v); 293 | } 294 | $last-break: $v; 295 | } 296 | } 297 | } 298 | } 299 | 300 | // Write the last breakpoint. 301 | @if $last-break { 302 | @media (min-width: $last-break) { 303 | #{$prop}: ms-function($val, $thread: $last-break, $settings: $map); 304 | } 305 | } 306 | }// To attempt to avoid conflicts with other libraries 307 | // all funcitons are namespaced with `ms-`. 308 | // However, to increase usability, a shorthand function is included here. 309 | 310 | @function ms($v: 0, $base: false, $ratio: false, $thread: false, $settings: $modularscale) { 311 | @return ms-function($v, $base, $ratio, $thread, $settings); 312 | } 313 | -------------------------------------------------------------------------------- /_support/cf-prime.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ( 4 | echo https://devhints.io/ 5 | ( 6 | git ls-files \ 7 | | grep -E '\.md$' \ 8 | | grep -v -E 'CONTRIBUTING|README|Readme' \ 9 | | grep -v -E '^_' \ 10 | | sort \ 11 | | uniq \ 12 | | sed 's/\.md$//g' 13 | ) \ 14 | | sed 's#^#https://devhints.io/#g' 15 | ) \ 16 | | xargs curl >/dev/null 17 | -------------------------------------------------------------------------------- /_support/cf-purge.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Helper to copy the latest cheatsheets to the clipboard for CloudFlare 3 | # purging. This ensures visitors will see new versions. 4 | 5 | ( 6 | git log "master@{3 days ago}..HEAD" --pretty="" --name-only \ 7 | | grep -E '\.md$' \ 8 | | grep -v -E 'CONTRIBUTING|README|Readme' \ 9 | | grep -v -E '^_' \ 10 | | sort \ 11 | | uniq \ 12 | | sed 's/\.md$//g' 13 | ) \ 14 | | sed 's#^#https://devhints.io/#g' \ 15 | | xargs echo https://devhints.io/ \ 16 | | pbcopy 17 | 18 | echo "Copied to clipboard." 19 | echo "Purge it here:" 20 | echo "" 21 | echo " https://www.cloudflare.com/a/caching/devhints.io" 22 | echo "" 23 | echo "Then click 'Purge Individual Files'" 24 | -------------------------------------------------------------------------------- /_support/critical.js: -------------------------------------------------------------------------------- 1 | const critical = require('critical') 2 | 3 | console.warn('Generating critical path styles into _includes/2017/critical/...') 4 | 5 | const OPTIONS = { 6 | base: '_site', 7 | width: 1400, 8 | height: 900, 9 | minify: true, 10 | extract: true, 11 | ignore: [ 12 | '@font-face' 13 | ], 14 | include: [ 15 | // fade-in magic (base/fade) 16 | /html\.WithJs/ 17 | ] 18 | } 19 | 20 | critical.generate({ 21 | ...OPTIONS, 22 | src: 'index.html', 23 | dest: '../_includes/2017/critical/home.css', 24 | include: [ 25 | ...OPTIONS.include, 26 | 27 | // searchbox with placeholder 28 | /\.search-box/ 29 | ] 30 | }) 31 | 32 | critical.generate({ 33 | ...OPTIONS, 34 | src: 'react.html', 35 | dest: '../_includes/2017/critical/sheet.css', 36 | include: [ 37 | ...OPTIONS.include, 38 | 39 | // sections (and h3 section list), just to be sure 40 | /\.h3-section/, 41 | 42 | // eg, -six-column in devhints.io/layout-thrashing 43 | /-column/ 44 | ] 45 | }) 46 | -------------------------------------------------------------------------------- /_support/webpack.config.js: -------------------------------------------------------------------------------- 1 | const join = require('path').resolve 2 | const webpack = require('webpack') 3 | 4 | module.exports = { 5 | context: join(__dirname, '..'), 6 | entry: { 7 | app: './_js/app.js', 8 | vendor: [ 9 | // Large 3rd-party libs 10 | 'prismjs', 11 | 12 | // Prism plugins 13 | 'prismjs/plugins/line-highlight/prism-line-highlight.min.js', 14 | 'prismjs/components/prism-jsx.min.js', 15 | 'prismjs/components/prism-bash.min.js', 16 | 'prismjs/components/prism-scss.min.js', 17 | 'prismjs/components/prism-css.min.js', 18 | 'prismjs/components/prism-elixir.min.js', 19 | 'prismjs/components/prism-ruby.min.js', 20 | 21 | // CSS 22 | 'prismjs/plugins/line-highlight/prism-line-highlight.css', 23 | 'hint.css/hint.min.css' 24 | ] 25 | }, 26 | output: { 27 | path: join(__dirname, '..', 'assets', 'packed'), 28 | filename: '[name].js', 29 | devtoolModuleFilenameTemplate: 'webpack:///[absolute-resource-path]' 30 | }, 31 | module: { 32 | rules: [ 33 | { 34 | test: /\.js$/, 35 | exclude: /node_modules/, 36 | use: [ 37 | { loader: 'babel-loader' } 38 | ] 39 | }, 40 | { 41 | test: /\.css$/, 42 | use: [ 43 | { loader: 'style-loader' }, 44 | { loader: 'css-loader' } 45 | ] 46 | } 47 | ] 48 | }, 49 | resolve: { 50 | alias: { 51 | // Never bundle jQuery 52 | 'jquery': join(__dirname, '..', '_js/helpers/noop.js') 53 | } 54 | }, 55 | stats: 'minimal', 56 | plugins: [ 57 | // Optimize module ID's for vendor chunks 58 | new webpack.HashedModuleIdsPlugin({ 59 | hashFunction: 'sha256', 60 | hashDigest: 'base64', 61 | hashDigestLength: 20 62 | }), 63 | 64 | // Optimize vendor 65 | new webpack.optimize.CommonsChunkPlugin('vendor'), 66 | 67 | // Don't include debug symbols ever 68 | new webpack.EnvironmentPlugin({ 69 | NODE_ENV: 'production' 70 | }) 71 | ], 72 | devtool: 'source-map' 73 | } 74 | -------------------------------------------------------------------------------- /_support/webpack.critical.js: -------------------------------------------------------------------------------- 1 | const join = require('path').resolve 2 | const webpack = require('webpack') 3 | 4 | module.exports = { 5 | context: join(__dirname, '..'), 6 | entry: './_js/critical.js', 7 | output: { 8 | path: join(__dirname, '..', '_includes', '2017', 'critical'), 9 | filename: 'critical.js' 10 | }, 11 | module: { 12 | rules: [ 13 | { 14 | test: /\.js$/, 15 | exclude: /node_modules/, 16 | use: [ 17 | { loader: 'babel-loader' } 18 | ] 19 | } 20 | ] 21 | }, 22 | stats: 'minimal', 23 | plugins: [ 24 | new webpack.EnvironmentPlugin({ 25 | NODE_ENV: 'production' 26 | }) 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /architecture.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Architecture 3 | layout: 2017/sheet 4 | prism_languages: [bash,yaml] 5 | weight: -3 6 | tags: [Featured] 7 | updated: 2022-08-04 8 | category: Concepts 9 | intro: 10 | Istio concepts. 11 | --- 12 | 13 | ## Intro 14 | 15 | ## Architecture 16 | 17 | ### Istio Architecture 18 | 19 | Istio control plane is a single process - `istiod`, which contains three components Pilot, Citadel and Galley. You can bring containers in Kubernetes and virtual machines into the Istio mesh together. 20 | 21 | ![Istio architecture](img/istio-arch.svg){:data-img="img/istio-arch.svg"} 22 | 23 | ### Components 24 | 25 | The following figure show the components in Istio mesh. 26 | 27 | ![Istio components](img/istio-components.svg){:data-img="img/istio-components.svg"} 28 | 29 | ### Transparent Traffic Hijacking 30 | 31 | The following figure shows the transparent traffic hijacking and traffic routing in Istio. 32 | 33 | ![Transparent traffic hijacking](img/transparent-traffic-hijacking.svg){:data-img="img/transparent-traffic-hijacking.svg"} 34 | 35 | **Note** 36 | 37 | - Only TCP traffic is shown in the figure. Traffic for UDP and other protocols will not be hijacked. 38 | - It is based on Istio 1.14. 39 | - It shows the traffic routing in `reviews` pod of the [Bookinfo](https://istio.io/latest/docs/examples/bookinfo/) sample. 40 | 41 | ### Data Plane 42 | 43 | [Envoy](https://envoyproxy.io) is the default sidecar proxy in Istio. 44 | 45 | ![Envoy architecture](img/envoy-arch.svg){:data-img="img/envoy-arch.svg"} 46 | 47 | See [Envoy section](#envoy). 48 | 49 | ## Envoy 50 | 51 | ### xDS 52 | 53 | Istiod distributes the proxy configurations to Envoy via [xDS](https://www.envoyproxy.io/docs/envoy/latest/api-docs/xds_protocol) protocol. 54 | 55 | ![xDS](img/xds.svg){:data-img="img/xds.svg"} 56 | 57 | -------------------------------------------------------------------------------- /assets/2017/style.scss: -------------------------------------------------------------------------------- 1 | --- 2 | type: other 3 | --- 4 | @import '2017/style.scss'; 5 | -------------------------------------------------------------------------------- /assets/bigger-picture-1.1.5/bigger-picture.css: -------------------------------------------------------------------------------- 1 | @keyframes bp-fadein { 2 | from { 3 | opacity: 0.01; 4 | } 5 | to { 6 | opacity: 1; 7 | } 8 | } 9 | @keyframes bp-bar { 10 | from { 11 | transform: translateX(-100%); 12 | } 13 | to { 14 | transform: translateX(0); 15 | } 16 | } 17 | @keyframes bp-o { 18 | from { 19 | transform: rotate(0deg); 20 | } 21 | to { 22 | transform: rotate(360deg); 23 | } 24 | } 25 | .bp-wrap { 26 | top: 0; 27 | left: 0; 28 | width: 100%; 29 | height: 100%; 30 | position: fixed; 31 | z-index: 999; 32 | /* If you're mounting on a portion of the screen and need visible 33 | overflow on .bp-wrap, change contain to "layout" on that instance */ 34 | contain: strict; 35 | touch-action: none; 36 | -webkit-tap-highlight-color: transparent; 37 | } 38 | .bp-wrap > div:first-child { 39 | position: absolute; 40 | top: 0; 41 | left: 0; 42 | width: 100%; 43 | height: 100%; 44 | background: rgba(0, 0, 0, 0.75); 45 | animation: bp-fadein 0.48s cubic-bezier(0.215, 0.61, 0.355, 1); 46 | } 47 | 48 | .bp-vid audio { 49 | position: absolute; 50 | left: 14px; 51 | width: calc(100% - 28px); 52 | bottom: 14px; 53 | height: 50px; 54 | } 55 | 56 | .bp-inner { 57 | top: 0; 58 | left: 0; 59 | width: 100%; 60 | height: 100%; 61 | position: absolute; 62 | display: flex; 63 | } 64 | 65 | .bp-html { 66 | display: contents; 67 | } 68 | .bp-html > :first-child { 69 | margin: auto; 70 | } 71 | 72 | .bp-img-wrap { 73 | top: 0; 74 | left: 0; 75 | width: 100%; 76 | height: 100%; 77 | position: absolute; 78 | contain: strict; 79 | } 80 | .bp-img-wrap.bp-drag .bp-img { 81 | cursor: grabbing; 82 | } 83 | 84 | .bp-close { 85 | contain: layout size; 86 | } 87 | 88 | .bp-img { 89 | position: absolute; 90 | top: 50%; 91 | left: 50%; 92 | user-select: none; 93 | cursor: zoom-in; 94 | background-size: 100% 100%; 95 | } 96 | .bp-img img, 97 | .bp-img div { 98 | position: absolute; 99 | top: 0; 100 | left: 0; 101 | width: 100%; 102 | height: 100%; 103 | } 104 | .bp-img .bp-o { 105 | display: none; 106 | } 107 | 108 | .bp-zoomed .bp-img { 109 | cursor: grab; 110 | } 111 | .bp-zoomed .bp-cap { 112 | opacity: 0; 113 | animation: none !important; 114 | } 115 | 116 | .bp-zoomed.bp-small .bp-controls { 117 | opacity: 0; 118 | } 119 | .bp-zoomed.bp-small .bp-controls button { 120 | pointer-events: none; 121 | } 122 | 123 | .bp-controls { 124 | position: absolute; 125 | top: 0; 126 | left: 0; 127 | width: 100%; 128 | height: 100%; 129 | pointer-events: none; 130 | text-align: left; 131 | transition: opacity 0.3s; 132 | animation: bp-fadein 0.3s; 133 | } 134 | .bp-controls button { 135 | pointer-events: auto; 136 | cursor: pointer; 137 | position: absolute; 138 | border: 0; 139 | background: rgba(0, 0, 0, 0.15); 140 | opacity: 0.9; 141 | transition: all 0.1s; 142 | contain: content; 143 | } 144 | .bp-controls button:hover { 145 | background-color: rgba(0, 0, 0, 0.2); 146 | opacity: 1; 147 | } 148 | .bp-controls svg { 149 | fill: #fff; 150 | } 151 | 152 | .bp-count { 153 | position: absolute; 154 | color: rgba(255, 255, 255, 0.9); 155 | line-height: 1; 156 | margin: 16px; 157 | height: 50px; 158 | width: 100px; 159 | } 160 | 161 | .bp-prev, 162 | .bp-next { 163 | top: 50%; 164 | right: 0; 165 | margin-top: -32px; 166 | height: 64px; 167 | width: 58px; 168 | border-radius: 3px 0 0 3px; 169 | } 170 | .bp-prev:hover:before, 171 | .bp-next:hover:before { 172 | transform: translateX(-2px); 173 | } 174 | .bp-prev:before, 175 | .bp-next:before { 176 | content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23fff'%3E%3Cpath d='M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z'/%3E%3C/svg%3E"); 177 | position: absolute; 178 | left: 7px; 179 | top: 9px; 180 | width: 46px; 181 | transition: all 0.2s; 182 | } 183 | 184 | .bp-prev { 185 | right: auto; 186 | left: 0; 187 | transform: scalex(-1); 188 | } 189 | 190 | .bp-x { 191 | top: 0; 192 | right: 0; 193 | height: 55px; 194 | width: 58px; 195 | border-radius: 0 0 0 3px; 196 | } 197 | .bp-x:before { 198 | content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' fill='%23fff'%3E%3Cpath d='M24 10l-2-2-6 6-6-6-2 2 6 6-6 6 2 2 6-6 6 6 2-2-6-6z'/%3E%3C/svg%3E"); 199 | position: absolute; 200 | width: 37px; 201 | top: 8px; 202 | right: 10px; 203 | } 204 | 205 | .bp-if, 206 | .bp-vid { 207 | position: relative; 208 | margin: auto; 209 | background: #000; 210 | background-size: 100% 100%; 211 | } 212 | .bp-if iframe, 213 | .bp-if video, 214 | .bp-if div, 215 | .bp-vid iframe, 216 | .bp-vid video, 217 | .bp-vid div { 218 | top: 0; 219 | left: 0; 220 | width: 100%; 221 | height: 100%; 222 | position: absolute; 223 | border: 0; 224 | } 225 | 226 | .bp-load { 227 | display: flex; 228 | background-size: 100% 100%; 229 | overflow: hidden; 230 | z-index: 1; 231 | } 232 | 233 | .bp-bar { 234 | position: absolute; 235 | top: 0; 236 | left: 0; 237 | height: 3px; 238 | width: 100%; 239 | transform: translateX(-100%); 240 | background: rgba(255, 255, 255, 0.9); 241 | border-radius: 0 3px 3px 0; 242 | animation: bp-bar 4s both; 243 | } 244 | 245 | .bp-o, 246 | .bp-o:after { 247 | border-radius: 50%; 248 | width: 90px; 249 | height: 90px; 250 | } 251 | 252 | .bp-o { 253 | margin: auto; 254 | border: 10px solid rgba(255, 255, 255, 0.2); 255 | border-left-color: rgba(255, 255, 255, 0.9); 256 | animation: bp-o 1s infinite linear; 257 | } 258 | 259 | .bp-cap { 260 | position: absolute; 261 | bottom: 2%; 262 | background: rgba(9, 9, 9, 0.8); 263 | color: rgba(255, 255, 255, 0.9); 264 | border-radius: 4px; 265 | max-width: 95%; 266 | line-height: 1.3; 267 | padding: 0.6em 1.2em; 268 | left: 50%; 269 | transform: translateX(-50%); 270 | width: fit-content; 271 | width: -moz-fit-content; 272 | display: table; 273 | transition: opacity 0.3s; 274 | animation: bp-fadein 0.2s; 275 | } 276 | .bp-cap a { 277 | color: inherit; 278 | } 279 | 280 | .bp-inline { 281 | position: absolute; 282 | } 283 | 284 | .bp-lock { 285 | overflow-y: hidden; 286 | } 287 | .bp-lock body { 288 | overflow: scroll; 289 | } 290 | 291 | .bp-noclose .bp-x { 292 | display: none; 293 | } 294 | .bp-noclose:not(.bp-zoomed) { 295 | touch-action: pan-y; 296 | } 297 | .bp-noclose:not(.bp-zoomed) .bp-img-wrap { 298 | cursor: zoom-in; 299 | } 300 | 301 | @media (prefers-reduced-motion) { 302 | .bp-wrap * { 303 | animation-duration: 0s !important; 304 | } 305 | } 306 | @media (max-width: 500px) { 307 | .bp-x { 308 | height: 47px; 309 | width: 47px; 310 | } 311 | .bp-x:before { 312 | width: 34px; 313 | top: 6px; 314 | right: 6px; 315 | } 316 | 317 | .bp-prev, 318 | .bp-next { 319 | margin-top: -27px; 320 | height: 54px; 321 | width: 45px; 322 | } 323 | .bp-prev:before, 324 | .bp-next:before { 325 | top: 7px; 326 | left: 2px; 327 | width: 43px; 328 | } 329 | 330 | .bp-o, 331 | .bp-o:after { 332 | border-width: 6px; 333 | width: 60px; 334 | height: 60px; 335 | } 336 | 337 | .bp-count { 338 | margin: 12px 10px; 339 | } 340 | } 341 | -------------------------------------------------------------------------------- /assets/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tetratelabs/istio-cheatsheet/59993e57ae0a7a6dda292db7a86e62cdaec8d211/assets/favicon.png -------------------------------------------------------------------------------- /assets/print.css: -------------------------------------------------------------------------------- 1 | .site-header, .social-list, .about-the-site, 2 | #see-also, #see-also+ul { 3 | display: none; 4 | } 5 | /*.post-headline.-cheatsheet .prelude span:before { 6 | content: 'cheatsheet for' 7 | }*/ 8 | .post-list { 9 | margin: 0; 10 | padding-top: 0; 11 | padding-bottom: 0; 12 | } 13 | .post-item { 14 | max-width: 100%; 15 | } 16 | .post-headline.-cheatsheet .prelude { 17 | max-width: 300px; 18 | } 19 | .post-headline, p.prelude { 20 | margin-top: 0; 21 | } 22 | .post-headline.-cheatsheet .prelude { 23 | font-size: 0.6em; 24 | letter-spacing: 1px; 25 | } 26 | .post-headline { 27 | margin-bottom: 1.5em; 28 | } 29 | .post-headline.-cheatsheet .prelude span { 30 | padding: 0.75em 20px; 31 | border-bottom: solid 1.5px #111; 32 | } 33 | .post-headline.-cheatsheet h1 { 34 | font-size: 1.75em; 35 | text-shadow: none; 36 | } 37 | pre { 38 | border-top: solid 1px #ddd; 39 | border-bottom: solid 1px #ddd; 40 | background: none; 41 | } 42 | h3 { 43 | margin: 1em 0; 44 | } 45 | pre { 46 | margin-top: 1.1em; 47 | margin-bottom: 1.1em; 48 | } 49 | -------------------------------------------------------------------------------- /assets/script.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var tags = document.querySelectorAll('h1,h2,h3,h4,h5,h6,li,p,span'); 3 | 4 | for (var i=0, len=tags.length; i') || 7 | (!tag.innerHTML.match(/https?:\/\//)))) 8 | continue; 9 | tag.innerHTML = tag.innerHTML.replace(/https?:\/\/[^ ]*/g, function (url) { 10 | url = url.replace(/[\.\),!]*$/, ''); 11 | var label = url; 12 | label = label.replace(/^https?:\/\//, '') 13 | .replace(/\/$/, ''); 14 | return ""+label+""; 15 | }); 16 | } 17 | })(); 18 | 19 | /* unorphan */ 20 | (function () { 21 | var els = document.querySelectorAll('h1 a, h1, h2, p.brief-intro, .pull-quote'); 22 | for (var i = 0, len = els.length; i < len; i++) { 23 | var el = els[i]; 24 | var last = el.lastChild; 25 | 26 | if (last && last.nodeType === 3) { 27 | console.log('=>', last.nodeValue, last.nodeValue.replace(/\s+([^\s]+\s*)$/g, '\xA0$1')); 28 | last.nodeValue = last.nodeValue.replace(/\s+([^\s]+\s*)$/g, '\xA0$1'); 29 | } 30 | } 31 | })(); 32 | 33 | /* loaded */ 34 | document.documentElement.className += ' loaded'; 35 | 36 | /* hljs */ 37 | (function () { 38 | var codes = document.querySelectorAll('pre > code'); 39 | for (var i = 0, len = codes.length; i < len; i++) { 40 | var block = codes[i]; 41 | hljs.highlightBlock(block); 42 | } 43 | })(); 44 | -------------------------------------------------------------------------------- /assets/style.css: -------------------------------------------------------------------------------- 1 | /* 2 | * pages list 3 | */ 4 | 5 | .pages-list { 6 | font-size: 0.9em; 7 | max-width: 800px; 8 | margin: 60px auto; 9 | overflow: hidden; 10 | } 11 | 12 | .pages-list a { 13 | display: block; 14 | padding: 6px 0; 15 | text-align: left; 16 | float: left; 17 | width: 44%; 18 | margin: 0 3%; 19 | box-shadow: none; 20 | transition: all 100ms linear; 21 | } 22 | 23 | .pages-list a .title, 24 | .pages-list a .date { 25 | display: block; 26 | } 27 | 28 | .pages-list a .title { 29 | font-weight: bold; 30 | color: #111; 31 | float: left; 32 | } 33 | 34 | .pages-list a .date { 35 | color: #aaa; 36 | font-size: 0.9em; 37 | float: right; 38 | } 39 | 40 | .pages-list a:hover .title, 41 | .pages-list a:focus .title { 42 | color: dodgerblue; 43 | } 44 | 45 | /* 46 | * post headline 47 | */ 48 | 49 | .post-headline.-cheatsheet .prelude { 50 | color: #111; 51 | font-size: 0.85em; 52 | text-transform: uppercase; 53 | letter-spacing: 2px; 54 | margin-bottom: 0; 55 | font-weight: bold; 56 | } 57 | 58 | .post-headline.-cheatsheet .prelude span { 59 | border-bottom: solid 3px #111; 60 | padding: 1.5em 20px; 61 | } 62 | 63 | .post-headline.-cheatsheet .prelude span:before { 64 | content: 'Cheatsheet for'; 65 | } 66 | 67 | @media (min-width: 769px) { 68 | .post-headline.-cheatsheet .prelude { 69 | max-width: 230px; 70 | margin-left: auto; 71 | margin-right: auto; 72 | } 73 | .post-headline.-cheatsheet .prelude span { 74 | display: inline-block; 75 | } 76 | } 77 | 78 | .post-headline.-cheatsheet h1 { 79 | color: #111; 80 | font-size: 3.5em; 81 | text-shadow: 82 | 2px 2px 0 white, 83 | 3px 3px 0 #ddd; 84 | } 85 | 86 | /* 87 | * about the site 88 | */ 89 | 90 | .about-the-site { 91 | margin-top: 8em; 92 | } 93 | 94 | .about-the-site .back { 95 | margin-right: 0; 96 | } 97 | 98 | /* 99 | * markdown 100 | */ 101 | 102 | @media (min-width: 768px) { 103 | h2 { 104 | margin-top: 3em; 105 | } 106 | } 107 | 108 | /* 109 | * grey code 110 | */ 111 | 112 | .greycode td:first-child code, 113 | .greycode th:first-child code { 114 | background: white; 115 | padding: 6px 8px 5px 8px; 116 | border-radius: 3px; 117 | } 118 | 119 | .greycode td:first-child code + em, 120 | .greycode th:first-child code + em { 121 | color: #808890; 122 | font-size: 0.9em; 123 | margin: 0 5px; 124 | } 125 | 126 | .greycode a { 127 | margin: 0 5px; 128 | } 129 | 130 | @media (min-width: 768px) { 131 | table.greycode { 132 | background: #fcfcfc; 133 | border-radius: 4px; 134 | border-top: 0; 135 | border-bottom: solid 1px #c7d7ee; 136 | } 137 | 138 | table.greycode:not(.wide) { 139 | width: calc(620px + 100px); 140 | margin-left: -50px; 141 | } 142 | 143 | table.greycode thead:first-child > tr:first-child > th, 144 | table.greycode thead:first-child > tr:first-child > td, 145 | table.greycode tbody:first-child > tr:first-child > th, 146 | table.greycode tbody:first-child > tr:first-child > td, 147 | table.greycode.no-head thead:nth-child(2) > tr:first-child > th, 148 | table.greycode.no-head thead:nth-child(2) > tr:first-child > td, 149 | table.greycode.no-head tbody:nth-child(2) > tr:first-child > th, 150 | table.greycode.no-head tbody:nth-child(2) > tr:first-child > td { 151 | border-top: 0; 152 | } 153 | 154 | table.greycode thead > tr:first-child > th, 155 | table.greycode thead > tr:first-child > td, 156 | table.greycode tbody > tr:first-child > th, 157 | table.greycode tbody > tr:first-child > td { 158 | border-top: solid 1px #c7d7ee; 159 | } 160 | 161 | table.greycode td:first-child, 162 | table.greycode th:first-child { 163 | padding-left: 50px; 164 | } 165 | 166 | table.greycode td:last-child, 167 | table.greycode th:last-child { 168 | padding-right: 50px; 169 | } 170 | } 171 | 172 | .hljs-comment { 173 | font-style: normal; 174 | } 175 | 176 | .key-codes code { 177 | background: #fdfdff; 178 | padding: 3px 8px 3px 8px; 179 | border-radius: 3px; 180 | box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1); 181 | margin: 0 5px; 182 | } 183 | 184 | .key-codes code + code { 185 | margin-left: 0; 186 | } 187 | 188 | .key-codes pre code { 189 | background: transparent; 190 | padding: 0; 191 | box-shadow: none; 192 | margin: 0; 193 | } 194 | 195 | /* 196 | * Carbon: side 197 | */ 198 | 199 | .side-ad { 200 | position: absolute; 201 | top: 80px; 202 | right: 20px; 203 | width: 130px; 204 | display: block; 205 | font-size: .8em; 206 | } 207 | 208 | .side-ad a { 209 | text-decoration: none; 210 | box-shadow: none; 211 | background: rgba(255, 255, 255, .01); 212 | } 213 | 214 | .side-ad a:hover { 215 | color: #111; 216 | } 217 | 218 | .side-ad .carbon-text { 219 | margin-top: 5px; 220 | display: block; 221 | } 222 | 223 | .side-ad .carbon-poweredby { 224 | display: block; 225 | color: #aaa; 226 | } 227 | 228 | @media (max-width: 768px) { 229 | .side-ad { 230 | display: none; 231 | } 232 | } 233 | 234 | /* 235 | * Cardbon: headline 236 | */ 237 | 238 | .headline-ad { 239 | width: 300px; 240 | min-height: 100px; 241 | font-size: .8em; 242 | margin: 0 auto 45px auto; 243 | line-height: 1.5; 244 | } 245 | 246 | .headline-ad:after { 247 | content: ''; 248 | display: table; 249 | clear: both; 250 | zoom: 1; 251 | } 252 | 253 | .headline-ad a { 254 | text-decoration: none; 255 | box-shadow: none; 256 | display: block; 257 | background: rgba(255, 255, 255, .01); 258 | } 259 | 260 | .headline-ad a:hover { 261 | color: #111; 262 | } 263 | 264 | .headline-ad img { 265 | float: left; 266 | margin-right: 15px; 267 | background: #fafafa; 268 | } 269 | 270 | .headline-ad .carbon-text { 271 | } 272 | 273 | .headline-ad .carbon-poweredby { 274 | display: block; 275 | color: #aaa; 276 | margin-top: 5px; 277 | } 278 | 279 | .social-list.-collapse { 280 | margin-top: 0; 281 | position: absolute; 282 | top: 40vh; 283 | left: 30px; 284 | width: 32px; 285 | } 286 | 287 | @media (max-width: 480px) { 288 | .social-list.-collapse { 289 | display: none; 290 | } 291 | } 292 | 293 | -------------------------------------------------------------------------------- /data/search-index.json: -------------------------------------------------------------------------------- 1 | --- 2 | layout: blank 3 | type: other 4 | --- 5 | {% assign pages = site.pages 6 | | where_exp: "page", 'page.type == "article"' 7 | %}[ 8 | {% for page in pages 9 | %}{% if forloop.index0 != 0 %},{% endif %}{ 10 | "id": {{ page.url | replace: ".html", "" | slice: 1, 9999 | jsonify }}, 11 | "title": {{ page.title | jsonify }}, 12 | "url": {{ page.url | replace: ".html", "" | jsonify }}, 13 | "category": {{ page.category | jsonify }}, 14 | "keywords": {{ page.keywords | jsonify }}, 15 | "content_html": {{ page.content | markdownify | strip | jsonify }}, 16 | "intro_html": {{ page.intro | markdownify | strip | jsonify }}, 17 | "description_html": {{ page.description | markdownify | strip | jsonify }}, 18 | "tags": {{ page.tags | jsonify }}, 19 | "updated": {{ page.updated | jsonify }} 20 | }{% endfor %} 21 | ] 22 | -------------------------------------------------------------------------------- /index.md: -------------------------------------------------------------------------------- 1 | --- 2 | full_title: "Istio cheatsheet" 3 | description: "Istio configuration cheatsheet" 4 | layout: 2017/home 5 | og_type: website 6 | type: home 7 | --- 8 | -------------------------------------------------------------------------------- /istioctl.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: istioctl 3 | layout: 2017/sheet 4 | prism_languages: [bash,yaml] 5 | weight: -3 6 | tags: [Featured] 7 | updated: 2022-08-05 8 | category: CLI 9 | intro: 10 | Istio command line cheatsheet. 11 | --- 12 | 13 | ## Intro 14 | 15 | ## Istioctl Overview 16 | 17 | ### Usage 18 | 19 | [`istioctl`](https://istio.io/latest/docs/reference/commands/istioctl) command line usage overview. 20 | 21 | ![istioctl cheatsheet](img/istioctl.svg){:data-img="img/istioctl.svg"} 22 | 23 | ### experimental/x 24 | 25 | Experimental commands that may be modified or deprecated. 26 | 27 | ![istioctl-x](img/istioctl-x.svg){:data-img="img/istioctl-x.svg"} 28 | 29 | See [Istio docs](https://istio.io/latest/docs/reference/commands/istioctl/#istioctl-experimental) for details. 30 | 31 | ## dashboard/dash/d 32 | 33 | ### controlz 34 | 35 | Open the ControlZ web UI for a pod in the Istio control plane. 36 | 37 | ```bash 38 | istioctl dashboard controlz [/][.] [flags] 39 | ``` 40 | 41 | Example 42 | 43 | ```bash 44 | istioctl d controlz istiod-6bc78ccdb-sgdgh -n istio-system 45 | ``` 46 | 47 | You will see the ControlZ UI at . 48 | 49 | ### envoy 50 | 51 | Open the Envoy admin dashboard for a sidecar. 52 | 53 | ```bash 54 | istioctl dashboard envoy [/][.] [flags] 55 | ``` 56 | 57 | Example 58 | 59 | ```bash 60 | istioctl d envoy details-v1-7d88846999-ptz54 -n default 61 | ``` 62 | 63 | You can see the UI at . 64 | 65 | ### grafana 66 | 67 | Open Istio's Grafana dashboard. 68 | 69 | ```bash 70 | istioctl dashboard grafana [flags] 71 | ``` 72 | 73 | Example 74 | 75 | ```bash 76 | istioctl d grafana 77 | ``` 78 | 79 | You can see the Grafana UI at . 80 | 81 | ### jaeger 82 | 83 | Open Istio's Jaeger dashboard. 84 | 85 | ```bash 86 | istioctl dashboard jaeger [flags] 87 | ``` 88 | 89 | Jaeger is not installed by default, run the following command to install Jaeger. 90 | 91 | ```bash 92 | kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.14/samples/addons/jaeger.yaml 93 | ``` 94 | 95 | See [Istio docs](https://istio.io/latest/docs/ops/integrations/jaeger/#installation) for details. 96 | 97 | Example 98 | 99 | ```bash 100 | istioctl d jaeger 101 | ``` 102 | 103 | you can see the Jaeger UI at . 104 | 105 | ### kiali 106 | 107 | Open Istio's Kiali dashboard. 108 | 109 | ```bash 110 | istioctl dashboard kiali [flags] 111 | ``` 112 | 113 | Kiali is not installed by default, run the following command to install Kiali. 114 | 115 | ```bash 116 | kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.14/samples/addons/kiali.yaml 117 | ``` 118 | 119 | See [Istio docs](https://istio.io/latest/docs/ops/integrations/kiali/#installation) for details. 120 | 121 | Example 122 | 123 | ```bash 124 | istioctl d kiali 125 | ``` 126 | 127 | You can see the Kiali UI at . 128 | 129 | ### prometheus 130 | 131 | Open Istio's Prometheus dashboard. 132 | 133 | ```bash 134 | istioctl dashboard prometheus [flags] 135 | ``` 136 | 137 | Example 138 | 139 | ```bash 140 | istioctl d prometheus 141 | ``` 142 | 143 | See the Prometheus UI at . 144 | 145 | ### skywalking 146 | 147 | Open the Istio dashboard in the SkyWalking UI. 148 | 149 | ```bash 150 | istioctl dashboard skywalking [flags] 151 | ``` 152 | 153 | SkyWalking is not installed by default, refer to the [SkyWalking docs](https://skywalking.apache.org/docs/main/latest/en/setup/istio/readme/) to see how to install. 154 | 155 | Example 156 | 157 | ```bash 158 | istioctl d skywalking 159 | ``` 160 | 161 | ### zipkin 162 | 163 | Open Istio's Zipkin dashboard. 164 | 165 | ```bash 166 | istioctl dashboard zipkin [flags] 167 | ``` 168 | 169 | Zipkin is not installed by default, run the following command to install Zipkin. 170 | 171 | ```bash 172 | kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.14/samples/addons/extras/zipkin.yaml 173 | ``` 174 | 175 | See [Istio docs](https://istio.io/latest/docs/ops/integrations/zipkin/#installation) for details. 176 | 177 | Example 178 | 179 | ```bash 180 | istioctl d zipkin 181 | ``` 182 | 183 | You can see the Zipkin UI at . 184 | 185 | ## Frequently Used Commands 186 | 187 | ### install 188 | 189 | The `install` command generates an Istio install manifest and applies it to a cluster. 190 | 191 | Example 192 | 193 | ```bash 194 | # Apply a default Istio installation 195 | istioctl install 196 | 197 | # Enable Tracing 198 | istioctl install --set meshConfig.enableTracing=true 199 | 200 | # Generate the demo profile and don't wait for confirmation 201 | istioctl install --set profile=demo --skip-confirmation 202 | 203 | # To override a setting that includes dots, escape them with a backslash (\). Your shell may require enclosing quotes. 204 | istioctl install --set "values.sidecarInjectorWebhook.injectedAnnotations.container\.apparmor\.security\.beta\.kubernetes\.io/istio-proxy=runtime/default" 205 | 206 | # For setting boolean-string option, it should be enclosed quotes and escaped with a backslash (\). 207 | istioctl install --set meshConfig.defaultConfig.proxyMetadata.PROXY_XDS_VIA_AGENT=\"false\" 208 | ``` 209 | 210 | ### manifest 211 | 212 | The manifest command generates and diffs Istio manifests. 213 | 214 | **istioctl manifest install** 215 | 216 | ```bash 217 | # Apply a default Istio installation 218 | istioctl install 219 | 220 | # Enable Tracing 221 | istioctl install --set meshConfig.enableTracing=true 222 | 223 | # Generate the demo profile and don't wait for confirmation 224 | istioctl install --set profile=demo --skip-confirmation 225 | 226 | # To override a setting that includes dots, escape them with a backslash (\). Your shell may require enclosing quotes. 227 | istioctl install --set "values.sidecarInjectorWebhook.injectedAnnotations.container\.apparmor\.security\.beta\.kubernetes\.io/istio-proxy=runtime/default" 228 | 229 | # For setting boolean-string option, it should be enclosed quotes and escaped with a backslash (\). 230 | istioctl install --set meshConfig.defaultConfig.proxyMetadata.PROXY_XDS_VIA_AGENT=\"false\" 231 | ``` 232 | 233 | **istioctl manifest generate** 234 | 235 | ```bash 236 | # Generate a default Istio installation 237 | istioctl manifest generate 238 | 239 | # Enable Tracing 240 | istioctl manifest generate --set meshConfig.enableTracing=true 241 | 242 | # Generate the demo profile 243 | istioctl manifest generate --set profile=demo 244 | 245 | # To override a setting that includes dots, escape them with a backslash (\). Your shell may require enclosing quotes. 246 | istioctl manifest generate --set "values.sidecarInjectorWebhook.injectedAnnotations.container\.apparmor\.security\.beta\.kubernetes\.io/istio-proxy=runtime/default" 247 | 248 | # For setting boolean-string option, it should be enclosed quotes and escaped with a backslash (\). 249 | istioctl manifest generate --set meshConfig.defaultConfig.proxyMetadata.PROXY_XDS_VIA_AGENT=\"false\" 250 | ``` 251 | 252 | ### proxy-config/pc 253 | 254 | A group of commands used to retrieve information about proxy configuration from the Envoy config dump. 255 | 256 | ```bash 257 | # Retrieve information about proxy configuration from an Envoy instance. 258 | istioctl proxy-config 259 | ``` 260 | 261 | **Example** 262 | 263 | ```bash 264 | # Retrieve cluster summary. 265 | istioctl pc all 266 | 267 | # Show a human-readable Istio and Envoy version summary. 268 | istioctl pc b reviews-v1-55b668fc65-9twc9 -o short 269 | 270 | # Retrieve summary about cluster configuration for a given pod from Envoy. 271 | 272 | istioctl pc c reviews-v1-55b668fc65-9twc9 273 | 274 | # Retrieve full endpoint configuration for a given pod from Envoy. 275 | istioctl pc ep reviews-v1-55b668fc65-9twc9 276 | 277 | # Retrieve summary about listener configuration for a given pod from Envoy. 278 | istioctl pc l reviews-v1-55b668fc65-9twc9 279 | 280 | # Retrieve summary about route configuration for a given pod from Envoy. 281 | istioctl pc r reviews-v1-55b668fc65-9twc9 282 | ``` 283 | 284 | ### proxy-status/ps 285 | 286 | Retrieves last sent and last acknowledged xDS sync from Istiod to each Envoy in the mesh. 287 | 288 | **Examples** 289 | 290 | ```bash 291 | # Retrieve sync status for all Envoys in a mesh 292 | istioctl proxy-status 293 | 294 | # Retrieve sync diff for a single Envoy and Istiod 295 | istioctl proxy-status istio-egressgateway-59585c5b9c-ndc59.istio-system 296 | 297 | # Retrieve sync diff between Istiod and one pod under a deployment 298 | istioctl proxy-status deployment/productpage-v1 299 | 300 | # Write proxy config-dump to file, and compare to Istio control plane 301 | kubectl port-forward -n istio-system istio-egressgateway-59585c5b9c-ndc59 15000 & 302 | curl localhost:15000/config_dump > cd.json 303 | istioctl proxy-status istio-egressgateway-59585c5b9c-ndc59.istio-system --file cd.json 304 | ``` 305 | -------------------------------------------------------------------------------- /observability.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Observability 3 | layout: 2017/sheet 4 | prism_languages: [bash,yaml] 5 | weight: -2 6 | tags: [Featured] 7 | updated: 2022-08-03 8 | category: Concepts 9 | intro: 10 | Cheatsheet for observability (Metrics, Tracing and Logging) in Istio. 11 | --- 12 | 13 | ## Intro 14 | 15 | ## Metrics 16 | 17 | ### Prometheus 18 | 19 | The following figure shows the architecture of Prometheus. 20 | 21 | ![Prometheus architecture](img/prometheus-arch.svg){:data-img="img/prometheus-arch.svg"} 22 | 23 | #### [Data model](https://prometheus.io/docs/concepts/data_model/) 24 | 25 | ``` 26 | {