├── .appcast.xml
├── .gitignore
├── LICENSE
├── README.md
├── assets
└── icon.png
├── design-token-exporter.sketchplugin
└── Contents
│ ├── Resources
│ └── icon.png
│ └── Sketch
│ ├── __colorTokens.js
│ ├── __colorTokens.js.map
│ ├── __exportTokens.js
│ ├── __exportTokens.js.map
│ ├── __spacingTokens.js
│ ├── __spacingTokens.js.map
│ ├── __textObjects.js
│ ├── __textObjects.js.map
│ ├── __textTokens.js
│ ├── __textTokens.js.map
│ ├── colorTokens.js
│ ├── colorTokens.js.map
│ ├── exportTokens.js
│ ├── exportTokens.js.map
│ ├── manifest.json
│ ├── spacingTokens.js
│ ├── spacingTokens.js.map
│ ├── textObjects.js
│ ├── textObjects.js.map
│ ├── textTokens.js
│ └── textTokens.js.map
├── images
├── colors.gif
├── exportTokens.gif
├── fontsize.gif
├── gitcover.jpg
├── spacing.gif
└── textstyles.gif
├── package-lock.json
├── package.json
└── src
├── colorTokens.js
├── exportTokens.js
├── lib
├── dialogFields.js
├── formatObject.js
├── hexAToRGBA.js
├── tokenValue.js
├── values.js
└── varNaming.js
├── manifest.json
├── spacingTokens.js
├── textObjects.js
└── textTokens.js
/.appcast.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | -
5 |
6 |
7 | -
8 |
9 |
10 | -
11 |
12 |
13 | -
14 |
15 |
16 | -
17 |
18 |
19 | -
20 |
21 |
22 | -
23 |
24 |
25 | -
26 |
27 |
28 | -
29 |
30 |
31 | -
32 |
33 |
34 | -
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # build artifacts
2 | # design-token-exporter.sketchplugin
3 |
4 | # npm
5 | node_modules
6 | .npm
7 | npm-debug.log
8 |
9 | # mac
10 | .DS_Store
11 |
12 | # WebStorm
13 | .idea
14 |
15 | # sketch
16 | # sketch-assets
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2019 Herkko Huttunen
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining
6 | a copy of this software and associated documentation files (the
7 | "Software"), to deal in the Software without restriction, including
8 | without limitation the rights to use, copy, modify, merge, publish,
9 | distribute, sublicense, and/or sell copies of the Software, and to
10 | permit persons to whom the Software is furnished to do so, subject to
11 | the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included
14 | in all copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # This project is not maintained anymore
4 |
5 | ## Design Token Exporter
6 |
7 | **Export Design Tokens from your Sketch project.**
8 |
9 | - You can export Design Token file either JSON or YAML format. Token file follow Salesforce [Theo](https://github.com/salesforce-ux/theo) spec.
10 | - Layers naming format is type/category/tokenname (e.g. color/background-color/bg-light)
11 |
12 | **Available categories:**
13 |
14 | | Category | Sketch Layer type | Value |
15 | | --------------------------- | ------------------------------ | --------------------------------------------------------- |
16 | | `spacing`/`space`/`spacer` | Shape Layer | Layer height |
17 | | `sizing`/`size` | Shape Layer | Layer height |
18 | | `font` | Text Layer | Font weight (type=number) / Font Family (type=...) |
19 | | `font-style` | Text Layer | Font style |
20 | | `font-weight` | Text Layer | Font weight |
21 | | `font-size` | Text Layer | Font Size |
22 | | `line-height` | Text Layer | Line height |
23 | | `font-family` | Text Layer | Font Family |
24 | | `border-style` | Shape Layer | Border style |
25 | | `border-color` | Shape Layer | Border style or Fill color |
26 | | `radius` | Shape Layer | Radius |
27 | | `border-radius` | Shape Layer | Radius |
28 | | `hr-color` | Shape Layer | Fill color |
29 | | `background-color` | Shape Layer | Fill color |
30 | | `gradient` | Shape Layer | Fill gradient |
31 | | `background-gradient` | Shape Layer | Fill gradient |
32 | | `drop-shadow` | Shape Layer | Shadows |
33 | | `box-shadow` | Shape Layer | Shadows |
34 | | `inner-shadow` | Shape Layer | Inner Shadows |
35 | | `text-color` | Shape Layer or Text Layer | Text color or Fill color |
36 | | `text-shadow` | Shape Layer or Text Layer | Layer shadow |
37 | | `time` | Text Layer | Text layer value |
38 | | `media-query` | Text Layer | Text layer value |
39 | | `z-index` | Text Layer | Text layer value |
40 | | `any` | Shape Layer | Fill color (type=color) |
41 |
42 |
43 | **Export variables from your Sketch project. You can export colors, text, spacing variables and text styles.**
44 |
45 | - You can choose file format: SCSS, CSS, LESS, JSON, JavaScript (Object/Variables)
46 | - You can choose color format: HEX or RGBA
47 | - You can choose text value: font family, font size, font weight, line height or letter spacing
48 | - You can choose units: Absolute (px) or Relative (rem)
49 | - You can choose naming (kebab-case, camelCase or part of layer name)
50 |
51 | ## Features
52 |
53 | 1. Export Tokens
54 | 2. Export Color Variables
55 | 3. Export Text Variables
56 | 4. Export Spacing Variables
57 | 5. Export Text Styles
58 |
59 | ### 1. Export Tokens
60 |
61 | Select layers or one artboard and go to `Plugins -> Design Token Exporter -> Export Tokens`
62 |
63 | 
64 |
65 | **Example output - tokens.yml**
66 |
67 | ```yml
68 | props:
69 | gray_1:
70 | value: "#fafaf9"
71 | type: "color"
72 | category: "gray"
73 | gradient_background:
74 | value: "linear-gradient(180deg, #FAFAF9 0%, #F3F2F2 100%)"
75 | type: "..."
76 | category: "gradient"
77 | spacing_m:
78 | value: "16px"
79 | type: "number"
80 | category: "spacing"
81 | font_size_l:
82 | value: "24px"
83 | type: "number"
84 | category: "font-size"
85 | ```
86 |
87 | ### 2. Export Color Variables
88 |
89 | Select layers and go to `Plugins -> Design Token Exporter -> Export Color Variables`
90 |
91 | 
92 |
93 | **Example output - colors.scss (SCSS, HEX)**
94 |
95 | ```scss
96 | $primary1: #b39ddb;
97 | $primary2: #673ab7;
98 | $primary3: #512da8;
99 | $primary4: #311b92;
100 | $secondary1: #b2dfdb;
101 | $secondary2: #4db6ac;
102 | $secondary3: #009688;
103 | $secondary4: #00796b;
104 | $grey1: #cfd8dc;
105 | $grey2: #90a4ae;
106 | $grey3: #607d8b;
107 | $grey4: #37474f;
108 | ```
109 |
110 | ### 3. Export Text Variables
111 |
112 | Select layers and go to `Plugins -> Design Token Exporter -> Export Text Variables`
113 |
114 | 
115 |
116 | **Example output - fontsize.json (JSON, Font size, Absolute(px))**
117 |
118 | ```json
119 | {
120 | "fontSize": {
121 | "xxl": "64px",
122 | "xl": "48px",
123 | "l": "32px",
124 | "m": "24px",
125 | "s": "20px",
126 | "xs": "16px",
127 | "xxs": "12px"
128 | }
129 | }
130 | ```
131 |
132 | ### 4. Export Spacing Variables
133 |
134 | Select layers and go to `Plugins -> Design Token Exporter -> Export Spacing Variables`
135 |
136 | 
137 |
138 | **Example output - spacing.css (CSS, Relative(rem))**
139 |
140 | ```css
141 | :root {
142 | --spacing-xxs: 0.25rem;
143 | --spacing-xs: 0.5rem;
144 | --spacing-s: 1rem;
145 | --spacing-m: 1.5rem;
146 | --spacing-l: 3rem;
147 | --spacing-xl: 4rem;
148 | --spacing-xxl: 8rem;
149 | }
150 | ```
151 |
152 | ### 5. Export Text Styles
153 |
154 | Select layers and go to `Plugins -> Design Token Exporter -> Export Text Styles`
155 |
156 | 
157 |
158 | **Example output - textstyles.js (JavaScript Object, Absolute(px))**
159 |
160 | ```js
161 | const textStyles = {
162 | h1: {
163 | fontFamily: "Museo Sans",
164 | fontSize: "64px",
165 | fontWeight: 300,
166 | lineHeight: "64px",
167 | letterSpacing: "normal",
168 | textTransform: "none",
169 | },
170 | h2: {
171 | fontFamily: "Museo Sans",
172 | fontSize: "48px",
173 | fontWeight: 300,
174 | lineHeight: "48px",
175 | letterSpacing: "normal",
176 | textTransform: "none",
177 | },
178 | h3: {
179 | fontFamily: "Museo Sans",
180 | fontSize: "32px",
181 | fontWeight: 300,
182 | lineHeight: "48px",
183 | letterSpacing: "normal",
184 | textTransform: "none",
185 | },
186 | h4: {
187 | fontFamily: "Museo Sans",
188 | fontSize: "24px",
189 | fontWeight: 500,
190 | lineHeight: "36px",
191 | letterSpacing: "normal",
192 | textTransform: "none",
193 | },
194 | title: {
195 | fontFamily: "Museo Sans",
196 | fontSize: "20px",
197 | fontWeight: 700,
198 | lineHeight: "36px",
199 | letterSpacing: "1.5px",
200 | textTransform: "uppercase",
201 | },
202 | body: {
203 | fontFamily: "Museo Sans",
204 | fontSize: "16px",
205 | fontWeight: 500,
206 | lineHeight: "24px",
207 | letterSpacing: "normal",
208 | textTransform: "none",
209 | },
210 | caption: {
211 | fontFamily: "Museo Sans",
212 | fontSize: "12px",
213 | fontWeight: 500,
214 | lineHeight: "18px",
215 | letterSpacing: "normal",
216 | textTransform: "none",
217 | },
218 | }
219 | ```
220 |
221 |
222 | ## License
223 |
224 | This project is licensed under the terms of the MIT license.
225 |
--------------------------------------------------------------------------------
/assets/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/here-erhe/Design-Token-Exporter/876d92c845a4500a8babf68e4a63ca56f43e3951/assets/icon.png
--------------------------------------------------------------------------------
/design-token-exporter.sketchplugin/Contents/Resources/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/here-erhe/Design-Token-Exporter/876d92c845a4500a8babf68e4a63ca56f43e3951/design-token-exporter.sketchplugin/Contents/Resources/icon.png
--------------------------------------------------------------------------------
/design-token-exporter.sketchplugin/Contents/Sketch/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Design Token Exporter",
3 | "identifier": "fi.erhe.design-token-exporter",
4 | "description": "Simple Design Token Exporter",
5 | "homepage": "https://github.com/here-erhe/Design-Token-Exporter",
6 | "author": "Herkko Huttunen",
7 | "icon": "icon.png",
8 | "compatibleVersion": "54.0",
9 | "commands": [
10 | {
11 | "name": "Export Tokens",
12 | "identifier": "tokens.tokens",
13 | "script": "__exportTokens.js",
14 | "description": "Export multiple multiple layers or one artboard"
15 | },
16 | {
17 | "name": "Export Colors Variables",
18 | "identifier": "tokens.colors",
19 | "script": "__colorTokens.js",
20 | "description": "Export selected layers"
21 | },
22 | {
23 | "name": "Export Text Variables",
24 | "identifier": "tokens.text",
25 | "script": "__textTokens.js",
26 | "description": "Export selected layers"
27 | },
28 | {
29 | "name": "Export Spacing Variables",
30 | "identifier": "tokens.spacing",
31 | "script": "__spacingTokens.js",
32 | "description": "Export selected layers"
33 | },
34 | {
35 | "name": "Export Text Styles",
36 | "identifier": "tokens.styles",
37 | "script": "__textObjects.js",
38 | "description": "Export selected layers"
39 | }
40 | ],
41 | "menu": {
42 | "title": "Design Token Exporter",
43 | "items": [
44 | "tokens.tokens",
45 | "-",
46 | "tokens.colors",
47 | "tokens.text",
48 | "tokens.spacing",
49 | "-",
50 | "tokens.styles"
51 | ]
52 | },
53 | "version": "1.0.0",
54 | "disableCocoaScriptPreprocessor": true,
55 | "appcast": "https://raw.githubusercontent.com/here-erhe/Design-Token-Exporter/master/.appcast.xml"
56 | }
--------------------------------------------------------------------------------
/design-token-exporter.sketchplugin/Contents/Sketch/spacingTokens.js:
--------------------------------------------------------------------------------
1 | var globalThis=this;function __skpm_run(n,t){globalThis.context=t;var r=function(n){var t={};function r(e){if(t[e])return t[e].exports;var u=t[e]={i:e,l:!1,exports:{}};return n[e].call(u.exports,u,u.exports,r),u.l=!0,u.exports}return r.m=n,r.c=t,r.d=function(n,t,e){r.o(n,t)||Object.defineProperty(n,t,{enumerable:!0,get:e})},r.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},r.t=function(n,t){if(1&t&&(n=r(n)),8&t)return n;if(4&t&&"object"==typeof n&&n&&n.__esModule)return n;var e=Object.create(null);if(r.r(e),Object.defineProperty(e,"default",{enumerable:!0,value:n}),2&t&&"string"!=typeof n)for(var u in n)r.d(e,u,function(t){return n[t]}.bind(null,u));return e},r.n=function(n){var t=n&&n.__esModule?function(){return n.default}:function(){return n};return r.d(t,"a",t),t},r.o=function(n,t){return Object.prototype.hasOwnProperty.call(n,t)},r.p="",r(r.s=7)}([function(n,t,r){(function(n,e){var u;(function(){var i,o=200,a="Unsupported core-js use. Try https://npms.io/search?q=ponyfill.",f="Expected a function",c="__lodash_hash_undefined__",l=500,s="__lodash_placeholder__",p=1,h=2,v=4,_=1,g=2,y=1,d=2,b=4,w=8,m=16,x=32,S=64,j=128,A=256,O=512,k=30,E="...",I=800,R=16,C=1,z=2,W=1/0,L=9007199254740991,T=17976931348623157e292,N=NaN,B=4294967295,U=B-1,M=B>>>1,F=[["ary",j],["bind",y],["bindKey",d],["curry",w],["curryRight",m],["flip",O],["partial",x],["partialRight",S],["rearg",A]],P="[object Arguments]",$="[object Array]",D="[object AsyncFunction]",q="[object Boolean]",V="[object Date]",J="[object DOMException]",Z="[object Error]",K="[object Function]",Y="[object GeneratorFunction]",G="[object Map]",H="[object Number]",Q="[object Null]",X="[object Object]",nn="[object Proxy]",tn="[object RegExp]",rn="[object Set]",en="[object String]",un="[object Symbol]",on="[object Undefined]",an="[object WeakMap]",fn="[object WeakSet]",cn="[object ArrayBuffer]",ln="[object DataView]",sn="[object Float32Array]",pn="[object Float64Array]",hn="[object Int8Array]",vn="[object Int16Array]",_n="[object Int32Array]",gn="[object Uint8Array]",yn="[object Uint8ClampedArray]",dn="[object Uint16Array]",bn="[object Uint32Array]",wn=/\b__p \+= '';/g,mn=/\b(__p \+=) '' \+/g,xn=/(__e\(.*?\)|\b__t\)) \+\n'';/g,Sn=/&(?:amp|lt|gt|quot|#39);/g,jn=/[&<>"']/g,An=RegExp(Sn.source),On=RegExp(jn.source),kn=/<%-([\s\S]+?)%>/g,En=/<%([\s\S]+?)%>/g,In=/<%=([\s\S]+?)%>/g,Rn=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,Cn=/^\w*$/,zn=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,Wn=/[\\^$.*+?()[\]{}|]/g,Ln=RegExp(Wn.source),Tn=/^\s+|\s+$/g,Nn=/^\s+/,Bn=/\s+$/,Un=/\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,Mn=/\{\n\/\* \[wrapped with (.+)\] \*/,Fn=/,? & /,Pn=/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g,$n=/\\(\\)?/g,Dn=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,qn=/\w*$/,Vn=/^[-+]0x[0-9a-f]+$/i,Jn=/^0b[01]+$/i,Zn=/^\[object .+?Constructor\]$/,Kn=/^0o[0-7]+$/i,Yn=/^(?:0|[1-9]\d*)$/,Gn=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g,Hn=/($^)/,Qn=/['\n\r\u2028\u2029\\]/g,Xn="\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff",nt="\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000",tt="[\\ud800-\\udfff]",rt="["+nt+"]",et="["+Xn+"]",ut="\\d+",it="[\\u2700-\\u27bf]",ot="[a-z\\xdf-\\xf6\\xf8-\\xff]",at="[^\\ud800-\\udfff"+nt+ut+"\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde]",ft="\\ud83c[\\udffb-\\udfff]",ct="[^\\ud800-\\udfff]",lt="(?:\\ud83c[\\udde6-\\uddff]){2}",st="[\\ud800-\\udbff][\\udc00-\\udfff]",pt="[A-Z\\xc0-\\xd6\\xd8-\\xde]",ht="(?:"+ot+"|"+at+")",vt="(?:"+pt+"|"+at+")",_t="(?:"+et+"|"+ft+")"+"?",gt="[\\ufe0e\\ufe0f]?"+_t+("(?:\\u200d(?:"+[ct,lt,st].join("|")+")[\\ufe0e\\ufe0f]?"+_t+")*"),yt="(?:"+[it,lt,st].join("|")+")"+gt,dt="(?:"+[ct+et+"?",et,lt,st,tt].join("|")+")",bt=RegExp("['’]","g"),wt=RegExp(et,"g"),mt=RegExp(ft+"(?="+ft+")|"+dt+gt,"g"),xt=RegExp([pt+"?"+ot+"+(?:['’](?:d|ll|m|re|s|t|ve))?(?="+[rt,pt,"$"].join("|")+")",vt+"+(?:['’](?:D|LL|M|RE|S|T|VE))?(?="+[rt,pt+ht,"$"].join("|")+")",pt+"?"+ht+"+(?:['’](?:d|ll|m|re|s|t|ve))?",pt+"+(?:['’](?:D|LL|M|RE|S|T|VE))?","\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])","\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])",ut,yt].join("|"),"g"),St=RegExp("[\\u200d\\ud800-\\udfff"+Xn+"\\ufe0e\\ufe0f]"),jt=/[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/,At=["Array","Buffer","DataView","Date","Error","Float32Array","Float64Array","Function","Int8Array","Int16Array","Int32Array","Map","Math","Object","Promise","RegExp","Set","String","Symbol","TypeError","Uint8Array","Uint8ClampedArray","Uint16Array","Uint32Array","WeakMap","_","clearTimeout","isFinite","parseInt","setTimeout"],Ot=-1,kt={};kt[sn]=kt[pn]=kt[hn]=kt[vn]=kt[_n]=kt[gn]=kt[yn]=kt[dn]=kt[bn]=!0,kt[P]=kt[$]=kt[cn]=kt[q]=kt[ln]=kt[V]=kt[Z]=kt[K]=kt[G]=kt[H]=kt[X]=kt[tn]=kt[rn]=kt[en]=kt[an]=!1;var Et={};Et[P]=Et[$]=Et[cn]=Et[ln]=Et[q]=Et[V]=Et[sn]=Et[pn]=Et[hn]=Et[vn]=Et[_n]=Et[G]=Et[H]=Et[X]=Et[tn]=Et[rn]=Et[en]=Et[un]=Et[gn]=Et[yn]=Et[dn]=Et[bn]=!0,Et[Z]=Et[K]=Et[an]=!1;var It={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},Rt=parseFloat,Ct=parseInt,zt="object"==typeof n&&n&&n.Object===Object&&n,Wt="object"==typeof self&&self&&self.Object===Object&&self,Lt=zt||Wt||Function("return this")(),Tt=t&&!t.nodeType&&t,Nt=Tt&&"object"==typeof e&&e&&!e.nodeType&&e,Bt=Nt&&Nt.exports===Tt,Ut=Bt&&zt.process,Mt=function(){try{var n=Nt&&Nt.require&&Nt.require("util").types;return n||Ut&&Ut.binding&&Ut.binding("util")}catch(t){}}(),Ft=Mt&&Mt.isArrayBuffer,Pt=Mt&&Mt.isDate,$t=Mt&&Mt.isMap,Dt=Mt&&Mt.isRegExp,qt=Mt&&Mt.isSet,Vt=Mt&&Mt.isTypedArray;function Jt(n,t,r){switch(r.length){case 0:return n.call(t);case 1:return n.call(t,r[0]);case 2:return n.call(t,r[0],r[1]);case 3:return n.call(t,r[0],r[1],r[2])}return n.apply(t,r)}function Zt(n,t,r,e){for(var u=-1,i=null==n?0:n.length;++u-1}function Xt(n,t,r){for(var e=-1,u=null==n?0:n.length;++e-1;);return r}function mr(n,t){for(var r=n.length;r--&&fr(t,n[r],0)>-1;);return r}var xr=hr({"À":"A","Á":"A","Â":"A","Ã":"A","Ä":"A","Å":"A","à":"a","á":"a","â":"a","ã":"a","ä":"a","å":"a","Ç":"C","ç":"c","Ð":"D","ð":"d","È":"E","É":"E","Ê":"E","Ë":"E","è":"e","é":"e","ê":"e","ë":"e","Ì":"I","Í":"I","Î":"I","Ï":"I","ì":"i","í":"i","î":"i","ï":"i","Ñ":"N","ñ":"n","Ò":"O","Ó":"O","Ô":"O","Õ":"O","Ö":"O","Ø":"O","ò":"o","ó":"o","ô":"o","õ":"o","ö":"o","ø":"o","Ù":"U","Ú":"U","Û":"U","Ü":"U","ù":"u","ú":"u","û":"u","ü":"u","Ý":"Y","ý":"y","ÿ":"y","Æ":"Ae","æ":"ae","Þ":"Th","þ":"th","ß":"ss","Ā":"A","Ă":"A","Ą":"A","ā":"a","ă":"a","ą":"a","Ć":"C","Ĉ":"C","Ċ":"C","Č":"C","ć":"c","ĉ":"c","ċ":"c","č":"c","Ď":"D","Đ":"D","ď":"d","đ":"d","Ē":"E","Ĕ":"E","Ė":"E","Ę":"E","Ě":"E","ē":"e","ĕ":"e","ė":"e","ę":"e","ě":"e","Ĝ":"G","Ğ":"G","Ġ":"G","Ģ":"G","ĝ":"g","ğ":"g","ġ":"g","ģ":"g","Ĥ":"H","Ħ":"H","ĥ":"h","ħ":"h","Ĩ":"I","Ī":"I","Ĭ":"I","Į":"I","İ":"I","ĩ":"i","ī":"i","ĭ":"i","į":"i","ı":"i","Ĵ":"J","ĵ":"j","Ķ":"K","ķ":"k","ĸ":"k","Ĺ":"L","Ļ":"L","Ľ":"L","Ŀ":"L","Ł":"L","ĺ":"l","ļ":"l","ľ":"l","ŀ":"l","ł":"l","Ń":"N","Ņ":"N","Ň":"N","Ŋ":"N","ń":"n","ņ":"n","ň":"n","ŋ":"n","Ō":"O","Ŏ":"O","Ő":"O","ō":"o","ŏ":"o","ő":"o","Ŕ":"R","Ŗ":"R","Ř":"R","ŕ":"r","ŗ":"r","ř":"r","Ś":"S","Ŝ":"S","Ş":"S","Š":"S","ś":"s","ŝ":"s","ş":"s","š":"s","Ţ":"T","Ť":"T","Ŧ":"T","ţ":"t","ť":"t","ŧ":"t","Ũ":"U","Ū":"U","Ŭ":"U","Ů":"U","Ű":"U","Ų":"U","ũ":"u","ū":"u","ŭ":"u","ů":"u","ű":"u","ų":"u","Ŵ":"W","ŵ":"w","Ŷ":"Y","ŷ":"y","Ÿ":"Y","Ź":"Z","Ż":"Z","Ž":"Z","ź":"z","ż":"z","ž":"z","IJ":"IJ","ij":"ij","Œ":"Oe","œ":"oe","ʼn":"'n","ſ":"s"}),Sr=hr({"&":"&","<":"<",">":">",'"':""","'":"'"});function jr(n){return"\\"+It[n]}function Ar(n){return St.test(n)}function Or(n){var t=-1,r=Array(n.size);return n.forEach(function(n,e){r[++t]=[e,n]}),r}function kr(n,t){return function(r){return n(t(r))}}function Er(n,t){for(var r=-1,e=n.length,u=0,i=[];++r",""":'"',"'":"'"});var Lr=function n(t){var r,e=(t=null==t?Lt:Lr.defaults(Lt.Object(),t,Lr.pick(Lt,At))).Array,u=t.Date,Xn=t.Error,nt=t.Function,tt=t.Math,rt=t.Object,et=t.RegExp,ut=t.String,it=t.TypeError,ot=e.prototype,at=nt.prototype,ft=rt.prototype,ct=t["__core-js_shared__"],lt=at.toString,st=ft.hasOwnProperty,pt=0,ht=(r=/[^.]+$/.exec(ct&&ct.keys&&ct.keys.IE_PROTO||""))?"Symbol(src)_1."+r:"",vt=ft.toString,_t=lt.call(rt),gt=Lt._,yt=et("^"+lt.call(st).replace(Wn,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),dt=Bt?t.Buffer:i,mt=t.Symbol,St=t.Uint8Array,It=dt?dt.allocUnsafe:i,zt=kr(rt.getPrototypeOf,rt),Wt=rt.create,Tt=ft.propertyIsEnumerable,Nt=ot.splice,Ut=mt?mt.isConcatSpreadable:i,Mt=mt?mt.iterator:i,ir=mt?mt.toStringTag:i,hr=function(){try{var n=Ui(rt,"defineProperty");return n({},"",{}),n}catch(t){}}(),Tr=t.clearTimeout!==Lt.clearTimeout&&t.clearTimeout,Nr=u&&u.now!==Lt.Date.now&&u.now,Br=t.setTimeout!==Lt.setTimeout&&t.setTimeout,Ur=tt.ceil,Mr=tt.floor,Fr=rt.getOwnPropertySymbols,Pr=dt?dt.isBuffer:i,$r=t.isFinite,Dr=ot.join,qr=kr(rt.keys,rt),Vr=tt.max,Jr=tt.min,Zr=u.now,Kr=t.parseInt,Yr=tt.random,Gr=ot.reverse,Hr=Ui(t,"DataView"),Qr=Ui(t,"Map"),Xr=Ui(t,"Promise"),ne=Ui(t,"Set"),te=Ui(t,"WeakMap"),re=Ui(rt,"create"),ee=te&&new te,ue={},ie=lo(Hr),oe=lo(Qr),ae=lo(Xr),fe=lo(ne),ce=lo(te),le=mt?mt.prototype:i,se=le?le.valueOf:i,pe=le?le.toString:i;function he(n){if(Ea(n)&&!ya(n)&&!(n instanceof ye)){if(n instanceof ge)return n;if(st.call(n,"__wrapped__"))return so(n)}return new ge(n)}var ve=function(){function n(){}return function(t){if(!ka(t))return{};if(Wt)return Wt(t);n.prototype=t;var r=new n;return n.prototype=i,r}}();function _e(){}function ge(n,t){this.__wrapped__=n,this.__actions__=[],this.__chain__=!!t,this.__index__=0,this.__values__=i}function ye(n){this.__wrapped__=n,this.__actions__=[],this.__dir__=1,this.__filtered__=!1,this.__iteratees__=[],this.__takeCount__=B,this.__views__=[]}function de(n){var t=-1,r=null==n?0:n.length;for(this.clear();++t=t?n:t)),n}function Te(n,t,r,e,u,o){var a,f=t&p,c=t&h,l=t&v;if(r&&(a=u?r(n,e,u,o):r(n)),a!==i)return a;if(!ka(n))return n;var s=ya(n);if(s){if(a=function(n){var t=n.length,r=new n.constructor(t);return t&&"string"==typeof n[0]&&st.call(n,"index")&&(r.index=n.index,r.input=n.input),r}(n),!f)return ri(n,a)}else{var _=Pi(n),g=_==K||_==Y;if(ma(n))return Gu(n,f);if(_==X||_==P||g&&!u){if(a=c||g?{}:Di(n),!f)return c?function(n,t){return ei(n,Fi(n),t)}(n,function(n,t){return n&&ei(t,of(t),n)}(a,n)):function(n,t){return ei(n,Mi(n),t)}(n,Ce(a,n))}else{if(!Et[_])return u?n:{};a=function(n,t,r){var e,u=n.constructor;switch(t){case cn:return Hu(n);case q:case V:return new u(+n);case ln:return function(n,t){var r=t?Hu(n.buffer):n.buffer;return new n.constructor(r,n.byteOffset,n.byteLength)}(n,r);case sn:case pn:case hn:case vn:case _n:case gn:case yn:case dn:case bn:return Qu(n,r);case G:return new u;case H:case en:return new u(n);case tn:return function(n){var t=new n.constructor(n.source,qn.exec(n));return t.lastIndex=n.lastIndex,t}(n);case rn:return new u;case un:return e=n,se?rt(se.call(e)):{}}}(n,_,f)}}o||(o=new xe);var y=o.get(n);if(y)return y;o.set(n,a),Wa(n)?n.forEach(function(e){a.add(Te(e,t,r,e,n,o))}):Ia(n)&&n.forEach(function(e,u){a.set(u,Te(e,t,r,u,n,o))});var d=s?i:(l?c?Ci:Ri:c?of:uf)(n);return Kt(d||n,function(e,u){d&&(e=n[u=e]),Ee(a,u,Te(e,t,r,u,n,o))}),a}function Ne(n,t,r){var e=r.length;if(null==n)return!e;for(n=rt(n);e--;){var u=r[e],o=t[u],a=n[u];if(a===i&&!(u in n)||!o(a))return!1}return!0}function Be(n,t,r){if("function"!=typeof n)throw new it(f);return eo(function(){n.apply(i,r)},t)}function Ue(n,t,r,e){var u=-1,i=Qt,a=!0,f=n.length,c=[],l=t.length;if(!f)return c;r&&(t=nr(t,yr(r))),e?(i=Xt,a=!1):t.length>=o&&(i=br,a=!1,t=new me(t));n:for(;++u-1},be.prototype.set=function(n,t){var r=this.__data__,e=Ie(r,n);return e<0?(++this.size,r.push([n,t])):r[e][1]=t,this},we.prototype.clear=function(){this.size=0,this.__data__={hash:new de,map:new(Qr||be),string:new de}},we.prototype.delete=function(n){var t=Ni(this,n).delete(n);return this.size-=t?1:0,t},we.prototype.get=function(n){return Ni(this,n).get(n)},we.prototype.has=function(n){return Ni(this,n).has(n)},we.prototype.set=function(n,t){var r=Ni(this,n),e=r.size;return r.set(n,t),this.size+=r.size==e?0:1,this},me.prototype.add=me.prototype.push=function(n){return this.__data__.set(n,c),this},me.prototype.has=function(n){return this.__data__.has(n)},xe.prototype.clear=function(){this.__data__=new be,this.size=0},xe.prototype.delete=function(n){var t=this.__data__,r=t.delete(n);return this.size=t.size,r},xe.prototype.get=function(n){return this.__data__.get(n)},xe.prototype.has=function(n){return this.__data__.has(n)},xe.prototype.set=function(n,t){var r=this.__data__;if(r instanceof be){var e=r.__data__;if(!Qr||e.length0&&r(a)?t>1?qe(a,t-1,r,e,u):tr(u,a):e||(u[u.length]=a)}return u}var Ve=ai(),Je=ai(!0);function Ze(n,t){return n&&Ve(n,t,uf)}function Ke(n,t){return n&&Je(n,t,uf)}function Ye(n,t){return Ht(t,function(t){return ja(n[t])})}function Ge(n,t){for(var r=0,e=(t=Ju(t,n)).length;null!=n&&rt}function nu(n,t){return null!=n&&st.call(n,t)}function tu(n,t){return null!=n&&t in rt(n)}function ru(n,t,r){for(var u=r?Xt:Qt,o=n[0].length,a=n.length,f=a,c=e(a),l=1/0,s=[];f--;){var p=n[f];f&&t&&(p=nr(p,yr(t))),l=Jr(p.length,l),c[f]=!r&&(t||o>=120&&p.length>=120)?new me(f&&p):i}p=n[0];var h=-1,v=c[0];n:for(;++h=a)return f;var c=r[e];return f*("desc"==c?-1:1)}}return n.index-t.index}(n,t,r)})}function du(n,t,r){for(var e=-1,u=t.length,i={};++e-1;)a!==n&&Nt.call(a,f,1),Nt.call(n,f,1);return n}function wu(n,t){for(var r=n?t.length:0,e=r-1;r--;){var u=t[r];if(r==e||u!==i){var i=u;Vi(u)?Nt.call(n,u,1):Uu(n,u)}}return n}function mu(n,t){return n+Mr(Yr()*(t-n+1))}function xu(n,t){var r="";if(!n||t<1||t>L)return r;do{t%2&&(r+=n),(t=Mr(t/2))&&(n+=n)}while(t);return r}function Su(n,t){return uo(Xi(n,t,Cf),n+"")}function ju(n){return je(vf(n))}function Au(n,t){var r=vf(n);return ao(r,Le(t,0,r.length))}function Ou(n,t,r,e){if(!ka(n))return n;for(var u=-1,o=(t=Ju(t,n)).length,a=o-1,f=n;null!=f&&++ui?0:i+t),(r=r>i?i:r)<0&&(r+=i),i=t>r?0:r-t>>>0,t>>>=0;for(var o=e(i);++u>>1,o=n[i];null!==o&&!Ta(o)&&(r?o<=t:o=o){var l=t?null:xi(n);if(l)return Ir(l);a=!1,u=br,c=new me}else c=t?[]:f;n:for(;++e=e?n:Ru(n,t,r)}var Yu=Tr||function(n){return Lt.clearTimeout(n)};function Gu(n,t){if(t)return n.slice();var r=n.length,e=It?It(r):new n.constructor(r);return n.copy(e),e}function Hu(n){var t=new n.constructor(n.byteLength);return new St(t).set(new St(n)),t}function Qu(n,t){var r=t?Hu(n.buffer):n.buffer;return new n.constructor(r,n.byteOffset,n.length)}function Xu(n,t){if(n!==t){var r=n!==i,e=null===n,u=n==n,o=Ta(n),a=t!==i,f=null===t,c=t==t,l=Ta(t);if(!f&&!l&&!o&&n>t||o&&a&&c&&!f&&!l||e&&a&&c||!r&&c||!u)return 1;if(!e&&!o&&!l&&n1?r[u-1]:i,a=u>2?r[2]:i;for(o=n.length>3&&"function"==typeof o?(u--,o):i,a&&Ji(r[0],r[1],a)&&(o=u<3?i:o,u=1),t=rt(t);++e-1?u[o?t[a]:a]:i}}function pi(n){return Ii(function(t){var r=t.length,e=r,u=ge.prototype.thru;for(n&&t.reverse();e--;){var o=t[e];if("function"!=typeof o)throw new it(f);if(u&&!a&&"wrapper"==Wi(o))var a=new ge([],!0)}for(e=a?e:r;++e1&&w.reverse(),p&&lf))return!1;var l=o.get(n);if(l&&o.get(t))return l==t;var s=-1,p=!0,h=r&g?new me:i;for(o.set(n,t),o.set(t,n);++s-1&&n%1==0&&n1?"& ":"")+t[e],t=t.join(r>2?", ":" "),n.replace(Un,"{\n/* [wrapped with "+t+"] */\n")}(e,function(n,t){return Kt(F,function(r){var e="_."+r[0];t&r[1]&&!Qt(n,e)&&n.push(e)}),n.sort()}(function(n){var t=n.match(Mn);return t?t[1].split(Fn):[]}(e),r)))}function oo(n){var t=0,r=0;return function(){var e=Zr(),u=R-(e-r);if(r=e,u>0){if(++t>=I)return arguments[0]}else t=0;return n.apply(i,arguments)}}function ao(n,t){var r=-1,e=n.length,u=e-1;for(t=t===i?e:t;++r1?n[t-1]:i;return r="function"==typeof r?(n.pop(),r):i,zo(n,r)});function Mo(n){var t=he(n);return t.__chain__=!0,t}function Fo(n,t){return t(n)}var Po=Ii(function(n){var t=n.length,r=t?n[0]:0,e=this.__wrapped__,u=function(t){return We(t,n)};return!(t>1||this.__actions__.length)&&e instanceof ye&&Vi(r)?((e=e.slice(r,+r+(t?1:0))).__actions__.push({func:Fo,args:[u],thisArg:i}),new ge(e,this.__chain__).thru(function(n){return t&&!n.length&&n.push(i),n})):this.thru(u)});var $o=ui(function(n,t,r){st.call(n,r)?++n[r]:ze(n,r,1)});var Do=si(_o),qo=si(go);function Vo(n,t){return(ya(n)?Kt:Me)(n,Ti(t,3))}function Jo(n,t){return(ya(n)?Yt:Fe)(n,Ti(t,3))}var Zo=ui(function(n,t,r){st.call(n,r)?n[r].push(t):ze(n,r,[t])});var Ko=Su(function(n,t,r){var u=-1,i="function"==typeof t,o=ba(n)?e(n.length):[];return Me(n,function(n){o[++u]=i?Jt(t,n,r):eu(n,t,r)}),o}),Yo=ui(function(n,t,r){ze(n,r,t)});function Go(n,t){return(ya(n)?nr:pu)(n,Ti(t,3))}var Ho=ui(function(n,t,r){n[r?0:1].push(t)},function(){return[[],[]]});var Qo=Su(function(n,t){if(null==n)return[];var r=t.length;return r>1&&Ji(n,t[0],t[1])?t=[]:r>2&&Ji(t[0],t[1],t[2])&&(t=[t[0]]),yu(n,qe(t,1),[])}),Xo=Nr||function(){return Lt.Date.now()};function na(n,t,r){return t=r?i:t,t=n&&null==t?n.length:t,ji(n,j,i,i,i,i,t)}function ta(n,t){var r;if("function"!=typeof t)throw new it(f);return n=Pa(n),function(){return--n>0&&(r=t.apply(this,arguments)),n<=1&&(t=i),r}}var ra=Su(function(n,t,r){var e=y;if(r.length){var u=Er(r,Li(ra));e|=x}return ji(n,e,t,r,u)}),ea=Su(function(n,t,r){var e=y|d;if(r.length){var u=Er(r,Li(ea));e|=x}return ji(t,e,n,r,u)});function ua(n,t,r){var e,u,o,a,c,l,s=0,p=!1,h=!1,v=!0;if("function"!=typeof n)throw new it(f);function _(t){var r=e,o=u;return e=u=i,s=t,a=n.apply(o,r)}function g(n){var r=n-l;return l===i||r>=t||r<0||h&&n-s>=o}function y(){var n=Xo();if(g(n))return d(n);c=eo(y,function(n){var r=t-(n-l);return h?Jr(r,o-(n-s)):r}(n))}function d(n){return c=i,v&&e?_(n):(e=u=i,a)}function b(){var n=Xo(),r=g(n);if(e=arguments,u=this,l=n,r){if(c===i)return function(n){return s=n,c=eo(y,t),p?_(n):a}(l);if(h)return Yu(c),c=eo(y,t),_(l)}return c===i&&(c=eo(y,t)),a}return t=Da(t)||0,ka(r)&&(p=!!r.leading,o=(h="maxWait"in r)?Vr(Da(r.maxWait)||0,t):o,v="trailing"in r?!!r.trailing:v),b.cancel=function(){c!==i&&Yu(c),s=0,e=l=u=c=i},b.flush=function(){return c===i?a:d(Xo())},b}var ia=Su(function(n,t){return Be(n,1,t)}),oa=Su(function(n,t,r){return Be(n,Da(t)||0,r)});function aa(n,t){if("function"!=typeof n||null!=t&&"function"!=typeof t)throw new it(f);var r=function(){var e=arguments,u=t?t.apply(this,e):e[0],i=r.cache;if(i.has(u))return i.get(u);var o=n.apply(this,e);return r.cache=i.set(u,o)||i,o};return r.cache=new(aa.Cache||we),r}function fa(n){if("function"!=typeof n)throw new it(f);return function(){var t=arguments;switch(t.length){case 0:return!n.call(this);case 1:return!n.call(this,t[0]);case 2:return!n.call(this,t[0],t[1]);case 3:return!n.call(this,t[0],t[1],t[2])}return!n.apply(this,t)}}aa.Cache=we;var ca=Zu(function(n,t){var r=(t=1==t.length&&ya(t[0])?nr(t[0],yr(Ti())):nr(qe(t,1),yr(Ti()))).length;return Su(function(e){for(var u=-1,i=Jr(e.length,r);++u=t}),ga=uu(function(){return arguments}())?uu:function(n){return Ea(n)&&st.call(n,"callee")&&!Tt.call(n,"callee")},ya=e.isArray,da=Ft?yr(Ft):function(n){return Ea(n)&&Qe(n)==cn};function ba(n){return null!=n&&Oa(n.length)&&!ja(n)}function wa(n){return Ea(n)&&ba(n)}var ma=Pr||qf,xa=Pt?yr(Pt):function(n){return Ea(n)&&Qe(n)==V};function Sa(n){if(!Ea(n))return!1;var t=Qe(n);return t==Z||t==J||"string"==typeof n.message&&"string"==typeof n.name&&!Ca(n)}function ja(n){if(!ka(n))return!1;var t=Qe(n);return t==K||t==Y||t==D||t==nn}function Aa(n){return"number"==typeof n&&n==Pa(n)}function Oa(n){return"number"==typeof n&&n>-1&&n%1==0&&n<=L}function ka(n){var t=typeof n;return null!=n&&("object"==t||"function"==t)}function Ea(n){return null!=n&&"object"==typeof n}var Ia=$t?yr($t):function(n){return Ea(n)&&Pi(n)==G};function Ra(n){return"number"==typeof n||Ea(n)&&Qe(n)==H}function Ca(n){if(!Ea(n)||Qe(n)!=X)return!1;var t=zt(n);if(null===t)return!0;var r=st.call(t,"constructor")&&t.constructor;return"function"==typeof r&&r instanceof r&<.call(r)==_t}var za=Dt?yr(Dt):function(n){return Ea(n)&&Qe(n)==tn};var Wa=qt?yr(qt):function(n){return Ea(n)&&Pi(n)==rn};function La(n){return"string"==typeof n||!ya(n)&&Ea(n)&&Qe(n)==en}function Ta(n){return"symbol"==typeof n||Ea(n)&&Qe(n)==un}var Na=Vt?yr(Vt):function(n){return Ea(n)&&Oa(n.length)&&!!kt[Qe(n)]};var Ba=bi(su),Ua=bi(function(n,t){return n<=t});function Ma(n){if(!n)return[];if(ba(n))return La(n)?zr(n):ri(n);if(Mt&&n[Mt])return function(n){for(var t,r=[];!(t=n.next()).done;)r.push(t.value);return r}(n[Mt]());var t=Pi(n);return(t==G?Or:t==rn?Ir:vf)(n)}function Fa(n){return n?(n=Da(n))===W||n===-W?(n<0?-1:1)*T:n==n?n:0:0===n?n:0}function Pa(n){var t=Fa(n),r=t%1;return t==t?r?t-r:t:0}function $a(n){return n?Le(Pa(n),0,B):0}function Da(n){if("number"==typeof n)return n;if(Ta(n))return N;if(ka(n)){var t="function"==typeof n.valueOf?n.valueOf():n;n=ka(t)?t+"":t}if("string"!=typeof n)return 0===n?n:+n;n=n.replace(Tn,"");var r=Jn.test(n);return r||Kn.test(n)?Ct(n.slice(2),r?2:8):Vn.test(n)?N:+n}function qa(n){return ei(n,of(n))}function Va(n){return null==n?"":Nu(n)}var Ja=ii(function(n,t){if(Gi(t)||ba(t))ei(t,uf(t),n);else for(var r in t)st.call(t,r)&&Ee(n,r,t[r])}),Za=ii(function(n,t){ei(t,of(t),n)}),Ka=ii(function(n,t,r,e){ei(t,of(t),n,e)}),Ya=ii(function(n,t,r,e){ei(t,uf(t),n,e)}),Ga=Ii(We);var Ha=Su(function(n,t){n=rt(n);var r=-1,e=t.length,u=e>2?t[2]:i;for(u&&Ji(t[0],t[1],u)&&(e=1);++r1),t}),ei(n,Ci(n),r),e&&(r=Te(r,p|h|v,ki));for(var u=t.length;u--;)Uu(r,t[u]);return r});var lf=Ii(function(n,t){return null==n?{}:function(n,t){return du(n,t,function(t,r){return nf(n,r)})}(n,t)});function sf(n,t){if(null==n)return{};var r=nr(Ci(n),function(n){return[n]});return t=Ti(t),du(n,r,function(n,r){return t(n,r[0])})}var pf=Si(uf),hf=Si(of);function vf(n){return null==n?[]:dr(n,uf(n))}var _f=ci(function(n,t,r){return t=t.toLowerCase(),n+(r?gf(t):t)});function gf(n){return jf(Va(n).toLowerCase())}function yf(n){return(n=Va(n))&&n.replace(Gn,xr).replace(wt,"")}var df=ci(function(n,t,r){return n+(r?"-":"")+t.toLowerCase()}),bf=ci(function(n,t,r){return n+(r?" ":"")+t.toLowerCase()}),wf=fi("toLowerCase");var mf=ci(function(n,t,r){return n+(r?"_":"")+t.toLowerCase()});var xf=ci(function(n,t,r){return n+(r?" ":"")+jf(t)});var Sf=ci(function(n,t,r){return n+(r?" ":"")+t.toUpperCase()}),jf=fi("toUpperCase");function Af(n,t,r){return n=Va(n),(t=r?i:t)===i?function(n){return jt.test(n)}(n)?function(n){return n.match(xt)||[]}(n):function(n){return n.match(Pn)||[]}(n):n.match(t)||[]}var Of=Su(function(n,t){try{return Jt(n,i,t)}catch(r){return Sa(r)?r:new Xn(r)}}),kf=Ii(function(n,t){return Kt(t,function(t){t=co(t),ze(n,t,ra(n[t],n))}),n});function Ef(n){return function(){return n}}var If=pi(),Rf=pi(!0);function Cf(n){return n}function zf(n){return fu("function"==typeof n?n:Te(n,p))}var Wf=Su(function(n,t){return function(r){return eu(r,n,t)}}),Lf=Su(function(n,t){return function(r){return eu(n,r,t)}});function Tf(n,t,r){var e=uf(t),u=Ye(t,e);null!=r||ka(t)&&(u.length||!e.length)||(r=t,t=n,n=this,u=Ye(t,uf(t)));var i=!(ka(r)&&"chain"in r&&!r.chain),o=ja(n);return Kt(u,function(r){var e=t[r];n[r]=e,o&&(n.prototype[r]=function(){var t=this.__chain__;if(i||t){var r=n(this.__wrapped__),u=r.__actions__=ri(this.__actions__);return u.push({func:e,args:arguments,thisArg:n}),r.__chain__=t,r}return e.apply(n,tr([this.value()],arguments))})}),n}function Nf(){}var Bf=gi(nr),Uf=gi(Gt),Mf=gi(ur);function Ff(n){return Zi(n)?pr(co(n)):function(n){return function(t){return Ge(t,n)}}(n)}var Pf=di(),$f=di(!0);function Df(){return[]}function qf(){return!1}var Vf=_i(function(n,t){return n+t},0),Jf=mi("ceil"),Zf=_i(function(n,t){return n/t},1),Kf=mi("floor");var Yf,Gf=_i(function(n,t){return n*t},1),Hf=mi("round"),Qf=_i(function(n,t){return n-t},0);return he.after=function(n,t){if("function"!=typeof t)throw new it(f);return n=Pa(n),function(){if(--n<1)return t.apply(this,arguments)}},he.ary=na,he.assign=Ja,he.assignIn=Za,he.assignInWith=Ka,he.assignWith=Ya,he.at=Ga,he.before=ta,he.bind=ra,he.bindAll=kf,he.bindKey=ea,he.castArray=function(){if(!arguments.length)return[];var n=arguments[0];return ya(n)?n:[n]},he.chain=Mo,he.chunk=function(n,t,r){t=(r?Ji(n,t,r):t===i)?1:Vr(Pa(t),0);var u=null==n?0:n.length;if(!u||t<1)return[];for(var o=0,a=0,f=e(Ur(u/t));ou?0:u+r),(e=e===i||e>u?u:Pa(e))<0&&(e+=u),e=r>e?0:$a(e);r>>0)?(n=Va(n))&&("string"==typeof t||null!=t&&!za(t))&&!(t=Nu(t))&&Ar(n)?Ku(zr(n),0,r):n.split(t,r):[]},he.spread=function(n,t){if("function"!=typeof n)throw new it(f);return t=null==t?0:Vr(Pa(t),0),Su(function(r){var e=r[t],u=Ku(r,0,t);return e&&tr(u,e),Jt(n,this,u)})},he.tail=function(n){var t=null==n?0:n.length;return t?Ru(n,1,t):[]},he.take=function(n,t,r){return n&&n.length?Ru(n,0,(t=r||t===i?1:Pa(t))<0?0:t):[]},he.takeRight=function(n,t,r){var e=null==n?0:n.length;return e?Ru(n,(t=e-(t=r||t===i?1:Pa(t)))<0?0:t,e):[]},he.takeRightWhile=function(n,t){return n&&n.length?Fu(n,Ti(t,3),!1,!0):[]},he.takeWhile=function(n,t){return n&&n.length?Fu(n,Ti(t,3)):[]},he.tap=function(n,t){return t(n),n},he.throttle=function(n,t,r){var e=!0,u=!0;if("function"!=typeof n)throw new it(f);return ka(r)&&(e="leading"in r?!!r.leading:e,u="trailing"in r?!!r.trailing:u),ua(n,t,{leading:e,maxWait:t,trailing:u})},he.thru=Fo,he.toArray=Ma,he.toPairs=pf,he.toPairsIn=hf,he.toPath=function(n){return ya(n)?nr(n,co):Ta(n)?[n]:ri(fo(Va(n)))},he.toPlainObject=qa,he.transform=function(n,t,r){var e=ya(n),u=e||ma(n)||Na(n);if(t=Ti(t,4),null==r){var i=n&&n.constructor;r=u?e?new i:[]:ka(n)&&ja(i)?ve(zt(n)):{}}return(u?Kt:Ze)(n,function(n,e,u){return t(r,n,e,u)}),r},he.unary=function(n){return na(n,1)},he.union=Eo,he.unionBy=Io,he.unionWith=Ro,he.uniq=function(n){return n&&n.length?Bu(n):[]},he.uniqBy=function(n,t){return n&&n.length?Bu(n,Ti(t,2)):[]},he.uniqWith=function(n,t){return t="function"==typeof t?t:i,n&&n.length?Bu(n,i,t):[]},he.unset=function(n,t){return null==n||Uu(n,t)},he.unzip=Co,he.unzipWith=zo,he.update=function(n,t,r){return null==n?n:Mu(n,t,Vu(r))},he.updateWith=function(n,t,r,e){return e="function"==typeof e?e:i,null==n?n:Mu(n,t,Vu(r),e)},he.values=vf,he.valuesIn=function(n){return null==n?[]:dr(n,of(n))},he.without=Wo,he.words=Af,he.wrap=function(n,t){return la(Vu(t),n)},he.xor=Lo,he.xorBy=To,he.xorWith=No,he.zip=Bo,he.zipObject=function(n,t){return Du(n||[],t||[],Ee)},he.zipObjectDeep=function(n,t){return Du(n||[],t||[],Ou)},he.zipWith=Uo,he.entries=pf,he.entriesIn=hf,he.extend=Za,he.extendWith=Ka,Tf(he,he),he.add=Vf,he.attempt=Of,he.camelCase=_f,he.capitalize=gf,he.ceil=Jf,he.clamp=function(n,t,r){return r===i&&(r=t,t=i),r!==i&&(r=(r=Da(r))==r?r:0),t!==i&&(t=(t=Da(t))==t?t:0),Le(Da(n),t,r)},he.clone=function(n){return Te(n,v)},he.cloneDeep=function(n){return Te(n,p|v)},he.cloneDeepWith=function(n,t){return Te(n,p|v,t="function"==typeof t?t:i)},he.cloneWith=function(n,t){return Te(n,v,t="function"==typeof t?t:i)},he.conformsTo=function(n,t){return null==t||Ne(n,t,uf(t))},he.deburr=yf,he.defaultTo=function(n,t){return null==n||n!=n?t:n},he.divide=Zf,he.endsWith=function(n,t,r){n=Va(n),t=Nu(t);var e=n.length,u=r=r===i?e:Le(Pa(r),0,e);return(r-=t.length)>=0&&n.slice(r,u)==t},he.eq=ha,he.escape=function(n){return(n=Va(n))&&On.test(n)?n.replace(jn,Sr):n},he.escapeRegExp=function(n){return(n=Va(n))&&Ln.test(n)?n.replace(Wn,"\\$&"):n},he.every=function(n,t,r){var e=ya(n)?Gt:Pe;return r&&Ji(n,t,r)&&(t=i),e(n,Ti(t,3))},he.find=Do,he.findIndex=_o,he.findKey=function(n,t){return or(n,Ti(t,3),Ze)},he.findLast=qo,he.findLastIndex=go,he.findLastKey=function(n,t){return or(n,Ti(t,3),Ke)},he.floor=Kf,he.forEach=Vo,he.forEachRight=Jo,he.forIn=function(n,t){return null==n?n:Ve(n,Ti(t,3),of)},he.forInRight=function(n,t){return null==n?n:Je(n,Ti(t,3),of)},he.forOwn=function(n,t){return n&&Ze(n,Ti(t,3))},he.forOwnRight=function(n,t){return n&&Ke(n,Ti(t,3))},he.get=Xa,he.gt=va,he.gte=_a,he.has=function(n,t){return null!=n&&$i(n,t,nu)},he.hasIn=nf,he.head=bo,he.identity=Cf,he.includes=function(n,t,r,e){n=ba(n)?n:vf(n),r=r&&!e?Pa(r):0;var u=n.length;return r<0&&(r=Vr(u+r,0)),La(n)?r<=u&&n.indexOf(t,r)>-1:!!u&&fr(n,t,r)>-1},he.indexOf=function(n,t,r){var e=null==n?0:n.length;if(!e)return-1;var u=null==r?0:Pa(r);return u<0&&(u=Vr(e+u,0)),fr(n,t,u)},he.inRange=function(n,t,r){return t=Fa(t),r===i?(r=t,t=0):r=Fa(r),function(n,t,r){return n>=Jr(t,r)&&n=-L&&n<=L},he.isSet=Wa,he.isString=La,he.isSymbol=Ta,he.isTypedArray=Na,he.isUndefined=function(n){return n===i},he.isWeakMap=function(n){return Ea(n)&&Pi(n)==an},he.isWeakSet=function(n){return Ea(n)&&Qe(n)==fn},he.join=function(n,t){return null==n?"":Dr.call(n,t)},he.kebabCase=df,he.last=So,he.lastIndexOf=function(n,t,r){var e=null==n?0:n.length;if(!e)return-1;var u=e;return r!==i&&(u=(u=Pa(r))<0?Vr(e+u,0):Jr(u,e-1)),t==t?function(n,t,r){for(var e=r+1;e--;)if(n[e]===t)return e;return e}(n,t,u):ar(n,lr,u,!0)},he.lowerCase=bf,he.lowerFirst=wf,he.lt=Ba,he.lte=Ua,he.max=function(n){return n&&n.length?$e(n,Cf,Xe):i},he.maxBy=function(n,t){return n&&n.length?$e(n,Ti(t,2),Xe):i},he.mean=function(n){return sr(n,Cf)},he.meanBy=function(n,t){return sr(n,Ti(t,2))},he.min=function(n){return n&&n.length?$e(n,Cf,su):i},he.minBy=function(n,t){return n&&n.length?$e(n,Ti(t,2),su):i},he.stubArray=Df,he.stubFalse=qf,he.stubObject=function(){return{}},he.stubString=function(){return""},he.stubTrue=function(){return!0},he.multiply=Gf,he.nth=function(n,t){return n&&n.length?gu(n,Pa(t)):i},he.noConflict=function(){return Lt._===this&&(Lt._=gt),this},he.noop=Nf,he.now=Xo,he.pad=function(n,t,r){n=Va(n);var e=(t=Pa(t))?Cr(n):0;if(!t||e>=t)return n;var u=(t-e)/2;return yi(Mr(u),r)+n+yi(Ur(u),r)},he.padEnd=function(n,t,r){n=Va(n);var e=(t=Pa(t))?Cr(n):0;return t&&et){var e=n;n=t,t=e}if(r||n%1||t%1){var u=Yr();return Jr(n+u*(t-n+Rt("1e-"+((u+"").length-1))),t)}return mu(n,t)},he.reduce=function(n,t,r){var e=ya(n)?rr:vr,u=arguments.length<3;return e(n,Ti(t,4),r,u,Me)},he.reduceRight=function(n,t,r){var e=ya(n)?er:vr,u=arguments.length<3;return e(n,Ti(t,4),r,u,Fe)},he.repeat=function(n,t,r){return t=(r?Ji(n,t,r):t===i)?1:Pa(t),xu(Va(n),t)},he.replace=function(){var n=arguments,t=Va(n[0]);return n.length<3?t:t.replace(n[1],n[2])},he.result=function(n,t,r){var e=-1,u=(t=Ju(t,n)).length;for(u||(u=1,n=i);++eL)return[];var r=B,e=Jr(n,B);t=Ti(t),n-=B;for(var u=gr(e,t);++r=o)return n;var f=r-Cr(e);if(f<1)return e;var c=a?Ku(a,0,f).join(""):n.slice(0,f);if(u===i)return c+e;if(a&&(f+=c.length-f),za(u)){if(n.slice(f).search(u)){var l,s=c;for(u.global||(u=et(u.source,Va(qn.exec(u))+"g")),u.lastIndex=0;l=u.exec(s);)var p=l.index;c=c.slice(0,p===i?f:p)}}else if(n.indexOf(Nu(u),f)!=f){var h=c.lastIndexOf(u);h>-1&&(c=c.slice(0,h))}return c+e},he.unescape=function(n){return(n=Va(n))&&An.test(n)?n.replace(Sn,Wr):n},he.uniqueId=function(n){var t=++pt;return Va(n)+t},he.upperCase=Sf,he.upperFirst=jf,he.each=Vo,he.eachRight=Jo,he.first=bo,Tf(he,(Yf={},Ze(he,function(n,t){st.call(he.prototype,t)||(Yf[t]=n)}),Yf),{chain:!1}),he.VERSION="4.17.14",Kt(["bind","bindKey","curry","curryRight","partial","partialRight"],function(n){he[n].placeholder=he}),Kt(["drop","take"],function(n,t){ye.prototype[n]=function(r){r=r===i?1:Vr(Pa(r),0);var e=this.__filtered__&&!t?new ye(this):this.clone();return e.__filtered__?e.__takeCount__=Jr(r,e.__takeCount__):e.__views__.push({size:Jr(r,B),type:n+(e.__dir__<0?"Right":"")}),e},ye.prototype[n+"Right"]=function(t){return this.reverse()[n](t).reverse()}}),Kt(["filter","map","takeWhile"],function(n,t){var r=t+1,e=r==C||3==r;ye.prototype[n]=function(n){var t=this.clone();return t.__iteratees__.push({iteratee:Ti(n,3),type:r}),t.__filtered__=t.__filtered__||e,t}}),Kt(["head","last"],function(n,t){var r="take"+(t?"Right":"");ye.prototype[n]=function(){return this[r](1).value()[0]}}),Kt(["initial","tail"],function(n,t){var r="drop"+(t?"":"Right");ye.prototype[n]=function(){return this.__filtered__?new ye(this):this[r](1)}}),ye.prototype.compact=function(){return this.filter(Cf)},ye.prototype.find=function(n){return this.filter(n).head()},ye.prototype.findLast=function(n){return this.reverse().find(n)},ye.prototype.invokeMap=Su(function(n,t){return"function"==typeof n?new ye(this):this.map(function(r){return eu(r,n,t)})}),ye.prototype.reject=function(n){return this.filter(fa(Ti(n)))},ye.prototype.slice=function(n,t){n=Pa(n);var r=this;return r.__filtered__&&(n>0||t<0)?new ye(r):(n<0?r=r.takeRight(-n):n&&(r=r.drop(n)),t!==i&&(r=(t=Pa(t))<0?r.dropRight(-t):r.take(t-n)),r)},ye.prototype.takeRightWhile=function(n){return this.reverse().takeWhile(n).reverse()},ye.prototype.toArray=function(){return this.take(B)},Ze(ye.prototype,function(n,t){var r=/^(?:filter|find|map|reject)|While$/.test(t),e=/^(?:head|last)$/.test(t),u=he[e?"take"+("last"==t?"Right":""):t],o=e||/^find/.test(t);u&&(he.prototype[t]=function(){var t=this.__wrapped__,a=e?[1]:arguments,f=t instanceof ye,c=a[0],l=f||ya(t),s=function(n){var t=u.apply(he,tr([n],a));return e&&p?t[0]:t};l&&r&&"function"==typeof c&&1!=c.length&&(f=l=!1);var p=this.__chain__,h=!!this.__actions__.length,v=o&&!p,_=f&&!h;if(!o&&l){t=_?t:new ye(this);var g=n.apply(t,a);return g.__actions__.push({func:Fo,args:[s],thisArg:i}),new ge(g,p)}return v&&_?n.apply(this,a):(g=this.thru(s),v?e?g.value()[0]:g.value():g)})}),Kt(["pop","push","shift","sort","splice","unshift"],function(n){var t=ot[n],r=/^(?:push|sort|unshift)$/.test(n)?"tap":"thru",e=/^(?:pop|shift)$/.test(n);he.prototype[n]=function(){var n=arguments;if(e&&!this.__chain__){var u=this.value();return t.apply(ya(u)?u:[],n)}return this[r](function(r){return t.apply(ya(r)?r:[],n)})}}),Ze(ye.prototype,function(n,t){var r=he[t];if(r){var e=r.name+"";st.call(ue,e)||(ue[e]=[]),ue[e].push({name:t,func:r})}}),ue[hi(i,d).name]=[{name:"wrapper",func:i}],ye.prototype.clone=function(){var n=new ye(this.__wrapped__);return n.__actions__=ri(this.__actions__),n.__dir__=this.__dir__,n.__filtered__=this.__filtered__,n.__iteratees__=ri(this.__iteratees__),n.__takeCount__=this.__takeCount__,n.__views__=ri(this.__views__),n},ye.prototype.reverse=function(){if(this.__filtered__){var n=new ye(this);n.__dir__=-1,n.__filtered__=!0}else(n=this.clone()).__dir__*=-1;return n},ye.prototype.value=function(){var n=this.__wrapped__.value(),t=this.__dir__,r=ya(n),e=t<0,u=r?n.length:0,i=function(n,t,r){for(var e=-1,u=r.length;++e=this.__values__.length;return{done:n,value:n?i:this.__values__[this.__index__++]}},he.prototype.plant=function(n){for(var t,r=this;r instanceof _e;){var e=so(r);e.__index__=0,e.__values__=i,t?u.__wrapped__=e:t=e;var u=e;r=r.__wrapped__}return u.__wrapped__=n,t},he.prototype.reverse=function(){var n=this.__wrapped__;if(n instanceof ye){var t=n;return this.__actions__.length&&(t=new ye(this)),(t=t.reverse()).__actions__.push({func:Fo,args:[ko],thisArg:i}),new ge(t,this.__chain__)}return this.thru(ko)},he.prototype.toJSON=he.prototype.valueOf=he.prototype.value=function(){return Pu(this.__wrapped__,this.__actions__)},he.prototype.first=he.prototype.head,Mt&&(he.prototype[Mt]=function(){return this}),he}();Lt._=Lr,(u=function(){return Lr}.call(t,r,t,e))===i||(e.exports=u)}).call(this)}).call(this,r(3),r(4)(n))},function(n,t){n.exports=require("sketch")},function(n,t,r){!function(){"use strict";var t=r(5).typeOf,e=r(6);n.exports.stringify=function(n){var r,u="";return e((r={undefined:function(){return"null"},null:function(){return"null"},number:function(n){return n},boolean:function(n){return n?"true":"false"},string:function(n){return JSON.stringify(n)},array:function(n){var e="";return 0===n.length?e+="[]":(u=u.replace(/$/," "),n.forEach(function(n,i){var o=r[t(n)];if(!o)throw new Error("what the crap: "+t(n));e+="\n"+u+"- "+o(n,!0)}),u=u.replace(/ /,""),e)},object:function(n,e,i){var o="";return 0===Object.keys(n).length?o+="{}":(i||(u=u.replace(/$/," ")),Object.keys(n).forEach(function(i,a){var f=n[i],c=r[t(f)];if(void 0!==f){if(!c)throw new Error("what the crap: "+t(f));e&&0===a||(o+="\n"+u),o+=i+": "+c(f)}}),u=u.replace(/ /,""),o)},function:function(){return"[object Function]"}})[t(n)](n,!0,!0)+"\n")}}()},function(n,t){var r;r=function(){return this}();try{r=r||new Function("return this")()}catch(e){"object"==typeof window&&(r=window)}n.exports=r},function(n,t){n.exports=function(n){return n.webpackPolyfill||(n.deprecate=function(){},n.paths=[],n.children||(n.children=[]),Object.defineProperty(n,"loaded",{enumerable:!0,get:function(){return n.l}}),Object.defineProperty(n,"id",{enumerable:!0,get:function(){return n.i}}),n.webpackPolyfill=1),n}},function(n,t){!function(){"use strict";var t,r,e=Function("return this")(),u="Boolean Number String Function Array Date RegExp Object".split(" "),i={};for(t in u)u.hasOwnProperty(t)&&(r=u[t],i["[object "+r+"]"]=r.toLowerCase());function o(n){return null==n?String(n):i[Object.prototype.toString.call(n)]||"object"}function a(n){var t,r;if("object"===o(n))for(t in n)if(void 0!==(r=n[t])&&"function"!==o(r))return!1;return!0}String.prototype.entityify||(String.prototype.entityify=function(){return this.replace(/&/g,"&").replace(//g,">")}),String.prototype.quote||(String.prototype.quote=function(){var n,t,r=this.length,e='"';for(t=0;t=" ")"\\"!==n&&'"'!==n||(e+="\\"),e+=n;else switch(n){case"\b":e+="\\b";break;case"\f":e+="\\f";break;case"\n":e+="\\n";break;case"\r":e+="\\r";break;case"\t":e+="\\t";break;default:n=n.charCodeAt(),e+="\\u00"+Math.floor(n/16).toString(16)+(n%16).toString(16)}return e+'"'}),String.prototype.supplant||(String.prototype.supplant=function(n){return this.replace(/{([^{}]*)}/g,function(t,r){var e=n[r];return"string"==typeof e||"number"==typeof e?e:t})}),String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^\s*(\S*(?:\s+\S+)*)\s*$/,"$1")}),n.exports={typeOf:o,isEmpty:a},e.typeOf=e.typeOf||o,e.isEmpty=e.isEmpty||a}()},function(n,t,r){"use strict";n.exports=function(n){return n.split("\n").map(function(n){return n.trimRight()}).join("\n")}},function(n,r,e){"use strict";e.r(r);var u,i,o,a,f=e(1),c=e.n(f),l=e(0),s=e.n(l),p={"JavaScript Object":{lineStart:"",prefix:" '",diviner:"': '",postfix:"',\n",lineEnd:"}",filetype:"js"},"JavaScript Variables":{lineStart:"",prefix:"const ",diviner:" = '",postfix:"';\n",lineEnd:"",filetype:"js"},SCSS:{lineStart:"",prefix:"$",diviner:": ",postfix:";\n",lineEnd:"",filetype:"scss"},Less:{lineStart:"",prefix:"@",diviner:": ",postfix:";\n",lineEnd:"",filetype:"less"},CSS:{lineStart:":root {\n",prefix:" --",diviner:": ",postfix:";\n",lineEnd:"}",filetype:"css"},JSON:{lineStart:{},prefix:"",diviner:"",postfix:"",lineEnd:"",filetype:"json"},YAML:{lineStart:{},prefix:"",diviner:"",postfix:"",lineEnd:"",filetype:"yml"}},h=e(2),v=e.n(h),_=function(n,t,r){var e="";if("JSON"==t){var u={};u[s.a.camelCase(r)]=n,e=JSON.stringify(u,null,"\t")}else if("YAML"==t){var i={};i[s.a.camelCase(r)]=n,e=v.a.stringify(i)}else e=(e=(e="JavaScript Object"==t?"const "+s.a.camelCase(r)+" = {\n":p[t].lineStart).concat(s.a.join(s.a.map(n,function(n,r){return p[t].prefix+r+p[t].diviner+n+p[t].postfix}),""))).concat(p[t].lineEnd);return e},g=function(n,t){var r=n.name.split("/"),e="";if(0==t)e=s.a.kebabCase(r);else if(1==t)e=s.a.camelCase(s.a.join(r,"-"));else{var u=t-2;e=r.length4&&void 0!==arguments[4]&&arguments[4],i=NSPopUpButton.alloc().initWithFrame(NSMakeRect(0,e-n,r,22));if(u){var o=t.map(function(n){return n.name}),a=o[0].split("/"),f=s.a.kebabCase(a),c=s.a.camelCase(s.a.join(a,"-"));i.addItemWithTitle(f),i.addItemWithTitle(c),a.length>1&&s.a.forEach(a,function(n){i.addItemWithTitle(n.toLowerCase().replace(/ /g,""))})}else s.a.forEach(t,function(n){i.addItemWithTitle(n)});return i.selectItemAtIndex(0),i},b=function(n){var r=function(n){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"Choose variables format.",e=COSAlertWindow.new();return e.setIcon(NSImage.alloc().initByReferencingFile(t.plugin.urlForResourceNamed("icon.png").path())),e.setMessageText(n),e.setInformativeText(r),e.addButtonWithTitle("Ok"),e.addButtonWithTitle("Cancel"),e}("Export Spacing Variables"),e=NSView.alloc().initWithFrame(NSMakeRect(0,0,300,225));r.addAccessoryView(e),e.addSubview(y(35,"File format:",300,225));u=d(45,["SCSS","Less","CSS","JSON","JavaScript Object","JavaScript Variables"],300,225),e.addSubview(u),e.addSubview(y(90,"Dimension:",300,225));i=d(100,["Width","Height"],300,225),e.addSubview(i),e.addSubview(y(145,"Units:",300,225));return a=d(155,["Absolute (px)","Relative (rem)"],300,225),e.addSubview(a),e.addSubview(y(200,"Naming:",300,225)),o=d(210,n,300,225,!0),e.addSubview(o),r.runModal()};r.default=function(){var n=c.a.getSelectedDocument().selectedLayers.layers,t=s.a.filter(s.a.reverse(n),["type","ShapePath"]);if(0!==s.a.size(t)){var r=b(t),e=u.titleOfSelectedItem(),f=i.titleOfSelectedItem(),l=o.indexOfSelectedItem(),h=a.titleOfSelectedItem();"1000"==r&&function(n,t,r,e,u){var i=n.length,o=NSArray.arrayWithArray([p[t].filetype,nil]),a=NSSavePanel.savePanel();if(a.setAllowedFileTypes(o),a.setNameFieldStringValue("spacing."+p[t].filetype),a.setPrompt("Save Spacing Variables"),a.runModal()&&0!==i){var f={};s.a.forEach(n,function(n){var t=g(n,e),i="Width"==r?n.frame.width:n.frame.height,o="Absolute (px)"==u?i+"px":i/16+"rem";f[t]=o});var l=NSString.stringWithString(_(f,t,"spacing")),h=a.URL().path();l.writeToFile_atomically_encoding_error(h,!0,NSUTF8StringEncoding,null),c.a.UI.message("Spacing Variables Exported!")}}(t,e,f,l,h)}else c.a.UI.alert("Select layers","Please select shape layers first.")}}]);if("default"===n&&"function"==typeof r)r(t);else{if("function"!=typeof r[n])throw new Error('Missing export named "'+n+'". Your command should contain something like `export function " + key +"() {}`.');r[n](t)}}globalThis.onRun=__skpm_run.bind(this,"default");
--------------------------------------------------------------------------------
/design-token-exporter.sketchplugin/Contents/Sketch/textObjects.js:
--------------------------------------------------------------------------------
1 | var globalThis=this;function __skpm_run(n,t){globalThis.context=t;var r=function(n){var t={};function r(e){if(t[e])return t[e].exports;var u=t[e]={i:e,l:!1,exports:{}};return n[e].call(u.exports,u,u.exports,r),u.l=!0,u.exports}return r.m=n,r.c=t,r.d=function(n,t,e){r.o(n,t)||Object.defineProperty(n,t,{enumerable:!0,get:e})},r.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},r.t=function(n,t){if(1&t&&(n=r(n)),8&t)return n;if(4&t&&"object"==typeof n&&n&&n.__esModule)return n;var e=Object.create(null);if(r.r(e),Object.defineProperty(e,"default",{enumerable:!0,value:n}),2&t&&"string"!=typeof n)for(var u in n)r.d(e,u,function(t){return n[t]}.bind(null,u));return e},r.n=function(n){var t=n&&n.__esModule?function(){return n.default}:function(){return n};return r.d(t,"a",t),t},r.o=function(n,t){return Object.prototype.hasOwnProperty.call(n,t)},r.p="",r(r.s=4)}([function(n,t,r){(function(n,e){var u;(function(){var i,o=200,a="Unsupported core-js use. Try https://npms.io/search?q=ponyfill.",f="Expected a function",c="__lodash_hash_undefined__",l=500,s="__lodash_placeholder__",h=1,p=2,v=4,_=1,g=2,d=1,y=2,b=4,w=8,m=16,x=32,S=64,j=128,A=256,O=512,k=30,E="...",I=800,z=16,R=1,T=2,W=1/0,C=9007199254740991,L=17976931348623157e292,N=NaN,B=4294967295,F=B-1,U=B>>>1,M=[["ary",j],["bind",d],["bindKey",y],["curry",w],["curryRight",m],["flip",O],["partial",x],["partialRight",S],["rearg",A]],V="[object Arguments]",P="[object Array]",$="[object AsyncFunction]",D="[object Boolean]",q="[object Date]",J="[object DOMException]",Z="[object Error]",H="[object Function]",K="[object GeneratorFunction]",G="[object Map]",Y="[object Number]",Q="[object Null]",X="[object Object]",nn="[object Proxy]",tn="[object RegExp]",rn="[object Set]",en="[object String]",un="[object Symbol]",on="[object Undefined]",an="[object WeakMap]",fn="[object WeakSet]",cn="[object ArrayBuffer]",ln="[object DataView]",sn="[object Float32Array]",hn="[object Float64Array]",pn="[object Int8Array]",vn="[object Int16Array]",_n="[object Int32Array]",gn="[object Uint8Array]",dn="[object Uint8ClampedArray]",yn="[object Uint16Array]",bn="[object Uint32Array]",wn=/\b__p \+= '';/g,mn=/\b(__p \+=) '' \+/g,xn=/(__e\(.*?\)|\b__t\)) \+\n'';/g,Sn=/&(?:amp|lt|gt|quot|#39);/g,jn=/[&<>"']/g,An=RegExp(Sn.source),On=RegExp(jn.source),kn=/<%-([\s\S]+?)%>/g,En=/<%([\s\S]+?)%>/g,In=/<%=([\s\S]+?)%>/g,zn=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,Rn=/^\w*$/,Tn=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,Wn=/[\\^$.*+?()[\]{}|]/g,Cn=RegExp(Wn.source),Ln=/^\s+|\s+$/g,Nn=/^\s+/,Bn=/\s+$/,Fn=/\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,Un=/\{\n\/\* \[wrapped with (.+)\] \*/,Mn=/,? & /,Vn=/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g,Pn=/\\(\\)?/g,$n=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,Dn=/\w*$/,qn=/^[-+]0x[0-9a-f]+$/i,Jn=/^0b[01]+$/i,Zn=/^\[object .+?Constructor\]$/,Hn=/^0o[0-7]+$/i,Kn=/^(?:0|[1-9]\d*)$/,Gn=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g,Yn=/($^)/,Qn=/['\n\r\u2028\u2029\\]/g,Xn="\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff",nt="\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000",tt="[\\ud800-\\udfff]",rt="["+nt+"]",et="["+Xn+"]",ut="\\d+",it="[\\u2700-\\u27bf]",ot="[a-z\\xdf-\\xf6\\xf8-\\xff]",at="[^\\ud800-\\udfff"+nt+ut+"\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde]",ft="\\ud83c[\\udffb-\\udfff]",ct="[^\\ud800-\\udfff]",lt="(?:\\ud83c[\\udde6-\\uddff]){2}",st="[\\ud800-\\udbff][\\udc00-\\udfff]",ht="[A-Z\\xc0-\\xd6\\xd8-\\xde]",pt="(?:"+ot+"|"+at+")",vt="(?:"+ht+"|"+at+")",_t="(?:"+et+"|"+ft+")"+"?",gt="[\\ufe0e\\ufe0f]?"+_t+("(?:\\u200d(?:"+[ct,lt,st].join("|")+")[\\ufe0e\\ufe0f]?"+_t+")*"),dt="(?:"+[it,lt,st].join("|")+")"+gt,yt="(?:"+[ct+et+"?",et,lt,st,tt].join("|")+")",bt=RegExp("['’]","g"),wt=RegExp(et,"g"),mt=RegExp(ft+"(?="+ft+")|"+yt+gt,"g"),xt=RegExp([ht+"?"+ot+"+(?:['’](?:d|ll|m|re|s|t|ve))?(?="+[rt,ht,"$"].join("|")+")",vt+"+(?:['’](?:D|LL|M|RE|S|T|VE))?(?="+[rt,ht+pt,"$"].join("|")+")",ht+"?"+pt+"+(?:['’](?:d|ll|m|re|s|t|ve))?",ht+"+(?:['’](?:D|LL|M|RE|S|T|VE))?","\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])","\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])",ut,dt].join("|"),"g"),St=RegExp("[\\u200d\\ud800-\\udfff"+Xn+"\\ufe0e\\ufe0f]"),jt=/[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/,At=["Array","Buffer","DataView","Date","Error","Float32Array","Float64Array","Function","Int8Array","Int16Array","Int32Array","Map","Math","Object","Promise","RegExp","Set","String","Symbol","TypeError","Uint8Array","Uint8ClampedArray","Uint16Array","Uint32Array","WeakMap","_","clearTimeout","isFinite","parseInt","setTimeout"],Ot=-1,kt={};kt[sn]=kt[hn]=kt[pn]=kt[vn]=kt[_n]=kt[gn]=kt[dn]=kt[yn]=kt[bn]=!0,kt[V]=kt[P]=kt[cn]=kt[D]=kt[ln]=kt[q]=kt[Z]=kt[H]=kt[G]=kt[Y]=kt[X]=kt[tn]=kt[rn]=kt[en]=kt[an]=!1;var Et={};Et[V]=Et[P]=Et[cn]=Et[ln]=Et[D]=Et[q]=Et[sn]=Et[hn]=Et[pn]=Et[vn]=Et[_n]=Et[G]=Et[Y]=Et[X]=Et[tn]=Et[rn]=Et[en]=Et[un]=Et[gn]=Et[dn]=Et[yn]=Et[bn]=!0,Et[Z]=Et[H]=Et[an]=!1;var It={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},zt=parseFloat,Rt=parseInt,Tt="object"==typeof n&&n&&n.Object===Object&&n,Wt="object"==typeof self&&self&&self.Object===Object&&self,Ct=Tt||Wt||Function("return this")(),Lt=t&&!t.nodeType&&t,Nt=Lt&&"object"==typeof e&&e&&!e.nodeType&&e,Bt=Nt&&Nt.exports===Lt,Ft=Bt&&Tt.process,Ut=function(){try{var n=Nt&&Nt.require&&Nt.require("util").types;return n||Ft&&Ft.binding&&Ft.binding("util")}catch(t){}}(),Mt=Ut&&Ut.isArrayBuffer,Vt=Ut&&Ut.isDate,Pt=Ut&&Ut.isMap,$t=Ut&&Ut.isRegExp,Dt=Ut&&Ut.isSet,qt=Ut&&Ut.isTypedArray;function Jt(n,t,r){switch(r.length){case 0:return n.call(t);case 1:return n.call(t,r[0]);case 2:return n.call(t,r[0],r[1]);case 3:return n.call(t,r[0],r[1],r[2])}return n.apply(t,r)}function Zt(n,t,r,e){for(var u=-1,i=null==n?0:n.length;++u-1}function Xt(n,t,r){for(var e=-1,u=null==n?0:n.length;++e-1;);return r}function mr(n,t){for(var r=n.length;r--&&fr(t,n[r],0)>-1;);return r}var xr=pr({"À":"A","Á":"A","Â":"A","Ã":"A","Ä":"A","Å":"A","à":"a","á":"a","â":"a","ã":"a","ä":"a","å":"a","Ç":"C","ç":"c","Ð":"D","ð":"d","È":"E","É":"E","Ê":"E","Ë":"E","è":"e","é":"e","ê":"e","ë":"e","Ì":"I","Í":"I","Î":"I","Ï":"I","ì":"i","í":"i","î":"i","ï":"i","Ñ":"N","ñ":"n","Ò":"O","Ó":"O","Ô":"O","Õ":"O","Ö":"O","Ø":"O","ò":"o","ó":"o","ô":"o","õ":"o","ö":"o","ø":"o","Ù":"U","Ú":"U","Û":"U","Ü":"U","ù":"u","ú":"u","û":"u","ü":"u","Ý":"Y","ý":"y","ÿ":"y","Æ":"Ae","æ":"ae","Þ":"Th","þ":"th","ß":"ss","Ā":"A","Ă":"A","Ą":"A","ā":"a","ă":"a","ą":"a","Ć":"C","Ĉ":"C","Ċ":"C","Č":"C","ć":"c","ĉ":"c","ċ":"c","č":"c","Ď":"D","Đ":"D","ď":"d","đ":"d","Ē":"E","Ĕ":"E","Ė":"E","Ę":"E","Ě":"E","ē":"e","ĕ":"e","ė":"e","ę":"e","ě":"e","Ĝ":"G","Ğ":"G","Ġ":"G","Ģ":"G","ĝ":"g","ğ":"g","ġ":"g","ģ":"g","Ĥ":"H","Ħ":"H","ĥ":"h","ħ":"h","Ĩ":"I","Ī":"I","Ĭ":"I","Į":"I","İ":"I","ĩ":"i","ī":"i","ĭ":"i","į":"i","ı":"i","Ĵ":"J","ĵ":"j","Ķ":"K","ķ":"k","ĸ":"k","Ĺ":"L","Ļ":"L","Ľ":"L","Ŀ":"L","Ł":"L","ĺ":"l","ļ":"l","ľ":"l","ŀ":"l","ł":"l","Ń":"N","Ņ":"N","Ň":"N","Ŋ":"N","ń":"n","ņ":"n","ň":"n","ŋ":"n","Ō":"O","Ŏ":"O","Ő":"O","ō":"o","ŏ":"o","ő":"o","Ŕ":"R","Ŗ":"R","Ř":"R","ŕ":"r","ŗ":"r","ř":"r","Ś":"S","Ŝ":"S","Ş":"S","Š":"S","ś":"s","ŝ":"s","ş":"s","š":"s","Ţ":"T","Ť":"T","Ŧ":"T","ţ":"t","ť":"t","ŧ":"t","Ũ":"U","Ū":"U","Ŭ":"U","Ů":"U","Ű":"U","Ų":"U","ũ":"u","ū":"u","ŭ":"u","ů":"u","ű":"u","ų":"u","Ŵ":"W","ŵ":"w","Ŷ":"Y","ŷ":"y","Ÿ":"Y","Ź":"Z","Ż":"Z","Ž":"Z","ź":"z","ż":"z","ž":"z","IJ":"IJ","ij":"ij","Œ":"Oe","œ":"oe","ʼn":"'n","ſ":"s"}),Sr=pr({"&":"&","<":"<",">":">",'"':""","'":"'"});function jr(n){return"\\"+It[n]}function Ar(n){return St.test(n)}function Or(n){var t=-1,r=Array(n.size);return n.forEach(function(n,e){r[++t]=[e,n]}),r}function kr(n,t){return function(r){return n(t(r))}}function Er(n,t){for(var r=-1,e=n.length,u=0,i=[];++r",""":'"',"'":"'"});var Cr=function n(t){var r,e=(t=null==t?Ct:Cr.defaults(Ct.Object(),t,Cr.pick(Ct,At))).Array,u=t.Date,Xn=t.Error,nt=t.Function,tt=t.Math,rt=t.Object,et=t.RegExp,ut=t.String,it=t.TypeError,ot=e.prototype,at=nt.prototype,ft=rt.prototype,ct=t["__core-js_shared__"],lt=at.toString,st=ft.hasOwnProperty,ht=0,pt=(r=/[^.]+$/.exec(ct&&ct.keys&&ct.keys.IE_PROTO||""))?"Symbol(src)_1."+r:"",vt=ft.toString,_t=lt.call(rt),gt=Ct._,dt=et("^"+lt.call(st).replace(Wn,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),yt=Bt?t.Buffer:i,mt=t.Symbol,St=t.Uint8Array,It=yt?yt.allocUnsafe:i,Tt=kr(rt.getPrototypeOf,rt),Wt=rt.create,Lt=ft.propertyIsEnumerable,Nt=ot.splice,Ft=mt?mt.isConcatSpreadable:i,Ut=mt?mt.iterator:i,ir=mt?mt.toStringTag:i,pr=function(){try{var n=Fi(rt,"defineProperty");return n({},"",{}),n}catch(t){}}(),Lr=t.clearTimeout!==Ct.clearTimeout&&t.clearTimeout,Nr=u&&u.now!==Ct.Date.now&&u.now,Br=t.setTimeout!==Ct.setTimeout&&t.setTimeout,Fr=tt.ceil,Ur=tt.floor,Mr=rt.getOwnPropertySymbols,Vr=yt?yt.isBuffer:i,Pr=t.isFinite,$r=ot.join,Dr=kr(rt.keys,rt),qr=tt.max,Jr=tt.min,Zr=u.now,Hr=t.parseInt,Kr=tt.random,Gr=ot.reverse,Yr=Fi(t,"DataView"),Qr=Fi(t,"Map"),Xr=Fi(t,"Promise"),ne=Fi(t,"Set"),te=Fi(t,"WeakMap"),re=Fi(rt,"create"),ee=te&&new te,ue={},ie=lo(Yr),oe=lo(Qr),ae=lo(Xr),fe=lo(ne),ce=lo(te),le=mt?mt.prototype:i,se=le?le.valueOf:i,he=le?le.toString:i;function pe(n){if(Ea(n)&&!da(n)&&!(n instanceof de)){if(n instanceof ge)return n;if(st.call(n,"__wrapped__"))return so(n)}return new ge(n)}var ve=function(){function n(){}return function(t){if(!ka(t))return{};if(Wt)return Wt(t);n.prototype=t;var r=new n;return n.prototype=i,r}}();function _e(){}function ge(n,t){this.__wrapped__=n,this.__actions__=[],this.__chain__=!!t,this.__index__=0,this.__values__=i}function de(n){this.__wrapped__=n,this.__actions__=[],this.__dir__=1,this.__filtered__=!1,this.__iteratees__=[],this.__takeCount__=B,this.__views__=[]}function ye(n){var t=-1,r=null==n?0:n.length;for(this.clear();++t=t?n:t)),n}function Le(n,t,r,e,u,o){var a,f=t&h,c=t&p,l=t&v;if(r&&(a=u?r(n,e,u,o):r(n)),a!==i)return a;if(!ka(n))return n;var s=da(n);if(s){if(a=function(n){var t=n.length,r=new n.constructor(t);return t&&"string"==typeof n[0]&&st.call(n,"index")&&(r.index=n.index,r.input=n.input),r}(n),!f)return ri(n,a)}else{var _=Vi(n),g=_==H||_==K;if(ma(n))return Gu(n,f);if(_==X||_==V||g&&!u){if(a=c||g?{}:$i(n),!f)return c?function(n,t){return ei(n,Mi(n),t)}(n,function(n,t){return n&&ei(t,of(t),n)}(a,n)):function(n,t){return ei(n,Ui(n),t)}(n,Re(a,n))}else{if(!Et[_])return u?n:{};a=function(n,t,r){var e,u=n.constructor;switch(t){case cn:return Yu(n);case D:case q:return new u(+n);case ln:return function(n,t){var r=t?Yu(n.buffer):n.buffer;return new n.constructor(r,n.byteOffset,n.byteLength)}(n,r);case sn:case hn:case pn:case vn:case _n:case gn:case dn:case yn:case bn:return Qu(n,r);case G:return new u;case Y:case en:return new u(n);case tn:return function(n){var t=new n.constructor(n.source,Dn.exec(n));return t.lastIndex=n.lastIndex,t}(n);case rn:return new u;case un:return e=n,se?rt(se.call(e)):{}}}(n,_,f)}}o||(o=new xe);var d=o.get(n);if(d)return d;o.set(n,a),Wa(n)?n.forEach(function(e){a.add(Le(e,t,r,e,n,o))}):Ia(n)&&n.forEach(function(e,u){a.set(u,Le(e,t,r,u,n,o))});var y=s?i:(l?c?Ri:zi:c?of:uf)(n);return Ht(y||n,function(e,u){y&&(e=n[u=e]),Ee(a,u,Le(e,t,r,u,n,o))}),a}function Ne(n,t,r){var e=r.length;if(null==n)return!e;for(n=rt(n);e--;){var u=r[e],o=t[u],a=n[u];if(a===i&&!(u in n)||!o(a))return!1}return!0}function Be(n,t,r){if("function"!=typeof n)throw new it(f);return eo(function(){n.apply(i,r)},t)}function Fe(n,t,r,e){var u=-1,i=Qt,a=!0,f=n.length,c=[],l=t.length;if(!f)return c;r&&(t=nr(t,dr(r))),e?(i=Xt,a=!1):t.length>=o&&(i=br,a=!1,t=new me(t));n:for(;++u-1},be.prototype.set=function(n,t){var r=this.__data__,e=Ie(r,n);return e<0?(++this.size,r.push([n,t])):r[e][1]=t,this},we.prototype.clear=function(){this.size=0,this.__data__={hash:new ye,map:new(Qr||be),string:new ye}},we.prototype.delete=function(n){var t=Ni(this,n).delete(n);return this.size-=t?1:0,t},we.prototype.get=function(n){return Ni(this,n).get(n)},we.prototype.has=function(n){return Ni(this,n).has(n)},we.prototype.set=function(n,t){var r=Ni(this,n),e=r.size;return r.set(n,t),this.size+=r.size==e?0:1,this},me.prototype.add=me.prototype.push=function(n){return this.__data__.set(n,c),this},me.prototype.has=function(n){return this.__data__.has(n)},xe.prototype.clear=function(){this.__data__=new be,this.size=0},xe.prototype.delete=function(n){var t=this.__data__,r=t.delete(n);return this.size=t.size,r},xe.prototype.get=function(n){return this.__data__.get(n)},xe.prototype.has=function(n){return this.__data__.has(n)},xe.prototype.set=function(n,t){var r=this.__data__;if(r instanceof be){var e=r.__data__;if(!Qr||e.length0&&r(a)?t>1?De(a,t-1,r,e,u):tr(u,a):e||(u[u.length]=a)}return u}var qe=ai(),Je=ai(!0);function Ze(n,t){return n&&qe(n,t,uf)}function He(n,t){return n&&Je(n,t,uf)}function Ke(n,t){return Yt(t,function(t){return ja(n[t])})}function Ge(n,t){for(var r=0,e=(t=Ju(t,n)).length;null!=n&&rt}function nu(n,t){return null!=n&&st.call(n,t)}function tu(n,t){return null!=n&&t in rt(n)}function ru(n,t,r){for(var u=r?Xt:Qt,o=n[0].length,a=n.length,f=a,c=e(a),l=1/0,s=[];f--;){var h=n[f];f&&t&&(h=nr(h,dr(t))),l=Jr(h.length,l),c[f]=!r&&(t||o>=120&&h.length>=120)?new me(f&&h):i}h=n[0];var p=-1,v=c[0];n:for(;++p=a)return f;var c=r[e];return f*("desc"==c?-1:1)}}return n.index-t.index}(n,t,r)})}function yu(n,t,r){for(var e=-1,u=t.length,i={};++e-1;)a!==n&&Nt.call(a,f,1),Nt.call(n,f,1);return n}function wu(n,t){for(var r=n?t.length:0,e=r-1;r--;){var u=t[r];if(r==e||u!==i){var i=u;qi(u)?Nt.call(n,u,1):Fu(n,u)}}return n}function mu(n,t){return n+Ur(Kr()*(t-n+1))}function xu(n,t){var r="";if(!n||t<1||t>C)return r;do{t%2&&(r+=n),(t=Ur(t/2))&&(n+=n)}while(t);return r}function Su(n,t){return uo(Xi(n,t,Rf),n+"")}function ju(n){return je(vf(n))}function Au(n,t){var r=vf(n);return ao(r,Ce(t,0,r.length))}function Ou(n,t,r,e){if(!ka(n))return n;for(var u=-1,o=(t=Ju(t,n)).length,a=o-1,f=n;null!=f&&++ui?0:i+t),(r=r>i?i:r)<0&&(r+=i),i=t>r?0:r-t>>>0,t>>>=0;for(var o=e(i);++u>>1,o=n[i];null!==o&&!La(o)&&(r?o<=t:o=o){var l=t?null:xi(n);if(l)return Ir(l);a=!1,u=br,c=new me}else c=t?[]:f;n:for(;++e=e?n:zu(n,t,r)}var Ku=Lr||function(n){return Ct.clearTimeout(n)};function Gu(n,t){if(t)return n.slice();var r=n.length,e=It?It(r):new n.constructor(r);return n.copy(e),e}function Yu(n){var t=new n.constructor(n.byteLength);return new St(t).set(new St(n)),t}function Qu(n,t){var r=t?Yu(n.buffer):n.buffer;return new n.constructor(r,n.byteOffset,n.length)}function Xu(n,t){if(n!==t){var r=n!==i,e=null===n,u=n==n,o=La(n),a=t!==i,f=null===t,c=t==t,l=La(t);if(!f&&!l&&!o&&n>t||o&&a&&c&&!f&&!l||e&&a&&c||!r&&c||!u)return 1;if(!e&&!o&&!l&&n1?r[u-1]:i,a=u>2?r[2]:i;for(o=n.length>3&&"function"==typeof o?(u--,o):i,a&&Ji(r[0],r[1],a)&&(o=u<3?i:o,u=1),t=rt(t);++e-1?u[o?t[a]:a]:i}}function hi(n){return Ii(function(t){var r=t.length,e=r,u=ge.prototype.thru;for(n&&t.reverse();e--;){var o=t[e];if("function"!=typeof o)throw new it(f);if(u&&!a&&"wrapper"==Wi(o))var a=new ge([],!0)}for(e=a?e:r;++e1&&w.reverse(),h&&lf))return!1;var l=o.get(n);if(l&&o.get(t))return l==t;var s=-1,h=!0,p=r&g?new me:i;for(o.set(n,t),o.set(t,n);++s-1&&n%1==0&&n1?"& ":"")+t[e],t=t.join(r>2?", ":" "),n.replace(Fn,"{\n/* [wrapped with "+t+"] */\n")}(e,function(n,t){return Ht(M,function(r){var e="_."+r[0];t&r[1]&&!Qt(n,e)&&n.push(e)}),n.sort()}(function(n){var t=n.match(Un);return t?t[1].split(Mn):[]}(e),r)))}function oo(n){var t=0,r=0;return function(){var e=Zr(),u=z-(e-r);if(r=e,u>0){if(++t>=I)return arguments[0]}else t=0;return n.apply(i,arguments)}}function ao(n,t){var r=-1,e=n.length,u=e-1;for(t=t===i?e:t;++r1?n[t-1]:i;return r="function"==typeof r?(n.pop(),r):i,To(n,r)});function Uo(n){var t=pe(n);return t.__chain__=!0,t}function Mo(n,t){return t(n)}var Vo=Ii(function(n){var t=n.length,r=t?n[0]:0,e=this.__wrapped__,u=function(t){return We(t,n)};return!(t>1||this.__actions__.length)&&e instanceof de&&qi(r)?((e=e.slice(r,+r+(t?1:0))).__actions__.push({func:Mo,args:[u],thisArg:i}),new ge(e,this.__chain__).thru(function(n){return t&&!n.length&&n.push(i),n})):this.thru(u)});var Po=ui(function(n,t,r){st.call(n,r)?++n[r]:Te(n,r,1)});var $o=si(_o),Do=si(go);function qo(n,t){return(da(n)?Ht:Ue)(n,Li(t,3))}function Jo(n,t){return(da(n)?Kt:Me)(n,Li(t,3))}var Zo=ui(function(n,t,r){st.call(n,r)?n[r].push(t):Te(n,r,[t])});var Ho=Su(function(n,t,r){var u=-1,i="function"==typeof t,o=ba(n)?e(n.length):[];return Ue(n,function(n){o[++u]=i?Jt(t,n,r):eu(n,t,r)}),o}),Ko=ui(function(n,t,r){Te(n,r,t)});function Go(n,t){return(da(n)?nr:hu)(n,Li(t,3))}var Yo=ui(function(n,t,r){n[r?0:1].push(t)},function(){return[[],[]]});var Qo=Su(function(n,t){if(null==n)return[];var r=t.length;return r>1&&Ji(n,t[0],t[1])?t=[]:r>2&&Ji(t[0],t[1],t[2])&&(t=[t[0]]),du(n,De(t,1),[])}),Xo=Nr||function(){return Ct.Date.now()};function na(n,t,r){return t=r?i:t,t=n&&null==t?n.length:t,ji(n,j,i,i,i,i,t)}function ta(n,t){var r;if("function"!=typeof t)throw new it(f);return n=Va(n),function(){return--n>0&&(r=t.apply(this,arguments)),n<=1&&(t=i),r}}var ra=Su(function(n,t,r){var e=d;if(r.length){var u=Er(r,Ci(ra));e|=x}return ji(n,e,t,r,u)}),ea=Su(function(n,t,r){var e=d|y;if(r.length){var u=Er(r,Ci(ea));e|=x}return ji(t,e,n,r,u)});function ua(n,t,r){var e,u,o,a,c,l,s=0,h=!1,p=!1,v=!0;if("function"!=typeof n)throw new it(f);function _(t){var r=e,o=u;return e=u=i,s=t,a=n.apply(o,r)}function g(n){var r=n-l;return l===i||r>=t||r<0||p&&n-s>=o}function d(){var n=Xo();if(g(n))return y(n);c=eo(d,function(n){var r=t-(n-l);return p?Jr(r,o-(n-s)):r}(n))}function y(n){return c=i,v&&e?_(n):(e=u=i,a)}function b(){var n=Xo(),r=g(n);if(e=arguments,u=this,l=n,r){if(c===i)return function(n){return s=n,c=eo(d,t),h?_(n):a}(l);if(p)return Ku(c),c=eo(d,t),_(l)}return c===i&&(c=eo(d,t)),a}return t=$a(t)||0,ka(r)&&(h=!!r.leading,o=(p="maxWait"in r)?qr($a(r.maxWait)||0,t):o,v="trailing"in r?!!r.trailing:v),b.cancel=function(){c!==i&&Ku(c),s=0,e=l=u=c=i},b.flush=function(){return c===i?a:y(Xo())},b}var ia=Su(function(n,t){return Be(n,1,t)}),oa=Su(function(n,t,r){return Be(n,$a(t)||0,r)});function aa(n,t){if("function"!=typeof n||null!=t&&"function"!=typeof t)throw new it(f);var r=function(){var e=arguments,u=t?t.apply(this,e):e[0],i=r.cache;if(i.has(u))return i.get(u);var o=n.apply(this,e);return r.cache=i.set(u,o)||i,o};return r.cache=new(aa.Cache||we),r}function fa(n){if("function"!=typeof n)throw new it(f);return function(){var t=arguments;switch(t.length){case 0:return!n.call(this);case 1:return!n.call(this,t[0]);case 2:return!n.call(this,t[0],t[1]);case 3:return!n.call(this,t[0],t[1],t[2])}return!n.apply(this,t)}}aa.Cache=we;var ca=Zu(function(n,t){var r=(t=1==t.length&&da(t[0])?nr(t[0],dr(Li())):nr(De(t,1),dr(Li()))).length;return Su(function(e){for(var u=-1,i=Jr(e.length,r);++u=t}),ga=uu(function(){return arguments}())?uu:function(n){return Ea(n)&&st.call(n,"callee")&&!Lt.call(n,"callee")},da=e.isArray,ya=Mt?dr(Mt):function(n){return Ea(n)&&Qe(n)==cn};function ba(n){return null!=n&&Oa(n.length)&&!ja(n)}function wa(n){return Ea(n)&&ba(n)}var ma=Vr||Df,xa=Vt?dr(Vt):function(n){return Ea(n)&&Qe(n)==q};function Sa(n){if(!Ea(n))return!1;var t=Qe(n);return t==Z||t==J||"string"==typeof n.message&&"string"==typeof n.name&&!Ra(n)}function ja(n){if(!ka(n))return!1;var t=Qe(n);return t==H||t==K||t==$||t==nn}function Aa(n){return"number"==typeof n&&n==Va(n)}function Oa(n){return"number"==typeof n&&n>-1&&n%1==0&&n<=C}function ka(n){var t=typeof n;return null!=n&&("object"==t||"function"==t)}function Ea(n){return null!=n&&"object"==typeof n}var Ia=Pt?dr(Pt):function(n){return Ea(n)&&Vi(n)==G};function za(n){return"number"==typeof n||Ea(n)&&Qe(n)==Y}function Ra(n){if(!Ea(n)||Qe(n)!=X)return!1;var t=Tt(n);if(null===t)return!0;var r=st.call(t,"constructor")&&t.constructor;return"function"==typeof r&&r instanceof r&<.call(r)==_t}var Ta=$t?dr($t):function(n){return Ea(n)&&Qe(n)==tn};var Wa=Dt?dr(Dt):function(n){return Ea(n)&&Vi(n)==rn};function Ca(n){return"string"==typeof n||!da(n)&&Ea(n)&&Qe(n)==en}function La(n){return"symbol"==typeof n||Ea(n)&&Qe(n)==un}var Na=qt?dr(qt):function(n){return Ea(n)&&Oa(n.length)&&!!kt[Qe(n)]};var Ba=bi(su),Fa=bi(function(n,t){return n<=t});function Ua(n){if(!n)return[];if(ba(n))return Ca(n)?Tr(n):ri(n);if(Ut&&n[Ut])return function(n){for(var t,r=[];!(t=n.next()).done;)r.push(t.value);return r}(n[Ut]());var t=Vi(n);return(t==G?Or:t==rn?Ir:vf)(n)}function Ma(n){return n?(n=$a(n))===W||n===-W?(n<0?-1:1)*L:n==n?n:0:0===n?n:0}function Va(n){var t=Ma(n),r=t%1;return t==t?r?t-r:t:0}function Pa(n){return n?Ce(Va(n),0,B):0}function $a(n){if("number"==typeof n)return n;if(La(n))return N;if(ka(n)){var t="function"==typeof n.valueOf?n.valueOf():n;n=ka(t)?t+"":t}if("string"!=typeof n)return 0===n?n:+n;n=n.replace(Ln,"");var r=Jn.test(n);return r||Hn.test(n)?Rt(n.slice(2),r?2:8):qn.test(n)?N:+n}function Da(n){return ei(n,of(n))}function qa(n){return null==n?"":Nu(n)}var Ja=ii(function(n,t){if(Gi(t)||ba(t))ei(t,uf(t),n);else for(var r in t)st.call(t,r)&&Ee(n,r,t[r])}),Za=ii(function(n,t){ei(t,of(t),n)}),Ha=ii(function(n,t,r,e){ei(t,of(t),n,e)}),Ka=ii(function(n,t,r,e){ei(t,uf(t),n,e)}),Ga=Ii(We);var Ya=Su(function(n,t){n=rt(n);var r=-1,e=t.length,u=e>2?t[2]:i;for(u&&Ji(t[0],t[1],u)&&(e=1);++r1),t}),ei(n,Ri(n),r),e&&(r=Le(r,h|p|v,ki));for(var u=t.length;u--;)Fu(r,t[u]);return r});var lf=Ii(function(n,t){return null==n?{}:function(n,t){return yu(n,t,function(t,r){return nf(n,r)})}(n,t)});function sf(n,t){if(null==n)return{};var r=nr(Ri(n),function(n){return[n]});return t=Li(t),yu(n,r,function(n,r){return t(n,r[0])})}var hf=Si(uf),pf=Si(of);function vf(n){return null==n?[]:yr(n,uf(n))}var _f=ci(function(n,t,r){return t=t.toLowerCase(),n+(r?gf(t):t)});function gf(n){return jf(qa(n).toLowerCase())}function df(n){return(n=qa(n))&&n.replace(Gn,xr).replace(wt,"")}var yf=ci(function(n,t,r){return n+(r?"-":"")+t.toLowerCase()}),bf=ci(function(n,t,r){return n+(r?" ":"")+t.toLowerCase()}),wf=fi("toLowerCase");var mf=ci(function(n,t,r){return n+(r?"_":"")+t.toLowerCase()});var xf=ci(function(n,t,r){return n+(r?" ":"")+jf(t)});var Sf=ci(function(n,t,r){return n+(r?" ":"")+t.toUpperCase()}),jf=fi("toUpperCase");function Af(n,t,r){return n=qa(n),(t=r?i:t)===i?function(n){return jt.test(n)}(n)?function(n){return n.match(xt)||[]}(n):function(n){return n.match(Vn)||[]}(n):n.match(t)||[]}var Of=Su(function(n,t){try{return Jt(n,i,t)}catch(r){return Sa(r)?r:new Xn(r)}}),kf=Ii(function(n,t){return Ht(t,function(t){t=co(t),Te(n,t,ra(n[t],n))}),n});function Ef(n){return function(){return n}}var If=hi(),zf=hi(!0);function Rf(n){return n}function Tf(n){return fu("function"==typeof n?n:Le(n,h))}var Wf=Su(function(n,t){return function(r){return eu(r,n,t)}}),Cf=Su(function(n,t){return function(r){return eu(n,r,t)}});function Lf(n,t,r){var e=uf(t),u=Ke(t,e);null!=r||ka(t)&&(u.length||!e.length)||(r=t,t=n,n=this,u=Ke(t,uf(t)));var i=!(ka(r)&&"chain"in r&&!r.chain),o=ja(n);return Ht(u,function(r){var e=t[r];n[r]=e,o&&(n.prototype[r]=function(){var t=this.__chain__;if(i||t){var r=n(this.__wrapped__),u=r.__actions__=ri(this.__actions__);return u.push({func:e,args:arguments,thisArg:n}),r.__chain__=t,r}return e.apply(n,tr([this.value()],arguments))})}),n}function Nf(){}var Bf=gi(nr),Ff=gi(Gt),Uf=gi(ur);function Mf(n){return Zi(n)?hr(co(n)):function(n){return function(t){return Ge(t,n)}}(n)}var Vf=yi(),Pf=yi(!0);function $f(){return[]}function Df(){return!1}var qf=_i(function(n,t){return n+t},0),Jf=mi("ceil"),Zf=_i(function(n,t){return n/t},1),Hf=mi("floor");var Kf,Gf=_i(function(n,t){return n*t},1),Yf=mi("round"),Qf=_i(function(n,t){return n-t},0);return pe.after=function(n,t){if("function"!=typeof t)throw new it(f);return n=Va(n),function(){if(--n<1)return t.apply(this,arguments)}},pe.ary=na,pe.assign=Ja,pe.assignIn=Za,pe.assignInWith=Ha,pe.assignWith=Ka,pe.at=Ga,pe.before=ta,pe.bind=ra,pe.bindAll=kf,pe.bindKey=ea,pe.castArray=function(){if(!arguments.length)return[];var n=arguments[0];return da(n)?n:[n]},pe.chain=Uo,pe.chunk=function(n,t,r){t=(r?Ji(n,t,r):t===i)?1:qr(Va(t),0);var u=null==n?0:n.length;if(!u||t<1)return[];for(var o=0,a=0,f=e(Fr(u/t));ou?0:u+r),(e=e===i||e>u?u:Va(e))<0&&(e+=u),e=r>e?0:Pa(e);r>>0)?(n=qa(n))&&("string"==typeof t||null!=t&&!Ta(t))&&!(t=Nu(t))&&Ar(n)?Hu(Tr(n),0,r):n.split(t,r):[]},pe.spread=function(n,t){if("function"!=typeof n)throw new it(f);return t=null==t?0:qr(Va(t),0),Su(function(r){var e=r[t],u=Hu(r,0,t);return e&&tr(u,e),Jt(n,this,u)})},pe.tail=function(n){var t=null==n?0:n.length;return t?zu(n,1,t):[]},pe.take=function(n,t,r){return n&&n.length?zu(n,0,(t=r||t===i?1:Va(t))<0?0:t):[]},pe.takeRight=function(n,t,r){var e=null==n?0:n.length;return e?zu(n,(t=e-(t=r||t===i?1:Va(t)))<0?0:t,e):[]},pe.takeRightWhile=function(n,t){return n&&n.length?Mu(n,Li(t,3),!1,!0):[]},pe.takeWhile=function(n,t){return n&&n.length?Mu(n,Li(t,3)):[]},pe.tap=function(n,t){return t(n),n},pe.throttle=function(n,t,r){var e=!0,u=!0;if("function"!=typeof n)throw new it(f);return ka(r)&&(e="leading"in r?!!r.leading:e,u="trailing"in r?!!r.trailing:u),ua(n,t,{leading:e,maxWait:t,trailing:u})},pe.thru=Mo,pe.toArray=Ua,pe.toPairs=hf,pe.toPairsIn=pf,pe.toPath=function(n){return da(n)?nr(n,co):La(n)?[n]:ri(fo(qa(n)))},pe.toPlainObject=Da,pe.transform=function(n,t,r){var e=da(n),u=e||ma(n)||Na(n);if(t=Li(t,4),null==r){var i=n&&n.constructor;r=u?e?new i:[]:ka(n)&&ja(i)?ve(Tt(n)):{}}return(u?Ht:Ze)(n,function(n,e,u){return t(r,n,e,u)}),r},pe.unary=function(n){return na(n,1)},pe.union=Eo,pe.unionBy=Io,pe.unionWith=zo,pe.uniq=function(n){return n&&n.length?Bu(n):[]},pe.uniqBy=function(n,t){return n&&n.length?Bu(n,Li(t,2)):[]},pe.uniqWith=function(n,t){return t="function"==typeof t?t:i,n&&n.length?Bu(n,i,t):[]},pe.unset=function(n,t){return null==n||Fu(n,t)},pe.unzip=Ro,pe.unzipWith=To,pe.update=function(n,t,r){return null==n?n:Uu(n,t,qu(r))},pe.updateWith=function(n,t,r,e){return e="function"==typeof e?e:i,null==n?n:Uu(n,t,qu(r),e)},pe.values=vf,pe.valuesIn=function(n){return null==n?[]:yr(n,of(n))},pe.without=Wo,pe.words=Af,pe.wrap=function(n,t){return la(qu(t),n)},pe.xor=Co,pe.xorBy=Lo,pe.xorWith=No,pe.zip=Bo,pe.zipObject=function(n,t){return $u(n||[],t||[],Ee)},pe.zipObjectDeep=function(n,t){return $u(n||[],t||[],Ou)},pe.zipWith=Fo,pe.entries=hf,pe.entriesIn=pf,pe.extend=Za,pe.extendWith=Ha,Lf(pe,pe),pe.add=qf,pe.attempt=Of,pe.camelCase=_f,pe.capitalize=gf,pe.ceil=Jf,pe.clamp=function(n,t,r){return r===i&&(r=t,t=i),r!==i&&(r=(r=$a(r))==r?r:0),t!==i&&(t=(t=$a(t))==t?t:0),Ce($a(n),t,r)},pe.clone=function(n){return Le(n,v)},pe.cloneDeep=function(n){return Le(n,h|v)},pe.cloneDeepWith=function(n,t){return Le(n,h|v,t="function"==typeof t?t:i)},pe.cloneWith=function(n,t){return Le(n,v,t="function"==typeof t?t:i)},pe.conformsTo=function(n,t){return null==t||Ne(n,t,uf(t))},pe.deburr=df,pe.defaultTo=function(n,t){return null==n||n!=n?t:n},pe.divide=Zf,pe.endsWith=function(n,t,r){n=qa(n),t=Nu(t);var e=n.length,u=r=r===i?e:Ce(Va(r),0,e);return(r-=t.length)>=0&&n.slice(r,u)==t},pe.eq=pa,pe.escape=function(n){return(n=qa(n))&&On.test(n)?n.replace(jn,Sr):n},pe.escapeRegExp=function(n){return(n=qa(n))&&Cn.test(n)?n.replace(Wn,"\\$&"):n},pe.every=function(n,t,r){var e=da(n)?Gt:Ve;return r&&Ji(n,t,r)&&(t=i),e(n,Li(t,3))},pe.find=$o,pe.findIndex=_o,pe.findKey=function(n,t){return or(n,Li(t,3),Ze)},pe.findLast=Do,pe.findLastIndex=go,pe.findLastKey=function(n,t){return or(n,Li(t,3),He)},pe.floor=Hf,pe.forEach=qo,pe.forEachRight=Jo,pe.forIn=function(n,t){return null==n?n:qe(n,Li(t,3),of)},pe.forInRight=function(n,t){return null==n?n:Je(n,Li(t,3),of)},pe.forOwn=function(n,t){return n&&Ze(n,Li(t,3))},pe.forOwnRight=function(n,t){return n&&He(n,Li(t,3))},pe.get=Xa,pe.gt=va,pe.gte=_a,pe.has=function(n,t){return null!=n&&Pi(n,t,nu)},pe.hasIn=nf,pe.head=bo,pe.identity=Rf,pe.includes=function(n,t,r,e){n=ba(n)?n:vf(n),r=r&&!e?Va(r):0;var u=n.length;return r<0&&(r=qr(u+r,0)),Ca(n)?r<=u&&n.indexOf(t,r)>-1:!!u&&fr(n,t,r)>-1},pe.indexOf=function(n,t,r){var e=null==n?0:n.length;if(!e)return-1;var u=null==r?0:Va(r);return u<0&&(u=qr(e+u,0)),fr(n,t,u)},pe.inRange=function(n,t,r){return t=Ma(t),r===i?(r=t,t=0):r=Ma(r),function(n,t,r){return n>=Jr(t,r)&&n=-C&&n<=C},pe.isSet=Wa,pe.isString=Ca,pe.isSymbol=La,pe.isTypedArray=Na,pe.isUndefined=function(n){return n===i},pe.isWeakMap=function(n){return Ea(n)&&Vi(n)==an},pe.isWeakSet=function(n){return Ea(n)&&Qe(n)==fn},pe.join=function(n,t){return null==n?"":$r.call(n,t)},pe.kebabCase=yf,pe.last=So,pe.lastIndexOf=function(n,t,r){var e=null==n?0:n.length;if(!e)return-1;var u=e;return r!==i&&(u=(u=Va(r))<0?qr(e+u,0):Jr(u,e-1)),t==t?function(n,t,r){for(var e=r+1;e--;)if(n[e]===t)return e;return e}(n,t,u):ar(n,lr,u,!0)},pe.lowerCase=bf,pe.lowerFirst=wf,pe.lt=Ba,pe.lte=Fa,pe.max=function(n){return n&&n.length?Pe(n,Rf,Xe):i},pe.maxBy=function(n,t){return n&&n.length?Pe(n,Li(t,2),Xe):i},pe.mean=function(n){return sr(n,Rf)},pe.meanBy=function(n,t){return sr(n,Li(t,2))},pe.min=function(n){return n&&n.length?Pe(n,Rf,su):i},pe.minBy=function(n,t){return n&&n.length?Pe(n,Li(t,2),su):i},pe.stubArray=$f,pe.stubFalse=Df,pe.stubObject=function(){return{}},pe.stubString=function(){return""},pe.stubTrue=function(){return!0},pe.multiply=Gf,pe.nth=function(n,t){return n&&n.length?gu(n,Va(t)):i},pe.noConflict=function(){return Ct._===this&&(Ct._=gt),this},pe.noop=Nf,pe.now=Xo,pe.pad=function(n,t,r){n=qa(n);var e=(t=Va(t))?Rr(n):0;if(!t||e>=t)return n;var u=(t-e)/2;return di(Ur(u),r)+n+di(Fr(u),r)},pe.padEnd=function(n,t,r){n=qa(n);var e=(t=Va(t))?Rr(n):0;return t&&et){var e=n;n=t,t=e}if(r||n%1||t%1){var u=Kr();return Jr(n+u*(t-n+zt("1e-"+((u+"").length-1))),t)}return mu(n,t)},pe.reduce=function(n,t,r){var e=da(n)?rr:vr,u=arguments.length<3;return e(n,Li(t,4),r,u,Ue)},pe.reduceRight=function(n,t,r){var e=da(n)?er:vr,u=arguments.length<3;return e(n,Li(t,4),r,u,Me)},pe.repeat=function(n,t,r){return t=(r?Ji(n,t,r):t===i)?1:Va(t),xu(qa(n),t)},pe.replace=function(){var n=arguments,t=qa(n[0]);return n.length<3?t:t.replace(n[1],n[2])},pe.result=function(n,t,r){var e=-1,u=(t=Ju(t,n)).length;for(u||(u=1,n=i);++eC)return[];var r=B,e=Jr(n,B);t=Li(t),n-=B;for(var u=gr(e,t);++r=o)return n;var f=r-Rr(e);if(f<1)return e;var c=a?Hu(a,0,f).join(""):n.slice(0,f);if(u===i)return c+e;if(a&&(f+=c.length-f),Ta(u)){if(n.slice(f).search(u)){var l,s=c;for(u.global||(u=et(u.source,qa(Dn.exec(u))+"g")),u.lastIndex=0;l=u.exec(s);)var h=l.index;c=c.slice(0,h===i?f:h)}}else if(n.indexOf(Nu(u),f)!=f){var p=c.lastIndexOf(u);p>-1&&(c=c.slice(0,p))}return c+e},pe.unescape=function(n){return(n=qa(n))&&An.test(n)?n.replace(Sn,Wr):n},pe.uniqueId=function(n){var t=++ht;return qa(n)+t},pe.upperCase=Sf,pe.upperFirst=jf,pe.each=qo,pe.eachRight=Jo,pe.first=bo,Lf(pe,(Kf={},Ze(pe,function(n,t){st.call(pe.prototype,t)||(Kf[t]=n)}),Kf),{chain:!1}),pe.VERSION="4.17.14",Ht(["bind","bindKey","curry","curryRight","partial","partialRight"],function(n){pe[n].placeholder=pe}),Ht(["drop","take"],function(n,t){de.prototype[n]=function(r){r=r===i?1:qr(Va(r),0);var e=this.__filtered__&&!t?new de(this):this.clone();return e.__filtered__?e.__takeCount__=Jr(r,e.__takeCount__):e.__views__.push({size:Jr(r,B),type:n+(e.__dir__<0?"Right":"")}),e},de.prototype[n+"Right"]=function(t){return this.reverse()[n](t).reverse()}}),Ht(["filter","map","takeWhile"],function(n,t){var r=t+1,e=r==R||3==r;de.prototype[n]=function(n){var t=this.clone();return t.__iteratees__.push({iteratee:Li(n,3),type:r}),t.__filtered__=t.__filtered__||e,t}}),Ht(["head","last"],function(n,t){var r="take"+(t?"Right":"");de.prototype[n]=function(){return this[r](1).value()[0]}}),Ht(["initial","tail"],function(n,t){var r="drop"+(t?"":"Right");de.prototype[n]=function(){return this.__filtered__?new de(this):this[r](1)}}),de.prototype.compact=function(){return this.filter(Rf)},de.prototype.find=function(n){return this.filter(n).head()},de.prototype.findLast=function(n){return this.reverse().find(n)},de.prototype.invokeMap=Su(function(n,t){return"function"==typeof n?new de(this):this.map(function(r){return eu(r,n,t)})}),de.prototype.reject=function(n){return this.filter(fa(Li(n)))},de.prototype.slice=function(n,t){n=Va(n);var r=this;return r.__filtered__&&(n>0||t<0)?new de(r):(n<0?r=r.takeRight(-n):n&&(r=r.drop(n)),t!==i&&(r=(t=Va(t))<0?r.dropRight(-t):r.take(t-n)),r)},de.prototype.takeRightWhile=function(n){return this.reverse().takeWhile(n).reverse()},de.prototype.toArray=function(){return this.take(B)},Ze(de.prototype,function(n,t){var r=/^(?:filter|find|map|reject)|While$/.test(t),e=/^(?:head|last)$/.test(t),u=pe[e?"take"+("last"==t?"Right":""):t],o=e||/^find/.test(t);u&&(pe.prototype[t]=function(){var t=this.__wrapped__,a=e?[1]:arguments,f=t instanceof de,c=a[0],l=f||da(t),s=function(n){var t=u.apply(pe,tr([n],a));return e&&h?t[0]:t};l&&r&&"function"==typeof c&&1!=c.length&&(f=l=!1);var h=this.__chain__,p=!!this.__actions__.length,v=o&&!h,_=f&&!p;if(!o&&l){t=_?t:new de(this);var g=n.apply(t,a);return g.__actions__.push({func:Mo,args:[s],thisArg:i}),new ge(g,h)}return v&&_?n.apply(this,a):(g=this.thru(s),v?e?g.value()[0]:g.value():g)})}),Ht(["pop","push","shift","sort","splice","unshift"],function(n){var t=ot[n],r=/^(?:push|sort|unshift)$/.test(n)?"tap":"thru",e=/^(?:pop|shift)$/.test(n);pe.prototype[n]=function(){var n=arguments;if(e&&!this.__chain__){var u=this.value();return t.apply(da(u)?u:[],n)}return this[r](function(r){return t.apply(da(r)?r:[],n)})}}),Ze(de.prototype,function(n,t){var r=pe[t];if(r){var e=r.name+"";st.call(ue,e)||(ue[e]=[]),ue[e].push({name:t,func:r})}}),ue[pi(i,y).name]=[{name:"wrapper",func:i}],de.prototype.clone=function(){var n=new de(this.__wrapped__);return n.__actions__=ri(this.__actions__),n.__dir__=this.__dir__,n.__filtered__=this.__filtered__,n.__iteratees__=ri(this.__iteratees__),n.__takeCount__=this.__takeCount__,n.__views__=ri(this.__views__),n},de.prototype.reverse=function(){if(this.__filtered__){var n=new de(this);n.__dir__=-1,n.__filtered__=!0}else(n=this.clone()).__dir__*=-1;return n},de.prototype.value=function(){var n=this.__wrapped__.value(),t=this.__dir__,r=da(n),e=t<0,u=r?n.length:0,i=function(n,t,r){for(var e=-1,u=r.length;++e=this.__values__.length;return{done:n,value:n?i:this.__values__[this.__index__++]}},pe.prototype.plant=function(n){for(var t,r=this;r instanceof _e;){var e=so(r);e.__index__=0,e.__values__=i,t?u.__wrapped__=e:t=e;var u=e;r=r.__wrapped__}return u.__wrapped__=n,t},pe.prototype.reverse=function(){var n=this.__wrapped__;if(n instanceof de){var t=n;return this.__actions__.length&&(t=new de(this)),(t=t.reverse()).__actions__.push({func:Mo,args:[ko],thisArg:i}),new ge(t,this.__chain__)}return this.thru(ko)},pe.prototype.toJSON=pe.prototype.valueOf=pe.prototype.value=function(){return Vu(this.__wrapped__,this.__actions__)},pe.prototype.first=pe.prototype.head,Ut&&(pe.prototype[Ut]=function(){return this}),pe}();Ct._=Cr,(u=function(){return Cr}.call(t,r,t,e))===i||(e.exports=u)}).call(this)}).call(this,r(2),r(3)(n))},function(n,t){n.exports=require("sketch")},function(n,t){var r;r=function(){return this}();try{r=r||new Function("return this")()}catch(e){"object"==typeof window&&(r=window)}n.exports=r},function(n,t){n.exports=function(n){return n.webpackPolyfill||(n.deprecate=function(){},n.paths=[],n.children||(n.children=[]),Object.defineProperty(n,"loaded",{enumerable:!0,get:function(){return n.l}}),Object.defineProperty(n,"id",{enumerable:!0,get:function(){return n.i}}),n.webpackPolyfill=1),n}},function(n,r,e){"use strict";e.r(r);var u,i,o,a,f,c,l,s,h,p,v=e(1),_=e.n(v),g=e(0),d=e.n(g),y={"JavaScript Object":{lineStart:"",prefix:" '",diviner:"': '",postfix:"',\n",lineEnd:"}",filetype:"js"},"JavaScript Variables":{lineStart:"",prefix:"const ",diviner:" = '",postfix:"';\n",lineEnd:"",filetype:"js"},SCSS:{lineStart:"",prefix:"$",diviner:": ",postfix:";\n",lineEnd:"",filetype:"scss"},Less:{lineStart:"",prefix:"@",diviner:": ",postfix:";\n",lineEnd:"",filetype:"less"},CSS:{lineStart:":root {\n",prefix:" --",diviner:": ",postfix:";\n",lineEnd:"}",filetype:"css"},JSON:{lineStart:{},prefix:"",diviner:"",postfix:"",lineEnd:"",filetype:"json"},YAML:{lineStart:{},prefix:"",diviner:"",postfix:"",lineEnd:"",filetype:"yml"}},b=function(n,t){var r=n.name.split("/"),e="";if(0==t)e=d.a.kebabCase(r);else if(1==t)e=d.a.camelCase(d.a.join(r,"-"));else{var u=t-2;e=r.length4&&void 0!==arguments[4]&&arguments[4],i=NSPopUpButton.alloc().initWithFrame(NSMakeRect(0,e-n,r,22));if(u){var o=t.map(function(n){return n.name}),a=o[0].split("/"),f=d.a.kebabCase(a),c=d.a.camelCase(d.a.join(a,"-"));i.addItemWithTitle(f),i.addItemWithTitle(c),a.length>1&&d.a.forEach(a,function(n){i.addItemWithTitle(n.toLowerCase().replace(/ /g,""))})}else d.a.forEach(t,function(n){i.addItemWithTitle(n)});return i.selectItemAtIndex(0),i},x=function(n,t,r,e){var u=arguments.length>4&&void 0!==arguments[4]&&arguments[4],i=NSButton.alloc().initWithFrame(NSMakeRect(0,e-n,r,20)),o=u?NSOnState:NSOffState;return i.setButtonType(NSSwitchButton),i.setBezelStyle(0),i.setTitle(t),i.setState(o),i},S=function(n){var r=function(n){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"Choose variables format.",e=COSAlertWindow.new();return e.setIcon(NSImage.alloc().initByReferencingFile(t.plugin.urlForResourceNamed("icon.png").path())),e.setMessageText(n),e.setInformativeText(r),e.addButtonWithTitle("Ok"),e.addButtonWithTitle("Cancel"),e}("Export Text Styles"),e=NSView.alloc().initWithFrame(NSMakeRect(0,0,300,340));r.addAccessoryView(e),e.addSubview(w(35,"File format:",300,340));u=m(45,["CSS","JSON","JavaScript Object"],300,340),e.addSubview(u),e.addSubview(w(90,"Units:",300,340));return i=m(100,["Absolute (px)","Relative (em/rem)"],300,340),e.addSubview(i),e.addSubview(w(145,"Naming:",300,340)),o=m(155,n,300,340,!0),e.addSubview(o),e.addSubview(w(200,"Export selected values:",300,340)),a=x(210,"Font Family",300,340),e.addSubview(a),f=x(230,"Font Size",300,340,!0),e.addSubview(f),c=x(250,"Font Weight",300,340,!0),e.addSubview(c),l=x(270,"Line Height",300,340,!0),e.addSubview(l),s=x(290,"Letter Spacing",300,340,!0),e.addSubview(s),h=x(310,"Text Transform",300,340,!0),e.addSubview(h),p=x(330,"Color",300,340),e.addSubview(p),r.runModal()};r.default=function(){var n=_.a.getSelectedDocument().selectedLayers.layers,t=d.a.filter(d.a.reverse(n),["type","Text"]);if(0!==d.a.size(t)){var r=S(t),e=u.titleOfSelectedItem(),v=i.titleOfSelectedItem(),g=o.indexOfSelectedItem();"1000"==r&&function(n,t,r,e){var u=n.length,i=NSArray.arrayWithArray([y[t].filetype,nil]),o=NSSavePanel.savePanel();if(o.setAllowedFileTypes(i),o.setNameFieldStringValue("textstyles."+y[t].filetype),o.setPrompt("Save Text Styles"),o.runModal()&&0!==u){var v="";v="JSON"==t?{}:"JavaScript Object"==t?"const textStyles = {\n":"",d.a.forEach(n,function(n){var u=b(n,e),i=n.style.fontFamily,o="Absolute (px)"==r?n.style.fontSize+"px":n.style.fontSize/16+"rem",_=100*n.style.fontWeight,g="Absolute (px)"==r?d.a.round(n.style.lineHeight,2)+"px":d.a.round(n.style.lineHeight/n.style.fontSize,2),y=null==n.style.kerning?"normal":"Absolute (px)"==r?d.a.round(n.style.kerning,2)+"px":d.a.round(n.style.kerning/n.style.fontSize,2)+"em",w=n.style.textTransform,m=n.style.textColor.substr(0,7);"JSON"==t?(v[u]={},1==a.stringValue()&&(v[u].fontFamily=i),1==f.stringValue()&&(v[u].fontSize=o),1==c.stringValue()&&(v[u].fontWeight=_),1==l.stringValue()&&(v[u].lineHeight=g),1==s.stringValue()&&(v[u].letterSpacing=y),1==h.stringValue()&&(v[u].textTransform=w),1==p.stringValue()&&(v[u].color=m)):"JavaScript Object"==t?(v=v.concat('\t"'+u+'": {\n'),1==a.stringValue()&&(v=v.concat('\t\tfontFamily: "'+i+'",\n')),1==f.stringValue()&&(v=v.concat('\t\tfontSize: "'+o+'",\n')),1==c.stringValue()&&(v=v.concat("\t\tfontWeight: "+_+",\n")),1==l.stringValue()&&(v=v.concat('\t\tlineHeight: "'+g+'",\n')),1==s.stringValue()&&(v=v.concat('\t\tletterSpacing: "'+y+'",\n')),1==h.stringValue()&&(v=v.concat('\t\ttextTransform: "'+w+'",\n')),1==p.stringValue()&&(v=v.concat('\t\tcolor: "'+m+'",\n')),v=v.concat("\t},\n")):"CSS"==t&&(v=v.concat("."+u+"{\n"),1==a.stringValue()&&(v=v.concat('\tfont-family: "'+i+'";\n')),1==f.stringValue()&&(v=v.concat("\tfont-size: "+o+";\n")),1==c.stringValue()&&(v=v.concat("\tfont-weight: "+_+";\n")),1==l.stringValue()&&(v=v.concat("\tline-height: "+g+";\n")),1==s.stringValue()&&(v=v.concat("\tletter-spacing: "+y+";\n")),1==h.stringValue()&&(v=v.concat("\ttext-transform: "+w+";\n")),1==p.stringValue()&&(v=v.concat("\tcolor: "+m+";\n")),v=v.concat("}\n"))});var g="";if("JSON"==t){var w={textstyles:v};g=NSString.stringWithString(JSON.stringify(w,null,"\t"))}else"JavaScript Object"==t?(v=v.concat("}"),g=NSString.stringWithString(v)):g=NSString.stringWithString(v);var m=o.URL().path();g.writeToFile_atomically_encoding_error(m,!0,NSUTF8StringEncoding,null),_.a.UI.message("Text Styles Exported!")}}(t,e,v,g)}else _.a.UI.alert("Select layers","Please select text layers first.")}}]);if("default"===n&&"function"==typeof r)r(t);else{if("function"!=typeof r[n])throw new Error('Missing export named "'+n+'". Your command should contain something like `export function " + key +"() {}`.');r[n](t)}}globalThis.onRun=__skpm_run.bind(this,"default");
--------------------------------------------------------------------------------
/images/colors.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/here-erhe/Design-Token-Exporter/876d92c845a4500a8babf68e4a63ca56f43e3951/images/colors.gif
--------------------------------------------------------------------------------
/images/exportTokens.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/here-erhe/Design-Token-Exporter/876d92c845a4500a8babf68e4a63ca56f43e3951/images/exportTokens.gif
--------------------------------------------------------------------------------
/images/fontsize.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/here-erhe/Design-Token-Exporter/876d92c845a4500a8babf68e4a63ca56f43e3951/images/fontsize.gif
--------------------------------------------------------------------------------
/images/gitcover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/here-erhe/Design-Token-Exporter/876d92c845a4500a8babf68e4a63ca56f43e3951/images/gitcover.jpg
--------------------------------------------------------------------------------
/images/spacing.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/here-erhe/Design-Token-Exporter/876d92c845a4500a8babf68e4a63ca56f43e3951/images/spacing.gif
--------------------------------------------------------------------------------
/images/textstyles.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/here-erhe/Design-Token-Exporter/876d92c845a4500a8babf68e4a63ca56f43e3951/images/textstyles.gif
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "design-token-exporter",
3 | "description": "Simple Design Token Exporter",
4 | "author": "Herkko Huttunen",
5 | "version": "1.0.1",
6 | "license": "MIT",
7 | "repository": {
8 | "type": "git",
9 | "url": "https://github.com/here-erhe/Design-Token-Exporter"
10 | },
11 | "engines": {
12 | "sketch": ">=51.0"
13 | },
14 | "skpm": {
15 | "name": "Design Token Exporter",
16 | "manifest": "src/manifest.json",
17 | "main": "design-token-exporter.sketchplugin",
18 | "assets": [
19 | "assets/**/*"
20 | ]
21 | },
22 | "scripts": {
23 | "build": "skpm-build",
24 | "watch": "skpm-build --watch",
25 | "start": "skpm-build --watch --run",
26 | "postinstall": "npm run build && skpm-link"
27 | },
28 | "devDependencies": {
29 | "@skpm/builder": "^0.7.5"
30 | },
31 | "dependencies": {
32 | "json-to-pretty-yaml": "^1.2.2",
33 | "lodash": "^4.17.15"
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/colorTokens.js:
--------------------------------------------------------------------------------
1 | import sketch from 'sketch'
2 | import _ from 'lodash'
3 |
4 | import values from './lib/values'
5 | import hexAToRGBA from './lib/hexAToRGBA'
6 | import formatObject from './lib/formatObject'
7 | import varNaming from './lib/varNaming'
8 |
9 | import {dialogAlert,fieldLabel, fieldSelect} from './lib/dialogFields'
10 |
11 |
12 | let dropdownFileType;
13 | let dropdownFormat;
14 | let dropdownNames;
15 |
16 | /**
17 | *
18 | * Dialog
19 | *
20 | */
21 | const dialogBox = (selectedLayers) => {
22 |
23 | let alert = dialogAlert("Export Color Variables");
24 |
25 | // Creating the view
26 |
27 | let viewWidth = 300;
28 | let viewHeight = 180;
29 |
30 |
31 | let view = NSView.alloc().initWithFrame(NSMakeRect(0, 0, viewWidth, viewHeight));
32 | alert.addAccessoryView(view);
33 |
34 | //Dropdown: File format
35 |
36 | view.addSubview(fieldLabel(35, 'File format:', viewWidth, viewHeight));
37 |
38 | let names = ["SCSS","Less","CSS","JSON","JavaScript Object","JavaScript Variables"];
39 | dropdownFileType = fieldSelect(45, names, viewWidth, viewHeight)
40 |
41 | view.addSubview(dropdownFileType);
42 |
43 | //Dropdown: Color value
44 |
45 | view.addSubview(fieldLabel(90, 'Color value:', viewWidth, viewHeight));
46 |
47 | let types = ["HEX", "RGBA"];
48 | dropdownFormat = fieldSelect(100, types, viewWidth, viewHeight)
49 | view.addSubview(dropdownFormat);
50 |
51 | //Dropdown: Naming
52 |
53 | view.addSubview(fieldLabel(145, 'Naming:', viewWidth, viewHeight));
54 |
55 | dropdownNames = fieldSelect(155, selectedLayers, viewWidth, viewHeight, true)
56 | view.addSubview(dropdownNames);
57 |
58 |
59 | return alert.runModal();
60 |
61 | }
62 |
63 | /**
64 | *
65 | * Export exportColors
66 | *
67 | */
68 | const exportColors = (selectedLayers, type, format, naming) => {
69 |
70 |
71 | const selectedCount = selectedLayers.length;
72 |
73 | if (selectedCount !== 0) {
74 |
75 | let variables = {}
76 |
77 | _.forEach(selectedLayers, function (layer) {
78 |
79 | let fillArray = layer.style.fills;
80 |
81 | if(_.size(fillArray) != 0 && _.last(fillArray).fillType == 'Color' && _.last(fillArray).enabled){
82 |
83 | let colorName = varNaming(layer, naming);
84 | let colorFill = format == 'HEX' ? _.last(fillArray).color.substr(0, 7) : hexAToRGBA(_.last(fillArray).color);
85 | variables[colorName] = colorFill
86 |
87 | }
88 |
89 | })
90 |
91 | if(_.size(variables) == 0){
92 | sketch.UI.alert('Select layers','Select shape layers with solid fill color');
93 | }else{
94 |
95 |
96 | let fileTypes = NSArray.arrayWithArray([values[type].filetype, nil]);
97 | let savePanel = NSSavePanel.savePanel()
98 |
99 |
100 | //savePanel.setCanChooseDirectories(false);
101 | //savePanel.setCanCreateDirectories(false);
102 | savePanel.setAllowedFileTypes(fileTypes)
103 |
104 |
105 | savePanel.setNameFieldStringValue('colors.' + values[type].filetype)
106 | savePanel.setPrompt("Save Color Variables");
107 |
108 | savePanel.runModal();
109 |
110 |
111 | let file = NSString.stringWithString(formatObject(variables, type, 'colors'));
112 | let file_path = savePanel.URL().path();
113 | file.writeToFile_atomically_encoding_error(file_path, true, NSUTF8StringEncoding, null);
114 |
115 | sketch.UI.message('Color Variables Exported!');
116 | }
117 |
118 |
119 | }
120 |
121 | }
122 |
123 | /**
124 | *
125 | * Main
126 | *
127 | */
128 | export default () => {
129 |
130 | const doc = sketch.getSelectedDocument();
131 | const selected = doc.selectedLayers.layers;
132 |
133 | // Only ShapePath layers - no text layers
134 | const selectedLayers = _.filter(_.reverse(selected), ['type', 'ShapePath']);
135 | const selectedCount = _.size(selectedLayers);
136 |
137 | if (selectedCount !== 0) {
138 |
139 | const dialog = dialogBox(selectedLayers);
140 | const exportType = dropdownFileType.titleOfSelectedItem();
141 | const exportFormat = dropdownFormat.titleOfSelectedItem();
142 | const exportNaming = dropdownNames.indexOfSelectedItem();
143 |
144 |
145 | if(dialog == "1000"){
146 | exportColors(selectedLayers, exportType, exportFormat, exportNaming);
147 | }
148 |
149 | }else{
150 | sketch.UI.alert('Select layers','Please select shape layers first.');
151 | }
152 |
153 | }
--------------------------------------------------------------------------------
/src/exportTokens.js:
--------------------------------------------------------------------------------
1 | import sketch from 'sketch'
2 | import _ from 'lodash'
3 |
4 | import values from './lib/values'
5 | import formatObject from './lib/formatObject'
6 |
7 | import tokenValue from './lib/tokenValue'
8 |
9 | import {dialogAlert,fieldLabel, fieldSelect} from './lib/dialogFields'
10 |
11 |
12 | let dropdownFileType;
13 |
14 | /**
15 | *
16 | * Dialog
17 | *
18 | */
19 | const dialogBox = (selectedLayers) => {
20 |
21 | let alert = dialogAlert(
22 | "Export Design Tokens",
23 | "Choose tokens file format. Layers naming format is type/category/name (e.g. Color/Background-Color/Primary-red)."
24 | );
25 |
26 | // Creating the view
27 |
28 | let viewWidth = 300;
29 | let viewHeight = 60;
30 |
31 |
32 | let view = NSView.alloc().initWithFrame(NSMakeRect(0, 0, viewWidth, viewHeight));
33 | alert.addAccessoryView(view);
34 |
35 | //Dropdown: File format
36 |
37 | view.addSubview(fieldLabel(35, 'File format:', viewWidth, viewHeight));
38 |
39 | let names = ["YAML","JSON"];
40 | dropdownFileType = fieldSelect(45, names, viewWidth, viewHeight)
41 |
42 | view.addSubview(dropdownFileType);
43 |
44 |
45 | return alert.runModal();
46 |
47 | }
48 |
49 | /**
50 | *
51 | * Export exportColors
52 | *
53 | */
54 | const exportTokens = (selectedLayers, type) => {
55 |
56 |
57 | const selectedCount = selectedLayers.length;
58 |
59 | if (selectedCount !== 0) {
60 |
61 | let variables = {}
62 |
63 | _.forEach(selectedLayers, function (layer) {
64 |
65 | let layerNameArr = layer.name.split('/');
66 |
67 |
68 | if(_.size(layerNameArr) > 2){
69 | // Notice layer if it contains type/category/name
70 |
71 | let value = tokenValue(layer);
72 |
73 | if(value !== ""){
74 |
75 | let tokenType = layerNameArr[0];
76 | let tokenCategory = _.kebabCase(layerNameArr[1]);
77 | let tokenName = _.snakeCase(layerNameArr[2]);
78 |
79 | let newObj = {
80 | "value" : value,
81 | "type" : tokenType,
82 | "category" : tokenCategory
83 | };
84 |
85 | variables[tokenName] = newObj;
86 |
87 | }
88 | }
89 |
90 |
91 |
92 | })
93 |
94 | if(_.size(variables) == 0){
95 | sketch.UI.alert('Select layers or artboard','Select one artboard or multiple layers');
96 | }else{
97 |
98 |
99 | let fileTypes = NSArray.arrayWithArray([values[type].filetype, nil]);
100 | let savePanel = NSSavePanel.savePanel()
101 |
102 | savePanel.setAllowedFileTypes(fileTypes)
103 |
104 | savePanel.setNameFieldStringValue('tokens.' + values[type].filetype)
105 | savePanel.setPrompt("Save Tokens");
106 |
107 | savePanel.runModal();
108 |
109 |
110 | let file = NSString.stringWithString(formatObject(variables, type, 'props'));
111 | let file_path = savePanel.URL().path();
112 | file.writeToFile_atomically_encoding_error(file_path, true, NSUTF8StringEncoding, null);
113 |
114 | sketch.UI.message('Design Tokens Exported!');
115 | }
116 |
117 |
118 | }
119 |
120 | }
121 |
122 | /**
123 | *
124 | * Main
125 | *
126 | */
127 | export default () => {
128 |
129 | const doc = sketch.getSelectedDocument();
130 |
131 | let selected = [];
132 |
133 | selected = doc.selectedLayers.layers;
134 |
135 | const selectedCount = _.size(selected);
136 |
137 | if (selectedCount !== 0) {
138 |
139 | if(selected[0].type === "Artboard"){
140 | // Select artboard layers
141 | selected = selected[0].layers;
142 | }
143 |
144 | const selectedLayers = _.reverse(selected);
145 |
146 | const dialog = dialogBox(selectedLayers);
147 | const exportType = dropdownFileType.titleOfSelectedItem();
148 |
149 |
150 |
151 | if(dialog == "1000"){
152 | exportTokens(selectedLayers, exportType);
153 | }
154 |
155 | }else{
156 | sketch.UI.alert('Select tokens','Please select layers or artboard first.');
157 | }
158 |
159 | }
--------------------------------------------------------------------------------
/src/lib/dialogFields.js:
--------------------------------------------------------------------------------
1 | import _ from 'lodash'
2 |
3 | export const dialogAlert = (title, desc = "Choose variables format.") => {
4 |
5 | let alert = COSAlertWindow.new();
6 |
7 | alert.setIcon(NSImage.alloc().initByReferencingFile(context.plugin.urlForResourceNamed("icon.png").path()));
8 | alert.setMessageText(title);
9 | alert.setInformativeText(desc);
10 | alert.addButtonWithTitle("Ok");
11 | alert.addButtonWithTitle("Cancel");
12 |
13 | return alert;
14 |
15 | }
16 |
17 | export const fieldLabel = (pos, title, viewWidth, viewHeight) => {
18 |
19 | let label = NSTextField.alloc().initWithFrame(NSMakeRect(0,viewHeight - pos,viewWidth,35));
20 | label.setBezeled(false);
21 | label.setDrawsBackground(false);
22 | label.setEditable(false);
23 | label.setSelectable(false);
24 | label.setStringValue(title);
25 |
26 | return label;
27 |
28 | }
29 |
30 | export const fieldSelect = (pos, values, viewWidth, viewHeight, namingSelect = false) => {
31 |
32 | let select = NSPopUpButton.alloc().initWithFrame(NSMakeRect(0, viewHeight - pos, viewWidth, 22));
33 |
34 | if(namingSelect){
35 |
36 | const layerNames = values.map(layer => layer.name);
37 | const sliceArr = layerNames[0].split('/');
38 |
39 | let kebabCase = _.kebabCase(sliceArr);
40 | let camelCase = _.camelCase(_.join(sliceArr, '-'));
41 |
42 | select.addItemWithTitle(kebabCase);
43 | select.addItemWithTitle(camelCase);
44 |
45 | if(sliceArr.length > 1){
46 |
47 | _.forEach(sliceArr,function (slice) {
48 | select.addItemWithTitle(slice.toLowerCase().replace(/ /g, ''));
49 | });
50 |
51 | }
52 |
53 | }else{
54 |
55 | _.forEach(values, function(value) {
56 | select.addItemWithTitle(value);
57 | });
58 |
59 | }
60 |
61 |
62 | select.selectItemAtIndex(0);
63 |
64 | return select;
65 |
66 | }
67 |
68 |
69 | export const fieldCheckbox = (pos, label, viewWidth, viewHeight, state = false) => {
70 |
71 | let checkbox = NSButton.alloc().initWithFrame(NSMakeRect(0, viewHeight - pos, viewWidth, 20));
72 |
73 | let initState = state ? NSOnState : NSOffState;
74 |
75 | checkbox.setButtonType(NSSwitchButton);
76 | checkbox.setBezelStyle(0);
77 | checkbox.setTitle(label);
78 | checkbox.setState(initState);
79 |
80 | return checkbox;
81 |
82 | }
--------------------------------------------------------------------------------
/src/lib/formatObject.js:
--------------------------------------------------------------------------------
1 | import _ from 'lodash'
2 | import values from './values'
3 | import YAML from 'json-to-pretty-yaml';
4 |
5 | const formatObject = (obj, type, jsonTitle) => {
6 |
7 | let string = '';
8 |
9 | if(type == 'JSON'){
10 |
11 | let jsonObj = {};
12 | jsonObj[_.camelCase(jsonTitle)] = obj;
13 |
14 | string = JSON.stringify(jsonObj, null, "\t");
15 |
16 | }else if(type == 'YAML'){
17 |
18 | let jsonObj = {};
19 | jsonObj[_.camelCase(jsonTitle)] = obj;
20 |
21 | string = YAML.stringify(jsonObj);
22 |
23 | }else{
24 |
25 | if(type == 'JavaScript Object'){
26 | string = "const " + _.camelCase(jsonTitle) + " = {\n";
27 | }else{
28 | string = values[type].lineStart;
29 | }
30 |
31 |
32 | string = string.concat(
33 | _.join(
34 | _.map(obj, (value, key) => values[type].prefix + key + values[type].diviner + value + values[type].postfix),
35 | ''
36 | ));
37 |
38 | string = string.concat(values[type].lineEnd);
39 | }
40 |
41 | return string;
42 |
43 | }
44 |
45 | export default formatObject;
46 |
--------------------------------------------------------------------------------
/src/lib/hexAToRGBA.js:
--------------------------------------------------------------------------------
1 | const hexAToRGBA = (h) => {
2 | let r = 0, g = 0, b = 0, a = 1;
3 |
4 | if (h.length == 5) {
5 | r = "0x" + h[1] + h[1];
6 | g = "0x" + h[2] + h[2];
7 | b = "0x" + h[3] + h[3];
8 | a = "0x" + h[4] + h[4];
9 |
10 | } else if (h.length == 9) {
11 | r = "0x" + h[1] + h[2];
12 | g = "0x" + h[3] + h[4];
13 | b = "0x" + h[5] + h[6];
14 | a = "0x" + h[7] + h[8];
15 | }
16 | a = +(a / 255).toFixed(2);
17 |
18 | return "rgba(" + +r + "," + +g + "," + +b + "," + a + ")";
19 | }
20 |
21 | export default hexAToRGBA;
22 |
--------------------------------------------------------------------------------
/src/lib/tokenValue.js:
--------------------------------------------------------------------------------
1 | import hexAToRGBA from './hexAToRGBA'
2 |
3 |
4 | const tokenValue = (layer) => {
5 |
6 | let value = '';
7 |
8 | let layerType = layer.type;
9 |
10 | let layerNameArr = layer.name.split('/');
11 | let tokenType = layerNameArr[0];
12 | let tokenCategory = _.kebabCase(layerNameArr[1]);
13 |
14 |
15 | if(layerType === "ShapePath"){
16 |
17 | // ShapeLayers + Category match
18 |
19 | if(_.indexOf(['spacing','space','spacer','sizing','size'], tokenCategory) !== -1){
20 | // Get spacing
21 | value = _.round(layer.frame.height,0) + 'px';
22 | }else if(_.indexOf(['hr-color','background-color','text-color','color'], tokenCategory) !== -1){
23 |
24 | // Get color
25 | let color = _.last(layer.style.fills).color;
26 | value = color.slice(-2) === "ff" ? color.substr(0, 7) : hexAToRGBA(color);
27 |
28 | }else if(tokenCategory === 'border-color'){
29 | // Get border color
30 |
31 | if(_.size(layer.style.borders) !== 0){
32 | let border = _.last(layer.style.borders);
33 | value = border.color.substr(0, 7);
34 | }else{
35 | let fillArray = layer.style.fills;
36 | value = _.last(fillArray).color.substr(0, 7);
37 | }
38 |
39 | }else if(_.indexOf(['radius','border-radius'], tokenCategory) !== -1){
40 |
41 | // Get color
42 |
43 | let points = _.map(layer.points, 'cornerRadius');
44 |
45 | if(_.size(_.uniq(points)) === 1){
46 |
47 | if(layer.frame.width / 2 === points[1] || layer.frame.height / 2 === points[1]){
48 | value = '50%';
49 | }else{
50 | value = points[1] + 'px';
51 | }
52 |
53 | }else{
54 | value = _.join(points, 'px ') + 'px';
55 | }
56 |
57 |
58 | }else if(_.indexOf(['drop-shadow','box-shadow','text-shadow','shadow'], tokenCategory) !== -1){
59 |
60 | // Get shadow
61 | let shadowArr = _.last(layer.style.shadows);
62 | let x = shadowArr.x == 0 ? 0 : shadowArr.x + "px";
63 | let y = shadowArr.y == 0 ? 0 : shadowArr.y + "px";
64 | let blur = shadowArr.blur == 0 ? 0 : shadowArr.blur + "px";
65 | let spread = shadowArr.spread == 0 ? 0 : shadowArr.spread + "px";
66 | let color = shadowArr.color.slice(-2) === "ff" ? shadowArr.color.substr(0, 7) : hexAToRGBA(shadowArr.color);
67 |
68 | value = x + " " + y + " " + blur + " " + spread + " " + color;
69 |
70 | }else if(tokenCategory === 'inner-shadow'){
71 | // Get innershadow
72 | let shadowArr = _.last(layer.style.innerShadows);
73 | let x = shadowArr.x == 0 ? 0 : shadowArr.x + "px";
74 | let y = shadowArr.y == 0 ? 0 : shadowArr.y + "px";
75 | let blur = shadowArr.blur == 0 ? 0 : shadowArr.blur + "px";
76 | let spread = shadowArr.spread == 0 ? 0 : shadowArr.spread + "px";
77 | let color = shadowArr.color.slice(-2) === "ff" ? shadowArr.color.substr(0, 7) : hexAToRGBA(shadowArr.color);
78 |
79 |
80 | value = "inset " + x + " " + y + " " + blur + " " + spread + " " + color;
81 |
82 | }else if(_.indexOf(['background-gradient','gradient'], tokenCategory) !== -1){
83 |
84 | // Get gradient
85 | var gradient = layer.style.fills[0].gradient;
86 |
87 | if(gradient.gradientType === "Radial"){
88 | value = "radial-gradient(" + gradient.sketchObject.gradientStringWithMasterAlpha(1) + ")";
89 | }else if(gradient.gradientType === "Linear"){
90 | value = "linear-gradient(" + gradient.sketchObject.gradientStringWithMasterAlpha(1) + ")";
91 | }
92 |
93 |
94 | }else if(tokenCategory === 'border-style'){
95 | // Get border style
96 | let border = _.last(layer.style.borders);
97 | let borderColor = border.color.substr(0, 7);
98 | let borderThickness = border.thickness + "px";
99 |
100 | let borderStyle = _.isEmpty(layer.style.borderOptions.dashPattern) ? "solid" : "dashed";
101 |
102 | value = borderThickness + " " + borderStyle + " " + borderColor;
103 |
104 |
105 | }else if(['opacity'].indexOf(tokenCategory) !== -1){
106 |
107 | // Get opacity
108 | value = _.round(layer.style.opacity,2);
109 |
110 | }else if(tokenType === 'color'){
111 |
112 | // Token type color
113 | let color = _.last(layer.style.fills).color;
114 | let colorFormat = color.slice(-2) === "ff" ? color.substr(0, 7) : hexAToRGBA(color);
115 |
116 | value = colorFormat;
117 |
118 | }
119 |
120 | }else if(layerType === "Text"){
121 |
122 | // ShapeLayers + Category match
123 |
124 | if(tokenCategory === 'font-style'){
125 |
126 | value = layer.style.fontStyle;
127 |
128 | }else if(tokenCategory === 'font'){
129 |
130 |
131 | if(tokenType === "..."){
132 | value = layer.style.fontFamily;
133 | }else if(tokenType === "number"){
134 | value = layer.style.fontWeight * 100;
135 | }
136 |
137 |
138 | }else if(tokenCategory === 'font-weight'){
139 |
140 | value = layer.style.fontWeight * 100;
141 |
142 | }else if(tokenCategory === 'font-size'){
143 |
144 | value = layer.style.fontSize + 'px';
145 |
146 | }else if(tokenCategory === 'line-height'){
147 |
148 | value = _.round(layer.style.lineHeight / layer.style.fontSize, 2);
149 |
150 | }else if(tokenCategory === 'font-family'){
151 |
152 | value = layer.style.fontFamily;
153 |
154 | }else if(tokenCategory === 'text-color'){
155 |
156 | var color = layer.style.textColor;
157 | value = color.slice(-2) === "ff" ? color.substr(0, 7) : hexAToRGBA(color);
158 |
159 |
160 | }else if(tokenCategory === 'text-shadow'){
161 |
162 | let shadowArr = layer.style.shadows[0];
163 | let x = shadowArr.x == 0 ? 0 : shadowArr.x + "px";
164 | let y = shadowArr.y == 0 ? 0 : shadowArr.y + "px";
165 | let blur = shadowArr.blur == 0 ? 0 : shadowArr.blur + "px";
166 | let spread = shadowArr.spread == 0 ? 0 : shadowArr.spread + "px";
167 | let color = shadowArr.color.slice(-2) === "ff" ? shadowArr.color.substr(0, 7) : hexAToRGBA(shadowArr.color);
168 |
169 |
170 | value = x + " " + y + " " + blur + " " + spread + " " + color;
171 |
172 | }else if(_.indexOf(['z-index','time','media-query'], tokenCategory) !== -1){
173 |
174 | value = layer.text;
175 |
176 | }
177 |
178 | }
179 |
180 | return value;
181 | }
182 |
183 | export default tokenValue;
--------------------------------------------------------------------------------
/src/lib/values.js:
--------------------------------------------------------------------------------
1 | const values = {
2 | 'JavaScript Object': {
3 | lineStart: "",
4 | prefix: " '",
5 | diviner: "': '",
6 | postfix: "',\n",
7 | lineEnd: "}",
8 | filetype: "js",
9 | },
10 | 'JavaScript Variables': {
11 | lineStart: "",
12 | prefix: "const ",
13 | diviner: " = '",
14 | postfix: "';\n",
15 | lineEnd: "",
16 | filetype: "js"
17 | },
18 | 'SCSS': {
19 | lineStart: "",
20 | prefix: "$",
21 | diviner: ": ",
22 | postfix: ";\n",
23 | lineEnd: "",
24 | filetype: "scss"
25 | },
26 | 'Less': {
27 | lineStart: "",
28 | prefix: "@",
29 | diviner: ": ",
30 | postfix: ";\n",
31 | lineEnd: "",
32 | filetype: "less"
33 | },
34 | 'CSS': {
35 | lineStart: ":root {\n",
36 | prefix: " --",
37 | diviner: ": ",
38 | postfix: ";\n",
39 | lineEnd: "}",
40 | filetype: "css"
41 | },
42 | 'JSON': {
43 | lineStart: {},
44 | prefix: "",
45 | diviner: "",
46 | postfix: "",
47 | lineEnd: "",
48 | filetype: "json"
49 | },
50 | 'YAML': {
51 | lineStart: {},
52 | prefix: "",
53 | diviner: "",
54 | postfix: "",
55 | lineEnd: "",
56 | filetype: "yml"
57 | },
58 | }
59 |
60 | export default values;
--------------------------------------------------------------------------------
/src/lib/varNaming.js:
--------------------------------------------------------------------------------
1 | import _ from 'lodash';
2 |
3 | const varNaming = (layer, naming) => {
4 |
5 | let layerNameArr = layer.name.split('/');
6 | let layerName = '';
7 |
8 | if(naming == 0){
9 | layerName = _.kebabCase(layerNameArr);
10 | }else if(naming == 1){
11 | layerName = _.camelCase(_.join(layerNameArr, '-'));
12 | }else{
13 |
14 | let stringPosition = naming-2;
15 |
16 | if(layerNameArr.length < stringPosition+1){
17 | layerName = layerNameArr[0].toLowerCase().replace(/ /g, '');
18 | }else{
19 | layerName = layerNameArr[stringPosition].toLowerCase().replace(/ /g, '');
20 | }
21 | }
22 |
23 | return layerName;
24 |
25 | }
26 |
27 | export default varNaming;
28 |
--------------------------------------------------------------------------------
/src/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Design Token Exporter",
3 | "identifier": "fi.erhe.design-token-exporter",
4 | "description": "Simple Design Token Exporter",
5 | "homepage": "https://github.com/here-erhe/Design-Token-Exporter",
6 | "author": "Herkko Huttunen",
7 | "icon": "icon.png",
8 | "compatibleVersion": "54.0",
9 | "commands": [
10 | {
11 | "name": "Export Tokens",
12 | "identifier": "tokens.tokens",
13 | "script": "./exportTokens.js",
14 | "description": "Export multiple multiple layers or one artboard"
15 | },
16 | {
17 | "name": "Export Colors Variables",
18 | "identifier": "tokens.colors",
19 | "script": "./colorTokens.js",
20 | "description": "Export selected layers"
21 | },
22 | {
23 | "name": "Export Text Variables",
24 | "identifier": "tokens.text",
25 | "script": "./textTokens.js",
26 | "description": "Export selected layers"
27 | },
28 | {
29 | "name": "Export Spacing Variables",
30 | "identifier": "tokens.spacing",
31 | "script": "./spacingTokens.js",
32 | "description": "Export selected layers"
33 | },
34 | {
35 | "name": "Export Text Styles",
36 | "identifier": "tokens.styles",
37 | "script": "./textObjects.js",
38 | "description": "Export selected layers"
39 | }
40 | ],
41 | "menu": {
42 | "title": "Design Token Exporter",
43 | "items": [
44 | "tokens.tokens",
45 | "-",
46 | "tokens.colors",
47 | "tokens.text",
48 | "tokens.spacing",
49 | "-",
50 | "tokens.styles"
51 | ]
52 | }
53 | }
--------------------------------------------------------------------------------
/src/spacingTokens.js:
--------------------------------------------------------------------------------
1 | import sketch from 'sketch'
2 | import _ from 'lodash'
3 |
4 | import values from './lib/values'
5 | import formatObject from './lib/formatObject'
6 | import varNaming from './lib/varNaming'
7 |
8 | import {dialogAlert,fieldLabel, fieldSelect} from './lib/dialogFields'
9 |
10 | let dropdownFileType;
11 | let dropdownFormat;
12 | let dropdownNames;
13 | let dropdownUnits;
14 |
15 | /**
16 | *
17 | * Dialog
18 | *
19 | */
20 | const dialogBox = (selectedLayers) => {
21 |
22 | let alert = dialogAlert("Export Spacing Variables");
23 |
24 | // Creating the view
25 | let viewWidth = 300;
26 | let viewHeight = 225;
27 |
28 | let view = NSView.alloc().initWithFrame(NSMakeRect(0, 0, viewWidth, viewHeight));
29 | alert.addAccessoryView(view);
30 |
31 | //Dropdown: File format
32 |
33 | view.addSubview(fieldLabel(35, 'File format:', viewWidth, viewHeight));
34 |
35 | let names = ["SCSS","Less","CSS","JSON","JavaScript Object","JavaScript Variables"];
36 | dropdownFileType = fieldSelect(45, names, viewWidth, viewHeight)
37 |
38 | view.addSubview(dropdownFileType);
39 |
40 | //Dropdown: Dimension
41 |
42 | view.addSubview(fieldLabel(90, 'Dimension:', viewWidth, viewHeight));
43 |
44 | let types = [ "Width", "Height"];
45 | dropdownFormat = fieldSelect(100, types, viewWidth, viewHeight)
46 | view.addSubview(dropdownFormat);
47 |
48 | //Dropdown: Units
49 |
50 | view.addSubview(fieldLabel(145, 'Units:', viewWidth, viewHeight));
51 |
52 | let units = [ "Absolute (px)", "Relative (rem)"];
53 | dropdownUnits = fieldSelect(155, units, viewWidth, viewHeight)
54 | view.addSubview(dropdownUnits);
55 |
56 | //Dropdown: Naming
57 |
58 | view.addSubview(fieldLabel(200, 'Naming:', viewWidth, viewHeight));
59 |
60 | dropdownNames = fieldSelect(210, selectedLayers, viewWidth, viewHeight, true)
61 | view.addSubview(dropdownNames);
62 |
63 |
64 | return alert.runModal();
65 |
66 | }
67 |
68 | /**
69 | *
70 | * Export exportTextstyles
71 | *
72 | */
73 | const exportTextstyles = (selectedLayers, type, format, naming, units) => {
74 |
75 | const selectedCount = selectedLayers.length;
76 |
77 | let fileTypes = NSArray.arrayWithArray([values[type].filetype, nil]);
78 |
79 | let savePanel = NSSavePanel.savePanel()
80 | //savePanel.setCanChooseDirectories(true)
81 | //savePanel.setCanCreateDirectories(true)
82 | savePanel.setAllowedFileTypes(fileTypes)
83 |
84 | savePanel.setNameFieldStringValue('spacing.' + values[type].filetype)
85 | savePanel.setPrompt("Save Spacing Variables");
86 |
87 | if (savePanel.runModal() && selectedCount !== 0) {
88 |
89 | let variables = {}
90 |
91 | _.forEach(selectedLayers, function (layer) {
92 |
93 |
94 | let layerName = varNaming(layer, naming);
95 |
96 | let side = format == 'Width' ? layer.frame.width : layer.frame.height;
97 | let space = units == 'Absolute (px)' ? side + 'px' : side / 16 + 'rem';
98 |
99 | variables[layerName] = space;
100 |
101 |
102 | })
103 |
104 | let file = NSString.stringWithString(formatObject(variables, type, 'spacing'));
105 | let file_path = savePanel.URL().path();
106 | file.writeToFile_atomically_encoding_error(file_path, true, NSUTF8StringEncoding, null);
107 |
108 | sketch.UI.message('Spacing Variables Exported!');
109 |
110 | }
111 |
112 | }
113 |
114 | /**
115 | *
116 | * Main
117 | *
118 | */
119 | export default () => {
120 |
121 | const doc = sketch.getSelectedDocument();
122 | const selected = doc.selectedLayers.layers;
123 |
124 | // Only ShapePath layers - no text layers
125 | const selectedLayers = _.filter(_.reverse(selected), ['type', 'ShapePath']);
126 | const selectedCount = _.size(selectedLayers);
127 |
128 | if (selectedCount !== 0) {
129 |
130 | const dialog = dialogBox(selectedLayers);
131 | const exportType = dropdownFileType.titleOfSelectedItem();
132 | const exportFormat = dropdownFormat.titleOfSelectedItem();
133 | const exportNaming = dropdownNames.indexOfSelectedItem();
134 | const exportUnits = dropdownUnits.titleOfSelectedItem();
135 |
136 |
137 |
138 | if(dialog == "1000"){
139 | exportTextstyles(selectedLayers, exportType, exportFormat, exportNaming, exportUnits);
140 | }
141 |
142 | }else{
143 | sketch.UI.alert('Select layers','Please select shape layers first.');
144 | }
145 |
146 | }
--------------------------------------------------------------------------------
/src/textObjects.js:
--------------------------------------------------------------------------------
1 | import sketch from 'sketch'
2 | import _ from 'lodash'
3 |
4 | import values from './lib/values'
5 | import varNaming from './lib/varNaming'
6 |
7 | import {dialogAlert,fieldLabel, fieldSelect, fieldCheckbox} from './lib/dialogFields'
8 |
9 | let dropdownFileType;
10 | let dropdownUnits;
11 | let dropdownNames;
12 |
13 | let checkFontFamily;
14 | let checkFontSize;
15 | let checkFontWeight;
16 | let checkLineHeight;
17 | let checkLetterSpacing;
18 | let checkTextTransform;
19 | let checkColor;
20 |
21 |
22 | /**
23 | *
24 | * Dialog
25 | *
26 | */
27 | const dialogBox = (selectedLayers) => {
28 |
29 | let alert = dialogAlert("Export Text Styles");
30 |
31 | // Creating the view
32 | let viewWidth = 300;
33 | let viewHeight = 340;
34 |
35 | let view = NSView.alloc().initWithFrame(NSMakeRect(0, 0, viewWidth, viewHeight));
36 | alert.addAccessoryView(view);
37 |
38 | //Dropdown: File format
39 |
40 | view.addSubview(fieldLabel(35, 'File format:', viewWidth, viewHeight));
41 |
42 | let names = ["CSS","JSON","JavaScript Object"];
43 | dropdownFileType = fieldSelect(45, names, viewWidth, viewHeight)
44 |
45 | view.addSubview(dropdownFileType);
46 |
47 | //Dropdown: Select units
48 |
49 | view.addSubview(fieldLabel(90, 'Units:', viewWidth, viewHeight));
50 |
51 | let units = [ "Absolute (px)", "Relative (em/rem)"];
52 | dropdownUnits = fieldSelect(100, units, viewWidth, viewHeight)
53 | view.addSubview(dropdownUnits);
54 |
55 | //Dropdown: Naming
56 |
57 | view.addSubview(fieldLabel(145, 'Naming:', viewWidth, viewHeight));
58 |
59 | dropdownNames = fieldSelect(155, selectedLayers, viewWidth, viewHeight, true)
60 | view.addSubview(dropdownNames);
61 |
62 | //Checkbox: Select values
63 |
64 | view.addSubview(fieldLabel(200, 'Export selected values:', viewWidth, viewHeight));
65 |
66 | checkFontFamily = fieldCheckbox(210, 'Font Family', viewWidth, viewHeight)
67 | view.addSubview(checkFontFamily);
68 |
69 | checkFontSize = fieldCheckbox(230, 'Font Size', viewWidth, viewHeight, true)
70 | view.addSubview(checkFontSize);
71 |
72 | checkFontWeight = fieldCheckbox(250, 'Font Weight', viewWidth, viewHeight, true)
73 | view.addSubview(checkFontWeight);
74 |
75 | checkLineHeight = fieldCheckbox(270, 'Line Height', viewWidth, viewHeight, true)
76 | view.addSubview(checkLineHeight);
77 |
78 | checkLetterSpacing = fieldCheckbox(290, 'Letter Spacing', viewWidth, viewHeight, true)
79 | view.addSubview(checkLetterSpacing);
80 |
81 | checkTextTransform = fieldCheckbox(310, 'Text Transform', viewWidth, viewHeight, true)
82 | view.addSubview(checkTextTransform);
83 |
84 | checkColor = fieldCheckbox(330, 'Color', viewWidth, viewHeight)
85 | view.addSubview(checkColor);
86 |
87 |
88 |
89 | return alert.runModal();
90 |
91 | }
92 |
93 | /**
94 | *
95 | * Export exportTextstyles
96 | *
97 | */
98 | const exportTextstyles = (selectedLayers, type, units, naming) => {
99 |
100 |
101 | const selectedCount = selectedLayers.length;
102 |
103 | let fileTypes = NSArray.arrayWithArray([values[type].filetype, nil]);
104 |
105 | let savePanel = NSSavePanel.savePanel()
106 | //savePanel.setCanChooseDirectories(true)
107 | //savePanel.setCanCreateDirectories(true)
108 | savePanel.setAllowedFileTypes(fileTypes)
109 |
110 | savePanel.setNameFieldStringValue('textstyles.' + values[type].filetype)
111 | savePanel.setPrompt("Save Text Styles");
112 |
113 | if (savePanel.runModal() && selectedCount !== 0) {
114 |
115 |
116 | let texts = '';
117 |
118 | if(type == 'JSON'){
119 | texts = {}
120 | }else if(type == 'JavaScript Object'){
121 | texts = 'const textStyles = {\n';
122 | }else{
123 | texts = '';
124 | }
125 |
126 | _.forEach(selectedLayers, function (layer) {
127 |
128 |
129 | let layerName = varNaming(layer, naming);
130 |
131 | let fontFamily = layer.style.fontFamily;
132 | let fontSize = units == 'Absolute (px)' ? layer.style.fontSize + 'px' : layer.style.fontSize / 16 + 'rem';
133 | let fontWeight = layer.style.fontWeight * 100;
134 | let lineHeight = units == 'Absolute (px)' ? _.round(layer.style.lineHeight, 2) + 'px' : _.round(layer.style.lineHeight / layer.style.fontSize, 2);
135 | let letterSpacing = layer.style.kerning == null ? 'normal' : units == 'Absolute (px)' ? _.round(layer.style.kerning, 2) + 'px' : _.round(layer.style.kerning / layer.style.fontSize, 2) + 'em';
136 | let textTransform = layer.style.textTransform;
137 |
138 | let textColor = layer.style.textColor.substr(0, 7);
139 |
140 |
141 |
142 |
143 | // JSON
144 | if(type == 'JSON'){
145 |
146 | texts[layerName] = {};
147 |
148 | if(checkFontFamily.stringValue() == 1) texts[layerName]['fontFamily'] = fontFamily;
149 | if(checkFontSize.stringValue() == 1) texts[layerName]['fontSize'] = fontSize;
150 | if(checkFontWeight.stringValue() == 1) texts[layerName]['fontWeight'] = fontWeight;
151 | if(checkLineHeight.stringValue() == 1) texts[layerName]['lineHeight'] = lineHeight;
152 | if(checkLetterSpacing.stringValue() == 1) texts[layerName]['letterSpacing'] = letterSpacing;
153 | if(checkTextTransform.stringValue() == 1) texts[layerName]['textTransform'] = textTransform;
154 | if(checkColor.stringValue() == 1) texts[layerName]['color'] = textColor;
155 |
156 |
157 | }else if(type == 'JavaScript Object'){
158 | // JS Object
159 | texts = texts.concat('\t"' + layerName + '": {\n');
160 | if(checkFontFamily.stringValue() == 1) texts = texts.concat('\t\tfontFamily: "' + fontFamily +'",\n');
161 | if(checkFontSize.stringValue() == 1) texts = texts.concat('\t\tfontSize: "' + fontSize +'",\n');
162 | if(checkFontWeight.stringValue() == 1) texts = texts.concat('\t\tfontWeight: ' + fontWeight +',\n');
163 | if(checkLineHeight.stringValue() == 1) texts = texts.concat('\t\tlineHeight: "' + lineHeight + '",\n');
164 | if(checkLetterSpacing.stringValue() == 1) texts = texts.concat('\t\tletterSpacing: "' + letterSpacing + '",\n');
165 | if(checkTextTransform.stringValue() == 1) texts = texts.concat('\t\ttextTransform: "' + textTransform + '",\n');
166 | if(checkColor.stringValue() == 1) texts = texts.concat('\t\tcolor: "' + textColor + '",\n');
167 |
168 | texts = texts.concat( '\t},\n');
169 |
170 | }else if(type == 'CSS'){
171 | // CSS
172 | texts = texts.concat('.' + layerName + '{\n');
173 | if(checkFontFamily.stringValue() == 1) texts = texts.concat('\tfont-family: "' + fontFamily +'";\n');
174 | if(checkFontSize.stringValue() == 1) texts = texts.concat('\tfont-size: ' + fontSize +';\n');
175 | if(checkFontWeight.stringValue() == 1) texts = texts.concat('\tfont-weight: ' + fontWeight +';\n');
176 | if(checkLineHeight.stringValue() == 1) texts = texts.concat('\tline-height: ' + lineHeight + ';\n');
177 | if(checkLetterSpacing.stringValue() == 1) texts = texts.concat('\tletter-spacing: ' + letterSpacing + ';\n');
178 | if(checkTextTransform.stringValue() == 1) texts = texts.concat('\ttext-transform: ' + textTransform + ';\n');
179 | if(checkColor.stringValue() == 1) texts = texts.concat('\tcolor: ' + textColor + ';\n');
180 | texts = texts.concat( '}\n');
181 |
182 | }
183 |
184 | })
185 |
186 | let file = '';
187 |
188 | if(type == 'JSON'){
189 | let jsonObj = { "textstyles": texts };
190 | file = NSString.stringWithString(JSON.stringify(jsonObj, null, "\t"));
191 | }else if(type == 'JavaScript Object'){
192 | texts = texts.concat('}');
193 | file = NSString.stringWithString(texts);
194 | }else{
195 | file = NSString.stringWithString(texts);
196 | }
197 |
198 | let file_path = savePanel.URL().path();
199 | file.writeToFile_atomically_encoding_error(file_path, true, NSUTF8StringEncoding, null);
200 |
201 | sketch.UI.message('Text Styles Exported!');
202 | }
203 |
204 | }
205 |
206 | /**
207 | *
208 | * Main
209 | *
210 | */
211 | export default () => {
212 |
213 | const doc = sketch.getSelectedDocument();
214 | const selected = doc.selectedLayers.layers;
215 |
216 | // Only Text layers - no shape layers
217 | const selectedLayers = _.filter(_.reverse(selected), ['type', 'Text']);
218 | const selectedCount = _.size(selectedLayers);
219 |
220 | if (selectedCount !== 0) {
221 |
222 | const dialog = dialogBox(selectedLayers);
223 | const exportType = dropdownFileType.titleOfSelectedItem();
224 | const exportUnits = dropdownUnits.titleOfSelectedItem();
225 | const exportNaming = dropdownNames.indexOfSelectedItem();
226 |
227 |
228 | if(dialog == "1000"){
229 | exportTextstyles(selectedLayers, exportType, exportUnits, exportNaming);
230 | }
231 |
232 | }else{
233 | sketch.UI.alert('Select layers','Please select text layers first.');
234 | }
235 |
236 | }
--------------------------------------------------------------------------------
/src/textTokens.js:
--------------------------------------------------------------------------------
1 | import sketch from 'sketch'
2 | import _ from 'lodash'
3 |
4 | import values from './lib/values'
5 | import formatObject from './lib/formatObject'
6 | import varNaming from './lib/varNaming'
7 |
8 | let dropdownFileType;
9 | let dropdownFormat;
10 | let dropdownNames;
11 | let dropdownUnits;
12 |
13 | import {dialogAlert,fieldLabel, fieldSelect} from './lib/dialogFields'
14 |
15 |
16 | /**
17 | *
18 | * Dialog
19 | *
20 | */
21 | const dialogBox = (selectedLayers) => {
22 |
23 | let alert = dialogAlert("Export Text Variables");
24 |
25 | // Creating the view
26 | let viewWidth = 300;
27 | let viewHeight = 225;
28 |
29 | let view = NSView.alloc().initWithFrame(NSMakeRect(0, 0, viewWidth, viewHeight));
30 | alert.addAccessoryView(view);
31 |
32 | //Dropdown: File format
33 |
34 | view.addSubview(fieldLabel(35, 'File format:', viewWidth, viewHeight));
35 |
36 | let names = ["SCSS","Less","CSS","JSON","JavaScript Object","JavaScript Variables"];
37 | dropdownFileType = fieldSelect(45, names, viewWidth, viewHeight)
38 |
39 | view.addSubview(dropdownFileType);
40 |
41 | //Dropdown: Select text tokens
42 |
43 | view.addSubview(fieldLabel(90, 'Select values:', viewWidth, viewHeight));
44 |
45 | let types = [ "Font Size", "Font Weight", "Font Family", "Line Height", "Letter Spacing"];
46 | dropdownFormat = fieldSelect(100, types, viewWidth, viewHeight)
47 | view.addSubview(dropdownFormat);
48 |
49 | //Dropdown: Select units
50 |
51 | view.addSubview(fieldLabel(145, 'Units:', viewWidth, viewHeight));
52 |
53 | let units = [ "Absolute (px)", "Relative (em/rem)"];
54 | dropdownUnits = fieldSelect(155, units, viewWidth, viewHeight)
55 | view.addSubview(dropdownUnits);
56 |
57 | //Dropdown: Naming
58 |
59 | view.addSubview(fieldLabel(200, 'Naming:', viewWidth, viewHeight));
60 |
61 | dropdownNames = fieldSelect(210, selectedLayers, viewWidth, viewHeight, true)
62 | view.addSubview(dropdownNames);
63 |
64 |
65 | return alert.runModal();
66 |
67 | }
68 |
69 | /**
70 | *
71 | * Export exportTextstyles
72 | *
73 | */
74 | const exportTextstyles = (selectedLayers, type, format, naming, units) => {
75 |
76 | const selectedCount = selectedLayers.length;
77 |
78 | let fileTypes = NSArray.arrayWithArray([values[type].filetype, nil]);
79 |
80 | let savePanel = NSSavePanel.savePanel()
81 | //savePanel.setCanChooseDirectories(true)
82 | //savePanel.setCanCreateDirectories(true)
83 | savePanel.setAllowedFileTypes(fileTypes)
84 |
85 | savePanel.setNameFieldStringValue(_.camelCase(format) + '.' + values[type].filetype)
86 | savePanel.setPrompt("Save Text Tokens");
87 |
88 | if (savePanel.runModal() && selectedCount !== 0) {
89 |
90 | let variables = {}
91 |
92 | _.forEach(selectedLayers, function (layer) {
93 |
94 |
95 | let layerName = varNaming(layer, naming);
96 |
97 | let fontFamily = layer.style.fontFamily;
98 | let fontSize = units == 'Absolute (px)' ? layer.style.fontSize + 'px' : layer.style.fontSize / 16 + 'rem';
99 | let fontWeight = layer.style.fontWeight * 100;
100 | let lineHeight = units == 'Absolute (px)' ? _.round(layer.style.lineHeight, 2) + 'px' : _.round(layer.style.lineHeight / layer.style.fontSize, 2);
101 | let letterSpacing = layer.style.kerning == null ? 'normal' : units == 'Absolute (px)' ? _.round(layer.style.kerning, 2) + 'px' : _.round(layer.style.kerning / layer.style.fontSize, 2) + 'em';
102 |
103 | if(format == 'Font Family') variables[layerName] = fontFamily
104 | if(format == 'Font Size') variables[layerName] = fontSize
105 | if(format == 'Font Weight') variables[layerName] = fontWeight
106 | if(format == 'Line Height') variables[layerName] = lineHeight
107 | if(format == 'Letter Spacing') variables[layerName] = letterSpacing
108 |
109 | })
110 |
111 | let file = NSString.stringWithString(formatObject(variables, type, format));
112 | let file_path = savePanel.URL().path();
113 | file.writeToFile_atomically_encoding_error(file_path, true, NSUTF8StringEncoding, null);
114 |
115 | sketch.UI.message('Text Variables Exported!');
116 |
117 | }
118 |
119 | }
120 |
121 | /**
122 | *
123 | * Main
124 | *
125 | */
126 | export default () => {
127 |
128 | const doc = sketch.getSelectedDocument();
129 | const selected = doc.selectedLayers.layers;
130 |
131 | // Only Text layers - no shape layers
132 | const selectedLayers = _.filter(_.reverse(selected), ['type', 'Text']);
133 | const selectedCount = _.size(selectedLayers);
134 |
135 | if (selectedCount !== 0) {
136 |
137 | const dialog = dialogBox(selectedLayers);
138 | const exportType = dropdownFileType.titleOfSelectedItem();
139 | const exportFormat = dropdownFormat.titleOfSelectedItem();
140 | const exportNaming = dropdownNames.indexOfSelectedItem();
141 | const exportUnits = dropdownUnits.titleOfSelectedItem();
142 |
143 |
144 |
145 | if(dialog == "1000"){
146 | exportTextstyles(selectedLayers, exportType, exportFormat, exportNaming, exportUnits);
147 | }
148 |
149 | }else{
150 | sketch.UI.alert('Select layers','Please select text layers first.');
151 | }
152 |
153 | }
--------------------------------------------------------------------------------