@razorwind/storybook 0.0.71 → 0.0.72

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -71,26 +71,18 @@ import { ColorPaletteBlock } from "./blocks";
71
71
  ## Regenerate
72
72
 
73
73
  Re-run Razorwind generate when tokens change to refresh docs under \`${e.outputPath}/\`.
74
- `}const p=/* @__PURE__ */ new Set([`fontFamily`,`fontWeight`,`typography`]),m=/font|typography|type|text|line[-_.]?height|letter[-_.]?spacing/i;function h(e){return p.has(e.type??``)?!0:(e.type===`dimension`||e.type===`number`)&&m.test(e.path)}function g(e,t){return e.some(e=>t.some(t=>e.path===t||e.path.startsWith(`${t}.`)))}const _=/^\{([^{}]+)\}$/,v=/^var\((--[^),\s]+)(?:\s*,[^)]*)?\)$/;function y(e){if(typeof e==`string`)return _.exec(e.trim())?.[1]?.trim()}function b(e){if(typeof e==`string`)return v.exec(e.trim())?.[1]}function x(e){let t=new Map(e.map(e=>[e.path,e])),r=new Map(e.map(e=>[(0,n.toThemeCssVar)(e.path),e])),i=e=>{let n=e,i=/* @__PURE__ */ new Set;for(let a=0;a<8;a++){if(i.has(n.path))return e.cssValue;i.add(n.path);let a=t.get(y(n.value)??``)??r.get(b(n.value)??b(n.cssValue)??``);if(!a||a.path===n.path)return n.cssValue;n=a}return e.cssValue};return e.map(e=>e.type===`color`?{...e,cssValue:i(e)}:e)}function S(e){return Object.keys(e).length>1}function ee(){return`import { useGlobals, useMemo } from "storybook/preview-api";
75
-
76
- /**
77
- * Select a generated token variant. By default this follows Storybook's
78
- * \`theme\` global; callers may pass \`theme\` to override it.
74
+ `}const p=/* @__PURE__ */ new Set([`fontFamily`,`fontWeight`,`typography`]),m=/font|typography|type|text|line[-_.]?height|letter[-_.]?spacing/i;function h(e){return p.has(e.type??``)?!0:(e.type===`dimension`||e.type===`number`)&&m.test(e.path)}function g(e,t){return e.some(e=>t.some(t=>e.path===t||e.path.startsWith(`${t}.`)))}const _=/^\{([^{}]+)\}$/,v=/^var\((--[^),\s]+)(?:\s*,[^)]*)?\)$/;function y(e){if(typeof e==`string`)return _.exec(e.trim())?.[1]?.trim()}function b(e){if(typeof e==`string`)return v.exec(e.trim())?.[1]}function x(e){let t=new Map(e.map(e=>[e.path,e])),r=new Map(e.map(e=>[(0,n.toThemeCssVar)(e.path),e])),i=e=>{let n=e,i=/* @__PURE__ */ new Set;for(let a=0;a<8;a++){if(i.has(n.path))return e.cssValue;i.add(n.path);let a=t.get(y(n.value)??``)??r.get(b(n.value)??b(n.cssValue)??``);if(!a||a.path===n.path)return n.cssValue;n=a}return e.cssValue};return e.map(e=>e.type===`color`?{...e,cssValue:i(e)}:e)}function S(e){return Object.keys(e).length>1}function ee(){return`/**
75
+ * Select a generated token variant. Callers may pass \`theme\` to override
76
+ * the generated fallback without requiring Storybook preview-hook context.
79
77
  */
80
- export function useThemeVariant<T extends Record<string, unknown>>(
78
+ export function resolveThemeVariant<T extends Record<string, unknown>>(
81
79
  variants: T,
82
80
  fallback: keyof T & string,
83
81
  theme?: string
84
82
  ): keyof T & string {
85
- const [globals] = useGlobals();
86
-
87
- return useMemo(() => {
88
- const candidate = theme ?? globals.theme;
89
-
90
- return typeof candidate === "string" && candidate in variants
91
- ? (candidate as keyof T & string)
92
- : fallback;
93
- }, [fallback, globals.theme, theme, variants]);
83
+ return typeof theme === "string" && theme in variants
84
+ ? (theme as keyof T & string)
85
+ : fallback;
94
86
  }
95
87
  `}function C(e,t){let r=(0,n.resolveTokenSets)(e),i=r.filter(e=>!(0,n.isSharedThemeId)(e.id));return i.length<=1?{default:x(l(e,t))}:Object.fromEntries(i.map(e=>[e.id,x(l(B(r,e),t))]))}function w(e,t){let n=/* @__PURE__ */ new Map;for(let r of e){let e=r.path.split(`.`).slice(0,Math.max(t,1)).join(`.`)||r.path,i=n.get(e)??[];i.push(r),n.set(e,i)}return n}function T(e,t){return e===t?e.split(`.`).at(-1)??e:e.startsWith(`${t}.`)?e.slice(t.length+1):e.split(`.`).at(-1)??e}function E(e,t={}){let n=t.colorGroupBy??2,r=Object.entries(e),i=r[0]?.[0]??`default`,a=S(e),o=(e,t=` `)=>[...w(e,n).entries()].toSorted(([e],[t])=>e.localeCompare(t)).map(([e,n])=>{let r=n.map(n=>`${t} ${d(T(n.path,e))}: ${d(n.cssValue)}`).join(`,
96
88
  `),i=n.find(e=>e.description)?.description??`${n.length} token${n.length===1?``:`s`}`;return`${t}<ColorItem
@@ -108,7 +100,7 @@ ${o(t,` `)}
108
100
  </section>`).join(`
109
101
  `);return a?`<>\n${c}\n </>`:`<ColorPalette>\n${s||` {/* No color tokens */}`}\n </ColorPalette>`},c=r.map(([e,t])=>` ${d(e)}: (\n ${s(t)}\n )`).join(`,
110
102
  `);return`import { ColorPalette, ColorItem } from "@storybook/addon-docs/blocks";
111
- ${a?`import { useThemeVariant } from "./ThemeVariant";
103
+ ${a?`import { resolveThemeVariant } from "./ThemeVariant";
112
104
  `:``}
113
105
 
114
106
  /**
@@ -121,12 +113,12 @@ ${c}
121
113
  };
122
114
 
123
115
  export interface ColorPaletteBlockProps {
124
- /** Generated token-set name. Defaults to Storybook's \`theme\` global. */
116
+ /** Generated token-set name. Defaults to the first generated variant. */
125
117
  theme?: string;
126
118
  }
127
119
 
128
120
  export function ColorPaletteBlock({ theme }: ColorPaletteBlockProps = {}) {
129
- const activeTheme = ${a?`useThemeVariant(COLOR_VARIANTS, ${d(i)}, theme)`:d(i)};
121
+ const activeTheme = ${a?`resolveThemeVariant(COLOR_VARIANTS, ${d(i)}, theme)`:d(i)};
130
122
 
131
123
  return COLOR_VARIANTS[activeTheme];
132
124
  }
@@ -137,7 +129,7 @@ export function ColorPaletteBlock({ theme }: ColorPaletteBlockProps = {}) {
137
129
  sampleText={${d(r)}}
138
130
  />`},c=a.map(([e,t])=>` ${d(e)}: (${s(t)})`).join(`,
139
131
  `);return`import { Typeset } from "@storybook/addon-docs/blocks";
140
- ${i?`import { useThemeVariant } from "./ThemeVariant";
132
+ ${i?`import { resolveThemeVariant } from "./ThemeVariant";
141
133
  `:``}
142
134
 
143
135
  /**
@@ -150,12 +142,12 @@ ${c}
150
142
  };
151
143
 
152
144
  export interface TypesetBlockProps {
153
- /** Generated token-set name. Defaults to Storybook's \`theme\` global. */
145
+ /** Generated token-set name. Defaults to the first generated variant. */
154
146
  theme?: string;
155
147
  }
156
148
 
157
149
  export function TypesetBlock({ theme }: TypesetBlockProps = {}) {
158
- const activeTheme = ${i?`useThemeVariant(TYPESET_VARIANTS, ${d(o)}, theme)`:d(o)};
150
+ const activeTheme = ${i?`resolveThemeVariant(TYPESET_VARIANTS, ${d(o)}, theme)`:d(o)};
159
151
 
160
152
  return TYPESET_VARIANTS[activeTheme];
161
153
  }
@@ -172,7 +164,7 @@ export function TypesetBlock({ theme }: TypesetBlockProps = {}) {
172
164
  ${i(t)}
173
165
  ]`).join(`,
174
166
  `);return`import type { CSSProperties, ReactElement } from "react";
175
- ${t?`import { useThemeVariant } from "./ThemeVariant";
167
+ ${t?`import { resolveThemeVariant } from "./ThemeVariant";
176
168
  `:``}
177
169
 
178
170
  export interface TokenTableRow {
@@ -220,7 +212,7 @@ export interface TokenTableBlockProps {
220
212
  type?: string;
221
213
  /** Restrict rows to tokens used to define typography. */
222
214
  typography?: boolean;
223
- /** Generated token-set name. Defaults to Storybook's \`theme\` global. */
215
+ /** Generated token-set name. Defaults to the first generated variant. */
224
216
  theme?: string;
225
217
  }
226
218
 
@@ -233,7 +225,7 @@ export function TokenTableBlock({
233
225
  typography,
234
226
  theme
235
227
  }: TokenTableBlockProps = {}): ReactElement {
236
- const activeTheme = ${t?`useThemeVariant(TOKEN_VARIANTS, ${d(r)}, theme)`:d(r)};
228
+ const activeTheme = ${t?`resolveThemeVariant(TOKEN_VARIANTS, ${d(r)}, theme)`:d(r)};
237
229
  const rows = TOKEN_VARIANTS[activeTheme].filter(token => {
238
230
  const filters = typeof filter === "string" ? [filter] : filter;
239
231
  if (
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../src/types.ts","../src/flatten.ts","../src/install.ts","../src/generate.ts","../src/index.ts"],"mappings":";;;;;;;;;UAwBiB;;EAEf;;EAEA,OAAO;;EAEP;;EAEA;;EAEA;;EAEA;;EAEA;;EAEA;;EAEA;;;;;;;UAQe;;EAEf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;KAGU,wBAAwB,YAAY;KAEpC,uBACV,wBAAwB,eAAe;;;;;;KAO7B,0BACV,QAAQ,SAAS,eAAe,YAC7B;;;;UAKY;;;;;;EAMf;;;;;;EAOA;;;;;;EAOA;;;;;;EAOA;;;;;EAMA,eAAe;;;;;;EAOf;;;;;;;;;;;;;;EAeA,WAAW;;;;;;EAOX;;;;;EAMA;;;;;;;iBC3Dc,cACd,QAAQ,WAAS,eAAe,WAChC,UAAS,KAAK,2DACb;;;;;;;;iBC3Fa,gBAAgB;EAC9B;EACA;EACA;EACA;EACA;;;;;;;iBCi7Bc,mBACd,wBACA,OAAO,YAAY,yBACnB;EAAY;EAAgB;EAAmB;GAC/C,QAAQ,QACP;;;;;;;;;iBAkEa,gBACd,OAAO,iBAAiB,eAAe;;;;;;iBAwBzB,gBACd,iBACA,MAAM,KAAK,uCACX;EAAY;EAAgB;EAAmB;GAC/C,UAAU,YAAY,sCACrB,eAAe;;;;iBAwEF,kBACd,MAAM,QACN,UAAS,yBACR,wBAAwB,QAAQ"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/types.ts","../src/flatten.ts","../src/install.ts","../src/generate.ts","../src/index.ts"],"mappings":";;;;;;;;;UAwBiB;;EAEf;;EAEA,OAAO;;EAEP;;EAEA;;EAEA;;EAEA;;EAEA;;EAEA;;EAEA;;;;;;;UAQe;;EAEf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;KAGU,wBAAwB,YAAY;KAEpC,uBACV,wBAAwB,eAAe;;;;;;KAO7B,0BACV,QAAQ,SAAS,eAAe,YAC7B;;;;UAKY;;;;;;EAMf;;;;;;EAOA;;;;;;EAOA;;;;;;EAOA;;;;;EAMA,eAAe;;;;;;EAOf;;;;;;;;;;;;;;EAeA,WAAW;;;;;;EAOX;;;;;EAMA;;;;;;;iBC3Dc,cACd,QAAQ,WAAS,eAAe,WAChC,UAAS,KAAK,2DACb;;;;;;;;iBC3Fa,gBAAgB;EAC9B;EACA;EACA;EACA;EACA;;;;;;;iBCy6Bc,mBACd,wBACA,OAAO,YAAY,yBACnB;EAAY;EAAgB;EAAmB;GAC/C,QAAQ,QACP;;;;;;;;;iBAkEa,gBACd,OAAO,iBAAiB,eAAe;;;;;;iBAwBzB,gBACd,iBACA,MAAM,KAAK,uCACX;EAAY;EAAgB;EAAmB;GAC/C,UAAU,YAAY,sCACrB,eAAe;;;;iBAwEF,kBACd,MAAM,QACN,UAAS,yBACR,wBAAwB,QAAQ"}
package/dist/index.mjs CHANGED
@@ -71,26 +71,18 @@ import { ColorPaletteBlock } from "./blocks";
71
71
  ## Regenerate
72
72
 
73
73
  Re-run Razorwind generate when tokens change to refresh docs under \`${e.outputPath}/\`.
74
- `}const E=/* @__PURE__ */ new Set([`fontFamily`,`fontWeight`,`typography`]),ne=/font|typography|type|text|line[-_.]?height|letter[-_.]?spacing/i;function D(e){return E.has(e.type??``)?!0:(e.type===`dimension`||e.type===`number`)&&ne.test(e.path)}function O(e,t){return e.some(e=>t.some(t=>e.path===t||e.path.startsWith(`${t}.`)))}const re=/^\{([^{}]+)\}$/,ie=/^var\((--[^),\s]+)(?:\s*,[^)]*)?\)$/;function k(e){if(typeof e==`string`)return re.exec(e.trim())?.[1]?.trim()}function A(e){if(typeof e==`string`)return ie.exec(e.trim())?.[1]}function j(e){let t=new Map(e.map(e=>[e.path,e])),n=new Map(e.map(e=>[g(e.path),e])),r=e=>{let r=e,i=/* @__PURE__ */ new Set;for(let a=0;a<8;a++){if(i.has(r.path))return e.cssValue;i.add(r.path);let a=t.get(k(r.value)??``)??n.get(A(r.value)??A(r.cssValue)??``);if(!a||a.path===r.path)return r.cssValue;r=a}return e.cssValue};return e.map(e=>e.type===`color`?{...e,cssValue:r(e)}:e)}function M(e){return Object.keys(e).length>1}function ae(){return`import { useGlobals, useMemo } from "storybook/preview-api";
75
-
76
- /**
77
- * Select a generated token variant. By default this follows Storybook's
78
- * \`theme\` global; callers may pass \`theme\` to override it.
74
+ `}const E=/* @__PURE__ */ new Set([`fontFamily`,`fontWeight`,`typography`]),ne=/font|typography|type|text|line[-_.]?height|letter[-_.]?spacing/i;function D(e){return E.has(e.type??``)?!0:(e.type===`dimension`||e.type===`number`)&&ne.test(e.path)}function O(e,t){return e.some(e=>t.some(t=>e.path===t||e.path.startsWith(`${t}.`)))}const re=/^\{([^{}]+)\}$/,ie=/^var\((--[^),\s]+)(?:\s*,[^)]*)?\)$/;function k(e){if(typeof e==`string`)return re.exec(e.trim())?.[1]?.trim()}function A(e){if(typeof e==`string`)return ie.exec(e.trim())?.[1]}function j(e){let t=new Map(e.map(e=>[e.path,e])),n=new Map(e.map(e=>[g(e.path),e])),r=e=>{let r=e,i=/* @__PURE__ */ new Set;for(let a=0;a<8;a++){if(i.has(r.path))return e.cssValue;i.add(r.path);let a=t.get(k(r.value)??``)??n.get(A(r.value)??A(r.cssValue)??``);if(!a||a.path===r.path)return r.cssValue;r=a}return e.cssValue};return e.map(e=>e.type===`color`?{...e,cssValue:r(e)}:e)}function M(e){return Object.keys(e).length>1}function ae(){return`/**
75
+ * Select a generated token variant. Callers may pass \`theme\` to override
76
+ * the generated fallback without requiring Storybook preview-hook context.
79
77
  */
80
- export function useThemeVariant<T extends Record<string, unknown>>(
78
+ export function resolveThemeVariant<T extends Record<string, unknown>>(
81
79
  variants: T,
82
80
  fallback: keyof T & string,
83
81
  theme?: string
84
82
  ): keyof T & string {
85
- const [globals] = useGlobals();
86
-
87
- return useMemo(() => {
88
- const candidate = theme ?? globals.theme;
89
-
90
- return typeof candidate === "string" && candidate in variants
91
- ? (candidate as keyof T & string)
92
- : fallback;
93
- }, [fallback, globals.theme, theme, variants]);
83
+ return typeof theme === "string" && theme in variants
84
+ ? (theme as keyof T & string)
85
+ : fallback;
94
86
  }
95
87
  `}function oe(e,t){let n=p(e),r=n.filter(e=>!u(e.id));return r.length<=1?{default:j(S(e,t))}:Object.fromEntries(r.map(e=>[e.id,j(S(K(n,e),t))]))}function se(e,t){let n=/* @__PURE__ */ new Map;for(let r of e){let e=r.path.split(`.`).slice(0,Math.max(t,1)).join(`.`)||r.path,i=n.get(e)??[];i.push(r),n.set(e,i)}return n}function ce(e,t){return e===t?e.split(`.`).at(-1)??e:e.startsWith(`${t}.`)?e.slice(t.length+1):e.split(`.`).at(-1)??e}function le(e,t={}){let n=t.colorGroupBy??2,r=Object.entries(e),i=r[0]?.[0]??`default`,a=M(e),o=(e,t=` `)=>[...se(e,n).entries()].toSorted(([e],[t])=>e.localeCompare(t)).map(([e,n])=>{let r=n.map(n=>`${t} ${w(ce(n.path,e))}: ${w(n.cssValue)}`).join(`,
96
88
  `),i=n.find(e=>e.description)?.description??`${n.length} token${n.length===1?``:`s`}`;return`${t}<ColorItem
@@ -108,7 +100,7 @@ ${o(t,` `)}
108
100
  </section>`).join(`
109
101
  `);return a?`<>\n${c}\n </>`:`<ColorPalette>\n${s||` {/* No color tokens */}`}\n </ColorPalette>`},c=r.map(([e,t])=>` ${w(e)}: (\n ${s(t)}\n )`).join(`,
110
102
  `);return`import { ColorPalette, ColorItem } from "@storybook/addon-docs/blocks";
111
- ${a?`import { useThemeVariant } from "./ThemeVariant";
103
+ ${a?`import { resolveThemeVariant } from "./ThemeVariant";
112
104
  `:``}
113
105
 
114
106
  /**
@@ -121,12 +113,12 @@ ${c}
121
113
  };
122
114
 
123
115
  export interface ColorPaletteBlockProps {
124
- /** Generated token-set name. Defaults to Storybook's \`theme\` global. */
116
+ /** Generated token-set name. Defaults to the first generated variant. */
125
117
  theme?: string;
126
118
  }
127
119
 
128
120
  export function ColorPaletteBlock({ theme }: ColorPaletteBlockProps = {}) {
129
- const activeTheme = ${a?`useThemeVariant(COLOR_VARIANTS, ${w(i)}, theme)`:w(i)};
121
+ const activeTheme = ${a?`resolveThemeVariant(COLOR_VARIANTS, ${w(i)}, theme)`:w(i)};
130
122
 
131
123
  return COLOR_VARIANTS[activeTheme];
132
124
  }
@@ -137,7 +129,7 @@ export function ColorPaletteBlock({ theme }: ColorPaletteBlockProps = {}) {
137
129
  sampleText={${w(a)}}
138
130
  />`},u=s.map(([e,t])=>` ${w(e)}: (${l(t)})`).join(`,
139
131
  `);return`import { Typeset } from "@storybook/addon-docs/blocks";
140
- ${o?`import { useThemeVariant } from "./ThemeVariant";
132
+ ${o?`import { resolveThemeVariant } from "./ThemeVariant";
141
133
  `:``}
142
134
 
143
135
  /**
@@ -150,12 +142,12 @@ ${u}
150
142
  };
151
143
 
152
144
  export interface TypesetBlockProps {
153
- /** Generated token-set name. Defaults to Storybook's \`theme\` global. */
145
+ /** Generated token-set name. Defaults to the first generated variant. */
154
146
  theme?: string;
155
147
  }
156
148
 
157
149
  export function TypesetBlock({ theme }: TypesetBlockProps = {}) {
158
- const activeTheme = ${o?`useThemeVariant(TYPESET_VARIANTS, ${w(c)}, theme)`:w(c)};
150
+ const activeTheme = ${o?`resolveThemeVariant(TYPESET_VARIANTS, ${w(c)}, theme)`:w(c)};
159
151
 
160
152
  return TYPESET_VARIANTS[activeTheme];
161
153
  }
@@ -172,7 +164,7 @@ export function TypesetBlock({ theme }: TypesetBlockProps = {}) {
172
164
  ${i(t)}
173
165
  ]`).join(`,
174
166
  `);return`import type { CSSProperties, ReactElement } from "react";
175
- ${t?`import { useThemeVariant } from "./ThemeVariant";
167
+ ${t?`import { resolveThemeVariant } from "./ThemeVariant";
176
168
  `:``}
177
169
 
178
170
  export interface TokenTableRow {
@@ -220,7 +212,7 @@ export interface TokenTableBlockProps {
220
212
  type?: string;
221
213
  /** Restrict rows to tokens used to define typography. */
222
214
  typography?: boolean;
223
- /** Generated token-set name. Defaults to Storybook's \`theme\` global. */
215
+ /** Generated token-set name. Defaults to the first generated variant. */
224
216
  theme?: string;
225
217
  }
226
218
 
@@ -233,7 +225,7 @@ export function TokenTableBlock({
233
225
  typography,
234
226
  theme
235
227
  }: TokenTableBlockProps = {}): ReactElement {
236
- const activeTheme = ${t?`useThemeVariant(TOKEN_VARIANTS, ${w(r)}, theme)`:w(r)};
228
+ const activeTheme = ${t?`resolveThemeVariant(TOKEN_VARIANTS, ${w(r)}, theme)`:w(r)};
237
229
  const rows = TOKEN_VARIANTS[activeTheme].filter(token => {
238
230
  const filters = typeof filter === "string" ? [filter] : filter;
239
231
  if (
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@razorwind/storybook",
3
- "version": "0.0.71",
3
+ "version": "0.0.72",
4
4
  "type": "module",
5
5
  "description": "Razorwind plugin that creates Storybook MDX token doc blocks from Razorwind design tokens.",
6
6
  "repository": {
@@ -85,7 +85,7 @@
85
85
  "dependencies": {
86
86
  "@power-plant/core": "^0.0.93",
87
87
  "@power-plant/dtcg-schema": "^0.0.1",
88
- "@razorwind/core": "^0.0.73",
88
+ "@razorwind/core": "^0.0.74",
89
89
  "@stryke/path": "^0.29.42",
90
90
  "@stryke/type-checks": "^0.6.48"
91
91
  },
@@ -102,9 +102,9 @@
102
102
  "devDependencies": {
103
103
  "@powerlines/plugin-tsdown": "^0.1.614",
104
104
  "@stryke/types": "^0.12.43",
105
- "@types/node": "^25.9.7",
105
+ "@types/node": "^25.9.8",
106
106
  "typescript": "^6.0.3"
107
107
  },
108
108
  "publishConfig": { "access": "public" },
109
- "gitHead": "65650c7f21668e9942ca662de1a5ac72beed01e1"
109
+ "gitHead": "b974ce9d1f860a656d4af34b1c1f2ff82d80f4f6"
110
110
  }