CINXE.COM
Advanced Tasks
<!DOCTYPE html> <html lang=""> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="generator" content="Asciidoctor 2.0.23"> <title>Advanced Tasks</title> <style> /* * Copyright 2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* Custom Admonition Blocks */ body { --gradle-blue: #209BC4; --gradle-bg-dark: #010002; --gradle-bg-gray: #F8F8F8; --gradle-bg-white: #FFFFFF; --gradle-blue: #209BC4; --gradle-blue-lite: #4DC9C0; --gradle-blue-dark: #1b3262; --gradle-blue-darker: #19274f; --button-gradient-angle: 160deg; --caution-color: #e40046; --caution-on-color: #fff; --important-color: #802392; --important-on-color: #fff; --note-color: #2d7dd2; --note-on-color: #fff; --tip-color: #43b929; --tip-on-color: #fff; --warning-color: #f70; --warning-on-color: #fff; --admonition-background: #fafafa; --doc-icon-filter: invert(14.5%); --rem-base: 18; --black-color: #000; --white-color: #fff; --text-color: #02303A; --title-color: #02303A; --header-color: rgba(0, 0, 0, 0.85); --footer-color: #fff; --footer-other-text-color: #02303; --footer-form-color: #1BA8CB; --code-color: #f7f7f8; --code-text-color: rgba(0, 0, 0, 0.9); --code-link-color: #021274; --num-color: rgba(0, 0, 0, 0.8); --nav-color: #f8f8f7; --table-color: #f7f8f7; --box-shadow-color: rgba(0, 0, 0, .15); --top-header-color: #fff; --footer-white-color: #fff; --footer-text-color: #fff; --quoteblock-color: #7a2518; --menu-burger-color: #fff; --various-border-color: #e7e7e9; } body.dark-theme { --admonition-background: #2a2929; --black-color: #fff; --white-color: #121212; --text-color: #aaa; --title-color: #fff; --header-color: rgba(255, 255, 255, 0.85); --footer-color: #121212; --footer-other-text-color: #ddd; --code-color: #1f1f1f; --code-text-color: rgba(255, 255, 255, 0.9); --code-link-color: #1fafcc; --num-color: #fff; --nav-color: #121212; --table-color: #121212; --box-shadow-color: rgba(255, 255, 255, .15); --top-header-color: #242526; --footer-white-color: #242526; --footer-text-color: #aaa; --footer-form-color: #1BA8CB; --quoteblock-color: #1DA2BD; --menu-burger-color: #242526; --various-border-color: #242526; } @media (prefers-color-scheme: dark) { /* defaults to dark theme */ body { --admonition-background: #2a2929; --black-color: #fff; --white-color: #121212; --text-color: #aaa; --title-color: #fff; --header-color: rgba(255, 255, 255, 0.85); --footer-color: #121212; --footer-other-text-color: #ddd; --code-color: #1f1f1f; --code-text-color: rgba(255, 255, 255, 0.9); --code-link-color: #1fafcc; --num-color: #fff; --nav-color: #121212; --table-color: #121212; --box-shadow-color: rgba(255, 255, 255, .15); --top-header-color: #242526; --footer-white-color: #242526; --footer-text-color: #aaa; --footer-form-color: #1BA8CB; --quoteblock-color: #1DA2BD; --menu-burger-color: #242526; --various-border-color: #242526; } body.light-theme { --gradle-blue: #209BC4; --gradle-bg-dark: #010002; --gradle-bg-gray: #F8F8F8; --gradle-bg-white: #FFFFFF; --gradle-blue: #209BC4; --gradle-blue-lite: #4DC9C0; --gradle-blue-dark: #1b3262; --gradle-blue-darker: #19274f; --button-gradient-angle: 160deg; --caution-color: #e40046; --caution-on-color: #fff; --important-color: #802392; --important-on-color: #fff; --note-color: #2d7dd2; --note-on-color: #fff; --tip-color: #43b929; --tip-on-color: #fff; --warning-color: #f70; --warning-on-color: #fff; --admonition-background: #fafafa; --doc-icon-filter: invert(14.5%); --rem-base: 18; --black-color: #000; --white-color: #fff; --text-color: #02303A; --title-color: #02303A; --header-color: rgba(0, 0, 0, 0.85); --footer-color: #fff; --footer-other-text-color: #02303; --code-color: #f7f7f8; --code-text-color: rgba(0, 0, 0, 0.9); --code-link-color: #021274; --num-color: rgba(0, 0, 0, 0.8); --nav-color: #f8f8f7; --table-color: #f7f8f7; --box-shadow-color: rgba(0, 0, 0, .15); --top-header-color: #fff; --footer-white-color: #fff; --footer-text-color: #fff; --footer-form-color: #1BA8CB; --quoteblock-color: #7a2518; --menu-burger-color: #fff; --various-border-color: #e7e7e9; } } .cls-1 { fill: #02303a; } body.dark-theme { .cls-1 { fill: #fff; } } @media (prefers-color-scheme: dark) { .cls-1 { fill: #fff; } body.light-theme { .cls-1 { fill: #02303a; } } } /* Lato (normal, regular) */ @font-face { font-family: Lato; font-weight: 400; font-style: normal; src: url("https://assets.gradle.com/lato/fonts/lato-normal/lato-normal.woff2") format("woff2"), url("https://assets.gradle.com/lato/fonts/lato-normal/lato-normal.woff") format("woff"); } /* Lato (normal, italic) */ @font-face { font-display: swap; font-family: Lato; font-weight: 400; font-style: italic; src: url("https://assets.gradle.com/lato/fonts/lato-normal-italic/lato-normal-italic.woff2") format("woff2"), url("https://assets.gradle.com/lato/fonts/lato-normal-italic/lato-normal-italic.woff") format("woff"); } /* Lato (bold, regular) */ @font-face { font-display: swap; font-family: Lato; font-weight: 500; font-style: normal; src: url("https://assets.gradle.com/lato/fonts/lato-semibold/lato-semibold.woff2") format("woff2"), url("https://assets.gradle.com/lato/fonts/lato-semibold/lato-semibold.woff") format("woff"); } /* Lato (bold, regular) */ @font-face { font-display: swap; font-family: Lato; font-weight: 800; font-style: normal; src: url("https://assets.gradle.com/lato/fonts/lato-heavy/lato-heavy.woff2") format("woff2"), url("https://assets.gradle.com/lato/fonts/lato-heavy/lato-heavy.woff") format("woff"); } /* BEGIN asciidoc.css */ /*! normalize.css v2.1.2 | MIT License | git.io/normalize */ /* ========================================================================== HTML5 display definitions ========================================================================== */ /** Correct `block` display not defined in IE 8/9. */ article, aside, details, figcaption, figure, footer, header, hgroup, main, nav, section, summary { display: block; } /** Correct `inline-block` display not defined in IE 8/9. */ audio, canvas, video { display: inline-block; } /** Prevent modern browsers from displaying `audio` without controls. Remove excess height in iOS 5 devices. */ audio:not([controls]) { display: none; height: 0; } /** Address `[hidden]` styling not present in IE 8/9. Hide the `template` element in IE, Safari, and Firefox < 22. */ [hidden], template { display: none; } script { display: none !important; } /* ========================================================================== Base ========================================================================== */ /** 1. Set default font family to sans-serif. 2. Prevent iOS text size adjust after orientation change, without disabling user zoom. */ html { font-family: sans-serif; /* 1 */ -ms-text-size-adjust: 100%; /* 2 */ -webkit-text-size-adjust: 100%; /* 2 */ } /** Remove default margin. */ body { margin: 0; } /* ========================================================================== Links ========================================================================== */ /** Remove the gray background color from active links in IE 10. */ a { background: transparent; } /** Address `outline` inconsistency between Chrome and other browsers. */ a:focus { outline: thin dotted; } /** Improve readability when focused and also mouse hovered in all browsers. */ a:active, a:hover { outline: 0; } /* ========================================================================== Typography ========================================================================== */ /** Address variable `h1` font-size and margin within `section` and `article` contexts in Firefox 4+, Safari 5, and Chrome. */ h1 { font-size: 2em; margin: 0.67em 0; } /** Address styling not present in IE 8/9, Safari 5, and Chrome. */ abbr[title] { border-bottom: 1px dotted; } /** Address style set to `bolder` in Firefox 4+, Safari 5, and Chrome. */ b, strong { font-weight: bold; } /** Address styling not present in Safari 5 and Chrome. */ dfn { font-style: italic; } /** Address differences between Firefox and other browsers. */ hr { -moz-box-sizing: content-box; box-sizing: content-box; height: 0; } /** Address styling not present in IE 8/9. */ mark { background: #ff0; color: var(--black-color); } /** Correct font family set oddly in Safari 5 and Chrome. */ code, kbd, pre, samp { font-family: monospace, serif; font-size: 1em; } /** Improve readability of pre-formatted text in all browsers. */ pre { white-space: pre-wrap; } /** Set consistent quote types. */ q { quotes: "\201C""\201D""\2018""\2019"; } /** Address inconsistent and variable font size in all browsers. */ small { font-size: 80%; } /** Prevent `sub` and `sup` affecting `line-height` in all browsers. */ sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; } sup { top: -0.5em; } sub { bottom: -0.25em; } /* ========================================================================== Embedded content ========================================================================== */ /** Remove border when inside `a` element in IE 8/9. */ img { border: 0; } /** Correct overflow displayed oddly in IE 9. */ svg:not(:root) { overflow: hidden; } /* ========================================================================== Figures ========================================================================== */ /** Address margin not present in IE 8/9 and Safari 5. */ figure { margin: 0; } /* ========================================================================== Forms ========================================================================== */ /** Define consistent border, margin, and padding. */ fieldset { border: 1px solid #c0c0c0; margin: 0 2px; padding: 0.35em 0.625em 0.75em; } /** 1. Correct `color` not being inherited in IE 8/9. 2. Remove padding so people aren't caught out if they zero out fieldsets. */ legend { border: 0; /* 1 */ padding: 0; /* 2 */ } /** 1. Correct font family not being inherited in all browsers. 2. Correct font size not being inherited in all browsers. 3. Address margins set differently in Firefox 4+, Safari 5, and Chrome. */ button, input, select, textarea { font-family: inherit; /* 1 */ font-size: 100%; /* 2 */ margin: 0; /* 3 */ } /** Address Firefox 4+ setting `line-height` on `input` using `!important` in the UA stylesheet. */ button, input { line-height: normal; } /** Address inconsistent `text-transform` inheritance for `button` and `select`. All other form control elements do not inherit `text-transform` values. Correct `button` style inheritance in Chrome, Safari 5+, and IE 8+. Correct `select` style inheritance in Firefox 4+ and Opera. */ button, select { text-transform: none; } /** 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` and `video` controls. 2. Correct inability to style clickable `input` types in iOS. 3. Improve usability and consistency of cursor style between image-type `input` and others. */ button, html input[type="button"], input[type="reset"], input[type="submit"] { -webkit-appearance: button; /* 2 */ cursor: pointer; /* 3 */ } /** Re-set default cursor for disabled elements. */ button[disabled], html input[disabled] { cursor: default; } /** 1. Address box sizing set to `content-box` in IE 8/9. 2. Remove excess padding in IE 8/9. */ input[type="checkbox"], input[type="radio"] { box-sizing: border-box; /* 1 */ padding: 0; /* 2 */ } /** 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome. 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome (include `-moz` to future-proof). */ input[type="search"] { -webkit-appearance: textfield; /* 1 */ -moz-box-sizing: content-box; -webkit-box-sizing: content-box; /* 2 */ box-sizing: content-box; } /** Remove inner padding and search cancel button in Safari 5 and Chrome on OS X. */ input[type="search"]::-webkit-search-cancel-button, input[type="search"]::-webkit-search-decoration { -webkit-appearance: none; } /** Remove inner padding and border in Firefox 4+. */ button::-moz-focus-inner, input::-moz-focus-inner { border: 0; padding: 0; } /** 1. Remove default vertical scrollbar in IE 8/9. 2. Improve readability and alignment in all browsers. */ textarea { overflow: auto; /* 1 */ vertical-align: top; /* 2 */ } /* ========================================================================== Tables ========================================================================== */ /** Remove most spacing between table cells. */ table { border-collapse: collapse; border-spacing: 0; } meta.foundation-mq-small { font-family: "only screen and (min-width: 768px)"; width: 768px; } meta.foundation-mq-medium { font-family: "only screen and (min-width:1280px)"; width: 1280px; } meta.foundation-mq-large { font-family: "only screen and (min-width:1440px)"; width: 1440px; } *, *:before, *:after { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; } html, body { font-size: 100%; } body { background: var(--white-color); color: var(--num-color); padding: 0; margin: 0; font-family: "Noto Serif", "DejaVu Serif", serif; font-weight: normal; font-style: normal; line-height: 1; position: relative; cursor: auto; } a:hover { cursor: pointer; } img, object, embed { max-width: 100%; height: auto; } object, embed { height: 100%; } img { -ms-interpolation-mode: bicubic; } #map_canvas img, #map_canvas embed, #map_canvas object, .map_canvas img, .map_canvas embed, .map_canvas object { max-width: none !important; } .left { float: left !important; } .right { float: right !important; } .text-left { text-align: left !important; } .text-right { text-align: right !important; } .text-center { text-align: center !important; } .text-justify { text-align: justify !important; } .hide { display: none; } .antialiased { -webkit-font-smoothing: antialiased; } img { display: inline-block; vertical-align: middle; } textarea { height: auto; min-height: 50px; } select { width: 100%; } object, svg { display: inline-block; vertical-align: middle; } .center { margin-left: auto; margin-right: auto; } .spread { width: 100%; } p.lead, .paragraph.lead>p, #preamble>.sectionbody>.paragraph:first-of-type p { font-size: 1.21875em; line-height: 1.6; } .subheader, .admonitionblock td.content>.title, .audioblock>.title, .exampleblock>.title, .imageblock>.title, .listingblock>.title, .literalblock>.title, .stemblock>.title, .openblock>.title, .paragraph>.title, .quoteblock>.title, table.tableblock>.title, .verseblock>.title, .videoblock>.title, .dlist>.title, .olist>.title, .ulist>.title, .qlist>.title, .hdlist>.title { line-height: 1.45; color: #7a2518; font-weight: normal; margin-top: 0; margin-bottom: 0.25em; } /* Typography resets */ div, dl, dt, dd, ul, ol, li, h1, h2, h3, #toctitle, .sidebarblock>.content>.title, h4, h5, h6, pre, form, p, blockquote, th, td { margin: 0; padding: 0; direction: ltr; } /* Default Link Styles */ a { color: #2156a5; text-decoration: underline; line-height: inherit; } a:hover, a:focus { color: #1d4b8f; } a img { border: none; } /* Default paragraph styles */ p { font-family: inherit; font-weight: normal; font-size: 1em; line-height: 1.6; margin-bottom: 1.25em; text-rendering: optimizeLegibility; } p aside { font-size: 0.875em; line-height: 1.35; font-style: italic; } /* Default header styles */ h1, h2, h3, #toctitle, .sidebarblock>.content>.title, h4, h5, h6 { font-family: "Open Sans", "DejaVu Sans", sans-serif; font-weight: 300; font-style: normal; color: #ba3925; text-rendering: optimizeLegibility; margin-top: 1em; margin-bottom: 0.5em; line-height: 1.0125em; } h1 small, h2 small, h3 small, #toctitle small, .sidebarblock>.content>.title small, h4 small, h5 small, h6 small { font-size: 60%; color: #e99b8f; line-height: 0; } h1 { font-size: 2.125em; } h2 { font-size: 1.6875em; } h3, #toctitle, .sidebarblock>.content>.title { font-size: 1.375em; } h4 { font-size: 1.125em; } h5 { font-size: 1.125em; } h6 { font-size: 1em; } hr { border: solid #ddddd8; border-width: 1px 0 0; clear: both; margin: 1.25em 0 1.1875em; height: 0; } /* Helpful Typography Defaults */ em, i { font-style: italic; line-height: inherit; } strong, b { font-weight: bold; line-height: inherit; } small { font-size: 60%; line-height: inherit; } code { font-family: "Droid Sans Mono", "DejaVu Sans Mono", monospace; font-weight: normal; color: var(--code-text-color); } a code { color: var(--code-link-color); } /* Lists */ ul, ol, dl { font-size: 1em; line-height: 1.6; margin-bottom: 1.25em; list-style-position: outside; font-family: inherit; } ul, ol { margin-left: 1.5em; } ul.no-bullet, ol.no-bullet { margin-left: 1.5em; } /* Unordered Lists */ ul li ul, ul li ol { margin-left: 1.25em; margin-bottom: 0; font-size: 1em; /* Override nested font-size change */ } ul.square li ul, ul.circle li ul, ul.disc li ul { list-style: inherit; } ul.square { list-style-type: square; } ul.circle { list-style-type: circle; } ul.disc { list-style-type: disc; } ul.no-bullet { list-style: none; } /* Ordered Lists */ ol li ul, ol li ol { margin-left: 1.25em; margin-bottom: 0; } /* Definition Lists */ dl dt { margin-bottom: 0.3125em; font-weight: bold; } dl dd { margin-bottom: 1.25em; } /* Abbreviations */ abbr, acronym { text-transform: uppercase; font-size: 90%; color: var(--num-color); border-bottom: 1px dotted #dddddd; cursor: help; } abbr { text-transform: none; } /* Blockquotes */ blockquote { margin: 0 0 1.25em; padding: 0.5625em 1.25em 0 1.1875em; border-left: 1px solid #dddddd; } blockquote cite { display: block; font-size: 0.9375em; color: rgba(0, 0, 0, 0.6); } blockquote cite:before { content: "\2014 \0020"; } blockquote cite a, blockquote cite a:visited { color: rgba(0, 0, 0, 0.6); } blockquote, blockquote p { line-height: 1.6; color: var(--header-color); } /* Microformats */ .vcard { display: inline-block; margin: 0 0 1.25em 0; border: 1px solid #dddddd; padding: 0.625em 0.75em; } .vcard li { margin: 0; display: block; } .vcard .fn { font-weight: bold; font-size: 0.9375em; } .vevent .summary { font-weight: bold; } .vevent abbr { cursor: auto; text-decoration: none; font-weight: bold; border: none; padding: 0 0.0625em; } @media only screen and (min-width: 768px) { h1, h2, h3, #toctitle, .sidebarblock>.content>.title, h4, h5, h6 { line-height: 1.2; } h1 { font-size: 2.75em; } h2 { font-size: 2.3125em; } h3, #toctitle, .sidebarblock>.content>.title { font-size: 1.6875em; } h4 { font-size: 1.4375em; } } /* Tables */ table { background: var(--white-color); margin-bottom: 1.25em; border: solid 1px #dedede; } table thead, table tfoot { background: var(--table-color); font-weight: bold; } table thead tr th, table thead tr td, table tfoot tr th, table tfoot tr td { padding: 0.5em 0.625em 0.625em; font-size: inherit; color: var(--num-color); text-align: left; } table tr th, table tr td { padding: 0.5625em 0.625em; font-size: inherit; color: var(--num-color); } table tr.even, table tr.alt, table tr:nth-of-type(even) { background: var(--nav-color); } table thead tr th, table tfoot tr th, table tbody tr td, table tr td, table tfoot tr td { display: table-cell; line-height: 1.6; } body { tab-size: 4; } h1, h2, h3, #toctitle, .sidebarblock>.content>.title, h4, h5, h6 { line-height: 1.2; word-spacing: -0.05em; } h1 strong, h2 strong, h3 strong, #toctitle strong, .sidebarblock>.content>.title strong, h4 strong, h5 strong, h6 strong { font-weight: 400; } .clearfix:before, .clearfix:after, .float-group:before, .float-group:after { content: " "; display: table; } .clearfix:after, .float-group:after { clear: both; } *:not(pre)>code { font-size: 0.9375em; font-style: normal !important; letter-spacing: 0; padding: 0.1em 0.5ex; word-spacing: -0.15em; background-color: var(--code-color); -webkit-border-radius: 4px; border-radius: 4px; line-height: 1.45; text-rendering: optimizeSpeed; word-wrap: break-word; } *:not(pre)>code.nobreak { word-wrap: normal; } *:not(pre)>code.nowrap { white-space: nowrap; } pre, pre>code { line-height: 1.45; color: var(--code-text-color); font-family: "Droid Sans Mono", "DejaVu Sans Mono", "Monospace", monospace; font-weight: normal; text-rendering: optimizeSpeed; } em em { font-style: normal; } strong strong { font-weight: normal; } .keyseq { color: rgba(51, 51, 51, 0.8); } kbd { font-family: "Droid Sans Mono", "DejaVu Sans Mono", monospace; display: inline-block; color: var(--num-color); font-size: 0.65em; line-height: 1.45; background-color: #f7f7f7; border: 1px solid #ccc; -webkit-border-radius: 3px; border-radius: 3px; -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 0 0 0.1em white inset; box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 0 0 0.1em white inset; margin: 0 0.15em; padding: 0.2em 0.5em; vertical-align: middle; position: relative; top: -0.1em; white-space: nowrap; } .keyseq kbd:first-child { margin-left: 0; } .keyseq kbd:last-child { margin-right: 0; } .menuseq, .menu { color: var(--num-color); } b.button:before, b.button:after { position: relative; top: -1px; font-weight: normal; } b.button:before { content: "["; padding: 0 3px 0 2px; } b.button:after { content: "]"; padding: 0 2px 0 3px; } p a>code:hover { color: var(--code-text-color); } #header, #content, #footnotes, #footer { width: 100%; margin-left: auto; margin-right: auto; margin-top: 0; margin-bottom: 0; max-width: 62.5em; *zoom: 1; position: relative; padding-left: 0.9375em; padding-right: 0.9375em; } #header:before, #header:after, #content:before, #content:after, #footnotes:before, #footnotes:after, #footer:before, #footer:after { content: " "; display: table; } #header:after, #content:after, #footnotes:after, #footer:after { clear: both; } #content { margin-top: 1.25em; } #content:before { content: none; } #header>h1:first-child { color: var(--header-color); margin-top: 2.25rem; margin-bottom: 0; } #header>h1:first-child+#toc { margin-top: 8px; border-top: 1px solid #ddddd8; } #header>h1:only-child, body.toc2 #header>h1:nth-last-child(2) { border-bottom: 1px solid #ddddd8; padding-bottom: 8px; } #header .details { border-bottom: 1px solid #ddddd8; line-height: 1.45; padding-top: 0.25em; padding-bottom: 0.25em; padding-left: 0.25em; color: rgba(0, 0, 0, 0.6); display: -ms-flexbox; display: -webkit-flex; display: flex; -ms-flex-flow: row wrap; -webkit-flex-flow: row wrap; flex-flow: row wrap; } #header .details span:first-child { margin-left: -0.125em; } #header .details span.email a { color: var(--header-color); } #header .details br { display: none; } #header .details br+span:before { content: "\00a0\2013\00a0"; } #header .details br+span.author:before { content: "\00a0\22c5\00a0"; color: var(--header-color); } #header .details br+span#revremark:before { content: "\00a0|\00a0"; } #header #revnumber { text-transform: capitalize; } #header #revnumber:after { content: "\00a0"; } #content>h1:first-child:not([class]) { color: var(--header-color); border-bottom: 1px solid #ddddd8; padding-bottom: 8px; margin-top: 0; padding-top: 1rem; margin-bottom: 1.25rem; } #toc { border-bottom: 1px solid #efefed; padding-bottom: 0.5em; } #toc>ul { margin-left: 0.125em; } #toc ul.sectlevel0>li>a { font-style: italic; } #toc ul.sectlevel0 ul.sectlevel1 { margin: 0.5em 0; } #toc ul { font-family: "Open Sans", "DejaVu Sans", sans-serif; list-style-type: none; } #toc li { line-height: 1.3334; margin-top: 0.3334em; } #toc a { text-decoration: none; } #toc a:active { text-decoration: underline; } #toctitle { color: #7a2518; font-size: 1.2em; } @media only screen and (min-width: 768px) { #toctitle { font-size: 1.375em; } body.toc2 { padding-left: 15em; padding-right: 0; } #toc.toc2 { margin-top: 0 !important; background-color: var(--nav-color); position: fixed; width: 15em; left: 0; top: 0; border-right: 1px solid #efefed; border-top-width: 0 !important; border-bottom-width: 0 !important; z-index: 1000; padding: 1.25em 1em; height: 100%; overflow: auto; } #toc.toc2 #toctitle { margin-top: 0; margin-bottom: 0.8rem; font-size: 1.2em; } #toc.toc2>ul { font-size: 0.9em; margin-bottom: 0; } #toc.toc2 ul ul { margin-left: 0; padding-left: 1em; } #toc.toc2 ul.sectlevel0 ul.sectlevel1 { padding-left: 0; margin-top: 0.5em; margin-bottom: 0.5em; } body.toc2.toc-right { padding-left: 0; padding-right: 15em; } body.toc2.toc-right #toc.toc2 { border-right-width: 0; border-left: 1px solid #efefed; left: auto; right: 0; } } @media only screen and (min-width: 1280px) { body.toc2 { padding-left: 20em; padding-right: 0; } #toc.toc2 { width: 20em; } #toc.toc2 #toctitle { font-size: 1.375em; } #toc.toc2>ul { font-size: 0.95em; } #toc.toc2 ul ul { padding-left: 1.25em; } body.toc2.toc-right { padding-left: 0; padding-right: 20em; } } #content #toc { border-style: solid; border-width: 1px; border-color: #e0e0dc; margin-bottom: 1.25em; padding: 1.25em; background: var(--nav-color); -webkit-border-radius: 4px; border-radius: 4px; } #content #toc> :first-child { margin-top: 0; } #content #toc> :last-child { margin-bottom: 0; } #footer { max-width: 100%; background-color: var(--num-color); padding: 1.25em; } #footer-text { color: rgba(255, 255, 255, 0.8); line-height: 1.44; } .sect1 { padding-bottom: 0.625em; } @media only screen and (min-width: 768px) { .sect1 { padding-bottom: 1.25em; } } .sect1+.sect1 { border-top: 1px solid #efefed; } #content h1>a.anchor, h2>a.anchor, h3>a.anchor, #toctitle>a.anchor, .sidebarblock>.content>.title>a.anchor, h4>a.anchor, h5>a.anchor, h6>a.anchor { position: absolute; z-index: 1001; width: 1.5ex; margin-left: -1.5ex; display: block; text-decoration: none !important; visibility: hidden; text-align: center; font-weight: normal; } #content h1>a.anchor:before, h2>a.anchor:before, h3>a.anchor:before, #toctitle>a.anchor:before, .sidebarblock>.content>.title>a.anchor:before, h4>a.anchor:before, h5>a.anchor:before, h6>a.anchor:before { content: "\00A7"; font-size: 0.85em; display: block; padding-top: 0.1em; } #content h1:hover>a.anchor, #content h1>a.anchor:hover, h2:hover>a.anchor, h2>a.anchor:hover, h3:hover>a.anchor, #toctitle:hover>a.anchor, .sidebarblock>.content>.title:hover>a.anchor, h3>a.anchor:hover, #toctitle>a.anchor:hover, .sidebarblock>.content>.title>a.anchor:hover, h4:hover>a.anchor, h4>a.anchor:hover, h5:hover>a.anchor, h5>a.anchor:hover, h6:hover>a.anchor, h6>a.anchor:hover { visibility: visible; } #content h1>a.link, h2>a.link, h3>a.link, #toctitle>a.link, .sidebarblock>.content>.title>a.link, h4>a.link, h5>a.link, h6>a.link { color: #ba3925; text-decoration: none; } #content h1>a.link:hover, h2>a.link:hover, h3>a.link:hover, #toctitle>a.link:hover, .sidebarblock>.content>.title>a.link:hover, h4>a.link:hover, h5>a.link:hover, h6>a.link:hover { color: #a53221; } .audioblock, .imageblock, .literalblock, .listingblock, .stemblock, .videoblock { margin-bottom: 1.25em; } .admonitionblock td.content>.title, .audioblock>.title, .exampleblock>.title, .imageblock>.title, .listingblock>.title, .literalblock>.title, .stemblock>.title, .openblock>.title, .paragraph>.title, .quoteblock>.title, table.tableblock>.title, .verseblock>.title, .videoblock>.title, .dlist>.title, .olist>.title, .ulist>.title, .qlist>.title, .hdlist>.title { text-rendering: optimizeLegibility; text-align: left; font-family: "Noto Serif", "DejaVu Serif", serif; font-size: 1rem; font-style: italic; } table.tableblock>caption.title { white-space: nowrap; overflow: visible; max-width: 0; } .paragraph.lead>p, #preamble>.sectionbody>.paragraph:first-of-type p { color: var(--header-color); } table.tableblock #preamble>.sectionbody>.paragraph:first-of-type p { font-size: inherit; } /* Custom SVG logos coloring */ path { fill: #02303A; } body.dark-theme { path { fill: white; } } @media (prefers-color-scheme: dark) { path { fill: white; } body.light-theme { path { fill: #02303A; } } } /* Custom scroll bar */ /* Works on Firefox */ .docs-navigation { scrollbar-width: auto; scrollbar-color: #686868 #e7e7e9; } /* Works on Chrome, Edge, and Safari */ .docs-navigation::-webkit-scrollbar { width: 12px; } .docs-navigation::-webkit-scrollbar-track { background: #e7e7e9; } .docs-navigation::-webkit-scrollbar-thumb { background-color: #686868; border-radius: 20px; border: 3px #686868; } body.dark-theme { /* Works on Firefox */ * { scrollbar-width: auto; scrollbar-color: #686868 #242526; } /* Works on Chrome, Edge, and Safari */ *::-webkit-scrollbar { width: auto; } *::-webkit-scrollbar-track { background: #242526; } *::-webkit-scrollbar-thumb { background-color: #686868; border-radius: 20px; border: 3px #686868; } } @media (prefers-color-scheme: dark) { /* Works on Firefox */ * { scrollbar-width: auto; scrollbar-color: #686868 #242526; } /* Works on Chrome, Edge, and Safari */ *::-webkit-scrollbar { width: auto; } *::-webkit-scrollbar-track { background: #242526; } *::-webkit-scrollbar-thumb { background-color: #686868; border-radius: 20px; border: 3px #686868; } body.light-theme { .docs-navigation { scrollbar-width: auto; scrollbar-color: #686868 #e7e7e9; } /* Works on Chrome, Edge, and Safari */ .docs-navigation::-webkit-scrollbar { width: 12px; } .docs-navigation::-webkit-scrollbar-track { background: #e7e7e9; } .docs-navigation::-webkit-scrollbar-thumb { background-color: #686868; border-radius: 20px; border: 3px #686868; } } } /* Custom Admonition Blocks - Icons from https://github.com/primer/octicons */ .admonitionblock td div:last-of-type p { margin-bottom: 0em !important; } .admonitionblock { margin: 1.4rem 0 0 } .admonitionblock i { font-family: inherit; } .admonitionblock i.fa { background: no-repeat 50%/1em 1em; display: inline-block; filter: var(--doc-icon-filter); font-style: normal; height: 1em; -webkit-hyphens: none; hyphens: none; vertical-align: -.125em; width: 1em } .admonitionblock p, .admonitionblock td.content { font-size: 1rem; } .admonitionblock td.content>.title+*, .admonitionblock td.content>:not(.title):first-child { margin-top: 0 } .admonitionblock pre { font-size: calc(15/var(--rem-base)*1rem) } .admonitionblock>table { position: relative; table-layout: fixed; border: none; width: 100% } .admonitionblock td.content { word-wrap: anywhere; background: var(--admonition-background); padding: 1rem 1rem 1rem 1rem; width: 100%; border-radius: 4px; } .admonitionblock td.icon { background: linear-gradient(90deg, rgba(0, 0, 0, .2) 0, rgba(0, 0, 0, .2)) no-repeat 0 /2.075em 100%; border-radius: .5em; font-size: calc(15/var(--rem-base)*1rem); left: 0; line-height: 1; padding: .25em .075em; position: absolute; top: 0; transform: translate(-.5rem, -50%) } .admonitionblock td.icon i { align-items: center; background-position-x: .5em; display: inline-flex; filter: invert(100%); padding-left: 2em; vertical-align: initial; width: auto } .admonitionblock td.icon i::after { content: attr(title); filter: invert(100%); font-style: normal; font-weight: bold; margin: -.05em; padding: 0 .5em; text-transform: uppercase } .admonitionblock.caution td.icon { background-color: var(--caution-color); color: var(--caution-on-color) } .admonitionblock.caution td.icon i { background-image: url(./img/octicons-16.svg#view-flame) } .admonitionblock.important td.icon { background-color: var(--important-color); color: var(--important-on-color) } .admonitionblock.important td.icon i { background-image: url(./img/octicons-16.svg#view-stop) } .admonitionblock.note td.icon { background-color: var(--note-color); color: var(--note-on-color) } .admonitionblock.note td.icon i { background-image: url(./img/octicons-16.svg#view-info) } .admonitionblock.tip td.icon { background-color: var(--tip-color); color: var(--tip-on-color) } .admonitionblock.tip td.icon i { background-image: url(./img/octicons-16.svg#view-light-bulb) } .admonitionblock.warning td.icon { background-color: var(--warning-color); color: var(--warning-on-color) } .admonitionblock.warning td.icon i { background-image: url(./img/octicons-16.svg#view-alert) } /* Custom collapsible block */ details summary { width: 100%; padding: 1rem 0; border-top: 1px solid gray; position: relative; cursor: pointer; list-style: none; } details summary:after { content: "+"; color: var(--black-color); position: absolute; font-size: 1.75rem; line-height: 0; margin-top: 0.3rem; right: 0; font-weight: 400; transform-origin: center; transition: 200ms linear; } details[open] summary:after { transform: rotate(45deg); font-size: 2rem; } details summary { outline: 0; } details p { font-size: 0.95rem; margin: 0 0 1rem; padding-top: 1rem; } .exampleblock>.content { border-style: solid; border-width: 1px; border-color: #e6e6e6; margin-bottom: 1.25em; padding: 1.25em; background: var(--white-color); -webkit-border-radius: 4px; border-radius: 4px; } .exampleblock>.content> :first-child { margin-top: 0; } .exampleblock>.content> :last-child { margin-bottom: 0; } .sidebarblock { border-style: solid; border-width: 1px; border-color: #e0e0dc; margin-bottom: 1.25em; padding: 1.25em; background: var(--nav-color); -webkit-border-radius: 4px; border-radius: 4px; } .sidebarblock> :first-child { margin-top: 0; } .sidebarblock> :last-child { margin-bottom: 0; } .sidebarblock>.content>.title { color: #7a2518; margin-top: 0; text-align: center; } .exampleblock>.content> :last-child> :last-child, .exampleblock>.content .olist>ol>li:last-child> :last-child, .exampleblock>.content .ulist>ul>li:last-child> :last-child, .exampleblock>.content .qlist>ol>li:last-child> :last-child, .sidebarblock>.content> :last-child> :last-child, .sidebarblock>.content .olist>ol>li:last-child> :last-child, .sidebarblock>.content .ulist>ul>li:last-child> :last-child, .sidebarblock>.content .qlist>ol>li:last-child> :last-child { margin-bottom: 0; } .literalblock pre, .listingblock pre:not(.highlight), .listingblock pre[class="highlight"], .listingblock pre[class^="highlight "], .listingblock pre.CodeRay, .listingblock pre.prettyprint { background: var(--code-color); } .sidebarblock .literalblock pre, .sidebarblock .listingblock pre:not(.highlight), .sidebarblock .listingblock pre[class="highlight"], .sidebarblock .listingblock pre[class^="highlight "], .sidebarblock .listingblock pre.CodeRay, .sidebarblock .listingblock pre.prettyprint { background: #f2f1f1; } .literalblock pre, .literalblock pre[class], .listingblock pre, .listingblock pre[class] { -webkit-border-radius: 4px; border-radius: 4px; word-wrap: break-word; padding: 1em; font-size: 0.8125em; } .literalblock pre.nowrap, .literalblock pre[class].nowrap, .listingblock pre.nowrap, .listingblock pre[class].nowrap { overflow-x: auto; white-space: pre; word-wrap: normal; } @media only screen and (min-width: 768px) { .literalblock pre, .literalblock pre[class], .listingblock pre, .listingblock pre[class] { font-size: 0.90625em; } } @media only screen and (min-width: 1280px) { .literalblock pre, .literalblock pre[class], .listingblock pre, .listingblock pre[class] { font-size: 1em; } } .literalblock.output pre { color: var(--code-color); background-color: var(--code-text-color); } .listingblock pre.highlightjs { padding: 0; } .listingblock pre.highlightjs>code { padding: 1em; -webkit-border-radius: 4px; border-radius: 4px; } .listingblock pre.prettyprint { border-width: 0; } .listingblock>.content { position: relative; } .listingblock code[data-lang]:before { display: none; content: attr(data-lang); position: absolute; font-size: 0.75em; top: 0.425rem; right: 0.5rem; line-height: 1; text-transform: uppercase; color: #999; } .listingblock:hover code[data-lang]:before { display: block; } .listingblock.terminal pre .command:before { content: attr(data-prompt); padding-right: 0.5em; color: #999; } .listingblock.terminal pre .command:not([data-prompt]):before { content: "$"; } table.pyhltable { border-collapse: separate; border: 0; margin-bottom: 0; background: none; } table.pyhltable td { vertical-align: top; padding-top: 0; padding-bottom: 0; line-height: 1.45; } table.pyhltable td.code { padding-left: .75em; padding-right: 0; } pre.pygments .lineno, table.pyhltable td:not(.code) { color: #999; padding-left: 0; padding-right: .5em; border-right: 1px solid #ddddd8; } pre.pygments .lineno { display: inline-block; margin-right: .25em; } table.pyhltable .linenodiv { background: none !important; padding-right: 0 !important; } .quoteblock { margin: 0 1em 1.25em 1.5em; display: table; } .quoteblock>.title { margin-left: -1.5em; margin-bottom: 0.75em; } .quoteblock blockquote, .quoteblock blockquote p { color: var(--header-color); font-size: 1.15rem; line-height: 1.75; word-spacing: 0.1em; letter-spacing: 0; font-style: italic; text-align: justify; } .quoteblock blockquote { margin: 0; padding: 0; border: 0; } .quoteblock blockquote:before { content: "\201c"; float: left; font-size: 2.75em; font-weight: bold; line-height: 0.6em; margin-left: -0.6em; color: var(--quoteblock-color); text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); } .quoteblock blockquote>.paragraph:last-child p { margin-bottom: 0; } .quoteblock .attribution { margin-top: 0.5em; margin-right: 0.5ex; text-align: right; } .quoteblock .quoteblock { margin-left: 0; margin-right: 0; padding: 0.5em 0; border-left: 3px solid rgba(0, 0, 0, 0.6); } .quoteblock .quoteblock blockquote { padding: 0 0 0 0.75em; } .quoteblock .quoteblock blockquote:before { display: none; } .verseblock { margin: 0 1em 1.25em 1em; } .verseblock pre { font-family: "Open Sans", "DejaVu Sans", sans; font-size: 1.15rem; color: var(--header-color); font-weight: 300; text-rendering: optimizeLegibility; } .verseblock pre strong { font-weight: 400; } .verseblock .attribution { margin-top: 1.25rem; margin-left: 0.5ex; } .quoteblock .attribution, .verseblock .attribution { font-size: 0.9375em; line-height: 1.45; font-style: italic; } .quoteblock .attribution br, .verseblock .attribution br { display: none; } .quoteblock .attribution cite, .verseblock .attribution cite { display: block; letter-spacing: -0.025em; color: rgba(0, 0, 0, 0.6); } .quoteblock.abstract { margin: 0 0 1.25em 0; display: block; } .quoteblock.abstract blockquote, .quoteblock.abstract blockquote p { text-align: left; word-spacing: 0; } .quoteblock.abstract blockquote:before, .quoteblock.abstract blockquote p:first-of-type:before { display: none; } table.tableblock { max-width: 100%; border-collapse: separate; } table.tableblock td>.paragraph:last-child p>p:last-child, table.tableblock th>p:last-child, table.tableblock td>p:last-child { margin-bottom: 0; } table.tableblock, th.tableblock, td.tableblock { border: 0 solid #dedede; } table.grid-all th.tableblock, table.grid-all td.tableblock { border-width: 0 1px 1px 0; } table.grid-all tfoot>tr>th.tableblock, table.grid-all tfoot>tr>td.tableblock { border-width: 1px 1px 0 0; } table.grid-cols th.tableblock, table.grid-cols td.tableblock { border-width: 0 1px 0 0; } table.grid-all *>tr>.tableblock:last-child, table.grid-cols *>tr>.tableblock:last-child { border-right-width: 0; } table.grid-rows th.tableblock, table.grid-rows td.tableblock { border-width: 0 0 1px 0; } table.grid-all tbody>tr:last-child>th.tableblock, table.grid-all tbody>tr:last-child>td.tableblock, table.grid-all thead:last-child>tr>th.tableblock, table.grid-rows tbody>tr:last-child>th.tableblock, table.grid-rows tbody>tr:last-child>td.tableblock, table.grid-rows thead:last-child>tr>th.tableblock { border-bottom-width: 0; } table.grid-rows tfoot>tr>th.tableblock, table.grid-rows tfoot>tr>td.tableblock { border-width: 1px 0 0 0; } table.frame-all { border-width: 1px; } table.frame-sides { border-width: 0 1px; } table.frame-topbot { border-width: 1px 0; } th.halign-left, td.halign-left { text-align: left; } th.halign-right, td.halign-right { text-align: right; } th.halign-center, td.halign-center { text-align: center; } th.valign-top, td.valign-top { vertical-align: top; } th.valign-bottom, td.valign-bottom { vertical-align: bottom; } th.valign-middle, td.valign-middle { vertical-align: middle; } table thead th, table tfoot th { font-weight: bold; } tbody tr th { display: table-cell; line-height: 1.6; background: var(--table-color); } tbody tr th, tbody tr th p, tfoot tr th, tfoot tr th p { color: var(--num-color); font-weight: bold; } p.tableblock>code:only-child { background: none; padding: 0; } p.tableblock { font-size: 1em; } td>div.verse { white-space: pre; } ol { margin-left: 1.75em; } ul li ol { margin-left: 1.5em; } dl dd { margin-left: 1.125em; } dl dd:last-child, dl dd:last-child> :last-child { margin-bottom: 0; } ol>li p, ul>li p, ul dd, ol dd, .olist .olist, .ulist .ulist, .ulist .olist, .olist .ulist { margin-bottom: 0.625em; } ul.unstyled, ol.unnumbered, ul.checklist, ul.none { list-style-type: none; } ul.unstyled, ol.unnumbered, ul.checklist { margin-left: 0.625em; } ul.checklist li>p:first-child>.fa-square-o:first-child, ul.checklist li>p:first-child>.fa-check-square-o:first-child { width: 1em; font-size: 0.85em; } ul.checklist li>p:first-child>input[type="checkbox"]:first-child { width: 1em; position: relative; top: 1px; } ul.inline { margin: 0 auto 0.625em auto; margin-left: -1.375em; margin-right: 0; padding: 0; list-style: none; overflow: hidden; } ul.inline>li { list-style: none; float: left; margin-left: 1.375em; display: block; } ul.inline>li>* { display: block; } .unstyled dl dt { font-weight: normal; font-style: normal; } ol.arabic { list-style-type: decimal; } ol.decimal { list-style-type: decimal-leading-zero; } ol.loweralpha { list-style-type: lower-alpha; } ol.upperalpha { list-style-type: upper-alpha; } ol.lowerroman { list-style-type: lower-roman; } ol.upperroman { list-style-type: upper-roman; } ol.lowergreek { list-style-type: lower-greek; } .hdlist>table, .colist>table { border: 0; background: none; } .hdlist>table>tbody>tr, .colist>table>tbody>tr { background: none; } td.hdlist1, td.hdlist2 { vertical-align: top; padding: 0 0.625em; } td.hdlist1 { font-weight: bold; padding-bottom: 1.25em; } .literalblock+.colist { margin-top: -0.5em; } .colist>table tr>td:first-of-type { padding: 0 0.75em; line-height: 1; } .colist>table tr>td:first-of-type img { max-width: initial; } .colist>table tr>td:last-of-type { padding: 0.25em 0; } .thumb, .th { line-height: 0; display: inline-block; border: solid 4px var(--white-color); -webkit-box-shadow: 0 0 0 1px #dddddd; box-shadow: 0 0 0 1px #dddddd; } .imageblock.left, .imageblock[style*="float: left"] { margin: 0.25em 0.625em 1.25em 0; } .imageblock.right, .imageblock[style*="float: right"] { margin: 0.25em 0 1.25em 0.625em; } .imageblock>.title { margin-bottom: 0; } .imageblock.thumb, .imageblock.th { border-width: 6px; } .imageblock.thumb>.title, .imageblock.th>.title { padding: 0 0.125em; } .image.left, .image.right { margin-top: 0.25em; margin-bottom: 0.25em; display: inline-block; line-height: 0; } .image.left { margin-right: 0.625em; } .image.right { margin-left: 0.625em; } a.image { text-decoration: none; display: inline-block; } a.image object { pointer-events: none; } sup.footnote, sup.footnoteref { font-size: 0.875em; position: static; vertical-align: super; } sup.footnote a, sup.footnoteref a { text-decoration: none; } sup.footnote a:active, sup.footnoteref a:active { text-decoration: underline; } #footnotes { padding-top: 0.75em; padding-bottom: 0.75em; margin-bottom: 0.625em; } #footnotes hr { width: 20%; min-width: 6.25em; margin: -0.25em 0 0.75em 0; border-width: 1px 0 0 0; } #footnotes .footnote { padding: 0 0.375em 0 0.225em; line-height: 1.3334; font-size: 0.875em; margin-left: 1.2em; text-indent: -1.05em; margin-bottom: 0.2em; } #footnotes .footnote a:first-of-type { font-weight: bold; text-decoration: none; } #footnotes .footnote:last-of-type { margin-bottom: 0; } #content #footnotes { margin-top: -0.625em; margin-bottom: 0; padding: 0.75em 0; } .gist .file-data>table { border: 0; background: var(--white-color); width: 100%; margin-bottom: 0; } .gist .file-data>table td.line-data { width: 99%; } div.unbreakable { page-break-inside: avoid; } .big { font-size: larger; } .small { font-size: smaller; } .underline { text-decoration: underline; } .overline { text-decoration: overline; } .line-through { text-decoration: line-through; } .green { color: #006000; } .red { color: #bf0000; } .yellow { color: #bfbf00; } span.icon>.fa { cursor: default; } .conum[data-value] { display: inline-block; color: var(--white-color) !important; background-color: var(--num-color); -webkit-border-radius: 100px; border-radius: 100px; text-align: center; font-size: 0.75em; width: 1.67em; height: 1.67em; line-height: 1.67em; font-family: "Open Sans", "DejaVu Sans", sans-serif; font-style: normal; font-weight: bold; } .conum[data-value] * { color: var(--white-color) !important; } .conum[data-value]+b { display: none; } .conum[data-value]:after { content: attr(data-value); } pre .conum[data-value] { position: relative; top: -0.125em; } b.conum * { color: inherit !important; } .conum:not([data-value]):empty { display: none; } dt, th.tableblock, td.content, div.footnote { text-rendering: optimizeLegibility; } h1, h2, p, td.content, span.alt { letter-spacing: -0.01em; } p strong, td.content strong, div.footnote strong { letter-spacing: -0.005em; } p, blockquote, dt, td.content, span.alt { font-size: 1.0625rem; } p { margin-bottom: 1.25rem; } .sidebarblock p, .sidebarblock dt, .sidebarblock td.content, p.tableblock { font-size: 1em; } .exampleblock>.content { background-color: #fffef7; border-color: #e0e0dc; -webkit-box-shadow: 0 1px 4px #e0e0dc; box-shadow: 0 1px 4px #e0e0dc; } .print-only { display: none !important; } @media print { @page { margin: 1.25cm 0.75cm; } * { -webkit-box-shadow: none !important; box-shadow: none !important; text-shadow: none !important; } a { color: inherit !important; text-decoration: underline !important; } a.bare, a[href^="#"], a[href^="mailto:"] { text-decoration: none !important; } a[href^="http:"]:not(.bare):after, a[href^="https:"]:not(.bare):after { content: "(" attr(href) ")"; display: inline-block; font-size: 0.875em; padding-left: 0.25em; } abbr[title]:after { content: " (" attr(title) ")"; } pre, blockquote, tr, img, object, svg { page-break-inside: avoid; } thead { display: table-header-group; } svg { max-width: 100%; } p, blockquote, dt, td.content { font-size: 1em; orphans: 3; widows: 3; } h2, h3, #toctitle, .sidebarblock>.content>.title, #toctitle, .sidebarblock>.content>.title { page-break-after: avoid; } #toc, .sidebarblock, .exampleblock>.content { background: none !important; } #toc { border-bottom: 1px solid #ddddd8 !important; padding-bottom: 0 !important; } .sect1 { padding-bottom: 0 !important; } .sect1+.sect1 { border: 0 !important; } #header>h1:first-child { margin-top: 1.25rem; } body.book #header { text-align: center; } body.book #header>h1:first-child { border: 0 !important; margin: 2.5em 0 1em 0; } body.book #header .details { border: 0 !important; display: block; padding: 0 !important; } body.book #header .details span:first-child { margin-left: 0 !important; } body.book #header .details br { display: block; } body.book #header .details br+span:before { content: none !important; } body.book #toc { border: 0 !important; text-align: left !important; padding: 0 !important; margin: 0 !important; } body.book #toc, body.book #preamble, body.book h1.sect0, body.book .sect1>h2 { page-break-before: always; } .listingblock code[data-lang]:before { display: block; } #footer { background: none !important; padding: 0 0.9375em; } #footer-text { color: rgba(0, 0, 0, 0.6) !important; font-size: 0.9em; } .hide-on-print { display: none !important; } .print-only { display: block !important; } .hide-for-print { display: none !important; } .show-for-print { display: inherit !important; } } /* END asciidoc.css */ html, body { margin: 0; padding: 0; } html { font-size: 16px; font-weight: 400; line-height: 1.5; } body { color: var(--text-color); background-color: var(--white-color); font-family: "Lato", "Helvetica Neue", Arial, sans-serif; line-height: 1.5; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } /* Links */ a { color: #1DA2BD; text-decoration: none; } a:hover, a:focus { text-decoration: underline; } #content a[href^='../dsl/'], #content a[href^='../kotlin-dsl/'], #content a[href^='../javadoc/'] { font-family: 'Inconsolata', monospace; font-style: normal; border-bottom: 1px dotted rgba(29, 162, 189, 0.5); padding: 0 1px; } #content a[href^='../dsl/']:hover, #content a[href^='../dsl/']:focus, #content a[href^='../kotlin-dsl/']:hover, #content a[href^='../kotlin-dsl/']:focus, #content a[href^='../javadoc/']:hover, #content a[href^='../javadoc/']:focus { text-decoration: none; } /* Copy */ p { font-size: 1rem; } pre, pre>code, code { font-family: 'Inconsolata', monospace; } h1, h2, h3, h4, h5, h6, #toctitle, .sidebarblock>.content>.title { font-family: inherit; font-weight: 500; color: inherit; } h1 { font-size: 2rem; } h2 { font-size: 1.5rem; } h3 { font-size: 1.125rem; } h4 { font-size: 1.0625rem; } h5, h6 { font-size: 1rem; } b, strong { font-weight: 500; } dl { margin: 0 0 1.25rem 1.5rem; } .dlist dt code { color: var(--text-color); font-size: 1em; font-weight: bold; } .dlist p { margin-bottom: 0.625rem; } .sr-only { border: 0; clip: rect(0, 0, 0, 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; } /* Layout */ .main-content>.appendix, .main-content>.book, .main-content>.chapter, .main-content>.footer { background-color: var(--white-color); border-radius: 5px; max-width: 45rem; padding: 1.5rem; } @media screen and (max-width: 45em) { .footer { max-width: 100%; } .main-content>.appendix, .main-content>.book, .main-content>.chapter { margin-top: 0; margin-bottom: 0; } } /* Override asciidoc styles */ #header { position: static; } #header, #content { padding: 0; } #header .details { /* TODO: Pretty sure there's a way to avoid Asciidoc generating details */ display: none; } p { color: var(--text-color); } h1, h2, p, p strong, td.content, td.content strong, div.footnote strong, span.alt { letter-spacing: normal; } .subheader, .admonitionblock td.content>.title, .audioblock>.title, .exampleblock>.title, .imageblock>.title, .listingblock>.title, .literalblock>.title, .stemblock>.title, .openblock>.title, .paragraph>.title, .quoteblock>.title, table.tableblock>.title, .verseblock>.title, .videoblock>.title, .dlist>.title, .olist>.title, .ulist>.title, .qlist>.title, .hdlist>.title { color: inherit; font-family: inherit; } .listingblock .title, .listingblock .title code { font-style: normal; font-weight: bold; } .imageblock, .videoblock { padding: 0.25em; } p.lead, .paragraph.lead>p, #preamble>.sectionbody>.paragraph:first-of-type p { font-size: 1.0625rem; } .paragraph.lead>p, #preamble>.sectionbody>.paragraph:first-of-type p { color: inherit; } .sect1 { padding-bottom: 0; } .sect1+.sect1 { border: 0 none; } .verseblock pre { font-family: "Lato", Arial, sans-serif; } td.hdlist1 { padding-bottom: 0.625rem; } td.hdlist2 p { margin-bottom: 0.625rem; } body.book #header>h1 { border: 0; } #header>h1:first-child { margin-top: 0; } #content a.link { color: var(--title-color); } .highlight .com { color: #777; } .listingblock pre.highlightjs>code { overflow-x: auto; } .listingblock pre.highlight { overflow-x: auto; } .listingblock pre.highlight>code { white-space: pre; } .conum[data-value] { font-family: "Lato", Arial, sans-serif; } .colist>table tr>td:first-of-type { padding-top: 0.25em; padding-bottom: 0.25em; line-height: 1.4; vertical-align: baseline; } /* * Samples */ .exampleblock>.content { background-color: inherit; border: 0 none; box-shadow: none; padding: 0; padding-bottom: 0.7rem; margin-bottom: 0; } .exampleblock>.content .title { background-color: var(--code-color); border-top: 1px solid #ccc; font-family: 'Inconsolata', monospace; margin: 0; padding: 1em 1em 0; } .exampleblock>.title>a { text-decoration: none; color: var(--num-color); } .exampleblock .listingblock { margin: 0; } /* * Ensure that blocks of code do not wrap by applying the behavior of `[listing%nowrap]` by default. * * These styles are copied from a CSS ruleset in asciidoctor.css that has the same group of * selectors except that they end with `.nowrap`. */ .openblock .content { background: var(--admonition-background); margin-bottom: 1.25em; padding: 1em 1em 0em 1em; border-radius: 4px; overflow: auto !important; } .literalblock pre, .literalblock pre[class], .listingblock pre, .listingblock pre[class] { overflow-x: auto; white-space: pre; word-wrap: normal; } /* * This CSS ruleset solves: https://github.com/gradle/guides/issues/113#issuecomment-314826749. */ .literalblock pre::after, .literalblock pre[class]::after, .listingblock pre::after, .listingblock pre[class]::after { content: ""; } .quoteblock blockquote, .quoteblock blockquote p { text-align: left; text-align: start; } div.screenshot { box-shadow: 0 0 20px 1px rgba(0, 0, 0, 0.2); margin-left: auto; margin-right: auto; width: 90%; } .inset { box-shadow: 0 0 1px 1px rgba(0, 0, 0, 0.1); padding: 1em; } .image.inline-icon img { vertical-align: sub; } /* TOC */ #header>h1:first-child+#toc { background: none; border: 0 none; margin-top: 0; } #toc, #content #toc { border: 0 none; } #toc>ul { margin-left: 0; font-family: inherit; } #toc>ul>li { line-height: 1.25; margin-top: 0; padding-bottom: 0.5rem; } #toc>ul>li:last-of-type { padding-bottom: 0; } #toc a { font-style: normal; } #toc a:hover, #toc a:focus, #toc a:hover code, #toc a:focus code { color: #1DA2BD; } #toc a:active { text-decoration: none; } /* Site header specific styles */ .hamburger { background-color: transparent; background-image: none; border: none; border-radius: 4px; cursor: pointer; margin-left: auto; padding: 11px 10px; } .hamburger:focus { outline: 0; } .hamburger__bar { display: block; width: 22px; height: 2px; background-color: var(--black-color); border-radius: 1px; } .hamburger__bar+.hamburger__bar { margin-top: 4px; } .site-header { background-color: var(--top-header-color); } /* Override javadoc styles */ .site-header div { font-family: 'Lato', Arial, sans-serif; } .site-header__navigation-header a { align-self: center; border-bottom: 0 none; height: 36px; } .site-header .site-header-version { align-self: center; color: #1da2bd; font-size: 20px; padding-left: 1px; margin-top: 22px; } .site-header__navigation { z-index: 2; display: flex; flex-direction: column; } .site-header__navigation-header { display: flex; flex: 0 0 auto; margin-left: 12px; } .site-header__navigation-collapsible { flex: 1 1 auto; height: 210px; overflow: visible; transition: height 0.3s ease; } .site-header__navigation-items { display: flex; flex-direction: column; flex-wrap: wrap; align-items: flex-start; max-height: 210px; /* This matches the collapsible height above */ margin: 0 20px; padding-top: 12px; padding-left: 0; list-style-type: none; } .site-header__navigation-item { flex: 0 1 auto; font-size: 16px; width: 250px; } .site-header__navigation-item .site-header__navigation-link { position: relative; display: inline-block; cursor: pointer; width: 100%; padding: 5px; line-height: 20px; border: 0 none; color: var(--text-color); text-decoration: none; transition: none; -o-transition: none; -moz-transition: none; -webkit-transition: none; } .site-header__navigation-item .site-header__navigation-link:hover { color: #1DA2BD; } .site-header__navigation-item .site-header__navigation-link.active { font-weight: 500; } /* Navigation submenu styles */ .site-header__navigation-submenu-section { position: relative; } .site-header__navigation-submenu-section .site-header__down-arrow { width: 8px; height: 8px; margin-left: 2px; margin-top: 0; } .site-header__navigation-submenu-section .site-header__navigation-link:hover path { fill: none; } .site-header__navigation-submenu-section .site-header__navigation-submenu .site-header__navigation-submenu-item-link:hover { color: #1DA2BD; } .site-header__navigation-submenu-section .site-header__navigation-submenu { display: none; width: 170px; background-color: var(--menu-burger-color); top: 40px; left: 7px; /* NOTE: This must match the padding of .site-header__navigation-link */ padding: 3px 10px 6px 10px; z-index: 100; } .site-header__navigation-submenu-section .site-header__navigation-submenu .site-header__navigation-submenu-item-link { width: 100%; color: var(--text-color); white-space: nowrap; display: inline-block; padding-top: 3px; border: 0 none; transition: none; -o-transition: none; -moz-transition: none; -webkit-transition: none; } .site-header__navigation-submenu-section .site-header__navigation-submenu .site-header__navigation-submenu-item-link .site-header__navigation-submenu-item-link-text { display: inline-block; font-size: 16px; } .site-header__navigation-submenu-section.open .site-header__navigation-submenu { display: block; } /* Top navigation mobile styles */ @media (max-width: 1023px) { .site-header__navigation-collapsible--collapse { height: 0; overflow-y: hidden; } .site-header__navigation-submenu-section .site-header__navigation-submenu { padding: 0 1rem 0.5rem 1.5rem; display: block; top: 30px !important; left: 0 !important; } .site-header__navigation-item, .site-header__navigation-submenu-section .site-header__navigation-submenu .site-header__navigation-submenu-item-link .site-header__navigation-submenu-item-link-text { font-size: 18px; } .site-header { padding: 5px 12px; } .site-header-version { display: none; } .site-footer__navigation { flex-direction: column; } .site-footer__links { flex-wrap: wrap; } .site-footer__link-group { margin-bottom: 1rem; } } /* Top navigation desktop styles */ @media (min-width: 1024px) { .site-header { -webkit-box-shadow: 0 2px 4px 0 var(--box-shadow-color); -moz-box-shadow: 0 2px 4px 0 var(--box-shadow-color); box-shadow: 0 2px 4px 0 var(--box-shadow-color); z-index: 2; } body.dark-theme { .site-header { -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none; z-index: 2; } } @media (prefers-color-scheme: dark) { .site-header { -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none; z-index: 2; } body.light-theme { .site-header { -webkit-box-shadow: 0 2px 4px 0 var(--box-shadow-color); -moz-box-shadow: 0 2px 4px 0 var(--box-shadow-color); box-shadow: 0 2px 4px 0 var(--box-shadow-color); z-index: 2; } } } /* Pushes the section headings to just below the top nav bar when a user navigates directly to section anchors. */ #content h2[id], #content h3[id], #content h4[id], #content h5[id] { padding-top: 60px; } #content h2[id] { /* Little extra room above h2s */ margin-top: -1em; } #content h3[id], #content h4[id], #content h5[id] { margin-top: -60px; } .site-header__navigation { flex-direction: row; } .site-header__navigation-button { display: none; } .site-header__navigation-items { flex-direction: row; align-items: center; float: right; width: auto; padding-top: 0; } .site-header__navigation-item { width: auto; } .site-header__navigation-item .site-header__navigation-link { padding: 15px 18px; } .site-header__navigation-item:last-of-type .site-header__navigation-link { padding-right: 0; } .site-header__navigation-link--button { padding: 6px 12px; } .site-header__navigation-collapsible { height: auto; } .site-header__navigation-submenu-section .site-header__navigation-submenu { position: absolute; border: 1px solid #9a9a9a; border-radius: 3px; } .site-header__navigation-submenu-section:hover .site-header__navigation-submenu { display: block; } /* Pushes the section headings to just below the top nav bar when a user navigates directly to section anchors. It doesn't work if you try to apply the padding and margin to the `h` elements directly. */ .chapter a[name], .chapter .anchor { padding-top: 60px; margin-top: -60px; text-decoration: none; border: none; display: inline-block; } } /* Side Navigation styles */ /* Docs Navigation */ .docs-navigation { border-right: 1px solid var(--various-border-color); } .docs-navigation .search-container { display: none; margin-bottom: 1rem; } .docs-navigation a { color: var(--text-color); display: block; font-size: .95rem; position: relative; } .docs-navigation a:focus { outline: none; } .docs-navigation a:hover { color: #35c1e4; text-decoration: none; } .docs-navigation a code { color: var(--text-color); overflow-wrap: break-word; padding: 0; word-break: break-all; } .docs-navigation a.active { color: #06A0CE; outline: 0; border: none; -moz-outline-style: none; } .docs-navigation a.active:hover { color: #35c1e4; text-decoration: underline; } .docs-navigation ul { list-style-type: none; margin: 0; padding: 0; } .docs-navigation li>ul>li a { font-size: 14px; color: #7d7d7d; } .docs-navigation ul:last-of-type { margin-bottom: 0; } .docs-navigation li { margin-top: 0.3334em; line-height: 1.3334; } .docs-navigation li:last-of-type { margin-bottom: 0; } .docs-navigation .nav-dropdown:before { content: '\2023'; font-size: 28px; position: absolute; margin-left: -14px; margin-top: -8px; } .docs-navigation .nav-dropdown.expanded:before { transform: rotate(90deg); } .docs-navigation>ul ul, .docs-navigation>ul ul ul { display: none; height: 0; margin-left: 1rem; } .docs-navigation>ul ul:target, .docs-navigation>ul ul:target ul, .docs-navigation>ul .nav-dropdown.expanded~ul { display: block; height: auto; } .docs-navigation h3 { font-size: .95rem; font-weight: 600; line-height: 1.5; margin: 1.5em 0 0; } .docs-navigation .docs-home-link { position: relative; } @media screen and (min-width: 45rem) { .main-content { display: flex; } } /* User guide navigation appears for desktops */ @media screen and (min-width: 64rem) { .docs-navigation { flex: 0 0 auto; width: 13.75rem; } .main-content>.appendix, .main-content>.book, .main-content>.chapter { flex: 0 0 auto; margin: 0 auto; } } /** * For mobile devices, we show navigation at bottom of page. * * This is the simplest solution to this issue. */ @media not screen and (min-width: 64rem) { /* Repeat the class twice to prioritize our mobile classes! */ .content.content { /* Make the height equal to the real height of content */ overflow: visible; } .main-content { /* Main content show first */ flex-direction: column-reverse; } .docs-navigation.docs-navigation { /* Fill the main container */ width: 100%; /* Don't clip the navigation container */ overflow: visible; } } /* Userguide Meta */ .chapter-meta { float: right; text-align: right; } .chapter-meta .edit-link { color: #999; font-size: 0.9em; padding-right: 3px; } .chapter-meta .edit-link svg { margin-right: 1px; } /* Clever use of RTL to fill in all stars to left of hover position */ .rating { direction: rtl; } .rating>.star { cursor: pointer; display: table-cell; padding: 3px; } .rating>.star:hover>svg>g, .rating>.star:hover~.star>svg>g, .rating>.star.selected>svg>g, .rating>.star.selected~.star>svg>g { fill: #999; } /* Footer styles */ .site-footer {} .site-footer__navigation { display: flex; padding: 30px 12px; max-width: 62.5rem; margin: 0 auto; padding-left: 5rem; } @media not screen and (min-width: 64rem) { .site-footer__navigation { /* same to nav.docs-navigation for mobiles */ padding: 20px 20px 20px 26px; } } .site-footer__links { display: flex; flex: 1 1 auto; } .site-footer__links .site-footer__links-list { list-style-type: none; margin: 0; } .site-footer__links .site-footer__links-list a { color: var(--footer-other-text-color); } .site-footer__link-group { flex: 1 1 auto; flex-basis: 175px; } .site-footer__link-group header { color: var(--text-color); } .site-footer__subscribe-newsletter .newsletter-form__header h5 { color: var(--text-color); margin-top: 0; } .site-footer__subscribe-newsletter p { font-size: 0.875rem; margin: 2px 0 0 2px; opacity: 0.7; } .site-footer__subscribe-newsletter .disclaimer { color: var(--footer-other-text-color); font-size: 0.75rem; opacity: 0.55; } .site-footer__subscribe-newsletter .newsletter-form { padding-top: 6px; display: flex; justify-content: flex-start; } .site-footer__subscribe-newsletter .email, .site-footer__subscribe-newsletter .submit { height: 40px; } .site-footer__subscribe-newsletter .email { line-height: 40px; width: 250px; color: #1DA2BD; font-size: 16px; padding-left: 20px; border-top-left-radius: 4px; border-bottom-left-radius: 4px; border: 1px solid var(--footer-form-color); } .site-footer__subscribe-newsletter .submit { font-family: inherit; font-size: inherit; line-height: inherit; width: 100px; background-color: #1BA8CB; color: #fff; font-weight: 500; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-style: none; cursor: pointer; transition: all .3s ease; } /* Secondary footer (below) */ .site-footer-secondary { background-color: var(--footer-white-color); border-top: 1px solid var(--various-border-color); width: 100%; z-index: 1; } body.dark-theme { .site-footer-secondary { background-color: var(--footer-white-color); border-top: none; width: 100%; z-index: 1; } } @media (prefers-color-scheme: dark) { .site-footer-secondary { background-color: var(--footer-white-color); border-top: none; width: 100%; z-index: 1; } body.light-theme { .site-footer-secondary { background-color: var(--footer-white-color); border-top: 1px solid var(--various-border-color); width: 100%; z-index: 1; } } } .site-footer-secondary__contents { display: flex; align-items: center; justify-content: space-between; max-width: 75rem; margin-left: auto; margin-right: auto; font-size: 0.875rem; padding: 0.5rem 0.75rem; } /* * 1. Value is the largest computed width among 'site-footer__copy' and 'site-footer__links'. */ .site-footer__copy, .site-footer__secondary-links { flex-grow: 0; flex-basis: 280px; /* 1. */ } /* * 1. 'flex-shrink: 1' is applied to the element with the smallest computed width among * 'site-footer__copy' and 'site-footer__links'. */ .site-footer__copy { flex-shrink: 1; /* 1. */ } .site-footer__logo { flex: 0 0 auto; margin-right: 10px; margin-left: 10px; } .site-footer__logo svg { width: 35px; height: 35px; } /* * 1. 'flex-shrink: 0' is applied to the element with the largest computed width among * 'site-footer__copy' and 'site-footer__links'. */ .site-footer__secondary-links { flex-shrink: 0; /* 1 */ text-align: right; white-space: nowrap; } .site-footer-secondary a { color: #999; } .site-footer-secondary__links a:not(:last-child) { padding-right: 10px; } .site-footer-secondary__links a:not(:first-child) { padding-left: 10px; } @media all and (max-width: 29.99rem) { .site-footer__rights, .site-footer-secondary__links { display: none; } .site-footer__logo { order: 1; text-align: left; } .site-footer__copy { order: 2; text-align: right; } } /* Avoid the footer taking up much of the screen on short displays */ @media all and (max-height: 56.25rem) { .site-footer__navigation { margin: 1.5rem auto 0 auto; padding-top: 0; padding-bottom: 0; } } @media screen and (min-width: 84.375rem) { .ui-logos .ui-logo { box-shadow: 0 6px 15px 1px rgba(0, 0, 0, 0.56); } } /* User Manual Home */ .technology-logos, .ui-logos { display: flex; flex-direction: row; flex-wrap: wrap; justify-content: space-around; } .technology-logo, .ui-logo { flex: 0 1 auto; } .ui-logo { width: 224px; height: 135px; margin: 12px; } /* Samples download button */ .download { display: flex; } .download a { border-style: solid; border-width: 1px; text-decoration: none; padding: 5px; display: block; width: 10em; margin: 5px; } .download ul { list-style: none; list-style-type: none; } .download li { float: right; } .docs-navigation { width: 18rem; padding: 20px 20px 20px 26px; background: var(--nav-color); overflow-y: scroll; overflow-x: auto; } .layout { display: flex; flex-direction: column; overflow: hidden; height: 100vh; } .main-content { overflow-y: auto; overflow-x: auto; display: flex; } .content { flex: 1 1 auto; overflow: auto; padding-left: 0; padding-right: 0; } .content .chapter { padding: 2rem 2.4rem; } #toc a:active { font-weight: 500; } .site-header { margin-bottom: 1rem; } .site-header__navigation-submenu-item { padding: 2px 0; } .site-footer { background-color: var(--footer-color); padding: 20px 0 40px 0; border-top: 1px solid var(--various-border-color); } #header { margin-left: 0; } #header>h1:first-child { margin-bottom: 40px; } @media screen and (min-width: 64rem) { #header { margin-bottom: 20px; } .site-header { margin-bottom: 0; z-index: 2; } .site-header__navigation-header { margin-top: -7px; } .site-header__navigation-submenu-section:after { content: '\2023'; font-size: 28px; position: absolute; transform: rotate(90deg); margin-right: 10px; top: 5px; right: -7px; } .site-footer__navigation { flex-wrap: wrap; } .site-footer__link-group { flex: 1 1 auto; } .site-footer__links { margin-bottom: 1rem; } } @media screen and (min-width: 75rem) { .content .chapter { box-sizing: content-box; } #content { padding-right: 260px; margin: 0; } /* #toc here must be referenced as #header #toc since we don't want to change single page #toc */ #header #toc { position: fixed; margin: 0 auto; padding-bottom: 0; right: 0; top: 65px; width: 260px; z-index: 1; overflow: auto; border-radius: 0 0 5px 0; max-height: calc(100% - 118px); margin-right: 15px; } #header #toctitle { margin-top: 1.3em; } #header #toc>ul { /* margin-left have to increase if you change border thickness of active toc item */ margin-left: 1px; border-left: 1px solid #666; margin-bottom: 0; padding-right: 10px; padding-bottom: 0.5rem; background-color: var(--white-color); } #header #toc>ul>li, #toc>ul>li:last-of-type { padding: 0.5rem 0; margin: 0; } #header #toc a { padding-left: 10px; font-weight: 400; color: var(--text-color); font-size: .95rem; display: inline-block; } #header #toc a.active { font-weight: 500; border-left: 3px solid #01303a; margin-left: -2px; padding-left: 9px; } .site-footer__navigation { flex-wrap: wrap; margin-left: auto; padding-left: 3rem; } .site-footer__link-group { flex: 0.15 1 auto; } .site-footer__subscribe-newsletter { /* A fix so subscribe disclaimer does not go under long ToC */ max-width: calc(100% - 17rem); } } @media screen and (min-width: 80rem) { .site-footer__subscribe-newsletter { max-height: none; } } @media screen and (min-width: 100rem) { .content .chapter { max-width: 60.5rem; } #header { margin: 0 auto; } #content { padding-right: 0; margin: 0 auto; } #header #toc { right: initial; margin-left: 62.5rem; } .site-footer__navigation { padding-left: 0; } .site-footer__link-group { flex: 0.2 1 auto; } } @media screen and (min-width: 112rem) { .content .chapter { max-width: 62.5rem; margin: 0 auto; padding-right: 3.5rem; position: relative; left: -130px; } #header #toc { right: initial; margin-left: 64.5rem; } .site-footer__link-group { flex: 0.2 1 auto; } } @supports (-moz-appearance:meterbar) and (background-blend-mode:difference, normal) { /* Firefox only */ .site-header__navigation-submenu-section:after { top: 2px; right: -4px; } } /* Added dark mode and other items for outdated Prettify.css */ code[data-lang="text"] .pln, code[data-lang="text"] .str, code[data-lang="text"] .kwd, code[data-lang="text"] .com, code[data-lang="text"] .typ, code[data-lang="text"] .lit, code[data-lang="text"] .pun, code[data-lang="text"] .opn, code[data-lang="text"] .clo, code[data-lang="text"] .tag, code[data-lang="text"] .atn, code[data-lang="text"] .atv, code[data-lang="text"] .dec, code[data-lang="text"] .var, code[data-lang="text"] .fun { color: #000; } body.dark-theme { code[data-lang="text"] .pln, code[data-lang="text"] .str, code[data-lang="text"] .kwd, code[data-lang="text"] .com, code[data-lang="text"] .typ, code[data-lang="text"] .lit, code[data-lang="text"] .pun, code[data-lang="text"] .opn, code[data-lang="text"] .clo, code[data-lang="text"] .tag, code[data-lang="text"] .atn, code[data-lang="text"] .atv, code[data-lang="text"] .dec, code[data-lang="text"] .var, code[data-lang="text"] .fun { color: #fff !important; } .com { color: #909090 !important; } .str, .tag { color: #90a959 !important; } .kwd, .atv { color: #d28445 !important; } .typ { color: #f4bf75 !important; } .lit, .atn { color: #6a9fb5 !important; } .pun, .pln, .opn, .clo { color: #d0d0d0 !important; } .dec, .var { color: #aa759f !important; } li.L1, li.L3, li.L5, li.L7, li.L9 { background: #111 !important; } } @media (prefers-color-scheme: dark) { code[data-lang="text"] .pln, code[data-lang="text"] .str, code[data-lang="text"] .kwd, code[data-lang="text"] .com, code[data-lang="text"] .typ, code[data-lang="text"] .lit, code[data-lang="text"] .pun, code[data-lang="text"] .opn, code[data-lang="text"] .clo, code[data-lang="text"] .tag, code[data-lang="text"] .atn, code[data-lang="text"] .atv, code[data-lang="text"] .dec, code[data-lang="text"] .var, code[data-lang="text"] .fun { color: #fff !important; } .com { color: #909090 !important; } .str, .tag { color: #90a959 !important; } .kwd, .atv { color: #d28445 !important; } .typ { color: #f4bf75 !important; } .lit, .atn { color: #6a9fb5 !important; } .pun, .pln, .opn, .clo { color: #d0d0d0 !important; } .dec, .var { color: #aa759f !important; } li.L1, li.L3, li.L5, li.L7, li.L9 { background: #111 !important; } body.light-theme { code[data-lang="text"] .pln, code[data-lang="text"] .str, code[data-lang="text"] .kwd, code[data-lang="text"] .com, code[data-lang="text"] .typ, code[data-lang="text"] .lit, code[data-lang="text"] .pun, code[data-lang="text"] .opn, code[data-lang="text"] .clo, code[data-lang="text"] .tag, code[data-lang="text"] .atn, code[data-lang="text"] .atv, code[data-lang="text"] .dec, code[data-lang="text"] .var, code[data-lang="text"] .fun { color: #000; } .pln { color: #000 !important;; } .com { color: #800 !important;; } .str, .tag { color: #080 !important;; } .kwd, .atv { color: #008 !important;; } .typ { color: #606 !important;; } .lit, .atn { color: #066 !important;; } .pun, .opn, .clo { color: #660 !important;; } .dec, .var { color: #606 !important;; } li.L1, li.L3, li.L5, li.L7, li.L9 { background: #eee; } } } /* DPE University button*/ /* CSS */ .badge-wrapper { padding-top: 0px; padding-bottom: 20px; a { text-decoration: none; } a:link { text-decoration: none; } a:visited { text-decoration: none; } a:hover { text-decoration: none; } a:active { text-decoration: none; } } .badge { background-color: var(--black-color); height: 24px; border-radius: 12px; border-color: var(--black-color); border-style: solid; border-width: 1px; padding: 5px; a { color: var(--gradle-blue); } } .badge-type { border-radius: 8px; margin-right: 10px; padding-left: 10px; padding-right: 10px; } .badge-text { color: var(--white-color); } .button--blue { color: white; border-color: transparent; &:hover { color: white; } } .button--blue { background: var(--gradle-blue); background: linear-gradient(var(--button-gradient-angle), var(--gradle-blue) 0%, var(--gradle-blue-lite) 100%); &:hover { background: var(--gradle-blue-lite); } } /* Custom Download button*/ /* CSS */ .button-9 { appearance: button; backface-visibility: hidden; background-color: #209BC4; border-radius: 6px; border-width: 0; box-shadow: rgba(50, 50, 93, .1) 0 0 0 1px inset, rgba(50, 50, 93, .1) 0 2px 5px 0, rgba(0, 0, 0, .07) 0 1px 1px 0; box-sizing: border-box; color: #fff; cursor: pointer; font-family: -apple-system, system-ui, "Segoe UI", Roboto, "Helvetica Neue", Ubuntu, sans-serif; font-size: 100%; height: 44px; line-height: 1.15; margin: 12px 12px 12px 0px; outline: none; overflow: hidden; padding: 0 25px; position: relative; text-align: center; text-transform: none; transform: translateZ(0); transition: all .2s, box-shadow .08s ease-in; user-select: none; -webkit-user-select: none; touch-action: manipulation; width: 25%; } .button-9:disabled { cursor: default; } .button-9:focus { box-shadow: rgba(50, 50, 93, .1) 0 0 0 1px inset, rgba(50, 50, 93, .2) 0 6px 15px 0, rgba(0, 0, 0, .1) 0 2px 2px 0, rgba(50, 151, 211, .3) 0 0 0 4px; } .button-9-sect { padding-bottom: 1.25em; } /* Theme toggle switch button */ /* Switch */ .switch { position: relative; display: inline-block; width: 60px; height: 34px; align-self: center; } .switch input { opacity: 0; width: 0; height: 0; } .slider { position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0; background-color: #ccc; -webkit-transition: 0.4s; transition: 0.4s; } .slider:before { position: absolute; content: ""; height: 26px; width: 26px; left: 4px; bottom: 4px; background-color: white; -webkit-transition: 0.4s; transition: 0.4s; } input:checked+.slider { background-color: #2196f3; } input:checked+.slider:before { -webkit-transform: translateX(26px); -ms-transform: translateX(26px); transform: translateX(26px); } /* Rounded sliders */ .slider { border-radius: 30px; } .slider:before { border-radius: 50%; } </style> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prettify/r298/prettify.min.css"> <meta name="adoc-src-path" content="authoring-builds/tasks/custom_tasks.adoc"> <link crossorigin href="//assets.gradle.com" rel="preconnect"> <link href="https://fonts.googleapis.com/css?family=Inconsolata:400,700" rel="stylesheet"/> <style type="text/css">.multi-language-selector .language-option[data-lang='groovy'], .exampleblock[data-lang=groovy] > .content .title { background-image: url('data:image/svg+xml;base64,PHN2Zw0KICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIg0KICAgd2lkdGg9IjYxNC4wNjA4NSINCiAgIGhlaWdodD0iMzAzLjU5ODYiDQogICB2ZXJzaW9uPSIxLjEiPg0KICA8Zw0KICAgICB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMzUuMzk2NTk5LC0zMC41NTgxOTYpIj4NCiAgICA8cGF0aA0KICAgICAgIGQ9Im0gMTU0Ljk3Njg3LDMzMi42OTE2MiBjIDAsLTAuODA1ODcgMTAuODMxMjMsLTE4LjYyMTcyIDI0LjA2OTQsLTM5LjU5MDc2IDEzLjIzODE5LC0yMC45NjkwNSAyMi42NjA1NywtMzguNjIwNjYgMjAuOTM4NjcsLTM5LjIyNTc3IC0xLjcyMTkxLC0wLjYwNTEgLTcuNjc5OTIsMC40ODU2NyAtMTMuMjQwMDIsMi40MjM5MyAtMTYuNzQ1MjQsNS44Mzc0MyAtMjAuMTg2MDUsNC4yOTAxNiAtMzIuNjkzMDgsLTE0LjcwMTU1IC0xMy41MzI2NSwtMjAuNTQ5MDYgLTE0LjAxNzI0LC0yMi42Njk4MyAtNi45NjE1OCwtMzAuNDY2MjQgNC42MDg3NiwtNS4wOTI1NiA0LjMzMTU5LC02LjI3OTY3IC0zLjIzMTksLTEzLjg0MzE2IC00LjU1MDA5LC00LjU1MDEgLTguMjcyODksLTkuNjQzMDkgLTguMjcyODksLTExLjMxNzc2IDAsLTIuODE2NzkgLTMwLjk5MTQ1LC0xNS41ODkzMyAtNzkuOTg5NDk2LC0zMi45NjYxNSAtMTEuMTA5NjYsLTMuOTM5OTcgLTIwLjE5OTM3NSwtNy44MjkyOCAtMjAuMTk5Mzc1LC04LjY0MjkxIDAsLTAuODEzNjYgMjMuNDcwNzM4LC0xLjAwNDc2IDUyLjE1NzE5MSwtMC40MjQ2OSBsIDUyLjE1NzIxLDEuMDU0NjYgNS4wOTEyNywtOC4wMzAwMSBjIDIxLjUxNjQ0LC0zMy45MzU5MiA1NC4wMDk1MiwtNjQuNTg4MjEyIDY4LjQ2NzA1LC02NC41ODgyMTIgMy4wMTA2LDAgOS4xMjE0MSwyLjg2OTE4IDEzLjU3OTUzLDYuMzc1OTQ1IDcuMjU5NDYsNS43MTAyODMgOC4yNTY1LDkuMjQ4NjMyIDkuNTQ5OTQsMzMuODkxOTY3IDAuNzk0MywxNS4xMzM4MiAyLjQyNDIyLDI4LjQ5NjAxIDMuNjIxOTgsMjkuNjkzNzkgMS4xOTc3NSwxLjE5Nzc2IDQuOTk3NjksLTAuMzc0MjUgOC40NDQzMSwtMy40OTMzOSA0LjQwMTQsLTMuOTgzMjMgOS4wMzQ4NCwtNS4wNjMxMyAxNS41Njc2MSwtMy42MjgzIDYuNzY3NTYsMS40ODY0MSAxMC42MjcxLDAuNDY4OTUgMTQuMTY5MzgsLTMuNzM1NDMgNS4zMTM2LC02LjMwNjY2IDMxLjkwNTk2LC00OC45MzcyMDEgMzEuOTA1OTYsLTUxLjE0ODc0NCAwLC0wLjc1MTU4OCA1LjI2NTA5LC05Ljc1NzMwNiAxMS43MDAyMywtMjAuMDEyNzAzIDYuNDM1MDksLTEwLjI1NTM5NyAxMy44NDY2NCwtMjIuMDgwNjMxIDE2LjQ3MDA3LC0yNi4yNzgyODMgNC42NjU1OCwtNy40NjUyMDEgNS4zOTY2LC02LjU4MTczNSAzMy40MjY5Miw0MC4zOTg3MzYgMjguOTQxMjEsNDguNTA3MTY0IDQ0LjUxNzY3LDY2LjQwNjU1NCA1Mi4zMTU3LDYwLjExNzYzNCA1LjQ0MiwtNC4zODg4OSAzNC4wMDA1NSwtNC42Mzc5NCA0MS45ODI0NiwtMC4zNjYxNCA0LjUzNjY1LDIuNDI3OTMgNy40MTkxNiwyLjM5NjEgOS45MjQ4NCwtMC4xMDk2MiA1LjIwMDA3LC01LjIwMDA2IDE3LjY0OTgyLC00LjI5NDM3IDIwLjkwNDEyLDEuNTIwNzggMi41NjM5Myw0LjU4MTQ2IDMuMjE3ODQsNC41ODE0NiA3LjAyMDE0LDAgMi4zMDYwNiwtMi43Nzg2NyA5LjEzNjE5LC01LjA1MjA4IDE1LjE3ODAzLC01LjA1MjA4IDguNTM4ODQsMCAxMS43OTMzNiwxLjc3MzY3IDE0LjYxNDAzLDcuOTY0MzcgbCAzLjYyODgxLDcuOTY0MzYgNTYuMDkyMDMsLTEuOTg1OCBjIDMwLjg1MDYyLC0xLjA5MjIyIDU2LjA5MjA0LC0xLjI4Njg4IDU2LjA5MjA0LC0wLjQzMjU1IDAsMC44NTQyNyAtMjIuOTA2MDgsMTAuMDcxOTUgLTUwLjkwMjQxLDIwLjQ4MzcxIC0yNy45OTYzMiwxMC40MTE3MiAtNTEuMzY3LDE5LjI0MzA1IC01MS45MzQ4NCwxOS42MjUxMiAtMC41Njc4NSwwLjM4MjA3IDAuNjk4NDcsOS40OTI3MyAyLjgxNDA1LDIwLjI0NTg4IDUuNTA0NTcsMjcuOTc5MTcgMS45MTQ1OCw0Ni42MjU4OSAtMTEuOTI2MjksNjEuOTQ2MDQgLTYuMjA5LDYuODcyNjMgLTE2LjI4MzM4LDE0LjE0Mzk1IC0yMi4zODc1MywxNi4xNTg0OSAtNi4xMDQxNSwyLjAxNDU0IC0xMS4wOTg0NCw0LjM4NjE0IC0xMS4wOTg0NCw1LjI3MDE5IDAsMC44ODQwNiA2LjUxNTI1LDExLjY3ODkzIDE0LjQ3ODM1LDIzLjk4ODU5IDcuOTYzMDksMTIuMzA5NjkgMTMuMjgyOCwyMi4zODEyNSAxMS44MjE1MiwyMi4zODEyNSAtMi4zODUwNCwwIC02MC40Njk4NywtMjIuNDQyMzggLTE1MC43ODg5OCwtNTguMjYwNyAtMTcuODA5LC03LjA2MjU4IC0zNC4wMjY4MywtMTIuODQxMDkgLTM2LjAzOTYxLC0xMi44NDEwOSAtMy43NTM2MywwIC0zNi4xNjY5LDEyLjI4NjYyIC0xMzEuMjI0MjMsNDkuNzQyMDYgLTU1LjEyNTI1LDIxLjcyMTAzIC01Ny4yOTIxNywyMi40NzM0OCAtNTcuMjkyMTcsMTkuODk0NTEgeiBtIDExMy4xMTY0OCwtNTEuMjUyNjUgYyAyOS4zMjk0OSwtMTEuMzk1MDYgNTguNDE2NTcsLTIyLjUzMDggNjQuNjM3OTgsLTI0Ljc0NjA3IDEwLjcwMDY4LC0zLjgxMDE5IDE0LjI3OTE4LC0yLjg1NDkzIDY2LjI1Mzk0LDE3LjY4NjM0IDMwLjIxODI1LDExLjk0Mjc0IDYwLjAzMjUyLDIzLjU3NTg3IDY2LjI1MzkyLDI1Ljg1MTM0IDYuMjIxNDEsMi4yNzU1MiAxOS4wNDMxNyw3LjIyMDU5IDI4LjQ5Mjc1LDEwLjk4OTA4IDEwLjc3NTAzLDQuMjk3MDQgMTYuMjgyNTEsNS4zMzE2NiAxNC43NzEwOCwyLjc3NDg0IC0xNi44ODM3LC0yOC41NjExMyAtMTcuMzk5OCwtMjkuMDM3MTYgLTI5LjEwMDgzLC0yNi44NDIwNSAtMTQuMTEzNjEsMi42NDc3MiAtMjIuODc4OTcsLTAuMDY4NSAtMjcuMzgzNjksLTguNDg1NTQgLTIuOTIxMTIsLTUuNDU4MTYgLTIuMDI5NDQsLTguMTI3NTkgNS4yNTQ0MiwtMTUuNzMwMzEgMTAuODQ4ODcsLTExLjMyMzc3IDkuMTQ0NTcsLTIxLjc0MTQ0IC00Ljg0NDI5LC0yOS42MTA5OSAtNS4zNjc2NCwtMy4wMTk1OSAtMTIuMTQwNTksLTEwLjQ4MzcyIC0xNS4wNTEwMiwtMTYuNTg2OTcgbCAtNS4yOTE2OSwtMTEuMDk2ODIgLTExLjM0NTUxLDcuNjk5MjggYyAtMTMuOTQ0NTgsOS40NjMwNCAtMzAuOTUwNjIsOS45NTA2MyAtNDUuMTQ3NjQsMS4yOTQ0OCBsIC0xMC40NjQ4OCwtNi4zODA2NSAtMTIuMTU4NDEsOC4yNjI4NCBjIC0xMi4xNzQ2Miw4LjI3Mzg2IC0yNi4xOTEwOCw5LjM0MjggLTQwLjQzNzUyLDMuMDgzOTIgLTMuOTI0OTgsLTEuNzI0MzkgLTUuNjU1ODMsLTEuMDU0MTUgLTUuNjU1ODMsMi4xOTAwOCAwLDIuNTcxMTggLTMuNzA0MjksNi4zNjI2NSAtOC4yMzE4MSw4LjQyNTUzIC0xMy41NzQyLDYuMTg0NzkgLTI2LjgyMTA3LDQuNTQyNDcgLTM1LjgwMjI5LC00LjQzODc1IGwgLTguMTg5NDQsLTguMTg5NDQgLTYuNjA5ODIsOC40MDMwMyBjIC0zLjYzNTM5LDQuNjIxNjYgLTEyLjA0OTUyLDExLjgzNjk4IC0xOC42OTgwNSwxNi4wMzM5OCAtOC4yMjk2NSw1LjE5NTE4IC0xOC40MTc0MSwxNy44NzE4MiAtMzEuOTE2NCwzOS43MTM2MSAtMTAuOTA1NDksMTcuNjQ1NDYgLTE5LjgyODE2LDMyLjk4MDQyIC0xOS44MjgxNiwzNC4wNzc3NiAwLDEuMDk3MyA4LjM2MjU1LC0xLjUyNzM2IDE4LjU4MzQyLC01LjgzMjU5IDEwLjIyMDg5LC00LjMwNTIxIDQyLjU4MDI4LC0xNy4xNTA4NyA3MS45MDk3NywtMjguNTQ1OTMgeiBtIDI0OC43NjcyOSwtMTIuMjU4NDYgYyAyMi4yNTU1NywtMTIuNTA4MzMgMjcuNDE0MjQsLTM1LjY0ODA4IDE3LjU3Njg1LC03OC44NDMxOCAtOC4yMjE0LC0zNi4wOTk2MSAtMTIuMzI1NSwtNDcuOTEzMjcgLTE3LjE5NDk0LC00OS40OTU5NyAtMy4zNjkwMiwtMS4wOTUwMyAtMy44ODY3NCwwLjEwNjk5IC0xLjk4ODU4LDQuNjE2MzUgMTIuMzE1MTYsMjkuMjU3NzEgMTIuOTk5NjMsNDMuOTQ2NjIgMi4yNDAyMiw0OC4wNzU0MSAtNy4zOTE1MSwyLjgzNjQyIC0xNS4yMzIzOSwtNy43OTA3NSAtMjEuMzk5MDIsLTI5LjAwMzI2IC00Ljc3NTEyLC0xNi40MjU4NyAtOS43Njg2MSwtMjMuODI4MzcgLTEzLjUzMzg3LC0yMC4wNjMxMSAtMC45MDE1NywwLjkwMTYgMC42Nzg0OCw2LjEyMTE3IDMuNTExMjQsMTEuNTk5MTMgMi44MzI3Myw1LjQ3NzkgNi43MTcyMSwyMS45NzQ1NSA4LjYzMjE3LDM2LjY1OTIgMS45MTQ5NywxNC42ODQ2MiA1LjYxMzg1LDMwLjA2MDczIDguMjE5NzMsMzQuMTY5MTIgNi43NzE5OCwxMC42NzY2MSAxNy41NTEyOCw4LjEwMzYgMjQuNTIzODIsLTUuODUzODQgNi44OTM3MywtMTMuNzk5NzUgNy42NzI4NCwtNC42MDc4MSAwLjk2OTMsMTEuNDM2MDIgLTYuOTYwNzQsMTYuNjU5MzcgLTI3LjYzNDQyLDIxLjY1NDgxIC01MS41ODQxOCwxMi40NjQ0MiAtMy44MzMzLC0xLjQ3MDk2IC01LjEzMDM5LDAuMDUxNSAtNS4xMzAzOSw2LjAyMDk3IDAsNC4zOTQzMSAtMi45MzYxOCwxMS43MjI0NSAtNi41MjQ4OCwxNi4yODQ3IGwgLTYuNTI0ODgsOC4yOTUwNiA4Ljk0ODgxLDEuNTExMjMgYyAxNS40NDk0NSwyLjYwOTA5IDM2LjYzMzI4LC0wLjc3NjQyIDQ5LjI1ODYsLTcuODcyMjUgeiBtIC0zMjAuMzY2NSwtMjcuNTM3MzMgYyA0Ni40NTk2NSwtMTMuMzU0NSA1NC43NjE4OCwtMjguOTMwOTMgMzkuMzI4ODUsLTczLjc4NzgyIC0zLjU4MTg1LC0xMC40MTA3OSAtNi41MTI0MywtMjEuNjA5NzEgLTYuNTEyNDMsLTI0Ljg4NjU0IDAsLTExLjE1NzEyIC01LjYxMTUyLC02LjAwMTYxIC05LjgxNzEzLDkuMDE5NDMgLTUuNTYyMDMsMTkuODY1NjEgLTIyLjI5MTE1LDM2Ljc1MDUzIC0zNi4zNDUxNiwzNi42ODM2NCAtMTIuMjA1NDcsLTAuMDU4MiAtMTYuMTgyNTEsLTIuMjgwMDggLTIxLjIyMzc4LC0xMS44NTc2OCAtOS4wNDc0OCwtMTcuMTg4ODIgMC44MTQ2OSwtNDMuNTY3OTcgMjUuOTY5NTQsLTY5LjQ2MjcyIDE4LjQyNDMxLC0xOC45NjYzMDQgMjguNDg4OTMsLTIwLjY4Mzk2NSAyOC40ODg5MywtNC44NjIwNSAwLDI0LjY3MzIgLTE3LjAxMTM0LDYwLjk5NDcgLTI1Ljk3MzA5LDU1LjQ1NjA0IC00LjM4MjA1LC0yLjcwODI2IC0zLjY3MTM4LC0xNC42Njc1MiAxLjQxNzIyLC0yMy44NTAwOSA0LjMyNzM1LC03LjgwODgyIDMuNDQ4MTQsLTE5LjcwNzcxIC0xLjQ1NjIsLTE5LjcwNzcxIC01LjY4Njg5LDAgLTE2Ljk0NTQ3LDIwLjcxMTk2IC0xOC40MzMxOCwzMy45MTA3NCAtMS4zMTUxNSwxMS42NjgyNiAtMC40OTI4NiwxNC41MDU0NSA1LjA2NjUyLDE3LjQ4MDcyIDE5LjQ4MjQ0LDEwLjQyNjcgNDUuMDA1MzEsLTIxLjM5NTQ1IDQ2LjI5MDgzLC01Ny43MTU4NCAwLjY3NTA0LC0xOS4wNzMxODEgLTMuMDE2NzYsLTI0LjQ0MTEwNSAtMTQuNzc5MDYsLTIxLjQ4ODk1MSAtMTcuMTE4NzksNC4yOTY1NDMgLTYzLjIzNDgzLDYzLjc4NjY0MSAtNjMuMjM0ODMsODEuNTczNDYxIDAsMTMuOTEyOCA2Ljk4NzM3LDIzLjY5NzI4IDE5LjI4ODI3LDI3LjAwOTYgMjAuOTE0MTksNS42MzE2MiA0MS4xMzUzOSwtNC4zNzM4OSA1NS40NjMzLC0yNy40NDMzOCBsIDYuMDIxNzUsLTkuNjk1NzEgMC4wMTMyLDEzLjE3MjIzIGMgMC4wMTYyLDE5LjA3MzggLTEyLjQyNjE5LDI5LjEyNzQgLTUxLjY5ODE3LDQxLjc2NzkzIC05Ljc3NjQ5LDMuMTQ2OCAtMTguMTgzMzIsNi4wNTQ0MSAtMTguNjgxOCw2LjQ2MTM3IC0xLjgyMDU2LDEuNDg2MzIgMTYuNjg3MzksMjcuNDc1NzEgMTkuNTY2NDQsMjcuNDc1NzEgMS42MzI2MiwwIDExLjE5MTE1LC0yLjM2MzU5IDIxLjI0MTIzLC01LjI1MjM4IHogTSA0NzYuNDExLDIxNy45NjMwMSBjIDQuNjYzNDcsLTUuMTUzMSA1LjQ4NTUxLC0xMC43NTEwMyA0LjQ4NTc5LC0zMC41NDgyMyAtMS4wODczOSwtMjEuNTMzMzEgLTIuMjc3NDYsLTI1LjMzODUxIC0xMC42NjE0MywtMzQuMDg5NDkgLTE1LjE0ODgyLC0xNS44MTE5NCAtMzMuODYxMjMsLTExLjc3ODI4IC0yMi45MDgxOSw0LjkzODE0IDUuODIyNTYsOC44ODYzNyAxMi45MjU0LDcuMzY4NjQgMTAuNDE2NDEsLTIuMjI1ODEgLTEuOTk4NjQsLTcuNjQyNzYgMS43Mjk5OCwtNy44NDM1OCA4LjIyODM5LC0wLjQ0MzIyIDEyLjE5MzAxLDEzLjg4NTM3IDkuMTE1MzQsMzMuMTI2OTggLTUuMjk4NiwzMy4xMjY5OCAtOS44NjcxNiwwIC0xMi45NDE5NSwtNC4yMzE3NiAtMTkuMzczNTMsLTI2LjY2MzE4IC0yLjkzMDU5LC0xMC4yMjA4NyAtNi40OTk2NCwtMTguNTgzNDMgLTcuOTMxMjcsLTE4LjU4MzQzIC00Ljc2ODk5LDAgLTYuODkyODcsNC4yMDg3OCAtMy45MjcyMSw3Ljc4MjQgMS42MTA4OCwxLjk0MTEgNi4wNzIxOCwxNS44OTEyNyA5LjkxNDA0LDMxLjAwMDQxIDkuNjY5MDMsMzguMDI1OTYgMjMuMTc2NjYsNTEuMDQxNDUgMzcuMDU1NiwzNS43MDU0MyB6IG0gLTE4My43NzEyNSwwLjYwMzk1IGMgMS45ODk3OCwtMS4zMzUgMi44OTk3NSwtNy42NDg5MyAyLjA3ODY1LC0xNC40MjMgLTEuMzI0NDksLTEwLjkyNzAyIC0yLjA2NjYyLC0xMS43MjQxIC03Ljk3MjcsLTguNTYzMjcgLTguNDg3MzMsNC41NDIyNyAtMTcuNjA4MzksLTQuMDYzNTEgLTIwLjcwMjIyLC0xOS41MzI2IC0yLjM0NzA3LC0xMS43MzUzOCAtMy4wNjUyNiwtMTEuNTA0ODkgMTQuMDI1NzYsLTQuNTAxNDkgMi4xNDI4OCwwLjg3ODA4IDcuNTk2NzEsLTIuMTA0MDIgMTIuMTE5NjMsLTYuNjI2OTQgOC4yNzQwOCwtOC4yNzQwOCAxMC45OTgwMiwtMTguMjEyOTkgNC45OTE1NiwtMTguMjEyOTkgLTEuNzc3NTQsMCAtMy4yMzE5LDEuNDU0MzYgLTMuMjMxOSwzLjIzMTkgMCw0LjY0OTIzIC04Ljg0MjMxLDMuOTg5ODIgLTEwLjgzNDY1LC0wLjgwNzk3IC0xLjE2MjI0LC0yLjc5ODc5IC0zLjYzODA3LC0xLjgwNTkxIC04LjA1OTE1LDMuMjMxOSAtMy41MDk4NSwzLjk5OTQ4IC03Ljc5NjczLDcuMjcxNzggLTkuNTI2NDEsNy4yNzE3OCAtMS43Mjk2OSwwIC00LjA2NTYsLTMuMjcyMyAtNS4xOTA4OCwtNy4yNzE3OCAtMS45NzE5NSwtNy4wMDg1NiAtMi4yMTM2NiwtNy4wNTI3NyAtNi42NzczNywtMS4yMjE2OSAtMy45MTA2LDUuMTA4NTQgLTMuOTQ1NTcsNi43MzU4MyAtMC4yMjQ2MSwxMC40NTY2MSAzLjk0MDYyLDMuOTQwNjQgMTEuNDI2MTUsMzAuODcxMDIgMTEuNDI2MTUsNDEuMTA3NDQgMCwxMi43Mjg2NyAxNy41MjkzMywyMi43MzgzMiAyNy43NzgzLDE1Ljg2MjEgeiBtIDU4Ljk0MzA5LC0xNi44NzUzMSBjIDEyLjE0NTY3LC0xMi4xNDU2NyAxNS43NDQ1MiwtMzAuMzUxNDMgOS4xMjk0MywtNDYuMTgzNTcgLTUuMTcwMTYsLTEyLjM3Mzk3IC0xNC4xNDQ2NiwtMTcuMDA1MTYgLTI2Ljc5ODc4LC0xMy44MjkxOCAtOS40MDI2MywyLjM1OTkxIC0yMy43MjMxMSwyOS43NzY1OSAtMjMuNzczODcsNDUuNTE1MzYgLTAuMDc5MiwyNC41MjkwMiAyMy4yNTA1MywzMi42OTAwNSA0MS40NDMyMiwxNC40OTczOSB6IG0gLTIyLjA4MzQxLC0xOS40MzQwNyBjIC0zLjU1NTEsLTMuNTU1MSAtNi40MTc1NSwtMTAuNDYzMjggLTYuMzYxMDIsLTE1LjM1MTUzIDAuMDkzNCwtOC4wNzk2NSAwLjQ5MzE1LC04LjM3MzUgNC4zOTYxOSwtMy4yMzE5IDQuODI0NjQsNi4zNTU2OSAxMy4zOTc5Nyw3LjQ1NjY2IDE2LjY4MjQxLDIuMTQyMzIgMS4xOTQzMiwtMS45MzI0MSAwLjU1Mjk1LC01LjEzMjAyIC0xLjQyNTIsLTcuMTEwMTcgLTUuMDgxMzIsLTUuMDgxMzIgLTQuNDY1NjEsLTExLjk5OTYzIDEuMDY3OTIsLTExLjk5OTYzIDYuMTUxMzcsMCAxNC43MjY3OSwxMi41MTQ3NyAxNC43MjY3OSwyMS40OTE5MSAwLDYuNjA2NzQgLTEzLjQ0NDQsMjAuNTIyOCAtMTkuODI3MjQsMjAuNTIyOCAtMS41Mzc4NSwwIC01LjcwNDc2LC0yLjkwODcyIC05LjI1OTg1LC02LjQ2MzggeiBtIDg2LjM0ODk3LDE4LjU4MzQxIGMgMTMuNDEwNzQsLTE0LjYwMjYzIDEyLjEwMzc2LC0zNy4wOTggLTMuMDk4MjUsLTUzLjMyNjM0IC03Ljg1MDU3LC04LjM4MDYgLTI1LjI5Mjk4LC05LjgyNTUyIC0zMi40MzE4NSwtMi42ODY2NCAtNi41ODc2MSw2LjU4NzYxIC0xMy4xNjQ2NSwzMi40OTMwMyAtMTAuNzIxMjIsNDIuMjI4NDEgNS4yMTEyMiwyMC43NjMxOCAzMi40MDA0MSwyOC44NjY1MiA0Ni4yNTEzMiwxMy43ODQ1NyB6IG0gLTI3LjQ1NTY1LC0yMy42MTQ1MiBjIC01LjMwNjIzLC0zLjcxNjY0IC03LjEyOTQxLC04LjE0OTc0IC02Ljk3ODA2LC0xNi45Njc0NyAwLjE2OTM1LC05Ljg2MDMzIDAuNjg0MywtMTAuNzQ5ODEgMi45NjE0NSwtNS4xMTQxNSAzLjM0NTczLDguMjgwMzIgMTAuMzYyOTIsMTEuNDA3MzQgMTYuNTE4MTQsNy4zNjA5IDMuODE3NTMsLTIuNTA5NjMgMy42MzkyOSwtMy42OTU5NyAtMS4xMDEwNCwtNy4zMjkwNyAtNi4zMjE4OSwtNC44NDUyMyAtNy41NTUwOCwtMTEuNzAxOTEgLTIuMTA0NjUsLTExLjcwMTkxIDQuODczNjQsMCAyMi4zMDQwMiwxOS4wNjY2NiAyMi4zMDQwMiwyNC4zOTc3OCAwLDUuMjAzMTYgLTEyLjM3NzM5LDE0LjM4NTAzIC0xOS4zOTEzOSwxNC4zODUwMyAtMi43NjQwNSwwIC04LjI1NzksLTIuMjY0MDIgLTEyLjIwODQ3LC01LjAzMTExIHogbSAxODkuOTYyOTIsLTE0LjI4ODg3IDMzLjkzNDk1LC0xMi43MzY4MiAtMzYuMzU4ODgsLTAuMTMxMjUgYyAtMzIuNTM5MiwtMC4xMTczNiAtMzYuMzU0MjQsMC40NjMwNyAtMzYuMzE0NzUsNS41MjQ3NSAwLjA0MDEsNS4xMjc1NyAzLjMzMDczLDIwLjI4Mzk1IDQuMzcyNywyMC4xMzk2NyAwLjIzNzIyLC0wLjAzMjkgMTUuNzAxNzcsLTUuNzkxMjQgMzQuMzY1OTgsLTEyLjc5NjQ4IHogbSAtNDQzLjQ5MzQzLC0yLjI3OTMgMy40NjgyNSwtMTAuMjg3NjEgLTMwLjQ2Njg2LC0xLjAyNDA0IGMgLTE2Ljc1Njc0NCwtMC41NjMyMiAtMzAuNDYzNTg0LC0wLjEzMjEzIC0zMC40NTk1OCwwLjk1ODA0IDAuMDA1OCwxLjU5NTEzIDUyLjUwNjU3LDIyLjEwNzA3IDUzLjY2MTc0LDIwLjk2NTUyIDAuMTgwMzUsLTAuMTc4NCAxLjg4ODkyLC00Ljk1MzcyIDMuNzk2NDUsLTEwLjYxMTkxIHogbSAyMDguOTA5MiwtMzEuODg2OTUgYyA3LjE2NjY3LDEuMTQ2IDE1LjI0OTgxLDQuMDc5MjQgMTcuOTYyNTYsNi41MTgzNSA0LjIxMjc5LDMuNzg3ODMgNi4wNDUyOCwzLjUyOTY2IDEyLjU2MjA3LC0xLjc2OTg1IDQuMTk2NDMsLTMuNDEyNSA5LjY1MDI2LC02LjIwNDU3IDEyLjExOTYzLC02LjIwNDU3IDIuNDY5MzksMCA0LjQ4OTgyLC0wLjcxMzA4IDQuNDg5ODIsLTEuNTg0NjcgMCwtMy4wMDkxOCAtNDYuNTM5NTQsLTc5LjIxMjUyIC00OC4zMTQ0NywtNzkuMTA5NjEgLTIuMDg1LDAuMTIwODcyIC00OS43ODYwMyw4MC4wODc5OCAtNTEuMjU0NjQsODUuOTI0MzcgLTAuNjE2MzQsMi40NDk1MiAxLjMxODA0LDMuMzUzNzEgNS4wNzM2NCwyLjM3MTYgMy4zMzgzNiwtMC44NzMgNy45NTQxNiwwLjY4MzI2IDEwLjI1NzI3LDMuNDU4MzYgMy43MzU0LDQuNTAwODcgNS4yNjEwOCw0LjE0MjI5IDE0LjEzMDY4LC0zLjMyMDk3IDguNDI2NDcsLTcuMDkwNDEgMTEuOTMwOCwtOC4wNDg4IDIyLjk3MzQ0LC02LjI4MzAxIHoiDQogICAgICAgc3R5bGU9ImZpbGw6IzMzMzMzMztmaWxsLW9wYWNpdHk6MSIgLz4NCiAgICA8cGF0aA0KICAgICAgIHN0eWxlPSJmaWxsOiM2Mzk4YWE7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOm5vbmUiDQogICAgICAgZD0ibSAzMDkuNTQ1NzksMTQwLjg3OTIyIGMgLTAuNTAwNzUsLTAuMjMzMTEgLTEuMTE4MDQsLTAuNzY3OTkgLTIuNTI3OCwtMi4xOTAzNSAtMS45MTE4OCwtMS45Mjg5NyAtMi42NzE4OCwtMi40OTAxMyAtNC4yNjEwOCwtMy4xNDYyOCAtMi4wODc5MSwtMC44NjIwNCAtNC4zNTQ5LC0xLjA5NDIzIC02LjQ4MjMxLC0wLjY2MzkxIC0xLjg5ODA4LDAuMzgzOTMgLTIuNDI0MzUsMC40MjUyNyAtMy4yODI0MiwwLjI1NzggLTEuNDMyMjQsLTAuMjc5NTMgLTEuOTQxNTcsLTEuMTQ5MjkgLTEuNTM1ODMsLTIuNjIyNzIgMC41MDU3MywtMS44MzY1NyA0LjMzNjkzLC04Ljk0MjU1IDEyLjAwODk5LC0yMi4yNzM4NyAxNS41ODM3LC0yNy4wNzg5ODggMzYuNTM2MjQsLTYxLjIyMDk2OCAzOC44NTA1NiwtNjMuMzA2NjYyIDAuMjU2MzEsLTAuMjMwOTk0IDAuMjY1LC0wLjIzMDk5NCAwLjUyMjQ4LDAgMS4zNzc2OCwxLjIzNTk3NiA5LjQ3NjIsMTMuNzI1ODg5IDIwLjU0MDM2LDMxLjY3ODI5OCAxNC45NjY5NiwyNC4yODUwMDQgMjcuNDExMDIsNDUuNjQzNzE0IDI3LjQxMTAyLDQ3LjA0NzcwNCAwLDAuODU3MjkgLTEuMzE2MDgsMS4zNzIxNSAtNC4wODU5MSwxLjU5ODQ1IC0zLjQ0MjI2LDAuMjgxMjQgLTcuNDI0NzgsMi4zMDE4OCAtMTIuODY4ODcsNi41MjkzNiAtMi41ODcxMiwyLjAwODk4IC0zLjY5MTI2LDIuNzU5MzMgLTQuOTUwNjIsMy4zNjQzOCAtMS4wNDkyOCwwLjUwNDExIC0xLjEzNjkyLDAuNTI0MzcgLTIuMjY4NTQsMC41MjQzNyAtMS4xMTM2OCwwIC0xLjIyNjYxLC0wLjAyNDkgLTIuMDk2MjMsLTAuNDYxMjggLTAuNTEyMTMsLTAuMjU3MDIgLTEuNTA0NjksLTAuOTQ5MyAtMi4yNDE1NSwtMS41NjM0MiAtMi4xNzg0OCwtMS44MTU2MSAtNC43OTkxOCwtMy4xMzYxNCAtOS4wNzE5NywtNC41NzEyNCAtNS40Mjk5NywtMS44MjM3NiAtMTEuMjQ0NTQsLTIuOTE4NCAtMTYuMTk1NTEsLTMuMDQ4OTYgLTMuOTA5MzQsLTAuMTAzMDggLTUuNzEyMDEsMC4yNDc5OCAtOC42NzYwMiwxLjY4OTYzIC0yLjQxOTg4LDEuMTc2OTggLTMuNTg2MjEsMi4wMTMxMSAtOS4xMjQ3NSw2LjU0MTQ1IC01LjYzMzc2LDQuNjA2MTcgLTcuNjM0NDIsNS41NjIwNSAtOS42NjQsNC42MTcyNSB6IiAvPg0KICAgIDxwYXRoDQogICAgICAgc3R5bGU9ImZpbGw6IzYzOThhYTtmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZSINCiAgICAgICBkPSJtIDEyOC42Mzc4NiwxNzAuNzM5IGMgLTEwLjE1OSwtMi45NjA3IC00NS41MDMxNzEsLTE2LjkxOTYyIC01MC40NTA5MjQsLTE5LjkyNTIzIC0wLjY4MjkxNiwtMC40MTQ4NCAtMC43MzgwOTgsLTAuNDc3ODcgLTAuNTQzMjA3LC0wLjYyMDM4IDEuMTMxNTYzLC0wLjgyNzQxIDEyLjMzNzk4MywtMS4yMzkwMSAyNS4wMDQwMzEsLTAuOTE4MzYgNS4wNTEzMSwwLjEyNzg4IDM1LjUwMTMyLDEuMTMzMjMgMzUuNTUwOSwxLjE3Mzc3IDAuMDk5NywwLjA4MTUgLTYuNTIxNjQsMTkuMjg4OCAtNy4wMzA1MSwyMC4zOTQzMyAtMC4yMTI1MSwwLjQ2MTcgLTAuNjUwNjMsMC40NDM2NyAtMi41MzAyOSwtMC4xMDQxMyB6IiAvPg0KICAgIDxwYXRoDQogICAgICAgc3R5bGU9ImZpbGw6IzYzOThhYTtmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZSINCiAgICAgICBkPSJtIDU0My42OTQxMywxNzUuMzEwNTUgYyAtMS4zODYyLC0yLjcxMjg3IC0zLjg4NzY5LC0xNC45NzA2NyAtMy45NjA3OCwtMTkuNDA4NTggLTAuMDI4NCwtMS43MjQyNCAwLjE4NjY3LC0yLjQyNzQxIDAuOTYwNiwtMy4xNDA4IDEuNzczNzgsLTEuNjM1MDEgNS4zNzkzOCwtMi4yMjMyIDE1LjI5MDE3LC0yLjQ5NDM0IDUuMDAzNDcsLTAuMTM2ODkgMjguMTAxOSwtMC4xNTc5NiA0NC40MTEyNywtMC4wNDA1IGwgMTEuNDI4NTksMC4wODIzIC0yNy41MTc3LDEwLjMxNDI3IGMgLTI1LjA5MjkyLDkuNDA1NCAtMzkuNjg0NzMsMTQuODQxMjYgLTQwLjIyNDkxLDE0Ljk4NDkgLTAuMTM1MTcsMC4wMzYgLTAuMjY5ODEsLTAuMDY3NCAtMC4zODcyNCwtMC4yOTcyMyBsIDAsMCB6IiAvPg0KICAgIDxwYXRoDQogICAgICAgc3R5bGU9ImZpbGw6IzYzOThhYTtmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZSINCiAgICAgICBkPSJtIDE3OC4wODgzNSwzMTUuNTE0MzMgYyAwLC0wLjc3MDc4IDMuMjY4OSwtNi41MzMxIDExLjU1Mzk1LC0yMC4zNjY5OCAxOS44NTExOCwtMzMuMTQ2MzEgMjguOTI3MTUsLTQ1LjE2MDEyIDQwLjA3MjkyLC01My4wNDQyOSA5Ljk3MTI3LC03LjA1MzM3IDE1LjMwMjc5LC0xMS45Mjk0IDIxLjI0NTM5LC0xOS40MzAzMyBsIDMuNjY0MDksLTQuNjI0OTIgNC45Mzk5LDQuODU2NTIgYyA4LjY0Nzg0LDguNTAxODkgMTMuODYxMywxMC45NjY2OCAyMy4yOTcxNywxMS4wMTQzMiAxMS41NDA1OCwwLjA1ODMgMjQuMTc4NDksLTYuMzg4MSAyNC4xNzg0OSwtMTIuMzMyOTkgMCwtMS4zMzk4IDAuOTU0MDQsLTIuNzIyMzYgMS44Nzg1NywtMi43MjIzNiAwLjM5MTMyLDAgMi42MTY4NiwwLjY4MzY1IDQuOTQ1NjUsMS41MTkyMyA2LjA2OTkyLDIuMTc3OSA5LjYzMDI4LDIuOTY1NDggMTQuNjA5MTIsMy4yMzE2NSA0LjkzOTk4LDAuMjY0MDkgOC41NDg0OCwtMC4xNzA0IDEzLjM1ODE3LC0xLjYwODQxIDQuNzI1NjEsLTEuNDEyODggNy40NDcwOSwtMi44NTkwNSAxNS41OTgzMywtOC4yODg4MiA0LjEwNzYsLTIuNzM2MTggNy41OTk1NCwtNC45NzQ4NyA3Ljc1OTg4LC00Ljk3NDg3IDAuMTYwMzMsMCAzLjEyNTM0LDEuNzE4OTYgNi41ODg5LDMuODE5OTEgMy40NjM1NiwyLjEwMDk1IDcuNjI1NDIsNC4zODEzMyA5LjI0ODU5LDUuMDY3NTEgMTEuMDY4NjIsNC42NzkxOCAyMy4wMjQ0NSw0LjM3MzkgMzMuOTcxMjYsLTAuODY3NDEgMS45NTc5NSwtMC45Mzc0NyA2LjU2NzkzLC0zLjczMDc0IDEwLjI0NDQsLTYuMjA3MjcgMy42NzY0OCwtMi40NzY1MyA2LjczNjEzLC00LjQ0NTc2IDYuNzk5MjMsLTQuMzc2MDYgMC4wNjMxLDAuMDY5NyAxLjQ1NjA1LDIuOTIwOCAzLjA5NTQ0LDYuMzM1NzggMS42Mzk0LDMuNDE0OTggMy42OTg5NSw3LjI2NjcgNC41NzY3OSw4LjU1OTM3IDMuODAwMDEsNS41OTU3OCA4LjE3NTg4LDkuNzUxNDEgMTQuMDgzNDMsMTMuMzc0NjQgNi4wODEyMiwzLjcyOTc1IDkuODMyMDYsOC42ODY4IDEwLjIxODgyLDEzLjUwNTA3IDAuMzgzNjcsNC43Nzk2OCAtMS43MDMyOSw5LjAxOTM5IC03LjcyMTg5LDE1LjY4NzIxIC00LjY5NzQ3LDUuMjA0MTkgLTUuODczMyw3LjIzNTQgLTUuODYxMTMsMTAuMTI0OTEgMC4wMTIyLDIuODkyNjIgMS43MDEwMyw2LjIyODU0IDQuNjY5NjQsOS4yMjM3OSA0LjgwNTMzLDQuODQ4NDQgMTIuMzQ2MDUsNi4yODc3NyAyMy40MzUzNCw0LjQ3MzE5IDIuNDc0MDgsLTAuNDA0ODQgNS41OTQ3OSwtMC43Mzc1NyA2LjkzNDkxLC0wLjczOTM4IDQuMjg1NTEsLTAuMDA2IDYuOTAzMTksMi4wOTU5NSAxMS44OTI1MSw5LjU0ODU5IDMuNDQzNTEsNS4xNDM2NSAxMC45NzM5NiwxNy43NTUwOCAxMC45NzM5NiwxOC4zNzgzNiAwLDAuMzI0MDcgLTAuMzUxNDUsMC41NTIwOCAtMC44NTA5NywwLjU1MjA4IC0xLjA1MTA5LDAgLTUuNjIzMTQsLTEuMjQzOCAtOC45MzIxNCwtMi40Mjk5NCAtNC4zNDg1LC0xLjU1ODc1IC01Ny4yNzIzOCwtMjIuMDA1MjYgLTc0Ljc0Nzg2LC0yOC44Nzc5NSAtNDYuNjYzNSwtMTguMzUxNjIgLTYyLjAyODA1LC0yNC4yMTI0NiAtNjkuNTM2NTcsLTI2LjUyNDg5IC04LjExNDE3LC0yLjQ5ODk1IC0xMy42NDAyOSwtMy4wODUyMiAtMTguMTI2NjEsLTEuOTIzMDYgLTUuNTc5OTYsMS40NDU0NiAtODEuNzIwNjcsMzAuODY4ODggLTEyNi4xMzI0NSw0OC43NDE5NSAtMjEuOTMxMTksOC44MjYgLTI0LjY3NzQ5LDkuODc1NzcgLTI4Ljc4MTE2LDExLjAwMTU5IC0zLjI2MzAzLDAuODk1MjEgLTMuMTQ0MDcsMC44ODI5NCAtMy4xNDQwNywwLjMyNDI2IHoiIC8+DQogIDwvZz4NCjwvc3ZnPg=='); background-position: 16px 80%; background-repeat: no-repeat; background-size: 20px 12px; padding-left: 2.5em; } .multi-language-selector .language-option[data-lang='kotlin'], .exampleblock[data-lang=kotlin] > .content .title { background-image: url("data:image/svg+xml;utf8,<svg viewBox='0 0 8 8' xmlns='http://www.w3.org/2000/svg'><linearGradient id='g' gradientUnits='userSpaceOnUse' x1='8' y1='0' x2='0' y2='8'><stop offset='0' stop-color='%23e44857'/><stop offset='.4689' stop-color='%23c711e1'/><stop offset='1' stop-color='%237f52ff'/></linearGradient><polygon fill='url(%23g)' points='8 8 0 8 0 0 8 0 4 4'/></svg>"); background-position: 17px 80%; background-repeat: no-repeat; background-size: 11px 11px; padding-left: 2.3em; } .multi-language-selector { display: block; } .multi-language-selector .language-option[data-lang='groovy'] { background-position: 20px center; padding-left: 32px; } .multi-language-selector .language-option[data-lang='kotlin'] { background-position: 30px center; padding-left: 27px; } .multi-language-selector .language-option { background-color: white; border: 1px solid #f7f7f8; border-radius: 4px 4px 0 0; cursor: pointer; display: inline-block; font-weight: normal; font-family: 'Lato', Arial, sans-serif; margin: 0; padding: 4px 20px; min-width: 130px; max-width: 320px; text-align: center; filter: grayscale(1); -webkit-filter: grayscale(1); opacity: 0.7; } .multi-language-selector .language-option.selected { background-color: #f7f7f8; color: #02303a; filter: none; -webkit-filter: none; opacity: 1; } .multi-language-text.hidden, .multi-language-selector ~ .multi-language-sample.hidden { display: none; } .multi-language-sample { border-radius: 0 0 4px 4px; } body.dark-theme { .multi-language-selector .language-option { background-color: #1f1f1f; border: 1px solid #1e1e22; } .multi-language-selector .language-option.selected { background-color: #2c2c2c; color: white; } } @media (prefers-color-scheme: dark) { .multi-language-selector .language-option { background-color: #1f1f1f; border: 1px solid #1e1e22; } .multi-language-selector .language-option.selected { background-color: #2c2c2c; color: white; } body.light-theme { .multi-language-selector .language-option { background-color: #white; border: 1px solid #f7f7f8; } .multi-language-selector .language-option.selected { background-color: #f7f7f8; color: #02303a; } } } </style><script type="text/javascript">function postProcessCodeBlocks() { // Assumptions: // 1) All siblings that are marked with class="multi-language-sample" should be grouped // 2) Only one language can be selected per domain (to allow selection to persist across all docs pages) // 3) There is exactly 1 small set of languages to choose from. This does not allow for multiple language preferences. For example, users cannot prefer both Kotlin and ZSH. // 4) Only 1 sample of each language can exist in the same collection. var GRADLE_DSLs = ["kotlin", "groovy"]; var preferredBuildScriptLanguage = initPreferredBuildScriptLanguage(); // Ensure preferred DSL is valid, defaulting to Kotlin DSL function initPreferredBuildScriptLanguage() { var lang = window.localStorage.getItem("preferred-gradle-dsl"); if (GRADLE_DSLs.indexOf(lang) === -1) { window.localStorage.setItem("preferred-gradle-dsl", "kotlin"); lang = "kotlin"; } return lang; } function capitalizeFirstLetter(string) { return string.charAt(0).toUpperCase() + string.slice(1); } function processSampleEl(sampleEl, prefLangId) { var codeEl = sampleEl.querySelector("code[data-lang]"); if (codeEl != null) { sampleEl.setAttribute("data-lang", codeEl.getAttribute("data-lang")); if (codeEl.getAttribute("data-lang") !== prefLangId) { sampleEl.classList.add("hidden"); } else { sampleEl.classList.remove("hidden"); } } } function switchSampleLanguage(languageId) { var multiLanguageSampleElements = [].slice.call( document.querySelectorAll(".multi-language-sample") ); // Array of Arrays, each top-level array representing a single collection of samples var multiLanguageSets = []; for (var i = 0; i < multiLanguageSampleElements.length; i++) { var currentCollection = [multiLanguageSampleElements[i]]; var currentSampleElement = multiLanguageSampleElements[i]; processSampleEl(currentSampleElement, languageId); while ( currentSampleElement.nextElementSibling != null && currentSampleElement.nextElementSibling.classList.contains( "multi-language-sample" ) ) { currentCollection.push(currentSampleElement.nextElementSibling); currentSampleElement = currentSampleElement.nextElementSibling; processSampleEl(currentSampleElement, languageId); i++; } multiLanguageSets.push(currentCollection); } multiLanguageSets.forEach(function (sampleCollection) { // Create selector element if not existing if ( sampleCollection.length > 1 && (sampleCollection[0].previousElementSibling == null || !sampleCollection[0].previousElementSibling.classList.contains( "multi-language-selector" )) ) { var languageSelectorFragment = document.createDocumentFragment(); var multiLanguageSelectorElement = document.createElement("div"); multiLanguageSelectorElement.classList.add("multi-language-selector"); languageSelectorFragment.appendChild(multiLanguageSelectorElement); sampleCollection.forEach(function (sampleEl) { var optionEl = document.createElement("code"); var sampleLanguage = sampleEl.getAttribute("data-lang"); optionEl.setAttribute("data-lang", sampleLanguage); optionEl.setAttribute("role", "button"); optionEl.classList.add("language-option"); optionEl.innerText = capitalizeFirstLetter(sampleLanguage); optionEl.addEventListener( "click", function updatePreferredLanguage(evt) { var preferredLanguageId = optionEl.getAttribute("data-lang"); window.localStorage.setItem( "preferred-gradle-dsl", preferredLanguageId ); // Record how far down the page the clicked element is before switching all samples var beforeOffset = evt.target.offsetTop; switchSampleLanguage(preferredLanguageId); // Scroll the window to account for content height differences between different sample languages window.scrollBy(0, evt.target.offsetTop - beforeOffset); } ); multiLanguageSelectorElement.appendChild(optionEl); }); sampleCollection[0].parentNode.insertBefore( languageSelectorFragment, sampleCollection[0] ); } }); [].slice .call( document.querySelectorAll(".multi-language-selector .language-option") ) .forEach(function (optionEl) { if (optionEl.getAttribute("data-lang") === languageId) { optionEl.classList.add("selected"); } else { optionEl.classList.remove("selected"); } }); [].slice .call(document.querySelectorAll(".multi-language-text")) .forEach(function (el) { if (!el.classList.contains("lang-" + languageId)) { el.classList.add("hidden"); } else { el.classList.remove("hidden"); } }); } switchSampleLanguage(preferredBuildScriptLanguage); } document.addEventListener("DOMContentLoaded", function () { postProcessCodeBlocks(); }); </script> <!-- Prefetch header and footer if on Gradle 4.4 and lower only --> <!-- Load build-tool.css if on Gradle<=4.4 or release notes --> <!-- Load build-tool.css if on Gradle<8.0 and javadoc --> <!-- Load build-tool-modern.css if on Gradle>=8.0 and javadoc --> <!-- Load decorate.css if on Gradle<=4.3 for user manual, Gradle<=4.4 for DSL Reference, or Gradle<=4.5 for Javadoc --> <style type="text/css"> cloudflare-app[app="cookiless"] cookiless-div { font-family: "Lato","Helvetica Neue",Arial,sans-serif; font-weight: 300; background-color: #02303A !important; opacity: 1 !important; } cloudflare-app[app="cookiless"] cookiless-div .iAccept { font-weight: 400; } @media (max-width: 1023px) { .notification { display: none; } } @media (min-width: 1024px) { cloudflare-app[app="cookiless"] { position: fixed !important; width: 400px !important; left: auto !important; right: 0 !important; bottom: 0 !important; } /* Overrides for banner */ .notification { height: 44px; line-height: 44px; vertical-align: middle; background-color: #02303A; text-align: center; color: white; z-index: 1; } .notification a { color: white; text-decoration: underline; } .notification ~ .main-content #header #toc, .notification ~ .main-content .toc { top: 98px; } } </style> <!-- Load common JS for all Gradle versions --> <script src="/build-tool.js" type="text/javascript" defer></script> <!-- Google Tag Manager --> <script> (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); })(window,document,'script','dataLayer','GTM-WRTQKGT'); </script> <!-- End Google Tag Manager --> <!-- Inject new header and footer for Gradle<=4.4 or release notes--> <script type="text/javascript" defer> window.siteDecorateVersion = "8.11.1"; </script> <!-- Load DocSearch assets if on current manual, dsl, or samples --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@algolia/autocomplete-theme-classic"> <script src="https://cdn.jsdelivr.net/npm/algoliasearch@4.23.3/dist/algoliasearch-lite.umd.js"></script> <script src="https://cdn.jsdelivr.net/npm/instantsearch.js@4.69.0/dist/instantsearch.production.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/@algolia/autocomplete-js"></script> <script src="/build-tool-search.js" type="text/javascript" defer></script> <link rel="stylesheet" href="/build-tool-search.css"> <!--Load ratings css and js if on current user manual --> <link rel="stylesheet" href="/build-tool-rating.css"> <script src="/build-tool-rating.js" type="text/javascript" defer></script> <!--Load banner css, html and js if on current user manual --> <link rel="stylesheet" href="/build-tool-banner.css"> <script src="/build-tool-banner.js" type="text/javascript" defer></script> <!-- Canonical Link and Structured Data for SEO --> <link rel="canonical" href="https://docs.gradle.org/current/userguide/custom_tasks.html" /> <script type="application/ld+json"> { "@context": "http://schema.org", "@type": "WebPage", "name": "Gradle Documentation", "url": "https://docs.gradle.org/current/userguide/custom_tasks.html" } </script> <meta name="google-site-verification" content="kCnBfMu0lbnMpfg3t1-ZgJHbSOSYRSquWsxQ4HgqLkA" /></head> <body id="custom_tasks" class="book"><!-- Google Tag Manager (noscript) --> <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-WRTQKGT" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript> <!-- End Google Tag Manager (noscript) --> <div class="layout"> <header class="site-layout__header site-header" itemscope="itemscope" itemtype="https://schema.org/WPHeader"> <nav class="site-header__navigation" itemscope="itemscope" itemtype="https://schema.org/SiteNavigationElement"> <div class="site-header__navigation-header"> <a target="_top" class="logo" href="https://docs.gradle.org" title="Gradle Docs"> <svg width="139px" height="43px" viewBox="0 0 278 86" version="1.1" xmlns="http://www.w3.org/2000/svg"> <title>Gradle</title> <path class="cls-1" d="M155,56.32V70.27a18.32,18.32,0,0,1-5.59,2.83,21.82,21.82,0,0,1-6.36.89,21.08,21.08,0,0,1-7.64-1.31A17.12,17.12,0,0,1,129.59,69a16.14,16.14,0,0,1-3.73-5.58,18.78,18.78,0,0,1-1.31-7.08,19.58,19.58,0,0,1,1.26-7.14A15.68,15.68,0,0,1,135,40a20.39,20.39,0,0,1,7.45-1.29,22,22,0,0,1,3.92.33,20.43,20.43,0,0,1,3.39.92,15.16,15.16,0,0,1,2.85,1.42A17.3,17.3,0,0,1,155,43.25l-1.84,2.91a1.72,1.72,0,0,1-1.12.84,2,2,0,0,1-1.5-.34L149,45.75a10.49,10.49,0,0,0-1.75-.79,14.33,14.33,0,0,0-2.17-.54,15.29,15.29,0,0,0-2.78-.22,11.91,11.91,0,0,0-4.61.86,9.66,9.66,0,0,0-3.52,2.46,10.9,10.9,0,0,0-2.24,3.84,14.88,14.88,0,0,0-.79,5,15.23,15.23,0,0,0,.85,5.28,11.06,11.06,0,0,0,2.38,3.94A10.15,10.15,0,0,0,138.05,68a14.28,14.28,0,0,0,8.25.44,17.1,17.1,0,0,0,2.94-1.09V61.14h-4.35a1.3,1.3,0,0,1-1-.35,1.15,1.15,0,0,1-.35-.85V56.32Zm10.47-2.93a10.53,10.53,0,0,1,2.72-3.45,5.77,5.77,0,0,1,3.72-1.25,4.5,4.5,0,0,1,2.72.74l-.38,4.41a1.18,1.18,0,0,1-.34.61,1,1,0,0,1-.61.18,6.76,6.76,0,0,1-1.06-.12,8.22,8.22,0,0,0-1.38-.12,5,5,0,0,0-1.74.28,4.37,4.37,0,0,0-1.37.83,5.55,5.55,0,0,0-1.07,1.3,12.26,12.26,0,0,0-.87,1.74V73.61H160V49.14h3.45a1.94,1.94,0,0,1,1.27.32,1.9,1.9,0,0,1,.48,1.16Zm11.36-.84A14.49,14.49,0,0,1,187,48.69a9.92,9.92,0,0,1,3.84.7,8.06,8.06,0,0,1,2.86,2,8.38,8.38,0,0,1,1.78,3,11.64,11.64,0,0,1,.61,3.82V73.61h-2.68a2.64,2.64,0,0,1-1.28-.25,1.72,1.72,0,0,1-.72-1l-.52-1.77a20.25,20.25,0,0,1-1.82,1.47,10.86,10.86,0,0,1-1.83,1.06,10.36,10.36,0,0,1-2,.66,12,12,0,0,1-2.4.22,9.64,9.64,0,0,1-2.86-.41,6.28,6.28,0,0,1-2.27-1.26,5.6,5.6,0,0,1-1.48-2.07,7.38,7.38,0,0,1-.52-2.89,5.7,5.7,0,0,1,.31-1.85,5.3,5.3,0,0,1,1-1.75,8.25,8.25,0,0,1,1.83-1.57,11.17,11.17,0,0,1,2.75-1.29,23.28,23.28,0,0,1,3.81-.9,36.77,36.77,0,0,1,5-.41V58.16a5.35,5.35,0,0,0-1.05-3.64,3.83,3.83,0,0,0-3-1.18,7.3,7.3,0,0,0-2.38.33,9.39,9.39,0,0,0-1.65.75l-1.3.75a2.52,2.52,0,0,1-1.3.34,1.7,1.7,0,0,1-1.05-.32,2.61,2.61,0,0,1-.69-.76Zm13.5,10.61a31.66,31.66,0,0,0-4.3.45,11,11,0,0,0-2.79.82,3.57,3.57,0,0,0-1.5,1.17,2.89,2.89,0,0,0,.47,3.67,3.93,3.93,0,0,0,2.39.67,7,7,0,0,0,3.14-.66,9.52,9.52,0,0,0,2.59-2Zm32.53-25V73.61h-3.6a1.39,1.39,0,0,1-1.48-1.07l-.5-2.36a12.4,12.4,0,0,1-3.4,2.74,9.17,9.17,0,0,1-4.47,1,7.95,7.95,0,0,1-6.55-3.26A11.61,11.61,0,0,1,201,66.79a19.71,19.71,0,0,1-.66-5.34,16.77,16.77,0,0,1,.74-5.06,12.21,12.21,0,0,1,2.13-4,9.88,9.88,0,0,1,3.31-2.69,9.64,9.64,0,0,1,4.34-1,8.63,8.63,0,0,1,3.51.64,9,9,0,0,1,2.6,1.74V38.17ZM217,55.39a5.94,5.94,0,0,0-2.18-1.72,6.54,6.54,0,0,0-2.54-.5,5.68,5.68,0,0,0-2.41.5A4.87,4.87,0,0,0,208,55.19a7.19,7.19,0,0,0-1.17,2.57,14.83,14.83,0,0,0-.4,3.69,16.34,16.34,0,0,0,.34,3.63,7.14,7.14,0,0,0,1,2.44,3.79,3.79,0,0,0,1.58,1.36,5,5,0,0,0,2.07.41,6,6,0,0,0,3.13-.76A9.19,9.19,0,0,0,217,66.36Zm17.67-17.22V73.61h-5.89V38.17ZM245.1,62.11a11.37,11.37,0,0,0,.67,3.26,6.54,6.54,0,0,0,1.38,2.27,5.39,5.39,0,0,0,2,1.33,7.26,7.26,0,0,0,2.61.44,8.21,8.21,0,0,0,2.47-.33,11.51,11.51,0,0,0,1.81-.74c.52-.27,1-.52,1.36-.74a2.31,2.31,0,0,1,1.13-.33,1.21,1.21,0,0,1,1.1.55L261.36,70a9.45,9.45,0,0,1-2.19,1.92,12.18,12.18,0,0,1-2.54,1.24,14,14,0,0,1-2.7.66,18.78,18.78,0,0,1-2.65.19,12.93,12.93,0,0,1-4.75-.85,10.65,10.65,0,0,1-3.82-2.5,11.8,11.8,0,0,1-2.55-4.1,15.9,15.9,0,0,1-.93-5.67,13.55,13.55,0,0,1,.81-4.71,11.34,11.34,0,0,1,2.33-3.84,11,11,0,0,1,3.69-2.59,12.31,12.31,0,0,1,4.93-1,11.86,11.86,0,0,1,4.27.74,9.25,9.25,0,0,1,3.36,2.16,9.84,9.84,0,0,1,2.21,3.48,13,13,0,0,1,.8,4.71,3.82,3.82,0,0,1-.29,1.8,1.19,1.19,0,0,1-1.1.46Zm11.23-3.55A7.28,7.28,0,0,0,256,56.4a5.16,5.16,0,0,0-1-1.77,4.44,4.44,0,0,0-1.63-1.21,5.68,5.68,0,0,0-2.3-.44,5.46,5.46,0,0,0-4,1.45,7.13,7.13,0,0,0-1.87,4.13ZM112.26,14a13.72,13.72,0,0,0-19.08-.32,1.27,1.27,0,0,0-.41.93,1.31,1.31,0,0,0,.38.95l1.73,1.73a1.31,1.31,0,0,0,1.71.12,7.78,7.78,0,0,1,4.71-1.57,7.87,7.87,0,0,1,5.57,13.43C96,40.2,81.41,9.66,48.4,25.37a4.48,4.48,0,0,0-2,6.29l5.66,9.79a4.49,4.49,0,0,0,6.07,1.67l.14-.08-.11.08,2.51-1.41a57.72,57.72,0,0,0,7.91-5.89,1.37,1.37,0,0,1,1.8-.06h0a1.29,1.29,0,0,1,0,2A59.79,59.79,0,0,1,62.11,44l-.09.05-2.51,1.4a7,7,0,0,1-3.47.91,7.19,7.19,0,0,1-6.23-3.57l-5.36-9.24C34.17,40.81,27.93,54.8,31.28,72.5a1.31,1.31,0,0,0,1.29,1.06h6.09A1.3,1.3,0,0,0,40,72.42a8.94,8.94,0,0,1,17.73,0A1.3,1.3,0,0,0,59,73.56h5.94a1.31,1.31,0,0,0,1.3-1.14,8.93,8.93,0,0,1,17.72,0,1.3,1.3,0,0,0,1.29,1.14h5.87a1.3,1.3,0,0,0,1.3-1.28c.14-8.28,2.37-17.79,8.74-22.55C123.15,33.25,117.36,19.12,112.26,14ZM89.79,38.92l-4.2-2.11h0a2.64,2.64,0,1,1,4.2,2.12Z"/> </svg> </a> <div class="site-header__doc-type sr-only">User Manual</div> <div class="site-header-version"></div> <button type="button" aria-label="Navigation Menu" class="site-header__navigation-button hamburger"> <span class="hamburger__bar"></span> <span class="hamburger__bar"></span> <span class="hamburger__bar"></span> </button> </div> <div class="site-header__navigation-collapsible site-header__navigation-collapsible--collapse"> <ul class="site-header__navigation-items"> <li id="theme-toggle" class="site-header__navigation-item"> <a class="site-header__navigation-link theme-toggle" title="Theme"> <svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> <title>Theme</title> <path d="m12 22c5.5228475 0 10-4.4771525 10-10s-4.4771525-10-10-10-10 4.4771525-10 10 4.4771525 10 10 10zm0-1.5v-17c4.6944204 0 8.5 3.80557963 8.5 8.5 0 4.6944204-3.8055796 8.5-8.5 8.5z"/> </svg> </a> <script type="text/javascript"> const btn = document.querySelector(".theme-toggle"); const prefersDarkScheme = window.matchMedia("(prefers-color-scheme: dark)"); const currentTheme = localStorage.getItem("theme"); if (currentTheme == "dark") { document.body.classList.toggle("dark-theme"); } else if (currentTheme == "light") { document.body.classList.toggle("light-theme"); } btn.addEventListener("click", function () { if (prefersDarkScheme.matches) { document.body.classList.toggle("light-theme"); var theme = document.body.classList.contains("light-theme")? "light" : "dark"; } else { document.body.classList.toggle("dark-theme"); var theme = document.body.classList.contains("dark-theme")? "dark" : "light"; } localStorage.setItem("theme", theme); }); </script> </li> <li class="site-header__navigation-item site-header__navigation-submenu-section" tabindex="0"> <span class="site-header__navigation-link"> Community </span> <div class="site-header__navigation-submenu"> <div class="site-header__navigation-submenu-item" itemprop="name"> <a target="_top" class="site-header__navigation-submenu-item-link" href="https://gradle.org/" itemprop="url"> <span class="site-header__navigation-submenu-item-link-text">Community Home</span> </a> </div> <div class="site-header__navigation-submenu-item" itemprop="name"> <a target="_top" class="site-header__navigation-submenu-item-link" href="https://discuss.gradle.org/" itemprop="url"> <span class="site-header__navigation-submenu-item-link-text">Community Forums</span> </a> </div> <div class="site-header__navigation-submenu-item" itemprop="name"> <a target="_top" class="site-header__navigation-submenu-item-link" href="https://plugins.gradle.org" itemprop="url"> <span class="site-header__navigation-submenu-item-link-text">Community Plugins</span> </a> </div> </div> </li> <li class="site-header__navigation-item" itemprop="name"> <a target="_top" class="site-header__navigation-link" href="https://dpeuniversity.gradle.com/" itemprop="url">DPE University</a> </li> <li class="site-header__navigation-item" itemprop="name"> <a target="_top" class="site-header__navigation-link" href="https://gradle.org/training/" itemprop="url">Events</a> </li> <li class="site-header__navigation-item site-header__navigation-submenu-section" tabindex="0"> <span class="site-header__navigation-link"> News </span> <div class="site-header__navigation-submenu"> <div class="site-header__navigation-submenu-item" itemprop="name"> <a class="site-header__navigation-submenu-item-link" href="https://newsletter.gradle.org" itemprop="url"> <span class="site-header__navigation-submenu-item-link-text">Newsletter</span> </a> </div> <div class="site-header__navigation-submenu-item" itemprop="name"> <a class="site-header__navigation-submenu-item-link" href="https://blog.gradle.org" itemprop="url"> <span class="site-header__navigation-submenu-item-link-text">Blog</span> </a> </div> <div class="site-header__navigation-submenu-item"> <a class="site-header__navigation-submenu-item-link" href="https://twitter.com/gradle"> <span class="site-header__navigation-submenu-item-link-text">Twitter</span> </a> </div> </div> </li> <li class="site-header__navigation-item" itemprop="name"> <a target="_top" class="site-header__navigation-link" href="https://gradle.com/develocity" itemprop="url">Develocity</a> </li> <li class="site-header__navigation-item"> <a class="site-header__navigation-link" title="Gradle on GitHub" href="https://github.com/gradle/gradle"> <svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"> <title>Github</title> <path d="M10 0C4.477 0 0 4.477 0 10c0 4.418 2.865 8.166 6.839 9.489.5.092.682-.217.682-.482 0-.237-.008-.866-.013-1.7-2.782.603-3.369-1.342-3.369-1.342-.454-1.155-1.11-1.462-1.11-1.462-.908-.62.069-.608.069-.608 1.003.07 1.531 1.03 1.531 1.03.892 1.529 2.341 1.087 2.91.831.092-.646.35-1.086.636-1.336-2.22-.253-4.555-1.11-4.555-4.943 0-1.091.39-1.984 1.029-2.683-.103-.253-.446-1.27.098-2.647 0 0 .84-.268 2.75 1.026A9.578 9.578 0 0 1 10 4.836c.85.004 1.705.114 2.504.337 1.909-1.294 2.747-1.026 2.747-1.026.546 1.377.203 2.394.1 2.647.64.699 1.028 1.592 1.028 2.683 0 3.842-2.339 4.687-4.566 4.935.359.309.678.919.678 1.852 0 1.336-.012 2.415-.012 2.743 0 .267.18.579.688.481C17.137 18.163 20 14.418 20 10c0-5.523-4.478-10-10-10" fill-rule="evenodd";/> </svg> </a> </li> </ul> </div> </nav> </header> <main class="main-content"> <!-- Primary Navigation --> <nav class="docs-navigation"> <div class="search-container"></div> <h3 id="overview">Overview</h3> <ul> <li><a href="../userguide/userguide.html">What is Gradle?</a></li> <li><a href="../userguide/quick_start.html">Quick Start</a></li> </ul> <h3 id="what-is-new">Releases</h3> <ul> <li><a href="https://gradle.org/releases/">All Releases</a></li> <li><a href="../release-notes.html">Release Notes</a></li> <li><a href="../userguide/installation.html">Installing Gradle</a></li> <li><a class="nav-dropdown" data-toggle="collapse" href="#upgrading-gradle" aria-expanded="false" aria-controls="upgrading-gradle">Upgrading Gradle</a> <ul id="upgrading-gradle"> <li><a href="../userguide/upgrading_version_8.html">version 8.X to latest</a></li> <li><a href="../userguide/upgrading_version_7.html">version 7.X to 8.0</a></li> <li><a href="../userguide/upgrading_version_6.html">version 6.X to 7.0</a></li> <li><a href="../userguide/upgrading_version_5.html">version 5.X to 6.0</a></li> <li><a href="../userguide/upgrading_version_4.html">version 4.X to 5.0</a></li> </ul> </li> <li><a class="nav-dropdown" data-toggle="collapse" href="#migrating-to-gradle" aria-expanded="false" aria-controls="migrating-to-gradle">Migrating to Gradle</a> <ul id="migrating-to-gradle"> <li><a href="../userguide/migrating_from_maven.html">from Maven</a></li> <li><a href="../userguide/migrating_from_ant.html">from Ant</a></li> </ul> </li> <li><a href="../userguide/troubleshooting.html">Troubleshooting</a></li> <li><a href="../userguide/compatibility.html">Compatibility Notes</a></li> <li><a href="../userguide/feature_lifecycle.html">Gradle's Feature Lifecycle</a></li> </ul> <h3 id="running-gradle-builds">Running Gradle Builds</h3> <ul> <li><a href="../userguide/getting_started_eng.html">Getting Started</a></li> <li><a class="nav-dropdown" data-toggle="collapse" href="#running-introduction" aria-expanded="false" aria-controls="introduction">Core Concepts</a> <ul id="running-introduction"> <li><a href="../userguide/gradle_basics.html">1. Gradle Basics</a></li> <li><a href="../userguide/gradle_wrapper_basics.html">2. Gradle Wrapper Basics</a></li> <li><a href="../userguide/command_line_interface_basics.html">3. Command-Line Interface Basics</a></li> <li><a href="../userguide/settings_file_basics.html">4. Settings File Basics</a></li> <li><a href="../userguide/build_file_basics.html">5. Build File Basics</a></li> <li><a href="../userguide/dependency_management_basics.html">6. Dependency Management Basics</a></li> <li><a href="../userguide/task_basics.html">7. Task Basics</a></li> <li><a href="../userguide/plugin_basics.html">8. Plugins Basics</a></li> <li><a href="../userguide/gradle_optimizations.html">9. Incremental Builds + Caching</a></li> <li><a href="../userguide/build_scans.html">10. Build Scans</a></li> </ul> </li> <li><a class="nav-dropdown" data-toggle="collapse" aria-expanded="false">Tutorial</a> <ul id="running-tutorial"> <li><a href="../userguide/part1_gradle_init.html">1. Initializing the Project</a></li> <li><a href="../userguide/part2_gradle_tasks.html">2. Running Tasks</a></li> <li><a href="../userguide/part3_gradle_dep_man.html">3. Understanding Dependencies</a></li> <li><a href="../userguide/part4_gradle_plugins.html">4. Applying Plugins</a></li> <li><a href="../userguide/part5_gradle_inc_builds.html">5. Exploring Incremental Builds</a></li> <li><a href="../userguide/part6_gradle_caching.html">6. Enabling the Build Cache</a></li> <li><a href="../userguide/part7_gradle_refs.html">7. Using Reference Materials</a></li> </ul> </li> <li><a href="../userguide/gradle_ides.html">Gradle in the IDE</a></li> <li><a href="../userguide/continuous_builds.html">Continuous Build</a></li> </ul> <h3 id="authoring-gradle-builds">Authoring Gradle Builds</h3> <ul> <li><a href="../userguide/getting_started_dev.html">Getting Started</a></li> <li><a class="nav-dropdown" data-toggle="collapse" href="#learning-the-basics" aria-expanded="false" aria-controls="learning-the-basics">Learning the Basics</a> <ul id="authoring-introduction"> <li><a href="../userguide/gradle_directories.html">1. Gradle Directories</a></li> <li><a href="../userguide/intro_multi_project_builds.html">2. Multi-Project Builds</a></li> <li><a href="../userguide/build_lifecycle.html">3. Gradle Build Lifecycle</a></li> <li><a href="../userguide/writing_settings_files.html">4. Writing Settings Files</a></li> <li><a href="../userguide/writing_build_scripts.html">5. Writing Build Scripts</a></li> <li><a href="../userguide/tutorial_using_tasks.html">6. Using Tasks</a></li> <li><a href="../userguide/writing_tasks.html">7. Writing Tasks</a></li> <li><a href="../userguide/plugins.html">8. Using Plugins</a></li> <li><a href="../userguide/writing_plugins.html">9. Writing Plugins</a></li> </ul> </li> <li><a class="nav-dropdown" data-toggle="collapse" aria-expanded="false">Tutorial</a> <ul id="authoring-tutorial"> <li><a href="../userguide/partr1_gradle_init.html">1. Initializing the Project</a></li> <li><a href="../userguide/partr2_build_lifecycle.html">2. Understanding the Build Lifecycle</a></li> <li><a href="../userguide/partr3_multi_project_builds.html">3. Multi-Project Builds</a></li> <li><a href="../userguide/partr4_settings_file.html">4. Writing the Settings File</a></li> <li><a href="../userguide/partr5_build_scripts.html">5. Writing a Build Script</a></li> <li><a href="../userguide/partr6_writing_tasks.html">6. Writing Tasks</a></li> <li><a href="../userguide/partr7_writing_plugins.html">7. Writing Plugins</a></li> </ul> </li> <li><a class="nav-dropdown" data-toggle="collapse" href="#authoring-multi-project-builds" aria-expanded="false" aria-controls="authoring-multi-project-builds">Structuring Builds</a> <ul id="authoring-multi-project-builds"> <li><a href="../userguide/multi_project_builds.html">Structuring Projects with Gradle</a></li> <li><a href="../userguide/declaring_dependencies_between_subprojects.html">Declaring Dependencies between Subprojects</a></li> <li><a href="../userguide/sharing_build_logic_between_subprojects.html">Sharing Build Logic between Subprojects</a></li> <li><a href="../userguide/composite_builds.html">Composite Builds</a></li> <li><a href="../userguide/multi_project_configuration_and_execution.html">Configuration on Demand</a></li> </ul> </li> <li><a class="nav-dropdown" data-toggle="collapse" href="#developing-tasks" aria-expanded="false" aria-controls="developing-tasks">Developing Tasks</a> <ul id="developing-tasks"> <li><a href="../userguide/more_about_tasks.html">Understanding Tasks</a></li> <li><a href="../userguide/controlling_task_execution.html">Controlling Task Execution</a></li> <li><a href="../userguide/organizing_tasks.html">Organizing Tasks</a></li> <li><a href="../userguide/implementing_custom_tasks.html">Implementing Custom Tasks</a></li> <li><a href="../userguide/lazy_configuration.html">Configuring Tasks Lazily</a></li> <li><a href="../userguide/worker_api.html">Developing Parallel Tasks</a></li> <li><a href="../userguide/custom_tasks.html">Developing Advanced Tasks</a></li> <li><a href="../userguide/build_services.html">Using Shared Build Services</a></li> </ul> </li> <li><a class="nav-dropdown" data-toggle="collapse" href="#developing-plugins" aria-expanded="false" aria-controls="developing-plugins">Developing Plugins</a> <ul id="developing-plugins"> <li><a href="../userguide/custom_plugins.html">Understanding Plugins</a></li> <li><a href="../userguide/implementing_gradle_plugins.html">Understanding Implementation Options</a></li> <li><a href="../userguide/implementing_gradle_plugins_precompiled.html">Implementing Pre-compiled Script Plugins</a></li> <li><a href="../userguide/implementing_gradle_plugins_binary.html">Implementing Binary Plugins</a></li> <li><a href="../userguide/testing_gradle_plugins.html">Testing Plugins</a></li> <li><a href="../userguide/publishing_gradle_plugins.html">Publishing Plugins</a></li> </ul> </li> <li><a class="nav-dropdown" data-toggle="collapse" href="#gradle-properties" aria-expanded="false" aria-controls="gradle-properties">Understanding Gradle Types</a> <ul id="gradle-properties-topics"> <li><a href="../userguide/properties_providers.html">Understanding Properties and Providers</a></li> <li><a href="../userguide/collections.html">Understanding Collections</a></li> <li><a href="../userguide/service_injection.html">Understanding Services and Service Injection</a></li> </ul> </li> <li><a class="nav-dropdown" data-toggle="collapse" href="#other-developing-topics" aria-expanded="false" aria-controls="other-developing-topics">Other Topics</a> <ul id="other-developing-topics"> <li><a href="../userguide/working_with_files.html">Working with Files</a></li> <li><a href="../userguide/init_scripts.html">Initialization Scripts</a></li> <li><a href="../userguide/dataflow_actions.html">Dataflow Actions</a></li> <li><a href="../userguide/test_kit.html">Testing with TestKit</a></li> <li><a href="../userguide/ant.html">Using Ant from Gradle</a></li> </ul> </li> <li><a href="../userguide/directory_layout.html">Gradle-managed Directories</a></li> <li><a href="../userguide/build_environment.html">Configuring the Build Environment</a></li> <li><a href="../userguide/logging.html">Logging with Gradle</a></li> </ul> <h3 id="managing-dependencies">Dependency Management</h3> <ul> <li><a href="../userguide/getting_started_dep_man.html">Getting Started</a></li> <li><a class="nav-dropdown" data-toggle="collapse" href="#learning-the-basics-dependency-management" aria-expanded="false" aria-controls="learning-the-basics-dependency-management">Learning the Basics</a> <ul id="learning-the-basics-dependency-management"> <li><a href="../userguide/declaring_dependencies.html">1. Declaring Dependencies</a></li> <li><a href="../userguide/dependency_configurations.html">2. Dependency Configurations</a></li> <li><a href="../userguide/declaring_repositories.html">3. Declaring Repositories</a></li> <li><a href="../userguide/centralizing_dependencies.html">4. Centralizing Dependencies</a></li> <li><a href="../userguide/dependency_constraints_conflicts.html">5. Dependency Constraints and Conflict Resolution</a></li> <li><a href="../userguide/dependency_resolution.html">6. Dependency Resolution</a></li> <li><a href="../userguide/variant_aware_resolution.html">7. Variant Aware Dependency Resolution</a></li> </ul> </li> <li><a class="nav-dropdown" data-toggle="collapse" href="#declaring-dependencies" aria-expanded="false" aria-controls="declaring-dependencies">Declaring Dependencies</a> <ul id="declaring-dependencies"> <li><a href="../userguide/declaring_dependencies_basics.html">Declaring Dependencies Basics</a></li> <li><a href="../userguide/viewing_debugging_dependencies.html">Viewing Dependencies</a></li> <li><a href="../userguide/dependency_versions.html">Declaring Versions and Ranges</a></li> <li><a href="../userguide/dependency_constraints.html">Declaring Dependency Constraints</a></li> <li><a href="../userguide/declaring_configurations.html">Creating Dependency Configurations</a></li> </ul> </li> <li><a class="nav-dropdown" data-toggle="collapse" href="#declaring-repositories" aria-expanded="false" aria-controls="declaring-repositories">Declaring Repositories</a> <ul id="declaring-repositories"> <li><a href="../userguide/declaring_repositories_basics.html">Declaring Repositories Basics</a></li> <li><a href="../userguide/centralizing_repositories.html">Centralizing Repository Declarations</a></li> <li><a href="../userguide/supported_repository_types.html">Repository Types</a></li> <li><a href="../userguide/supported_metadata_formats.html">Metadata Formats</a></li> <li><a href="../userguide/supported_repository_protocols.html">Supported Protocols</a></li> <li><a href="../userguide/filtering_repository_content.html">Filtering Repository Content</a></li> </ul> </li> <li><a class="nav-dropdown" data-toggle="collapse" href="#centralizing-dependencies" aria-expanded="false" aria-controls="centralizing-dependencies">Centralizing Dependencies</a> <ul id="centralizing-dependencies"> <li><a href="../userguide/platforms.html">Creating Platforms</a></li> <li><a href="../userguide/version_catalogs.html">Creating Version Catalogs</a></li> <li><a href="../userguide/centralizing_catalog_platform.html">Using Catalogs with Platforms</a></li> </ul> </li> <li><a class="nav-dropdown" data-toggle="collapse" href="#dependency-management" aria-expanded="false" aria-controls="dependency-management">Managing Dependencies</a> <ul id="dependency-management"> <li><a href="../userguide/dependency_locking.html">Locking Versions</a></li> <li><a href="../userguide/resolution_rules.html">Using Resolution Rules</a></li> <li><a href="../userguide/component_metadata_rules.html">Modifying Dependency Metadata</a></li> <li><a href="../userguide/dependency_caching.html">Caching Dependencies</a></li> </ul> </li> <li><a class="nav-dropdown" data-toggle="collapse" href="#understanding_dep_res" aria-expanded="false" aria-controls="understanding_dep_res">Understanding Dependency Resolution</a> <ul id="understanding_dep_res"> <li><a href="../userguide/variant_model.html">Understanding The Model</a></li> <li><a href="../userguide/component_capabilities.html">Capabilities</a></li> <li><a href="../userguide/variant_attributes.html">Variants and Attributes</a></li> </ul> </li> <li><a class="nav-dropdown" data-toggle="collapse" href="#dependency-resolution" aria-expanded="false" aria-controls="dependency-resolution">Controlling Dependency Resolution</a> <ul id="dependency-resolution"> <li><a href="../userguide/dependency_resolution_basics.html">Dependency Resolution Basics</a></li> <li><a href="../userguide/dependency_graph_resolution.html">Graph Resolution</a></li> <li><a href="../userguide/artifact_resolution.html">Artifact Resolution</a></li> <li><a href="../userguide/artifact_transforms.html">Artifact Transforms</a></li> </ul> </li> <li><a class="nav-dropdown" data-toggle="collapse" href="#publishing" aria-expanded="false" aria-controls="publishing">Publishing Libraries</a> <ul id="publishing"> <li><a href="../userguide/publishing_setup.html">Setting up Publishing</a></li> <li><a href="../userguide/publishing_gradle_module_metadata.html">Understanding Gradle Module Metadata</a></li> <li><a href="../userguide/publishing_signing.html">Signing Artifacts</a></li> <li><a href="../userguide/publishing_customization.html">Customizing Publishing</a></li> <li><a href="../userguide/publishing_maven.html">Maven Publish Plugin</a></li> <li><a href="../userguide/publishing_ivy.html">Ivy Publish Plugin</a></li> </ul> </li> <li><a class="nav-dropdown" data-toggle="collapse" href="#other" aria-expanded="false" aria-controls="other">Other Topics</a> <ul id="other"> <li><a href="../userguide/dependency_verification.html">Verifying Dependencies</a></li> <li><a href="../userguide/dependency_version_alignment.html">Aligning Dependencies</a></li> <li><a href="../userguide/feature_variants.html">Modeling Feature Variants and Optional Dependencies</a></li> </ul> </li> </ul> <h3 id="authoring-gradle-builds-java">Authoring JVM Builds</h3> <ul> <li><a href="../userguide/building_java_projects.html">Building Java & JVM projects</a></li> <li><a href="../userguide/java_testing.html">Testing Java & JVM projects</a></li> <li><a class="nav-dropdown" data-toggle="collapse" href="#java-toolchains" aria-expanded="false" aria-controls="java-toolchains">Java Toolchains</a> <ul id="java-toolchains"> <li><a href="../userguide/toolchains.html">Toolchains for JVM projects</a></li> <li><a href="../userguide/toolchain_plugins.html">Toolchain Resolver Plugins</a></li> </ul> </li> <li><a href="../userguide/dependency_management_for_java_projects.html">Managing Dependencies</a></li> <li><a class="nav-dropdown" data-toggle="collapse" href="#jvm-plugins" aria-expanded="false" aria-controls="jvm-plugins">JVM Plugins</a> <ul id="jvm-plugins"> <li><a href="../userguide/java_library_plugin.html">Java Library Plugin</a></li> <li><a href="../userguide/application_plugin.html">Java Application Plugin</a></li> <li><a href="../userguide/java_platform_plugin.html">Java Platform Plugin</a></li> <li><a href="../userguide/groovy_plugin.html">Groovy Plugin</a></li> <li><a href="../userguide/scala_plugin.html">Scala Plugin</a></li> </ul> </li> </ul> <h3 id="optimizing-build-performance">Optimizing Build Performance</h3> <ul> <li><a href="../userguide/performance.html">Improving Performance of Gradle Builds</a></li> <li><a href="../userguide/gradle_daemon.html">Gradle Daemon</a></li> <li><a href="../userguide/file_system_watching.html">File System Watching</a></li> <li><a href="../userguide/incremental_build.html">Incremental Build</a></li> <li><a class="nav-dropdown" data-toggle="collapse" href="#build-cache" aria-expanded="false" aria-controls="optimizing-build-performance">Using the Build Cache</a> <ul id="build-cache"> <li><a href="../userguide/build_cache.html">Enabling and Configuring</a></li> <li><a href="../userguide/build_cache_use_cases.html">Why use the Build Cache?</a></li> <li><a href="../userguide/build_cache_performance.html">Understanding the Impact</a></li> <li><a href="../userguide/build_cache_concepts.html">Learning Basic Concepts</a></li> <li><a href="../userguide/caching_java_projects.html">Caching Java Project</a></li> <li><a href="../userguide/caching_android_projects.html">Caching Android Project</a></li> <li><a href="../userguide/build_cache_debugging.html">Debugging Caching Issues</a></li> <li><a href="../userguide/common_caching_problems.html">Troubleshooting</a></li> </ul> </li> <li><a href="../userguide/configuration_cache.html">Using the Configuration Cache</a></li> <li><a href="../userguide/inspect.html">Inspecting Gradle Builds</a></li> <li><a href="../userguide/config_gradle.html">Configuring Gradle</a></li> <li><a href="../userguide/project_properties.html">Project Properties</a></li> <li><a href="../userguide/networking.html">Gradle Networking</a></li> </ul> <h3 id="authoring-gradle-builds-native">Authoring C++/Swift Builds</h3> <ul> <li><a href="../userguide/building_cpp_projects.html">Building C++ projects</a></li> <li><a href="../userguide/cpp_testing.html">Testing C++ projects</a></li> <li><a href="../userguide/building_swift_projects.html">Building Swift projects</a></li> <li><a href="../userguide/swift_testing.html">Testing Swift projects</a></li> </ul> <h3 id="reference">Reference</h3> <ul> <li><a class="nav-dropdown" data-toggle="collapse" href="#gradle-api" aria-expanded="false" aria-controls="gradle-api">Gradle DSLs and API</a> <ul id="gradle-api"> <li><a href="../javadoc/index.html?overview-summary.html">Javadoc</a></li> <li><a href="../userguide/groovy_build_script_primer.html">Groovy DSL Primer</a></li> <li><a href="../dsl/index.html">Groovy DSL Reference</a></li> <li><a href="../userguide/kotlin_dsl.html">Kotlin DSL Primer</a></li> <li><a href="../kotlin-dsl/index.html" target="_blank">Kotlin DSL API</a></li> <li><a href="../userguide/migrating_from_groovy_to_kotlin_dsl.html">Groovy to Kotlin DSL Migration</a></li> <li><a href="../samples/index.html">Samples</a></li> <li><a href="../userguide/glossary.html">Glossary</a></li> </ul> </li> <li><a href="https://community.gradle.org/cookbook/">Gradle Cookbook</a></li> <li><a href="../userguide/command_line_interface.html">Command-Line Interface</a></li> <li><a href="../userguide/gradle_wrapper.html">Gradle Wrapper</a></li> <li><a href="../userguide/plugin_reference.html">Core Plugins</a></li> <li id="third-party-integration"><a href="../userguide/third_party_integration.html">Gradle & Third-party Tools</a></li> <li><a href="../userguide/userguide_single.html">User Manual Single Page</a></li> <li><a href="../userguide/userguide.pdf">User Manual PDF</a></li> </ul> </nav> <!-- End Primary Navigation --> <div class="content"> <div class="chapter"> <div id="header"> <h1>Advanced Tasks</h1> <div class="details"> <span id="revnumber">version 8.11.1</span> </div> <div id="toc" class="toc"> <div id="toctitle">Contents</div> <ul class="sectlevel1"> <li><a href="#incremental_tasks">Incremental tasks</a></li> <li><a href="#sec:declaring_and_using_command_line_options">Command Line options</a></li> <li><a href="#verification_failures">Verification failures</a></li> </ul> </div> </div> <div id="content"> <div class="sect1"> <h2 id="incremental_tasks"><a class="anchor" href="#incremental_tasks"></a><a class="link" href="#incremental_tasks">Incremental tasks</a></h2> <div class="sectionbody"> <div class="paragraph"> <p>In Gradle, implementing a task that skips execution when its inputs and outputs are already <code>UP-TO-DATE</code> is simple and efficient, thanks to the <a href="incremental_build.html#incremental_build">Incremental Build</a> feature.</p> </div> <div class="paragraph"> <p>However, there are times when only a few input files have changed since the last execution, and it is best to avoid reprocessing all the unchanged inputs. This situation is common in tasks that transform input files into output files on a one-to-one basis.</p> </div> <div class="paragraph"> <p>To optimize your build process you can use an incremental task. This approach ensures that only out-of-date input files are processed, improving build performance.</p> </div> <div class="sect2"> <h3 id="sec:implementing_an_incremental_task"><a class="anchor" href="#sec:implementing_an_incremental_task"></a><a class="link" href="#sec:implementing_an_incremental_task">Implementing an incremental task</a></h3> <div class="paragraph"> <p>For a task to process inputs incrementally, that task must contain an <em>incremental</em> task action.</p> </div> <div class="paragraph"> <p>This is a task action method that has a single <a href="../dsl/org.gradle.work.InputChanges.html">InputChanges</a> parameter. That parameter tells Gradle that the action only wants to process the changed inputs.</p> </div> <div class="paragraph"> <p>In addition, the task needs to declare at least one incremental file input property by using either <a href="../javadoc/org/gradle/work/Incremental.html"><code>@Incremental</code></a> or <a href="../javadoc/org/gradle/api/tasks/SkipWhenEmpty.html"><code>@SkipWhenEmpty</code></a>:</p> </div> <div class="exampleblock"> <div class="content"> <div class="exampleblock multi-language-sample"> <div class="content"> <div class="listingblock"> <div class="title">build.gradle.kts</div> <div class="content"> <pre class="prettyprint highlight"><code data-lang="kotlin">public class IncrementalReverseTask : DefaultTask() { @get:Incremental @get:InputDirectory val inputDir: DirectoryProperty = project.objects.directoryProperty() @get:OutputDirectory val outputDir: DirectoryProperty = project.objects.directoryProperty() @get:Input val inputProperty: RegularFileProperty = project.objects.fileProperty() // File input property @TaskAction fun execute(inputs: InputChanges) { // InputChanges parameter val msg = if (inputs.isIncremental) "CHANGED inputs are out of date" else "ALL inputs are out of date" println(msg) } }</code></pre> </div> </div> </div> </div> <div class="exampleblock multi-language-sample"> <div class="content"> <div class="listingblock"> <div class="title">build.gradle</div> <div class="content"> <pre class="prettyprint highlight"><code data-lang="groovy">class IncrementalReverseTask extends DefaultTask { @Incremental @InputDirectory def File inputDir @OutputDirectory def File outputDir @Input def inputProperty // File input property @TaskAction void execute(InputChanges inputs) { // InputChanges parameter println inputs.incremental ? "CHANGED inputs are out of date" : "ALL inputs are out of date" } }</code></pre> </div> </div> </div> </div> </div> </div> <div class="admonitionblock important"> <table> <tr> <td class="icon"> <i class="fa icon-important" title="Important"></i> </td> <td class="content"> <div class="paragraph"> <p>To query incremental changes for an input file property, that property must always return the same instance. The easiest way to accomplish this is to use one of the following property types: <a href="../javadoc/org/gradle/api/file/RegularFileProperty.html"><code>RegularFileProperty</code></a>, <a href="../javadoc/org/gradle/api/file/DirectoryProperty.html"><code>DirectoryProperty</code></a> or <a href="../javadoc/org/gradle/api/file/ConfigurableFileCollection.html"><code>ConfigurableFileCollection</code></a>.</p> </div> <div class="paragraph"> <p>You can learn more about <code>RegularFileProperty</code> and <code>DirectoryProperty</code> in <a href="lazy_configuration.html#lazy_configuration">Lazy Configuration</a>.</p> </div> </td> </tr> </table> </div> <div class="paragraph"> <p>The incremental task action can use <a href="../dsl/org.gradle.work.InputChanges.html#org.gradle.work.InputChanges:getFileChanges(org.gradle.api.file.FileCollection)"><code>InputChanges.getFileChanges()</code></a> to find out what files have changed for a given file-based input property, be it of type <code>RegularFileProperty</code>, <code>DirectoryProperty</code> or <code>ConfigurableFileCollection</code>.</p> </div> <div class="paragraph"> <p>The method returns an <code>Iterable</code> of type <a href="../javadoc/org/gradle/work/FileChange.html">FileChanges</a>, which in turn can be queried for the following:</p> </div> <div class="ulist"> <ul> <li> <p>the <a href="../javadoc/org/gradle/work/FileChange.html#getFile--">affected file</a></p> </li> <li> <p>the <a href="../javadoc/org/gradle/work/FileChange.html#getChangeType--">change type</a> (<code>ADDED</code>, <code>REMOVED</code> or <code>MODIFIED</code>)</p> </li> <li> <p>the <a href="../javadoc/org/gradle/work/FileChange.html#getNormalizedPath--">normalized path</a> of the changed file</p> </li> <li> <p>the <a href="../javadoc/org/gradle/work/FileChange.html#getFileType--">file type</a> of the changed file</p> </li> </ul> </div> <div class="paragraph"> <p>The following example demonstrates an incremental task that has a directory input. It assumes that the directory contains a collection of text files and copies them to an output directory, reversing the text within each file:</p> </div> <div id="taskDefinition" class="exampleblock"> <div class="content"> <div class="exampleblock testable-sample multi-language-sample"> <div class="content"> <div class="listingblock"> <div class="title">build.gradle.kts</div> <div class="content"> <pre class="prettyprint highlight"><code data-lang="kotlin">abstract class IncrementalReverseTask : DefaultTask() { @get:Incremental @get:PathSensitive(PathSensitivity.NAME_ONLY) @get:InputDirectory abstract val inputDir: DirectoryProperty @get:OutputDirectory abstract val outputDir: DirectoryProperty @get:Input abstract val inputProperty: Property<String> @TaskAction fun execute(inputChanges: InputChanges) { println( if (inputChanges.isIncremental) "Executing incrementally" else "Executing non-incrementally" ) inputChanges.getFileChanges(inputDir).forEach { change -> if (change.fileType == FileType.DIRECTORY) return@forEach println("${change.changeType}: ${change.normalizedPath}") val targetFile = outputDir.file(change.normalizedPath).get().asFile if (change.changeType == ChangeType.REMOVED) { targetFile.delete() } else { targetFile.writeText(change.file.readText().reversed()) } } } }</code></pre> </div> </div> </div> </div> <div class="exampleblock testable-sample multi-language-sample"> <div class="content"> <div class="listingblock"> <div class="title">build.gradle</div> <div class="content"> <pre class="prettyprint highlight"><code data-lang="groovy">abstract class IncrementalReverseTask extends DefaultTask { @Incremental @PathSensitive(PathSensitivity.NAME_ONLY) @InputDirectory abstract DirectoryProperty getInputDir() @OutputDirectory abstract DirectoryProperty getOutputDir() @Input abstract Property<String> getInputProperty() @TaskAction void execute(InputChanges inputChanges) { println(inputChanges.incremental ? 'Executing incrementally' : 'Executing non-incrementally' ) inputChanges.getFileChanges(inputDir).each { change -> if (change.fileType == FileType.DIRECTORY) return println "${change.changeType}: ${change.normalizedPath}" def targetFile = outputDir.file(change.normalizedPath).get().asFile if (change.changeType == ChangeType.REMOVED) { targetFile.delete() } else { targetFile.text = change.file.text.reverse() } } } }</code></pre> </div> </div> </div> </div> </div> </div> <div class="admonitionblock note"> <table> <tr> <td class="icon"> <i class="fa icon-note" title="Note"></i> </td> <td class="content"> The type of the <code>inputDir</code> property, its annotations, and the <code>execute()</code> action use <code>getFileChanges()</code> to process the subset of files that have changed since the last build. The action deletes a target file if the corresponding input file has been removed. </td> </tr> </table> </div> <div class="paragraph"> <p>If, for some reason, the task is executed non-incrementally (by running with <code>--rerun-tasks</code>, for example), all files are reported as <code>ADDED</code>, irrespective of the previous state. In this case, Gradle automatically removes the previous outputs, so the incremental task must only process the given files.</p> </div> <div class="paragraph"> <p>For a simple transformer task like the above example, the task action must generate output files for any out-of-date inputs and delete output files for any removed inputs.</p> </div> <div class="admonitionblock important"> <table> <tr> <td class="icon"> <i class="fa icon-important" title="Important"></i> </td> <td class="content"> A task may only contain a single incremental task action. </td> </tr> </table> </div> </div> <div class="sect2"> <h3 id="sec:which_inputs_are_considered_out_of_date"><a class="anchor" href="#sec:which_inputs_are_considered_out_of_date"></a><a class="link" href="#sec:which_inputs_are_considered_out_of_date">Which inputs are considered out of date?</a></h3> <div class="paragraph"> <p>When a task has been previously executed, and the only changes since that execution are to incremental input file properties, Gradle can intelligently determine which input files need to be processed, a concept known as incremental execution.</p> </div> <div class="paragraph"> <p>In this scenario, the <a href="../dsl/org.gradle.work.InputChanges.html#org.gradle.work.InputChanges:getFileChanges(org.gradle.api.file.FileCollection)"><code>InputChanges.getFileChanges()</code></a> method, available in the <code>org.gradle.work.InputChanges</code> class, provides details for all input files associated with the given property that have been <code>ADDED</code>, <code>REMOVED</code> or <code>MODIFIED</code>.</p> </div> <div class="paragraph"> <p>However, there are many cases where Gradle cannot determine which input files need to be processed (i.e., non-incremental execution). Examples include:</p> </div> <div class="ulist"> <ul> <li> <p>There is no history available from a previous execution.</p> </li> <li> <p>You are building with a different version of Gradle. Currently, Gradle does not use task history from a different version.</p> </li> <li> <p>An <a href="../javadoc/org/gradle/api/tasks/TaskOutputs.html#upToDateWhen-groovy.lang.Closure-"><code>upToDateWhen</code></a> criterion added to the task returns <code>false</code>.</p> </li> <li> <p>An input property has changed since the previous execution.</p> </li> <li> <p>A non-incremental input file property has changed since the previous execution.</p> </li> <li> <p>One or more output files have changed since the previous execution.</p> </li> </ul> </div> <div class="paragraph"> <p>In these cases, Gradle will report all input files as <code>ADDED</code>, and the <code>getFileChanges()</code> method will return details for all the files that comprise the given input property.</p> </div> <div class="paragraph"> <p>You can check if the task execution is incremental or not with the <a href="../dsl/org.gradle.work.InputChanges.html#org.gradle.work.InputChanges.html##org.gradle.work.InputChanges:incremental"><code>InputChanges.isIncremental()</code></a> method.</p> </div> </div> <div class="sect2"> <h3 id="sec:an_incremental_task_in_action"><a class="anchor" href="#sec:an_incremental_task_in_action"></a><a class="link" href="#sec:an_incremental_task_in_action">An incremental task in action</a></h3> <div class="paragraph"> <p>Consider an instance of <code>IncrementalReverseTask</code> executed against a set of inputs for the first time.</p> </div> <div class="paragraph"> <p>In this case, all inputs will be considered <code>ADDED</code>, as shown here:</p> </div> <div id="ex:incremental_task_definition" class="exampleblock"> <div class="content"> <div class="exampleblock testable-sample multi-language-sample"> <div class="content"> <div class="listingblock"> <div class="title">build.gradle.kts</div> <div class="content"> <pre class="prettyprint highlight"><code data-lang="kotlin">tasks.register<IncrementalReverseTask>("incrementalReverse") { inputDir = file("inputs") outputDir = layout.buildDirectory.dir("outputs") inputProperty = project.findProperty("taskInputProperty") as String? ?: "original" }</code></pre> </div> </div> </div> </div> <div class="exampleblock testable-sample multi-language-sample"> <div class="content"> <div class="listingblock"> <div class="title">build.gradle</div> <div class="content"> <pre class="prettyprint highlight"><code data-lang="groovy">tasks.register('incrementalReverse', IncrementalReverseTask) { inputDir = file('inputs') outputDir = layout.buildDirectory.dir("outputs") inputProperty = project.properties['taskInputProperty'] ?: 'original' }</code></pre> </div> </div> </div> </div> </div> </div> <div class="paragraph"> <p>The build layout:</p> </div> <div class="listingblock"> <div class="content"> <pre class="prettyprint highlight"><code data-lang="text">. ├── build.gradle └── inputs ├── 1.txt ├── 2.txt └── 3.txt</code></pre> </div> </div> <div class="listingblock"> <div class="content"> <pre class="prettyprint highlight"><code data-lang="text">$ gradle -q incrementalReverse Executing non-incrementally ADDED: 1.txt ADDED: 2.txt ADDED: 3.txt</code></pre> </div> </div> <div class="paragraph"> <p>Naturally, when the task is executed again with no changes, then the entire task is <code>UP-TO-DATE</code>, and the task action is not executed:</p> </div> <div class="listingblock"> <div class="content"> <pre class="prettyprint highlight"><code data-lang="text">$ gradle incrementalReverse > Task :incrementalReverse UP-TO-DATE BUILD SUCCESSFUL in 0s 1 actionable task: 1 up-to-date</code></pre> </div> </div> <div class="paragraph"> <p>When an input file is modified in some way or a new input file is added, then re-executing the task results in those files being returned by <a href="../dsl/org.gradle.work.InputChanges.html#org.gradle.work.InputChanges:getFileChanges(org.gradle.api.file.FileCollection)"><code>InputChanges.getFileChanges()</code></a>.</p> </div> <div class="paragraph"> <p>The following example modifies the content of one file and adds another before running the incremental task:</p> </div> <div class="exampleblock"> <div class="content"> <div class="exampleblock testable-sample multi-language-sample"> <div class="content"> <div class="listingblock"> <div class="title">build.gradle.kts</div> <div class="content"> <pre class="prettyprint highlight"><code data-lang="kotlin">tasks.register("updateInputs") { val inputsDir = layout.projectDirectory.dir("inputs") outputs.dir(inputsDir) doLast { inputsDir.file("1.txt").asFile.writeText("Changed content for existing file 1.") inputsDir.file("4.txt").asFile.writeText("Content for new file 4.") } }</code></pre> </div> </div> </div> </div> <div class="exampleblock testable-sample multi-language-sample"> <div class="content"> <div class="listingblock"> <div class="title">build.gradle</div> <div class="content"> <pre class="prettyprint highlight"><code data-lang="groovy">tasks.register('updateInputs') { def inputsDir = layout.projectDirectory.dir('inputs') outputs.dir(inputsDir) doLast { inputsDir.file('1.txt').asFile.text = 'Changed content for existing file 1.' inputsDir.file('4.txt').asFile.text = 'Content for new file 4.' } }</code></pre> </div> </div> </div> </div> <div class="listingblock"> <div class="content"> <pre>$ gradle -q updateInputs incrementalReverse Executing incrementally MODIFIED: 1.txt ADDED: 4.txt</pre> </div> </div> </div> </div> <div class="admonitionblock note"> <table> <tr> <td class="icon"> <i class="fa icon-note" title="Note"></i> </td> <td class="content"> The various mutation tasks (<code>updateInputs</code>, <code>removeInput</code>, etc) are only present to demonstrate the behavior of incremental tasks. They should not be viewed as the kinds of tasks or task implementations you should have in your own build scripts. </td> </tr> </table> </div> <div class="paragraph"> <p>When an existing input file is removed, then re-executing the task results in that file being returned by <a href="../dsl/org.gradle.work.InputChanges.html#org.gradle.work.InputChanges:getFileChanges(org.gradle.api.file.FileCollection)"><code>InputChanges.getFileChanges()</code></a> as <code>REMOVED</code>.</p> </div> <div class="paragraph"> <p>The following example removes one of the existing files before executing the incremental task:</p> </div> <div class="exampleblock"> <div class="content"> <div class="exampleblock testable-sample multi-language-sample"> <div class="content"> <div class="listingblock"> <div class="title">build.gradle.kts</div> <div class="content"> <pre class="prettyprint highlight"><code data-lang="kotlin">tasks.register<Delete>("removeInput") { delete("inputs/3.txt") }</code></pre> </div> </div> </div> </div> <div class="exampleblock testable-sample multi-language-sample"> <div class="content"> <div class="listingblock"> <div class="title">build.gradle</div> <div class="content"> <pre class="prettyprint highlight"><code data-lang="groovy">tasks.register('removeInput', Delete) { delete 'inputs/3.txt' }</code></pre> </div> </div> </div> </div> <div class="listingblock"> <div class="content"> <pre>$ gradle -q removeInput incrementalReverse Executing incrementally REMOVED: 3.txt</pre> </div> </div> </div> </div> <div class="paragraph"> <p>Gradle cannot determine which input files are out-of-date when an <em>output</em> file is deleted (or modified). In this case, details for <em>all</em> the input files for the given property are returned by <a href="../dsl/org.gradle.work.InputChanges.html#org.gradle.work.InputChanges:getFileChanges(org.gradle.api.file.FileCollection)"><code>InputChanges.getFileChanges()</code></a>.</p> </div> <div class="paragraph"> <p>The following example removes one of the output files from the build directory. However, all the input files are considered to be <code>ADDED</code>:</p> </div> <div class="exampleblock"> <div class="content"> <div class="exampleblock testable-sample multi-language-sample"> <div class="content"> <div class="listingblock"> <div class="title">build.gradle.kts</div> <div class="content"> <pre class="prettyprint highlight"><code data-lang="kotlin">tasks.register<Delete>("removeOutput") { delete(layout.buildDirectory.file("outputs/1.txt")) }</code></pre> </div> </div> </div> </div> <div class="exampleblock testable-sample multi-language-sample"> <div class="content"> <div class="listingblock"> <div class="title">build.gradle</div> <div class="content"> <pre class="prettyprint highlight"><code data-lang="groovy">tasks.register('removeOutput', Delete) { delete layout.buildDirectory.file("outputs/1.txt") }</code></pre> </div> </div> </div> </div> <div class="listingblock"> <div class="content"> <pre>$ gradle -q removeOutput incrementalReverse Executing non-incrementally ADDED: 1.txt ADDED: 2.txt ADDED: 3.txt</pre> </div> </div> </div> </div> <div class="paragraph"> <p>The last scenario we want to cover concerns what happens when a non-file-based input property is modified. In such cases, Gradle cannot determine how the property impacts the task outputs, so the task is executed non-incrementally. This means that <em>all</em> input files for the given property are returned by <a href="../dsl/org.gradle.work.InputChanges.html#org.gradle.work.InputChanges:getFileChanges(org.gradle.api.file.FileCollection)"><code>InputChanges.getFileChanges()</code></a> and they are all treated as <code>ADDED</code>.</p> </div> <div class="paragraph"> <p>The following example sets the project property <code>taskInputProperty</code> to a new value when running the <code>incrementalReverse</code> task. That project property is used to initialize the task’s <code>inputProperty</code> property, as you can see in the <a href="#ex:incremental_task_definition">first example of this section</a>.</p> </div> <div class="paragraph"> <p>Here is the expected output in this case:</p> </div> <div class="exampleblock"> <div class="content"> <div class="listingblock"> <div class="content"> <pre>$ gradle -q -PtaskInputProperty=changed incrementalReverse Executing non-incrementally ADDED: 1.txt ADDED: 2.txt ADDED: 3.txt</pre> </div> </div> </div> </div> </div> </div> </div> <div class="sect1"> <h2 id="sec:declaring_and_using_command_line_options"><a class="anchor" href="#sec:declaring_and_using_command_line_options"></a><a class="link" href="#sec:declaring_and_using_command_line_options">Command Line options</a></h2> <div class="sectionbody"> <div class="paragraph"> <p>Sometimes, a user wants to declare the value of an exposed task property on the command line instead of the build script. Passing property values on the command line is particularly helpful if they change more frequently.</p> </div> <div class="paragraph"> <p>The task API supports a mechanism for marking a property to automatically generate a corresponding command line parameter with a specific name at runtime.</p> </div> <div class="sect2"> <h3 id="sec:declaring_task_option"><a class="anchor" href="#sec:declaring_task_option"></a><a class="link" href="#sec:declaring_task_option">Step 1. Declare a command-line option</a></h3> <div class="paragraph"> <p>To expose a new command line option for a task property, annotate the corresponding setter method of a property with <a href="../javadoc/org/gradle/api/tasks/options/Option.html">Option</a>:</p> </div> <div class="listingblock"> <div class="content"> <pre class="prettyprint highlight"><code>@Option(option = "flag", description = "Sets the flag")</code></pre> </div> </div> <div class="paragraph"> <p>An option requires a mandatory identifier. You can provide an optional description.</p> </div> <div class="paragraph"> <p>A task can expose as many command line options as properties available in the class.</p> </div> <div class="paragraph"> <p>Options may be declared in superinterfaces of the task class as well. If multiple interfaces declare the same property but with different option flags, they will both work to set the property.</p> </div> <div class="paragraph"> <p>In the example below, the custom task <code>UrlVerify</code> verifies whether a URL can be resolved by making an HTTP call and checking the response code. The URL to be verified is configurable through the property <code>url</code>. The setter method for the property is annotated with <a href="../javadoc/org/gradle/api/tasks/options/Option.html">@Option</a>:</p> </div> <div class="listingblock multi-language-sample"> <div class="title">UrlVerify.java</div> <div class="content"> <pre class="prettyprint highlight"><code data-lang="java">import org.gradle.api.tasks.options.Option; public class UrlVerify extends DefaultTask { private String url; @Option(option = "url", description = "Configures the URL to be verified.") public void setUrl(String url) { this.url = url; } @Input public String getUrl() { return url; } @TaskAction public void verify() { getLogger().quiet("Verifying URL '{}'", url); // verify URL by making a HTTP call } }</code></pre> </div> </div> <div class="paragraph"> <p>All options declared for a task can be <a href="#sec:listing_task_options">rendered as console output</a> by running the <code>help</code> task and the <code>--task</code> option.</p> </div> </div> <div class="sect2"> <h3 id="sec:using_task_option_command_line"><a class="anchor" href="#sec:using_task_option_command_line"></a><a class="link" href="#sec:using_task_option_command_line">Step 2. Use an option on the command line</a></h3> <div class="paragraph"> <p>There are a few rules for options on the command line:</p> </div> <div class="ulist"> <ul> <li> <p>The option uses a double-dash as a prefix, e.g., <code>--url</code>. A single dash does not qualify as valid syntax for a task option.</p> </li> <li> <p>The option argument follows directly after the task declaration, e.g., <code>verifyUrl --url=http://www.google.com/</code>.</p> </li> <li> <p>Multiple task options can be declared in any order on the command line following the task name.</p> </li> </ul> </div> <div class="paragraph"> <p>Building upon the earlier example, the build script creates a task instance of type <code>UrlVerify</code> and provides a value from the command line through the exposed option:</p> </div> <div class="exampleblock"> <div class="content"> <div class="exampleblock testable-sample multi-language-sample"> <div class="content"> <div class="listingblock"> <div class="title">build.gradle.kts</div> <div class="content"> <pre class="prettyprint highlight"><code data-lang="kotlin">tasks.register<UrlVerify>("verifyUrl")</code></pre> </div> </div> </div> </div> <div class="exampleblock testable-sample multi-language-sample"> <div class="content"> <div class="listingblock"> <div class="title">build.gradle</div> <div class="content"> <pre class="prettyprint highlight"><code data-lang="groovy">tasks.register('verifyUrl', UrlVerify)</code></pre> </div> </div> </div> </div> </div> </div> <div class="listingblock"> <div class="content"> <pre>$ gradle -q verifyUrl --url=http://www.google.com/ Verifying URL 'http://www.google.com/'</pre> </div> </div> </div> <div class="sect2"> <h3 id="sec:supported_task_option_data_types"><a class="anchor" href="#sec:supported_task_option_data_types"></a><a class="link" href="#sec:supported_task_option_data_types">Supported data types for options</a></h3> <div class="paragraph"> <p>Gradle limits the data types that can be used for declaring command line options.</p> </div> <div class="paragraph"> <p>The use of the command line differs per type:</p> </div> <div class="dlist"> <dl> <dt class="hdlist1"><code>boolean</code>, <code>Boolean</code>, <code>Property<Boolean></code></dt> <dd> <p>Describes an option with the value <code>true</code> or <code>false</code>.<br> Passing the option on the command line treats the value as <code>true</code>. For example, <code>--foo</code> equates to <code>true</code>.<br> The absence of the option uses the default value of the property. For each boolean option, an opposite option is created automatically. For example, <code>--no-foo</code> is created for the provided option <code>--foo</code> and <code>--bar</code> is created for <code>--no-bar</code>. Options whose name starts with <code>--no</code> are disabled options and set the option value to <code>false</code>. An opposite option is only created if no option with the same name already exists for the task.</p> </dd> <dt class="hdlist1"><code>Double</code>, <code>Property<Double></code></dt> <dd> <p>Describes an option with a double value.<br> Passing the option on the command line also requires a value, e.g., <code>--factor=2.2</code> or <code>--factor 2.2</code>.</p> </dd> <dt class="hdlist1"><code>Integer</code>, <code>Property<Integer></code></dt> <dd> <p>Describes an option with an integer value.<br> Passing the option on the command line also requires a value, e.g., <code>--network-timeout=5000</code> or <code>--network-timeout 5000</code>.</p> </dd> <dt class="hdlist1"><code>Long</code>, <code>Property<Long></code></dt> <dd> <p>Describes an option with a long value.<br> Passing the option on the command line also requires a value, e.g., <code>--threshold=2147483648</code> or <code>--threshold 2147483648</code>.</p> </dd> <dt class="hdlist1"><code>String</code>, <code>Property<String></code></dt> <dd> <p>Describes an option with an arbitrary String value.<br> Passing the option on the command line also requires a value, e.g., <code>--container-id=2x94held</code> or <code>--container-id 2x94held</code>.</p> </dd> <dt class="hdlist1"><code>enum</code>, <code>Property<enum></code></dt> <dd> <p>Describes an option as an enumerated type.<br> Passing the option on the command line also requires a value e.g., <code>--log-level=DEBUG</code> or <code>--log-level debug</code>.<br> The value is not case-sensitive.</p> </dd> <dt class="hdlist1"><code>List<T></code> where <code>T</code> is <code>Double</code>, <code>Integer</code>, <code>Long</code>, <code>String</code>, <code>enum</code></dt> <dd> <p>Describes an option that can take multiple values of a given type.<br> The values for the option have to be provided as multiple declarations, e.g., <code>--image-id=123 --image-id=456</code>.<br> Other notations, such as comma-separated lists or multiple values separated by a space character, are currently not supported.</p> </dd> <dt class="hdlist1"><code>ListProperty<T></code>, <code>SetProperty<T></code> where <code>T</code> is <code>Double</code>, <code>Integer</code>, <code>Long</code>, <code>String</code>, <code>enum</code></dt> <dd> <p>Describes an option that can take multiple values of a given type.<br> The values for the option have to be provided as multiple declarations, e.g., <code>--image-id=123 --image-id=456</code>.<br> Other notations, such as comma-separated lists or multiple values separated by a space character, are currently not supported.</p> </dd> <dt class="hdlist1"><code>DirectoryProperty</code>, <code>RegularFileProperty</code></dt> <dd> <p>Describes an option with a file system element.<br> Passing the option on the command line also requires a value representing a path, e.g., <code>--output-file=file.txt</code> or <code>--output-dir outputDir</code>.<br> Relative paths are resolved relative to the project directory of the project that owns this property instance. See <a href="../javadoc/org/gradle/api/file/FileSystemLocationProperty.html#set-java.io.File"><code>FileSystemLocationProperty.set()</code></a>.</p> </dd> </dl> </div> </div> <div class="sect2"> <h3 id="sec:documenting_available_task_option_values"><a class="anchor" href="#sec:documenting_available_task_option_values"></a><a class="link" href="#sec:documenting_available_task_option_values">Documenting available values for an option</a></h3> <div class="paragraph"> <p>Theoretically, an option for a property type <code>String</code> or <code>List<String></code> can accept any arbitrary value. Accepted values for such an option can be documented programmatically with the help of the annotation <a href="../javadoc/org/gradle/api/tasks/options/OptionValues.html">OptionValues</a>:</p> </div> <div class="listingblock"> <div class="content"> <pre class="prettyprint highlight"><code>@OptionValues('file')</code></pre> </div> </div> <div class="paragraph"> <p>This annotation may be assigned to any method that returns a <code>List</code> of one of the supported data types. You need to specify an option identifier to indicate the relationship between the option and available values.</p> </div> <div class="admonitionblock note"> <table> <tr> <td class="icon"> <i class="fa icon-note" title="Note"></i> </td> <td class="content"> Passing a value on the command line not supported by the option does not fail the build or throw an exception. You must implement custom logic for such behavior in the task action. </td> </tr> </table> </div> <div class="paragraph"> <p>The example below demonstrates the use of multiple options for a single task. The task implementation provides a list of available values for the option <code>output-type</code>:</p> </div> <div class="listingblock multi-language-sample"> <div class="title">UrlProcess.java</div> <div class="content"> <pre class="prettyprint highlight"><code data-lang="java">import org.gradle.api.tasks.options.Option; import org.gradle.api.tasks.options.OptionValues; public abstract class UrlProcess extends DefaultTask { private String url; private OutputType outputType; @Input @Option(option = "http", description = "Configures the http protocol to be allowed.") public abstract Property<Boolean> getHttp(); @Option(option = "url", description = "Configures the URL to send the request to.") public void setUrl(String url) { if (!getHttp().getOrElse(true) && url.startsWith("http://")) { throw new IllegalArgumentException("HTTP is not allowed"); } else { this.url = url; } } @Input public String getUrl() { return url; } @Option(option = "output-type", description = "Configures the output type.") public void setOutputType(OutputType outputType) { this.outputType = outputType; } @OptionValues("output-type") public List<OutputType> getAvailableOutputTypes() { return new ArrayList<OutputType>(Arrays.asList(OutputType.values())); } @Input public OutputType getOutputType() { return outputType; } @TaskAction public void process() { getLogger().quiet("Writing out the URL response from '{}' to '{}'", url, outputType); // retrieve content from URL and write to output } private static enum OutputType { CONSOLE, FILE } }</code></pre> </div> </div> </div> <div class="sect2"> <h3 id="sec:listing_task_options"><a class="anchor" href="#sec:listing_task_options"></a><a class="link" href="#sec:listing_task_options">Listing command line options</a></h3> <div class="paragraph"> <p>Command line options using the annotations <a href="../javadoc/org/gradle/api/tasks/options/Option.html">Option</a> and <a href="../javadoc/org/gradle/api/tasks/options/OptionValues.html">OptionValues</a> are self-documenting.</p> </div> <div class="paragraph"> <p>You will see <a href="#sec:declaring_task_option">declared options</a> and their <a href="#sec:documenting_available_task_option_values">available values</a> reflected in the console output of the <code>help</code> task. The output renders options alphabetically, except for boolean disable options, which appear following the enable option:</p> </div> <div class="listingblock"> <div class="content"> <pre>$ gradle -q help --task processUrl Detailed task information for processUrl Path :processUrl Type UrlProcess (UrlProcess) Options --http Configures the http protocol to be allowed. --no-http Disables option --http. --output-type Configures the output type. Available values are: CONSOLE FILE --url Configures the URL to send the request to. --rerun Causes the task to be re-run even if up-to-date. Description - Group -</pre> </div> </div> </div> <div class="sect2"> <h3 id="limitations"><a class="anchor" href="#limitations"></a><a class="link" href="#limitations">Limitations</a></h3> <div class="paragraph"> <p>Support for declaring command line options currently comes with a few limitations.</p> </div> <div class="ulist"> <ul> <li> <p>Command line options can only be declared for custom tasks via annotation. There’s no programmatic equivalent for defining options.</p> </li> <li> <p>Options cannot be declared globally, e.g., on a project level or as part of a plugin.</p> </li> <li> <p>When assigning an option on the command line, the task exposing the option needs to be spelled out explicitly, e.g., <code>gradle check --tests abc</code> does not work even though the <code>check</code> task depends on the <code>test</code> task.</p> </li> <li> <p>If you specify a task option name that conflicts with the name of a built-in Gradle option, use the <code>--</code> delimiter before calling your task to reference that option. For more information, see <a href="command_line_interface.html#sec:disambiguate_task_options_from_built_in_options">Disambiguate Task Options from Built-in Options</a>.</p> </li> </ul> </div> </div> </div> </div> <div class="sect1"> <h2 id="verification_failures"><a class="anchor" href="#verification_failures"></a><a class="link" href="#verification_failures">Verification failures</a></h2> <div class="sectionbody"> <div class="paragraph"> <p>Normally, exceptions thrown during task execution result in a failure that immediately terminates a build. The outcome of the task will be <code>FAILED</code>, the result of the build will be <code>FAILED</code>, and no further tasks will be executed. When <a href="command_line_interface.html#sec:continue_build_on_failure">running with the <code>--continue</code> flag</a>, Gradle will continue to run other requested tasks in the build after encountering a task failure. However, any tasks that depend on a failed task will not be executed.</p> </div> <div class="paragraph"> <p>There is a special type of exception that behaves differently when downstream tasks only rely on the outputs of a failing task. A task can throw a subtype of <a href="../javadoc/org/gradle/api/tasks/VerificationException.html">VerificationException</a> to indicate that it has failed in a controlled manner such that its output is still valid for consumers. A task depends on the <strong>outcome</strong> of another task when it directly depends on it using <code>dependsOn</code>. When Gradle is run with <code>--continue</code>, consumer tasks that depend on a producer task’s output (via a relationship between task inputs and outputs) can still run after the producer fails.</p> </div> <div class="paragraph"> <p>A failed unit test, for instance, will cause a failing outcome for the test task. However, this doesn’t prevent another task from reading and processing the (valid) test results the task produced. Verification failures are used in exactly this manner by the <a href="test_report_aggregation_plugin.html#test_report_aggregation_plugin"><code>Test Report Aggregation Plugin</code></a>.</p> </div> <div class="paragraph"> <p>Verification failures are also useful for tasks that need to report a failure even after producing useful output consumable by other tasks.</p> </div> <div class="exampleblock"> <div class="content"> <div class="exampleblock testable-sample multi-language-sample"> <div class="content"> <div class="listingblock"> <div class="title">build.gradle.kts</div> <div class="content"> <pre class="prettyprint highlight"><code data-lang="kotlin">val process = tasks.register("process") { val outputFile = layout.buildDirectory.file("processed.log") outputs.files(outputFile) <i class="conum" data-value="1"></i><b>(1)</b> doLast { val logFile = outputFile.get().asFile logFile.appendText("Step 1 Complete.") <i class="conum" data-value="2"></i><b>(2)</b> throw VerificationException("Process failed!") <i class="conum" data-value="3"></i><b>(3)</b> logFile.appendText("Step 2 Complete.") <i class="conum" data-value="4"></i><b>(4)</b> } } tasks.register("postProcess") { inputs.files(process) <i class="conum" data-value="5"></i><b>(5)</b> doLast { println("Results: ${inputs.files.singleFile.readText()}") <i class="conum" data-value="6"></i><b>(6)</b> } }</code></pre> </div> </div> </div> </div> <div class="exampleblock testable-sample multi-language-sample"> <div class="content"> <div class="listingblock"> <div class="title">build.gradle</div> <div class="content"> <pre class="prettyprint highlight"><code data-lang="groovy">tasks.register("process") { def outputFile = layout.buildDirectory.file("processed.log") outputs.files(outputFile) <i class="conum" data-value="1"></i><b>(1)</b> doLast { def logFile = outputFile.get().asFile logFile << "Step 1 Complete." <i class="conum" data-value="2"></i><b>(2)</b> throw new VerificationException("Process failed!") <i class="conum" data-value="3"></i><b>(3)</b> logFile << "Step 2 Complete." <i class="conum" data-value="4"></i><b>(4)</b> } } tasks.register("postProcess") { inputs.files(tasks.named("process")) <i class="conum" data-value="5"></i><b>(5)</b> doLast { println("Results: ${inputs.files.singleFile.text}") <i class="conum" data-value="6"></i><b>(6)</b> } }</code></pre> </div> </div> </div> </div> </div> </div> <div class="listingblock"> <div class="content"> <pre>$ gradle postProcess --continue > Task :process FAILED > Task :postProcess Results: Step 1 Complete. 2 actionable tasks: 2 executed FAILURE: Build failed with an exception.</pre> </div> </div> <div class="colist arabic"> <table> <tr> <td><i class="conum" data-value="1"></i><b>1</b></td> <td><strong>Register Output</strong>: The <code>process</code> task writes its output to a log file.</td> </tr> <tr> <td><i class="conum" data-value="2"></i><b>2</b></td> <td><strong>Modify Output</strong>: The task writes to its output file as it executes.</td> </tr> <tr> <td><i class="conum" data-value="3"></i><b>3</b></td> <td><strong>Task Failure</strong>: The task throws a <code>VerificationException</code> and fails at this point.</td> </tr> <tr> <td><i class="conum" data-value="4"></i><b>4</b></td> <td><strong>Continue to Modify Output</strong>: This line never runs due to the exception stopping the task.</td> </tr> <tr> <td><i class="conum" data-value="5"></i><b>5</b></td> <td><strong>Consume Output</strong>: The <code>postProcess</code> task depends on the output of the <code>process</code> task due to using that task’s outputs as its own inputs.</td> </tr> <tr> <td><i class="conum" data-value="6"></i><b>6</b></td> <td><strong>Use Partial Result</strong>: With the <code>--continue</code> flag set, Gradle still runs the requested <code>postProcess</code> task despite the <code>process</code> task’s failure. <code>postProcess</code> can read and display the partial (though still valid) result.</td> </tr> </table> </div> </div> </div> </div> <div id="feedback-container" class="feedback-container"> <div class="feedback-buttons"> <label id="feedback-container-label"> Was this page helpful?</label> <button id="thumbs-up" onclick="showFeedbackForm(true)"> <!-- Thumbs Up SVG --> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24px" height="24px" viewBox="0 0 24 24" version="1.1"> <g id="surface1"> <path style=" stroke:none;fill-rule:nonzero;fill:rgb(10.588235%,65.882353%,79.607843%);fill-opacity:1;" d="M 3 21.375 C 3 21.582031 2.832031 21.75 2.625 21.75 C 2.417969 21.75 2.25 21.582031 2.25 21.375 C 2.25 21.167969 2.417969 21 2.625 21 C 2.832031 21 3 21.167969 3 21.375 Z M 3 21.375 "/> <path style=" stroke:none;fill-rule:nonzero;fill:rgb(10.588235%,65.882353%,79.607843%);fill-opacity:1;" d="M 5.25 9.75 C 5.25 8.921875 4.578125 8.25 3.75 8.25 L 1.5 8.25 C 0.671875 8.25 0 8.921875 0 9.75 L 0 22.5 C 0 23.328125 0.671875 24 1.5 24 L 3.75 24 C 4.578125 24 5.25 23.328125 5.25 22.5 Z M 2.625 22.5 C 2.003906 22.5 1.5 21.996094 1.5 21.375 C 1.5 20.753906 2.003906 20.25 2.625 20.25 C 3.246094 20.25 3.75 20.753906 3.75 21.375 C 3.75 21.996094 3.246094 22.5 2.625 22.5 Z M 2.625 22.5 "/> <path style=" stroke:none;fill-rule:nonzero;fill:rgb(10.588235%,65.882353%,79.607843%);fill-opacity:1;" d="M 24 10.5 C 24 9.257812 22.992188 8.25 21.75 8.25 L 15.367188 8.25 L 15.375 8.25 L 16.125 1.5 C 16.203125 0.679688 15.640625 0 14.8125 0 L 13.3125 0 C 12.375 0 11.984375 0.65625 11.625 1.5 L 8.625 8.25 C 7.816406 10.1875 6.75 10.5 6 10.5 L 6 21.832031 C 6.449219 21.9375 7.019531 22.1875 7.578125 22.761719 C 8.746094 23.960938 10.140625 24 10.875 24 L 19.5 24 C 20.742188 24 21.75 22.992188 21.75 21.75 C 21.75 21.101562 21.472656 20.515625 21.035156 20.105469 C 21.890625 19.789062 22.5 18.964844 22.5 18 C 22.5 17.351562 22.222656 16.765625 21.785156 16.355469 C 22.640625 16.039062 23.25 15.214844 23.25 14.25 C 23.25 13.601562 22.972656 13.015625 22.535156 12.605469 C 23.390625 12.289062 24 11.464844 24 10.5 Z M 24 10.5 "/> </g> </svg> </button> <button id="thumbs-down" onclick="showFeedbackForm(false)"> <!-- Thumbs Down SVG --> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24px" height="24px" viewBox="0 0 24 24" version="1.1"> <g id="surface1"> <path style=" stroke:none;fill-rule:nonzero;fill:rgb(10.588235%,65.882353%,79.607843%);fill-opacity:1;" d="M 3 13.125 C 3 13.332031 2.832031 13.5 2.625 13.5 C 2.417969 13.5 2.25 13.332031 2.25 13.125 C 2.25 12.917969 2.417969 12.75 2.625 12.75 C 2.832031 12.75 3 12.917969 3 13.125 Z M 3 13.125 "/> <path style=" stroke:none;fill-rule:nonzero;fill:rgb(10.588235%,65.882353%,79.607843%);fill-opacity:1;" d="M 0 1.5 C 0 0.671875 0.671875 0 1.5 0 L 3.75 0 C 4.578125 0 5.25 0.671875 5.25 1.5 L 5.25 14.25 C 5.25 15.078125 4.578125 15.75 3.75 15.75 L 1.5 15.75 C 0.671875 15.75 0 15.078125 0 14.25 Z M 2.625 14.25 C 3.246094 14.25 3.75 13.746094 3.75 13.125 C 3.75 12.503906 3.246094 12 2.625 12 C 2.003906 12 1.5 12.503906 1.5 13.125 C 1.5 13.746094 2.003906 14.25 2.625 14.25 Z M 2.625 14.25 "/> <path style=" stroke:none;fill-rule:nonzero;fill:rgb(10.588235%,65.882353%,79.607843%);fill-opacity:1;" d="M 24 13.5 C 24 14.742188 22.992188 15.75 21.75 15.75 L 15.367188 15.75 L 15.375 15.75 L 16.125 22.5 C 16.203125 23.320312 15.640625 24 14.8125 24 L 13.3125 24 C 12.375 24 11.984375 23.34375 11.625 22.5 L 8.625 15.75 C 7.816406 13.8125 6.75 13.5 6 13.5 L 6 2.167969 C 6.449219 2.0625 7.019531 1.8125 7.578125 1.238281 C 8.746094 0.0390625 10.140625 0 10.875 0 L 19.5 0 C 20.742188 0 21.75 1.007812 21.75 2.25 C 21.75 2.898438 21.472656 3.484375 21.035156 3.894531 C 21.890625 4.210938 22.5 5.035156 22.5 6 C 22.5 6.648438 22.222656 7.234375 21.785156 7.644531 C 22.640625 7.960938 23.25 8.785156 23.25 9.75 C 23.25 10.398438 22.972656 10.984375 22.535156 11.394531 C 23.390625 11.710938 24 12.535156 24 13.5 Z M 24 13.5 "/> </g> </svg> </button> </div> <div id="feedback-form" class="hidden-feedback-form"> <form> <label for="feedback">Additional Feedback:</label> <textarea id="feedback" name="feedback" rows="4" cols="50" placeholder="Tell us more about your experience."></textarea> <div>You can <a href="https://github.com/gradle/gradle/issues/new?assignees=&labels=a%3Adocumentation%2Cto-triage&projects=&template=40_contributor_documentation.yml"> submit issues</a> directly on Github.</div> <button id="feedback-button" type="button" onclick="submitAdditionalFeedback()" disabled> Submit Feedback <div class="animate-flicker"></div> </button> </form> </div> </div><script src="https://cdnjs.cloudflare.com/ajax/libs/prettify/r298/run_prettify.min.js"></script> </div> <!-- end div class="chapter" --> <footer class="site-layout__footer site-footer" itemscope="itemscope" itemtype="https://schema.org/WPFooter"> <nav class="site-footer__navigation" itemtype="https://schema.org/SiteNavigationElement"> <section class="site-footer__links"> <div class="site-footer__link-group"> <header><strong>Docs</strong></header> <ul class="site-footer__links-list"> <li itemprop="name"><a href="/release-notes.html" itemprop="url">Release Notes</a></li> <li itemprop="name"><a href="/dsl/" itemprop="url">Groovy DSL</a></li> <li itemprop="name"><a href="/kotlin-dsl/" itemprop="url">Kotlin DSL</a></li> <li itemprop="name"><a href="/javadoc/" itemprop="url">Javadoc</a></li> </ul> </div> <div class="site-footer__link-group"> <header><strong>News</strong></header> <ul class="site-footer__links-list"> <li itemprop="name"><a href="https://blog.gradle.org/" itemprop="url">Blog</a></li> <li itemprop="name"><a href="https://newsletter.gradle.org/" itemprop="url">Newsletter</a></li> <li itemprop="name"><a href="https://twitter.com/gradle" itemprop="url">Twitter</a></li> <li itemprop="name"><a href="https://status.gradle.com/" itemprop="url">Status</a></li> </ul> </div> <div class="site-footer__link-group"> <header><strong>Products</strong></header> <ul class="site-footer__links-list"> <li itemprop="name"><a href="https://gradle.com/develocity/" itemprop="url">Develocity</a></li> <li itemprop="name"><a href="https://gradle.com/build-scans/" itemprop="url">Build Scan™</a></li> <li itemprop="name"><a href="https://gradle.com/build-cache/" itemprop="url">Build Cache</a></li> <li itemprop="name"><a href="https://gradle.org/services/" itemprop="url">Services</a></li> </ul> </div> <div class="site-footer__link-group"> <header><strong>Get Help</strong></header> <ul class="site-footer__links-list"> <li itemprop="name"><a href="https://discuss.gradle.org/c/help-discuss" itemprop="url">Forums</a></li> <li itemprop="name"><a href="https://github.com/gradle/" itemprop="url">GitHub</a></li> <li itemprop="name"><a href="https://gradle.org/training/" itemprop="url">Events</a></li> <li itemprop="name"><a href="https://dpeuniversity.gradle.com/" itemprop="url">DPE University</a></li> </ul> </div> </section> <section class="site-footer__subscribe-newsletter" id="newsletter-form-container"> <header class="newsletter-form__header"><h5>Stay <code>UP-TO-DATE</code> on new features and news</h5></header> <p class="disclaimer">By entering your email, you agree to our <a href="https://gradle.com/legal/terms-of-service/">Terms</a> and <a href="https://gradle.com/legal/privacy/">Privacy Policy</a>, including receipt of emails. You can unsubscribe at any time.</p> <div class="newsletter-form__container"> <form id="newsletter-form" class="newsletter-form" action="https://go.gradle.com/l/68052/2018-09-07/bk6wml" method="post"> <input id="email" class="email" name="email" type="email" placeholder="name@email.com" pattern="[^@\s]+@[^@\s]+\.[^@\s]+" maxlength="255" required=""/> <button id="submit" class="submit" type="submit">Subscribe</button> </form> </div> </section> </nav> </footer> </div> <!-- end div class="content" --> </main> <div class="site-footer-secondary"> <div class="site-footer-secondary__contents"> <div class="site-footer__copy">© <a href="https://gradle.com">Gradle Inc.</a> <time>2023</time> All rights reserved. </div> <div class="site-footer__logo"><a href="/"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 90 66.06"> <title>Gradle</title> <path class="cls-1" d="M85.11,4.18a14.27,14.27,0,0,0-19.83-.34,1.38,1.38,0,0,0,0,2L67,7.6a1.36,1.36,0,0,0,1.78.12A8.18,8.18,0,0,1,79.5,20.06C68.17,31.38,53.05-.36,18.73,16a4.65,4.65,0,0,0-2,6.54l5.89,10.17a4.64,4.64,0,0,0,6.3,1.73l.14-.08-.11.08L31.53,33a60.29,60.29,0,0,0,8.22-6.13,1.44,1.44,0,0,1,1.87-.06h0a1.34,1.34,0,0,1,.06,2A61.61,61.61,0,0,1,33,35.34l-.09,0-2.61,1.46a7.34,7.34,0,0,1-3.61.94,7.45,7.45,0,0,1-6.47-3.71l-5.57-9.61C4,32-2.54,46.56,1,65a1.36,1.36,0,0,0,1.33,1.11H8.61A1.36,1.36,0,0,0,10,64.87a9.29,9.29,0,0,1,18.42,0,1.35,1.35,0,0,0,1.34,1.19H35.9a1.36,1.36,0,0,0,1.34-1.19,9.29,9.29,0,0,1,18.42,0A1.36,1.36,0,0,0,57,66.06H63.1a1.36,1.36,0,0,0,1.36-1.34c.14-8.6,2.46-18.48,9.07-23.43C96.43,24.16,90.41,9.48,85.11,4.18ZM61.76,30.05l-4.37-2.19h0a2.74,2.74,0,1,1,4.37,2.2Z"/> </svg> </a></div> <div class="site-footer-secondary__links"> <a href="https://gradle.com/careers/">Careers</a> | <a href="https://gradle.com/legal/privacy/">Privacy</a> | <a href="https://gradle.com/legal/terms-of-service/">Terms of Service</a> | <a href="https://gradle.org/contact/">Contact</a> </div> </div> </div> </div> <!-- end div class="layout" --> <script type="text/javascript"> // Polyfill Element.matches() if (!Element.prototype.matches) { Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector; } // Polyfill Element.closest() if (!Element.prototype.closest) { Element.prototype.closest = function (s) { var el = this; if (!document.documentElement.contains(el)) return null; do { if (typeof el.matches === "function" && el.matches(s)) return el; el = el.parentElement || el.parentNode; } while (el !== null); return null; }; } function getCurrentChapterFileName(givenUrl) { var currentChapterFileName = givenUrl.substr(givenUrl.lastIndexOf("/") + 1); if (currentChapterFileName === "index.html" || currentChapterFileName === "") { currentChapterFileName = givenUrl.substr(0, givenUrl.lastIndexOf("/")); currentChapterFileName = currentChapterFileName.substr(currentChapterFileName.lastIndexOf("/") + 1) + "/index.html"; } return currentChapterFileName; } // The media query indicating that a device is a desktop. // The `min-width: 64rem` definition should be aligned to // the one of `css/manual.css`. const desktopMediaQuery = window.matchMedia("screen and (min-width: 64rem)"); [].forEach.call(document.querySelectorAll(".docs-navigation a[href$='/" + getCurrentChapterFileName(window.location.pathname) + "']"), function (link) { // Add "active" to all links same as current URL link.classList.add("active"); // Expand all parent navigation var parentListEl = link.closest("li"); while (parentListEl !== null) { var dropDownEl = parentListEl.querySelector(".nav-dropdown"); if (dropDownEl !== null) { dropDownEl.classList.add("expanded"); } parentListEl = parentListEl.parentNode.closest("li"); } // Only scroll if the device is a desktop. // // Mobile's `docs-navigation` is always at bottom of `content`, // so we should not slide down to where `docs-navigation` lays. if (desktopMediaQuery.matches) { // Scroll to center of the page link.scrollIntoView({behavior: 'auto', block: 'center', inline: 'center'}) } }); // Expand/contract multi-level side navigation [].forEach.call(document.querySelectorAll(".docs-navigation .nav-dropdown"), function registerSideNavActions(collapsibleElement) { collapsibleElement.addEventListener("click", function toggleExpandedSideNav(evt) { evt.preventDefault(); evt.target.classList.toggle("expanded"); evt.target.setAttribute("aria-expanded", evt.target.classList.contains("expanded").toString()); return false; }, false); }); // Fix a weird issue making the initial screen always at the bottom. document.querySelector(".content").scrollIntoView(true); </script> </body> </html>