Comparing version 0.0.6 to 0.1.0
891
lib/Bling.js
@@ -5,14 +5,9 @@ Object.defineProperty(exports, "__esModule", { | ||
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 _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; }; | ||
var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; | ||
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; }; }(); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } | ||
var _class, _temp2; /* eslint-disable react/sort-comp */ | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
function _inherits(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; } | ||
/* eslint-disable react/sort-comp */ | ||
var _react = require("react"); | ||
@@ -22,2 +17,40 @@ | ||
var _reactDom = require("react-dom"); | ||
var _reactDom2 = _interopRequireDefault(_reactDom); | ||
var _deepEqual = require("deep-equal"); | ||
var _deepEqual2 = _interopRequireDefault(_deepEqual); | ||
var _invariant = require("fbjs/lib/invariant"); | ||
var _invariant2 = _interopRequireDefault(_invariant); | ||
var _immutable = require("immutable"); | ||
var _immutable2 = _interopRequireDefault(_immutable); | ||
var _hoistNonReactStatics = require("hoist-non-react-statics"); | ||
var _hoistNonReactStatics2 = _interopRequireDefault(_hoistNonReactStatics); | ||
var _Events = require("./Events"); | ||
var _Events2 = _interopRequireDefault(_Events); | ||
var _immutableHelper = require("./utils/immutableHelper"); | ||
var _createManager = require("./createManager"); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
function _possibleConstructorReturn(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; } | ||
function _inherits(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; } | ||
/** | ||
@@ -29,56 +62,55 @@ * An Ad Component using Google Publisher Tags. | ||
* @module Bling | ||
* @class Bling | ||
* @fires Bling#Events.READY | ||
* @fires Bling#Events.SLOT_RENDER_ENDED | ||
* @fires Bling#Events.IMPRESSION_VIEWABLE | ||
* @fires Bling#Events.SLOT_VISIBILITY_CHANGED | ||
*/ | ||
var adCnt = 0; | ||
var generateDivId = function generateDivId() { | ||
return "ad-" + ++adCnt + "-" + Date.now(); | ||
}; | ||
var promise = undefined; | ||
var Bling = (function (_Component) { | ||
var Bling = (_temp2 = _class = function (_Component) { | ||
_inherits(Bling, _Component); | ||
function Bling() { | ||
var _this = this; | ||
var _Object$getPrototypeO; | ||
var _temp, _this, _ret; | ||
_classCallCheck(this, Bling); | ||
_get(Object.getPrototypeOf(Bling.prototype), "constructor", this).apply(this, arguments); | ||
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { | ||
args[_key] = arguments[_key]; | ||
} | ||
this.state = { | ||
return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_Object$getPrototypeO = Object.getPrototypeOf(Bling)).call.apply(_Object$getPrototypeO, [this].concat(args))), _this), _this.state = { | ||
scriptLoaded: false, | ||
rendered: false, | ||
invalidated: false | ||
}; | ||
this._handleMediaQueryChange = function () { | ||
_this.setState({ invalidated: true }); | ||
}; | ||
inViewport: false | ||
}, _temp), _possibleConstructorReturn(_this, _ret); | ||
} | ||
/** | ||
* An array of prop names which can reflect to the ad by calling `refresh`. | ||
* | ||
* @property refreshableProps | ||
* @static | ||
*/ | ||
/** | ||
* An array of prop names which requires to create a new ad slot and render as a new ad. | ||
* | ||
* @property reRenderProps | ||
* @static | ||
*/ | ||
/** | ||
* An instance of ad manager. | ||
* | ||
* @property _adManager | ||
* @private | ||
* @static | ||
*/ | ||
_createClass(Bling, [{ | ||
key: "componentDidMount", | ||
value: function componentDidMount() { | ||
var _this2 = this; | ||
// add itself to static list | ||
var mountedInstances = this.constructor.getMountedInstances(); | ||
mountedInstances.push(this); | ||
// listen for media query change | ||
var sizeMapping = this.props.sizeMapping; | ||
if (sizeMapping && Array.isArray(sizeMapping)) { | ||
sizeMapping.forEach(function (size) { | ||
var viewportWidth = size.viewport && size.viewport[0]; | ||
if (viewportWidth) { | ||
if (!_this2._mqls) { | ||
_this2._mqls = []; | ||
} | ||
var mql = window.matchMedia("(min-width: " + viewportWidth + "px)"); | ||
mql.addListener(_this2._handleMediaQueryChange); | ||
_this2._mqls.push(mql); | ||
} | ||
}); | ||
} | ||
// load seed file | ||
this._load().then(this._onScriptLoaded.bind(this))["catch"](this._onScriptError.bind(this)); | ||
Bling._adManager.addInstance(this); | ||
Bling._adManager.load(this.props.seedFileUrl).then(this.onScriptLoaded.bind(this)).catch(this.onScriptError.bind(this)); | ||
} | ||
@@ -88,8 +120,45 @@ }, { | ||
value: function shouldComponentUpdate(nextProps, nextState) { | ||
var shouldRender = this.props.invalidated !== nextProps.invalidated; // external state change (route change, etc) | ||
if (this.state.rendered && nextState.rendered && nextState.invalidated) { | ||
// internal state change (media query change) | ||
this._googletag.cmd.push(this._refresh.bind(this)); | ||
// if adUnitPath changes, need to create a new slot, re-render | ||
// otherwise, just refresh | ||
var scriptLoaded = nextState.scriptLoaded; | ||
var inViewport = nextState.inViewport; | ||
var notInViewport = this.notInViewport(nextProps, nextState); | ||
var inViewportChanged = this.state.inViewport !== inViewport; | ||
var isScriptLoaded = this.state.scriptLoaded !== scriptLoaded; | ||
// Exit early for visibility change, before executing deep equality check. | ||
if (notInViewport) { | ||
return false; | ||
} else if (inViewportChanged) { | ||
return true; | ||
} | ||
return !nextState.rendered || shouldRender; | ||
var refreshableProps = this.filterProps(Bling.refreshableProps, this.props, nextProps); | ||
var reRenderProps = this.filterProps(Bling.reRenderProps, this.props, nextProps); | ||
var shouldRender = !(0, _deepEqual2.default)(reRenderProps.next, reRenderProps.current); | ||
var shouldRefresh = !shouldRender && !(0, _deepEqual2.default)(refreshableProps.next, refreshableProps.current); | ||
//console.log(`shouldRefresh: ${shouldRefresh}, shouldRender: ${shouldRender}, isScriptLoaded: ${isScriptLoaded}, syncCorrelator: ${Bling._adManager.syncCorrelator}`); | ||
if (shouldRefresh) { | ||
this.configureSlot(this._adSlot, nextProps); | ||
} | ||
if (Bling._adManager._syncCorrelator) { | ||
if (shouldRefresh) { | ||
Bling._adManager.refresh(); | ||
} else if (shouldRender || isScriptLoaded) { | ||
Bling._adManager.renderAll(); | ||
} | ||
} else { | ||
if (shouldRefresh) { | ||
this.refresh(); | ||
return false; | ||
} | ||
if (shouldRender || isScriptLoaded) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
@@ -99,19 +168,10 @@ }, { | ||
value: function componentDidUpdate() { | ||
var _this3 = this; | ||
if (this.state.scriptLoaded) { | ||
// now render ad within the rendered div. | ||
if (!this.props.invalidated) { | ||
(function () { | ||
var mountedInstances = _this3.constructor.getMountedInstances(); | ||
var index = mountedInstances.indexOf(_this3); | ||
// the first registered(executing) component is responsible for updating correlator value for the page. | ||
_this3._googletag.cmd.push(function () { | ||
if (index === 0) { | ||
// only update correlator when considered to be a new page. | ||
_this3._googletag.pubads().updateCorrelator(); | ||
} | ||
_this3._render(); | ||
}); | ||
})(); | ||
if (this.notInViewport(this.props, this.state)) { | ||
return; | ||
} | ||
if (this._divId) { | ||
if (Bling._adManager._initialRender) { | ||
Bling._adManager.render(); | ||
} else { | ||
this.renderAd(); | ||
} | ||
@@ -123,211 +183,602 @@ } | ||
value: function componentWillUnmount() { | ||
var _this4 = this; | ||
// remove itself from static list | ||
var mountedInstances = this.constructor.getMountedInstances(), | ||
index = mountedInstances.indexOf(this); | ||
mountedInstances.splice(index, 1); | ||
// remove media query listener | ||
if (this._mqls) { | ||
this._mqls.forEach(function (mql) { | ||
mql.removeListener(_this4._handleMediaQueryChange); | ||
}); | ||
this._mqls = null; | ||
} | ||
Bling._adManager.removeInstance(this); | ||
this._adSlot = null; | ||
} | ||
}, { | ||
key: "_load", | ||
value: function _load() { | ||
var _this5 = this; | ||
key: "onScriptLoaded", | ||
value: function onScriptLoaded() { | ||
var _props = this.props; | ||
var renderWhenViewable = _props.renderWhenViewable; | ||
var onScriptLoaded = _props.onScriptLoaded; | ||
return promise || (promise = new Promise(function (resolve, reject) { | ||
if (window.googletag) { | ||
resolve(window.googletag); | ||
} else { | ||
var script = document.createElement("script"); | ||
script.onload = function () { | ||
resolve(window.googletag); | ||
}; | ||
script.onerror = reject; | ||
script.src = _this5.props.seedFileUrl; | ||
document.head.appendChild(script); | ||
} | ||
})); | ||
} | ||
}, { | ||
key: "_onScriptLoaded", | ||
value: function _onScriptLoaded(googletag) { | ||
var _this6 = this; | ||
this._googletag = this._googletag || googletag; | ||
this._googletag.cmd.push(function () { | ||
_this6._pubService = _this6._googletag.pubads(); | ||
Bling.listen("slotRenderEnded", _this6._pubService); | ||
_this6.setState({ scriptLoaded: true }); | ||
}); | ||
if (renderWhenViewable) { | ||
this.foldCheck(); | ||
} | ||
this.setState({ scriptLoaded: true }, onScriptLoaded); // eslint-disable-line react/no-did-mount-set-state | ||
} | ||
}, { | ||
key: "_onScriptError", | ||
value: function _onScriptError(error) { | ||
console.warn("Ad: Failed to load gpt", error); | ||
key: "onScriptError", | ||
value: function onScriptError() { | ||
console.warn("Ad: Failed to load gpt for " + this.props.seedFileUrl); | ||
} | ||
}, { | ||
key: "_refresh", | ||
value: function _refresh() { | ||
this._googletag.pubads().refresh([this._adSlot]); | ||
// mark the refresh is done. | ||
if (!this.state.invalidated) { | ||
this.setState({ invalidated: false }); | ||
key: "foldCheck", | ||
value: function foldCheck() { | ||
if (this.state.inViewport) { | ||
return; | ||
} | ||
var slotSize = this.getSlotSize(); | ||
if (Array.isArray(slotSize) && Array.isArray(slotSize[0])) { | ||
slotSize = slotSize[0]; | ||
} | ||
if (slotSize === "fluid") { | ||
slotSize = [0, 0]; | ||
} | ||
var inViewport = Bling._adManager.isInViewport(_reactDom2.default.findDOMNode(this), slotSize); | ||
if (inViewport) { | ||
this.setState({ inViewport: true }); | ||
} | ||
} | ||
}, { | ||
key: "_defineSizeMapping", | ||
value: function _defineSizeMapping(adSlot, sizeMapping) { | ||
key: "filterProps", | ||
value: function filterProps(propList, props, nextProps) { | ||
var _this2 = this; | ||
return propList.reduce(function (filtered, key) { | ||
var nonEqual = false; | ||
if ((0, _immutableHelper.isImmutableListOrMap)(nextProps[key]) && (0, _immutableHelper.isImmutableListOrMap)(props[key])) { | ||
nonEqual = !_immutable2.default.is(nextProps[key], _this2.props[key]); | ||
if (!nonEqual) { | ||
// makes deep equality check cheap | ||
filtered.next[key] = filtered.current[key] = 0; | ||
} | ||
} else if ((0, _immutableHelper.isImmutableListOrMap)(nextProps[key]) || (0, _immutableHelper.isImmutableListOrMap)(props[key])) { | ||
nonEqual = true; | ||
} else { | ||
filtered.next[key] = nextProps[key]; | ||
filtered.current[key] = props[key]; | ||
} | ||
if (nonEqual) { | ||
// makes deep equality check cheap | ||
filtered.next[key] = 0; | ||
filtered.current[key] = 1; | ||
} | ||
return filtered; | ||
}, { | ||
next: {}, | ||
current: {} | ||
}); | ||
} | ||
}, { | ||
key: "defineSizeMapping", | ||
value: function defineSizeMapping(adSlot, sizeMapping) { | ||
if (sizeMapping) { | ||
adSlot.defineSizeMapping(sizeMapping.reduce(function (mapping, size) { | ||
var sizeMappingArray = (0, _immutableHelper.toJS)(sizeMapping).reduce(function (mapping, size) { | ||
return mapping.addSize(size.viewport, size.slot); | ||
}, this._googletag.sizeMapping()).build()); | ||
}, Bling._adManager.googletag.sizeMapping()).build(); | ||
adSlot.defineSizeMapping(sizeMappingArray); | ||
} | ||
} | ||
}, { | ||
key: "_setTargeting", | ||
value: function _setTargeting(adSlot, targeting) { | ||
key: "setTargeting", | ||
value: function setTargeting(adSlot, targeting) { | ||
adSlot.clearTargeting(); | ||
if (targeting) { | ||
for (var key in targeting) { | ||
if (targeting.hasOwnProperty(key)) { | ||
adSlot.setTargeting(key, targeting[key]); | ||
} | ||
} | ||
targeting = (0, _immutableHelper.toJS)(targeting); | ||
Object.keys(targeting).forEach(function (key) { | ||
adSlot.setTargeting(key, targeting[key]); | ||
}); | ||
} | ||
} | ||
}, { | ||
key: "_addCompanionAdService", | ||
value: function _addCompanionAdService(adSlot) { | ||
var companionAdsService = this._googletag.companionAds(); | ||
key: "addCompanionAdService", | ||
value: function addCompanionAdService(serviceConfig, adSlot) { | ||
var companionAdsService = Bling._adManager.googletag.companionAds(); | ||
adSlot.addService(companionAdsService); | ||
companionAdsService.setRefreshUnfilledSlots(true); | ||
this._googletag.enableServices(); | ||
if ((typeof serviceConfig === "undefined" ? "undefined" : _typeof(serviceConfig)) === "object") { | ||
if (serviceConfig.hasOwnProperty("enableSyncLoading")) { | ||
companionAdsService.enableSyncLoading(); | ||
} | ||
if (serviceConfig.hasOwnProperty("refreshUnfilledSlots")) { | ||
companionAdsService.setRefreshUnfilledSlots(serviceConfig.refreshUnfilledSlots); | ||
} | ||
} | ||
} | ||
}, { | ||
key: "_render", | ||
value: function _render() { | ||
var _props = this.props; | ||
var adUnitPath = _props.adUnitPath; | ||
var slotSize = _props.slotSize; | ||
var sizeMapping = _props.sizeMapping; | ||
var collapseEmptyDiv = _props.collapseEmptyDiv; | ||
var targeting = _props.targeting; | ||
var companionAd = _props.companionAd; | ||
key: "getSlotSize", | ||
value: function getSlotSize() { | ||
var _props2 = this.props; | ||
var origSlotSize = _props2.slotSize; | ||
var origSizeMapping = _props2.sizeMapping; | ||
var pubService = this._googletag.pubads(); | ||
var slotSize = void 0; | ||
if (origSlotSize) { | ||
slotSize = (0, _immutableHelper.toJS)(origSlotSize); | ||
} else if (origSizeMapping) { | ||
var sizeMapping = (0, _immutableHelper.toJS)(origSizeMapping); | ||
slotSize = sizeMapping[0] && sizeMapping[0].slot; | ||
} | ||
return slotSize; | ||
} | ||
}, { | ||
key: "renderAd", | ||
value: function renderAd() { | ||
this.defineSlot(); | ||
this.display(); | ||
} | ||
}, { | ||
key: "notInViewport", | ||
value: function notInViewport() { | ||
var props = arguments.length <= 0 || arguments[0] === undefined ? this.props : arguments[0]; | ||
var state = arguments.length <= 1 || arguments[1] === undefined ? this.state : arguments[1]; | ||
var renderWhenViewable = props.renderWhenViewable; | ||
var inViewport = state.inViewport; | ||
return renderWhenViewable && !inViewport; | ||
} | ||
}, { | ||
key: "defineSlot", | ||
value: function defineSlot() { | ||
var _props3 = this.props; | ||
var adUnitPath = _props3.adUnitPath; | ||
var interstitial = _props3.interstitial; | ||
var divId = this._divId; | ||
var adSlot = this._googletag.defineSlot(adUnitPath, slotSize || [], divId); | ||
var slotSize = this.getSlotSize(); | ||
this._defineSizeMapping(adSlot, sizeMapping); | ||
if (!this._adSlot) { | ||
if (interstitial) { | ||
this._adSlot = Bling._adManager.googletag.defineOutOfPageSlot(adUnitPath, divId); | ||
} else { | ||
this._adSlot = Bling._adManager.googletag.defineSlot(adUnitPath, slotSize || [], divId); | ||
} | ||
} | ||
adSlot.addService(pubService); | ||
this.configureSlot(this._adSlot); | ||
} | ||
}, { | ||
key: "configureSlot", | ||
value: function configureSlot(adSlot) { | ||
var props = arguments.length <= 1 || arguments[1] === undefined ? this.props : arguments[1]; | ||
var sizeMapping = props.sizeMapping; | ||
var targeting = props.targeting; | ||
var companionAdService = props.companionAdService; | ||
var categoryExclusion = props.categoryExclusion; | ||
var content = props.content; | ||
var clickUrl = props.clickUrl; | ||
var forceSafeFrame = props.forceSafeFrame; | ||
var collapseEmptyDiv = props.collapseEmptyDiv; | ||
var attributes = props.attributes; | ||
var safeFrameConfig = props.safeFrameConfig; | ||
adSlot.setCollapseEmptyDiv(collapseEmptyDiv); | ||
this._setTargeting(adSlot, targeting); | ||
this.defineSizeMapping(adSlot, sizeMapping); | ||
if (!this._adSlot) { | ||
pubService.enableAsyncRendering(); | ||
if (collapseEmptyDiv !== undefined) { | ||
collapseEmptyDiv = (0, _immutableHelper.toJS)(collapseEmptyDiv); | ||
if (Array.isArray(collapseEmptyDiv)) { | ||
var _adSlot$setCollapseEm; | ||
(_adSlot$setCollapseEm = adSlot.setCollapseEmptyDiv).call.apply(_adSlot$setCollapseEm, [adSlot].concat(_toConsumableArray(collapseEmptyDiv))); | ||
} else { | ||
adSlot.setCollapseEmptyDiv(collapseEmptyDiv); | ||
} | ||
} | ||
// Enables all Google Publisher Tag services that have been defined for ad slots on the page. | ||
// This is only needed once per page but including it multiple times will not cause any harm. | ||
this._googletag.enableServices(); | ||
this._googletag.display(divId); | ||
// Overrides click url | ||
if (clickUrl) { | ||
adSlot.setClickUrl(clickUrl); | ||
} | ||
if (companionAd) { | ||
this._addCompanionAdService(adSlot); | ||
// Sets category exclusion | ||
if (categoryExclusion) { | ||
var exclusion = (0, _immutableHelper.toJS)(categoryExclusion); | ||
if (typeof exclusion === "string") { | ||
exclusion = [exclusion]; | ||
} | ||
adSlot.clearCategoryExclusions(); | ||
exclusion.forEach(function (item) { | ||
adSlot.setCategoryExclusion(item); | ||
}); | ||
} | ||
this._adSlot = adSlot; | ||
// Sets AdSense attributes | ||
if (attributes) { | ||
attributes = (0, _immutableHelper.toJS)(attributes); | ||
Object.keys(attributes).forEach(function (key) { | ||
adSlot.set(key, attributes[key]); | ||
}); | ||
} | ||
// When the size mapping is configured not to render ad with the viewport in initial render, | ||
// GPT won't render ad and 'slotRenderEnded' is not triggered, so set the 'rendered' state here. | ||
// Not supposed to set state during component rendering life cycle, but ad needs to maintain the states and rendering logic on its own. | ||
if (!this.state.rendered) { | ||
this.setState({ rendered: true }); | ||
if (safeFrameConfig) { | ||
safeFrameConfig = (0, _immutableHelper.toJS)(safeFrameConfig); | ||
adSlot.setSafeFrameConfig(safeFrameConfig); | ||
} | ||
if (forceSafeFrame) { | ||
adSlot.setForceSafeFrame(forceSafeFrame); | ||
} | ||
// Sets custom targeting parameters | ||
this.setTargeting(adSlot, targeting); | ||
// Enables companion ad service | ||
if (companionAdService) { | ||
this.addCompanionAdService(companionAdService, adSlot); | ||
} | ||
// GPT checks if the same service is already added. | ||
if (content) { | ||
adSlot.addService(Bling._adManager.googletag.content()); | ||
} else { | ||
adSlot.addService(Bling._adManager.googletag.pubads()); | ||
} | ||
} | ||
}, { | ||
key: "display", | ||
value: function display() { | ||
var content = this.props.content; | ||
var divId = this._divId; | ||
var adSlot = this._adSlot; | ||
if (content) { | ||
Bling._adManager.googletag.content().setContent(adSlot, content); | ||
} else { | ||
if (!Bling._adManager._disableInitialLoad && !Bling._adManager._syncCorrelator) { | ||
Bling._adManager.updateCorrelator(); | ||
} | ||
Bling._adManager.googletag.display(divId); | ||
if (Bling._adManager._disableInitialLoad && !Bling._adManager._initialRender) { | ||
this.refresh(); | ||
} | ||
} | ||
} | ||
}, { | ||
key: "clear", | ||
value: function clear() { | ||
var adSlot = this._adSlot; | ||
if (adSlot) { | ||
// googletag.ContentService doesn't clear content | ||
var services = adSlot.getServices(); | ||
if (this._divId && services.some(function (s) { | ||
return !!s.setContent; | ||
})) { | ||
document.getElementById(this._divId).innerHTML = ""; | ||
return; | ||
} | ||
Bling._adManager.clear([adSlot]); | ||
} | ||
} | ||
}, { | ||
key: "refresh", | ||
value: function refresh(options) { | ||
var adSlot = this._adSlot; | ||
if (adSlot) { | ||
Bling._adManager.refresh([adSlot], options); | ||
} | ||
} | ||
}, { | ||
key: "render", | ||
value: function render() { | ||
if (!this.props.invalidated) { | ||
this._divId = generateDivId(); | ||
var scriptLoaded = this.state.scriptLoaded; | ||
var interstitial = this.props.interstitial; | ||
var shouldNotRender = this.notInViewport(this.props, this.state); | ||
if (!scriptLoaded || shouldNotRender) { | ||
var slotSize = this.getSlotSize(); | ||
if (!interstitial) { | ||
(0, _invariant2.default)(slotSize, "Either 'slotSize' or 'sizeMapping' prop needs to be set."); | ||
} | ||
if (Array.isArray(slotSize) && Array.isArray(slotSize[0])) { | ||
slotSize = slotSize[0]; | ||
} | ||
// https://developers.google.com/doubleclick-gpt/reference?hl=en#googletag.NamedSize | ||
if (slotSize === "fluid") { | ||
slotSize = ["auto", "auto"]; | ||
} | ||
var style = slotSize && { width: slotSize[0], height: slotSize[1] }; | ||
// render node element instead of script element so that `inViewport` check works. | ||
return _react2.default.createElement("div", { style: style }); | ||
} | ||
// when 'invalidated' prop is true, remove the container to clear out an old ad. | ||
// it's followed by 'invalidated' prop set to false, this time renders a new ad. | ||
return this.props.invalidated ? null : _react2["default"].createElement("div", { id: this._divId }); | ||
// clear the current ad if exists | ||
this.clear(); | ||
if (this._adSlot) { | ||
Bling._adManager.googletag.destroySlots([this._adSlot]); | ||
this._adSlot = null; | ||
} | ||
this._divId = this._adSlot ? this._adSlot.getSlotElementId() : Bling._adManager.generateDivId(); | ||
return _react2.default.createElement("div", { id: this._divId }); | ||
} | ||
}, { | ||
key: "adSlot", | ||
get: function get() { | ||
return this._adSlot; | ||
} | ||
}], [{ | ||
key: "clearMountedInstances", | ||
value: function clearMountedInstances() { | ||
Bling.mountedInstances = []; | ||
key: "on", | ||
value: function on(eventType, cb) { | ||
Bling._on("on", eventType, cb); | ||
} | ||
}, { | ||
key: "getMountedInstances", | ||
value: function getMountedInstances() { | ||
if (!Bling.mountedInstances) { | ||
Bling.mountedInstances = []; | ||
} | ||
return Bling.mountedInstances; | ||
key: "once", | ||
value: function once(eventType, cb) { | ||
Bling._on("once", eventType, cb); | ||
} | ||
}, { | ||
key: "listen", | ||
value: function listen(eventName, pubService) { | ||
if (!Bling._listening && pubService) { | ||
pubService.addEventListener(eventName, Bling._onAdRendered.bind(Bling)); | ||
Bling._listening = true; | ||
} | ||
key: "removeListener", | ||
value: function removeListener() { | ||
var _Bling$_adManager; | ||
(_Bling$_adManager = Bling._adManager).removeListener.apply(_Bling$_adManager, arguments); | ||
} | ||
}, { | ||
key: "_onAdRendered", | ||
value: function _onAdRendered(event) { | ||
var instances = Bling.getMountedInstances(); | ||
var slot = event.slot; | ||
var instance = instances.filter(function (inst) { | ||
return slot === inst._adSlot; | ||
}); | ||
if (instance && instance[0] && instance[0].props.onRendered) { | ||
instance[0].props.onRendered(event); | ||
key: "removeAllListeners", | ||
value: function removeAllListeners() { | ||
var _Bling$_adManager2; | ||
(_Bling$_adManager2 = Bling._adManager).removeAllListeners.apply(_Bling$_adManager2, arguments); | ||
} | ||
}, { | ||
key: "_on", | ||
value: function _on(fn, eventType, cb) { | ||
if (typeof cb !== "function") { | ||
return; | ||
} | ||
if (eventType === _Events2.default.READY && Bling._adManager.isReady) { | ||
cb.call(Bling._adManager, Bling._adManager.googletag); | ||
} else { | ||
Bling._adManager[fn](eventType, cb); | ||
} | ||
} | ||
/** | ||
* Returns the GPT version. | ||
* | ||
* @method getGPTVersion | ||
* @returns {Number|boolean} a version or false if GPT is not yet ready. | ||
* @static | ||
*/ | ||
}, { | ||
key: "propTypes", | ||
value: { | ||
seedFileUrl: _react.PropTypes.string, | ||
adUnitPath: _react.PropTypes.string.isRequired, | ||
targeting: _react.PropTypes.object, | ||
slotSize: _react.PropTypes.array, | ||
sizeMapping: _react.PropTypes.arrayOf(_react.PropTypes.shape({ | ||
viewport: _react.PropTypes.array, | ||
slot: _react.PropTypes.array | ||
})), | ||
companionAd: _react.PropTypes.bool, | ||
collapseEmptyDiv: _react.PropTypes.bool, | ||
onRendered: _react.PropTypes.func, | ||
invalidated: _react.PropTypes.bool | ||
}, | ||
enumerable: true | ||
key: "getGPTVersion", | ||
value: function getGPTVersion() { | ||
return Bling._adManager.getGPTVersion(); | ||
} | ||
/** | ||
* Returns the Pubads Service version. | ||
* | ||
* @method getPubadsVersion | ||
* @returns {Number|boolean} a version or false if Pubads Service is not yet ready. | ||
* @static | ||
*/ | ||
}, { | ||
key: "defaultProps", | ||
value: { | ||
seedFileUrl: "//www.googletagservices.com/tag/js/gpt.js", | ||
companionAd: false, | ||
collapseEmptyDiv: true, | ||
invalidated: false | ||
}, | ||
enumerable: true | ||
key: "getPubadsVersion", | ||
value: function getPubadsVersion() { | ||
return Bling._adManager.getPubadsVersion(); | ||
} | ||
/** | ||
* Sets a flag to indicate whether the correlator value should always be same across the ads in the page or not. | ||
* | ||
* @method syncCorrelator | ||
* @param {boolean} value | ||
* @static | ||
*/ | ||
}, { | ||
key: "syncCorrelator", | ||
value: function syncCorrelator(value) { | ||
Bling._adManager.syncCorrelator(value); | ||
} | ||
/** | ||
* Trigger re-rendering of all the ads. | ||
* | ||
* @method render | ||
* @static | ||
*/ | ||
}, { | ||
key: "render", | ||
value: function render() { | ||
Bling._adManager.renderAll(); | ||
} | ||
/** | ||
* Refreshes all the ads in the page with a new correlator value. | ||
* | ||
* @param {Array} slots An array of ad slots. | ||
* @param {Object} options You can pass `changeCorrelator` flag. | ||
* @static | ||
*/ | ||
}, { | ||
key: "refresh", | ||
value: function refresh(slots, options) { | ||
Bling._adManager.refresh(slots, options); | ||
} | ||
/** | ||
* Clears the ads for the specified ad slots, if no slots are provided, all the ads will be cleared. | ||
* | ||
* @method clear | ||
* @param {Array} slots An optional array of slots to clear. | ||
* @static | ||
*/ | ||
}, { | ||
key: "clear", | ||
value: function clear(slots) { | ||
Bling._adManager.clear(slots); | ||
} | ||
/** | ||
* Updates the correlator value for the next ad request. | ||
* | ||
* @method updateCorrelator | ||
* @static | ||
*/ | ||
}, { | ||
key: "updateCorrelator", | ||
value: function updateCorrelator() { | ||
Bling._adManager.updateCorrelator(); | ||
} | ||
}]); | ||
return Bling; | ||
})(_react.Component); | ||
}(_react.Component), _class.propTypes = { | ||
/** | ||
* An optional string for GPT seed file url to override. | ||
* | ||
* @property seedFileUrl | ||
*/ | ||
seedFileUrl: _react.PropTypes.string, | ||
/** | ||
* An optional string indicating ad unit path which will be used | ||
* if specified over the rest of the props which constructs 'adUnitPath'. | ||
* | ||
* @property adUnitPath | ||
*/ | ||
adUnitPath: _react.PropTypes.string.isRequired, | ||
/** | ||
* An optional object which includes ad targeting key-value pairs. | ||
* | ||
* @property targeting | ||
*/ | ||
targeting: _react.PropTypes.oneOfType([_react.PropTypes.object, _react.PropTypes.instanceOf(_immutable2.default.Map)]), | ||
/** | ||
* An optional array of width and height size for the ad slot. | ||
* This will be preceded by the sizeMapping if specified. | ||
* | ||
* @property slotSize | ||
*/ | ||
slotSize: _react.PropTypes.oneOfType([_react.PropTypes.array, _react.PropTypes.instanceOf(_immutable2.default.List)]), | ||
/** | ||
* An optional array of object which contains an array of viewport size and slot size. | ||
* This needs to be set if the ad needs to serve different ad sizes per different viewport sizes (responsive ad). | ||
* If the empty array is provided as an ad slot for the particular viewport size, the ad won't be served for the viewport size. | ||
* The ad slot size which is provided for the viewport size of [0, 0] will be used as default ad size if none of viewport size matches. | ||
* | ||
* https://support.google.com/dfp_premium/answer/3423562?hl=en | ||
* | ||
* e.g. | ||
* | ||
* sizeMapping={[ | ||
* {viewport: [0, 0], slot: [320, 50]}, | ||
* {viewport: [768, 0], slot: [728, 90]} | ||
* ]} | ||
* | ||
* @property sizeMapping | ||
*/ | ||
sizeMapping: _react.PropTypes.oneOfType([_react.PropTypes.arrayOf(_react.PropTypes.shape({ | ||
viewport: _react.PropTypes.array, | ||
slot: _react.PropTypes.array | ||
})), _react.PropTypes.instanceOf(_immutable2.default.List)]), | ||
/** | ||
* An optional flag to indicate whether an ad slot should be out-of-page(interstitial) slot. | ||
* | ||
* @property interstitial | ||
*/ | ||
interstitial: _react.PropTypes.bool, | ||
/** | ||
* An optional flag to indicate whether companion ad service should be enabled for the ad. | ||
* If an object is passed, it takes as a configuration expecting `enableSyncLoading` or `refreshUnfilledSlots`. | ||
* | ||
* @property companionAdService | ||
*/ | ||
companionAdService: _react.PropTypes.oneOfType([_react.PropTypes.bool, _react.PropTypes.oneOfType([_react.PropTypes.object, _react.PropTypes.instanceOf(_immutable2.default.Map)])]), | ||
/** | ||
* An optional HTML content for the slot. If specified, the ad will render with the HTML content using content service. | ||
* | ||
* @property content | ||
*/ | ||
content: _react.PropTypes.string, | ||
/** | ||
* An optional click through URL. If specified, any landing page URL associated with the creative that is served is overridden. | ||
* | ||
* @property clickUrl | ||
*/ | ||
clickUrl: _react.PropTypes.string, | ||
/** | ||
* An optional string or an array of string which specifies a page-level ad category exclusion for the given label name. | ||
* | ||
* @property categoryExclusion | ||
*/ | ||
categoryExclusion: _react.PropTypes.oneOfType([_react.PropTypes.string, _react.PropTypes.oneOfType([_react.PropTypes.array, _react.PropTypes.instanceOf(_immutable2.default.List)])]), | ||
/** | ||
* An optional map of key-value pairs for an AdSense attribute on a particular ad slot. | ||
* see the list of supported key value: https://developers.google.com/doubleclick-gpt/adsense_attributes#adsense_parameters.googletag.Slot | ||
* | ||
* @property attributes | ||
*/ | ||
attributes: _react.PropTypes.oneOfType([_react.PropTypes.object, _react.PropTypes.instanceOf(_immutable2.default.Map)]), | ||
/** | ||
* An optional flag to indicate whether an empty ad should be collapsed or not. | ||
* | ||
* @property collapseEmptyDiv | ||
*/ | ||
collapseEmptyDiv: _react.PropTypes.oneOfType([_react.PropTypes.bool, _react.PropTypes.arrayOf(_react.PropTypes.bool)]), | ||
/** | ||
* An optional flag to indicate whether ads in this slot should be forced to be rendered using a SafeFrame container. | ||
* | ||
* @property forceSafeFrame | ||
*/ | ||
forceSafeFrame: _react.PropTypes.bool, | ||
/** | ||
* An optional object to set the slot-level preferences for SafeFrame configuration. | ||
* | ||
* @property safeFrameConfig | ||
*/ | ||
safeFrameConfig: _react.PropTypes.oneOfType([_react.PropTypes.object, _react.PropTypes.instanceOf(_immutable2.default.Map)]), | ||
/** | ||
* An optional event handler function for `googletag.events.SlotRenderEndedEvent`. | ||
* | ||
* @property onSlotRenderEnded | ||
*/ | ||
onSlotRenderEnded: _react.PropTypes.func, | ||
/** | ||
* An optional event handler function for `googletag.events.ImpressionViewableEvent`. | ||
* | ||
* @property onImpressionViewable | ||
*/ | ||
onImpressionViewable: _react.PropTypes.func, | ||
/** | ||
* An optional event handler function for `googletag.events.slotVisibilityChangedEvent`. | ||
* | ||
* @property onSlotVisibilityChanged | ||
*/ | ||
onSlotVisibilityChanged: _react.PropTypes.func, | ||
/** | ||
* An optional flag to indicate whether an ad should only render when it's fully in the viewport area. Default is `true`. | ||
* | ||
* @property renderWhenViewable | ||
*/ | ||
renderWhenViewable: _react.PropTypes.bool, | ||
/** | ||
* An optional call back function to notify when the script is loaded. | ||
* | ||
* @property onScriptLoaded | ||
*/ | ||
onScriptLoaded: _react.PropTypes.func | ||
}, _class.defaultProps = { | ||
seedFileUrl: "//www.googletagservices.com/tag/js/gpt.js", | ||
renderWhenViewable: true | ||
}, _class.refreshableProps = ["targeting", "sizeMapping", "clickUrl", "categoryExclusion", "attributes", "collapseEmptyDiv", "companionAdService", "forceSafeFrame", "safeFrameConfig"], _class.reRenderProps = ["adUnitPath", "slotSize", "interstitial", "content"], _class._adManager = (0, _createManager.createManager)(), _temp2); | ||
exports["default"] = Bling; | ||
module.exports = exports["default"]; | ||
// proxy pubads API through Bling | ||
exports.default = (0, _hoistNonReactStatics2.default)(Bling, _createManager.pubadsAPI.reduce(function (api, method) { | ||
api[method] = function () { | ||
for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { | ||
args[_key2] = arguments[_key2]; | ||
} | ||
return Bling._adManager.pubadsProxy({ method: method, args: args }); | ||
}; | ||
return api; | ||
}, {})); |
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
value: true | ||
}); | ||
exports.Events = exports.Bling = undefined; | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } | ||
var _Bling = require("./Bling"); | ||
require("./polyfill"); | ||
Object.defineProperty(exports, "Bling", { | ||
enumerable: true, | ||
get: function get() { | ||
return _interopRequireDefault(_Bling).default; | ||
} | ||
}); | ||
var _NFLBling = require("./NFLBling"); | ||
var _Events = require("./Events"); | ||
var _NFLBling2 = _interopRequireDefault(_NFLBling); | ||
Object.defineProperty(exports, "Events", { | ||
enumerable: true, | ||
get: function get() { | ||
return _interopRequireDefault(_Events).default; | ||
} | ||
}); | ||
var _Bling = require("./Bling"); | ||
require("./polyfill"); | ||
var _Bling2 = _interopRequireDefault(_Bling); | ||
exports["default"] = { | ||
NFLBling: _NFLBling2["default"], | ||
Bling: _Bling2["default"] | ||
}; | ||
module.exports = exports["default"]; | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } |
@@ -0,3 +1,7 @@ | ||
require("core-js/fn/array/from"); | ||
require("core-js/fn/object/assign"); | ||
require("core-js/fn/promise"); | ||
require("core-js/fn/promise"); | ||
require("core-js/fn/set"); |
@@ -1,19 +0,57 @@ | ||
## [HEAD] | ||
> Unreleased | ||
## [v2.0.0] | ||
> Feb 4, 2016 | ||
- **Bugfix:** Fix search base logic with an empty query ([#221]) | ||
- **Bugfix:** Fail gracefully when Safari 5 security settings prevent access to window.sessionStorage ([#223]) | ||
[v2.0.0]: https://github.com/reactjs/history/compare/v2.0.0-rc3...v2.0.0 | ||
[#221]: https://github.com/reactjs/history/issues/221 | ||
[#223]: https://github.com/reactjs/history/pull/223 | ||
## [v2.0.0-rc3] | ||
> Feb 3, 2016 | ||
- **Bugfix:** Don't convert same-path `PUSH` to `REPLACE` when `location.state` changes ([#179]) | ||
- **Bugfix:** Re-enable browser history on Chrome iOS ([#208]) | ||
- **Bugfix:** Properly support location descriptors in `history.createLocation` ([#200]) | ||
[v2.0.0-rc3]: https://github.com/reactjs/history/compare/v2.0.0-rc2...v2.0.0-rc3 | ||
[#179]: https://github.com/reactjs/history/pull/179 | ||
[#208]: https://github.com/reactjs/history/pull/208 | ||
[#200]: https://github.com/reactjs/history/pull/200 | ||
## [v2.0.0-rc2] | ||
> Jan 9, 2016 | ||
- Add back deprecation warnings | ||
[v2.0.0-rc2]: https://github.com/reactjs/history/compare/v2.0.0-rc1...v2.0.0-rc2 | ||
## [v2.0.0-rc1] | ||
> Jan 2, 2016 | ||
- **Bugfix:** Don't create empty entries in session storage ([#177]) | ||
[v2.0.0-rc1]: https://github.com/reactjs/history/compare/v1.17.0...v2.0.0-rc1 | ||
[#177]: https://github.com/reactjs/history/pull/177 | ||
## [v1.17.0] | ||
> Dec 19, 2015 | ||
- **Bugfix:** Don't throw in memory history when out of history entries ([#170]) | ||
- **Bugfix:** Fix the deprecation warnings on `createPath` and `createHref` ([#189]) | ||
[HEAD]: https://github.com/rackt/history/compare/latest...HEAD | ||
[#170]: https://github.com/rackt/history/pull/170 | ||
[#189]: https://github.com/rackt/history/pull/189 | ||
[v1.17.0]: https://github.com/reactjs/history/compare/v1.16.0...v1.17.0 | ||
[#170]: https://github.com/reactjs/history/pull/170 | ||
[#189]: https://github.com/reactjs/history/pull/189 | ||
## [v1.16.0] | ||
> Dec 10, 2015 | ||
- **Bugfix:** Silence all warnings that were introduced since 1.13 (see [rackt/react-router#2682]) | ||
- **Bugfix:** Silence all warnings that were introduced since 1.13 (see [reactjs/react-router#2682]) | ||
- **Deprecation:** Deprecate the `createLocation` method in the top-level exports | ||
- **Deprecation:** Deprecate the `state` arg to `history.createLocation` | ||
[v1.16.0]: https://github.com/rackt/history/compare/v1.15.0...v1.16.0 | ||
[rackt/react-router#2682]: https://github.com/rackt/react-router/issues/2682 | ||
[v1.16.0]: https://github.com/reactjs/history/compare/v1.15.0...v1.16.0 | ||
[reactjs/react-router#2682]: https://github.com/reactjs/react-router/issues/2682 | ||
@@ -26,4 +64,4 @@ ## [v1.15.0] | ||
[v1.15.0]: https://github.com/rackt/history/compare/v1.14.0...v1.15.0 | ||
[#173]: https://github.com/rackt/history/pull/173 | ||
[v1.15.0]: https://github.com/reactjs/history/compare/v1.14.0...v1.15.0 | ||
[#173]: https://github.com/reactjs/history/pull/173 | ||
@@ -40,9 +78,9 @@ ## [v1.14.0] | ||
[v1.14.0]: https://github.com/rackt/history/compare/v1.13.1...v1.14.0 | ||
[#121]: https://github.com/rackt/history/issues/121 | ||
[#141]: https://github.com/rackt/history/pull/141 | ||
[#146]: https://github.com/rackt/history/pull/146 | ||
[#152]: https://github.com/rackt/history/pull/152 | ||
[#167]: https://github.com/rackt/history/pull/167 | ||
[#168]: https://github.com/rackt/history/pull/168 | ||
[v1.14.0]: https://github.com/reactjs/history/compare/v1.13.1...v1.14.0 | ||
[#121]: https://github.com/reactjs/history/issues/121 | ||
[#141]: https://github.com/reactjs/history/pull/141 | ||
[#146]: https://github.com/reactjs/history/pull/146 | ||
[#152]: https://github.com/reactjs/history/pull/152 | ||
[#167]: https://github.com/reactjs/history/pull/167 | ||
[#168]: https://github.com/reactjs/history/pull/168 | ||
@@ -56,5 +94,5 @@ ## [v1.13.1] | ||
[v1.13.1]: https://github.com/rackt/history/compare/v1.13.0...v1.13.1 | ||
[#43]: https://github.com/rackt/history/pull/43 | ||
[#139]: https://github.com/rackt/history/pull/139 | ||
[v1.13.1]: https://github.com/reactjs/history/compare/v1.13.0...v1.13.1 | ||
[#43]: https://github.com/reactjs/history/pull/43 | ||
[#139]: https://github.com/reactjs/history/pull/139 | ||
@@ -68,5 +106,5 @@ ## [v1.13.0] | ||
[v1.13.0]: https://github.com/rackt/history/compare/v1.12.6...v1.13.0 | ||
[#108]: https://github.com/rackt/history/pull/108 | ||
[#94]: https://github.com/rackt/history/issues/94 | ||
[v1.13.0]: https://github.com/reactjs/history/compare/v1.12.6...v1.13.0 | ||
[#108]: https://github.com/reactjs/history/pull/108 | ||
[#94]: https://github.com/reactjs/history/issues/94 | ||
@@ -79,4 +117,4 @@ ## [v1.12.6] | ||
[v1.12.6]: https://github.com/rackt/history/compare/v1.12.5...v1.12.6 | ||
[#95]: https://github.com/rackt/history/issues/95 | ||
[v1.12.6]: https://github.com/reactjs/history/compare/v1.12.5...v1.12.6 | ||
[#95]: https://github.com/reactjs/history/issues/95 | ||
@@ -91,4 +129,4 @@ ## [v1.12.5] | ||
[v1.12.5]: https://github.com/rackt/history/compare/v1.12.4...v1.12.5 | ||
[#93]: https://github.com/rackt/history/issues/93 | ||
[v1.12.5]: https://github.com/reactjs/history/compare/v1.12.4...v1.12.5 | ||
[#93]: https://github.com/reactjs/history/issues/93 | ||
@@ -100,4 +138,4 @@ ## [v1.12.4] | ||
[v1.12.4]: https://github.com/rackt/history/compare/v1.12.3...v1.12.4 | ||
[#62]: https://github.com/rackt/history/issues/62 | ||
[v1.12.4]: https://github.com/reactjs/history/compare/v1.12.3...v1.12.4 | ||
[#62]: https://github.com/reactjs/history/issues/62 | ||
@@ -110,5 +148,5 @@ ## [v1.12.3] | ||
[v1.12.3]: https://github.com/rackt/history/compare/v1.12.2...v1.12.3 | ||
[#71]: https://github.com/rackt/history/issues/71 | ||
[#42]: https://github.com/rackt/history/issues/42 | ||
[v1.12.3]: https://github.com/reactjs/history/compare/v1.12.2...v1.12.3 | ||
[#71]: https://github.com/reactjs/history/issues/71 | ||
[#42]: https://github.com/reactjs/history/issues/42 | ||
@@ -120,4 +158,4 @@ ## [v1.12.2] | ||
[v1.12.2]: https://github.com/rackt/history/compare/v1.12.1...v1.12.2 | ||
[#51-comments]: https://github.com/rackt/history/pull/51#issuecomment-143189672 | ||
[v1.12.2]: https://github.com/reactjs/history/compare/v1.12.1...v1.12.2 | ||
[#51-comments]: https://github.com/reactjs/history/pull/51#issuecomment-143189672 | ||
@@ -130,3 +168,3 @@ ## [v1.12.1] | ||
[v1.12.1]: https://github.com/rackt/history/compare/v1.12.0...v1.12.1 | ||
[v1.12.1]: https://github.com/reactjs/history/compare/v1.12.0...v1.12.1 | ||
@@ -139,3 +177,3 @@ ## [v1.12.0] | ||
[v1.12.0]: https://github.com/rackt/history/compare/v1.11.1...v1.12.0 | ||
[v1.12.0]: https://github.com/reactjs/history/compare/v1.11.1...v1.12.0 | ||
@@ -148,4 +186,4 @@ ## [v1.11.1] | ||
[v1.11.1]: https://github.com/rackt/history/compare/v1.11.0...v1.11.1 | ||
[#68]: https://github.com/rackt/history/issues/68 | ||
[v1.11.1]: https://github.com/reactjs/history/compare/v1.11.0...v1.11.1 | ||
[#68]: https://github.com/reactjs/history/issues/68 | ||
@@ -162,2 +200,2 @@ ## [v1.11.0] | ||
[v1.11.0]: https://github.com/rackt/history/compare/v1.10.2...v1.11.0 | ||
[v1.11.0]: https://github.com/reactjs/history/compare/v1.10.2...v1.11.0 |
"use strict"; | ||
var _slice = Array.prototype.slice; | ||
export { loopAsync }; | ||
function loopAsync(turns, work, callback) { | ||
var currentTurn = 0; | ||
var isDone = false; | ||
var currentTurn = 0, | ||
isDone = false; | ||
var sync = false, | ||
hasNext = false, | ||
doneArgs = undefined; | ||
function done() { | ||
isDone = true; | ||
if (sync) { | ||
// Iterate instead of recursing if possible. | ||
doneArgs = [].concat(_slice.call(arguments)); | ||
return; | ||
} | ||
callback.apply(this, arguments); | ||
@@ -15,9 +25,31 @@ } | ||
function next() { | ||
if (isDone) return; | ||
if (isDone) { | ||
return; | ||
} | ||
if (currentTurn < turns) { | ||
hasNext = true; | ||
if (sync) { | ||
// Iterate instead of recursing if possible. | ||
return; | ||
} | ||
sync = true; | ||
while (!isDone && currentTurn < turns && hasNext) { | ||
hasNext = false; | ||
work.call(this, currentTurn++, next, done); | ||
} else { | ||
done.apply(this, arguments); | ||
} | ||
sync = false; | ||
if (isDone) { | ||
// This means the loop finished synchronously. | ||
callback.apply(this, doneArgs); | ||
return; | ||
} | ||
if (currentTurn >= turns && hasNext) { | ||
isDone = true; | ||
callback(); | ||
} | ||
} | ||
@@ -24,0 +56,0 @@ |
@@ -7,2 +7,3 @@ 'use strict'; | ||
import { PUSH, POP } from './Actions'; | ||
import { parsePath } from './PathUtils'; | ||
import { canUseDOM } from './ExecutionEnvironment'; | ||
@@ -12,3 +13,2 @@ import { addEventListener, removeEventListener, getWindowPath, supportsHistory } from './DOMUtils'; | ||
import createDOMHistory from './createDOMHistory'; | ||
import parsePath from './parsePath'; | ||
@@ -15,0 +15,0 @@ /** |
@@ -8,2 +8,3 @@ 'use strict'; | ||
import { PUSH, POP } from './Actions'; | ||
import { parsePath } from './PathUtils'; | ||
import { canUseDOM } from './ExecutionEnvironment'; | ||
@@ -13,3 +14,2 @@ import { addEventListener, removeEventListener, getHashPath, replaceHashPath, supportsGoWithoutReloadUsingHash } from './DOMUtils'; | ||
import createDOMHistory from './createDOMHistory'; | ||
import parsePath from './parsePath'; | ||
@@ -16,0 +16,0 @@ function isAbsolutePath(path) { |
@@ -1,2 +0,1 @@ | ||
//import warning from 'warning' | ||
'use strict'; | ||
@@ -6,3 +5,5 @@ | ||
import warning from 'warning'; | ||
import deepEqual from 'deep-equal'; | ||
import { parsePath } from './PathUtils'; | ||
import { loopAsync } from './AsyncUtils'; | ||
@@ -12,3 +13,2 @@ import { PUSH, REPLACE, POP } from './Actions'; | ||
import runTransitionHook from './runTransitionHook'; | ||
import parsePath from './parsePath'; | ||
import deprecate from './deprecate'; | ||
@@ -34,4 +34,4 @@ | ||
var go = options.go; | ||
var getUserConfirmation = options.getUserConfirmation; | ||
var keyLength = options.keyLength; | ||
var getUserConfirmation = options.getUserConfirmation; | ||
@@ -136,3 +136,3 @@ if (typeof keyLength !== 'number') keyLength = DefaultKeyLength; | ||
if (nextPath === prevPath) nextLocation.action = REPLACE; | ||
if (nextPath === prevPath && deepEqual(location.state, nextLocation.state)) nextLocation.action = REPLACE; | ||
} | ||
@@ -194,7 +194,3 @@ | ||
if (typeof action === 'object') { | ||
//warning( | ||
// false, | ||
// 'The state (2nd) argument to history.createLocation is deprecated; use a ' + | ||
// 'location descriptor instead' | ||
//) | ||
process.env.NODE_ENV !== 'production' ? warning(false, 'The state (2nd) argument to history.createLocation is deprecated; use a ' + 'location descriptor instead') : undefined; | ||
@@ -201,0 +197,0 @@ if (typeof location === 'string') location = parsePath(location); |
@@ -1,2 +0,1 @@ | ||
//import warning from 'warning' | ||
'use strict'; | ||
@@ -6,4 +5,5 @@ | ||
import warning from 'warning'; | ||
import { POP } from './Actions'; | ||
import parsePath from './parsePath'; | ||
import { parsePath } from './PathUtils'; | ||
@@ -20,7 +20,3 @@ function createLocation() { | ||
if (typeof action === 'object') { | ||
//warning( | ||
// false, | ||
// 'The state (2nd) argument to createLocation is deprecated; use a ' + | ||
// 'location descriptor instead' | ||
//) | ||
process.env.NODE_ENV !== 'production' ? warning(false, 'The state (2nd) argument to createLocation is deprecated; use a ' + 'location descriptor instead') : undefined; | ||
@@ -27,0 +23,0 @@ location = _extends({}, location, { state: action }); |
@@ -7,5 +7,5 @@ 'use strict'; | ||
import invariant from 'invariant'; | ||
import { parsePath } from './PathUtils'; | ||
import { PUSH, REPLACE, POP } from './Actions'; | ||
import createHistory from './createHistory'; | ||
import parsePath from './parsePath'; | ||
@@ -75,3 +75,2 @@ function createStateStorage(entries) { | ||
var entry = entries[current]; | ||
var key = entry.key; | ||
var basename = entry.basename; | ||
@@ -83,8 +82,10 @@ var pathname = entry.pathname; | ||
var state = undefined; | ||
if (key) { | ||
var key = undefined, | ||
state = undefined; | ||
if (entry.key) { | ||
key = entry.key; | ||
state = readState(key); | ||
} else { | ||
key = history.createKey(); | ||
state = null; | ||
key = history.createKey(); | ||
entry.key = key; | ||
@@ -91,0 +92,0 @@ } |
@@ -1,13 +0,12 @@ | ||
//import warning from 'warning' | ||
'use strict'; | ||
"use strict"; | ||
import warning from 'warning'; | ||
function deprecate(fn) { | ||
return fn; | ||
//return function () { | ||
// warning(false, '[history] ' + message) | ||
// return fn.apply(this, arguments) | ||
//} | ||
function deprecate(fn, message) { | ||
return function () { | ||
process.env.NODE_ENV !== 'production' ? warning(false, '[history] ' + message) : undefined; | ||
return fn.apply(this, arguments); | ||
}; | ||
} | ||
export default deprecate; |
@@ -9,3 +9,4 @@ /*eslint-disable no-empty */ | ||
var KeyPrefix = '@@History/'; | ||
var QuotaExceededError = 'QuotaExceededError'; | ||
var QuotaExceededErrors = ['QuotaExceededError', 'QUOTA_EXCEEDED_ERR']; | ||
var SecurityError = 'SecurityError'; | ||
@@ -19,3 +20,7 @@ | ||
try { | ||
window.sessionStorage.setItem(createKey(key), JSON.stringify(state)); | ||
if (state == null) { | ||
window.sessionStorage.removeItem(createKey(key)); | ||
} else { | ||
window.sessionStorage.setItem(createKey(key), JSON.stringify(state)); | ||
} | ||
} catch (error) { | ||
@@ -30,3 +35,3 @@ if (error.name === SecurityError) { | ||
if (error.name === QuotaExceededError && window.sessionStorage.length === 0) { | ||
if (QuotaExceededErrors.indexOf(error.name) >= 0 && window.sessionStorage.length === 0) { | ||
// Safari "private mode" throws QuotaExceededError. | ||
@@ -33,0 +38,0 @@ process.env.NODE_ENV !== 'production' ? warning(false, '[history] Unable to save state; sessionStorage is not available in Safari private mode') : undefined; |
@@ -64,7 +64,2 @@ 'use strict'; | ||
} | ||
// FIXME: Work around our browser history not working correctly on Chrome | ||
// iOS: https://github.com/rackt/react-router/issues/2565 | ||
if (ua.indexOf('CriOS') !== -1) { | ||
return false; | ||
} | ||
return window.history && 'pushState' in window.history; | ||
@@ -71,0 +66,0 @@ } |
@@ -5,8 +5,5 @@ 'use strict'; | ||
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } | ||
import { canUseDOM } from './ExecutionEnvironment'; | ||
import { extractPath, parsePath } from './PathUtils'; | ||
import runTransitionHook from './runTransitionHook'; | ||
import extractPath from './extractPath'; | ||
import parsePath from './parsePath'; | ||
import deprecate from './deprecate'; | ||
@@ -17,7 +14,6 @@ | ||
var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; | ||
var basename = options.basename; | ||
var historyOptions = _objectWithoutProperties(options, ['basename']); | ||
var history = createHistory(options); | ||
var history = createHistory(historyOptions); | ||
var basename = options.basename; | ||
@@ -92,4 +88,8 @@ // Automatically use the value of <base href> in HTML | ||
function createLocation() { | ||
return addBasename(history.createLocation.apply(history, arguments)); | ||
function createLocation(location) { | ||
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { | ||
args[_key - 1] = arguments[_key]; | ||
} | ||
return addBasename(history.createLocation.apply(history, [prependBasename(location)].concat(args))); | ||
} | ||
@@ -96,0 +96,0 @@ |
@@ -5,8 +5,6 @@ 'use strict'; | ||
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } | ||
import warning from 'warning'; | ||
import { parse, stringify } from 'query-string'; | ||
import runTransitionHook from './runTransitionHook'; | ||
import parsePath from './parsePath'; | ||
import { parsePath } from './PathUtils'; | ||
import deprecate from './deprecate'; | ||
@@ -35,9 +33,8 @@ | ||
var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; | ||
var history = createHistory(options); | ||
var stringifyQuery = options.stringifyQuery; | ||
var parseQueryString = options.parseQueryString; | ||
var historyOptions = _objectWithoutProperties(options, ['stringifyQuery', 'parseQueryString']); | ||
var history = createHistory(historyOptions); | ||
if (typeof stringifyQuery !== 'function') stringifyQuery = defaultStringifyQuery; | ||
@@ -64,4 +61,7 @@ | ||
var queryString = undefined; | ||
if (!query || (queryString = stringifyQuery(query)) === '') return location; | ||
var searchBaseSpec = location[SEARCH_BASE_KEY]; | ||
var queryString = query ? stringifyQuery(query) : ''; | ||
if (!searchBaseSpec && !queryString) { | ||
return location; | ||
} | ||
@@ -72,3 +72,2 @@ process.env.NODE_ENV !== 'production' ? warning(stringifyQuery !== defaultStringifyQuery || !isNestedObject(query), 'useQueries does not stringify nested query objects by default; ' + 'use a custom stringifyQuery function') : undefined; | ||
var searchBaseSpec = location[SEARCH_BASE_KEY]; | ||
var searchBase = undefined; | ||
@@ -81,3 +80,6 @@ if (searchBaseSpec && location.search === searchBaseSpec.search) { | ||
var search = searchBase + (searchBase ? '&' : '?') + queryString; | ||
var search = searchBase; | ||
if (queryString) { | ||
search += (search ? '&' : '?') + queryString; | ||
} | ||
@@ -112,6 +114,4 @@ return _extends({}, location, (_extends2 = { | ||
function createPath(location, query) { | ||
//warning( | ||
// !query, | ||
// 'the query argument to createPath is deprecated; use a location descriptor instead' | ||
//) | ||
process.env.NODE_ENV !== 'production' ? warning(!query, 'the query argument to createPath is deprecated; use a location descriptor instead') : undefined; | ||
return history.createPath(appendQuery(location, query || location.query)); | ||
@@ -121,11 +121,17 @@ } | ||
function createHref(location, query) { | ||
//warning( | ||
// !query, | ||
// 'the query argument to createHref is deprecated; use a location descriptor instead' | ||
//) | ||
process.env.NODE_ENV !== 'production' ? warning(!query, 'the query argument to createHref is deprecated; use a location descriptor instead') : undefined; | ||
return history.createHref(appendQuery(location, query || location.query)); | ||
} | ||
function createLocation() { | ||
return addQuery(history.createLocation.apply(history, arguments)); | ||
function createLocation(location) { | ||
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { | ||
args[_key - 1] = arguments[_key]; | ||
} | ||
var fullLocation = history.createLocation.apply(history, [appendQuery(location, location.query)].concat(args)); | ||
if (location.query) { | ||
fullLocation.query = location.query; | ||
} | ||
return addQuery(fullLocation); | ||
} | ||
@@ -132,0 +138,0 @@ |
"use strict"; | ||
exports.__esModule = true; | ||
var _slice = Array.prototype.slice; | ||
exports.loopAsync = loopAsync; | ||
function loopAsync(turns, work, callback) { | ||
var currentTurn = 0; | ||
var isDone = false; | ||
var currentTurn = 0, | ||
isDone = false; | ||
var sync = false, | ||
hasNext = false, | ||
doneArgs = undefined; | ||
function done() { | ||
isDone = true; | ||
if (sync) { | ||
// Iterate instead of recursing if possible. | ||
doneArgs = [].concat(_slice.call(arguments)); | ||
return; | ||
} | ||
callback.apply(this, arguments); | ||
@@ -16,9 +26,31 @@ } | ||
function next() { | ||
if (isDone) return; | ||
if (isDone) { | ||
return; | ||
} | ||
if (currentTurn < turns) { | ||
hasNext = true; | ||
if (sync) { | ||
// Iterate instead of recursing if possible. | ||
return; | ||
} | ||
sync = true; | ||
while (!isDone && currentTurn < turns && hasNext) { | ||
hasNext = false; | ||
work.call(this, currentTurn++, next, done); | ||
} else { | ||
done.apply(this, arguments); | ||
} | ||
sync = false; | ||
if (isDone) { | ||
// This means the loop finished synchronously. | ||
callback.apply(this, doneArgs); | ||
return; | ||
} | ||
if (currentTurn >= turns && hasNext) { | ||
isDone = true; | ||
callback(); | ||
} | ||
} | ||
@@ -25,0 +57,0 @@ |
@@ -15,2 +15,4 @@ 'use strict'; | ||
var _PathUtils = require('./PathUtils'); | ||
var _ExecutionEnvironment = require('./ExecutionEnvironment'); | ||
@@ -26,6 +28,2 @@ | ||
var _parsePath = require('./parsePath'); | ||
var _parsePath2 = _interopRequireDefault(_parsePath); | ||
/** | ||
@@ -67,3 +65,3 @@ * Creates and returns a history object that uses HTML5's history API | ||
var location = _parsePath2['default'](path); | ||
var location = _PathUtils.parsePath(path); | ||
@@ -70,0 +68,0 @@ return history.createLocation(_extends({}, location, { state: state }), undefined, key); |
@@ -19,2 +19,4 @@ 'use strict'; | ||
var _PathUtils = require('./PathUtils'); | ||
var _ExecutionEnvironment = require('./ExecutionEnvironment'); | ||
@@ -30,6 +32,2 @@ | ||
var _parsePath = require('./parsePath'); | ||
var _parsePath2 = _interopRequireDefault(_parsePath); | ||
function isAbsolutePath(path) { | ||
@@ -93,3 +91,3 @@ return typeof path === 'string' && path.charAt(0) === '/'; | ||
var location = _parsePath2['default'](path); | ||
var location = _PathUtils.parsePath(path); | ||
@@ -96,0 +94,0 @@ return history.createLocation(_extends({}, location, { state: state }), undefined, key); |
@@ -1,2 +0,1 @@ | ||
//import warning from 'warning' | ||
'use strict'; | ||
@@ -10,2 +9,6 @@ | ||
var _warning = require('warning'); | ||
var _warning2 = _interopRequireDefault(_warning); | ||
var _deepEqual = require('deep-equal'); | ||
@@ -15,2 +18,4 @@ | ||
var _PathUtils = require('./PathUtils'); | ||
var _AsyncUtils = require('./AsyncUtils'); | ||
@@ -28,6 +33,2 @@ | ||
var _parsePath = require('./parsePath'); | ||
var _parsePath2 = _interopRequireDefault(_parsePath); | ||
var _deprecate = require('./deprecate'); | ||
@@ -55,4 +56,4 @@ | ||
var go = options.go; | ||
var getUserConfirmation = options.getUserConfirmation; | ||
var keyLength = options.keyLength; | ||
var getUserConfirmation = options.getUserConfirmation; | ||
@@ -157,3 +158,3 @@ if (typeof keyLength !== 'number') keyLength = DefaultKeyLength; | ||
if (nextPath === prevPath) nextLocation.action = _Actions.REPLACE; | ||
if (nextPath === prevPath && _deepEqual2['default'](location.state, nextLocation.state)) nextLocation.action = _Actions.REPLACE; | ||
} | ||
@@ -215,9 +216,5 @@ | ||
if (typeof action === 'object') { | ||
//warning( | ||
// false, | ||
// 'The state (2nd) argument to history.createLocation is deprecated; use a ' + | ||
// 'location descriptor instead' | ||
//) | ||
process.env.NODE_ENV !== 'production' ? _warning2['default'](false, 'The state (2nd) argument to history.createLocation is deprecated; use a ' + 'location descriptor instead') : undefined; | ||
if (typeof location === 'string') location = _parsePath2['default'](location); | ||
if (typeof location === 'string') location = _PathUtils.parsePath(location); | ||
@@ -262,3 +259,3 @@ location = _extends({}, location, { state: action }); | ||
function pushState(state, path) { | ||
if (typeof path === 'string') path = _parsePath2['default'](path); | ||
if (typeof path === 'string') path = _PathUtils.parsePath(path); | ||
@@ -270,3 +267,3 @@ push(_extends({ state: state }, path)); | ||
function replaceState(state, path) { | ||
if (typeof path === 'string') path = _parsePath2['default'](path); | ||
if (typeof path === 'string') path = _PathUtils.parsePath(path); | ||
@@ -273,0 +270,0 @@ replace(_extends({ state: state }, path)); |
@@ -1,2 +0,1 @@ | ||
//import warning from 'warning' | ||
'use strict'; | ||
@@ -10,8 +9,10 @@ | ||
var _warning = require('warning'); | ||
var _warning2 = _interopRequireDefault(_warning); | ||
var _Actions = require('./Actions'); | ||
var _parsePath = require('./parsePath'); | ||
var _PathUtils = require('./PathUtils'); | ||
var _parsePath2 = _interopRequireDefault(_parsePath); | ||
function createLocation() { | ||
@@ -24,10 +25,6 @@ var location = arguments.length <= 0 || arguments[0] === undefined ? '/' : arguments[0]; | ||
if (typeof location === 'string') location = _parsePath2['default'](location); | ||
if (typeof location === 'string') location = _PathUtils.parsePath(location); | ||
if (typeof action === 'object') { | ||
//warning( | ||
// false, | ||
// 'The state (2nd) argument to createLocation is deprecated; use a ' + | ||
// 'location descriptor instead' | ||
//) | ||
process.env.NODE_ENV !== 'production' ? _warning2['default'](false, 'The state (2nd) argument to createLocation is deprecated; use a ' + 'location descriptor instead') : undefined; | ||
@@ -34,0 +31,0 @@ location = _extends({}, location, { state: action }); |
@@ -17,2 +17,4 @@ 'use strict'; | ||
var _PathUtils = require('./PathUtils'); | ||
var _Actions = require('./Actions'); | ||
@@ -24,6 +26,2 @@ | ||
var _parsePath = require('./parsePath'); | ||
var _parsePath2 = _interopRequireDefault(_parsePath); | ||
function createStateStorage(entries) { | ||
@@ -92,3 +90,2 @@ return entries.filter(function (entry) { | ||
var entry = entries[current]; | ||
var key = entry.key; | ||
var basename = entry.basename; | ||
@@ -100,12 +97,14 @@ var pathname = entry.pathname; | ||
var state = undefined; | ||
if (key) { | ||
var key = undefined, | ||
state = undefined; | ||
if (entry.key) { | ||
key = entry.key; | ||
state = readState(key); | ||
} else { | ||
key = history.createKey(); | ||
state = null; | ||
key = history.createKey(); | ||
entry.key = key; | ||
} | ||
var location = _parsePath2['default'](path); | ||
var location = _PathUtils.parsePath(path); | ||
@@ -112,0 +111,0 @@ return history.createLocation(_extends({}, location, { state: state }), undefined, key); |
@@ -1,15 +0,19 @@ | ||
//import warning from 'warning' | ||
'use strict'; | ||
"use strict"; | ||
exports.__esModule = true; | ||
exports.__esModule = true; | ||
function deprecate(fn) { | ||
return fn; | ||
//return function () { | ||
// warning(false, '[history] ' + message) | ||
// return fn.apply(this, arguments) | ||
//} | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } | ||
var _warning = require('warning'); | ||
var _warning2 = _interopRequireDefault(_warning); | ||
function deprecate(fn, message) { | ||
return function () { | ||
process.env.NODE_ENV !== 'production' ? _warning2['default'](false, '[history] ' + message) : undefined; | ||
return fn.apply(this, arguments); | ||
}; | ||
} | ||
exports["default"] = deprecate; | ||
module.exports = exports["default"]; | ||
exports['default'] = deprecate; | ||
module.exports = exports['default']; |
@@ -15,3 +15,4 @@ /*eslint-disable no-empty */ | ||
var KeyPrefix = '@@History/'; | ||
var QuotaExceededError = 'QuotaExceededError'; | ||
var QuotaExceededErrors = ['QuotaExceededError', 'QUOTA_EXCEEDED_ERR']; | ||
var SecurityError = 'SecurityError'; | ||
@@ -25,3 +26,7 @@ | ||
try { | ||
window.sessionStorage.setItem(createKey(key), JSON.stringify(state)); | ||
if (state == null) { | ||
window.sessionStorage.removeItem(createKey(key)); | ||
} else { | ||
window.sessionStorage.setItem(createKey(key), JSON.stringify(state)); | ||
} | ||
} catch (error) { | ||
@@ -36,3 +41,3 @@ if (error.name === SecurityError) { | ||
if (error.name === QuotaExceededError && window.sessionStorage.length === 0) { | ||
if (QuotaExceededErrors.indexOf(error.name) >= 0 && window.sessionStorage.length === 0) { | ||
// Safari "private mode" throws QuotaExceededError. | ||
@@ -39,0 +44,0 @@ process.env.NODE_ENV !== 'production' ? _warning2['default'](false, '[history] Unable to save state; sessionStorage is not available in Safari private mode') : undefined; |
@@ -65,7 +65,2 @@ 'use strict'; | ||
} | ||
// FIXME: Work around our browser history not working correctly on Chrome | ||
// iOS: https://github.com/rackt/react-router/issues/2565 | ||
if (ua.indexOf('CriOS') !== -1) { | ||
return false; | ||
} | ||
return window.history && 'pushState' in window.history; | ||
@@ -72,0 +67,0 @@ } |
@@ -9,6 +9,6 @@ 'use strict'; | ||
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } | ||
var _ExecutionEnvironment = require('./ExecutionEnvironment'); | ||
var _PathUtils = require('./PathUtils'); | ||
var _runTransitionHook = require('./runTransitionHook'); | ||
@@ -18,10 +18,2 @@ | ||
var _extractPath = require('./extractPath'); | ||
var _extractPath2 = _interopRequireDefault(_extractPath); | ||
var _parsePath = require('./parsePath'); | ||
var _parsePath2 = _interopRequireDefault(_parsePath); | ||
var _deprecate = require('./deprecate'); | ||
@@ -34,7 +26,6 @@ | ||
var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; | ||
var basename = options.basename; | ||
var historyOptions = _objectWithoutProperties(options, ['basename']); | ||
var history = createHistory(options); | ||
var history = createHistory(historyOptions); | ||
var basename = options.basename; | ||
@@ -46,3 +37,3 @@ // Automatically use the value of <base href> in HTML | ||
if (base) basename = _extractPath2['default'](base.href); | ||
if (base) basename = _PathUtils.extractPath(base.href); | ||
} | ||
@@ -68,3 +59,3 @@ | ||
if (typeof location === 'string') location = _parsePath2['default'](location); | ||
if (typeof location === 'string') location = _PathUtils.parsePath(location); | ||
@@ -111,4 +102,8 @@ var pname = location.pathname; | ||
function createLocation() { | ||
return addBasename(history.createLocation.apply(history, arguments)); | ||
function createLocation(location) { | ||
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { | ||
args[_key - 1] = arguments[_key]; | ||
} | ||
return addBasename(history.createLocation.apply(history, [prependBasename(location)].concat(args))); | ||
} | ||
@@ -118,3 +113,3 @@ | ||
function pushState(state, path) { | ||
if (typeof path === 'string') path = _parsePath2['default'](path); | ||
if (typeof path === 'string') path = _PathUtils.parsePath(path); | ||
@@ -126,3 +121,3 @@ push(_extends({ state: state }, path)); | ||
function replaceState(state, path) { | ||
if (typeof path === 'string') path = _parsePath2['default'](path); | ||
if (typeof path === 'string') path = _PathUtils.parsePath(path); | ||
@@ -129,0 +124,0 @@ replace(_extends({ state: state }, path)); |
@@ -9,4 +9,2 @@ 'use strict'; | ||
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } | ||
var _warning = require('warning'); | ||
@@ -22,6 +20,4 @@ | ||
var _parsePath = require('./parsePath'); | ||
var _PathUtils = require('./PathUtils'); | ||
var _parsePath2 = _interopRequireDefault(_parsePath); | ||
var _deprecate = require('./deprecate'); | ||
@@ -52,9 +48,8 @@ | ||
var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; | ||
var history = createHistory(options); | ||
var stringifyQuery = options.stringifyQuery; | ||
var parseQueryString = options.parseQueryString; | ||
var historyOptions = _objectWithoutProperties(options, ['stringifyQuery', 'parseQueryString']); | ||
var history = createHistory(historyOptions); | ||
if (typeof stringifyQuery !== 'function') stringifyQuery = defaultStringifyQuery; | ||
@@ -81,10 +76,12 @@ | ||
var queryString = undefined; | ||
if (!query || (queryString = stringifyQuery(query)) === '') return location; | ||
var searchBaseSpec = location[SEARCH_BASE_KEY]; | ||
var queryString = query ? stringifyQuery(query) : ''; | ||
if (!searchBaseSpec && !queryString) { | ||
return location; | ||
} | ||
process.env.NODE_ENV !== 'production' ? _warning2['default'](stringifyQuery !== defaultStringifyQuery || !isNestedObject(query), 'useQueries does not stringify nested query objects by default; ' + 'use a custom stringifyQuery function') : undefined; | ||
if (typeof location === 'string') location = _parsePath2['default'](location); | ||
if (typeof location === 'string') location = _PathUtils.parsePath(location); | ||
var searchBaseSpec = location[SEARCH_BASE_KEY]; | ||
var searchBase = undefined; | ||
@@ -97,3 +94,6 @@ if (searchBaseSpec && location.search === searchBaseSpec.search) { | ||
var search = searchBase + (searchBase ? '&' : '?') + queryString; | ||
var search = searchBase; | ||
if (queryString) { | ||
search += (search ? '&' : '?') + queryString; | ||
} | ||
@@ -128,6 +128,4 @@ return _extends({}, location, (_extends2 = { | ||
function createPath(location, query) { | ||
//warning( | ||
// !query, | ||
// 'the query argument to createPath is deprecated; use a location descriptor instead' | ||
//) | ||
process.env.NODE_ENV !== 'production' ? _warning2['default'](!query, 'the query argument to createPath is deprecated; use a location descriptor instead') : undefined; | ||
return history.createPath(appendQuery(location, query || location.query)); | ||
@@ -137,11 +135,17 @@ } | ||
function createHref(location, query) { | ||
//warning( | ||
// !query, | ||
// 'the query argument to createHref is deprecated; use a location descriptor instead' | ||
//) | ||
process.env.NODE_ENV !== 'production' ? _warning2['default'](!query, 'the query argument to createHref is deprecated; use a location descriptor instead') : undefined; | ||
return history.createHref(appendQuery(location, query || location.query)); | ||
} | ||
function createLocation() { | ||
return addQuery(history.createLocation.apply(history, arguments)); | ||
function createLocation(location) { | ||
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { | ||
args[_key - 1] = arguments[_key]; | ||
} | ||
var fullLocation = history.createLocation.apply(history, [appendQuery(location, location.query)].concat(args)); | ||
if (location.query) { | ||
fullLocation.query = location.query; | ||
} | ||
return addQuery(fullLocation); | ||
} | ||
@@ -151,3 +155,3 @@ | ||
function pushState(state, path, query) { | ||
if (typeof path === 'string') path = _parsePath2['default'](path); | ||
if (typeof path === 'string') path = _PathUtils.parsePath(path); | ||
@@ -159,3 +163,3 @@ push(_extends({ state: state }, path, { query: query })); | ||
function replaceState(state, path, query) { | ||
if (typeof path === 'string') path = _parsePath2['default'](path); | ||
if (typeof path === 'string') path = _PathUtils.parsePath(path); | ||
@@ -162,0 +166,0 @@ replace(_extends({ state: state }, path, { query: query })); |
The MIT License (MIT) | ||
Copyright (c) 2015 Michael Jackson | ||
Copyright (c) 2015-2016 Michael Jackson | ||
@@ -5,0 +5,0 @@ Permission is hereby granted, free of charge, to any person obtaining a copy |
@@ -23,6 +23,6 @@ /** | ||
var __DEV__ = process.env.NODE_ENV !== 'production'; | ||
var NODE_ENV = process.env.NODE_ENV; | ||
var invariant = function(condition, format, a, b, c, d, e, f) { | ||
if (__DEV__) { | ||
if (NODE_ENV !== 'production') { | ||
if (format === undefined) { | ||
@@ -29,0 +29,0 @@ throw new Error('invariant requires an error message argument'); |
@@ -60,3 +60,4 @@ { | ||
"directories": {}, | ||
"_resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-1.0.2.tgz" | ||
"_resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-1.0.2.tgz", | ||
"readme": "ERROR: No README data found!" | ||
} |
@@ -59,3 +59,4 @@ { | ||
"directories": {}, | ||
"_resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.1.0.tgz" | ||
"_resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.1.0.tgz", | ||
"readme": "ERROR: No README data found!" | ||
} |
{ | ||
"name": "invariant", | ||
"version": "2.2.0", | ||
"version": "2.2.1", | ||
"description": "invariant", | ||
@@ -38,3 +38,3 @@ "keywords": [ | ||
}, | ||
"gitHead": "1660eab9f183183e71ef57a7765bb1121680fff9", | ||
"gitHead": "594d6cbcde933a7bd3ecd76a7c4f19892a95e0de", | ||
"bugs": { | ||
@@ -44,7 +44,7 @@ "url": "https://github.com/zertosh/invariant/issues" | ||
"homepage": "https://github.com/zertosh/invariant#readme", | ||
"_id": "invariant@2.2.0", | ||
"_shasum": "c8d7e847366a49cc18b622f058a689d481e895f2", | ||
"_id": "invariant@2.2.1", | ||
"_shasum": "b097010547668c7e337028ebe816ebe36c8a8d54", | ||
"_from": "invariant@>=2.0.0 <3.0.0", | ||
"_npmVersion": "2.14.7", | ||
"_nodeVersion": "4.2.2", | ||
"_npmVersion": "2.14.4", | ||
"_nodeVersion": "4.1.1", | ||
"_npmUser": { | ||
@@ -54,4 +54,12 @@ "name": "zertosh", | ||
}, | ||
"dist": { | ||
"shasum": "b097010547668c7e337028ebe816ebe36c8a8d54", | ||
"tarball": "http://registry.npmjs.org/invariant/-/invariant-2.2.1.tgz" | ||
}, | ||
"maintainers": [ | ||
{ | ||
"name": "cpojer", | ||
"email": "christoph.pojer@gmail.com" | ||
}, | ||
{ | ||
"name": "zertosh", | ||
@@ -61,8 +69,9 @@ "email": "zertosh@gmail.com" | ||
], | ||
"dist": { | ||
"shasum": "c8d7e847366a49cc18b622f058a689d481e895f2", | ||
"tarball": "http://registry.npmjs.org/invariant/-/invariant-2.2.0.tgz" | ||
"_npmOperationalInternal": { | ||
"host": "packages-13-west.internal.npmjs.com", | ||
"tmp": "tmp/invariant-2.2.1.tgz_1457504319192_0.7920392917003483" | ||
}, | ||
"directories": {}, | ||
"_resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.0.tgz" | ||
"_resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.1.tgz", | ||
"readme": "ERROR: No README data found!" | ||
} |
@@ -57,3 +57,3 @@ 'use strict'; | ||
if (Array.isArray(val)) { | ||
return val.sort().map(function (val2) { | ||
return val.slice().sort().map(function (val2) { | ||
return strictUriEncode(key) + '=' + strictUriEncode(val2); | ||
@@ -60,0 +60,0 @@ }).join('&'); |
{ | ||
"name": "query-string", | ||
"version": "3.0.0", | ||
"version": "3.0.1", | ||
"description": "Parse and stringify URL query strings", | ||
@@ -46,3 +46,3 @@ "license": "MIT", | ||
}, | ||
"gitHead": "265aee0b8bf185be8cc33bb38393b1156081a0f1", | ||
"gitHead": "229eabc7487d8f1a012a287dc0ac7605e86a39be", | ||
"bugs": { | ||
@@ -52,7 +52,7 @@ "url": "https://github.com/sindresorhus/query-string/issues" | ||
"homepage": "https://github.com/sindresorhus/query-string", | ||
"_id": "query-string@3.0.0", | ||
"_shasum": "02fd306f0432040b91b11063f9404fe1bbd4ba7b", | ||
"_id": "query-string@3.0.1", | ||
"_shasum": "f04a0758902ab2788582d8177203db9cd9e6a0ad", | ||
"_from": "query-string@>=3.0.0 <4.0.0", | ||
"_npmVersion": "2.14.4", | ||
"_nodeVersion": "4.1.1", | ||
"_npmVersion": "2.14.12", | ||
"_nodeVersion": "4.3.0", | ||
"_npmUser": { | ||
@@ -63,4 +63,4 @@ "name": "sindresorhus", | ||
"dist": { | ||
"shasum": "02fd306f0432040b91b11063f9404fe1bbd4ba7b", | ||
"tarball": "http://registry.npmjs.org/query-string/-/query-string-3.0.0.tgz" | ||
"shasum": "f04a0758902ab2788582d8177203db9cd9e6a0ad", | ||
"tarball": "http://registry.npmjs.org/query-string/-/query-string-3.0.1.tgz" | ||
}, | ||
@@ -73,4 +73,8 @@ "maintainers": [ | ||
], | ||
"_npmOperationalInternal": { | ||
"host": "packages-5-east.internal.npmjs.com", | ||
"tmp": "tmp/query-string-3.0.1.tgz_1456549355439_0.5011087558232248" | ||
}, | ||
"directories": {}, | ||
"_resolved": "https://registry.npmjs.org/query-string/-/query-string-3.0.0.tgz" | ||
"_resolved": "https://registry.npmjs.org/query-string/-/query-string-3.0.1.tgz" | ||
} |
@@ -60,3 +60,4 @@ { | ||
"directories": {}, | ||
"_resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-1.0.2.tgz" | ||
"_resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-1.0.2.tgz", | ||
"readme": "ERROR: No README data found!" | ||
} |
@@ -59,3 +59,4 @@ { | ||
"directories": {}, | ||
"_resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.1.0.tgz" | ||
"_resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.1.0.tgz", | ||
"readme": "ERROR: No README data found!" | ||
} |
{ | ||
"name": "history", | ||
"version": "1.17.0", | ||
"description": "A minimal, functional history implementation for JavaScript", | ||
"version": "2.0.1", | ||
"description": "Manage browser history with JavaScript", | ||
"files": [ | ||
"*.md", | ||
"docs", | ||
"es6", | ||
"lib", | ||
"npm-scripts", | ||
"modules/*.js", | ||
"umd" | ||
], | ||
"main": "lib/index", | ||
"jsnext:main": "es6/index", | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/rackt/history.git" | ||
"url": "git+https://github.com/mjackson/history.git" | ||
}, | ||
"bugs": { | ||
"url": "https://github.com/rackt/history/issues" | ||
}, | ||
"scripts": { | ||
"build": "npm run build-cjs && npm run build-es6", | ||
"lint": "eslint modules", | ||
"start": "webpack-dev-server -d --content-base ./ --history-api-fallback --inline modules/index.js", | ||
"build-cjs": "rimraf lib && babel ./modules --stage 0 --loose all --plugins dev-expression -d lib --ignore '__tests__'", | ||
@@ -27,6 +24,6 @@ "build-es6": "rimraf es6 && babel ./modules --stage 0 --loose all --plugins dev-expression -d es6 --blacklist=es6.modules --ignore '__tests__'", | ||
"build-min": "NODE_ENV=production webpack -p modules/index.js umd/History.min.js", | ||
"lint": "eslint modules", | ||
"start": "webpack-dev-server -d --content-base ./ --history-api-fallback --inline modules/index.js", | ||
"test": "npm run lint && karma start", | ||
"postinstall": "node ./npm-scripts/postinstall.js" | ||
"build": "node ./scripts/build.js", | ||
"release": "node ./scripts/release.js", | ||
"prepublish": "npm run build", | ||
"test": "npm run lint && karma start" | ||
}, | ||
@@ -45,18 +42,15 @@ "authors": [ | ||
"assert": "1.3.0", | ||
"babel": "^5.4.7", | ||
"babel-core": "^5.4.7", | ||
"babel-eslint": "^3.1.23", | ||
"babel-loader": "^5.0.0", | ||
"babel": "^5.8.35", | ||
"babel-core": "^5.8.35", | ||
"babel-eslint": "^4.1.8", | ||
"babel-loader": "^5.4.0", | ||
"babel-plugin-dev-expression": "^0.1.0", | ||
"eslint": "1.4.1", | ||
"eslint-config-rackt": "1.0.0", | ||
"eslint-plugin-react": "3.3.2", | ||
"eslint": "^1.10.3", | ||
"eslint-config-rackt": "^1.1.1", | ||
"eslint-plugin-react": "^3.16.1", | ||
"expect": "^1.12.0", | ||
"gzip-size": "^3.0.0", | ||
"isparta-loader": "^1.0.0", | ||
"karma": "^0.13.3", | ||
"karma-browserstack-launcher": "^0.1.3", | ||
"karma-chrome-launcher": "^0.2.0", | ||
"karma-coverage": "^0.5.3", | ||
"karma-coveralls": "^1.1.2", | ||
"karma-mocha": "^0.2.0", | ||
@@ -67,3 +61,4 @@ "karma-mocha-reporter": "^1.0.4", | ||
"mocha": "^2.0.1", | ||
"pretty-bytes": "^2.0.1", | ||
"pretty-bytes": "^3.0.1", | ||
"readline-sync": "^1.4.1", | ||
"rimraf": "^2.4.2", | ||
@@ -81,9 +76,12 @@ "webpack": "^1.4.13", | ||
], | ||
"gitHead": "daf0bd52b8f3bc862c58faf4c7d5a40c86afed9e", | ||
"homepage": "https://github.com/rackt/history#readme", | ||
"_id": "history@1.17.0", | ||
"_shasum": "c5483caa5a1d1fea00a1a7d8d19b874016711d29", | ||
"_from": "history@>=1.13.1 <2.0.0", | ||
"_npmVersion": "3.4.1", | ||
"_nodeVersion": "5.0.0", | ||
"gitHead": "1b4003f91cfb09c47122831633226a657c5ea686", | ||
"bugs": { | ||
"url": "https://github.com/mjackson/history/issues" | ||
}, | ||
"homepage": "https://github.com/mjackson/history#readme", | ||
"_id": "history@2.0.1", | ||
"_shasum": "4a0b7f2b87b29f4da2d47910f0c86de0fad579f8", | ||
"_from": "history@>=2.0.1 <3.0.0", | ||
"_npmVersion": "3.3.12", | ||
"_nodeVersion": "5.3.0", | ||
"_npmUser": { | ||
@@ -94,4 +92,4 @@ "name": "mjackson", | ||
"dist": { | ||
"shasum": "c5483caa5a1d1fea00a1a7d8d19b874016711d29", | ||
"tarball": "http://registry.npmjs.org/history/-/history-1.17.0.tgz" | ||
"shasum": "4a0b7f2b87b29f4da2d47910f0c86de0fad579f8", | ||
"tarball": "http://registry.npmjs.org/history/-/history-2.0.1.tgz" | ||
}, | ||
@@ -104,4 +102,8 @@ "maintainers": [ | ||
], | ||
"_npmOperationalInternal": { | ||
"host": "packages-13-west.internal.npmjs.com", | ||
"tmp": "tmp/history-2.0.1.tgz_1456978260388_0.6892792345024645" | ||
}, | ||
"directories": {}, | ||
"_resolved": "https://registry.npmjs.org/history/-/history-1.17.0.tgz" | ||
"_resolved": "https://registry.npmjs.org/history/-/history-2.0.1.tgz" | ||
} |
# history [![Travis][build-badge]][build] [![npm package][npm-badge]][npm] | ||
[build-badge]: https://img.shields.io/travis/mjackson/history/master.svg?style=flat-square | ||
[build]: https://travis-ci.org/mjackson/history | ||
[npm-badge]: https://img.shields.io/npm/v/history.svg?style=flat-square | ||
[npm]: https://www.npmjs.org/package/history | ||
[`history`](https://www.npmjs.com/package/history) is a JavaScript library that lets you easily manage session history in browsers, testing environments, and (soon, via [React Native](https://facebook.github.io/react-native/)) native devices. `history` abstracts away the differences in these different platforms and provides a minimal API that lets you manage the history stack, navigate, confirm navigation, and persist state between sessions. `history` is library-agnostic and may easily be included in any JavaScript project. | ||
[![Coveralls][coveralls-badge]][coveralls] | ||
[![Discord][discord-badge]][discord] | ||
## Docs & Help | ||
@@ -20,3 +23,3 @@ | ||
$ npm install history | ||
$ npm install --save history | ||
@@ -48,7 +51,7 @@ Then with a module bundler like [webpack](https://webpack.github.io/), use as you would anything else: | ||
let history = createHistory() | ||
const history = createHistory() | ||
// Listen for changes to the current location. The | ||
// listener is called once immediately. | ||
let unlisten = history.listen(location => { | ||
const unlisten = history.listen(location => { | ||
console.log(location.pathname) | ||
@@ -67,3 +70,3 @@ }) | ||
You can find many more examples [in the documentation](https://github.com/rackt/history/tree/master/docs)! | ||
You can find many more examples [in the documentation](https://github.com/mjackson/history/tree/master/docs)! | ||
@@ -75,13 +78,1 @@ ## Thanks | ||
Also, thanks to [BrowserStack](https://www.browserstack.com/) for providing the infrastructure that allows us to run our build in real browsers. | ||
[build-badge]: https://img.shields.io/travis/rackt/history/master.svg?style=flat-square | ||
[build]: https://travis-ci.org/rackt/history | ||
[npm-badge]: https://img.shields.io/npm/v/history.svg?style=flat-square | ||
[npm]: https://www.npmjs.org/package/history | ||
[coveralls-badge]: https://img.shields.io/coveralls/rackt/history/master.svg?style=flat-square | ||
[coveralls]: https://coveralls.io/github/rackt/history | ||
[discord-badge]: https://img.shields.io/badge/Discord-join%20chat%20%E2%86%92-738bd7.svg?style=flat-square | ||
[discord]: https://discord.gg/0ZcbPKXt5bYaNQ46 |
@@ -1,1 +0,1 @@ | ||
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.History=t():e.History=t()}(this,function(){return function(e){function t(r){if(n[r])return n[r].exports;var a=n[r]={exports:{},id:r,loaded:!1};return e[r].call(a.exports,a,a.exports,t),a.loaded=!0,a.exports}var n={};return t.m=e,t.c=n,t.p="",t(0)}([function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}t.__esModule=!0;var a=n(1),o=r(a),u=n(12),i=r(u),s=n(17),f=r(s);t.createHistory=f["default"];var c=n(18),l=r(c);t.createHashHistory=l["default"];var d=n(19),p=r(d);t.createMemoryHistory=p["default"];var h=n(22),g=r(h);t.useBasename=g["default"];var v=n(14),y=r(v);t.useBeforeUnload=y["default"];var m=n(15),w=r(m);t.useQueries=w["default"];var O=n(4),b=r(O);t.Actions=b["default"];var _=n(20),P=r(_);t.enableBeforeUnload=P["default"];var S=n(21),x=r(S);t.enableQueries=x["default"];var H=o["default"](i["default"],"Using createLocation without a history instance is deprecated; please use history.createLocation instead");t.createLocation=H},function(e,t){"use strict";function n(e){return e}t.__esModule=!0,t["default"]=n,e.exports=t["default"]},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function a(e){var t=i["default"](e),n="",r="",a=t.indexOf("#");-1!==a&&(r=t.substring(a),t=t.substring(0,a));var o=t.indexOf("?");return-1!==o&&(n=t.substring(o),t=t.substring(0,o)),""===t&&(t="/"),{pathname:t,search:n,hash:r}}t.__esModule=!0;var o=n(3),u=(r(o),n(13)),i=r(u);t["default"]=a,e.exports=t["default"]},function(e,t,n){"use strict";var r=function(){};e.exports=r},function(e,t){"use strict";t.__esModule=!0;var n="PUSH";t.PUSH=n;var r="REPLACE";t.REPLACE=r;var a="POP";t.POP=a,t["default"]={PUSH:n,REPLACE:r,POP:a}},function(e,t){"use strict";t.__esModule=!0;var n=!("undefined"==typeof window||!window.document||!window.document.createElement);t.canUseDOM=n},function(e,t){"use strict";function n(e,t,n){e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent("on"+t,n)}function r(e,t,n){e.removeEventListener?e.removeEventListener(t,n,!1):e.detachEvent("on"+t,n)}function a(){return window.location.href.split("#")[1]||""}function o(e){window.location.replace(window.location.pathname+window.location.search+"#"+e)}function u(){return window.location.pathname+window.location.search+window.location.hash}function i(e){e&&window.history.go(e)}function s(e,t){t(window.confirm(e))}function f(){var e=navigator.userAgent;return-1===e.indexOf("Android 2.")&&-1===e.indexOf("Android 4.0")||-1===e.indexOf("Mobile Safari")||-1!==e.indexOf("Chrome")||-1!==e.indexOf("Windows Phone")?-1!==e.indexOf("CriOS")?!1:window.history&&"pushState"in window.history:!1}function c(){var e=navigator.userAgent;return-1===e.indexOf("Firefox")}t.__esModule=!0,t.addEventListener=n,t.removeEventListener=r,t.getHashPath=a,t.replaceHashPath=o,t.getWindowPath=u,t.go=i,t.getUserConfirmation=s,t.supportsHistory=f,t.supportsGoWithoutReloadUsingHash=c},function(e,t,n){"use strict";var r=function(e,t,n,r,a,o,u,i){if(!e){var s;if(void 0===t)s=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var f=[n,r,a,o,u,i],c=0;s=new Error("Invariant Violation: "+t.replace(/%s/g,function(){return f[c++]}))}throw s.framesToPop=1,s}};e.exports=r},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function a(e,t,n){var r=e(t,n);e.length<2&&n(r)}t.__esModule=!0;var o=n(3);r(o);t["default"]=a,e.exports=t["default"]},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function a(e){return s+e}function o(e,t){try{window.sessionStorage.setItem(a(e),JSON.stringify(t))}catch(n){if(n.name===c)return;if(n.name===f&&0===window.sessionStorage.length)return;throw n}}function u(e){var t=void 0;try{t=window.sessionStorage.getItem(a(e))}catch(n){if(n.name===c)return null}if(t)try{return JSON.parse(t)}catch(n){}return null}t.__esModule=!0,t.saveState=o,t.readState=u;var i=n(3),s=(r(i),"@@History/"),f="QuotaExceededError",c="SecurityError"},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function a(e){function t(e){return s.canUseDOM?void 0:i["default"](!1),n.listen(e)}var n=l["default"](o({getUserConfirmation:f.getUserConfirmation},e,{go:f.go}));return o({},n,{listen:t})}t.__esModule=!0;var o=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},u=n(7),i=r(u),s=n(5),f=n(6),c=n(11),l=r(c);t["default"]=a,e.exports=t["default"]},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function a(e){return Math.random().toString(36).substr(2,e)}function o(e,t){return e.pathname===t.pathname&&e.search===t.search&&e.key===t.key&&f["default"](e.state,t.state)}function u(){function e(e){return R.push(e),function(){R=R.filter(function(t){return t!==e})}}function t(){return I&&I.action===l.POP?q.indexOf(I.key):Q?q.indexOf(Q.key):-1}function n(e){var n=t();Q=e,Q.action===l.PUSH?q=[].concat(q.slice(0,n+1),[Q.key]):Q.action===l.REPLACE&&(q[n]=Q.key),D.forEach(function(e){e(Q)})}function r(e){if(D.push(e),Q)e(Q);else{var t=U();q=[t.key],n(t)}return function(){D=D.filter(function(t){return t!==e})}}function u(e,t){c.loopAsync(R.length,function(t,n,r){g["default"](R[t],e,function(e){null!=e?r(e):n()})},function(e){C&&"string"==typeof e?C(e,function(e){t(e!==!1)}):t(e!==!1)})}function s(e){Q&&o(Q,e)||(I=e,u(e,function(t){if(I===e)if(t){if(e.action===l.PUSH){var r=b(Q),a=b(e);a===r&&(e.action=l.REPLACE)}L(e)!==!1&&n(e)}else if(Q&&e.action===l.POP){var o=q.indexOf(Q.key),u=q.indexOf(e.key);-1!==o&&-1!==u&&B(o-u)}}))}function f(e){s(P(e,l.PUSH,m()))}function d(e){s(P(e,l.REPLACE,m()))}function h(){B(-1)}function v(){B(1)}function m(){return a(T)}function b(e){if(null==e||"string"==typeof e)return e;var t=e.pathname,n=e.search,r=e.hash,a=t;return n&&(a+=n),r&&(a+=r),a}function _(e){return b(e)}function P(e,t){var n=arguments.length<=2||void 0===arguments[2]?m():arguments[2];return"object"==typeof t&&("string"==typeof e&&(e=y["default"](e)),e=i({},e,{state:t}),t=n,n=arguments[3]||m()),p["default"](e,t,n)}function S(e){Q?(x(Q,e),n(Q)):x(U(),e)}function x(e,t){e.state=i({},e.state,t),A(e.key,e.state)}function H(e){-1===R.indexOf(e)&&R.push(e)}function k(e){R=R.filter(function(t){return t!==e})}function M(e,t){"string"==typeof t&&(t=y["default"](t)),f(i({state:e},t))}function j(e,t){"string"==typeof t&&(t=y["default"](t)),d(i({state:e},t))}var E=arguments.length<=0||void 0===arguments[0]?{}:arguments[0],U=E.getCurrentLocation,L=E.finishTransition,A=E.saveState,B=E.go,T=E.keyLength,C=E.getUserConfirmation;"number"!=typeof T&&(T=O);var R=[],q=[],D=[],Q=void 0,I=void 0;return{listenBefore:e,listen:r,transitionTo:s,push:f,replace:d,go:B,goBack:h,goForward:v,createKey:m,createPath:b,createHref:_,createLocation:P,setState:w["default"](S,"setState is deprecated; use location.key to save state instead"),registerTransitionHook:w["default"](H,"registerTransitionHook is deprecated; use listenBefore instead"),unregisterTransitionHook:w["default"](k,"unregisterTransitionHook is deprecated; use the callback returned from listenBefore instead"),pushState:w["default"](M,"pushState is deprecated; use push instead"),replaceState:w["default"](j,"replaceState is deprecated; use replace instead")}}t.__esModule=!0;var i=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s=n(23),f=r(s),c=n(16),l=n(4),d=n(12),p=r(d),h=n(8),g=r(h),v=n(2),y=r(v),m=n(1),w=r(m),O=6;t["default"]=u,e.exports=t["default"]},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function a(){var e=arguments.length<=0||void 0===arguments[0]?"/":arguments[0],t=arguments.length<=1||void 0===arguments[1]?u.POP:arguments[1],n=arguments.length<=2||void 0===arguments[2]?null:arguments[2],r=arguments.length<=3||void 0===arguments[3]?null:arguments[3];"string"==typeof e&&(e=s["default"](e)),"object"==typeof t&&(e=o({},e,{state:t}),t=n||u.POP,n=r);var a=e.pathname||"/",i=e.search||"",f=e.hash||"",c=e.state||null;return{pathname:a,search:i,hash:f,state:c,action:t,key:n}}t.__esModule=!0;var o=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},u=n(4),i=n(2),s=r(i);t["default"]=a,e.exports=t["default"]},function(e,t){"use strict";function n(e){var t=e.match(/^https?:\/\/[^\/]*/);return null==t?e:e.substring(t[0].length)}t.__esModule=!0,t["default"]=n,e.exports=t["default"]},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function a(e){function t(t){var n=e();return"string"==typeof n?((t||window.event).returnValue=n,n):void 0}return f.addEventListener(window,"beforeunload",t),function(){f.removeEventListener(window,"beforeunload",t)}}function o(e){return function(t){function n(){for(var e=void 0,t=0,n=d.length;null==e&&n>t;++t)e=d[t].call();return e}function r(e){return d.push(e),1===d.length&&s.canUseDOM&&(c=a(n)),function(){d=d.filter(function(t){return t!==e}),0===d.length&&c&&(c(),c=null)}}function o(e){s.canUseDOM&&-1===d.indexOf(e)&&(d.push(e),1===d.length&&(c=a(n)))}function i(e){d.length>0&&(d=d.filter(function(t){return t!==e}),0===d.length&&c())}var f=e(t),c=void 0,d=[];return u({},f,{listenBeforeUnload:r,registerBeforeUnloadHook:l["default"](o,"registerBeforeUnloadHook is deprecated; use listenBeforeUnload instead"),unregisterBeforeUnloadHook:l["default"](i,"unregisterBeforeUnloadHook is deprecated; use the callback returned from listenBeforeUnload instead")})}}t.__esModule=!0;var u=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},i=n(3),s=(r(i),n(5)),f=n(6),c=n(1),l=r(c);t["default"]=o,e.exports=t["default"]},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function a(e,t){var n={};for(var r in e)t.indexOf(r)>=0||Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=e[r]);return n}function o(e){return f.stringify(e).replace(/%20/g,"+")}function u(e){return function(){function t(e){if(null==e.query){var t=e.search;e.query=_(t.substring(1)),e[v]={search:t,searchBase:""}}return e}function n(e,t){var n,r=void 0;if(!t||""===(r=b(t)))return e;"string"==typeof e&&(e=p["default"](e));var a=e[v],o=void 0;o=a&&e.search===a.search?a.searchBase:e.search||"";var u=o+(o?"&":"?")+r;return i({},e,(n={search:u},n[v]={search:u,searchBase:o},n))}function r(e){return S.listenBefore(function(n,r){l["default"](e,t(n),r)})}function u(e){return S.listen(function(n){e(t(n))})}function s(e){S.push(n(e,e.query))}function f(e){S.replace(n(e,e.query))}function c(e,t){return S.createPath(n(e,t||e.query))}function d(e,t){return S.createHref(n(e,t||e.query))}function h(){return t(S.createLocation.apply(S,arguments))}function m(e,t,n){"string"==typeof t&&(t=p["default"](t)),s(i({state:e},t,{query:n}))}function w(e,t,n){"string"==typeof t&&(t=p["default"](t)),f(i({state:e},t,{query:n}))}var O=arguments.length<=0||void 0===arguments[0]?{}:arguments[0],b=O.stringifyQuery,_=O.parseQueryString,P=a(O,["stringifyQuery","parseQueryString"]),S=e(P);return"function"!=typeof b&&(b=o),"function"!=typeof _&&(_=y),i({},S,{listenBefore:r,listen:u,push:s,replace:f,createPath:c,createHref:d,createLocation:h,pushState:g["default"](m,"pushState is deprecated; use push instead"),replaceState:g["default"](w,"replaceState is deprecated; use replace instead")})}}t.__esModule=!0;var i=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s=n(3),f=(r(s),n(26)),c=n(8),l=r(c),d=n(2),p=r(d),h=n(1),g=r(h),v="$searchBase",y=f.parse;t["default"]=u,e.exports=t["default"]},function(e,t){"use strict";function n(e,t,n){function r(){u=!0,n.apply(this,arguments)}function a(){u||(e>o?t.call(this,o++,a,r):r.apply(this,arguments))}var o=0,u=!1;a()}t.__esModule=!0,t.loopAsync=n},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function a(){function e(e){e=e||window.history.state||{};var t=c.getWindowPath(),n=e,r=n.key,a=void 0;r?a=l.readState(r):(a=null,r=w.createKey(),y&&window.history.replaceState(o({},e,{key:r}),null,t));var u=g["default"](t);return w.createLocation(o({},u,{state:a}),void 0,r)}function t(t){function n(t){void 0!==t.state&&r(e(t.state))}var r=t.transitionTo;return c.addEventListener(window,"popstate",n),function(){c.removeEventListener(window,"popstate",n)}}function n(e){var t=e.basename,n=e.pathname,r=e.search,a=e.hash,o=e.state,u=e.action,i=e.key;if(u!==s.POP){l.saveState(i,o);var f=(t||"")+n+r+a,c={key:i};if(u===s.PUSH){if(m)return window.location.href=f,!1;window.history.pushState(c,null,f)}else{if(m)return window.location.replace(f),!1;window.history.replaceState(c,null,f)}}}function r(e){1===++O&&(b=t(w));var n=w.listenBefore(e);return function(){n(),0===--O&&b()}}function a(e){1===++O&&(b=t(w));var n=w.listen(e);return function(){n(),0===--O&&b()}}function u(e){1===++O&&(b=t(w)),w.registerTransitionHook(e)}function d(e){w.unregisterTransitionHook(e),0===--O&&b()}var h=arguments.length<=0||void 0===arguments[0]?{}:arguments[0];f.canUseDOM?void 0:i["default"](!1);var v=h.forceRefresh,y=c.supportsHistory(),m=!y||v,w=p["default"](o({},h,{getCurrentLocation:e,finishTransition:n,saveState:l.saveState})),O=0,b=void 0;return o({},w,{listenBefore:r,listen:a,registerTransitionHook:u,unregisterTransitionHook:d})}t.__esModule=!0;var o=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},u=n(7),i=r(u),s=n(4),f=n(5),c=n(6),l=n(9),d=n(10),p=r(d),h=n(2),g=r(h);t["default"]=a,e.exports=t["default"]},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function a(e){return"string"==typeof e&&"/"===e.charAt(0)}function o(){var e=v.getHashPath();return a(e)?!0:(v.replaceHashPath("/"+e),!1)}function u(e,t,n){return e+(-1===e.indexOf("?")?"?":"&")+(t+"="+n)}function i(e,t){return e.replace(new RegExp("[?&]?"+t+"=[a-zA-Z0-9]+"),"")}function s(e,t){var n=e.match(new RegExp("\\?.*?\\b"+t+"=(.+?)\\b"));return n&&n[1]}function f(){function e(){var e=v.getHashPath(),t=void 0,n=void 0;k?(t=s(e,k),e=i(e,k),t?n=y.readState(t):(n=null,t=M.createKey(),v.replaceHashPath(u(e,k,t)))):t=n=null;var r=b["default"](e);return M.createLocation(c({},r,{state:n}),void 0,t)}function t(t){function n(){o()&&r(e())}var r=t.transitionTo;return o(),v.addEventListener(window,"hashchange",n),function(){v.removeEventListener(window,"hashchange",n)}}function n(e){var t=e.basename,n=e.pathname,r=e.search,a=e.state,o=e.action,i=e.key;if(o!==h.POP){var s=(t||"")+n+r;k?(s=u(s,k,i),y.saveState(i,a)):e.key=e.state=null;var f=v.getHashPath();o===h.PUSH?f!==s&&(window.location.hash=s):f!==s&&v.replaceHashPath(s)}}function r(e){1===++j&&(E=t(M));var n=M.listenBefore(e);return function(){n(),0===--j&&E()}}function a(e){1===++j&&(E=t(M));var n=M.listen(e);return function(){n(),0===--j&&E()}}function f(e){M.push(e)}function l(e){M.replace(e)}function d(e){M.go(e)}function m(e){return"#"+M.createHref(e)}function O(e){1===++j&&(E=t(M)),M.registerTransitionHook(e)}function P(e){M.unregisterTransitionHook(e),0===--j&&E()}function S(e,t){M.pushState(e,t)}function x(e,t){M.replaceState(e,t)}var H=arguments.length<=0||void 0===arguments[0]?{}:arguments[0];g.canUseDOM?void 0:p["default"](!1);var k=H.queryKey;(void 0===k||k)&&(k="string"==typeof k?k:_);var M=w["default"](c({},H,{getCurrentLocation:e,finishTransition:n,saveState:y.saveState})),j=0,E=void 0;v.supportsGoWithoutReloadUsingHash();return c({},M,{listenBefore:r,listen:a,push:f,replace:l,go:d,createHref:m,registerTransitionHook:O,unregisterTransitionHook:P,pushState:S,replaceState:x})}t.__esModule=!0;var c=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},l=n(3),d=(r(l),n(7)),p=r(d),h=n(4),g=n(5),v=n(6),y=n(9),m=n(10),w=r(m),O=n(2),b=r(O),_="_k";t["default"]=f,e.exports=t["default"]},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function a(e){return e.filter(function(e){return e.state}).reduce(function(e,t){return e[t.key]=t.state,e},{})}function o(){function e(e,t){y[e]=t}function t(e){return y[e]}function n(){var e=g[v],n=e.key,r=e.basename,a=e.pathname,o=e.search,i=(r||"")+a+(o||""),s=void 0;n?s=t(n):(s=null,n=l.createKey(),e.key=n);var f=h["default"](i);return l.createLocation(u({},f,{state:s}),void 0,n)}function r(e){var t=v+e;return t>=0&&t<g.length}function o(e){if(e){if(!r(e))return;v+=e;var t=n();l.transitionTo(u({},t,{action:c.POP}))}}function i(t){switch(t.action){case c.PUSH:v+=1,v<g.length&&g.splice(v),g.push(t),e(t.key,t.state);break;case c.REPLACE:g[v]=t,e(t.key,t.state)}}var s=arguments.length<=0||void 0===arguments[0]?{}:arguments[0];Array.isArray(s)?s={entries:s}:"string"==typeof s&&(s={entries:[s]});var l=d["default"](u({},s,{getCurrentLocation:n,finishTransition:i,saveState:e,go:o})),p=s,g=p.entries,v=p.current;"string"==typeof g?g=[g]:Array.isArray(g)||(g=["/"]),g=g.map(function(e){var t=l.createKey();return"string"==typeof e?{pathname:e,key:t}:"object"==typeof e&&e?u({},e,{key:t}):void f["default"](!1)}),null==v?v=g.length-1:v>=0&&v<g.length?void 0:f["default"](!1);var y=a(g);return l}t.__esModule=!0;var u=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},i=n(3),s=(r(i),n(7)),f=r(s),c=n(4),l=n(11),d=r(l),p=n(2),h=r(p);t["default"]=o,e.exports=t["default"]},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}t.__esModule=!0;var a=n(1),o=r(a),u=n(14),i=r(u);t["default"]=o["default"](i["default"],"enableBeforeUnload is deprecated, use useBeforeUnload instead"),e.exports=t["default"]},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}t.__esModule=!0;var a=n(1),o=r(a),u=n(15),i=r(u);t["default"]=o["default"](i["default"],"enableQueries is deprecated, use useQueries instead"),e.exports=t["default"]},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function a(e,t){var n={};for(var r in e)t.indexOf(r)>=0||Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=e[r]);return n}function o(e){return function(){function t(e){return O&&null==e.basename&&(0===e.pathname.indexOf(O)?(e.pathname=e.pathname.substring(O.length),e.basename=O,""===e.pathname&&(e.pathname="/")):e.basename=""),e}function n(e){if(!O)return e;"string"==typeof e&&(e=p["default"](e));var t=e.pathname,n="/"===O.slice(-1)?O:O+"/",r="/"===t.charAt(0)?t.slice(1):t,a=n+r;return u({},e,{pathname:a})}function r(e){return _.listenBefore(function(n,r){f["default"](e,t(n),r)})}function o(e){return _.listen(function(n){e(t(n))})}function s(e){_.push(n(e))}function c(e){_.replace(n(e))}function d(e){return _.createPath(n(e))}function h(e){return _.createHref(n(e))}function v(){return t(_.createLocation.apply(_,arguments))}function y(e,t){"string"==typeof t&&(t=p["default"](t)),s(u({state:e},t))}function m(e,t){"string"==typeof t&&(t=p["default"](t)),c(u({state:e},t))}var w=arguments.length<=0||void 0===arguments[0]?{}:arguments[0],O=w.basename,b=a(w,["basename"]),_=e(b);if(null==O&&i.canUseDOM){var P=document.getElementsByTagName("base")[0];P&&(O=l["default"](P.href))}return u({},_,{listenBefore:r,listen:o,push:s,replace:c,createPath:d,createHref:h,createLocation:v,pushState:g["default"](y,"pushState is deprecated; use push instead"),replaceState:g["default"](m,"replaceState is deprecated; use replace instead")})}}t.__esModule=!0;var u=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},i=n(5),s=n(8),f=r(s),c=n(13),l=r(c),d=n(2),p=r(d),h=n(1),g=r(h);t["default"]=o,e.exports=t["default"]},function(e,t,n){function r(e){return null===e||void 0===e}function a(e){return e&&"object"==typeof e&&"number"==typeof e.length?"function"!=typeof e.copy||"function"!=typeof e.slice?!1:e.length>0&&"number"!=typeof e[0]?!1:!0:!1}function o(e,t,n){var o,c;if(r(e)||r(t))return!1;if(e.prototype!==t.prototype)return!1;if(s(e))return s(t)?(e=u.call(e),t=u.call(t),f(e,t,n)):!1;if(a(e)){if(!a(t))return!1;if(e.length!==t.length)return!1;for(o=0;o<e.length;o++)if(e[o]!==t[o])return!1;return!0}try{var l=i(e),d=i(t)}catch(p){return!1}if(l.length!=d.length)return!1;for(l.sort(),d.sort(),o=l.length-1;o>=0;o--)if(l[o]!=d[o])return!1;for(o=l.length-1;o>=0;o--)if(c=l[o],!f(e[c],t[c],n))return!1;return typeof e==typeof t}var u=Array.prototype.slice,i=n(25),s=n(24),f=e.exports=function(e,t,n){return n||(n={}),e===t?!0:e instanceof Date&&t instanceof Date?e.getTime()===t.getTime():!e||!t||"object"!=typeof e&&"object"!=typeof t?n.strict?e===t:e==t:o(e,t,n)}},function(e,t){function n(e){return"[object Arguments]"==Object.prototype.toString.call(e)}function r(e){return e&&"object"==typeof e&&"number"==typeof e.length&&Object.prototype.hasOwnProperty.call(e,"callee")&&!Object.prototype.propertyIsEnumerable.call(e,"callee")||!1}var a="[object Arguments]"==function(){return Object.prototype.toString.call(arguments)}();t=e.exports=a?n:r,t.supported=n,t.unsupported=r},function(e,t){function n(e){var t=[];for(var n in e)t.push(n);return t}t=e.exports="function"==typeof Object.keys?Object.keys:n,t.shim=n},function(e,t,n){"use strict";var r=n(27);t.extract=function(e){return e.split("?")[1]||""},t.parse=function(e){return"string"!=typeof e?{}:(e=e.trim().replace(/^(\?|#|&)/,""),e?e.split("&").reduce(function(e,t){var n=t.replace(/\+/g," ").split("="),r=n.shift(),a=n.length>0?n.join("="):void 0;return r=decodeURIComponent(r),a=void 0===a?null:decodeURIComponent(a),e.hasOwnProperty(r)?Array.isArray(e[r])?e[r].push(a):e[r]=[e[r],a]:e[r]=a,e},{}):{})},t.stringify=function(e){return e?Object.keys(e).sort().map(function(t){var n=e[t];return void 0===n?"":null===n?t:Array.isArray(n)?n.sort().map(function(e){return r(t)+"="+r(e)}).join("&"):r(t)+"="+r(n)}).filter(function(e){return e.length>0}).join("&"):""}},function(e,t){"use strict";e.exports=function(e){return encodeURIComponent(e).replace(/[!'()*]/g,function(e){return"%"+e.charCodeAt(0).toString(16)})}}])}); | ||
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.History=t():e.History=t()}(this,function(){return function(e){function t(r){if(n[r])return n[r].exports;var a=n[r]={exports:{},id:r,loaded:!1};return e[r].call(a.exports,a,a.exports,t),a.loaded=!0,a.exports}var n={};return t.m=e,t.c=n,t.p="",t(0)}([function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}t.__esModule=!0;var a=n(3),o=r(a),u=n(12),i=r(u),s=n(16),c=r(s);t.createHistory=c["default"];var f=n(17),l=r(f);t.createHashHistory=l["default"];var d=n(18),p=r(d);t.createMemoryHistory=p["default"];var h=n(21),g=r(h);t.useBasename=g["default"];var v=n(13),y=r(v);t.useBeforeUnload=y["default"];var m=n(14),w=r(m);t.useQueries=w["default"];var P=n(4),_=r(P);t.Actions=_["default"];var O=n(19),b=r(O);t.enableBeforeUnload=b["default"];var S=n(20),x=r(S);t.enableQueries=x["default"];var k=o["default"](i["default"],"Using createLocation without a history instance is deprecated; please use history.createLocation instead");t.createLocation=k},function(e,t,n){"use strict";var r=function(){};e.exports=r},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function a(e){var t=e.match(/^https?:\/\/[^\/]*/);return null==t?e:e.substring(t[0].length)}function o(e){var t=a(e),n="",r="",o=t.indexOf("#");-1!==o&&(r=t.substring(o),t=t.substring(0,o));var u=t.indexOf("?");return-1!==u&&(n=t.substring(u),t=t.substring(0,u)),""===t&&(t="/"),{pathname:t,search:n,hash:r}}t.__esModule=!0,t.extractPath=a,t.parsePath=o;var u=n(1);r(u)},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function a(e,t){return function(){return e.apply(this,arguments)}}t.__esModule=!0;var o=n(1);r(o);t["default"]=a,e.exports=t["default"]},function(e,t){"use strict";t.__esModule=!0;var n="PUSH";t.PUSH=n;var r="REPLACE";t.REPLACE=r;var a="POP";t.POP=a,t["default"]={PUSH:n,REPLACE:r,POP:a}},function(e,t){"use strict";t.__esModule=!0;var n=!("undefined"==typeof window||!window.document||!window.document.createElement);t.canUseDOM=n},function(e,t){"use strict";function n(e,t,n){e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent("on"+t,n)}function r(e,t,n){e.removeEventListener?e.removeEventListener(t,n,!1):e.detachEvent("on"+t,n)}function a(){return window.location.href.split("#")[1]||""}function o(e){window.location.replace(window.location.pathname+window.location.search+"#"+e)}function u(){return window.location.pathname+window.location.search+window.location.hash}function i(e){e&&window.history.go(e)}function s(e,t){t(window.confirm(e))}function c(){var e=navigator.userAgent;return-1===e.indexOf("Android 2.")&&-1===e.indexOf("Android 4.0")||-1===e.indexOf("Mobile Safari")||-1!==e.indexOf("Chrome")||-1!==e.indexOf("Windows Phone")?window.history&&"pushState"in window.history:!1}function f(){var e=navigator.userAgent;return-1===e.indexOf("Firefox")}t.__esModule=!0,t.addEventListener=n,t.removeEventListener=r,t.getHashPath=a,t.replaceHashPath=o,t.getWindowPath=u,t.go=i,t.getUserConfirmation=s,t.supportsHistory=c,t.supportsGoWithoutReloadUsingHash=f},function(e,t,n){"use strict";var r=function(e,t,n,r,a,o,u,i){if(!e){var s;if(void 0===t)s=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var c=[n,r,a,o,u,i],f=0;s=new Error(t.replace(/%s/g,function(){return c[f++]})),s.name="Invariant Violation"}throw s.framesToPop=1,s}};e.exports=r},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function a(e,t,n){var r=e(t,n);e.length<2&&n(r)}t.__esModule=!0;var o=n(1);r(o);t["default"]=a,e.exports=t["default"]},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function a(e){return s+e}function o(e,t){try{null==t?window.sessionStorage.removeItem(a(e)):window.sessionStorage.setItem(a(e),JSON.stringify(t))}catch(n){if(n.name===f)return;if(c.indexOf(n.name)>=0&&0===window.sessionStorage.length)return;throw n}}function u(e){var t=void 0;try{t=window.sessionStorage.getItem(a(e))}catch(n){if(n.name===f)return null}if(t)try{return JSON.parse(t)}catch(n){}return null}t.__esModule=!0,t.saveState=o,t.readState=u;var i=n(1),s=(r(i),"@@History/"),c=["QuotaExceededError","QUOTA_EXCEEDED_ERR"],f="SecurityError"},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function a(e){function t(e){return s.canUseDOM?void 0:i["default"](!1),n.listen(e)}var n=l["default"](o({getUserConfirmation:c.getUserConfirmation},e,{go:c.go}));return o({},n,{listen:t})}t.__esModule=!0;var o=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},u=n(7),i=r(u),s=n(5),c=n(6),f=n(11),l=r(f);t["default"]=a,e.exports=t["default"]},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function a(e){return Math.random().toString(36).substr(2,e)}function o(e,t){return e.pathname===t.pathname&&e.search===t.search&&e.key===t.key&&f["default"](e.state,t.state)}function u(){function e(e){return q.push(e),function(){q=q.filter(function(t){return t!==e})}}function t(){return K&&K.action===p.POP?D.indexOf(K.key):Q?D.indexOf(Q.key):-1}function n(e){var n=t();Q=e,Q.action===p.PUSH?D=[].concat(D.slice(0,n+1),[Q.key]):Q.action===p.REPLACE&&(D[n]=Q.key),I.forEach(function(e){e(Q)})}function r(e){if(I.push(e),Q)e(Q);else{var t=L();D=[t.key],n(t)}return function(){I=I.filter(function(t){return t!==e})}}function u(e,t){d.loopAsync(q.length,function(t,n,r){y["default"](q[t],e,function(e){null!=e?r(e):n()})},function(e){C&&"string"==typeof e?C(e,function(e){t(e!==!1)}):t(e!==!1)})}function s(e){Q&&o(Q,e)||(K=e,u(e,function(t){if(K===e)if(t){if(e.action===p.PUSH){var r=O(Q),a=O(e);a===r&&f["default"](Q.state,e.state)&&(e.action=p.REPLACE)}A(e)!==!1&&n(e)}else if(Q&&e.action===p.POP){var o=D.indexOf(Q.key),u=D.indexOf(e.key);-1!==o&&-1!==u&&T(o-u)}}))}function c(e){s(S(e,p.PUSH,_()))}function h(e){s(S(e,p.REPLACE,_()))}function v(){T(-1)}function m(){T(1)}function _(){return a(R)}function O(e){if(null==e||"string"==typeof e)return e;var t=e.pathname,n=e.search,r=e.hash,a=t;return n&&(a+=n),r&&(a+=r),a}function b(e){return O(e)}function S(e,t){var n=arguments.length<=2||void 0===arguments[2]?_():arguments[2];return"object"==typeof t&&("string"==typeof e&&(e=l.parsePath(e)),e=i({},e,{state:t}),t=n,n=arguments[3]||_()),g["default"](e,t,n)}function x(e){Q?(k(Q,e),n(Q)):k(L(),e)}function k(e,t){e.state=i({},e.state,t),B(e.key,e.state)}function H(e){-1===q.indexOf(e)&&q.push(e)}function M(e){q=q.filter(function(t){return t!==e})}function E(e,t){"string"==typeof t&&(t=l.parsePath(t)),c(i({state:e},t))}function j(e,t){"string"==typeof t&&(t=l.parsePath(t)),h(i({state:e},t))}var U=arguments.length<=0||void 0===arguments[0]?{}:arguments[0],L=U.getCurrentLocation,A=U.finishTransition,B=U.saveState,T=U.go,C=U.getUserConfirmation,R=U.keyLength;"number"!=typeof R&&(R=P);var q=[],D=[],I=[],Q=void 0,K=void 0;return{listenBefore:e,listen:r,transitionTo:s,push:c,replace:h,go:T,goBack:v,goForward:m,createKey:_,createPath:O,createHref:b,createLocation:S,setState:w["default"](x,"setState is deprecated; use location.key to save state instead"),registerTransitionHook:w["default"](H,"registerTransitionHook is deprecated; use listenBefore instead"),unregisterTransitionHook:w["default"](M,"unregisterTransitionHook is deprecated; use the callback returned from listenBefore instead"),pushState:w["default"](E,"pushState is deprecated; use push instead"),replaceState:w["default"](j,"replaceState is deprecated; use replace instead")}}t.__esModule=!0;var i=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s=n(1),c=(r(s),n(22)),f=r(c),l=n(2),d=n(15),p=n(4),h=n(12),g=r(h),v=n(8),y=r(v),m=n(3),w=r(m),P=6;t["default"]=u,e.exports=t["default"]},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function a(){var e=arguments.length<=0||void 0===arguments[0]?"/":arguments[0],t=arguments.length<=1||void 0===arguments[1]?i.POP:arguments[1],n=arguments.length<=2||void 0===arguments[2]?null:arguments[2],r=arguments.length<=3||void 0===arguments[3]?null:arguments[3];"string"==typeof e&&(e=s.parsePath(e)),"object"==typeof t&&(e=o({},e,{state:t}),t=n||i.POP,n=r);var a=e.pathname||"/",u=e.search||"",c=e.hash||"",f=e.state||null;return{pathname:a,search:u,hash:c,state:f,action:t,key:n}}t.__esModule=!0;var o=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},u=n(1),i=(r(u),n(4)),s=n(2);t["default"]=a,e.exports=t["default"]},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function a(e){function t(t){var n=e();return"string"==typeof n?((t||window.event).returnValue=n,n):void 0}return c.addEventListener(window,"beforeunload",t),function(){c.removeEventListener(window,"beforeunload",t)}}function o(e){return function(t){function n(){for(var e=void 0,t=0,n=d.length;null==e&&n>t;++t)e=d[t].call();return e}function r(e){return d.push(e),1===d.length&&s.canUseDOM&&(f=a(n)),function(){d=d.filter(function(t){return t!==e}),0===d.length&&f&&(f(),f=null)}}function o(e){s.canUseDOM&&-1===d.indexOf(e)&&(d.push(e),1===d.length&&(f=a(n)))}function i(e){d.length>0&&(d=d.filter(function(t){return t!==e}),0===d.length&&f())}var c=e(t),f=void 0,d=[];return u({},c,{listenBeforeUnload:r,registerBeforeUnloadHook:l["default"](o,"registerBeforeUnloadHook is deprecated; use listenBeforeUnload instead"),unregisterBeforeUnloadHook:l["default"](i,"unregisterBeforeUnloadHook is deprecated; use the callback returned from listenBeforeUnload instead")})}}t.__esModule=!0;var u=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},i=n(1),s=(r(i),n(5)),c=n(6),f=n(3),l=r(f);t["default"]=o,e.exports=t["default"]},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function a(e){return s.stringify(e).replace(/%20/g,"+")}function o(e){return function(){function t(e){if(null==e.query){var t=e.search;e.query=O(t.substring(1)),e[h]={search:t,searchBase:""}}return e}function n(e,t){var n,r=e[h],a=t?_(t):"";if(!r&&!a)return e;"string"==typeof e&&(e=l.parsePath(e));var o=void 0;o=r&&e.search===r.search?r.searchBase:e.search||"";var i=o;return a&&(i+=(i?"&":"?")+a),u({},e,(n={search:i},n[h]={search:i,searchBase:o},n))}function r(e){return P.listenBefore(function(n,r){f["default"](e,t(n),r)})}function o(e){return P.listen(function(n){e(t(n))})}function i(e){P.push(n(e,e.query))}function s(e){P.replace(n(e,e.query))}function c(e,t){return P.createPath(n(e,t||e.query))}function d(e,t){return P.createHref(n(e,t||e.query))}function v(e){for(var r=arguments.length,a=Array(r>1?r-1:0),o=1;r>o;o++)a[o-1]=arguments[o];var u=P.createLocation.apply(P,[n(e,e.query)].concat(a));return e.query&&(u.query=e.query),t(u)}function y(e,t,n){"string"==typeof t&&(t=l.parsePath(t)),i(u({state:e},t,{query:n}))}function m(e,t,n){"string"==typeof t&&(t=l.parsePath(t)),s(u({state:e},t,{query:n}))}var w=arguments.length<=0||void 0===arguments[0]?{}:arguments[0],P=e(w),_=w.stringifyQuery,O=w.parseQueryString;return"function"!=typeof _&&(_=a),"function"!=typeof O&&(O=g),u({},P,{listenBefore:r,listen:o,push:i,replace:s,createPath:c,createHref:d,createLocation:v,pushState:p["default"](y,"pushState is deprecated; use push instead"),replaceState:p["default"](m,"replaceState is deprecated; use replace instead")})}}t.__esModule=!0;var u=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},i=n(1),s=(r(i),n(25)),c=n(8),f=r(c),l=n(2),d=n(3),p=r(d),h="$searchBase",g=s.parse;t["default"]=o,e.exports=t["default"]},function(e,t){"use strict";function n(e,t,n){function a(){return i=!0,s?void(f=[].concat(r.call(arguments))):void n.apply(this,arguments)}function o(){if(!i&&(c=!0,!s)){for(s=!0;!i&&e>u&&c;)c=!1,t.call(this,u++,o,a);return s=!1,i?void n.apply(this,f):void(u>=e&&c&&(i=!0,n()))}}var u=0,i=!1,s=!1,c=!1,f=void 0;o()}t.__esModule=!0;var r=Array.prototype.slice;t.loopAsync=n},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function a(){function e(e){e=e||window.history.state||{};var t=l.getWindowPath(),n=e,r=n.key,a=void 0;r?a=d.readState(r):(a=null,r=w.createKey(),y&&window.history.replaceState(o({},e,{key:r}),null,t));var u=c.parsePath(t);return w.createLocation(o({},u,{state:a}),void 0,r)}function t(t){function n(t){void 0!==t.state&&r(e(t.state))}var r=t.transitionTo;return l.addEventListener(window,"popstate",n),function(){l.removeEventListener(window,"popstate",n)}}function n(e){var t=e.basename,n=e.pathname,r=e.search,a=e.hash,o=e.state,u=e.action,i=e.key;if(u!==s.POP){d.saveState(i,o);var c=(t||"")+n+r+a,f={key:i};if(u===s.PUSH){if(m)return window.location.href=c,!1;window.history.pushState(f,null,c)}else{if(m)return window.location.replace(c),!1;window.history.replaceState(f,null,c)}}}function r(e){1===++P&&(_=t(w));var n=w.listenBefore(e);return function(){n(),0===--P&&_()}}function a(e){1===++P&&(_=t(w));var n=w.listen(e);return function(){n(),0===--P&&_()}}function u(e){1===++P&&(_=t(w)),w.registerTransitionHook(e)}function p(e){w.unregisterTransitionHook(e),0===--P&&_()}var g=arguments.length<=0||void 0===arguments[0]?{}:arguments[0];f.canUseDOM?void 0:i["default"](!1);var v=g.forceRefresh,y=l.supportsHistory(),m=!y||v,w=h["default"](o({},g,{getCurrentLocation:e,finishTransition:n,saveState:d.saveState})),P=0,_=void 0;return o({},w,{listenBefore:r,listen:a,registerTransitionHook:u,unregisterTransitionHook:p})}t.__esModule=!0;var o=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},u=n(7),i=r(u),s=n(4),c=n(2),f=n(5),l=n(6),d=n(9),p=n(10),h=r(p);t["default"]=a,e.exports=t["default"]},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function a(e){return"string"==typeof e&&"/"===e.charAt(0)}function o(){var e=y.getHashPath();return a(e)?!0:(y.replaceHashPath("/"+e),!1)}function u(e,t,n){return e+(-1===e.indexOf("?")?"?":"&")+(t+"="+n)}function i(e,t){return e.replace(new RegExp("[?&]?"+t+"=[a-zA-Z0-9]+"),"")}function s(e,t){var n=e.match(new RegExp("\\?.*?\\b"+t+"=(.+?)\\b"));return n&&n[1]}function c(){function e(){var e=y.getHashPath(),t=void 0,n=void 0;H?(t=s(e,H),e=i(e,H),t?n=m.readState(t):(n=null,t=M.createKey(),y.replaceHashPath(u(e,H,t)))):t=n=null;var r=g.parsePath(e);return M.createLocation(f({},r,{state:n}),void 0,t)}function t(t){function n(){o()&&r(e())}var r=t.transitionTo;return o(),y.addEventListener(window,"hashchange",n),function(){y.removeEventListener(window,"hashchange",n)}}function n(e){var t=e.basename,n=e.pathname,r=e.search,a=e.state,o=e.action,i=e.key;if(o!==h.POP){var s=(t||"")+n+r;H?(s=u(s,H,i),m.saveState(i,a)):e.key=e.state=null;var c=y.getHashPath();o===h.PUSH?c!==s&&(window.location.hash=s):c!==s&&y.replaceHashPath(s)}}function r(e){1===++E&&(j=t(M));var n=M.listenBefore(e);return function(){n(),0===--E&&j()}}function a(e){1===++E&&(j=t(M));var n=M.listen(e);return function(){n(),0===--E&&j()}}function c(e){M.push(e)}function l(e){M.replace(e)}function d(e){M.go(e)}function w(e){return"#"+M.createHref(e)}function O(e){1===++E&&(j=t(M)),M.registerTransitionHook(e)}function b(e){M.unregisterTransitionHook(e),0===--E&&j()}function S(e,t){M.pushState(e,t)}function x(e,t){M.replaceState(e,t)}var k=arguments.length<=0||void 0===arguments[0]?{}:arguments[0];v.canUseDOM?void 0:p["default"](!1);var H=k.queryKey;(void 0===H||H)&&(H="string"==typeof H?H:_);var M=P["default"](f({},k,{getCurrentLocation:e,finishTransition:n,saveState:m.saveState})),E=0,j=void 0;y.supportsGoWithoutReloadUsingHash();return f({},M,{listenBefore:r,listen:a,push:c,replace:l,go:d,createHref:w,registerTransitionHook:O,unregisterTransitionHook:b,pushState:S,replaceState:x})}t.__esModule=!0;var f=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},l=n(1),d=(r(l),n(7)),p=r(d),h=n(4),g=n(2),v=n(5),y=n(6),m=n(9),w=n(10),P=r(w),_="_k";t["default"]=c,e.exports=t["default"]},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function a(e){return e.filter(function(e){return e.state}).reduce(function(e,t){return e[t.key]=t.state,e},{})}function o(){function e(e,t){y[e]=t}function t(e){return y[e]}function n(){var e=g[v],n=e.basename,r=e.pathname,a=e.search,o=(n||"")+r+(a||""),i=void 0,s=void 0;e.key?(i=e.key,s=t(i)):(i=d.createKey(),s=null,e.key=i);var c=f.parsePath(o);return d.createLocation(u({},c,{state:s}),void 0,i)}function r(e){var t=v+e;return t>=0&&t<g.length}function o(e){if(e){if(!r(e))return;v+=e;var t=n();d.transitionTo(u({},t,{action:l.POP}))}}function i(t){switch(t.action){case l.PUSH:v+=1,v<g.length&&g.splice(v),g.push(t),e(t.key,t.state);break;case l.REPLACE:g[v]=t,e(t.key,t.state)}}var s=arguments.length<=0||void 0===arguments[0]?{}:arguments[0];Array.isArray(s)?s={entries:s}:"string"==typeof s&&(s={entries:[s]});var d=p["default"](u({},s,{getCurrentLocation:n,finishTransition:i,saveState:e,go:o})),h=s,g=h.entries,v=h.current;"string"==typeof g?g=[g]:Array.isArray(g)||(g=["/"]),g=g.map(function(e){var t=d.createKey();return"string"==typeof e?{pathname:e,key:t}:"object"==typeof e&&e?u({},e,{key:t}):void c["default"](!1)}),null==v?v=g.length-1:v>=0&&v<g.length?void 0:c["default"](!1);var y=a(g);return d}t.__esModule=!0;var u=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},i=n(1),s=(r(i),n(7)),c=r(s),f=n(2),l=n(4),d=n(11),p=r(d);t["default"]=o,e.exports=t["default"]},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}t.__esModule=!0;var a=n(3),o=r(a),u=n(13),i=r(u);t["default"]=o["default"](i["default"],"enableBeforeUnload is deprecated, use useBeforeUnload instead"),e.exports=t["default"]},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}t.__esModule=!0;var a=n(3),o=r(a),u=n(14),i=r(u);t["default"]=o["default"](i["default"],"enableQueries is deprecated, use useQueries instead"),e.exports=t["default"]},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function a(e){return function(){function t(e){return w&&null==e.basename&&(0===e.pathname.indexOf(w)?(e.pathname=e.pathname.substring(w.length),e.basename=w,""===e.pathname&&(e.pathname="/")):e.basename=""),e}function n(e){if(!w)return e;"string"==typeof e&&(e=i.parsePath(e));var t=e.pathname,n="/"===w.slice(-1)?w:w+"/",r="/"===t.charAt(0)?t.slice(1):t,a=n+r;return o({},e,{pathname:a})}function r(e){return m.listenBefore(function(n,r){c["default"](e,t(n),r)})}function a(e){return m.listen(function(n){e(t(n))})}function s(e){m.push(n(e))}function f(e){m.replace(n(e))}function d(e){return m.createPath(n(e))}function p(e){return m.createHref(n(e))}function h(e){for(var r=arguments.length,a=Array(r>1?r-1:0),o=1;r>o;o++)a[o-1]=arguments[o];return t(m.createLocation.apply(m,[n(e)].concat(a)))}function g(e,t){"string"==typeof t&&(t=i.parsePath(t)),s(o({state:e},t))}function v(e,t){"string"==typeof t&&(t=i.parsePath(t)),f(o({state:e},t))}var y=arguments.length<=0||void 0===arguments[0]?{}:arguments[0],m=e(y),w=y.basename;if(null==w&&u.canUseDOM){var P=document.getElementsByTagName("base")[0];P&&(w=i.extractPath(P.href))}return o({},m,{listenBefore:r,listen:a,push:s,replace:f,createPath:d,createHref:p,createLocation:h,pushState:l["default"](g,"pushState is deprecated; use push instead"),replaceState:l["default"](v,"replaceState is deprecated; use replace instead")})}}t.__esModule=!0;var o=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},u=n(5),i=n(2),s=n(8),c=r(s),f=n(3),l=r(f);t["default"]=a,e.exports=t["default"]},function(e,t,n){function r(e){return null===e||void 0===e}function a(e){return e&&"object"==typeof e&&"number"==typeof e.length?"function"!=typeof e.copy||"function"!=typeof e.slice?!1:e.length>0&&"number"!=typeof e[0]?!1:!0:!1}function o(e,t,n){var o,f;if(r(e)||r(t))return!1;if(e.prototype!==t.prototype)return!1;if(s(e))return s(t)?(e=u.call(e),t=u.call(t),c(e,t,n)):!1;if(a(e)){if(!a(t))return!1;if(e.length!==t.length)return!1;for(o=0;o<e.length;o++)if(e[o]!==t[o])return!1;return!0}try{var l=i(e),d=i(t)}catch(p){return!1}if(l.length!=d.length)return!1;for(l.sort(),d.sort(),o=l.length-1;o>=0;o--)if(l[o]!=d[o])return!1;for(o=l.length-1;o>=0;o--)if(f=l[o],!c(e[f],t[f],n))return!1;return typeof e==typeof t}var u=Array.prototype.slice,i=n(24),s=n(23),c=e.exports=function(e,t,n){return n||(n={}),e===t?!0:e instanceof Date&&t instanceof Date?e.getTime()===t.getTime():!e||!t||"object"!=typeof e&&"object"!=typeof t?n.strict?e===t:e==t:o(e,t,n)}},function(e,t){function n(e){return"[object Arguments]"==Object.prototype.toString.call(e)}function r(e){return e&&"object"==typeof e&&"number"==typeof e.length&&Object.prototype.hasOwnProperty.call(e,"callee")&&!Object.prototype.propertyIsEnumerable.call(e,"callee")||!1}var a="[object Arguments]"==function(){return Object.prototype.toString.call(arguments)}();t=e.exports=a?n:r,t.supported=n,t.unsupported=r},function(e,t){function n(e){var t=[];for(var n in e)t.push(n);return t}t=e.exports="function"==typeof Object.keys?Object.keys:n,t.shim=n},function(e,t,n){"use strict";var r=n(26);t.extract=function(e){return e.split("?")[1]||""},t.parse=function(e){return"string"!=typeof e?{}:(e=e.trim().replace(/^(\?|#|&)/,""),e?e.split("&").reduce(function(e,t){var n=t.replace(/\+/g," ").split("="),r=n.shift(),a=n.length>0?n.join("="):void 0;return r=decodeURIComponent(r),a=void 0===a?null:decodeURIComponent(a),e.hasOwnProperty(r)?Array.isArray(e[r])?e[r].push(a):e[r]=[e[r],a]:e[r]=a,e},{}):{})},t.stringify=function(e){return e?Object.keys(e).sort().map(function(t){var n=e[t];return void 0===n?"":null===n?t:Array.isArray(n)?n.sort().map(function(e){return r(t)+"="+r(e)}).join("&"):r(t)+"="+r(n)}).filter(function(e){return e.length>0}).join("&"):""}},function(e,t){"use strict";e.exports=function(e){return encodeURIComponent(e).replace(/[!'()*]/g,function(e){return"%"+e.charCodeAt(0).toString(16).toUpperCase()})}}])}); |
{ | ||
"name": "react-gpt", | ||
"version": "0.0.6", | ||
"version": "0.1.0", | ||
"description": "A react display ad component using Google Publisher Tag", | ||
@@ -27,33 +27,75 @@ "main": "lib/index.js", | ||
}, | ||
"files": [ | ||
"*.md", | ||
"docs", | ||
"src", | ||
"lib" | ||
], | ||
"dependencies": { | ||
"core-js": "^1.2.6", | ||
"core-js": "^2.1.1", | ||
"debounce": "^1.0.0", | ||
"fbjs": "^0.4.0", | ||
"querystring": "^0.2.0", | ||
"react": "^0.14.3", | ||
"react-dom": "^0.14.3", | ||
"deep-equal": "^1.0.1", | ||
"eventemitter3": "^1.1.1", | ||
"fbjs": "^0.7.2", | ||
"hoist-non-react-statics": "^1.0.5", | ||
"immutable": "^3.7.5", | ||
"react": "^0.14.6", | ||
"react-dom": "^0.14.6", | ||
"rimraf": "^2.4.4" | ||
}, | ||
"devDependencies": { | ||
"babel": "^5.8.21", | ||
"babel-core": "^5.8.22", | ||
"babel-eslint": "^4.1.6", | ||
"babel-loader": "^5.3.2", | ||
"eslint": "^1.10.1", | ||
"eslint-config-nfl": "^4.0.2", | ||
"hoist-non-react-statics": "^1.0.3", | ||
"webpack": "^1.12.9", | ||
"webpack-dev-server": "^1.14.0" | ||
"babel-cli": "^6.5.1", | ||
"babel-core": "^6.5.1", | ||
"babel-eslint": "^5.0.0", | ||
"babel-loader": "^6.2.3", | ||
"babel-plugin-transform-decorators-legacy": "^1.3.4", | ||
"babel-preset-es2015-without-strict": "^0.0.2", | ||
"babel-preset-react": "^6.5.0", | ||
"babel-preset-stage-0": "^6.5.0", | ||
"babel-register": "^6.7.2", | ||
"chai": "^3.4.1", | ||
"eslint": "2.4.0", | ||
"eslint-config-nfl": "6.1.0", | ||
"eslint-plugin-import": "1.0.4", | ||
"eslint-plugin-mocha": "2.0.0", | ||
"eslint-plugin-react": "4.2.1", | ||
"estraverse": "4.2.0", | ||
"estraverse-fb": "1.3.1", | ||
"express": "^4.13.4", | ||
"history": "^2.0.1", | ||
"isparta-loader": "^2.0.0", | ||
"karma": "^0.13.19", | ||
"karma-chai-sinon": "^0.1.5", | ||
"karma-chrome-launcher": "^0.2.2", | ||
"karma-cli": "^0.1.2", | ||
"karma-coverage": "^0.5.3", | ||
"karma-mocha": "^0.2.1", | ||
"karma-mocha-reporter": "^2.0.0", | ||
"karma-sourcemap-loader": "^0.3.6", | ||
"karma-tap-reporter": "0.0.6", | ||
"karma-webpack": "^1.7.0", | ||
"mocha": "^2.3.4", | ||
"phantom": "^2.0.4", | ||
"querystring": "^0.2.0", | ||
"radium": "^0.16.6", | ||
"react-addons-test-utils": "^0.14.6", | ||
"serve-static": "^1.10.2", | ||
"sinon": "^1.17.2", | ||
"sinon-chai": "^2.8.0", | ||
"webpack": "^1.4.13", | ||
"webpack-dev-middleware": "^1.5.1", | ||
"webpack-dev-server": "^1.14.1" | ||
}, | ||
"scripts": { | ||
"build": "npm run clean && npm run compile", | ||
"clean": "rimraf lib", | ||
"clean": "rimraf lib coverage", | ||
"compile": "babel src --out-dir lib", | ||
"examples": "webpack-dev-server --config examples/webpack.config.js --content-base examples --inline", | ||
"lint": "eslint src examples", | ||
"examples": "webpack-dev-server --config examples/webpack.config.js --content-base examples/apps --inline", | ||
"lint": "eslint src test examples", | ||
"start": "node examples/server/index.js", | ||
"pretest": "npm run build", | ||
"prepublish": "npm run build", | ||
"test": "echo \"Error: no test specified\" && exit 1", | ||
"postinstall": "node ./npm-scripts/postinstall.js" | ||
"test": "npm run lint && karma start", | ||
"update-apilist": "node ./scripts/updateAPIList.js" | ||
} | ||
} |
@@ -1,56 +0,64 @@ | ||
<!-- START doctoc generated TOC please keep comment here to allow auto update --> | ||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --> | ||
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)* | ||
<img src="http://static.nfl.com/static/content/public/static/img/logos/nfl-engineering-light.svg" width="300" /> | ||
# React GPT | ||
- [Ad](#ad) | ||
- [Goal](#goal) | ||
- [Terms](#terms) | ||
- [Links](#links) | ||
- [TODO](#todo) | ||
A [React](https://github.com/facebook/react) component for [Google Publisher Tags](https://developers.google.com/doubleclick-gpt/?hl=en). | ||
<!-- END doctoc generated TOC please keep comment here to allow auto update --> | ||
## Requirements | ||
# Ad | ||
* React 0.14+ | ||
## Goal | ||
## Browser Requirements | ||
To create a reusable component for displaying GPT Ads of any size. | ||
* IE10+ | ||
We'll provide an interface for developers to code the following types of Ads: | ||
## Features | ||
* Medium Rectangle | ||
* Rectangle | ||
* Wide Skyscraper | ||
* Leaderboard | ||
* Super Leaderboard | ||
* Half Page | ||
* Button 2 | ||
* Micro Bar | ||
* Supports all rendering mode(single request mode, async rendering node and *sync rendering mode) | ||
* Supports responsive ads. | ||
* Supports interstitial ads. | ||
* Supports lazy render. | ||
We'll also provide monitoring (successes/failures/notifications) of Ads. | ||
\* Synchronous rendering requires that the GPT JavaScript be loaded synchronously. | ||
## Terms | ||
## Installation | ||
* GPT - Google Publisher Tags | ||
* UAP - Universal Ad Package | ||
* OAU - Other Ad Units | ||
* Medium Rectangle - Ad type of size 300x250, expansion not allowed | ||
* Rectangle - Ad type of size 180x150, expansion not allowed | ||
* Wide Skyscraper - Ad type of size 160x600, expansion not allowed | ||
* Leaderboard - Ad type of size 728x90, expansion not allowed | ||
* Super Leaderboard - Ad type of size 970x90, expansion not allowed | ||
* Half Page - Ad type of size 300x600, expansion not allowed | ||
* Button 2 - Ad type of size 120x60, expansion not allowed | ||
* Micro Bar - Ad type of size 88x31, expansion not allowed | ||
``` | ||
$ npm install --save react-gpt | ||
``` | ||
## Links | ||
## Getting Started | ||
* [Google Publisher Tags (GPT)](https://support.google.com/dfp_sb/topic/1651546?hl=en&ref_topic=1405) | ||
* [IAB Display Advertising Guidelines](http://www.iab.net/guidelines/508676/508767/displayguidelines) | ||
Import React GPT and pass props to the component. | ||
## TODO | ||
```javascript | ||
import {Bling as GPT} from "react-gpt"; | ||
1. Create placeholder ad | ||
2. Create non-expandable (UAP/OAU) ad | ||
3. Create expandable (Rising Stars) ad | ||
4. Create responsive ad | ||
class Application extends React.Component { | ||
render() { | ||
return ( | ||
<GPT | ||
adUnitPath="/4595/nfl.test.open" | ||
slotSize={[728, 90]} | ||
/> | ||
); | ||
} | ||
} | ||
``` | ||
## To run examples: | ||
1. Clone this repo | ||
2. Run `npm install` | ||
3. Run `npm run examples` for client side rendering, `npm start` for server side rendering. | ||
4. Point your browser to http://localhost:8080 | ||
## Contributing to this project | ||
Please take a moment to review the [guidelines for contributing](CONTRIBUTING.md). | ||
* [Pull requests](CONTRIBUTING.md#pull-requests) | ||
* [Development Process](CONTRIBUTING.md#development) | ||
## License | ||
MIT |
769
src/Bling.js
/* eslint-disable react/sort-comp */ | ||
import React, {Component, PropTypes} from "react"; | ||
import ReactDOM from "react-dom"; | ||
import deepEqual from "deep-equal"; | ||
import invariant from "fbjs/lib/invariant"; | ||
import Immutable from "immutable"; | ||
import hoistStatics from "hoist-non-react-statics"; | ||
import Events from "./Events"; | ||
import {toJS, isImmutableListOrMap} from "./utils/immutableHelper"; | ||
import {createManager, pubadsAPI} from "./createManager"; | ||
/** | ||
@@ -9,23 +17,173 @@ * An Ad Component using Google Publisher Tags. | ||
* @module Bling | ||
* @class Bling | ||
* @fires Bling#Events.READY | ||
* @fires Bling#Events.SLOT_RENDER_ENDED | ||
* @fires Bling#Events.IMPRESSION_VIEWABLE | ||
* @fires Bling#Events.SLOT_VISIBILITY_CHANGED | ||
*/ | ||
let adCnt = 0; | ||
const generateDivId = () => { | ||
return `ad-${++adCnt}-${Date.now()}`; | ||
}; | ||
let promise; | ||
class Bling extends Component { | ||
static propTypes = { | ||
/** | ||
* An optional string for GPT seed file url to override. | ||
* | ||
* @property seedFileUrl | ||
*/ | ||
seedFileUrl: PropTypes.string, | ||
/** | ||
* An optional string indicating ad unit path which will be used | ||
* if specified over the rest of the props which constructs 'adUnitPath'. | ||
* | ||
* @property adUnitPath | ||
*/ | ||
adUnitPath: PropTypes.string.isRequired, | ||
targeting: PropTypes.object, | ||
slotSize: PropTypes.array, | ||
sizeMapping: PropTypes.arrayOf(PropTypes.shape({ | ||
viewport: PropTypes.array, | ||
slot: PropTypes.array | ||
})), | ||
companionAd: PropTypes.bool, | ||
collapseEmptyDiv: PropTypes.bool, | ||
onRendered: PropTypes.func, | ||
invalidated: PropTypes.bool | ||
/** | ||
* An optional object which includes ad targeting key-value pairs. | ||
* | ||
* @property targeting | ||
*/ | ||
targeting: PropTypes.oneOfType([ | ||
PropTypes.object, | ||
PropTypes.instanceOf(Immutable.Map) | ||
]), | ||
/** | ||
* An optional array of width and height size for the ad slot. | ||
* This will be preceded by the sizeMapping if specified. | ||
* | ||
* @property slotSize | ||
*/ | ||
slotSize: PropTypes.oneOfType([ | ||
PropTypes.array, | ||
PropTypes.instanceOf(Immutable.List) | ||
]), | ||
/** | ||
* An optional array of object which contains an array of viewport size and slot size. | ||
* This needs to be set if the ad needs to serve different ad sizes per different viewport sizes (responsive ad). | ||
* If the empty array is provided as an ad slot for the particular viewport size, the ad won't be served for the viewport size. | ||
* The ad slot size which is provided for the viewport size of [0, 0] will be used as default ad size if none of viewport size matches. | ||
* | ||
* https://support.google.com/dfp_premium/answer/3423562?hl=en | ||
* | ||
* e.g. | ||
* | ||
* sizeMapping={[ | ||
* {viewport: [0, 0], slot: [320, 50]}, | ||
* {viewport: [768, 0], slot: [728, 90]} | ||
* ]} | ||
* | ||
* @property sizeMapping | ||
*/ | ||
sizeMapping: PropTypes.oneOfType([ | ||
PropTypes.arrayOf(PropTypes.shape({ | ||
viewport: PropTypes.array, | ||
slot: PropTypes.array | ||
})), | ||
PropTypes.instanceOf(Immutable.List) | ||
]), | ||
/** | ||
* An optional flag to indicate whether an ad slot should be out-of-page(interstitial) slot. | ||
* | ||
* @property interstitial | ||
*/ | ||
interstitial: PropTypes.bool, | ||
/** | ||
* An optional flag to indicate whether companion ad service should be enabled for the ad. | ||
* If an object is passed, it takes as a configuration expecting `enableSyncLoading` or `refreshUnfilledSlots`. | ||
* | ||
* @property companionAdService | ||
*/ | ||
companionAdService: PropTypes.oneOfType([ | ||
PropTypes.bool, | ||
PropTypes.oneOfType([ | ||
PropTypes.object, | ||
PropTypes.instanceOf(Immutable.Map) | ||
]) | ||
]), | ||
/** | ||
* An optional HTML content for the slot. If specified, the ad will render with the HTML content using content service. | ||
* | ||
* @property content | ||
*/ | ||
content: PropTypes.string, | ||
/** | ||
* An optional click through URL. If specified, any landing page URL associated with the creative that is served is overridden. | ||
* | ||
* @property clickUrl | ||
*/ | ||
clickUrl: PropTypes.string, | ||
/** | ||
* An optional string or an array of string which specifies a page-level ad category exclusion for the given label name. | ||
* | ||
* @property categoryExclusion | ||
*/ | ||
categoryExclusion: PropTypes.oneOfType([ | ||
PropTypes.string, | ||
PropTypes.oneOfType([ | ||
PropTypes.array, | ||
PropTypes.instanceOf(Immutable.List) | ||
]) | ||
]), | ||
/** | ||
* An optional map of key-value pairs for an AdSense attribute on a particular ad slot. | ||
* see the list of supported key value: https://developers.google.com/doubleclick-gpt/adsense_attributes#adsense_parameters.googletag.Slot | ||
* | ||
* @property attributes | ||
*/ | ||
attributes: PropTypes.oneOfType([ | ||
PropTypes.object, | ||
PropTypes.instanceOf(Immutable.Map) | ||
]), | ||
/** | ||
* An optional flag to indicate whether an empty ad should be collapsed or not. | ||
* | ||
* @property collapseEmptyDiv | ||
*/ | ||
collapseEmptyDiv: PropTypes.oneOfType([ | ||
PropTypes.bool, | ||
PropTypes.arrayOf(PropTypes.bool) | ||
]), | ||
/** | ||
* An optional flag to indicate whether ads in this slot should be forced to be rendered using a SafeFrame container. | ||
* | ||
* @property forceSafeFrame | ||
*/ | ||
forceSafeFrame: PropTypes.bool, | ||
/** | ||
* An optional object to set the slot-level preferences for SafeFrame configuration. | ||
* | ||
* @property safeFrameConfig | ||
*/ | ||
safeFrameConfig: PropTypes.oneOfType([ | ||
PropTypes.object, | ||
PropTypes.instanceOf(Immutable.Map) | ||
]), | ||
/** | ||
* An optional event handler function for `googletag.events.SlotRenderEndedEvent`. | ||
* | ||
* @property onSlotRenderEnded | ||
*/ | ||
onSlotRenderEnded: PropTypes.func, | ||
/** | ||
* An optional event handler function for `googletag.events.ImpressionViewableEvent`. | ||
* | ||
* @property onImpressionViewable | ||
*/ | ||
onImpressionViewable: PropTypes.func, | ||
/** | ||
* An optional event handler function for `googletag.events.slotVisibilityChangedEvent`. | ||
* | ||
* @property onSlotVisibilityChanged | ||
*/ | ||
onSlotVisibilityChanged: PropTypes.func, | ||
/** | ||
* An optional flag to indicate whether an ad should only render when it's fully in the viewport area. Default is `true`. | ||
* | ||
* @property renderWhenViewable | ||
*/ | ||
renderWhenViewable: PropTypes.bool, | ||
/** | ||
* An optional call back function to notify when the script is loaded. | ||
* | ||
* @property onScriptLoaded | ||
*/ | ||
onScriptLoaded: PropTypes.func | ||
} | ||
@@ -35,87 +193,200 @@ | ||
seedFileUrl: "//www.googletagservices.com/tag/js/gpt.js", | ||
companionAd: false, | ||
collapseEmptyDiv: true, | ||
invalidated: false | ||
renderWhenViewable: true | ||
} | ||
/** | ||
* An array of prop names which can reflect to the ad by calling `refresh`. | ||
* | ||
* @property refreshableProps | ||
* @static | ||
*/ | ||
static refreshableProps = [ | ||
"targeting", | ||
"sizeMapping", | ||
"clickUrl", | ||
"categoryExclusion", | ||
"attributes", | ||
"collapseEmptyDiv", | ||
"companionAdService", | ||
"forceSafeFrame", | ||
"safeFrameConfig" | ||
] | ||
/** | ||
* An array of prop names which requires to create a new ad slot and render as a new ad. | ||
* | ||
* @property reRenderProps | ||
* @static | ||
*/ | ||
static reRenderProps = [ | ||
"adUnitPath", | ||
"slotSize", | ||
"interstitial", | ||
"content" | ||
] | ||
/** | ||
* An instance of ad manager. | ||
* | ||
* @property _adManager | ||
* @private | ||
* @static | ||
*/ | ||
static _adManager = createManager() | ||
static clearMountedInstances() { | ||
Bling.mountedInstances = []; | ||
static on(eventType, cb) { | ||
Bling._on("on", eventType, cb); | ||
} | ||
static getMountedInstances() { | ||
if (!Bling.mountedInstances) { | ||
Bling.mountedInstances = []; | ||
} | ||
return Bling.mountedInstances; | ||
static once(eventType, cb) { | ||
Bling._on("once", eventType, cb); | ||
} | ||
static listen(eventName, pubService) { | ||
if (!Bling._listening && pubService) { | ||
pubService.addEventListener(eventName, Bling._onAdRendered.bind(Bling)); | ||
Bling._listening = true; | ||
} | ||
static removeListener(...args) { | ||
Bling._adManager.removeListener(...args); | ||
} | ||
static _onAdRendered(event) { | ||
const instances = Bling.getMountedInstances(); | ||
const slot = event.slot; | ||
const instance = instances.filter(inst => { | ||
return slot === inst._adSlot; | ||
}); | ||
if (instance && instance[0] && instance[0].props.onRendered) { | ||
instance[0].props.onRendered(event); | ||
static removeAllListeners(...args) { | ||
Bling._adManager.removeAllListeners(...args); | ||
} | ||
static _on(fn, eventType, cb) { | ||
if (typeof cb !== "function") { | ||
return; | ||
} | ||
if (eventType === Events.READY && Bling._adManager.isReady) { | ||
cb.call(Bling._adManager, Bling._adManager.googletag); | ||
} else { | ||
Bling._adManager[fn](eventType, cb); | ||
} | ||
} | ||
/** | ||
* Returns the GPT version. | ||
* | ||
* @method getGPTVersion | ||
* @returns {Number|boolean} a version or false if GPT is not yet ready. | ||
* @static | ||
*/ | ||
static getGPTVersion() { | ||
return Bling._adManager.getGPTVersion(); | ||
} | ||
/** | ||
* Returns the Pubads Service version. | ||
* | ||
* @method getPubadsVersion | ||
* @returns {Number|boolean} a version or false if Pubads Service is not yet ready. | ||
* @static | ||
*/ | ||
static getPubadsVersion() { | ||
return Bling._adManager.getPubadsVersion(); | ||
} | ||
/** | ||
* Sets a flag to indicate whether the correlator value should always be same across the ads in the page or not. | ||
* | ||
* @method syncCorrelator | ||
* @param {boolean} value | ||
* @static | ||
*/ | ||
static syncCorrelator(value) { | ||
Bling._adManager.syncCorrelator(value); | ||
} | ||
/** | ||
* Trigger re-rendering of all the ads. | ||
* | ||
* @method render | ||
* @static | ||
*/ | ||
static render() { | ||
Bling._adManager.renderAll(); | ||
} | ||
/** | ||
* Refreshes all the ads in the page with a new correlator value. | ||
* | ||
* @param {Array} slots An array of ad slots. | ||
* @param {Object} options You can pass `changeCorrelator` flag. | ||
* @static | ||
*/ | ||
static refresh(slots, options) { | ||
Bling._adManager.refresh(slots, options); | ||
} | ||
/** | ||
* Clears the ads for the specified ad slots, if no slots are provided, all the ads will be cleared. | ||
* | ||
* @method clear | ||
* @param {Array} slots An optional array of slots to clear. | ||
* @static | ||
*/ | ||
static clear(slots) { | ||
Bling._adManager.clear(slots); | ||
} | ||
/** | ||
* Updates the correlator value for the next ad request. | ||
* | ||
* @method updateCorrelator | ||
* @static | ||
*/ | ||
static updateCorrelator() { | ||
Bling._adManager.updateCorrelator(); | ||
} | ||
state = { | ||
scriptLoaded: false, | ||
rendered: false, | ||
invalidated: false | ||
inViewport: false | ||
} | ||
componentDidMount() { | ||
// add itself to static list | ||
const mountedInstances = this.constructor.getMountedInstances(); | ||
mountedInstances.push(this); | ||
// listen for media query change | ||
const {sizeMapping} = this.props; | ||
if (sizeMapping && Array.isArray(sizeMapping)) { | ||
sizeMapping.forEach(size => { | ||
const viewportWidth = size.viewport && size.viewport[0]; | ||
if (viewportWidth) { | ||
if (!this._mqls) { | ||
this._mqls = []; | ||
} | ||
const mql = window.matchMedia(`(min-width: ${viewportWidth}px)`); | ||
mql.addListener(this._handleMediaQueryChange); | ||
this._mqls.push(mql); | ||
} | ||
}); | ||
} | ||
// load seed file | ||
this._load().then(this._onScriptLoaded.bind(this)).catch(this._onScriptError.bind(this)); | ||
Bling._adManager.addInstance(this); | ||
Bling._adManager.load(this.props.seedFileUrl).then(this.onScriptLoaded.bind(this)).catch(this.onScriptError.bind(this)); | ||
} | ||
shouldComponentUpdate(nextProps, nextState) { | ||
const shouldRender = this.props.invalidated !== nextProps.invalidated; // external state change (route change, etc) | ||
if (this.state.rendered && nextState.rendered && nextState.invalidated) { // internal state change (media query change) | ||
this._googletag.cmd.push(this._refresh.bind(this)); | ||
// if adUnitPath changes, need to create a new slot, re-render | ||
// otherwise, just refresh | ||
const {scriptLoaded, inViewport} = nextState; | ||
const notInViewport = this.notInViewport(nextProps, nextState); | ||
const inViewportChanged = (this.state.inViewport !== inViewport); | ||
const isScriptLoaded = (this.state.scriptLoaded !== scriptLoaded); | ||
// Exit early for visibility change, before executing deep equality check. | ||
if (notInViewport) { | ||
return false; | ||
} else if (inViewportChanged) { | ||
return true; | ||
} | ||
return !nextState.rendered || shouldRender; | ||
const refreshableProps = this.filterProps(Bling.refreshableProps, this.props, nextProps); | ||
const reRenderProps = this.filterProps(Bling.reRenderProps, this.props, nextProps); | ||
const shouldRender = !deepEqual(reRenderProps.next, reRenderProps.current); | ||
const shouldRefresh = !shouldRender && !deepEqual(refreshableProps.next, refreshableProps.current); | ||
//console.log(`shouldRefresh: ${shouldRefresh}, shouldRender: ${shouldRender}, isScriptLoaded: ${isScriptLoaded}, syncCorrelator: ${Bling._adManager.syncCorrelator}`); | ||
if (shouldRefresh) { | ||
this.configureSlot(this._adSlot, nextProps); | ||
} | ||
if (Bling._adManager._syncCorrelator) { | ||
if (shouldRefresh) { | ||
Bling._adManager.refresh(); | ||
} else if (shouldRender || isScriptLoaded) { | ||
Bling._adManager.renderAll(); | ||
} | ||
} else { | ||
if (shouldRefresh) { | ||
this.refresh(); | ||
return false; | ||
} | ||
if (shouldRender || isScriptLoaded) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
componentDidUpdate() { | ||
if (this.state.scriptLoaded) { | ||
// now render ad within the rendered div. | ||
if (!this.props.invalidated) { | ||
const mountedInstances = this.constructor.getMountedInstances(); | ||
const index = mountedInstances.indexOf(this); | ||
// the first registered(executing) component is responsible for updating correlator value for the page. | ||
this._googletag.cmd.push(() => { | ||
if (index === 0) { | ||
// only update correlator when considered to be a new page. | ||
this._googletag.pubads().updateCorrelator(); | ||
} | ||
this._render(); | ||
}); | ||
if (this.notInViewport(this.props, this.state)) { | ||
return; | ||
} | ||
if (this._divId) { | ||
if (Bling._adManager._initialRender) { | ||
Bling._adManager.render(); | ||
} else { | ||
this.renderAd(); | ||
} | ||
@@ -126,130 +397,306 @@ } | ||
componentWillUnmount() { | ||
// remove itself from static list | ||
const mountedInstances = this.constructor.getMountedInstances(), | ||
index = mountedInstances.indexOf(this); | ||
mountedInstances.splice(index, 1); | ||
// remove media query listener | ||
if (this._mqls) { | ||
this._mqls.forEach((mql) => { | ||
mql.removeListener(this._handleMediaQueryChange); | ||
}); | ||
this._mqls = null; | ||
} | ||
Bling._adManager.removeInstance(this); | ||
this._adSlot = null; | ||
} | ||
_handleMediaQueryChange = () => { | ||
this.setState({invalidated: true}); | ||
onScriptLoaded() { | ||
const {renderWhenViewable, onScriptLoaded} = this.props; | ||
if (renderWhenViewable) { | ||
this.foldCheck(); | ||
} | ||
this.setState({scriptLoaded: true}, onScriptLoaded); // eslint-disable-line react/no-did-mount-set-state | ||
} | ||
_load() { | ||
return promise || (promise = new Promise((resolve, reject) => { | ||
if (window.googletag) { | ||
resolve(window.googletag); | ||
} else { | ||
const script = document.createElement("script"); | ||
script.onload = () => { | ||
resolve(window.googletag); | ||
}; | ||
script.onerror = reject; | ||
script.src = this.props.seedFileUrl; | ||
document.head.appendChild(script); | ||
} | ||
})); | ||
onScriptError() { | ||
console.warn(`Ad: Failed to load gpt for ${this.props.seedFileUrl}`); | ||
} | ||
_onScriptLoaded(googletag) { | ||
this._googletag = this._googletag || googletag; | ||
this._googletag.cmd.push(() => { | ||
this._pubService = this._googletag.pubads(); | ||
Bling.listen("slotRenderEnded", this._pubService); | ||
this.setState({scriptLoaded: true}); | ||
}); | ||
foldCheck() { | ||
if (this.state.inViewport) { | ||
return; | ||
} | ||
let slotSize = this.getSlotSize(); | ||
if (Array.isArray(slotSize) && Array.isArray(slotSize[0])) { | ||
slotSize = slotSize[0]; | ||
} | ||
if (slotSize === "fluid") { | ||
slotSize = [0, 0]; | ||
} | ||
const inViewport = Bling._adManager.isInViewport(ReactDOM.findDOMNode(this), slotSize); | ||
if (inViewport) { | ||
this.setState({inViewport: true}); | ||
} | ||
} | ||
_onScriptError(error) { | ||
console.warn("Ad: Failed to load gpt", error); | ||
get adSlot() { | ||
return this._adSlot; | ||
} | ||
_refresh() { | ||
this._googletag.pubads().refresh([this._adSlot]); | ||
// mark the refresh is done. | ||
if (!this.state.invalidated) { | ||
this.setState({invalidated: false}); | ||
} | ||
filterProps(propList, props, nextProps) { | ||
return propList.reduce((filtered, key) => { | ||
let nonEqual = false; | ||
if (isImmutableListOrMap(nextProps[key]) && | ||
isImmutableListOrMap(props[key])) { | ||
nonEqual = !Immutable.is(nextProps[key], this.props[key]); | ||
if (!nonEqual) { | ||
// makes deep equality check cheap | ||
filtered.next[key] = filtered.current[key] = 0; | ||
} | ||
} else if (isImmutableListOrMap(nextProps[key]) || | ||
isImmutableListOrMap(props[key])) { | ||
nonEqual = true; | ||
} else { | ||
filtered.next[key] = nextProps[key]; | ||
filtered.current[key] = props[key]; | ||
} | ||
if (nonEqual) { | ||
// makes deep equality check cheap | ||
filtered.next[key] = 0; | ||
filtered.current[key] = 1; | ||
} | ||
return filtered; | ||
}, { | ||
next: {}, | ||
current: {} | ||
}); | ||
} | ||
_defineSizeMapping(adSlot, sizeMapping) { | ||
defineSizeMapping(adSlot, sizeMapping) { | ||
if (sizeMapping) { | ||
adSlot.defineSizeMapping(sizeMapping.reduce((mapping, size) => { | ||
const sizeMappingArray = toJS(sizeMapping).reduce((mapping, size) => { | ||
return mapping.addSize(size.viewport, size.slot); | ||
}, this._googletag.sizeMapping()).build()); | ||
}, Bling._adManager.googletag.sizeMapping()).build(); | ||
adSlot.defineSizeMapping(sizeMappingArray); | ||
} | ||
} | ||
_setTargeting(adSlot, targeting) { | ||
setTargeting(adSlot, targeting) { | ||
adSlot.clearTargeting(); | ||
if (targeting) { | ||
for (const key in targeting) { | ||
if (targeting.hasOwnProperty(key)) { | ||
adSlot.setTargeting(key, targeting[key]); | ||
} | ||
} | ||
targeting = toJS(targeting); | ||
Object.keys(targeting).forEach(key => { | ||
adSlot.setTargeting(key, targeting[key]); | ||
}); | ||
} | ||
} | ||
_addCompanionAdService(adSlot) { | ||
const companionAdsService = this._googletag.companionAds(); | ||
addCompanionAdService(serviceConfig, adSlot) { | ||
const companionAdsService = Bling._adManager.googletag.companionAds(); | ||
adSlot.addService(companionAdsService); | ||
companionAdsService.setRefreshUnfilledSlots(true); | ||
this._googletag.enableServices(); | ||
if (typeof serviceConfig === "object") { | ||
if (serviceConfig.hasOwnProperty("enableSyncLoading")) { | ||
companionAdsService.enableSyncLoading(); | ||
} | ||
if (serviceConfig.hasOwnProperty("refreshUnfilledSlots")) { | ||
companionAdsService.setRefreshUnfilledSlots(serviceConfig.refreshUnfilledSlots); | ||
} | ||
} | ||
} | ||
_render() { | ||
const {adUnitPath, slotSize, sizeMapping, collapseEmptyDiv, targeting, companionAd} = this.props; | ||
const pubService = this._googletag.pubads(); | ||
const divId = this._divId; | ||
const adSlot = this._googletag.defineSlot(adUnitPath, slotSize || [], divId); | ||
getSlotSize() { | ||
const { | ||
slotSize: origSlotSize, | ||
sizeMapping: origSizeMapping | ||
} = this.props; | ||
let slotSize; | ||
if (origSlotSize) { | ||
slotSize = toJS(origSlotSize); | ||
} else if (origSizeMapping) { | ||
const sizeMapping = toJS(origSizeMapping); | ||
slotSize = sizeMapping[0] && sizeMapping[0].slot; | ||
} | ||
this._defineSizeMapping(adSlot, sizeMapping); | ||
return slotSize; | ||
} | ||
adSlot.addService(pubService); | ||
renderAd() { | ||
this.defineSlot(); | ||
this.display(); | ||
} | ||
adSlot.setCollapseEmptyDiv(collapseEmptyDiv); | ||
notInViewport(props = this.props, state = this.state) { | ||
const {renderWhenViewable} = props; | ||
const {inViewport} = state; | ||
return renderWhenViewable && !inViewport; | ||
} | ||
this._setTargeting(adSlot, targeting); | ||
defineSlot() { | ||
const { | ||
adUnitPath, | ||
interstitial | ||
} = this.props; | ||
const divId = this._divId; | ||
const slotSize = this.getSlotSize(); | ||
if (!this._adSlot) { | ||
pubService.enableAsyncRendering(); | ||
if (interstitial) { | ||
this._adSlot = Bling._adManager.googletag.defineOutOfPageSlot(adUnitPath, divId); | ||
} else { | ||
this._adSlot = Bling._adManager.googletag.defineSlot(adUnitPath, slotSize || [], divId); | ||
} | ||
} | ||
// Enables all Google Publisher Tag services that have been defined for ad slots on the page. | ||
// This is only needed once per page but including it multiple times will not cause any harm. | ||
this._googletag.enableServices(); | ||
this._googletag.display(divId); | ||
this.configureSlot(this._adSlot); | ||
} | ||
if (companionAd) { | ||
this._addCompanionAdService(adSlot); | ||
configureSlot(adSlot, props = this.props) { | ||
const { | ||
sizeMapping, | ||
targeting, | ||
companionAdService, | ||
categoryExclusion, | ||
content, | ||
clickUrl, | ||
forceSafeFrame | ||
} = props; | ||
let { | ||
collapseEmptyDiv, | ||
attributes, | ||
safeFrameConfig | ||
} = props; | ||
this.defineSizeMapping(adSlot, sizeMapping); | ||
if (collapseEmptyDiv !== undefined) { | ||
collapseEmptyDiv = toJS(collapseEmptyDiv); | ||
if (Array.isArray(collapseEmptyDiv)) { | ||
adSlot.setCollapseEmptyDiv.call(adSlot, ...collapseEmptyDiv); | ||
} else { | ||
adSlot.setCollapseEmptyDiv(collapseEmptyDiv); | ||
} | ||
} | ||
this._adSlot = adSlot; | ||
// Overrides click url | ||
if (clickUrl) { | ||
adSlot.setClickUrl(clickUrl); | ||
} | ||
// When the size mapping is configured not to render ad with the viewport in initial render, | ||
// GPT won't render ad and 'slotRenderEnded' is not triggered, so set the 'rendered' state here. | ||
// Not supposed to set state during component rendering life cycle, but ad needs to maintain the states and rendering logic on its own. | ||
if (!this.state.rendered) { | ||
this.setState({rendered: true}); | ||
// Sets category exclusion | ||
if (categoryExclusion) { | ||
let exclusion = toJS(categoryExclusion); | ||
if (typeof exclusion === "string") { | ||
exclusion = [exclusion]; | ||
} | ||
adSlot.clearCategoryExclusions(); | ||
exclusion.forEach(item => { | ||
adSlot.setCategoryExclusion(item); | ||
}); | ||
} | ||
// Sets AdSense attributes | ||
if (attributes) { | ||
attributes = toJS(attributes); | ||
Object.keys(attributes).forEach(key => { | ||
adSlot.set(key, attributes[key]); | ||
}); | ||
} | ||
if (safeFrameConfig) { | ||
safeFrameConfig = toJS(safeFrameConfig); | ||
adSlot.setSafeFrameConfig(safeFrameConfig); | ||
} | ||
if (forceSafeFrame) { | ||
adSlot.setForceSafeFrame(forceSafeFrame); | ||
} | ||
// Sets custom targeting parameters | ||
this.setTargeting(adSlot, targeting); | ||
// Enables companion ad service | ||
if (companionAdService) { | ||
this.addCompanionAdService(companionAdService, adSlot); | ||
} | ||
// GPT checks if the same service is already added. | ||
if (content) { | ||
adSlot.addService(Bling._adManager.googletag.content()); | ||
} else { | ||
adSlot.addService(Bling._adManager.googletag.pubads()); | ||
} | ||
} | ||
display() { | ||
const {content} = this.props; | ||
const divId = this._divId; | ||
const adSlot = this._adSlot; | ||
if (content) { | ||
Bling._adManager.googletag.content().setContent(adSlot, content); | ||
} else { | ||
if (!Bling._adManager._disableInitialLoad && !Bling._adManager._syncCorrelator) { | ||
Bling._adManager.updateCorrelator(); | ||
} | ||
Bling._adManager.googletag.display(divId); | ||
if (Bling._adManager._disableInitialLoad && !Bling._adManager._initialRender) { | ||
this.refresh(); | ||
} | ||
} | ||
} | ||
clear() { | ||
const adSlot = this._adSlot; | ||
if (adSlot) { | ||
// googletag.ContentService doesn't clear content | ||
const services = adSlot.getServices(); | ||
if (this._divId && services.some(s => !!s.setContent)) { | ||
document.getElementById(this._divId).innerHTML = ""; | ||
return; | ||
} | ||
Bling._adManager.clear([adSlot]); | ||
} | ||
} | ||
refresh(options) { | ||
const adSlot = this._adSlot; | ||
if (adSlot) { | ||
Bling._adManager.refresh([adSlot], options); | ||
} | ||
} | ||
render() { | ||
if (!this.props.invalidated) { | ||
this._divId = generateDivId(); | ||
const {scriptLoaded} = this.state; | ||
const {interstitial} = this.props; | ||
const shouldNotRender = this.notInViewport(this.props, this.state); | ||
if (!scriptLoaded || shouldNotRender) { | ||
let slotSize = this.getSlotSize(); | ||
if (!interstitial) { | ||
invariant( | ||
slotSize, | ||
"Either 'slotSize' or 'sizeMapping' prop needs to be set." | ||
); | ||
} | ||
if (Array.isArray(slotSize) && Array.isArray(slotSize[0])) { | ||
slotSize = slotSize[0]; | ||
} | ||
// https://developers.google.com/doubleclick-gpt/reference?hl=en#googletag.NamedSize | ||
if (slotSize === "fluid") { | ||
slotSize = ["auto", "auto"]; | ||
} | ||
const style = slotSize && {width: slotSize[0], height: slotSize[1]}; | ||
// render node element instead of script element so that `inViewport` check works. | ||
return <div style={style}/>; | ||
} | ||
// when 'invalidated' prop is true, remove the container to clear out an old ad. | ||
// it's followed by 'invalidated' prop set to false, this time renders a new ad. | ||
return this.props.invalidated ? null : <div id={this._divId}></div>; | ||
// clear the current ad if exists | ||
this.clear(); | ||
if (this._adSlot) { | ||
Bling._adManager.googletag.destroySlots([this._adSlot]); | ||
this._adSlot = null; | ||
} | ||
this._divId = this._adSlot ? this._adSlot.getSlotElementId() : Bling._adManager.generateDivId(); | ||
return <div id={this._divId}></div>; | ||
} | ||
} | ||
export default Bling; | ||
// proxy pubads API through Bling | ||
export default hoistStatics(Bling, pubadsAPI.reduce((api, method) => { | ||
api[method] = (...args) => Bling._adManager.pubadsProxy({method, args}); | ||
return api; | ||
}, {})); |
import "./polyfill"; | ||
import NFLBling from "./NFLBling"; | ||
import Bling from "./Bling"; | ||
export default { | ||
NFLBling, | ||
Bling | ||
}; | ||
export {default as Bling} from "./Bling"; | ||
export {default as Events} from "./Events"; |
@@ -0,2 +1,4 @@ | ||
import "core-js/fn/array/from"; | ||
import "core-js/fn/object/assign"; | ||
import "core-js/fn/promise"; | ||
import "core-js/fn/set"; |
Sorry, the diff of this file is too big to display
Install scripts
Supply chain riskInstall scripts are run when the package is installed. The majority of malware in npm is hidden in install scripts.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
No tests
QualityPackage does not have any tests. This is a strong signal of a poorly maintained or low quality package.
Found 1 instance in 1 package
8278
2
65
0
0
399279
10
41
125
52
+ Addeddeep-equal@^1.0.1
+ Addedeventemitter3@^1.1.1
+ Addedimmutable@^3.7.5
+ Addedcall-bind@1.0.8(transitive)
+ Addedcall-bind-apply-helpers@1.0.1(transitive)
+ Addedcall-bound@1.0.3(transitive)
+ Addedcore-js@2.6.12(transitive)
+ Addeddeep-equal@1.1.2(transitive)
+ Addeddefine-data-property@1.1.4(transitive)
+ Addeddefine-properties@1.2.1(transitive)
+ Addeddunder-proto@1.0.1(transitive)
+ Addedencoding@0.1.13(transitive)
+ Addedes-define-property@1.0.1(transitive)
+ Addedes-errors@1.3.0(transitive)
+ Addedes-object-atoms@1.1.1(transitive)
+ Addedeventemitter3@1.2.0(transitive)
+ Addedfbjs@0.7.2(transitive)
+ Addedfunction-bind@1.1.2(transitive)
+ Addedfunctions-have-names@1.2.3(transitive)
+ Addedget-intrinsic@1.2.7(transitive)
+ Addedget-proto@1.0.1(transitive)
+ Addedgopd@1.2.0(transitive)
+ Addedhas-property-descriptors@1.0.2(transitive)
+ Addedhas-symbols@1.1.0(transitive)
+ Addedhas-tostringtag@1.0.2(transitive)
+ Addedhasown@2.0.2(transitive)
+ Addedhoist-non-react-statics@1.2.0(transitive)
+ Addediconv-lite@0.6.3(transitive)
+ Addedimmutable@3.8.2(transitive)
+ Addedis-arguments@1.2.0(transitive)
+ Addedis-date-object@1.1.0(transitive)
+ Addedis-regex@1.2.1(transitive)
+ Addedis-stream@1.1.0(transitive)
+ Addedisomorphic-fetch@2.2.1(transitive)
+ Addedmath-intrinsics@1.1.0(transitive)
+ Addednode-fetch@1.7.3(transitive)
+ Addedobject-is@1.1.6(transitive)
+ Addedobject-keys@1.1.1(transitive)
+ Addedregexp.prototype.flags@1.5.4(transitive)
+ Addedset-function-length@1.2.2(transitive)
+ Addedset-function-name@2.0.2(transitive)
+ Addedwhatwg-fetch@3.6.20(transitive)
- Removedquerystring@^0.2.0
- Removedfbjs@0.4.0(transitive)
- Removedquerystring@0.2.1(transitive)
Updatedcore-js@^2.1.1
Updatedfbjs@^0.7.2
Updatedreact@^0.14.6
Updatedreact-dom@^0.14.6