Note:
-An R Notebook is an R Markdown document with chunks that can be executed independently and interactively, with output visible immediately beneath the input.
-Notebook output are available as HTML, PDF, Word, or Latex.
-This Notebook as HTML is preferably open with Google Chrome.
-R-Code can be extracted as Rmd file under the button “Code” in the notebook.
-This Notebook using iterative development. It means the process starts with a simple implementation of a small set of idea requirements and iteratively enhances the evolving versions until the complete version is implemented and perfect.
#link: https://de.pngtree.com/freepng/vector-color-drop-base-effect_137484.html
Color Theory 101
Let’s first go back to high school art class to discuss the basics of color.
Primary Colors:
#link: https://marketingaccesspass.com/what-colors-make-green-what-two-colors-make-green/
It cannot be created by mixing other colors. There are three primary colors:
Secondary Colors:
#link: https://www.colorpsychology.org/primary-secondary-tertiary-colors/
It combined any two of the three primary colors (Red, Yellow, Blue). There are three secondary colors: orange, purple, and green.
- Red + Yellow = Orange
- Blue + Red = Purple
- Yellow + Blue = Green
Tertiary Colors:
#link: https://www.vectorstock.com/royalty-free-vector/watercolor-tertiary-colors-chart-vector-4121992
It created when you mix a primary color with secondary color.
There are six tertiary colors that fit this requirement:
- Red + Purple = Red-Purple (magenta)
- Red + Orange = Red-Orange (vermillion)
- Blue + Purple = Blue-Purple (violet)
- Blue + Green = Blue-Green (teal)
- Yellow + Orange = Yellow-Orange (amber)
- Yellow + Green = Yellow-Green (chartreuse)
The Color Theory Wheel
Color wheel is a circle graph that charts each primary, secondary, and tertiary color. The color wheel helps you to visualize the relationships between colors.
#link: https://blog.hubspot.com/marketing/color-theory-design
These color wheel create the color variants described below:
- Hue: all of the primary and secondary colors, for instance, are “hues.”
- Tint: the opposite of a shade (add white to any given hue)
- Tone (or Saturation): add both white and black to a color to create a tone
- Shade: light and dark versions of the same hue (add black to any given hue)
How to Choose a Color Scheme
1. Consider your color context.
#Link: https://blog.hubspot.com/marketing/color-theory-design
The contrast with another color. The middle of each of the circles is the same size, shape, and color. The only thing that changes is the background color. There are logical rules for how to create color schemes that work together.
2. Refer to a color wheel to identify analogous colors.
Analogous color schemes are formed by pairing one or more color.
#Link: https://blog.hubspot.com/marketing/color-theory-design
This color scheme could be create warmer (with yellow) or cooloer (with purple)
#Link: https://blog.hubspot.com/marketing/color-theory-design
3. Refer to a color wheel to identify complementary colors.
Use of two colors directly across from each other.
#Link: https://blog.hubspot.com/marketing/color-theory-design
The two across color scheme is also great for graphs. High contrast helps you highlight important points.
#Link: https://blog.hubspot.com/marketing/color-theory-design
4. Focus on monochromatic colors in the same hue.
It created shades and tints in one hue.
#Link: https://blog.hubspot.com/marketing/color-theory-design
Example of monochromatic color under the red hue.
#Link: https://blog.hubspot.com/marketing/color-theory-design
5. Use a triadic color scheme to create high contrast.
Triad color schemes (3 colors) are used to create high contrast between each color.
#Link: https://blog.hubspot.com/marketing/color-theory-design
changing up the intensity of the colors for highlighting important points and terms.
#Link: https://blog.hubspot.com/marketing/color-theory-design
6. Create a split complementary color scheme.
One dominant color and the two colors adjacent to the dominant color’s complement.
#Link: https://blog.hubspot.com/marketing/color-theory-design
An example is like this pallet.
#Link: https://blog.hubspot.com/marketing/color-theory-design
7. Think beyond the presets, but start with just one color.
Extra tips for choosing colors:
- Don’t stick with automatically presets color in every program or software. Use the color wheel theory or online color wheel designer
- Start with one color you like
- Save your color schemes
- Practice makes perfect
Logical rules to choosing color
Defining the basics for choosing colors:
#Link: https://coloursandmaterials.wordpress.com/2014/09/16/colour-system/
Below are the explanation of this logical rules:
#Link: https://expertphotography.com/color-in-photography/
#Link: https://mason.gmu.edu/~kshiffl4/375/module5-4.html
#Link: https://www.123rf.com/photo_82958382_stock-vector-vector-illustration-of-color-circle-complementary-analogous-similar-triadic-tetradic-dual-complement.html
Colortools: R package
Developed by Gaston Sanchez for generating color schemes in R (without leaving R IDE).
Install and load colortools:
install.packages("colortools")
Installing package into 㤼㸱C:/Users/cevi herdian/Documents/R/win-library/3.5㤼㸲
(as 㤼㸱lib㤼㸲 is unspecified)
trying URL 'https://cran.rstudio.com/bin/windows/contrib/3.5/colortools_0.1.5.zip'
Content type 'application/zip' length 70483 bytes (68 KB)
downloaded 68 KB
package ‘colortools’ successfully unpacked and MD5 sums checked
The downloaded binary packages are in
C:\Users\cevi herdian\AppData\Local\Temp\RtmpOOcOAq\downloaded_packages
package 㤼㸱colortools㤼㸲 was built under R version 3.5.2
Color Wheel:
Historically, there have been many variations of the basic design, but the most popular version is 12 colors based on the RYB (Red, Yellow, Blue).
Create color wheels by using the function wheel
and some given color.
# color wheel for 'pink'
wheel("pink")
[1] "#FFC0CB" "#FFD4C0" "#FFF4C0" "#EBFFC0" "#CBFFC0" "#C0FFD5" "#C0FFF4" "#C0EBFF" "#C0CBFF"
[10] "#D5C0FF" "#F4C0FF" "#FFC0EA"
Analogous (Adjacent) Color Scheme:
Three colors from a 12 part color wheel.
# analogous (adjacent) colors of 'pink'
analogous("pink")
[1] "#FFC0CB" "#FFD4C0" "#FFC0EA"
Complementary (Opposite) Color Scheme:
Oposite colors from the color wheel (2 colors).
# complementary (opposite) color of 'pink'
complementary("pink")
[1] "#FFC0CB" "#C0FFF4"
Split Complementary Color Scheme:
Complementary color scheme that uses two colors on either side of a directly opposite color.
# split complementary colors of 'pink'
splitComp("pink")
[1] "#FFC0CB" "#C0FFD5" "#C0EBFF"
Triadic Color Scheme:
Three colors from around the color wheel.
# triadic colors of 'pink'
triadic("pink")
[1] "#FFC0CB" "#CBFFC0" "#C0CBFF"
Tetradic Color Scheme:
Four colors arranged into two complementary pairs from color wheel.
# tetradic colors of 'pink'
tetradic("pink")
[1] "#FFC0CB" "#FFF4C0" "#C0FFF4" "#C0CBFF"
Square Color Scheme:
Similar with tetradic scheme, but with all four colors around the color wheel (not complementary).
# square colors of 'pink'
square("pink")
[1] "#FFC0CB" "#EBFFC0" "#C0FFF4" "#D5C0FF"
Sequential Colors:
sequential
get a sequence of colors from high to low.
# sequential colors of 'pink'
sequential("pink")
[1] "#FFFFFFFF" "#FFF2F4FF" "#FFE6EAFF" "#FFD9DFFF" "#FFCCD5FF" "#FFBFCAFF" "#FFB3C0FF"
[8] "#FFA6B5FF" "#FF99ABFF" "#FF8CA0FF" "#FF8096FF" "#FF738BFF" "#FF6681FF" "#FF5976FF"
[15] "#FF4C6CFF" "#FF4061FF" "#FF3357FF" "#FF264CFF" "#FF1942FF" "#FF0D37FF" "#FF002DFF"
Another example:
# sequential sequence for saturation, with fix value s=0.8, alpha=0.5,
# percentage 10, and fun='log'
sequential("pink", 10, what = "value", s = 0.7, alpha = 0.5, fun = "log")
[1] "#00000080" "#18070A80" "#2E0E1480" "#43141C80" "#561A2480" "#671F2C80" "#78243380"
[8] "#87293980" "#962D3F80" "#A4314580" "#B1354B80"
Small assorment of color palettes:
A function pals
contains an assortment of nice color palettes.
To get the names of the colors:
# color names of palette 'cheer'
pals("fish")
[1] "#69D2E7" "#A7DBD8" "#E0E4CC" "#F38630" "#FA6900"
Visualize the colors in a ‘pizza’ wheel:
# color names of palette 'cheer'
pizza(pals("fish"))
Visualizing R color palettes:
A pie chart with given colors.
# terrain colors (12)
pizza(terrain.colors(12), bg = "pink")
LS0tDQp0aXRsZTogIkNvbG9yb2xvZ3kiDQpzdWJ0aXRsZTogIlRoZSBHcmFtbWFyIG9mIGNvbG9yaXppbmciDQphdXRob3I6ICJDZXZpIEhlcmRpYW4sIEIuIFNjIg0KZGF0ZTogIjI1LjEyLjIwMTgiDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6DQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgaGlnaGxpZ2h0OiBweWdtZW50cw0KICAgIHRoZW1lOiBjb3Ntbw0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiA1DQogICAgdG9jX2Zsb2F0OiB5ZXMNCiAgaHRtbF9kb2N1bWVudDoNCiAgICBkZl9wcmludDogcGFnZWQNCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogJzUnDQogIHBkZl9kb2N1bWVudDoNCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogJzUnDQogIHdvcmRfZG9jdW1lbnQ6DQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6ICc1Jw0KLS0tDQoNCg0KDQoNCioqTm90ZToqKg0KDQotQW4gUiBOb3RlYm9vayBpcyBhbiBSIE1hcmtkb3duIGRvY3VtZW50IHdpdGggY2h1bmtzIHRoYXQgY2FuIGJlIGV4ZWN1dGVkIGluZGVwZW5kZW50bHkgYW5kIGludGVyYWN0aXZlbHksIHdpdGggb3V0cHV0IHZpc2libGUgaW1tZWRpYXRlbHkgYmVuZWF0aCB0aGUgaW5wdXQuDQoNCi1Ob3RlYm9vayBvdXRwdXQgYXJlIGF2YWlsYWJsZSBhcyBIVE1MLCBQREYsIFdvcmQsIG9yIExhdGV4LiANCg0KLVRoaXMgTm90ZWJvb2sgYXMgSFRNTCBpcyBwcmVmZXJhYmx5IG9wZW4gd2l0aCBHb29nbGUgQ2hyb21lLg0KDQotUi1Db2RlIGNhbiBiZSBleHRyYWN0ZWQgYXMgUm1kIGZpbGUgdW5kZXIgdGhlIGJ1dHRvbiAiQ29kZSIgaW4gdGhlIG5vdGVib29rLg0KDQotVGhpcyBOb3RlYm9vayB1c2luZyBpdGVyYXRpdmUgZGV2ZWxvcG1lbnQuIEl0IG1lYW5zIHRoZSBwcm9jZXNzIHN0YXJ0cyB3aXRoIGEgc2ltcGxlIGltcGxlbWVudGF0aW9uIG9mIGEgc21hbGwgc2V0IG9mIGlkZWEgcmVxdWlyZW1lbnRzIGFuZCBpdGVyYXRpdmVseSBlbmhhbmNlcyB0aGUgZXZvbHZpbmcgdmVyc2lvbnMgdW50aWwgdGhlIGNvbXBsZXRlIHZlcnNpb24gaXMgaW1wbGVtZW50ZWQgYW5kIHBlcmZlY3QuDQoNCg0KX19fX19fX19fX19fDQoNCg0KPEJyPg0KDQohW10oY292ZXIuanBnKQ0KDQpgYGB7cn0NCg0KI2xpbms6IGh0dHBzOi8vZGUucG5ndHJlZS5jb20vZnJlZXBuZy92ZWN0b3ItY29sb3ItZHJvcC1iYXNlLWVmZmVjdF8xMzc0ODQuaHRtbA0KDQpgYGANCg0KPEJyPg0KDQojTGVhcm5pbmcgb2JqZWN0aXZlcyANCg0KKiBXaHkgQ29sb3IgTWF0dGVycw0KDQoqIENob29zZSB0aGUgcmlnaHQgY29sb3IgZm9yIGluc2lnaGZ1bCB2aXN1YWxpemF0aW9uDQoNCjxCcj4NCg0KI0NvbG9yIFRoZW9yeSAxMDEgDQoNCkxldCdzIGZpcnN0IGdvIGJhY2sgdG8gaGlnaCBzY2hvb2wgYXJ0IGNsYXNzIHRvIGRpc2N1c3MgdGhlIGJhc2ljcyBvZiBjb2xvci4NCg0KKipQcmltYXJ5IENvbG9yczoqKiANCg0KIVtdKDEuanBnKQ0KDQoNCg0KDQpgYGB7cn0NCg0KI2xpbms6IGh0dHBzOi8vbWFya2V0aW5nYWNjZXNzcGFzcy5jb20vd2hhdC1jb2xvcnMtbWFrZS1ncmVlbi13aGF0LXR3by1jb2xvcnMtbWFrZS1ncmVlbi8NCg0KYGBgDQoNCg0KDQpJdCBjYW5ub3QgYmUgY3JlYXRlZCBieSBtaXhpbmcgb3RoZXIgY29sb3JzLiBUaGVyZSBhcmUgdGhyZWUgcHJpbWFyeSBjb2xvcnM6DQoNCiogKipSZWQqKg0KKiAqKlllbGxvdyoqDQoqICoqQmx1ZSoqDQoNCg0KKipTZWNvbmRhcnkgQ29sb3JzOioqDQoNCiFbXSgyLnBuZykNCg0KYGBge3J9DQoNCiNsaW5rOiBodHRwczovL3d3dy5jb2xvcnBzeWNob2xvZ3kub3JnL3ByaW1hcnktc2Vjb25kYXJ5LXRlcnRpYXJ5LWNvbG9ycy8NCg0KYGBgDQoNCg0KSXQgY29tYmluZWQgYW55IHR3byBvZiB0aGUgdGhyZWUgcHJpbWFyeSBjb2xvcnMgKFJlZCwgWWVsbG93LCBCbHVlKS4gVGhlcmUgYXJlIHRocmVlIHNlY29uZGFyeSBjb2xvcnM6IG9yYW5nZSwgcHVycGxlLCBhbmQgZ3JlZW4uDQoNCiogKipSZWQgKyBZZWxsb3cgPSBPcmFuZ2UqKg0KKiAqKkJsdWUgKyBSZWQgPSBQdXJwbGUqKg0KKiAqKlllbGxvdyArIEJsdWUgPSBHcmVlbioqDQoNCg0KKipUZXJ0aWFyeSBDb2xvcnM6KioNCg0KIVtdKDNhLlBORykNCg0KYGBge3J9DQoNCiNsaW5rOiBodHRwczovL3d3dy52ZWN0b3JzdG9jay5jb20vcm95YWx0eS1mcmVlLXZlY3Rvci93YXRlcmNvbG9yLXRlcnRpYXJ5LWNvbG9ycy1jaGFydC12ZWN0b3ItNDEyMTk5Mg0KDQpgYGANCg0KDQpJdCBjcmVhdGVkIHdoZW4geW91IG1peCBhIHByaW1hcnkgY29sb3Igd2l0aCBzZWNvbmRhcnkgY29sb3IuDQoNClRoZXJlIGFyZSBzaXggdGVydGlhcnkgY29sb3JzIHRoYXQgZml0IHRoaXMgcmVxdWlyZW1lbnQ6DQoNCiogKipSZWQgKyBQdXJwbGUgPSBSZWQtUHVycGxlIChtYWdlbnRhKSoqDQoqICoqUmVkICsgT3JhbmdlID0gUmVkLU9yYW5nZSAodmVybWlsbGlvbikqKg0KKiAqKkJsdWUgKyBQdXJwbGUgPSBCbHVlLVB1cnBsZSAodmlvbGV0KSoqDQoqICoqQmx1ZSArIEdyZWVuID0gQmx1ZS1HcmVlbiAodGVhbCkqKg0KKiAqKlllbGxvdyArIE9yYW5nZSA9IFllbGxvdy1PcmFuZ2UgKGFtYmVyKSoqDQoqICoqWWVsbG93ICsgR3JlZW4gPSBZZWxsb3ctR3JlZW4gKGNoYXJ0cmV1c2UpKioNCg0KDQo8QnI+DQoNCiNUaGUgQ29sb3IgVGhlb3J5IFdoZWVsDQoNCkNvbG9yIHdoZWVsIGlzIGEgY2lyY2xlIGdyYXBoIHRoYXQgY2hhcnRzIGVhY2ggcHJpbWFyeSwgc2Vjb25kYXJ5LCBhbmQgdGVydGlhcnkgY29sb3IuIFRoZSBjb2xvciB3aGVlbCBoZWxwcyB5b3UgdG8gdmlzdWFsaXplIHRoZSByZWxhdGlvbnNoaXBzIGJldHdlZW4gY29sb3JzLg0KDQohW10oNC5QTkcpDQoNCg0KDQpgYGB7cn0NCg0KI2xpbms6IGh0dHBzOi8vYmxvZy5odWJzcG90LmNvbS9tYXJrZXRpbmcvY29sb3ItdGhlb3J5LWRlc2lnbg0KDQpgYGANCg0KVGhlc2UgY29sb3Igd2hlZWwgY3JlYXRlIHRoZSBjb2xvciB2YXJpYW50cyBkZXNjcmliZWQgYmVsb3c6DQoNCiogSHVlOiBhbGwgb2YgdGhlIHByaW1hcnkgYW5kIHNlY29uZGFyeSBjb2xvcnMsIGZvciBpbnN0YW5jZSwgYXJlICJodWVzLiINCiogVGludDogdGhlIG9wcG9zaXRlIG9mIGEgc2hhZGUgKGFkZCB3aGl0ZSB0byBhbnkgZ2l2ZW4gaHVlKQ0KKiBUb25lIChvciBTYXR1cmF0aW9uKTogYWRkIGJvdGggd2hpdGUgYW5kIGJsYWNrIHRvIGEgY29sb3IgdG8gY3JlYXRlIGEgdG9uZQ0KKiBTaGFkZTogbGlnaHQgYW5kIGRhcmsgdmVyc2lvbnMgb2YgdGhlIHNhbWUgaHVlIChhZGQgYmxhY2sgdG8gYW55IGdpdmVuIGh1ZSkNCg0KPEJyPg0KDQojSG93IHRvIENob29zZSBhIENvbG9yIFNjaGVtZQ0KDQoqKjEuIENvbnNpZGVyIHlvdXIgY29sb3IgY29udGV4dC4qKg0KDQohW10oNS5QTkcpDQoNCmBgYHtyfQ0KDQojTGluazogaHR0cHM6Ly9ibG9nLmh1YnNwb3QuY29tL21hcmtldGluZy9jb2xvci10aGVvcnktZGVzaWduDQoNCmBgYA0KDQoNClRoZSBjb250cmFzdCB3aXRoIGFub3RoZXIgY29sb3IuIFRoZSBtaWRkbGUgb2YgZWFjaCBvZiB0aGUgY2lyY2xlcyBpcyB0aGUgc2FtZSBzaXplLCBzaGFwZSwgYW5kIGNvbG9yLiBUaGUgb25seSB0aGluZyB0aGF0IGNoYW5nZXMgaXMgdGhlIGJhY2tncm91bmQgY29sb3IuIFRoZXJlIGFyZSBsb2dpY2FsIHJ1bGVzIGZvciBob3cgdG8gY3JlYXRlIGNvbG9yIHNjaGVtZXMgdGhhdCB3b3JrIHRvZ2V0aGVyLg0KDQoNCioqMi4gUmVmZXIgdG8gYSBjb2xvciB3aGVlbCB0byBpZGVudGlmeSBhbmFsb2dvdXMgY29sb3JzLioqDQoNCkFuYWxvZ291cyBjb2xvciBzY2hlbWVzIGFyZSBmb3JtZWQgYnkgcGFpcmluZyBvbmUgb3IgbW9yZSBjb2xvci4NCg0KIVtdKDYuUE5HKQ0KDQpgYGB7cn0NCg0KI0xpbms6IGh0dHBzOi8vYmxvZy5odWJzcG90LmNvbS9tYXJrZXRpbmcvY29sb3ItdGhlb3J5LWRlc2lnbg0KDQpgYGANCg0KDQpUaGlzIGNvbG9yIHNjaGVtZSBjb3VsZCBiZSBjcmVhdGUgd2FybWVyICh3aXRoIHllbGxvdykgb3IgY29vbG9lciAod2l0aCBwdXJwbGUpDQoNCiFbXSg3LlBORykNCg0KYGBge3J9DQoNCiNMaW5rOiBodHRwczovL2Jsb2cuaHVic3BvdC5jb20vbWFya2V0aW5nL2NvbG9yLXRoZW9yeS1kZXNpZ24NCg0KYGBgDQoNCg0KDQoqKjMuIFJlZmVyIHRvIGEgY29sb3Igd2hlZWwgdG8gaWRlbnRpZnkgY29tcGxlbWVudGFyeSBjb2xvcnMuKioNCg0KVXNlIG9mIHR3byBjb2xvcnMgZGlyZWN0bHkgYWNyb3NzIGZyb20gZWFjaCBvdGhlci4NCiFbXSg4LlBORykNCg0KYGBge3J9DQoNCiNMaW5rOiBodHRwczovL2Jsb2cuaHVic3BvdC5jb20vbWFya2V0aW5nL2NvbG9yLXRoZW9yeS1kZXNpZ24NCg0KYGBgDQoNCg0KVGhlIHR3byBhY3Jvc3MgY29sb3Igc2NoZW1lIGlzIGFsc28gZ3JlYXQgZm9yIGdyYXBocy4gSGlnaCBjb250cmFzdCBoZWxwcyB5b3UgaGlnaGxpZ2h0IGltcG9ydGFudCBwb2ludHMuDQoNCiFbXSg5LlBORykNCg0KYGBge3J9DQoNCiNMaW5rOiBodHRwczovL2Jsb2cuaHVic3BvdC5jb20vbWFya2V0aW5nL2NvbG9yLXRoZW9yeS1kZXNpZ24NCg0KYGBgDQoNCg0KKio0LiBGb2N1cyBvbiBtb25vY2hyb21hdGljIGNvbG9ycyBpbiB0aGUgc2FtZSBodWUuKioNCg0KSXQgY3JlYXRlZCBzaGFkZXMgYW5kIHRpbnRzIGluIG9uZSBodWUuDQohW10oMTAuUE5HKQ0KDQpgYGB7cn0NCg0KI0xpbms6IGh0dHBzOi8vYmxvZy5odWJzcG90LmNvbS9tYXJrZXRpbmcvY29sb3ItdGhlb3J5LWRlc2lnbg0KDQpgYGANCg0KRXhhbXBsZSBvZiBtb25vY2hyb21hdGljIGNvbG9yIHVuZGVyIHRoZSByZWQgaHVlLg0KDQohW10oMTEuUE5HKQ0KDQpgYGB7cn0NCg0KI0xpbms6IGh0dHBzOi8vYmxvZy5odWJzcG90LmNvbS9tYXJrZXRpbmcvY29sb3ItdGhlb3J5LWRlc2lnbg0KDQpgYGANCg0KKio1LiBVc2UgYSB0cmlhZGljIGNvbG9yIHNjaGVtZSB0byBjcmVhdGUgaGlnaCBjb250cmFzdC4qKg0KDQpUcmlhZCBjb2xvciBzY2hlbWVzICgzIGNvbG9ycykgYXJlIHVzZWQgdG8gY3JlYXRlIGhpZ2ggY29udHJhc3QgYmV0d2VlbiBlYWNoIGNvbG9yLg0KDQohW10oMTIuUE5HKQ0KDQpgYGB7cn0NCg0KI0xpbms6IGh0dHBzOi8vYmxvZy5odWJzcG90LmNvbS9tYXJrZXRpbmcvY29sb3ItdGhlb3J5LWRlc2lnbg0KDQpgYGANCg0KDQpjaGFuZ2luZyB1cCB0aGUgaW50ZW5zaXR5IG9mIHRoZSBjb2xvcnMgZm9yIGhpZ2hsaWdodGluZyBpbXBvcnRhbnQgcG9pbnRzIGFuZCB0ZXJtcy4NCg0KIVtdKDEzLlBORykNCg0KYGBge3J9DQoNCiNMaW5rOiBodHRwczovL2Jsb2cuaHVic3BvdC5jb20vbWFya2V0aW5nL2NvbG9yLXRoZW9yeS1kZXNpZ24NCg0KDQpgYGANCg0KDQoNCg0KDQoNCg0KKio2LiBDcmVhdGUgYSBzcGxpdCBjb21wbGVtZW50YXJ5IGNvbG9yIHNjaGVtZS4qKg0KDQpPbmUgZG9taW5hbnQgY29sb3IgYW5kIHRoZSB0d28gY29sb3JzIGFkamFjZW50IHRvIHRoZSBkb21pbmFudCBjb2xvcidzIGNvbXBsZW1lbnQuDQoNCiFbXSgxNC5QTkcpDQoNCmBgYHtyfQ0KDQojTGluazogaHR0cHM6Ly9ibG9nLmh1YnNwb3QuY29tL21hcmtldGluZy9jb2xvci10aGVvcnktZGVzaWduDQoNCg0KYGBgDQogDQogDQpBbiBleGFtcGxlIGlzIGxpa2UgdGhpcyBwYWxsZXQuDQoNCiFbXSgxNS5QTkcpDQoNCmBgYHtyfQ0KDQojTGluazogaHR0cHM6Ly9ibG9nLmh1YnNwb3QuY29tL21hcmtldGluZy9jb2xvci10aGVvcnktZGVzaWduDQoNCmBgYA0KDQoNCg0KDQoqKjcuIFRoaW5rIGJleW9uZCB0aGUgcHJlc2V0cywgYnV0IHN0YXJ0IHdpdGgganVzdCBvbmUgY29sb3IuKioNCg0KRXh0cmEgdGlwcyBmb3IgY2hvb3NpbmcgY29sb3JzOg0KDQoqIERvbid0IHN0aWNrIHdpdGggYXV0b21hdGljYWxseSBwcmVzZXRzIGNvbG9yIGluIGV2ZXJ5IHByb2dyYW0gb3Igc29mdHdhcmUuIFVzZSB0aGUgY29sb3Igd2hlZWwgdGhlb3J5IG9yIG9ubGluZSBjb2xvciB3aGVlbCBkZXNpZ25lcg0KKiBTdGFydCB3aXRoIG9uZSBjb2xvciB5b3UgbGlrZQ0KKiBTYXZlIHlvdXIgY29sb3Igc2NoZW1lcw0KKiBQcmFjdGljZSBtYWtlcyBwZXJmZWN0DQoNCg0KDQoNCjxCcj4NCg0KI0xvZ2ljYWwgcnVsZXMgdG8gY2hvb3NpbmcgY29sb3INCg0KKipEZWZpbmluZyB0aGUgYmFzaWNzIGZvciBjaG9vc2luZyBjb2xvcnM6KioNCg0KIVtdKDE2LmpwZykNCg0KYGBge3J9DQoNCiNMaW5rOiBodHRwczovL2NvbG91cnNhbmRtYXRlcmlhbHMud29yZHByZXNzLmNvbS8yMDE0LzA5LzE2L2NvbG91ci1zeXN0ZW0vDQoNCmBgYA0KDQoqKkJlbG93IGFyZSB0aGUgZXhwbGFuYXRpb24gb2YgdGhpcyBsb2dpY2FsIHJ1bGVzOioqDQoNCiFbXSgxNy5wbmcpDQoNCmBgYHtyfQ0KDQojTGluazogaHR0cHM6Ly9leHBlcnRwaG90b2dyYXBoeS5jb20vY29sb3ItaW4tcGhvdG9ncmFwaHkvDQoNCmBgYA0KDQoNCg0KIVtdKDE4LmpwZykNCg0KYGBge3J9DQoNCiNMaW5rOiBodHRwczovL21hc29uLmdtdS5lZHUvfmtzaGlmZmw0LzM3NS9tb2R1bGU1LTQuaHRtbA0KDQpgYGANCg0KDQohW10oMTkuanBnKQ0KDQpgYGB7cn0NCg0KI0xpbms6IGh0dHBzOi8vd3d3LjEyM3JmLmNvbS9waG90b184Mjk1ODM4Ml9zdG9jay12ZWN0b3ItdmVjdG9yLWlsbHVzdHJhdGlvbi1vZi1jb2xvci1jaXJjbGUtY29tcGxlbWVudGFyeS1hbmFsb2dvdXMtc2ltaWxhci10cmlhZGljLXRldHJhZGljLWR1YWwtY29tcGxlbWVudC5odG1sDQoNCmBgYA0KDQo8QnI+DQoNCiNDb2xvcnRvb2xzOiBSIHBhY2thZ2UNCg0KRGV2ZWxvcGVkIGJ5IFtHYXN0b24gU2FuY2hlel0oaHR0cDovL3d3dy5nYXN0b25zYW5jaGV6LmNvbS8pIGZvciBnZW5lcmF0aW5nIGNvbG9yIHNjaGVtZXMgaW4gUiAod2l0aG91dCBsZWF2aW5nIFIgSURFKS4NCg0KKipJbnN0YWxsIGFuZCBsb2FkIGNvbG9ydG9vbHM6KioNCg0KYGBge3J9DQoNCmluc3RhbGwucGFja2FnZXMoImNvbG9ydG9vbHMiKQ0KbGlicmFyeShjb2xvcnRvb2xzKQ0KDQoNCmBgYA0KDQoqKkNvbG9yIFdoZWVsOioqDQoNCkhpc3RvcmljYWxseSwgdGhlcmUgaGF2ZSBiZWVuIG1hbnkgdmFyaWF0aW9ucyBvZiB0aGUgYmFzaWMgZGVzaWduLCBidXQgdGhlIG1vc3QgcG9wdWxhciB2ZXJzaW9uIGlzIDEyIGNvbG9ycyBiYXNlZCBvbiB0aGUgUllCIChSZWQsIFllbGxvdywgQmx1ZSkuIA0KDQpDcmVhdGUgY29sb3Igd2hlZWxzIGJ5IHVzaW5nIHRoZSBmdW5jdGlvbiBgd2hlZWxgIGFuZCBzb21lIGdpdmVuIGNvbG9yLg0KDQpgYGB7cn0NCg0KIyBjb2xvciB3aGVlbCBmb3IgJ3BpbmsnDQp3aGVlbCgicGluayIpDQoNCmBgYA0KDQoqKkFuYWxvZ291cyAoQWRqYWNlbnQpIENvbG9yIFNjaGVtZToqKg0KDQpUaHJlZSBjb2xvcnMgZnJvbSBhIDEyIHBhcnQgY29sb3Igd2hlZWwuDQoNCmBgYHtyfQ0KDQojIGFuYWxvZ291cyAoYWRqYWNlbnQpIGNvbG9ycyBvZiAncGluaycNCmFuYWxvZ291cygicGluayIpDQoNCmBgYA0KDQoqKkNvbXBsZW1lbnRhcnkgKE9wcG9zaXRlKSBDb2xvciBTY2hlbWU6KioNCg0KT3Bvc2l0ZSBjb2xvcnMgZnJvbSB0aGUgY29sb3Igd2hlZWwgKDIgY29sb3JzKS4NCg0KYGBge3J9DQoNCiMgY29tcGxlbWVudGFyeSAob3Bwb3NpdGUpIGNvbG9yIG9mICdwaW5rJw0KY29tcGxlbWVudGFyeSgicGluayIpDQoNCg0KYGBgDQoNCg0KKipTcGxpdCBDb21wbGVtZW50YXJ5IENvbG9yIFNjaGVtZToqKg0KDQpDb21wbGVtZW50YXJ5IGNvbG9yIHNjaGVtZSB0aGF0IHVzZXMgdHdvIGNvbG9ycyBvbiBlaXRoZXIgc2lkZSBvZiBhIGRpcmVjdGx5IG9wcG9zaXRlIGNvbG9yLg0KDQpgYGB7cn0NCg0KIyBzcGxpdCBjb21wbGVtZW50YXJ5IGNvbG9ycyBvZiAncGluaycNCnNwbGl0Q29tcCgicGluayIpDQoNCmBgYA0KDQoqKlRyaWFkaWMgQ29sb3IgU2NoZW1lOioqDQoNClRocmVlIGNvbG9ycyBmcm9tIGFyb3VuZCB0aGUgY29sb3Igd2hlZWwuDQoNCmBgYHtyfQ0KDQojIHRyaWFkaWMgY29sb3JzIG9mICdwaW5rJw0KdHJpYWRpYygicGluayIpDQoNCmBgYA0KDQoqKlRldHJhZGljIENvbG9yIFNjaGVtZToqKg0KDQpGb3VyIGNvbG9ycyBhcnJhbmdlZCBpbnRvIHR3byBjb21wbGVtZW50YXJ5IHBhaXJzIGZyb20gY29sb3Igd2hlZWwuDQoNCmBgYHtyfQ0KDQojIHRldHJhZGljIGNvbG9ycyBvZiAncGluaycNCnRldHJhZGljKCJwaW5rIikNCg0KDQpgYGANCg0KDQoqKlNxdWFyZSBDb2xvciBTY2hlbWU6KioNCg0KU2ltaWxhciB3aXRoIHRldHJhZGljIHNjaGVtZSwgYnV0IHdpdGggYWxsIGZvdXIgY29sb3JzIGFyb3VuZCB0aGUgY29sb3Igd2hlZWwgKG5vdCBjb21wbGVtZW50YXJ5KS4NCg0KYGBge3J9DQoNCiMgc3F1YXJlIGNvbG9ycyBvZiAncGluaycNCnNxdWFyZSgicGluayIpDQoNCg0KYGBgDQoNCg0KKipTZXF1ZW50aWFsIENvbG9yczoqKg0KDQpgc2VxdWVudGlhbGAgZ2V0IGEgc2VxdWVuY2Ugb2YgY29sb3JzIGZyb20gaGlnaCB0byBsb3cuIA0KDQpgYGB7cn0NCg0KIyBzZXF1ZW50aWFsIGNvbG9ycyBvZiAncGluaycNCnNlcXVlbnRpYWwoInBpbmsiKQ0KDQoNCmBgYA0KDQpBbm90aGVyIGV4YW1wbGU6DQoNCmBgYHtyfQ0KDQojIHNlcXVlbnRpYWwgc2VxdWVuY2UgZm9yIHNhdHVyYXRpb24sIHdpdGggZml4IHZhbHVlIHM9MC44LCBhbHBoYT0wLjUsDQojIHBlcmNlbnRhZ2UgMTAsIGFuZCBmdW49J2xvZycNCnNlcXVlbnRpYWwoInBpbmsiLCAxMCwgd2hhdCA9ICJ2YWx1ZSIsIHMgPSAwLjcsIGFscGhhID0gMC41LCBmdW4gPSAibG9nIikNCg0KYGBgDQoNCg0KKipTbWFsbCBhc3Nvcm1lbnQgb2YgY29sb3IgcGFsZXR0ZXM6KioNCg0KQSBmdW5jdGlvbiBgcGFsc2AgY29udGFpbnMgYW4gYXNzb3J0bWVudCBvZiBuaWNlIGNvbG9yIHBhbGV0dGVzLg0KDQpgYGB7cn0NCg0KIyBjb2xvciBwYWxldHRlcw0KcGFscygpDQoNCmBgYA0KDQpUbyBnZXQgdGhlIG5hbWVzIG9mIHRoZSBjb2xvcnM6DQoNCmBgYHtyfQ0KDQojIGNvbG9yIG5hbWVzIG9mIHBhbGV0dGUgJ2NoZWVyJw0KcGFscygiZmlzaCIpDQoNCmBgYA0KDQoNClZpc3VhbGl6ZSB0aGUgY29sb3JzIGluIGEgJ3BpenphJyB3aGVlbDoNCg0KYGBge3J9DQoNCiMgY29sb3IgbmFtZXMgb2YgcGFsZXR0ZSAnY2hlZXInDQpwaXp6YShwYWxzKCJmaXNoIikpDQoNCmBgYA0KDQoNCioqVmlzdWFsaXppbmcgUiBjb2xvciBwYWxldHRlczoqKg0KDQpBIHBpZSBjaGFydCB3aXRoIGdpdmVuIGNvbG9ycy4NCg0KYGBge3J9DQoNCiMgdGVycmFpbiBjb2xvcnMgKDEyKQ0KcGl6emEodGVycmFpbi5jb2xvcnMoMTIpLCBiZyA9ICJwaW5rIikNCg0KYGBgDQoNCg0KPEJyPg0KDQoNCiNPbmxpbmUgY29sb3Igc2NoZW1lDQoNCltBZG9iZSBDb2xvciAoQWRvYmUgS3VsZXIpXShodHRwczovL2NvbG9yLmFkb2JlLmNvbS9kZS9jcmVhdGUvY29sb3Itd2hlZWwvKQ0KDQpbQ29sb3IgU2NoZW1hIERlc2lnbmVyXShodHRwOi8vY29sb3JzY2hlbWVkZXNpZ25lci5jb20vY3NkLTMuNS8pDQoNCltDb2xvciBDYWxjdWxhdG9yXShodHRwczovL3d3dy5zZXNzaW9ucy5lZHUvY29sb3ItY2FsY3VsYXRvci8pDQoNCltBbm90aGVyIHByb2R1Y3RzXShodHRwczovL3d3dy5wcm9kdWN0aHVudC5jb20vYWx0ZXJuYXRpdmVzL2Fkb2JlLWt1bGVyKQ0KDQo8QnI+DQoNCg0KI0NoYW5nZSBsb2cgdXBkYXRlDQoNCiogMjUuMTIuMjAxOA0KDQo8QnI+DQoNCiNQcmVmZXJlbmNlcw0KDQoqIFtSIHBhY2thZ2UgY29sb3J0b29sc10oaHR0cDovL3JwdWJzLmNvbS9nYXN0b24vY29sb3J0b29scykNCg0KKiBbU2xpZGU6b2xvZ3ldKGh0dHBzOi8vd3d3LmR1YXJ0ZS5jb20vYm9va3Mvc2xpZGVvbG9neS8pDQoNCiogW1JEb2N1bWVudGF0aW9uXShodHRwczovL3d3dy5yZG9jdW1lbnRhdGlvbi5vcmcvKQ0KDQoqIFtDb2xvciBUaGVvcnkgRGVzaWduXShodHRwczovL2Jsb2cuaHVic3BvdC5jb20vbWFya2V0aW5nL2NvbG9yLXRoZW9yeS1kZXNpZ24pDQoNCiogW1N0YXRpc3RpY2FsIHRvb2xzIGZvciBoaWdoLXRocm91Z2hwdXQgZGF0YSBhbmFseXNpc10oaHR0cDovL3d3dy5zdGhkYS5jb20vZW5nbGlzaC8pDQoNCjxCcj4NCg0KI0xpY2Vuc2UNCg0KW1RoZSBNSVQgTGljZW5zZV0oaHR0cHM6Ly9vcGVuc291cmNlLm9yZy9saWNlbnNlcy9NSVQp