flopflip
Version:
A feature toggle wrapper to use LaunchDarkly with React Redux
1,860 lines (1,562 loc) • 86 kB
JavaScript
import { bindActionCreators, combineReducers } from 'redux';
import React, { Component } from 'react';
import propTypes from 'prop-types';
import { connect } from 'react-redux';
var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
function createCommonjsModule(fn, module) {
return module = { exports: {} }, fn(module, module.exports), module.exports;
}
var base64 = createCommonjsModule(function (module, exports) {
(function () {
var object = exports; // #8: web workers
var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
function InvalidCharacterError(message) {
this.message = message;
}
InvalidCharacterError.prototype = new Error;
InvalidCharacterError.prototype.name = 'InvalidCharacterError';
// encoder
// [https://gist.github.com/999166] by [https://github.com/nignag]
object.btoa || (
object.btoa = function (input) {
var str = String(input);
for (
// initialize result and counter
var block, charCode, idx = 0, map = chars, output = '';
// if the next str index does not exist:
// change the mapping table to "="
// check if d has no fractional digits
str.charAt(idx | 0) || (map = '=', idx % 1);
// "8 - idx % 1 * 8" generates the sequence 2, 4, 6, 8
output += map.charAt(63 & block >> 8 - idx % 1 * 8)
) {
charCode = str.charCodeAt(idx += 3/4);
if (charCode > 0xFF) {
throw new InvalidCharacterError("'btoa' failed: The string to be encoded contains characters outside of the Latin1 range.");
}
block = block << 8 | charCode;
}
return output;
});
// decoder
// [https://gist.github.com/1020396] by [https://github.com/atk]
object.atob || (
object.atob = function (input) {
var str = String(input).replace(/=+$/, '');
if (str.length % 4 == 1) {
throw new InvalidCharacterError("'atob' failed: The string to be decoded is not correctly encoded.");
}
for (
// initialize result and counters
var bc = 0, bs, buffer, idx = 0, output = '';
// get next character
buffer = str.charAt(idx++);
// character found in table? initialize bit storage and add its ascii value;
~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer,
// and if not first of each 4 characters,
// convert the first 8 bits to one ascii character
bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0
) {
// try to find character in table (0-63, not found => -1)
buffer = chars.indexOf(buffer);
}
return output;
});
}());
});
// See http://ecmanaut.blogspot.com/2006/07/encoding-decoding-utf8-in-javascript.html
function btoa(s) {
return base64.btoa(unescape(encodeURIComponent(s)));
}
function base64URLEncode(s) {
return btoa(s)
.replace(/=/g, '')
.replace(/\+/g, '-')
.replace(/\//g, '_');
}
function clone(obj) {
return JSON.parse(JSON.stringify(obj));
}
function modifications(oldObj, newObj) {
var mods = {};
if (!oldObj || !newObj) { return {}; }
for (var prop in oldObj) {
if (oldObj.hasOwnProperty(prop)) {
if (newObj[prop] !== oldObj[prop]) {
mods[prop] = {previous: oldObj[prop], current: newObj[prop]};
}
}
}
return mods;
}
var utils = {
btoa: btoa,
base64URLEncode: base64URLEncode,
clone: clone,
modifications: modifications
};
function EventProcessor(eventsUrl) {
var processor = {};
var queue = [];
var initialFlush = true;
processor.enqueue = function(event) {
queue.push(event);
};
processor.flush = function(user, sync) {
var maxLength = 2000 - eventsUrl.length;
var data = [];
if (!user) {
if (initialFlush) {
console && console.warn && console.warn('Be sure to call `identify` in the LaunchDarkly client: http://docs.launchdarkly.com/docs/running-an-ab-test#include-the-client-side-snippet');
}
return false;
}
initialFlush = false;
while (maxLength > 0 && queue.length > 0) {
var event = queue.pop();
event.user = user;
maxLength = maxLength - utils.base64URLEncode(JSON.stringify(event)).length;
// If we are over the max size, put this one back on the queue
// to try in the next round, unless this event alone is larger
// than the limit, in which case, screw it, and try it anyway.
if (maxLength < 0 && data.length > 0) {
queue.push(event);
} else {
data.push(event);
}
}
if (data.length > 0) {
var src = eventsUrl + '?d=' + utils.base64URLEncode(JSON.stringify(data));
//Detect browser support for CORS
if ('withCredentials' in new XMLHttpRequest()) {
/* supports cross-domain requests */
var xhr = new XMLHttpRequest();
xhr.open('GET', src, !sync);
xhr.send();
} else {
var img = new Image();
img.src = src;
}
}
// if the queue is not empty, call settimeout to flush it again
// with a 0 timeout (stack-less recursion)
// Or, just recursively call flush_queue with the remaining elements
// if we're doing this on unload
if (queue.length > 0) {
if (sync) {
processor.flush(user, sync);
}
else {
setTimeout(function() {
processor.flush(user);
}, 0);
}
}
return false;
};
return processor;
}
var EventProcessor_1 = EventProcessor;
function EventEmitter() {
var emitter = {};
var events = {};
emitter.on = function(event, handler, context) {
events[event] = events[event] || [];
events[event] = events[event].concat({handler: handler, context: context});
};
emitter.off = function(event, handler, context) {
if (!events[event]) { return; }
for (var i = 0; i < events[event].length ; i++) {
if (events[event][i].handler === handler && events[event][i].context === context) {
events[event] = events[event].slice(0, i).concat(events[event].slice(i + 1));
}
}
};
emitter.emit = function(event) {
if (!events[event]) { return; }
for (var i = 0; i < events[event].length; i++) {
events[event][i].handler.apply(events[event][i].context, Array.prototype.slice.call(arguments, 1));
}
};
return emitter;
}
var EventEmitter_1 = EventEmitter;
var matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g;
var index$1 = function (str) {
if (typeof str !== 'string') {
throw new TypeError('Expected a string');
}
return str.replace(matchOperatorsRe, '\\$&');
};
function doesUrlMatch(matcher, href, search, hash) {
var canonicalUrl = href.replace(search, '').replace(hash, '');
var regex;
var testUrl;
switch (matcher.kind) {
case 'exact':
testUrl = href;
regex = new RegExp('^' + index$1(matcher.url) + '/?$');
break;
case 'canonical':
testUrl = canonicalUrl;
regex = new RegExp('^' + index$1(matcher.url) + '/?$');
break;
case 'substring':
testUrl = canonicalUrl;
regex = new RegExp('.*' + index$1(matcher.substring) + '.*$');
break;
case 'regex':
testUrl = canonicalUrl;
regex = new RegExp(matcher.pattern);
break;
default:
return false;
}
return regex.test(testUrl);
}
function findGoalsForClick(event, clickGoals) {
var matches = [];
for (var i = 0; i < clickGoals.length; i++) {
var target = event.target;
var goal = clickGoals[i];
var selector = goal.selector;
var elements = document.querySelectorAll(selector);
while (target && elements.length > 0) {
for (var j = 0; j < elements.length; j++) {
if (target === elements[j])
matches.push(goal);
}
target = target.parentNode;
}
}
return matches;
}
function GoalTracker(goals, onEvent) {
var tracker = {};
var goals = goals;
var listenerFn = null;
var clickGoals = [];
for (var i = 0; i < goals.length; i++) {
var goal = goals[i];
var urls = goal.urls || [];
for (var j = 0; j < urls.length; j++) {
if (doesUrlMatch(urls[j], location.href, location.search, location.hash)) {
if (goal.kind === 'pageview') {
onEvent('pageview', goal);
} else {
clickGoals.push(goal);
onEvent('click_pageview', goal);
}
break;
}
}
}
if (clickGoals.length > 0) {
listenerFn = function(event) {
var goals = findGoalsForClick(event, clickGoals);
for (var i = 0; i < goals.length; i++) {
onEvent('click', goals[i]);
}
};
document.addEventListener('click', listenerFn);
}
tracker.dispose = function() {
document.removeEventListener('click', listenerFn);
};
return tracker;
}
var GoalTracker_1 = GoalTracker;
function Stream(url, environment) {
var stream = {};
var url = url + '/ping/' + environment;
var es = null;
stream.connect = function(onPing) {
if (typeof EventSource !== 'undefined') {
es = new window.EventSource(url);
es.addEventListener('ping', onPing);
}
};
stream.disconnect = function() {
es && es.close();
};
stream.isConnected = function() {
return es && (es.readyState === EventSource.OPEN || es.readyState === EventSource.CONNECTING);
};
return stream;
}
var Stream_1 = Stream;
var json = 'application/json';
function fetchJSON(endpoint, callback) {
var xhr = new XMLHttpRequest();
xhr.addEventListener('load', function() {
if (xhr.status === 200 && xhr.getResponseHeader('Content-type') === json) {
callback(null, JSON.parse(xhr.responseText));
} else {
callback(xhr.statusText);
}
});
xhr.addEventListener('error', function() {
callback(xhr.statusText);
});
xhr.open('GET', endpoint);
xhr.send();
return xhr;
}
var flagSettingsRequest;
var lastFlagSettingsCallback;
function Requestor(baseUrl, environment) {
var requestor = {};
requestor.fetchFlagSettings = function(user, hash, callback) {
var data = utils.base64URLEncode(JSON.stringify(user));
var endpoint = [baseUrl, '/sdk/eval/', environment, '/users/', data, hash ? '?h=' + hash : ''].join('');
var cb;
var wrappedCallback = (function(currentCallback) {
return function() {
currentCallback.apply(null, arguments);
flagSettingsRequest = null;
lastFlagSettingsCallback = null;
};
})(callback);
if (flagSettingsRequest) {
flagSettingsRequest.abort();
cb = (function(prevCallback) {
return function() {
prevCallback && prevCallback.apply(null, arguments);
wrappedCallback.apply(null, arguments);
};
})(lastFlagSettingsCallback);
} else {
cb = wrappedCallback;
}
lastFlagSettingsCallback = cb;
flagSettingsRequest = fetchJSON(endpoint, cb);
};
requestor.fetchGoals = function(callback) {
var endpoint = [baseUrl, '/sdk/goals/', environment].join('');
fetchJSON(endpoint, callback);
};
return requestor;
}
var Requestor_1 = Requestor;
function sanitizeUser(u) {
var sane = utils.clone(u);
if (sane.key) {
sane.key = sane.key.toString();
}
return sane;
}
function Identity(initialUser, onChange) {
var ident = {};
var user;
ident.setUser = function(u) {
user = sanitizeUser(u);
onChange(utils.clone(user));
};
ident.getUser = function() {
return utils.clone(user);
};
if (initialUser) {
ident.setUser(initialUser);
}
return ident;
}
var Identity_1 = Identity;
var messages ={
invalidKey: function() {
return 'Event key must be a string';
},
unknownCustomEventKey: function(key) {
return 'Custom event "' + key + '" does not exist'
}
};
var index = createCommonjsModule(function (module) {
var flags = {};
var environment;
var events;
var requestor;
var stream;
var emitter;
var hash;
var ident;
var baseUrl;
var eventsUrl;
var streamUrl;
var goalTracker;
var useLocalStorage;
var goals;
var readyEvent = 'ready';
var changeEvent = 'change';
var flushInterval = 2000;
var seenRequests = {};
function sendIdentifyEvent(user) {
events.enqueue({
kind: 'identify',
key: user.key,
user: user,
creationDate: (new Date()).getTime()
});
}
function sendFlagEvent(key, value, defaultValue) {
var user = ident.getUser();
var cacheKey = JSON.stringify(value) + (user && user.key ? user.key : '') + key;
var now = new Date();
var cached = seenRequests[cacheKey];
if (cached && (now - cached) < 300000 /* five minutes, in ms */) {
return;
}
seenRequests[cacheKey] = now;
events.enqueue({
kind: 'feature',
key: key,
user: user,
value: value,
'default': defaultValue,
creationDate: now.getTime()
});
}
function sendGoalEvent(kind, goal) {
var event = {
kind: kind,
key: goal.key,
data: null,
url: window.location.href,
creationDate: (new Date()).getTime()
};
if (kind === 'click') {
event.selector = goal.selector;
}
return events.enqueue(event);
}
function identify(user, hash, onDone) {
ident.setUser(user);
requestor.fetchFlagSettings(ident.getUser(), hash, function(err, settings) {
if (err) {
console.warn('Error fetching flag settings: ', err);
}
if (settings) {
updateSettings(settings);
}
onDone && onDone();
});
}
function variation(key, defaultValue) {
var value;
if (flags && flags.hasOwnProperty(key)) {
value = flags[key] === null ? defaultValue : flags[key];
} else {
value = defaultValue;
}
sendFlagEvent(key, value, defaultValue);
return value;
}
function allFlags() {
var results = {};
if (!flags) { return results; }
for (var key in flags) {
if (flags.hasOwnProperty(key)) {
results[key] = variation(key, null);
}
}
return results;
}
function customEventExists(key) {
if (!goals || goals.length === 0) { return false; }
for (var i=0 ; i < goals.length ; i++) {
if (goals[i].kind === 'custom' && goals[i].key === key) {
return true;
}
}
return false;
}
function track(key, data) {
if (typeof key !== 'string') {
throw messages.invalidKey();
}
// Validate key if we have goals
if (!!goals && !customEventExists(key)) {
console.warn(messages.unknownCustomEventKey(key));
}
events.enqueue({
kind: 'custom',
key: key,
data: data,
url: window.location.href,
creationDate: (new Date()).getTime()
});
}
function connectStream() {
stream.connect(function() {
requestor.fetchFlagSettings(ident.getUser(), hash, function(err, settings) {
if (err) {
console.warn('Error fetching flag settings: ', err);
}
updateSettings(settings);
});
});
}
function updateSettings(settings) {
var changes;
var keys;
if (!settings) { return; }
changes = utils.modifications(flags, settings);
keys = Object.keys(changes);
flags = settings;
if (useLocalStorage) {
localStorage.setItem(lsKey(environment, ident.getUser()), JSON.stringify(flags));
}
if (keys.length > 0) {
keys.forEach(function(key) {
emitter.emit(changeEvent + ':' + key, changes[key].current, changes[key].previous);
});
emitter.emit(changeEvent, changes);
keys.forEach(function(key) {
sendFlagEvent(key, changes[key].current);
});
}
}
function on(event, handler, context) {
if (event.substr(0, changeEvent.length) === changeEvent) {
if (!stream.isConnected()) {
connectStream();
}
emitter.on.apply(emitter, [event, handler, context]);
} else {
emitter.on.apply(emitter, Array.prototype.slice.call(arguments));
}
}
function off() {
emitter.off.apply(emitter, Array.prototype.slice.call(arguments));
}
function handleMessage(event) {
if (event.origin !== baseUrl) { return; }
if (event.data.type === 'SYN') {
window.editorClientBaseUrl = baseUrl;
var editorTag = document.createElement('script');
editorTag.type = 'text/javascript';
editorTag.async = true;
editorTag.src = baseUrl + event.data.editorClientUrl;
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(editorTag, s);
}
}
var client = {
identify: identify,
variation: variation,
track: track,
on: on,
off: off,
allFlags: allFlags
};
function lsKey(env, user) {
var uKey = '';
if (user && user.key) {
uKey = user.key;
}
return 'ld:' + env + ':' + uKey;
}
function initialize(env, user, options) {
var localStorageKey;
options = options || {};
environment = env;
flags = typeof(options.bootstrap) === 'object' ? options.bootstrap : {};
hash = options.hash;
baseUrl = options.baseUrl || 'https://app.launchdarkly.com';
eventsUrl = options.eventsUrl || 'https://events.launchdarkly.com';
streamUrl = options.streamUrl || 'https://clientstream.launchdarkly.com';
stream = Stream_1(streamUrl, environment);
events = EventProcessor_1(eventsUrl + '/a/' + environment + '.gif');
emitter = EventEmitter_1();
ident = Identity_1(user, sendIdentifyEvent);
requestor = Requestor_1(baseUrl, environment);
localStorageKey = lsKey(environment, ident.getUser());
if (typeof options.bootstrap === 'object') {
// Emitting the event here will happen before the consumer
// can register a listener, so defer to next tick.
setTimeout(function() { emitter.emit(readyEvent); }, 0);
}
else if (typeof(options.bootstrap) === 'string' && options.bootstrap.toUpperCase() === 'LOCALSTORAGE' && typeof(Storage) !== 'undefined') {
useLocalStorage = true;
// check if localstorage data is corrupted, if so clear it
try {
flags = JSON.parse(localStorage.getItem(localStorageKey));
} catch (error) {
localStorage.setItem(localStorageKey, null);
}
if (flags === null) {
requestor.fetchFlagSettings(ident.getUser(), hash, function(err, settings) {
if (err) {
console.warn('Error fetching flag settings: ', err);
}
flags = settings;
settings && localStorage.setItem(localStorageKey, JSON.stringify(flags));
emitter.emit(readyEvent);
});
} else {
// We're reading the flags from local storage. Signal that we're ready,
// then update localStorage for the next page load. We won't signal changes or update
// the in-memory flags unless you subscribe for changes
setTimeout(function() { emitter.emit(readyEvent); }, 0);
requestor.fetchFlagSettings(ident.getUser(), hash, function(err, settings) {
if (err) {
console.warn('Error fetching flag settings: ', err);
}
settings && localStorage.setItem(localStorageKey, JSON.stringify(settings));
});
}
}
else {
requestor.fetchFlagSettings(ident.getUser(), hash, function(err, settings) {
if (err) {
console.warn('Error fetching flag settings: ', err);
}
flags = settings;
emitter.emit(readyEvent);
});
}
requestor.fetchGoals(function(err, g) {
if (err) {
console.warn('Error fetching goals: ', err);
}
if (g && g.length > 0) {
goals = g;
goalTracker = GoalTracker_1(goals, sendGoalEvent);
}
});
function start() {
setTimeout(function tick() {
events.flush(ident.getUser());
setTimeout(tick, flushInterval);
}, flushInterval);
}
if (document.readyState !== 'complete') {
window.addEventListener('load', start);
} else {
start();
}
window.addEventListener('beforeunload', function() {
events.flush(ident.getUser(), true);
});
function refreshGoalTracker() {
if (goalTracker) {
goalTracker.dispose();
}
if (goals && goals.length) {
goalTracker = GoalTracker_1(goals, sendGoalEvent);
}
}
if (goals && goals.length > 0) {
if (!!(window.history && history.pushState)) {
window.addEventListener('popstate', refreshGoalTracker);
} else {
window.addEventListener('hashchange', refreshGoalTracker);
}
}
window.addEventListener('message', handleMessage);
return client;
}
module.exports = {
initialize: initialize
};
{
module.exports.version = '1.0.0';
}
});
/**
* lodash (Custom Build) <https://lodash.com/>
* Build: `lodash modularize exports="npm" -o ./`
* Copyright jQuery Foundation and other contributors <https://jquery.org/>
* Released under MIT license <https://lodash.com/license>
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
*/
/** Used as references for various `Number` constants. */
var INFINITY = 1 / 0;
/** `Object#toString` result references. */
var symbolTag = '[object Symbol]';
/** Used to match words composed of alphanumeric characters. */
var reAsciiWord = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
/** Used to match Latin Unicode letters (excluding mathematical operators). */
var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g;
/** Used to compose unicode character classes. */
var rsAstralRange = '\\ud800-\\udfff';
var rsComboMarksRange = '\\u0300-\\u036f\\ufe20-\\ufe23';
var rsComboSymbolsRange = '\\u20d0-\\u20f0';
var rsDingbatRange = '\\u2700-\\u27bf';
var rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff';
var rsMathOpRange = '\\xac\\xb1\\xd7\\xf7';
var rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf';
var rsPunctuationRange = '\\u2000-\\u206f';
var rsSpaceRange = ' \\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';
var rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde';
var rsVarRange = '\\ufe0e\\ufe0f';
var rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange;
/** Used to compose unicode capture groups. */
var rsApos = "['\u2019]";
var rsAstral = '[' + rsAstralRange + ']';
var rsBreak = '[' + rsBreakRange + ']';
var rsCombo = '[' + rsComboMarksRange + rsComboSymbolsRange + ']';
var rsDigits = '\\d+';
var rsDingbat = '[' + rsDingbatRange + ']';
var rsLower = '[' + rsLowerRange + ']';
var rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']';
var rsFitz = '\\ud83c[\\udffb-\\udfff]';
var rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')';
var rsNonAstral = '[^' + rsAstralRange + ']';
var rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}';
var rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]';
var rsUpper = '[' + rsUpperRange + ']';
var rsZWJ = '\\u200d';
/** Used to compose unicode regexes. */
var rsLowerMisc = '(?:' + rsLower + '|' + rsMisc + ')';
var rsUpperMisc = '(?:' + rsUpper + '|' + rsMisc + ')';
var rsOptLowerContr = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?';
var rsOptUpperContr = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?';
var reOptMod = rsModifier + '?';
var rsOptVar = '[' + rsVarRange + ']?';
var rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*';
var rsSeq = rsOptVar + reOptMod + rsOptJoin;
var rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq;
var rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
/** Used to match apostrophes. */
var reApos = RegExp(rsApos, 'g');
/**
* Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and
* [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).
*/
var reComboMark = RegExp(rsCombo, 'g');
/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');
/** Used to match complex or compound words. */
var reUnicodeWord = RegExp([
rsUpper + '?' + rsLower + '+' + rsOptLowerContr + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',
rsUpperMisc + '+' + rsOptUpperContr + '(?=' + [rsBreak, rsUpper + rsLowerMisc, '$'].join('|') + ')',
rsUpper + '?' + rsLowerMisc + '+' + rsOptLowerContr,
rsUpper + '+' + rsOptUpperContr,
rsDigits,
rsEmoji
].join('|'), 'g');
/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */
var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboMarksRange + rsComboSymbolsRange + rsVarRange + ']');
/** Used to detect strings that need a more robust regexp to match words. */
var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;
/** Used to map Latin Unicode letters to basic Latin letters. */
var deburredLetters = {
// Latin-1 Supplement block.
'\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A',
'\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a',
'\xc7': 'C', '\xe7': 'c',
'\xd0': 'D', '\xf0': 'd',
'\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E',
'\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e',
'\xcc': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I',
'\xec': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i',
'\xd1': 'N', '\xf1': 'n',
'\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O',
'\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o',
'\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U',
'\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u',
'\xdd': 'Y', '\xfd': 'y', '\xff': 'y',
'\xc6': 'Ae', '\xe6': 'ae',
'\xde': 'Th', '\xfe': 'th',
'\xdf': 'ss',
// Latin Extended-A block.
'\u0100': 'A', '\u0102': 'A', '\u0104': 'A',
'\u0101': 'a', '\u0103': 'a', '\u0105': 'a',
'\u0106': 'C', '\u0108': 'C', '\u010a': 'C', '\u010c': 'C',
'\u0107': 'c', '\u0109': 'c', '\u010b': 'c', '\u010d': 'c',
'\u010e': 'D', '\u0110': 'D', '\u010f': 'd', '\u0111': 'd',
'\u0112': 'E', '\u0114': 'E', '\u0116': 'E', '\u0118': 'E', '\u011a': 'E',
'\u0113': 'e', '\u0115': 'e', '\u0117': 'e', '\u0119': 'e', '\u011b': 'e',
'\u011c': 'G', '\u011e': 'G', '\u0120': 'G', '\u0122': 'G',
'\u011d': 'g', '\u011f': 'g', '\u0121': 'g', '\u0123': 'g',
'\u0124': 'H', '\u0126': 'H', '\u0125': 'h', '\u0127': 'h',
'\u0128': 'I', '\u012a': 'I', '\u012c': 'I', '\u012e': 'I', '\u0130': 'I',
'\u0129': 'i', '\u012b': 'i', '\u012d': 'i', '\u012f': 'i', '\u0131': 'i',
'\u0134': 'J', '\u0135': 'j',
'\u0136': 'K', '\u0137': 'k', '\u0138': 'k',
'\u0139': 'L', '\u013b': 'L', '\u013d': 'L', '\u013f': 'L', '\u0141': 'L',
'\u013a': 'l', '\u013c': 'l', '\u013e': 'l', '\u0140': 'l', '\u0142': 'l',
'\u0143': 'N', '\u0145': 'N', '\u0147': 'N', '\u014a': 'N',
'\u0144': 'n', '\u0146': 'n', '\u0148': 'n', '\u014b': 'n',
'\u014c': 'O', '\u014e': 'O', '\u0150': 'O',
'\u014d': 'o', '\u014f': 'o', '\u0151': 'o',
'\u0154': 'R', '\u0156': 'R', '\u0158': 'R',
'\u0155': 'r', '\u0157': 'r', '\u0159': 'r',
'\u015a': 'S', '\u015c': 'S', '\u015e': 'S', '\u0160': 'S',
'\u015b': 's', '\u015d': 's', '\u015f': 's', '\u0161': 's',
'\u0162': 'T', '\u0164': 'T', '\u0166': 'T',
'\u0163': 't', '\u0165': 't', '\u0167': 't',
'\u0168': 'U', '\u016a': 'U', '\u016c': 'U', '\u016e': 'U', '\u0170': 'U', '\u0172': 'U',
'\u0169': 'u', '\u016b': 'u', '\u016d': 'u', '\u016f': 'u', '\u0171': 'u', '\u0173': 'u',
'\u0174': 'W', '\u0175': 'w',
'\u0176': 'Y', '\u0177': 'y', '\u0178': 'Y',
'\u0179': 'Z', '\u017b': 'Z', '\u017d': 'Z',
'\u017a': 'z', '\u017c': 'z', '\u017e': 'z',
'\u0132': 'IJ', '\u0133': 'ij',
'\u0152': 'Oe', '\u0153': 'oe',
'\u0149': "'n", '\u017f': 'ss'
};
/** Detect free variable `global` from Node.js. */
var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;
/** Detect free variable `self`. */
var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
/** Used as a reference to the global object. */
var root = freeGlobal || freeSelf || Function('return this')();
/**
* A specialized version of `_.reduce` for arrays without support for
* iteratee shorthands.
*
* @private
* @param {Array} [array] The array to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @param {*} [accumulator] The initial value.
* @param {boolean} [initAccum] Specify using the first element of `array` as
* the initial value.
* @returns {*} Returns the accumulated value.
*/
function arrayReduce(array, iteratee, accumulator, initAccum) {
var index = -1,
length = array ? array.length : 0;
if (initAccum && length) {
accumulator = array[++index];
}
while (++index < length) {
accumulator = iteratee(accumulator, array[index], index, array);
}
return accumulator;
}
/**
* Converts an ASCII `string` to an array.
*
* @private
* @param {string} string The string to convert.
* @returns {Array} Returns the converted array.
*/
function asciiToArray(string) {
return string.split('');
}
/**
* Splits an ASCII `string` into an array of its words.
*
* @private
* @param {string} The string to inspect.
* @returns {Array} Returns the words of `string`.
*/
function asciiWords(string) {
return string.match(reAsciiWord) || [];
}
/**
* The base implementation of `_.propertyOf` without support for deep paths.
*
* @private
* @param {Object} object The object to query.
* @returns {Function} Returns the new accessor function.
*/
function basePropertyOf(object) {
return function(key) {
return object == null ? undefined : object[key];
};
}
/**
* Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A
* letters to basic Latin letters.
*
* @private
* @param {string} letter The matched letter to deburr.
* @returns {string} Returns the deburred letter.
*/
var deburrLetter = basePropertyOf(deburredLetters);
/**
* Checks if `string` contains Unicode symbols.
*
* @private
* @param {string} string The string to inspect.
* @returns {boolean} Returns `true` if a symbol is found, else `false`.
*/
function hasUnicode(string) {
return reHasUnicode.test(string);
}
/**
* Checks if `string` contains a word composed of Unicode symbols.
*
* @private
* @param {string} string The string to inspect.
* @returns {boolean} Returns `true` if a word is found, else `false`.
*/
function hasUnicodeWord(string) {
return reHasUnicodeWord.test(string);
}
/**
* Converts `string` to an array.
*
* @private
* @param {string} string The string to convert.
* @returns {Array} Returns the converted array.
*/
function stringToArray(string) {
return hasUnicode(string)
? unicodeToArray(string)
: asciiToArray(string);
}
/**
* Converts a Unicode `string` to an array.
*
* @private
* @param {string} string The string to convert.
* @returns {Array} Returns the converted array.
*/
function unicodeToArray(string) {
return string.match(reUnicode) || [];
}
/**
* Splits a Unicode `string` into an array of its words.
*
* @private
* @param {string} The string to inspect.
* @returns {Array} Returns the words of `string`.
*/
function unicodeWords(string) {
return string.match(reUnicodeWord) || [];
}
/** Used for built-in method references. */
var objectProto = Object.prototype;
/**
* Used to resolve the
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
* of values.
*/
var objectToString = objectProto.toString;
/** Built-in value references. */
var Symbol$1 = root.Symbol;
/** Used to convert symbols to primitives and strings. */
var symbolProto = Symbol$1 ? Symbol$1.prototype : undefined;
var symbolToString = symbolProto ? symbolProto.toString : undefined;
/**
* The base implementation of `_.slice` without an iteratee call guard.
*
* @private
* @param {Array} array The array to slice.
* @param {number} [start=0] The start position.
* @param {number} [end=array.length] The end position.
* @returns {Array} Returns the slice of `array`.
*/
function baseSlice(array, start, end) {
var index = -1,
length = array.length;
if (start < 0) {
start = -start > length ? 0 : (length + start);
}
end = end > length ? length : end;
if (end < 0) {
end += length;
}
length = start > end ? 0 : ((end - start) >>> 0);
start >>>= 0;
var result = Array(length);
while (++index < length) {
result[index] = array[index + start];
}
return result;
}
/**
* The base implementation of `_.toString` which doesn't convert nullish
* values to empty strings.
*
* @private
* @param {*} value The value to process.
* @returns {string} Returns the string.
*/
function baseToString(value) {
// Exit early for strings to avoid a performance hit in some environments.
if (typeof value == 'string') {
return value;
}
if (isSymbol(value)) {
return symbolToString ? symbolToString.call(value) : '';
}
var result = (value + '');
return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
}
/**
* Casts `array` to a slice if it's needed.
*
* @private
* @param {Array} array The array to inspect.
* @param {number} start The start position.
* @param {number} [end=array.length] The end position.
* @returns {Array} Returns the cast slice.
*/
function castSlice(array, start, end) {
var length = array.length;
end = end === undefined ? length : end;
return (!start && end >= length) ? array : baseSlice(array, start, end);
}
/**
* Creates a function like `_.lowerFirst`.
*
* @private
* @param {string} methodName The name of the `String` case method to use.
* @returns {Function} Returns the new case function.
*/
function createCaseFirst(methodName) {
return function(string) {
string = toString(string);
var strSymbols = hasUnicode(string)
? stringToArray(string)
: undefined;
var chr = strSymbols
? strSymbols[0]
: string.charAt(0);
var trailing = strSymbols
? castSlice(strSymbols, 1).join('')
: string.slice(1);
return chr[methodName]() + trailing;
};
}
/**
* Creates a function like `_.camelCase`.
*
* @private
* @param {Function} callback The function to combine each word.
* @returns {Function} Returns the new compounder function.
*/
function createCompounder(callback) {
return function(string) {
return arrayReduce(words(deburr(string).replace(reApos, '')), callback, '');
};
}
/**
* Checks if `value` is object-like. A value is object-like if it's not `null`
* and has a `typeof` result of "object".
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
* @example
*
* _.isObjectLike({});
* // => true
*
* _.isObjectLike([1, 2, 3]);
* // => true
*
* _.isObjectLike(_.noop);
* // => false
*
* _.isObjectLike(null);
* // => false
*/
function isObjectLike(value) {
return !!value && typeof value == 'object';
}
/**
* Checks if `value` is classified as a `Symbol` primitive or object.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
* @example
*
* _.isSymbol(Symbol.iterator);
* // => true
*
* _.isSymbol('abc');
* // => false
*/
function isSymbol(value) {
return typeof value == 'symbol' ||
(isObjectLike(value) && objectToString.call(value) == symbolTag);
}
/**
* Converts `value` to a string. An empty string is returned for `null`
* and `undefined` values. The sign of `-0` is preserved.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to process.
* @returns {string} Returns the string.
* @example
*
* _.toString(null);
* // => ''
*
* _.toString(-0);
* // => '-0'
*
* _.toString([1, 2, 3]);
* // => '1,2,3'
*/
function toString(value) {
return value == null ? '' : baseToString(value);
}
/**
* Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).
*
* @static
* @memberOf _
* @since 3.0.0
* @category String
* @param {string} [string=''] The string to convert.
* @returns {string} Returns the camel cased string.
* @example
*
* _.camelCase('Foo Bar');
* // => 'fooBar'
*
* _.camelCase('--foo-bar--');
* // => 'fooBar'
*
* _.camelCase('__FOO_BAR__');
* // => 'fooBar'
*/
var camelCase = createCompounder(function(result, word, index) {
word = word.toLowerCase();
return result + (index ? capitalize(word) : word);
});
/**
* Converts the first character of `string` to upper case and the remaining
* to lower case.
*
* @static
* @memberOf _
* @since 3.0.0
* @category String
* @param {string} [string=''] The string to capitalize.
* @returns {string} Returns the capitalized string.
* @example
*
* _.capitalize('FRED');
* // => 'Fred'
*/
function capitalize(string) {
return upperFirst(toString(string).toLowerCase());
}
/**
* Deburrs `string` by converting
* [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
* and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A)
* letters to basic Latin letters and removing
* [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
*
* @static
* @memberOf _
* @since 3.0.0
* @category String
* @param {string} [string=''] The string to deburr.
* @returns {string} Returns the deburred string.
* @example
*
* _.deburr('déjà vu');
* // => 'deja vu'
*/
function deburr(string) {
string = toString(string);
return string && string.replace(reLatin, deburrLetter).replace(reComboMark, '');
}
/**
* Converts the first character of `string` to upper case.
*
* @static
* @memberOf _
* @since 4.0.0
* @category String
* @param {string} [string=''] The string to convert.
* @returns {string} Returns the converted string.
* @example
*
* _.upperFirst('fred');
* // => 'Fred'
*
* _.upperFirst('FRED');
* // => 'FRED'
*/
var upperFirst = createCaseFirst('toUpperCase');
/**
* Splits `string` into an array of its words.
*
* @static
* @memberOf _
* @since 3.0.0
* @category String
* @param {string} [string=''] The string to inspect.
* @param {RegExp|string} [pattern] The pattern to match words.
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
* @returns {Array} Returns the words of `string`.
* @example
*
* _.words('fred, barney, & pebbles');
* // => ['fred', 'barney', 'pebbles']
*
* _.words('fred, barney, & pebbles', /[^, ]+/g);
* // => ['fred', 'barney', '&', 'pebbles']
*/
function words(string, pattern, guard) {
string = toString(string);
pattern = guard ? undefined : pattern;
if (pattern === undefined) {
return hasUnicodeWord(string) ? unicodeWords(string) : asciiWords(string);
}
return string.match(pattern) || [];
}
var index$3 = camelCase;
/**
* To avoid having to rely on node-uuid and crypto.
*
* Credit: https://gist.github.com/antonioaguilar/6135f84658328d399ed656ba3169e558
*/
var uuid = (function () {
var date = new Date().getTime();
var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var random = (date + Math.random() * 16) % 16 | 0;
date = Math.floor(date / 16);
return (c === 'x' ? random : random & 0x3 | 0x8).toString(16);
});
return uuid;
});
var classCallCheck = function (instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
};
var createClass = function () {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
return Constructor;
};
}();
var defineProperty = function (obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
};
var _extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
var inherits = function (subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
enumerable: false,
writable: true,
configurable: true
}
});
if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
};
var possibleConstructorReturn = function (self, call) {
if (!self) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return call && (typeof call === "object" || typeof call === "function") ? call : self;
};
var slicedToArray = function () {
function sliceIterator(arr, i) {
var _arr = [];
var _n = true;
var _d = false;
var _e = undefined;
try {
for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
_arr.push(_s.value);
if (i && _arr.length === i) break;
}
} catch (err) {
_d = true;
_e = err;
} finally {
try {
if (!_n && _i["return"]) _i["return"]();
} finally {
if (_d) throw _e;
}
}
return _arr;
}
return function (arr, i) {
if (Array.isArray(arr)) {
return arr;
} else if (Symbol.iterator in Object(arr)) {
return sliceIterator(arr, i);
} else {
throw new TypeError("Invalid attempt to destructure non-iterable instance");
}
};
}();
var createAnonymousUser = function createAnonymousUser() {
return {
key: uuid()
};
};
var normalizeFlag = function normalizeFlag(flagName, flagValue) {
return [index$3(flagName),
// Multivariate flags contain a string or `null` - `false` seems
// more natural.
flagValue === null ? false : flagValue];
};
var camelCaseFlags = function camelCaseFlags(rawFlags) {
return Object.entries(rawFlags).reduce(function (camelCasedFlags, _ref) {
var _ref2 = slicedToArray(_ref, 2),
flagName = _ref2[0],
flagValue = _ref2[1];
var _normalizeFlag = normalizeFlag(flagName, flagValue),
_normalizeFlag2 = slicedToArray(_normalizeFlag, 2),
normalzedFlagName = _normalizeFlag2[0],
normalzedFlagValue = _normalizeFlag2[1];
// Can't return expression as it is the assigned value
camelCasedFlags[normalzedFlagName] = normalzedFlagValue;
return camelCasedFlags;
}, {});
};
var initialize = function initialize(_ref3) {
var clientSideId = _ref3.clientSideId,
user = _ref3.user;
return index.initialize(clientSideId, user || createAnonymousUser());
};
var flagUpdates = function flagUpdates(_ref4) {
var rawFlags = _ref4.rawFlags,
client = _ref4.client,
updateFlags = _ref4.updateFlags;
var _loop = function _loop(flagName) {
if (Object.prototype.hasOwnProperty.call(rawFlags, flagName)) {
client.on('change:' + flagName, function (flagValue) {
var _normalizeFlag3 = normalizeFlag(flagName, flagValue),
_normalizeFlag4 = slicedToArray(_normalizeFlag3, 2),
normalzedFlagName = _normalizeFlag4[0],
normalzedFlagValue = _normalizeFlag4[1];
updateFlags(defineProperty({}, normalzedFlagName, normalzedFlagValue));
});
}
};
// Dispatch whenever configured flag value changes
for (var flagName in rawFlags) {
_loop(flagName);
}
};
var listen = function listen(_ref5) {
var client = _ref5.client,
updateFlags = _ref5.updateFlags,
updateStatus = _ref5.updateStatus;
client.on('ready', function () {
updateStatus({ isReady: true });
var rawFlags = client.allFlags();
var camelCasedFlags = camelCaseFlags(rawFlags);
updateFlags(camelCasedFlags);
flagUpdates({ rawFlags: rawFlags, client: client, updateFlags: updateFlags });
});
};
// Actions
var UPDATE_FLAGS = '@flopflip/flags/update';
var initialState = {};
// Reducer
function reducer() {
var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState;
var action = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
switch (action.type) {
case UPDATE_FLAGS:
return _extends({}, state, action.payload);
default:
return state;
}
}
// Action Creators
var update = function update(flags) {
return {
type: UPDATE_FLAGS,
payload: flags
};
};
// Actions
var UPDATE_STATUS = '@flopflip/status/update';
var initialState$1 = { isReady: false };
// Reducer
function reducer$1() {
var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState$1;
var action = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
switch (action.type) {
case UPDATE_STATUS:
return _extends({}, state, {
isReady: action.payload.isReady
});
default:
return state;
}
}
// Action Creators
var update$1 = function update(status) {
return {
type: UPDATE_STATUS,
payload: status
};
};
var flopflipReducer = combineReducers({
flags: reducer,
status: reducer$1
});
function createFlopFlipEnhancer(clientSideId, user) {
var client = initialize({ clientSideId: clientSideId, user: user });
return function (next) {
return function () {
var store = next.apply(undefined, arguments);
listen({
client: client,
updateFlags: store.dispatch(update),
updateStatus: store.dispatch(update$1)
});
return store;
};
};
}
var STATE_SLICE = '@flopflip';
var FeatureToggled = function (_React$Component) {
inherits(FeatureToggled, _React$Component);
function FeatureToggled() {
classCallCheck(this, FeatureToggled);
return possibleConstructorReturn(this, (FeatureToggled.__proto__ || Object.getPrototypeOf(FeatureToggled)).apply(this, arguments));
}
createClass(FeatureToggled, [{
key: 'render',
value: function render() {
if (this.props.isFeatureEnabled) {
return this.props.children;
}
return this.props.untoggledComponent;
}
}]);
return FeatureToggled;
}(React.Component);
FeatureToggled.defaultProps = {
untoggledComponent: null
};
var featureToggled = connect(function (state, ownProps) {
return {
isFeatureEnabled: Boolean(state[STATE_SLICE].flags[ownProps.flag])
};
})(FeatureToggled);
/**
* Copyright (c) 2013-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @typechecks
*
*/
/*eslint-disable no-self-compare */
/**
* Copyright 2015, Yahoo! Inc.
* Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
*/
var index$5 = createCommonjsModule(function (module, exports) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var createChangeEmitter = exports.createChangeEmitter = function createChangeEmitter() {
var currentListeners = [];
var nextListeners = currentListeners;
function ensureCanMutateNextListeners() {
if (nextListeners === currentListeners) {
nextListeners = currentListeners.slice();
}
}
function listen(listener) {
if (typeof listener !== 'function') {
throw new Error('Expected listener to be a function.');
}
var isSubscribed = true;
ensureCanMutateNextListeners();
nextListeners.push(listener);
return function () {
if (!isSubscribed) {
return;
}
isSubscribed = false;
ensureCanMutateNextListeners();
var index = nextListeners.indexOf(listener);
nextListeners.splice(index, 1);
};
}
function emit() {
currentListeners = nextListeners;
var listeners = currentListeners;
for (var i = 0; i < listeners.length; i++) {
listeners[i].apply(listeners, arguments);
}
}
return {
listen: listen,
emit: emit
};
};
});
var ponyfill = createCommonjsModule(function (module, exports) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports['default'] = symbolObservablePonyfill;
function symbolObservablePonyfill(root) {
var result;
var _Symbol = root.Symbol;
if (typeof _Symbol === 'function') {
if (_Symbol.observable) {
result = _Symbol.observable;
} else {
result = _Symbol('observable');
_Symbol.observable = result;
}
} else {
result = '@@observable';
}
return result;
}
});
var index$8 = createCommonjsModule(function (module, exports) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _ponyfill2 = _interopRequireDefault(ponyfill);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
var root; /* global window */
if (typeof self !== 'undefined') {
root =