{"version":3,"sources":["FoldingForThread.min__00ecf0bd3e47c7b52b32.js","./src/ui/Folding/Folding.ts","./src/ui/FoldingForThread/FoldingForThread.ts","./src/ui/Sort/SortCriteria.ts"],"names":["webpackJsonpCoveo__temporary","187","module","exports","__webpack_require__","__extends","this","extendStatics","Object","setPrototypeOf","__proto__","Array","d","b","p","hasOwnProperty","__","constructor","prototype","create","defineProperty","value","element","options","bindings","Folding","ID","ComponentOptions","initComponentOptions","Assert","check","Utils","isCoveoField","field","exists","maximumExpandedResults","swapParentChildFoldingFields","bind","onRootElement","QueryEvents","buildingQuery","handleBuildingQuery","preprocessResults","handlepreprocessResults","_this","foldWithParent","queryResults","rootNode","score","Number","NEGATIVE_INFINITY","children","result","raw","each","queryResult","i","resultNode","findUniqueId","uniqueId","parentResult","push","parent","Math","min","without","POSITIVE_INFINITY","rootResult","resultNodeToQueryResult","attachments","attachment","defaultGetResult","results","childResults","unshift","topResult","shift","defaultGetMoreResults","map","sortBy","resultNodes","length","childField","logger","warn","parentField","child","data","disabled","queryBuilder","filterField","filterFieldRange","range","requiredFields","_folded","getResult","rearrange","forEach","getFieldValue","sort","shouldBeReversed","reverse","addLoadMoreHandler","query","direction","any","childResult","isNullOrUndefined","originalQuery","enableExpand","moreResults","clone","builder","QueryBuilder","numberOfResults","fieldValue","isNonEmptyString","advancedExpression","addFieldExpression","aq","build","q","enableQuerySyntax","expandExpression","cq","firstResult","putInQueryBuilder","sortCriteria","sortField","queryController","getEndpoint","search","then","handlePreprocessMoreResults","catch","e","error","getResults","getMoreResults","$$","trigger","preprocessMoreResults","doExport","exportGlobally","buildFieldOption","defaultValue","deprecated","buildNumberOption","buildCustomOption","SortCriteria","parse","buildBooleanOption","buildQueryExpressionOption","depend","Component","Initialization","registerAutoCreateComponent","254","defaultResult","FoldingForThread","498","VALID_SORT","VALID_DIRECTION","SortCriterion","sortIsField","isValidSort","values","sortNeedsDirection","isValidDirection","chain","contains","criteria","charAt","sortsNeedingDirection","DATE","rawCriteriaString","split","criterion","match","get","first","enumerable","configurable","toString","join","equals"],"mappings":"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","file":"FoldingForThread.min__00ecf0bd3e47c7b52b32.js","sourcesContent":["webpackJsonpCoveo__temporary([37,47],{\n\n/***/ 187:\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar __extends = (this && this.__extends) || (function () {\n var extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n return function (d, b) {\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar underscore_1 = __webpack_require__(0);\nvar QueryEvents_1 = __webpack_require__(11);\nvar GlobalExports_1 = __webpack_require__(3);\nvar Assert_1 = __webpack_require__(5);\nvar Dom_1 = __webpack_require__(1);\nvar Utils_1 = __webpack_require__(4);\nvar Component_1 = __webpack_require__(7);\nvar ComponentOptions_1 = __webpack_require__(8);\nvar Initialization_1 = __webpack_require__(2);\nvar QueryBuilder_1 = __webpack_require__(47);\nvar SortCriteria_1 = __webpack_require__(498);\n/**\n * The `Folding` component makes it possible to render hierarchic representations of search results sharing a common\n * [`field`]{@link Folding.options.field}.\n *\n * This component has no visual impact on its own. It simply folds certain search results so that the\n * [`ResultFolding`]{@link ResultFolding} and [`ResultAttachments`]{@link ResultAttachments} components can then nicely\n * render them within result templates (see [Result Templates](https://docs.coveo.com/en/413/)).\n *\n * A typical use case of the `Folding` component is to fold email conversations and message board threads results in a\n * result set in order to display them in a convenient format. Messages belonging to a single conversation typically\n * have a unique conversation ID. By indexing this ID on a field, you can use it to fold search results (see\n * [Folding Results](https://docs.coveo.com/en/428/)).\n *\n * **Note:**\n * > There can only be one `Folding` component per [`Tab`]{@link Tab} component.\n *\n */\nvar Folding = /** @class */ (function (_super) {\n __extends(Folding, _super);\n /**\n * Creates a new `Folding` component.\n * @param element The HTMLElement on which to instantiate the component.\n * @param options The options for the `Folding` component.\n * @param bindings The bindings that the component requires to function normally. If not set, these will be\n * automatically resolved (with a slower execution time).\n */\n function Folding(element, options, bindings) {\n var _this = _super.call(this, element, Folding.ID, bindings) || this;\n _this.element = element;\n _this.options = options;\n _this.options = ComponentOptions_1.ComponentOptions.initComponentOptions(element, Folding, options);\n Assert_1.Assert.check(Utils_1.Utils.isCoveoField(_this.options.field), _this.options.field + ' is not a valid field');\n Assert_1.Assert.exists(_this.options.maximumExpandedResults);\n _this.swapParentChildFoldingFields();\n _this.bind.onRootElement(QueryEvents_1.QueryEvents.buildingQuery, _this.handleBuildingQuery);\n _this.bind.onRootElement(QueryEvents_1.QueryEvents.preprocessResults, _this.handlepreprocessResults);\n return _this;\n }\n // From a list of results, return a list of results and their attachments\n // We use parentResult to build a tree of result\n Folding.foldWithParent = function (queryResults) {\n var rootNode = {\n score: Number.NEGATIVE_INFINITY,\n children: [],\n result: {\n raw: false\n }\n };\n underscore_1.each(queryResults, function (queryResult, i) {\n var resultNode = Folding.findUniqueId(rootNode.children, queryResult.uniqueId);\n // If he have no parent or is parent is him self, add it to the root\n if (queryResult.parentResult == null || queryResult.parentResult.uniqueId == queryResult.uniqueId) {\n // Add it only if he do not exist\n if (resultNode == null) {\n resultNode = {\n result: queryResult,\n score: i,\n children: []\n };\n rootNode.children.push(resultNode);\n resultNode.parent = rootNode;\n }\n }\n else {\n // If the resultNode already exist\n if (resultNode != null) {\n resultNode.score = Math.min(i, resultNode.score);\n // Remove himself from his parent because it will be added in his parent. This allowed to remove duplicate.\n resultNode.parent.children = underscore_1.without(resultNode.parent.children, resultNode);\n }\n else {\n resultNode = {\n result: queryResult,\n score: i,\n children: []\n };\n }\n var parentResult = Folding.findUniqueId(rootNode.children, queryResult.parentResult.uniqueId);\n // If the parent does not already exist, create it and add it the root\n if (parentResult == null) {\n parentResult = {\n result: queryResult.parentResult,\n score: Number.POSITIVE_INFINITY,\n children: []\n };\n rootNode.children.push(parentResult);\n parentResult.parent = rootNode;\n }\n // Add the resultNode to parent\n parentResult.children.push(resultNode);\n resultNode.parent = parentResult;\n var parent_1 = parentResult;\n while (parent_1 != null && resultNode.score < parent_1.score) {\n parent_1.score = resultNode.score;\n parent_1 = parent_1.parent;\n }\n }\n });\n var rootResult = Folding.resultNodeToQueryResult(rootNode);\n // Remove the root from all results\n underscore_1.each(rootResult.attachments, function (attachment) { return (attachment.parentResult = null); });\n return rootResult.attachments;\n };\n // 99.9% of the folding case will be alright with those default functions.\n // Otherwise use the options getResult and getMoreResults\n Folding.defaultGetResult = function (result) {\n var results = result.childResults || [];\n // Add the top result at the top of the list\n results.unshift(result);\n // Empty childResults just to make it more clean\n result.childResults = [];\n // Fold those results\n results = Folding.foldWithParent(results);\n // The first result is the top one\n var topResult = results.shift();\n // All other the results are childResults\n topResult.childResults = results;\n return topResult;\n };\n Folding.defaultGetMoreResults = function (results) {\n // The result are flat, just do the fold\n return Folding.foldWithParent(results);\n };\n // Convert ResultNode to QueryResult\n Folding.resultNodeToQueryResult = function (resultNode) {\n var result = resultNode.result;\n result.attachments = underscore_1.map(underscore_1.sortBy(resultNode.children, 'score'), Folding.resultNodeToQueryResult);\n result.parentResult = resultNode.parent != null ? resultNode.parent.result : null;\n return result;\n };\n Folding.findUniqueId = function (resultNodes, uniqueId) {\n for (var i = 0; i < resultNodes.length; i++) {\n if (resultNodes[i].result.uniqueId == uniqueId) {\n return resultNodes[i];\n }\n var resultNode = Folding.findUniqueId(resultNodes[i].children, uniqueId);\n if (resultNode != null) {\n return resultNode;\n }\n }\n return null;\n };\n Folding.prototype.swapParentChildFoldingFields = function () {\n // Swap \"old\" childField and parentField and assign them to the \"new\" parent option\n // This needs to be done because connectors push the default data in *reverse* order compared to what the index expect.\n if (this.options.childField != null) {\n this.logger.warn('Detecting usage of deprecated option \"childField\". Assigning it automatically to the \"parent\" option instead.');\n this.logger.warn('The option definition was changed to support universal folding across all sources.');\n this.logger.warn('To remove this warning, rename the \"childField\" option (data-child-field) to \"parent\" (data-parent).');\n this.options.parent = this.options.childField;\n }\n if (this.options.parentField != null) {\n this.logger.warn('Detecting usage of deprecated option \"parentField\". Assigning it automatically to the \"child\" option instead.');\n this.logger.warn('The option definition was changed to support universal folding across all sources.');\n this.logger.warn('To remove this warning, rename the \"parentField\" option (data-parent-field) to \"child\" (data-child).');\n this.options.child = this.options.parentField;\n }\n };\n Folding.prototype.handleBuildingQuery = function (data) {\n Assert_1.Assert.exists(data);\n if (!this.disabled) {\n data.queryBuilder.childField = this.options.parent;\n data.queryBuilder.parentField = this.options.child;\n data.queryBuilder.filterField = this.options.field;\n data.queryBuilder.filterFieldRange = this.options.range;\n data.queryBuilder.requiredFields.push(this.options.field);\n if (this.options.parent != null) {\n data.queryBuilder.requiredFields.push(this.options.parent);\n }\n if (this.options.child != null) {\n data.queryBuilder.requiredFields.push(this.options.child);\n }\n }\n };\n Folding.prototype.handlepreprocessResults = function (data) {\n var _this = this;\n Assert_1.Assert.exists(data);\n Assert_1.Assert.check(!data.results._folded, 'Two or more Folding components are active at the same time for the same Tab. Cannot process the results.');\n data.results._folded = true;\n var queryResults = data.results;\n var getResult = this.options.getResult || Folding.defaultGetResult;\n queryResults.results = underscore_1.map(queryResults.results, getResult);\n if (this.options.rearrange) {\n queryResults.results.forEach(function (result) {\n result.childResults = underscore_1.sortBy(result.childResults, function (result) { return Utils_1.Utils.getFieldValue(result, _this.options.rearrange.sort); });\n if (_this.shouldBeReversed(result.childResults)) {\n result.childResults = result.childResults.reverse();\n }\n });\n }\n this.addLoadMoreHandler(queryResults.results, data.query);\n };\n Folding.prototype.shouldBeReversed = function (childResults) {\n var _this = this;\n if (this.options.rearrange.direction == 'ascending') {\n return false;\n }\n var childMissingSortByValue = underscore_1.any(childResults, function (childResult) {\n return Utils_1.Utils.isNullOrUndefined(Utils_1.Utils.getFieldValue(childResult, _this.options.rearrange.sort));\n });\n if (childMissingSortByValue) {\n return false;\n }\n return true;\n };\n Folding.prototype.addLoadMoreHandler = function (results, originalQuery) {\n var _this = this;\n return underscore_1.map(results, function (result) {\n if (_this.options.enableExpand && !Utils_1.Utils.isNullOrUndefined(Utils_1.Utils.getFieldValue(result, _this.options.field))) {\n result.moreResults = function () {\n return _this.moreResults(result, originalQuery);\n };\n }\n return result;\n });\n };\n Folding.prototype.moreResults = function (result, originalQuery) {\n var _this = this;\n var query = underscore_1.clone(originalQuery);\n var builder = new QueryBuilder_1.QueryBuilder();\n query.numberOfResults = this.options.maximumExpandedResults;\n var fieldValue = Utils_1.Utils.getFieldValue(result, this.options.field);\n if (Utils_1.Utils.isNonEmptyString(fieldValue)) {\n builder.advancedExpression.addFieldExpression(this.options.field, '=', [fieldValue]);\n query.aq = builder.build().aq;\n }\n if (Utils_1.Utils.isNonEmptyString(originalQuery.q)) {\n // We add keywords to get the highlight and we add @uri to get all results\n // To ensure it plays nicely with query syntax, we ensure that the needed part of the query\n // are correctly surrounded with the no syntax block\n if (originalQuery.enableQuerySyntax) {\n query.q = \"( \" + originalQuery.q + \" ) OR @uri\";\n }\n else {\n query.enableQuerySyntax = true;\n query.q = \"( <@- \" + originalQuery.q + \" -@> ) OR @uri\";\n }\n }\n if (Utils_1.Utils.isNonEmptyString(this.options.expandExpression)) {\n query.cq = this.options.expandExpression;\n }\n if (this.options.child != null) {\n query.parentField = this.options.child;\n }\n if (this.options.parent != null) {\n query.childField = this.options.parent;\n }\n query.filterField = null;\n query.filterFieldRange = null;\n query.firstResult = 0;\n if (this.options.rearrange) {\n this.options.rearrange.putInQueryBuilder(builder);\n query.sortCriteria = builder.sortCriteria;\n query.sortField = builder.sortField;\n }\n else {\n query.sortCriteria = originalQuery.sortCriteria;\n query.sortField = originalQuery.sortField;\n }\n return this.queryController\n .getEndpoint()\n .search(query)\n .then(function (results) {\n _this.handlePreprocessMoreResults(results);\n return results.results;\n })\n .catch(function (e) {\n _this.logger.error(\"Invalid query performed while trying to retrieve more results for folding.\", e);\n return [];\n });\n };\n Folding.prototype.handlePreprocessMoreResults = function (queryResults) {\n var getResults = this.options.getMoreResults || Folding.defaultGetMoreResults;\n queryResults.results = getResults(queryResults.results);\n Dom_1.$$(this.element).trigger(QueryEvents_1.QueryEvents.preprocessMoreResults, {\n results: queryResults\n });\n };\n Folding.ID = 'Folding';\n Folding.doExport = function () {\n GlobalExports_1.exportGlobally({\n Folding: Folding\n });\n };\n /**\n * The options for the component\n * @componentOptions\n */\n Folding.options = {\n /**\n * Specifies the name of the field on which to do the folding.\n *\n * Specifying a value for this option is required for this component to work.\n *\n * **Note:**\n * > In an Elasticsearch index, the corresponding field must be configured as a *Facet* field\n * > (see [Add or Edit Fields](https://docs.coveo.com/en/1982/)).\n * > This limitation does not apply to Coveo indexes.\n *\n * Default value is `@foldingcollection`.\n */\n field: ComponentOptions_1.ComponentOptions.buildFieldOption({ defaultValue: '@foldingcollection' }),\n /**\n * Specifies the field that determines whether a certain result is a child of another top result.\n *\n * **Note:**\n * > In the index, the values of the corresponding field must:\n * >Â - Contain alphanumerical characters only.\n * > - Contain no more than 60 characters.\n *\n * Default value is `@foldingchild`.\n */\n child: ComponentOptions_1.ComponentOptions.buildFieldOption({ defaultValue: '@foldingchild' }),\n /**\n * Specifies the field that determines whether a certain result is a top result containing other child results.\n *\n * **Note:**\n * > In the index, the values of the corresponding field must:\n * >Â - Contain alphanumerical characters only.\n * > - Contain no more than 60 characters.\n *\n * Default value is `@foldingparent`.\n */\n parent: ComponentOptions_1.ComponentOptions.buildFieldOption({ defaultValue: '@foldingparent' }),\n /**\n * This option is deprecated. Instead, use the {@link Folding.options.parent} option.\n * @deprecated\n */\n childField: ComponentOptions_1.ComponentOptions.buildFieldOption({\n deprecated: 'This option is deprecated. Instead, use the data-parent option.'\n }),\n /**\n * This option is deprecated. Instead, use the {@link Folding.options.child} option.\n * @deprecated\n */\n parentField: ComponentOptions_1.ComponentOptions.buildFieldOption({\n deprecated: 'This option is deprecated. Instead, use the data-child option.'\n }),\n /**\n * Specifies the maximum number of child results to fold.\n *\n * **Example:**\n * > For an email thread with a total of 20 messages, using the default value of `2` means that the component loads\n * > up to a maximum of 2 child messages under the original message, unless the end user expands the entire\n * > conversation using the **Show More** link (see the [`enableExpand`]{@link Folding.options.enableExpand}\n * > option).\n *\n * Default value is `2`. Minimum value is `0`.\n */\n range: ComponentOptions_1.ComponentOptions.buildNumberOption({ defaultValue: 2, min: 0 }),\n /**\n * Specifies the sort criteria to apply to the top result and its child results (e.g., `date ascending`,\n * `@myfield descending`, etc.). See [sortCriteria](https://docs.coveo.com/en/1461/#RestQueryParameters-sortCriteria).\n *\n * This option works from the results returned by the index. This means that if only the three most relevant folded results are returned by the index\n * and you choose to rearrange the folded results by date, then the three most relevant results will be rearranged by date,\n * meaning that the first folded result is not necessarily the oldest or newest item.\n *\n * However, since clicking on the `Show More` button triggers a new query, you would receive new results based on the sort criteria of this option.\n *\n * **Example**\n * > If you are folding email results by conversation and you specify `date descending` as the `rearrange` value of\n * > the `Folding` component, the component re-arranges email conversations so that the newest email is always the\n * > top result. Specifying `date ascending` instead always makes the original email the top result, as it is also\n * > necessarily the oldest.\n *\n * By default, the component displays the results in the order that the index returns them.\n */\n rearrange: ComponentOptions_1.ComponentOptions.buildCustomOption(function (value) { return (Utils_1.Utils.isNonEmptyString(value) ? SortCriteria_1.SortCriteria.parse(value) : null); }),\n /**\n * Specifies whether to add a callback function on the top result, allowing to make an additional query to load all\n * of its child results (e.g., to load all conversations of a given thread).\n *\n * Concretely, the [`ResultFolding`]{@link ResultFolding} component uses this for its **Show More** link.\n *\n * See also the [`expandExpression`]{@link Folding.options.expandExpression} and\n * [`maximumExpandedResults`]{@link Folding.options.maximumExpandedResults} options.\n *\n * Default value is `true`.\n */\n enableExpand: ComponentOptions_1.ComponentOptions.buildBooleanOption({ defaultValue: true }),\n /**\n * If the [`enableExpand`]{@link Folding.options.enableExpand} option is `true`, specifies a custom constant\n * expression to send when querying the expanded results.\n *\n * Default value is `undefined`.\n */\n expandExpression: ComponentOptions_1.ComponentOptions.buildQueryExpressionOption({ depend: 'enableExpand' }),\n /**\n * If the [`enableExpand`]{@link Folding.options.enableExpand} option is `true`, specifies the maximum number of\n * results to load when expanding.\n *\n * Default value is `100`. Minimum value is `1`.\n */\n maximumExpandedResults: ComponentOptions_1.ComponentOptions.buildNumberOption({ defaultValue: 100, min: 1, depend: 'enableExpand' }),\n /**\n * Specifies the function that manages the individual folding of each result.\n *\n * Default value is:\n *\n * ```javascript\n * var results = result.childResults || [];\n * // Add the top result at the top of the list.\n * results.unshift(result);\n * // Empty childResults just to clean it.\n * result.childResults = [];\n * // Fold those results.\n * results = Coveo.Folding.foldWithParent(results);\n * // The first result is the top one.\n * var topResult = results.shift();\n * // All other results are childResults.\n * topResult.childResults = results;\n * return topResult;\n * ```\n *\n * You can pre-process all the result with this option in the [`init`]{@link init} call of your search interface:\n *\n * ```javascript\n * Coveo.init(document.querySelector('#search'), {\n * Folding: {\n * getResult: function(result) {\n * result = Coveo.Folding.defaultGetResult(result);\n * // Your code here\n * }\n * }\n * })\n * ```\n */\n getResult: ComponentOptions_1.ComponentOptions.buildCustomOption(function () {\n return null;\n }),\n /**\n * Specifies the function that manages the folding of all results.\n *\n * Default value is:\n *\n * ```javascript\n * Coveo.Folding.defaultGetMoreResults = function(results) {\n * // The results are flat, just do the folding.\n * return Coveo.Folding.foldWithParent(results);\n * }\n * ```\n */\n getMoreResults: ComponentOptions_1.ComponentOptions.buildCustomOption(function () {\n return null;\n })\n };\n return Folding;\n}(Component_1.Component));\nexports.Folding = Folding;\nInitialization_1.Initialization.registerAutoCreateComponent(Folding);\n\n\n/***/ }),\n\n/***/ 254:\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar __extends = (this && this.__extends) || (function () {\n var extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n return function (d, b) {\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar GlobalExports_1 = __webpack_require__(3);\nvar Initialization_1 = __webpack_require__(2);\nvar Folding_1 = __webpack_require__(187);\n/**\n * The `FoldingForThread` component inherits from the [`Folding`]{@link Folding} component. It offers the\n * same configuration options.\n *\n * Folding conversations and threads requires different processing. When you need to fold all child items (including\n * their attachments) on the same level under a common ancestor item, use this component rather than the `Folding`\n * component.\n *\n * This component works well with Chatter and Lithium.\n *\n * **Note:**\n * > There can only be one `FoldingForThread` component per [`Tab`]{@link Tab} component.\n *\n * See [Folding Results](https://docs.coveo.com/en/428/).\n */\nvar FoldingForThread = /** @class */ (function (_super) {\n __extends(FoldingForThread, _super);\n /**\n * Creates a new `FoldingForThread` component\n * @param element The HTMLElement on which to instantiate the component.\n * @param options The options for the `FoldingForThread` component.\n * @param bindings The bindings that the component requires to function normally. If not set, these will be\n * automatically resolved (with a slower execution time).\n */\n function FoldingForThread(element, options, bindings) {\n var _this = _super.call(this, element, options, bindings) || this;\n _this.element = element;\n _this.options = options;\n _this.options.getMoreResults = function (results) {\n return Folding_1.Folding.foldWithParent(results)[0].attachments;\n };\n _this.options.getResult = function (result) {\n var defaultResult = Folding_1.Folding.defaultGetResult(result);\n defaultResult.childResults = defaultResult.attachments;\n defaultResult.attachments = [];\n return defaultResult;\n };\n return _this;\n }\n FoldingForThread.ID = 'FoldingForThread';\n FoldingForThread.doExport = function () {\n GlobalExports_1.exportGlobally({\n FoldingForThread: FoldingForThread\n });\n };\n return FoldingForThread;\n}(Folding_1.Folding));\nexports.FoldingForThread = FoldingForThread;\nInitialization_1.Initialization.registerAutoCreateComponent(FoldingForThread);\n\n\n/***/ }),\n\n/***/ 498:\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar underscore_1 = __webpack_require__(0);\nvar Assert_1 = __webpack_require__(5);\nvar VALID_SORT;\n(function (VALID_SORT) {\n VALID_SORT[\"RELEVANCY\"] = \"relevancy\";\n VALID_SORT[\"DATE\"] = \"date\";\n VALID_SORT[\"QRE\"] = \"qre\";\n})(VALID_SORT = exports.VALID_SORT || (exports.VALID_SORT = {}));\nvar VALID_DIRECTION;\n(function (VALID_DIRECTION) {\n VALID_DIRECTION[\"ASCENDING\"] = \"ascending\";\n VALID_DIRECTION[\"DESCENDING\"] = \"descending\";\n})(VALID_DIRECTION = exports.VALID_DIRECTION || (exports.VALID_DIRECTION = {}));\nvar SortCriterion = /** @class */ (function () {\n /**\n * Create a new SortCriteria\n * @param sort The sort criteria (e.g.: relevancy, date)\n * @param direction The direction by which to sort (e.g.: ascending, descending)\n */\n function SortCriterion(sort, direction) {\n if (direction === void 0) { direction = ''; }\n this.sort = sort;\n this.direction = direction;\n if (!SortCriterion.sortIsField(sort)) {\n Assert_1.Assert.check(this.isValidSort(sort), sort + \" is not a valid sort criteria. Valid values are \" + underscore_1.values(VALID_SORT) + \" or a valid index sortable index field.\");\n }\n if (SortCriterion.sortNeedsDirection(sort)) {\n Assert_1.Assert.check(this.isValidDirection(direction), direction + \" is not a valid sort criteria direction. Valid values are \" + underscore_1.values(VALID_DIRECTION));\n }\n else {\n Assert_1.Assert.check(direction == '');\n }\n }\n SortCriterion.prototype.isValidDirection = function (direction) {\n return underscore_1.chain(VALID_DIRECTION)\n .values()\n .contains(direction)\n .value();\n };\n SortCriterion.prototype.isValidSort = function (sort) {\n return underscore_1.chain(VALID_SORT)\n .values()\n .contains(sort)\n .value();\n };\n SortCriterion.sortIsField = function (criteria) {\n return criteria.charAt(0) == '@';\n };\n SortCriterion.sortNeedsDirection = function (sort) {\n return underscore_1.contains(SortCriterion.sortsNeedingDirection, sort) || SortCriterion.sortIsField(sort);\n };\n SortCriterion.sortsNeedingDirection = [VALID_SORT.DATE];\n return SortCriterion;\n}());\nexports.SortCriterion = SortCriterion;\nvar SortCriteria = /** @class */ (function () {\n function SortCriteria(rawCriteriaString) {\n var _this = this;\n this.criteria = [];\n var criteria = rawCriteriaString.split(';');\n criteria.forEach(function (criterion) {\n var split = criterion.match(/\\S+/g);\n _this.criteria.push(new SortCriterion(split[0], split[1]));\n });\n }\n Object.defineProperty(SortCriteria.prototype, \"direction\", {\n get: function () {\n return underscore_1.first(this.criteria).direction;\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(SortCriteria.prototype, \"sort\", {\n get: function () {\n return underscore_1.first(this.criteria).sort;\n },\n enumerable: true,\n configurable: true\n });\n /**\n * Return a new SortCriteria from a string\n * @param criteria The string from which to create the SortCriteria\n */\n SortCriteria.parse = function (criteria) {\n return new SortCriteria(criteria);\n };\n /**\n * Put the sort criteria in the passed queryBuilder\n * @param queryBuilder The queryBuilder in which to put the sort criteria.\n */\n SortCriteria.prototype.putInQueryBuilder = function (queryBuilder) {\n Assert_1.Assert.exists(queryBuilder);\n queryBuilder.sortCriteria = this.toString()\n .split(';')\n .join(',');\n };\n /**\n * Returns a string representation of the sort criteria (e.g.: 'date ascending').\n */\n SortCriteria.prototype.toString = function () {\n return this.criteria\n .map(function (criterion) {\n return criterion.direction ? criterion.sort + \" \" + criterion.direction : \"\" + criterion.sort;\n })\n .join(';');\n };\n /**\n * Checks if the SortCriteria is equal to another.\n * @param criteria The SortCriteria to compare with\n */\n SortCriteria.prototype.equals = function (criteria) {\n return criteria.toString() == this.toString();\n };\n return SortCriteria;\n}());\nexports.SortCriteria = SortCriteria;\n\n\n/***/ })\n\n});\n\n\n// WEBPACK FOOTER //\n// FoldingForThread.min__00ecf0bd3e47c7b52b32.js","import { any, clone, each, map, sortBy, without } from 'underscore';\nimport { IBuildingQueryEventArgs, IPreprocessResultsEventArgs, QueryEvents } from '../../events/QueryEvents';\nimport { exportGlobally } from '../../GlobalExports';\nimport { Assert } from '../../misc/Assert';\nimport { IQuery } from '../../rest/Query';\nimport { IQueryResult } from '../../rest/QueryResult';\nimport { IQueryResults } from '../../rest/QueryResults';\nimport { $$ } from '../../utils/Dom';\nimport { Utils } from '../../utils/Utils';\nimport { Component } from '../Base/Component';\nimport { IComponentBindings } from '../Base/ComponentBindings';\nimport { ComponentOptions } from '../Base/ComponentOptions';\nimport { IFieldOption, IQueryExpression } from '../Base/IComponentOptions';\nimport { Initialization } from '../Base/Initialization';\nimport { QueryBuilder } from '../Base/QueryBuilder';\nimport { SortCriteria } from '../Sort/SortCriteria';\n\nexport interface IFoldingOptions {\n field?: IFieldOption;\n child?: IFieldOption;\n parent?: IFieldOption;\n\n childField?: IFieldOption;\n parentField?: IFieldOption;\n\n range?: number;\n rearrange?: SortCriteria;\n\n enableExpand?: boolean;\n expandExpression?: IQueryExpression;\n maximumExpandedResults?: number;\n\n /**\n * Manage folding for each results individually\n */\n getResult?: (result: IQueryResult) => IQueryResult;\n /**\n * Manage folding of all more results\n */\n getMoreResults?: (results: IQueryResult[]) => IQueryResult[];\n}\n\ninterface IResultNode {\n score: number;\n parent?: IResultNode;\n result: IQueryResult;\n children: IResultNode[];\n}\n\n/**\n * The `Folding` component makes it possible to render hierarchic representations of search results sharing a common\n * [`field`]{@link Folding.options.field}.\n *\n * This component has no visual impact on its own. It simply folds certain search results so that the\n * [`ResultFolding`]{@link ResultFolding} and [`ResultAttachments`]{@link ResultAttachments} components can then nicely\n * render them within result templates (see [Result Templates](https://docs.coveo.com/en/413/)).\n *\n * A typical use case of the `Folding` component is to fold email conversations and message board threads results in a\n * result set in order to display them in a convenient format. Messages belonging to a single conversation typically\n * have a unique conversation ID. By indexing this ID on a field, you can use it to fold search results (see\n * [Folding Results](https://docs.coveo.com/en/428/)).\n *\n * **Note:**\n * > There can only be one `Folding` component per [`Tab`]{@link Tab} component.\n *\n */\nexport class Folding extends Component {\n static ID = 'Folding';\n\n static doExport = () => {\n exportGlobally({\n Folding: Folding\n });\n };\n\n /**\n * The options for the component\n * @componentOptions\n */\n static options: IFoldingOptions = {\n /**\n * Specifies the name of the field on which to do the folding.\n *\n * Specifying a value for this option is required for this component to work.\n *\n * **Note:**\n * > In an Elasticsearch index, the corresponding field must be configured as a *Facet* field\n * > (see [Add or Edit Fields](https://docs.coveo.com/en/1982/)).\n * > This limitation does not apply to Coveo indexes.\n *\n * Default value is `@foldingcollection`.\n */\n field: ComponentOptions.buildFieldOption({ defaultValue: '@foldingcollection' }),\n /**\n * Specifies the field that determines whether a certain result is a child of another top result.\n *\n * **Note:**\n * > In the index, the values of the corresponding field must:\n * >Â - Contain alphanumerical characters only.\n * > - Contain no more than 60 characters.\n *\n * Default value is `@foldingchild`.\n */\n child: ComponentOptions.buildFieldOption({ defaultValue: '@foldingchild' }),\n /**\n * Specifies the field that determines whether a certain result is a top result containing other child results.\n *\n * **Note:**\n * > In the index, the values of the corresponding field must:\n * >Â - Contain alphanumerical characters only.\n * > - Contain no more than 60 characters.\n *\n * Default value is `@foldingparent`.\n */\n parent: ComponentOptions.buildFieldOption({ defaultValue: '@foldingparent' }),\n\n /**\n * This option is deprecated. Instead, use the {@link Folding.options.parent} option.\n * @deprecated\n */\n childField: ComponentOptions.buildFieldOption({\n deprecated: 'This option is deprecated. Instead, use the data-parent option.'\n }),\n /**\n * This option is deprecated. Instead, use the {@link Folding.options.child} option.\n * @deprecated\n */\n parentField: ComponentOptions.buildFieldOption({\n deprecated: 'This option is deprecated. Instead, use the data-child option.'\n }),\n\n /**\n * Specifies the maximum number of child results to fold.\n *\n * **Example:**\n * > For an email thread with a total of 20 messages, using the default value of `2` means that the component loads\n * > up to a maximum of 2 child messages under the original message, unless the end user expands the entire\n * > conversation using the **Show More** link (see the [`enableExpand`]{@link Folding.options.enableExpand}\n * > option).\n *\n * Default value is `2`. Minimum value is `0`.\n */\n range: ComponentOptions.buildNumberOption({ defaultValue: 2, min: 0 }),\n\n /**\n * Specifies the sort criteria to apply to the top result and its child results (e.g., `date ascending`,\n * `@myfield descending`, etc.). See [sortCriteria](https://docs.coveo.com/en/1461/#RestQueryParameters-sortCriteria).\n *\n * This option works from the results returned by the index. This means that if only the three most relevant folded results are returned by the index\n * and you choose to rearrange the folded results by date, then the three most relevant results will be rearranged by date,\n * meaning that the first folded result is not necessarily the oldest or newest item.\n *\n * However, since clicking on the `Show More` button triggers a new query, you would receive new results based on the sort criteria of this option.\n *\n * **Example**\n * > If you are folding email results by conversation and you specify `date descending` as the `rearrange` value of\n * > the `Folding` component, the component re-arranges email conversations so that the newest email is always the\n * > top result. Specifying `date ascending` instead always makes the original email the top result, as it is also\n * > necessarily the oldest.\n *\n * By default, the component displays the results in the order that the index returns them.\n */\n rearrange: ComponentOptions.buildCustomOption(value => (Utils.isNonEmptyString(value) ? SortCriteria.parse(value) : null)),\n\n /**\n * Specifies whether to add a callback function on the top result, allowing to make an additional query to load all\n * of its child results (e.g., to load all conversations of a given thread).\n *\n * Concretely, the [`ResultFolding`]{@link ResultFolding} component uses this for its **Show More** link.\n *\n * See also the [`expandExpression`]{@link Folding.options.expandExpression} and\n * [`maximumExpandedResults`]{@link Folding.options.maximumExpandedResults} options.\n *\n * Default value is `true`.\n */\n enableExpand: ComponentOptions.buildBooleanOption({ defaultValue: true }),\n /**\n * If the [`enableExpand`]{@link Folding.options.enableExpand} option is `true`, specifies a custom constant\n * expression to send when querying the expanded results.\n *\n * Default value is `undefined`.\n */\n expandExpression: ComponentOptions.buildQueryExpressionOption({ depend: 'enableExpand' }),\n\n /**\n * If the [`enableExpand`]{@link Folding.options.enableExpand} option is `true`, specifies the maximum number of\n * results to load when expanding.\n *\n * Default value is `100`. Minimum value is `1`.\n */\n maximumExpandedResults: ComponentOptions.buildNumberOption({ defaultValue: 100, min: 1, depend: 'enableExpand' }),\n\n /**\n * Specifies the function that manages the individual folding of each result.\n *\n * Default value is:\n *\n * ```javascript\n * var results = result.childResults || [];\n * // Add the top result at the top of the list.\n * results.unshift(result);\n * // Empty childResults just to clean it.\n * result.childResults = [];\n * // Fold those results.\n * results = Coveo.Folding.foldWithParent(results);\n * // The first result is the top one.\n * var topResult = results.shift();\n * // All other results are childResults.\n * topResult.childResults = results;\n * return topResult;\n * ```\n *\n * You can pre-process all the result with this option in the [`init`]{@link init} call of your search interface:\n *\n * ```javascript\n * Coveo.init(document.querySelector('#search'), {\n * Folding: {\n * getResult: function(result) {\n * result = Coveo.Folding.defaultGetResult(result);\n * // Your code here\n * }\n * }\n * })\n * ```\n */\n getResult: ComponentOptions.buildCustomOption<(result: IQueryResult) => IQueryResult>(() => {\n return null;\n }),\n\n /**\n * Specifies the function that manages the folding of all results.\n *\n * Default value is:\n *\n * ```javascript\n * Coveo.Folding.defaultGetMoreResults = function(results) {\n * // The results are flat, just do the folding.\n * return Coveo.Folding.foldWithParent(results);\n * }\n * ```\n */\n getMoreResults: ComponentOptions.buildCustomOption<(results: IQueryResult[]) => IQueryResult[]>(() => {\n return null;\n })\n };\n\n /**\n * Creates a new `Folding` component.\n * @param element The HTMLElement on which to instantiate the component.\n * @param options The options for the `Folding` component.\n * @param bindings The bindings that the component requires to function normally. If not set, these will be\n * automatically resolved (with a slower execution time).\n */\n constructor(public element: HTMLElement, public options: IFoldingOptions, bindings?: IComponentBindings) {\n super(element, Folding.ID, bindings);\n\n this.options = ComponentOptions.initComponentOptions(element, Folding, options);\n\n Assert.check(Utils.isCoveoField(<string>this.options.field), this.options.field + ' is not a valid field');\n Assert.exists(this.options.maximumExpandedResults);\n\n this.swapParentChildFoldingFields();\n\n this.bind.onRootElement(QueryEvents.buildingQuery, this.handleBuildingQuery);\n this.bind.onRootElement(QueryEvents.preprocessResults, this.handlepreprocessResults);\n }\n\n // From a list of results, return a list of results and their attachments\n // We use parentResult to build a tree of result\n static foldWithParent(queryResults: IQueryResult[]): IQueryResult[] {\n const rootNode: IResultNode = {\n score: Number.NEGATIVE_INFINITY,\n children: [],\n result: <IQueryResult>{\n raw: false\n }\n };\n\n each(queryResults, (queryResult: IQueryResult, i: number) => {\n let resultNode = Folding.findUniqueId(rootNode.children, queryResult.uniqueId);\n // If he have no parent or is parent is him self, add it to the root\n if (queryResult.parentResult == null || queryResult.parentResult.uniqueId == queryResult.uniqueId) {\n // Add it only if he do not exist\n if (resultNode == null) {\n resultNode = {\n result: queryResult,\n score: i,\n children: []\n };\n rootNode.children.push(resultNode);\n resultNode.parent = rootNode;\n }\n } else {\n // If the resultNode already exist\n if (resultNode != null) {\n resultNode.score = Math.min(i, resultNode.score);\n // Remove himself from his parent because it will be added in his parent. This allowed to remove duplicate.\n resultNode.parent.children = without(resultNode.parent.children, resultNode);\n } else {\n resultNode = {\n result: queryResult,\n score: i,\n children: []\n };\n }\n\n let parentResult = Folding.findUniqueId(rootNode.children, queryResult.parentResult.uniqueId);\n // If the parent does not already exist, create it and add it the root\n if (parentResult == null) {\n parentResult = {\n result: queryResult.parentResult,\n score: Number.POSITIVE_INFINITY,\n children: []\n };\n rootNode.children.push(parentResult);\n parentResult.parent = rootNode;\n }\n // Add the resultNode to parent\n parentResult.children.push(resultNode);\n resultNode.parent = parentResult;\n let parent = parentResult;\n while (parent != null && resultNode.score < parent.score) {\n parent.score = resultNode.score;\n parent = parent.parent;\n }\n }\n });\n const rootResult = Folding.resultNodeToQueryResult(rootNode);\n // Remove the root from all results\n each(rootResult.attachments, attachment => (attachment.parentResult = null));\n return rootResult.attachments;\n }\n\n // 99.9% of the folding case will be alright with those default functions.\n // Otherwise use the options getResult and getMoreResults\n public static defaultGetResult(result: IQueryResult) {\n let results: IQueryResult[] = result.childResults || [];\n // Add the top result at the top of the list\n results.unshift(result);\n // Empty childResults just to make it more clean\n result.childResults = [];\n // Fold those results\n results = Folding.foldWithParent(results);\n // The first result is the top one\n const topResult = results.shift();\n // All other the results are childResults\n topResult.childResults = results;\n\n return topResult;\n }\n\n public static defaultGetMoreResults(results: IQueryResult[]) {\n // The result are flat, just do the fold\n return Folding.foldWithParent(results);\n }\n\n // Convert ResultNode to QueryResult\n private static resultNodeToQueryResult(resultNode: IResultNode): IQueryResult {\n const result = resultNode.result;\n result.attachments = map(sortBy<IResultNode>(resultNode.children, 'score'), Folding.resultNodeToQueryResult);\n result.parentResult = resultNode.parent != null ? resultNode.parent.result : null;\n return result;\n }\n\n private static findUniqueId(resultNodes: IResultNode[], uniqueId: string): IResultNode {\n for (let i = 0; i < resultNodes.length; i++) {\n if (resultNodes[i].result.uniqueId == uniqueId) {\n return resultNodes[i];\n }\n const resultNode = Folding.findUniqueId(resultNodes[i].children, uniqueId);\n if (resultNode != null) {\n return resultNode;\n }\n }\n return null;\n }\n\n private swapParentChildFoldingFields() {\n // Swap \"old\" childField and parentField and assign them to the \"new\" parent option\n // This needs to be done because connectors push the default data in *reverse* order compared to what the index expect.\n if (this.options.childField != null) {\n this.logger.warn('Detecting usage of deprecated option \"childField\". Assigning it automatically to the \"parent\" option instead.');\n this.logger.warn('The option definition was changed to support universal folding across all sources.');\n this.logger.warn('To remove this warning, rename the \"childField\" option (data-child-field) to \"parent\" (data-parent).');\n this.options.parent = this.options.childField;\n }\n\n if (this.options.parentField != null) {\n this.logger.warn('Detecting usage of deprecated option \"parentField\". Assigning it automatically to the \"child\" option instead.');\n this.logger.warn('The option definition was changed to support universal folding across all sources.');\n this.logger.warn('To remove this warning, rename the \"parentField\" option (data-parent-field) to \"child\" (data-child).');\n this.options.child = this.options.parentField;\n }\n }\n\n private handleBuildingQuery(data: IBuildingQueryEventArgs) {\n Assert.exists(data);\n\n if (!this.disabled) {\n data.queryBuilder.childField = <string>this.options.parent;\n data.queryBuilder.parentField = <string>this.options.child;\n data.queryBuilder.filterField = <string>this.options.field;\n data.queryBuilder.filterFieldRange = this.options.range;\n\n data.queryBuilder.requiredFields.push(<string>this.options.field);\n if (this.options.parent != null) {\n data.queryBuilder.requiredFields.push(<string>this.options.parent);\n }\n if (this.options.child != null) {\n data.queryBuilder.requiredFields.push(<string>this.options.child);\n }\n }\n }\n\n private handlepreprocessResults(data: IPreprocessResultsEventArgs) {\n Assert.exists(data);\n Assert.check(\n !data.results._folded,\n 'Two or more Folding components are active at the same time for the same Tab. Cannot process the results.'\n );\n data.results._folded = true;\n\n const queryResults = data.results;\n\n const getResult: (result: IQueryResult) => IQueryResult = this.options.getResult || Folding.defaultGetResult;\n queryResults.results = map(queryResults.results, getResult);\n\n if (this.options.rearrange) {\n queryResults.results.forEach(result => {\n result.childResults = sortBy(result.childResults, result => Utils.getFieldValue(result, this.options.rearrange.sort));\n if (this.shouldBeReversed(result.childResults)) {\n result.childResults = result.childResults.reverse();\n }\n });\n }\n\n this.addLoadMoreHandler(<IQueryResult[]>queryResults.results, data.query);\n }\n\n private shouldBeReversed(childResults: IQueryResult[]) {\n if (this.options.rearrange.direction == 'ascending') {\n return false;\n }\n const childMissingSortByValue = any(childResults, childResult => {\n return Utils.isNullOrUndefined(Utils.getFieldValue(childResult, this.options.rearrange.sort));\n });\n if (childMissingSortByValue) {\n return false;\n }\n return true;\n }\n\n private addLoadMoreHandler(results: IQueryResult[], originalQuery: IQuery) {\n return map(results, result => {\n if (this.options.enableExpand && !Utils.isNullOrUndefined(Utils.getFieldValue(result, <string>this.options.field))) {\n result.moreResults = () => {\n return this.moreResults(result, originalQuery);\n };\n }\n return result;\n });\n }\n\n private moreResults(result: IQueryResult, originalQuery: IQuery): Promise<IQueryResult[]> {\n const query = clone(originalQuery);\n const builder = new QueryBuilder();\n\n query.numberOfResults = this.options.maximumExpandedResults;\n const fieldValue = Utils.getFieldValue(result, <string>this.options.field);\n\n if (Utils.isNonEmptyString(fieldValue)) {\n builder.advancedExpression.addFieldExpression(<string>this.options.field, '=', [fieldValue]);\n query.aq = builder.build().aq;\n }\n\n if (Utils.isNonEmptyString(originalQuery.q)) {\n // We add keywords to get the highlight and we add @uri to get all results\n // To ensure it plays nicely with query syntax, we ensure that the needed part of the query\n // are correctly surrounded with the no syntax block\n if (originalQuery.enableQuerySyntax) {\n query.q = `( ${originalQuery.q} ) OR @uri`;\n } else {\n query.enableQuerySyntax = true;\n query.q = `( <@- ${originalQuery.q} -@> ) OR @uri`;\n }\n }\n\n if (Utils.isNonEmptyString(this.options.expandExpression)) {\n query.cq = this.options.expandExpression;\n }\n\n if (this.options.child != null) {\n query.parentField = <string>this.options.child;\n }\n\n if (this.options.parent != null) {\n query.childField = <string>this.options.parent;\n }\n\n query.filterField = null;\n query.filterFieldRange = null;\n query.firstResult = 0;\n\n if (this.options.rearrange) {\n this.options.rearrange.putInQueryBuilder(builder);\n query.sortCriteria = builder.sortCriteria;\n query.sortField = builder.sortField;\n } else {\n query.sortCriteria = originalQuery.sortCriteria;\n query.sortField = originalQuery.sortField;\n }\n\n return this.queryController\n .getEndpoint()\n .search(query)\n .then((results: IQueryResults) => {\n this.handlePreprocessMoreResults(results);\n return results.results;\n })\n .catch(e => {\n this.logger.error(`Invalid query performed while trying to retrieve more results for folding.`, e);\n return [];\n });\n }\n\n private handlePreprocessMoreResults(queryResults: IQueryResults) {\n const getResults: (results: IQueryResult[]) => IQueryResult[] = this.options.getMoreResults || Folding.defaultGetMoreResults;\n queryResults.results = getResults(queryResults.results);\n $$(this.element).trigger(QueryEvents.preprocessMoreResults, {\n results: queryResults\n });\n }\n}\n\nInitialization.registerAutoCreateComponent(Folding);\n\n\n\n// WEBPACK FOOTER //\n// ./src/ui/Folding/Folding.ts","import { exportGlobally } from '../../GlobalExports';\nimport { IQueryResult } from '../../rest/QueryResult';\nimport { IComponentBindings } from '../Base/ComponentBindings';\nimport { Initialization } from '../Base/Initialization';\nimport { Folding, IFoldingOptions } from '../Folding/Folding';\n\n/**\n * The `FoldingForThread` component inherits from the [`Folding`]{@link Folding} component. It offers the\n * same configuration options.\n *\n * Folding conversations and threads requires different processing. When you need to fold all child items (including\n * their attachments) on the same level under a common ancestor item, use this component rather than the `Folding`\n * component.\n *\n * This component works well with Chatter and Lithium.\n *\n * **Note:**\n * > There can only be one `FoldingForThread` component per [`Tab`]{@link Tab} component.\n *\n * See [Folding Results](https://docs.coveo.com/en/428/).\n */\nexport class FoldingForThread extends Folding {\n static ID = 'FoldingForThread';\n\n static doExport = () => {\n exportGlobally({\n FoldingForThread: FoldingForThread\n });\n };\n\n /**\n * Creates a new `FoldingForThread` component\n * @param element The HTMLElement on which to instantiate the component.\n * @param options The options for the `FoldingForThread` component.\n * @param bindings The bindings that the component requires to function normally. If not set, these will be\n * automatically resolved (with a slower execution time).\n */\n constructor(public element: HTMLElement, public options: IFoldingOptions, bindings?: IComponentBindings) {\n super(element, options, bindings);\n this.options.getMoreResults = (results: IQueryResult[]) => {\n return Folding.foldWithParent(results)[0].attachments;\n };\n\n this.options.getResult = (result: IQueryResult) => {\n var defaultResult = Folding.defaultGetResult(result);\n defaultResult.childResults = defaultResult.attachments;\n defaultResult.attachments = [];\n return defaultResult;\n };\n }\n}\n\nInitialization.registerAutoCreateComponent(FoldingForThread);\n\n\n\n// WEBPACK FOOTER //\n// ./src/ui/FoldingForThread/FoldingForThread.ts","import { chain, contains, first, values } from 'underscore';\nimport { Assert } from '../../misc/Assert';\nimport { QueryBuilder } from '../../ui/Base/QueryBuilder';\n\nexport enum VALID_SORT {\n RELEVANCY = 'relevancy',\n DATE = 'date',\n QRE = 'qre'\n}\n\nexport enum VALID_DIRECTION {\n ASCENDING = 'ascending',\n DESCENDING = 'descending'\n}\n\nexport class SortCriterion {\n private static sortsNeedingDirection = [VALID_SORT.DATE];\n\n /**\n * Create a new SortCriteria\n * @param sort The sort criteria (e.g.: relevancy, date)\n * @param direction The direction by which to sort (e.g.: ascending, descending)\n */\n constructor(public sort: VALID_SORT, public direction: VALID_DIRECTION | '' = '') {\n if (!SortCriterion.sortIsField(sort)) {\n Assert.check(\n this.isValidSort(sort),\n `${sort} is not a valid sort criteria. Valid values are ${values(VALID_SORT)} or a valid index sortable index field.`\n );\n }\n if (SortCriterion.sortNeedsDirection(sort)) {\n Assert.check(\n this.isValidDirection(direction),\n `${direction} is not a valid sort criteria direction. Valid values are ${values(VALID_DIRECTION)}`\n );\n } else {\n Assert.check(direction == '');\n }\n }\n\n private isValidDirection(direction: string): direction is VALID_DIRECTION {\n return chain(VALID_DIRECTION)\n .values()\n .contains(direction as any)\n .value();\n }\n\n private isValidSort(sort: string): sort is VALID_SORT {\n return chain(VALID_SORT)\n .values()\n .contains(sort as any)\n .value();\n }\n\n private static sortIsField(criteria: string) {\n return criteria.charAt(0) == '@';\n }\n\n private static sortNeedsDirection(sort: string) {\n return contains(SortCriterion.sortsNeedingDirection, sort) || SortCriterion.sortIsField(sort);\n }\n}\n\nexport class SortCriteria {\n private criteria: SortCriterion[] = [];\n\n constructor(rawCriteriaString: string) {\n const criteria = rawCriteriaString.split(';');\n criteria.forEach(criterion => {\n const split = criterion.match(/\\S+/g);\n this.criteria.push(new SortCriterion(split[0] as VALID_SORT, split[1] as VALID_DIRECTION));\n });\n }\n\n public get direction() {\n return first(this.criteria).direction;\n }\n\n public get sort() {\n return first(this.criteria).sort;\n }\n\n /**\n * Return a new SortCriteria from a string\n * @param criteria The string from which to create the SortCriteria\n */\n static parse(criteria: string): SortCriteria {\n return new SortCriteria(criteria);\n }\n\n /**\n * Put the sort criteria in the passed queryBuilder\n * @param queryBuilder The queryBuilder in which to put the sort criteria.\n */\n public putInQueryBuilder(queryBuilder: QueryBuilder) {\n Assert.exists(queryBuilder);\n queryBuilder.sortCriteria = this.toString()\n .split(';')\n .join(',');\n }\n\n /**\n * Returns a string representation of the sort criteria (e.g.: 'date ascending').\n */\n public toString(): string {\n return this.criteria\n .map(criterion => {\n return criterion.direction ? `${criterion.sort} ${criterion.direction}` : `${criterion.sort}`;\n })\n .join(';');\n }\n\n /**\n * Checks if the SortCriteria is equal to another.\n * @param criteria The SortCriteria to compare with\n */\n public equals(criteria: SortCriteria): boolean {\n return criteria.toString() == this.toString();\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/ui/Sort/SortCriteria.ts"],"sourceRoot":""}