@constructor-io/constructorio-client-javascript 2.21.0 → 2.25.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -1
- package/lib/constructorio.js +38 -33
- package/lib/modules/autocomplete.js +5 -7
- package/lib/modules/browse.js +23 -17
- package/lib/modules/recommendations.js +5 -7
- package/lib/modules/search.js +6 -7
- package/lib/modules/tracker.js +154 -121
- package/lib/utils/event-dispatcher.js +5 -7
- package/lib/utils/helpers.js +21 -6
- package/lib/utils/humanity-check.js +16 -9
- package/lib/utils/request-queue.js +98 -92
- package/package.json +20 -15
package/README.md
CHANGED
|
@@ -3,14 +3,19 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/@constructor-io/constructorio-client-javascript)
|
|
4
4
|
[](https://github.com/Constructor-io/constructorio-client-javascript/blob/master/LICENSE)
|
|
5
5
|
[](https://bundlephobia.com/result?p=@constructor-io/constructorio-client-javascript)
|
|
6
|
-
[](https://david-dm.org/constructor-io/constructorio-client-javascript)
|
|
7
6
|
|
|
8
7
|
A JavaScript client for [Constructor.io](http://constructor.io/). [Constructor.io](http://constructor.io/) provides search as a service that optimizes results using artificial intelligence (including natural language processing, re-ranking to optimize for conversions, and user personalization).
|
|
9
8
|
|
|
9
|
+
> This client is intended for use in a browser environment but can also be used in React Native based mobile applications. Additional information about utilization in a React Native context can be found on the [Wiki](https://github.com/Constructor-io/constructorio-client-javascript/wiki/Utilization-in-a-DOM-less-environment). If you want a JavaScript client for server side integrations please use [@constructor-io/constructorio-node](https://github.com/Constructor-io/constructorio-node)
|
|
10
|
+
|
|
10
11
|
## 1. Install
|
|
11
12
|
|
|
12
13
|
This package can be installed via npm: `npm i @constructor-io/constructorio-client-javascript`. Once installed, simply import or require the package into your repository.
|
|
13
14
|
|
|
15
|
+
Alternatively, a bundled version consisting of a single JavaScript file is published within the `./dist` folder on Github. This can be utilized within a browser context if hosted locally - _please do not link directly to the Github hosted version_.
|
|
16
|
+
|
|
17
|
+
**Important**: this library should only be used in a client-side context where standard HTTP request headers are populated by the client (`User-Agent`, `Referer`, etc.).
|
|
18
|
+
|
|
14
19
|
## 2. Retrieve an API key
|
|
15
20
|
|
|
16
21
|
You can find this in your [Constructor.io dashboard](https://constructor.io/dashboard). Contact sales if you'd like to sign up, or support if you believe your company already has an account.
|
package/lib/constructorio.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
8
8
|
|
|
9
9
|
/* eslint-disable camelcase, no-unneeded-ternary, max-len */
|
|
10
10
|
var ConstructorioID = require('@constructor-io/constructorio-id'); // Modules
|
|
@@ -33,35 +33,34 @@ var _require = require('../package.json'),
|
|
|
33
33
|
|
|
34
34
|
var ConstructorIO = /*#__PURE__*/function () {
|
|
35
35
|
/**
|
|
36
|
-
* @param {
|
|
37
|
-
* @param {string}
|
|
38
|
-
* @param {
|
|
39
|
-
* @param {
|
|
40
|
-
* @param {
|
|
41
|
-
* @param {string} [
|
|
42
|
-
* @param {string} [
|
|
43
|
-
* @param {
|
|
44
|
-
* @param {
|
|
45
|
-
* @param {
|
|
46
|
-
* @param {boolean} [
|
|
47
|
-
* @param {
|
|
48
|
-
* @param {object} [
|
|
49
|
-
* @param {
|
|
50
|
-
* @param {boolean} [eventDispatcher.
|
|
51
|
-
* @param {
|
|
52
|
-
* @param {
|
|
53
|
-
* @
|
|
54
|
-
* @property {object}
|
|
55
|
-
* @property {object}
|
|
56
|
-
* @property {object}
|
|
57
|
-
* @property {object}
|
|
36
|
+
* @param {object} parameters - Parameters for client instantiation
|
|
37
|
+
* @param {string} parameters.apiKey - Constructor.io API key
|
|
38
|
+
* @param {string} [parameters.serviceUrl='https://ac.cnstrc.com'] - API URL endpoint
|
|
39
|
+
* @param {array} [parameters.segments] - User segments
|
|
40
|
+
* @param {object} [parameters.testCells] - User test cells
|
|
41
|
+
* @param {string} [parameters.clientId] - Client ID, defaults to value supplied by 'constructorio-id' module
|
|
42
|
+
* @param {string} [parameters.sessionId] - Session ID, defaults to value supplied by 'constructorio-id' module
|
|
43
|
+
* @param {string} [parameters.userId] - User ID
|
|
44
|
+
* @param {function} [parameters.fetch] - If supplied, will be utilized for requests rather than default Fetch API
|
|
45
|
+
* @param {number} [parameters.trackingSendDelay=250] - Amount of time to wait before sending tracking events (in ms)
|
|
46
|
+
* @param {boolean} [parameters.sendReferrerWithTrackingEvents=true] - Indicates if the referrer is sent with tracking events
|
|
47
|
+
* @param {boolean} [parameters.sendTrackingEvents=false] - Indicates if tracking events should be dispatched
|
|
48
|
+
* @param {object} [parameters.idOptions] - Options object to be supplied to 'constructorio-id' module
|
|
49
|
+
* @param {object} [parameters.eventDispatcher] - Options related to 'EventDispatcher' class
|
|
50
|
+
* @param {boolean} [parameters.eventDispatcher.enabled=true] - Determine if events should be dispatched
|
|
51
|
+
* @param {boolean} [parameters.eventDispatcher.waitForBeacon=true] - Wait for beacon before dispatching events
|
|
52
|
+
* @param {object} [parameters.networkParameters] - Parameters relevant to network requests
|
|
53
|
+
* @param {number} [parameters.networkParameters.timeout] - Request timeout (in milliseconds) - may be overridden within individual method calls
|
|
54
|
+
* @property {object} search - Interface to {@link module:search}
|
|
55
|
+
* @property {object} browse - Interface to {@link module:browse}
|
|
56
|
+
* @property {object} autocomplete - Interface to {@link module:autocomplete}
|
|
57
|
+
* @property {object} recommendations - Interface to {@link module:recommendations}
|
|
58
|
+
* @property {object} tracker - Interface to {@link module:tracker}
|
|
58
59
|
* @returns {class}
|
|
59
60
|
*/
|
|
60
61
|
function ConstructorIO() {
|
|
61
62
|
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
62
|
-
|
|
63
|
-
_classCallCheck(this, ConstructorIO);
|
|
64
|
-
|
|
63
|
+
(0, _classCallCheck2["default"])(this, ConstructorIO);
|
|
65
64
|
var canUseDOM = helpers.canUseDOM();
|
|
66
65
|
var apiKey = options.apiKey,
|
|
67
66
|
version = options.version,
|
|
@@ -106,8 +105,8 @@ var ConstructorIO = /*#__PURE__*/function () {
|
|
|
106
105
|
|
|
107
106
|
this.options = {
|
|
108
107
|
apiKey: apiKey,
|
|
109
|
-
version: version || global.CLIENT_VERSION || "ciojs-client-".concat(canUseDOM ? '' : 'domless-').concat(packageVersion),
|
|
110
|
-
serviceUrl: serviceUrl || 'https://ac.cnstrc.com',
|
|
108
|
+
version: version || typeof global !== 'undefined' && global.CLIENT_VERSION || "ciojs-client-".concat(canUseDOM ? '' : 'domless-').concat(process.env.BUNDLED ? 'bundled-' : '').concat(packageVersion),
|
|
109
|
+
serviceUrl: serviceUrl && serviceUrl.replace(/\/$/, '') || 'https://ac.cnstrc.com',
|
|
111
110
|
sessionId: sessionId || session_id,
|
|
112
111
|
clientId: clientId || client_id,
|
|
113
112
|
userId: userId,
|
|
@@ -141,7 +140,7 @@ var ConstructorIO = /*#__PURE__*/function () {
|
|
|
141
140
|
*/
|
|
142
141
|
|
|
143
142
|
|
|
144
|
-
|
|
143
|
+
(0, _createClass2["default"])(ConstructorIO, [{
|
|
145
144
|
key: "setClientOptions",
|
|
146
145
|
value: function setClientOptions(options) {
|
|
147
146
|
if (Object.keys(options).length) {
|
|
@@ -168,8 +167,14 @@ var ConstructorIO = /*#__PURE__*/function () {
|
|
|
168
167
|
}
|
|
169
168
|
}
|
|
170
169
|
}]);
|
|
171
|
-
|
|
172
170
|
return ConstructorIO;
|
|
173
|
-
}();
|
|
171
|
+
}(); // Exposed for testing
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
ConstructorIO.Tracker = Tracker; // Expose on window object if available
|
|
175
|
+
|
|
176
|
+
if (helpers.canUseDOM()) {
|
|
177
|
+
window.ConstructorioClient = ConstructorIO;
|
|
178
|
+
}
|
|
174
179
|
|
|
175
180
|
module.exports = ConstructorIO;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
8
8
|
|
|
9
9
|
/* eslint-disable object-curly-newline, no-underscore-dangle */
|
|
10
10
|
var qs = require('qs');
|
|
@@ -104,8 +104,7 @@ function createAutocompleteUrl(query, parameters, options) {
|
|
|
104
104
|
|
|
105
105
|
var Autocomplete = /*#__PURE__*/function () {
|
|
106
106
|
function Autocomplete(options) {
|
|
107
|
-
|
|
108
|
-
|
|
107
|
+
(0, _classCallCheck2["default"])(this, Autocomplete);
|
|
109
108
|
this.options = options || {};
|
|
110
109
|
this.eventDispatcher = new EventDispatcher(options.eventDispatcher);
|
|
111
110
|
}
|
|
@@ -137,7 +136,7 @@ var Autocomplete = /*#__PURE__*/function () {
|
|
|
137
136
|
*/
|
|
138
137
|
|
|
139
138
|
|
|
140
|
-
|
|
139
|
+
(0, _createClass2["default"])(Autocomplete, [{
|
|
141
140
|
key: "getAutocompleteResults",
|
|
142
141
|
value: function getAutocompleteResults(query, parameters) {
|
|
143
142
|
var _this = this;
|
|
@@ -192,7 +191,6 @@ var Autocomplete = /*#__PURE__*/function () {
|
|
|
192
191
|
});
|
|
193
192
|
}
|
|
194
193
|
}]);
|
|
195
|
-
|
|
196
194
|
return Autocomplete;
|
|
197
195
|
}();
|
|
198
196
|
|
package/lib/modules/browse.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
10
10
|
|
|
11
|
-
function
|
|
11
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
|
|
12
12
|
|
|
13
|
-
function
|
|
13
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|
14
14
|
|
|
15
15
|
/* eslint-disable object-curly-newline, no-underscore-dangle */
|
|
16
16
|
var qs = require('qs');
|
|
@@ -133,7 +133,7 @@ function createBrowseUrlFromFilter(filterName, filterValue, parameters, options)
|
|
|
133
133
|
function createBrowseUrlFromIDs(ids, parameters, options) {
|
|
134
134
|
var serviceUrl = options.serviceUrl; // Validate id's are provided
|
|
135
135
|
|
|
136
|
-
if (!ids || !(ids
|
|
136
|
+
if (!ids || !Array.isArray(ids) || !ids.length) {
|
|
137
137
|
throw new Error('ids is a required parameter of type array');
|
|
138
138
|
}
|
|
139
139
|
|
|
@@ -173,8 +173,7 @@ function createBrowseUrlForFacets(parameters, options) {
|
|
|
173
173
|
|
|
174
174
|
var Browse = /*#__PURE__*/function () {
|
|
175
175
|
function Browse(options) {
|
|
176
|
-
|
|
177
|
-
|
|
176
|
+
(0, _classCallCheck2["default"])(this, Browse);
|
|
178
177
|
this.options = options || {};
|
|
179
178
|
this.eventDispatcher = new EventDispatcher(options.eventDispatcher);
|
|
180
179
|
}
|
|
@@ -196,7 +195,7 @@ var Browse = /*#__PURE__*/function () {
|
|
|
196
195
|
* @param {object} [networkParameters] - Parameters relevant to the network request
|
|
197
196
|
* @param {number} [networkParameters.timeout] - Request timeout (in milliseconds)
|
|
198
197
|
* @returns {Promise}
|
|
199
|
-
* @see https://docs.constructor.io/rest_api/browse/
|
|
198
|
+
* @see https://docs.constructor.io/rest_api/browse/results
|
|
200
199
|
* @example
|
|
201
200
|
* constructorio.browse.getBrowseResults('group_id', 't-shirts', {
|
|
202
201
|
* resultsPerPage: 40,
|
|
@@ -207,7 +206,7 @@ var Browse = /*#__PURE__*/function () {
|
|
|
207
206
|
*/
|
|
208
207
|
|
|
209
208
|
|
|
210
|
-
|
|
209
|
+
(0, _createClass2["default"])(Browse, [{
|
|
211
210
|
key: "getBrowseResults",
|
|
212
211
|
value: function getBrowseResults(filterName, filterValue, parameters) {
|
|
213
212
|
var _this = this;
|
|
@@ -334,13 +333,13 @@ var Browse = /*#__PURE__*/function () {
|
|
|
334
333
|
* @param {object} [networkParameters] - Parameters relevant to the network request
|
|
335
334
|
* @param {number} [networkParameters.timeout] - Request timeout (in milliseconds)
|
|
336
335
|
* @returns {Promise}
|
|
337
|
-
* @see https://docs.constructor.io/
|
|
336
|
+
* @see https://docs.constructor.io/rest_api/browse/groups
|
|
338
337
|
* @example
|
|
339
338
|
* constructorio.browse.getBrowseGroups({
|
|
340
339
|
* filters: {
|
|
341
340
|
* group_id: 'drill_collection'
|
|
342
341
|
* },
|
|
343
|
-
*
|
|
342
|
+
* fmtOptions: {
|
|
344
343
|
* groups_max_depth: 2
|
|
345
344
|
* }
|
|
346
345
|
* });
|
|
@@ -391,6 +390,8 @@ var Browse = /*#__PURE__*/function () {
|
|
|
391
390
|
* @param {object} [parameters] - Additional parameters to refine result set
|
|
392
391
|
* @param {number} [parameters.page] - The page number of the results
|
|
393
392
|
* @param {number} [parameters.resultsPerPage] - The number of results per page to return
|
|
393
|
+
* @param {object} [networkParameters] - Parameters relevant to the network request
|
|
394
|
+
* @param {number} [networkParameters.timeout] - Request timeout (in milliseconds)
|
|
394
395
|
* @returns {Promise}
|
|
395
396
|
* @see https://docs.constructor.io/rest_api/browse/facets
|
|
396
397
|
* @example
|
|
@@ -402,21 +403,27 @@ var Browse = /*#__PURE__*/function () {
|
|
|
402
403
|
|
|
403
404
|
}, {
|
|
404
405
|
key: "getBrowseFacets",
|
|
405
|
-
value: function getBrowseFacets(parameters) {
|
|
406
|
+
value: function getBrowseFacets(parameters, networkParameters) {
|
|
406
407
|
var _this4 = this;
|
|
407
408
|
|
|
408
409
|
var requestUrl;
|
|
409
410
|
var fetch = this.options && this.options.fetch || fetchPonyfill({
|
|
410
411
|
Promise: Promise
|
|
411
412
|
}).fetch;
|
|
413
|
+
var controller = new AbortController();
|
|
414
|
+
var signal = controller.signal;
|
|
412
415
|
|
|
413
416
|
try {
|
|
414
417
|
requestUrl = createBrowseUrlForFacets(parameters, this.options);
|
|
415
418
|
} catch (e) {
|
|
416
419
|
return Promise.reject(e);
|
|
417
|
-
}
|
|
420
|
+
} // Handle network timeout if specified
|
|
421
|
+
|
|
418
422
|
|
|
419
|
-
|
|
423
|
+
helpers.applyNetworkTimeout(this.options, networkParameters, controller);
|
|
424
|
+
return fetch(requestUrl, {
|
|
425
|
+
signal: signal
|
|
426
|
+
}).then(function (response) {
|
|
420
427
|
if (response.ok) {
|
|
421
428
|
return response.json();
|
|
422
429
|
}
|
|
@@ -433,7 +440,6 @@ var Browse = /*#__PURE__*/function () {
|
|
|
433
440
|
});
|
|
434
441
|
}
|
|
435
442
|
}]);
|
|
436
|
-
|
|
437
443
|
return Browse;
|
|
438
444
|
}();
|
|
439
445
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
8
8
|
|
|
9
9
|
/* eslint-disable object-curly-newline, no-param-reassign */
|
|
10
10
|
var qs = require('qs');
|
|
@@ -96,8 +96,7 @@ function createRecommendationsUrl(podId, parameters, options) {
|
|
|
96
96
|
|
|
97
97
|
var Recommendations = /*#__PURE__*/function () {
|
|
98
98
|
function Recommendations(options) {
|
|
99
|
-
|
|
100
|
-
|
|
99
|
+
(0, _classCallCheck2["default"])(this, Recommendations);
|
|
101
100
|
this.options = options || {};
|
|
102
101
|
this.eventDispatcher = new EventDispatcher(options.eventDispatcher);
|
|
103
102
|
}
|
|
@@ -127,7 +126,7 @@ var Recommendations = /*#__PURE__*/function () {
|
|
|
127
126
|
*/
|
|
128
127
|
|
|
129
128
|
|
|
130
|
-
|
|
129
|
+
(0, _createClass2["default"])(Recommendations, [{
|
|
131
130
|
key: "getRecommendations",
|
|
132
131
|
value: function getRecommendations(podId, parameters) {
|
|
133
132
|
var _this = this;
|
|
@@ -175,7 +174,6 @@ var Recommendations = /*#__PURE__*/function () {
|
|
|
175
174
|
});
|
|
176
175
|
}
|
|
177
176
|
}]);
|
|
178
|
-
|
|
179
177
|
return Recommendations;
|
|
180
178
|
}();
|
|
181
179
|
|
package/lib/modules/search.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
8
8
|
|
|
9
9
|
/* eslint-disable object-curly-newline, no-underscore-dangle */
|
|
10
10
|
var qs = require('qs');
|
|
@@ -123,8 +123,7 @@ function createSearchUrl(query, parameters, options) {
|
|
|
123
123
|
|
|
124
124
|
var Search = /*#__PURE__*/function () {
|
|
125
125
|
function Search(options) {
|
|
126
|
-
|
|
127
|
-
|
|
126
|
+
(0, _classCallCheck2["default"])(this, Search);
|
|
128
127
|
this.options = options || {};
|
|
129
128
|
this.eventDispatcher = new EventDispatcher(options.eventDispatcher);
|
|
130
129
|
}
|
|
@@ -140,6 +139,7 @@ var Search = /*#__PURE__*/function () {
|
|
|
140
139
|
* @param {object} [parameters.filters] - Key / value mapping (dictionary) of filters used to refine results
|
|
141
140
|
* @param {string} [parameters.sortBy='relevance'] - The sort method for results
|
|
142
141
|
* @param {string} [parameters.sortOrder='descending'] - The sort order for results
|
|
142
|
+
* @param {string} [parameters.section='Products'] - The section name for results
|
|
143
143
|
* @param {object} [parameters.fmtOptions] - The format options used to refine result groups
|
|
144
144
|
* @param {string[]} [parameters.hiddenFields] - Hidden metadata fields to return
|
|
145
145
|
* @param {object} [networkParameters] - Parameters relevant to the network request
|
|
@@ -156,7 +156,7 @@ var Search = /*#__PURE__*/function () {
|
|
|
156
156
|
*/
|
|
157
157
|
|
|
158
158
|
|
|
159
|
-
|
|
159
|
+
(0, _createClass2["default"])(Search, [{
|
|
160
160
|
key: "getSearchResults",
|
|
161
161
|
value: function getSearchResults(query, parameters) {
|
|
162
162
|
var _this = this;
|
|
@@ -211,7 +211,6 @@ var Search = /*#__PURE__*/function () {
|
|
|
211
211
|
});
|
|
212
212
|
}
|
|
213
213
|
}]);
|
|
214
|
-
|
|
215
214
|
return Search;
|
|
216
215
|
}();
|
|
217
216
|
|