5275 lines
999 KiB
HTML
5275 lines
999 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<title>SheetJS Community Edition</title>
|
|
<link rel="icon" href="data:image/x-icon;base64,AAABAAEAEBAAAAEACABoBQAAFgAAACgAAAAQAAAAIAAAAAEACAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAKCgr/FRUX/xYWGP8YGBr/GRkb/xsbHP8dHR7/Hh4f/x4eIP8fHyD/ICAh/yMjJP8kJCX/JiYo/ygoKv8pKSr/LCwu/y0tLv80NDT/QUFC/0ZGR/9MTE7/UFBR/1JSUv9bW1v/XFxc/2BgYP9hYWP/aGhp/2xsbP9ycnL/d3d3/3l5e/98fHz/f3+A/2dn/P9z3a//cNX8/4CAgP+Xl5f/nZ2e/56en/+fn5//n5+h/6amp/+rq6v/rKys/7CvsP+zs7T/uLi5/7u7u/+8vLz/wMDA/8fHx//Kysr/zc3N/9HR0f/d3d3/3t7e/+Xl5f/q6ur/6+vr/+3t7f/z8/P/9fX1//b29v/39/f/+Pj4//n5+f/6+vr/+/v7//z8/P/9/f3//v7+//////8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/NCYmJiYmJiYmJiYmJiYmNCZKSkpKSkpKSkpKSkpKSiYmSkpKRisdRkMbMklKSkomJkpKSSEiNUhEEQwpSUpKJiZKSi8LHhhAPAwBDDZKSiYmSkoWACA7SEc6HAEaSkomJkpKBxI/SkpKSj4ICkpKJiZKSgUTR0pKSkpGDwZKSiYmSkoTED1KSkpKOQQVSkomJkpKKgowMy4sNycIMUpKJiZKSkEZDgkDAgsNH0VKSiYmSkpKQigUBgkXLUhKSkomJkpKSkpKSkpKSkpKSkpKJiYmJiYmJiYmJiYmJiYmJiYmIyUkNDQ0NDQ0NDQ0NDQmOCYmJiYmJiYmJiYmJiYmOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=" />
|
|
<link rel="stylesheet" href="/__/grip/static/octicons/octicons.css" />
|
|
<style>
|
|
/*!
|
|
* GitHub Light v0.4.1
|
|
* Copyright (c) 2012 - 2017 GitHub, Inc.
|
|
* Licensed under MIT (https://github.com/primer/github-syntax-theme-generator/blob/master/LICENSE)
|
|
*/.pl-c{color:#6a737d}.pl-c1,.pl-s .pl-v{color:#005cc5}.pl-e,.pl-en{color:#6f42c1}.pl-smi,.pl-s .pl-s1{color:#24292e}.pl-ent{color:#22863a}.pl-k{color:#d73a49}.pl-s,.pl-pds,.pl-s .pl-pse .pl-s1,.pl-sr,.pl-sr .pl-cce,.pl-sr .pl-sre,.pl-sr .pl-sra{color:#032f62}.pl-v,.pl-smw{color:#e36209}.pl-bu{color:#b31d28}.pl-ii{color:#fafbfc;background-color:#b31d28}.pl-c2{color:#fafbfc;background-color:#d73a49}.pl-c2::before{content:"^M"}.pl-sr .pl-cce{font-weight:bold;color:#22863a}.pl-ml{color:#735c0f}.pl-mh,.pl-mh .pl-en,.pl-ms{font-weight:bold;color:#005cc5}.pl-mi{font-style:italic;color:#24292e}.pl-mb{font-weight:bold;color:#24292e}.pl-md{color:#b31d28;background-color:#ffeef0}.pl-mi1{color:#22863a;background-color:#f0fff4}.pl-mc{color:#e36209;background-color:#ffebda}.pl-mi2{color:#f6f8fa;background-color:#005cc5}.pl-mdr{font-weight:bold;color:#6f42c1}.pl-ba{color:#586069}.pl-sg{color:#959da5}.pl-corl{text-decoration:underline;color:#032f62}.CodeMirror{font-family:monospace;height:300px;color:black;direction:ltr}.CodeMirror-lines{padding:4px 0}.CodeMirror pre{padding:0 4px}.CodeMirror-scrollbar-filler,.CodeMirror-gutter-filler{background-color:white}.CodeMirror-gutters{border-right:1px solid #ddd;background-color:#f7f7f7;white-space:nowrap}.CodeMirror-linenumber{padding:0 3px 0 5px;min-width:20px;text-align:right;color:#999;white-space:nowrap}.CodeMirror-guttermarker{color:black}.CodeMirror-guttermarker-subtle{color:#999}.CodeMirror-cursor{border-left:1px solid black;border-right:none;width:0}.CodeMirror div.CodeMirror-secondarycursor{border-left:1px solid silver}.cm-fat-cursor .CodeMirror-cursor{width:auto;border:0 !important;background:#7e7}.cm-fat-cursor div.CodeMirror-cursors{z-index:1}.cm-fat-cursor-mark{background-color:rgba(20,255,20,0.5);animation:blink 1.06s steps(1) infinite}.cm-animate-fat-cursor{width:auto;border:0;animation:blink 1.06s steps(1) infinite;background-color:#7e7}@keyframes blink{0%{}50%{background-color:transparent}100%{}}.cm-tab{display:inline-block;text-decoration:inherit}.CodeMirror-rulers{position:absolute;left:0;right:0;top:-50px;bottom:-20px;overflow:hidden}.CodeMirror-ruler{border-left:1px solid #ccc;top:0;bottom:0;position:absolute}.cm-s-default .cm-header{color:blue}.cm-s-default .cm-quote{color:#090}.cm-negative{color:#d44}.cm-positive{color:#292}.cm-header,.cm-strong{font-weight:bold}.cm-em{font-style:italic}.cm-link{text-decoration:underline}.cm-strikethrough{text-decoration:line-through}.cm-s-default .cm-keyword{color:#708}.cm-s-default .cm-atom{color:#219}.cm-s-default .cm-number{color:#164}.cm-s-default .cm-def{color:#00f}.cm-s-default .cm-variable-2{color:#05a}.cm-s-default .cm-variable-3,.cm-s-default .cm-type{color:#085}.cm-s-default .cm-comment{color:#a50}.cm-s-default .cm-string{color:#a11}.cm-s-default .cm-string-2{color:#f50}.cm-s-default .cm-meta{color:#555}.cm-s-default .cm-qualifier{color:#555}.cm-s-default .cm-builtin{color:#30a}.cm-s-default .cm-bracket{color:#997}.cm-s-default .cm-tag{color:#170}.cm-s-default .cm-attribute{color:#00c}.cm-s-default .cm-hr{color:#999}.cm-s-default .cm-link{color:#00c}.cm-s-default .cm-error{color:#f00}.cm-invalidchar{color:#f00}.CodeMirror-composing{border-bottom:2px solid}div.CodeMirror span.CodeMirror-matchingbracket{color:#0b0}div.CodeMirror span.CodeMirror-nonmatchingbracket{color:#a22}.CodeMirror-matchingtag{background:rgba(255,150,0,0.3)}.CodeMirror-activeline-background{background:#e8f2ff}.CodeMirror{position:relative;overflow:hidden;background:white}.CodeMirror-scroll{overflow:scroll !important;margin-bottom:-30px;margin-right:-30px;padding-bottom:30px;height:100%;outline:none;position:relative}.CodeMirror-sizer{position:relative;border-right:30px solid transparent}.CodeMirror-vscrollbar,.CodeMirror-hscrollbar,.CodeMirror-scrollbar-filler,.CodeMirror-gutter-filler{position:absolute;z-index:6;display:none}.CodeMirror-vscrollbar{right:0;top:0;overflow-x:hidden;overflow-y:scroll}.CodeMirror-hscrollbar{bottom:0;left:0;overflow-y:hidden;overflow-x:scroll}.CodeMirror-scrollbar-filler{right:0;bottom:0}.CodeMirror-gutter-filler{left:0;bottom:0}.CodeMirror-gutters{position:absolute;left:0;top:0;min-height:100%;z-index:3}.CodeMirror-gutter{white-space:normal;height:100%;display:inline-block;vertical-align:top;margin-bottom:-30px}.CodeMirror-gutter-wrapper{position:absolute;z-index:4;background:none !important;border:none !important}.CodeMirror-gutter-background{position:absolute;top:0;bottom:0;z-index:4}.CodeMirror-gutter-elt{position:absolute;cursor:default;z-index:4}.CodeMirror-gutter-wrapper ::-moz-selection{background-color:transparent}.CodeMirror-gutter-wrapper ::selection{background-color:transparent}.CodeMirror-gutter-wrapper ::-moz-selection{background-color:transparent}.CodeMirror-lines{cursor:text;min-height:1px}.CodeMirror pre{border-radius:0;border-width:0;background:transparent;font-family:inherit;font-size:inherit;margin:0;white-space:pre;word-wrap:normal;line-height:inherit;color:inherit;z-index:2;position:relative;overflow:visible;-webkit-tap-highlight-color:transparent;-webkit-font-variant-ligatures:contextual;font-variant-ligatures:contextual}.CodeMirror-wrap pre{word-wrap:break-word;white-space:pre-wrap;word-break:normal}.CodeMirror-linebackground{position:absolute;left:0;right:0;top:0;bottom:0;z-index:0}.CodeMirror-linewidget{position:relative;z-index:2;padding:0.1px}.CodeMirror-rtl pre{direction:rtl}.CodeMirror-code{outline:none}.CodeMirror-scroll,.CodeMirror-sizer,.CodeMirror-gutter,.CodeMirror-gutters,.CodeMirror-linenumber{box-sizing:content-box}.CodeMirror-measure{position:absolute;width:100%;height:0;overflow:hidden;visibility:hidden}.CodeMirror-cursor{position:absolute;pointer-events:none}.CodeMirror-measure pre{position:static}div.CodeMirror-cursors{visibility:hidden;position:relative;z-index:3}div.CodeMirror-dragcursors{visibility:visible}.CodeMirror-focused div.CodeMirror-cursors{visibility:visible}.CodeMirror-selected{background:#d9d9d9}.CodeMirror-focused .CodeMirror-selected{background:#d7d4f0}.CodeMirror-crosshair{cursor:crosshair}.CodeMirror-line::-moz-selection,.CodeMirror-line>span::-moz-selection,.CodeMirror-line>span>span::-moz-selection{background:#d7d4f0}.CodeMirror-line::selection,.CodeMirror-line>span::selection,.CodeMirror-line>span>span::selection{background:#d7d4f0}.CodeMirror-line::-moz-selection,.CodeMirror-line>span::-moz-selection,.CodeMirror-line>span>span::-moz-selection{background:#d7d4f0}.cm-searching{background-color:#ffa;background-color:rgba(255,255,0,0.4)}.cm-force-border{padding-right:.1px}@media print{.CodeMirror div.CodeMirror-cursors{visibility:hidden}}.cm-tab-wrap-hack:after{content:''}span.CodeMirror-selectedtext{background:none}.CodeMirror-dialog{position:absolute;left:0;right:0;background:inherit;z-index:15;padding:.1em .8em;overflow:hidden;color:inherit}.CodeMirror-dialog-top{border-bottom:1px solid #eee;top:0}.CodeMirror-dialog-bottom{border-top:1px solid #eee;bottom:0}.CodeMirror-dialog input{border:none;outline:none;background:transparent;width:20em;color:inherit;font-family:monospace}.CodeMirror-dialog button{font-size:70%}.CodeMirror-merge{position:relative;border:1px solid #ddd;white-space:pre}.CodeMirror-merge,.CodeMirror-merge .CodeMirror{height:350px}.CodeMirror-merge-2pane .CodeMirror-merge-pane{width:47%}.CodeMirror-merge-2pane .CodeMirror-merge-gap{width:6%}.CodeMirror-merge-3pane .CodeMirror-merge-pane{width:31%}.CodeMirror-merge-3pane .CodeMirror-merge-gap{width:3.5%}.CodeMirror-merge-pane{display:inline-block;white-space:normal;vertical-align:top}.CodeMirror-merge-pane-rightmost{position:absolute;right:0px;z-index:1}.CodeMirror-merge-gap{z-index:2;display:inline-block;height:100%;box-sizing:border-box;overflow:hidden;border-left:1px solid #ddd;border-right:1px solid #ddd;position:relative;background:#f8f8f8}.CodeMirror-merge-scrolllock-wrap{position:absolute;bottom:0;left:50%}.CodeMirror-merge-scrolllock{position:relative;left:-50%;cursor:pointer;color:#555;line-height:1}.CodeMirror-merge-scrolllock:after{content:"\21db\00a0\00a0\21da"}.CodeMirror-merge-scrolllock.CodeMirror-merge-scrolllock-enabled:after{content:"\21db\21da"}.CodeMirror-merge-copybuttons-left,.CodeMirror-merge-copybuttons-right{position:absolute;left:0;top:0;right:0;bottom:0;line-height:1}.CodeMirror-merge-copy{position:absolute;cursor:pointer;color:#44c;z-index:3}.CodeMirror-merge-copy-reverse{position:absolute;cursor:pointer;color:#44c}.CodeMirror-merge-copybuttons-left .CodeMirror-merge-copy{left:2px}.CodeMirror-merge-copybuttons-right .CodeMirror-merge-copy{right:2px}.CodeMirror-merge-r-inserted,.CodeMirror-merge-l-inserted{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAACCAYAAACddGYaAAAAGUlEQVQI12MwuCXy3+CWyH8GBgYGJgYkAABZbAQ9ELXurwAAAABJRU5ErkJggg==);background-position:bottom left;background-repeat:repeat-x}.CodeMirror-merge-r-deleted,.CodeMirror-merge-l-deleted{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAACCAYAAACddGYaAAAAGUlEQVQI12M4Kyb2/6yY2H8GBgYGJgYkAABURgPz6Ks7wQAAAABJRU5ErkJggg==);background-position:bottom left;background-repeat:repeat-x}.CodeMirror-merge-r-chunk{background:#ffffe0}.CodeMirror-merge-r-chunk-start{border-top:1px solid #ee8}.CodeMirror-merge-r-chunk-end{border-bottom:1px solid #ee8}.CodeMirror-merge-r-connect{fill:#ffffe0;stroke:#ee8;stroke-width:1px}.CodeMirror-merge-l-chunk{background:#eef}.CodeMirror-merge-l-chunk-start{border-top:1px solid #88e}.CodeMirror-merge-l-chunk-end{border-bottom:1px solid #88e}.CodeMirror-merge-l-connect{fill:#eef;stroke:#88e;stroke-width:1px}.CodeMirror-merge-l-chunk.CodeMirror-merge-r-chunk{background:#dfd}.CodeMirror-merge-l-chunk-start.CodeMirror-merge-r-chunk-start{border-top:1px solid #4e4}.CodeMirror-merge-l-chunk-end.CodeMirror-merge-r-chunk-end{border-bottom:1px solid #4e4}.CodeMirror-merge-collapsed-widget:before{content:"(...)"}.CodeMirror-merge-collapsed-widget{cursor:pointer;color:#88b;background:#eef;border:1px solid #ddf;font-size:90%;padding:0 3px;border-radius:4px}.CodeMirror-merge-collapsed-line .CodeMirror-gutter-elt{display:none}/*!
|
|
* GitHub Light v0.4.2
|
|
* Copyright (c) 2012 - 2017 GitHub, Inc.
|
|
* Licensed under MIT (https://github.com/primer/github-syntax-theme-generator/blob/master/LICENSE)
|
|
*/.cm-s-github-light.CodeMirror{background:#fff;color:#24292e}.cm-s-github-light .CodeMirror-gutters{background:#fff;border-right-width:0}.cm-s-github-light .CodeMirror-guttermarker{color:white}.cm-s-github-light .CodeMirror-guttermarker-subtle{color:#d0d0d0}.cm-s-github-light .CodeMirror-linenumber{color:#959da5;padding:0 16px 0 16px}.cm-s-github-light .CodeMirror-cursor{border-left:1px solid #24292e}.cm-s-github-light div.CodeMirror-selected,.cm-s-github-light .CodeMirror-line::-moz-selection,.cm-s-github-light .CodeMirror-line>span::-moz-selection,.cm-s-github-light .CodeMirror-line>span>span::-moz-selection,.cm-s-github-light .CodeMirror-line::-moz-selection,.cm-s-github-light .CodeMirror-line>span::-moz-selection,.cm-s-github-light .CodeMirror-line>span>span::-moz-selection{background:#c8c8fa}.cm-s-github-light div.CodeMirror-selected,.cm-s-github-light .CodeMirror-line::selection,.cm-s-github-light .CodeMirror-line>span::selection,.cm-s-github-light .CodeMirror-line>span>span::selection,.cm-s-github-light .CodeMirror-line::-moz-selection,.cm-s-github-light .CodeMirror-line>span::-moz-selection,.cm-s-github-light .CodeMirror-line>span>span::-moz-selection{background:#c8c8fa}.cm-s-github-light .CodeMirror-activeline-background{background:#fafbfc}.cm-s-github-light .CodeMirror-matchingbracket{text-decoration:underline;color:#24292e !important}.cm-s-github-light .CodeMirror-lines{font-family:"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size:12px;background:#fff;line-height:1.5}.cm-s-github-light .cm-comment{color:#6a737d}.cm-s-github-light .cm-constant{color:#005cc5}.cm-s-github-light .cm-entity{font-weight:normal;font-style:normal;text-decoration:none;color:#6f42c1}.cm-s-github-light .cm-keyword{font-weight:normal;font-style:normal;text-decoration:none;color:#d73a49}.cm-s-github-light .cm-storage{color:#d73a49}.cm-s-github-light .cm-string{font-weight:normal;font-style:normal;text-decoration:none;color:#032f62}.cm-s-github-light .cm-support{font-weight:normal;font-style:normal;text-decoration:none;color:#005cc5}.cm-s-github-light .cm-variable{font-weight:normal;font-style:normal;text-decoration:none;color:#e36209}details-dialog{position:fixed;margin:10vh auto;top:0;left:50%;transform:translateX(-50%);z-index:999;max-height:80vh;max-width:90vw;width:448px}.octicon{display:inline-block;vertical-align:text-top;fill:currentColor}body.intent-mouse [role="button"]:focus,body.intent-mouse button:focus,body.intent-mouse summary:focus{outline:none}.CodeMirror{height:calc(100vh - 1px)}.file-editor-textarea{width:100%;padding:5px 4px;font:12px "SFMono-Regular",Consolas,"Liberation Mono",Menlo,Courier,monospace;resize:vertical;border:0;border-radius:0;outline:none}.container-preview .tabnav-tabs{margin:-6px 0 -6px -11px}.container-preview .tabnav-tabs .tabnav-tab{padding:12px 15px;border-radius:0}.container-preview .tabnav-tabs>.selected:first-child{border-top-left-radius:3px}.container-preview .tabnav-tabs .selected{font-weight:600}.container-preview.template-editor .commit-create,.container-preview.template-editor .file-actions{display:block}.container-preview.template-editor .show-code,.container-preview.template-editor .commit-preview,.container-preview.template-editor .loading-preview-msg,.container-preview.template-editor .no-changes-preview-msg,.container-preview.template-editor .error-preview-msg{display:none}.container-preview.render-editor .commit-create,.container-preview.render-editor .file-actions{display:block}.container-preview.render-editor .template-editor,.container-preview.render-editor .show-code,.container-preview.render-editor .commit-preview,.container-preview.render-editor .loading-preview-msg,.container-preview.render-editor .no-changes-preview-msg,.container-preview.render-editor .error-preview-msg{display:none}.container-preview.show-code .commit-create,.container-preview.show-code .file-actions{display:block}.container-preview.show-code .template-editor,.container-preview.show-code .render-editor,.container-preview.show-code .commit-preview,.container-preview.show-code .loading-preview-msg,.container-preview.show-code .no-changes-preview-msg,.container-preview.show-code .error-preview-msg{display:none}.container-preview:not(.show-code) .commit-create,.container-preview:not(.show-code) .file-actions{display:none}.container-preview.loading-preview .loading-preview-msg{display:block}.container-preview.loading-preview .template-editor,.container-preview.loading-preview .render-editor,.container-preview.loading-preview .no-changes-preview-msg,.container-preview.loading-preview .error-preview-msg,.container-preview.loading-preview .commit-preview{display:none}.container-preview.show-preview .commit-preview{display:block}.container-preview.show-preview .template-editor,.container-preview.show-preview .render-editor,.container-preview.show-preview .loading-preview-msg,.container-preview.show-preview .no-changes-preview-msg,.container-preview.show-preview .error-preview-msg{display:none}.container-preview.no-changes-preview .no-changes-preview-msg{display:block}.container-preview.no-changes-preview .template-editor,.container-preview.no-changes-preview .render-editor,.container-preview.no-changes-preview .loading-preview-msg,.container-preview.no-changes-preview .error-preview-msg,.container-preview.no-changes-preview .commit-preview{display:none}.container-preview.error-preview .error-preview-msg{display:block}.container-preview.error-preview .template-editor,.container-preview.error-preview .render-editor,.container-preview.error-preview .loading-preview-msg,.container-preview.error-preview .no-changes-preview-msg,.container-preview.error-preview .commit-preview{display:none}.container-preview p.preview-msg{padding:30px;font-size:16px}.CodeMirror-merge-header{height:30px}.CodeMirror-merge-header .CodeMirror-merge-pane{height:30px;line-height:30px}.cm-s-github-light .merge-gutter{width:14px}.conflict-background+.CodeMirror-gutter-wrapper .CodeMirror-linenumber{background-color:#fffbdd}.conflict-gutter-marker{background-color:#fffbdd}.conflict-gutter-marker::after,.conflict-gutter-marker::before{position:absolute;left:-1px;content:"";background-color:#d73a49}.conflict-gutter-marker-start::after,.conflict-gutter-marker-end::after{width:1px;height:10px}.conflict-gutter-marker-start::before,.conflict-gutter-marker-middle::before,.conflict-gutter-marker-end::before{width:10px;height:1px}.conflict-gutter-marker-start::after{bottom:0}.conflict-gutter-marker-end::after{top:0}.conflict-gutter-marker-start::before{top:7px}.conflict-gutter-marker-end::before{bottom:7px}.conflict-gutter-marker-line::after,.conflict-gutter-marker-middle::after{width:1px;height:18px}.conflict-gutter-marker-middle::before{top:9px}.form-group .draggable-box{height:20px;opacity:0}.form-group .draggable-box:hover{cursor:move}.form-group .edit-action{opacity:0.6}.form-group .draggable-box-icon{margin-left:-4px}.form-group .form-field-hover{background-color:none;border:1px solid rgba(149,157,165,0)}.form-group:hover{cursor:pointer}.form-group:hover .draggable-box{opacity:0.2}.form-group:hover .edit-action{opacity:0.7}.form-group:hover .form-field-hover{border:1px solid #959da5}.placeholder-box{border:1px solid #959da5}.template-previews{max-width:768px}.template-previews .Box .expand-group{display:none;height:0}.template-previews .Box .dismiss-preview-button{display:none}.template-previews .Box.expand-preview .expand-group{display:block;height:100%;transition:height 3s}.template-previews .Box.expand-preview .preview-button{display:none}.template-previews .Box.expand-preview .dismiss-preview-button{display:inline}.additional-options{display:none}.edit-labels{display:none}.preview-section{display:block}.edit-section{display:none}.Box .section-focus .preview-section{display:none}.Box .section-focus .edit-section{display:block}.user-select-contain{-ms-user-select:element;-webkit-user-select:contain;-moz-user-select:contain;user-select:contain}.zeroclipboard-link{padding:0;margin:0;color:#0366d6;cursor:pointer;background:none;border:0}.zeroclipboard-link .octicon{display:block}image-crop{display:block}image-crop.nesw{cursor:nesw-resize}image-crop.nwse{cursor:nwse-resize}image-crop.nesw .crop-box,image-crop.nwse .crop-box{cursor:inherit}image-crop[loaded] .crop-image{display:block}image-crop[loaded] [data-loading-slot],image-crop .crop-image{display:none}image-crop .crop-wrapper{position:relative;font-size:0}image-crop .crop-container{user-select:none;-ms-user-select:none;-moz-user-select:none;-webkit-user-select:none;position:absolute;overflow:hidden;z-index:1;top:0;width:100%;height:100%}image-crop .crop-box{position:absolute;border:1px dashed #fff;box-sizing:border-box;cursor:move}image-crop .crop-outline{position:absolute;top:0;bottom:0;left:0;right:0;outline:600px solid rgba(0,0,0,0.3)}image-crop .handle{position:absolute}image-crop .handle:before{position:absolute;display:block;padding:4px;transform:translate(-50%, -50%);content:' ';background:#fff;border:1px solid #767676}image-crop .ne{top:0;right:0;cursor:nesw-resize}image-crop .nw{top:0;left:0;cursor:nwse-resize}image-crop .se{bottom:0;right:0;cursor:nwse-resize}image-crop .sw{bottom:0;left:0;cursor:nesw-resize}/*!
|
|
* Primer-core
|
|
* http://primer.github.io
|
|
*
|
|
* Released under MIT license. Copyright (c) 2018 GitHub Inc.
|
|
*//*! normalize.css v4.1.1 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,main,menu,nav,section{display:block}summary{display:list-item}audio,canvas,progress,video{display:inline-block}audio:not([controls]){display:none;height:0}progress{vertical-align:baseline}template,[hidden]{display:none}a{background-color:transparent}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:inherit}b,strong{font-weight:bolder}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}svg:not(:root){overflow:hidden}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}figure{margin:1em 40px}hr{box-sizing:content-box;height:0;overflow:visible}button,input,select,textarea{font:inherit;margin:0}optgroup{font-weight:bold}button,input{overflow:visible}button,select{text-transform:none}button,html [type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button::-moz-focus-inner,[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type="button"]:-moz-focusring,[type="reset"]:-moz-focusring,[type="submit"]:-moz-focusring{outline:1px dotted ButtonText}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}textarea{overflow:auto}[type="checkbox"],[type="radio"]{box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}[type="search"]::-webkit-search-cancel-button,[type="search"]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-input-placeholder{color:inherit;opacity:0.54}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}*{box-sizing:border-box}input,select,textarea,button{font-family:inherit;font-size:inherit;line-height:inherit}body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:14px;line-height:1.5;color:#24292e;background-color:#fff}a{color:#0366d6;text-decoration:none}a:hover{text-decoration:underline}b,strong{font-weight:600}hr,.rule{height:0;margin:15px 0;overflow:hidden;background:transparent;border:0;border-bottom:1px solid #dfe2e5}hr::before,.rule::before{display:table;content:""}hr::after,.rule::after{display:table;clear:both;content:""}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}button{cursor:pointer;border-radius:0}details summary{cursor:pointer}details:not([open])>*:not(summary){display:none !important}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:0}h1{font-size:32px;font-weight:600}h2{font-size:24px;font-weight:600}h3{font-size:20px;font-weight:600}h4{font-size:16px;font-weight:600}h5{font-size:14px;font-weight:600}h6{font-size:12px;font-weight:600}p{margin-top:0;margin-bottom:10px}small{font-size:90%}blockquote{margin:0}ul,ol{padding-left:0;margin-top:0;margin-bottom:0}ol ol,ul ol{list-style-type:lower-roman}ul ul ol,ul ol ol,ol ul ol,ol ol ol{list-style-type:lower-alpha}dd{margin-left:0}tt,code{font-family:"SFMono-Regular",Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:12px}pre{margin-top:0;margin-bottom:0;font-family:"SFMono-Regular",Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:12px}.octicon{vertical-align:text-bottom}.Box{background-color:#fff;border:1px solid #d1d5da;border-radius:3px}.Box--condensed{line-height:1.25}.Box--condensed .Box-header{padding:8px 16px}.Box--condensed .Box-body{padding:8px 16px}.Box--condensed .Box-footer{padding:8px 16px}.Box--condensed .Box-btn-octicon.btn-octicon{padding:8px 16px;margin:-8px -16px;line-height:1.25}.Box--condensed .Box-row{padding:8px 16px}.Box--spacious .Box-header{padding:24px;line-height:1.25}.Box--spacious .Box-title{font-size:20px}.Box--spacious .Box-body{padding:24px}.Box--spacious .Box-footer{padding:24px}.Box--spacious .Box-btn-octicon.btn-octicon{padding:24px;margin:-24px -24px}.Box--spacious .Box-row{padding:24px}.Box-header{padding:16px;margin:-1px -1px 0 -1px;background-color:#f6f8fa;border-color:#d1d5da;border-style:solid;border-width:1px;border-top-left-radius:3px;border-top-right-radius:3px}.Box-title{font-size:14px;font-weight:600}.Box-body{padding:16px;border-bottom:1px solid #e1e4e8}.Box-body:last-of-type{margin-bottom:-1px;border-bottom-right-radius:2px;border-bottom-left-radius:2px}.Box-row{padding:16px;margin-top:-1px;list-style-type:none;border-top:1px solid #e1e4e8}.Box-row:first-of-type{border-top-color:transparent;border-top-left-radius:2px;border-top-right-radius:2px}.Box-row:last-of-type{border-bottom-right-radius:2px;border-bottom-left-radius:2px}.Box-row.Box-row--unread,.Box-row.unread{box-shadow:2px 0 0 #0366d6 inset}.Box-row.navigation-focus .Box-row--drag-button{color:#0366d6;cursor:-webkit-grab;cursor:grab;opacity:100}.Box-row.navigation-focus.is-dragging .Box-row--drag-button{cursor:-webkit-grabbing;cursor:grabbing}.Box-row.navigation-focus.sortable-chosen{background-color:#fafbfc}.Box-row.navigation-focus.sortable-ghost{background-color:#f6f8fa}.Box-row.navigation-focus.sortable-ghost .Box-row--drag-hide{opacity:0}.Box-row--focus-gray.navigation-focus{background-color:#f6f8fa}.Box-row--focus-blue.navigation-focus{background-color:#f1f8ff}.Box-row--hover-gray:hover{background-color:#f6f8fa}.Box-row--hover-blue:hover{background-color:#f1f8ff}@media (min-width: 768px){.Box-row-link{color:#24292e;text-decoration:none}.Box-row-link:hover{color:#0366d6;text-decoration:none}}.Box-row--drag-button{opacity:0}.Box-footer{padding:16px;margin-top:-1px;border-top:1px solid #e1e4e8}.Box--scrollable{max-height:324px;overflow:scroll}.Box--blue{border-color:#c8e1ff}.Box--blue .Box-header{background-color:#f1f8ff;border-color:#c8e1ff}.Box--blue .Box-body{border-color:#c8e1ff}.Box--blue .Box-row{border-color:#c8e1ff}.Box--blue .Box-footer{border-color:#c8e1ff}.Box--danger{border-color:#d73a49}.Box--danger .Box-row:first-of-type{border-color:#d73a49}.Box--danger .Box-body:last-of-type{border-color:#d73a49}.Box-header--blue{background-color:#f1f8ff;border-color:#c8e1ff}.Box-row--yellow{background-color:#fffbdd}.Box-row--blue{background-color:#f1f8ff}.Box-row--gray{background-color:#f6f8fa}.Box-btn-octicon.btn-octicon{padding:16px 16px;margin:-16px -16px;line-height:1.5}.breadcrumb-item{display:inline-block;margin-left:-0.35em;white-space:nowrap;list-style:none}.breadcrumb-item::after{padding-right:.5em;padding-left:.5em;color:#e1e4e8;content:"/"}.breadcrumb-item:first-child{margin-left:0}.breadcrumb-item-selected::after{content:none}.btn{position:relative;display:inline-block;padding:6px 12px;font-size:14px;font-weight:600;line-height:20px;white-space:nowrap;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-repeat:repeat-x;background-position:-1px -1px;background-size:110% 110%;border:1px solid rgba(27,31,35,0.2);border-radius:0.25em;-webkit-appearance:none;-moz-appearance:none;appearance:none}.btn i{font-style:normal;font-weight:500;opacity:0.75}.btn .octicon{vertical-align:text-top}.btn .Counter{color:#586069;text-shadow:none;background-color:rgba(27,31,35,0.1)}.btn:hover{text-decoration:none;background-repeat:repeat-x}.btn:focus{outline:0}.btn:disabled,.btn.disabled{cursor:default;background-position:0 0}.btn:active,.btn.selected{background-image:none}.btn{color:#24292e;background-color:#eff3f6;background-image:linear-gradient(-180deg, #fafbfc 0%, #eff3f6 90%)}.btn:focus,.btn.focus{box-shadow:0 0 0 0.2em rgba(3,102,214,0.3)}.btn:hover,.btn.hover{background-color:#e6ebf1;background-image:linear-gradient(-180deg, #f0f3f6 0%, #e6ebf1 90%);background-position:-.5em;border-color:rgba(27,31,35,0.35)}.btn:active,.btn.selected,[open]>.btn{background-color:#e9ecef;background-image:none;border-color:rgba(27,31,35,0.35);box-shadow:inset 0 0.15em 0.3em rgba(27,31,35,0.15)}.btn:disabled,.btn.disabled{color:rgba(36,41,46,0.4);background-color:#eff3f6;background-image:none;border-color:rgba(27,31,35,0.2);box-shadow:none}.btn-primary{color:#fff;background-color:#28a745;background-image:linear-gradient(-180deg, #34d058 0%, #28a745 90%)}.btn-primary:focus,.btn-primary.focus{box-shadow:0 0 0 0.2em rgba(52,208,88,0.4)}.btn-primary:hover,.btn-primary.hover{background-color:#269f42;background-image:linear-gradient(-180deg, #2fcb53 0%, #269f42 90%);background-position:-.5em;border-color:rgba(27,31,35,0.5)}.btn-primary:active,.btn-primary.selected,[open]>.btn-primary{background-color:#279f43;background-image:none;border-color:rgba(27,31,35,0.5);box-shadow:inset 0 0.15em 0.3em rgba(27,31,35,0.15)}.btn-primary:disabled,.btn-primary.disabled{color:rgba(255,255,255,0.75);background-color:#94d3a2;background-image:none;border-color:rgba(27,31,35,0.2);box-shadow:none}.btn-primary .Counter{color:#29b249;background-color:#fff}.btn-purple{color:#fff;background-color:#643ab0;background-image:linear-gradient(-180deg, #7e55c7 0%, #643ab0 90%)}.btn-purple:focus,.btn-purple.focus{box-shadow:0 0 0 0.2em rgba(126,85,199,0.4)}.btn-purple:hover,.btn-purple.hover{background-color:#5f37a8;background-image:linear-gradient(-180deg, #784ec5 0%, #5f37a8 90%);background-position:-.5em;border-color:rgba(27,31,35,0.5)}.btn-purple:active,.btn-purple.selected,[open]>.btn-purple{background-color:#613ca4;background-image:none;border-color:rgba(27,31,35,0.5);box-shadow:inset 0 0.15em 0.3em rgba(27,31,35,0.15)}.btn-purple:disabled,.btn-purple.disabled{color:rgba(255,255,255,0.75);background-color:#b19cd7;background-image:none;border-color:rgba(27,31,35,0.2);box-shadow:none}.btn-purple .Counter{color:#683cb8;background-color:#fff}.btn-blue{color:#fff;background-color:#0361cc;background-image:linear-gradient(-180deg, #0679fc 0%, #0361cc 90%)}.btn-blue:focus,.btn-blue.focus{box-shadow:0 0 0 0.2em rgba(6,121,252,0.4)}.btn-blue:hover,.btn-blue.hover{background-color:#035cc2;background-image:linear-gradient(-180deg, #0374f4 0%, #035cc2 90%);background-position:-.5em;border-color:rgba(27,31,35,0.5)}.btn-blue:active,.btn-blue.selected,[open]>.btn-blue{background-color:#045cc1;background-image:none;border-color:rgba(27,31,35,0.5);box-shadow:inset 0 0.15em 0.3em rgba(27,31,35,0.15)}.btn-blue:disabled,.btn-blue.disabled{color:rgba(255,255,255,0.75);background-color:#81b0e5;background-image:none;border-color:rgba(27,31,35,0.2);box-shadow:none}.btn-blue .Counter{color:#0366d6;background-color:#fff}.btn-danger{color:#cb2431;background-color:#fafbfc;background-image:linear-gradient(-180deg, #fafbfc 0%, #eff3f6 90%)}.btn-danger:focus{box-shadow:0 0 0 0.2em rgba(203,36,49,0.4)}.btn-danger:hover{color:#fff;background-color:#cb2431;background-image:linear-gradient(-180deg, #de4450 0%, #cb2431 90%);border-color:rgba(27,31,35,0.5)}.btn-danger:hover .Counter{color:#fff}.btn-danger:active,.btn-danger.selected,[open]>.btn-danger{color:#fff;background-color:#b5202c;background-image:none;border-color:rgba(27,31,35,0.5);box-shadow:inset 0 0.15em 0.3em rgba(27,31,35,0.15)}.btn-danger:disabled,.btn-danger.disabled{color:rgba(203,36,49,0.4);background-color:#eff3f6;background-image:none;border-color:rgba(27,31,35,0.2);box-shadow:none}.btn-outline{color:#0366d6;background-color:#fff;background-image:none}.btn-outline .Counter{background-color:rgba(27,31,35,0.07)}.btn-outline:hover,.btn-outline:active,.btn-outline.selected,[open]>.btn-outline{color:#fff;background-color:#0366d6;background-image:none;border-color:#0366d6}.btn-outline:hover .Counter,.btn-outline:active .Counter,.btn-outline.selected .Counter,[open]>.btn-outline .Counter{color:#0366d6;background-color:#fff}.btn-outline:focus{border-color:#0366d6;box-shadow:0 0 0 0.2em rgba(3,102,214,0.4)}.btn-outline:disabled,.btn-outline.disabled{color:rgba(27,31,35,0.3);background-color:#fff;border-color:rgba(27,31,35,0.15);box-shadow:none}.btn-with-count{float:left;border-top-right-radius:0;border-bottom-right-radius:0}.btn-sm{padding:3px 10px;font-size:12px;line-height:20px}.btn-large{padding:.75em 1.25em;font-size:inherit;border-radius:6px}.hidden-text-expander{display:block}.hidden-text-expander.inline{position:relative;top:-1px;display:inline-block;margin-left:5px;line-height:0}.hidden-text-expander a,.ellipsis-expander{display:inline-block;height:12px;padding:0 5px 5px;font-size:12px;font-weight:600;line-height:6px;color:#444d56;text-decoration:none;vertical-align:middle;background:#dfe2e5;border:0;border-radius:1px}.hidden-text-expander a:hover,.ellipsis-expander:hover{text-decoration:none;background-color:#c6cbd1}.hidden-text-expander a:active,.ellipsis-expander:active{color:#fff;background-color:#2188ff}.social-count{float:left;padding:3px 10px;font-size:12px;font-weight:600;line-height:20px;color:#24292e;vertical-align:middle;background-color:#fff;border:1px solid rgba(27,31,35,0.2);border-left:0;border-top-right-radius:3px;border-bottom-right-radius:3px}.social-count:hover,.social-count:active{text-decoration:none}.social-count:hover{color:#0366d6;cursor:pointer}.btn-block{display:block;width:100%;text-align:center}.btn-link{display:inline-block;padding:0;font-size:inherit;color:#0366d6;text-decoration:none;white-space:nowrap;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:transparent;border:0;-webkit-appearance:none;-moz-appearance:none;appearance:none}.btn-link:hover{text-decoration:underline}.btn-link:disabled,.btn-link:disabled:hover{color:rgba(88,96,105,0.5);cursor:default}.details-reset>summary{list-style:none}.details-reset>summary::before{display:none}.details-reset>summary::-webkit-details-marker{display:none}.BtnGroup{display:inline-block;vertical-align:middle}.BtnGroup::before{display:table;content:""}.BtnGroup::after{display:table;clear:both;content:""}.BtnGroup+.BtnGroup,.BtnGroup+.btn{margin-left:5px}.BtnGroup-item{position:relative;float:left;border-right-width:0;border-radius:0}.BtnGroup-item:first-child{border-top-left-radius:3px;border-bottom-left-radius:3px}.BtnGroup-item:last-child{border-right-width:1px;border-top-right-radius:3px;border-bottom-right-radius:3px}.BtnGroup-item.selected,.BtnGroup-item:focus,.BtnGroup-item:active,.BtnGroup-item:hover{border-right-width:1px}.BtnGroup-item.selected+.BtnGroup-item,.BtnGroup-item.selected+.BtnGroup-parent .BtnGroup-item,.BtnGroup-item.selected+.BtnGroup-form .BtnGroup-item,.BtnGroup-item:focus+.BtnGroup-item,.BtnGroup-item:focus+.BtnGroup-parent .BtnGroup-item,.BtnGroup-item:focus+.BtnGroup-form .BtnGroup-item,.BtnGroup-item:active+.BtnGroup-item,.BtnGroup-item:active+.BtnGroup-parent .BtnGroup-item,.BtnGroup-item:active+.BtnGroup-form .BtnGroup-item,.BtnGroup-item:hover+.BtnGroup-item,.BtnGroup-item:hover+.BtnGroup-parent .BtnGroup-item,.BtnGroup-item:hover+.BtnGroup-form .BtnGroup-item{border-left-width:0}.BtnGroup-parent,.BtnGroup-form{float:left}.BtnGroup-parent:first-child .BtnGroup-item,.BtnGroup-form:first-child .BtnGroup-item{border-top-left-radius:3px;border-bottom-left-radius:3px}.BtnGroup-parent:last-child .BtnGroup-item,.BtnGroup-form:last-child .BtnGroup-item{border-right-width:1px;border-top-right-radius:3px;border-bottom-right-radius:3px}.BtnGroup-parent .BtnGroup-item,.BtnGroup-form .BtnGroup-item{border-right-width:0;border-radius:0}.BtnGroup-parent.selected .BtnGroup-item,.BtnGroup-parent:focus .BtnGroup-item,.BtnGroup-parent:active .BtnGroup-item,.BtnGroup-parent:hover .BtnGroup-item,.BtnGroup-form.selected .BtnGroup-item,.BtnGroup-form:focus .BtnGroup-item,.BtnGroup-form:active .BtnGroup-item,.BtnGroup-form:hover .BtnGroup-item{border-right-width:1px}.BtnGroup-parent.selected+.BtnGroup-item,.BtnGroup-parent.selected+.BtnGroup-parent .BtnGroup-item,.BtnGroup-parent.selected+.BtnGroup-form .BtnGroup-item,.BtnGroup-parent:focus+.BtnGroup-item,.BtnGroup-parent:focus+.BtnGroup-parent .BtnGroup-item,.BtnGroup-parent:focus+.BtnGroup-form .BtnGroup-item,.BtnGroup-parent:active+.BtnGroup-item,.BtnGroup-parent:active+.BtnGroup-parent .BtnGroup-item,.BtnGroup-parent:active+.BtnGroup-form .BtnGroup-item,.BtnGroup-parent:hover+.BtnGroup-item,.BtnGroup-parent:hover+.BtnGroup-parent .BtnGroup-item,.BtnGroup-parent:hover+.BtnGroup-form .BtnGroup-item,.BtnGroup-form.selected+.BtnGroup-item,.BtnGroup-form.selected+.BtnGroup-parent .BtnGroup-item,.BtnGroup-form.selected+.BtnGroup-form .BtnGroup-item,.BtnGroup-form:focus+.BtnGroup-item,.BtnGroup-form:focus+.BtnGroup-parent .BtnGroup-item,.BtnGroup-form:focus+.BtnGroup-form .BtnGroup-item,.BtnGroup-form:active+.BtnGroup-item,.BtnGroup-form:active+.BtnGroup-parent .BtnGroup-item,.BtnGroup-form:active+.BtnGroup-form .BtnGroup-item,.BtnGroup-form:hover+.BtnGroup-item,.BtnGroup-form:hover+.BtnGroup-parent .BtnGroup-item,.BtnGroup-form:hover+.BtnGroup-form .BtnGroup-item{border-left-width:0}.TableObject{display:table}.TableObject-item{display:table-cell;width:1%;white-space:nowrap;vertical-align:middle}.TableObject-item--primary{width:99%}fieldset{padding:0;margin:0;border:0}label{font-weight:600}.form-control,.form-select{min-height:34px;padding:6px 8px;font-size:16px;line-height:20px;color:#24292e;vertical-align:middle;background-color:#fff;background-repeat:no-repeat;background-position:right 8px center;border:1px solid #d1d5da;border-radius:3px;outline:none;box-shadow:inset 0 1px 2px rgba(27,31,35,0.075)}.form-control.focus,.form-control:focus,.form-select.focus,.form-select:focus{border-color:#2188ff;outline:none;box-shadow:inset 0 1px 2px rgba(27,31,35,0.075),0 0 0 0.2em rgba(3,102,214,0.3)}@media (min-width: 768px){.form-control,.form-select{font-size:14px}}.input-contrast{background-color:#fafbfc}.input-contrast:focus{background-color:#fff}:-ms-input-placeholder{color:#6a737d}::-ms-input-placeholder{color:#6a737d}::placeholder{color:#6a737d}.input-sm{min-height:28px;padding-top:3px;padding-bottom:3px;font-size:12px;line-height:20px}.input-lg{padding:4px 10px;font-size:16px}.input-block{display:block;width:100%}.input-monospace{font-family:"SFMono-Regular",Consolas,"Liberation Mono",Menlo,Courier,monospace}.input-hide-webkit-autofill::-webkit-contacts-auto-fill-button{position:absolute;right:0;display:none !important;pointer-events:none;visibility:hidden}.form-checkbox{padding-left:20px;margin:15px 0;vertical-align:middle}.form-checkbox label em.highlight{position:relative;left:-4px;padding:2px 4px;font-style:normal;background:#fffbdd;border-radius:3px}.form-checkbox input[type=checkbox],.form-checkbox input[type=radio]{float:left;margin:5px 0 0 -20px;vertical-align:middle}.form-checkbox .note{display:block;margin:0;font-size:12px;font-weight:400;color:#586069}.form-checkbox-details{display:none}.form-checkbox-details-trigger:checked ~ * .form-checkbox-details,.form-checkbox-details-trigger:checked ~ .form-checkbox-details{display:block}.hfields{margin:15px 0}.hfields::before{display:table;content:""}.hfields::after{display:table;clear:both;content:""}.hfields .form-group{float:left;margin:0 30px 0 0}.hfields .form-group dt label{display:inline-block;margin:5px 0 0;color:#586069}.hfields .form-group dt img{position:relative;top:-2px}.hfields .btn{float:left;margin:28px 25px 0 -20px}.hfields .form-select{margin-top:5px}input::-webkit-outer-spin-button,input::-webkit-inner-spin-button{margin:0;-webkit-appearance:none;appearance:none}.form-actions::before{display:table;content:""}.form-actions::after{display:table;clear:both;content:""}.form-actions .btn{float:right}.form-actions .btn+.btn{margin-right:5px}.form-warning{padding:8px 10px;margin:10px 0;font-size:14px;color:#735c0f;background:#fffbdd;border:1px solid #d9d0a5;border-radius:3px}.form-warning p{margin:0;line-height:1.5}.form-warning a{font-weight:600}.form-select{display:inline-block;max-width:100%;height:34px;padding-right:24px;padding-right:8px \9;background:#fff url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAUCAMAAACzvE1FAAAADFBMVEUzMzMzMzMzMzMzMzMKAG/3AAAAA3RSTlMAf4C/aSLHAAAAPElEQVR42q3NMQ4AIAgEQTn//2cLdRKppSGzBYwzVXvznNWs8C58CiussPJj8h6NwgorrKRdTvuV9v16Afn0AYFOB7aYAAAAAElFTkSuQmCC") no-repeat right 8px center;background-image:none \9;background-size:8px 10px;-webkit-appearance:none;-moz-appearance:none;appearance:none}.form-select::-ms-expand{opacity:0}.form-select[multiple]{height:auto}.select-sm{height:28px;min-height:28px;padding-top:3px;padding-bottom:3px;font-size:12px}.select-sm[multiple]{height:auto;min-height:0}.form-group{margin:15px 0}.form-group .form-control{width:440px;max-width:100%;margin-right:5px;background-color:#fafbfc}.form-group .form-control:focus{background-color:#fff}.form-group .form-control.shorter{width:130px}.form-group .form-control.short{width:250px}.form-group .form-control.long{width:100%}.form-group textarea.form-control{width:100%;height:200px;min-height:200px}.form-group textarea.form-control.short{height:50px;min-height:50px}.form-group dt{margin:0 0 6px}.form-group label{position:relative}.form-group.flattened dt{float:left;margin:0;line-height:32px}.form-group.flattened dd{line-height:32px}.form-group dd h4{margin:4px 0 0}.form-group dd h4.is-error{color:#cb2431}.form-group dd h4.is-success{color:#28a745}.form-group dd h4+.note{margin-top:0}.form-group.required dt label::after{padding-left:5px;color:#cb2431;content:"*"}.form-group .success,.form-group .error,.form-group .indicator{display:none;font-size:12px;font-weight:600}.form-group.loading{opacity:0.5}.form-group.loading .indicator{display:inline}.form-group.loading .spinner{display:inline-block;vertical-align:middle}.form-group.successful .success{display:inline;color:#28a745}.form-group.warn .warning,.form-group.warn .error,.form-group.errored .warning,.form-group.errored .error{position:absolute;z-index:10;display:block;max-width:450px;padding:5px 8px;margin:4px 0 0;font-size:13px;font-weight:400;border-style:solid;border-width:1px;border-radius:3px}.form-group.warn .warning::after,.form-group.warn .warning::before,.form-group.warn .error::after,.form-group.warn .error::before,.form-group.errored .warning::after,.form-group.errored .warning::before,.form-group.errored .error::after,.form-group.errored .error::before{position:absolute;bottom:100%;left:10px;z-index:15;width:0;height:0;pointer-events:none;content:" ";border:solid transparent}.form-group.warn .warning::after,.form-group.warn .error::after,.form-group.errored .warning::after,.form-group.errored .error::after{border-width:5px}.form-group.warn .warning::before,.form-group.warn .error::before,.form-group.errored .warning::before,.form-group.errored .error::before{margin-left:-1px;border-width:6px}.form-group.warn .warning{color:#735c0f;background-color:#fffbdd;border-color:#d9d0a5}.form-group.warn .warning::after{border-bottom-color:#fffbdd}.form-group.warn .warning::before{border-bottom-color:#d9d0a5}.form-group.errored label{color:#cb2431}.form-group.errored .error{color:#86181d;background-color:#ffdce0;border-color:#cea0a5}.form-group.errored .error::after{border-bottom-color:#ffdce0}.form-group.errored .error::before{border-bottom-color:#cea0a5}.note{min-height:17px;margin:4px 0 2px;font-size:12px;color:#586069}.note .spinner{margin-right:3px;vertical-align:middle}dl.form-group>dd .form-control.is-autocheck-loading,dl.form-group>dd .form-control.is-autocheck-successful,dl.form-group>dd .form-control.is-autocheck-errored{padding-right:30px}dl.form-group>dd .form-control.is-autocheck-loading{background-image:url("/images/spinners/octocat-spinner-16px.gif")}dl.form-group>dd .form-control.is-autocheck-successful{background-image:url("/images/modules/ajax/success.png")}dl.form-group>dd .form-control.is-autocheck-errored{background-image:url("/images/modules/ajax/error.png")}@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-moz-min-device-pixel-ratio: 2), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx){dl.form-group>dd .form-control.is-autocheck-loading,dl.form-group>dd .form-control.is-autocheck-successful,dl.form-group>dd .form-control.is-autocheck-errored{background-size:16px 16px}dl.form-group>dd .form-control.is-autocheck-loading{background-image:url("/images/spinners/octocat-spinner-32.gif")}dl.form-group>dd .form-control.is-autocheck-successful{background-image:url("/images/modules/ajax/success@2x.png")}dl.form-group>dd .form-control.is-autocheck-errored{background-image:url("/images/modules/ajax/error@2x.png")}}.status-indicator{display:inline-block;width:16px;height:16px;margin-left:5px}.status-indicator .octicon{display:none}.status-indicator-success::before{content:""}.status-indicator-success .octicon-check{display:inline-block;color:#28a745;fill:#28a745}.status-indicator-success .octicon-x{display:none}.status-indicator-failed::before{content:""}.status-indicator-failed .octicon-check{display:none}.status-indicator-failed .octicon-x{display:inline-block;color:#cb2431;fill:#d73a49}.status-indicator-loading{width:16px;background:url("/images/spinners/octocat-spinner-32-EAF2F5.gif") 0 0 no-repeat;background-size:16px}.inline-form{display:inline-block}.inline-form .btn-plain{background-color:transparent;border:0}.drag-and-drop{padding:7px 10px;margin:0;font-size:13px;line-height:16px;color:#586069;background-color:#fafbfc;border:1px solid #c3c8cf;border-top:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.drag-and-drop .default,.drag-and-drop .loading,.drag-and-drop .error{display:none}.drag-and-drop .error{color:#cb2431}.drag-and-drop img{vertical-align:top}.is-default .drag-and-drop .default{display:inline-block}.is-uploading .drag-and-drop .loading{display:inline-block}.is-bad-file .drag-and-drop .bad-file{display:inline-block}.is-duplicate-filename .drag-and-drop .duplicate-filename{display:inline-block}.is-too-big .drag-and-drop .too-big{display:inline-block}.is-hidden-file .drag-and-drop .hidden-file{display:inline-block}.is-empty .drag-and-drop .empty{display:inline-block}.is-bad-permissions .drag-and-drop .bad-permissions{display:inline-block}.is-repository-required .drag-and-drop .repository-required{display:inline-block}.drag-and-drop-error-info{font-weight:400;color:#586069}.drag-and-drop-error-info a{color:#0366d6}.is-failed .drag-and-drop .failed-request{display:inline-block}.manual-file-chooser{position:absolute;width:240px;padding:5px;margin-left:-80px;cursor:pointer;opacity:0.0001}.manual-file-chooser:hover+.manual-file-chooser-text{text-decoration:underline}.btn .manual-file-chooser{top:0;padding:0;line-height:34px}.upload-enabled textarea{display:block;border-bottom:1px dashed #dfe2e5;border-bottom-right-radius:0;border-bottom-left-radius:0}.upload-enabled.focused{border-radius:3px;box-shadow:inset 0 1px 2px rgba(27,31,35,0.075),0 0 0 0.2em rgba(3,102,214,0.3)}.upload-enabled.focused .form-control{box-shadow:none}.upload-enabled.focused .drag-and-drop{border-color:#4a9eff}.dragover textarea,.dragover .drag-and-drop{box-shadow:#c9ff00 0 0 3px}.write-content{position:relative}.previewable-comment-form{position:relative}.previewable-comment-form .tabnav{position:relative;padding:8px 8px 0}.previewable-comment-form .comment{border:1px solid #c3c8cf}.previewable-comment-form .comment-form-error{margin-bottom:8px}.previewable-comment-form .write-content,.previewable-comment-form .preview-content{display:none;margin:0 8px 8px}.previewable-comment-form.write-selected .write-content,.previewable-comment-form.preview-selected .preview-content{display:block}.previewable-comment-form textarea{display:block;width:100%;min-height:100px;max-height:500px;padding:8px;resize:vertical}.form-action-spacious{margin-top:10px}div.composer{margin-top:0;border:0}.composer .comment-form-textarea{height:200px;min-height:200px}.composer .tabnav{margin:0 0 10px}h2.account{margin:15px 0 0;font-size:18px;font-weight:400;color:#586069}p.explain{position:relative;font-size:12px;color:#586069}p.explain strong{color:#24292e}p.explain .octicon{margin-right:5px;color:#959da5}p.explain .minibutton{top:-4px;float:right}.form-group label{position:static}.input-group{display:table}.input-group .form-control{position:relative;width:100%}.input-group .form-control:focus{z-index:2}.input-group .form-control+.btn{margin-left:0}.input-group.inline{display:inline-table}.input-group .form-control,.input-group-button{display:table-cell}.input-group-button{width:1%;vertical-align:middle}.input-group .form-control:first-child,.input-group-button:first-child .btn{border-top-right-radius:0;border-bottom-right-radius:0}.input-group-button:first-child .btn{margin-right:-1px}.input-group .form-control:last-child,.input-group-button:last-child .btn{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-button:last-child .btn{margin-left:-1px}.container{width:980px;margin-right:auto;margin-left:auto}.container::before{display:table;content:""}.container::after{display:table;clear:both;content:""}.container-md{max-width:768px;margin-right:auto;margin-left:auto}.container-lg{max-width:1012px;margin-right:auto;margin-left:auto}.container-xl{max-width:1280px;margin-right:auto;margin-left:auto}.columns{margin-right:-10px;margin-left:-10px}.columns::before{display:table;content:""}.columns::after{display:table;clear:both;content:""}.column{float:left;padding-right:10px;padding-left:10px}.one-third{width:33.333333%}.two-thirds{width:66.666667%}.one-fourth{width:25%}.one-half{width:50%}.three-fourths{width:75%}.one-fifth{width:20%}.four-fifths{width:80%}.centered{display:block;float:none;margin-right:auto;margin-left:auto}.col-1{width:8.33333%}.col-2{width:16.66667%}.col-3{width:25%}.col-4{width:33.33333%}.col-5{width:41.66667%}.col-6{width:50%}.col-7{width:58.33333%}.col-8{width:66.66667%}.col-9{width:75%}.col-10{width:83.33333%}.col-11{width:91.66667%}.col-12{width:100%}@media (min-width: 544px){.col-sm-1{width:8.33333%}.col-sm-2{width:16.66667%}.col-sm-3{width:25%}.col-sm-4{width:33.33333%}.col-sm-5{width:41.66667%}.col-sm-6{width:50%}.col-sm-7{width:58.33333%}.col-sm-8{width:66.66667%}.col-sm-9{width:75%}.col-sm-10{width:83.33333%}.col-sm-11{width:91.66667%}.col-sm-12{width:100%}}@media (min-width: 768px){.col-md-1{width:8.33333%}.col-md-2{width:16.66667%}.col-md-3{width:25%}.col-md-4{width:33.33333%}.col-md-5{width:41.66667%}.col-md-6{width:50%}.col-md-7{width:58.33333%}.col-md-8{width:66.66667%}.col-md-9{width:75%}.col-md-10{width:83.33333%}.col-md-11{width:91.66667%}.col-md-12{width:100%}}@media (min-width: 1012px){.col-lg-1{width:8.33333%}.col-lg-2{width:16.66667%}.col-lg-3{width:25%}.col-lg-4{width:33.33333%}.col-lg-5{width:41.66667%}.col-lg-6{width:50%}.col-lg-7{width:58.33333%}.col-lg-8{width:66.66667%}.col-lg-9{width:75%}.col-lg-10{width:83.33333%}.col-lg-11{width:91.66667%}.col-lg-12{width:100%}}@media (min-width: 1280px){.col-xl-1{width:8.33333%}.col-xl-2{width:16.66667%}.col-xl-3{width:25%}.col-xl-4{width:33.33333%}.col-xl-5{width:41.66667%}.col-xl-6{width:50%}.col-xl-7{width:58.33333%}.col-xl-8{width:66.66667%}.col-xl-9{width:75%}.col-xl-10{width:83.33333%}.col-xl-11{width:91.66667%}.col-xl-12{width:100%}}.gutter{margin-right:-16px;margin-left:-16px}.gutter>[class*="col-"]{padding-right:16px !important;padding-left:16px !important}.gutter-condensed{margin-right:-8px;margin-left:-8px}.gutter-condensed>[class*="col-"]{padding-right:8px !important;padding-left:8px !important}.gutter-spacious{margin-right:-24px;margin-left:-24px}.gutter-spacious>[class*="col-"]{padding-right:24px !important;padding-left:24px !important}@media (min-width: 544px){.gutter-sm{margin-right:-16px;margin-left:-16px}.gutter-sm>[class*="col-"]{padding-right:16px !important;padding-left:16px !important}.gutter-sm-condensed{margin-right:-8px;margin-left:-8px}.gutter-sm-condensed>[class*="col-"]{padding-right:8px !important;padding-left:8px !important}.gutter-sm-spacious{margin-right:-24px;margin-left:-24px}.gutter-sm-spacious>[class*="col-"]{padding-right:24px !important;padding-left:24px !important}}@media (min-width: 768px){.gutter-md{margin-right:-16px;margin-left:-16px}.gutter-md>[class*="col-"]{padding-right:16px !important;padding-left:16px !important}.gutter-md-condensed{margin-right:-8px;margin-left:-8px}.gutter-md-condensed>[class*="col-"]{padding-right:8px !important;padding-left:8px !important}.gutter-md-spacious{margin-right:-24px;margin-left:-24px}.gutter-md-spacious>[class*="col-"]{padding-right:24px !important;padding-left:24px !important}}@media (min-width: 1012px){.gutter-lg{margin-right:-16px;margin-left:-16px}.gutter-lg>[class*="col-"]{padding-right:16px !important;padding-left:16px !important}.gutter-lg-condensed{margin-right:-8px;margin-left:-8px}.gutter-lg-condensed>[class*="col-"]{padding-right:8px !important;padding-left:8px !important}.gutter-lg-spacious{margin-right:-24px;margin-left:-24px}.gutter-lg-spacious>[class*="col-"]{padding-right:24px !important;padding-left:24px !important}}@media (min-width: 1280px){.gutter-xl{margin-right:-16px;margin-left:-16px}.gutter-xl>[class*="col-"]{padding-right:16px !important;padding-left:16px !important}.gutter-xl-condensed{margin-right:-8px;margin-left:-8px}.gutter-xl-condensed>[class*="col-"]{padding-right:8px !important;padding-left:8px !important}.gutter-xl-spacious{margin-right:-24px;margin-left:-24px}.gutter-xl-spacious>[class*="col-"]{padding-right:24px !important;padding-left:24px !important}}.offset-1{margin-left:8.33333%}.offset-2{margin-left:16.66667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333%}.offset-5{margin-left:41.66667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333%}.offset-8{margin-left:66.66667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333%}.offset-11{margin-left:91.66667%}@media (min-width: 544px){.offset-sm-1{margin-left:8.33333%}.offset-sm-2{margin-left:16.66667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333%}.offset-sm-5{margin-left:41.66667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333%}.offset-sm-8{margin-left:66.66667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333%}.offset-sm-11{margin-left:91.66667%}}@media (min-width: 768px){.offset-md-1{margin-left:8.33333%}.offset-md-2{margin-left:16.66667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333%}.offset-md-5{margin-left:41.66667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333%}.offset-md-8{margin-left:66.66667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333%}.offset-md-11{margin-left:91.66667%}}@media (min-width: 1012px){.offset-lg-1{margin-left:8.33333%}.offset-lg-2{margin-left:16.66667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333%}.offset-lg-5{margin-left:41.66667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333%}.offset-lg-8{margin-left:66.66667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333%}.offset-lg-11{margin-left:91.66667%}}@media (min-width: 1280px){.offset-xl-1{margin-left:8.33333%}.offset-xl-2{margin-left:16.66667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333%}.offset-xl-5{margin-left:41.66667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333%}.offset-xl-8{margin-left:66.66667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333%}.offset-xl-11{margin-left:91.66667%}}.menu{margin-bottom:15px;list-style:none;background-color:#fff;border:1px solid #d1d5da;border-radius:3px}.menu-item{position:relative;display:block;padding:8px 10px;border-bottom:1px solid #e1e4e8}.menu-item:first-child{border-top:0;border-top-left-radius:2px;border-top-right-radius:2px}.menu-item:first-child::before{border-top-left-radius:2px}.menu-item:last-child{border-bottom:0;border-bottom-right-radius:2px;border-bottom-left-radius:2px}.menu-item:last-child::before{border-bottom-left-radius:2px}.menu-item:hover{text-decoration:none;background-color:#f6f8fa}.menu-item.selected{font-weight:600;color:#24292e;cursor:default;background-color:#fff}.menu-item.selected::before{position:absolute;top:0;bottom:0;left:0;width:2px;content:"";background-color:#e36209}.menu-item .octicon{width:16px;margin-right:5px;color:#24292e;text-align:center}.menu-item .Counter{float:right;margin-left:5px}.menu-item .menu-warning{float:right;color:#86181d}.menu-item .avatar{float:left;margin-right:5px}.menu-item.alert .Counter{color:#cb2431}.menu-heading{display:block;padding:8px 10px;margin-top:0;margin-bottom:0;font-size:13px;font-weight:600;line-height:20px;color:#586069;background-color:#f3f5f8;border-bottom:1px solid #e1e4e8}.menu-heading:hover{text-decoration:none}.menu-heading:first-child{border-top-left-radius:2px;border-top-right-radius:2px}.menu-heading:last-child{border-bottom:0;border-bottom-right-radius:2px;border-bottom-left-radius:2px}.tabnav{margin-top:0;margin-bottom:15px;border-bottom:1px solid #d1d5da}.tabnav .Counter{margin-left:5px}.tabnav-tabs{margin-bottom:-1px}.tabnav-tab{display:inline-block;padding:8px 12px;font-size:14px;line-height:20px;color:#586069;text-decoration:none;background-color:transparent;border:1px solid transparent;border-bottom:0}.tabnav-tab.selected{color:#24292e;background-color:#fff;border-color:#d1d5da;border-radius:3px 3px 0 0}.tabnav-tab:hover,.tabnav-tab:focus{color:#24292e;text-decoration:none}.tabnav-extra{display:inline-block;padding-top:10px;margin-left:10px;font-size:12px;color:#586069}.tabnav-extra>.octicon{margin-right:2px}a.tabnav-extra:hover{color:#0366d6;text-decoration:none}.tabnav-btn{margin-left:10px}.filter-list{list-style-type:none}.filter-list.small .filter-item{padding:4px 10px;margin:0 0 2px;font-size:12px}.filter-list.pjax-active .filter-item{color:#586069;background-color:transparent}.filter-list.pjax-active .filter-item.pjax-active{color:#fff;background-color:#0366d6}.filter-item{position:relative;display:block;padding:8px 10px;margin-bottom:5px;overflow:hidden;font-size:14px;color:#586069;text-decoration:none;text-overflow:ellipsis;white-space:nowrap;cursor:pointer;border-radius:3px}.filter-item:hover{text-decoration:none;background-color:#eaecef}.filter-item.selected{color:#fff;background-color:#0366d6}.filter-item .count{float:right;font-weight:600}.filter-item .bar{position:absolute;top:2px;right:0;bottom:2px;z-index:-1;display:inline-block;background-color:#eff3f6}.subnav{margin-bottom:20px}.subnav::before{display:table;content:""}.subnav::after{display:table;clear:both;content:""}.subnav-bordered{padding-bottom:20px;border-bottom:1px solid #eaecef}.subnav-flush{margin-bottom:0}.subnav-item{position:relative;float:left;padding:6px 14px;font-weight:600;line-height:20px;color:#586069;border:1px solid #e1e4e8}.subnav-item+.subnav-item{margin-left:-1px}.subnav-item:hover,.subnav-item:focus{text-decoration:none;background-color:#f6f8fa}.subnav-item.selected,.subnav-item.selected:hover,.subnav-item.selected:focus{z-index:2;color:#fff;background-color:#0366d6;border-color:#0366d6}.subnav-item:first-child{border-top-left-radius:3px;border-bottom-left-radius:3px}.subnav-item:last-child{border-top-right-radius:3px;border-bottom-right-radius:3px}.subnav-search{position:relative;margin-left:10px}.subnav-search-input{width:320px;padding-left:30px;color:#586069}.subnav-search-input-wide{width:500px}.subnav-search-icon{position:absolute;top:9px;left:8px;display:block;color:#c6cbd1;text-align:center;pointer-events:none}.subnav-search-context .btn{color:#444d56;border-top-right-radius:0;border-bottom-right-radius:0}.subnav-search-context .btn:hover,.subnav-search-context .btn:focus,.subnav-search-context .btn:active,.subnav-search-context .btn.selected{z-index:2}.subnav-search-context+.subnav-search{margin-left:-1px}.subnav-search-context+.subnav-search .subnav-search-input{border-top-left-radius:0;border-bottom-left-radius:0}.subnav-search-context .select-menu-modal-holder{z-index:30}.subnav-search-context .select-menu-modal{width:220px}.subnav-search-context .select-menu-item-icon{color:inherit}.subnav-spacer-right{padding-right:10px}.UnderlineNav{display:flex;justify-content:space-between;border-bottom:1px solid #e1e4e8}.UnderlineNav-body{display:flex;margin-bottom:-1px}.UnderlineNav-item{padding:16px 8px;margin-right:16px;font-size:14px;line-height:1.5;color:#586069;text-align:center;border-bottom:2px solid transparent}.UnderlineNav-item:hover,.UnderlineNav-item:focus{color:#24292e;text-decoration:none;border-bottom-color:#d1d5da;transition:0.2s ease}.UnderlineNav-item:hover .UnderlineNav-octicon,.UnderlineNav-item:focus .UnderlineNav-octicon{color:#6a737d}.UnderlineNav-item.selected{font-weight:600;color:#24292e;border-bottom-color:#e36209}.UnderlineNav-item.selected .UnderlineNav-octicon{color:#6a737d}.UnderlineNav--right{justify-content:flex-end}.UnderlineNav--right .UnderlineNav-item{margin-right:0;margin-left:16px}.UnderlineNav--right .UnderlineNav-actions{flex:1 1 auto}.UnderlineNav-actions{align-self:center}.UnderlineNav--full{display:block}.UnderlineNav-octicon{color:#959da5}.UnderlineNav-container{display:flex;justify-content:space-between}.pagination::before{display:table;content:""}.pagination::after{display:table;clear:both;content:""}.pagination a,.pagination span,.pagination em{position:relative;float:left;padding:7px 12px;margin-left:-1px;font-size:13px;font-style:normal;font-weight:600;color:#0366d6;white-space:nowrap;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background:#fff;border:1px solid #e1e4e8}.pagination a:first-child,.pagination span:first-child,.pagination em:first-child{margin-left:0;border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination a:last-child,.pagination span:last-child,.pagination em:last-child{border-top-right-radius:3px;border-bottom-right-radius:3px}.pagination a:hover,.pagination a:focus,.pagination span:hover,.pagination span:focus,.pagination em:hover,.pagination em:focus{z-index:2;text-decoration:none;background-color:#eff3f6;border-color:#e1e4e8}.pagination .selected{z-index:3}.pagination .current,.pagination .current:hover{z-index:3;color:#fff;background-color:#0366d6;border-color:#0366d6}.pagination .gap,.pagination .disabled,.pagination .gap:hover,.pagination .disabled:hover{color:#d1d5da;cursor:default;background-color:#fafbfc}.paginate-container{margin-top:20px;margin-bottom:15px;text-align:center}.paginate-container .pagination{display:inline-block}.tooltipped{position:relative}.tooltipped::after{position:absolute;z-index:1000000;display:none;padding:.5em .75em;font:normal normal 11px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";-webkit-font-smoothing:subpixel-antialiased;color:#fff;text-align:center;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-wrap:break-word;white-space:pre;pointer-events:none;content:attr(aria-label);background:#1b1f23;border-radius:3px;opacity:0}.tooltipped::before{position:absolute;z-index:1000001;display:none;width:0;height:0;color:#1b1f23;pointer-events:none;content:"";border:6px solid transparent;opacity:0}@keyframes tooltip-appear{from{opacity:0}to{opacity:1}}.tooltipped:hover::before,.tooltipped:hover::after,.tooltipped:active::before,.tooltipped:active::after,.tooltipped:focus::before,.tooltipped:focus::after{display:inline-block;text-decoration:none;animation-name:tooltip-appear;animation-duration:.1s;animation-fill-mode:forwards;animation-timing-function:ease-in;animation-delay:.4s}.tooltipped-no-delay:hover::before,.tooltipped-no-delay:hover::after,.tooltipped-no-delay:active::before,.tooltipped-no-delay:active::after,.tooltipped-no-delay:focus::before,.tooltipped-no-delay:focus::after{animation-delay:0s}.tooltipped-multiline:hover::after,.tooltipped-multiline:active::after,.tooltipped-multiline:focus::after{display:table-cell}.tooltipped-s::after,.tooltipped-se::after,.tooltipped-sw::after{top:100%;right:50%;margin-top:6px}.tooltipped-s::before,.tooltipped-se::before,.tooltipped-sw::before{top:auto;right:50%;bottom:-7px;margin-right:-6px;border-bottom-color:#1b1f23}.tooltipped-se::after{right:auto;left:50%;margin-left:-16px}.tooltipped-sw::after{margin-right:-16px}.tooltipped-n::after,.tooltipped-ne::after,.tooltipped-nw::after{right:50%;bottom:100%;margin-bottom:6px}.tooltipped-n::before,.tooltipped-ne::before,.tooltipped-nw::before{top:-7px;right:50%;bottom:auto;margin-right:-6px;border-top-color:#1b1f23}.tooltipped-ne::after{right:auto;left:50%;margin-left:-16px}.tooltipped-nw::after{margin-right:-16px}.tooltipped-s::after,.tooltipped-n::after{transform:translateX(50%)}.tooltipped-w::after{right:100%;bottom:50%;margin-right:6px;transform:translateY(50%)}.tooltipped-w::before{top:50%;bottom:50%;left:-7px;margin-top:-6px;border-left-color:#1b1f23}.tooltipped-e::after{bottom:50%;left:100%;margin-left:6px;transform:translateY(50%)}.tooltipped-e::before{top:50%;right:-7px;bottom:50%;margin-top:-6px;border-right-color:#1b1f23}.tooltipped-align-right-1::after,.tooltipped-align-right-2::after{right:0;margin-right:0}.tooltipped-align-right-1::before{right:10px}.tooltipped-align-right-2::before{right:15px}.tooltipped-align-left-1::after,.tooltipped-align-left-2::after{left:0;margin-left:0}.tooltipped-align-left-1::before{left:5px}.tooltipped-align-left-2::before{left:10px}.tooltipped-multiline::after{width:-webkit-max-content;width:-moz-max-content;width:max-content;max-width:250px;word-wrap:break-word;white-space:pre-line;border-collapse:separate}.tooltipped-multiline.tooltipped-s::after,.tooltipped-multiline.tooltipped-n::after{right:auto;left:50%;transform:translateX(-50%)}.tooltipped-multiline.tooltipped-w::after,.tooltipped-multiline.tooltipped-e::after{right:100%}@media screen and (min-width: 0\0){.tooltipped-multiline::after{width:250px}}.tooltipped-sticky::before,.tooltipped-sticky::after{display:inline-block}.tooltipped-sticky.tooltipped-multiline::after{display:table-cell}.css-truncate.css-truncate-target,.css-truncate .css-truncate-target{display:inline-block;max-width:125px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:top}.css-truncate.expandable.zeroclipboard-is-hover .css-truncate-target,.css-truncate.expandable.zeroclipboard-is-hover.css-truncate-target,.css-truncate.expandable:hover .css-truncate-target,.css-truncate.expandable:hover.css-truncate-target{max-width:10000px !important}.anim-fade-in{animation-name:fade-in;animation-duration:1s;animation-timing-function:ease-in-out}.anim-fade-in.fast{animation-duration:300ms}@keyframes fade-in{0%{opacity:0}100%{opacity:1}}.anim-fade-out{animation-name:fade-out;animation-duration:1s;animation-timing-function:ease-out}.anim-fade-out.fast{animation-duration:0.3s}@keyframes fade-out{0%{opacity:1}100%{opacity:0}}.anim-fade-up{opacity:0;animation-name:fade-up;animation-duration:0.3s;animation-fill-mode:forwards;animation-timing-function:ease-out;animation-delay:1s}@keyframes fade-up{0%{opacity:0.8;transform:translateY(100%)}100%{opacity:1;transform:translateY(0)}}.anim-fade-down{animation-name:fade-down;animation-duration:0.3s;animation-fill-mode:forwards;animation-timing-function:ease-in}@keyframes fade-down{0%{opacity:1;transform:translateY(0)}100%{opacity:0.5;transform:translateY(100%)}}.anim-grow-x{width:0%;animation-name:grow-x;animation-duration:0.3s;animation-fill-mode:forwards;animation-timing-function:ease;animation-delay:0.5s}@keyframes grow-x{to{width:100%}}.anim-shrink-x{animation-name:shrink-x;animation-duration:0.3s;animation-fill-mode:forwards;animation-timing-function:ease-in-out;animation-delay:0.5s}@keyframes shrink-x{to{width:0%}}.anim-scale-in{animation-name:scale-in;animation-duration:0.15s;animation-timing-function:cubic-bezier(0.2, 0, 0.13, 1.5)}@keyframes scale-in{0%{opacity:0;transform:scale(0.5)}100%{opacity:1;transform:scale(1)}}.anim-pulse{animation-name:pulse;animation-duration:2s;animation-timing-function:linear;animation-iteration-count:infinite}@keyframes pulse{0%{opacity:0.3}10%{opacity:1}100%{opacity:0.3}}.anim-pulse-in{animation-name:pulse-in;animation-duration:0.5s}@keyframes pulse-in{0%{transform:scale3d(1, 1, 1)}50%{transform:scale3d(1.1, 1.1, 1.1)}100%{transform:scale3d(1, 1, 1)}}.hover-grow{transition:transform 0.3s;-webkit-backface-visibility:hidden;backface-visibility:hidden}.hover-grow:hover{transform:scale(1.025)}.border{border:1px #e1e4e8 solid !important}.border-top{border-top:1px #e1e4e8 solid !important}.border-right{border-right:1px #e1e4e8 solid !important}.border-bottom{border-bottom:1px #e1e4e8 solid !important}.border-left{border-left:1px #e1e4e8 solid !important}.border-y{border-top:1px #e1e4e8 solid !important;border-bottom:1px #e1e4e8 solid !important}.border-dashed{border-style:dashed !important}.border-blue{border-color:#0366d6 !important}.border-blue-light{border-color:#c8e1ff !important}.border-green{border-color:#34d058 !important}.border-green-light{border-color:#a2cbac !important}.border-red{border-color:#d73a49 !important}.border-red-light{border-color:#cea0a5 !important}.border-purple{border-color:#6f42c1 !important}.border-yellow{border-color:#d9d0a5 !important}.border-gray-light{border-color:#eaecef !important}.border-gray-dark{border-color:#d1d5da !important}.border-black-fade{border-color:rgba(27,31,35,0.15) !important}.border-0{border:0 !important}.border-top-0{border-top:0 !important}.border-right-0{border-right:0 !important}.border-bottom-0{border-bottom:0 !important}.border-left-0{border-left:0 !important}.rounded-0{border-radius:0 !important}.rounded-1{border-radius:3px !important}.rounded-2{border-radius:6px !important}.circle{border-radius:50% !important}.box-shadow{box-shadow:0 1px 1px rgba(27,31,35,0.1) !important}.box-shadow-medium{box-shadow:0 1px 5px rgba(27,31,35,0.15) !important}.box-shadow-large{box-shadow:0 1px 15px rgba(27,31,35,0.15) !important}.box-shadow-extra-large{box-shadow:0 10px 50px rgba(27,31,35,0.07) !important}.box-shadow-none{box-shadow:none !important}.bg-white{background-color:#fff !important}.bg-blue{background-color:#0366d6 !important}.bg-blue-light{background-color:#f1f8ff !important}.bg-gray-dark{background-color:#24292e !important}.bg-gray{background-color:#f6f8fa !important}.bg-gray-light{background-color:#fafbfc !important}.bg-green{background-color:#28a745 !important}.bg-green-light{background-color:#dcffe4 !important}.bg-red{background-color:#d73a49 !important}.bg-red-light{background-color:#ffdce0 !important}.bg-yellow{background-color:#ffd33d !important}.bg-yellow-light{background-color:#fff5b1 !important}.bg-purple{background-color:#6f42c1 !important}.bg-purple-light{background-color:#f5f0ff !important}.bg-shade-gradient{background-image:linear-gradient(180deg, rgba(27,31,35,0.065), rgba(27,31,35,0)) !important;background-repeat:no-repeat !important;background-size:100% 200px !important}.text-blue{color:#0366d6 !important}.text-red{color:#cb2431 !important}.text-gray-light{color:#6a737d !important}.text-gray{color:#586069 !important}.text-gray-dark{color:#24292e !important}.text-green{color:#28a745 !important}.text-orange{color:#a04100 !important}.text-orange-light{color:#e36209 !important}.text-purple{color:#6f42c1 !important}.text-white{color:#fff !important}.text-inherit{color:inherit !important}.text-pending{color:#b08800 !important}.bg-pending{color:#dbab09 !important}.link-gray{color:#586069 !important}.link-gray:hover{color:#0366d6 !important}.link-gray-dark{color:#24292e !important}.link-gray-dark:hover{color:#0366d6 !important}.link-hover-blue:hover{color:#0366d6 !important}.muted-link{color:#586069 !important}.muted-link:hover{color:#0366d6 !important;text-decoration:none}.details-overlay[open]>summary::before{position:fixed;top:0;right:0;bottom:0;left:0;z-index:80;display:block;cursor:default;content:" ";background:transparent}.details-overlay-dark[open]>summary::before{z-index:99;background:rgba(27,31,35,0.5)}.flex-row{flex-direction:row !important}.flex-row-reverse{flex-direction:row-reverse !important}.flex-column{flex-direction:column !important}.flex-wrap{flex-wrap:wrap !important}.flex-nowrap{flex-wrap:nowrap !important}.flex-justify-start{justify-content:flex-start !important}.flex-justify-end{justify-content:flex-end !important}.flex-justify-center{justify-content:center !important}.flex-justify-between{justify-content:space-between !important}.flex-justify-around{justify-content:space-around !important}.flex-items-start{align-items:flex-start !important}.flex-items-end{align-items:flex-end !important}.flex-items-center{align-items:center !important}.flex-items-baseline{align-items:baseline !important}.flex-items-stretch{align-items:stretch !important}.flex-content-start{align-content:flex-start !important}.flex-content-end{align-content:flex-end !important}.flex-content-center{align-content:center !important}.flex-content-between{align-content:space-between !important}.flex-content-around{align-content:space-around !important}.flex-content-stretch{align-content:stretch !important}.flex-auto{flex:1 1 auto !important}.flex-shrink-0{flex-shrink:0 !important}.flex-self-auto{align-self:auto !important}.flex-self-start{align-self:flex-start !important}.flex-self-end{align-self:flex-end !important}.flex-self-center{align-self:center !important}.flex-self-baseline{align-self:baseline !important}.flex-self-stretch{align-self:stretch !important}.flex-item-equal{flex-grow:1;flex-basis:0}@media (min-width: 544px){.flex-sm-row{flex-direction:row !important}.flex-sm-row-reverse{flex-direction:row-reverse !important}.flex-sm-column{flex-direction:column !important}.flex-sm-wrap{flex-wrap:wrap !important}.flex-sm-nowrap{flex-wrap:nowrap !important}.flex-sm-justify-start{justify-content:flex-start !important}.flex-sm-justify-end{justify-content:flex-end !important}.flex-sm-justify-center{justify-content:center !important}.flex-sm-justify-between{justify-content:space-between !important}.flex-sm-justify-around{justify-content:space-around !important}.flex-sm-items-start{align-items:flex-start !important}.flex-sm-items-end{align-items:flex-end !important}.flex-sm-items-center{align-items:center !important}.flex-sm-items-baseline{align-items:baseline !important}.flex-sm-items-stretch{align-items:stretch !important}.flex-sm-content-start{align-content:flex-start !important}.flex-sm-content-end{align-content:flex-end !important}.flex-sm-content-center{align-content:center !important}.flex-sm-content-between{align-content:space-between !important}.flex-sm-content-around{align-content:space-around !important}.flex-sm-content-stretch{align-content:stretch !important}.flex-sm-auto{flex:1 1 auto !important}.flex-sm-shrink-0{flex-shrink:0 !important}.flex-sm-self-auto{align-self:auto !important}.flex-sm-self-start{align-self:flex-start !important}.flex-sm-self-end{align-self:flex-end !important}.flex-sm-self-center{align-self:center !important}.flex-sm-self-baseline{align-self:baseline !important}.flex-sm-self-stretch{align-self:stretch !important}.flex-sm-item-equal{flex-grow:1;flex-basis:0}}@media (min-width: 768px){.flex-md-row{flex-direction:row !important}.flex-md-row-reverse{flex-direction:row-reverse !important}.flex-md-column{flex-direction:column !important}.flex-md-wrap{flex-wrap:wrap !important}.flex-md-nowrap{flex-wrap:nowrap !important}.flex-md-justify-start{justify-content:flex-start !important}.flex-md-justify-end{justify-content:flex-end !important}.flex-md-justify-center{justify-content:center !important}.flex-md-justify-between{justify-content:space-between !important}.flex-md-justify-around{justify-content:space-around !important}.flex-md-items-start{align-items:flex-start !important}.flex-md-items-end{align-items:flex-end !important}.flex-md-items-center{align-items:center !important}.flex-md-items-baseline{align-items:baseline !important}.flex-md-items-stretch{align-items:stretch !important}.flex-md-content-start{align-content:flex-start !important}.flex-md-content-end{align-content:flex-end !important}.flex-md-content-center{align-content:center !important}.flex-md-content-between{align-content:space-between !important}.flex-md-content-around{align-content:space-around !important}.flex-md-content-stretch{align-content:stretch !important}.flex-md-auto{flex:1 1 auto !important}.flex-md-shrink-0{flex-shrink:0 !important}.flex-md-self-auto{align-self:auto !important}.flex-md-self-start{align-self:flex-start !important}.flex-md-self-end{align-self:flex-end !important}.flex-md-self-center{align-self:center !important}.flex-md-self-baseline{align-self:baseline !important}.flex-md-self-stretch{align-self:stretch !important}.flex-md-item-equal{flex-grow:1;flex-basis:0}}@media (min-width: 1012px){.flex-lg-row{flex-direction:row !important}.flex-lg-row-reverse{flex-direction:row-reverse !important}.flex-lg-column{flex-direction:column !important}.flex-lg-wrap{flex-wrap:wrap !important}.flex-lg-nowrap{flex-wrap:nowrap !important}.flex-lg-justify-start{justify-content:flex-start !important}.flex-lg-justify-end{justify-content:flex-end !important}.flex-lg-justify-center{justify-content:center !important}.flex-lg-justify-between{justify-content:space-between !important}.flex-lg-justify-around{justify-content:space-around !important}.flex-lg-items-start{align-items:flex-start !important}.flex-lg-items-end{align-items:flex-end !important}.flex-lg-items-center{align-items:center !important}.flex-lg-items-baseline{align-items:baseline !important}.flex-lg-items-stretch{align-items:stretch !important}.flex-lg-content-start{align-content:flex-start !important}.flex-lg-content-end{align-content:flex-end !important}.flex-lg-content-center{align-content:center !important}.flex-lg-content-between{align-content:space-between !important}.flex-lg-content-around{align-content:space-around !important}.flex-lg-content-stretch{align-content:stretch !important}.flex-lg-auto{flex:1 1 auto !important}.flex-lg-shrink-0{flex-shrink:0 !important}.flex-lg-self-auto{align-self:auto !important}.flex-lg-self-start{align-self:flex-start !important}.flex-lg-self-end{align-self:flex-end !important}.flex-lg-self-center{align-self:center !important}.flex-lg-self-baseline{align-self:baseline !important}.flex-lg-self-stretch{align-self:stretch !important}.flex-lg-item-equal{flex-grow:1;flex-basis:0}}@media (min-width: 1280px){.flex-xl-row{flex-direction:row !important}.flex-xl-row-reverse{flex-direction:row-reverse !important}.flex-xl-column{flex-direction:column !important}.flex-xl-wrap{flex-wrap:wrap !important}.flex-xl-nowrap{flex-wrap:nowrap !important}.flex-xl-justify-start{justify-content:flex-start !important}.flex-xl-justify-end{justify-content:flex-end !important}.flex-xl-justify-center{justify-content:center !important}.flex-xl-justify-between{justify-content:space-between !important}.flex-xl-justify-around{justify-content:space-around !important}.flex-xl-items-start{align-items:flex-start !important}.flex-xl-items-end{align-items:flex-end !important}.flex-xl-items-center{align-items:center !important}.flex-xl-items-baseline{align-items:baseline !important}.flex-xl-items-stretch{align-items:stretch !important}.flex-xl-content-start{align-content:flex-start !important}.flex-xl-content-end{align-content:flex-end !important}.flex-xl-content-center{align-content:center !important}.flex-xl-content-between{align-content:space-between !important}.flex-xl-content-around{align-content:space-around !important}.flex-xl-content-stretch{align-content:stretch !important}.flex-xl-auto{flex:1 1 auto !important}.flex-xl-shrink-0{flex-shrink:0 !important}.flex-xl-self-auto{align-self:auto !important}.flex-xl-self-start{align-self:flex-start !important}.flex-xl-self-end{align-self:flex-end !important}.flex-xl-self-center{align-self:center !important}.flex-xl-self-baseline{align-self:baseline !important}.flex-xl-self-stretch{align-self:stretch !important}.flex-xl-item-equal{flex-grow:1;flex-basis:0}}.position-static{position:static !important}.position-relative{position:relative !important}.position-absolute{position:absolute !important}.position-fixed{position:fixed !important}.top-0{top:0 !important}.right-0{right:0 !important}.bottom-0{bottom:0 !important}.left-0{left:0 !important}.v-align-middle{vertical-align:middle !important}.v-align-top{vertical-align:top !important}.v-align-bottom{vertical-align:bottom !important}.v-align-text-top{vertical-align:text-top !important}.v-align-text-bottom{vertical-align:text-bottom !important}.v-align-baseline{vertical-align:baseline !important}.overflow-hidden{overflow:hidden !important}.overflow-scroll{overflow:scroll !important}.overflow-auto{overflow:auto !important}.clearfix::before{display:table;content:""}.clearfix::after{display:table;clear:both;content:""}.float-right{float:right !important}.float-left{float:left !important}.float-none{float:none !important}@media (min-width: 544px){.float-sm-left{float:left !important}.float-sm-right{float:right !important}.float-sm-none{float:none !important}}@media (min-width: 768px){.float-md-left{float:left !important}.float-md-right{float:right !important}.float-md-none{float:none !important}}@media (min-width: 1012px){.float-lg-left{float:left !important}.float-lg-right{float:right !important}.float-lg-none{float:none !important}}@media (min-width: 1280px){.float-xl-left{float:left !important}.float-xl-right{float:right !important}.float-xl-none{float:none !important}}.width-fit{max-width:100% !important}.width-full{width:100% !important}.height-fit{max-height:100% !important}.height-full{height:100% !important}.min-width-0{min-width:0 !important}.direction-rtl{direction:rtl !important}.direction-ltr{direction:ltr !important}@media (min-width: 544px){.direction-sm-rtl{direction:rtl !important}.direction-sm-ltr{direction:ltr !important}}@media (min-width: 768px){.direction-md-rtl{direction:rtl !important}.direction-md-ltr{direction:ltr !important}}@media (min-width: 1012px){.direction-lg-rtl{direction:rtl !important}.direction-lg-ltr{direction:ltr !important}}@media (min-width: 1280px){.direction-xl-rtl{direction:rtl !important}.direction-xl-ltr{direction:ltr !important}}.m-0{margin:0 !important}.mt-0{margin-top:0 !important}.mr-0{margin-right:0 !important}.mb-0{margin-bottom:0 !important}.ml-0{margin-left:0 !important}.mt-n0{margin-top:-0 !important}.mr-n0{margin-right:-0 !important}.mb-n0{margin-bottom:-0 !important}.ml-n0{margin-left:-0 !important}.mx-0{margin-right:0 !important;margin-left:0 !important}.my-0{margin-top:0 !important;margin-bottom:0 !important}.m-1{margin:4px !important}.mt-1{margin-top:4px !important}.mr-1{margin-right:4px !important}.mb-1{margin-bottom:4px !important}.ml-1{margin-left:4px !important}.mt-n1{margin-top:-4px !important}.mr-n1{margin-right:-4px !important}.mb-n1{margin-bottom:-4px !important}.ml-n1{margin-left:-4px !important}.mx-1{margin-right:4px !important;margin-left:4px !important}.my-1{margin-top:4px !important;margin-bottom:4px !important}.m-2{margin:8px !important}.mt-2{margin-top:8px !important}.mr-2{margin-right:8px !important}.mb-2{margin-bottom:8px !important}.ml-2{margin-left:8px !important}.mt-n2{margin-top:-8px !important}.mr-n2{margin-right:-8px !important}.mb-n2{margin-bottom:-8px !important}.ml-n2{margin-left:-8px !important}.mx-2{margin-right:8px !important;margin-left:8px !important}.my-2{margin-top:8px !important;margin-bottom:8px !important}.m-3{margin:16px !important}.mt-3{margin-top:16px !important}.mr-3{margin-right:16px !important}.mb-3{margin-bottom:16px !important}.ml-3{margin-left:16px !important}.mt-n3{margin-top:-16px !important}.mr-n3{margin-right:-16px !important}.mb-n3{margin-bottom:-16px !important}.ml-n3{margin-left:-16px !important}.mx-3{margin-right:16px !important;margin-left:16px !important}.my-3{margin-top:16px !important;margin-bottom:16px !important}.m-4{margin:24px !important}.mt-4{margin-top:24px !important}.mr-4{margin-right:24px !important}.mb-4{margin-bottom:24px !important}.ml-4{margin-left:24px !important}.mt-n4{margin-top:-24px !important}.mr-n4{margin-right:-24px !important}.mb-n4{margin-bottom:-24px !important}.ml-n4{margin-left:-24px !important}.mx-4{margin-right:24px !important;margin-left:24px !important}.my-4{margin-top:24px !important;margin-bottom:24px !important}.m-5{margin:32px !important}.mt-5{margin-top:32px !important}.mr-5{margin-right:32px !important}.mb-5{margin-bottom:32px !important}.ml-5{margin-left:32px !important}.mt-n5{margin-top:-32px !important}.mr-n5{margin-right:-32px !important}.mb-n5{margin-bottom:-32px !important}.ml-n5{margin-left:-32px !important}.mx-5{margin-right:32px !important;margin-left:32px !important}.my-5{margin-top:32px !important;margin-bottom:32px !important}.m-6{margin:40px !important}.mt-6{margin-top:40px !important}.mr-6{margin-right:40px !important}.mb-6{margin-bottom:40px !important}.ml-6{margin-left:40px !important}.mt-n6{margin-top:-40px !important}.mr-n6{margin-right:-40px !important}.mb-n6{margin-bottom:-40px !important}.ml-n6{margin-left:-40px !important}.mx-6{margin-right:40px !important;margin-left:40px !important}.my-6{margin-top:40px !important;margin-bottom:40px !important}.mx-auto{margin-right:auto !important;margin-left:auto !important}@media (min-width: 544px){.m-sm-0{margin:0 !important}.mt-sm-0{margin-top:0 !important}.mr-sm-0{margin-right:0 !important}.mb-sm-0{margin-bottom:0 !important}.ml-sm-0{margin-left:0 !important}.mt-sm-n0{margin-top:-0 !important}.mr-sm-n0{margin-right:-0 !important}.mb-sm-n0{margin-bottom:-0 !important}.ml-sm-n0{margin-left:-0 !important}.mx-sm-0{margin-right:0 !important;margin-left:0 !important}.my-sm-0{margin-top:0 !important;margin-bottom:0 !important}}@media (min-width: 544px){.m-sm-1{margin:4px !important}.mt-sm-1{margin-top:4px !important}.mr-sm-1{margin-right:4px !important}.mb-sm-1{margin-bottom:4px !important}.ml-sm-1{margin-left:4px !important}.mt-sm-n1{margin-top:-4px !important}.mr-sm-n1{margin-right:-4px !important}.mb-sm-n1{margin-bottom:-4px !important}.ml-sm-n1{margin-left:-4px !important}.mx-sm-1{margin-right:4px !important;margin-left:4px !important}.my-sm-1{margin-top:4px !important;margin-bottom:4px !important}}@media (min-width: 544px){.m-sm-2{margin:8px !important}.mt-sm-2{margin-top:8px !important}.mr-sm-2{margin-right:8px !important}.mb-sm-2{margin-bottom:8px !important}.ml-sm-2{margin-left:8px !important}.mt-sm-n2{margin-top:-8px !important}.mr-sm-n2{margin-right:-8px !important}.mb-sm-n2{margin-bottom:-8px !important}.ml-sm-n2{margin-left:-8px !important}.mx-sm-2{margin-right:8px !important;margin-left:8px !important}.my-sm-2{margin-top:8px !important;margin-bottom:8px !important}}@media (min-width: 544px){.m-sm-3{margin:16px !important}.mt-sm-3{margin-top:16px !important}.mr-sm-3{margin-right:16px !important}.mb-sm-3{margin-bottom:16px !important}.ml-sm-3{margin-left:16px !important}.mt-sm-n3{margin-top:-16px !important}.mr-sm-n3{margin-right:-16px !important}.mb-sm-n3{margin-bottom:-16px !important}.ml-sm-n3{margin-left:-16px !important}.mx-sm-3{margin-right:16px !important;margin-left:16px !important}.my-sm-3{margin-top:16px !important;margin-bottom:16px !important}}@media (min-width: 544px){.m-sm-4{margin:24px !important}.mt-sm-4{margin-top:24px !important}.mr-sm-4{margin-right:24px !important}.mb-sm-4{margin-bottom:24px !important}.ml-sm-4{margin-left:24px !important}.mt-sm-n4{margin-top:-24px !important}.mr-sm-n4{margin-right:-24px !important}.mb-sm-n4{margin-bottom:-24px !important}.ml-sm-n4{margin-left:-24px !important}.mx-sm-4{margin-right:24px !important;margin-left:24px !important}.my-sm-4{margin-top:24px !important;margin-bottom:24px !important}}@media (min-width: 544px){.m-sm-5{margin:32px !important}.mt-sm-5{margin-top:32px !important}.mr-sm-5{margin-right:32px !important}.mb-sm-5{margin-bottom:32px !important}.ml-sm-5{margin-left:32px !important}.mt-sm-n5{margin-top:-32px !important}.mr-sm-n5{margin-right:-32px !important}.mb-sm-n5{margin-bottom:-32px !important}.ml-sm-n5{margin-left:-32px !important}.mx-sm-5{margin-right:32px !important;margin-left:32px !important}.my-sm-5{margin-top:32px !important;margin-bottom:32px !important}}@media (min-width: 544px){.m-sm-6{margin:40px !important}.mt-sm-6{margin-top:40px !important}.mr-sm-6{margin-right:40px !important}.mb-sm-6{margin-bottom:40px !important}.ml-sm-6{margin-left:40px !important}.mt-sm-n6{margin-top:-40px !important}.mr-sm-n6{margin-right:-40px !important}.mb-sm-n6{margin-bottom:-40px !important}.ml-sm-n6{margin-left:-40px !important}.mx-sm-6{margin-right:40px !important;margin-left:40px !important}.my-sm-6{margin-top:40px !important;margin-bottom:40px !important}}@media (min-width: 768px){.m-md-0{margin:0 !important}.mt-md-0{margin-top:0 !important}.mr-md-0{margin-right:0 !important}.mb-md-0{margin-bottom:0 !important}.ml-md-0{margin-left:0 !important}.mt-md-n0{margin-top:-0 !important}.mr-md-n0{margin-right:-0 !important}.mb-md-n0{margin-bottom:-0 !important}.ml-md-n0{margin-left:-0 !important}.mx-md-0{margin-right:0 !important;margin-left:0 !important}.my-md-0{margin-top:0 !important;margin-bottom:0 !important}}@media (min-width: 768px){.m-md-1{margin:4px !important}.mt-md-1{margin-top:4px !important}.mr-md-1{margin-right:4px !important}.mb-md-1{margin-bottom:4px !important}.ml-md-1{margin-left:4px !important}.mt-md-n1{margin-top:-4px !important}.mr-md-n1{margin-right:-4px !important}.mb-md-n1{margin-bottom:-4px !important}.ml-md-n1{margin-left:-4px !important}.mx-md-1{margin-right:4px !important;margin-left:4px !important}.my-md-1{margin-top:4px !important;margin-bottom:4px !important}}@media (min-width: 768px){.m-md-2{margin:8px !important}.mt-md-2{margin-top:8px !important}.mr-md-2{margin-right:8px !important}.mb-md-2{margin-bottom:8px !important}.ml-md-2{margin-left:8px !important}.mt-md-n2{margin-top:-8px !important}.mr-md-n2{margin-right:-8px !important}.mb-md-n2{margin-bottom:-8px !important}.ml-md-n2{margin-left:-8px !important}.mx-md-2{margin-right:8px !important;margin-left:8px !important}.my-md-2{margin-top:8px !important;margin-bottom:8px !important}}@media (min-width: 768px){.m-md-3{margin:16px !important}.mt-md-3{margin-top:16px !important}.mr-md-3{margin-right:16px !important}.mb-md-3{margin-bottom:16px !important}.ml-md-3{margin-left:16px !important}.mt-md-n3{margin-top:-16px !important}.mr-md-n3{margin-right:-16px !important}.mb-md-n3{margin-bottom:-16px !important}.ml-md-n3{margin-left:-16px !important}.mx-md-3{margin-right:16px !important;margin-left:16px !important}.my-md-3{margin-top:16px !important;margin-bottom:16px !important}}@media (min-width: 768px){.m-md-4{margin:24px !important}.mt-md-4{margin-top:24px !important}.mr-md-4{margin-right:24px !important}.mb-md-4{margin-bottom:24px !important}.ml-md-4{margin-left:24px !important}.mt-md-n4{margin-top:-24px !important}.mr-md-n4{margin-right:-24px !important}.mb-md-n4{margin-bottom:-24px !important}.ml-md-n4{margin-left:-24px !important}.mx-md-4{margin-right:24px !important;margin-left:24px !important}.my-md-4{margin-top:24px !important;margin-bottom:24px !important}}@media (min-width: 768px){.m-md-5{margin:32px !important}.mt-md-5{margin-top:32px !important}.mr-md-5{margin-right:32px !important}.mb-md-5{margin-bottom:32px !important}.ml-md-5{margin-left:32px !important}.mt-md-n5{margin-top:-32px !important}.mr-md-n5{margin-right:-32px !important}.mb-md-n5{margin-bottom:-32px !important}.ml-md-n5{margin-left:-32px !important}.mx-md-5{margin-right:32px !important;margin-left:32px !important}.my-md-5{margin-top:32px !important;margin-bottom:32px !important}}@media (min-width: 768px){.m-md-6{margin:40px !important}.mt-md-6{margin-top:40px !important}.mr-md-6{margin-right:40px !important}.mb-md-6{margin-bottom:40px !important}.ml-md-6{margin-left:40px !important}.mt-md-n6{margin-top:-40px !important}.mr-md-n6{margin-right:-40px !important}.mb-md-n6{margin-bottom:-40px !important}.ml-md-n6{margin-left:-40px !important}.mx-md-6{margin-right:40px !important;margin-left:40px !important}.my-md-6{margin-top:40px !important;margin-bottom:40px !important}}@media (min-width: 1012px){.m-lg-0{margin:0 !important}.mt-lg-0{margin-top:0 !important}.mr-lg-0{margin-right:0 !important}.mb-lg-0{margin-bottom:0 !important}.ml-lg-0{margin-left:0 !important}.mt-lg-n0{margin-top:-0 !important}.mr-lg-n0{margin-right:-0 !important}.mb-lg-n0{margin-bottom:-0 !important}.ml-lg-n0{margin-left:-0 !important}.mx-lg-0{margin-right:0 !important;margin-left:0 !important}.my-lg-0{margin-top:0 !important;margin-bottom:0 !important}}@media (min-width: 1012px){.m-lg-1{margin:4px !important}.mt-lg-1{margin-top:4px !important}.mr-lg-1{margin-right:4px !important}.mb-lg-1{margin-bottom:4px !important}.ml-lg-1{margin-left:4px !important}.mt-lg-n1{margin-top:-4px !important}.mr-lg-n1{margin-right:-4px !important}.mb-lg-n1{margin-bottom:-4px !important}.ml-lg-n1{margin-left:-4px !important}.mx-lg-1{margin-right:4px !important;margin-left:4px !important}.my-lg-1{margin-top:4px !important;margin-bottom:4px !important}}@media (min-width: 1012px){.m-lg-2{margin:8px !important}.mt-lg-2{margin-top:8px !important}.mr-lg-2{margin-right:8px !important}.mb-lg-2{margin-bottom:8px !important}.ml-lg-2{margin-left:8px !important}.mt-lg-n2{margin-top:-8px !important}.mr-lg-n2{margin-right:-8px !important}.mb-lg-n2{margin-bottom:-8px !important}.ml-lg-n2{margin-left:-8px !important}.mx-lg-2{margin-right:8px !important;margin-left:8px !important}.my-lg-2{margin-top:8px !important;margin-bottom:8px !important}}@media (min-width: 1012px){.m-lg-3{margin:16px !important}.mt-lg-3{margin-top:16px !important}.mr-lg-3{margin-right:16px !important}.mb-lg-3{margin-bottom:16px !important}.ml-lg-3{margin-left:16px !important}.mt-lg-n3{margin-top:-16px !important}.mr-lg-n3{margin-right:-16px !important}.mb-lg-n3{margin-bottom:-16px !important}.ml-lg-n3{margin-left:-16px !important}.mx-lg-3{margin-right:16px !important;margin-left:16px !important}.my-lg-3{margin-top:16px !important;margin-bottom:16px !important}}@media (min-width: 1012px){.m-lg-4{margin:24px !important}.mt-lg-4{margin-top:24px !important}.mr-lg-4{margin-right:24px !important}.mb-lg-4{margin-bottom:24px !important}.ml-lg-4{margin-left:24px !important}.mt-lg-n4{margin-top:-24px !important}.mr-lg-n4{margin-right:-24px !important}.mb-lg-n4{margin-bottom:-24px !important}.ml-lg-n4{margin-left:-24px !important}.mx-lg-4{margin-right:24px !important;margin-left:24px !important}.my-lg-4{margin-top:24px !important;margin-bottom:24px !important}}@media (min-width: 1012px){.m-lg-5{margin:32px !important}.mt-lg-5{margin-top:32px !important}.mr-lg-5{margin-right:32px !important}.mb-lg-5{margin-bottom:32px !important}.ml-lg-5{margin-left:32px !important}.mt-lg-n5{margin-top:-32px !important}.mr-lg-n5{margin-right:-32px !important}.mb-lg-n5{margin-bottom:-32px !important}.ml-lg-n5{margin-left:-32px !important}.mx-lg-5{margin-right:32px !important;margin-left:32px !important}.my-lg-5{margin-top:32px !important;margin-bottom:32px !important}}@media (min-width: 1012px){.m-lg-6{margin:40px !important}.mt-lg-6{margin-top:40px !important}.mr-lg-6{margin-right:40px !important}.mb-lg-6{margin-bottom:40px !important}.ml-lg-6{margin-left:40px !important}.mt-lg-n6{margin-top:-40px !important}.mr-lg-n6{margin-right:-40px !important}.mb-lg-n6{margin-bottom:-40px !important}.ml-lg-n6{margin-left:-40px !important}.mx-lg-6{margin-right:40px !important;margin-left:40px !important}.my-lg-6{margin-top:40px !important;margin-bottom:40px !important}}@media (min-width: 1280px){.m-xl-0{margin:0 !important}.mt-xl-0{margin-top:0 !important}.mr-xl-0{margin-right:0 !important}.mb-xl-0{margin-bottom:0 !important}.ml-xl-0{margin-left:0 !important}.mt-xl-n0{margin-top:-0 !important}.mr-xl-n0{margin-right:-0 !important}.mb-xl-n0{margin-bottom:-0 !important}.ml-xl-n0{margin-left:-0 !important}.mx-xl-0{margin-right:0 !important;margin-left:0 !important}.my-xl-0{margin-top:0 !important;margin-bottom:0 !important}}@media (min-width: 1280px){.m-xl-1{margin:4px !important}.mt-xl-1{margin-top:4px !important}.mr-xl-1{margin-right:4px !important}.mb-xl-1{margin-bottom:4px !important}.ml-xl-1{margin-left:4px !important}.mt-xl-n1{margin-top:-4px !important}.mr-xl-n1{margin-right:-4px !important}.mb-xl-n1{margin-bottom:-4px !important}.ml-xl-n1{margin-left:-4px !important}.mx-xl-1{margin-right:4px !important;margin-left:4px !important}.my-xl-1{margin-top:4px !important;margin-bottom:4px !important}}@media (min-width: 1280px){.m-xl-2{margin:8px !important}.mt-xl-2{margin-top:8px !important}.mr-xl-2{margin-right:8px !important}.mb-xl-2{margin-bottom:8px !important}.ml-xl-2{margin-left:8px !important}.mt-xl-n2{margin-top:-8px !important}.mr-xl-n2{margin-right:-8px !important}.mb-xl-n2{margin-bottom:-8px !important}.ml-xl-n2{margin-left:-8px !important}.mx-xl-2{margin-right:8px !important;margin-left:8px !important}.my-xl-2{margin-top:8px !important;margin-bottom:8px !important}}@media (min-width: 1280px){.m-xl-3{margin:16px !important}.mt-xl-3{margin-top:16px !important}.mr-xl-3{margin-right:16px !important}.mb-xl-3{margin-bottom:16px !important}.ml-xl-3{margin-left:16px !important}.mt-xl-n3{margin-top:-16px !important}.mr-xl-n3{margin-right:-16px !important}.mb-xl-n3{margin-bottom:-16px !important}.ml-xl-n3{margin-left:-16px !important}.mx-xl-3{margin-right:16px !important;margin-left:16px !important}.my-xl-3{margin-top:16px !important;margin-bottom:16px !important}}@media (min-width: 1280px){.m-xl-4{margin:24px !important}.mt-xl-4{margin-top:24px !important}.mr-xl-4{margin-right:24px !important}.mb-xl-4{margin-bottom:24px !important}.ml-xl-4{margin-left:24px !important}.mt-xl-n4{margin-top:-24px !important}.mr-xl-n4{margin-right:-24px !important}.mb-xl-n4{margin-bottom:-24px !important}.ml-xl-n4{margin-left:-24px !important}.mx-xl-4{margin-right:24px !important;margin-left:24px !important}.my-xl-4{margin-top:24px !important;margin-bottom:24px !important}}@media (min-width: 1280px){.m-xl-5{margin:32px !important}.mt-xl-5{margin-top:32px !important}.mr-xl-5{margin-right:32px !important}.mb-xl-5{margin-bottom:32px !important}.ml-xl-5{margin-left:32px !important}.mt-xl-n5{margin-top:-32px !important}.mr-xl-n5{margin-right:-32px !important}.mb-xl-n5{margin-bottom:-32px !important}.ml-xl-n5{margin-left:-32px !important}.mx-xl-5{margin-right:32px !important;margin-left:32px !important}.my-xl-5{margin-top:32px !important;margin-bottom:32px !important}}@media (min-width: 1280px){.m-xl-6{margin:40px !important}.mt-xl-6{margin-top:40px !important}.mr-xl-6{margin-right:40px !important}.mb-xl-6{margin-bottom:40px !important}.ml-xl-6{margin-left:40px !important}.mt-xl-n6{margin-top:-40px !important}.mr-xl-n6{margin-right:-40px !important}.mb-xl-n6{margin-bottom:-40px !important}.ml-xl-n6{margin-left:-40px !important}.mx-xl-6{margin-right:40px !important;margin-left:40px !important}.my-xl-6{margin-top:40px !important;margin-bottom:40px !important}}.p-0{padding:0 !important}.pt-0{padding-top:0 !important}.pr-0{padding-right:0 !important}.pb-0{padding-bottom:0 !important}.pl-0{padding-left:0 !important}.px-0{padding-right:0 !important;padding-left:0 !important}.py-0{padding-top:0 !important;padding-bottom:0 !important}.p-1{padding:4px !important}.pt-1{padding-top:4px !important}.pr-1{padding-right:4px !important}.pb-1{padding-bottom:4px !important}.pl-1{padding-left:4px !important}.px-1{padding-right:4px !important;padding-left:4px !important}.py-1{padding-top:4px !important;padding-bottom:4px !important}.p-2{padding:8px !important}.pt-2{padding-top:8px !important}.pr-2{padding-right:8px !important}.pb-2{padding-bottom:8px !important}.pl-2{padding-left:8px !important}.px-2{padding-right:8px !important;padding-left:8px !important}.py-2{padding-top:8px !important;padding-bottom:8px !important}.p-3{padding:16px !important}.pt-3{padding-top:16px !important}.pr-3{padding-right:16px !important}.pb-3{padding-bottom:16px !important}.pl-3{padding-left:16px !important}.px-3{padding-right:16px !important;padding-left:16px !important}.py-3{padding-top:16px !important;padding-bottom:16px !important}.p-4{padding:24px !important}.pt-4{padding-top:24px !important}.pr-4{padding-right:24px !important}.pb-4{padding-bottom:24px !important}.pl-4{padding-left:24px !important}.px-4{padding-right:24px !important;padding-left:24px !important}.py-4{padding-top:24px !important;padding-bottom:24px !important}.p-5{padding:32px !important}.pt-5{padding-top:32px !important}.pr-5{padding-right:32px !important}.pb-5{padding-bottom:32px !important}.pl-5{padding-left:32px !important}.px-5{padding-right:32px !important;padding-left:32px !important}.py-5{padding-top:32px !important;padding-bottom:32px !important}.p-6{padding:40px !important}.pt-6{padding-top:40px !important}.pr-6{padding-right:40px !important}.pb-6{padding-bottom:40px !important}.pl-6{padding-left:40px !important}.px-6{padding-right:40px !important;padding-left:40px !important}.py-6{padding-top:40px !important;padding-bottom:40px !important}@media (min-width: 544px){.p-sm-0{padding:0 !important}.pt-sm-0{padding-top:0 !important}.pr-sm-0{padding-right:0 !important}.pb-sm-0{padding-bottom:0 !important}.pl-sm-0{padding-left:0 !important}.px-sm-0{padding-right:0 !important;padding-left:0 !important}.py-sm-0{padding-top:0 !important;padding-bottom:0 !important}}@media (min-width: 544px){.p-sm-1{padding:4px !important}.pt-sm-1{padding-top:4px !important}.pr-sm-1{padding-right:4px !important}.pb-sm-1{padding-bottom:4px !important}.pl-sm-1{padding-left:4px !important}.px-sm-1{padding-right:4px !important;padding-left:4px !important}.py-sm-1{padding-top:4px !important;padding-bottom:4px !important}}@media (min-width: 544px){.p-sm-2{padding:8px !important}.pt-sm-2{padding-top:8px !important}.pr-sm-2{padding-right:8px !important}.pb-sm-2{padding-bottom:8px !important}.pl-sm-2{padding-left:8px !important}.px-sm-2{padding-right:8px !important;padding-left:8px !important}.py-sm-2{padding-top:8px !important;padding-bottom:8px !important}}@media (min-width: 544px){.p-sm-3{padding:16px !important}.pt-sm-3{padding-top:16px !important}.pr-sm-3{padding-right:16px !important}.pb-sm-3{padding-bottom:16px !important}.pl-sm-3{padding-left:16px !important}.px-sm-3{padding-right:16px !important;padding-left:16px !important}.py-sm-3{padding-top:16px !important;padding-bottom:16px !important}}@media (min-width: 544px){.p-sm-4{padding:24px !important}.pt-sm-4{padding-top:24px !important}.pr-sm-4{padding-right:24px !important}.pb-sm-4{padding-bottom:24px !important}.pl-sm-4{padding-left:24px !important}.px-sm-4{padding-right:24px !important;padding-left:24px !important}.py-sm-4{padding-top:24px !important;padding-bottom:24px !important}}@media (min-width: 544px){.p-sm-5{padding:32px !important}.pt-sm-5{padding-top:32px !important}.pr-sm-5{padding-right:32px !important}.pb-sm-5{padding-bottom:32px !important}.pl-sm-5{padding-left:32px !important}.px-sm-5{padding-right:32px !important;padding-left:32px !important}.py-sm-5{padding-top:32px !important;padding-bottom:32px !important}}@media (min-width: 544px){.p-sm-6{padding:40px !important}.pt-sm-6{padding-top:40px !important}.pr-sm-6{padding-right:40px !important}.pb-sm-6{padding-bottom:40px !important}.pl-sm-6{padding-left:40px !important}.px-sm-6{padding-right:40px !important;padding-left:40px !important}.py-sm-6{padding-top:40px !important;padding-bottom:40px !important}}@media (min-width: 768px){.p-md-0{padding:0 !important}.pt-md-0{padding-top:0 !important}.pr-md-0{padding-right:0 !important}.pb-md-0{padding-bottom:0 !important}.pl-md-0{padding-left:0 !important}.px-md-0{padding-right:0 !important;padding-left:0 !important}.py-md-0{padding-top:0 !important;padding-bottom:0 !important}}@media (min-width: 768px){.p-md-1{padding:4px !important}.pt-md-1{padding-top:4px !important}.pr-md-1{padding-right:4px !important}.pb-md-1{padding-bottom:4px !important}.pl-md-1{padding-left:4px !important}.px-md-1{padding-right:4px !important;padding-left:4px !important}.py-md-1{padding-top:4px !important;padding-bottom:4px !important}}@media (min-width: 768px){.p-md-2{padding:8px !important}.pt-md-2{padding-top:8px !important}.pr-md-2{padding-right:8px !important}.pb-md-2{padding-bottom:8px !important}.pl-md-2{padding-left:8px !important}.px-md-2{padding-right:8px !important;padding-left:8px !important}.py-md-2{padding-top:8px !important;padding-bottom:8px !important}}@media (min-width: 768px){.p-md-3{padding:16px !important}.pt-md-3{padding-top:16px !important}.pr-md-3{padding-right:16px !important}.pb-md-3{padding-bottom:16px !important}.pl-md-3{padding-left:16px !important}.px-md-3{padding-right:16px !important;padding-left:16px !important}.py-md-3{padding-top:16px !important;padding-bottom:16px !important}}@media (min-width: 768px){.p-md-4{padding:24px !important}.pt-md-4{padding-top:24px !important}.pr-md-4{padding-right:24px !important}.pb-md-4{padding-bottom:24px !important}.pl-md-4{padding-left:24px !important}.px-md-4{padding-right:24px !important;padding-left:24px !important}.py-md-4{padding-top:24px !important;padding-bottom:24px !important}}@media (min-width: 768px){.p-md-5{padding:32px !important}.pt-md-5{padding-top:32px !important}.pr-md-5{padding-right:32px !important}.pb-md-5{padding-bottom:32px !important}.pl-md-5{padding-left:32px !important}.px-md-5{padding-right:32px !important;padding-left:32px !important}.py-md-5{padding-top:32px !important;padding-bottom:32px !important}}@media (min-width: 768px){.p-md-6{padding:40px !important}.pt-md-6{padding-top:40px !important}.pr-md-6{padding-right:40px !important}.pb-md-6{padding-bottom:40px !important}.pl-md-6{padding-left:40px !important}.px-md-6{padding-right:40px !important;padding-left:40px !important}.py-md-6{padding-top:40px !important;padding-bottom:40px !important}}@media (min-width: 1012px){.p-lg-0{padding:0 !important}.pt-lg-0{padding-top:0 !important}.pr-lg-0{padding-right:0 !important}.pb-lg-0{padding-bottom:0 !important}.pl-lg-0{padding-left:0 !important}.px-lg-0{padding-right:0 !important;padding-left:0 !important}.py-lg-0{padding-top:0 !important;padding-bottom:0 !important}}@media (min-width: 1012px){.p-lg-1{padding:4px !important}.pt-lg-1{padding-top:4px !important}.pr-lg-1{padding-right:4px !important}.pb-lg-1{padding-bottom:4px !important}.pl-lg-1{padding-left:4px !important}.px-lg-1{padding-right:4px !important;padding-left:4px !important}.py-lg-1{padding-top:4px !important;padding-bottom:4px !important}}@media (min-width: 1012px){.p-lg-2{padding:8px !important}.pt-lg-2{padding-top:8px !important}.pr-lg-2{padding-right:8px !important}.pb-lg-2{padding-bottom:8px !important}.pl-lg-2{padding-left:8px !important}.px-lg-2{padding-right:8px !important;padding-left:8px !important}.py-lg-2{padding-top:8px !important;padding-bottom:8px !important}}@media (min-width: 1012px){.p-lg-3{padding:16px !important}.pt-lg-3{padding-top:16px !important}.pr-lg-3{padding-right:16px !important}.pb-lg-3{padding-bottom:16px !important}.pl-lg-3{padding-left:16px !important}.px-lg-3{padding-right:16px !important;padding-left:16px !important}.py-lg-3{padding-top:16px !important;padding-bottom:16px !important}}@media (min-width: 1012px){.p-lg-4{padding:24px !important}.pt-lg-4{padding-top:24px !important}.pr-lg-4{padding-right:24px !important}.pb-lg-4{padding-bottom:24px !important}.pl-lg-4{padding-left:24px !important}.px-lg-4{padding-right:24px !important;padding-left:24px !important}.py-lg-4{padding-top:24px !important;padding-bottom:24px !important}}@media (min-width: 1012px){.p-lg-5{padding:32px !important}.pt-lg-5{padding-top:32px !important}.pr-lg-5{padding-right:32px !important}.pb-lg-5{padding-bottom:32px !important}.pl-lg-5{padding-left:32px !important}.px-lg-5{padding-right:32px !important;padding-left:32px !important}.py-lg-5{padding-top:32px !important;padding-bottom:32px !important}}@media (min-width: 1012px){.p-lg-6{padding:40px !important}.pt-lg-6{padding-top:40px !important}.pr-lg-6{padding-right:40px !important}.pb-lg-6{padding-bottom:40px !important}.pl-lg-6{padding-left:40px !important}.px-lg-6{padding-right:40px !important;padding-left:40px !important}.py-lg-6{padding-top:40px !important;padding-bottom:40px !important}}@media (min-width: 1280px){.p-xl-0{padding:0 !important}.pt-xl-0{padding-top:0 !important}.pr-xl-0{padding-right:0 !important}.pb-xl-0{padding-bottom:0 !important}.pl-xl-0{padding-left:0 !important}.px-xl-0{padding-right:0 !important;padding-left:0 !important}.py-xl-0{padding-top:0 !important;padding-bottom:0 !important}}@media (min-width: 1280px){.p-xl-1{padding:4px !important}.pt-xl-1{padding-top:4px !important}.pr-xl-1{padding-right:4px !important}.pb-xl-1{padding-bottom:4px !important}.pl-xl-1{padding-left:4px !important}.px-xl-1{padding-right:4px !important;padding-left:4px !important}.py-xl-1{padding-top:4px !important;padding-bottom:4px !important}}@media (min-width: 1280px){.p-xl-2{padding:8px !important}.pt-xl-2{padding-top:8px !important}.pr-xl-2{padding-right:8px !important}.pb-xl-2{padding-bottom:8px !important}.pl-xl-2{padding-left:8px !important}.px-xl-2{padding-right:8px !important;padding-left:8px !important}.py-xl-2{padding-top:8px !important;padding-bottom:8px !important}}@media (min-width: 1280px){.p-xl-3{padding:16px !important}.pt-xl-3{padding-top:16px !important}.pr-xl-3{padding-right:16px !important}.pb-xl-3{padding-bottom:16px !important}.pl-xl-3{padding-left:16px !important}.px-xl-3{padding-right:16px !important;padding-left:16px !important}.py-xl-3{padding-top:16px !important;padding-bottom:16px !important}}@media (min-width: 1280px){.p-xl-4{padding:24px !important}.pt-xl-4{padding-top:24px !important}.pr-xl-4{padding-right:24px !important}.pb-xl-4{padding-bottom:24px !important}.pl-xl-4{padding-left:24px !important}.px-xl-4{padding-right:24px !important;padding-left:24px !important}.py-xl-4{padding-top:24px !important;padding-bottom:24px !important}}@media (min-width: 1280px){.p-xl-5{padding:32px !important}.pt-xl-5{padding-top:32px !important}.pr-xl-5{padding-right:32px !important}.pb-xl-5{padding-bottom:32px !important}.pl-xl-5{padding-left:32px !important}.px-xl-5{padding-right:32px !important;padding-left:32px !important}.py-xl-5{padding-top:32px !important;padding-bottom:32px !important}}@media (min-width: 1280px){.p-xl-6{padding:40px !important}.pt-xl-6{padding-top:40px !important}.pr-xl-6{padding-right:40px !important}.pb-xl-6{padding-bottom:40px !important}.pl-xl-6{padding-left:40px !important}.px-xl-6{padding-right:40px !important;padding-left:40px !important}.py-xl-6{padding-top:40px !important;padding-bottom:40px !important}}.p-responsive{padding-right:16px !important;padding-left:16px !important}@media (min-width: 544px){.p-responsive{padding-right:40px !important;padding-left:40px !important}}@media (min-width: 1012px){.p-responsive{padding-right:16px !important;padding-left:16px !important}}.h1{font-size:26px !important}@media (min-width: 768px){.h1{font-size:32px !important}}.h2{font-size:22px !important}@media (min-width: 768px){.h2{font-size:24px !important}}.h3{font-size:18px !important}@media (min-width: 768px){.h3{font-size:20px !important}}.h4{font-size:16px !important}.h5{font-size:14px !important}.h6{font-size:12px !important}.h1,.h2,.h3,.h4,.h5,.h6{font-weight:600 !important}.f1{font-size:26px !important}@media (min-width: 768px){.f1{font-size:32px !important}}.f2{font-size:22px !important}@media (min-width: 768px){.f2{font-size:24px !important}}.f3{font-size:18px !important}@media (min-width: 768px){.f3{font-size:20px !important}}.f4{font-size:16px !important}@media (min-width: 768px){.f4{font-size:16px !important}}.f5{font-size:14px !important}.f6{font-size:12px !important}.f00-light{font-size:40px !important;font-weight:300 !important}@media (min-width: 768px){.f00-light{font-size:48px !important}}.f0-light{font-size:32px !important;font-weight:300 !important}@media (min-width: 768px){.f0-light{font-size:40px !important}}.f1-light{font-size:26px !important;font-weight:300 !important}@media (min-width: 768px){.f1-light{font-size:32px !important}}.f2-light{font-size:22px !important;font-weight:300 !important}@media (min-width: 768px){.f2-light{font-size:24px !important}}.f3-light{font-size:18px !important;font-weight:300 !important}@media (min-width: 768px){.f3-light{font-size:20px !important}}.text-small{font-size:12px !important}.lead{margin-bottom:30px;font-size:20px;font-weight:300;color:#586069}.lh-condensed-ultra{line-height:1 !important}.lh-condensed{line-height:1.25 !important}.lh-default{line-height:1.5 !important}.lh-0{line-height:0 !important}.text-right{text-align:right !important}.text-left{text-align:left !important}.text-center{text-align:center !important}@media (min-width: 544px){.text-sm-right{text-align:right !important}.text-sm-left{text-align:left !important}.text-sm-center{text-align:center !important}}@media (min-width: 768px){.text-md-right{text-align:right !important}.text-md-left{text-align:left !important}.text-md-center{text-align:center !important}}@media (min-width: 1012px){.text-lg-right{text-align:right !important}.text-lg-left{text-align:left !important}.text-lg-center{text-align:center !important}}@media (min-width: 1280px){.text-xl-right{text-align:right !important}.text-xl-left{text-align:left !important}.text-xl-center{text-align:center !important}}.text-normal{font-weight:400 !important}.text-bold{font-weight:600 !important}.text-italic{font-style:italic !important}.text-uppercase{text-transform:uppercase !important}.text-underline{text-decoration:underline !important}.no-underline{text-decoration:none !important}.no-wrap{white-space:nowrap !important}.ws-normal{white-space:normal !important}.wb-break-all{word-break:break-all !important}.text-emphasized{font-weight:600;color:#24292e}.list-style-none{list-style:none !important}.text-shadow-dark{text-shadow:0 1px 1px rgba(27,31,35,0.25),0 1px 25px rgba(27,31,35,0.75)}.text-shadow-light{text-shadow:0 1px 0 rgba(255,255,255,0.5)}.text-mono{font-family:"SFMono-Regular",Consolas,"Liberation Mono",Menlo,Courier,monospace}.user-select-none{-webkit-user-select:none !important;-moz-user-select:none !important;-ms-user-select:none !important;user-select:none !important}.v-hidden{visibility:hidden !important}.v-visible{visibility:visible !important}.d-table{display:table !important}.d-table-cell{display:table-cell !important}.table-fixed{table-layout:fixed !important}.d-block{display:block !important}.d-inline{display:inline !important}.d-inline-block{display:inline-block !important}.d-flex{display:flex !important}.d-inline-flex{display:inline-flex !important}.d-none{display:none !important}@media (min-width: 544px){.d-sm-table{display:table !important}.d-sm-table-cell{display:table-cell !important}.d-sm-block{display:block !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-flex{display:flex !important}.d-sm-inline-flex{display:inline-flex !important}.d-sm-none{display:none !important}}@media (min-width: 768px){.d-md-table{display:table !important}.d-md-table-cell{display:table-cell !important}.d-md-block{display:block !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-flex{display:flex !important}.d-md-inline-flex{display:inline-flex !important}.d-md-none{display:none !important}}@media (min-width: 1012px){.d-lg-table{display:table !important}.d-lg-table-cell{display:table-cell !important}.d-lg-block{display:block !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-flex{display:flex !important}.d-lg-inline-flex{display:inline-flex !important}.d-lg-none{display:none !important}}@media (min-width: 1280px){.d-xl-table{display:table !important}.d-xl-table-cell{display:table-cell !important}.d-xl-block{display:block !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-flex{display:flex !important}.d-xl-inline-flex{display:inline-flex !important}.d-xl-none{display:none !important}}@media (max-width: 544px){.hide-sm{display:none !important}}@media (min-width: 544px) and (max-width: 768px){.hide-md{display:none !important}}@media (min-width: 768px) and (max-width: 1012px){.hide-lg{display:none !important}}@media (min-width: 1012px){.hide-xl{display:none !important}}.sr-only{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);word-wrap:normal;border:0}.show-on-focus{position:absolute;width:1px;height:1px;margin:0;overflow:hidden;clip:rect(1px, 1px, 1px, 1px)}.show-on-focus:focus{z-index:20;width:auto;height:auto;clip:auto}
|
|
/*# sourceMappingURL=frameworks-afd119c67567f2c750f08c93d4211333.css.map */
|
|
|
|
/*!
|
|
* Primer-marketing
|
|
* http://primer.github.io
|
|
*
|
|
* Released under MIT license. Copyright (c) 2018 GitHub Inc.
|
|
*/.alt-mono-font{font-family:"SFMono-Regular",Consolas,"Liberation Mono",Menlo,Courier,monospace}.alt-h0,.alt-h1,.alt-h2,.alt-h3,.alt-h4,.alt-h5,.alt-h6,.alt-lead{-webkit-font-smoothing:antialiased;font-family:Roboto,-apple-system,BlinkMacSystemFont,"Helvetica Neue","Segoe UI","Oxygen","Ubuntu","Cantarell","Open Sans",sans-serif}.alt-h0{font-size:48px;font-weight:300}@media (min-width: 768px){.alt-h0{font-size:54px}}@media (min-width: 1012px){.alt-h0{font-size:72px}}.alt-h1{font-size:36px;font-weight:300}@media (min-width: 768px){.alt-h1{font-size:48px}}@media (min-width: 1012px){.alt-h1{font-size:54px}}.alt-h2{font-size:28px;font-weight:300}@media (min-width: 768px){.alt-h2{font-size:34px}}@media (min-width: 1012px){.alt-h2{font-size:38px}}.alt-h3{font-size:18px;font-weight:400}@media (min-width: 768px){.alt-h3{font-size:20px}}@media (min-width: 1012px){.alt-h3{font-size:22px}}.alt-h4{font-size:16px;font-weight:500}.alt-h5{font-size:14px;font-weight:500}.alt-h6{font-size:12px;font-weight:500}.alt-lead{-webkit-font-smoothing:antialiased;font-size:21px;font-weight:300}@media (min-width: 768px){.alt-lead{font-size:24px}}@media (min-width: 1012px){.alt-lead{font-size:26px}}.alt-text-small{font-size:14px !important}.pullquote{padding-top:0;padding-bottom:0;padding-left:8px;margin-bottom:24px;font-family:"SFMono-Regular",Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:16px;line-height:1.4;color:#586069;border-left:3px solid #e1e4e8}@media (min-width: 768px){.pullquote{padding-left:12px;margin-bottom:32px;margin-left:-15px;font-size:18px;line-height:1.5}}.btn-orange{color:#fff;background-color:#d25a08;background-image:linear-gradient(-180deg, #f7802f 0%, #d25a08 90%)}.btn-orange:focus,.btn-orange.focus{box-shadow:0 0 0 0.2em rgba(247,128,47,0.4)}.btn-orange:hover,.btn-orange.hover{background-color:#c85607;background-image:linear-gradient(-180deg, #f77a25 0%, #c85607 90%);background-position:-.5em;border-color:rgba(27,31,35,0.5)}.btn-orange:active,.btn-orange.selected,[open]>.btn-orange{background-color:#c65e17;background-image:none;border-color:rgba(27,31,35,0.5);box-shadow:inset 0 0.15em 0.3em rgba(27,31,35,0.15)}.btn-orange:disabled,.btn-orange.disabled{color:rgba(255,255,255,0.75);background-color:#e9ad83;background-image:none;border-color:rgba(27,31,35,0.2);box-shadow:none}.btn-orange .Counter{color:#f46909;background-color:#fff}.btn-outline-purple{color:#6f42c1;background-color:#fff;background-image:none}.btn-outline-purple .Counter{background-color:rgba(27,31,35,0.07)}.btn-outline-purple:hover,.btn-outline-purple:active,.btn-outline-purple.selected,[open]>.btn-outline-purple{color:#fff;background-color:#6f42c1;background-image:none;border-color:#6f42c1}.btn-outline-purple:hover .Counter,.btn-outline-purple:active .Counter,.btn-outline-purple.selected .Counter,[open]>.btn-outline-purple .Counter{color:#6f42c1;background-color:#fff}.btn-outline-purple:focus{border-color:#6f42c1;box-shadow:0 0 0 0.2em rgba(111,66,193,0.4)}.btn-outline-purple:disabled,.btn-outline-purple.disabled{color:rgba(27,31,35,0.3);background-color:#fff;border-color:rgba(27,31,35,0.15);box-shadow:none}.btn-outline-orange{color:#f66a0a;background-color:#fff;background-image:none}.btn-outline-orange .Counter{background-color:rgba(27,31,35,0.07)}.btn-outline-orange:hover,.btn-outline-orange:active,.btn-outline-orange.selected,[open]>.btn-outline-orange{color:#fff;background-color:#f66a0a;background-image:none;border-color:#f66a0a}.btn-outline-orange:hover .Counter,.btn-outline-orange:active .Counter,.btn-outline-orange.selected .Counter,[open]>.btn-outline-orange .Counter{color:#f66a0a;background-color:#fff}.btn-outline-orange:focus{border-color:#f66a0a;box-shadow:0 0 0 0.2em rgba(246,106,10,0.4)}.btn-outline-orange:disabled,.btn-outline-orange.disabled{color:rgba(27,31,35,0.3);background-color:#fff;border-color:rgba(27,31,35,0.15);box-shadow:none}.btn-outline-green{color:#28a745;background-color:#fff;background-image:none}.btn-outline-green .Counter{background-color:rgba(27,31,35,0.07)}.btn-outline-green:hover,.btn-outline-green:active,.btn-outline-green.selected,[open]>.btn-outline-green{color:#fff;background-color:#28a745;background-image:none;border-color:#28a745}.btn-outline-green:hover .Counter,.btn-outline-green:active .Counter,.btn-outline-green.selected .Counter,[open]>.btn-outline-green .Counter{color:#28a745;background-color:#fff}.btn-outline-green:focus{border-color:#28a745;box-shadow:0 0 0 0.2em rgba(40,167,69,0.4)}.btn-outline-green:disabled,.btn-outline-green.disabled{color:rgba(27,31,35,0.3);background-color:#fff;border-color:rgba(27,31,35,0.15);box-shadow:none}.btn-transparent{color:#fff;background-color:transparent;background-image:none;border:1px solid rgba(255,255,255,0.5)}.btn-transparent:hover,.btn-transparent:active{color:#2f363d;background-color:#fff;background-image:none;border-color:#fff}.jumbotron{position:relative;padding-top:40px;padding-bottom:40px}@media (min-width: 544px){.jumbotron{padding-top:60px;padding-bottom:60px}}@media (min-width: 1280px){.jumbotron{padding-top:120px;padding-bottom:120px}}@media (min-width: 1012px){.jumbotron-supertron{height:45vw;min-height:590px;max-height:55vh;padding-top:80px;padding-bottom:80px}}.jumbotron-minitron{padding-top:24px;padding-bottom:24px}@media (min-width: 544px){.jumbotron-minitron{padding-top:32px;padding-bottom:32px}}.jumbotron-shadow::after{position:absolute;bottom:0;left:0;width:100%;height:30px;content:" ";background-color:transparent;background-image:linear-gradient(rgba(0,0,0,0), rgba(0,0,0,0.05));background-repeat:repeat-x;box-shadow:inset 0 -1px 0 rgba(0,0,0,0.05)}.jumbotron-photo{position:relative;background-color:#24292e;background-size:cover}.jumbotron-photo::before{position:absolute;bottom:0;left:0;display:block;width:100%;height:100%;content:"";background-color:rgba(0,0,0,0.25)}.page-section{padding:32px 0;margin-top:0}@media (min-width: 768px){.page-section{padding:56px 0}}.page-section-jumplink:target{padding-top:112px}@media (min-width: 768px){.page-section-jumplink:target{padding-top:80px}}.data-table{width:100%;margin-top:16px;border-collapse:collapse;border:1px #e1e4e8 solid;box-shadow:0 1px 1px rgba(27,31,35,0.05)}.data-table th{font-weight:400;text-align:left}.data-table td,.data-table th{padding:16px;border-right:1px #e1e4e8 solid;border-bottom:1px #e1e4e8 solid}.data-table tbody th{width:25%}.data-table tbody th,.data-table tbody td{border-bottom-color:#e1e4e8}.data-table tbody tr:last-child th,.data-table tbody tr:last-child td{border-bottom:1px #e1e4e8 solid}.grayscale{filter:grayscale(100%)}@media (min-width: 544px){.border-sm-top{border-top:1px #e1e4e8 solid !important}.border-sm-right{border-right:1px #e1e4e8 solid !important}.border-sm-bottom{border-bottom:1px #e1e4e8 solid !important}.border-sm-left{border-left:1px #e1e4e8 solid !important}.border-sm-top-0{border-top:0 !important}.border-sm-right-0{border-right:0 !important}.border-sm-bottom-0{border-bottom:0 !important}.border-sm-left-0{border-left:0 !important}}@media (min-width: 768px){.border-md-top{border-top:1px #e1e4e8 solid !important}.border-md-right{border-right:1px #e1e4e8 solid !important}.border-md-bottom{border-bottom:1px #e1e4e8 solid !important}.border-md-left{border-left:1px #e1e4e8 solid !important}.border-md-top-0{border-top:0 !important}.border-md-right-0{border-right:0 !important}.border-md-bottom-0{border-bottom:0 !important}.border-md-left-0{border-left:0 !important}}@media (min-width: 1012px){.border-lg-top{border-top:1px #e1e4e8 solid !important}.border-lg-right{border-right:1px #e1e4e8 solid !important}.border-lg-bottom{border-bottom:1px #e1e4e8 solid !important}.border-lg-left{border-left:1px #e1e4e8 solid !important}.border-lg-top-0{border-top:0 !important}.border-lg-right-0{border-right:0 !important}.border-lg-bottom-0{border-bottom:0 !important}.border-lg-left-0{border-left:0 !important}}@media (min-width: 1280px){.border-xl-top{border-top:1px #e1e4e8 solid !important}.border-xl-right{border-right:1px #e1e4e8 solid !important}.border-xl-bottom{border-bottom:1px #e1e4e8 solid !important}.border-xl-left{border-left:1px #e1e4e8 solid !important}.border-xl-top-0{border-top:0 !important}.border-xl-right-0{border-right:0 !important}.border-xl-bottom-0{border-bottom:0 !important}.border-xl-left-0{border-left:0 !important}}.border-white-fade{border-color:rgba(255,255,255,0.15) !important}@media (min-width: 544px){.position-sm-relative{position:relative !important}.position-sm-absolute{position:absolute !important}.position-sm-fixed{position:fixed !important}}@media (min-width: 768px){.position-md-relative{position:relative !important}.position-md-absolute{position:absolute !important}.position-md-fixed{position:fixed !important}}@media (min-width: 1012px){.position-lg-relative{position:relative !important}.position-lg-absolute{position:absolute !important}.position-lg-fixed{position:fixed !important}}@media (min-width: 1280px){.position-xl-relative{position:relative !important}.position-xl-absolute{position:absolute !important}.position-xl-fixed{position:fixed !important}}.mt-7{margin-top:48px !important}.mb-7{margin-bottom:48px !important}.my-7{margin-top:48px !important;margin-bottom:48px !important}.mt-8{margin-top:64px !important}.mb-8{margin-bottom:64px !important}.my-8{margin-top:64px !important;margin-bottom:64px !important}.mt-9{margin-top:80px !important}.mb-9{margin-bottom:80px !important}.my-9{margin-top:80px !important;margin-bottom:80px !important}.mt-10{margin-top:96px !important}.mb-10{margin-bottom:96px !important}.my-10{margin-top:96px !important;margin-bottom:96px !important}.mt-11{margin-top:112px !important}.mb-11{margin-bottom:112px !important}.my-11{margin-top:112px !important;margin-bottom:112px !important}.mt-12{margin-top:128px !important}.mb-12{margin-bottom:128px !important}.my-12{margin-top:128px !important;margin-bottom:128px !important}@media (min-width: 544px){.mt-sm-7{margin-top:48px !important}.mb-sm-7{margin-bottom:48px !important}.my-sm-7{margin-top:48px !important;margin-bottom:48px !important}}@media (min-width: 544px){.mt-sm-8{margin-top:64px !important}.mb-sm-8{margin-bottom:64px !important}.my-sm-8{margin-top:64px !important;margin-bottom:64px !important}}@media (min-width: 544px){.mt-sm-9{margin-top:80px !important}.mb-sm-9{margin-bottom:80px !important}.my-sm-9{margin-top:80px !important;margin-bottom:80px !important}}@media (min-width: 544px){.mt-sm-10{margin-top:96px !important}.mb-sm-10{margin-bottom:96px !important}.my-sm-10{margin-top:96px !important;margin-bottom:96px !important}}@media (min-width: 544px){.mt-sm-11{margin-top:112px !important}.mb-sm-11{margin-bottom:112px !important}.my-sm-11{margin-top:112px !important;margin-bottom:112px !important}}@media (min-width: 544px){.mt-sm-12{margin-top:128px !important}.mb-sm-12{margin-bottom:128px !important}.my-sm-12{margin-top:128px !important;margin-bottom:128px !important}}@media (min-width: 768px){.mt-md-7{margin-top:48px !important}.mb-md-7{margin-bottom:48px !important}.my-md-7{margin-top:48px !important;margin-bottom:48px !important}}@media (min-width: 768px){.mt-md-8{margin-top:64px !important}.mb-md-8{margin-bottom:64px !important}.my-md-8{margin-top:64px !important;margin-bottom:64px !important}}@media (min-width: 768px){.mt-md-9{margin-top:80px !important}.mb-md-9{margin-bottom:80px !important}.my-md-9{margin-top:80px !important;margin-bottom:80px !important}}@media (min-width: 768px){.mt-md-10{margin-top:96px !important}.mb-md-10{margin-bottom:96px !important}.my-md-10{margin-top:96px !important;margin-bottom:96px !important}}@media (min-width: 768px){.mt-md-11{margin-top:112px !important}.mb-md-11{margin-bottom:112px !important}.my-md-11{margin-top:112px !important;margin-bottom:112px !important}}@media (min-width: 768px){.mt-md-12{margin-top:128px !important}.mb-md-12{margin-bottom:128px !important}.my-md-12{margin-top:128px !important;margin-bottom:128px !important}}@media (min-width: 1012px){.mt-lg-7{margin-top:48px !important}.mb-lg-7{margin-bottom:48px !important}.my-lg-7{margin-top:48px !important;margin-bottom:48px !important}}@media (min-width: 1012px){.mt-lg-8{margin-top:64px !important}.mb-lg-8{margin-bottom:64px !important}.my-lg-8{margin-top:64px !important;margin-bottom:64px !important}}@media (min-width: 1012px){.mt-lg-9{margin-top:80px !important}.mb-lg-9{margin-bottom:80px !important}.my-lg-9{margin-top:80px !important;margin-bottom:80px !important}}@media (min-width: 1012px){.mt-lg-10{margin-top:96px !important}.mb-lg-10{margin-bottom:96px !important}.my-lg-10{margin-top:96px !important;margin-bottom:96px !important}}@media (min-width: 1012px){.mt-lg-11{margin-top:112px !important}.mb-lg-11{margin-bottom:112px !important}.my-lg-11{margin-top:112px !important;margin-bottom:112px !important}}@media (min-width: 1012px){.mt-lg-12{margin-top:128px !important}.mb-lg-12{margin-bottom:128px !important}.my-lg-12{margin-top:128px !important;margin-bottom:128px !important}}@media (min-width: 1280px){.mt-xl-7{margin-top:48px !important}.mb-xl-7{margin-bottom:48px !important}.my-xl-7{margin-top:48px !important;margin-bottom:48px !important}}@media (min-width: 1280px){.mt-xl-8{margin-top:64px !important}.mb-xl-8{margin-bottom:64px !important}.my-xl-8{margin-top:64px !important;margin-bottom:64px !important}}@media (min-width: 1280px){.mt-xl-9{margin-top:80px !important}.mb-xl-9{margin-bottom:80px !important}.my-xl-9{margin-top:80px !important;margin-bottom:80px !important}}@media (min-width: 1280px){.mt-xl-10{margin-top:96px !important}.mb-xl-10{margin-bottom:96px !important}.my-xl-10{margin-top:96px !important;margin-bottom:96px !important}}@media (min-width: 1280px){.mt-xl-11{margin-top:112px !important}.mb-xl-11{margin-bottom:112px !important}.my-xl-11{margin-top:112px !important;margin-bottom:112px !important}}@media (min-width: 1280px){.mt-xl-12{margin-top:128px !important}.mb-xl-12{margin-bottom:128px !important}.my-xl-12{margin-top:128px !important;margin-bottom:128px !important}}.pt-7{padding-top:48px !important}.pb-7{padding-bottom:48px !important}.py-7{padding-top:48px !important;padding-bottom:48px !important}.pt-8{padding-top:64px !important}.pb-8{padding-bottom:64px !important}.py-8{padding-top:64px !important;padding-bottom:64px !important}.pt-9{padding-top:80px !important}.pb-9{padding-bottom:80px !important}.py-9{padding-top:80px !important;padding-bottom:80px !important}.pt-10{padding-top:96px !important}.pb-10{padding-bottom:96px !important}.py-10{padding-top:96px !important;padding-bottom:96px !important}.pt-11{padding-top:112px !important}.pb-11{padding-bottom:112px !important}.py-11{padding-top:112px !important;padding-bottom:112px !important}.pt-12{padding-top:128px !important}.pb-12{padding-bottom:128px !important}.py-12{padding-top:128px !important;padding-bottom:128px !important}@media (min-width: 544px){.pt-sm-7{padding-top:48px !important}.pb-sm-7{padding-bottom:48px !important}.py-sm-7{padding-top:48px !important;padding-bottom:48px !important}}@media (min-width: 544px){.pt-sm-8{padding-top:64px !important}.pb-sm-8{padding-bottom:64px !important}.py-sm-8{padding-top:64px !important;padding-bottom:64px !important}}@media (min-width: 544px){.pt-sm-9{padding-top:80px !important}.pb-sm-9{padding-bottom:80px !important}.py-sm-9{padding-top:80px !important;padding-bottom:80px !important}}@media (min-width: 544px){.pt-sm-10{padding-top:96px !important}.pb-sm-10{padding-bottom:96px !important}.py-sm-10{padding-top:96px !important;padding-bottom:96px !important}}@media (min-width: 544px){.pt-sm-11{padding-top:112px !important}.pb-sm-11{padding-bottom:112px !important}.py-sm-11{padding-top:112px !important;padding-bottom:112px !important}}@media (min-width: 544px){.pt-sm-12{padding-top:128px !important}.pb-sm-12{padding-bottom:128px !important}.py-sm-12{padding-top:128px !important;padding-bottom:128px !important}}@media (min-width: 768px){.pt-md-7{padding-top:48px !important}.pb-md-7{padding-bottom:48px !important}.py-md-7{padding-top:48px !important;padding-bottom:48px !important}}@media (min-width: 768px){.pt-md-8{padding-top:64px !important}.pb-md-8{padding-bottom:64px !important}.py-md-8{padding-top:64px !important;padding-bottom:64px !important}}@media (min-width: 768px){.pt-md-9{padding-top:80px !important}.pb-md-9{padding-bottom:80px !important}.py-md-9{padding-top:80px !important;padding-bottom:80px !important}}@media (min-width: 768px){.pt-md-10{padding-top:96px !important}.pb-md-10{padding-bottom:96px !important}.py-md-10{padding-top:96px !important;padding-bottom:96px !important}}@media (min-width: 768px){.pt-md-11{padding-top:112px !important}.pb-md-11{padding-bottom:112px !important}.py-md-11{padding-top:112px !important;padding-bottom:112px !important}}@media (min-width: 768px){.pt-md-12{padding-top:128px !important}.pb-md-12{padding-bottom:128px !important}.py-md-12{padding-top:128px !important;padding-bottom:128px !important}}@media (min-width: 1012px){.pt-lg-7{padding-top:48px !important}.pb-lg-7{padding-bottom:48px !important}.py-lg-7{padding-top:48px !important;padding-bottom:48px !important}}@media (min-width: 1012px){.pt-lg-8{padding-top:64px !important}.pb-lg-8{padding-bottom:64px !important}.py-lg-8{padding-top:64px !important;padding-bottom:64px !important}}@media (min-width: 1012px){.pt-lg-9{padding-top:80px !important}.pb-lg-9{padding-bottom:80px !important}.py-lg-9{padding-top:80px !important;padding-bottom:80px !important}}@media (min-width: 1012px){.pt-lg-10{padding-top:96px !important}.pb-lg-10{padding-bottom:96px !important}.py-lg-10{padding-top:96px !important;padding-bottom:96px !important}}@media (min-width: 1012px){.pt-lg-11{padding-top:112px !important}.pb-lg-11{padding-bottom:112px !important}.py-lg-11{padding-top:112px !important;padding-bottom:112px !important}}@media (min-width: 1012px){.pt-lg-12{padding-top:128px !important}.pb-lg-12{padding-bottom:128px !important}.py-lg-12{padding-top:128px !important;padding-bottom:128px !important}}@media (min-width: 1280px){.pt-xl-7{padding-top:48px !important}.pb-xl-7{padding-bottom:48px !important}.py-xl-7{padding-top:48px !important;padding-bottom:48px !important}}@media (min-width: 1280px){.pt-xl-8{padding-top:64px !important}.pb-xl-8{padding-bottom:64px !important}.py-xl-8{padding-top:64px !important;padding-bottom:64px !important}}@media (min-width: 1280px){.pt-xl-9{padding-top:80px !important}.pb-xl-9{padding-bottom:80px !important}.py-xl-9{padding-top:80px !important;padding-bottom:80px !important}}@media (min-width: 1280px){.pt-xl-10{padding-top:96px !important}.pb-xl-10{padding-bottom:96px !important}.py-xl-10{padding-top:96px !important;padding-bottom:96px !important}}@media (min-width: 1280px){.pt-xl-11{padding-top:112px !important}.pb-xl-11{padding-bottom:112px !important}.py-xl-11{padding-top:112px !important;padding-bottom:112px !important}}@media (min-width: 1280px){.pt-xl-12{padding-top:128px !important}.pb-xl-12{padding-bottom:128px !important}.py-xl-12{padding-top:128px !important;padding-bottom:128px !important}}hr{border-bottom-color:#eee}.img-responsive{display:block;width:100%;max-width:100%;height:auto}@font-face{font-family:InterUI;font-style:normal;font-weight:400;src:local("InterUI"),local("InterUI-Regular"),url(data:font/woff;base64,PCFET0NUWVBFIEhUTUwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDMuMiBGaW5hbC8vRU4iPgo8dGl0bGU+NDA0IE5vdCBGb3VuZDwvdGl0bGU+CjxoMT5Ob3QgRm91bmQ8L2gxPgo8cD5UaGUgcmVxdWVzdGVkIFVSTCB3YXMgbm90IGZvdW5kIG9uIHRoZSBzZXJ2ZXIuIElmIHlvdSBlbnRlcmVkIHRoZSBVUkwgbWFudWFsbHkgcGxlYXNlIGNoZWNrIHlvdXIgc3BlbGxpbmcgYW5kIHRyeSBhZ2Fpbi48L3A+Cg==) format("woff")}@font-face{font-family:InterUI;font-style:normal;font-weight:500;src:local("InterUI Medium"),local("InterUI-Medium"),url(data:font/woff;base64,PCFET0NUWVBFIEhUTUwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDMuMiBGaW5hbC8vRU4iPgo8dGl0bGU+NDA0IE5vdCBGb3VuZDwvdGl0bGU+CjxoMT5Ob3QgRm91bmQ8L2gxPgo8cD5UaGUgcmVxdWVzdGVkIFVSTCB3YXMgbm90IGZvdW5kIG9uIHRoZSBzZXJ2ZXIuIElmIHlvdSBlbnRlcmVkIHRoZSBVUkwgbWFudWFsbHkgcGxlYXNlIGNoZWNrIHlvdXIgc3BlbGxpbmcgYW5kIHRyeSBhZ2Fpbi48L3A+Cg==) format("woff")}.bg-blue-dark{background-color:#032f62 !important}.text-blue-mktg{color:#1277eb !important}.text-blue-light{color:#79b8ff !important}.text-white-fade{color:rgba(255,255,255,0.7) !important}.h000-mktg,.h00-mktg,.h0-mktg,.h1-mktg,.h2-mktg,.h3-mktg,.h4-mktg,.h5-mktg,.h6-mktg,.lead-mktg{font-family:InterUI,-apple-system,BlinkMacSystemFont,"Helvetica Neue","Segoe UI",Oxygen,Ubuntu,Cantarell,"Open Sans",sans-serif;font-weight:500}.lead-mktg{font-size:21px !important;font-weight:normal !important}.h000-mktg,.h000{font-size:48px !important}@media (min-width: 768px){.h000-mktg,.h000{font-size:64px !important}}.h00-mktg{font-size:40px !important}@media (min-width: 768px){.h00-mktg{font-size:48px !important}}.h0-mktg{font-size:32px !important}@media (min-width: 768px){.h0-mktg{font-size:40px !important}}.h1-mktg{font-size:26px !important}@media (min-width: 768px){.h1-mktg{font-size:32px !important}}.h2-mktg{font-size:22px !important}@media (min-width: 768px){.h2-mktg{font-size:24px !important}}.h3-mktg{font-size:18px !important}@media (min-width: 768px){.h3-mktg{font-size:20px !important}}.h4-mktg{font-size:16px !important}.h5-mktg{font-size:14px !important}.h6-mktg{font-size:12px !important}.text-gray-light-ultra{font-style:normal;font-weight:400;color:#808891}.underline-dashed{display:inline;padding-bottom:4px;background-image:linear-gradient(to right, #d1d5da 50%, rgba(255,255,255,0) 0%);background-repeat:repeat-x;background-position:bottom;background-size:10px 2px}.link-mktg{color:#1277eb;text-decoration:none !important;box-shadow:0 1px 0 0 rgba(18,119,235,0.5);transition:.2s}.link-mktg:hover{color:#0366d6;box-shadow:0 1px 0 0 #1277eb}.Tile{position:relative;display:block;min-height:250px;background-color:#f6f8fa;border-radius:3px;transition:.4s}.Tile:hover{background-color:#fff;box-shadow:0 4px 14px rgba(0,0,0,0.1)}.Tile:active{box-shadow:0 2px 7px rgba(0,0,0,0.1)}.Tile--dots::before{position:absolute;top:0;left:0;z-index:-1;width:180px;height:180px;content:"";background:url("/images/modules/site/patterns/dots-small.svg");opacity:0;transition:.4s}.Tile--dots::after{position:absolute;right:0;bottom:0;z-index:-1;width:180px;height:180px;content:"";background:url("/images/modules/site/patterns/dots-small.svg");opacity:0;transition:.4s}.Tile--dots:hover::before{opacity:1;transform:translate3d(-18px, -18px, 0)}.Tile--dots:hover::after{opacity:1;transform:translate3d(23px, 23px, 0)}.Tile--dots:active::before{opacity:0.5;transform:translate3d(-10px, -10px, 0)}.Tile--dots:active::after{opacity:0.5;transform:translate3d(18px, 18px, 0)}.Tile--symbol::before{position:absolute;top:16px;right:24px;font-size:24px;content:"â";opacity:0;transition:.4s,color 0s;transform:rotate(-45deg) translateX(-3px)}.Tile--symbol:hover::before{opacity:1;transform:rotate(-45deg) translateX(0)}.Tile--symbol:active::before{opacity:1;transition:.2s;transform:rotate(-45deg) translateX(-5px)}.Tile-date{position:absolute;bottom:24px;left:24px;margin-bottom:0;line-height:1;color:#959da5}.dots-4{position:relative}.dots-4::before{position:absolute;top:-31px;left:-31px;z-index:-1;width:75%;height:75%;content:"";background:url("/images/modules/site/patterns/dots-small.svg")}.dots-3{position:relative}.dots-3::before{position:absolute;top:-21px;left:-21px;z-index:-1;width:75%;height:75%;content:"";background:url("/images/modules/site/patterns/dots-small.svg")}.Point:hover .Point-symbol{transform:translateY(-5px)}.Point-symbol{transition:.2s;transform:translateY(0)}.Bump-link-symbol{display:inline-block;transition:.2s;transform:translateX(0)}.Bump-link:hover .Bump-link-symbol{transform:translateX(3px)}.Bump-link--hover .Bump-link-symbol{color:inherit;opacity:0;transition:.2s;transform:translateX(0)}.Bump-link--hover:hover .Bump-link-symbol{opacity:1;transform:translateX(3px)}.btn-mktg{display:inline-block;padding:16px 24px;font-size:14px;font-weight:500;color:#fff;background-color:#1277eb;border:0;border-radius:3px;transition:.2s}.btn-mktg:hover{text-decoration:none;background-color:#0366d6}.btn-primary-mktg{background-color:#2ebc4f}.btn-primary-mktg:hover{background-color:#28a745}.btn-large-mktg{padding:20px 32px;font-size:16px}.btn-outline-mktg{color:#1277eb !important;background-color:transparent !important;box-shadow:0 0 0 1px rgba(18,119,235,0.5) inset}.btn-outline-mktg:hover{color:#0366d6 !important;text-decoration:none;box-shadow:0 0 0 1px #1277eb inset}.top-0{top:0 !important}.right-0{right:0 !important}.bottom-0{bottom:0 !important}.left-0{left:0 !important}.top-n0{top:-0 !important}.right-n0{right:-0 !important}.bottom-n0{bottom:-0 !important}.left-n0{left:-0 !important}.top-1{top:4px !important}.right-1{right:4px !important}.bottom-1{bottom:4px !important}.left-1{left:4px !important}.top-n1{top:-4px !important}.right-n1{right:-4px !important}.bottom-n1{bottom:-4px !important}.left-n1{left:-4px !important}.top-2{top:8px !important}.right-2{right:8px !important}.bottom-2{bottom:8px !important}.left-2{left:8px !important}.top-n2{top:-8px !important}.right-n2{right:-8px !important}.bottom-n2{bottom:-8px !important}.left-n2{left:-8px !important}.top-3{top:16px !important}.right-3{right:16px !important}.bottom-3{bottom:16px !important}.left-3{left:16px !important}.top-n3{top:-16px !important}.right-n3{right:-16px !important}.bottom-n3{bottom:-16px !important}.left-n3{left:-16px !important}.top-4{top:24px !important}.right-4{right:24px !important}.bottom-4{bottom:24px !important}.left-4{left:24px !important}.top-n4{top:-24px !important}.right-n4{right:-24px !important}.bottom-n4{bottom:-24px !important}.left-n4{left:-24px !important}.top-5{top:32px !important}.right-5{right:32px !important}.bottom-5{bottom:32px !important}.left-5{left:32px !important}.top-n5{top:-32px !important}.right-n5{right:-32px !important}.bottom-n5{bottom:-32px !important}.left-n5{left:-32px !important}.top-6{top:40px !important}.right-6{right:40px !important}.bottom-6{bottom:40px !important}.left-6{left:40px !important}.top-n6{top:-40px !important}.right-n6{right:-40px !important}.bottom-n6{bottom:-40px !important}.left-n6{left:-40px !important}.top-7{top:48px !important}.right-7{right:48px !important}.bottom-7{bottom:48px !important}.left-7{left:48px !important}.top-n7{top:-48px !important}.right-n7{right:-48px !important}.bottom-n7{bottom:-48px !important}.left-n7{left:-48px !important}.top-8{top:64px !important}.right-8{right:64px !important}.bottom-8{bottom:64px !important}.left-8{left:64px !important}.top-n8{top:-64px !important}.right-n8{right:-64px !important}.bottom-n8{bottom:-64px !important}.left-n8{left:-64px !important}.top-9{top:80px !important}.right-9{right:80px !important}.bottom-9{bottom:80px !important}.left-9{left:80px !important}.top-n9{top:-80px !important}.right-n9{right:-80px !important}.bottom-n9{bottom:-80px !important}.left-n9{left:-80px !important}.top-10{top:96px !important}.right-10{right:96px !important}.bottom-10{bottom:96px !important}.left-10{left:96px !important}.top-n10{top:-96px !important}.right-n10{right:-96px !important}.bottom-n10{bottom:-96px !important}.left-n10{left:-96px !important}.top-11{top:112px !important}.right-11{right:112px !important}.bottom-11{bottom:112px !important}.left-11{left:112px !important}.top-n11{top:-112px !important}.right-n11{right:-112px !important}.bottom-n11{bottom:-112px !important}.left-n11{left:-112px !important}.top-12{top:128px !important}.right-12{right:128px !important}.bottom-12{bottom:128px !important}.left-12{left:128px !important}.top-n12{top:-128px !important}.right-n12{right:-128px !important}.bottom-n12{bottom:-128px !important}.left-n12{left:-128px !important}@media (min-width: 544px){.top-sm-0{top:0 !important}.right-sm-0{right:0 !important}.bottom-sm-0{bottom:0 !important}.left-sm-0{left:0 !important}.top-sm-n0{top:-0 !important}.right-sm-n0{right:-0 !important}.bottom-sm-n0{bottom:-0 !important}.left-sm-n0{left:-0 !important}}@media (min-width: 544px){.top-sm-1{top:4px !important}.right-sm-1{right:4px !important}.bottom-sm-1{bottom:4px !important}.left-sm-1{left:4px !important}.top-sm-n1{top:-4px !important}.right-sm-n1{right:-4px !important}.bottom-sm-n1{bottom:-4px !important}.left-sm-n1{left:-4px !important}}@media (min-width: 544px){.top-sm-2{top:8px !important}.right-sm-2{right:8px !important}.bottom-sm-2{bottom:8px !important}.left-sm-2{left:8px !important}.top-sm-n2{top:-8px !important}.right-sm-n2{right:-8px !important}.bottom-sm-n2{bottom:-8px !important}.left-sm-n2{left:-8px !important}}@media (min-width: 544px){.top-sm-3{top:16px !important}.right-sm-3{right:16px !important}.bottom-sm-3{bottom:16px !important}.left-sm-3{left:16px !important}.top-sm-n3{top:-16px !important}.right-sm-n3{right:-16px !important}.bottom-sm-n3{bottom:-16px !important}.left-sm-n3{left:-16px !important}}@media (min-width: 544px){.top-sm-4{top:24px !important}.right-sm-4{right:24px !important}.bottom-sm-4{bottom:24px !important}.left-sm-4{left:24px !important}.top-sm-n4{top:-24px !important}.right-sm-n4{right:-24px !important}.bottom-sm-n4{bottom:-24px !important}.left-sm-n4{left:-24px !important}}@media (min-width: 544px){.top-sm-5{top:32px !important}.right-sm-5{right:32px !important}.bottom-sm-5{bottom:32px !important}.left-sm-5{left:32px !important}.top-sm-n5{top:-32px !important}.right-sm-n5{right:-32px !important}.bottom-sm-n5{bottom:-32px !important}.left-sm-n5{left:-32px !important}}@media (min-width: 544px){.top-sm-6{top:40px !important}.right-sm-6{right:40px !important}.bottom-sm-6{bottom:40px !important}.left-sm-6{left:40px !important}.top-sm-n6{top:-40px !important}.right-sm-n6{right:-40px !important}.bottom-sm-n6{bottom:-40px !important}.left-sm-n6{left:-40px !important}}@media (min-width: 544px){.top-sm-7{top:48px !important}.right-sm-7{right:48px !important}.bottom-sm-7{bottom:48px !important}.left-sm-7{left:48px !important}.top-sm-n7{top:-48px !important}.right-sm-n7{right:-48px !important}.bottom-sm-n7{bottom:-48px !important}.left-sm-n7{left:-48px !important}}@media (min-width: 544px){.top-sm-8{top:64px !important}.right-sm-8{right:64px !important}.bottom-sm-8{bottom:64px !important}.left-sm-8{left:64px !important}.top-sm-n8{top:-64px !important}.right-sm-n8{right:-64px !important}.bottom-sm-n8{bottom:-64px !important}.left-sm-n8{left:-64px !important}}@media (min-width: 544px){.top-sm-9{top:80px !important}.right-sm-9{right:80px !important}.bottom-sm-9{bottom:80px !important}.left-sm-9{left:80px !important}.top-sm-n9{top:-80px !important}.right-sm-n9{right:-80px !important}.bottom-sm-n9{bottom:-80px !important}.left-sm-n9{left:-80px !important}}@media (min-width: 544px){.top-sm-10{top:96px !important}.right-sm-10{right:96px !important}.bottom-sm-10{bottom:96px !important}.left-sm-10{left:96px !important}.top-sm-n10{top:-96px !important}.right-sm-n10{right:-96px !important}.bottom-sm-n10{bottom:-96px !important}.left-sm-n10{left:-96px !important}}@media (min-width: 544px){.top-sm-11{top:112px !important}.right-sm-11{right:112px !important}.bottom-sm-11{bottom:112px !important}.left-sm-11{left:112px !important}.top-sm-n11{top:-112px !important}.right-sm-n11{right:-112px !important}.bottom-sm-n11{bottom:-112px !important}.left-sm-n11{left:-112px !important}}@media (min-width: 544px){.top-sm-12{top:128px !important}.right-sm-12{right:128px !important}.bottom-sm-12{bottom:128px !important}.left-sm-12{left:128px !important}.top-sm-n12{top:-128px !important}.right-sm-n12{right:-128px !important}.bottom-sm-n12{bottom:-128px !important}.left-sm-n12{left:-128px !important}}@media (min-width: 768px){.top-md-0{top:0 !important}.right-md-0{right:0 !important}.bottom-md-0{bottom:0 !important}.left-md-0{left:0 !important}.top-md-n0{top:-0 !important}.right-md-n0{right:-0 !important}.bottom-md-n0{bottom:-0 !important}.left-md-n0{left:-0 !important}}@media (min-width: 768px){.top-md-1{top:4px !important}.right-md-1{right:4px !important}.bottom-md-1{bottom:4px !important}.left-md-1{left:4px !important}.top-md-n1{top:-4px !important}.right-md-n1{right:-4px !important}.bottom-md-n1{bottom:-4px !important}.left-md-n1{left:-4px !important}}@media (min-width: 768px){.top-md-2{top:8px !important}.right-md-2{right:8px !important}.bottom-md-2{bottom:8px !important}.left-md-2{left:8px !important}.top-md-n2{top:-8px !important}.right-md-n2{right:-8px !important}.bottom-md-n2{bottom:-8px !important}.left-md-n2{left:-8px !important}}@media (min-width: 768px){.top-md-3{top:16px !important}.right-md-3{right:16px !important}.bottom-md-3{bottom:16px !important}.left-md-3{left:16px !important}.top-md-n3{top:-16px !important}.right-md-n3{right:-16px !important}.bottom-md-n3{bottom:-16px !important}.left-md-n3{left:-16px !important}}@media (min-width: 768px){.top-md-4{top:24px !important}.right-md-4{right:24px !important}.bottom-md-4{bottom:24px !important}.left-md-4{left:24px !important}.top-md-n4{top:-24px !important}.right-md-n4{right:-24px !important}.bottom-md-n4{bottom:-24px !important}.left-md-n4{left:-24px !important}}@media (min-width: 768px){.top-md-5{top:32px !important}.right-md-5{right:32px !important}.bottom-md-5{bottom:32px !important}.left-md-5{left:32px !important}.top-md-n5{top:-32px !important}.right-md-n5{right:-32px !important}.bottom-md-n5{bottom:-32px !important}.left-md-n5{left:-32px !important}}@media (min-width: 768px){.top-md-6{top:40px !important}.right-md-6{right:40px !important}.bottom-md-6{bottom:40px !important}.left-md-6{left:40px !important}.top-md-n6{top:-40px !important}.right-md-n6{right:-40px !important}.bottom-md-n6{bottom:-40px !important}.left-md-n6{left:-40px !important}}@media (min-width: 768px){.top-md-7{top:48px !important}.right-md-7{right:48px !important}.bottom-md-7{bottom:48px !important}.left-md-7{left:48px !important}.top-md-n7{top:-48px !important}.right-md-n7{right:-48px !important}.bottom-md-n7{bottom:-48px !important}.left-md-n7{left:-48px !important}}@media (min-width: 768px){.top-md-8{top:64px !important}.right-md-8{right:64px !important}.bottom-md-8{bottom:64px !important}.left-md-8{left:64px !important}.top-md-n8{top:-64px !important}.right-md-n8{right:-64px !important}.bottom-md-n8{bottom:-64px !important}.left-md-n8{left:-64px !important}}@media (min-width: 768px){.top-md-9{top:80px !important}.right-md-9{right:80px !important}.bottom-md-9{bottom:80px !important}.left-md-9{left:80px !important}.top-md-n9{top:-80px !important}.right-md-n9{right:-80px !important}.bottom-md-n9{bottom:-80px !important}.left-md-n9{left:-80px !important}}@media (min-width: 768px){.top-md-10{top:96px !important}.right-md-10{right:96px !important}.bottom-md-10{bottom:96px !important}.left-md-10{left:96px !important}.top-md-n10{top:-96px !important}.right-md-n10{right:-96px !important}.bottom-md-n10{bottom:-96px !important}.left-md-n10{left:-96px !important}}@media (min-width: 768px){.top-md-11{top:112px !important}.right-md-11{right:112px !important}.bottom-md-11{bottom:112px !important}.left-md-11{left:112px !important}.top-md-n11{top:-112px !important}.right-md-n11{right:-112px !important}.bottom-md-n11{bottom:-112px !important}.left-md-n11{left:-112px !important}}@media (min-width: 768px){.top-md-12{top:128px !important}.right-md-12{right:128px !important}.bottom-md-12{bottom:128px !important}.left-md-12{left:128px !important}.top-md-n12{top:-128px !important}.right-md-n12{right:-128px !important}.bottom-md-n12{bottom:-128px !important}.left-md-n12{left:-128px !important}}@media (min-width: 1012px){.top-lg-0{top:0 !important}.right-lg-0{right:0 !important}.bottom-lg-0{bottom:0 !important}.left-lg-0{left:0 !important}.top-lg-n0{top:-0 !important}.right-lg-n0{right:-0 !important}.bottom-lg-n0{bottom:-0 !important}.left-lg-n0{left:-0 !important}}@media (min-width: 1012px){.top-lg-1{top:4px !important}.right-lg-1{right:4px !important}.bottom-lg-1{bottom:4px !important}.left-lg-1{left:4px !important}.top-lg-n1{top:-4px !important}.right-lg-n1{right:-4px !important}.bottom-lg-n1{bottom:-4px !important}.left-lg-n1{left:-4px !important}}@media (min-width: 1012px){.top-lg-2{top:8px !important}.right-lg-2{right:8px !important}.bottom-lg-2{bottom:8px !important}.left-lg-2{left:8px !important}.top-lg-n2{top:-8px !important}.right-lg-n2{right:-8px !important}.bottom-lg-n2{bottom:-8px !important}.left-lg-n2{left:-8px !important}}@media (min-width: 1012px){.top-lg-3{top:16px !important}.right-lg-3{right:16px !important}.bottom-lg-3{bottom:16px !important}.left-lg-3{left:16px !important}.top-lg-n3{top:-16px !important}.right-lg-n3{right:-16px !important}.bottom-lg-n3{bottom:-16px !important}.left-lg-n3{left:-16px !important}}@media (min-width: 1012px){.top-lg-4{top:24px !important}.right-lg-4{right:24px !important}.bottom-lg-4{bottom:24px !important}.left-lg-4{left:24px !important}.top-lg-n4{top:-24px !important}.right-lg-n4{right:-24px !important}.bottom-lg-n4{bottom:-24px !important}.left-lg-n4{left:-24px !important}}@media (min-width: 1012px){.top-lg-5{top:32px !important}.right-lg-5{right:32px !important}.bottom-lg-5{bottom:32px !important}.left-lg-5{left:32px !important}.top-lg-n5{top:-32px !important}.right-lg-n5{right:-32px !important}.bottom-lg-n5{bottom:-32px !important}.left-lg-n5{left:-32px !important}}@media (min-width: 1012px){.top-lg-6{top:40px !important}.right-lg-6{right:40px !important}.bottom-lg-6{bottom:40px !important}.left-lg-6{left:40px !important}.top-lg-n6{top:-40px !important}.right-lg-n6{right:-40px !important}.bottom-lg-n6{bottom:-40px !important}.left-lg-n6{left:-40px !important}}@media (min-width: 1012px){.top-lg-7{top:48px !important}.right-lg-7{right:48px !important}.bottom-lg-7{bottom:48px !important}.left-lg-7{left:48px !important}.top-lg-n7{top:-48px !important}.right-lg-n7{right:-48px !important}.bottom-lg-n7{bottom:-48px !important}.left-lg-n7{left:-48px !important}}@media (min-width: 1012px){.top-lg-8{top:64px !important}.right-lg-8{right:64px !important}.bottom-lg-8{bottom:64px !important}.left-lg-8{left:64px !important}.top-lg-n8{top:-64px !important}.right-lg-n8{right:-64px !important}.bottom-lg-n8{bottom:-64px !important}.left-lg-n8{left:-64px !important}}@media (min-width: 1012px){.top-lg-9{top:80px !important}.right-lg-9{right:80px !important}.bottom-lg-9{bottom:80px !important}.left-lg-9{left:80px !important}.top-lg-n9{top:-80px !important}.right-lg-n9{right:-80px !important}.bottom-lg-n9{bottom:-80px !important}.left-lg-n9{left:-80px !important}}@media (min-width: 1012px){.top-lg-10{top:96px !important}.right-lg-10{right:96px !important}.bottom-lg-10{bottom:96px !important}.left-lg-10{left:96px !important}.top-lg-n10{top:-96px !important}.right-lg-n10{right:-96px !important}.bottom-lg-n10{bottom:-96px !important}.left-lg-n10{left:-96px !important}}@media (min-width: 1012px){.top-lg-11{top:112px !important}.right-lg-11{right:112px !important}.bottom-lg-11{bottom:112px !important}.left-lg-11{left:112px !important}.top-lg-n11{top:-112px !important}.right-lg-n11{right:-112px !important}.bottom-lg-n11{bottom:-112px !important}.left-lg-n11{left:-112px !important}}@media (min-width: 1012px){.top-lg-12{top:128px !important}.right-lg-12{right:128px !important}.bottom-lg-12{bottom:128px !important}.left-lg-12{left:128px !important}.top-lg-n12{top:-128px !important}.right-lg-n12{right:-128px !important}.bottom-lg-n12{bottom:-128px !important}.left-lg-n12{left:-128px !important}}@media (min-width: 1280px){.top-xl-0{top:0 !important}.right-xl-0{right:0 !important}.bottom-xl-0{bottom:0 !important}.left-xl-0{left:0 !important}.top-xl-n0{top:-0 !important}.right-xl-n0{right:-0 !important}.bottom-xl-n0{bottom:-0 !important}.left-xl-n0{left:-0 !important}}@media (min-width: 1280px){.top-xl-1{top:4px !important}.right-xl-1{right:4px !important}.bottom-xl-1{bottom:4px !important}.left-xl-1{left:4px !important}.top-xl-n1{top:-4px !important}.right-xl-n1{right:-4px !important}.bottom-xl-n1{bottom:-4px !important}.left-xl-n1{left:-4px !important}}@media (min-width: 1280px){.top-xl-2{top:8px !important}.right-xl-2{right:8px !important}.bottom-xl-2{bottom:8px !important}.left-xl-2{left:8px !important}.top-xl-n2{top:-8px !important}.right-xl-n2{right:-8px !important}.bottom-xl-n2{bottom:-8px !important}.left-xl-n2{left:-8px !important}}@media (min-width: 1280px){.top-xl-3{top:16px !important}.right-xl-3{right:16px !important}.bottom-xl-3{bottom:16px !important}.left-xl-3{left:16px !important}.top-xl-n3{top:-16px !important}.right-xl-n3{right:-16px !important}.bottom-xl-n3{bottom:-16px !important}.left-xl-n3{left:-16px !important}}@media (min-width: 1280px){.top-xl-4{top:24px !important}.right-xl-4{right:24px !important}.bottom-xl-4{bottom:24px !important}.left-xl-4{left:24px !important}.top-xl-n4{top:-24px !important}.right-xl-n4{right:-24px !important}.bottom-xl-n4{bottom:-24px !important}.left-xl-n4{left:-24px !important}}@media (min-width: 1280px){.top-xl-5{top:32px !important}.right-xl-5{right:32px !important}.bottom-xl-5{bottom:32px !important}.left-xl-5{left:32px !important}.top-xl-n5{top:-32px !important}.right-xl-n5{right:-32px !important}.bottom-xl-n5{bottom:-32px !important}.left-xl-n5{left:-32px !important}}@media (min-width: 1280px){.top-xl-6{top:40px !important}.right-xl-6{right:40px !important}.bottom-xl-6{bottom:40px !important}.left-xl-6{left:40px !important}.top-xl-n6{top:-40px !important}.right-xl-n6{right:-40px !important}.bottom-xl-n6{bottom:-40px !important}.left-xl-n6{left:-40px !important}}@media (min-width: 1280px){.top-xl-7{top:48px !important}.right-xl-7{right:48px !important}.bottom-xl-7{bottom:48px !important}.left-xl-7{left:48px !important}.top-xl-n7{top:-48px !important}.right-xl-n7{right:-48px !important}.bottom-xl-n7{bottom:-48px !important}.left-xl-n7{left:-48px !important}}@media (min-width: 1280px){.top-xl-8{top:64px !important}.right-xl-8{right:64px !important}.bottom-xl-8{bottom:64px !important}.left-xl-8{left:64px !important}.top-xl-n8{top:-64px !important}.right-xl-n8{right:-64px !important}.bottom-xl-n8{bottom:-64px !important}.left-xl-n8{left:-64px !important}}@media (min-width: 1280px){.top-xl-9{top:80px !important}.right-xl-9{right:80px !important}.bottom-xl-9{bottom:80px !important}.left-xl-9{left:80px !important}.top-xl-n9{top:-80px !important}.right-xl-n9{right:-80px !important}.bottom-xl-n9{bottom:-80px !important}.left-xl-n9{left:-80px !important}}@media (min-width: 1280px){.top-xl-10{top:96px !important}.right-xl-10{right:96px !important}.bottom-xl-10{bottom:96px !important}.left-xl-10{left:96px !important}.top-xl-n10{top:-96px !important}.right-xl-n10{right:-96px !important}.bottom-xl-n10{bottom:-96px !important}.left-xl-n10{left:-96px !important}}@media (min-width: 1280px){.top-xl-11{top:112px !important}.right-xl-11{right:112px !important}.bottom-xl-11{bottom:112px !important}.left-xl-11{left:112px !important}.top-xl-n11{top:-112px !important}.right-xl-n11{right:-112px !important}.bottom-xl-n11{bottom:-112px !important}.left-xl-n11{left:-112px !important}}@media (min-width: 1280px){.top-xl-12{top:128px !important}.right-xl-12{right:128px !important}.bottom-xl-12{bottom:128px !important}.left-xl-12{left:128px !important}.top-xl-n12{top:-128px !important}.right-xl-n12{right:-128px !important}.bottom-xl-n12{bottom:-128px !important}.left-xl-n12{left:-128px !important}}.z-n1{z-index:-1}.z-n2{z-index:-2}.site-subheader{position:relative;z-index:2;padding-top:16px;padding-bottom:16px}.site-subheader-overlay{margin-bottom:-96px}@media (min-width: 1012px){.site-subheader-overlay{margin-bottom:-72px}}.site-subheader-sticky{position:-webkit-sticky;position:sticky;top:0;z-index:21}.site-subheader-sticky.is-stuck{background-color:#fff;background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,0.1)}.site-subheader-sticky.is-stuck::after{position:absolute;right:0;bottom:-12px;left:0;z-index:-1;display:block;height:12px;content:"";background:linear-gradient(rgba(0,0,0,0.075), rgba(0,0,0,0.001)) repeat-x 0 0}.subheader-title{display:block;margin-bottom:10px;font-weight:400;text-align:center}@media (min-width: 1012px){.subheader-title{float:left;text-align:left}}.subheader-nav{font-size:14px}@media (min-width: 768px){.subheader-nav{font-size:16px}}.subheader-nav .btn-outline-purple{font-size:inherit}.subheader-nav .nav-item.selected{color:#24292e}.site-subheader-business{margin-bottom:0;border-bottom:1px solid rgba(0,0,0,0.1)}.site-subheader-pricing{background-color:#fafbfc}.subheader-nav-business .nav-item{color:#6a737d}.subheader-nav-business .nav-item:hover{color:#586069}.plans-cards{display:flex;flex:0 1 100%;flex-direction:column;align-items:center}@media (min-width: 768px){.plans-cards{align-items:stretch;flex-flow:row wrap;justify-content:center}}@media (min-width: 1012px){.plans-cards{flex-wrap:nowrap}}.plans-card{display:flex;margin-right:10px;margin-bottom:20px;margin-left:10px;font-size:14px;flex-direction:column}.plans-card-pricing-footnote{display:inline-block;margin-left:-0.5em}.plans-card-btn{padding:16px;border-color:#e1e4e8;border-width:1px 0 0;border-radius:0 0 2px 2px}.plans-card-btn:hover,.plans-card-btn:active,.plans-card-btn.selected{border-color:transparent}.plans-card-text{display:flex;flex-direction:column;flex:1 1 auto}.pricing-table{text-align:center}.pricing-table thead th{border-bottom:1px #e1e4e8 solid}.pricing-table .pricing-table-spacer{height:5px;border:0}.pricing-table td:first-child{font-weight:500;text-align:left}.pricing-table td,.pricing-table th{width:18%;padding:8px 16px}.pricing-table td:first-child,.pricing-table th:first-child{width:28%;padding-left:0}.pricing-table td:last-child,.pricing-table th:last-child{padding-right:0}.pricing-table td{border-bottom:1px solid #eaecef}.pricing-table td+td{border-left:1px solid #eaecef}.pricing-table-responsive{display:block;width:100%;min-height:0.01%;overflow-x:auto}@media (min-width: 768px){.pricing-table-responsive{display:table}}.pricing-table-header .octicon-link{visibility:hidden}.pricing-table-header:hover .octicon-link{visibility:visible}.jumbotron-codelines{color:rgba(255,255,255,0.6);background:url("/images/modules/site/heroes/simple-codelines.svg"),#2b3137;background-position:center 10%;background-size:cover}.jumbotron-netneutrality{background:#24292e}@media (min-width: 768px){.jumbotron-netneutrality{background:url("/images/modules/site/netneutrality/netneutrality.png"),#24292e;background-position:center top;background-size:150% auto}}@media (min-width: 1012px){.jumbotron-netneutrality{background-size:130% auto}}@media (min-width: 1280px){.jumbotron-netneutrality{background-size:cover}}.jumbotron-integrations{background-image:url("/images/modules/site/heroes/features-hero-integrations.svg");background-repeat:no-repeat;background-position:top center;background-size:110% auto}.jumbotron-endpoints{background-image:url("/images/modules/site/heroes/features-hero-integrations-endpoints.svg");background-repeat:no-repeat;background-position:center;background-size:100%}.jumbotron-projects{background-image:url("/images/modules/site/heroes/features-hero-project-management.svg");background-position:top center, 0 0;background-size:110% auto}.jumbotron-code-review{background-image:url("/images/modules/site/heroes/features-hero-code-review.svg");background-position:top center, 0 0;background-size:110% auto}.jumbotron-updates{margin-bottom:40px;background-color:#2f363d;background-image:url("/images/modules/marketplace/bg-hero.svg");background-repeat:repeat-y;background-position:center top;background-size:110% auto}@media (min-width: 768px){.jumbotron-updates{background-repeat:no-repeat}}.jumbotron-updates .updates-video{bottom:-40px}.jumbotron-link{font-weight:400;border-bottom:1px solid rgba(255,255,255,0.125)}.jumbotron-link:hover{text-decoration:none;border-bottom-color:rgba(255,255,255,0.75)}.jumbotron-video{position:relative;margin-top:24px;margin-bottom:-24px}@media (min-width: 544px){.jumbotron-video{margin-top:32px;margin-bottom:-32px}}@media (min-width: 1012px){.jumbotron-video{margin-top:48px;margin-bottom:-48px}}@media (min-width: 1280px){.jumbotron-video{margin-top:64px;margin-bottom:-64px}}.jumbotron-video-close{position:absolute;top:0;right:-40px}.jumbotron-link-followup{position:relative;z-index:1;display:inline-block;padding:4px;margin:0 auto;line-height:1;white-space:normal}.jumbotron-link-followup:hover{text-decoration:none}@media (min-width: 768px){.jumbotron-link-followup{display:block;margin:0}}.jumbotron-link-followup .jumbotron-link-followup-icon{position:relative;left:-4px;width:25px;height:25px;margin-left:-30px;vertical-align:middle}@media (min-width: 768px){.jumbotron-link-followup .jumbotron-link-followup-icon{width:30px;height:30px;margin-top:-2px;margin-left:-40px}}.featurette-heading{text-align:center}@media (min-width: 768px){.featurette-heading{text-align:inherit}}.featurette-benefit-img{width:50px;vertical-align:top}@media (min-width: 768px){.featurette-benefit-img{width:60px}}.featurette-icon{width:100%;height:auto}.featurette-illo{padding:0 5%}@media (min-width: 768px){.featurette-illo{padding:0}}.business-security-cta{padding-top:40px;padding-bottom:40px;border-top:1px solid #eee}.business-security-cta .container{width:500px;max-width:90%}@media (min-width: 1012px){.business-security-cta{height:690px;padding-top:290px;padding-bottom:0;background-image:url("/images/modules/site/business-security-billboard-bg.svg");background-repeat:no-repeat;background-position:center 20px;background-size:1850px 675px;border-top:0}}@media (min-width: 768px){.illflow{height:600px;background-image:url("/images/modules/site/illflow_window_ui.png");background-repeat:no-repeat;background-position:top center;background-size:795px auto}}@media (min-width: 768px){.illflow-purple .selected{background-color:#f5f0ff}.illflow-purple .selected::after{border-color:transparent transparent #f5f0ff}.illflow-purple .illflow-item .illflow-item-heading{color:#6f42c1}}@media (min-width: 768px){.illflow-blue .selected{background-color:#f1f8ff}.illflow-blue .selected::after{border-color:transparent transparent #f1f8ff}.illflow-blue .illflow-item .illflow-item-heading{color:#0366d6}}@media (min-width: 768px){.illflow-no-bg{background-image:none}}.illflow-no-bg .illflow-item::before{background-image:none}@media (min-width: 768px){.illflow-steps{margin-top:24px;margin-right:-24px;margin-left:-24px}.illflow-steps::before{display:table;content:""}.illflow-steps::after{display:table;clear:both;content:""}}.illflow-step{display:none}@media (min-width: 768px){.illflow-step.active{display:block}}.illflow-item{position:relative;padding:0 10%;margin-bottom:40px;text-align:center}.illflow-item::before{position:absolute;top:10%;left:-6%;z-index:-1;display:block;padding-top:200%;padding-left:110%;content:"";background-image:url("/images/modules/site/illflow_window_ui.png");background-repeat:no-repeat;background-size:100% auto}@media (min-width: 768px){.illflow-item::before{display:none}}.illflow-item .illflow-item-heading{position:relative;color:#444d56}@media (min-width: 768px){.illflow-item{float:left;width:33.333333%;padding:24px;margin-bottom:0;cursor:pointer;border-radius:6px}.illflow-item:not(.selected):hover{background-color:#fafbfc}.illflow-item.selected .illflow-item-heading{color:#24292e}.illflow-item.selected::after{position:absolute;top:-30px;left:50%;display:block;width:0;height:0;margin-left:-15px;pointer-events:none;content:" ";border-style:outset solid solid;border-width:15px}.illflow-item.selected:first-child::after{left:75%}.illflow-item.selected:last-child::after{left:25%}}.illflow-item-description{margin-top:0}.illflow-img{display:block;width:400px;height:auto;margin:0 auto}@media (min-width: 768px){.illflow-bizsecurity{height:auto;background-image:url("/images/modules/site/business-security-illflow-bg.png");background-size:1000px auto}}.illflow-bizsecurity .img-responsive{max-width:400px}.illflow-bizsecurity .illflow-item::before{display:none}.IconNav{font-size:12px;transition:transform ease 0.4s}@media (min-width: 1012px){.IconNav{font-size:14px}}.IconNav-item{border-bottom:3px solid transparent}.IconNav-item .IconNav-img{max-height:60px;transition:transform ease-in-out 0.25s}.IconNav-item:hover .IconNav-img{transform:translateY(-10px)}.IconNav-item.selected{border-color:#444d56}.IconNav.is-stuck{transform:translateY(-70px)}.IconNav.is-stuck .IconNav-img{opacity:0;transition:opacity ease-in-out 0.4s, transform ease-in-out 0.25s}.IconNav.is-stuck:hover{transform:translateY(0)}.IconNav.is-stuck:hover .IconNav-img{opacity:1}.home-hero-signup .form-label{display:block;margin-bottom:5px;font-size:16px;font-weight:inherit;text-align:left}.home-hero-signup .form-control-lg{width:100%;min-height:46px;padding:10px;font-size:16px;border-radius:5px}.home-hero-signup .form-control-lg:-ms-input-placeholder{color:#24292e}.home-hero-signup .form-control-lg::-ms-input-placeholder{color:#24292e}.home-hero-signup .form-control-lg::placeholder{color:#24292e}.home-hero-signup .form-control-lg:focus{box-shadow:0 0 0 0.2em rgba(255,255,255,0.3)}.home-hero-signup .form-control-note{margin-top:5px;margin-bottom:0;font-size:12px;color:#6a737d}.home-hero-signup .form-control-note .notice-highlight{color:#959da5}.casestudy-hero{background-position:center;background-size:cover}.casestudy-square::after,.casestudy-rectangle::after{display:block;content:"";transition:padding-bottom 0.3s}.casestudy-square::after{padding-bottom:100%}.casestudy-rectangle::after{padding-bottom:50%}.casestudy-hero-btn{position:absolute;top:16px;right:16px;z-index:2;opacity:0;transform:translate3d(-5px, 5px, 0) scale(0.95)}.casestudy-hero-btn,.casestudy-header,.casestudy-facts{transition:.4s}.casestudy-controls{transition:transform .4s}.casestudy-link{flex:1;background-position:center;background-size:cover;transition:transform 0.3s, box-shadow 0.3s}.casestudy-link .casestudy-facts{opacity:0}.casestudy-link:hover{text-decoration:none}@media (min-width: 544px){.casestudy-link:hover .casestudy-controls{transform:scale(1.08)}}.casestudy-link:hover .casestudy-title{color:#1277eb !important}@media (min-width: 544px){.casestudy-link:hover .casestudy-header{opacity:0}}@media (min-width: 544px){.casestudy-link:hover .casestudy-hero-btn,.casestudy-link:hover .casestudy-facts{opacity:1 !important;transform:translate3d(0, 0, 0) scale(1)}}.is-expanded .casestudy-link:hover{transform:scale(1)}.col-12 .casestudy-link .casestudy-square::after{padding-bottom:25%}.col-12 .casestudy-link .casestudy-facts{display:none !important}.col-12 .casestudy-link .casestudy-header{opacity:1 !important}.MarketingBody{font-size:16px}.MarketingBody>p{margin-bottom:24px;color:#586069}.MarketingBody h2,.MarketingBody h3{margin-bottom:8px;font-family:InterUI,-apple-system,BlinkMacSystemFont,"Helvetica Neue","Segoe UI",Oxygen,Ubuntu,Cantarell,"Open Sans",sans-serif;font-weight:400}.MarketingBody blockquote{padding-top:0;padding-bottom:0;padding-left:8px;margin-bottom:24px;font-family:"SFMono-Regular",Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:16px;line-height:1.4;color:#586069;border-left:3px solid #e1e4e8;padding:0;font-size:20px !important;color:#1277eb;border:0}@media (min-width: 768px){.MarketingBody blockquote{padding-left:12px;margin-bottom:32px;margin-left:-15px;font-size:18px;line-height:1.5}}.MarketingBody ul,.MarketingBody ol{padding-left:1.25em;margin-bottom:24px;overflow:hidden;color:#586069}.MarketingBody p+ul{margin-top:-8px}.MarketingBody .video-responsive{margin-right:16px;margin-bottom:16px;margin-left:16px}.MarketingBody-lead{font-family:InterUI, -apple-system, BlinkMacSystemFont, "Helvetica Neue", "Segoe UI", Oxygen, Ubuntu, Cantarell, "Open Sans", sans-serif}.MarketingBody-lead>p:first-child{-webkit-font-smoothing:antialiased;font-size:21px;font-weight:300;color:#24292e !important}@media (min-width: 768px){.MarketingBody-lead>p:first-child{font-size:24px}}@media (min-width: 1012px){.MarketingBody-lead>p:first-child{font-size:26px}}.MarketingBody-lead a{color:#1277eb;text-decoration:none !important;box-shadow:0 1px 0 0 rgba(18,119,235,0.5);transition:.2s}.MarketingBody-lead a:hover{color:#0366d6;box-shadow:0 1px 0 0 #1277eb}.Story{min-width:280px}@media (min-width: 1012px){.Story--large{min-width:330px;max-width:400px}}.Story--stagger:nth-child(even){margin-top:-16px}.Story--stagger:nth-child(odd){margin-bottom:-16px}.Story-link{transition:transform 0.3s}.Story-link:hover{text-decoration:none;transform:scale(1.025)}.Story-link:hover .Story-title{color:#e36209 !important;text-decoration:underline}.Story-link--customer:hover .Story-title{color:#6f42c1 !important}.Story-title{transition:color 0.3s}.summarylink .summarylink-illustration{display:none;transition:opacity 0.7s}@media (min-width: 544px){.summarylink .summarylink-illustration{top:-50%;display:block;opacity:0}}.summarylink:hover,.summarylink:active{text-decoration:none}.summarylink:hover .circle,.summarylink:active .circle{text-decoration:none;transform:scale(1.05)}@media (min-width: 544px){.summarylink:hover .summarylink-illustration,.summarylink:active .summarylink-illustration{top:24px;opacity:1}}@media (min-width: 544px){.summarylink:hover .summarylink-btn,.summarylink:active .summarylink-btn{border-color:#d1d5da;box-shadow:0 1px 15px rgba(27,31,35,0.15)}}.summarylink:hover .summarylink-btn .octicon,.summarylink:active .summarylink-btn .octicon{filter:grayscale(0%)}.summarylink-btn{border:solid 1px transparent;transition:box-shadow 0.3s, border-color 0.3s}@media (min-width: 544px){.summarylink-btn .octicon{filter:grayscale(100%);transition:filter 0.3s}}@media (min-width: 544px){.summarylink-illustration{position:absolute;top:0;right:40px;width:25%}}@media (min-width: 1012px){.summarylink-illustration{top:16px;right:auto;left:40%;width:15%}}@media (min-width: 768px){.communitystats{padding-left:50%}}.communitystats .summarylink:nth-child(1) .circle{width:225px;height:225px}.communitystats .summarylink:nth-child(2) .circle{left:20%;width:175px;height:175px}@media (min-width: 1012px){.communitystats .summarylink:nth-child(2) .circle{top:40px;left:25%}}.communitystats .summarylink:nth-child(3) .circle{left:10%;width:140px;height:140px}@media (min-width: 1012px){.communitystats .summarylink:nth-child(3) .circle{left:16%}}.communitystats .circle{transition:transform 0.3s}.communitystats .circle.bg-orange{background-color:#fb8532 !important}@media (min-width: 768px){.communitystats .circle{position:absolute;left:0}}@media (min-width: 768px){.communitystats .summarylink-btn{max-width:400px}}.logo-img{position:relative;display:inline-block;width:auto;height:25px;margin:10px;vertical-align:middle}@media (min-width: 768px){.logo-img{width:auto;height:30px;margin:10px}}@media (min-width: 1012px){.logo-img{height:35px;margin:10px 20px}}.logo-img-sm{position:relative;display:inline-block;width:auto;height:20px;margin:10px;vertical-align:middle}@media (min-width: 768px){.logo-img-sm{width:auto;height:25px;margin:10px}}.logo-img-lg{width:auto;height:35px;margin:5px 15px}@media (min-width: 768px){.logo-img-lg{width:auto;height:40px;margin:10px 15px}}@media (min-width: 1012px){.logo-img-lg{height:50px;margin:10px 25px}}.tooltipped-logo{display:inline-block}.tooltipped-logo.tooltipped-s::after,.tooltipped-logo.tooltipped-se::after,.tooltipped-logo.tooltipped-sw::after{font-size:14px}.Slots{height:1.5em;margin-bottom:-0.15em}.Slots-item{height:2em;padding-top:5px}@keyframes RotateSlot{0%{margin-top:0}3%{margin-top:-2em}20%{margin-top:-2em}23%{margin-top:-4em}40%{margin-top:-4em}43%{margin-top:-6em}60%{margin-top:-6em}63%{margin-top:-8em}90%{margin-top:-8em}93%{margin-top:0}100%{margin-top:0}}.Slots-item:first-of-type{animation-name:RotateSlot;animation-duration:15s;animation-timing-function:ease-in;animation-delay:2.5s;animation-iteration-count:infinite}.jumbotron-updates-universe{background:#2f363d url("/images/modules/site/updates/stars-sm.svg") center center repeat;background-size:contain}.btn-outline-transparent{color:#fff;background-color:rgba(0,0,0,0);border-color:rgba(255,255,255,0.3)}.btn-outline-transparent:hover,.btn-outline-transparent:active{color:#0366d6;background:#fff;border-color:#fff}.waves{background:#fff url("/images/modules/site/updates/waves.svg") top center no-repeat;background-size:cover}@media (min-width: 1640px){.waves{background-repeat:repeat-x;background-size:contain}}.hr-darker{border-bottom-color:#d1d5da}.octoverse{padding-top:80px;padding-bottom:80px;background-color:#30363d;background-image:url("/images/modules/site/updates/octoverse-bg.png");background-repeat:no-repeat;background-position:bottom right;background-size:contain}@media (min-width: 768px){.octoverse{padding-top:120px;padding-bottom:120px;background-position:center right}}.i-am-a-developer-link{background-position:center center;background-size:cover}.i-am-a-developer-link::before{position:absolute;top:0;display:block;width:100%;height:100%;content:"";background:#24292e;opacity:0.8;transition:opacity 0.3s ease-in-out}.i-am-a-developer-link:hover::before{opacity:0.1}.coming-soon{position:relative;background-color:#2f363d;background-image:linear-gradient(145deg, #e46e65 0%, #db5070 50%, #98649f 100%);background-repeat:no-repeat;background-position:center center}@media (min-width: 768px){.pt-md-biggo{padding-top:160px}}.stars-rainbow{background:#fafbfc url("/images/modules/site/updates/stars-color.png") center top repeat-x;background-size:80% auto}.featurette-video{margin-bottom:40px;background-color:#2f363d;background-repeat:repeat-y;background-position:center top;background-size:110% auto}@media (min-width: 768px){.featurette-video{background-repeat:no-repeat}}.featurette-video .updates-video{bottom:-40px}.btn-outline-desktop{color:#9f7be1;background:#24292e;border-color:rgba(159,123,225,0.5)}.btn-outline-desktop:hover,.btn-outline-desktop:active{color:#fff;background:#9f7be1;background-image:linear-gradient(to bottom, #8241f9, #4e277b);border-color:#9f7be1;border-color:#150a27}.btn-outline-desktop:active{background-image:linear-gradient(to top, #8241f9, #7038cd)}.btn-outline-atom{color:#4de0c1;background:#24292e;border-color:rgba(77,224,193,0.5)}.btn-outline-atom:hover,.btn-outline-atom:active{color:#fff;background:rgba(77,224,193,0.5);background-image:linear-gradient(to bottom, #3fb69c, #2b7e6c);border-color:#3fb69c;border-color:#150a27}.btn-outline-atom:active{background-image:linear-gradient(to top, #3fb69c, #2b7e6c)}.featurette-desktop{background-color:#24292e;background-image:url("/images/modules/site/heroes/star-bg.svg"),linear-gradient(#191c20, #24292e 15%);background-repeat:repeat-x;background-position:center 0, 0 0, 0 0;background-size:100% auto}.apps-cluster .CircleBadge{margin:16px}@media (min-width: 1012px){.apps-cluster .CircleBadge{position:relative}}@media (min-width: 1012px){.apps-cluster .CircleBadge:nth-child(odd){margin-top:-24px;animation-delay:1.5s;animation-direction:reverse}}@media (min-width: 1012px){.apps-cluster .CircleBadge:nth-child(even){margin-top:24px;animation-duration:6s}}@media (min-width: 1012px){.apps-cluster .CircleBadge:nth-child(1){animation-delay:2.1s}}@media (min-width: 1012px){.apps-cluster .CircleBadge:nth-child(4){animation-delay:0.7s;animation-direction:reverse}}@media (min-width: 1012px){.apps-cluster .CircleBadge:nth-child(6){animation-delay:0.3s}}.apps-cluster .CircleBadge.tooltipped:hover{box-shadow:0 3px 8px 0 rgba(0,0,0,0.2)}@keyframes appsClusterFloat{0%{top:0}40%{top:8px}100%{top:0}}.apps-quadrangle{position:relative;width:280px;height:280px}.apps-quadrangle .CircleBadge{position:absolute}.apps-quadrangle .CircleBadge::after{position:absolute;top:50%;left:0;z-index:-1;display:inline-block;height:3px;content:"";background-color:#e1e4e8;animation:2s ease-in-out infinite alternate forwards connect_four}.apps-quadrangle .CircleBadge:nth-child(1){top:0;left:0}.apps-quadrangle .CircleBadge:nth-child(2){top:0;right:0}.apps-quadrangle .CircleBadge:nth-child(2)::after{margin-top:32px;margin-left:-40px;transform:rotate(-45deg) scale(-1, 1);transform-origin:96px 96px;animation-delay:0.7s}.apps-quadrangle .CircleBadge:nth-child(3){top:auto;bottom:0;left:0}.apps-quadrangle .CircleBadge:nth-child(3)::after{animation-delay:1.7s}.apps-quadrangle .CircleBadge:nth-child(4){top:auto;right:0;bottom:0}.apps-quadrangle .CircleBadge:nth-child(4)::after{content:none}@keyframes connect_four{from{width:0}to{width:280px}}.video-responsive{position:relative;max-width:100%;height:0;padding-bottom:56.25%}.video-responsive iframe,.video-responsive object,.video-responsive embed{position:absolute;top:0;left:0;width:100%;height:100%}.togglevideo .togglevideo-hidewhencollapsed{display:none}.togglevideo.is-expanded .togglevideo-hidewhenexpanded{display:none}.togglevideo.is-expanded .togglevideo-showwhenexpanded{display:block}@media (min-width: 768px){.togglevideo.is-expanded .togglevideo-hidewhenexpanded-md{display:none}}.DeveloperVideo-data{right:0;bottom:0;left:0;z-index:0;background:#24292e}@media (min-width: 768px){.DeveloperVideo-data{padding-top:30%;background:none;background-image:linear-gradient(rgba(0,0,0,0), rgba(27,31,35,0.95))}}.DeveloperVideoData-play{top:calc(50% - 40px);left:calc(50% - 40px);z-index:1}@media (min-width: 768px){.DeveloperVideoData-play{top:20%}}@media (min-width: 1012px){.DeveloperVideoData-play{top:calc(50% - 40px)}}.TenYearNav{top:calc(50% - 175px);z-index:10}.TenYearNav-digits{opacity:0}.TenYearNav-year{display:block;border-left:8px solid #d1d5da;transition:border 0.3s ease-in-out}.TenYearNav-year.blue{color:#2188ff !important;border-color:#2188ff}.TenYearNav-year.purple{color:#8a63d2 !important;border-color:#8a63d2}.TenYearNav-year.yellow{color:#ffd33d !important;border-color:#ffd33d}.TenYearNav-year.green{color:#34d058 !important;border-color:#34d058}.TenYearNav-year.red{color:#ea4a5a !important;border-color:#ea4a5a}.TenYearNav-year.orange{color:#fb8532 !important;border-color:#fb8532}.TenYearNav-year.selected,.TenYearNav-year:hover{border-left-width:16px}.TenYearNav-year.selected .TenYearNav-digits,.TenYearNav-year:hover .TenYearNav-digits{background:#fff;opacity:1}.TenYears-hero{margin-top:-15%}@media (min-height: 720px){.TenYears-hero{margin-top:0}}.TenYears-year{font-size:60px;font-weight:500;line-height:0.9}@media (min-width: 768px){.TenYears-year{font-size:80px}}.btn-tenyear{border:2px solid #0366d6;box-shadow:6px 6px 0 0 #0366d6;transition:box-shadow 0.15s, margin 0.15s}.btn-tenyear:hover{box-shadow:0 0 0 0 #0366d6}.tentpole-purple{border:2px solid #6f42c1;box-shadow:10px 10px 0 0 #6f42c1}.tentpole-blue{border:2px solid #0366d6;box-shadow:10px 10px 0 0 #0366d6}.tentpole-green{border:2px solid #28a745;box-shadow:10px 10px 0 0 #28a745}.tentpole-yellow{border:2px solid #dbab09;box-shadow:10px 10px 0 0 #dbab09}.tentpole-date{top:-20px}.TenYearsImg-lowerleft{bottom:0;left:4%}@media (min-width: 1280px){.TenYearsImg-lowerleft{left:-5%}}.TenYearsImg-lowerright{right:4%;bottom:0}@media (min-width: 1280px){.TenYearsImg-lowerright{right:-10%}}.TenYearsImg-midright{top:10%;right:0}@media (min-width: 1012px){.TenYearsImg-midright{right:-6%}}.alt-mono-font{font-family:"SFMono-Regular",Consolas,"Liberation Mono",Menlo,Courier,monospace !important}.text-yellow-700{color:#dbab09}.text-yellow-800{color:#b08800}.bg-yellow-700{background-color:#dbab09}.text-orange-600{color:#e36209}@media (min-width: 768px){.mt-md-n10{margin-top:-96px !important}}@media (min-width: 1012px){.mt-lg-n10{margin-top:-96px !important}}.z-n1{z-index:-1}.rotated{transform:rotate(15deg)}@media (min-width: 768px){.px-md-8{padding-right:64px !important;padding-left:64px !important}}.library-collection-card-header{height:300px;background-color:#24292e;background-position:center center;background-size:cover;border-top-left-radius:6px;border-top-right-radius:6px}.library-resource-border{border-top:1px #e1e4e8 solid}.server-stats .container{width:auto;max-width:1012px;padding-right:16px;padding-left:16px;margin-right:auto;margin-left:auto}@media (min-width: 544px){.server-stats .container{padding-right:40px;padding-left:40px}}@media (min-width: 1012px){.server-stats .container{padding-right:16px;padding-left:16px}}.icon-cta{padding-left:24px}.icon-cta>.octicon{float:left;width:16px;margin-top:0.1em;margin-left:-24px;color:#6a737d;text-align:center}.signup-prompt{border:1px solid rgba(27,31,35,0.075)}@media (min-width: 768px){.signup-prompt{background:url("/images/modules/site/site-signup-prompt.png");background-position:center 10%;background-size:cover}}@media (min-width: 1012px){.signup-prompt{background-position:center 30%;background-size:100% auto}}.signup-prompt-bg{background-image:linear-gradient(180deg, rgba(255,255,255,0) 50%, #fff),linear-gradient(70deg, #eaf5ff 32%, #f6fff8)}@media (min-width: 1012px){.enterprise-prompt{background:url("/images/modules/site/patterns/dots-large.svg");background-position:center 10%}}
|
|
/*# sourceMappingURL=site-73680c8bae9d90e48e18affb463ea2cd.css.map */
|
|
|
|
/*!
|
|
* Primer-product
|
|
* http://primer.github.io
|
|
*
|
|
* Released under MIT license. Copyright (c) 2018 GitHub Inc.
|
|
*/.flash{position:relative;padding:16px;color:#032f62;background-color:#dbedff;border:1px solid rgba(27,31,35,0.15);border-radius:3px}.flash p:last-child{margin-bottom:0}.flash-messages{margin-bottom:24px}.flash-close{float:right;padding:16px;margin:-16px;color:inherit;text-align:center;cursor:pointer;background:none;border:0;-webkit-appearance:none;-moz-appearance:none;appearance:none;opacity:0.6}.flash-close:hover{opacity:1}.flash-action{float:right;margin-top:-3px;margin-left:24px}.flash-warn{color:#735c0f;background-color:#fffbdd;border-color:rgba(27,31,35,0.15)}.flash-error{color:#86181d;background-color:#ffdce0;border-color:rgba(27,31,35,0.15)}.flash-success{color:#165c26;background-color:#dcffe4;border-color:rgba(27,31,35,0.15)}.flash-full{margin-top:-1px;border-width:1px 0;border-radius:0}.warning{padding:.5em;margin-bottom:0.8em;font-weight:600;background-color:#fffbdd}.avatar{display:inline-block;overflow:hidden;line-height:1;vertical-align:middle;border-radius:3px}.avatar-small{border-radius:2px}.avatar-link{float:left;line-height:1}.avatar-group-item{display:inline-block;margin-bottom:3px}.avatar-parent-child{position:relative}.avatar-child{position:absolute;right:-15%;bottom:-9%;background-color:#fff;border-radius:2px;box-shadow:-2px -2px 0 rgba(255,255,255,0.8)}.avatar-stack{display:inline-block;white-space:nowrap}.avatar-stack .avatar{position:relative;z-index:2;display:inline-block;width:20px;height:20px;box-sizing:content-box;margin-right:-15px;background-color:#fff;border-right:1px solid #fff;border-radius:2px;transition:margin 0.1s ease-in-out}.avatar-stack .avatar:only-child{background-color:transparent}.avatar-stack .avatar:first-child{z-index:3}.avatar-stack .avatar:last-child{z-index:1;margin-right:0;border-right:0}.avatar-stack:hover .avatar{margin-right:3px}.avatar-stack:hover .avatar:last-child{margin-right:0}.AvatarStack{position:relative;min-width:26px;height:20px}.AvatarStack .AvatarStack-body{position:absolute}.AvatarStack.AvatarStack--two{min-width:36px}.AvatarStack.AvatarStack--three-plus{min-width:46px}.AvatarStack-body{display:flex;background:#fff}.AvatarStack-body .avatar{position:relative;z-index:2;display:flex;width:20px;height:20px;box-sizing:content-box;margin-right:-11px;background-color:#fff;border-right:1px solid #fff;border-radius:2px;transition:margin 0.1s ease-in-out}.AvatarStack-body .avatar:first-child{z-index:3}.AvatarStack-body .avatar:last-child{z-index:1;border-right:0}.AvatarStack-body .avatar img{border-radius:2px}.AvatarStack-body .avatar:nth-child(n+4){display:none;opacity:0}.AvatarStack-body:hover .avatar{margin-right:3px}.AvatarStack-body:hover .avatar:nth-child(n+4){display:flex;opacity:1}.AvatarStack-body:hover .avatar-more{display:none !important}.avatar.avatar-more{z-index:1;margin-right:0;background:#f6f8fa}.avatar.avatar-more::before,.avatar.avatar-more::after{position:absolute;display:block;height:20px;content:"";border-radius:2px;outline:1px solid #fff}.avatar.avatar-more::before{width:17px;background:#e1e4e8}.avatar.avatar-more::after{width:14px;background:#d1d5da}.AvatarStack--right .AvatarStack-body{right:0;flex-direction:row-reverse}.AvatarStack--right .AvatarStack-body:hover .avatar{margin-right:0;margin-left:3px}.AvatarStack--right .avatar.avatar-more{background:#d1d5da}.AvatarStack--right .avatar.avatar-more::before{width:5px}.AvatarStack--right .avatar.avatar-more::after{width:2px;background:#f6f8fa}.AvatarStack--right .avatar{margin-right:0;margin-left:-11px;border-right:0;border-left:1px solid #fff}.CircleBadge{display:flex;align-items:center;justify-content:center;background-color:#fff;border-radius:50%;box-shadow:0 1px 5px rgba(27,31,35,0.15)}.CircleBadge-icon{max-width:60% !important;height:auto !important;max-height:55% !important}.CircleBadge--small{width:56px;height:56px}.CircleBadge--medium{width:96px;height:96px}.CircleBadge--large{width:128px;height:128px}.DashedConnection{position:relative}.DashedConnection::before{position:absolute;top:50%;left:0;width:100%;content:"";border-bottom:2px dashed #e1e4e8}.DashedConnection .CircleBadge{position:relative}.blankslate{position:relative;padding:32px;text-align:center;background-color:#fafbfc;border:1px solid #e1e4e8;border-radius:3px;box-shadow:inset 0 0 10px rgba(27,31,35,0.05)}.blankslate code{padding:2px 5px 3px;font-size:14px;background:#fff;border:1px solid #eaecef;border-radius:3px}.blankslate-icon{margin-right:4px;margin-bottom:8px;margin-left:4px;color:#a3aab1}.blankslate-capped{border-radius:0 0 3px 3px}.blankslate-spacious{padding:80px 40px}.blankslate-narrow{width:485px;margin:0 auto}.blankslate-large h3{margin:16px 0;font-size:20px}.blankslate-large p{font-size:16px}.blankslate-clean-background{background:none;border:0;box-shadow:none}.branch-name{display:inline-block;padding:2px 6px;font:12px "SFMono-Regular",Consolas,"Liberation Mono",Menlo,Courier,monospace;color:rgba(27,31,35,0.6);background-color:#eaf5ff;border-radius:3px}.branch-name .octicon{margin:1px -2px 0 0;color:#a8bbd0}a.branch-name{color:#0366d6}.labels{position:relative}.label,.Label{display:inline-block;padding:3px 4px;font-size:12px;font-weight:600;line-height:1;color:#fff;border-radius:2px;box-shadow:inset 0 -1px 0 rgba(27,31,35,0.12)}.label:hover,.Label:hover{text-decoration:none}.Label--gray{color:#586069;background-color:#eaecef}.Label--outline{margin-top:-1px;margin-bottom:-1px;font-weight:400;color:#586069;background-color:transparent;border:1px solid rgba(27,31,35,0.15);box-shadow:none}.Label--outline-green{color:#28a745;border:1px solid #34d058}.Label--gray-darker{background-color:#6a737d}.Label--orange{background-color:#d15704}.state,.State{display:inline-block;padding:4px 8px;font-weight:600;line-height:20px;color:#fff;text-align:center;background-color:#6a737d;border-radius:3px}.State--green{background-color:#2cbe4e}.State--purple{background-color:#6f42c1}.State--red{background-color:#cb2431}.State--small{padding:.125em 4px;font-size:12px}.State--small .octicon{width:1em}.Counter{display:inline-block;padding:2px 5px;font-size:12px;font-weight:600;line-height:1;color:#586069;background-color:rgba(27,31,35,0.08);border-radius:20px}.Counter--gray-light{color:#24292e;background-color:rgba(27,31,35,0.15)}.Counter--gray{color:#fff;background-color:#6a737d}.markdown-body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:16px;line-height:1.5;word-wrap:break-word}.markdown-body::before{display:table;content:""}.markdown-body::after{display:table;clear:both;content:""}.markdown-body>*:first-child{margin-top:0 !important}.markdown-body>*:last-child{margin-bottom:0 !important}.markdown-body a:not([href]){color:inherit;text-decoration:none}.markdown-body .absent{color:#cb2431}.markdown-body .anchor{float:left;padding-right:4px;margin-left:-20px;line-height:1}.markdown-body .anchor:focus{outline:none}.markdown-body p,.markdown-body blockquote,.markdown-body ul,.markdown-body ol,.markdown-body dl,.markdown-body table,.markdown-body pre{margin-top:0;margin-bottom:16px}.markdown-body hr{height:.25em;padding:0;margin:24px 0;background-color:#e1e4e8;border:0}.markdown-body blockquote{padding:0 1em;color:#6a737d;border-left:0.25em solid #dfe2e5}.markdown-body blockquote>:first-child{margin-top:0}.markdown-body blockquote>:last-child{margin-bottom:0}.markdown-body kbd{display:inline-block;padding:3px 5px;font-size:11px;line-height:10px;color:#444d56;vertical-align:middle;background-color:#fafbfc;border:solid 1px #c6cbd1;border-bottom-color:#959da5;border-radius:3px;box-shadow:inset 0 -1px 0 #959da5}.markdown-body h1,.markdown-body h2,.markdown-body h3,.markdown-body h4,.markdown-body h5,.markdown-body h6{margin-top:24px;margin-bottom:16px;font-weight:600;line-height:1.25}.markdown-body h1 .octicon-link,.markdown-body h2 .octicon-link,.markdown-body h3 .octicon-link,.markdown-body h4 .octicon-link,.markdown-body h5 .octicon-link,.markdown-body h6 .octicon-link{color:#1b1f23;vertical-align:middle;visibility:hidden}.markdown-body h1:hover .anchor,.markdown-body h2:hover .anchor,.markdown-body h3:hover .anchor,.markdown-body h4:hover .anchor,.markdown-body h5:hover .anchor,.markdown-body h6:hover .anchor{text-decoration:none}.markdown-body h1:hover .anchor .octicon-link,.markdown-body h2:hover .anchor .octicon-link,.markdown-body h3:hover .anchor .octicon-link,.markdown-body h4:hover .anchor .octicon-link,.markdown-body h5:hover .anchor .octicon-link,.markdown-body h6:hover .anchor .octicon-link{visibility:visible}.markdown-body h1 tt,.markdown-body h1 code,.markdown-body h2 tt,.markdown-body h2 code,.markdown-body h3 tt,.markdown-body h3 code,.markdown-body h4 tt,.markdown-body h4 code,.markdown-body h5 tt,.markdown-body h5 code,.markdown-body h6 tt,.markdown-body h6 code{font-size:inherit}.markdown-body h1{padding-bottom:0.3em;font-size:2em;border-bottom:1px solid #eaecef}.markdown-body h2{padding-bottom:0.3em;font-size:1.5em;border-bottom:1px solid #eaecef}.markdown-body h3{font-size:1.25em}.markdown-body h4{font-size:1em}.markdown-body h5{font-size:0.875em}.markdown-body h6{font-size:0.85em;color:#6a737d}.markdown-body ul,.markdown-body ol{padding-left:2em}.markdown-body ul.no-list,.markdown-body ol.no-list{padding:0;list-style-type:none}.markdown-body ul ul,.markdown-body ul ol,.markdown-body ol ol,.markdown-body ol ul{margin-top:0;margin-bottom:0}.markdown-body li{word-wrap:break-all}.markdown-body li>p{margin-top:16px}.markdown-body li+li{margin-top:.25em}.markdown-body dl{padding:0}.markdown-body dl dt{padding:0;margin-top:16px;font-size:1em;font-style:italic;font-weight:600}.markdown-body dl dd{padding:0 16px;margin-bottom:16px}.markdown-body table{display:block;width:100%;overflow:auto}.markdown-body table th{font-weight:600}.markdown-body table th,.markdown-body table td{padding:6px 13px;border:1px solid #dfe2e5}.markdown-body table tr{background-color:#fff;border-top:1px solid #c6cbd1}.markdown-body table tr:nth-child(2n){background-color:#f6f8fa}.markdown-body table img{background-color:transparent}.markdown-body img{max-width:100%;box-sizing:content-box;background-color:#fff}.markdown-body img[align=right]{padding-left:20px}.markdown-body img[align=left]{padding-right:20px}.markdown-body .emoji{max-width:none;vertical-align:text-top;background-color:transparent}.markdown-body span.frame{display:block;overflow:hidden}.markdown-body span.frame>span{display:block;float:left;width:auto;padding:7px;margin:13px 0 0;overflow:hidden;border:1px solid #dfe2e5}.markdown-body span.frame span img{display:block;float:left}.markdown-body span.frame span span{display:block;padding:5px 0 0;clear:both;color:#24292e}.markdown-body span.align-center{display:block;overflow:hidden;clear:both}.markdown-body span.align-center>span{display:block;margin:13px auto 0;overflow:hidden;text-align:center}.markdown-body span.align-center span img{margin:0 auto;text-align:center}.markdown-body span.align-right{display:block;overflow:hidden;clear:both}.markdown-body span.align-right>span{display:block;margin:13px 0 0;overflow:hidden;text-align:right}.markdown-body span.align-right span img{margin:0;text-align:right}.markdown-body span.float-left{display:block;float:left;margin-right:13px;overflow:hidden}.markdown-body span.float-left span{margin:13px 0 0}.markdown-body span.float-right{display:block;float:right;margin-left:13px;overflow:hidden}.markdown-body span.float-right>span{display:block;margin:13px auto 0;overflow:hidden;text-align:right}.markdown-body code,.markdown-body tt{padding:0.2em 0.4em;margin:0;font-size:85%;background-color:rgba(27,31,35,0.05);border-radius:3px}.markdown-body code br,.markdown-body tt br{display:none}.markdown-body del code{text-decoration:inherit}.markdown-body pre{word-wrap:normal}.markdown-body pre>code{padding:0;margin:0;font-size:100%;word-break:normal;white-space:pre;background:transparent;border:0}.markdown-body .highlight{margin-bottom:16px}.markdown-body .highlight pre{margin-bottom:0;word-break:normal}.markdown-body .highlight pre,.markdown-body pre{padding:16px;overflow:auto;font-size:85%;line-height:1.45;background-color:#f6f8fa;border-radius:3px}.markdown-body pre code,.markdown-body pre tt{display:inline;max-width:auto;padding:0;margin:0;overflow:visible;line-height:inherit;word-wrap:normal;background-color:transparent;border:0}.markdown-body .csv-data td,.markdown-body .csv-data th{padding:5px;overflow:hidden;font-size:12px;line-height:1;text-align:left;white-space:nowrap}.markdown-body .csv-data .blob-num{padding:10px 8px 9px;text-align:right;background:#fff;border:0}.markdown-body .csv-data tr{border-top:0}.markdown-body .csv-data th{font-weight:600;background:#f6f8fa;border-top:0}.Popover{position:absolute;z-index:100}.Popover-message{position:relative;width:232px;margin-right:auto;margin-left:auto}.Popover-message::before,.Popover-message::after{position:absolute;left:50%;display:inline-block;content:""}.Popover-message::before{top:-16px;margin-left:-9px;border:8px solid transparent;border-bottom-color:rgba(27,31,35,0.15)}.Popover-message::after{top:-14px;margin-left:-8px;border:7px solid transparent;border-bottom-color:#fff}.Popover-message--bottom::before,.Popover-message--bottom::after,.Popover-message--bottom-right::before,.Popover-message--bottom-right::after,.Popover-message--bottom-left::before,.Popover-message--bottom-left::after{top:auto;border-bottom-color:transparent}.Popover-message--bottom::before,.Popover-message--bottom-right::before,.Popover-message--bottom-left::before{bottom:-16px;border-top-color:rgba(27,31,35,0.15)}.Popover-message--bottom::after,.Popover-message--bottom-right::after,.Popover-message--bottom-left::after{bottom:-14px;border-top-color:#fff}.Popover-message--top-right,.Popover-message--bottom-right{right:-9px;margin-right:0}.Popover-message--top-right::before,.Popover-message--top-right::after,.Popover-message--bottom-right::before,.Popover-message--bottom-right::after{left:auto;margin-left:0}.Popover-message--top-right::before,.Popover-message--bottom-right::before{right:20px}.Popover-message--top-right::after,.Popover-message--bottom-right::after{right:21px}.Popover-message--top-left,.Popover-message--bottom-left{left:-9px;margin-left:0}.Popover-message--top-left::before,.Popover-message--top-left::after,.Popover-message--bottom-left::before,.Popover-message--bottom-left::after{left:24px;margin-left:0}.Popover-message--top-left::after,.Popover-message--bottom-left::after{left:25px}.Popover-message--right::before,.Popover-message--right::after,.Popover-message--right-top::before,.Popover-message--right-top::after,.Popover-message--right-bottom::before,.Popover-message--right-bottom::after,.Popover-message--left::before,.Popover-message--left::after,.Popover-message--left-top::before,.Popover-message--left-top::after,.Popover-message--left-bottom::before,.Popover-message--left-bottom::after{top:50%;left:auto;margin-left:0;border-bottom-color:transparent}.Popover-message--right::before,.Popover-message--right-top::before,.Popover-message--right-bottom::before,.Popover-message--left::before,.Popover-message--left-top::before,.Popover-message--left-bottom::before{margin-top:-9px}.Popover-message--right::after,.Popover-message--right-top::after,.Popover-message--right-bottom::after,.Popover-message--left::after,.Popover-message--left-top::after,.Popover-message--left-bottom::after{margin-top:-8px}.Popover-message--right::before,.Popover-message--right-top::before,.Popover-message--right-bottom::before{right:-16px;border-left-color:rgba(27,31,35,0.15)}.Popover-message--right::after,.Popover-message--right-top::after,.Popover-message--right-bottom::after{right:-14px;border-left-color:#fff}.Popover-message--left::before,.Popover-message--left-top::before,.Popover-message--left-bottom::before{left:-16px;border-right-color:rgba(27,31,35,0.15)}.Popover-message--left::after,.Popover-message--left-top::after,.Popover-message--left-bottom::after{left:-14px;border-right-color:#fff}.Popover-message--right-top::before,.Popover-message--right-top::after,.Popover-message--left-top::before,.Popover-message--left-top::after{top:24px}.Popover-message--right-bottom::before,.Popover-message--right-bottom::after,.Popover-message--left-bottom::before,.Popover-message--left-bottom::after{top:auto}.Popover-message--right-bottom::before,.Popover-message--left-bottom::before{bottom:16px}.Popover-message--right-bottom::after,.Popover-message--left-bottom::after{bottom:17px}@media (min-width: 544px){.Popover-message--large{min-width:320px}}.Subhead{display:flex;padding-bottom:8px;margin-bottom:16px;border-bottom:1px #e1e4e8 solid;flex-flow:row wrap}.Subhead--spacious{margin-top:40px}.Subhead-heading{font-size:24px;font-weight:normal;flex:1 1 auto}.Subhead-heading--danger{font-weight:600;color:#cb2431}.Subhead-description{font-size:14px;color:#586069;flex:1 100%}.Subhead-actions{align-self:center;justify-content:flex-end}.table-list{display:table;width:100%;color:#6a737d;table-layout:fixed;border-bottom:1px solid #e1e4e8}.table-list ol{list-style-type:decimal}.table-list-bordered{border-bottom-color:#eaecef}.table-list-bordered .table-list-cell:first-child{border-left:1px solid #eaecef}.table-list-bordered .table-list-cell:last-child{border-right:1px solid #eaecef}.table-list-item{position:relative;display:table-row;list-style:none}.table-list-item.unread .table-list-cell:first-child{box-shadow:2px 0 0 #0366d6 inset}.table-list-cell{position:relative;display:table-cell;padding:8px 10px;font-size:12px;vertical-align:top;border-top:1px solid #eaecef}.table-list-cell.flush-left{padding-left:0}.table-list-cell.flush-right{padding-right:0}.table-list-cell-checkbox{width:30px;padding-right:0;padding-left:0;text-align:center}.table-list-header{position:relative;margin-top:20px;background-color:#f6f8fa;border:1px solid #e1e4e8;border-radius:3px 3px 0 0}.table-list-header::before{display:table;content:""}.table-list-header::after{display:table;clear:both;content:""}.table-list-header .btn-link{position:relative;display:inline-block;padding-top:13px;padding-bottom:13px;font-weight:400}.table-list-heading{margin-left:10px}.table-list-header-select-all{float:left;width:30px;padding:12px 10px;margin-right:5px;margin-left:-1px;text-align:center}.table-list-header-meta{display:inline-block;padding-top:13px;padding-bottom:13px;color:#586069}.table-list-header-toggle h4{padding:12px 0}.table-list-filters:first-child .table-list-header-toggle:first-child{padding-left:16px}.table-list-header-toggle.states .selected{font-weight:600}.table-list-header-toggle .btn-link{color:#586069}.table-list-header-toggle .btn-link .octicon{margin-right:2px}.table-list-header-toggle .btn-link:hover{color:#24292e;text-decoration:none}.table-list-header-toggle .btn-link.selected,.table-list-header-toggle .btn-link.selected:hover{color:#24292e}.table-list-header-toggle .btn-link+.btn-link{margin-left:10px}.table-list-header-toggle .btn-link:disabled,.table-list-header-toggle .btn-link.disabled{pointer-events:none;opacity:0.5}.table-list-header-toggle .select-menu{position:relative}.table-list-header-toggle .select-menu-item.selected{font-weight:600}.table-list-header-toggle .select-menu-button{padding-right:15px;padding-left:15px}.table-list-header-toggle .select-menu-button:hover,.table-list-header-toggle .select-menu-button.selected,.table-list-header-toggle .select-menu-button.selected:hover{color:#24292e}.table-list-header-toggle .select-menu-modal-holder{right:10px}.table-list-header-toggle .select-menu-modal-holder .select-menu-modal{margin-top:-1px}.table-list-header-next{margin-top:20px;margin-bottom:-1px}.table-list-header-next .table-list-header-select-all{padding-left:14px}.table-list-header-next .select-all-dropdown{padding-top:10px;padding-bottom:10px}.bulk-actions-header{position:-webkit-sticky;position:sticky;top:0;z-index:32;height:50px}.table-list-triage{display:none}.triage-mode .table-list-filters{display:none}.triage-mode .table-list-triage{display:block}.ajax-pagination-form .ajax-pagination-btn{width:100%;padding:6px;margin-top:20px;font-weight:600;color:#0366d6;background:#fff;border:1px solid #e1e4e8;border-radius:3px}.ajax-pagination-form .ajax-pagination-btn:hover,.ajax-pagination-form .ajax-pagination-btn:focus{background-color:#f6f8fa}.ajax-pagination-form.loading .ajax-pagination-btn{text-indent:-3000px;background-color:#f6f8fa;background-image:url("/images/spinners/octocat-spinner-16px-EAF2F5.gif");background-repeat:no-repeat;background-position:center center;border-color:#d1d5da}@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-moz-min-device-pixel-ratio: 2), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx){.ajax-pagination-form.loading .ajax-pagination-btn{background-image:url("/images/spinners/octocat-spinner-32-EAF2F5.gif");background-size:16px auto}}.autocomplete-results{position:absolute;z-index:99;max-height:20em;overflow-y:auto;font-size:13px;list-style:none;background:#fff;border-radius:3px;box-shadow:0 0 5px rgba(27,31,35,0.3)}.autocomplete-item{display:block;padding:5px;overflow:hidden;font-weight:600;text-decoration:none;text-overflow:ellipsis;white-space:nowrap;cursor:pointer}.autocomplete-item:hover,.autocomplete-item[aria-selected="true"],.autocomplete-item.selected,.autocomplete-item.navigation-focus{color:#fff;text-decoration:none;background-color:#0366d6}.autocomplete-item:hover .organization-member,.autocomplete-item:hover .ldap-group-dn,.autocomplete-item[aria-selected="true"] .organization-member,.autocomplete-item[aria-selected="true"] .ldap-group-dn,.autocomplete-item.selected .organization-member,.autocomplete-item.selected .ldap-group-dn,.autocomplete-item.navigation-focus .organization-member,.autocomplete-item.navigation-focus .ldap-group-dn{color:#f6f8fa}.autocomplete-item .secondary-label{font-weight:400}.autocomplete-item .organization-member{float:right;padding-top:1px;color:#6a737d}.suggester-container{position:absolute;top:0;left:0;z-index:30;transform:translateZ(0)}.suggester{position:relative;top:0;left:0;min-width:180px;margin-top:20px;cursor:pointer;background:#fff;border:1px solid #dfe2e5;border-radius:3px;box-shadow:0 0 5px rgba(27,31,35,0.1)}.suggester ul{padding:0;margin:0;list-style:none}.suggester li{display:block;padding:5px 10px;font-weight:600;border-bottom:1px solid #dfe2e5}.suggester li small{font-weight:400;color:#586069}.suggester li:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.suggester li:first-child a{border-top-left-radius:3px;border-top-right-radius:3px}.suggester li[aria-selected="true"],.suggester li.navigation-focus{color:#fff;text-decoration:none;background:#0366d6}.suggester li[aria-selected="true"] small,.suggester li.navigation-focus small{color:#fff}.Box--overlay{width:448px;margin-right:auto;margin-left:auto;background-color:#fff;background-clip:padding-box;border-color:#444d56;box-shadow:0 0 18px rgba(0,0,0,0.4)}.Box--overlay .Box-header{margin:0;border-width:0;border-bottom-width:1px;border-top-left-radius:2px;border-top-right-radius:2px}.Box-overlay--narrow{width:320px}.Box-overlay--wide{width:640px}.Overlay{position:fixed;top:0;right:0;bottom:0;left:0;z-index:99;overflow-y:auto}.Overlay-table-full{display:table;width:100%;height:100%;table-layout:fixed}.Overlay-cell-middle{display:table-cell;width:100%;height:100%;padding:32px;vertical-align:middle}.bg-transparent-dark{background-color:rgba(0,0,0,0.5)}.transition-in-out{transition:opacity 0.2s ease-in-out}.transition-in-out[hidden]{opacity:0}.Box-body.scrollable-overlay{max-height:400px;overflow-y:scroll}.Box-body .help{padding-top:8px;margin:0;color:#586069;text-align:center}.boxed-group{position:relative;margin-bottom:30px;border-radius:3px}.boxed-group .Counter{color:#fff;background-color:rgba(47,54,61,0.5)}.boxed-group.flush .boxed-group-inner{padding:0}.boxed-group.condensed .boxed-group-inner{padding:0;font-size:12px}.boxed-group>h3,.boxed-group .heading{display:block;padding:9px 10px 10px;margin:0;font-size:14px;line-height:17px;background-color:#f6f8fa;border:1px solid rgba(27,31,35,0.15);border-bottom:0;border-radius:3px 3px 0 0}.boxed-group>h3 a,.boxed-group .heading a{color:inherit}.boxed-group>h3 a.boxed-group-breadcrumb,.boxed-group .heading a.boxed-group-breadcrumb{font-weight:400;color:#586069;text-decoration:none}.boxed-group>h3 .avatar,.boxed-group .heading .avatar{margin-top:-4px}.boxed-group .tabnav.heading{padding:0}.boxed-group .tabnav.heading .tabnav-tab.selected{border-top:0}.boxed-group .tabnav.heading li:first-child .selected{border-left-color:#fff;border-top-left-radius:3px}.boxed-group .tabnav-tab{border-top:0;border-radius:0}.boxed-group code.heading{font-size:12px}.boxed-group.dangerzone>h3{color:#fff;background-color:#d73a49;border:1px solid #9e1c23}.boxed-group.dangerzone .boxed-group-inner{border-top:0}.boxed-group.condensed>h3{padding:6px 6px 7px;font-size:12px}.boxed-group.condensed>h3 .octicon{padding:0 6px 0 2px}.one-half .boxed-group,.dashboard-sidebar .boxed-group{margin-bottom:20px}.boxed-group .bleed-flush{width:100%;padding:0 10px;margin-left:-10px}.boxed-group .compact{margin-top:10px;margin-bottom:10px}.boxed-group-inner{padding:10px;color:#586069;background:#fff;border:1px solid #d1d5da;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.boxed-group-inner .markdown-body{padding:20px 10px 10px;font-size:13px}.boxed-group-inner.markdown-body{padding-top:10px;padding-bottom:10px}.boxed-group-inner.seamless{padding:0}.boxed-group-inner .tabnav{padding-right:10px;padding-left:10px;margin-right:-10px;margin-left:-10px}.boxed-group-inner .tabnav-tab.selected{border-top:1px solid #dfe2e5}.boxed-group-inner .help{padding:1em 10px 1em 35px;margin:1em -10px -10px;clear:both;color:#586069;border-top:1px solid #dfe2e5}.boxed-group-inner .help .octicon{margin-right:5px;margin-left:-25px}.boxed-group-inner .boxed-group-list+.help{margin-top:0}.boxed-action{float:right;margin-left:10px}.boxed-group-action{position:relative;z-index:2;float:right;margin:5px 10px 0 0}.boxed-group-action.flush{margin-top:0;margin-right:0}.field-with-errors{display:inline}.compact-options{margin:-6px 0 13px}.compact-options>li{display:inline-block;margin:0 12px 0 0;font-weight:600;list-style-type:none}.compact-options>li label{float:left}.compact-options>li .spinner{display:block;float:left;width:16px;height:16px;margin-left:5px}.boxed-group-list{margin:0;list-style:none}.boxed-group-list:first-child>li:first-child{border-top:0}.boxed-group-list>li{display:block;padding:5px 10px;margin-right:-10px;margin-left:-10px;line-height:23px;border-bottom:1px solid #e1e4e8}.boxed-group-list>li:first-child{border-top:1px solid #dfe2e5}.boxed-group-list>li:last-of-type{border-bottom:0}.boxed-group-list>li.selected{background:#dcffe4}.boxed-group-list>li.approved .btn-sm,.boxed-group-list>li.rejected .btn-sm{display:none}.boxed-group-list>li.rejected a{text-decoration:line-through}.boxed-group-list>li .avatar{margin-top:-2px;margin-right:4px}.boxed-group-list>li .octicon{width:24px;margin-right:4px}.boxed-group-list>li .btn-sm{float:right;margin:-1px 0 0 10px}.boxed-group-list>li .BtnGroup{float:right}.boxed-group-list>li .BtnGroup .btn-sm{float:left}.boxed-group.flush .boxed-group-list li{width:auto;padding-right:0;padding-left:0;margin-left:0}.boxed-group-list.standalone{margin-top:-1px}.boxed-group-list.standalone>li:first-child{border-top:0}.boxed-group-standalone{margin-top:-10px;margin-bottom:-10px}.boxed-group-standalone>li:last-child{border-radius:0 0 2px 2px}.boxed-group-table{width:100%;text-align:left}.boxed-group-table tr:last-child td{border-bottom:0}.boxed-group-table th{padding:9px;background-color:#fafbfc;border-bottom:1px solid #eaecef}.boxed-group-table td{padding:9px;vertical-align:top;border-bottom:1px solid #eaecef}.ajax-error-message{position:fixed;top:-200px;left:50%;z-index:9999;display:none;width:974px;margin:0 3px;margin-left:-487px;transition:top 0.5s ease-in-out}.ajax-error-message.visible{top:0;display:block}.ajax-error-message>.octicon-alert{vertical-align:text-top}.boxed-group-warning{padding:10px 15px;margin:-10px -10px 10px;color:rgba(27,31,35,0.85);background-color:#fffbdd;border-color:rgba(27,31,35,0.15);border-style:solid;border-width:1px 0}.boxed-group-warning .btn-sm{margin:-5px 0}.boxed-group-warning:first-child{border-top:0}.breadcrumb{margin-bottom:10px;font-size:18px;color:#586069}.breadcrumb .separator::before,.breadcrumb .separator::after{content:" "}.breadcrumb strong.final-path{color:#24292e}.breadcrumb .zeroclipboard-button{display:inline-block;margin-left:5px}.breadcrumb .repo-root{font-weight:600}.breadcrumb .octicon{vertical-align:-2px}.editor-license-template,.editor-code-of-conduct-template,.editor-gitignore-template{position:relative;top:3px;display:block;float:right;font-size:14px}.editor-license-template .select-menu-git-ignore,.editor-code-of-conduct-template .select-menu-git-ignore,.editor-gitignore-template .select-menu-git-ignore{right:0}.starring-container .unstarred,.starring-container.on .starred{display:block}.starring-container.on .unstarred,.starring-container .starred{display:none}.starring-container.loading{opacity:0.5}.user-following-container .follow,.user-following-container.on .unfollow{display:inline-block}.user-following-container.on .follow,.user-following-container .unfollow{display:none}.user-following-container.loading{opacity:0.5}.members .user-following-container{float:right}.close-button{padding:0;background:transparent;border:0;outline:none}.btn-invisible{color:#0366d6;background-color:#fff;background-image:none;border:0}.btn-invisible:hover,.btn-invisible:active,.btn-invisible:focus,.btn-invisible.selected,.btn-invisible.zeroclipboard-is-hover,.btn-invisible.zeroclipboard-is-active{color:#0366d6;background:none;outline:none;box-shadow:none}.btn-octicon{display:inline-block;padding:5px;margin-left:5px;line-height:1;color:#586069;vertical-align:middle;background:transparent;border:0}.btn-octicon:hover{color:#0366d6}.btn-octicon.disabled{color:#959da5;cursor:default}.btn-octicon.disabled:hover{color:#959da5}.btn-octicon-danger:hover{color:#cb2431}.btn-states .btn-state-alternate{display:none}.btn-states:hover .btn-state-default{display:none}.btn-states:hover .btn-state-alternate{display:inline-block}.commit-ref{position:relative;display:inline-block;padding:0 5px;font:0.75em/2 "SFMono-Regular",Consolas,"Liberation Mono",Menlo,Courier,monospace;color:#274466;white-space:nowrap;background-color:#eff7ff;border-radius:3px}.commit-ref .user{color:#044289}a.commit-ref:hover{text-decoration:none;background-color:#dbedff}.capped-cards{list-style:none}.capped-cards .capped-card{float:left;width:450px}.capped-card{margin:10px;list-style:none;border:1px solid #dfe2e5;border-radius:2px}.capped-card::before{display:table;content:""}.capped-card::after{display:table;clear:both;content:""}.capped-card:nth-child(odd){margin-left:0}.capped-card:nth-child(even){margin-right:0}.capped-card h3{padding:10px;margin:0;line-height:100%;border-bottom:1px solid #eaecef}.capped-card>p{display:block;padding:0 10px 10px;margin:0;font-size:15px;line-height:100%;color:#586069;border-bottom:1px solid #eaecef}.capped-card-content{display:block;background:#f6f8fa}.capped-card-content::before{display:table;content:""}.capped-card-content::after{display:table;clear:both;content:""}.details-collapse .collapse{position:relative;display:none;height:0;overflow:hidden;transition:height 0.35s ease-in-out}.details-collapse.open .collapse{display:block;height:auto;overflow:visible}.comment .email-format{line-height:1.5}.previewable-edit .previewable-comment-form{display:none}.previewable-edit .previewable-comment-form::before{display:table;content:""}.previewable-edit .previewable-comment-form::after{display:table;clear:both;content:""}.previewable-edit .previewable-comment-form .tabnav-tabs{display:inline-block}.previewable-edit .previewable-comment-form .form-actions{float:right;margin-right:10px;margin-bottom:10px}.previewable-edit.is-comment-editing .timeline-comment-header{display:none}.is-comment-editing .previewable-comment-form{display:block}.is-comment-editing .timeline-comment-actions,.is-comment-editing .edit-comment-hide{display:none}.is-comment-loading .previewable-comment-form{opacity:0.5}.is-comment-stale .comment-form-stale{display:block}.comment-body{width:100%;padding:15px;overflow:visible;font-size:14px}.comment-body .highlight{overflow:visible !important;background-color:transparent}.comment-form-textarea{width:100%;max-width:100%;height:100px;min-height:100px;margin:0;line-height:1.6}.comment-form-textarea.dragover{border:solid 1px #0366d6}.discussion-topic-header{position:relative;padding:10px;word-wrap:break-word}.comment-form-error,.comment-form-stale{display:none;padding:15px 10px;margin:10px;color:#86181d;background-color:#ffdce0;border:1px solid rgba(27,31,35,0.15);border-radius:3px}.comment-form-error.comment-form-bottom,.comment-form-stale.comment-form-bottom{margin-bottom:10px}.email-format{line-height:1.5em !important}.email-format div{white-space:pre-wrap}.email-format .email-hidden-reply{display:none;white-space:pre-wrap}.email-format .email-hidden-reply.expanded{display:block}.email-format .email-quoted-reply,.email-format .email-signature-reply{padding:0 15px;margin:15px 0;color:#586069;border-left:4px solid #dfe2e5}.email-format .email-hidden-toggle a{display:inline-block;height:12px;padding:0 9px;font-size:12px;font-weight:600;line-height:6px;color:#444d56;text-decoration:none;vertical-align:middle;background:#dfe2e5;border-radius:1px}.email-format .email-hidden-toggle a:hover{background-color:#c6cbd1}.email-format .email-hidden-toggle a:active{color:#fff;background-color:#0366d6}.comment-email-format div{white-space:normal}.comment-email-format .email-hidden-reply{display:none;white-space:normal}.comment-email-format .email-hidden-reply.expanded{display:block}.comment-email-format blockquote,.comment-email-format p{margin:0}.blankslate.conversation-limited{padding:20px 0 10px;margin:15px}.locked-conversation .write-tab,.locked-conversation .preview-tab{color:#c6cbd1}.commit-form{position:relative;padding:15px;border:1px solid #dfe2e5;border-radius:3px}.commit-form::after,.commit-form::before{position:absolute;top:11px;right:100%;left:-16px;display:block;width:0;height:0;pointer-events:none;content:" ";border-color:transparent;border-style:solid solid outset}.commit-form::after{margin-top:1px;margin-left:2px;border-width:7px;border-right-color:#fff}.commit-form::before{border-width:8px;border-right-color:#dfe2e5}.commit-form .input-block{margin-top:10px;margin-bottom:10px}.commit-form-avatar{float:left;margin-left:-64px;border-radius:3px}.commit-form-actions::before{display:table;content:""}.commit-form-actions::after{display:table;clear:both;content:""}.commit-form-actions .BtnGroup{margin-right:5px}.commit-form-actions .check-for-fork{line-height:34px}.merge-commit-message{resize:vertical}.commit-sha{padding:0.2em 0.4em;font-size:90%;font-weight:400;background-color:#f6f8fa;border:1px solid #eaecef;border-radius:0.2em}.commit-partial-notice{margin-top:20px;margin-bottom:20px}.commit-paginate-container{float:right;margin:-5px 0 0;text-align:inherit}.commit .commit-title,.commit .commit-title a{color:#444d56}.commit .commit-title.blank,.commit .commit-title.blank a{color:rgba(27,31,35,0.3)}.commit .commit-title .issue-link{font-weight:600;color:#0366d6}.commit .sha-block,.commit .sha{font-family:"SFMono-Regular",Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:12px}.commit.open .commit-desc{display:block}.commit-link{font-weight:400;color:#0366d6}.commit-email-flash{display:inline}.commit-desc{display:none}.commit-desc pre{max-width:700px;margin-top:10px;font-family:"SFMono-Regular",Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:11px;line-height:1.45;color:#444d56;white-space:pre-wrap}.commit-desc+.commit-branches{padding-top:8px;margin-top:2px;border-top:solid 1px rgba(27,31,35,0.15)}.commit-author-section{color:#24292e}.commit-author-section span.user-mention{font-weight:400}.commit-tease{position:relative;padding:10px;margin-bottom:-1px;font-size:13px;line-height:20px;color:#586069;background-color:#f1f8ff;border:1px solid #c8e1ff;border-radius:3px;border-bottom-right-radius:0;border-bottom-left-radius:0}.commit-tease .muted-link{color:inherit}.commit-tease .loader{float:left;margin:2px 5px 0 2px}.commit-tease .message{color:inherit}.commit-tease .avatar{margin-top:-1px}.commit-tease.open .commit-desc{display:block}.branch-infobar+.commit-tease{border-top-left-radius:0;border-top-right-radius:0}.commit-tease-comments{margin-right:15px}.commit-tease-sha{display:inline-block;font-family:"SFMono-Regular",Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:90%;color:#444d56}.commit-tease-contributors{padding:5px 10px;margin:10px -10px -10px;background-color:#fff;border-top:1px solid #bedfff;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.commit-tease-contributors::before{display:table;content:""}.commit-tease-contributors::after{display:table;clear:both;content:""}.commit-tease-contributors .avatar-link{float:left;margin-right:3px}.commit-tease-contributors .loader-loading{margin:2px 5px 2px 0}.commit-tease-contributors.error .loader-loading{display:none}.commit-tease-contributors.error .loader-error{display:block}.commits-listing{position:relative;padding-bottom:20px;margin-bottom:15px}.commits-listing::before{position:absolute;top:0;bottom:0;left:14px;z-index:-1;display:block;width:2px;content:"";background-color:#eff1f3}.commits-listing .discussion-item-icon{margin-right:5px;margin-left:-1px}.commits-listing .timeline-commits{padding-left:8px;margin-bottom:20px}.commits-listing .timeline-commits:last-child{margin-bottom:0}.commits-listing-padded{padding-left:39px}.commit-group{margin-top:10px;list-style-type:none}.commit-group-title{margin-top:15px;margin-left:-31px;color:#586069}.commit-group-title .octicon-git-commit{margin-right:17px;color:#c6cbd1;background:#fff}.commits-list-item[aria-selected="true"],.commits-list-item.navigation-focus{background:#f6fbff}.commits-list-item .commit-title{margin:0;font-size:15px;font-weight:600;color:#24292e}.commits-list-item .commit-meta{margin-top:1px;font-weight:400;color:#586069}.commits-list-item .status .octicon{height:14px;line-height:14px}.commits-list-item .commit-author{color:#586069}.commits-list-item .octicon-arrow-right{margin:0 3px}.commits-list-item .btn-outline{margin-top:2px}.commits-list-item .commit-desc pre{margin-top:5px;margin-bottom:10px;color:#586069}.commits-list-item .commit-desc pre a{word-break:break-word}.commits-list-item em{padding:3px;font-style:normal;font-weight:600;background-color:rgba(255,247,140,0.5);border-radius:3px}.commit-indicator{margin-left:4px}.commit-links-cell{width:335px;text-align:right}.commit-links-group{margin-right:5px}.commits-list-item+.commits-list-item{border-top:1px solid #e1e4e8}.timeline-commits{width:100%;margin-top:5px;border-collapse:separate}.timeline-commits+.timeline-commits{margin-top:15px}.timeline-commits td{padding-top:4px;padding-right:8px;padding-bottom:4px;font-size:12px;line-height:16px;vertical-align:top;background-color:transparent}.discussion-item .timeline-commits .commit-author{display:none}.timeline-commits .author{font-weight:600;color:#444d56}.timeline-commits .commit-message{max-width:550px;min-height:0;flex-grow:2;white-space:normal}.timeline-commits .commit-message>code a{color:#444d56}.timeline-commits .commit-message>code a:hover{color:#0366d6}.timeline-commits .commit-desc pre{overflow:visible;color:#586069}.timeline-commits .hidden-text-expander .ellipsis-expander{height:13px;background-color:#eaecef}.timeline-commits .hidden-text-expander .ellipsis-expander:hover{color:#fff;background-color:#0366d6}.timeline-commits .commit-sig-status{width:60px;margin-left:auto}.timeline-commits .commit-ci-status{width:16px}.timeline-commits .commit-ci-status .octicon-primitive-dot{width:9px;margin-right:3px;margin-left:2px}.timeline-commits .commit-meta{width:50px}.commit-icon{color:#d1d5da}.commit-icon .octicon{background-color:#fff}.commit-id{color:#959da5}.commit-id:hover{color:#0366d6}.full-commit{padding:8px 8px 0;margin:10px 0;font-size:14px;background:#eaf5ff;border:1px solid rgba(27,31,35,0.15);border-radius:3px}.full-commit:first-child{margin-top:0}.full-commit .btn-outline,.full-commit .btn-outline:disabled{background-color:transparent;border-color:rgba(27,31,35,0.15)}.full-commit .btn-outline:not(:disabled):hover{color:#005cc5;border-color:#005cc5}.full-commit p.commit-title{margin:0 0 8px;font-size:18px;font-weight:600;color:#05264c}.full-commit .branches-list{display:inline;margin-right:10px;margin-left:2px;vertical-align:middle;list-style:none}.full-commit .branches-list li{display:inline-block;padding-left:3px;font-weight:600;color:#444d56}.full-commit .branches-list li::before{padding-right:6px;font-weight:400;content:"+"}.full-commit .branches-list li:first-child{padding-left:0}.full-commit .branches-list li:first-child::before{padding-right:0;content:""}.full-commit .branches-list li.loading{font-weight:400;color:#6a737d}.full-commit .branches-list li.pull-request{font-weight:400;color:#6a737d}.full-commit .branches-list li.pull-request::before{margin-left:-8px;content:""}.full-commit .branches-list li.pull-request-error{margin-bottom:-1px}.full-commit .branches-list li a{color:inherit}.full-commit .commit-meta{padding:8px;margin-right:-8px;margin-left:-8px;background:#fff;border-top:1px solid rgba(27,31,35,0.15);border-bottom-right-radius:3px;border-bottom-left-radius:3px}.full-commit .sha-block{margin-left:16px;font-size:12px;line-height:24px;color:#586069}.full-commit .sha-block>.sha{color:#444d56}.full-commit .sha-block>a{color:#444d56;text-decoration:none;border-bottom:1px dotted #c6cbd1}.full-commit .sha-block>a:hover{border-bottom:1px solid #444d56}.full-commit .commit-desc{display:block;margin:-5px 0 10px}.full-commit .commit-desc pre{max-width:100%;overflow:visible;font-size:13px;word-wrap:break-word}.branches-tag-list{display:inline;margin-right:10px;margin-left:2px;vertical-align:middle;list-style:none}.branches-tag-list .more-commit-details,.branches-tag-list.open .hidden-text-expander{display:none}.branches-tag-list.open .more-commit-details{display:inline-block}.branches-tag-list li{display:inline-block;padding-left:3px}.branches-tag-list li:first-child{padding-left:0;font-weight:600;color:#444d56}.branches-tag-list li.loading{font-weight:400;color:#6a737d}.branches-tag-list li.abbrev-tags{cursor:pointer}.branches-tag-list li a,.branches-tag-list li .ellipsis-expander{color:inherit}.branches-tag-list li .ellipsis-expander{background-color:#d3e2f4}.branches-tag-list li .ellipsis-expander:hover{background-color:#d6e2f1}.commit-branches{min-height:18px;margin-top:-6px;margin-bottom:8px;font-size:12px;color:#6a737d;vertical-align:middle}.commit-branches .octicon{vertical-align:middle}.commit-loader .loader-error{display:none;margin:0;font-size:12px;font-weight:600;color:#cb2431}.commit-loader.is-error .loader-loading{display:none}.commit-loader.is-error .loader-error{display:block}.commit-comments-heading{max-width:780px;margin-bottom:15px}.commit-comment-count{display:inline-block;margin-right:15px;margin-bottom:0}.commit-build-statuses{position:relative;display:inline-block;text-align:left}.commit-build-statuses .octicon-primitive-dot{width:10px}.commit-build-statuses.active .dropdown-menu-content{display:block}.commit-build-statuses.active .tooltipped::before,.commit-build-statuses.active .tooltipped::after{display:none}.commit-build-statuses .dropdown-menu{min-width:400px;max-width:500px;padding-top:0;padding-bottom:0}.commit-build-statuses .dropdown-menu .merge-status-list{max-height:170px;border-bottom:0}.commit-build-statuses .dropdown-menu-w,.commit-build-statuses .dropdown-menu-e{top:-11px}.commit-build-statuses .merge-status-item:last-child{border-radius:0 0 2px 2px}.dropdown-signed-commit .dropdown-menu{width:260px;margin-top:8px;font-size:13px;line-height:1.4}.dropdown-signed-commit .dropdown-menu::after{border-bottom-color:#f6f8fa}.dropdown-signed-commit .dropdown-menu-w{top:-28px;margin-top:0}.dropdown-signed-commit .dropdown-menu-w::after{border-bottom-color:transparent;border-left-color:#f6f8fa}.signed-commit-header{padding:12px;line-height:1.3;white-space:normal;border-collapse:separate;background-color:#f6f8fa;border-bottom:solid 1px #e1e4e8;border-top-left-radius:3px;border-top-right-radius:3px}.signed-commit-header .octicon-verified{color:#28a745}.signed-commit-header .octicon-unverified{color:#959da5}.signed-commit-signer{padding-right:12px;padding-left:12px;margin-top:12px;border-collapse:separate}.signed-commit-footer{padding:12px;font-size:12px;line-height:1.5}.signed-commit-cert-info{margin-bottom:6px}.signed-commit-cert-info td{vertical-align:top}.signed-commit-cert-info td:first-child{width:44px;padding-right:12px}.signed-commit-badge{display:inline-block;padding:1px 4px;font-size:10px;color:#586069;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background:none;border:solid 1px #e1e4e8;border-radius:2px}.signed-commit-badge:hover{text-decoration:none;border-color:#c6cbd1}.signed-commit-badge.verified{color:#22863a}.signed-commit-badge.verified:hover{border-color:#28a745}.signed-commit-badge-small{margin-top:-2px;margin-right:3px}.signed-commit-badge-medium{padding:3px 8px;font-size:12px;border-radius:3px}.signed-commit-badge-large{padding:6px 12px;margin-top:2px;margin-right:9px;font-size:13px;line-height:20px;border-radius:3px}.signed-commit-verified-label{color:#1e7e34;white-space:nowrap}.signed-commit-signer-name{font-size:14px;text-align:left}.signed-commit-signer-name .signer{display:block;font-weight:600;color:#24292e}.table-of-contents{margin:15px 0}.table-of-contents li{padding:7px 0;list-style-type:none}.table-of-contents li+li{border-top:1px solid #eaecef}.table-of-contents li>.octicon{margin-right:3px}.table-of-contents .toc-diff-stats{padding-left:20px;line-height:26px}.table-of-contents .toc-diff-stats .octicon{float:left;margin-top:3px;margin-left:-20px;color:#c6cbd1}.table-of-contents .toc-diff-stats .btn-link{font-weight:600}.table-of-contents .toc-diff-stats+.content{padding-top:5px}.table-of-contents .octicon-diff-removed{color:#cb2431}.table-of-contents .octicon-diff-renamed{color:#6a737d}.table-of-contents .octicon-diff-modified{color:#dbab09}.table-of-contents .octicon-diff-added{color:#28a745}.toc-select .select-menu-modal{width:420px}.toc-select .select-menu-item .css-truncate{max-width:290px}.toc-select .select-menu-item-heading,.toc-select .select-menu-item-text{color:#24292e}.toc-select .select-menu-item-icon.octicon-diff-removed{color:#cb2431}.toc-select .select-menu-item-icon.octicon-diff-renamed{color:#6a737d}.toc-select .select-menu-item-icon.octicon-diff-modified{color:#dbab09}.toc-select .select-menu-item-icon.octicon-diff-added{color:#28a745}.toc-select[aria-selected="true"] .select-menu-item-heading,.toc-select[aria-selected="true"] .select-menu-item-text,.toc-select[aria-selected="true"] .text-green,.toc-select[aria-selected="true"] .text-red,.toc-select[aria-selected="true"] .text-gray-light,.toc-select[aria-selected="true"] .octicon-diff-removed,.toc-select[aria-selected="true"] .octicon-diff-renamed,.toc-select[aria-selected="true"] .octicon-diff-modified,.toc-select[aria-selected="true"] .octicon-diff-added,.toc-select[aria-selected="true"] .diffstat,.toc-select .navigation-focus .select-menu-item-heading,.toc-select .navigation-focus .select-menu-item-text,.toc-select .navigation-focus .text-green,.toc-select .navigation-focus .text-red,.toc-select .navigation-focus .text-gray-light,.toc-select .navigation-focus .octicon-diff-removed,.toc-select .navigation-focus .octicon-diff-renamed,.toc-select .navigation-focus .octicon-diff-modified,.toc-select .navigation-focus .octicon-diff-added,.toc-select .navigation-focus .diffstat{color:#fff !important}.select-menu-item+.semantic-toc-file,.semantic-toc-symbol:not(.last-visible){overflow:visible !important}.semantic-toc-symbol:not(.last-visible)::after,.select-menu-item+.semantic-toc-file::after{position:absolute;left:0;width:100%;height:16px;pointer-events:none;content:" ";background-color:#f6f8fa;border-color:#e1e4e8;border-style:solid;border-width:1px 0}.semantic-toc-symbol:not(.last-visible){margin-bottom:16px}.semantic-toc-symbol:not(.last-visible)::after{bottom:-18px}.select-menu-item+.semantic-toc-file{margin-top:16px}.select-menu-item+.semantic-toc-file::after{top:-18px}.filterable-active .select-menu-item-nested{padding-left:16px !important;margin-left:0}.filterable-active .semantic-toc-symbol{margin-bottom:0}.filterable-active .semantic-toc-file{margin-top:0}.filterable-active .semantic-toc-symbol::after,.filterable-active .semantic-toc-file::after{display:none}.conversation-list-heading{height:0;margin:35px 0 10px;font-size:16px;font-weight:400;color:#6a737d;text-align:center;border-bottom:1px solid #dfe2e5}.conversation-list-heading .inner{position:relative;top:-10px;display:inline-block;padding:0 5px;background:#fff}.simple-conversation-list{margin:15px 0;font-size:13px;color:#6a737d}.simple-conversation-list>li{padding:11px 0 8px;margin:0;list-style-type:none;border-top:1px solid #f6f8fa}.simple-conversation-list>li:first-child{border-top:0}.simple-conversation-list>li .title{font-weight:600}.simple-conversation-list>li .num{color:#6a737d}.simple-conversation-list>li .state{padding-top:2px;padding-bottom:2px;margin-top:-3px;margin-right:3px}.simple-conversation-list>li .meta{float:right;margin-left:10px}.simple-conversation-list.varied-states>li .state{float:left;width:80px;margin-left:-90px}.copyable-terminal{position:relative;padding:10px 55px 10px 10px;background-color:#f6f8fa;border-radius:3px}.copyable-terminal-content{overflow:auto}.copyable-terminal-button{position:absolute;top:5px;right:5px}.copyable-terminal-button .zeroclipboard-button{float:right}.copyable-terminal-button .zeroclipboard-button .octicon{padding-left:1px;margin:0 auto}.Details--on .Details-content--shown{display:none !important}.Details:not(.Details--on) .Details-content--hidden{display:none !important}.Details-element[open]>summary .Details-content--closed{display:none !important}.Details-element:not([open])>summary .Details-content--open{display:none !important}.details-overlay[open]>.dropdown-item:hover{color:inherit;background:#fff}details-menu{display:block}.blob-wrapper{overflow-x:auto;overflow-y:hidden;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.blob-wrapper-embedded{max-height:240px;overflow-y:auto}.diff-table{width:100%;border-collapse:separate}.diff-table .line-comments{padding:10px;vertical-align:top;border-top:1px solid #e1e4e8}.diff-table .line-comments:first-child+.empty-cell{border-left-width:1px}.diff-table tr:not(:last-child) .line-comments{border-top:1px solid #e1e4e8;border-bottom:1px solid #e1e4e8}.blob-num{width:1%;min-width:50px;padding-right:10px;padding-left:10px;font-family:"SFMono-Regular",Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:12px;line-height:20px;color:rgba(27,31,35,0.3);text-align:right;white-space:nowrap;vertical-align:top;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.blob-num:hover{color:rgba(27,31,35,0.6)}.blob-num::before{content:attr(data-line-number)}.blob-num.non-expandable{cursor:default}.blob-num.non-expandable:hover{color:rgba(27,31,35,0.3)}.blob-code{position:relative;padding-right:10px;padding-left:10px;line-height:20px;vertical-align:top}.blob-code-inner{overflow:visible;font-family:"SFMono-Regular",Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:12px;color:#24292e;word-wrap:normal;white-space:pre}.blob-code-inner .x-first{border-top-left-radius:0.2em;border-bottom-left-radius:0.2em}.blob-code-inner .x-last{border-top-right-radius:0.2em;border-bottom-right-radius:0.2em}.blob-code-inner::before{content:" "}.blob-code-inner.highlighted{background-color:#fffbdd}.blob-code-marker-addition::before{content:"+ "}.blob-code-marker-deletion::before{content:"- "}.blob-code-marker-context::before{content:" "}.soft-wrap .diff-table{table-layout:fixed}.soft-wrap .blob-code{padding-left:18px;text-indent:-7px}.soft-wrap .blob-code-inner{word-wrap:break-word;white-space:pre-wrap}.soft-wrap .no-nl-marker{display:none}.soft-wrap .add-line-comment{margin-left:-28px}.blob-num-hunk,.blob-code-hunk,.blob-num-expandable,.blob-code-expandable{color:rgba(27,31,35,0.5);vertical-align:middle}.blob-num-hunk,.blob-num-expandable{background-color:#dbedff}.blob-code-hunk,.blob-code-expandable{padding-top:4px;padding-bottom:4px;background-color:#f1f8ff;border-width:1px 0}.blob-expanded .blob-num,.blob-expanded .blob-code{background-color:#fafbfc}.blob-expanded+tr:not(.blob-expanded) .blob-num,.blob-expanded+tr:not(.blob-expanded) .blob-code{border-top:1px solid #eaecef}.blob-expanded .blob-num-hunk{border-top:1px solid #eaecef}tr:not(.blob-expanded)+.blob-expanded .blob-num,tr:not(.blob-expanded)+.blob-expanded .blob-code{border-top:1px solid #eaecef}.blob-num-expandable{padding:0;font-size:12px;text-align:center}.blob-num-expandable .octicon{vertical-align:top}.blob-num-expandable .diff-expander{display:block;width:auto;height:auto;padding:4px 11px 4px 10px;margin-right:-1px;color:#586069;cursor:pointer}.blob-num-expandable .diff-expander:hover{color:#fff;text-shadow:none;background-color:#0366d6;border-color:#0366d6}.blob-code-addition{background-color:#e6ffed}.blob-code-addition .x{color:#24292e;background-color:#acf2bd}.blob-num-addition{background-color:#cdffd8;border-color:#bef5cb}.blob-code-deletion{background-color:#ffeef0}.blob-code-deletion .x{color:#24292e;background-color:#fdb8c0}.blob-num-deletion{background-color:#ffdce0;border-color:#fdaeb7}.selected-line.blob-code{background-color:#fffbdd}.selected-line.blob-code .x{background-color:transparent}.selected-line.blob-num{background-color:#fff5b1;border-color:#ffea7f}.add-line-comment{position:relative;z-index:5;float:left;width:22px;height:22px;margin:-2px -10px -2px -20px;line-height:21px;color:#fff;text-align:center;text-indent:0;cursor:pointer;background-color:#0366d6;background-image:linear-gradient(#0372ef, #0366d6);border-radius:3px;box-shadow:0 1px 4px rgba(27,31,35,0.15);opacity:0;transition:transform 0.1s ease-in-out;transform:scale(0.8, 0.8)}.add-line-comment:hover{transform:scale(1, 1)}.is-hovered .add-line-comment,.add-line-comment:focus{opacity:1}.add-line-comment .octicon{vertical-align:text-top;pointer-events:none}.add-line-comment.octicon-check{background:#333;opacity:1}.inline-comment-form{border:1px solid #dfe2e5;border-radius:3px}.inline-review-comment{margin-top:0 !important;margin-bottom:10px !important}.inline-review-comment .gc:first-child+tr .blob-num,.inline-review-comment .gc:first-child+tr .blob-code{padding-top:5px}.inline-review-comment tr:last-child{border-bottom-right-radius:2px;border-bottom-left-radius:2px}.inline-review-comment tr:last-child .blob-num,.inline-review-comment tr:last-child .blob-code{padding-bottom:8px}.inline-review-comment tr:last-child .blob-num:first-child,.inline-review-comment tr:last-child .blob-code:first-child{border-bottom-left-radius:2px}.inline-review-comment tr:last-child .blob-num:last-child,.inline-review-comment tr:last-child .blob-code:last-child{border-bottom-right-radius:2px}.timeline-inline-comments{width:100%;table-layout:fixed}.timeline-inline-comments .inline-comments,.show-inline-notes .inline-comments{display:table-row}.inline-comments{display:none}.inline-comments.is-collapsed{display:none}.inline-comments .line-comments.is-collapsed{visibility:hidden}.inline-comments .line-comments+.blob-num{border-left-width:1px}.inline-comments .timeline-comment{margin-bottom:10px}.inline-comments .inline-comment-form,.inline-comments .inline-comment-form-container{max-width:780px}.comment-holder{max-width:780px}.line-comments+.line-comments,.empty-cell+.line-comments{border-left:1px solid #eaecef}.inline-comment-form-container .inline-comment-form,.inline-comment-form-container.open .inline-comment-form-actions{display:none}.inline-comment-form-container .inline-comment-form-actions,.inline-comment-form-container.open .inline-comment-form{display:block}body.split-diff .container,body.split-diff .container-lg,body.full-width .container,body.full-width .container-lg{width:100%;max-width:none;padding-right:20px;padding-left:20px}body.split-diff .repository-content,body.full-width .repository-content{width:100%}body.split-diff .new-pr-form,body.full-width .new-pr-form{max-width:980px}body.split-diff .new-pr-form .discussion-sidebar,body.full-width .new-pr-form .discussion-sidebar{width:200px}.file-diff-split{table-layout:fixed}.file-diff-split .blob-code+.blob-num{border-left:1px solid #f6f8fa}.file-diff-split .blob-code-inner{word-wrap:break-word;white-space:pre-wrap}.file-diff-split .empty-cell{cursor:default;background-color:#fafbfc;border-right-color:#eaecef}.submodule-diff-stats .octicon-diff-removed{color:#cb2431}.submodule-diff-stats .octicon-diff-renamed{color:#677a85}.submodule-diff-stats .octicon-diff-modified{color:#d0b44c}.submodule-diff-stats .octicon-diff-added{color:#28a745}.BlobToolbar{left:-17px}.BlobToolbar-dropdown{margin-left:-2px}.diffstat{font-size:12px;font-weight:600;color:#586069;white-space:nowrap;cursor:default}.block-diff-deleted,.block-diff-added,.block-diff-neutral{display:inline-block;width:8px;height:8px;margin-left:1px}.block-diff-deleted,.text-red .block-diff-neutral{background-color:#cb2431}.block-diff-added,.block-diff-neutral{background-color:#2cbe4e}.block-diff-neutral{background-color:#d1d5da}.discussion-timeline{position:relative;float:left;width:760px}.discussion-timeline::before{position:absolute;top:0;bottom:0;left:79px;z-index:-1;display:block;width:2px;content:"";background-color:#e6ebf1}.discussion-timeline.team-discussion-timeline::before{bottom:24px;left:20px;z-index:auto;background-color:#e1e4e8}.discussion-timeline.team-discussion-timeline .blankslate{background:#fff}.discussion-sidebar{top:0;z-index:21;float:right;width:200px}.discussion-sidebar-item{padding-top:15px;font-size:12px;color:#586069}.discussion-sidebar-item .btn .octicon{margin-right:0}.discussion-sidebar-item+.discussion-sidebar-item{margin-top:15px;border-top:1px solid #e6ebf1}.discussion-sidebar-item .select-menu{position:relative}.discussion-sidebar-item .select-menu-modal-holder{top:25px;right:-1px;left:auto}.discussion-sidebar-heading{margin-bottom:10px;font-size:12px;line-height:16px;color:#586069}.discussion-sidebar-toggle{padding:5px 0;margin:-5px 0 5px}.discussion-sidebar-toggle .octicon{float:right;color:#c3c8cf}.discussion-sidebar-toggle:hover{color:#0366d6;text-decoration:none;cursor:pointer}.discussion-sidebar-toggle:hover .octicon{color:inherit}button.discussion-sidebar-toggle{display:block;width:100%;font-weight:600;text-align:left;background:none;border:0}.sidebar-milestone .progress-bar,.sidebar-projects .progress-bar{height:8px;margin-bottom:2px;border-radius:2px}.milestone-name{display:block;margin-top:5px;font-weight:600;color:#586069}.milestone-name .css-truncate-target{max-width:100%}.milestone-name:hover{color:#0366d6;text-decoration:none}.sidebar-assignee .css-truncate-target{max-width:110px}.sidebar-assignee .assignee{font-weight:600;color:#586069;vertical-align:middle}.sidebar-assignee .assignee:hover{color:#0366d6;text-decoration:none}.sidebar-assignee .reviewers-status-icon{width:14px}.sidebar-assignee .octicon{margin-top:2px}.sidebar-notifications{position:relative}.sidebar-notifications .thread-subscription-status{padding:0;margin:0;border:0}.sidebar-notifications .thread-subscription-status .thread-subscribe-form{display:block}.sidebar-notifications .thread-subscription-status .octicon-radio-tower{display:none}.sidebar-notifications .thread-subscription-status .reason{padding:0;margin:5px 0 0}.sidebar-notifications .thread-subscription-status .btn-sm{display:block;width:100%}.participation .participant-avatar{float:left;margin:3px 0 0 3px}.participation a{color:#586069}.participation a:hover{color:#0366d6;text-decoration:none}.participation-avatars{margin-left:-3px}.participation-avatars::before{display:table;content:""}.participation-avatars::after{display:table;clear:both;content:""}.participation-more{float:left;margin:6px 0 0;line-height:14px}.inline-comment-form .form-actions,.timeline-new-comment .form-actions{padding:0 10px 10px}.inline-comment-form::before{display:table;content:""}.inline-comment-form::after{display:table;clear:both;content:""}.inline-comment-form .tabnav-tabs{display:inline-block}.inline-comment-form .form-actions{float:right}.gh-header-actions{float:right;margin-top:3px}.gh-header-actions .btn-sm{float:left;margin-left:5px}.gh-header-actions .btn-sm .octicon{margin-right:0}.gh-header .gh-header-edit{display:none}.gh-header .gh-header-meta .base-ref{display:inline-block}.gh-header .gh-header-meta .commit-ref-dropdown{display:none}.gh-header.open .gh-header-show{display:none}.gh-header.open .gh-header-edit{display:block}.gh-header.open .gh-header-meta .base-ref{display:none}.gh-header.open .gh-header-meta .commit-ref-dropdown{display:inline-block;margin-top:-3px;margin-bottom:-1px;vertical-align:top}.gh-header-title{margin-right:150px;margin-bottom:0;font-weight:400;line-height:1.125;word-wrap:break-word}.gh-header-no-access .gh-header-title{margin-right:0}.gh-header-number{font-weight:300;color:#a3aab1;letter-spacing:-1px}.gh-header-edit::before{display:table;content:""}.gh-header-edit::after{display:table;clear:both;content:""}.gh-header-edit .edit-issue-title{float:left;width:760px;padding:7px 10px;margin-right:10px;font-size:16px;background-color:#fafbfc}.gh-header-edit .edit-issue-title:focus{background-color:#fff}.gh-header-edit .btn{float:left;padding:7px 15px}.gh-header-edit .btn-link{float:left;margin:7px 10px}.gh-header-meta{padding-bottom:20px;margin-top:8px;font-size:14px;line-height:20px;color:#586069;border-bottom:1px solid #e6ebf1}.gh-header.issue .gh-header-meta{margin-bottom:15px}.gh-header.pull .gh-header-meta{padding-bottom:0;border-bottom:0}.gh-header-meta .TableObject-item--primary{word-wrap:break-word;white-space:normal}.gh-header-meta .TableObject-item--primary .commit-ref .css-truncate-target,.gh-header-meta .TableObject-item--primary .commit-ref:hover .css-truncate-target{max-width:780px !important}.gh-header-meta .State{margin-right:8px}.gh-header-meta .avatar{float:left;margin-top:-3px;margin-right:5px}.gh-header-meta .author{font-weight:600;color:#586069}.gh-header-meta .noun{text-transform:lowercase}.tabnav-pr{margin:15px 0 20px;border-color:#e1e4e8}.tabnav-pr .tabnav-tab{position:relative;padding:9px 14px;font-size:13px;color:#586069}.tabnav-pr .tabnav-tab.selected{color:#24292e;border-color:#e1e4e8}.timeline-comment-wrapper>.timeline-comment::after,.timeline-comment-wrapper>.timeline-comment::before,.timeline-new-comment .timeline-comment::after,.timeline-new-comment .timeline-comment::before{position:absolute;top:11px;right:100%;left:-16px;display:block;width:0;height:0;pointer-events:none;content:" ";border-color:transparent;border-style:solid solid outset}.timeline-comment-wrapper>.timeline-comment::after,.timeline-new-comment .timeline-comment::after{margin-top:1px;margin-left:2px;border-width:7px;border-right-color:#f6f8fa}.timeline-comment-wrapper>.timeline-comment::before,.timeline-new-comment .timeline-comment::before{border-width:8px;border-right-color:#d1d5da}.timeline-comment-wrapper{position:relative;padding-left:60px;margin-top:15px;margin-bottom:15px;border-top:2px solid #fff;border-bottom:2px solid #fff}.timeline-comment-wrapper .timeline-comment.current-user::after,.timeline-comment-wrapper .timeline-comment.current-user::before{position:absolute;top:11px;right:100%;left:-16px;display:block;width:0;height:0;pointer-events:none;content:" ";border-color:transparent;border-style:solid solid outset}.timeline-comment-wrapper .timeline-comment.current-user::after{margin-top:1px;margin-left:2px;border-width:7px;border-right-color:#f1f8ff}.timeline-comment-wrapper .timeline-comment.current-user::before{border-width:8px;border-right-color:#c0d3eb}.timeline-comment-wrapper .timeline-comment.unread-item::after,.timeline-comment-wrapper .timeline-comment.unread-item::before{position:absolute;top:11px;right:100%;left:-16px;display:block;width:0;height:0;pointer-events:none;content:" ";border-color:transparent;border-style:solid solid outset}.timeline-comment-wrapper .timeline-comment.unread-item::after{margin-top:1px;margin-left:2px;border-width:7px;border-right-color:#fffdef}.timeline-comment-wrapper .timeline-comment.unread-item::before{border-width:8px;border-right-color:#e5d999}.timeline-comment-avatar{float:left;margin-left:-60px;border-radius:3px}.timeline-comment{position:relative;background-color:#fff;border:1px solid #d1d5da;border-radius:3px}.timeline-comment.will-transition-once{transition:border-color .65s ease-in-out}.timeline-comment.will-transition-once .timeline-comment-header{transition:background-color .65s ease,border-bottom-color .65s ease-in-out}.timeline-comment.will-transition-once .timeline-comment-label{transition:border-color .65s ease-in-out}.timeline-comment.will-transition-once::before,.timeline-comment.will-transition-once::after{transition:border-right-color .65s ease-in-out}.timeline-comment.current-user{border-color:#c0d3eb}.timeline-comment.current-user .timeline-comment-header{background-color:#f1f8ff;border-bottom-color:#c0d3eb}.timeline-comment.current-user .timeline-comment-label{border-color:#c0d3eb}.timeline-comment.current-user .previewable-comment-form .comment-form-head.tabnav{color:#c0d3eb;background-color:#f1f8ff;border-bottom-color:#c0d3eb}.timeline-comment.unread-item{border-color:#e5d999}.timeline-comment.unread-item .timeline-comment-header{background-color:#fffdef;border-bottom-color:#e5d999}.timeline-comment.unread-item .timeline-comment-label{border-color:#e5d999}.timeline-comment.unread-item .previewable-comment-form .comment-form-head.tabnav{color:#e5d999;background-color:#fffdef;border-bottom-color:#e5d999}.timeline-comment:empty{display:none}.timeline-comment .comment+.comment{border-top:1px solid #e1e4e8}.timeline-comment .comment+.comment::before,.timeline-comment .comment+.comment::after{display:none}.timeline-comment .comment+.comment .timeline-comment-header{border-top-left-radius:0;border-top-right-radius:0}.timeline-comment-group:target .timeline-comment{border-color:#2188ff;box-shadow:0 0 0 0.2em #c8e1ff}.timeline-comment-group:target .timeline-comment::before{filter:drop-shadow(-0.25em 0 0 #c8e1ff);border-right-color:#2188ff}.review-comment:target{border:1px solid #2188ff;border-radius:3px;box-shadow:0 0 0 0.2em #c8e1ff}.timeline-comment:target .review-summary{box-shadow:0 0 0 0.2em #c8e1ff}.timeline-comment:target .review-summary::before{filter:drop-shadow(0 -0.28em 0 #c8e1ff);border-bottom-color:#2188ff}.timeline-comment:target .review-summary .comment-body{border:1px solid #2188ff;border-radius:3px}.timeline-comment-header{padding-right:15px;padding-left:15px;color:#586069;background-color:#f6f8fa;border-bottom:1px solid #d1d5da;border-top-left-radius:3px;border-top-right-radius:3px}.timeline-comment-header:only-child{border-bottom:0;border-radius:3px}.timeline-comment-header .author{color:#586069}.timeline-comment-header .timestamp{color:inherit;white-space:nowrap}.timeline-comment-header .timestamp.timestamp-edited{cursor:default}.timeline-comment-header code{word-break:break-all}.comment-type-icon{color:inherit}.timeline-comment-label{float:right;padding:2px 5px;margin:8px 0 0 10px;font-size:12px;cursor:default;border:1px solid rgba(27,31,35,0.1);border-radius:3px}.timeline-comment-label-spammy{color:#cb2431;border-color:#d73a49}.timeline-comment-header-text{max-width:78%;padding-top:10px;padding-bottom:10px}.timeline-comment-header-text code a{color:#586069}.timeline-comment-actions{float:right;margin-right:-5px;margin-left:10px}.timeline-comment-actions .show-more-popover.dropdown-menu-sw{right:-6px;margin-top:-5px}.timeline-comment-action{display:inline-block;padding:10px 5px;color:inherit;opacity:0.5}.timeline-comment-action:hover,.timeline-comment-action:focus{color:#0366d6;text-decoration:none;opacity:1}.timeline-comment-action .octicon-check{height:16px;font-size:18px}.timeline-comment-action.disabled{color:#b1b7bc;cursor:default}.timeline-comment-action.disabled:hover{color:#b1b7bc}.compare-tab-comments .timeline-comment-actions{display:none}.timeline-new-comment{max-width:780px;margin-bottom:0}.timeline-new-comment .comment-form-head{margin-bottom:10px}.timeline-new-comment .previewable-comment-form .comment-body{padding:5px 5px 15px;border-bottom:1px solid #e1e4e8}.discussion-item+.discussion-item,.discussion-item-review+.discussion-item{padding-top:15px;border-top:1px solid #e6ebf1}.discussion-item+.discussion-item-review{padding-top:8px;border-top:1px solid #e6ebf1}.discussion-item{position:relative;padding-left:25px;margin:15px 0 15px 79px}.discussion-item .author{font-weight:600;color:#586069}.discussion-item .timestamp{color:inherit;white-space:nowrap}.discussion-item.open .discussion-item-details{display:block}.discussion-item.open .discussion-item-toggler-opened{display:inline}.discussion-item.open .discussion-item-toggler-closed{display:none}.discussion-item .code-owner{color:inherit}.discussion-item-details{display:none}.discussion-item-deployed{padding-top:15px;border-top:1px solid #e6ebf1}.discussion-item-toggler-opened{display:none}.discussion-item-icon{float:left;width:32px;height:32px;margin-top:-7px;margin-left:-40px;line-height:28px;color:#586069;text-align:center;background-color:#e6ebf1;border:2px solid #fff;border-radius:50%}.discussion-item-icon .octicon-pencil{font-size:14px}.discussion-item-header{min-height:30px;padding-top:5px;padding-bottom:5px;line-height:22px;color:#586069;word-wrap:break-word}.discussion-item-header .avatar{width:16px;height:16px}.discussion-item-header .discussion-item-private{vertical-align:-1px}.discussion-item-header:last-child{padding-bottom:0}.discussion-item-header .commit-ref{font-size:85%;vertical-align:baseline}.discussion-item-header .btn-outline{float:right;padding:4px 8px;margin-top:-5px;margin-left:10px}.discussion-item-body{margin-top:5px}.discussion-item-footer{font-size:12px}.discussion-item-link{color:#586069}.discussion-item-link:hover{color:#0366d6}.discussion-item-entity{font-weight:600;color:#24292e}.discussion-item-entity:hover{color:#0366d6;text-decoration:none}.discussion-item-ref-title .issue-num{font-weight:400;color:#586069}.discussion-item-ref-title .title-link{color:#24292e}.discussion-item-ref-title .title-link:hover{color:#0366d6;text-decoration:none}.discussion-item-ref-title .title-link:hover .issue-num{color:inherit}.discussion-item-context-icon{display:inline-block;margin-left:10px;line-height:22px}.discussion-item-help{color:#586069}.discussion-item-help:hover{color:#0366d6}.discussion-item-private{color:rgba(27,31,35,0.7)}.discussion-item-rollup-ref .State{margin-top:2px}.discussion-item-rollup-ref .discussion-item-context-icon{margin-top:2px}.discussion-item-reopened .discussion-item-icon,.discussion-item-review.is-approved.is-writer .discussion-item-icon{color:#fff;background-color:#2cbe4e}.discussion-item-closed .discussion-item-icon,.discussion-item-review.is-rejected.is-writer .discussion-item-icon{color:#fff;background-color:#cb2431}.discussion-item-head_ref_deleted .discussion-item-icon{padding-left:1px;color:#fff;background-color:#6a737d}.discussion-item-locked .discussion-item-icon,.discussion-item-unlocked .discussion-item-icon{color:#fff;background-color:#24292e}.discussion-item-integrations-callout .discussion-item-icon{color:#fff;background-color:#428ade}.discussion-item-integrations-callout .pull-request-integrations-dismiss{padding:4px 8px;margin:-3px 0 0 10px;color:#586069}.pull-request-integrations-title{margin:0;font-size:15px;color:#24292e}.pull-request-integrations-body{margin-top:5px;color:#586069}.discussion-item .renamed-was,.discussion-item .renamed-is{font-weight:600;color:#24292e}.discussion-commits .discussion-item-icon{padding-top:1px}.discussion-commits .discussion-item-body{margin-top:0;margin-left:-31px}.discussion-item-changes-marker{margin-bottom:0}.discussion-item-changes-marker .discussion-item-icon{color:#fff;background-color:#0366d6}.discussion-item-changes-marker+.discussion-commits{padding-top:0;margin-top:0;border-top:0}.discussion-item-changes-marker+.discussion-commits .discussion-item-icon{display:none}.new-discussion-timeline .previewable-comment-form .comment-form-head.tabnav{padding:6px 10px 0;background:#f6f8fa;border-radius:3px 3px 0 0}.new-discussion-timeline .previewable-comment-form .comment{border:0}.new-discussion-timeline .previewable-comment-form .comment-body{padding:5px 5px 15px;background-color:transparent;border-bottom:1px solid #e1e4e8}.new-discussion-timeline .previewable-comment-form .timeline-comment .timeline-comment-actions{display:none}.new-discussion-timeline .closed-banner{position:relative;height:19px;margin:15px 0 -15px;overflow:visible;background:#e6ebf1;border-bottom:15px solid #fff;border-radius:0}.new-discussion-timeline .composer .timeline-comment{margin-bottom:10px}.new-discussion-timeline .composer .timeline-comment::after{border-right-color:#fff}.new-discussion-timeline .composer .comment-form-head.tabnav{padding-top:0;background-color:#fff}.discussion-timeline-actions{background-color:#fff;border-top:2px solid #e6ebf1}.discussion-timeline-actions .merge-pr{padding-top:0;border-top:0}.discussion-timeline-actions .thread-subscription-status{margin-top:20px}.discussion-timeline-actions .thread-subscription-status .octicon-radio-tower{display:none}.discussion-item-merged .discussion-item-icon{padding-left:1px;color:#fff;background-color:#6f42c1}.discussion-item-merged.open .discussion-item-footer{display:none}.discussion-item-merged.open .discussion-item-details{margin-top:5px;margin-bottom:10px;border:1px solid #d1d5da;border-radius:3px}.discussion-item-merged.open .discussion-item-details-header{padding:12px 15px;margin-top:0;margin-bottom:0;font-size:inherit;border-top:1px solid #d1d5da}.discussion-item-merged.open .discussion-item-details-header:first-child{border-top:0}.discussion-item-merged.open .merge-status-list{max-height:370px;margin:0;border-top-color:#d1d5da}.discussion-item-merged.open .merge-status-item{padding-left:15px}.pagination-loader-container{background-color:#fff;background-image:url("/images/modules/pulls/progressive-disclosure-line@2x.png");background-repeat:repeat-x;background-position:left center;background-size:32px}.progressive-timeline-loader-container{padding-left:64px}.deployment-icon .octicon-rocket{position:relative;bottom:-1px;left:-1px}.environment-name{color:#586069}.deployment-meta{font-size:12px;color:#586069}.deployment-meta .octicon{color:#c3c8cf}.deployment-status-label{display:inline-block;padding:1px 4px;margin-top:-2px;margin-right:3px;font-size:10px;line-height:16px;color:#6a737d;vertical-align:middle;background:none;border:solid 1px #e1e4e8;border-radius:2px}.deployment-status-label.is-error,.deployment-status-label.is-failure{color:#cb2431;text-align:center}.deployment-status-label.is-active{color:#28a745}.deployment-status-label.is-pending,.deployment-status-label.is-queued,.deployment-status-label.is-in_progress{color:#b08800}.discussion-item-review{padding-left:0;margin:20px 0 20px 80px;border:0}.discussion-item-review .discussion-item{margin-left:-30px}.discussion-item-review .discussion-item-copy{max-width:460px}.discussion-item-review .discussion-item-body{margin-left:25px}.discussion-item-review .file-header{padding:2px 12px;background-color:#fafbfc;border-bottom:1px solid #d1d5da;border-top-left-radius:3px;border-top-right-radius:3px}.discussion-item-review .blob-wrapper{border-bottom-right-radius:0;border-bottom-left-radius:0}.discussion-item-review .timeline-comment{background-color:transparent;border:0}.discussion-item-review .timeline-comment::before,.discussion-item-review .timeline-comment::after{display:none}.discussion-item-review .timeline-comment .timeline-comment-header{padding-right:5px;background-color:inherit;border:0}.discussion-item-review .timeline-comment .discussion-item-icon{margin-right:8px;margin-left:-11px}.discussion-item-review .timeline-comment-avatar{margin-top:-7px;margin-left:-80px}.discussion-item-review.is-pending .form-actions{margin-right:10px;margin-bottom:5px}.discussion-item-review.is-pending .file,.discussion-item-review.is-pending .file-header,.discussion-item-review.is-pending .tabnav-tab.selected,.discussion-item-review.is-pending .comment-form-head.tabnav{border-color:#d9d0a5}.discussion-item-review.is-pending .file-header,.discussion-item-review.is-pending .comment-form-head.tabnav{background-color:#fffdef}.discussion-item-review-comment{border-bottom:1px solid #e1e4e8}.discussion-item-review-comment:last-child{border-bottom:0}.review-summary{position:relative;margin-left:-20px}.review-summary::after,.review-summary::before{position:absolute;left:11px;content:" ";border-color:transparent transparent #fff;border-style:solid;border-width:8px}.review-summary::after{top:-15px;border-bottom-color:#fff}.review-summary::before{top:-16px;border-bottom-color:#d1d5da}.discussion-item-icon-gray{background-color:#e6ebf1 !important}.dropdown{position:relative}.dropdown.active .dropdown-menu-content{display:block;pointer-events:all}.dropdown-caret{display:inline-block;width:0;height:0;vertical-align:middle;content:"";border:4px solid;border-right-color:transparent;border-bottom-color:transparent;border-left-color:transparent}.dropdown-menu{position:absolute;top:100%;left:0;z-index:100;width:160px;padding-top:5px;padding-bottom:5px;margin-top:2px;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(27,31,35,0.15);border-radius:4px;box-shadow:0 3px 12px rgba(27,31,35,0.15)}.dropdown-menu::before,.dropdown-menu::after{position:absolute;display:inline-block;content:""}.dropdown-menu::before{border:8px solid transparent;border-bottom-color:rgba(27,31,35,0.15)}.dropdown-menu::after{border:7px solid transparent;border-bottom-color:#fff}.dropdown-menu>ul{list-style:none}.dropdown-menu-no-overflow{width:auto}.dropdown-menu-no-overflow .dropdown-item{padding:4px 15px;overflow:visible;text-overflow:inherit}.dropdown-item{display:block;padding:4px 10px 4px 15px;overflow:hidden;color:#24292e;text-overflow:ellipsis;white-space:nowrap}.dropdown-item:focus,.dropdown-item:hover,.dropdown-item.zeroclipboard-is-hover{color:#fff;text-decoration:none;background-color:#0366d6;outline:none}.dropdown-item:focus>.octicon,.dropdown-item:hover>.octicon,.dropdown-item.zeroclipboard-is-hover>.octicon{color:inherit;opacity:1}.dropdown-item.btn-link{width:100%;text-align:left}.dropdown-signout{width:100%;text-align:left;background:none;border:0}.dropdown-divider{height:1px;margin:8px 1px;background-color:#e1e4e8}.dropdown-header{padding:4px 15px;font-size:12px;color:#586069}.dropdown-menu-content{display:none}.dropdown-menu-content.anim-scale-in{position:relative;z-index:100;pointer-events:none}.dropdown-menu-w{top:0;right:100%;left:auto;width:auto;margin-top:0;margin-right:10px}.dropdown-menu-w::before{top:10px;right:-16px;left:auto;border-color:transparent;border-left-color:rgba(27,31,35,0.15)}.dropdown-menu-w::after{top:11px;right:-14px;left:auto;border-color:transparent;border-left-color:#fff}.dropdown-menu-e{top:0;left:100%;width:auto;margin-top:0;margin-left:10px}.dropdown-menu-e::before{top:10px;left:-16px;border-color:transparent;border-right-color:rgba(27,31,35,0.15)}.dropdown-menu-e::after{top:11px;left:-14px;border-color:transparent;border-right-color:#fff}.dropdown-menu-ne{top:auto;bottom:100%;left:0;margin-bottom:3px}.dropdown-menu-ne::before,.dropdown-menu-ne::after{top:auto;right:auto}.dropdown-menu-ne::before{bottom:-8px;left:9px;border-top:8px solid rgba(27,31,35,0.15);border-right:8px solid transparent;border-bottom:0;border-left:8px solid transparent}.dropdown-menu-ne::after{bottom:-7px;left:10px;border-top:7px solid #fff;border-right:7px solid transparent;border-bottom:0;border-left:7px solid transparent}.dropdown-menu-s{right:50%;left:auto;transform:translateX(50%)}.dropdown-menu-s::before{top:-16px;right:50%;transform:translateX(50%)}.dropdown-menu-s::after{top:-14px;right:50%;transform:translateX(50%)}.dropdown-menu-sw{right:0;left:auto}.dropdown-menu-sw::before{top:-16px;right:9px;left:auto}.dropdown-menu-sw::after{top:-14px;right:10px;left:auto}.dropdown-menu-se::before{top:-16px;left:9px}.dropdown-menu-se::after{top:-14px;left:10px}g-emoji{font-family:"Apple Color Emoji", "Segoe UI", "Segoe UI Emoji", "Segoe UI Symbol";font-size:1.2em;font-weight:400;line-height:20px;vertical-align:middle}g-emoji img{width:1em;height:1em}body.emoji-size-boost g-emoji{margin-right:3px}@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-moz-min-device-pixel-ratio: 2), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx){body.emoji-size-boost g-emoji{margin-right:0;font-size:1.4em}}.emoji-icon{display:inline-block;width:20px;height:20px;vertical-align:middle;background-repeat:no-repeat;background-size:20px 20px}.emoji-result{display:inline-block;height:20px;font-size:18px;font-weight:400;vertical-align:middle}.facebox{position:absolute;top:0;left:0;z-index:100;padding-bottom:40px}.facebox ul{margin-bottom:15px;margin-left:25px}.facebox .suggester ul{margin:0}.facebox-popup{position:relative;background-color:#fff;background-clip:padding-box;border:1px solid rgba(27,31,35,0.25);border-radius:5px;box-shadow:0 0 18px rgba(27,31,35,0.4)}.facebox-content{width:455px;padding:15px}.facebox-content::before{display:table;content:""}.facebox-content::after{display:table;clear:both;content:""}.facebox-close{position:absolute;top:8px;right:5px;padding:10px;cursor:pointer;background-color:transparent;border:0;opacity:0.25;-webkit-appearance:none;-moz-appearance:none;appearance:none}.facebox-close:hover{opacity:1}.facebox-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.facebox-overlay-hide{z-index:-100}.facebox-overlay-active{z-index:99}.facebox-header{padding:15px;margin:-15px -15px 15px;font-size:18px;font-weight:400;border-bottom:1px solid #e1e4e8}.facebox-header:focus{outline:none}.facebox-footer{padding:10px 15px;margin:0 -15px -15px;text-align:right;background:#fafbfc;border-top:1px solid #e1e4e8;border-bottom-right-radius:5px;border-bottom-left-radius:5px}.facebox-footer .help{margin:0;color:#586069;text-align:center}.facebox-alert{padding:10px 15px;margin:-16px -15px 15px;color:#735c0f;background-color:#ffea7f;border-color:rgba(176,136,0,0.3);border-style:solid;border-width:1px 0}.keyboard-shortcuts{float:right}.keyboard-mappings{font-size:12px;color:#444d56}.keyboard-mappings th{padding-top:25px;font-size:14px;line-height:1.5;color:#24292e;text-align:left}.keyboard-mappings tbody:first-child tr:first-child th{padding-top:0}.keyboard-mappings td{padding-top:3px;padding-bottom:3px;line-height:20px;vertical-align:top}.keyboard-mappings .keys{padding-right:10px;color:#586069;text-align:right;white-space:nowrap}.linejump .linejump-input{width:340px;background-color:#fafbfc}.linejump .linejump-input,.linejump .btn{padding:10px 15px;font-size:16px}.linejump+.facebox-close{top:18px}.repo-transfer-tip{margin-bottom:0}.flash-banner{position:fixed;top:0;z-index:90;width:100%;border-top:0;border-right:0;border-left:0;border-radius:0}.signed-in-tab-flash,.signed-out-tab-flash{display:none}.stale-session-flash.is-signed-in .signed-in-tab-flash{display:inline}.stale-session-flash.is-signed-out .signed-out-tab-flash{display:inline}.org-privileges-tour-dismiss{padding:4px 8px;margin:-3px 0 0 10px;color:#586069}.footer-octicon{color:#c6cbd1}.footer-octicon:hover{color:#959da5}.page-responsive .footer .footer-octicon{display:none}@media (min-width: 1012px){.page-responsive .footer .footer-octicon{display:block}}.gollum-editor .comment-form-head.tabnav{border:1px solid #dfe2e5}.gollum-editor .gollum-editor-body{height:390px;resize:vertical}.active .gollum-editor-function-buttons{display:block !important}include-fragment,poll-include-fragment{display:block}kbd{display:inline-block;padding:3px 5px;font:11px "SFMono-Regular",Consolas,"Liberation Mono",Menlo,Courier,monospace;line-height:10px;color:#444d56;vertical-align:middle;background-color:#fafbfc;border:solid 1px #d1d5da;border-bottom-color:#c6cbd1;border-radius:3px;box-shadow:inset 0 -1px 0 #c6cbd1}.badmono{font-family:sans-serif;font-weight:600}.IssueLabel{height:20px;padding:0.15em 4px;font-size:12px;font-weight:600;line-height:15px;border-radius:2px;box-shadow:inset 0 -1px 0 rgba(27,31,35,0.12)}.IssueLabel .g-emoji{position:relative;top:-0.05em;display:inline-block;font-size:1em;line-height:1}.IssueLabel:hover{text-decoration:none}.IssueLabel--big{padding:0 8px;font-size:16px;font-weight:600;line-height:2;border-radius:3px;transition:opacity 0.2s linear}.IssueLabel--big .g-emoji{display:inline-block;margin-top:-1px}.IssueLabel--big:hover{opacity:0.85}.list-group-item{position:relative;display:block;padding:8px 10px 10px 40px;margin-bottom:-1px;border:1px solid #e1e4e8}.list-group-item::before{display:table;content:""}.list-group-item::after{display:table;clear:both;content:""}.list-group-item a:hover{text-decoration:none}.list-group-item:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.list-group-item.closed{background-color:#fafbfc}.list-group-item.selectable{padding-left:60px}.list-group-item.selected{background-color:#fffdef}.list-group-item[aria-selected="true"],.list-group-item.navigation-focus{background-color:#f1f8ff}.list-group-item .list-group-item-summary a{color:#586069}.list-group-item .list-group-item-summary a.quiet{color:#6a737d}.list-group-item .status{position:relative;top:2px;float:right;margin-right:-9px}.list-group-item .type-icon{position:relative;top:1px;width:16px;text-align:center;vertical-align:middle}.list-group-item .assignee{float:right}.list-group-item .assignee img{display:block;border-radius:2px}.list-group-item .labels{top:-2px;display:inline-block;margin-bottom:-2px;margin-left:4px}.list-group-item-name{margin:0 60px 2px 0;font-size:15px;line-height:1.3;word-wrap:break-word}.list-group-item-name .type-icon{float:left;margin-top:1px;margin-left:-24px}.list-group-item-link{color:#24292e}.closed.octicon,.reverted.octicon{color:#cb2431}.open.octicon{color:#28a745}.merged.octicon{color:#6f42c1}.list-group-item-summary{margin-top:2px}.list-group-item-summary p{margin:0 0 5px}.standalone .list-group-item-summary p{margin-bottom:0}.animated-ellipsis-container{display:inline-block;width:12px;height:12px;overflow:hidden;transform:translateZ(0)}.animated-ellipsis-container>.animated-ellipsis{display:inline-block;overflow:hidden;vertical-align:bottom;animation:ellipsis 1s infinite}@keyframes ellipsis{from{width:2px}to{width:12px}}.large-loading-area{padding:100px 0;text-align:center}.user-mention,.team-mention{font-weight:600;color:#24292e;white-space:nowrap}.pagehead{position:relative;padding-top:20px;padding-bottom:20px;margin-bottom:20px}@media (min-width: 1012px){.pagehead{border-bottom:1px solid #e1e4e8}}.pagehead.admin{background:url("/images/modules/pagehead/background-yellowhatch-v3.png") 0 0 repeat-x}.pagehead ul.pagehead-actions{position:relative;z-index:31;float:right;margin:0}.pagehead .path-divider{margin:0 0.25em}.pagehead h1{margin-top:0;margin-bottom:0;font-size:20px;font-weight:400;line-height:28px}.pagehead h1 .avatar{margin-top:-2px;margin-right:9px;margin-bottom:-2px}.pagehead .account-switcher{margin-top:-3px;margin-bottom:-3px}.pagehead .underline-nav{height:69px;margin-top:-20px;margin-bottom:-20px}.pagehead-heading{color:inherit}.pagehead-actions>li{float:left;margin:0 10px 0 0;font-size:11px;color:#24292e;list-style-type:none}.pagehead-actions>li:last-child{margin-right:0}.pagehead-actions .octicon-mute{color:#cb2431}.pagehead-actions .select-menu{position:relative}.pagehead-actions .select-menu::before{display:table;content:""}.pagehead-actions .select-menu::after{display:table;clear:both;content:""}.pagehead-actions .select-menu-modal-holder{top:100%}.pagehead-tabs-item{float:left;padding:8px 15px 11px;color:#586069;white-space:nowrap;border:solid transparent;border-width:3px 1px 1px;border-radius:3px 3px 0 0}.pagehead-tabs-item .octicon{color:rgba(27,31,35,0.3)}.pagehead-tabs-item .Counter{color:#444d56}.pagehead-tabs-item:hover{color:#24292e;text-decoration:none}.pagehead-tabs-item.selected{font-weight:600;color:#24292e;background-color:#fff;border-color:#e36209 #e1e4e8 transparent}.pagehead-tabs-item.selected>.octicon{color:inherit}.repohead.experiment-repo-nav{padding-bottom:0;background-color:#fafbfc}.repohead .repohead-details-container{margin-bottom:20px}.repohead.mirror h1,.repohead.fork h1{height:auto;margin-top:-5px;margin-bottom:15px}.repohead h1{position:relative;float:left;max-width:635px;padding-left:18px;font-size:18px;line-height:26px;color:#586069}.repohead h1.private .octicon{color:rgba(27,31,35,0.5)}.repohead h1 .octicon{position:absolute;top:0;left:0;margin-top:5px;color:#959da5}.repohead .octicon-mirror{left:-3px}.repohead .octicon-lock{top:10px}.repohead .fork-flag,.repohead .mirror-flag{display:block;font-size:11px;line-height:10px;white-space:nowrap}.reponav{position:relative;top:1px;margin-top:-5px}.reponav::before{display:table;content:""}.reponav::after{display:table;clear:both;content:""}.reponav-dropdown{position:relative;float:left}.reponav-dropdown.active .dropdown-menu-content{display:block}.reponav-item{float:left;padding:7px 15px 8px;color:#586069;white-space:nowrap;border:solid transparent;border-width:3px 1px 1px;border-radius:3px 3px 0 0}.reponav-item .octicon{color:rgba(27,31,35,0.3)}.reponav-item .Counter{color:#444d56}.reponav-item:hover,.reponav-item:focus{color:#24292e;text-decoration:none}.reponav-item.selected{color:#24292e;background-color:#fff;border-color:#e36209 #e1e4e8 transparent}.reponav-item.selected>.octicon{color:inherit}.reponav-wrapper{position:relative;z-index:2;overflow-y:hidden;background-color:#24292e}.reponav-wrapper .reponav{top:0;padding-right:8px;padding-left:8px;margin-top:0;-webkit-overflow-scrolling:touch;overflow-x:auto;color:rgba(255,255,255,0.75)}.reponav-wrapper .reponav-item{display:inline-block;float:none;padding:4px 8px 16px;color:rgba(255,255,255,0.75);border:0}.reponav-wrapper .reponav-item .Counter{color:inherit;background-color:rgba(255,255,255,0.15)}.reponav-wrapper .reponav-item.selected{font-weight:600;color:#fff;background-color:transparent;border:0}.progress-bar{display:block;height:15px;overflow:hidden;background-color:#eaecef;border-radius:3px}.progress-bar .progress{display:block;height:100%;background-color:#2cbe4e}.reverse-progress-container{position:relative;height:3px;background-color:#e1e4e8;background-image:linear-gradient(to right, #28a745, #005cc5, #3a1d6e, #cb2431, #f66a0a);background-size:100% 3px}.reverse-progress-bar{position:absolute;right:0;height:100%;background-color:#e1e4e8}.progress-bar-small{height:10px}.progress-bar-inline .progress-bar{width:100%;border-color:#e1e4e8;border-style:solid;border-width:1px;border-top:0;border-radius:0}.steps{display:table;width:100%;padding:0;margin:30px auto 0;overflow:hidden;list-style:none;border:1px solid #dfe2e5;border-radius:3px;box-shadow:0 1px 3px rgba(27,31,35,0.05)}.steps li{display:table-cell;width:33.3%;padding:10px 15px;color:#c6cbd1;cursor:default;background-color:#fafbfc;border-left:1px solid #dfe2e5}.steps li.current{color:#24292e;background-color:#fff}.steps li.current .octicon{color:#0366d6}.steps li .octicon{float:left;margin-right:15px;margin-bottom:5px}.steps li .step{display:block}.steps li:first-child{border-left:0}.steps .complete{color:#586069}.steps .complete .octicon{color:#28a745}.prose-diff .anchor{display:none}.prose-diff .show-rich-diff{color:#0366d6;text-decoration:none;cursor:pointer}.prose-diff .show-rich-diff:hover{text-decoration:underline}.prose-diff.collapsed .rich-diff-level-zero.expandable{cursor:pointer}.prose-diff.collapsed .rich-diff-level-zero.expandable .vicinity{display:block}.prose-diff.collapsed .rich-diff-level-zero.expandable .unchanged:not(.vicinity){display:none}.prose-diff.collapsed .rich-diff-level-zero.expandable .octicon{display:block;margin:20px auto;color:#d1d5da}.prose-diff.collapsed .rich-diff-level-zero.expandable:hover .octicon{color:#24292e}.prose-diff.collapsed .rich-diff-level-zero.expandable:only-child::before{font-size:18px;color:#d1d5da;content:"Sorry, no visible changes to display."}.prose-diff.collapsed .rich-diff-level-zero.expandable:only-child:hover::before{color:#24292e}.prose-diff.collapsed .rich-diff-level-zero.expandable>.removed,.prose-diff.collapsed .rich-diff-level-zero.expandable>del{display:none;text-decoration:none}.prose-diff .markdown-body{padding:30px;padding-left:15px}.prose-diff .markdown-body>ins{box-shadow:inset 4px 0 0 #2cbe4e}.prose-diff .markdown-body>del{text-decoration:none;box-shadow:inset 4px 0 0 #cb2431}.prose-diff .markdown-body>ins,.prose-diff .markdown-body>del{display:block;border-radius:0}.prose-diff .markdown-body>ins>.rich-diff-level-zero,.prose-diff .markdown-body>ins>.rich-diff-level-one,.prose-diff .markdown-body>del>.rich-diff-level-zero,.prose-diff .markdown-body>del>.rich-diff-level-one{margin-left:15px}.prose-diff .markdown-body>ins:first-child *,.prose-diff .markdown-body>del:first-child *{margin-top:0}.prose-diff .rich-diff-level-zero.added{box-shadow:inset 4px 0 0 #2cbe4e}.prose-diff .rich-diff-level-zero.removed{box-shadow:inset 4px 0 0 #cb2431}.prose-diff .rich-diff-level-zero.changed{box-shadow:inset 4px 0 0 #f9c513}.prose-diff .rich-diff-level-zero.unchanged,.prose-diff .rich-diff-level-zero.vicinity{margin-left:15px}.prose-diff .rich-diff-level-zero.added,.prose-diff .rich-diff-level-zero.removed,.prose-diff .rich-diff-level-zero.changed{display:block;border-radius:0}.prose-diff .rich-diff-level-zero.added>.rich-diff-level-one,.prose-diff .rich-diff-level-zero.removed>.rich-diff-level-one,.prose-diff .rich-diff-level-zero.changed>.rich-diff-level-one{margin-left:15px}.prose-diff .rich-diff-level-zero.added:first-child *,.prose-diff .rich-diff-level-zero.removed:first-child *,.prose-diff .rich-diff-level-zero.changed:first-child *{margin-top:0}.prose-diff :not(.changed)>:not(.github-user-ins):not(.github-user-del)>.removed,.prose-diff :not(.changed)>:not(.github-user-ins):not(.github-user-del)>del{text-decoration:none}.prose-diff .changed del,.prose-diff .changed del pre,.prose-diff .changed del code,.prose-diff .changed del>div,.prose-diff .changed .removed,.prose-diff .changed .removed pre,.prose-diff .changed .removed code,.prose-diff .changed .removed>div{color:#cb2431;text-decoration:line-through;background:#ffdce0}.prose-diff .changed ins,.prose-diff .changed ins code,.prose-diff .changed ins pre,.prose-diff .changed .added{background:#e6ffed;border-bottom:1px solid #2cbe4e}.prose-diff>.markdown-body .github-user-ins{text-decoration:underline}.prose-diff>.markdown-body .github-user-del{text-decoration:line-through}.prose-diff>.markdown-body li ul.added{background:#e6ffed}.prose-diff>.markdown-body li ul.removed{color:#cb2431;background:#ffeef0}.prose-diff>.markdown-body li ul.removed:not(.github-user-ins){text-decoration:line-through}.prose-diff>.markdown-body li.added.moved-up .octicon,.prose-diff>.markdown-body li.added.moved-down .octicon{margin-right:5px;margin-left:5px;color:#d1d5da}.prose-diff>.markdown-body li.added.moved{background:#fffdef}.prose-diff>.markdown-body li.removed.moved{display:none}.prose-diff>.markdown-body pre{padding:10px 20px}.prose-diff>.markdown-body th.changed,.prose-diff>.markdown-body td.changed{background:#fffdef;border-left-color:#dfe2e5}.prose-diff>.markdown-body :not(li.moved).removed{color:#cb2431;text-decoration:line-through;background:#ffeef0}.prose-diff>.markdown-body :not(.github-user-ins):not(li.moved).removed{text-decoration:line-through}.prose-diff>.markdown-body :not(li.moved).added,.prose-diff>.markdown-body li:not(.moved).added{background:#e6ffed}.prose-diff>.markdown-body :not(.github-user-del):not(li.moved).added li:not(.moved):not(.github-user-del).added{text-decoration:none}.prose-diff>.markdown-body li:not(.moved).removed{color:#cb2431;background:#ffeef0}.prose-diff>.markdown-body li:not(.moved):not(.github-user-ins).removed{text-decoration:line-through}.prose-diff>.markdown-body .added,.prose-diff>.markdown-body ins+.added,.prose-diff>.markdown-body ins{border-top:0;border-bottom:0}.prose-diff>.markdown-body .added:not(.github-user-del):not(.github-user-ins),.prose-diff>.markdown-body ins+.added:not(.github-user-del):not(.github-user-ins),.prose-diff>.markdown-body ins:not(.github-user-del):not(.github-user-ins){text-decoration:none}.prose-diff>.markdown-body img.added,.prose-diff>.markdown-body img.removed{border-style:solid;border-width:1px}.prose-diff>.markdown-body ins pre:not(.github-user-del):not(.github-user-ins),.prose-diff>.markdown-body ins code:not(.github-user-del):not(.github-user-ins),.prose-diff>.markdown-body ins>div:not(.github-user-del):not(.github-user-ins){text-decoration:none}.prose-diff>.markdown-body ul>ins,.prose-diff>.markdown-body ul>del{display:block;padding:0}.prose-diff>.markdown-body .added>li,.prose-diff>.markdown-body .removed>li{margin-top:0;margin-bottom:0}span.changed_tag,em.changed_tag,strong.changed_tag,b.changed_tag,i.changed_tag,code.changed_tag{border-bottom:1px dotted #6a737d;border-radius:0}a.added_href,a.changed_href,span.removed_href{border-bottom:1px dotted #6a737d;border-radius:0}.diff-view .file-type-prose .rich-diff{display:none}.diff-view .display-rich-diff .rich-diff{display:block}.diff-view .display-rich-diff .file-diff{display:none}.diff-view .display-rich-diff.has-inline-notes .show-file-notes{display:none}.protip{margin-top:20px;text-align:center}.protip code{padding:2px;background-color:#f6f8fa;border-radius:3px}.protip-callout{padding:8px 10px;margin-bottom:20px;color:#444d56;text-align:left;border:solid 1px #eaecef;border-radius:3px}.radio-group::before{display:table;content:""}.radio-group::after{display:table;clear:both;content:""}.radio-label{float:left;padding:8px 10px 8px 35px;margin-left:-1px;color:#24292e;cursor:pointer;border:1px solid #d1d5da}:checked+.radio-label{position:relative;z-index:1;border-color:#0366d6}.radio-label .octicon{padding-right:5px}.radio-label:first-of-type{margin-left:0;border-top-left-radius:3px;border-bottom-left-radius:3px}.radio-label:last-of-type{padding-right:16px;border-top-right-radius:3px;border-bottom-right-radius:3px}.radio-input{z-index:3;float:left;margin:14px -35px 0 14px}.add-reaction-btn{opacity:0;transition:opacity 0.1s ease-in-out}.add-reaction-plus-icon{margin-right:-1px}.reaction-popover-container{display:inline-block}.reaction-popover-container[open] .add-reaction-btn{opacity:1}.add-reaction-popover.dropdown-menu{width:220px}.add-reaction-popover.dropdown-menu-ne{bottom:100%;left:6px;margin-bottom:3px}.reaction-popover-form .loading-spinner{display:none;float:right}.reaction-popover-form.loading .loading-spinner{display:inline}.add-reactions-options::before{display:table;content:""}.add-reactions-options::after{display:table;clear:both;content:""}.add-reactions-options-item{float:left;width:34px;line-height:29px;transition:transform 0.15s cubic-bezier(0.2, 0, 0.13, 2);transform:scale(1)}.add-reactions-options-item:hover,.add-reactions-options-item:focus{text-decoration:none;transform:scale(1.2)}.add-reactions-options-item:active{background-color:#dbedff}.comment-reactions::before{display:table;content:""}.comment-reactions::after{display:table;clear:both;content:""}.comment-reactions .reaction-popover-container{z-index:100}.comment-reactions.has-reactions{border-top:1px solid #e1e4e8}.comment-reactions.has-reactions:hover .add-reaction-btn{opacity:1}.comment-reactions .user-has-reacted{background-color:#f1f8ff}.comment-reactions .add-reaction-btn{border-right:0}.reaction-summary-item{float:left;padding:9px 15px 7px;line-height:18px;border-right:1px solid #e1e4e8}.reaction-summary-item:hover,.reaction-summary-item:focus{text-decoration:none}.comment-reactions-options .reaction-summary-item:first-child{border-bottom-left-radius:2px}.render-container{padding:30px;line-height:0;text-align:center;background:#dfe2e5}.render-container .render-viewer{display:none;width:100%;height:100%;border:0}.render-container .octospinner{display:none}.render-container .render-viewer-error,.render-container .render-viewer-fatal,.render-container .render-viewer-invalid{display:none}.render-container.is-render-automatic .octospinner{display:inline-block}.render-container.is-render-requested .octospinner{display:inline-block}.render-container.is-render-requested.is-render-failed .render-viewer-error{display:inline-block}.render-container.is-render-requested.is-render-failed .render-viewer,.render-container.is-render-requested.is-render-failed .render-viewer-fatal,.render-container.is-render-requested.is-render-failed .render-viewer-invalid,.render-container.is-render-requested.is-render-failed .octospinner{display:none}.render-container.is-render-requested.is-render-failed-fatal .render-viewer-fatal{display:inline-block}.render-container.is-render-requested.is-render-failed-fatal .render-viewer,.render-container.is-render-requested.is-render-failed-fatal .render-viewer-error,.render-container.is-render-requested.is-render-failed-fatal .render-viewer-invalid,.render-container.is-render-requested.is-render-failed-fatal .octospinner{display:none}.render-container.is-render-requested.is-render-failed-invalid .render-viewer-invalid{display:inline-block}.render-container.is-render-requested.is-render-failed-invalid .render-viewer,.render-container.is-render-requested.is-render-failed-invalid .render-viewer-error,.render-container.is-render-requested.is-render-failed-invalid .render-viewer-fatal,.render-container.is-render-requested.is-render-failed-invalid .octospinner{display:none}.render-container.is-render-ready.is-render-requested:not(.is-render-failed){height:500px;padding:0;background:none}.render-container.is-render-ready.is-render-requested:not(.is-render-failed) .render-viewer{display:block}.render-container.is-render-ready.is-render-requested:not(.is-render-failed) .render-viewer-error,.render-container.is-render-ready.is-render-requested:not(.is-render-failed) .render-viewer-fatal,.render-container.is-render-ready.is-render-requested:not(.is-render-failed) .octospinner{display:none}.render-notice{padding:20px 15px;font-size:14px;color:#444d56;background-color:#f6f8fa;border-color:rgba(27,31,35,0.15)}.select-menu-button::after{display:inline-block;width:0;height:0;vertical-align:-2px;content:"";border:4px solid;border-right-color:transparent;border-bottom-color:transparent;border-left-color:transparent}.select-menu-button.icon-only{padding-left:7px}.select-menu-button.primary::after{border-top-color:#fff}.select-menu-button.primary::after:active{background-color:#28a745}.select-menu-button-large::after{margin-left:0.25em;border-width:0.33em}.select-menu .spinner{float:left;margin:4px 0 0 -24px}.select-menu.active .select-menu-modal-holder{display:block}.select-menu.select-menu-modal-right{position:relative}.select-menu.select-menu-modal-right .select-menu-modal-holder{right:0}.select-menu .select-menu-clear-item{display:block}.select-menu .select-menu-clear-item .octicon{color:inherit}.select-menu .select-menu-clear-item+.select-menu-no-results{display:none !important}.select-menu.is-loading .select-menu-loading-overlay{display:block}.select-menu.is-loading .select-menu-modal{min-height:200px}.select-menu.has-error .select-menu-error{display:block}.select-menu-error{display:none}.select-menu-loading-overlay{position:absolute;top:0;z-index:5;display:none;width:100%;height:100%;background-color:rgba(255,255,255,0.8);border:1px solid transparent;border-radius:5px}.select-menu-loading-overlay .octicon-octoface{position:absolute;top:50%;left:50%;margin:-16px 0 0 -16px}.select-menu-modal-holder{position:absolute;z-index:30;display:none}.select-menu-modal{position:relative;width:300px;margin-top:4px;margin-bottom:20px;overflow:hidden;font-size:12px;color:#586069;background-color:#fff;background-clip:padding-box;border:1px solid rgba(27,31,35,0.15);border-radius:3px;box-shadow:0 3px 12px rgba(27,31,35,0.15)}.select-menu-modal-narrow{width:200px}.select-menu-header,.select-menu-divider{padding:8px 10px;line-height:16px;background:#f6f8fa;border-bottom:1px solid #e1e4e8}.select-menu-header .select-menu-title,.select-menu-divider{font-weight:600;color:#24292e}.select-menu-divider{margin-top:-1px;border-top:1px solid #e1e4e8}.select-menu-header .close-button,.select-menu-header .octicon{display:block;float:right;color:#c6cbd1;cursor:pointer}.select-menu-header .close-button:hover,.select-menu-header .octicon:hover{color:#444d56}.select-menu-header:focus{outline:none}.select-menu-filters{background-color:#f6f8fa}.select-menu-text-filter{padding:10px 10px 0}.select-menu-text-filter:first-child:last-child{padding-bottom:10px;border-bottom:1px solid #dfe2e5}.select-menu-text-filter input{display:block;width:100%;max-width:100%;padding:5px;border:1px solid #dfe2e5;border-radius:3px}.select-menu-text-filter input:-ms-input-placeholder{color:#a3aab1}.select-menu-text-filter input::-ms-input-placeholder{color:#a3aab1}.select-menu-text-filter input::placeholder{color:#a3aab1}.select-menu-tabs{padding:10px 10px 0;border-bottom:1px solid #dfe2e5}.select-menu-tabs ul{position:relative;bottom:-1px}.select-menu-tabs .select-menu-tab{display:inline-block}.select-menu-tabs a,.select-menu-tabs .select-menu-tab-nav{display:inline-block;padding:4px 8px 2px;font-size:11px;font-weight:600;color:#6a737d;text-decoration:none;cursor:pointer;background:transparent;border:1px solid transparent;border-radius:3px 3px 0 0}.select-menu-tabs a:hover,.select-menu-tabs .select-menu-tab-nav:hover{color:#24292e}.select-menu-tabs a.selected,.select-menu-tabs .select-menu-tab-nav.selected{color:#24292e;background-color:#fff;border-color:#dfe2e5;border-bottom-color:#fff}.select-menu-list{position:relative;max-height:400px;overflow:auto}.select-menu-list.select-menu-tab-bucket{display:none}.select-menu-list.select-menu-tab-bucket.selected{display:block}.select-menu-list.is-showing-new-item-form .select-menu-new-item-form{display:block}.select-menu-list.is-showing-new-item-form .select-menu-no-results,.select-menu-list.is-showing-new-item-form .select-menu-clear-item{display:none}.select-menu-blankslate{padding:16px;text-align:center}.select-menu-blankslate svg{display:block;margin-right:auto;margin-bottom:9px;margin-left:auto;fill:#879099}.select-menu-blankslate h3{font-size:14px;color:#24292e}.select-menu-blankslate p{width:195px;margin-right:auto;margin-bottom:0;margin-left:auto}.select-menu-item{display:block;padding:8px 8px 8px 30px;overflow:hidden;color:inherit;cursor:pointer;border-bottom:1px solid #eaecef}.select-menu-item .select-menu-item-text .octicon-x{display:none;float:right;margin:1px 10px 0 0;opacity:0.6}.select-menu-item:hover{text-decoration:none}.select-menu-item.select-menu-item-template{display:none}.select-menu-item.disabled,.select-menu-item.disabled.selected{color:#6a737d;cursor:default}.select-menu-item.disabled .description,.select-menu-item.disabled.selected .description{color:#6a737d}.select-menu-item.disabled.opaque,.select-menu-item.disabled.selected.opaque{opacity:0.7}.select-menu-item.disabled .select-menu-item-gravatar,.select-menu-item.disabled.selected .select-menu-item-gravatar{opacity:0.5}.select-menu-item .octicon{vertical-align:middle}.select-menu-item .octicon-check,.select-menu-item input[type="radio"]:not(:checked)+.octicon-check{visibility:hidden}.select-menu-item input[type="radio"]{display:none}.select-menu-item:focus{outline:none}.select-menu-item:hover,.select-menu-item:hover.selected,.select-menu-item:hover.select-menu-action,.select-menu-item:hover .description-inline,.select-menu-item:focus,.select-menu-item:focus.selected,.select-menu-item:focus.select-menu-action,.select-menu-item:focus .description-inline,.select-menu-item.navigation-focus,.select-menu-item.navigation-focus.selected,.select-menu-item.navigation-focus.select-menu-action,.select-menu-item.navigation-focus .description-inline,.select-menu-item[aria-selected="true"],.select-menu-item[aria-selected="true"].selected,.select-menu-item[aria-selected="true"].select-menu-action,.select-menu-item[aria-selected="true"] .description-inline{color:#fff;background-color:#0366d6}.select-menu-item:hover>.octicon,.select-menu-item:hover.selected>.octicon,.select-menu-item:hover.select-menu-action>.octicon,.select-menu-item:hover .description-inline>.octicon,.select-menu-item:focus>.octicon,.select-menu-item:focus.selected>.octicon,.select-menu-item:focus.select-menu-action>.octicon,.select-menu-item:focus .description-inline>.octicon,.select-menu-item.navigation-focus>.octicon,.select-menu-item.navigation-focus.selected>.octicon,.select-menu-item.navigation-focus.select-menu-action>.octicon,.select-menu-item.navigation-focus .description-inline>.octicon,.select-menu-item[aria-selected="true"]>.octicon,.select-menu-item[aria-selected="true"].selected>.octicon,.select-menu-item[aria-selected="true"].select-menu-action>.octicon,.select-menu-item[aria-selected="true"] .description-inline>.octicon{color:#fff}.select-menu-item:hover .description,.select-menu-item:hover .description-warning,.select-menu-item:hover.selected .description,.select-menu-item:hover.selected .description-warning,.select-menu-item:hover.select-menu-action .description,.select-menu-item:hover.select-menu-action .description-warning,.select-menu-item:hover .description-inline .description,.select-menu-item:hover .description-inline .description-warning,.select-menu-item:focus .description,.select-menu-item:focus .description-warning,.select-menu-item:focus.selected .description,.select-menu-item:focus.selected .description-warning,.select-menu-item:focus.select-menu-action .description,.select-menu-item:focus.select-menu-action .description-warning,.select-menu-item:focus .description-inline .description,.select-menu-item:focus .description-inline .description-warning,.select-menu-item.navigation-focus .description,.select-menu-item.navigation-focus .description-warning,.select-menu-item.navigation-focus.selected .description,.select-menu-item.navigation-focus.selected .description-warning,.select-menu-item.navigation-focus.select-menu-action .description,.select-menu-item.navigation-focus.select-menu-action .description-warning,.select-menu-item.navigation-focus .description-inline .description,.select-menu-item.navigation-focus .description-inline .description-warning,.select-menu-item[aria-selected="true"] .description,.select-menu-item[aria-selected="true"] .description-warning,.select-menu-item[aria-selected="true"].selected .description,.select-menu-item[aria-selected="true"].selected .description-warning,.select-menu-item[aria-selected="true"].select-menu-action .description,.select-menu-item[aria-selected="true"].select-menu-action .description-warning,.select-menu-item[aria-selected="true"] .description-inline .description,.select-menu-item[aria-selected="true"] .description-inline .description-warning{color:#fff}.select-menu-item[aria-selected="true"].disabled,.select-menu-item.navigation-focus.disabled{color:rgba(255,255,255,0.5)}.select-menu-item[aria-selected="true"].disabled .description,.select-menu-item.navigation-focus.disabled .description{color:rgba(255,255,255,0.6)}.select-menu-item>.octicon-dash{display:none}.select-menu-item.indeterminate>.octicon-check{display:none}.select-menu-item.indeterminate>.octicon-dash{display:block}.select-menu-item[aria-checked="true"] .octicon-check,.select-menu-item input:checked+.octicon-check{color:inherit;visibility:visible}.select-menu-item.selected{color:#24292e}.select-menu-item.selected .description{color:#586069}.select-menu-item.selected>.octicon{color:#24292e}.select-menu-item.selected .octicon-check{color:inherit;visibility:visible}.select-menu-item.selected .select-menu-item-text .octicon-x{display:block;color:inherit}.select-menu.label-select-menu .select-menu-item:active{background-color:transparent !important}.select-menu-item a{color:inherit;text-decoration:none}.select-menu-item .hidden-select-button-text{display:none}.select-menu-item .css-truncate-target{max-width:100%}.select-menu-item-parent{pointer-events:none}.select-menu-item-parent:hover{cursor:default}.select-menu-item-parent.navigation-focus,.select-menu-item-parent.navigation-focus.selected,.select-menu-item-parent[aria-selected="true"],.select-menu-item-parent[aria-selected="true"].selected{color:#24292e;background-color:#f1f8ff}.select-menu-item-parent.navigation-focus .octicon-check,.select-menu-item-parent.navigation-focus.selected .octicon-check,.select-menu-item-parent[aria-selected="true"] .octicon-check,.select-menu-item-parent[aria-selected="true"].selected .octicon-check{color:#24292e}.select-menu-item-icon{float:left;margin-left:-20px}form.select-menu-item>div:first-child{display:none !important}.select-menu-list:last-child .select-menu-item:last-child,.select-menu-item.last-visible{border-bottom:0;border-radius:0 0 3px 3px}.select-menu-action{font-weight:400;color:#444d56}.select-menu-action>.octicon{color:inherit}.select-menu-action:hover{color:#0366d6}.select-menu-no-results{display:none;padding:9px;color:#586069;cursor:auto}.select-menu-list.filterable-empty .select-menu-no-results,.select-menu-no-results:only-child{display:block}.select-menu-button-gravatar,.select-menu-item-gravatar{width:20px;overflow:hidden;line-height:0}.select-menu-button-gravatar img,.select-menu-item-gravatar img{display:inline-block;width:20px;height:20px;border-radius:3px}.select-menu-item-gravatar{float:left;width:20px;height:20px;margin-right:8px;border-radius:2px}.select-menu-button-gravatar{float:left;margin-right:5px}.select-menu-item-text{display:block;text-align:left}.select-menu-item-text .description{display:block;max-width:265px;font-size:12px;color:#586069}.select-menu-item-text .description-inline{font-size:10px;color:#586069}.select-menu-item-text .description-warning{color:#cb2431}.select-menu-item-heading{display:block;margin-top:0;margin-bottom:0;font-size:14px;font-weight:600}.select-menu-item-heading .description{display:inline;font-weight:400}.select-menu-new-item-form{display:none}.select-menu-new-item-form .octicon{color:#0366d6}.modal-backdrop{display:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.menu-active .modal-backdrop{position:fixed;top:0;left:0;z-index:20;display:block;width:100vw;height:100vh}.authors-2 .AvatarStack{min-width:36px !important}.authors-3 .AvatarStack{min-width:46px !important}[aria-selected="true"] .AvatarStack-body,.navigation-focus .AvatarStack-body{background:#f6fbff}.commit-tease .AvatarStack-body{background:#f1f8ff}.blame-commit .AvatarStack{margin-top:3px}.unfurl{padding:0 1em;border-left:.25em solid #d1d5da}.unfurl-icon{width:15px;height:15px}.hide-unfurl{display:none}.editable-comment .hide-unfurl{display:block}body{min-width:1012px;word-wrap:break-word}.page-content{padding-top:20px}.container-sm{max-width:544px}.marketing .pagehead h1{font-size:30px}.marketing .pagehead p{margin-top:4px;margin-bottom:0;font-size:14px;color:#586069}.marketing .pagehead ul.actions{margin-top:10px}.marketing h2 .secure{float:right;padding:1px 0;font-size:11px;font-weight:600;color:#28a745;text-transform:uppercase}.marketing .questions p{font-size:14px}.marketing-section{position:relative;padding-top:80px;padding-bottom:80px;font-size:16px;line-height:1.5;text-align:center;border-bottom:1px solid #e5e5e5}.marketing-section::before{display:table;content:""}.marketing-section::after{display:table;clear:both;content:""}.marketing-section h3{font-size:21px;font-weight:400}.marketing-hero-octicon{position:relative;width:100px;height:100px;margin:0 auto 15px;text-align:center;border:solid 1px #e5e5e5;border-radius:50px}.marketing-hero-octicon .octicon{margin-top:22px;color:#0366d6}.marketing-hero-octicon .octicon-checklist{position:relative;right:-3px}.hanging-icon-list li{padding-left:25px;margin:10px 0;font-size:14px;list-style-type:none}.hanging-icon-list .octicon{float:left;margin-top:3px;margin-left:-25px;color:#586069}.hanging-icon-list .octicon-check{color:#28a745}.hanging-icon-list .octicon-x{color:#cb2431}.nonprofit-head{padding:100px 0 120px}.heart{position:absolute;top:40%;left:50%;width:12px;height:12px;margin-left:400px;background:#83d6c0;box-shadow:140px 30px 0 #efa, 120px -120px 0 #aded84, 220px -60px 0 #ded, 30px 240px 0 #ada, 60px -60px 0 #d76666, 60px -30px 0 #ff846f, 60px 0 0 #f9a7a7, 60px 30px 0 #ffc8c8, 60px 60px 0 #ffd8d8, 30px 60px 0 #baf2ca, 30px 30px 0 #98eaac, 30px 0 0 #80d896, 30px -30px 0 #6dd085, 30px -60px 0 #55be6f, 0 -60px 0 #4cc2a7, 0 -30px 0 #73d3b9, 0 30px 0 #93e3cd, 0 60px 0 #adf9e4, -30px 60px 0 #ffe1b9, -30px 30px 0 #ffd194, -30px 0 0 #ffc86f, -60px 0 0 #fd9ff0, -60px 30px 0 #ffbaf7, -60px 60px 0 #fccdf7, -180px 60px 0 #9df;transform:rotate(45deg)}.heart:first-child{margin-left:-400px;transform:rotate(-45deg),scaleX(-1)}.octo-earth{position:absolute;bottom:-150px;left:50%;margin-left:-120px;animation:rotate 20s infinite linear}@keyframes rotate{0%{transform:rotate(0)}100%{transform:rotate(-360deg)}}.btn-blurple{color:#fff;background-color:#3b41af;background-image:linear-gradient(-180deg, #6570e2 0%, #3b41af 90%)}.btn-blurple:focus,.btn-blurple.focus{box-shadow:0 0 0 0.2em rgba(101,112,226,0.4)}.btn-blurple:hover,.btn-blurple.hover{background-color:#383ea7;background-image:linear-gradient(-180deg, #5c68e0 0%, #383ea7 90%);background-position:-.5em;border-color:rgba(27,31,35,0.5)}.btn-blurple:active,.btn-blurple.selected,[open]>.btn-blurple{background-color:#3a43bb;background-image:none;border-color:rgba(27,31,35,0.5);box-shadow:inset 0 0.15em 0.3em rgba(27,31,35,0.15)}.btn-blurple:disabled,.btn-blurple.disabled{color:rgba(255,255,255,0.75);background-color:#9da0d7;background-image:none;border-color:rgba(27,31,35,0.2);box-shadow:none}.btn-blurple .Counter{color:#4350dc;background-color:#fff}.integrations-hero-octicon.marketing-hero-octicon{width:75px;height:75px;border-width:5px}.integrations-hero-octicon.marketing-hero-octicon .octicon{margin-top:15px}.marketing-blue-octicon{color:#34acbf;border-color:#34acbf}.marketing-blue-octicon .octicon{color:#34acbf}.marketing-turquoise-octicon{color:#75bbb6;border-color:#75bbb6}.marketing-turquoise-octicon .octicon{color:#75bbb6}.marketing-purple-octicon{color:#b086b7;border-color:#b086b7}.marketing-purple-octicon .octicon{color:#b086b7}.marketing-graphic{position:relative}.intgrs-dir .marketing-graphic{padding-right:0;margin:0}.intgrs-dir .footer{margin-top:40px}.intgrs-dir-section h2{margin-top:0;margin-bottom:20px;font-size:26px;font-weight:300}.intgrs-dir-intro{padding:40px 0;margin:0;text-align:left;background-image:linear-gradient(-110deg, #48227d 0%, #2f569c 100%);border-bottom:0}.pagehead+.intgrs-dir-intro{margin-top:-20px}.intgrs-dir-intro .directory-header-back{margin-top:10px;font-size:18px;color:#fff}.intgrs-dir-intro .directory-header-back:hover{color:#d7def1;text-decoration:none}.intgrs-dir-intro .directory-header-back .octicon{vertical-align:middle}.intgrs-dir-intro .directory-header-back .header-link{color:#96dad9}.intgrs-dir-intro .column{padding-right:40px;padding-left:0}.intgrs-dir-intro .directory-tag-line{margin-bottom:0;font-size:28px;font-weight:400;color:#fff}.intgrs-dir-intro .lead{margin-top:10px;margin-bottom:6px;font-size:18px;font-weight:400;color:#d7def1}.intgrs-lstng-search{display:inline-block;width:33%;margin-left:20px}.intgrs-lstng-search .subnav-search-input{width:100%}.intgrs-lstng-categories-container{display:inline-block;float:left;width:20%}.intgrs-lstng-categories-container .intgrs-lstng-categories{top:0}.intgrs-lstng-categories-container .filter-item{padding:6px 10px;margin-right:-10px;margin-left:-10px}.intgrs-lstng-container{display:inline-block;width:80%;text-align:left}.intgrs-lstng-item{position:relative;display:inline-flex;width:30.8%;font-size:14px;border:1px solid #ededed;border-radius:4px;transition:border-color 0.15s ease 0s, transform 0.15s ease 0s, box-shadow 0.15s ease 0s, color 0.15s ease 0s}.intgrs-lstng-item:hover{border-color:#51a7e8;box-shadow:0 0 5px rgba(81,167,232,0.5);transform:scale(1.05)}.intgrs-lstng-item .intgrs-lstng-logo{display:block;margin:0 auto 10px}.intgrs-lstng-item .draft-tag{position:absolute;top:-1px;left:10px}.intgrs-lstng-item-link{display:block;width:100%;height:181px;padding-top:20px}.intgrs-lstng-item-link:hover{text-decoration:none}.intgrs-lstng-item-link:hover .intgrs-lstng-item-header{color:#0366d6}.intgrs-lstng-item-header{margin:15px 10px 0;font-size:14px;font-weight:600;color:#333}.intgrs-lstng-item-description{position:relative;height:2.8em;padding:0 10px;margin-top:5px;overflow:hidden;font-size:13px;color:#586069}.intgrs-lstng-item-description::after{position:absolute;right:0;bottom:0;padding:0 15px 0 20px;color:transparent;content:"\00a0";background-image:linear-gradient(to right, rgba(255,255,255,0), #fff 80%)}.intgr-admin-link{position:relative;display:inline-block;height:25px;padding-left:23px;font-size:13px;vertical-align:middle;border:1px solid #ededed;border-radius:3px}.intgr-admin-link.draft-tag{padding-left:25px;border:0}.intgr-admin-link.draft-tag .octicon,.intgr-admin-link.draft-tag:hover .octicon{color:#fff}.intgr-admin-link.draft-tag:hover{text-decoration:none;background-color:#000}.intgr-admin-link:hover .octicon{color:#0366d6}.intgr-admin-link .octicon{position:absolute;top:3px;left:5px;color:#586069}.intgr-feat-header{position:relative;width:85%;padding:0 65px 10px;color:#d7def1}.intgr-feat-header .intgr-admin-link{border-color:rgba(215,222,241,0.6)}.intgr-feat-header .intgr-admin-link .octicon{color:#d7def1}.intgr-feat-header .intgr-admin-link:hover .octicon{color:#fff}.intgr-feat-header .marketing-hero-octicon{position:absolute;top:0;left:5px;width:50px;height:50px;border-width:3px}.intgr-feat-header .marketing-hero-octicon .octicon{margin-top:11px}.intgr-feat-header h2{margin:0;font-size:25px;line-height:50px;color:#fff}.intgr-feat-header p{max-width:580px;margin:0;font-size:18px}.integrations-breadcrumb{display:inline-block;font-weight:400;color:#8296cc}.integrations-breadcrumb-link{line-height:0;color:#d7def1}.integrations-breadcrumb-link:hover{color:#fff;text-decoration:none}.integrations-auth-wrapper{width:511px;margin:60px auto}.integrations-auth-header{font-size:20px;text-align:center}.integrations-permissions-group dt{font-size:18px;font-weight:400}.integrations-permissions-group .integrations-permission{position:relative;padding-left:22px;margin-bottom:10px;list-style-type:none}.integrations-permissions-group .integrations-permission .octicon{position:absolute;top:1px;left:0;margin-right:10px}.integrations-install-target .select-menu{vertical-align:middle}.integrations-install-target input[type=radio]{margin-right:10px}.integrations-install-target .flash{background-color:transparent}.integrations-install-target .flash-error{background-color:transparent;border:0}.integrations-install-target .octicon-lock,.integrations-install-target .octicon-repo{margin-right:3px}.integrations-install-target .octicon-lock{color:rgba(27,31,35,0.7)}.integrations-install-target .private{background-color:#fff9ea}.integrations-install-target [aria-selected="true"].private,.integrations-install-target .navigation-focus.private{background-color:#4078c0}.integrations-install-target [aria-selected="true"].octicon-lock,.integrations-install-target .navigation-focus .octicon-lock{color:inherit}.integrations-setup-note{margin:10px 0}.listgroup-item{line-height:inherit}.listgroup-item.disabled{background-color:#fafbfc}.listgroup-item.disabled .listgroup-item-title{color:#333}.integration-key-management-wrapper .integration-key-downloading{display:none}.integration-key-management-wrapper .integration-key-list{display:none}.integration-key-management-wrapper .flash-error{display:none}.integration-key-management-wrapper .blankslate{margin-bottom:30px}.integration-key-management-wrapper .action .deletable{display:none}.integration-key-management-wrapper .action .undeletable{display:block}.integration-key-management-wrapper.multi-keys .action .deletable{display:block}.integration-key-management-wrapper.multi-keys .action .undeletable{display:none}.integration-key-management-wrapper.error .flash-error{display:block}.integration-key-management-wrapper.error .integration-key{opacity:0.5}.integration-key-management-wrapper.error .action .deletable{display:none}.integration-key-management-wrapper.error .action .undeletable{display:block}.integration-key-management-wrapper.downloading .blankslate{display:none}.integration-key-management-wrapper.downloading .integration-key-downloading{display:block}.integration-key-management-wrapper.downloading .integration-key-list{display:block}.integration-key-management-wrapper.downloading .integration-key-management{display:none}.integration-key-management-wrapper.has-keys .blankslate{display:none}.integration-key-management-wrapper.has-keys .integration-key-list{display:block}.link-small{color:#767676;transition:color 500ms ease}.listgroup-item:hover .link-small{color:#0366d6}.social-callout-twitter:hover .social-callout-twitter-logo{background-image:url("/images/icons/twitter-white.png")}.social-callout-twitter-logo{display:inline-block;width:32px;height:32px;vertical-align:middle;background:url("/images/icons/twitter.png") 0 0 no-repeat;background-size:32px auto}.accessibility-error{outline:10px solid #d73a49 !important}.account-membership-form .become-a-member,.account-membership-form .already-a-member{display:none}.account-membership-form.is-member .already-a-member{display:block}.account-membership-form.is-not-member .become-a-member{display:block}.billing-plans tbody td{width:25%;vertical-align:middle}.billing-plans .current{background-color:#f2ffed}.billing-plans .name{font-size:14px;font-weight:600;color:#333}.billing-plans .coupon{font-size:12px}.billing-plans .coupon td{color:#fff;background-color:#28a745}.billing-plans .coupon .text-right{white-space:nowrap}.billing-plans .coupon.expiring td{background-color:#df6e00}.billing-plans .coupon.expiring .coupon-label::after{border-bottom-color:#df6e00}.billing-plans tbody>.selected{background-color:#fdffce}.coupon-label{position:relative;padding:9px;margin:-9px}.coupon-label::after{position:absolute;bottom:100%;left:15px;width:0;height:0;pointer-events:none;content:" ";border:solid transparent;border-width:5px;border-bottom-color:#28a745}.boxed-group-table .toggle-currency{font-size:11px;font-weight:400}.has-removed-contents{display:none}.currency-notice{margin-bottom:10px}.org-login{margin-top:-30px;margin-bottom:30px}.org-login img{width:450px;padding:1px;margin:10px -25px;border:1px solid #ccc}.plan-notice{padding:10px;margin-bottom:0;border-top:1px solid #eee}.member-list-item .member-username{display:inline}.member-list-item .member-link{display:inline}.actor-and-action{font-weight:600}.vertical-separator{margin-right:8px;margin-left:5px;border-left:1px solid gray}.audit-log-search .audit-search-form{margin-bottom:10px}.audit-log-search .audit-results-actions{margin:15px 0}.audit-log-search .audit-search-clear{margin-bottom:0}.auth-form{width:340px;margin:0 auto}.auth-form .form-group.warn .warning,.auth-form .form-group.warn .error,.auth-form .form-group.errored .warning,.auth-form .form-group.errored .error{max-width:274px}.auth-form-header{padding:10px 20px;margin:0;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.3);background-color:#829aa8;border:1px solid #768995;border-radius:3px 3px 0 0}.auth-form-header h1{font-size:16px}.auth-form-header h1 a{color:#fff}.auth-form-header .octicon{position:absolute;top:10px;right:20px;color:rgba(0,0,0,0.4);text-shadow:0 1px 0 rgba(255,255,255,0.1)}.auth-form-message{max-height:140px;padding:20px 20px 10px;overflow-y:scroll;border:1px solid #d8dee2;border-radius:3px}.auth-form-message ol,.auth-form-message ul{padding-left:inherit;margin-bottom:inherit}.auth-form-body{padding:20px;font-size:14px;background-color:#fff;border:1px solid #d8dee2;border-top:0;border-radius:0 0 3px 3px}.auth-form-body .input-block{margin-top:5px;margin-bottom:15px}.auth-form-body p{margin:10px 0}.auth-form-body ol,.auth-form-body ul{padding-left:inherit;margin-bottom:inherit}.two-factor-help{position:relative;padding:10px 10px 10px 36px;margin:60px 0 auto auto;border:1px solid #eaeaea;border-radius:3px}.two-factor-help h4{margin-top:0;margin-bottom:5px}.two-factor-help .octicon-device-mobile{position:absolute;top:10px;left:10px}.two-factor-help .octicon-key{position:absolute;left:10px}.two-factor-help ul{list-style-type:none}.u2f-send-code-spinner{position:relative;bottom:2px;display:none;vertical-align:bottom}.loading .u2f-send-code-spinner{display:inline}.u2f-login-spinner{top:2px}.u2f-auth-header{padding-bottom:10px;margin-bottom:20px;border-bottom:1px solid #eaeaea}.auth-form-body .u2f-auth-form-body{padding:0}.u2f-auth-form-body{padding:30px 30px 20px;text-align:center}.u2f-auth-form-body button{margin-top:20px}.u2f-auth-form-body .u2f-enabled{display:block}.u2f-auth-form-body .u2f-disabled{display:none}.u2f-auth-form-body.unavailable .u2f-enabled{display:none}.u2f-auth-form-body.unavailable .u2f-disabled{display:block}.u2f-auth-icon{color:#aaa}.flash.sms-error,.flash.sms-success{display:none;margin:0 0 10px}.is-sent .sms-success{display:block}.is-sent .sms-error{display:none}.is-not-sent .sms-success{display:none}.is-not-sent .sms-error{display:block}.session-authentication{background-color:#f9f9f9}.session-authentication .header-logged-out{background-color:transparent;border-bottom:0}.session-authentication .header-logo{color:#333}.session-authentication .flash{padding:15px 20px;margin:0 auto;margin-bottom:10px;font-size:13px;border-style:solid;border-width:1px;border-radius:5px}.session-authentication .flash .container{width:auto}.session-authentication .flash .flash-close{height:40px}.session-authentication .flash.is-signed-in,.session-authentication .flash.is-signed-out{width:100%;border-top:0;border-right:0;border-left:0;border-radius:0}.session-authentication .auth-form label{display:block;margin-bottom:7px}.session-authentication .auth-form .btn{margin-top:20px}.session-authentication .auth-form .u2f-error{margin-bottom:0}.session-authentication .label-link{float:right;font-size:12px}.session-authentication .auth-form-header{margin-bottom:15px;color:#333;text-align:center;text-shadow:none;background-color:transparent;border:0}.session-authentication .auth-form-header h1{font-size:24px;font-weight:300;letter-spacing:-0.5px}.session-authentication .auth-form-body{border-top:1px solid #d8dee2;border-radius:5px}.session-authentication .auth-form-body.u2f-auth-form-body{padding:20px}.session-authentication .create-account-callout{padding:15px 20px;text-align:center;border:1px solid #d8dee2;border-radius:5px}.session-authentication .two-factor-help{padding:0 0 0 20px;margin-top:20px;border:0}.session-authentication .two-factor-help .octicon-device-mobile{top:3px;left:0}.session-authentication .two-factor-help .octicon-key{top:0;left:0}.session-authentication.enterprise .header-logged-out{padding:48px 0 28px;background-color:transparent}.session-authentication.hosted .header-logged-out{padding:40px 0 20px;background-color:transparent}.cvv-hint{position:relative}.cvv-hint:hover .cvv-hint-tooltip{display:block}.cvv-hint-tooltip{position:absolute;left:-115px;z-index:1000;display:none;padding:15px;background-color:#fff;border:1px solid #d0d0d0;border-radius:3px;transform:translateX(-100%) translateY(-50%)}.credit-card{position:relative;width:250px;height:150px;padding:20px;margin-top:5px;background-color:#f5f5f5;border-radius:10px}.credit-card.amex{margin-top:15px}.credit-card.amex .title{position:relative;top:-5px;z-index:1;font-family:"Arial Black", "Arial Bold", Gadget, sans-serif;color:#6a737d;text-align:center;letter-spacing:1px;transform:scale(1.3, 1)}.credit-card.amex .card-number{position:relative;display:inline-block;margin-top:40px;font-size:15px;white-space:nowrap}.credit-card.amex .gladiator{position:absolute;top:50px;left:50%;width:70px;height:80px;margin-left:-35px;background-color:#f5f5f5;border:3px solid #fff;border-radius:50%;box-shadow:0 0 1px #aaa}.credit-card.normal .strap{height:20px;margin:-5px -20px 15px;background-color:#555}.credit-card.normal .signature{display:inline-block;width:150px;height:30px;font-family:"Brush Script MT", cursive;font-size:17px;line-height:33px;color:#767676;text-indent:10px;letter-spacing:-1px;white-space:nowrap;background-color:#fff}.credit-card .cvv{position:relative;top:-10px;left:-7px;display:inline-block;padding:2px 5px;font-family:monospace;font-size:10px;line-height:1;text-align:center;border:2px solid #f00;border-top-left-radius:20px 10px;border-top-right-radius:20px 10px;border-bottom-right-radius:20px 10px;border-bottom-left-radius:20px 10px}.credit-card .cvv span{position:absolute;right:100%;margin-right:5px;color:#586069}.credit-card .text{display:block;font-family:monospace;font-size:7px;font-weight:600;line-height:1.1;text-transform:uppercase}.billing-addon-items table input{width:5em}.billing-addon-items td{vertical-align:middle;border-bottom:0}.billing-addon-items td.fixed{width:150px}.billing-addon-items td.black{color:#000}.billing-addon-items tr{border-bottom:1px solid #eee}.billing-addon-items tr:last-child{border-bottom-width:0}.billing-addon-items tr:nth-child(even){background-color:#fafbfc}.billing-addon-items tr.total-row{color:#cb2431;background-color:#fff}.billing-addon-items .new-addon-items{margin-left:5px}.billing-addon-items .addon-cost{color:#6a737d}.billing-addon-items .discounted-original-price{color:#666}.billing-addon-items .form-submit,.billing-addon-items .payment-method{margin-left:8px}.billing-addon-items .payment-summary{margin-right:8px;margin-left:8px}.billing-credit-card .javascript-disabled-overlay{position:absolute;top:0;left:0;z-index:1;display:none;width:100%;height:100%;background-color:#fff;opacity:0.5}.billing-credit-card.disabled .javascript-disabled-overlay,.billing-credit-card.unsupported .javascript-disabled-overlay{display:block}.billing-actions{padding-bottom:10px}.billing-heres-what-appears{margin:0 0 10px}.billing-extra-box{padding-left:10px;margin:10px 0;border-left:3px solid #eee}.billing-vat-box{padding-left:10px;margin:10px 0;border-left:3px solid #eee}.billing-section .action-button{float:right;margin-bottom:5px;margin-left:10px}.billing-section .section-label{position:absolute;width:85px;font-weight:400;color:#586069;text-align:right}.billing-section .section-title{width:100px}.billing-section .section-content{margin-left:100px;color:#333}.billing-section:last-child{border-bottom:0}.billing-section .usage-bar{max-width:304px}.usage-bar{width:100%;margin:5px 0 0;background:#eee;border-radius:20px}.usage-bar.exceeded .progress{background:#d73a49}.usage-bar .progress{position:relative;max-width:100%;height:5px;background:#67d07c;border-radius:20px;transition:width 0.3s}.usage-bar .progress.no-highlight{background:#959da5}.live-update-seats-usage{margin:10px 0 5px}.billing-per-seat-callout{position:relative}.lfs-data-pack-field{margin:-6px 0}.packs-table .desc{width:1%;white-space:nowrap}.lfs-data-icon{color:#586069;text-align:center}.lfs-data-icon.dark{color:#333}.lfs-data-icon.octicon-database{margin-right:3px;margin-left:2px}.setup-wrapper .paypal-container{margin-bottom:30px}.setup-wrapper .paypal-logged-in .paypal-container{margin-bottom:10px}.payment-methods{position:relative}.payment-methods .selected-payment-method{display:none}.payment-methods .selected-payment-method::before{display:table;content:""}.payment-methods .selected-payment-method::after{display:table;clear:both;content:""}.payment-methods .selected-payment-method.active{display:block}.payment-methods .form-group dd .card-select-number{width:300px}.payment-methods .form-group dd .form-control.short.input-vat{width:300px}.payment-methods .pay-with-header{margin:5px 0}.payment-methods .pay-with-paypal .setup-creditcard-form,.payment-methods .pay-with-paypal .paypal-form-actions,.payment-methods .pay-with-paypal .terms,.payment-methods .pay-with-paypal .paypal-signed-in,.payment-methods .pay-with-paypal .paypal-down-flash,.payment-methods .pay-with-paypal .loading-paypal-spinner{display:none}.payment-methods.paypal-loading .loading-paypal-spinner{display:block}.payment-methods.paypal-down .paypal-down-flash{display:block}.payment-methods.paypal-logged-in .paypal-sign-in{display:none}.payment-methods.paypal-logged-in .setup-creditcard-form,.payment-methods.paypal-logged-in .paypal-form-actions,.payment-methods.paypal-logged-in .terms,.payment-methods.paypal-logged-in .paypal-signed-in{display:block}.payment-methods.has-paypal-account .paypal-sign-in{display:none}.payment-methods.has-paypal-account .paypal-signed-in{display:block}.paypal-label{margin:15px 0 10px;font-weight:600}.paypal-container{display:inline-block;margin-bottom:15px;vertical-align:top;background-color:#f9f9f9;border-radius:4px}.braintree-paypal-loggedin{padding:11px 16px !important;background-position:12px 50% !important;border:1px solid #ddd !important;border-radius:4px}.bt-pp-name{margin-left:20px !important}.bt-pp-email{margin-left:15px !important}.bt-pp-cancel{font-size:0 !important;line-height:1 !important;color:#a00 !important;text-decoration:none !important}.payment-history .id,.payment-history .date,.payment-history .receipt,.payment-history .status,.payment-history .amount{white-space:nowrap}.payment-history .break-all{word-break:break-all}.payment-history .receipt{text-align:center}.payment-history .currency,.payment-history .status{color:#586069}.payment-history .status-icon{width:14px;text-align:center}.payment-history .succeeded .status{color:#28a745}.payment-history .refunded,.payment-history .failed{background:#f6f8fa}.payment-history .refunded td,.payment-history .failed td{opacity:0.5}.payment-history .refunded .receipt,.payment-history .refunded .status,.payment-history .failed .receipt,.payment-history .failed .status{opacity:1}.payment-history .refunded .status{color:#6a737d}.payment-history .failed .status{color:#cb2431}.paypal-icon{margin:0 2px 0 1px;vertical-align:middle}.inline-form-action{display:inline}.boxed-group .boxed-group-content{margin:10px}.currency-container .local-currency,.currency-container .local-currency-block{display:none}.currency-container.open .local-currency{display:inline}.currency-container.open .local-currency-block{display:block}.currency-container.open .default-currency{display:none}.strong-label{display:inline-block;margin-bottom:5px;font-weight:600}.discounted-original-price{font-weight:400;color:#586069;text-decoration:line-through}.billing-manager-input{width:500px}.billing-manager-banner{padding:30px 20px;margin-bottom:30px;overflow:hidden;background:#f9f9f9;border-bottom:1px solid #eee}.billing-manager-banner .container{position:relative}.billing-manager-banner-text{margin-left:210px;font-size:14px;color:#555}.billing-manager-banner-text .btn{margin-top:8px;margin-right:8px}.billing-manager-banner-title{font-size:12px;font-weight:600;color:#586069}.billing-manager-icon{position:absolute;top:-35px;left:0;width:180px;height:180px;font-size:180px;color:#e0e0e0}.golden-ticket-banner{margin-top:30px;margin-bottom:15px;text-align:center;border-top:1px solid #e6d445}.golden-ticket{height:60px;margin-top:-30px}.golden-ticket-button{float:left;width:50%;padding:30px 20px;font-size:18px;font-weight:400}.golden-ticket-button .octicon{margin-right:10px;vertical-align:middle}.golden-ticket-button:first-child{border-radius:3px 0 0 3px}.golden-ticket-button:last-child{border-left:0;border-radius:0 3px 3px 0}.golden-ticket-confirm .setup-header{text-align:center;border:0}.seats-change-arrow{margin:0 10px}.billing-note-block{margin:15px 0}.plan-choice{position:relative;display:block;padding:15px;padding-left:40px;font-weight:400;background-color:#fafbfc;border:1px solid #e0e0e0}.plan-choice.open,.plan-choice.selected{background-color:#fff}.plan-choice--experiment{cursor:pointer;transition:transform 0.3s, box-shadow 0.3s, border-color 0.3s}.plan-choice--experiment.open,.plan-choice--experiment.selected{border-color:#d1d5da;box-shadow:0 1px 15px rgba(27,31,35,0.15);transform:scale(1.025)}.plan-choice--experiment.open .plan-choice-icon,.plan-choice--experiment.selected .plan-choice-icon{background-color:#28a745;box-shadow:0 1px 1px rgba(27,31,35,0.1)}.plan-choice--experiment.open .plan-choice-icon .octicon,.plan-choice--experiment.selected .plan-choice-icon .octicon{transform:scale(1)}.plan-choice--experiment.plan-choice--blue.open,.plan-choice--experiment.plan-choice--blue.selected{border-color:#2188ff}.plan-choice--experiment.plan-choice--blue.open .plan-choice-icon,.plan-choice--experiment.plan-choice--blue.selected .plan-choice-icon{background-color:#0366d6}.plan-choice--experiment.plan-choice--green.open,.plan-choice--experiment.plan-choice--green.selected{border-color:#34d058}.plan-choice--experiment.plan-choice--green.open .plan-choice-icon,.plan-choice--experiment.plan-choice--green.selected .plan-choice-icon{background-color:#28a745}.plan-choice--experiment.plan-choice--purple.open,.plan-choice--experiment.plan-choice--purple.selected{border-color:#8a63d2}.plan-choice--experiment.plan-choice--purple.open .plan-choice-icon,.plan-choice--experiment.plan-choice--purple.selected .plan-choice-icon{background-color:#6f42c1}.plan-choice-icon{transition:box-shadow 0.3s}.plan-choice-icon .octicon{transition:transform 0.2s;transform:scale(0.5)}.plan-choice-top{border-radius:3px 3px 0 0}.plan-choice-bottom{margin-bottom:20px;border-top:0;border-radius:0 0 3px 3px}.plan-choice-radio{position:absolute;top:18px;left:15px}.plan-choice-exp{margin-top:5px;font-size:12px;color:#6a737d}.seat-field{width:50px;margin-right:5px}.billing-form-title{font-size:16px}.billing-line-items{margin-top:10px}.billing-line-item{padding:10px 0;font-size:12px;list-style:none;border-top:1px solid #e0e0e0}.billing-line-item::before{display:table;content:""}.billing-line-item::after{display:table;clear:both;content:""}.billing-line-item-last{font-weight:600;border-top-width:3px}.line-item-value{float:right}.condensed-payment-methods .vat-field,.condensed-payment-methods .cc-field,.condensed-payment-methods .expiration-field,.condensed-payment-methods .country-field,.condensed-payment-methods .vat-field{margin-top:15px}.condensed-payment-methods .vat-field{width:100%;margin-bottom:0}.condensed-payment-methods .cc-field{width:42%}.condensed-payment-methods .expiration-field,.condensed-payment-methods .state-field{width:30%}.condensed-payment-methods .expiration-field{white-space:nowrap}.condensed-payment-methods .expiration-field .select{width:40%}.condensed-payment-methods .expiration-divider{width:20%;line-height:30px;text-align:center}.condensed-payment-methods .cvv-field,.condensed-payment-methods .postcode-field{width:28%;margin-top:15px;margin-bottom:0}.condensed-payment-methods .state-field.column,.condensed-payment-methods .postcode-field.column{margin-top:15px;margin-bottom:0}.condensed-payment-methods .country-field{width:42%}.condensed-payment-methods .state-field{width:30%}.condensed-payment-methods .is-international .country-field{width:72%}.condensed-payment-methods .is-international.no-postcodes .country-field{width:100%}.zuora-billing-section.PaymentMethod--creditcard:not(.has-removed-contents) ~ .SignUpContinueActions{display:none}.zuora-billing-section.PaymentMethod--creditcard-added ~ .SignUpContinueActions{display:block}.zuora-billing-section.PaymentMethod--paypal ~ .SignUpContinueActions{display:block}.blame-commit{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.blame-commit[data-heat="1"]{border-right:2px solid #f66a0a}.blame-commit[data-heat="2"]{border-right:2px solid rgba(246,106,10,0.9)}.blame-commit[data-heat="3"]{border-right:2px solid rgba(246,106,10,0.8)}.blame-commit[data-heat="4"]{border-right:2px solid rgba(246,106,10,0.7)}.blame-commit[data-heat="5"]{border-right:2px solid rgba(246,106,10,0.6)}.blame-commit[data-heat="6"]{border-right:2px solid rgba(246,106,10,0.5)}.blame-commit[data-heat="7"]{border-right:2px solid rgba(246,106,10,0.4)}.blame-commit[data-heat="8"]{border-right:2px solid rgba(246,106,10,0.3)}.blame-commit[data-heat="9"]{border-right:2px solid rgba(246,106,10,0.2)}.blame-commit[data-heat="10"]{border-right:2px solid rgba(246,106,10,0.1)}.heat[data-heat="1"]{background:#f66a0a}.heat[data-heat="2"]{background:rgba(246,106,10,0.9)}.heat[data-heat="3"]{background:rgba(246,106,10,0.8)}.heat[data-heat="4"]{background:rgba(246,106,10,0.7)}.heat[data-heat="5"]{background:rgba(246,106,10,0.6)}.heat[data-heat="6"]{background:rgba(246,106,10,0.5)}.heat[data-heat="7"]{background:rgba(246,106,10,0.4)}.heat[data-heat="8"]{background:rgba(246,106,10,0.3)}.heat[data-heat="9"]{background:rgba(246,106,10,0.2)}.heat[data-heat="10"]{background:rgba(246,106,10,0.1)}.blame-commit-date{font-size:11px;line-height:25px;flex-shrink:0}.blame-commit-date[data-heat="1"]{color:#c24e00}.blame-commit-date[data-heat="2"]{color:#ac571f}.blame-commit-date[data-heat="3"]{color:#a35b2c}.blame-commit-date[data-heat="4"]{color:#9a5f38}.blame-commit-date[data-heat="5"]{color:#926245}.blame-commit-date[data-heat="6"]{color:#896651}.blame-commit-date[data-heat="7"]{color:#806a5e}.blame-commit-date[data-heat="8"]{color:#776d6a}.blame-commit-date[data-heat="9"]{color:#6e7177}.blame-commit-date[data-heat="10"]{color:#6a737d}.line-age-legend .heat{width:2px;height:10px;margin:2px 1px 0}.blame-breadcrumb .css-truncate-target{max-width:680px}.blame-commit-info{width:450px;height:26px}.blame-commit-content{flex-grow:2;overflow:hidden}.blame-commit-message{text-overflow:ellipsis}.blame-commit-message .message.blank{color:rgba(27,31,35,0.3)}.blob-reblame{min-width:24px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.reblame-link{padding-top:2px;color:#d1d5da}.blame-hunk g-emoji{font-size:14px !important}.blame-hunk:hover .reblame-link{color:#6a737d}.blame-container .blame-blob-num,.blame-container .blob-code-inner{padding-top:3px;padding-bottom:3px}.blame-container .blob-code-inner{flex-grow:1}.editor-abort{display:inline;font-size:14px}.blob-interaction-bar{position:relative;background-color:#f2f2f2;border-bottom:1px solid #e5e5e5}.blob-interaction-bar::before{display:table;content:""}.blob-interaction-bar::after{display:table;clear:both;content:""}.blob-interaction-bar .octicon-search{position:absolute;top:10px;left:10px;font-size:12px;color:#586069}.blob-filter{width:100%;padding:4px 20px 5px 30px;font-size:12px;border:0;border-radius:0;outline:none}.blob-filter:focus{outline:none}.html-blob{margin-bottom:15px}.TagsearchPopover-content{width:inherit;max-width:600px}.license-summary-octicon{color:#959da5}.rule-type-permissions{color:#28a745}.rule-type-conditions{color:#0366d6}.rule-type-limitations{color:#d73a49}.check-for-fork.is-error .check-for-fork-loading{display:none}.check-for-fork.is-error .check-for-fork-error{display:inline-block}.check-for-fork-error{display:none}.commit-form-avatar{margin-left:-64px}.file-commit-form{padding-left:64px}.commit-form::after,.commit-form::before{position:absolute;top:11px;right:100%;left:-16px;display:block;width:0;height:0;pointer-events:none;content:" ";border-color:transparent;border-style:solid solid outset}.commit-form::after{margin-top:1px;margin-left:2px;border-width:7px;border-right-color:#fff}.commit-form::before{border-width:8px;border-right-color:#ddd}.quick-pull-new-branch-icon{top:9px;left:10px}.code-formatting-menu{width:260px}.merge-pr{padding-top:10px;margin:20px 0 0;border-top:1px solid #d1d5da}.merge-pr.open .merge-branch-form{display:block}.merge-pr.open .branch-action{display:none}.status-heading{margin-bottom:1px}.merge-status-list{max-height:0;padding:0;margin:15px -15px -16px -55px;overflow-y:auto;border:solid #e1e4e8;border-width:1px 0 0;transition:max-height 0.25s ease-in-out}.statuses-toggle-opened{display:none}.merge-status-item{position:relative;padding:10px 15px;background-color:#fafbfc;border-bottom:1px solid #e1e4e8}.merge-status-item:last-child{border-bottom:0}.merge-status-item .css-truncate-target{max-width:100%}.merge-status-item .dismiss-review-form{display:none}.merge-status-item.open .review-status-item{display:none !important}.merge-status-item.open .dismiss-review-form{display:block}.status-meta{color:#586069}.status-meta-file-name{padding:0.2em 0.4em;margin:0;font-size:85%;background-color:rgba(27,31,35,0.05);border-radius:3px}.status-actions{margin-left:auto}.branch-action-item-icon{float:left;margin-left:-40px}.merge-status-icon{width:30px;margin-right:12px}.merge-pr-more-commits{margin-top:10px;margin-bottom:10px;margin-left:60px;font-size:12px;color:#586069}.branch-action{padding-left:60px;margin-top:15px;margin-bottom:15px}.branch-action .merge-branch-heading{margin-bottom:4px}.branch-action-icon{float:left;width:44px;height:44px;padding:6px;margin-left:-60px;color:#fff;text-align:center;border-radius:3px}.branch-action-body{position:relative;background-color:#fff;border:1px solid #d1d5da;border-radius:3px}.branch-action-body::after,.branch-action-body::before{position:absolute;top:11px;right:100%;left:-16px;display:block;width:0;height:0;pointer-events:none;content:" ";border-color:transparent;border-style:solid solid outset}.branch-action-body::after{margin-top:1px;margin-left:2px;border-width:7px;border-right-color:#fff}.branch-action-body::before{border-width:8px;border-right-color:#d1d5da}.branch-action-body .spinner{display:block;float:left;width:32px;height:32px;margin-right:15px;background:url("/images/spinners/octocat-spinner-32.gif") no-repeat}.branch-action-body .merge-message,.branch-action-body .merge-branch-form{padding:15px;background-color:#fafbfc;border-top:1px solid #e1e4e8;border-bottom-right-radius:2px;border-bottom-left-radius:2px}.post-merge-message{padding:15px}.branch-action-item{padding:15px 15px 15px 55px;font-size:13px;line-height:1.4}.branch-action-item+.branch-action-item,.branch-action-item+.mergeability-details{border-top:1px solid #e1e4e8}.branch-action-item.open>.merge-status-list{max-height:215px;margin-bottom:-15px}.branch-action-item.open .statuses-toggle-opened{display:inline}.branch-action-item.open .statuses-toggle-closed{display:none}.branch-action-btn{margin-left:15px}.branch-action-item-simple{padding-left:15px}.branch-action-item-simple .merge-status-list{margin-left:-15px}.branch-action-item-simple .merge-status-item{padding-left:12px}.branch-action-state-clean .branch-action-icon{background-color:#2cbe4e}.branch-action-state-clean .branch-action-body{border-color:#34d058}.branch-action-state-clean .branch-action-body::before{border-right-color:#34d058}.branch-action-state-unknown .branch-action-icon,.branch-action-state-unstable .branch-action-icon{background-color:#dbab09}.branch-action-state-unknown .branch-action-body,.branch-action-state-unstable .branch-action-body{border-color:#e2cc7a}.branch-action-state-unknown .branch-action-body::before,.branch-action-state-unstable .branch-action-body::before{border-right-color:#e2cc7a}.branch-action-state-merged .branch-action-icon{background-color:#6f42c1}.branch-action-state-merged .branch-action-body{border-color:#d5c8ed}.branch-action-state-merged .branch-action-body::before{border-right-color:#d5c8ed}.branch-action-state-dirty .branch-action-icon,.branch-action-state-closed-dirty .branch-action-icon,.is-rebasing .branch-action-state-dirty-if-rebasing .branch-action-icon{background-color:#6a737d}.branch-action-state-dirty .branch-action-body,.branch-action-state-closed-dirty .branch-action-body,.is-rebasing .branch-action-state-dirty-if-rebasing .branch-action-body{border-color:#d1d5da}.branch-action-state-dirty .branch-action-body::before,.branch-action-state-closed-dirty .branch-action-body::before,.is-rebasing .branch-action-state-dirty-if-rebasing .branch-action-body::before{border-right-color:#d1d5da}.branch-action-state-error .branch-action-icon{background-color:#d73a49}.branch-action-state-error .branch-action-body{border-color:#f97583}.branch-action-state-error .branch-action-body::before{border-right-color:#f97583}@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-moz-min-device-pixel-ratio: 2), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx){.branch-action-body .spinner{background-image:url("/images/spinners/octocat-spinner-64.gif");background-size:32px 32px}}.merge-branch-form{display:none;margin:15px 0}.merge-branch-form .commit-form{border-color:#85e89d}.merge-branch-form .commit-form::before{border-right-color:#e1e4e8}.merge-branch-form.error .commit-form,.merge-branch-form.danger .commit-form{border-color:#f97583}.merge-branch-form.error .commit-form::before,.merge-branch-form.danger .commit-form::before{border-right-color:#f97583}.merge-button-matrix-merge-form .merge-branch-form{display:block}.completeness-indicator{width:30px;height:30px;text-align:center}.completeness-indicator .octicon{display:block;margin-top:7px;margin-right:auto;margin-left:auto}.completeness-indicator .octicon-alert{margin-top:6px}.completeness-indicator-success{color:#fff;background-color:#2cbe4e;border-radius:50%}.completeness-indicator-error{color:#fff;background-color:#cb2431;border-radius:50%}.completeness-indicator-problem{color:#fff;background-color:#6a737d;border-radius:50%}.pull-merging .pull-merging-error{display:none}.pull-merging.is-error .pull-merging-error{display:block}.pull-merging.is-error .merge-pr{display:none}.RecentBranches{background-color:#fffbdd;border:1px solid rgba(27,31,35,0.15);border-radius:3px}.RecentBranches-item{line-height:28px;color:#735c0f}.RecentBranches-item+.RecentBranches-item{border-top:1px solid rgba(27,31,35,0.05)}.RecentBranches-item-link{color:#735c0f}.RecentBranches-item-link.css-truncate-target{max-width:400px}.range-editor{position:relative;padding:5px 15px 5px 40px;margin-top:15px;margin-bottom:15px;background-color:#fafbfc;border:1px solid #e1e4e8;border-radius:3px}.range-editor .dots{font-size:16px}.range-editor .select-menu{position:relative;display:inline-block}.range-editor .select-menu.fork-suggester{display:none}.range-editor .branch-name{line-height:22px}.range-editor .branch .css-truncate-target,.range-editor .fork-suggester .css-truncate-target{max-width:180px}.range-editor .pre-mergability{display:inline-block;padding:5px;line-height:26px;vertical-align:middle}.range-editor .pre-mergability .octicon{vertical-align:text-bottom}.range-editor.is-cross-repo .select-menu.fork-suggester{display:inline-block}.range-editor-icon{float:left;margin-top:10px;margin-left:-25px;color:#586069}.gh-header-new-pr{margin-bottom:15px}.gh-header-new-pr .gh-header-meta{padding-bottom:0;margin-top:5px;border-bottom:0}.gh-header-new-pr .branch-name{display:inline}.compare-pr-header{display:none}.is-pr-composer-expanded .compare-show-header{display:none}.is-pr-composer-expanded .compare-pr-header{display:block}.range-cross-repo-pair{display:inline-block;padding:5px;white-space:nowrap}ul.comparison-list{width:350px;margin:25px auto 15px;font-size:14px;text-align:left;background:#fff;border:1px solid #dfe2e5;border-radius:3px}ul.comparison-list>li{padding:7px 10px;list-style-type:none;border-top:1px solid #eaecef}ul.comparison-list>li a{font-weight:600}ul.comparison-list>li em{float:right;font-style:normal;color:#586069}ul.comparison-list>li .octicon{position:relative;top:1px;color:#a3aab1}ul.comparison-list>li .css-truncate-target{max-width:200px}ul.comparison-list>li.title{font-size:12px;font-weight:600;color:#6a737d;text-transform:uppercase;background:#fafbfc;border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.branches .page-header{margin-bottom:20px}.branches .clear-search{display:none}.branches .loading-overlay{position:absolute;top:0;z-index:20;display:none;width:100%;height:100%;padding-top:50px;text-align:center;background-color:rgba(255,255,255,0.7)}.branches .loading-overlay .spinner{display:inline-block}.branches.is-search-mode .clear-search{display:inline-block}.branches.is-loading .loading-overlay{display:block}.branches .status{display:inline-block;width:16px;text-align:center}.branches .status .octicon{position:relative}.branches .status .octicon-primitive-dot{width:10px}.branches .branch-actions{position:relative;top:-4px;right:-4px;float:right}.branches .branch-actions form{display:inline}.branches .branch-actions .octicon{width:16px;text-align:center}.branch-groups{position:relative}.branch-group{width:100%;margin-bottom:20px;border-radius:3px}.branch-group::before{display:table;content:""}.branch-group::after{display:table;clear:both;content:""}.branch-group-heading{padding:6px 12px;background:#f6f8fa;border:1px solid #dfe2e5;border-bottom:0}.branch-group-heading+.branch-summary{border-top:1px solid #dfe2e5}.branch-group-heading .branch-name{color:#fff;background:#6a737d}.branch-group-name{font-weight:600;color:#586069}.branch-group-heading:first-child,.branch-summary:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.branch-group-heading:last-child,.branch-summary:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.branches-view-switcher{display:inline-block;vertical-align:middle}.branch-search{position:relative;float:right;vertical-align:middle}.branch-search .clear-search{position:absolute;top:9px;right:12px;color:#6a737d}.branch-search-field{width:250px;padding-right:25px}.no-results-message{padding:12px;color:rgba(27,31,35,0.5);text-align:center;border:1px solid #dfe2e5;border-radius:0 0 3px 3px}.branch-summary{padding:12px;color:rgba(27,31,35,0.5);border:1px solid #dfe2e5;border-bottom:0}.branch-summary:last-child{border-bottom:1px solid #dfe2e5}.branch-summary .branch-spinner{display:none;vertical-align:text-bottom}.branch-summary.loading .branch-delete-icon{display:none}.branch-summary.loading .branch-spinner{display:inline-block}.branch-summary.is-deleted .existing-branch-summary{display:none}.branch-summary.is-deleted .deleted-branch-summary{display:block}.deleted-branch-summary{display:none}.deleted-branch-summary .css-truncate-target{max-width:500px}.deleted-branch-summary .branch-name{text-decoration:line-through;opacity:0.5}.deleted-branch-summary .branch-spinner{position:relative;top:4px;right:5px;float:right}.branch-delete{display:inline-block;margin:4px 2px 0 8px;color:#cb2431}.branch-delete.disabled{color:#dfe2e5}.more-branches{display:block;width:100%;padding:6px;color:#0366d6;text-align:center;text-decoration:none;background:#eaf5ff;border:1px solid rgba(27,31,35,0.05);border-radius:0 0 3px 3px}.more-branches:hover{background:#dbedff}.more-branches .octicon{position:relative;top:1px;margin-left:5px}.branch-details{display:inline-block;width:490px;margin-right:10px}.branch-details .css-truncate-target{max-width:240px}.branch-details .octicon-shield{margin-right:2px}.branch-meta{font-size:12px;line-height:20px;color:#6a737d}.default-label{display:inline-block;width:150px;text-align:center;vertical-align:top}.default-label .sha{font-family:"SFMono-Regular",Consolas,"Liberation Mono",Menlo,Courier,monospace}.default-label .sha .ellipses{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";color:inherit}.default-label .sha .octicon{padding-right:4px}.branch-a-b-count{display:inline-block;vertical-align:middle}.branch-a-b-count .count-half{position:relative;float:left;width:90px;padding-bottom:6px;text-align:right}.branch-a-b-count .count-half:last-child{text-align:left;border-left:1px solid #959da5}.branch-a-b-count .count-value{position:relative;top:-1px;display:block;padding:0 3px;font-size:10px}.branch-a-b-count .bar{position:absolute;min-width:3px;height:4px}.branch-a-b-count .meter{position:absolute;height:4px;background-color:#c6cbd1}.branch-a-b-count .meter.zero{background-color:transparent}.branch-a-b-count .bar-behind{right:0;border-radius:3px 0 0 3px}.branch-a-b-count .bar-behind .meter{right:0;border-radius:3px 0 0 3px}.branch-a-b-count .bar-ahead{left:0;border-radius:0 3px 3px 0}.branch-a-b-count .bar-ahead .meter{border-radius:0 3px 3px 0}.branch-a-b-count .bar-ahead.even,.branch-a-b-count .bar-behind.even{min-width:2px;background:#eaecef}.businesses-toolbar .subnav-search{width:240px;margin-right:20px}body.full-width-p-0 .new-discussion-timeline{padding:0 !important;border-bottom:1px #e1e4e8 solid}body.full-width-p-0 .footer .mt-6{margin-top:0 !important;border-top:0 !important}body.full-width-p-0 .tabnav-pr .tabnav-extra{margin-right:24px}body.full-width-p-0 .tabnav-pr .tabnav-tabs{margin-left:16px}.checks-toolbar-commit-message.css-truncate{max-width:300px}.checks-index-group .octicon{vertical-align:text-top}.checks-index-item:first-child::before{position:absolute;top:0;left:0;z-index:1;width:100%;height:5px;content:" ";background-image:linear-gradient(to bottom, rgba(47,54,61,0.1) 0%, rgba(255,255,255,0) 100%)}.checks-index-item:hover{background-color:#fff !important}.checks-index-item.selected{background-color:#fff !important}.checks-index-item.selected::after{position:absolute;top:0;bottom:0;left:0;display:block;width:3px;content:" ";background-color:#e36209}.checks-index-item .css-truncate-target{max-width:220px}.checks-index-item-icon{width:16px}.selected .checks-index-label{font-weight:600;color:#24292e}.checks-summary-meta .octicon{width:16px}.checks-results-items .octicon-fold{display:none}.checks-results-items .Details--on .octicon-fold{display:inline-block}.checks-results-items .Details--on .octicon-unfold{display:none}.check-annotation{border-left:0;border-top-left-radius:0;border-bottom-left-radius:0}.check-annotation::after{position:absolute;top:-1px;bottom:-1px;left:0;display:block;width:4px;content:" "}.check-annotation .annotation-actions{top:4px;right:8px}.check-annotation .annotation-octicon{width:16px}.check-annotation.Details--on .Details-content--hidden{display:block !important}.diff-table .check-annotation{max-width:962px}.annotation-title{word-break:break-all}.check-annotation-failure::after{background-color:#d73a49}.check-annotation-failure .annotation-title{color:#d73a49}.check-annotation-warning::after{background-color:#ffd33d}.check-annotation-warning .octicon-alert{color:#dbab09}.check-annotation-warning .annotation-title{color:#b08800}.check-annotation-notice::after{background-color:#6a737d}.check-annotation-notice .annotation-title{color:#6a737d}.neutral-check{color:#959da5}.code-frequency .addition{fill:#2cbe4e;fill-opacity:1}.code-frequency .deletion{fill:#cb2431;fill-opacity:1}.cadd{font-weight:600;color:#28a745}.cdel{font-weight:600;color:#cb2431}.code-list .file-box{border:1px #e1e4e8 solid;border-radius:3px}.code-list em{padding:2px;margin:0 -2px;font-style:normal;font-weight:600;color:#24292e;background-color:rgba(255,255,140,0.5);border-radius:3px}.code-list .title{min-height:24px;margin:-3px 0 10px 38px;font-weight:600;line-height:1.2}.code-list .repo-specific .title,.code-list .repo-specific .full-path{margin-left:0}.code-list .match-count,.code-list .updated-at{margin:0;font-weight:400}.code-list .language{float:right;margin-left:10px;font-size:12px;color:rgba(51,51,51,0.75)}.code-list .avatar{float:left}.code-list .code-list-item+.code-list-item{border-top:1px solid #eee}.code-list .blob-num{padding:0}.code-list .blob-num::before{content:normal}.code-list .blob-num a{padding:0 10px;color:inherit}.code-list .blob-num a:hover{color:#0366d6}.code-list .blob-code{white-space:pre-wrap}.code-list .divider .blob-num,.code-list .divider .blob-code{padding-top:0;padding-bottom:0;cursor:default;background-color:#f8fafd}.code-list .divider .blob-num{height:18px;padding:0 10px;line-height:15px;background-color:#f0f5fa}.code-list .full-path{margin:0 0 0 40px}.code-list .full-path .octicon-repo{color:#586069}.code-list .full-path .octicon-lock{color:#e9dba4}.code-list .full-path a{color:#6a737d}.code-list-item-private .file-box{border:1px solid #fadda5}.code-list-item-private .blob-num{background-color:#fffdef;border-right:1px solid #fadda5}.code-list-item-private .blob-num a{color:rgba(27,31,35,0.7)}.code-list-item-private .divider .blob-num,.code-list-item-private .divider .blob-code{color:rgba(27,31,35,0.7);background-color:#fffdef}.codesearch-head.pagehead h1{width:250px;line-height:33px}.search-autocomplete-dropdown{min-width:240px}.search-autocomplete-dropdown .autocomplete-category-heading::after{position:absolute;width:100%;height:1px;margin-top:8px;content:"";background-color:#e1e4e8}.search-autocomplete-dropdown .autocomplete-keyword-only{background:#f6f8fa}.search-autocomplete-dropdown .autocomplete-text{color:#24292e}.search-autocomplete-dropdown .navigation-item{cursor:pointer}.search-autocomplete-dropdown .navigation-item[aria-selected="true"],.search-autocomplete-dropdown .navigation-item.navigation-focus{color:#fff;background-color:#0366d6;border-radius:3px}.search-autocomplete-dropdown .navigation-item[aria-selected="true"] .autocomplete-text,.search-autocomplete-dropdown .navigation-item.navigation-focus .autocomplete-text{color:#fff}@media (min-width: 768px){.advanced-search-form .flattened dt{width:230px}.advanced-search-form .flattened dt label{font-weight:400}.advanced-search-form .flattened dd{margin-left:250px}.advanced-search-form .form-checkbox{margin-left:250px}}.codesearch-results .code-list .title a{word-wrap:break-word}.codesearch-results .repo-list-item{border-bottom:0}.codesearch-results .repo-list-item+.repo-list-item{border-top:1px #e1e4e8 solid}.search-form-fluid .TableObject-item--primary{position:relative;padding-right:8px}.search-form-fluid .completed-query{position:absolute;top:7px;right:8px;left:8px;z-index:1;margin:0;overflow:hidden;white-space:nowrap}.search-form-fluid .completed-query span{opacity:0}.search-form-fluid .search-page-label{position:relative;display:block;font-weight:400;cursor:text}.search-form-fluid .search-page-label.focus .completed-query{opacity:0.6}.search-form-fluid .search-page-input{position:relative;z-index:2;min-height:0;padding:0;margin:0;background:none;border:0;box-shadow:none}.search-form-fluid .search-page-input:focus{box-shadow:none}.sort-bar{padding-bottom:20px;margin-bottom:20px;border-bottom:1px solid #f1f1f1}.sort-bar .sort-label{padding-right:5px;font-size:13px;font-weight:200;color:#666}.sort-bar .select-menu{float:right}.topics-row-container{height:30px;overflow:hidden}@media (max-width: 544px){.codesearch-pagination-container a:not(.next_page):not(.previous_page),.codesearch-pagination-container .gap{display:none}.codesearch-pagination-container .previous_page,.codesearch-pagination-container .next_page{width:100%}.codesearch-pagination-container .current{color:#586069;background:#fff;border-color:#e1e4e8}.codesearch-pagination-container .current::after{content:" of " attr(data-total-pages)}}.comment-apps-container{border-top-width:0}.comment-apps-container .comment-app-details[open]>.comment-app{color:#fff;background-color:#0366d6}.comment-apps .select-menu{bottom:36px}.comment-apps .select-menu .select-menu-button{background-color:#e1e4e8;box-shadow:0 0 0 4px #fafbfc}.comment-apps .select-menu .select-menu-button.selected{color:#fff;background-color:#0366d6}.comment-apps .select-menu .select-menu-button::after{display:none}.comment-apps .select-menu-modal{z-index:90}.write-content.focused .select-menu-button{box-shadow:0 0 0 4px #fff}.commit-activity-graphs .dots{display:none}.commit-activity-master{margin-top:20px}.is-graph-loading .commit-activity-master{display:none}rect{shape-rendering:crispedges}rect.max{fill:#f9c513}g.bar{fill:#28a745}g.mini{fill:#fb8532}g.active rect{fill:#b31d28}circle.focus{fill:#444d56}.dot text{fill:#444d56;stroke:none}.CommunityTemplate-header{height:40px}.CommunityTemplate-markdown{height:800px;overflow-y:scroll;font-size:14px}.CommunityTemplate-highlight{padding:2px 4px;margin:0;font-family:"SFMono-Regular",Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:12px;font-style:normal;font-weight:600;color:#24292e;cursor:pointer;background-color:#ffd33d;border-radius:3px}.CommunityTemplate-highlight--focus{color:#fff;background-color:#0366d6}.community-checklist .progress-bar{background:linear-gradient(to right, #ffd33d, #c5e300, #28a745);background-color:transparent}.community-checklist .progress{float:right;background-color:#f6f8fa}.community-checklist .checklist-dot{color:#dbab09}body.full-width-p0 .container{width:100%;padding-right:20px;padding-left:20px}body.full-width-p0 .container.new-discussion-timeline{padding-right:0;padding-left:0}.compare-cutoff,.diff-cutoff{padding:8px 0;margin:5px 0;font-weight:600;color:#4c4a42;text-align:center;background-color:#fff9ea;border:solid 1px #dfd8c2;border-radius:3px}span.no-nl-marker{position:relative;color:#cb2431;vertical-align:middle}.symlink .no-nl-marker{display:none}.existing-pull{margin:10px 0}.existing-pull .list-group-item::before{display:table;content:""}.existing-pull .list-group-item::after{display:table;clear:both;content:""}.existing-pull .existing-pull-contents{float:left;width:680px}.existing-pull .existing-pull-button{float:right;margin-top:3px}.existing-pull .existing-pull-number{font-weight:400;color:#aaa}.existing-pull .css-truncate{max-width:700px}.existing-pull .css-truncate p{display:inline}.compare-pr-placeholder{padding:15px;margin:15px 0;font-size:14px;color:#4c4a42;background-color:#fff9ea;border:solid 1px #dfd8c2;border-radius:3px}.compare-pr-placeholder p{margin:7px 0;color:#6d6c60}.compare-pr-placeholder .btn{margin-right:10px;margin-bottom:-2px}.compare-pr-placeholder .help-link{padding:3px;margin-top:5px;margin-right:-3px;color:#9c997d;text-decoration:none}.compare-pr .new-pr-form{display:none}.compare-pr .contributing{display:none}.compare-pr.open .compare-pr-placeholder{display:none}.compare-pr.open .new-pr-form{display:block}.compare-pr.open .contributing{display:block}.contact-github textarea{height:100px;resize:vertical}.contact-github .contact-checklist>li{margin:5px 0 5px 18px;list-style-position:outside}.documentation-results-wrapper{position:relative;top:-19px}.documentation-results{position:absolute;top:0;z-index:2;width:400px;margin-top:5px;box-shadow:0 0 5px rgba(0,0,0,0.2)}.documentation-results ul{width:100%}.documentation-results ul li:first-child a{border-top-left-radius:3px;border-top-right-radius:3px}.documentation-results .documentation-results-footer a{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.documentation-results a{display:block;padding:5px 10px;font-weight:600;color:#333;text-decoration:none;cursor:pointer;background-color:#fff;border:solid #ddd;border-width:0 1px 1px;outline:none}.documentation-results a:hover{color:#fff;background-color:#3586c3}.documentation-results a.selected{color:#fff;background-color:#3586c3}ul.documentation-results-group{list-style-type:none}.contact-form-extras{display:none}.select-menu-item{text-align:left;background-color:#fff;border-top:0;border-right:0;border-left:0}.timeline-jump-to-menu{left:-85px;z-index:80}.contributions-setting-menu{z-index:80;width:330px}.calendar-graph{height:126px;padding:5px 0 0;text-align:center}.calendar-graph.days-selected rect.day{opacity:0.5}.calendar-graph.days-selected rect.day.active{opacity:1}.calendar-graph .dots{width:64px;height:64px;margin:20px auto 0}.calendar-graph text.month{font-size:10px;fill:#767676}.calendar-graph text.wday{font-size:9px;fill:#767676}.graph-before-activity-overview{border-top-left-radius:3px;border-top-right-radius:3px}.activity-overview-box{border-top-left-radius:0;border-top-right-radius:0}.contrib-footer{padding:0 10px 12px;font-size:11px}.contrib-legend{float:right}.contrib-legend .legend{position:relative;bottom:-1px;display:inline-block;margin:0 5px;list-style:none}.contrib-legend .legend li{display:inline-block;width:10px;height:10px}.contrib-square{font-size:22px;line-height:0.9;color:#cce888}.contribution-activity h2{margin:30px 0 15px;font-size:18px;font-weight:400}.contribution-activity .select-menu-button{position:relative;top:-4px}.contribution-activity.loading .contribution-activity-listing{display:none}.contribution-activity.loading .contribution-activity-show-more{display:none}.contribution-activity.loading .contribution-activity-spinner{display:block}.contribution-activity-spinner{display:none;width:64px;height:64px;margin:20px auto 0}.contribution-activity-spinner.next{margin:0 auto}ul.simple-conversation-list a.meta{color:#586069}li.contribution{padding:10px 0;list-style:none}li.contribution h3{display:inline-block;margin:0;font-size:14px}li.contribution .cmeta{display:block;font-size:12px}li.contribution .d{color:#c00}li.contribution .a{color:#8cac29}li.contribution .num{color:#586069}.activity-overview-axis,.activity-overview-point{stroke:#6cb267}.halloween-activity-overview .activity-overview-axis,.halloween-activity-overview .activity-overview-point{stroke:#fe9600}.activity-overview-label{fill:#586069}.activity-overview-percentage{font-size:10px;fill:#959da5}.tint-box{position:relative;margin-bottom:10px;background:#f6f8fa;border-radius:6px}.tint-box.transparent{background:#fff}.tint-box .activity{padding-top:100px;margin-top:0}.contrib-person path{fill:#fb8532}.contrib-person .midlabel{fill:#959da5}.logged-out.enter-coupon{background-color:#f9f9f9}.logged-out.enter-coupon .coupon-form-body{margin-bottom:-20px;background-image:none;box-shadow:0 1px 3px rgba(0,0,0,0.075),inset 1px 0 #fff,0 0 200px #fff}.logged-out.enter-coupon .header-logged-out{background-color:#fff}.coupons .setup-plans td img{margin-top:-2px;vertical-align:middle}.coupons .coupon-form-body{width:270px;padding:20px;margin:100px auto 60px;font-size:14px;text-align:center;background-color:#fff;background-image:linear-gradient(#fefefe, #fafafa);border:1px solid #ccc;border-radius:3px;box-shadow:0 1px 3px rgba(0,0,0,0.075),inset 1px 0 #fff}.coupons .coupon-form-body .input-block{margin-bottom:15px}.coupons .coupon-form-body .btn{display:block;width:100%}.coupon-icon{width:80px;height:80px;margin:0 auto 15px;color:#0366d6;border:1px solid #dedede;border-radius:40px}.coupon-icon .octicon{margin-top:15px;margin-right:2px}.coupons-list-options{margin-bottom:15px}.coupons-list-options .select-menu,.coupons-list-options .BtnGroup{display:inline-block;margin-right:10px}.coupons-list-options .pagination{float:right;margin:0}.user-repos .mini-repo-list-item{padding-right:6px}.user-repos .mini-repo-list-item .repo-and-owner{max-width:100%}.user-repos .mini-repo-list-item .owner{max-width:145px}.repo-private-icon{fill:#dbab09}.dashboard-rollup-items>.dashboard-rollup-item{border-top:1px solid #e1e4e8}@keyframes broadCastMaskFade{0%{opacity:0}30%{opacity:1}70%{opacity:1}100%{opacity:0}}.github-jobs-logo:hover{text-decoration:none}.github-jobs-logo strong{display:inline-block;width:62px;height:12px;text-indent:-9999px;vertical-align:middle;background:url("/images/modules/jobs/logo.png") 0 0 no-repeat;background-size:62px auto}.dashboard h1{margin-bottom:0.5em;font-size:160%}.dashboard h1 a{font-size:70%;font-weight:400}.dashboard .notice{padding:15px;margin-top:0;margin-bottom:0;text-align:center}.news-full,.page-profile .news{float:none;width:auto}.dashboard-break-word{-webkit-hyphens:auto;-ms-hyphens:auto;hyphens:auto;word-break:break-word}.news .error-message{display:none}.news .is-error .loading-message{display:none}.news .is-error .error-message{display:block}.news .bio g-emoji,.news .repo-description g-emoji{display:inline-block}.account-switcher-truncate-override{width:calc(100% - 36px);max-width:100% !important}.dashboard-notice{position:relative;padding:15px 15px 15px 55px;margin-bottom:20px;font-size:14px;background-color:#fafbfc;border:solid 1px #d1d5da;border-radius:3px}.dashboard-notice .dismiss{position:absolute;top:10px;right:10px;width:16px;height:16px;color:#959da5;cursor:pointer}.dashboard-notice .dismiss:hover{color:#586069}.dashboard-notice .notice-icon{position:absolute;top:15px;left:15px}.dashboard-notice .octicon-organization{color:#0366d6}.dashboard-notice h2{margin-top:9px;margin-bottom:16px;font-size:18px;font-weight:400;color:#24292e}.dashboard-notice p.no-title{padding-right:5px}.dashboard-notice .inset-figure{float:right;margin-bottom:15px;margin-left:20px}.dashboard-notice ul{margin-left:18px}.dashboard-notice li{padding-bottom:15px}.dashboard-notice .coupon{padding:10px;margin:15px 0;font-size:20px;font-weight:600;text-align:center;background:#fff;border:1px dashed #dbedff}.dashboards-overview-lead{width:700px}.dashboards-overview-cards .boxed-group{width:100%;margin:10px 0}.dashboards-overview-cards .boxed-group .graph-canvas path{stroke-opacity:0.5}.dashboards-overview-cards .is-no-activity .blankslate{display:block}.dashboards-overview-cards .is-no-activity .dashboards-overview-graph{display:none}.dashboards-overview-cards .blankslate{display:none;padding-top:47px;background-color:#fff;border:0;box-shadow:none}.dashboards-overview-cards .octicon-arrow-down,.dashboards-overview-cards .octicon-arrow-up{display:none}.dashboards-overview-cards .is-increase .octicon-arrow-up{display:inline-block}.dashboards-overview-cards .is-decrease .octicon-arrow-down{display:inline-block}.dashboards-overview-cards .octicon-arrow-down{color:#cb2431}.dashboards-overview-cards .octicon-arrow-up{color:#1db34f}.dashboards-overview-cards .graph-canvas .dots{padding:43px 0}.dashboards-overview-cards .summary-stats{height:78px}.dashboards-overview-cards .summary-stats .created_at{color:#1db34f}.dashboards-overview-cards .summary-stats .closed_at,.dashboards-overview-cards .summary-stats .merged_at{color:#0366d6}.dashboards-overview-cards .summary-stats .totals-num{margin:0 7px}.dashboards-overview-cards .summary-stats .single{width:100%}.dashboards-overview-graph{height:160px}.dashboards-overview-graph .path{fill:none;stroke-width:2}.dashboards-overview-graph path.created_at{stroke:#1db34f}.dashboards-overview-graph path.merged_at,.dashboards-overview-graph path.closed_at{stroke:#1d7fb3}.dashboards-overview-graph .y line{stroke:#1db34f}.dashboards-overview-graph .y.unique line{stroke:#1d7fb3}.dashboards-overview-graph .overlay{fill-opacity:0}.created_at circle{fill:#1db34f;stroke:#fff;stroke-width:2}.dots.merged_at circle,.dots.closed_at circle{fill:#1d7fb3;stroke:#fff;stroke-width:2}dl.form.developer-select-account{margin-top:0}.developer-wrapper .setup-info-module .features-list{margin-left:16px}.developer-wrapper .setup-info-module .features-list .octicon{margin-left:-17px}.developer-thanks h2{font-size:38px;font-weight:400}.developer-thanks .hook{margin-top:2px;margin-bottom:30px;font-size:18px;font-weight:300;color:#666}.developer-thanks-image{position:relative;bottom:-45px;float:left;width:400px}.developer-thanks-section{margin:130px 0 0 470px}.developer-next-steps{font-size:18px;font-weight:300;list-style:none}.developer-next-steps li{margin-top:10px}.developer-next-steps li:first-child{margin-top:0}.developer-next-steps .octicon{margin-right:10px;color:#28a745;vertical-align:middle}.donut-chart>.error,.donut-chart>.cancelled,.donut-chart>.action_required,.donut-chart>.timed_out,.donut-chart>.failure{fill:#cb2431}.donut-chart>.expected,.donut-chart>.queued,.donut-chart>.in_progress,.donut-chart>.pending{fill:#dbab09}.donut-chart>.success{fill:#2cbe4e}.donut-chart>.neutral{fill:#959da5}.survey-question-form .other-text-form,.survey-question-form .other-text-form-block{display:none;margin-top:0}.survey-question-form.is-other-selected .other-text-form{display:inline-block}.survey-question-form.is-other-selected .other-text-form-block{display:block}.setup-header .large-file-storage-header{font-size:44px}.early-acccess-setup-form .form-group{margin-top:0;margin-bottom:30px}.early-acccess-setup-form select{display:block;width:200px}.early-access-setup-list{padding:0 15px 15px;margin:0;font-size:14px}.early-access-setup-list .early-access-setup-list-item{margin-top:10px;margin-left:20px}.early-access-setup-list .early-access-setup-list-item:first-child{margin-top:0}.early-access-thanks-wrapper{position:relative;z-index:1;height:80vh;margin-bottom:-41px;background-color:#fcfcfc;border-bottom:1px solid #ddd}.early-access-thanks-content{position:relative;top:50%;width:500px;margin:0 auto;transform:translateY(-50%)}.early-access-thanks-title{margin-top:0;font-weight:400}.early-access-thanks-lead{margin-top:0;margin-bottom:0}.eap-error-state-title{margin-top:0}.ghe-license-status{padding:40px 0;font-size:16px;text-align:center}.ghe-license-status .octocat{width:225px;margin-bottom:20px}.ghe-license-status h1{margin-bottom:10px}.ghe-license-status p{margin-bottom:5px;color:#586069}.ghe-license-expiry-icon{margin:5px 10px 0 0;color:#ddb38a}.explore-content{margin-top:-15px}.explore-content .blankslate{margin-top:15px}.explore-pjax-container{position:relative}.repo-snipit{display:inline-block;margin-top:7px}.repo-snipit:hover{text-decoration:none}.repo-snipit .octicon{font-size:14px;color:#586069}.repo-snipit-name{max-width:200px;color:#666}.repo-snipit-description{max-width:300px;color:#586069}.repo-snipit:hover .repo-snipit-name,.repo-snipit:hover .repo-snipit-description{color:#0366d6}.newsletter-frequency-choice{font-weight:400;cursor:pointer;border:1px solid #eee;border-radius:4px}.newsletter-frequency-choice .notice{position:absolute;right:0;bottom:1em;left:0;z-index:-1;font-weight:600;color:#28a745;text-align:center;opacity:0}.newsletter-frequency-choice .notice.visible{bottom:-2em;opacity:1;transition:opacity 0.15s ease-in-out}.newsletter-frequency-choice h3{padding:10px;margin:0;font-weight:400;text-align:center;background-color:#fafbfc;border-bottom:1px solid #eee}.newsletter-frequency-choice h3 input{position:relative;top:-2px;margin:0 3px 0 -19px}.newsletter-frequency-choice p{margin:15px}.newsletter-frequency-choice:hover{border-color:#0366d6}.newsletter-frequency-choice:hover h3{color:#fff;background-color:#0366d6;border-color:#0366d6}.newsletter-frequency-choice.selected{border-color:#28a745;box-shadow:0 0 5px rgba(0,0,0,0.2)}.newsletter-frequency-choice.selected h3{color:#fff;background-color:#28a745;border-color:#28a745}@media (min-width: 1012px){.col-lg-9 .Collection{max-width:744px}}@media (min-width: 1012px){.Spotlight{margin-top:100px}}.Spotlight-text{z-index:1}.Spotlight-blur{z-index:0;opacity:0.9}@media (min-width: 1012px){.Spotlight-blur{opacity:1;-webkit-mask-image:linear-gradient(0deg, #000, #000 75%, transparent);mask-image:linear-gradient(0deg, #000, #000 75%, transparent)}}.exploregrid{display:flex;flex-wrap:wrap;justify-content:flex-start;align-items:stretch;list-style:none}.exploregrid-item-wrap{display:flex;flex-direction:column}.exploregrid-item{flex:1;position:relative;display:block;height:100%;padding-top:24px;padding-bottom:64px;font-size:14px;color:#555;border:1px solid rgba(0,0,0,0.075);border-bottom-color:rgba(0,0,0,0.125);border-radius:4px;box-shadow:0 1px 2px rgba(0,0,0,0.05),0 5px 10px rgba(0,0,0,0.05);transition:border-color 0.1s ease-in-out, box-shadow 0.1s ease-in-out}.exploregrid-item:hover{text-decoration:none;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.15);box-shadow:0 1px 3px rgba(0,0,0,0.05),0 8px 15px rgba(0,0,0,0.1)}.exploregrid-item:hover .exploregrid-item-title{color:#0366d6}.exploregrid-item:hover .exploregrid-item-header{opacity:1}.exploregrid-item-mini{float:left;width:100%;height:auto;margin:0 0 15px}.exploregrid-item-mini .exploregrid-item-header{height:10px}.exploregrid-item-mini .exploregrid-item-title{font-size:16px}.exploregrid-item-header{position:absolute;top:0;left:0;width:100%;height:18px;background-color:#f5f5f5;border:1px solid rgba(0,0,0,0.1);border-top-left-radius:4px;border-top-right-radius:4px;opacity:0.8;transition:opacity 0.1s ease-in-out}.exploregrid-item-title{margin-top:0;margin-bottom:5px;font-size:20px;font-weight:400;line-height:1.2;color:#24292e}.fakelogin{position:fixed;top:0;z-index:1000;width:100%;font-size:14px;line-height:34px;color:#fff;text-align:center;text-shadow:0 -1px 0 rgba(153,0,0,0.25);background-image:linear-gradient(#dc5f59, #b33630);border-bottom:1px solid #900}.fakelogin+.Header{margin-top:35px}.fakelogin+.server-stats{margin-top:35px}.fakelogin .cancel-impersonation{color:#fff;text-decoration:underline}.file{position:relative;margin-top:16px;margin-bottom:16px;border:1px solid #ddd;border-radius:3px}.file .data.empty{padding:5px 10px;color:#586069}.file:not(.open) .file-header.file-header--expandable{border-bottom:0}.file .data.suppressed,.file.open .image{display:none}.file.open .data.suppressed{display:block}.file .image{position:relative;padding:30px;text-align:center;background-color:#ddd}.file .image table{margin:0 auto}.file .image td{padding:0 5px;color:#888;text-align:center;vertical-align:top}.file .image td img{max-width:100%}.file .image .border-wrap{position:relative;display:inline-block;line-height:0;background-color:#fff;border:1px solid #6a737d}.file .image a{display:inline-block;line-height:0}.file .image img,.file .image canvas{max-width:600px;background:url("/images/modules/commit/trans_bg.gif") right bottom #eee;border:1px solid #fff}.file .image .view img,.file .image .view canvas{position:relative;top:0;right:0;max-width:inherit;background:url("/images/modules/commit/trans_bg.gif") right bottom #eee}.file .image .view>span{vertical-align:middle}.file .empty{background:none}.file-header{padding:5px 10px;background-color:#fafbfc;border-bottom:1px solid #e1e4e8;border-top-left-radius:2px;border-top-right-radius:2px}.file-header::before{display:table;content:""}.file-header::after{display:table;clear:both;content:""}.file-actions{float:right;padding-top:2px;font-size:13px}.file-actions select{margin-left:5px}.file-info{font-family:"SFMono-Regular",Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:12px;line-height:32px}.file-info .octicon{vertical-align:text-bottom}.file-info-divider{display:inline-block;width:1px;height:18px;margin-right:3px;margin-left:3px;vertical-align:middle;background-color:#ddd}.file-mode{text-transform:capitalize}.show-file-notes{display:none}.comments-indicator{display:none}.has-inline-notes .show-file-notes{display:inline-block;margin-right:10px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.has-inline-notes.hide-file-notes-toggle .show-file-notes{display:none !important}.has-inline-notes.hide-file-notes-toggle .comments-indicator{display:inline-block}.file-blankslate{border:0;border-radius:0 0 2px 2px}.diff-progressive-loader{min-height:150px}.load-diff-button,.load-diff-retry{z-index:1;min-height:32px}.diff-placeholder-svg{clip:rect(1px, 1px, 1px, 1px);-webkit-clip-path:inset(50%);clip-path:inset(50%)}.hidden-diff-reason{z-index:2}.axis{font-size:10px}.axis line{stroke:rgba(27,31,35,0.1);shape-rendering:crispedges}.axis path{display:none}.axis .zero line{stroke:#0366d6;stroke-dasharray:3 3;stroke-width:1.5}.graphs .is-graph-loading{min-height:500px}.graphs.wheader h2{padding:1px}.graphs .area{fill:#28a745;fill-opacity:0.5}.graphs .path{fill:none;stroke:#28a745;stroke-opacity:1;stroke-width:2px}.graphs .dot{fill:#28a745;stroke:#1e7e34;stroke-width:2px}.graphs .dot.padded{stroke:#fff;stroke-width:1px}.graphs .dot.padded circle:hover{fill:#0366d6}.graphs .d3-tip{fill:#24292e}.graphs .d3-tip text{font-size:11px;fill:#fff}.graphs .dir{float:right;padding-top:5px;font-size:12px;font-weight:400;line-height:100%;color:#6a737d}.graphs .selection .overlay{visibility:none}.graphs .selection .selection{fill:#24292e;fill-opacity:0.1;stroke:#24292e;stroke-dasharray:3 3;stroke-opacity:0.4;stroke-width:1px;shape-rendering:crispedges}.graph-filter h3{display:inline-block;font-size:24px;font-weight:300}.graph-filter .info{margin-bottom:20px;color:#586069}h2.ghead::after{display:block;height:0;clear:both;visibility:hidden;content:"."}.graph-canvas .activity{width:400px;padding:10px;margin:100px auto 0;color:#2f363d;text-align:center;border-radius:3px}.graph-canvas .dots{margin:0 auto}.graph-canvas>.activity{display:none}.graph-loading,.graph-error,.graph-no-usable-data,.graph-empty{display:none}.graph-canvas.is-graph-loading>.activity,.graph-canvas.is-graph-without-usable-data>.activity,.graph-canvas.is-graph-empty>.activity{display:block}.is-graph-loading .graph-loading,.is-graph-empty .graph-empty,.is-graph-without-usable-data .graph-no-usable-data,.is-graph-load-error .graph-error{display:block}.svg-tip{position:absolute;z-index:99999;padding:10px;font-size:12px;color:#959da5;text-align:center;background:rgba(0,0,0,0.8);border-radius:3px}.svg-tip strong{color:#dfe2e5}.svg-tip.is-visible{display:block}.svg-tip::after{position:absolute;bottom:-10px;left:50%;width:5px;height:5px;box-sizing:border-box;margin:0 0 0 -5px;content:" ";border:5px solid transparent;border-top-color:rgba(0,0,0,0.8)}.svg-tip.comparison{padding:0;text-align:left;pointer-events:none}.svg-tip.comparison .title{display:block;padding:10px;margin:0;font-weight:600;line-height:1;pointer-events:none}.svg-tip.comparison ul{margin:0;white-space:nowrap;list-style:none}.svg-tip.comparison li{display:inline-block;padding:10px}.svg-tip.comparison li:first-child{border-top:3px solid #28a745;border-right:1px solid #24292e}.svg-tip.comparison li:last-child{border-top:3px solid #2188ff}.svg-tip-one-line{white-space:nowrap}.LoadingDependencies{position:absolute;left:0;width:100%;animation:fadeOut;animation-duration:0.6s;animation-fill-mode:forwards;animation-timing-function:ease-in}.LoadingDependencies--loading{position:relative}.LoadingDependencies--loading .octicon{opacity:0;animation:dropBox;animation-duration:1.25s;animation-fill-mode:forwards;animation-timing-function:linear;animation-delay:1s;animation-iteration-count:infinite}.LoadingDependencies--loading .octicon:nth-child(2){position:absolute;left:calc(50% - 27px);animation-delay:1.61s}@keyframes fadeOut{0%{opacity:1}100%{opacity:0}}@keyframes dropBox{0%{opacity:1;transform:translateY(-110%)}7%{opacity:1;transform:translateY(20%);transform:translateX(0)}80%{opacity:1}100%{opacity:0;transform:translateX(-250%)}}.getting-started .main-content .container{width:420px}.getting-started .list-group-item{background:#fff}.getting-started .list-group-item .octicon{color:#bbb}.getting-started .list-group-item .octicon-lead{width:30px}.getting-started .list-group-item:hover,.getting-started .list-group-item:focus{background:#fafbfc}.getting-started .link-text{color:#24292e}.getting-started .link-text strong{color:#0366d6}.topic-tag{display:inline-block;padding:0.3em 0.9em;margin:0 0.5em 0.5em 0;white-space:nowrap;background-color:#f1f8ff;border-radius:3px}.topic-tag-link:hover{text-decoration:none;background-color:#def}.delete-topic-button{display:inline-block;width:26px;color:#6a737d;background-color:#f1f8ff;border-top:0;border-right:0;border-bottom:0;border-left:1px solid #b4d9ff;border-top-right-radius:3px;border-bottom-right-radius:3px}.delete-topic-button:hover{background-color:#def}.invalid-topic .delete-topic-button{color:#86181d;background-color:#ffdce0;border-left-color:#cea0a5}.invalid-topic .delete-topic-button:hover{background-color:#ffc8ce}.topic-tag-action{display:inline-flex;align-items:center;padding-left:0.8em;margin:0.4em 0.4em 0 0;background-color:#f1f8ff;border-radius:3px}.topic-tag-action.invalid-topic{color:#86181d;background-color:#ffdce0;border-color:#cea0a5}.topic-tag-action .add-topic-button,.topic-tag-action .remove-topic-button{display:inline-block;width:26px;font-size:15px;color:#6a737d;background-color:#f1f8ff;border-top:0;border-right:0;border-bottom:0;border-left:1px solid #b4d9ff}.topic-tag-action .add-topic-button:hover,.topic-tag-action .remove-topic-button:hover{color:#fff}.topic-tag-action .add-topic-button:hover{background-color:#28a745}.topic-tag-action .remove-topic-button{border-right:0;border-top-right-radius:3px;border-bottom-right-radius:3px}.topic-tag-action .remove-topic-button:hover{background-color:#d73a49}.topic-input-container .tag-input{width:908px;cursor:text}.topic-input-container .tag-input.org-repo-tag-input{width:100%}.topic-input-container .tag-input .tag-input-inner{min-height:26px}.topic-input-container .topic-tag{margin-top:2px}.repository-topics-container .list-topics-container{display:inline-flex;flex-wrap:wrap;align-items:baseline}.repository-topics-container .manage-topics-container{display:none}.repository-topics-container.open .list-topics-container{display:none}.repository-topics-container.open .manage-topics-container{display:block}.topic .css-truncate-target{max-width:75%}.topic-list .topic-list-item+.topic-list-item{border-top:1px #e1e4e8 solid}.team-breadcrumb .team-breadcrumb-item{display:inline-block}.team-breadcrumb .team-breadcrumb-item::after{padding-right:0.5em;padding-left:0.5em;color:#e1e4e8;content:"/"}.team-breadcrumb .team-breadcrumb-item-selected::after{content:none}.team-discussions-container{min-height:100vh}.team-left-column{max-width:100%}@media (min-width: 768px){.team-left-column{max-width:350px}}.team-left-column .team-avatar{width:80px;height:80px}@media (min-width: 768px){.team-left-column .team-avatar{width:140px;height:140px}}.team-discussions{max-width:768px}.team-discussions .previewable-comment-form .comment{border:0}.discussion-post{opacity:1;transition:opacity 400ms}.discussion-post .timeline-comment::after,.discussion-post .timeline-comment::before{display:none}.discussion-post .post-author{margin-top:-6px}.discussion-post .post-author-timestamp{margin-top:-3px}.discussion-post.fade-out{opacity:0}.discussion-post .timeline-inline-comments{background:#fafbfc}.discussion-post .team-discussion-timeline::before{bottom:20px}.discussion-post .reply-comment:first-child{border-top:1px solid #e1e4e8}.discussion-post .reply-comment:first-child .review-comment{padding-top:16px}.discussion-post .reply-comment .review-comment{padding:8px 16px}.discussion-post .reply-comment .review-comment.is-comment-editing{padding:0;background:#fafbfc}.discussion-post .comment .comment-reactions{margin-left:16px;border-top:0}.discussion-post .comment .reaction-summary-item{margin-bottom:16px}.discussion-post .reaction-summary-item:not(.add-reaction-btn){padding:0 8px;font-size:12px;line-height:26px;border:1px solid #d2dff0;border-radius:3px}.discussion-post .reaction-summary-item:not(.add-reaction-btn) .emoji{font-size:16px;vertical-align:sub}.discussion-post .reaction-summary-item:not(.add-reaction-btn)+.reaction-summary-item{margin-left:8px}.discussion-post .reply-comments-holder{position:relative}.discussion-post .reply-comments-holder::before{position:absolute;top:51px;bottom:0;left:29px;width:2px;content:"";background-color:#e1e4e8}.discussion-post .add-reaction-btn{padding:4px 10px}.discussion-post .pin-btn:disabled{pointer-events:none}.discussion-post .pinned{color:#f66a0a;opacity:1}.discussion-post .loading-spinner{display:none;float:left;margin-top:12px}.discussion-post .loading .loading-spinner{display:block}.discussion-post ~ .blankslate{display:none}.team-discussion-new-post .review-thread-reply-button:disabled{cursor:inherit;background-color:#f6f8fa;border:0;box-shadow:none}.team-project-suggestion-number{font-weight:300;color:#a3aab1}.team-discussion-nav-disabled{pointer-events:none}.header-search-wrapper{display:table;width:100%;max-width:100%;min-height:0;padding:0;font-weight:400;vertical-align:middle}.header-search-wrapper.header-search-wrapper-jump-to .header-search-scope{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content}.header-search-input{display:table-cell;width:100%;min-height:26px;padding-top:0;padding-bottom:0;background:none;border:0;box-shadow:none}.header-search-input:focus{border:0;box-shadow:none}.header-search-input:focus ~ .header-search-key-slash{display:none !important}.header-search-input::-ms-clear{display:none}.header-search-scope{display:none;width:1%;padding-right:8px;padding-left:8px;font-size:12px;color:#586069;white-space:nowrap;vertical-align:middle;border-right:1px solid #eaecef;border-top-left-radius:3px;border-bottom-left-radius:3px}.header-search-scope:empty+.header-search-input{width:100%}.header-search-scope:hover{color:#fff;background-color:rgba(255,255,255,0.12)}.scoped-search .header-search-scope{display:table-cell}.scoped-search .form-control.focus .header-search-scope{color:#0366d6;background-color:#c0ddfe;border-color:#8ec2fd}.jump-to-field-active{color:#24292e !important;background-color:#fafbfc}.jump-to-field-active:-ms-input-placeholder{color:#586069 !important}.jump-to-field-active::-ms-input-placeholder{color:#586069 !important}.jump-to-field-active::placeholder{color:#586069 !important}.jump-to-field-active ~ .header-search-key-slash{display:none}.jump-to-field-active.jump-to-dropdown-visible{border-bottom-right-radius:0;border-bottom-left-radius:0}.jump-to-suggestions{top:30px;left:0;z-index:35;width:100%;border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px;box-shadow:0 4px 10px rgba(0,0,0,0.1)}.jump-to-suggestions-path{min-width:0;min-height:44px;color:#1b1f23}.jump-to-suggestions-path .jump-to-octicon{width:28px;color:#6a737d}.jump-to-suggestions-path .jump-to-suggestion-name{max-width:none}.jump-to-suggestions-path mark{font-weight:600;background-color:transparent}.jump-to-suggestions-results-container .navigation-item{border-bottom:1px solid #e1e4e8}.jump-to-suggestions-results-container .navigation-item:last-child{border-bottom:0}.jump-to-suggestions-results-container .d-on-nav-focus{display:none}.jump-to-suggestions-results-container [aria-selected="true"] .jump-to-octicon,.jump-to-suggestions-results-container .navigation-focus .jump-to-octicon{color:#fff}.jump-to-suggestions-results-container [aria-selected="true"] .jump-to-suggestions-path,.jump-to-suggestions-results-container .navigation-focus .jump-to-suggestions-path{color:#fff;background:#0366d6}.jump-to-suggestions-results-container [aria-selected="true"] mark,.jump-to-suggestions-results-container .navigation-focus mark{color:#fff}.jump-to-suggestions-results-container [aria-selected="true"] .d-on-nav-focus,.jump-to-suggestions-results-container .navigation-focus .d-on-nav-focus{display:block}.Header{z-index:32;padding-top:12px;padding-bottom:12px;color:rgba(255,255,255,0.75);background-color:#24292e}.server-stats+.Header{box-shadow:inset 0 1px 0 rgba(255,255,255,0.075)}.Header .header-search-scope{font-size:inherit;line-height:28px;color:rgba(255,255,255,0.75);border-right-color:#282e34}.Header .header-search-wrapper{min-height:30px;font-size:inherit;color:#fff;background-color:rgba(255,255,255,0.125);border:0;box-shadow:none}.Header .header-search-wrapper .truncate-repo-scope{max-width:110px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.Header .header-search-wrapper.focus{background-color:rgba(255,255,255,0.175);box-shadow:none}.Header .header-search-wrapper.focus .header-search-scope{color:#fff;background-color:rgba(255,255,255,0.075);border-right-color:#282e34}.Header .header-search-input{min-height:30px;font-size:16px;color:inherit}@media (min-width: 1012px){.Header .header-search-input{font-size:inherit}}.Header .header-search-input:-ms-input-placeholder{color:rgba(255,255,255,0.75)}.Header .header-search-input::-ms-input-placeholder{color:rgba(255,255,255,0.75)}.Header .header-search-input::placeholder{color:rgba(255,255,255,0.75)}.Header .dropdown-menu{width:300px}.Header .platform-nav .dropdown-menu{width:500px}.page-responsive .Header .platform-nav .dropdown-menu{width:auto}@media (min-width: 1012px){.page-responsive .Header .platform-nav .dropdown-menu{width:500px}}.Header .notification-indicator:hover::after{content:none}@media (min-width: 1012px){.Header .notification-indicator:hover::after{content:attr(aria-label)}}.page-responsive .HeaderMenu{display:none;clear:both}@media (min-width: 1012px){.page-responsive .HeaderMenu{display:block;clear:none}}.page-responsive .HeaderMenu .header-search{float:none;width:auto;max-width:none;padding-top:16px;padding-bottom:16px;margin-right:0;border-top:1px solid #444d56}@media (min-width: 1012px){.page-responsive .HeaderMenu .header-search{float:left;width:300px;padding-top:4px;padding-bottom:4px;border-top:0}}.open .HeaderMenu{display:block}.HeaderMenu .header-search{width:300px;padding-top:3px;padding-bottom:3px;font-size:13px}.page-responsive .HeaderMenu--experiment{z-index:100;width:300px;overflow:auto;background-color:#fff;box-shadow:0 10px 50px rgba(27,31,35,0.15)}@media (min-width: 1012px){.page-responsive .HeaderMenu--experiment{width:auto;overflow:visible;background-color:transparent;box-shadow:none}}.page-responsive .HeaderMenu--experiment .HeaderMenu-item{border-bottom:1px solid #eaecef}@media (min-width: 1012px){.page-responsive .HeaderMenu--experiment .HeaderMenu-item{border-bottom:0 solid transparent}}.page-responsive .HeaderMenu--experiment .HeaderMenu-target{color:#586069 !important}@media (min-width: 1012px){.page-responsive .HeaderMenu--experiment .HeaderMenu-target{color:#fff !important}}.page-responsive .HeaderMenu--experiment .dropdown-menu{position:static;width:auto;border:0 solid transparent;box-shadow:none}.page-responsive .HeaderMenu--experiment .dropdown-menu::before,.page-responsive .HeaderMenu--experiment .dropdown-menu::after{content:none}@media (min-width: 1012px){.page-responsive .HeaderMenu--experiment .dropdown-menu{position:absolute;width:300px;border:1px solid rgba(27,31,35,0.15);box-shadow:0 3px 12px rgba(27,31,35,0.15)}.page-responsive .HeaderMenu--experiment .dropdown-menu::before,.page-responsive .HeaderMenu--experiment .dropdown-menu::after{content:""}}.page-responsive .HeaderMenu--experiment .dropdown-menu-s{transform:none}@media (min-width: 1012px){.page-responsive .HeaderMenu--experiment .dropdown-menu-s{transform:translateX(50%)}}.page-responsive .HeaderMenu--experiment .header-search{width:auto;padding-top:0;padding-bottom:0;border-top:0}@media (min-width: 1012px){.page-responsive .HeaderMenu--experiment .header-search{width:240px}}.page-responsive .HeaderMenu--experiment .header-search-key-slash{opacity:0}@media (min-width: 1012px){.page-responsive .HeaderMenu--experiment .header-search-key-slash{opacity:1}}.page-responsive .HeaderMenu--experiment .header-search-input{border:1px solid #eaecef}@media (min-width: 1012px){.page-responsive .HeaderMenu--experiment .header-search-input{border:0}}.page-responsive .HeaderMenu--experiment .header-search-input:-ms-input-placeholder{color:#586069 !important}.page-responsive .HeaderMenu--experiment .header-search-input::-ms-input-placeholder{color:#586069 !important}.page-responsive .HeaderMenu--experiment .header-search-input::placeholder{color:#586069 !important}@media (min-width: 1012px){.page-responsive .HeaderMenu--experiment .header-search-input:-ms-input-placeholder{color:rgba(255,255,255,0.75) !important}.page-responsive .HeaderMenu--experiment .header-search-input::-ms-input-placeholder{color:rgba(255,255,255,0.75) !important}.page-responsive .HeaderMenu--experiment .header-search-input::placeholder{color:rgba(255,255,255,0.75) !important}}.HeaderMenu--experiment .header-search{width:240px}.read-only-mode-banner{text-align:center;background-color:#f8e45f;border-bottom-color:#f6dc2e}.header-logo-invertocat{margin:-1px 15px -1px -2px;color:#fff;white-space:nowrap}.header-logo-invertocat .octicon-mark-github{float:left}.header-logo-invertocat:hover{color:#fff;text-decoration:none}.header-logo-subbrand{float:left;margin-left:6px;font-size:16px;font-weight:600;line-height:30px}.header-logo-wordmark{position:relative;float:left;height:26px;margin-right:15px;color:#fff}.header-logo-wordmark .octicon{float:left}.header-logo-wordmark:hover{color:#fff}.header-actions{float:right;margin-top:-3px;margin-bottom:-3px}.header-actions .btn{margin-left:5px}.notification-indicator{color:rgba(255,255,255,0.75)}.notification-indicator .mail-status{position:absolute;top:-6px;left:6px;z-index:2;display:none;width:14px;height:14px;color:#fff;background-image:linear-gradient(#54a3ff, #006eed);background-clip:padding-box;border:2px solid #24292e;border-radius:50%}.notification-indicator .mail-status.unread{display:inline-block}.notification-indicator:hover .mail-status{text-decoration:none;background-color:#0366d6}.HeaderNavlink{display:block;color:#fff}.page-responsive .HeaderNavlink{border-top:1px solid #444d56}@media (min-width: 1012px){.page-responsive .HeaderNavlink{border-top:0}}.HeaderNavlink:hover,.HeaderNavlink:focus{color:rgba(255,255,255,0.75);text-decoration:none}.HeaderNavlink:hover .dropdown-caret,.HeaderNavlink:focus .dropdown-caret{border-top-color:rgba(255,255,255,0.75)}.HeaderNavlink.selected{color:#fff}.HeaderNavlink.selected.js-menu-target{border-bottom-color:transparent}.HeaderNavlink.selected.tooltipped::before,.HeaderNavlink.selected.tooltipped::after{display:none}.user-nav .octicon{width:16px}.user-nav .octicon-plus{margin-right:1px}.user-nav .dropdown-menu{width:180px;margin-top:8px}.header-nav-current-user{padding-bottom:0;font-size:inherit}.header-nav-current-user .css-truncate-target{max-width:100%}.header-nav-current-user .user-profile-link{color:#24292e}.unsupported-browser{color:#211e14;background-image:linear-gradient(#feefae, #fae692);border-bottom:1px solid #b3a569}.mobile-banner button.switch-to-mobile{display:block;width:100%;padding:30px 0 45px;font-size:60px;font-weight:600;color:#eaeaea;text-align:center;background-color:#444;border:0}.hooks-listing .boxed-group-action.select-menu{z-index:auto}.hooks-listing .boxed-group-inner{padding:0 10px;margin-bottom:10px}.hook-item a:hover{text-decoration:none}.hook-item .item-status{float:left;width:16px;margin-right:8px;text-align:center}.hook-item .description{color:#6a737d}.hook-item .description .css-truncate-target{max-width:160px}.hook-item .icon-for-success,.hook-item .icon-for-failure,.hook-item .icon-for-pending,.hook-item .icon-for-mute,.hook-item .icon-for-inactive{display:none}.hook-item.success .icon-for-success{display:inline-block;color:#28a745}.hook-item.failure .icon-for-failure{display:inline-block;color:#cb2431}.hook-item.pending .icon-for-pending{display:inline-block;color:#6a737d}.hook-item.inactive .icon-for-inactive{display:inline-block;color:#6a737d}.hook-item.mute .icon-for-mute{display:inline-block;color:#6a737d}.hook-item .icon-for-enabled,.hook-item .icon-for-disabled{display:none}.hook-item.enabled .icon-for-enabled{display:inline-block;color:#28a745}.hook-item.disabled .icon-for-disabled{display:inline-block;color:#ccc}.hook-item .hook-error-message{margin-left:24px;color:#cb2431}.hook-url.css-truncate-target{max-width:360px}.hook-events-field .hook-event-selector{display:none}.hook-events-field.is-custom .hook-event-selector{display:block}.hook-event-selector{margin-left:10px}.hook-event{display:inline-block;width:310px;padding:5px 0 5px 30px;margin:0}.hook-event p{font-weight:400}.hook-event-choice{font-weight:400}.hooks-oap-warning{margin-top:0}.hooks-oap-warning ul{margin:10px 0}.hooks-oap-warning ul li{margin-left:16px}.hook-secret .hook-secret-standin{display:block}.hook-secret .hook-secret-field{display:none}.hook-secret.open .hook-secret-standin{display:none}.hook-secret.open .hook-secret-field{display:block}.hook-deliveries-list .loading-message{display:block}.hook-deliveries-list .error-message{display:none}.hook-deliveries-list.is-error .loading-message{display:none}.hook-deliveries-list.is-error .error-message{display:block}.hook-deliveries-list .spinner{display:inline-block;margin:0;vertical-align:top}.hook-deliveries-list .hook-delivery-item:hover{background-color:transparent}.hook-deliveries-list .item-status{display:inline-block;width:16px;margin-right:5px;text-align:center}.hook-deliveries-list .item-status .icon-for-success,.hook-deliveries-list .item-status .icon-for-failure,.hook-deliveries-list .item-status .icon-for-pending{display:none}.hook-deliveries-list .item-status.success{color:#28a745;visibility:visible}.hook-deliveries-list .item-status.success .icon-for-success{display:inline-block}.hook-deliveries-list .item-status.failure{color:#cb2431}.hook-deliveries-list .item-status.failure .icon-for-failure{display:inline-block}.hook-deliveries-list .item-status.pending{color:#6a737d}.hook-deliveries-list .item-status.pending .icon-for-pending{display:inline-block}.hook-deliveries-pagination-loading-message{display:none}.hook-deliveries-pagination-loading-message .animated-ellipsis-container{text-align:left}.hook-deliveries-pagination.loading .hook-deliveries-pagination-button{display:none}.hook-deliveries-pagination.loading .hook-deliveries-pagination-loading-message{display:block}.boxed-group-list li.hook-delivery-item{padding:10px}.hook-delivery-item .hook-delivery-details{display:none}.hook-delivery-item .hook-delivery-details .loading-message,.hook-delivery-item .hook-delivery-details .error-message{display:none}.hook-delivery-item .hook-delivery-details.is-loading .loading-message{display:block}.hook-delivery-item .hook-delivery-details.has-error .error-message{display:block}.hook-delivery-item.open .hook-delivery-details{display:block}.hook-delivery-item .loading-message{text-align:center}.hook-delivery-time{float:right;margin-right:10px;font-size:10px;color:#6a737d}.hook-delivery-guid{display:inline-block;padding:2px 6px;font-family:"SFMono-Regular",Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:12px;color:rgba(0,0,0,0.5);background-color:rgba(209,227,237,0.5);border-radius:3px}.hook-delivery-guid .octicon{margin:1px -2px 0 0;color:#b0c4ce}.hook-delivery-actions{padding-top:1px}.boxed-group-list>li.hook-delivery-item .btn-sm{margin:0}.boxed-group-list>li.hook-delivery-item .hook-delivery-details .btn-sm{margin:5px 0 0}.hook-deliveries-list .error-message,.hook-delivery-details .error-message{padding:7px 4px;margin:10px 0}.hook-deliveries-list .error-message .octicon,.hook-delivery-details .error-message .octicon{position:relative;top:1px}.boxed-group span.animated-ellipsis-container,.boxed-group span.animated-ellipsis{padding:0}.boxed-group .animated-ellipsis-container{line-height:1.3}.hook-delivery-details{clear:right}.hook-delivery-details .error-message{margin-bottom:0}.hook-delivery-details .tabnav-tabcontent{display:none}.hook-delivery-details .tabnav-tabcontent.selected{display:block}.hook-delivery-details hr{margin:10px 0}.hook-delivery-details pre{padding:7px 12px;margin:10px 0;overflow:auto;font-size:13px;line-height:1.5;background-color:#f8f8f8;border:1px solid #ddd;border-radius:3px}.hook-delivery-details .tabnav{margin:10px 0}.hook-delivery-details h4.remote-call-header{margin:20px 0 10px;border-bottom:1px solid #959da5}.hook-delivery-response-status{display:inline-block;padding:4px 6px 3px;font-family:"SFMono-Regular",Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:10px;line-height:1.1;color:#fff;background-color:#d73a49;border-radius:3px}.hook-delivery-response-status[data-response-status^="2"]{background-color:#28a745}.redelivery-dialog .pending-message{display:block}.redelivery-dialog .failure-message{display:none}.redelivery-dialog.failed{color:#9c2400;background-image:linear-gradient(#f8d8d8, #efd0d0);border-color:#da9797}.redelivery-dialog.failed .pending-message{display:none}.redelivery-dialog.failed .failure-message{display:block}.redelivering-hook-delivery .error-message{display:none}.redelivering-hook-delivery.is-error .loading-message{display:none}.redelivering-hook-delivery.is-error .error-message{display:block}.test-hook-message .success-message,.test-hook-message .error-message{display:none;margin-top:10px}.test-hook-message.success .success-message{display:block}.test-hook-message.error .error-message{display:block}.item-name{float:left;font-weight:600}.integration-meta-head{font-size:16px;color:#586069}.integrations-select-repos{max-height:138px;overflow-y:scroll;border-radius:3px}.integrations-select-repos .mini-repo-list-item{padding:8px 64px 8px 30px}.integrations-select-repos .mini-repo-list-item:hover .repo,.integrations-select-repos .mini-repo-list-item:hover .owner{text-decoration:none}.integrations-select-repos .mini-repo-list-item .css-truncate-target{max-width:345px}.integrations-select-repos::-webkit-scrollbar{width:10px}.integrations-select-repos::-webkit-scrollbar-thumb{background-color:rgba(0,0,0,0.5);border:solid #fff 2px;border-radius:6px;box-shadow:0 0 1px rgba(255,255,255,0.5)}.integrations-select-repos::-webkit-scrollbar-track-piece{background:transparent}.integrations-repository-picker{position:relative;top:-5px;width:440px}.integrations-repository-picker .select-menu-modal{width:440px}.integrations-repository-picker .autocomplete-results{border:0}.integrations-repository-picker .select-menu .search-status{display:none}.integrations-repository-picker .select-menu.is-loading .search-status{display:block}.integrations-repository-picker .subnav-search{margin-bottom:5px;margin-left:0}.integrations-repository-picker .flash{padding:10px;margin-bottom:10px}dl.form-group>dd .integrations-repository-picker .form-control{margin-right:0}.integrations-repository-picker .octicon-x{position:absolute;top:8px;right:10px;cursor:pointer}.target-avatar{position:relative;top:-2px}.issue-list em{padding:3px;font-style:normal;font-weight:600;background-color:rgba(255,255,140,0.5);border-radius:3px}.issue-list .title{min-height:24px;padding:0;margin:0 80px 10px 0;font-size:18px;font-weight:400;line-height:24px;word-wrap:break-word}.issue-list .title .octicon{position:absolute;top:-4px;left:0;color:#888}.issue-list .title .closed.octicon{color:#cb2431}.issue-list .title .open.octicon{color:#28a745}.issue-list .title .merged.octicon{color:#6f42c1}.issue-list .description{margin:0 0 10px;overflow:hidden;line-height:20px}.issue-list-item+.issue-list-item{border-top:1px #e1e4e8 solid}.issues-reset-query-wrapper{margin-bottom:20px}.label-link:hover{text-decoration:none}.issues-reset-query{font-weight:600;color:#586069}.issues-reset-query:hover{color:#0366d6;text-decoration:none}.issues-reset-query:hover .issues-reset-query-icon{background-color:#0366d6}.issues-reset-query-icon{width:18px;height:18px;padding:1px;margin-right:3px;color:#fff;text-align:center;background-color:#6a737d;border-radius:3px}.table-list-milestones .table-list-cell{padding:15px 20px}.table-list-milestones .stat{display:inline-block;font-size:14px;font-weight:600;line-height:1.2;color:#555;white-space:nowrap}.table-list-milestones .stat a{color:inherit}.table-list-milestones .stat+.stat{margin-left:15px}.table-list-milestones .stat-label{font-weight:400;color:#586069}.milestone-title{width:500px}.milestone-title-link{margin-top:0;margin-bottom:5px;font-size:24px;font-weight:400;line-height:1.2}.milestone-title-link a{color:#333}.milestone-title-link a:hover{color:#0366d6}.milestone-progress{width:420px}.milestone-progress .progress-bar{margin-top:7px;margin-bottom:12px}.milestone-meta{font-size:14px}.milestone-meta-item{display:inline-block;margin-right:10px}.milestone-meta-item .octicon{width:16px;text-align:center}.milestone-description-html{display:none}.milestone-description{margin-top:5px}.milestone-description .expand-more{color:#0366d6;cursor:pointer}.milestone-description .expand-more:hover{text-decoration:underline}.milestone-description.open .milestone-description-plaintext{display:none}.milestone-description.open .milestone-description-html{display:block}.issue-reorder-warning{z-index:110}.task-progress{color:#586069;text-decoration:none;vertical-align:top}.task-progress .octicon{margin-right:5px;color:#999;vertical-align:bottom}.task-progress .progress-bar{display:inline-block;width:80px;height:5px;vertical-align:2px;background-color:#eee}.task-progress .progress-bar .progress{background-color:#ccc}.task-progress-counts{display:inline-block;margin-right:6px;margin-left:-2px;font-size:12px}a.task-progress:hover{color:#0366d6}a.task-progress:hover .octicon{color:inherit}a.task-progress:hover .progress-bar .progress{background-color:#0366d6}.issues-listing{position:relative}.issues-listing .octocat-search{position:absolute;right:0;height:250px;margin:-132px -4px;transform:scaleX(-1)}.issue-meta-section .octicon{color:#ccc;vertical-align:bottom}.issue-milestone{max-width:240px}.issue-milestone .css-truncate-target{max-width:100px}.milestone-link .octicon{font-size:14px}.milestone-link:hover .octicon{color:inherit}.new-issue-form{padding-top:20px;margin-top:15px;border-top:1px solid #ddd}.new-issue-form::before{display:table;content:""}.new-issue-form::after{display:table;clear:both;content:""}.new-issue-form .discussion-timeline::before{display:none}.new-pr-form{margin-top:15px;margin-bottom:20px}.new-pr-form::before{display:table;content:""}.new-pr-form::after{display:table;clear:both;content:""}.new-pr-form .discussion-timeline::before{display:none}.new-pr-form .discussion-sidebar{position:relative}.label-select-menu .description{margin-left:19px}.label-select-menu .color{display:inline-block;width:14px;height:14px;margin-top:-1px;margin-right:2px;vertical-align:middle;border-radius:3px}.label-select-menu .selected .select-menu-item-icon{color:inherit !important}.label-select-menu .selected:active{background-color:transparent !important}.label-select-menu .select-menu-item{position:relative}.label-select-menu .select-menu-item[aria-selected="true"],.label-select-menu .select-menu-item.navigation-focus{color:inherit;background-color:#f4f4f4}.label-select-menu .select-menu-item[aria-selected="true"] .select-menu-item-icon,.label-select-menu .select-menu-item.navigation-focus .select-menu-item-icon{color:transparent}.label-select-menu>form{position:relative}.closed-banner{height:7px;margin:15px 0 15px 60px;overflow:hidden;background:url("/images/modules/comments/closed_pattern.gif");border-radius:3px}.subnav .btn+.issues-search{padding-right:10px;border-right:1px solid #eee}.reaction-sort-item{float:left;width:39px;padding:5px;margin-top:5px;text-align:center;pointer-events:all;border:solid 1px transparent;border-radius:3px;opacity:0.7}.reaction-sort-item:hover,.reaction-sort-item.selected:hover,.reaction-sort-item[aria-selected="true"],.reaction-sort-item.navigation-focus{text-decoration:none;background-color:#0366d6;opacity:1}.reaction-sort-item.selected{background-color:#f1f8ff;border-color:#0366d6;opacity:1}body.emoji-size-boost .reaction-sort-item g-emoji{margin-left:-3px}@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-moz-min-device-pixel-ratio: 2), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx){body.emoji-size-boost .reaction-sort-item g-emoji{margin-left:0}}.issue-keyword{border-bottom:1px dotted #959da5}.issue-keyword:hover{border-bottom:0}.new-label-color-dimensions{width:24px;height:24px}.select-menu-item[aria-selected="true"]>.octicon.label-options-icon,.select-menu-item.navigation-focus>.octicon.label-options-icon{color:#24292e}.new-label-color-input:invalid{color:#cb2431}.repository-lang-stats{position:relative}.repository-lang-stats ol.repository-lang-stats-numbers li{display:table-cell;width:1%;padding:10px 5px;text-align:center;white-space:nowrap;border-bottom:0}.repository-lang-stats ol.repository-lang-stats-numbers li span.percent{float:none}.repository-lang-stats ol.repository-lang-stats-numbers li>a,.repository-lang-stats ol.repository-lang-stats-numbers li>span{font-weight:600;color:#6a737d;text-decoration:none}.repository-lang-stats ol.repository-lang-stats-numbers li .lang{color:#24292e}.repository-lang-stats ol.repository-lang-stats-numbers li .language-color{display:inline-block;width:10px;height:10px;border-radius:50%}.repository-lang-stats ol.repository-lang-stats-numbers li a:hover{background:transparent}.stats-switcher-viewport{height:41px;overflow:hidden}.stats-switcher-viewport .stats-switcher-wrapper{position:relative;top:0;transition:top 0.25s ease-in-out}.stats-switcher-viewport.is-revealing-lang-stats .stats-switcher-wrapper{top:-41px}.stats-switcher-viewport.is-revealing-overview .stats-switcher-wrapper{top:41px}.repository-lang-stats-graph{width:100%;overflow:hidden;white-space:nowrap;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border:1px solid #ddd;border-top:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.repository-lang-stats-graph .language-color{line-height:8px;text-indent:-9999px}.repository-lang-stats-graph .language-color:first-child{border-bottom-left-radius:2px}.repository-lang-stats-graph .language-color:last-child{border-bottom-right-radius:2px}.facebox-loading,.octocat-spinner{min-height:64px;background-image:url("/images/spinners/octocat-spinner-64.gif");background-repeat:no-repeat;background-position:center center}@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-moz-min-device-pixel-ratio: 2), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx){.facebox-loading,.octocat-spinner{background-image:url("/images/spinners/octocat-spinner-128.gif");background-size:64px 64px}}.MarketplaceJumbotron{background-color:#2f363d;background-image:url("/images/modules/marketplace/bg-hero.svg");background-repeat:repeat-y;background-position:center top;background-size:150% auto}@media (min-width: 768px){.MarketplaceJumbotron{background-repeat:no-repeat;background-size:cover}}.CircleBadge--feature{position:relative;top:0;transition:top 0.15s ease-in, box-shadow 0.12s ease-in}.MarketplaceFeature-wrap{-webkit-overflow-scrolling:touch;overflow-x:auto}.MarketplaceFeature{min-width:250px}.MarketplaceFeature-text{opacity:0.7;transition:opacity 0.12s ease-in}.MarketplaceFeature-link:hover .CircleBadge--feature{top:-3px;box-shadow:0 3px 8px 0 rgba(0,0,0,0.2)}.MarketplaceFeature-link:hover .MarketplaceFeature-text{opacity:1}.MarketplaceFeature-link:active .CircleBadge--feature{top:0;box-shadow:0}.MarketplaceSideNav{-webkit-overflow-scrolling:touch;background-color:#f6f8fa}@media (min-width: 768px){.MarketplaceSideNav{background-color:#fff;border-right:1px #e1e4e8 solid}}.ScreenshotCarousel{border:1px #e1e4e8 solid;border-radius:3px}.ScreenshotCarousel-screenshot{display:none;padding:16px}.ScreenshotCarousel-screenshot.active{display:block}.ScreenshotCarousel-nav{display:flex;overflow-x:auto;align-items:top;box-shadow:inset 0 1px 0 #e1e4e8}.ScreenshotCarousel-navitem{width:20%;min-width:120px;padding:16px;cursor:pointer;border-right:1px #e1e4e8 solid}.ScreenshotCarousel-navitem:last-child{border-right:0}.ScreenshotCarousel-navitem.selected{background-color:#f6f8fa;box-shadow:inset 0 0 4px rgba(36,41,46,0.15)}.marketplace-plan-edit-unit,.marketplace-plan-edit-unit-label,.marketplace-plan-edit-price{display:none}.marketplace-plan-enable-free-trial{display:none}.marketplace-plan-editor[data-model="FLAT_RATE"] .marketplace-plan-edit-price{display:block}.marketplace-plan-editor[data-model="FLAT_RATE"] .marketplace-plan-enable-free-trial{display:block}.marketplace-plan-editor[data-model="PER_UNIT"] .marketplace-plan-edit-price,.marketplace-plan-editor[data-model="PER_UNIT"] .marketplace-plan-edit-unit{display:block}.marketplace-plan-editor[data-model="PER_UNIT"] .marketplace-plan-edit-unit-label{display:inline}.marketplace-plan-editor[data-model="PER_UNIT"] .marketplace-plan-enable-free-trial{display:block}.marketplace-listing-screenshot-container{width:175px;min-height:175px;background-repeat:no-repeat;background-position:center center;background-size:cover}.marketplace-listing-screenshot-container .marketplace-listing-screenshot{min-width:100%;min-height:100%;opacity:0}.marketplace-listing-screenshot-zoom{display:none;cursor:move}.marketplace-listing-details-sidebar{order:2}@media (min-width: 768px){.marketplace-listing-details-sidebar{order:1}}.marketplace-listing-details-description{order:1}@media (min-width: 768px){.marketplace-listing-details-description{order:2}}.marketplace-listing-screenshot-link{height:100px;cursor:move}.marketplace-listing-screenshot-link:hover .marketplace-listing-screenshot-zoom,.marketplace-listing-screenshot-link:focus .marketplace-listing-screenshot-zoom{top:0;left:0;display:block;width:100%;height:100%;padding-top:28px;background-color:rgba(255,255,255,0.75)}.marketplace-integratable-logo{width:40px;height:40px}.marketplace-listing-save-notice,.marketplace-listing-save-error{display:none;opacity:0;transition:opacity 0.15s linear}.marketplace-listing-save-notice.visible,.marketplace-listing-save-error.visible{display:inline-block;opacity:1}.marketplace-listing-screenshot-delete-form{position:absolute;bottom:-24px;width:100%;text-align:center}.marketplace-plan-dollar-field-container .price-note{display:none}.marketplace-plan-dollar-field-container.is-errored .price-note{display:block}.marketplace-plan-dollar-field-container.is-errored .form-control{border-color:#d73a49}.marketplace-plan-emphasis{color:#24292e}.selected .marketplace-plan-emphasis{color:#fff}.marketplace-plan-unit-name-preview::before{content:"per "}.marketplace-plan-per-time{clear:right}.marketplace-billing-modal{width:540px;max-height:90vh}.marketplace-listing-markdown,.marketplace-url-link{word-wrap:break-word;white-space:pre-wrap}.marketplace-listing-markdown{line-height:1.4}.integrations-promo-bg{background-image:url("/images/modules/works-with/build-your-own.svg");background-repeat:no-repeat;background-size:0 0}@media (min-width: 544px){.integrations-promo-bg{background-position:top right;background-size:auto 100%}}.marketplace-product-callout{border-color:#d1d5da !important}.marketplace-product-callout::before,.marketplace-product-callout::after{display:none}.marketplace-product-callout .branch-action-item-icon{color:#586069;background-color:#e1e4e8}.filter-item.selected .Label--outline-white{color:#fff;border-color:#fff}.MarketplaceEdit-body{min-height:570px}.MarketplaceEdit-body .pricing-model-selector{width:calc(100% - 12px);max-width:100% !important}.MarketplaceEdit-body .Box-row--pending{box-shadow:2px 0 0 #f9c513 inset}.MarketplaceEdit-body .menu{border-right:0;border-left:0;border-radius:0}.MarketplaceEdit-body .menu-item{padding:12px 16px;background:#fafbfc}.MarketplaceEdit-body .menu-item.selected{background:#fff}.MarketplaceEdit-body .menu-item:hover{background:#f6f8fa}.MarketplaceEdit-body .menu-item.selected::before{position:absolute;top:0;bottom:0;left:0;width:3px;content:"";background-color:#f66a0a}.MarketplaceEdit-body .menu-item:first-child::before{border-top-left-radius:0}.MarketplaceEdit-body .CircleIcon{display:inline-block;width:32px;height:32px;font-weight:bold;line-height:32px;color:#586069;text-align:center;background:#e6ebf1;border-radius:100%}.MarketplaceEdit-body .CircleIcon .octicon{display:inline-block}.MarketplaceEdit-body .CircleIcon--success{color:#fff;background:#28a745}.MarketplaceInsights-graph .insights-month .tick:nth-child(2n){visibility:hidden}.CircleBadge--tiny{width:32px;height:32px}.CircleBadge--github{position:relative}.CircleBadge--github.CircleBadge--large::after{right:5px;bottom:5px}.CircleBadge--github.CircleBadge--small::after{right:-5px;bottom:-5px}.CircleBadge--github::after{position:absolute;right:0;bottom:0;display:block;width:22px;height:22px;padding:3px;line-height:0;content:"";background:#fff url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHdpZHRoPSIyMnB4IiBoZWlnaHQ9IjIycHgiIHZpZXdCb3g9IjAgMCAyMiAyMiIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4gICAgICAgIDx0aXRsZT5TaGFwZSBDb3B5PC90aXRsZT4gICAgPGRlc2M+Q3JlYXRlZCB3aXRoIFNrZXRjaC48L2Rlc2M+ICAgIDxkZWZzPjwvZGVmcz4gICAgPGcgaWQ9IktpdGNoZW4tc2luayIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+ICAgICAgICA8ZyBpZD0iT2N0aWNvbnMiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0zNzAuMDAwMDAwLCAtMTU4NC4wMDAwMDApIiBmaWxsPSIjMUIxRjIzIj4gICAgICAgICAgICA8cGF0aCBkPSJNMzgxLDE1ODQgQzM3NC45MjI1LDE1ODQgMzcwLDE1ODguOTIyNSAzNzAsMTU5NSBDMzcwLDE1OTkuODY3NSAzNzMuMTQ4NzUsMTYwMy45Nzg3NSAzNzcuNTIxMjUsMTYwNS40MzYyNSBDMzc4LjA3MTI1LDE2MDUuNTMyNSAzNzguMjc3NSwxNjA1LjIwMjUgMzc4LjI3NzUsMTYwNC45MTM3NSBDMzc4LjI3NzUsMTYwNC42NTI1IDM3OC4yNjM3NSwxNjAzLjc4NjI1IDM3OC4yNjM3NSwxNjAyLjg2NSBDMzc1LjUsMTYwMy4zNzM3NSAzNzQuNzg1LDE2MDIuMTkxMjUgMzc0LjU2NSwxNjAxLjU3MjUgQzM3NC40NDEyNSwxNjAxLjI1NjI1IDM3My45MDUsMTYwMC4yOCAzNzMuNDM3NSwxNjAwLjAxODc1IEMzNzMuMDUyNSwxNTk5LjgxMjUgMzcyLjUwMjUsMTU5OS4zMDM3NSAzNzMuNDIzNzUsMTU5OS4yOSBDMzc0LjI5LDE1OTkuMjc2MjUgMzc0LjkwODc1LDE2MDAuMDg3NSAzNzUuMTE1LDE2MDAuNDE3NSBDMzc2LjEwNSwxNjAyLjA4MTI1IDM3Ny42ODYyNSwxNjAxLjYxMzc1IDM3OC4zMTg3NSwxNjAxLjMyNSBDMzc4LjQxNSwxNjAwLjYxIDM3OC43MDM3NSwxNjAwLjEyODc1IDM3OS4wMiwxNTk5Ljg1Mzc1IEMzNzYuNTcyNSwxNTk5LjU3ODc1IDM3NC4wMTUsMTU5OC42MyAzNzQuMDE1LDE1OTQuNDIyNSBDMzc0LjAxNSwxNTkzLjIyNjI1IDM3NC40NDEyNSwxNTkyLjIzNjI1IDM3NS4xNDI1LDE1OTEuNDY2MjUgQzM3NS4wMzI1LDE1OTEuMTkxMjUgMzc0LjY0NzUsMTU5MC4wNjM3NSAzNzUuMjUyNSwxNTg4LjU1MTI1IEMzNzUuMjUyNSwxNTg4LjU1MTI1IDM3Ni4xNzM3NSwxNTg4LjI2MjUgMzc4LjI3NzUsMTU4OS42Nzg3NSBDMzc5LjE1NzUsMTU4OS40MzEyNSAzODAuMDkyNSwxNTg5LjMwNzUgMzgxLjAyNzUsMTU4OS4zMDc1IEMzODEuOTYyNSwxNTg5LjMwNzUgMzgyLjg5NzUsMTU4OS40MzEyNSAzODMuNzc3NSwxNTg5LjY3ODc1IEMzODUuODgxMjUsMTU4OC4yNDg3NSAzODYuODAyNSwxNTg4LjU1MTI1IDM4Ni44MDI1LDE1ODguNTUxMjUgQzM4Ny40MDc1LDE1OTAuMDYzNzUgMzg3LjAyMjUsMTU5MS4xOTEyNSAzODYuOTEyNSwxNTkxLjQ2NjI1IEMzODcuNjEzNzUsMTU5Mi4yMzYyNSAzODguMDQsMTU5My4yMTI1IDM4OC4wNCwxNTk0LjQyMjUgQzM4OC4wNCwxNTk4LjY0Mzc1IDM4NS40Njg3NSwxNTk5LjU3ODc1IDM4My4wMjEyNSwxNTk5Ljg1Mzc1IEMzODMuNDIsMTYwMC4xOTc1IDM4My43NjM3NSwxNjAwLjg1NzUgMzgzLjc2Mzc1LDE2MDEuODg4NzUgQzM4My43NjM3NSwxNjAzLjM2IDM4My43NSwxNjA0LjU0MjUgMzgzLjc1LDE2MDQuOTEzNzUgQzM4My43NSwxNjA1LjIwMjUgMzgzLjk1NjI1LDE2MDUuNTQ2MjUgMzg0LjUwNjI1LDE2MDUuNDM2MjUgQzM4OC44NTEyNSwxNjAzLjk3ODc1IDM5MiwxNTk5Ljg1Mzc1IDM5MiwxNTk1IEMzOTIsMTU4OC45MjI1IDM4Ny4wNzc1LDE1ODQgMzgxLDE1ODQgTDM4MSwxNTg0IFoiIGlkPSJTaGFwZS1Db3B5Ij48L3BhdGg+ICAgICAgICA8L2c+ICAgIDwvZz48L3N2Zz4=") center no-repeat;border-radius:100px}body.min-width-0.page-responsive .flash-full .container{width:100%;max-width:980px}.member-list-item .table-list-cell-checkbox{width:30px}.member-list-item.adminable .member-info{padding-left:5px}.member-list-item .member-avatar-cell{width:58px}.member-list-item .dropdown-menu-content{text-align:left}.member-info{width:450px}.member-info .css-truncate-target{max-width:430px}.member-meta .select-menu-modal{width:310px}.member-meta .select-menu-modal-holder{right:0;text-align:left}.triage-mode .none-selected{display:none}.member-role-menu .select-menu-item-text{padding-right:8px}.merge-branch-heading{margin:0;line-height:1;color:#24292e}.merge-branch-description{margin-right:160px;margin-bottom:-5px;line-height:1.6em;color:#586069}.merge-branch-description .zeroclipboard-link .octicon{top:2px}.alt-merge-options{display:inline-block;margin-bottom:0;margin-left:4px;vertical-align:middle}.merged .merge-branch-description .commit-ref .css-truncate-target{max-width:180px}.merge-branch-prh-output{margin-top:10px}.merge-branch-form{display:none;padding-left:64px}.merge-branch.open .merge-branch-form{display:block}.merge-branch.open .merge-message{display:none}.merge-branch-manually{display:none;padding-top:15px;margin-top:14px;background-color:transparent;border-top:1px solid #ddd}.merge-branch-manually p{margin-bottom:0}.merge-branch-manually h3{margin-bottom:10px}.merge-branch-manually .intro{padding-bottom:10px;margin-top:0}.merge-branch-manually .step{margin:15px 0 5px}.merge-branch-manually .url-box{padding:0;margin-left:0;border:0}.merge-branch-manually .copyable-terminal{background-color:#f2f2f2}.open .merge-branch-manually{display:block}.select-menu-merge-method{width:310px}.merge-pr.is-rebasing .commit-form-fields{margin-top:-110px;opacity:0;transition:opacity 0.15s linear 0s, margin-top 0.25s ease 0.1s}.merge-pr .btn-group-merge,.merge-pr.is-squashing .btn-group-squash,.merge-pr.is-rebasing .btn-group-rebase{display:inline-block}.merge-pr .merging-body,.merge-pr .rebasing-body,.merge-pr .squashing-body{display:none}.merge-pr.is-merging .merging-body,.merge-pr.is-rebasing .rebasing-body,.merge-pr.is-squashing .squashing-body{display:block}.merge-pr .btn-group-squash,.merge-pr .btn-group-rebase,.merge-pr.is-squashing .btn-group-merge,.merge-pr.is-rebasing .btn-group-merge{display:none;margin-left:0}.commit-form-fields{transition:opacity 0.15s linear 0.1s, margin-top 0.25s ease 0s}.unavailable-merge-method{display:block;margin-top:6px;color:#a04100}[aria-selected="true"].disabled .unavailable-merge-method,.navigation-focus.disabled .unavailable-merge-method{color:#fff}.network .network-tree{vertical-align:middle}.network .gravatar{margin-right:4px;vertical-align:middle;border-radius:3px}.network .octicon{display:inline-block;width:16px;margin-left:2px;text-align:center;vertical-align:middle}.network .current-repository{background-color:#fff5b1}.page-new-repo .octicon-repo{color:#959da5}.page-new-repo .octicon-lock{color:rgba(115,92,15,0.5)}.page-new-repo ul.repo-templates{margin:10px 0}.page-new-repo ul.repo-templates>li{display:inline-block;margin:0 10px 0 0;list-style-type:none}.page-new-repo ul.repo-templates .select-menu{float:left}.page-new-repo .form-checkbox .octicon{float:left;margin-right:5px}.page-new-repo .form-checkbox.disabled{color:#6a737d}.page-new-repo .license-info{float:left;margin-top:5px;margin-left:10px;color:#0366d6}.new-repo-container{width:700px;margin:40px auto 0}.new-repo-container .Subhead{margin-bottom:30px}.owner-reponame dl.form-group{margin-top:5px;margin-bottom:0}.owner-reponame .slash{float:left;padding-top:32px;margin:0 8px;font-size:21px;color:#586069}.reponame-suggestion{color:#34631a;cursor:pointer}.upgrade-upsell{padding-left:33px}.cc-upgrade{padding-left:20px}.featured-license{font-weight:600}.license-container{padding-left:15px;border-left:1px solid #ccc}.news .account-switcher{margin-bottom:20px}.news .release{margin-top:0;margin-bottom:0}.news blockquote{color:#586069}.news h1{margin-bottom:0}.news .alert{position:relative;padding:0 0 1em 45px;overflow:hidden;border-top:1px solid #eff3f6}.news .alert .commits{padding-left:40px}.news .alert .css-truncate.css-truncate-target,.news .alert .css-truncate .css-truncate-target{max-width:180px}.news .alert p{margin:0}.news .alert .markdown-body blockquote{padding:0 0 0 40px;border:0 none}.news .alert .octicon{color:#959da5}.news .alert .dashboard-event-icon{position:absolute;top:18px;left:22px;transform:translateX(-50%)}.news .alert .body{padding:1em 0 0;overflow:hidden;font-size:14px;border-bottom:0}.news .alert .time{font-size:12px;color:#959da5}.news .alert .title{padding:0;font-weight:600}.news .alert .title .subtle{color:#959da5}.news .alert .gravatar{float:left;margin-right:0.6em;line-height:0;background-color:#fff;border-radius:3px}.news .alert .simple .title{display:inline-block;font-size:13px;font-weight:400;color:#586069}.news .alert .simple .time{display:inline-block}.news .alert .branch-link{position:relative;top:-2px;margin:0;font-family:"SFMono-Regular",Consolas,"Liberation Mono",Menlo,Courier,monospace;color:#4183c4}.news .alert .branch-link .octicon{display:none}.news .alert:first-child{border-top:0}.news .alert:first-child .body{padding-top:0}.news .alert:first-child .dashboard-event-icon{top:0}.news .github-welcome .done{color:#586069;text-decoration:line-through}.news .commits li{margin-top:0.15em;list-style-type:none}.news .commits li.more{padding-top:2px;font-size:11px}.news .commits li .committer{display:none;padding-left:0.5em}.news .commits li img{margin:0 1px 0 0;vertical-align:middle;background-color:#fff;border-radius:2px}.news .commits li img.emoji{padding:0;margin:0;border:0}.news .commits li .message{display:inline-block;max-width:390px;margin-top:2px;overflow:hidden;font-size:13px;line-height:1.3;text-overflow:ellipsis;white-space:nowrap;vertical-align:top}.news div.message,.news li blockquote{display:inline;font-size:13px;color:#586069}.notification-routing .notification-email .edit-link{margin-right:10px;font-weight:600}.notification-routing .notification-email .btn-sm{float:none;margin:-2px 0 0}.notification-routing .notification-email .edit-form{display:none}.notification-routing .notification-email.open .edit-form{display:block}.notification-routing .notification-email.open .email-display{display:none}.notifications .list-group-item{padding-top:8px;padding-bottom:8px;padding-left:35px;border-width:1px 0 0}.notifications .list-group-item:first-child{border:0}.notifications .list-group-item-name{display:block;max-width:400px;font-size:14px;line-height:1.5em}.notifications .list-group-item-name a{display:block;max-width:460px}.notifications .notifications-more{padding:0}.notifications .notifications-more>a{display:block;padding:10px 15px;font-weight:600;color:#0366d6;text-align:center}.notifications .notifications-more>a:hover{text-decoration:underline}.notifications .read .type-icon{color:#586069}.notifications .read .list-group-item-name>a{color:#586069}.notifications .read .notification-actions{color:#586069}.notifications .read .avatar-stack{opacity:0.5}.notifications .read .undo{display:block}.notifications .read .delete{visibility:hidden}.notifications .read[aria-selected="true"],.notifications .read.navigation-focus{background-color:#f5f9fc}.notifications .muted .unmute{display:block}.notifications .muted .mute{display:none}.notifications .unmute{display:none}.notifications-sso-prompt{padding:0}.notifications-sso-prompt[aria-selected="true"],.notifications-sso-prompt.navigation-focus{background-color:#f5f9fc}.notifications-sso-prompt a{display:block;padding:10px 15px;color:#586069;text-align:center;background:none;border:0;outline:none}.notifications-sso-prompt a:hover{text-decoration:none}.notifications-sso-prompt em{font-style:normal;color:#0366d6}.notifications-sso-prompt a:hover em{text-decoration:underline}.notifications-sso-prompt strong{font-weight:bold}.type-icon-state-none{color:#586069}.type-icon-state-open{color:#28a745}.type-icon-state-closed{color:#cb2431}.type-icon-state-merged{color:#6f42c1}.notifications-list{float:left;width:100%}.notifications-list .notifications-repo-link{max-width:500px}.notifications-list .boxed-group .notification-success{position:absolute;right:3px;width:220px;margin-top:4px;font-size:13px;color:#28a745;text-align:right;visibility:hidden;opacity:0;transition:opacity 0.35s ease-in-out, transform 0.35s ease-in-out;transform:translateX(10px)}.notifications-list .mark-all-as-read{padding:2px 6px 5px 10px;margin-top:0;margin-right:0;line-height:20px;color:#586069;background-color:transparent;border:0}.notifications-list .mark-all-as-read-confirmed .notification-success{visibility:visible;opacity:1;transform:translateX(0)}.notifications-list .mark-all-as-read-confirmed .mark-all-as-read{visibility:hidden}.notifications-list .confirmation{max-height:0;padding:0;overflow:hidden;color:#666;text-align:center;opacity:0;transition:opacity 0.4s ease-in-out, max-height 0.4s ease-in-out, padding 0.4s ease-in-out}.notifications-list .confirmation+.list-group-item{margin-top:-1px;border-top-color:#d5d5d5}.notifications-list .confirmation.mark-all-as-read-confirmed{max-height:300px;padding:10px 0;opacity:1}.notification-actions{position:absolute;top:8px;right:10px;list-style:none}.notification-actions li{float:right;margin-left:10px;font-size:16px;line-height:20px}.notification-actions .age{width:120px;font-size:12px;color:#586069}.notification-actions .undo{position:absolute;top:0;display:none}.notification-actions .btn-link{padding-right:5px;padding-left:5px;line-height:inherit;color:#586069}.notification-actions .btn-link:hover{color:#0366d6;text-decoration:none}.repo-subscription-container{width:600px;margin-right:auto;margin-left:auto}.repo-subscription-container .spinner{float:right}.repo-subscription-container h2{margin-top:24px;margin-bottom:16px;font-size:22px;font-weight:400}.repo-subscription-container .intro{font-size:14px;color:#666}.repo-subscription-label{display:inline-block}.subscriptions-content .repo-icon{margin-right:5px;color:#666;vertical-align:middle}.subscriptions-content .repo-list form{display:inline}.subscriptions-content .repo-list .only-loading{display:none}.subscriptions-content .repo-list .loading .only-loading{display:inline-block}.subscriptions-content .repo-list .only-unsubed{display:none}.subscriptions-content .repo-list .unsubscribed .only-unsubed{display:inline}.subscriptions-content .repo-list .unsubscribed .only-subed{display:none}.subscriptions-content .repo-list .only-unignored{display:none}.subscriptions-content .repo-list .unsubscribed .only-unignored{display:inline}.subscriptions-content .repo-list .unsubscribed .only-ignored{display:none}.thread-subscription-status{padding:10px;margin:40px 0 20px;color:#586069;background-color:#fff;border:1px solid #eee;border-radius:3px}.thread-subscription-status .octicon-radio-tower{margin-right:10px;margin-left:4px;color:#ccc;vertical-align:middle}.thread-subscription-status .btn-sm>.octicon{margin-right:1px}.thread-subscription-status .reason{display:inline-block;margin:0 10px;vertical-align:middle}.thread-subscription-status .thread-subscribe-form{display:inline-block;vertical-align:middle}.subscription .loading{opacity:0.5}.oauth-permissions-details{position:relative;padding:15px;margin:0;list-style:none;border-bottom:1px solid #f2f2f2}.oauth-permissions-details:first-child{border-radius:3px 3px 0 0}.oauth-permissions-details:last-child{border:0;border-radius:0 0 3px 3px}.oauth-permissions-details.oauth-public-data-only{border-radius:3px}.oauth-permissions-details .markdown-body{font-size:13px}.oauth-permissions-details .content{display:none;margin-left:45px}.oauth-permissions-details .content .form-checkbox{margin-left:0}.oauth-permissions-details .content .form-checkbox:last-child{margin-bottom:0}.oauth-permissions-details .octicon{float:left;color:#586069;text-align:center}.oauth-permissions-details .permission-help{font-size:13px}.oauth-permissions-details .permission-help ul{padding-left:20px;margin:1em 0}.oauth-permissions-details .permission-summary{margin-left:45px}.oauth-permissions-details .permission-summary .access-details{position:relative;color:#586069}.oauth-permissions-details .permission-summary em.highlight{position:relative;padding:2px 3px;margin-right:-2px;margin-left:-3px;font-style:normal;color:#4c4a42;background:#fff9ea;border-radius:3px}.oauth-permissions-details .permission-title{display:block;color:#000}.oauth-permissions-details a.btn-sm{float:right;margin-top:4px}.oauth-permissions-details.open a.btn-sm{background-color:#dcdcdc;background-image:none;border-color:#b5b5b5;box-shadow:inset 0 2px 4px rgba(0,0,0,0.15)}.oauth-permissions-details.open .content{display:block}.oauth-permissions-details.default:not(.delete) .no-access,.oauth-permissions-details.default:not(.delete) .default-access,.oauth-permissions-details.none .no-access,.oauth-permissions-details.none .default-access{display:inline}.oauth-permissions-details.default:not(.delete) .access-details,.oauth-permissions-details.default:not(.delete) .permission-title,.oauth-permissions-details.none .access-details,.oauth-permissions-details.none .permission-title{color:#6a737d}.oauth-permissions-details.default:not(.delete) .octicon,.oauth-permissions-details.none .octicon{color:#ccc}.oauth-permissions-details.default .default-access{display:inline}.oauth-permissions-details.full .full-access{display:inline}.oauth-details-toggle{position:absolute;top:0;right:0;padding:20px 15px}.oauth-details-toggle .octicon-chevron-up{display:none}.open .oauth-details-toggle .octicon-chevron-down{display:none}.open .oauth-details-toggle .octicon-chevron-up{display:block}.oauth-user-permissions .full-access,.oauth-user-permissions .limited-access,.oauth-user-permissions .limited-access-emails-followers,.oauth-user-permissions .limited-access-emails-profile,.oauth-user-permissions .limited-access-followers-profile,.oauth-user-permissions .limited-access-profile,.oauth-user-permissions .limited-access-followers,.oauth-user-permissions .limited-access-emails,.oauth-user-permissions .no-access{display:none}.oauth-user-permissions.limited.limited-email .limited-access-emails{display:inline}.oauth-user-permissions.limited.limited-email.limited-profile .limited-access-emails,.oauth-user-permissions.limited.limited-email.limited-profile .limited-access-profile{display:none}.oauth-user-permissions.limited.limited-email.limited-profile .limited-access-emails-profile{display:inline}.oauth-user-permissions.limited.limited-email.limited-profile.limited-follow .limited-access-emails,.oauth-user-permissions.limited.limited-email.limited-profile.limited-follow .limited-access-profile,.oauth-user-permissions.limited.limited-email.limited-profile.limited-follow .limited-access-followers,.oauth-user-permissions.limited.limited-email.limited-profile.limited-follow .limited-access-emails-profile,.oauth-user-permissions.limited.limited-email.limited-profile.limited-follow .limited-access-emails-followers,.oauth-user-permissions.limited.limited-email.limited-profile.limited-follow .limited-access-followers-profile{display:none}.oauth-user-permissions.limited.limited-email.limited-profile.limited-follow .limited-access{display:inline}.oauth-user-permissions.limited.limited-email.limited-follow .limited-access-emails,.oauth-user-permissions.limited.limited-email.limited-follow .limited-access-followers{display:none}.oauth-user-permissions.limited.limited-email.limited-follow .limited-access-emails-followers{display:inline}.oauth-user-permissions.limited.limited-follow .limited-access-followers{display:inline}.oauth-user-permissions.limited.limited-follow.limited-profile .limited-access-followers,.oauth-user-permissions.limited.limited-follow.limited-profile .limited-access-profile{display:none}.oauth-user-permissions.limited.limited-follow.limited-profile .limited-access-followers-profile{display:inline}.oauth-user-permissions.limited.limited-profile .limited-access-profile{display:inline}.oauth-repo-permissions .default-access,.oauth-repo-permissions .public-access,.oauth-repo-permissions .limited-repo-invite-access,.oauth-repo-permissions .full-access{display:none}.oauth-repo-permissions.public .public-access{display:inline}.oauth-delete-repo-permissions .octicon-alert{color:#cb2431}.oauth-repo-status-permissions .no-access,.oauth-repo-status-permissions .full-access,.oauth-repo-deployment-permissions .no-access,.oauth-repo-deployment-permissions .full-access{display:none}.oauth-notifications-permissions .no-access,.oauth-notifications-permissions .read-access,.oauth-notifications-permissions .via-public-access,.oauth-notifications-permissions .via-full-access{display:none}.oauth-notifications-permissions.read .read-access{display:inline}.oauth-notifications-permissions.via-public .via-public-access{display:inline}.oauth-notifications-permissions.via-public .octicon{display:none}.oauth-notifications-permissions.via-full .via-full-access{display:inline}.oauth-gist-permissions .no-access,.oauth-gist-permissions .full-access{display:none}.oauth-granular-permissions .no-access,.oauth-granular-permissions .read-access,.oauth-granular-permissions .write-access,.oauth-granular-permissions .full-access{display:none}.oauth-granular-permissions.none .no-access{display:inline}.oauth-granular-permissions.read .read-access{display:inline}.oauth-granular-permissions.write .write-access{display:inline}.oauth-granular-permissions.full .full-access{display:inline}.oauth-no-description{color:#586069}.oauth-org-access-details a:hover{text-decoration:none}.oauth-org-access-details .boxed-group-inner{border:0;border-radius:3px}.oauth-org-access-details .oauth-org-item{line-height:24px}.oauth-org-access-details .oauth-org-item:first-child{border-radius:3px 3px 0 0}.oauth-org-access-details .oauth-org-item .loading-indicator{display:none;margin:4px}.oauth-org-access-details .oauth-org-item.on{background:#fff}.oauth-org-access-details .oauth-org-item.on:hover{background:#ffe}.oauth-org-access-details .oauth-org-item.on .authorized-tools{display:block}.oauth-org-access-details .oauth-org-item.on .unauthorized-tools{display:none}.oauth-org-access-details .oauth-org-item.on strong{color:#24292e}.oauth-org-access-details .oauth-org-item.on .octicon-check{display:inline}.oauth-org-access-details .oauth-org-item.on .octicon-x{display:none}.oauth-org-access-details .oauth-org-item.revoked{background:#fff}.oauth-org-access-details .oauth-org-item.revoked .unauthorized-tools,.oauth-org-access-details .oauth-org-item.revoked .authorized-tools{display:none}.oauth-org-access-details .oauth-org-item.revoked .octicon-x{color:#cb2431}.oauth-org-access-details .oauth-org-item.loading .unauthorized-tools,.oauth-org-access-details .oauth-org-item.loading .authorized-tools{display:none}.oauth-org-access-details .oauth-org-item.loading .loading-indicator{display:block}.oauth-org-access-details .oauth-org-item .authorized-tools{display:none}.oauth-org-access-details .oauth-org-item .unauthorized-tools{display:block}.oauth-org-access-details .btn{line-height:1.5em}.oauth-org-access-details .octicon{color:#979797}.oauth-org-access-details .octicon-check{display:none;color:#28a745}.oauth-org-access-details .octicon-x{display:inline}.oauth-org-access-details .octicon-x.org-access-denied{color:#cb2431}.permission-title{margin-top:0}.oauth-application-whitelist h2{display:inline-block}.oauth-application-whitelist .request-info{display:block}.oauth-application-whitelist .request-info strong{display:inline-block;color:#24292e}.oauth-application-whitelist .request-info .application-description{display:none}.oauth-application-whitelist .request-info.open .application-description{display:block}.oauth-application-whitelist .avatar{margin-top:0}.oauth-application-whitelist .requestor{font-weight:600}.oauth-application-whitelist .octicon-alert{color:#a04100}.oauth-application-whitelist .octicon-check,.oauth-application-whitelist .approved-request{color:#28a745}.oauth-application-whitelist .denied-request{color:#cb2431}.oauth-application-whitelist .request-indicator{margin-left:10px}.oauth-application-whitelist .edit-link{color:#6a737d}.oauth-application-whitelist .edit-link:hover{color:#0366d6}.oauth-application-whitelist .boxed-group-list{margin-top:1em}.oauth-application-whitelist .boxed-group-list li{padding:10px}.boxed-group-inner .oauth-application-info{margin-bottom:10px}.oauth-application-info .application-title{font-size:30px;color:#24292e}.oauth-application-info .application-description{margin-top:3px;margin-bottom:0}.oauth-application-info .app-info{display:inline-block;margin-right:10px;color:#6a737d}.oauth-application-info .app-info .octicon{margin-right:5px}.oauth-application-info .listgroup-item{line-height:inherit}.oauth-application-info .app-denied,.oauth-application-info .app-approved{margin-left:10px;font-size:13px;font-weight:400;white-space:nowrap}.oauth-application-info .app-approved,.oauth-application-info .octicon-check{color:#28a745}.oauth-application-info .app-denied,.oauth-application-info .octicon-x{color:#a04100}.restrict-oauth-access-button{margin-right:20px}.restrict-oauth-access-info{margin-bottom:40px;font-size:15px}.restrict-oauth-access-list{padding-left:25px}.restrict-oauth-access-list li{margin-bottom:10px}.restrict-oauth-access-list li:last-child{margin-bottom:0}.app-transfer-actions form{display:inline}.oauth-border{border-bottom:1px solid #e5e5e5}.oauth-border:last-child{border:0}.developer-app-item .developer-app-avatar-cell{width:60px}.developer-app-item .developer-app-name{font-size:15px;font-weight:600;line-height:1.2;color:#24292e}.developer-app-item .developer-app-name:hover{color:#0366d6;text-decoration:none}.developer-app-item .developer-app-info-cell{padding-left:0}.developer-app-item .developer-app-list-meta{margin-top:3px;margin-bottom:2px;font-weight:400;color:#6a737d}.org-transfer-requests{margin:10px 0 20px}.octocaptcha-element{width:450px;height:310px}.octocaptcha-frame{width:450px;height:340px}.invitation-2fa-banner{margin-right:-24px;margin-left:-24px}.sign-up-via-invitation .bleed-flush{width:100%;padding:0 20px;margin-left:-20px;border-color:#d8dee2}.sign-up-via-invitation label{font-size:13px}.orghead{padding-top:20px;padding-bottom:0;margin-bottom:20px;color:#666;background-color:#fafbfc;border-bottom:1px solid #eee}.orghead .edit-org{position:relative;top:-6px;display:inline-block;padding:3px 5px;font-size:14px;color:#aaa;border:1px solid #e5e5e5;border-radius:3px}.orghead .edit-org:hover{color:#0366d6;background-color:#fff}.orghead .edit-org .octicon{font-size:14px}.orghead .orgnav{position:relative;top:1px;margin-top:10px}.org-header-wrapper .TableObject-item--primary,.org-repos .TableObject-item--primary{white-space:normal}.org-header-wrapper .avatar{display:block;width:100px}.org-header-wrapper .TableObject-item--primary{padding-left:20px}.org-name{font-weight:400;color:#333}.org-description{margin-top:0;margin-bottom:8px;font-size:16px;line-height:1.25}.org-header-meta{font-size:12px;line-height:1.5;list-style:none}.org-header-meta .meta-item{display:inline-block;max-width:100%;padding-right:18px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.org-header-meta .octicon{position:relative;top:1px;margin-right:2px;color:#ccc;vertical-align:text-bottom}.org-header-meta.has-email.has-blog .meta-item,.org-header-meta.has-email.has-location .meta-item,.org-header-meta.has-blog.has-location .meta-item{max-width:278px}.org-header-meta.has-email.has-blog.has-location .meta-item{max-width:186px}.org-profile .member-badge{display:block;padding-top:0;padding-bottom:0;border-top:0}.audit-log-map-container{position:relative;margin-bottom:20px}.audit-log-map-container .activity{position:absolute;top:120px;left:340px;z-index:99999;display:none;text-align:center}.audit-log-map-container .is-graph-loading .activity{display:block}.audit-search-form{position:relative;margin-bottom:20px}.audit-search-form::before{display:table;content:""}.audit-search-form::after{display:table;clear:both;content:""}.audit-search-form .subnav-search-input{width:250px}.audit-log-map{height:277px;overflow:hidden;background-color:#0366d6;border-radius:3px;box-shadow:inset 1px 1px 0 rgba(0,0,0,0.2)}.map-background{pointer-events:all;fill:#0366d6;cursor:-webkit-grab;cursor:grab}.land{fill:none;stroke:#256aae;stroke-width:2;shape-rendering:crispedges}.country{fill:#d7c7ad;shape-rendering:crispedges;cursor:pointer}.country.hk{stroke:#a5967e}.country:hover{fill:#c8b28e}.country.active{fill:#f6e5ca}.borders{fill:none;stroke:#a5967e;shape-rendering:crispedges}.graticule{pointer-events:none;fill:none;stroke:#fff;stroke-opacity:0.2;shape-rendering:crispedges}.graticule :nth-child(2n){stroke-dasharray:2, 2}.security-map-legend circle{fill-opacity:0;stroke:#fff;stroke-width:1.5}.security-map-legend text{font-size:10px;fill:#fff;text-anchor:end}.security-map-legend .link{stroke:#fff;stroke-width:1.5}.audit-point{pointer-events:none;fill:#d73a49;fill-opacity:0.8;stroke:#d73a49}.country-info{position:absolute;top:10px;right:10px;padding:10px;pointer-events:none;background:rgba(255,255,255,0.9);border-radius:2px;opacity:0}.audit-log-search .member-info{width:300px}.audit-log-search .member-info .member-avatar{float:left;margin-right:15px}.audit-log-search .member-info .member-link{display:block}.audit-log-search .member-info .member-list-avatar{margin-right:0}.audit-log-search .member-info .ghost{display:inline-block;color:#586069}.audit-log-search .blankslate{border-top-left-radius:0;border-top-right-radius:0}.audit-log-search .export-phrase{margin:5px 0}.audit-results-actions{overflow:auto}.audit-search-clear{float:left;margin-bottom:20px;border:0}.audit-search-clear .issues-reset-query{margin-bottom:0}.audit-type{width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.audit-type .octicon{margin-right:3px;font-weight:400;vertical-align:bottom}.audit-type .repo{color:#a04100}.audit-type .team{color:#28a745}.audit-type .user{color:#6f42c1}.audit-type .oauth_access{color:#cb2431}.audit-type .hook{color:#e1bf4e}.export-actions{display:inline-block;margin-left:10px}.export-actions a{margin-top:-3px;color:#6a737d}.export-actions a:hover{color:#0366d6;text-decoration:none}.export-actions .select-menu-button::after{position:absolute;top:50%;right:15px;margin-top:-2px}.export-actions .select-menu-modal{width:111px}.export-actions .select-menu-item-text{text-align:center}.export-phrase{margin-top:5px}.export-phrase pre{padding-left:10px;font-family:"SFMono-Regular",Consolas,"Liberation Mono",Menlo,Courier,monospace;white-space:pre-wrap;border-left:1px solid #eee}.audit-log-export-button{width:110px;height:30px;transition:0.25s width ease-in-out}.audit-log-export-button .loader{position:absolute;top:50%;left:11px;display:none;margin-top:-9px}.audit-log-export-button .octicon{position:absolute;top:50%;left:11px;margin-top:-9px}.audit-log-export-button .audit-log-export-status{position:absolute;top:4px;left:35px}.audit-log-export-button.disabled{width:125px}.audit-log-export-button.disabled::after{display:none}.audit-log-export-button.disabled .octicon{display:none}.audit-log-export-button.disabled .loader{display:block}.two-factor-enforcement-form .loading-spinner{float:left;margin:0 0 0 -20px;vertical-align:middle}.saml-enabled-banner-container{background-image:linear-gradient(-1deg, #fff 0%, #f5f5f5 100%)}.saml-settings-form .test-status-indicator{width:30px;height:30px;margin-top:-4px;border-radius:50%}.saml-settings-form .test-status-indicator .octicon{display:block;margin-top:7px;margin-right:auto;margin-left:auto}.saml-settings-form .form-group.errored{margin-bottom:40px}.saml-settings-form .test-status-indicator-error{color:#fff;background-color:#cb2431}.saml-settings-form .test-status-indicator-success{color:#fff;background-color:#28a745}.saml-settings-form .details-container .method-field{display:none}.saml-settings-form .details-container .method-label{font-weight:400}.saml-settings-form .details-container .details-target{cursor:pointer}.saml-settings-form .details-container.open .method-value,.saml-settings-form .details-container.open .details-target{display:none}.saml-settings-form .details-container.open .method-field{display:inline-block}.saml-settings-form .saml-enforcement-disabled{opacity:0.5}.form-group .form-control.saml-certificate-field{width:440px;height:150px;min-height:0}.member-avatar-group{margin:-1px}.member-avatar-group::before{display:table;content:""}.member-avatar-group::after{display:table;clear:both;content:""}.member-avatar{float:left;margin:1px}.member-row{width:100%;min-height:40px;padding-bottom:15px;margin-top:15px;font-size:14px;color:#333;border-bottom:1px solid #eee}.member-row::before{display:table;content:""}.member-row::after{display:table;clear:both;content:""}.member-row a:hover{color:#0366d6;text-decoration:none}.member-row:last-child{padding-bottom:0;border-bottom:0}.member-row .member-name{display:block;padding-left:50px}.member-row .member-fullname{display:block;padding-left:50px;word-wrap:break-word}.member-fullname{color:#586069}.org-toolbar.disabled{pointer-events:none}.org-toolbar .subnav-search{width:320px;margin-right:20px;margin-left:0}.org-toolbar .subnav-search-context+.subnav-search{margin-left:-1px}.org-toolbar .subnav-search-input{width:100%}.org-toolbar-next{margin-bottom:24px}.org-toolbar-next .subnav-search{width:240px}.auto-search-group{position:relative}.auto-search-group .auto-search-input{padding-left:30px}.auto-search-group .spinner,.auto-search-group>.octicon{position:absolute;left:10px;z-index:5;width:16px;height:16px}.auto-search-group .spinner{top:9px;background-color:#fff}.auto-search-group>.octicon{top:10px;font-size:14px;color:#bbb;text-align:center}.org-list .list-item{position:relative;padding-top:15px;padding-bottom:15px;border-bottom:1px solid #eee}.org-list .list-item::before{display:table;content:""}.org-list .list-item::after{display:table;clear:both;content:""}.org-repos .blankslate{margin-top:15px}.org-repos-mini{padding:0;margin:0}.org-repos-mini .org-repo-mini-item:first-child .org-repo-mini-cell{border-top:0}.org-repos-mini .org-repo-name{margin-top:0;margin-bottom:0;font-size:14px;word-wrap:break-word}.org-repos-mini .org-repo-name .octicon-repo{color:#586069}.org-repos-mini .org-repo-name .octicon-lock{color:rgba(115,92,15,0.5)}.org-repos-mini .org-repo-name .repo-prefix{font-weight:400}.org-repos-mini .org-repo-name .repo-slash{display:inline-block;margin-right:-4px;margin-left:-4px}.org-repo-mini-cell{padding-top:15px;padding-bottom:15px;vertical-align:middle}.org-repo-meta{width:165px}.org-repo-meta .access-level{cursor:default}.org-repo-access-level{text-align:center}.org-repo-manage{width:270px}.with-higher-access .table-list-cell-checkbox{vertical-align:top}.permission-level-cell .select-menu-button{width:78px;text-align:left}.permission-level-cell .select-menu-button::after{position:absolute;top:10px;right:10px}.permission-level-cell .spinner,.permission-level-cell .permission-success-icon{float:none;opacity:0;transition:opacity 0.2s ease-in-out}.permission-level-cell .permission-success-icon{color:#28a745}.permission-level-cell .is-loading .spinner,.permission-level-cell .was-successful .permission-success-icon{opacity:1}.select-menu-option-title{margin-top:0;margin-bottom:0}.reinstate-org-member{position:relative;width:500px;margin:40px auto}.reinstate-org-member .reinstate-lead{margin-bottom:30px;font-size:16px}.reinstate-org-member label{cursor:pointer}.reinstate-org-member .reinstate-detail-container{margin:15px 0}.reinstate-org-member .reinstate-title{color:#333}.reinstate-org-member .reinstate-title .octicon{width:16px;margin-right:10px;color:#999}.add-member-wrapper{position:relative;width:500px;margin:40px auto}.add-member-wrapper .available-seats{color:#586069}.add-member-wrapper .buy-more-link{margin-right:5px}.cancel-invitation-form{margin-top:-34px}.add-member-lead{font-size:16px}.add-member-roles{margin:30px 0}.add-member-roles .role-make-member{display:block;margin-bottom:10px}.add-member-team-list{display:block;margin-bottom:30px;list-style:none}.add-member-team-list .team-row-header{padding:10px 20px 10px 0;font-size:12px;text-align:right;background:#fafafa;border-top-left-radius:3px;border-top-right-radius:3px}.add-member-team-list .team-row-header .team-row-teams{margin-right:245px}.add-member-team-list .team-row-header .team-row-members{margin-right:35px}.add-member-team-list .team{display:block;font-weight:400;cursor:pointer}.add-member-team-list .team:first-child{border-top:1px solid #f2f2f2}.add-member-team-list .team .btn-sm{float:right}.add-member-team-list .team-info{max-width:80%;color:#000;text-decoration:none}.add-member-team-list .team-meta{margin-top:2px;margin-bottom:2px;color:#586069}.add-member-team-list .team-description{width:260px;margin-top:2px;margin-bottom:2px}.add-member-team-list .team-toggler .turn-on{display:inline-block}.add-member-team-list .team-toggler.on .turn-off{display:inline-block}.add-member-team-list .team-toggler .turn-off{display:none}.add-member-team-list .team-toggler.on .turn-on{display:none}.team-list-footer{padding:10px 0;text-align:center;border-top:1px solid #e5e5e5}.team-list-footer .show-all-link .octicon{margin-left:5px;color:#586069}.invite-team-member-list .team{cursor:default}.invite-team-member-list .team:first-child .table-list-cell{border-top:0}.invite-team-member-list .table-list-cell-checkbox{width:42px}.invite-team-member-list .team-toggler{padding-top:12px;padding-right:3px}.invite-team-member-list .team-info{width:260px;padding:10px 15px 10px 0}.invite-team-member-list .team-description{display:block;padding-top:0;padding-bottom:0;font-weight:400}.invite-team-member-list .team-meta{width:100px;text-align:left;vertical-align:middle}.invite-team-member-list .team-link{color:#0366d6;text-align:right}.migration-jumbotron{height:70vh;min-height:450px;max-height:650px}.migration-jumbotron,.migration-sub-header{position:relative;margin-top:-1px;background-color:#3f4851;background-image:linear-gradient(#3f4851 0, #282d33 100%)}.migration-jumbotron::after,.migration-sub-header::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:" ";background-image:url("/images/modules/orgs/dots-bg.png");background-repeat:repeat;background-size:80%;opacity:0.75}.migration-jumbotron-content{position:relative;top:50%;z-index:2;width:980px;padding:100px 60px;margin:0 auto;text-align:center;transform:translateY(-50%)}.migration-jumbotron-octicons{height:60px;margin-bottom:20px;text-align:center}.migration-jumbotron-octicon-item{position:relative;display:inline-block;width:60px;height:60px;margin-right:10px;margin-left:10px;background-image:linear-gradient(-45deg, #6f42c1 30%, #f66a0a 100%);border-radius:50px}.migration-jumbotron-octicon-item::after{position:absolute;top:1px;right:1px;bottom:1px;left:1px;content:"";background-color:#383f47;border-radius:50px}.migration-jumbotron-octicon-item .octicon{position:relative;z-index:2;margin-top:16px;color:rgba(255,255,255,0.9)}.migration-jumbotron-title,.migration-jumbotron-lead,.migration-sub-title,.migration-sub-lead{color:#fff;text-shadow:0 1px 1px rgba(0,0,0,0.05)}.migration-jumbotron-title,.migration-section-title{margin-bottom:10px;font-weight:300}.migration-jumbotron-title{font-size:40px}.migration-section-title{margin-top:0;font-size:30px}.migration-jumbotron-lead{margin-top:0;font-size:24px;opacity:0.85}.migration-section-lead{margin-top:20px;margin-bottom:20px}.migration-jumbotron-btn{padding:12px 18px;font-size:16px;color:#6f42c1;background-color:#fff;border-width:0;box-shadow:0 3px 3px rgba(0,0,0,0.05)}.migration-jumbotron-btn:hover{color:#6f42c1;background-color:#eee}.migration-section{padding-top:100px;padding-bottom:100px;overflow:hidden;border-bottom:1px solid #ddd}.migration-feature-list{margin-top:30px;margin-bottom:20px;overflow:hidden;font-size:14px;color:#586069;list-style:none}.migration-feature-list::before{display:block;width:100px;margin-bottom:30px;content:"";border-top:1px solid #ddd}.migration-feature-list .octicon{width:22px;margin-left:-3px;color:#586069;text-align:center}.migration-feature-list-item{float:left;width:50%;margin-bottom:15px}.migration-section-grey{background-color:#fcfcfc}.migration-illustration-wrapper::before{display:table;content:""}.migration-illustration-wrapper::after{display:table;clear:both;content:""}.migration-illustration{width:700px;margin-top:-30px;margin-bottom:-50px;border:1px solid #ddd;border-radius:3px;box-shadow:0 0 15px rgba(0,0,0,0.05)}.migration-illustration-left{float:right;margin-right:50px}.migration-illustration-right{float:left;margin-left:50px}.migration-section-privileges{padding-top:80px;padding-bottom:80px}.migration-footer{position:relative;z-index:1;padding-top:60px;padding-bottom:60px;margin-bottom:-41px;border-bottom:1px solid #ddd}.migration-footer-content{width:800px;margin:0 auto;text-align:center}.migration-footer-title,.migration-footer-lead{margin-bottom:0}.migration-footer-lead{margin-top:10px}.migration-footer-btn{margin-top:20px}.migration-sub-header{padding-top:40px;padding-bottom:40px;margin-bottom:40px}.org-settings-updating{padding:15px;margin-top:0;margin-bottom:30px;background-color:#fff;border:1px solid #ddd;border-radius:3px}.org-settings-updating .spinner{display:inline-block;margin-top:-2px;vertical-align:middle}.org-disabled-settings{pointer-events:none;opacity:0.5}.migration-sub-header-content{width:68%}.migration-sub-title{margin-bottom:0}.migration-sub-lead{margin-top:10px;margin-bottom:0}.migration-org-avatar{margin-top:6px;margin-right:72px;border:3px solid #fff;border-radius:3px}.org-migration-settings-sidebar{position:-webkit-sticky;position:sticky;top:20px}.org-migration-settings-sidebar .migrate-org-roles{margin-top:0;margin-bottom:10px}.org-migration-settings-sidebar .preserve-member-privileges-btn{display:none}.org-migration-settings-sidebar .member-privilege-radios-preserved .preserve-member-privileges-btn{display:block}.org-migration-settings-sidebar .member-privilege-radios-preserved .save-member-privileges-btn{display:none}.org-migration-settings-section{position:relative;padding-bottom:50px;margin-right:60px;margin-bottom:50px;border-bottom:1px solid #ddd}.org-migration-settings-section:last-child{padding-bottom:0;margin-bottom:0;border-bottom:0}.org-migration-settings-section .disabled{pointer-events:none;opacity:0.5}.org-migration-settings-section .spinner{display:inline-block;margin-bottom:-3px}.org-migration-settings-icon{position:absolute;left:-45px;color:#ccc}.org-migration-settings-title{margin-bottom:0;font-size:22px;font-weight:400}.org-migration-settings-info{margin-top:5px;margin-bottom:30px;font-size:16px;color:#586069}.migrate-owners-wrapper{position:relative;min-height:550px}.migrate-owners-content-about{position:absolute;top:0;left:50%;width:700px;margin:30px auto 0;text-align:center;transition:opacity 0.2s ease-in-out, transform 0.3s ease-in-out;transform:translate(-50%, 0)}.migrate-owners-title{font-size:35px;font-weight:400}.migrate-owners-lead{margin-top:0;margin-bottom:20px}.migrate-owners-content-rename{width:520px;margin:auto}.delete-owners-button{color:#586069}.delete-owners-button:hover{color:#cb2431}.migrate-org-roles{display:table;width:100%;margin-top:-20px;border:1px solid #ddd;border-radius:3px}.migrate-org-roles .tooltipped::after{width:150px;white-space:normal}.no-avatars-roles-matrix .migrate-org-roles{margin-top:5px}.migrate-org-roles-item{display:table-cell;width:33.33%;border-right:1px solid #ddd}.migrate-org-roles-item:last-child{border-right:0}.migrate-ability-list{margin:15px 0;list-style:none}.migrate-ability-list-item{padding-top:5px;padding-bottom:5px;margin:0 20px;font-size:14px}.migrate-ability-list-item:first-child{border-top:0}.migrate-ability-list-item .octicon-check,.migrate-ability-list-item .octicon-x{width:15px}.migrate-ability-list-item .octicon-check{color:#28a745}.migrate-ability-list-item .octicon-x{color:#aaa}.migrate-ability-list-item .octicon-question{font-size:12px;color:#555}.migrate-ability-not-possible{color:#586069}.default-repository-permission .octicon-x,.members-can-create-repositories .octicon-x,.team-privacy .octicon-x{display:none}.default-repository-permission.migrate-ability-not-possible .octicon-x,.members-can-create-repositories.migrate-ability-not-possible .octicon-x,.team-privacy.migrate-ability-not-possible .octicon-x{display:inline-block}.default-repository-permission.migrate-ability-not-possible .octicon-check,.members-can-create-repositories.migrate-ability-not-possible .octicon-check,.team-privacy.migrate-ability-not-possible .octicon-check{display:none}.migrate-org-roles-header{padding:15px 20px;border-bottom:1px solid #ddd}.migrate-org-roles-title{margin-top:0;margin-bottom:0;font-size:18px;font-weight:400}.migrate-org-roles-lead{margin-top:4px;margin-bottom:0;font-size:14px;color:#586069}.migrate-org-roles-count{padding:10px 20px;color:#586069;border-top:1px solid #ddd}.migrate-org-avatar-list{margin-top:5px;margin-bottom:10px}.migrate-org-avatar-list::before{display:table;content:""}.migrate-org-avatar-list::after{display:table;clear:both;content:""}.migrate-org-avatar-list .migrate-org-avatar,.migrate-org-avatar-list .migrate-org-avatar-empty{float:left;margin-left:2px}.migrate-org-avatar-list .migrate-org-avatar:first-child,.migrate-org-avatar-list .migrate-org-avatar-empty:first-child{margin-left:0}.migrate-org-avatar-list .migrate-org-avatar-empty{width:30px;height:30px;border-radius:3px}.migrate-org-avatar-list .migrate-org-more-ellipsis,.migrate-org-avatar-list .migrate-org-zero{font-size:18px;line-height:30px;color:#586069;text-align:center}.migrate-org-avatar-list .migrate-org-more-ellipsis{font-weight:600;line-height:20px;background-color:#f5f5f5}.migrate-org-avatar-list .migrate-org-zero{color:#586069;border:1px dashed #ddd}.migrate-org-avatar-list .migrate-org-more-ellipsis:hover{text-decoration:none}.migrate-org-avatar-list .tooltipped::after{width:auto;white-space:nowrap}.menu-item .org-avatar,.menu-item .org-octicon-credit-card{position:absolute}.menu-item .org-octicon-credit-card{right:0}.org-settings-link{display:block;padding:0 30px;word-wrap:break-word}.team-stats{padding-right:15px;padding-left:15px;margin-right:-15px;margin-bottom:-15px;margin-left:-15px;border-top:1px solid #eee}.stats-group{display:table;width:100%;table-layout:fixed}.stats-group-stat{display:table-cell;padding-top:10px;padding-bottom:10px;padding-left:15px;font-size:12px;color:#586069;text-transform:uppercase}.stats-group-stat:first-child{padding-left:0;border-right:1px solid #eee}.stats-group-stat:hover,.stats-group-stat:hover .stat-number{color:#0366d6;text-decoration:none}.stats-group-stat.no-link:hover{color:#586069;text-decoration:none}.stats-group-stat.no-link:hover .stat-number{color:#333}.stat-number{display:block;font-size:16px;color:#333}.permission-title{margin-top:0}.add-to-org-wrapper{width:500px}.invite-member-results ul{margin:0}.invite-member-header{text-align:center}.add-to-org-title{font-size:21px;font-weight:400;line-height:normal}.team-member-list{list-style:none}.team-member-list .table-list-cell{padding-top:15px;padding-bottom:15px}.team-member-list .team-member-content{margin-left:50px}.team-member-list .team-member-username{margin:0;font-size:14px;font-weight:600;line-height:20px}.team-member-list .Label--gray,.team-member-list .Label--outline{cursor:default}.team-member-list .invite-icon{width:28px;color:#959da5}.menu-item-danger,.menu-item-danger.selected{color:#cb2431}.menu-item-danger:hover,.menu-item-danger[aria-selected="true"],.menu-item-danger.navigation-focus,.menu-item-danger.selected:hover,.menu-item-danger.selected[aria-selected="true"],.menu-item-danger.selected.navigation-focus{color:#fff;background:#d73a49}.team-member-list-avatar{float:left;margin-right:10px}.team-member-list-avatar .octicon{width:40px;color:#959da5}.org-team-form .disabled{opacity:0.5}.org-team-form .css-truncate-target{max-width:250px}.confirm-removal-container .private-fork-count{margin-top:0;font-size:12px;font-weight:400;color:#586069}.confirm-removal-container .deleting-private-forks-warning{position:relative;padding-left:26px}.confirm-removal-container .deleting-private-forks-warning .octicon{position:absolute;top:2px;left:0;color:#cb2431}.confirm-removal-list-container{margin-bottom:15px;border:1px solid #eaeaea;border-radius:3px}.confirm-removal-list-item{padding:10px;margin:0;font-size:14px;font-weight:600;border-top:1px solid #eaeaea}.confirm-removal-list-item:first-child{border-top:0}.confirm-removal-team .octicon,.confirm-removal-repo .octicon{margin-right:3px;color:#586069}.team-repo-access-list{max-height:245px}.manage-member-meta{list-style:none}.manage-member-meta-item{margin-top:12px;color:#586069}.manage-member-meta-item:first-child{margin-top:0}.manage-member-meta-item .btn-link{color:#586069}.manage-member-meta-item>.octicon{width:14px;margin-right:5px;color:#586069;text-align:center}.manage-member-meta-item>.octicon-alert{color:#a04100}.member-two-factor-disabled{color:#cb2431}.manage-member-button{margin-bottom:10px}.org-person-repo-header{margin-top:0}.org-person-repo-search{margin-top:5px;margin-right:5px}.org-user-notice-title{margin-top:0;margin-bottom:0}.org-user-notice-content{margin-top:10px;margin-bottom:10px;font-size:14px}.org-user-notice-content strong{color:#333}.org-user-notice-content:last-child{margin-bottom:0}.org-user-notice-content .octicon{color:#586069}.org-user-notice-icon{float:right;margin:10px 10px 20px;font-size:45px;color:#ccc}.manage-repo-access-header{margin-top:30px;margin-bottom:30px}.manage-repo-access-header::before{display:table;content:""}.manage-repo-access-header::after{display:table;clear:both;content:""}.manage-repo-access-header .btn{margin-top:8px}.manage-repo-access-header .tooltipped::after{width:250px;white-space:normal}.manage-repo-access-heading{margin-top:-2px;margin-bottom:0;font-size:24px;font-weight:400}.manage-repo-access-lead{margin-top:3px;margin-bottom:0;font-size:16px;color:#586069}.manage-repo-access-group{background-color:#fff;border:1px solid #ddd;border-radius:3px}.manage-repo-access-title{padding:12px 15px;margin-top:0;margin-bottom:0;font-size:14px;background-color:#f8f8f8;border-bottom:1px solid #ddd;border-radius:3px 3px 0 0}.manage-repo-access-wrapper{position:relative;padding-left:25px}.manage-repo-access-wrapper::before{position:absolute;top:15px;bottom:15px;left:20px;z-index:1;display:block;width:2px;content:"";background-color:#eee}.manage-repo-access-icon{position:relative;z-index:2;float:left;padding-top:2px;padding-bottom:2px;margin-top:-3px;margin-left:-25px;background:#fff}.manage-repo-access-icon .octicon{font-size:14px;color:#ccc}.manage-repo-access-list{list-style:none}.manage-repo-access-list-item{padding:15px}.manage-repo-access-list-item:last-child{border-bottom:0;border-radius:0 0 3px 3px}.manage-repo-access-teams-group{margin-top:-20px;list-style:none;border:1px solid #ddd;border-radius:3px}.manage-repo-access-team-item{border-top:1px solid #eee}.manage-repo-access-team-item:first-child{border-top:0}.manage-repo-access-description{margin-top:3px;margin-bottom:0;overflow:hidden;text-overflow:ellipsis;word-wrap:break-word;white-space:nowrap}.manage-repo-access-not-active{color:#24292e;background-color:#fafbfc}.manage-repo-access-not-active .manage-repo-access-icon{background:#f9f9f9}.manage-access-remove-footer{padding:15px;border-top:1px solid #ddd}.manage-access-remove-footer .tooltipped::after{width:250px;white-space:normal}.manage-access-none{margin:20px 50px;text-align:center}.ldap-group-dn{display:block;font-weight:400;color:#aaa}.ldap-import-groups-container .blankslate{display:none}.ldap-import-groups-container.is-empty .blankslate{display:block}.ldap-import-groups-container.is-empty .ldap-memberships-list{display:none}.ldap-memberships-list{margin-bottom:30px}.ldap-memberships-list .table-list-cell{padding-top:10px;padding-bottom:10px;font-size:13px;vertical-align:middle}.ldap-memberships-list .table-list-cell:last-child{width:92px}.ldap-memberships-list .ldap-list-team-name{width:380px}.ldap-memberships-list .ldap-group-dn{font-size:11px}.ldap-memberships-list .ldap-mention-as{width:260px}.ldap-memberships-list .edit{position:absolute;padding:10px;margin-left:-33px;color:#0366d6;cursor:pointer}.ldap-memberships-list .edit-fields{display:none}.ldap-memberships-list .is-editing .edit-hide{display:none}.ldap-memberships-list .is-editing .edit-fields{display:block}.ldap-memberships-list .is-editing .spinner{margin-left:15px;vertical-align:middle}.ldap-memberships-list .is-removing{opacity:0.25}.ldap-memberships-list .is-removing .edit{opacity:0.5}.team-name-field{height:33px}.ldap-import-form-actions{margin-top:30px}.invited .team-member-list{margin:-20px 0}.invited .team-member-list .list-item{padding:10px 0;border-bottom:1px solid #eee}.invited .team-member-list .list-item::before{display:table;content:""}.invited .team-member-list .list-item::after{display:table;clear:both;content:""}.invited .team-member-list .list-item:last-of-type{border:0}.invited .team-member-list .list-item .edit-invitation{float:right;margin-top:6px}.invited-banner{margin-bottom:20px}.invited-banner::before{display:table;content:""}.invited-banner::after{display:table;clear:both;content:""}.invited-banner .btn-sm{float:right;margin-left:5px}.invited-banner p{font-size:15px;line-height:1.6}.invited-banner .inviter-link{font-weight:600}.manage-member-sso-sessions.has-active-sessions .blankslate{display:none}.manage-memberships-nav{position:relative;top:1px;margin-top:10px}.manage-memberships-tabs-item{color:#586069;white-space:nowrap;cursor:pointer;border:solid transparent;border-width:3px 1px 1px;border-radius:3px 3px 0 0}.manage-memberships-tabs-item:hover{color:#333}.manage-memberships-tabs-item.selected{font-weight:600;color:#24292e;background-color:#fff;border-bottom:2px solid #d26911}.owner-select-grid{margin-left:-8px}.owner-select-grid::before{display:table;content:""}.owner-select-grid::after{display:table;clear:both;content:""}.owner-select-target{float:left;padding:10px;margin:0 10px 20px;font-weight:600;text-align:center;cursor:pointer;background-color:#f2f2f2;border:0;border-radius:3px}.owner-select-target:hover,.owner-select-target:focus{color:#fff;background-color:#0366d6}.owner-select-target:active{color:#fff;background-color:#024ea4}.owner-select-target .css-truncate-target{max-width:90px}.owner-select-target.disabled{color:#6a737d;cursor:not-allowed}.owner-select-target.disabled .user-mention{color:#6a737d}.owner-select-target.disabled .owner-select-avatar{opacity:0.3}.owner-select-avatar{display:block;margin-bottom:9px}.theme-picker{margin-bottom:-1px;background-color:#fff;background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,0.1);box-shadow:0 5px 10px rgba(0,0,0,0.1)}.theme-picker>.container{position:relative;overflow:hidden;text-align:center}.theme-picker-thumbs{border-bottom:1px solid #eee}.theme-toggle{width:32px;height:32px;padding:0;color:#ccc;background:none;border:0}.theme-toggle:hover{color:#0084c8;text-decoration:none}.theme-toggle.disabled,.theme-toggle.disabled:hover{color:#ccc;cursor:not-allowed;opacity:0.3}.theme-toggle-full-left,.theme-toggle-full-right{position:absolute;top:50px;overflow:hidden}.theme-toggle-full-left{left:4px}.theme-toggle-full-right{right:4px}.theme-selector{height:102px;margin:15px 46px}.theme-selector-thumbnail{padding:2px;border:1px solid #ddd}.theme-selector-thumbnail:hover{text-decoration:none;background-color:#f5f5f5}.theme-selector-thumbnail.selected{padding:3px;background-color:#0366d6;border:0}.theme-selector-thumbnail.selected .theme-selector-img{border:1px solid #fff}.theme-selector-img{width:126px;height:96px;border-radius:1px}.theme-picker-spinner{position:absolute;top:16px;left:50%;margin-left:-16px;background-color:#fff;opacity:0;transition:0.2s, opacity ease-in-out}.theme-picker-spinner.visible{opacity:1}.theme-picker-spinner.visible ~ .theme-picker-controls .theme-name{opacity:0}.theme-picker-view-toggle{float:left}.theme-picker-view-toggle .for-hiding{display:none}.theme-picker-view-toggle.open .for-hiding{display:inline}.theme-picker-view-toggle.open .for-showing{display:none}.theme-picker-controls{position:absolute;top:15px;left:50%;width:220px;margin-left:-110px;line-height:34px;text-align:center}.theme-picker-controls .theme-toggle{vertical-align:middle}.theme-name{display:inline-block;margin-right:10px;margin-left:10px;font-size:20px;line-height:1;vertical-align:middle}.page-preview{z-index:-100;display:block;width:100%;height:6000px;padding:0;background-color:#fff;border:0}.pinned-repos-spinner{position:relative;top:2px;left:6px}.pinned-repos-reorder-error{padding-left:6px;font-size:12px;font-weight:400;color:#86181d}.pinned-repos-setting-link{font-size:13px;font-weight:400}.pinned-repo-name{color:#6a737d}.pinned-repo-checkbox:checked+.pinned-repo-name{color:#24292e;background-color:#f1f8ff}.org-pinned-repos-list.pinned-repos-list{justify-content:flex-start}.org-pinned-repo-item.pinned-repo-item{width:319px;margin-right:11px}.org-pinned-repo-item.pinned-repo-item+.org-pinned-repo-item+.org-pinned-repo-item+.org-pinned-repo-item{margin-right:11px}.org-pinned-repo-item.pinned-repo-item+.org-pinned-repo-item+.org-pinned-repo-item{margin-right:0}.org-pinned-repo-item.pinned-repo-item+.org-pinned-repo-item+.org-pinned-repo-item+.org-pinned-repo-item+.org-pinned-repo-item+.org-pinned-repo-item{margin-right:0}@media print{#serverstats,.Header,.header-search,.site-search,.reponav,.comment::before,.comment::after,.footer,.pagehead-actions,.discussion-timeline-actions,.timeline-comment-actions,.timeline-new-comment,.thread-subscription-status,.lock-toggle-link,.header,.pr-review-tools,.file-actions,.js-expandable-line,.pr-toolbar-shadow,.pr-toolbar.is-placeholder,.language-color{display:none !important}.repository-lang-stats-graph{height:0}.btn:not(.btn-outline){color:#24292e !important;background:none}p,.comment h2{page-break-inside:avoid}.markdown-body h2{page-break-after:avoid}.topic-tag{padding:0}.topic-tag::before{content:"#";margin-right:-2px}.blob-num{border-right:2px solid #e1e4e8}.blob-num-deletion{border-right-color:#d73a49}.blob-num-addition{border-right-color:#28a745}.blob-code-addition .x{border-bottom:2px solid #28a745;border-radius:0px}.blob-code-deletion .x{border-bottom:2px solid #d73a49;border-radius:0px}.pr-toolbar.is-stuck{position:static !important;width:100% !important}.block-diff-neutral{border:4px solid #d1d5da}.block-diff-deleted{border:4px solid #d73a49}.block-diff-added{border:4px solid #28a745}.State{border:1px #e1e4e8 solid;color:#1b1f23;border-color:none;background:none}.State--green{border:1px solid #2cbe4e;color:#28a745}.State--purple{border:1px solid #6f42c1;color:#6f42c1}.State--red{border:1px solid #cb2431;color:#cb2431}.markdown-body pre>code{white-space:pre-wrap}}.pjax-loader-bar{position:fixed;top:0;left:0;z-index:40;opacity:0;transition:opacity 0.4s linear 0.4s}.pjax-loader-bar .progress{position:fixed;top:0;left:0;height:2px;background:#77b6ff;box-shadow:0 0 10px rgba(119,182,255,0.7);transition:width 0.4s ease}.pjax-loader-bar.is-loading{opacity:1;transition:none}.project-full-screen .pagehead,.project-full-screen .Header{display:block}@media (min-width: 544px){.project-full-screen .pagehead,.project-full-screen .Header{display:none}}.project-full-screen .project-header{padding-top:10px;padding-bottom:10px;color:rgba(255,255,255,0.75)}@media (min-width: 544px){.project-full-screen .project-header{background-color:#24292e}}.project-full-screen .project-header .project-header-link{color:rgba(255,255,255,0.75) !important}.project-full-screen .project-header .project-header-link:hover{color:#fff !important}.project-full-screen .project-header .pending-cards-status{border-color:#24292e}@media (min-width: 544px){.project-full-screen .card-filter-input{color:#fff;background-color:rgba(255,255,255,0.125);border:0;outline:none;box-shadow:none}.project-full-screen .card-filter-input:-ms-input-placeholder{color:rgba(255,255,255,0.7)}.project-full-screen .card-filter-input::-ms-input-placeholder{color:rgba(255,255,255,0.7)}.project-full-screen .card-filter-input::placeholder{color:rgba(255,255,255,0.7)}.project-full-screen .card-filter-input:focus{background-color:rgba(255,255,255,0.175)}}.project-header{background-color:#eff1f3}@media (min-width: 544px){.project-header{background-color:#fff}}.project-header .select-menu-modal-holder{z-index:500}.project-updated-message{top:6px;left:50%;z-index:50;transform:translate(-50%, 0)}.pending-cards-status{top:-2px;right:-9px;z-index:2;width:14px;height:14px;background-image:linear-gradient(#54a3ff, #006eed);background-clip:padding-box;border:2px solid #fff}.project-columns{overflow-x:auto}@media (min-width: 544px){.project-columns-container{height:0;overflow-x:visible !important}}.project-column{min-width:100%;max-width:100%;background-color:#eff1f3;border-width:0 !important;border-radius:0 !important}.project-column:focus{outline:none}@media (min-width: 544px){.project-column{min-width:355px;max-width:355px;border-width:1px !important;border-radius:6px !important}.project-column:focus{border-color:#2188ff !important;box-shadow:0 0 0 0.2em rgba(3,102,214,0.3)}}.project-column.moving{background-color:#f1f8ff !important;box-shadow:0 0 0 0.2em rgba(3,102,214,0.3);transform:translateX(4px) translateY(-4px)}.project-column .automation-summary-tooltip::after{max-width:190px !important}.new-project-column{width:315px;border-color:#959da5 !important}.project-search-form .loading-indicator{top:21px;right:21px;display:none}.project-search-form.loading .loading-indicator{display:inline-block}.sortable-ghost{background-color:#f6f8fa;opacity:0.5}.project-card .project-reference-markdown>p,.project-card:last-child{margin-bottom:0 !important}.project-card:first-child{margin-top:8px !important}@media (min-width: 544px){.project-card:first-child{margin-top:3px !important}}.project-card ul,.project-card ol{margin-bottom:8px;margin-left:16px}.project-card .contains-task-list{margin-left:24px}.project-card:hover{border-color:#d1d5da !important;box-shadow:0 1px 3px rgba(106,115,125,0.3) !important}.project-card:focus{outline:none}@media (min-width: 544px){.project-card:focus{border-color:#2188ff !important;box-shadow:0 0 0 0.2em rgba(3,102,214,0.3) !important}}.project-card.moving{background-color:#f1f8ff !important;box-shadow:0 0 0 0.2em rgba(3,102,214,0.3) !important;transform:translateX(4px) translateY(0)}.archived-project-cards-pane .project-card .archived-header{display:flex !important;color:#735c0f}.archived-project-cards-pane .project-card .archive-dropdown-item{display:none}.issue-card.draggable{cursor:move}.issue-card .issue-card-label{max-width:50%}.issue-card .issue-card-label::after{max-width:150px}.issue-card .avatar-stack:hover .from-avatar{margin-right:-4px}.issue-card pre{word-wrap:break-word;white-space:pre-wrap}@keyframes show-pane{0%{transform:translateX(390px)}100%{transform:translateX(0)}}.project-pane{z-index:30;background-clip:padding-box;box-shadow:-3px 0 5px rgba(36,41,46,0.05)}@media (min-width: 544px){.project-pane{position:absolute !important;width:360px !important;height:auto !important;animation:show-pane 0.2s cubic-bezier(0, 0, 0, 1)}}.project-pane .redacted-activity{cursor:help;border-bottom:1px dotted #959da5}.project-pane .project-body-markdown p:last-child,.project-pane .project-body-markdown ul:last-child,.project-pane .project-body-markdown ol:last-child{margin-bottom:0}.project-pane-close{color:rgba(27,31,35,0.5)}.project-pane-close:hover{color:rgba(27,31,35,0.7)}.project-note-form textarea{resize:vertical}.card-menu-container .dropdown-menu,.column-menu-container .dropdown-menu{min-width:180px}.card-octicon{top:6px;left:10px}.card-note-octicon{top:8px}.is-sending .auto-search-group .chooser-spinner{top:15px;right:21px;left:auto}.card-filter-input{width:0}@media (min-width: 544px){.card-filter-input{width:290px}}.card-filter-autocomplete-dropdown{z-index:500;float:none;min-width:240px;max-height:240px;cursor:pointer}.card-filter-autocomplete-dropdown [aria-selected="true"],.card-filter-autocomplete-dropdown .navigation-focus{color:#fff !important;background-color:#0366d6;border-radius:3px}.card-filter-autocomplete-dropdown [aria-selected="true"] .autocomplete-text-qualifier,.card-filter-autocomplete-dropdown .navigation-focus .autocomplete-text-qualifier{color:#fff !important}.projects-reset-query:hover .projects-reset-query-icon{background-color:#0366d6}.projects-reset-query-icon{width:18px;height:18px;padding:1px;background-color:#6a737d}.project-small-menu-dropdown::before,.project-small-menu-dropdown::after{display:none}.project-header-controls,.project-header-search{flex-grow:1}@media (min-width: 1012px){.project-header-controls,.project-header-search{flex-grow:0}}.project-header-subnav-search{flex-grow:1}@media (min-width: 544px){.project-header-subnav-search{flex-grow:0}}.project-modal{max-width:90vw}.project-page .application-main{flex-shrink:0 !important}@media (min-width: 544px){.project-page .application-main{flex-shrink:1 !important}}.project-page .reponav-small{display:none !important}@media (min-width: 544px){.project-page .reponav-small{display:block !important}}@media (min-width: 1012px){.project-page .reponav-small{display:none !important}}.project-edit-mode .column-menu-container,.project-edit-mode .column-menu-item{display:none !important}.project-edit-mode .project-move-actions{display:flex !important}.push-board-over{padding-right:0 !important;transition:all 0.2s ease}@media (min-width: 544px){.push-board-over{padding-right:360px !important}}.project-touch-scrolling{-webkit-overflow-scrolling:touch}.project-page.menu-active .project-touch-scrolling{-webkit-overflow-scrolling:auto}.projects-comment-form .comment-md-support-link{float:none;width:100%;text-align:center}.projects-comment-form .comment-form-actions{width:100%;padding:8px 16px;margin:4px 0 !important}.projects-comment-form .comment-form-actions button{width:100%;margin:4px 0 !important}.projects-comment-form .comment-form-head{padding:0 !important;margin:0 !important;border-bottom:0}.projects-comment-form .comment-form-head .tabnav-tabs{padding:8px 8px 0}.projects-comment-form .comment-form-head .toolbar-commenting{width:100%;background-color:#fff;border-top:1px solid #d1d5da}.projects-comment-form .comment-form-head .toolbar-commenting .toolbar-group{margin:10px 7px 5px !important}.projects-comment-form .comment-form-head::after{display:block;clear:both;content:" "}.projects-comment-form .comment-form-textarea{height:250px !important}.projects-comment-form .preview-content{margin:0;border-top:1px solid #d1d5da}.projects-comment-form .preview-content .comment-body{padding:16px}.project-issue-body-wrapper{max-height:200px;overflow:hidden}.Details--on .project-issue-body-wrapper{max-height:none;overflow:visible}.project-issue-body-blur{height:32px;background:linear-gradient(to top, #fff, rgba(255,255,255,0))}.Details--on .project-issue-body-blur{height:0}.project-comment-title-hover .comment-action,.project-comment-body-hover .comment-action{opacity:0}.project-comment-title-hover:hover .comment-action,.project-comment-body-hover:hover .comment-action{opacity:1}.project-comment-title-hover .octicon-pencil,.project-comment-body-hover .octicon-pencil{color:rgba(27,31,35,0.5)}.project-comment-title-hover .octicon-pencil:hover,.project-comment-body-hover .octicon-pencil:hover{color:#0366d6}.project-comment-body-reaction .timeline-comment-action{padding:4px 8px}.project-comment-reactions .reaction-summary-item{padding:8px}.project-comment-reactions .reaction-summary-item g-emoji{margin:0 !important}.vcard-names{line-height:1}.vcard-fullname{font-size:26px;line-height:30px}.vcard-username{font-size:20px;font-style:normal;font-weight:300;line-height:24px;color:#666}.vcard-details{list-style:none}.vcard-details .css-truncate.css-truncate-target{width:100%;max-width:100%}.vcard-details .css-truncate.css-truncate-target div{overflow:hidden;text-overflow:ellipsis}.vcard-detail{padding-left:24px;font-size:14px}.vcard-detail .octicon{float:left;width:16px;margin-top:3px;margin-left:-24px;color:#6a737d;text-align:center}.member-badge{padding-left:24px;font-size:14px;color:#0366d6}.member-badge .octicon{float:left;width:16px;margin-left:-24px;color:#6a737d;text-align:center}.member-badge+.member-badge{padding-top:0;margin-top:-3px;border-top:0}.new-user-avatar-cta{font-size:14px;color:#244f79;background-color:#f1f6fb;border:solid 1px #d0e5f8;border-radius:3px}.user-profile-bio{margin-bottom:12px;overflow:hidden;font-size:14px;color:#6a737d}.form-group .form-control.user-profile-bio-field{width:440px;height:5.35em;min-height:0}.user-profile-bio-field-container,.user-profile-company-field-container{position:relative}.user-profile-bio-message{margin:5px 0 0;font-size:12px;color:#86181d}.vcard-detail{padding-left:22px}.vcard-detail .octicon{margin-left:-22px}.member-badge{font-size:13px}.user-profile-sticky-bar{position:fixed;top:0;z-index:90;width:233px;word-break:break-all;pointer-events:none;opacity:0;transition:0.2s}.user-profile-sticky-bar::after{position:fixed;top:0;right:0;left:0;z-index:100;display:none;height:54px;content:"";background-color:#fff;border-bottom:solid 1px #d1d5da;box-shadow:0 1px 2px rgba(0,0,0,0.075);opacity:0;transition:0.2s}.user-profile-sticky-bar.is-stuck{pointer-events:auto;opacity:1}.user-profile-sticky-bar.is-stuck::after{display:block;opacity:1}.user-profile-mini-vcard{position:relative;top:1px;z-index:110;height:54px}.user-profile-mini-avatar{width:32px}.mini-follow-button{padding:0 8px;line-height:1.5;opacity:0;transition:0.2s}.is-follow-stuck .mini-follow-button{opacity:1}.user-profile-following-container .user-following-container.on .follow,.user-profile-following-container .user-following-container .unfollow{display:none}.user-profile-following-container .user-following-container .follow,.user-profile-following-container .user-following-container.on .unfollow{display:block}.vcard-names-container{top:0}.vcard-names-container.is-stuck{pointer-events:none}.vcard-names-container.is-stuck .vcard-names{opacity:0}.vcard-names-container.is-stuck::after{opacity:1}.blocked-user-notice{width:100%;padding:8px 16px;color:#cb2431;text-align:center;border:solid 1px #d73a49;border-radius:3px}.user-profile-nav{background-color:#fff;border-bottom:solid 1px #d1d5da}.user-profile-nav.is-stuck{z-index:90}.pinned-repos-list{display:flex;list-style:none;flex-wrap:wrap;justify-content:space-between}.pinned-repo-item{display:flex;width:359px}.pinned-repo-item .pinned-repository-handle{padding-top:1px;color:#586069}.pinned-repo-item .pinned-repository-handle:hover{cursor:-webkit-grab;cursor:grab}.pinned-repo-item.is-dragging,.pinned-repo-item.is-dragging .pinned-repository-handle{cursor:-webkit-grabbing;cursor:grabbing}.pinned-repo-item.is-dragging{background-color:#f1f8ff}.pinned-repo-item.sortable-ghost{background-color:#f1f8ff;opacity:0}.pinned-repo-item.empty{border-style:dashed;border-width:1px;align-items:center;justify-content:center}.pinned-repo-item-content{display:flex;width:100%;flex-direction:column}.pinned-repo-desc{flex:1 0 auto}.pinned-repo-meta{display:inline-block}.pinned-repo-meta+.pinned-repo-meta{margin-left:16px}.user-repo-search-results-summary{white-space:normal}.profile-timeline.discussion-timeline{float:none}.profile-timeline.discussion-timeline .profile-timeline-month-heading::after{position:absolute;top:12px;z-index:-1;width:100%;height:1px;content:"";background-color:#eaecef}.profile-timeline.discussion-timeline::before{left:15px;background-color:#eaecef}.profile-timeline.discussion-timeline .contribution-joined-github,.profile-timeline.discussion-timeline .contribution-first-pull-request,.profile-timeline.discussion-timeline .contribution-first-repository,.profile-timeline.discussion-timeline .contribution-first-issue{margin-top:-16px}.profile-break-word{-webkit-hyphens:auto;-ms-hyphens:auto;hyphens:auto;word-break:break-word}.profile-timeline-year-list{top:74px}.profile-timeline-card-wrapper{border-top:solid 2px #fff;border-bottom:solid 2px #fff}.profile-timeline-card .issue-meta-section .progress-bar{width:40px}.profile-timeline-card .issue-meta-section .octicon{color:#6a737d;vertical-align:middle}.profile-rollup-wrapper .css-truncate-target{max-width:85%}.profile-rollup-wrapper .progress-bar{height:8px;border-radius:2px}.profile-rollup-wrapper+.profile-rollup-wrapper{border-top:1px solid #eaecef}.profile-timeline-card-wrapper+.profile-timeline-card-wrapper{margin-top:24px}.profile-rollup-wrapper+.profile-timeline-card-wrapper{margin-top:0}.profile-timeline-month-heading+.profile-timeline-card-wrapper{margin-top:24px}.profile-rollup-summarized+.profile-rollup-summarized{border-top:1px solid #eaecef}.profile-rollup-icon{display:inline-block;width:16px;text-align:center}.profile-rollup-content{display:none}.profile-rollup-content .content-title:hover .link-gray-dark-underline{text-decoration:underline}.vertical-text-bottom{vertical-align:text-bottom}.profile-rollup-summarized.open>.profile-rollup-content,.profile-rollup-summarized.open .profile-rollup-toggle-closed,.profile-rollup-wrapper.open>.profile-rollup-content,.profile-rollup-wrapper.open .profile-rollup-toggle-closed{display:block}.profile-rollup-summarized.open .profile-rollup-toggle-open,.profile-rollup-wrapper.open .profile-rollup-toggle-open{display:none}.profile-rollup-toggle-closed{display:none}.profile-rollup-toggle{color:#6a737d;cursor:pointer}.profile-rollup-toggle:hover{color:#0366d6}.pull-request-tab-content{display:none}.pull-request-tab-content.is-visible{display:block}.discussion-timeline p.explain{margin:0;font-size:12px}.pull-request-ref-restore{display:none}.pull-request-ref-restore .animated-ellipsis-container{line-height:16px}.pull-request-ref-restore-text{display:block}.pull-discussion-timeline.is-pull-restorable .pull-request-ref-restore.last{display:block}.stale-files-tab{margin-bottom:10px}.files-bucket{margin-bottom:15px}.full-width .diffbar .container,.split-diff .diffbar .container{padding-right:0;padding-left:0}.pr-toolbar{position:-webkit-sticky;position:sticky;top:0;z-index:29;height:60px;padding:0 20px;margin:-20px -20px 0;background-color:#fff}.pr-toolbar .stale-files-tab{float:left;padding:5px 10px;margin-top:-5px;margin-bottom:-5px;color:#a04100;background-color:#fff8f2;border-radius:3px}.pr-toolbar .subset-files-tab{float:left;padding:5px 10px;margin-top:-5px;margin-bottom:-5px;font-size:13px;color:#0366d6;background-color:#e6f1f6;border-radius:3px}.pr-toolbar .stale-files-tab-link{font-weight:600;color:inherit}.pr-toolbar.is-stuck+.pr-toolbar-shadow{position:fixed;top:60px;right:0;left:0;z-index:28;display:block;height:5px;content:"";background:linear-gradient(rgba(0,0,0,0.075), rgba(0,0,0,0.001)) repeat-x 0 0;border-top:1px solid rgba(0,0,0,0.15)}.pr-toolbar .float-right .diffbar-item{margin-right:0}.pr-toolbar .float-right .diffbar-item+.diffbar-item{margin-left:20px}.files-next-bucket .file,.files-next-bucket .full-commit{margin-top:0;margin-bottom:20px}.diffbar{height:20px;padding-top:20px;padding-bottom:20px;background-color:#fff}.diffbar::before{display:table;content:""}.diffbar::after{display:table;clear:both;content:""}.diffbar .container{width:auto}.diffbar .table-of-contents{margin-bottom:0}.diffbar .table-of-contents ol{margin-bottom:-15px}.diffbar .table-of-contents li{border-top:1px solid #eee}.diffbar .table-of-contents li:first-child{border-top:0}.diffbar [aria-selected="true"] .text-emphasized,.diffbar .navigation-focus .text-emphasized{color:#fff}.diffbar-range-menu .select-menu-modal{width:380px}.diffbar-range-menu .css-truncate-target{max-width:280px}.diffbar-range-menu .select-menu-item:not(.select-menu-action){padding:8px 10px}.diffbar-range-menu .emoji{vertical-align:bottom}.diffbar-range-menu .in-range:not([aria-selected="true"]):not(.is-range-selected),.diffbar-range-menu .in-range:not(.navigation-focus):not(.is-range-selected){background-color:#f1f8ff;border-bottom-color:rgba(27,31,35,0.15)}.diffbar-range-menu .is-range-selected{color:#735c0f;cursor:default;background-color:#fffbdd;border-bottom-color:rgba(38,44,49,0.15);outline:none}.diffbar-range-menu .is-range-selected .text-emphasized{color:#776521}.diffbar-range-menu .is-range-selected .description{color:inherit}.diffbar-range-menu .is-last-in-range{cursor:pointer;background-color:#fff5b1}.diffbar-item{float:left;margin-right:20px;font-size:13px;line-height:20px;vertical-align:middle}.fork-collab-tip{width:270px;margin-top:-30px}.fork-collab-tip.dropdown-menu-s{margin-top:10px}.fork-collab-link{margin-left:15px}.conflict-resolver .conflict-loader,.conflict-resolver.loading .resolve-file-form{display:none}.conflict-resolver .resolve-file-form,.conflict-resolver.loading .conflict-loader{display:block}.conflict-resolver.loading{position:relative;height:calc(100vh + 51px);padding-top:50px;border:1px #e1e4e8 solid}.conflict-resolver .file-header{padding:9px 10px}.conflicts-nav{height:100vh;-ms-overflow-style:-ms-autohiding-scrollbar;border-width:0 0 1px}.conflict-nav-item .discussion-item-icon{display:none}.conflict-nav-item.resolved .discussion-item-icon{display:block;margin-left:-5px}.conflict-nav-item.resolved .octicon-file-code{display:none}.conflict-nav-item.selected::before{border-radius:0}.conflict-nav-item .octicon{width:22px}.conflict-nav-item .css-truncate-target{max-width:100%}.is-resolved .file-actions{display:none}.is-resolved .resolved-notice{display:block}.resolved-notice{display:none}.finish-review-label,.add-comment-label,.review-cancel-button,.is-review-pending .start-review-label{display:none}.start-review-label,.is-review-pending .finish-review-label,.is-review-pending .add-comment-label{display:inline-block}.is-review-pending .review-simple-reply-button{display:none}.is-review-pending .review-cancel-button{display:block}.is-review-pending .review-title-default{display:none}.is-review-pending .review-title-with-count{display:block}.review-title-default{display:block}.review-title-with-count{display:none}.pr-review-tools{margin-top:-4px}.pr-review-tools .Counter{display:none}.is-review-pending .pr-review-tools .Counter{display:inline-block}.pull-request-review-menu{top:30px;width:400px}.pull-request-review-menu::after,.pull-request-review-menu::before{display:none}.pull-request-review-menu .select-menu-header{border-radius:3px 3px 0 0}.pull-request-review-menu .form-actions{border-radius:0 0 3px 3px}.pull-request-review-menu .comment-form-head{display:none}.review-thread{border:1px #e1e4e8 solid;border-radius:3px}.review-thread:not(:last-child){margin-bottom:16px}.last-review-thread{padding:10px 10px 0;margin:10px -10px 0;border-top:1px solid #e1e4e8}.review-comment-contents{margin-left:44px}.review-comment-contents .timestamp{color:inherit;white-space:nowrap}.review-comment::after,.review-comment-loader::after,.review-comment.is-comment-editing::after{position:absolute;top:31px;left:29px;z-index:-1;width:3px;height:100%;content:"";background-color:#f6f8fa}.review-comment{position:relative;padding:8px 16px}.review-comment:first-child{padding-top:16px}.review-comment:last-child{padding-bottom:16px}.review-comment .comment-body,.review-comment .comment-reactions{padding:0}.review-comment .comment-body{padding-top:4px}.review-comment .comment-body .suggested-change-form-container:nth-last-of-type(2){margin-bottom:0 !important}.review-comment .comment-reactions{margin-top:5px;border-top:0}.review-comment .comment-reactions .add-reaction-btn{padding:4px 10px}.review-comment .comment-reactions.has-reactions{margin-top:12px}.review-comment .add-reaction-popover.dropdown-menu-sw,.review-comment .show-more-popover.dropdown-menu-sw{right:-5px;margin-top:5px}.review-comment .add-reaction-popover.dropdown-menu-ne{left:9px}.review-comment .reaction-summary-item:not(.add-reaction-btn){padding:0 8px;font-size:12px;line-height:26px;border:1px solid #d2dff0;border-radius:3px}.review-comment .reaction-summary-item:not(.add-reaction-btn) .emoji{font-size:16px;vertical-align:sub}.review-comment .reaction-summary-item:not(.add-reaction-btn)+.reaction-summary-item{margin-left:8px}.review-comment:last-child::after,.review-comment:last-child .review-comment-contents::after{display:none}.review-comment .timeline-comment-actions{opacity:0}.review-comment:hover .timeline-comment-actions,.review-comment.is-reacting .timeline-comment-actions{opacity:1}.review-comment .timeline-comment-action{padding:0 5px}.review-comment .timeline-comment-label{float:none;margin-top:0}.review-comment .is-comment-editing{position:relative;background-color:#fff;border:1px #e1e4e8 solid;border-radius:3px}.review-comment .is-comment-editing::after{top:100%;bottom:0;left:19px;height:20px}.review-comment .is-comment-editing .timeline-comment-actions,.review-comment .is-comment-editing .edit-comment-hide{display:none}.review-comment .is-comment-editing .previewable-comment-form{display:block}.review-comment.is-comment-loading .previewable-comment-form{opacity:0.5}.review-comment.is-comment-stale .comment-form-stale{display:block}.timeline-comment.is-comment-editing .discussion-item-header{display:none}.discussion-item-body .outdated-comment .hide-outdated-button{display:none}.discussion-item-body .outdated-comment.file{margin:4px 0}.discussion-item-body .outdated-comment .file-header{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.discussion-item-body .outdated-comment[open] .hide-outdated-button{display:block}.discussion-item-body .outdated-comment[open] .show-outdated-button{display:none}.discussion-item-body .outdated-comment[open] .file-header{border-bottom:1px #e1e4e8 solid;border-bottom-right-radius:0;border-bottom-left-radius:0}.discussion-item-body .outdated-comment .blob-code{position:static}.discussion-item-body .outdated-comment-label{height:26px;margin-top:3px;line-height:25px}.discussion-item-body .outdated-comment-label .octicon{top:1px}.review-thread-reply{padding:8px 16px;background-color:#f6f8fa;border-top:1px #e1e4e8 solid;border-radius:0 0 3px 3px}.discussion-item-review .review-thread-reply{margin-bottom:0;border-width:1px 0 0}.review-thread-reply .inline-comment-form{margin:-8px -16px;background-color:#fff;border:0}.review-thread-reply-button{display:inline-block;min-height:28px;padding:3px 8px;margin-left:8px;cursor:text}.review-summary-form-wrapper{display:none;margin-bottom:24px;margin-left:-20px;background-color:#fff;border:1px #e1e4e8 solid;border-radius:3px}.is-pending .review-summary-form-wrapper,.is-comment-editing .review-summary-form-wrapper{display:block}.is-pending .review-summary-form-wrapper{border-color:#d9d0a5}.tooltipped-left::after{right:auto;left:0}.tooltipped-left::before{right:auto;left:0}.discussion-item-review .edit-review{opacity:0;transition:opacity 0.15s ease 0s}.discussion-item-review:hover .edit-review{opacity:1}.diffstat-summary{padding:0 20px 0 0;font-size:16px;line-height:1.8;color:#586069;text-align:left;vertical-align:middle;border-radius:3px}.diffstat-summary a{color:#555}.diffstat-summary strong{color:#333}.authors-and-code .insertions{color:#28a745}.authors-and-code .deletions{color:#cb2431}.authors-and-code .section{display:table-cell;width:459px;height:150px}.pulse-authors-graph{position:relative;height:150px}.pulse-authors-graph>svg{width:100%}.pulse-authors-graph .dots{position:absolute;top:40px;right:0;left:0;width:64px;height:64px;margin:0 auto}.pulse-authors-graph .bar rect{fill:#f66a0a;fill-opacity:0.7}.pulse-authors-graph .bar rect:hover{fill-opacity:1}.summary-stats{display:table;width:100%;table-layout:fixed}.summary-stats li{display:table-cell;color:#586069;text-align:center;border-left:1px solid #e1e4e8}.summary-stats li a{display:block;padding-bottom:10px;color:#586069;text-decoration:none}.summary-stats li a:hover{background:#fafafa}.summary-stats li .octicon-git-pull-request{color:#6f42c1}.summary-stats li .octicon-git-branch{color:#28a745}.summary-stats li .octicon-issue-closed{color:#cb2431}.summary-stats li .octicon-issue-opened{color:#28a745}.summary-stats li:first-child{border-left:0;border-bottom-left-radius:3px}.summary-stats li .num{display:block;padding-top:10px;font-size:16px;font-weight:600;color:#000}.pulse-sections{margin-top:20px;clear:both}.pulse-section{padding:0;clear:both;font-size:14px;color:#666}.pulse-section p{margin-top:20px}.readme.contributing>div{max-height:250px;overflow:auto}.readme .markdown-body,.readme .plain{padding:45px;word-wrap:break-word;background-color:#fff;border:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.readme .plain pre{font-size:15px;white-space:pre-wrap}.file .readme .markdown-body{padding:45px;border:0;border-radius:0}.file .readme table[data-table-type="yaml-metadata"]{font-size:12px;line-height:1}.file .readme table[data-table-type="yaml-metadata"] table{margin:0}.release-timeline-tags .tag-timeline-date::after{position:absolute;top:50%;right:-7px;z-index:10;display:block;width:12px;height:12px;box-sizing:border-box;margin-top:-6px;content:" ";background-color:#e1e4e8;border:2px solid #fff;border-radius:6px}.release-timeline-tags.is-collapsed .expander{display:block !important}.release-timeline-tags.is-collapsed>.collapsable{display:none}.Label--draft{color:#cb2431;border-color:#d73a49}.Label--prerelease{color:#f66a0a;border-color:#f66a0a}.uploaded-files{border-top-left-radius:3px;border-top-right-radius:3px}.uploaded-files.not-populated+.drop-target p{border-top:1px #c3c8cf;border-top-left-radius:3px;border-top-right-radius:3px}.uploaded-files.is-populated{border:1px solid #ddd;border-bottom-color:#e5e5e5}.uploaded-files.is-populated+.drop-target p{border-top:0;border-top-left-radius:0;border-top-right-radius:0}.uploaded-files>li.delete{background:#f9f9f9}.uploaded-files>li.delete:nth-child(2){border-top-left-radius:3px;border-top-right-radius:3px}.uploaded-files>li.delete .delete-pending{display:block !important}.uploaded-files>li.delete .live{display:none !important}.uploaded-files>li:nth-child(2){border-top:0 !important}.uploaded-files .remove:hover{color:#cb2431 !important}.upload-progress{height:3px;margin-top:3px;border-radius:30px;box-shadow:0 1px 1px #fff,inset 0 1px 1px rgba(255,255,255,0.5)}.upload-progress .upload-meter{background-image:linear-gradient(#8dd2f7, #58b8f4);border-radius:30px}.release-entry{border-bottom:1px #e1e4e8 solid}.release-entry:last-child{border-bottom:0}@media (min-width: 768px){.release-tag-field{width:130px !important}.release-main-section{border-left:2px solid #e1e4e8}.release-entry{border-bottom:0}}.repo-file-upload-progress{position:relative;height:0;overflow:hidden;color:#246;background:#f7fbfe;border-bottom-right-radius:3px;border-bottom-left-radius:3px;box-shadow:0 0 0 1px #d0dbe7 inset;transition:height 0.2s ease-out}.repo-file-upload-progress.active{height:50px}.repo-file-upload-progress.is-file-list{border-bottom-right-radius:0;border-bottom-left-radius:0}.repo-file-upload-progress .repo-file-upload-meter{position:absolute;top:1px;left:1px;width:0;height:48px;background:#d8e8f7}.repo-file-upload-progress .repo-file-upload-meter-text{position:absolute;top:7px;left:10px}.repo-file-upload-progress .repo-file-upload-meter-text .repo-file-upload-info{display:block;font-weight:600}.repo-file-upload-progress .repo-file-upload-meter-text .repo-file-upload-meter-filename{display:block;margin:0}.manifest-commit-form{margin-top:20px}.repo-file-upload-outline{width:100%;height:100%}.repo-file-upload-target{position:relative;padding-top:100px;padding-bottom:80px;color:#666}.repo-file-upload-target.is-progress-bar,.repo-file-upload-target.is-uploading{border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.repo-file-upload-target.is-file-list{border-bottom-right-radius:0;border-bottom-left-radius:0}.repo-file-upload-target.is-uploading .repo-file-upload-text.initial-text,.repo-file-upload-target.is-failed .repo-file-upload-text.initial-text,.repo-file-upload-target.is-default .repo-file-upload-text.initial-text{display:none}.repo-file-upload-target.is-uploading .repo-file-upload-text.alternate-text,.repo-file-upload-target.is-failed .repo-file-upload-text.alternate-text,.repo-file-upload-target.is-default .repo-file-upload-text.alternate-text{display:block}.repo-file-upload-target.is-uploading.dragover .repo-file-upload-text,.repo-file-upload-target.is-failed.dragover .repo-file-upload-text,.repo-file-upload-target.is-default.dragover .repo-file-upload-text{display:none}.repo-file-upload-target .repo-file-upload-text.initial-text{display:block}.repo-file-upload-target .repo-file-upload-text.alternate-text{display:none}.repo-file-upload-target .repo-file-upload-text,.repo-file-upload-target .repo-file-upload-drop-text{margin-bottom:5px}.repo-file-upload-target .repo-file-upload-choose{display:inline-block;margin-top:0;font-size:18px}.repo-file-upload-target .manual-file-chooser{margin-left:0}.repo-file-upload-target .repo-file-upload-outline{position:absolute;top:3%;left:1%;width:98%;height:94%}.repo-file-upload-target.is-failed .repo-file-upload-outline,.repo-file-upload-target.is-bad-file .repo-file-upload-outline,.repo-file-upload-target.is-too-big .repo-file-upload-outline,.repo-file-upload-target.is-too-many .repo-file-upload-outline,.repo-file-upload-target.is-empty .repo-file-upload-outline{height:85%}.repo-file-upload-target.dragover .repo-file-upload-text{display:none}.repo-file-upload-target.dragover .repo-file-upload-choose{visibility:hidden}.repo-file-upload-target.dragover .repo-file-upload-drop-text{display:block}.repo-file-upload-target.dragover .repo-file-upload-outline{border:6px #ddd dashed;border-radius:5px}.repo-file-upload-target .repo-file-upload-drop-text{display:none}.repo-file-upload-errors{display:none}.repo-file-upload-errors .error{display:none}.is-failed .repo-file-upload-errors,.is-bad-file .repo-file-upload-errors,.is-too-big .repo-file-upload-errors,.is-too-many .repo-file-upload-errors,.is-hidden-file .repo-file-upload-errors,.is-empty .repo-file-upload-errors{position:absolute;right:0;bottom:0;left:0;display:block;padding:5px 8px;line-height:1.5;text-align:left;background-color:#fff;border-top:1px solid #e5e5e5;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.is-file-list .repo-file-upload-errors{border-bottom-right-radius:0;border-bottom-left-radius:0}.is-failed .repo-file-upload-errors .failed-request,.is-bad-file .repo-file-upload-errors .failed-request{display:inline-block}.is-too-big .repo-file-upload-errors .too-big{display:inline-block}.is-hidden-file .repo-file-upload-errors .hidden-file{display:inline-block}.is-too-many .repo-file-upload-errors .too-many{display:inline-block}.is-empty .repo-file-upload-errors .empty{display:inline-block}.repo-file-upload-tree-target{position:fixed;top:0;left:0;z-index:1000;width:100%;height:100%;padding:12px;color:#666;visibility:hidden;background:radial-gradient(ellipse at center, #fff 0%, rgba(255,255,255,0.85) 65%, rgba(255,255,255,0.85) 100%);opacity:0;transition:visibility 0.2s, opacity 0.2s}.repo-file-upload-tree-target .repo-file-upload-outline{border:6px #ddd dashed;border-radius:5px}.dragover .repo-file-upload-tree-target{visibility:visible;opacity:1}.dragover .repo-file-upload-tree-target .repo-file-upload-slate{top:50%;opacity:1}.dragover .repo-file-upload-tree-target .files-lg>.file-graph{opacity:1;transform:translateX(4px)}.dragover .repo-file-upload-tree-target .files-lg>.file-zip{opacity:1;transform:translateX(9px)}.dragover .repo-file-upload-tree-target .files-lg>.file-generic{opacity:1;transform:translateX(-4px)}.dragover .repo-file-upload-tree-target .files-lg>.file-acrobat{opacity:1;transform:translateX(-9px)}.repo-file-upload-slate{position:absolute;top:50%;width:100%;text-align:center;transform:translateY(-50%)}.repo-file-upload-slate h2{margin-top:5px}.repo-file-upload-slate .file-graph{opacity:0;transition:opacity 0.2s 0.12s cubic-bezier(0.175, 0.885, 0.32, 1.275),transform 0.2s 0.12s cubic-bezier(0.175, 0.885, 0.32, 1.275);transform:translateX(50px)}.repo-file-upload-slate .file-zip{opacity:0;transition:opacity 0.2s 0.12s cubic-bezier(0.175, 0.885, 0.32, 1.275),transform 0.2s 0.12s cubic-bezier(0.175, 0.885, 0.32, 1.275);transform:translateX(90px)}.repo-file-upload-slate .file-generic{opacity:0;transition:opacity 0.2s 0.12s cubic-bezier(0.175, 0.885, 0.32, 1.275),transform 0.2s 0.12s cubic-bezier(0.175, 0.885, 0.32, 1.275);transform:translateX(-50px)}.repo-file-upload-slate .file-acrobat{opacity:0;transition:opacity 0.2s 0.12s cubic-bezier(0.175, 0.885, 0.32, 1.275),transform 0.2s 0.12s cubic-bezier(0.175, 0.885, 0.32, 1.275);transform:translateX(-90px)}.repo-file-upload-file-wrap .name{color:#888}.repo-file-upload-file-wrap .actions{width:50px;padding-right:10px;text-align:right}.repo-file-upload-file-wrap .remove-file{color:#888}.repo-file-upload-file-wrap .remove-file:hover{color:#666}.repo-upload-breadcrumb{margin-bottom:18px}.labels-list .blankslate{display:none}.labels-list .table-list-header{display:block}.labels-list.is-empty .blankslate{display:block}.labels-list.is-empty .table-list-header{display:none}.labels-list-item .table-list-cell{width:100%}.label-description{padding:8px 16px}.label-delete-confirmation{line-height:34px}.labels-list-action{display:block;float:left;padding:8px 10px;color:#586069}.labels-list-action .octicon{margin-right:2px}.labels-list-action .octicon-pencil{font-size:14px}.sidebar-labels .sidebar-labels-style{margin-top:3px}.label-select-menu-item .g-emoji{font-size:12px;line-height:1;vertical-align:baseline}.new-label{padding:10px;margin-bottom:15px;background-color:#fafbfc;border:1px solid #e5e5e5;border-radius:3px}.new-label .label-edit::before{display:table;content:""}.new-label .label-edit::after{display:table;clear:both;content:""}.label-edit::before{display:table;content:""}.label-edit::after{display:table;clear:both;content:""}.label-edit label{display:block;margin-bottom:8px}.label-edit .error{float:left;margin-top:8px;margin-left:10px;color:#f00}.label-edit.is-valid .octicon-check{display:block}.label-edit.loading{display:block}.label-delete-form{display:inline}.label-delete-form.loading .label-delete-spinner{display:block}.label-delete-spinner{display:none;float:left;margin-top:10px;margin-right:10px}.label-characters-remaining{color:#586069}.emoji-size-boost .IssueLabel .g-emoji{top:0;font-size:1.15em;line-height:1.1}.repo-list{position:relative}.repo-list-item{position:relative;padding-top:30px;padding-bottom:30px;list-style:none;border-bottom:1px solid #eee}.repo-list-item-with-avatar{padding-left:42px}.repo-list-item-hanging-avatar{float:left;margin-left:-42px}.mini-repo-list-item{position:relative;display:block;padding:6px 64px 6px 30px;font-size:14px;border-top:1px solid #d1d5da}.mini-repo-list-item:hover{text-decoration:none}.mini-repo-list-item:hover .repo,.mini-repo-list-item:hover .owner{text-decoration:underline}.mini-repo-list-item .repo-icon{float:left;margin-top:2px;margin-left:-20px;color:#666}.mini-repo-list-item .repo-and-owner{max-width:220px}.mini-repo-list-item .owner{max-width:110px}.mini-repo-list-item .repo{font-weight:600}.mini-repo-list-item .stars{position:absolute;top:0;right:10px;margin-top:6px;font-size:12px;color:#6a737d}.mini-repo-list-item .repo-description{display:block;max-width:100%;font-size:12px;line-height:21px;color:#586069}.private .mini-repo-list-item{background-color:#fffdef}.private .mini-repo-list-item .repo-icon{color:rgba(27,31,35,0.7)}.filter-bar{padding:10px;background-color:#fafbfc;border-bottom:1px solid #e5e5e5}.filter-bar::before{display:table;content:""}.filter-bar::after{display:table;clear:both;content:""}.user-repos .filter-bar{text-align:center}.url-box{width:100%;height:26px;padding:10px 10px 0;margin-top:10px;margin-left:-10px;border-top:1px solid #ddd}.url-box p{float:left;height:26px;margin:0 0 0 5px;line-height:26px}.url-box p strong{color:#000}.clone-url-button{display:table-cell;width:1%;vertical-align:top}.clone-url-button:first-child .clone-url-link{border-top-left-radius:3px;border-bottom-left-radius:3px}.clone-url-button>.clone-url-link{position:relative;display:block;padding:0 9px;margin-right:-1px;font-size:11px;font-weight:600;line-height:26px;color:#333;text-decoration:none;white-space:nowrap;cursor:pointer;background-image:linear-gradient(#fafafa, #eaeaea);border:1px solid #ccc}.clone-url-button>.clone-url-link:hover,.clone-url-button>.clone-url-link:active{z-index:3;color:#fff;text-decoration:none;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-image:linear-gradient(#599bcd, #3072b3);border-color:#2a65a0}.clone-url-button>.clone-url-link:active{background-color:#3072b3;background-image:none;border-color:#25588c;box-shadow:inset 0 3px 5px rgba(0,0,0,0.15)}.clone-url-button>.clone-url-link:focus{outline:0}.clone-url-button+.clone-url-button>.clone-url-link{box-shadow:inset 1px 0 0 #fff}.clone-url-button+.clone-url-button>.clone-url-link:hover{box-shadow:none}.clone-url-button+.clone-url-button>.clone-url-link:active{box-shadow:inset 0 3px 5px rgba(0,0,0,0.15)}.clone-url-button.selected>.clone-url-link,.clone-url-button.selected>.clone-url-link:hover{z-index:2;color:#333;text-shadow:0 1px 0 rgba(255,255,255,0.6);background-color:#ccc;background-image:linear-gradient(#ccc, #d5d5d5);border-color:#bbb;box-shadow:inset 0 2px 3px rgba(0,0,0,0.075)}.url-box-clippy .zeroclipboard-button{margin-left:0 !important;border-left:0;border-radius:0 3px 3px 0}.repository-import .repository-import-label{display:block;margin-bottom:8px;font-size:18px;font-weight:400}.repository-import .state-header{font-size:16px}.text-yellow{color:rgba(115,92,15,0.5)}.timeout{width:auto;height:300px;padding:0;margin:20px 0;background-color:transparent;border:0}.timeout h3{padding-top:100px;color:#586069}.overall-summary{position:relative;margin-bottom:10px;border:1px solid #dfe2e5;border-radius:3px}.overall-summary-bottomless{margin-bottom:0;border-bottom:0;border-radius:3px 3px 0 0}.numbers-summary{display:table;width:100%;table-layout:fixed}.numbers-summary li{display:table-cell;padding:0;text-align:center;white-space:nowrap}.numbers-summary a,.numbers-summary .nolink{display:block;padding:10px 0;color:#586069;text-decoration:none}.numbers-summary .octicon{color:#6a737d}.numbers-summary a:hover{color:#0366d6}.numbers-summary a:hover .num{color:inherit}.repo-language-color{position:relative;top:1px;display:inline-block;width:12px;height:12px;border-radius:50%}.repository-meta{margin:0 0 20px;clear:both;font-size:16px;color:#586069}.repository-meta::before{display:table;content:""}.repository-meta::after{display:table;clear:both;content:""}.repository-meta .repo-description-field{width:540px}.repository-meta .repo-website-field{width:300px}.repository-meta .repository-meta-content{display:inline-block}.repository-meta .edit-repository-meta{display:none;margin-bottom:5px;font-size:13px}.repository-meta .edit-repository-meta .field{display:inline-block;margin-right:5px}.repository-meta .edit-repository-meta label{display:block;margin-bottom:6px;font-weight:600;color:#24292e}.repository-meta.open .repository-meta-content,.repository-meta.open .edit-link{display:none}.repository-meta.open .edit-repository-meta{display:block;margin-bottom:20px}.experiment-repo-nav .capped-cards .capped-card{width:480px}.experiment-repo-nav .new-issue-form{padding-top:0;border-top:0}.experiment-repo-nav.repohead .repo-mirror{padding-left:20px}.iconbutton .octicon{margin-right:0}.file-navigation::before{display:table;content:""}.file-navigation::after{display:table;clear:both;content:""}.file-navigation.in-mid-page{margin-top:15px}.file-navigation .select-menu-button .css-truncate-target{max-width:200px}.file-navigation .branch-select-menu{margin-right:6px;margin-bottom:10px}.file-navigation .new-pull-request-btn{float:left}.file-navigation .breadcrumb{float:left;margin-top:0;margin-left:5px;font-size:16px;line-height:26px}.file-navigation+.breadcrumb{margin-bottom:10px}.file-navigation .BtnGroup{margin-bottom:10px;margin-left:10px}.file-navigation .get-repo-select-menu{margin-left:6px}.file-navigation .get-repo-modal{top:6px;width:352px}.file-navigation .get-repo-modal .https-clone-options{display:block}.file-navigation .get-repo-modal .ssh-clone-options{display:none}.file-navigation .get-repo-modal.on .https-clone-options{display:none}.file-navigation .get-repo-modal.on .ssh-clone-options{display:block}.file-navigation .get-repo-modal .get-repo-modal-options{display:block}.file-navigation .get-repo-modal.is-downloading .get-repo-modal-options{display:none}.file-navigation .get-repo-modal .animated-ellipsis-container{width:16px;height:16px}.file-navigation .get-repo-modal .animated-ellipsis-container>.animated-ellipsis{animation:ellipsis 1s infinite}@keyframes ellipsis{from{width:2px}to{width:16px}}.file-navigation .btn-change-protocol{font-size:12px}.file-navigation .get-repo-decription-text{font-size:13px}.file-navigation .get-repo-btn{float:left;width:50%;padding:10px 0;text-align:center;border:0;border-top:1px solid #e1e4e8;border-radius:0}.file-navigation .get-repo-btn:first-child{border-right:1px solid #e1e4e8;border-bottom-left-radius:3px}.file-navigation .get-repo-btn:nth-child(1):nth-last-child(3){border-radius:0}.file-navigation .get-repo-btn:last-child{border-bottom-right-radius:3px}.file-navigation .get-repo-btn.btn-block,.file-navigation .get-repo-btn:only-child{width:100%;border-right:0;border-radius:0 0 3px 3px}.file-navigation .clone-options{padding:8px 16px 16px}.file-wrap,.details-truncate-file-list.Details--on .file-wrap{max-height:none;margin-bottom:10px;border:1px solid #dfe2e5;border-top:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.file-wrap .include-fragment-error,.details-truncate-file-list.Details--on .file-wrap .include-fragment-error{display:none}.file-wrap.is-error .include-fragment-error,.details-truncate-file-list.Details--on .file-wrap.is-error .include-fragment-error{display:table-row}.details-truncate-file-list .file-wrap{max-height:185px;margin-bottom:0;overflow-y:scroll;border-bottom-right-radius:0;border-bottom-left-radius:0}.details-truncate-file-list .file-wrap .files{border-bottom-right-radius:0;border-bottom-left-radius:0}.details-truncate-file-list .btn-truncate-file-list{background:#fff;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.details-truncate-file-list .btn-truncate-file-list:hover{background:#f6f8fa}table.files{width:100%;background:#fff;border-radius:2px}table.files tr[aria-selected="true"] td,table.files tr.navigation-focus td{background:#f6f8fa}table.files td{padding:6px 3px;line-height:20px;border-top:1px solid #eaecef}table.files td.icon{width:17px;padding-right:2px;padding-left:10px;color:rgba(3,47,98,0.55)}table.files td.icon .octicon-file-directory{color:rgba(3,47,98,0.5)}table.files td.icon .spinner{position:relative;top:3px;display:none;margin-top:-3px;margin-left:-2px}table.files td .simplified-path{color:#6a737d}table.files td .css-truncate{max-width:100%}table.files td.content{max-width:180px}table.files td.message{max-width:442px;padding-left:10px;overflow:hidden;color:#6a737d}table.files td.message .emoji{vertical-align:top}table.files td.message a{color:#6a737d}table.files td.message a:hover{color:#0366d6}table.files td.age{width:125px;padding-right:10px;color:#6a737d;text-align:right;white-space:nowrap}table.files .message .tooltipped::before,table.files .message .tooltipped::after{display:none}table.files tr.is-loading td.icon .octicon{display:none}table.files tr.is-loading td.icon .spinner{display:inline-block}table.files tr.up-tree{border-top:1px solid #eaecef;border-bottom:1px solid #eaecef}table.files tr.up-tree a{padding:3px 6px;margin-left:-3px;font-weight:600;border-radius:2px}table.files tr.up-tree a:hover{background-color:#dfe2e5}table.files tbody tr:first-child td{border-top:0}.branch-infobar{padding:8px;color:#586069;background-color:#fafbfc;border:solid #dfe2e5;border-width:1px 1px 0;border-top-left-radius:3px;border-top-right-radius:3px}.branch-infobar::before{display:table;content:""}.branch-infobar::after{display:table;clear:both;content:""}.branch-infobar .muted-link{display:inline-block;margin-left:10px}.branch-infobar .muted-link .octicon{color:#959da5}.branch-infobar .muted-link:hover .octicon{color:inherit}.spinner-forking{display:block;margin:20px auto 40px}.prereceive-feedback{padding:15px;margin-bottom:15px;border:1px solid #dfe2e5;border-left:3px solid #caa21a;border-radius:3px}.prereceive-feedback-heading{margin-top:0;margin-bottom:10px;color:#b08800}.file-navigation-options{float:right;margin-left:3px}.file-navigation-options.active .dropdown-menu-content{display:block}.file-navigation-options .dropdown-menu{width:360px;padding:15px}.file-navigation-options .dropdown-divider{margin:15px -15px}.file-navigation-option{position:relative;display:inline-block;margin-left:3px}.file-navigation-option .select-menu{display:inline-block;margin-right:0;margin-bottom:0;vertical-align:middle}.file-navigation-option .select-menu-button .octicon:only-child{margin-left:2px}.file-navigation-option .zeroclipboard-button{padding-right:8px}.file-navigation-option .input-group{width:290px}.file-navigation-option .input-group .form-control{width:calc(100% + 2px);height:28px;min-height:0;margin-right:-1px;margin-left:-1px;border-radius:0}.file-navigation-option .input-group .select-menu-button{position:relative;z-index:2}.profile-picture{margin:10px 0 0}.profile-picture>p{float:left;margin:0;line-height:30px}.profile-picture>img{float:left;margin:0 10px 0 0;border-radius:3px}.app-owner{margin:15px 0 0}.edit-profile-avatar{width:200px}.edit-profile-avatar .drag-and-drop{padding:0;color:#666;border-width:0}.edit-profile-avatar input{cursor:pointer}.edit-profile-avatar.is-bad-file{border:0}.edit-profile-avatar .manual-file-chooser{position:absolute;top:0;left:0;height:34px;padding:0;cursor:pointer}.button-change-avatar{overflow:hidden}.profile-picture-spinner{background-image:url("/images/spinners/octocat-spinner-128.gif");background-repeat:no-repeat;background-position:center;background-size:64px 64px}.avatar-upload .flash{width:100%;padding:30px 15px;border:dashed 1px #d73a49;box-shadow:none}.avatar-upload .upload-state{display:none;padding:10px 0}.avatar-upload .upload-state p{margin:0;font-size:12px;color:#586069}.avatar-upload .avatar-upload .octicon{display:inline-block}.is-uploading .avatar-upload .loading{display:block;padding:0}.is-uploading .avatar-upload .loading img{vertical-align:top}.is-uploading .avatar-upload .button-change-avatar{display:none}.is-bad-file .avatar-upload .bad-file{display:block;margin:0}.is-too-big .avatar-upload .too-big{display:block;margin:0}.is-bad-dimensions .avatar-upload .bad-dimensions{display:block;margin:0}.is-bad-format .avatar-upload .bad-format{display:block;margin:0}.is-failed .avatar-upload .failed-request{display:block;margin:0}.is-empty .avatar-upload .file-empty{display:block;margin:0}dl.new-email-form{padding:10px 10px 0;margin:0 -10px 10px;border-top:1px solid #e5e5e5}.email-actions{float:right}.email-actions>span{float:left}.email-actions form{display:inline}.email-actions span.label{padding:0 10px;font-size:13px;color:#586069}.email-actions .octicon-alert{color:#ca5633}.boxed-group .fork-flag{margin-left:16px;font-size:12px;color:#586069}.selected-user-key{background-color:#fffdef}.user-key-type{padding-right:20px;padding-left:10px;text-align:center}.user-key-badge{display:block;padding-right:5px;padding-left:5px;margin-top:3px;font-size:12px;line-height:1.4;border:solid 1px #ddd;border-radius:3px}.user-key-email-badge{display:inline-table;margin-right:4px}.user-key-email{display:table-cell;padding:1px 5px;font-size:12px;line-height:1.4;border:solid 1px #ddd;border-radius:3px}.user-key-email.unverified{border-top-right-radius:0;border-bottom-right-radius:0}.user-key-email-unverified{display:table-cell;padding-right:5px;padding-left:5px;font-size:11px;color:#666;background-color:#ecebec;border:solid 1px #ddd;border-left:0;border-top-right-radius:3px;border-bottom-right-radius:3px}.user-key-details{width:400px;line-height:1.6;white-space:normal}.user-key-details code{font-size:13px}.recent-user-key{color:#28a745}.recent-user-key-access{color:#1e7e34}.unverified-user-key,.unverified-user-key-notice{color:#cb2431}.notification-center .overview{padding:0 10px 10px;border-bottom:1px solid #ddd}.oauth-app-info-container .float-left-container{float:left;text-align:left}.oauth-app-info-container .float-right-container{float:right;text-align:right}.oauth-app-info-container dl.keys{margin:10px 0}.oauth-app-info-container dl.keys dt{margin-top:10px;font-weight:600;color:#586069}.oauth-app-info-container dl.keys dd{font-family:"SFMono-Regular",Consolas,"Liberation Mono",Menlo,Courier,monospace;color:#333}.oauth-app-info-container .user-count{font-size:30px;font-weight:300;color:#586069}.logo-uploader-container{display:block}.logo-upload{position:relative;display:inline-block}.logo-upload a.delete,.logo-upload span.delete{position:absolute;left:88px;display:none;padding:8px 10px}.logo-upload a.delete:hover,.logo-upload span.delete:hover{color:#cb2431}.logo-upload-container{display:inline-block}.logo-upload-container .logo-upload-label .manual-file-chooser{top:0;left:0;width:130px;height:34px;padding:0;margin-left:0;cursor:pointer}.logo-upload-container .upload-state{padding:10px 0}.logo-upload-container .upload-state p{margin:0;font-size:12px;color:#586069}.logo-box{display:inline-block;float:left;width:120px;height:120px;background-color:#eee;border:1px solid #ccc;border-radius:3px}.logo-box img{display:none;width:118px;height:118px;border-radius:3px}.logo-placeholder{color:#586069;text-align:center;text-shadow:0 1px 0 #fff}.logo-placeholder p{margin:0;font-size:14px}.has-uploaded-logo .logo-placeholder,.has-uploaded-logo .or{display:none}.has-uploaded-logo:hover a.delete,.has-uploaded-logo:hover span.delete{display:block}.has-uploaded-logo .logo-box img{display:block}.saved-reply-form{border:1px solid #ddd;border-radius:3px}.saved-reply-form .tabnav-tab.selected{border-radius:3px 3px 0 0}.saved-reply-form .form-actions{margin-right:10px;margin-bottom:8px}.saved-reply-form .comment{border:0}.saved-reply-form .comment-body{padding:5px 5px 15px;background-color:transparent;border-bottom:1px solid #eee}.saved-reply-settings-container.has-replies .listgroup{display:block}.saved-reply-settings-container.has-replies .blankslate{display:none}.saved-reply-settings-container .listgroup{display:none}.access-token{border-bottom:1px solid #e5e5e5}.access-token:last-child{border:0}.access-token .last-used{margin-right:10px}.access-token .zeroclipboard-link{display:inline-block;vertical-align:text-bottom}.access-token.new-token{background-color:rgba(108,198,68,0.1)}.access-token.new-token .octicon-check{color:#28a745}.access-token .token-description{max-width:450px;color:#24292e}.access-token .token{font-size:14px}.access-token .sso-ready-badge{display:inline-block;padding:1px 4px;font-size:10px;line-height:16px;color:#767676;vertical-align:middle;background:none;border:1px solid #e5e5e5;border-radius:2px}.access-token .sso-ready-badge:focus{outline:none}.access-token .sso-ready-badge:hover{border-color:#ccc}.access-token .sso-ready-badge.ready{color:#55a532}.access-token .sso-ready-badge.ready:hover{border-color:#55a532}.access-token .credential-authorization-statuses{position:relative;display:inline-block}.access-token .credential-authorization-statuses.active .dropdown-menu-content{display:block}.access-token .credential-authorization-statuses .dropdown-menu{top:-4px;min-width:400px;max-width:500px;padding-top:0;padding-bottom:0}.access-token .credential-authorization-menu{padding:15px;font-size:13px;line-height:1.4}.access-token .credential-authorization-menu .status-heading{color:#24292e}.access-token .credential-authorization-status-list{max-height:235px;padding:0;margin:15px -15px -15px;overflow:scroll;border-top:1px solid #eee;transition:max-height 0.25s ease-in-out}.access-token .credential-authorization-status-item{position:relative;padding:10px 15px 10px 12px;background-color:#fafbfc;border-bottom:1px solid #eee}.access-token .credential-authorization-status-item:last-child{border-bottom:0;border-radius:0 0 2px 2px}.access-token .credential-authorization-status-icon{width:30px;margin-right:10px}.access-token .credential-authorization-status-avatar{position:relative;top:5px}.regenerate-token-cta .btn-danger{margin-left:30px}.personal-access-tokens-group{padding:0 10px}.personal-access-tokens label{display:inline}.personal-access-tokens label p{display:inline-block;margin:0;font-size:13px;font-weight:400}.personal-access-tokens .child-scopes{margin-left:20px;list-style:none}.personal-access-tokens .child-scopes .token-scope{width:180px;font-weight:400}.personal-access-tokens .child-scopes .child-scopes{margin-left:0}.token-scope{display:inline-block;width:200px;padding:2px 0;margin:0;font-size:13px;color:#24292e}.token-scope input{margin-right:5px}.callback-urls dl dd .form-control{width:100%}.callback-urls.has-many .callback-url-action-cell{display:table-cell}.callback-description{margin-top:20px}.callback-description .octicon{padding-left:0}.callback-url .label{display:none;width:64px;text-align:center}.callback-url.is-default-callback .label{display:inline-block}.callback-url.is-default-callback .btn{display:none}.callback-url-wrap{display:table;width:100%}.callback-url-field-cell{display:table-cell}.callback-url-action-cell{display:none;width:70px;text-align:right}.boxed-group.application-show-group dl.form-group>dd .form-control.wide{width:460px}.boxed-group.application-show-group dl.form-group>dd .form-control.short{height:50px;min-height:50px}.application-show-group .errored .note{display:none}.application-show-group .drag-and-drop{padding:0;text-align:left;background-color:transparent;border:0}.application-show-group .drag-and-drop img{margin-bottom:1px;vertical-align:bottom}.application-show-group .drag-and-drop span{padding:0}.application-show-group .dragover .logo-box{box-shadow:#c9ff00 0 0 3px}.application-show-group .is-uploading .loading{display:inline-block}.application-show-group .is-uploading .default{display:none}.application-show-group .is-failed .failed-request{display:inline-block}.application-show-group .is-failed .default{display:none}.application-show-group .is-bad-file .bad-file{display:inline-block}.application-show-group .is-bad-file .default{display:none}.application-show-group .is-too-big .file-too-big{display:inline-block}.application-show-group .is-too-big .default{display:none}.application-show-group .is-bad-format .bad-format{display:inline-block}.application-show-group .is-bad-format .default{display:none}.application-show-group .is-default .default{display:block}.post-recovery-token .octospinner,.post-recovery-token .create-recovery-token-error{display:none}.post-recovery-token.loading .octospinner{display:block}.post-recovery-token.failed .create-recovery-token-error{display:block}.security-history .security-history-timestamp{float:right;color:#586069}table.security-history-detail{width:100%;font-size:12px}table.security-history-detail td{max-width:200px;word-wrap:break-word}.settings-email .email-actions .settings-remove-email{float:right;padding-right:7px;padding-left:7px;margin-left:5px;line-height:24px;color:#cb2431;cursor:pointer}.settings-email .email-actions .settings-remove-email.settings-disabled-remove-email{display:block;color:#6a737d}.settings-email .octicon-info{margin-left:5px}.settings-email .css-truncate-target{max-width:300px}.email-preference-exceptions{font-size:12px}.email-preference-exceptions h5{margin:15px 0 5px;color:#666}.email-preference-exceptions .exception-list{list-style:none}.email-preference-exceptions .exception{max-width:400px;padding:5px;padding-left:0;border-top:1px solid #eee}.email-preference-exceptions .exception:last-child{border-bottom:1px solid #eee}.email-preference-exceptions.opt-in-list{display:none}.transactional-only .email-preference-exceptions.opt-in-list{display:block}.transactional-only .email-preference-exceptions.opt-out-list{display:none}.two-factor-intro{width:675px;margin:40px auto 0}.two-factor-intro .two-factor-graphic{margin:20px 0}.two-factor-intro .two-factor-explain{padding:0;margin:0 0 40px;font-size:13px;list-style:none}.two-factor-intro .two-factor-explain li{float:left;padding:0;margin:0}.two-factor-intro .two-factor-explain .step-one{width:185px;margin-right:36px}.two-factor-intro .two-factor-explain .step-two{width:230px;margin-right:42px}.two-factor-intro .two-factor-explain .step-three{width:180px}.two-factor-graphic{width:675px;height:135px;background-image:url("/images/modules/settings/2fa_guide.png");background-repeat:no-repeat}.two-factor-recovery-codes{margin:30px 0;font-family:"SFMono-Regular",Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:21px}.two-factor-recovery-code-mark{width:24px;height:24px;font-size:24px;line-height:16px;color:#bbb}.two-factor-recovery-code{display:inline-block;width:48%;line-height:1.6;text-align:center}.two-factor-recovery-code::before{position:relative;top:-3px;margin-right:10px;font-size:10px;color:#d8d8d8;content:"\25CF"}.recovery-codes-saving-options{margin-left:35px}.recovery-codes-saving-options .recovery-code-save-button{width:115px;margin-right:15px;text-align:center}.recovery-codes-warning{margin:0 -15px}.recovery-codes-warning .recovery-codes-warning-octicon{height:40px;margin-right:15px}@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-moz-min-device-pixel-ratio: 2), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx){.two-factor-graphic{background-image:url("/images/modules/settings/2fa_guide@2x.png");background-size:675px 135px}}.btn-two-factor-state{min-width:70px}.sms-or-app{width:100%;padding:40px 0 0;margin:0;border-top:1px solid #ddd}.sms-or-app::before{display:table;content:""}.sms-or-app::after{display:table;clear:both;content:""}.sms-or-app li{float:left;width:325px;padding:0;list-style:none}.sms-or-app li:first-child{margin-right:25px}.sms-or-app li .btn{display:block;width:100%;height:100%;padding-top:12px;padding-bottom:12px;margin:10px 0;font-size:15px;text-align:center}.sms-or-app small{font-size:80%}.app-only{padding:20px 0 0}.app-only li{float:none;width:auto}.app-only li .btn{display:inline-block;width:auto;padding-right:20px;padding-left:20px}.two-factor-wrapper{width:500px;margin:40px auto}.two-factor-lead{font-size:16px}.two-factor-qr-code{text-align:center}.two-factor-steps{padding:15px 15px 0;margin:30px 0;border:1px solid #eee;border-radius:3px}.two-factor-steps .error-icon{position:relative;top:2px;left:5px;color:#cb2431}.two-factor-steps .sent-message{position:relative;top:2px;left:5px;color:#28a745}.container.two-factor-toggle{width:700px}.sms-country-code-field{padding-right:10px}.two-factor-toggle{margin-top:40px}.two-factor-toggle .two-factor-status{padding:20px 0;margin:0 0 20px;color:#586069;border-bottom:1px solid #eaeaea}.two-factor-toggle .two-factor-status p{margin:0}.two-factor-toggle .two-factor-status .btn{position:relative;top:-3px;float:right}.two-factor-toggle .two-factor-on{padding:3px 5px;margin-right:5px;color:#fff;text-shadow:0 1px 1px rgba(0,0,0,0.1);background-color:#28a745;border-radius:2px}.two-factor-settings-group{position:relative;padding:0 0 20px 220px;margin:0 0 20px;border-bottom:1px solid #ddd}.two-factor-settings-group>h3{position:absolute;left:0;width:200px;font-size:14px}.two-factor-settings-group>h3 .octicon{position:absolute;left:-24px;color:#cb2431}.two-factor-settings-group li{line-height:1.5;list-style:none}.u2f-registrations{padding-left:24px}.u2f-registration{position:relative;padding-bottom:8px;margin-bottom:8px;border-bottom:1px solid #f8f8f8}.u2f-registration.is-sending .u2f-registration-delete{display:none}.u2f-registration.is-sending .spinner{position:relative;top:3px}.u2f-registration-nickname{font-weight:600}.u2f-registration-icon{position:absolute;left:-24px;color:rgba(47,38,6,0.5)}.new-u2f-registration{position:relative}.new-u2f-registration .add-u2f-registration-form{display:none;margin-bottom:10px}.new-u2f-registration.is-active .add-u2f-registration-link{display:none}.new-u2f-registration.is-active .add-u2f-registration-form{display:block}.new-u2f-registration .u2f-request-interaction,.new-u2f-registration .u2f-request-error{display:none}.new-u2f-registration.is-sending .u2f-request-interaction{display:block}.new-u2f-registration.is-showing-error .u2f-request-error{display:block}.new-u2f-registration .u2f-error-icon{font-size:64px}.u2f-box .u2f-sorry{display:block}.u2f-box .new-u2f-registration{display:none}.u2f-box.available .u2f-sorry{display:none}.u2f-box.available .new-u2f-registration{display:block}.github-access-banner{position:relative;padding:10px 20px 10px 70px;margin:0 0 20px;font-size:14px;border:1px solid #ddd;border-radius:3px}.github-access-banner .octicon{position:absolute;top:20px;left:20px;color:#cb2431}.error-icon,.spinner,.sent-message,.sms-error-message{display:none}.sms-error-message{margin-top:15px}.is-sending .spinner{display:inline-block}.is-sent .sent-message{display:inline-block}.is-not-sent .sms-error-message{display:block}.is-not-sent .error-icon{display:inline-block}.qr-code-table{display:inline-block;padding:20px;margin:30px auto;border:1px solid #eee;border-radius:3px;box-shadow:0 2px 2px 0 rgba(0,0,0,0.04)}.qr-code-table tr{background:transparent;border:0}.qr-code-table th,.qr-code-table td{padding:0;border:0}.qr-code-table td{width:3px;height:3px}.qr-code-table .black{background:#000}.qr-code-table .white{background:#fff}.confirmation-phrase{font-style:italic;font-weight:400}.do-not-copy-me{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.session-device{position:relative;padding:15px;line-height:18px;color:#586069}.session-device .btn{float:right;margin-top:4px}.session-device .session-state-indicator{float:left;width:8px;height:8px;margin-top:10px;border-radius:5px}.session-device .session-state-indicator.recent{background-color:#28a745;box-shadow:0 0 10px rgba(108,198,68,0.5)}.session-device .session-state-indicator.not-recent{background-image:linear-gradient(#aaa, #ccc);box-shadow:0 1px 0 #fff}.session-device .session-icon{float:left;width:32px;margin-top:1px;margin-left:15px;color:#bbb;text-align:center}.session-device .sessions-more-info{margin-top:10px}.session-device.session-current{margin-top:0;background-color:#fff}.session-device.session-current .sessions-more-info{color:#586069}.session-device.session-current .sessions-more-info::after{border-top-color:#fff}.session-device.session-current .octicon{color:#586069}.session-details{margin-left:70px}.session-details:hover .octicon{color:#0366d6;cursor:pointer}.session-details.open .sessions-more-info{display:block}.collaborators .collab-list{border-bottom-width:0}.collaborators .collab-list-item:first-child .collab-list-cell{border-top-width:0}.collaborators .collab-list-cell{padding-top:15px;padding-bottom:15px;vertical-align:middle}.collaborators .collab-meta{width:140px}.collaborators .collab-remove{padding-right:20px;text-align:right}.collaborators .collab-remove .remove-link{color:#586069}.collaborators .collab-remove .remove-link:hover{color:#cb2431}.collaborators .collab-team-link{width:300px}.collaborators .collab-team-link:hover{text-decoration:none}.collaborators .collab-team-link .avatar{float:left;margin-top:1px;margin-right:10px}.collaborators .collab-team-link.disabled{pointer-events:none}.collaborators .collab-info{height:100%;color:#666}.collaborators .collab-info .description{padding-right:50px;margin-top:3px;margin-bottom:3px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.collaborators .collab-info .collab-name{display:block;font-size:14px}.collaborators .collab-info .collab-message{position:relative;top:25%;display:block}.collaborators .copy-invite-modal{width:352px}.collaborators .cancel-invite-cell{width:113px;padding-left:0}.access-sub-heading{float:right;font-weight:400;line-height:1.4;color:#586069}.access-form-wrapper{padding:10px;background-color:#fcfcfc;border-top:1px solid #ddd;border-radius:0 0 3px 3px}.access-flash{padding:8px;margin-right:10px;margin-bottom:10px;margin-left:10px}.repo-access-group .blankslate{display:none}.repo-access-group.is-empty .blankslate{display:block}.repo-access-group.no-form .add-team-form{display:none}.repo-access-group .select-menu-item.has-access{display:none}.oauth-pending-deletion-list-item{background-color:#fafbfc;box-shadow:inset 0 0 8px #eee}.oauth-pending-deletion-list-item:hover{background-color:#fafbfc}.oauth-pending-deletion-list-item .oauth-pending-deletion{display:inline-block;width:19%;line-height:30px}.oauth-pending-deletion-list-item .active{display:none}.oauth-pending-deletion{display:none;width:100%}.boxed-group-list .access-level{color:#586069}.boxed-group-list .access-level.css-truncate-target{max-width:500px}.settings-next{font-size:14px;line-height:1.5}.settings-next label{font-size:14px}.settings-next .note{font-size:13px}.settings-next .form-checkbox input[type="radio"],.settings-next .form-checkbox input[type="checkbox"]{margin-top:4px}dl.form-group>dd textarea.compact{height:100px;min-height:0}.form-hr{margin-top:15px;margin-bottom:15px;border-bottom-color:#e5e5e5}.listgroup{list-style:none;border:1px solid #e5e5e5;border-radius:3px}.listgroup-item{min-height:inherit;padding:10px;font-size:13px;line-height:26px;color:#586069}.listgroup-item::before{display:table;content:""}.listgroup-item::after{display:table;clear:both;content:""}.listgroup-item+.listgroup-item{border-top:1px solid #e5e5e5}.listgroup-item.listgroup-item-preview{line-height:inherit}.listgroup-item.listgroup-item-preview .BtnGroup{margin-top:5px}.listgroup-item .css-truncate-target{max-width:615px}.listgroup-item-title{display:block;font-weight:600}.listgroup-item-body{display:block}.listgroup-header{border-top:0;border-bottom:1px solid #e5e5e5}.listgroup-overflow{max-height:240px;overflow-y:auto;background-color:#f5f5f5}.listgroup-sm .listgroup-item{padding-top:5px;padding-bottom:5px}.protected-branches{margin-top:15px;margin-bottom:15px}.protected-branch-options,.repo-data-options{margin-left:20px;opacity:0.5}.protected-branch-options.active,.repo-data-options.active{opacity:1}.protected-branch-reviews.on .require-code-owner-review,.protected-branch-reviews.on .reviews-dismiss-on-push,.protected-branch-reviews.on .reviews-include-dismiss,.protected-branch-reviews.on .require-approving-reviews{display:block}.protected-branch-reviews .require-code-owner-review,.protected-branch-reviews .reviews-dismiss-on-push,.protected-branch-reviews .reviews-include-dismiss,.protected-branch-reviews .require-approving-reviews{display:none}.protected-branch-orgs-and-repo-admins{padding:10px;background-color:#fafbfc}.authorized-pushers{width:440px}.authorized-pushers .add-protected-branch-user-or-team{display:block}.authorized-pushers .user-or-team-limit-reached{display:none;padding:10px;font-size:13px}.authorized-pushers.at-limit .add-protected-branch-user-or-team{display:none}.authorized-pushers.at-limit .user-or-team-limit-reached{display:block;width:440px}.protected-branch-authorized-pushers-table{margin-top:10px}.protected-branch-authorized-pushers-table .boxed-group-inner{max-height:350px;overflow-y:auto}.protected-branch-authorized-pushers-table .table-list{border-bottom:0}.protected-branch-authorized-pushers-table .table-list-cell{vertical-align:middle}.protected-branch-authorized-pushers-table .table-list-cell:first-child{width:100%}.protected-branch-authorized-pushers-table .avatar,.protected-branch-authorized-pushers-table .octicon-jersey,.protected-branch-authorized-pushers-table .octicon-organization{width:36px;margin-right:10px;text-align:center}.protected-branch-pusher{color:#333}.user-already-added::after{display:inline-block;padding:1px 5px;margin-left:6px;font-size:11px;line-height:1.4;color:#fff;content:"Already added";background-color:#d15704;border-radius:3px}.protected-branch-admin-permission{float:left;padding:3px;margin:-2px 0 -2px -4px;line-height:normal;border:1px solid transparent;border-radius:3px}.protected-branch-admin-permission.active{animation:toggle-color 1s ease-in-out 0s}@keyframes toggle-color{0%{background-color:transparent}50%{color:#4c4a42;background-color:#fff9ea;border-color:#dfd8c2}100%{background-color:transparent}}.automated-check-options{margin-top:10px}.automated-check-options .listgroup-item label{font-size:inherit}.automated-check-options .listgroup-item input[type="checkbox"]{float:none;margin-top:-2px;margin-right:5px;margin-left:0}.automated-check-options .label{margin-top:4px}.repository-merge-features .form-group.errored label{color:inherit}.repository-merge-features .form-group.errored .error{position:inherit;padding:0;margin-top:0;margin-left:6px;font-size:11px;color:#cb2431;background:transparent;border:0}.repository-merge-features .form-group.errored .error::before,.repository-merge-features .form-group.errored .error::after{display:none}.logged-out.signup .header-actions .primary,.logged-out.signup .footer,.logged-out.signup .header-search{display:none}.setup-wrapper{width:750px;padding-top:30px;margin:0 auto}.setup-wrapper::before{display:table;content:""}.setup-wrapper::after{display:table;clear:both;content:""}.setup-header{padding-bottom:20px;margin:0 auto 30px;overflow:hidden;text-align:left;border-bottom:1px solid #ddd}.setup-header h1{margin-top:0;margin-bottom:0;font-size:45px;font-weight:400;line-height:1.1;letter-spacing:-1px}.setup-header h1 .octicon{color:#bbb}.setup-header .lead{margin-top:2px;margin-bottom:0;font-size:21px}.setup-header .lead a{color:#586069}.setup-header .lead a:hover{color:#0366d6;text-decoration:none}.setup-org{padding-bottom:0;border-bottom:0}.setup-main{float:left;width:450px}.setup-main.without-secondary{margin-left:150px}.setup-secondary{float:right;width:250px}.setup-secondary .info{padding-top:0;padding-bottom:0;margin-top:-10px;font-size:12px;line-height:18px;color:#586069;text-align:center}.setup-info-module{margin-bottom:30px;background-color:#fff;border:1px solid #ccc;border-radius:3px;box-shadow:0 1px 3px rgba(0,0,0,0.075)}.setup-info-module h2{padding:15px;margin-bottom:15px;overflow:hidden;font-size:16px;border-bottom:1px solid #ddd}.setup-info-module h2 .price{float:right;font-weight:600;color:#586069}.setup-info-module h3{padding:0 15px;margin:0 0 -7px;font-size:14px}.setup-info-module p{padding:0 15px;margin:15px 0}.setup-info-module .setup-info-note{padding:1px 0;margin:0;background:#f9f9f9;border-top:1px solid #e0e0e0}.features-list{padding:0 15px 15px;margin:0;font-size:14px;list-style:none}.features-list li{margin-top:10px}.features-list li:first-child{margin-top:0}.features-list .list-divider{margin:15px -15px;border-top:1px solid #eee}.features-list .octicon-check{margin-right:5px;color:#60b044}.features-list .octicon-question{font-size:12px;color:#555}.features-list .tooltipped::after{width:250px;white-space:normal}.features-list.features-list-org{padding-bottom:0}.setup-form-container .setup-form-title{font-size:16px}.setup-form-container .secure{float:right;margin-top:2px;font-size:11px;color:#60b044;text-transform:uppercase}.setup-form-container hr{margin-top:25px;margin-bottom:25px}.setup-form-container .form-actions{padding-top:0;padding-bottom:0;text-align:left}.team-member-container{margin-bottom:20px}.team-member-container .team-member-username{line-height:1.2}.setup-form{padding-bottom:15px}.setup-form .form-group dd .form-control{width:100%}.setup-form .form-group dd .form-control.short{width:250px}.setup-form dd{position:relative}.setup-form dd .octicon{position:absolute;top:8px;right:25px}.setup-form .octicon-alert{color:#cb2431}.setup-form .octicon-check{color:#28a745}.setup-form .tos-info,.setup-form .setup-organization-next{margin:15px 0;border-top:1px solid #eee;border-bottom:1px solid #eee}.setup-form .tos-info{padding:15px 0}.setup-form .setup-organization-next{padding-top:15px;padding-bottom:15px}.setup-form .setup-plans{border-collapse:separate;border:1px solid #d1d5da}.setup-form .setup-plans tr.selected{background-color:#f1f8ff}.setup-form .setup-plans .name{font-weight:600}.setup-form .setup-plans .choose-plan input[type="radio"]{display:none}.setup-form .new-business-initial-admins td{padding:5px 10px;border:1px solid #f5f5f5}.setup-creditcard-form .cc-extras{margin-bottom:15px}.setup-creditcard-form .expiration-form select{width:80px}.setup-creditcard-form .expiration-form,.setup-creditcard-form .cvv-form,.setup-creditcard-form .country-form,.setup-creditcard-form .state-form{float:left;margin:0;word-wrap:normal}.setup-creditcard-form .country-form,.setup-creditcard-form .postal-code-form{margin-top:0;margin-bottom:15px}.setup-creditcard-form .form-group dd .input-cvv{width:80px}.setup-creditcard-form .form-group select.select-country{width:182px;margin-right:5px}.setup-creditcard-form .form-group select:invalid{color:#6a737d}.setup-creditcard-form .form-group select.select-state{width:113px}.setup-creditcard-form .form-group .card-select-number-field{width:100%}.setup-creditcard-form .form-group .input-vat{width:288px}.setup-creditcard-form .form-group .card-select-number-field-icons{top:1px;right:2px}.setup-creditcard-form .form-group .card-select-number-field-icons>.placeholder{top:8px;right:10px}.setup-creditcard-form .form-group .card-select-number-field-icons>.card{height:20px;margin-top:6px;margin-right:5px;margin-bottom:6px}.setup-creditcard-form .form-group .card-select-number-field-icons>.card.enabled{display:block}.setup-creditcard-form .form-group input.input-postal-code{width:180px}.setup-creditcard-form.is-vat-country .vat-field{display:block}.setup-creditcard-form.is-international .form-group select.select-country{width:300px}.setup-creditcard-form.is-international .state-form{display:none}.setup-creditcard-form.no-postcodes .postal-code-form{display:none}.setup-creditcard-form dd .octicon-credit-card{position:inherit}.setup-creditcard-form .enter-new-card{display:none}.setup-creditcard-form.has-credit-card .enter-new-card{display:inline-block}.setup-creditcard-form.has-credit-card .card-select-number-field-icons,.setup-creditcard-form.has-credit-card .card-select-number-field,.setup-creditcard-form.has-credit-card .cancel-enter-new-card{display:none}.setup-creditcard-form .vat-field{display:none}.setup-creditcard-form .vat-field.prefilled{display:block}.setup-creditcard-form .help-text{font-size:80%;font-weight:400;color:#586069}.org-creation-questions,.user-identification-questions{float:none;width:auto}.org-creation-questions .question,.user-identification-questions .question{margin-bottom:30px}.org-creation-questions .question-title,.user-identification-questions .question-title{padding-right:40px;margin-bottom:10px;font-size:14px;line-height:1.5}.org-creation-questions .question-title i,.user-identification-questions .question-title i{font-size:13px;font-style:normal;font-weight:400;color:#767676}.org-creation-questions .response-group label,.user-identification-questions .response-group label{font-weight:400}.org-creation-questions .form-checkbox,.user-identification-questions .form-checkbox{margin:8px 0}.org-creation-questions .other-field .form-control,.user-identification-questions .other-field .form-control{margin-top:10px}.org-creation-questions .other-field input+.form-control,.user-identification-questions .other-field input+.form-control{display:none}.org-creation-questions .other-field input:checked+.form-control,.user-identification-questions .other-field input:checked+.form-control{display:block}.org-creation-questions .alternate-action,.user-identification-questions .alternate-action{margin-left:10px;line-height:34px}.org-creation-questions .disclaimer,.user-identification-questions .disclaimer{margin:40px 0 0;text-align:center}.user-identification-questions{margin-top:40px}.user-identification-questions .form-checkbox{float:left;width:250px}.shelf{padding-top:20px;margin-bottom:20px;background-color:#fefefe;border-bottom:1px solid #eff1f3}.shelf .container{position:relative}.shelf-title{margin:0;font-size:30px;font-weight:400}.shelf-content{width:800px;margin:50px auto;text-align:center}.shelf-lead{margin-top:10px;margin-bottom:30px;font-size:18px;color:#586069}.shelf-dismiss{position:absolute;top:0;right:20px;font-size:12px;color:#959da5}.shelf-dismiss:hover{color:#0366d6;text-decoration:none}.shelf-dismiss .close-button{width:28px;height:28px;padding:3px 5px;color:rgba(27,31,35,0.7);border:1px solid rgba(27,31,35,0.15);border-radius:28px}.shelf-dismiss .close-button:hover{color:#24292e;border-color:rgba(27,31,35,0.3)}.shelf-cta{padding:10px 50px;font-size:16px}.intro-shelf{margin-top:0;color:rgba(27,31,35,0.85);background-image:linear-gradient(180deg, rgba(255,255,255,0) 60%, #fff),linear-gradient(70deg, #dbedff 32%, #ebfff0);border-bottom:#fff}.intro-shelf .shelf-lead{color:rgba(27,31,35,0.7)}.orgs-help-shelf{padding-top:20px;padding-bottom:20px;margin-top:-20px;margin-bottom:20px;border-bottom:1px solid #eff1f3}.orgs-help-shelf .orgs-help-title{font-size:30px;font-weight:400}.orgs-help-shelf-content{width:800px;margin:50px auto;text-align:center}.orgs-help-shelf-content .orgs-help-lead{padding-right:45px;padding-left:45px;font-size:18px}.orgs-help-shelf-content .orgs-help-divider{display:block;width:150px;margin:40px auto;content:"";border-top:1px solid #d1d5da}.orgs-help-lead{margin-top:10px;margin-bottom:30px;color:#586069}.orgs-help-items{margin-bottom:40px}.orgs-help-item-octicon{width:70px;height:70px;margin:0 auto 15px;text-align:center;background-color:#fff;border:solid 1px #e1e4e8;border-radius:50px}.orgs-help-item-octicon .octicon{margin-top:20px;color:#0366d6}.orgs-help-item-title{margin-bottom:10px;font-weight:400}.orgs-help-item-content{margin-top:0;font-size:14px;color:#586069}.orgs-help-dismiss{float:right;margin-top:5px;margin-right:10px;font-size:12px;color:#586069}.orgs-help-dismiss:hover{color:#0366d6;text-decoration:none}.orgs-help-dismiss .octicon{position:relative;top:1px}.orgs-help-title{margin-top:0;margin-bottom:0}.collection-page .column.main{margin-right:260px !important}.collection-page .column.sidebar{width:240px}.collection-search-results em{padding:0.1em;background-color:#faffa6}.draft-tag{padding:5px 10px;font-weight:600;color:#eee;background-color:#404040}.showcase-page-pattern{position:relative;z-index:-1;height:100px;margin-top:-21px;margin-bottom:-70px}.showcase-page-pattern::after{position:absolute;top:0;right:0;bottom:0;left:0;display:block;content:"";background-image:linear-gradient(180deg, rgba(255,255,255,0.85), #fff)}.showcase-page-repo-list{border-top:1px solid #eee}.repo-health .repo-health-loading{display:none;font-style:italic}.repo-health.is-loading .repo-health-loading{display:block}.repo-health.is-loading .repo-health-results{display:none}.sortable-button-item:first-of-type .sortable-button[data-direction="up"],.sortable-button-item:last-of-type .sortable-button[data-direction="down"]{display:none}.org-sso{width:340px;margin:0 auto}.org-sso .sso-title{font-size:24px;font-weight:300;letter-spacing:-0.5px}.org-sso .org-sso-panel{padding:20px;background-color:#fff;border:1px #e1e4e8 solid;border-radius:5px}.org-sso .sso-recovery-callout{padding:15px 10px;text-align:center;border:1px solid #d1d5da;border-radius:5px}.sso-modal{padding:16px}.sso-modal .org-sso{width:auto}.sso-modal .org-sso .org-sso-panel{border:0}.sso-modal .sso-prompt-success,.sso-modal .sso-prompt-error{display:none}.sso-modal.success .sso-prompt-default{display:none}.sso-modal.success .sso-prompt-success{display:block}.sso-modal.error .sso-prompt-default{display:none}.sso-modal.error .sso-prompt-error{display:block}.sso-modal.error .flash-error{margin-right:-35px;margin-left:-35px;border-right:0;border-left:0;border-radius:0}.tab-size[data-tab-size="1"]{-moz-tab-size:1;tab-size:1}.tab-size[data-tab-size="2"]{-moz-tab-size:2;tab-size:2}.tab-size[data-tab-size="3"]{-moz-tab-size:3;tab-size:3}.tab-size[data-tab-size="4"]{-moz-tab-size:4;tab-size:4}.tab-size[data-tab-size="5"]{-moz-tab-size:5;tab-size:5}.tab-size[data-tab-size="6"]{-moz-tab-size:6;tab-size:6}.tab-size[data-tab-size="7"]{-moz-tab-size:7;tab-size:7}.tab-size[data-tab-size="8"]{-moz-tab-size:8;tab-size:8}.tab-size[data-tab-size="9"]{-moz-tab-size:9;tab-size:9}.tab-size[data-tab-size="10"]{-moz-tab-size:10;tab-size:10}.tab-size[data-tab-size="11"]{-moz-tab-size:11;tab-size:11}.tab-size[data-tab-size="12"]{-moz-tab-size:12;tab-size:12}.tag-input-container{position:relative}.tag-input-container .suggester{position:absolute;z-index:100;width:100%;margin-top:-1px}.tag-input-container ul{list-style:none}.tag-input{width:100%;overflow:auto}.tag-input input{float:left;padding-left:2px;margin:0;background:none;border:0;box-shadow:none}.tag-input input:focus{box-shadow:none}.tag-input .tag-input-tag{float:left;margin-right:5px}.tag-input .tag-input-tag:hover{background-color:#eee}.tag-input-tag{position:relative;padding:5px 30px 5px 10px;background:#eee;border-radius:3px}.tag-input-tag:hover{background-color:#ddd}.tag-input-tag .remove{position:absolute;top:6px;right:6px;display:block;width:18px;height:18px;font-size:15px;line-height:16px;color:#fff;text-align:center;text-decoration:none;cursor:pointer;background:#c8c8c8;border-radius:18px}.tag-input-tag .remove:hover{background:#bd2c00}.task-list-item{list-style-type:none}.task-list-item label{font-weight:400}.task-list-item.enabled label{cursor:pointer}.task-list-item+.task-list-item{margin-top:3px}.task-list-item .handle{display:none}.task-list-item-checkbox{margin:0 0.2em 0.25em -1.6em;vertical-align:middle}.reorderable-task-lists .markdown-body .contains-task-list{padding:0}.reorderable-task-lists .markdown-body li:not(.task-list-item){margin-left:26px}.reorderable-task-lists .markdown-body ol:not(.contains-task-list) li,.reorderable-task-lists .markdown-body ul:not(.contains-task-list) li{margin-left:0}.reorderable-task-lists .markdown-body li p{margin-top:0}.reorderable-task-lists .markdown-body .task-list-item{padding-right:15px;padding-left:42px;margin-right:-15px;margin-left:-15px;border:1px solid transparent}.reorderable-task-lists .markdown-body .task-list-item+.task-list-item{margin-top:0}.reorderable-task-lists .markdown-body .task-list-item .contains-task-list{padding-top:4px}.reorderable-task-lists .markdown-body .task-list-item .handle{display:block;float:left;width:20px;padding:2px 0 0 2px;margin-left:-43px;opacity:0}.reorderable-task-lists .markdown-body .task-list-item .drag-handle{fill:#333}.reorderable-task-lists .markdown-body .task-list-item.hovered{background:#fafafa;border-top-color:#ededed;border-bottom-color:#ededed}.reorderable-task-lists .markdown-body .task-list-item.hovered>.handle{opacity:1}.reorderable-task-lists .markdown-body .task-list-item.is-dragging{opacity:0}.reorderable-task-lists .markdown-body .task-list-item.is-ghost{border-right-color:#ededed;border-left-color:#ededed}.review-comment-contents .markdown-body .task-list-item{padding-left:42px;margin-right:-12px;margin-left:-12px;border-top-left-radius:3px;border-bottom-left-radius:3px}.review-comment-contents .markdown-body .task-list-item.hovered{border-left-color:#ededed}.task-run .icon-for-success,.task-run .icon-for-failure,.task-run .icon-for-pending,.task-run .icon-for-inactive{display:none}.task-run.success .icon-for-success{display:inline-block;color:#28a745}.task-run.failure .icon-for-failure{display:inline-block;color:#cb2431}.task-run.pending .icon-for-pending{display:inline-block;color:#6a737d}.task-run.inactive .icon-for-inactive{display:inline-block;color:#6a737d}.task-run .task-run-name{display:inline-block;max-width:40%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:bottom}.team-label-ldap{display:inline-block;padding:0 9px;line-height:25px;color:#586069;text-transform:uppercase;cursor:default;border:1px solid #eaeaea;border-radius:3px;box-shadow:none}.team-label-ldap.header-label-ldap{padding:3px 5px}.team-member-ellipsis{width:25px;height:25px;line-height:24px;color:#586069}.team-member-ellipsis:hover{color:#0366d6;background:#f6f8fa}.team-listing .table-list-cell{padding-top:10px;padding-bottom:10px;vertical-align:middle}.team-listing .table-list-cell-checkbox{width:30px;padding-right:0;padding-left:10px}.team-listing .nested-teams-checkbox{padding-left:3px}.team-listing .nested-teams-checkbox.show{padding-right:11px}.team-listing .nested-teams-checkbox.indent-1{padding-left:30px}.team-listing .nested-teams-checkbox.indent-2{padding-left:54px}.team-listing .nested-teams-checkbox.indent-3{padding-left:78px}.team-listing .nested-teams-checkbox.indent-4{padding-left:102px}.team-listing .nested-teams-checkbox.indent-5{padding-left:126px}.team-listing .nested-teams-checkbox.indent-6{padding-left:150px}.team-listing .nested-teams-checkbox.indent-7{padding-left:174px}.team-listing .nested-teams-checkbox.indent-8{padding-left:198px}.team-listing .nested-teams-checkbox.indent-9{padding-left:222px}.team-listing .nested-teams-checkbox.indent-10{padding-left:246px}.team-listing .nested-teams-checkbox.indent-11{padding-left:270px}.team-listing .nested-teams-checkbox.indent-12{padding-left:294px}.team-listing .nested-teams-checkbox.indent-13{padding-left:318px}.team-listing .nested-teams-checkbox.indent-14{padding-left:342px}.team-listing .nested-teams-checkbox.indent-15{padding-left:366px}.team-listing .team-info{width:280px}.team-listing .nested-team-info{width:650px}.team-listing .nested-team-name{max-width:268px}.team-listing .team-name{line-height:1.3;color:#0366d6}.team-listing .description{display:block}.team-listing .shortened-teams-avatars{margin-left:auto}.team-listing .shortened-teams-avatars.width-0{width:300px}.team-listing .shortened-teams-avatars.width-1{width:233px}.team-listing .shortened-teams-avatars.width-2{width:167px}.team-listing .shortened-teams-avatars.width-3{width:99px}.team-listing .team-meta{font-size:14px}.team-listing .team-members-count{width:124px;text-align:right}.team-listing .team-show-more-cell{display:block;width:980px}.team-listing .team-show-more{display:block;width:110px;height:30px;padding-top:6px;margin:auto;color:#0366d6;text-align:center;text-decoration:none;cursor:pointer}.team-listing .team-buttons{width:130px;text-align:right}.team-listing .octicon-chevron-up{display:none}.team-listing .octicon-wrapper{display:inline-block;width:10px}.team-listing .is-open.root-team{background-color:#fafbfc}.team-listing .is-open .expand-nested-team{font-weight:bold;color:#24292e}.team-listing .is-open .octicon-chevron-down{transform:rotate(180deg)}.team-listing .expand-nested-team{color:#6a737d;cursor:pointer}.team-listing .expand-nested-team:hover{color:#0366d6}.team-listing .team-menu{padding-right:15px}.traffic-graph{min-height:150px}.traffic-graph .activity{margin-top:0}.traffic-graph .activity .dots{margin-top:40px}.traffic-graph .path{fill:none;stroke-width:2}.traffic-graph path.total{stroke:#28a745}.traffic-graph path.unique{stroke:#005cc5}.traffic-graph .axis .tick:first-of-type line{stroke:#28a745;stroke-width:2px}.traffic-graph .y line{stroke:#28a745}.traffic-graph .y.unique line{stroke:#005cc5}.traffic-graph .overlay{fill-opacity:0}.uniques-graph .axis .tick:last-child line{stroke:#005cc5;stroke-width:2px}.svg-tip .date{color:#fff}.top-domains .dots{display:block;margin:167px auto 0}.top-domains-icon{display:inline-block;margin-right:5px;vertical-align:middle}table.capped-list{width:100%;line-height:100%}table.capped-list th{padding:8px;text-align:left;background:#f6f8fa;border-bottom:1px solid #dfe2e5}table.capped-list td{padding:8px;font-size:12px;border-bottom:1px solid #eaecef}table.capped-list th.middle,table.capped-list td.middle{text-align:center}table.capped-list .favicon{width:16px;height:16px;margin:0 5px;vertical-align:middle}table.capped-list .octicon{margin-right:10px;color:#444d56;vertical-align:-1px}table.capped-list tr:nth-child(even){background-color:#fafbfc}.capped-list-label{max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.traffic-graph-stats{border-top:1px solid #dfe2e5}.traffic-graph-stats .summary-stats{width:100%}.traffic-graph-stats .summary-stats::before{display:table;content:""}.traffic-graph-stats .summary-stats::after{display:table;clear:both;content:""}.traffic-graph-stats .summary-stats li{display:block;float:left;width:50%;padding-bottom:10px}.totals circle{fill:#28a745;stroke:#fff;stroke-width:2}.uniques circle{fill:#005cc5;stroke:#fff;stroke-width:2}.top-lists .is-loading{margin:40px;text-align:center}ul.web-views li{width:140px}ul.clones li{width:170px}.tree-browser{width:100%;margin:0;border-right:0;border-bottom:1px solid #cacaca;border-left:0}.tree-browser td{padding:7px 3px;color:#484848;white-space:nowrap;vertical-align:middle;background:#f8f8f8;border-bottom:1px solid #eee}.tree-browser td.icon{width:17px;padding-right:2px;padding-left:10px}.tree-browser td:first-child{border-left:1px solid #cacaca}.tree-browser td:last-child{border-right:1px solid #cacaca}.tree-browser td a.message{color:#484848}.tree-browser td span.ref{color:#aaa}.tree-browser img{vertical-align:text-bottom}.tree-browser tbody tr:last-child td{border-bottom:0}.tree-browser .history{float:right;padding-right:5px}.tree-browser .octicon-chevron-right{color:transparent}.tree-browser tr[aria-selected="true"] td,.tree-browser tr.navigation-focus td{background-color:#fff}.tree-browser tr[aria-selected="true"] td .octicon-chevron-right,.tree-browser tr.navigation-focus td .octicon-chevron-right{color:#0366d6}.tree-browser .octicon-file-directory{color:rgba(3,102,214,0.75)}.tree-browser .octicon-file-submodule{color:#3cbf5e}.tree-browser .octicon-file{color:#586069}.tree-browser .content{max-width:220px}.tree-browser .message{max-width:420px}.tree-browser .css-truncate-target{max-width:100%}.tree-browser-result-template{display:none}.tree-browser-result .css-truncate-target{max-width:870px}.tree-browser-result mark{font-weight:600;color:#0366d6;background-color:transparent}.tree-finder-input,.tree-finder-input:focus{padding-left:0;margin-left:5px;font-size:inherit;line-height:inherit;border:0;outline:none;box-shadow:none;-webkit-appearance:none;-moz-appearance:none;appearance:none}.tree-finder .no-results{display:none}.tree-finder .no-results th{text-align:center}.tree-finder tr td.icon{cursor:pointer}.tree-finder .tree-browser{border-top:1px solid #cacaca}.filterable-empty+.no-results{display:block}.toolbar-commenting{float:right}.toolbar-commenting .dropdown.active .dropdown-menu-content{display:block}.toolbar-commenting .dropdown-menu-s{width:100px}.toolbar-commenting .dropdown-item{font-weight:600;line-height:1em;background:none;border:0}.toolbar-commenting .dropdown-item:hover{color:#0366d6}.toolbar-commenting .dropdown-item:focus{color:#0366d6;outline:none}.toolbar-item{display:block;float:left;padding:4px 5px;color:#586069;background:none;border:0}.toolbar-item.dropdown,.toolbar-item.select-menu{padding:0}.toolbar-item .select-menu-modal{margin-top:2px}.toolbar-item .select-menu-item{padding-left:8px}.toolbar-item .menu-target{display:block;padding:4px 5px;color:#586069;background:none;border:0}.toolbar-item .menu-target:hover,.toolbar-item:hover{color:#0366d6}.toolbar-item .menu-target:focus,.toolbar-item:focus{color:#0366d6;outline:none}.toolbar-item .dropdown-caret{margin-left:-3px}.toolbar-item:disabled{color:#ddd}.toolbar-item .octicon-link,.toolbar-item .octicon-tasklist{margin-left:-3px}.toolbar-item .octicon-mention{margin-left:-4px}.toolbar-item .octicon-bold{margin-left:-2px}.toolbar-group{display:inline-block;margin-left:20px}.toolbar-group:first-child{margin-left:0}.typeahead-result{position:relative;display:block;min-width:100%;padding:10px;margin-top:0;color:#333;cursor:pointer}.typeahead-result::before{display:table;content:""}.typeahead-result::after{display:table;clear:both;content:""}.typeahead-result:first-child{border-top:0}.typeahead-result:focus,.typeahead-result:hover,.typeahead-result[aria-selected="true"],.typeahead-result.navigation-focus{text-decoration:none}.typeahead-result[aria-selected="true"],.typeahead-result:hover,.typeahead-result.navigation-focus{color:#fff;background-color:#0366d6}.typeahead-result[aria-selected="true"] .octicon-plus,.typeahead-result:hover .octicon-plus,.typeahead-result.navigation-focus .octicon-plus{color:#fff}.typeahead-result.disabled{pointer-events:none;opacity:0.5}.member-suggestion{padding-left:44px}.member-suggestion .avatar{float:left;margin-right:10px;margin-left:-34px}.member-suggestion .member-suggestion-info{width:90%;margin-top:2px;margin-bottom:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.member-suggestion .member-name{font-size:12px;color:#586069}.member-suggestion .member-email{margin-top:0;margin-bottom:0}.member-suggestion .octicon-plus,.member-suggestion .octicon-check{position:absolute;top:50%;right:15px;margin-top:-8px;color:#ddd}.member-suggestion .already-member-note,.member-suggestion .non-member-note,.member-suggestion .non-member-action{margin-top:0;margin-bottom:0;color:#586069}.member-suggestion .non-member-action{display:none}.member-suggestion[aria-selected="true"] .member-name,.member-suggestion[aria-selected="true"] .non-member-note,.member-suggestion[aria-selected="true"] .already-member-note,.member-suggestion[aria-selected="true"] .non-member-action,.member-suggestion[aria-selected="true"] .member-email,.member-suggestion:hover .member-name,.member-suggestion:hover .non-member-note,.member-suggestion:hover .already-member-note,.member-suggestion:hover .non-member-action,.member-suggestion:hover .member-email,.member-suggestion.navigation-focus .member-name,.member-suggestion.navigation-focus .non-member-note,.member-suggestion.navigation-focus .already-member-note,.member-suggestion.navigation-focus .non-member-action,.member-suggestion.navigation-focus .member-email{color:#fff}.member-suggestion[aria-selected="true"] .non-member-note,.member-suggestion:hover .non-member-note,.member-suggestion.navigation-focus .non-member-note{display:none}.member-suggestion[aria-selected="true"] .non-member-action,.member-suggestion:hover .non-member-action,.member-suggestion.navigation-focus .non-member-action{display:block}.member-suggestion[aria-selected="true"] .octicon,.member-suggestion:hover .octicon,.member-suggestion.navigation-focus .octicon{color:#fff}.member-suggestion.not-a-member .member-info,.member-suggestion.disabled .member-info{margin-top:-2px}.non-member-result{padding-left:31px}.team-suggestion{padding-left:32px}.team-suggestion .octicon{float:left;margin-top:2px;margin-left:-22px}.team-suggestion .team-suggestion-info{margin:2px 0 0}.team-suggestion .team-suggestion-info .css-truncate-target{max-width:none}.team-suggestion .team-size,.team-suggestion .team-description{font-size:12px;color:#586069}.team-suggestion[aria-selected="true"] .team-size,.team-suggestion[aria-selected="true"] .team-description,.team-suggestion.navigation-focus .team-size,.team-suggestion.navigation-focus .team-description{color:#fff}.email-suggestion{padding-left:32px}.email-suggestion .octicon-mail{margin-left:-20px;color:#959da5}.email-suggestion .member-suggestion-info{margin-top:1px}.repo-access-add-team .team-name{font-size:13px}.repo-access-add-team .team-description{display:block}.repo-access-add-team .team-size,.repo-access-add-team .team-description{font-size:12px;color:#586069}.repo-access-add-team[aria-selected="true"] .team-size,.repo-access-add-team[aria-selected="true"] .team-description,.repo-access-add-team.navigation-focus .team-size,.repo-access-add-team.navigation-focus .team-description{color:#fff}#user-content-toc{overflow:visible}#user-content-toc tr{border-top:0}#user-content-toc td{padding:0 20px;background-color:#f7f7f7;border:0;border-radius:3px}#user-content-toc ul{padding-left:0;font-weight:600;list-style:none}#user-content-toc ul li{padding-left:0.2em}#user-content-toc ul ul{font-weight:400}#user-content-toc ul ul li::before{float:left;margin-top:-0.2em;margin-right:0.2em;font-size:1.2em;line-height:1;color:#aaa;content:"\231e"}#user-content-toc ul ul ul{padding-left:0.9em}#user-content-toctitle h2{margin-top:1em;margin-bottom:0.5em;font-size:1.25em;border-bottom:0}.user-list em{padding:3px;font-style:normal;font-weight:600;background-color:rgba(255,255,140,0.5);border-radius:3px}.user-list .avatar{position:absolute;top:0;left:0}.user-list-info{min-height:48px;padding:0;font-size:18px;font-weight:400;line-height:20px}.user-list-meta{overflow:hidden}.user-list-item+.user-list-item{border-top:1px solid #e1e4e8}.follow-list{list-style-type:none}.follow-list .follow-list-item{width:305px;height:100px;padding-bottom:20px;margin-right:20px;margin-bottom:20px}.follow-list .follower-list-align-top{vertical-align:top}.follow-list .flagged-banner{width:75px;padding:3px 0;font-size:10px;font-weight:600;color:#fff;text-transform:uppercase;background-color:#cb2431;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.follow-list .follow-list-name{margin-bottom:1px;font-weight:400}.follow-list .follow-list-name a{color:inherit}.follow-list .follow-list-info{margin-bottom:0.6em;font-size:12px;color:#586069}.follow-list .css-truncate.css-truncate-target{max-width:190px}.wiki-list em{padding:3px;font-style:normal;font-weight:600;background-color:rgba(255,255,140,0.5);border-radius:3px}.wiki-list .avatar{float:left}.wiki-list .title{min-height:24px;margin:-3px 0 10px 38px;font-weight:600;line-height:1.2}.wiki-list .title .updated-at{font-weight:400}.wiki-list .repo-specific .title,.wiki-list .repo-specific .full-path{margin-left:0}.wiki-list .description{margin:0 0 10px;overflow:hidden;line-height:20px}.wiki-list .wiki-list-item+.wiki-list-item{border-top:1px #e1e4e8 solid}@media (min-width: 768px){.wiki-rightbar{width:230px !important}}.wiki-rightbar .markdown-body .anchor{display:none}.wiki-rightbar .markdown-body h1{font-size:1.6em}.wiki-rightbar .markdown-body h2{font-size:1.4em}.wiki-rightbar p:last-child,.wiki-rightbar ul:last-child,.wiki-rightbar ol:last-child{margin-bottom:0}.wiki-footer .markdown-body,.wiki-rightbar .markdown-body{font-size:13px}.wiki-footer .markdown-body.wiki-writable>:nth-child(2),.wiki-rightbar .markdown-body.wiki-writable>:nth-child(2){margin-top:0 !important}.wiki-footer .markdown-body img{background:none}.wiki-pages-box .wiki-more-pages{display:none}.wiki-pages-box.wiki-show-more .wiki-more-pages,.wiki-pages-box .filterable-active .wiki-more-pages{display:block}.wiki-pages-box.wiki-show-more .wiki-more-pages-link,.wiki-pages-box .filterable-active .wiki-more-pages-link{display:none}
|
|
/*# sourceMappingURL=github-a12fe4c88979a8931d7e7adfee5656fc.css.map */
|
|
|
|
</style>
|
|
<style>
|
|
/* Page tweaks */
|
|
.preview-page {
|
|
margin-top: 64px;
|
|
}
|
|
/* User-content tweaks */
|
|
.timeline-comment-wrapper > .timeline-comment:after,
|
|
.timeline-comment-wrapper > .timeline-comment:before {
|
|
content: none;
|
|
}
|
|
/* User-content overrides */
|
|
.discussion-timeline.wide {
|
|
width: 920px;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="page">
|
|
<div id="preview-page" class="preview-page" data-autorefresh-url="">
|
|
|
|
|
|
|
|
<div role="main" class="main-content">
|
|
<div class="container new-discussion-timeline experiment-repo-nav">
|
|
<div class="repository-content">
|
|
<div id="readme" class="readme boxed-group clearfix announce instapaper_body md">
|
|
|
|
<h3>
|
|
<span class="octicon octicon-book"></span>
|
|
SheetJS Community Edition
|
|
</h3>
|
|
|
|
<article class="markdown-body entry-content" itemprop="text" id="grip-content">
|
|
<h1>
|
|
<a id="user-content-sheetjs" class="anchor" href="#sheetjs" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a><a href="https://sheetjs.com" rel="nofollow">SheetJS</a>
|
|
</h1>
|
|
<p>The SheetJS Community Edition offers battle-tested open-source solutions for
|
|
extracting useful data from almost any complex spreadsheet and generating new
|
|
spreadsheets that will work with legacy and modern software alike.</p>
|
|
<p><a href="https://sheetjs.com/pro" rel="nofollow">SheetJS Pro</a> offers solutions beyond data processing:
|
|
Edit complex templates with ease; let out your inner Picasso with styling; make
|
|
custom sheets with images/graphs/PivotTables; evaluate formula expressions and
|
|
port calculations to web apps; automate common spreadsheet tasks, and much more!</p>
|
|
<p><a href="https://camo.githubusercontent.com/756bdb2076e17b3344ba27668018c9f0011b82a2a02f029790b3e3aa805154d7/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f53686565744a532f73686565746a73" target="_blank" rel="nofollow"><img src="https://camo.githubusercontent.com/756bdb2076e17b3344ba27668018c9f0011b82a2a02f029790b3e3aa805154d7/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f53686565744a532f73686565746a73" alt="License" data-canonical-src="https://img.shields.io/github/license/SheetJS/sheetjs" style="max-width:100%;"></a>
|
|
<a href="https://github.com/SheetJS/sheetjs/actions"><img src="https://camo.githubusercontent.com/dba2780ce8f220a047aa004f096aa7b440ceee8afdb7a8b8f539e240e33673d5/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f776f726b666c6f772f7374617475732f73686565746a732f73686565746a732f54657374733a2532306e6f64652e6a73" alt="Build Status" data-canonical-src="https://img.shields.io/github/workflow/status/sheetjs/sheetjs/Tests:%20node.js" style="max-width:100%;"></a>
|
|
<a href="https://snyk.io/test/github/SheetJS/sheetjs" rel="nofollow"><img src="https://camo.githubusercontent.com/7ce09de464c75d8a533b9b2a156b487ab8db9f025f6ca9119395d894e82f69a7/68747470733a2f2f696d672e736869656c64732e696f2f736e796b2f76756c6e65726162696c69746965732f6769746875622f53686565744a532f73686565746a73" alt="Snyk Vulnerabilities" data-canonical-src="https://img.shields.io/snyk/vulnerabilities/github/SheetJS/sheetjs" style="max-width:100%;"></a>
|
|
<a href="https://npmjs.org/package/xlsx" rel="nofollow"><img src="https://camo.githubusercontent.com/d271e8f58341837d08c59de862121e6faa608414d48b74fd12b88c507ee1bcdf/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f646d2f786c73782e737667" alt="npm Downloads" data-canonical-src="https://img.shields.io/npm/dm/xlsx.svg" style="max-width:100%;"></a>
|
|
<a href="https://github.com/SheetJS/sheetjs"><img src="https://camo.githubusercontent.com/5835ef9524626d64db0c7a60890d3723b178fb5ca8783250f405dd15dfc3b000/68747470733a2f2f67612d626561636f6e2e61707073706f742e636f6d2f55412d33363831303333332d312f53686565744a532f73686565746a733f706978656c" alt="Analytics" data-canonical-src="https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/sheetjs?pixel" style="max-width:100%;"></a></p>
|
|
<p><a href="https://oss.sheetjs.com/sheetjs/tests/" rel="nofollow"><strong>Browser Test and Support Matrix</strong></a></p>
|
|
<p><a href="https://saucelabs.com/u/sheetjs" rel="nofollow"><img src="https://camo.githubusercontent.com/fd3943851066063e253cd05bc1a8b9436b80f841af7d193c3eacb560012acea6/68747470733a2f2f73617563656c6162732e636f6d2f62726f777365722d6d61747269782f73686565746a732e737667" alt="Build Status" data-canonical-src="https://saucelabs.com/browser-matrix/sheetjs.svg" style="max-width:100%;"></a></p>
|
|
<p><strong>Supported File Formats</strong></p>
|
|
<p><a href="formats.png" target="_blank" rel="noopener noreferrer"><img src="formats.png" alt="circo graph of format support" style="max-width:100%;"></a></p>
|
|
<p><a href="legend.png" target="_blank" rel="noopener noreferrer"><img src="legend.png" alt="graph legend" style="max-width:100%;"></a></p>
|
|
<h2>
|
|
<a id="user-content-table-of-contents" class="anchor" href="#table-of-contents" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Table of Contents</h2>
|
|
<details>
|
|
<summary><b>Expand to show Table of Contents</b></summary>
|
|
|
|
<ul>
|
|
<li>
|
|
<a href="#getting-started">Getting Started</a>
|
|
<ul>
|
|
<li>
|
|
<a href="#installation">Installation</a>
|
|
<ul>
|
|
<li><a href="#standalone-browser-scripts">Standalone Browser Scripts</a></li>
|
|
<li><a href="#ecmascript-modules">ECMAScript Modules</a></li>
|
|
<li><a href="#deno">Deno</a></li>
|
|
<li><a href="#nodejs">NodeJS</a></li>
|
|
<li><a href="#photoshop-and-indesign">Photoshop and InDesign</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#usage">Usage</a></li>
|
|
<li><a href="#the-zen-of-sheetjs">The Zen of SheetJS</a></li>
|
|
<li><a href="#js-ecosystem-demos">JS Ecosystem Demos</a></li>
|
|
</ul>
|
|
</li>
|
|
<li>
|
|
<a href="#acquiring-and-extracting-data">Acquiring and Extracting Data</a>
|
|
<ul>
|
|
<li><a href="#parsing-workbooks">Parsing Workbooks</a></li>
|
|
<li><a href="#processing-json-and-js-data">Processing JSON and JS Data</a></li>
|
|
<li><a href="#processing-html-tables">Processing HTML Tables</a></li>
|
|
</ul>
|
|
</li>
|
|
<li>
|
|
<a href="#processing-data">Processing Data</a>
|
|
<ul>
|
|
<li><a href="#modifying-workbook-structure">Modifying Workbook Structure</a></li>
|
|
<li><a href="#modifying-cell-values">Modifying Cell Values</a></li>
|
|
<li><a href="#modifying-other-worksheet--workbook--cell-properties">Modifying Other Worksheet / Workbook / Cell Properties</a></li>
|
|
</ul>
|
|
</li>
|
|
<li>
|
|
<a href="#packaging-and-releasing-data">Packaging and Releasing Data</a>
|
|
<ul>
|
|
<li><a href="#writing-workbooks">Writing Workbooks</a></li>
|
|
<li><a href="#writing-examples">Writing Examples</a></li>
|
|
<li><a href="#streaming-write">Streaming Write</a></li>
|
|
<li><a href="#generating-json-and-js-data">Generating JSON and JS Data</a></li>
|
|
<li><a href="#generating-html-tables">Generating HTML Tables</a></li>
|
|
<li><a href="#generating-single-worksheet-snapshots">Generating Single-Worksheet Snapshots</a></li>
|
|
</ul>
|
|
</li>
|
|
<li>
|
|
<a href="#interface">Interface</a>
|
|
<ul>
|
|
<li><a href="#parsing-functions">Parsing functions</a></li>
|
|
<li><a href="#writing-functions">Writing functions</a></li>
|
|
<li><a href="#utilities">Utilities</a></li>
|
|
</ul>
|
|
</li>
|
|
<li>
|
|
<a href="#common-spreadsheet-format">Common Spreadsheet Format</a>
|
|
<ul>
|
|
<li><a href="#general-structures">General Structures</a></li>
|
|
<li>
|
|
<a href="#cell-object">Cell Object</a>
|
|
<ul>
|
|
<li><a href="#data-types">Data Types</a></li>
|
|
<li><a href="#dates">Dates</a></li>
|
|
</ul>
|
|
</li>
|
|
<li>
|
|
<a href="#sheet-objects">Sheet Objects</a>
|
|
<ul>
|
|
<li><a href="#worksheet-object">Worksheet Object</a></li>
|
|
<li><a href="#chartsheet-object">Chartsheet Object</a></li>
|
|
<li><a href="#macrosheet-object">Macrosheet Object</a></li>
|
|
<li><a href="#dialogsheet-object">Dialogsheet Object</a></li>
|
|
</ul>
|
|
</li>
|
|
<li>
|
|
<a href="#workbook-object">Workbook Object</a>
|
|
<ul>
|
|
<li><a href="#workbook-file-properties">Workbook File Properties</a></li>
|
|
</ul>
|
|
</li>
|
|
<li>
|
|
<a href="#workbook-level-attributes">Workbook-Level Attributes</a>
|
|
<ul>
|
|
<li><a href="#defined-names">Defined Names</a></li>
|
|
<li><a href="#workbook-views">Workbook Views</a></li>
|
|
<li><a href="#miscellaneous-workbook-properties">Miscellaneous Workbook Properties</a></li>
|
|
</ul>
|
|
</li>
|
|
<li>
|
|
<a href="#document-features">Document Features</a>
|
|
<ul>
|
|
<li><a href="#formulae">Formulae</a></li>
|
|
<li><a href="#row-and-column-properties">Row and Column Properties</a></li>
|
|
<li><a href="#number-formats">Number Formats</a></li>
|
|
<li><a href="#hyperlinks">Hyperlinks</a></li>
|
|
<li><a href="#cell-comments">Cell Comments</a></li>
|
|
<li><a href="#sheet-visibility">Sheet Visibility</a></li>
|
|
<li><a href="#vba-and-macros">VBA and Macros</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li>
|
|
<a href="#parsing-options">Parsing Options</a>
|
|
<ul>
|
|
<li><a href="#input-type">Input Type</a></li>
|
|
<li><a href="#guessing-file-type">Guessing File Type</a></li>
|
|
</ul>
|
|
</li>
|
|
<li>
|
|
<a href="#writing-options">Writing Options</a>
|
|
<ul>
|
|
<li><a href="#supported-output-formats">Supported Output Formats</a></li>
|
|
<li><a href="#output-type">Output Type</a></li>
|
|
</ul>
|
|
</li>
|
|
<li>
|
|
<a href="#utility-functions">Utility Functions</a>
|
|
<ul>
|
|
<li><a href="#array-of-arrays-input">Array of Arrays Input</a></li>
|
|
<li><a href="#array-of-objects-input">Array of Objects Input</a></li>
|
|
<li><a href="#html-table-input">HTML Table Input</a></li>
|
|
<li><a href="#formulae-output">Formulae Output</a></li>
|
|
<li>
|
|
<a href="#delimiter-separated-output">Delimiter-Separated Output</a>
|
|
<ul>
|
|
<li><a href="#utf-16-unicode-text">UTF-16 Unicode Text</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#html-output">HTML Output</a></li>
|
|
<li><a href="#json">JSON</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#file-formats">File Formats</a></li>
|
|
<li>
|
|
<a href="#testing">Testing</a>
|
|
<ul>
|
|
<li><a href="#node">Node</a></li>
|
|
<li><a href="#browser">Browser</a></li>
|
|
<li><a href="#tested-environments">Tested Environments</a></li>
|
|
<li><a href="#test-files">Test Files</a></li>
|
|
</ul>
|
|
</li>
|
|
<li>
|
|
<a href="#contributing">Contributing</a>
|
|
<ul>
|
|
<li><a href="#osxlinux">OSX/Linux</a></li>
|
|
<li><a href="#windows">Windows</a></li>
|
|
<li><a href="#tests">Tests</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#license">License</a></li>
|
|
<li><a href="#references">References</a></li>
|
|
</ul>
|
|
|
|
</details>
|
|
<h2>
|
|
<a id="user-content-getting-started" class="anchor" href="#getting-started" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Getting Started</h2>
|
|
<h3>
|
|
<a id="user-content-installation" class="anchor" href="#installation" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Installation</h3>
|
|
<h4>
|
|
<a id="user-content-standalone-browser-scripts" class="anchor" href="#standalone-browser-scripts" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Standalone Browser Scripts</h4>
|
|
<p>Each standalone release script is available at <a href="https://cdn.sheetjs.com/" rel="nofollow">https://cdn.sheetjs.com/</a>.</p>
|
|
<p>The current version is <code>0.18.7</code> and can be referenced as follows:</p>
|
|
<div class="highlight highlight-text-html-basic"><pre><span class="pl-c"><!-- use version 0.18.7 --></span>
|
|
<span class="pl-kos"><</span><span class="pl-ent">script</span> <span class="pl-c1">lang</span>="<span class="pl-s">javascript</span>" <span class="pl-c1">src</span>="<span class="pl-s">https://cdn.sheetjs.com/xlsx-0.18.7/package/dist/xlsx.full.min.js</span>"<span class="pl-kos">></span><span class="pl-kos"></</span><span class="pl-ent">script</span><span class="pl-kos">></span></pre></div>
|
|
<p>The <code>latest</code> tag references the latest version and updates with each release:</p>
|
|
<div class="highlight highlight-text-html-basic"><pre><span class="pl-c"><!-- use the latest version --></span>
|
|
<span class="pl-kos"><</span><span class="pl-ent">script</span> <span class="pl-c1">lang</span>="<span class="pl-s">javascript</span>" <span class="pl-c1">src</span>="<span class="pl-s">https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js</span>"<span class="pl-kos">></span><span class="pl-kos"></</span><span class="pl-ent">script</span><span class="pl-kos">></span></pre></div>
|
|
<p><strong>For production use, scripts should be downloaded and added to a public folder
|
|
alongside other scripts.</strong></p>
|
|
<details>
|
|
<summary><b>Browser builds</b> (click to show)</summary>
|
|
<p>The complete single-file version is generated at <code>dist/xlsx.full.min.js</code></p>
|
|
<p><code>dist/xlsx.core.min.js</code> omits codepage library (no support for XLS encodings)</p>
|
|
<p>A slimmer build is generated at <code>dist/xlsx.mini.min.js</code>. Compared to full build:</p>
|
|
<ul>
|
|
<li>codepage library skipped (no support for XLS encodings)</li>
|
|
<li>no support for XLSB / XLS / Lotus 1-2-3 / SpreadsheetML 2003 / Numbers</li>
|
|
<li>node stream utils removed</li>
|
|
</ul>
|
|
<p>These scripts are also available on the CDN:</p>
|
|
<div class="highlight highlight-text-html-basic"><pre><span class="pl-c"><!-- use xlsx.mini.min.js from version 0.18.7 --></span>
|
|
<span class="pl-kos"><</span><span class="pl-ent">script</span> <span class="pl-c1">lang</span>="<span class="pl-s">javascript</span>" <span class="pl-c1">src</span>="<span class="pl-s">https://cdn.sheetjs.com/xlsx-0.18.7/package/dist/xlsx.mini.min.js</span>"<span class="pl-kos">></span><span class="pl-kos"></</span><span class="pl-ent">script</span><span class="pl-kos">></span></pre></div>
|
|
</details>
|
|
<p><a href="https://bower.io/" rel="nofollow">Bower</a> plays nice with the CDN tarballs:</p>
|
|
<div class="highlight highlight-source-shell"><pre>$ npx bower install https://cdn.sheetjs.com/xlsx-0.18.7/xlsx-0.18.7.tgz</pre></div>
|
|
<p>Bower will place the standalone scripts in <code>bower_components/js-xlsx/dist/</code></p>
|
|
<details>
|
|
<summary><b>Internet Explorer and ECMAScript 3 Compatibility</b> (click to show)</summary>
|
|
<p>For broad compatibility with JavaScript engines, the library is written using
|
|
ECMAScript 3 language dialect as well as some ES5 features like <code>Array#forEach</code>.
|
|
Older browsers require shims to provide missing functions.</p>
|
|
<p>To use the shim, add the shim before the script tag that loads <code>xlsx.js</code>:</p>
|
|
<div class="highlight highlight-text-html-basic"><pre><span class="pl-c"><!-- add the shim first --></span>
|
|
<span class="pl-kos"><</span><span class="pl-ent">script</span> <span class="pl-c1">type</span>="<span class="pl-s">text/javascript</span>" <span class="pl-c1">src</span>="<span class="pl-s">shim.min.js</span>"<span class="pl-kos">></span><span class="pl-kos"></</span><span class="pl-ent">script</span><span class="pl-kos">></span>
|
|
<span class="pl-c"><!-- after the shim is referenced, add the library --></span>
|
|
<span class="pl-kos"><</span><span class="pl-ent">script</span> <span class="pl-c1">type</span>="<span class="pl-s">text/javascript</span>" <span class="pl-c1">src</span>="<span class="pl-s">xlsx.full.min.js</span>"<span class="pl-kos">></span><span class="pl-kos"></</span><span class="pl-ent">script</span><span class="pl-kos">></span></pre></div>
|
|
<p>Due to SSL certificate compatibility issues, it is highly recommended to save
|
|
the Standalone and Shim scripts from <a href="https://cdn.sheetjs.com/" rel="nofollow">https://cdn.sheetjs.com/</a> and add to a
|
|
public directory in the site.</p>
|
|
<p>The script also includes <code>IE_LoadFile</code> and <code>IE_SaveFile</code> for loading and saving
|
|
files in Internet Explorer versions 6-9. The <code>xlsx.extendscript.js</code> script
|
|
bundles the shim in a format suitable for Photoshop and other Adobe products.</p>
|
|
</details>
|
|
<h4>
|
|
<a id="user-content-ecmascript-modules" class="anchor" href="#ecmascript-modules" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>ECMAScript Modules</h4>
|
|
<p><em>Browser ESM</em></p>
|
|
<p>The ECMAScript Module build is saved to <code>xlsx.mjs</code> and can be directly added to
|
|
a page with a <code>script</code> tag using <code>type="module"</code>:</p>
|
|
<div class="highlight highlight-text-html-basic"><pre><span class="pl-kos"><</span><span class="pl-ent">script</span> <span class="pl-c1">type</span>="<span class="pl-s">module</span>"<span class="pl-kos">></span>
|
|
<span class="pl-k">import</span> <span class="pl-kos">{</span> <span class="pl-s1">read</span><span class="pl-kos">,</span> <span class="pl-s1">writeFileXLSX</span> <span class="pl-kos">}</span> <span class="pl-k">from</span> <span class="pl-s">"https://cdn.sheetjs.com/xlsx-0.18.7/package/xlsx.mjs"</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* load the codepage support library for extended support with older formats */</span>
|
|
<span class="pl-k">import</span> <span class="pl-kos">{</span> <span class="pl-s1">set_cptable</span> <span class="pl-kos">}</span> <span class="pl-k">from</span> <span class="pl-s">"https://cdn.sheetjs.com/xlsx-0.18.7/package/xlsx.mjs"</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">import</span> <span class="pl-c1">*</span> <span class="pl-k">as</span> <span class="pl-s1">cptable</span> <span class="pl-k">from</span> <span class="pl-s">'https://cdn.sheetjs.com/xlsx-0.18.7/package/dist/cpexcel.full.mjs'</span><span class="pl-kos">;</span>
|
|
<span class="pl-en">set_cptable</span><span class="pl-kos">(</span><span class="pl-s1">cptable</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-kos"></</span><span class="pl-ent">script</span><span class="pl-kos">></span></pre></div>
|
|
<p><em>Frameworks (Angular, VueJS, React) and Bundlers (webpack, etc)</em></p>
|
|
<p>The NodeJS package is readily installed from the tarballs:</p>
|
|
<div class="highlight highlight-source-shell"><pre>$ npm install --save https://cdn.sheetjs.com/xlsx-0.18.7/xlsx-0.18.7.tgz <span class="pl-c"><span class="pl-c">#</span> npm</span>
|
|
$ pnpm install --save https://cdn.sheetjs.com/xlsx-0.18.7/xlsx-0.18.7.tgz <span class="pl-c"><span class="pl-c">#</span> pnpm</span>
|
|
$ yarn add --save https://cdn.sheetjs.com/xlsx-0.18.7/xlsx-0.18.7.tgz <span class="pl-c"><span class="pl-c">#</span> yarn</span></pre></div>
|
|
<p>Once installed, the library can be imported under the name <code>xlsx</code>:</p>
|
|
<div class="highlight highlight-source-ts"><pre><span class="pl-k">import</span> <span class="pl-kos">{</span> <span class="pl-s1">read</span><span class="pl-kos">,</span> <span class="pl-s1">writeFileXLSX</span> <span class="pl-kos">}</span> <span class="pl-k">from</span> <span class="pl-s">"xlsx"</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* load the codepage support library for extended support with older formats */</span>
|
|
<span class="pl-k">import</span> <span class="pl-kos">{</span> <span class="pl-s1">set_cptable</span> <span class="pl-kos">}</span> <span class="pl-k">from</span> <span class="pl-s">"xlsx"</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">import</span> <span class="pl-c1">*</span> <span class="pl-k">as</span> <span class="pl-s1">cptable</span> <span class="pl-k">from</span> <span class="pl-s">'xlsx/dist/cpexcel.full.mjs'</span><span class="pl-kos">;</span>
|
|
<span class="pl-en">set_cptable</span><span class="pl-kos">(</span><span class="pl-s1">cptable</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<h4>
|
|
<a id="user-content-deno" class="anchor" href="#deno" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Deno</h4>
|
|
<p><code>xlsx.mjs</code> can be imported in Deno:</p>
|
|
<div class="highlight highlight-source-ts"><pre><span class="pl-c">// <span class="pl-k">@deno</span>-types="https://cdn.sheetjs.com/xlsx-0.18.7/package/types/index.d.ts"</span>
|
|
<span class="pl-k">import</span> <span class="pl-c1">*</span> <span class="pl-k">as</span> <span class="pl-smi">XLSX</span> <span class="pl-k">from</span> <span class="pl-s">'https://cdn.sheetjs.com/xlsx-0.18.7/package/xlsx.mjs'</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* load the codepage support library for extended support with older formats */</span>
|
|
<span class="pl-k">import</span> <span class="pl-c1">*</span> <span class="pl-k">as</span> <span class="pl-s1">cptable</span> <span class="pl-k">from</span> <span class="pl-s">'https://cdn.sheetjs.com/xlsx-0.18.7/package/dist/cpexcel.full.mjs'</span><span class="pl-kos">;</span>
|
|
<span class="pl-smi">XLSX</span><span class="pl-kos">.</span><span class="pl-en">set_cptable</span><span class="pl-kos">(</span><span class="pl-s1">cptable</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<h4>
|
|
<a id="user-content-nodejs" class="anchor" href="#nodejs" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>NodeJS</h4>
|
|
<p>Tarballs are available on <a href="https://cdn.sheetjs.com" rel="nofollow">https://cdn.sheetjs.com</a>.</p>
|
|
<p>Each individual version can be referenced using a similar URL pattern.
|
|
<a href="https://cdn.sheetjs.com/xlsx-0.18.7/xlsx-0.18.7.tgz" rel="nofollow">https://cdn.sheetjs.com/xlsx-0.18.7/xlsx-0.18.7.tgz</a> is the URL for <code>0.18.7</code></p>
|
|
<p><a href="https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz" rel="nofollow">https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz</a> is a link to the latest
|
|
version and will refresh on each release.</p>
|
|
<p><em>Installation</em></p>
|
|
<p>Tarballs can be directly installed using a package manager:</p>
|
|
<div class="highlight highlight-source-shell"><pre>$ npm install https://cdn.sheetjs.com/xlsx-0.18.7/xlsx-0.18.7.tgz <span class="pl-c"><span class="pl-c">#</span> npm</span>
|
|
$ pnpm install https://cdn.sheetjs.com/xlsx-0.18.7/xlsx-0.18.7.tgz <span class="pl-c"><span class="pl-c">#</span> pnpm</span>
|
|
$ yarn add https://cdn.sheetjs.com/xlsx-0.18.7/xlsx-0.18.7.tgz <span class="pl-c"><span class="pl-c">#</span> yarn</span></pre></div>
|
|
<p>For general stability, "vendoring" modules is the recommended approach:</p>
|
|
<ol>
|
|
<li>
|
|
<p>Download the tarball (<code>xlsx-0.18.7.tgz</code>) for the desired version. The current
|
|
version is available at <a href="https://cdn.sheetjs.com/xlsx-0.18.7/xlsx-0.18.7.tgz" rel="nofollow">https://cdn.sheetjs.com/xlsx-0.18.7/xlsx-0.18.7.tgz</a></p>
|
|
</li>
|
|
<li>
|
|
<p>Create a <code>vendor</code> subdirectory at the root of your project and move the
|
|
tarball to that folder. Add it to your project repository.</p>
|
|
</li>
|
|
<li>
|
|
<p>Install the tarball using a package manager:</p>
|
|
</li>
|
|
</ol>
|
|
<div class="highlight highlight-source-shell"><pre>$ npm install --save file:vendor/xlsx-0.18.7.tgz <span class="pl-c"><span class="pl-c">#</span> npm</span>
|
|
$ pnpm install --save file:vendor/xlsx-0.18.7.tgz <span class="pl-c"><span class="pl-c">#</span> pnpm</span>
|
|
$ yarn add file:vendor/xlsx-0.18.7.tgz <span class="pl-c"><span class="pl-c">#</span> yarn</span></pre></div>
|
|
<p>The package will be installed and accessible as <code>xlsx</code>.</p>
|
|
<p><em>Usage</em></p>
|
|
<p>By default, the module supports <code>require</code> and it will automatically add support
|
|
for streams and filesystem access:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> <span class="pl-c1">XLSX</span> <span class="pl-c1">=</span> <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">"xlsx"</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>The module also ships with <code>xlsx.mjs</code> for use with <code>import</code>. The <code>mjs</code> version
|
|
does not automatically load native node modules:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">import</span> <span class="pl-c1">*</span> <span class="pl-k">as</span> <span class="pl-c1">XLSX</span> <span class="pl-k">from</span> <span class="pl-s">'xlsx/xlsx.mjs'</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* load 'fs' for readFile and writeFile support */</span>
|
|
<span class="pl-k">import</span> <span class="pl-c1">*</span> <span class="pl-k">as</span> <span class="pl-s1">fs</span> <span class="pl-k">from</span> <span class="pl-s">'fs'</span><span class="pl-kos">;</span>
|
|
<span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-en">set_fs</span><span class="pl-kos">(</span><span class="pl-s1">fs</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* load 'stream' for stream support */</span>
|
|
<span class="pl-k">import</span> <span class="pl-kos">{</span> <span class="pl-v">Readable</span> <span class="pl-kos">}</span> <span class="pl-k">from</span> <span class="pl-s">'stream'</span><span class="pl-kos">;</span>
|
|
<span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">stream</span><span class="pl-kos">.</span><span class="pl-en">set_readable</span><span class="pl-kos">(</span><span class="pl-v">Readable</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* load the codepage support library for extended support with older formats */</span>
|
|
<span class="pl-k">import</span> <span class="pl-c1">*</span> <span class="pl-k">as</span> <span class="pl-s1">cpexcel</span> <span class="pl-k">from</span> <span class="pl-s">'xlsx/dist/cpexcel.full.mjs'</span><span class="pl-kos">;</span>
|
|
<span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-en">set_cptable</span><span class="pl-kos">(</span><span class="pl-s1">cpexcel</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<h4>
|
|
<a id="user-content-photoshop-and-indesign" class="anchor" href="#photoshop-and-indesign" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Photoshop and InDesign</h4>
|
|
<p><code>dist/xlsx.extendscript.js</code> is an ExtendScript build for Photoshop and InDesign.
|
|
<a href="https://cdn.sheetjs.com/xlsx-0.18.7/package/dist/xlsx.extendscript.js" rel="nofollow">https://cdn.sheetjs.com/xlsx-0.18.7/package/dist/xlsx.extendscript.js</a> is the
|
|
current version. After downloading the script, it can be directly referenced
|
|
with a <code>#include</code> directive:</p>
|
|
<pre lang="extendscript"><code>#include "xlsx.extendscript.js"
|
|
</code></pre>
|
|
<h3>
|
|
<a id="user-content-usage" class="anchor" href="#usage" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Usage</h3>
|
|
<p>Most scenarios involving spreadsheets and data can be broken into 5 parts:</p>
|
|
<ol>
|
|
<li>
|
|
<p><strong>Acquire Data</strong>: Data may be stored anywhere: local or remote files,
|
|
databases, HTML TABLE, or even generated programmatically in the web browser.</p>
|
|
</li>
|
|
<li>
|
|
<p><strong>Extract Data</strong>: For spreadsheet files, this involves parsing raw bytes to
|
|
read the cell data. For general JS data, this involves reshaping the data.</p>
|
|
</li>
|
|
<li>
|
|
<p><strong>Process Data</strong>: From generating summary statistics to cleaning data
|
|
records, this step is the heart of the problem.</p>
|
|
</li>
|
|
<li>
|
|
<p><strong>Package Data</strong>: This can involve making a new spreadsheet or serializing
|
|
with <code>JSON.stringify</code> or writing XML or simply flattening data for UI tools.</p>
|
|
</li>
|
|
<li>
|
|
<p><strong>Release Data</strong>: Spreadsheet files can be uploaded to a server or written
|
|
locally. Data can be presented to users in an HTML TABLE or data grid.</p>
|
|
</li>
|
|
</ol>
|
|
<p>A common problem involves generating a valid spreadsheet export from data stored
|
|
in an HTML table. In this example, an HTML TABLE on the page will be scraped,
|
|
a row will be added to the bottom with the date of the report, and a new file
|
|
will be generated and downloaded locally. <code>XLSX.writeFile</code> takes care of
|
|
packaging the data and attempting a local download:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-c">// Acquire Data (reference to the HTML table)</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">table_elt</span> <span class="pl-c1">=</span> <span class="pl-smi">document</span><span class="pl-kos">.</span><span class="pl-en">getElementById</span><span class="pl-kos">(</span><span class="pl-s">"my-table-id"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">// Extract Data (create a workbook object from the table)</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">workbook</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">table_to_book</span><span class="pl-kos">(</span><span class="pl-s1">table_elt</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">// Process Data (add a new row)</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">ws</span> <span class="pl-c1">=</span> <span class="pl-s1">workbook</span><span class="pl-kos">.</span><span class="pl-c1">Sheets</span><span class="pl-kos">[</span><span class="pl-s">"Sheet1"</span><span class="pl-kos">]</span><span class="pl-kos">;</span>
|
|
<span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">sheet_add_aoa</span><span class="pl-kos">(</span><span class="pl-s1">ws</span><span class="pl-kos">,</span> <span class="pl-kos">[</span><span class="pl-kos">[</span><span class="pl-s">"Created "</span><span class="pl-c1">+</span><span class="pl-k">new</span> <span class="pl-v">Date</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">toISOString</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">]</span><span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-kos">{</span><span class="pl-c1">origin</span>:<span class="pl-c1">-</span><span class="pl-c1">1</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">// Package and Release Data (`writeFile` tries to write and save an XLSB file)</span>
|
|
<span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-en">writeFile</span><span class="pl-kos">(</span><span class="pl-s1">workbook</span><span class="pl-kos">,</span> <span class="pl-s">"Report.xlsb"</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>This library tries to simplify steps 2 and 4 with functions to extract useful
|
|
data from spreadsheet files (<code>read</code> / <code>readFile</code>) and generate new spreadsheet
|
|
files from data (<code>write</code> / <code>writeFile</code>). Additional utility functions like
|
|
<code>table_to_book</code> work with other common data sources like HTML tables.</p>
|
|
<p>This documentation and various demo projects cover a number of common scenarios
|
|
and approaches for steps 1 and 5.</p>
|
|
<p>Utility functions help with step 3.</p>
|
|
<p><a href="#acquiring-and-extracting-data">"Acquiring and Extracting Data"</a> describes
|
|
solutions for common data import scenarios.</p>
|
|
<p><a href="#packaging-and-releasing-data">"Packaging and Releasing Data"</a> describes
|
|
solutions for common data export scenarios.</p>
|
|
<p><a href="#packaging-and-releasing-data">"Processing Data"</a> describes solutions for
|
|
common workbook processing and manipulation scenarios.</p>
|
|
<p><a href="#utility-functions">"Utility Functions"</a> details utility functions for
|
|
translating JSON Arrays and other common JS structures into worksheet objects.</p>
|
|
<h3>
|
|
<a id="user-content-the-zen-of-sheetjs" class="anchor" href="#the-zen-of-sheetjs" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>The Zen of SheetJS</h3>
|
|
<p><em>Data processing should fit in any workflow</em></p>
|
|
<p>The library does not impose a separate lifecycle. It fits nicely in websites
|
|
and apps built using any framework. The plain JS data objects play nice with
|
|
Web Workers and future APIs.</p>
|
|
<p><em>JavaScript is a powerful language for data processing</em></p>
|
|
<p>The <a href="#common-spreadsheet-format">"Common Spreadsheet Format"</a> is a simple object
|
|
representation of the core concepts of a workbook. The various functions in the
|
|
library provide low-level tools for working with the object.</p>
|
|
<p>For friendly JS processing, there are utility functions for converting parts of
|
|
a worksheet to/from an Array of Arrays. The following example combines powerful
|
|
JS Array methods with a network request library to download data, select the
|
|
information we want and create a workbook file:</p>
|
|
<details>
|
|
<summary><b>Get Data from a JSON Endpoint and Generate a Workbook</b> (click to show)</summary>
|
|
<p>The goal is to generate a XLSB workbook of US President names and birthdays.</p>
|
|
<p><strong>Acquire Data</strong></p>
|
|
<p><em>Raw Data</em></p>
|
|
<p><a href="https://theunitedstates.io/congress-legislators/executive.json" rel="nofollow">https://theunitedstates.io/congress-legislators/executive.json</a> has the desired
|
|
data. For example, John Adams:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-kos">{</span>
|
|
<span class="pl-s">"id"</span>: <span class="pl-kos">{</span> <span class="pl-c">/* (data omitted) */</span> <span class="pl-kos">}</span><span class="pl-kos">,</span>
|
|
<span class="pl-s">"name"</span>: <span class="pl-kos">{</span>
|
|
<span class="pl-s">"first"</span>: <span class="pl-s">"John"</span><span class="pl-kos">,</span> <span class="pl-c">// <-- first name</span>
|
|
<span class="pl-s">"last"</span>: <span class="pl-s">"Adams"</span> <span class="pl-c">// <-- last name</span>
|
|
<span class="pl-kos">}</span><span class="pl-kos">,</span>
|
|
<span class="pl-s">"bio"</span>: <span class="pl-kos">{</span>
|
|
<span class="pl-s">"birthday"</span>: <span class="pl-s">"1735-10-19"</span><span class="pl-kos">,</span> <span class="pl-c">// <-- birthday</span>
|
|
<span class="pl-s">"gender"</span>: <span class="pl-s">"M"</span>
|
|
<span class="pl-kos">}</span><span class="pl-kos">,</span>
|
|
<span class="pl-s">"terms"</span>: <span class="pl-kos">[</span>
|
|
<span class="pl-kos">{</span> <span class="pl-s">"type"</span>: <span class="pl-s">"viceprez"</span><span class="pl-kos">,</span> <span class="pl-c">/* (other fields omitted) */</span> <span class="pl-kos">}</span><span class="pl-kos">,</span>
|
|
<span class="pl-kos">{</span> <span class="pl-s">"type"</span>: <span class="pl-s">"viceprez"</span><span class="pl-kos">,</span> <span class="pl-c">/* (other fields omitted) */</span> <span class="pl-kos">}</span><span class="pl-kos">,</span>
|
|
<span class="pl-kos">{</span> <span class="pl-s">"type"</span>: <span class="pl-s">"prez"</span><span class="pl-kos">,</span> <span class="pl-c">/* (other fields omitted) */</span> <span class="pl-kos">}</span> <span class="pl-c">// <-- look for "prez"</span>
|
|
<span class="pl-kos">]</span>
|
|
<span class="pl-kos">}</span></pre></div>
|
|
<p><em>Filtering for Presidents</em></p>
|
|
<p>The dataset includes Aaron Burr, a Vice President who was never President!</p>
|
|
<p><code>Array#filter</code> creates a new array with the desired rows. A President served
|
|
at least one term with <code>type</code> set to <code>"prez"</code>. To test if a particular row has
|
|
at least one <code>"prez"</code> term, <code>Array#some</code> is another native JS function. The
|
|
complete filter would be:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">const</span> <span class="pl-s1">prez</span> <span class="pl-c1">=</span> <span class="pl-s1">raw_data</span><span class="pl-kos">.</span><span class="pl-en">filter</span><span class="pl-kos">(</span><span class="pl-s1">row</span> <span class="pl-c1">=></span> <span class="pl-s1">row</span><span class="pl-kos">.</span><span class="pl-c1">terms</span><span class="pl-kos">.</span><span class="pl-en">some</span><span class="pl-kos">(</span><span class="pl-s1">term</span> <span class="pl-c1">=></span> <span class="pl-s1">term</span><span class="pl-kos">.</span><span class="pl-c1">type</span> <span class="pl-c1">===</span> <span class="pl-s">"prez"</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p><em>Lining up the data</em></p>
|
|
<p>For this example, the name will be the first name combined with the last name
|
|
(<code>row.name.first + " " + row.name.last</code>) and the birthday will be the subfield
|
|
<code>row.bio.birthday</code>. Using <code>Array#map</code>, the dataset can be massaged in one call:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">const</span> <span class="pl-s1">rows</span> <span class="pl-c1">=</span> <span class="pl-s1">prez</span><span class="pl-kos">.</span><span class="pl-en">map</span><span class="pl-kos">(</span><span class="pl-s1">row</span> <span class="pl-c1">=></span> <span class="pl-kos">(</span><span class="pl-kos">{</span>
|
|
<span class="pl-c1">name</span>: <span class="pl-s1">row</span><span class="pl-kos">.</span><span class="pl-c1">name</span><span class="pl-kos">.</span><span class="pl-c1">first</span> <span class="pl-c1">+</span> <span class="pl-s">" "</span> <span class="pl-c1">+</span> <span class="pl-s1">row</span><span class="pl-kos">.</span><span class="pl-c1">name</span><span class="pl-kos">.</span><span class="pl-c1">last</span><span class="pl-kos">,</span>
|
|
<span class="pl-c1">birthday</span>: <span class="pl-s1">row</span><span class="pl-kos">.</span><span class="pl-c1">bio</span><span class="pl-kos">.</span><span class="pl-c1">birthday</span>
|
|
<span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>The result is an array of "simple" objects with no nesting:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-kos">[</span>
|
|
<span class="pl-kos">{</span> <span class="pl-c1">name</span>: <span class="pl-s">"George Washington"</span><span class="pl-kos">,</span> <span class="pl-c1">birthday</span>: <span class="pl-s">"1732-02-22"</span> <span class="pl-kos">}</span><span class="pl-kos">,</span>
|
|
<span class="pl-kos">{</span> <span class="pl-c1">name</span>: <span class="pl-s">"John Adams"</span><span class="pl-kos">,</span> <span class="pl-c1">birthday</span>: <span class="pl-s">"1735-10-19"</span> <span class="pl-kos">}</span><span class="pl-kos">,</span>
|
|
<span class="pl-c">// ... one row per President</span>
|
|
<span class="pl-kos">]</span></pre></div>
|
|
<p><strong>Extract Data</strong></p>
|
|
<p>With the cleaned dataset, <code>XLSX.utils.json_to_sheet</code> generates a worksheet:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">const</span> <span class="pl-s1">worksheet</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">json_to_sheet</span><span class="pl-kos">(</span><span class="pl-s1">rows</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p><code>XLSX.utils.book_new</code> creates a new workbook and <code>XLSX.utils.book_append_sheet</code>
|
|
appends a worksheet to the workbook. The new worksheet will be called "Dates":</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">const</span> <span class="pl-s1">workbook</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">book_new</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">book_append_sheet</span><span class="pl-kos">(</span><span class="pl-s1">workbook</span><span class="pl-kos">,</span> <span class="pl-s1">worksheet</span><span class="pl-kos">,</span> <span class="pl-s">"Dates"</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p><strong>Process Data</strong></p>
|
|
<p><em>Fixing headers</em></p>
|
|
<p>By default, <code>json_to_sheet</code> creates a worksheet with a header row. In this case,
|
|
the headers come from the JS object keys: "name" and "birthday".</p>
|
|
<p>The headers are in cells A1 and B1. <code>XLSX.utils.sheet_add_aoa</code> can write text
|
|
values to the existing worksheet starting at cell A1:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">sheet_add_aoa</span><span class="pl-kos">(</span><span class="pl-s1">worksheet</span><span class="pl-kos">,</span> <span class="pl-kos">[</span><span class="pl-kos">[</span><span class="pl-s">"Name"</span><span class="pl-kos">,</span> <span class="pl-s">"Birthday"</span><span class="pl-kos">]</span><span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-kos">{</span> <span class="pl-c1">origin</span>: <span class="pl-s">"A1"</span> <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p><em>Fixing Column Widths</em></p>
|
|
<p>Some of the names are longer than the default column width. Column widths are
|
|
set by <a href="#row-and-column-properties">setting the <code>"!cols"</code> worksheet property</a>.</p>
|
|
<p>The following line sets the width of column A to approximately 10 characters:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-s1">worksheet</span><span class="pl-kos">[</span><span class="pl-s">"!cols"</span><span class="pl-kos">]</span> <span class="pl-c1">=</span> <span class="pl-kos">[</span> <span class="pl-kos">{</span> <span class="pl-c1">wch</span>: <span class="pl-c1">10</span> <span class="pl-kos">}</span> <span class="pl-kos">]</span><span class="pl-kos">;</span> <span class="pl-c">// set column A width to 10 characters</span></pre></div>
|
|
<p>One <code>Array#reduce</code> call over <code>rows</code> can calculate the maximum width:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">const</span> <span class="pl-s1">max_width</span> <span class="pl-c1">=</span> <span class="pl-s1">rows</span><span class="pl-kos">.</span><span class="pl-en">reduce</span><span class="pl-kos">(</span><span class="pl-kos">(</span><span class="pl-s1">w</span><span class="pl-kos">,</span> <span class="pl-s1">r</span><span class="pl-kos">)</span> <span class="pl-c1">=></span> <span class="pl-v">Math</span><span class="pl-kos">.</span><span class="pl-en">max</span><span class="pl-kos">(</span><span class="pl-s1">w</span><span class="pl-kos">,</span> <span class="pl-s1">r</span><span class="pl-kos">.</span><span class="pl-c1">name</span><span class="pl-kos">.</span><span class="pl-c1">length</span><span class="pl-kos">)</span><span class="pl-kos">,</span> <span class="pl-c1">10</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-s1">worksheet</span><span class="pl-kos">[</span><span class="pl-s">"!cols"</span><span class="pl-kos">]</span> <span class="pl-c1">=</span> <span class="pl-kos">[</span> <span class="pl-kos">{</span> <span class="pl-c1">wch</span>: <span class="pl-s1">max_width</span> <span class="pl-kos">}</span> <span class="pl-kos">]</span><span class="pl-kos">;</span></pre></div>
|
|
<p>Note: If the starting point was a file or HTML table, <code>XLSX.utils.sheet_to_json</code>
|
|
will generate an array of JS objects.</p>
|
|
<p><strong>Package and Release Data</strong></p>
|
|
<p><code>XLSX.writeFile</code> creates a spreadsheet file and tries to write it to the system.
|
|
In the browser, it will try to prompt the user to download the file. In NodeJS,
|
|
it will write to the local directory.</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-en">writeFile</span><span class="pl-kos">(</span><span class="pl-s1">workbook</span><span class="pl-kos">,</span> <span class="pl-s">"Presidents.xlsx"</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p><strong>Complete Example</strong></p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-c">// Uncomment the next line for use in NodeJS:</span>
|
|
<span class="pl-c">// const XLSX = require("xlsx"), axios = require("axios");</span>
|
|
|
|
<span class="pl-kos">(</span><span class="pl-k">async</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c1">=></span> <span class="pl-kos">{</span>
|
|
<span class="pl-c">/* fetch JSON data and parse */</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">url</span> <span class="pl-c1">=</span> <span class="pl-s">"https://theunitedstates.io/congress-legislators/executive.json"</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">raw_data</span> <span class="pl-c1">=</span> <span class="pl-kos">(</span><span class="pl-k">await</span> <span class="pl-en">axios</span><span class="pl-kos">(</span><span class="pl-s1">url</span><span class="pl-kos">,</span> <span class="pl-kos">{</span><span class="pl-c1">responseType</span>: <span class="pl-s">"json"</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-c1">data</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* filter for the Presidents */</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">prez</span> <span class="pl-c1">=</span> <span class="pl-s1">raw_data</span><span class="pl-kos">.</span><span class="pl-en">filter</span><span class="pl-kos">(</span><span class="pl-s1">row</span> <span class="pl-c1">=></span> <span class="pl-s1">row</span><span class="pl-kos">.</span><span class="pl-c1">terms</span><span class="pl-kos">.</span><span class="pl-en">some</span><span class="pl-kos">(</span><span class="pl-s1">term</span> <span class="pl-c1">=></span> <span class="pl-s1">term</span><span class="pl-kos">.</span><span class="pl-c1">type</span> <span class="pl-c1">===</span> <span class="pl-s">"prez"</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* flatten objects */</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">rows</span> <span class="pl-c1">=</span> <span class="pl-s1">prez</span><span class="pl-kos">.</span><span class="pl-en">map</span><span class="pl-kos">(</span><span class="pl-s1">row</span> <span class="pl-c1">=></span> <span class="pl-kos">(</span><span class="pl-kos">{</span>
|
|
<span class="pl-c1">name</span>: <span class="pl-s1">row</span><span class="pl-kos">.</span><span class="pl-c1">name</span><span class="pl-kos">.</span><span class="pl-c1">first</span> <span class="pl-c1">+</span> <span class="pl-s">" "</span> <span class="pl-c1">+</span> <span class="pl-s1">row</span><span class="pl-kos">.</span><span class="pl-c1">name</span><span class="pl-kos">.</span><span class="pl-c1">last</span><span class="pl-kos">,</span>
|
|
<span class="pl-c1">birthday</span>: <span class="pl-s1">row</span><span class="pl-kos">.</span><span class="pl-c1">bio</span><span class="pl-kos">.</span><span class="pl-c1">birthday</span>
|
|
<span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* generate worksheet and workbook */</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">worksheet</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">json_to_sheet</span><span class="pl-kos">(</span><span class="pl-s1">rows</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">workbook</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">book_new</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">book_append_sheet</span><span class="pl-kos">(</span><span class="pl-s1">workbook</span><span class="pl-kos">,</span> <span class="pl-s1">worksheet</span><span class="pl-kos">,</span> <span class="pl-s">"Dates"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* fix headers */</span>
|
|
<span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">sheet_add_aoa</span><span class="pl-kos">(</span><span class="pl-s1">worksheet</span><span class="pl-kos">,</span> <span class="pl-kos">[</span><span class="pl-kos">[</span><span class="pl-s">"Name"</span><span class="pl-kos">,</span> <span class="pl-s">"Birthday"</span><span class="pl-kos">]</span><span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-kos">{</span> <span class="pl-c1">origin</span>: <span class="pl-s">"A1"</span> <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* calculate column width */</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">max_width</span> <span class="pl-c1">=</span> <span class="pl-s1">rows</span><span class="pl-kos">.</span><span class="pl-en">reduce</span><span class="pl-kos">(</span><span class="pl-kos">(</span><span class="pl-s1">w</span><span class="pl-kos">,</span> <span class="pl-s1">r</span><span class="pl-kos">)</span> <span class="pl-c1">=></span> <span class="pl-v">Math</span><span class="pl-kos">.</span><span class="pl-en">max</span><span class="pl-kos">(</span><span class="pl-s1">w</span><span class="pl-kos">,</span> <span class="pl-s1">r</span><span class="pl-kos">.</span><span class="pl-c1">name</span><span class="pl-kos">.</span><span class="pl-c1">length</span><span class="pl-kos">)</span><span class="pl-kos">,</span> <span class="pl-c1">10</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-s1">worksheet</span><span class="pl-kos">[</span><span class="pl-s">"!cols"</span><span class="pl-kos">]</span> <span class="pl-c1">=</span> <span class="pl-kos">[</span> <span class="pl-kos">{</span> <span class="pl-c1">wch</span>: <span class="pl-s1">max_width</span> <span class="pl-kos">}</span> <span class="pl-kos">]</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* create an XLSX file and try to save to Presidents.xlsx */</span>
|
|
<span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-en">writeFile</span><span class="pl-kos">(</span><span class="pl-s1">workbook</span><span class="pl-kos">,</span> <span class="pl-s">"Presidents.xlsx"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>For use in the web browser, assuming the snippet is saved to <code>snippet.js</code>,
|
|
script tags should be used to include the <code>axios</code> and <code>xlsx</code> standalone builds:</p>
|
|
<div class="highlight highlight-text-html-basic"><pre><span class="pl-kos"><</span><span class="pl-ent">script</span> <span class="pl-c1">src</span>="<span class="pl-s">https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js</span>"<span class="pl-kos">></span><span class="pl-kos"></</span><span class="pl-ent">script</span><span class="pl-kos">></span>
|
|
<span class="pl-kos"><</span><span class="pl-ent">script</span> <span class="pl-c1">src</span>="<span class="pl-s">https://unpkg.com/axios/dist/axios.min.js</span>"<span class="pl-kos">></span><span class="pl-kos"></</span><span class="pl-ent">script</span><span class="pl-kos">></span>
|
|
<span class="pl-kos"><</span><span class="pl-ent">script</span> <span class="pl-c1">src</span>="<span class="pl-s">snippet.js</span>"<span class="pl-kos">></span><span class="pl-kos"></</span><span class="pl-ent">script</span><span class="pl-kos">></span></pre></div>
|
|
</details>
|
|
<p><em>File formats are implementation details</em></p>
|
|
<p>The parser covers a wide gamut of common spreadsheet file formats to ensure that
|
|
"HTML-saved-as-XLS" files work as well as actual XLS or XLSX files.</p>
|
|
<p>The writer supports a number of common output formats for broad compatibility
|
|
with the data ecosystem.</p>
|
|
<p>To the greatest extent possible, data processing code should not have to worry
|
|
about the specific file formats involved.</p>
|
|
<h3>
|
|
<a id="user-content-js-ecosystem-demos" class="anchor" href="#js-ecosystem-demos" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>JS Ecosystem Demos</h3>
|
|
<p>The <a href="https://github.com/SheetJS/SheetJS/tree/master/demos/"><code>demos</code> directory</a> includes sample projects for:</p>
|
|
<p><strong>Frameworks and APIs</strong></p>
|
|
<ul>
|
|
<li><a href="https://github.com/SheetJS/SheetJS/tree/master/demos/angular/"><code>angularjs</code></a></li>
|
|
<li><a href="https://github.com/SheetJS/SheetJS/tree/master/demos/angular2/"><code>angular and ionic</code></a></li>
|
|
<li><a href="https://github.com/SheetJS/SheetJS/tree/master/demos/knockout/"><code>knockout</code></a></li>
|
|
<li><a href="https://github.com/SheetJS/SheetJS/tree/master/demos/meteor/"><code>meteor</code></a></li>
|
|
<li><a href="https://github.com/SheetJS/SheetJS/tree/master/demos/react/"><code>react, react-native, next</code></a></li>
|
|
<li><a href="https://github.com/SheetJS/SheetJS/tree/master/demos/vue/"><code>vue 2.x, weex, nuxt</code></a></li>
|
|
<li><a href="https://github.com/SheetJS/SheetJS/tree/master/demos/xhr/"><code>XMLHttpRequest and fetch</code></a></li>
|
|
<li><a href="https://github.com/SheetJS/SheetJS/tree/master/demos/server/"><code>nodejs server</code></a></li>
|
|
<li><a href="https://github.com/SheetJS/SheetJS/tree/master/demos/database/"><code>databases and key/value stores</code></a></li>
|
|
<li><a href="https://github.com/SheetJS/SheetJS/tree/master/demos/array/"><code>typed arrays and math</code></a></li>
|
|
</ul>
|
|
<p><strong>Bundlers and Tooling</strong></p>
|
|
<ul>
|
|
<li><a href="https://github.com/SheetJS/SheetJS/tree/master/demos/browserify/"><code>browserify</code></a></li>
|
|
<li><a href="https://github.com/SheetJS/SheetJS/tree/master/demos/fusebox/"><code>fusebox</code></a></li>
|
|
<li><a href="https://github.com/SheetJS/SheetJS/tree/master/demos/parcel/"><code>parcel</code></a></li>
|
|
<li><a href="https://github.com/SheetJS/SheetJS/tree/master/demos/requirejs/"><code>requirejs</code></a></li>
|
|
<li><a href="https://github.com/SheetJS/SheetJS/tree/master/demos/rollup/"><code>rollup</code></a></li>
|
|
<li><a href="https://github.com/SheetJS/SheetJS/tree/master/demos/systemjs/"><code>systemjs</code></a></li>
|
|
<li><a href="https://github.com/SheetJS/SheetJS/tree/master/demos/typescript/"><code>typescript</code></a></li>
|
|
<li><a href="https://github.com/SheetJS/SheetJS/tree/master/demos/webpack/"><code>webpack 2.x</code></a></li>
|
|
</ul>
|
|
<p><strong>Platforms and Integrations</strong></p>
|
|
<ul>
|
|
<li><a href="https://github.com/SheetJS/SheetJS/tree/master/demos/deno/"><code>deno</code></a></li>
|
|
<li><a href="https://github.com/SheetJS/SheetJS/tree/master/demos/electron/"><code>electron application</code></a></li>
|
|
<li><a href="https://github.com/SheetJS/SheetJS/tree/master/demos/nwjs/"><code>nw.js application</code></a></li>
|
|
<li><a href="https://github.com/SheetJS/SheetJS/tree/master/demos/chrome/"><code>Chrome / Chromium extensions</code></a></li>
|
|
<li><a href="https://github.com/SheetJS/SheetJS/tree/master/demos/google-sheet/"><code>Download a Google Sheet locally</code></a></li>
|
|
<li><a href="https://github.com/SheetJS/SheetJS/tree/master/demos/extendscript/"><code>Adobe ExtendScript</code></a></li>
|
|
<li><a href="https://github.com/SheetJS/SheetJS/tree/master/demos/headless/"><code>Headless Browsers</code></a></li>
|
|
<li><a href="https://github.com/SheetJS/SheetJS/tree/master/demos/datagrid/"><code>canvas-datagrid</code></a></li>
|
|
<li><a href="https://github.com/SheetJS/SheetJS/tree/master/demos/xspreadsheet/"><code>x-spreadsheet</code></a></li>
|
|
<li><a href="https://github.com/SheetJS/SheetJS/tree/master/demos/react/modify/"><code>react-data-grid</code></a></li>
|
|
<li><a href="https://github.com/SheetJS/SheetJS/tree/master/demos/vue/modify/"><code>vue3-table-light</code></a></li>
|
|
<li><a href="https://github.com/SheetJS/SheetJS/tree/master/demos/altjs/"><code>Swift JSC and other engines</code></a></li>
|
|
<li><a href="https://github.com/SheetJS/SheetJS/tree/master/demos/function/"><code>"serverless" functions</code></a></li>
|
|
<li><a href="https://github.com/SheetJS/SheetJS/tree/master/demos/oldie/"><code>internet explorer</code></a></li>
|
|
</ul>
|
|
<p>Other examples are included in the <a href="https://github.com/SheetJS/SheetJS/tree/master/demos/showcase/">showcase</a>.</p>
|
|
<p><a href="https://sheetjs.com/demos/modify.html" rel="nofollow">https://sheetjs.com/demos/modify.html</a> shows a complete example of reading,
|
|
modifying, and writing files.</p>
|
|
<p><a href="https://github.com/SheetJS/sheetjs/blob/HEAD/bin/xlsx.njs">https://github.com/SheetJS/sheetjs/blob/HEAD/bin/xlsx.njs</a> is the command-line
|
|
tool included with node installations, reading spreadsheet files and exporting
|
|
the contents in various formats.</p>
|
|
<h2>
|
|
<a id="user-content-acquiring-and-extracting-data" class="anchor" href="#acquiring-and-extracting-data" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Acquiring and Extracting Data</h2>
|
|
<h3>
|
|
<a id="user-content-parsing-workbooks" class="anchor" href="#parsing-workbooks" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Parsing Workbooks</h3>
|
|
<p><strong>API</strong></p>
|
|
<p><em>Extract data from spreadsheet bytes</em></p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> <span class="pl-s1">workbook</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-en">read</span><span class="pl-kos">(</span><span class="pl-s1">data</span><span class="pl-kos">,</span> <span class="pl-s1">opts</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>The <code>read</code> method can extract data from spreadsheet bytes stored in a JS string,
|
|
"binary string", NodeJS buffer or typed array (<code>Uint8Array</code> or <code>ArrayBuffer</code>).</p>
|
|
<p><em>Read spreadsheet bytes from a local file and extract data</em></p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> <span class="pl-s1">workbook</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-en">readFile</span><span class="pl-kos">(</span><span class="pl-s1">filename</span><span class="pl-kos">,</span> <span class="pl-s1">opts</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>The <code>readFile</code> method attempts to read a spreadsheet file at the supplied path.
|
|
Browsers generally do not allow reading files in this way (it is deemed a
|
|
security risk), and attempts to read files in this way will throw an error.</p>
|
|
<p>The second <code>opts</code> argument is optional. <a href="#parsing-options">"Parsing Options"</a>
|
|
covers the supported properties and behaviors.</p>
|
|
<p><strong>Examples</strong></p>
|
|
<p>Here are a few common scenarios (click on each subtitle to see the code):</p>
|
|
<details>
|
|
<summary><b>Local file in a NodeJS server</b> (click to show)</summary>
|
|
<p><code>readFile</code> uses <code>fs.readFileSync</code> under the hood:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> <span class="pl-c1">XLSX</span> <span class="pl-c1">=</span> <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">"xlsx"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-k">var</span> <span class="pl-s1">workbook</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-en">readFile</span><span class="pl-kos">(</span><span class="pl-s">"test.xlsx"</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>For Node ESM, the <code>readFile</code> helper is not enabled. Instead, <code>fs.readFileSync</code>
|
|
should be used to read the file data as a <code>Buffer</code> for use with <code>XLSX.read</code>:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">import</span> <span class="pl-kos">{</span> <span class="pl-s1">readFileSync</span> <span class="pl-kos">}</span> <span class="pl-k">from</span> <span class="pl-s">"fs"</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">import</span> <span class="pl-kos">{</span> <span class="pl-s1">read</span> <span class="pl-kos">}</span> <span class="pl-k">from</span> <span class="pl-s">"xlsx/xlsx.mjs"</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-k">const</span> <span class="pl-s1">buf</span> <span class="pl-c1">=</span> <span class="pl-en">readFileSync</span><span class="pl-kos">(</span><span class="pl-s">"test.xlsx"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-c">/* buf is a Buffer */</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">workbook</span> <span class="pl-c1">=</span> <span class="pl-en">read</span><span class="pl-kos">(</span><span class="pl-s1">buf</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
</details>
|
|
<details>
|
|
<summary><b>Local file in a Deno application</b> (click to show)</summary>
|
|
<p><code>readFile</code> uses <code>Deno.readFileSync</code> under the hood:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-c">// <span class="pl-k">@deno</span>-types="https://deno.land/x/sheetjs/types/index.d.ts"</span>
|
|
<span class="pl-k">import</span> <span class="pl-c1">*</span> <span class="pl-k">as</span> <span class="pl-c1">XLSX</span> <span class="pl-k">from</span> <span class="pl-s">'https://deno.land/x/sheetjs/xlsx.mjs'</span>
|
|
|
|
<span class="pl-k">const</span> <span class="pl-s1">workbook</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-en">readFile</span><span class="pl-kos">(</span><span class="pl-s">"test.xlsx"</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>Applications reading files must be invoked with the <code>--allow-read</code> flag. The
|
|
<a href="https://github.com/SheetJS/SheetJS/tree/master/demos/deno/"><code>deno</code> demo</a> has more examples</p>
|
|
</details>
|
|
<details>
|
|
<summary><b>User-submitted file in a web page ("Drag-and-Drop")</b> (click to show)</summary>
|
|
<p>For modern websites targeting Chrome 76+, <code>File#arrayBuffer</code> is recommended:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-c">// XLSX is a global from the standalone script</span>
|
|
|
|
<span class="pl-k">async</span> <span class="pl-k">function</span> <span class="pl-en">handleDropAsync</span><span class="pl-kos">(</span><span class="pl-s1">e</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
|
|
<span class="pl-s1">e</span><span class="pl-kos">.</span><span class="pl-en">stopPropagation</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-s1">e</span><span class="pl-kos">.</span><span class="pl-en">preventDefault</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">f</span> <span class="pl-c1">=</span> <span class="pl-s1">e</span><span class="pl-kos">.</span><span class="pl-c1">dataTransfer</span><span class="pl-kos">.</span><span class="pl-c1">files</span><span class="pl-kos">[</span><span class="pl-c1">0</span><span class="pl-kos">]</span><span class="pl-kos">;</span>
|
|
<span class="pl-c">/* f is a File */</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">data</span> <span class="pl-c1">=</span> <span class="pl-k">await</span> <span class="pl-s1">f</span><span class="pl-kos">.</span><span class="pl-en">arrayBuffer</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-c">/* data is an ArrayBuffer */</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">workbook</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-en">read</span><span class="pl-kos">(</span><span class="pl-s1">data</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* DO SOMETHING WITH workbook HERE */</span>
|
|
<span class="pl-kos">}</span>
|
|
<span class="pl-s1">drop_dom_element</span><span class="pl-kos">.</span><span class="pl-en">addEventListener</span><span class="pl-kos">(</span><span class="pl-s">"drop"</span><span class="pl-kos">,</span> <span class="pl-s1">handleDropAsync</span><span class="pl-kos">,</span> <span class="pl-c1">false</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>For maximal compatibility, the <code>FileReader</code> API should be used:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">function</span> <span class="pl-en">handleDrop</span><span class="pl-kos">(</span><span class="pl-s1">e</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
|
|
<span class="pl-s1">e</span><span class="pl-kos">.</span><span class="pl-en">stopPropagation</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-s1">e</span><span class="pl-kos">.</span><span class="pl-en">preventDefault</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">f</span> <span class="pl-c1">=</span> <span class="pl-s1">e</span><span class="pl-kos">.</span><span class="pl-c1">dataTransfer</span><span class="pl-kos">.</span><span class="pl-c1">files</span><span class="pl-kos">[</span><span class="pl-c1">0</span><span class="pl-kos">]</span><span class="pl-kos">;</span>
|
|
<span class="pl-c">/* f is a File */</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">reader</span> <span class="pl-c1">=</span> <span class="pl-k">new</span> <span class="pl-v">FileReader</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-s1">reader</span><span class="pl-kos">.</span><span class="pl-en">onload</span> <span class="pl-c1">=</span> <span class="pl-k">function</span><span class="pl-kos">(</span><span class="pl-s1">e</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">data</span> <span class="pl-c1">=</span> <span class="pl-s1">e</span><span class="pl-kos">.</span><span class="pl-c1">target</span><span class="pl-kos">.</span><span class="pl-c1">result</span><span class="pl-kos">;</span>
|
|
<span class="pl-c">/* reader.readAsArrayBuffer(file) -> data will be an ArrayBuffer */</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">workbook</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-en">read</span><span class="pl-kos">(</span><span class="pl-s1">data</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* DO SOMETHING WITH workbook HERE */</span>
|
|
<span class="pl-kos">}</span><span class="pl-kos">;</span>
|
|
<span class="pl-s1">reader</span><span class="pl-kos">.</span><span class="pl-en">readAsArrayBuffer</span><span class="pl-kos">(</span><span class="pl-s1">f</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-kos">}</span>
|
|
<span class="pl-s1">drop_dom_element</span><span class="pl-kos">.</span><span class="pl-en">addEventListener</span><span class="pl-kos">(</span><span class="pl-s">"drop"</span><span class="pl-kos">,</span> <span class="pl-s1">handleDrop</span><span class="pl-kos">,</span> <span class="pl-c1">false</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p><a href="https://oss.sheetjs.com/sheetjs/" rel="nofollow">https://oss.sheetjs.com/sheetjs/</a> demonstrates the FileReader technique.</p>
|
|
</details>
|
|
<details>
|
|
<summary><b>User-submitted file with an HTML INPUT element</b> (click to show)</summary>
|
|
<p>Starting with an HTML INPUT element with <code>type="file"</code>:</p>
|
|
<div class="highlight highlight-text-html-basic"><pre><span class="pl-kos"><</span><span class="pl-ent">input</span> <span class="pl-c1">type</span>="<span class="pl-s">file</span>" <span class="pl-c1">id</span>="<span class="pl-s">input_dom_element</span>"<span class="pl-kos">></span></pre></div>
|
|
<p>For modern websites targeting Chrome 76+, <code>Blob#arrayBuffer</code> is recommended:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-c">// XLSX is a global from the standalone script</span>
|
|
|
|
<span class="pl-k">async</span> <span class="pl-k">function</span> <span class="pl-en">handleFileAsync</span><span class="pl-kos">(</span><span class="pl-s1">e</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">file</span> <span class="pl-c1">=</span> <span class="pl-s1">e</span><span class="pl-kos">.</span><span class="pl-c1">target</span><span class="pl-kos">.</span><span class="pl-c1">files</span><span class="pl-kos">[</span><span class="pl-c1">0</span><span class="pl-kos">]</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">data</span> <span class="pl-c1">=</span> <span class="pl-k">await</span> <span class="pl-s1">file</span><span class="pl-kos">.</span><span class="pl-en">arrayBuffer</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-c">/* data is an ArrayBuffer */</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">workbook</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-en">read</span><span class="pl-kos">(</span><span class="pl-s1">data</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* DO SOMETHING WITH workbook HERE */</span>
|
|
<span class="pl-kos">}</span>
|
|
<span class="pl-s1">input_dom_element</span><span class="pl-kos">.</span><span class="pl-en">addEventListener</span><span class="pl-kos">(</span><span class="pl-s">"change"</span><span class="pl-kos">,</span> <span class="pl-s1">handleFileAsync</span><span class="pl-kos">,</span> <span class="pl-c1">false</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>For broader support (including IE10+), the <code>FileReader</code> approach is recommended:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">function</span> <span class="pl-en">handleFile</span><span class="pl-kos">(</span><span class="pl-s1">e</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">file</span> <span class="pl-c1">=</span> <span class="pl-s1">e</span><span class="pl-kos">.</span><span class="pl-c1">target</span><span class="pl-kos">.</span><span class="pl-c1">files</span><span class="pl-kos">[</span><span class="pl-c1">0</span><span class="pl-kos">]</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">reader</span> <span class="pl-c1">=</span> <span class="pl-k">new</span> <span class="pl-v">FileReader</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-s1">reader</span><span class="pl-kos">.</span><span class="pl-en">onload</span> <span class="pl-c1">=</span> <span class="pl-k">function</span><span class="pl-kos">(</span><span class="pl-s1">e</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">data</span> <span class="pl-c1">=</span> <span class="pl-s1">e</span><span class="pl-kos">.</span><span class="pl-c1">target</span><span class="pl-kos">.</span><span class="pl-c1">result</span><span class="pl-kos">;</span>
|
|
<span class="pl-c">/* reader.readAsArrayBuffer(file) -> data will be an ArrayBuffer */</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">workbook</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-en">read</span><span class="pl-kos">(</span><span class="pl-s1">e</span><span class="pl-kos">.</span><span class="pl-c1">target</span><span class="pl-kos">.</span><span class="pl-c1">result</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* DO SOMETHING WITH workbook HERE */</span>
|
|
<span class="pl-kos">}</span><span class="pl-kos">;</span>
|
|
<span class="pl-s1">reader</span><span class="pl-kos">.</span><span class="pl-en">readAsArrayBuffer</span><span class="pl-kos">(</span><span class="pl-s1">file</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-kos">}</span>
|
|
<span class="pl-s1">input_dom_element</span><span class="pl-kos">.</span><span class="pl-en">addEventListener</span><span class="pl-kos">(</span><span class="pl-s">"change"</span><span class="pl-kos">,</span> <span class="pl-s1">handleFile</span><span class="pl-kos">,</span> <span class="pl-c1">false</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>The <a href="https://github.com/SheetJS/SheetJS/tree/master/demos/oldie/"><code>oldie</code> demo</a> shows an IE-compatible fallback scenario.</p>
|
|
</details>
|
|
<details>
|
|
<summary><b>Fetching a file in the web browser ("Ajax")</b> (click to show)</summary>
|
|
<p>For modern websites targeting Chrome 42+, <code>fetch</code> is recommended:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-c">// XLSX is a global from the standalone script</span>
|
|
|
|
<span class="pl-kos">(</span><span class="pl-k">async</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c1">=></span> <span class="pl-kos">{</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">url</span> <span class="pl-c1">=</span> <span class="pl-s">"http://oss.sheetjs.com/test_files/formula_stress_test.xlsx"</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">data</span> <span class="pl-c1">=</span> <span class="pl-k">await</span> <span class="pl-kos">(</span><span class="pl-k">await</span> <span class="pl-en">fetch</span><span class="pl-kos">(</span><span class="pl-s1">url</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">arrayBuffer</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-c">/* data is an ArrayBuffer */</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">workbook</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-en">read</span><span class="pl-kos">(</span><span class="pl-s1">data</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* DO SOMETHING WITH workbook HERE */</span>
|
|
<span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>For broader support, the <code>XMLHttpRequest</code> approach is recommended:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> <span class="pl-s1">url</span> <span class="pl-c1">=</span> <span class="pl-s">"http://oss.sheetjs.com/test_files/formula_stress_test.xlsx"</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* set up async GET request */</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">req</span> <span class="pl-c1">=</span> <span class="pl-k">new</span> <span class="pl-v">XMLHttpRequest</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-s1">req</span><span class="pl-kos">.</span><span class="pl-en">open</span><span class="pl-kos">(</span><span class="pl-s">"GET"</span><span class="pl-kos">,</span> <span class="pl-s1">url</span><span class="pl-kos">,</span> <span class="pl-c1">true</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-s1">req</span><span class="pl-kos">.</span><span class="pl-c1">responseType</span> <span class="pl-c1">=</span> <span class="pl-s">"arraybuffer"</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-s1">req</span><span class="pl-kos">.</span><span class="pl-en">onload</span> <span class="pl-c1">=</span> <span class="pl-k">function</span><span class="pl-kos">(</span><span class="pl-s1">e</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">workbook</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-en">read</span><span class="pl-kos">(</span><span class="pl-s1">req</span><span class="pl-kos">.</span><span class="pl-c1">response</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* DO SOMETHING WITH workbook HERE */</span>
|
|
<span class="pl-kos">}</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-s1">req</span><span class="pl-kos">.</span><span class="pl-en">send</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>The <a href="https://github.com/SheetJS/SheetJS/tree/master/demos/xhr/"><code>xhr</code> demo</a> includes a longer discussion and more examples.</p>
|
|
<p><a href="http://oss.sheetjs.com/sheetjs/ajax.html" rel="nofollow">http://oss.sheetjs.com/sheetjs/ajax.html</a> shows fallback approaches for IE6+.</p>
|
|
</details>
|
|
<details>
|
|
<summary><b>Local file in a PhotoShop or InDesign plugin</b> (click to show)</summary>
|
|
<p><code>readFile</code> wraps the <code>File</code> logic in Photoshop and other ExtendScript targets.
|
|
The specified path should be an absolute path:</p>
|
|
<div class="highlight highlight-source-js"><pre>#<span class="pl-s1">include</span> <span class="pl-s">"xlsx.extendscript.js"</span>
|
|
|
|
<span class="pl-c">/* Read test.xlsx from the Documents folder */</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">workbook</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-en">readFile</span><span class="pl-kos">(</span><span class="pl-v">Folder</span><span class="pl-kos">.</span><span class="pl-c1">myDocuments</span> <span class="pl-c1">+</span> <span class="pl-s">"/test.xlsx"</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>The <a href="https://github.com/SheetJS/SheetJS/tree/master/demos/extendscript/"><code>extendscript</code> demo</a> includes a more complex example.</p>
|
|
</details>
|
|
<details>
|
|
<summary><b>Local file in an Electron app</b> (click to show)</summary>
|
|
<p><code>readFile</code> can be used in the renderer process:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-c">/* From the renderer process */</span>
|
|
<span class="pl-k">var</span> <span class="pl-c1">XLSX</span> <span class="pl-c1">=</span> <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">"xlsx"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-k">var</span> <span class="pl-s1">workbook</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-en">readFile</span><span class="pl-kos">(</span><span class="pl-s1">path</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>Electron APIs have changed over time. The <a href="https://github.com/SheetJS/SheetJS/tree/master/demos/electron/"><code>electron</code> demo</a>
|
|
shows a complete example and details the required version-specific settings.</p>
|
|
</details>
|
|
<details>
|
|
<summary><b>Local file in a mobile app with React Native</b> (click to show)</summary>
|
|
<p>The <a href="https://github.com/SheetJS/SheetJS/tree/master/demos/react"><code>react</code> demo</a> includes a sample React Native app.</p>
|
|
<p>Since React Native does not provide a way to read files from the filesystem, a
|
|
third-party library must be used. The following libraries have been tested:</p>
|
|
<ul>
|
|
<li><a href="https://npm.im/react-native-file-access" rel="nofollow"><code>react-native-file-access</code></a></li>
|
|
</ul>
|
|
<p>The <code>base64</code> encoding returns strings compatible with the <code>base64</code> type:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">import</span> <span class="pl-c1">XLSX</span> <span class="pl-k">from</span> <span class="pl-s">"xlsx"</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">import</span> <span class="pl-kos">{</span> <span class="pl-v">FileSystem</span> <span class="pl-kos">}</span> <span class="pl-k">from</span> <span class="pl-s">"react-native-file-access"</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-k">const</span> <span class="pl-s1">b64</span> <span class="pl-c1">=</span> <span class="pl-k">await</span> <span class="pl-v">FileSystem</span><span class="pl-kos">.</span><span class="pl-en">readFile</span><span class="pl-kos">(</span><span class="pl-s1">path</span><span class="pl-kos">,</span> <span class="pl-s">"base64"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-c">/* b64 is a base64 string */</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">workbook</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-en">read</span><span class="pl-kos">(</span><span class="pl-s1">b64</span><span class="pl-kos">,</span> <span class="pl-kos">{</span><span class="pl-c1">type</span>: <span class="pl-s">"base64"</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<ul>
|
|
<li><a href="https://npm.im/react-native-fs" rel="nofollow"><code>react-native-fs</code></a></li>
|
|
</ul>
|
|
<p>The <code>ascii</code> encoding returns binary strings compatible with the <code>binary</code> type:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">import</span> <span class="pl-c1">XLSX</span> <span class="pl-k">from</span> <span class="pl-s">"xlsx"</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">import</span> <span class="pl-kos">{</span> <span class="pl-s1">readFile</span> <span class="pl-kos">}</span> <span class="pl-k">from</span> <span class="pl-s">"react-native-fs"</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-k">const</span> <span class="pl-s1">bstr</span> <span class="pl-c1">=</span> <span class="pl-k">await</span> <span class="pl-en">readFile</span><span class="pl-kos">(</span><span class="pl-s1">path</span><span class="pl-kos">,</span> <span class="pl-s">"ascii"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-c">/* bstr is a binary string */</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">workbook</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-en">read</span><span class="pl-kos">(</span><span class="pl-s1">bstr</span><span class="pl-kos">,</span> <span class="pl-kos">{</span><span class="pl-c1">type</span>: <span class="pl-s">"binary"</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
</details>
|
|
<details>
|
|
<summary><b>NodeJS Server File Uploads</b> (click to show)</summary>
|
|
<p><code>read</code> can accept a NodeJS buffer. <code>readFile</code> can read files generated by a
|
|
HTTP POST request body parser like <a href="https://npm.im/formidable" rel="nofollow"><code>formidable</code></a>:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">const</span> <span class="pl-c1">XLSX</span> <span class="pl-c1">=</span> <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">"xlsx"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">http</span> <span class="pl-c1">=</span> <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">"http"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">formidable</span> <span class="pl-c1">=</span> <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">"formidable"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-k">const</span> <span class="pl-s1">server</span> <span class="pl-c1">=</span> <span class="pl-s1">http</span><span class="pl-kos">.</span><span class="pl-en">createServer</span><span class="pl-kos">(</span><span class="pl-kos">(</span><span class="pl-s1">req</span><span class="pl-kos">,</span> <span class="pl-s1">res</span><span class="pl-kos">)</span> <span class="pl-c1">=></span> <span class="pl-kos">{</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">form</span> <span class="pl-c1">=</span> <span class="pl-k">new</span> <span class="pl-s1">formidable</span><span class="pl-kos">.</span><span class="pl-c1">IncomingForm</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-s1">form</span><span class="pl-kos">.</span><span class="pl-en">parse</span><span class="pl-kos">(</span><span class="pl-s1">req</span><span class="pl-kos">,</span> <span class="pl-kos">(</span><span class="pl-s1">err</span><span class="pl-kos">,</span> <span class="pl-s1">fields</span><span class="pl-kos">,</span> <span class="pl-s1">files</span><span class="pl-kos">)</span> <span class="pl-c1">=></span> <span class="pl-kos">{</span>
|
|
<span class="pl-c">/* grab the first file */</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">f</span> <span class="pl-c1">=</span> <span class="pl-v">Object</span><span class="pl-kos">.</span><span class="pl-en">entries</span><span class="pl-kos">(</span><span class="pl-s1">files</span><span class="pl-kos">)</span><span class="pl-kos">[</span><span class="pl-c1">0</span><span class="pl-kos">]</span><span class="pl-kos">[</span><span class="pl-c1">1</span><span class="pl-kos">]</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">path</span> <span class="pl-c1">=</span> <span class="pl-s1">f</span><span class="pl-kos">.</span><span class="pl-c1">filepath</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">workbook</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-en">readFile</span><span class="pl-kos">(</span><span class="pl-s1">path</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* DO SOMETHING WITH workbook HERE */</span>
|
|
<span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">listen</span><span class="pl-kos">(</span><span class="pl-s1">process</span><span class="pl-kos">.</span><span class="pl-c1">env</span><span class="pl-kos">.</span><span class="pl-c1">PORT</span> <span class="pl-c1">||</span> <span class="pl-c1">7262</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>The <a href="https://github.com/SheetJS/SheetJS/tree/master/demos/server"><code>server</code> demo</a> has more advanced examples.</p>
|
|
</details>
|
|
<details>
|
|
<summary><b>Download files in a NodeJS process</b> (click to show)</summary>
|
|
<p>Node 17.5 and 18.0 have native support for fetch:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">const</span> <span class="pl-c1">XLSX</span> <span class="pl-c1">=</span> <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">"xlsx"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-k">const</span> <span class="pl-s1">data</span> <span class="pl-c1">=</span> <span class="pl-k">await</span> <span class="pl-kos">(</span><span class="pl-k">await</span> <span class="pl-en">fetch</span><span class="pl-kos">(</span><span class="pl-s1">url</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">arrayBuffer</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-c">/* data is an ArrayBuffer */</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">workbook</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-en">read</span><span class="pl-kos">(</span><span class="pl-s1">data</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>For broader compatibility, third-party modules are recommended.</p>
|
|
<p><a href="https://npm.im/request" rel="nofollow"><code>request</code></a> requires a <code>null</code> encoding to yield Buffers:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> <span class="pl-c1">XLSX</span> <span class="pl-c1">=</span> <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">"xlsx"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">request</span> <span class="pl-c1">=</span> <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">"request"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-s1">request</span><span class="pl-kos">(</span><span class="pl-kos">{</span><span class="pl-c1">url</span>: <span class="pl-s1">url</span><span class="pl-kos">,</span> <span class="pl-c1">encoding</span>: <span class="pl-c1">null</span><span class="pl-kos">}</span><span class="pl-kos">,</span> <span class="pl-k">function</span><span class="pl-kos">(</span><span class="pl-s1">err</span><span class="pl-kos">,</span> <span class="pl-s1">resp</span><span class="pl-kos">,</span> <span class="pl-s1">body</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">workbook</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-en">read</span><span class="pl-kos">(</span><span class="pl-s1">body</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* DO SOMETHING WITH workbook HERE */</span>
|
|
<span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p><a href="https://npm.im/axios" rel="nofollow"><code>axios</code></a> works the same way in browser and in NodeJS:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">const</span> <span class="pl-c1">XLSX</span> <span class="pl-c1">=</span> <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">"xlsx"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">axios</span> <span class="pl-c1">=</span> <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">"axios"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-kos">(</span><span class="pl-k">async</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c1">=></span> <span class="pl-kos">{</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">res</span> <span class="pl-c1">=</span> <span class="pl-k">await</span> <span class="pl-s1">axios</span><span class="pl-kos">.</span><span class="pl-en">get</span><span class="pl-kos">(</span><span class="pl-s1">url</span><span class="pl-kos">,</span> <span class="pl-kos">{</span><span class="pl-c1">responseType</span>: <span class="pl-s">"arraybuffer"</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-c">/* res.data is a Buffer */</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">workbook</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-en">read</span><span class="pl-kos">(</span><span class="pl-s1">res</span><span class="pl-kos">.</span><span class="pl-c1">data</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* DO SOMETHING WITH workbook HERE */</span>
|
|
<span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
</details>
|
|
<details>
|
|
<summary><b>Download files in an Electron app</b> (click to show)</summary>
|
|
<p>The <code>net</code> module in the main process can make HTTP/HTTPS requests to external
|
|
resources. Responses should be manually concatenated using <code>Buffer.concat</code>:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">const</span> <span class="pl-c1">XLSX</span> <span class="pl-c1">=</span> <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">"xlsx"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">const</span> <span class="pl-kos">{</span> net <span class="pl-kos">}</span> <span class="pl-c1">=</span> <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">"electron"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-k">const</span> <span class="pl-s1">req</span> <span class="pl-c1">=</span> <span class="pl-s1">net</span><span class="pl-kos">.</span><span class="pl-en">request</span><span class="pl-kos">(</span><span class="pl-s1">url</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-s1">req</span><span class="pl-kos">.</span><span class="pl-en">on</span><span class="pl-kos">(</span><span class="pl-s">"response"</span><span class="pl-kos">,</span> <span class="pl-kos">(</span><span class="pl-s1">res</span><span class="pl-kos">)</span> <span class="pl-c1">=></span> <span class="pl-kos">{</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">bufs</span> <span class="pl-c1">=</span> <span class="pl-kos">[</span><span class="pl-kos">]</span><span class="pl-kos">;</span> <span class="pl-c">// this array will collect all of the buffers</span>
|
|
<span class="pl-s1">res</span><span class="pl-kos">.</span><span class="pl-en">on</span><span class="pl-kos">(</span><span class="pl-s">"data"</span><span class="pl-kos">,</span> <span class="pl-kos">(</span><span class="pl-s1">chunk</span><span class="pl-kos">)</span> <span class="pl-c1">=></span> <span class="pl-kos">{</span> <span class="pl-s1">bufs</span><span class="pl-kos">.</span><span class="pl-en">push</span><span class="pl-kos">(</span><span class="pl-s1">chunk</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-s1">res</span><span class="pl-kos">.</span><span class="pl-en">on</span><span class="pl-kos">(</span><span class="pl-s">"end"</span><span class="pl-kos">,</span> <span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c1">=></span> <span class="pl-kos">{</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">workbook</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-en">read</span><span class="pl-kos">(</span><span class="pl-v">Buffer</span><span class="pl-kos">.</span><span class="pl-en">concat</span><span class="pl-kos">(</span><span class="pl-s1">bufs</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* DO SOMETHING WITH workbook HERE */</span>
|
|
<span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-s1">req</span><span class="pl-kos">.</span><span class="pl-en">end</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
</details>
|
|
<details>
|
|
<summary><b>Readable Streams in NodeJS</b> (click to show)</summary>
|
|
<p>When dealing with Readable Streams, the easiest approach is to buffer the stream
|
|
and process the whole thing at the end:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> <span class="pl-s1">fs</span> <span class="pl-c1">=</span> <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">"fs"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">var</span> <span class="pl-c1">XLSX</span> <span class="pl-c1">=</span> <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">"xlsx"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-k">function</span> <span class="pl-en">process_RS</span><span class="pl-kos">(</span><span class="pl-s1">stream</span><span class="pl-kos">,</span> <span class="pl-s1">cb</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">buffers</span> <span class="pl-c1">=</span> <span class="pl-kos">[</span><span class="pl-kos">]</span><span class="pl-kos">;</span>
|
|
<span class="pl-s1">stream</span><span class="pl-kos">.</span><span class="pl-en">on</span><span class="pl-kos">(</span><span class="pl-s">"data"</span><span class="pl-kos">,</span> <span class="pl-k">function</span><span class="pl-kos">(</span><span class="pl-s1">data</span><span class="pl-kos">)</span> <span class="pl-kos">{</span> <span class="pl-s1">buffers</span><span class="pl-kos">.</span><span class="pl-en">push</span><span class="pl-kos">(</span><span class="pl-s1">data</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-s1">stream</span><span class="pl-kos">.</span><span class="pl-en">on</span><span class="pl-kos">(</span><span class="pl-s">"end"</span><span class="pl-kos">,</span> <span class="pl-k">function</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">buffer</span> <span class="pl-c1">=</span> <span class="pl-v">Buffer</span><span class="pl-kos">.</span><span class="pl-en">concat</span><span class="pl-kos">(</span><span class="pl-s1">buffers</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">workbook</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-en">read</span><span class="pl-kos">(</span><span class="pl-s1">buffer</span><span class="pl-kos">,</span> <span class="pl-kos">{</span><span class="pl-c1">type</span>:<span class="pl-s">"buffer"</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* DO SOMETHING WITH workbook IN THE CALLBACK */</span>
|
|
<span class="pl-s1">cb</span><span class="pl-kos">(</span><span class="pl-s1">workbook</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-kos">}</span></pre></div>
|
|
</details>
|
|
<details>
|
|
<summary><b>ReadableStream in the browser</b> (click to show)</summary>
|
|
<p>When dealing with <code>ReadableStream</code>, the easiest approach is to buffer the stream
|
|
and process the whole thing at the end:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-c">// XLSX is a global from the standalone script</span>
|
|
|
|
<span class="pl-k">async</span> <span class="pl-k">function</span> <span class="pl-en">process_RS</span><span class="pl-kos">(</span><span class="pl-s1">stream</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
|
|
<span class="pl-c">/* collect data */</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">buffers</span> <span class="pl-c1">=</span> <span class="pl-kos">[</span><span class="pl-kos">]</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">reader</span> <span class="pl-c1">=</span> <span class="pl-s1">stream</span><span class="pl-kos">.</span><span class="pl-en">getReader</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">for</span><span class="pl-kos">(</span><span class="pl-kos">;</span><span class="pl-kos">;</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">res</span> <span class="pl-c1">=</span> <span class="pl-k">await</span> <span class="pl-s1">reader</span><span class="pl-kos">.</span><span class="pl-en">read</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">if</span><span class="pl-kos">(</span><span class="pl-s1">res</span><span class="pl-kos">.</span><span class="pl-c1">value</span><span class="pl-kos">)</span> <span class="pl-s1">buffers</span><span class="pl-kos">.</span><span class="pl-en">push</span><span class="pl-kos">(</span><span class="pl-s1">res</span><span class="pl-kos">.</span><span class="pl-c1">value</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">if</span><span class="pl-kos">(</span><span class="pl-s1">res</span><span class="pl-kos">.</span><span class="pl-c1">done</span><span class="pl-kos">)</span> <span class="pl-k">break</span><span class="pl-kos">;</span>
|
|
<span class="pl-kos">}</span>
|
|
|
|
<span class="pl-c">/* concat */</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">out</span> <span class="pl-c1">=</span> <span class="pl-k">new</span> <span class="pl-v">Uint8Array</span><span class="pl-kos">(</span><span class="pl-s1">buffers</span><span class="pl-kos">.</span><span class="pl-en">reduce</span><span class="pl-kos">(</span><span class="pl-kos">(</span><span class="pl-s1">acc</span><span class="pl-kos">,</span> <span class="pl-s1">v</span><span class="pl-kos">)</span> <span class="pl-c1">=></span> <span class="pl-s1">acc</span> <span class="pl-c1">+</span> <span class="pl-s1">v</span><span class="pl-kos">.</span><span class="pl-c1">length</span><span class="pl-kos">,</span> <span class="pl-c1">0</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-k">let</span> <span class="pl-s1">off</span> <span class="pl-c1">=</span> <span class="pl-c1">0</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">for</span><span class="pl-kos">(</span><span class="pl-k">const</span> <span class="pl-s1">u8</span> <span class="pl-k">of</span> <span class="pl-s1">buffers</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
|
|
<span class="pl-s1">out</span><span class="pl-kos">.</span><span class="pl-en">set</span><span class="pl-kos">(</span><span class="pl-s1">u8</span><span class="pl-kos">,</span> <span class="pl-s1">off</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-s1">off</span> <span class="pl-c1">+=</span> <span class="pl-s1">u8</span><span class="pl-kos">.</span><span class="pl-c1">length</span><span class="pl-kos">;</span>
|
|
<span class="pl-kos">}</span>
|
|
|
|
<span class="pl-k">return</span> <span class="pl-s1">out</span><span class="pl-kos">;</span>
|
|
<span class="pl-kos">}</span>
|
|
|
|
<span class="pl-k">const</span> <span class="pl-s1">data</span> <span class="pl-c1">=</span> <span class="pl-k">await</span> <span class="pl-en">process_RS</span><span class="pl-kos">(</span><span class="pl-s1">stream</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-c">/* data is Uint8Array */</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">workbook</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-en">read</span><span class="pl-kos">(</span><span class="pl-s1">data</span><span class="pl-kos">,</span> <span class="pl-kos">{</span><span class="pl-c1">type</span>: <span class="pl-s">'array'</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
</details>
|
|
<p>More detailed examples are covered in the <a href="https://github.com/SheetJS/SheetJS/tree/master/demos/">included demos</a></p>
|
|
<h3>
|
|
<a id="user-content-processing-json-and-js-data" class="anchor" href="#processing-json-and-js-data" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Processing JSON and JS Data</h3>
|
|
<p>JSON and JS data tend to represent single worksheets. This section will use a
|
|
few utility functions to generate workbooks.</p>
|
|
<p><em>Create a new Workbook</em></p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> <span class="pl-s1">workbook</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">book_new</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>The <code>book_new</code> utility function creates an empty workbook with no worksheets.</p>
|
|
<p>Spreadsheet software generally require at least one worksheet and enforce the
|
|
requirement in the user interface. This library enforces the requirement at
|
|
write time, throwing errors if an empty workbook is passed to write functions.</p>
|
|
<p><strong>API</strong></p>
|
|
<p><em>Create a worksheet from an array of arrays of JS values</em></p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> <span class="pl-s1">worksheet</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">aoa_to_sheet</span><span class="pl-kos">(</span><span class="pl-s1">aoa</span><span class="pl-kos">,</span> <span class="pl-s1">opts</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>The <code>aoa_to_sheet</code> utility function walks an "array of arrays" in row-major
|
|
order, generating a worksheet object. The following snippet generates a sheet
|
|
with cell <code>A1</code> set to the string <code>A1</code>, cell <code>B1</code> set to <code>B1</code>, etc:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> <span class="pl-s1">worksheet</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">aoa_to_sheet</span><span class="pl-kos">(</span><span class="pl-kos">[</span>
|
|
<span class="pl-kos">[</span><span class="pl-s">"A1"</span><span class="pl-kos">,</span> <span class="pl-s">"B1"</span><span class="pl-kos">,</span> <span class="pl-s">"C1"</span><span class="pl-kos">]</span><span class="pl-kos">,</span>
|
|
<span class="pl-kos">[</span><span class="pl-s">"A2"</span><span class="pl-kos">,</span> <span class="pl-s">"B2"</span><span class="pl-kos">,</span> <span class="pl-s">"C2"</span><span class="pl-kos">]</span><span class="pl-kos">,</span>
|
|
<span class="pl-kos">[</span><span class="pl-s">"A3"</span><span class="pl-kos">,</span> <span class="pl-s">"B3"</span><span class="pl-kos">,</span> <span class="pl-s">"C3"</span><span class="pl-kos">]</span>
|
|
<span class="pl-kos">]</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p><a href="#array-of-arrays-input">"Array of Arrays Input"</a> describes the function and the
|
|
optional <code>opts</code> argument in more detail.</p>
|
|
<p><em>Create a worksheet from an array of JS objects</em></p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> <span class="pl-s1">worksheet</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">json_to_sheet</span><span class="pl-kos">(</span><span class="pl-s1">jsa</span><span class="pl-kos">,</span> <span class="pl-s1">opts</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>The <code>json_to_sheet</code> utility function walks an array of JS objects in order,
|
|
generating a worksheet object. By default, it will generate a header row and
|
|
one row per object in the array. The optional <code>opts</code> argument has settings to
|
|
control the column order and header output.</p>
|
|
<p><a href="#array-of-objects-input">"Array of Objects Input"</a> describes the function and
|
|
the optional <code>opts</code> argument in more detail.</p>
|
|
<p><strong>Examples</strong></p>
|
|
<p><a href="#the-zen-of-sheetjs">"Zen of SheetJS"</a> contains a detailed example "Get Data
|
|
from a JSON Endpoint and Generate a Workbook"</p>
|
|
<p><a href="https://github.com/myliang/x-spreadsheet"><code>x-spreadsheet</code></a> is an interactive
|
|
data grid for previewing and modifying structured data in the web browser. The
|
|
<a href="/demos/xspreadsheet"><code>xspreadsheet</code> demo</a> includes a sample script with the
|
|
<code>xtos</code> function for converting from x-spreadsheet data object to a workbook.
|
|
<a href="https://oss.sheetjs.com/sheetjs/x-spreadsheet" rel="nofollow">https://oss.sheetjs.com/sheetjs/x-spreadsheet</a> is a live demo.</p>
|
|
<details>
|
|
<summary><b>Records from a database query (SQL or no-SQL)</b> (click to show)</summary>
|
|
<p>The <a href="/demos/database/"><code>database</code> demo</a> includes examples of working with
|
|
databases and query results.</p>
|
|
</details>
|
|
<details>
|
|
<summary><b>Numerical Computations with TensorFlow.js</b> (click to show)</summary>
|
|
<p><a href="@tensorflow/tfjs"><code>@tensorflow/tfjs</code></a> and other libraries expect data in simple
|
|
arrays, well-suited for worksheets where each column is a data vector. That is
|
|
the transpose of how most people use spreadsheets, where each row is a vector.</p>
|
|
<p>When recovering data from <code>tfjs</code>, the returned data points are stored in a typed
|
|
array. An array of arrays can be constructed with loops. <code>Array#unshift</code> can
|
|
prepend a title row before the conversion:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">const</span> <span class="pl-c1">XLSX</span> <span class="pl-c1">=</span> <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">"xlsx"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">tf</span> <span class="pl-c1">=</span> <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">'@tensorflow/tfjs'</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* suppose xs and ys are vectors (1D tensors) -> tfarr will be a typed array */</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">tfdata</span> <span class="pl-c1">=</span> <span class="pl-s1">tf</span><span class="pl-kos">.</span><span class="pl-en">stack</span><span class="pl-kos">(</span><span class="pl-kos">[</span><span class="pl-s1">xs</span><span class="pl-kos">,</span> <span class="pl-s1">ys</span><span class="pl-kos">]</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">transpose</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">shape</span> <span class="pl-c1">=</span> <span class="pl-s1">tfdata</span><span class="pl-kos">.</span><span class="pl-c1">shape</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">tfarr</span> <span class="pl-c1">=</span> <span class="pl-s1">tfdata</span><span class="pl-kos">.</span><span class="pl-en">dataSync</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* construct the array of arrays */</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">aoa</span> <span class="pl-c1">=</span> <span class="pl-kos">[</span><span class="pl-kos">]</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">for</span><span class="pl-kos">(</span><span class="pl-k">let</span> <span class="pl-s1">j</span> <span class="pl-c1">=</span> <span class="pl-c1">0</span><span class="pl-kos">;</span> <span class="pl-s1">j</span> <span class="pl-c1"><</span> <span class="pl-s1">shape</span><span class="pl-kos">[</span><span class="pl-c1">0</span><span class="pl-kos">]</span><span class="pl-kos">;</span> <span class="pl-c1">++</span><span class="pl-s1">j</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
|
|
<span class="pl-s1">aoa</span><span class="pl-kos">[</span><span class="pl-s1">j</span><span class="pl-kos">]</span> <span class="pl-c1">=</span> <span class="pl-kos">[</span><span class="pl-kos">]</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">for</span><span class="pl-kos">(</span><span class="pl-k">let</span> <span class="pl-s1">i</span> <span class="pl-c1">=</span> <span class="pl-c1">0</span><span class="pl-kos">;</span> <span class="pl-s1">i</span> <span class="pl-c1"><</span> <span class="pl-s1">shape</span><span class="pl-kos">[</span><span class="pl-c1">1</span><span class="pl-kos">]</span><span class="pl-kos">;</span> <span class="pl-c1">++</span><span class="pl-s1">i</span><span class="pl-kos">)</span> <span class="pl-s1">aoa</span><span class="pl-kos">[</span><span class="pl-s1">j</span><span class="pl-kos">]</span><span class="pl-kos">[</span><span class="pl-s1">i</span><span class="pl-kos">]</span> <span class="pl-c1">=</span> <span class="pl-s1">tfarr</span><span class="pl-kos">[</span><span class="pl-s1">j</span> <span class="pl-c1">*</span> <span class="pl-s1">shape</span><span class="pl-kos">[</span><span class="pl-c1">1</span><span class="pl-kos">]</span> <span class="pl-c1">+</span> <span class="pl-s1">i</span><span class="pl-kos">]</span><span class="pl-kos">;</span>
|
|
<span class="pl-kos">}</span>
|
|
<span class="pl-c">/* add headers to the top */</span>
|
|
<span class="pl-s1">aoa</span><span class="pl-kos">.</span><span class="pl-en">unshift</span><span class="pl-kos">(</span><span class="pl-kos">[</span><span class="pl-s">"x"</span><span class="pl-kos">,</span> <span class="pl-s">"y"</span><span class="pl-kos">]</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* generate worksheet */</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">worksheet</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">aoa_to_sheet</span><span class="pl-kos">(</span><span class="pl-s1">aoa</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>The <a href="https://github.com/SheetJS/SheetJS/tree/master/demos/array/"><code>array</code> demo</a> shows a complete example.</p>
|
|
</details>
|
|
<h3>
|
|
<a id="user-content-processing-html-tables" class="anchor" href="#processing-html-tables" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Processing HTML Tables</h3>
|
|
<p><strong>API</strong></p>
|
|
<p><em>Create a worksheet by scraping an HTML TABLE in the page</em></p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> <span class="pl-s1">worksheet</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">table_to_sheet</span><span class="pl-kos">(</span><span class="pl-s1">dom_element</span><span class="pl-kos">,</span> <span class="pl-s1">opts</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>The <code>table_to_sheet</code> utility function takes a DOM TABLE element and iterates
|
|
through the rows to generate a worksheet. The <code>opts</code> argument is optional.
|
|
<a href="#html-table-input">"HTML Table Input"</a> describes the function in more detail.</p>
|
|
<p><em>Create a workbook by scraping an HTML TABLE in the page</em></p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> <span class="pl-s1">workbook</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">table_to_book</span><span class="pl-kos">(</span><span class="pl-s1">dom_element</span><span class="pl-kos">,</span> <span class="pl-s1">opts</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>The <code>table_to_book</code> utility function follows the same logic as <code>table_to_sheet</code>.
|
|
After generating a worksheet, it creates a blank workbook and appends the
|
|
spreadsheet.</p>
|
|
<p>The options argument supports the same options as <code>table_to_sheet</code>, with the
|
|
addition of a <code>sheet</code> property to control the worksheet name. If the property
|
|
is missing or no options are specified, the default name <code>Sheet1</code> is used.</p>
|
|
<p><strong>Examples</strong></p>
|
|
<p>Here are a few common scenarios (click on each subtitle to see the code):</p>
|
|
<details>
|
|
<summary><b>HTML TABLE element in a webpage</b> (click to show)</summary>
|
|
<div class="highlight highlight-text-html-basic"><pre><span class="pl-c"><!-- include the standalone script and shim. this uses the UNPKG CDN --></span>
|
|
<span class="pl-kos"><</span><span class="pl-ent">script</span> <span class="pl-c1">src</span>="<span class="pl-s">https://cdn.sheetjs.com/xlsx-latest/package/dist/shim.min.js</span>"<span class="pl-kos">></span><span class="pl-kos"></</span><span class="pl-ent">script</span><span class="pl-kos">></span>
|
|
<span class="pl-kos"><</span><span class="pl-ent">script</span> <span class="pl-c1">src</span>="<span class="pl-s">https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js</span>"<span class="pl-kos">></span><span class="pl-kos"></</span><span class="pl-ent">script</span><span class="pl-kos">></span>
|
|
|
|
<span class="pl-c"><!-- example table with id attribute --></span>
|
|
<span class="pl-kos"><</span><span class="pl-ent">table</span> <span class="pl-c1">id</span>="<span class="pl-s">tableau</span>"<span class="pl-kos">></span>
|
|
<span class="pl-kos"><</span><span class="pl-ent">tr</span><span class="pl-kos">></span><span class="pl-kos"><</span><span class="pl-ent">td</span><span class="pl-kos">></span>Sheet<span class="pl-kos"></</span><span class="pl-ent">td</span><span class="pl-kos">></span><span class="pl-kos"><</span><span class="pl-ent">td</span><span class="pl-kos">></span>JS<span class="pl-kos"></</span><span class="pl-ent">td</span><span class="pl-kos">></span><span class="pl-kos"></</span><span class="pl-ent">tr</span><span class="pl-kos">></span>
|
|
<span class="pl-kos"><</span><span class="pl-ent">tr</span><span class="pl-kos">></span><span class="pl-kos"><</span><span class="pl-ent">td</span><span class="pl-kos">></span>12345<span class="pl-kos"></</span><span class="pl-ent">td</span><span class="pl-kos">></span><span class="pl-kos"><</span><span class="pl-ent">td</span><span class="pl-kos">></span>67<span class="pl-kos"></</span><span class="pl-ent">td</span><span class="pl-kos">></span><span class="pl-kos"></</span><span class="pl-ent">tr</span><span class="pl-kos">></span>
|
|
<span class="pl-kos"></</span><span class="pl-ent">table</span><span class="pl-kos">></span>
|
|
|
|
<span class="pl-c"><!-- this block should appear after the table HTML and the standalone script --></span>
|
|
<span class="pl-kos"><</span><span class="pl-ent">script</span> <span class="pl-c1">type</span>="<span class="pl-s">text/javascript</span>"<span class="pl-kos">></span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">workbook</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">table_to_book</span><span class="pl-kos">(</span><span class="pl-smi">document</span><span class="pl-kos">.</span><span class="pl-en">getElementById</span><span class="pl-kos">(</span><span class="pl-s">"tableau"</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* DO SOMETHING WITH workbook HERE */</span>
|
|
<span class="pl-kos"></</span><span class="pl-ent">script</span><span class="pl-kos">></span></pre></div>
|
|
<p>Multiple tables on a web page can be converted to individual worksheets:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-c">/* create new workbook */</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">workbook</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">book_new</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* convert table "table1" to worksheet named "Sheet1" */</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">sheet1</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">table_to_sheet</span><span class="pl-kos">(</span><span class="pl-smi">document</span><span class="pl-kos">.</span><span class="pl-en">getElementById</span><span class="pl-kos">(</span><span class="pl-s">"table1"</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">book_append_sheet</span><span class="pl-kos">(</span><span class="pl-s1">workbook</span><span class="pl-kos">,</span> <span class="pl-s1">sheet1</span><span class="pl-kos">,</span> <span class="pl-s">"Sheet1"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* convert table "table2" to worksheet named "Sheet2" */</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">sheet2</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">table_to_sheet</span><span class="pl-kos">(</span><span class="pl-smi">document</span><span class="pl-kos">.</span><span class="pl-en">getElementById</span><span class="pl-kos">(</span><span class="pl-s">"table2"</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">book_append_sheet</span><span class="pl-kos">(</span><span class="pl-s1">workbook</span><span class="pl-kos">,</span> <span class="pl-s1">sheet2</span><span class="pl-kos">,</span> <span class="pl-s">"Sheet2"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* workbook now has 2 worksheets */</span></pre></div>
|
|
<p>Alternatively, the HTML code can be extracted and parsed:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> <span class="pl-s1">htmlstr</span> <span class="pl-c1">=</span> <span class="pl-smi">document</span><span class="pl-kos">.</span><span class="pl-en">getElementById</span><span class="pl-kos">(</span><span class="pl-s">"tableau"</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-c1">outerHTML</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">workbook</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-en">read</span><span class="pl-kos">(</span><span class="pl-s1">htmlstr</span><span class="pl-kos">,</span> <span class="pl-kos">{</span><span class="pl-c1">type</span>:<span class="pl-s">"string"</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
</details>
|
|
<details>
|
|
<summary><b>Chrome/Chromium Extension</b> (click to show)</summary>
|
|
<p>The <a href="https://github.com/SheetJS/SheetJS/tree/master/demos/chrome/"><code>chrome</code> demo</a> shows a complete example and details the
|
|
required permissions and other settings.</p>
|
|
<p>In an extension, it is recommended to generate the workbook in a content script
|
|
and pass the object back to the extension:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-c">/* in the worker script */</span>
|
|
<span class="pl-s1">chrome</span><span class="pl-kos">.</span><span class="pl-c1">runtime</span><span class="pl-kos">.</span><span class="pl-c1">onMessage</span><span class="pl-kos">.</span><span class="pl-en">addListener</span><span class="pl-kos">(</span><span class="pl-k">function</span><span class="pl-kos">(</span><span class="pl-s1">msg</span><span class="pl-kos">,</span> <span class="pl-s1">sender</span><span class="pl-kos">,</span> <span class="pl-s1">cb</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
|
|
<span class="pl-c">/* pass a message like { sheetjs: true } from the extension to scrape */</span>
|
|
<span class="pl-k">if</span><span class="pl-kos">(</span><span class="pl-c1">!</span><span class="pl-s1">msg</span> <span class="pl-c1">||</span> <span class="pl-c1">!</span><span class="pl-s1">msg</span><span class="pl-kos">.</span><span class="pl-c1">sheetjs</span><span class="pl-kos">)</span> <span class="pl-k">return</span><span class="pl-kos">;</span>
|
|
<span class="pl-c">/* create a new workbook */</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">workbook</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">book_new</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-c">/* loop through each table element */</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">tables</span> <span class="pl-c1">=</span> <span class="pl-smi">document</span><span class="pl-kos">.</span><span class="pl-en">getElementsByTagName</span><span class="pl-kos">(</span><span class="pl-s">"table"</span><span class="pl-kos">)</span>
|
|
<span class="pl-k">for</span><span class="pl-kos">(</span><span class="pl-k">var</span> <span class="pl-s1">i</span> <span class="pl-c1">=</span> <span class="pl-c1">0</span><span class="pl-kos">;</span> <span class="pl-s1">i</span> <span class="pl-c1"><</span> <span class="pl-s1">tables</span><span class="pl-kos">.</span><span class="pl-c1">length</span><span class="pl-kos">;</span> <span class="pl-c1">++</span><span class="pl-s1">i</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">worksheet</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">table_to_sheet</span><span class="pl-kos">(</span><span class="pl-s1">tables</span><span class="pl-kos">[</span><span class="pl-s1">i</span><span class="pl-kos">]</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">book_append_sheet</span><span class="pl-kos">(</span><span class="pl-s1">workbook</span><span class="pl-kos">,</span> <span class="pl-s1">worksheet</span><span class="pl-kos">,</span> <span class="pl-s">"Table"</span> <span class="pl-c1">+</span> <span class="pl-s1">i</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-kos">}</span>
|
|
<span class="pl-c">/* pass back to the extension */</span>
|
|
<span class="pl-k">return</span> <span class="pl-s1">cb</span><span class="pl-kos">(</span><span class="pl-s1">workbook</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
</details>
|
|
<details>
|
|
<summary><b>Server-Side HTML Tables with Headless Chrome</b> (click to show)</summary>
|
|
<p>The <a href="https://github.com/SheetJS/SheetJS/tree/master/demos/headless/"><code>headless</code> demo</a> includes a complete demo to convert HTML
|
|
files to XLSB workbooks. The core idea is to add the script to the page, parse
|
|
the table in the page context, generate a <code>base64</code> workbook and send it back
|
|
for further processing:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">const</span> <span class="pl-c1">XLSX</span> <span class="pl-c1">=</span> <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">"xlsx"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">const</span> <span class="pl-kos">{</span> readFileSync <span class="pl-kos">}</span> <span class="pl-c1">=</span> <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">"fs"</span><span class="pl-kos">)</span><span class="pl-kos">,</span> <span class="pl-s1">puppeteer</span> <span class="pl-c1">=</span> <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">"puppeteer"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-k">const</span> <span class="pl-s1">url</span> <span class="pl-c1">=</span> <span class="pl-s">`https://sheetjs.com/demos/table`</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* get the standalone build source (node_modules/xlsx/dist/xlsx.full.min.js) */</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">lib</span> <span class="pl-c1">=</span> <span class="pl-en">readFileSync</span><span class="pl-kos">(</span><span class="pl-en">require</span><span class="pl-kos">.</span><span class="pl-en">resolve</span><span class="pl-kos">(</span><span class="pl-s">"xlsx/dist/xlsx.full.min.js"</span><span class="pl-kos">)</span><span class="pl-kos">,</span> <span class="pl-s">"utf8"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-kos">(</span><span class="pl-k">async</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c1">=></span> <span class="pl-kos">{</span>
|
|
<span class="pl-c">/* start browser and go to web page */</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">browser</span> <span class="pl-c1">=</span> <span class="pl-k">await</span> <span class="pl-s1">puppeteer</span><span class="pl-kos">.</span><span class="pl-en">launch</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">page</span> <span class="pl-c1">=</span> <span class="pl-k">await</span> <span class="pl-s1">browser</span><span class="pl-kos">.</span><span class="pl-en">newPage</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">await</span> <span class="pl-s1">page</span><span class="pl-kos">.</span><span class="pl-en">goto</span><span class="pl-kos">(</span><span class="pl-s1">url</span><span class="pl-kos">,</span> <span class="pl-kos">{</span><span class="pl-c1">waitUntil</span>: <span class="pl-s">"networkidle2"</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* inject library */</span>
|
|
<span class="pl-k">await</span> <span class="pl-s1">page</span><span class="pl-kos">.</span><span class="pl-en">addScriptTag</span><span class="pl-kos">(</span><span class="pl-kos">{</span><span class="pl-c1">content</span>: <span class="pl-s1">lib</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* this function `s5s` will be called by the script below, receiving the Base64-encoded file */</span>
|
|
<span class="pl-k">await</span> <span class="pl-s1">page</span><span class="pl-kos">.</span><span class="pl-en">exposeFunction</span><span class="pl-kos">(</span><span class="pl-s">"s5s"</span><span class="pl-kos">,</span> <span class="pl-k">async</span><span class="pl-kos">(</span><span class="pl-s1">b64</span><span class="pl-kos">)</span> <span class="pl-c1">=></span> <span class="pl-kos">{</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">workbook</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-en">read</span><span class="pl-kos">(</span><span class="pl-s1">b64</span><span class="pl-kos">,</span> <span class="pl-kos">{</span><span class="pl-c1">type</span>: <span class="pl-s">"base64"</span> <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* DO SOMETHING WITH workbook HERE */</span>
|
|
<span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* generate XLSB file in webpage context and send back result */</span>
|
|
<span class="pl-k">await</span> <span class="pl-s1">page</span><span class="pl-kos">.</span><span class="pl-en">addScriptTag</span><span class="pl-kos">(</span><span class="pl-kos">{</span><span class="pl-c1">content</span>: <span class="pl-s">`</span>
|
|
<span class="pl-s"> /* call table_to_book on first table */</span>
|
|
<span class="pl-s"> var workbook = XLSX.utils.table_to_book(document.querySelector("TABLE"));</span>
|
|
<span class="pl-s"></span>
|
|
<span class="pl-s"> /* generate XLSX file */</span>
|
|
<span class="pl-s"> var b64 = XLSX.write(workbook, {type: "base64", bookType: "xlsb"});</span>
|
|
<span class="pl-s"></span>
|
|
<span class="pl-s"> /* call "s5s" hook exposed from the node process */</span>
|
|
<span class="pl-s"> window.s5s(b64);</span>
|
|
<span class="pl-s"> `</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* cleanup */</span>
|
|
<span class="pl-k">await</span> <span class="pl-s1">browser</span><span class="pl-kos">.</span><span class="pl-en">close</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
</details>
|
|
<details>
|
|
<summary><b>Server-Side HTML Tables with Headless WebKit</b> (click to show)</summary>
|
|
<p>The <a href="https://github.com/SheetJS/SheetJS/tree/master/demos/headless/"><code>headless</code> demo</a> includes a complete demo to convert HTML
|
|
files to XLSB workbooks using <a href="https://phantomjs.org/" rel="nofollow">PhantomJS</a>. The core idea
|
|
is to add the script to the page, parse the table in the page context, generate
|
|
a <code>binary</code> workbook and send it back for further processing:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> <span class="pl-c1">XLSX</span> <span class="pl-c1">=</span> <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">'xlsx'</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">page</span> <span class="pl-c1">=</span> <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">'webpage'</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">create</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* this code will be run in the page */</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">code</span> <span class="pl-c1">=</span> <span class="pl-kos">[</span> <span class="pl-s">"function(){"</span><span class="pl-kos">,</span>
|
|
<span class="pl-c">/* call table_to_book on first table */</span>
|
|
<span class="pl-s">"var wb = XLSX.utils.table_to_book(document.body.getElementsByTagName('table')[0]);"</span><span class="pl-kos">,</span>
|
|
|
|
<span class="pl-c">/* generate XLSB file and return binary string */</span>
|
|
<span class="pl-s">"return XLSX.write(wb, {type: 'binary', bookType: 'xlsb'});"</span><span class="pl-kos">,</span>
|
|
<span class="pl-s">"}"</span> <span class="pl-kos">]</span><span class="pl-kos">.</span><span class="pl-en">join</span><span class="pl-kos">(</span><span class="pl-s">""</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-s1">page</span><span class="pl-kos">.</span><span class="pl-en">open</span><span class="pl-kos">(</span><span class="pl-s">'https://sheetjs.com/demos/table'</span><span class="pl-kos">,</span> <span class="pl-k">function</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
|
|
<span class="pl-c">/* Load the browser script from the UNPKG CDN */</span>
|
|
<span class="pl-s1">page</span><span class="pl-kos">.</span><span class="pl-en">includeJs</span><span class="pl-kos">(</span><span class="pl-s">"https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js"</span><span class="pl-kos">,</span> <span class="pl-k">function</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
|
|
<span class="pl-c">/* The code will return an XLSB file encoded as binary string */</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">bin</span> <span class="pl-c1">=</span> <span class="pl-s1">page</span><span class="pl-kos">.</span><span class="pl-en">evaluateJavaScript</span><span class="pl-kos">(</span><span class="pl-s1">code</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-k">var</span> <span class="pl-s1">workbook</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-en">read</span><span class="pl-kos">(</span><span class="pl-s1">bin</span><span class="pl-kos">,</span> <span class="pl-kos">{</span><span class="pl-c1">type</span>: <span class="pl-s">"binary"</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-c">/* DO SOMETHING WITH workbook HERE */</span>
|
|
|
|
<span class="pl-s1">phantom</span><span class="pl-kos">.</span><span class="pl-en">exit</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
</details>
|
|
<details>
|
|
<summary><b>NodeJS HTML Tables without a browser</b> (click to show)</summary>
|
|
<p>NodeJS does not include a DOM implementation and Puppeteer requires a hefty
|
|
Chromium build. <a href="https://npm.im/jsdom" rel="nofollow"><code>jsdom</code></a> is a lightweight alternative:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">const</span> <span class="pl-c1">XLSX</span> <span class="pl-c1">=</span> <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">"xlsx"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">const</span> <span class="pl-kos">{</span> readFileSync <span class="pl-kos">}</span> <span class="pl-c1">=</span> <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">"fs"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">const</span> <span class="pl-kos">{</span> <span class="pl-c1">JSDOM</span> <span class="pl-kos">}</span> <span class="pl-c1">=</span> <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">"jsdom"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* obtain HTML string. This example reads from test.html */</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">html_str</span> <span class="pl-c1">=</span> <span class="pl-s1">fs</span><span class="pl-kos">.</span><span class="pl-en">readFileSync</span><span class="pl-kos">(</span><span class="pl-s">"test.html"</span><span class="pl-kos">,</span> <span class="pl-s">"utf8"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-c">/* get first TABLE element */</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">doc</span> <span class="pl-c1">=</span> <span class="pl-k">new</span> <span class="pl-c1">JSDOM</span><span class="pl-kos">(</span><span class="pl-s1">html_str</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-c1">window</span><span class="pl-kos">.</span><span class="pl-c1">document</span><span class="pl-kos">.</span><span class="pl-en">querySelector</span><span class="pl-kos">(</span><span class="pl-s">"table"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-c">/* generate workbook */</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">workbook</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">table_to_book</span><span class="pl-kos">(</span><span class="pl-s1">doc</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
</details>
|
|
<h2>
|
|
<a id="user-content-processing-data" class="anchor" href="#processing-data" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Processing Data</h2>
|
|
<p>The <a href="#common-spreadsheet-format">"Common Spreadsheet Format"</a> is a simple object
|
|
representation of the core concepts of a workbook. The utility functions work
|
|
with the object representation and are intended to handle common use cases.</p>
|
|
<h3>
|
|
<a id="user-content-modifying-workbook-structure" class="anchor" href="#modifying-workbook-structure" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Modifying Workbook Structure</h3>
|
|
<p><strong>API</strong></p>
|
|
<p><em>Append a Worksheet to a Workbook</em></p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">book_append_sheet</span><span class="pl-kos">(</span><span class="pl-s1">workbook</span><span class="pl-kos">,</span> <span class="pl-s1">worksheet</span><span class="pl-kos">,</span> <span class="pl-s1">sheet_name</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>The <code>book_append_sheet</code> utility function appends a worksheet to the workbook.
|
|
The third argument specifies the desired worksheet name. Multiple worksheets can
|
|
be added to a workbook by calling the function multiple times. If the worksheet
|
|
name is already used in the workbook, it will throw an error.</p>
|
|
<p><em>Append a Worksheet to a Workbook and find a unique name</em></p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> <span class="pl-s1">new_name</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">book_append_sheet</span><span class="pl-kos">(</span><span class="pl-s1">workbook</span><span class="pl-kos">,</span> <span class="pl-s1">worksheet</span><span class="pl-kos">,</span> <span class="pl-s1">name</span><span class="pl-kos">,</span> <span class="pl-c1">true</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>If the fourth argument is <code>true</code>, the function will start with the specified
|
|
worksheet name. If the sheet name exists in the workbook, a new worksheet name
|
|
will be chosen by finding the name stem and incrementing the counter:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">book_append_sheet</span><span class="pl-kos">(</span><span class="pl-s1">workbook</span><span class="pl-kos">,</span> <span class="pl-s1">sheetA</span><span class="pl-kos">,</span> <span class="pl-s">"Sheet2"</span><span class="pl-kos">,</span> <span class="pl-c1">true</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-c">// Sheet2</span>
|
|
<span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">book_append_sheet</span><span class="pl-kos">(</span><span class="pl-s1">workbook</span><span class="pl-kos">,</span> <span class="pl-s1">sheetB</span><span class="pl-kos">,</span> <span class="pl-s">"Sheet2"</span><span class="pl-kos">,</span> <span class="pl-c1">true</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-c">// Sheet3</span>
|
|
<span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">book_append_sheet</span><span class="pl-kos">(</span><span class="pl-s1">workbook</span><span class="pl-kos">,</span> <span class="pl-s1">sheetC</span><span class="pl-kos">,</span> <span class="pl-s">"Sheet2"</span><span class="pl-kos">,</span> <span class="pl-c1">true</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-c">// Sheet4</span>
|
|
<span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">book_append_sheet</span><span class="pl-kos">(</span><span class="pl-s1">workbook</span><span class="pl-kos">,</span> <span class="pl-s1">sheetD</span><span class="pl-kos">,</span> <span class="pl-s">"Sheet2"</span><span class="pl-kos">,</span> <span class="pl-c1">true</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-c">// Sheet5</span></pre></div>
|
|
<p><em>List the Worksheet names in tab order</em></p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> <span class="pl-s1">wsnames</span> <span class="pl-c1">=</span> <span class="pl-s1">workbook</span><span class="pl-kos">.</span><span class="pl-c1">SheetNames</span><span class="pl-kos">;</span></pre></div>
|
|
<p>The <code>SheetNames</code> property of the workbook object is a list of the worksheet
|
|
names in "tab order". API functions will look at this array.</p>
|
|
<p><em>Replace a Worksheet in place</em></p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-s1">workbook</span><span class="pl-kos">.</span><span class="pl-c1">Sheets</span><span class="pl-kos">[</span><span class="pl-s1">sheet_name</span><span class="pl-kos">]</span> <span class="pl-c1">=</span> <span class="pl-s1">new_worksheet</span><span class="pl-kos">;</span></pre></div>
|
|
<p>The <code>Sheets</code> property of the workbook object is an object whose keys are names
|
|
and whose values are worksheet objects. By reassigning to a property of the
|
|
<code>Sheets</code> object, the worksheet object can be changed without disrupting the
|
|
rest of the worksheet structure.</p>
|
|
<p><strong>Examples</strong></p>
|
|
<details>
|
|
<summary><b>Add a new worksheet to a workbook</b> (click to show)</summary>
|
|
<p>This example uses <a href="#array-of-arrays-input"><code>XLSX.utils.aoa_to_sheet</code></a>.</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> <span class="pl-s1">ws_name</span> <span class="pl-c1">=</span> <span class="pl-s">"SheetJS"</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* Create worksheet */</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">ws_data</span> <span class="pl-c1">=</span> <span class="pl-kos">[</span>
|
|
<span class="pl-kos">[</span> <span class="pl-s">"S"</span><span class="pl-kos">,</span> <span class="pl-s">"h"</span><span class="pl-kos">,</span> <span class="pl-s">"e"</span><span class="pl-kos">,</span> <span class="pl-s">"e"</span><span class="pl-kos">,</span> <span class="pl-s">"t"</span><span class="pl-kos">,</span> <span class="pl-s">"J"</span><span class="pl-kos">,</span> <span class="pl-s">"S"</span> <span class="pl-kos">]</span><span class="pl-kos">,</span>
|
|
<span class="pl-kos">[</span> <span class="pl-c1">1</span> <span class="pl-kos">,</span> <span class="pl-c1">2</span> <span class="pl-kos">,</span> <span class="pl-c1">3</span> <span class="pl-kos">,</span> <span class="pl-c1">4</span> <span class="pl-kos">,</span> <span class="pl-c1">5</span> <span class="pl-kos">]</span>
|
|
<span class="pl-kos">]</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">ws</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">aoa_to_sheet</span><span class="pl-kos">(</span><span class="pl-s1">ws_data</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* Add the worksheet to the workbook */</span>
|
|
<span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">book_append_sheet</span><span class="pl-kos">(</span><span class="pl-s1">wb</span><span class="pl-kos">,</span> <span class="pl-s1">ws</span><span class="pl-kos">,</span> <span class="pl-s1">ws_name</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
</details>
|
|
<h3>
|
|
<a id="user-content-modifying-cell-values" class="anchor" href="#modifying-cell-values" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Modifying Cell Values</h3>
|
|
<p><strong>API</strong></p>
|
|
<p><em>Modify a single cell value in a worksheet</em></p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">sheet_add_aoa</span><span class="pl-kos">(</span><span class="pl-s1">worksheet</span><span class="pl-kos">,</span> <span class="pl-kos">[</span><span class="pl-kos">[</span><span class="pl-s1">new_value</span><span class="pl-kos">]</span><span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-kos">{</span> <span class="pl-c1">origin</span>: <span class="pl-s1">address</span> <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p><em>Modify multiple cell values in a worksheet</em></p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">sheet_add_aoa</span><span class="pl-kos">(</span><span class="pl-s1">worksheet</span><span class="pl-kos">,</span> <span class="pl-s1">aoa</span><span class="pl-kos">,</span> <span class="pl-s1">opts</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>The <code>sheet_add_aoa</code> utility function modifies cell values in a worksheet. The
|
|
first argument is the worksheet object. The second argument is an array of
|
|
arrays of values. The <code>origin</code> key of the third argument controls where cells
|
|
will be written. The following snippet sets <code>B3=1</code> and <code>E5="abc"</code>:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">sheet_add_aoa</span><span class="pl-kos">(</span><span class="pl-s1">worksheet</span><span class="pl-kos">,</span> <span class="pl-kos">[</span>
|
|
<span class="pl-kos">[</span><span class="pl-c1">1</span><span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-c">// <-- Write 1 to cell B3</span>
|
|
<span class="pl-kos">,</span> <span class="pl-c">// <-- Do nothing in row 4</span>
|
|
<span class="pl-kos">[</span><span class="pl-c">/*B5*/</span><span class="pl-kos">,</span> <span class="pl-c">/*C5*/</span><span class="pl-kos">,</span> <span class="pl-c">/*D5*/</span><span class="pl-kos">,</span> <span class="pl-s">"abc"</span><span class="pl-kos">]</span> <span class="pl-c">// <-- Write "abc" to cell E5</span>
|
|
<span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-kos">{</span> <span class="pl-c1">origin</span>: <span class="pl-s">"B3"</span> <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p><a href="#array-of-arrays-input">"Array of Arrays Input"</a> describes the function and the
|
|
optional <code>opts</code> argument in more detail.</p>
|
|
<p><strong>Examples</strong></p>
|
|
<details>
|
|
<summary><b>Appending rows to a worksheet</b> (click to show)</summary>
|
|
<p>The special origin value <code>-1</code> instructs <code>sheet_add_aoa</code> to start in column A of
|
|
the row after the last row in the range, appending the data:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">sheet_add_aoa</span><span class="pl-kos">(</span><span class="pl-s1">worksheet</span><span class="pl-kos">,</span> <span class="pl-kos">[</span>
|
|
<span class="pl-kos">[</span><span class="pl-s">"first row after data"</span><span class="pl-kos">,</span> <span class="pl-c1">1</span><span class="pl-kos">]</span><span class="pl-kos">,</span>
|
|
<span class="pl-kos">[</span><span class="pl-s">"second row after data"</span><span class="pl-kos">,</span> <span class="pl-c1">2</span><span class="pl-kos">]</span>
|
|
<span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-kos">{</span> <span class="pl-c1">origin</span>: <span class="pl-c1">-</span><span class="pl-c1">1</span> <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
</details>
|
|
<h3>
|
|
<a id="user-content-modifying-other-worksheet--workbook--cell-properties" class="anchor" href="#modifying-other-worksheet--workbook--cell-properties" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Modifying Other Worksheet / Workbook / Cell Properties</h3>
|
|
<p>The <a href="#common-spreadsheet-format">"Common Spreadsheet Format"</a> section describes
|
|
the object structures in greater detail.</p>
|
|
<h2>
|
|
<a id="user-content-packaging-and-releasing-data" class="anchor" href="#packaging-and-releasing-data" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Packaging and Releasing Data</h2>
|
|
<h3>
|
|
<a id="user-content-writing-workbooks" class="anchor" href="#writing-workbooks" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Writing Workbooks</h3>
|
|
<p><strong>API</strong></p>
|
|
<p><em>Generate spreadsheet bytes (file) from data</em></p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> <span class="pl-s1">data</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-en">write</span><span class="pl-kos">(</span><span class="pl-s1">workbook</span><span class="pl-kos">,</span> <span class="pl-s1">opts</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>The <code>write</code> method attempts to package data from the workbook into a file in
|
|
memory. By default, XLSX files are generated, but that can be controlled with
|
|
the <code>bookType</code> property of the <code>opts</code> argument. Based on the <code>type</code> option,
|
|
the data can be stored as a "binary string", JS string, <code>Uint8Array</code> or Buffer.</p>
|
|
<p>The second <code>opts</code> argument is required. <a href="#writing-options">"Writing Options"</a>
|
|
covers the supported properties and behaviors.</p>
|
|
<p><em>Generate and attempt to save file</em></p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-en">writeFile</span><span class="pl-kos">(</span><span class="pl-s1">workbook</span><span class="pl-kos">,</span> <span class="pl-s1">filename</span><span class="pl-kos">,</span> <span class="pl-s1">opts</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>The <code>writeFile</code> method packages the data and attempts to save the new file. The
|
|
export file format is determined by the extension of <code>filename</code> (<code>SheetJS.xlsx</code>
|
|
signals XLSX export, <code>SheetJS.xlsb</code> signals XLSB export, etc).</p>
|
|
<p>The <code>writeFile</code> method uses platform-specific APIs to initiate the file save. In
|
|
NodeJS, <code>fs.readFileSync</code> can create a file. In the web browser, a download is
|
|
attempted using the HTML5 <code>download</code> attribute, with fallbacks for IE.</p>
|
|
<p><em>Generate and attempt to save an XLSX file</em></p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-en">writeFileXLSX</span><span class="pl-kos">(</span><span class="pl-s1">workbook</span><span class="pl-kos">,</span> <span class="pl-s1">filename</span><span class="pl-kos">,</span> <span class="pl-s1">opts</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>The <code>writeFile</code> method embeds a number of different export functions. This is
|
|
great for developer experience but not amenable to tree shaking using the
|
|
current developer tools. When only XLSX exports are needed, this method avoids
|
|
referencing the other export functions.</p>
|
|
<p>The second <code>opts</code> argument is optional. <a href="#writing-options">"Writing Options"</a>
|
|
covers the supported properties and behaviors.</p>
|
|
<p><strong>Examples</strong></p>
|
|
<details>
|
|
<summary><b>Local file in a NodeJS server</b> (click to show)</summary>
|
|
<p><code>writeFile</code> uses <code>fs.writeFileSync</code> in server environments:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> <span class="pl-c1">XLSX</span> <span class="pl-c1">=</span> <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">"xlsx"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* output format determined by filename */</span>
|
|
<span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-en">writeFile</span><span class="pl-kos">(</span><span class="pl-s1">workbook</span><span class="pl-kos">,</span> <span class="pl-s">"out.xlsb"</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>For Node ESM, the <code>writeFile</code> helper is not enabled. Instead, <code>fs.writeFileSync</code>
|
|
should be used to write the file data to a <code>Buffer</code> for use with <code>XLSX.write</code>:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">import</span> <span class="pl-kos">{</span> <span class="pl-s1">writeFileSync</span> <span class="pl-kos">}</span> <span class="pl-k">from</span> <span class="pl-s">"fs"</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">import</span> <span class="pl-kos">{</span> <span class="pl-s1">write</span> <span class="pl-kos">}</span> <span class="pl-k">from</span> <span class="pl-s">"xlsx/xlsx.mjs"</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-k">const</span> <span class="pl-s1">buf</span> <span class="pl-c1">=</span> <span class="pl-en">write</span><span class="pl-kos">(</span><span class="pl-s1">workbook</span><span class="pl-kos">,</span> <span class="pl-kos">{</span><span class="pl-c1">type</span>: <span class="pl-s">"buffer"</span><span class="pl-kos">,</span> <span class="pl-c1">bookType</span>: <span class="pl-s">"xlsb"</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-c">/* buf is a Buffer */</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">workbook</span> <span class="pl-c1">=</span> <span class="pl-en">writeFileSync</span><span class="pl-kos">(</span><span class="pl-s">"out.xlsb"</span><span class="pl-kos">,</span> <span class="pl-s1">buf</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
</details>
|
|
<details>
|
|
<summary><b>Local file in a Deno application</b> (click to show)</summary>
|
|
<p><code>writeFile</code> uses <code>Deno.writeFileSync</code> under the hood:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-c">// <span class="pl-k">@deno</span>-types="https://deno.land/x/sheetjs/types/index.d.ts"</span>
|
|
<span class="pl-k">import</span> <span class="pl-c1">*</span> <span class="pl-k">as</span> <span class="pl-c1">XLSX</span> <span class="pl-k">from</span> <span class="pl-s">'https://deno.land/x/sheetjs/xlsx.mjs'</span>
|
|
|
|
<span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-en">writeFile</span><span class="pl-kos">(</span><span class="pl-s1">workbook</span><span class="pl-kos">,</span> <span class="pl-s">"test.xlsx"</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>Applications writing files must be invoked with the <code>--allow-write</code> flag. The
|
|
<a href="https://github.com/SheetJS/SheetJS/tree/master/demos/deno/"><code>deno</code> demo</a> has more examples</p>
|
|
</details>
|
|
<details>
|
|
<summary><b>Local file in a PhotoShop or InDesign plugin</b> (click to show)</summary>
|
|
<p><code>writeFile</code> wraps the <code>File</code> logic in Photoshop and other ExtendScript targets.
|
|
The specified path should be an absolute path:</p>
|
|
<div class="highlight highlight-source-js"><pre>#<span class="pl-s1">include</span> <span class="pl-s">"xlsx.extendscript.js"</span>
|
|
|
|
<span class="pl-c">/* output format determined by filename */</span>
|
|
<span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-en">writeFile</span><span class="pl-kos">(</span><span class="pl-s1">workbook</span><span class="pl-kos">,</span> <span class="pl-s">"out.xlsx"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-c">/* at this point, out.xlsx is a file that you can distribute */</span></pre></div>
|
|
<p>The <a href="https://github.com/SheetJS/SheetJS/tree/master/demos/extendscript/"><code>extendscript</code> demo</a> includes a more complex example.</p>
|
|
</details>
|
|
<details>
|
|
<summary><b>Download a file in the browser to the user machine</b> (click to show)</summary>
|
|
<p><code>XLSX.writeFile</code> wraps a few techniques for triggering a file save:</p>
|
|
<ul>
|
|
<li>
|
|
<code>URL</code> browser API creates an object URL for the file, which the library uses
|
|
by creating a link and forcing a click. It is supported in modern browsers.</li>
|
|
<li>
|
|
<code>msSaveBlob</code> is an IE10+ API for triggering a file save.</li>
|
|
<li>
|
|
<code>IE_FileSave</code> uses VBScript and ActiveX to write a file in IE6+ for Windows
|
|
XP and Windows 7. The shim must be included in the containing HTML page.</li>
|
|
</ul>
|
|
<p>There is no standard way to determine if the actual file has been downloaded.</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-c">/* output format determined by filename */</span>
|
|
<span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-en">writeFile</span><span class="pl-kos">(</span><span class="pl-s1">workbook</span><span class="pl-kos">,</span> <span class="pl-s">"out.xlsb"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-c">/* at this point, out.xlsb will have been downloaded */</span></pre></div>
|
|
</details>
|
|
<details>
|
|
<summary><b>Download a file in legacy browsers</b> (click to show)</summary>
|
|
<p><code>XLSX.writeFile</code> techniques work for most modern browsers as well as older IE.
|
|
For much older browsers, there are workarounds implemented by wrapper libraries.</p>
|
|
<p><a href="https://github.com/eligrey/FileSaver.js/"><code>FileSaver.js</code></a> implements <code>saveAs</code>.
|
|
Note: <code>XLSX.writeFile</code> will automatically call <code>saveAs</code> if available.</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-c">/* bookType can be any supported output type */</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">wopts</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span> <span class="pl-c1">bookType</span>:<span class="pl-s">"xlsx"</span><span class="pl-kos">,</span> <span class="pl-c1">bookSST</span>:<span class="pl-c1">false</span><span class="pl-kos">,</span> <span class="pl-c1">type</span>:<span class="pl-s">"array"</span> <span class="pl-kos">}</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-k">var</span> <span class="pl-s1">wbout</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-en">write</span><span class="pl-kos">(</span><span class="pl-s1">workbook</span><span class="pl-kos">,</span><span class="pl-s1">wopts</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* the saveAs call downloads a file on the local machine */</span>
|
|
<span class="pl-en">saveAs</span><span class="pl-kos">(</span><span class="pl-k">new</span> <span class="pl-v">Blob</span><span class="pl-kos">(</span><span class="pl-kos">[</span><span class="pl-s1">wbout</span><span class="pl-kos">]</span><span class="pl-kos">,</span><span class="pl-kos">{</span><span class="pl-c1">type</span>:<span class="pl-s">"application/octet-stream"</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">,</span> <span class="pl-s">"test.xlsx"</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p><a href="https://github.com/dcneiner/downloadify"><code>Downloadify</code></a> uses a Flash SWF button
|
|
to generate local files, suitable for environments where ActiveX is unavailable:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-v">Downloadify</span><span class="pl-kos">.</span><span class="pl-en">create</span><span class="pl-kos">(</span><span class="pl-s1">id</span><span class="pl-kos">,</span><span class="pl-kos">{</span>
|
|
<span class="pl-c">/* other options are required! read the downloadify docs for more info */</span>
|
|
<span class="pl-c1">filename</span>: <span class="pl-s">"test.xlsx"</span><span class="pl-kos">,</span>
|
|
<span class="pl-en">data</span>: <span class="pl-k">function</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span> <span class="pl-k">return</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-en">write</span><span class="pl-kos">(</span><span class="pl-s1">wb</span><span class="pl-kos">,</span> <span class="pl-kos">{</span><span class="pl-c1">bookType</span>:<span class="pl-s">"xlsx"</span><span class="pl-kos">,</span> <span class="pl-c1">type</span>:<span class="pl-s">"base64"</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-kos">}</span><span class="pl-kos">,</span>
|
|
<span class="pl-c1">append</span>: <span class="pl-c1">false</span><span class="pl-kos">,</span>
|
|
<span class="pl-c1">dataType</span>: <span class="pl-s">"base64"</span>
|
|
<span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>The <a href="https://github.com/SheetJS/SheetJS/tree/master/demos/oldie/"><code>oldie</code> demo</a> shows an IE-compatible fallback scenario.</p>
|
|
</details>
|
|
<details>
|
|
<summary><b>Browser upload file (ajax)</b> (click to show)</summary>
|
|
<p>A complete example using XHR is <a href="https://github.com/SheetJS/SheetJS/tree/master/demos/xhr/">included in the XHR demo</a>, along
|
|
with examples for fetch and wrapper libraries. This example assumes the server
|
|
can handle Base64-encoded files (see the demo for a basic nodejs server):</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-c">/* in this example, send a base64 string to the server */</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">wopts</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span> <span class="pl-c1">bookType</span>:<span class="pl-s">"xlsx"</span><span class="pl-kos">,</span> <span class="pl-c1">bookSST</span>:<span class="pl-c1">false</span><span class="pl-kos">,</span> <span class="pl-c1">type</span>:<span class="pl-s">"base64"</span> <span class="pl-kos">}</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-k">var</span> <span class="pl-s1">wbout</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-en">write</span><span class="pl-kos">(</span><span class="pl-s1">workbook</span><span class="pl-kos">,</span><span class="pl-s1">wopts</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-k">var</span> <span class="pl-s1">req</span> <span class="pl-c1">=</span> <span class="pl-k">new</span> <span class="pl-v">XMLHttpRequest</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-s1">req</span><span class="pl-kos">.</span><span class="pl-en">open</span><span class="pl-kos">(</span><span class="pl-s">"POST"</span><span class="pl-kos">,</span> <span class="pl-s">"/upload"</span><span class="pl-kos">,</span> <span class="pl-c1">true</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">formdata</span> <span class="pl-c1">=</span> <span class="pl-k">new</span> <span class="pl-v">FormData</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-s1">formdata</span><span class="pl-kos">.</span><span class="pl-en">append</span><span class="pl-kos">(</span><span class="pl-s">"file"</span><span class="pl-kos">,</span> <span class="pl-s">"test.xlsx"</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-c">// <-- server expects `file` to hold name</span>
|
|
<span class="pl-s1">formdata</span><span class="pl-kos">.</span><span class="pl-en">append</span><span class="pl-kos">(</span><span class="pl-s">"data"</span><span class="pl-kos">,</span> <span class="pl-s1">wbout</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-c">// <-- `data` holds the base64-encoded data</span>
|
|
<span class="pl-s1">req</span><span class="pl-kos">.</span><span class="pl-en">send</span><span class="pl-kos">(</span><span class="pl-s1">formdata</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
</details>
|
|
<details>
|
|
<summary><b>PhantomJS (Headless Webkit) File Generation</b> (click to show)</summary>
|
|
<p>The <a href="https://github.com/SheetJS/SheetJS/tree/master/demos/headless/"><code>headless</code> demo</a> includes a complete demo to convert HTML
|
|
files to XLSB workbooks using <a href="https://phantomjs.org/" rel="nofollow">PhantomJS</a>. PhantomJS
|
|
<code>fs.write</code> supports writing files from the main process but has a different
|
|
interface from the NodeJS <code>fs</code> module:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> <span class="pl-c1">XLSX</span> <span class="pl-c1">=</span> <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">'xlsx'</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">fs</span> <span class="pl-c1">=</span> <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">'fs'</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* generate a binary string */</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">bin</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-en">write</span><span class="pl-kos">(</span><span class="pl-s1">workbook</span><span class="pl-kos">,</span> <span class="pl-kos">{</span> <span class="pl-c1">type</span>:<span class="pl-s">"binary"</span><span class="pl-kos">,</span> <span class="pl-c1">bookType</span>: <span class="pl-s">"xlsx"</span> <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-c">/* write to file */</span>
|
|
<span class="pl-s1">fs</span><span class="pl-kos">.</span><span class="pl-en">write</span><span class="pl-kos">(</span><span class="pl-s">"test.xlsx"</span><span class="pl-kos">,</span> <span class="pl-s1">bin</span><span class="pl-kos">,</span> <span class="pl-s">"wb"</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>Note: The section <a href="#processing-html-tables">"Processing HTML Tables"</a> shows how
|
|
to generate a workbook from HTML tables in a page in "Headless WebKit".</p>
|
|
</details>
|
|
<p>The <a href="https://github.com/SheetJS/SheetJS/tree/master/demos/">included demos</a> cover mobile apps and other special deployments.</p>
|
|
<h3>
|
|
<a id="user-content-writing-examples" class="anchor" href="#writing-examples" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Writing Examples</h3>
|
|
<ul>
|
|
<li>
|
|
<a href="http://sheetjs.com/demos/table.html" rel="nofollow">http://sheetjs.com/demos/table.html</a> exporting an HTML table</li>
|
|
<li>
|
|
<a href="http://sheetjs.com/demos/writexlsx.html" rel="nofollow">http://sheetjs.com/demos/writexlsx.html</a> generates a simple file</li>
|
|
</ul>
|
|
<h3>
|
|
<a id="user-content-streaming-write" class="anchor" href="#streaming-write" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Streaming Write</h3>
|
|
<p>The streaming write functions are available in the <code>XLSX.stream</code> object. They
|
|
take the same arguments as the normal write functions but return a NodeJS
|
|
Readable Stream.</p>
|
|
<ul>
|
|
<li>
|
|
<code>XLSX.stream.to_csv</code> is the streaming version of <code>XLSX.utils.sheet_to_csv</code>.</li>
|
|
<li>
|
|
<code>XLSX.stream.to_html</code> is the streaming version of <code>XLSX.utils.sheet_to_html</code>.</li>
|
|
<li>
|
|
<code>XLSX.stream.to_json</code> is the streaming version of <code>XLSX.utils.sheet_to_json</code>.</li>
|
|
</ul>
|
|
<details>
|
|
<summary><b>nodejs convert to CSV and write file</b> (click to show)</summary>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> <span class="pl-s1">output_file_name</span> <span class="pl-c1">=</span> <span class="pl-s">"out.csv"</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">stream</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">stream</span><span class="pl-kos">.</span><span class="pl-en">to_csv</span><span class="pl-kos">(</span><span class="pl-s1">worksheet</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-s1">stream</span><span class="pl-kos">.</span><span class="pl-en">pipe</span><span class="pl-kos">(</span><span class="pl-s1">fs</span><span class="pl-kos">.</span><span class="pl-en">createWriteStream</span><span class="pl-kos">(</span><span class="pl-s1">output_file_name</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
</details>
|
|
<details>
|
|
<summary><b>nodejs write JSON stream to screen</b> (click to show)</summary>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-c">/* to_json returns an object-mode stream */</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">stream</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">stream</span><span class="pl-kos">.</span><span class="pl-en">to_json</span><span class="pl-kos">(</span><span class="pl-s1">worksheet</span><span class="pl-kos">,</span> <span class="pl-kos">{</span><span class="pl-c1">raw</span>:<span class="pl-c1">true</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* the following stream converts JS objects to text via JSON.stringify */</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">conv</span> <span class="pl-c1">=</span> <span class="pl-k">new</span> <span class="pl-v">Transform</span><span class="pl-kos">(</span><span class="pl-kos">{</span><span class="pl-c1">writableObjectMode</span>:<span class="pl-c1">true</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-s1">conv</span><span class="pl-kos">.</span><span class="pl-en">_transform</span> <span class="pl-c1">=</span> <span class="pl-k">function</span><span class="pl-kos">(</span><span class="pl-s1">obj</span><span class="pl-kos">,</span> <span class="pl-s1">e</span><span class="pl-kos">,</span> <span class="pl-s1">cb</span><span class="pl-kos">)</span><span class="pl-kos">{</span> <span class="pl-s1">cb</span><span class="pl-kos">(</span><span class="pl-c1">null</span><span class="pl-kos">,</span> <span class="pl-c1">JSON</span><span class="pl-kos">.</span><span class="pl-en">stringify</span><span class="pl-kos">(</span><span class="pl-s1">obj</span><span class="pl-kos">)</span> <span class="pl-c1">+</span> <span class="pl-s">"\n"</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-kos">}</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-s1">stream</span><span class="pl-kos">.</span><span class="pl-en">pipe</span><span class="pl-kos">(</span><span class="pl-s1">conv</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-s1">conv</span><span class="pl-kos">.</span><span class="pl-en">pipe</span><span class="pl-kos">(</span><span class="pl-s1">process</span><span class="pl-kos">.</span><span class="pl-c1">stdout</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
</details>
|
|
<details>
|
|
<summary><b>Exporting NUMBERS files</b> (click to show)</summary>
|
|
<p>The NUMBERS writer requires a fairly large base. The supplementary <code>xlsx.zahl</code>
|
|
scripts provide support. <code>xlsx.zahl.js</code> is designed for standalone and NodeJS
|
|
use, while <code>xlsx.zahl.mjs</code> is suitable for ESM.</p>
|
|
<p><em>Browser</em></p>
|
|
<div class="highlight highlight-text-html-basic"><pre><span class="pl-kos"><</span><span class="pl-ent">meta</span> <span class="pl-c1">charset</span>="<span class="pl-s">utf8</span>"<span class="pl-kos">></span>
|
|
<span class="pl-kos"><</span><span class="pl-ent">script</span> <span class="pl-c1">src</span>="<span class="pl-s">xlsx.full.min.js</span>"<span class="pl-kos">></span><span class="pl-kos"></</span><span class="pl-ent">script</span><span class="pl-kos">></span>
|
|
<span class="pl-kos"><</span><span class="pl-ent">script</span> <span class="pl-c1">src</span>="<span class="pl-s">xlsx.zahl.js</span>"<span class="pl-kos">></span><span class="pl-kos"></</span><span class="pl-ent">script</span><span class="pl-kos">></span>
|
|
<span class="pl-kos"><</span><span class="pl-ent">script</span><span class="pl-kos">></span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">wb</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">book_new</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-k">var</span> <span class="pl-s1">ws</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">aoa_to_sheet</span><span class="pl-kos">(</span><span class="pl-kos">[</span>
|
|
<span class="pl-kos">[</span><span class="pl-s">"SheetJS"</span><span class="pl-kos">,</span> <span class="pl-s">"<3"</span><span class="pl-kos">,</span><span class="pl-s">"விரிதாள்"</span><span class="pl-kos">]</span><span class="pl-kos">,</span>
|
|
<span class="pl-kos">[</span><span class="pl-c1">72</span><span class="pl-kos">,</span><span class="pl-kos">,</span><span class="pl-s">"Arbeitsblätter"</span><span class="pl-kos">]</span><span class="pl-kos">,</span>
|
|
<span class="pl-kos">[</span><span class="pl-kos">,</span><span class="pl-c1">62</span><span class="pl-kos">,</span><span class="pl-s">"数据"</span><span class="pl-kos">]</span><span class="pl-kos">,</span>
|
|
<span class="pl-kos">[</span><span class="pl-c1">true</span><span class="pl-kos">,</span><span class="pl-c1">false</span><span class="pl-kos">,</span><span class="pl-kos">]</span><span class="pl-kos">,</span>
|
|
<span class="pl-kos">]</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">book_append_sheet</span><span class="pl-kos">(</span><span class="pl-s1">wb</span><span class="pl-kos">,</span> <span class="pl-s1">ws</span><span class="pl-kos">,</span> <span class="pl-s">"Sheet1"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-en">writeFile</span><span class="pl-kos">(</span><span class="pl-s1">wb</span><span class="pl-kos">,</span> <span class="pl-s">"textport.numbers"</span><span class="pl-kos">,</span> <span class="pl-kos">{</span><span class="pl-c1">numbers</span>: <span class="pl-c1">XLSX_ZAHL</span><span class="pl-kos">,</span> <span class="pl-c1">compression</span>: <span class="pl-c1">true</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-kos"></</span><span class="pl-ent">script</span><span class="pl-kos">></span></pre></div>
|
|
<p><em>Node</em></p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> <span class="pl-c1">XLSX</span> <span class="pl-c1">=</span> <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">"./xlsx.flow"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">var</span> <span class="pl-c1">XLSX_ZAHL</span> <span class="pl-c1">=</span> <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">"./dist/xlsx.zahl"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">wb</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">book_new</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-k">var</span> <span class="pl-s1">ws</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">aoa_to_sheet</span><span class="pl-kos">(</span><span class="pl-kos">[</span>
|
|
<span class="pl-kos">[</span><span class="pl-s">"SheetJS"</span><span class="pl-kos">,</span> <span class="pl-s">"<3"</span><span class="pl-kos">,</span><span class="pl-s">"விரிதாள்"</span><span class="pl-kos">]</span><span class="pl-kos">,</span>
|
|
<span class="pl-kos">[</span><span class="pl-c1">72</span><span class="pl-kos">,</span><span class="pl-kos">,</span><span class="pl-s">"Arbeitsblätter"</span><span class="pl-kos">]</span><span class="pl-kos">,</span>
|
|
<span class="pl-kos">[</span><span class="pl-kos">,</span><span class="pl-c1">62</span><span class="pl-kos">,</span><span class="pl-s">"数据"</span><span class="pl-kos">]</span><span class="pl-kos">,</span>
|
|
<span class="pl-kos">[</span><span class="pl-c1">true</span><span class="pl-kos">,</span><span class="pl-c1">false</span><span class="pl-kos">,</span><span class="pl-kos">]</span><span class="pl-kos">,</span>
|
|
<span class="pl-kos">]</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">book_append_sheet</span><span class="pl-kos">(</span><span class="pl-s1">wb</span><span class="pl-kos">,</span> <span class="pl-s1">ws</span><span class="pl-kos">,</span> <span class="pl-s">"Sheet1"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-en">writeFile</span><span class="pl-kos">(</span><span class="pl-s1">wb</span><span class="pl-kos">,</span> <span class="pl-s">"textport.numbers"</span><span class="pl-kos">,</span> <span class="pl-kos">{</span><span class="pl-c1">numbers</span>: <span class="pl-c1">XLSX_ZAHL</span><span class="pl-kos">,</span> <span class="pl-c1">compression</span>: <span class="pl-c1">true</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p><em>Deno</em></p>
|
|
<div class="highlight highlight-source-ts"><pre><span class="pl-k">import</span> <span class="pl-c1">*</span> <span class="pl-k">as</span> <span class="pl-smi">XLSX</span> <span class="pl-k">from</span> <span class="pl-s">'./xlsx.mjs'</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">import</span> <span class="pl-smi">XLSX_ZAHL</span> <span class="pl-k">from</span> <span class="pl-s">'./dist/xlsx.zahl.mjs'</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-k">var</span> <span class="pl-s1">wb</span> <span class="pl-c1">=</span> <span class="pl-smi">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">book_new</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-k">var</span> <span class="pl-s1">ws</span> <span class="pl-c1">=</span> <span class="pl-smi">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">aoa_to_sheet</span><span class="pl-kos">(</span><span class="pl-kos">[</span>
|
|
<span class="pl-kos">[</span><span class="pl-s">"SheetJS"</span><span class="pl-kos">,</span> <span class="pl-s">"<3"</span><span class="pl-kos">,</span><span class="pl-s">"விரிதாள்"</span><span class="pl-kos">]</span><span class="pl-kos">,</span>
|
|
<span class="pl-kos">[</span><span class="pl-c1">72</span><span class="pl-kos">,</span><span class="pl-kos">,</span><span class="pl-s">"Arbeitsblätter"</span><span class="pl-kos">]</span><span class="pl-kos">,</span>
|
|
<span class="pl-kos">[</span><span class="pl-kos">,</span><span class="pl-c1">62</span><span class="pl-kos">,</span><span class="pl-s">"数据"</span><span class="pl-kos">]</span><span class="pl-kos">,</span>
|
|
<span class="pl-kos">[</span><span class="pl-c1">true</span><span class="pl-kos">,</span><span class="pl-c1">false</span><span class="pl-kos">,</span><span class="pl-kos">]</span><span class="pl-kos">,</span>
|
|
<span class="pl-kos">]</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-smi">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">book_append_sheet</span><span class="pl-kos">(</span><span class="pl-s1">wb</span><span class="pl-kos">,</span> <span class="pl-s1">ws</span><span class="pl-kos">,</span> <span class="pl-s">"Sheet1"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-smi">XLSX</span><span class="pl-kos">.</span><span class="pl-en">writeFile</span><span class="pl-kos">(</span><span class="pl-s1">wb</span><span class="pl-kos">,</span> <span class="pl-s">"textports.numbers"</span><span class="pl-kos">,</span> <span class="pl-kos">{</span><span class="pl-c1">numbers</span>: <span class="pl-smi">XLSX_ZAHL</span><span class="pl-kos">,</span> <span class="pl-c1">compression</span>: <span class="pl-c1">true</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
</details>
|
|
<p><a href="https://github.com/sheetjs/sheetaki">https://github.com/sheetjs/sheetaki</a> pipes write streams to nodejs response.</p>
|
|
<h3>
|
|
<a id="user-content-generating-json-and-js-data" class="anchor" href="#generating-json-and-js-data" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Generating JSON and JS Data</h3>
|
|
<p>JSON and JS data tend to represent single worksheets. The utility functions in
|
|
this section work with single worksheets.</p>
|
|
<p>The <a href="#common-spreadsheet-format">"Common Spreadsheet Format"</a> section describes
|
|
the object structure in more detail. <code>workbook.SheetNames</code> is an ordered list
|
|
of the worksheet names. <code>workbook.Sheets</code> is an object whose keys are sheet
|
|
names and whose values are worksheet objects.</p>
|
|
<p>The "first worksheet" is stored at <code>workbook.Sheets[workbook.SheetNames[0]]</code>.</p>
|
|
<p><strong>API</strong></p>
|
|
<p><em>Create an array of JS objects from a worksheet</em></p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> <span class="pl-s1">jsa</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">sheet_to_json</span><span class="pl-kos">(</span><span class="pl-s1">worksheet</span><span class="pl-kos">,</span> <span class="pl-s1">opts</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p><em>Create an array of arrays of JS values from a worksheet</em></p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> <span class="pl-s1">aoa</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">sheet_to_json</span><span class="pl-kos">(</span><span class="pl-s1">worksheet</span><span class="pl-kos">,</span> <span class="pl-kos">{</span>...<span class="pl-s1">opts</span><span class="pl-kos">,</span> <span class="pl-c1">header</span>: <span class="pl-c1">1</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>The <code>sheet_to_json</code> utility function walks a workbook in row-major order,
|
|
generating an array of objects. The second <code>opts</code> argument controls a number of
|
|
export decisions including the type of values (JS values or formatted text). The
|
|
<a href="#json">"JSON"</a> section describes the argument in more detail.</p>
|
|
<p>By default, <code>sheet_to_json</code> scans the first row and uses the values as headers.
|
|
With the <code>header: 1</code> option, the function exports an array of arrays of values.</p>
|
|
<p><strong>Examples</strong></p>
|
|
<p><a href="https://github.com/myliang/x-spreadsheet"><code>x-spreadsheet</code></a> is an interactive
|
|
data grid for previewing and modifying structured data in the web browser. The
|
|
<a href="/demos/xspreadsheet"><code>xspreadsheet</code> demo</a> includes a sample script with the
|
|
<code>stox</code> function for converting from a workbook to x-spreadsheet data object.
|
|
<a href="https://oss.sheetjs.com/sheetjs/x-spreadsheet" rel="nofollow">https://oss.sheetjs.com/sheetjs/x-spreadsheet</a> is a live demo.</p>
|
|
<details>
|
|
<summary><b>Previewing data in a React data grid</b> (click to show)</summary>
|
|
<p><a href="https://npm.im/react-data-grid" rel="nofollow"><code>react-data-grid</code></a> is a data grid tailored for
|
|
react. It expects two properties: <code>rows</code> of data objects and <code>columns</code> which
|
|
describe the columns. For the purposes of massaging the data to fit the react
|
|
data grid API it is easiest to start from an array of arrays.</p>
|
|
<p>This demo starts by fetching a remote file and using <code>XLSX.read</code> to extract:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">import</span> <span class="pl-kos">{</span> <span class="pl-s1">useEffect</span><span class="pl-kos">,</span> <span class="pl-s1">useState</span> <span class="pl-kos">}</span> <span class="pl-k">from</span> <span class="pl-s">"react"</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">import</span> <span class="pl-v">DataGrid</span> <span class="pl-k">from</span> <span class="pl-s">"react-data-grid"</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">import</span> <span class="pl-kos">{</span> <span class="pl-s1">read</span><span class="pl-kos">,</span> <span class="pl-s1">utils</span> <span class="pl-kos">}</span> <span class="pl-k">from</span> <span class="pl-s">"xlsx"</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-k">const</span> <span class="pl-s1">url</span> <span class="pl-c1">=</span> <span class="pl-s">"https://oss.sheetjs.com/test_files/RkNumber.xls"</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-k">export</span> <span class="pl-k">default</span> <span class="pl-k">function</span> <span class="pl-v">App</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
|
|
<span class="pl-k">const</span> <span class="pl-kos">[</span><span class="pl-s1">columns</span><span class="pl-kos">,</span> <span class="pl-s1">setColumns</span><span class="pl-kos">]</span> <span class="pl-c1">=</span> <span class="pl-en">useState</span><span class="pl-kos">(</span><span class="pl-kos">[</span><span class="pl-kos">]</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">const</span> <span class="pl-kos">[</span><span class="pl-s1">rows</span><span class="pl-kos">,</span> <span class="pl-s1">setRows</span><span class="pl-kos">]</span> <span class="pl-c1">=</span> <span class="pl-en">useState</span><span class="pl-kos">(</span><span class="pl-kos">[</span><span class="pl-kos">]</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-en">useEffect</span><span class="pl-kos">(</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c1">=></span> <span class="pl-kos">{</span><span class="pl-kos">(</span><span class="pl-k">async</span> <span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c1">=></span> <span class="pl-kos">{</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">wb</span> <span class="pl-c1">=</span> <span class="pl-en">read</span><span class="pl-kos">(</span><span class="pl-k">await</span> <span class="pl-kos">(</span><span class="pl-k">await</span> <span class="pl-en">fetch</span><span class="pl-kos">(</span><span class="pl-s1">url</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">arrayBuffer</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">,</span> <span class="pl-kos">{</span> <span class="pl-c1">WTF</span>: <span class="pl-c1">1</span> <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* use sheet_to_json with header: 1 to generate an array of arrays */</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">data</span> <span class="pl-c1">=</span> <span class="pl-s1">utils</span><span class="pl-kos">.</span><span class="pl-en">sheet_to_json</span><span class="pl-kos">(</span><span class="pl-s1">wb</span><span class="pl-kos">.</span><span class="pl-c1">Sheets</span><span class="pl-kos">[</span><span class="pl-s1">wb</span><span class="pl-kos">.</span><span class="pl-c1">SheetNames</span><span class="pl-kos">[</span><span class="pl-c1">0</span><span class="pl-kos">]</span><span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-kos">{</span> <span class="pl-c1">header</span>: <span class="pl-c1">1</span> <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* see react-data-grid docs to understand the shape of the expected data */</span>
|
|
<span class="pl-s1">setColumns</span><span class="pl-kos">(</span><span class="pl-s1">data</span><span class="pl-kos">[</span><span class="pl-c1">0</span><span class="pl-kos">]</span><span class="pl-kos">.</span><span class="pl-en">map</span><span class="pl-kos">(</span><span class="pl-kos">(</span><span class="pl-s1">r</span><span class="pl-kos">)</span> <span class="pl-c1">=></span> <span class="pl-kos">(</span><span class="pl-kos">{</span> <span class="pl-c1">key</span>: <span class="pl-s1">r</span><span class="pl-kos">,</span> <span class="pl-c1">name</span>: <span class="pl-s1">r</span> <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-s1">setRows</span><span class="pl-kos">(</span><span class="pl-s1">data</span><span class="pl-kos">.</span><span class="pl-en">slice</span><span class="pl-kos">(</span><span class="pl-c1">1</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">map</span><span class="pl-kos">(</span><span class="pl-kos">(</span><span class="pl-s1">r</span><span class="pl-kos">)</span> <span class="pl-c1">=></span> <span class="pl-s1">r</span><span class="pl-kos">.</span><span class="pl-en">reduce</span><span class="pl-kos">(</span><span class="pl-kos">(</span><span class="pl-s1">acc</span><span class="pl-kos">,</span> <span class="pl-s1">x</span><span class="pl-kos">,</span> <span class="pl-s1">i</span><span class="pl-kos">)</span> <span class="pl-c1">=></span> <span class="pl-kos">{</span>
|
|
<span class="pl-s1">acc</span><span class="pl-kos">[</span><span class="pl-s1">data</span><span class="pl-kos">[</span><span class="pl-c1">0</span><span class="pl-kos">]</span><span class="pl-kos">[</span><span class="pl-s1">i</span><span class="pl-kos">]</span><span class="pl-kos">]</span> <span class="pl-c1">=</span> <span class="pl-s1">x</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">return</span> <span class="pl-s1">acc</span><span class="pl-kos">;</span>
|
|
<span class="pl-kos">}</span><span class="pl-kos">,</span> <span class="pl-kos">{</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-k">return</span> <span class="pl-c1"><</span><span class="pl-ent">DataGrid</span> <span class="pl-c1">columns</span><span class="pl-c1">=</span><span class="pl-kos">{</span><span class="pl-s1">columns</span><span class="pl-kos">}</span> <span class="pl-c1">rows</span><span class="pl-c1">=</span><span class="pl-kos">{</span><span class="pl-s1">rows</span><span class="pl-kos">}</span> <span class="pl-c1">/</span><span class="pl-c1">></span><span class="pl-kos">;</span>
|
|
<span class="pl-kos">}</span></pre></div>
|
|
</details>
|
|
<details>
|
|
<summary><b>Previewing data in a VueJS data grid</b> (click to show)</summary>
|
|
<p><a href="https://github.com/linmasahiro/vue3-table-lite"><code>vue3-table-lite</code></a> is a simple
|
|
VueJS 3 data table. It is featured <a href="/demos/vue/modify/">in the VueJS demo</a>.</p>
|
|
</details>
|
|
<details>
|
|
<summary><b>Populating a database (SQL or no-SQL)</b> (click to show)</summary>
|
|
<p>The <a href="/demos/database/"><code>database</code> demo</a> includes examples of working with
|
|
databases and query results.</p>
|
|
</details>
|
|
<details>
|
|
<summary><b>Numerical Computations with TensorFlow.js</b> (click to show)</summary>
|
|
<p><a href="@tensorflow/tfjs"><code>@tensorflow/tfjs</code></a> and other libraries expect data in simple
|
|
arrays, well-suited for worksheets where each column is a data vector. That is
|
|
the transpose of how most people use spreadsheets, where each row is a vector.</p>
|
|
<p>A single <code>Array#map</code> can pull individual named rows from <code>sheet_to_json</code> export:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">const</span> <span class="pl-c1">XLSX</span> <span class="pl-c1">=</span> <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">"xlsx"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">tf</span> <span class="pl-c1">=</span> <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">'@tensorflow/tfjs'</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-k">const</span> <span class="pl-s1">key</span> <span class="pl-c1">=</span> <span class="pl-s">"age"</span><span class="pl-kos">;</span> <span class="pl-c">// this is the field we want to pull</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">ages</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">sheet_to_json</span><span class="pl-kos">(</span><span class="pl-s1">worksheet</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">map</span><span class="pl-kos">(</span><span class="pl-s1">r</span> <span class="pl-c1">=></span> <span class="pl-s1">r</span><span class="pl-kos">[</span><span class="pl-s1">key</span><span class="pl-kos">]</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">tf_data</span> <span class="pl-c1">=</span> <span class="pl-s1">tf</span><span class="pl-kos">.</span><span class="pl-en">tensor1d</span><span class="pl-kos">(</span><span class="pl-s1">ages</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>All fields can be processed at once using a transpose of the 2D tensor generated
|
|
with the <code>sheet_to_json</code> export with <code>header: 1</code>. The first row, if it contains
|
|
header labels, should be removed with a slice:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">const</span> <span class="pl-c1">XLSX</span> <span class="pl-c1">=</span> <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">"xlsx"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">tf</span> <span class="pl-c1">=</span> <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">'@tensorflow/tfjs'</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* array of arrays of the data starting on the second row */</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">aoa</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">sheet_to_json</span><span class="pl-kos">(</span><span class="pl-s1">worksheet</span><span class="pl-kos">,</span> <span class="pl-kos">{</span><span class="pl-c1">header</span>: <span class="pl-c1">1</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">slice</span><span class="pl-kos">(</span><span class="pl-c1">1</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-c">/* dataset in the "correct orientation" */</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">tf_dataset</span> <span class="pl-c1">=</span> <span class="pl-s1">tf</span><span class="pl-kos">.</span><span class="pl-en">tensor2d</span><span class="pl-kos">(</span><span class="pl-s1">aoa</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">transpose</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-c">/* pull out each dataset with a slice */</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">tf_field0</span> <span class="pl-c1">=</span> <span class="pl-s1">tf_dataset</span><span class="pl-kos">.</span><span class="pl-en">slice</span><span class="pl-kos">(</span><span class="pl-kos">[</span><span class="pl-c1">0</span><span class="pl-kos">,</span><span class="pl-c1">0</span><span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-kos">[</span><span class="pl-c1">1</span><span class="pl-kos">,</span><span class="pl-s1">tensor</span><span class="pl-kos">.</span><span class="pl-c1">shape</span><span class="pl-kos">[</span><span class="pl-c1">1</span><span class="pl-kos">]</span><span class="pl-kos">]</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">flatten</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">tf_field1</span> <span class="pl-c1">=</span> <span class="pl-s1">tf_dataset</span><span class="pl-kos">.</span><span class="pl-en">slice</span><span class="pl-kos">(</span><span class="pl-kos">[</span><span class="pl-c1">1</span><span class="pl-kos">,</span><span class="pl-c1">0</span><span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-kos">[</span><span class="pl-c1">1</span><span class="pl-kos">,</span><span class="pl-s1">tensor</span><span class="pl-kos">.</span><span class="pl-c1">shape</span><span class="pl-kos">[</span><span class="pl-c1">1</span><span class="pl-kos">]</span><span class="pl-kos">]</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">flatten</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>The <a href="https://github.com/SheetJS/SheetJS/tree/master/demos/array/"><code>array</code> demo</a> shows a complete example.</p>
|
|
</details>
|
|
<h3>
|
|
<a id="user-content-generating-html-tables" class="anchor" href="#generating-html-tables" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Generating HTML Tables</h3>
|
|
<p><strong>API</strong></p>
|
|
<p><em>Generate HTML Table from Worksheet</em></p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> <span class="pl-s1">html</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">sheet_to_html</span><span class="pl-kos">(</span><span class="pl-s1">worksheet</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>The <code>sheet_to_html</code> utility function generates HTML code based on the worksheet
|
|
data. Each cell in the worksheet is mapped to a <code><TD></code> element. Merged cells
|
|
in the worksheet are serialized by setting <code>colspan</code> and <code>rowspan</code> attributes.</p>
|
|
<p><strong>Examples</strong></p>
|
|
<p>The <code>sheet_to_html</code> utility function generates HTML code that can be added to
|
|
any DOM element by setting the <code>innerHTML</code>:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> <span class="pl-s1">container</span> <span class="pl-c1">=</span> <span class="pl-smi">document</span><span class="pl-kos">.</span><span class="pl-en">getElementById</span><span class="pl-kos">(</span><span class="pl-s">"tavolo"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-s1">container</span><span class="pl-kos">.</span><span class="pl-c1">innerHTML</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">sheet_to_html</span><span class="pl-kos">(</span><span class="pl-s1">worksheet</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>Combining with <code>fetch</code>, constructing a site from a workbook is straightforward:</p>
|
|
<details>
|
|
<summary><b>Vanilla JS + HTML fetch workbook and generate table previews</b> (click to show)</summary>
|
|
<div class="highlight highlight-text-html-basic"><pre><span class="pl-kos"><</span><span class="pl-ent">body</span><span class="pl-kos">></span>
|
|
<span class="pl-kos"><</span><span class="pl-ent">style</span><span class="pl-kos">></span><span class="pl-ent">TABLE</span> { <span class="pl-c1">border-collapse</span><span class="pl-kos">:</span> collapse; } <span class="pl-ent">TD</span> { <span class="pl-c1">border</span><span class="pl-kos">:</span> <span class="pl-c1">1<span class="pl-smi">px</span></span> solid; }<span class="pl-kos"></</span><span class="pl-ent">style</span><span class="pl-kos">></span>
|
|
<span class="pl-kos"><</span><span class="pl-ent">div</span> <span class="pl-c1">id</span>="<span class="pl-s">tavolo</span>"<span class="pl-kos">></span><span class="pl-kos"></</span><span class="pl-ent">div</span><span class="pl-kos">></span>
|
|
<span class="pl-kos"><</span><span class="pl-ent">script</span> <span class="pl-c1">src</span>="<span class="pl-s">https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js</span>"<span class="pl-kos">></span><span class="pl-kos"></</span><span class="pl-ent">script</span><span class="pl-kos">></span>
|
|
<span class="pl-kos"><</span><span class="pl-ent">script</span> <span class="pl-c1">type</span>="<span class="pl-s">text/javascript</span>"<span class="pl-kos">></span>
|
|
<span class="pl-kos">(</span><span class="pl-k">async</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c1">=></span> <span class="pl-kos">{</span>
|
|
<span class="pl-c">/* fetch and parse workbook -- see the fetch example for details */</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">workbook</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-en">read</span><span class="pl-kos">(</span><span class="pl-k">await</span> <span class="pl-kos">(</span><span class="pl-k">await</span> <span class="pl-en">fetch</span><span class="pl-kos">(</span><span class="pl-s">"sheetjs.xlsx"</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">arrayBuffer</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-k">let</span> <span class="pl-s1">output</span> <span class="pl-c1">=</span> <span class="pl-kos">[</span><span class="pl-kos">]</span><span class="pl-kos">;</span>
|
|
<span class="pl-c">/* loop through the worksheet names in order */</span>
|
|
<span class="pl-s1">workbook</span><span class="pl-kos">.</span><span class="pl-c1">SheetNames</span><span class="pl-kos">.</span><span class="pl-en">forEach</span><span class="pl-kos">(</span><span class="pl-s1">name</span> <span class="pl-c1">=></span> <span class="pl-kos">{</span>
|
|
|
|
<span class="pl-c">/* generate HTML from the corresponding worksheets */</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">worksheet</span> <span class="pl-c1">=</span> <span class="pl-s1">workbook</span><span class="pl-kos">.</span><span class="pl-c1">Sheets</span><span class="pl-kos">[</span><span class="pl-s1">name</span><span class="pl-kos">]</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">html</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">sheet_to_html</span><span class="pl-kos">(</span><span class="pl-s1">worksheet</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* add a header with the title name followed by the table */</span>
|
|
<span class="pl-s1">output</span><span class="pl-kos">.</span><span class="pl-en">push</span><span class="pl-kos">(</span><span class="pl-s">`<H3><span class="pl-s1"><span class="pl-kos">${</span><span class="pl-s1">name</span><span class="pl-kos">}</span></span></H3><span class="pl-s1"><span class="pl-kos">${</span><span class="pl-s1">html</span><span class="pl-kos">}</span></span>`</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-c">/* write to the DOM at the end */</span>
|
|
<span class="pl-s1">tavolo</span><span class="pl-kos">.</span><span class="pl-c1">innerHTML</span> <span class="pl-c1">=</span> <span class="pl-s1">output</span><span class="pl-kos">.</span><span class="pl-en">join</span><span class="pl-kos">(</span><span class="pl-s">"\n"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-kos"></</span><span class="pl-ent">script</span><span class="pl-kos">></span>
|
|
<span class="pl-kos"></</span><span class="pl-ent">body</span><span class="pl-kos">></span></pre></div>
|
|
</details>
|
|
<details>
|
|
<summary><b>React fetch workbook and generate HTML table previews</b> (click to show)</summary>
|
|
<p>It is generally recommended to use a React-friendly workflow, but it is possible
|
|
to generate HTML and use it in React with <code>dangerouslySetInnerHTML</code>:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">function</span> <span class="pl-v">Tabeller</span><span class="pl-kos">(</span><span class="pl-s1">props</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
|
|
<span class="pl-c">/* the workbook object is the state */</span>
|
|
<span class="pl-k">const</span> <span class="pl-kos">[</span><span class="pl-s1">workbook</span><span class="pl-kos">,</span> <span class="pl-s1">setWorkbook</span><span class="pl-kos">]</span> <span class="pl-c1">=</span> <span class="pl-v">React</span><span class="pl-kos">.</span><span class="pl-en">useState</span><span class="pl-kos">(</span><span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">book_new</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* fetch and update the workbook with an effect */</span>
|
|
<span class="pl-v">React</span><span class="pl-kos">.</span><span class="pl-en">useEffect</span><span class="pl-kos">(</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c1">=></span> <span class="pl-kos">{</span> <span class="pl-kos">(</span><span class="pl-k">async</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c1">=></span> <span class="pl-kos">{</span>
|
|
<span class="pl-c">/* fetch and parse workbook -- see the fetch example for details */</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">wb</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-en">read</span><span class="pl-kos">(</span><span class="pl-k">await</span> <span class="pl-kos">(</span><span class="pl-k">await</span> <span class="pl-en">fetch</span><span class="pl-kos">(</span><span class="pl-s">"sheetjs.xlsx"</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">arrayBuffer</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-s1">setWorkbook</span><span class="pl-kos">(</span><span class="pl-s1">wb</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-k">return</span> <span class="pl-s1">workbook</span><span class="pl-kos">.</span><span class="pl-c1">SheetNames</span><span class="pl-kos">.</span><span class="pl-en">map</span><span class="pl-kos">(</span><span class="pl-s1">name</span> <span class="pl-c1">=></span> <span class="pl-kos">(</span><span class="pl-c1"><</span><span class="pl-c1">></span>
|
|
<span class="pl-c1"><</span><span class="pl-ent">h3</span><span class="pl-c1">></span>name<span class="pl-c1"><</span><span class="pl-c1">/</span><span class="pl-ent">h3</span><span class="pl-c1">></span>
|
|
<span class="pl-c1"><</span><span class="pl-ent">div</span> <span class="pl-c1">dangerouslySetInnerHTML</span><span class="pl-c1">=</span><span class="pl-kos">{</span><span class="pl-kos">{</span>
|
|
<span class="pl-c">/* this __html mantra is needed to set the inner HTML */</span>
|
|
<span class="pl-c1">__html</span>: <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">sheet_to_html</span><span class="pl-kos">(</span><span class="pl-s1">workbook</span><span class="pl-kos">.</span><span class="pl-c1">Sheets</span><span class="pl-kos">[</span><span class="pl-s1">name</span><span class="pl-kos">]</span><span class="pl-kos">)</span>
|
|
<span class="pl-kos">}</span><span class="pl-kos">}</span> <span class="pl-c1">/</span><span class="pl-c1">></span>
|
|
<span class="pl-c1"><</span><span class="pl-c1">/</span><span class="pl-c1">></span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-kos">}</span></pre></div>
|
|
<p>The <a href="https://github.com/SheetJS/SheetJS/tree/master/demos/react"><code>react</code> demo</a> includes more React examples.</p>
|
|
</details>
|
|
<details>
|
|
<summary><b>VueJS fetch workbook and generate HTML table previews</b> (click to show)</summary>
|
|
<p>It is generally recommended to use a VueJS-friendly workflow, but it is possible
|
|
to generate HTML and use it in VueJS with the <code>v-html</code> directive:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">import</span> <span class="pl-kos">{</span> <span class="pl-s1">read</span><span class="pl-kos">,</span> <span class="pl-s1">utils</span> <span class="pl-kos">}</span> <span class="pl-k">from</span> <span class="pl-s">'xlsx'</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">import</span> <span class="pl-kos">{</span> <span class="pl-s1">reactive</span> <span class="pl-kos">}</span> <span class="pl-k">from</span> <span class="pl-s">'vue'</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-k">const</span> <span class="pl-v">S5SComponent</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span>
|
|
<span class="pl-en">mounted</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span> <span class="pl-kos">(</span><span class="pl-k">async</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c1">=></span> <span class="pl-kos">{</span>
|
|
<span class="pl-c">/* fetch and parse workbook -- see the fetch example for details */</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">workbook</span> <span class="pl-c1">=</span> <span class="pl-en">read</span><span class="pl-kos">(</span><span class="pl-k">await</span> <span class="pl-kos">(</span><span class="pl-k">await</span> <span class="pl-en">fetch</span><span class="pl-kos">(</span><span class="pl-s">"sheetjs.xlsx"</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">arrayBuffer</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-c">/* loop through the worksheet names in order */</span>
|
|
<span class="pl-s1">workbook</span><span class="pl-kos">.</span><span class="pl-c1">SheetNames</span><span class="pl-kos">.</span><span class="pl-en">forEach</span><span class="pl-kos">(</span><span class="pl-s1">name</span> <span class="pl-c1">=></span> <span class="pl-kos">{</span>
|
|
<span class="pl-c">/* generate HTML from the corresponding worksheets */</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">html</span> <span class="pl-c1">=</span> <span class="pl-s1">utils</span><span class="pl-kos">.</span><span class="pl-en">sheet_to_html</span><span class="pl-kos">(</span><span class="pl-s1">workbook</span><span class="pl-kos">.</span><span class="pl-c1">Sheets</span><span class="pl-kos">[</span><span class="pl-s1">name</span><span class="pl-kos">]</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-c">/* add to state */</span>
|
|
<span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">wb</span><span class="pl-kos">.</span><span class="pl-c1">wb</span><span class="pl-kos">.</span><span class="pl-en">push</span><span class="pl-kos">(</span><span class="pl-kos">{</span> name<span class="pl-kos">,</span> html <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-kos">}</span><span class="pl-kos">,</span>
|
|
<span class="pl-c">/* this state mantra is required for array updates to work */</span>
|
|
<span class="pl-en">setup</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span> <span class="pl-k">return</span> <span class="pl-kos">{</span> <span class="pl-c1">wb</span>: <span class="pl-en">reactive</span><span class="pl-kos">(</span><span class="pl-kos">{</span> <span class="pl-c1">wb</span>: <span class="pl-kos">[</span><span class="pl-kos">]</span> <span class="pl-kos">}</span><span class="pl-kos">)</span> <span class="pl-kos">}</span><span class="pl-kos">;</span> <span class="pl-kos">}</span><span class="pl-kos">,</span>
|
|
<span class="pl-c1">template</span>: <span class="pl-s">`</span>
|
|
<span class="pl-s"> <div v-for="ws in wb.wb" :key="ws.name"></span>
|
|
<span class="pl-s"> <h3>{{ ws.name }}</h3></span>
|
|
<span class="pl-s"> <div v-html="ws.html"></div></span>
|
|
<span class="pl-s"> </div>`</span>
|
|
<span class="pl-kos">}</span><span class="pl-kos">;</span></pre></div>
|
|
<p>The <a href="https://github.com/SheetJS/SheetJS/tree/master/demos/vue"><code>vuejs</code> demo</a> includes more React examples.</p>
|
|
</details>
|
|
<h3>
|
|
<a id="user-content-generating-single-worksheet-snapshots" class="anchor" href="#generating-single-worksheet-snapshots" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Generating Single-Worksheet Snapshots</h3>
|
|
<p>The <code>sheet_to_*</code> functions accept a worksheet object.</p>
|
|
<p><strong>API</strong></p>
|
|
<p><em>Generate a CSV from a single worksheet</em></p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> <span class="pl-s1">csv</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">sheet_to_csv</span><span class="pl-kos">(</span><span class="pl-s1">worksheet</span><span class="pl-kos">,</span> <span class="pl-s1">opts</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>This snapshot is designed to replicate the "CSV UTF8 (<code>.csv</code>)" output type.
|
|
<a href="#delimiter-separated-output">"Delimiter-Separated Output"</a> describes the
|
|
function and the optional <code>opts</code> argument in more detail.</p>
|
|
<p><em>Generate "Text" from a single worksheet</em></p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> <span class="pl-s1">txt</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">sheet_to_txt</span><span class="pl-kos">(</span><span class="pl-s1">worksheet</span><span class="pl-kos">,</span> <span class="pl-s1">opts</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>This snapshot is designed to replicate the "UTF16 Text (<code>.txt</code>)" output type.
|
|
<a href="#delimiter-separated-output">"Delimiter-Separated Output"</a> describes the
|
|
function and the optional <code>opts</code> argument in more detail.</p>
|
|
<p><em>Generate a list of formulae from a single worksheet</em></p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> <span class="pl-s1">fmla</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">sheet_to_formulae</span><span class="pl-kos">(</span><span class="pl-s1">worksheet</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>This snapshot generates an array of entries representing the embedded formulae.
|
|
Array formulae are rendered in the form <code>range=formula</code> while plain cells are
|
|
rendered in the form <code>cell=formula or value</code>. String literals are prefixed with
|
|
an apostrophe <code>'</code>, consistent with Excel's formula bar display.</p>
|
|
<p><a href="#formulae-output">"Formulae Output"</a> describes the function in more detail.</p>
|
|
<h2>
|
|
<a id="user-content-interface" class="anchor" href="#interface" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Interface</h2>
|
|
<p><code>XLSX</code> is the exposed variable in the browser and the exported node variable</p>
|
|
<p><code>XLSX.version</code> is the version of the library (added by the build script).</p>
|
|
<p><code>XLSX.SSF</code> is an embedded version of the <a href="https://github.com/SheetJS/ssf">format library</a>.</p>
|
|
<h3>
|
|
<a id="user-content-parsing-functions" class="anchor" href="#parsing-functions" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Parsing functions</h3>
|
|
<p><code>XLSX.read(data, read_opts)</code> attempts to parse <code>data</code>.</p>
|
|
<p><code>XLSX.readFile(filename, read_opts)</code> attempts to read <code>filename</code> and parse.</p>
|
|
<p>Parse options are described in the <a href="#parsing-options">Parsing Options</a> section.</p>
|
|
<h3>
|
|
<a id="user-content-writing-functions" class="anchor" href="#writing-functions" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Writing functions</h3>
|
|
<p><code>XLSX.write(wb, write_opts)</code> attempts to write the workbook <code>wb</code></p>
|
|
<p><code>XLSX.writeFile(wb, filename, write_opts)</code> attempts to write <code>wb</code> to <code>filename</code>.
|
|
In browser-based environments, it will attempt to force a client-side download.</p>
|
|
<p><code>XLSX.writeFileAsync(filename, wb, o, cb)</code> attempts to write <code>wb</code> to <code>filename</code>.
|
|
If <code>o</code> is omitted, the writer will use the third argument as the callback.</p>
|
|
<p><code>XLSX.stream</code> contains a set of streaming write functions.</p>
|
|
<p>Write options are described in the <a href="#writing-options">Writing Options</a> section.</p>
|
|
<h3>
|
|
<a id="user-content-utilities" class="anchor" href="#utilities" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Utilities</h3>
|
|
<p>Utilities are available in the <code>XLSX.utils</code> object and are described in the
|
|
<a href="#utility-functions">Utility Functions</a> section:</p>
|
|
<p><strong>Constructing:</strong></p>
|
|
<ul>
|
|
<li>
|
|
<code>book_new</code> creates an empty workbook</li>
|
|
<li>
|
|
<code>book_append_sheet</code> adds a worksheet to a workbook</li>
|
|
</ul>
|
|
<p><strong>Importing:</strong></p>
|
|
<ul>
|
|
<li>
|
|
<code>aoa_to_sheet</code> converts an array of arrays of JS data to a worksheet.</li>
|
|
<li>
|
|
<code>json_to_sheet</code> converts an array of JS objects to a worksheet.</li>
|
|
<li>
|
|
<code>table_to_sheet</code> converts a DOM TABLE element to a worksheet.</li>
|
|
<li>
|
|
<code>sheet_add_aoa</code> adds an array of arrays of JS data to an existing worksheet.</li>
|
|
<li>
|
|
<code>sheet_add_json</code> adds an array of JS objects to an existing worksheet.</li>
|
|
</ul>
|
|
<p><strong>Exporting:</strong></p>
|
|
<ul>
|
|
<li>
|
|
<code>sheet_to_json</code> converts a worksheet object to an array of JSON objects.</li>
|
|
<li>
|
|
<code>sheet_to_csv</code> generates delimiter-separated-values output.</li>
|
|
<li>
|
|
<code>sheet_to_txt</code> generates UTF16 formatted text.</li>
|
|
<li>
|
|
<code>sheet_to_html</code> generates HTML output.</li>
|
|
<li>
|
|
<code>sheet_to_formulae</code> generates a list of the formulae (with value fallbacks).</li>
|
|
</ul>
|
|
<p><strong>Cell and cell address manipulation:</strong></p>
|
|
<ul>
|
|
<li>
|
|
<code>format_cell</code> generates the text value for a cell (using number formats).</li>
|
|
<li>
|
|
<code>encode_row / decode_row</code> converts between 0-indexed rows and 1-indexed rows.</li>
|
|
<li>
|
|
<code>encode_col / decode_col</code> converts between 0-indexed columns and column names.</li>
|
|
<li>
|
|
<code>encode_cell / decode_cell</code> converts cell addresses.</li>
|
|
<li>
|
|
<code>encode_range / decode_range</code> converts cell ranges.</li>
|
|
</ul>
|
|
<h2>
|
|
<a id="user-content-common-spreadsheet-format" class="anchor" href="#common-spreadsheet-format" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Common Spreadsheet Format</h2>
|
|
<p>SheetJS conforms to the Common Spreadsheet Format (CSF):</p>
|
|
<h3>
|
|
<a id="user-content-general-structures" class="anchor" href="#general-structures" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>General Structures</h3>
|
|
<p>Cell address objects are stored as <code>{c:C, r:R}</code> where <code>C</code> and <code>R</code> are 0-indexed
|
|
column and row numbers, respectively. For example, the cell address <code>B5</code> is
|
|
represented by the object <code>{c:1, r:4}</code>.</p>
|
|
<p>Cell range objects are stored as <code>{s:S, e:E}</code> where <code>S</code> is the first cell and
|
|
<code>E</code> is the last cell in the range. The ranges are inclusive. For example, the
|
|
range <code>A3:B7</code> is represented by the object <code>{s:{c:0, r:2}, e:{c:1, r:6}}</code>.
|
|
Utility functions perform a row-major order walk traversal of a sheet range:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">for</span><span class="pl-kos">(</span><span class="pl-k">var</span> <span class="pl-v">R</span> <span class="pl-c1">=</span> <span class="pl-s1">range</span><span class="pl-kos">.</span><span class="pl-c1">s</span><span class="pl-kos">.</span><span class="pl-c1">r</span><span class="pl-kos">;</span> <span class="pl-v">R</span> <span class="pl-c1"><=</span> <span class="pl-s1">range</span><span class="pl-kos">.</span><span class="pl-c1">e</span><span class="pl-kos">.</span><span class="pl-c1">r</span><span class="pl-kos">;</span> <span class="pl-c1">++</span><span class="pl-v">R</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
|
|
<span class="pl-k">for</span><span class="pl-kos">(</span><span class="pl-k">var</span> <span class="pl-v">C</span> <span class="pl-c1">=</span> <span class="pl-s1">range</span><span class="pl-kos">.</span><span class="pl-c1">s</span><span class="pl-kos">.</span><span class="pl-c1">c</span><span class="pl-kos">;</span> <span class="pl-v">C</span> <span class="pl-c1"><=</span> <span class="pl-s1">range</span><span class="pl-kos">.</span><span class="pl-c1">e</span><span class="pl-kos">.</span><span class="pl-c1">c</span><span class="pl-kos">;</span> <span class="pl-c1">++</span><span class="pl-v">C</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">cell_address</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span><span class="pl-c1">c</span>:<span class="pl-v">C</span><span class="pl-kos">,</span> <span class="pl-c1">r</span>:<span class="pl-v">R</span><span class="pl-kos">}</span><span class="pl-kos">;</span>
|
|
<span class="pl-c">/* if an A1-style address is needed, encode the address */</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">cell_ref</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">encode_cell</span><span class="pl-kos">(</span><span class="pl-s1">cell_address</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-kos">}</span>
|
|
<span class="pl-kos">}</span></pre></div>
|
|
<h3>
|
|
<a id="user-content-cell-object" class="anchor" href="#cell-object" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Cell Object</h3>
|
|
<p>Cell objects are plain JS objects with keys and values following the convention:</p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Key</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><code>v</code></td>
|
|
<td>raw value (see Data Types section for more info)</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>w</code></td>
|
|
<td>formatted text (if applicable)</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>t</code></td>
|
|
<td>type: <code>b</code> Boolean, <code>e</code> Error, <code>n</code> Number, <code>d</code> Date, <code>s</code> Text, <code>z</code> Stub</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>f</code></td>
|
|
<td>cell formula encoded as an A1-style string (if applicable)</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>F</code></td>
|
|
<td>range of enclosing array if formula is array formula (if applicable)</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>D</code></td>
|
|
<td>if true, array formula is dynamic (if applicable)</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>r</code></td>
|
|
<td>rich text encoding (if applicable)</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>h</code></td>
|
|
<td>HTML rendering of the rich text (if applicable)</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>c</code></td>
|
|
<td>comments associated with the cell</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>z</code></td>
|
|
<td>number format string associated with the cell (if requested)</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>l</code></td>
|
|
<td>cell hyperlink object (<code>.Target</code> holds link, <code>.Tooltip</code> is tooltip)</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>s</code></td>
|
|
<td>the style/theme of the cell (if applicable)</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>Built-in export utilities (such as the CSV exporter) will use the <code>w</code> text if it
|
|
is available. To change a value, be sure to delete <code>cell.w</code> (or set it to
|
|
<code>undefined</code>) before attempting to export. The utilities will regenerate the <code>w</code>
|
|
text from the number format (<code>cell.z</code>) and the raw value if possible.</p>
|
|
<p>The actual array formula is stored in the <code>f</code> field of the first cell in the
|
|
array range. Other cells in the range will omit the <code>f</code> field.</p>
|
|
<h4>
|
|
<a id="user-content-data-types" class="anchor" href="#data-types" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Data Types</h4>
|
|
<p>The raw value is stored in the <code>v</code> value property, interpreted based on the <code>t</code>
|
|
type property. This separation allows for representation of numbers as well as
|
|
numeric text. There are 6 valid cell types:</p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th align="center">Type</th>
|
|
<th align="left">Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td align="center"><code>b</code></td>
|
|
<td align="left">Boolean: value interpreted as JS <code>boolean</code>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center"><code>e</code></td>
|
|
<td align="left">Error: value is a numeric code and <code>w</code> property stores common name **</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center"><code>n</code></td>
|
|
<td align="left">Number: value is a JS <code>number</code> **</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center"><code>d</code></td>
|
|
<td align="left">Date: value is a JS <code>Date</code> object or string to be parsed as Date **</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center"><code>s</code></td>
|
|
<td align="left">Text: value interpreted as JS <code>string</code> and written as text **</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center"><code>z</code></td>
|
|
<td align="left">Stub: blank stub cell that is ignored by data processing utilities **</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<details>
|
|
<summary><b>Error values and interpretation</b> (click to show)</summary>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th align="right">Value</th>
|
|
<th align="left">Error Meaning</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td align="right"><code>0x00</code></td>
|
|
<td align="left"><code>#NULL!</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="right"><code>0x07</code></td>
|
|
<td align="left"><code>#DIV/0!</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="right"><code>0x0F</code></td>
|
|
<td align="left"><code>#VALUE!</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="right"><code>0x17</code></td>
|
|
<td align="left"><code>#REF!</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="right"><code>0x1D</code></td>
|
|
<td align="left"><code>#NAME?</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="right"><code>0x24</code></td>
|
|
<td align="left"><code>#NUM!</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="right"><code>0x2A</code></td>
|
|
<td align="left"><code>#N/A</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="right"><code>0x2B</code></td>
|
|
<td align="left"><code>#GETTING_DATA</code></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</details>
|
|
<p>Type <code>n</code> is the Number type. This includes all forms of data that Excel stores
|
|
as numbers, such as dates/times and Boolean fields. Excel exclusively uses data
|
|
that can be fit in an IEEE754 floating point number, just like JS Number, so the
|
|
<code>v</code> field holds the raw number. The <code>w</code> field holds formatted text. Dates are
|
|
stored as numbers by default and converted with <code>XLSX.SSF.parse_date_code</code>.</p>
|
|
<p>Type <code>d</code> is the Date type, generated only when the option <code>cellDates</code> is passed.
|
|
Since JSON does not have a natural Date type, parsers are generally expected to
|
|
store ISO 8601 Date strings like you would get from <code>date.toISOString()</code>. On
|
|
the other hand, writers and exporters should be able to handle date strings and
|
|
JS Date objects. Note that Excel disregards timezone modifiers and treats all
|
|
dates in the local timezone. The library does not correct for this error.</p>
|
|
<p>Type <code>s</code> is the String type. Values are explicitly stored as text. Excel will
|
|
interpret these cells as "number stored as text". Generated Excel files
|
|
automatically suppress that class of error, but other formats may elicit errors.</p>
|
|
<p>Type <code>z</code> represents blank stub cells. They are generated in cases where cells
|
|
have no assigned value but hold comments or other metadata. They are ignored by
|
|
the core library data processing utility functions. By default these cells are
|
|
not generated; the parser <code>sheetStubs</code> option must be set to <code>true</code>.</p>
|
|
<h4>
|
|
<a id="user-content-dates" class="anchor" href="#dates" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Dates</h4>
|
|
<details>
|
|
<summary><b>Excel Date Code details</b> (click to show)</summary>
|
|
<p>By default, Excel stores dates as numbers with a format code that specifies date
|
|
processing. For example, the date <code>19-Feb-17</code> is stored as the number <code>42785</code>
|
|
with a number format of <code>d-mmm-yy</code>. The <code>SSF</code> module understands number formats
|
|
and performs the appropriate conversion.</p>
|
|
<p>XLSX also supports a special date type <code>d</code> where the data is an ISO 8601 date
|
|
string. The formatter converts the date back to a number.</p>
|
|
<p>The default behavior for all parsers is to generate number cells. Setting
|
|
<code>cellDates</code> to true will force the generators to store dates.</p>
|
|
</details>
|
|
<details>
|
|
<summary><b>Time Zones and Dates</b> (click to show)</summary>
|
|
<p>Excel has no native concept of universal time. All times are specified in the
|
|
local time zone. Excel limitations prevent specifying true absolute dates.</p>
|
|
<p>Following Excel, this library treats all dates as relative to local time zone.</p>
|
|
</details>
|
|
<details>
|
|
<summary><b>Epochs: 1900 and 1904</b> (click to show)</summary>
|
|
<p>Excel supports two epochs (January 1 1900 and January 1 1904).
|
|
The workbook's epoch can be determined by examining the workbook's
|
|
<code>wb.Workbook.WBProps.date1904</code> property:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-c1">!</span><span class="pl-c1">!</span><span class="pl-kos">(</span><span class="pl-kos">(</span><span class="pl-kos">(</span><span class="pl-s1">wb</span><span class="pl-kos">.</span><span class="pl-c1">Workbook</span><span class="pl-c1">||</span><span class="pl-kos">{</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-c1">WBProps</span><span class="pl-c1">||</span><span class="pl-kos">{</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-c1">date1904</span><span class="pl-kos">)</span></pre></div>
|
|
</details>
|
|
<h3>
|
|
<a id="user-content-sheet-objects" class="anchor" href="#sheet-objects" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Sheet Objects</h3>
|
|
<p>Each key that does not start with <code>!</code> maps to a cell (using <code>A-1</code> notation)</p>
|
|
<p><code>sheet[address]</code> returns the cell object for the specified address.</p>
|
|
<p><strong>Special sheet keys (accessible as <code>sheet[key]</code>, each starting with <code>!</code>):</strong></p>
|
|
<ul>
|
|
<li>
|
|
<p><code>sheet['!ref']</code>: A-1 based range representing the sheet range. Functions that
|
|
work with sheets should use this parameter to determine the range. Cells that
|
|
are assigned outside of the range are not processed. In particular, when
|
|
writing a sheet by hand, cells outside of the range are not included</p>
|
|
<p>Functions that handle sheets should test for the presence of <code>!ref</code> field.
|
|
If the <code>!ref</code> is omitted or is not a valid range, functions are free to treat
|
|
the sheet as empty or attempt to guess the range. The standard utilities that
|
|
ship with this library treat sheets as empty (for example, the CSV output is
|
|
empty string).</p>
|
|
<p>When reading a worksheet with the <code>sheetRows</code> property set, the ref parameter
|
|
will use the restricted range. The original range is set at <code>ws['!fullref']</code></p>
|
|
</li>
|
|
<li>
|
|
<p><code>sheet['!margins']</code>: Object representing the page margins. The default values
|
|
follow Excel's "normal" preset. Excel also has a "wide" and a "narrow" preset
|
|
but they are stored as raw measurements. The main properties are listed below:</p>
|
|
</li>
|
|
</ul>
|
|
<details>
|
|
<summary><b>Page margin details</b> (click to show)</summary>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>key</th>
|
|
<th>description</th>
|
|
<th align="left">"normal"</th>
|
|
<th align="left">"wide"</th>
|
|
<th align="left">"narrow"</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><code>left</code></td>
|
|
<td>left margin (inches)</td>
|
|
<td align="left"><code>0.7</code></td>
|
|
<td align="left"><code>1.0</code></td>
|
|
<td align="left"><code>0.25</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>right</code></td>
|
|
<td>right margin (inches)</td>
|
|
<td align="left"><code>0.7</code></td>
|
|
<td align="left"><code>1.0</code></td>
|
|
<td align="left"><code>0.25</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>top</code></td>
|
|
<td>top margin (inches)</td>
|
|
<td align="left"><code>0.75</code></td>
|
|
<td align="left"><code>1.0</code></td>
|
|
<td align="left"><code>0.75</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>bottom</code></td>
|
|
<td>bottom margin (inches)</td>
|
|
<td align="left"><code>0.75</code></td>
|
|
<td align="left"><code>1.0</code></td>
|
|
<td align="left"><code>0.75</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>header</code></td>
|
|
<td>header margin (inches)</td>
|
|
<td align="left"><code>0.3</code></td>
|
|
<td align="left"><code>0.5</code></td>
|
|
<td align="left"><code>0.3</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>footer</code></td>
|
|
<td>footer margin (inches)</td>
|
|
<td align="left"><code>0.3</code></td>
|
|
<td align="left"><code>0.5</code></td>
|
|
<td align="left"><code>0.3</code></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-c">/* Set worksheet sheet to "normal" */</span>
|
|
<span class="pl-s1">ws</span><span class="pl-kos">[</span><span class="pl-s">"!margins"</span><span class="pl-kos">]</span><span class="pl-c1">=</span><span class="pl-kos">{</span><span class="pl-c1">left</span>:<span class="pl-c1">0.7</span><span class="pl-kos">,</span> <span class="pl-c1">right</span>:<span class="pl-c1">0.7</span><span class="pl-kos">,</span> <span class="pl-c1">top</span>:<span class="pl-c1">0.75</span><span class="pl-kos">,</span><span class="pl-c1">bottom</span>:<span class="pl-c1">0.75</span><span class="pl-kos">,</span><span class="pl-c1">header</span>:<span class="pl-c1">0.3</span><span class="pl-kos">,</span><span class="pl-c1">footer</span>:<span class="pl-c1">0.3</span><span class="pl-kos">}</span>
|
|
<span class="pl-c">/* Set worksheet sheet to "wide" */</span>
|
|
<span class="pl-s1">ws</span><span class="pl-kos">[</span><span class="pl-s">"!margins"</span><span class="pl-kos">]</span><span class="pl-c1">=</span><span class="pl-kos">{</span><span class="pl-c1">left</span>:<span class="pl-c1">1.0</span><span class="pl-kos">,</span> <span class="pl-c1">right</span>:<span class="pl-c1">1.0</span><span class="pl-kos">,</span> <span class="pl-c1">top</span>:<span class="pl-c1">1.0</span><span class="pl-kos">,</span> <span class="pl-c1">bottom</span>:<span class="pl-c1">1.0</span><span class="pl-kos">,</span> <span class="pl-c1">header</span>:<span class="pl-c1">0.5</span><span class="pl-kos">,</span><span class="pl-c1">footer</span>:<span class="pl-c1">0.5</span><span class="pl-kos">}</span>
|
|
<span class="pl-c">/* Set worksheet sheet to "narrow" */</span>
|
|
<span class="pl-s1">ws</span><span class="pl-kos">[</span><span class="pl-s">"!margins"</span><span class="pl-kos">]</span><span class="pl-c1">=</span><span class="pl-kos">{</span><span class="pl-c1">left</span>:<span class="pl-c1">0.25</span><span class="pl-kos">,</span><span class="pl-c1">right</span>:<span class="pl-c1">0.25</span><span class="pl-kos">,</span><span class="pl-c1">top</span>:<span class="pl-c1">0.75</span><span class="pl-kos">,</span><span class="pl-c1">bottom</span>:<span class="pl-c1">0.75</span><span class="pl-kos">,</span><span class="pl-c1">header</span>:<span class="pl-c1">0.3</span><span class="pl-kos">,</span><span class="pl-c1">footer</span>:<span class="pl-c1">0.3</span><span class="pl-kos">}</span></pre></div>
|
|
</details>
|
|
<h4>
|
|
<a id="user-content-worksheet-object" class="anchor" href="#worksheet-object" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Worksheet Object</h4>
|
|
<p>In addition to the base sheet keys, worksheets also add:</p>
|
|
<ul>
|
|
<li>
|
|
<p><code>ws['!cols']</code>: array of column properties objects. Column widths are actually
|
|
stored in files in a normalized manner, measured in terms of the "Maximum
|
|
Digit Width" (the largest width of the rendered digits 0-9, in pixels). When
|
|
parsed, the column objects store the pixel width in the <code>wpx</code> field, character
|
|
width in the <code>wch</code> field, and the maximum digit width in the <code>MDW</code> field.</p>
|
|
</li>
|
|
<li>
|
|
<p><code>ws['!rows']</code>: array of row properties objects as explained later in the docs.
|
|
Each row object encodes properties including row height and visibility.</p>
|
|
</li>
|
|
<li>
|
|
<p><code>ws['!merges']</code>: array of range objects corresponding to the merged cells in
|
|
the worksheet. Plain text formats do not support merge cells. CSV export
|
|
will write all cells in the merge range if they exist, so be sure that only
|
|
the first cell (upper-left) in the range is set.</p>
|
|
</li>
|
|
<li>
|
|
<p><code>ws['!outline']</code>: configure how outlines should behave. Options default to
|
|
the default settings in Excel 2019:</p>
|
|
</li>
|
|
</ul>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th align="left">key</th>
|
|
<th align="left">Excel feature</th>
|
|
<th align="left">default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td align="left"><code>above</code></td>
|
|
<td align="left">Uncheck "Summary rows below detail"</td>
|
|
<td align="left"><code>false</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>left</code></td>
|
|
<td align="left">Uncheck "Summary rows to the right of detail"</td>
|
|
<td align="left"><code>false</code></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<ul>
|
|
<li>
|
|
<code>ws['!protect']</code>: object of write sheet protection properties. The <code>password</code>
|
|
key specifies the password for formats that support password-protected sheets
|
|
(XLSX/XLSB/XLS). The writer uses the XOR obfuscation method. The following
|
|
keys control the sheet protection -- set to <code>false</code> to enable a feature when
|
|
sheet is locked or set to <code>true</code> to disable a feature:</li>
|
|
</ul>
|
|
<details>
|
|
<summary><b>Worksheet Protection Details</b> (click to show)</summary>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th align="left">key</th>
|
|
<th align="left">feature (true=disabled / false=enabled)</th>
|
|
<th align="left">default</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td align="left"><code>selectLockedCells</code></td>
|
|
<td align="left">Select locked cells</td>
|
|
<td align="left">enabled</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>selectUnlockedCells</code></td>
|
|
<td align="left">Select unlocked cells</td>
|
|
<td align="left">enabled</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>formatCells</code></td>
|
|
<td align="left">Format cells</td>
|
|
<td align="left">disabled</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>formatColumns</code></td>
|
|
<td align="left">Format columns</td>
|
|
<td align="left">disabled</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>formatRows</code></td>
|
|
<td align="left">Format rows</td>
|
|
<td align="left">disabled</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>insertColumns</code></td>
|
|
<td align="left">Insert columns</td>
|
|
<td align="left">disabled</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>insertRows</code></td>
|
|
<td align="left">Insert rows</td>
|
|
<td align="left">disabled</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>insertHyperlinks</code></td>
|
|
<td align="left">Insert hyperlinks</td>
|
|
<td align="left">disabled</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>deleteColumns</code></td>
|
|
<td align="left">Delete columns</td>
|
|
<td align="left">disabled</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>deleteRows</code></td>
|
|
<td align="left">Delete rows</td>
|
|
<td align="left">disabled</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>sort</code></td>
|
|
<td align="left">Sort</td>
|
|
<td align="left">disabled</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>autoFilter</code></td>
|
|
<td align="left">Filter</td>
|
|
<td align="left">disabled</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>pivotTables</code></td>
|
|
<td align="left">Use PivotTable reports</td>
|
|
<td align="left">disabled</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>objects</code></td>
|
|
<td align="left">Edit objects</td>
|
|
<td align="left">enabled</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>scenarios</code></td>
|
|
<td align="left">Edit scenarios</td>
|
|
<td align="left">enabled</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</details>
|
|
<ul>
|
|
<li>
|
|
<code>ws['!autofilter']</code>: AutoFilter object following the schema:</li>
|
|
</ul>
|
|
<div class="highlight highlight-source-ts"><pre><span class="pl-k">type</span> <span class="pl-smi">AutoFilter</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span>
|
|
<span class="pl-c1">ref</span>:<span class="pl-smi">string</span><span class="pl-kos">;</span> <span class="pl-c">// A-1 based range representing the AutoFilter table range</span>
|
|
<span class="pl-kos">}</span></pre></div>
|
|
<h4>
|
|
<a id="user-content-chartsheet-object" class="anchor" href="#chartsheet-object" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Chartsheet Object</h4>
|
|
<p>Chartsheets are represented as standard sheets. They are distinguished with the
|
|
<code>!type</code> property set to <code>"chart"</code>.</p>
|
|
<p>The underlying data and <code>!ref</code> refer to the cached data in the chartsheet. The
|
|
first row of the chartsheet is the underlying header.</p>
|
|
<h4>
|
|
<a id="user-content-macrosheet-object" class="anchor" href="#macrosheet-object" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Macrosheet Object</h4>
|
|
<p>Macrosheets are represented as standard sheets. They are distinguished with the
|
|
<code>!type</code> property set to <code>"macro"</code>.</p>
|
|
<h4>
|
|
<a id="user-content-dialogsheet-object" class="anchor" href="#dialogsheet-object" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Dialogsheet Object</h4>
|
|
<p>Dialogsheets are represented as standard sheets. They are distinguished with the
|
|
<code>!type</code> property set to <code>"dialog"</code>.</p>
|
|
<h3>
|
|
<a id="user-content-workbook-object" class="anchor" href="#workbook-object" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Workbook Object</h3>
|
|
<p><code>workbook.SheetNames</code> is an ordered list of the sheets in the workbook</p>
|
|
<p><code>wb.Sheets[sheetname]</code> returns an object representing the worksheet.</p>
|
|
<p><code>wb.Props</code> is an object storing the standard properties. <code>wb.Custprops</code> stores
|
|
custom properties. Since the XLS standard properties deviate from the XLSX
|
|
standard, XLS parsing stores core properties in both places.</p>
|
|
<p><code>wb.Workbook</code> stores <a href="#workbook-level-attributes">workbook-level attributes</a>.</p>
|
|
<h4>
|
|
<a id="user-content-workbook-file-properties" class="anchor" href="#workbook-file-properties" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Workbook File Properties</h4>
|
|
<p>The various file formats use different internal names for file properties. The
|
|
workbook <code>Props</code> object normalizes the names:</p>
|
|
<details>
|
|
<summary><b>File Properties</b> (click to show)</summary>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th align="left">JS Name</th>
|
|
<th align="left">Excel Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td align="left"><code>Title</code></td>
|
|
<td align="left">Summary tab "Title"</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>Subject</code></td>
|
|
<td align="left">Summary tab "Subject"</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>Author</code></td>
|
|
<td align="left">Summary tab "Author"</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>Manager</code></td>
|
|
<td align="left">Summary tab "Manager"</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>Company</code></td>
|
|
<td align="left">Summary tab "Company"</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>Category</code></td>
|
|
<td align="left">Summary tab "Category"</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>Keywords</code></td>
|
|
<td align="left">Summary tab "Keywords"</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>Comments</code></td>
|
|
<td align="left">Summary tab "Comments"</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>LastAuthor</code></td>
|
|
<td align="left">Statistics tab "Last saved by"</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>CreatedDate</code></td>
|
|
<td align="left">Statistics tab "Created"</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</details>
|
|
<p>For example, to set the workbook title property:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">if</span><span class="pl-kos">(</span><span class="pl-c1">!</span><span class="pl-s1">wb</span><span class="pl-kos">.</span><span class="pl-c1">Props</span><span class="pl-kos">)</span> <span class="pl-s1">wb</span><span class="pl-kos">.</span><span class="pl-c1">Props</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span><span class="pl-kos">}</span><span class="pl-kos">;</span>
|
|
<span class="pl-s1">wb</span><span class="pl-kos">.</span><span class="pl-c1">Props</span><span class="pl-kos">.</span><span class="pl-c1">Title</span> <span class="pl-c1">=</span> <span class="pl-s">"Insert Title Here"</span><span class="pl-kos">;</span></pre></div>
|
|
<p>Custom properties are added in the workbook <code>Custprops</code> object:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">if</span><span class="pl-kos">(</span><span class="pl-c1">!</span><span class="pl-s1">wb</span><span class="pl-kos">.</span><span class="pl-c1">Custprops</span><span class="pl-kos">)</span> <span class="pl-s1">wb</span><span class="pl-kos">.</span><span class="pl-c1">Custprops</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span><span class="pl-kos">}</span><span class="pl-kos">;</span>
|
|
<span class="pl-s1">wb</span><span class="pl-kos">.</span><span class="pl-c1">Custprops</span><span class="pl-kos">[</span><span class="pl-s">"Custom Property"</span><span class="pl-kos">]</span> <span class="pl-c1">=</span> <span class="pl-s">"Custom Value"</span><span class="pl-kos">;</span></pre></div>
|
|
<p>Writers will process the <code>Props</code> key of the options object:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-c">/* force the Author to be "SheetJS" */</span>
|
|
<span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-en">write</span><span class="pl-kos">(</span><span class="pl-s1">wb</span><span class="pl-kos">,</span> <span class="pl-kos">{</span><span class="pl-c1">Props</span>:<span class="pl-kos">{</span><span class="pl-c1">Author</span>:<span class="pl-s">"SheetJS"</span><span class="pl-kos">}</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<h3>
|
|
<a id="user-content-workbook-level-attributes" class="anchor" href="#workbook-level-attributes" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Workbook-Level Attributes</h3>
|
|
<p><code>wb.Workbook</code> stores workbook-level attributes.</p>
|
|
<h4>
|
|
<a id="user-content-defined-names" class="anchor" href="#defined-names" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Defined Names</h4>
|
|
<details>
|
|
<summary><b>Format Support</b> (click to show)</summary>
|
|
<p><strong>Defined Names</strong>: XLSX/M, XLSB, BIFF8 XLS, XLML, SYLK</p>
|
|
<p><strong>Unicode Defined Names</strong>: XLSX/M, XLSB, BIFF8 XLS, XLML</p>
|
|
<p><strong>Defined Name Comment</strong>: XLSX/M, XLSB, BIFF8 XLS</p>
|
|
</details>
|
|
<p><code>wb.Workbook.Names</code> is an array of defined name objects which have the keys:</p>
|
|
<details>
|
|
<summary><b>Defined Name Properties</b> (click to show)</summary>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th align="left">Key</th>
|
|
<th align="left">Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td align="left"><code>Sheet</code></td>
|
|
<td align="left">Name scope. Sheet Index (0 = first sheet) or <code>null</code> (Workbook)</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>Name</code></td>
|
|
<td align="left">Case-sensitive name. Standard rules apply **</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>Ref</code></td>
|
|
<td align="left">A1-style Reference (<code>"Sheet1!$A$1:$D$20"</code>)</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>Comment</code></td>
|
|
<td align="left">Comment (only applicable for XLS/XLSX/XLSB)</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</details>
|
|
<p>Excel allows two sheet-scoped defined names to share the same name. However, a
|
|
sheet-scoped name cannot collide with a workbook-scope name. Workbook writers
|
|
may not enforce this constraint.</p>
|
|
<h4>
|
|
<a id="user-content-workbook-views" class="anchor" href="#workbook-views" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Workbook Views</h4>
|
|
<p><code>wb.Workbook.Views</code> is an array of workbook view objects which have the keys:</p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th align="left">Key</th>
|
|
<th align="left">Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td align="left"><code>RTL</code></td>
|
|
<td align="left">If true, display right-to-left</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<h4>
|
|
<a id="user-content-miscellaneous-workbook-properties" class="anchor" href="#miscellaneous-workbook-properties" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Miscellaneous Workbook Properties</h4>
|
|
<p><code>wb.Workbook.WBProps</code> holds other workbook properties:</p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th align="left">Key</th>
|
|
<th align="left">Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td align="left"><code>CodeName</code></td>
|
|
<td align="left"><a href="#vba-and-macros">VBA Project Workbook Code Name</a></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>date1904</code></td>
|
|
<td align="left">epoch: 0/false for 1900 system, 1/true for 1904</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>filterPrivacy</code></td>
|
|
<td align="left">Warn or strip personally identifying info on save</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<h3>
|
|
<a id="user-content-document-features" class="anchor" href="#document-features" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Document Features</h3>
|
|
<p>Even for basic features like date storage, the official Excel formats store the
|
|
same content in different ways. The parsers are expected to convert from the
|
|
underlying file format representation to the Common Spreadsheet Format. Writers
|
|
are expected to convert from CSF back to the underlying file format.</p>
|
|
<h4>
|
|
<a id="user-content-formulae" class="anchor" href="#formulae" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Formulae</h4>
|
|
<p>The A1-style formula string is stored in the <code>f</code> field. Even though different
|
|
file formats store the formulae in different ways, the formats are translated.
|
|
Even though some formats store formulae with a leading equal sign, CSF formulae
|
|
do not start with <code>=</code>.</p>
|
|
<details>
|
|
<summary><b>Formulae File Format Support</b> (click to show)</summary>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th align="left">Storage Representation</th>
|
|
<th align="left">Formats</th>
|
|
<th align="center">Read</th>
|
|
<th align="center">Write</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td align="left">A1-style strings</td>
|
|
<td align="left">XLSX</td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">RC-style strings</td>
|
|
<td align="left">XLML and plain text</td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">BIFF Parsed formulae</td>
|
|
<td align="left">XLSB and all XLS formats</td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
<td align="center"></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">OpenFormula formulae</td>
|
|
<td align="left">ODS/FODS/UOS</td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">Lotus Parsed formulae</td>
|
|
<td align="left">All Lotus WK_ formats</td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
<td align="center"></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>Since Excel prohibits named cells from colliding with names of A1 or RC style
|
|
cell references, a (not-so-simple) regex conversion is possible. BIFF Parsed
|
|
formulae and Lotus Parsed formulae have to be explicitly unwound. OpenFormula
|
|
formulae can be converted with regular expressions.</p>
|
|
<p>Shared formulae are decompressed and each cell has the formula corresponding to
|
|
its cell. Writers generally do not attempt to generate shared formulae.</p>
|
|
</details>
|
|
<p><strong>Single-Cell Formulae</strong></p>
|
|
<p>For simple formulae, the <code>f</code> key of the desired cell can be set to the actual
|
|
formula text. This worksheet represents <code>A1=1</code>, <code>A2=2</code>, and <code>A3=A1+A2</code>:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> <span class="pl-s1">worksheet</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span>
|
|
<span class="pl-s">"!ref"</span>: <span class="pl-s">"A1:A3"</span><span class="pl-kos">,</span>
|
|
<span class="pl-c1">A1</span>: <span class="pl-kos">{</span> <span class="pl-c1">t</span>:<span class="pl-s">'n'</span><span class="pl-kos">,</span> <span class="pl-c1">v</span>:<span class="pl-c1">1</span> <span class="pl-kos">}</span><span class="pl-kos">,</span>
|
|
<span class="pl-c1">A2</span>: <span class="pl-kos">{</span> <span class="pl-c1">t</span>:<span class="pl-s">'n'</span><span class="pl-kos">,</span> <span class="pl-c1">v</span>:<span class="pl-c1">2</span> <span class="pl-kos">}</span><span class="pl-kos">,</span>
|
|
<span class="pl-c1">A3</span>: <span class="pl-kos">{</span> <span class="pl-c1">t</span>:<span class="pl-s">'n'</span><span class="pl-kos">,</span> <span class="pl-c1">v</span>:<span class="pl-c1">3</span><span class="pl-kos">,</span> <span class="pl-c1">f</span>:<span class="pl-s">'A1+A2'</span> <span class="pl-kos">}</span>
|
|
<span class="pl-kos">}</span><span class="pl-kos">;</span></pre></div>
|
|
<p>Utilities like <code>aoa_to_sheet</code> will accept cell objects in lieu of values:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> <span class="pl-s1">worksheet</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">aoa_to_sheet</span><span class="pl-kos">(</span><span class="pl-kos">[</span>
|
|
<span class="pl-kos">[</span> <span class="pl-c1">1</span> <span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-c">// A1</span>
|
|
<span class="pl-kos">[</span> <span class="pl-c1">2</span> <span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-c">// A2</span>
|
|
<span class="pl-kos">[</span> <span class="pl-kos">{</span><span class="pl-c1">t</span>: <span class="pl-s">"n"</span><span class="pl-kos">,</span> <span class="pl-c1">v</span>: <span class="pl-c1">3</span><span class="pl-kos">,</span> <span class="pl-c1">f</span>: <span class="pl-s">"A1+A2"</span><span class="pl-kos">}</span> <span class="pl-kos">]</span> <span class="pl-c">// A3</span>
|
|
<span class="pl-kos">]</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>Cells with formula entries but no value will be serialized in a way that Excel
|
|
and other spreadsheet tools will recognize. This library will not automatically
|
|
compute formula results! For example, the following worksheet will include the
|
|
<code>BESSELJ</code> function but the result will not be available in JavaScript:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> <span class="pl-s1">worksheet</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-c1">aoa_to_sheet</span><span class="pl-kos">(</span><span class="pl-kos">[</span>
|
|
<span class="pl-kos">[</span> <span class="pl-c1">3.14159</span><span class="pl-kos">,</span> <span class="pl-c1">2</span> <span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-c">// Row "1"</span>
|
|
<span class="pl-kos">[</span> <span class="pl-kos">{</span> <span class="pl-c1">t</span>:<span class="pl-s">'n'</span><span class="pl-kos">,</span> <span class="pl-c1">f</span>:<span class="pl-s">'BESSELJ(A1,B1)'</span> <span class="pl-kos">}</span> <span class="pl-kos">]</span> <span class="pl-c">// Row "2" will be calculated on file open</span>
|
|
<span class="pl-kos">}</span></pre></div>
|
|
<p>If the actual results are needed in JS, <a href="https://sheetjs.com/pro" rel="nofollow">SheetJS Pro</a>
|
|
offers a formula calculator component for evaluating expressions, updating
|
|
values and dependent cells, and refreshing entire workbooks.</p>
|
|
<p><strong>Array Formulae</strong></p>
|
|
<p><em>Assign an array formula</em></p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">sheet_set_array_formula</span><span class="pl-kos">(</span><span class="pl-s1">worksheet</span><span class="pl-kos">,</span> <span class="pl-s1">range</span><span class="pl-kos">,</span> <span class="pl-s1">formula</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>Array formulae are stored in the top-left cell of the array block. All cells
|
|
of an array formula have a <code>F</code> field corresponding to the range. A single-cell
|
|
formula can be distinguished from a plain formula by the presence of <code>F</code> field.</p>
|
|
<p>For example, setting the cell <code>C1</code> to the array formula <code>{=SUM(A1:A3*B1:B3)}</code>:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-c">// API function</span>
|
|
<span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">sheet_set_array_formula</span><span class="pl-kos">(</span><span class="pl-s1">worksheet</span><span class="pl-kos">,</span> <span class="pl-s">"C1"</span><span class="pl-kos">,</span> <span class="pl-s">"SUM(A1:A3*B1:B3)"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">// ... OR raw operations</span>
|
|
<span class="pl-s1">worksheet</span><span class="pl-kos">[</span><span class="pl-s">'C1'</span><span class="pl-kos">]</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span> <span class="pl-c1">t</span>:<span class="pl-s">'n'</span><span class="pl-kos">,</span> <span class="pl-c1">f</span>: <span class="pl-s">"SUM(A1:A3*B1:B3)"</span><span class="pl-kos">,</span> <span class="pl-c1">F</span>:<span class="pl-s">"C1:C1"</span> <span class="pl-kos">}</span><span class="pl-kos">;</span></pre></div>
|
|
<p>For a multi-cell array formula, every cell has the same array range but only the
|
|
first cell specifies the formula. Consider <code>D1:D3=A1:A3*B1:B3</code>:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-c">// API function</span>
|
|
<span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">sheet_set_array_formula</span><span class="pl-kos">(</span><span class="pl-s1">worksheet</span><span class="pl-kos">,</span> <span class="pl-s">"D1:D3"</span><span class="pl-kos">,</span> <span class="pl-s">"A1:A3*B1:B3"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">// ... OR raw operations</span>
|
|
<span class="pl-s1">worksheet</span><span class="pl-kos">[</span><span class="pl-s">'D1'</span><span class="pl-kos">]</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span> <span class="pl-c1">t</span>:<span class="pl-s">'n'</span><span class="pl-kos">,</span> <span class="pl-c1">F</span>:<span class="pl-s">"D1:D3"</span><span class="pl-kos">,</span> <span class="pl-c1">f</span>:<span class="pl-s">"A1:A3*B1:B3"</span> <span class="pl-kos">}</span><span class="pl-kos">;</span>
|
|
<span class="pl-s1">worksheet</span><span class="pl-kos">[</span><span class="pl-s">'D2'</span><span class="pl-kos">]</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span> <span class="pl-c1">t</span>:<span class="pl-s">'n'</span><span class="pl-kos">,</span> <span class="pl-c1">F</span>:<span class="pl-s">"D1:D3"</span> <span class="pl-kos">}</span><span class="pl-kos">;</span>
|
|
<span class="pl-s1">worksheet</span><span class="pl-kos">[</span><span class="pl-s">'D3'</span><span class="pl-kos">]</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span> <span class="pl-c1">t</span>:<span class="pl-s">'n'</span><span class="pl-kos">,</span> <span class="pl-c1">F</span>:<span class="pl-s">"D1:D3"</span> <span class="pl-kos">}</span><span class="pl-kos">;</span></pre></div>
|
|
<p>Utilities and writers are expected to check for the presence of a <code>F</code> field and
|
|
ignore any possible formula element <code>f</code> in cells other than the starting cell.
|
|
They are not expected to perform validation of the formulae!</p>
|
|
<p><strong>Dynamic Array Formulae</strong></p>
|
|
<p><em>Assign a dynamic array formula</em></p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">sheet_set_array_formula</span><span class="pl-kos">(</span><span class="pl-s1">worksheet</span><span class="pl-kos">,</span> <span class="pl-s1">range</span><span class="pl-kos">,</span> <span class="pl-s1">formula</span><span class="pl-kos">,</span> <span class="pl-c1">true</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>Released in 2020, Dynamic Array Formulae are supported in the XLSX/XLSM and XLSB
|
|
file formats. They are represented like normal array formulae but have special
|
|
cell metadata indicating that the formula should be allowed to adjust the range.</p>
|
|
<p>An array formula can be marked as dynamic by setting the cell's <code>D</code> property to
|
|
true. The <code>F</code> range is expected but can be the set to the current cell:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-c">// API function</span>
|
|
<span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">sheet_set_array_formula</span><span class="pl-kos">(</span><span class="pl-s1">worksheet</span><span class="pl-kos">,</span> <span class="pl-s">"C1"</span><span class="pl-kos">,</span> <span class="pl-s">"_xlfn.UNIQUE(A1:A3)"</span><span class="pl-kos">,</span> <span class="pl-c1">1</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">// ... OR raw operations</span>
|
|
<span class="pl-s1">worksheet</span><span class="pl-kos">[</span><span class="pl-s">'C1'</span><span class="pl-kos">]</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span> <span class="pl-c1">t</span>: <span class="pl-s">"s"</span><span class="pl-kos">,</span> <span class="pl-c1">f</span>: <span class="pl-s">"_xlfn.UNIQUE(A1:A3)"</span><span class="pl-kos">,</span> <span class="pl-c1">F</span>:<span class="pl-s">"C1"</span><span class="pl-kos">,</span> <span class="pl-c1">D</span>: <span class="pl-c1">1</span> <span class="pl-kos">}</span><span class="pl-kos">;</span> <span class="pl-c">// dynamic</span></pre></div>
|
|
<p><strong>Localization with Function Names</strong></p>
|
|
<p>SheetJS operates at the file level. Excel stores formula expressions using the
|
|
English (United States) function names. For non-English users, Excel uses a
|
|
localized set of function names.</p>
|
|
<p>For example, when the computer language and region is set to French (France),
|
|
Excel interprets <code>=SOMME(A1:C3)</code> as if <code>SOMME</code> is the <code>SUM</code> function. However,
|
|
in the actual file, Excel stores <code>SUM(A1:C3)</code>.</p>
|
|
<p><strong>Prefixed "Future Functions"</strong></p>
|
|
<p>Functions introduced in newer versions of Excel are prefixed with <code>_xlfn.</code> when
|
|
stored in files. When writing formula expressions using these functions, the
|
|
prefix is required for maximal compatibility:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-c">// Broadest compatibility</span>
|
|
<span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">sheet_set_array_formula</span><span class="pl-kos">(</span><span class="pl-s1">worksheet</span><span class="pl-kos">,</span> <span class="pl-s">"C1"</span><span class="pl-kos">,</span> <span class="pl-s">"_xlfn.UNIQUE(A1:A3)"</span><span class="pl-kos">,</span> <span class="pl-c1">1</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">// Can cause errors in spreadsheet software</span>
|
|
<span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">sheet_set_array_formula</span><span class="pl-kos">(</span><span class="pl-s1">worksheet</span><span class="pl-kos">,</span> <span class="pl-s">"C1"</span><span class="pl-kos">,</span> <span class="pl-s">"UNIQUE(A1:A3)"</span><span class="pl-kos">,</span> <span class="pl-c1">1</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>When reading a file, the <code>xlfn</code> option preserves the prefixes.</p>
|
|
<details>
|
|
<summary><b> Functions requiring `_xlfn.` prefix</b> (click to show)</summary>
|
|
<p>This list is growing with each Excel release.</p>
|
|
<pre><code>ACOT
|
|
ACOTH
|
|
AGGREGATE
|
|
ARABIC
|
|
BASE
|
|
BETA.DIST
|
|
BETA.INV
|
|
BINOM.DIST
|
|
BINOM.DIST.RANGE
|
|
BINOM.INV
|
|
BITAND
|
|
BITLSHIFT
|
|
BITOR
|
|
BITRSHIFT
|
|
BITXOR
|
|
BYCOL
|
|
BYROW
|
|
CEILING.MATH
|
|
CEILING.PRECISE
|
|
CHISQ.DIST
|
|
CHISQ.DIST.RT
|
|
CHISQ.INV
|
|
CHISQ.INV.RT
|
|
CHISQ.TEST
|
|
COMBINA
|
|
CONFIDENCE.NORM
|
|
CONFIDENCE.T
|
|
COT
|
|
COTH
|
|
COVARIANCE.P
|
|
COVARIANCE.S
|
|
CSC
|
|
CSCH
|
|
DAYS
|
|
DECIMAL
|
|
ERF.PRECISE
|
|
ERFC.PRECISE
|
|
EXPON.DIST
|
|
F.DIST
|
|
F.DIST.RT
|
|
F.INV
|
|
F.INV.RT
|
|
F.TEST
|
|
FIELDVALUE
|
|
FILTERXML
|
|
FLOOR.MATH
|
|
FLOOR.PRECISE
|
|
FORMULATEXT
|
|
GAMMA
|
|
GAMMA.DIST
|
|
GAMMA.INV
|
|
GAMMALN.PRECISE
|
|
GAUSS
|
|
HYPGEOM.DIST
|
|
IFNA
|
|
IMCOSH
|
|
IMCOT
|
|
IMCSC
|
|
IMCSCH
|
|
IMSEC
|
|
IMSECH
|
|
IMSINH
|
|
IMTAN
|
|
ISFORMULA
|
|
ISOMITTED
|
|
ISOWEEKNUM
|
|
LAMBDA
|
|
LET
|
|
LOGNORM.DIST
|
|
LOGNORM.INV
|
|
MAKEARRAY
|
|
MAP
|
|
MODE.MULT
|
|
MODE.SNGL
|
|
MUNIT
|
|
NEGBINOM.DIST
|
|
NORM.DIST
|
|
NORM.INV
|
|
NORM.S.DIST
|
|
NORM.S.INV
|
|
NUMBERVALUE
|
|
PDURATION
|
|
PERCENTILE.EXC
|
|
PERCENTILE.INC
|
|
PERCENTRANK.EXC
|
|
PERCENTRANK.INC
|
|
PERMUTATIONA
|
|
PHI
|
|
POISSON.DIST
|
|
QUARTILE.EXC
|
|
QUARTILE.INC
|
|
QUERYSTRING
|
|
RANDARRAY
|
|
RANK.AVG
|
|
RANK.EQ
|
|
REDUCE
|
|
RRI
|
|
SCAN
|
|
SEC
|
|
SECH
|
|
SEQUENCE
|
|
SHEET
|
|
SHEETS
|
|
SKEW.P
|
|
SORTBY
|
|
STDEV.P
|
|
STDEV.S
|
|
T.DIST
|
|
T.DIST.2T
|
|
T.DIST.RT
|
|
T.INV
|
|
T.INV.2T
|
|
T.TEST
|
|
UNICHAR
|
|
UNICODE
|
|
UNIQUE
|
|
VAR.P
|
|
VAR.S
|
|
WEBSERVICE
|
|
WEIBULL.DIST
|
|
XLOOKUP
|
|
XOR
|
|
Z.TEST
|
|
</code></pre>
|
|
</details>
|
|
<h4>
|
|
<a id="user-content-row-and-column-properties" class="anchor" href="#row-and-column-properties" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Row and Column Properties</h4>
|
|
<details>
|
|
<summary><b>Format Support</b> (click to show)</summary>
|
|
<p><strong>Row Properties</strong>: XLSX/M, XLSB, BIFF8 XLS, XLML, SYLK, DOM, ODS</p>
|
|
<p><strong>Column Properties</strong>: XLSX/M, XLSB, BIFF8 XLS, XLML, SYLK, DOM</p>
|
|
</details>
|
|
<p>Row and Column properties are not extracted by default when reading from a file
|
|
and are not persisted by default when writing to a file. The option
|
|
<code>cellStyles: true</code> must be passed to the relevant read or write function.</p>
|
|
<p><em>Column Properties</em></p>
|
|
<p>The <code>!cols</code> array in each worksheet, if present, is a collection of <code>ColInfo</code>
|
|
objects which have the following properties:</p>
|
|
<div class="highlight highlight-source-ts"><pre><span class="pl-k">type</span> <span class="pl-smi">ColInfo</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span>
|
|
<span class="pl-c">/* visibility */</span>
|
|
<span class="pl-c1">hidden</span>?: <span class="pl-smi">boolean</span><span class="pl-kos">;</span> <span class="pl-c">// if true, the column is hidden</span>
|
|
|
|
<span class="pl-c">/* column width is specified in one of the following ways: */</span>
|
|
<span class="pl-c1">wpx</span>?: <span class="pl-smi">number</span><span class="pl-kos">;</span> <span class="pl-c">// width in screen pixels</span>
|
|
<span class="pl-c1">width</span>?: <span class="pl-smi">number</span><span class="pl-kos">;</span> <span class="pl-c">// width in Excel's "Max Digit Width", width*256 is integral</span>
|
|
<span class="pl-c1">wch</span>?: <span class="pl-smi">number</span><span class="pl-kos">;</span> <span class="pl-c">// width in characters</span>
|
|
|
|
<span class="pl-c">/* other fields for preserving features from files */</span>
|
|
<span class="pl-c1">level</span>?: <span class="pl-smi">number</span><span class="pl-kos">;</span> <span class="pl-c">// 0-indexed outline / group level</span>
|
|
<span class="pl-c1">MDW</span>?: <span class="pl-smi">number</span><span class="pl-kos">;</span> <span class="pl-c">// Excel's "Max Digit Width" unit, always integral</span>
|
|
<span class="pl-kos">}</span><span class="pl-kos">;</span></pre></div>
|
|
<p><em>Row Properties</em></p>
|
|
<p>The <code>!rows</code> array in each worksheet, if present, is a collection of <code>RowInfo</code>
|
|
objects which have the following properties:</p>
|
|
<div class="highlight highlight-source-ts"><pre><span class="pl-k">type</span> <span class="pl-smi">RowInfo</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span>
|
|
<span class="pl-c">/* visibility */</span>
|
|
<span class="pl-c1">hidden</span>?: <span class="pl-smi">boolean</span><span class="pl-kos">;</span> <span class="pl-c">// if true, the row is hidden</span>
|
|
|
|
<span class="pl-c">/* row height is specified in one of the following ways: */</span>
|
|
<span class="pl-c1">hpx</span>?: <span class="pl-smi">number</span><span class="pl-kos">;</span> <span class="pl-c">// height in screen pixels</span>
|
|
<span class="pl-c1">hpt</span>?: <span class="pl-smi">number</span><span class="pl-kos">;</span> <span class="pl-c">// height in points</span>
|
|
|
|
<span class="pl-c1">level</span>?: <span class="pl-smi">number</span><span class="pl-kos">;</span> <span class="pl-c">// 0-indexed outline / group level</span>
|
|
<span class="pl-kos">}</span><span class="pl-kos">;</span></pre></div>
|
|
<p><em>Outline / Group Levels Convention</em></p>
|
|
<p>The Excel UI displays the base outline level as <code>1</code> and the max level as <code>8</code>.
|
|
Following JS conventions, SheetJS uses 0-indexed outline levels wherein the base
|
|
outline level is <code>0</code> and the max level is <code>7</code>.</p>
|
|
<details>
|
|
<summary><b>Why are there three width types?</b> (click to show)</summary>
|
|
<p>There are three different width types corresponding to the three different ways
|
|
spreadsheets store column widths:</p>
|
|
<p>SYLK and other plain text formats use raw character count. Contemporaneous tools
|
|
like Visicalc and Multiplan were character based. Since the characters had the
|
|
same width, it sufficed to store a count. This tradition was continued into the
|
|
BIFF formats.</p>
|
|
<p>SpreadsheetML (2003) tried to align with HTML by standardizing on screen pixel
|
|
count throughout the file. Column widths, row heights, and other measures use
|
|
pixels. When the pixel and character counts do not align, Excel rounds values.</p>
|
|
<p>XLSX internally stores column widths in a nebulous "Max Digit Width" form. The
|
|
Max Digit Width is the width of the largest digit when rendered (generally the
|
|
"0" character is the widest). The internal width must be an integer multiple of
|
|
the the width divided by 256. ECMA-376 describes a formula for converting
|
|
between pixels and the internal width. This represents a hybrid approach.</p>
|
|
<p>Read functions attempt to populate all three properties. Write functions will
|
|
try to cycle specified values to the desired type. In order to avoid potential
|
|
conflicts, manipulation should delete the other properties first. For example,
|
|
when changing the pixel width, delete the <code>wch</code> and <code>width</code> properties.</p>
|
|
</details>
|
|
<details>
|
|
<summary><b>Implementation details</b> (click to show)</summary>
|
|
<p><em>Row Heights</em></p>
|
|
<p>Excel internally stores row heights in points. The default resolution is 72 DPI
|
|
or 96 PPI, so the pixel and point size should agree. For different resolutions
|
|
they may not agree, so the library separates the concepts.</p>
|
|
<p>Even though all of the information is made available, writers are expected to
|
|
follow the priority order:</p>
|
|
<ol>
|
|
<li>use <code>hpx</code> pixel height if available</li>
|
|
<li>use <code>hpt</code> point height if available</li>
|
|
</ol>
|
|
<p><em>Column Widths</em></p>
|
|
<p>Given the constraints, it is possible to determine the MDW without actually
|
|
inspecting the font! The parsers guess the pixel width by converting from width
|
|
to pixels and back, repeating for all possible MDW and selecting the MDW that
|
|
minimizes the error. XLML actually stores the pixel width, so the guess works
|
|
in the opposite direction.</p>
|
|
<p>Even though all of the information is made available, writers are expected to
|
|
follow the priority order:</p>
|
|
<ol>
|
|
<li>use <code>width</code> field if available</li>
|
|
<li>use <code>wpx</code> pixel width if available</li>
|
|
<li>use <code>wch</code> character count if available</li>
|
|
</ol>
|
|
</details>
|
|
<h4>
|
|
<a id="user-content-number-formats" class="anchor" href="#number-formats" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Number Formats</h4>
|
|
<p>The <code>cell.w</code> formatted text for each cell is produced from <code>cell.v</code> and <code>cell.z</code>
|
|
format. If the format is not specified, the Excel <code>General</code> format is used.
|
|
The format can either be specified as a string or as an index into the format
|
|
table. Parsers are expected to populate <code>workbook.SSF</code> with the number format
|
|
table. Writers are expected to serialize the table.</p>
|
|
<p>Custom tools should ensure that the local table has each used format string
|
|
somewhere in the table. Excel convention mandates that the custom formats start
|
|
at index 164. The following example creates a custom format from scratch:</p>
|
|
<details>
|
|
<summary><b>New worksheet with custom format</b> (click to show)</summary>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> <span class="pl-s1">wb</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span>
|
|
<span class="pl-c1">SheetNames</span>: <span class="pl-kos">[</span><span class="pl-s">"Sheet1"</span><span class="pl-kos">]</span><span class="pl-kos">,</span>
|
|
<span class="pl-c1">Sheets</span>: <span class="pl-kos">{</span>
|
|
<span class="pl-c1">Sheet1</span>: <span class="pl-kos">{</span>
|
|
<span class="pl-s">"!ref"</span>:<span class="pl-s">"A1:C1"</span><span class="pl-kos">,</span>
|
|
<span class="pl-c1">A1</span>: <span class="pl-kos">{</span> <span class="pl-c1">t</span>:<span class="pl-s">"n"</span><span class="pl-kos">,</span> <span class="pl-c1">v</span>:<span class="pl-c1">10000</span> <span class="pl-kos">}</span><span class="pl-kos">,</span> <span class="pl-c">// <-- General format</span>
|
|
<span class="pl-c1">B1</span>: <span class="pl-kos">{</span> <span class="pl-c1">t</span>:<span class="pl-s">"n"</span><span class="pl-kos">,</span> <span class="pl-c1">v</span>:<span class="pl-c1">10000</span><span class="pl-kos">,</span> <span class="pl-c1">z</span>: <span class="pl-s">"0%"</span> <span class="pl-kos">}</span><span class="pl-kos">,</span> <span class="pl-c">// <-- Builtin format</span>
|
|
<span class="pl-c1">C1</span>: <span class="pl-kos">{</span> <span class="pl-c1">t</span>:<span class="pl-s">"n"</span><span class="pl-kos">,</span> <span class="pl-c1">v</span>:<span class="pl-c1">10000</span><span class="pl-kos">,</span> <span class="pl-c1">z</span>: <span class="pl-s">"\"T\"\ #0.00"</span> <span class="pl-kos">}</span> <span class="pl-c">// <-- Custom format</span>
|
|
<span class="pl-kos">}</span>
|
|
<span class="pl-kos">}</span>
|
|
<span class="pl-kos">}</span></pre></div>
|
|
</details>
|
|
<p>The rules are slightly different from how Excel displays custom number formats.
|
|
In particular, literal characters must be wrapped in double quotes or preceded
|
|
by a backslash. For more info, see the Excel documentation article
|
|
<code>Create or delete a custom number format</code> or ECMA-376 18.8.31 (Number Formats)</p>
|
|
<details>
|
|
<summary><b>Default Number Formats</b> (click to show)</summary>
|
|
<p>The default formats are listed in ECMA-376 18.8.30:</p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th align="right">ID</th>
|
|
<th align="left">Format</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td align="right">0</td>
|
|
<td align="left"><code>General</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="right">1</td>
|
|
<td align="left"><code>0</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="right">2</td>
|
|
<td align="left"><code>0.00</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="right">3</td>
|
|
<td align="left"><code>#,##0</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="right">4</td>
|
|
<td align="left"><code>#,##0.00</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="right">9</td>
|
|
<td align="left"><code>0%</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="right">10</td>
|
|
<td align="left"><code>0.00%</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="right">11</td>
|
|
<td align="left"><code>0.00E+00</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="right">12</td>
|
|
<td align="left"><code># ?/?</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="right">13</td>
|
|
<td align="left"><code># ??/??</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="right">14</td>
|
|
<td align="left">
|
|
<code>m/d/yy</code> (see below)</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="right">15</td>
|
|
<td align="left"><code>d-mmm-yy</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="right">16</td>
|
|
<td align="left"><code>d-mmm</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="right">17</td>
|
|
<td align="left"><code>mmm-yy</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="right">18</td>
|
|
<td align="left"><code>h:mm AM/PM</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="right">19</td>
|
|
<td align="left"><code>h:mm:ss AM/PM</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="right">20</td>
|
|
<td align="left"><code>h:mm</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="right">21</td>
|
|
<td align="left"><code>h:mm:ss</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="right">22</td>
|
|
<td align="left"><code>m/d/yy h:mm</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="right">37</td>
|
|
<td align="left"><code>#,##0 ;(#,##0)</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="right">38</td>
|
|
<td align="left"><code>#,##0 ;[Red](#,##0)</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="right">39</td>
|
|
<td align="left"><code>#,##0.00;(#,##0.00)</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="right">40</td>
|
|
<td align="left"><code>#,##0.00;[Red](#,##0.00)</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="right">45</td>
|
|
<td align="left"><code>mm:ss</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="right">46</td>
|
|
<td align="left"><code>[h]:mm:ss</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="right">47</td>
|
|
<td align="left"><code>mmss.0</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="right">48</td>
|
|
<td align="left"><code>##0.0E+0</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="right">49</td>
|
|
<td align="left"><code>@</code></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</details>
|
|
<p>Format 14 (<code>m/d/yy</code>) is localized by Excel: even though the file specifies that
|
|
number format, it will be drawn differently based on system settings. It makes
|
|
sense when the producer and consumer of files are in the same locale, but that
|
|
is not always the case over the Internet. To get around this ambiguity, parse
|
|
functions accept the <code>dateNF</code> option to override the interpretation of that
|
|
specific format string.</p>
|
|
<h4>
|
|
<a id="user-content-hyperlinks" class="anchor" href="#hyperlinks" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Hyperlinks</h4>
|
|
<details>
|
|
<summary><b>Format Support</b> (click to show)</summary>
|
|
<p><strong>Cell Hyperlinks</strong>: XLSX/M, XLSB, BIFF8 XLS, XLML, ODS</p>
|
|
<p><strong>Tooltips</strong>: XLSX/M, XLSB, BIFF8 XLS, XLML</p>
|
|
</details>
|
|
<p>Hyperlinks are stored in the <code>l</code> key of cell objects. The <code>Target</code> field of the
|
|
hyperlink object is the target of the link, including the URI fragment. Tooltips
|
|
are stored in the <code>Tooltip</code> field and are displayed when you move your mouse
|
|
over the text.</p>
|
|
<p>For example, the following snippet creates a link from cell <code>A3</code> to
|
|
<a href="https://sheetjs.com" rel="nofollow">https://sheetjs.com</a> with the tip <code>"Find us @ SheetJS.com!"</code>:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-s1">ws</span><span class="pl-kos">[</span><span class="pl-s">'A1'</span><span class="pl-kos">]</span><span class="pl-kos">.</span><span class="pl-c1">l</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span> <span class="pl-c1">Target</span>:<span class="pl-s">"https://sheetjs.com"</span><span class="pl-kos">,</span> <span class="pl-c1">Tooltip</span>:<span class="pl-s">"Find us @ SheetJS.com!"</span> <span class="pl-kos">}</span><span class="pl-kos">;</span></pre></div>
|
|
<p>Note that Excel does not automatically style hyperlinks -- they will generally
|
|
be displayed as normal text.</p>
|
|
<p><em>Remote Links</em></p>
|
|
<p>HTTP / HTTPS links can be used directly:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-s1">ws</span><span class="pl-kos">[</span><span class="pl-s">'A2'</span><span class="pl-kos">]</span><span class="pl-kos">.</span><span class="pl-c1">l</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span> <span class="pl-c1">Target</span>:<span class="pl-s">"https://docs.sheetjs.com/#hyperlinks"</span> <span class="pl-kos">}</span><span class="pl-kos">;</span>
|
|
<span class="pl-s1">ws</span><span class="pl-kos">[</span><span class="pl-s">'A3'</span><span class="pl-kos">]</span><span class="pl-kos">.</span><span class="pl-c1">l</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span> <span class="pl-c1">Target</span>:<span class="pl-s">"http://localhost:7262/yes_localhost_works"</span> <span class="pl-kos">}</span><span class="pl-kos">;</span></pre></div>
|
|
<p>Excel also supports <code>mailto</code> email links with subject line:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-s1">ws</span><span class="pl-kos">[</span><span class="pl-s">'A4'</span><span class="pl-kos">]</span><span class="pl-kos">.</span><span class="pl-c1">l</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span> <span class="pl-c1">Target</span>:<span class="pl-s">"mailto:ignored@dev.null"</span> <span class="pl-kos">}</span><span class="pl-kos">;</span>
|
|
<span class="pl-s1">ws</span><span class="pl-kos">[</span><span class="pl-s">'A5'</span><span class="pl-kos">]</span><span class="pl-kos">.</span><span class="pl-c1">l</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span> <span class="pl-c1">Target</span>:<span class="pl-s">"mailto:ignored@dev.null?subject=Test Subject"</span> <span class="pl-kos">}</span><span class="pl-kos">;</span></pre></div>
|
|
<p><em>Local Links</em></p>
|
|
<p>Links to absolute paths should use the <code>file://</code> URI scheme:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-s1">ws</span><span class="pl-kos">[</span><span class="pl-s">'B1'</span><span class="pl-kos">]</span><span class="pl-kos">.</span><span class="pl-c1">l</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span> <span class="pl-c1">Target</span>:<span class="pl-s">"file:///SheetJS/t.xlsx"</span> <span class="pl-kos">}</span><span class="pl-kos">;</span> <span class="pl-c">/* Link to /SheetJS/t.xlsx */</span>
|
|
<span class="pl-s1">ws</span><span class="pl-kos">[</span><span class="pl-s">'B2'</span><span class="pl-kos">]</span><span class="pl-kos">.</span><span class="pl-c1">l</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span> <span class="pl-c1">Target</span>:<span class="pl-s">"file:///c:/SheetJS.xlsx"</span> <span class="pl-kos">}</span><span class="pl-kos">;</span> <span class="pl-c">/* Link to c:\SheetJS.xlsx */</span></pre></div>
|
|
<p>Links to relative paths can be specified without a scheme:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-s1">ws</span><span class="pl-kos">[</span><span class="pl-s">'B3'</span><span class="pl-kos">]</span><span class="pl-kos">.</span><span class="pl-c1">l</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span> <span class="pl-c1">Target</span>:<span class="pl-s">"SheetJS.xlsb"</span> <span class="pl-kos">}</span><span class="pl-kos">;</span> <span class="pl-c">/* Link to SheetJS.xlsb */</span>
|
|
<span class="pl-s1">ws</span><span class="pl-kos">[</span><span class="pl-s">'B4'</span><span class="pl-kos">]</span><span class="pl-kos">.</span><span class="pl-c1">l</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span> <span class="pl-c1">Target</span>:<span class="pl-s">"../SheetJS.xlsm"</span> <span class="pl-kos">}</span><span class="pl-kos">;</span> <span class="pl-c">/* Link to ../SheetJS.xlsm */</span></pre></div>
|
|
<p>Relative Paths have undefined behavior in the SpreadsheetML 2003 format. Excel
|
|
2019 will treat a <code>..\</code> parent mark as two levels up.</p>
|
|
<p><em>Internal Links</em></p>
|
|
<p>Links where the target is a cell or range or defined name in the same workbook
|
|
("Internal Links") are marked with a leading hash character:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-s1">ws</span><span class="pl-kos">[</span><span class="pl-s">'C1'</span><span class="pl-kos">]</span><span class="pl-kos">.</span><span class="pl-c1">l</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span> <span class="pl-c1">Target</span>:<span class="pl-s">"#E2"</span> <span class="pl-kos">}</span><span class="pl-kos">;</span> <span class="pl-c">/* Link to cell E2 */</span>
|
|
<span class="pl-s1">ws</span><span class="pl-kos">[</span><span class="pl-s">'C2'</span><span class="pl-kos">]</span><span class="pl-kos">.</span><span class="pl-c1">l</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span> <span class="pl-c1">Target</span>:<span class="pl-s">"#Sheet2!E2"</span> <span class="pl-kos">}</span><span class="pl-kos">;</span> <span class="pl-c">/* Link to cell E2 in sheet Sheet2 */</span>
|
|
<span class="pl-s1">ws</span><span class="pl-kos">[</span><span class="pl-s">'C3'</span><span class="pl-kos">]</span><span class="pl-kos">.</span><span class="pl-c1">l</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span> <span class="pl-c1">Target</span>:<span class="pl-s">"#SomeDefinedName"</span> <span class="pl-kos">}</span><span class="pl-kos">;</span> <span class="pl-c">/* Link to Defined Name */</span></pre></div>
|
|
<h4>
|
|
<a id="user-content-cell-comments" class="anchor" href="#cell-comments" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Cell Comments</h4>
|
|
<p>Cell comments are objects stored in the <code>c</code> array of cell objects. The actual
|
|
contents of the comment are split into blocks based on the comment author. The
|
|
<code>a</code> field of each comment object is the author of the comment and the <code>t</code> field
|
|
is the plain text representation.</p>
|
|
<p>For example, the following snippet appends a cell comment into cell <code>A1</code>:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">if</span><span class="pl-kos">(</span><span class="pl-c1">!</span><span class="pl-s1">ws</span><span class="pl-kos">.</span><span class="pl-c1">A1</span><span class="pl-kos">.</span><span class="pl-c1">c</span><span class="pl-kos">)</span> <span class="pl-s1">ws</span><span class="pl-kos">.</span><span class="pl-c1">A1</span><span class="pl-kos">.</span><span class="pl-c1">c</span> <span class="pl-c1">=</span> <span class="pl-kos">[</span><span class="pl-kos">]</span><span class="pl-kos">;</span>
|
|
<span class="pl-s1">ws</span><span class="pl-kos">.</span><span class="pl-c1">A1</span><span class="pl-kos">.</span><span class="pl-c1">c</span><span class="pl-kos">.</span><span class="pl-en">push</span><span class="pl-kos">(</span><span class="pl-kos">{</span><span class="pl-c1">a</span>:<span class="pl-s">"SheetJS"</span><span class="pl-kos">,</span> <span class="pl-c1">t</span>:<span class="pl-s">"I'm a little comment, short and stout!"</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>Note: XLSB enforces a 54 character limit on the Author name. Names longer than
|
|
54 characters may cause issues with other formats.</p>
|
|
<p>To mark a comment as normally hidden, set the <code>hidden</code> property:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">if</span><span class="pl-kos">(</span><span class="pl-c1">!</span><span class="pl-s1">ws</span><span class="pl-kos">.</span><span class="pl-c1">A1</span><span class="pl-kos">.</span><span class="pl-c1">c</span><span class="pl-kos">)</span> <span class="pl-s1">ws</span><span class="pl-kos">.</span><span class="pl-c1">A1</span><span class="pl-kos">.</span><span class="pl-c1">c</span> <span class="pl-c1">=</span> <span class="pl-kos">[</span><span class="pl-kos">]</span><span class="pl-kos">;</span>
|
|
<span class="pl-s1">ws</span><span class="pl-kos">.</span><span class="pl-c1">A1</span><span class="pl-kos">.</span><span class="pl-c1">c</span><span class="pl-kos">.</span><span class="pl-en">push</span><span class="pl-kos">(</span><span class="pl-kos">{</span><span class="pl-c1">a</span>:<span class="pl-s">"SheetJS"</span><span class="pl-kos">,</span> <span class="pl-c1">t</span>:<span class="pl-s">"This comment is visible"</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-k">if</span><span class="pl-kos">(</span><span class="pl-c1">!</span><span class="pl-s1">ws</span><span class="pl-kos">.</span><span class="pl-c1">A2</span><span class="pl-kos">.</span><span class="pl-c1">c</span><span class="pl-kos">)</span> <span class="pl-s1">ws</span><span class="pl-kos">.</span><span class="pl-c1">A2</span><span class="pl-kos">.</span><span class="pl-c1">c</span> <span class="pl-c1">=</span> <span class="pl-kos">[</span><span class="pl-kos">]</span><span class="pl-kos">;</span>
|
|
<span class="pl-s1">ws</span><span class="pl-kos">.</span><span class="pl-c1">A2</span><span class="pl-kos">.</span><span class="pl-c1">c</span><span class="pl-kos">.</span><span class="pl-c1">hidden</span> <span class="pl-c1">=</span> <span class="pl-c1">true</span><span class="pl-kos">;</span>
|
|
<span class="pl-s1">ws</span><span class="pl-kos">.</span><span class="pl-c1">A2</span><span class="pl-kos">.</span><span class="pl-c1">c</span><span class="pl-kos">.</span><span class="pl-en">push</span><span class="pl-kos">(</span><span class="pl-kos">{</span><span class="pl-c1">a</span>:<span class="pl-s">"SheetJS"</span><span class="pl-kos">,</span> <span class="pl-c1">t</span>:<span class="pl-s">"This comment will be hidden"</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p><em>Threaded Comments</em></p>
|
|
<p>Introduced in Excel 365, threaded comments are plain text comment snippets with
|
|
author metadata and parent references. They are supported in XLSX and XLSB.</p>
|
|
<p>To mark a comment as threaded, each comment part must have a true <code>T</code> property:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">if</span><span class="pl-kos">(</span><span class="pl-c1">!</span><span class="pl-s1">ws</span><span class="pl-kos">.</span><span class="pl-c1">A1</span><span class="pl-kos">.</span><span class="pl-c1">c</span><span class="pl-kos">)</span> <span class="pl-s1">ws</span><span class="pl-kos">.</span><span class="pl-c1">A1</span><span class="pl-kos">.</span><span class="pl-c1">c</span> <span class="pl-c1">=</span> <span class="pl-kos">[</span><span class="pl-kos">]</span><span class="pl-kos">;</span>
|
|
<span class="pl-s1">ws</span><span class="pl-kos">.</span><span class="pl-c1">A1</span><span class="pl-kos">.</span><span class="pl-c1">c</span><span class="pl-kos">.</span><span class="pl-en">push</span><span class="pl-kos">(</span><span class="pl-kos">{</span><span class="pl-c1">a</span>:<span class="pl-s">"SheetJS"</span><span class="pl-kos">,</span> <span class="pl-c1">t</span>:<span class="pl-s">"This is not threaded"</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-k">if</span><span class="pl-kos">(</span><span class="pl-c1">!</span><span class="pl-s1">ws</span><span class="pl-kos">.</span><span class="pl-c1">A2</span><span class="pl-kos">.</span><span class="pl-c1">c</span><span class="pl-kos">)</span> <span class="pl-s1">ws</span><span class="pl-kos">.</span><span class="pl-c1">A2</span><span class="pl-kos">.</span><span class="pl-c1">c</span> <span class="pl-c1">=</span> <span class="pl-kos">[</span><span class="pl-kos">]</span><span class="pl-kos">;</span>
|
|
<span class="pl-s1">ws</span><span class="pl-kos">.</span><span class="pl-c1">A2</span><span class="pl-kos">.</span><span class="pl-c1">c</span><span class="pl-kos">.</span><span class="pl-c1">hidden</span> <span class="pl-c1">=</span> <span class="pl-c1">true</span><span class="pl-kos">;</span>
|
|
<span class="pl-s1">ws</span><span class="pl-kos">.</span><span class="pl-c1">A2</span><span class="pl-kos">.</span><span class="pl-c1">c</span><span class="pl-kos">.</span><span class="pl-en">push</span><span class="pl-kos">(</span><span class="pl-kos">{</span><span class="pl-c1">a</span>:<span class="pl-s">"SheetJS"</span><span class="pl-kos">,</span> <span class="pl-c1">t</span>:<span class="pl-s">"This is threaded"</span><span class="pl-kos">,</span> <span class="pl-c1">T</span>: <span class="pl-c1">true</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-s1">ws</span><span class="pl-kos">.</span><span class="pl-c1">A2</span><span class="pl-kos">.</span><span class="pl-c1">c</span><span class="pl-kos">.</span><span class="pl-en">push</span><span class="pl-kos">(</span><span class="pl-kos">{</span><span class="pl-c1">a</span>:<span class="pl-s">"JSSheet"</span><span class="pl-kos">,</span> <span class="pl-c1">t</span>:<span class="pl-s">"This is also threaded"</span><span class="pl-kos">,</span> <span class="pl-c1">T</span>: <span class="pl-c1">true</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>There is no Active Directory or Office 365 metadata associated with authors in a thread.</p>
|
|
<h4>
|
|
<a id="user-content-sheet-visibility" class="anchor" href="#sheet-visibility" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Sheet Visibility</h4>
|
|
<p>Excel enables hiding sheets in the lower tab bar. The sheet data is stored in
|
|
the file but the UI does not readily make it available. Standard hidden sheets
|
|
are revealed in the "Unhide" menu. Excel also has "very hidden" sheets which
|
|
cannot be revealed in the menu. It is only accessible in the VB Editor!</p>
|
|
<p>The visibility setting is stored in the <code>Hidden</code> property of sheet props array.</p>
|
|
<details>
|
|
<summary><b>More details</b> (click to show)</summary>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th align="center">Value</th>
|
|
<th align="left">Definition</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td align="center">0</td>
|
|
<td align="left">Visible</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center">1</td>
|
|
<td align="left">Hidden</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center">2</td>
|
|
<td align="left">Very Hidden</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>With <a href="https://rawgit.com/SheetJS/test_files/HEAD/sheet_visibility.xlsx" rel="nofollow">https://rawgit.com/SheetJS/test_files/HEAD/sheet_visibility.xlsx</a>:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-c1">></span> <span class="pl-s1">wb</span><span class="pl-kos">.</span><span class="pl-c1">Workbook</span><span class="pl-kos">.</span><span class="pl-c1">Sheets</span><span class="pl-kos">.</span><span class="pl-en">map</span><span class="pl-kos">(</span><span class="pl-k">function</span><span class="pl-kos">(</span><span class="pl-s1">x</span><span class="pl-kos">)</span> <span class="pl-kos">{</span> <span class="pl-k">return</span> <span class="pl-kos">[</span><span class="pl-s1">x</span><span class="pl-kos">.</span><span class="pl-c1">name</span><span class="pl-kos">,</span> <span class="pl-s1">x</span><span class="pl-kos">.</span><span class="pl-c1">Hidden</span><span class="pl-kos">]</span> <span class="pl-kos">}</span><span class="pl-kos">)</span>
|
|
<span class="pl-kos">[</span> <span class="pl-kos">[</span> <span class="pl-s">'Visible'</span><span class="pl-kos">,</span> <span class="pl-c1">0</span> <span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-kos">[</span> <span class="pl-s">'Hidden'</span><span class="pl-kos">,</span> <span class="pl-c1">1</span> <span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-kos">[</span> <span class="pl-s">'VeryHidden'</span><span class="pl-kos">,</span> <span class="pl-c1">2</span> <span class="pl-kos">]</span> <span class="pl-kos">]</span></pre></div>
|
|
<p>Non-Excel formats do not support the Very Hidden state. The best way to test
|
|
if a sheet is visible is to check if the <code>Hidden</code> property is logical truth:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-c1">></span> <span class="pl-s1">wb</span><span class="pl-kos">.</span><span class="pl-c1">Workbook</span><span class="pl-kos">.</span><span class="pl-c1">Sheets</span><span class="pl-kos">.</span><span class="pl-en">map</span><span class="pl-kos">(</span><span class="pl-k">function</span><span class="pl-kos">(</span><span class="pl-s1">x</span><span class="pl-kos">)</span> <span class="pl-kos">{</span> <span class="pl-k">return</span> <span class="pl-kos">[</span><span class="pl-s1">x</span><span class="pl-kos">.</span><span class="pl-c1">name</span><span class="pl-kos">,</span> <span class="pl-c1">!</span><span class="pl-s1">x</span><span class="pl-kos">.</span><span class="pl-c1">Hidden</span><span class="pl-kos">]</span> <span class="pl-kos">}</span><span class="pl-kos">)</span>
|
|
<span class="pl-kos">[</span> <span class="pl-kos">[</span> <span class="pl-s">'Visible'</span><span class="pl-kos">,</span> <span class="pl-c1">true</span> <span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-kos">[</span> <span class="pl-s">'Hidden'</span><span class="pl-kos">,</span> <span class="pl-c1">false</span> <span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-kos">[</span> <span class="pl-s">'VeryHidden'</span><span class="pl-kos">,</span> <span class="pl-c1">false</span> <span class="pl-kos">]</span> <span class="pl-kos">]</span></pre></div>
|
|
</details>
|
|
<h4>
|
|
<a id="user-content-vba-and-macros" class="anchor" href="#vba-and-macros" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>VBA and Macros</h4>
|
|
<p>VBA Macros are stored in a special data blob that is exposed in the <code>vbaraw</code>
|
|
property of the workbook object when the <code>bookVBA</code> option is <code>true</code>. They are
|
|
supported in <code>XLSM</code>, <code>XLSB</code>, and <code>BIFF8 XLS</code> formats. The supported format
|
|
writers automatically insert the data blobs if it is present in the workbook and
|
|
associate with the worksheet names.</p>
|
|
<details>
|
|
<summary><b>Custom Code Names</b> (click to show)</summary>
|
|
<p>The workbook code name is stored in <code>wb.Workbook.WBProps.CodeName</code>. By default,
|
|
Excel will write <code>ThisWorkbook</code> or a translated phrase like <code>DieseArbeitsmappe</code>.
|
|
Worksheet and Chartsheet code names are in the worksheet properties object at
|
|
<code>wb.Workbook.Sheets[i].CodeName</code>. Macrosheets and Dialogsheets are ignored.</p>
|
|
<p>The readers and writers preserve the code names, but they have to be manually
|
|
set when adding a VBA blob to a different workbook.</p>
|
|
</details>
|
|
<details>
|
|
<summary><b>Macrosheets</b> (click to show)</summary>
|
|
<p>Older versions of Excel also supported a non-VBA "macrosheet" sheet type that
|
|
stored automation commands. These are exposed in objects with the <code>!type</code>
|
|
property set to <code>"macro"</code>.</p>
|
|
</details>
|
|
<details>
|
|
<summary><b>Detecting macros in workbooks</b> (click to show)</summary>
|
|
<p>The <code>vbaraw</code> field will only be set if macros are present, so testing is simple:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">function</span> <span class="pl-en">wb_has_macro</span><span class="pl-kos">(</span><span class="pl-s1">wb</span><span class="pl-c">/*:workbook*/</span><span class="pl-kos">)</span><span class="pl-c">/*:boolean*/</span> <span class="pl-kos">{</span>
|
|
<span class="pl-k">if</span><span class="pl-kos">(</span><span class="pl-c1">!</span><span class="pl-c1">!</span><span class="pl-s1">wb</span><span class="pl-kos">.</span><span class="pl-c1">vbaraw</span><span class="pl-kos">)</span> <span class="pl-k">return</span> <span class="pl-c1">true</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">const</span> <span class="pl-s1">sheets</span> <span class="pl-c1">=</span> <span class="pl-s1">wb</span><span class="pl-kos">.</span><span class="pl-c1">SheetNames</span><span class="pl-kos">.</span><span class="pl-en">map</span><span class="pl-kos">(</span><span class="pl-kos">(</span><span class="pl-s1">n</span><span class="pl-kos">)</span> <span class="pl-c1">=></span> <span class="pl-s1">wb</span><span class="pl-kos">.</span><span class="pl-c1">Sheets</span><span class="pl-kos">[</span><span class="pl-s1">n</span><span class="pl-kos">]</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">return</span> <span class="pl-s1">sheets</span><span class="pl-kos">.</span><span class="pl-en">some</span><span class="pl-kos">(</span><span class="pl-kos">(</span><span class="pl-s1">ws</span><span class="pl-kos">)</span> <span class="pl-c1">=></span> <span class="pl-c1">!</span><span class="pl-c1">!</span><span class="pl-s1">ws</span> <span class="pl-c1">&&</span> <span class="pl-s1">ws</span><span class="pl-kos">[</span><span class="pl-s">'!type'</span><span class="pl-kos">]</span><span class="pl-c1">==</span><span class="pl-s">'macro'</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-kos">}</span></pre></div>
|
|
</details>
|
|
<h2>
|
|
<a id="user-content-parsing-options" class="anchor" href="#parsing-options" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Parsing Options</h2>
|
|
<p>The exported <code>read</code> and <code>readFile</code> functions accept an options argument:</p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th align="left">Option Name</th>
|
|
<th align="right">Default</th>
|
|
<th align="left">Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td align="left"><code>type</code></td>
|
|
<td align="right"></td>
|
|
<td align="left">Input data encoding (see Input Type below)</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>raw</code></td>
|
|
<td align="right">false</td>
|
|
<td align="left">If true, plain text parsing will not parse values **</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>codepage</code></td>
|
|
<td align="right"></td>
|
|
<td align="left">If specified, use code page when appropriate **</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>cellFormula</code></td>
|
|
<td align="right">true</td>
|
|
<td align="left">Save formulae to the .f field</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>cellHTML</code></td>
|
|
<td align="right">true</td>
|
|
<td align="left">Parse rich text and save HTML to the <code>.h</code> field</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>cellNF</code></td>
|
|
<td align="right">false</td>
|
|
<td align="left">Save number format string to the <code>.z</code> field</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>cellStyles</code></td>
|
|
<td align="right">false</td>
|
|
<td align="left">Save style/theme info to the <code>.s</code> field</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>cellText</code></td>
|
|
<td align="right">true</td>
|
|
<td align="left">Generated formatted text to the <code>.w</code> field</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>cellDates</code></td>
|
|
<td align="right">false</td>
|
|
<td align="left">Store dates as type <code>d</code> (default is <code>n</code>)</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>dateNF</code></td>
|
|
<td align="right"></td>
|
|
<td align="left">If specified, use the string for date code 14 **</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>sheetStubs</code></td>
|
|
<td align="right">false</td>
|
|
<td align="left">Create cell objects of type <code>z</code> for stub cells</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>sheetRows</code></td>
|
|
<td align="right">0</td>
|
|
<td align="left">If >0, read the first <code>sheetRows</code> rows **</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>bookDeps</code></td>
|
|
<td align="right">false</td>
|
|
<td align="left">If true, parse calculation chains</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>bookFiles</code></td>
|
|
<td align="right">false</td>
|
|
<td align="left">If true, add raw files to book object **</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>bookProps</code></td>
|
|
<td align="right">false</td>
|
|
<td align="left">If true, only parse enough to get book metadata **</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>bookSheets</code></td>
|
|
<td align="right">false</td>
|
|
<td align="left">If true, only parse enough to get the sheet names</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>bookVBA</code></td>
|
|
<td align="right">false</td>
|
|
<td align="left">If true, copy VBA blob to <code>vbaraw</code> field **</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>password</code></td>
|
|
<td align="right">""</td>
|
|
<td align="left">If defined and file is encrypted, use password **</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>WTF</code></td>
|
|
<td align="right">false</td>
|
|
<td align="left">If true, throw errors on unexpected file features **</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>sheets</code></td>
|
|
<td align="right"></td>
|
|
<td align="left">If specified, only parse specified sheets **</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>PRN</code></td>
|
|
<td align="right">false</td>
|
|
<td align="left">If true, allow parsing of PRN files **</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>xlfn</code></td>
|
|
<td align="right">false</td>
|
|
<td align="left">If true, preserve <code>_xlfn.</code> prefixes in formulae **</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>FS</code></td>
|
|
<td align="right"></td>
|
|
<td align="left">DSV Field Separator override</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<ul>
|
|
<li>Even if <code>cellNF</code> is false, formatted text will be generated and saved to <code>.w</code>
|
|
</li>
|
|
<li>In some cases, sheets may be parsed even if <code>bookSheets</code> is false.</li>
|
|
<li>Excel aggressively tries to interpret values from CSV and other plain text.
|
|
This leads to surprising behavior! The <code>raw</code> option suppresses value parsing.</li>
|
|
<li>
|
|
<code>bookSheets</code> and <code>bookProps</code> combine to give both sets of information</li>
|
|
<li>
|
|
<code>Deps</code> will be an empty object if <code>bookDeps</code> is false</li>
|
|
<li>
|
|
<code>bookFiles</code> behavior depends on file type:
|
|
<ul>
|
|
<li>
|
|
<code>keys</code> array (paths in the ZIP) for ZIP-based formats</li>
|
|
<li>
|
|
<code>files</code> hash (mapping paths to objects representing the files) for ZIP</li>
|
|
<li>
|
|
<code>cfb</code> object for formats using CFB containers</li>
|
|
</ul>
|
|
</li>
|
|
<li>
|
|
<code>sheetRows-1</code> rows will be generated when looking at the JSON object output
|
|
(since the header row is counted as a row when parsing the data)</li>
|
|
<li>By default all worksheets are parsed. <code>sheets</code> restricts based on input type:
|
|
<ul>
|
|
<li>number: zero-based index of worksheet to parse (<code>0</code> is first worksheet)</li>
|
|
<li>string: name of worksheet to parse (case insensitive)</li>
|
|
<li>array of numbers and strings to select multiple worksheets.</li>
|
|
</ul>
|
|
</li>
|
|
<li>
|
|
<code>bookVBA</code> merely exposes the raw VBA CFB object. It does not parse the data.
|
|
XLSM and XLSB store the VBA CFB object in <code>xl/vbaProject.bin</code>. BIFF8 XLS mixes
|
|
the VBA entries alongside the core Workbook entry, so the library generates a
|
|
new XLSB-compatible blob from the XLS CFB container.</li>
|
|
<li>
|
|
<code>codepage</code> is applied to BIFF2 - BIFF5 files without <code>CodePage</code> records and to
|
|
CSV files without BOM in <code>type:"binary"</code>. BIFF8 XLS always defaults to 1200.</li>
|
|
<li>
|
|
<code>PRN</code> affects parsing of text files without a common delimiter character.</li>
|
|
<li>Currently only XOR encryption is supported. Unsupported error will be thrown
|
|
for files employing other encryption methods.</li>
|
|
<li>Newer Excel functions are serialized with the <code>_xlfn.</code> prefix, hidden from the
|
|
user. SheetJS will strip <code>_xlfn.</code> normally. The <code>xlfn</code> option preserves them.</li>
|
|
<li>WTF is mainly for development. By default, the parser will suppress read
|
|
errors on single worksheets, allowing you to read from the worksheets that do
|
|
parse properly. Setting <code>WTF:true</code> forces those errors to be thrown.</li>
|
|
</ul>
|
|
<h3>
|
|
<a id="user-content-input-type" class="anchor" href="#input-type" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Input Type</h3>
|
|
<p>Strings can be interpreted in multiple ways. The <code>type</code> parameter for <code>read</code>
|
|
tells the library how to parse the data argument:</p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th><code>type</code></th>
|
|
<th>expected input</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><code>"base64"</code></td>
|
|
<td>string: Base64 encoding of the file</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>"binary"</code></td>
|
|
<td>string: binary string (byte <code>n</code> is <code>data.charCodeAt(n)</code>)</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>"string"</code></td>
|
|
<td>string: JS string (characters interpreted as UTF8)</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>"buffer"</code></td>
|
|
<td>nodejs Buffer</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>"array"</code></td>
|
|
<td>array: array of 8-bit unsigned int (byte <code>n</code> is <code>data[n]</code>)</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>"file"</code></td>
|
|
<td>string: path of file that will be read (nodejs only)</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<h3>
|
|
<a id="user-content-guessing-file-type" class="anchor" href="#guessing-file-type" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Guessing File Type</h3>
|
|
<details>
|
|
<summary><b>Implementation Details</b> (click to show)</summary>
|
|
<p>Excel and other spreadsheet tools read the first few bytes and apply other
|
|
heuristics to determine a file type. This enables file type punning: renaming
|
|
files with the <code>.xls</code> extension will tell your computer to use Excel to open the
|
|
file but Excel will know how to handle it. This library applies similar logic:</p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th align="left">Byte 0</th>
|
|
<th align="left">Raw File Type</th>
|
|
<th align="left">Spreadsheet Types</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td align="left"><code>0xD0</code></td>
|
|
<td align="left">CFB Container</td>
|
|
<td align="left">BIFF 5/8 or protected XLSX/XLSB or WQ3/QPW or XLR</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>0x09</code></td>
|
|
<td align="left">BIFF Stream</td>
|
|
<td align="left">BIFF 2/3/4/5</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>0x3C</code></td>
|
|
<td align="left">XML/HTML</td>
|
|
<td align="left">SpreadsheetML / Flat ODS / UOS1 / HTML / plain text</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>0x50</code></td>
|
|
<td align="left">ZIP Archive</td>
|
|
<td align="left">XLSB or XLSX/M or ODS or UOS2 or NUMBERS or text</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>0x49</code></td>
|
|
<td align="left">Plain Text</td>
|
|
<td align="left">SYLK or plain text</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>0x54</code></td>
|
|
<td align="left">Plain Text</td>
|
|
<td align="left">DIF or plain text</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>0xEF</code></td>
|
|
<td align="left">UTF8 Encoded</td>
|
|
<td align="left">SpreadsheetML / Flat ODS / UOS1 / HTML / plain text</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>0xFF</code></td>
|
|
<td align="left">UTF16 Encoded</td>
|
|
<td align="left">SpreadsheetML / Flat ODS / UOS1 / HTML / plain text</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>0x00</code></td>
|
|
<td align="left">Record Stream</td>
|
|
<td align="left">Lotus WK* or Quattro Pro or plain text</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>0x7B</code></td>
|
|
<td align="left">Plain text</td>
|
|
<td align="left">RTF or plain text</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>0x0A</code></td>
|
|
<td align="left">Plain text</td>
|
|
<td align="left">SpreadsheetML / Flat ODS / UOS1 / HTML / plain text</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>0x0D</code></td>
|
|
<td align="left">Plain text</td>
|
|
<td align="left">SpreadsheetML / Flat ODS / UOS1 / HTML / plain text</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>0x20</code></td>
|
|
<td align="left">Plain text</td>
|
|
<td align="left">SpreadsheetML / Flat ODS / UOS1 / HTML / plain text</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>DBF files are detected based on the first byte as well as the third and fourth
|
|
bytes (corresponding to month and day of the file date)</p>
|
|
<p>Works for Windows files are detected based on the BOF record with type <code>0xFF</code></p>
|
|
<p>Plain text format guessing follows the priority order:</p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th align="left">Format</th>
|
|
<th align="left">Test</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td align="left">XML</td>
|
|
<td align="left">
|
|
<code><?xml</code> appears in the first 1024 characters</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">HTML</td>
|
|
<td align="left">starts with <code><</code> and HTML tags appear in the first 1024 characters *</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">XML</td>
|
|
<td align="left">starts with <code><</code> and the first tag is valid</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">RTF</td>
|
|
<td align="left">starts with <code>{\rt</code>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">DSV</td>
|
|
<td align="left">starts with <code>/sep=.$/</code>, separator is the specified character</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">DSV</td>
|
|
<td align="left">more unquoted `</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">DSV</td>
|
|
<td align="left">more unquoted <code>;</code> chars than <code>\t</code> or <code>,</code> in the first 1024</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">TSV</td>
|
|
<td align="left">more unquoted <code>\t</code> chars than <code>,</code> chars in the first 1024</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">CSV</td>
|
|
<td align="left">one of the first 1024 characters is a comma <code>","</code>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">ETH</td>
|
|
<td align="left">starts with <code>socialcalc:version:</code>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">PRN</td>
|
|
<td align="left">
|
|
<code>PRN</code> option is set to true</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">CSV</td>
|
|
<td align="left">(fallback)</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<ul>
|
|
<li>HTML tags include: <code>html</code>, <code>table</code>, <code>head</code>, <code>meta</code>, <code>script</code>, <code>style</code>, <code>div</code>
|
|
</li>
|
|
</ul>
|
|
</details>
|
|
<details>
|
|
<summary><b>Why are random text files valid?</b> (click to show)</summary>
|
|
<p>Excel is extremely aggressive in reading files. Adding an XLS extension to any
|
|
display text file (where the only characters are ANSI display chars) tricks
|
|
Excel into thinking that the file is potentially a CSV or TSV file, even if it
|
|
is only one column! This library attempts to replicate that behavior.</p>
|
|
<p>The best approach is to validate the desired worksheet and ensure it has the
|
|
expected number of rows or columns. Extracting the range is extremely simple:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> <span class="pl-s1">range</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">decode_range</span><span class="pl-kos">(</span><span class="pl-s1">worksheet</span><span class="pl-kos">[</span><span class="pl-s">'!ref'</span><span class="pl-kos">]</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">ncols</span> <span class="pl-c1">=</span> <span class="pl-s1">range</span><span class="pl-kos">.</span><span class="pl-c1">e</span><span class="pl-kos">.</span><span class="pl-c1">c</span> <span class="pl-c1">-</span> <span class="pl-s1">range</span><span class="pl-kos">.</span><span class="pl-c1">s</span><span class="pl-kos">.</span><span class="pl-c1">c</span> <span class="pl-c1">+</span> <span class="pl-c1">1</span><span class="pl-kos">,</span> <span class="pl-s1">nrows</span> <span class="pl-c1">=</span> <span class="pl-s1">range</span><span class="pl-kos">.</span><span class="pl-c1">e</span><span class="pl-kos">.</span><span class="pl-c1">r</span> <span class="pl-c1">-</span> <span class="pl-s1">range</span><span class="pl-kos">.</span><span class="pl-c1">s</span><span class="pl-kos">.</span><span class="pl-c1">r</span> <span class="pl-c1">+</span> <span class="pl-c1">1</span><span class="pl-kos">;</span></pre></div>
|
|
</details>
|
|
<h2>
|
|
<a id="user-content-writing-options" class="anchor" href="#writing-options" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Writing Options</h2>
|
|
<p>The exported <code>write</code> and <code>writeFile</code> functions accept an options argument:</p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th align="left">Option Name</th>
|
|
<th align="right">Default</th>
|
|
<th align="left">Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td align="left"><code>type</code></td>
|
|
<td align="right"></td>
|
|
<td align="left">Output data encoding (see Output Type below)</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>cellDates</code></td>
|
|
<td align="right"><code>false</code></td>
|
|
<td align="left">Store dates as type <code>d</code> (default is <code>n</code>)</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>bookSST</code></td>
|
|
<td align="right"><code>false</code></td>
|
|
<td align="left">Generate Shared String Table **</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>bookType</code></td>
|
|
<td align="right"><code>"xlsx"</code></td>
|
|
<td align="left">Type of Workbook (see below for supported formats)</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>sheet</code></td>
|
|
<td align="right"><code>""</code></td>
|
|
<td align="left">Name of Worksheet for single-sheet formats **</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>compression</code></td>
|
|
<td align="right"><code>false</code></td>
|
|
<td align="left">Use ZIP compression for ZIP-based formats **</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>Props</code></td>
|
|
<td align="right"></td>
|
|
<td align="left">Override workbook properties when writing **</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>themeXLSX</code></td>
|
|
<td align="right"></td>
|
|
<td align="left">Override theme XML when writing XLSX/XLSB/XLSM **</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>ignoreEC</code></td>
|
|
<td align="right"><code>true</code></td>
|
|
<td align="left">Suppress "number as text" errors **</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>numbers</code></td>
|
|
<td align="right"></td>
|
|
<td align="left">Payload for NUMBERS export **</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<ul>
|
|
<li>
|
|
<code>bookSST</code> is slower and more memory intensive, but has better compatibility
|
|
with older versions of iOS Numbers</li>
|
|
<li>The raw data is the only thing guaranteed to be saved. Features not described
|
|
in this README may not be serialized.</li>
|
|
<li>
|
|
<code>cellDates</code> only applies to XLSX output and is not guaranteed to work with
|
|
third-party readers. Excel itself does not usually write cells with type <code>d</code>
|
|
so non-Excel tools may ignore the data or error in the presence of dates.</li>
|
|
<li>
|
|
<code>Props</code> is an object mirroring the workbook <code>Props</code> field. See the table from
|
|
the <a href="#workbook-file-properties">Workbook File Properties</a> section.</li>
|
|
<li>if specified, the string from <code>themeXLSX</code> will be saved as the primary theme
|
|
for XLSX/XLSB/XLSM files (to <code>xl/theme/theme1.xml</code> in the ZIP)</li>
|
|
<li>Due to a bug in the program, some features like "Text to Columns" will crash
|
|
Excel on worksheets where error conditions are ignored. The writer will mark
|
|
files to ignore the error by default. Set <code>ignoreEC</code> to <code>false</code> to suppress.</li>
|
|
<li>Due to the size of the data, the NUMBERS data is not included by default. The
|
|
included <code>xlsx.zahl.js</code> and <code>xlsx.zahl.mjs</code> scripts include the data.</li>
|
|
</ul>
|
|
<h3>
|
|
<a id="user-content-supported-output-formats" class="anchor" href="#supported-output-formats" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Supported Output Formats</h3>
|
|
<p>For broad compatibility with third-party tools, this library supports many
|
|
output formats. The specific file type is controlled with <code>bookType</code> option:</p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th align="left"><code>bookType</code></th>
|
|
<th align="right">file ext</th>
|
|
<th align="center">container</th>
|
|
<th align="left">sheets</th>
|
|
<th align="left">Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td align="left"><code>xlsx</code></td>
|
|
<td align="right"><code>.xlsx</code></td>
|
|
<td align="center">ZIP</td>
|
|
<td align="left">multi</td>
|
|
<td align="left">Excel 2007+ XML Format</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>xlsm</code></td>
|
|
<td align="right"><code>.xlsm</code></td>
|
|
<td align="center">ZIP</td>
|
|
<td align="left">multi</td>
|
|
<td align="left">Excel 2007+ Macro XML Format</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>xlsb</code></td>
|
|
<td align="right"><code>.xlsb</code></td>
|
|
<td align="center">ZIP</td>
|
|
<td align="left">multi</td>
|
|
<td align="left">Excel 2007+ Binary Format</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>biff8</code></td>
|
|
<td align="right"><code>.xls</code></td>
|
|
<td align="center">CFB</td>
|
|
<td align="left">multi</td>
|
|
<td align="left">Excel 97-2004 Workbook Format</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>biff5</code></td>
|
|
<td align="right"><code>.xls</code></td>
|
|
<td align="center">CFB</td>
|
|
<td align="left">multi</td>
|
|
<td align="left">Excel 5.0/95 Workbook Format</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>biff4</code></td>
|
|
<td align="right"><code>.xls</code></td>
|
|
<td align="center">none</td>
|
|
<td align="left">single</td>
|
|
<td align="left">Excel 4.0 Worksheet Format</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>biff3</code></td>
|
|
<td align="right"><code>.xls</code></td>
|
|
<td align="center">none</td>
|
|
<td align="left">single</td>
|
|
<td align="left">Excel 3.0 Worksheet Format</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>biff2</code></td>
|
|
<td align="right"><code>.xls</code></td>
|
|
<td align="center">none</td>
|
|
<td align="left">single</td>
|
|
<td align="left">Excel 2.0 Worksheet Format</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>xlml</code></td>
|
|
<td align="right"><code>.xls</code></td>
|
|
<td align="center">none</td>
|
|
<td align="left">multi</td>
|
|
<td align="left">Excel 2003-2004 (SpreadsheetML)</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>numbers</code></td>
|
|
<td align="right"><code>.numbers</code></td>
|
|
<td align="center">ZIP</td>
|
|
<td align="left">single</td>
|
|
<td align="left">Numbers 3.0+ Spreadsheet</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>ods</code></td>
|
|
<td align="right"><code>.ods</code></td>
|
|
<td align="center">ZIP</td>
|
|
<td align="left">multi</td>
|
|
<td align="left">OpenDocument Spreadsheet</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>fods</code></td>
|
|
<td align="right"><code>.fods</code></td>
|
|
<td align="center">none</td>
|
|
<td align="left">multi</td>
|
|
<td align="left">Flat OpenDocument Spreadsheet</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>wk3</code></td>
|
|
<td align="right"><code>.wk3</code></td>
|
|
<td align="center">none</td>
|
|
<td align="left">multi</td>
|
|
<td align="left">Lotus Workbook (WK3)</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>csv</code></td>
|
|
<td align="right"><code>.csv</code></td>
|
|
<td align="center">none</td>
|
|
<td align="left">single</td>
|
|
<td align="left">Comma Separated Values</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>txt</code></td>
|
|
<td align="right"><code>.txt</code></td>
|
|
<td align="center">none</td>
|
|
<td align="left">single</td>
|
|
<td align="left">UTF-16 Unicode Text (TXT)</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>sylk</code></td>
|
|
<td align="right"><code>.sylk</code></td>
|
|
<td align="center">none</td>
|
|
<td align="left">single</td>
|
|
<td align="left">Symbolic Link (SYLK)</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>html</code></td>
|
|
<td align="right"><code>.html</code></td>
|
|
<td align="center">none</td>
|
|
<td align="left">single</td>
|
|
<td align="left">HTML Document</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>dif</code></td>
|
|
<td align="right"><code>.dif</code></td>
|
|
<td align="center">none</td>
|
|
<td align="left">single</td>
|
|
<td align="left">Data Interchange Format (DIF)</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>dbf</code></td>
|
|
<td align="right"><code>.dbf</code></td>
|
|
<td align="center">none</td>
|
|
<td align="left">single</td>
|
|
<td align="left">dBASE II + VFP Extensions (DBF)</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>wk1</code></td>
|
|
<td align="right"><code>.wk1</code></td>
|
|
<td align="center">none</td>
|
|
<td align="left">single</td>
|
|
<td align="left">Lotus Worksheet (WK1)</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>rtf</code></td>
|
|
<td align="right"><code>.rtf</code></td>
|
|
<td align="center">none</td>
|
|
<td align="left">single</td>
|
|
<td align="left">Rich Text Format (RTF)</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>prn</code></td>
|
|
<td align="right"><code>.prn</code></td>
|
|
<td align="center">none</td>
|
|
<td align="left">single</td>
|
|
<td align="left">Lotus Formatted Text</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>eth</code></td>
|
|
<td align="right"><code>.eth</code></td>
|
|
<td align="center">none</td>
|
|
<td align="left">single</td>
|
|
<td align="left">Ethercalc Record Format (ETH)</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<ul>
|
|
<li>
|
|
<code>compression</code> only applies to formats with ZIP containers.</li>
|
|
<li>Formats that only support a single sheet require a <code>sheet</code> option specifying
|
|
the worksheet. If the string is empty, the first worksheet is used.</li>
|
|
<li>
|
|
<code>writeFile</code> will automatically guess the output file format based on the file
|
|
extension if <code>bookType</code> is not specified. It will choose the first format in
|
|
the aforementioned table that matches the extension.</li>
|
|
</ul>
|
|
<h3>
|
|
<a id="user-content-output-type" class="anchor" href="#output-type" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Output Type</h3>
|
|
<p>The <code>type</code> argument for <code>write</code> mirrors the <code>type</code> argument for <code>read</code>:</p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th><code>type</code></th>
|
|
<th>output</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><code>"base64"</code></td>
|
|
<td>string: Base64 encoding of the file</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>"binary"</code></td>
|
|
<td>string: binary string (byte <code>n</code> is <code>data.charCodeAt(n)</code>)</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>"string"</code></td>
|
|
<td>string: JS string (characters interpreted as UTF8)</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>"buffer"</code></td>
|
|
<td>nodejs Buffer</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>"array"</code></td>
|
|
<td>ArrayBuffer, fallback array of 8-bit unsigned int</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>"file"</code></td>
|
|
<td>string: path of file that will be created (nodejs only)</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<ul>
|
|
<li>For compatibility with Excel, <code>csv</code> output will always include the UTF-8 byte
|
|
order mark.</li>
|
|
</ul>
|
|
<h2>
|
|
<a id="user-content-utility-functions" class="anchor" href="#utility-functions" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Utility Functions</h2>
|
|
<p>The <code>sheet_to_*</code> functions accept a worksheet and an optional options object.</p>
|
|
<p>The <code>*_to_sheet</code> functions accept a data object and an optional options object.</p>
|
|
<p>The examples are based on the following worksheet:</p>
|
|
<pre><code>XXX| A | B | C | D | E | F | G |
|
|
---+---+---+---+---+---+---+---+
|
|
1 | S | h | e | e | t | J | S |
|
|
2 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|
|
3 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
|
|
</code></pre>
|
|
<h3>
|
|
<a id="user-content-array-of-arrays-input" class="anchor" href="#array-of-arrays-input" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Array of Arrays Input</h3>
|
|
<p><code>XLSX.utils.aoa_to_sheet</code> takes an array of arrays of JS values and returns a
|
|
worksheet resembling the input data. Numbers, Booleans and Strings are stored
|
|
as the corresponding styles. Dates are stored as date or numbers. Array holes
|
|
and explicit <code>undefined</code> values are skipped. <code>null</code> values may be stubbed. All
|
|
other values are stored as strings. The function takes an options argument:</p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th align="left">Option Name</th>
|
|
<th align="center">Default</th>
|
|
<th align="left">Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td align="left"><code>dateNF</code></td>
|
|
<td align="center">FMT 14</td>
|
|
<td align="left">Use specified date format in string output</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>cellDates</code></td>
|
|
<td align="center">false</td>
|
|
<td align="left">Store dates as type <code>d</code> (default is <code>n</code>)</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>sheetStubs</code></td>
|
|
<td align="center">false</td>
|
|
<td align="left">Create cell objects of type <code>z</code> for <code>null</code> values</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>nullError</code></td>
|
|
<td align="center">false</td>
|
|
<td align="left">If true, emit <code>#NULL!</code> error cells for <code>null</code> values</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<details>
|
|
<summary><b>Examples</b> (click to show)</summary>
|
|
<p>To generate the example sheet:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> <span class="pl-s1">ws</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">aoa_to_sheet</span><span class="pl-kos">(</span><span class="pl-kos">[</span>
|
|
<span class="pl-s">"SheetJS"</span><span class="pl-kos">.</span><span class="pl-en">split</span><span class="pl-kos">(</span><span class="pl-s">""</span><span class="pl-kos">)</span><span class="pl-kos">,</span>
|
|
<span class="pl-kos">[</span><span class="pl-c1">1</span><span class="pl-kos">,</span><span class="pl-c1">2</span><span class="pl-kos">,</span><span class="pl-c1">3</span><span class="pl-kos">,</span><span class="pl-c1">4</span><span class="pl-kos">,</span><span class="pl-c1">5</span><span class="pl-kos">,</span><span class="pl-c1">6</span><span class="pl-kos">,</span><span class="pl-c1">7</span><span class="pl-kos">]</span><span class="pl-kos">,</span>
|
|
<span class="pl-kos">[</span><span class="pl-c1">2</span><span class="pl-kos">,</span><span class="pl-c1">3</span><span class="pl-kos">,</span><span class="pl-c1">4</span><span class="pl-kos">,</span><span class="pl-c1">5</span><span class="pl-kos">,</span><span class="pl-c1">6</span><span class="pl-kos">,</span><span class="pl-c1">7</span><span class="pl-kos">,</span><span class="pl-c1">8</span><span class="pl-kos">]</span>
|
|
<span class="pl-kos">]</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
</details>
|
|
<p><code>XLSX.utils.sheet_add_aoa</code> takes an array of arrays of JS values and updates an
|
|
existing worksheet object. It follows the same process as <code>aoa_to_sheet</code> and
|
|
accepts an options argument:</p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th align="left">Option Name</th>
|
|
<th align="center">Default</th>
|
|
<th align="left">Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td align="left"><code>dateNF</code></td>
|
|
<td align="center">FMT 14</td>
|
|
<td align="left">Use specified date format in string output</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>cellDates</code></td>
|
|
<td align="center">false</td>
|
|
<td align="left">Store dates as type <code>d</code> (default is <code>n</code>)</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>sheetStubs</code></td>
|
|
<td align="center">false</td>
|
|
<td align="left">Create cell objects of type <code>z</code> for <code>null</code> values</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>nullError</code></td>
|
|
<td align="center">false</td>
|
|
<td align="left">If true, emit <code>#NULL!</code> error cells for <code>null</code> values</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>origin</code></td>
|
|
<td align="center"></td>
|
|
<td align="left">Use specified cell as starting point (see below)</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><code>origin</code> is expected to be one of:</p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th align="left"><code>origin</code></th>
|
|
<th align="left">Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td align="left">(cell object)</td>
|
|
<td align="left">Use specified cell (cell object)</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">(string)</td>
|
|
<td align="left">Use specified cell (A1-style cell)</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">(number >= 0)</td>
|
|
<td align="left">Start from the first column at specified row (0-indexed)</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">-1</td>
|
|
<td align="left">Append to bottom of worksheet starting on first column</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">(default)</td>
|
|
<td align="left">Start from cell A1</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<details>
|
|
<summary><b>Examples</b> (click to show)</summary>
|
|
<p>Consider the worksheet:</p>
|
|
<pre><code>XXX| A | B | C | D | E | F | G |
|
|
---+---+---+---+---+---+---+---+
|
|
1 | S | h | e | e | t | J | S |
|
|
2 | 1 | 2 | | | 5 | 6 | 7 |
|
|
3 | 2 | 3 | | | 6 | 7 | 8 |
|
|
4 | 3 | 4 | | | 7 | 8 | 9 |
|
|
5 | 4 | 5 | 6 | 7 | 8 | 9 | 0 |
|
|
</code></pre>
|
|
<p>This worksheet can be built up in the order <code>A1:G1, A2:B4, E2:G4, A5:G5</code>:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-c">/* Initial row */</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">ws</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">aoa_to_sheet</span><span class="pl-kos">(</span><span class="pl-kos">[</span> <span class="pl-s">"SheetJS"</span><span class="pl-kos">.</span><span class="pl-en">split</span><span class="pl-kos">(</span><span class="pl-s">""</span><span class="pl-kos">)</span> <span class="pl-kos">]</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* Write data starting at A2 */</span>
|
|
<span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">sheet_add_aoa</span><span class="pl-kos">(</span><span class="pl-s1">ws</span><span class="pl-kos">,</span> <span class="pl-kos">[</span><span class="pl-kos">[</span><span class="pl-c1">1</span><span class="pl-kos">,</span><span class="pl-c1">2</span><span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-kos">[</span><span class="pl-c1">2</span><span class="pl-kos">,</span><span class="pl-c1">3</span><span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-kos">[</span><span class="pl-c1">3</span><span class="pl-kos">,</span><span class="pl-c1">4</span><span class="pl-kos">]</span><span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-kos">{</span><span class="pl-c1">origin</span>: <span class="pl-s">"A2"</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* Write data starting at E2 */</span>
|
|
<span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">sheet_add_aoa</span><span class="pl-kos">(</span><span class="pl-s1">ws</span><span class="pl-kos">,</span> <span class="pl-kos">[</span><span class="pl-kos">[</span><span class="pl-c1">5</span><span class="pl-kos">,</span><span class="pl-c1">6</span><span class="pl-kos">,</span><span class="pl-c1">7</span><span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-kos">[</span><span class="pl-c1">6</span><span class="pl-kos">,</span><span class="pl-c1">7</span><span class="pl-kos">,</span><span class="pl-c1">8</span><span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-kos">[</span><span class="pl-c1">7</span><span class="pl-kos">,</span><span class="pl-c1">8</span><span class="pl-kos">,</span><span class="pl-c1">9</span><span class="pl-kos">]</span><span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-kos">{</span><span class="pl-c1">origin</span>:<span class="pl-kos">{</span><span class="pl-c1">r</span>:<span class="pl-c1">1</span><span class="pl-kos">,</span> <span class="pl-c1">c</span>:<span class="pl-c1">4</span><span class="pl-kos">}</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* Append row */</span>
|
|
<span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">sheet_add_aoa</span><span class="pl-kos">(</span><span class="pl-s1">ws</span><span class="pl-kos">,</span> <span class="pl-kos">[</span><span class="pl-kos">[</span><span class="pl-c1">4</span><span class="pl-kos">,</span><span class="pl-c1">5</span><span class="pl-kos">,</span><span class="pl-c1">6</span><span class="pl-kos">,</span><span class="pl-c1">7</span><span class="pl-kos">,</span><span class="pl-c1">8</span><span class="pl-kos">,</span><span class="pl-c1">9</span><span class="pl-kos">,</span><span class="pl-c1">0</span><span class="pl-kos">]</span><span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-kos">{</span><span class="pl-c1">origin</span>: <span class="pl-c1">-</span><span class="pl-c1">1</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
</details>
|
|
<h3>
|
|
<a id="user-content-array-of-objects-input" class="anchor" href="#array-of-objects-input" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Array of Objects Input</h3>
|
|
<p><code>XLSX.utils.json_to_sheet</code> takes an array of objects and returns a worksheet
|
|
with automatically-generated "headers" based on the keys of the objects. The
|
|
default column order is determined by the first appearance of the field using
|
|
<code>Object.keys</code>. The function accepts an options argument:</p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th align="left">Option Name</th>
|
|
<th align="center">Default</th>
|
|
<th align="left">Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td align="left"><code>header</code></td>
|
|
<td align="center"></td>
|
|
<td align="left">Use specified field order (default <code>Object.keys</code>) **</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>dateNF</code></td>
|
|
<td align="center">FMT 14</td>
|
|
<td align="left">Use specified date format in string output</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>cellDates</code></td>
|
|
<td align="center">false</td>
|
|
<td align="left">Store dates as type <code>d</code> (default is <code>n</code>)</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>skipHeader</code></td>
|
|
<td align="center">false</td>
|
|
<td align="left">If true, do not include header row in output</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>nullError</code></td>
|
|
<td align="center">false</td>
|
|
<td align="left">If true, emit <code>#NULL!</code> error cells for <code>null</code> values</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<ul>
|
|
<li>All fields from each row will be written. If <code>header</code> is an array and it does
|
|
not contain a particular field, the key will be appended to the array.</li>
|
|
<li>Cell types are deduced from the type of each value. For example, a <code>Date</code>
|
|
object will generate a Date cell, while a string will generate a Text cell.</li>
|
|
<li>Null values will be skipped by default. If <code>nullError</code> is true, an error cell
|
|
corresponding to <code>#NULL!</code> will be written to the worksheet.</li>
|
|
</ul>
|
|
<details>
|
|
<summary><b>Examples</b> (click to show)</summary>
|
|
<p>The original sheet cannot be reproduced using plain objects since JS object keys
|
|
must be unique. After replacing the second <code>e</code> and <code>S</code> with <code>e_1</code> and <code>S_1</code>:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> <span class="pl-s1">ws</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">json_to_sheet</span><span class="pl-kos">(</span><span class="pl-kos">[</span>
|
|
<span class="pl-kos">{</span> <span class="pl-c1">S</span>:<span class="pl-c1">1</span><span class="pl-kos">,</span> <span class="pl-c1">h</span>:<span class="pl-c1">2</span><span class="pl-kos">,</span> <span class="pl-c1">e</span>:<span class="pl-c1">3</span><span class="pl-kos">,</span> <span class="pl-c1">e_1</span>:<span class="pl-c1">4</span><span class="pl-kos">,</span> <span class="pl-c1">t</span>:<span class="pl-c1">5</span><span class="pl-kos">,</span> <span class="pl-c1">J</span>:<span class="pl-c1">6</span><span class="pl-kos">,</span> <span class="pl-c1">S_1</span>:<span class="pl-c1">7</span> <span class="pl-kos">}</span><span class="pl-kos">,</span>
|
|
<span class="pl-kos">{</span> <span class="pl-c1">S</span>:<span class="pl-c1">2</span><span class="pl-kos">,</span> <span class="pl-c1">h</span>:<span class="pl-c1">3</span><span class="pl-kos">,</span> <span class="pl-c1">e</span>:<span class="pl-c1">4</span><span class="pl-kos">,</span> <span class="pl-c1">e_1</span>:<span class="pl-c1">5</span><span class="pl-kos">,</span> <span class="pl-c1">t</span>:<span class="pl-c1">6</span><span class="pl-kos">,</span> <span class="pl-c1">J</span>:<span class="pl-c1">7</span><span class="pl-kos">,</span> <span class="pl-c1">S_1</span>:<span class="pl-c1">8</span> <span class="pl-kos">}</span>
|
|
<span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-kos">{</span><span class="pl-c1">header</span>:<span class="pl-kos">[</span><span class="pl-s">"S"</span><span class="pl-kos">,</span><span class="pl-s">"h"</span><span class="pl-kos">,</span><span class="pl-s">"e"</span><span class="pl-kos">,</span><span class="pl-s">"e_1"</span><span class="pl-kos">,</span><span class="pl-s">"t"</span><span class="pl-kos">,</span><span class="pl-s">"J"</span><span class="pl-kos">,</span><span class="pl-s">"S_1"</span><span class="pl-kos">]</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
<p>Alternatively, the header row can be skipped:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> <span class="pl-s1">ws</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">json_to_sheet</span><span class="pl-kos">(</span><span class="pl-kos">[</span>
|
|
<span class="pl-kos">{</span> <span class="pl-c1">A</span>:<span class="pl-s">"S"</span><span class="pl-kos">,</span> <span class="pl-c1">B</span>:<span class="pl-s">"h"</span><span class="pl-kos">,</span> <span class="pl-c1">C</span>:<span class="pl-s">"e"</span><span class="pl-kos">,</span> <span class="pl-c1">D</span>:<span class="pl-s">"e"</span><span class="pl-kos">,</span> <span class="pl-c1">E</span>:<span class="pl-s">"t"</span><span class="pl-kos">,</span> <span class="pl-c1">F</span>:<span class="pl-s">"J"</span><span class="pl-kos">,</span> <span class="pl-c1">G</span>:<span class="pl-s">"S"</span> <span class="pl-kos">}</span><span class="pl-kos">,</span>
|
|
<span class="pl-kos">{</span> <span class="pl-c1">A</span>: <span class="pl-c1">1</span><span class="pl-kos">,</span> <span class="pl-c1">B</span>: <span class="pl-c1">2</span><span class="pl-kos">,</span> <span class="pl-c1">C</span>: <span class="pl-c1">3</span><span class="pl-kos">,</span> <span class="pl-c1">D</span>: <span class="pl-c1">4</span><span class="pl-kos">,</span> <span class="pl-c1">E</span>: <span class="pl-c1">5</span><span class="pl-kos">,</span> <span class="pl-c1">F</span>: <span class="pl-c1">6</span><span class="pl-kos">,</span> <span class="pl-c1">G</span>: <span class="pl-c1">7</span> <span class="pl-kos">}</span><span class="pl-kos">,</span>
|
|
<span class="pl-kos">{</span> <span class="pl-c1">A</span>: <span class="pl-c1">2</span><span class="pl-kos">,</span> <span class="pl-c1">B</span>: <span class="pl-c1">3</span><span class="pl-kos">,</span> <span class="pl-c1">C</span>: <span class="pl-c1">4</span><span class="pl-kos">,</span> <span class="pl-c1">D</span>: <span class="pl-c1">5</span><span class="pl-kos">,</span> <span class="pl-c1">E</span>: <span class="pl-c1">6</span><span class="pl-kos">,</span> <span class="pl-c1">F</span>: <span class="pl-c1">7</span><span class="pl-kos">,</span> <span class="pl-c1">G</span>: <span class="pl-c1">8</span> <span class="pl-kos">}</span>
|
|
<span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-kos">{</span><span class="pl-c1">header</span>:<span class="pl-kos">[</span><span class="pl-s">"A"</span><span class="pl-kos">,</span><span class="pl-s">"B"</span><span class="pl-kos">,</span><span class="pl-s">"C"</span><span class="pl-kos">,</span><span class="pl-s">"D"</span><span class="pl-kos">,</span><span class="pl-s">"E"</span><span class="pl-kos">,</span><span class="pl-s">"F"</span><span class="pl-kos">,</span><span class="pl-s">"G"</span><span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-c1">skipHeader</span>:<span class="pl-c1">true</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
</details>
|
|
<p><code>XLSX.utils.sheet_add_json</code> takes an array of objects and updates an existing
|
|
worksheet object. It follows the same process as <code>json_to_sheet</code> and accepts
|
|
an options argument:</p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th align="left">Option Name</th>
|
|
<th align="center">Default</th>
|
|
<th align="left">Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td align="left"><code>header</code></td>
|
|
<td align="center"></td>
|
|
<td align="left">Use specified column order (default <code>Object.keys</code>)</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>dateNF</code></td>
|
|
<td align="center">FMT 14</td>
|
|
<td align="left">Use specified date format in string output</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>cellDates</code></td>
|
|
<td align="center">false</td>
|
|
<td align="left">Store dates as type <code>d</code> (default is <code>n</code>)</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>skipHeader</code></td>
|
|
<td align="center">false</td>
|
|
<td align="left">If true, do not include header row in output</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>nullError</code></td>
|
|
<td align="center">false</td>
|
|
<td align="left">If true, emit <code>#NULL!</code> error cells for <code>null</code> values</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>origin</code></td>
|
|
<td align="center"></td>
|
|
<td align="left">Use specified cell as starting point (see below)</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><code>origin</code> is expected to be one of:</p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th align="left"><code>origin</code></th>
|
|
<th align="left">Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td align="left">(cell object)</td>
|
|
<td align="left">Use specified cell (cell object)</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">(string)</td>
|
|
<td align="left">Use specified cell (A1-style cell)</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">(number >= 0)</td>
|
|
<td align="left">Start from the first column at specified row (0-indexed)</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">-1</td>
|
|
<td align="left">Append to bottom of worksheet starting on first column</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">(default)</td>
|
|
<td align="left">Start from cell A1</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<details>
|
|
<summary><b>Examples</b> (click to show)</summary>
|
|
<p>Consider the worksheet:</p>
|
|
<pre><code>XXX| A | B | C | D | E | F | G |
|
|
---+---+---+---+---+---+---+---+
|
|
1 | S | h | e | e | t | J | S |
|
|
2 | 1 | 2 | | | 5 | 6 | 7 |
|
|
3 | 2 | 3 | | | 6 | 7 | 8 |
|
|
4 | 3 | 4 | | | 7 | 8 | 9 |
|
|
5 | 4 | 5 | 6 | 7 | 8 | 9 | 0 |
|
|
</code></pre>
|
|
<p>This worksheet can be built up in the order <code>A1:G1, A2:B4, E2:G4, A5:G5</code>:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-c">/* Initial row */</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">ws</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">json_to_sheet</span><span class="pl-kos">(</span><span class="pl-kos">[</span>
|
|
<span class="pl-kos">{</span> <span class="pl-c1">A</span>: <span class="pl-s">"S"</span><span class="pl-kos">,</span> <span class="pl-c1">B</span>: <span class="pl-s">"h"</span><span class="pl-kos">,</span> <span class="pl-c1">C</span>: <span class="pl-s">"e"</span><span class="pl-kos">,</span> <span class="pl-c1">D</span>: <span class="pl-s">"e"</span><span class="pl-kos">,</span> <span class="pl-c1">E</span>: <span class="pl-s">"t"</span><span class="pl-kos">,</span> <span class="pl-c1">F</span>: <span class="pl-s">"J"</span><span class="pl-kos">,</span> <span class="pl-c1">G</span>: <span class="pl-s">"S"</span> <span class="pl-kos">}</span>
|
|
<span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-kos">{</span><span class="pl-c1">header</span>: <span class="pl-kos">[</span><span class="pl-s">"A"</span><span class="pl-kos">,</span> <span class="pl-s">"B"</span><span class="pl-kos">,</span> <span class="pl-s">"C"</span><span class="pl-kos">,</span> <span class="pl-s">"D"</span><span class="pl-kos">,</span> <span class="pl-s">"E"</span><span class="pl-kos">,</span> <span class="pl-s">"F"</span><span class="pl-kos">,</span> <span class="pl-s">"G"</span><span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-c1">skipHeader</span>: <span class="pl-c1">true</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* Write data starting at A2 */</span>
|
|
<span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">sheet_add_json</span><span class="pl-kos">(</span><span class="pl-s1">ws</span><span class="pl-kos">,</span> <span class="pl-kos">[</span>
|
|
<span class="pl-kos">{</span> <span class="pl-c1">A</span>: <span class="pl-c1">1</span><span class="pl-kos">,</span> <span class="pl-c1">B</span>: <span class="pl-c1">2</span> <span class="pl-kos">}</span><span class="pl-kos">,</span> <span class="pl-kos">{</span> <span class="pl-c1">A</span>: <span class="pl-c1">2</span><span class="pl-kos">,</span> <span class="pl-c1">B</span>: <span class="pl-c1">3</span> <span class="pl-kos">}</span><span class="pl-kos">,</span> <span class="pl-kos">{</span> <span class="pl-c1">A</span>: <span class="pl-c1">3</span><span class="pl-kos">,</span> <span class="pl-c1">B</span>: <span class="pl-c1">4</span> <span class="pl-kos">}</span>
|
|
<span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-kos">{</span><span class="pl-c1">skipHeader</span>: <span class="pl-c1">true</span><span class="pl-kos">,</span> <span class="pl-c1">origin</span>: <span class="pl-s">"A2"</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* Write data starting at E2 */</span>
|
|
<span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">sheet_add_json</span><span class="pl-kos">(</span><span class="pl-s1">ws</span><span class="pl-kos">,</span> <span class="pl-kos">[</span>
|
|
<span class="pl-kos">{</span> <span class="pl-c1">A</span>: <span class="pl-c1">5</span><span class="pl-kos">,</span> <span class="pl-c1">B</span>: <span class="pl-c1">6</span><span class="pl-kos">,</span> <span class="pl-c1">C</span>: <span class="pl-c1">7</span> <span class="pl-kos">}</span><span class="pl-kos">,</span> <span class="pl-kos">{</span> <span class="pl-c1">A</span>: <span class="pl-c1">6</span><span class="pl-kos">,</span> <span class="pl-c1">B</span>: <span class="pl-c1">7</span><span class="pl-kos">,</span> <span class="pl-c1">C</span>: <span class="pl-c1">8</span> <span class="pl-kos">}</span><span class="pl-kos">,</span> <span class="pl-kos">{</span> <span class="pl-c1">A</span>: <span class="pl-c1">7</span><span class="pl-kos">,</span> <span class="pl-c1">B</span>: <span class="pl-c1">8</span><span class="pl-kos">,</span> <span class="pl-c1">C</span>: <span class="pl-c1">9</span> <span class="pl-kos">}</span>
|
|
<span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-kos">{</span><span class="pl-c1">skipHeader</span>: <span class="pl-c1">true</span><span class="pl-kos">,</span> <span class="pl-c1">origin</span>: <span class="pl-kos">{</span> <span class="pl-c1">r</span>: <span class="pl-c1">1</span><span class="pl-kos">,</span> <span class="pl-c1">c</span>: <span class="pl-c1">4</span> <span class="pl-kos">}</span><span class="pl-kos">,</span> <span class="pl-c1">header</span>: <span class="pl-kos">[</span> <span class="pl-s">"A"</span><span class="pl-kos">,</span> <span class="pl-s">"B"</span><span class="pl-kos">,</span> <span class="pl-s">"C"</span> <span class="pl-kos">]</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
|
|
<span class="pl-c">/* Append row */</span>
|
|
<span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">sheet_add_json</span><span class="pl-kos">(</span><span class="pl-s1">ws</span><span class="pl-kos">,</span> <span class="pl-kos">[</span>
|
|
<span class="pl-kos">{</span> <span class="pl-c1">A</span>: <span class="pl-c1">4</span><span class="pl-kos">,</span> <span class="pl-c1">B</span>: <span class="pl-c1">5</span><span class="pl-kos">,</span> <span class="pl-c1">C</span>: <span class="pl-c1">6</span><span class="pl-kos">,</span> <span class="pl-c1">D</span>: <span class="pl-c1">7</span><span class="pl-kos">,</span> <span class="pl-c1">E</span>: <span class="pl-c1">8</span><span class="pl-kos">,</span> <span class="pl-c1">F</span>: <span class="pl-c1">9</span><span class="pl-kos">,</span> <span class="pl-c1">G</span>: <span class="pl-c1">0</span> <span class="pl-kos">}</span>
|
|
<span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-kos">{</span><span class="pl-c1">header</span>: <span class="pl-kos">[</span><span class="pl-s">"A"</span><span class="pl-kos">,</span> <span class="pl-s">"B"</span><span class="pl-kos">,</span> <span class="pl-s">"C"</span><span class="pl-kos">,</span> <span class="pl-s">"D"</span><span class="pl-kos">,</span> <span class="pl-s">"E"</span><span class="pl-kos">,</span> <span class="pl-s">"F"</span><span class="pl-kos">,</span> <span class="pl-s">"G"</span><span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-c1">skipHeader</span>: <span class="pl-c1">true</span><span class="pl-kos">,</span> <span class="pl-c1">origin</span>: <span class="pl-c1">-</span><span class="pl-c1">1</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
</details>
|
|
<h3>
|
|
<a id="user-content-html-table-input" class="anchor" href="#html-table-input" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>HTML Table Input</h3>
|
|
<p><code>XLSX.utils.table_to_sheet</code> takes a table DOM element and returns a worksheet
|
|
resembling the input table. Numbers are parsed. All other data will be stored
|
|
as strings.</p>
|
|
<p><code>XLSX.utils.table_to_book</code> produces a minimal workbook based on the worksheet.</p>
|
|
<p>Both functions accept options arguments:</p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th align="left">Option Name</th>
|
|
<th align="center">Default</th>
|
|
<th align="left">Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td align="left"><code>raw</code></td>
|
|
<td align="center"></td>
|
|
<td align="left">If true, every cell will hold raw strings</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>dateNF</code></td>
|
|
<td align="center">FMT 14</td>
|
|
<td align="left">Use specified date format in string output</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>cellDates</code></td>
|
|
<td align="center">false</td>
|
|
<td align="left">Store dates as type <code>d</code> (default is <code>n</code>)</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>sheetRows</code></td>
|
|
<td align="center">0</td>
|
|
<td align="left">If >0, read the first <code>sheetRows</code> rows of the table</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>display</code></td>
|
|
<td align="center">false</td>
|
|
<td align="left">If true, hidden rows and cells will not be parsed</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<details>
|
|
<summary><b>Examples</b> (click to show)</summary>
|
|
<p>To generate the example sheet, start with the HTML table:</p>
|
|
<div class="highlight highlight-text-html-basic"><pre><span class="pl-kos"><</span><span class="pl-ent">table</span> <span class="pl-c1">id</span>="<span class="pl-s">sheetjs</span>"<span class="pl-kos">></span>
|
|
<span class="pl-kos"><</span><span class="pl-ent">tr</span><span class="pl-kos">></span><span class="pl-kos"><</span><span class="pl-ent">td</span><span class="pl-kos">></span>S<span class="pl-kos"></</span><span class="pl-ent">td</span><span class="pl-kos">></span><span class="pl-kos"><</span><span class="pl-ent">td</span><span class="pl-kos">></span>h<span class="pl-kos"></</span><span class="pl-ent">td</span><span class="pl-kos">></span><span class="pl-kos"><</span><span class="pl-ent">td</span><span class="pl-kos">></span>e<span class="pl-kos"></</span><span class="pl-ent">td</span><span class="pl-kos">></span><span class="pl-kos"><</span><span class="pl-ent">td</span><span class="pl-kos">></span>e<span class="pl-kos"></</span><span class="pl-ent">td</span><span class="pl-kos">></span><span class="pl-kos"><</span><span class="pl-ent">td</span><span class="pl-kos">></span>t<span class="pl-kos"></</span><span class="pl-ent">td</span><span class="pl-kos">></span><span class="pl-kos"><</span><span class="pl-ent">td</span><span class="pl-kos">></span>J<span class="pl-kos"></</span><span class="pl-ent">td</span><span class="pl-kos">></span><span class="pl-kos"><</span><span class="pl-ent">td</span><span class="pl-kos">></span>S<span class="pl-kos"></</span><span class="pl-ent">td</span><span class="pl-kos">></span><span class="pl-kos"></</span><span class="pl-ent">tr</span><span class="pl-kos">></span>
|
|
<span class="pl-kos"><</span><span class="pl-ent">tr</span><span class="pl-kos">></span><span class="pl-kos"><</span><span class="pl-ent">td</span><span class="pl-kos">></span>1<span class="pl-kos"></</span><span class="pl-ent">td</span><span class="pl-kos">></span><span class="pl-kos"><</span><span class="pl-ent">td</span><span class="pl-kos">></span>2<span class="pl-kos"></</span><span class="pl-ent">td</span><span class="pl-kos">></span><span class="pl-kos"><</span><span class="pl-ent">td</span><span class="pl-kos">></span>3<span class="pl-kos"></</span><span class="pl-ent">td</span><span class="pl-kos">></span><span class="pl-kos"><</span><span class="pl-ent">td</span><span class="pl-kos">></span>4<span class="pl-kos"></</span><span class="pl-ent">td</span><span class="pl-kos">></span><span class="pl-kos"><</span><span class="pl-ent">td</span><span class="pl-kos">></span>5<span class="pl-kos"></</span><span class="pl-ent">td</span><span class="pl-kos">></span><span class="pl-kos"><</span><span class="pl-ent">td</span><span class="pl-kos">></span>6<span class="pl-kos"></</span><span class="pl-ent">td</span><span class="pl-kos">></span><span class="pl-kos"><</span><span class="pl-ent">td</span><span class="pl-kos">></span>7<span class="pl-kos"></</span><span class="pl-ent">td</span><span class="pl-kos">></span><span class="pl-kos"></</span><span class="pl-ent">tr</span><span class="pl-kos">></span>
|
|
<span class="pl-kos"><</span><span class="pl-ent">tr</span><span class="pl-kos">></span><span class="pl-kos"><</span><span class="pl-ent">td</span><span class="pl-kos">></span>2<span class="pl-kos"></</span><span class="pl-ent">td</span><span class="pl-kos">></span><span class="pl-kos"><</span><span class="pl-ent">td</span><span class="pl-kos">></span>3<span class="pl-kos"></</span><span class="pl-ent">td</span><span class="pl-kos">></span><span class="pl-kos"><</span><span class="pl-ent">td</span><span class="pl-kos">></span>4<span class="pl-kos"></</span><span class="pl-ent">td</span><span class="pl-kos">></span><span class="pl-kos"><</span><span class="pl-ent">td</span><span class="pl-kos">></span>5<span class="pl-kos"></</span><span class="pl-ent">td</span><span class="pl-kos">></span><span class="pl-kos"><</span><span class="pl-ent">td</span><span class="pl-kos">></span>6<span class="pl-kos"></</span><span class="pl-ent">td</span><span class="pl-kos">></span><span class="pl-kos"><</span><span class="pl-ent">td</span><span class="pl-kos">></span>7<span class="pl-kos"></</span><span class="pl-ent">td</span><span class="pl-kos">></span><span class="pl-kos"><</span><span class="pl-ent">td</span><span class="pl-kos">></span>8<span class="pl-kos"></</span><span class="pl-ent">td</span><span class="pl-kos">></span><span class="pl-kos"></</span><span class="pl-ent">tr</span><span class="pl-kos">></span>
|
|
<span class="pl-kos"></</span><span class="pl-ent">table</span><span class="pl-kos">></span></pre></div>
|
|
<p>To process the table:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> <span class="pl-s1">tbl</span> <span class="pl-c1">=</span> <span class="pl-smi">document</span><span class="pl-kos">.</span><span class="pl-en">getElementById</span><span class="pl-kos">(</span><span class="pl-s">'sheetjs'</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">wb</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">table_to_book</span><span class="pl-kos">(</span><span class="pl-s1">tbl</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
</details>
|
|
<p>Note: <code>XLSX.read</code> can handle HTML represented as strings.</p>
|
|
<p><code>XLSX.utils.sheet_add_dom</code> takes a table DOM element and updates an existing
|
|
worksheet object. It follows the same process as <code>table_to_sheet</code> and accepts
|
|
an options argument:</p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th align="left">Option Name</th>
|
|
<th align="center">Default</th>
|
|
<th align="left">Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td align="left"><code>raw</code></td>
|
|
<td align="center"></td>
|
|
<td align="left">If true, every cell will hold raw strings</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>dateNF</code></td>
|
|
<td align="center">FMT 14</td>
|
|
<td align="left">Use specified date format in string output</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>cellDates</code></td>
|
|
<td align="center">false</td>
|
|
<td align="left">Store dates as type <code>d</code> (default is <code>n</code>)</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>sheetRows</code></td>
|
|
<td align="center">0</td>
|
|
<td align="left">If >0, read the first <code>sheetRows</code> rows of the table</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>display</code></td>
|
|
<td align="center">false</td>
|
|
<td align="left">If true, hidden rows and cells will not be parsed</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><code>origin</code> is expected to be one of:</p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th align="left"><code>origin</code></th>
|
|
<th align="left">Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td align="left">(cell object)</td>
|
|
<td align="left">Use specified cell (cell object)</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">(string)</td>
|
|
<td align="left">Use specified cell (A1-style cell)</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">(number >= 0)</td>
|
|
<td align="left">Start from the first column at specified row (0-indexed)</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">-1</td>
|
|
<td align="left">Append to bottom of worksheet starting on first column</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">(default)</td>
|
|
<td align="left">Start from cell A1</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<details>
|
|
<summary><b>Examples</b> (click to show)</summary>
|
|
<p>A small helper function can create gap rows between tables:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">function</span> <span class="pl-en">create_gap_rows</span><span class="pl-kos">(</span><span class="pl-s1">ws</span><span class="pl-kos">,</span> <span class="pl-s1">nrows</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">ref</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">decode_range</span><span class="pl-kos">(</span><span class="pl-s1">ws</span><span class="pl-kos">[</span><span class="pl-s">"!ref"</span><span class="pl-kos">]</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-c">// get original range</span>
|
|
<span class="pl-s1">ref</span><span class="pl-kos">.</span><span class="pl-c1">e</span><span class="pl-kos">.</span><span class="pl-c1">r</span> <span class="pl-c1">+=</span> <span class="pl-s1">nrows</span><span class="pl-kos">;</span> <span class="pl-c">// add to ending row</span>
|
|
<span class="pl-s1">ws</span><span class="pl-kos">[</span><span class="pl-s">"!ref"</span><span class="pl-kos">]</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">encode_range</span><span class="pl-kos">(</span><span class="pl-s1">ref</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-c">// reassign row</span>
|
|
<span class="pl-kos">}</span>
|
|
|
|
<span class="pl-c">/* first table */</span>
|
|
<span class="pl-k">var</span> <span class="pl-s1">ws</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">table_to_sheet</span><span class="pl-kos">(</span><span class="pl-smi">document</span><span class="pl-kos">.</span><span class="pl-en">getElementById</span><span class="pl-kos">(</span><span class="pl-s">'table1'</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-en">create_gap_rows</span><span class="pl-kos">(</span><span class="pl-s1">ws</span><span class="pl-kos">,</span> <span class="pl-c1">1</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-c">// one row gap after first table</span>
|
|
|
|
<span class="pl-c">/* second table */</span>
|
|
<span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">sheet_add_dom</span><span class="pl-kos">(</span><span class="pl-s1">ws</span><span class="pl-kos">,</span> <span class="pl-smi">document</span><span class="pl-kos">.</span><span class="pl-en">getElementById</span><span class="pl-kos">(</span><span class="pl-s">'table2'</span><span class="pl-kos">)</span><span class="pl-kos">,</span> <span class="pl-kos">{</span><span class="pl-c1">origin</span>: <span class="pl-c1">-</span><span class="pl-c1">1</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-en">create_gap_rows</span><span class="pl-kos">(</span><span class="pl-s1">ws</span><span class="pl-kos">,</span> <span class="pl-c1">3</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-c">// three rows gap after second table</span>
|
|
|
|
<span class="pl-c">/* third table */</span>
|
|
<span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">sheet_add_dom</span><span class="pl-kos">(</span><span class="pl-s1">ws</span><span class="pl-kos">,</span> <span class="pl-smi">document</span><span class="pl-kos">.</span><span class="pl-en">getElementById</span><span class="pl-kos">(</span><span class="pl-s">'table3'</span><span class="pl-kos">)</span><span class="pl-kos">,</span> <span class="pl-kos">{</span><span class="pl-c1">origin</span>: <span class="pl-c1">-</span><span class="pl-c1">1</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
|
|
</details>
|
|
<h3>
|
|
<a id="user-content-formulae-output" class="anchor" href="#formulae-output" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Formulae Output</h3>
|
|
<p><code>XLSX.utils.sheet_to_formulae</code> generates an array of commands that represent
|
|
how a person would enter data into an application. Each entry is of the form
|
|
<code>A1-cell-address=formula-or-value</code>. String literals are prefixed with a <code>'</code> in
|
|
accordance with Excel.</p>
|
|
<details>
|
|
<summary><b>Examples</b> (click to show)</summary>
|
|
<p>For the example sheet:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-c1">></span> <span class="pl-k">var</span> <span class="pl-s1">o</span> <span class="pl-c1">=</span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">sheet_to_formulae</span><span class="pl-kos">(</span><span class="pl-s1">ws</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-c1">></span> <span class="pl-kos">[</span><span class="pl-s1">o</span><span class="pl-kos">[</span><span class="pl-c1">0</span><span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-s1">o</span><span class="pl-kos">[</span><span class="pl-c1">5</span><span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-s1">o</span><span class="pl-kos">[</span><span class="pl-c1">10</span><span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-s1">o</span><span class="pl-kos">[</span><span class="pl-c1">15</span><span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-s1">o</span><span class="pl-kos">[</span><span class="pl-c1">20</span><span class="pl-kos">]</span><span class="pl-kos">]</span><span class="pl-kos">;</span>
|
|
<span class="pl-kos">[</span> <span class="pl-s">'A1=\'S'</span><span class="pl-kos">,</span> <span class="pl-s">'F1=\'J'</span><span class="pl-kos">,</span> <span class="pl-s">'D2=4'</span><span class="pl-kos">,</span> <span class="pl-s">'B3=3'</span><span class="pl-kos">,</span> <span class="pl-s">'G3=8'</span> <span class="pl-kos">]</span></pre></div>
|
|
</details>
|
|
<h3>
|
|
<a id="user-content-delimiter-separated-output" class="anchor" href="#delimiter-separated-output" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Delimiter-Separated Output</h3>
|
|
<p>As an alternative to the <code>writeFile</code> CSV type, <code>XLSX.utils.sheet_to_csv</code> also
|
|
produces CSV output. The function takes an options argument:</p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th align="left">Option Name</th>
|
|
<th align="center">Default</th>
|
|
<th align="left">Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td align="left"><code>FS</code></td>
|
|
<td align="center"><code>","</code></td>
|
|
<td align="left">"Field Separator" delimiter between fields</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>RS</code></td>
|
|
<td align="center"><code>"\n"</code></td>
|
|
<td align="left">"Record Separator" delimiter between rows</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>dateNF</code></td>
|
|
<td align="center">FMT 14</td>
|
|
<td align="left">Use specified date format in string output</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>strip</code></td>
|
|
<td align="center">false</td>
|
|
<td align="left">Remove trailing field separators in each record **</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>blankrows</code></td>
|
|
<td align="center">true</td>
|
|
<td align="left">Include blank lines in the CSV output</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>skipHidden</code></td>
|
|
<td align="center">false</td>
|
|
<td align="left">Skips hidden rows/columns in the CSV output</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>forceQuotes</code></td>
|
|
<td align="center">false</td>
|
|
<td align="left">Force quotes around fields</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<ul>
|
|
<li>
|
|
<code>strip</code> will remove trailing commas from each line under default <code>FS/RS</code>
|
|
</li>
|
|
<li>
|
|
<code>blankrows</code> must be set to <code>false</code> to skip blank lines.</li>
|
|
<li>Fields containing the record or field separator will automatically be wrapped
|
|
in double quotes; <code>forceQuotes</code> forces all cells to be wrapped in quotes.</li>
|
|
<li>
|
|
<code>XLSX.write</code> with <code>csv</code> type will always prepend the UTF-8 byte-order mark for
|
|
Excel compatibility. <code>sheet_to_csv</code> returns a JS string and omits the mark.
|
|
Using <code>XLSX.write</code> with type <code>string</code> will also skip the mark.</li>
|
|
</ul>
|
|
<details>
|
|
<summary><b>Examples</b> (click to show)</summary>
|
|
<p>For the example sheet:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-c1">></span> <span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">sheet_to_csv</span><span class="pl-kos">(</span><span class="pl-s1">ws</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-v">S</span><span class="pl-kos">,</span><span class="pl-s1">h</span><span class="pl-kos">,</span><span class="pl-s1">e</span><span class="pl-kos">,</span><span class="pl-s1">e</span><span class="pl-kos">,</span><span class="pl-s1">t</span><span class="pl-kos">,</span><span class="pl-v">J</span><span class="pl-kos">,</span><span class="pl-v">S</span>
|
|
<span class="pl-c1">1</span><span class="pl-kos">,</span><span class="pl-c1">2</span><span class="pl-kos">,</span><span class="pl-c1">3</span><span class="pl-kos">,</span><span class="pl-c1">4</span><span class="pl-kos">,</span><span class="pl-c1">5</span><span class="pl-kos">,</span><span class="pl-c1">6</span><span class="pl-kos">,</span><span class="pl-c1">7</span>
|
|
<span class="pl-c1">2</span><span class="pl-kos">,</span><span class="pl-c1">3</span><span class="pl-kos">,</span><span class="pl-c1">4</span><span class="pl-kos">,</span><span class="pl-c1">5</span><span class="pl-kos">,</span><span class="pl-c1">6</span><span class="pl-kos">,</span><span class="pl-c1">7</span><span class="pl-kos">,</span><span class="pl-c1">8</span>
|
|
<span class="pl-c1">></span> <span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">sheet_to_csv</span><span class="pl-kos">(</span><span class="pl-s1">ws</span><span class="pl-kos">,</span> <span class="pl-kos">{</span><span class="pl-c1">FS</span>:<span class="pl-s">"\t"</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-v">S</span> <span class="pl-s1">h</span> <span class="pl-s1">e</span> <span class="pl-s1">e</span> <span class="pl-s1">t</span> <span class="pl-v">J</span> <span class="pl-v">S</span>
|
|
<span class="pl-c1">1</span> <span class="pl-c1">2</span> <span class="pl-c1">3</span> <span class="pl-c1">4</span> <span class="pl-c1">5</span> <span class="pl-c1">6</span> <span class="pl-c1">7</span>
|
|
<span class="pl-c1">2</span> <span class="pl-c1">3</span> <span class="pl-c1">4</span> <span class="pl-c1">5</span> <span class="pl-c1">6</span> <span class="pl-c1">7</span> <span class="pl-c1">8</span>
|
|
<span class="pl-c1">></span> <span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">sheet_to_csv</span><span class="pl-kos">(</span><span class="pl-s1">ws</span><span class="pl-kos">,</span><span class="pl-kos">{</span><span class="pl-c1">FS</span>:<span class="pl-s">":"</span><span class="pl-kos">,</span><span class="pl-c1">RS</span>:<span class="pl-s">"|"</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-v">S</span>:<span class="pl-s1">h</span>:<span class="pl-s1">e</span>:<span class="pl-s1">e</span>:<span class="pl-s1">t</span>:<span class="pl-v">J</span>:<span class="pl-v">S</span><span class="pl-c1">|</span><span class="pl-c1">1</span>:<span class="pl-c1">2</span>:<span class="pl-c1">3</span>:<span class="pl-c1">4</span>:<span class="pl-c1">5</span>:<span class="pl-c1">6</span>:<span class="pl-c1">7</span><span class="pl-c1">|</span><span class="pl-c1">2</span>:<span class="pl-c1">3</span>:<span class="pl-c1">4</span>:<span class="pl-c1">5</span>:<span class="pl-c1">6</span>:<span class="pl-c1">7</span>:<span class="pl-c1">8</span><span class="pl-c1">|</span></pre></div>
|
|
</details>
|
|
<h4>
|
|
<a id="user-content-utf-16-unicode-text" class="anchor" href="#utf-16-unicode-text" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>UTF-16 Unicode Text</h4>
|
|
<p>The <code>txt</code> output type uses the tab character as the field separator. If the
|
|
<code>codepage</code> library is available (included in full distribution but not core),
|
|
the output will be encoded in <code>CP1200</code> and the BOM will be prepended.</p>
|
|
<p><code>XLSX.utils.sheet_to_txt</code> takes the same arguments as <code>sheet_to_csv</code>.</p>
|
|
<h3>
|
|
<a id="user-content-html-output" class="anchor" href="#html-output" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>HTML Output</h3>
|
|
<p>As an alternative to the <code>writeFile</code> HTML type, <code>XLSX.utils.sheet_to_html</code> also
|
|
produces HTML output. The function takes an options argument:</p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th align="left">Option Name</th>
|
|
<th align="center">Default</th>
|
|
<th align="left">Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td align="left"><code>id</code></td>
|
|
<td align="center"></td>
|
|
<td align="left">Specify the <code>id</code> attribute for the <code>TABLE</code> element</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>editable</code></td>
|
|
<td align="center">false</td>
|
|
<td align="left">If true, set <code>contenteditable="true"</code> for every TD</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>header</code></td>
|
|
<td align="center"></td>
|
|
<td align="left">Override header (default <code>html body</code>)</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>footer</code></td>
|
|
<td align="center"></td>
|
|
<td align="left">Override footer (default <code>/body /html</code>)</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<details>
|
|
<summary><b>Examples</b> (click to show)</summary>
|
|
<p>For the example sheet:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-c1">></span> <span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">sheet_to_html</span><span class="pl-kos">(</span><span class="pl-s1">ws</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-c">// ...</span></pre></div>
|
|
</details>
|
|
<h3>
|
|
<a id="user-content-json" class="anchor" href="#json" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>JSON</h3>
|
|
<p><code>XLSX.utils.sheet_to_json</code> generates different types of JS objects. The function
|
|
takes an options argument:</p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th align="left">Option Name</th>
|
|
<th align="center">Default</th>
|
|
<th align="left">Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td align="left"><code>raw</code></td>
|
|
<td align="center"><code>true</code></td>
|
|
<td align="left">Use raw values (true) or formatted strings (false)</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>range</code></td>
|
|
<td align="center">from WS</td>
|
|
<td align="left">Override Range (see table below)</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>header</code></td>
|
|
<td align="center"></td>
|
|
<td align="left">Control output format (see table below)</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>dateNF</code></td>
|
|
<td align="center">FMT 14</td>
|
|
<td align="left">Use specified date format in string output</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>defval</code></td>
|
|
<td align="center"></td>
|
|
<td align="left">Use specified value in place of null or undefined</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>blankrows</code></td>
|
|
<td align="center">**</td>
|
|
<td align="left">Include blank lines in the output **</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<ul>
|
|
<li>
|
|
<code>raw</code> only affects cells which have a format code (<code>.z</code>) field or a formatted
|
|
text (<code>.w</code>) field.</li>
|
|
<li>If <code>header</code> is specified, the first row is considered a data row; if <code>header</code>
|
|
is not specified, the first row is the header row and not considered data.</li>
|
|
<li>When <code>header</code> is not specified, the conversion will automatically disambiguate
|
|
header entries by affixing <code>_</code> and a count starting at <code>1</code>. For example, if
|
|
three columns have header <code>foo</code> the output fields are <code>foo</code>, <code>foo_1</code>, <code>foo_2</code>
|
|
</li>
|
|
<li>
|
|
<code>null</code> values are returned when <code>raw</code> is true but are skipped when false.</li>
|
|
<li>If <code>defval</code> is not specified, null and undefined values are skipped normally.
|
|
If specified, all null and undefined points will be filled with <code>defval</code>
|
|
</li>
|
|
<li>When <code>header</code> is <code>1</code>, the default is to generate blank rows. <code>blankrows</code> must
|
|
be set to <code>false</code> to skip blank rows.</li>
|
|
<li>When <code>header</code> is not <code>1</code>, the default is to skip blank rows. <code>blankrows</code> must
|
|
be true to generate blank rows</li>
|
|
</ul>
|
|
<p><code>range</code> is expected to be one of:</p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th align="left"><code>range</code></th>
|
|
<th align="left">Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td align="left">(number)</td>
|
|
<td align="left">Use worksheet range but set starting row to the value</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">(string)</td>
|
|
<td align="left">Use specified range (A1-style bounded range string)</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">(default)</td>
|
|
<td align="left">Use worksheet range (<code>ws['!ref']</code>)</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><code>header</code> is expected to be one of:</p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th align="left"><code>header</code></th>
|
|
<th align="left">Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td align="left"><code>1</code></td>
|
|
<td align="left">Generate an array of arrays ("2D Array")</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>"A"</code></td>
|
|
<td align="left">Row object keys are literal column labels</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">array of strings</td>
|
|
<td align="left">Use specified strings as keys in row objects</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">(default)</td>
|
|
<td align="left">Read and disambiguate first row as keys</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<ul>
|
|
<li>If header is not <code>1</code>, the row object will contain the non-enumerable property
|
|
<code>__rowNum__</code> that represents the row of the sheet corresponding to the entry.</li>
|
|
<li>If header is an array, the keys will not be disambiguated. This can lead to
|
|
unexpected results if the array values are not unique!</li>
|
|
</ul>
|
|
<details>
|
|
<summary><b>Examples</b> (click to show)</summary>
|
|
<p>For the example sheet:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-c1">></span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">sheet_to_json</span><span class="pl-kos">(</span><span class="pl-s1">ws</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-kos">[</span> <span class="pl-kos">{</span> <span class="pl-c1">S</span>: <span class="pl-c1">1</span><span class="pl-kos">,</span> <span class="pl-c1">h</span>: <span class="pl-c1">2</span><span class="pl-kos">,</span> <span class="pl-c1">e</span>: <span class="pl-c1">3</span><span class="pl-kos">,</span> <span class="pl-c1">e_1</span>: <span class="pl-c1">4</span><span class="pl-kos">,</span> <span class="pl-c1">t</span>: <span class="pl-c1">5</span><span class="pl-kos">,</span> <span class="pl-c1">J</span>: <span class="pl-c1">6</span><span class="pl-kos">,</span> <span class="pl-c1">S_1</span>: <span class="pl-c1">7</span> <span class="pl-kos">}</span><span class="pl-kos">,</span>
|
|
<span class="pl-kos">{</span> <span class="pl-c1">S</span>: <span class="pl-c1">2</span><span class="pl-kos">,</span> <span class="pl-c1">h</span>: <span class="pl-c1">3</span><span class="pl-kos">,</span> <span class="pl-c1">e</span>: <span class="pl-c1">4</span><span class="pl-kos">,</span> <span class="pl-c1">e_1</span>: <span class="pl-c1">5</span><span class="pl-kos">,</span> <span class="pl-c1">t</span>: <span class="pl-c1">6</span><span class="pl-kos">,</span> <span class="pl-c1">J</span>: <span class="pl-c1">7</span><span class="pl-kos">,</span> <span class="pl-c1">S_1</span>: <span class="pl-c1">8</span> <span class="pl-kos">}</span> <span class="pl-kos">]</span>
|
|
|
|
<span class="pl-c1">></span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">sheet_to_json</span><span class="pl-kos">(</span><span class="pl-s1">ws</span><span class="pl-kos">,</span> <span class="pl-kos">{</span><span class="pl-c1">header</span>:<span class="pl-s">"A"</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-kos">[</span> <span class="pl-kos">{</span> <span class="pl-c1">A</span>: <span class="pl-s">'S'</span><span class="pl-kos">,</span> <span class="pl-c1">B</span>: <span class="pl-s">'h'</span><span class="pl-kos">,</span> <span class="pl-c1">C</span>: <span class="pl-s">'e'</span><span class="pl-kos">,</span> <span class="pl-c1">D</span>: <span class="pl-s">'e'</span><span class="pl-kos">,</span> <span class="pl-c1">E</span>: <span class="pl-s">'t'</span><span class="pl-kos">,</span> <span class="pl-c1">F</span>: <span class="pl-s">'J'</span><span class="pl-kos">,</span> <span class="pl-c1">G</span>: <span class="pl-s">'S'</span> <span class="pl-kos">}</span><span class="pl-kos">,</span>
|
|
<span class="pl-kos">{</span> <span class="pl-c1">A</span>: <span class="pl-s">'1'</span><span class="pl-kos">,</span> <span class="pl-c1">B</span>: <span class="pl-s">'2'</span><span class="pl-kos">,</span> <span class="pl-c1">C</span>: <span class="pl-s">'3'</span><span class="pl-kos">,</span> <span class="pl-c1">D</span>: <span class="pl-s">'4'</span><span class="pl-kos">,</span> <span class="pl-c1">E</span>: <span class="pl-s">'5'</span><span class="pl-kos">,</span> <span class="pl-c1">F</span>: <span class="pl-s">'6'</span><span class="pl-kos">,</span> <span class="pl-c1">G</span>: <span class="pl-s">'7'</span> <span class="pl-kos">}</span><span class="pl-kos">,</span>
|
|
<span class="pl-kos">{</span> <span class="pl-c1">A</span>: <span class="pl-s">'2'</span><span class="pl-kos">,</span> <span class="pl-c1">B</span>: <span class="pl-s">'3'</span><span class="pl-kos">,</span> <span class="pl-c1">C</span>: <span class="pl-s">'4'</span><span class="pl-kos">,</span> <span class="pl-c1">D</span>: <span class="pl-s">'5'</span><span class="pl-kos">,</span> <span class="pl-c1">E</span>: <span class="pl-s">'6'</span><span class="pl-kos">,</span> <span class="pl-c1">F</span>: <span class="pl-s">'7'</span><span class="pl-kos">,</span> <span class="pl-c1">G</span>: <span class="pl-s">'8'</span> <span class="pl-kos">}</span> <span class="pl-kos">]</span>
|
|
|
|
<span class="pl-c1">></span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">sheet_to_json</span><span class="pl-kos">(</span><span class="pl-s1">ws</span><span class="pl-kos">,</span> <span class="pl-kos">{</span><span class="pl-c1">header</span>:<span class="pl-kos">[</span><span class="pl-s">"A"</span><span class="pl-kos">,</span><span class="pl-s">"E"</span><span class="pl-kos">,</span><span class="pl-s">"I"</span><span class="pl-kos">,</span><span class="pl-s">"O"</span><span class="pl-kos">,</span><span class="pl-s">"U"</span><span class="pl-kos">,</span><span class="pl-s">"6"</span><span class="pl-kos">,</span><span class="pl-s">"9"</span><span class="pl-kos">]</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-kos">[</span> <span class="pl-kos">{</span> <span class="pl-s">'6'</span>: <span class="pl-s">'J'</span><span class="pl-kos">,</span> <span class="pl-s">'9'</span>: <span class="pl-s">'S'</span><span class="pl-kos">,</span> <span class="pl-c1">A</span>: <span class="pl-s">'S'</span><span class="pl-kos">,</span> <span class="pl-c1">E</span>: <span class="pl-s">'h'</span><span class="pl-kos">,</span> <span class="pl-c1">I</span>: <span class="pl-s">'e'</span><span class="pl-kos">,</span> <span class="pl-c1">O</span>: <span class="pl-s">'e'</span><span class="pl-kos">,</span> <span class="pl-c1">U</span>: <span class="pl-s">'t'</span> <span class="pl-kos">}</span><span class="pl-kos">,</span>
|
|
<span class="pl-kos">{</span> <span class="pl-s">'6'</span>: <span class="pl-s">'6'</span><span class="pl-kos">,</span> <span class="pl-s">'9'</span>: <span class="pl-s">'7'</span><span class="pl-kos">,</span> <span class="pl-c1">A</span>: <span class="pl-s">'1'</span><span class="pl-kos">,</span> <span class="pl-c1">E</span>: <span class="pl-s">'2'</span><span class="pl-kos">,</span> <span class="pl-c1">I</span>: <span class="pl-s">'3'</span><span class="pl-kos">,</span> <span class="pl-c1">O</span>: <span class="pl-s">'4'</span><span class="pl-kos">,</span> <span class="pl-c1">U</span>: <span class="pl-s">'5'</span> <span class="pl-kos">}</span><span class="pl-kos">,</span>
|
|
<span class="pl-kos">{</span> <span class="pl-s">'6'</span>: <span class="pl-s">'7'</span><span class="pl-kos">,</span> <span class="pl-s">'9'</span>: <span class="pl-s">'8'</span><span class="pl-kos">,</span> <span class="pl-c1">A</span>: <span class="pl-s">'2'</span><span class="pl-kos">,</span> <span class="pl-c1">E</span>: <span class="pl-s">'3'</span><span class="pl-kos">,</span> <span class="pl-c1">I</span>: <span class="pl-s">'4'</span><span class="pl-kos">,</span> <span class="pl-c1">O</span>: <span class="pl-s">'5'</span><span class="pl-kos">,</span> <span class="pl-c1">U</span>: <span class="pl-s">'6'</span> <span class="pl-kos">}</span> <span class="pl-kos">]</span>
|
|
|
|
<span class="pl-c1">></span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">sheet_to_json</span><span class="pl-kos">(</span><span class="pl-s1">ws</span><span class="pl-kos">,</span> <span class="pl-kos">{</span><span class="pl-c1">header</span>:<span class="pl-c1">1</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-kos">[</span> <span class="pl-kos">[</span> <span class="pl-s">'S'</span><span class="pl-kos">,</span> <span class="pl-s">'h'</span><span class="pl-kos">,</span> <span class="pl-s">'e'</span><span class="pl-kos">,</span> <span class="pl-s">'e'</span><span class="pl-kos">,</span> <span class="pl-s">'t'</span><span class="pl-kos">,</span> <span class="pl-s">'J'</span><span class="pl-kos">,</span> <span class="pl-s">'S'</span> <span class="pl-kos">]</span><span class="pl-kos">,</span>
|
|
<span class="pl-kos">[</span> <span class="pl-s">'1'</span><span class="pl-kos">,</span> <span class="pl-s">'2'</span><span class="pl-kos">,</span> <span class="pl-s">'3'</span><span class="pl-kos">,</span> <span class="pl-s">'4'</span><span class="pl-kos">,</span> <span class="pl-s">'5'</span><span class="pl-kos">,</span> <span class="pl-s">'6'</span><span class="pl-kos">,</span> <span class="pl-s">'7'</span> <span class="pl-kos">]</span><span class="pl-kos">,</span>
|
|
<span class="pl-kos">[</span> <span class="pl-s">'2'</span><span class="pl-kos">,</span> <span class="pl-s">'3'</span><span class="pl-kos">,</span> <span class="pl-s">'4'</span><span class="pl-kos">,</span> <span class="pl-s">'5'</span><span class="pl-kos">,</span> <span class="pl-s">'6'</span><span class="pl-kos">,</span> <span class="pl-s">'7'</span><span class="pl-kos">,</span> <span class="pl-s">'8'</span> <span class="pl-kos">]</span> <span class="pl-kos">]</span></pre></div>
|
|
<p>Example showing the effect of <code>raw</code>:</p>
|
|
<div class="highlight highlight-source-js"><pre><span class="pl-c1">></span> <span class="pl-s1">ws</span><span class="pl-kos">[</span><span class="pl-s">'A2'</span><span class="pl-kos">]</span><span class="pl-kos">.</span><span class="pl-c1">w</span> <span class="pl-c1">=</span> <span class="pl-s">"3"</span><span class="pl-kos">;</span> <span class="pl-c">// set A2 formatted string value</span>
|
|
|
|
<span class="pl-c1">></span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">sheet_to_json</span><span class="pl-kos">(</span><span class="pl-s1">ws</span><span class="pl-kos">,</span> <span class="pl-kos">{</span><span class="pl-c1">header</span>:<span class="pl-c1">1</span><span class="pl-kos">,</span> <span class="pl-c1">raw</span>:<span class="pl-c1">false</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-kos">[</span> <span class="pl-kos">[</span> <span class="pl-s">'S'</span><span class="pl-kos">,</span> <span class="pl-s">'h'</span><span class="pl-kos">,</span> <span class="pl-s">'e'</span><span class="pl-kos">,</span> <span class="pl-s">'e'</span><span class="pl-kos">,</span> <span class="pl-s">'t'</span><span class="pl-kos">,</span> <span class="pl-s">'J'</span><span class="pl-kos">,</span> <span class="pl-s">'S'</span> <span class="pl-kos">]</span><span class="pl-kos">,</span>
|
|
<span class="pl-kos">[</span> <span class="pl-s">'3'</span><span class="pl-kos">,</span> <span class="pl-s">'2'</span><span class="pl-kos">,</span> <span class="pl-s">'3'</span><span class="pl-kos">,</span> <span class="pl-s">'4'</span><span class="pl-kos">,</span> <span class="pl-s">'5'</span><span class="pl-kos">,</span> <span class="pl-s">'6'</span><span class="pl-kos">,</span> <span class="pl-s">'7'</span> <span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-c">// <-- A2 uses the formatted string</span>
|
|
<span class="pl-kos">[</span> <span class="pl-s">'2'</span><span class="pl-kos">,</span> <span class="pl-s">'3'</span><span class="pl-kos">,</span> <span class="pl-s">'4'</span><span class="pl-kos">,</span> <span class="pl-s">'5'</span><span class="pl-kos">,</span> <span class="pl-s">'6'</span><span class="pl-kos">,</span> <span class="pl-s">'7'</span><span class="pl-kos">,</span> <span class="pl-s">'8'</span> <span class="pl-kos">]</span> <span class="pl-kos">]</span>
|
|
|
|
<span class="pl-c1">></span> <span class="pl-c1">XLSX</span><span class="pl-kos">.</span><span class="pl-c1">utils</span><span class="pl-kos">.</span><span class="pl-en">sheet_to_json</span><span class="pl-kos">(</span><span class="pl-s1">ws</span><span class="pl-kos">,</span> <span class="pl-kos">{</span><span class="pl-c1">header</span>:<span class="pl-c1">1</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
|
|
<span class="pl-kos">[</span> <span class="pl-kos">[</span> <span class="pl-s">'S'</span><span class="pl-kos">,</span> <span class="pl-s">'h'</span><span class="pl-kos">,</span> <span class="pl-s">'e'</span><span class="pl-kos">,</span> <span class="pl-s">'e'</span><span class="pl-kos">,</span> <span class="pl-s">'t'</span><span class="pl-kos">,</span> <span class="pl-s">'J'</span><span class="pl-kos">,</span> <span class="pl-s">'S'</span> <span class="pl-kos">]</span><span class="pl-kos">,</span>
|
|
<span class="pl-kos">[</span> <span class="pl-c1">1</span><span class="pl-kos">,</span> <span class="pl-c1">2</span><span class="pl-kos">,</span> <span class="pl-c1">3</span><span class="pl-kos">,</span> <span class="pl-c1">4</span><span class="pl-kos">,</span> <span class="pl-c1">5</span><span class="pl-kos">,</span> <span class="pl-c1">6</span><span class="pl-kos">,</span> <span class="pl-c1">7</span> <span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-c">// <-- A2 uses the raw value</span>
|
|
<span class="pl-kos">[</span> <span class="pl-c1">2</span><span class="pl-kos">,</span> <span class="pl-c1">3</span><span class="pl-kos">,</span> <span class="pl-c1">4</span><span class="pl-kos">,</span> <span class="pl-c1">5</span><span class="pl-kos">,</span> <span class="pl-c1">6</span><span class="pl-kos">,</span> <span class="pl-c1">7</span><span class="pl-kos">,</span> <span class="pl-c1">8</span> <span class="pl-kos">]</span> <span class="pl-kos">]</span></pre></div>
|
|
</details>
|
|
<h2>
|
|
<a id="user-content-file-formats" class="anchor" href="#file-formats" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>File Formats</h2>
|
|
<p>Despite the library name <code>xlsx</code>, it supports numerous spreadsheet file formats:</p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th align="left">Format</th>
|
|
<th align="center">Read</th>
|
|
<th align="center">Write</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td align="left"><strong>Excel Worksheet/Workbook Formats</strong></td>
|
|
<td align="center">:-----:</td>
|
|
<td align="center">:-----:</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">Excel 2007+ XML Formats (XLSX/XLSM)</td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">Excel 2007+ Binary Format (XLSB BIFF12)</td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">Excel 2003-2004 XML Format (XML "SpreadsheetML")</td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">Excel 97-2004 (XLS BIFF8)</td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">Excel 5.0/95 (XLS BIFF5)</td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">Excel 4.0 (XLS/XLW BIFF4)</td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">Excel 3.0 (XLS BIFF3)</td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">Excel 2.0/2.1 / Multiplan 4.x DOS (XLS BIFF2)</td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><strong>Excel Supported Text Formats</strong></td>
|
|
<td align="center">:-----:</td>
|
|
<td align="center">:-----:</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">Delimiter-Separated Values (CSV/TXT)</td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">Data Interchange Format (DIF)</td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">Symbolic Link (SYLK/SLK)</td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">Lotus Formatted Text (PRN)</td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">UTF-16 Unicode Text (TXT)</td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><strong>Other Workbook/Worksheet Formats</strong></td>
|
|
<td align="center">:-----:</td>
|
|
<td align="center">:-----:</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">Numbers 3.0+ / iWork 2013+ Spreadsheet (NUMBERS)</td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">OpenDocument Spreadsheet (ODS)</td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">Flat XML ODF Spreadsheet (FODS)</td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">Uniform Office Format Spreadsheet (标文通 UOS1/UOS2)</td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
<td align="center"></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">dBASE II/III/IV / Visual FoxPro (DBF)</td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">Lotus 1-2-3 (WK1/WK3)</td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">Lotus 1-2-3 (WKS/WK2/WK4/123)</td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
<td align="center"></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">Quattro Pro Spreadsheet (WQ1/WQ2/WB1/WB2/WB3/QPW)</td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
<td align="center"></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">Works 1.x-3.x DOS / 2.x-5.x Windows Spreadsheet (WKS)</td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
<td align="center"></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">Works 6.x-9.x Spreadsheet (XLR)</td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
<td align="center"></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><strong>Other Common Spreadsheet Output Formats</strong></td>
|
|
<td align="center">:-----:</td>
|
|
<td align="center">:-----:</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">HTML Tables</td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">Rich Text Format tables (RTF)</td>
|
|
<td align="center"></td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">Ethercalc Record Format (ETH)</td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
<td align="center"><g-emoji class="g-emoji" alias="heavy_check_mark" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2714.png">✔</g-emoji></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>Features not supported by a given file format will not be written. Formats with
|
|
range limits will be silently truncated:</p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th align="left">Format</th>
|
|
<th align="left">Last Cell</th>
|
|
<th align="right">Max Cols</th>
|
|
<th align="right">Max Rows</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td align="left">Excel 2007+ XML Formats (XLSX/XLSM)</td>
|
|
<td align="left">XFD1048576</td>
|
|
<td align="right">16384</td>
|
|
<td align="right">1048576</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">Excel 2007+ Binary Format (XLSB BIFF12)</td>
|
|
<td align="left">XFD1048576</td>
|
|
<td align="right">16384</td>
|
|
<td align="right">1048576</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">Numbers 12.0 (NUMBERS)</td>
|
|
<td align="left">ALL1000000</td>
|
|
<td align="right">1000</td>
|
|
<td align="right">1000000</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">Quattro Pro 9+ (QPW)</td>
|
|
<td align="left">IV1000000</td>
|
|
<td align="right">256</td>
|
|
<td align="right">1000000</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">Excel 97-2004 (XLS BIFF8)</td>
|
|
<td align="left">IV65536</td>
|
|
<td align="right">256</td>
|
|
<td align="right">65536</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">Excel 5.0/95 (XLS BIFF5)</td>
|
|
<td align="left">IV16384</td>
|
|
<td align="right">256</td>
|
|
<td align="right">16384</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">Excel 4.0 (XLS BIFF4)</td>
|
|
<td align="left">IV16384</td>
|
|
<td align="right">256</td>
|
|
<td align="right">16384</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">Excel 3.0 (XLS BIFF3)</td>
|
|
<td align="left">IV16384</td>
|
|
<td align="right">256</td>
|
|
<td align="right">16384</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">Excel 2.0/2.1 (XLS BIFF2)</td>
|
|
<td align="left">IV16384</td>
|
|
<td align="right">256</td>
|
|
<td align="right">16384</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">Lotus 1-2-3 R2 - R5 (WK1/WK3/WK4)</td>
|
|
<td align="left">IV8192</td>
|
|
<td align="right">256</td>
|
|
<td align="right">8192</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left">Lotus 1-2-3 R1 (WKS)</td>
|
|
<td align="left">IV2048</td>
|
|
<td align="right">256</td>
|
|
<td align="right">2048</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>Excel 2003 SpreadsheetML range limits are governed by the version of Excel and
|
|
are not enforced by the writer.</p>
|
|
<details>
|
|
<summary><b>File Format Details</b> (click to show)</summary>
|
|
<p><strong>Core Spreadsheet Formats</strong></p>
|
|
<ul>
|
|
<li><strong>Excel 2007+ XML (XLSX/XLSM)</strong></li>
|
|
</ul>
|
|
<p>XLSX and XLSM files are ZIP containers containing a series of XML files in
|
|
accordance with the Open Packaging Conventions (OPC). The XLSM format, almost
|
|
identical to XLSX, is used for files containing macros.</p>
|
|
<p>The format is standardized in ECMA-376 and later in ISO/IEC 29500. Excel does
|
|
not follow the specification, and there are additional documents discussing how
|
|
Excel deviates from the specification.</p>
|
|
<ul>
|
|
<li><strong>Excel 2.0-95 (BIFF2/BIFF3/BIFF4/BIFF5)</strong></li>
|
|
</ul>
|
|
<p>BIFF 2/3 XLS are single-sheet streams of binary records. Excel 4 introduced
|
|
the concept of a workbook (<code>XLW</code> files) but also had single-sheet <code>XLS</code> format.
|
|
The structure is largely similar to the Lotus 1-2-3 file formats. BIFF5/8/12
|
|
extended the format in various ways but largely stuck to the same record format.</p>
|
|
<p>Multiplan 4 "Normal" files are identical in structure to BIFF2 and use the same
|
|
cell value records. There are some different record types for more advanced
|
|
features like Print Settings. The BIFF2 writer generates files that can be read
|
|
in Multiplan 4 and the parser can extract values from "Normal" files.</p>
|
|
<p>There is no official specification for any of these formats. Excel 95 can write
|
|
files in these formats, so record lengths and fields were determined by writing
|
|
in all of the supported formats and comparing files. Excel 2016 can generate
|
|
BIFF5 files, enabling a full suite of file tests starting from XLSX or BIFF2.</p>
|
|
<ul>
|
|
<li><strong>Excel 97-2004 Binary (BIFF8)</strong></li>
|
|
</ul>
|
|
<p>BIFF8 exclusively uses the Compound File Binary container format, splitting some
|
|
content into streams within the file. At its core, it still uses an extended
|
|
version of the binary record format from older versions of BIFF.</p>
|
|
<p>The <code>MS-XLS</code> specification covers the basics of the file format, and other
|
|
specifications expand on serialization of features like properties.</p>
|
|
<ul>
|
|
<li><strong>Excel 2003-2004 (SpreadsheetML)</strong></li>
|
|
</ul>
|
|
<p>Predating XLSX, SpreadsheetML files are simple XML files. There is no official
|
|
and comprehensive specification, although MS has released documentation on the
|
|
format. Since Excel 2016 can generate SpreadsheetML files, mapping features is
|
|
pretty straightforward.</p>
|
|
<ul>
|
|
<li><strong>Excel 2007+ Binary (XLSB, BIFF12)</strong></li>
|
|
</ul>
|
|
<p>Introduced in parallel with XLSX, the XLSB format combines the BIFF architecture
|
|
with the content separation and ZIP container of XLSX. For the most part nodes
|
|
in an XLSX sub-file can be mapped to XLSB records in a corresponding sub-file.</p>
|
|
<p>The <code>MS-XLSB</code> specification covers the basics of the file format, and other
|
|
specifications expand on serialization of features like properties.</p>
|
|
<ul>
|
|
<li><strong>Delimiter-Separated Values (CSV/TXT)</strong></li>
|
|
</ul>
|
|
<p>Excel CSV deviates from RFC4180 in a number of important ways. The generated
|
|
CSV files should generally work in Excel although they may not work in RFC4180
|
|
compatible readers. The parser should generally understand Excel CSV. The
|
|
writer proactively generates cells for formulae if values are unavailable.</p>
|
|
<p>Excel TXT uses tab as the delimiter and code page 1200.</p>
|
|
<p>Like in Excel, files starting with <code>0x49 0x44 ("ID")</code> are treated as Symbolic
|
|
Link files. Unlike Excel, if the file does not have a valid SYLK header, it
|
|
will be proactively reinterpreted as CSV. There are some files with semicolon
|
|
delimiter that align with a valid SYLK file. For the broadest compatibility,
|
|
all cells with the value of <code>ID</code> are automatically wrapped in double-quotes.</p>
|
|
<p><strong>Miscellaneous Workbook Formats</strong></p>
|
|
<p>Support for other formats is generally far behind XLS/XLSB/XLSX support, due in
|
|
part to a lack of publicly available documentation. Test files were produced in
|
|
the respective apps and compared to their XLS exports to determine structure.
|
|
The main focus is data extraction.</p>
|
|
<ul>
|
|
<li><strong>Lotus 1-2-3 (WKS/WK1/WK2/WK3/WK4/123)</strong></li>
|
|
</ul>
|
|
<p>The Lotus formats consist of binary records similar to the BIFF structure. Lotus
|
|
did release a specification decades ago covering the original WK1 format. Other
|
|
features were deduced by producing files and comparing to Excel support.</p>
|
|
<p>Generated WK1 worksheets are compatible with Lotus 1-2-3 R2 and Excel 5.0.</p>
|
|
<p>Generated WK3 workbooks are compatible with Lotus 1-2-3 R9 and Excel 5.0.</p>
|
|
<ul>
|
|
<li><strong>Quattro Pro (WQ1/WQ2/WB1/WB2/WB3/QPW)</strong></li>
|
|
</ul>
|
|
<p>The Quattro Pro formats use binary records in the same way as BIFF and Lotus.
|
|
Some of the newer formats (namely WB3 and QPW) use a CFB enclosure just like
|
|
BIFF8 XLS.</p>
|
|
<ul>
|
|
<li><strong>Works for DOS / Windows Spreadsheet (WKS/XLR)</strong></li>
|
|
</ul>
|
|
<p>All versions of Works were limited to a single worksheet.</p>
|
|
<p>Works for DOS 1.x - 3.x and Works for Windows 2.x extends the Lotus WKS format
|
|
with additional record types.</p>
|
|
<p>Works for Windows 3.x - 5.x uses the same format and WKS extension. The BOF
|
|
record has type <code>FF</code></p>
|
|
<p>Works for Windows 6.x - 9.x use the XLR format. XLR is nearly identical to
|
|
BIFF8 XLS: it uses the CFB container with a Workbook stream. Works 9 saves the
|
|
exact Workbook stream for the XLR and the 97-2003 XLS export. Works 6 XLS
|
|
includes two empty worksheets but the main worksheet has an identical encoding.
|
|
XLR also includes a <code>WksSSWorkBook</code> stream similar to Lotus FM3/FMT files.</p>
|
|
<ul>
|
|
<li><strong>Numbers 3.0+ / iWork 2013+ Spreadsheet (NUMBERS)</strong></li>
|
|
</ul>
|
|
<p>iWork 2013 (Numbers 3.0 / Pages 5.0 / Keynote 6.0) switched from a proprietary
|
|
XML-based format to the current file format based on the iWork Archive (IWA).
|
|
This format has been used up through the current release (Numbers 11.2).</p>
|
|
<p>The parser focuses on extracting raw data from tables. Numbers technically
|
|
supports multiple tables in a logical worksheet, including custom titles. This
|
|
parser will generate one worksheet per Numbers table.</p>
|
|
<p>The writer currently exports a small range from the first worksheet.</p>
|
|
<ul>
|
|
<li><strong>OpenDocument Spreadsheet (ODS/FODS)</strong></li>
|
|
</ul>
|
|
<p>ODS is an XML-in-ZIP format akin to XLSX while FODS is an XML format akin to
|
|
SpreadsheetML. Both are detailed in the OASIS standard, but tools like LO/OO
|
|
add undocumented extensions. The parsers and writers do not implement the full
|
|
standard, instead focusing on parts necessary to extract and store raw data.</p>
|
|
<ul>
|
|
<li><strong>Uniform Office Spreadsheet (UOS1/2)</strong></li>
|
|
</ul>
|
|
<p>UOS is a very similar format, and it comes in 2 varieties corresponding to ODS
|
|
and FODS respectively. For the most part, the difference between the formats
|
|
is in the names of tags and attributes.</p>
|
|
<p><strong>Miscellaneous Worksheet Formats</strong></p>
|
|
<p>Many older formats supported only one worksheet:</p>
|
|
<ul>
|
|
<li><strong>dBASE and Visual FoxPro (DBF)</strong></li>
|
|
</ul>
|
|
<p>DBF is really a typed table format: each column can only hold one data type and
|
|
each record omits type information. The parser generates a header row and
|
|
inserts records starting at the second row of the worksheet. The writer makes
|
|
files compatible with Visual FoxPro extensions.</p>
|
|
<p>Multi-file extensions like external memos and tables are currently unsupported,
|
|
limited by the general ability to read arbitrary files in the web browser. The
|
|
reader understands DBF Level 7 extensions like DATETIME.</p>
|
|
<ul>
|
|
<li><strong>Symbolic Link (SYLK)</strong></li>
|
|
</ul>
|
|
<p><a href="https://oss.sheetjs.com/notes/sylk/" rel="nofollow">https://oss.sheetjs.com/notes/sylk/</a> is an informal specification based on our
|
|
experimentation and previous documentation efforts.</p>
|
|
<ul>
|
|
<li><strong>Lotus Formatted Text (PRN)</strong></li>
|
|
</ul>
|
|
<p>There is no real documentation, and in fact Excel treats PRN as an output-only
|
|
file format. Nevertheless we can guess the column widths and reverse-engineer
|
|
the original layout. Excel's 240 character width limitation is not enforced.</p>
|
|
<ul>
|
|
<li><strong>Data Interchange Format (DIF)</strong></li>
|
|
</ul>
|
|
<p>There is no unified definition. Visicalc DIF differs from Lotus DIF, and both
|
|
differ from Excel DIF. Where ambiguous, the parser/writer follows the expected
|
|
behavior from Excel. In particular, Excel extends DIF in incompatible ways:</p>
|
|
<ul>
|
|
<li>
|
|
<p>Since Excel automatically converts numbers-as-strings to numbers, numeric
|
|
string constants are converted to formulae: <code>"0.3" -> "=""0.3""</code></p>
|
|
</li>
|
|
<li>
|
|
<p>DIF technically expects numeric cells to hold the raw numeric data, but Excel
|
|
permits formatted numbers (including dates)</p>
|
|
</li>
|
|
<li>
|
|
<p>DIF technically has no support for formulae, but Excel will automatically
|
|
convert plain formulae. Array formulae are not preserved.</p>
|
|
</li>
|
|
<li>
|
|
<p><strong>HTML</strong></p>
|
|
</li>
|
|
</ul>
|
|
<p>Excel HTML worksheets include special metadata encoded in styles. For example,
|
|
<code>mso-number-format</code> is a localized string containing the number format. Despite
|
|
the metadata the output is valid HTML, although it does accept bare <code>&</code> symbols.</p>
|
|
<p>The writer adds type metadata to the TD elements via the <code>t</code> tag. The parser
|
|
looks for those tags and overrides the default interpretation. For example, text
|
|
like <code><td>12345</td></code> will be parsed as numbers but <code><td t="s">12345</td></code> will
|
|
be parsed as text.</p>
|
|
<ul>
|
|
<li><strong>Rich Text Format (RTF)</strong></li>
|
|
</ul>
|
|
<p>Excel RTF worksheets are stored in clipboard when copying cells or ranges from a
|
|
worksheet. The supported codes are a subset of the Word RTF support.</p>
|
|
<ul>
|
|
<li><strong>Ethercalc Record Format (ETH)</strong></li>
|
|
</ul>
|
|
<p><a href="https://ethercalc.net/" rel="nofollow">Ethercalc</a> is an open source web spreadsheet powered by
|
|
a record format reminiscent of SYLK wrapped in a MIME multi-part message.</p>
|
|
</details>
|
|
<h2>
|
|
<a id="user-content-testing" class="anchor" href="#testing" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Testing</h2>
|
|
<h3>
|
|
<a id="user-content-node" class="anchor" href="#node" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Node</h3>
|
|
<details>
|
|
<summary>(click to show)</summary>
|
|
<p><code>make test</code> will run the node-based tests. By default it runs tests on files in
|
|
every supported format. To test a specific file type, set <code>FMTS</code> to the format
|
|
you want to test. Feature-specific tests are available with <code>make test_misc</code></p>
|
|
<div class="highlight highlight-source-shell"><pre>$ make test_misc <span class="pl-c"><span class="pl-c">#</span> run core tests</span>
|
|
$ make <span class="pl-c1">test</span> <span class="pl-c"><span class="pl-c">#</span> run full tests</span>
|
|
$ make test_xls <span class="pl-c"><span class="pl-c">#</span> only use the XLS test files</span>
|
|
$ make test_xlsx <span class="pl-c"><span class="pl-c">#</span> only use the XLSX test files</span>
|
|
$ make test_xlsb <span class="pl-c"><span class="pl-c">#</span> only use the XLSB test files</span>
|
|
$ make test_xml <span class="pl-c"><span class="pl-c">#</span> only use the XML test files</span>
|
|
$ make test_ods <span class="pl-c"><span class="pl-c">#</span> only use the ODS test files</span></pre></div>
|
|
<p>To enable all errors, set the environment variable <code>WTF=1</code>:</p>
|
|
<div class="highlight highlight-source-shell"><pre>$ make <span class="pl-c1">test</span> <span class="pl-c"><span class="pl-c">#</span> run full tests</span>
|
|
$ WTF=1 make <span class="pl-c1">test</span> <span class="pl-c"><span class="pl-c">#</span> enable all error messages</span></pre></div>
|
|
<p><code>flow</code> and <code>eslint</code> checks are available:</p>
|
|
<div class="highlight highlight-source-shell"><pre>$ make lint <span class="pl-c"><span class="pl-c">#</span> eslint checks</span>
|
|
$ make flow <span class="pl-c"><span class="pl-c">#</span> make lint + Flow checking</span>
|
|
$ make tslint <span class="pl-c"><span class="pl-c">#</span> check TS definitions</span></pre></div>
|
|
</details>
|
|
<h3>
|
|
<a id="user-content-browser" class="anchor" href="#browser" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Browser</h3>
|
|
<details>
|
|
<summary>(click to show)</summary>
|
|
<p>The core in-browser tests are available at <code>tests/index.html</code> within this repo.
|
|
Start a local server and navigate to that directory to run the tests.
|
|
<code>make ctestserv</code> will start a server on port 8000.</p>
|
|
<p><code>make ctest</code> will generate the browser fixtures. To add more files, edit the
|
|
<code>tests/fixtures.lst</code> file and add the paths.</p>
|
|
<p>To run the full in-browser tests, clone the repo for
|
|
<a href="https://github.com/SheetJS/SheetJS.github.io"><code>oss.sheetjs.com</code></a> and replace
|
|
the <code>xlsx.js</code> file (then open a browser window and go to <code>stress.html</code>):</p>
|
|
<div class="highlight highlight-source-shell"><pre>$ cp xlsx.js ../SheetJS.github.io
|
|
$ <span class="pl-c1">cd</span> ../SheetJS.github.io
|
|
$ simplehttpserver <span class="pl-c"><span class="pl-c">#</span> or "python -mSimpleHTTPServer" or "serve"</span>
|
|
$ open -a Chromium.app http://localhost:8000/stress.html</pre></div>
|
|
</details>
|
|
<h3>
|
|
<a id="user-content-tested-environments" class="anchor" href="#tested-environments" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Tested Environments</h3>
|
|
<details>
|
|
<summary>(click to show)</summary>
|
|
<ul>
|
|
<li>NodeJS <code>0.8</code>, <code>0.10</code>, <code>0.12</code>, <code>4.x</code>, <code>5.x</code>, <code>6.x</code>, <code>7.x</code>, <code>8.x</code>
|
|
</li>
|
|
<li>IE 6/7/8/9/10/11 (IE 6-9 require shims)</li>
|
|
<li>Chrome 24+ (including Android 4.0+)</li>
|
|
<li>Safari 6+ (iOS and Desktop)</li>
|
|
<li>Edge 13+, FF 18+, and Opera 12+</li>
|
|
</ul>
|
|
<p>Tests utilize the mocha testing framework.</p>
|
|
<ul>
|
|
<li>
|
|
<a href="https://saucelabs.com/u/sheetjs" rel="nofollow">https://saucelabs.com/u/sheetjs</a> for XLS* modules using Sauce Labs</li>
|
|
</ul>
|
|
<p>The test suite also includes tests for various time zones. To change
|
|
the timezone locally, set the TZ environment variable:</p>
|
|
<div class="highlight highlight-source-shell"><pre>$ env TZ=<span class="pl-s"><span class="pl-pds">"</span>Asia/Kolkata<span class="pl-pds">"</span></span> WTF=1 make test_misc</pre></div>
|
|
</details>
|
|
<h3>
|
|
<a id="user-content-test-files" class="anchor" href="#test-files" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Test Files</h3>
|
|
<p>Test files are housed in <a href="https://github.com/SheetJS/test_files">another repo</a>.</p>
|
|
<p>Running <code>make init</code> will refresh the <code>test_files</code> submodule and get the files.
|
|
Note that this requires <code>svn</code>, <code>git</code>, <code>hg</code> and other commands that may not be
|
|
available. If <code>make init</code> fails, please download the latest version of the test
|
|
files snapshot from <a href="https://github.com/SheetJS/test_files/releases">the repo</a></p>
|
|
<details>
|
|
<summary><b>Latest Snapshot</b> (click to show)</summary>
|
|
<p>Latest test files snapshot:
|
|
<a href="http://github.com/SheetJS/test_files/releases/download/20170409/test_files.zip">http://github.com/SheetJS/test_files/releases/download/20170409/test_files.zip</a></p>
|
|
<p>(download and unzip to the <code>test_files</code> subdirectory)</p>
|
|
</details>
|
|
<h2>
|
|
<a id="user-content-contributing" class="anchor" href="#contributing" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Contributing</h2>
|
|
<p>Due to the precarious nature of the Open Specifications Promise, it is very
|
|
important to ensure code is cleanroom. <a href="CONTRIBUTING.md">Contribution Notes</a></p>
|
|
<details>
|
|
<summary><b>File organization</b> (click to show)</summary>
|
|
<p>At a high level, the final script is a concatenation of the individual files in
|
|
the <code>bits</code> folder. Running <code>make</code> should reproduce the final output on all
|
|
platforms. The README is similarly split into bits in the <code>docbits</code> folder.</p>
|
|
<p>Folders:</p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th align="left">folder</th>
|
|
<th align="left">contents</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td align="left"><code>bits</code></td>
|
|
<td align="left">raw source files that make up the final script</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>docbits</code></td>
|
|
<td align="left">raw markdown files that make up <code>README.md</code>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>bin</code></td>
|
|
<td align="left">server-side bin scripts (<code>xlsx.njs</code>)</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>dist</code></td>
|
|
<td align="left">dist files for web browsers and nonstandard JS environments</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>demos</code></td>
|
|
<td align="left">demo projects for platforms like ExtendScript and Webpack</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>tests</code></td>
|
|
<td align="left">browser tests (run <code>make ctest</code> to rebuild)</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>types</code></td>
|
|
<td align="left">typescript definitions and tests</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>misc</code></td>
|
|
<td align="left">miscellaneous supporting scripts</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="left"><code>test_files</code></td>
|
|
<td align="left">test files (pulled from the test files repository)</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</details>
|
|
<p>After cloning the repo, running <code>make help</code> will display a list of commands.</p>
|
|
<h3>
|
|
<a id="user-content-osxlinux" class="anchor" href="#osxlinux" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>OSX/Linux</h3>
|
|
<details>
|
|
<summary>(click to show)</summary>
|
|
<p>The <code>xlsx.js</code> file is constructed from the files in the <code>bits</code> subdirectory. The
|
|
build script (run <code>make</code>) will concatenate the individual bits to produce the
|
|
script. Before submitting a contribution, ensure that running make will produce
|
|
the <code>xlsx.js</code> file exactly. The simplest way to test is to add the script:</p>
|
|
<div class="highlight highlight-source-shell"><pre>$ git add xlsx.js
|
|
$ make clean
|
|
$ make
|
|
$ git diff xlsx.js</pre></div>
|
|
<p>To produce the dist files, run <code>make dist</code>. The dist files are updated in each
|
|
version release and <em>should not be committed between versions</em>.</p>
|
|
</details>
|
|
<h3>
|
|
<a id="user-content-windows" class="anchor" href="#windows" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Windows</h3>
|
|
<details>
|
|
<summary>(click to show)</summary>
|
|
<p>The included <code>make.cmd</code> script will build <code>xlsx.js</code> from the <code>bits</code> directory.
|
|
Building is as simple as:</p>
|
|
<div class="highlight highlight-source-batchfile"><pre><span class="pl-k">></span> make</pre></div>
|
|
<p>To prepare development environment:</p>
|
|
<div class="highlight highlight-source-batchfile"><pre><span class="pl-k">></span> make init</pre></div>
|
|
<p>The full list of commands available in Windows are displayed in <code>make help</code>:</p>
|
|
<pre><code>make init -- install deps and global modules
|
|
make lint -- run eslint linter
|
|
make test -- run mocha test suite
|
|
make misc -- run smaller test suite
|
|
make book -- rebuild README and summary
|
|
make help -- display this message
|
|
</code></pre>
|
|
<p>As explained in <a href="#test-files">Test Files</a>, on Windows the release ZIP file must
|
|
be downloaded and extracted. If Bash on Windows is available, it is possible
|
|
to run the OSX/Linux workflow. The following steps prepares the environment:</p>
|
|
<div class="highlight highlight-source-shell"><pre><span class="pl-c"><span class="pl-c">#</span> Install support programs for the build and test commands</span>
|
|
sudo apt-get install make git subversion mercurial
|
|
|
|
<span class="pl-c"><span class="pl-c">#</span> Install nodejs and NPM within the WSL</span>
|
|
wget -qO- https://deb.nodesource.com/setup_8.x <span class="pl-k">|</span> sudo bash
|
|
sudo apt-get install nodejs
|
|
|
|
<span class="pl-c"><span class="pl-c">#</span> Install dev dependencies</span>
|
|
sudo npm install -g mocha voc blanket xlsjs</pre></div>
|
|
</details>
|
|
<h3>
|
|
<a id="user-content-tests" class="anchor" href="#tests" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Tests</h3>
|
|
<details>
|
|
<summary>(click to show)</summary>
|
|
<p>The <code>test_misc</code> target (<code>make test_misc</code> on Linux/OSX / <code>make misc</code> on Windows)
|
|
runs the targeted feature tests. It should take 5-10 seconds to perform feature
|
|
tests without testing against the entire test battery. New features should be
|
|
accompanied with tests for the relevant file formats and features.</p>
|
|
<p>For tests involving the read side, an appropriate feature test would involve
|
|
reading an existing file and checking the resulting workbook object. If a
|
|
parameter is involved, files should be read with different values to verify that
|
|
the feature is working as expected.</p>
|
|
<p>For tests involving a new write feature which can already be parsed, appropriate
|
|
feature tests would involve writing a workbook with the feature and then opening
|
|
and verifying that the feature is preserved.</p>
|
|
<p>For tests involving a new write feature without an existing read ability, please
|
|
add a feature test to the kitchen sink <code>tests/write.js</code>.</p>
|
|
</details>
|
|
<h2>
|
|
<a id="user-content-license" class="anchor" href="#license" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>License</h2>
|
|
<p>Please consult the attached LICENSE file for details. All rights not explicitly
|
|
granted by the Apache 2.0 License are reserved by the Original Author.</p>
|
|
<h2>
|
|
<a id="user-content-references" class="anchor" href="#references" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>References</h2>
|
|
<details>
|
|
<summary><b>OSP-covered Specifications</b> (click to show)</summary>
|
|
<ul>
|
|
<li>
|
|
<code>MS-CFB</code>: Compound File Binary File Format</li>
|
|
<li>
|
|
<code>MS-CTXLS</code>: Excel Custom Toolbar Binary File Format</li>
|
|
<li>
|
|
<code>MS-EXSPXML3</code>: Excel Calculation Version 2 Web Service XML Schema</li>
|
|
<li>
|
|
<code>MS-ODATA</code>: Open Data Protocol (OData)</li>
|
|
<li>
|
|
<code>MS-ODRAW</code>: Office Drawing Binary File Format</li>
|
|
<li>
|
|
<code>MS-ODRAWXML</code>: Office Drawing Extensions to Office Open XML Structure</li>
|
|
<li>
|
|
<code>MS-OE376</code>: Office Implementation Information for ECMA-376 Standards Support</li>
|
|
<li>
|
|
<code>MS-OFFCRYPTO</code>: Office Document Cryptography Structure</li>
|
|
<li>
|
|
<code>MS-OI29500</code>: Office Implementation Information for ISO/IEC 29500 Standards Support</li>
|
|
<li>
|
|
<code>MS-OLEDS</code>: Object Linking and Embedding (OLE) Data Structures</li>
|
|
<li>
|
|
<code>MS-OLEPS</code>: Object Linking and Embedding (OLE) Property Set Data Structures</li>
|
|
<li>
|
|
<code>MS-OODF3</code>: Office Implementation Information for ODF 1.2 Standards Support</li>
|
|
<li>
|
|
<code>MS-OSHARED</code>: Office Common Data Types and Objects Structures</li>
|
|
<li>
|
|
<code>MS-OVBA</code>: Office VBA File Format Structure</li>
|
|
<li>
|
|
<code>MS-XLDM</code>: Spreadsheet Data Model File Format</li>
|
|
<li>
|
|
<code>MS-XLS</code>: Excel Binary File Format (.xls) Structure Specification</li>
|
|
<li>
|
|
<code>MS-XLSB</code>: Excel (.xlsb) Binary File Format</li>
|
|
<li>
|
|
<code>MS-XLSX</code>: Excel (.xlsx) Extensions to the Office Open XML SpreadsheetML File Format</li>
|
|
<li>
|
|
<code>XLS</code>: Microsoft Office Excel 97-2007 Binary File Format Specification</li>
|
|
<li>
|
|
<code>RTF</code>: Rich Text Format</li>
|
|
</ul>
|
|
</details>
|
|
<ul>
|
|
<li>ISO/IEC 29500:2012(E) "Information technology — Document description and processing languages — Office Open XML File Formats"</li>
|
|
<li>Open Document Format for Office Applications Version 1.2 (29 September 2011)</li>
|
|
<li>Worksheet File Format (From Lotus) December 1984</li>
|
|
</ul>
|
|
|
|
</article>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
<div> </div>
|
|
</div><script>
|
|
function showCanonicalImages() {
|
|
var images = document.getElementsByTagName('img');
|
|
if (!images) {
|
|
return;
|
|
}
|
|
for (var index = 0; index < images.length; index++) {
|
|
var image = images[index];
|
|
if (image.getAttribute('data-canonical-src') && image.src !== image.getAttribute('data-canonical-src')) {
|
|
image.src = image.getAttribute('data-canonical-src');
|
|
}
|
|
}
|
|
}
|
|
|
|
function scrollToHash() {
|
|
if (location.hash && !document.querySelector(':target')) {
|
|
var element = document.getElementById('user-content-' + location.hash.slice(1));
|
|
if (element) {
|
|
element.scrollIntoView();
|
|
}
|
|
}
|
|
}
|
|
|
|
function autorefreshContent(eventSourceUrl) {
|
|
var initialTitle = document.title;
|
|
var contentElement = document.getElementById('grip-content');
|
|
var source = new EventSource(eventSourceUrl);
|
|
var isRendering = false;
|
|
|
|
source.onmessage = function(ev) {
|
|
var msg = JSON.parse(ev.data);
|
|
if (msg.updating) {
|
|
isRendering = true;
|
|
document.title = '(Rendering) ' + document.title;
|
|
} else {
|
|
isRendering = false;
|
|
document.title = initialTitle;
|
|
contentElement.innerHTML = msg.content;
|
|
showCanonicalImages();
|
|
}
|
|
}
|
|
|
|
source.onerror = function(e) {
|
|
if (e.readyState === EventSource.CLOSED && isRendering) {
|
|
isRendering = false;
|
|
document.title = initialTitle;
|
|
}
|
|
}
|
|
}
|
|
|
|
window.onhashchange = function() {
|
|
scrollToHash();
|
|
}
|
|
|
|
window.onload = function() {
|
|
scrollToHash();
|
|
}
|
|
|
|
showCanonicalImages();
|
|
|
|
var autorefreshUrl = document.getElementById('preview-page').getAttribute('data-autorefresh-url');
|
|
if (autorefreshUrl) {
|
|
autorefreshContent(autorefreshUrl);
|
|
}
|
|
</script>
|
|
</body>
|
|
</html> |