{"version":3,"file":"styled-components.cjs.js","sources":["../src/models/BrowserStyleSheet.js","../src/models/StyleSheet.js","../src/models/ServerStyleSheet.js","../src/models/ThemeProvider.js","../src/models/StyledComponent.js","../src/models/ComponentStyle.js","../src/constructors/styled.js","../src/constructors/keyframes.js"],"sourcesContent":["// @flow\n/* eslint-disable no-underscore-dangle */\n/*\n * Browser Style Sheet with Rehydration\n *\n * \n *\n * Note: replace · with * in the above snippet.\n * */\nimport extractCompsFromCSS from '../utils/extractCompsFromCSS'\nimport stringifyRules from '../utils/stringifyRules'\nimport getNonce from '../utils/nonce'\nimport type { Tag } from './StyleSheet'\nimport StyleSheet, { SC_ATTR, LOCAL_ATTR } from './StyleSheet'\n\ndeclare var __DEV__: ?string\n\nconst DISABLE_SPEEDY =\n (typeof __DEV__ === 'boolean' && __DEV__) ||\n process.env.NODE_ENV !== 'production'\n\nconst COMPONENTS_PER_TAG = 40\nconst SPEEDY_COMPONENTS_PER_TAG = 1000 // insertRule allows more injections before a perf slowdown\n\n// Source: https://github.com/threepointone/glamor/blob/master/src/sheet.js#L32-L43\nconst sheetForTag = (tag: HTMLStyleElement): CSSStyleSheet => {\n if (tag.sheet) {\n // $FlowFixMe\n return tag.sheet\n }\n\n for (let i = 0; i < document.styleSheets.length; i += 1) {\n if (document.styleSheets[i].ownerNode === tag) {\n // $FlowFixMe\n return document.styleSheets[i]\n }\n }\n\n // NOTE: This should never happen\n throw new Error('')\n}\n\n// Safely (try/catch) injects rule at index and returns whether it was successful\nconst safeInsertRule = (\n sheet: CSSStyleSheet,\n cssRule: string,\n index: number\n): boolean => {\n if (cssRule === undefined || cssRule.length === 0) {\n return false\n }\n\n const maxIndex = sheet.cssRules.length\n const cappedIndex = index <= maxIndex ? index : maxIndex\n\n try {\n sheet.insertRule(cssRule, cappedIndex)\n } catch (err) {\n // NOTE: An invalid rule here means it's not supported by the browser or obviously malformed\n return false\n }\n\n return true\n}\n\n// Counts up the number of rules inside the array until a specific component entry is found\n// This is used to determine the necessary insertRule index\nconst sizeUpToComponentIndex = (\n componentSizes: Array,\n componentIndex: number\n) => {\n let cssRulesSize = 0\n for (let i = 0; i <= componentIndex; i += 1) {\n cssRulesSize += componentSizes[i]\n }\n\n return cssRulesSize\n}\n\nclass BaseBrowserTag {\n components: { [string]: Object }\n\n toReactElement() {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? \"BrowserTag doesn't implement toReactElement!\"\n : ''\n )\n }\n\n clone() {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? 'BrowserTag cannot be cloned!'\n : ''\n )\n }\n\n getComponentIds() {\n return Object.keys(this.components)\n }\n}\n\nlet BrowserTag\nif (!DISABLE_SPEEDY) {\n BrowserTag = class SpeedyBrowserTag extends BaseBrowserTag implements Tag {\n // Store component ruleSizes in an array per component (in order)\n componentSizes: Array\n components: { [string]: Object }\n\n isLocal: boolean\n size: number\n el: HTMLStyleElement\n ready: boolean\n\n constructor(\n el: HTMLStyleElement,\n isLocal: boolean,\n existingSource: ?string\n ) {\n super()\n\n const nonce = getNonce()\n if (nonce) {\n el.setAttribute('nonce', nonce)\n }\n\n const extractedComps = extractCompsFromCSS(existingSource)\n\n this.el = el\n this.isLocal = isLocal\n this.ready = false\n this.componentSizes = []\n this.size = extractedComps.length\n this.components = extractedComps.reduce((acc, obj) => {\n acc[obj.componentId] = obj // eslint-disable-line no-param-reassign\n return acc\n }, {})\n }\n\n /* Because we care about source order, before we can inject anything we need to\n * create a text node for each component and replace the existing CSS. */\n replaceElement() {\n // Build up our replacement style tag\n const newEl = this.el.cloneNode(false)\n\n if (!this.el.parentNode) {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? \"Trying to replace an element that wasn't mounted!\"\n : ''\n )\n }\n\n // workaround for an IE/Edge bug: https://twitter.com/probablyup/status/958138927981977600\n newEl.appendChild(document.createTextNode(''))\n\n // $FlowFixMe\n this.el.parentNode.replaceChild(newEl, this.el)\n this.el = newEl\n this.ready = true\n\n // Retrieve the sheet for the new style tag\n const sheet = sheetForTag(newEl)\n\n Object.keys(this.components).forEach(componentId => {\n const comp = this.components[componentId]\n const { cssFromDOM } = comp\n const rules = stringifyRules([cssFromDOM])\n const rulesSize = rules.length\n\n let injectedRules = 0\n for (let j = 0; j < rulesSize; j += 1) {\n if (safeInsertRule(sheet, rules[j], sheet.cssRules.length)) {\n injectedRules += 1\n }\n }\n\n comp.componentIndex = this.componentSizes.length\n comp.css = rules.join(' ')\n this.componentSizes.push(injectedRules)\n })\n }\n\n isSealed() {\n return this.size >= SPEEDY_COMPONENTS_PER_TAG\n }\n\n addComponent(componentId: string) {\n if (!this.ready) this.replaceElement()\n\n if (\n process.env.NODE_ENV !== 'production' &&\n this.components[componentId]\n ) {\n throw new Error(`Trying to add Component '${componentId}' twice!`)\n }\n\n this.components[componentId] = {\n componentIndex: this.componentSizes.length,\n css: '',\n }\n\n this.componentSizes.push(0)\n this.size += 1\n }\n\n inject(componentId: string, cssRules: Array, name: ?string) {\n if (!this.ready) this.replaceElement()\n\n const comp = this.components[componentId]\n if (process.env.NODE_ENV !== 'production' && !comp) {\n throw new Error(\n 'Must add a new component before you can inject css into it'\n )\n }\n\n const cssRulesSize = cssRules.length\n const sheet = sheetForTag(this.el)\n const { componentIndex } = comp\n\n // Determine start index for injection\n const insertIndex = sizeUpToComponentIndex(\n this.componentSizes,\n componentIndex\n )\n\n // Inject each rule shifting index forward for each one (in-order injection)\n let injectedRules = 0\n for (let i = 0; i < cssRulesSize; i += 1) {\n const cssRule = cssRules[i]\n if (safeInsertRule(sheet, cssRule, insertIndex + injectedRules)) {\n comp.css += ` ${cssRule}`\n injectedRules += 1\n }\n }\n\n // Update number of rules for component\n this.componentSizes[componentIndex] += injectedRules\n\n if (name !== undefined && name !== null) {\n const existingNames = this.el.getAttribute(SC_ATTR)\n this.el.setAttribute(\n SC_ATTR,\n existingNames ? `${existingNames} ${name}` : name\n )\n }\n }\n\n toRawCSS() {\n return '' // NOTE: Unsupported in production mode (SpeedyBrowserTag)\n }\n\n toHTML() {\n return '' // NOTE: Unsupported in production mode (SpeedyBrowserTag)\n }\n }\n} else {\n BrowserTag = class TextNodeBrowserTag extends BaseBrowserTag implements Tag {\n isLocal: boolean\n components: { [string]: Object }\n size: number\n el: HTMLStyleElement\n ready: boolean\n\n constructor(\n el: HTMLStyleElement,\n isLocal: boolean,\n existingSource: string = ''\n ) {\n super()\n\n const nonce = getNonce()\n if (nonce !== null) {\n el.setAttribute('nonce', nonce)\n }\n\n const extractedComps = extractCompsFromCSS(existingSource)\n\n this.el = el\n this.isLocal = isLocal\n this.ready = false\n this.size = extractedComps.length\n this.components = extractedComps.reduce((acc, obj) => {\n acc[obj.componentId] = obj // eslint-disable-line no-param-reassign\n return acc\n }, {})\n }\n\n isSealed() {\n return this.size >= COMPONENTS_PER_TAG\n }\n\n addComponent(componentId: string) {\n if (!this.ready) this.replaceElement()\n if (\n process.env.NODE_ENV !== 'production' &&\n this.components[componentId]\n ) {\n throw new Error(`Trying to add Component '${componentId}' twice!`)\n }\n\n const comp = { componentId, textNode: document.createTextNode('') }\n this.el.appendChild(comp.textNode)\n this.size += 1\n this.components[componentId] = comp\n }\n\n inject(componentId: string, css: Array, name: ?string) {\n if (!this.ready) this.replaceElement()\n const comp = this.components[componentId]\n\n if (process.env.NODE_ENV !== 'production' && !comp) {\n throw new Error(\n 'Must add a new component before you can inject css into it'\n )\n }\n\n if (comp.textNode.data === '') {\n comp.textNode.appendData(`\\n/* sc-component-id: ${componentId} */\\n`)\n }\n\n comp.textNode.appendData(css.join(' '))\n\n if (name !== undefined && name !== null) {\n const existingNames = this.el.getAttribute(SC_ATTR)\n this.el.setAttribute(\n SC_ATTR,\n existingNames ? `${existingNames} ${name}` : name\n )\n }\n }\n\n toHTML() {\n return this.el.outerHTML\n }\n\n toReactElement() {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? \"BrowserTag doesn't implement toReactElement!\"\n : ''\n )\n }\n\n clone() {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? 'BrowserTag cannot be cloned!'\n : ''\n )\n }\n\n /* Because we care about source order, before we can inject anything we need to\n * create a text node for each component and replace the existing CSS. */\n replaceElement() {\n this.ready = true\n // We have nothing to inject. Use the current el.\n if (this.size === 0) return\n\n // Build up our replacement style tag\n const newEl = this.el.cloneNode(false)\n newEl.appendChild(document.createTextNode('\\n'))\n\n Object.keys(this.components).forEach(key => {\n const comp = this.components[key]\n\n // eslint-disable-next-line no-param-reassign\n comp.textNode = document.createTextNode(comp.cssFromDOM)\n newEl.appendChild(comp.textNode)\n })\n\n if (!this.el.parentNode) {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? \"Trying to replace an element that wasn't mounted!\"\n : ''\n )\n }\n\n // The ol' switcheroo\n this.el.parentNode.replaceChild(newEl, this.el)\n this.el = newEl\n }\n }\n}\n\n/* Factory function to separate DOM operations from logical ones*/\nexport default {\n create() {\n const tags = []\n const names = {}\n\n /* Construct existing state from DOM */\n const nodes = document.querySelectorAll(`[${SC_ATTR}]`)\n const nodesLength = nodes.length\n\n for (let i = 0; i < nodesLength; i += 1) {\n // $FlowFixMe: We can trust that all elements in this query are style elements\n const el = (nodes[i]: HTMLStyleElement)\n const attr = el.getAttribute(SC_ATTR)\n\n if (attr) {\n attr\n .trim()\n .split(/\\s+/)\n .forEach(name => {\n names[name] = true\n })\n }\n\n tags.push(\n new BrowserTag(\n el,\n el.getAttribute(LOCAL_ATTR) === 'true',\n el.textContent\n )\n )\n }\n\n /* Factory for making more tags */\n const tagConstructor = (isLocal: boolean): Tag => {\n const el = document.createElement('style')\n el.type = 'text/css'\n el.setAttribute(SC_ATTR, '')\n el.setAttribute(LOCAL_ATTR, isLocal ? 'true' : 'false')\n if (!document.head) {\n throw new Error(\n process.env.NODE_ENV !== 'production' ? 'Missing document ' : ''\n )\n }\n document.head.appendChild(el)\n return new BrowserTag(el, isLocal)\n }\n\n return new StyleSheet(tagConstructor, tags, names)\n },\n}\n","// @flow\nimport React from 'react'\nimport BrowserStyleSheet from './BrowserStyleSheet'\nimport ServerStyleSheet from './ServerStyleSheet'\n\nexport const SC_ATTR = 'data-styled-components'\nexport const LOCAL_ATTR = 'data-styled-components-is-local'\nexport const CONTEXT_KEY = '__styled-components-stylesheet__'\n\n/* eslint-disable flowtype/object-type-delimiter */\nexport interface Tag {\n isLocal: boolean;\n\n isSealed(): boolean;\n getComponentIds(): Array;\n addComponent(componentId: string): void;\n inject(componentId: string, css: Array, name: ?string): void;\n toHTML(): string;\n toReactElement(key: string): React.Element<*>;\n clone(): Tag;\n}\n/* eslint-enable flowtype/object-type-delimiter */\n\nlet instance = null\n// eslint-disable-next-line no-use-before-define\nexport const clones: Array = []\n\nconst IS_BROWSER = typeof document !== 'undefined'\n\nexport default class StyleSheet {\n tagConstructor: boolean => Tag\n tags: Array\n names: { [string]: boolean }\n hashes: { [string]: string } = {}\n deferredInjections: { [string]: Array } = {}\n componentTags: { [string]: Tag }\n\n // helper for `ComponentStyle` to know when it cache static styles.\n // staticly styled-component can not safely cache styles on the server\n // without all `ComponentStyle` instances saving a reference to the\n // the styleSheet instance they last rendered with,\n // or listening to creation / reset events. otherwise you might create\n // a component with one stylesheet and render it another api response\n // with another, losing styles on from your server-side render.\n stylesCacheable = IS_BROWSER\n\n constructor(\n tagConstructor: boolean => Tag,\n tags: Array = [],\n names: { [string]: boolean } = {}\n ) {\n this.tagConstructor = tagConstructor\n this.tags = tags\n this.names = names\n this.constructComponentTagMap()\n }\n\n constructComponentTagMap() {\n this.componentTags = {}\n\n this.tags.forEach(tag => {\n tag.getComponentIds().forEach(componentId => {\n this.componentTags[componentId] = tag\n })\n })\n }\n\n /* Best level of caching—get the name from the hash straight away. */\n getName(hash: any) {\n return this.hashes[hash.toString()]\n }\n\n /* Second level of caching—if the name is already in the dom, don't\n * inject anything and record the hash for getName next time. */\n alreadyInjected(hash: any, name: string) {\n if (!this.names[name]) return false\n\n this.hashes[hash.toString()] = name\n return true\n }\n\n /* Third type of caching—don't inject components' componentId twice. */\n hasInjectedComponent(componentId: string) {\n return !!this.componentTags[componentId]\n }\n\n deferredInject(componentId: string, isLocal: boolean, css: Array) {\n if (this === instance) {\n clones.forEach(clone => {\n clone.deferredInject(componentId, isLocal, css)\n })\n }\n\n this.getOrCreateTag(componentId, isLocal)\n this.deferredInjections[componentId] = css\n }\n\n inject(\n componentId: string,\n isLocal: boolean,\n css: Array,\n hash: ?any,\n name: ?string\n ) {\n if (this === instance) {\n clones.forEach(clone => {\n clone.inject(componentId, isLocal, css)\n })\n }\n\n const tag = this.getOrCreateTag(componentId, isLocal)\n\n const deferredInjection = this.deferredInjections[componentId]\n if (deferredInjection) {\n tag.inject(componentId, deferredInjection)\n delete this.deferredInjections[componentId]\n }\n\n tag.inject(componentId, css, name)\n\n if (hash && name) {\n this.hashes[hash.toString()] = name\n }\n }\n\n toHTML() {\n return this.tags.map(tag => tag.toHTML()).join('')\n }\n\n toReactElements() {\n return this.tags.map((tag, i) => tag.toReactElement(`sc-${i}`))\n }\n\n getOrCreateTag(componentId: string, isLocal: boolean) {\n const existingTag = this.componentTags[componentId]\n\n /**\n * in a streaming context, once a tag is sealed it can never be added to again\n * or those styles will never make it to the client\n */\n if (existingTag && !existingTag.isSealed()) {\n return existingTag\n }\n\n const lastTag = this.tags[this.tags.length - 1]\n const componentTag =\n !lastTag || lastTag.isSealed() || lastTag.isLocal !== isLocal\n ? this.createNewTag(isLocal)\n : lastTag\n this.componentTags[componentId] = componentTag\n componentTag.addComponent(componentId)\n return componentTag\n }\n\n createNewTag(isLocal: boolean) {\n const newTag = this.tagConstructor(isLocal)\n this.tags.push(newTag)\n return newTag\n }\n\n static get instance() {\n return instance || (instance = StyleSheet.create())\n }\n\n static reset(isServer: ?boolean) {\n instance = StyleSheet.create(isServer)\n }\n\n /* We can make isServer totally implicit once Jest 20 drops and we\n * can change environment on a per-test basis. */\n static create(isServer: ?boolean = !IS_BROWSER) {\n return (isServer ? ServerStyleSheet : BrowserStyleSheet).create()\n }\n\n static clone(oldSheet: StyleSheet) {\n const newSheet = new StyleSheet(\n oldSheet.tagConstructor,\n oldSheet.tags.map(tag => tag.clone()),\n { ...oldSheet.names }\n )\n\n newSheet.hashes = { ...oldSheet.hashes }\n newSheet.deferredInjections = { ...oldSheet.deferredInjections }\n clones.push(newSheet)\n\n return newSheet\n }\n}\n","// @flow\n/* eslint-disable no-underscore-dangle */\nimport React from 'react'\nimport stream from 'stream'\nimport type { Tag } from './StyleSheet'\nimport StyleSheet, { SC_ATTR, LOCAL_ATTR, clones } from './StyleSheet'\nimport StyleSheetManager from './StyleSheetManager'\nimport getNonce from '../utils/nonce'\n\ndeclare var __SERVER__: boolean\n\nclass ServerTag implements Tag {\n emitted: boolean\n isLocal: boolean\n isProduction: boolean\n components: { [string]: Object }\n size: number\n names: Array\n\n constructor(isLocal: boolean) {\n this.emitted = false\n this.isLocal = isLocal\n this.isProduction = process.env.NODE_ENV === 'production'\n this.components = {}\n this.size = 0\n this.names = []\n }\n\n isSealed() {\n return this.emitted\n }\n\n getComponentIds() {\n return Object.keys(this.components)\n }\n\n addComponent(componentId: string) {\n if (this.components[componentId]) {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? `Trying to add Component '${componentId}' twice!`\n : ''\n )\n }\n this.components[componentId] = { componentId, css: '' }\n this.size += 1\n }\n\n concatenateCSS() {\n return Object.keys(this.components).reduce(\n (styles, k) => styles + this.components[k].css,\n ''\n )\n }\n\n inject(componentId: string, css: Array, name: ?string) {\n const comp = this.components[componentId]\n\n if (!comp) {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? 'Must add a new component before you can inject css into it'\n : ''\n )\n }\n\n if (comp.css === '') {\n comp.css = `/* sc-component-id: ${componentId} */\\n`\n }\n\n const cssRulesSize = css.length\n for (let i = 0; i < cssRulesSize; i += 1) {\n const cssRule = css[i]\n comp.css += `${cssRule}\\n`.replace(/\\n*$/, '\\n')\n }\n\n if (name) this.names.push(name)\n }\n\n toHTML() {\n const attrs: Array = [\n 'type=\"text/css\"',\n `${SC_ATTR}=\"${this.names.join(' ')}\"`,\n `${LOCAL_ATTR}=\"${this.isLocal ? 'true' : 'false'}\"`,\n ]\n\n const nonce = getNonce()\n if (nonce) {\n attrs.push(`nonce=\"${nonce}\"`)\n }\n\n this.emitted = true\n return ``\n }\n\n toReactElement(key: string) {\n const attrs: Object = {\n [SC_ATTR]: this.names.join(' '),\n [LOCAL_ATTR]: this.isLocal.toString(),\n }\n\n const nonce = getNonce()\n if (nonce) {\n attrs.nonce = nonce\n }\n\n this.emitted = true\n\n return (\n \n )\n }\n\n clone() {\n const copy = new ServerTag(this.isLocal)\n copy.names = [].concat(this.names)\n copy.size = this.size\n copy.components = Object.keys(this.components).reduce((acc, key) => {\n acc[key] = { ...this.components[key] } // eslint-disable-line no-param-reassign\n return acc\n }, {})\n\n return copy\n }\n}\n\nexport default class ServerStyleSheet {\n closed: boolean\n instance: StyleSheet\n isStreaming: boolean\n\n constructor() {\n this.instance = StyleSheet.clone(StyleSheet.instance)\n this.isStreaming = false\n }\n\n collectStyles(children: any) {\n if (this.closed) {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? \"Can't collect styles once you've called getStyleTags!\"\n : ''\n )\n }\n return (\n {children}\n )\n }\n\n close() {\n clones.splice(clones.indexOf(this.instance), 1)\n this.closed = true\n }\n\n getStyleTags(): string {\n if (!this.closed) {\n this.close()\n }\n\n return this.instance.toHTML()\n }\n\n getStyleElement() {\n if (!this.closed) {\n this.close()\n }\n\n return this.instance.toReactElements()\n }\n\n interleaveWithNodeStream(readableStream: stream.Readable) {\n if (__SERVER__) {\n const ourStream = new stream.Readable()\n\n // $FlowFixMe\n ourStream._read = () => {}\n\n this.isStreaming = true\n\n readableStream.on('data', chunk => {\n ourStream.push(\n this.instance.tags.reduce((html, tag) => {\n if (!tag.isSealed()) {\n html += tag.toHTML() // eslint-disable-line no-param-reassign\n }\n\n return html\n }, '') + chunk\n )\n })\n\n readableStream.on('end', () => {\n ourStream.push(null)\n this.close()\n })\n\n readableStream.on('error', err => {\n ourStream.emit('error', err)\n this.close()\n })\n\n return ourStream\n } else {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? 'streaming only works in Node.js, please do not try to call this method in the browser'\n : ''\n )\n }\n }\n\n static create() {\n return new StyleSheet(isLocal => new ServerTag(isLocal))\n }\n}\n","// @flow\n/* globals React$Element */\nimport React, { Component } from 'react'\nimport PropTypes from 'prop-types'\nimport isPlainObject from 'is-plain-object'\nimport createBroadcast from '../utils/create-broadcast'\nimport type { Broadcast } from '../utils/create-broadcast'\nimport once from '../utils/once'\n\n// NOTE: DO NOT CHANGE, changing this is a semver major change!\nexport const CHANNEL = '__styled-components__'\nexport const CHANNEL_NEXT = `${CHANNEL}next__`\n\nexport const CONTEXT_CHANNEL_SHAPE = PropTypes.shape({\n getTheme: PropTypes.func,\n subscribe: PropTypes.func,\n unsubscribe: PropTypes.func,\n})\n\nexport type Theme = { [key: string]: mixed }\ntype ThemeProviderProps = {|\n children?: React$Element,\n theme: Theme | ((outerTheme: Theme) => void),\n|}\n\nlet warnChannelDeprecated\nif (process.env.NODE_ENV !== 'production') {\n warnChannelDeprecated = once(() => {\n // eslint-disable-next-line no-console\n console.error(\n `Warning: Usage of \\`context.${CHANNEL}\\` as a function is deprecated. It will be replaced with the object on \\`.context.${CHANNEL_NEXT}\\` in a future version.`\n )\n })\n}\n\nconst isFunction = test => typeof test === 'function'\n\n/**\n * Provide a theme to an entire react component tree via context and event listeners (have to do\n * both context and event emitter as pure components block context updates)\n */\nclass ThemeProvider extends Component {\n getTheme: (theme?: Theme | ((outerTheme: Theme) => void)) => Theme\n outerTheme: Theme\n unsubscribeToOuterId: string\n props: ThemeProviderProps\n broadcast: Broadcast\n unsubscribeToOuterId: number = -1\n\n constructor() {\n super()\n this.getTheme = this.getTheme.bind(this)\n }\n\n componentWillMount() {\n // If there is a ThemeProvider wrapper anywhere around this theme provider, merge this theme\n // with the outer theme\n const outerContext = this.context[CHANNEL_NEXT]\n if (outerContext !== undefined) {\n this.unsubscribeToOuterId = outerContext.subscribe(theme => {\n this.outerTheme = theme\n\n if (this.broadcast !== undefined) {\n this.publish(this.props.theme)\n }\n })\n }\n\n this.broadcast = createBroadcast(this.getTheme())\n }\n\n getChildContext() {\n return {\n ...this.context,\n [CHANNEL_NEXT]: {\n getTheme: this.getTheme,\n subscribe: this.broadcast.subscribe,\n unsubscribe: this.broadcast.unsubscribe,\n },\n [CHANNEL]: subscriber => {\n if (process.env.NODE_ENV !== 'production') {\n warnChannelDeprecated()\n }\n\n // Patch the old `subscribe` provide via `CHANNEL` for older clients.\n const unsubscribeId = this.broadcast.subscribe(subscriber)\n return () => this.broadcast.unsubscribe(unsubscribeId)\n },\n }\n }\n\n componentWillReceiveProps(nextProps: ThemeProviderProps) {\n if (this.props.theme !== nextProps.theme) {\n this.publish(nextProps.theme)\n }\n }\n\n componentWillUnmount() {\n if (this.unsubscribeToOuterId !== -1) {\n this.context[CHANNEL_NEXT].unsubscribe(this.unsubscribeToOuterId)\n }\n }\n\n // Get the theme from the props, supporting both (outerTheme) => {} as well as object notation\n getTheme(passedTheme: (outerTheme: Theme) => void | Theme) {\n const theme = passedTheme || this.props.theme\n if (isFunction(theme)) {\n const mergedTheme = theme(this.outerTheme)\n if (\n process.env.NODE_ENV !== 'production' &&\n !isPlainObject(mergedTheme)\n ) {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? '[ThemeProvider] Please return an object from your theme function, i.e. theme={() => ({})}!'\n : ''\n )\n }\n return mergedTheme\n }\n if (!isPlainObject(theme)) {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? '[ThemeProvider] Please make your theme prop a plain object'\n : ''\n )\n }\n return { ...this.outerTheme, ...(theme: Object) }\n }\n\n publish(theme: Theme | ((outerTheme: Theme) => void)) {\n this.broadcast.publish(this.getTheme(theme))\n }\n\n render() {\n if (!this.props.children) {\n return null\n }\n return React.Children.only(this.props.children)\n }\n}\n\nThemeProvider.childContextTypes = {\n [CHANNEL]: PropTypes.func, // legacy\n [CHANNEL_NEXT]: CONTEXT_CHANNEL_SHAPE,\n}\nThemeProvider.contextTypes = {\n [CHANNEL_NEXT]: CONTEXT_CHANNEL_SHAPE,\n}\n\nexport default ThemeProvider\n","// @flow\n\nimport { Component, createElement } from 'react'\nimport PropTypes from 'prop-types'\n\nimport type { Theme } from './ThemeProvider'\nimport createWarnTooManyClasses from '../utils/createWarnTooManyClasses'\n\nimport validAttr from '../utils/validAttr'\nimport isTag from '../utils/isTag'\nimport isStyledComponent from '../utils/isStyledComponent'\nimport getComponentName from '../utils/getComponentName'\nimport determineTheme from '../utils/determineTheme'\nimport escape from '../utils/escape'\nimport type { RuleSet, Target } from '../types'\n\nimport { CHANNEL, CHANNEL_NEXT, CONTEXT_CHANNEL_SHAPE } from './ThemeProvider'\nimport StyleSheet, { CONTEXT_KEY } from './StyleSheet'\nimport ServerStyleSheet from './ServerStyleSheet'\n\n// HACK for generating all static styles without needing to allocate\n// an empty execution context every single time...\nconst STATIC_EXECUTION_CONTEXT = {}\n\nexport default (ComponentStyle: Function, constructWithOptions: Function) => {\n const identifiers = {}\n\n /* We depend on components having unique IDs */\n const generateId = (_displayName: string, parentComponentId: string) => {\n const displayName =\n typeof _displayName !== 'string' ? 'sc' : escape(_displayName)\n\n let componentId\n\n /**\n * only fall back to hashing the component injection order if\n * a proper displayName isn't provided by the babel plugin\n */\n if (!_displayName) {\n const nr = (identifiers[displayName] || 0) + 1\n identifiers[displayName] = nr\n\n componentId = `${displayName}-${ComponentStyle.generateName(\n displayName + nr\n )}`\n } else {\n componentId = `${displayName}-${ComponentStyle.generateName(displayName)}`\n }\n\n return parentComponentId !== undefined\n ? `${parentComponentId}-${componentId}`\n : componentId\n }\n\n class BaseStyledComponent extends Component {\n static target: Target\n static styledComponentId: string\n static attrs: Object\n static componentStyle: Object\n static warnTooManyClasses: Function\n\n attrs = {}\n state = {\n theme: null,\n generatedClassName: '',\n }\n unsubscribeId: number = -1\n\n unsubscribeFromContext() {\n if (this.unsubscribeId !== -1) {\n this.context[CHANNEL_NEXT].unsubscribe(this.unsubscribeId)\n }\n }\n\n buildExecutionContext(theme: any, props: any) {\n const { attrs } = this.constructor\n const context = { ...props, theme }\n if (attrs === undefined) {\n return context\n }\n\n this.attrs = Object.keys(attrs).reduce((acc, key) => {\n const attr = attrs[key]\n // eslint-disable-next-line no-param-reassign\n acc[key] = typeof attr === 'function' ? attr(context) : attr\n return acc\n }, {})\n\n return { ...context, ...this.attrs }\n }\n\n generateAndInjectStyles(theme: any, props: any) {\n const { attrs, componentStyle, warnTooManyClasses } = this.constructor\n const styleSheet = this.context[CONTEXT_KEY] || StyleSheet.instance\n\n // staticaly styled-components don't need to build an execution context object,\n // and shouldn't be increasing the number of class names\n if (componentStyle.isStatic && attrs === undefined) {\n return componentStyle.generateAndInjectStyles(\n STATIC_EXECUTION_CONTEXT,\n styleSheet\n )\n } else {\n const executionContext = this.buildExecutionContext(theme, props)\n const className = componentStyle.generateAndInjectStyles(\n executionContext,\n styleSheet\n )\n\n if (\n process.env.NODE_ENV !== 'production' &&\n warnTooManyClasses !== undefined\n ) {\n warnTooManyClasses(className)\n }\n\n return className\n }\n }\n\n componentWillMount() {\n const { componentStyle } = this.constructor\n const styledContext = this.context[CHANNEL_NEXT]\n\n // If this is a staticaly-styled component, we don't need to the theme\n // to generate or build styles.\n if (componentStyle.isStatic) {\n const generatedClassName = this.generateAndInjectStyles(\n STATIC_EXECUTION_CONTEXT,\n this.props\n )\n this.setState({ generatedClassName })\n // If there is a theme in the context, subscribe to the event emitter. This\n // is necessary due to pure components blocking context updates, this circumvents\n // that by updating when an event is emitted\n } else if (styledContext !== undefined) {\n const { subscribe } = styledContext\n this.unsubscribeId = subscribe(nextTheme => {\n // This will be called once immediately\n const theme = determineTheme(\n this.props,\n nextTheme,\n this.constructor.defaultProps\n )\n const generatedClassName = this.generateAndInjectStyles(\n theme,\n this.props\n )\n\n this.setState({ theme, generatedClassName })\n })\n } else {\n // eslint-disable-next-line react/prop-types\n const theme = this.props.theme || {}\n const generatedClassName = this.generateAndInjectStyles(\n theme,\n this.props\n )\n this.setState({ theme, generatedClassName })\n }\n }\n\n componentWillReceiveProps(nextProps: {\n theme?: Theme,\n [key: string]: any,\n }) {\n // If this is a staticaly-styled component, we don't need to listen to\n // props changes to update styles\n const { componentStyle } = this.constructor\n if (componentStyle.isStatic) {\n return\n }\n\n this.setState(oldState => {\n const theme = determineTheme(\n nextProps,\n oldState.theme,\n this.constructor.defaultProps\n )\n const generatedClassName = this.generateAndInjectStyles(\n theme,\n nextProps\n )\n\n return { theme, generatedClassName }\n })\n }\n\n componentWillUnmount() {\n this.unsubscribeFromContext()\n }\n\n render() {\n // eslint-disable-next-line react/prop-types\n const { innerRef } = this.props\n const { generatedClassName } = this.state\n const { styledComponentId, target } = this.constructor\n\n const isTargetTag = isTag(target)\n\n const className = [\n // eslint-disable-next-line react/prop-types\n this.props.className,\n styledComponentId,\n this.attrs.className,\n generatedClassName,\n ]\n .filter(Boolean)\n .join(' ')\n\n const baseProps = {\n ...this.attrs,\n className,\n }\n\n if (isStyledComponent(target)) {\n baseProps.innerRef = innerRef\n } else {\n baseProps.ref = innerRef\n }\n\n const propsForElement = Object.keys(this.props).reduce(\n (acc, propName) => {\n // Don't pass through non HTML tags through to HTML elements\n // always omit innerRef\n if (\n propName !== 'innerRef' &&\n propName !== 'className' &&\n (!isTargetTag || validAttr(propName))\n ) {\n // eslint-disable-next-line no-param-reassign\n acc[propName] = this.props[propName]\n }\n\n return acc\n },\n baseProps\n )\n\n return createElement(target, propsForElement)\n }\n }\n\n const createStyledComponent = (\n target: Target,\n options: Object,\n rules: RuleSet\n ) => {\n const {\n displayName = isTag(target)\n ? `styled.${target}`\n : `Styled(${getComponentName(target)})`,\n componentId = generateId(options.displayName, options.parentComponentId),\n ParentComponent = BaseStyledComponent,\n rules: extendingRules,\n attrs,\n } = options\n\n const styledComponentId =\n options.displayName && options.componentId\n ? `${escape(options.displayName)}-${options.componentId}`\n : componentId\n\n const componentStyle = new ComponentStyle(\n extendingRules === undefined ? rules : extendingRules.concat(rules),\n attrs,\n styledComponentId\n )\n\n class StyledComponent extends ParentComponent {\n static contextTypes = {\n [CHANNEL]: PropTypes.func,\n [CHANNEL_NEXT]: CONTEXT_CHANNEL_SHAPE,\n [CONTEXT_KEY]: PropTypes.oneOfType([\n PropTypes.instanceOf(StyleSheet),\n PropTypes.instanceOf(ServerStyleSheet),\n ]),\n }\n\n static displayName = displayName\n static styledComponentId = styledComponentId\n static attrs = attrs\n static componentStyle = componentStyle\n static target = target\n\n static withComponent(tag) {\n const { componentId: previousComponentId, ...optionsToCopy } = options\n\n const newComponentId =\n previousComponentId &&\n `${previousComponentId}-${\n isTag(tag) ? tag : escape(getComponentName(tag))\n }`\n\n const newOptions = {\n ...optionsToCopy,\n componentId: newComponentId,\n ParentComponent: StyledComponent,\n }\n\n return createStyledComponent(tag, newOptions, rules)\n }\n\n static get extend() {\n const {\n rules: rulesFromOptions,\n componentId: parentComponentId,\n ...optionsToCopy\n } = options\n\n const newRules =\n rulesFromOptions === undefined\n ? rules\n : rulesFromOptions.concat(rules)\n\n const newOptions = {\n ...optionsToCopy,\n rules: newRules,\n parentComponentId,\n ParentComponent: StyledComponent,\n }\n\n return constructWithOptions(createStyledComponent, target, newOptions)\n }\n }\n\n if (process.env.NODE_ENV !== 'production') {\n StyledComponent.warnTooManyClasses = createWarnTooManyClasses(displayName)\n }\n\n return StyledComponent\n }\n\n return createStyledComponent\n}\n","// @flow\nimport hashStr from '../vendor/glamor/hash'\n\nimport type { RuleSet, NameGenerator, Flattener, Stringifier } from '../types'\nimport StyleSheet from './StyleSheet'\nimport isStyledComponent from '../utils/isStyledComponent'\n\nconst isStaticRules = (rules: RuleSet, attrs?: Object): boolean => {\n for (let i = 0; i < rules.length; i += 1) {\n const rule = rules[i]\n\n // recursive case\n if (Array.isArray(rule) && !isStaticRules(rule)) {\n return false\n } else if (typeof rule === 'function' && !isStyledComponent(rule)) {\n // functions are allowed to be static if they're just being\n // used to get the classname of a nested styled copmonent\n return false\n }\n }\n\n if (attrs !== undefined) {\n // eslint-disable-next-line guard-for-in, no-restricted-syntax\n for (const key in attrs) {\n const value = attrs[key]\n if (typeof value === 'function') {\n return false\n }\n }\n }\n\n return true\n}\n\nconst isHRMEnabled =\n typeof module !== 'undefined' &&\n module.hot &&\n process.env.NODE_ENV !== 'production'\n\n/*\n ComponentStyle is all the CSS-specific stuff, not\n the React-specific stuff.\n */\nexport default (\n nameGenerator: NameGenerator,\n flatten: Flattener,\n stringifyRules: Stringifier\n) => {\n class ComponentStyle {\n rules: RuleSet\n componentId: string\n isStatic: boolean\n lastClassName: ?string\n\n constructor(rules: RuleSet, attrs?: Object, componentId: string) {\n this.rules = rules\n this.isStatic = !isHRMEnabled && isStaticRules(rules, attrs)\n this.componentId = componentId\n if (!StyleSheet.instance.hasInjectedComponent(this.componentId)) {\n const placeholder =\n process.env.NODE_ENV !== 'production' ? `.${componentId} {}` : ''\n StyleSheet.instance.deferredInject(componentId, true, [placeholder])\n }\n }\n\n /*\n * Flattens a rule set into valid CSS\n * Hashes it, wraps the whole chunk in a .hash1234 {}\n * Returns the hash to be injected on render()\n * */\n generateAndInjectStyles(executionContext: Object, styleSheet: StyleSheet) {\n const { isStatic, lastClassName } = this\n if (isStatic && lastClassName !== undefined) {\n return lastClassName\n }\n\n const flatCSS = flatten(this.rules, executionContext)\n const hash = hashStr(this.componentId + flatCSS.join(''))\n\n const { stylesCacheable } = styleSheet\n const existingName = styleSheet.getName(hash)\n\n if (existingName !== undefined) {\n if (stylesCacheable) {\n this.lastClassName = existingName\n }\n return existingName\n }\n\n const name = nameGenerator(hash)\n if (stylesCacheable) {\n this.lastClassName = existingName\n }\n if (styleSheet.alreadyInjected(hash, name)) {\n return name\n }\n\n const css = stringifyRules(flatCSS, `.${name}`)\n // NOTE: this can only be set when we inject the class-name.\n // For some reason, presumably due to how css is stringifyRules behaves in\n // differently between client and server, styles break.\n styleSheet.inject(this.componentId, true, css, hash, name)\n return name\n }\n\n static generateName(str: string) {\n return nameGenerator(hashStr(str))\n }\n }\n\n return ComponentStyle\n}\n","// @flow\nimport type { Target } from '../types'\nimport domElements from '../utils/domElements'\n\nexport default (styledComponent: Function, constructWithOptions: Function) => {\n const styled = (tag: Target) => constructWithOptions(styledComponent, tag)\n\n // Shorthands for all valid HTML Elements\n domElements.forEach(domElement => {\n styled[domElement] = styled(domElement)\n })\n\n return styled\n}\n","// @flow\nimport hashStr from '../vendor/glamor/hash'\nimport type { Interpolation, NameGenerator, Stringifier } from '../types'\nimport StyleSheet from '../models/StyleSheet'\n\nconst replaceWhitespace = (str: string): string => str.replace(/\\s|\\\\n/g, '')\n\nexport default (\n nameGenerator: NameGenerator,\n stringifyRules: Stringifier,\n css: Function\n) => (\n strings: Array,\n ...interpolations: Array\n): string => {\n const rules = css(strings, ...interpolations)\n const hash = hashStr(replaceWhitespace(JSON.stringify(rules)))\n\n const existingName = StyleSheet.instance.getName(hash)\n if (existingName) return existingName\n\n const name = nameGenerator(hash)\n if (StyleSheet.instance.alreadyInjected(hash, name)) return name\n\n const generatedCSS = stringifyRules(rules, name, '@keyframes')\n StyleSheet.instance.inject(\n `sc-keyframes-${name}`,\n true,\n generatedCSS,\n hash,\n name\n )\n return name\n}\n"],"names":["deferredInjections","constructComponentTagMap","nonce","componentWillMount","state","unsubscribeId","attrs","reduce","length","i"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwBA,iGAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SCMEA;;;;;;SAmBOC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBAoDD,YAAA,SAAA,KAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBCNYC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC5EpB,kCAAA;AACA,yCAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0BA0BEC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+JCSEC;;;eAIAC;;;;;;;;;;;;;;;;;+BAe2BC,OAAYC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4BCnEfC,QAA0BC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iCA0ClD,OAAA,aAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AChDJ;;;;;;;;;;;;;;;;;;;SCSK,iBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}